Skip to main content

ferroui_dialogs/
about_ferro_dialog_xaml.rs

1//! The class of the document `AboutFerroDialog.xaml`.
2
3use 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
20/// The address the button of the dialog opens.
21const PROJECT_URL: &str = "https://github.com/wieslawsoltes/FerroUI";
22
23/// The version of the library (the assembly version of the original): the
24/// four components of a version, missing ones zero.
25static 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/// The about dialog of the framework: the logo, the version and a link to
35/// the project.
36#[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    /// The URI of the document of the class.
75    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    /// Creates the dialog and populates it from its document
82    /// (`InitializeComponent()`: the compiled markup of the document, which
83    /// the build of the crate generates).
84    ///
85    /// # Panics
86    /// Panics when no windowing platform is registered, and when the
87    /// document fails to load (an exception of the constructor in the
88    /// managed original).
89    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    /// The version of the library: `v` and the major and minor versions.
100    pub fn version() -> String {
101        format!("v{}.{}", S_VERSION[0], S_VERSION[1])
102    }
103
104    /// Whether the library is a development build (revision 999).
105    pub fn is_development_build() -> bool {
106        S_VERSION[3] == 999
107    }
108
109    /// The copyright line, with the current year.
110    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}