The Rust UI-Toolkit.

Overview

OrbTk

Build and test MIT licensed crates.io docs.rs

The Orbital Widget Toolkit is a cross-platform (G)UI toolkit for building scalable user interfaces with the programming language Rust. It's based on the Entity Component System Pattern and provides a functional Reactive-like API.

The main goals of OrbTk are speed, ease of use, and cross-platform compatibility.

Screenshots

showcase

calculator-macos calculator-macos-light calculator-redox

Features:

  • Modern lightweight API
  • Cross platform
  • Modular crates
  • Based on Entity Component System library DCES
  • Flexible event system
  • Integrated widget library
  • Custom widgets
  • Custom theming engine
  • Dynamic theme switching
  • Integrated debugging tools
  • Localization

Platforms

  • Redox OS (native)
  • Linux (native | cargo-node)
  • macOS (native | cargo-node)
  • Windows (native | cargo-node)
  • openBSD (not tested, but should work)
  • Web (cargo-node)
  • Android (native planned | cargo-node)
  • iOS (native planned | cargo-node planned)
  • Ubuntu Touch (native planned | cargo-node planned)

Planned features

  • Conformable use of async
  • More default widgets
  • Book
  • Animations
  • Split application in modules
  • 3D context
  • More integrated debugging tools

Usage

To include OrbTk in your project, add this dependency line to your Cargo.toml file:

orbtk = "0.3.1-alpha3"

To use the latest development version of OrbTk, add this dependency line to your Cargo.toml file:

orbtk = { git = "https://github.com/redox-os/orbtk.git", branch = "develop" }

You can also check out the OrbTk template project to start a new project: https://github.com/redox-os/orbtk-template.

Minimal Example

use orbtk::prelude::*;

fn main() {
      Application::new()
        .window(|ctx| {
            Window::new()
                .title("OrbTk - minimal example")
                .position((100.0, 100.0))
                .size(420.0, 730.0)
                .child(TextBlock::new().text("OrbTk").build(ctx))
                .build(ctx)
        })
        .run();
}

Base concepts

Widget

Widgets are the building blocks of user interfaces in OrbTk. They are things like Buttons, TextBoxes, ListViews, Views (Screens) and Grid(Layout)s. Each widget implements the Widget trait and is generated by the widget! macro. A widget consists of a name like Button and a list of its properties like text: String, background: Brush or count: u32. After the build method of a widget is called it's added to the Entity Component System where it exists as an Entity (index) with Components. The struct of a widget serves as a builder using the builder pattern.

Basic usage of the widget! macro:

widget!(
    MyWidget {
      background: Brush,
      count: u32,
      text: String,
      ...
    }
);

Widget Templates

Each widget has to implement the Template trait. The template defines the default values of a widget's properties as well as its structure. A Button e.g. consists of a Container widget, a StackPanel widget and a TextBlock widget.

Basic usage of the Template trait:

impl Template for MyWidget {
    fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
         self.name("MyWidget")
            .style("my_widget_style")
            .background("#000000")
            .count(0)
            .text("Initial text")
            .child(Container::new()
                    // Container references the same background as MyWidget
                    .background(id)
                    .child(TextBlock::new()
                            // TextBlock references the same text as MyWidget
                            .text(id)
                            .build(ctx)
                    )
                    .build(ctx)
            )
    }
}

Widget State

The state of a widget is used to update its inner state. Each state has to implement the State trait. The inner state of a widget is represented by the current values of its properties.

Basic usage of the state trait:

#[derive(Default, AsAny)]
struct MyState {
    ...
}

impl State for MyState {
    fn update(&mut self, _: &mut Registry, ctx: &mut Context) {
        // update the widget
        ...
    }
}

widget!(
    // Add MyState as state of MyWidget
    MyWidget<MyState> {
        ...
    }
);

The Context parameter of the update method provides access to the state's widget (entity) and its properties (components). It also provides functions to access the children of the widget, and to manipulate the widget tree.

Styling widgets and define themes

OrbTk provides a theme engine base on RON. The engine provides the following features:

  • Split theme in different files
  • Outsource resources like colors and font stuff
  • Derive styles
  • Dynamic theme switch
  • State styling (pressed | selected | focused | disabled)

Short example:

Theme (
    styles: {
        "base": (
            properties: {
                "font_size": "$FONT_SIZE_12",
                "font_family": "$MEDIUM_FONT",
            }
        ),
        "button": (
            base: "base",
            properties: {
                "background": "$BLACK",
            },
            states: [
                (
                    key: "pressed",
                    properties: {
                        "background": "$WHITE",
                    }
                )
            ]
        )
    },
    resource: {
        "BLACK": "#000000",
        "WHITE": "#ffffff",
        "MEDIUM_FONT": "Roboto-Medium",
        "FONT_SIZE_12": 12,
        "FONT_SIZE_16": 16,
    }
)

