Coder Social home page Coder Social logo

orbtk's Introduction

OrbTk is Sunsetting

It is with great sadness that I announce that OrbTk is sunsetting. In the many years since I first made OrbTk, the Rust GUI ecosystem has grown at an amazing rate. Toolkits with more features have developed, and which are more actively maintained. I first created this project to bootstrap UI development on Redox OS. Many of the applications on Redox use OrbTk. @FloVanGH stepped in to do large refactoring between the 0.2 and 0.3 release, which modernized the OrbTk API. @rzerres stepped in to add many features and maintain OrbTk since the 0.3 release.

I have since moved on to working with iced. @FloVanGH has taken a job working on slint. And @rzerres has expressed interest in using slint for their projects. Both iced and slint provide renderer agnostic toolkits that will be compatible with Redox OS, but they also support more features than OrbTk. So, I have decided, with agreement from @rzerres, that OrbTk is to stop being actively maintained, in favor of these other Rust native toolkits.

-- Jeremy Soller

Original README

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

The next images are taken from example applications, that have been compiled for MacOS / OS-X.

  • The showcase example

showcase

  • Themed calculator examples

calculator_dark_macos calculator_light_macos calculator_redox

Other screenshots have been rendered from examples code, that is stored inside the orbtk crate.

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
  • Linux
  • macOS
  • Windows
  • openBSD (not tested, but should work)
  • Web (broken, will be fixed soon)
  • Android (wip, will be released soon)
  • iOS (wip, will be released soon)
  • Ubuntu Touch (on hold)

Planned features

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

Documentation

Build and open documentation

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

cargo doc --no-deps --open

OrbTk book

The OrbTk book is written from a developers perspective. It aims to introduce the basic concept, beside a bird's eye view of the toolkit structure. An in depth discussion of the provided crates is followed by example listings. This section collects example code with annotated blocks. The annotations are targeting best practice usage of available widgets, their interaction with other modules coupled with a descriptive text where reasonable.

A precompiled version is available for online reading. You are invited to checkout its repository at OrbTk book.

Please do not expect at finalized version. It is not complete at all. The given statis is marked as work in progress (WIP). Any help to improve the chapters and/or translations are quite welcome.

Usage

To include OrbTk as an external dependency into your project, add this line to its Cargo.toml file:

...
[dependencies]
...
orbtk = "0.3.1-alpha4"
...

To use the latest development version of OrbTk as an external dependency, add this line into its Cargo.toml file:

...
[dependencies]
...
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 structure and the default values that the widget will store in its properties. For example: You can define your hand-crafted Button widget (lets call it MyButton). MyButton is represented as a tree of three child widgets: A top level Container widget that will hand over to its child, the StackPanel widget, which in turn will hand over to its child, the TextBlock widget.

The next code snippet prints out the source code of this basic Template trait:

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

Widget State

Any changes that are triggered via user interaction or via events are handled inside the state of a widget. If generated, they are processed to manipulate the inner state. Each state must implement the State trait. The inner state of a widget is represented by the current values of its properties.

Have a look at this code snippet to make up a 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 update method requires a Context parameter. This structure provides access to the state's widget itself (the entity) and its components (the properties). It also provides methods (the associated functions) to access the children of the widget, this it is able 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
  • Reference resources values in the theme files (colors, font stuff)
  • Derive styles
  • Dynamic theme switching
  • State styling (pressed | selected | focused | disabled)

Have a look at this short style definition:

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,
	}
)

But you are not requested to reference a theme engine. OrbTk enables as well the declaraton of property values inside the source code (inlined theming).

Localization

OrbTk supports the functionality to register an 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 for an application. Simply make use of the RonLocalization, that can read localization dictionaries coded 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)
			.resizable(true)
			.child(TextBlock::new().text("hello").build(ctx))
			.build(ctx)
	})
	.run();

Inside this example code the text property (value hello) is used as the key. This key is matched to the correponding value inside the dictionary of the corresponding localization service. If you haven't defined a dictionary for the current language, OrbTk will simply take the value of the property itself. You are free to start development without and any localization, but add it afterwards.

You may switch the language at runtime. Inside the state widget you simply consume the set_language method, that is accessible via the Context structure.

Run Examples

Build with sdl2 installation

If your target Operating-System is Linux, macOS or Windows, a sdl2 installation is required. Please check the documentation that is provieded for th rust-sdk2 crate.

Build with sdl2 from source

As an alternative, you may build OrbTk while bundling sdl2. To activate the bundled feature go ahead like this:

cargo run --example showcase --features bundled

