Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kud1ing/guiver
GUI programming with Rust
https://github.com/kud1ing/guiver
gui guiver immediate-mode rust rust-lang widget-library
Last synced: 3 months ago
JSON representation
GUI programming with Rust
- Host: GitHub
- URL: https://github.com/kud1ing/guiver
- Owner: kud1ing
- License: apache-2.0
- Created: 2022-07-24T10:05:48.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-03-01T05:44:38.000Z (11 months ago)
- Last Synced: 2024-08-01T16:52:23.512Z (6 months ago)
- Topics: gui, guiver, immediate-mode, rust, rust-lang, widget-library
- Language: Rust
- Homepage:
- Size: 469 KB
- Stars: 13
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# guiver
guiver tries to make GUI programming with Rust simple, but perhaps without perfect efficiency.
guiver can be used in [immediate mode](https://en.wikipedia.org/wiki/Immediate_mode_(computer_graphics)), which is
inspired by [egui](https://github.com/emilk/egui). In this case it is
just a thin wrapper around [druid-shell](https://github.com/linebender/druid/tree/master/druid-shell) for event
handling/windowing and [Piet](https://github.com/linebender/piet) for rendering.There are [retained mode](https://en.wikipedia.org/wiki/Retained_mode) widgets that can be used with the help of an
optional widget manager.
The widgets are decoupled from the application data via message passing. This is inspired by
[Tk commands](https://www.tcl.tk/man/tcl/TkCmd/contents.html) and egui.
The widget size constraint system and some layout widgets are influenced by [Flutter](https://flutter.dev).The [example code](guiver-piet/examples/) may appear a bit verbose.
On the upside you get simple setup and simple control flow.## Status
* Operating systems:
* macOS: tested intensively
* Windows: works in general, probably has rough edges
* other: testers are welcome
* Widget manager:
* handles widget lifetimes
* handles a main widget
* handles widget focussing – including tab order
* handles copy/paste
* Widgets:
* Button
* Hyperlink
* Placeholder
* Text
* TextInput
* Layout widgets:
* Center
* Column
* Expanded
* Grid
* Padding
* Row
* SizedBox## Developer guide
Widgets are decoupled from the developers code via the `WidgetManager`. It owns the widgets and manages their lifetimes.
Widgets are created via `new_*()` methods and are modified and composed via `Command`s.
Commands allow transactional modification, where a re-layout happens once at the end.Widgets implement the `Widget` trait. The methods can be used by the `WidgetManager` and by other widgets (e.g. the
`TextInput` widget contains a `Text` widget).
A widget reacts to user `Event`s and possibly creates `WidgetEvent`s accordingly.
The developer code can handle those widget events.## Backlog
* `guiver-wasm`:
* [ ] add `WidgetManager`* [ ] `guiver-piet`: bundle the `Command`s per `WidgetId`: add `Command::ToWidget>`
* [ ] add `WidgetCommand`* `guiver-piet`: unify widgets:
* [ ] add `fn core(&self) -> &WidgetCore` to `PietWidget` or `Widget`?
* [ ] add a method to return an iterator over th child widgets
* [ ] default implement `PietWidget::paint()` using `core()` and the child widgets iterator yielding method* [ ] `guiver-piet`: add support to `PietWidget` for the concept of layers/z-order for dropdown boxes, tooltips etc.
* [ ] how?
* Druid: [`PaintCtx::paint_with_z_index()`](https://docs.rs/druid/latest/src/druid/contexts.rs.html#735-746)* add selectors:
* [ ] add `Command::SetClass(Option)`
* [ ] add `WidgetSelector`:
* `All`
* `WithId(WidgetId)`
* `ChildrenOf(WidgetId)`
* `ParentOf(WidgetId)`
* [ ] use it in
* [ ] `Command::Destroy`
* [ ] `Command::RemoveChild`
* [ ] remove `Command::RemoveChildren`
* [ ] `Command::RemoveEventObservation`
* [ ] `Command::AddEventObservation`
* [ ] `Command::SetDebugRendering`
* [ ] `Command::SetFill`
* [ ] `Command::SetFont`
* [ ] `Command::SetHorizontalAlignment`
* [ ] `Command::SetIsDisabled`
* [ ] `Command::SetIsHidden`
* [ ] `Command::SetStroke`
* [ ] `Command::SetValue`
* [ ] `Command::SetVerticalAlignment`
* [ ] add `Widget::class() -> Option`
* [ ] implement in `Core`
* [ ] add `WidgetSelector::WithClass(C)`* [ ] sketch a WASM backend?
* [ ] sketch a `cacao` backend?
* [ ] sketch a `egui` backend?* `guiver-piet`: text:
* `test_selected_text_replaced()`:
* [ ] fix
* [ ] add a test case using umlauts
* [ ] `test_selected_text()`: add a test case using umlauts
* [ ] `test_text_inserted()`: implement
* add a test case using umlauts
* [ ] `TextInput::set_selected_value()`: implement
* determine the graphical positions:
* [TextLayout::hit_test_text_position(())](https://docs.rs/druid/latest/druid/piet/trait.TextLayout.html#tymethod.hit_test_text_position)
* [HitTestPosition](https://docs.rs/druid/latest/druid/piet/struct.HitTestPosition.html)
* [ ] text cursor
* [ ] text selection
* [ ] `paint()`: paint the cursor
* [ ] `paint()`: paint the text selection
* [ ] `TextInput::handle_event()`: adjust the text cursor on arrow left/right
* [ ] `TextInput::handle_event()`: adjust the text selection on Shift + arrow left/right
* [ ] `TextInput::update_caret_character_index()`: implement
* [ ] `TextInput`: Meta+X should cut the selected text
* [ ] `TextInput`: if a text is too large to fit in, the size of the text input should not increase but truncate
* [ ] `TextInput::handle_event()`: select the whole text on double click* [ ] `guiver-piet`: add support for scrolling
* [ ] how?* [ ] `test::widgets_layout()`: add remaining layout widgets
* [ ] `test::widgets()`: add child widgets to the layout widgets* [ ] move `WidgetManager::focused_widget` to `WidgetFocusOrder`?
* [ ] publish 0.1.1, once the updated `druid-shell` >0.7.0 is [released](https://github.com/linebender)
* [ ] make `Text` selectable:
* [ ] via double click
* [ ] how?
* [ ] via click + drag
* [ ] add `WidgetCore::is_disabled`?
* makes sense for non-layout widgets:
* `Button`
* `Hyperlink`
* `Text`
* `TextInput`
* [ ] does it make sense for layout widgets?
* [ ] should they pass the command down to its child widgets?
* [ ] `Widget`: remove `flex_factor()`?
* Pro:
* for `Grid` it needs to be held externally (`GridColumnProperties`, `GridRowProperties`)
* Cons:
* does it make usage of `Column`, `Row` less pleasant?
* [ ] should all container widgets clip the child widget's painting?
* Pro:
* restricts misbehaving widgets paint
* Con:
* performance impact if clipping is unnecessary?
* add integration tests:
* `widgets()`:
* [ ] add `Column`
* [ ] add `Padding`
* [ ] add `Row`
* add for `Column`:
* [ ] `test_apply_size_constraints()`
* [ ] `test_handle_command()`
* [ ] `test_handle_event()`
* add for `Row`:
* [ ] `test_apply_size_constraints()`
* [ ] `test_handle_command()`
* [ ] `test_handle_event()`
* add for `Center`:
* [ ] `test_apply_size_constraints()`
* [ ] `test_handle_command()`
* [ ] `test_handle_event()`
* add for `Padding`:
* [ ] `test_apply_size_constraints()`
* [ ] `test_handle_command()`
* [ ] `test_handle_event()`
* add unit tests:
* add for `Button`:
* [ ] `test_apply_size_constraints()`
* [ ] `test_handle_command()`
* [ ] `test_handle_event()`
* add for `Placeholder`:
* [ ] `test_handle_command()`
* [ ] `test_handle_event()`
* add for `Text`:
* [ ] `test_handle_command()`
* [ ] `test_handle_event()`
* add for `TextInput`:
* [ ] `test_apply_size_constraints()`
* [ ] `test_handle_command()`
* [ ] `test_handle_event()`
* [ ] add a `Table` widget
* [ ] example `layout_expanded_row_column.rs`: make the row not grab all height
* [ ] all layout widgets need to clip too big child widgets
* [ ] add layout widget `Stacked` + `Positioned`
* [ ] `Hyperlink`: make it possible to remember/pass "was visited" status across widget lifetimes
* support text selection:
* [ ] Shift + cursor movement
* [ ] Meta+A
* [ ] support Drag and drop
* `druid-shell` has [no support](https://github.com/linebender/druid/issues/1742)
* [ ] implement [7GUIs](https://eugenkiss.github.io/7guis/tasks)
* [ ] 7GUIs "Flight Booker"
* [ ] implement `DropdownBox` (needs 2 layers)
* [ ] 7GUIs "Timer"
* [ ] 7GUIs "CRUD"
* [ ] 7GUIs "Circle Drawer"
* [ ] 7GUIs "Cells"
* [ ] optimize: do not paint on every event. Make the widgets request the repaint in a region/Rect
* [ ] add Redmond 31 widgets?
* [ ] add Python bindings?
* [ ] provide wrappers to native widgets?
* [ ] provide a WebAssembly demo
* [ ] consider decoupling from druid-shell/pietSee also ["So you want to write a GUI framework"](https://www.cmyr.net/blog/gui-framework-ingredients.html)
## License
Licensed under either of
* Apache License, Version 2.0 ([LICENSE-APACHE](guiver-piet/LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](guiver-piet/LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you shall be dual licensed as above, without any
additional terms or conditions.