September 14, 2022 by The Slint Team

Slint 0.3 Released, with a platform API for MicrocontrollersBlog RSS

We're proud to announce the release of Slint version 0.3.0, with many new features and APIs. Let's look at the highlights:


Slint 0.3.0

Platform API for Microcontrollers

Earlier this year we blogged about our effort of porting Slint to Microcontrollers (MCUs). One strength of MCUs is that they are highly customizable with different peripherals - it's like when you were playing with LEGO as a kid. In this release we're empowering you to use Slint on your MCU. Use our new APIs to integrate touch input and rendering into your own event loop, and then focus on adding a delightful user interface to our device.

These new platform abstraction and rendering APIs are only available for the Rust programming language today; C++ is in our future plans.

The skeleton of a typical bare metal Rust application looks like this:

#![no_std]
  #![no_main]
  extern crate alloc;
  use alloc::{rc::Rc, boxed::Box};
  use slint::platform::software_renderer::MinimalSoftwareWindow;
  
  // Include code build.rs generated from the Slint files.
  slint::include_modules!();
  
  // MyPlatform implements the Slint platform abstraction trait, to
  // create windows and provide time.
  struct MyPlatform {
    // the window need to be shared between Slint and your event loop
    window: Rc<MinimalSoftwareWindow>,
  }
  
  impl slint::platform::Platform for MyPlatform {
    fn create_window_adapter(&self) -> Rc<dyn slint::platform::WindowAdapter> {
      self.window.clone()
    }
    fn duration_since_start(&self) -> core::time::Duration {
      // ... get the time from a system timer API ...
    }
  }
  
  
  #[hal::entry]
  fn main() -> ! {
    // Initialize your peripherals ...
  
    // Initialize the Slint platform abstraction.
    let window = MinimalSoftwareWindow::new();
    slint::platform::set_platform(Box::new(
      MyPlatform { window: window.clone() }
    ));
  
    // Instantiate the Slint component.
    let ui = AppWindow::new();
    ui.show();
  
    // Event loop:
    loop {
      slint::platform::update_timers_and_animations();
  
      // Maybe deliver Touch events to the Slint window.
      if let Some(event) = check_for_touch_event(/*...*/) {
        window.dispatch_event(event);
      }
  
      window.draw_if_needed(|renderer| {
        renderer.render(FRAME_BUFFER, DISPLAY_WIDTH);
      })
    }
  }
  

For more details and examples see the Slint on Microcontrollers documentation and check out our Slint Bare Metal Microcontroller Rust Template.

Slint on a RP2040 with 260K of RAM (RaspberryPi Pico)
Slint on STM32H735G

New Rendering Backends

In desktop and embedded environments, Slint typically uses operating system provided APIs to render the user interface using the GPU. We do this with the help of the femtovg crate, which uses OpenGL. In this release, we're adding a second hardware-accelerated renderer that's based on the popular Skia Graphics Engine. Skia is used by Google Chrome, Mozilla Firefox, Android, Flutter, and many other projects. It uses Metal on macOS, and Direct 3D on Windows to achieve great rendering performance. To try this new feature, enable the renderer-winit-skia feature on the Slint crate or the SLINT_FEATURE_RENDERER_WINIT_SKIA CMake option.

In contrast, most MCUs don't have GPUs. Instead, all rendering is done by software on the CPU. In this release we're including a software renderer API, that supports rendering into a whole frame buffer or rendering line by line for memory constrained devices.

Both renderers are not entirely feature complete yet. We're including them as opt-in features in this release because we feel that they provide value to our users today, and we'll enhance them incrementally in future releases.

Improved Online Editor

Our Online Editor is a very useful playground for prototyping and sharing Slint designs. In this release, we added two major improvements:

  • The user interface features a docking framework. This is our new basis for many more UI enhancements in the future.
  • The editor uses the same LSP server that we're also using in the IDE integration to provide much improved code completion and features like go-to definition.
The Online Editor

Smaller, Noteworthy Features

  • Use the new size and position APIs on slint::Window to programmatically place windows on the screen.
  • Images can now be rotated using the new rotation-angle property.
  • We added an animation-tick() function that allows creating highly customized animations.
  • Use the slint::format! macro to create a slint::SharedString using interpolation of arguments.

Upgrading

If you're using Slint with Rust, upgrade by editing your Cargo.toml: Change your dependency line for both slint and slint-build from "0.2" to "0.3".

If you're using Slint with C++ and CMake's FetchContent, update the GIT_TAG entry in your CMakeLists.txt to specify either v0.3.0 or use release/0.3 to automatically pick up all 0.3.x releases in the future.

We follow the Semantic Versioning conventions. By going from version 0.2.x to 0.3.0 we are increasing the left-most non-zero component, which means that there may be breaking changes in the existing APIs. We've kept changes to a minimum, but you may encounter new compile warnings or errors. For more details, see our Breaking Changes section in the ChangeLog.

Conclusion

Thank you to everyone who contributed, especially the numerous external contributors.

We hope that you'll enjoy upgrading to this new version. If you run into any issues or notice missing functionality, please don't hesitate to let us know. We'd love to get your feedback. You can get in touch with us via our GitHub site, email, or via chat on our Mattermost instance.


Comments

Slint is a Rust-based toolkit for creating reactive and fluent user interfaces across a range of targets, from embedded devices with limited resources to powerful mobile devices and desktop machines. Supporting Android, Windows, Mac, Linux, and bare-metal systems, Slint features an easy-to-learn domain-specific language (DSL) that compiles into native code, optimizing for the target device's capabilities. It facilitates collaboration between designers and developers on shared projects and supports business logic development in Rust, C++, JavaScript, or Python.