diff options
author | 2022-01-12 11:15:05 +0700 | |
---|---|---|
committer | 2022-01-12 11:15:05 +0700 | |
commit | 870d651f35c4dad12c805951fca70213816983de (patch) | |
tree | dcf50e912ca3e7823e07aee635c7e5f464b5bd66 /native | |
parent | 5a03cac7e75ccb8ca87a97def723694be0471742 (diff) | |
download | iced-870d651f35c4dad12c805951fca70213816983de.tar.gz iced-870d651f35c4dad12c805951fca70213816983de.tar.bz2 iced-870d651f35c4dad12c805951fca70213816983de.zip |
Implement `Widget::overlay` for `Responsive` widget
Diffstat (limited to 'native')
-rw-r--r-- | native/src/widget.rs | 3 | ||||
-rw-r--r-- | native/src/widget/responsive.rs | 212 |
2 files changed, 0 insertions, 215 deletions
diff --git a/native/src/widget.rs b/native/src/widget.rs index 30405346..acd2e580 100644 --- a/native/src/widget.rs +++ b/native/src/widget.rs @@ -20,7 +20,6 @@ pub mod pane_grid; pub mod pick_list; pub mod progress_bar; pub mod radio; -pub mod responsive; pub mod row; pub mod rule; pub mod scrollable; @@ -51,8 +50,6 @@ pub use progress_bar::ProgressBar; #[doc(no_inline)] pub use radio::Radio; #[doc(no_inline)] -pub use responsive::Responsive; -#[doc(no_inline)] pub use row::Row; #[doc(no_inline)] pub use rule::Rule; diff --git a/native/src/widget/responsive.rs b/native/src/widget/responsive.rs deleted file mode 100644 index fd9e490a..00000000 --- a/native/src/widget/responsive.rs +++ /dev/null @@ -1,212 +0,0 @@ -use crate::event::{self, Event}; -use crate::layout::{self, Layout}; -use crate::mouse; -use crate::renderer; -use crate::{ - Clipboard, Element, Hasher, Length, Point, Rectangle, Shell, Size, Widget, -}; - -use std::cell::RefCell; -use std::hash::Hasher as _; - -#[derive(Debug, Clone, Default)] -pub struct State { - last_size: Option<Size>, - last_layout: layout::Node, - last_layout_hash: u64, -} - -impl State { - pub fn new() -> State { - State::default() - } -} - -#[allow(missing_debug_implementations)] -pub struct Responsive<'a, Message, Renderer>( - RefCell<Internal<'a, Message, Renderer>>, -); - -impl<'a, Message, Renderer> Responsive<'a, Message, Renderer> { - pub fn new( - state: &'a mut State, - view: impl FnOnce(Size) -> Element<'a, Message, Renderer> + 'a, - ) -> Self { - Self(RefCell::new(Internal { - state, - content: Content::Pending(Some(Box::new(view))), - })) - } -} - -impl<'a, Message, Renderer> Widget<Message, Renderer> - for Responsive<'a, Message, Renderer> -where - Renderer: crate::Renderer, -{ - fn width(&self) -> Length { - Length::Fill - } - - fn height(&self) -> Length { - Length::Fill - } - - fn hash_layout(&self, _hasher: &mut Hasher) {} - - fn layout( - &self, - _renderer: &Renderer, - limits: &layout::Limits, - ) -> layout::Node { - let size = limits.max(); - - self.0.borrow_mut().state.last_size = Some(size); - - layout::Node::new(size) - } - - fn on_event( - &mut self, - event: Event, - layout: Layout<'_>, - cursor_position: Point, - renderer: &Renderer, - clipboard: &mut dyn Clipboard, - shell: &mut Shell<'_, Message>, - ) -> event::Status { - let mut internal = self.0.borrow_mut(); - - if internal.state.last_size != Some(internal.state.last_layout.size()) { - shell.invalidate_widgets(); - } - - let (content, content_layout) = internal.content(layout, renderer); - - content.on_event( - event, - content_layout, - cursor_position, - renderer, - clipboard, - shell, - ) - } - - fn draw( - &self, - renderer: &mut Renderer, - style: &renderer::Style, - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - ) { - let mut internal = self.0.borrow_mut(); - let (content, content_layout) = internal.content(layout, renderer); - - content.draw(renderer, style, content_layout, cursor_position, viewport) - } - - fn mouse_interaction( - &self, - layout: Layout<'_>, - cursor_position: Point, - viewport: &Rectangle, - renderer: &Renderer, - ) -> mouse::Interaction { - let mut internal = self.0.borrow_mut(); - let (content, content_layout) = internal.content(layout, renderer); - - content.mouse_interaction( - content_layout, - cursor_position, - viewport, - renderer, - ) - } -} - -struct Internal<'a, Message, Renderer> { - state: &'a mut State, - content: Content<'a, Message, Renderer>, -} - -impl<'a, Message, Renderer> Internal<'a, Message, Renderer> -where - Renderer: crate::Renderer, -{ - fn content( - &mut self, - layout: Layout<'_>, - renderer: &Renderer, - ) -> (&mut Element<'a, Message, Renderer>, Layout<'_>) { - let content = self.content.resolve(&mut self.state, renderer); - - let content_layout = Layout::with_offset( - layout.position() - Point::ORIGIN, - &self.state.last_layout, - ); - - (content, content_layout) - } -} - -enum Content<'a, Message, Renderer> { - Pending( - Option<Box<dyn FnOnce(Size) -> Element<'a, Message, Renderer> + 'a>>, - ), - Ready(Element<'a, Message, Renderer>), -} - -impl<'a, Message, Renderer> Content<'a, Message, Renderer> -where - Renderer: crate::Renderer, -{ - fn resolve( - &mut self, - state: &mut State, - renderer: &Renderer, - ) -> &mut Element<'a, Message, Renderer> { - match self { - Content::Ready(element) => element, - Content::Pending(view) => { - let element = - view.take().unwrap()(state.last_size.unwrap_or(Size::ZERO)); - - let new_layout_hash = { - let mut hasher = Hasher::default(); - element.hash_layout(&mut hasher); - - hasher.finish() - }; - - if new_layout_hash != state.last_layout_hash { - state.last_layout = element.layout( - renderer, - &layout::Limits::new( - Size::ZERO, - state.last_size.unwrap_or(Size::ZERO), - ), - ); - - state.last_layout_hash = new_layout_hash; - } - - *self = Content::Ready(element); - - self.resolve(state, renderer) - } - } - } -} - -impl<'a, Message, Renderer> From<Responsive<'a, Message, Renderer>> - for Element<'a, Message, Renderer> -where - Renderer: crate::Renderer + 'a, - Message: 'a, -{ - fn from(responsive: Responsive<'a, Message, Renderer>) -> Self { - Self::new(responsive) - } -} |