|
| 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. |
0 commit comments