Implement Widget::draw for overlay::Menu

This commit is contained in:
Héctor Ramón Jiménez 2021-10-28 16:43:05 +07:00
parent 5a942ee7ee
commit 081f2c1e1a
No known key found for this signature in database
GPG key ID: 140CC052C94F138E

View file

@ -1,14 +1,16 @@
//! Build and show dropdown menus. //! Build and show dropdown menus.
use crate::alignment;
use crate::event::{self, Event}; use crate::event::{self, Event};
use crate::layout; use crate::layout;
use crate::mouse; use crate::mouse;
use crate::overlay; use crate::overlay;
use crate::renderer; use crate::renderer;
use crate::renderer::text;
use crate::scrollable; use crate::scrollable;
use crate::touch; use crate::touch;
use crate::{ use crate::{
Clipboard, Container, Element, Hasher, Layout, Length, Padding, Point, Clipboard, Color, Container, Element, Hasher, Layout, Length, Padding,
Rectangle, Scrollable, Size, Vector, Widget, Point, Rectangle, Scrollable, Size, Vector, Widget,
}; };
pub use iced_style::menu::Style; pub use iced_style::menu::Style;
@ -238,21 +240,18 @@ where
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: Point, cursor_position: Point,
) { ) {
// TODO let bounds = layout.bounds();
// let primitives = self.container.draw(
// renderer,
// defaults,
// layout,
// cursor_position,
// &layout.bounds(),
// );
// renderer.decorate( renderer.fill_rectangle(renderer::Quad {
// layout.bounds(), bounds,
// cursor_position, background: self.style.background,
// &self.style, border_color: self.style.border_color,
// primitives, 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( fn draw(
&self, &self,
_renderer: &mut Renderer, renderer: &mut Renderer,
_style: &renderer::Style, _style: &renderer::Style,
_layout: Layout<'_>, layout: Layout<'_>,
_cursor_position: Point, _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,
});
}
} }
} }