ferroui_dialogs/
managed_file_chooser_overwrite_prompt.rs1use ferroui_base::input::InputElementImpl;
2use ferroui_base::interactivity::InteractiveImpl;
3use ferroui_base::layout::LayoutableImpl;
4use ferroui_base::reactive::{Disposable, IDisposable};
5use ferroui_base::utilities::HandlerList;
6use ferroui_base::{
7 ferro_class, ferro_class_info, ferro_impl_classes, ferro_properties, ferro_property, instantiate, DirectProperty,
8 FerroObjectImpl, FerroProperty, Ref, StyledElementImpl, VisualImpl,
9};
10use ferroui_controls::primitives::{TemplatedControl, TemplatedControlImpl};
11use ferroui_controls::ControlImpl;
12use std::cell::RefCell;
13use std::rc::Rc;
14
15#[repr(C)]
19pub struct ManagedFileChooserOverwritePrompt {
20 base: TemplatedControl,
21 result: Rc<HandlerList<dyn Fn(bool)>>,
22 file_name: RefCell<String>,
23}
24
25ferro_class!(ManagedFileChooserOverwritePrompt: TemplatedControl);
26ferro_impl_classes!(
27 ManagedFileChooserOverwritePrompt: FerroObjectImpl,
28 StyledElementImpl,
29 VisualImpl,
30 LayoutableImpl,
31 InteractiveImpl,
32 InputElementImpl,
33 ControlImpl,
34 TemplatedControlImpl
35);
36ferro_class_info!(ManagedFileChooserOverwritePrompt {
37 new: ManagedFileChooserOverwritePrompt::new,
38 markup: {
39 methods: [
40 fn Confirm() => ManagedFileChooserOverwritePrompt::confirm,
41 fn Cancel() => ManagedFileChooserOverwritePrompt::cancel,
42 ],
43 },
44});
45
46ferro_properties! { impl ManagedFileChooserOverwritePrompt {
47 ferro_property!(
48 pub fn file_name_property() -> DirectProperty<ManagedFileChooserOverwritePrompt, String> {
50 FerroProperty::register_direct::<ManagedFileChooserOverwritePrompt, _>(
51 "FileName",
52 |o| o.file_name(),
53 Some(|o, v| o.set_file_name(v)),
54 String::new(),
55 )
56 }
57 );
58} }
59
60impl ManagedFileChooserOverwritePrompt {
61 pub fn construct() -> Self {
62 Self { base: TemplatedControl::construct(), result: Rc::new(HandlerList::new()), file_name: RefCell::new(String::new()) }
63 }
64
65 pub fn new() -> Ref<Self> {
66 instantiate(Self::construct())
67 }
68
69 pub fn result(&self, handler: impl Fn(bool) + 'static) -> Rc<dyn IDisposable> {
71 let token = self.result.add(Rc::new(handler));
72 let handlers = self.result.clone();
73 Disposable::create(move || {
74 handlers.remove(token);
75 })
76 }
77
78 fn raise_result(&self, value: bool) {
79 for (_, handler) in self.result.snapshot().iter() {
80 handler(value);
81 }
82 }
83
84 pub fn file_name(&self) -> String {
86 self.file_name.borrow().clone()
87 }
88
89 pub fn set_file_name(&self, value: String) {
90 self.set_and_raise(Self::file_name_property(), &self.file_name, value);
91 }
92
93 pub fn confirm(&self) {
95 self.raise_result(true);
96 }
97
98 pub fn cancel(&self) {
100 self.raise_result(false);
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
108 use std::cell::RefCell;
109
110 #[test]
111 fn confirm_and_cancel_raise_the_result() {
112 let prompt = ManagedFileChooserOverwritePrompt::new();
113 let results = Rc::new(RefCell::new(Vec::new()));
114 let sink = results.clone();
115 let subscription = prompt.result(move |result| sink.borrow_mut().push(result));
116
117 prompt.confirm();
118 prompt.cancel();
119 subscription.dispose();
120 prompt.confirm();
121
122 assert_eq!(vec![true, false], *results.borrow());
123 }
124
125 #[test]
126 fn file_name_is_a_direct_property() {
127 let prompt = ManagedFileChooserOverwritePrompt::new();
128 assert_eq!("", prompt.file_name());
129
130 prompt.set_file_name("a.txt".to_string());
131
132 assert_eq!("a.txt", prompt.get_direct_value(ManagedFileChooserOverwritePrompt::file_name_property()));
133 }
134}