Skip to main content

winio_ui_winui/widgets/
link_label.rs

1use std::rc::Rc;
2
3use compio_log::info;
4use inherit_methods_macro::inherit_methods;
5use send_wrapper::SendWrapper;
6use windows::{
7    Foundation::Uri,
8    core::{HSTRING, Interface},
9};
10use winio_callback::Callback;
11use winio_handle::AsContainer;
12use winio_primitive::{Point, Size};
13use winui3::Microsoft::UI::Xaml::{Controls as MUXC, RoutedEventHandler};
14
15use crate::{GlobalRuntime, Result, Widget};
16
17#[derive(Debug)]
18pub struct LinkLabel {
19    on_click: SendWrapper<Rc<Callback>>,
20    handle: Widget,
21    button: MUXC::HyperlinkButton,
22    text: MUXC::TextBlock,
23}
24
25#[inherit_methods(from = "self.handle")]
26impl LinkLabel {
27    pub fn new(parent: impl AsContainer) -> Result<Self> {
28        let button = MUXC::HyperlinkButton::new()?;
29        let on_click = SendWrapper::new(Rc::new(Callback::new()));
30        {
31            let on_click = on_click.clone();
32            button.Click(&RoutedEventHandler::new(move |sender, _| {
33                let button = sender.ok()?.cast::<MUXC::HyperlinkButton>()?;
34                let uri = button.NavigateUri();
35                if let Ok(_uri) = uri {
36                    info!("Opening link: {}", _uri.ToString()?.to_string_lossy());
37                } else {
38                    on_click.signal::<GlobalRuntime>(());
39                }
40                Ok(())
41            }))?;
42        }
43        let text = MUXC::TextBlock::new()?;
44        button.SetContent(&text)?;
45        Ok(Self {
46            on_click,
47            handle: Widget::new(parent, button.cast()?)?,
48            button,
49            text,
50        })
51    }
52
53    pub fn is_visible(&self) -> Result<bool>;
54
55    pub fn set_visible(&mut self, v: bool) -> Result<()>;
56
57    pub fn is_enabled(&self) -> Result<bool>;
58
59    pub fn set_enabled(&mut self, v: bool) -> Result<()>;
60
61    pub fn preferred_size(&self) -> Result<Size>;
62
63    pub fn loc(&self) -> Result<Point>;
64
65    pub fn set_loc(&mut self, p: Point) -> Result<()>;
66
67    pub fn size(&self) -> Result<Size>;
68
69    pub fn set_size(&mut self, v: Size) -> Result<()>;
70
71    pub fn tooltip(&self) -> Result<String>;
72
73    pub fn set_tooltip(&mut self, s: impl AsRef<str>) -> Result<()>;
74
75    pub fn text(&self) -> Result<String> {
76        Ok(self.text.Text()?.to_string_lossy())
77    }
78
79    pub fn set_text(&mut self, s: impl AsRef<str>) -> Result<()> {
80        self.text.SetText(&HSTRING::from(s.as_ref()))?;
81        Ok(())
82    }
83
84    pub fn uri(&self) -> Result<String> {
85        if let Ok(uri) = self.button.NavigateUri() {
86            Ok(uri.ToString()?.to_string_lossy())
87        } else {
88            Ok(String::new())
89        }
90    }
91
92    pub fn set_uri(&mut self, s: impl AsRef<str>) -> Result<()> {
93        let s = s.as_ref();
94        if s.is_empty() {
95            self.button.SetNavigateUri(None)?;
96        } else {
97            self.button
98                .SetNavigateUri(&Uri::CreateUri(&HSTRING::from(s))?)?;
99        }
100        Ok(())
101    }
102
103    pub async fn wait_click(&self) {
104        self.on_click.wait().await;
105    }
106}
107
108winio_handle::impl_as_widget!(LinkLabel, handle);