ferroui_dialogs/
about_ferro_dialog_xaml.rs1use ferroui_base::input::InputElementImpl;
4use ferroui_base::interactivity::{IRoutedEventArgs, InteractiveImpl, RoutedEventArgs};
5use ferroui_base::layout::LayoutableImpl;
6use ferroui_base::threading::Dispatcher;
7use ferroui_base::utilities::{DateTime, Uri};
8use ferroui_base::{
9 ferro_class, ferro_class_info, ferro_impl_classes, instantiate, BoxedValue, FerroObjectImpl, Ref,
10 StyledElementImpl, VisualImpl,
11};
12use ferroui_controls::platform::PlatformManager;
13use ferroui_controls::primitives::TemplatedControlImpl;
14use ferroui_controls::{
15 ContentControlImpl, Control, ControlImpl, TopLevelImpl, Window, WindowBaseImpl, WindowImpl,
16};
17use std::rc::Rc;
18use std::sync::LazyLock;
19
20const PROJECT_URL: &str = "https://github.com/wieslawsoltes/FerroUI";
22
23static S_VERSION: LazyLock<[u32; 4]> = LazyLock::new(|| {
26 let mut components = [0u32; 4];
27 let numeric = env!("CARGO_PKG_VERSION").split(['-', '+']).next().unwrap_or_default();
28 for (component, text) in components.iter_mut().zip(numeric.split('.')) {
29 *component = text.parse().unwrap_or(0);
30 }
31 components
32});
33
34#[repr(C)]
37pub struct AboutFerroDialog {
38 base: Window,
39}
40
41ferro_class!(AboutFerroDialog: Window);
42ferro_impl_classes!(
43 AboutFerroDialog: FerroObjectImpl,
44 StyledElementImpl,
45 VisualImpl,
46 LayoutableImpl,
47 InteractiveImpl,
48 InputElementImpl,
49 ControlImpl,
50 TemplatedControlImpl,
51 ContentControlImpl,
52 TopLevelImpl,
53 WindowBaseImpl,
54 WindowImpl
55);
56ferro_class_info!(AboutFerroDialog {
57 new: AboutFerroDialog::new,
58 markup: {
59 static_properties: [
60 Version: String { get: AboutFerroDialog::version },
61 IsDevelopmentBuild: bool { get: AboutFerroDialog::is_development_build },
62 Copyright: String { get: AboutFerroDialog::copyright },
63 ],
64 methods: [
65 fn Button_OnClick(Option<BoxedValue>, Rc<dyn IRoutedEventArgs>) =>
66 |this: &Ref<AboutFerroDialog>, sender: Option<BoxedValue>, args: Rc<dyn IRoutedEventArgs>| {
67 this.button_on_click(&sender, args.as_routed_event_args())
68 },
69 ],
70 },
71});
72
73impl AboutFerroDialog {
74 pub const DOCUMENT_URI: &'static str = "ferres://FerroUI.Dialogs/AboutFerroDialog.xaml";
76
77 pub fn construct() -> Self {
78 Self { base: Window::construct(PlatformManager::create_window()) }
79 }
80
81 pub fn new() -> Ref<Self> {
90 crate::register_types();
91 let this = instantiate(Self::construct());
92 if let Err(error) = crate::compiled_about_ferro_dialog::populate(None, &this) {
93 panic!("{}: {error}", Self::DOCUMENT_URI);
94 }
95 this.set_data_context(Some(Control::boxed(this.clone())));
96 this
97 }
98
99 pub fn version() -> String {
101 format!("v{}.{}", S_VERSION[0], S_VERSION[1])
102 }
103
104 pub fn is_development_build() -> bool {
106 S_VERSION[3] == 999
107 }
108
109 pub fn copyright() -> String {
111 format!("© {} The FerroUI Project", DateTime::now().year())
112 }
113
114 fn button_on_click(&self, _sender: &Option<BoxedValue>, _e: &RoutedEventArgs) {
115 let url = Uri::absolute(PROJECT_URL).expect("the project address is an absolute URI");
116 let launcher = self.launcher();
117 Dispatcher::ui_thread().invoke_async_task_local(move || async move {
118 launcher.launch_uri_async(&url).await;
119 });
120 }
121}