From 0ff5a02550e5d5de8fb5fd0643ea424d9e508888 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 23 May 2020 01:07:59 +0200 Subject: Rename `Layer` to `overlay::Content` --- native/src/layer/menu.rs | 323 ----------------------------------------------- 1 file changed, 323 deletions(-) delete mode 100644 native/src/layer/menu.rs (limited to 'native/src/layer/menu.rs') diff --git a/native/src/layer/menu.rs b/native/src/layer/menu.rs deleted file mode 100644 index 05026a54..00000000 --- a/native/src/layer/menu.rs +++ /dev/null @@ -1,323 +0,0 @@ -use crate::{ - container, layout, mouse, scrollable, Clipboard, Container, Element, Event, - Hasher, Layer, Layout, Length, Point, Rectangle, Scrollable, Size, Vector, - Widget, -}; -use std::borrow::Cow; - -pub struct Menu<'a, Message, Renderer: self::Renderer> { - container: Container<'a, Message, Renderer>, - is_open: &'a mut bool, - width: u16, - target_height: f32, -} - -#[derive(Default)] -pub struct State { - scrollable: scrollable::State, - hovered_option: Option, - is_open: bool, -} - -impl State { - pub fn is_open(&self) -> bool { - self.is_open - } - - pub fn open(&mut self, hovered_option: Option) { - self.is_open = true; - self.hovered_option = hovered_option; - } -} - -impl<'a, Message, Renderer: self::Renderer> Menu<'a, Message, Renderer> -where - Message: 'static, - Renderer: 'a, -{ - pub fn new( - state: &'a mut State, - options: impl Into>, - on_selected: Box Message>, - width: u16, - target_height: f32, - text_size: u16, - padding: u16, - ) -> Self - where - T: Clone + ToString, - [T]: ToOwned>, - { - let container = Container::new( - Scrollable::new(&mut state.scrollable).push(List::new( - &mut state.hovered_option, - options, - on_selected, - text_size, - padding, - )), - ) - .padding(1); - - Self { - container, - is_open: &mut state.is_open, - width, - target_height, - } - } -} - -impl<'a, Message, Renderer> Layer - for Menu<'a, Message, Renderer> -where - Renderer: self::Renderer, -{ - fn layout( - &self, - renderer: &Renderer, - bounds: Size, - position: Point, - ) -> layout::Node { - let space_below = bounds.height - (position.y + self.target_height); - let space_above = position.y; - - let limits = layout::Limits::new( - Size::ZERO, - Size::new( - bounds.width - position.x, - if space_below > space_above { - space_below - } else { - space_above - }, - ), - ) - .width(Length::Units(self.width)); - - let mut node = self.container.layout(renderer, &limits); - - node.move_to(if space_below > space_above { - position + Vector::new(0.0, self.target_height) - } else { - position - Vector::new(0.0, node.size().height) - }); - - node - } - - fn hash_layout(&self, state: &mut Hasher, position: Point) { - use std::hash::Hash; - - (position.x as u32).hash(state); - (position.y as u32).hash(state); - } - - fn on_event( - &mut self, - event: Event, - layout: Layout<'_>, - cursor_position: Point, - messages: &mut Vec, - renderer: &Renderer, - clipboard: Option<&dyn Clipboard>, - ) { - let bounds = layout.bounds(); - let current_messages = messages.len(); - - self.container.on_event( - event.clone(), - layout, - cursor_position, - messages, - renderer, - clipboard, - ); - - match event { - Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) - if !bounds.contains(cursor_position) - || current_messages < messages.len() => - { - *self.is_open = false; - } - _ => {} - } - } - - fn draw( - &self, - renderer: &mut Renderer, - defaults: &Renderer::Defaults, - layout: Layout<'_>, - cursor_position: Point, - ) -> Renderer::Output { - let primitives = - self.container - .draw(renderer, defaults, layout, cursor_position); - - renderer.decorate(layout.bounds(), cursor_position, primitives) - } -} - -struct List<'a, T, Message> -where - [T]: ToOwned, -{ - hovered_option: &'a mut Option, - options: Cow<'a, [T]>, - on_selected: Box Message>, - text_size: u16, - padding: u16, -} - -impl<'a, T, Message> List<'a, T, Message> -where - [T]: ToOwned, -{ - pub fn new( - hovered_option: &'a mut Option, - options: impl Into>, - on_selected: Box Message>, - text_size: u16, - padding: u16, - ) -> Self { - List { - hovered_option, - options: options.into(), - on_selected, - text_size, - padding, - } - } -} - -impl<'a, T, Message, Renderer> Widget<'a, Message, Renderer> - for List<'a, T, Message> -where - T: ToString + Clone, - [T]: ToOwned, - Renderer: self::Renderer, -{ - fn width(&self) -> Length { - Length::Fill - } - - fn height(&self) -> Length { - Length::Shrink - } - - fn layout( - &self, - _renderer: &Renderer, - limits: &layout::Limits, - ) -> layout::Node { - use std::f32; - - let limits = limits.width(Length::Fill).height(Length::Shrink); - - let size = { - let intrinsic = Size::new( - 0.0, - f32::from(self.text_size + self.padding * 2) - * self.options.len() as f32, - ); - - limits.resolve(intrinsic) - }; - - layout::Node::new(size) - } - - fn hash_layout(&self, state: &mut Hasher) { - use std::hash::Hash as _; - - 0.hash(state); - } - - fn on_event( - &mut self, - event: Event, - layout: Layout<'_>, - cursor_position: Point, - messages: &mut Vec, - _renderer: &Renderer, - _clipboard: Option<&dyn Clipboard>, - ) { - match event { - Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => { - let bounds = layout.bounds(); - - if bounds.contains(cursor_position) { - if let Some(index) = *self.hovered_option { - if let Some(option) = self.options.get(index) { - messages.push((self.on_selected)(option.clone())); - } - } - } - } - Event::Mouse(mouse::Event::CursorMoved { .. }) => { - let bounds = layout.bounds(); - - if bounds.contains(cursor_position) { - *self.hovered_option = Some( - ((cursor_position.y - bounds.y) - / f32::from(self.text_size + self.padding * 2)) - as usize, - ); - } - } - _ => {} - } - } - - fn draw( - &self, - renderer: &mut Renderer, - _defaults: &Renderer::Defaults, - layout: Layout<'_>, - cursor_position: Point, - ) -> Renderer::Output { - self::Renderer::draw( - renderer, - layout.bounds(), - cursor_position, - &self.options, - *self.hovered_option, - self.text_size, - self.padding, - ) - } -} - -pub trait Renderer: scrollable::Renderer + container::Renderer { - fn decorate( - &mut self, - bounds: Rectangle, - cursor_position: Point, - primitive: Self::Output, - ) -> Self::Output; - - fn draw( - &mut self, - bounds: Rectangle, - cursor_position: Point, - options: &[T], - hovered_option: Option, - text_size: u16, - padding: u16, - ) -> Self::Output; -} - -impl<'a, T, Message, Renderer> Into> - for List<'a, T, Message> -where - T: ToString + Clone, - [T]: ToOwned, - Message: 'static, - Renderer: self::Renderer, -{ - fn into(self) -> Element<'a, Message, Renderer> { - Element::new(self) - } -} -- cgit