diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/application.rs | 13 | ||||
-rw-r--r-- | src/lib.rs | 55 | ||||
-rw-r--r-- | src/pure.rs | 112 | ||||
-rw-r--r-- | src/pure/application.rs | 195 | ||||
-rw-r--r-- | src/pure/sandbox.rs | 123 | ||||
-rw-r--r-- | src/pure/widget.rs | 174 | ||||
-rw-r--r-- | src/sandbox.rs | 10 | ||||
-rw-r--r-- | src/widget.rs | 50 |
8 files changed, 49 insertions, 683 deletions
diff --git a/src/application.rs b/src/application.rs index aca97367..58d4a577 100644 --- a/src/application.rs +++ b/src/application.rs @@ -60,7 +60,8 @@ pub use iced_native::application::{Appearance, StyleSheet}; /// says "Hello, world!": /// /// ```no_run -/// use iced::{executor, Application, Command, Element, Settings, Text, Theme}; +/// use iced::executor; +/// use iced::{Application, Command, Element, Settings, Theme}; /// /// pub fn main() -> iced::Result { /// Hello::run(Settings::default()) @@ -86,8 +87,8 @@ pub use iced_native::application::{Appearance, StyleSheet}; /// Command::none() /// } /// -/// fn view(&mut self) -> Element<Self::Message> { -/// Text::new("Hello, world!").into() +/// fn view(&self) -> Element<Self::Message> { +/// "Hello, world!".into() /// } /// } /// ``` @@ -139,9 +140,7 @@ pub trait Application: Sized { /// Returns the widgets to display in the [`Application`]. /// /// These widgets can produce __messages__ based on user interaction. - fn view( - &mut self, - ) -> Element<'_, Self::Message, crate::Renderer<Self::Theme>>; + fn view(&self) -> Element<'_, Self::Message, crate::Renderer<Self::Theme>>; /// Returns the current [`Theme`] of the [`Application`]. /// @@ -249,7 +248,7 @@ where self.0.update(message) } - fn view(&mut self) -> Element<'_, Self::Message, Self::Renderer> { + fn view(&self) -> Element<'_, Self::Message, Self::Renderer> { self.0.view() } } @@ -51,15 +51,9 @@ //! We start by modelling the __state__ of our application: //! //! ``` -//! use iced::button; -//! //! struct Counter { //! // The counter value //! value: i32, -//! -//! // The local state of the two buttons -//! increment_button: button::State, -//! decrement_button: button::State, //! } //! ``` //! @@ -78,15 +72,9 @@ //! __view logic__: //! //! ``` -//! # use iced::button; -//! # //! # struct Counter { //! # // The counter value //! # value: i32, -//! # -//! # // The local state of the two buttons -//! # increment_button: button::State, -//! # decrement_button: button::State, //! # } //! # //! # #[derive(Debug, Clone, Copy)] @@ -95,28 +83,22 @@ //! # DecrementPressed, //! # } //! # -//! use iced::{Button, Column, Text}; +//! use iced::widget::{button, column, text, Column}; //! //! impl Counter { //! pub fn view(&mut self) -> Column<Message> { //! // We use a column: a simple vertical layout -//! Column::new() -//! .push( -//! // The increment button. We tell it to produce an -//! // `IncrementPressed` message when pressed -//! Button::new(&mut self.increment_button, Text::new("+")) -//! .on_press(Message::IncrementPressed), -//! ) -//! .push( -//! // We show the value of the counter here -//! Text::new(self.value.to_string()).size(50), -//! ) -//! .push( -//! // The decrement button. We tell it to produce a -//! // `DecrementPressed` message when pressed -//! Button::new(&mut self.decrement_button, Text::new("-")) -//! .on_press(Message::DecrementPressed), -//! ) +//! column![ +//! // The increment button. We tell it to produce an +//! // `IncrementPressed` message when pressed +//! button("+").on_press(Message::IncrementPressed), +//! +//! // We show the value of the counter here +//! text(self.value.to_string()).size(50), +//! +//! // The decrement button. We tell it to produce a +//! button("-").on_press(Message::DecrementPressed), +//! ] //! } //! } //! ``` @@ -125,15 +107,9 @@ //! our __state__ accordingly in our __update logic__: //! //! ``` -//! # use iced::button; -//! # //! # struct Counter { //! # // The counter value //! # value: i32, -//! # -//! # // The local state of the two buttons -//! # increment_button: button::State, -//! # decrement_button: button::State, //! # } //! # //! # #[derive(Debug, Clone, Copy)] @@ -203,10 +179,6 @@ pub mod time; pub mod widget; pub mod window; -#[cfg(feature = "pure")] -#[cfg_attr(docsrs, doc(cfg(feature = "pure")))] -pub mod pure; - #[cfg(all(not(feature = "glow"), feature = "wgpu"))] use iced_winit as runtime; @@ -221,9 +193,6 @@ use iced_glow as renderer; pub use iced_native::theme; -#[doc(no_inline)] -pub use widget::*; - pub use application::Application; pub use element::Element; pub use error::Error; diff --git a/src/pure.rs b/src/pure.rs deleted file mode 100644 index 23f56570..00000000 --- a/src/pure.rs +++ /dev/null @@ -1,112 +0,0 @@ -//! Leverage pure, virtual widgets in your application. -//! -//! The widgets found in this module are completely stateless versions of -//! [the original widgets]. -//! -//! Effectively, this means that, as a user of the library, you do not need to -//! keep track of the local state of each widget (e.g. [`button::State`]). -//! Instead, the runtime will keep track of everything for you! -//! -//! You can embed pure widgets anywhere in your [impure `Application`] using the -//! [`Pure`] widget and some [`State`]. -//! -//! In case you want to only use pure widgets in your application, this module -//! offers an alternate [`Application`] trait with a completely pure `view` -//! method. -//! -//! # The Elm Architecture, purity, and continuity -//! As you may know, applications made with `iced` use [The Elm Architecture]. -//! -//! In a nutshell, this architecture defines the initial state of the application, a way to `view` it, and a way to `update` it after a user interaction. The `update` logic is called after a meaningful user interaction, which in turn updates the state of the application. Then, the `view` logic is executed to redisplay the application. -//! -//! Since `view` logic is only run after an `update`, all of the mutations to the application state must only happen in the `update` logic. If the application state changes anywhere else, the `view` logic will not be rerun and, therefore, the previously generated `view` may stay outdated. -//! -//! However, the `Application` trait in `iced` defines `view` as: -//! -//! ```ignore -//! pub trait Application { -//! fn view(&mut self) -> Element<Self::Message>; -//! } -//! ``` -//! -//! As a consequence, the application state can be mutated in `view` logic. The `view` logic in `iced` is __impure__. -//! -//! This impurity is necessary because `iced` puts the burden of widget __continuity__ on its users. In other words, it's up to you to provide `iced` with the internal state of each widget every time `view` is called. -//! -//! If we take a look at the classic `counter` example: -//! -//! ```ignore -//! struct Counter { -//! value: i32, -//! increment_button: button::State, -//! decrement_button: button::State, -//! } -//! -//! // ... -//! -//! impl Counter { -//! pub fn view(&mut self) -> Column<Message> { -//! Column::new() -//! .push( -//! Button::new(&mut self.increment_button, Text::new("+")) -//! .on_press(Message::IncrementPressed), -//! ) -//! .push(Text::new(self.value.to_string()).size(50)) -//! .push( -//! Button::new(&mut self.decrement_button, Text::new("-")) -//! .on_press(Message::DecrementPressed), -//! ) -//! } -//! } -//! ``` -//! -//! We can see how we need to keep track of the `button::State` of each `Button` in our `Counter` state and provide a mutable reference to the widgets in our `view` logic. The widgets produced by `view` are __stateful__. -//! -//! While this approach forces users to keep track of widget state and causes impurity, I originally chose it because it allows `iced` to directly consume the widget tree produced by `view`. Since there is no internal state decoupled from `view` maintained by the runtime, `iced` does not need to compare (e.g. reconciliate) widget trees in order to ensure continuity. -//! -//! # Stateless widgets -//! As the library matures, the need for some kind of persistent widget data (see #553) between `view` calls becomes more apparent (e.g. incremental rendering, animations, accessibility, etc.). -//! -//! If we are going to end up having persistent widget data anyways... There is no reason to have impure, stateful widgets anymore! -//! -//! With the help of this module, we can now write a pure `counter` example: -//! -//! ```ignore -//! struct Counter { -//! value: i32, -//! } -//! -//! // ... -//! -//! impl Counter { -//! fn view(&self) -> Column<Message> { -//! Column::new() -//! .push(Button::new("Increment").on_press(Message::IncrementPressed)) -//! .push(Text::new(self.value.to_string()).size(50)) -//! .push(Button::new("Decrement").on_press(Message::DecrementPressed)) -//! } -//! } -//! ``` -//! -//! Notice how we no longer need to keep track of the `button::State`! The widgets in `iced_pure` do not take any mutable application state in `view`. They are __stateless__ widgets. As a consequence, we do not need mutable access to `self` in `view` anymore. `view` becomes __pure__. -//! -//! [The Elm Architecture]: https://guide.elm-lang.org/architecture/ -//! -//! [the original widgets]: crate::widget -//! [`button::State`]: crate::widget::button::State -//! [impure `Application`]: crate::Application -pub mod application; -pub mod widget; - -mod sandbox; - -pub use application::Application; -pub use sandbox::Sandbox; - -pub use iced_pure::helpers::*; -pub use iced_pure::Widget; -pub use iced_pure::{Pure, State}; - -/// A generic, pure [`Widget`]. -pub type Element<'a, Message, Renderer = crate::Renderer> = - iced_pure::Element<'a, Message, Renderer>; diff --git a/src/pure/application.rs b/src/pure/application.rs deleted file mode 100644 index 396854ad..00000000 --- a/src/pure/application.rs +++ /dev/null @@ -1,195 +0,0 @@ -//! Build interactive cross-platform applications. -use crate::pure::{self, Pure}; -use crate::window; -use crate::{Command, Executor, Settings, Subscription}; - -pub use iced_native::application::StyleSheet; - -/// A pure version of [`Application`]. -/// -/// Unlike the impure version, the `view` method of this trait takes an -/// immutable reference to `self` and returns a pure [`Element`]. -/// -/// [`Application`]: crate::Application -/// [`Element`]: pure::Element -pub trait Application: Sized { - /// The [`Executor`] that will run commands and subscriptions. - /// - /// The [default executor] can be a good starting point! - /// - /// [`Executor`]: Self::Executor - /// [default executor]: crate::executor::Default - type Executor: Executor; - - /// The type of __messages__ your [`Application`] will produce. - type Message: std::fmt::Debug + Send; - - /// The theme of your [`Application`]. - type Theme: Default + StyleSheet; - - /// The data needed to initialize your [`Application`]. - type Flags; - - /// Initializes the [`Application`] with the flags provided to - /// [`run`] as part of the [`Settings`]. - /// - /// Here is where you should return the initial state of your app. - /// - /// Additionally, you can return a [`Command`] if you need to perform some - /// async action in the background on startup. This is useful if you want to - /// load state from a file, perform an initial HTTP request, etc. - /// - /// [`run`]: Self::run - fn new(flags: Self::Flags) -> (Self, Command<Self::Message>); - - /// Returns the current title of the [`Application`]. - /// - /// This title can be dynamic! The runtime will automatically update the - /// title of your application when necessary. - fn title(&self) -> String; - - /// Handles a __message__ and updates the state of the [`Application`]. - /// - /// This is where you define your __update logic__. All the __messages__, - /// produced by either user interactions or commands, will be handled by - /// this method. - /// - /// Any [`Command`] returned will be executed immediately in the background. - fn update(&mut self, message: Self::Message) -> Command<Self::Message>; - - /// Returns the widgets to display in the [`Application`]. - /// - /// These widgets can produce __messages__ based on user interaction. - fn view( - &self, - ) -> pure::Element<'_, Self::Message, crate::Renderer<Self::Theme>>; - - /// Returns the current [`Theme`] of the [`Application`]. - fn theme(&self) -> Self::Theme { - Self::Theme::default() - } - - /// Returns the event [`Subscription`] for the current state of the - /// application. - /// - /// A [`Subscription`] will be kept alive as long as you keep returning it, - /// and the __messages__ produced will be handled by - /// [`update`](#tymethod.update). - /// - /// By default, this method returns an empty [`Subscription`]. - fn subscription(&self) -> Subscription<Self::Message> { - Subscription::none() - } - - /// Returns the current [`Application`] mode. - /// - /// The runtime will automatically transition your application if a new mode - /// is returned. - /// - /// Currently, the mode only has an effect in native platforms. - /// - /// By default, an application will run in windowed mode. - fn mode(&self) -> window::Mode { - window::Mode::Windowed - } - - /// Returns the scale factor of the [`Application`]. - /// - /// It can be used to dynamically control the size of the UI at runtime - /// (i.e. zooming). - /// - /// For instance, a scale factor of `2.0` will make widgets twice as big, - /// while a scale factor of `0.5` will shrink them to half their size. - /// - /// By default, it returns `1.0`. - fn scale_factor(&self) -> f64 { - 1.0 - } - - /// Returns whether the [`Application`] should be terminated. - /// - /// By default, it returns `false`. - fn should_exit(&self) -> bool { - false - } - - /// Runs the [`Application`]. - /// - /// On native platforms, this method will take control of the current thread - /// until the [`Application`] exits. - /// - /// On the web platform, this method __will NOT return__ unless there is an - /// [`Error`] during startup. - /// - /// [`Error`]: crate::Error - fn run(settings: Settings<Self::Flags>) -> crate::Result - where - Self: 'static, - { - <Instance<Self> as crate::Application>::run(settings) - } -} - -struct Instance<A: Application> { - application: A, - state: pure::State, -} - -impl<A> crate::Application for Instance<A> -where - A: Application, - A::Message: 'static, -{ - type Executor = A::Executor; - type Message = A::Message; - type Flags = A::Flags; - type Theme = A::Theme; - - fn new(flags: Self::Flags) -> (Self, Command<Self::Message>) { - let (application, command) = A::new(flags); - - ( - Instance { - application, - state: pure::State::new(), - }, - command, - ) - } - - fn title(&self) -> String { - A::title(&self.application) - } - - fn update(&mut self, message: Self::Message) -> Command<Self::Message> { - A::update(&mut self.application, message) - } - - fn subscription(&self) -> Subscription<Self::Message> { - A::subscription(&self.application) - } - - fn view( - &mut self, - ) -> crate::Element<'_, Self::Message, crate::Renderer<Self::Theme>> { - let content = A::view(&self.application); - - Pure::new(&mut self.state, content).into() - } - - fn theme(&self) -> Self::Theme { - A::theme(&self.application) - } - - fn mode(&self) -> window::Mode { - A::mode(&self.application) - } - - fn scale_factor(&self) -> f64 { - A::scale_factor(&self.application) - } - - fn should_exit(&self) -> bool { - A::should_exit(&self.application) - } -} diff --git a/src/pure/sandbox.rs b/src/pure/sandbox.rs deleted file mode 100644 index a58cace7..00000000 --- a/src/pure/sandbox.rs +++ /dev/null @@ -1,123 +0,0 @@ -use crate::pure; -use crate::{Command, Error, Settings, Subscription, Theme}; - -/// A pure version of [`Sandbox`]. -/// -/// Unlike the impure version, the `view` method of this trait takes an -/// immutable reference to `self` and returns a pure [`Element`]. -/// -/// [`Sandbox`]: crate::Sandbox -/// [`Element`]: pure::Element -pub trait Sandbox { - /// The type of __messages__ your [`Sandbox`] will produce. - type Message: std::fmt::Debug + Send; - - /// Initializes the [`Sandbox`]. - /// - /// Here is where you should return the initial state of your app. - fn new() -> Self; - - /// Returns the current title of the [`Sandbox`]. - /// - /// This title can be dynamic! The runtime will automatically update the - /// title of your application when necessary. - fn title(&self) -> String; - - /// Handles a __message__ and updates the state of the [`Sandbox`]. - /// - /// This is where you define your __update logic__. All the __messages__, - /// produced by user interactions, will be handled by this method. - fn update(&mut self, message: Self::Message); - - /// Returns the widgets to display in the [`Sandbox`]. - /// - /// These widgets can produce __messages__ based on user interaction. - fn view(&self) -> pure::Element<'_, Self::Message>; - - /// Returns the current [`Theme`] of the [`Sandbox`]. - /// - /// If you want to use your own custom theme type, you will have to use an - /// [`Application`]. - /// - /// By default, it returns [`Theme::default`]. - fn theme(&self) -> Theme { - Theme::default() - } - - /// Returns the scale factor of the [`Sandbox`]. - /// - /// It can be used to dynamically control the size of the UI at runtime - /// (i.e. zooming). - /// - /// For instance, a scale factor of `2.0` will make widgets twice as big, - /// while a scale factor of `0.5` will shrink them to half their size. - /// - /// By default, it returns `1.0`. - fn scale_factor(&self) -> f64 { - 1.0 - } - - /// Returns whether the [`Sandbox`] should be terminated. - /// - /// By default, it returns `false`. - fn should_exit(&self) -> bool { - false - } - - /// Runs the [`Sandbox`]. - /// - /// On native platforms, this method will take control of the current thread - /// and __will NOT return__. - /// - /// It should probably be that last thing you call in your `main` function. - fn run(settings: Settings<()>) -> Result<(), Error> - where - Self: 'static + Sized, - { - <Self as pure::Application>::run(settings) - } -} - -impl<T> pure::Application for T -where - T: Sandbox, -{ - type Executor = iced_futures::backend::null::Executor; - type Flags = (); - type Message = T::Message; - type Theme = Theme; - - fn new(_flags: ()) -> (Self, Command<T::Message>) { - (T::new(), Command::none()) - } - - fn title(&self) -> String { - T::title(self) - } - - fn update(&mut self, message: T::Message) -> Command<T::Message> { - T::update(self, message); - - Command::none() - } - - fn view(&self) -> pure::Element<'_, T::Message> { - T::view(self) - } - - fn theme(&self) -> Self::Theme { - T::theme(self) - } - - fn subscription(&self) -> Subscription<T::Message> { - Subscription::none() - } - - fn scale_factor(&self) -> f64 { - T::scale_factor(self) - } - - fn should_exit(&self) -> bool { - T::should_exit(self) - } -} diff --git a/src/pure/widget.rs b/src/pure/widget.rs deleted file mode 100644 index 336f498f..00000000 --- a/src/pure/widget.rs +++ /dev/null @@ -1,174 +0,0 @@ -//! Pure versions of the widgets. - -/// A container that distributes its contents vertically. -pub type Column<'a, Message, Renderer = crate::Renderer> = - iced_pure::widget::Column<'a, Message, Renderer>; - -/// A container that distributes its contents horizontally. -pub type Row<'a, Message, Renderer = crate::Renderer> = - iced_pure::widget::Row<'a, Message, Renderer>; - -/// A paragraph of text. -pub type Text<Renderer = crate::Renderer> = iced_pure::widget::Text<Renderer>; - -pub mod button { - //! Allow your users to perform actions by pressing a button. - pub use iced_pure::widget::button::{Appearance, StyleSheet}; - - /// A widget that produces a message when clicked. - pub type Button<'a, Message, Renderer = crate::Renderer> = - iced_pure::widget::Button<'a, Message, Renderer>; -} - -pub mod checkbox { - //! Show toggle controls using checkboxes. - pub use iced_pure::widget::checkbox::{Appearance, StyleSheet}; - - /// A box that can be checked. - pub type Checkbox<'a, Message, Renderer = crate::Renderer> = - iced_native::widget::Checkbox<'a, Message, Renderer>; -} - -pub mod container { - //! Decorate content and apply alignment. - pub use iced_pure::widget::container::{Appearance, StyleSheet}; - - /// An element decorating some content. - pub type Container<'a, Message, Renderer = crate::Renderer> = - iced_pure::widget::Container<'a, Message, Renderer>; -} - -pub mod pane_grid { - //! Let your users split regions of your application and organize layout dynamically. - //! - //! [](https://gfycat.com/mixedflatjellyfish) - //! - //! # Example - //! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing, - //! drag and drop, and hotkey support. - //! - //! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.4/examples/pane_grid - pub use iced_pure::widget::pane_grid::{ - Axis, Configuration, Direction, DragEvent, Line, Node, Pane, - ResizeEvent, Split, State, StyleSheet, - }; - - /// A collection of panes distributed using either vertical or horizontal splits - /// to completely fill the space available. - /// - /// [](https://gfycat.com/mixedflatjellyfish) - pub type PaneGrid<'a, Message, Renderer = crate::Renderer> = - iced_pure::widget::PaneGrid<'a, Message, Renderer>; - - /// The content of a [`Pane`]. - pub type Content<'a, Message, Renderer = crate::Renderer> = - iced_pure::widget::pane_grid::Content<'a, Message, Renderer>; - - /// The title bar of a [`Pane`]. - pub type TitleBar<'a, Message, Renderer = crate::Renderer> = - iced_pure::widget::pane_grid::TitleBar<'a, Message, Renderer>; -} - -pub mod pick_list { - //! Display a dropdown list of selectable values. - pub use iced_pure::widget::pick_list::{Appearance, StyleSheet}; - - /// A widget allowing the selection of a single value from a list of options. - pub type PickList<'a, T, Message, Renderer = crate::Renderer> = - iced_pure::widget::PickList<'a, T, Message, Renderer>; -} - -pub mod radio { - //! Create choices using radio buttons. - pub use iced_pure::widget::radio::{Appearance, StyleSheet}; - - /// A circular button representing a choice. - pub type Radio<Message, Renderer = crate::Renderer> = - iced_pure::widget::Radio<Message, Renderer>; -} - -pub mod scrollable { - //! Navigate an endless amount of content with a scrollbar. - pub use iced_pure::widget::scrollable::{Scrollbar, Scroller, StyleSheet}; - - /// A widget that can vertically display an infinite amount of content - /// with a scrollbar. - pub type Scrollable<'a, Message, Renderer = crate::Renderer> = - iced_pure::widget::Scrollable<'a, Message, Renderer>; -} - -pub mod toggler { - //! Show toggle controls using togglers. - pub use iced_pure::widget::toggler::{Appearance, StyleSheet}; - - /// A toggler widget. - pub type Toggler<'a, Message, Renderer = crate::Renderer> = - iced_pure::widget::Toggler<'a, Message, Renderer>; -} - -pub mod text_input { - //! Display fields that can be filled with text. - pub use iced_pure::widget::text_input::{Appearance, StyleSheet}; - - /// A field that can be filled with text. - pub type TextInput<'a, Message, Renderer = crate::Renderer> = - iced_pure::widget::TextInput<'a, Message, Renderer>; -} - -pub mod tooltip { - //! Display a widget over another. - pub use iced_pure::widget::tooltip::Position; - - /// A widget allowing the selection of a single value from a list of options. - pub type Tooltip<'a, Message, Renderer = crate::Renderer> = - iced_pure::widget::Tooltip<'a, Message, Renderer>; -} - -pub use iced_pure::widget::progress_bar; -pub use iced_pure::widget::rule; -pub use iced_pure::widget::slider; -pub use iced_pure::widget::Space; - -pub use button::Button; -pub use checkbox::Checkbox; -pub use container::Container; -pub use pane_grid::PaneGrid; -pub use pick_list::PickList; -pub use progress_bar::ProgressBar; -pub use radio::Radio; -pub use rule::Rule; -pub use scrollable::Scrollable; -pub use slider::Slider; -pub use text_input::TextInput; -pub use toggler::Toggler; -pub use tooltip::Tooltip; - -#[cfg(feature = "canvas")] -pub use iced_graphics::widget::pure::canvas; - -#[cfg(feature = "qr_code")] -pub use iced_graphics::widget::pure::qr_code; - -#[cfg(feature = "image")] -pub mod image { - //! Display images in your user interface. - pub use iced_native::image::Handle; - - /// A frame that displays an image. - pub type Image = iced_pure::widget::Image<Handle>; -} - -#[cfg(feature = "svg")] -pub use iced_pure::widget::svg; - -#[cfg(feature = "canvas")] -pub use canvas::Canvas; - -#[cfg(feature = "qr_code")] -pub use qr_code::QRCode; - -#[cfg(feature = "image")] -pub use image::Image; - -#[cfg(feature = "svg")] -pub use svg::Svg; diff --git a/src/sandbox.rs b/src/sandbox.rs index 3ca3fe8f..bdb6ad5a 100644 --- a/src/sandbox.rs +++ b/src/sandbox.rs @@ -56,7 +56,7 @@ use crate::{Application, Command, Element, Error, Settings, Subscription}; /// says "Hello, world!": /// /// ```no_run -/// use iced::{Element, Sandbox, Settings, Text}; +/// use iced::{Element, Sandbox, Settings}; /// /// pub fn main() -> iced::Result { /// Hello::run(Settings::default()) @@ -79,8 +79,8 @@ use crate::{Application, Command, Element, Error, Settings, Subscription}; /// // This application has no interactions /// } /// -/// fn view(&mut self) -> Element<Self::Message> { -/// Text::new("Hello, world!").into() +/// fn view(&self) -> Element<Self::Message> { +/// "Hello, world!".into() /// } /// } /// ``` @@ -108,7 +108,7 @@ pub trait Sandbox { /// Returns the widgets to display in the [`Sandbox`]. /// /// These widgets can produce __messages__ based on user interaction. - fn view(&mut self) -> Element<'_, Self::Message>; + fn view(&self) -> Element<'_, Self::Message>; /// Returns the current [`Theme`] of the [`Sandbox`]. /// @@ -184,7 +184,7 @@ where Command::none() } - fn view(&mut self) -> Element<'_, T::Message> { + fn view(&self) -> Element<'_, T::Message> { T::view(self) } diff --git a/src/widget.rs b/src/widget.rs index b8b5c493..4ddf0566 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -1,18 +1,7 @@ //! Display information and interactive controls in your application. -//! -//! # Re-exports -//! For convenience, the contents of this module are available at the root -//! module. Therefore, you can directly type: -//! -//! ``` -//! use iced::{button, Button}; -//! ``` -//! -//! # Stateful widgets -//! Some widgets need to keep track of __local state__. -//! -//! These widgets have their own module with a `State` type. For instance, a -//! [`TextInput`] has some [`text_input::State`]. +pub use iced_native::widget::helpers::*; + +pub use iced_native::{column, row}; /// A container that distributes its contents vertically. pub type Column<'a, Message, Renderer = crate::Renderer> = @@ -22,14 +11,18 @@ pub type Column<'a, Message, Renderer = crate::Renderer> = pub type Row<'a, Message, Renderer = crate::Renderer> = iced_native::widget::Row<'a, Message, Renderer>; -/// A paragraph of text. -pub type Text<Renderer = crate::Renderer> = iced_native::widget::Text<Renderer>; +pub mod text { + //! Write some text for your users to read. + pub use iced_native::widget::text::{Appearance, StyleSheet}; + + /// A paragraph of text. + pub type Text<Renderer = crate::Renderer> = + iced_native::widget::Text<Renderer>; +} pub mod button { //! Allow your users to perform actions by pressing a button. - //! - //! A [`Button`] has some local [`State`]. - pub use iced_native::widget::button::{Appearance, State, StyleSheet}; + pub use iced_native::widget::button::{Appearance, StyleSheet}; /// A widget that produces a message when clicked. pub type Button<'a, Message, Renderer = crate::Renderer> = @@ -87,7 +80,7 @@ pub mod pane_grid { pub mod pick_list { //! Display a dropdown list of selectable values. - pub use iced_native::widget::pick_list::{Appearance, State, StyleSheet}; + pub use iced_native::widget::pick_list::{Appearance, StyleSheet}; /// A widget allowing the selection of a single value from a list of options. pub type PickList<'a, T, Message, Renderer = crate::Renderer> = @@ -106,7 +99,7 @@ pub mod radio { pub mod scrollable { //! Navigate an endless amount of content with a scrollbar. pub use iced_native::widget::scrollable::{ - style::Scrollbar, style::Scroller, State, StyleSheet, + style::Scrollbar, style::Scroller, StyleSheet, }; /// A widget that can vertically display an infinite amount of content @@ -126,9 +119,7 @@ pub mod toggler { pub mod text_input { //! Display fields that can be filled with text. - //! - //! A [`TextInput`] has some local [`State`]. - pub use iced_native::widget::text_input::{Appearance, State, StyleSheet}; + pub use iced_native::widget::text_input::{Appearance, StyleSheet}; /// A field that can be filled with text. pub type TextInput<'a, Message, Renderer = crate::Renderer> = @@ -159,6 +150,7 @@ pub use radio::Radio; pub use rule::Rule; pub use scrollable::Scrollable; pub use slider::Slider; +pub use text::Text; pub use text_input::TextInput; pub use toggler::Toggler; pub use tooltip::Tooltip; @@ -167,6 +159,16 @@ pub use tooltip::Tooltip; #[cfg_attr(docsrs, doc(cfg(feature = "canvas")))] pub use iced_graphics::widget::canvas; +#[cfg(feature = "canvas")] +#[cfg_attr(docsrs, doc(cfg(feature = "canvas")))] +/// Creates a new [`Canvas`]. +pub fn canvas<P, Message, Theme>(program: P) -> Canvas<Message, Theme, P> +where + P: canvas::Program<Message, Theme>, +{ + Canvas::new(program) +} + #[cfg(feature = "image")] #[cfg_attr(docsrs, doc(cfg(feature = "image")))] pub mod image { |