pub struct Ui { /* private fields */ }Expand description
Proof that the current thread is set up for glasskit windows.
Create it once, on the thread that shows the windows, and give it to EventLoop::new,
ChoicePopup::new, and Dialog::new. Each of them keeps a copy, so the setup stays
while any window exists. Ui is not Send: windows must stay on the thread that made
them, and the compiler enforces it.
Ui::new does this setup for the process and the thread:
- It makes the process aware of the DPI of each monitor (per-monitor v2), unless the application manifest or an earlier call has set the DPI awareness.
- It starts the Windows Runtime on the thread (single-threaded apartment).
- It loads the standard common controls.
- It creates the dispatcher queue that the popup animations need.
Implementations§
Source§impl Ui
impl Ui
Sourcepub fn new() -> Result<Self>
pub fn new() -> Result<Self>
Set up the current thread, or get the setup that exists on it.
Examples found in repository?
examples/gallery.rs (line 46)
40fn main() -> glasskit::Result<()> {
41 let kind = std::env::args().nth(1).unwrap_or_default();
42 let Some(prompt) = prompt(&kind) else {
43 println!("kinds: {}", KINDS.join(", "));
44 return Ok(());
45 };
46 let ui = Ui::new()?;
47 let mut first = ChoicePopup::new(&ui, Placement::default())?;
48 if kind == "stack" {
49 first.show(&Prompt::new("A first question?", ["Yes", "No"]))?;
50 }
51 let mut popup = ChoicePopup::new(&ui, Placement::default())?;
52 println!("{:?}", popup.ask(&prompt)?.response);
53 Ok(())
54}More examples
examples/quiz.rs (line 22)
21fn main() -> glasskit::Result<()> {
22 let ui = Ui::new()?;
23 let mut events = EventLoop::new(&ui)?;
24 let size = Icon::tray_size();
25 let icon = Icon::from_argb(size, vec![0xFF2E_86DE; (size * size) as usize])?;
26 let mut tray = Tray::new(&events, "Quiz", &icon)?;
27 tray.set_menu(&[
28 MenuItem::command(Command::AskNow, "Ask now"),
29 MenuItem::Separator,
30 MenuItem::Quit("Quit".into()),
31 ]);
32 let mut popup = ChoicePopup::new(&ui, Placement::default())?;
33 let mut next = SystemTime::now() + Duration::from_secs(60);
34 loop {
35 match events.next(Some(next))? {
36 Event::Quit => return Ok(()),
37 Event::Deadline | Event::Command(Command::AskNow) => {
38 next = SystemTime::now() + Duration::from_secs(60);
39 if !popup.is_showing() {
40 let prompt = Prompt::new("What is 2 + 2?", ["3", "4", "5"])
41 .marks(|clicked| answer_marks(clicked, 1))
42 .auto_dismiss(Some(Duration::from_secs(30)));
43 popup.show(&prompt)?;
44 }
45 }
46 Event::Popup(id) if id == popup.id() => {
47 if let Some(reply) = popup.take_reply() {
48 println!("{:?}", reply.response);
49 }
50 }
51 _ => {}
52 }
53 }
54}examples/dialog.rs (line 13)
12fn main() -> glasskit::Result<()> {
13 let ui = Ui::new()?;
14 let (width, height) = (420, 186);
15 let mut d = Dialog::new(&ui, "Profile", width, height)?;
16 let mut rows = Column::new(Bounds::new(0, 0, width, height).inset(16), 10);
17
18 let field = |row: Bounds| row.columns([Size::Fixed(110), Size::Fill(1)], 8);
19 let [label, control] = field(rows.next(26));
20 d.add_label("Name", label)?;
21 let name = d.add_edit(EditStyle::default(), control)?;
22 let [label, control] = field(rows.next(26));
23 d.add_label("Language", label)?;
24 let language = d.add_drop_down(control)?;
25 d.set_items(language, &["English", "Cantonese", "Japanese"]);
26 d.set_selected(language, Some(0));
27 let news = d.add_check("Send me news", rows.next(26))?;
28
29 let [_, save, cancel] = rows
30 .next(30)
31 .columns([Size::Fill(1), Size::Fixed(96), Size::Fixed(96)], 8);
32 let save = d.add_button("Save", save)?;
33 let cancel = d.add_button("Cancel", cancel)?;
34
35 d.run(|d, event| match event {
36 Event::Clicked(id) if id == save => {
37 println!(
38 "{} / {:?} / news: {}",
39 d.text(name),
40 d.selected(language),
41 d.checked(news)
42 );
43 Flow::Close
44 }
45 Event::Submit => Flow::Continue,
46 Event::Clicked(id) if id == cancel => Flow::Close,
47 Event::Close => Flow::Close,
48 _ => Flow::Continue,
49 })?;
50 Ok(())
51}examples/kanban.rs (line 24)
23fn main() -> glasskit::Result<()> {
24 let ui = Ui::new()?;
25 let mut events: EventLoop<()> = EventLoop::new(&ui)?;
26 let mut window = Window::new(&ui, "Kanban", 820.0, 520.0)?;
27 window.set_min_size(560.0, 360.0);
28
29 let mut board = Board::new(&mut window, &["To do", "Doing", "Done"]);
30 for (lane, title, body) in CARDS {
31 board.add_card(&mut window, lane, CardData::new(title, body));
32 }
33 let pinned = CardData {
34 pinned: true,
35 ..CardData::new("Ask for the budget", "")
36 };
37 board.add_card(&mut window, 1, pinned);
38
39 let title = window.add(Text::new("Board").style(TextStyle::Title));
40 let gap = window.add(Spacer::fill());
41 let archived = window.add(Button::new("Show archived"));
42 let top = window.add(Row::new().child(title).child(gap).child(archived));
43 let root = window.add(
44 Column::new()
45 .padding(Insets::all(16.0))
46 .gap(12.0)
47 .child(top)
48 .child(board.widget()),
49 );
50 window.set_root(root);
51 window.show();
52
53 loop {
54 match events.next(None)? {
55 Event::Window(id) if id == window.id() => {
56 while let Some(event) = window.next_event() {
57 match event {
58 WindowEvent::CloseRequested => return Ok(()),
59 WindowEvent::Clicked(id) if id == archived => {
60 let show = !board.show_archived();
61 board.set_show_archived(&mut window, show);
62 let label = if show {
63 "Hide archived"
64 } else {
65 "Show archived"
66 };
67 window.set_text(archived, label);
68 }
69 event => {
70 if let Some(change) = board.handle(&ui, &mut window, &event)? {
71 println!("{}", describe(&board, &change));
72 }
73 }
74 }
75 }
76 }
77 Event::Quit => return Ok(()),
78 _ => {}
79 }
80 }
81}examples/sidebar.rs (line 23)
22fn main() -> glasskit::Result<()> {
23 let ui = Ui::new()?;
24 let mut events: EventLoop<()> = EventLoop::new(&ui)?;
25 let mut window = Window::new(&ui, "Side bar", 560.0, 360.0)?;
26 window.set_min_size(360.0, 260.0);
27
28 let items = PAGES.map(|(name, icon)| window.add(NavItem::new(name).icon(icon)));
29 let pages = PAGES.map(|(name, _)| {
30 let title = window.add(Text::new(name).style(TextStyle::Title));
31 window.add(Column::new().padding(Insets::all(16.0)).child(title))
32 });
33 let gap = window.add(Spacer::fill());
34 let mode = match std::env::args().nth(1).as_deref() {
35 Some("icons") => SideMode::Icons,
36 Some("collapsed") => SideMode::Collapsed,
37 _ => SideMode::Expanded,
38 };
39 let side = window.add(
40 SideBar::new()
41 .title("glasskit")
42 .expanded_width(180.0)
43 .mode(mode)
44 .gap(4.0)
45 .child(items[0])
46 .child(items[1])
47 .child(gap)
48 .child(items[2]),
49 );
50 let stack = window.add(Stack::new().width(Length::Fill(1.0)).children(pages));
51 let root = window.add(
52 Row::new()
53 .padding(Insets::all(8.0))
54 .gap(8.0)
55 .align(Align::Stretch)
56 .child(side)
57 .child(stack),
58 );
59 window.set_root(root);
60 let show = |window: &mut Window, shown: usize| {
61 for (i, (item, page)) in items.into_iter().zip(pages).enumerate() {
62 window.set_selected(item, i == shown);
63 window.set_visible(page, i == shown);
64 }
65 };
66 show(&mut window, 0);
67 window.show();
68
69 loop {
70 match events.next(None)? {
71 Event::Window(id) if id == window.id() => {
72 while let Some(event) = window.next_event() {
73 match event {
74 WindowEvent::Clicked(id) => {
75 if let Some(shown) = items.iter().position(|&item| id == item) {
76 show(&mut window, shown);
77 }
78 }
79 WindowEvent::SideModeChanged(id) if id == side => {
80 println!("{:?}", window.side_mode(side));
81 }
82 WindowEvent::CloseRequested => return Ok(()),
83 _ => {}
84 }
85 }
86 }
87 Event::Quit => return Ok(()),
88 _ => {}
89 }
90 }
91}examples/window.rs (line 16)
15fn main() -> glasskit::Result<()> {
16 let ui = Ui::new()?;
17 let mut events: EventLoop<()> = EventLoop::new(&ui)?;
18 let mut window = Window::new(&ui, "glasskit", 420.0, 330.0)?;
19 window.set_min_size(320.0, 290.0);
20 match std::env::args().nth(1).as_deref() {
21 Some("glass") => window.set_material(Material::Glass),
22 Some("solid") => window.set_material(Material::Solid),
23 _ => {}
24 }
25
26 let title = window.add(Text::new("Settings").style(TextStyle::Title));
27 let note = window.add(Text::new(
28 "Widgets lay out in rows and columns, and the window follows the display scale.",
29 ));
30 let count = window.add(Text::new("Count: 0").style(TextStyle::BodyStrong));
31 let add = window.add(Button::new("Add one"));
32 let counter = window.add(Row::new().gap(12.0).child(count).child(add));
33 let card = window.add(Card::new().child(counter));
34 let name = window.add(TextBox::new().placeholder("Your name").max_length(40));
35 let spacer = window.add(Spacer::fill());
36 let cancel = window.add(Button::new("Cancel"));
37 let ok = window.add(Button::new("OK").accent());
38 let buttons = window.add(Row::new().gap(8.0).child(spacer).child(cancel).child(ok));
39 let gap = window.add(Spacer::fill());
40 let root = window.add(
41 Column::new()
42 .padding(Insets::all(24.0))
43 .gap(12.0)
44 .child(title)
45 .child(note)
46 .child(card)
47 .child(name)
48 .child(gap)
49 .child(buttons),
50 );
51 window.set_root(root);
52 window.show();
53
54 let mut n = 0;
55 loop {
56 match events.next(None)? {
57 Event::Window(id) if id == window.id() => {
58 while let Some(event) = window.next_event() {
59 match event {
60 WindowEvent::Clicked(b) if b == add => {
61 n += 1;
62 window.set_text(count, &format!("Count: {n}"));
63 println!("count {n}");
64 }
65 WindowEvent::Clicked(b) if b == ok => {
66 println!("ok {}", window.text(name));
67 return Ok(());
68 }
69 WindowEvent::Submitted(b) if b == name => {
70 println!("ok {}", window.text(name));
71 return Ok(());
72 }
73 WindowEvent::Clicked(b) if b == cancel => return Ok(()),
74 WindowEvent::Key(k) if k.is_plain(Key::ESCAPE) => {
75 println!("escape");
76 return Ok(());
77 }
78 WindowEvent::CloseRequested => return Ok(()),
79 _ => {}
80 }
81 }
82 }
83 Event::Quit => return Ok(()),
84 _ => {}
85 }
86 }
87}Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for Ui
impl !Send for Ui
impl !Sync for Ui
impl !UnwindSafe for Ui
impl Forget for Ui
impl Freeze for Ui
impl Move for Ui
impl Unpin for Ui
impl UnsafeUnpin for Ui
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more