Skip to main content

sidebar/
sidebar.rs

1// Copyright (c) 2026 John Law
2// SPDX-License-Identifier: MIT
3
4//! A window with a side bar that the user can make narrow.
5//!
6//! Run it with `cargo run -p glasskit --example sidebar`. Pass `icons` or `collapsed` to
7//! start in that mode.
8
9use glasskit::Ui;
10use glasskit::events::{Event, EventLoop};
11use glasskit::widget::{
12    Align, Column, Insets, Length, NavItem, Row, SideBar, SideMode, Spacer, Stack, Text, TextStyle,
13};
14use glasskit::window::{Window, WindowEvent};
15
16const PAGES: [(&str, &str); 3] = [
17    ("Home", "\u{E80F}"),
18    ("Mail", "\u{E715}"),
19    ("Settings", "\u{E713}"),
20];
21
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}