The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .github
    ├── ISSUE_TEMPLATE
    │   ├── bug_report.md
    │   └── feature-request.md
    ├── pull_request_template.md
    └── workflows
    │   └── orbtk.yml
├── .gitignore
├── .vscode
    ├── launch.json
    └── tasks.json
├── CHANGELOG.md
├── Cargo.toml
├── LICENSE
├── Node.toml
├── README.md
├── clippy.toml
├── orbtk
    ├── Cargo.toml
    ├── assets
    │   └── orbtk_space.png
    ├── examples
    │   ├── README.md
    │   ├── assets
    │   │   ├── calculator
    │   │   │   └── calculator_dark.ron
    │   │   ├── popup
    │   │   │   ├── default_dark.ron
    │   │   │   └── popup_de_DE.ron
    │   │   └── showcase
    │   │   │   ├── orbtk_logo.png
    │   │   │   └── showcase_de_DE.ron
    │   ├── calculator.rs
    │   ├── login.rs
    │   ├── message.rs
    │   ├── minimal.rs
    │   ├── msg_handler.rs
    │   ├── multi_window.rs
    │   ├── overlay.rs
    │   ├── popup.rs
    │   ├── showcase.rs
    │   └── stack.rs
    ├── images
    │   ├── layout_constraints.png
    │   ├── layout_constraints.svg
    │   ├── orbtk_logo_dark.png
    │   ├── orbtk_planet.svg
    │   └── orbtk_space.png
    ├── screenshots
    │   ├── calculator.png
    │   ├── calculator_dark_macos.png
    │   ├── calculator_light_macos.png
    │   ├── calculator_redox.png
    │   ├── canvas.jpg
    │   ├── canvas.png
    │   ├── login.png
    │   ├── message.png
    │   ├── minimal.png
    │   ├── msg_handler.png
    │   ├── multi_window.jpg
    │   ├── multi_window.png
    │   ├── overlay.jpg
    │   ├── overlay.png
    │   ├── popup.png
    │   ├── showcase.png
    │   ├── showcase_button.png
    │   ├── showcase_button_macos.png
    │   ├── showcase_image.png
    │   ├── showcase_interactive.png
    │   ├── showcase_items.png
    │   ├── showcase_layouts.png
    │   ├── showcase_localization.png
    │   ├── showcase_navigation.png
    │   └── stack.png
    └── src
    │   ├── application.rs
    │   ├── lib.rs
    │   └── prelude.rs
├── orbtk_core
    ├── Cargo.toml
    ├── README.md
    └── src
    │   ├── application
    │       ├── context_provider.rs
    │       ├── mod.rs
    │       ├── overlay.rs
    │       └── window_adapter.rs
    │   ├── event
    │       ├── drop.rs
    │       ├── editable.rs
    │       ├── event_adapter.rs
    │       ├── event_handler.rs
    │       ├── event_queue.rs
    │       ├── focus.rs
    │       ├── key.rs
    │       ├── mod.rs
    │       ├── mouse.rs
    │       ├── system.rs
    │       ├── text_input.rs
    │       └── window.rs
    │   ├── layout
    │       ├── absolute.rs
    │       ├── fixed_size.rs
    │       ├── grid.rs
    │       ├── mod.rs
    │       ├── padding.rs
    │       ├── popup.rs
    │       └── stack.rs
    │   ├── lib.rs
    │   ├── localization
    │       ├── mod.rs
    │       └── ron_localization
    │       │   ├── dictionary.rs
    │       │   └── mod.rs
    │   ├── macros.rs
    │   ├── prelude.rs
    │   ├── properties
    │       ├── layout
    │       │   ├── block.rs
    │       │   ├── mod.rs
    │       │   └── scroll_viewer_mode.rs
    │       ├── mod.rs
    │       └── widget
    │       │   ├── focus_state.rs
    │       │   ├── keyboard_state.rs
    │       │   ├── mod.rs
    │       │   ├── render_pipeline.rs
    │       │   ├── selected_entities.rs
    │       │   ├── selected_indices.rs
    │       │   └── text_selection.rs
    │   ├── render_object
    │       ├── cursor.rs
    │       ├── default.rs
    │       ├── font_icon.rs
    │       ├── image.rs
    │       ├── mod.rs
    │       ├── pipeline.rs
    │       ├── popup.rs
    │       ├── rectangle.rs
    │       └── text.rs
    │   ├── services
    │       ├── clipboard.rs
    │       ├── mod.rs
    │       └── settings.rs
    │   ├── systems
    │       ├── cleanup_system.rs
    │       ├── event_state_system.rs
    │       ├── init_system.rs
    │       ├── layout_system.rs
    │       ├── mod.rs
    │       ├── post_layout_state_system.rs
    │       └── render_system.rs
    │   ├── theming
    │       ├── config
    │       │   ├── mod.rs
    │       │   ├── style_config.rs
    │       │   └── theme_config.rs
    │       ├── mod.rs
    │       ├── selector.rs
    │       ├── style.rs
    │       ├── theme.rs
    │       └── theme_state.rs
    │   ├── tree
    │       └── mod.rs
    │   └── widget_base
    │       ├── build_context.rs
    │       ├── context.rs
    │       ├── message_adapter.rs
    │       ├── mod.rs
    │       ├── registry.rs
    │       ├── state.rs
    │       ├── states_context.rs
    │       ├── template.rs
    │       └── widget_container.rs
├── orbtk_orbclient
    ├── Cargo.toml
    ├── README.md
    └── src
    │   ├── event.rs
    │   ├── lib.rs
    │   ├── native
    │       └── mod.rs
    │   ├── orbclient
    │       ├── mod.rs
    │       ├── states.rs
    │       ├── window.rs
    │       └── window_builder.rs
    │   ├── prelude.rs
    │   ├── web
    │       ├── mod.rs
    │       ├── states.rs
    │       ├── window.rs
    │       └── window_builder.rs
    │   └── window_adapter.rs
├── orbtk_tinyskia
    ├── Cargo.toml
    ├── README.md
    └── src
    │   ├── common.rs
    │   ├── lib.rs
    │   ├── prelude.rs
    │   ├── render_target.rs
    │   └── tinyskia
    │       ├── font.rs
    │       ├── image.rs
    │       └── mod.rs
├── orbtk_widgets
    ├── Cargo.toml
    ├── README.md
    ├── assets
    │   ├── fonts
    │   │   ├── material
    │   │   │   ├── MATERIAL_ICONS_LICENSE
    │   │   │   ├── MaterialIcons-Baseline.woff2
    │   │   │   ├── MaterialIcons-Outlined.woff2
    │   │   │   ├── MaterialIcons-Round.woff2
    │   │   │   ├── MaterialIcons-Sharp.woff2
    │   │   │   ├── MaterialIcons-TwoTone.woff2
    │   │   │   ├── MaterialIcons.ttf
    │   │   │   ├── README.md
    │   │   │   ├── material_icons_font.ron
    │   │   │   └── package.json
    │   │   ├── mdl2
    │   │   │   ├── mdl2.otf
    │   │   │   └── mdl2_assets_font.ron
    │   │   ├── roboto
    │   │   │   ├── ROBOTO_LICENSE
    │   │   │   ├── Roboto-Medium.ttf
    │   │   │   └── Roboto-Regular.ttf
    │   │   └── selawik
    │   │   │   ├── Selawik-Bold.otf
    │   │   │   ├── Selawik-Light.otf
    │   │   │   └── Selawik-Regular.otf
    │   └── themes
    │   │   ├── fluent
    │   │       ├── theme_fluent.ron
    │   │       ├── theme_fluent_colors_dark.ron
    │   │       ├── theme_fluent_colors_light.ron
    │   │       └── theme_fluent_fonts.ron
    │   │   ├── orbtk
    │   │       ├── theme_default.ron
    │   │       ├── theme_default_colors_dark.ron
    │   │       ├── theme_default_colors_light.ron
    │   │       └── theme_default_fonts.ron
    │   │   └── redox
    │   │       ├── theme_redox.ron
    │   │       ├── theme_redox_colors.ron
    │   │       └── theme_redox_fonts.ron
    └── src
    │   ├── behaviors
    │       ├── mod.rs
    │       ├── mouse_behavior.rs
    │       ├── selection_behavior.rs
    │       └── text_behavior.rs
    │   ├── button.rs
    │   ├── canvas.rs
    │   ├── check_box.rs
    │   ├── combo_box.rs
    │   ├── container.rs
    │   ├── cursor.rs
    │   ├── font_icon_block.rs
    │   ├── grid.rs
    │   ├── image_widget.rs
    │   ├── items_widget.rs
    │   ├── lib.rs
    │   ├── list_view.rs
    │   ├── master_detail.rs
    │   ├── numeric_box.rs
    │   ├── pager.rs
    │   ├── password_box.rs
    │   ├── popup.rs
    │   ├── prelude.rs
    │   ├── progress_bar.rs
    │   ├── scroll_bar.rs
    │   ├── scroll_indicator.rs
    │   ├── scroll_viewer.rs
    │   ├── slider.rs
    │   ├── stack.rs
    │   ├── switch.rs
    │   ├── tab_widget.rs
    │   ├── text_block.rs
    │   ├── text_box.rs
    │   ├── themes
    │       ├── mod.rs
    │       ├── theme_fluent
    │       │   ├── fluent_fonts.rs
    │       │   ├── mdl2_assets_font.rs
    │       │   └── mod.rs
    │       ├── theme_orbtk
    │       │   ├── colors.rs
    │       │   ├── material_icons_font.rs
    │       │   ├── mod.rs
    │       │   └── orbtk_fonts.rs
    │       └── theme_redox.rs
    │   ├── toggle_button.rs
    │   └── window.rs
├── policies
    └── code-of-conduct.md
├── proc_macros
    ├── Cargo.toml
    ├── README.md
    └── src
    │   └── lib.rs
└── utils
    ├── Cargo.toml
    ├── README.md
    ├── build.rs
    ├── colors.txt
    └── src
        ├── alignment.rs
        ├── angle.rs
        ├── border.rs
        ├── brush.rs
        ├── color.rs
        ├── constraint.rs
        ├── dirty_size.rs
        ├── expression.rs
        ├── f32_cmp.rs
        ├── f64_cmp.rs
        ├── filter.rs
        ├── gradients.rs
        ├── lib.rs
        ├── number.rs
        ├── orientation.rs
        ├── point.rs
        ├── prelude.rs
        ├── rectangle.rs
        ├── relative_direction.rs
        ├── selection_mode.rs
        ├── size.rs
        ├── spacer.rs
        ├── string16.rs
        ├── text_alignment.rs
        ├── text_baseline.rs
        ├── thickness.rs
        ├── value.rs
        └── visibility.rs


/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | name: Bug report
 3 | about: Create a report to help us improve
 4 | title: ''
 5 | labels: bug
 6 | assignees: ''
 7 | 
 8 | ---
 9 | 
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 | 
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 | 
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 | 
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 | 
26 | **Desktop (please complete the following information):**
27 |  - OS: [e.g. iOS]
28 |  - Browser [e.g. chrome, safari]
29 |  - Version [e.g. 22]
30 | 
31 | **Smartphone (please complete the following information):**
32 |  - Device: [e.g. iPhone6]
33 |  - OS: [e.g. iOS8.1]
34 |  - Browser [e.g. stock browser, safari]
35 |  - Version [e.g. 22]
36 | 
37 | **Additional context**
38 | Add any other context about the problem here.
39 | 


--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature-request.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | name: Feature request
 3 | about: " Suggest an idea for this project "
 4 | title: ''
 5 | labels: ''
 6 | assignees: ''
 7 | 
 8 | ---
 9 | 
10 | # Context
11 | 
12 | In which context or scenario will your feature/widget be used?
13 | 
14 | # Problem description & Solution
15 | 
16 | Describe your problem and possible solution here
17 | 
18 | # Examples and MockUps
19 | 
20 | Can you give a concrete example of how you'd use the feature? A relevant code sample?
21 | Can you draw a picture of what you're imagining? :-)
22 | 


