176 lines
5.6 KiB
Rust
176 lines
5.6 KiB
Rust
|
/*
|
||
|
Copyright 2024, Savanni D'Gerinel <savanni@luminescent-dreams.com>
|
||
|
|
||
|
This file is part of Kifu.
|
||
|
|
||
|
Kifu is free software: you can redistribute it and/or modify it under the terms of the GNU
|
||
|
General Public License as published by the Free Software Foundation, either version 3 of the
|
||
|
License, or (at your option) any later version.
|
||
|
|
||
|
Kifu is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||
|
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License along with Kifu. If not, see <https://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
use adw::prelude::*;
|
||
|
use gio::resources_lookup_data;
|
||
|
use glib::IsA;
|
||
|
use gtk::STYLE_PROVIDER_PRIORITY_USER;
|
||
|
use kifu_core::{Config, Core};
|
||
|
|
||
|
use crate::view_models::SettingsViewModel;
|
||
|
|
||
|
enum AppView {
|
||
|
Settings(SettingsViewModel),
|
||
|
Home,
|
||
|
}
|
||
|
|
||
|
// An application window should generally contain
|
||
|
// - an overlay widget
|
||
|
// - the main content in a stack on the bottom panel of the overlay
|
||
|
// - the settings and the about page in bins atop the overlay
|
||
|
pub struct AppWindow {
|
||
|
pub window: adw::ApplicationWindow,
|
||
|
header: adw::HeaderBar,
|
||
|
|
||
|
// content is a stack which contains the view models for the application. These are the main
|
||
|
// elements that users want to interact with: the home page, the game library, a review, a game
|
||
|
// itself, perhaps also chat rooms and player lists on other networks. stack contains the
|
||
|
// widgets that need to be rendered. The two of these work together in order to ensure that
|
||
|
// we can maintain the state of previous views. Since the two of these work together, they are
|
||
|
// a candidate for extraction into a new widget or a new struct.
|
||
|
stack: adw::NavigationView,
|
||
|
content: Vec<AppView>,
|
||
|
|
||
|
// Overlays are for transient content, such as about and settings, which can be accessed from
|
||
|
// anywhere but shouldn't be part of the main application flow.
|
||
|
panel_overlay: gtk::Overlay,
|
||
|
core: Core,
|
||
|
}
|
||
|
|
||
|
impl AppWindow {
|
||
|
pub fn new(app: &adw::Application, core: Core) -> Self {
|
||
|
/*
|
||
|
|
||
|
let stylesheet = String::from_utf8(
|
||
|
resources_lookup_data(
|
||
|
"/com/luminescent-dreams/kifu-gtk/style.css",
|
||
|
gio::ResourceLookupFlags::NONE,
|
||
|
)
|
||
|
.expect("stylesheet should just be available")
|
||
|
.to_vec(),
|
||
|
)
|
||
|
.expect("to parse stylesheet");
|
||
|
|
||
|
let provider = gtk::CssProvider::new();
|
||
|
provider.load_from_data(&stylesheet);
|
||
|
let context = window.style_context();
|
||
|
context.add_provider(&provider, STYLE_PROVIDER_PRIORITY_USER);
|
||
|
|
||
|
let header = setup_header();
|
||
|
|
||
|
let current_view = match config.get::<Database>() {
|
||
|
Some(_) => AppView::Home,
|
||
|
None => AppView::Config(SettingsViewModel::new(core.clone())),
|
||
|
};
|
||
|
|
||
|
let content = adw::Bin::builder().css_classes(vec!["content"]).build();
|
||
|
content.set_child(Some(
|
||
|
));
|
||
|
|
||
|
|
||
|
window.set_content(Some(&layout));
|
||
|
*/
|
||
|
|
||
|
let window = Self::setup_window(app);
|
||
|
let header = Self::setup_header();
|
||
|
let panel_overlay = Self::setup_panel_overlay();
|
||
|
let (stack, content) = Self::setup_content(core.clone());
|
||
|
|
||
|
let layout = gtk::Box::builder()
|
||
|
.orientation(gtk::Orientation::Vertical)
|
||
|
.build();
|
||
|
layout.append(&header);
|
||
|
layout.append(&panel_overlay);
|
||
|
panel_overlay.set_child(Some(&stack));
|
||
|
|
||
|
window.set_content(Some(&layout));
|
||
|
|
||
|
Self {
|
||
|
window,
|
||
|
header,
|
||
|
stack,
|
||
|
content,
|
||
|
panel_overlay,
|
||
|
core,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn setup_window(app: &adw::Application) -> adw::ApplicationWindow {
|
||
|
let window = adw::ApplicationWindow::builder()
|
||
|
.application(app)
|
||
|
.width_request(800)
|
||
|
.height_request(500)
|
||
|
.build();
|
||
|
|
||
|
window
|
||
|
}
|
||
|
|
||
|
fn setup_header() -> adw::HeaderBar {
|
||
|
let header = adw::HeaderBar::builder()
|
||
|
.title_widget(>k::Label::new(Some("Kifu")))
|
||
|
.build();
|
||
|
|
||
|
let app_menu = gio::Menu::new();
|
||
|
let menu_item = gio::MenuItem::new(Some("Configuration"), Some("app.show_config"));
|
||
|
app_menu.append_item(&menu_item);
|
||
|
|
||
|
let hamburger = gtk::MenuButton::builder()
|
||
|
.icon_name("open-menu-symbolic")
|
||
|
.build();
|
||
|
hamburger.set_menu_model(Some(&app_menu));
|
||
|
|
||
|
header.pack_end(&hamburger);
|
||
|
header
|
||
|
}
|
||
|
|
||
|
fn setup_panel_overlay() -> gtk::Overlay {
|
||
|
gtk::Overlay::new()
|
||
|
}
|
||
|
|
||
|
fn setup_content(core: Core) -> (adw::NavigationView, Vec<AppView>) {
|
||
|
let stack = adw::NavigationView::new();
|
||
|
let mut content = Vec::new();
|
||
|
|
||
|
let nothing_page = adw::StatusPage::builder().title("Nothing here").build();
|
||
|
let _ = stack.push(
|
||
|
&adw::NavigationPage::builder()
|
||
|
.can_pop(false)
|
||
|
.title("Kifu")
|
||
|
.child(¬hing_page)
|
||
|
.build(),
|
||
|
);
|
||
|
content.push(AppView::Home);
|
||
|
|
||
|
/*
|
||
|
match *core.library() {
|
||
|
Some(_) => {
|
||
|
}
|
||
|
None => {
|
||
|
let settings_vm = SettingsViewModel::new(core.clone());
|
||
|
let _ = stack.push(&adw::NavigationPage::new(&settings_vm.widget, "Settings"));
|
||
|
content.push(AppView::Settings(settings_vm));
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
(stack, content)
|
||
|
}
|
||
|
|
||
|
// pub fn set_content(content: &impl IsA<gtk::Widget>) -> adw::ViewStack {
|
||
|
// self.content.set_child(Some(content));
|
||
|
// }
|
||
|
}
|