Please asure, that you toolchain will provide a working C compiler (e.g. gcc, clang, or MS's compiler).

To target linux, you also need to provide cmake:

sudo apt install cmake

If you have trouble build the provided OrbTk examples or simply don't want to use a C compiler, please check the backend section. It contains alternatives.

All example source-code resides inside the examples subdirectory of the orbtk subcrate.

Compile, start and play around with the showcase example while executing the following command:

cargo run --example showcase --release

OrbTk has an integrated debug tools. It will oultline the bounds of all managed widgets inside the widget tree. This will include invisible ones. You may also want to print out the tree structure of your app. This is activated, via feature flags like this:

cargo run --example showcase --release --features "debug, log"

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

cargo-node itself relies on npm version 6.9.0, which is included with Node.js version 10.16.3. You can download it from its homepage.

Rust's cargo is also required. All cargo-node's dependencies are installed automatically.

Start examples

To start the showcase example as a node binary, 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

crates structure

  • orbtk: sub-crate, that provides all needed components to build an OrbTk cross platform UI.
  • orbtk_core: sub-crate, that provides the core components of Orbtk (widget basics, tree handling, theming)
  • orbtk_orbclient: sub-crate, that handles cross platform aware window and event management. It is based on OrbClient.
  • orbtk_tinyskia: Wrapper methods that consumes the tiny-skia 2D rendering engine.
  • orbtk_widgets: sub-crate providing the standard OrbTk widget library and and theming support.

Inspirations

Showcases

Contribution

If you want to help and improve OrbTk submit your feedback via the issue tracker. All pull requests are welcome and will be reviewed. You can also discuss with other OrbTk developers via the Redox chat interface. Please join the orbtk channel.

Contribution check list

  • Please document for all your pub structs, traits and functions.
  • Please add suitable tests methods.
  • Use static &str for widget ids and new style definitions.
  • For widget development check ProgressBar or Slider as an example.
  • Add your changes inside CHANGELOG.md
  • Extend the example section to show consumption of your code.
  • Always run cargo fmt before uploading.
  • Please run cargo cippy before uploading.
  • Create the PR using our template.

License

Source-Code is licensed under MIT license (LICENSE).

© 2017-2022 Jeremy Soller
© 2018-2022 Florian Blasius

This documentation work is licensed under a Creative Common License 4.0

Creative Common Logo

© 2020-2022 Ralf Zerres

orbtk's People

Contributors

adminxvii avatar andreinbio avatar arctic-alpaca avatar blackle avatar emily avatar flovangh avatar hughlang avatar jackpot51 avatar jrmuizel avatar jsalzbergedu avatar keawade avatar kivimango avatar kod-kristoff avatar lazyoxen avatar learning avatar ltrlg avatar lukors avatar michalsieron avatar mjhouse avatar mmstick avatar polymetric avatar robbycerantola avatar rzerres avatar sandmor avatar trickypr avatar tshepang avatar uniformbuffer avatar valkum avatar xixixao avatar xtibor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

orbtk's Issues

Update failed because input buffer is too small

I just did a clone of the repo and typed: cargo run --example widgets

This was the result: Update failed because input buffer is too small. Required size for 956 x 1036 window (1x scale) is 3961664 bytes but the size of the input buffer has the size 1366560 bytes

This is the backtrace when run with export RUST_BACKTRACE=1:


λ ~/Projects/rust/orbtk/ develop cargo run --example widgets          
   Compiling autocfg v0.1.7
   Compiling libc v0.2.65
   Compiling semver-parser v0.7.0
   Compiling rand_core v0.4.2
   Compiling cfg-if v0.1.10
   Compiling byteorder v1.3.2
   Compiling lazy_static v1.4.0
   Compiling proc-macro2 v1.0.6
   Compiling unicode-xid v0.2.0
   Compiling syn v1.0.8
   Compiling proc-macro2 v0.4.30
   Compiling bitflags v1.2.1
   Compiling scopeguard v1.0.0
   Compiling unicode-xid v0.1.0
   Compiling siphasher v0.2.3
   Compiling crc32fast v1.2.0
   Compiling rayon-core v1.6.1
   Compiling syn v0.15.44
   Compiling adler32 v1.0.4
   Compiling unicode-xid v0.0.4
   Compiling quote v0.3.15
   Compiling arrayvec v0.4.12
   Compiling num-derive v0.2.5
   Compiling nodrop v0.1.14
   Compiling lzw v0.10.0
   Compiling maybe-uninit v2.0.0
   Compiling pkg-config v0.3.17
   Compiling either v1.5.3
   Compiling procedural-masquerade v0.1.6
   Compiling cc v1.0.47
   Compiling color_quant v1.0.1
   Compiling orbtk-utils v0.3.1-alpha2 (/home/patrick/Projects/rust/orbtk/crates/utils)
   Compiling scoped_threadpool v0.1.9
   Compiling matches v0.1.8
   Compiling arrayvec v0.5.1
   Compiling typed-arena v1.7.0
   Compiling sw-composite v0.7.2
   Compiling serde v1.0.103
   Compiling dces v0.2.0 (https://gitlab.redox-os.org/redox-os/dces-rust.git?branch=develop#fb2c2638)
   Compiling spin_sleep v0.3.7
   Compiling approx v0.1.1
   Compiling static_assertions v0.2.5
   Compiling semver v0.9.0
   Compiling rand_core v0.3.1
   Compiling rand_jitter v0.1.4
   Compiling num-traits v0.2.10
   Compiling crossbeam-utils v0.7.0
   Compiling crossbeam-epoch v0.8.0
   Compiling num-integer v0.1.41
   Compiling rand_pcg v0.1.2
   Compiling rand_chacha v0.1.1
   Compiling rand v0.6.5
   Compiling num-rational v0.2.2
   Compiling num-iter v0.1.39
   Compiling phf_shared v0.7.24
   Compiling inflate v0.4.5
   Compiling synom v0.11.3
   Compiling gif v0.10.3
   Compiling x11-dl v2.18.4
   Compiling orbtk-tree v0.3.1-alpha2 (/home/patrick/Projects/rust/orbtk/crates/tree)
   Compiling rustc_version v0.2.3
   Compiling rand_hc v0.1.0
   Compiling rand_isaac v0.1.1
   Compiling rand_xorshift v0.1.1
   Compiling phf v0.7.24
   Compiling syn v0.11.11
   Compiling minifb v0.13.0
   Compiling memoffset v0.5.3
   Compiling cast v0.2.3
   Compiling vek v0.9.11
   Compiling quote v1.0.2
   Compiling deflate v0.7.20
   Compiling stb_truetype v0.3.1
   Compiling base64 v0.10.1
   Compiling rand_os v0.1.3
   Compiling num_cpus v1.11.1
   Compiling time v0.1.42
   Compiling dirs-sys v0.3.4
   Compiling quote v0.6.13
   Compiling png v0.15.1
   Compiling crossbeam-queue v0.2.0
   Compiling euclid v0.20.4
   Compiling ordered-float v1.0.2
   Compiling approx v0.3.2
   Compiling num-traits v0.1.43
   Compiling dirs v2.0.2
   Compiling cssparser v0.17.0
   Compiling rusttype v0.8.2
   Compiling lyon_geom v0.14.1
   Compiling phf_generator v0.7.24
   Compiling raqote v0.7.6
   Compiling phf_codegen v0.7.24
   Compiling crossbeam-deque v0.7.2
   Compiling euc v0.4.2
   Compiling rayon v1.2.1
   Compiling jpeg-decoder v0.1.16
   Compiling tiff v0.3.1
   Compiling image v0.22.3
   Compiling cssparser-macros v0.3.6
   Compiling serde_derive v1.0.103
   Compiling derive_more v0.99.2
   Compiling orbtk-proc-macros v0.3.1-alpha2 (/home/patrick/Projects/rust/orbtk/crates/proc-macros)
   Compiling orbtk-render v0.3.1-alpha2 (/home/patrick/Projects/rust/orbtk/crates/render)
   Compiling orbtk-shell v0.3.1-alpha2 (/home/patrick/Projects/rust/orbtk/crates/shell)
   Compiling orbtk-css-engine v0.3.1-alpha2 (/home/patrick/Projects/rust/orbtk/crates/css-engine)
   Compiling orbtk-theme v0.3.1-alpha2 (/home/patrick/Projects/rust/orbtk/crates/theme)
   Compiling ron v0.5.1
   Compiling orbtk-api v0.3.1-alpha2 (/home/patrick/Projects/rust/orbtk/crates/api)
   Compiling orbtk-widgets v0.3.1-alpha2 (/home/patrick/Projects/rust/orbtk/crates/widgets)
   Compiling orbtk v0.3.1-alpha1 (/home/patrick/Projects/rust/orbtk)
    Finished dev [optimized + debuginfo] target(s) in 4m 13s
     Running `target/debug/examples/widgets`
UnexpectedToken(Number { has_sign: false, value: 16.0, int_value: None })
Error occured in `border-radius: 16.0;`
UnexpectedToken(Number { has_sign: false, value: 16.0, int_value: None })
Error occured in `border-radius: 16.0;`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: UpdateFailed("Update failed because input buffer is too small. Required size for 956 x 1036 window (1x scale) is 3961664 bytes but the size of the input buffer has the size 1366560 bytes")', src/libcore/result.rs:1165:5
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.37/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.37/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:76
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:60
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1030
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1412
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:64
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:196
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:210
  10: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:473
  11: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:380
  12: rust_begin_unwind
             at src/libstd/panicking.rs:307
  13: core::panicking::panic_fmt
             at src/libcore/panicking.rs:85
  14: core::result::unwrap_failed
             at src/libcore/result.rs:1165
  15: core::result::Result<T,E>::unwrap
             at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libcore/result.rs:933
  16: orbtk_shell::platform::WindowShell<A>::flip
             at ./crates/shell/src/minifb/mod.rs:274
  17: orbtk_shell::platform::ShellRunner<A>::run
             at ./crates/shell/src/minifb/mod.rs:331
  18: orbtk_api::application::Application::run
             at crates/api/src/application/mod.rs:234
  19: widgets::main
             at examples/widgets.rs:411
  20: std::rt::lang_start::{{closure}}
             at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libstd/rt.rs:64
  21: std::rt::lang_start_internal::{{closure}}
             at src/libstd/rt.rs:49
  22: std::panicking::try::do_call
             at src/libstd/panicking.rs:292
  23: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:80
  24: std::panicking::try
             at src/libstd/panicking.rs:271
  25: std::panic::catch_unwind
             at src/libstd/panic.rs:394
  26: std::rt::lang_start_internal
             at src/libstd/rt.rs:48
  27: std::rt::lang_start
             at /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libstd/rt.rs:64
  28: __libc_start_main
  29: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

I am a rust beginner, so I am not sure how to resolve this or what more info you need. Please let me know and I will provide it!

Theming support

This would provide more ability for customization. Themes could be stored in TOML files.

iOS support

Context

OrbTk applications should be run on the mobile operating system iOS.

Problem description & Solution

It should be possible to build, run and deploy OrbTk applications on iOS.

Suggestion: CheckBox

Create a CheckBox widget

Visually:
image

Example usage:

    let cb = CheckBox::new();
    cb
        .text("Start with Sunday")
        .checked(true) // Default false
        .checkbox_right(true) // For right side example, default false
        .on_checked_changed(... {
        
        });

Detailed UI

checkbox

HTML example (non interactive) of the above picture

Create layout managers

This would allow a developer to quickly put together an application without having to calculate positioning and could offload some of the resizing logic.

A widget could default to absolute positioning of child widgets if no layout is specified.

TabsWidget

Context

The TabWidget should be used in a navigation context.

Problem description & Solution

The TabWidget should be used to organize different content on different views. The content should be switched by select from a list of items.

Examples and MockUps

image

Drag 'n' Drop infrastructure (intern)

Context

Drag 'n' Drop should be used to move an widget (item) from one place to another.

Problem description & Solution

It should be possible to implement Drag 'n' Drop inside of an OrbTk application. To make it easier to implement such a feature a base infrastructure for intern Drag 'n' Drop should be integrated in OrbTk.

Make Windows closable

Currently there is no easy way to close a window after it has been opened, unless you implement the event loop yourself. I think there should be a close() function, that allows us to easily close the window again.

Unable to compile examples

I am not able to compile orbclient. I just keep getting errors saying that four features cannot be used on the stable release channel.

I'm running Pop!_OS, a variant of Ubuntu, and I've installed Rust 1.24.1 using the script over on rust-lang.org and installed SDL2 via apt install libsdl2-dev per the instructions.

What did I miss?

Here's my full output:

λ cargo run --example widgets               
    Updating registry `https://github.com/rust-lang/crates.io-index`
 Downloading orbclient v0.3.13                                                  
 Downloading lazy_static v0.2.11                                                
 Downloading orbfont v0.1.8                                                     
 Downloading cssparser v0.16.1                                                  
 Downloading orbimage v0.1.16                                                   
 Downloading rayon v0.8.2                                                       
 Downloading time v0.1.39                                                       
 Downloading rayon-core v1.4.0                                                  
 Downloading crossbeam-deque v0.2.0                                             
 Downloading num_cpus v1.8.0                                                    
 Downloading rand v0.4.2                                                        
 Downloading libc v0.2.39                                                       
 Downloading lazy_static v1.0.0                                                 
 Downloading crossbeam-utils v0.2.2                                             
 Downloading crossbeam-epoch v0.3.0                                             
 Downloading cfg-if v0.1.2                                                      
 Downloading arrayvec v0.4.7                                                    
 Downloading scopeguard v0.3.3                                                  
 Downloading nodrop v0.1.12                                                     
 Downloading memoffset v0.2.1                                                   
 Downloading rusttype v0.2.3                                                    
 Downloading linked-hash-map v0.5.1                                             
 Downloading stb_truetype v0.2.2                                                
 Downloading byteorder v1.2.1                                                   
 Downloading matches v0.1.6                                                     
 Downloading cssparser-macros v0.3.2                                            
 Downloading phf v0.7.21                                                        
 Downloading procedural-masquerade v0.1.5                                       
 Downloading syn v0.12.14                                                       
 Downloading quote v0.4.2                                                       
 Downloading proc-macro2 v0.2.3                                                 
 Downloading phf_codegen v0.7.21                                                
 Downloading unicode-xid v0.1.0                                                 
 Downloading phf_shared v0.7.21                                                 
 Downloading phf_generator v0.7.21                                              
 Downloading siphasher v0.2.2                                                   
 Downloading rand v0.3.22                                                       
 Downloading syn v0.11.11                                                       
 Downloading quote v0.3.15                                                      
 Downloading synom v0.11.3                                                      
 Downloading unicode-xid v0.0.4                                                 
 Downloading resize v0.2.0                                                      
 Downloading image v0.12.4                                                      
 Downloading jpeg-decoder v0.1.14                                               
 Downloading scoped_threadpool v0.1.9                                           
 Downloading num-rational v0.1.42                                               
 Downloading num-iter v0.1.35                                                   
 Downloading gif v0.9.2                                                         
 Downloading enum_primitive v0.1.1                                              
 Downloading num-traits v0.1.43                                                 
 Downloading png v0.6.2                                                         
 Downloading rayon v1.0.0                                                       
 Downloading either v1.4.0                                                      
 Downloading num-traits v0.2.1                                                  
 Downloading num-integer v0.1.36                                                
 Downloading color_quant v1.0.0                                                 
 Downloading lzw v0.10.0                                                        
 Downloading deflate v0.7.17                                                    
 Downloading inflate v0.1.1                                                     
 Downloading bitflags v0.7.0                                                    
 Downloading adler32 v1.0.2                                                     
 Downloading sdl2 v0.31.0                                                       
 Downloading num v0.1.42                                                        
 Downloading sdl2-sys v0.31.0                                                   
   Compiling rayon-core v1.4.0                                                  
   Compiling procedural-masquerade v0.1.5
   Compiling libc v0.2.39
   Compiling quote v0.3.15
   Compiling inflate v0.1.1
   Compiling lazy_static v0.2.11
   Compiling resize v0.2.0
   Compiling bitflags v0.7.0
   Compiling color_quant v1.0.0
   Compiling siphasher v0.2.2
   Compiling matches v0.1.6
   Compiling num-traits v0.2.1
   Compiling scopeguard v0.3.3
   Compiling scoped_threadpool v0.1.9
   Compiling lazy_static v1.0.0
   Compiling byteorder v1.2.1
   Compiling linked-hash-map v0.5.1
   Compiling adler32 v1.0.2
   Compiling cfg-if v0.1.2
   Compiling either v1.4.0
   Compiling lzw v0.10.0
   Compiling memoffset v0.2.1
   Compiling nodrop v0.1.12
   Compiling unicode-xid v0.0.4
   Compiling unicode-xid v0.1.0
   Compiling phf_shared v0.7.21
   Compiling rand v0.4.2
   Compiling num_cpus v1.8.0
   Compiling time v0.1.39
   Compiling sdl2-sys v0.31.0
   Compiling crossbeam-utils v0.2.2
   Compiling deflate v0.7.17
   Compiling stb_truetype v0.2.2
   Compiling arrayvec v0.4.7
   Compiling proc-macro2 v0.2.3
   Compiling synom v0.11.3
   Compiling phf v0.7.21
   Compiling gif v0.9.2
   Compiling num-integer v0.1.36
   Compiling num-traits v0.1.43
   Compiling syn v0.11.11
   Compiling crossbeam-epoch v0.3.0
   Compiling rusttype v0.2.3
   Compiling rand v0.3.22
   Compiling enum_primitive v0.1.1
   Compiling quote v0.4.2
   Compiling num-iter v0.1.35
   Compiling num-rational v0.1.42
   Compiling phf_generator v0.7.21
   Compiling num v0.1.42
   Compiling phf_codegen v0.7.21
   Compiling crossbeam-deque v0.2.0
   Compiling syn v0.12.14
   Compiling png v0.6.2
   Compiling sdl2 v0.31.0
   Compiling rayon v0.8.2
   Compiling rayon v1.0.0
   Compiling cssparser v0.16.1
   Compiling orbclient v0.3.13
error[E0554]: #![feature] may not be used on the stable release channel
 --> /home/keawade/.cargo/registry/src/github.com-1ecc6299db9ec823/orbclient-0.3.13/src/lib.rs:3:1
  |
3 | #![feature(alloc)]
  | ^^^^^^^^^^^^^^^^^^

error[E0554]: #![feature] may not be used on the stable release channel
 --> /home/keawade/.cargo/registry/src/github.com-1ecc6299db9ec823/orbclient-0.3.13/src/lib.rs:4:1
  |
4 | #![feature(asm)]
  | ^^^^^^^^^^^^^^^^

error[E0554]: #![feature] may not be used on the stable release channel
 --> /home/keawade/.cargo/registry/src/github.com-1ecc6299db9ec823/orbclient-0.3.13/src/lib.rs:5:1
  |
5 | #![feature(const_fn)]
  | ^^^^^^^^^^^^^^^^^^^^^

error[E0554]: #![feature] may not be used on the stable release channel
 --> /home/keawade/.cargo/registry/src/github.com-1ecc6299db9ec823/orbclient-0.3.13/src/lib.rs:6:67
  |
6 | #![cfg_attr(all(not(feature="no_std"), not(target_os = "redox")), feature(const_ptr_null_mut))]
  |                                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 4 previous errors

error: Could not compile `orbclient`.
warning: build failed, waiting for other jobs to finish...
error: build failed

SVG Icon Widget

SVG Icons

SVG Icons can be used where possible. PNG will have to be available as a fallback.
SVG has obvious benefits, but it has a LOT of features. For Icons, basic SVG support should be fine.
Line works well, however I have sometimes seen compatibility issues appear with gradients and drop shadows.

It would be nice to have animated Icons, but I believe we should stay away from SVG animation. We can probably find a better solution using a Widget.

Notes Regarding the SVG Standard

The SVG standard is quite comprehensive. Implementations of the standard seems to list the features they don't support more often than the features that they do.

There is the SVG 1.1 Spec
https://www.w3.org/TR/SVG11/text.html

And the SVGTiny 1.2 Spec
https://www.w3.org/TR/SVGTiny12/

And then the SVG 2.0 Spec
https://svgwg.org/svg2-draft/

There is a W3C taskforce studying how to better unify CSS and SVG.
https://www.w3.org/Graphics/fx/wiki/Main_Page

Examples

Here is a Rust library that implements the Full Static Subset of the SVG 1.1 Standard.
https://github.com/RazrFalcon/resvg

@FloVanGH metioned raqote as a solution, since OrbTk already uses it, resvg also uses it, so it seems to be the way forward.

Drag 'n' Drop infrastructure (extern)

Context

Drag 'n' Drop should be used to move an content system GUI wide from one place to another .

Problem description & Solution

It should be possible to implement Drag 'n' Drop between an OrbTk application and the rest of GUI applications of system. To make it easier to implement such a feature a base infrastructure for extern Drag 'n' Drop should be integrated in OrbTk.

Suggestion: Documentation

A documentation (Readme and rustdoc) should support novice by starting with orbtk or orbtk base application development.

When widgets overlap, clicks register on both widgets

Steps to reproduce:

  1. Run widgets example
  2. Click Multi-Line Text widget to focus on it
  3. Open menu and click "Reset Label" while mouse cursor is also over the text box

Expected behavior:
Label resets, but focus remains on the Multi-Line Widget.

Actual behavior:
Label resets, but focus moves to the text box

This was tested on Ubuntu. I'm not sure if this behavior is intentional, but it can make using drop down menus difficult because menu clicks will also affect what's underneath them.

Examples initially load with black screen

Describe the bug
When running any of the examples, the window will load as a black screen until clicking into it. Clicking into the image example does not display the image though, so it may be related to an animation or something.

To Reproduce
Steps to reproduce the behavior:

  1. run cargo run --release --example calculator
  2. window is black
  3. click anywhere in the window
  4. calculator elements now appear

Expected behavior
Window elements should be loaded initially.

Desktop (please complete the following information):

  • OS: Manjaro Linux
  • Rust version: 1.39
  • Orbtk version: master (hash 40d28c8)

Text resizing

Describe the bug
When resizing a window, the text block font size also changes.

To Reproduce
Start the "My first OrbTk app".
Resize the window.

Expected behavior
The window should resize, but the content should remain in tact.

Screenshots
large
small
These screenshots show the large window and the smaller (resized) window. In the latter the text is not readable anymore.
Also note the destortion. The bug report for this issue is already provided at #105 (or at least seems similar to that issue).

Desktop (please complete the following information):

  • OS: MacOS Catalina

Deprecation and Build Failing

The function char_range_at used in text_box.rs has been deprecated as of Rust 1.9 which is the cause of the current builds in both OrbTK and OrbUtils failing.

The recommended solution according to the documentation link above is to use a combination of the chars() and len_utf8() functions.

I am currently working on a few possible solutions on my fork but have been running into a strange issue where the cursor does not move along as you type, thus typing backwards.

Doesn't work well with i3wm

I haven't tried other window managers, but at least on i3, windows created with orbtk are floating, rather than tiling. This is unexpected, as the default state is tiled for most other applications

Ubuntu Touch support

Context

OrbTk applications should be run on the mobile operating system Ubuntu Touch https://ubports.com/.

Problem description & Solution

It should be possible to build, run and deploy OrbTk applications on Ubuntu Touch.

Examples and MockUps

image

load external font

Context

currently orbtk uses the built-in Roboto font, and it is load using register_font in Application::new().window(), but it looks like there is no way to add fonts from the external and skip built-in font loading

Problem description & Solution

built-in font do not contain CJK characters, need a way to load font from outside

Examples and MockUps

load parameter font from window widget?

        let font = world
            .entity_component_manager()
            .component_store()
            .get::<HashMap<String, PathBuf>>("font", window)
            .unwrap()
            .clone();
        for (name, path) in font {
            window_shell
                .borrow_mut()
                .render_context_2_d()
                .register_font(&name, path);
        }

Visibility enum

orbtk should provide a visibility enum for widgets. By Visibility::Visible the widget should be drawn, by Visibility::None it should not be drawn and by Visibility::Collapsed it shouldn’t be drawn andit should shrink to with/height = 0.

Text box doesn't filter numbers

In the example in examples/filtered.rs, one of the textbox is supposed to filter characters that aren't numbers but it isn't the case.

Click events

Did you know, that click event consists of mouse down and mouse up in one (small) spot?

I've just looked in the Button widget code, and I've got a heart attack :)

Focus and Redraw Systems

The current system of determining focus and determining if an widget needs a redraw is really problematic. It is convoluted and almost unreadable, as well as just being poor code:

let mut redraw = false;
for event in events.iter() {
    for i in 0..self.widgets.borrow().len() {
        if let Some(widget) = self.widgets.borrow().get(i) {
            if widget.event(*event, self.widget_focus.get() == i, &mut redraw) {
                if self.widget_focus.get() != i {
                    self.widget_focus.set(i);
                    redraw = true;
                }
            }
        }
    }
}

if redraw {
    self.draw();
}

Iterating through the list of widgets with the widget_focus field on the Window struct as the index of the focused widget is bad form. And using the redraw variable in that way is strange to say the least.

The issues with this system is primarily that a widget cannot be redrawn without stealing focus. the self.widget_focus.set(i) immediately sets the focus to be the widget that needs a redraw. Additionally the draw() function on the Window struct has semi-redundant code:

for i in 0..self.widgets.borrow().len() {
    if let Some(widget) = self.widgets.borrow().get(i) {
        widget.draw(&mut renderer, self.widget_focus.get() == i);
    }
}

The focus and redraw systems need to be separated out. A containers based focus and redraw systems would also go well with #10.

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...

Add a function to close a window.

Title is sloppy, I couldn't come up with any better.

I want to create a button inside the window that closes the same window, how. I can't see a way to do it as of now.

Android support

Context

OrbTk applications should be run on the mobile operating system Android https://www.android.com.

Problem description & Solution

It should be possible to build, run and deploy OrbTk applications on Android.

Suggestion: Styleguide

A styleguide should help to provide a consistent look and feel in redox and orbtk. It could be provided as part of the rustdoc or as extra web page.

The styleguide should contains following components:

  • Color-Overview
  • Font-Overview: Fonts, Sizes, Weights, ...
  • Control-Overview
  • Icon-Overview

Grid upgrade

I'm missing some functionality

  • clear() - remove all entries
  • remove(i, j) remove element at position
  • columns(n) - define how many columns there should be in a row
  • add(widget) - works together with columns, instead of calculating a position in a grid you just add elements and they are put in place.

Label default sizes

Similar to Button suggestion, Label needs default size as well.

Current usage

let l = Label::new();
let text = "Hello world";
l
    .text(text)
    .size(text.len() as u32 * 8, 16)
    .position(50, 80);

After having default sizes

let l = Label::new();
l
    .text("Hello world")
    .position(50, 80);

Switching desktop issue

Describe the bug
When starting an orbTK application, then change desktop, the orbTk application becomes black. It will only update upon a trigger (clicking a button or resizing the window).
Note that clicking a button while not seing the button is a real challenge

To Reproduce
Steps to reproduce the behavior:

  1. Start application
  2. Switch to other desktop
  3. Switch back to the desktop on which the application was started

Expected behavior
The original widgets and colors should be rendered when switching back to the desktop.

Screenshots
The screenshot shows the same application started twice. Both where black when switching back to the desktop, but I clicked a button on the right application.

Screenshot_2019-12-06_11-07-08

Note; there is also a black square on the right image, this is where the screenshot application was just before taking the screenshot.

Desktop (please complete the following information):
I am on ArchLinux

λ ~/ uname -a
Linux copernicus 5.3.13-arch1-1 #1 SMP PREEMPT Sun, 24 Nov 2019 10:15:50 +0000 x86_64 GNU/Linux

I run Xfce4 with i3 as wm on Xorg with Intel:

  • xf86-video-intel 1:2.99.917+897+g0867eea6-
  • extra/xorg-server 1.20.6-1
  • xfce4 4.14.0-1
  • i3-wm 4.17.1-1

Always On Top Button

Always on Top, great for utility apps

A user wants to have one window/widget/application always be on top of other windows.

Current Window behaviour switches between windows (as expected)

If a Always On Top Button is added to a window, it might be great for apps like the Calculator, that the user will always want to keep on top when doing repetitive tasks.

Discussion Points

There will probably have to be a caveat where only one window can be marked as always on top?

Otherwise more than one window can be marked as always on top, and they then join a second layout group where they all behave as expected. (Focus switching between windows)

Layouts incorrect for stacks within stacks

Given the following application with a vertical stack containing three horizontal stacks, the layout is getting calculated strangely, which causes it to render like so:

image

use orbtk::prelude::*;

fn main() {
    Application::new()
        .window(|ctx| {
            let container = Stack::create()
                .vertical_alignment(Alignment::Stretch)
                .orientation(Orientation::Vertical)
                .child(
                    Stack::create()
                        .margin(4)
                        .orientation(Orientation::Horizontal)
                        .child(TextBlock::create().text("First").build(ctx))
                        .build(ctx)
                )
                .child(
                    Stack::create()
                        .margin(4)
                        .orientation(Orientation::Horizontal)
                        .child(TextBlock::create().text("Second").build(ctx))
                        .build(ctx)
                )
                .child(
                    Stack::create()
                        .margin(4)
                        .orientation(Orientation::Horizontal)
                        .child(TextBlock::create().text("Third").build(ctx))
                        .build(ctx)
                )
                .build(ctx);

            Window::create()
                .title("test")
                .position((100.0, 100.0))
                .size(300.0, 300.0)
                .child(container)
                .build(ctx)
        })
        .run();
}

**Copied from GitLab board (created by @mmstick)

Enabled flag

It should be possible to enable / disable widgets like button.

Suggestion: ComboBox

combobox

Example use

let combo_box = ComboBox::new();
list.position(5, 5).size(266, 28);

for i in 0..5 {
    let item = ComboBoxItem::new(format!("Item {}", i));
    combo_box.push(&item);  
} 

SDF (Signed Distance Field) Support

SDF advantages and use cases

TLDR: SDF Renders crisp imagery and text, and provides a lot of flexibility for later use, especially with Localization and Fonts.

SDF, simply put, generates a vector representing a given raster image.
This is great for the rendering of icons at any size, since the derived SDF is really small and can be rendered (Reconstructed) at any size.

See this for a way greater explanation, and crate 📦

SDF has great uses with fonts as well, and a great use is TextMeshPro in Unity3D.
It generates SDF's from fonts, given Unicode Ranges.
The creator Stephan B. shows it off here
The greatest feature of this for me is the fallback fonts which easily allows Missing Unicode Chars to drop through a Table of alternative fonts until a suitable Char is found. No more 𖡄𖡄𖡄 missing stuff in your UI's and input fields with Eastern Char Sets.

This is a great read by Joel Spolsky on The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets

Display Sizes and Resolution

Given the plethora of screen and devices out there, designers generally have to choose between a series of PNG images for all sizes (64x64, 128x128, 256x256 etc etc) or to use SVG.

SDF can alleviate some of that pain and bring some flexibility to the rendering capabilites of OrbTk, with a Single file, rendered at scale on demand.

Localization Advantages

There are real dangers to assuming that the char input we just received has to go after the char we just made. Or even making assumptions regarding the concept of 'baseline' when it comes to Text

These are the 'baselines' in Thai:
Thai word construction

For example, consider input has no spaces in written Thai or Laotian. Phrase:

เลขหมายที่ท่านเรียกยังไม่เปิดให้บริการ -> The number you are trying to call is not in service.

You only know where the word boundaries are, based on the rules of the Thai Language.
So when the user presses the Enter or Return key, you CANNOT simply enter a line break, or hyphenate the word, you have to find the word boundary according to the rules of where Vowels and Consonants belong. Some Consonants go in front of the preceding vowel, but only sometimes, based on the Vowel!

So, having a flexible soltion for rendering crisp chars, individually, that can be moved scaled etc etc. is quite attractive, even if it is just sparing us the headache down the line when Redox and Orbital runs everything, everywhere, one day.

KeyEvents pressed flag

The orbtk KeyEvent is missing a pressed flag. The KeyEvents should also be added to the events of window by key release.

What is the OrbTk way to Localization

I am new to Rust and OrbTk, so I am trying to figure out how to use it, documentation from cargo doc is sparse, so I can only assume you have not got that far, or have not revealed your plans in a place I could find, so as far as integrating Localization into the framework, I do not know if you have any plans at this time, but I am sure you have thought about it, leaving it up to the user to localize all their text is one option I am not really a fan of.

Not sure where this is going:
https://internals.rust-lang.org/t/pre-rfc-localization-for-rustdoc/3190/5
but it would seem that rust is looking at doing this using comments,
or tags, then using something like cargo or rustc that parses the file extracting the elements,
which is what my thoughts were also,
but that is just how to populate the po,
and the debate over i18 or i20,
and not how to implement it,
and why I like the idea of building into the framework,
whereas most people are waiting to see what rust will do, it only makes sense to implement it one way, instead of having OrbTk apps run differently, or have to be implemented differently.

Suggestion: Container

Container

With three different layouts: Stack, Absolute, and Dock.

Stack layout would be the default, with top to bottom orientation.

These ideas are inspired by Cascades Container and Kivy Layouts.

Stack

image

let outer = Container::new();
outer
    .size(300, 300)
    .layout(StackLayout::new(LayoutOrientation::TopToBottom)) // TopToBottom, LeftToRight, RightToLeft, BottomToTop
    .border(true);

let c1 = Container::new();
c1
    .size(300, 60)
    .background(Color::rgb(255, 0, 0));

let c2 = Container::new();
c2
    .size(300, 60)
    .background(Color::rgb(0, 255, 0));

let c3 = Container::new();
c3
    .size(300, 60)
    .background(Color::rgb(0, 0, 255));
    
outer.add(&c1);
outer.add(&c2);
outer.add(&c3);

Absolute

image

let outer = Container::new();
outer
    .size(300, 300)
    .layout(AbsoluteLayout::new());
    .border(true);

let c1 = Container::new();
c1
    .size(120, 60)
    .layoutProperties(AbsoluteLayoutProperties::new(40, 20)) // x and y of c1, relative to outer container
    .background(Color::rgb(255, 0, 0));

let c2 = Container::new();
c2
    .size(120, 60)
    .layoutProperties(AbsoluteLayoutProperties::new(150, 80))
    .background(Color::rgb(0, 255, 0));

let c3 = Container::new();
c3
    .size(120, 60)
    .layoutProperties(AbsoluteLayoutProperties::new(220, 160))
    .background(Color::rgb(0, 0, 255));
    
outer.add(&c1);
outer.add(&c2);
outer.add(&c3);

Dock

image

let outer = Container::new();
outer
    .size(300, 300)
    .layout(DockLayout::new());
    .border(true);

let c1 = Container::new();
c1
    .size(120, 60)
    .layoutProperties(
        DockLayoutProperties::new()
            .horizontal(HorizontalAlignment::Left)
            .vertical(VerticalAlignment::Top)
    )
    .background(Color::rgb(255, 0, 0));

let c2 = Container::new();
c2
    .size(120, 60)
    .layoutProperties(
        DockLayoutProperties::new()
            .horizontal(HorizontalAlignment::Right)
            .vertical(VerticalAlignment::Center)
    )
    .background(Color::rgb(0, 255, 0));

let c3 = Container::new();
c3
    .size(120, 60)
    .layoutProperties(
        DockLayoutProperties::new()
            .horizontal(HorizontalAlignment::Center)
            .vertical(VerticalAlignment::Bottom)
    )
    .background(Color::rgb(0, 0, 255));
    
outer.add(&c1);
outer.add(&c2);
outer.add(&c3);

Other features

You should be able to:

  • add border color
  • add border width
  • add border radius
  • add background color
  • add padding
  • detect clicks
  • allow/stop click propagation

Features not covered:

  • Child getting width/height from their parent (to fill)
  • Children filling parent (Stack layout) with different widths. Such as 1, 1, 1 = (1/3 + 1/3 + 1/3), or 1, 2, 1 = (1/4, 1/2, 1/4). Similar to Bootstrap 4 grid or Android weight.
  • Docking elements to each other (such as c2 to be next to c1 on the right)

All widgets would have layoutProperties to position them inside a Container.

This is similar to #10

Code examples are most probaby not syntactically correct. Suggestions and opinions welcome.

Button default sizes

By default, Button has no size or text offset. We should provide defaults if those are not set, so you don't need to set them every time. It would also help with having a "standard" button size in all apps.

I suggest the following:

  • Button height: 35px
  • Text offset: 11px
  • Button width depends on text

button-defaults

This is current implementation

        let b = Button::new();
        let text = "Hello world";
        b
            .text(text)
            .size(11 + text.len() as u32 * 8 + 11, 35)
            .position(50, 80)
            .text_offset(11, 11);

After this change it would only be

        let b = Button::new();
        b
            .text("Hello world")
            .position(50, 80);

Animations

Context

At the moment visual appearance is very static. Visual elements could also be in motion by user input e.g. move the scroll bar. What is needed is the possibility to move visual elements from code. This would make the appearance of an OrbTk more attractive and give us the possibility to direct the view of an user to important elements on a view.

Problem description & Solution

It should be possible to animate numeric values of widgets like position, size, rotation and colors.
It should be possible to define a duration in ms and an easing curve for each animation.

Rewrite of the system event system

Here my suggestion for a new system event system:

Event capture

Events should be only captured by widgets, that are interested in the event. e.g. mouse events should be only propagate to widgets, that contains the current mouse position.

Propagation

Propagate events from root to leaf (tunnelling / preview events) and than back from leaf to root (bubbling). Events could be interrupted with event.handled = true.

http://csharphelper.com/blog/2015/03/understand-event-bubbling-and-tunneling-in-wpf-and-c/

Default set of event functions for system events

The widget trait should provide for each system event type (mouse, key, resize, ...) a separate function. The default implementation should do nothing. Each widget that is interested in a particular event could be override the corresponding function. After that there is no need to write complex event match statements in each widget.

Example

pub trait Widget {
    fn preview_mouse_down(event: MouseEvent) {}
    fn mouse_down(event: MouseEvent){}
    fn preview_key_pressed(event: KeyEvent) {}
    fn key_pressed(event: KeyEvent) {}
    ...
}

impl Widget for Button {
    fn mouse_down(event: MouseEvent) {
        // do something
        event.handled = true;
   }
}

Handled flag

Each event should provide a handled flag. If the flag is set to true the propagation of the event should stop. The flag should be set from the widget, that handles the event. This should be solve #44.

Additional

A combination with event aggregation or similar to handle custom "user" event should be possible.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.