--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
 1 | # Context:
 2 | A description of the changes proposed in the pull request.
 3 | 
 4 | Reference to a related issue in the repository.
 5 | @mentions of the person or team responsible for reviewing proposed changes.
 6 | 
 7 | ## Contribution checklist:
 8 | - [ ] Add [documentation](https://doc.rust-lang.org/1.7.0/book/documentation.html) to all public structs, traits and functions.
 9 | - [ ] Add unit tests if possible
10 | - [ ] Describe the major change(s) in the CHANGELOG.MD
11 | - [ ] Run `cargo fmt` to make the formatting consistent across the codebase
12 | - [ ] Run `cargo clippy` to check with the linter
13 | 


--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
 1 | # Compiled files
 2 | *.o
 3 | *.so
 4 | *.rlib
 5 | *.dll
 6 | 
 7 | # Executables
 8 | *.exe
 9 | 
10 | # Generated by Cargo
11 | Cargo.lock
12 | /target/
13 | /crates/*/target/
14 | 
15 | .idea/
16 | *.iml
17 | #.vscode
18 | 
19 | # Brainstorming files
20 | brain_*.rs
21 | 
22 | .DS_Store
23 | Thumbs.db
24 | 
25 | # Generated by cargo node
26 | static/
27 | 
28 | book
29 | orbclient


--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
  1 | {
  2 |   // See https://go.microsoft.com/fwlink/?LinkId=733558
  3 |   // for the documentation about the tasks.json format
  4 |   "version": "2.0.0",
  5 |   "tasks": [
  6 |     {
  7 |       "label": "build",
  8 |       "command": "cargo",
  9 |       "type": "shell",
 10 |       "args": [
 11 |         "build",
 12 |         "--examples=minimal",
 13 |         "--features",
 14 |         "log"
 15 |       ],
 16 |       "presentation": {
 17 |         "reveal": "always",
 18 |         "panel": "new"
 19 |       },
 20 |       "group": {
 21 |         "kind": "build",
 22 |         "isDefault": true
 23 |       },
 24 |       "problemMatcher": []
 25 |     },
 26 |     {
 27 |       "label": "build release",
 28 |       "command": "cargo",
 29 |       "type": "shell",
 30 |       "args": [
 31 |         "build",
 32 |         "--examples=minimal",
 33 |         "--release"
 34 |       ],
 35 |       "presentation": {
 36 |         "reveal": "always",
 37 |         "panel": "new"
 38 |       },
 39 |       "group": {
 40 |         "kind": "build",
 41 |         "isDefault": true
 42 |       },
 43 |       "problemMatcher": []
 44 |     },
 45 |     {
 46 |       "label": "build preview",
 47 |       "command": "cargo",
 48 |       "type": "shell",
 49 |       "args": [
 50 |         "build",
 51 |         "--examples=minimal",
 52 |         "--features",
 53 |         "preview"
 54 |       ],
 55 |       "presentation": {
 56 |         "reveal": "always",
 57 |         "panel": "new"
 58 |       },
 59 |       "group": {
 60 |         "kind": "build",
 61 |         "isDefault": true
 62 |       },
 63 |       "problemMatcher": []
 64 |     },
 65 |     {
 66 |       "label": "build debug",
 67 |       "command": "cargo",
 68 |       "type": "shell",
 69 |       "args": [
 70 |         "build",
 71 |         "--examples=minimal",
 72 |         "--features",
 73 |         "debug"
 74 |       ],
 75 |       "presentation": {
 76 |         "reveal": "always",
 77 |         "panel": "new"
 78 |       },
 79 |       "group": {
 80 |         "kind": "build",
 81 |         "isDefault": true
 82 |       }
 83 |     },
 84 |     {
 85 |       "label": "run-web",
 86 |       "command": "cargo",
 87 |       "type": "shell",
 88 |       "args": [
 89 |         "web",
 90 |         "start",
 91 |         "--target=wasm32-unknown-unknown",
 92 |         "--auto-reload",
 93 |         "--example",
 94 |         "widgets"
 95 |       ],
 96 |       "presentation": {
 97 |         "reveal": "always",
 98 |         "panel": "new"
 99 |       },
100 |       "group": {
101 |         "kind": "build",
102 |         "isDefault": true
103 |       }
104 |     },
105 |   ]
106 | }


--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
 1 | [profile.dev]
 2 | opt-level = 1
 3 | 
 4 | [workspace]
 5 | members = [
 6 |     "orbtk",
 7 |     "orbtk_core",
 8 |     "orbtk_widgets",
 9 |     "orbtk_orbclient",
10 |     "orbtk_tinyskia",
11 |     "proc_macros",
12 |     "utils",
13 | ]


--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
 1 | The MIT License (MIT)
 2 | 
 3 | Copyright (c) 2015 Jeremy Soller
 4 | 
 5 | Permission is hereby granted, free of charge, to any person obtaining a copy
 6 | of this software and associated documentation files (the "Software"), to deal
 7 | in the Software without restriction, including without limitation the rights
 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 | 
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 | 
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 | 
23 | 


--------------------------------------------------------------------------------
/Node.toml:
--------------------------------------------------------------------------------
 1 | [[apps]]
 2 | name = "showcase"
 3 | width = 468
 4 | height = 730
 5 | assets = "assets/showcase"
 6 |     [[apps.fonts]]
 7 |     font_family = "MaterialIcons-Regular"
 8 |     src = "crates/theme_default/assets/fonts/MaterialIcons.ttf"
 9 |     [[apps.fonts]]
10 |     font_family = "Roboto-Regular"
11 |     src = "crates/theme_default/assets/fonts/Roboto-Regular.ttf"
12 |     [[apps.fonts]]
13 |     font_family = "Roboto-Medium"
14 |     src = "crates/theme_default/assets/fonts/Roboto-Medium.ttf"
15 | 
16 | [[apps]]
17 | name = "calculator"
18 | width = 212
19 | height = 360
20 | 
21 | [[apps]]
22 | name = "canvas"
23 | width = 468
24 | height = 730
25 |     [[apps.fonts]]
26 |     font_family = "MaterialIcons-Regular"
27 |     src = "crates/theme_default/assets/fonts/MaterialIcons.ttf"
28 |     [[apps.fonts]]
29 |     font_family = "Roboto-Regular"
30 |     src = "crates/theme_default/assets/fonts/Roboto-Regular.ttf"
31 |     [[apps.fonts]]
32 |     font_family = "Roboto-Medium"
33 |     src = "crates/theme_default/assets/fonts/Roboto-Medium.ttf"
34 | 


--------------------------------------------------------------------------------
/clippy.toml:
--------------------------------------------------------------------------------
1 | too-many-arguments-threshold = 10
2 | type-complexity-threshold = 400


--------------------------------------------------------------------------------
/orbtk/Cargo.toml:
--------------------------------------------------------------------------------
 1 | [package]
 2 | authors = [
 3 |     "Florian Blasius <flovanpt@posteo.de>",
 4 |     "Jeremy Soller <jackpot51@gmail.com>"
 5 | ]
 6 | description = "The Orbital Widget Toolkit"
 7 | documentation = "https://docs.rs/orbtk"
 8 | edition = "2021"
 9 | keywords = [
10 |     "orbital",
11 |     "redox",
12 |     "ui",
13 | ]
14 | license = "MIT"
15 | name = "orbtk"
16 | readme = "README.md"
17 | repository = "https://github.com/redox-os/orbtk"
18 | version = "0.3.1-alpha5"
19 | 
20 | [dependencies]
21 | orbtk_proc_macros = { version = "0.3.1-alpha5", path = "../proc_macros" }
22 | orbtk_core = { version = "0.3.1-alpha5", path = "../orbtk_core", default-features = false }
23 | orbtk_tinyskia = { version = "0.3.1-alpha5", path = "../orbtk_tinyskia", default-features = false }
24 | orbtk_orbclient = { version = "0.3.1-alpha5", path = "../orbtk_orbclient", default-features = false }
25 | orbtk_utils = { version = "0.3.1-alpha5", path = "../utils" }
26 | orbtk_widgets = { version = "0.3.1-alpha5", path="../orbtk_widgets", default-features = false }
27 | 
28 | [dependencies.dces]
29 | #version = "0.3.1"
30 | git = "https://gitlab.redox-os.org/redox-os/dces-rust.git"
31 | branch = "master"
32 | #branch = "develop"
33 | 
34 | [dev-dependencies]
35 | euc = "0.5.0"
36 | vek = { version = "0.15.7", default-features = false, features = ["rgb", "rgba"] }
37 | serde = "1.0.106"
38 | serde_derive = "1.0.106"
39 | 
40 | [features]
41 | log = ["orbtk_orbclient/log"]
42 | debug = ["orbtk_core/debug"]
43 | bundled = ["orbtk_orbclient/bundled"]
44 | 
45 | [lib]
46 | name = "orbtk"
47 | path = "src/lib.rs"
48 | 


--------------------------------------------------------------------------------
/orbtk/assets/orbtk_space.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/assets/orbtk_space.png


--------------------------------------------------------------------------------
/orbtk/examples/README.md:
--------------------------------------------------------------------------------
 1 | # OrbTk examples
 2 | 
 3 | [![Build and test](https://github.com/redox-os/orbtk/workflows/CI/badge.svg)](https://github.com/redox-os/orbtk/actions)
 4 | ![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)
 5 | 
 6 | ## Basic reference examples
 7 | 
 8 | * `minimal`: minimal example
 9 | 
10 | 	![minimal](https://raw.githubusercontent.com/redox-os/orbtk/develop/orbtk/screenshots/minimal.png)
11 | 
12 | Howto start your OrbTk journey.
13 | 
14 | * `showcase`: major reference app
15 | 
16 | <p float="left">
17 | <img alt="showcase" width="720" src="https://raw.githubusercontent.com/redox-os/orbtk/develop/orbtk/screenshots/showcase.png">
18 | </p>
19 | 
20 | It provides a structured overview of an OrbTk app. We try to
21 | incorporate example implementation that make use of the supported
22 | widgets inside the orbtk-widget crate.
23 | 
24 | ## Specialized examples
25 | 
26 | * calculator: a calculator example
27 | 
28 | 	![calculator](https://raw.githubusercontent.com/redox-os/orbtk/develop/orbtk/screenshots/calculator.png)
29 | 
30 | * canvas: use third party render library in canvas
31 | 
32 | 	![canvas](https://raw.githubusercontent.com/redox-os/orbtk/develop/orbtk/screenshots/canvas.png)
33 | 
34 | * login: PasswordBox showcase implementing a login form
35 | 
36 | 	<img alt="login" width="360" src="https://raw.githubusercontent.com/redox-os/orbtk/develop/orbtk/screenshots/login.png">
37 | 
38 | * message: MessageAdapter example
39 | 
40 | 	<img alt="message" width="360" src="https://raw.githubusercontent.com/redox-os/orbtk/develop/orbtk/screenshots/message.png">
41 | 
42 | 	1. Assign and implement a thread inside the state of a MainView.
43 | 	2. Generate a time based loop that sleeps given amount out
44 | 	seconds.
45 | 	3. When the timer expires, increment a counter and issue a message
46 | 	inside the state. A message will be triggered and send via the
47 | 	message_adapter.
48 | 	4. The receiver side will evaluate (match) the
49 | 	message type. The associated function block will increment a
50 | 	counter and update a text property inside the MainView. Thus, the View will update that counter every given time period.
51 | 
52 | * msg_handler: sender-receiver example
53 | 
54 | 	<img alt="msg_handler" width="480" src="https://raw.githubusercontent.com/redox-os/orbtk/develop/orbtk/screenshots/msg_handler.png">
55 | 
56 | * multi_window: multi window example
57 | 
58 | 	![multi_window](https://raw.githubusercontent.com/redox-os/orbtk/develop/orbtk/screenshots/multi_window.png)
59 | 
60 | * overlay: draw widgets on the top of the render stack
61 | 
62 | 	![overlay](https://raw.githubusercontent.com/redox-os/orbtk/develop/orbtk/screenshots/overlay.png)
63 | 
64 | * popup: show how to open and use a popup
65 | 
66 | 	<img alt="popup" width="480" src="https://raw.githubusercontent.com/redox-os/orbtk/develop/orbtk/screenshots/popup.png">
67 | 
68 | * stack: stack layout example
69 | 
70 | 	<img alt="stack" width="360" src="https://raw.githubusercontent.com/redox-os/orbtk/develop/orbtk/screenshots/stack.png">
71 | 
72 | ## License
73 | 
74 | Licensed under MIT license ([LICENSE](../LICENSE)).
75 | 


--------------------------------------------------------------------------------
/orbtk/examples/assets/calculator/calculator_dark.ron:
--------------------------------------------------------------------------------
 1 | Theme (
 2 |     styles: {
 3 |         "input": (
 4 |             // based on body style the of default_theme
 5 |             base: "body",
 6 |             properties: {
 7 |                 "foreground": "#9dafbf"
 8 |             }
 9 |         ),
10 |         "result": (
11 |             // based on body style the of default_theme
12 |             base: "body",
13 |             properties: {
14 |                 "font_size": "$FONT_SIZE_36",
15 |             }
16 |         ),
17 |         "header_area": (
18 |             properties: {
19 |                 "background": "#444e55"
20 |             }
21 |         ),
22 |         "content_area": (
23 |             properties: {
24 |                 "background": "#3b434a"
25 |             }
26 |         ),
27 |          "button_calculator": ( 
28 |             // based on button style the of default_theme
29 |             base: "button",
30 |             properties: {
31 |                 "min_width": 48,
32 |                 "height": 48,
33 |                 "border_radius": 1,
34 |                 "spacing": 0,
35 |             },
36 |         ),
37 |         "button_calculator_primary": (
38 |             // based on button_primary style the of default_theme
39 |             base: "button_primary",
40 |             properties: {
41 |                 "min_width": 48,
42 |                 "height": 48,
43 |                 "border_radius": 1,
44 |                 "spacing": 0,
45 |             },
46 |         ),
47 |     }
48 | )


--------------------------------------------------------------------------------
/orbtk/examples/assets/popup/default_dark.ron:
--------------------------------------------------------------------------------
 1 | // Popup: extended default theme.
 2 | Theme (
 3 |     styles: {
 4 |         "popup_combo_box": (
 5 |             base: "combo_box",
 6 |             properties: {
 7 |                 "offset": 3
 8 |             },
 9 |         ),
10 |         "container_form": (
11 |             base: "container",
12 |             properties: {
13 |                 "background": "#0000FF",
14 |                 "border_brush": "$CONTAINER_BORDER",
15 |                 "border_radius": 3,
16 |                 "border_width": 2,
17 |                 "height": 200,
18 |                 "padding": 16,
19 |                 "width": 200
20 |             },
21 |         ),
22 |         "popup_form": (
23 |             base: "popup",
24 |             properties: {
25 |                 "background": "#FFFFFF",
26 |                 "border_brush": "#000000",
27 |                 "border_radius": 12,
28 |                 "border_width": 5,
29 |                 "margin": 8,
30 |                 "padding": 0
31 |             },
32 |         ),
33 |         "popup_text_block": (
34 |             base: "popup",
35 |             properties: {
36 |                 "foreground": "#000000",
37 |                 "h_align": "center",
38 |                 "v_align": "top"
39 |             },
40 |         ),
41 |         "popup_numeric_box": (
42 |             base: "numeric_box",
43 |             properties: {
44 |                 "width": 100
45 |             },
46 |         ),
47 |         "target_text_block": (
48 |             base: "small_text",
49 |             properties: {
50 |                 "h_align": "center",
51 |                 "v_align": "center"
52 |             },
53 |         ),
54 |     }
55 | )
56 | 


--------------------------------------------------------------------------------
/orbtk/examples/assets/popup/popup_de_DE.ron:
--------------------------------------------------------------------------------
1 | Dictionary (
2 |     words: {
3 | 	"Click me to show the popup": "Klicken zum Anzeigen des Popup",
4 | 	"Click me to hide the popup": "Klicken zum Verbergen des Popup",
5 |     "Offset:": "Versatz:",
6 | 	"Placement:": "Plazierung:",
7 |     }
8 | )
9 | 


--------------------------------------------------------------------------------
/orbtk/examples/assets/showcase/orbtk_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/examples/assets/showcase/orbtk_logo.png


--------------------------------------------------------------------------------
/orbtk/examples/assets/showcase/showcase_de_DE.ron:
--------------------------------------------------------------------------------
 1 | Dictionary (
 2 |     words: {
 3 |         // ButtonView
 4 |         "Text only": "nur Text",
 5 |         "disabled": "deaktiviert",
 6 |         // ItemsView
 7 |         "Item 1": "Eintrag 1",
 8 |         "Item 2": "Eintrag 2",
 9 |         "Item 3": "Eintrag 3",
10 |         "Item 4": "Eintrag 4",
11 |         "Item 5": "Eintrag 5",
12 |         // LocalizationView
13 |         "Hello": "Hallo",
14 |         "world": "Welt",
15 |         "I": "ich",
16 |         "love": "liebe",
17 |         "localization": "Lokalisierung",
18 |         "German": "Deutsch",
19 |         "English": "Englisch",
20 |         "Localization": "Lokalisierung",
21 |         // NavigationView
22 |         "back": "zurück",
23 |         "Content inside the master pane": "Inhalt im Hautpfenster",
24 |         "Content inside the detail pane": "Inhalt im Detailfenster",
25 |         "Detail Pane": "Detailfenster",
26 |         "Master Pane": "Hautpfenster",
27 |         "Page 1": "Seite 1",
28 |         "Page 2": "Seite 2",
29 |         "Page 3": "Seite 3",
30 |         "Resize the window: Pane brake is set to 800 pixel": "Fenstergröße ändern: Die Splitgrenze ist bei 800 Pixel",
31 |         "Navigation": "Navigation",
32 |         "show detail pane": "zeige Detailfenster",
33 |     }
34 | )
35 | 


--------------------------------------------------------------------------------
/orbtk/examples/message.rs:
--------------------------------------------------------------------------------
 1 | use orbtk::prelude::*;
 2 | 
 3 | use std::{thread, time};
 4 | 
 5 | enum Message {
 6 |     Increment,
 7 | }
 8 | 
 9 | // constants
10 | pub static ID_MESSAGE: &str = "message";
11 | pub static ID_MESSAGE_STACK: &str = "message_stack";
12 | pub static ID_MESSAGE_TEXTBLOCK_COUNTER: &str = "message_counter";
13 | pub static ID_MESSAGE_TEXTBLOCK_LABEL: &str = "message_counter_label";
14 | 
15 | #[derive(Default, AsAny)]
16 | struct MainState {
17 |     count: i32,
18 |     _my_thread: Option<thread::JoinHandle<()>>,
19 | }
20 | 
21 | impl State for MainState {
22 |     fn init(&mut self, _registry: &mut Registry, ctx: &mut Context) {
23 |         let entity = ctx.widget().entity();
24 |         let message_adapter = ctx.message_adapter();
25 | 
26 |         // increments a counter and send the result as message to `MainView`.
27 |         self._my_thread = Some(thread::spawn(move || {
28 |             let duration = time::Duration::from_secs(1);
29 |             loop {
30 |                 thread::sleep(duration);
31 |                 message_adapter.send_message(Message::Increment, entity);
32 |             }
33 |         }));
34 |     }
35 |     fn messages(
36 |         &mut self,
37 |         mut messages: MessageReader,
38 |         _registry: &mut Registry,
39 |         ctx: &mut Context,
40 |     ) {
41 |         for message in messages.read::<Message>() {
42 |             match message {
43 |                 Message::Increment => {
44 |                     self.count += 1;
45 |                     MainView::text_set(&mut ctx.widget(), self.count.to_string());
46 |                 }
47 |             }
48 |         }
49 |     }
50 | }
51 | 
52 | widget!(MainView<MainState> { text: String });
53 | 
54 | impl Template for MainView {
55 |     fn template(self, id: Entity, ctx: &mut BuildContext) -> Self {
56 |         self.id(ID_MESSAGE).name(ID_MESSAGE).text("0").child(
57 |             Stack::new()
58 |                 .id(ID_MESSAGE_STACK)
59 |                 .name(ID_MESSAGE_STACK)
60 |                 .margin(8)
61 |                 .spacing(4)
62 |                 .child(
63 |                     TextBlock::new()
64 |                         .id(ID_MESSAGE_TEXTBLOCK_LABEL)
65 |                         .name(ID_MESSAGE_TEXTBLOCK_LABEL)
66 |                         .text("Message counter example")
67 |                         .style("header")
68 |                         .build(ctx),
69 |                 )
70 |                 .child(
71 |                     TextBlock::new()
72 |                         .id(ID_MESSAGE_TEXTBLOCK_COUNTER)
73 |                         .name(ID_MESSAGE_TEXTBLOCK_COUNTER)
74 |                         .style("body")
75 |                         .margin((0, 8, 0, 0))
76 |                         .text(id)
77 |                         .build(ctx),
78 |                 )
79 |                 .build(ctx),
80 |         )
81 |     }
82 | }
83 | 
84 | fn main() {
85 |     // use this only if you want to run it as web application.
86 |     orbtk::initialize();
87 | 
88 |     Application::new()
89 |         .window(|ctx| {
90 |             Window::new()
91 |                 .title("OrbTk - message example")
92 |                 .position((100.0, 100.0))
93 |                 .size(420.0, 730.0)
94 |                 .child(MainView::new().build(ctx))
95 |                 .build(ctx)
96 |         })
97 |         .run();
98 | }
99 | 


--------------------------------------------------------------------------------
/orbtk/examples/minimal.rs:
--------------------------------------------------------------------------------
 1 | // ANCHOR: All
 2 | // ANCHOR: Use
 3 | use orbtk::prelude::*;
 4 | // ANCHOR_END: Use
 5 | 
 6 | // ANCHOR: Main
 7 | fn main() {
 8 |     // ANCHOR_END: Main
 9 |     // ANCHOR: Initialize
10 |     // use this only if you want to run it as web application.
11 |     orbtk::initialize();
12 |     // ANCHOR_END: Initialize
13 | 
14 |     // ANCHOR: Application
15 |     Application::new()
16 |         // ANCHOR_END: Application
17 |         // ANCHOR: Window
18 |         .window(|ctx| {
19 |             Window::new()
20 |                 .title("OrbTk - Minimal")
21 |                 .position((100.0, 100.0))
22 |                 .size(420.0, 140.0)
23 |                 // ANCHOR_END: Window
24 |                 // ANCHOR: Child
25 |                 .child(
26 |                     TextBlock::new()
27 |                         // ANCHOR: Properties
28 |                         .font_size(28)
29 |                         .h_align("center")
30 |                         .text("Hey OrbTk!")
31 |                         .v_align("center")
32 |                         // ANCHOR_END: Properties
33 |                         .build(ctx),
34 |                 )
35 |                 // ANCHOR: Build
36 |                 .build(ctx)
37 |             // ANCHOR_END: Build
38 |             // ANCHOR_END: Child
39 |         })
40 |         // ANCHOR: Run
41 |         .run();
42 |     // ANCHOR_END: Run
43 | }
44 | // ANCHOR_END: All
45 | 


--------------------------------------------------------------------------------
/orbtk/examples/overlay.rs:
--------------------------------------------------------------------------------
 1 | use orbtk::prelude::*;
 2 | 
 3 | widget!(MainView);
 4 | 
 5 | impl Template for MainView {
 6 |     fn template(self, _: Entity, ctx: &mut BuildContext) -> Self {
 7 |         let container = Container::new()
 8 |             .background("#dfebf5")
 9 |             .width(200.0)
10 |             .height(200.0)
11 |             .child(
12 |                 TextBlock::new()
13 |                     .foreground("#3b434a")
14 |                     .text("Overlay")
15 |                     .v_align("center")
16 |                     .h_align("center")
17 |                     .build(ctx),
18 |             )
19 |             .build(ctx);
20 | 
21 |         ctx.append_child_to_overlay(container).unwrap();
22 |         self.name("MainView").child(
23 |             Container::new()
24 |                 .background("#e1bc21")
25 |                 .child(
26 |                     TextBlock::new()
27 |                         .text("MainView")
28 |                         .style("text_block_header")
29 |                         .v_align("center")
30 |                         .h_align("center")
31 |                         .build(ctx),
32 |                 )
33 |                 .build(ctx),
34 |         )
35 |     }
36 | }
37 | 
38 | fn main() {
39 |     // use this only if you want to run it as web application.
40 |     orbtk::initialize();
41 | 
42 |     Application::new()
43 |         .window(|ctx| {
44 |             Window::new()
45 |                 .title("OrbTk - overlay example")
46 |                 .position((100.0, 100.0))
47 |                 .size(420.0, 730.0)
48 |                 .child(MainView::new().build(ctx))
49 |                 .build(ctx)
50 |         })
51 |         .run();
52 | }
53 | 


--------------------------------------------------------------------------------
/orbtk/images/layout_constraints.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/images/layout_constraints.png


--------------------------------------------------------------------------------
/orbtk/images/orbtk_logo_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/images/orbtk_logo_dark.png


--------------------------------------------------------------------------------
/orbtk/images/orbtk_space.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/images/orbtk_space.png


--------------------------------------------------------------------------------
/orbtk/screenshots/calculator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/calculator.png


--------------------------------------------------------------------------------
/orbtk/screenshots/calculator_dark_macos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/calculator_dark_macos.png


--------------------------------------------------------------------------------
/orbtk/screenshots/calculator_light_macos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/calculator_light_macos.png


--------------------------------------------------------------------------------
/orbtk/screenshots/calculator_redox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/calculator_redox.png


--------------------------------------------------------------------------------
/orbtk/screenshots/canvas.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/canvas.jpg


--------------------------------------------------------------------------------
/orbtk/screenshots/canvas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/canvas.png


--------------------------------------------------------------------------------
/orbtk/screenshots/login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/login.png


--------------------------------------------------------------------------------
/orbtk/screenshots/message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/message.png


--------------------------------------------------------------------------------
/orbtk/screenshots/minimal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/minimal.png


--------------------------------------------------------------------------------
/orbtk/screenshots/msg_handler.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/msg_handler.png


--------------------------------------------------------------------------------
/orbtk/screenshots/multi_window.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/multi_window.jpg


--------------------------------------------------------------------------------
/orbtk/screenshots/multi_window.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/multi_window.png


--------------------------------------------------------------------------------
/orbtk/screenshots/overlay.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/overlay.jpg


--------------------------------------------------------------------------------
/orbtk/screenshots/overlay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/overlay.png


--------------------------------------------------------------------------------
/orbtk/screenshots/popup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/popup.png


--------------------------------------------------------------------------------
/orbtk/screenshots/showcase.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/showcase.png


--------------------------------------------------------------------------------
/orbtk/screenshots/showcase_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/showcase_button.png


--------------------------------------------------------------------------------
/orbtk/screenshots/showcase_button_macos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/showcase_button_macos.png


--------------------------------------------------------------------------------
/orbtk/screenshots/showcase_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/showcase_image.png


--------------------------------------------------------------------------------
/orbtk/screenshots/showcase_interactive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/showcase_interactive.png


--------------------------------------------------------------------------------
/orbtk/screenshots/showcase_items.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/showcase_items.png


--------------------------------------------------------------------------------
/orbtk/screenshots/showcase_layouts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/showcase_layouts.png


--------------------------------------------------------------------------------
/orbtk/screenshots/showcase_localization.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/showcase_localization.png


--------------------------------------------------------------------------------
/orbtk/screenshots/showcase_navigation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/showcase_navigation.png


--------------------------------------------------------------------------------
/orbtk/screenshots/stack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk/screenshots/stack.png


--------------------------------------------------------------------------------
/orbtk/src/application.rs:
--------------------------------------------------------------------------------
 1 | //! This module contains the base elements of an OrbTk application (Application, WindowBuilder and Window).
 2 | 
 3 | use std::sync::mpsc;
 4 | 
 5 | use dces::prelude::Entity;
 6 | 
 7 | use crate::{
 8 |     core::{application::WindowAdapter, localization::*, *},
 9 |     shell::{Shell, ShellRequest},
10 | };
11 | 
12 | /// The `Application` represents the entry point of an OrbTk based application.
13 | pub struct Application {
14 |     // shells: Vec<Shell<WindowAdapter>>,
15 |     request_sender: mpsc::Sender<ShellRequest<WindowAdapter>>,
16 |     shell: Shell<WindowAdapter>,
17 |     name: Box<str>,
18 |     theme: Rc<Theme>,
19 |     localization: Option<Rc<RefCell<Box<dyn Localization>>>>,
20 | }
21 | 
22 | impl Default for Application {
23 |     fn default() -> Self {
24 |         Application::from_name("orbtk_application")
25 |     }
26 | }
27 | 
28 | impl Application {
29 |     /// Creates a new application.
30 |     pub fn new() -> Self {
31 |         Self::default()
32 |     }
33 | 
34 |     /// Sets the default theme for the application. Could be changed per window.
35 |     pub fn theme(mut self, theme: Theme) -> Self {
36 |         self.theme = Rc::new(theme);
37 |         self
38 |     }
39 | 
40 |     pub fn localization<L>(mut self, localization: L) -> Self
41 |     where
42 |         L: Localization + 'static,
43 |     {
44 |         self.localization = Some(Rc::new(RefCell::new(Box::new(localization))));
45 |         self
46 |     }
47 | 
48 |     /// Create a new application with the given name.
49 |     pub fn from_name(name: impl Into<Box<str>>) -> Self {
50 |         let (sender, receiver) = mpsc::channel();
51 | 
52 |         Application {
53 |             request_sender: sender,
54 |             name: name.into(),
55 |             shell: Shell::new(receiver),
56 |             theme: Rc::new(crate::widgets::themes::theme_orbtk::theme_default()),
57 |             localization: None,
58 |         }
59 |     }
60 | 
61 |     /// Creates a new window and add it to the application.
62 |     pub fn window<F: Fn(&mut BuildContext) -> Entity + 'static>(mut self, create_fn: F) -> Self {
63 |         let (adapter, settings, receiver) = create_window(
64 |             self.name.clone(),
65 |             &self.theme,
66 |             self.request_sender.clone(),
67 |             create_fn,
68 |             self.localization.clone(),
69 |         );
70 | 
71 |         self.shell
72 |             .create_window_from_settings(settings, adapter)
73 |             .request_receiver(receiver)
74 |             .build();
75 | 
76 |         self
77 |     }
78 | 
79 |     /// Starts the application and run it until quit is requested.
80 |     pub fn run(mut self) {
81 |         self.shell.run();
82 |     }
83 | }
84 | 


--------------------------------------------------------------------------------
/orbtk/src/lib.rs:
--------------------------------------------------------------------------------
 1 | #![crate_name = "orbtk"]
 2 | #![crate_type = "lib"]
 3 | 
 4 | //! # OrbTk - The Orbital Toolkit
 5 | //!
 6 | //! ![Welcome to the OrbTk planet.][orbtk_planet]
 7 | //!
 8 | //! The `OrbTk` crate implements a cross-platform (G)UI toolkit for
 9 | //! building scalable user interfaces. The codebase is natively build
10 | //! with the `Rust` programming language.
11 | //!
12 | //! `OrbTk` provides a [functional reactive-like][functional_reative] API. It depends on
13 | //! the rust [`DCES`][dces] crate, that provides an Entity Component
14 | //! System. Interaction with `DCES` is managed via the `Entity
15 | //! Component Manager`(ECM), a wrapper API, that transparently mapps `OrbTk` widgets
16 | //! to `ECM`  entities and `OrbTk` properties to `ECM` components.
17 | //!
18 | //! The main goals of `OrbTk` are speed, ease of use, and cross-platform compatibility.
19 | //!
20 | //! Happy 🦀 hacking! ✨
21 | //!
22 | //! [dces]: https://docs.rs/dces
23 | //! [functional_reative]: https://en.wikipedia.org/wiki/Functional_reactive_programming
24 | //! [orbtk_planet]: https://raw.githubusercontent.com/rzerres/orbtk/wip_documentation/orbtk/images/orbtk_planet.svg
25 | // //! [orbtk_planet]: https://raw.githubusercontent.com/redox-os/orbtk/develop/orbtk/images/orbtk_planet.svg
26 | 
27 | //#![feature(extern_doc)]
28 | //#[doc(include="../README.md")]
29 | 
30 | /// Tries to make your OrbTk experience more convenient.
31 | /// It will automatically import traits and types into scope, that you likely need in your app.
32 | pub use orbtk_orbclient::prelude::initialize;
33 | 
34 | /// Handles core implenentations (OrbTk building blocks).
35 | pub mod core {
36 |     pub use orbtk_core::application;
37 |     pub use orbtk_core::localization;
38 |     pub use orbtk_core::macros;
39 |     pub use orbtk_core::prelude::*;
40 |     pub use orbtk_core::theming;
41 |     pub use orbtk_core::tree;
42 | }
43 | 
44 | /// Handles procedural macros.
45 | pub mod proc_macros {
46 |     pub use orbtk_proc_macros::*;
47 | }
48 | 
49 | /// Handles renderer implementations.
50 | pub mod render {
51 |     pub use orbtk_tinyskia::*;
52 | }
53 | 
54 | /// Handles shell interaction implementations.
55 | pub mod shell {
56 |     pub use orbtk_orbclient::prelude::*;
57 | }
58 | 
59 | /// Handles helper utilities and global methods.
60 | pub mod utils {
61 |     pub use orbtk_utils::*;
62 | }
63 | 
64 | /// Handle widget implementations.
65 | pub mod widgets {
66 |     pub use orbtk_widgets::*;
67 | }
68 | 
69 | /// Pre-selects commonly used OrbTk crates and put them into scope.
70 | pub mod prelude;
71 | 
72 | mod application;
73 | 
74 | pub use self::application::*;
75 | 


--------------------------------------------------------------------------------
/orbtk/src/prelude.rs:
--------------------------------------------------------------------------------
 1 | /// This module pre-selects commonly used OrbTk crates and put them into scope.
 2 | pub use std::{
 3 |     any::{Any, TypeId},
 4 |     cell::RefCell,
 5 |     collections::HashMap,
 6 |     fmt::Debug,
 7 |     rc::Rc,
 8 | };
 9 | 
10 | pub use dces::prelude::*;
11 | 
12 | pub use crate::{
13 |     core::macros::*, core::*, proc_macros::*, render::prelude::*, utils::prelude::*,
14 |     widgets::prelude::*, Application,
15 | };
16 | 


--------------------------------------------------------------------------------
/orbtk_core/Cargo.toml:
--------------------------------------------------------------------------------
 1 | [package]
 2 | authors = ["Florian Blasius <flovanpt@posteo.de>"]
 3 | description = "Core crate that provides base api and elements for OrbTk like widgets basis."
 4 | edition = "2021"
 5 | keywords = ["ui", "api"]
 6 | license = "MIT"
 7 | name = "orbtk_core"
 8 | readme = "README.md"
 9 | repository = "https://github.com/redox-os/orbtk"
10 | version = "0.3.1-alpha5"
11 | 
12 | [features]
13 | debug = []
14 | 
15 | [lib]
16 | doctest = false
17 | 
18 | [dependencies]
19 | dirs-next = { version = "2.0" }
20 | derive_more = { version = "0.99", default-features = false, features = ["constructor"] }
21 | memchr = {version = "2"}
22 | orbtk_proc_macros = { path = "../proc_macros", version = "0.3.1-alpha5" }
23 | orbtk_utils = { path = "../utils", version = "0.3.1-alpha5" }
24 | orbtk_tinyskia = { path = "../orbtk_tinyskia", version = "0.3.1-alpha5", default-features = false }
25 | orbtk_orbclient = { path = "../orbtk_orbclient", version = "0.3.1-alpha5", default-features = false }
26 | raw-window-handle = "0.4"
27 | ron = { version = "0.8" }
28 | rust_decimal = { version = "1.15" }
29 | serde = { version = "1.0" }
30 | serde_derive = { version = "1.0" }
31 | smallvec = { version = "1", default-features = false }
32 | 
33 | [dependencies.dces]
34 | #version = "0.3.1"
35 | git = "https://gitlab.redox-os.org/redox-os/dces-rust.git"
36 | branch =  "master"
37 | #branch = "develop"
38 | 
39 | [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
40 | threadpool = { version = "1.8" }
41 | 
42 | [target.wasm32-unknown-unknown.dependencies]
43 | stdweb = { version = "0.4" }
44 | 


--------------------------------------------------------------------------------
/orbtk_core/README.md:
--------------------------------------------------------------------------------
 1 | # orbtk_core
 2 | 
 3 | Provides base traits and structs for application, widgets and properties. It's part of [OrbTk](https://gitlab.redox-os.org/redox-os/orbtk) - The Rust UI-Toolkit.
 4 | 
 5 | [![Build and test](https://github.com/redox-os/orbtk/workflows/CI/badge.svg)](https://github.com/redox-os/orbtk/actions)
 6 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
 7 | 
 8 | ## Dependencies
 9 | 
10 | * [dces](https://gitlab.redox-os.org/redox-os/dces-rust) (MIT): Entity Component System
11 | * [ron](https://github.com/ron-rs/ron) (Apache 2.0, MIT): Save settings to ron file
12 | * [serde](https://github.com/serde-rs/serde) (Apache 2.0, MIT): serialize, deserialize setting objects
13 | * [dirs](https://github.com/xdg-rs/dirs.git) (Apache 2.0, MIT): platform-specific, user-accessible locations
14 | * [raw-window-handle](https://github.com/rust-windowing/raw-window-handle) (MIT): access to a window's platform-specific raw window handle
15 | 
16 | ## License
17 | 
18 | Licensed under MIT license ([LICENSE](../../LICENSE)).
19 | 


--------------------------------------------------------------------------------
/orbtk_core/src/application/context_provider.rs:
--------------------------------------------------------------------------------
 1 | use std::{
 2 |     cell::{Cell, RefCell},
 3 |     collections::BTreeMap,
 4 |     rc::Rc,
 5 |     sync::mpsc,
 6 | };
 7 | 
 8 | use dces::prelude::*;
 9 | 
10 | use super::WindowAdapter;
11 | 
12 | use crate::{
13 |     event::*,
14 |     layout::*,
15 |     localization::Localization,
16 |     render_object::*,
17 |     shell::{ShellRequest, WindowRequest},
18 |     utils::Point,
19 |     widget_base::*,
20 | };
21 | 
22 | /// Temporary solution to share dependencies and needs to be refactored.
23 | #[derive(Clone)]
24 | pub struct ContextProvider {
25 |     /// Reference counted cells of render objects.
26 |     pub render_objects: Rc<RefCell<BTreeMap<Entity, Box<dyn RenderObject>>>>,
27 | 
28 |     /// Reference counted cells of layouts objects.
29 |     pub layouts: Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
30 | 
31 |     /// Reference counted cells of handler_map objects.
32 |     pub handler_map: Rc<RefCell<EventHandlerMap>>,
33 | 
34 |     /// Reference counted cells of handler_states.
35 |     pub states: Rc<RefCell<BTreeMap<Entity, Box<dyn State>>>>,
36 | 
37 |     /// Event adapter objects.
38 |     pub event_adapter: EventAdapter,
39 | 
40 |     /// Message adapter objects.
41 |     pub message_adapter: MessageAdapter,
42 | 
43 |     /// Reference counted cells of mouse_positions defined as `points`
44 |     pub mouse_position: Rc<Cell<Point>>,
45 | 
46 |     /// A window_sender object, used for multiparty session-typed communication.
47 |     pub window_sender: mpsc::Sender<WindowRequest>,
48 | 
49 |     /// A shell_sender object, used for multiparty session-typed communication.
50 |     pub shell_sender: mpsc::Sender<ShellRequest<WindowAdapter>>,
51 | 
52 |     /// Holds the application name.
53 |     pub application_name: String,
54 | 
55 |     /// Reference counted cell to track the `first_run`
56 |     pub first_run: Rc<Cell<bool>>,
57 | 
58 |     /// Holds a raw window handler object.
59 |     pub raw_window_handle: Option<raw_window_handle::RawWindowHandle>,
60 | 
61 |     // TODO: make it thread safe
62 |     /// Reference counted cells that hold the supported localization identifiers.
63 |     pub localization: Option<Rc<RefCell<Box<dyn Localization>>>>,
64 | }
65 | 
66 | impl ContextProvider {
67 |     /// Creates a new context provider.
68 |     pub fn new(
69 |         window_sender: mpsc::Sender<WindowRequest>,
70 |         shell_sender: mpsc::Sender<ShellRequest<WindowAdapter>>,
71 |         application_name: impl Into<String>,
72 |         localization: Option<Rc<RefCell<Box<dyn Localization>>>>,
73 |     ) -> Self {
74 |         ContextProvider {
75 |             render_objects: Rc::new(RefCell::new(BTreeMap::new())),
76 |             layouts: Rc::new(RefCell::new(BTreeMap::new())),
77 |             handler_map: Rc::new(RefCell::new(EventHandlerMap::new())),
78 |             states: Rc::new(RefCell::new(BTreeMap::new())),
79 |             event_adapter: EventAdapter::new(window_sender.clone()),
80 |             message_adapter: MessageAdapter::new(window_sender.clone()),
81 |             mouse_position: Rc::new(Cell::new(Point::new(0.0, 0.0))),
82 |             window_sender,
83 |             shell_sender,
84 |             application_name: application_name.into(),
85 |             first_run: Rc::new(Cell::new(true)),
86 |             raw_window_handle: None,
87 |             localization,
88 |         }
89 |     }
90 | }
91 | 


--------------------------------------------------------------------------------
/orbtk_core/src/application/mod.rs:
--------------------------------------------------------------------------------
 1 | //! This module contains the base elements of an OrbTk application (Application, WindowBuilder and Window).
 2 | 
 3 | pub use self::context_provider::*;
 4 | pub use self::overlay::*;
 5 | pub use self::window_adapter::*;
 6 | 
 7 | mod context_provider;
 8 | mod overlay;
 9 | mod window_adapter;
10 | 


--------------------------------------------------------------------------------
/orbtk_core/src/application/overlay.rs:
--------------------------------------------------------------------------------
 1 | pub use std::{
 2 |     any::{Any, TypeId},
 3 |     cell::RefCell,
 4 |     collections::{HashMap, HashSet},
 5 |     fmt::Debug,
 6 |     rc::Rc,
 7 | };
 8 | 
 9 | use dces::prelude::*;
10 | 
11 | use crate::{
12 |     event::*,
13 |     layout::{AbsoluteLayout, Layout},
14 |     proc_macros::WidgetCtx,
15 |     properties::*,
16 |     theming::Selector,
17 |     utils::*,
18 |     widget,
19 |     widget_base::*,
20 | };
21 | 
22 | widget!(
23 |     /// The `Overlay` is used to draw its children on the top of all
24 |     /// other widgets in the tree.
25 |     Overlay
26 | );
27 | 
28 | impl Template for Overlay {
29 |     fn template(self, _: Entity, _: &mut BuildContext) -> Self {
30 |         self.name("Overlay")
31 |     }
32 | 
33 |     fn layout(&self) -> Box<dyn Layout> {
34 |         Box::new(AbsoluteLayout::new())
35 |     }
36 | }
37 | 


--------------------------------------------------------------------------------
/orbtk_core/src/event/drop.rs:
--------------------------------------------------------------------------------
 1 | use crate::{
 2 |     prelude::*,
 3 |     proc_macros::{Event, IntoHandler},
 4 | };
 5 | 
 6 | /// This event occurs on a drop file event on the window.
 7 | #[derive(Event, Clone)]
 8 | pub struct DropFileEvent {
 9 |     pub file_name: String,
10 |     pub position: Point,
11 | }
12 | 
13 | /// This event occurs on a drop file event on the window.
14 | #[derive(Event, Clone)]
15 | pub struct DropTextEvent {
16 |     pub text: String,
17 |     pub position: Point,
18 | }
19 | 
20 | pub type DropFn = dyn Fn(&mut StatesContext, String, Point) -> bool + 'static;
21 | 
22 | /// Structure to handle drops inside the file handles.
23 | #[derive(IntoHandler)]
24 | pub struct DropFileHandler {
25 |     /// A reference counted handler object.
26 |     pub handler: Rc<DropFn>,
27 | }
28 | 
29 | impl EventHandler for DropFileHandler {
30 |     fn handle_event(&self, states: &mut StatesContext, event: &EventBox) -> bool {
31 |         if let Ok(event) = event.downcast_ref::<DropFileEvent>() {
32 |             return (self.handler)(states, event.file_name.clone(), event.position);
33 |         }
34 | 
35 |         false
36 |     }
37 | 
38 |     fn handles_event(&self, event: &EventBox) -> bool {
39 |         event.is_type::<DropFileEvent>()
40 |     }
41 | }
42 | 
43 | /// Structure to handle droppings inside the text handles.
44 | #[derive(IntoHandler)]
45 | pub struct DropTextHandler {
46 |     /// A reference counted handler object.
47 |     pub handler: Rc<DropFn>,
48 | }
49 | 
50 | impl EventHandler for DropTextHandler {
51 |     fn handle_event(&self, states: &mut StatesContext, event: &EventBox) -> bool {
52 |         if let Ok(event) = event.downcast_ref::<DropTextEvent>() {
53 |             return (self.handler)(states, event.text.clone(), event.position);
54 |         }
55 | 
56 |         false
57 |     }
58 | 
59 |     fn handles_event(&self, event: &EventBox) -> bool {
60 |         event.is_type::<DropTextEvent>()
61 |     }
62 | }
63 | 
64 | /// Implement this trait if you want that your widget can handle drop (file | text) events
65 | pub trait DropHandler: Sized + Widget {
66 |     /// Inserts a handler for drop file events.
67 |     fn on_drop_file<H: Fn(&mut StatesContext, String, Point) -> bool + 'static>(
68 |         self,
69 |         handler: H,
70 |     ) -> Self {
71 |         self.insert_handler(DropFileHandler {
72 |             handler: Rc::new(handler),
73 |         })
74 |     }
75 | 
76 |     /// Inserts a handler for drop text events.
77 |     fn on_drop_text<H: Fn(&mut StatesContext, String, Point) -> bool + 'static>(
78 |         self,
79 |         handler: H,
80 |     ) -> Self {
81 |         self.insert_handler(DropTextHandler {
82 |             handler: Rc::new(handler),
83 |         })
84 |     }
85 | }
86 | 


--------------------------------------------------------------------------------
/orbtk_core/src/event/event_handler.rs:
--------------------------------------------------------------------------------
 1 | use crate::{event::EventBox, widget_base::StatesContext};
 2 | 
 3 | /// This trait is used to define an event handler.
 4 | pub trait EventHandler {
 5 |     /// Handles an `event` by the given `widget`. If it returns `true` the event will not be forwarded.
 6 |     fn handle_event(&self, state_context: &mut StatesContext, event: &EventBox) -> bool;
 7 | 
 8 |     /// Check if the handler could handle the given event box.
 9 |     fn handles_event(&self, event: &EventBox) -> bool;
10 | }
11 | 


--------------------------------------------------------------------------------
/orbtk_core/src/event/focus.rs:
--------------------------------------------------------------------------------
 1 | use dces::prelude::Entity;
 2 | 
 3 | use crate::{
 4 |     prelude::*,
 5 |     proc_macros::{Event, IntoHandler},
 6 | };
 7 | 
 8 | /// Used to request keyboard focus on the window.
 9 | #[derive(Event, Clone)]
10 | pub enum FocusEvent {
11 |     RequestFocus(Entity),
12 |     RemoveFocus(Entity),
13 | }
14 | 
15 | pub type FocusHandlerFn = dyn Fn(&mut StatesContext, FocusEvent) -> bool + 'static;
16 | 
17 | /// Structure for the focus handling of an event
18 | #[derive(IntoHandler)]
19 | pub struct FocusEventHandler {
20 |     /// A reference counted handler
21 |     pub handler: Rc<FocusHandlerFn>,
22 | }
23 | 
24 | impl EventHandler for FocusEventHandler {
25 |     fn handle_event(&self, states: &mut StatesContext, event: &EventBox) -> bool {
26 |         if let Ok(event) = event.downcast_ref::<FocusEvent>() {
27 |             return (self.handler)(states, event.clone());
28 |         }
29 | 
30 |         false
31 |     }
32 | 
33 |     fn handles_event(&self, event: &EventBox) -> bool {
34 |         event.is_type::<FocusEvent>()
35 |     }
36 | }
37 | 


--------------------------------------------------------------------------------
/orbtk_core/src/event/key.rs:
--------------------------------------------------------------------------------
 1 | use std::rc::Rc;
 2 | 
 3 | use crate::{
 4 |     prelude::*,
 5 |     proc_macros::*,
 6 |     shell::{Key, KeyEvent},
 7 | };
 8 | 
 9 | use super::{EventBox, EventHandler};
10 | 
11 | /// A structure to handle a keyboard `key-down` events
12 | #[derive(Event)]
13 | pub struct KeyDownEvent {
14 |     /// the keyboard event
15 |     pub event: KeyEvent,
16 | }
17 | 
18 | /// A structure to handle a keyboard `key-up` events
19 | #[derive(Event)]
20 | pub struct KeyUpEvent {
21 |     /// the keyboard event
22 |     pub event: KeyEvent,
23 | }
24 | 
25 | pub type KeyHandler = dyn Fn(&mut StatesContext, KeyEvent) -> bool + 'static;
26 | 
27 | /// Used to handle key down events. Could be attached to a widget.
28 | #[derive(IntoHandler)]
29 | pub struct KeyDownEventHandler {
30 |     handler: Rc<KeyHandler>,
31 | }
32 | 
33 | impl EventHandler for KeyDownEventHandler {
34 |     fn handle_event(&self, state_context: &mut StatesContext, event: &EventBox) -> bool {
35 |         event
36 |             .downcast_ref::<KeyDownEvent>()
37 |             .ok()
38 |             .map_or(false, |event| {
39 |                 (self.handler)(state_context, event.event.clone())
40 |             })
41 |     }
42 | 
43 |     fn handles_event(&self, event: &EventBox) -> bool {
44 |         event.is_type::<KeyDownEvent>()
45 |     }
46 | }
47 | 
48 | pub trait KeyDownHandler: Sized + Widget {
49 |     /// Inserts a handler.
50 |     fn on_key_down<H: Fn(&mut StatesContext, KeyEvent) -> bool + 'static>(
51 |         self,
52 |         handler: H,
53 |     ) -> Self {
54 |         self.insert_handler(KeyDownEventHandler {
55 |             handler: Rc::new(handler),
56 |         })
57 |     }
58 | 
59 |     /// Handles events triggered by a specific key.
60 |     fn on_key_down_key<H: Fn() -> bool + 'static>(self, key: Key, handler: H) -> Self {
61 |         self.on_key_down(
62 |             move |_, event| {
63 |                 if event.key == key {
64 |                     handler()
65 |                 } else {
66 |                     false
67 |                 }
68 |             },
69 |         )
70 |     }
71 | }
72 | 


--------------------------------------------------------------------------------
/orbtk_core/src/event/mod.rs:
--------------------------------------------------------------------------------
 1 | //! This module contains all resources to call and handle events.
 2 | 
 3 | use std::{any::Any, collections::BTreeMap, rc::Rc};
 4 | 
 5 | use dces::entity::Entity;
 6 | 
 7 | use crate::widget_base::StatesContext;
 8 | 
 9 | pub use self::drop::*;
10 | pub use self::editable::*;
11 | pub use self::event_adapter::*;
12 | pub use self::event_handler::*;
13 | pub use self::event_queue::*;
14 | pub use self::focus::*;
15 | pub use self::key::*;
16 | pub use self::mouse::*;
17 | pub use self::system::*;
18 | pub use self::text_input::*;
19 | pub use self::window::*;
20 | 
21 | mod drop;
22 | mod editable;
23 | mod event_adapter;
24 | mod event_handler;
25 | mod event_queue;
26 | mod focus;
27 | mod key;
28 | mod mouse;
29 | mod system;
30 | mod text_input;
31 | mod window;
32 | 
33 | /// Defines the strategy of an event how it moves through the tree.
34 | #[derive(Debug, Clone, Eq, PartialEq)]
35 | pub enum EventStrategy {
36 |     // /// From root to leaf.
37 |     // TopDown,
38 |     /// From leaf to root.
39 |     BottomUp,
40 | 
41 |     /// Occurs direct.
42 |     Direct,
43 | }
44 | 
45 | /// Used to define an event.
46 | pub trait Event: Any {
47 |     fn strategy(&self) -> EventStrategy {
48 |         EventStrategy::BottomUp
49 |     }
50 | }
51 | 
52 | /// Assign the `EventHandlerMap` type.
53 | pub type EventHandlerMap = BTreeMap<Entity, Vec<Rc<dyn EventHandler>>>;
54 | 
55 | /// Assign the `TriggerHandler` type.
56 | pub type TriggerHandler = dyn Fn(&mut StatesContext, Entity) + 'static;
57 | 


--------------------------------------------------------------------------------
/orbtk_core/src/event/system.rs:
--------------------------------------------------------------------------------
1 | use crate::{event::Event, proc_macros::Event};
2 | 
3 | /// An enumeration of valid system events
4 | #[derive(Event)]
5 | pub enum SystemEvent {
6 |     Quit,
7 | }
8 | 


--------------------------------------------------------------------------------
/orbtk_core/src/event/text_input.rs:
--------------------------------------------------------------------------------
 1 | use std::rc::Rc;
 2 | 
 3 | use crate::{prelude::*, proc_macros::*};
 4 | 
 5 | /// The text input occurs if the keyboard registers a text input.
 6 | #[derive(Clone, Default, Debug, Event)]
 7 | pub struct TextInputEvent {
 8 |     pub text: String,
 9 | }
10 | 
11 | /// Callback closure to handle text input events.
12 | pub type TextHandler = dyn Fn(&mut StatesContext, &str) -> bool + 'static;
13 | 
14 | /// Internal struct to manage text input event handlers.
15 | #[derive(IntoHandler)]
16 | pub struct TextInputEventHandler {
17 |     handler: Rc<TextHandler>,
18 | }
19 | 
20 | impl EventHandler for TextInputEventHandler {
21 |     fn handle_event(&self, state_context: &mut StatesContext, event: &EventBox) -> bool {
22 |         event
23 |             .downcast_ref::<TextInputEvent>()
24 |             .ok()
25 |             .map_or(false, |event| {
26 |                 (self.handler)(state_context, event.text.as_str())
27 |             })
28 |     }
29 | 
30 |     fn handles_event(&self, event: &EventBox) -> bool {
31 |         event.is_type::<TextInputEvent>()
32 |     }
33 | }
34 | 
35 | /// Implement this trait for widgets that should handle text input events.
36 | ///
37 | /// # Examples
38 | ///
39 | /// ```rust
40 | /// widget!(MyWidget: TextInputHandler {});
41 | ///
42 | /// MyWidget::new()
43 | ///     .on_text_input(|_ctx, text| {
44 | ///         println!("{}", text);
45 | ///         true
46 | ///     }).build(ctx)
47 | /// ```
48 | pub trait TextInputHandler: Sized + Widget {
49 |     /// Callback that is called when a text input event reaches the widget.
50 |     ///
51 |     /// If the callback returns `true` the event is marked as handled and will not available to
52 |     /// to other widgets.
53 |     fn on_text_input<H: Fn(&mut StatesContext, &str) -> bool + 'static>(self, handler: H) -> Self {
54 |         self.insert_handler(TextInputEventHandler {
55 |             handler: Rc::new(handler),
56 |         })
57 |     }
58 | }
59 | 


--------------------------------------------------------------------------------
/orbtk_core/src/event/window.rs:
--------------------------------------------------------------------------------
 1 | use std::rc::Rc;
 2 | 
 3 | use super::*;
 4 | 
 5 | use crate::{proc_macros::*, widget_base::*};
 6 | 
 7 | /// The enumeration of valid window events.
 8 | #[derive(Clone, Event)]
 9 | pub enum WindowEvent {
10 |     Resize { width: f64, height: f64 },
11 |     ActiveChanged(bool),
12 |     None,
13 | }
14 | 
15 | pub type WindowHandlerFn = dyn Fn(&mut StatesContext, WindowEvent) -> bool + 'static;
16 | 
17 | /// The structure handling windows events.
18 | #[derive(IntoHandler)]
19 | pub struct WindowEventHandler {
20 |     /// A reference counted handler.
21 |     pub handler: Rc<WindowHandlerFn>,
22 | }
23 | 
24 | impl EventHandler for WindowEventHandler {
25 |     fn handle_event(&self, states: &mut StatesContext, event: &EventBox) -> bool {
26 |         if let Ok(event) = event.downcast_ref::<WindowEvent>() {
27 |             return (self.handler)(states, event.clone());
28 |         }
29 | 
30 |         false
31 |     }
32 | 
33 |     fn handles_event(&self, event: &EventBox) -> bool {
34 |         event.is_type::<WindowEvent>()
35 |     }
36 | }
37 | 


--------------------------------------------------------------------------------
/orbtk_core/src/layout/mod.rs:
--------------------------------------------------------------------------------
 1 | //! This module contains the layout types of an OrbTk application (Absolute, Fixed, Grid, Padding, Popup, Stack).
 2 | use std::{any::Any, collections::BTreeMap};
 3 | 
 4 | use dces::prelude::*;
 5 | 
 6 | use crate::{render::RenderContext2D, theming::*, tree::Tree, utils::*};
 7 | 
 8 | pub use self::absolute::*;
 9 | pub use self::fixed_size::*;
10 | pub use self::grid::*;
11 | pub use self::padding::*;
12 | pub use self::popup::*;
13 | pub use self::stack::*;
14 | 
15 | mod absolute;
16 | mod fixed_size;
17 | mod grid;
18 | mod padding;
19 | mod popup;
20 | mod stack;
21 | 
22 | /// The layout process will order the children of a given widget in a dynamic iteration.
23 | /// It will respect constraint values between its elements. The following image illustrates
24 | /// the relationship between known layout elements:
25 | ///
26 | /// ![cheat-sheet: layout constraints][layout_constraints]
27 | ///
28 | /// [layout_constraints]: https://raw.githubusercontent.com/rzerres/orbtk/wip_documentation/orbtk/images/layout_constraints.png
29 | // /// [layout_constraints.svg]: https://raw.githubusercontent.com/redox-os/orbtk/develop/orbtk/images/layout_constraints.svg
30 | 
31 | pub trait Layout: Any {
32 |     // Measure all children before the arrangement.
33 |     fn measure(
34 |         &self,
35 |         render_context_2_d: &mut RenderContext2D,
36 |         entity: Entity,
37 |         ecm: &mut EntityComponentManager<Tree>,
38 |         layouts: &BTreeMap<Entity, Box<dyn Layout>>,
39 |         theme: &Theme,
40 |     ) -> DirtySize;
41 | 
42 |     /// Arranges and sizes the children.
43 |     fn arrange(
44 |         &self,
45 |         render_context_2_d: &mut RenderContext2D,
46 |         parent_size: (f64, f64),
47 |         entity: Entity,
48 |         ecm: &mut EntityComponentManager<Tree>,
49 |         layouts: &BTreeMap<Entity, Box<dyn Layout>>,
50 |         theme: &Theme,
51 |     ) -> (f64, f64);
52 | }
53 | 
54 | fn component<C: Component + Clone>(
55 |     ecm: &mut EntityComponentManager<Tree>,
56 |     entity: Entity,
57 |     component: &str,
58 | ) -> C {
59 |     ecm.component_store()
60 |         .get::<C>(component, entity)
61 |         .unwrap()
62 |         .clone()
63 | }
64 | 
65 | fn try_component<C: Component + Clone>(
66 |     ecm: &mut EntityComponentManager<Tree>,
67 |     entity: Entity,
68 |     component: &str,
69 | ) -> Option<C> {
70 |     if let Ok(c) = ecm.component_store().get::<C>(component, entity) {
71 |         return Some(c.clone());
72 |     }
73 | 
74 |     None
75 | }
76 | 
77 | fn component_or_default<C: Component + Clone + Default>(
78 |     ecm: &mut EntityComponentManager<Tree>,
79 |     entity: Entity,
80 |     component: &str,
81 | ) -> C {
82 |     ecm.component_store()
83 |         .get::<C>(component, entity)
84 |         .map(Clone::clone)
85 |         .unwrap_or_default()
86 | }
87 | 
88 | fn component_try_mut<'a, C: Component>(
89 |     ecm: &'a mut EntityComponentManager<Tree>,
90 |     entity: Entity,
91 |     component: &str,
92 | ) -> Option<&'a mut C> {
93 |     ecm.component_store_mut()
94 |         .get_mut::<C>(component, entity)
95 |         .ok()
96 | }
97 | 


--------------------------------------------------------------------------------
/orbtk_core/src/lib.rs:
--------------------------------------------------------------------------------
 1 | /*!
 2 |    API crate that provides base api and elements for OrbTk like widgets basis.
 3 | */
 4 | 
 5 | #[macro_use]
 6 | extern crate derive_more;
 7 | 
 8 | pub(crate) use orbtk_orbclient::prelude as shell;
 9 | pub(crate) use orbtk_proc_macros as proc_macros;
10 | pub(crate) use orbtk_tinyskia::prelude as render;
11 | pub(crate) use orbtk_utils::prelude as utils;
12 | 
13 | pub mod application;
14 | pub mod localization;
15 | pub mod theming;
16 | #[macro_use]
17 | pub mod event;
18 | pub mod layout;
19 | pub mod prelude;
20 | pub mod properties;
21 | pub mod render_object;
22 | pub mod services;
23 | pub mod systems;
24 | pub mod tree;
25 | pub mod widget_base;
26 | 
27 | #[macro_use]
28 | pub mod macros;
29 | 


--------------------------------------------------------------------------------
/orbtk_core/src/localization/mod.rs:
--------------------------------------------------------------------------------
 1 | //! This module contains the localization methods, that handle runtime based adaption of involved OrbTk entities.
 2 | 
 3 | mod ron_localization;
 4 | 
 5 | pub use self::ron_localization::*;
 6 | 
 7 | pub trait Localization {
 8 |     /// Gets the current language by language key e.g. `en_US`,
 9 |     /// `de_DE` or `fr_FR`.
10 |     fn language(&self) -> &String;
11 | 
12 |     /// Sets the current language identified by its language key (e.g. `en_US`, `de_DE`).
13 |     fn set_language(&mut self, key: &str);
14 | 
15 |     /// Gets the translated text for the given key. If there is no
16 |     /// given translation, the `key` will be returned as the result.
17 |     fn text(&self, key: String) -> String;
18 | }
19 | 


--------------------------------------------------------------------------------
/orbtk_core/src/localization/ron_localization/dictionary.rs:
--------------------------------------------------------------------------------
 1 | use std::collections::HashMap;
 2 | 
 3 | use ron::de::from_str;
 4 | use serde_derive::Deserialize;
 5 | 
 6 | /// Internal struct used by the `RonLocalization` to parse as language file.
 7 | #[derive(Debug, Clone, Deserialize)]
 8 | pub struct Dictionary {
 9 |     pub words: HashMap<String, String>,
10 | }
11 | 
12 | impl From<&str> for Dictionary {
13 |     fn from(s: &str) -> Self {
14 |         from_str(s).unwrap()
15 |     }
16 | }
17 | 


--------------------------------------------------------------------------------
/orbtk_core/src/localization/ron_localization/mod.rs:
--------------------------------------------------------------------------------
  1 | use std::collections::HashMap;
  2 | 
  3 | use crate::localization::Localization;
  4 | 
  5 | use dictionary::Dictionary;
  6 | 
  7 | mod dictionary;
  8 | 
  9 | /// Used to build a new `RonLocalization` and configure language file
 10 | /// path and initial language.
 11 | #[derive(Debug, Default, Clone)]
 12 | pub struct RonLocalizationBuilder {
 13 |     language: String,
 14 |     dictionaries: HashMap<String, Dictionary>,
 15 | }
 16 | 
 17 | impl RonLocalizationBuilder {
 18 |     /// Adds a new dictionary.
 19 |     pub fn dictionary(mut self, key: impl Into<String>, dictionary: &str) -> Self {
 20 |         self.dictionaries
 21 |             .insert(key.into(), Dictionary::from(dictionary));
 22 |         self
 23 |     }
 24 | 
 25 |     /// Sets the initial language.
 26 |     pub fn language(mut self, language: impl Into<String>) -> Self {
 27 |         self.language = language.into();
 28 |         self
 29 |     }
 30 | 
 31 |     /// Builds a new ron localization service.
 32 |     pub fn build(self) -> RonLocalization {
 33 |         RonLocalization {
 34 |             language: self.language,
 35 |             dictionaries: self.dictionaries,
 36 |         }
 37 |     }
 38 | }
 39 | 
 40 | /// `RonLocalization` represents the default implementation of a
 41 | /// localization service based on `ron`.
 42 | ///
 43 | /// # Example
 44 | ///
 45 | /// ```rust
 46 | /// pub const EN_US: &str = include_str!("../assets/dictionary_en_US.ron");
 47 | ///
 48 | /// let localization = RonLocalization::create().language("en_US").dictionary("en_US", EN_US).build();
 49 | /// if let Some(text) = localization.text("hello") {
 50 | ///     println!("{}", text);
 51 | /// }
 52 | /// ```
 53 | #[derive(Debug, Default, Clone)]
 54 | pub struct RonLocalization {
 55 |     language: String,
 56 |     dictionaries: HashMap<String, Dictionary>,
 57 | }
 58 | 
 59 | impl RonLocalization {
 60 |     /// Creates a new `RonLocalizationBuilder` to configure the localization service.
 61 |     pub fn create() -> RonLocalizationBuilder {
 62 |         RonLocalizationBuilder::default()
 63 |     }
 64 | }
 65 | 
 66 | impl Localization for RonLocalization {
 67 |     fn language(&self) -> &String {
 68 |         &self.language
 69 |     }
 70 | 
 71 |     fn set_language(&mut self, key: &str) {
 72 |         self.language = key.to_string();
 73 |     }
 74 | 
 75 |     fn text(&self, key: String) -> String {
 76 |         if let Some(dictionary) = self.dictionaries.get(&self.language) {
 77 |             if let Some(word) = dictionary.words.get(&key) {
 78 |                 return word.clone();
 79 |             }
 80 |         }
 81 | 
 82 |         key
 83 |     }
 84 | }
 85 | 
 86 | #[cfg(test)]
 87 | mod tests {
 88 |     use super::*;
 89 | 
 90 |     #[test]
 91 |     fn test_text() {
 92 |         let de_de = r#"
 93 |         Dictionary(
 94 |             words: {
 95 |                 "hello": "Hallo",
 96 |                 "world": "Welt",
 97 |             }
 98 |         )
 99 |         "#;
100 | 
101 |         let localization = RonLocalization::create()
102 |             .language("de_DE")
103 |             .dictionary("de_DE", de_de)
104 |             .build();
105 | 
106 |         assert_eq!(localization.text("hello".to_string()), "Hallo".to_string());
107 |         assert_eq!(localization.text("world".to_string()), "Welt".to_string());
108 |         assert_eq!(localization.text("test".to_string()), "test".to_string());
109 |     }
110 | }
111 | 


--------------------------------------------------------------------------------
/orbtk_core/src/prelude.rs:
--------------------------------------------------------------------------------
 1 | //! This module pre-selects commonly used OrbTk crates and put them into scope.
 2 | 
 3 | // std
 4 | pub use std::rc::Rc;
 5 | 
 6 | // crates modules
 7 | pub use crate::application::*;
 8 | pub use crate::event::*;
 9 | pub use crate::layout::*;
10 | pub use crate::localization::*;
11 | pub use crate::macros::*;
12 | pub use crate::properties::*;
13 | pub use crate::render_object::*;
14 | pub use crate::services::*;
15 | pub use crate::systems::*;
16 | pub use crate::theming::*;
17 | pub use crate::tree::*;
18 | pub use crate::widget_base::*;
19 | 
20 | pub use crate::{into_property_source, trigger_event, widget};
21 | 


--------------------------------------------------------------------------------
/orbtk_core/src/properties/layout/mod.rs:
--------------------------------------------------------------------------------
1 | // Layout specific properties.
2 | 
3 | pub use self::block::*;
4 | pub use self::scroll_viewer_mode::*;
5 | 
6 | mod block;
7 | mod scroll_viewer_mode;
8 | 


--------------------------------------------------------------------------------
/orbtk_core/src/properties/layout/scroll_viewer_mode.rs:
--------------------------------------------------------------------------------
 1 | /// The `ScrollMode` defines the mode of a scroll direction.
 2 | #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 3 | pub enum ScrollMode {
 4 |     /// Scrolling will process by `ScrollViewer` logic
 5 |     Auto,
 6 | 
 7 |     /// Scrolling could be handled from outside. It will not be
 8 |     /// process by `ScrollViewer` logic.
 9 |     Custom,
10 | 
11 |     /// Scrolling will be disabled.
12 |     Disabled,
13 | }
14 | 
15 | impl Default for ScrollMode {
16 |     fn default() -> Self {
17 |         ScrollMode::Auto
18 |     }
19 | }
20 | 
21 | impl From<&str> for ScrollMode {
22 |     fn from(s: &str) -> ScrollMode {
23 |         match s {
24 |             "Custom" | "custom" => ScrollMode::Custom,
25 |             "Disabled" | "disabled" => ScrollMode::Disabled,
26 |             _ => ScrollMode::Auto,
27 |         }
28 |     }
29 | }
30 | 
31 | /// `ScrollViewerMode` describes the vertical and horizontal scroll
32 | /// behavior of the `ScrollViewer`.
33 | #[derive(Clone, Copy, Debug, Eq, PartialEq)]
34 | pub struct ScrollViewerMode {
35 |     /// Vertical scroll mode.
36 |     pub vertical: ScrollMode,
37 | 
38 |     /// Horizontal scroll mode.
39 |     pub horizontal: ScrollMode,
40 | }
41 | 
42 | // --- Conversions ---
43 | 
44 | impl From<(&str, &str)> for ScrollViewerMode {
45 |     fn from(s: (&str, &str)) -> ScrollViewerMode {
46 |         ScrollViewerMode {
47 |             horizontal: ScrollMode::from(s.0),
48 |             vertical: ScrollMode::from(s.1),
49 |         }
50 |     }
51 | }
52 | 
53 | impl Default for ScrollViewerMode {
54 |     fn default() -> ScrollViewerMode {
55 |         ScrollViewerMode {
56 |             vertical: ScrollMode::Auto,
57 |             horizontal: ScrollMode::Auto,
58 |         }
59 |     }
60 | }
61 | 


