#![feature(min_specialization)]
#![feature(type_alias_impl_trait)]
use frui::prelude::*;
mod misc;
use misc::{ChangesOnRebuild, SwitchGuard};
#[derive(InheritedWidget)]
struct InheritedSwitch<W: Widget> {
child: W,
}
impl<W: Widget> WidgetState for InheritedSwitch<W> {
type State = bool;
fn create_state<'a>(&'a self) -> Self::State {
false
}
}
impl<W: Widget> InheritedWidget for InheritedSwitch<W> {
fn child<'w>(&'w self) -> &'w Self::Widget<'w> {
&self.child
}
}
impl InheritedSwitch<()> {
pub fn of<'a, T>(ctx: BuildContext<'a, T>) -> SwitchGuard<'a> {
let state = ctx.depend_on_inherited_widget::<Self>().unwrap();
SwitchGuard::new(state)
}
}
#[derive(ViewWidget)]
struct InheritedSwitchDispatcher;
impl ViewWidget for InheritedSwitchDispatcher {
fn build<'w>(&'w self, ctx: BuildContext<'w, Self>) -> Self::Widget<'w> {
KeyboardEventDetector {
on_event: |_| InheritedSwitch::of(ctx).switch(),
child: (),
}
}
}
#[derive(ViewWidget)]
struct InheritedSwitchConsumer;
impl ViewWidget for InheritedSwitchConsumer {
fn build<'w>(&'w self, ctx: BuildContext<'w, Self>) -> Self::Widget<'w> {
Text::new(InheritedSwitch::of(ctx).to_string())
}
}
#[derive(ViewWidget)]
struct App;
impl ViewWidget for App {
fn build<'w>(&'w self, _: BuildContext<'w, Self>) -> Self::Widget<'w> {
Center::child(Column::builder().children((
Text::new(concat!(
"Following widget doesn't depend on inherited widget, ",
"so it should not be rebuilt (number should stay the same).",
)),
ChangesOnRebuild,
Text::new("\n"),
Text::new(concat!(
"Following widget depends on inherited widget, ",
"so its value should update when you press a key.",
)),
InheritedSwitchConsumer,
InheritedSwitchDispatcher,
)))
}
}
fn main() {
run_app(InheritedSwitch { child: App });
}
#[cfg(all(test, feature = "miri"))]
mod test {
use super::*;
use frui::{
app::runner::miri::MiriAppRunner,
druid_shell::{keyboard_types::Key, Modifiers},
};
#[test]
pub fn run_example_under_miri() {
let mut runner = MiriAppRunner::new(InheritedSwitch { child: App });
for _ in 0..4 {
runner.send_keyboard_event(KeyEvent::for_test(
Modifiers::default(),
Key::Character(" ".into()),
));
runner.update();
}
}
}