OrbTk will also provide a plain mechanism to style and theme widgets and UIs.

Localization

OrbTk provides the possibility to register a application wide localization service. A localization service has to implement the Localization trait.

Example

pub struct MyLocalization {
    ...
}

impl Localization for MyLocalization {
    /// Gets the current language by language key e.g. `en_US` or `de_DE`.
    fn language(&self) -> &String {
        ...
    }

    /// Sets the current language by key e.g. `en_US` or `de_DE`.
    fn set_language(&mut self, key: &str) {
        ...
    }

    /// Gets the translated text for the given key. If there is no given translation the `key` will be returned as result.
    fn text(&self, key: String) -> String {
        ...
    }
}

It is possible to register a localization service on an application. There is also a ready to use RonLocalization service, that can read localization dictionaries in the RON format.

Example

let de_de = r#"
    Dictionary( 
        words: {
            "hello": "Hallo",
            "world": "Welt",
        }
    )
    "#;

Application::new()
    .localization(
        RonLocalization::create()
            // sets the initial language
            .language("en_US")
            // adds an language dictionary to the localization service. 
            .dictionary("de_DE", de_de)
            .build()
    )
    .window(|ctx| {
        Window::new()
            .title("OrbTk - showcase example")
            .position((100, 100))
            .size(600, 730)
            .resizeable(true)
            .child(TextBlock::new().text("hello").build(ctx))
            .build(ctx)
    })
    .run();

In this example the text property with the value hello is the key of the localization service. If there is no localization service or no given dictionary for the current language the value of the property will drawn. It is possible to start the development of an complete without localization and add it later.

To switch the language on runtime the set_language method of the Context struct can be used.

Run Examples