--------------------------------------------------------------------------------
/orbtk_core/src/properties/widget/focus_state.rs:
--------------------------------------------------------------------------------
 1 | use crate::{theming::Selector, widget_base::Context};
 2 | 
 3 | use dces::prelude::Entity;
 4 | 
 5 | /// Contains the state information of the current focused element.
 6 | ///
 7 | /// Provides methods to request and remove focus.
 8 | #[derive(Debug, Default, Clone, Eq, PartialEq)]
 9 | pub struct FocusState {
10 |     focused_entity: Option<Entity>,
11 | }
12 | 
13 | impl FocusState {
14 |     /// Request focus for the given entity.
15 |     pub fn request_focus(&mut self, entity: impl Into<Entity>, ctx: &mut Context) {
16 |         let entity = entity.into();
17 | 
18 |         if (self.focused_entity.is_some() && self.focused_entity.unwrap() == entity)
19 |             || !*ctx.get_widget(entity).get::<bool>("enabled")
20 |         {
21 |             return;
22 |         }
23 | 
24 |         if let Some(old_focused_element) = self.focused_entity {
25 |             let mut old_focused_element = ctx.get_widget(old_focused_element);
26 | 
27 |             old_focused_element.set("focused", false);
28 |             old_focused_element
29 |                 .get_mut::<Selector>("selector")
30 |                 .remove_all_similar_states("focused");
31 |             old_focused_element.update(false);
32 |         }
33 | 
34 |         self.focused_entity = Some(entity);
35 | 
36 |         if ctx.get_widget(entity).has::<bool>("focused") {
37 |             let mut focused_element = ctx.get_widget(entity);
38 | 
39 |             focused_element.set("focused", true);
40 |             focused_element
41 |                 .get_mut::<Selector>("selector")
42 |                 .push_state("focused");
43 |             focused_element.update(false);
44 |         }
45 |     }
46 | 
47 |     /// Remove the focus of the given entity. If the given entity is
48 |     /// not the focused entity nothing will happen.
49 |     pub fn remove_focus(&mut self, entity: impl Into<Entity>, ctx: &mut Context) {
50 |         let entity = entity.into();
51 | 
52 |         if let Some(old_focused_element) = self.focused_entity {
53 |             if old_focused_element != entity {
54 |                 return;
55 |             }
56 |             let mut old_focused_element = ctx.get_widget(old_focused_element);
57 |             old_focused_element.set("focused", false);
58 |             old_focused_element
59 |                 .get_mut::<Selector>("selector")
60 |                 .remove_all_similar_states("focused");
61 |             old_focused_element.update(false);
62 |         }
63 | 
64 |         self.focused_entity = None;
65 |     }
66 | 
67 |     /// Returns `true` if the given entity is focused.
68 |     pub fn has_focus(&self, entity: impl Into<Entity>) -> bool {
69 |         self.focused_entity.is_some() && self.focused_entity.unwrap() == entity.into()
70 |     }
71 | 
72 |     /// Returns a reference to the current focused entity.
73 |     pub fn focused_entity(&self) -> &Option<Entity> {
74 |         &self.focused_entity
75 |     }
76 | }
77 | 


--------------------------------------------------------------------------------
/orbtk_core/src/properties/widget/mod.rs:
--------------------------------------------------------------------------------
 1 | // Widget related properties.
 2 | pub use self::focus_state::*;
 3 | pub use self::keyboard_state::*;
 4 | pub use self::render_pipeline::*;
 5 | pub use self::selected_entities::*;
 6 | pub use self::selected_indices::*;
 7 | pub use self::text_selection::*;
 8 | 
 9 | mod focus_state;
10 | mod keyboard_state;
11 | mod render_pipeline;
12 | mod selected_entities;
13 | mod selected_indices;
14 | mod text_selection;
15 | 


--------------------------------------------------------------------------------
/orbtk_core/src/properties/widget/render_pipeline.rs:
--------------------------------------------------------------------------------
 1 | use std::any::Any;
 2 | 
 3 | use crate::render;
 4 | 
 5 | #[derive(Clone, PartialEq)]
 6 | struct EmptyRenderPipeline;
 7 | 
 8 | impl render::PipelineTrait for EmptyRenderPipeline {
 9 |     fn box_eq(&self, other: &dyn Any) -> bool {
10 |         other.downcast_ref::<Self>().map_or(false, |a| self == a)
11 |     }
12 |     fn as_any(&self) -> &dyn Any {
13 |         self
14 |     }
15 | 
16 |     fn clone_box(&self) -> Box<dyn render::PipelineTrait> {
17 |         Box::new(self.clone())
18 |     }
19 | }
20 | 
21 | impl render::RenderPipeline for EmptyRenderPipeline {
22 |     fn draw(&self, _: &mut render::RenderTarget) {}
23 | }
24 | 
25 | /// RenderPipeline object.
26 | #[derive(Clone, Debug)]
27 | pub struct DefaultRenderPipeline(pub Box<dyn render::PipelineTrait>);
28 | 
29 | impl PartialEq for DefaultRenderPipeline {
30 |     fn eq(&self, _other: &Self) -> bool {
31 |         // todo this is workaround for property checking
32 |         false
33 |     }
34 | }
35 | 
36 | impl Default for DefaultRenderPipeline {
37 |     fn default() -> Self {
38 |         DefaultRenderPipeline(Box::new(EmptyRenderPipeline))
39 |     }
40 | }
41 | 


--------------------------------------------------------------------------------
/orbtk_core/src/properties/widget/selected_entities.rs:
--------------------------------------------------------------------------------
 1 | use std::collections::HashSet;
 2 | 
 3 | use dces::prelude::*;
 4 | 
 5 | /// `SelectedEntities` describes a list of selected entities.
 6 | #[derive(Debug, Default, Clone, Eq, PartialEq)]
 7 | pub struct SelectedEntities(pub HashSet<Entity>);
 8 | 
 9 | impl From<HashSet<Entity>> for SelectedEntities {
10 |     fn from(i: HashSet<Entity>) -> Self {
11 |         SelectedEntities(i)
12 |     }
13 | }
14 | 


--------------------------------------------------------------------------------
/orbtk_core/src/properties/widget/selected_indices.rs:
--------------------------------------------------------------------------------
 1 | use std::collections::HashSet;
 2 | 
 3 | /// `SelectedIndices` describes a list of selected indices.
 4 | #[derive(Debug, Default, Clone, Eq, PartialEq)]
 5 | pub struct SelectedIndices(pub HashSet<usize>);
 6 | 
 7 | impl From<HashSet<usize>> for SelectedIndices {
 8 |     fn from(i: HashSet<usize>) -> Self {
 9 |         SelectedIndices(i)
10 |     }
11 | }
12 | 


--------------------------------------------------------------------------------
/orbtk_core/src/properties/widget/text_selection.rs:
--------------------------------------------------------------------------------
 1 | /// Mark the selection inside a text object.
 2 | #[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
 3 | pub struct TextSelection {
 4 |     start: usize,
 5 |     end: usize,
 6 | }
 7 | 
 8 | impl TextSelection {
 9 |     /// Creates a new text selection with an given start and end.
10 |     pub fn new(start: usize, end: usize) -> Self {
11 |         TextSelection { start, end }
12 |     }
13 | 
14 |     /// Gets the start index.
15 |     pub fn start(&self) -> usize {
16 |         self.start
17 |     }
18 | 
19 |     /// Sets the start index.
20 |     pub fn set_start(&mut self, start: usize) {
21 |         self.start = start;
22 |     }
23 | 
24 |     /// Gets the end index.
25 |     pub fn end(&self) -> usize {
26 |         self.end
27 |     }
28 | 
29 |     /// Sets the end index.
30 |     pub fn set_end(&mut self, end: usize) {
31 |         self.end = end;
32 |     }
33 | 
34 |     /// Sets start and end to the same value.
35 |     pub fn set(&mut self, value: usize) {
36 |         self.start = value;
37 |         self.end = value;
38 |     }
39 | 
40 |     /// Gets the length of the selection.
41 |     pub fn len(&self) -> usize {
42 |         (self.start as i32 - self.end as i32).unsigned_abs() as usize
43 |     }
44 | 
45 |     /// Check if the selection is empty (start == end).
46 |     pub fn is_empty(&self) -> bool {
47 |         self.len() == 0
48 |     }
49 | }
50 | 
51 | impl From<(usize, usize)> for TextSelection {
52 |     fn from(t: (usize, usize)) -> Self {
53 |         TextSelection::new(t.0, t.1)
54 |     }
55 | }
56 | 
57 | #[cfg(test)]
58 | mod tests {
59 |     use super::*;
60 | 
61 |     #[test]
62 |     fn test_into() {
63 |         let offset: TextSelection = (14, 16).into();
64 |         assert_eq!(offset.start(), 14);
65 |         assert_eq!(offset.end(), 16);
66 |     }
67 | 
68 |     #[test]
69 |     fn test_len() {
70 |         let offset: TextSelection = (14, 16).into();
71 |         assert_eq!(offset.len(), 2);
72 | 
73 |         let offset: TextSelection = (16, 14).into();
74 |         assert_eq!(offset.len(), 2);
75 |     }
76 | 
77 |     #[test]
78 |     fn test_set() {
79 |         let mut offset: TextSelection = (14, 16).into();
80 |         offset.set(5);
81 | 
82 |         assert_eq!(offset.start(), 5);
83 |         assert_eq!(offset.end(), 5);
84 |     }
85 | }
86 | 


--------------------------------------------------------------------------------
/orbtk_core/src/render_object/cursor.rs:
--------------------------------------------------------------------------------
 1 | use crate::{
 2 |     proc_macros::IntoRenderObject,
 3 |     render_object::*,
 4 |     utils::{Brush, Point, Rectangle, Thickness},
 5 | };
 6 | 
 7 | /// The `CursorRenderObject` is used to render the `Cursor` widget.
 8 | ///
 9 | /// [`Cursor`]: ../../widgets/struct.Cursor.html
10 | #[derive(Debug, IntoRenderObject)]
11 | pub struct CursorRenderObject;
12 | 
13 | impl RenderObject for CursorRenderObject {
14 |     fn render_self(&self, ctx: &mut Context, global_position: &Point) {
15 |         let (
16 |             bounds,
17 |             background,
18 |             border_width,
19 |             border_brush,
20 |             background_opacity,
21 |             cursor_x,
22 |             selection_width,
23 |             selection_x,
24 |             offset,
25 |         ) = {
26 |             let widget = ctx.widget();
27 |             (
28 |                 *widget.get::<Rectangle>("bounds"),
29 |                 widget.get::<Brush>("background").clone(),
30 |                 *widget.get::<Thickness>("border_width"),
31 |                 widget.clone_or_default::<Brush>("border_brush"),
32 |                 *widget.get::<f32>("background_opacity"),
33 |                 *widget.get::<f64>("cursor_x"),
34 |                 *widget.get::<f64>("selection_width"),
35 |                 *widget.get::<f64>("selection_x"),
36 |                 *widget.get::<f64>("offset"),
37 |             )
38 |         };
39 | 
40 |         let border_width = border_width.right();
41 | 
42 |         // background
43 |         ctx.render_context_2_d().set_alpha(background_opacity);
44 |         ctx.render_context_2_d().set_fill_style(background);
45 |         ctx.render_context_2_d().fill_rect(
46 |             global_position.x() + bounds.x() + offset + selection_x - border_width / 2.,
47 |             global_position.y() + bounds.y(),
48 |             selection_width,
49 |             bounds.height(),
50 |         );
51 |         ctx.render_context_2_d().set_alpha(1.);
52 | 
53 |         // border
54 |         ctx.render_context_2_d().set_fill_style(border_brush);
55 |         ctx.render_context_2_d().fill_rect(
56 |             global_position.x() + bounds.x() + offset + cursor_x - border_width / 2.,
57 |             global_position.y() + bounds.y(),
58 |             border_width,
59 |             bounds.height(),
60 |         );
61 |     }
62 | }
63 | 


--------------------------------------------------------------------------------
/orbtk_core/src/render_object/default.rs:
--------------------------------------------------------------------------------
1 | use crate::{proc_macros::IntoRenderObject, render_object::*};
2 | 
3 | /// The `DefaultRenderObject` holds default objects inside
4 | /// a render object.
5 | #[derive(Debug, IntoRenderObject)]
6 | pub struct DefaultRenderObject;
7 | 
8 | impl RenderObject for DefaultRenderObject {}
9 | 


--------------------------------------------------------------------------------
/orbtk_core/src/render_object/font_icon.rs:
--------------------------------------------------------------------------------
 1 | use crate::{
 2 |     proc_macros::IntoRenderObject,
 3 |     render_object::*,
 4 |     utils::{Brush, Point, Rectangle},
 5 | };
 6 | 
 7 | /// The `FontIconRenderObject` holds the font icons inside
 8 | /// a render object.
 9 | #[derive(Debug, IntoRenderObject)]
10 | pub struct FontIconRenderObject;
11 | 
12 | impl RenderObject for FontIconRenderObject {
13 |     fn render_self(&self, ctx: &mut Context, global_position: &Point) {
14 |         let (bounds, icon, icon_brush, icon_font, icon_size) = {
15 |             let widget = ctx.widget();
16 |             (
17 |                 *widget.get::<Rectangle>("bounds"),
18 |                 widget.clone::<String>("icon"),
19 |                 widget.get::<Brush>("icon_brush").clone(),
20 |                 widget.get::<String>("icon_font").clone(),
21 |                 *widget.get::<f64>("icon_size"),
22 |             )
23 |         };
24 | 
25 |         if bounds.width() == 0.0
26 |             || bounds.height() == 0.0
27 |             || icon_brush.is_transparent()
28 |             || icon_size == 0.0
29 |             || icon.is_empty()
30 |         {
31 |             return;
32 |         }
33 | 
34 |         if !icon.is_empty() {
35 |             ctx.render_context_2_d().begin_path();
36 |             ctx.render_context_2_d().set_font_family(icon_font);
37 |             ctx.render_context_2_d().set_font_size(icon_size);
38 |             ctx.render_context_2_d().set_fill_style(icon_brush);
39 | 
40 |             ctx.render_context_2_d().fill_text(
41 |                 &icon,
42 |                 global_position.x() + bounds.x(),
43 |                 global_position.y() + bounds.y(),
44 |             );
45 |             ctx.render_context_2_d().close_path();
46 |         }
47 |     }
48 | }
49 | 


