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 { | 
