winio_ui_winui/widgets/
link_label.rs1use 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);