Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "handled" state to event #70

Merged
merged 1 commit into from
Jul 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ pub struct EventCtx<'a> {
window: &'a WindowHandle,
base_state: &'a mut BaseState,
had_active: bool,
is_handled: bool,
}

pub struct UpdateCtx {
Expand Down Expand Up @@ -226,7 +227,7 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {
data: &mut T,
env: &Env,
) -> Option<Action> {
if !event.recurse() {
if ctx.is_handled || !event.recurse() {
// This function is called by containers to propagate an event from
// containers to children. Non-recurse events will be invoked directly
// from other points in the library.
Expand All @@ -237,6 +238,7 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {
window: &ctx.window,
base_state: &mut self.state,
had_active,
is_handled: false,
};
let rect = child_ctx.base_state.layout_rect;
// Note: could also represent this as `Option<Event>`.
Expand Down Expand Up @@ -283,6 +285,7 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {
ctx.base_state.needs_inval |= child_ctx.base_state.needs_inval;
ctx.base_state.is_hot |= child_ctx.base_state.is_hot;
ctx.base_state.has_active |= child_ctx.base_state.has_active;
ctx.is_handled |= child_ctx.is_handled;
action
}

Expand Down Expand Up @@ -349,6 +352,7 @@ impl<T: Data> UiState<T> {
window: &self.handle,
base_state: &mut base_state,
had_active: self.root.state.has_active,
is_handled: false,
};
let env = self.root_env();
let action = self.root.event(&event, &mut ctx, &mut self.data, &env);
Expand All @@ -360,7 +364,7 @@ impl<T: Data> UiState<T> {
self.handle.invalidate();
}
// TODO: process actions
action.is_some()
ctx.is_handled()
}

fn paint(&mut self, piet: &mut Piet) -> bool {
Expand Down Expand Up @@ -526,6 +530,17 @@ impl<'a> EventCtx<'a> {
pub fn window(&self) -> &WindowHandle {
&self.window
}

/// Set the event as "handled", which stops its propagation to other
/// widgets.
pub fn set_handled(&mut self) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an asymmetry here between set_handled and set_active. I prefer this to not take an argument, but maybe set_active doesn't need to either?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, set_active can definitely take false, for example on mouse-up in a button. I don't think it makes any sense to unset handled. Open to ideas of improving naming/docs tho.

self.is_handled = true;
}

/// Determine whether the event has been handled by some other widget.
pub fn is_handled(&self) -> bool {
self.is_handled
}
}

impl UpdateCtx {
Expand Down
17 changes: 10 additions & 7 deletions src/widget/scroll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,21 @@ impl<T: Data> Widget<T> for Scroll<T> {
) -> Option<Action> {
let size = ctx.base_state.size();
let viewport = Rect::from_origin_size(Point::ORIGIN, size);
if let Event::Wheel(wheel) = event {
if self.scroll(wheel.delta, size) {
ctx.invalidate();
}
}
// TODO: cancellation logic
let child_event = event.transform_scroll(self.scroll_offset, viewport);
if let Some(child_event) = child_event {
let action = if let Some(child_event) = child_event {
self.child.event(&child_event, ctx, data, env)
} else {
None
};
if !ctx.is_handled() {
if let Event::Wheel(wheel) = event {
if self.scroll(wheel.delta, size) {
ctx.invalidate();
ctx.set_handled();
}
}
}
action
}

fn update(&mut self, ctx: &mut UpdateCtx, _old_data: Option<&T>, data: &T, env: &Env) {
Expand Down