Add main window with sidebar navigation
This commit is contained in:
122
outlay-gtk/src/window.rs
Normal file
122
outlay-gtk/src/window.rs
Normal file
@@ -0,0 +1,122 @@
|
||||
use adw::prelude::*;
|
||||
|
||||
pub struct MainWindow {
|
||||
pub window: adw::ApplicationWindow,
|
||||
pub split_view: adw::NavigationSplitView,
|
||||
pub content_stack: gtk::Stack,
|
||||
}
|
||||
|
||||
struct SidebarItem {
|
||||
id: &'static str,
|
||||
label: &'static str,
|
||||
icon: &'static str,
|
||||
}
|
||||
|
||||
const SIDEBAR_ITEMS: &[SidebarItem] = &[
|
||||
SidebarItem { id: "log", label: "Log", icon: "list-add-symbolic" },
|
||||
SidebarItem { id: "history", label: "History", icon: "document-open-recent-symbolic" },
|
||||
SidebarItem { id: "charts", label: "Charts", icon: "utilities-system-monitor-symbolic" },
|
||||
SidebarItem { id: "budgets", label: "Budgets", icon: "wallet2-symbolic" },
|
||||
SidebarItem { id: "recurring", label: "Recurring", icon: "view-refresh-symbolic" },
|
||||
SidebarItem { id: "settings", label: "Settings", icon: "emblem-system-symbolic" },
|
||||
];
|
||||
|
||||
impl MainWindow {
|
||||
pub fn new(app: &adw::Application) -> Self {
|
||||
let content_stack = gtk::Stack::new();
|
||||
content_stack.set_transition_type(gtk::StackTransitionType::Crossfade);
|
||||
|
||||
for item in SIDEBAR_ITEMS {
|
||||
let page = adw::StatusPage::builder()
|
||||
.title(item.label)
|
||||
.icon_name(item.icon)
|
||||
.build();
|
||||
content_stack.add_named(&page, Some(item.id));
|
||||
}
|
||||
|
||||
let sidebar_list = gtk::ListBox::new();
|
||||
sidebar_list.set_selection_mode(gtk::SelectionMode::Single);
|
||||
sidebar_list.add_css_class("navigation-sidebar");
|
||||
|
||||
for item in SIDEBAR_ITEMS {
|
||||
let row = Self::make_sidebar_row(item);
|
||||
sidebar_list.append(&row);
|
||||
}
|
||||
|
||||
let content_stack_ref = content_stack.clone();
|
||||
sidebar_list.connect_row_selected(move |_, row| {
|
||||
if let Some(row) = row {
|
||||
let idx = row.index() as usize;
|
||||
if idx < SIDEBAR_ITEMS.len() {
|
||||
content_stack_ref.set_visible_child_name(SIDEBAR_ITEMS[idx].id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Select the first row by default
|
||||
if let Some(first_row) = sidebar_list.row_at_index(0) {
|
||||
sidebar_list.select_row(Some(&first_row));
|
||||
}
|
||||
|
||||
let sidebar_scroll = gtk::ScrolledWindow::builder()
|
||||
.hscrollbar_policy(gtk::PolicyType::Never)
|
||||
.vexpand(true)
|
||||
.child(&sidebar_list)
|
||||
.build();
|
||||
|
||||
let sidebar_toolbar = adw::ToolbarView::new();
|
||||
sidebar_toolbar.add_top_bar(&adw::HeaderBar::new());
|
||||
sidebar_toolbar.set_content(Some(&sidebar_scroll));
|
||||
|
||||
let sidebar_page = adw::NavigationPage::builder()
|
||||
.title("Outlay")
|
||||
.child(&sidebar_toolbar)
|
||||
.build();
|
||||
|
||||
let content_toolbar = adw::ToolbarView::new();
|
||||
content_toolbar.add_top_bar(&adw::HeaderBar::new());
|
||||
content_toolbar.set_content(Some(&content_stack));
|
||||
|
||||
let content_page = adw::NavigationPage::builder()
|
||||
.title("Outlay")
|
||||
.child(&content_toolbar)
|
||||
.build();
|
||||
|
||||
let split_view = adw::NavigationSplitView::new();
|
||||
split_view.set_sidebar(Some(&sidebar_page));
|
||||
split_view.set_content(Some(&content_page));
|
||||
|
||||
let window = adw::ApplicationWindow::builder()
|
||||
.application(app)
|
||||
.title("Outlay")
|
||||
.default_width(900)
|
||||
.default_height(600)
|
||||
.content(&split_view)
|
||||
.build();
|
||||
|
||||
MainWindow {
|
||||
window,
|
||||
split_view,
|
||||
content_stack,
|
||||
}
|
||||
}
|
||||
|
||||
fn make_sidebar_row(item: &SidebarItem) -> gtk::ListBoxRow {
|
||||
let hbox = gtk::Box::new(gtk::Orientation::Horizontal, 12);
|
||||
hbox.set_margin_top(8);
|
||||
hbox.set_margin_bottom(8);
|
||||
hbox.set_margin_start(12);
|
||||
hbox.set_margin_end(12);
|
||||
|
||||
let icon = gtk::Image::from_icon_name(item.icon);
|
||||
let label = gtk::Label::new(Some(item.label));
|
||||
label.set_halign(gtk::Align::Start);
|
||||
|
||||
hbox.append(&icon);
|
||||
hbox.append(&label);
|
||||
|
||||
let row = gtk::ListBoxRow::new();
|
||||
row.set_child(Some(&hbox));
|
||||
row
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user