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

DisabledIf widget #1702

Merged
merged 14 commits into from
Apr 13, 2021
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,7 @@ Last release without a changelog :(
[#1691]: https://github.com/linebender/druid/pull/1691
[#1693]: https://github.com/linebender/druid/pull/1693
[#1695]: https://github.com/linebender/druid/pull/1695
[#1696]: https://github.com/linebender/druid/pull/1696
[#1698]: https://github.com/linebender/druid/pull/1698
[#1702]: https://github.com/linebender/druid/pull/1702

Expand Down
42 changes: 41 additions & 1 deletion druid/examples/disabled.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
use druid::widget::{Checkbox, CrossAxisAlignment, Flex, Label, Slider, Stepper, Switch, TextBox};
// Copyright 2020 The Druid Authors.
cmyr marked this conversation as resolved.
Show resolved Hide resolved
//
// 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.

//! An example showing the effect of the disabled state on focus-chain and the widgets.
//! When the disabled checkbox is clicked only the widgets not marked as disabled should
//! respond. Pressing Tab should only focus widgets not marked as disabled. If a widget
//! is focused while getting disabled it should resign the focus.

use druid::widget::{
Button, Checkbox, CrossAxisAlignment, Flex, Label, Slider, Stepper, Switch, TextBox,
};
use druid::{AppLauncher, Data, Lens, LocalizedString, UnitPoint, Widget, WidgetExt, WindowDesc};

#[derive(Clone, Data, Lens)]
Expand Down Expand Up @@ -69,6 +90,25 @@ fn main_widget() -> impl Widget<AppData> {
.disabled_if(|data, _| data.disabled),
))
.with_default_spacer()
.with_child(
Flex::row()
.with_child(
Button::new("-")
.on_click(|_, data: &mut f64, _| *data -= 1.0)
.disabled_if(|data, _| *data < 1.0),
)
.with_default_spacer()
.with_child(Label::dynamic(|data: &f64, _| data.to_string()))
.with_default_spacer()
.with_child(
Button::new("+")
.on_click(|_, data: &mut f64, _| *data += 1.0)
.disabled_if(|data, _| *data > 9.0),
)
.lens(AppData::value)
.disabled_if(|data: &AppData, _| data.disabled),
)
.with_default_spacer()
.with_default_spacer()
.with_default_spacer()
.with_child(Checkbox::new("disabled").lens(AppData::disabled))
Expand Down
23 changes: 22 additions & 1 deletion druid/src/widget/disable_if.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,38 @@
// Copyright 2020 The Druid Authors.
cmyr marked this conversation as resolved.
Show resolved Hide resolved
//
// 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.

use crate::{
cmyr marked this conversation as resolved.
Show resolved Hide resolved
BoxConstraints, Data, Env, Event, EventCtx, LayoutCtx, LifeCycle, LifeCycleCtx, PaintCtx,
Point, Size, UpdateCtx, Widget, WidgetPod,
};

/// A widget wrapper which disables the inner widget if the provided closure return true.
///
/// See [`is_disabled`] or [`set_disabled`] for more info about disabled state.
///
/// [`is_disabled`]: crate::EventCtx::is_disabled
/// [`set_disabled`]: crate::EventCtx::set_disabled
pub struct DisabledIf<T, W> {
inner: WidgetPod<T, W>,
xarvic marked this conversation as resolved.
Show resolved Hide resolved
disabled_if: Box<dyn Fn(&T, &Env) -> bool>,
}

impl<T: Data, W: Widget<T>> DisabledIf<T, W> {
/// Creates a new `DisabledIf` widget with the inner widget and the closure to decide if the
/// widget should be disabled.
/// widget should be [`disabled`].
///
/// [`disabled`]: crate::EventCtx::is_disabled
pub fn new(widget: W, disabled_if: impl Fn(&T, &Env) -> bool + 'static) -> Self {
DisabledIf {
inner: WidgetPod::new(widget),
Expand Down
10 changes: 5 additions & 5 deletions druid/src/widget/widget_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,13 +275,13 @@ pub trait WidgetExt<T: Data>: Widget<T> + Sized + 'static {
}

/// Wrap this widget in a [`DisabledIf`] widget.
/// The provided closure will determine if the widget is disabled.
///
/// See [`is_disabled`] or [`set_disabled`] for more info about the disabled state.
/// The provided closure will determine if the widget is disabled.
/// See [`is_disabled`] or [`set_disabled`] for more info about disabled state.
///
/// [`is_disabled`]: struct.EventCtx.html#method.is_disabled
/// [`set_disabled`]: struct.EventCtx.html#method.set_disabled
/// [`DisabledIf`]: widget/struct.DisabledIf.html
/// [`is_disabled`]: crate::EventCtx::is_disabled
/// [`set_disabled`]: crate::EventCtx::set_disabled
/// [`DisabledIf`]: crate::widget::DisabledIf
cmyr marked this conversation as resolved.
Show resolved Hide resolved
fn disabled_if(self, disabled_if: impl Fn(&T, &Env) -> bool + 'static) -> DisabledIf<T, Self> {
DisabledIf::new(self, disabled_if)
}
Expand Down