Merge pull request #2587 from iced-rs/improve-api-reference
Add widget examples to API reference and update `README`
This commit is contained in:
commit
ddbb8445bf
32 changed files with 2344 additions and 324 deletions
91
ECOSYSTEM.md
91
ECOSYSTEM.md
|
|
@ -1,91 +0,0 @@
|
|||
# Ecosystem
|
||||
This document describes the Iced ecosystem and explains how the different crates relate to each other.
|
||||
|
||||
## Overview
|
||||
Iced is meant to be used by 2 different types of users:
|
||||
|
||||
- __End-users__. They should be able to:
|
||||
- get started quickly,
|
||||
- have many widgets available,
|
||||
- keep things simple,
|
||||
- and build applications that are __maintainable__ and __performant__.
|
||||
- __GUI toolkit developers / Ecosystem contributors__. They should be able to:
|
||||
- build new kinds of widgets,
|
||||
- implement custom runtimes,
|
||||
- integrate existing runtimes in their own system (like game engines),
|
||||
- and create their own custom renderers.
|
||||
|
||||
Iced consists of different crates which offer different layers of abstractions for our users. This modular architecture helps us keep implementation details hidden and decoupled, which should allow us to rewrite or change strategies in the future.
|
||||
|
||||
<p align="center">
|
||||
<img alt="The Iced Ecosystem" src="docs/graphs/ecosystem.png" width="60%">
|
||||
</p>
|
||||
|
||||
## The foundations
|
||||
There are a bunch of concepts that permeate the whole ecosystem. These concepts are considered __the foundations__, and they are provided by three different crates:
|
||||
|
||||
- [`iced_core`] contains many lightweight, reusable primitives (e.g. `Point`, `Rectangle`, `Color`).
|
||||
- [`iced_futures`] implements the concurrent concepts of [The Elm Architecture] on top of the [`futures`] ecosystem.
|
||||
- [`iced_style`] defines the default styling capabilities of built-in widgets.
|
||||
|
||||
<p align="center">
|
||||
<img alt="The foundations" src="docs/graphs/foundations.png" width="50%">
|
||||
</p>
|
||||
|
||||
## The native target
|
||||
The native side of the ecosystem is split into two different groups: __renderers__ and __shells__.
|
||||
|
||||
<p align="center">
|
||||
<img alt="The native target" src="docs/graphs/native.png" width="80%">
|
||||
</p>
|
||||
|
||||
### Renderers
|
||||
The widgets of a _graphical_ user interface produce some primitives that eventually need to be drawn on screen. __Renderers__ take care of this task, potentially leveraging GPU acceleration.
|
||||
|
||||
Currently, there are two different official renderers:
|
||||
|
||||
- [`iced_wgpu`] is powered by [`wgpu`] and supports Vulkan, DirectX 12, and Metal.
|
||||
- [`tiny-skia`] is used as a fallback software renderer when `wgpu` is not supported.
|
||||
|
||||
Additionally, the [`iced_graphics`] subcrate contains a bunch of backend-agnostic types that can be leveraged to build renderers. Both of the renderers rely on the graphical foundations provided by this crate.
|
||||
|
||||
### Shells
|
||||
The widgets of a graphical user _interface_ are interactive. __Shells__ gather and process user interactions in an event loop.
|
||||
|
||||
Normally, a shell will be responsible of creating a window and managing the lifecycle of a user interface, implementing a runtime of [The Elm Architecture].
|
||||
|
||||
As of now, there is one official shell: [`iced_winit`] implements a shell runtime on top of [`winit`].
|
||||
|
||||
## The web target
|
||||
The Web platform provides all the abstractions necessary to draw widgets and gather users interactions.
|
||||
|
||||
Therefore, unlike the native path, the web side of the ecosystem does not need to split renderers and shells. Instead, [`iced_web`] leverages [`dodrio`] to both render widgets and implement a proper runtime.
|
||||
|
||||
## Iced
|
||||
Finally, [`iced`] unifies everything into a simple abstraction to create cross-platform applications:
|
||||
|
||||
- On native, it uses __[shells](#shells)__ and __[renderers](#renderers)__.
|
||||
- On the web, it uses [`iced_web`].
|
||||
|
||||
<p align="center">
|
||||
<img alt="Iced" src="docs/graphs/iced.png" width="80%">
|
||||
</p>
|
||||
|
||||
[`iced_core`]: core
|
||||
[`iced_futures`]: futures
|
||||
[`iced_style`]: style
|
||||
[`iced_native`]: native
|
||||
[`iced_web`]: https://github.com/iced-rs/iced_web
|
||||
[`iced_graphics`]: graphics
|
||||
[`iced_wgpu`]: wgpu
|
||||
[`iced_glow`]: glow
|
||||
[`iced_winit`]: winit
|
||||
[`iced_glutin`]: glutin
|
||||
[`iced`]: ..
|
||||
[`futures`]: https://github.com/rust-lang/futures-rs
|
||||
[`glow`]: https://github.com/grovesNL/glow
|
||||
[`wgpu`]: https://github.com/gfx-rs/wgpu
|
||||
[`winit`]: https://github.com/rust-windowing/winit
|
||||
[`glutin`]: https://github.com/rust-windowing/glutin
|
||||
[`dodrio`]: https://github.com/fitzgen/dodrio
|
||||
[The Elm Architecture]: https://guide.elm-lang.org/architecture/
|
||||
36
README.md
36
README.md
|
|
@ -15,11 +15,11 @@
|
|||
A cross-platform GUI library for Rust focused on simplicity and type-safety.
|
||||
Inspired by [Elm].
|
||||
|
||||
<a href="https://iced.rs/examples/todos.mp4">
|
||||
<img src="https://iced.rs/examples/todos.gif" width="275px">
|
||||
<a href="https://github.com/squidowl/halloy">
|
||||
<img src="https://iced.rs/showcase/halloy.gif" width="460px">
|
||||
</a>
|
||||
<a href="https://iced.rs/examples/tour.mp4">
|
||||
<img src="https://iced.rs/examples/tour.gif" width="273px">
|
||||
<a href="https://github.com/hecrj/icebreaker">
|
||||
<img src="https://iced.rs/showcase/icebreaker.gif" width="360px">
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
|
@ -34,34 +34,28 @@ Inspired by [Elm].
|
|||
* Custom widget support (create your own!)
|
||||
* [Debug overlay with performance metrics]
|
||||
* First-class support for async actions (use futures!)
|
||||
* [Modular ecosystem] split into reusable parts:
|
||||
* Modular ecosystem split into reusable parts:
|
||||
* A [renderer-agnostic native runtime] enabling integration with existing systems
|
||||
* Two [built-in renderers] leveraging [`wgpu`] and [`tiny-skia`]
|
||||
* Two built-in renderers leveraging [`wgpu`] and [`tiny-skia`]
|
||||
* [`iced_wgpu`] supporting Vulkan, Metal and DX12
|
||||
* [`iced_tiny_skia`] offering a software alternative as a fallback
|
||||
* A [windowing shell]
|
||||
* A [web runtime] leveraging the DOM
|
||||
|
||||
__Iced is currently experimental software.__ [Take a look at the roadmap],
|
||||
[check out the issues], and [feel free to contribute!]
|
||||
__Iced is currently experimental software.__ [Take a look at the roadmap] and
|
||||
[check out the issues].
|
||||
|
||||
[Cross-platform support]: https://raw.githubusercontent.com/iced-rs/iced/master/docs/images/todos_desktop.jpg
|
||||
[text inputs]: https://iced.rs/examples/text_input.mp4
|
||||
[scrollables]: https://iced.rs/examples/scrollable.mp4
|
||||
[Debug overlay with performance metrics]: https://iced.rs/examples/debug.mp4
|
||||
[Modular ecosystem]: ECOSYSTEM.md
|
||||
[renderer-agnostic native runtime]: runtime/
|
||||
[`wgpu`]: https://github.com/gfx-rs/wgpu
|
||||
[`tiny-skia`]: https://github.com/RazrFalcon/tiny-skia
|
||||
[`iced_wgpu`]: wgpu/
|
||||
[`iced_tiny_skia`]: tiny_skia/
|
||||
[built-in renderers]: ECOSYSTEM.md#Renderers
|
||||
[windowing shell]: winit/
|
||||
[`dodrio`]: https://github.com/fitzgen/dodrio
|
||||
[web runtime]: https://github.com/iced-rs/iced_web
|
||||
[Take a look at the roadmap]: ROADMAP.md
|
||||
[check out the issues]: https://github.com/iced-rs/iced/issues
|
||||
[feel free to contribute!]: #contributing--feedback
|
||||
|
||||
## Overview
|
||||
|
||||
|
|
@ -164,7 +158,7 @@ Read the [book], the [documentation], and the [examples] to learn more!
|
|||
## Implementation details
|
||||
|
||||
Iced was originally born as an attempt at bringing the simplicity of [Elm] and
|
||||
[The Elm Architecture] into [Coffee], a 2D game engine I am working on.
|
||||
[The Elm Architecture] into [Coffee], a 2D game library I am working on.
|
||||
|
||||
The core of the library was implemented during May 2019 in [this pull request].
|
||||
[The first alpha version] was eventually released as
|
||||
|
|
@ -172,25 +166,17 @@ The core of the library was implemented during May 2019 in [this pull request].
|
|||
implemented the current [tour example] on top of [`ggez`], a game library.
|
||||
|
||||
Since then, the focus has shifted towards providing a batteries-included,
|
||||
end-user-oriented GUI library, while keeping [the ecosystem] modular:
|
||||
|
||||
<p align="center">
|
||||
<a href="ECOSYSTEM.md">
|
||||
<img alt="The Iced Ecosystem" src="docs/graphs/ecosystem.png" width="80%">
|
||||
</a>
|
||||
</p>
|
||||
end-user-oriented GUI library, while keeping the ecosystem modular.
|
||||
|
||||
[this pull request]: https://github.com/hecrj/coffee/pull/35
|
||||
[The first alpha version]: https://github.com/iced-rs/iced/tree/0.1.0-alpha
|
||||
[a renderer-agnostic GUI library]: https://www.reddit.com/r/rust/comments/czzjnv/iced_a_rendereragnostic_gui_library_focused_on/
|
||||
[tour example]: examples/README.md#tour
|
||||
[`ggez`]: https://github.com/ggez/ggez
|
||||
[the ecosystem]: ECOSYSTEM.md
|
||||
|
||||
## Contributing / Feedback
|
||||
|
||||
Contributions are greatly appreciated! If you want to contribute, please
|
||||
read our [contributing guidelines] for more details.
|
||||
If you want to contribute, please read our [contributing guidelines] for more details.
|
||||
|
||||
Feedback is also welcome! You can create a new topic in [our Discourse forum] or
|
||||
come chat to [our Discord server].
|
||||
|
|
|
|||
|
|
@ -1,4 +1,25 @@
|
|||
//! Write some text for your users to read.
|
||||
//! Text widgets display information through writing.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub fn text<T>(t: T) -> iced_core::widget::Text<'static, iced_core::Theme, ()> { unimplemented!() } }
|
||||
//! # pub use iced_core::color; }
|
||||
//! # pub type State = ();
|
||||
//! # pub type Element<'a, Message> = iced_core::Element<'a, Message, iced_core::Theme, ()>;
|
||||
//! use iced::widget::text;
|
||||
//! use iced::color;
|
||||
//!
|
||||
//! enum Message {
|
||||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! text("Hello, this is iced!")
|
||||
//! .size(20)
|
||||
//! .color(color!(0x0000ff))
|
||||
//! .into()
|
||||
//! }
|
||||
//! ```
|
||||
use crate::alignment;
|
||||
use crate::layout;
|
||||
use crate::mouse;
|
||||
|
|
@ -13,7 +34,28 @@ use crate::{
|
|||
|
||||
pub use text::{LineHeight, Shaping, Wrapping};
|
||||
|
||||
/// A paragraph of text.
|
||||
/// A bunch of text.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub fn text<T>(t: T) -> iced_core::widget::Text<'static, iced_core::Theme, ()> { unimplemented!() } }
|
||||
/// # pub use iced_core::color; }
|
||||
/// # pub type State = ();
|
||||
/// # pub type Element<'a, Message> = iced_core::Element<'a, Message, iced_core::Theme, ()>;
|
||||
/// use iced::widget::text;
|
||||
/// use iced::color;
|
||||
///
|
||||
/// enum Message {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// text("Hello, this is iced!")
|
||||
/// .size(20)
|
||||
/// .color(color!(0x0000ff))
|
||||
/// .into()
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Text<'a, Theme, Renderer>
|
||||
where
|
||||
|
|
|
|||
|
|
@ -138,11 +138,16 @@ impl<T> Subscription<T> {
|
|||
/// and returning the `Sender` as a `Message` for the `Application`:
|
||||
///
|
||||
/// ```
|
||||
/// use iced_futures::subscription::{self, Subscription};
|
||||
/// use iced_futures::stream;
|
||||
/// use iced_futures::futures::channel::mpsc;
|
||||
/// use iced_futures::futures::sink::SinkExt;
|
||||
/// use iced_futures::futures::Stream;
|
||||
/// # mod iced {
|
||||
/// # pub use iced_futures::Subscription;
|
||||
/// # pub use iced_futures::futures;
|
||||
/// # pub use iced_futures::stream;
|
||||
/// # }
|
||||
/// use iced::futures::channel::mpsc;
|
||||
/// use iced::futures::sink::SinkExt;
|
||||
/// use iced::futures::Stream;
|
||||
/// use iced::stream;
|
||||
/// use iced::Subscription;
|
||||
///
|
||||
/// pub enum Event {
|
||||
/// Ready(mpsc::Sender<Input>),
|
||||
|
|
|
|||
30
src/lib.rs
30
src/lib.rs
|
|
@ -380,16 +380,18 @@
|
|||
//! # use iced::{Element, Task};
|
||||
//! # pub struct Contacts;
|
||||
//! # impl Contacts {
|
||||
//! # pub fn update(&mut self, message: Message) -> Task<Message> { unimplemented!() }
|
||||
//! # pub fn update(&mut self, message: Message) -> Action { unimplemented!() }
|
||||
//! # pub fn view(&self) -> Element<Message> { unimplemented!() }
|
||||
//! # }
|
||||
//! # #[derive(Debug)]
|
||||
//! # pub enum Message {}
|
||||
//! # pub enum Action { None, Run(Task<Message>), Chat(()) }
|
||||
//! # }
|
||||
//! # mod conversation {
|
||||
//! # use iced::{Element, Task};
|
||||
//! # pub struct Conversation;
|
||||
//! # impl Conversation {
|
||||
//! # pub fn new(contact: ()) -> (Self, Task<Message>) { unimplemented!() }
|
||||
//! # pub fn update(&mut self, message: Message) -> Task<Message> { unimplemented!() }
|
||||
//! # pub fn view(&self) -> Element<Message> { unimplemented!() }
|
||||
//! # }
|
||||
|
|
@ -419,7 +421,19 @@
|
|||
//! match message {
|
||||
//! Message::Contacts(message) => {
|
||||
//! if let Screen::Contacts(contacts) = &mut state.screen {
|
||||
//! contacts.update(message).map(Message::Contacts)
|
||||
//! let action = contacts.update(message);
|
||||
//!
|
||||
//! match action {
|
||||
//! contacts::Action::None => Task::none(),
|
||||
//! contacts::Action::Run(task) => task.map(Message::Contacts),
|
||||
//! contacts::Action::Chat(contact) => {
|
||||
//! let (conversation, task) = Conversation::new(contact);
|
||||
//!
|
||||
//! state.screen = Screen::Conversation(conversation);
|
||||
//!
|
||||
//! task.map(Message::Conversation)
|
||||
//! }
|
||||
//! }
|
||||
//! } else {
|
||||
//! Task::none()
|
||||
//! }
|
||||
|
|
@ -442,8 +456,16 @@
|
|||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! Functor methods like [`Task::map`], [`Element::map`], and [`Subscription::map`] make this
|
||||
//! approach seamless.
|
||||
//! The `update` method of a screen can return an `Action` enum that can be leveraged by the parent to
|
||||
//! execute a task or transition to a completely different screen altogether. The variants of `Action` can
|
||||
//! have associated data. For instance, in the example above, the `Conversation` screen is created when
|
||||
//! `Contacts::update` returns an `Action::Chat` with the selected contact.
|
||||
//!
|
||||
//! Effectively, this approach lets you "tell a story" to connect different screens together in a type safe
|
||||
//! way.
|
||||
//!
|
||||
//! Furthermore, functor methods like [`Task::map`], [`Element::map`], and [`Subscription::map`] make composition
|
||||
//! seamless.
|
||||
#![doc(
|
||||
html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/bdf0430880f5c29443f5f0a0ae4895866dfef4c6/docs/logo.svg"
|
||||
)]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,21 @@
|
|||
//! Allow your users to perform actions by pressing a button.
|
||||
//! Buttons allow your users to perform actions by pressing them.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
//! # pub type State = ();
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! use iced::widget::button;
|
||||
//!
|
||||
//! #[derive(Clone)]
|
||||
//! enum Message {
|
||||
//! ButtonPressed,
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! button("Press me!").on_press(Message::ButtonPressed).into()
|
||||
//! }
|
||||
//! ```
|
||||
use crate::core::border::{self, Border};
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::layout;
|
||||
|
|
@ -16,34 +33,39 @@ use crate::core::{
|
|||
|
||||
/// A generic widget that produces a message when pressed.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # type Button<'a, Message> = iced_widget::Button<'a, Message>;
|
||||
/// #
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
/// # pub type State = ();
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// use iced::widget::button;
|
||||
///
|
||||
/// #[derive(Clone)]
|
||||
/// enum Message {
|
||||
/// ButtonPressed,
|
||||
/// }
|
||||
///
|
||||
/// let button = Button::new("Press me!").on_press(Message::ButtonPressed);
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// button("Press me!").on_press(Message::ButtonPressed).into()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// If a [`Button::on_press`] handler is not set, the resulting [`Button`] will
|
||||
/// be disabled:
|
||||
///
|
||||
/// ```
|
||||
/// # type Button<'a, Message> = iced_widget::Button<'a, Message>;
|
||||
/// #
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
/// # pub type State = ();
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// use iced::widget::button;
|
||||
///
|
||||
/// #[derive(Clone)]
|
||||
/// enum Message {
|
||||
/// ButtonPressed,
|
||||
/// }
|
||||
///
|
||||
/// fn disabled_button<'a>() -> Button<'a, Message> {
|
||||
/// Button::new("I'm disabled!")
|
||||
/// }
|
||||
///
|
||||
/// fn enabled_button<'a>() -> Button<'a, Message> {
|
||||
/// disabled_button().on_press(Message::ButtonPressed)
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// button("I am disabled!").into()
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,53 @@
|
|||
//! Draw 2D graphics for your users.
|
||||
//! Canvases can be leveraged to draw interactive 2D graphics.
|
||||
//!
|
||||
//! # Example: Drawing a Simple Circle
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
//! # pub type State = ();
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! #
|
||||
//! use iced::mouse;
|
||||
//! use iced::widget::canvas;
|
||||
//! use iced::{Color, Rectangle, Renderer, Theme};
|
||||
//!
|
||||
//! // First, we define the data we need for drawing
|
||||
//! #[derive(Debug)]
|
||||
//! struct Circle {
|
||||
//! radius: f32,
|
||||
//! }
|
||||
//!
|
||||
//! // Then, we implement the `Program` trait
|
||||
//! impl<Message> canvas::Program<Message> for Circle {
|
||||
//! // No internal state
|
||||
//! type State = ();
|
||||
//!
|
||||
//! fn draw(
|
||||
//! &self,
|
||||
//! _state: &(),
|
||||
//! renderer: &Renderer,
|
||||
//! _theme: &Theme,
|
||||
//! bounds: Rectangle,
|
||||
//! _cursor: mouse::Cursor
|
||||
//! ) -> Vec<canvas::Geometry> {
|
||||
//! // We prepare a new `Frame`
|
||||
//! let mut frame = canvas::Frame::new(renderer, bounds.size());
|
||||
//!
|
||||
//! // We create a `Path` representing a simple circle
|
||||
//! let circle = canvas::Path::circle(frame.center(), self.radius);
|
||||
//!
|
||||
//! // And fill it with some color
|
||||
//! frame.fill(&circle, Color::BLACK);
|
||||
//!
|
||||
//! // Then, we produce the geometry
|
||||
//! vec![frame.into_geometry()]
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! // Finally, we simply use our `Circle` to create the `Canvas`!
|
||||
//! fn view<'a, Message: 'a>(_state: &'a State) -> Element<'a, Message> {
|
||||
//! canvas(Circle { radius: 50.0 }).into()
|
||||
//! }
|
||||
//! ```
|
||||
pub mod event;
|
||||
|
||||
mod program;
|
||||
|
|
@ -39,15 +88,16 @@ pub type Frame<Renderer = crate::Renderer> = geometry::Frame<Renderer>;
|
|||
|
||||
/// A widget capable of drawing 2D graphics.
|
||||
///
|
||||
/// ## Drawing a simple circle
|
||||
/// If you want to get a quick overview, here's how we can draw a simple circle:
|
||||
///
|
||||
/// # Example: Drawing a Simple Circle
|
||||
/// ```no_run
|
||||
/// # use iced_widget::canvas::{self, Canvas, Fill, Frame, Geometry, Path, Program};
|
||||
/// # use iced_widget::core::{Color, Rectangle};
|
||||
/// # use iced_widget::core::mouse;
|
||||
/// # use iced_widget::{Renderer, Theme};
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type State = ();
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// #
|
||||
/// use iced::mouse;
|
||||
/// use iced::widget::canvas;
|
||||
/// use iced::{Color, Rectangle, Renderer, Theme};
|
||||
///
|
||||
/// // First, we define the data we need for drawing
|
||||
/// #[derive(Debug)]
|
||||
/// struct Circle {
|
||||
|
|
@ -55,26 +105,36 @@ pub type Frame<Renderer = crate::Renderer> = geometry::Frame<Renderer>;
|
|||
/// }
|
||||
///
|
||||
/// // Then, we implement the `Program` trait
|
||||
/// impl Program<()> for Circle {
|
||||
/// impl<Message> canvas::Program<Message> for Circle {
|
||||
/// // No internal state
|
||||
/// type State = ();
|
||||
///
|
||||
/// fn draw(&self, _state: &(), renderer: &Renderer, _theme: &Theme, bounds: Rectangle, _cursor: mouse::Cursor) -> Vec<Geometry> {
|
||||
/// fn draw(
|
||||
/// &self,
|
||||
/// _state: &(),
|
||||
/// renderer: &Renderer,
|
||||
/// _theme: &Theme,
|
||||
/// bounds: Rectangle,
|
||||
/// _cursor: mouse::Cursor
|
||||
/// ) -> Vec<canvas::Geometry> {
|
||||
/// // We prepare a new `Frame`
|
||||
/// let mut frame = Frame::new(renderer, bounds.size());
|
||||
/// let mut frame = canvas::Frame::new(renderer, bounds.size());
|
||||
///
|
||||
/// // We create a `Path` representing a simple circle
|
||||
/// let circle = Path::circle(frame.center(), self.radius);
|
||||
/// let circle = canvas::Path::circle(frame.center(), self.radius);
|
||||
///
|
||||
/// // And fill it with some color
|
||||
/// frame.fill(&circle, Color::BLACK);
|
||||
///
|
||||
/// // Finally, we produce the geometry
|
||||
/// // Then, we produce the geometry
|
||||
/// vec![frame.into_geometry()]
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // Finally, we simply use our `Circle` to create the `Canvas`!
|
||||
/// let canvas = Canvas::new(Circle { radius: 50.0 });
|
||||
/// fn view<'a, Message: 'a>(_state: &'a State) -> Element<'a, Message> {
|
||||
/// canvas(Circle { radius: 50.0 }).into()
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Debug)]
|
||||
pub struct Canvas<P, Message, Theme = crate::Theme, Renderer = crate::Renderer>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,35 @@
|
|||
//! Show toggle controls using checkboxes.
|
||||
//! Checkboxes can be used to let users make binary choices.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! #
|
||||
//! use iced::widget::checkbox;
|
||||
//!
|
||||
//! struct State {
|
||||
//! is_checked: bool,
|
||||
//! }
|
||||
//!
|
||||
//! enum Message {
|
||||
//! CheckboxToggled(bool),
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! checkbox("Toggle me!", state.is_checked)
|
||||
//! .on_toggle(Message::CheckboxToggled)
|
||||
//! .into()
|
||||
//! }
|
||||
//!
|
||||
//! fn update(state: &mut State, message: Message) {
|
||||
//! match message {
|
||||
//! Message::CheckboxToggled(is_checked) => {
|
||||
//! state.is_checked = is_checked;
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
//! 
|
||||
use crate::core::alignment;
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::layout;
|
||||
|
|
@ -17,19 +48,34 @@ use crate::core::{
|
|||
/// A box that can be checked.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # type Checkbox<'a, Message> = iced_widget::Checkbox<'a, Message>;
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// #
|
||||
/// pub enum Message {
|
||||
/// use iced::widget::checkbox;
|
||||
///
|
||||
/// struct State {
|
||||
/// is_checked: bool,
|
||||
/// }
|
||||
///
|
||||
/// enum Message {
|
||||
/// CheckboxToggled(bool),
|
||||
/// }
|
||||
///
|
||||
/// let is_checked = true;
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// checkbox("Toggle me!", state.is_checked)
|
||||
/// .on_toggle(Message::CheckboxToggled)
|
||||
/// .into()
|
||||
/// }
|
||||
///
|
||||
/// Checkbox::new("Toggle me!", is_checked).on_toggle(Message::CheckboxToggled);
|
||||
/// fn update(state: &mut State, message: Message) {
|
||||
/// match message {
|
||||
/// Message::CheckboxToggled(is_checked) => {
|
||||
/// state.is_checked = is_checked;
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// 
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Checkbox<
|
||||
|
|
|
|||
|
|
@ -12,6 +12,27 @@ use crate::core::{
|
|||
};
|
||||
|
||||
/// A container that distributes its contents vertically.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
/// # pub type State = ();
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// use iced::widget::{button, column};
|
||||
///
|
||||
/// #[derive(Debug, Clone)]
|
||||
/// enum Message {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// column![
|
||||
/// "I am on top!",
|
||||
/// button("I am in the center!"),
|
||||
/// "I am below.",
|
||||
/// ].into()
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Column<'a, Message, Theme = crate::Theme, Renderer = crate::Renderer>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,59 @@
|
|||
//! Display a dropdown list of searchable and selectable options.
|
||||
//! Combo boxes display a dropdown list of searchable and selectable options.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! #
|
||||
//! use iced::widget::combo_box;
|
||||
//!
|
||||
//! struct State {
|
||||
//! fruits: combo_box::State<Fruit>,
|
||||
//! favorite: Option<Fruit>,
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(Debug, Clone)]
|
||||
//! enum Fruit {
|
||||
//! Apple,
|
||||
//! Orange,
|
||||
//! Strawberry,
|
||||
//! Tomato,
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(Debug, Clone)]
|
||||
//! enum Message {
|
||||
//! FruitSelected(Fruit),
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! combo_box(
|
||||
//! &state.fruits,
|
||||
//! "Select your favorite fruit...",
|
||||
//! state.favorite.as_ref(),
|
||||
//! Message::FruitSelected
|
||||
//! )
|
||||
//! .into()
|
||||
//! }
|
||||
//!
|
||||
//! fn update(state: &mut State, message: Message) {
|
||||
//! match message {
|
||||
//! Message::FruitSelected(fruit) => {
|
||||
//! state.favorite = Some(fruit);
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! impl std::fmt::Display for Fruit {
|
||||
//! fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
//! f.write_str(match self {
|
||||
//! Self::Apple => "Apple",
|
||||
//! Self::Orange => "Orange",
|
||||
//! Self::Strawberry => "Strawberry",
|
||||
//! Self::Tomato => "Tomato",
|
||||
//! })
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::keyboard;
|
||||
use crate::core::keyboard::key;
|
||||
|
|
@ -21,9 +76,60 @@ use std::fmt::Display;
|
|||
|
||||
/// A widget for searching and selecting a single value from a list of options.
|
||||
///
|
||||
/// This widget is composed by a [`TextInput`] that can be filled with the text
|
||||
/// to search for corresponding values from the list of options that are displayed
|
||||
/// as a Menu.
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// #
|
||||
/// use iced::widget::combo_box;
|
||||
///
|
||||
/// struct State {
|
||||
/// fruits: combo_box::State<Fruit>,
|
||||
/// favorite: Option<Fruit>,
|
||||
/// }
|
||||
///
|
||||
/// #[derive(Debug, Clone)]
|
||||
/// enum Fruit {
|
||||
/// Apple,
|
||||
/// Orange,
|
||||
/// Strawberry,
|
||||
/// Tomato,
|
||||
/// }
|
||||
///
|
||||
/// #[derive(Debug, Clone)]
|
||||
/// enum Message {
|
||||
/// FruitSelected(Fruit),
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// combo_box(
|
||||
/// &state.fruits,
|
||||
/// "Select your favorite fruit...",
|
||||
/// state.favorite.as_ref(),
|
||||
/// Message::FruitSelected
|
||||
/// )
|
||||
/// .into()
|
||||
/// }
|
||||
///
|
||||
/// fn update(state: &mut State, message: Message) {
|
||||
/// match message {
|
||||
/// Message::FruitSelected(fruit) => {
|
||||
/// state.favorite = Some(fruit);
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl std::fmt::Display for Fruit {
|
||||
/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
/// f.write_str(match self {
|
||||
/// Self::Apple => "Apple",
|
||||
/// Self::Orange => "Orange",
|
||||
/// Self::Strawberry => "Strawberry",
|
||||
/// Self::Tomato => "Tomato",
|
||||
/// })
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct ComboBox<
|
||||
'a,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,24 @@
|
|||
//! Decorate content and apply alignment.
|
||||
//! Containers let you align a widget inside their boundaries.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
//! # pub type State = ();
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! use iced::widget::container;
|
||||
//!
|
||||
//! enum Message {
|
||||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! container("This text is centered inside a rounded box!")
|
||||
//! .padding(10)
|
||||
//! .center(800)
|
||||
//! .style(container::rounded_box)
|
||||
//! .into()
|
||||
//! }
|
||||
//! ```
|
||||
use crate::core::alignment::{self, Alignment};
|
||||
use crate::core::border::{self, Border};
|
||||
use crate::core::event::{self, Event};
|
||||
|
|
@ -16,9 +36,27 @@ use crate::core::{
|
|||
};
|
||||
use crate::runtime::task::{self, Task};
|
||||
|
||||
/// An element decorating some content.
|
||||
/// A widget that aligns its contents inside of its boundaries.
|
||||
///
|
||||
/// It is normally used for alignment purposes.
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
/// # pub type State = ();
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// use iced::widget::container;
|
||||
///
|
||||
/// enum Message {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// container("This text is centered inside a rounded box!")
|
||||
/// .padding(10)
|
||||
/// .center(800)
|
||||
/// .style(container::rounded_box)
|
||||
/// .into()
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Container<
|
||||
'a,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,21 @@
|
|||
//! Display images in your user interface.
|
||||
//! Images display raster graphics in different formats (PNG, JPG, etc.).
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
//! # pub type State = ();
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! use iced::widget::image;
|
||||
//!
|
||||
//! enum Message {
|
||||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! image("ferris.png").into()
|
||||
//! }
|
||||
//! ```
|
||||
//! <img src="https://github.com/iced-rs/iced/blob/9712b319bb7a32848001b96bd84977430f14b623/examples/resources/ferris.png?raw=true" width="300">
|
||||
pub mod viewer;
|
||||
pub use viewer::Viewer;
|
||||
|
||||
|
|
@ -22,16 +39,23 @@ pub fn viewer<Handle>(handle: Handle) -> Viewer<Handle> {
|
|||
/// A frame that displays an image while keeping aspect ratio.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use iced_widget::image::{self, Image};
|
||||
/// #
|
||||
/// let image = Image::<image::Handle>::new("resources/ferris.png");
|
||||
/// ```
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
/// # pub type State = ();
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// use iced::widget::image;
|
||||
///
|
||||
/// enum Message {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// image("ferris.png").into()
|
||||
/// }
|
||||
/// ```
|
||||
/// <img src="https://github.com/iced-rs/iced/blob/9712b319bb7a32848001b96bd84977430f14b623/examples/resources/ferris.png?raw=true" width="300">
|
||||
#[derive(Debug)]
|
||||
pub struct Image<Handle> {
|
||||
pub struct Image<Handle = image::Handle> {
|
||||
handle: Handle,
|
||||
width: Length,
|
||||
height: Length,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! Use widgets that can provide hints to ensure continuity.
|
||||
//! Keyed widgets can provide hints to ensure continuity.
|
||||
//!
|
||||
//! # What is continuity?
|
||||
//! Continuity is the feeling of persistence of state.
|
||||
|
|
@ -41,13 +41,35 @@ pub mod column;
|
|||
|
||||
pub use column::Column;
|
||||
|
||||
/// Creates a [`Column`] with the given children.
|
||||
/// Creates a keyed [`Column`] with the given children.
|
||||
///
|
||||
/// Keyed columns distribute content vertically while keeping continuity.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
/// # pub type State = ();
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// use iced::widget::keyed_column;
|
||||
///
|
||||
/// enum Message {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// keyed_column![
|
||||
/// (0, "Item 0"),
|
||||
/// (1, "Item 1"),
|
||||
/// (2, "Item 2"),
|
||||
/// ].into()
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! keyed_column {
|
||||
() => (
|
||||
$crate::Column::new()
|
||||
$crate::keyed::Column::new()
|
||||
);
|
||||
($($x:expr),+ $(,)?) => (
|
||||
$crate::keyed::Column::with_children(vec![$($crate::core::Element::from($x)),+])
|
||||
($(($key:expr, $x:expr)),+ $(,)?) => (
|
||||
$crate::keyed::Column::with_children(vec![$(($key, $crate::core::Element::from($x))),+])
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! Distribute content vertically.
|
||||
//! Keyed columns distribute content vertically while keeping continuity.
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::layout;
|
||||
use crate::core::mouse;
|
||||
|
|
@ -11,7 +11,25 @@ use crate::core::{
|
|||
Shell, Size, Vector, Widget,
|
||||
};
|
||||
|
||||
/// A container that distributes its contents vertically.
|
||||
/// A container that distributes its contents vertically while keeping continuity.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
/// # pub type State = ();
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// use iced::widget::{keyed_column, text};
|
||||
///
|
||||
/// enum Message {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// keyed_column((0..=100).map(|i| {
|
||||
/// (i, text!("Item {i}").into())
|
||||
/// })).into()
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Column<
|
||||
'a,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,52 @@
|
|||
//! Parse and display Markdown.
|
||||
//! Markdown widgets can parse and display Markdown.
|
||||
//!
|
||||
//! You can enable the `highlighter` feature for syntax highligting
|
||||
//! in code blocks.
|
||||
//!
|
||||
//! Only the variants of [`Item`] are currently supported.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! #
|
||||
//! use iced::widget::markdown;
|
||||
//! use iced::Theme;
|
||||
//!
|
||||
//! struct State {
|
||||
//! markdown: Vec<markdown::Item>,
|
||||
//! }
|
||||
//!
|
||||
//! enum Message {
|
||||
//! LinkClicked(markdown::Url),
|
||||
//! }
|
||||
//!
|
||||
//! impl State {
|
||||
//! pub fn new() -> Self {
|
||||
//! Self {
|
||||
//! markdown: markdown::parse("This is some **Markdown**!").collect(),
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! fn view(&self) -> Element<'_, Message> {
|
||||
//! markdown::view(
|
||||
//! &self.markdown,
|
||||
//! markdown::Settings::default(),
|
||||
//! markdown::Style::from_palette(Theme::TokyoNightStorm.palette()),
|
||||
//! )
|
||||
//! .map(Message::LinkClicked)
|
||||
//! .into()
|
||||
//! }
|
||||
//!
|
||||
//! fn update(state: &mut State, message: Message) {
|
||||
//! match message {
|
||||
//! Message::LinkClicked(url) => {
|
||||
//! println!("The following url was clicked: {url}");
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
use crate::core::border;
|
||||
use crate::core::font::{self, Font};
|
||||
use crate::core::padding;
|
||||
|
|
@ -145,6 +188,49 @@ impl Span {
|
|||
}
|
||||
|
||||
/// Parse the given Markdown content.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// #
|
||||
/// use iced::widget::markdown;
|
||||
/// use iced::Theme;
|
||||
///
|
||||
/// struct State {
|
||||
/// markdown: Vec<markdown::Item>,
|
||||
/// }
|
||||
///
|
||||
/// enum Message {
|
||||
/// LinkClicked(markdown::Url),
|
||||
/// }
|
||||
///
|
||||
/// impl State {
|
||||
/// pub fn new() -> Self {
|
||||
/// Self {
|
||||
/// markdown: markdown::parse("This is some **Markdown**!").collect(),
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn view(&self) -> Element<'_, Message> {
|
||||
/// markdown::view(
|
||||
/// &self.markdown,
|
||||
/// markdown::Settings::default(),
|
||||
/// markdown::Style::from_palette(Theme::TokyoNightStorm.palette()),
|
||||
/// )
|
||||
/// .map(Message::LinkClicked)
|
||||
/// .into()
|
||||
/// }
|
||||
///
|
||||
/// fn update(state: &mut State, message: Message) {
|
||||
/// match message {
|
||||
/// Message::LinkClicked(url) => {
|
||||
/// println!("The following url was clicked: {url}");
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub fn parse(markdown: &str) -> impl Iterator<Item = Item> + '_ {
|
||||
struct List {
|
||||
start: Option<u64>,
|
||||
|
|
@ -484,6 +570,49 @@ impl Style {
|
|||
/// Display a bunch of Markdown items.
|
||||
///
|
||||
/// You can obtain the items with [`parse`].
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// #
|
||||
/// use iced::widget::markdown;
|
||||
/// use iced::Theme;
|
||||
///
|
||||
/// struct State {
|
||||
/// markdown: Vec<markdown::Item>,
|
||||
/// }
|
||||
///
|
||||
/// enum Message {
|
||||
/// LinkClicked(markdown::Url),
|
||||
/// }
|
||||
///
|
||||
/// impl State {
|
||||
/// pub fn new() -> Self {
|
||||
/// Self {
|
||||
/// markdown: markdown::parse("This is some **Markdown**!").collect(),
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn view(&self) -> Element<'_, Message> {
|
||||
/// markdown::view(
|
||||
/// &self.markdown,
|
||||
/// markdown::Settings::default(),
|
||||
/// markdown::Style::from_palette(Theme::TokyoNightStorm.palette()),
|
||||
/// )
|
||||
/// .map(Message::LinkClicked)
|
||||
/// .into()
|
||||
/// }
|
||||
///
|
||||
/// fn update(state: &mut State, message: Message) {
|
||||
/// match message {
|
||||
/// Message::LinkClicked(url) => {
|
||||
/// println!("The following url was clicked: {url}");
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub fn view<'a, Theme, Renderer>(
|
||||
items: impl IntoIterator<Item = &'a Item>,
|
||||
settings: Settings,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,54 @@
|
|||
//! Let your users split regions of your application and organize layout dynamically.
|
||||
//! Pane grids let your users split regions of your application and organize layout dynamically.
|
||||
//!
|
||||
//! 
|
||||
//!
|
||||
//! This distribution of space is common in tiling window managers (like
|
||||
//! [`awesome`](https://awesomewm.org/), [`i3`](https://i3wm.org/), or even
|
||||
//! [`tmux`](https://github.com/tmux/tmux)).
|
||||
//!
|
||||
//! A [`PaneGrid`] supports:
|
||||
//!
|
||||
//! * Vertical and horizontal splits
|
||||
//! * Tracking of the last active pane
|
||||
//! * Mouse-based resizing
|
||||
//! * Drag and drop to reorganize panes
|
||||
//! * Hotkey support
|
||||
//! * Configurable modifier keys
|
||||
//! * [`State`] API to perform actions programmatically (`split`, `swap`, `resize`, etc.)
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! #
|
||||
//! use iced::widget::{pane_grid, text};
|
||||
//!
|
||||
//! struct State {
|
||||
//! panes: pane_grid::State<Pane>,
|
||||
//! }
|
||||
//!
|
||||
//! enum Pane {
|
||||
//! SomePane,
|
||||
//! AnotherKindOfPane,
|
||||
//! }
|
||||
//!
|
||||
//! enum Message {
|
||||
//! PaneDragged(pane_grid::DragEvent),
|
||||
//! PaneResized(pane_grid::ResizeEvent),
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! pane_grid(&state.panes, |pane, state, is_maximized| {
|
||||
//! pane_grid::Content::new(match state {
|
||||
//! Pane::SomePane => text("This is some pane"),
|
||||
//! Pane::AnotherKindOfPane => text("This is another kind of pane"),
|
||||
//! })
|
||||
//! })
|
||||
//! .on_drag(Message::PaneDragged)
|
||||
//! .on_resize(10, Message::PaneResized)
|
||||
//! .into()
|
||||
//! }
|
||||
//! ```
|
||||
//! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing,
|
||||
//! drag and drop, and hotkey support.
|
||||
//!
|
||||
|
|
@ -68,14 +114,18 @@ const THICKNESS_RATIO: f32 = 25.0;
|
|||
/// * Configurable modifier keys
|
||||
/// * [`State`] API to perform actions programmatically (`split`, `swap`, `resize`, etc.)
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # use iced_widget::{pane_grid, text};
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// #
|
||||
/// # type PaneGrid<'a, Message> = iced_widget::PaneGrid<'a, Message>;
|
||||
/// #
|
||||
/// enum PaneState {
|
||||
/// use iced::widget::{pane_grid, text};
|
||||
///
|
||||
/// struct State {
|
||||
/// panes: pane_grid::State<Pane>,
|
||||
/// }
|
||||
///
|
||||
/// enum Pane {
|
||||
/// SomePane,
|
||||
/// AnotherKindOfPane,
|
||||
/// }
|
||||
|
|
@ -85,17 +135,17 @@ const THICKNESS_RATIO: f32 = 25.0;
|
|||
/// PaneResized(pane_grid::ResizeEvent),
|
||||
/// }
|
||||
///
|
||||
/// let (mut state, _) = pane_grid::State::new(PaneState::SomePane);
|
||||
///
|
||||
/// let pane_grid =
|
||||
/// PaneGrid::new(&state, |pane, state, is_maximized| {
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// pane_grid(&state.panes, |pane, state, is_maximized| {
|
||||
/// pane_grid::Content::new(match state {
|
||||
/// PaneState::SomePane => text("This is some pane"),
|
||||
/// PaneState::AnotherKindOfPane => text("This is another kind of pane"),
|
||||
/// Pane::SomePane => text("This is some pane"),
|
||||
/// Pane::AnotherKindOfPane => text("This is another kind of pane"),
|
||||
/// })
|
||||
/// })
|
||||
/// .on_drag(Message::PaneDragged)
|
||||
/// .on_resize(10, Message::PaneResized);
|
||||
/// .on_resize(10, Message::PaneResized)
|
||||
/// .into()
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct PaneGrid<
|
||||
|
|
|
|||
|
|
@ -1,4 +1,65 @@
|
|||
//! Display a dropdown list of selectable values.
|
||||
//! Pick lists display a dropdown list of selectable options.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! #
|
||||
//! use iced::widget::pick_list;
|
||||
//!
|
||||
//! struct State {
|
||||
//! favorite: Option<Fruit>,
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
//! enum Fruit {
|
||||
//! Apple,
|
||||
//! Orange,
|
||||
//! Strawberry,
|
||||
//! Tomato,
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(Debug, Clone)]
|
||||
//! enum Message {
|
||||
//! FruitSelected(Fruit),
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! let fruits = [
|
||||
//! Fruit::Apple,
|
||||
//! Fruit::Orange,
|
||||
//! Fruit::Strawberry,
|
||||
//! Fruit::Tomato,
|
||||
//! ];
|
||||
//!
|
||||
//! pick_list(
|
||||
//! fruits,
|
||||
//! state.favorite,
|
||||
//! Message::FruitSelected,
|
||||
//! )
|
||||
//! .placeholder("Select your favorite fruit...")
|
||||
//! .into()
|
||||
//! }
|
||||
//!
|
||||
//! fn update(state: &mut State, message: Message) {
|
||||
//! match message {
|
||||
//! Message::FruitSelected(fruit) => {
|
||||
//! state.favorite = Some(fruit);
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! impl std::fmt::Display for Fruit {
|
||||
//! fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
//! f.write_str(match self {
|
||||
//! Self::Apple => "Apple",
|
||||
//! Self::Orange => "Orange",
|
||||
//! Self::Strawberry => "Strawberry",
|
||||
//! Self::Tomato => "Tomato",
|
||||
//! })
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
use crate::core::alignment;
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::keyboard;
|
||||
|
|
@ -20,6 +81,67 @@ use std::borrow::Borrow;
|
|||
use std::f32;
|
||||
|
||||
/// A widget for selecting a single value from a list of options.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// #
|
||||
/// use iced::widget::pick_list;
|
||||
///
|
||||
/// struct State {
|
||||
/// favorite: Option<Fruit>,
|
||||
/// }
|
||||
///
|
||||
/// #[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
/// enum Fruit {
|
||||
/// Apple,
|
||||
/// Orange,
|
||||
/// Strawberry,
|
||||
/// Tomato,
|
||||
/// }
|
||||
///
|
||||
/// #[derive(Debug, Clone)]
|
||||
/// enum Message {
|
||||
/// FruitSelected(Fruit),
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// let fruits = [
|
||||
/// Fruit::Apple,
|
||||
/// Fruit::Orange,
|
||||
/// Fruit::Strawberry,
|
||||
/// Fruit::Tomato,
|
||||
/// ];
|
||||
///
|
||||
/// pick_list(
|
||||
/// fruits,
|
||||
/// state.favorite,
|
||||
/// Message::FruitSelected,
|
||||
/// )
|
||||
/// .placeholder("Select your favorite fruit...")
|
||||
/// .into()
|
||||
/// }
|
||||
///
|
||||
/// fn update(state: &mut State, message: Message) {
|
||||
/// match message {
|
||||
/// Message::FruitSelected(fruit) => {
|
||||
/// state.favorite = Some(fruit);
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl std::fmt::Display for Fruit {
|
||||
/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
/// f.write_str(match self {
|
||||
/// Self::Apple => "Apple",
|
||||
/// Self::Orange => "Orange",
|
||||
/// Self::Strawberry => "Strawberry",
|
||||
/// Self::Tomato => "Tomato",
|
||||
/// })
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct PickList<
|
||||
'a,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,24 @@
|
|||
//! Provide progress feedback to your users.
|
||||
//! Progress bars visualize the progression of an extended computer operation, such as a download, file transfer, or installation.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! #
|
||||
//! use iced::widget::progress_bar;
|
||||
//!
|
||||
//! struct State {
|
||||
//! progress: f32,
|
||||
//! }
|
||||
//!
|
||||
//! enum Message {
|
||||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! progress_bar(0.0..=100.0, state.progress).into()
|
||||
//! }
|
||||
//! ```
|
||||
use crate::core::border::{self, Border};
|
||||
use crate::core::layout;
|
||||
use crate::core::mouse;
|
||||
|
|
@ -15,14 +35,23 @@ use std::ops::RangeInclusive;
|
|||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # type ProgressBar<'a> = iced_widget::ProgressBar<'a>;
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// #
|
||||
/// let value = 50.0;
|
||||
/// use iced::widget::progress_bar;
|
||||
///
|
||||
/// ProgressBar::new(0.0..=100.0, value);
|
||||
/// struct State {
|
||||
/// progress: f32,
|
||||
/// }
|
||||
///
|
||||
/// enum Message {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// progress_bar(0.0..=100.0, state.progress).into()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// 
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct ProgressBar<'a, Theme = crate::Theme>
|
||||
where
|
||||
|
|
|
|||
|
|
@ -1,4 +1,25 @@
|
|||
//! Encode and display information in a QR code.
|
||||
//! QR codes display information in a type of two-dimensional matrix barcode.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! #
|
||||
//! use iced::widget::qr_code;
|
||||
//!
|
||||
//! struct State {
|
||||
//! data: qr_code::Data,
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(Debug, Clone)]
|
||||
//! enum Message {
|
||||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! qr_code(&state.data).into()
|
||||
//! }
|
||||
//! ```
|
||||
use crate::canvas;
|
||||
use crate::core::layout;
|
||||
use crate::core::mouse;
|
||||
|
|
@ -18,6 +39,27 @@ const QUIET_ZONE: usize = 2;
|
|||
|
||||
/// A type of matrix barcode consisting of squares arranged in a grid which
|
||||
/// can be read by an imaging device, such as a camera.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// #
|
||||
/// use iced::widget::qr_code;
|
||||
///
|
||||
/// struct State {
|
||||
/// data: qr_code::Data,
|
||||
/// }
|
||||
///
|
||||
/// #[derive(Debug, Clone)]
|
||||
/// enum Message {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// qr_code(&state.data).into()
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct QRCode<'a, Theme = crate::Theme>
|
||||
where
|
||||
|
|
|
|||
|
|
@ -1,4 +1,61 @@
|
|||
//! Create choices using radio buttons.
|
||||
//! Radio buttons let users choose a single option from a bunch of options.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! #
|
||||
//! use iced::widget::{column, radio};
|
||||
//!
|
||||
//! struct State {
|
||||
//! selection: Option<Choice>,
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(Debug, Clone, Copy)]
|
||||
//! enum Message {
|
||||
//! RadioSelected(Choice),
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
//! enum Choice {
|
||||
//! A,
|
||||
//! B,
|
||||
//! C,
|
||||
//! All,
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! let a = radio(
|
||||
//! "A",
|
||||
//! Choice::A,
|
||||
//! state.selection,
|
||||
//! Message::RadioSelected,
|
||||
//! );
|
||||
//!
|
||||
//! let b = radio(
|
||||
//! "B",
|
||||
//! Choice::B,
|
||||
//! state.selection,
|
||||
//! Message::RadioSelected,
|
||||
//! );
|
||||
//!
|
||||
//! let c = radio(
|
||||
//! "C",
|
||||
//! Choice::C,
|
||||
//! state.selection,
|
||||
//! Message::RadioSelected,
|
||||
//! );
|
||||
//!
|
||||
//! let all = radio(
|
||||
//! "All of the above",
|
||||
//! Choice::All,
|
||||
//! state.selection,
|
||||
//! Message::RadioSelected
|
||||
//! );
|
||||
//!
|
||||
//! column![a, b, c, all].into()
|
||||
//! }
|
||||
//! ```
|
||||
use crate::core::alignment;
|
||||
use crate::core::border::{self, Border};
|
||||
use crate::core::event::{self, Event};
|
||||
|
|
@ -18,54 +75,59 @@ use crate::core::{
|
|||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # type Radio<'a, Message> =
|
||||
/// # iced_widget::Radio<'a, Message, iced_widget::Theme, iced_widget::renderer::Renderer>;
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// #
|
||||
/// # use iced_widget::column;
|
||||
/// use iced::widget::{column, radio};
|
||||
///
|
||||
/// struct State {
|
||||
/// selection: Option<Choice>,
|
||||
/// }
|
||||
///
|
||||
/// #[derive(Debug, Clone, Copy)]
|
||||
/// enum Message {
|
||||
/// RadioSelected(Choice),
|
||||
/// }
|
||||
///
|
||||
/// #[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
/// pub enum Choice {
|
||||
/// enum Choice {
|
||||
/// A,
|
||||
/// B,
|
||||
/// C,
|
||||
/// All,
|
||||
/// }
|
||||
///
|
||||
/// #[derive(Debug, Clone, Copy)]
|
||||
/// pub enum Message {
|
||||
/// RadioSelected(Choice),
|
||||
/// }
|
||||
///
|
||||
/// let selected_choice = Some(Choice::A);
|
||||
///
|
||||
/// let a = Radio::new(
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// let a = radio(
|
||||
/// "A",
|
||||
/// Choice::A,
|
||||
/// selected_choice,
|
||||
/// state.selection,
|
||||
/// Message::RadioSelected,
|
||||
/// );
|
||||
///
|
||||
/// let b = Radio::new(
|
||||
/// let b = radio(
|
||||
/// "B",
|
||||
/// Choice::B,
|
||||
/// selected_choice,
|
||||
/// state.selection,
|
||||
/// Message::RadioSelected,
|
||||
/// );
|
||||
///
|
||||
/// let c = Radio::new(
|
||||
/// let c = radio(
|
||||
/// "C",
|
||||
/// Choice::C,
|
||||
/// selected_choice,
|
||||
/// state.selection,
|
||||
/// Message::RadioSelected,
|
||||
/// );
|
||||
///
|
||||
/// let all = Radio::new(
|
||||
/// let all = radio(
|
||||
/// "All of the above",
|
||||
/// Choice::All,
|
||||
/// selected_choice,
|
||||
/// state.selection,
|
||||
/// Message::RadioSelected
|
||||
/// );
|
||||
///
|
||||
/// let content = column![a, b, c, all];
|
||||
/// column![a, b, c, all].into()
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Radio<'a, Message, Theme = crate::Theme, Renderer = crate::Renderer>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,27 @@ use crate::core::{
|
|||
};
|
||||
|
||||
/// A container that distributes its contents horizontally.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
/// # pub type State = ();
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// use iced::widget::{button, row};
|
||||
///
|
||||
/// #[derive(Debug, Clone)]
|
||||
/// enum Message {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// row![
|
||||
/// "I am to the left!",
|
||||
/// button("I am in the middle!"),
|
||||
/// "I am to the right!",
|
||||
/// ].into()
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Row<'a, Message, Theme = crate::Theme, Renderer = crate::Renderer> {
|
||||
spacing: f32,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,21 @@
|
|||
//! Display a horizontal or vertical rule for dividing content.
|
||||
//! Rules divide space horizontally or vertically.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
//! # pub type State = ();
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! use iced::widget::horizontal_rule;
|
||||
//!
|
||||
//! #[derive(Clone)]
|
||||
//! enum Message {
|
||||
//! // ...,
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! horizontal_rule(2).into()
|
||||
//! }
|
||||
//! ```
|
||||
use crate::core;
|
||||
use crate::core::border;
|
||||
use crate::core::layout;
|
||||
|
|
@ -10,6 +27,23 @@ use crate::core::{
|
|||
};
|
||||
|
||||
/// Display a horizontal or vertical rule for dividing content.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
/// # pub type State = ();
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// use iced::widget::horizontal_rule;
|
||||
///
|
||||
/// #[derive(Clone)]
|
||||
/// enum Message {
|
||||
/// // ...,
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// horizontal_rule(2).into()
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Rule<'a, Theme = crate::Theme>
|
||||
where
|
||||
|
|
|
|||
|
|
@ -1,4 +1,24 @@
|
|||
//! Navigate an endless amount of content with a scrollbar.
|
||||
//! Scrollables let users navigate an endless amount of content with a scrollbar.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
//! # pub type State = ();
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! use iced::widget::{column, scrollable, vertical_space};
|
||||
//!
|
||||
//! enum Message {
|
||||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! scrollable(column![
|
||||
//! "Scroll me!",
|
||||
//! vertical_space().height(3000),
|
||||
//! "You did it!",
|
||||
//! ]).into()
|
||||
//! }
|
||||
//! ```
|
||||
use crate::container;
|
||||
use crate::core::border::{self, Border};
|
||||
use crate::core::event::{self, Event};
|
||||
|
|
@ -24,6 +44,26 @@ pub use operation::scrollable::{AbsoluteOffset, RelativeOffset};
|
|||
|
||||
/// A widget that can vertically display an infinite amount of content with a
|
||||
/// scrollbar.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
/// # pub type State = ();
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// use iced::widget::{column, scrollable, vertical_space};
|
||||
///
|
||||
/// enum Message {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// scrollable(column![
|
||||
/// "Scroll me!",
|
||||
/// vertical_space().height(3000),
|
||||
/// "You did it!",
|
||||
/// ]).into()
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Scrollable<
|
||||
'a,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,33 @@
|
|||
//! Display an interactive selector of a single value from a range of values.
|
||||
//! Sliders let users set a value by moving an indicator.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! #
|
||||
//! use iced::widget::slider;
|
||||
//!
|
||||
//! struct State {
|
||||
//! value: f32,
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(Debug, Clone)]
|
||||
//! enum Message {
|
||||
//! ValueChanged(f32),
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! slider(0.0..=100.0, state.value, Message::ValueChanged).into()
|
||||
//! }
|
||||
//!
|
||||
//! fn update(state: &mut State, message: Message) {
|
||||
//! match message {
|
||||
//! Message::ValueChanged(value) => {
|
||||
//! state.value = value;
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
use crate::core::border::{self, Border};
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::keyboard;
|
||||
|
|
@ -25,19 +54,32 @@ use std::ops::RangeInclusive;
|
|||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # type Slider<'a, T, Message> = iced_widget::Slider<'a, Message, T>;
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// #
|
||||
/// #[derive(Clone)]
|
||||
/// pub enum Message {
|
||||
/// SliderChanged(f32),
|
||||
/// use iced::widget::slider;
|
||||
///
|
||||
/// struct State {
|
||||
/// value: f32,
|
||||
/// }
|
||||
///
|
||||
/// let value = 50.0;
|
||||
/// #[derive(Debug, Clone)]
|
||||
/// enum Message {
|
||||
/// ValueChanged(f32),
|
||||
/// }
|
||||
///
|
||||
/// Slider::new(0.0..=100.0, value, Message::SliderChanged);
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// slider(0.0..=100.0, state.value, Message::ValueChanged).into()
|
||||
/// }
|
||||
///
|
||||
/// fn update(state: &mut State, message: Message) {
|
||||
/// match message {
|
||||
/// Message::ValueChanged(value) => {
|
||||
/// state.value = value;
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// 
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Slider<'a, T, Message, Theme = crate::Theme>
|
||||
where
|
||||
|
|
|
|||
|
|
@ -1,4 +1,20 @@
|
|||
//! Display vector graphics in your application.
|
||||
//! Svg widgets display vector graphics in your application.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
//! # pub type State = ();
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! use iced::widget::svg;
|
||||
//!
|
||||
//! enum Message {
|
||||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! svg("tiger.svg").into()
|
||||
//! }
|
||||
//! ```
|
||||
use crate::core::layout;
|
||||
use crate::core::mouse;
|
||||
use crate::core::renderer;
|
||||
|
|
@ -19,6 +35,22 @@ pub use crate::core::svg::Handle;
|
|||
///
|
||||
/// [`Svg`] images can have a considerable rendering cost when resized,
|
||||
/// specially when they are complex.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
/// # pub type State = ();
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// use iced::widget::svg;
|
||||
///
|
||||
/// enum Message {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// svg("tiger.svg").into()
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Svg<'a, Theme = crate::Theme>
|
||||
where
|
||||
|
|
|
|||
|
|
@ -5,6 +5,26 @@ pub use crate::core::text::{Fragment, Highlighter, IntoFragment, Span};
|
|||
pub use crate::core::widget::text::*;
|
||||
pub use rich::Rich;
|
||||
|
||||
/// A paragraph.
|
||||
/// A bunch of text.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type State = ();
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// use iced::widget::text;
|
||||
/// use iced::color;
|
||||
///
|
||||
/// enum Message {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// text("Hello, this is iced!")
|
||||
/// .size(20)
|
||||
/// .color(color!(0x0000ff))
|
||||
/// .into()
|
||||
/// }
|
||||
/// ```
|
||||
pub type Text<'a, Theme = crate::Theme, Renderer = crate::Renderer> =
|
||||
crate::core::widget::Text<'a, Theme, Renderer>;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,36 @@
|
|||
//! Display a multi-line text input for text editing.
|
||||
//! Text editors display a multi-line text input for text editing.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! #
|
||||
//! use iced::widget::text_editor;
|
||||
//!
|
||||
//! struct State {
|
||||
//! content: text_editor::Content,
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(Debug, Clone)]
|
||||
//! enum Message {
|
||||
//! Edit(text_editor::Action)
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! text_editor(&state.content)
|
||||
//! .placeholder("Type something here...")
|
||||
//! .on_action(Message::Edit)
|
||||
//! .into()
|
||||
//! }
|
||||
//!
|
||||
//! fn update(state: &mut State, message: Message) {
|
||||
//! match message {
|
||||
//! Message::Edit(action) => {
|
||||
//! state.content.perform(action);
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
use crate::core::alignment;
|
||||
use crate::core::clipboard::{self, Clipboard};
|
||||
use crate::core::event::{self, Event};
|
||||
|
|
@ -27,6 +59,38 @@ use std::sync::Arc;
|
|||
pub use text::editor::{Action, Edit, Motion};
|
||||
|
||||
/// A multi-line text input.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// #
|
||||
/// use iced::widget::text_editor;
|
||||
///
|
||||
/// struct State {
|
||||
/// content: text_editor::Content,
|
||||
/// }
|
||||
///
|
||||
/// #[derive(Debug, Clone)]
|
||||
/// enum Message {
|
||||
/// Edit(text_editor::Action)
|
||||
/// }
|
||||
///
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// text_editor(&state.content)
|
||||
/// .placeholder("Type something here...")
|
||||
/// .on_action(Message::Edit)
|
||||
/// .into()
|
||||
/// }
|
||||
///
|
||||
/// fn update(state: &mut State, message: Message) {
|
||||
/// match message {
|
||||
/// Message::Edit(action) => {
|
||||
/// state.content.perform(action);
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct TextEditor<
|
||||
'a,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,35 @@
|
|||
//! Display fields that can be filled with text.
|
||||
//! Text inputs display fields that can be filled with text.
|
||||
//!
|
||||
//! A [`TextInput`] has some local [`State`].
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! #
|
||||
//! use iced::widget::text_input;
|
||||
//!
|
||||
//! struct State {
|
||||
//! content: String,
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(Debug, Clone)]
|
||||
//! enum Message {
|
||||
//! ContentChanged(String)
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! text_input("Type something here...", &state.content)
|
||||
//! .on_input(Message::ContentChanged)
|
||||
//! .into()
|
||||
//! }
|
||||
//!
|
||||
//! fn update(state: &mut State, message: Message) {
|
||||
//! match message {
|
||||
//! Message::ContentChanged(content) => {
|
||||
//! state.content = content;
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
mod editor;
|
||||
mod value;
|
||||
|
||||
|
|
@ -38,23 +67,34 @@ use crate::runtime::Action;
|
|||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # pub type TextInput<'a, Message> = iced_widget::TextInput<'a, Message>;
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// #
|
||||
/// #[derive(Debug, Clone)]
|
||||
/// enum Message {
|
||||
/// TextInputChanged(String),
|
||||
/// use iced::widget::text_input;
|
||||
///
|
||||
/// struct State {
|
||||
/// content: String,
|
||||
/// }
|
||||
///
|
||||
/// let value = "Some text";
|
||||
/// #[derive(Debug, Clone)]
|
||||
/// enum Message {
|
||||
/// ContentChanged(String)
|
||||
/// }
|
||||
///
|
||||
/// let input = TextInput::new(
|
||||
/// "This is the placeholder...",
|
||||
/// value,
|
||||
/// )
|
||||
/// .on_input(Message::TextInputChanged)
|
||||
/// .padding(10);
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// text_input("Type something here...", &state.content)
|
||||
/// .on_input(Message::ContentChanged)
|
||||
/// .into()
|
||||
/// }
|
||||
///
|
||||
/// fn update(state: &mut State, message: Message) {
|
||||
/// match message {
|
||||
/// Message::ContentChanged(content) => {
|
||||
/// state.content = content;
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// 
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct TextInput<
|
||||
'a,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,35 @@
|
|||
//! Show toggle controls using togglers.
|
||||
//! Togglers let users make binary choices by toggling a switch.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! #
|
||||
//! use iced::widget::toggler;
|
||||
//!
|
||||
//! struct State {
|
||||
//! is_checked: bool,
|
||||
//! }
|
||||
//!
|
||||
//! enum Message {
|
||||
//! TogglerToggled(bool),
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! toggler(state.is_checked)
|
||||
//! .label("Toggle me!")
|
||||
//! .on_toggle(Message::TogglerToggled)
|
||||
//! .into()
|
||||
//! }
|
||||
//!
|
||||
//! fn update(state: &mut State, message: Message) {
|
||||
//! match message {
|
||||
//! Message::TogglerToggled(is_checked) => {
|
||||
//! state.is_checked = is_checked;
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
use crate::core::alignment;
|
||||
use crate::core::event;
|
||||
use crate::core::layout;
|
||||
|
|
@ -16,19 +47,34 @@ use crate::core::{
|
|||
/// A toggler widget.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # type Toggler<'a, Message> = iced_widget::Toggler<'a, Message>;
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// #
|
||||
/// pub enum Message {
|
||||
/// use iced::widget::toggler;
|
||||
///
|
||||
/// struct State {
|
||||
/// is_checked: bool,
|
||||
/// }
|
||||
///
|
||||
/// enum Message {
|
||||
/// TogglerToggled(bool),
|
||||
/// }
|
||||
///
|
||||
/// let is_toggled = true;
|
||||
///
|
||||
/// Toggler::new(is_toggled)
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// toggler(state.is_checked)
|
||||
/// .label("Toggle me!")
|
||||
/// .on_toggle(Message::TogglerToggled);
|
||||
/// .on_toggle(Message::TogglerToggled)
|
||||
/// .into()
|
||||
/// }
|
||||
///
|
||||
/// fn update(state: &mut State, message: Message) {
|
||||
/// match message {
|
||||
/// Message::TogglerToggled(is_checked) => {
|
||||
/// state.is_checked = is_checked;
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Toggler<
|
||||
|
|
|
|||
|
|
@ -1,4 +1,26 @@
|
|||
//! Display a widget over another.
|
||||
//! Tooltips display a hint of information over some element when hovered.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
//! # pub type State = ();
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! use iced::widget::{container, tooltip};
|
||||
//!
|
||||
//! enum Message {
|
||||
//! // ...
|
||||
//! }
|
||||
//!
|
||||
//! fn view(_state: &State) -> Element<'_, Message> {
|
||||
//! tooltip(
|
||||
//! "Hover me to display the tooltip!",
|
||||
//! container("This is the tooltip contents!")
|
||||
//! .padding(10)
|
||||
//! .style(container::rounded_box),
|
||||
//! tooltip::Position::Bottom,
|
||||
//! ).into()
|
||||
//! }
|
||||
//! ```
|
||||
use crate::container;
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::layout::{self, Layout};
|
||||
|
|
@ -13,6 +35,28 @@ use crate::core::{
|
|||
};
|
||||
|
||||
/// An element to display a widget over another.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } }
|
||||
/// # pub type State = ();
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// use iced::widget::{container, tooltip};
|
||||
///
|
||||
/// enum Message {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// fn view(_state: &State) -> Element<'_, Message> {
|
||||
/// tooltip(
|
||||
/// "Hover me to display the tooltip!",
|
||||
/// container("This is the tooltip contents!")
|
||||
/// .padding(10)
|
||||
/// .style(container::rounded_box),
|
||||
/// tooltip::Position::Bottom,
|
||||
/// ).into()
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Tooltip<
|
||||
'a,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,33 @@
|
|||
//! Display an interactive selector of a single value from a range of values.
|
||||
//! Sliders let users set a value by moving an indicator.
|
||||
//!
|
||||
//! # Example
|
||||
//! ```no_run
|
||||
//! # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
//! # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
//! #
|
||||
//! use iced::widget::slider;
|
||||
//!
|
||||
//! struct State {
|
||||
//! value: f32,
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(Debug, Clone)]
|
||||
//! enum Message {
|
||||
//! ValueChanged(f32),
|
||||
//! }
|
||||
//!
|
||||
//! fn view(state: &State) -> Element<'_, Message> {
|
||||
//! slider(0.0..=100.0, state.value, Message::ValueChanged).into()
|
||||
//! }
|
||||
//!
|
||||
//! fn update(state: &mut State, message: Message) {
|
||||
//! match message {
|
||||
//! Message::ValueChanged(value) => {
|
||||
//! state.value = value;
|
||||
//! }
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
pub use crate::slider::{
|
||||
|
|
@ -29,16 +58,31 @@ use crate::core::{
|
|||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # type VerticalSlider<'a, T, Message> = iced_widget::VerticalSlider<'a, T, Message>;
|
||||
/// # mod iced { pub mod widget { pub use iced_widget::*; } pub use iced_widget::Renderer; pub use iced_widget::core::*; }
|
||||
/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
|
||||
/// #
|
||||
/// #[derive(Clone)]
|
||||
/// pub enum Message {
|
||||
/// SliderChanged(f32),
|
||||
/// use iced::widget::vertical_slider;
|
||||
///
|
||||
/// struct State {
|
||||
/// value: f32,
|
||||
/// }
|
||||
///
|
||||
/// let value = 50.0;
|
||||
/// #[derive(Debug, Clone)]
|
||||
/// enum Message {
|
||||
/// ValueChanged(f32),
|
||||
/// }
|
||||
///
|
||||
/// VerticalSlider::new(0.0..=100.0, value, Message::SliderChanged);
|
||||
/// fn view(state: &State) -> Element<'_, Message> {
|
||||
/// vertical_slider(0.0..=100.0, state.value, Message::ValueChanged).into()
|
||||
/// }
|
||||
///
|
||||
/// fn update(state: &mut State, message: Message) {
|
||||
/// match message {
|
||||
/// Message::ValueChanged(value) => {
|
||||
/// state.value = value;
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct VerticalSlider<'a, T, Message, Theme = crate::Theme>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue