Cross-platform GUI toolkit written in Rust

Related tags

GUI tuix
Overview

logo


GitHub Build Discord

Tuix is a cross-platform GUI toolkit written in Rust.

The driving principle behind tuix is to be a self-contained, small-as-possible, but still fast, toolkit for creating graphical user interfaces in Rust.

calculator

Features

  • Build Cross-Platform Applications
  • Flexible Layout
  • Fully Customisable Styling
  • Animatable Style Properties
  • A Reactive Data Model
  • Numerous Built-In Widgets
  • Custom Widgets

editor

Including tuix

Add tuix to your project by adding tuix = {git = "https://github.com/geom3trik/tuix", branch = "main"} to your projects Cargo.toml under dependencies.

Debug Performance

Note: In order to get acceptable performance when running your app in Debug mode, it is highly recommended to add this to the Cargo.toml of your root crate:

[profile.dev.package.tuix_core]
opt-level = 2
[profile.dev.package.tuix_widgets]
opt-level = 2
[profile.dev.package.femtovg]
opt-level = 2

Getting Started

Running Examples

You can run any of the examples with:

cargo run --example example_name --release

To run any example with the baseview backend:

cargo run --example example_name --no-default-features --features "baseview" --release

Hello GUI

Since it's probably best to learn by example, here is the "hello world" of GUI applications in tuix:

use tuix::*;

fn main() {

    let app = Application::new(WindowDescription::new().with_title("Hello GUI"), |state, window| {
        
        Button::with_label("Button")
            .build(state, window.entity(), |builder| {
                builder
                    .set_width(Pixels(100.0))
                    .set_height(Pixels(30.0))
                    .set_background_color(Color::from("#ff5e1a"))
                    .set_child_space(Stretch(1.0))
            });
    });

    app.run();
}

You can run this example with: cargo run --example hello_gui --release

Tuix Book (In Development)

The Book

