Skip to content

Commit

Permalink
fix(core): 🐛 allow children to be hit outside the boundaries for non-…
Browse files Browse the repository at this point in the history
…fixed-size container
  • Loading branch information
M-Adoo authored and rchangelog[bot] committed Dec 22, 2024
1 parent e338610 commit a9d99a4
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Please only add new entries below the [Unreleased](#unreleased---releasedate) he
- **core**: Running an animation that is already in progress does not trigger a smooth transition. (#672 @M-Adoo)
- **core**: The framework incorrectly clamps the layout result of the render widget. (#672 @M-Adoo)
- **core**: Padding will not change the child's size; otherwise, child elements like `Icon` may not work correctly. (#674 @M-Adoo)
- **core**: Allow children to be hit outside their parent's boundaries for non-fixed-size containers. (#676 @M-Adoo)
- **painter**: Fixed text line height does not work correctly. (#674 @M-Adoo)
- **painter**: Fixed issue with text not being drawn at the middle baseline by default. (#674 @M-Adoo)

Expand Down
4 changes: 4 additions & 0 deletions core/src/builtin_widgets/constrained_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ impl WrapRender for ConstrainedBox {
let min = clamp.clamp(self.clamp.min);
host.perform_layout(BoxClamp { min, max }, ctx)
}

fn only_sized_by_parent(&self, _: &dyn Render) -> bool {
self.clamp.min == self.clamp.max
}
}

#[cfg(test)]
Expand Down
9 changes: 4 additions & 5 deletions core/src/context/widget_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use ribir_geom::{Point, Rect, Size};
use crate::{
query::QueryRef,
state::WriteRef,
widget::{BoxClamp, HitTest, WidgetTree},
widget::{BoxClamp, WidgetTree},
widget_tree::WidgetId,
window::Window,
};
Expand Down Expand Up @@ -228,11 +228,10 @@ pub(crate) use define_widget_context;
define_widget_context!(HitTestCtx);

impl HitTestCtx {
pub fn box_hit_test(&self, pos: Point) -> HitTest {
let is_hit = self
pub fn box_hit_test(&self, pos: Point) -> bool {
self
.box_rect()
.is_some_and(|rect| rect.contains(pos));
HitTest { hit: is_hit, can_hit_child: is_hit }
.is_some_and(|rect| rect.contains(pos))
}
}

Expand Down
21 changes: 21 additions & 0 deletions core/src/events/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -793,4 +793,25 @@ mod tests {
assert!(expect_hit.read().is_some());
assert_eq!(dispatcher.hit_widget(), *expect_hit.read());
}

#[test]
fn fix_over_container_hit() {
reset_test_env!();

let mut wnd = TestWindow::new_with_size(
mock_stack! {
@MockBox {
anchor: Anchor::left_top(100., 100.),
size: Size::new(100., 100.),
}
},
Size::new(500., 500.),
);
wnd.draw_frame();
let mut dispatcher = wnd.dispatcher.borrow_mut();
dispatcher.info.cursor_pos = Point::new(105., 105.);
let w = dispatcher.hit_widget();

assert_ne!(w.unwrap(), wnd.tree().root());
}
}
8 changes: 7 additions & 1 deletion core/src/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,13 @@ pub trait Render: 'static {

/// Verify if the provided position is within this widget and return whether
/// its child can be hit if the widget itself is not hit.
fn hit_test(&self, ctx: &HitTestCtx, pos: Point) -> HitTest { ctx.box_hit_test(pos) }
fn hit_test(&self, ctx: &HitTestCtx, pos: Point) -> HitTest {
let hit = ctx.box_hit_test(pos);
// If the widget is not solely sized by the parent, indicating it is not a
// fixed-size container, we permit the child to receive hits even if it
// extends beyond its parent boundaries.
HitTest { hit, can_hit_child: hit || !self.only_sized_by_parent() }
}

/// Return a transform to map the coordinate from its parent to this widget.
fn get_transform(&self) -> Option<Transform> { None }
Expand Down
9 changes: 2 additions & 7 deletions widgets/src/layout/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,11 @@ impl Render for Stack {
let mut size = ZERO_SIZE;
let (ctx, children) = ctx.split_children();
for c in children {
ctx.perform_child_layout(c, stack_clamp);
let rect = ctx.widget_box_rect(c).unwrap();
size = size.max(rect.max().to_vector().to_size());
let child_size = ctx.perform_child_layout(c, stack_clamp);
size = size.max(child_size);
}
clamp.clamp(size)
}

fn paint(&self, _: &mut PaintingCtx) {
// nothing to paint.
}
}

#[cfg(test)]
Expand Down

0 comments on commit a9d99a4

Please sign in to comment.