To build and run the examples you will need an C compiler (like gcc, clang, or MS's own compiler).

On Linux you also nee to install cmake. e.g.:

sudo apt install cmake

If you have trouble to build and run the examples or you don't want to use a C compiler check the backend section please? It contains alternatives.

You can find examples in the examples/ directory.

You can start the showcase example by executing the following command:

cargo run --example showcase --release

OrbTk has integrated debug tools. If you want to show the bounds of all widgets (even invisible ones) and want to see a debug print of the whole widget tree, you can run the examples with --features debug, like this:

cargo run --example showcase --release --features debug

Run Examples with cargo-node

To run the examples as a browser, electron or cordova app you have to install cargo-node:

cargo install -f cargo-node

Before you can use cargo-node you have to install npm version 6.9.0, which is included with Node.js version 10.16.3. You can download it from https://nodejs.org/dist/v10.16.3/.

Rust's cargo is also required. The rest of cargo-node's dependencies are installed automatically.

Start examples

You can run the "showcase" example by executing one of the following commands:

  • Run as browser app:
cargo node run --target browser --example showcase
  • Run as electron app:
cargo node run --target electron --example showcase
  • Run as cordova app on android:
cargo node run --target android --example showcase

OrbTk backends

At the moment will evaluate different backends for OrbTk. A OrbTk backend consists of two different parts, window / events and rendering. OrbTk provides at the moment the following backends:

orbraq (default)

  • default backend for Redox, Linux, macOS and Windows (default feature)
  • window and events based on OrbClient
  • 2D rendering based on raqote
  • Known issues: window does not redraw while resizing

stdweb

  • default backend for web (default feature)
  • window, events and 2D rendering based on stdweb
  • Does not yet support all features of orbraq e.g. DropEvents, Clipboard access

Documentation

Build and open documentation

You can build and view the latest documentation by executing the following command:

cargo doc --no-deps --open

OrbTk Manual

To build and run the latest version of the OrbTk manual check: Manual

OrbTk book

There is a (wip) OrbTk book check OrbTk book

Sub Crates

  • api: base api elements of OrbTk e.g. widget and application parts
  • proc_macros: procedural helper macros
  • render: cross platform 2D/3D render library
  • shell: cross platform window and event handling
  • theming: provide mechanism to style OrbTk UI's in rust and ron (replaces css-engine)
  • tree: tree structure based on DCES
  • utils: helper structs and traits
  • widgets: base widget library

Inspirations

Showcases

Contribution

If you want to help improve OrbTk you submit your feedback in the issue tracker, or make a pull request to fix an issue https://github.com/redox-os/orbtk/issues. You can also discuss OrbTk with us on the Redox chat https://redox-os.org/community/ (join the OrbTk channel).

Contribution check list

  • Documentation for all pub structs, traits and funs
  • Add tests if needed
  • Use static &str for widget ids and new style definitions
  • For widget development check ProgressBar or Slider as example
  • Add changes to changelog
  • Expand examples or create a new one if needed
  • cargo fmt at the end
  • Create PR

License

Licensed under MIT license (LICENSE).

Comments
  • Consider using tiny-skia

    Consider using tiny-skia

    Since you're already using raqote, I though you might be interest in a faster, more actively developed alternative.

    tiny-skia is a direct raqote rival. It's basically a Skia CPU subset ported to pure Rust. And it's usually 2-6x faster than raqote, while still 2-3 times slower than Skia (it's mainly SIMD issues). In many cases it's even faster than cairo.

    Is still in development (90% is done) and I plan to use it in resvg very soon. And I'm interested in any kind of feedback.

    opened by RazrFalcon 32
  • Beginners documentation

    Beginners documentation

    Context

    There is very (too?) little documentation available, especially for newbies.

    Problem description & Solution

    Documentation can be generated with: cargo doc --no-deps --open The resulting documentation is nice and all, but a bit to daunting for a beginner. The examples are super helpful, but do not provide sufficient context. It would be helpful to have some documentation on how to get started. How to connect functions to buttons, update labels (textboxes), etc. These can be extracted from the examples, but only with a lot of effort.

    Help?

    I am going to try to get some stuff made with orbTk. I would really love to help out by writing documentation (a starters guide or something... to help beginners). However, I would be helpful if somebody could create a start on which I can continue...

    duplicate documentation 
    opened by hanckmann 21
  • New Popup widget

    New Popup widget

    Context:

    this is the PR linked to the issue https://github.com/redox-os/orbtk/issues/298 .

    Contribution checklist:

    • [x] Add documentation to all public structs, traits and functions.
    • [ ] Add unit tests if possible
    • [x] Describe the major change(s) in the CHANGELOG.MD
    • [x] Run cargo fmt to make the formatting consistent across the codebase
    • [x] Run cargo clippy to check with the linter

    Hi, The Popup should work correctly, but currently make ComboBox unable to open. There is a strange behaviour on ComboBox that i don't understand: it have a closing function, but not an opening one. The only thing that could open the popup could be the SelectedBehaviour on:

                            SelectionBehavior::new()
                                .selected(id) //<--- here
                                .enabled(id)
                                .target(id.0)
                                .child(container)
                                .build(ctx),
    

    Unfortunately i have never used that struct, so i don't know how exactly work.

    Maybe there is some strange interaction that i miss. Anyway i have moved the popup logic on the PopupRenderObject. It is a simple Render Object that run the popup logic and than tell to a RectangleRenderObject to render. In this way there is no code repetition, while keeping all the features of RectangleRenderObject. I have also pushed the example code that i have used to test it. For now i have pushed it as "popup2.rs" on the example folder. I think that a good test is also check that the current popup example work correctly with the new popup.

    I will keep looking for the root of the problem, meanwhile i would like to know what do you think.

    Have a good day

    opened by uniformbuffer 20
  • TabWidget

    TabWidget

    Hi, for an application that i'm making i needed a tab widget to manage the user interface, so i have realized it. I think that now it is in a good shape from a functionality point of view, visually it is ugly but at least work correctly. Maybe with some css magic could be better. Since i saw that there is a tab widget request on the project page, i thought: "why not share?". Following an example code that i have used during testing:

    use orbtk::prelude::*;
    
    fn main() {
          Application::new()
            .window(|ctx| {
                Window::new()
                    .title("OrbTk - minimal example")
                    .position((100.0, 100.0))
                    .size(600.0, 500.0)
                    .resizeable(true)
                    .child(
                        TabWidget::new()
                        .tab("Tab header 1",TextBlock::new().text("Tab content 1").build(ctx))
                        .tab("Tab header 2",TextBlock::new().text("Tab content 2").build(ctx))
                        .tab("Tab header 3",TextBlock::new().text("Tab content 3").build(ctx))
                        .build(ctx)
                    )
                    .build(ctx)
            })
            .run();
    }
    

    Currently the TabWidget does not share values about tabs because setting them from the outside could lead into inconsistencies because i cannot get some change callbacks that hint the widget to change state. So for now the widget state is managed internally by the TabWidgetState structure. The widget will not draw everything during the update call, but only what it is changed, so this make it very lightweight. There are 2 values shared by TabWidget:

    • close_button(bool): should set the visibility of the close button on the right of the tabs, currently not implemented
    • spacing(f64): set the spacing between tabs

    I'm writing some other widgets that are less fundamental and more specialized. If you want i can also share those (maybe putting in a separated folder inside widget folder called "extra" or something similar?) Some of those widget already completed:

    • DiscreteBar: Similar to ProgressBar, but instead of working on 0%-100% work on discrete value that can be setted as "min" and "max", then the current value can be setted with "val". The widget will display the value using Container widgets that look like bars.
    • Fraction: It is a simple TextBlock that have "val" and "max" property and they are used to display a fraction like "3/10". Since they are managed using properties, setting a shared property will make the widget automatically adjust it's values (i have used it in combination with the DiscreteBar)

    Hope it could be useful, Have a good day

    opened by uniformbuffer 19
  • Interface appears laggy

    Interface appears laggy

    All examples show that the toolkit is using a fixed timestep, rendering at approximately at 10-15 FPS.

    To reproduce Run any example.

    Expected behavior The toolkit should pick up the refresh rate of my monitor by using vertical sync.

    Configuration:

    • OS: Windows 10 Pro
    • Native (no browser)
    • OrbTK v0.3.1-alpha2
    bug 
    opened by kotauskas 19
  • Update value of Textbox

    Update value of Textbox

    This code

    use orbtk::*;
    use std::vec::Vec;
    use std::cell::RefCell;
    use std::rc::Rc;
    use std::io::Write;
    use std::str::FromStr;
    
    extern crate strum;
    #[macro_use]
    extern crate strum_macros;
    
    widget!(MainView);
    
    // Enumeration of all possible operators
    #[derive(EnumString)]
    enum Operator {
        #[strum(serialize="+")]
        Plus,
        #[strum(serialize="-")]
        Min,
        #[strum(serialize="*")]
        Times,
        #[strum(serialize="/")]
        Divide,
    }
    
    impl Template for MainView {
        fn template(self, _: Entity, ctx: &mut BuildContext) -> Self {
    
            // String holding pressed keys creating an infix string
            // And a TextBox object holding that string
            let pressed_keys : Rc<RefCell<String>> = Rc::new(RefCell::new("".to_string()));
            let mut screen : Rc<RefCell<TextBox>> =
                Rc::new(RefCell::new(
                    TextBox::create()
                        .text("")
                        .attach(Grid::row(0))
                        .attach(Grid::column(0))
                        .attach(Grid::column_span(4))
                ));
    
    
            // Initializing Grid
            let mut grid = Grid::create(); 
    
            // Configuring grid (amount of rows and columns)
            grid = grid
                .columns(
                    Columns::create()
                        .column("*")
                        .column("*")
                        .column("*")
                        .column("*")
                        .build()
                )
                .rows(
                    Rows::create()
                        .row(50.0)
                        .row(50.0)
                        .row(50.0)
                        .row(50.0)
                        .row(50.0)
                        .row(50.0)
                        .row(50.0)
                        .build()
                );
           
            //Adding textbox holding entered numbers and operators
            grid = grid.child(
                screen.borrow_mut().build(ctx)
            );
    
            // Adding all buttons from 1-9 to the grid
            // in calculator format
            let mut counter : u8 = 9;
            for i in 1..4 {
                for j in 0..3 {
                    grid = grid.child(
                        Button::create()
                            .text(counter.to_string())
                            .attach(Grid::column(2-j))
                            .attach(Grid::row(i))
                            .on_click({
                                let pressed_keys = pressed_keys.clone();
                                let screen = screen.clone();
                                move |_states, _| -> bool {
                                    *pressed_keys.borrow_mut() = format!("{}{}", *pressed_keys.borrow(), counter.to_string());
                                    let screen_text : String = pressed_keys.borrow().clone();
                                    screen.borrow().text(screen_text);
                                    true
                                }
                            })
                            .build(ctx)
                    );
    
                    counter = counter - 1;
                }
            }
    
    
            self.name("MainView").child(
                grid.build(ctx)
            )
       } 
    }
    
    
    fn main() {
        Application::new()
            .window(|ctx| {
                Window::create()
                    .title("OrbTk - Calculator")
                    .position((100.0, 100.0))
                    .size(420.0, 500.0)
                    .child(MainView::create().build(ctx))
                    .build(ctx)
            })
            .run();
    }
    
    

    returns the following error:

    error[E0507]: cannot move out of dereference of `std::cell::Ref<'_, orbtk_widgets::text_box::TextBox>`
      --> src/main.rs:89:33
       |
    89 | ...                   screen.borrow().text(screen_text);
       |                       ^^^^^^^^^^^^^^^ move occurs because value has type `orbtk_widgets::text_box::TextBox`, which does not implement the `Copy` trait
    

    In the Calculator example they use .id() but this doesn't seem to work. How to fix this? I just want to update the value of a textbox when a button is clicked.

    question 
    opened by UA-Niel 14
  • Grid row auto height does not work as expected

    Grid row auto height does not work as expected

    Describe the bug Grid rows with auto height are not sized correctly to contain their children. The children end up overlapping with those of other rows. Unsure whether this issue applies to column width as well.

    Thank you for your work on this toolkit. On paper it's exactly what I want. :)

    To Reproduce Compile and run the following code.

    use orbtk::prelude::*;
    
    #[derive(Default, AsAny)]
    struct MainViewState {}
    
    impl MainViewState {}
    
    impl State for MainViewState {}
    
    widget!(MainView<MainViewState> {
        text: String16
    });
    
    impl Template for MainView {
        fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
            self.name("MainView")
                .width(400.0)
                .height(1000.0)
                .text("")
                .child(
                    Grid::create()
                        .rows(
                            Rows::create()
                                .row("auto")
                                .row("auto")
                                .row("auto")
                                .row("auto")
                                .row("auto")
                                .row("auto")
                                .row("auto")
                                .row("auto")
                                .build(),
                        )
                        .child(
                            generate_text_field(ctx, "Title")
                                .attach(Grid::column(0))
                                .attach(Grid::row(0))
                                .build(ctx),
                        )
                        .child(
                            generate_text_array_field(ctx, "Authors")
                                .attach(Grid::column(0))
                                .attach(Grid::row(1))
                                .build(ctx),
                        )
                        .child(
                            generate_text_array_field(ctx, "Owners")
                                .attach(Grid::column(0))
                                .attach(Grid::row(2))
                                .build(ctx),
                        )
                        .child(
                            generate_text_array_field(ctx, "Recipients")
                                .attach(Grid::column(0))
                                .attach(Grid::row(3))
                                .build(ctx),
                        )
                        .child(
                            generate_text_field(ctx, "Type")
                                .attach(Grid::column(0))
                                .attach(Grid::row(4))
                                .build(ctx),
                        )
                        .child(
                            generate_text_array_field(ctx, "Languages")
                                .attach(Grid::column(0))
                                .attach(Grid::row(5))
                                .build(ctx),
                        )
                        .child(
                            generate_text_array_field(ctx, "Tags")
                                .attach(Grid::column(0))
                                .attach(Grid::row(6))
                                .build(ctx),
                        )
                        .child(
                            generate_text_array_field(ctx, "Keywords")
                                .attach(Grid::column(0))
                                .attach(Grid::row(7))
                                .build(ctx),
                        )
                        .build(ctx),
                )
        }
    }
    
    fn generate_text_field(ctx: &mut BuildContext, label: &str) -> Container {
        Container::create()
            .padding(8)
            .border_width(2.0)
            .border_brush(Color::rgb(255, 255, 255))
            .child(
                Grid::create()
                    .rows(Rows::create().row("auto").row("auto").build())
                    .child(
                        orbtk::TextBlock::create()
                            .attach(Grid::row(0))
                            .text(label)
                            .build(ctx),
                    )
                    .child(
                        orbtk::TextBox::create()
                            .attach(Grid::row(1))
                            .width(300.0)
                            .text("")
                            .build(ctx),
                    )
                    .build(ctx),
            )
    }
    
    fn generate_text_array_field(ctx: &mut BuildContext, label: &str) -> Container {
        Container::create()
            .padding(8)
            .border_width(2.0)
            .border_brush(Color::rgb(255, 255, 255))
            .child(
                Grid::create()
                    .columns(Columns::create().column("auto").column("auto").build())
                    .rows(Rows::create().row("auto").row("auto").row("auto").build())
                    .child(
                        TextBlock::create()
                            .attach(Grid::row(0))
                            .text(label)
                            .build(ctx),
                    )
                    .child(
                        TextBox::create()
                            .width(300.0)
                            .text("")
                            .attach(Grid::column(0))
                            .attach(Grid::row(1))
                            .build(ctx),
                    )
                    .child(
                        Button::create()
                            .size(40.0, 32.0)
                            .text("Delete")
                            .attach(Grid::row(1))
                            .attach(Grid::column(1))
                            .build(ctx),
                    )
                    .child(
                        Button::create()
                            .size(40.0, 32.0)
                            .text("Add")
                            .attach(Grid::row(2))
                            .attach(Grid::column(0))
                            .build(ctx),
                    )
                    .build(ctx),
            )
    }
    
    pub fn main() {
        orbtk::Application::new()
            .window(|ctx| {
                Window::create()
                    .title("Window Title")
                    .position((100.0, 100.0))
                    .resizeable(true)
                    .size(450.0, 500.0)
                    .child(MainView::create().build(ctx))
                    .build(ctx)
            })
            .run();
    }
    

    Expected behavior The rows should automatically be made tall enough to fully contain their respective children. The same should be true for the width of columns with auto width.

    Screenshots Screenshot_2020-03-10_22-12-28

    Desktop

    • OS: Arch Linux with XFCE 4.14

    Additional context OrbTk rev abd8f786010584ba21d9f410d381685b14794dad (current develop)

    bug 
    opened by janibonnevier 12
  • Unable to compile examples: `sdl2-sys` fails to download

    Unable to compile examples: `sdl2-sys` fails to download

    Describe the bug The command cargo run --example showcase --release fails with

    error: failed to run custom build command for `sdl2-sys v0.34.3`
    
    Caused by:
      process didn't exit successfully: `/home/wucke13/documents/projects/rust/orbtk/target/release/build/sdl2-sys-d600d0eb48651eb0/build-script-build` (exit code: 101)
    --- stderr
    thread 'main' panicked at 'Command 'curl' failed:   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
      0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
    curl: (60) SSL certificate problem: unable to get local issuer certificate
    More details here: https://curl.haxx.se/docs/sslcerts.html
    
    curl failed to verify the legitimacy of the server and therefore could not
    establish a secure connection to it. To learn more about this situation and
    how to fix it, please visit the web page mentioned above.
    ', /home/wucke13/.cargo/registry/src/github.com-1ecc6299db9ec823/sdl2-sys-0.34.3/build.rs:53:17
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    
    warning: build failed, waiting for other jobs to finish...
    error: build failed
    

    To Reproduce Steps to reproduce the behavior:

    1. run cargo run --example showcase --releas on latest develop branch

    Expected behavior The thing compiles at least

    Desktop (please complete the following information):

    • OS: NixOS 20.09
    bug 
    opened by wucke13 11
  • showcase example runs frozen

    showcase example runs frozen

    When running showcase example on Linux X11 a window with all widget appears but it does not react on any input events (e.g. appears to be frozen)

    Steps to reproduce:

    • find linux workstation
    • find X11 DE ( KDE 5.20 in my case)
    • cargo new showcase
    • copy contents from showcase example
    • cargo run

    observe the frozen window

    bug 
    opened by ngortheone 11
  • Improve messaging system performance

    Improve messaging system performance

    Describe the bug The showcase example is lagging even in release mode. I suspect the problem is with the new messaging system introduced not so long ago. The screenshot shows the performance measurement made with perf that the example spends most of the time with multi-threaded types. Also a lot of mouse clicks is lost.

    To Reproduce Steps to reproduce the behavior: cargo run --example showcase --release

    Expected behavior The example should not lag at all.

    Screenshots showcase_perf

    Desktop: Win 10 Manjaro KDE 20.0.3

    Additional context Even on idle, i have constant 20-35% CPU usage when running an orbtk app.

    bug 
    opened by kivimango 11
  • ProgressBar

    ProgressBar

    Context

    The ProgessBar should be used to indicates a progress, e.g. the progress by loading a file, or a screen.

    Problem description & Solution

    The ProgressBar should be indicates the progress between a min-value and a max-value. The current progress should be set by a val property.

    Examples and MockUps

    ProgressBar::create().min(0.0).max(100.0).val(50.0).build(ctx)
    
    image
    opened by FloVanGH 11
  • orbtk sdl2-sys compiles standalone but not with orbtk

    orbtk sdl2-sys compiles standalone but not with orbtk

    Hello,

    when i use sdl2 as ony dependencie it compliles without an error, when i use orbtk (crates and dev-version) as standalone it compliles not under windows-msys2.

     C:/Mounts/externalDrives/extHDD(Home5TB)/Development/Rust/Users/cypu/.cargo/registry/src/github.com-1ecc6299db9ec823/sdl2-sys-0.35.2/SDL/src/joystick/windows/SDL_windows_gaming_input.c:649:113: note: expected '__FIReference_1_INT32 **' but argument is of type 'int **'
      make[2]: *** [CMakeFiles/SDL2-static.dir/build.make:2386: CMakeFiles/SDL2-static.dir/src/joystick/windows/SDL_windows_gaming_input.c.obj] Error 1
      make[2]: *** Waiting for unfinished jobs....
      make[1]: *** [CMakeFiles/Makefile2:112: CMakeFiles/SDL2-static.dir/all] Error 2
      make: *** [Makefile:136: all] Error 2
      thread 'main' panicked at '
      command did not execute successfully, got: exit code: 2
    

    thx

    bug 
    opened by cyberpunkbln 0
  • TextBlock does not show up

    TextBlock does not show up

    When trying to do the exercises in the orbtk book, I am able to compile the first example orbtk_hello. The window title shows up but the TextBlock contents do not show up. I tried changing the background but that did not resolve the issue. I then tried to use the orbtk_template code. Again, it compiled, title showed up but not the TextBlock.

    Screenshot from 2022-10-02 16-32-48 Screenshot from 2022-10-02 16-42-04

    Desktop (please complete the following information):

    • OS: PopOs
    • Browser Firefox 105.0.1

    Additional context Add any other context about the problem here.

    bug 
    opened by ItalicIntegral 1
  • Is this project still alive, and when can I expect the android and ios support coming out?

    Is this project still alive, and when can I expect the android and ios support coming out?

    Context

    In which context or scenario will your feature/widget be used?

    Problem description & Solution

    Describe your problem and possible solution here

    Examples and MockUps

    Can you give a concrete example of how you'd use the feature? A relevant code sample? Can you draw a picture of what you're imagining? :-)

    feature request 
    opened by gitlarky 1
  • current develop branch breaks on MacOS, showing black window

    current develop branch breaks on MacOS, showing black window

    Describe the bug On commit id 68c67da85002195cf8e3ef5ed7fd325ed7bccebe (currently top of develop), I ran

    ❯ cargo run --example showcase
    

    which gives me a black window. then I use git bisect, find out it's the top commit causing the problem.

    My OS is macOS 12.2.

    To Reproduce Steps to reproduce the behavior:

    1. Git checkout to 68c67da85002195cf8e3ef5ed7fd325ed7bccebe
    2. cargo run --example showcase
    3. If compile failed due to missing symbol, try to add a orbtk/build.rs and manually link against CoreHaptics
    4. See error

    Expected behavior Showing normal examples

    Screenshots screenshot-20220808-142402

    Desktop (please complete the following information):

    • OS: MacOS
    • Version 12.2

    Additional context I'm willing to help, but it currently gives no more info in console.

    bug 
    opened by Phantato 3
  • Undefined symbols for architecture x86_64

    Undefined symbols for architecture x86_64

    Describe the bug When compiling the showcase example on an Intel-based Macbook, it fails with the error "Undefined symbols for architecture x86_64." I know this has been reported in the past but it was for a different version of macOS and I didn't want to hijack another thread.

      = note: Undefined symbols for architecture x86_64:
                "_OBJC_CLASS_$_CHHapticDynamicParameter", referenced from:
                    objc-class-ref in libsdl2_sys-ee657edccdc41d23.rlib(SDL_mfijoystick.m.o)
                "_OBJC_CLASS_$_CHHapticEventParameter", referenced from:
                    objc-class-ref in libsdl2_sys-ee657edccdc41d23.rlib(SDL_mfijoystick.m.o)
                "_CHHapticDynamicParameterIDHapticIntensityControl", referenced from:
                    -[SDL_RumbleMotor setIntensity:] in libsdl2_sys-ee657edccdc41d23.rlib(SDL_mfijoystick.m.o)
                "_CHHapticEventParameterIDHapticIntensity", referenced from:
                    -[SDL_RumbleMotor setIntensity:] in libsdl2_sys-ee657edccdc41d23.rlib(SDL_mfijoystick.m.o)
                "_OBJC_CLASS_$_CHHapticPattern", referenced from:
                    objc-class-ref in libsdl2_sys-ee657edccdc41d23.rlib(SDL_mfijoystick.m.o)
                "_OBJC_CLASS_$_CHHapticEvent", referenced from:
                    objc-class-ref in libsdl2_sys-ee657edccdc41d23.rlib(SDL_mfijoystick.m.o)
                "_CHHapticEventTypeHapticContinuous", referenced from:
                    -[SDL_RumbleMotor setIntensity:] in libsdl2_sys-ee657edccdc41d23.rlib(SDL_mfijoystick.m.o)
              ld: symbol(s) not found for architecture x86_64
              clang: error: linker command failed with exit code 1 (use -v to see invocation)
    
    
    error: could not compile `orbtk` due to previous error
    

    To Reproduce Steps to reproduce the behavior:

    1. Clone this repo.
    2. Install sdl2 with Homebrew.
    3. Build the showcase example as described in the README, with or without the "bundled" feature.
    4. See error

    Expected behavior the build process to complete successfully

    Desktop:

    • OS: macOS Monterey
    • Version: 12.4
    • Darwin kernel version: 21.5.0
    • Architecture: x86_64

    Additional context

    • orbtk develop branch (68c67da8)
    • sdl2: stable 2.0.22 (installed by brew install sdl2)
    • Command Line Tools for Xcode 13.4

    I also tried export LIBRARY_PATH="$(brew --prefix)/lib" as suggested by the rust-sdl2 project but this made no difference.

    bug 
    opened by duffrecords 1
