diff --git a/src/view/mod.rs b/src/view/mod.rs index 86c066d3a..9ad8c7270 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -21,6 +21,7 @@ mod text; // mod use_state; mod linear_layout; mod list; +mod switch; #[allow(clippy::module_inception)] mod view; @@ -29,4 +30,5 @@ pub use xilem_core::{Id, IdPath, VecSplice}; pub use button::button; pub use linear_layout::{h_stack, v_stack, LinearLayout}; pub use list::{list, List}; +pub use switch::switch; pub use view::{Adapt, AdaptState, Cx, Memoize, View, ViewMarker, ViewSequence}; diff --git a/src/view/switch.rs b/src/view/switch.rs new file mode 100644 index 000000000..009490383 --- /dev/null +++ b/src/view/switch.rs @@ -0,0 +1,81 @@ +// Copyright 2022 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. + +use std::any::Any; + +use crate::view::ViewMarker; +use crate::{view::Id, widget::ChangeFlags, MessageResult}; + +use super::{Cx, View}; + +pub struct Switch { + is_on: bool, + #[allow(clippy::type_complexity)] + callback: Box A + Send>, +} + +pub fn switch( + is_on: bool, + clicked: impl Fn(&mut T, bool) -> A + Send + 'static, +) -> Switch { + Switch::new(is_on, clicked) +} + +impl Switch { + pub fn new(is_on: bool, clicked: impl Fn(&mut T, bool) -> A + Send + 'static) -> Self { + Switch { + is_on, + callback: Box::new(clicked), + } + } +} + +impl ViewMarker for Switch {} + +impl View for Switch { + type State = (); + + type Element = crate::widget::Switch; + + fn build(&self, cx: &mut Cx) -> (crate::view::Id, Self::State, Self::Element) { + let (id, element) = + cx.with_new_id(|cx| crate::widget::Switch::new(cx.id_path(), self.is_on)); + (id, (), element) + } + + fn rebuild( + &self, + _cx: &mut Cx, + prev: &Self, + _id: &mut Id, + _state: &mut Self::State, + element: &mut Self::Element, + ) -> ChangeFlags { + if prev.is_on != self.is_on { + element.set_is_on(self.is_on) + } else { + ChangeFlags::default() + } + } + + fn message( + &self, + _id_path: &[Id], + _state: &mut Self::State, + _message: Box, + app_state: &mut T, + ) -> MessageResult { + MessageResult::Action((self.callback)(app_state, !self.is_on)) + } +}