Skip to content

Commit

Permalink
adding added controller widget (#1485)
Browse files Browse the repository at this point in the history
* adding added controller widget

* updating docs to use linking by name for intra doc links

* adding added controller widget

* updating docs to use linking by name for intra doc links

* making docs more concise

Co-authored-by: Colin Rofls <[email protected]>

* updating some formatting on comment

Co-authored-by: Colin Rofls <[email protected]>

* Added controller will now take a mut reference to child

* updating on added function signature

Co-authored-by: lazypassion <[email protected]>
Co-authored-by: Colin Rofls <[email protected]>
Co-authored-by: Richard Dodd (dodj) <[email protected]>
  • Loading branch information
4 people authored Jan 8, 2021
1 parent 497be22 commit 78e1570
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 2 deletions.
62 changes: 62 additions & 0 deletions druid/src/widget/added.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2020 The Druid Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! A [`Controller`] widget that responds to [`LifeCycle::WidgetAdded`] event.
//!
//! [`Controller`]: crate::widget::Controller
//! [`LifeCycle::WidgetAdded`]: crate::LifeCycle::WidgetAdded
use crate::widget::Controller;
use crate::{Data, Env, LifeCycleCtx, Widget};

/// This [`Controller`] widget responds to [`LifeCycle::WidgetAdded`] event
/// with the provided closure. Pass this and a child widget to [`ControllerHost`]
/// to respond to the event when the child widget is added to the widget tree.
/// This is also available, for convenience, as an `on_added` method
/// via [`WidgetExt`].
///
/// [`Controller`]: crate::widget::Controller
/// [`ControllerHost`]: crate::widget::ControllerHost
/// [`WidgetExt`]: crate::widget::WidgetExt
/// [`LifeCycle::WidgetAdded`]: crate::LifeCycle::WidgetAdded
pub struct Added<T, W> {
/// A closure that will be invoked when the child widget is added
/// to the widget tree
action: Box<dyn Fn(&mut W, &mut LifeCycleCtx, &T, &Env)>,
}

impl<T: Data, W: Widget<T>> Added<T, W> {
/// Create a new [`Controller`] widget to respond to widget added to tree event.
pub fn new(action: impl Fn(&mut W, &mut LifeCycleCtx, &T, &Env) + 'static) -> Self {
Self {
action: Box::new(action),
}
}
}

impl<T: Data, W: Widget<T>> Controller<T, W> for Added<T, W> {
fn lifecycle(
&mut self,
child: &mut W,
ctx: &mut LifeCycleCtx,
event: &crate::LifeCycle,
data: &T,
env: &Env,
) {
if let crate::LifeCycle::WidgetAdded = event {
(self.action)(child, ctx, data, env);
}
child.lifecycle(ctx, event, data, env)
}
}
2 changes: 2 additions & 0 deletions druid/src/widget/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#[macro_use]
mod widget_wrapper;

mod added;
mod align;
mod button;
mod checkbox;
Expand Down Expand Up @@ -59,6 +60,7 @@ mod widget;
mod widget_ext;

pub use self::image::Image;
pub use added::Added;
pub use align::Align;
pub use button::Button;
pub use checkbox::Checkbox;
Expand Down
21 changes: 19 additions & 2 deletions druid/src/widget/widget_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
use super::invalidation::DebugInvalidation;
use super::{
Align, BackgroundBrush, Click, Container, Controller, ControllerHost, EnvScope,
Added, Align, BackgroundBrush, Click, Container, Controller, ControllerHost, EnvScope,
IdentityWrapper, LensWrap, Padding, Parse, SizedBox, WidgetId,
};
use crate::{Color, Data, Env, EventCtx, Insets, KeyOrValue, Lens, UnitPoint, Widget};
use crate::{
Color, Data, Env, EventCtx, Insets, KeyOrValue, Lens, LifeCycleCtx, UnitPoint, Widget,
};

/// A trait that provides extra methods for combining `Widget`s.
pub trait WidgetExt<T: Data>: Widget<T> + Sized + 'static {
Expand Down Expand Up @@ -159,6 +161,21 @@ pub trait WidgetExt<T: Data>: Widget<T> + Sized + 'static {
ControllerHost::new(self, controller)
}

/// Provide a closure that will be called when this widget is added to the widget tree.
///
/// You can use this to perform any initial setup.
///
/// This is equivalent to handling the [`LifeCycle::WidgetAdded`] event in a
/// custom [`Controller`].
///
/// [`LifeCycle::WidgetAdded`]: crate::LifeCycle::WidgetAdded
fn on_added(
self,
f: impl Fn(&mut Self, &mut LifeCycleCtx, &T, &Env) + 'static,
) -> ControllerHost<Self, Added<T, Self>> {
ControllerHost::new(self, Added::new(f))
}

/// Control the events of this widget with a [`Click`] widget. The closure
/// provided will be called when the widget is clicked with the left mouse
/// button.
Expand Down

0 comments on commit 78e1570

Please sign in to comment.