Skip to content

Commit

Permalink
Add the LifeCycle::Size event. (#953)
Browse files Browse the repository at this point in the history
  • Loading branch information
xStrom authored May 17, 2020
1 parent 70aba49 commit 7955f76
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ This means that druid no longer requires cairo on macOS and uses Core Graphics i
- `WidgetExt::debug_widget_id`, for displaying widget ids on hover. ([#876] by [@cmyr])
- `im` feature, with `Data` support for the [`im` crate](https://docs.rs/im/) collections. ([#924] by [@cmyr])
- `im::Vector` support for the `List` widget. ([#940] by [@xStrom])
- `LifeCycle::Size` event to inform widgets that their size changed. ([#953] by [@xStrom])

### Changed

Expand Down Expand Up @@ -194,6 +195,7 @@ This means that druid no longer requires cairo on macOS and uses Core Graphics i
[#942]: https://github.com/xi-editor/druid/pull/942
[#943]: https://github.com/xi-editor/druid/pull/943
[#951]: https://github.com/xi-editor/druid/pull/951
[#953]: https://github.com/xi-editor/druid/pull/953

## [0.5.0] - 2020-04-01

Expand Down
46 changes: 41 additions & 5 deletions druid/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,13 +188,37 @@ impl<T, W: Widget<T>> WidgetPod<T, W> {
self.state.id
}

/// Set layout rectangle.
/// Set the layout [`Rect`].
///
/// Intended to be called on child widget in container's `layout`
/// implementation.
/// A container widget should call the [`Widget::layout`] method on its children in
/// its own [`Widget::layout`] implementation, then possibly modify the returned [`Size`], and
/// finally call this `set_layout_rect` method on the child to set the final layout [`Rect`].
///
/// The child will receive the [`LifeCycle::Size`] event informing them of the final [`Size`].
///
/// [`Widget::layout`]: trait.Widget.html#tymethod.layout
/// [`Rect`]: struct.Rect.html
/// [`Size`]: struct.Size.html
/// [`LifeCycle::Size`]: enum.LifeCycle.html#variant.Size
pub fn set_layout_rect(&mut self, ctx: &mut LayoutCtx, data: &T, env: &Env, layout_rect: Rect) {
let mut needs_merge = false;

let old_size = self.state.layout_rect.map(|r| r.size());
let new_size = layout_rect.size();

self.state.layout_rect = Some(layout_rect);

if old_size.is_none() || old_size.unwrap() != new_size {
let mut child_ctx = LifeCycleCtx {
command_queue: ctx.command_queue,
base_state: &mut self.state,
window_id: ctx.window_id,
};
let size_event = LifeCycle::Size(new_size);
self.inner.lifecycle(&mut child_ctx, &size_event, data, env);
needs_merge = true;
}

if WidgetPod::set_hot_state(
&mut self.inner,
ctx.command_queue,
Expand All @@ -205,6 +229,10 @@ impl<T, W: Widget<T>> WidgetPod<T, W> {
data,
env,
) {
needs_merge = true;
}

if needs_merge {
ctx.base_state.merge_up(&self.state);
}
}
Expand All @@ -215,9 +243,12 @@ impl<T, W: Widget<T>> WidgetPod<T, W> {
self.layout_rect()
}

/// The layout rectangle.
/// Returns the layout [`Rect`].
///
/// This will be the same [`Rect`] that was set by [`set_layout_rect`].
///
/// This will be same value as set by `set_layout_rect`.
/// [`Rect`]: struct.Rect.html
/// [`set_layout_rect`]: #method.set_layout_rect
pub fn layout_rect(&self) -> Rect {
self.state.layout_rect.unwrap_or_default()
}
Expand Down Expand Up @@ -790,6 +821,11 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {

true
}
LifeCycle::Size(_) => {
// We are a descendant of a widget that received the Size event.
// This event was meant only for our parent, so don't recurse.
false
}
//NOTE: this is not sent here, but from the special set_hot_state method
LifeCycle::HotChanged(_) => false,
LifeCycle::FocusChanged(_) => {
Expand Down
8 changes: 8 additions & 0 deletions druid/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,14 @@ pub enum LifeCycle {
/// [`WidgetPod`]: struct.WidgetPod.html
/// [`LifeCycleCtx::register_for_focus`]: struct.LifeCycleCtx.html#method.register_for_focus
WidgetAdded,
/// Called when the size of the widget changes.
///
/// The [`Size`] is derived from the [`Rect`] that was set with [`WidgetPod::set_layout_rect`].
///
/// [`Size`]: struct.Size.html
/// [`Rect`]: struct.Rect.html
/// [`WidgetPod::set_layout_rect`]: struct.WidgetPod.html#method.set_layout_rect
Size(Size),
/// Called at the beginning of a new animation frame.
///
/// On the first frame when transitioning from idle to animating, `interval`
Expand Down

0 comments on commit 7955f76

Please sign in to comment.