Comments
  • typo in font file

    typo in font file

    Hi, I just tried to build the example on Linux and got an error in application.rs. It seems that resources/entypo.ttf should be renamed into resources/Entypo.ttf.

    bug 
    opened by xunil-cloud 5
  • New layout system

    New layout system

    New layout system based on: https://subformapp.com/articles/why-not-flexbox/

    Overview:

    • All elements have a horizontal and vertical axis, each of which consists of space before, size, and space after.
    • Elements either control their own position (“self-directed”, akin to CSS absolute positioning) or are positioned by their parent (parent-directed).
    • Parents can position their parent-directed children in a vertical stack, horizontal stack, or grid.
    • The same units—pixels, percentages (of the parent size), and stretch (akin to flex, proportionally dividing up available space)—are used everywhere, with minimum and maximum constraints as part of the unit.

    Progress:

    Element

    • [x] parent-directed
    • [x] self-directed
    • [x] space_before, space_after, and size for main and cross axes.
    • [x] pixel units
    • [x] percentage units
    • [x] stretch units
    • [x] min/max on units

    Stack

    • [x] horizontal stack
    • [x] vertical stack
    • [x] space_before_first, space_between, space_after_last
    • [x] element override for space_before and space_after

    Stack Wrapping

    • [ ] wrapping
    • [ ] element override for space_before and space_after on cross axis (wrap axis)
    • [ ] space_before_first and space_after_last for wrapped elements
    • [ ] space_between for cross axis (wrap axis)

    Grid

    • [x] grid rows
    • [x] grid cols
    • [x] grid item row index and row span
    • [x] grid item col index and col span
    • [x] grid space_before_first and space_after_last
    • [ ] element override for space_before and space_after (does this even make sense?)
    opened by geom3trik 4
  • Bundling assets with release build

    Bundling assets with release build

    First of all, I can't express strongly enough how much this project excites me. I've been looking around the GUI libs in rust, and while quite a few of them show great potential, Tuix is the first library that seems to make simple desktop apps possible without the cognitive overhead of other libraries. Since I have no production goals with the things I'm building, I don't mind that this is only early stages of this library.

    I do have a question regarding assets required when building my application. It seems like as of now, when I need to load a stylesheet or an image, my application needs to load them from the file system. When creating a release build, I couldn't see any way to bundle those assets with the build. My assumption is that this is because of how the image and css crates work, but are there any plans to make assets and build bundled together? For my specific immediate needs this isn't really an issue, as I can keep everything in the same folder without an issue, but I am having a hard time thinking how I could distribute my application should I ever need to. I certainly could just zip everything and ship a zip file, or I could try to package it and use the default app settings folder in whatever native way the OS does that (like a folder in ProgramData for window, or $XDG_CONFIG_HOME on ubuntu), but if I am using filesystem paths inside the source code this seems like it might be harder to get consistently right.

    This is less of an actual issue, and more of a question about future plans.

    Thank you so much for your hard work on this!

    opened by aimerib 4
  • Add baseview backend to workspace

    Add baseview backend to workspace

    I found out cargo isn't happy when you have multiple bin examples that use different dependencies. So the way around this is to keep the existing examples as non-bins, and run this command to run the example with baseview:

    cargo run --example example_name --no-default-features --features "baseview"
    
    opened by BillyDM 4
  • Split container (vertical & horizontal)

    Split container (vertical & horizontal)

    Vertical/horizontal split containter for 2 widgets, with handle to let the user adjust the ratio.

    With some feedback when hovering the handle, like mouse cursor changing, but hovering should be fine too.

    I would also need a on_change callback, that communicates when the user changed the ratio and a message to set the ratio externally. This is required to persist the UI state.

    opened by WeirdConstructor 1
  • Font in stylesheet is not respected

    Font in stylesheet is not respected

    I added a font from memory like in the screenshot (green), and I added a class to a Label widget. The class is correctly respected because height and font-size are properly applied. But the font does not seem to be set correctly.

    image

    opened by WeirdConstructor 1
  • Clicking with right (or middle) mouse button does not reset active state (or not redraw?)

    Clicking with right (or middle) mouse button does not reset active state (or not redraw?)

    From the counter example in the tuix repository. You can reproduce by right clicking in the button and not leaving the button hover area. The visible state of the button stays activated.

    http://m8geil.de/data/push/Kazam_screencast_00057_up.mp4

    opened by WeirdConstructor 1
  • Fix keyboard input to attempt virtual keys first

    Fix keyboard input to attempt virtual keys first

    I think I found a fairly elegant solution that won't break anything already in-place. It first tries to convert Winit's virtual keycode from the input struct to a keyboard_types Code rather than using the scan code, then fails over to scan code if it has to.

    Closes #18

    opened by SonicZentropy 1
  • Crash on cursor/arrow up key

    Crash on cursor/arrow up key

    In HexoSynth, if I hit arrow key up, without doing anything else before, I get the following crash backtrace:

    thread 'main' panicked at 'index out of bounds: the len is 68 but the index is 16777215', /home/weicon/devel/rust/tuix/core/
    src/tree/tree.rs:133:9
    stack backtrace:
       0: rust_begin_unwind
                 at /rustc/ff2c947c00f867b9f012e28ba88cecfbe556f904/library/std/src/panicking.rs:515:5
       1: core::panicking::panic_fmt
                 at /rustc/ff2c947c00f867b9f012e28ba88cecfbe556f904/library/core/src/panicking.rs:92:14
       2: core::panicking::panic_bounds_check
                 at /rustc/ff2c947c00f867b9f012e28ba88cecfbe556f904/library/core/src/panicking.rs:69:5
       3: tuix_core::tree::tree::Tree::get_prev_sibling
       4: <tuix_widgets::containers::listbox::List as tuix_core::widget::widget::Widget>::on_event
       5: <tuix_widgets::tab::TabBar2 as tuix_core::widget::widget::Widget>::on_event
       6: tuix_core::events::event_manager::EventManager::flush_events
       7: tuix_glutin::application::Application::run::{{closure}}
       8: winit::platform_impl::platform::x11::EventLoop<T>::run
       9: winit::platform_impl::platform::EventLoop<T>::run
      10: winit::event_loop::EventLoop<T>::run
      11: tuix_glutin::application::Application::run
      12: tuix_gui::jack::start_backend
      13: tuix_gui::synth::start
    

    The "listbox" I am using is probably the Tabs.

    What probably happens is, that the Entity::null() that is used to initialize the "checked_entity" in Listbox is passed into get_prev_sibling and that does call Entity::index() on a null entity, which returns 16777215. Not sure however where/how to fix. My defensive programming guts tell me that either Entity::index() always returns a valid value. Or it should return Option<usize>. Or all callers should check if they are holding a null entity (which boils down to a similar if as the Option<usize> would), or they should consistently check if the index is out of range, like set_first_child does (it returns a TreeError::InvalidSibling in that case).

    On the other hand, the List should probably check for itself?

    opened by WeirdConstructor 0
  • Textbox styling does not respect bevel corners

    Textbox styling does not respect bevel corners

    From my toolkit I tried styling the 3 text boxes in a column inside a popup. The border on the corners look a bit odd, as they are not continuing on the edges. The corners also don't respect the new bevel borders in the default on_draw impl of Widget.

    image

    you can reproduce it by checking out this revision from my HexoSynth application: https://github.com/WeirdConstructor/HexoSynth/tree/e8734b3d62f53f1b7c8f375cd0cc860745ce68d9

     cd tuix_gui
     cargo run --release
    

    Then Ctrl+Right click on the knob on the right to open the popup.

    bug 
    opened by WeirdConstructor 0
  • Adds editor and some enhancements

    Adds editor and some enhancements

    • Editor example
    • Color picker widget (WIP)
    • Event listeners
    • Bevel corners
    • Inner shadow (TODO)
    • Color Shadows (BUG)

    ~ Makes dropdown generic to allow syncing state with binding

    opened by geom3trik 0
  • Custom style sheet properties for custom widgets

    Custom style sheet properties for custom widgets

    It would be awesome to have custom style properties in style sheets for custom widgets. I often have the problem that I would love custom colors and line thickness for my custom widget drawing. I would suggest collecting style properties that start with ext- or -ext- (what ever you like) and provide widgets a way to access them:

    block_code {
        -ext-block-border-width: 10px;
        -ext-block-color1: #FF00FF;
        -ext-block-color2: #FFFFFF;
        -ext-block-color3: #FF0000;
    }
    

    The type of the HashMap could be HashMap<String, StyleValueEnum> and the StyleValueEnum (if tuix doesn't already have something like this) could then be used by the widget to check if the contents is a color or size (or whatever types are possible).

    opened by WeirdConstructor 0
  • Widget Layers

    Widget Layers

    I need the ability to redraw only certain widgets. So that the rest of the UI does neither have to be re-layouted or be redrawn. Only the on_draw routine of the widgets in the layer would be called then.

    Having a manual way to assign the layers would be fine for now. But I would also be fine with some semi automatic layer mechanism that suffices the following use cases.

    A few use cases:

    • Live signal view, where the parent widget draws the background lines, and a child widget (which is in a separate layer) is drawing the signal graph. Then the layer with the signal graph widgets get a redraw each frame to update the signal (which is read out from eg. a ring buffer).
    • Blinking LEDs in a custom hex tile map. The hex tile map widget is drawing everything itself, like the tiles, their text. But there are parts that need to be redrawn each frame for the LED signals. Those would become a child widget of the tile map to draw these LEDs as overlay.
    • Redrawing the pattern editor is more or less expensive, as there is lots of single text elements in it. It would be awesome to have more control over when it is really redrawn and when not. I could put it into it's own layer, which is additionally redrawn when the widget is interacted with.
    opened by WeirdConstructor 0
  • Multiline labels or text views

    Multiline labels or text views

    I need some way to display simple multiline text. Preferably automatically wrapped, but for starters requiring some pre-wrapping with "\n" would be fine too.

    Use case here is: panels with help text, error popups with an error message, tooltips, a credits page to display the license and contributors in my HexoSynth project...

    opened by WeirdConstructor 0
  • Simple Menu API

    Simple Menu API

    I just need a way to make a very simple popup context menu for instance. Where I specify a few item labels and have a callback which one was clicked.

    This was the quick pseudo code I wrote earlier:

       Menu::new(cx, |cx| { ... })
           .items(vec![
               MenuItem::Button(id1, "next"),
               MenuItem::Button(id2, "prev"),
               ...
        ]).on_item(|id| {
             if id == id1 {
                  println!("Next clicked!");
             }
       });
    
    opened by WeirdConstructor 0
  • Resizeable panels/windows

    Resizeable panels/windows

    I envision a panel, sub window or window popup that I can grab on an edge and manually resize. It should be possible to make only certain edges resizeable so that some edges stay fixed.

    Also here it would be good to have visual feedback with hovering on that edge and with the mouse cursor changing shape.

    And here would also be a on_size_change callback good and a way to set the size via a message, to persist the size of the panel.

    opened by WeirdConstructor 0
Releases(v0.2.0)
Owner
George Atkinson
George Atkinson
Simple and portable (but not inflexible) GUI library in C that uses the native GUI technologies of each platform it supports.

libui: a portable GUI library for C This README is being written. Status It has come to my attention that I have not been particularly clear about how

Pietro Gagliardi 10.4k Dec 31, 2022
Rust bindings to the minimalist, native, cross-platform UI toolkit `libui`

Improved User Interface A cross-platform UI toolkit for Rust based on libui iui: ui-sys: iui is a simple (about 4 kLOC of Rust), small (about 800kb, i

Rust Native UI Group 865 Dec 27, 2022
A Rust binding of the wxWidgets cross platform toolkit.

wxRust master: / mac(0.10): This is a Rust binding for the wxWidgets cross platform toolkit. API wxRust API documentation How it works The wxRust libr

KENZ 129 Jan 4, 2023
A simple, cross-platform GUI automation module for Rust.

AutoPilot AutoPilot is a Rust port of the Python C extension AutoPy, a simple, cross-platform GUI automation library for Python. For more information,

null 271 Dec 27, 2022
A cross-platform GUI library for Rust, inspired by Elm

Iced A cross-platform GUI library for Rust focused on simplicity and type-safety. Inspired by Elm. Features Simple, easy-to-use, batteries-included AP

Héctor Ramón 17.5k Jan 2, 2023
Truly cross platform, truly native. multiple backend GUI for rust

WIP: Sauron-native a rust UI library that conquers all platforms ranging from desktop to mobile devices. An attempt to create a truly native, truly cr

Jovansonlee Cesar 627 Jan 5, 2023
A cross-platform GUI library for Rust focused on simplicity and type-safety

A cross-platform GUI library for Rust, inspired by Elm

Héctor Ramón 17.5k Jan 8, 2023
A cross-platform GUI library for Rust, inspired by Elm

Iced A cross-platform GUI library for Rust focused on simplicity and type-safety. Inspired by Elm. Features Simple, easy-to-use, batteries-included AP

null 17.5k Dec 28, 2022
rsautogui aims to be a cross-platform GUI automation rust crate.

rsautogui rsautogui aims to be a cross-platform GUI automation rust crate. It lets you control the mouse and keyboard to automate interactions with ot

null 5 Sep 18, 2022
A single-header ANSI C immediate mode cross-platform GUI library

Nuklear This is a minimal-state, immediate-mode graphical user interface toolkit written in ANSI C and licensed under public domain. It was designed a

Immediate Mode UIs, Nuklear, etc. 6.9k Jan 8, 2023
A lightweight cross-platform system-monitoring fltk gui application based on sysinfo

Sysinfo-gui A lightweight cross-platform system-monitoring fltk gui application based on sysinfo. The UI design is inspired by stacer. The svg icons a

Mohammed Alyousef 22 Dec 31, 2022
A light windows GUI toolkit for rust

Native Windows GUI Welcome to Native Windows GUI (aka NWG). A rust library to develop native GUI applications on the desktop for Microsoft Windows. NW

Gabriel Dube 1.6k Jan 7, 2023
Modular FFXIV data toolkit written in rust.

ironworks Modular FFXIV data toolkit written in rust. ironworks is pre-1.0, and as such its API should be considered unstable. Breaking API changes wi

Saxon Landers 10 Oct 21, 2022
Cross-platform native Rust menu library

A cross-platform Rust library for managing the native operating system menus.

Mads Marquart 16 Jan 6, 2023
An easy-to-use, 2D GUI library written entirely in Rust.

Conrod An easy-to-use, 2D GUI library written entirely in Rust. Guide What is Conrod? A Brief Summary Screenshots and Videos Feature Overview Availabl

PistonDevelopers 3.3k Jan 1, 2023
Idiomatic, GTK+-based, GUI library, inspired by Elm, written in Rust

Relm Asynchronous, GTK+-based, GUI library, inspired by Elm, written in Rust. This library is in beta stage: it has not been thoroughly tested and its

null 2.2k Dec 31, 2022
GUI based tool to sort and categorize images written in Rust

ImageSieve GUI based tool to sort out images based on similarity, categorize them according to their creation date and archive them in a target folder

Florian Fetz 67 Dec 14, 2022
A GUI for NordVPN on Linux that maintains feature parity with the official clients, written with Rust and GTK.

Viking for NordVPN This project aims to provide a fully usable and feature-complete graphical interface for NordVPN on Linux. While it attempts to clo

Jacob Birkett 2 Oct 23, 2022
Neovim GUI written in Rust, using relm4 and gtk4-rs

Reovim Neovim GUI written in Rust, using relm4 and gtk4-rs. Thanks Neovide Configuration To setup font add next line to init.vim set guifont=Cascadia\

songww 70 Dec 13, 2022