From 9713953cf0c13394c037ede2943ad45635fde6e1 Mon Sep 17 00:00:00 2001 From: jrmoulton Date: Sat, 12 Oct 2024 15:00:42 -0600 Subject: [PATCH 1/7] initial --- src/view.rs | 107 +++++++++++++++++++++++++++-------------- src/views/button.rs | 11 ++++- src/views/clip.rs | 2 + src/views/container.rs | 3 ++ src/views/decorator.rs | 88 ++++++++++++++++++++++++++++++++- src/views/mod.rs | 85 ++++++++++++++------------------ src/views/scroll.rs | 68 ++++++++++++++++++++------ 7 files changed, 263 insertions(+), 101 deletions(-) diff --git a/src/view.rs b/src/view.rs index 1243416a..0d2a9c2d 100644 --- a/src/view.rs +++ b/src/view.rs @@ -1,16 +1,3 @@ -//! # View and Widget Traits -//! Views are self-contained components that can be composed together to create complex UIs. -//! Views are the main building blocks of Floem. -//! -//! Views are structs that implement the View and widget traits. Many of these structs will also contain a child field that also implements View. In this way, views can be composed together easily to create complex UIs. This is the most common way to build UIs in Floem. For more information on how to compose views check out the [Views](crate::views) module. -//! -//! Creating a struct and manually implementing the View and Widget traits is typically only needed for building new widgets and for special cases. The rest of this module documentation is for help when manually implementing View and Widget on your own types. -//! -//! -//! ## The View and Widget Traits -//! The [`View`] trait is the trait that Floem uses to build and display elements, and it builds on the [`Widget`] trait. The [`Widget`] trait contains the methods for implementing updates, styling, layout, events, and painting. -//! Eventually, the goal is for Floem to integrate the Widget trait with other rust UI libraries so that the widget layer can be shared among all compatible UI libraries. -//! //! ## State management //! //! For all reactive state that your type contains, either in the form of signals or derived signals, you need to process the changes within an effect. @@ -20,28 +7,25 @@ //! Then, we use a function to construct the slider. As part of this function we create an effect that will be re-run every time the signals in the `percent` closure change. //! In the effect we send the change to the associated [`Id`]. This change can then be handled in the [`Widget::update`] method. //! ```rust -//! use floem::ViewId; //! use floem::reactive::*; +//! use floem::ViewId; //! //! struct Slider { //! id: ViewId, //! } //! pub fn slider(percent: impl Fn() -> f32 + 'static) -> Slider { -//! let id = ViewId::new(); +//! let id = ViewId::new(); //! -//! // If the following effect is not created, and `percent` is accessed directly, -//! // `percent` will only be accessed a single time and will not be reactive. -//! // Therefore the following `create_effect` is necessary for reactivity. -//! create_effect(move |_| { -//! let percent = percent(); -//! id.update_state(percent); -//! }); -//! Slider { -//! id, -//! } +//! // If the following effect is not created, and `percent` is accessed directly, +//! // `percent` will only be accessed a single time and will not be reactive. +//! // Therefore the following `create_effect` is necessary for reactivity. +//! create_effect(move |_| { +//! let percent = percent(); +//! id.update_state(percent); +//! }); +//! Slider { id } //! } //! ``` -//! use floem_reactive::{ReadSignal, RwSignal, SignalGet}; use floem_renderer::Renderer; @@ -59,7 +43,7 @@ use crate::{ views::{dyn_view, DynamicView}, }; -/// type erased [`View`] +/// Type erased [`View`] /// /// Views in Floem are strongly typed. [`AnyView`] allows you to escape the strong typing by converting any type implementing [View] into the [AnyView] type. /// @@ -96,7 +80,20 @@ use crate::{ /// ``` pub type AnyView = Box; -/// Converts the value into a [`View`]. +/// Converts a value into a [`View`]. +/// +/// This trait can be implemented on types which can be built into another type that implements the `View` trait. +/// +/// For example, `&str` implements `IntoView` by building a `text` view and can therefore be used directly in a View tuple. +/// ```rust +/// # use floem::reactive::*; +/// # use floem::views::*; +/// # use floem::IntoView; +/// fn app_view() -> impl IntoView { +/// v_stack(("Item One", "Item Two")) +/// } +/// ``` +/// Check out the [other types](#foreign-impls) that `IntoView` is implemented for. pub trait IntoView: Sized { type V: View + 'static; @@ -199,7 +196,47 @@ pub fn recursively_layout_view(id: ViewId, cx: &mut LayoutCx) -> NodeId { /// The View trait contains the methods for implementing updates, styling, layout, events, and painting. /// /// The [id](View::id) method must be implemented. -/// The other methods may be implemented as necessary to implement the Widget. +/// The other methods may be implemented as necessary to implement the functionality of the View. +/// ## State Management in a Custom View +/// +/// For all reactive state that your type contains, either in the form of signals or derived signals, you need to process the changes within an effect. +/// The most common pattern is to [get](floem_reactive::SignalGet::get) the data in an effect and pass it in to `id.update_state()` and then handle that data in the `update` method of the View trait. +/// +/// For example a minimal slider might look like the following. First, we define the struct that contains the [ViewId](crate::ViewId). +/// Then, we use a function to construct the slider. As part of this function we create an effect that will be re-run every time the signals in the `percent` closure change. +/// In the effect we send the change to the associated [ViewId](crate::ViewId). This change can then be handled in the [View::update](crate::View::update) method. +/// ```rust +/// # use floem::{*, views::*, reactive::*}; +/// +/// struct Slider { +/// id: ViewId, +/// percent: f32, +/// } +/// pub fn slider(percent: impl Fn() -> f32 + 'static) -> Slider { +/// let id = ViewId::new(); +/// +/// // If the following effect is not created, and `percent` is accessed directly, +/// // `percent` will only be accessed a single time and will not be reactive. +/// // Therefore the following `create_effect` is necessary for reactivity. +/// create_effect(move |_| { +/// let percent = percent(); +/// id.update_state(percent); +/// }); +/// Slider { id, percent: 0.0 } +/// } +/// impl View for Slider { +/// fn id(&self) -> ViewId { +/// self.id +/// } +/// +/// fn update(&mut self, cx: &mut floem::context::UpdateCx, state: Box) { +/// if let Ok(percent) = state.downcast::() { +/// self.percent = *percent; +/// self.id.request_layout(); +/// } +/// } +/// } +/// ``` pub trait View { fn id(&self) -> ViewId; @@ -259,12 +296,12 @@ pub trait View { default_compute_layout(self.id(), cx) } - /// Implement this to handle events and to pass them down to children - /// - /// Return true to stop the event from propagating to other views - /// - /// If the event needs other passes to run you're expected to call - /// `cx.app_state_mut().request_changes`. + // Implement this to handle events and to pass them down to children + // + // Return true to stop the event from propagating to other views + // + // If the event needs other passes to run you're expected to call + // `cx.app_state_mut().request_changes`. // fn event( // &mut self, // cx: &mut EventCx, diff --git a/src/views/button.rs b/src/views/button.rs index b80ebd27..cbfa41fb 100644 --- a/src/views/button.rs +++ b/src/views/button.rs @@ -1,12 +1,17 @@ use crate::{style_class, views::Decorators, IntoView, View, ViewId}; use core::ops::FnMut; -style_class!(pub ButtonClass); +style_class!( + /// A Style class for buttons + pub ButtonClass +); +/// A wrapper around a view that adds a button style class and provides an `action` method to add a callback to the button. pub fn button(child: V) -> Button { Button::new(child) } +/// A wrapper around a view that adds a button style class and provides an `action` method to add a callback to the button. pub struct Button { id: ViewId, } @@ -16,12 +21,14 @@ impl View for Button { } } impl Button { + /// Create a new button with the given child view. pub fn new(child: impl IntoView) -> Self { let id = ViewId::new(); id.add_child(Box::new(child.into_view())); Button { id }.keyboard_navigatable().class(ButtonClass) } + /// Add a callback to the button that will be called when the button is pressed. pub fn action(self, mut on_press: impl FnMut() + 'static) -> Self { self.on_click_stop(move |_| { on_press(); @@ -29,7 +36,9 @@ impl Button { } } +/// A trait that adds a `button` method to any type that implements `IntoView`. pub trait ButtonExt { + /// Wrap the view in a button. fn button(self) -> Button; } impl ButtonExt for T { diff --git a/src/views/clip.rs b/src/views/clip.rs index 4b62d821..e80619ab 100644 --- a/src/views/clip.rs +++ b/src/views/clip.rs @@ -54,7 +54,9 @@ impl View for Clip { } } +/// A trait that adds a `clip` method to any type that implements `IntoView`. pub trait ClipExt { + /// Wrap the view in a clip view. fn clip(self) -> Clip; } diff --git a/src/views/container.rs b/src/views/container.rs index a63e9606..2208329e 100644 --- a/src/views/container.rs +++ b/src/views/container.rs @@ -28,7 +28,10 @@ impl View for Container { "Container".into() } } + +/// A trait that adds a `container` method to any type that implements `IntoView`. pub trait ContainerExt { + /// Wrap the view in a container. fn container(self) -> Container; } diff --git a/src/views/decorator.rs b/src/views/decorator.rs index 86ef0158..bc48dc06 100644 --- a/src/views/decorator.rs +++ b/src/views/decorator.rs @@ -18,6 +18,9 @@ use crate::{ /// A trait that extends the appearance and functionality of Views through styling and event handling. pub trait Decorators: IntoView + Sized { + /// The type of the decorated view. + /// + /// Using this type allows for chaining of decorators as well as maintaining the original type of the view which allows you to call methods that were a part of the original view even after calling a decorators method. type DV: View; /// Alter the style of the view. @@ -26,8 +29,7 @@ pub trait Decorators: IntoView + Sized { /// ```rust /// # use floem::{peniko::Color, View, views::{Decorators, label, stack}}; /// fn view() -> impl View { - /// label(|| "Hello".to_string()) - /// .style(|s| s.font_size(20.0).color(Color::RED)) + /// label(|| "Hello".to_string()).style(|s| s.font_size(20.0).color(Color::RED)) /// } /// /// fn other() -> impl View { @@ -55,6 +57,9 @@ pub trait Decorators: IntoView + Sized { view } + /// Add a debug name to the view that will be shown in the inspector. + /// + /// This can be called multiple times and each name will be shown in the inspector with the most recent name showing first. fn debug_name(self, name: impl Into) -> Self::DV { let view = self.into_view(); let view_id = view.id(); @@ -63,6 +68,10 @@ pub trait Decorators: IntoView + Sized { view } + /// Conditionally add a debug name to the view that will be shown in the inspector. + /// + /// # Reactivity + /// Both the `apply` and `name` functions are reactive. fn debug_name_if>( self, apply: impl Fn() -> bool + 'static, @@ -97,12 +106,14 @@ pub trait Decorators: IntoView + Sized { view } + /// Add a class to the view fn class(self, _class: C) -> Self::DV { let view = self.into_view(); view.id().add_class(C::class_ref()); view } + /// Conditionally add a class to the view fn class_if(self, apply: impl Fn() -> bool + 'static, _class: C) -> Self::DV { let view = self.into_view(); let id = view.id(); @@ -117,6 +128,7 @@ pub trait Decorators: IntoView + Sized { view } + /// Remove a class from the view fn remove_class(self, _class: C) -> Self::DV { let view = self.into_view(); view.id().remove_class(C::class_ref()); @@ -130,12 +142,17 @@ pub trait Decorators: IntoView + Sized { view } + /// Mark the view as draggable fn draggable(self) -> Self::DV { let view = self.into_view(); view.id().draggable(); view } + /// Mark the view as disabled + /// + /// # Reactivity + /// The `disabled_fn` is reactive. fn disabled(self, disabled_fn: impl Fn() -> bool + 'static) -> Self::DV { let view = self.into_view(); let id = view.id(); @@ -286,6 +303,12 @@ pub trait Decorators: IntoView + Sized { }) } + /// Set the event handler for resize events for this view. + /// + /// There can only be one resize event handler for a view. + /// + /// # Reactivity + /// The action will be called whenever the view is resized but will not rerun automatically in response to signal changes fn on_resize(self, action: impl Fn(Rect) + 'static) -> Self::DV { let view = self.into_view(); let id = view.id(); @@ -294,6 +317,12 @@ pub trait Decorators: IntoView + Sized { view } + /// Set the event handler for move events for this view. + /// + /// There can only be one move event handler for a view. + /// + /// # Reactivity + /// The action will be called whenever the view is moved but will not rerun automatically in response to signal changes fn on_move(self, action: impl Fn(Point) + 'static) -> Self::DV { let view = self.into_view(); let id = view.id(); @@ -302,6 +331,14 @@ pub trait Decorators: IntoView + Sized { view } + /// Set the event handler for cleanup events for this view. + /// + /// The cleanup event is called when the view is removed from the view tree. + /// + /// There can only be one cleanup event handler for a view. + /// + /// # Reactivity + /// The action will be called when the view is removed from the view tree but will not rerun automatically in response to signal changes fn on_cleanup(self, action: impl Fn() + 'static) -> Self::DV { let view = self.into_view(); let id = view.id(); @@ -310,6 +347,14 @@ pub trait Decorators: IntoView + Sized { view } + /// Add an animation to the view. + /// + /// You can add more than one animation to a view and all of them can be active at the same time. + /// + /// See the [Animation] struct for more information on how to create animations. + /// + /// # Reactivity + /// The animation function will be updated in response to signal changes in the function. The behavior is the same as the [style] method. fn animation(self, animation: impl Fn(Animation) -> Animation + 'static) -> Self::DV { let view = self.into_view(); let view_id = view.id(); @@ -331,6 +376,10 @@ pub trait Decorators: IntoView + Sized { view } + /// Clear the focus from the window. + /// + /// # Reactivity + /// The when function is reactive and will rereun in response to any signal changes in the function. fn clear_focus(self, when: impl Fn() + 'static) -> Self::DV { let view = self.into_view(); let id = view.id(); @@ -341,6 +390,10 @@ pub trait Decorators: IntoView + Sized { view } + /// Request that this view gets the focus for the window. + /// + /// # Reactivity + /// The when function is reactive and will rereun in response to any signal changes in the function. fn request_focus(self, when: impl Fn() + 'static) -> Self::DV { let view = self.into_view(); let id = view.id(); @@ -351,6 +404,12 @@ pub trait Decorators: IntoView + Sized { view } + /// Set the window scale factor. + /// + /// This internally calls the [floem::action::set_window_scale] function. + /// + /// # Reactivity + /// The scale function is reactive and will rereun in response to any signal changes in the function. fn window_scale(self, scale_fn: impl Fn() -> f64 + 'static) -> Self { create_effect(move |_| { let window_scale = scale_fn(); @@ -359,6 +418,12 @@ pub trait Decorators: IntoView + Sized { self } + /// Set the window title. + /// + /// This internally calls the [floem::action::set_window_title] function. + /// + /// # Reactivity + /// The title function is reactive and will rereun in response to any signal changes in the function. fn window_title(self, title_fn: impl Fn() -> String + 'static) -> Self { create_effect(move |_| { let window_title = title_fn(); @@ -367,6 +432,17 @@ pub trait Decorators: IntoView + Sized { self } + /// Set the system window menu + /// + /// This internally calls the [floem::action::set_window_menu] function. + /// + /// Platform support: + /// - Windows: No + /// - macOS: Yes (not currently implemented) + /// - Linux: No + /// + /// # Reactivity + /// The menu function is reactive and will rereun in response to any signal changes in the function. fn window_menu(self, menu_fn: impl Fn() -> Menu + 'static) -> Self { create_effect(move |_| { let menu = menu_fn(); @@ -376,6 +452,10 @@ pub trait Decorators: IntoView + Sized { } /// Adds a secondary-click context menu to the view, which opens at the mouse position. + /// + /// # Reactivity + /// the menu function is not reactive and will not rerun in response to signal changes + // TODO: should this be reactive? fn context_menu(self, menu: impl Fn() -> Menu + 'static) -> Self::DV { let view = self.into_view(); let id = view.id(); @@ -384,6 +464,10 @@ pub trait Decorators: IntoView + Sized { } /// Adds a primary-click context menu, which opens below the view. + /// + /// # Reactivity + /// the menu function is not reactive and will not rerun in response to signal changes + // TODO: should this be reactive? fn popout_menu(self, menu: impl Fn() -> Menu + 'static) -> Self::DV { let view = self.into_view(); let id = view.id(); diff --git a/src/views/mod.rs b/src/views/mod.rs index 0c89e506..d094b246 100644 --- a/src/views/mod.rs +++ b/src/views/mod.rs @@ -1,4 +1,5 @@ -//! # Floem built-in Views +//#![deny(missing_docs)] +//! # Built-In Views //! //! This module contains the basic built-in Views of Floem. //! @@ -21,65 +22,51 @@ //! )), //! )); //! ``` +//! Views in Floem can also be easily refactored. +//! ## Example: Refactored Counter +//! ```rust +//! use floem::{reactive::*, views::*}; //! -//! ### Stacks and Lists -//! There are a few different stacks and lists that you can use to group your views and each is discussed here. -//! There are basic [stacks](stack()) and [lists](list()), a [dynamic stack](dyn_stack()), and [virtual stacks](virtual_stack()) and [virtual_lists](virtual_list()). -//! The basic stacks and basic lists are static and always contain the same elements in the same order, but the children can still get reactive updates. -//! The dynamic stack can dynamically change the elements in the stack by reactively updating the list of items provided to the [dyn_stack](dyn_stack()). -//! Virtual stacks and virtual lists are like the dynamic stack but they also lazily load the items as they appear in a [scroll view](scroll()) and do not support the flexbox nor grid layout algorithms. -//! Instead, they give every element a consistent size and use a basic layout. -//! This is done for performance and allows for lists of millions of items to be used with very high performance. -//! -//! Lists differ from stacks in that they also have built-in support for the selection of items: up and down using arrow keys, top and bottom control using the home and end keys, and for the "acceptance" of an item using the Enter key. -//! You could build this manually yourself using stacks but it is common enough that it is built-in as a list. +//! let mut counter = RwSignal::new(0); //! -//! For the most direct documentation for Floem Views see the [Functions](#functions) section of this module documentation. - -//! # View and Widget Traits +//! let counter_label = label(move || format!("Value: {counter}")); //! -//! Views are self-contained components that can be composed together to create complex UIs. -//! Views are the main building blocks of Floem. +//! let increment_button = button("Increment").action(move || counter += 1); +//! let decrement_button = button("Decrement").action(move || counter -= 1); //! -//! Views are structs that implement the View and widget traits. Many of these structs will also contain a child field that also implements View. In this way, views can be composed together easily to create complex UIs. This is the most common way to build UIs in Floem. For more information on how to compose views check out the [Views](crate::views) module. +//! let button_stack = (increment_button, decrement_button).h_stack(); //! -//! Creating a struct and manually implementing the View and Widget traits is typically only needed for building new widgets and for special cases. The rest of this module documentation is for help when manually implementing View and Widget on your own types. +//! (counter_label, button_stack).v_stack(); +//! ``` //! //! -//! ## The View and Widget Traits -//! The [View](crate::View) trait is the trait that Floem uses to build and display elements. The trait contains the methods for implementing updates, styling, layout, events, and painting. +//! ### Stacks and Lists +//! There are a few different stacks and lists that you can use to group your views and each is discussed here. //! -//! ## State management //! -//! For all reactive state that your type contains, either in the form of signals or derived signals, you need to process the changes within an effect. -//! The most common pattern is to [get](floem_reactive::SignalGet::get) the data in an effect and pass it in to `id.update_state()` and then handle that data in the `update` method of the View trait. +//! They are: +//! - basic [stack](stack()) +//! - static and always contains the same elements in the same order +//! - [dynamic stack](dyn_stack()) +//! - can dynamically change the elements in the stack by reactively updating the list of items provided +//! - [virtual stack](virtual_stack()) +//! - can dynamically change the elements in the stack +//! - can lazily load the items as they appear in a [scroll view](scroll()) //! -//! For example a minimal slider might look like the following. First, we define the struct that contains the [ViewId](crate::ViewId). -//! Then, we use a function to construct the slider. As part of this function we create an effect that will be re-run every time the signals in the `percent` closure change. -//! In the effect we send the change to the associated [ViewId](crate::ViewId). This change can then be handled in the [View::update](crate::View::update) method. -//! ```rust -//! use floem::ViewId; -//! use floem::reactive::*; -//! -//! struct Slider { -//! id: ViewId, -//! } -//! pub fn slider(percent: impl Fn() -> f32 + 'static) -> Slider { -//! let id = ViewId::new(); -//! -//! // If the following effect is not created, and `percent` is accessed directly, -//! // `percent` will only be accessed a single time and will not be reactive. -//! // Therefore the following `create_effect` is necessary for reactivity. -//! create_effect(move |_| { -//! let percent = percent(); -//! id.update_state(percent); -//! }); -//! Slider { -//! id, -//! } -//! } -//! ``` +//! There is also a basic [list](list()) and a [virtual list](virtual_list()). +//! Lists are like their stack counterparts but they also have built-in support for the selection of items: up and down using arrow keys, top and bottom control using the home and end keys, and for the "acceptance" of an item using the Enter key. +//! You could build this manually yourself using stacks but it is common enough that it is built-in as a list. +//! +//! ## View Trait +//! The [View](crate::View) trait is the trait that Floem uses to build and display elements. +//! The trait contains the methods for implementing updates, styling, layout, events, and painting. +//! +//! Views are types that implement `View`. +//! Many of these types will also be built with a child that also implements `View`. +//! In this way, views can be composed together easily to create complex UIs. +//! This composition is the most common way to build UIs in Floem. //! +//! Creating a type and manually implementing the View trait is typically only needed for building new widgets and for special cases. mod label; pub use label::*; diff --git a/src/views/scroll.rs b/src/views/scroll.rs index 64425f0a..bd20244d 100644 --- a/src/views/scroll.rs +++ b/src/views/scroll.rs @@ -44,12 +44,27 @@ enum BarHeldState { Horizontal(f64, Vec2), } -style_class!(pub Handle); -style_class!(pub Track); - -prop!(pub Rounded: bool {} = cfg!(target_os = "macos")); -prop!(pub Thickness: Px {} = Px(10.0)); -prop!(pub Border: Px {} = Px(0.0)); +style_class!( + /// Style class that will be applied to the handles of the scroll view + pub Handle +); +style_class!( + /// Style class that will be applied to the scroll tracks of the scroll view + pub Track +); + +prop!( + /// Determines if scroll handles should be rounded. + pub Rounded: bool {} = cfg!(target_os = "macos") +); +prop!( + /// Specifies the thickness of scroll handles in pixels. + pub Thickness: Px {} = Px(10.0) +); +prop!( + /// Defines the border width of a scroll track in pixels. + pub Border: Px {} = Px(0.0) +); prop_extractor! { ScrollTrackStyle { @@ -62,13 +77,35 @@ prop_extractor! { } } -prop!(pub VerticalInset: Px {} = Px(0.0)); -prop!(pub HorizontalInset: Px {} = Px(0.0)); -prop!(pub HideBars: bool {} = false); -prop!(pub PropagatePointerWheel: bool {} = true); -prop!(pub VerticalScrollAsHorizontal: bool {} = false); -prop!(pub OverflowClip: bool {} = true); - +prop!( + /// Specifies the vertical inset of the scrollable area in pixels. + pub VerticalInset: Px {} = Px(0.0) +); + +prop!( + /// Defines the horizontal inset of the scrollable area in pixels. + pub HorizontalInset: Px {} = Px(0.0) +); + +prop!( + /// Controls the visibility of scroll bars. When true, bars are hidden. + pub HideBars: bool {} = false +); + +prop!( + /// Determines if pointer wheel events should propagate to parent elements. + pub PropagatePointerWheel: bool {} = true +); + +prop!( + /// When true, vertical scroll input is interpreted as horizontal scrolling. + pub VerticalScrollAsHorizontal: bool {} = false +); + +prop!( + /// Enables clipping of overflowing content when set to true. + pub OverflowClip: bool {} = true +); prop_extractor!(ScrollStyle { vertical_bar_inset: VerticalInset, horizontal_bar_inset: HorizontalInset, @@ -80,7 +117,10 @@ prop_extractor!(ScrollStyle { const HANDLE_COLOR: Brush = Brush::Solid(Color::rgba8(0, 0, 0, 120)); -style_class!(pub ScrollClass); +style_class!( + /// Style class that is applied to every scroll view + pub ScrollClass +); pub struct Scroll { id: ViewId, From affb4b800aad5e983cfc0aeaf50ba3ee936b5f60 Mon Sep 17 00:00:00 2001 From: jrmoulton Date: Sat, 12 Oct 2024 15:12:47 -0600 Subject: [PATCH 2/7] export fewer modules from views --- examples/counter/src/main.rs | 2 +- examples/dropped_file/src/main.rs | 2 +- examples/editor/src/main.rs | 4 ++- examples/flight_booker/src/main.rs | 3 +- examples/layout/src/draggable_sidebar.rs | 5 +-- examples/layout/src/holy_grail.rs | 5 +-- examples/layout/src/left_sidebar.rs | 5 +-- examples/layout/src/right_sidebar.rs | 5 +-- examples/layout/src/tab_navigation.rs | 2 +- examples/stacks/src/virtual_stack.rs | 2 +- examples/syntax-editor/src/main.rs | 4 ++- examples/virtual_list/src/main.rs | 4 +-- examples/widget-gallery/src/buttons.rs | 2 +- examples/widget-gallery/src/checkbox.rs | 2 +- examples/widget-gallery/src/labels.rs | 2 +- examples/widget-gallery/src/lists.rs | 5 ++- examples/widget-gallery/src/main.rs | 5 +-- examples/widget-gallery/src/radio_buttons.rs | 2 +- src/inspector.rs | 2 +- src/theme.rs | 15 ++++---- src/view.rs | 2 +- src/views/checkbox.rs | 5 +-- src/views/editor/text.rs | 2 +- src/views/mod.rs | 38 +++++++------------- src/views/radio_button.rs | 4 +-- src/views/virtual_list.rs | 6 ++-- src/views/virtual_stack.rs | 2 +- 27 files changed, 50 insertions(+), 87 deletions(-) diff --git a/examples/counter/src/main.rs b/examples/counter/src/main.rs index 631b75fb..72d285b9 100644 --- a/examples/counter/src/main.rs +++ b/examples/counter/src/main.rs @@ -3,7 +3,7 @@ use floem::{ peniko::Color, reactive::{create_signal, SignalGet, SignalUpdate}, unit::UnitExt, - views::{dyn_view, Decorators, LabelClass, LabelCustomStyle}, + views::{dyn_view::*, Decorators, LabelClass, LabelCustomStyle}, IntoView, View, }; diff --git a/examples/dropped_file/src/main.rs b/examples/dropped_file/src/main.rs index b38afd0a..f0e6d414 100644 --- a/examples/dropped_file/src/main.rs +++ b/examples/dropped_file/src/main.rs @@ -2,7 +2,7 @@ use floem::{ event::EventListener, keyboard::{Key, Modifiers, NamedKey}, unit::UnitExt, - views::{dyn_view, Decorators}, + views::{dyn_view::*, Decorators}, IntoView, View, }; diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index 7f2f83c2..bc523880 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -8,7 +8,9 @@ use floem::{ core::{command::EditCommand, editor::EditType, selection::Selection}, text::{default_dark_color, SimpleStyling}, }, - stack, text_editor, Decorators, + stack, + text_editor::*, + Decorators, }, IntoView, View, }; diff --git a/examples/flight_booker/src/main.rs b/examples/flight_booker/src/main.rs index d882ef6e..4d93fd36 100644 --- a/examples/flight_booker/src/main.rs +++ b/examples/flight_booker/src/main.rs @@ -1,11 +1,12 @@ use std::fmt::Display; +use floem::views::radio_button::RadioButton; use floem::views::StackExt; use floem::{ peniko::Color, reactive::{create_rw_signal, RwSignal, SignalGet, SignalUpdate}, unit::UnitExt, - views::{button, dyn_container, empty, text, text_input, v_stack, Decorators, RadioButton}, + views::{button, dyn_container, empty, text, text_input, v_stack, Decorators}, IntoView, }; use strum::IntoEnumIterator; diff --git a/examples/layout/src/draggable_sidebar.rs b/examples/layout/src/draggable_sidebar.rs index 2059f610..257ee691 100644 --- a/examples/layout/src/draggable_sidebar.rs +++ b/examples/layout/src/draggable_sidebar.rs @@ -3,10 +3,7 @@ use floem::{ peniko::Color, reactive::{create_rw_signal, create_signal, SignalGet, SignalUpdate}, style::{CursorStyle, Position}, - views::{ - container, h_stack, label, scroll, virtual_stack, Decorators, VirtualDirection, - VirtualItemSize, - }, + views::{container, h_stack, label, scroll, virtual_stack::*, Decorators}, IntoView, View, }; diff --git a/examples/layout/src/holy_grail.rs b/examples/layout/src/holy_grail.rs index 8a918f7d..d4e71e91 100644 --- a/examples/layout/src/holy_grail.rs +++ b/examples/layout/src/holy_grail.rs @@ -3,10 +3,7 @@ use floem::{ peniko::Color, reactive::{create_rw_signal, SignalGet}, style::Position, - views::{ - container, h_stack, label, scroll, v_stack, virtual_stack, Decorators, VirtualDirection, - VirtualItemSize, - }, + views::{container, h_stack, label, scroll, v_stack, virtual_stack::*, Decorators}, IntoView, View, }; diff --git a/examples/layout/src/left_sidebar.rs b/examples/layout/src/left_sidebar.rs index ee103c2e..e0efb5f7 100644 --- a/examples/layout/src/left_sidebar.rs +++ b/examples/layout/src/left_sidebar.rs @@ -3,10 +3,7 @@ use floem::{ peniko::Color, reactive::{create_rw_signal, SignalGet}, style::Position, - views::{ - container, h_stack, label, scroll, v_stack, virtual_stack, Decorators, VirtualDirection, - VirtualItemSize, - }, + views::{container, h_stack, label, scroll, v_stack, virtual_stack::*, Decorators}, IntoView, View, }; diff --git a/examples/layout/src/right_sidebar.rs b/examples/layout/src/right_sidebar.rs index 3b9dcc61..07ef725b 100644 --- a/examples/layout/src/right_sidebar.rs +++ b/examples/layout/src/right_sidebar.rs @@ -3,10 +3,7 @@ use floem::{ peniko::Color, reactive::{create_rw_signal, SignalGet}, style::Position, - views::{ - container, h_stack, label, scroll, v_stack, virtual_stack, Decorators, VirtualDirection, - VirtualItemSize, - }, + views::{container, h_stack, label, scroll, v_stack, virtual_stack::*, Decorators}, IntoView, View, }; diff --git a/examples/layout/src/tab_navigation.rs b/examples/layout/src/tab_navigation.rs index 3a8f249d..83310189 100644 --- a/examples/layout/src/tab_navigation.rs +++ b/examples/layout/src/tab_navigation.rs @@ -4,7 +4,7 @@ use floem::{ reactive::{create_signal, ReadSignal, SignalGet, SignalUpdate, WriteSignal}, style::{CursorStyle, Position}, text::Weight, - views::{container, h_stack, label, scroll, tab, v_stack, Decorators}, + views::{container, h_stack, label, scroll, tab::*, v_stack, Decorators}, IntoView, View, }; diff --git a/examples/stacks/src/virtual_stack.rs b/examples/stacks/src/virtual_stack.rs index 743c787a..8a8f7af8 100644 --- a/examples/stacks/src/virtual_stack.rs +++ b/examples/stacks/src/virtual_stack.rs @@ -1,6 +1,6 @@ use floem::{ reactive::{create_rw_signal, SignalGet, SignalUpdate}, - views::{scroll, virtual_stack, ButtonClass, Decorators, VirtualDirection, VirtualItemSize}, + views::{scroll, virtual_stack::*, ButtonClass, Decorators}, IntoView, }; diff --git a/examples/syntax-editor/src/main.rs b/examples/syntax-editor/src/main.rs index e639f0d0..6fa28c1f 100644 --- a/examples/syntax-editor/src/main.rs +++ b/examples/syntax-editor/src/main.rs @@ -16,7 +16,9 @@ use floem::{ core::{editor::EditType, selection::Selection}, text::WrapMethod, }, - stack, text_editor, Decorators, + stack, + text_editor::*, + Decorators, }, }; use floem::{IntoView, View}; diff --git a/examples/virtual_list/src/main.rs b/examples/virtual_list/src/main.rs index 895c73fe..98f959f9 100644 --- a/examples/virtual_list/src/main.rs +++ b/examples/virtual_list/src/main.rs @@ -1,9 +1,7 @@ use floem::{ reactive::{create_signal, SignalGet}, unit::UnitExt, - views::{ - container, label, scroll, virtual_list, Decorators, VirtualDirection, VirtualItemSize, - }, + views::{container, label, scroll, virtual_list::virtual_list, virtual_stack::*, Decorators}, IntoView, }; diff --git a/examples/widget-gallery/src/buttons.rs b/examples/widget-gallery/src/buttons.rs index fa7018fc..e746d7b1 100644 --- a/examples/widget-gallery/src/buttons.rs +++ b/examples/widget-gallery/src/buttons.rs @@ -1,7 +1,7 @@ use floem::{ peniko::Color, style::CursorStyle, - views::{button, toggle_button, Decorators, ToggleHandleBehavior}, + views::{button, toggle_button::*, Decorators}, IntoView, }; diff --git a/examples/widget-gallery/src/checkbox.rs b/examples/widget-gallery/src/checkbox.rs index 91595486..672aebe3 100644 --- a/examples/widget-gallery/src/checkbox.rs +++ b/examples/widget-gallery/src/checkbox.rs @@ -1,6 +1,6 @@ use floem::{ reactive::{RwSignal, SignalGet}, - views::{checkbox, labeled_checkbox, Checkbox, Decorators}, + views::{checkbox::*, Decorators}, IntoView, }; diff --git a/examples/widget-gallery/src/labels.rs b/examples/widget-gallery/src/labels.rs index 940fff72..0fc04beb 100644 --- a/examples/widget-gallery/src/labels.rs +++ b/examples/widget-gallery/src/labels.rs @@ -1,7 +1,7 @@ use floem::{ peniko::Color, text::{Style as FontStyle, Weight}, - views::{label, static_label, tooltip, Decorators}, + views::{label, static_label, tooltip::*, Decorators}, IntoView, }; diff --git a/examples/widget-gallery/src/lists.rs b/examples/widget-gallery/src/lists.rs index 989abe65..43d61728 100644 --- a/examples/widget-gallery/src/lists.rs +++ b/examples/widget-gallery/src/lists.rs @@ -4,9 +4,8 @@ use floem::{ style::JustifyContent, text::Weight, views::{ - button, container, h_stack, h_stack_from_iter, label, list, scroll, stack, v_stack, - v_stack_from_iter, virtual_list, Checkbox, Decorators, VirtualDirection, VirtualItemSize, - VirtualVector, + button, checkbox::Checkbox, container, h_stack, h_stack_from_iter, label, list, scroll, + stack, v_stack, v_stack_from_iter, virtual_list::*, virtual_stack::*, Decorators, }, IntoView, }; diff --git a/examples/widget-gallery/src/main.rs b/examples/widget-gallery/src/main.rs index b898c35a..22042c7f 100644 --- a/examples/widget-gallery/src/main.rs +++ b/examples/widget-gallery/src/main.rs @@ -19,10 +19,7 @@ use floem::{ reactive::{create_signal, SignalGet, SignalUpdate}, style::{Background, CursorStyle, Transition}, unit::{DurationUnitExt, UnitExt}, - views::{ - button, h_stack, label, scroll, stack, tab, v_stack, virtual_stack, Decorators, - VirtualDirection, VirtualItemSize, - }, + views::{button, h_stack, label, scroll, stack, tab::*, v_stack, virtual_stack::*, Decorators}, IntoView, View, }; diff --git a/examples/widget-gallery/src/radio_buttons.rs b/examples/widget-gallery/src/radio_buttons.rs index 3b25f0b1..0e5197fd 100644 --- a/examples/widget-gallery/src/radio_buttons.rs +++ b/examples/widget-gallery/src/radio_buttons.rs @@ -3,7 +3,7 @@ use std::fmt::Display; use floem::{ reactive::RwSignal, style_class, - views::{Decorators, RadioButton, StackExt as _}, + views::{radio_button::RadioButton, Decorators, StackExt as _}, IntoView, }; use strum::IntoEnumIterator; diff --git a/src/inspector.rs b/src/inspector.rs index 87111127..9005e9c9 100644 --- a/src/inspector.rs +++ b/src/inspector.rs @@ -9,7 +9,7 @@ use crate::view::{IntoView, View}; use crate::view_state::ChangeFlags; use crate::views::{ button, container, dyn_container, empty, h_stack, img_dynamic, scroll, stack, static_label, - tab, text, text_input, v_stack, v_stack_from_iter, Decorators, Label, + tab::*, text, text_input, v_stack, v_stack_from_iter, Decorators, Label, }; use crate::window::WindowConfig; use crate::{new_window, style, Clipboard}; diff --git a/src/theme.rs b/src/theme.rs index 86be0df3..15dc55d5 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -1,19 +1,16 @@ use crate::{ style::{Background, CursorStyle, Foreground, Style, Transition}, unit::{DurationUnitExt, UnitExt}, - views::{ - dropdown::{self}, - scroll, - slider::{self, SliderClass}, - ButtonClass, CheckboxClass, LabelClass, LabelCustomStyle, LabeledCheckboxClass, - LabeledRadioButtonClass, ListClass, ListItemClass, PlaceholderTextClass, RadioButtonClass, - RadioButtonDotClass, TextInputClass, ToggleButtonCircleRad, ToggleButtonClass, - ToggleButtonInset, TooltipClass, - }, + views::*, }; +use checkbox::{CheckboxClass, LabeledCheckboxClass}; use peniko::{Brush, Color}; +use radio_button::{LabeledRadioButtonClass, RadioButtonClass, RadioButtonDotClass}; +use slider::SliderClass; use std::rc::Rc; use taffy::style::AlignItems; +use toggle_button::{ToggleButtonCircleRad, ToggleButtonClass, ToggleButtonInset}; +use tooltip::TooltipClass; pub(crate) struct Theme { pub(crate) background: Color, diff --git a/src/view.rs b/src/view.rs index 0d2a9c2d..56047a55 100644 --- a/src/view.rs +++ b/src/view.rs @@ -40,7 +40,7 @@ use crate::{ id::ViewId, style::{BoxShadowProp, LayoutProps, Style, StyleClassRef}, view_state::ViewStyleProps, - views::{dyn_view, DynamicView}, + views::dyn_view::*, }; /// Type erased [`View`] diff --git a/src/views/checkbox.rs b/src/views/checkbox.rs index c1fe75b0..b82a1427 100644 --- a/src/views/checkbox.rs +++ b/src/views/checkbox.rs @@ -1,10 +1,7 @@ use crate::{ style_class, view::IntoView, - views::{ - self, create_value_container_signals, h_stack, svg, value_container, Decorators, - ValueContainer, - }, + views::{self, h_stack, svg, value_container::*, Decorators}, }; use floem_reactive::{SignalGet, SignalUpdate}; use std::fmt::Display; diff --git a/src/views/editor/text.rs b/src/views/editor/text.rs index 3fa3bbd3..d3b924d4 100644 --- a/src/views/editor/text.rs +++ b/src/views/editor/text.rs @@ -5,7 +5,7 @@ use crate::{ peniko::Color, reactive::{RwSignal, Scope}, text::{Attrs, AttrsList, FamilyOwned, Stretch, Weight}, - views::EditorCustomStyle, + views::text_editor::EditorCustomStyle, }; use downcast_rs::{impl_downcast, Downcast}; use floem_editor_core::{ diff --git a/src/views/mod.rs b/src/views/mod.rs index d094b246..d792aaa6 100644 --- a/src/views/mod.rs +++ b/src/views/mod.rs @@ -71,8 +71,7 @@ mod label; pub use label::*; -mod rich_text; -pub use rich_text::*; +pub mod rich_text; mod dyn_stack; pub use dyn_stack::*; @@ -89,11 +88,9 @@ pub use container::*; mod dyn_container; pub use dyn_container::*; -mod dyn_view; -pub use dyn_view::*; +pub mod dyn_view; -mod value_container; -pub use value_container::*; +pub mod value_container; mod decorator; pub use decorator::*; @@ -101,20 +98,16 @@ pub use decorator::*; mod list; pub use list::*; -mod virtual_list; -pub use virtual_list::*; +pub mod virtual_list; -mod virtual_stack; -pub use virtual_stack::*; +pub mod virtual_stack; pub mod scroll; pub use scroll::{scroll, Scroll}; -mod tab; -pub use tab::*; +pub mod tab; -mod tooltip; -pub use tooltip::*; +pub mod tooltip; mod stack; pub use stack::*; @@ -125,11 +118,9 @@ pub use text_input::*; mod empty; pub use empty::*; -mod drag_window_area; -pub use drag_window_area::*; +pub mod drag_window_area; -mod drag_resize_window_area; -pub use drag_resize_window_area::*; +pub mod drag_resize_window_area; mod img; pub use img::*; @@ -142,18 +133,13 @@ pub mod editor; #[cfg(feature = "editor")] pub mod text_editor; -#[cfg(feature = "editor")] -pub use text_editor::*; pub mod dropdown; pub mod slider; -mod radio_button; -pub use radio_button::*; +pub mod radio_button; -mod checkbox; -pub use checkbox::*; +pub mod checkbox; -mod toggle_button; -pub use toggle_button::*; +pub mod toggle_button; diff --git a/src/views/radio_button.rs b/src/views/radio_button.rs index 797363ac..6ec93484 100644 --- a/src/views/radio_button.rs +++ b/src/views/radio_button.rs @@ -1,13 +1,11 @@ use crate::{ style_class, view::View, - views::{self, container, empty, h_stack, Decorators}, + views::{self, container, empty, h_stack, value_container::*, Decorators}, IntoView, }; use floem_reactive::{SignalGet, SignalUpdate}; -use super::{create_value_container_signals, value_container, ValueContainer}; - style_class!(pub RadioButtonClass); style_class!(pub RadioButtonDotClass); style_class!(pub RadioButtonDotSelectedClass); diff --git a/src/views/virtual_list.rs b/src/views/virtual_list.rs index d582da44..f440356f 100644 --- a/src/views/virtual_list.rs +++ b/src/views/virtual_list.rs @@ -1,7 +1,3 @@ -use super::{ - container, virtual_stack, Decorators, Item, ListClass, ListItemClass, VirtualDirection, - VirtualItemSize, VirtualVector, -}; use crate::context::ComputeLayoutCx; use crate::event::EventPropagation; use crate::id::ViewId; @@ -19,6 +15,8 @@ use peniko::kurbo::{Rect, Size}; use std::hash::Hash; use std::rc::Rc; +use super::{container, virtual_stack::*, Decorators, Item, ListClass, ListItemClass}; + enum ListUpdate { SelectionChanged, ScrollToSelected, diff --git a/src/views/virtual_stack.rs b/src/views/virtual_stack.rs index cc3fe594..a3f86865 100644 --- a/src/views/virtual_stack.rs +++ b/src/views/virtual_stack.rs @@ -80,7 +80,7 @@ struct VirtualStackState { /// /// ## Example /// ``` -/// use floem::{reactive::*, views::*, unit::UnitExt}; +/// use floem::{reactive::*, unit::UnitExt, views::*}; /// /// let long_list: im::Vector = (0..1000000).collect(); /// let (long_list, _set_long_list) = create_signal(long_list); From a7079a9fe1d47dc81d77b1843f3d386e44af77c5 Mon Sep 17 00:00:00 2001 From: jrmoulton Date: Sat, 12 Oct 2024 15:24:40 -0600 Subject: [PATCH 3/7] fix doc links --- src/views/decorator.rs | 8 ++++---- src/views/mod.rs | 4 ++-- src/views/value_container.rs | 2 +- src/views/virtual_list.rs | 8 ++++---- src/views/virtual_stack.rs | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/views/decorator.rs b/src/views/decorator.rs index bc48dc06..1755d875 100644 --- a/src/views/decorator.rs +++ b/src/views/decorator.rs @@ -354,7 +354,7 @@ pub trait Decorators: IntoView + Sized { /// See the [Animation] struct for more information on how to create animations. /// /// # Reactivity - /// The animation function will be updated in response to signal changes in the function. The behavior is the same as the [style] method. + /// The animation function will be updated in response to signal changes in the function. The behavior is the same as the [Decorators::style] method. fn animation(self, animation: impl Fn(Animation) -> Animation + 'static) -> Self::DV { let view = self.into_view(); let view_id = view.id(); @@ -406,7 +406,7 @@ pub trait Decorators: IntoView + Sized { /// Set the window scale factor. /// - /// This internally calls the [floem::action::set_window_scale] function. + /// This internally calls the [crate::action::update_window_scale] function. /// /// # Reactivity /// The scale function is reactive and will rereun in response to any signal changes in the function. @@ -420,7 +420,7 @@ pub trait Decorators: IntoView + Sized { /// Set the window title. /// - /// This internally calls the [floem::action::set_window_title] function. + /// This internally calls the [crate::action::set_window_title] function. /// /// # Reactivity /// The title function is reactive and will rereun in response to any signal changes in the function. @@ -434,7 +434,7 @@ pub trait Decorators: IntoView + Sized { /// Set the system window menu /// - /// This internally calls the [floem::action::set_window_menu] function. + /// This internally calls the [crate::action::set_window_menu] function. /// /// Platform support: /// - Windows: No diff --git a/src/views/mod.rs b/src/views/mod.rs index d792aaa6..bfad2c6d 100644 --- a/src/views/mod.rs +++ b/src/views/mod.rs @@ -49,11 +49,11 @@ //! - static and always contains the same elements in the same order //! - [dynamic stack](dyn_stack()) //! - can dynamically change the elements in the stack by reactively updating the list of items provided -//! - [virtual stack](virtual_stack()) +//! - [virtual stack](virtual_stack::virtual_stack()) //! - can dynamically change the elements in the stack //! - can lazily load the items as they appear in a [scroll view](scroll()) //! -//! There is also a basic [list](list()) and a [virtual list](virtual_list()). +//! There is also a basic [list](list()) and a [virtual list](virtual_list::virtual_list()). //! Lists are like their stack counterparts but they also have built-in support for the selection of items: up and down using arrow keys, top and bottom control using the home and end keys, and for the "acceptance" of an item using the Enter key. //! You could build this manually yourself using stacks but it is common enough that it is built-in as a list. //! diff --git a/src/views/value_container.rs b/src/views/value_container.rs index ba4ae638..d271d832 100644 --- a/src/views/value_container.rs +++ b/src/views/value_container.rs @@ -46,7 +46,7 @@ where /// A wrapper around another View that has value updates. /// -/// A [`ValueContainer`] is useful for wrapping another [View](crate::view::View). +/// A [`ValueContainer`] is useful for wrapping another [View]. /// This is to provide the `on_update` method which can notify when the view's /// internal value was get changed pub fn value_container( diff --git a/src/views/virtual_list.rs b/src/views/virtual_list.rs index f440356f..869ff552 100644 --- a/src/views/virtual_list.rs +++ b/src/views/virtual_list.rs @@ -22,8 +22,8 @@ enum ListUpdate { ScrollToSelected, } -/// A view that is like a [`virtual_stack`](super::virtual_stack()) but also supports item selection. -/// See [`virtual_list`] and [`virtual_stack`](super::virtual_stack()). +/// A view that is like a [`virtual_stack`] but also supports item selection. +/// See [`virtual_list`] and [`virtual_stack`]. pub struct VirtualList { id: ViewId, direction: VirtualDirection, @@ -47,8 +47,8 @@ impl VirtualList { } } -/// A view that is like a [`virtual_stack`](super::virtual_stack()) but also supports item selection. -/// See the [`virtual_stack`](super::virtual_stack()) for more documentation and an example. +/// A view that is like a [`virtual_stack`] but also supports item selection. +/// See the [`virtual_stack`] for more documentation and an example. /// /// Selection is done using the following: up and down using arrow keys, top and bottom control using the home and end keys, and for the “acceptance” of an item using the Enter key. pub fn virtual_list( diff --git a/src/views/virtual_stack.rs b/src/views/virtual_stack.rs index a3f86865..ca747f1d 100644 --- a/src/views/virtual_stack.rs +++ b/src/views/virtual_stack.rs @@ -30,7 +30,7 @@ pub enum VirtualItemSize { Fixed(Box f64>), } -/// A trait that can be implemented on a type so that the type can be used in a [`virtual_stack`] or [`virtual_list`](super::virtual_list()). +/// A trait that can be implemented on a type so that the type can be used in a [`virtual_stack`] or [`virtual_list`](super::virtual_list::virtual_list). pub trait VirtualVector { fn total_len(&self) -> usize; From 6e6be0e797d46d7337d3406cac57e4d45fc84b2c Mon Sep 17 00:00:00 2001 From: jrmoulton Date: Sat, 12 Oct 2024 16:54:05 -0600 Subject: [PATCH 4/7] use f as keframe animation convention --- examples/animations/src/main.rs | 14 +++++++------- examples/view-transition/src/main.rs | 2 +- src/animate.rs | 16 ++++++++-------- src/lib.rs | 10 +++++----- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/examples/animations/src/main.rs b/examples/animations/src/main.rs index dd2976fd..c4c7b087 100644 --- a/examples/animations/src/main.rs +++ b/examples/animations/src/main.rs @@ -12,13 +12,13 @@ fn app_view() -> impl IntoView { let animation = RwSignal::new( Animation::new() .duration(5.seconds()) - .keyframe(0, |kf| kf.computed_style()) - .keyframe(50, |kf| { - kf.style(|s| s.background(Color::BLACK).size(30, 30)) + .keyframe(0, |f| f.computed_style()) + .keyframe(50, |f| { + f.style(|s| s.background(Color::BLACK).size(30, 30)) .ease_in() }) - .keyframe(100, |kf| { - kf.style(|s| s.background(Color::AQUAMARINE).size(10, 300)) + .keyframe(100, |f| { + f.style(|s| s.background(Color::AQUAMARINE).size(10, 300)) .ease_out() }) .repeat(true) @@ -36,8 +36,8 @@ fn app_view() -> impl IntoView { .style(|s| s.background(Color::BLUE).size(50, 100)) .animation(move |_| animation.get()) .animation(move |a| { - a.keyframe(100, |kf| { - kf.style(|s| s.border(5).border_color(Color::PURPLE)) + a.keyframe(100, |f| { + f.style(|s| s.border(5).border_color(Color::PURPLE)) }) .duration(5.seconds()) .repeat(true) diff --git a/examples/view-transition/src/main.rs b/examples/view-transition/src/main.rs index e0b1e9b9..85c3faa6 100644 --- a/examples/view-transition/src/main.rs +++ b/examples/view-transition/src/main.rs @@ -34,7 +34,7 @@ impl ViewSwitcher { .style(|s| s.padding(8)) .animation(|a| { a.view_transition() - .keyframe(0, |kf| kf.style(|s| s.padding(0))) + .keyframe(0, |f| f.style(|s| s.padding(0))) }) } } diff --git a/src/animate.rs b/src/animate.rs index 5e3a66cf..b77b524b 100644 --- a/src/animate.rs +++ b/src/animate.rs @@ -421,28 +421,28 @@ impl Animation { self.run_on_create(true) .run_on_remove(true) .initial_state(AnimStateCommand::Stop) - .keyframe(0, |kf| kf.computed_style().ease(Spring::gentle())) - .keyframe(100, |kf| kf.computed_style().ease(Spring::gentle())) + .keyframe(0, |f| f.computed_style().ease(Spring::gentle())) + .keyframe(100, |f| f.computed_style().ease(Spring::gentle())) } /// Quickly set an animation to be a view transition and override the default easing function on keyframes 0 and 100. pub fn view_transition_with_ease(self, ease: impl Easing + 'static + Clone) -> Self { self.view_transition() - .keyframe(0, |kf| kf.computed_style().ease(ease.clone())) - .keyframe(100, |kf| kf.computed_style().ease(ease.clone())) + .keyframe(0, |f| f.computed_style().ease(ease.clone())) + .keyframe(100, |f| f.computed_style().ease(ease.clone())) } /// Quickly set an animation to be a view transition and set the animation to animate from scale 0% to the "normal" computed style of a view (the view with no animations applied). pub fn scale_effect(self) -> Self { self.view_transition() - .keyframe(0, |kf| kf.style(|s| s.scale(0.pct()))) + .keyframe(0, |f| f.style(|s| s.scale(0.pct()))) .debug_name("Scale the width and height from zero to the default") } /// Quickly set an animation to be a view transition and set the animation to animate from size(0, 0) to the "normal" computed style of a view (the view with no animations applied). pub fn scale_size_effect(self) -> Self { self.view_transition() - .keyframe(0, |kf| kf.style(|s| s.size(0, 0))) + .keyframe(0, |f| f.style(|s| s.size(0, 0))) .debug_name("Scale the width and height from zero to the default") } } @@ -503,8 +503,8 @@ impl Animation { ) -> Self { let frame = key_frame(KeyFrame::new(frame_id)); let frame_style = frame.style.clone(); - if let Some(kf) = self.key_frames.insert(frame_id, frame) { - if let KeyFrameStyle::Style(style) = kf.style { + if let Some(f) = self.key_frames.insert(frame_id, frame) { + if let KeyFrameStyle::Style(style) = f.style { for prop in style.style_props() { self.cache.remove_prop(prop, frame_id); } diff --git a/src/lib.rs b/src/lib.rs index f7a78f30..6815908b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -153,13 +153,13 @@ //! .style(|s| s.background(Color::RED).size(500, 100)) //! .animation(move |a| { //! a.duration(5.seconds()) -//! .keyframe(0, |kf| kf.computed_style()) -//! .keyframe(50, |kf| { -//! kf.style(|s| s.background(Color::BLACK).size(30, 30)) +//! .keyframe(0, |f| f.computed_style()) +//! .keyframe(50, |f| { +//! f.style(|s| s.background(Color::BLACK).size(30, 30)) //! .ease_in() //! }) -//! .keyframe(100, |kf| { -//! kf.style(|s| s.background(Color::AQUAMARINE).size(10, 300)) +//! .keyframe(100, |f| { +//! f.style(|s| s.background(Color::AQUAMARINE).size(10, 300)) //! .ease_out() //! }) //! .auto_reverse(true) From 7b11003b6062e072a9a1bad939cd9ed286a60bde Mon Sep 17 00:00:00 2001 From: jrmoulton Date: Sat, 12 Oct 2024 16:55:36 -0600 Subject: [PATCH 5/7] remove view tuple stack ext --- src/view_tuple.rs | 23 ++++++++++++++++++++++- src/views/stack.rs | 37 +++++++------------------------------ 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/view_tuple.rs b/src/view_tuple.rs index 77703db8..825f4689 100644 --- a/src/view_tuple.rs +++ b/src/view_tuple.rs @@ -1,7 +1,25 @@ -use crate::view::{IntoView, View}; +use taffy::FlexDirection; + +use crate::{ + view::{IntoView, View}, + views::{create_stack, Stack}, +}; pub trait ViewTuple { fn into_views(self) -> Vec>; + fn stack(self, direction: FlexDirection) -> Stack; + fn v_stack(self) -> Stack + where + Self: Sized, + { + ViewTuple::stack(self, FlexDirection::Column) + } + fn h_stack(self) -> Stack + where + Self: Sized, + { + ViewTuple::stack(self, FlexDirection::Row) + } } // Macro to implement ViewTuple for tuples of Views and Vec> @@ -15,6 +33,9 @@ macro_rules! impl_view_tuple { $($t.into_any(),)+ ] } + fn stack(self, direction: FlexDirection) -> Stack { + create_stack(self.into_views(), Some(direction)) + } } impl<$($t: IntoView + 'static),+> IntoView for ($($t,)+) { diff --git a/src/views/stack.rs b/src/views/stack.rs index 134b4b13..855b74ec 100644 --- a/src/views/stack.rs +++ b/src/views/stack.rs @@ -34,13 +34,7 @@ pub(crate) fn create_stack( /// ## Example /// ```rust /// use floem::views::*; -/// stack(( -/// text("first element"), -/// stack(( -/// text("new stack"), -/// empty(), -/// )), -/// )); +/// stack((text("first element"), stack((text("new stack"), empty())))); /// ``` pub fn stack(children: VT) -> Stack { create_stack(children.into_views(), None) @@ -74,7 +68,11 @@ where /// ## Example /// ```rust /// use floem::views::*; -/// stack_from_iter(vec![1,1,2,2,3,4,5,6,7,8,9].iter().map(|val| text(val))); +/// stack_from_iter( +/// vec![1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9] +/// .iter() +/// .map(|val| text(val)), +/// ); /// ``` pub fn stack_from_iter(iterator: impl IntoIterator) -> Stack where @@ -135,6 +133,7 @@ impl Stack { } } +/// An extenstion trait that let's you build a stack by calling `.v_stack` or `.h_stack`. pub trait StackExt { fn stack(self, direction: FlexDirection) -> Stack; fn v_stack(self) -> Stack @@ -155,25 +154,3 @@ impl + 'static> StackExt for T from_iter(self, Some(direction)) } } -// Necessary to have a separate Ext trait because IntoIterator could be implemented on tuples of specific view types -pub trait TupleStackExt { - fn stack(self, direction: FlexDirection) -> Stack; - fn v_stack(self) -> Stack - where - Self: Sized, - { - TupleStackExt::stack(self, FlexDirection::Column) - } - fn h_stack(self) -> Stack - where - Self: Sized, - { - TupleStackExt::stack(self, FlexDirection::Row) - } -} - -impl TupleStackExt for T { - fn stack(self, direction: FlexDirection) -> Stack { - create_stack(self.into_views(), Some(direction)) - } -} From e9912be6f5f0e80390dbf00908fb2e0fbfac9765 Mon Sep 17 00:00:00 2001 From: jrmoulton Date: Sat, 12 Oct 2024 16:57:45 -0600 Subject: [PATCH 6/7] add prelude --- examples/widget-gallery/src/main.rs | 7 ++----- src/inspector.rs | 7 ++----- src/lib.rs | 11 +++++++++++ src/views/dyn_container.rs | 7 ++----- src/views/mod.rs | 11 +++++++---- src/views/toggle_button.rs | 10 +++++----- src/views/virtual_stack.rs | 3 ++- 7 files changed, 31 insertions(+), 25 deletions(-) diff --git a/examples/widget-gallery/src/main.rs b/examples/widget-gallery/src/main.rs index 22042c7f..20aa783c 100644 --- a/examples/widget-gallery/src/main.rs +++ b/examples/widget-gallery/src/main.rs @@ -15,13 +15,10 @@ pub mod slider; use floem::{ event::{Event, EventListener, EventPropagation}, keyboard::{Key, NamedKey}, - peniko::Color, - reactive::{create_signal, SignalGet, SignalUpdate}, + prelude::*, style::{Background, CursorStyle, Transition}, - unit::{DurationUnitExt, UnitExt}, - views::{button, h_stack, label, scroll, stack, tab::*, v_stack, virtual_stack::*, Decorators}, - IntoView, View, }; +use virtual_stack::*; fn app_view() -> impl IntoView { let tabs: im::Vector<&str> = vec![ diff --git a/src/inspector.rs b/src/inspector.rs index 9005e9c9..acce9dc3 100644 --- a/src/inspector.rs +++ b/src/inspector.rs @@ -3,14 +3,10 @@ use crate::app_state::AppState; use crate::context::StyleCx; use crate::event::{Event, EventListener, EventPropagation}; use crate::id::ViewId; +use crate::prelude::*; use crate::profiler::profiler; use crate::style::{Style, StyleClassRef, StylePropRef, Transition}; -use crate::view::{IntoView, View}; use crate::view_state::ChangeFlags; -use crate::views::{ - button, container, dyn_container, empty, h_stack, img_dynamic, scroll, stack, static_label, - tab::*, text, text_input, v_stack, v_stack_from_iter, Decorators, Label, -}; use crate::window::WindowConfig; use crate::{new_window, style, Clipboard}; use floem_reactive::{ @@ -19,6 +15,7 @@ use floem_reactive::{ use floem_winit::keyboard::{self, NamedKey}; use floem_winit::window::WindowId; use image::DynamicImage; +use img::img_dynamic; use peniko::kurbo::{Point, Rect, Size}; use peniko::Color; use slotmap::Key; diff --git a/src/lib.rs b/src/lib.rs index 6815908b..52cfa014 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -228,3 +228,14 @@ pub use taffy; pub use view::{recursively_layout_view, AnyView, IntoView, View}; pub use window::{close_window, new_window}; pub use window_id::{Urgency, WindowIdExt}; + +pub mod prelude { + pub use crate::unit::{DurationUnitExt, UnitExt}; + pub use crate::view_tuple::ViewTuple; + pub use crate::views::*; + pub use crate::{IntoView, View}; + pub use floem_reactive::{ + create_rw_signal, create_signal, RwSignal, SignalGet, SignalTrack, SignalUpdate, SignalWith, + }; + pub use peniko::Color; +} diff --git a/src/views/dyn_container.rs b/src/views/dyn_container.rs index 7273f7ae..79e1ab7a 100644 --- a/src/views/dyn_container.rs +++ b/src/views/dyn_container.rs @@ -48,11 +48,8 @@ pub struct DynamicContainer { /// /// ## Example /// ``` -/// use floem::{ -/// reactive::{create_rw_signal, SignalGet, SignalUpdate}, -/// views::{dyn_container, label, toggle_button, v_stack, Decorators}, -/// IntoView, View, -/// }; +/// use floem::prelude::*; +/// use toggle_button::toggle_button; /// /// #[derive(Clone)] /// enum ViewSwitcher { diff --git a/src/views/mod.rs b/src/views/mod.rs index bfad2c6d..5107ac16 100644 --- a/src/views/mod.rs +++ b/src/views/mod.rs @@ -25,7 +25,7 @@ //! Views in Floem can also be easily refactored. //! ## Example: Refactored Counter //! ```rust -//! use floem::{reactive::*, views::*}; +//! use floem::prelude::*; //! //! let mut counter = RwSignal::new(0); //! @@ -99,13 +99,16 @@ mod list; pub use list::*; pub mod virtual_list; +pub use virtual_list::virtual_list; pub mod virtual_stack; +pub use virtual_stack::virtual_stack; pub mod scroll; -pub use scroll::{scroll, Scroll}; +pub use scroll::{scroll, Scroll, ScrollExt}; pub mod tab; +pub use tab::tab; pub mod tooltip; @@ -122,8 +125,8 @@ pub mod drag_window_area; pub mod drag_resize_window_area; -mod img; -pub use img::*; +pub mod img; +pub use img::img; mod button; pub use button::*; diff --git a/src/views/toggle_button.rs b/src/views/toggle_button.rs index b0594874..f4db66c3 100644 --- a/src/views/toggle_button.rs +++ b/src/views/toggle_button.rs @@ -82,12 +82,12 @@ pub struct ToggleButton { /// /// An example using [`RwSignal`](floem_reactive::RwSignal): /// ```rust -/// use floem::reactive::{SignalGet, SignalUpdate}; +/// use floem::prelude::*; +/// use toggle_button::toggle_button; /// -/// let state = floem::reactive::create_rw_signal(true); -/// floem::views::toggle_button(move || state.get()) -/// .on_toggle(move |new_state| state.set(new_state)); -///``` +/// let state = create_rw_signal(true); +/// toggle_button(move || state.get()).on_toggle(move |new_state| state.set(new_state)); +/// ``` pub fn toggle_button(state: impl Fn() -> bool + 'static) -> ToggleButton { ToggleButton::new(state) } diff --git a/src/views/virtual_stack.rs b/src/views/virtual_stack.rs index ca747f1d..6aa0ee24 100644 --- a/src/views/virtual_stack.rs +++ b/src/views/virtual_stack.rs @@ -80,7 +80,8 @@ struct VirtualStackState { /// /// ## Example /// ``` -/// use floem::{reactive::*, unit::UnitExt, views::*}; +/// use floem::prelude::*; +/// use floem::views::virtual_stack::*; /// /// let long_list: im::Vector = (0..1000000).collect(); /// let (long_list, _set_long_list) = create_signal(long_list); From 42b017bf6298aacf7620137a7c27a006d19675a3 Mon Sep 17 00:00:00 2001 From: jrmoulton Date: Sat, 12 Oct 2024 16:58:26 -0600 Subject: [PATCH 7/7] update checkbox docs also removes checkbox constructor function --- examples/widget-gallery/src/checkbox.rs | 13 ++++---- src/view.rs | 7 ++--- src/views/checkbox.rs | 40 ++++++++++++------------- 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/examples/widget-gallery/src/checkbox.rs b/examples/widget-gallery/src/checkbox.rs index 672aebe3..b5f4ff1e 100644 --- a/examples/widget-gallery/src/checkbox.rs +++ b/examples/widget-gallery/src/checkbox.rs @@ -1,8 +1,5 @@ -use floem::{ - reactive::{RwSignal, SignalGet}, - views::{checkbox::*, Decorators}, - IntoView, -}; +use checkbox::Checkbox; +use floem::prelude::*; use crate::form::{form, form_item}; @@ -15,18 +12,18 @@ pub fn checkbox_view() -> impl IntoView { Checkbox::new_rw(is_checked).style(|s| s.margin(5.0)) }), form_item("Disabled Checkbox:".to_string(), width, move || { - checkbox(move || is_checked.get()) + Checkbox::new(move || is_checked.get()) .style(|s| s.margin(5.0)) .disabled(|| true) }), form_item("Labelled Checkbox:".to_string(), width, move || { - Checkbox::new_labeled_rw(is_checked, || "Check me!") + Checkbox::labeled_rw(is_checked, || "Check me!") }), form_item( "Disabled Labelled Checkbox:".to_string(), width, move || { - labeled_checkbox(move || is_checked.get(), || "Check me!").disabled(|| true) + Checkbox::labeled(move || is_checked.get(), || "Check me!").disabled(|| true) }, ), ) diff --git a/src/view.rs b/src/view.rs index 56047a55..f2cf2159 100644 --- a/src/view.rs +++ b/src/view.rs @@ -66,14 +66,13 @@ use crate::{ /// to escape the strongly typed requirement. /// /// ``` -/// use floem::reactive::{RwSignal, SignalGet}; -/// use floem::views::*; -/// use floem::{IntoView, View}; +/// use checkbox::Checkbox; +/// use floem::prelude::*; /// /// let check = true; /// /// container(if check == true { -/// checkbox(|| true).into_any() +/// Checkbox::new(|| true).into_any() /// } else { /// label(|| "no check".to_string()).into_any() /// }); diff --git a/src/views/checkbox.rs b/src/views/checkbox.rs index b82a1427..30086c0b 100644 --- a/src/views/checkbox.rs +++ b/src/views/checkbox.rs @@ -1,3 +1,6 @@ +#![deny(missing_docs)] +//! A checkbox view for boolean selection. + use crate::{ style_class, view::IntoView, @@ -6,9 +9,15 @@ use crate::{ use floem_reactive::{SignalGet, SignalUpdate}; use std::fmt::Display; -style_class!(pub CheckboxClass); +style_class!( + /// The Style class that is applied to the checkbox. + pub CheckboxClass +); -style_class!(pub LabeledCheckboxClass); +style_class!( + /// The Style class that is applied to the labeled checkbox stack. + pub LabeledCheckboxClass +); fn checkbox_svg(checked: impl SignalGet + 'static) -> impl IntoView { const CHECKBOX_SVG: &str = r#""#; @@ -19,11 +28,13 @@ fn checkbox_svg(checked: impl SignalGet + 'static) -> impl IntoView { .keyboard_navigatable() } -/// The `Checkbox` struct provides various methods to create and manage checkboxes. +/// # A customizable checkbox view for boolean selection. +/// +/// The `Checkbox` struct provides several constructors, each offering different levels of +/// customization and ease of use. The simplest is the [Checkbox::new_rw] constructor, which gets direct access to a signal and will update it when the checkbox is clicked. /// -/// # Related Functions -/// - [`checkbox`] -/// - [`labeled_checkbox`] +/// Choose the constructor that best fits your needs based on whether you require labeling +/// and how you prefer to manage the checkbox's state (via closure or direct signal manipulation). pub struct Checkbox; impl Checkbox { @@ -62,7 +73,7 @@ impl Checkbox { /// /// This method is useful when you want a labeled checkbox whose state is determined by a closure. /// The label is also provided by a closure, allowing for dynamic updates. - pub fn new_labeled( + pub fn labeled( checked: impl Fn() -> bool + 'static, label: impl Fn() -> S + 'static, ) -> ValueContainer { @@ -87,7 +98,7 @@ impl Checkbox { /// /// This method is ideal when you need a labeled checkbox that not only reflects a signal's state but also updates it. /// Clicking the checkbox will toggle its state and update the signal accordingly. - pub fn new_labeled_rw( + pub fn labeled_rw( checked: impl SignalGet + SignalUpdate + Copy + 'static, label: impl Fn() -> S + 'static, ) -> impl IntoView { @@ -99,16 +110,3 @@ impl Checkbox { }) } } - -/// Renders a checkbox the provided checked signal. -pub fn checkbox(checked: impl Fn() -> bool + 'static) -> ValueContainer { - Checkbox::new(checked) -} - -/// Renders a checkbox using the provided checked signal. -pub fn labeled_checkbox( - checked: impl Fn() -> bool + 'static, - label: impl Fn() -> S + 'static, -) -> ValueContainer { - Checkbox::new_labeled(checked, label) -}