blocking_function/
blocking_function.rs1#![windows_subsystem = "windows"]
21
22use std::{thread, time};
23
24use druid::widget::prelude::*;
25use druid::widget::{Button, Either, Flex, Label, Spinner};
26use druid::{
27 AppDelegate, AppLauncher, Command, Data, DelegateCtx, ExtEventSink, Handled, Lens,
28 LocalizedString, Selector, Target, WidgetExt, WindowDesc,
29};
30
31const FINISH_SLOW_FUNCTION: Selector<u32> = Selector::new("finish_slow_function");
32
33#[derive(Clone, Default, Data, Lens)]
34struct AppState {
35 processing: bool,
36 value: u32,
37}
38
39fn ui_builder() -> impl Widget<AppState> {
40 let button = Button::new("Start slow increment")
41 .on_click(|ctx, data: &mut AppState, _env| {
42 data.processing = true;
43 wrapped_slow_function(ctx.get_external_handle(), data.value);
47 })
48 .padding(5.0);
49
50 let button_placeholder = Flex::column()
51 .with_child(Label::new(LocalizedString::new("Processing...")).padding(5.0))
52 .with_child(Spinner::new());
53
54 let text = LocalizedString::new("hello-counter")
57 .with_arg("count", |data: &AppState, _env| (data.value).into());
58 let label = Label::new(text).padding(5.0).center();
59
60 let either = Either::new(|data, _env| data.processing, button_placeholder, button);
61
62 Flex::column().with_child(label).with_child(either)
63}
64
65fn wrapped_slow_function(sink: ExtEventSink, number: u32) {
66 thread::spawn(move || {
67 let number = slow_function(number);
68 sink.submit_command(FINISH_SLOW_FUNCTION, number, Target::Auto)
72 .expect("command failed to submit");
73 });
74}
75
76fn slow_function(number: u32) -> u32 {
78 let a_while = time::Duration::from_millis(2000);
79 thread::sleep(a_while);
80 number + 1
81}
82
83struct Delegate;
84
85impl AppDelegate<AppState> for Delegate {
86 fn command(
87 &mut self,
88 _ctx: &mut DelegateCtx,
89 _target: Target,
90 cmd: &Command,
91 data: &mut AppState,
92 _env: &Env,
93 ) -> Handled {
94 if let Some(number) = cmd.get(FINISH_SLOW_FUNCTION) {
95 data.processing = false;
97 data.value = *number;
98 Handled::Yes
99 } else {
100 Handled::No
101 }
102 }
103}
104
105fn main() {
106 let main_window =
107 WindowDesc::new(ui_builder()).title(LocalizedString::new("Blocking functions"));
108 AppLauncher::with_window(main_window)
109 .delegate(Delegate {})
110 .log_to_console()
111 .launch(AppState::default())
112 .expect("launch failed");
113}