├── .gitignore ├── images ├── showcase │ ├── badge.png │ ├── card.png │ ├── modal.png │ ├── color_picker.png │ ├── date_picker.png │ ├── number_input.png │ ├── split_example.gif │ ├── tabs_example.gif │ ├── time_picker.png │ └── floating_button.png └── concept_drawings │ ├── modal.svg │ └── floating_action_button.svg ├── examples ├── tabs │ ├── fonts │ │ ├── icons.ttf │ │ ├── LICENSE.txt │ │ └── config.json │ ├── images │ │ └── ferris.png │ ├── Cargo.toml │ └── src │ │ ├── counter.rs │ │ ├── ferris.rs │ │ ├── settings.rs │ │ ├── login.rs │ │ └── main.rs ├── pure │ ├── tabs │ │ ├── fonts │ │ │ ├── icons.ttf │ │ │ ├── LICENSE.txt │ │ │ └── config.json │ │ ├── images │ │ │ └── ferris.png │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── counter.rs │ │ │ ├── ferris.rs │ │ │ ├── login.rs │ │ │ ├── settings.rs │ │ │ └── main.rs │ ├── tab_bar │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── split │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── grid │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── card │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── badge │ │ └── Cargo.toml │ ├── selection_list │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── modal │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── time_picker │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── color_picker │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── date_picker │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── wrap │ │ └── Cargo.toml │ ├── number_input │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ └── floating_element │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── web │ ├── index.html │ ├── Makefile │ ├── Cargo.toml │ └── src │ │ ├── modal_section.rs │ │ ├── card_section.rs │ │ ├── badge_section.rs │ │ ├── date_picker_section.rs │ │ ├── color_picker_section.rs │ │ ├── floating_button_section.rs │ │ ├── picklist_section.rs │ │ └── time_picker_section.rs ├── tabs_min │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── tab_bar │ └── Cargo.toml ├── split │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── grid │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── card │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── badge │ └── Cargo.toml ├── selection_list │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── date_picker │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── color_picker │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── modal │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── time_picker │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── wrap │ └── Cargo.toml ├── number_input │ ├── Cargo.toml │ └── src │ │ └── main.rs └── floating_button │ ├── Cargo.toml │ └── src │ └── main.rs ├── src ├── graphics │ ├── fonts │ │ ├── bootstrap-icons.ttf │ │ └── required-icons.ttf │ ├── selection_list.rs │ ├── color_picker.rs │ ├── time_picker.rs │ ├── grid.rs │ ├── wrap.rs │ ├── card.rs │ ├── badge.rs │ ├── date_picker.rs │ ├── icon_text.rs │ ├── modal.rs │ ├── floating_button.rs │ ├── number_input.rs │ ├── split.rs │ ├── tab_bar.rs │ ├── tabs.rs │ ├── icons │ │ └── required.rs │ ├── icons.rs │ └── mod.rs ├── style │ ├── style_state.rs │ ├── mod.rs │ ├── modal.rs │ ├── selection_list.rs │ ├── number_input.rs │ ├── tab_bar.rs │ ├── split.rs │ ├── color_picker.rs │ ├── date_picker.rs │ ├── time_picker.rs │ └── button.rs ├── core │ ├── mod.rs │ ├── renderer.rs │ └── overlay.rs ├── native │ ├── tab_bar │ │ └── tab_label.rs │ ├── tabs │ │ └── tab_bar_position.rs │ ├── overlay │ │ └── mod.rs │ ├── floating_button │ │ ├── anchor.rs │ │ └── offset.rs │ └── mod.rs ├── pure │ ├── overlay │ │ └── mod.rs │ └── mod.rs └── lib.rs ├── .github └── workflows │ ├── clippy.yml │ ├── format.yml │ ├── rustdoc.yml │ └── test.yml ├── LICENSE └── Cargo.toml /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | Cargo.lock 3 | pkg/ 4 | .vscode 5 | .idea 6 | -------------------------------------------------------------------------------- /images/showcase/badge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/images/showcase/badge.png -------------------------------------------------------------------------------- /images/showcase/card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/images/showcase/card.png -------------------------------------------------------------------------------- /images/showcase/modal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/images/showcase/modal.png -------------------------------------------------------------------------------- /examples/tabs/fonts/icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/examples/tabs/fonts/icons.ttf -------------------------------------------------------------------------------- /examples/tabs/images/ferris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/examples/tabs/images/ferris.png -------------------------------------------------------------------------------- /images/showcase/color_picker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/images/showcase/color_picker.png -------------------------------------------------------------------------------- /images/showcase/date_picker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/images/showcase/date_picker.png -------------------------------------------------------------------------------- /images/showcase/number_input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/images/showcase/number_input.png -------------------------------------------------------------------------------- /images/showcase/split_example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/images/showcase/split_example.gif -------------------------------------------------------------------------------- /images/showcase/tabs_example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/images/showcase/tabs_example.gif -------------------------------------------------------------------------------- /images/showcase/time_picker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/images/showcase/time_picker.png -------------------------------------------------------------------------------- /examples/pure/tabs/fonts/icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/examples/pure/tabs/fonts/icons.ttf -------------------------------------------------------------------------------- /images/showcase/floating_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/images/showcase/floating_button.png -------------------------------------------------------------------------------- /examples/pure/tabs/images/ferris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/examples/pure/tabs/images/ferris.png -------------------------------------------------------------------------------- /src/graphics/fonts/bootstrap-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/src/graphics/fonts/bootstrap-icons.ttf -------------------------------------------------------------------------------- /src/graphics/fonts/required-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kaiden42/iced_aw/HEAD/src/graphics/fonts/required-icons.ttf -------------------------------------------------------------------------------- /examples/tabs/fonts/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Font license info 2 | 3 | 4 | ## Font Awesome 5 | 6 | Copyright (C) 2016 by Dave Gandy 7 | 8 | Author: Dave Gandy 9 | License: SIL () 10 | Homepage: http://fortawesome.github.com/Font-Awesome/ 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/pure/tabs/fonts/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Font license info 2 | 3 | 4 | ## Font Awesome 5 | 6 | Copyright (C) 2016 by Dave Gandy 7 | 8 | Author: Dave Gandy 9 | License: SIL () 10 | Homepage: http://fortawesome.github.com/Font-Awesome/ 11 | 12 | 13 | -------------------------------------------------------------------------------- /.github/workflows/clippy.yml: -------------------------------------------------------------------------------- 1 | name: Clippy 2 | on: [push, pull_request] 3 | jobs: 4 | all: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: hecrj/setup-rust-action@v1 8 | with: 9 | components: clippy 10 | - uses: actions/checkout@master 11 | - name: Lint with clippy 12 | run: cargo clippy --all -------------------------------------------------------------------------------- /.github/workflows/format.yml: -------------------------------------------------------------------------------- 1 | name: Format 2 | on: [push, pull_request] 3 | jobs: 4 | all: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: hecrj/setup-rust-action@v1 8 | with: 9 | components: rustfmt 10 | - uses: actions/checkout@master 11 | - name: Check format 12 | run: cargo fmt --all -- --check -------------------------------------------------------------------------------- /src/style/style_state.rs: -------------------------------------------------------------------------------- 1 | //! Helper enum for the state of the style 2 | 3 | /// The state of the style 4 | #[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 5 | pub enum StyleState { 6 | /// Use the active style 7 | Active, 8 | /// Use the selected style 9 | Selected, 10 | /// Use the hovered style 11 | Hovered, 12 | /// Use the focused style 13 | Focused, 14 | } 15 | -------------------------------------------------------------------------------- /examples/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Embedded web application 7 | 8 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /src/graphics/selection_list.rs: -------------------------------------------------------------------------------- 1 | //! Display a list of selectable values. 2 | use iced_graphics::Renderer; 3 | 4 | pub use crate::native::selection_list::{self, list, State}; 5 | pub use crate::style::selection_list::{Style, StyleSheet}; 6 | 7 | /// A widget allowing the selection of a single value from a list of options. 8 | pub type SelectionList<'a, T, Message, Backend> = 9 | selection_list::SelectionList<'a, T, Message, Renderer>; 10 | -------------------------------------------------------------------------------- /src/graphics/color_picker.rs: -------------------------------------------------------------------------------- 1 | //! Use a color picker as an input element for picking colors. 2 | //! 3 | //! *This API requires the following crate features to be activated: `color_picker`* 4 | 5 | use crate::native::color_picker; 6 | pub use crate::native::color_picker::State; 7 | 8 | /// An input element for picking colors. 9 | /// 10 | /// This is an alias of an `iced_native` `ColorPicker` with an `iced_wgpu::Renderer`. 11 | pub use color_picker::ColorPicker; 12 | -------------------------------------------------------------------------------- /examples/tabs_min/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tabs_min" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../.." } 11 | 12 | [dependencies.iced] 13 | #git = "https://github.com/iced-rs/iced.git" 14 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 15 | version = "0.4.2" 16 | -------------------------------------------------------------------------------- /src/graphics/time_picker.rs: -------------------------------------------------------------------------------- 1 | //! Use a time picker as an input element for picking times. 2 | //! 3 | //! *This API requires the following crate features to be activated: `time_picker`* 4 | 5 | use crate::native::time_picker; 6 | pub use crate::native::time_picker::{Period, State, Time}; 7 | 8 | /// An input element for picking times. 9 | /// 10 | /// This is an alias of an `iced_native` `TimePicker` with an `iced_wgpu::Renderer`. 11 | pub use time_picker::TimePicker; 12 | -------------------------------------------------------------------------------- /src/graphics/grid.rs: -------------------------------------------------------------------------------- 1 | //! Use a grid as an input element for creating grids. 2 | //! 3 | //! *This API requires the following crate features to be activated: `grid`* 4 | use iced_graphics::Renderer; 5 | 6 | use crate::native::grid; 7 | 8 | /// A container that distributes its contents in a grid. 9 | /// 10 | /// This is an alias of an `iced_native` `Grid` with a default `iced_wgpu::Renderer`. 11 | pub type Grid<'a, Message, Backend> = grid::Grid<'a, Message, Renderer>; 12 | -------------------------------------------------------------------------------- /src/graphics/wrap.rs: -------------------------------------------------------------------------------- 1 | //! A widget that displays its children in multiple horizontal or vertical runs. 2 | //! 3 | //! *This API requires the following crate features to be activated: `wrap`* 4 | use crate::native::wrap; 5 | 6 | /// A widget that displays its children in multiple horizontal or vertical runs. 7 | /// 8 | /// This is an alias of an `iced_native` `Wrap` with an `iced_wgpu::Renderer`. 9 | pub type Wrap<'a, B, Message, Direction> = wrap::Wrap<'a, B, Message, Direction>; 10 | -------------------------------------------------------------------------------- /examples/tab_bar/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tab_bar" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../..", features = ["tab_bar"] } 11 | 12 | [dependencies.iced] 13 | #git = "https://github.com/iced-rs/iced.git" 14 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 15 | version = "0.4.2" 16 | -------------------------------------------------------------------------------- /src/graphics/card.rs: -------------------------------------------------------------------------------- 1 | //! Displays a [`Card`](Card). 2 | //! 3 | //! *This API requires the following crate features to be activated: card* 4 | use iced_graphics::Renderer; 5 | 6 | use crate::native::card; 7 | pub use crate::style::card::{Style, StyleSheet}; 8 | 9 | /// A card consisting of a head, body and optional foot. 10 | /// 11 | /// This is an alias of an `iced_native` Card with an `iced_wgpu::Renderer`. 12 | pub type Card<'a, Message, Backend> = card::Card<'a, Message, Renderer>; 13 | -------------------------------------------------------------------------------- /examples/split/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "split" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../..", default-features = false, features = ["split"] } 11 | 12 | [dependencies.iced] 13 | #git = "https://github.com/iced-rs/iced.git" 14 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 15 | version = "0.4.2" 16 | -------------------------------------------------------------------------------- /examples/tabs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tabs" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | publish = false 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | iced_aw = { path = "../..", features = ["tabs"] } 12 | 13 | [dependencies.iced] 14 | #git = "https://github.com/iced-rs/iced.git" 15 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 16 | version = "0.4.2" 17 | features = [ "image",] -------------------------------------------------------------------------------- /examples/pure/tab_bar/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pure_tab_bar" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../../..", features = ["tab_bar", "pure"] } 11 | 12 | [dependencies.iced] 13 | #git = "https://github.com/iced-rs/iced.git" 14 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 15 | version = "0.4.2" 16 | features = ["pure"] -------------------------------------------------------------------------------- /src/graphics/badge.rs: -------------------------------------------------------------------------------- 1 | //! Use a badge for color highlighting important information. 2 | //! 3 | //! *This API requires the following crate features to be activated: badge* 4 | use iced_graphics::Renderer; 5 | 6 | use crate::native::badge; 7 | pub use crate::style::badge::{Style, StyleSheet}; 8 | 9 | /// A badge for color highlighting small information. 10 | /// 11 | /// This is an alias of an `iced_native` Badge with an `iced_wgpu::Renderer`. 12 | pub type Badge<'a, Message, Backend> = badge::Badge<'a, Message, Renderer>; 13 | -------------------------------------------------------------------------------- /examples/grid/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "grid" 3 | version = "0.1.0" 4 | authors = ["daxpedda ", "Luni-4 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../..", default-features = false, features = ["grid"] } 11 | 12 | [dependencies.iced] 13 | #git = "https://github.com/iced-rs/iced.git" 14 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 15 | version = "0.4.2" 16 | -------------------------------------------------------------------------------- /examples/card/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "card" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../..", default-features = false, features = [ 11 | "card", 12 | "colors", 13 | ] } 14 | 15 | [dependencies.iced] 16 | #git = "https://github.com/iced-rs/iced.git" 17 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 18 | version = "0.4.2" 19 | -------------------------------------------------------------------------------- /examples/badge/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "badge" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../..", default-features = false, features = [ 11 | "badge", 12 | "colors", 13 | ] } 14 | 15 | [dependencies.iced] 16 | #git = "https://github.com/iced-rs/iced.git" 17 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 18 | version = "0.4.2" 19 | -------------------------------------------------------------------------------- /examples/pure/tabs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pure_tabs" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | publish = false 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | iced_aw = { path = "../../..", features = ["tabs", "pure"] } 12 | 13 | [dependencies.iced] 14 | #git = "https://github.com/iced-rs/iced.git" 15 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 16 | version = "0.4.2" 17 | features = [ "image", "pure"] -------------------------------------------------------------------------------- /examples/selection_list/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "selection_list" 3 | version = "0.1.0" 4 | authors = [ 5 | "Héctor Ramón Jiménez ", 6 | "Andrew Wheeler ", 7 | ] 8 | edition = "2021" 9 | publish = false 10 | 11 | [dependencies] 12 | iced_aw = { path = "../..", default-features = false, features = [ 13 | "selection_list", 14 | ] } 15 | 16 | [dependencies.iced] 17 | #git = "https://github.com/iced-rs/iced.git" 18 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 19 | version = "0.4.2" 20 | -------------------------------------------------------------------------------- /examples/date_picker/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "date_picker" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | iced_aw = { path = "../..", default-features = false, features = [ 10 | "date_picker", 11 | "colors", 12 | ] } 13 | 14 | [dependencies.iced] 15 | #git = "https://github.com/iced-rs/iced.git" 16 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 17 | version = "0.4.2" 18 | -------------------------------------------------------------------------------- /examples/pure/split/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pure_split" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../../..", default-features = false, features = ["split", "pure"] } 11 | 12 | [dependencies.iced] 13 | #git = "https://github.com/iced-rs/iced.git" 14 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 15 | version = "0.4.2" 16 | features = ["pure"] 17 | -------------------------------------------------------------------------------- /examples/color_picker/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "color_picker" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../..", default-features = false, features = [ 11 | "color_picker", 12 | "colors", 13 | ] } 14 | 15 | [dependencies.iced] 16 | #git = "https://github.com/iced-rs/iced.git" 17 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 18 | version = "0.4.2" -------------------------------------------------------------------------------- /examples/modal/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "modal" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../..", default-features = false, features = [ 11 | "card", 12 | "colors", 13 | "modal", 14 | ] } 15 | 16 | [dependencies.iced] 17 | #git = "https://github.com/iced-rs/iced.git" 18 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 19 | version = "0.4.2" 20 | -------------------------------------------------------------------------------- /examples/time_picker/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "time_picker" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../..", default-features = false, features = [ 11 | "colors", 12 | "time_picker", 13 | ] } 14 | 15 | [dependencies.iced] 16 | #git = "https://github.com/iced-rs/iced.git" 17 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 18 | version = "0.4.2" 19 | -------------------------------------------------------------------------------- /src/graphics/date_picker.rs: -------------------------------------------------------------------------------- 1 | //! Use a date picker as an input element for picking dates. 2 | //! 3 | //! *This API requires the following crate features to be activated: `date_picker`* 4 | use iced_graphics::Renderer; 5 | 6 | use crate::native::date_picker; 7 | pub use crate::native::date_picker::{Date, State}; 8 | 9 | /// An input element for picking dates. 10 | /// 11 | /// This is an alias of an `iced_native` `DatePicker` with an `iced_wgpu::Renderer`. 12 | pub type DatePicker<'a, Message, Backend> = date_picker::DatePicker<'a, Message, Renderer>; 13 | -------------------------------------------------------------------------------- /examples/wrap/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wrap" 3 | version = "0.1.0" 4 | authors = ["Downtime "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../..", default-features = false, features = [ 11 | "wrap", 12 | "number_input", 13 | ] } 14 | rand = "0.8" 15 | 16 | [dependencies.iced] 17 | #git = "https://github.com/iced-rs/iced.git" 18 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 19 | version = "0.4.2" 20 | -------------------------------------------------------------------------------- /examples/pure/grid/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pure_grid" 3 | version = "0.1.0" 4 | authors = ["daxpedda ", "Luni-4 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../../..", default-features = false, features = ["grid", "pure"] } 11 | 12 | [dependencies.iced] 13 | #git = "https://github.com/iced-rs/iced.git" 14 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 15 | version = "0.4.2" 16 | features = [ "pure" ] -------------------------------------------------------------------------------- /src/graphics/icon_text.rs: -------------------------------------------------------------------------------- 1 | //! Text widget for rendering icons. 2 | //! 3 | //! Nearly a complete copy of the `iced_native::Text` widget, but with the 4 | //! icons font as a default font. Maybe I'll find a better way in the future. 5 | //! 6 | //! //! *This API requires the following crate features to be activated: `icon_text`* 7 | use iced_graphics::Renderer; 8 | 9 | /// Text widget with icon font. 10 | /// 11 | /// This is an alias of an `iced_native` `IconText` with an `iced_wgpu::Renderer`. 12 | pub type IconText = crate::native::icon_text::IconText>; 13 | -------------------------------------------------------------------------------- /examples/number_input/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "number_input" 3 | version = "0.1.0" 4 | authors = ["leang27 <52003343+leang27@users.noreply.github.com>"] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../..", default-features = false, features = [ 11 | "number_input", 12 | "icons", 13 | ] } 14 | 15 | [dependencies.iced] 16 | #git = "https://github.com/iced-rs/iced.git" 17 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 18 | version = "0.4.2" 19 | -------------------------------------------------------------------------------- /examples/floating_button/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "floating_button" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../..", default-features = false, features = [ 11 | "floating_button", 12 | "colors", 13 | "icons", 14 | ] } 15 | 16 | [dependencies.iced] 17 | #git = "https://github.com/iced-rs/iced.git" 18 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 19 | version = "0.4.2" 20 | -------------------------------------------------------------------------------- /examples/pure/card/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pure_card" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../../..", default-features = false, features = [ 11 | "card", 12 | "colors", 13 | "pure", 14 | ] } 15 | 16 | [dependencies.iced] 17 | #git = "https://github.com/iced-rs/iced.git" 18 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 19 | version = "0.4.2" 20 | features = ["pure"] -------------------------------------------------------------------------------- /examples/pure/badge/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pure_badge" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../../..", default-features = false, features = [ 11 | "badge", 12 | "colors", 13 | "pure" 14 | ] } 15 | 16 | [dependencies.iced] 17 | #git = "https://github.com/iced-rs/iced.git" 18 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 19 | version = "0.4.2" 20 | features = ["pure"] 21 | -------------------------------------------------------------------------------- /examples/pure/selection_list/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pure_selection_list" 3 | version = "0.1.0" 4 | authors = [ 5 | "Héctor Ramón Jiménez ", 6 | "Andrew Wheeler ", 7 | ] 8 | edition = "2021" 9 | publish = false 10 | 11 | [dependencies] 12 | iced_aw = { path = "../../..", default-features = false, features = [ 13 | "selection_list", 14 | "pure" 15 | ] } 16 | 17 | [dependencies.iced] 18 | #git = "https://github.com/iced-rs/iced.git" 19 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 20 | version = "0.4.2" 21 | features = ["pure"] -------------------------------------------------------------------------------- /src/graphics/modal.rs: -------------------------------------------------------------------------------- 1 | //! Use a badge for color highlighting important information. 2 | //! 3 | //! *This API requires the following crate features to be activated: badge* 4 | 5 | use iced_graphics::Renderer; 6 | 7 | use crate::native::modal; 8 | pub use crate::native::modal::State; 9 | pub use crate::style::modal::{Style, StyleSheet}; 10 | 11 | /// A modal content as an overlay. 12 | /// 13 | /// This is an alias of an `iced_native` Modal with an `iced_wgpu::Renderer`. 14 | pub type Modal<'a, State, Content, Message, Backend> = 15 | modal::Modal<'a, State, Content, Message, Renderer>; 16 | -------------------------------------------------------------------------------- /examples/web/Makefile: -------------------------------------------------------------------------------- 1 | debug: 2 | cargo build --target wasm32-unknown-unknown 3 | #wasm-bindgen target/wasm32-unknown-unknown/debug/web.wasm --out-dir pkg --web 4 | # after change of workspace -> new location... 5 | wasm-bindgen ../../target/wasm32-unknown-unknown/debug/web.wasm --out-dir pkg --web 6 | 7 | 8 | release: 9 | cargo build --release --target wasm32-unknown-unknown 10 | #wasm-bindgen target/wasm32-unknown-unknown/release/web.wasm --out-dir pkg --web 11 | # after change of workspace -> new location... 12 | wasm-bindgen ../../target/wasm32-unknown-unknown/release/web.wasm --out-dir pkg --web -------------------------------------------------------------------------------- /examples/pure/modal/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pure_modal" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../../..", default-features = false, features = [ 11 | "card", 12 | "colors", 13 | "modal", 14 | "pure" 15 | ] } 16 | 17 | [dependencies.iced] 18 | #git = "https://github.com/iced-rs/iced.git" 19 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 20 | version = "0.4.2" 21 | features = ["pure"] -------------------------------------------------------------------------------- /examples/pure/time_picker/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pure_time_picker" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../../..", default-features = false, features = [ 11 | "colors", 12 | "time_picker", 13 | "pure" 14 | ] } 15 | 16 | [dependencies.iced] 17 | #git = "https://github.com/iced-rs/iced.git" 18 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 19 | version = "0.4.2" 20 | features = [ "pure" ] -------------------------------------------------------------------------------- /src/graphics/floating_button.rs: -------------------------------------------------------------------------------- 1 | //! Use a floating button to overlay a button over some content 2 | //! 3 | //! *This API requires the following crate features to be activated: `floating_button`* 4 | use iced_graphics::Renderer; 5 | 6 | use crate::native::floating_button; 7 | pub use floating_button::{Anchor, Offset}; 8 | 9 | /// A floating button floating over some content. 10 | /// 11 | /// This is an alias of an `iced_native` `FloatingButton` with an `iced_wgpu::Renderer`. 12 | pub type FloatingButton<'a, B, Message, Backend> = 13 | floating_button::FloatingButton<'a, B, Message, Renderer>; 14 | -------------------------------------------------------------------------------- /examples/pure/color_picker/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pure_color_picker" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../../..", default-features = false, features = [ 11 | "color_picker", 12 | "colors", 13 | "pure", 14 | ] } 15 | 16 | [dependencies.iced] 17 | #git = "https://github.com/iced-rs/iced.git" 18 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 19 | version = "0.4.2" 20 | features = ["pure"] -------------------------------------------------------------------------------- /examples/pure/date_picker/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pure_date_picker" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | iced_aw = { path = "../../..", default-features = false, features = [ 10 | "date_picker", 11 | "colors", 12 | "pure", 13 | ] } 14 | 15 | [dependencies.iced] 16 | #git = "https://github.com/iced-rs/iced.git" 17 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 18 | version = "0.4.2" 19 | features = [ "pure" ] 20 | -------------------------------------------------------------------------------- /src/graphics/number_input.rs: -------------------------------------------------------------------------------- 1 | //! Display fields that can only be filled with numeric type. 2 | //! 3 | //! A [`NumberInput`] has some local [`State`]. 4 | use iced_graphics::Renderer; 5 | 6 | use crate::native::number_input; 7 | pub use crate::native::number_input::State; 8 | pub use crate::style::number_input::{Style, StyleSheet}; 9 | 10 | /// A field that can only be filled with numeric type. 11 | /// 12 | /// This is an alias of an `iced_native` number input with an `iced_wgpu::Renderer`. 13 | pub type NumberInput<'a, T, Message, Backend> = 14 | number_input::NumberInput<'a, T, Message, Renderer>; 15 | -------------------------------------------------------------------------------- /examples/pure/wrap/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pure_wrap" 3 | version = "0.1.0" 4 | authors = ["Downtime "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../../..", default-features = false, features = [ 11 | "wrap", 12 | "number_input", 13 | "pure" 14 | ] } 15 | rand = "0.8" 16 | 17 | [dependencies.iced] 18 | #git = "https://github.com/iced-rs/iced.git" 19 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 20 | version = "0.4.2" 21 | features = ["pure"] 22 | -------------------------------------------------------------------------------- /examples/pure/number_input/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pure_number_input" 3 | version = "0.1.0" 4 | authors = ["leang27 <52003343+leang27@users.noreply.github.com>"] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../../..", default-features = false, features = [ 11 | "number_input", 12 | "icons", 13 | "pure", 14 | ] } 15 | 16 | [dependencies.iced] 17 | #git = "https://github.com/iced-rs/iced.git" 18 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 19 | version = "0.4.2" 20 | features = ["pure"] -------------------------------------------------------------------------------- /src/core/mod.rs: -------------------------------------------------------------------------------- 1 | //! A module fitting `iced_core`. 2 | 3 | #[cfg(feature = "date_picker")] 4 | //#[cfg(all(feature = "date_picker", not(target_arch = "wasm32")))] 5 | pub mod date; 6 | 7 | #[cfg(all(feature = "time_picker", not(target_arch = "wasm32")))] 8 | pub mod clock; 9 | 10 | #[cfg(all(feature = "color_picker", not(target_arch = "wasm32")))] 11 | pub mod color; 12 | 13 | #[cfg(not(target_arch = "wasm32"))] 14 | pub mod overlay; 15 | 16 | #[cfg(not(target_arch = "wasm32"))] 17 | pub mod renderer; 18 | 19 | #[cfg(feature = "time_picker")] 20 | //#[cfg(all(feature = "time_picker", not(target_arch = "wasm32")))] 21 | pub mod time; 22 | -------------------------------------------------------------------------------- /examples/pure/floating_element/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pure_floating_button" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../../..", default-features = false, features = [ 11 | "floating_element", 12 | "colors", 13 | "icons", 14 | "pure", 15 | ] } 16 | 17 | [dependencies.iced] 18 | #git = "https://github.com/iced-rs/iced.git" 19 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 20 | version = "0.4.2" 21 | features = [ "pure" ] -------------------------------------------------------------------------------- /examples/web/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "web" 3 | version = "0.1.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | iced_aw = { path = "../..", default-features = false, features = [ 11 | "badge", 12 | "card", 13 | "color_picker", 14 | "colors", 15 | "date_picker", 16 | "floating_button", 17 | "modal", 18 | "time_picker", 19 | ] } 20 | 21 | [dependencies.iced] 22 | #git = "https://github.com/iced-rs/iced.git" 23 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 24 | version = "0.4.2" 25 | -------------------------------------------------------------------------------- /src/graphics/split.rs: -------------------------------------------------------------------------------- 1 | //! Use a split to split the available space in two parts to display two different elements. 2 | //! 3 | //! *This API requires the following crate features to be activated: split* 4 | use iced_graphics::Renderer; 5 | 6 | use crate::native::split; 7 | pub use crate::native::split::{Axis, State}; 8 | pub use crate::style::split::{Style, StyleSheet}; 9 | 10 | /// A split can divide the available space by half to display two different elements. 11 | /// It can split horizontally or vertically. 12 | /// 13 | /// This is an alias of an `iced_native` Split with an `iced_wgpu::Renderer`. 14 | pub type Split<'a, Message, Backend> = split::Split<'a, Message, Renderer>; 15 | -------------------------------------------------------------------------------- /src/graphics/tab_bar.rs: -------------------------------------------------------------------------------- 1 | //! Displays a [`TabBar`](TabBar) to select the content to be displayed. 2 | //! 3 | //! You have to manage the logic to show the contend by yourself or you may want 4 | //! to use the [`Tabs`](super::tabs) widget instead. 5 | //! 6 | //! *This API requires the following crate features to be activated: `tab_bar`* 7 | use crate::native::tab_bar; 8 | pub use crate::style::tab_bar::{Style, StyleSheet}; 9 | use iced_graphics::Renderer; 10 | pub use tab_bar::tab_label::TabLabel; 11 | 12 | /// A tab bar to show tabs. 13 | /// 14 | /// This is an alias of an `iced_native` `TabBar` with an `iced_wgpu::Renderer`. 15 | pub type TabBar = tab_bar::TabBar>; 16 | -------------------------------------------------------------------------------- /src/core/renderer.rs: -------------------------------------------------------------------------------- 1 | //! Helper struct for drawing 2 | 3 | use iced_native::{Layout, Point, Rectangle}; 4 | 5 | /// Collection of all necessary data to draw a widget. 6 | #[derive(Debug)] 7 | pub struct DrawEnvironment<'a, Defaults, Style, Focus> { 8 | /// The defaults of the renderer. 9 | pub defaults: &'a Defaults, 10 | /// The layout of the widget. 11 | pub layout: Layout<'a>, 12 | /// The position of the cursor. 13 | pub cursor_position: Point, 14 | /// The style of the widget. 15 | pub style_sheet: &'a Style, 16 | /// The viewport of the renderer. 17 | pub viewport: Option<&'a Rectangle>, 18 | /// The focus to an input element on the widget. 19 | pub focus: Focus, 20 | } 21 | -------------------------------------------------------------------------------- /src/native/tab_bar/tab_label.rs: -------------------------------------------------------------------------------- 1 | //! A [`TabLabel`](TabLabel) showing an icon and/or a text on a tab. 2 | //! 3 | //! *This API requires the following crate features to be activated: `tab_bar`* 4 | 5 | /// A [`TabLabel`](TabLabel) showing an icon and/or a text on a tab 6 | /// on a [`TabBar`](super::TabBar). 7 | #[allow(missing_debug_implementations)] 8 | #[derive(Clone, Hash)] 9 | pub enum TabLabel { 10 | /// A [`TabLabel`](TabLabel) showing only an icon on the tab. 11 | Icon(char), 12 | 13 | /// A [`TabLabel`](TabLabel) showing only a text on the tab. 14 | Text(String), 15 | 16 | /// A [`TabLabel`](TabLabel) showing an icon and a text on the tab. 17 | IconText(char, String), 18 | // TODO: Support any element as a label. 19 | } 20 | -------------------------------------------------------------------------------- /src/native/tabs/tab_bar_position.rs: -------------------------------------------------------------------------------- 1 | //! A [`TabBarPosition`](TabBarPosition) for defining the position of a 2 | //! [`TabBar`](crate::native::tab_bar::TabBar). 3 | //! 4 | //! *This API requires the following crate features to be activated: tabs* 5 | 6 | /// A [`TabBarPosition`](TabBarPosition) for defining the position of a 7 | /// [`TabBar`](crate::native::tab_bar::TabBar). 8 | #[derive(Clone, Hash)] 9 | #[allow(missing_debug_implementations)] 10 | pub enum TabBarPosition { 11 | /// A [`TabBarPosition`] for placing the 12 | /// [`TabBar`](crate::native::tab_bar::TabBar) on top of its content. 13 | Top, 14 | 15 | /// A [`TabBarPosition`] for placing the 16 | /// [`TabBar`](crate::native::tab_bar::TabBar) on bottom of its content. 17 | Bottom, 18 | } 19 | -------------------------------------------------------------------------------- /src/native/overlay/mod.rs: -------------------------------------------------------------------------------- 1 | //! Display interactive elements on top of other widgets. 2 | 3 | #[cfg(feature = "color_picker")] 4 | pub mod color_picker; 5 | #[cfg(feature = "color_picker")] 6 | pub use color_picker::ColorPickerOverlay; 7 | 8 | #[cfg(feature = "date_picker")] 9 | pub mod date_picker; 10 | #[cfg(feature = "date_picker")] 11 | pub use date_picker::DatePickerOverlay; 12 | 13 | #[cfg(feature = "floating_button")] 14 | pub mod floating_button; 15 | #[cfg(feature = "floating_button")] 16 | pub use floating_button::FloatingButtonOverlay; 17 | 18 | #[cfg(feature = "modal")] 19 | pub mod modal; 20 | #[cfg(feature = "modal")] 21 | pub use modal::ModalOverlay; 22 | 23 | #[cfg(feature = "time_picker")] 24 | pub mod time_picker; 25 | #[cfg(feature = "time_picker")] 26 | pub use time_picker::TimePickerOverlay; 27 | -------------------------------------------------------------------------------- /src/style/mod.rs: -------------------------------------------------------------------------------- 1 | //! The appearance of the widgets 2 | 3 | pub mod style_state; 4 | 5 | #[cfg(feature = "colors")] 6 | pub mod colors; 7 | 8 | #[cfg(feature = "badge")] 9 | pub mod badge; 10 | 11 | #[cfg(feature = "button")] 12 | pub mod button; 13 | 14 | #[cfg(feature = "card")] 15 | pub mod card; 16 | 17 | #[cfg(feature = "color_picker")] 18 | pub mod color_picker; 19 | 20 | #[cfg(feature = "date_picker")] 21 | pub mod date_picker; 22 | 23 | #[cfg(feature = "modal")] 24 | pub mod modal; 25 | 26 | #[cfg(feature = "tab_bar")] 27 | pub mod tab_bar; 28 | 29 | #[cfg(feature = "time_picker")] 30 | pub mod time_picker; 31 | 32 | #[cfg(feature = "number_input")] 33 | pub mod number_input; 34 | 35 | #[cfg(feature = "selection_list")] 36 | pub mod selection_list; 37 | 38 | #[cfg(feature = "split")] 39 | pub mod split; 40 | -------------------------------------------------------------------------------- /src/pure/overlay/mod.rs: -------------------------------------------------------------------------------- 1 | //! Display interactive elements on top of other widgets. 2 | 3 | #[cfg(feature = "color_picker")] 4 | pub mod color_picker; 5 | #[cfg(feature = "color_picker")] 6 | pub use color_picker::ColorPickerOverlay; 7 | 8 | #[cfg(feature = "date_picker")] 9 | pub mod date_picker; 10 | #[cfg(feature = "date_picker")] 11 | pub use date_picker::DatePickerOverlay; 12 | 13 | #[cfg(feature = "floating_element")] 14 | pub mod floating_element; 15 | #[cfg(feature = "floating_element")] 16 | pub use floating_element::FloatingElementOverlay; 17 | 18 | #[cfg(feature = "modal")] 19 | pub mod modal; 20 | #[cfg(feature = "modal")] 21 | pub use modal::ModalOverlay; 22 | 23 | #[cfg(feature = "time_picker")] 24 | pub mod time_picker; 25 | #[cfg(feature = "time_picker")] 26 | pub use time_picker::{State, TimePickerOverlay}; 27 | -------------------------------------------------------------------------------- /src/graphics/tabs.rs: -------------------------------------------------------------------------------- 1 | //! Displays a [`Tabs`](Tabs) widget to select the content to be displayed. 2 | //! 3 | //! This is a wrapper around the [`TabBar`](super::tab_bar::TabBar) widget. 4 | //! Unlike the [`TabBar`](super::tab_bar::TabBar) widget it will also handle 5 | //! the content of the tabs. 6 | //! 7 | //! *This API requires the following crate features to be activated: tabs* 8 | use crate::native::tabs; 9 | pub use crate::style::tab_bar::{Style, StyleSheet}; 10 | use iced_graphics::Renderer; 11 | pub use tabs::tab_bar_position::TabBarPosition; 12 | 13 | /// A [`Tabs`](Tabs) widget for showing a [`TabBar`](super::tab_bar::TabBar) 14 | /// along with the tab's content. 15 | /// 16 | /// This is an alias of an `iced_native` Tabs widget with an 17 | /// `iced_wgpu::Renderer`. 18 | pub type Tabs<'a, Message, Backend> = tabs::Tabs<'a, Message, Renderer>; 19 | -------------------------------------------------------------------------------- /src/graphics/icons/required.rs: -------------------------------------------------------------------------------- 1 | //! Bootstrap icons. 2 | //! Machine generated code. Do not change! 3 | 4 | /// Bootstrap icons 5 | #[derive(Copy, Clone, Debug, Hash)] 6 | pub enum Icon { 7 | /// caret-down-fill 8 | CaretDownFill, 9 | /// caret-left-fill 10 | CaretLeftFill, 11 | /// caret-right-fill 12 | CaretRightFill, 13 | /// caret-up-fill 14 | CaretUpFill, 15 | /// check 16 | Check, 17 | /// x 18 | X, 19 | } 20 | 21 | /// Converts an icon into a char. 22 | #[must_use] 23 | pub const fn icon_to_char(icon: Icon) -> char { 24 | match icon { 25 | Icon::CaretDownFill => '\u{f217}', 26 | Icon::CaretLeftFill => '\u{f21b}', 27 | Icon::CaretRightFill => '\u{f21f}', 28 | Icon::CaretUpFill => '\u{f223}', 29 | Icon::Check => '\u{f25c}', 30 | Icon::X => '\u{f5ae}', 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/web/src/modal_section.rs: -------------------------------------------------------------------------------- 1 | use crate::Section; 2 | use iced::{button, Alignment, Button, Column, Element, Length, Text}; 3 | 4 | pub struct ModalSection { 5 | open_button: button::State, 6 | } 7 | 8 | impl Section for ModalSection { 9 | type Message = crate::Message; 10 | 11 | fn new() -> Self { 12 | Self { 13 | open_button: button::State::new(), 14 | } 15 | } 16 | 17 | fn header(&self) -> String { 18 | String::from("Modal") 19 | } 20 | 21 | fn content(&mut self) -> Element<'_, Self::Message> { 22 | Column::new() 23 | .align_items(Alignment::Center) 24 | .width(Length::Fill) 25 | .push( 26 | Button::new(&mut self.open_button, Text::new("Open modal!")) 27 | .on_press(crate::Message::OpenPrimaryModal), 28 | ) 29 | .into() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/tabs/fonts/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "icons", 3 | "css_prefix_text": "icon-", 4 | "css_use_suffix": false, 5 | "hinting": true, 6 | "units_per_em": 1000, 7 | "ascent": 850, 8 | "glyphs": [ 9 | { 10 | "uid": "8b80d36d4ef43889db10bc1f0dc9a862", 11 | "css": "user", 12 | "code": 59392, 13 | "src": "fontawesome" 14 | }, 15 | { 16 | "uid": "d73eceadda1f594cec0536087539afbf", 17 | "css": "heart", 18 | "code": 59393, 19 | "src": "fontawesome" 20 | }, 21 | { 22 | "uid": "1ee2aeb352153a403df4b441a8bc9bda", 23 | "css": "calc", 24 | "code": 61932, 25 | "src": "fontawesome" 26 | }, 27 | { 28 | "uid": "98687378abd1faf8f6af97c254eb6cd6", 29 | "css": "cog-alt", 30 | "code": 59394, 31 | "src": "fontawesome" 32 | }, 33 | { 34 | "uid": "5211af474d3a9848f67f945e2ccaf143", 35 | "css": "cancel", 36 | "code": 59395, 37 | "src": "fontawesome" 38 | } 39 | ] 40 | } -------------------------------------------------------------------------------- /examples/pure/tabs/fonts/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "icons", 3 | "css_prefix_text": "icon-", 4 | "css_use_suffix": false, 5 | "hinting": true, 6 | "units_per_em": 1000, 7 | "ascent": 850, 8 | "glyphs": [ 9 | { 10 | "uid": "8b80d36d4ef43889db10bc1f0dc9a862", 11 | "css": "user", 12 | "code": 59392, 13 | "src": "fontawesome" 14 | }, 15 | { 16 | "uid": "d73eceadda1f594cec0536087539afbf", 17 | "css": "heart", 18 | "code": 59393, 19 | "src": "fontawesome" 20 | }, 21 | { 22 | "uid": "1ee2aeb352153a403df4b441a8bc9bda", 23 | "css": "calc", 24 | "code": 61932, 25 | "src": "fontawesome" 26 | }, 27 | { 28 | "uid": "98687378abd1faf8f6af97c254eb6cd6", 29 | "css": "cog-alt", 30 | "code": 59394, 31 | "src": "fontawesome" 32 | }, 33 | { 34 | "uid": "5211af474d3a9848f67f945e2ccaf143", 35 | "css": "cancel", 36 | "code": 59395, 37 | "src": "fontawesome" 38 | } 39 | ] 40 | } -------------------------------------------------------------------------------- /.github/workflows/rustdoc.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Docs to GitHub Pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | release: 10 | name: GitHub Pages 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout Repository 15 | uses: actions/checkout@v1 16 | 17 | - name: Install Rust toolchain 18 | uses: actions-rs/toolchain@v1 19 | with: 20 | toolchain: nightly 21 | profile: minimal 22 | override: true 23 | components: rustfmt, rust-src 24 | - uses: Swatinem/rust-cache@v1 25 | - name: Build Documentation 26 | uses: actions-rs/cargo@v1 27 | with: 28 | command: doc 29 | args: --all --no-deps 30 | - name: Add index.html 31 | run: echo '' > target/doc/index.html 32 | - name: Deploy Documentation 33 | uses: peaceiris/actions-gh-pages@v3 34 | with: 35 | github_token: ${{ secrets.GITHUB_TOKEN }} 36 | publish_branch: gh-pages 37 | publish_dir: ./target/doc 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Kaiden42 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 | -------------------------------------------------------------------------------- /src/native/floating_button/anchor.rs: -------------------------------------------------------------------------------- 1 | //! Use a floating button to overlay a button over some content 2 | //! 3 | //! *This API requires the following crate features to be activated: `floating_button`* 4 | 5 | /// Positional [`Anchor`](Anchor) for the [`FloatingButton`](super::FloatingButton). 6 | #[derive(Copy, Clone, Debug, Hash)] 7 | pub enum Anchor { 8 | /// NortWest [`Anchor`](Anchor) for positioning the 9 | /// [`Button`](iced_native::widget::button::Button) on the top left of the 10 | /// underlying element. 11 | NorthWest, 12 | 13 | /// NorthEast [`Anchor`](Anchor) for positioning the 14 | /// [`Button`](iced_native::widget::button::Button) on the top right of the 15 | /// underlying element. 16 | NorthEast, 17 | 18 | /// SouthWest [`Anchor`](Anchor) for positioning the 19 | /// [`Button`](iced_native::widget::button::Button) on the bottom left of the 20 | /// underlying element. 21 | SouthWest, 22 | 23 | /// SouthEast [`Anchor`](Anchor) for positioning the 24 | /// [`Button`](iced_native::widget::button::Button) on the bottom right of the 25 | /// underlying element. 26 | SouthEast, 27 | } 28 | -------------------------------------------------------------------------------- /src/native/floating_button/offset.rs: -------------------------------------------------------------------------------- 1 | //! Use a floating button to overlay a button over some content 2 | //! 3 | //! *This API requires the following crate features to be activated: `floating_button`* 4 | 5 | use iced_native::Point; 6 | 7 | /// The [`Offset`](Offset) for the [`FloatingButton`](super::FloatingButton). 8 | #[derive(Copy, Clone, Debug)] 9 | pub struct Offset { 10 | /// Offset on the x-axis from the [`Anchor`](super::Anchor) 11 | pub x: f32, 12 | /// Offset on the y-axis from the [`Anchor`](super::Anchor) 13 | pub y: f32, 14 | } 15 | 16 | impl From for Offset { 17 | fn from(float: f32) -> Self { 18 | Self { x: float, y: float } 19 | } 20 | } 21 | 22 | impl From<[f32; 2]> for Offset { 23 | fn from(array: [f32; 2]) -> Self { 24 | Self { 25 | x: array[0], 26 | y: array[1], 27 | } 28 | } 29 | } 30 | 31 | impl From for Point { 32 | fn from(offset: Offset) -> Self { 33 | Self::new(offset.x, offset.y) 34 | } 35 | } 36 | 37 | impl From<&Offset> for Point { 38 | fn from(offset: &Offset) -> Self { 39 | Self::new(offset.x, offset.y) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/graphics/icons.rs: -------------------------------------------------------------------------------- 1 | //! The default icon font of the widgets of this library. 2 | use iced_graphics::Font; 3 | 4 | #[cfg(feature = "icons")] 5 | mod bootstrap; 6 | #[cfg(feature = "icons")] 7 | pub use bootstrap::*; 8 | 9 | #[cfg(not(feature = "icons"))] 10 | mod required; 11 | #[cfg(not(feature = "icons"))] 12 | pub use required::*; 13 | 14 | /// The default icon font. 15 | #[cfg(feature = "icons")] 16 | pub const ICON_FONT: Font = iced_native::Font::External { 17 | name: "Icons", 18 | bytes: include_bytes!("./fonts/bootstrap-icons.ttf"), 19 | }; 20 | 21 | /// The default icon font. 22 | #[cfg(not(feature = "icons"))] 23 | pub const ICON_FONT: Font = iced_native::Font::External { 24 | name: "Icons", 25 | bytes: include_bytes!("./fonts/required-icons.ttf"), 26 | }; 27 | 28 | impl From for char { 29 | fn from(icon: Icon) -> Self { 30 | icon_to_char(icon) 31 | } 32 | } 33 | 34 | impl From for String { 35 | fn from(icon: Icon) -> Self { 36 | format!("{}", icon_to_char(icon)) 37 | } 38 | } 39 | 40 | impl std::fmt::Display for Icon { 41 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 42 | write!(f, "{}", icon_to_char(*self)) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/core/overlay.rs: -------------------------------------------------------------------------------- 1 | //! Helper functions for overlays 2 | use iced_native::{Point, Size}; 3 | 4 | /// Trait containing functions for positioning of nodes. 5 | pub trait Position { 6 | /// Centers this node around the given position. If the node is over the 7 | /// specified bounds it's bouncing back to be fully visible on screen. 8 | fn center_and_bounce(&mut self, position: Point, bounds: Size); 9 | } 10 | 11 | impl Position for iced_native::layout::Node { 12 | fn center_and_bounce(&mut self, position: Point, bounds: Size) { 13 | self.move_to(Point::new( 14 | (position.x - self.size().width / 2.0).max(0.0), 15 | (position.y - self.size().height / 2.0).max(0.0), 16 | )); 17 | 18 | self.move_to(Point::new( 19 | if self.bounds().x + self.bounds().width > bounds.width { 20 | (self.bounds().x - (self.bounds().width - (bounds.width - self.bounds().x))) 21 | .max(0.0) 22 | } else { 23 | self.bounds().x 24 | }, 25 | if self.bounds().y + self.bounds().height > bounds.height { 26 | (self.bounds().y - (self.bounds().height - (bounds.height - self.bounds().y))) 27 | .max(0.0) 28 | } else { 29 | self.bounds().y 30 | }, 31 | )); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/split/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{Container, Length, Sandbox, Settings, Text}; 2 | use iced_aw::{split, Split}; 3 | 4 | fn main() -> iced::Result { 5 | SplitPaneExample::run(Settings::default()) 6 | } 7 | 8 | #[derive(Debug, Clone)] 9 | enum Message { 10 | OnResize(u16), 11 | } 12 | 13 | struct SplitPaneExample { 14 | split_pane: split::State, 15 | } 16 | 17 | impl Sandbox for SplitPaneExample { 18 | type Message = Message; 19 | 20 | fn new() -> Self { 21 | SplitPaneExample { 22 | split_pane: split::State::new(None, split::Axis::Vertical), 23 | } 24 | } 25 | 26 | fn title(&self) -> String { 27 | String::from("Split example") 28 | } 29 | 30 | fn update(&mut self, message: Self::Message) { 31 | match message { 32 | Message::OnResize(position) => self.split_pane.set_divider_position(position), 33 | } 34 | } 35 | 36 | fn view(&mut self) -> iced::Element { 37 | let first = Container::new(Text::new("First")) 38 | .width(Length::Fill) 39 | .height(Length::Fill) 40 | .center_x() 41 | .center_y(); 42 | 43 | let second = Container::new(Text::new("Second")) 44 | .width(Length::Fill) 45 | .height(Length::Fill) 46 | .center_x() 47 | .center_y(); 48 | 49 | Split::new(&mut self.split_pane, first, second, Message::OnResize).into() 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/style/modal.rs: -------------------------------------------------------------------------------- 1 | //! Use a badge for color highlighting important information. 2 | //! 3 | //! *This API requires the following crate features to be activated: badge* 4 | 5 | #[cfg(not(target_arch = "wasm32"))] 6 | use iced_native::Background; 7 | 8 | /// The appearance of a [`Modal`](crate::native::Modal). 9 | #[derive(Clone, Copy, Debug)] 10 | pub struct Style { 11 | /// The backgronud of the [`Modal`](crate::native::Modal). 12 | /// 13 | /// This is used to color the backdrop of the modal. 14 | pub background: Background, 15 | } 16 | 17 | /// The appearance of a [`Modal`](crate::native::Modal). 18 | pub trait StyleSheet { 19 | /// The normal appearance of a [`Modal`](crate::native::Modal). 20 | fn active(&self) -> Style; 21 | } 22 | 23 | /// The default appearance of a [`Modal`](crate::native::Modal). 24 | #[derive(Clone, Copy, Debug)] 25 | pub struct Default; 26 | 27 | impl StyleSheet for Default { 28 | fn active(&self) -> Style { 29 | Style { 30 | background: Background::Color([0.87, 0.87, 0.87, 0.30].into()), 31 | } 32 | } 33 | } 34 | 35 | #[allow(clippy::use_self)] 36 | impl std::default::Default for Box { 37 | fn default() -> Self { 38 | Box::new(Default) 39 | } 40 | } 41 | 42 | #[allow(clippy::use_self)] 43 | impl From for Box 44 | where 45 | T: 'static + StyleSheet, 46 | { 47 | fn from(style: T) -> Self { 48 | Box::new(style) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /examples/tabs_min/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{Column, Element, Sandbox, Settings, Text}; 2 | use iced_aw::{Tabs, TabLabel}; 3 | 4 | fn main() -> iced::Result { 5 | TabBarExample::run(Settings::default()) 6 | } 7 | 8 | #[derive(Debug, Clone, Copy)] 9 | enum Message { 10 | TabSelected(usize), 11 | } 12 | 13 | struct TabBarExample { 14 | active_tab: usize, 15 | } 16 | 17 | impl Sandbox for TabBarExample { 18 | 19 | type Message = Message; 20 | 21 | fn new() -> Self { 22 | TabBarExample { 23 | active_tab: 0, 24 | } 25 | } 26 | 27 | fn title(&self) -> String { 28 | String::from("TabBar example") 29 | } 30 | 31 | fn update(&mut self, message: Self::Message) { 32 | match message { 33 | Message::TabSelected(index) => { 34 | self.active_tab = index 35 | }, 36 | } 37 | } 38 | 39 | fn view(&mut self) -> Element<'_, Self::Message> { 40 | //Tabs::new(self.active_tab, Message::TabSelected) 41 | // TODO: Fix error 42 | /*.push( 43 | TabLabel::Text(String::from("One")), 44 | Text::new("This is tab one") 45 | ) 46 | .push( 47 | TabLabel::Text(String::from("Two")), 48 | Text::new("This is tab two") 49 | ) 50 | .push( 51 | TabLabel::Text(String::from("Three")), 52 | Text::new("This is tab three") 53 | )*/ 54 | //.into() 55 | todo!() 56 | } 57 | } -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: [push, pull_request] 3 | jobs: 4 | todo_linux: 5 | name: Ubuntu Checks 6 | runs-on: ubuntu-latest 7 | strategy: 8 | matrix: 9 | rust: [stable, beta] 10 | steps: 11 | - uses: hecrj/setup-rust-action@v1 12 | with: 13 | rust-version: ${{ matrix.rust }} 14 | - uses: actions/checkout@master 15 | - name: Install dependencies 16 | run: | 17 | export DEBIAN_FRONTED=noninteractive 18 | sudo apt-get -qq update 19 | sudo apt-get install -y libxkbcommon-dev 20 | - name: Run tests 21 | run: | 22 | cargo test --verbose --all 23 | cargo test --verbose --all --all-features 24 | 25 | todo_windows: 26 | name: Windows Checks 27 | runs-on: windows-latest 28 | strategy: 29 | matrix: 30 | rust: [stable, beta] 31 | steps: 32 | - uses: hecrj/setup-rust-action@v1 33 | with: 34 | rust-version: ${{ matrix.rust }} 35 | - uses: actions/checkout@master 36 | - name: Run tests 37 | run: | 38 | cargo test --verbose --all 39 | cargo test --verbose --all --all-features 40 | 41 | todo_macos: 42 | name: Mac OS Checks 43 | runs-on: macos-latest 44 | strategy: 45 | matrix: 46 | rust: [stable, beta] 47 | steps: 48 | - uses: hecrj/setup-rust-action@v1 49 | with: 50 | rust-version: ${{ matrix.rust }} 51 | - uses: actions/checkout@master 52 | - name: Run tests 53 | run: | 54 | cargo test --verbose --all 55 | cargo test --verbose --all --all-features 56 | -------------------------------------------------------------------------------- /examples/pure/split/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | pure::{ 3 | widget::{Container, Text}, 4 | Element, Sandbox, 5 | }, 6 | Length, Settings, 7 | }; 8 | use iced_aw::pure::{split, Split}; 9 | 10 | fn main() -> iced::Result { 11 | SplitPaneExample::run(Settings::default()) 12 | } 13 | 14 | #[derive(Debug, Clone)] 15 | enum Message { 16 | OnResize(u16), 17 | } 18 | 19 | struct SplitPaneExample { 20 | divider_position: Option, 21 | } 22 | 23 | impl Sandbox for SplitPaneExample { 24 | type Message = Message; 25 | 26 | fn new() -> Self { 27 | SplitPaneExample { 28 | divider_position: None, 29 | } 30 | } 31 | 32 | fn title(&self) -> String { 33 | String::from("Split example") 34 | } 35 | 36 | fn update(&mut self, message: Self::Message) { 37 | match message { 38 | Message::OnResize(position) => self.divider_position = Some(position), 39 | } 40 | } 41 | 42 | fn view(&self) -> Element { 43 | let first = Container::new(Text::new("First")) 44 | .width(Length::Fill) 45 | .height(Length::Fill) 46 | .center_x() 47 | .center_y(); 48 | 49 | let second = Container::new(Text::new("Second")) 50 | .width(Length::Fill) 51 | .height(Length::Fill) 52 | .center_x() 53 | .center_y(); 54 | 55 | Split::new( 56 | first, 57 | second, 58 | self.divider_position, 59 | split::Axis::Vertical, 60 | Message::OnResize, 61 | ) 62 | .into() 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /examples/web/src/card_section.rs: -------------------------------------------------------------------------------- 1 | use crate::Section; 2 | use iced::{Element, Row, Text}; 3 | use iced_aw::Card; 4 | 5 | pub struct CardSection { 6 | primary_card: bool, 7 | secondary_card: bool, 8 | } 9 | 10 | #[derive(Clone, Debug)] 11 | pub enum Message { 12 | PrimaryCardClose, 13 | SecondaryCardClose, 14 | } 15 | 16 | impl Section for CardSection { 17 | type Message = Message; 18 | 19 | fn new() -> Self { 20 | Self { 21 | primary_card: true, 22 | secondary_card: true, 23 | } 24 | } 25 | 26 | fn header(&self) -> String { 27 | String::from("Card") 28 | } 29 | 30 | fn update(&mut self, message: Self::Message) { 31 | match message { 32 | Message::PrimaryCardClose => self.primary_card = false, 33 | Message::SecondaryCardClose => self.secondary_card = false, 34 | } 35 | } 36 | 37 | fn content(&mut self) -> Element<'_, Self::Message> { 38 | let mut row = Row::new().spacing(20); 39 | 40 | if self.primary_card { 41 | row = row.push( 42 | Card::new(Text::new("Primary"), Text::new("Primary text")) 43 | .on_close(Message::PrimaryCardClose) 44 | .style(iced_aw::style::card::Primary), 45 | ); 46 | } 47 | 48 | if self.secondary_card { 49 | row = row.push( 50 | Card::new(Text::new("Secondary"), Text::new("Secondary text")) 51 | .on_close(Message::SecondaryCardClose) 52 | .style(iced_aw::style::card::Secondary), 53 | ); 54 | } 55 | 56 | row.into() 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /examples/web/src/badge_section.rs: -------------------------------------------------------------------------------- 1 | use crate::Section; 2 | use iced::{Alignment, Column, Element, Row, Text}; 3 | use iced_aw::Badge; 4 | 5 | pub struct BadgeSection; 6 | 7 | impl Section for BadgeSection { 8 | type Message = crate::Message; 9 | 10 | fn new() -> Self { 11 | Self {} 12 | } 13 | 14 | fn header(&self) -> String { 15 | String::from("Badge") 16 | } 17 | 18 | fn content(&mut self) -> Element<'_, Self::Message> { 19 | Column::new() 20 | .spacing(10) 21 | .push( 22 | Row::new() 23 | .align_items(Alignment::Center) 24 | .spacing(10) 25 | .push(Badge::new(Text::new("Default")).style(iced_aw::style::badge::Default)) 26 | .push(Badge::new(Text::new("Primary")).style(iced_aw::style::badge::Primary)) 27 | .push( 28 | Badge::new(Text::new("Secondary")).style(iced_aw::style::badge::Secondary), 29 | ) 30 | .push(Badge::new(Text::new("Success")).style(iced_aw::style::badge::Success)) 31 | .push(Badge::new(Text::new("Danger")).style(iced_aw::style::badge::Danger)), 32 | ) 33 | .push( 34 | Row::new() 35 | .spacing(10) 36 | .align_items(Alignment::Center) 37 | .push(Badge::new(Text::new("Warning")).style(iced_aw::style::badge::Warning)) 38 | .push(Badge::new(Text::new("Info")).style(iced_aw::style::badge::Info)) 39 | .push(Badge::new(Text::new("Dark")).style(iced_aw::style::badge::Dark)) 40 | .push(Badge::new(Text::new("Light")).style(iced_aw::style::badge::Light)) 41 | .push(Badge::new(Text::new("White")).style(iced_aw::style::badge::White)), 42 | ) 43 | .into() 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /examples/pure/tabs/src/counter.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | pure::{ 3 | widget::{Button, Column, Container, Row, Text}, 4 | Element, 5 | }, 6 | Alignment, 7 | }; 8 | use iced_aw::pure::tab_bar::TabLabel; 9 | 10 | use crate::{Icon, Message, Tab}; 11 | 12 | #[derive(Debug, Clone)] 13 | pub enum CounterMessage { 14 | Increase, 15 | Decrease, 16 | } 17 | 18 | pub struct CounterTab { 19 | value: i32, 20 | } 21 | 22 | impl CounterTab { 23 | pub fn new() -> Self { 24 | CounterTab { value: 0 } 25 | } 26 | 27 | pub fn update(&mut self, message: CounterMessage) { 28 | match message { 29 | CounterMessage::Increase => self.value += 1, 30 | CounterMessage::Decrease => self.value -= 1, 31 | } 32 | } 33 | } 34 | 35 | impl Tab for CounterTab { 36 | type Message = Message; 37 | 38 | fn title(&self) -> String { 39 | String::from("Counter") 40 | } 41 | 42 | fn tab_label(&self) -> TabLabel { 43 | //TabLabel::Text(self.title()) 44 | TabLabel::IconText(Icon::Calc.into(), self.title()) 45 | } 46 | 47 | fn content(&self) -> Element<'_, Self::Message> { 48 | let content: Element<'_, CounterMessage> = Container::new( 49 | Column::new() 50 | .align_items(Alignment::Center) 51 | .max_width(600) 52 | .padding(20) 53 | .spacing(16) 54 | .push(Text::new(format!("Count: {}", self.value)).size(32)) 55 | .push( 56 | Row::new() 57 | .spacing(10) 58 | .push(Button::new(Text::new("Decrease")).on_press(CounterMessage::Decrease)) 59 | .push( 60 | Button::new(Text::new("Increase")).on_press(CounterMessage::Increase), 61 | ), 62 | ), 63 | ) 64 | .into(); 65 | 66 | content.map(Message::Counter) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/native/mod.rs: -------------------------------------------------------------------------------- 1 | //! A module fitting `iced_native`. 2 | 3 | pub mod overlay; 4 | 5 | #[cfg(feature = "badge")] 6 | pub mod badge; 7 | #[cfg(feature = "badge")] 8 | pub use badge::Badge; 9 | 10 | #[cfg(feature = "card")] 11 | pub mod card; 12 | #[cfg(feature = "card")] 13 | pub use card::Card; 14 | 15 | #[cfg(feature = "color_picker")] 16 | pub mod color_picker; 17 | #[cfg(feature = "color_picker")] 18 | pub use color_picker::ColorPicker; 19 | 20 | #[cfg(feature = "date_picker")] 21 | pub mod date_picker; 22 | #[cfg(feature = "date_picker")] 23 | pub use date_picker::DatePicker; 24 | 25 | #[cfg(feature = "floating_button")] 26 | pub mod floating_button; 27 | #[cfg(feature = "floating_button")] 28 | pub use floating_button::FloatingButton; 29 | 30 | #[cfg(feature = "icon_text")] 31 | pub mod icon_text; 32 | #[cfg(feature = "icon_text")] 33 | pub use icon_text::IconText; 34 | 35 | #[cfg(feature = "grid")] 36 | pub mod grid; 37 | #[cfg(feature = "grid")] 38 | pub use grid::Grid; 39 | 40 | #[cfg(feature = "modal")] 41 | pub mod modal; 42 | #[cfg(feature = "modal")] 43 | pub use modal::Modal; 44 | 45 | #[cfg(feature = "tab_bar")] 46 | pub mod tab_bar; 47 | #[cfg(feature = "tab_bar")] 48 | pub use tab_bar::{TabBar, TabLabel}; 49 | 50 | #[cfg(feature = "tabs")] 51 | pub mod tabs; 52 | #[cfg(feature = "tabs")] 53 | pub use tabs::Tabs; 54 | 55 | #[cfg(feature = "time_picker")] 56 | pub mod time_picker; 57 | #[cfg(feature = "time_picker")] 58 | pub use time_picker::TimePicker; 59 | 60 | #[cfg(feature = "wrap")] 61 | pub mod wrap; 62 | #[cfg(feature = "wrap")] 63 | pub use wrap::Wrap; 64 | 65 | #[cfg(feature = "number_input")] 66 | pub mod number_input; 67 | #[cfg(feature = "number_input")] 68 | pub use number_input::NumberInput; 69 | 70 | #[cfg(feature = "selection_list")] 71 | pub mod selection_list; 72 | #[cfg(feature = "selection_list")] 73 | pub use selection_list::{List, SelectionList, State}; 74 | 75 | #[cfg(feature = "split")] 76 | pub mod split; 77 | #[cfg(feature = "split")] 78 | pub use split::Split; 79 | -------------------------------------------------------------------------------- /src/pure/mod.rs: -------------------------------------------------------------------------------- 1 | //! Stateless, pure widgets for iced 2 | 3 | pub mod overlay; 4 | 5 | #[cfg(feature = "badge")] 6 | pub mod badge; 7 | #[cfg(feature = "badge")] 8 | pub use badge::Badge; 9 | 10 | #[cfg(feature = "number_input")] 11 | pub mod number_input; 12 | #[cfg(feature = "number_input")] 13 | pub use number_input::NumberInput; 14 | 15 | #[cfg(feature = "card")] 16 | pub mod card; 17 | #[cfg(feature = "card")] 18 | pub use card::Card; 19 | 20 | #[cfg(feature = "color_picker")] 21 | pub mod color_picker; 22 | #[cfg(feature = "color_picker")] 23 | pub use color_picker::ColorPicker; 24 | 25 | #[cfg(feature = "date_picker")] 26 | pub mod date_picker; 27 | #[cfg(feature = "date_picker")] 28 | pub use date_picker::DatePicker; 29 | 30 | #[cfg(feature = "selection_list")] 31 | pub mod selection_list; 32 | #[cfg(feature = "selection_list")] 33 | pub use selection_list::{List, SelectionList}; 34 | 35 | #[cfg(feature = "floating_element")] 36 | pub mod floating_element; 37 | #[cfg(feature = "floating_element")] 38 | pub use floating_element::FloatingElement; 39 | 40 | #[cfg(feature = "grid")] 41 | pub mod grid; 42 | #[cfg(feature = "grid")] 43 | pub use grid::Grid; 44 | 45 | #[cfg(feature = "icon_text")] 46 | pub mod icon_text; 47 | #[cfg(feature = "icon_text")] 48 | pub use icon_text::IconText; 49 | 50 | #[cfg(feature = "modal")] 51 | pub mod modal; 52 | #[cfg(feature = "modal")] 53 | pub use modal::Modal; 54 | 55 | #[cfg(feature = "split")] 56 | pub mod split; 57 | #[cfg(feature = "split")] 58 | pub use split::Split; 59 | 60 | #[cfg(feature = "tab_bar")] 61 | pub mod tab_bar; 62 | #[cfg(feature = "tab_bar")] 63 | pub use tab_bar::{TabBar, TabLabel}; 64 | 65 | #[cfg(feature = "tabs")] 66 | pub mod tabs; 67 | #[cfg(feature = "tabs")] 68 | pub use tabs::{TabBarPosition, Tabs}; 69 | 70 | #[cfg(feature = "time_picker")] 71 | pub mod time_picker; 72 | #[cfg(feature = "time_picker")] 73 | pub use time_picker::TimePicker; 74 | 75 | #[cfg(feature = "wrap")] 76 | pub mod wrap; 77 | #[cfg(feature = "wrap")] 78 | pub use wrap::Wrap; 79 | -------------------------------------------------------------------------------- /src/graphics/mod.rs: -------------------------------------------------------------------------------- 1 | //! A module fitting `iced_graphics`. 2 | 3 | pub mod icons; 4 | 5 | #[cfg(feature = "badge")] 6 | pub mod badge; 7 | #[cfg(feature = "badge")] 8 | pub use badge::Badge; 9 | 10 | #[cfg(feature = "card")] 11 | pub mod card; 12 | #[cfg(feature = "card")] 13 | pub use card::Card; 14 | 15 | #[cfg(feature = "color_picker")] 16 | pub mod color_picker; 17 | #[cfg(feature = "color_picker")] 18 | pub use color_picker::ColorPicker; 19 | 20 | #[cfg(feature = "date_picker")] 21 | pub mod date_picker; 22 | #[cfg(feature = "date_picker")] 23 | pub use date_picker::DatePicker; 24 | 25 | #[cfg(feature = "floating_button")] 26 | pub mod floating_button; 27 | #[cfg(feature = "floating_button")] 28 | pub use floating_button::FloatingButton; 29 | 30 | #[cfg(feature = "grid")] 31 | pub mod grid; 32 | #[cfg(feature = "grid")] 33 | pub use grid::Grid; 34 | 35 | #[cfg(feature = "icon_text")] 36 | pub mod icon_text; 37 | #[cfg(feature = "icon_text")] 38 | pub use icon_text::IconText; 39 | 40 | #[cfg(feature = "modal")] 41 | pub mod modal; 42 | #[cfg(feature = "modal")] 43 | pub use modal::Modal; 44 | 45 | #[cfg(feature = "tab_bar")] 46 | pub mod tab_bar; 47 | #[cfg(feature = "tab_bar")] 48 | pub use tab_bar::TabBar; 49 | 50 | #[cfg(feature = "tabs")] 51 | pub mod tabs; 52 | #[doc(no_inline)] 53 | #[cfg(feature = "tabs")] 54 | pub use tabs::Tabs; 55 | 56 | #[cfg(feature = "time_picker")] 57 | pub mod time_picker; 58 | #[doc(no_inline)] 59 | #[cfg(feature = "time_picker")] 60 | pub use time_picker::TimePicker; 61 | 62 | #[cfg(feature = "wrap")] 63 | pub mod wrap; 64 | #[cfg(feature = "wrap")] 65 | pub use wrap::Wrap; 66 | 67 | #[cfg(feature = "number_input")] 68 | pub mod number_input; 69 | #[cfg(feature = "number_input")] 70 | pub use number_input::NumberInput; 71 | 72 | #[cfg(feature = "selection_list")] 73 | pub mod selection_list; 74 | #[cfg(feature = "selection_list")] 75 | pub use selection_list::SelectionList; 76 | 77 | #[cfg(feature = "split")] 78 | pub mod split; 79 | #[cfg(feature = "split")] 80 | pub use split::Split; 81 | -------------------------------------------------------------------------------- /examples/web/src/date_picker_section.rs: -------------------------------------------------------------------------------- 1 | use crate::Section; 2 | use iced::{button, Alignment, Button, Column, Element, Length, Row, Text}; 3 | use iced_aw::{ 4 | date_picker::{self, Date}, 5 | DatePicker, 6 | }; 7 | 8 | pub struct DatePickerSection { 9 | date_picker_state: date_picker::State, 10 | button_state: button::State, 11 | date: Date, 12 | } 13 | 14 | #[derive(Clone, Debug)] 15 | pub enum Message { 16 | OpenDatePicker, 17 | CancelDate, 18 | SubmitDate(Date), 19 | } 20 | 21 | impl Section for DatePickerSection { 22 | type Message = Message; 23 | 24 | fn new() -> Self { 25 | Self { 26 | date_picker_state: date_picker::State::now(), 27 | button_state: button::State::new(), 28 | date: Date::default(), 29 | } 30 | } 31 | 32 | fn header(&self) -> String { 33 | String::from("Date Picker") 34 | } 35 | 36 | fn update(&mut self, message: Self::Message) { 37 | match message { 38 | Message::OpenDatePicker => self.date_picker_state.show(true), 39 | Message::CancelDate => self.date_picker_state.show(false), 40 | Message::SubmitDate(date) => { 41 | self.date = date; 42 | self.date_picker_state.show(false); 43 | } 44 | } 45 | } 46 | 47 | fn content(&mut self) -> Element<'_, Self::Message> { 48 | let date_picker = DatePicker::new( 49 | &mut self.date_picker_state, 50 | Button::new(&mut self.button_state, Text::new("Pick Date")) 51 | .on_press(Message::OpenDatePicker), 52 | Message::CancelDate, 53 | Message::SubmitDate, 54 | ); 55 | 56 | let column = Column::new() 57 | .align_items(Alignment::Center) 58 | .width(Length::Fill) 59 | .push( 60 | Row::new() 61 | .width(Length::Shrink) 62 | .align_items(Alignment::Center) 63 | .spacing(20) 64 | .push(date_picker) 65 | .push(Text::new(format!("Picked date: {}", self.date))), 66 | ); 67 | 68 | column.into() 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /examples/web/src/color_picker_section.rs: -------------------------------------------------------------------------------- 1 | use crate::Section; 2 | use iced::{button, Alignment, Button, Color, Column, Element, Length, Row, Text}; 3 | use iced_aw::{color_picker, ColorPicker}; 4 | 5 | pub struct ColorPickerSection { 6 | color_picker_state: color_picker::State, 7 | button_state: button::State, 8 | color: Color, 9 | } 10 | 11 | #[derive(Clone, Debug)] 12 | pub enum Message { 13 | OpenColorPicker, 14 | CancelColor, 15 | SubmitColor(Color), 16 | } 17 | 18 | impl Section for ColorPickerSection { 19 | type Message = Message; 20 | 21 | fn new() -> Self { 22 | Self { 23 | color_picker_state: color_picker::State::new(), 24 | button_state: button::State::new(), 25 | color: Color::default(), 26 | } 27 | } 28 | 29 | fn header(&self) -> String { 30 | String::from("Color Picker") 31 | } 32 | 33 | fn update(&mut self, message: Self::Message) { 34 | match message { 35 | Message::OpenColorPicker => self.color_picker_state.show(true), 36 | Message::CancelColor => self.color_picker_state.show(false), 37 | Message::SubmitColor(color) => { 38 | self.color = color; 39 | self.color_picker_state.show(false); 40 | } 41 | } 42 | } 43 | 44 | fn content(&mut self) -> Element<'_, Self::Message> { 45 | let color_picker = ColorPicker::new( 46 | &mut self.color_picker_state, 47 | Button::new(&mut self.button_state, Text::new("Pick Color")) 48 | .on_press(Message::OpenColorPicker), 49 | Message::CancelColor, 50 | Message::SubmitColor, 51 | ); 52 | 53 | let column = Column::new() 54 | .align_items(Alignment::Center) 55 | .width(Length::Fill) 56 | .push( 57 | Row::new() 58 | .width(Length::Shrink) 59 | .align_items(Alignment::Center) 60 | .spacing(20) 61 | .push(color_picker) 62 | .push(Text::new(format!("Picked color: {:?}", self.color))), 63 | ); 64 | 65 | column.into() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /examples/pure/date_picker/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | pure::{ 3 | widget::{Button, Container, Row, Text}, 4 | Element, Sandbox, 5 | }, 6 | Alignment, Length, Settings, 7 | }; 8 | use iced_aw::{date_picker::Date, pure::DatePicker}; 9 | 10 | fn main() -> iced::Result { 11 | DatePickerExample::run(Settings::default()) 12 | } 13 | 14 | #[derive(Clone, Debug)] 15 | #[allow(clippy::enum_variant_names)] 16 | enum Message { 17 | ChooseDate, 18 | SubmitDate(Date), 19 | CancelDate, 20 | } 21 | 22 | struct DatePickerExample { 23 | date: Date, 24 | show_picker: bool, 25 | } 26 | 27 | impl Sandbox for DatePickerExample { 28 | type Message = Message; 29 | 30 | fn new() -> Self { 31 | DatePickerExample { 32 | date: Date::today(), 33 | show_picker: false, 34 | } 35 | } 36 | 37 | fn title(&self) -> String { 38 | String::from("DatePicker example") 39 | } 40 | 41 | fn update(&mut self, message: Self::Message) { 42 | match message { 43 | Message::ChooseDate => { 44 | //self.state.reset(); 45 | self.show_picker = true; 46 | } 47 | Message::SubmitDate(date) => { 48 | self.date = date; 49 | self.show_picker = false; 50 | } 51 | Message::CancelDate => { 52 | self.show_picker = false; 53 | } 54 | } 55 | } 56 | 57 | fn view(&self) -> Element<'_, Self::Message> { 58 | let but = Button::new(Text::new("Set Date")).on_press(Message::ChooseDate); 59 | 60 | let datepicker = DatePicker::new( 61 | self.show_picker, 62 | self.date, 63 | but, 64 | Message::CancelDate, 65 | Message::SubmitDate, 66 | ); 67 | 68 | let row = Row::new() 69 | .align_items(Alignment::Center) 70 | .spacing(10) 71 | .push(datepicker) 72 | .push(Text::new(format!("Date: {}", self.date,))); 73 | 74 | Container::new(row) 75 | .center_x() 76 | .center_y() 77 | .width(Length::Fill) 78 | .height(Length::Fill) 79 | .into() 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /examples/pure/time_picker/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | pure::{ 3 | widget::{Button, Container, Row, Text}, 4 | Element, Sandbox, 5 | }, 6 | Alignment, Length, Settings, 7 | }; 8 | use iced_aw::pure::{time_picker::Time, TimePicker}; 9 | 10 | fn main() -> iced::Result { 11 | TimePickerExample::run(Settings::default()) 12 | } 13 | 14 | #[derive(Clone, Debug)] 15 | #[allow(clippy::enum_variant_names)] 16 | enum Message { 17 | ChooseTime, 18 | SubmitTime(Time), 19 | CancelTime, 20 | } 21 | 22 | struct TimePickerExample { 23 | time: Time, 24 | show_picker: bool, 25 | } 26 | 27 | impl Sandbox for TimePickerExample { 28 | type Message = Message; 29 | 30 | fn new() -> Self { 31 | TimePickerExample { 32 | time: Time::now_hm(true), 33 | show_picker: false, 34 | } 35 | } 36 | 37 | fn title(&self) -> String { 38 | String::from("TimePicker example") 39 | } 40 | 41 | fn update(&mut self, message: Self::Message) { 42 | match message { 43 | Message::ChooseTime => { 44 | self.show_picker = true; 45 | } 46 | Message::SubmitTime(time) => { 47 | self.time = time; 48 | self.show_picker = false; 49 | } 50 | Message::CancelTime => { 51 | self.show_picker = false; 52 | } 53 | } 54 | } 55 | 56 | fn view(&self) -> Element<'_, Self::Message> { 57 | let but = Button::new(Text::new("Set Time")).on_press(Message::ChooseTime); 58 | 59 | let timepicker = TimePicker::new( 60 | self.show_picker, 61 | self.time, 62 | but, 63 | Message::CancelTime, 64 | Message::SubmitTime, 65 | ) 66 | //.show_seconds() 67 | .use_24h(); 68 | 69 | let row = Row::new() 70 | .align_items(Alignment::Center) 71 | .spacing(10) 72 | .push(timepicker) 73 | .push(Text::new(format!("Time: {}", self.time))); 74 | 75 | Container::new(row) 76 | .center_x() 77 | .center_y() 78 | .width(Length::Fill) 79 | .height(Length::Fill) 80 | .into() 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /examples/pure/tabs/src/ferris.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | pure::{ 3 | widget::{Column, Container, Image, Slider, Text}, 4 | Element, 5 | }, 6 | Alignment, Length, 7 | }; 8 | use iced_aw::pure::tab_bar::TabLabel; 9 | 10 | use crate::{Icon, Message, Tab}; 11 | 12 | #[derive(Debug, Clone)] 13 | pub enum FerrisMessage { 14 | ImageWidthChanged(u16), 15 | } 16 | 17 | pub struct FerrisTab { 18 | ferris_width: u16, 19 | } 20 | 21 | impl FerrisTab { 22 | pub fn new() -> Self { 23 | FerrisTab { ferris_width: 100 } 24 | } 25 | 26 | pub fn update(&mut self, message: FerrisMessage) { 27 | match message { 28 | FerrisMessage::ImageWidthChanged(value) => self.ferris_width = value, 29 | } 30 | } 31 | } 32 | 33 | impl Tab for FerrisTab { 34 | type Message = Message; 35 | 36 | fn title(&self) -> String { 37 | String::from("Ferris") 38 | } 39 | 40 | fn tab_label(&self) -> TabLabel { 41 | TabLabel::IconText(Icon::Heart.into(), self.title()) 42 | } 43 | 44 | fn content(&self) -> Element<'_, Self::Message> { 45 | let content: Element<'_, FerrisMessage> = Container::new( 46 | Column::new() 47 | .align_items(Alignment::Center) 48 | .max_width(600) 49 | .padding(20) 50 | .spacing(16) 51 | .push(Text::new(if self.ferris_width == 500 { 52 | "Hugs!!!" 53 | } else { 54 | "Pull me closer!" 55 | })) 56 | .push(ferris(self.ferris_width)) 57 | .push(Slider::new( 58 | 100..=500, 59 | self.ferris_width, 60 | FerrisMessage::ImageWidthChanged, 61 | )), 62 | ) 63 | .into(); 64 | 65 | content.map(Message::Ferris) 66 | } 67 | } 68 | 69 | fn ferris<'a>(width: u16) -> Container<'a, FerrisMessage> { 70 | Container::new(if cfg!(target_carch = "wasm32") { 71 | Image::new("images/ferris.png") 72 | } else { 73 | Image::new(format!("{}/images/ferris.png", env!("CARGO_MANIFEST_DIR"))) 74 | .width(Length::Units(width)) 75 | }) 76 | .width(Length::Fill) 77 | .center_x() 78 | } 79 | -------------------------------------------------------------------------------- /examples/date_picker/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{button, Alignment, Button, Container, Element, Length, Row, Sandbox, Settings, Text}; 2 | 3 | use iced_aw::date_picker::{self, Date, DatePicker}; 4 | 5 | fn main() -> iced::Result { 6 | DatePickerExample::run(Settings::default()) 7 | } 8 | 9 | #[derive(Clone, Debug)] 10 | #[allow(clippy::enum_variant_names)] 11 | enum Message { 12 | ChooseDate, 13 | SubmitDate(Date), 14 | CancelDate, 15 | } 16 | 17 | struct DatePickerExample { 18 | date: Date, 19 | state: date_picker::State, 20 | button_state: button::State, 21 | } 22 | 23 | impl Sandbox for DatePickerExample { 24 | type Message = Message; 25 | 26 | fn new() -> Self { 27 | DatePickerExample { 28 | date: Date::default(), 29 | state: date_picker::State::now(), 30 | button_state: button::State::new(), 31 | } 32 | } 33 | 34 | fn title(&self) -> String { 35 | String::from("DatePicker example") 36 | } 37 | 38 | fn update(&mut self, message: Self::Message) { 39 | match message { 40 | Message::ChooseDate => { 41 | self.state.reset(); 42 | self.state.show(true); 43 | } 44 | Message::SubmitDate(date) => { 45 | self.date = date; 46 | self.state.show(false); 47 | } 48 | Message::CancelDate => { 49 | self.state.show(false); 50 | } 51 | } 52 | } 53 | 54 | fn view(&mut self) -> Element<'_, Self::Message> { 55 | let but = Button::new(&mut self.button_state, Text::new("Set Date")) 56 | .on_press(Message::ChooseDate); 57 | 58 | let datepicker = DatePicker::new( 59 | &mut self.state, 60 | but, 61 | Message::CancelDate, 62 | Message::SubmitDate, 63 | ); 64 | 65 | let row = Row::new() 66 | .align_items(Alignment::Center) 67 | .spacing(10) 68 | .push(datepicker) 69 | .push(Text::new(format!("Date: {}", self.date,))); 70 | 71 | Container::new(row) 72 | .center_x() 73 | .center_y() 74 | .width(Length::Fill) 75 | .height(Length::Fill) 76 | .into() 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /examples/tabs/src/counter.rs: -------------------------------------------------------------------------------- 1 | use crate::{Icon, Message, Tab}; 2 | use iced::{button, Alignment, Button, Column, Container, Element, Row, Text}; 3 | use iced_aw::TabLabel; 4 | #[derive(Debug, Clone)] 5 | pub enum CounterMessage { 6 | Increase, 7 | Decrease, 8 | } 9 | 10 | pub struct CounterTab { 11 | value: i32, 12 | increase_button: button::State, 13 | decrease_button: button::State, 14 | } 15 | 16 | impl CounterTab { 17 | pub fn new() -> Self { 18 | CounterTab { 19 | value: 0, 20 | increase_button: button::State::default(), 21 | decrease_button: button::State::default(), 22 | } 23 | } 24 | 25 | pub fn update(&mut self, message: CounterMessage) { 26 | match message { 27 | CounterMessage::Increase => self.value += 1, 28 | CounterMessage::Decrease => self.value -= 1, 29 | } 30 | } 31 | } 32 | 33 | impl Tab for CounterTab { 34 | type Message = Message; 35 | 36 | fn title(&self) -> String { 37 | String::from("Counter") 38 | } 39 | 40 | fn tab_label(&self) -> TabLabel { 41 | //TabLabel::Text(self.title()) 42 | TabLabel::IconText(Icon::Calc.into(), self.title()) 43 | } 44 | 45 | fn content(&mut self) -> Element<'_, Self::Message> { 46 | let content: Element<'_, CounterMessage> = Container::new( 47 | Column::new() 48 | .align_items(Alignment::Center) 49 | .max_width(600) 50 | .padding(20) 51 | .spacing(16) 52 | .push(Text::new(format!("Count: {}", self.value)).size(32)) 53 | .push( 54 | Row::new() 55 | .spacing(10) 56 | .push( 57 | Button::new(&mut self.decrease_button, Text::new("Decrease")) 58 | .on_press(CounterMessage::Decrease), 59 | ) 60 | .push( 61 | Button::new(&mut self.increase_button, Text::new("Increase")) 62 | .on_press(CounterMessage::Increase), 63 | ), 64 | ), 65 | ) 66 | .into(); 67 | 68 | content.map(Message::Counter) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/style/selection_list.rs: -------------------------------------------------------------------------------- 1 | //! Selection List 2 | //! 3 | //! *This API requires the following crate features to be activated: `selection_list`* 4 | #[cfg(not(target_arch = "wasm32"))] 5 | use iced_native::{Background, Color, Length}; 6 | 7 | /// The appearance of a menu. 8 | #[derive(Debug, Clone, Copy)] 9 | pub struct Style { 10 | /// The List Label Text Color 11 | pub text_color: Color, 12 | /// The background 13 | pub background: Background, 14 | /// The container Border width 15 | pub border_width: f32, 16 | /// The container Border color 17 | pub border_color: Color, 18 | /// The List Label Text Select Color 19 | pub hovered_text_color: Color, 20 | /// The List Label Text Select Background Color 21 | pub hovered_background: Background, 22 | /// The List Label Text Select Color 23 | pub selected_text_color: Color, 24 | /// The List Label Text Select Background Color 25 | pub selected_background: Background, 26 | /// The Containers Width 27 | pub width: Length, 28 | /// The Containers height 29 | pub height: Length, 30 | /// The padding Width 31 | pub padding: u16, 32 | /// The Text Size 33 | pub text_size: u16, 34 | } 35 | 36 | impl std::default::Default for Style { 37 | fn default() -> Self { 38 | Self { 39 | text_color: Color::BLACK, 40 | background: Background::Color([0.87, 0.87, 0.87].into()), 41 | border_width: 1.0, 42 | border_color: [0.7, 0.7, 0.7].into(), 43 | hovered_text_color: Color::WHITE, 44 | hovered_background: Background::Color([0.0, 0.5, 1.0].into()), 45 | selected_text_color: Color::WHITE, 46 | selected_background: Background::Color([0.2, 0.5, 0.8].into()), 47 | width: Length::Fill, 48 | height: Length::Fill, 49 | padding: 5, 50 | text_size: 12, 51 | } 52 | } 53 | } 54 | 55 | /// A set of rules that dictate the style of a container. 56 | pub trait StyleSheet { 57 | /// Produces the style of a container. 58 | fn style() -> Style; 59 | } 60 | 61 | /// default Style holder. 62 | #[derive(Clone, Copy, Debug)] 63 | pub struct Default; 64 | 65 | impl StyleSheet for Default { 66 | fn style() -> Style { 67 | Style::default() 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /examples/tabs/src/ferris.rs: -------------------------------------------------------------------------------- 1 | use iced::{slider, Alignment, Column, Container, Element, Image, Length, Slider, Text}; 2 | use iced_aw::TabLabel; 3 | 4 | use crate::{Icon, Message, Tab}; 5 | 6 | #[derive(Debug, Clone)] 7 | pub enum FerrisMessage { 8 | ImageWidthChanged(u16), 9 | } 10 | 11 | pub struct FerrisTab { 12 | ferris_width: u16, 13 | slider: slider::State, 14 | } 15 | 16 | impl FerrisTab { 17 | pub fn new() -> Self { 18 | FerrisTab { 19 | ferris_width: 100, 20 | slider: slider::State::default(), 21 | } 22 | } 23 | 24 | pub fn update(&mut self, message: FerrisMessage) { 25 | match message { 26 | FerrisMessage::ImageWidthChanged(value) => self.ferris_width = value, 27 | } 28 | } 29 | } 30 | 31 | impl Tab for FerrisTab { 32 | type Message = Message; 33 | 34 | fn title(&self) -> String { 35 | String::from("Ferris") 36 | } 37 | 38 | fn tab_label(&self) -> TabLabel { 39 | TabLabel::IconText(Icon::Heart.into(), self.title()) 40 | } 41 | 42 | fn content(&mut self) -> Element<'_, Self::Message> { 43 | let content: Element<'_, FerrisMessage> = Container::new( 44 | Column::new() 45 | .align_items(Alignment::Center) 46 | .max_width(600) 47 | .padding(20) 48 | .spacing(16) 49 | .push(Text::new(if self.ferris_width == 500 { 50 | "Hugs!!!" 51 | } else { 52 | "Pull me closer!" 53 | })) 54 | .push(ferris(self.ferris_width)) 55 | .push(Slider::new( 56 | &mut self.slider, 57 | 100..=500, 58 | self.ferris_width, 59 | FerrisMessage::ImageWidthChanged, 60 | )), 61 | ) 62 | .into(); 63 | 64 | content.map(Message::Ferris) 65 | } 66 | } 67 | 68 | fn ferris<'a>(width: u16) -> Container<'a, FerrisMessage> { 69 | Container::new(if cfg!(target_carch = "wasm32") { 70 | Image::new("images/ferris.png") 71 | } else { 72 | Image::new(format!("{}/images/ferris.png", env!("CARGO_MANIFEST_DIR"))) 73 | .width(Length::Units(width)) 74 | }) 75 | .width(Length::Fill) 76 | .center_x() 77 | } 78 | -------------------------------------------------------------------------------- /examples/color_picker/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | button, Alignment, Button, Color, Container, Element, Length, Row, Sandbox, Settings, Text, 3 | }; 4 | 5 | use iced_aw::color_picker::{self, ColorPicker}; 6 | 7 | fn main() -> iced::Result { 8 | ColorPickerExample::run(Settings::default()) 9 | } 10 | 11 | #[derive(Clone, Debug)] 12 | #[allow(clippy::enum_variant_names)] 13 | enum Message { 14 | ChooseColor, 15 | SubmitColor(Color), 16 | CancelColor, 17 | } 18 | 19 | struct ColorPickerExample { 20 | color: Color, 21 | state: color_picker::State, 22 | button_state: button::State, 23 | } 24 | 25 | impl Sandbox for ColorPickerExample { 26 | type Message = Message; 27 | 28 | fn new() -> Self { 29 | ColorPickerExample { 30 | color: Color::default(), 31 | state: color_picker::State::new(), 32 | button_state: button::State::new(), 33 | } 34 | } 35 | 36 | fn title(&self) -> String { 37 | String::from("ColorPicker example") 38 | } 39 | 40 | fn update(&mut self, message: Self::Message) { 41 | match message { 42 | Message::ChooseColor => { 43 | //self.state.reset(); 44 | self.state.show(true); 45 | } 46 | Message::SubmitColor(color) => { 47 | self.color = color; 48 | self.state.show(false); 49 | } 50 | Message::CancelColor => { 51 | self.state.show(false); 52 | } 53 | } 54 | } 55 | 56 | fn view(&mut self) -> Element<'_, Self::Message> { 57 | let but = Button::new(&mut self.button_state, Text::new("Set Color")) 58 | .on_press(Message::ChooseColor); 59 | 60 | let datepicker = ColorPicker::new( 61 | &mut self.state, 62 | but, 63 | Message::CancelColor, 64 | Message::SubmitColor, 65 | ); 66 | 67 | let row = Row::new() 68 | .align_items(Alignment::Center) 69 | .spacing(10) 70 | .push(datepicker) 71 | .push(Text::new(format!("Color: {:?}", self.color))); 72 | 73 | Container::new(row) 74 | .center_x() 75 | .center_y() 76 | .width(Length::Fill) 77 | .height(Length::Fill) 78 | .into() 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /examples/pure/grid/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | pure::{ 3 | widget::{Button, Column, Container, Scrollable, Text}, 4 | Element, Sandbox, 5 | }, 6 | Alignment, Color, Length, Settings, 7 | }; 8 | 9 | use iced_aw::pure::Grid; 10 | 11 | // Number of columns for the grid 12 | const COLUMNS: usize = 2; 13 | 14 | fn main() -> iced::Result { 15 | GridExample::run(Settings::default()) 16 | } 17 | 18 | #[derive(Debug, Clone)] 19 | enum Message { 20 | AddElement, 21 | } 22 | 23 | struct GridExample { 24 | element_index: usize, 25 | } 26 | 27 | impl Sandbox for GridExample { 28 | type Message = Message; 29 | 30 | fn new() -> Self { 31 | GridExample { element_index: 0 } 32 | } 33 | 34 | fn title(&self) -> String { 35 | String::from("Grid example") 36 | } 37 | 38 | fn update(&mut self, message: self::Message) { 39 | match message { 40 | Message::AddElement => { 41 | self.element_index += 1; 42 | } 43 | } 44 | } 45 | 46 | fn view(&self) -> Element<'_, self::Message> { 47 | // Creates a grid with two columns 48 | let mut grid = Grid::with_columns(COLUMNS) 49 | .push(Text::new("Column 1").color(Color::from_rgb8(255, 0, 0))) 50 | .push(Text::new("Column 2").color(Color::from_rgb8(255, 0, 0))); 51 | 52 | // Add elements to the grid 53 | for i in 0..self.element_index { 54 | grid.insert(Text::new(format!( 55 | "Row {} Element {}", 56 | (i / COLUMNS) as usize, 57 | i 58 | ))); 59 | } 60 | 61 | let add_button: Element<'_, Message> = Button::new(Text::new("Add element")) 62 | .on_press(Message::AddElement) 63 | .into(); 64 | 65 | let column: Element<'_, Message> = Column::new() 66 | .spacing(15) 67 | .max_width(600) 68 | .align_items(Alignment::Center) 69 | .push(grid) 70 | .push(add_button) 71 | .into(); 72 | 73 | let content = Scrollable::new(column); 74 | 75 | Container::new(content) 76 | .width(Length::Fill) 77 | .height(Length::Fill) 78 | .padding(10) 79 | .center_x() 80 | .center_y() 81 | .into() 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /examples/time_picker/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{button, Alignment, Button, Container, Element, Length, Row, Sandbox, Settings, Text}; 2 | 3 | use iced_aw::time_picker::{self, Period, Time, TimePicker}; 4 | 5 | fn main() -> iced::Result { 6 | TimePickerExample::run(Settings::default()) 7 | } 8 | 9 | #[derive(Clone, Debug)] 10 | #[allow(clippy::enum_variant_names)] 11 | enum Message { 12 | ChooseTime, 13 | SubmitTime(Time), 14 | CancelTime, 15 | } 16 | 17 | struct TimePickerExample { 18 | time: Time, 19 | state: time_picker::State, 20 | button_state: button::State, 21 | } 22 | 23 | impl Sandbox for TimePickerExample { 24 | type Message = Message; 25 | 26 | fn new() -> Self { 27 | TimePickerExample { 28 | time: Time::default_hm(Period::H24), 29 | state: time_picker::State::now(), 30 | button_state: button::State::new(), 31 | } 32 | } 33 | 34 | fn title(&self) -> String { 35 | String::from("TimePicker example") 36 | } 37 | 38 | fn update(&mut self, message: Self::Message) { 39 | match message { 40 | Message::ChooseTime => { 41 | self.state.reset(); 42 | self.state.show(true); 43 | } 44 | Message::SubmitTime(time) => { 45 | self.time = time; 46 | self.state.show(false); 47 | } 48 | Message::CancelTime => { 49 | self.state.show(false); 50 | } 51 | } 52 | } 53 | 54 | fn view(&mut self) -> Element<'_, Self::Message> { 55 | let but = Button::new(&mut self.button_state, Text::new("Set Time")) 56 | .on_press(Message::ChooseTime); 57 | 58 | let timepicker = TimePicker::new( 59 | &mut self.state, 60 | but, 61 | Message::CancelTime, 62 | Message::SubmitTime, 63 | ) 64 | //.show_seconds() 65 | .use_24h(); 66 | 67 | let row = Row::new() 68 | .align_items(Alignment::Center) 69 | .spacing(10) 70 | .push(timepicker) 71 | .push(Text::new(format!("Time: {}", self.time))); 72 | 73 | Container::new(row) 74 | .center_x() 75 | .center_y() 76 | .width(Length::Fill) 77 | .height(Length::Fill) 78 | .into() 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /examples/pure/color_picker/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | pure::{ 3 | widget::{Button, Container, Row, Text}, 4 | Element, Sandbox, 5 | }, 6 | Alignment, Color, Length, Settings, 7 | }; 8 | 9 | use iced_aw::pure::ColorPicker; 10 | 11 | fn main() -> iced::Result { 12 | ColorPickerExample::run(Settings::default()) 13 | } 14 | 15 | #[derive(Clone, Debug)] 16 | #[allow(clippy::enum_variant_names)] 17 | enum Message { 18 | ChooseColor, 19 | SubmitColor(Color), 20 | CancelColor, 21 | } 22 | 23 | struct ColorPickerExample { 24 | color: Color, 25 | show_picker: bool, 26 | } 27 | 28 | impl Sandbox for ColorPickerExample { 29 | type Message = Message; 30 | 31 | fn new() -> Self { 32 | ColorPickerExample { 33 | color: Color::default(), 34 | show_picker: false, 35 | } 36 | } 37 | 38 | fn title(&self) -> String { 39 | String::from("ColorPicker example") 40 | } 41 | 42 | fn update(&mut self, message: Self::Message) { 43 | match message { 44 | Message::ChooseColor => { 45 | //self.state.reset(); 46 | //self.state.show(true); 47 | self.show_picker = true; 48 | } 49 | Message::SubmitColor(color) => { 50 | self.color = color; 51 | //self.state.show(false); 52 | self.show_picker = false; 53 | } 54 | Message::CancelColor => { 55 | //self.state.show(false); 56 | self.show_picker = false; 57 | } 58 | } 59 | } 60 | 61 | fn view(&self) -> Element<'_, Self::Message> { 62 | let but = Button::new(Text::new("Set Color")).on_press(Message::ChooseColor); 63 | 64 | let datepicker = ColorPicker::new( 65 | self.show_picker, 66 | self.color, 67 | but, 68 | Message::CancelColor, 69 | Message::SubmitColor, 70 | ); 71 | 72 | let row = Row::new() 73 | .align_items(Alignment::Center) 74 | .spacing(10) 75 | .push(datepicker) 76 | .push(Text::new(format!("Color: {:?}", self.color))); 77 | 78 | Container::new(row) 79 | .center_x() 80 | .center_y() 81 | .width(Length::Fill) 82 | .height(Length::Fill) 83 | .into() 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /examples/web/src/floating_button_section.rs: -------------------------------------------------------------------------------- 1 | use crate::Section; 2 | use iced::{ 3 | button, scrollable, Button, Checkbox, Column, Container, Element, Length, Scrollable, Text, 4 | }; 5 | use iced_aw::{floating_button::Anchor, FloatingButton}; 6 | 7 | pub struct FloatingButtonSection { 8 | lines: Vec, 9 | scrollable_state: scrollable::State, 10 | button_state: button::State, 11 | hide: bool, 12 | } 13 | 14 | #[derive(Clone, Debug)] 15 | pub enum Message { 16 | FloatingButtonPressed, 17 | HideButton(bool), 18 | } 19 | 20 | impl Section for FloatingButtonSection { 21 | type Message = Message; 22 | 23 | fn new() -> Self { 24 | Self { 25 | lines: vec!["Hello".into(), "World".into()], 26 | scrollable_state: scrollable::State::new(), 27 | button_state: button::State::new(), 28 | hide: false, 29 | } 30 | } 31 | 32 | fn header(&self) -> String { 33 | String::from("Floating Button") 34 | } 35 | 36 | fn update(&mut self, message: Self::Message) { 37 | match message { 38 | Message::FloatingButtonPressed => self.lines.push("This is a newly added line.".into()), 39 | Message::HideButton(hide) => self.hide = hide, 40 | } 41 | } 42 | 43 | fn content(&mut self) -> Element<'_, Self::Message> { 44 | let column = self 45 | .lines 46 | .iter() 47 | .fold(Column::new(), |col, line| { 48 | col.push(Text::new(line.to_owned())) 49 | }) 50 | .width(Length::Fill); 51 | 52 | let scrollable = Scrollable::new(&mut self.scrollable_state) 53 | .width(Length::Fill) 54 | .height(Length::Fill) 55 | .max_height(100) 56 | .push(column); 57 | 58 | let container = Container::new( 59 | FloatingButton::new(&mut self.button_state, scrollable, |state| { 60 | Button::new(state, Text::new("Press Me!")) 61 | .on_press(Message::FloatingButtonPressed) 62 | .style(iced_aw::style::button::Primary) 63 | }) 64 | .anchor(Anchor::SouthEast) 65 | .offset([20.0, 5.0]) 66 | .hide(self.hide), 67 | ) 68 | .width(Length::Fill); 69 | 70 | let column = Column::new() 71 | .spacing(10) 72 | .push(Checkbox::new(self.hide, "Hide button", Message::HideButton)) 73 | .push(container); 74 | 75 | column.into() 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /examples/pure/card/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | pure::{ 3 | widget::{Button, Column, Container, Scrollable, Text}, 4 | Element, Sandbox, 5 | }, 6 | Length, Settings, 7 | }; 8 | use iced_aw::{pure::Card, style}; 9 | 10 | fn main() -> iced::Result { 11 | CardExample::run(Settings::default()) 12 | } 13 | 14 | #[derive(Debug, Clone)] 15 | enum Message { 16 | CloseCard, 17 | OpenCard, 18 | } 19 | 20 | struct CardExample { 21 | card_open: bool, 22 | } 23 | 24 | impl Sandbox for CardExample { 25 | type Message = Message; 26 | 27 | fn new() -> Self { 28 | CardExample { card_open: true } 29 | } 30 | 31 | fn title(&self) -> String { 32 | String::from("Card example") 33 | } 34 | 35 | fn update(&mut self, message: self::Message) { 36 | match message { 37 | Message::CloseCard | Message::OpenCard => { 38 | self.card_open = !self.card_open; 39 | } 40 | } 41 | } 42 | 43 | fn view(&self) -> Element<'_, self::Message> { 44 | let element: Element<'_, Message> = if self.card_open { 45 | Card::new( 46 | Text::new("Head"), 47 | Column::new() 48 | //.push(Text::new("Body").size(42)) 49 | .push(Text::new("Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit, morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. Qui animated corpse, cricket bat max brucks terribilem incessu zomby. The voodoo sacerdos flesh eater, suscitat mortuos comedere carnem virus. Zonbi tattered for solum oculi eorum defunctis go lum cerebro. Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.")) 50 | ) 51 | .foot(Text::new("Foot")) 52 | .style(style::card::Primary) 53 | .on_close(Message::CloseCard) 54 | .into() 55 | } else { 56 | Button::new(Text::new("Open card")) 57 | .on_press(Message::OpenCard) 58 | .into() 59 | }; 60 | 61 | let content = Scrollable::new(element); 62 | 63 | Container::new(Column::new().push(content).max_width(600)) 64 | .width(Length::Fill) 65 | .height(Length::Fill) 66 | .padding(10) 67 | .center_x() 68 | .center_y() 69 | .into() 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /examples/grid/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | button, scrollable, Alignment, Button, Color, Column, Container, Element, Length, Sandbox, 3 | Scrollable, Settings, Text, 4 | }; 5 | 6 | use iced_aw::Grid; 7 | 8 | // Number of columns for the grid 9 | const COLUMNS: usize = 2; 10 | 11 | fn main() -> iced::Result { 12 | GridExample::run(Settings::default()) 13 | } 14 | 15 | #[derive(Debug, Clone)] 16 | enum Message { 17 | AddElement, 18 | } 19 | 20 | struct GridExample { 21 | element_index: usize, 22 | button_state: button::State, 23 | scrollable_state: scrollable::State, 24 | } 25 | 26 | impl Sandbox for GridExample { 27 | type Message = Message; 28 | 29 | fn new() -> Self { 30 | GridExample { 31 | element_index: 0, 32 | button_state: button::State::new(), 33 | scrollable_state: scrollable::State::new(), 34 | } 35 | } 36 | 37 | fn title(&self) -> String { 38 | String::from("Grid example") 39 | } 40 | 41 | fn update(&mut self, message: self::Message) { 42 | match message { 43 | Message::AddElement => { 44 | self.element_index += 1; 45 | } 46 | } 47 | } 48 | 49 | fn view(&mut self) -> Element<'_, self::Message> { 50 | // Creates a grid with two columns 51 | let mut grid = Grid::with_columns(COLUMNS) 52 | .push(Text::new("Column 1").color(Color::from_rgb8(255, 0, 0))) 53 | .push(Text::new("Column 2").color(Color::from_rgb8(255, 0, 0))); 54 | 55 | // Add elements to the grid 56 | for i in 0..self.element_index { 57 | grid.insert(Text::new(format!( 58 | "Row {} Element {}", 59 | (i / COLUMNS) as usize, 60 | i 61 | ))); 62 | } 63 | 64 | let add_button: Element<'_, Message> = 65 | Button::new(&mut self.button_state, Text::new("Add element")) 66 | .on_press(Message::AddElement) 67 | .into(); 68 | 69 | let column: Element<'_, Message> = Column::new() 70 | .spacing(15) 71 | .align_items(Alignment::Center) 72 | .push(grid) 73 | .push(add_button) 74 | .into(); 75 | 76 | let content = Scrollable::new(&mut self.scrollable_state) 77 | .max_width(600) 78 | .push(column); 79 | 80 | Container::new(content) 81 | .width(Length::Fill) 82 | .height(Length::Fill) 83 | .padding(10) 84 | .center_x() 85 | .center_y() 86 | .into() 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/style/number_input.rs: -------------------------------------------------------------------------------- 1 | //! Display fields that can only be filled with numeric type. 2 | //! 3 | //! *This API requires the following crate features to be activated: `number_input`* 4 | #[cfg(not(target_arch = "wasm32"))] 5 | use iced_native::{Background, Color}; 6 | 7 | /// The appearance of a [`NumberInput`](crate::native::number_input::NumberInput). 8 | #[derive(Clone, Copy, Debug)] 9 | pub struct Style { 10 | /// The background of the [`NumberInput`](crate::native::number_input::NumberInput). 11 | pub button_background: Option, 12 | /// The Color of the arrows of [`NumberInput`](crate::native::number_input::NumberInput). 13 | pub icon_color: Color, 14 | } 15 | 16 | impl std::default::Default for Style { 17 | fn default() -> Self { 18 | Self { 19 | button_background: None, 20 | icon_color: Color::BLACK, 21 | } 22 | } 23 | } 24 | 25 | /// The appearance of a [`NumberInput`](crate::native::number_input::NumberInput). 26 | pub trait StyleSheet { 27 | /// The normal appearance of a [`NumberInput`](crate::native::number_input::NumberInput). 28 | fn active(&self) -> Style; 29 | 30 | /// The appearance when the [`NumberInput`](crate::native::number_input::NumberInput) is pressed. 31 | fn pressed(&self) -> Style { 32 | self.active() 33 | } 34 | 35 | /// The appearance when the [`NumberInput`](crate::native::number_input::NumberInput) is disabled. 36 | fn disabled(&self) -> Style { 37 | let active = self.active(); 38 | Style { 39 | button_background: active.button_background.map(|bg| match bg { 40 | Background::Color(color) => Background::Color(Color { 41 | a: color.a * 0.5, 42 | ..color 43 | }), 44 | }), 45 | icon_color: Color { 46 | a: active.icon_color.a * 0.5, 47 | ..active.icon_color 48 | }, 49 | } 50 | } 51 | } 52 | 53 | /// The default appearance of the [`NumberInput`](crate::native::number_input::NumberInput). 54 | #[derive(Clone, Copy, Debug)] 55 | struct Default; 56 | 57 | impl StyleSheet for Default { 58 | fn active(&self) -> Style { 59 | Style::default() 60 | } 61 | } 62 | 63 | #[allow(clippy::use_self)] 64 | impl std::default::Default for Box { 65 | fn default() -> Self { 66 | Box::new(Default) 67 | } 68 | } 69 | 70 | #[allow(clippy::use_self)] 71 | impl From for Box 72 | where 73 | T: 'static + StyleSheet, 74 | { 75 | fn from(style: T) -> Self { 76 | Box::new(style) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /examples/card/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | button, scrollable, Button, Column, Container, Element, Length, Sandbox, Scrollable, Settings, 3 | Text, 4 | }; 5 | 6 | use iced_aw::{style, Card}; 7 | 8 | fn main() -> iced::Result { 9 | CardExample::run(Settings::default()) 10 | } 11 | 12 | #[derive(Debug, Clone)] 13 | enum Message { 14 | CloseCard, 15 | OpenCard, 16 | } 17 | 18 | struct CardExample { 19 | card_open: bool, 20 | button_state: button::State, 21 | scrollable_state: scrollable::State, 22 | } 23 | 24 | impl Sandbox for CardExample { 25 | type Message = Message; 26 | 27 | fn new() -> Self { 28 | CardExample { 29 | card_open: true, 30 | button_state: button::State::new(), 31 | scrollable_state: scrollable::State::new(), 32 | } 33 | } 34 | 35 | fn title(&self) -> String { 36 | String::from("Card example") 37 | } 38 | 39 | fn update(&mut self, message: self::Message) { 40 | match message { 41 | Message::CloseCard | Message::OpenCard => { 42 | self.card_open = !self.card_open; 43 | } 44 | } 45 | } 46 | 47 | fn view(&mut self) -> Element<'_, self::Message> { 48 | let element: Element<'_, Message> = if self.card_open { 49 | Card::new( 50 | Text::new("Head"), 51 | Column::new() 52 | //.push(Text::new("Body").size(42)) 53 | .push(Text::new("Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit, morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. Qui animated corpse, cricket bat max brucks terribilem incessu zomby. The voodoo sacerdos flesh eater, suscitat mortuos comedere carnem virus. Zonbi tattered for solum oculi eorum defunctis go lum cerebro. Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.")) 54 | ) 55 | .foot(Text::new("Foot")) 56 | .style(style::card::Primary) 57 | .on_close(Message::CloseCard) 58 | .into() 59 | } else { 60 | Button::new(&mut self.button_state, Text::new("Open card")) 61 | .on_press(Message::OpenCard) 62 | .into() 63 | }; 64 | 65 | let content = Scrollable::new(&mut self.scrollable_state) 66 | .max_width(600) 67 | .push(element); 68 | 69 | Container::new(content) 70 | .width(Length::Fill) 71 | .height(Length::Fill) 72 | .padding(10) 73 | .center_x() 74 | .center_y() 75 | .into() 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /examples/web/src/picklist_section.rs: -------------------------------------------------------------------------------- 1 | 2 | use iced::{pick_list, Column, Length, Text, 3 | PickList, Align, Element}; 4 | use crate::Section; 5 | 6 | pub struct PickListSection { 7 | pick_list: pick_list::State, 8 | selected_language: Language, 9 | } 10 | 11 | impl PickListSection { 12 | pub fn new() -> Self { 13 | Self { 14 | pick_list: pick_list::State::default(), 15 | selected_language: Language::Haskell, 16 | } 17 | } 18 | 19 | pub fn update(&mut self, message: Message) { 20 | match message { 21 | Message::LanguageSelected(language) => self.selected_language = language, 22 | } 23 | } 24 | } 25 | 26 | #[derive(Clone, Debug)] 27 | pub enum Message { 28 | LanguageSelected(Language), 29 | } 30 | 31 | impl Section for PickListSection { 32 | 33 | type Message = crate::Message; 34 | 35 | fn header(&self) -> String { 36 | String::from("Picklist") 37 | } 38 | 39 | fn content(&mut self) -> Element<'_, Self::Message> { 40 | let pick_list = PickList::new( 41 | &mut self.pick_list, 42 | &Language::ALL[..], 43 | Some(self.selected_language), 44 | Message::LanguageSelected, 45 | ); 46 | 47 | let column: Element<'_, Message> = Column::new() 48 | .width(Length::Fill) 49 | .align_items(Align::Center) 50 | .spacing(5) 51 | .push( 52 | Text::new("Which is your favorite language?") 53 | ) 54 | .push( 55 | pick_list 56 | ).into(); 57 | 58 | column.map(|msg| crate::Message::PickList(msg)) 59 | } 60 | } 61 | 62 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] 63 | pub enum Language { 64 | Rust, 65 | Elm, 66 | Ruby, 67 | Haskell, 68 | C, 69 | Javascript, 70 | Other, 71 | } 72 | 73 | impl Language { 74 | const ALL: [Language; 7] = [ 75 | Language::C, 76 | Language::Elm, 77 | Language::Ruby, 78 | Language::Haskell, 79 | Language::Rust, 80 | Language::Javascript, 81 | Language::Other, 82 | ]; 83 | } 84 | 85 | impl Default for Language { 86 | fn default() -> Language { 87 | Language::Rust 88 | } 89 | } 90 | 91 | impl std::fmt::Display for Language { 92 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 93 | write!( 94 | f, 95 | "{}", 96 | match self { 97 | Language::Rust => "Rust", 98 | Language::Elm => "Elm", 99 | Language::Ruby => "Ruby", 100 | Language::Haskell => "Haskell", 101 | Language::C => "C", 102 | Language::Javascript => "Javascript", 103 | Language::Other => "Some other language", 104 | } 105 | ) 106 | } 107 | } -------------------------------------------------------------------------------- /src/style/tab_bar.rs: -------------------------------------------------------------------------------- 1 | //! Displays a [`TabBar`](crate::native::tab_bar::TabBar) to select the content 2 | //! to be displayed. 3 | //! 4 | //! You have to manage the logic to show the contend by yourself or you may want 5 | //! to use the [`Tabs`](crate::native::tabs::Tabs) widget instead. 6 | //! 7 | //! *This API requires the following crate features to be activated: `tab_bar`* 8 | #[cfg(not(target_arch = "wasm32"))] 9 | use iced_native::{Background, Color}; 10 | 11 | /// The appearance of a [`TabBar`](crate::native::tab_bar::TabBar). 12 | #[derive(Clone, Copy, Debug)] 13 | pub struct Style { 14 | /// The background of the tab bar. 15 | pub background: Option, 16 | 17 | /// The border color of the tab bar. 18 | pub border_color: Option, 19 | 20 | /// The border width of the tab bar. 21 | pub border_width: f32, 22 | 23 | /// The background of the tab labels. 24 | pub tab_label_background: Background, 25 | 26 | /// The border color of the tab labels. 27 | pub tab_label_border_color: Color, 28 | 29 | /// The border with of the tab labels. 30 | pub tab_label_border_width: f32, 31 | 32 | /// The icon color of the tab labels. 33 | pub icon_color: Color, 34 | 35 | /// The text color of the tab labels. 36 | pub text_color: Color, 37 | } 38 | 39 | /// The appearance of a [`TabBar`](crate::native::tab_bar::TabBar). 40 | pub trait StyleSheet { 41 | /// The normal appearance0of a tab bar and its tab labels. 42 | /// 43 | /// `is_active` is true if the tab is selected. 44 | fn active(&self, is_active: bool) -> Style; 45 | 46 | /// The appearance when the tab bar and/or a tab label is hovered. 47 | /// 48 | /// `is_active` is true if the tab is selected. 49 | fn hovered(&self, is_active: bool) -> Style; 50 | } 51 | 52 | /// The default appearance of a [`TabBar`](crate::native::TabBar). 53 | #[derive(Clone, Copy, Debug)] 54 | pub struct Default; 55 | 56 | impl StyleSheet for Default { 57 | fn active(&self, is_active: bool) -> Style { 58 | Style { 59 | background: None, 60 | border_color: None, 61 | border_width: 0.0, 62 | tab_label_background: if is_active { 63 | Background::Color([0.9, 0.9, 0.9].into()) 64 | } else { 65 | Background::Color([0.87, 0.87, 0.87].into()) 66 | }, 67 | tab_label_border_color: [0.7, 0.7, 0.7].into(), 68 | tab_label_border_width: 1.0, 69 | icon_color: Color::BLACK, 70 | text_color: Color::BLACK, 71 | } 72 | } 73 | 74 | fn hovered(&self, is_active: bool) -> Style { 75 | Style { 76 | tab_label_background: Background::Color([0.9, 0.9, 0.9].into()), 77 | ..self.active(is_active) 78 | } 79 | } 80 | } 81 | 82 | #[allow(clippy::use_self)] 83 | impl std::default::Default for Box { 84 | fn default() -> Self { 85 | Box::new(Default) 86 | } 87 | } 88 | 89 | #[allow(clippy::use_self)] 90 | impl From for Box 91 | where 92 | T: 'static + StyleSheet, 93 | { 94 | fn from(style: T) -> Self { 95 | Box::new(style) 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/style/split.rs: -------------------------------------------------------------------------------- 1 | //! Use a split to split the available space in two parts to display two different elements. 2 | //! 3 | //! *This API requires the following crate features to be activated: split* 4 | #[cfg(not(target_arch = "wasm32"))] 5 | use iced_native::{Background, Color}; 6 | 7 | /// The appearance of a [`Split`](crate::native::split::Split). 8 | #[derive(Clone, Copy, Debug)] 9 | pub struct Style { 10 | /// The optional background of the [`Split`](crate::native::split::Split). 11 | pub background: Option, 12 | /// The optional background of the first element of the [`Split`](crate::native::split::Split). 13 | pub first_background: Option, 14 | /// The optional background of the second element of the [`Split`](crate::native::split::Split). 15 | pub second_background: Option, 16 | /// The border width of the [`Split`](crate::native::split::Split). 17 | pub border_width: f32, 18 | /// The border color of the [`Split`](crate::native::split::Split). 19 | pub border_color: Color, 20 | /// The background of the divider of the [`Split`](crate::native::split::Split). 21 | pub divider_background: Background, 22 | /// The border width of the divider of the [`Split`](crate::native::split::Split). 23 | pub divider_border_width: f32, 24 | /// The border color of the divider of the [`Split`](crate::native::split::Split). 25 | pub divider_border_color: Color, 26 | } 27 | 28 | /// The appearance of a [`Split`](crate::native::split::Split). 29 | pub trait StyleSheet { 30 | /// The normal appearance of a [`Split`](crate::native::split::Split). 31 | fn active(&self) -> Style; 32 | 33 | /// The appearance when the [`Split`](crate::native::split::Split) is hovered. 34 | fn hovered(&self) -> Style; 35 | 36 | /// The appearance when the divider of the [`Split`](crate::native::split::Split) is dragged 37 | fn dragged(&self) -> Style; 38 | } 39 | 40 | /// The default appearance of the [`Split`](crate::native::split::Split). 41 | #[derive(Clone, Copy, Debug)] 42 | pub struct Default; 43 | 44 | impl StyleSheet for Default { 45 | fn active(&self) -> Style { 46 | Style { 47 | background: None, 48 | first_background: None, 49 | second_background: None, 50 | border_width: 1.0, 51 | border_color: Color::from_rgb(0.6, 0.6, 0.6), 52 | divider_background: Color::WHITE.into(), 53 | divider_border_width: 1.0, 54 | divider_border_color: Color::from_rgb(0.8, 0.8, 0.8), 55 | } 56 | } 57 | 58 | fn hovered(&self) -> Style { 59 | Style { 60 | divider_background: Color::from_rgb(0.8, 0.8, 0.8).into(), 61 | ..self.active() 62 | } 63 | } 64 | 65 | fn dragged(&self) -> Style { 66 | Style { 67 | divider_background: Color::from_rgb(0.7, 0.7, 0.7).into(), 68 | ..self.active() 69 | } 70 | } 71 | } 72 | 73 | #[allow(clippy::use_self)] 74 | impl std::default::Default for Box { 75 | fn default() -> Self { 76 | Box::new(Default) 77 | } 78 | } 79 | 80 | #[allow(clippy::use_self)] 81 | impl From for Box 82 | where 83 | T: 'static + StyleSheet, 84 | { 85 | fn from(style: T) -> Self { 86 | Box::new(style) 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/style/color_picker.rs: -------------------------------------------------------------------------------- 1 | //! Use a color picker as an input element for picking colors. 2 | //! 3 | //! *This API requires the following crate features to be activated: `color_picker`* 4 | #[cfg(not(target_arch = "wasm32"))] 5 | use iced_native::{Background, Color}; 6 | 7 | /// The appearance of a [`ColorPicker`](crate::native::ColorPicker). 8 | #[derive(Clone, Copy, Debug)] 9 | pub struct Style { 10 | /// The background of the [`ColorPicker`](crate::native::ColorPicker). 11 | pub background: Background, 12 | 13 | /// The border radius of the [`ColorPicker`](crate::native::ColorPicker). 14 | pub border_radius: f32, 15 | 16 | /// The border with of the [`ColorPicker`](crate::native::ColorPicker). 17 | pub border_width: f32, 18 | 19 | /// The border color of the [`ColorPicker`](crate::native::ColorPicker). 20 | pub border_color: Color, 21 | 22 | /// The border radius of the bars of the [`ColorPicker`](crate::native::ColorPicker). 23 | pub bar_border_radius: f32, 24 | 25 | /// The border width of the bars of the [`ColorPicker`](crate::native::ColorPicker). 26 | pub bar_border_width: f32, 27 | 28 | /// The border color of the bars of the [`ColorPicker`](crate::native::ColorPicker). 29 | pub bar_border_color: Color, 30 | } 31 | 32 | /// The appearance of a [`ColorPicker`](crate::native::ColorPicker). 33 | pub trait StyleSheet { 34 | /// The normal appearance of a [`ColorPicker`](crate::native::ColorPicker). 35 | fn active(&self) -> Style; 36 | 37 | /// The appearance when something is selected of the 38 | /// [`ColorPicker`](crate::native::ColorPicker). 39 | fn selected(&self) -> Style; 40 | 41 | /// The appearance when something is hovered of the 42 | /// [`ColorPicker`](crate::native::ColorPicker). 43 | fn hovered(&self) -> Style; 44 | 45 | /// The appearance when something is focused of the 46 | /// [`ColorPicker`](crate::native::ColorPicker). 47 | fn focused(&self) -> Style; 48 | } 49 | 50 | /// The default appearance of the [`ColorPicker`](crate::native::ColorPicker). 51 | #[derive(Clone, Copy, Debug)] 52 | pub struct Default; 53 | 54 | impl StyleSheet for Default { 55 | fn active(&self) -> Style { 56 | Style { 57 | background: Color::WHITE.into(), 58 | border_radius: 15.0, 59 | border_width: 1.0, 60 | border_color: Color::BLACK, 61 | bar_border_radius: 5.0, 62 | bar_border_width: 1.0, 63 | bar_border_color: Color::BLACK, 64 | } 65 | } 66 | 67 | fn selected(&self) -> Style { 68 | Style { ..self.active() } 69 | } 70 | 71 | fn hovered(&self) -> Style { 72 | Style { ..self.active() } 73 | } 74 | 75 | fn focused(&self) -> Style { 76 | Style { 77 | border_color: Color::from_rgb(0.5, 0.5, 0.5), 78 | bar_border_color: Color::from_rgb(0.5, 0.5, 0.5), 79 | ..self.active() 80 | } 81 | } 82 | } 83 | 84 | #[allow(clippy::use_self)] 85 | impl std::default::Default for Box { 86 | fn default() -> Self { 87 | Box::new(Default) 88 | } 89 | } 90 | 91 | #[allow(clippy::use_self)] 92 | impl From for Box 93 | where 94 | T: 'static + StyleSheet, 95 | { 96 | fn from(style: T) -> Self { 97 | Box::new(style) 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /examples/pure/floating_element/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | pure::{ 3 | widget::{Button, Column, Container, Scrollable, Text}, 4 | Element, Sandbox, 5 | }, 6 | Length, Settings, 7 | }; 8 | 9 | use iced_aw::pure::floating_element::{self, FloatingElement}; 10 | use iced_aw::{Icon, ICON_FONT}; 11 | 12 | fn main() -> iced::Result { 13 | FloatingElementExample::run(Settings::default()) 14 | } 15 | 16 | #[derive(Debug, Clone)] 17 | enum Message { 18 | ButtonPressed, 19 | } 20 | 21 | struct FloatingElementExample { 22 | lines: Vec, 23 | } 24 | 25 | impl Sandbox for FloatingElementExample { 26 | type Message = Message; 27 | 28 | fn new() -> Self { 29 | FloatingElementExample { lines: Vec::new() } 30 | } 31 | 32 | fn title(&self) -> String { 33 | String::from("FloatingButton example") 34 | } 35 | 36 | fn update(&mut self, message: Message) { 37 | match message { 38 | Message::ButtonPressed => self.lines.push("This is a newly added line.".into()), 39 | } 40 | } 41 | 42 | fn view(&self) -> Element { 43 | let scrollable_content = self.lines.iter().enumerate().fold( 44 | Column::new() 45 | .width(Length::Fill) 46 | .height(Length::Fill) 47 | .padding(10), 48 | |scroll, (i, line)| scroll.push(Text::new(format!("{}. {}", i + 1, line))), 49 | ); 50 | let scrollable_content = Scrollable::new(scrollable_content); 51 | 52 | let content = FloatingElement::new( 53 | Container::new(scrollable_content) 54 | .width(Length::Fill) 55 | .height(Length::Fill) 56 | .max_width(400) 57 | .max_height(600) 58 | .style(BorderedContainer), 59 | || { 60 | Button::new( 61 | Text::new(Icon::Plus) 62 | .width(Length::Shrink) 63 | .height(Length::Shrink) 64 | .font(ICON_FONT) 65 | .size(39), 66 | ) 67 | //.style(iced_aw::style::button::Primary), 68 | .on_press(Message::ButtonPressed) 69 | .padding(5) 70 | .style(RoundedButton) 71 | .into() 72 | }, 73 | ) 74 | .anchor(floating_element::Anchor::SouthEast) 75 | .offset(20.0) 76 | .hide(false); 77 | 78 | Container::new(content) 79 | .width(Length::Fill) 80 | .height(Length::Fill) 81 | .padding(10) 82 | .center_x() 83 | .center_y() 84 | .into() 85 | } 86 | } 87 | 88 | struct RoundedButton; 89 | 90 | impl iced::button::StyleSheet for RoundedButton { 91 | fn active(&self) -> iced::button::Style { 92 | iced::button::Style { 93 | border_radius: 25.0, 94 | ..iced_aw::style::button::Primary.active() 95 | } 96 | } 97 | } 98 | 99 | struct BorderedContainer; 100 | 101 | impl iced::container::StyleSheet for BorderedContainer { 102 | fn style(&self) -> iced::container::Style { 103 | iced::container::Style { 104 | border_width: 1.0, 105 | border_color: iced::Color::BLACK, 106 | border_radius: 10.0, 107 | ..Default::default() 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /examples/pure/tabs/src/login.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | alignment::{Horizontal, Vertical}, 3 | pure::{ 4 | widget::{Button, Column, Container, Row, Text, TextInput}, 5 | Element, 6 | }, 7 | Alignment, Length, 8 | }; 9 | use iced_aw::pure::tab_bar::TabLabel; 10 | 11 | use crate::{Icon, Message, Tab}; 12 | 13 | #[derive(Debug, Clone)] 14 | pub enum LoginMessage { 15 | UsernameChanged(String), 16 | PasswordChanged(String), 17 | ClearPressed, 18 | LoginPressed, 19 | } 20 | 21 | pub struct LoginTab { 22 | username: String, 23 | password: String, 24 | } 25 | 26 | impl LoginTab { 27 | pub fn new() -> Self { 28 | LoginTab { 29 | username: String::new(), 30 | password: String::new(), 31 | } 32 | } 33 | 34 | pub fn update(&mut self, message: LoginMessage) { 35 | match message { 36 | LoginMessage::UsernameChanged(value) => self.username = value, 37 | LoginMessage::PasswordChanged(value) => self.password = value, 38 | LoginMessage::ClearPressed => { 39 | self.username = String::new(); 40 | self.password = String::new(); 41 | } 42 | LoginMessage::LoginPressed => {} 43 | } 44 | } 45 | } 46 | 47 | impl Tab for LoginTab { 48 | type Message = Message; 49 | 50 | fn title(&self) -> String { 51 | String::from("Login") 52 | } 53 | 54 | fn tab_label(&self) -> TabLabel { 55 | //TabLabel::Text(self.title()) 56 | TabLabel::IconText(Icon::User.into(), self.title()) 57 | } 58 | 59 | fn content(&self) -> Element<'_, Self::Message> { 60 | let content: Element<'_, LoginMessage> = Container::new( 61 | Column::new() 62 | .align_items(Alignment::Center) 63 | .max_width(600) 64 | .padding(20) 65 | .spacing(16) 66 | .push( 67 | TextInput::new("Username", &self.username, LoginMessage::UsernameChanged) 68 | .padding(10) 69 | .size(32), 70 | ) 71 | .push( 72 | TextInput::new("Password", &self.password, LoginMessage::PasswordChanged) 73 | .padding(10) 74 | .size(32) 75 | .password(), 76 | ) 77 | .push( 78 | Row::new() 79 | .spacing(10) 80 | .push( 81 | Button::new( 82 | Text::new("Clear").horizontal_alignment(Horizontal::Center), 83 | ) 84 | .width(Length::Fill) 85 | .on_press(LoginMessage::ClearPressed), 86 | ) 87 | .push( 88 | Button::new( 89 | Text::new("Login").horizontal_alignment(Horizontal::Center), 90 | ) 91 | .width(Length::Fill) 92 | .on_press(LoginMessage::LoginPressed), 93 | ), 94 | ), 95 | ) 96 | .align_x(Horizontal::Center) 97 | .align_y(Vertical::Center) 98 | .into(); 99 | 100 | content.map(Message::Login) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "iced_aw" 3 | version = "0.2.0" 4 | authors = ["Kaiden42 "] 5 | edition = "2021" 6 | description = "Additional widgets for the Iced GUI library" 7 | license = "MIT" 8 | repository = "https://github.com/kaiden42/iced_aw" 9 | # TODO documentation 10 | readme = "README.md" 11 | keywords = ["gui", "ui", "graphics", "interface", "widgets", "iced"] 12 | categories = ["gui"] 13 | 14 | [features] 15 | badge = [] 16 | button = [] 17 | card = [] 18 | colors = [] 19 | date_picker = ["chrono", "lazy_static", "icon_text"] 20 | color_picker = ["icon_text", "iced_graphics/canvas"] 21 | floating_button = ["button"] 22 | floating_element = ["button", "floating_button"] 23 | grid = [] 24 | glow = [] # TODO 25 | icon_text = ["icons"] 26 | icons = [] 27 | modal = [] 28 | pure = ["iced_pure"] 29 | tab_bar = [] 30 | tabs = ["tab_bar"] 31 | time_picker = ["chrono", "icon_text", "iced_graphics/canvas"] 32 | wrap = [] 33 | number_input = ["num-traits"] 34 | selection_list = [] 35 | split = [] 36 | 37 | default = [ 38 | "badge", 39 | "card", 40 | "colors", 41 | "date_picker", 42 | "color_picker", 43 | "floating_button", 44 | "floating_element", 45 | "grid", 46 | "modal", 47 | "pure", 48 | "tab_bar", 49 | "tabs", 50 | "time_picker", 51 | "wrap", 52 | "selection_list", 53 | "split", 54 | ] 55 | 56 | [dependencies] 57 | num-traits = { version = "0.2.15", optional = true } 58 | 59 | [target.'cfg(not(target_arch = "wasm32"))'.dependencies] 60 | chrono = { version = "0.4.19", optional = true } 61 | lazy_static = { version = "1.4.0", optional = true } 62 | 63 | [target.'cfg(not(target_arch = "wasm32"))'.dependencies.iced_native] 64 | #git = "https://github.com/iced-rs/iced.git" 65 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 66 | version = "0.5.1" 67 | 68 | [target.'cfg(not(target_arch = "wasm32"))'.dependencies.iced_graphics] 69 | #git = "https://github.com/iced-rs/iced.git" 70 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 71 | version = "0.3.0" 72 | 73 | [target.'cfg(not(target_arch = "wasm32"))'.dependencies.iced_pure] 74 | #git = "https://github.com/iced-rs/iced.git" 75 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 76 | version = "0.2.2" 77 | optional = true 78 | 79 | [dependencies.iced_style] 80 | #git = "https://github.com/iced-rs/iced.git" 81 | #rev = "ba33e92818ec181508b4957d1eae5b2beb9ea221" 82 | version = "0.4.0" 83 | 84 | [profile.dev.package."*"] 85 | opt-level = 2 86 | 87 | [workspace] 88 | members = [ 89 | "examples/badge", 90 | "examples/card", 91 | "examples/color_picker", 92 | "examples/date_picker", 93 | "examples/floating_button", 94 | "examples/grid", 95 | "examples/modal", 96 | "examples/pure/badge", 97 | "examples/pure/card", 98 | "examples/pure/color_picker", 99 | "examples/pure/date_picker", 100 | "examples/pure/floating_element", 101 | "examples/pure/modal", 102 | "examples/pure/grid", 103 | "examples/pure/split", 104 | "examples/pure/tab_bar", 105 | "examples/pure/tabs", 106 | "examples/pure/time_picker", 107 | "examples/tab_bar", 108 | "examples/tabs", 109 | #"examples/tabs_min", 110 | "examples/time_picker", 111 | "examples/wrap", 112 | "examples/pure/wrap", 113 | "examples/web", 114 | "examples/number_input", 115 | "examples/pure/number_input", 116 | "examples/selection_list", 117 | "examples/pure/selection_list", 118 | "examples/split", 119 | ] 120 | -------------------------------------------------------------------------------- /examples/floating_button/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | button, scrollable, Button, Container, Element, Length, Sandbox, Scrollable, Settings, Text, 3 | }; 4 | 5 | use iced_aw::{floating_button, FloatingButton, Icon, ICON_FONT}; 6 | 7 | fn main() -> iced::Result { 8 | FloatingButtonExample::run(Settings::default()) 9 | } 10 | 11 | #[derive(Debug, Clone)] 12 | enum Message { 13 | ButtonPressed, 14 | } 15 | 16 | struct FloatingButtonExample { 17 | button_state: button::State, 18 | scrollable_state: scrollable::State, 19 | lines: Vec, 20 | } 21 | 22 | impl Sandbox for FloatingButtonExample { 23 | type Message = Message; 24 | 25 | fn new() -> Self { 26 | FloatingButtonExample { 27 | button_state: button::State::new(), 28 | scrollable_state: scrollable::State::new(), 29 | lines: Vec::new(), 30 | } 31 | } 32 | 33 | fn title(&self) -> String { 34 | String::from("FloatingButton example") 35 | } 36 | 37 | fn update(&mut self, message: Message) { 38 | match message { 39 | Message::ButtonPressed => self.lines.push("This is a newly added line.".into()), 40 | } 41 | } 42 | 43 | fn view(&mut self) -> Element { 44 | let scrollable_content = self.lines.iter().enumerate().fold( 45 | Scrollable::new(&mut self.scrollable_state) 46 | .width(Length::Fill) 47 | .height(Length::Fill) 48 | .padding(10), 49 | |scroll, (i, line)| scroll.push(Text::new(format!("{}. {}", i + 1, line))), 50 | ); 51 | 52 | let content = FloatingButton::new( 53 | &mut self.button_state, 54 | Container::new(scrollable_content) 55 | .width(Length::Fill) 56 | .height(Length::Fill) 57 | .max_width(400) 58 | .max_height(600) 59 | .style(BorderedContainer), 60 | |state| { 61 | Button::new( 62 | state, 63 | Text::new(Icon::Plus) 64 | .width(Length::Shrink) 65 | .height(Length::Shrink) 66 | .font(ICON_FONT) 67 | .size(39), 68 | ) 69 | //.style(iced_aw::style::button::Primary), 70 | .on_press(Message::ButtonPressed) 71 | .padding(5) 72 | .style(RoundedButton) 73 | }, 74 | ) 75 | .anchor(floating_button::Anchor::SouthEast) 76 | .offset(20.0) 77 | .hide(false); 78 | 79 | Container::new(content) 80 | .width(Length::Fill) 81 | .height(Length::Fill) 82 | .padding(10) 83 | .center_x() 84 | .center_y() 85 | .into() 86 | } 87 | } 88 | 89 | struct RoundedButton; 90 | 91 | impl iced::button::StyleSheet for RoundedButton { 92 | fn active(&self) -> iced::button::Style { 93 | iced::button::Style { 94 | border_radius: 25.0, 95 | ..iced_aw::style::button::Primary.active() 96 | } 97 | } 98 | } 99 | 100 | struct BorderedContainer; 101 | 102 | impl iced::container::StyleSheet for BorderedContainer { 103 | fn style(&self) -> iced::container::Style { 104 | iced::container::Style { 105 | border_width: 1.0, 106 | border_color: iced::Color::BLACK, 107 | border_radius: 10.0, 108 | ..Default::default() 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/style/date_picker.rs: -------------------------------------------------------------------------------- 1 | //! Use a date picker as an input element for picking dates. 2 | //! 3 | //! *This API requires the following crate features to be activated: `date_picker`* 4 | #[cfg(not(target_arch = "wasm32"))] 5 | use iced_native::{Background, Color}; 6 | 7 | /// The appearance of a [`DatePicker`](crate::native::DatePicker). 8 | #[derive(Clone, Copy, Debug)] 9 | pub struct Style { 10 | /// The background of the [`DatePicker`](crate::native::DatePicker). 11 | pub background: Background, 12 | 13 | /// The border radius of the [`DatePicker`](crate::native::DatePicker). 14 | pub border_radius: f32, 15 | 16 | /// The border with of the [`DatePicker`](crate::native::DatePicker). 17 | pub border_width: f32, 18 | 19 | /// The border color of the [`DatePicker`](crate::native::DatePicker). 20 | pub border_color: Color, 21 | 22 | /// The text color of the [`DatePicker`](crate::native::DatePicker). 23 | pub text_color: Color, 24 | 25 | /// The attenuated color of the days which are not in the selected month 26 | /// of the [`DatePicker`](crate::native::DatePicker). 27 | pub text_attenuated_color: Color, 28 | 29 | /// The background of the days in the calender of the 30 | /// [`DatePicker`](crate::native::DatePicker). 31 | pub day_background: Background, 32 | } 33 | 34 | /// The appearance of a [`DatePicker`](crate::native::DatePicker). 35 | pub trait StyleSheet { 36 | /// The normal appearance of a [`DatePicker`](crate::native::DatePicker). 37 | fn active(&self) -> Style; 38 | 39 | /// The appearance when something is selected of the 40 | /// [`DatePicker`](crate::native::DatePicker). 41 | fn selected(&self) -> Style; 42 | 43 | /// The appearance when something is hovered of the 44 | /// [`DatePicker`](crate::native::DatePicker). 45 | fn hovered(&self) -> Style; 46 | 47 | /// The appearance when something is focused of the 48 | /// [`DatePicker`](crate::native::DatePicker). 49 | fn focused(&self) -> Style; 50 | } 51 | 52 | /// The default appearance of the [`DatePicker`](crate::native::DatePicker). 53 | #[derive(Clone, Copy, Debug)] 54 | pub struct Default; 55 | 56 | impl StyleSheet for Default { 57 | fn active(&self) -> Style { 58 | Style { 59 | background: Color::WHITE.into(), 60 | border_radius: 15.0, 61 | border_width: 1.0, 62 | border_color: Color::BLACK, 63 | text_color: Color::BLACK, 64 | text_attenuated_color: [0.87, 0.87, 0.87].into(), 65 | day_background: Color::WHITE.into(), 66 | } 67 | } 68 | 69 | fn selected(&self) -> Style { 70 | Style { 71 | day_background: Background::Color([0.87, 0.87, 0.87].into()), 72 | ..self.active() 73 | } 74 | } 75 | 76 | fn hovered(&self) -> Style { 77 | Style { 78 | day_background: Background::Color([0.87, 0.87, 0.87].into()), 79 | ..self.active() 80 | } 81 | } 82 | 83 | fn focused(&self) -> Style { 84 | Style { 85 | border_color: Color::from_rgb(0.5, 0.5, 0.5), 86 | ..self.active() 87 | } 88 | } 89 | } 90 | 91 | #[allow(clippy::use_self)] 92 | impl std::default::Default for Box { 93 | fn default() -> Self { 94 | Box::new(Default) 95 | } 96 | } 97 | 98 | #[allow(clippy::use_self)] 99 | impl From for Box 100 | where 101 | T: 'static + StyleSheet, 102 | { 103 | fn from(style: T) -> Self { 104 | Box::new(style) 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /examples/web/src/time_picker_section.rs: -------------------------------------------------------------------------------- 1 | use crate::Section; 2 | use iced::{button, Alignment, Button, Checkbox, Column, Element, Length, Row, Text}; 3 | use iced_aw::{time_picker, TimePicker}; 4 | 5 | pub struct TimePickerSection { 6 | time_picker_state: time_picker::State, 7 | button_state: button::State, 8 | time: time_picker::Time, 9 | show_seconds: bool, 10 | use_24h: bool, 11 | } 12 | 13 | #[derive(Clone, Debug)] 14 | pub enum Message { 15 | OpenTimePicker, 16 | CancelTime, 17 | SubmitTime(time_picker::Time), 18 | ToggleSeconds(bool), 19 | Toggle24h(bool), 20 | } 21 | 22 | impl Section for TimePickerSection { 23 | type Message = Message; 24 | 25 | fn new() -> Self { 26 | Self { 27 | time_picker_state: time_picker::State::now(), 28 | button_state: button::State::new(), 29 | time: time_picker::Time::default_hm(time_picker::Period::H24), 30 | show_seconds: false, 31 | use_24h: false, 32 | } 33 | } 34 | 35 | fn header(&self) -> String { 36 | String::from("Time Picker") 37 | } 38 | 39 | fn update(&mut self, message: Self::Message) { 40 | match message { 41 | Message::OpenTimePicker => self.time_picker_state.show(true), 42 | Message::CancelTime => self.time_picker_state.show(false), 43 | Message::SubmitTime(time) => { 44 | self.time = time; 45 | self.time_picker_state.show(false); 46 | } 47 | Message::ToggleSeconds(b) => { 48 | self.show_seconds = b; 49 | self.time_picker_state.reset(); 50 | } 51 | Message::Toggle24h(b) => { 52 | self.use_24h = b; 53 | self.time_picker_state.reset(); 54 | } 55 | } 56 | } 57 | 58 | fn content(&mut self) -> Element<'_, Self::Message> { 59 | let mut time_picker = TimePicker::new( 60 | &mut self.time_picker_state, 61 | Button::new(&mut self.button_state, Text::new("Pick Time")) 62 | .on_press(Message::OpenTimePicker), 63 | Message::CancelTime, 64 | Message::SubmitTime, 65 | ) 66 | //.use_24h() 67 | //.show_seconds() 68 | ; 69 | 70 | if self.show_seconds { 71 | time_picker = time_picker.show_seconds(); 72 | } 73 | if self.use_24h { 74 | time_picker = time_picker.use_24h(); 75 | } 76 | 77 | let column = Column::new() 78 | .align_items(Alignment::Center) 79 | .width(Length::Fill) 80 | .spacing(20) 81 | .push( 82 | Row::new() 83 | .width(Length::Fill) 84 | .spacing(40) 85 | .push(Checkbox::new( 86 | self.show_seconds, 87 | "Show seconds", 88 | Message::ToggleSeconds, 89 | )) 90 | .push(Checkbox::new( 91 | self.use_24h, 92 | "Use 24h format", 93 | Message::Toggle24h, 94 | )), 95 | ) 96 | .push( 97 | Row::new() 98 | .width(Length::Shrink) 99 | .align_items(Alignment::Center) 100 | .spacing(20) 101 | .push(time_picker) 102 | .push(Text::new(format!("Picked time: {}", self.time))), 103 | ); 104 | 105 | column.into() 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /images/concept_drawings/modal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 41 | 48 | 55 | 62 | 69 | 70 | 72 | 73 | 75 | image/svg+xml 76 | 78 | 79 | 80 | 81 | 82 | 87 | 95 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /examples/pure/number_input/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | pure::{ 3 | widget::{Container, Row, Text}, 4 | Element, Sandbox, 5 | }, 6 | window, Alignment, Length, Settings, 7 | }; 8 | use iced_aw::pure::number_input::NumberInput; 9 | 10 | #[derive(Default)] 11 | pub struct NumberInputDemo { 12 | value: f32, 13 | } 14 | 15 | #[derive(Debug, Clone)] 16 | pub enum Message { 17 | NumInpChanged(f32), 18 | } 19 | 20 | fn main() -> iced::Result { 21 | NumberInputDemo::run(Settings { 22 | default_text_size: 14, 23 | window: window::Settings { 24 | size: (250, 200), 25 | ..Default::default() 26 | }, 27 | ..Settings::default() 28 | }) 29 | } 30 | 31 | impl Sandbox for NumberInputDemo { 32 | type Message = Message; 33 | 34 | fn new() -> Self { 35 | Self { value: 27.0 } 36 | } 37 | 38 | fn title(&self) -> String { 39 | String::from("Number Input Demo") 40 | } 41 | 42 | fn update(&mut self, message: Message) { 43 | match message { 44 | Message::NumInpChanged(val) => { 45 | self.value = val; 46 | } 47 | } 48 | } 49 | 50 | fn view(&self) -> Element { 51 | let lb_minute = Text::new("Number Input:"); 52 | let txt_minute = NumberInput::new(self.value, 255.0, Message::NumInpChanged) 53 | .step(0.5) 54 | .min(1.0) 55 | .input_style(style::CustomTextInput) 56 | .style(style::CustomNumInput); 57 | 58 | Container::new( 59 | Row::new() 60 | .spacing(10) 61 | .align_items(Alignment::Center) 62 | .push(lb_minute) 63 | .push(txt_minute), 64 | ) 65 | .width(Length::Fill) 66 | .height(Length::Fill) 67 | .center_x() 68 | .center_y() 69 | .into() 70 | } 71 | } 72 | 73 | mod style { 74 | use iced::{text_input, Color}; 75 | use iced_aw::number_input; 76 | 77 | const BACKGROUND: Color = Color::from_rgb(238.0 / 255.0, 238.0 / 255.0, 238.0 / 255.0); 78 | const FOREGROUND: Color = Color::from_rgb(224.0 / 255.0, 224.0 / 255.0, 224.0 / 255.0); 79 | const HOVERED: Color = Color::from_rgb(129.0 / 255.0, 129.0 / 255.0, 129.0 / 255.0); 80 | const PRIMARY: Color = Color::from_rgb(12.0 / 255.0, 46.0 / 251.0, 179.0 / 255.0); 81 | 82 | pub struct CustomNumInput; 83 | impl number_input::StyleSheet for CustomNumInput { 84 | fn active(&self) -> number_input::Style { 85 | number_input::Style { 86 | icon_color: PRIMARY, 87 | ..number_input::Style::default() 88 | } 89 | } 90 | } 91 | 92 | pub struct CustomTextInput; 93 | impl text_input::StyleSheet for CustomTextInput { 94 | fn active(&self) -> text_input::Style { 95 | text_input::Style { 96 | background: BACKGROUND.into(), 97 | border_color: PRIMARY, 98 | border_width: 1.0, 99 | border_radius: 5.5, 100 | } 101 | } 102 | 103 | fn focused(&self) -> text_input::Style { 104 | let active = self.active(); 105 | 106 | text_input::Style { 107 | background: FOREGROUND.into(), 108 | ..active 109 | } 110 | } 111 | 112 | fn placeholder_color(&self) -> Color { 113 | HOVERED 114 | } 115 | 116 | fn selection_color(&self) -> Color { 117 | HOVERED 118 | } 119 | 120 | fn value_color(&self) -> Color { 121 | Color::BLACK 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /examples/number_input/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{window, Alignment, Container, Element, Length, Row, Sandbox, Settings, Text}; 2 | use iced_aw::number_input::{self, NumberInput}; 3 | 4 | #[derive(Default)] 5 | pub struct NumberInputDemo { 6 | state: number_input::State, 7 | value: f32, 8 | } 9 | 10 | #[derive(Debug, Clone)] 11 | pub enum Message { 12 | NumInpChanged(f32), 13 | } 14 | 15 | fn main() -> iced::Result { 16 | NumberInputDemo::run(Settings { 17 | default_text_size: 14, 18 | window: window::Settings { 19 | size: (250, 200), 20 | ..Default::default() 21 | }, 22 | ..Settings::default() 23 | }) 24 | } 25 | 26 | impl Sandbox for NumberInputDemo { 27 | type Message = Message; 28 | 29 | fn new() -> Self { 30 | Self { 31 | value: 27.0, 32 | ..Self::default() 33 | } 34 | } 35 | 36 | fn title(&self) -> String { 37 | String::from("Number Input Demo") 38 | } 39 | 40 | fn update(&mut self, message: Message) { 41 | match message { 42 | Message::NumInpChanged(val) => { 43 | self.value = val; 44 | } 45 | } 46 | } 47 | 48 | fn view(&mut self) -> Element { 49 | let lb_minute = Text::new("Number Input:"); 50 | let txt_minute = 51 | NumberInput::new(&mut self.state, self.value, 255.0, Message::NumInpChanged) 52 | .step(0.5) 53 | .min(1.0) 54 | .input_style(style::CustomTextInput) 55 | .style(style::CustomNumInput); 56 | 57 | Container::new( 58 | Row::new() 59 | .spacing(10) 60 | .align_items(Alignment::Center) 61 | .push(lb_minute) 62 | .push(txt_minute), 63 | ) 64 | .width(Length::Fill) 65 | .height(Length::Fill) 66 | .center_x() 67 | .center_y() 68 | .into() 69 | } 70 | } 71 | 72 | mod style { 73 | use iced::{text_input, Color}; 74 | use iced_aw::number_input; 75 | 76 | const BACKGROUND: Color = Color::from_rgb(238.0 / 255.0, 238.0 / 255.0, 238.0 / 255.0); 77 | const FOREGROUND: Color = Color::from_rgb(224.0 / 255.0, 224.0 / 255.0, 224.0 / 255.0); 78 | const HOVERED: Color = Color::from_rgb(129.0 / 255.0, 129.0 / 255.0, 129.0 / 255.0); 79 | const PRIMARY: Color = Color::from_rgb(12.0 / 255.0, 46.0 / 251.0, 179.0 / 255.0); 80 | 81 | pub struct CustomNumInput; 82 | impl number_input::StyleSheet for CustomNumInput { 83 | fn active(&self) -> number_input::Style { 84 | number_input::Style { 85 | icon_color: PRIMARY, 86 | ..number_input::Style::default() 87 | } 88 | } 89 | } 90 | 91 | pub struct CustomTextInput; 92 | impl text_input::StyleSheet for CustomTextInput { 93 | fn active(&self) -> text_input::Style { 94 | text_input::Style { 95 | background: BACKGROUND.into(), 96 | border_color: PRIMARY, 97 | border_width: 1.0, 98 | border_radius: 5.5, 99 | } 100 | } 101 | 102 | fn focused(&self) -> text_input::Style { 103 | let active = self.active(); 104 | 105 | text_input::Style { 106 | background: FOREGROUND.into(), 107 | ..active 108 | } 109 | } 110 | 111 | fn placeholder_color(&self) -> Color { 112 | HOVERED 113 | } 114 | 115 | fn selection_color(&self) -> Color { 116 | HOVERED 117 | } 118 | 119 | fn value_color(&self) -> Color { 120 | Color::BLACK 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /examples/pure/selection_list/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | pure::{ 3 | widget::{Column, Container, Space, Text}, 4 | Element, Sandbox, 5 | }, 6 | Alignment, Length, Settings, 7 | }; 8 | use iced_aw::pure::selection_list::SelectionList; 9 | use iced_aw::selection_list::{Style, StyleSheet}; 10 | 11 | #[derive(Clone, Copy, Debug)] 12 | pub struct CustomStyle; 13 | 14 | impl StyleSheet for CustomStyle { 15 | fn style() -> Style { 16 | Style { 17 | width: Length::Shrink, 18 | height: Length::Units(100), 19 | ..Default::default() 20 | } 21 | } 22 | } 23 | 24 | pub fn main() -> iced::Result { 25 | Example::run(Settings::default()) 26 | } 27 | 28 | #[derive(Default)] 29 | struct Example { 30 | vec: Vec, 31 | selected_language: String, 32 | } 33 | 34 | #[derive(Debug, Clone)] 35 | enum Message { 36 | LanguageSelected(String), 37 | } 38 | 39 | impl Sandbox for Example { 40 | type Message = Message; 41 | 42 | fn new() -> Self { 43 | let mut vec = Vec::with_capacity(10); 44 | 45 | for i in Language::ALL.iter() { 46 | vec.push(format!("{:?}", i)) 47 | } 48 | 49 | Self { 50 | vec, 51 | ..Default::default() 52 | } 53 | } 54 | 55 | fn title(&self) -> String { 56 | String::from("Selection list - Iced") 57 | } 58 | 59 | fn update(&mut self, message: Message) { 60 | match message { 61 | Message::LanguageSelected(language) => { 62 | self.selected_language = language.clone(); 63 | 64 | if language == "Rust" { 65 | self.vec.push("Rusty".into()); 66 | } 67 | } 68 | } 69 | } 70 | 71 | fn view(&self) -> Element { 72 | let selection_list = SelectionList::new( 73 | &self.vec[..], 74 | Message::LanguageSelected, 75 | CustomStyle::style(), 76 | ); 77 | 78 | let mut content = Column::new() 79 | .width(Length::Fill) 80 | .align_items(Alignment::Center) 81 | .spacing(10) 82 | .push(selection_list) 83 | .push(Text::new("Which is your favorite language?")) 84 | .push(Text::new(format!("{:?}", self.selected_language))); 85 | 86 | content = content.push(Space::with_height(Length::Units(600))); 87 | 88 | Container::new(content) 89 | .width(Length::Fill) 90 | .height(Length::Fill) 91 | .center_x() 92 | .center_y() 93 | .into() 94 | } 95 | } 96 | 97 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] 98 | pub enum Language { 99 | Rust, 100 | Elm, 101 | Ruby, 102 | Haskell, 103 | C, 104 | Javascript, 105 | Other, 106 | } 107 | 108 | impl Language { 109 | const ALL: [Language; 7] = [ 110 | Language::C, 111 | Language::Elm, 112 | Language::Ruby, 113 | Language::Haskell, 114 | Language::Rust, 115 | Language::Javascript, 116 | Language::Other, 117 | ]; 118 | } 119 | 120 | impl Default for Language { 121 | fn default() -> Language { 122 | Language::Rust 123 | } 124 | } 125 | 126 | impl std::fmt::Display for Language { 127 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 128 | write!( 129 | f, 130 | "{}", 131 | match self { 132 | Language::Rust => "Rust", 133 | Language::Elm => "Elm", 134 | Language::Ruby => "Ruby", 135 | Language::Haskell => "Haskell", 136 | Language::C => "C", 137 | Language::Javascript => "Javascript", 138 | Language::Other => "Some other language", 139 | } 140 | ) 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /examples/selection_list/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{Alignment, Column, Container, Element, Length, Sandbox, Settings, Space, Text}; 2 | use iced_aw::selection_list::{self, SelectionList, Style, StyleSheet}; 3 | 4 | #[derive(Clone, Copy, Debug)] 5 | pub struct CustomStyle; 6 | 7 | impl StyleSheet for CustomStyle { 8 | fn style() -> Style { 9 | Style { 10 | width: Length::Shrink, 11 | height: Length::Units(100), 12 | ..Default::default() 13 | } 14 | } 15 | } 16 | 17 | pub fn main() -> iced::Result { 18 | Example::run(Settings::default()) 19 | } 20 | 21 | #[derive(Default)] 22 | struct Example { 23 | vec: Vec, 24 | selection_list: selection_list::State, 25 | selected_language: String, 26 | } 27 | 28 | #[derive(Debug, Clone)] 29 | enum Message { 30 | LanguageSelected(String), 31 | } 32 | 33 | impl Sandbox for Example { 34 | type Message = Message; 35 | 36 | fn new() -> Self { 37 | let mut vec = Vec::with_capacity(10); 38 | 39 | for i in Language::ALL.iter() { 40 | vec.push(format!("{:?}", i)) 41 | } 42 | 43 | Self { 44 | vec, 45 | ..Default::default() 46 | } 47 | } 48 | 49 | fn title(&self) -> String { 50 | String::from("Selection list - Iced") 51 | } 52 | 53 | fn update(&mut self, message: Message) { 54 | match message { 55 | Message::LanguageSelected(language) => { 56 | self.selected_language = language.clone(); 57 | 58 | if language == "Rust" { 59 | self.vec.push("Rusty".into()); 60 | } 61 | } 62 | } 63 | } 64 | 65 | fn view(&mut self) -> Element { 66 | let selection_list = SelectionList::new( 67 | &mut self.selection_list, 68 | &self.vec[..], 69 | &Some(self.selected_language.clone()), 70 | Message::LanguageSelected, 71 | CustomStyle::style(), 72 | ); 73 | 74 | let mut content = Column::new() 75 | .width(Length::Fill) 76 | .align_items(Alignment::Center) 77 | .spacing(10) 78 | .push(selection_list) 79 | .push(Text::new("Which is your favorite language?")) 80 | .push(Text::new(format!("{:?}", self.selected_language))); 81 | 82 | content = content.push(Space::with_height(Length::Units(600))); 83 | 84 | Container::new(content) 85 | .width(Length::Fill) 86 | .height(Length::Fill) 87 | .center_x() 88 | .center_y() 89 | .into() 90 | } 91 | } 92 | 93 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] 94 | pub enum Language { 95 | Rust, 96 | Elm, 97 | Ruby, 98 | Haskell, 99 | C, 100 | Javascript, 101 | Other, 102 | } 103 | 104 | impl Language { 105 | const ALL: [Language; 7] = [ 106 | Language::C, 107 | Language::Elm, 108 | Language::Ruby, 109 | Language::Haskell, 110 | Language::Rust, 111 | Language::Javascript, 112 | Language::Other, 113 | ]; 114 | } 115 | 116 | impl Default for Language { 117 | fn default() -> Language { 118 | Language::Rust 119 | } 120 | } 121 | 122 | impl std::fmt::Display for Language { 123 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 124 | write!( 125 | f, 126 | "{}", 127 | match self { 128 | Language::Rust => "Rust", 129 | Language::Elm => "Elm", 130 | Language::Ruby => "Ruby", 131 | Language::Haskell => "Haskell", 132 | Language::C => "C", 133 | Language::Javascript => "Javascript", 134 | Language::Other => "Some other language", 135 | } 136 | ) 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Additional widgets for the Iced GUI library. 2 | #![deny(missing_docs)] 3 | #![deny(missing_debug_implementations)] 4 | #![deny(unused_results)] 5 | #![forbid(unsafe_code)] 6 | #![warn( 7 | clippy::pedantic, 8 | clippy::nursery, 9 | 10 | // Restriction lints 11 | clippy::clone_on_ref_ptr, 12 | clippy::create_dir, 13 | clippy::dbg_macro, 14 | clippy::decimal_literal_representation, 15 | clippy::exit, 16 | clippy::float_cmp_const, 17 | clippy::get_unwrap, 18 | clippy::let_underscore_must_use, 19 | clippy::map_err_ignore, 20 | clippy::mem_forget, 21 | clippy::missing_docs_in_private_items, 22 | clippy::multiple_inherent_impl, 23 | clippy::panic, 24 | clippy::panic_in_result_fn, 25 | clippy::print_stderr, 26 | clippy::print_stdout, 27 | clippy::rest_pat_in_fully_bound_structs, 28 | clippy::str_to_string, 29 | clippy::string_to_string, 30 | clippy::todo, 31 | clippy::unimplemented, 32 | clippy::unneeded_field_pattern, 33 | clippy::unwrap_in_result, 34 | clippy::unwrap_used, 35 | clippy::use_debug, 36 | )] 37 | #![allow( 38 | clippy::suboptimal_flops, 39 | clippy::cast_possible_truncation, 40 | clippy::cast_sign_loss, 41 | clippy::cast_possible_wrap, 42 | clippy::module_name_repetitions, 43 | clippy::borrowed_box, 44 | clippy::missing_const_for_fn, 45 | clippy::too_many_lines 46 | )] 47 | 48 | #[cfg(not(target_arch = "wasm32"))] 49 | pub mod graphics; 50 | #[cfg(not(target_arch = "wasm32"))] 51 | pub mod native; 52 | 53 | pub mod core; 54 | pub mod style; 55 | 56 | #[cfg(not(target_arch = "wasm32"))] 57 | /// Exports for all platforms that are not WASM32. 58 | mod platform { 59 | #[doc(no_inline)] 60 | #[cfg(feature = "icons")] 61 | pub use {crate::graphics::icons::Icon, crate::graphics::icons::ICON_FONT}; 62 | 63 | #[doc(no_inline)] 64 | #[cfg(feature = "badge")] 65 | pub use {crate::graphics::badge, badge::Badge}; 66 | 67 | #[doc(no_inline)] 68 | #[cfg(feature = "card")] 69 | pub use {crate::graphics::card, card::Card}; 70 | 71 | #[doc(no_inline)] 72 | #[cfg(feature = "color_picker")] 73 | pub use {crate::graphics::color_picker, color_picker::ColorPicker}; 74 | 75 | #[doc(no_inline)] 76 | #[cfg(feature = "date_picker")] 77 | pub use {crate::graphics::date_picker, date_picker::DatePicker}; 78 | 79 | #[doc(no_inline)] 80 | #[cfg(feature = "floating_button")] 81 | pub use {crate::graphics::floating_button, floating_button::FloatingButton}; 82 | 83 | #[doc(no_inline)] 84 | #[cfg(feature = "grid")] 85 | pub use {crate::graphics::grid, grid::Grid}; 86 | 87 | #[doc(no_inline)] 88 | #[cfg(feature = "modal")] 89 | pub use {crate::graphics::modal, modal::Modal}; 90 | 91 | #[doc(no_inline)] 92 | #[cfg(feature = "tab_bar")] 93 | pub use { 94 | crate::graphics::tab_bar, 95 | tab_bar::{TabBar, TabLabel}, 96 | }; 97 | 98 | #[doc(no_inline)] 99 | #[cfg(feature = "tabs")] 100 | pub use { 101 | crate::graphics::tabs, 102 | tabs::{TabBarPosition, Tabs}, 103 | }; 104 | 105 | #[doc(no_inline)] 106 | #[cfg(feature = "time_picker")] 107 | pub use {crate::graphics::time_picker, time_picker::TimePicker}; 108 | 109 | #[doc(no_inline)] 110 | #[cfg(feature = "wrap")] 111 | pub use {crate::graphics::wrap, wrap::Wrap}; 112 | 113 | #[doc(no_inline)] 114 | #[cfg(feature = "number_input")] 115 | pub use {crate::graphics::number_input, number_input::NumberInput}; 116 | 117 | #[doc(no_inline)] 118 | #[cfg(feature = "selection_list")] 119 | pub use {crate::graphics::selection_list, selection_list::SelectionList}; 120 | 121 | #[doc(no_inline)] 122 | #[cfg(feature = "split")] 123 | pub use {crate::graphics::split, split::Split}; 124 | } 125 | 126 | #[doc(no_inline)] 127 | pub use platform::*; 128 | 129 | #[cfg(feature = "pure")] 130 | pub mod pure; 131 | -------------------------------------------------------------------------------- /examples/tabs/src/settings.rs: -------------------------------------------------------------------------------- 1 | use crate::{theme::Theme, Icon, Message, Tab}; 2 | use iced::{Column, Container, Element, Radio, Text}; 3 | use iced_aw::TabLabel; 4 | 5 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] 6 | pub enum TabBarPosition { 7 | Top, 8 | Bottom, 9 | } 10 | 11 | impl TabBarPosition { 12 | pub const ALL: [TabBarPosition; 2] = [TabBarPosition::Top, TabBarPosition::Bottom]; 13 | } 14 | 15 | impl From for String { 16 | fn from(position: TabBarPosition) -> Self { 17 | String::from(match position { 18 | TabBarPosition::Top => "Top", 19 | TabBarPosition::Bottom => "Bottom", 20 | }) 21 | } 22 | } 23 | 24 | impl Default for TabBarPosition { 25 | fn default() -> Self { 26 | TabBarPosition::Top 27 | } 28 | } 29 | 30 | //#[derive(Debug, Clone, Copy, PartialEq, Eq)] 31 | 32 | pub struct TabSettings { 33 | pub tab_bar_position: Option, 34 | pub tab_bar_theme: Option, 35 | } 36 | 37 | impl TabSettings { 38 | pub fn new() -> Self { 39 | TabSettings { 40 | tab_bar_position: Some(TabBarPosition::Top), 41 | tab_bar_theme: Some(Theme::default()), 42 | } 43 | } 44 | } 45 | 46 | #[derive(Debug, Clone)] 47 | pub enum SettingsMessage { 48 | PositionSelected(TabBarPosition), 49 | ThemeSelected(Theme), 50 | } 51 | 52 | pub struct SettingsTab { 53 | settings: TabSettings, 54 | } 55 | 56 | impl SettingsTab { 57 | pub fn new() -> Self { 58 | SettingsTab { 59 | settings: TabSettings::new(), 60 | } 61 | } 62 | 63 | pub fn settings(&mut self) -> &mut TabSettings { 64 | &mut self.settings 65 | } 66 | 67 | pub fn update(&mut self, message: SettingsMessage) { 68 | match message { 69 | SettingsMessage::PositionSelected(position) => { 70 | self.settings().tab_bar_position = Some(position) 71 | } 72 | SettingsMessage::ThemeSelected(theme) => self.settings().tab_bar_theme = Some(theme), 73 | } 74 | } 75 | } 76 | 77 | impl Tab for SettingsTab { 78 | type Message = Message; 79 | 80 | fn title(&self) -> String { 81 | String::from("Settings") 82 | } 83 | 84 | fn tab_label(&self) -> TabLabel { 85 | //TabLabel::Text(self.title()) 86 | TabLabel::IconText(Icon::CogAlt.into(), self.title()) 87 | } 88 | 89 | fn content(&mut self) -> Element<'_, Self::Message> { 90 | let content: Element<'_, SettingsMessage> = Container::new( 91 | Column::new() 92 | .push(Text::new("TabBar position:").size(20)) 93 | .push(TabBarPosition::ALL.iter().cloned().fold( 94 | Column::new().padding(10).spacing(10), 95 | |column, position| { 96 | column.push( 97 | Radio::new( 98 | position, 99 | position, 100 | self.settings().tab_bar_position, 101 | SettingsMessage::PositionSelected, 102 | ) 103 | .size(16), 104 | ) 105 | }, 106 | )) 107 | .push(Text::new("TabBar color:").size(20)) 108 | .push(Theme::ALL.iter().cloned().fold( 109 | Column::new().padding(10).spacing(10), 110 | |column, theme| { 111 | column.push( 112 | Radio::new( 113 | theme, 114 | theme, 115 | self.settings().tab_bar_theme, 116 | SettingsMessage::ThemeSelected, 117 | ) 118 | .size(16), 119 | ) 120 | }, 121 | )), 122 | ) 123 | .into(); 124 | 125 | content.map(Message::Settings) 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /examples/pure/modal/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | alignment::Horizontal, 3 | pure::{ 4 | widget::{Button, Container, Row, Text}, 5 | Element, Sandbox, 6 | }, 7 | Alignment, Length, Settings, 8 | }; 9 | 10 | use iced_aw::pure::{Card, Modal}; 11 | 12 | fn main() -> iced::Result { 13 | ModalExample::run(Settings::default()) 14 | } 15 | 16 | #[derive(Clone, Debug)] 17 | enum Message { 18 | OpenModal, 19 | CloseModal, 20 | CancelButtonPressed, 21 | OkButtonPressed, 22 | } 23 | 24 | #[derive(Default)] 25 | struct ModalExample { 26 | show_modal: bool, 27 | last_message: Option, 28 | } 29 | 30 | impl Sandbox for ModalExample { 31 | type Message = Message; 32 | 33 | fn new() -> Self { 34 | Self::default() 35 | } 36 | 37 | fn title(&self) -> String { 38 | String::from("Modal example") 39 | } 40 | 41 | fn update(&mut self, message: Self::Message) { 42 | match message { 43 | Message::OpenModal => self.show_modal = true, 44 | Message::CloseModal => self.show_modal = false, 45 | Message::CancelButtonPressed => self.show_modal = false, 46 | Message::OkButtonPressed => self.show_modal = false, 47 | } 48 | self.last_message = Some(message) 49 | } 50 | 51 | fn view(&self) -> Element<'_, Self::Message> { 52 | let content = Container::new( 53 | Row::new() 54 | .spacing(10) 55 | .align_items(Alignment::Center) 56 | .push(Button::new(Text::new("Open modal!")).on_press(Message::OpenModal)) 57 | .push(Text::new(format!( 58 | "Last message: {}", 59 | match self.last_message.as_ref() { 60 | Some(message) => match message { 61 | Message::OpenModal => "Modal opened", 62 | Message::CloseModal => "Modal closed", 63 | Message::CancelButtonPressed => "Modal canceled", 64 | Message::OkButtonPressed => "Modal accepted", 65 | }, 66 | None => "None", 67 | } 68 | ))), 69 | ); 70 | 71 | Modal::new(self.show_modal, content, || { 72 | Card::new( 73 | Text::new("My modal"), 74 | Text::new("This is a modal!"), //Text::new("Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit​​, morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. Qui animated corpse, cricket bat max brucks terribilem incessu zomby. The voodoo sacerdos flesh eater, suscitat mortuos comedere carnem virus. Zonbi tattered for solum oculi eorum defunctis go lum cerebro. Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.") 75 | ) 76 | .foot( 77 | Row::new() 78 | .spacing(10) 79 | .padding(5) 80 | .width(Length::Fill) 81 | .push( 82 | Button::new(Text::new("Cancel").horizontal_alignment(Horizontal::Center)) 83 | .width(Length::Fill) 84 | .on_press(Message::CancelButtonPressed), 85 | ) 86 | .push( 87 | Button::new(Text::new("Ok").horizontal_alignment(Horizontal::Center)) 88 | .width(Length::Fill) 89 | .on_press(Message::OkButtonPressed), 90 | ), 91 | ) 92 | .max_width(300) 93 | //.width(Length::Shrink) 94 | .on_close(Message::CloseModal) 95 | .into() 96 | }) 97 | .backdrop(Message::CloseModal) 98 | .on_esc(Message::CloseModal) 99 | .into() 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/style/time_picker.rs: -------------------------------------------------------------------------------- 1 | //! Use a time picker as an input element for picking times. 2 | //! 3 | //! *This API requires the following crate features to be activated: `time_picker`* 4 | #[cfg(not(target_arch = "wasm32"))] 5 | use iced_native::{Background, Color}; 6 | 7 | /// The appearance of a [`TimePicker`](crate::native::TimePicker). 8 | #[derive(Clone, Copy, Debug)] 9 | pub struct Style { 10 | /// The background of the [`TimePicker`](crate::native::TimePicker). 11 | pub background: Background, 12 | 13 | /// The border radius of the [`TimePicker`](crate::native::TimePicker). 14 | pub border_radius: f32, 15 | 16 | /// The border width of the [`TimePicker`](crate::native::TimePicker). 17 | pub border_width: f32, 18 | 19 | /// The border color of the [`TimePicker`](crate::native::TimePicker). 20 | pub border_color: Color, 21 | 22 | /// The text color of the [`TimePicker`](crate::native::TimePicker). 23 | pub text_color: Color, 24 | 25 | /// The color of the clock numbers of the 26 | /// [`TimePicker`](crate::native::TimePicker). 27 | pub clock_number_color: Color, 28 | 29 | /// The background of the clock numbers of the 30 | /// [`TimePicker`](crate::native::TimePicker). 31 | pub clock_number_background: Color, 32 | 33 | /// The color of the dots on the clock of the 34 | /// [`TimePicker`](crate::native::TimePicker). 35 | pub clock_dots_color: Color, 36 | 37 | /// The color of the hands of the clock of the 38 | /// [`TimePicker`](crate::native::TimePicker). 39 | pub clock_hand_color: Color, 40 | 41 | /// The with of the hands of the clock of the 42 | /// [`TimePicker](crate::native::TimePicker). 43 | pub clock_hand_width: f32, 44 | } 45 | 46 | /// The appearance of a [`TimePicker`](crate::native::TimePicker). 47 | pub trait StyleSheet { 48 | /// The normal appearance of a [`TimePicker`](crate::native::TimePicker). 49 | fn active(&self) -> Style; 50 | 51 | /// The appearance when something is selected of the 52 | /// [`TimePicker`](crate::native::TimePicker) 53 | fn selected(&self) -> Style; 54 | 55 | /// The appearance when something is hovered of the 56 | /// [`TimePicker`](crate::native::TimePicker). 57 | fn hovered(&self) -> Style; 58 | 59 | /// The appearance when something is focused of the 60 | /// [`TimePicker`](crate::native::TimePicker). 61 | fn focused(&self) -> Style; 62 | } 63 | 64 | /// The default appearance of the [`TimePicker`](crate::native::TimePicker) 65 | #[derive(Clone, Copy, Debug)] 66 | pub struct Default; 67 | 68 | impl StyleSheet for Default { 69 | fn active(&self) -> Style { 70 | Style { 71 | background: Color::WHITE.into(), 72 | border_radius: 15.0, 73 | border_width: 1.0, 74 | border_color: Color::BLACK, 75 | text_color: Color::BLACK, 76 | clock_number_color: Color::BLACK, 77 | clock_number_background: Color::WHITE, 78 | clock_dots_color: [0.87, 0.87, 0.87].into(), 79 | clock_hand_color: [0.87, 0.87, 0.87].into(), 80 | clock_hand_width: 1.0, 81 | } 82 | } 83 | 84 | fn selected(&self) -> Style { 85 | Style { 86 | clock_number_background: [0.87, 0.87, 0.87].into(), 87 | ..self.active() 88 | } 89 | } 90 | 91 | fn hovered(&self) -> Style { 92 | Style { 93 | clock_number_background: [0.87, 0.87, 0.87].into(), 94 | ..self.active() 95 | } 96 | } 97 | 98 | fn focused(&self) -> Style { 99 | Style { 100 | border_color: Color::from_rgb(0.5, 0.5, 0.5), 101 | ..self.active() 102 | } 103 | } 104 | } 105 | 106 | #[allow(clippy::use_self)] 107 | impl std::default::Default for Box { 108 | fn default() -> Self { 109 | Box::new(Default) 110 | } 111 | } 112 | 113 | #[allow(clippy::use_self)] 114 | impl From for Box 115 | where 116 | T: 'static + StyleSheet, 117 | { 118 | fn from(style: T) -> Self { 119 | Box::new(style) 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /examples/pure/tabs/src/settings.rs: -------------------------------------------------------------------------------- 1 | use crate::{theme::Theme, Icon, Message, Tab}; 2 | use iced::pure::{ 3 | widget::{Column, Container, Radio, Text}, 4 | Element, 5 | }; 6 | use iced_aw::pure::tab_bar::TabLabel; 7 | 8 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] 9 | pub enum TabBarPosition { 10 | Top, 11 | Bottom, 12 | } 13 | 14 | impl TabBarPosition { 15 | pub const ALL: [TabBarPosition; 2] = [TabBarPosition::Top, TabBarPosition::Bottom]; 16 | } 17 | 18 | impl From for String { 19 | fn from(position: TabBarPosition) -> Self { 20 | String::from(match position { 21 | TabBarPosition::Top => "Top", 22 | TabBarPosition::Bottom => "Bottom", 23 | }) 24 | } 25 | } 26 | 27 | impl Default for TabBarPosition { 28 | fn default() -> Self { 29 | TabBarPosition::Top 30 | } 31 | } 32 | 33 | //#[derive(Debug, Clone, Copy, PartialEq, Eq)] 34 | 35 | pub struct TabSettings { 36 | pub tab_bar_position: Option, 37 | pub tab_bar_theme: Option, 38 | } 39 | 40 | impl TabSettings { 41 | pub fn new() -> Self { 42 | TabSettings { 43 | tab_bar_position: Some(TabBarPosition::Top), 44 | tab_bar_theme: Some(Theme::default()), 45 | } 46 | } 47 | } 48 | 49 | #[derive(Debug, Clone)] 50 | pub enum SettingsMessage { 51 | PositionSelected(TabBarPosition), 52 | ThemeSelected(Theme), 53 | } 54 | 55 | pub struct SettingsTab { 56 | settings: TabSettings, 57 | } 58 | 59 | impl SettingsTab { 60 | pub fn new() -> Self { 61 | SettingsTab { 62 | settings: TabSettings::new(), 63 | } 64 | } 65 | 66 | pub fn settings(&self) -> &TabSettings { 67 | &self.settings 68 | } 69 | 70 | pub fn update(&mut self, message: SettingsMessage) { 71 | match message { 72 | SettingsMessage::PositionSelected(position) => { 73 | self.settings.tab_bar_position = Some(position) 74 | } 75 | SettingsMessage::ThemeSelected(theme) => self.settings.tab_bar_theme = Some(theme), 76 | } 77 | } 78 | } 79 | 80 | impl Tab for SettingsTab { 81 | type Message = Message; 82 | 83 | fn title(&self) -> String { 84 | String::from("Settings") 85 | } 86 | 87 | fn tab_label(&self) -> TabLabel { 88 | //TabLabel::Text(self.title()) 89 | TabLabel::IconText(Icon::CogAlt.into(), self.title()) 90 | } 91 | 92 | fn content(&self) -> Element<'_, Self::Message> { 93 | let content: Element<'_, SettingsMessage> = Container::new( 94 | Column::new() 95 | .push(Text::new("TabBar position:").size(20)) 96 | .push(TabBarPosition::ALL.iter().cloned().fold( 97 | Column::new().padding(10).spacing(10), 98 | |column, position| { 99 | column.push( 100 | Radio::new( 101 | position, 102 | position, 103 | self.settings().tab_bar_position, 104 | SettingsMessage::PositionSelected, 105 | ) 106 | .size(16), 107 | ) 108 | }, 109 | )) 110 | .push(Text::new("TabBar color:").size(20)) 111 | .push(Theme::ALL.iter().cloned().fold( 112 | Column::new().padding(10).spacing(10), 113 | |column, theme| { 114 | column.push( 115 | Radio::new( 116 | theme, 117 | theme, 118 | self.settings().tab_bar_theme, 119 | SettingsMessage::ThemeSelected, 120 | ) 121 | .size(16), 122 | ) 123 | }, 124 | )), 125 | ) 126 | .into(); 127 | 128 | content.map(Message::Settings) 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /examples/tabs/src/login.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | alignment::{Alignment, Horizontal, Vertical}, 3 | button, text_input, Button, Column, Container, Element, Length, Row, Text, TextInput, 4 | }; 5 | use iced_aw::TabLabel; 6 | 7 | use crate::{Icon, Message, Tab}; 8 | 9 | #[derive(Debug, Clone)] 10 | pub enum LoginMessage { 11 | UsernameChanged(String), 12 | PasswordChanged(String), 13 | ClearPressed, 14 | LoginPressed, 15 | } 16 | 17 | pub struct LoginTab { 18 | username: String, 19 | username_state: text_input::State, 20 | password: String, 21 | password_state: text_input::State, 22 | clear_button: button::State, 23 | login_button: button::State, 24 | } 25 | 26 | impl LoginTab { 27 | pub fn new() -> Self { 28 | LoginTab { 29 | username: String::new(), 30 | username_state: text_input::State::default(), 31 | password: String::new(), 32 | password_state: text_input::State::default(), 33 | clear_button: button::State::default(), 34 | login_button: button::State::default(), 35 | } 36 | } 37 | 38 | pub fn update(&mut self, message: LoginMessage) { 39 | match message { 40 | LoginMessage::UsernameChanged(value) => self.username = value, 41 | LoginMessage::PasswordChanged(value) => self.password = value, 42 | LoginMessage::ClearPressed => { 43 | self.username = String::new(); 44 | self.password = String::new(); 45 | } 46 | LoginMessage::LoginPressed => {} 47 | } 48 | } 49 | } 50 | 51 | impl Tab for LoginTab { 52 | type Message = Message; 53 | 54 | fn title(&self) -> String { 55 | String::from("Login") 56 | } 57 | 58 | fn tab_label(&self) -> TabLabel { 59 | //TabLabel::Text(self.title()) 60 | TabLabel::IconText(Icon::User.into(), self.title()) 61 | } 62 | 63 | fn content(&mut self) -> Element<'_, Self::Message> { 64 | let content: Element<'_, LoginMessage> = Container::new( 65 | Column::new() 66 | .align_items(Alignment::Center) 67 | .max_width(600) 68 | .padding(20) 69 | .spacing(16) 70 | .push( 71 | TextInput::new( 72 | &mut self.username_state, 73 | "Username", 74 | &self.username, 75 | LoginMessage::UsernameChanged, 76 | ) 77 | .padding(10) 78 | .size(32), 79 | ) 80 | .push( 81 | TextInput::new( 82 | &mut self.password_state, 83 | "Password", 84 | &self.password, 85 | LoginMessage::PasswordChanged, 86 | ) 87 | .padding(10) 88 | .size(32) 89 | .password(), 90 | ) 91 | .push( 92 | Row::new() 93 | .spacing(10) 94 | .push( 95 | Button::new( 96 | &mut self.clear_button, 97 | Text::new("Clear").horizontal_alignment(Horizontal::Center), 98 | ) 99 | .width(Length::Fill) 100 | .on_press(LoginMessage::ClearPressed), 101 | ) 102 | .push( 103 | Button::new( 104 | &mut self.login_button, 105 | Text::new("Login").horizontal_alignment(Horizontal::Center), 106 | ) 107 | .width(Length::Fill) 108 | .on_press(LoginMessage::LoginPressed), 109 | ), 110 | ), 111 | ) 112 | .align_x(Horizontal::Center) 113 | .align_y(Vertical::Center) 114 | .into(); 115 | 116 | content.map(Message::Login) 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /images/concept_drawings/floating_action_button.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 41 | 48 | 55 | 62 | 69 | 70 | 72 | 73 | 75 | image/svg+xml 76 | 78 | 79 | 80 | 81 | 82 | 87 | 94 | + 105 | 106 | 107 | -------------------------------------------------------------------------------- /examples/tabs/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | alignment::{Horizontal, Vertical}, 3 | Column, Container, Element, Font, Length, Sandbox, Settings, Text, 4 | }; 5 | 6 | use iced_aw::{TabLabel, Tabs}; 7 | 8 | mod login; 9 | use login::{LoginMessage, LoginTab}; 10 | 11 | mod ferris; 12 | use ferris::{FerrisMessage, FerrisTab}; 13 | 14 | mod counter; 15 | use counter::{CounterMessage, CounterTab}; 16 | 17 | mod settings; 18 | use settings::{SettingsMessage, SettingsTab, TabBarPosition}; 19 | 20 | mod theme; 21 | 22 | const HEADER_SIZE: u16 = 32; 23 | const TAB_PADDING: u16 = 16; 24 | 25 | const ICON_FONT: Font = iced::Font::External { 26 | name: "Icons", 27 | bytes: include_bytes!("../fonts/icons.ttf"), 28 | }; 29 | 30 | enum Icon { 31 | User, 32 | Heart, 33 | Calc, 34 | CogAlt, 35 | } 36 | 37 | impl From for char { 38 | fn from(icon: Icon) -> Self { 39 | match icon { 40 | Icon::User => '\u{E800}', 41 | Icon::Heart => '\u{E801}', 42 | Icon::Calc => '\u{F1EC}', 43 | Icon::CogAlt => '\u{E802}', 44 | } 45 | } 46 | } 47 | 48 | fn main() -> iced::Result { 49 | TabBarExample::run(Settings::default()) 50 | } 51 | 52 | struct TabBarExample { 53 | active_tab: usize, 54 | login_tab: LoginTab, 55 | ferris_tab: FerrisTab, 56 | counter_tab: CounterTab, 57 | settings_tab: SettingsTab, 58 | } 59 | 60 | #[derive(Clone, Debug)] 61 | enum Message { 62 | TabSelected(usize), 63 | Login(LoginMessage), 64 | Ferris(FerrisMessage), 65 | Counter(CounterMessage), 66 | Settings(SettingsMessage), 67 | } 68 | 69 | impl Sandbox for TabBarExample { 70 | type Message = Message; 71 | 72 | fn new() -> Self { 73 | TabBarExample { 74 | active_tab: 0, 75 | login_tab: LoginTab::new(), 76 | ferris_tab: FerrisTab::new(), 77 | counter_tab: CounterTab::new(), 78 | settings_tab: SettingsTab::new(), 79 | } 80 | } 81 | 82 | fn title(&self) -> String { 83 | String::from("TabBar Example") 84 | } 85 | 86 | fn update(&mut self, message: Self::Message) { 87 | match message { 88 | Message::TabSelected(selected) => self.active_tab = selected, 89 | Message::Login(message) => self.login_tab.update(message), 90 | Message::Ferris(message) => self.ferris_tab.update(message), 91 | Message::Counter(message) => self.counter_tab.update(message), 92 | Message::Settings(message) => self.settings_tab.update(message), 93 | } 94 | } 95 | 96 | fn view(&mut self) -> Element<'_, Self::Message> { 97 | let position = self 98 | .settings_tab 99 | .settings() 100 | .tab_bar_position 101 | .unwrap_or_default(); 102 | let theme = self 103 | .settings_tab 104 | .settings() 105 | .tab_bar_theme 106 | .unwrap_or_default(); 107 | 108 | Tabs::new(self.active_tab, Message::TabSelected) 109 | .push(self.login_tab.tab_label(), self.login_tab.view()) 110 | .push(self.ferris_tab.tab_label(), self.ferris_tab.view()) 111 | .push(self.counter_tab.tab_label(), self.counter_tab.view()) 112 | .push(self.settings_tab.tab_label(), self.settings_tab.view()) 113 | .tab_bar_style(theme) 114 | .icon_font(ICON_FONT) 115 | .tab_bar_position(match position { 116 | TabBarPosition::Top => iced_aw::TabBarPosition::Top, 117 | TabBarPosition::Bottom => iced_aw::TabBarPosition::Bottom, 118 | }) 119 | .into() 120 | } 121 | } 122 | 123 | trait Tab { 124 | type Message; 125 | 126 | fn title(&self) -> String; 127 | 128 | fn tab_label(&self) -> TabLabel; 129 | 130 | fn view(&mut self) -> Element<'_, Self::Message> { 131 | let column = Column::new() 132 | .spacing(20) 133 | .push(Text::new(self.title()).size(HEADER_SIZE)) 134 | .push(self.content()); 135 | 136 | Container::new(column) 137 | .width(Length::Fill) 138 | .height(Length::Fill) 139 | .align_x(Horizontal::Center) 140 | .align_y(Vertical::Center) 141 | .padding(TAB_PADDING) 142 | .into() 143 | } 144 | 145 | fn content(&mut self) -> Element<'_, Self::Message>; 146 | } 147 | -------------------------------------------------------------------------------- /examples/pure/tabs/src/main.rs: -------------------------------------------------------------------------------- 1 | mod login; 2 | use iced::{ 3 | alignment::{Horizontal, Vertical}, 4 | pure::{ 5 | widget::{Column, Container, Text}, 6 | Element, Sandbox, 7 | }, 8 | Font, Length, Settings, 9 | }; 10 | use iced_aw::pure::{TabLabel, Tabs}; 11 | use login::{LoginMessage, LoginTab}; 12 | 13 | mod ferris; 14 | use ferris::{FerrisMessage, FerrisTab}; 15 | 16 | mod counter; 17 | use counter::{CounterMessage, CounterTab}; 18 | 19 | mod settings; 20 | use settings::{SettingsMessage, SettingsTab, TabBarPosition}; 21 | 22 | mod theme; 23 | 24 | const HEADER_SIZE: u16 = 32; 25 | const TAB_PADDING: u16 = 16; 26 | 27 | const ICON_FONT: Font = iced::Font::External { 28 | name: "Icons", 29 | bytes: include_bytes!("../fonts/icons.ttf"), 30 | }; 31 | 32 | enum Icon { 33 | User, 34 | Heart, 35 | Calc, 36 | CogAlt, 37 | } 38 | 39 | impl From for char { 40 | fn from(icon: Icon) -> Self { 41 | match icon { 42 | Icon::User => '\u{E800}', 43 | Icon::Heart => '\u{E801}', 44 | Icon::Calc => '\u{F1EC}', 45 | Icon::CogAlt => '\u{E802}', 46 | } 47 | } 48 | } 49 | 50 | fn main() -> iced::Result { 51 | TabBarExample::run(Settings::default()) 52 | } 53 | 54 | struct TabBarExample { 55 | active_tab: usize, 56 | login_tab: LoginTab, 57 | ferris_tab: FerrisTab, 58 | counter_tab: CounterTab, 59 | settings_tab: SettingsTab, 60 | } 61 | 62 | #[derive(Clone, Debug)] 63 | enum Message { 64 | TabSelected(usize), 65 | Login(LoginMessage), 66 | Ferris(FerrisMessage), 67 | Counter(CounterMessage), 68 | Settings(SettingsMessage), 69 | } 70 | 71 | impl Sandbox for TabBarExample { 72 | type Message = Message; 73 | 74 | fn new() -> Self { 75 | TabBarExample { 76 | active_tab: 0, 77 | login_tab: LoginTab::new(), 78 | ferris_tab: FerrisTab::new(), 79 | counter_tab: CounterTab::new(), 80 | settings_tab: SettingsTab::new(), 81 | } 82 | } 83 | 84 | fn title(&self) -> String { 85 | String::from("TabBar Example") 86 | } 87 | 88 | fn update(&mut self, message: Self::Message) { 89 | match message { 90 | Message::TabSelected(selected) => self.active_tab = selected, 91 | Message::Login(message) => self.login_tab.update(message), 92 | Message::Ferris(message) => self.ferris_tab.update(message), 93 | Message::Counter(message) => self.counter_tab.update(message), 94 | Message::Settings(message) => self.settings_tab.update(message), 95 | } 96 | } 97 | 98 | fn view(&self) -> Element<'_, Self::Message> { 99 | let position = self 100 | .settings_tab 101 | .settings() 102 | .tab_bar_position 103 | .unwrap_or_default(); 104 | let theme = self 105 | .settings_tab 106 | .settings() 107 | .tab_bar_theme 108 | .unwrap_or_default(); 109 | 110 | Tabs::new(self.active_tab, Message::TabSelected) 111 | .push(self.login_tab.tab_label(), self.login_tab.view()) 112 | .push(self.ferris_tab.tab_label(), self.ferris_tab.view()) 113 | .push(self.counter_tab.tab_label(), self.counter_tab.view()) 114 | .push(self.settings_tab.tab_label(), self.settings_tab.view()) 115 | .tab_bar_style(theme) 116 | .icon_font(ICON_FONT) 117 | .tab_bar_position(match position { 118 | TabBarPosition::Top => iced_aw::TabBarPosition::Top, 119 | TabBarPosition::Bottom => iced_aw::TabBarPosition::Bottom, 120 | }) 121 | .into() 122 | } 123 | } 124 | 125 | trait Tab { 126 | type Message; 127 | 128 | fn title(&self) -> String; 129 | 130 | fn tab_label(&self) -> TabLabel; 131 | 132 | fn view(&self) -> Element<'_, Self::Message> { 133 | let column = Column::new() 134 | .spacing(20) 135 | .push(Text::new(self.title()).size(HEADER_SIZE)) 136 | .push(self.content()); 137 | 138 | Container::new(column) 139 | .width(Length::Fill) 140 | .height(Length::Fill) 141 | .align_x(Horizontal::Center) 142 | .align_y(Vertical::Center) 143 | .padding(TAB_PADDING) 144 | .into() 145 | } 146 | 147 | fn content(&self) -> Element<'_, Self::Message>; 148 | } 149 | -------------------------------------------------------------------------------- /examples/pure/tab_bar/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | pure::{ 3 | widget::{Button, Column, Row, Text, TextInput}, 4 | Element, Sandbox, 5 | }, 6 | Alignment, Length, Settings, 7 | }; 8 | use iced_aw::pure::{TabBar, TabLabel}; 9 | 10 | fn main() -> iced::Result { 11 | TabBarExample::run(Settings::default()) 12 | } 13 | 14 | #[derive(Debug, Clone)] 15 | enum Message { 16 | TabSelected(usize), 17 | TabClosed(usize), 18 | TabLabelInputChanged(String), 19 | TabContentInputChanged(String), 20 | NewTab, 21 | } 22 | 23 | struct TabBarExample { 24 | active_tab: usize, 25 | new_tab_label: String, 26 | new_tab_content: String, 27 | tabs: Vec<(String, String)>, 28 | } 29 | 30 | impl Sandbox for TabBarExample { 31 | type Message = Message; 32 | 33 | fn new() -> Self { 34 | TabBarExample { 35 | active_tab: 0, 36 | new_tab_label: String::new(), 37 | new_tab_content: String::new(), 38 | tabs: Vec::new(), 39 | } 40 | } 41 | 42 | fn title(&self) -> String { 43 | String::from("TabBar example") 44 | } 45 | 46 | fn update(&mut self, message: Message) { 47 | match message { 48 | Message::TabSelected(index) => self.active_tab = index, 49 | Message::TabClosed(index) => { 50 | self.tabs.remove(index); 51 | println!("active tab before: {}", self.active_tab); 52 | self.active_tab = if self.tabs.is_empty() { 53 | 0 54 | } else { 55 | usize::max(0, usize::min(self.active_tab, self.tabs.len() - 1)) 56 | }; 57 | println!("active tab after: {}", self.active_tab); 58 | } 59 | Message::TabLabelInputChanged(value) => self.new_tab_label = value, 60 | Message::TabContentInputChanged(value) => self.new_tab_content = value, 61 | Message::NewTab => { 62 | println!("New"); 63 | if !self.new_tab_label.is_empty() && !self.new_tab_content.is_empty() { 64 | println!("Create"); 65 | self.tabs.push(( 66 | self.new_tab_label.to_owned(), 67 | self.new_tab_content.to_owned(), 68 | )); 69 | self.new_tab_label.clear(); 70 | self.new_tab_content.clear(); 71 | } 72 | } 73 | } 74 | } 75 | 76 | fn view(&self) -> Element { 77 | Column::new() 78 | .push( 79 | Row::new() 80 | .push( 81 | TextInput::new( 82 | "Tab label", 83 | &self.new_tab_label, 84 | Message::TabLabelInputChanged, 85 | ) 86 | .size(22) 87 | .padding(5), 88 | ) 89 | .push( 90 | TextInput::new( 91 | "Tab content", 92 | &self.new_tab_content, 93 | Message::TabContentInputChanged, 94 | ) 95 | .size(22) 96 | .padding(5), 97 | ) 98 | .push(Button::new(Text::new("New")).on_press(Message::NewTab)) 99 | .align_items(Alignment::Center) 100 | .padding(10) 101 | .spacing(5), 102 | ) 103 | .push( 104 | self.tabs 105 | .iter() 106 | .fold( 107 | TabBar::new(self.active_tab, Message::TabSelected), 108 | |tab_bar, (tab_label, _)| { 109 | tab_bar.push(TabLabel::Text(tab_label.to_owned())) 110 | }, 111 | ) 112 | .on_close(Message::TabClosed) 113 | .tab_width(Length::Shrink) 114 | .spacing(5) 115 | .padding(5) 116 | .text_size(32), 117 | ) 118 | .push( 119 | if let Some((_, content)) = self.tabs.get(self.active_tab) { 120 | Text::new(content) 121 | } else { 122 | Text::new("Please create a new tab") 123 | } 124 | .size(25), 125 | ) 126 | .into() 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /examples/modal/src/main.rs: -------------------------------------------------------------------------------- 1 | use iced::{ 2 | alignment::{Alignment, Horizontal}, 3 | button, Button, Container, Element, Length, Row, Sandbox, Settings, Text, 4 | }; 5 | 6 | use iced_aw::{modal, Card, Modal}; 7 | 8 | fn main() -> iced::Result { 9 | ModalExample::run(Settings::default()) 10 | } 11 | 12 | #[derive(Clone, Debug)] 13 | enum Message { 14 | OpenModal, 15 | CloseModal, 16 | CancelButtonPressed, 17 | OkButtonPressed, 18 | } 19 | 20 | #[derive(Default)] 21 | struct ModalExample { 22 | open_state: button::State, 23 | modal_state: modal::State, 24 | last_message: Option, 25 | } 26 | 27 | #[derive(Default)] 28 | struct ModalState { 29 | cancel_state: button::State, 30 | ok_state: button::State, 31 | } 32 | 33 | impl Sandbox for ModalExample { 34 | type Message = Message; 35 | 36 | fn new() -> Self { 37 | Self::default() 38 | } 39 | 40 | fn title(&self) -> String { 41 | String::from("Modal example") 42 | } 43 | 44 | fn update(&mut self, message: Self::Message) { 45 | match message { 46 | Message::OpenModal => self.modal_state.show(true), 47 | Message::CloseModal => self.modal_state.show(false), 48 | Message::CancelButtonPressed => self.modal_state.show(false), 49 | Message::OkButtonPressed => self.modal_state.show(false), 50 | } 51 | self.last_message = Some(message) 52 | } 53 | 54 | fn view(&mut self) -> Element<'_, Self::Message> { 55 | let content = Container::new( 56 | Row::new() 57 | .spacing(10) 58 | .align_items(Alignment::Center) 59 | .push( 60 | Button::new(&mut self.open_state, Text::new("Open modal!")) 61 | .on_press(Message::OpenModal), 62 | ) 63 | .push(Text::new(format!( 64 | "Last message: {}", 65 | match self.last_message.as_ref() { 66 | Some(message) => match message { 67 | Message::OpenModal => "Modal opened", 68 | Message::CloseModal => "Modal closed", 69 | Message::CancelButtonPressed => "Modal canceled", 70 | Message::OkButtonPressed => "Modal accepted", 71 | }, 72 | None => "None", 73 | } 74 | ))), 75 | ); 76 | 77 | Modal::new(&mut self.modal_state, content, |state| { 78 | Card::new( 79 | Text::new("My modal"), 80 | Text::new("This is a modal!"), //Text::new("Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit​​, morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. Qui animated corpse, cricket bat max brucks terribilem incessu zomby. The voodoo sacerdos flesh eater, suscitat mortuos comedere carnem virus. Zonbi tattered for solum oculi eorum defunctis go lum cerebro. Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.") 81 | ) 82 | .foot( 83 | Row::new() 84 | .spacing(10) 85 | .padding(5) 86 | .width(Length::Fill) 87 | .push( 88 | Button::new( 89 | &mut state.cancel_state, 90 | Text::new("Cancel").horizontal_alignment(Horizontal::Center), 91 | ) 92 | .width(Length::Fill) 93 | .on_press(Message::CancelButtonPressed), 94 | ) 95 | .push( 96 | Button::new( 97 | &mut state.ok_state, 98 | Text::new("Ok").horizontal_alignment(Horizontal::Center), 99 | ) 100 | .width(Length::Fill) 101 | .on_press(Message::OkButtonPressed), 102 | ), 103 | ) 104 | .max_width(300) 105 | //.width(Length::Shrink) 106 | .on_close(Message::CloseModal) 107 | .into() 108 | }) 109 | .backdrop(Message::CloseModal) 110 | .on_esc(Message::CloseModal) 111 | .into() 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/style/button.rs: -------------------------------------------------------------------------------- 1 | //! Predefined styles for a [`Button`](iced_native::widget::button::Button). 2 | //! 3 | //! *This API requires the following crate features to be activated: colors* 4 | 5 | #[cfg(feature = "colors")] 6 | pub use predefined::*; 7 | #[cfg(feature = "colors")] 8 | /// Predefined styles for the [`Button`](iced_native::widget::Button) widget. 9 | mod predefined { 10 | use iced_style::button::{Style, StyleSheet}; 11 | 12 | use crate::style::colors; 13 | 14 | /// The appearance with the [`primary`](colors::PRIMARY) color of a 15 | /// [`Button`](iced_native::widget::button::Button). 16 | #[derive(Clone, Copy, Debug)] 17 | pub struct Primary; 18 | 19 | impl StyleSheet for Primary { 20 | fn active(&self) -> Style { 21 | Style { 22 | background: colors::PRIMARY.into(), 23 | text_color: colors::WHITE, 24 | ..Style::default() 25 | } 26 | } 27 | } 28 | 29 | /// The appearance with the [`secondary`](colors::SECONDARY) color of a 30 | /// [`Button`](iced_native::widget::button::Button). 31 | #[derive(Clone, Copy, Debug)] 32 | pub struct Secondary; 33 | 34 | impl StyleSheet for Secondary { 35 | fn active(&self) -> Style { 36 | Style { 37 | background: colors::SECONDARY.into(), 38 | text_color: colors::WHITE, 39 | ..Style::default() 40 | } 41 | } 42 | } 43 | 44 | /// The appearance with the [`success`](colors::SUCCESS) color of a 45 | /// [`Button`](iced_native::widget::button::Button). 46 | #[derive(Clone, Copy, Debug)] 47 | pub struct Success; 48 | 49 | impl StyleSheet for Success { 50 | fn active(&self) -> Style { 51 | Style { 52 | background: colors::SUCCESS.into(), 53 | text_color: colors::WHITE, 54 | ..Style::default() 55 | } 56 | } 57 | } 58 | 59 | /// The appearance with the [`danger`](colors::DANGER) color of a 60 | /// [`Button`](iced_native::widget::button::Button). 61 | #[derive(Clone, Copy, Debug)] 62 | pub struct Danger; 63 | 64 | impl StyleSheet for Danger { 65 | fn active(&self) -> Style { 66 | Style { 67 | background: colors::DANGER.into(), 68 | text_color: colors::WHITE, 69 | ..Style::default() 70 | } 71 | } 72 | } 73 | 74 | /// The appearance with the [`warning`](colors::WARNING) color of a 75 | /// [`Warning`](iced_native::widget::button::Button). 76 | #[derive(Clone, Copy, Debug)] 77 | pub struct Warning; 78 | 79 | impl StyleSheet for Warning { 80 | fn active(&self) -> Style { 81 | Style { 82 | background: colors::WARNING.into(), 83 | ..Style::default() 84 | } 85 | } 86 | } 87 | 88 | /// The appearance with the [`info`](colors::INFO) color of a 89 | /// [`Button`](iced_native::widget::button::Button). 90 | #[derive(Clone, Copy, Debug)] 91 | pub struct Info; 92 | 93 | impl StyleSheet for Info { 94 | fn active(&self) -> Style { 95 | Style { 96 | background: colors::INFO.into(), 97 | ..Style::default() 98 | } 99 | } 100 | } 101 | 102 | /// The appearance with the [`light`](colors::LIGHT) color of a 103 | /// [`Button`](iced_native::widget::button::Button). 104 | #[derive(Clone, Copy, Debug)] 105 | pub struct Light; 106 | 107 | impl StyleSheet for Light { 108 | fn active(&self) -> Style { 109 | Style { 110 | background: colors::LIGHT.into(), 111 | ..Style::default() 112 | } 113 | } 114 | } 115 | 116 | /// The appearance with the [`dark`](colors::DARK) color of a 117 | /// [`Button`](iced_native::widget::button::Button). 118 | #[derive(Clone, Copy, Debug)] 119 | pub struct Dark; 120 | 121 | impl StyleSheet for Dark { 122 | fn active(&self) -> Style { 123 | Style { 124 | background: colors::DARK.into(), 125 | text_color: colors::WHITE, 126 | ..Style::default() 127 | } 128 | } 129 | } 130 | 131 | /// The appearance with the [`white`](colors::WHITE) color of a 132 | /// [`Button`](iced_native::widget::button::Button). 133 | #[derive(Clone, Copy, Debug)] 134 | pub struct White; 135 | 136 | impl StyleSheet for White { 137 | fn active(&self) -> Style { 138 | Style { 139 | background: colors::WHITE.into(), 140 | ..Style::default() 141 | } 142 | } 143 | } 144 | } 145 | --------------------------------------------------------------------------------