Position Menu layer based on available space

This commit is contained in:
Héctor Ramón Jiménez 2020-04-18 20:44:14 +02:00
parent e29feef8ba
commit f655d9b967
3 changed files with 27 additions and 11 deletions

View File

@ -60,10 +60,6 @@ impl Sandbox for Example {
.push(Text::new("Which is your favorite language?")) .push(Text::new("Which is your favorite language?"))
.push(combo_box); .push(combo_box);
if self.selected_language == Language::Javascript {
content = content.push(Text::new("You are wrong!"));
}
content = content content = content
.push(button) .push(button)
.push(Space::with_height(Length::Units(800))); .push(Space::with_height(Length::Units(800)));

View File

@ -1,6 +1,7 @@
use crate::{ use crate::{
container, layout, mouse, scrollable, Clipboard, Container, Element, Event, container, layout, mouse, scrollable, Clipboard, Container, Element, Event,
Hasher, Layer, Layout, Length, Point, Rectangle, Scrollable, Size, Widget, Hasher, Layer, Layout, Length, Point, Rectangle, Scrollable, Size, Vector,
Widget,
}; };
use std::borrow::Cow; use std::borrow::Cow;
@ -8,6 +9,7 @@ pub struct Menu<'a, Message, Renderer: self::Renderer> {
container: Container<'a, Message, Renderer>, container: Container<'a, Message, Renderer>,
is_open: &'a mut bool, is_open: &'a mut bool,
width: u16, width: u16,
target_height: f32,
} }
#[derive(Default)] #[derive(Default)]
@ -38,6 +40,7 @@ where
options: impl Into<Cow<'a, [T]>>, options: impl Into<Cow<'a, [T]>>,
on_selected: Box<dyn Fn(T) -> Message>, on_selected: Box<dyn Fn(T) -> Message>,
width: u16, width: u16,
target_height: f32,
text_size: u16, text_size: u16,
padding: u16, padding: u16,
) -> Self ) -> Self
@ -60,6 +63,7 @@ where
container, container,
is_open: &mut state.is_open, is_open: &mut state.is_open,
width, width,
target_height,
} }
} }
} }
@ -75,15 +79,29 @@ where
bounds: Size, bounds: Size,
position: Point, position: Point,
) -> layout::Node { ) -> layout::Node {
let space_below = bounds.height - (position.y + self.target_height);
let space_above = position.y;
let limits = layout::Limits::new( let limits = layout::Limits::new(
Size::ZERO, Size::ZERO,
Size::new(bounds.width - position.x, bounds.height - position.y), Size::new(
bounds.width - position.x,
if space_below > space_above {
space_below
} else {
space_above
},
),
) )
.width(Length::Units(self.width)); .width(Length::Units(self.width));
let mut node = self.container.layout(renderer, &limits); let mut node = self.container.layout(renderer, &limits);
node.move_to(position); 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 node
} }

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
layer::{self, menu}, layer::{self, menu},
layout, mouse, scrollable, text, Clipboard, Element, Event, Hasher, Layout, layout, mouse, scrollable, text, Clipboard, Element, Event, Hasher, Layout,
Length, Overlay, Point, Rectangle, Size, Vector, Widget, Length, Overlay, Point, Rectangle, Size, Widget,
}; };
use std::borrow::Cow; use std::borrow::Cow;
@ -210,14 +210,16 @@ where
if is_open { if is_open {
if let Some(Internal { menu, on_selected }) = self.internal.take() { if let Some(Internal { menu, on_selected }) = self.internal.take() {
let bounds = layout.bounds();
Some(Overlay::new( Some(Overlay::new(
layout.position() layout.position(),
+ Vector::new(0.0, layout.bounds().height),
Box::new(layer::Menu::new( Box::new(layer::Menu::new(
menu, menu,
self.options.clone(), self.options.clone(),
on_selected, on_selected,
layout.bounds().width.round() as u16, bounds.width.round() as u16,
bounds.height,
self.text_size.unwrap_or(20), self.text_size.unwrap_or(20),
self.padding, self.padding,
)), )),