--------------------------------------------------------------------------------
/orbtk_core/src/render_object/image.rs:
--------------------------------------------------------------------------------
 1 | use crate::{proc_macros::IntoRenderObject, render::Image, render_object::*};
 2 | 
 3 | /// Used to render an image.
 4 | #[derive(Debug, IntoRenderObject)]
 5 | pub struct ImageRenderObject;
 6 | 
 7 | impl RenderObject for ImageRenderObject {
 8 |     fn render_self(&self, ctx: &mut Context, global_position: &Point) {
 9 |         let (bounds, mut image) = {
10 |             let widget = ctx.widget();
11 |             (
12 |                 widget.clone::<Rectangle>("bounds"),
13 |                 widget.try_clone::<Image>("image"),
14 |             )
15 |         };
16 | 
17 |         if let Some(image) = &mut image {
18 |             ctx.render_context_2_d().draw_image(
19 |                 image,
20 |                 bounds.x() + global_position.x(),
21 |                 bounds.y() + global_position.y(),
22 |             );
23 |         }
24 |     }
25 | }
26 | 


--------------------------------------------------------------------------------
/orbtk_core/src/render_object/pipeline.rs:
--------------------------------------------------------------------------------
 1 | use crate::{proc_macros::IntoRenderObject, render_object::*};
 2 | 
 3 | /// Structure that defines a pipeline for a render object.
 4 | #[derive(Debug, IntoRenderObject)]
 5 | pub struct PipelineRenderObject;
 6 | 
 7 | impl RenderObject for PipelineRenderObject {
 8 |     fn render_self(&self, ctx: &mut Context, _: &Point) {
 9 |         let bounds = *ctx.widget().get::<Rectangle>("bounds");
10 |         let pipeline = ctx
11 |             .widget()
12 |             .get::<DefaultRenderPipeline>("render_pipeline")
13 |             .0
14 |             .clone();
15 | 
16 |         ctx.render_context_2_d().draw_pipeline(
17 |             bounds.x(),
18 |             bounds.y(),
19 |             bounds.width(),
20 |             bounds.height(),
21 |             pipeline,
22 |         );
23 |     }
24 | }
25 | 


--------------------------------------------------------------------------------
/orbtk_core/src/render_object/text.rs:
--------------------------------------------------------------------------------
 1 | use crate::{
 2 |     proc_macros::IntoRenderObject,
 3 |     render_object::*,
 4 |     utils::{Brush, Point, Rectangle},
 5 | };
 6 | use memchr::memchr_iter;
 7 | use std::iter;
 8 | 
 9 | /// Used to render a text.
10 | #[derive(Debug, IntoRenderObject)]
11 | pub struct TextRenderObject;
12 | 
13 | impl RenderObject for TextRenderObject {
14 |     fn render_self(&self, ctx: &mut Context, global_position: &Point) {
15 |         let (bounds, text, foreground, font, font_size, offset) = {
16 |             let widget = ctx.widget();
17 |             let text = text(&widget);
18 |             let offset = *widget.get::<f64>("offset");
19 | 
20 |             let txt = {
21 |                 if !text.is_empty() {
22 |                     text
23 |                 } else {
24 |                     widget.clone_or_default::<String>("water_mark")
25 |                 }
26 |             };
27 |             (
28 |                 *widget.get::<Rectangle>("bounds"),
29 |                 txt,
30 |                 widget.get::<Brush>("foreground").clone(),
31 |                 widget.get::<String>("font").clone(),
32 |                 *widget.get::<f64>("font_size"),
33 |                 offset,
34 |             )
35 |         };
36 | 
37 |         if bounds.width() == 0.0
38 |             || bounds.height() == 0.0
39 |             || foreground.is_transparent()
40 |             || font_size == 0.0
41 |             || text.is_empty()
42 |         {
43 |             return;
44 |         }
45 |         if text.is_empty() {
46 |             return;
47 |         }
48 | 
49 |         ctx.render_context_2_d().begin_path();
50 |         ctx.render_context_2_d().set_font_family(font);
51 |         ctx.render_context_2_d().set_font_size(font_size);
52 |         ctx.render_context_2_d().set_fill_style(foreground);
53 | 
54 |         let mut y_disp = 0.0;
55 |         let mut last_ofs = 0;
56 |         for i in memchr_iter(b'\n', text.as_bytes()).chain(iter::once(text.len())) {
57 |             ctx.render_context_2_d().fill_text(
58 |                 &text[last_ofs..i],
59 |                 global_position.x() + bounds.x() + offset,
60 |                 global_position.y() + bounds.y() + y_disp,
61 |             );
62 |             y_disp += font_size * 1.15; // TODO: Make the space between lines customizable
63 |             last_ofs = i + 1; // + 1 to skip the end of line character
64 |         }
65 | 
66 |         ctx.render_context_2_d().close_path();
67 |     }
68 | }
69 | 
70 | fn text(widget: &WidgetContainer) -> String {
71 |     if let Some(localizable) = widget.try_get::<bool>("localizable") {
72 |         if *localizable {
73 |             if let Some(localized_text) = widget.try_get::<String>("localized_text") {
74 |                 if !localized_text.is_empty() {
75 |                     return localized_text.clone();
76 |                 }
77 |             }
78 |         }
79 |     }
80 | 
81 |     if let Some(text) = widget.try_get::<String>("text") {
82 |         return text.clone();
83 |     }
84 | 
85 |     String::default()
86 | }
87 | 


--------------------------------------------------------------------------------
/orbtk_core/src/services/clipboard.rs:
--------------------------------------------------------------------------------
 1 | /// Clipboard leads you read and store a value.
 2 | ///
 3 | /// To access the value of systems clipboard it must be used in
 4 | /// combination with a window shell.
 5 | ///
 6 | /// # Examples
 7 | /// ```
 8 | /// impl State for MyState {
 9 | ///     fn update(&mut self, registry: &mut Registry, _: &mut Context) {
10 | ///         let mut clipboard = registry.get_mut;:<Clipboard>("clipboard");
11 | ///         println!("{:?}", clipboard.get());
12 | ///         clipboard.set("paste");
13 | ///     }
14 | /// }
15 | /// ```
16 | #[derive(Clone, Default, Debug)]
17 | pub struct Clipboard {
18 |     value: Option<String>,
19 | }
20 | 
21 | impl Clipboard {
22 |     /// Creates a new clipboard with default values.
23 |     pub fn new() -> Self {
24 |         Clipboard::default()
25 |     }
26 | 
27 |     /// Return the latest value of the clipboard.
28 |     /// If there is no value present on the clipboard it will return `None`.
29 |     pub fn get(&self) -> Option<String> {
30 |         self.value.clone()
31 |     }
32 | 
33 |     /// Sets the value of the clipboard.
34 |     pub fn set(&mut self, value: impl Into<String>) {
35 |         self.value = Some(value.into());
36 |     }
37 | }
38 | 
39 | #[cfg(test)]
40 | mod tests {
41 |     use super::*;
42 | 
43 |     #[test]
44 |     /// A quick test to ensure that the items are properly set.
45 |     fn get_set() {
46 |         let mut clipboard = Clipboard::new();
47 |         let test = String::from("test");
48 |         clipboard.set(test.clone());
49 |         assert_eq!(test, clipboard.get().unwrap());
50 |     }
51 | }
52 | 


--------------------------------------------------------------------------------
/orbtk_core/src/services/mod.rs:
--------------------------------------------------------------------------------
1 | //! This module contains global services.
2 | //!
3 | pub use self::clipboard::*;
4 | pub use self::settings::*;
5 | 
6 | mod clipboard;
7 | mod settings;
8 | 


--------------------------------------------------------------------------------
/orbtk_core/src/systems/cleanup_system.rs:
--------------------------------------------------------------------------------
 1 | use std::{cell::RefCell, rc::Rc};
 2 | 
 3 | use dces::prelude::*;
 4 | 
 5 | use crate::{prelude::*, render::RenderContext2D, theming::Theme, tree::Tree};
 6 | 
 7 | /// Handles the inner cleanup while window is closing.
 8 | #[derive(Constructor)]
 9 | pub struct CleanupSystem {
10 |     context_provider: ContextProvider,
11 |     registry: Rc<RefCell<Registry>>,
12 | }
13 | 
14 | impl System<Tree, RenderContext2D> for CleanupSystem {
15 |     fn run_with_context(
16 |         &self,
17 |         ecm: &mut EntityComponentManager<Tree>,
18 |         render_context: &mut RenderContext2D,
19 |     ) {
20 |         // let mut shell = self.shell.borrow_mut();
21 |         let root = ecm.entity_store().root();
22 |         let theme = ecm
23 |             .component_store()
24 |             .get::<Rc<Theme>>("theme", root)
25 |             .unwrap()
26 |             .clone();
27 | 
28 |         let mut dirty_index = 0;
29 | 
30 |         loop {
31 |             if dirty_index
32 |                 >= ecm
33 |                     .component_store()
34 |                     .get::<Vec<Entity>>("dirty_widgets", root)
35 |                     .unwrap()
36 |                     .len()
37 |             {
38 |                 break;
39 |             }
40 | 
41 |             let skip = false;
42 | 
43 |             let widget = *ecm
44 |                 .component_store()
45 |                 .get::<Vec<Entity>>("dirty_widgets", root)
46 |                 .unwrap()
47 |                 .get(dirty_index)
48 |                 .unwrap();
49 | 
50 |             let mut keys = vec![];
51 | 
52 |             if !skip {
53 |                 let registry = &mut self.registry.borrow_mut();
54 | 
55 |                 let mut ctx = Context::new(
56 |                     (widget, ecm),
57 |                     &theme,
58 |                     &self.context_provider,
59 |                     render_context,
60 |                 );
61 | 
62 |                 if let Some(state) = self.context_provider.states.borrow_mut().get_mut(&widget) {
63 |                     state.cleanup(registry, &mut ctx);
64 |                 }
65 | 
66 |                 keys.append(&mut ctx.new_states_keys());
67 |             }
68 | 
69 |             dirty_index += 1;
70 |         }
71 |     }
72 | }
73 | 


--------------------------------------------------------------------------------
/orbtk_core/src/systems/init_system.rs:
--------------------------------------------------------------------------------
 1 | use std::{cell::RefCell, rc::Rc};
 2 | 
 3 | use dces::prelude::*;
 4 | 
 5 | use crate::{prelude::*, render::RenderContext2D, theming::Selector, tree::Tree};
 6 | 
 7 | /// This system is used to initializes the widgets.
 8 | #[derive(Constructor)]
 9 | pub struct InitSystem {
10 |     context_provider: ContextProvider,
11 |     registry: Rc<RefCell<Registry>>,
12 | }
13 | 
14 | impl System<Tree, RenderContext2D> for InitSystem {
15 |     fn run_with_context(
16 |         &self,
17 |         ecm: &mut EntityComponentManager<Tree>,
18 |         render_context: &mut RenderContext2D,
19 |     ) {
20 |         let root = ecm.entity_store().root();
21 | 
22 |         #[cfg(feature = "debug")]
23 |         let debug = true;
24 |         #[cfg(not(feature = "debug"))]
25 |         let debug = false;
26 | 
27 |         if debug {
28 |             crate::shell::CONSOLE.log("\n------ Widget tree ------\n".to_string());
29 | 
30 |             print_tree(root, 0, ecm);
31 | 
32 |             crate::shell::CONSOLE.log("\n------ Widget tree ------\n".to_string());
33 |         }
34 | 
35 |         // init css ids
36 |         let theme = ecm
37 |             .component_store()
38 |             .get::<Rc<Theme>>("theme", root)
39 |             .unwrap()
40 |             .clone();
41 | 
42 |         let mut current_node = root;
43 | 
44 |         loop {
45 |             {
46 |                 let mut ctx = Context::new(
47 |                     (current_node, ecm),
48 |                     &theme,
49 |                     &self.context_provider,
50 |                     render_context,
51 |                 );
52 | 
53 |                 if let Some(state) = self
54 |                     .context_provider
55 |                     .states
56 |                     .borrow_mut()
57 |                     .get_mut(&current_node)
58 |                 {
59 |                     state.init(&mut *self.registry.borrow_mut(), &mut ctx);
60 |                 }
61 | 
62 |                 drop(ctx);
63 |             }
64 | 
65 |             let mut it = ecm.entity_store().start_node(current_node).into_iter();
66 |             it.next();
67 | 
68 |             if let Some(node) = it.next() {
69 |                 current_node = node;
70 |             } else {
71 |                 break;
72 |             }
73 |         }
74 |     }
75 | }
76 | 
77 | pub fn print_tree(entity: Entity, depth: usize, ecm: &mut EntityComponentManager<Tree>) {
78 |     let name = ecm.component_store().get::<String>("name", entity).unwrap();
79 | 
80 |     let selector = if let Ok(selector) = ecm.component_store().get::<Selector>("selector", entity) {
81 |         selector.clone()
82 |     } else {
83 |         Selector::default()
84 |     };
85 | 
86 |     crate::shell::CONSOLE.log(format!(
87 |         "{}{} (entity: {}, {})",
88 |         "| ".repeat(depth),
89 |         name,
90 |         entity.0,
91 |         selector
92 |     ));
93 | 
94 |     for child in ecm.entity_store().clone().children.get(&entity).unwrap() {
95 |         print_tree(*child, depth + 1, ecm);
96 |     }
97 | }
98 | 


--------------------------------------------------------------------------------
/orbtk_core/src/systems/layout_system.rs:
--------------------------------------------------------------------------------
 1 | use dces::prelude::*;
 2 | 
 3 | use crate::{prelude::*, render::RenderContext2D, tree::Tree, utils::*};
 4 | 
 5 | /// The `LayoutSystem` takes care to rebuild the layout of the current
 6 | /// `UI` on a per iteration cycle. `layout widgets` are organized in
 7 | /// layout objects, that will in term calculate the resulting
 8 | /// positions of it objects inside the view.
 9 | #[derive(Constructor)]
10 | pub struct LayoutSystem {
11 |     context_provider: ContextProvider,
12 | }
13 | 
14 | impl System<Tree, RenderContext2D> for LayoutSystem {
15 |     fn run_with_context(
16 |         &self,
17 |         ecm: &mut EntityComponentManager<Tree>,
18 |         render_context: &mut RenderContext2D,
19 |     ) {
20 |         let root = ecm.entity_store().root();
21 | 
22 |         if ecm
23 |             .component_store()
24 |             .get::<Vec<Entity>>("dirty_widgets", root)
25 |             .unwrap()
26 |             .is_empty()
27 |             && !self.context_provider.first_run.get()
28 |         {
29 |             return;
30 |         }
31 | 
32 |         let mut window_size = (0.0, 0.0);
33 |         let root = ecm.entity_store().root();
34 | 
35 |         if let Ok(bounds) = ecm.component_store().get::<Rectangle>("bounds", root) {
36 |             window_size.0 = bounds.width();
37 |             window_size.1 = bounds.height();
38 |         };
39 | 
40 |         let theme = ecm
41 |             .component_store()
42 |             .get::<Rc<Theme>>("theme", root)
43 |             .unwrap()
44 |             .clone();
45 | 
46 |         self.context_provider.layouts.borrow()[&root].measure(
47 |             render_context,
48 |             root,
49 |             ecm,
50 |             &self.context_provider.layouts.borrow(),
51 |             &theme,
52 |         );
53 | 
54 |         self.context_provider.layouts.borrow()[&root].arrange(
55 |             render_context,
56 |             window_size,
57 |             root,
58 |             ecm,
59 |             &self.context_provider.layouts.borrow(),
60 |             &theme,
61 |         );
62 | 
63 |         // if self.debug_flag.get() {
64 |         //     println!("\n------ End layout update   ------\n");
65 |         // }
66 |     }
67 | }
68 | 


--------------------------------------------------------------------------------
/orbtk_core/src/systems/mod.rs:
--------------------------------------------------------------------------------
 1 | //! Provides dedicated `system` pipelines inside OrbTk.
 2 | //!
 3 | //! System pipelines are modules, that handle specific tasks when
 4 | //! iteratively walking the widget tree. Because each widget
 5 | //! implements the `state` trait, all system modules are accessible.
 6 | //! Pipelines are connected in a logical order. E.g. the `InitSystem`
 7 | //! is triggered **before** the `LayoutSystem`. The `LayoutSystem` is
 8 | //! triggerd **before** the `RenderSystem`. Handling of widget objects
 9 | //! inside the pipelines rely on the Entity Component System
10 | //! ([`DCES`]).
11 | //!
12 | //! [`DCES`]: https://gitlab.redox-os.org/redox-os/dces-rust
13 | 
14 | pub use self::cleanup_system::*;
15 | pub use self::event_state_system::*;
16 | pub use self::init_system::*;
17 | pub use self::layout_system::*;
18 | pub use self::post_layout_state_system::*;
19 | pub use self::render_system::*;
20 | 
21 | mod cleanup_system;
22 | mod event_state_system;
23 | mod init_system;
24 | mod layout_system;
25 | mod post_layout_state_system;
26 | mod render_system;
27 | 


--------------------------------------------------------------------------------
/orbtk_core/src/systems/render_system.rs:
--------------------------------------------------------------------------------
 1 | use std::collections::BTreeMap;
 2 | 
 3 | use dces::prelude::*;
 4 | 
 5 | use crate::{prelude::*, render::RenderContext2D, tree::Tree};
 6 | 
 7 | /// The `RenderSystem` iterates over all visual widgets.
 8 | ///
 9 | /// For any widgets that have been marked dirty, new bounds have to be
10 | /// recalculated. The resulting tree is rendered to the render buffer
11 | /// which is then drawn to the screen.
12 | #[derive(Constructor)]
13 | pub struct RenderSystem {
14 |     context_provider: ContextProvider,
15 | }
16 | 
17 | impl System<Tree, RenderContext2D> for RenderSystem {
18 |     fn run_with_context(
19 |         &self,
20 |         ecm: &mut EntityComponentManager<Tree>,
21 |         render_context: &mut RenderContext2D,
22 |     ) {
23 |         let root = ecm.entity_store().root();
24 | 
25 |         let dirty_widgets = ecm
26 |             .component_store()
27 |             .get::<Vec<Entity>>("dirty_widgets", root)
28 |             .unwrap()
29 |             .clone();
30 | 
31 |         // Only process, if
32 |         // * there are `dirty` elements inside the entity vector
33 |         // * context_provider it marked for first_run.
34 |         if dirty_widgets.is_empty() && !self.context_provider.first_run.get() {
35 |             return;
36 |         }
37 | 
38 |         // reset the dirty flag of all dirty widgets to `false`
39 |         for widget in dirty_widgets {
40 |             if let Ok(dirty) = ecm.component_store_mut().get_mut::<bool>("dirty", widget) {
41 |                 *dirty = false;
42 |             }
43 |         }
44 | 
45 |         ecm.component_store_mut()
46 |             .get_mut::<Vec<Entity>>("dirty_widgets", root)
47 |             .unwrap()
48 |             .clear();
49 | 
50 |         #[cfg(feature = "debug")]
51 |         let debug = true;
52 |         #[cfg(not(feature = "debug"))]
53 |         let debug = false;
54 | 
55 |         let root = ecm.entity_store().root();
56 |         let theme = ecm
57 |             .component_store()
58 |             .get::<Rc<Theme>>("theme", root)
59 |             .unwrap()
60 |             .clone();
61 | 
62 |         let mut offsets = BTreeMap::new();
63 |         offsets.insert(root, (0.0, 0.0));
64 | 
65 |         // CONSOLE.time("render");
66 | 
67 |         render_context.start();
68 |         render_context.begin_path();
69 |         self.context_provider.render_objects.borrow()[&root].render(
70 |             render_context,
71 |             root,
72 |             ecm,
73 |             &self.context_provider,
74 |             &theme,
75 |             &mut offsets,
76 |             debug,
77 |         );
78 |         render_context.finish();
79 | 
80 |         if self.context_provider.first_run.get() {
81 |             self.context_provider.first_run.set(false);
82 |         }
83 |     }
84 | }
85 | 


--------------------------------------------------------------------------------
/orbtk_core/src/theming/config/mod.rs:
--------------------------------------------------------------------------------
1 | pub use self::style_config::*;
2 | pub use self::theme_config::*;
3 | 
4 | mod style_config;
5 | mod theme_config;
6 | 


--------------------------------------------------------------------------------
/orbtk_core/src/theming/config/style_config.rs:
--------------------------------------------------------------------------------
 1 | use std::collections::HashMap;
 2 | 
 3 | use ron::Value;
 4 | use serde_derive::{Deserialize, Serialize};
 5 | 
 6 | use crate::theming::ThemeState;
 7 | 
 8 | /// Defines a style. A style could be base on other styles and
 9 | /// contains a list for properties and a list of state properties.
10 | #[derive(Default, Clone, Debug, Serialize, Deserialize)]
11 | pub struct StyleConfig {
12 |     // set default string to base style
13 |     #[serde(default)]
14 |     pub base: String,
15 |     #[serde(default)]
16 |     pub states: Vec<ThemeState>,
17 |     #[serde(default)]
18 |     pub properties: HashMap<String, Value>,
19 | }
20 | 


--------------------------------------------------------------------------------
/orbtk_core/src/theming/config/theme_config.rs:
--------------------------------------------------------------------------------
 1 | use std::collections::HashMap;
 2 | 
 3 | use ron::{de::from_str, Value};
 4 | use serde_derive::{Deserialize, Serialize};
 5 | 
 6 | use crate::theming::config::StyleConfig;
 7 | 
 8 | pub static BASE_STYLE: &str = "base";
 9 | pub static RESOURCE_KEY: &str = "
quot;;
10 | 
11 | /// Used to store and read properties that could be requested by a
12 | /// given property name and a selector.
13 | #[derive(Default, Clone, Debug, Serialize, Deserialize)]
14 | #[serde(rename = "Theme")]
15 | pub struct ThemeConfig {
16 |     #[serde(default)]
17 |     pub styles: HashMap<String, StyleConfig>,
18 |     #[serde(default)]
19 |     pub resources: HashMap<String, Value>,
20 | }
21 | 
22 | impl ThemeConfig {
23 |     /// Extends the given theme with another theme. Replaces the
24 |     /// current name with the new choosen name `other`.  If `other`
25 |     /// contains a style with the same key entry, this key will be
26 |     /// replaced in the current theme.
27 |     pub fn extend(mut self, other: ThemeConfig) -> Self {
28 |         let mut other = other;
29 | 
30 |         for style in other.styles.drain() {
31 |             self.styles.insert(style.0, style.1);
32 |         }
33 | 
34 |         for resource in other.resources.drain() {
35 |             self.resources.insert(resource.0, resource.1);
36 |         }
37 | 
38 |         self
39 |     }
40 | }
41 | 
42 | impl From<&str> for ThemeConfig {
43 |     fn from(s: &str) -> Self {
44 |         from_str(s).unwrap()
45 |     }
46 | }
47 | 


--------------------------------------------------------------------------------
/orbtk_core/src/theming/mod.rs:
--------------------------------------------------------------------------------
 1 | //! This module contains the theming methods, that handle runtime based rendering of OrbTk entities.
 2 | 
 3 | pub use self::config::*;
 4 | pub use self::selector::*;
 5 | pub use self::style::*;
 6 | pub use self::theme::*;
 7 | pub use self::theme_state::*;
 8 | 
 9 | mod config;
10 | mod selector;
11 | mod style;
12 | mod theme;
13 | mod theme_state;
14 | 


--------------------------------------------------------------------------------
/orbtk_core/src/theming/selector.rs:
--------------------------------------------------------------------------------
  1 | use std::fmt;
  2 | 
  3 | /// The selector is used to read a property value from the `Theme`.
  4 | #[derive(Debug, Clone, Default, Eq, PartialEq)]
  5 | pub struct Selector {
  6 |     /// Represents the key of a style.
  7 |     pub style: Option<String>,
  8 | 
  9 |     // Used to reference the state property list of the given
 10 |     // style. The state on the top of the vector is the active one.
 11 |     states: Vec<String>,
 12 | 
 13 |     /// Check if the selector is dirty.
 14 |     dirty: bool,
 15 | }
 16 | 
 17 | impl Selector {
 18 |     /// Creates a new selector with the given style key.
 19 |     pub fn new(style: impl Into<String>) -> Self {
 20 |         Selector {
 21 |             style: Some(style.into()),
 22 |             states: vec![],
 23 |             dirty: true,
 24 |         }
 25 |     }
 26 | 
 27 |     /// Returns a reference to list of active states.
 28 |     pub fn states(&self) -> &Vec<String> {
 29 |         &self.states
 30 |     }
 31 | 
 32 |     /// Pushes a state to the states vector.
 33 |     pub fn push_state(&mut self, state: impl Into<String>) {
 34 |         let state = state.into();
 35 | 
 36 |         if self.states.contains(&state) {
 37 |             return;
 38 |         }
 39 | 
 40 |         self.states.push(state);
 41 |         self.dirty = true;
 42 |     }
 43 | 
 44 |     /// Removes all states with a similar name compared to the given pattern.
 45 |     pub fn remove_all_similar_states(&mut self, pattern: &str) {
 46 |         while let Some(pos) = self.states.iter().position(|x| x.contains(pattern)) {
 47 |             self.states.remove(pos);
 48 |             self.dirty = true;
 49 |         }
 50 |     }
 51 | 
 52 |     /// Removes all instances of the give state from the vector and returns it.
 53 |     pub fn remove_state(&mut self, state: impl Into<String>) -> Option<String> {
 54 |         let state: String = state.into();
 55 | 
 56 |         if !state.is_empty() && self.states.contains(&state) {
 57 |             while let Some(pos) = self.states.iter().position(|x| *x == state) {
 58 |                 self.states.remove(pos);
 59 |             }
 60 | 
 61 |             self.dirty = true;
 62 |             return Some(state);
 63 |         }
 64 | 
 65 |         None
 66 |     }
 67 | 
 68 |     /// Removes the last state from a vector and returns it, or None
 69 |     /// if it is empty. If there is a new last vector it will be the
 70 |     /// new active state.
 71 |     pub fn pop_state(&mut self) -> Option<String> {
 72 |         self.dirty = true;
 73 |         self.states.pop()
 74 |     }
 75 | 
 76 |     /// Gets the dirty flag.
 77 |     pub fn dirty(&self) -> bool {
 78 |         self.dirty
 79 |     }
 80 | 
 81 |     /// Sets the dirty flag.
 82 |     pub fn set_dirty(&mut self, dirty: bool) {
 83 |         self.dirty = dirty;
 84 |     }
 85 | 
 86 |     /// Check if the selector has the given state.
 87 |     pub fn has_state(&self, state: &str) -> bool {
 88 |         self.states.contains(&state.to_string())
 89 |     }
 90 | }
 91 | 
 92 | impl fmt::Display for Selector {
 93 |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 94 |         if let Some(style) = &self.style {
 95 |             return write!(f, "Selector ( style: {} )", style);
 96 |         }
 97 |         write!(f, "Selector ( empty )")
 98 |     }
 99 | }
100 | 
101 | impl From<&str> for Selector {
102 |     fn from(s: &str) -> Self {
103 |         Selector::new(s)
104 |     }
105 | }
106 | 
107 | impl From<String> for Selector {
108 |     fn from(s: String) -> Self {
109 |         Selector::new(s)
110 |     }
111 | }
112 | 


--------------------------------------------------------------------------------
/orbtk_core/src/theming/style.rs:
--------------------------------------------------------------------------------
 1 | use std::collections::HashMap;
 2 | 
 3 | use super::ThemeState;
 4 | 
 5 | use ron::Value;
 6 | 
 7 | /// A style is used internaly by `Theme`. It contains a map of default
 8 | /// properties beside a list of states.
 9 | #[derive(Debug, Default, Clone, Eq, PartialEq)]
10 | pub struct Style {
11 |     /// Represents the map of default properties.
12 |     pub properties: HashMap<String, Value>,
13 | 
14 |     /// Represents the list of states.
15 |     pub states: Vec<ThemeState>,
16 | }
17 | 
18 | impl Style {
19 |     /// Creates a new style.
20 |     pub fn new() -> Self {
21 |         Style::default()
22 |     }
23 | }
24 | 


--------------------------------------------------------------------------------
/orbtk_core/src/theming/theme_state.rs:
--------------------------------------------------------------------------------
 1 | use std::collections::HashMap;
 2 | 
 3 | use serde_derive::{Deserialize, Serialize};
 4 | 
 5 | use ron::Value;
 6 | 
 7 | /// Contains a list of properties corresponding to the state key.
 8 | #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
 9 | pub struct ThemeState {
10 |     #[serde(default)]
11 |     pub key: String,
12 |     #[serde(default)]
13 |     pub properties: HashMap<String, Value>,
14 | }
15 | 
16 | impl ThemeState {
17 |     /// Creates a new state.
18 |     pub fn new(key: String) -> Self {
19 |         ThemeState {
20 |             key,
21 |             ..Default::default()
22 |         }
23 |     }
24 | }
25 | 


--------------------------------------------------------------------------------
/orbtk_core/src/widget_base/template.rs:
--------------------------------------------------------------------------------
 1 | use dces::prelude::Entity;
 2 | 
 3 | use crate::{layout::*, render_object::*};
 4 | 
 5 | use super::BuildContext;
 6 | 
 7 | /// The `Template` trait is used to implement a particular widget type.
 8 | ///
 9 | /// When a widget's `Template` is implemented, it provides three object types:
10 | /// * a template objet (with default values for its properties, children, handlers)
11 | /// * a render object
12 | /// * a layout object
13 | pub trait Template: Sized {
14 |     /// Builds the template of the widget and returns it.
15 |     ///
16 |     /// # Arguments
17 |     /// * `_id`: The id (Entity) of the instantiated widget in the Entity Store
18 |     /// * `_context`: The BuildContext used to build and instantiate new widgets
19 |     ///
20 |     /// # Example
21 |     ///
22 |     /// Define a widget called MyWidget with min, max and val
23 |     /// properties. The properties have a type of `usize` and we do
24 |     /// preset suitable default values. The definition is completed
25 |     /// with a TextBlock widget, that is the only child.
26 |     ///
27 |     /// ```rust
28 |     /// widget!(MyWidget {
29 |     ///     min: usize,
30 |     ///     max: usize,
31 |     ///     val: usize
32 |     /// });
33 |     ///
34 |     /// impl Template for MyWidget {
35 |     ///     fn template(self, _id: Entity, context: &mut BuildContext) -> Self {
36 |     ///         self.name("MyWidget")
37 |     ///             .min(100)
38 |     ///             .max(1000)
39 |     ///             .val(500)
40 |     ///             .child(TextBlock::new().text("Set a value!").build(context))
41 |     ///     }
42 |     ///
43 |     ///     fn render_object(&self) -> Box<dyn RenderObject> {
44 |     ///         Box::new(RectangleRenderObject)
45 |     ///     }
46 |     ///
47 |     ///     fn layout(&self) -> Box<dyn Layout> {
48 |     ///        Box::new(AbsoluteLayout)
49 |     ///     }
50 |     /// }
51 |     /// ```
52 |     fn template(self, _id: Entity, _ctx: &mut BuildContext) -> Self {
53 |         self
54 |     }
55 | 
56 |     /// Returns a pointer to a heap allocated object.
57 |     ///
58 |     /// Widgets will be rendered as pixmaps inside the render buffer.
59 |     /// For the list of available render objects, see the
60 |     /// [`render_object`] module.
61 |     ///
62 |     /// [`render_object`]: ../../orbtk_core/render_object/index.html
63 |     fn render_object(&self) -> Box<dyn RenderObject> {
64 |         DefaultRenderObject.into()
65 |     }
66 | 
67 |     /// Returns a pointer to a heap allocated object.
68 |     ///
69 |     /// The `layout` process will arrange all `box` entities of a widget
70 |     /// in a tree, were size properties will meet the individual constraints.
71 |     /// For the list of available layout objects, see
72 |     /// the [`layout`] module.
73 |     ///
74 |     /// [`layout`]: ../../orbtk_core/layout/index.html
75 |     fn layout(&self) -> Box<dyn Layout> {
76 |         GridLayout::new().into()
77 |     }
78 | }
79 | 


--------------------------------------------------------------------------------
/orbtk_orbclient/Cargo.toml:
--------------------------------------------------------------------------------
 1 | [package]
 2 | authors = ["Florian Blasius <flovanpt@posteo.de>"]
 3 | description = "Window shell crate used by OrbTk."
 4 | edition = "2021"
 5 | keywords = ["shell", "window", "ui"]
 6 | license = "MIT"
 7 | name = "orbtk_orbclient"
 8 | readme = "README.md"
 9 | repository = "https://github.com/redox-os/orbtk"
