Skip to content

Commit

Permalink
Merge pull request #164 from latidoremi/submenu_offset
Browse files Browse the repository at this point in the history
Submenu offset
  • Loading branch information
Andrew Wheeler(Genusis) authored Aug 7, 2023
2 parents 1165bfe + 020b9e0 commit 41754f2
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 17 deletions.
2 changes: 2 additions & 0 deletions examples/menu/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ impl Application for App {
}
.spacing(4.0)
.bounds_expand(30)
.main_offset(13)
.cross_offset(16)
.path_highlight(Some(PathHighlight::MenuActive))
.close_condition(CloseCondition {
leave: true,
Expand Down
20 changes: 20 additions & 0 deletions src/native/menu/menu_bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ where
spacing: f32,
padding: Padding,
bounds_expand: u16,
main_offset: i32,
cross_offset: i32,
close_condition: CloseCondition,
item_width: ItemWidth,
item_height: ItemHeight,
Expand All @@ -89,6 +91,8 @@ where
spacing: 0.0,
padding: Padding::ZERO,
bounds_expand: 15,
main_offset: 0,
cross_offset: 0,
close_condition: CloseCondition {
leave: true,
click_outside: true,
Expand Down Expand Up @@ -134,6 +138,20 @@ where
self
}

/// Moves all the menus in the vertical open direction
#[must_use]
pub fn main_offset(mut self, value: i32) -> Self {
self.main_offset = value;
self
}

/// Moves each menu in the horizontal open direction
#[must_use]
pub fn cross_offset(mut self, value: i32) -> Self {
self.cross_offset = value;
self
}

/// Sets the [`Padding`] of the [`MenuBar`]
#[must_use]
pub fn padding<P: Into<Padding>>(mut self, padding: P) -> Self {
Expand Down Expand Up @@ -387,6 +405,8 @@ where
item_width: self.item_width,
item_height: self.item_height,
bar_bounds: layout.bounds(),
main_offset: self.main_offset,
cross_offset: self.cross_offset,
root_bounds_list: layout.children().map(|lo| lo.bounds()).collect(),
path_highlight: self.path_highlight,
style: &self.style,
Expand Down
73 changes: 56 additions & 17 deletions src/native/menu/menu_inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,24 @@ struct Aod {
// default direction
horizontal_direction: Direction,
vertical_direction: Direction,

// Offset of the child in the default direction
horizontal_offset: f32,
vertical_offset: f32,
}
impl Aod {
/// Returns child position and offset position
#[allow(clippy::too_many_arguments)]
fn adaptive(
parent_pos: f32,
parent_size: f32,
child_size: f32,
max_size: f32,
offset: f32,
on: bool,
overlap: bool,
direction: Direction,
) -> f32 {
) -> (f32, f32) {
/*
Imagine there're two sticks, parent and child
parent: o-----o
Expand Down Expand Up @@ -139,16 +146,16 @@ impl Aod {
if overlap {
let overshoot = child_size - parent_size;
if on && space_negative > space_positive && overshoot > space_positive {
parent_pos - overshoot
(parent_pos - overshoot, parent_pos - overshoot)
} else {
parent_pos
(parent_pos, parent_pos)
}
} else {
let overshoot = child_size;
let overshoot = child_size + offset;
if on && space_negative > space_positive && overshoot > space_positive {
parent_pos - overshoot
(parent_pos - overshoot, parent_pos - offset)
} else {
parent_pos + parent_size
(parent_pos + parent_size + offset, parent_pos + parent_size)
}
}
}
Expand All @@ -159,43 +166,51 @@ impl Aod {
if overlap {
let overshoot = child_size - parent_size;
if on && space_negative > space_positive && overshoot > space_positive {
parent_pos
(parent_pos, parent_pos)
} else {
parent_pos - overshoot
(parent_pos - overshoot, parent_pos - overshoot)
}
} else {
let overshoot = child_size;
let overshoot = child_size + offset;
if on && space_negative > space_positive && overshoot > space_positive {
parent_pos + parent_size
(parent_pos + parent_size + offset, parent_pos + parent_size)
} else {
parent_pos - overshoot
(parent_pos - overshoot, parent_pos - offset)
}
}
}
}
}

fn point(&self, parent_bounds: Rectangle, children_size: Size, viewport_size: Size) -> Point {
let x = Self::adaptive(
/// Returns child position and offset position
fn resolve(
&self,
parent_bounds: Rectangle,
children_size: Size,
viewport_size: Size,
) -> (Point, Point) {
let (x, ox) = Self::adaptive(
parent_bounds.x,
parent_bounds.width,
children_size.width,
viewport_size.width,
self.horizontal_offset,
self.horizontal,
self.horizontal_overlap,
self.horizontal_direction,
);
let y = Self::adaptive(
let (y, oy) = Self::adaptive(
parent_bounds.y,
parent_bounds.height,
children_size.height,
viewport_size.height,
self.vertical_offset,
self.vertical,
self.vertical_overlap,
self.vertical_direction,
);

[x, y].into()
([x, y].into(), [ox, oy].into())
}
}

Expand All @@ -219,6 +234,7 @@ struct MenuBounds {
children_bounds: Rectangle,
parent_bounds: Rectangle,
check_bounds: Rectangle,
offset_bounds: Rectangle,
}
impl MenuBounds {
#[allow(clippy::too_many_arguments)]
Expand All @@ -243,8 +259,19 @@ impl MenuBounds {
let view_parent_bounds = parent_bounds + overlay_offset;

// overlay space children position
let children_position =
aod.point(view_parent_bounds, children_size, viewport_size) - overlay_offset;
let (children_position, offset_position) = {
let (cp, op) = aod.resolve(view_parent_bounds, children_size, viewport_size);
(cp - overlay_offset, op - overlay_offset)
};

// calc offset bounds
let delta = children_position - offset_position;
let offset_size = if delta.x.abs() > delta.y.abs() {
Size::new(delta.x, children_size.height)
} else {
Size::new(children_size.width, delta.y)
};
let offset_bounds = Rectangle::new(offset_position, offset_size);

let children_bounds = Rectangle::new(children_position, children_size);
let check_bounds = pad_rectangle(children_bounds, [bounds_expand; 4].into());
Expand All @@ -255,6 +282,7 @@ impl MenuBounds {
children_bounds,
parent_bounds,
check_bounds,
offset_bounds,
}
}
}
Expand Down Expand Up @@ -409,6 +437,8 @@ where
pub(super) item_width: ItemWidth,
pub(super) item_height: ItemHeight,
pub(super) bar_bounds: Rectangle,
pub(super) main_offset: i32,
pub(super) cross_offset: i32,
pub(super) root_bounds_list: Vec<Rectangle>,
pub(super) path_highlight: Option<PathHighlight>,
pub(super) style: &'b <Renderer::Theme as StyleSheet>::Style,
Expand Down Expand Up @@ -479,6 +509,7 @@ where
viewport_size,
overlay_offset,
self.bar_bounds,
self.main_offset as f32,
);

match event {
Expand All @@ -504,6 +535,7 @@ where
overlay_offset,
view_cursor,
overlay_cursor,
self.cross_offset as f32,
)
.merge(menu_status)
}
Expand Down Expand Up @@ -677,6 +709,7 @@ fn init_root_menu<Message, Renderer>(
viewport_size: Size,
overlay_offset: Vector,
bar_bounds: Rectangle,
main_offset: f32,
) where
Renderer: renderer::Renderer,
Renderer::Theme: StyleSheet,
Expand Down Expand Up @@ -713,6 +746,8 @@ fn init_root_menu<Message, Renderer>(
vertical_overlap: false,
horizontal_direction: state.horizontal_direction,
vertical_direction: state.vertical_direction,
horizontal_offset: 0.0,
vertical_offset: main_offset,
};

let menu_bounds = MenuBounds::new(
Expand Down Expand Up @@ -805,6 +840,7 @@ fn process_overlay_events<Message, Renderer>(
overlay_offset: Vector,
view_cursor: Cursor,
overlay_cursor: Point,
cross_offset: f32,
) -> event::Status
where
Renderer: renderer::Renderer,
Expand Down Expand Up @@ -853,6 +889,7 @@ where

if mb.parent_bounds.contains(overlay_cursor)
|| mb.children_bounds.contains(overlay_cursor)
|| mb.offset_bounds.contains(overlay_cursor)
|| (mb.check_bounds.contains(overlay_cursor)
&& prev_bounds.iter().all(|pvb| !pvb.contains(overlay_cursor)))
{
Expand Down Expand Up @@ -963,6 +1000,8 @@ where
vertical_overlap: true,
horizontal_direction: state.horizontal_direction,
vertical_direction: state.vertical_direction,
horizontal_offset: cross_offset,
vertical_offset: 0.0,
};

state.menu_states.push(MenuState {
Expand Down

0 comments on commit 41754f2

Please sign in to comment.