Releases(0.3.1-alpha3)
  • 0.3.1-alpha3(Aug 13, 2020)

    • Dynamic theme switch
    • Add all material font icons as resource
    • Replaces css-engine with custom Rust/Ron based theming
    • Add widget access helpers for states
    • API update check deprecated methods an replace to new ones
    • Performance improvements
    • Change state update order from tree order to incoming changes order
    • NumericBox widget
    • Update caret position on TextBox by mouse click
    • Text input support for ', /, , [, ], {, }
    • Multiple window support (experimental)
    • Pathfinder / Glutin backend (experimental)
    • ProgressBar widget
    • Measure distance between two Points
    • Improve: Mouse event arguments
    • Fix: Crash when a child widget is removed
    • TabWidget widget
    • Add on_changed property change callback to all widgets
    • OrbTk book (manual) wip
    Source code(tar.gz)
    Source code(zip)
  • 0.3.1-alpha2(Apr 22, 2020)

    • ComboBox / ComboboxItem widget
    • Slider widget
    • Popup widget
    • Overlay layer
    • Service registry for states
    • Settings service (serialize / deserialize data)
    • Direct access of states in callbacks
    • Impl RawWindowHandle for Context (wip)
    • Sent requests to window shell
    • Layout fixes and stack layout example
    • Many web fixes
    • State cleanup method
    • Refactor setting of styling selectors
    • TextBox select all (Ctrl + a)
    • Text input support for !, @, #
    • Borderless window
    Source code(tar.gz)
    Source code(zip)
