diff options
author | 2021-10-28 16:43:05 +0700 | |
---|---|---|
committer | 2021-10-28 16:43:05 +0700 | |
commit | 081f2c1e1a65a084326d5f7f9bbce68440369308 (patch) | |
tree | 27e207948c2bc41b1152a0de2d690e45fae76ca8 /native/src/overlay | |
parent | 5a942ee7ee55c8aa30b48b289661aaec81418f44 (diff) | |
download | iced-081f2c1e1a65a084326d5f7f9bbce68440369308.tar.gz iced-081f2c1e1a65a084326d5f7f9bbce68440369308.tar.bz2 iced-081f2c1e1a65a084326d5f7f9bbce68440369308.zip |
Implement `Widget::draw` for `overlay::Menu`
Diffstat (limited to 'native/src/overlay')
-rw-r--r-- | native/src/overlay/menu.rs | 92 |
1 files changed, 71 insertions, 21 deletions
diff --git a/native/src/overlay/menu.rs b/native/src/overlay/menu.rs index ebb2a4e1..8f91e4b7 100644 --- a/native/src/overlay/menu.rs +++ b/native/src/overlay/menu.rs @@ -1,14 +1,16 @@ //! Build and show dropdown menus. +use crate::alignment; use crate::event::{self, Event}; use crate::layout; use crate::mouse; use crate::overlay; use crate::renderer; +use crate::renderer::text; use crate::scrollable; use crate::touch; use crate::{ - Clipboard, Container, Element, Hasher, Layout, Length, Padding, Point, - Rectangle, Scrollable, Size, Vector, Widget, + Clipboard, Color, Container, Element, Hasher, Layout, Length, Padding, + Point, Rectangle, Scrollable, Size, Vector, Widget, }; pub use iced_style::menu::Style; @@ -238,21 +240,18 @@ where layout: Layout<'_>, cursor_position: Point, ) { - // TODO - // let primitives = self.container.draw( - // renderer, - // defaults, - // layout, - // cursor_position, - // &layout.bounds(), - // ); - - // renderer.decorate( - // layout.bounds(), - // cursor_position, - // &self.style, - // primitives, - // ) + let bounds = layout.bounds(); + + renderer.fill_rectangle(renderer::Quad { + bounds, + background: self.style.background, + border_color: self.style.border_color, + border_width: self.style.border_width, + border_radius: 0.0, + }); + + self.container + .draw(renderer, style, layout, cursor_position, &bounds); } } @@ -377,13 +376,64 @@ where fn draw( &self, - _renderer: &mut Renderer, + renderer: &mut Renderer, _style: &renderer::Style, - _layout: Layout<'_>, + layout: Layout<'_>, _cursor_position: Point, - _viewport: &Rectangle, + viewport: &Rectangle, ) { - // TODO + let bounds = layout.bounds(); + + let text_size = self.text_size.unwrap_or(renderer.default_size()); + let option_height = (text_size + self.padding.vertical()) as usize; + + let offset = viewport.y - bounds.y; + let start = (offset / option_height as f32) as usize; + let end = + ((offset + viewport.height) / option_height as f32).ceil() as usize; + + let visible_options = &self.options[start..end.min(self.options.len())]; + + for (i, option) in visible_options.iter().enumerate() { + let i = start + i; + let is_selected = *self.hovered_option == Some(i); + + let bounds = Rectangle { + x: bounds.x, + y: bounds.y + (option_height * i) as f32, + width: bounds.width, + height: f32::from(text_size + self.padding.vertical()), + }; + + if is_selected { + renderer.fill_rectangle(renderer::Quad { + bounds, + background: self.style.selected_background, + border_color: Color::TRANSPARENT, + border_width: 0.0, + border_radius: 0.0, + }); + } + + renderer.fill_text(text::Section { + content: &option.to_string(), + bounds: Rectangle { + x: bounds.x + self.padding.left as f32, + y: bounds.center_y(), + width: f32::INFINITY, + ..bounds + }, + size: f32::from(text_size), + font: self.font, + color: if is_selected { + self.style.selected_text_color + } else { + self.style.text_color + }, + horizontal_alignment: alignment::Horizontal::Left, + vertical_alignment: alignment::Vertical::Center, + }); + } } } |