Skip to content

Commit d61ebe0

Browse files
authored
Add blog post: Preview of LibrePCB 2.0's Next-Gen UI (#96)
1 parent 75ad4de commit d61ebe0

File tree

13 files changed

+320
-1
lines changed

13 files changed

+320
-1
lines changed

assets/style.css

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,6 @@ img.intro-screenshot {
326326
.body-container .olist,
327327
.body-container .ulist,
328328
.body-container .exampleblock,
329-
.body-container .imageblock,
330329
.body-container .listingblock,
331330
.body-container .literalblock,
332331
.body-container .sidebarblock,
@@ -339,6 +338,11 @@ img.intro-screenshot {
339338
margin-bottom: 1rem;
340339
}
341340

341+
.body-container .imageblock {
342+
/* was 1rem, but it looks ugly to have that space after images */
343+
margin-bottom: 0rem;
344+
}
345+
342346
.body-container .dlist .dlist,
343347
.body-container .dlist .olist,
344348
.body-container .dlist .ulist,
@@ -658,6 +662,10 @@ img.intro-screenshot {
658662
vertical-align: middle;
659663
}
660664

665+
.body-container .highlight pre {
666+
padding: 0.5rem;
667+
}
668+
661669
/* Open Collective logo from https://css.gg/open-collective (license: MIT) */
662670

663671
.gg-open-collective,
3.26 MB
Loading
2.59 MB
Loading
Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
---
2+
date: 2025-09-12
3+
title: Preview of LibrePCB 2.0's Next-Gen UI
4+
author: U. Bruhin
5+
preview: new-window.png
6+
---
7+
8+
I've made a lot of progress with the completely new user interface for
9+
LibrePCB 2.0 and am very excited to share some insights how it will look,
10+
and how it makes LibrePCB better in many ways.
11+
12+
The Original Problem
13+
--------------------
14+
15+
First, let's quickly look back how everything began. Since the early days of
16+
LibrePCB around 2013, we are using Qt as the UI toolkit and the concept was
17+
to implement every editor as a separate window (schematic editor, board editor,
18+
library editor etc.):
19+
20+
[.imageblock]
21+
{{< imglink "old windows" "old-windows.png" >}}
22+
23+
But with more features added over time, the UI got more and more cluttered.
24+
Also the paradigm of separate windows is often cumbersome to work with -- e.g.
25+
having just one library and one project opened required to constantly switch
26+
between four(!) windows. Even a dual-monitor setup was not enough to work
27+
efficiently with LibrePCB. So it was clear we need a completely new
28+
organization of windows and editors. Generally we could have done that with Qt,
29+
but its traditional approach makes is really hard to pursue more modern
30+
UI paradigms, not to mention the effort and the error-proneness it involves.
31+
In the past I have struggled many times with Qt to create nice UI elements,
32+
thus I didn't feel confident to build up a completely new UI with Qt again.
33+
34+
Slint: A Declarative UI Language
35+
--------------------------------
36+
37+
In the blog post
38+
link:{{< relref "blog/2024-10-17_roadmap_2.0/index.adoc" >}}[NGI0 Grant for LibrePCB 2.0]
39+
I listed a few possible solutions how to build a more modern user interface. The
40+
most promising option was https://slint.dev/[Slint], a relatively new UI
41+
toolkit (open-source & written in Rust) which uses a custom, declarative
42+
language to describe the UI. With the declarative approach, relations and
43+
behavior can be easily specified right in the UI description:
44+
45+
{{< highlight qml >}}
46+
Window {
47+
Button {
48+
x: parent.width - self.width - 5px; // place 5px from the right border
49+
y: 5px; // place 5px from the top border
50+
text: @tr("Open Project");
51+
}
52+
}
53+
{{< /highlight >}}
54+
55+
It may sound trivial to place a button at the top right corner of its parent,
56+
but with the procedural approach of Qt this is often not trivially doable. In
57+
many cases, it requires to implement event handlers in C++ which update the
58+
widgets position whenever the parent object's size or the widgets's own size
59+
has changed. Writing such code is time-consuming and error-prone, while the
60+
declarative approach of Slint is quick, easy and safe -- not just for
61+
this trivial example, but also in more complex cases. For a large project like
62+
LibrePCB, which consists of hundrets of UI elements, the declarative approach
63+
is really a game-changer for us developers! _(Side note: As of today, LibrePCB
64+
contains 23.746 lines of Slint code!)_
65+
66+
An Incremental Migration
67+
------------------------
68+
69+
Unfortunately, even with several months of full-time work, LibrePCB is too
70+
large to be migrated to Slint by 100% at once -- to avoid delaying the next
71+
release too much, we need to do the migration in steps. All the main windows &
72+
editors first, and the remaining dialogs and wizards in later releases. Also
73+
our whole business logic depends on Qt (it is much more than just a UI
74+
framework), thus our dependency on Qt will remain for a long time.
75+
76+
So the question is, can we mix Qt with Slint? In the end, LibrePCB only works
77+
if the main thread is running Qt's event loop. But Slint only works when the
78+
main thread is running _their_ event loop. So at first glance it seems we
79+
have a very bad conflict here :-/
80+
81+
In fact, Slint supports
82+
https://docs.slint.dev/latest/docs/slint/guide/backends-and-renderers/backends_and_renderers/[different backends]
83+
for interaction with the underlying system, e.g. for input events handling
84+
and window drawing. These are (interestingly) Qt,
85+
https://docs.rs/winit/latest/winit/[winit] and LinuxKMS. Winit comes with the
86+
ability of GPU-accelerated rendering, which would be interesting for
87+
performance reasons. But unfortunately right now we can't use winit because
88+
of the event loop conflict.
89+
90+
Luckily Slint's Qt backend avoids that problem since Slint will run Qt's
91+
event loop for us. So the event loop will process the events for both, the
92+
Slint UI and the LibrePCB backend. This works because Slint and LibrePCB
93+
are compiled and linked against the same Qt library. It also allows us to
94+
mix the new Slint window with legacy Qt dialogs & wizards, so we can do
95+
a step-by-step migration.
96+
97+
One Window For Everything
98+
-------------------------
99+
100+
Enough background information for now, let's have a look at the new UI of
101+
LibrePCB 2.0. The most important thing is that all the individual windows
102+
mentioned above have been replaced by a single, multifunctional window.
103+
Within that window, any kind of "document" (e.g. a footprint, a schematic or
104+
a board) is opened as a tab. The toolbars of the new window now depend on
105+
which tab is currently active, because for example the footprint editor
106+
supports other features than the schematic editor. This is how the new window
107+
currently looks like:
108+
109+
[.imageblock.rounded-window.window-border]
110+
{{< imglink "new window" "new-window.png" >}}
111+
112+
By the way, in this new window you can even have multiple projects (and
113+
libraries) opened at the same time! All the opened projects and libraries are
114+
listed in the documents panel, and the contained entities can be opened as
115+
individual tabs.
116+
117+
Sidebar & Panel
118+
~~~~~~~~~~~~~~~
119+
120+
A lot of functionality is accessible through the new sidebar. Depending on
121+
context, there are different kinds of panels available. For example if you're
122+
working on a schematic, there is a panel which displays ERC messages. But if
123+
you're working on a board, that panel will display DRC messages.
124+
125+
[.imageblock]
126+
{{< imglink "side panels" "side-panels.png" >}}
127+
128+
The sidebar also shows you status information about various parts of the
129+
application. For example you see if there are ERC warnings or outdated
130+
workspace libraries without even opening the corresponding panel:
131+
132+
[.imageblock]
133+
{{< imglink "side buttons" "side-buttons.png" >}}
134+
135+
Working Area
136+
~~~~~~~~~~~~
137+
138+
The most important part of our UI is of course the working area where you
139+
draw schematics or layout traces etc. This area has been improved in many ways.
140+
Not only that _everything_ is now a tab (remember that schematics were not
141+
tabs in the old UI), you can now even split the window into multiple sections
142+
and open tabs side-by-side. For example if you're working on a single-monitor
143+
setup, it is now easy to work on the board while still having the schematics
144+
in sight:
145+
146+
[.imageblock.rounded-window.window-border]
147+
{{< imglink "split section" "split-section.png" >}}
148+
149+
Tabs and sections can be easily arranged by drag&drop -- *see it in action
150+
in link:/blog/2025-09-12_preview_of_next_gen_ui/drag-n-drop.gif[this video]*.
151+
152+
In addition, the working area has been maximized and decluttered to have as
153+
much of the screen size available for the graphics view as possible. For
154+
example, tool buttons are now overlays inside the editors rather than
155+
traditional toolbars spanning the whole window height or width even if
156+
only a third of them is filled with buttons. There is no such wasted space
157+
anymore in the new UI.
158+
159+
Statusbar & Notifications
160+
~~~~~~~~~~~~~~~~~~~~~~~~~
161+
162+
We already had a status bar in the old UI, but it was purely visual and not
163+
interactive. Instead of just _displaying_ the grid interval, the new UI
164+
allows you to _modify_ the grid interval and the grid style right in the status
165+
bar -- no dedicated dialog window is required anymore. Also the state of
166+
placement locks is displayed and can be toggled right in the status bar.
167+
Last but not least, there is a completely new notification system which
168+
displays messages and ongoing operations in an expandable/collapsible popup
169+
in the bottom right corner:
170+
171+
[.imageblock]
172+
{{< imglink "statusbar" "statusbar.png" >}}
173+
174+
Multi-Monitor Ready
175+
~~~~~~~~~~~~~~~~~~~
176+
177+
If you are working on a multi-monitor setup and now worry that a single window
178+
is worse than the multiple windows we had before -- of course this use-case
179+
is covered as well. Although the new window replaces all the old windows,
180+
I have implemented the ability to open _multiple instances_ of that window
181+
at the same time. So you decide whether to display schematic and board
182+
side-by-side by splitting a single window, or by opening schematic and
183+
board in entirely separate windows -- everything is possible with the new
184+
concept!
185+
186+
Simplified Library Management
187+
-----------------------------
188+
189+
The old library manager was not that bad, but it was more complicated than
190+
necessary due to its "operation-based" workflow of manually triggering the
191+
installation or uninstallation of libraries, with those operations even
192+
spread across multiple list views and pages.
193+
194+
The new library manager is much simpler (but as functional as before)
195+
by following a "state-based" paradigm now. Instead of triggering the
196+
installation or uninstallation of individual libraries, you now just check
197+
the libraries you like to use (or uncheck those you don't want anymore) and
198+
a single _apply_ operation performs all the necessary installations or
199+
removals at once. Beside the improved user experience, this also fixes some
200+
issues of the old concept (e.g. limitations of the automatic dependency
201+
management).
202+
203+
[.imageblock.rounded-window.window-border]
204+
{{< imglink "library manager" "library-manager.gif" >}}
205+
206+
Configurable 3D View
207+
--------------------
208+
209+
The old 3D view was just a pure read-only display with no configuration
210+
options at all. But for a detailed review of the design, sometimes it is
211+
necessary to hide specific things -- e.g. the devices or the solder paste.
212+
This is now possible by changing the transparency of those objects:
213+
214+
[.imageblock.rounded-window.window-border]
215+
{{< imglink "3d view" "3d-view.gif" >}}
216+
217+
218+
Built-In Hints, Tips & Guides
219+
-----------------------------
220+
221+
In my vision, an EDA tool should support engineers/makers as well as
222+
possible (in a non-disruptive way) to help them creating PCB designs without
223+
errors as quick as possible. The new UI has therefore various new tips & hints
224+
implemented which show up in certain situations. Many of them are especially
225+
useful for LibrePCB beginners to ensure a smooth first-use experience, but
226+
some are useful for everyone to minimize errors or wasted time.
227+
228+
As an example, the built-in PCB ordering feature now displays the state of
229+
the electrical- & design-rule checks as a friendly reminder to review & fix
230+
any issues before ordering a (possibly faulty) PCB. The order panel contains
231+
direct hyperlinks to the ERC & DRC panels, and even allows to run the DRC
232+
right from the order panel. And as an additional psychological effect, the
233+
order button is only highlighted if there are no issues, though it is always
234+
clickable. 🤓
235+
236+
[.imageblock.rounded-window.window-border]
237+
{{< imglink "order pcb" "order-pcb.gif" >}}
238+
239+
What's Next?
240+
------------
241+
242+
Even though the new UI is the biggest change in the history of LibrePCB,
243+
this is just the beginning of a new user experience. There is still a lot
244+
of room for improvements which we will take care of after the LibrePCB 2.0
245+
release. Just a few examples:
246+
247+
* Object property editors (incl. multi-object editing) in side panel to get
248+
rid of modal dialogs
249+
* Replace remaining modal dialogs & wizards by integrating them as tabs
250+
or lightweight popups
251+
* Reflect typical workflows by the UI, for higher productivity and intuitivity
252+
* Productivity improvements, e.g. drag&drop, more keyboard shortcuts,
253+
hints, links to docs, ...
254+
* Theme improvements / cleanup / polishing, maybe some day support
255+
customizable themes
256+
257+
All the completed tasks and the planned tasks, together with more details
258+
and previews of the new UI, are summarized in
259+
https://github.com/LibrePCB/LibrePCB/issues/1494[this issue]. Of course there
260+
are also a lot of new non-UI features beeing developed for LibrePCB 2.0 and
261+
beyond, those are tracked in separate issues. This blog post just focused on
262+
the UI things due to its huge relevance in this moment.
263+
264+
Give it a Try!
265+
~~~~~~~~~~~~~~
266+
267+
If you like to try out the new UI already, we have nightly builds available
268+
*https://download.librepcb.org/nightly_builds/new-ui-with-file-format-1_0/[here]*.
269+
In contrast to the current `master` branch, these builds still use the stable
270+
file format 1.0 so no changes will be made to your library- and project files.
271+
But of course there might still be some bugs -- if you experience any issues
272+
or annoyances, or have any other feedback, please
273+
link:{{< relref "help/help/index.adoc" >}}[let us know]!
274+
275+
++++
276+
<div class="text-center my-3">
277+
<a class="btn btn-primary mx-1 my-1" role="button" href="https://download.librepcb.org/nightly_builds/new-ui-with-file-format-1_0" >
278+
<i class="fa-solid fa-download"></i>
279+
Get Nightly Builds
280+
</a>
281+
<a class="btn btn-warning mx-1 my-1" role="button" href="{{< relref "help/help/index.adoc" >}}" >
282+
<i class="fa-solid fa-message"></i>
283+
Give Feedback
284+
</a>
285+
<a class="btn btn-danger mx-1 my-1" role="button" href="{{< relref "donate/index.adoc" >}}" >
286+
<i class="fa-solid fa-heart"></i>
287+
Support My Work
288+
</a>
289+
</div>
290+
++++
291+
292+
Btw, if you are curious about the timeline of the LibrePCB 2.0 release:
293+
There are still some new features to be implemented (mostly non-UI things now)
294+
and it is hard to say when they are finished. But roughly I'd estimate it
295+
should be ready in around 2-3 months. If you like to support my work on
296+
the LibrePCB project, any link:{{< relref "donate/index.adoc" >}}[donations]
297+
are highly appreciated and help me to keep the development ongoing. icon:heart[]
298+
299+
---
300+
301+
Credits
302+
-------
303+
304+
[.right.ms-3]
305+
{{< imglink "NGI0" "nlnet-ngi0.png" "https://nlnet.nl/project/LibrePCB2.0/" 130 >}}
306+
307+
A majority of these updates were part of the
308+
link:{{< relref "blog/2024-10-17_roadmap_2.0/index.adoc" >}}[NGI0 Commons grant]
309+
we receive from link:https://nlnet.nl[NLnet], thanks a lot for their support!
310+
Also a special thanks to the Slint developers who helped me with support,
311+
feature development and bugfixes during this migration.
1.27 MB
Loading
271 KB
Loading
38.1 KB
Loading
286 KB
Loading
779 KB
Loading
11 KB
Loading

0 commit comments

Comments
 (0)