Owner
Redox OS
A Rust Operating System
Redox OS
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
SixtyFPS is a toolkit to efficiently develop fluid graphical user interfaces for any display: embedded devices and desktop applications. We support multiple programming languages, such as Rust, C++ or JavaScript.

SixtyFPS is a toolkit to efficiently develop fluid graphical user interfaces for any display: embedded devices and desktop applications. We support multiple programming languages, such as Rust, C++ or JavaScript.

SixtyFPS 5.5k Jan 1, 2023
Cross-platform GUI toolkit written in Rust

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,

George Atkinson 166 Dec 13, 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 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
A cross-platform GUI toolkit in Rust

NXUI - Native X UI A cross-platform GUI toolkit in Rust NXUI is a GUI toolkit that calls OS native APIs as much as possible to achieve fast operation.

らて 11 Jun 3, 2022
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
A graphical user interface toolkit for audio plugins.

HexoTK - A graphic user interface toolkit for audio plugins State of Development Super early! Building cargo run --example demo TODO / Features Every

Weird Constructor 14 Oct 20, 2022
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
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
Rust bindings to Core Foundation and other low level libraries on Mac OS X and iOS

core-foundation-rs Compatibility Targets macOS 10.7 by default. To enable features added in macOS 10.8, set Cargo feature mac_os_10_8_features. To hav

