summaryrefslogtreecommitdiffstats
path: root/graphics/src/overlay
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/src/overlay')
-rw-r--r--graphics/src/overlay/menu.rs108
1 files changed, 108 insertions, 0 deletions
diff --git a/graphics/src/overlay/menu.rs b/graphics/src/overlay/menu.rs
new file mode 100644
index 00000000..a952f065
--- /dev/null
+++ b/graphics/src/overlay/menu.rs
@@ -0,0 +1,108 @@
+//! Build and show dropdown menus.
+use crate::backend::{self, Backend};
+use crate::{Primitive, Renderer};
+use iced_native::{
+ mouse, overlay, Color, Font, HorizontalAlignment, Point, Rectangle,
+ VerticalAlignment,
+};
+
+pub use iced_style::menu::Style;
+
+impl<B> overlay::menu::Renderer for Renderer<B>
+where
+ B: Backend + backend::Text,
+{
+ type Style = Style;
+
+ fn decorate(
+ &mut self,
+ bounds: Rectangle,
+ _cursor_position: Point,
+ style: &Style,
+ (primitives, mouse_cursor): Self::Output,
+ ) -> Self::Output {
+ (
+ Primitive::Group {
+ primitives: vec![
+ Primitive::Quad {
+ bounds,
+ background: style.background,
+ border_color: style.border_color,
+ border_width: style.border_width,
+ border_radius: 0,
+ },
+ primitives,
+ ],
+ },
+ mouse_cursor,
+ )
+ }
+
+ fn draw<T: ToString>(
+ &mut self,
+ bounds: Rectangle,
+ cursor_position: Point,
+ options: &[T],
+ hovered_option: Option<usize>,
+ padding: u16,
+ text_size: u16,
+ font: Font,
+ style: &Style,
+ ) -> Self::Output {
+ use std::f32;
+
+ let is_mouse_over = bounds.contains(cursor_position);
+
+ let mut primitives = Vec::new();
+
+ for (i, option) in options.iter().enumerate() {
+ let is_selected = hovered_option == Some(i);
+
+ let bounds = Rectangle {
+ x: bounds.x,
+ y: bounds.y
+ + ((text_size as usize + padding as usize * 2) * i) as f32,
+ width: bounds.width,
+ height: f32::from(text_size + padding * 2),
+ };
+
+ if is_selected {
+ primitives.push(Primitive::Quad {
+ bounds,
+ background: style.selected_background,
+ border_color: Color::TRANSPARENT,
+ border_width: 0,
+ border_radius: 0,
+ });
+ }
+
+ primitives.push(Primitive::Text {
+ content: option.to_string(),
+ bounds: Rectangle {
+ x: bounds.x + f32::from(padding),
+ y: bounds.center_y(),
+ width: f32::INFINITY,
+ ..bounds
+ },
+ size: f32::from(text_size),
+ font,
+ color: if is_selected {
+ style.selected_text_color
+ } else {
+ style.text_color
+ },
+ horizontal_alignment: HorizontalAlignment::Left,
+ vertical_alignment: VerticalAlignment::Center,
+ });
+ }
+
+ (
+ Primitive::Group { primitives },
+ if is_mouse_over {
+ mouse::Interaction::Pointer
+ } else {
+ mouse::Interaction::default()
+ },
+ )
+ }
+}