10 | version = "0.3.1-alpha5"
11 | 
12 | [dependencies]
13 | image = { version = "0.24", default-features = false, features = ["ico"] }
14 | lazy_static = "1.4.0"
15 | orbtk_tinyskia = { path = "../orbtk_tinyskia", version = "0.3.1-alpha5", default-features = false }
16 | orbtk_utils = { path = "../utils", version = "0.3.1-alpha5" }
17 | raw-window-handle = { version = "0.4" }
18 | 
19 | [dependencies.orbclient]
20 | #version = "0.3.33"
21 | # git reference is needed until PR is merged upstream
22 | git = "https://gitlab.redox-os.org/rzerres/orbclient.git"
23 | branch = "master"
24 | default-features = false
25 | 
26 | [features]
27 | log = []
28 | bundled = ["sdl2/bundled", "sdl2/static-link", "orbclient/bundled"]
29 | 
30 | [lib]
31 | doctest = false
32 | 
33 | [target.'cfg(not(target_os = "redox"))'.dependencies]
34 | sdl2 = { version = "0.35", features = ["raw-window-handle"] }
35 | 


--------------------------------------------------------------------------------
/orbtk_orbclient/README.md:
--------------------------------------------------------------------------------
 1 | # orbtk_orbclient
 2 | 
 3 | This crate offers a cross platform `window shell` library. It's part of
 4 | [OrbTk](https://gitlab.redox-os.org/redox-os/orbtk) - The Rust
 5 | UI-Toolkit.
 6 | 
 7 | [![Build and test](https://github.com/redox-os/orbtk/workflows/CI/badge.svg)](https://github.com/redox-os/orbtk/actions)
 8 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
 9 | 
10 | ## Platforms
11 | 
12 | * Redox OS
13 | * Linux
14 | * macOS
15 | * Windows
16 | * openBSD (not tested, but should work)
17 | * Web
18 | * Android (planned)
19 | * iOS (planned)
20 | * Ubuntu Touch (planned)
21 | 
22 | ## Dependencies
23 | 
24 | * [lazy_static](https://github.com/rust-lang-nursery/lazy-static.rs) (MIT): A macro for declaring lazily evaluated statics in Rust
25 | * [image](https://github.com/image-rs/image) (MIT): load pixel images e.g. png
26 | * [orbclient](https://gitlab.redox-os.org/redox-os/orbclient) (MIT): The Orbital Client Library
27 | * [raw-window-handle](https://github.com/rust-windowing/raw-window-handle) (MIT): access to a window's platform-specific raw window handle
28 | * [sdl2](https://www.libsdl.org) (zlib): Simple DirectMedia Layer
29 | * [stdweb](https://github.com/koute/stdweb) (Apache 2.0, MIT): web window and events
30 | 
31 | ## License
32 | 
33 | Licensed under MIT license ([LICENSE](../../LICENSE)).


--------------------------------------------------------------------------------
/orbtk_orbclient/src/lib.rs:
--------------------------------------------------------------------------------
  1 | /*!
  2 | 
  3 | Window shell abstraction layer used by OrbTk. Provides support for desktop and web.
  4 | 
  5 | # Example
  6 | 
  7 | Basic usage of the shell:
  8 | 
  9 | ```rust,no_run
 10 | 
 11 | use orbtk_orbclient::prelude::*;
 12 | 
 13 | let shell = WindowBuilder::new(MyCustomWindowAdapter::new())
 14 |                         .title("Window")
 15 |                         .bounds((0.0, 0.0, 100.0, 100.0))
 16 |                         .build();
 17 | 
 18 | let runner = ShellRunner {
 19 |     shell,
 20 |     updater: Box::new(MyCustomUpdater::new())
 21 | };
 22 | 
 23 | runner.run()
 24 | ```
 25 | 
 26 |  */
 27 | #[macro_use]
 28 | extern crate lazy_static;
 29 | 
 30 | pub mod event;
 31 | pub mod prelude;
 32 | pub mod window_adapter;
 33 | 
 34 | pub use orbtk_utils::prelude as utils;
 35 | 
 36 | pub mod orbclient;
 37 | 
 38 | #[cfg(not(target_arch = "wasm32"))]
 39 | pub mod native;
 40 | 
 41 | pub use orbtk_tinyskia::prelude as render;
 42 | 
 43 | use std::{collections::HashMap, sync::mpsc};
 44 | 
 45 | /// Used to send a request to the window.
 46 | #[derive(Clone, Debug, PartialEq, Eq)]
 47 | pub enum WindowRequest {
 48 |     /// Request to change the title of the `Windows`.
 49 |     ChangeTitle(String),
 50 | 
 51 |     /// Request to close the `Windows`.
 52 |     Close,
 53 | 
 54 |     /// Request redraw of the `Windows`s content.
 55 |     Redraw,
 56 | }
 57 | 
 58 | /// Used to send a request to the application shell.
 59 | pub enum ShellRequest<W>
 60 | where
 61 |     W: window_adapter::WindowAdapter,
 62 | {
 63 |     /// Request redraw of the `Windows`s content.
 64 |     CreateWindow(W, WindowSettings, mpsc::Receiver<WindowRequest>),
 65 | 
 66 |     None,
 67 | }
 68 | 
 69 | impl<W> Default for ShellRequest<W>
 70 | where
 71 |     W: window_adapter::WindowAdapter,
 72 | {
 73 |     fn default() -> Self {
 74 |         ShellRequest::None
 75 |     }
 76 | }
 77 | 
 78 | /// Contains settings of a window.
 79 | #[derive(Clone, Debug, Default)]
 80 | pub struct WindowSettings {
 81 |     /// Will the window always shown on top of other windows.
 82 |     pub always_on_top: bool,
 83 | 
 84 |     /// Is the window borderless / without decorations?
 85 |     pub borderless: bool,
 86 | 
 87 |     /// List of fonts to register.
 88 |     pub fonts: HashMap<String, &'static [u8]>,
 89 | 
 90 |     /// The initial position of the window.
 91 |     pub position: (f64, f64),
 92 | 
 93 |     /// Is the window resizable?
 94 |     pub resizeable: bool,
 95 | 
 96 |     /// The initial size of the window.
 97 |     pub size: (f64, f64),
 98 | 
 99 |     /// Title of the window.
100 |     pub title: String,
101 | }
102 | 


--------------------------------------------------------------------------------
/orbtk_orbclient/src/native/mod.rs:
--------------------------------------------------------------------------------
 1 | //! This module provides native OS implementations.
 2 | 
 3 | use std::{collections::HashMap, sync::Mutex, time::Instant};
 4 | 
 5 | lazy_static! {
 6 |     pub static ref CONSOLE: Console = Console {
 7 |         instants: Mutex::new(HashMap::new())
 8 |     };
 9 | }
10 | 
11 | pub struct Console {
12 |     instants: Mutex<HashMap<String, Instant>>,
13 | }
14 | 
15 | impl Console {
16 |     pub fn time(&self, name: impl Into<String>) {
17 |         self.instants
18 |             .lock()
19 |             .unwrap()
20 |             .insert(name.into(), Instant::now());
21 |     }
22 | 
23 |     pub fn time_end(&self, name: impl Into<String>) {
24 |         if let Some((_k, _v)) = self.instants.lock().unwrap().remove_entry(&name.into()) {
25 |             #[cfg(feature = "log")]
26 |             println!("{} {}ms - timer ended", _k, _v.elapsed().as_millis());
27 |         }
28 |     }
29 | 
30 |     #[allow(unused_variables)]
31 |     pub fn log(&self, message: impl Into<String>) {
32 |         #[cfg(feature = "log")]
33 |         println!("{}", message.into());
34 |     }
35 | }
36 | 


--------------------------------------------------------------------------------
/orbtk_orbclient/src/orbclient/mod.rs:
--------------------------------------------------------------------------------
  1 | //! This module contains a platform specific implementation of the window shell.
  2 | 
  3 | use std::sync::mpsc;
  4 | 
  5 | pub use super::native::*;
  6 | 
  7 | use crate::prelude::*;
  8 | 
  9 | use self::states::*;
 10 | pub use self::window::*;
 11 | pub use self::window_builder::*;
 12 | 
 13 | mod states;
 14 | mod window;
 15 | mod window_builder;
 16 | 
 17 | /// Does nothing. This function is only used by the web backend.
 18 | pub fn initialize() {}
 19 | 
 20 | /// Represents an application shell that could handle multiple windows.
 21 | pub struct Shell<A: 'static>
 22 | where
 23 |     A: WindowAdapter,
 24 | {
 25 |     window_shells: Vec<Window<A>>,
 26 |     requests: mpsc::Receiver<ShellRequest<A>>,
 27 | }
 28 | 
 29 | impl<A> Shell<A>
 30 | where
 31 |     A: WindowAdapter,
 32 | {
 33 |     /// Creates a window builder, that could be used to create a window and add it to the application shell.
 34 |     pub fn create_window(&mut self, adapter: A) -> WindowBuilder<A> {
 35 |         WindowBuilder::new(self, adapter)
 36 |     }
 37 | 
 38 |     /// Creates a window builder from a settings object.
 39 |     pub fn create_window_from_settings(
 40 |         &mut self,
 41 |         settings: WindowSettings,
 42 |         adapter: A,
 43 |     ) -> WindowBuilder<A> {
 44 |         WindowBuilder::from_settings(settings, self, adapter)
 45 |     }
 46 | 
 47 |     /// Creates a new application shell.
 48 |     pub fn new(requests: mpsc::Receiver<ShellRequest<A>>) -> Self {
 49 |         Shell {
 50 |             window_shells: vec![],
 51 |             requests,
 52 |         }
 53 |     }
 54 | 
 55 |     /// Receives window request from the application and handles them.
 56 |     pub fn receive_requests(&mut self) {
 57 |         let mut requests = vec![];
 58 |         for request in self.requests.try_iter() {
 59 |             requests.push(request);
 60 |         }
 61 | 
 62 |         for request in requests {
 63 |             if let ShellRequest::CreateWindow(adapter, settings, window_requests) = request {
 64 |                 self.create_window_from_settings(settings, adapter)
 65 |                     .request_receiver(window_requests)
 66 |                     .build();
 67 |             }
 68 |         }
 69 |     }
 70 | 
 71 |     /// Runs (starts) the application shell and its windows.
 72 |     pub fn run(&mut self) {
 73 |         loop {
 74 |             if self.window_shells.is_empty() {
 75 |                 return;
 76 |             }
 77 | 
 78 |             for i in 0..self.window_shells.len() {
 79 |                 let mut remove = false;
 80 |                 if let Some(window_shell) = self.window_shells.get_mut(i) {
 81 |                     window_shell.update();
 82 |                     window_shell.render();
 83 | 
 84 |                     window_shell.update_clipboard();
 85 |                     window_shell.drain_events();
 86 |                     window_shell.receive_requests();
 87 | 
 88 |                     if !window_shell.is_open() {
 89 |                         remove = true;
 90 |                     }
 91 |                 }
 92 | 
 93 |                 if remove {
 94 |                     self.window_shells.remove(i);
 95 |                     break;
 96 |                 }
 97 |             }
 98 | 
 99 |             self.receive_requests();
100 |         }
101 |     }
102 | }
103 | 


--------------------------------------------------------------------------------
/orbtk_orbclient/src/orbclient/states.rs:
--------------------------------------------------------------------------------
 1 | /// Internal helper state to handle current mouse state.
 2 | #[derive(Copy, Clone, Default, Debug)]
 3 | pub struct MouseState {
 4 |     pub button_left: bool,
 5 |     pub button_middle: bool,
 6 |     pub button_right: bool,
 7 |     pub mouse_pos: (f32, f32),
 8 | }
 9 | 
10 | /// Internal helper state to handle current window state.
11 | #[derive(Copy, Clone, Default, Debug)]
12 | pub struct WindowState {
13 |     pub active: bool,
14 |     pub size: (usize, usize),
15 | }
16 | 


--------------------------------------------------------------------------------
/orbtk_orbclient/src/prelude.rs:
--------------------------------------------------------------------------------
1 | //! This module pre-selects commonly used OrbTk crates and put them into scope.
2 | pub use crate::{
3 |     event::*, orbclient::*, window_adapter::*, ShellRequest, WindowRequest, WindowSettings,
4 | };
5 | 


--------------------------------------------------------------------------------
/orbtk_orbclient/src/web/states.rs:
--------------------------------------------------------------------------------
 1 | use std::{cell::RefCell, rc::Rc};
 2 | 
 3 | use stdweb::web::event;
 4 | 
 5 | /// Used to store and read web events.
 6 | pub struct EventState {
 7 |     pub mouse_move_events: Rc<RefCell<Vec<event::MouseMoveEvent>>>,
 8 |     pub mouse_up_events: Rc<RefCell<Vec<event::MouseUpEvent>>>,
 9 |     pub touch_start_events: Rc<RefCell<Vec<event::TouchStart>>>,
10 |     pub touch_end_events: Rc<RefCell<Vec<event::TouchEnd>>>,
11 |     pub touch_move_events: Rc<RefCell<Vec<event::TouchMove>>>,
12 |     pub mouse_down_events: Rc<RefCell<Vec<event::MouseDownEvent>>>,
13 |     pub scroll_events: Rc<RefCell<Vec<event::MouseWheelEvent>>>,
14 |     pub key_up_events: Rc<RefCell<Vec<event::KeyUpEvent>>>,
15 |     pub key_down_events: Rc<RefCell<Vec<event::KeyDownEvent>>>,
16 |     pub resize_events: Rc<RefCell<Vec<event::ResizeEvent>>>,
17 | }
18 | 


--------------------------------------------------------------------------------
/orbtk_orbclient/src/window_adapter.rs:
--------------------------------------------------------------------------------
 1 | //! This module contains traits to inject custom logic into the window shell.
 2 | 
 3 | use crate::render::RenderContext2D;
 4 | use crate::{event::*, utils::Point};
 5 | 
 6 | /// The `WindowAdapter` represents the bridge to the `Shell` backend.
 7 | /// It receives events from the `Window` and runs it's own logic.  
 8 | pub trait WindowAdapter {
 9 |     /// Is called if active state of the window is changed.
10 |     fn active(&mut self, active: bool);
11 | 
12 |     /// Used to update the clipboard, could be used to read and set the current clipboard value.
13 |     fn clipboard_update(&mut self, value: &mut Option<String>);
14 | 
15 |     /// This method is called when a file is dropped on the window.
16 |     fn file_drop_event(&mut self, file_name: String);
17 | 
18 |     /// Is called after the state of a keyboard key is changed.
19 |     fn key_event(&mut self, _event: KeyEvent) {}
20 | 
21 |     /// Is called after the mouse was moved.
22 |     fn mouse(&mut self, _x: f64, _y: f64) {}
23 | 
24 |     /// Is called after the state of a mouse button is changed.
25 |     fn mouse_event(&mut self, _event: MouseEvent) {}
26 | 
27 |     /// Gets the current mouse position.
28 |     fn mouse_position(&self) -> Point;
29 | 
30 |     /// Is called after the quit event of the window is called.
31 |     fn quit_event(&mut self) {}
32 | 
33 |     /// Is called after the window is resized.
34 |     fn resize(&mut self, _width: f64, _height: f64) {}
35 | 
36 |     /// Runs the inner logic of the shell adapter.
37 |     fn run(&mut self, render_context: &mut RenderContext2D);
38 | 
39 |     /// Is called if mouse wheel or trackpad detect scroll event.
40 |     fn scroll(&mut self, _delta_x: f64, _delta_y: f64) {}
41 | 
42 |     /// Sets raw window handle.
43 |     fn set_raw_window_handle(&mut self, raw_window_handle: raw_window_handle::RawWindowHandle);
44 | 
45 |     /// Is called when the keyboard emits an text input.
46 |     fn text_input(&mut self, _text: String) {}
47 | 
48 |     /// This method is called when a text string is dropped on the window.
49 |     fn text_drop_event(&mut self, text: String);
50 | }
51 | 


--------------------------------------------------------------------------------
/orbtk_tinyskia/Cargo.toml:
--------------------------------------------------------------------------------
 1 | [package]
 2 | authors = ["Florian Blasius <flovanpt@posteo.de>"]
 3 | description = "2D Render library use by OrbTk."
 4 | edition = "2021"
 5 | keywords = ["2D", "orbtk_tinyskia", "canvas"]
 6 | license = "MIT"
 7 | name = "orbtk_tinyskia"
 8 | readme = "README.md"
 9 | repository = "https://github.com/redox-os/orbtk"
10 | version = "0.3.1-alpha5"
11 | 
12 | [dependencies]
13 | orbtk_utils = { path = "../utils", version = "0.3.1-alpha5" }
14 | 
15 | [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
16 | image = { version = "0.24",  default-features = false, features = ["ico"] }
17 | rusttype = { version = "0.9" }
18 | smallvec = "1"
19 | tiny-skia = { version = "0.8.1" }
20 | 


--------------------------------------------------------------------------------
/orbtk_tinyskia/README.md:
--------------------------------------------------------------------------------
 1 | # orbtk_tinyskia
 2 | 
 3 | Cross platform 2D/3D render library. It's part of [OrbTk](https://gitlab.redox-os.org/redox-os/orbtk) - The Rust UI-Toolkit.
 4 | 
 5 | [![Build and test](https://github.com/redox-os/orbtk/workflows/CI/badge.svg)](https://github.com/redox-os/orbtk/actions)
 6 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
 7 | 
 8 | ## Platforms
 9 | 
10 | * Redox OS
11 | * Linux
12 | * macOS
13 | * Windows
14 | * openBSD (not tested, but should work)
15 | * Web
16 | * Android (not tested, but should work)
17 | * iOS (not tested, but should work)
18 | * Ubuntu Touch (not tested, but should work)
19 | 
20 | ## Dependencies
21 | 
22 | * [stdweb](https://github.com/koute/stdweb) (Apache 2.0, MIT): 2D render context web
23 | * [raqote](https://github.com/jrmuizel/raqote) (BSD-3-Clause): 2D render context
24 | * [rusttype](https://gitlab.redox-os.org/redox-os/rusttype) (Apache 2.0, MIT): font processing
25 | * [image](https://github.com/image-rs/image) (MIT): load pixel images e.g. png
26 | 
27 | ## License
28 | 
29 | Licensed under MIT license ([LICENSE](../../LICENSE)).


--------------------------------------------------------------------------------
/orbtk_tinyskia/src/lib.rs:
--------------------------------------------------------------------------------
  1 | #![recursion_limit = "256"]
  2 | 
  3 | //! This module provides the render environment.
  4 | //!
  5 | //! OrbTk has choosen the [tinyskia] crate to handle all 2D rendering
  6 | //! tasks. Implemented as wrapper functions, it consumes the native
  7 | //! rendering functions provided from tinyskia.
  8 | //!
  9 | //! [tinyskia]: https://docs.rs/tiny-skia
 10 | 
 11 | use std::{any::Any, fmt};
 12 | 
 13 | /// Pre-selects commonly used OrbTk crates and put them into scope.
 14 | pub mod prelude;
 15 | 
 16 | /// Handles helper utilities and global methods.
 17 | pub use orbtk_utils::prelude as utils;
 18 | 
 19 | mod common;
 20 | 
 21 | pub use tinyskia::*;
 22 | 
 23 | pub mod tinyskia;
 24 | 
 25 | pub use self::render_target::*;
 26 | 
 27 | mod render_target;
 28 | 
 29 | /// Defines the current configuration used inside a render resource.
 30 | #[derive(Debug, Clone)]
 31 | pub struct RenderConfig {
 32 |     pub fill_style: utils::Brush,
 33 |     pub stroke_style: utils::Brush,
 34 |     pub line_width: f64,
 35 |     pub font_config: FontConfig,
 36 |     pub alpha: f32,
 37 | }
 38 | 
 39 | impl Default for RenderConfig {
 40 |     fn default() -> Self {
 41 |         RenderConfig {
 42 |             fill_style: utils::Brush::default(),
 43 |             stroke_style: utils::Brush::default(),
 44 |             line_width: 1.,
 45 |             font_config: FontConfig::default(),
 46 |             alpha: 1.,
 47 |         }
 48 |     }
 49 | }
 50 | 
 51 | /// The TextMetrics struct represents the dimension of a text.
 52 | #[derive(Clone, Copy, Default, Debug)]
 53 | pub struct TextMetrics {
 54 |     pub width: f64,
 55 |     pub height: f64,
 56 | }
 57 | 
 58 | /// Internal font helper.
 59 | #[derive(Default, Clone, PartialEq, Debug)]
 60 | pub struct FontConfig {
 61 |     pub family: String,
 62 |     pub font_size: f64,
 63 | }
 64 | 
 65 | impl ToString for FontConfig {
 66 |     fn to_string(&self) -> String {
 67 |         format!("{}px {}", self.font_size, self.family)
 68 |     }
 69 | }
 70 | 
 71 | /// Provides methods to handle the 2D render pipeline.
 72 | pub trait RenderPipeline {
 73 |     /// Draws the ctx of the pipeline.
 74 |     fn draw(&self, image: &mut RenderTarget);
 75 | }
 76 | 
 77 | /// Used to implement a custom render pipeline.
 78 | pub trait PipelineTrait: RenderPipeline + Any + Send {
 79 |     /// Equality for two Pipeline objects.
 80 |     fn box_eq(&self, other: &dyn Any) -> bool;
 81 | 
 82 |     /// Converts self to an any reference.
 83 |     fn as_any(&self) -> &dyn Any;
 84 | 
 85 |     /// Clones self as box.
 86 |     fn clone_box(&self) -> Box<dyn PipelineTrait>;
 87 | 
 88 |     /// Draws the ctx of the pipeline.
 89 |     fn draw_pipeline(&self, image: &mut RenderTarget) {
 90 |         self.draw(image);
 91 |     }
 92 | }
 93 | 
 94 | impl PartialEq for Box<dyn PipelineTrait> {
 95 |     fn eq(&self, other: &Box<dyn PipelineTrait>) -> bool {
 96 |         self.box_eq(other.as_any())
 97 |     }
 98 | }
 99 | 
100 | impl Clone for Box<dyn PipelineTrait> {
101 |     fn clone(&self) -> Self {
102 |         self.clone_box()
103 |     }
104 | }
105 | 
106 | impl fmt::Debug for Box<dyn PipelineTrait> {
107 |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108 |         write!(f, "Box<dyn PipelineTrait>")
109 |     }
110 | }
111 | 


--------------------------------------------------------------------------------
/orbtk_tinyskia/src/prelude.rs:
--------------------------------------------------------------------------------
1 | /// This module pre-selects commonly used OrbTk crates and put them into scope.
2 | #[cfg(not(target_arch = "wasm32"))]
3 | pub use crate::tinyskia::Font;
4 | pub use crate::tinyskia::Image;
5 | pub use crate::*;
6 | 


--------------------------------------------------------------------------------
/orbtk_tinyskia/src/render_target.rs:
--------------------------------------------------------------------------------
 1 | use std::fmt;
 2 | 
 3 | use crate::utils::*;
 4 | 
 5 | /// Structure used to define render targets.
 6 | #[derive(Clone, Default)]
 7 | pub struct RenderTarget {
 8 |     width: u32,
 9 |     height: u32,
10 |     pub data: Vec<u32>,
11 | }
12 | 
13 | impl fmt::Debug for RenderTarget {
14 |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
15 |         write!(
16 |             f,
17 |             "RenderTarget ( width: {}, height: {})",
18 |             self.width, self.height
19 |         )
20 |     }
21 | }
22 | 
23 | impl std::cmp::PartialEq for RenderTarget {
24 |     fn eq(&self, other: &Self) -> bool {
25 |         self.width == other.width && self.height == other.height
26 |     }
27 | }
28 | 
29 | impl RenderTarget {
30 |     /// Creates a new image with the given width and height.
31 |     pub fn new(width: u32, height: u32) -> Self {
32 |         RenderTarget {
33 |             width,
34 |             height,
35 |             data: vec![Color::rgba(0, 0, 0, 0).data; width as usize * height as usize],
36 |         }
37 |     }
38 | 
39 |     /// Draws a u32 slice into the image.
40 |     pub fn draw(&mut self, data: &[u32]) {
41 |         self.data.clone_from_slice(data);
42 |     }
43 | 
44 |     /// Create a new image from a boxed slice of colors
45 |     pub fn from_data(width: u32, height: u32, data: Vec<u32>) -> Result<Self, String> {
46 |         Ok(RenderTarget {
47 |             width,
48 |             height,
49 |             data,
50 |         })
51 |     }
52 | 
53 |     /// Gets the width.
54 |     pub fn width(&self) -> f64 {
55 |         self.width as f64
56 |     }
57 | 
58 |     /// Gets the height.
59 |     pub fn height(&self) -> f64 {
60 |         self.height as f64
61 |     }
62 | 
63 |     /// Gets the data object.
64 |     pub fn data(&self) -> &[u32] {
65 |         &self.data
66 |     }
67 | 
68 |     /// Gets a mutable data object.
69 |     pub fn data_mut(&mut self) -> &mut [u32] {
70 |         &mut self.data
71 |     }
72 | }
73 | 


--------------------------------------------------------------------------------
/orbtk_tinyskia/src/tinyskia/image.rs:
--------------------------------------------------------------------------------
  1 | use std::{fmt, path::Path};
  2 | 
  3 | use crate::RenderTarget;
  4 | 
  5 | /// Structure that defines elements of an image object.
  6 | #[derive(Clone, Default)]
  7 | pub struct Image {
  8 |     render_target: RenderTarget,
  9 |     source: String,
 10 | }
 11 | 
 12 | impl fmt::Debug for Image {
 13 |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 14 |         write!(f, "Image ( source: {})", self.source)
 15 |     }
 16 | }
 17 | 
 18 | impl std::cmp::PartialEq for Image {
 19 |     fn eq(&self, other: &Self) -> bool {
 20 |         self.source == other.source
 21 |     }
 22 | }
 23 | 
 24 | impl Image {
 25 |     /// Creates a new image with the given width and height.
 26 |     pub fn new(width: u32, height: u32) -> Self {
 27 |         Image {
 28 |             render_target: RenderTarget::new(width, height),
 29 |             source: String::default(),
 30 |         }
 31 |     }
 32 | 
 33 |     /// Draws a u32 slice into the image.
 34 |     pub fn draw(&mut self, data: &[u32]) {
 35 |         self.render_target.data.clone_from_slice(data);
 36 |     }
 37 | 
 38 |     /// Create a new image from a boxed slice of colors
 39 |     pub fn from_data(width: u32, height: u32, data: Vec<u32>) -> Result<Self, String> {
 40 |         Ok(Image {
 41 |             render_target: RenderTarget::from_data(width, height, data).unwrap(),
 42 |             source: String::new(),
 43 |         })
 44 |     }
 45 | 
 46 |     /// Creates a new image from an `RgbaImage`.
 47 |     pub fn from_rgba_image(image: image::RgbaImage) -> Result<Self, String> {
 48 |         let data: Vec<u32> = image
 49 |             .pixels()
 50 |             .map(|p| {
 51 |                 ((p[3] as u32) << 24) | ((p[0] as u32) << 16) | ((p[1] as u32) << 8) | (p[2] as u32)
 52 |             })
 53 |             .collect();
 54 |         Self::from_data(image.width(), image.height(), data)
 55 |     }
 56 | 
 57 |     /// Load an image from file path. Supports BMP and PNG
 58 |     pub fn from_path<P: AsRef<Path> + std::fmt::Debug + Clone>(path: P) -> Result<Self, String> {
 59 |         let img = image::open(path.clone());
 60 | 
 61 |         if let Ok(img) = img {
 62 |             return Self::from_rgba_image(img.to_rgba8());
 63 |         }
 64 | 
 65 |         Err(format!("Could not load image width path: {:?}", path))
 66 |     }
 67 | 
 68 |     /// Gets the width.
 69 |     pub fn width(&self) -> f64 {
 70 |         self.render_target.width() as f64
 71 |     }
 72 | 
 73 |     /// Gets the height.
 74 |     pub fn height(&self) -> f64 {
 75 |         self.render_target.height() as f64
 76 |     }
 77 | 
 78 |     pub fn data(&self) -> &[u32] {
 79 |         &self.render_target.data
 80 |     }
 81 | 
 82 |     pub fn data_mut(&mut self) -> &mut [u32] {
 83 |         &mut self.render_target.data
 84 |     }
 85 | }
 86 | 
 87 | impl From<(u32, u32, Vec<u32>)> for Image {
 88 |     fn from(image: (u32, u32, Vec<u32>)) -> Self {
 89 |         Image::from_data(image.0, image.1, image.2).unwrap()
 90 |     }
 91 | }
 92 | 
 93 | pub fn os_path(path: String) -> String {
 94 |     if cfg!(windows) {
 95 |         path.replace('/', "\\")
 96 |     } else {
 97 |         path.replace('\\', "/")
 98 |     }
 99 | }
100 | 
101 | // --- Conversions ---
102 | 
103 | impl From<&str> for Image {
104 |     fn from(s: &str) -> Image {
105 |         Image::from_path(os_path(s.to_string())).unwrap()
106 |     }
107 | }
108 | 
109 | impl From<String> for Image {
110 |     fn from(s: String) -> Image {
111 |         Image::from_path(os_path(s)).unwrap()
112 |     }
113 | }
114 | 
115 | // --- Conversions ---
116 | 


--------------------------------------------------------------------------------
/orbtk_widgets/Cargo.toml:
--------------------------------------------------------------------------------
 1 | [package]
 2 | authors = ["Florian Blasius <flovanpt@posteo.de>"]
 3 | description = "Base OrbTk widget library."
 4 | edition = "2021"
 5 | keywords = ["ui", "widgets"]
 6 | license = "MIT"
 7 | name = "orbtk_widgets"
 8 | version = "0.3.1-alpha5"
 9 | readme = "README.md"
10 | repository = "https://github.com/redox-os/orbtk"
11 | 
12 | [dependencies]
13 | lazy_static = "1.4"
14 | orbtk_core = { path = "../orbtk_core", version = "0.3.1-alpha5" }
15 | orbtk_orbclient = { path = "../orbtk_orbclient", version = "0.3.1-alpha5", default-features = false }
16 | orbtk_tinyskia = { path = "../orbtk_tinyskia", version = "0.3.1-alpha5", default-features = false }
17 | orbtk_utils = { path = "../utils", version = "0.3.1-alpha5" }
18 | orbtk_proc_macros = { version = "0.3.1-alpha5", path = "../proc_macros" }
19 | rust_decimal = "1.15"
20 | #rust_decimal_macros = "1.15"
21 | 
22 | [dependencies.dces]
23 | #version = "0.3.1"
24 | git = "https://gitlab.redox-os.org/redox-os/dces-rust.git"
25 | branch =  "master"
26 | #branch = "develop"
27 | 
28 | [lib]
29 | doctest = false
30 | 


--------------------------------------------------------------------------------
/orbtk_widgets/README.md:
--------------------------------------------------------------------------------
 1 | # orbtk_widgets
 2 | 
 3 | OrbTks default widget library. It's part of [OrbTk](https://gitlab.redox-os.org/redox-os/orbtk) - The Rust UI-Toolkit.
 4 | 
 5 | [![Build and test](https://github.com/redox-os/orbtk/workflows/CI/badge.svg)](https://github.com/redox-os/orbtk/actions)
 6 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
 7 | 
 8 | ## Dependencies
 9 | 
10 | * [dces](https://gitlab.redox-os.org/redox-os/dces-rust) (MIT): Entity Component System
11 | 
12 | ## License
13 | 
14 | Licensed under MIT license ([LICENSE](../../LICENSE)).


--------------------------------------------------------------------------------
/orbtk_widgets/assets/fonts/material/MaterialIcons-Baseline.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk_widgets/assets/fonts/material/MaterialIcons-Baseline.woff2


--------------------------------------------------------------------------------
/orbtk_widgets/assets/fonts/material/MaterialIcons-Outlined.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk_widgets/assets/fonts/material/MaterialIcons-Outlined.woff2


--------------------------------------------------------------------------------
/orbtk_widgets/assets/fonts/material/MaterialIcons-Round.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk_widgets/assets/fonts/material/MaterialIcons-Round.woff2


--------------------------------------------------------------------------------
/orbtk_widgets/assets/fonts/material/MaterialIcons-Sharp.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk_widgets/assets/fonts/material/MaterialIcons-Sharp.woff2


--------------------------------------------------------------------------------
/orbtk_widgets/assets/fonts/material/MaterialIcons-TwoTone.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk_widgets/assets/fonts/material/MaterialIcons-TwoTone.woff2


--------------------------------------------------------------------------------
/orbtk_widgets/assets/fonts/material/MaterialIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk_widgets/assets/fonts/material/MaterialIcons.ttf


--------------------------------------------------------------------------------
/orbtk_widgets/assets/fonts/material/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 | 	"name": "@material-icons/font",
 3 | 	"description": "Material Design icons by Google, updated (Font)",
 4 | 	"version": "1.0.1",
 5 | 	"author": "Material Design Authors",
 6 | 	"license": "Apache-2.0",
 7 | 	"bugs": {
 8 | 		"url": "https://github.com/material-icons/material-icons/issues"
 9 | 	},
10 | 	"homepage": "https://github.com/material-icons/material-icons",
11 | 	"scripts": {
12 | 		"build": "node build/font.js"
13 | 	},
14 | 	"devDependencies": {
15 | 		"cheerio": "^1.0.0-rc.3",
16 | 		"node-sass": "^4.13.1",
17 | 		"svg2ttf": "^4.3.0",
18 | 		"svgicons2svgfont": "^9.1.1",
19 | 		"ttf2woff": "^2.0.1",
20 | 		"ttf2woff2": "^3.0.0"
21 | 	}
22 | }
23 | 


--------------------------------------------------------------------------------
/orbtk_widgets/assets/fonts/mdl2/mdl2.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk_widgets/assets/fonts/mdl2/mdl2.otf


--------------------------------------------------------------------------------
/orbtk_widgets/assets/fonts/roboto/Roboto-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk_widgets/assets/fonts/roboto/Roboto-Medium.ttf


--------------------------------------------------------------------------------
/orbtk_widgets/assets/fonts/roboto/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk_widgets/assets/fonts/roboto/Roboto-Regular.ttf


--------------------------------------------------------------------------------
/orbtk_widgets/assets/fonts/selawik/Selawik-Bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk_widgets/assets/fonts/selawik/Selawik-Bold.otf


--------------------------------------------------------------------------------
/orbtk_widgets/assets/fonts/selawik/Selawik-Light.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk_widgets/assets/fonts/selawik/Selawik-Light.otf


--------------------------------------------------------------------------------
/orbtk_widgets/assets/fonts/selawik/Selawik-Regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/redox-os/orbtk/eba9e77821551076bbf1d9f7ab44d788150e3446/orbtk_widgets/assets/fonts/selawik/Selawik-Regular.otf


--------------------------------------------------------------------------------
/orbtk_widgets/assets/themes/fluent/theme_fluent_colors_dark.ron:
--------------------------------------------------------------------------------
 1 | Theme (
 2 |     resources: {
 3 |         // common
 4 |         "BLACK": "#000000",
 5 |         "WHITE": "#ffffff",
 6 |         "ACCENT_COLOR": "#0078D7",
 7 |         "ACCENT_COLOR_LIGHTER": "#f0d860",
 8 |         "ACCENT_COLOR_LIGHT": "#589BE6",
 9 |         "ACCENT_COLOR_DARK": "#2259A1",
10 |         "BACKGROUND": "#000000",
11 |         "BACKGROUND_SECONDARY": "#333333",
12 | 
13 |         // box colors (TextBox, CheckBox, ComboBox, ...)
14 |         "BOX_BACKGROUND": "tranparent",
15 |         "BOX_BORDER": "#CBCBCB",
16 |         "BOX_BORDER_HOVER": "#ffffff",
17 |         "BOX_BACKGROUND_PRESSED": "#666666",
18 | 
19 |         // CheckBox
20 |         "CHECKBOX_ICON_BRUSH": "#ffffff",
21 | 
22 |         // cursor
23 |         "CURSOR_BORDER_BRUSH": "#ffffff",
24 |         "CURSOR_BACKGROUND": "#0078D7",
25 | 
26 |         // content
27 |         "CONTENT_FOREGROUND": "#ffffff",
28 |         "CONTENT_FOREGROUND_INVERTED": "#3b434a",
29 |         "CONTENT_FOREGROUND_SECONDARY": "#9dafbf",
30 |         "CONRENT_FOREGROUND_ACCENT": "#ffffff",
31 | 
32 |         // button
33 |         "BUTTON_BACKGROUND": "#333333",
34 |         "BUTTON_BACKGROUND_HOVER": "#191919",
35 |         "BUTTON_BACKGORUND_PRESSED": "#666666",
36 |         "BUTTON_BACKGROUND_PRIMARY_SELECTED": "#ebbf13",
37 |         "BUTTON_BACKGORUND_PRIMARY_PRESSED": "#ebbf13", 
38 |         "BUTTON_FOREGROUND_DISABLED": "#6A6A6A",
39 |         "BUTTON_FOREGROUND_SELECTED": "#ffffff",
40 | 
41 |         // switch toggle
42 |         "SWITCH_TOGGLE_BACKGROUND": "#ffffff",
43 |         "SWITCH_TOGGLE_BACKGROUND_SELECTED": "#ffffff",
44 |         
45 |         // text box
46 |         "TEXT_BOX_FOCUSED_BORDER": "#efd035",
47 |         "TEXT_BOX_HOVER_BACKGROUND": "#000000",
48 | 
49 |         // combobox
50 |         "COMBO_BOX_BACKGROUND": "#647b91",
51 |         "POPUP_BACKGROUND": "#2B2B2B",
52 | 
53 |         // slider
54 |         "SLIDER_BACKGROUND": "#666666",
55 |         "SLIDER_BACKGROUND_HOVER": "#999999",
56 | 
57 |         // progress bar
58 |         "PROGRESS_BAR_BACKGROUND": "#333334",
59 | 
60 |         // containers such es lists and text box
61 |         "CONTAINER_BACKGROUND": "#2B2D2F",
62 |         "CONTAINER_BORDER": "#A5A5A5",
63 | 
64 |         // items (combobox item listview item)
65 |         "ITEM_BACKGROUND_HOVER": "#404040",
66 |         "ITEM_BACKGROUND_PRESSED": "#555555",
67 | 
68 |         // tab header
69 |         "TAB_HEADER_HOVER": "#1F1F1F"
70 |     },
71 | )


--------------------------------------------------------------------------------
/orbtk_widgets/assets/themes/fluent/theme_fluent_colors_light.ron:
--------------------------------------------------------------------------------
 1 | Theme (
 2 |     resources: {
 3 |         // common
 4 |         "BLACK": "#000000",
 5 |         "WHITE": "#ffffff",
 6 |         "ACCENT_COLOR": "#0078D7",
 7 |         "ACCENT_COLOR_LIGHTER": "#f0d860",
 8 |         "ACCENT_COLOR_LIGHT": "#589BE6",
 9 |         "ACCENT_COLOR_DARK": "#2259A1",
10 |         "BACKGROUND": "#FFFFFF",
11 |         "BACKGROUND_SECONDARY": "#E6E6E6",
12 | 
13 |         // box colors (TextBox, CheckBox, ComboBox, ...)
14 |         "BOX_BACKGROUND": "tranparent",
15 |         "BOX_BORDER": "#666666",
16 |         "BOX_BORDER_HOVER": "#4C4C4C",
17 |         "BOX_BACKGROUND_PRESSED": "#999999",
18 | 
19 |         // CheckBox
20 |         "CHECKBOX_ICON_BRUSH": "#ffffff",
21 | 
22 |         // cursor
23 |         "CURSOR_BORDER_BRUSH": "#000000",
24 |         "CURSOR_BACKGROUND": "#0078D7",
25 | 
26 |         // content
27 |         "CONTENT_FOREGROUND": "#242424",
28 |         "CONTENT_FOREGROUND_INVERTED": "#3b434a",
29 |         "CONTENT_FOREGROUND_SECONDARY": "#9dafbf",
30 |         "CONRENT_FOREGROUND_ACCENT": "#ffffff",
31 | 
32 |         // button
33 |         "BUTTON_BACKGROUND": "#CCCCCC",
34 |         "BUTTON_BACKGROUND_HOVER": "#E6E6E6",
35 |         "BUTTON_BACKGORUND_PRESSED": "#999999",
36 |         "BUTTON_BACKGROUND_PRIMARY_SELECTED": "#ebbf13",
37 |         "BUTTON_BACKGORUND_PRIMARY_PRESSED": "#ebbf13", 
38 |         "BUTTON_FOREGROUND_DISABLED": "#7A7A7A",
39 |         "BUTTON_FOREGROUND_SELECTED": "#ffffff",
40 | 
41 |         // switch toggle
42 |         "SWITCH_TOGGLE_BACKGROUND": "#000000",
43 |         "SWITCH_TOGGLE_BACKGROUND_SELECTED": "#ffffff",
44 |         
45 |         // text box
46 |         "TEXT_BOX_FOCUSED_BORDER": "#efd035",
47 |         "TEXT_BOX_HOVER_BACKGROUND": "#000000",
48 | 
49 |         // combobox
50 |         "COMBO_BOX_BACKGROUND": "#647b91",
51 |         "POPUP_BACKGROUND": "#E1E1E1",
52 | 
53 |         // slider
54 |         "SLIDER_BACKGROUND": "#999999",
55 |         "SLIDER_BACKGROUND_HOVER": "#666666",
56 | 
57 |         // progress bar
58 |         "PROGRESS_BAR_BACKGROUND": "#CCCCCC",
59 | 
60 |         // containers such es lists and text box
61 |         "CONTAINER_BACKGROUND": "#2B2D2F",
62 |         "CONTAINER_BORDER": "#A5A5A5",
63 | 
64 |         // items (combobox item listview item)
65 |         "ITEM_BACKGROUND_HOVER": "#DADADA",
66 |         "ITEM_BACKGROUND_PRESSED": "#C2C2C2",
67 | 
68 |         // tab header
69 |         "TAB_HEADER_HOVER": "#EDEDED"
70 |     },
71 | )


--------------------------------------------------------------------------------
/orbtk_widgets/assets/themes/fluent/theme_fluent_fonts.ron:
--------------------------------------------------------------------------------
 1 | Theme (
 2 |     resources: {
 3 |         // fonts
 4 |         "REGULAR_FONT": "Selawik-Regular",
 5 |         "BOLD_FONT": "Selawik-Bold",
 6 |         "LIGHT_FONT": "Selawik-Light",
 7 |         // material icon fonts is used as default:
 8 |         // OrbTk's default widget library reference it, thus resolution is needed.
 9 |         "ICON_FONT": "MaterialIcons-Regular",
10 |         "MDL2_ICON_FONT": "MDL2-Assets-Regular",
11 | 
12 |         // font sizes
13 |         "FONT_SIZE_12": 12,
14 |         "FONT_SIZE_13": 13,
15 |         "FONT_SIZE_14": 14,
16 |         "FONT_SIZE_16": 16,
17 |         "FONT_SIZE_24": 24,
18 |         "FONT_SIZE_32": 32,
19 |         "FONT_SIZE_36": 36,
20 | 
21 |         // icon sizes
22 |         "ICON_SIZE_4": 4,
23 |         "ICON_SIZE_6": 6,
24 |         "ICON_SIZE_8": 8,
25 |         "ICON_SIZE_10": 10,
26 |         "ICON_SIZE_12": 12,
27 |         "ICON_SIZE_14": 14,
28 |         "ICON_SIZE_16": 16,
29 |         "ICON_SIZE_18": 18,
30 |     },
31 | )
32 | 


--------------------------------------------------------------------------------
/orbtk_widgets/assets/themes/orbtk/theme_default_colors_dark.ron:
--------------------------------------------------------------------------------
 1 | Theme (
 2 |     resources: {
 3 |         // common
 4 |         "BLACK": "#000000",
 5 |         "WHITE": "#ffffff",
 6 |         "ACCENT_COLOR": "#efd035",
 7 |         "ACCENT_COLOR_LIGHTER": "#f0d860",
 8 |         "ACCENT_COLOR_LIGHT": "#5B6764",
 9 |         "ACCENT_COLOR_DARK": "#ebbf13",
10 |         "BACKGROUND": "#3b434a",
11 |         "BACKGROUND_SECONDARY": "#475b6e",
12 | 
13 |         // content
14 |         "CONTENT_FOREGROUND": "#dfebf5",
15 |         "CONTENT_FOREGROUND_INVERTED": "#3b434a",
16 |         "CONTENT_FOREGROUND_SECONDARY": "#9dafbf",
17 | 
18 |         // button
19 |         "BUTTON_BACKGROUND": "linear-gradient(to top, #7a8fa3, #647b91)",
20 |         "BUTTON_BACKGROUND_SELECTED": "#516475",
21 |         "BUTTON_BACKGROUND_HOVER": "linear-gradient(to top, #647b91, #475b6e)",
22 |         "BUTTON_BACKGORUND_PRESSED": "#516475",
23 |         "BUTTON_BACKGROUND_DISABLED": "linear-gradient(to top, #797d80, #808488)",
24 |         "BUTTON_BACKGROUND_PRIMARY": "linear-gradient(to top, #f7e899, #ebbf13)",
25 |         "BUTTON_BACKGROUND_PRIMARY_SELECTED": "#ebbf13",
26 |         "BUTTON_BACKGROUND_PRIMARY_HOVER": "linear-gradient(to top, #f0d860, #efd035)",
27 |         "BUTTON_BACKGORUND_PRIMARY_PRESSED": "#ebbf13", 
28 |         "BUTTON_FOREGROUND_DISABLED": "#3b434a",
29 | 
30 |         // text box
31 |         "TEXT_BOX_FOCUSED_BORDER": "#efd035",
32 |         "TEXT_BOX_HOVER_BACKGROUND": "#000000",
33 | 
34 |         // combobox
35 |         "COMBO_BOX_BACKGROUND": "#647b91",
36 |         "POPUP_BACKGROUND": "#444e55",
37 |         "POPUP_BORDER": "#adb3b8",
38 | 
39 |         // switch
40 |         "SWITCH_TOGGLE_BACKGROUND": "#dfebf5",
41 |         "SWITCH_TOGGLE_BORDER": "#dfebf5",
42 | 
43 |         // slider
44 |         "SLIDER_THUMB_BACKGROUND": "#dfebf5",
45 |         "SLIDER_THUMB_BORDER": "#dfebf5",
46 | 
47 |         // combobox
48 |         "COMBO_BOX_ITEM_SELECTED": "#3b434a",
49 | 
50 |         // progress bar
51 |         "PROGRESS_BAR_BACKGROUND": "#000000",
52 | 
53 |         // containers such es lists and text box
54 |         "CONTAINER_BACKGROUND": "#2B2D2F",
55 |         "CONTAINER_BORDER": "#dfebf5",
56 |     },
57 | )


--------------------------------------------------------------------------------
/orbtk_widgets/assets/themes/orbtk/theme_default_colors_light.ron:
--------------------------------------------------------------------------------
 1 | Theme (
 2 |     resources: {
 3 |         // common
 4 |         "BLACK": "#000000",
 5 |         "WHITE": "#ffffff",
 6 |         "ACCENT_COLOR": "#efd035",
 7 |         "ACCENT_COLOR_LIGHTER": "#f0d860",
 8 |         "ACCENT_COLOR_LIGHT": "#eeead8",
 9 |         "ACCENT_COLOR_DARK": "#ebbf13",
10 |         "BACKGROUND": "#fafafa",
11 |         "BACKGROUND_SECONDARY": "#d1d1d1",
12 | 
13 |         // content
14 |         "CONTENT_FOREGROUND": "#3b434a",
15 |         "CONTENT_FOREGROUND_INVERTED": "#3b434a",
16 |         "CONTENT_FOREGROUND_SECONDARY": "#71757A",
17 | 
18 |         // button
19 |         "BUTTON_BACKGROUND": "linear-gradient(to top, #e5e5e5, #d2d2d2)",
20 |         "BUTTON_BACKGROUND_SELECTED": "#a1a1a1",
21 |         "BUTTON_BACKGROUND_HOVER": "linear-gradient(to top, #c7c7c7, #b2b3b1)",
22 |         "BUTTON_BACKGORUND_PRESSED": "#a1a1a1",
23 |         "BUTTON_BACKGROUND_DISABLED": "linear-gradient(to top, #e9e9e8, #F2F1F1)",
24 |         "BUTTON_BACKGROUND_PRIMARY": "linear-gradient(to top, #f7e899, #efd035)",
25 |         "BUTTON_BACKGROUND_PRIMARY_SELECTED": "#f0d860",
26 |         "BUTTON_BACKGROUND_PRIMARY_HOVER": "linear-gradient(to top, #ebbf13, #ebbf14)",
27 |         "BUTTON_BACKGORUND_PRIMARY_PRESSED": "#f0d860", 
28 |         "BUTTON_FOREGROUND_DISABLED": "#BEC1C2",
29 | 
30 |         // text box
31 |         "TEXT_BOX_FOCUSED_BORDER": "#ebbf13",
32 |         "TEXT_BOX_HOVER_BACKGROUND": "#a1a1a1",
33 | 
34 |         // combobox
35 |         "COMBO_BOX_BACKGROUND": "#647b91",
36 |         "POPUP_BACKGROUND": "#ffffff",
37 |         "POPUP_BORDER": "#000000",
38 | 
39 |         // switch
40 |         "SWITCH_TOGGLE_BACKGROUND": "#ffffff",
41 |         "SWITCH_TOGGLE_BORDER": "#3b434a",
42 | 
43 |         // slider
44 |         "SLIDER_THUMB_BACKGROUND": "#ffffff",
45 |         "SLIDER_THUMB_BORDER": "#3b434a",
46 | 
47 |         // combobox
48 |         "COMBO_BOX_ITEM_SELECTED": "#3b434a",
49 | 
50 |         // progress bar
51 |         "PROGRESS_BAR_BACKGROUND": "#ffffff",
52 | 
53 |         // containers such es lists and text box
54 |         "CONTAINER_BACKGROUND": "#ffffff",
55 |         "CONTAINER_BORDER": "#000000",
56 |     },
57 | )


--------------------------------------------------------------------------------
/orbtk_widgets/assets/themes/orbtk/theme_default_fonts.ron:
--------------------------------------------------------------------------------
 1 | Theme (
 2 |     resources: {
 3 |         // fonts
 4 |         "MEDIUM_FONT": "Roboto-Medium",
 5 |         "REGULAR_FONT": "Roboto-Regular",
 6 |         "ICON_FONT": "MaterialIcons-Regular",
 7 | 
 8 |        // font sizes
 9 |         "FONT_SIZE_12": 12,
10 |         "FONT_SIZE_13": 13,
11 |         "FONT_SIZE_14": 14,
12 |         "FONT_SIZE_16": 16,
13 |         "FONT_SIZE_24": 24,
14 |         "FONT_SIZE_32": 32,
15 |         "FONT_SIZE_36": 36,
16 | 
17 |         // icon sizes
18 |         "ICON_SIZE_4": 4,
19 |         "ICON_SIZE_6": 6,
20 |         "ICON_SIZE_8": 8,
21 |         "ICON_SIZE_10": 10,
22 |         "ICON_SIZE_12": 12,
23 |         "ICON_SIZE_14": 14,
24 |         "ICON_SIZE_16": 16,
25 |         "ICON_SIZE_18": 18,
26 |     },
27 | )
28 | 


--------------------------------------------------------------------------------
/orbtk_widgets/assets/themes/redox/theme_redox_colors.ron:
--------------------------------------------------------------------------------
 1 | Theme (
 2 |     resources: {
 3 |         // common
 4 |         "BLACK": "#000000",
 5 |         "WHITE": "#ffffff",
 6 |         "ACCENT_COLOR": "#3C95DF",
 7 |         "ACCENT_COLOR_LIGHTER": "#5ba2de",
 8 |         "ACCENT_COLOR_LIGHT": "#5B6764",
 9 |         "ACCENT_COLOR_DARK": "#1986e0",
10 |         "BACKGROUND": "#F5F6F7",
11 |         "BACKGROUND_SECONDARY": "#F5F6F7",
12 |         "BORDER_DFAULT": "#CED6E5",
13 | 
14 |         // content
15 |         "CONTENT_FOREGROUND": "#000000",
16 |         "CONTENT_FOREGROUND_INVERTED": "#ffffff",
17 |         "CONTENT_FOREGROUND_SECONDARY": "#9dafbf",
18 | 
19 |         // button
20 |         "BUTTON_BACKGROUND": "#ffffff",
21 |         "BUTTON_BACKGROUND_SELECTED": "#3C95DF",
22 |         "BUTTON_BACKGROUND_HOVER": "#CED6E5",
23 |         "BUTTON_BACKGORUND_PRESSED": "#3C95DF",
24 |         "BUTTON_BACKGROUND_DISABLED": "linear-gradient(to top, #797d80, #808488)",
25 |         "BUTTON_BACKGROUND_PRIMARY": "linear-gradient(to top, #f7e899, #ebbf13)",
26 |         "BUTTON_BACKGROUND_PRIMARY_SELECTED": "#ebbf13",
27 |         "BUTTON_BACKGROUND_PRIMARY_HOVER": "linear-gradient(to top, #f0d860, #efd035)",
28 |         "BUTTON_BACKGORUND_PRIMARY_PRESSED": "#ebbf13", 
29 |         "BUTTON_FOREGROUND_DISABLED": "#3b434a",
30 | 
31 |         // text box
32 |         "TEXT_BOX_FOCUSED_BORDER": "#3C95DF",
33 |         "TEXT_BOX_HOVER_BACKGROUND": "#000000",
34 | 
35 |         // combobox
36 |         "COMBO_BOX_BACKGROUND": "#647b91",
37 |         "POPUP_BACKGROUND": "#ffffff",
38 |         "POPUP_BORDER": "#CED6E5",
39 | 
40 |         // switch
41 |         "SWITCH_TOGGLE_BACKGROUND": "#dfebf5",
42 |         "SWITCH_TOGGLE_BORDER": "#dfebf5",
43 | 
44 |         // slider
45 |         "SLIDER_THUMB_BACKGROUND": "#dfebf5",
46 |         "SLIDER_THUMB_BORDER": "#dfebf5",
47 | 
48 |         // combobox
49 |         "COMBO_BOX_ITEM_SELECTED": "#ffffff",
50 | 
51 |         // progress bar
52 |         "PROGRESS_BAR_BACKGROUND": "#ffffff",
53 | 
54 |         // containers such es lists and text box
55 |         "CONTAINER_BACKGROUND": "#ffffff",
56 |         "CONTAINER_BORDER": "#CED6E5",
57 |     },
58 | )


--------------------------------------------------------------------------------
/orbtk_widgets/assets/themes/redox/theme_redox_fonts.ron:
--------------------------------------------------------------------------------
 1 | Theme (
 2 |     resources: {
 3 |         "MEDIUM_FONT": "Roboto-Medium",
 4 |         "REGULAR_FONT": "Roboto-Regular",
 5 |         "ICON_FONT": "MaterialIcons-Regular",
 6 |         "FONT_SIZE_12": 12,
 7 |         "FONT_SIZE_16": 16,
 8 |         "FONT_SIZE_24": 24,
 9 |         "FONT_SIZE_32": 32,
10 |         "FONT_SIZE_36": 36,
11 |         "ICON_SIZE_12": 12,
12 |         "ICON_SIZE_14": 14,
13 |         "ICON_SIZE_16": 16,
14 |         "ICON_SIZE_18": 18,
15 |     },
16 | )


--------------------------------------------------------------------------------
/orbtk_widgets/src/behaviors/mod.rs:
--------------------------------------------------------------------------------
 1 | //! Behavior widgets are provides a default set of event actions like mouse event handling.
 2 | //! Use them as child to expand the event behavior of your widget.
 3 | 
 4 | pub use self::mouse_behavior::*;
 5 | pub use self::selection_behavior::*;
 6 | pub use self::text_behavior::*;
 7 | 
 8 | mod mouse_behavior;
 9 | mod selection_behavior;
10 | mod text_behavior;
11 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/behaviors/selection_behavior.rs:
--------------------------------------------------------------------------------
 1 | use crate::{api::prelude::*, proc_macros::*};
 2 | 
 3 | /// Used for selection.
 4 | pub enum SelectionAction {
 5 |     ToggleSelection,
 6 | }
 7 | 
 8 | /// The `SelectionBehaviorState` handles the `SelectionBehavior` widget.
 9 | #[derive(Default, AsAny)]
10 | pub struct SelectionBehaviorState {
11 |     target: Entity,
12 | }
13 | 
14 | impl State for SelectionBehaviorState {
15 |     fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
16 |         self.target = (*ctx.widget().get::<u32>("target")).into();
17 |         toggle_flag("selected", &mut ctx.get_widget(self.target));
18 |         ctx.get_widget(self.target).update(false);
19 |     }
20 | 
21 |     fn messages(
22 |         &mut self,
23 |         mut messages: MessageReader,
24 |         _registry: &mut Registry,
25 |         ctx: &mut Context,
26 |     ) {
27 |         for message in messages.read::<SelectionAction>() {
28 |             match message {
29 |                 SelectionAction::ToggleSelection => {
30 |                     let selected = *ctx.get_widget(self.target).get::<bool>("selected");
31 |                     ctx.get_widget(self.target).set("selected", !selected);
32 |                     toggle_flag("selected", &mut ctx.get_widget(self.target));
33 |                     ctx.get_widget(self.target).update(false);
34 |                 }
35 |             };
36 |         }
37 |     }
38 | }
39 | 
40 | widget!(
41 |     /// The `SelectionBehavior` widget will take care to handle the actions,
42 |     /// that should be triggered if text regions are marked or selected.
43 |     ///
44 |     /// **style:** `check_box`
45 |     SelectionBehavior<SelectionBehaviorState>: MouseHandler {
46 |         /// Sets or shares the target of the behavior.
47 |         target: u32,
48 | 
49 |         /// Sets or shares the selected property.
50 |         selected: bool,
51 | 
52 |         /// Sets the parent id.
53 |         parent: u32
54 |     }
55 | );
56 | 
57 | impl Template for SelectionBehavior {
58 |     fn template(self, id: Entity, _: &mut BuildContext) -> Self {
59 |         self.name("SelectionBehavior")
60 |             .selected(true)
61 |             .on_click(move |ctx, _| {
62 |                 ctx.send_message(SelectionAction::ToggleSelection, id);
63 |                 false
64 |             })
65 |     }
66 | }
67 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/canvas.rs:
--------------------------------------------------------------------------------
 1 | use crate::{api::prelude::*, proc_macros::*};
 2 | 
 3 | widget!(
 4 |     /// Canvas is used to render 3D graphics.
 5 |     Canvas {
 6 |         /// Sets or shares the render pipeline.
 7 |         render_pipeline: DefaultRenderPipeline
 8 |     }
 9 | );
10 | 
11 | impl Template for Canvas {
12 |     fn template(self, _: Entity, _: &mut BuildContext) -> Self {
13 |         self.name("Canvas").style("canvas-three")
14 |     }
15 | 
16 |     fn render_object(&self) -> Box<dyn RenderObject> {
17 |         PipelineRenderObject.into()
18 |     }
19 | }
20 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/container.rs:
--------------------------------------------------------------------------------
 1 | use crate::{api::prelude::*, proc_macros::*};
 2 | 
 3 | widget!(
 4 |     /// The `Container` layout widget surrounds its child with a padding. Draws a box around the child.
 5 |     Container {
 6 |         /// Sets or shares the background property.
 7 |         background: Brush,
 8 | 
 9 |         /// Sets or shares the border radius property.
10 |         border_radius: f64,
11 | 
12 |         /// Sets or shares the border thickness property.
13 |         border_width: Thickness,
14 | 
15 |         /// Sets or shares the border brush property.
16 |         border_brush: Brush,
17 | 
18 |         /// Sets or shares the padding property.
19 |         padding: Thickness
20 |     }
21 | );
22 | 
23 | impl Template for Container {
24 |     fn template(self, _: Entity, _: &mut BuildContext) -> Self {
25 |         self.name("Container")
26 |             .padding(0.0)
27 |             .background("transparent")
28 |             .border_radius(0.0)
29 |             .border_width(0.0)
30 |             .border_brush("transparent")
31 |     }
32 | 
33 |     fn render_object(&self) -> Box<dyn RenderObject> {
34 |         RectangleRenderObject.into()
35 |     }
36 | 
37 |     fn layout(&self) -> Box<dyn Layout> {
38 |         PaddingLayout::new().into()
39 |     }
40 | }
41 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/cursor.rs:
--------------------------------------------------------------------------------
 1 | use crate::{api::prelude::*, proc_macros::*};
 2 | 
 3 | widget!(
 4 |     /// The `Cursor` widget represents a text cursor that is used to mark text.
 5 |     ///
 6 |     /// **style:** `cursor`
 7 |     ///
 8 |     /// # Example
 9 |     ///
10 |     /// Create a cursor and share its text selection.
11 |     ///
12 |     /// ```rust
13 |     /// Cursor::new().selection(id).build(ctx)
14 |     /// ```
15 |     Cursor {
16 |         /// Defines the selection of that cursor that is shared with the `TextBehavior`.
17 |         selection: TextSelection,
18 | 
19 |         /// Defines the background of the whole selection range.
20 |         background: Brush,
21 | 
22 |         /// Defines the brush of the text selection indicator.
23 |         border_brush: Brush,
24 | 
25 |         /// Defines the with of the text selection indicator.
26 |         border_width: Thickness,
27 | 
28 |         // Defines the opacity of the background of the selection range.
29 |         background_opacity: f32,
30 | 
31 |         /// Defines the current width of the selection.
32 |         selection_width: f64,
33 | 
34 |         /// Defines the start position of the current selection.
35 |         selection_x: f64,
36 | 
37 |         /// Defines the x position of the cursor.
38 |         cursor_x: f64,
39 | 
40 |         /// Defines the of the cursor.
41 |         offset: f64
42 |     }
43 | );
44 | 
45 | impl Template for Cursor {
46 |     fn template(self, _: Entity, _: &mut BuildContext) -> Self {
47 |         self.name("Cursor")
48 |             .style("cursor")
49 |             .background_opacity(0.3)
50 |             .background("transparent")
51 |             .h_align("stretch")
52 |     }
53 | 
54 |     fn render_object(&self) -> Box<dyn RenderObject> {
55 |         CursorRenderObject.into()
56 |     }
57 | }
58 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/font_icon_block.rs:
--------------------------------------------------------------------------------
 1 | use crate::{api::prelude::*, proc_macros::*, themes::theme_orbtk::*};
 2 | 
 3 | widget!(
 4 |     /// The `FontIconBlock` widget is used to draw text. It is not interactive.
 5 |     ///
 6 |     /// **style:** `font-icon-block`
 7 |     FontIconBlock {
 8 |         /// Sets or shares the icon property.
 9 |         icon: String,
10 | 
11 |         /// Sets or shares the icon brush property.
12 |         icon_brush: Brush,
13 | 
14 |         /// Sets or share the icon font size property.
15 |         icon_size: f64,
16 | 
17 |         /// Sets or shares the icon font property.
18 |         icon_font: String
19 |     }
20 | );
21 | 
22 | impl Template for FontIconBlock {
23 |     fn template(self, _: Entity, _: &mut BuildContext) -> Self {
24 |         self.name("FontIconBlock")
25 |             .style("font-icon-block")
26 |             .icon("")
27 |             .icon_brush(colors::LINK_WATER_COLOR)
28 |             .icon_size(orbtk_fonts::ICON_FONT_SIZE_12)
29 |             .icon_font("MaterialIcons-Regular")
30 |     }
31 | 
32 |     fn render_object(&self) -> Box<dyn RenderObject> {
33 |         FontIconRenderObject.into()
34 |     }
35 | 
36 |     fn layout(&self) -> Box<dyn Layout> {
37 |         FixedSizeLayout::new().into()
38 |     }
39 | }
40 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/grid.rs:
--------------------------------------------------------------------------------
 1 | use crate::{api::prelude::*, proc_macros::*};
 2 | 
 3 | widget!(
 4 |     /// The `Grid` defines a flexible grid area that consists of columns and rows.
 5 |     ///
 6 |     /// **style:** `grid`
 7 |     Grid {
 8 |         /// Sets or shares the background property.
 9 |         background: Brush,
10 | 
11 |         /// Sets or shares the columns property.
12 |         columns: Blocks,
13 | 
14 |         /// Sets or shares the rows property.
15 |         rows: Blocks,
16 | 
17 |         /// Sets or shares the border radius property.
18 |         border_radius: f64
19 | 
20 |         attached_properties: {
21 |             /// Attach a column position to a widget.
22 |             column: usize,
23 | 
24 |             /// Attach a column span to a widget.
25 |             column_span: usize,
26 | 
27 |             /// Attach a row position to a widget.
28 |             row: usize,
29 | 
30 |             /// Attach a row span to a widget.
31 |             row_span: usize
32 |         }
33 |     }
34 | );
35 | 
36 | impl Grid {
37 |     /// Sets column and row to the given widget and add it as child.
38 |     pub fn place<W>(self, ctx: &mut BuildContext, child: W, column: usize, row: usize) -> Self
39 |     where
40 |         W: Widget,
41 |     {
42 |         self.child(
43 |             child
44 |                 .attach(Grid::column(column))
45 |                 .attach(Grid::row(row))
46 |                 .build(ctx),
47 |         )
48 |     }
49 | }
50 | 
51 | impl Template for Grid {
52 |     fn template(self, _: Entity, _: &mut BuildContext) -> Self {
53 |         self.name("Grid")
54 |             .style("grid")
55 |             .border_radius(0.0)
56 |             .background("transparent")
57 |             .rows(Blocks::default())
58 |             .columns(Blocks::default())
59 |     }
60 | 
61 |     fn render_object(&self) -> Box<dyn RenderObject> {
62 |         RectangleRenderObject.into()
63 |     }
64 | 
65 |     fn layout(&self) -> Box<dyn Layout> {
66 |         GridLayout::new().into()
67 |     }
68 | }
69 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/image_widget.rs:
--------------------------------------------------------------------------------
 1 | use crate::{api::prelude::*, proc_macros::*, render::prelude::*};
 2 | 
 3 | widget!(
 4 |     /// The `ImageWidget` widget is used to draw an image. It is not interactive.
 5 |     ///
 6 |     /// **style:** `image-widget`
 7 |     ImageWidget {
 8 |         /// Sets or shares the image property.
 9 |         ///
10 |         /// Set image property:
11 |         /// * &str: `ImageWidget::new().image("path/to/image.png").build(xt)`
12 |         /// * String: `ImageWidget::new().image(String::from()).build(xt)`
13 |         /// * (width: u32, height: u32, data: Vec<u32>): `ImageWidget::new().image((width, height, vec![0; width * height]));`
14 |         image: Image
15 |     }
16 | );
17 | 
18 | impl Template for ImageWidget {
19 |     fn template(self, _: Entity, _: &mut BuildContext) -> Self {
20 |         self.name("ImageWidget").style("image-widget").image("")
21 |     }
22 | 
23 |     fn render_object(&self) -> Box<dyn RenderObject> {
24 |         ImageRenderObject.into()
25 |     }
26 | 
27 |     fn layout(&self) -> Box<dyn Layout> {
28 |         FixedSizeLayout::new().into()
29 |     }
30 | }
31 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/lib.rs:
--------------------------------------------------------------------------------
 1 | /*!
 2 |    Base OrbTk widget library.
 3 | */
 4 | 
 5 | /// This module pre-selects commonly used OrbTk crates and put them into scope.
 6 | pub mod prelude;
 7 | 
 8 | pub(crate) use orbtk_core as api;
 9 | pub(crate) use orbtk_orbclient as shell;
10 | pub(crate) use orbtk_proc_macros as proc_macros;
11 | pub(crate) use orbtk_tinyskia as render;
12 | 
13 | pub use self::button::*;
14 | pub use self::canvas::*;
15 | pub use self::check_box::*;
16 | pub use self::combo_box::*;
17 | pub use self::container::*;
18 | pub use self::cursor::*;
19 | pub use self::font_icon_block::*;
20 | pub use self::grid::*;
21 | pub use self::image_widget::*;
22 | pub use self::items_widget::*;
23 | pub use self::list_view::*;
24 | pub use self::master_detail::*;
25 | pub use self::numeric_box::*;
26 | pub use self::pager::*;
27 | pub use self::password_box::*;
28 | pub use self::popup::*;
29 | pub use self::progress_bar::*;
30 | pub use self::scroll_bar::*;
31 | pub use self::scroll_indicator::*;
32 | pub use self::scroll_viewer::*;
33 | pub use self::slider::*;
34 | pub use self::stack::*;
35 | pub use self::switch::*;
36 | pub use self::tab_widget::*;
37 | pub use self::text_block::*;
38 | pub use self::text_box::*;
39 | pub use self::toggle_button::*;
40 | pub use self::window::*;
41 | 
42 | pub mod behaviors;
43 | mod button;
44 | mod canvas;
45 | mod check_box;
46 | mod combo_box;
47 | mod container;
48 | mod cursor;
49 | mod font_icon_block;
50 | mod grid;
51 | mod image_widget;
52 | mod items_widget;
53 | mod list_view;
54 | mod master_detail;
55 | mod numeric_box;
56 | mod pager;
57 | mod password_box;
58 | mod popup;
59 | mod progress_bar;
60 | mod scroll_bar;
61 | mod scroll_indicator;
62 | mod scroll_viewer;
63 | mod slider;
64 | mod stack;
65 | mod switch;
66 | mod tab_widget;
67 | mod text_block;
68 | mod text_box;
69 | pub mod themes;
70 | mod toggle_button;
71 | mod window;
72 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/popup.rs:
--------------------------------------------------------------------------------
 1 | use crate::{api::prelude::*, proc_macros::*};
 2 | 
 3 | /// The `PopupState` handles the open and close behavior of the `Popup` widget.
 4 | #[derive(AsAny, Default)]
 5 | pub struct PopupState {
 6 |     //actions: Vec<PopupAction>,
 7 | }
 8 | 
 9 | impl PopupState {}
10 | 
11 | impl State for PopupState {}
12 | 
13 | widget!(
14 |     /// The `Popup` is used to presents content bound to target entity.
15 |     ///
16 |     /// The `target` is specified either via its widget id (`Entitiy`)
17 |     /// or using a point coordinate (`Point`). The placmement of the
18 |     /// popup widget itself is controlled via its `placement`
19 |     /// property. An optional attribute (float), defines the
20 |     /// margin between the target and the popup widget.
21 |     ///
22 |     /// [`placement`]: ../orbtk_core/render_object/enum.Placement.html
23 |     ///
24 |     /// **style:** `popup``
25 |     Popup<PopupState> : KeyDownHandler, MouseHandler {
26 |     /// Sets or shares the background property.
27 |     background: Brush,
28 | 
29 |     /// Sets or shares the border brush property.
30 |     border_brush: Brush,
31 | 
32 |     /// Sets or shares the border radius property.
33 |     border_radius: f64,
34 | 
35 |     /// Sets or shares the border thickness property.
36 |     border_width: Thickness,
37 | 
38 |     /// Sets or shares the popup open state.
39 |     open: bool,
40 | 
41 |     /// Sets or shares the padding property.
42 |     padding: Thickness,
43 | 
44 |     /// Sets or shares the placement property relative to the
45 |     /// target position. Valid placement variants are defined via
46 |     /// the `Placement` enumeration.
47 |     placement: Placement,
48 | 
49 |     /// Sets or shares the offset property that assignes a margin
50 |     /// between popup and target entity.
51 |     offset: f64,
52 | 
53 |     ///
54 |     /// Defined ether as an entity (Entity), or as a point
55 |     /// coordinate (Point).
56 |     target: PopupTarget
57 |     }
58 | );
59 | 
60 | impl Template for Popup {
61 |     fn template(self, _id: Entity, _: &mut BuildContext) -> Self {
62 |         self.name("Popup").style("popup").open(false)
63 |     }
64 | 
65 |     fn render_object(&self) -> Box<dyn RenderObject> {
66 |         Box::new(PopupRenderObject::new())
67 |     }
68 | 
69 |     fn layout(&self) -> Box<dyn Layout> {
70 |         PopupLayout::new().into()
71 |     }
72 | }
73 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/prelude.rs:
--------------------------------------------------------------------------------
 1 | pub use std::{
 2 |     any::{Any, TypeId},
 3 |     cell::RefCell,
 4 |     collections::{HashMap, HashSet},
 5 |     fmt::Debug,
 6 |     rc::Rc,
 7 | };
 8 | 
 9 | pub use crate::*;
10 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/scroll_bar.rs:
--------------------------------------------------------------------------------
 1 | use crate::{api::prelude::*, proc_macros::*};
 2 | 
 3 | // --- KEYS --
 4 | 
 5 | pub static STYLE_SCROLL_BAR: &str = "scroll_bar";
 6 | 
 7 | // --- KEYS --
 8 | 
 9 | widget!(
10 |     /// The `ScrollBar` widget represents a position inside of a scroll container.
11 |     ///
12 |     /// **style:** `scroll_bar`
13 |     ScrollBar {
14 |         /// Sets or shares the background property.
15 |         background: Brush,
16 | 
17 |         /// Sets or shares the border radius property.
18 |         border_radius: f64
19 |     }
20 | );
21 | 
22 | impl Template for ScrollBar {
23 |     fn template(self, _: Entity, _: &mut BuildContext) -> Self {
24 |         self.name("ScrollBar")
25 |             .style(STYLE_SCROLL_BAR)
26 |             .width(4.0)
27 |             .border_radius(2.0)
28 |             .background("#647b91")
29 |     }
30 | 
31 |     fn render_object(&self) -> Box<dyn RenderObject> {
32 |         RectangleRenderObject.into()
33 |     }
34 | }
35 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/stack.rs:
--------------------------------------------------------------------------------
 1 | use crate::{api::prelude::*, proc_macros::*};
 2 | 
 3 | widget!(
 4 |     /// The `Stack` defines a layout that is used to stack its children vertical or horizontal.
 5 |     ///
 6 |     /// **style:** `stack`
 7 |     Stack {
 8 |         /// Sets or shares the orientation property.
 9 |         orientation: Orientation,
10 | 
11 |         /// Margin between widgets in the stack.
12 |         spacing: f64
13 |     }
14 | );
15 | 
16 | impl Template for Stack {
17 |     fn template(self, _: Entity, _: &mut BuildContext) -> Self {
18 |         self.name("Stack").orientation("vertical").style("stack")
19 |     }
20 | 
21 |     fn layout(&self) -> Box<dyn Layout> {
22 |         Box::new(StackLayout::new())
23 |     }
24 | }
25 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/text_block.rs:
--------------------------------------------------------------------------------
 1 | use crate::{api::prelude::*, proc_macros::*, themes::theme_orbtk::*};
 2 | 
 3 | enum TextAction {
 4 |     Localize,
 5 | }
 6 | 
 7 | /// Handles the localization of the text.
 8 | #[derive(Debug, Clone, Default, AsAny)]
 9 | pub struct TextBlockState;
10 | 
11 | impl TextBlockState {
12 |     fn localize(&self, ctx: &mut Context) {
13 |         if !*TextBlock::localizable_ref(&ctx.widget()) {
14 |             return;
15 |         }
16 | 
17 |         let text = TextBlock::text_clone(&ctx.widget());
18 |         let localized_text = ctx.localize_text(text);
19 | 
20 |         TextBlock::localized_text_set(&mut ctx.widget(), localized_text);
21 |     }
22 | }
23 | 
24 | impl State for TextBlockState {
25 |     fn init(&mut self, _registry: &mut Registry, ctx: &mut Context) {
26 |         self.localize(ctx);
27 |     }
28 | 
29 |     fn update(&mut self, _registry: &mut Registry, ctx: &mut Context) {
30 |         self.localize(ctx);
31 |     }
32 | 
33 |     fn messages(
34 |         &mut self,
35 |         mut messages: MessageReader,
36 |         _registry: &mut Registry,
37 |         ctx: &mut Context,
38 |     ) {
39 |         for message in messages.read::<TextAction>() {
40 |             match message {
41 |                 TextAction::Localize => self.localize(ctx),
42 |             }
43 |         }
44 |     }
45 | }
46 | 
47 | widget!(
48 |     /// The `TextBlock` widget is used to draw text. It is not interactive.
49 |     ///
50 |     /// **style:** `text-block`
51 |     TextBlock<TextBlockState> {
52 |         /// Sets or shares the text property.
53 |         text: String,
54 | 
55 |         /// If the `TextBlock` is localizable and the localized text is not empty, the localized_text will be drawn.
56 |         localized_text: String,
57 | 
58 |         /// Sets or shares the water_mark text property.
59 |         water_mark: String,
60 | 
61 |         /// Sets or shares the foreground property.
62 |         foreground: Brush,
63 | 
64 |         /// Sets or shares the font size property.
65 |         font_size: f64,
66 | 
67 |         /// Sets or shares the font property.
68 |         font: String,
69 | 
70 |         /// Defines an extra offset that can be used to the text on x axis.
71 |         offset: f64,
72 | 
73 |         /// Defines if the text is localizable. If set to `false` the text will not be localized.
74 |         localizable: bool
75 |     }
76 | );
77 | 
78 | impl Template for TextBlock {
79 |     fn template(self, id: Entity, _: &mut BuildContext) -> Self {
80 |         self.name("TextBlock")
81 |             .text("")
82 |             .foreground(colors::LINK_WATER_COLOR)
83 |             .font_size(orbtk_fonts::FONT_SIZE_12)
84 |             .font("Roboto-Regular")
85 |             .localizable(true)
86 |             .on_changed("text", move |ctx, _| {
87 |                 ctx.send_message(TextAction::Localize, id)
88 |             })
89 |     }
90 | 
91 |     fn render_object(&self) -> Box<dyn RenderObject> {
92 |         TextRenderObject.into()
93 |     }
94 | 
95 |     fn layout(&self) -> Box<dyn Layout> {
96 |         FixedSizeLayout::new().into()
97 |     }
98 | }
99 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/themes/mod.rs:
--------------------------------------------------------------------------------
 1 | //! Theme widgets provide fonts, icons and colors handling
 2 | //! that can refine the look and feel of an application at runtime.
 3 | 
 4 | pub mod theme_fluent;
 5 | pub mod theme_orbtk;
 6 | pub mod theme_redox;
 7 | 
 8 | pub use theme_fluent::*;
 9 | pub use theme_orbtk::*;
10 | pub use theme_redox::*;
11 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/themes/theme_fluent/fluent_fonts.rs:
--------------------------------------------------------------------------------
 1 | /// The `regular` variant of the `MDL2 Icons` asset font family.
 2 | pub const MDL2_ICONS_FONT: &[u8] =
 3 |     include_bytes!("../../../assets/fonts/mdl2/mdl2_assets_font.ron");
 4 | 
 5 | /// The `regular` variant of the `Selawik UI` font family.
 6 | pub const SELAWIK_REGULAR_FONT: &[u8] =
 7 |     include_bytes!("../../../assets/fonts/selawik/Selawik-Regular.otf");
 8 | 
 9 | /// The `bold` variant of the `Selawik UI` font family.
10 | pub const SELAWIK_BOLD_FONT: &[u8] =
11 |     include_bytes!("../../../assets/fonts/selawik/Selawik-Bold.otf");
12 | 
13 | /// The `light` variant of the `Selawik UI` font family.
14 | pub const SELAWIK_LIGHT_FONT: &[u8] =
15 |     include_bytes!("../../../assets/fonts/selawik/Selawik-Light.otf");
16 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/themes/theme_fluent/mod.rs:
--------------------------------------------------------------------------------
 1 | /*!
 2 | 
 3 | This submodule provides the default theme resources of OrbTks fluent theme dark and light.
 4 | It provides fonts, icons and colors.
 5 | 
 6 |  */
 7 | use orbtk_core::theming::*;
 8 | 
 9 | /// provides `constants` associated to fonts.
10 | pub mod fluent_fonts;
11 | 
12 | /// provides information processed by the `graphic render` (e.g. glyphs, icons).
13 | pub mod mdl2_assets_font;
14 | 
15 | /// Resource file of default theme
16 | pub const THEME_FLUENT: &str = include_str!("../../../assets/themes/fluent/theme_fluent.ron");
17 | 
18 | /// The default dark theme colors resource file.
19 | pub const THEME_FLUENT_COLORS_DARK: &str =
20 |     include_str!("../../../assets/themes/fluent/theme_fluent_colors_dark.ron");
21 | 
22 | /// The default light theme colors resource file.
23 | pub const THEME_FLUENT_COLORS_LIGHT: &str =
24 |     include_str!("../../../assets/themes/fluent/theme_fluent_colors_light.ron");
25 | 
26 | /// The font resources of the Fluent theme.
27 | pub const THEME_FLUENT_FONTS: &str =
28 |     include_str!("../../../assets/themes/fluent/theme_fluent_fonts.ron");
29 | 
30 | /// Segeo Icon Font map.
31 | pub const MDL2_ASSETS_ICONS: &str = include_str!("../../../assets/fonts/mdl2/mdl2_assets_font.ron");
32 | 
33 | /// Returns the fluent OrbTk theme.
34 | pub fn theme_fluent() -> Theme {
35 |     theme_fluent_dark()
36 | }
37 | 
38 | /// Creates OrbTks fluent dark theme.
39 | pub fn theme_fluent_dark() -> Theme {
40 |     register_fluent_fonts(Theme::from_config(
41 |         ThemeConfig::from(THEME_FLUENT)
42 |             .extend(ThemeConfig::from(THEME_FLUENT_COLORS_DARK))
43 |             .extend(ThemeConfig::from(THEME_FLUENT_FONTS))
44 |             .extend(ThemeConfig::from(MDL2_ASSETS_ICONS)),
45 |     ))
46 | }
47 | 
48 | /// Creates OrbTks fluent light theme.
49 | pub fn theme_fluent_light() -> Theme {
50 |     register_fluent_fonts(Theme::from_config(
51 |         ThemeConfig::from(THEME_FLUENT)
52 |             .extend(ThemeConfig::from(THEME_FLUENT_COLORS_LIGHT))
53 |             .extend(ThemeConfig::from(THEME_FLUENT_FONTS))
54 |             .extend(ThemeConfig::from(MDL2_ASSETS_ICONS)),
55 |     ))
56 | }
57 | 
58 | /// Register roboto and material icon fonts to the given theme.
59 | #[cfg(not(target_arch = "wasm32"))]
60 | pub fn register_fluent_fonts(theme: Theme) -> Theme {
61 |     theme
62 |         .register_font("Selawik-Regular", fluent_fonts::SELAWIK_REGULAR_FONT)
63 |         .register_font("Selawik-Bold", fluent_fonts::SELAWIK_BOLD_FONT)
64 |         .register_font("Selawik-Light", fluent_fonts::SELAWIK_LIGHT_FONT)
65 |         .register_font("MDL2-Assets-Regular", fluent_fonts::MDL2_ICONS_FONT)
66 |         // register also material icon fonts because OrbTk's default widget library relies on its availability.
67 |         .register_font(
68 |             "MaterialIcons-Regular",
69 |             super::theme_orbtk::orbtk_fonts::MATERIAL_ICONS_FONT,
70 |         )
71 | }
72 | 
73 | /// Dummy implementation for web to be compatible to other platforms.
74 | #[cfg(target_arch = "wasm32")]
75 | pub fn register_fluent_fonts(theme: Theme) -> Theme {
76 |     theme
77 | }
78 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/themes/theme_orbtk/colors.rs:
--------------------------------------------------------------------------------
1 | pub const LINK_WATER_COLOR: &str = "#dfebf5";
2 | pub const LYNCH_COLOR: &str = "#647b91";
3 | pub const BOMBAY_COLOR: &str = "#adb3B8";
4 | pub const SLATE_GRAY_COLOR: &str = "#6c7a90";
5 | pub const BRIGHT_GRAY_COLOR: &str = "#3b434a";
6 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/themes/theme_orbtk/mod.rs:
--------------------------------------------------------------------------------
 1 | /*!
 2 | 
 3 | This submodule provides the default theme resources of OrbTks default theme dark and light.
 4 | It provides fonts, icons and colors.
 5 | 
 6 |  */
 7 | 
 8 | use orbtk_core::theming::*;
 9 | 
10 | /// provides `constants` to reference colors.
11 | pub mod colors;
12 | /// provides `constants` associated to fonts.
13 | pub mod orbtk_fonts;
14 | 
15 | /// provides information processed by the `graphic render` (e.g. glyphs, icons).
16 | pub mod material_icons_font;
17 | 
18 | /// Resource file of default theme.
19 | pub const THEME_DEFAULT: &str = include_str!("../../../assets/themes/orbtk/theme_default.ron");
20 | 
21 | /// The default dark theme colors resource file.
22 | pub const THEME_DEFAULT_COLORS_DARK: &str =
23 |     include_str!("../../../assets/themes/orbtk/theme_default_colors_dark.ron");
24 | 
25 | /// The default light theme colors resource file.
26 | pub const THEME_DEFAULT_COLORS_LIGHT: &str =
27 |     include_str!("../../../assets/themes/orbtk/theme_default_colors_light.ron");
28 | 
29 | /// The font resources of the default theme
30 | pub const THEME_DEFAULT_FONTS: &str =
31 |     include_str!("../../../assets/themes/orbtk/theme_default_fonts.ron");
32 | 
33 | /// Segeo Icon Font map.
34 | pub const MATERIAL_ICONS: &str =
35 |     include_str!("../../../assets/fonts/material/material_icons_font.ron");
36 | 
37 | /// Returns the default OrbTk theme.
38 | pub fn theme_default() -> Theme {
39 |     theme_default_dark()
40 | }
41 | 
42 | /// Creates OrbTks default dark theme.
43 | pub fn theme_default_dark() -> Theme {
44 |     register_default_fonts(Theme::from_config(
45 |         ThemeConfig::from(THEME_DEFAULT)
46 |             .extend(ThemeConfig::from(THEME_DEFAULT_COLORS_DARK))
47 |             .extend(ThemeConfig::from(THEME_DEFAULT_FONTS))
48 |             .extend(ThemeConfig::from(MATERIAL_ICONS)),
49 |     ))
50 | }
51 | 
52 | /// Creates OrbTks default light theme.
53 | pub fn theme_default_light() -> Theme {
54 |     register_default_fonts(Theme::from_config(
55 |         ThemeConfig::from(THEME_DEFAULT)
56 |             .extend(ThemeConfig::from(THEME_DEFAULT_COLORS_LIGHT))
57 |             .extend(ThemeConfig::from(THEME_DEFAULT_FONTS))
58 |             .extend(ThemeConfig::from(MATERIAL_ICONS)),
59 |     ))
60 | }
61 | 
62 | /// Register roboto and material icon fonts to the given theme.
63 | #[cfg(not(target_arch = "wasm32"))]
64 | pub fn register_default_fonts(theme: Theme) -> Theme {
65 |     theme
66 |         .register_font("Roboto-Regular", orbtk_fonts::ROBOTO_REGULAR_FONT)
67 |         .register_font("Roboto-Medium", orbtk_fonts::ROBOTO_MEDIUM_FONT)
68 |         .register_font("MaterialIcons-Regular", orbtk_fonts::MATERIAL_ICONS_FONT)
69 | }
70 | 
71 | /// Dummy implementation for web to be compatible to other platforms.
72 | #[cfg(target_arch = "wasm32")]
73 | pub fn register_default_fonts(theme: Theme) -> Theme {
74 |     theme
75 | }
76 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/themes/theme_orbtk/orbtk_fonts.rs:
--------------------------------------------------------------------------------
 1 | // The 'Material Design Icons' provide an icon set developed by Google.
 2 | // Desing guidelines document the underlying structure.
 3 | // orbtk uses an activly maintained successor project called 'Material Icons'.
 4 | // Supported are 'ttf' and 'woff2' fonts.
 5 | 
 6 | // Project root: https://github.com/material-icons/material-icons-font
 7 | // Package-Info: package.json
 8 | 
 9 | // TL;DR
10 | // https://stackoverflow.com/questions/11002820/why-should-we-include-ttf-eot-woff-svg-in-a-font-face
11 | // ... woff2 gets drafted and accepted, which improves the compression
12 | // leading to even smaller files, along with the ability to load a single font
13 | // "in parts" so that a font that supports 20 scripts can be stored as "chunks"
14 | // on disk instead, with browsers automatically able to load the font "in parts"
15 | // as needed, rather than needing to transfer the entire font up front, further
16 | // improving the typesetting experience.
17 | // If you don't want to support IE 8 and lower, and iOS 4 and lower,
18 | // and android 4.3 or earlier, then you can just use WOFF
19 | // (and WOFF2, a more highly compressed WOFF, for the newest browsers that support it.)
20 | 
21 | /// The `regular` TrueType font, offering glyphs maintained in the `Material Incos Font` project.
22 | pub const MATERIAL_ICONS_FONT: &[u8] =
23 |     include_bytes!("../../../assets/fonts/material/MaterialIcons.ttf");
24 | 
25 | /// The baseline variant of the woff2 encoded font, offering glyphs maintained in the `Material Incos Font` project.
26 | pub const MATERIAL_ICONS_BASELINE_FONT: &[u8] =
27 |     include_bytes!("../../../assets/fonts/material/MaterialIcons-Baseline.woff2");
28 | 
29 | /// The 'outlined' variant of the woff2 encoded font, offering glyphs maintained in the `Material Incos Font` project.
30 | pub const MATERIAL_ICONS_OUTLINED_FONT: &[u8] =
31 |     include_bytes!("../../../assets/fonts/material/MaterialIcons-Outlined.woff2");
32 | 
33 | /// The `round` variant of the woff2 encoded font, offering glyphs maintained in the `Material Incos Font` project.
34 | pub const MATERIAL_ICONS_ROUND_FONT: &[u8] =
35 |     include_bytes!("../../../assets/fonts/material/MaterialIcons-Round.woff2");
36 | 
37 | /// The `sharp` variant of the woff2 encoded font, offering glyphs maintained in the `Material Incos Font` project.
38 | pub const MATERIAL_ICONS_SHARP_FONT: &[u8] =
39 |     include_bytes!("../../../assets/fonts/material/MaterialIcons-Sharp.woff2");
40 | 
41 | /// The `twotone` variant of the woff2 encoded font, offering glyphs maintained in the `Material Incos Font` project.
42 | pub const MATERIAL_ICONS_TWOTONE_FONT: &[u8] =
43 |     include_bytes!("../../../assets/fonts/material/MaterialIcons-TwoTone.woff2");
44 | 
45 | /// The `regular` variant of the `Roboto` font family.
46 | pub const ROBOTO_REGULAR_FONT: &[u8] =
47 |     include_bytes!("../../../assets/fonts/roboto/Roboto-Regular.ttf");
48 | 
49 | /// The `medium` variant of the `Roboto` font family.
50 | pub const ROBOTO_MEDIUM_FONT: &[u8] =
51 |     include_bytes!("../../../assets/fonts/roboto/Roboto-Medium.ttf");
52 | 
53 | /// Use fixed `font size` of 12pt.
54 | pub const FONT_SIZE_12: f64 = 12.0;
55 | 
56 | /// Use fixed `icon font size` of 12pt.
57 | pub const ICON_FONT_SIZE_12: f64 = 12.0;
58 | 


--------------------------------------------------------------------------------
/orbtk_widgets/src/themes/theme_redox.rs:
--------------------------------------------------------------------------------
 1 | /*!
 2 | 
 3 | This submodule provides the default theme resources of OrbTks redox theme dark and light.
 4 | It provides fonts, icons and colors.
 5 | 
 6 |  */
 7 | use orbtk_core::theming::*;
 8 | 
 9 | use super::theme_orbtk::{register_default_fonts, MATERIAL_ICONS};
10 | 
11 | /// Resource file of redox theme.
12 | pub const THEME_REDOX: &str = include_str!("../../assets/themes/redox/theme_redox.ron");
13 | 
14 | /// The redox dark theme colors resource file.
15 | pub const THEME_REDOX_COLORS_DARK: &str =
16 |     include_str!("../../assets/themes/redox/theme_redox_colors.ron");
17 | 
18 | /// The font resources of the redox theme.
19 | pub const THEME_REDOX_FONTS: &str = include_str!("../../assets/themes/redox/theme_redox_fonts.ron");
20 | 
21 | /// Returns the redox OrbTk theme.
22 | pub fn theme_redox() -> Theme {
23 |     register_default_fonts(Theme::from_config(
24 |         ThemeConfig::from(THEME_REDOX)
25 |             .extend(ThemeConfig::from(THEME_REDOX_COLORS_DARK))
26 |             .extend(ThemeConfig::from(THEME_REDOX_FONTS))
27 |             .extend(ThemeConfig::from(MATERIAL_ICONS)),
28 |     ))
29 | }
30 | 


--------------------------------------------------------------------------------
/policies/code-of-conduct.md:
--------------------------------------------------------------------------------
 1 | # Conduct
 2 | 
 3 | * We are committed to providing a friendly, safe and welcoming environment for
 4 |   all, regardless of level of experience, gender identity and expression, sexual
 5 |   orientation, disability, personal appearance, body size, race, ethnicity, age,
 6 |   religion, nationality, or other similar characteristic.
 7 | * Please avoid using overtly sexual aliases or other nicknames that might
 8 |   detract from a friendly, safe and welcoming environment for all.
 9 | * Please be kind and courteous. There’s no need to be mean or rude.
10 | * Respect that people have differences of opinion and that every design or
11 |   implementation choice carries a trade-off and numerous costs. There is seldom
12 |   a right answer.
13 | * Please keep unstructured critique to a minimum. If you have solid ideas you
14 |   want to experiment with, make a fork and see how it works.
15 | * We will exclude you from interaction if you insult, demean or harass anyone.
16 |   That is not welcome behavior. We interpret the term “harassment” as including
17 |   the definition in the Citizen Code of Conduct; if you have any lack of clarity
18 |   about what might be included in that concept, please read their definition. In
19 |   particular, we don’t tolerate behavior that excludes people in socially
20 |   marginalized groups.
21 | * Private harassment is also unacceptable. No matter who you are, if you feel
22 |   you have been or are being harassed or made uncomfortable by a community
23 |   member, please contact one of the channel ops or any of the Rust moderation
24 |   team immediately. Whether you’re a regular contributor or a newcomer, we care
25 |   about making this community a safe place for you and we’ve got your back.
26 | * Likewise any spamming, trolling, flaming, baiting or other attention-stealing
27 |   behavior is not welcome.
28 | 


--------------------------------------------------------------------------------
/proc_macros/Cargo.toml:
--------------------------------------------------------------------------------
 1 | [package]
 2 | authors = ["Florian Blasius <flovanpt@posteo.de>"]
 3 | description = "Procedural macros used by OrbTk."
 4 | edition = "2021"
 5 | license = "MIT"
 6 | keywords = ["ui", "api"]
 7 | name = "orbtk_proc_macros"
 8 | readme = "README.md"
 9 | repository = "https://github.com/redox-os/orbtk"
10 | version = "0.3.1-alpha5"
11 | 
12 | [lib]
13 | proc-macro = true
14 | 
15 | [dependencies]
16 | quote = "1.0"
17 | syn = "1.0"
18 | proc-macro2 = "1.0"
19 | case = "1.0"
20 | 
21 | [features]
22 | debug = []


--------------------------------------------------------------------------------
/proc_macros/README.md:
--------------------------------------------------------------------------------
 1 | # orbtk_proc_macros
 2 | 
 3 | Provides procedural helper macros. It's part of [OrbTk](https://gitlab.redox-os.org/redox-os/orbtk) - The Rust UI-Toolkit.
 4 | 
 5 | [![Build and test](https://github.com/redox-os/orbtk/workflows/CI/badge.svg)](https://github.com/redox-os/orbtk/actions)
 6 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
 7 | 
 8 | ## Dependencies
 9 | 
10 | * [dces](https://gitlab.redox-os.org/redox-os/dces-rust) (MIT): Entity Component System
11 | 
12 | ## License
13 | 
14 | Licensed under MIT license ([LICENSE](../../LICENSE)).


--------------------------------------------------------------------------------
/utils/Cargo.toml:
--------------------------------------------------------------------------------
 1 | [package]
 2 | authors = ["Florian Blasius <flovanpt@posteo.de>"]
 3 | description = "Helper utils and traits for OrbTk."
 4 | edition = "2021"
 5 | keywords = ["helpers", "utils", "traits", "ui"]
 6 | license = "MIT"
 7 | name = "orbtk_utils"
 8 | readme = "README.md"
 9 | repository = "https://github.com/redox-os/orbtk"
10 | version = "0.3.1-alpha5"
11 | 
12 | [dependencies]
13 | ron = { version = "0.8" }
14 | serde = { version = "1.0" }
15 | derive_more = { version = "0.99", default-features = false, features = ["add", "constructor", "from", "mul"] }
16 | lexical-core = { version = "0.8" }
17 | phf = { version = "0.10", default-features = false }
18 | 
19 | [build-dependencies]
20 | phf_codegen = { version = "0.11", default-features = false }


--------------------------------------------------------------------------------
/utils/README.md:
--------------------------------------------------------------------------------
 1 | # orbtk_utils
 2 | 
 3 | Base structs like point, brush, border, ... . It's part of [OrbTk](https://github.com/redox-os/orbtk) - The Rust UI-Toolkit.
 4 | 
 5 | [![Build and test](https://github.com/redox-os/orbtk/workflows/CI/badge.svg)](https://github.com/redox-os/orbtk/actions)
 6 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
 7 | 
 8 | 
 9 | ## License
10 | 
11 | Licensed under MIT license ([LICENSE](../../LICENSE)).


--------------------------------------------------------------------------------
/utils/build.rs:
--------------------------------------------------------------------------------
 1 | use std::env;
 2 | use std::error::Error;
 3 | use std::fs::File;
 4 | use std::io::{BufRead, BufReader, BufWriter, Write};
 5 | use std::path::{Path, PathBuf};
 6 | 
 7 | fn main() -> Result<(), Box<dyn Error>> {
 8 |     println!("cargo:rerun-if-changed=colors.txt");
 9 |     let path = Path::new(&env::var("OUT_DIR").unwrap()).join("colors.rs");
10 |     let mut file = BufWriter::new(File::create(&path).unwrap());
11 | 
12 |     let rdr = BufReader::new(File::open(
13 |         PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join("colors.txt"),
14 |     )?);
15 | 
16 |     let mut map = phf_codegen::Map::new();
17 |     let mut recs: Vec<(String, String)> = Vec::new();
18 | 
19 |     for result in rdr.lines() {
20 |         let record = result?;
21 |         let record = record.split("//").next().unwrap().trim();
22 |         if record.is_empty() {
23 |             continue;
24 |         }
25 |         let mut record = record.split_whitespace();
26 |         let id = record.next().unwrap().to_owned();
27 |         let hex = record.next().unwrap().to_owned();
28 |         let clean_hex = hex.trim_start_matches('#');
29 |         let color = match clean_hex.len() {
30 |             3 => {
31 |                 let d = u32::from_str_radix(clean_hex, 16).unwrap_or(0);
32 | 
33 |                 let mut r = (d & 0xF) << 4;
34 |                 let mut g = ((d >> 4) & 0xF) << 4;
35 |                 let mut b = ((d >> 8) & 0xF) << 4;
36 |                 r |= r >> 4;
37 |                 g |= g >> 4;
38 |                 b |= b >> 4;
39 | 
40 |                 format!("Color::rgb({}, {}, {})", r, g, b)
41 |             }
42 |             6 => {
43 |                 let x = u32::from_str_radix(clean_hex, 16).unwrap_or(0);
44 | 
45 |                 format!(
46 |                     "Color::rgb({}, {}, {})",
47 |                     ((x >> 16) & 0xFF) as u8,
48 |                     ((x >> 8) & 0xFF) as u8,
49 |                     (x & 0xFF) as u8
50 |                 )
51 |             }
52 |             _ => panic!(""),
53 |         };
54 |         recs.push((id, color));
55 |     }
56 | 
57 |     for rec in recs.iter() {
58 |         map.entry(&*rec.0, &rec.1);
59 |     }
60 | 
61 |     map.entry("transparent", "Color::rgba(0, 0, 0, 0)");
62 | 
63 |     writeln!(
64 |         &mut file,
65 |         "static COLORS: phf::Map<&'static str, Color> = \n{};\n",
66 |         map.build()
67 |     )
68 |     .unwrap();
69 | 
70 |     Ok(())
71 | }
72 | 


--------------------------------------------------------------------------------
/utils/src/angle.rs:
--------------------------------------------------------------------------------
 1 | use derive_more::{Add, Div, From, Mul, Sub};
 2 | use std::f64::consts::{PI, TAU};
 3 | 
 4 | /// The OrbTk way to handle angles
 5 | #[derive(Add, Sub, Copy, From, Clone, Debug, PartialEq, Mul, Div)]
 6 | pub struct Angle(f64);
 7 | 
 8 | impl Angle {
 9 |     // TODO: Make this const fns, when the floating point operations on const fns become stable
10 |     pub fn from_radians(radians: f64) -> Angle {
11 |         Angle(radians)
12 |     }
13 | 
14 |     pub fn from_degrees(degrees: f64) -> Angle {
15 |         Angle(degrees * PI / 180.0)
16 |     }
17 | 
18 |     /// Takes a number between 0.0 and 1.0 where 0.0 represents 0 degrees and 1.0 360 degrees
19 |     pub fn from_turn(turn: f64) -> Angle {
20 |         Angle(turn * TAU)
21 |     }
22 | 
23 |     pub fn to_radians(self) -> f64 {
24 |         self.0
25 |     }
26 | 
27 |     pub fn to_degrees(self) -> f64 {
28 |         self.0 * 180.0 / PI
29 |     }
30 | 
31 |     /// Gives a number between 0.0 and 1.0 where 0.0 represents 0 degrees and 1.0 360 degrees
32 |     pub fn to_turn(self) -> f64 {
33 |         self.0 / std::f64::consts::TAU
34 |     }
35 | 
36 |     /// Creates a `Angle` with a value of 0.0
37 |     pub fn zero() -> Angle {
38 |         Angle(0.0)
39 |     }
40 | }
41 | 
42 | impl Default for Angle {
43 |     fn default() -> Self {
44 |         Self::zero()
45 |     }
46 | }
47 | 


--------------------------------------------------------------------------------
/utils/src/dirty_size.rs:
--------------------------------------------------------------------------------
  1 | /// Size with width, height and dirty flag. If the dirty flag is `true`,
  2 | /// layout tasks will handle this objects in its arrange and measure
  3 | /// tasks.
  4 | #[derive(Copy, Clone, PartialEq)]
  5 | pub struct DirtySize {
  6 |     width: f64,
  7 |     height: f64,
  8 |     dirty: bool,
  9 | }
 10 | 
 11 | impl Default for DirtySize {
 12 |     fn default() -> Self {
 13 |         DirtySize {
 14 |             width: 0.0,
 15 |             height: 0.0,
 16 |             dirty: true,
 17 |         }
 18 |     }
 19 | }
 20 | 
 21 | impl DirtySize {
 22 |     /// Creates a new dirty size with default values.
 23 |     pub fn new() -> Self {
 24 |         DirtySize::default()
 25 |     }
 26 | 
 27 |     pub fn width(&self) -> f64 {
 28 |         self.width
 29 |     }
 30 | 
 31 |     pub fn set_width(&mut self, width: f64) {
 32 |         if (self.width - width).abs() > std::f64::EPSILON {
 33 |             self.dirty = true;
 34 |         }
 35 | 
 36 |         self.width = width;
 37 |     }
 38 | 
 39 |     pub fn height(&self) -> f64 {
 40 |         self.height
 41 |     }
 42 | 
 43 |     pub fn set_height(&mut self, height: f64) {
 44 |         if (self.height - height).abs() > std::f64::EPSILON {
 45 |             self.dirty = true;
 46 |         }
 47 | 
 48 |         self.height = height;
 49 |     }
 50 | 
 51 |     pub fn size(&self) -> (f64, f64) {
 52 |         (self.width, self.height)
 53 |     }
 54 | 
 55 |     pub fn set_size(&mut self, width: f64, height: f64) {
 56 |         if (self.width - width).abs() > std::f64::EPSILON
 57 |             && (self.height - height).abs() > std::f64::EPSILON
 58 |         {
 59 |             self.dirty = true
 60 |         }
 61 | 
 62 |         self.width = width;
 63 |         self.height = height;
 64 |     }
 65 | 
 66 |     /// Gets the dirty flag.
 67 |     pub fn dirty(&self) -> bool {
 68 |         self.dirty
 69 |     }
 70 | 
 71 |     /// Sets the dirty flag.
 72 |     pub fn set_dirty(&mut self, dirty: bool) {
 73 |         self.dirty = dirty;
 74 |     }
 75 | }
 76 | 
 77 | #[cfg(test)]
 78 | mod tests {
 79 |     use crate::prelude::*;
 80 | 
 81 |     #[test]
 82 |     fn test_set_width() {
 83 |         let width = 10.0;
 84 | 
 85 |         let mut dirty_size = DirtySize::default();
 86 | 
 87 |         dirty_size.set_width(width);
 88 | 
 89 |         assert!(crate::f64_cmp(dirty_size.width(), width));
 90 |         assert!(dirty_size.dirty());
 91 |     }
 92 | 
 93 |     #[test]
 94 |     fn test_set_height() {
 95 |         let height = 10.0;
 96 | 
 97 |         let mut dirty_size = DirtySize::default();
 98 |         dirty_size.set_height(height);
 99 | 
100 |         assert!(crate::f64_cmp(dirty_size.height(), height));
101 |         assert!(dirty_size.dirty());
102 |     }
103 | 
104 |     #[test]
105 |     fn test_set_size() {
106 |         let size = (10.0, 20.0);
107 | 
108 |         let mut dirty_size = DirtySize::default();
109 | 
110 |         dirty_size.set_size(size.0, size.1);
111 | 
112 |         assert_eq!(dirty_size.size(), size);
113 |         assert!(dirty_size.dirty());
114 |     }
115 | 
116 |     #[test]
117 |     fn test_set_dirty() {
118 |         let mut dirty_size = DirtySize::default();
119 | 
120 |         dirty_size.set_dirty(false);
121 | 
122 |         assert!(!dirty_size.dirty());
123 |     }
124 | }
125 | 


--------------------------------------------------------------------------------
/utils/src/f32_cmp.rs:
--------------------------------------------------------------------------------
1 | /// Compares two f32 values.
2 | pub fn f32_cmp(v1: f32, v2: f32) {
3 |     let error_margin = f32::EPSILON;
4 | 
5 |     assert!((v1 - v2).abs() < error_margin)
6 | }
7 | 


--------------------------------------------------------------------------------
/utils/src/f64_cmp.rs:
--------------------------------------------------------------------------------
1 | /// Compares two f64 values.
2 | pub fn f64_cmp(v1: f64, v2: f64) -> bool {
3 |     let error_margin = f64::EPSILON;
4 | 
5 |     (v1 - v2).abs() < error_margin
6 | }
7 | 


--------------------------------------------------------------------------------
/utils/src/filter.rs:
--------------------------------------------------------------------------------
 1 | /// Used to filter stuff such as the `on_changed` callback.
 2 | #[derive(Debug, Clone, Eq, PartialEq)]
 3 | pub enum Filter {
 4 |     // Everting will be filtered. No element will be available.
 5 |     Complete,
 6 | 
 7 |     // Nothing will be filtered, all elements will be available.
 8 |     Nothing,
 9 | 
10 |     /// Define a list of filtered element.
11 |     List(Vec<String>),
12 | }
13 | 
14 | impl From<&str> for Filter {
15 |     fn from(s: &str) -> Self {
16 |         match s {
17 |             "nothing" | "Nothing" => Filter::Nothing,
18 |             _ => Filter::Complete,
19 |         }
20 |     }
21 | }
22 | 
23 | impl From<String> for Filter {
24 |     fn from(s: String) -> Self {
25 |         Filter::from(s.as_str())
26 |     }
27 | }
28 | 
29 | impl From<Vec<String>> for Filter {
30 |     fn from(v: Vec<String>) -> Self {
31 |         Filter::List(v)
32 |     }
33 | }
34 | 
35 | impl From<Vec<&str>> for Filter {
36 |     fn from(v: Vec<&str>) -> Self {
37 |         let vec: Vec<String> = v.iter().map(|s| s.to_string()).collect();
38 |         Filter::from(vec)
39 |     }
40 | }
41 | 
42 | impl Default for Filter {
43 |     fn default() -> Self {
44 |         Filter::Complete
45 |     }
46 | }
47 | 


--------------------------------------------------------------------------------
/utils/src/lib.rs:
--------------------------------------------------------------------------------
 1 | //! Handles helper utilities and global methods.
 2 | 
 3 | pub use self::alignment::*;
 4 | pub use self::angle::*;
 5 | pub use self::border::*;
 6 | pub use self::brush::*;
 7 | pub use self::color::*;
 8 | pub use self::constraint::*;
 9 | pub use self::dirty_size::*;
10 | pub use self::expression::*;
11 | pub use self::f32_cmp::*;
12 | pub use self::f64_cmp::*;
13 | pub use self::filter::*;
14 | pub use self::gradients::*;
15 | pub use self::number::*;
16 | pub use self::orientation::*;
17 | pub use self::point::*;
18 | pub use self::rectangle::*;
19 | pub use self::relative_direction::*;
20 | pub use self::selection_mode::*;
21 | pub use self::size::*;
22 | pub use self::string16::*;
23 | pub use self::text_alignment::*;
24 | pub use self::text_baseline::*;
25 | pub use self::thickness::*;
26 | pub use self::value::*;
27 | pub use self::visibility::*;
28 | 
29 | mod alignment;
30 | mod angle;
31 | mod border;
32 | mod brush;
33 | mod color;
34 | mod constraint;
35 | mod dirty_size;
36 | mod expression;
37 | mod f32_cmp;
38 | mod f64_cmp;
39 | mod filter;
40 | mod gradients;
41 | mod number;
42 | mod orientation;
43 | mod point;
44 | 
45 | /// This module pre-selects commonly used OrbTk crates and put them into scope.
46 | pub mod prelude;
47 | 
48 | mod rectangle;
49 | mod relative_direction;
50 | mod selection_mode;
51 | mod size;
52 | mod spacer;
53 | mod string16;
54 | mod text_alignment;
55 | mod text_baseline;
56 | mod thickness;
57 | mod value;
58 | mod visibility;
59 | 


--------------------------------------------------------------------------------
/utils/src/number.rs:
--------------------------------------------------------------------------------
 1 | use std::ops::Neg;
 2 | 
 3 | /// Valid number types (64bit)
 4 | #[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
 5 | pub enum Number {
 6 |     Real(i64),
 7 |     Float(f64),
 8 | }
 9 | 
10 | impl Default for Number {
11 |     fn default() -> Self {
12 |         Self::Real(0)
13 |     }
14 | }
15 | 
16 | impl Eq for Number {}
17 | 
18 | impl Neg for Number {
19 |     type Output = Number;
20 | 
21 |     fn neg(self) -> Self::Output {
22 |         match self {
23 |             Number::Float(n) => Number::Float(-n),
24 |             Number::Real(n) => Number::Real(-n),
25 |         }
26 |     }
27 | }
28 | 
29 | macro_rules! impl_float {
30 |     ($t:ty) => {
31 |         impl From<$t> for Number {
32 |             fn from(n: $t) -> Number {
33 |                 Number::Float(n as f64)
34 |             }
35 |         }
36 | 
37 |         impl From<Number> for $t {
38 |             fn from(n: Number) -> Self {
39 |                 match n {
40 |                     Number::Real(n) => n as $t,
41 |                     Number::Float(n) => n as $t,
42 |                 }
43 |             }
44 |         }
45 |     };
46 | }
47 | 
48 | macro_rules! impl_real {
49 |     ($t:ty) => {
50 |         impl From<$t> for Number {
51 |             fn from(n: $t) -> Number {
52 |                 Number::Real(n as i64)
53 |             }
54 |         }
55 | 
56 |         impl From<Number> for $t {
57 |             fn from(n: Number) -> $t {
58 |                 match n {
59 |                     Number::Real(n) => n as $t,
60 |                     Number::Float(n) => n as $t,
61 |                 }
62 |             }
63 |         }
64 |     };
65 | }
66 | 
67 | impl_float!(f32);
68 | impl_float!(f64);
69 | 
70 | impl_real!(u8);
71 | impl_real!(i8);
72 | impl_real!(u16);
73 | impl_real!(i16);
74 | impl_real!(u32);
75 | impl_real!(i32);
76 | impl_real!(u64);
77 | impl_real!(i64);
78 | 


--------------------------------------------------------------------------------
/utils/src/orientation.rs:
--------------------------------------------------------------------------------
 1 | /// Is used to control the orientation of the `Stack`.
 2 | #[derive(Debug, Copy, Clone, Eq, PartialEq)]
 3 | pub enum Orientation {
 4 |     /// Vertical orientation.
 5 |     Vertical,
 6 | 
 7 |     /// Horizontal orientation.
 8 |     Horizontal,
 9 | }
10 | 
11 | // --- Conversions ---
12 | 
13 | impl From<&str> for Orientation {
14 |     fn from(t: &str) -> Self {
15 |         match t {
16 |             "Horizontal" | "horizontal" => Orientation::Horizontal,
17 |             _ => Orientation::Vertical,
18 |         }
19 |     }
20 | }
21 | 
22 | impl Default for Orientation {
23 |     fn default() -> Orientation {
24 |         Orientation::Vertical
25 |     }
26 | }
27 | 
28 | #[cfg(test)]
29 | mod tests {
30 |     use super::*;
31 | 
32 |     #[test]
33 |     fn test_into() {
34 |         let orientation: Orientation = "Vertical".into();
35 |         assert_eq!(orientation, Orientation::Vertical);
36 | 
37 |         let orientation: Orientation = "vertical".into();
38 |         assert_eq!(orientation, Orientation::Vertical);
39 | 
40 |         let orientation: Orientation = "Horizontal".into();
41 |         assert_eq!(orientation, Orientation::Horizontal);
42 | 
43 |         let orientation: Orientation = "horizontal".into();
44 |         assert_eq!(orientation, Orientation::Horizontal);
45 | 
46 |         let orientation: Orientation = "other".into();
47 |         assert_eq!(orientation, Orientation::Vertical);
48 |     }
49 | }
50 | 


--------------------------------------------------------------------------------
/utils/src/prelude.rs:
--------------------------------------------------------------------------------
1 | pub use crate::*;
2 | 


--------------------------------------------------------------------------------
/utils/src/relative_direction.rs:
--------------------------------------------------------------------------------
 1 | use crate::Point;
 2 | 
 3 | /// Describes the relative position of the object.
 4 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
 5 | pub enum RelativeDir {
 6 |     Top,
 7 |     TopRight,
 8 |     Right,
 9 |     BottomRight,
10 |     Bottom,
11 |     BottomLeft,
12 |     Left,
13 |     TopLeft,
14 | }
15 | 
16 | impl RelativeDir {
17 |     /// Computes the start and end points of a line that crosses a given field in the `self` direction
18 |     pub fn cross(&self, width: f64, height: f64) -> (Point, Point) {
19 |         let (start, end);
20 |         let mid_width = width / 2.0;
21 |         let mid_height = height / 2.0;
22 |         match self {
23 |             RelativeDir::Top => {
24 |                 start = Point::new(mid_width, height);
25 |                 end = Point::new(mid_width, 0.0);
26 |             }
27 |             RelativeDir::TopRight => {
28 |                 start = Point::new(0.0, height);
29 |                 end = Point::new(width, 0.0);
30 |             }
31 |             RelativeDir::Right => {
32 |                 start = Point::new(0.0, mid_height);
33 |                 end = Point::new(width, mid_height);
34 |             }
35 |             RelativeDir::BottomRight => {
36 |                 start = Point::new(0.0, 0.0);
37 |                 end = Point::new(width, height);
38 |             }
39 |             RelativeDir::Bottom => {
40 |                 start = Point::new(mid_width, 0.0);
41 |                 end = Point::new(mid_width, height);
42 |             }
43 |             RelativeDir::BottomLeft => {
44 |                 start = Point::new(width, 0.0);
45 |                 end = Point::new(0.0, height);
46 |             }
47 |             RelativeDir::Left => {
48 |                 start = Point::new(width, mid_height);
49 |                 end = Point::new(0.0, mid_height);
50 |             }
51 |             RelativeDir::TopLeft => {
52 |                 start = Point::new(width, height);
53 |                 end = Point::new(0.0, 0.0);
54 |             }
55 |         }
56 |         (start, end)
57 |     }
58 | }
59 | 


--------------------------------------------------------------------------------
/utils/src/selection_mode.rs:
--------------------------------------------------------------------------------
 1 | /// Represents a selection mode.
 2 | #[derive(Copy, Clone, Eq, PartialEq, Debug)]
 3 | pub enum SelectionMode {
 4 |     None,
 5 |     Single,
 6 |     Multiple,
 7 | }
 8 | 
 9 | impl Default for SelectionMode {
10 |     fn default() -> Self {
11 |         SelectionMode::Single
12 |     }
13 | }
14 | 
15 | impl From<&str> for SelectionMode {
16 |     fn from(t: &str) -> Self {
17 |         match t {
18 |             "Single" | "single" => SelectionMode::Single,
19 |             "Multiple" | "multiple" => SelectionMode::Multiple,
20 |             _ => SelectionMode::None,
21 |         }
22 |     }
23 | }
24 | 
25 | #[cfg(test)]
26 | mod tests {
27 |     use crate::prelude::*;
28 | 
29 |     #[test]
30 |     fn test_into() {
31 |         let selection_mode: SelectionMode = "Single".into();
32 |         assert_eq!(selection_mode, SelectionMode::Single);
33 | 
34 |         let selection_mode: SelectionMode = "single".into();
35 |         assert_eq!(selection_mode, SelectionMode::Single);
36 | 
37 |         let selection_mode: SelectionMode = "Multiple".into();
38 |         assert_eq!(selection_mode, SelectionMode::Multiple);
39 | 
40 |         let selection_mode: SelectionMode = "multiple".into();
41 |         assert_eq!(selection_mode, SelectionMode::Multiple);
42 | 
43 |         let selection_mode: SelectionMode = "None".into();
44 |         assert_eq!(selection_mode, SelectionMode::None);
45 | 
46 |         let selection_mode: SelectionMode = "none".into();
47 |         assert_eq!(selection_mode, SelectionMode::None);
48 | 
49 |         let selection_mode: SelectionMode = "other".into();
50 |         assert_eq!(selection_mode, SelectionMode::None);
51 |     }
52 | }
53 | 


--------------------------------------------------------------------------------
/utils/src/size.rs:
--------------------------------------------------------------------------------
  1 | use derive_more::{Add, Constructor, From, Sub};
  2 | use std::ops::Div;
  3 | 
  4 | /// A `Size` specified by width and height.
  5 | ///
  6 | /// # Examples
  7 | /// ```rust
  8 | /// # use orbtk_utils::Size;
  9 | /// let size = Size::new(10., 10.);
 10 | /// let other_size = Size::new(5., 7.);
 11 | /// let result = size - other_size;
 12 | ///
 13 | /// assert_eq!(result.width(), 5.);
 14 | /// assert_eq!(result.height(), 3.);
 15 | /// ```
 16 | #[derive(Constructor, Add, Sub, Copy, From, Clone, Default, Debug, PartialEq)]
 17 | pub struct Size {
 18 |     width: f64,
 19 |     height: f64,
 20 | }
 21 | 
 22 | impl Size {
 23 |     /// Gets the width of the size.
 24 |     pub fn width(&self) -> f64 {
 25 |         self.width
 26 |     }
 27 | 
 28 |     /// Sets the width of the size.
 29 |     pub fn set_width(&mut self, width: f64) {
 30 |         self.width = width;
 31 |     }
 32 | 
 33 |     /// Gets the height of the size.
 34 |     pub fn height(&self) -> f64 {
 35 |         self.height
 36 |     }
 37 | 
 38 |     /// Sets the height of the size.
 39 |     pub fn set_height(&mut self, height: f64) {
 40 |         self.height = height;
 41 |     }
 42 | }
 43 | 
 44 | // Operations
 45 | 
 46 | impl Div<f64> for Size {
 47 |     type Output = Size;
 48 | 
 49 |     fn div(mut self, rhs: f64) -> Self::Output {
 50 |         self.width /= rhs;
 51 |         self.height /= rhs;
 52 |         self
 53 |     }
 54 | }
 55 | 
 56 | impl Div<Size> for f64 {
 57 |     type Output = Size;
 58 | 
 59 |     fn div(self, mut rhs: Size) -> Self::Output {
 60 |         rhs.width /= self;
 61 |         rhs.height /= self;
 62 |         rhs
 63 |     }
 64 | }
 65 | 
 66 | // --- Conversions ---
 67 | 
 68 | impl From<f64> for Size {
 69 |     fn from(t: f64) -> Self {
 70 |         Size::new(t, t)
 71 |     }
 72 | }
 73 | 
 74 | impl From<i32> for Size {
 75 |     fn from(t: i32) -> Self {
 76 |         Size::new(t as f64, t as f64)
 77 |     }
 78 | }
 79 | 
 80 | impl From<(i32, i32)> for Size {
 81 |     fn from(s: (i32, i32)) -> Size {
 82 |         Size::from((s.0 as f64, s.1 as f64))
 83 |     }
 84 | }
 85 | 
 86 | // --- Conversions ---
 87 | 
 88 | #[cfg(test)]
 89 | mod tests {
 90 |     use super::*;
 91 | 
 92 |     #[test]
 93 |     fn test_sub() {
 94 |         let expected_result = Size::new(-3., 5.);
 95 |         const ERROR_MARGIN: f64 = 0.00001;
 96 | 
 97 |         let left_side = Size::new(5., 7.);
 98 |         let right_side = Size::new(8., 2.);
 99 | 
100 |         let result = left_side - right_side;
101 | 
102 |         assert!((result.width() - expected_result.width()).abs() < ERROR_MARGIN);
103 |         assert!((result.height() - expected_result.height()).abs() < ERROR_MARGIN);
104 |     }
105 | 
106 |     #[test]
107 |     fn test_add() {
108 |         let expected_result = Size::new(13., 9.);
109 |         const ERROR_MARGIN: f64 = 0.00001;
110 | 
111 |         let left_side = Size::new(5., 7.);
112 |         let right_side = Size::new(8., 2.);
113 | 
114 |         let result = left_side + right_side;
115 | 
116 |         assert!((result.width() - expected_result.width()).abs() < ERROR_MARGIN);
117 |         assert!((result.height() - expected_result.height()).abs() < ERROR_MARGIN);
118 |     }
119 | }
120 | 


--------------------------------------------------------------------------------
/utils/src/spacer.rs:
--------------------------------------------------------------------------------
 1 | use crate::Thickness;
 2 | 
 3 | // todo:  documentation
 4 | pub trait Spacer {
 5 |     /// Gets left.
 6 |     fn left(&self) -> f64;
 7 | 
 8 |     /// Sets left.
 9 |     fn set_left(&mut self, left: f64);
10 | 
11 |     /// Gets top.
12 |     fn top(&self) -> f64;
13 | 
14 |     /// Sets top.
15 |     fn set_top(&mut self, top: f64);
16 | 
17 |     /// Gets right.
18 |     fn right(&self) -> f64;
19 | 
20 |     /// Sets right.
21 |     fn set_right(&mut self, right: f64);
22 | 
23 |     /// Gets bottom.
24 |     fn bottom(&self) -> f64;
25 | 
26 |     /// Sets bottom.
27 |     fn set_bottom(&mut self, bottom: f64);
28 | 
29 |     /// Gets thickness.
30 |     fn thickness(&self) -> Thickness;
31 | 
32 |     /// Sets thickness.
33 |     fn set_thickness<T: Into<Thickness>>(&mut self, thickness: T);
34 | }
35 | 


--------------------------------------------------------------------------------
/utils/src/text_alignment.rs:
--------------------------------------------------------------------------------
 1 | /// Used to align a text.
 2 | #[derive(Clone, Copy, Eq, Debug, PartialEq)]
 3 | pub enum TextAlignment {
 4 |     Left,
 5 |     Right,
 6 |     Center,
 7 |     Start,
 8 |     End,
 9 | }
10 | 
11 | impl ToString for TextAlignment {
12 |     fn to_string(&self) -> String {
13 |         match self {
14 |             TextAlignment::Left => "left".to_string(),
15 |             TextAlignment::Right => "right".to_string(),
16 |             TextAlignment::Center => "center".to_string(),
17 |             TextAlignment::Start => "start".to_string(),
18 |             TextAlignment::End => "end".to_string(),
19 |         }
20 |     }
21 | }
22 | 


--------------------------------------------------------------------------------
/utils/src/text_baseline.rs:
--------------------------------------------------------------------------------
 1 | /// Text baseline being used when drawing text
 2 | pub enum TextBaseline {
 3 |     /// Text baseline is top of the em square
 4 |     Top,
 5 | 
 6 |     /// Text baseline is the hanging baseline.
 7 |     Hanging,
 8 | 
 9 |     /// Text baseline is the middle of the em square.
10 |     Middle,
11 | 
12 |     /// Text baseline is the normal alphabetic baseline. (default)
13 |     Alphabetic,
14 | 
15 |     /// Text baseline is the ideographic baseline
16 |     Ideographic,
17 | 
18 |     /// Text baseline is the bottom of the bounding box.
19 |     Bottom,
20 | }
21 | 
22 | impl Default for TextBaseline {
23 |     fn default() -> Self {
24 |         TextBaseline::Alphabetic
25 |     }
26 | }
27 | 


--------------------------------------------------------------------------------
/utils/src/value.rs:
--------------------------------------------------------------------------------
 1 | use serde::de::DeserializeOwned;
 2 | /// Wraps a ron value and is used to support conversion to different types.
 3 | pub struct Value(pub ron::Value);
 4 | 
 5 | impl Value {
 6 |     /// Converts the internal value to the given type.
 7 |     pub fn get<T>(self) -> T
 8 |     where
 9 |         T: Default + DeserializeOwned,
10 |     {
11 |         if let Ok(value) = self.0.into_rust::<T>() {
12 |             return value;
13 |         }
14 | 
15 |         T::default()
16 |     }
17 | }
18 | 
19 | impl From<ron::Value> for Value {
20 |     fn from(v: ron::Value) -> Self {
21 |         Value(v)
22 |     }
23 | }
24 | 
25 | impl From<Value> for String {
26 |     fn from(v: Value) -> String {
27 |         v.get::<String>()
28 |     }
29 | }
30 | 
31 | impl From<Value> for f64 {
32 |     fn from(v: Value) -> f64 {
33 |         v.get::<f64>()
34 |     }
35 | }
36 | 
37 | impl From<Value> for f32 {
38 |     fn from(v: Value) -> f32 {
39 |         v.get::<f32>()
40 |     }
41 | }
42 | 


--------------------------------------------------------------------------------
/utils/src/visibility.rs:
--------------------------------------------------------------------------------
 1 | /// Is used to control the visibility of a widget
 2 | #[derive(Debug, Copy, Clone, Eq, PartialEq)]
 3 | pub enum Visibility {
 4 |     /// The widget is visible.
 5 |     Visible,
 6 | 
 7 |     /// The widget will not be displayed, isn't taken into account in the
 8 |     /// layout pipeline. It **does** consume memory in the render buffer.
 9 |     Hidden,
10 | 
11 |     /// The widget isn't displayed but `is` rendered. Thus it **does
12 |     /// not** consume space in the layout.
13 |     Collapsed,
14 | }
15 | 
16 | impl Default for Visibility {
17 |     fn default() -> Visibility {
18 |         Visibility::Visible
19 |     }
20 | }
21 | 
22 | // --- Conversions ---
23 | 
24 | impl From<&str> for Visibility {
25 |     fn from(t: &str) -> Self {
26 |         match t {
27 |             "Hidden" | "hidden" => Visibility::Hidden,
28 |             "Collapsed" | "collapsed" => Visibility::Collapsed,
29 |             _ => Visibility::Visible,
30 |         }
31 |     }
32 | }
33 | 
34 | #[cfg(test)]
35 | mod tests {
36 |     use super::*;
37 | 
38 |     #[test]
39 |     fn test_into() {
40 |         let visibility: Visibility = "Hidden".into();
41 |         assert_eq!(visibility, Visibility::Hidden);
42 | 
43 |         let visibility: Visibility = "hidden".into();
44 |         assert_eq!(visibility, Visibility::Hidden);
45 | 
46 |         let visibility: Visibility = "Collapsed".into();
47 |         assert_eq!(visibility, Visibility::Collapsed);
48 | 
49 |         let visibility: Visibility = "collapsed".into();
50 |         assert_eq!(visibility, Visibility::Collapsed);
51 | 
52 |         let visibility: Visibility = "Visible".into();
53 |         assert_eq!(visibility, Visibility::Visible);
54 | 
55 |         let visibility: Visibility = "visible".into();
56 |         assert_eq!(visibility, Visibility::Visible);
57 | 
58 |         let visibility: Visibility = "other".into();
59 |         assert_eq!(visibility, Visibility::Visible);
60 |     }
61 | }
62 | 


--------------------------------------------------------------------------------