Servo 685 Jan 2, 2023
Rust bindings for the FLTK GUI library.

fltk-rs Rust bindings for the FLTK Graphical User Interface library. The FLTK crate is a crossplatform lightweight gui library which can be statically

Mohammed Alyousef 1.1k Jan 9, 2023
Build beautiful desktop apps with flutter and rust. 🌠 (wip)

flutter-rs Build flutter desktop app in dart & rust. Get Started Install requirements Rust flutter sdk Develop install the cargo flutter command cargo

null 2k Dec 26, 2022
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
Rust bindings for Dear ImGui

imgui-rs: Rust bindings for Dear ImGui (Recently under new maintenance, things subject to change) Window::new(im_str!("Hello world")) .size([300.0

null 2k Jan 7, 2023
Clear Coat is a Rust wrapper for the IUP GUI library.

Clear Coat Clear Coat is a Rust wrapper for the IUP GUI library. IUP uses native controls and has Windows and GTK backends. A macOS backend has been o

Jordan Miner 18 Feb 13, 2021
Rust binding for IUP

IUP Rust This library provides a high level wrapper around IUP, a multi-platform toolkit for building graphical user interfaces. See rust-iup-sys for

David Campbell 41 May 28, 2022
A simple UI framework for Rust built on top of IUP (http://webserver2.tecgraf.puc-rio.br/iup/)

KISS-UI A UI framework for Rust based on the KISS (Keep It Simple, Stupid!) philosophy. Powered by the IUP GUI library for C by Tecgraf, via the bindi

null 342 Jul 11, 2022
Integrate Qml and Rust by building the QMetaObject at compile time.

QMetaObject crate for Rust The qmetaobject crate is a crate which is used to expose rust object to Qt and QML. Objectives Rust procedural macro (custo

Woboq GmbH 495 Jan 3, 2023