{"id":13478202,"url":"https://github.com/kud1ing/guiver","last_synced_at":"2025-03-27T07:30:52.665Z","repository":{"id":49319605,"uuid":"517287129","full_name":"kud1ing/guiver","owner":"kud1ing","description":"GUI programming with Rust","archived":false,"fork":false,"pushed_at":"2024-03-01T05:44:38.000Z","size":480,"stargazers_count":13,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-30T11:42:00.423Z","etag":null,"topics":["gui","guiver","immediate-mode","rust","rust-lang","widget-library"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kud1ing.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-24T10:05:48.000Z","updated_at":"2024-02-17T17:18:56.000Z","dependencies_parsed_at":"2024-01-16T06:18:48.742Z","dependency_job_id":"e32691c8-0476-4ce1-ac4d-80f3bc615865","html_url":"https://github.com/kud1ing/guiver","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kud1ing%2Fguiver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kud1ing%2Fguiver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kud1ing%2Fguiver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kud1ing%2Fguiver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kud1ing","download_url":"https://codeload.github.com/kud1ing/guiver/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245802270,"owners_count":20674625,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gui","guiver","immediate-mode","rust","rust-lang","widget-library"],"created_at":"2024-07-31T16:01:53.924Z","updated_at":"2025-03-27T07:30:52.147Z","avatar_url":"https://github.com/kud1ing.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# guiver\n\nguiver tries to make GUI programming with Rust simple, but perhaps without perfect efficiency.\n\nguiver can be used in [immediate mode](https://en.wikipedia.org/wiki/Immediate_mode_(computer_graphics)), which is\ninspired by [egui](https://github.com/emilk/egui). In this case it is\njust a thin wrapper around [druid-shell](https://github.com/linebender/druid/tree/master/druid-shell) for event\nhandling/windowing and [Piet](https://github.com/linebender/piet) for rendering.\n\nThere are [retained mode](https://en.wikipedia.org/wiki/Retained_mode) widgets that can be used with the help of an\noptional widget manager.\nThe widgets are decoupled from the application data via message passing. This is inspired by\n[Tk commands](https://www.tcl.tk/man/tcl/TkCmd/contents.html) and egui.\nThe widget size constraint system and some layout widgets are influenced by [Flutter](https://flutter.dev).\n\nThe [example code](guiver-piet/examples/) may appear a bit verbose.\nOn the upside you get simple setup and simple control flow.\n\n\u003c!-- center --\u003e\n\u003cimg width=\"313\" alt=\"Bildschirm­foto 2022-12-16 um 09 19 34\" src=\"https://user-images.githubusercontent.com/391975/208054566-4774326f-9953-4537-b08b-ad82f59c2ab8.png\"\u003e\n\n\u003c!-- counter --\u003e\n\u003cimg width=\"193\" alt=\"Bildschirm­foto 2022-12-16 um 09 21 12\" src=\"https://user-images.githubusercontent.com/391975/208054852-b143b584-ec87-4bc7-a7bd-4c8fa38658ae.png\"\u003e\n\n\u003c!-- temperature converter--\u003e\n\u003cimg width=\"303\" alt=\"Bildschirm­foto 2022-12-16 um 09 26 50\" src=\"https://user-images.githubusercontent.com/391975/208056001-2335f536-0a39-4a07-8f8e-436a59a81e26.png\"\u003e\n\n\u003c!-- placeholder --\u003e\n\u003cimg width=\"183\" alt=\"Bildschirm­foto 2022-12-16 um 09 22 23\" src=\"https://user-images.githubusercontent.com/391975/208055118-18cc28fa-bf42-4980-acb9-713cc94c9697.png\"\u003e\n\n\u003c!-- padding --\u003e\n\u003cimg width=\"195\" alt=\"Bildschirm­foto 2022-12-16 um 09 25 50\" src=\"https://user-images.githubusercontent.com/391975/208055749-705cc320-0520-47a8-b82c-1136d29bb8aa.png\"\u003e\n\n\u003c!-- row --\u003e\n\u003cimg width=\"346\" alt=\"Bildschirm­foto 2022-12-16 um 09 27 34\" src=\"https://user-images.githubusercontent.com/391975/208056135-a3767c96-ec39-4309-8e6c-04ba81865b78.png\"\u003e\n\n\u003c!-- column --\u003e\n\u003cimg width=\"140\" alt=\"Bildschirm­foto 2022-12-20 um 08 08 19\" src=\"https://user-images.githubusercontent.com/391975/208604813-3b5c2809-0622-436f-b742-39c8db102b9e.png\"\u003e\n\n\u003c!-- grid --\u003e\n\u003cimg width=\"272\" alt=\"Bildschirm­foto 2022-12-20 um 08 13 10\" src=\"https://user-images.githubusercontent.com/391975/208605573-1a5d9171-51c9-419e-816e-53f9f6fc7a7b.png\"\u003e\n\n\u003c!-- freundchen --\u003e\n\u003cimg width=\"912\" alt=\"Bildschirm­foto 2022-12-20 um 08 16 51\" src=\"https://user-images.githubusercontent.com/391975/208606239-c548f2da-d4a7-4ca5-a49f-c7e81ea740bf.png\"\u003e\n\n\u003c!-- makamau 1 --\u003e\n\u003cimg width=\"677\" alt=\"Bildschirm­foto 2022-12-20 um 08 21 59\" src=\"https://user-images.githubusercontent.com/391975/208607090-5bd4d792-f75d-47bb-a0ac-ea5444d1da27.png\"\u003e\n\n\u003c!-- makamau 2 --\u003e\n\u003cimg width=\"571\" alt=\"Bildschirm­foto 2022-12-20 um 08 19 20\" src=\"https://user-images.githubusercontent.com/391975/208606700-6091eb6b-18c3-4655-83c9-93e292dda556.png\"\u003e\n\n\u003c!-- abermals --\u003e\n\u003cimg width=\"888\" alt=\"Bildschirmfoto 2022-07-05 um 19 43 55\" src=\"https://user-images.githubusercontent.com/391975/177385769-598d0fd0-c15b-4d7e-bb98-5fd46bd9d415.png\"\u003e\n\n\n## Status\n\n* Operating systems:\n  * macOS: tested intensively\n  * Windows: works in general, probably has rough edges\n  * other: testers are welcome\n* Widget manager:\n  * handles widget lifetimes\n  * handles a main widget\n  * handles widget focussing – including tab order\n  * handles copy/paste\n* Widgets:\n  * Button\n  * Hyperlink\n  * Placeholder\n  * Text\n  * TextInput\n* Layout widgets:\n  * Center\n  * Column\n  * Expanded\n  * Grid\n  * Padding\n  * Row\n  * SizedBox\n\n\n## Developer guide\n\nWidgets are decoupled from the developers code via the `WidgetManager`. It owns the widgets and manages their lifetimes.\nWidgets are created via `new_*()` methods and are modified and composed via `Command`s.\nCommands allow transactional modification, where a re-layout happens once at the end.\n\nWidgets implement the `Widget` trait. The methods can be used by the `WidgetManager` and by other widgets (e.g. the\n`TextInput` widget contains a `Text` widget).\nA widget reacts to user `Event`s and possibly creates `WidgetEvent`s accordingly.\nThe developer code can handle those widget events.\n\n\n\n## Backlog\n\n* `guiver-wasm`:\n  * [ ] add `WidgetManager`\n\n\n\n* [ ] `guiver-piet`: bundle the `Command`s per `WidgetId`: add `Command::ToWidget\u003cVec\u003cWidgetCommand\u003e\u003e`\n  * [ ] add `WidgetCommand`\n\n* `guiver-piet`: unify widgets:\n  * [ ] add `fn core(\u0026self) -\u003e \u0026WidgetCore` to `PietWidget` or `Widget`?\n  * [ ] add a method to return an iterator over th child widgets\n  * [ ] default implement `PietWidget::paint()` using `core()` and the child widgets iterator yielding method\n\n* [ ] `guiver-piet`: add support to `PietWidget` for the concept of layers/z-order for dropdown boxes, tooltips etc.\n  * [ ] how?\n    * Druid: [`PaintCtx::paint_with_z_index()`](https://docs.rs/druid/latest/src/druid/contexts.rs.html#735-746)\n\n* add selectors:\n  * [ ] add `Command::SetClass(Option\u003cC\u003e)`\n  * [ ] add `WidgetSelector`:\n    * `All`\n    * `WithId(WidgetId)`\n    * `ChildrenOf(WidgetId)`\n    * `ParentOf(WidgetId)`\n    * [ ] use it in\n      * [ ] `Command::Destroy`\n      * [ ] `Command::RemoveChild`\n        * [ ] remove `Command::RemoveChildren`\n      * [ ] `Command::RemoveEventObservation`\n      * [ ] `Command::AddEventObservation`\n      * [ ] `Command::SetDebugRendering`\n      * [ ] `Command::SetFill`\n      * [ ] `Command::SetFont`\n      * [ ] `Command::SetHorizontalAlignment`\n      * [ ] `Command::SetIsDisabled`\n      * [ ] `Command::SetIsHidden`\n      * [ ] `Command::SetStroke`\n      * [ ] `Command::SetValue`\n      * [ ] `Command::SetVerticalAlignment`\n* [ ] add `Widget::class() -\u003e Option\u003cC\u003e`\n  * [ ] implement in `Core`\n  * [ ] add `WidgetSelector::WithClass(C)`\n\n* [ ] sketch a WASM backend?\n* [ ] sketch a `cacao` backend?\n* [ ] sketch a `egui` backend?\n\n* `guiver-piet`: text:\n  * `test_selected_text_replaced()`:\n    * [ ] fix\n    * [ ] add a test case using umlauts\n  * [ ] `test_selected_text()`: add a test case using umlauts\n  * [ ] `test_text_inserted()`: implement\n    *  add a test case using umlauts\n  * [ ] `TextInput::set_selected_value()`: implement\n  * determine the graphical positions:\n    * [TextLayout::hit_test_text_position(())](https://docs.rs/druid/latest/druid/piet/trait.TextLayout.html#tymethod.hit_test_text_position)\n      * [HitTestPosition](https://docs.rs/druid/latest/druid/piet/struct.HitTestPosition.html)\n    * [ ] text cursor\n    * [ ] text selection\n  * [ ] `paint()`: paint the cursor\n  * [ ] `paint()`: paint the text selection\n  * [ ] `TextInput::handle_event()`: adjust the text cursor on arrow left/right\n  * [ ] `TextInput::handle_event()`: adjust the text selection on Shift + arrow left/right\n  * [ ] `TextInput::update_caret_character_index()`: implement\n  * [ ] `TextInput`: Meta+X should cut the selected text\n  * [ ] `TextInput`: if a text is too large to fit in, the size of the text input should not increase but truncate\n  * [ ] `TextInput::handle_event()`: select the whole text on double click\n\n* [ ] `guiver-piet`: add support for scrolling\n  * [ ] how?\n\n* [ ] `test::widgets_layout()`: add remaining layout widgets\n* [ ] `test::widgets()`: add child widgets to the layout widgets\n\n* [ ] move `WidgetManager::focused_widget` to `WidgetFocusOrder`?\n* [ ] publish 0.1.1, once the updated `druid-shell` \u003e0.7.0 is [released](https://github.com/linebender)\n* [ ] make `Text` selectable:\n  * [ ] via double click\n    * [ ] how?\n  * [ ] via click + drag\n* [ ] add `WidgetCore::is_disabled`?\n  * makes sense for non-layout widgets:\n    * `Button`\n    * `Hyperlink`\n    * `Text`\n    * `TextInput`\n  * [ ] does it make sense for layout widgets?\n    * [ ] should they pass the command down to its child widgets?\n* [ ] `Widget`: remove `flex_factor()`?\n  * Pro:\n    * for `Grid` it needs to be held externally (`GridColumnProperties`, `GridRowProperties`)\n  * Cons:\n    * does it make usage of `Column`, `Row` less pleasant?\n* [ ] should all container widgets clip the child widget's painting?\n  * Pro:\n    * restricts misbehaving widgets paint\n  * Con:\n    * performance impact if clipping is unnecessary?\n* add integration tests:\n  * `widgets()`:\n    * [ ] add `Column`\n    * [ ] add `Padding`\n    * [ ] add `Row`\n  * add for `Column`:\n    * [ ] `test_apply_size_constraints()`\n    * [ ] `test_handle_command()`\n    * [ ] `test_handle_event()`\n  * add for `Row`:\n    * [ ] `test_apply_size_constraints()`\n    * [ ] `test_handle_command()`\n    * [ ] `test_handle_event()`\n  * add for `Center`:\n    * [ ] `test_apply_size_constraints()`\n    * [ ] `test_handle_command()`\n    * [ ] `test_handle_event()`\n  * add for `Padding`:\n    * [ ] `test_apply_size_constraints()`\n    * [ ] `test_handle_command()`\n    * [ ] `test_handle_event()`\n* add unit tests:\n  * add for `Button`:\n    * [ ] `test_apply_size_constraints()`\n    * [ ] `test_handle_command()`\n    * [ ] `test_handle_event()`\n  * add for `Placeholder`:\n    * [ ] `test_handle_command()`\n    * [ ] `test_handle_event()`\n  * add for `Text`:\n    * [ ] `test_handle_command()`\n    * [ ] `test_handle_event()`\n  * add for `TextInput`:\n    * [ ] `test_apply_size_constraints()`\n    * [ ] `test_handle_command()`\n    * [ ] `test_handle_event()`\n* [ ] add a `Table` widget\n* [ ] example `layout_expanded_row_column.rs`: make the row not grab all height\n* [ ] all layout widgets need to clip too big child widgets\n* [ ] add layout widget `Stacked` + `Positioned`\n* [ ] `Hyperlink`: make it possible to remember/pass \"was visited\" status across widget lifetimes\n* support text selection:\n  * [ ] Shift + cursor movement\n  * [ ] Meta+A\n* [ ] support Drag and drop\n  * `druid-shell` has [no support](https://github.com/linebender/druid/issues/1742)\n* [ ] implement [7GUIs](https://eugenkiss.github.io/7guis/tasks)\n  * [ ] 7GUIs \"Flight Booker\"\n    * [ ] implement `DropdownBox` (needs 2 layers)\n  * [ ] 7GUIs \"Timer\"\n  * [ ] 7GUIs \"CRUD\"\n  * [ ] 7GUIs \"Circle Drawer\"\n  * [ ] 7GUIs \"Cells\"\n* [ ] optimize: do not paint on every event. Make the widgets request the repaint in a region/Rect\n* [ ] add Redmond 31 widgets?\n* [ ] add Python bindings?\n* [ ] provide wrappers to native widgets?\n* [ ] provide a WebAssembly demo\n* [ ] consider decoupling from druid-shell/piet \n\nSee also [\"So you want to write a GUI framework\"](https://www.cmyr.net/blog/gui-framework-ingredients.html)\n\n\n## License\n\nLicensed under either of\n* Apache License, Version 2.0 ([LICENSE-APACHE](guiver-piet/LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n* MIT license ([LICENSE-MIT](guiver-piet/LICENSE-MIT) or http://opensource.org/licenses/MIT)\n  at your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you shall be dual licensed as above, without any\nadditional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkud1ing%2Fguiver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkud1ing%2Fguiver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkud1ing%2Fguiver/lists"}