diff --git a/config/src/lib.rs b/config/src/lib.rs index 1c2b36b..054d96a 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -30,6 +30,7 @@ macro_rules! define_config { } #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] + #[serde(untagged)] pub enum ConfigOption { $($name($struct)),+ } diff --git a/kifu/core/src/api.rs b/kifu/core/src/api.rs index 38c4d84..4387187 100644 --- a/kifu/core/src/api.rs +++ b/kifu/core/src/api.rs @@ -71,8 +71,10 @@ impl CoreApp { pub fn new(config_path: std::path::PathBuf) -> Self { println!("config_path: {:?}", config_path); let config = Config::from_path(config_path).expect("configuration to open"); + println!("config: {:?}", config); let db_path: DatabasePath = config.get().unwrap(); + println!("db_path: {:?}", db_path); let state = Arc::new(RwLock::new(AppState::new(db_path))); println!("config: {:?}", config); diff --git a/kifu/gtk/Cargo.toml b/kifu/gtk/Cargo.toml index fe09ef7..d58e07f 100644 --- a/kifu/gtk/Cargo.toml +++ b/kifu/gtk/Cargo.toml @@ -12,7 +12,7 @@ screenplay = [] cairo-rs = { version = "0.17" } gio = { version = "0.17" } glib = { version = "0.17" } -gtk = { version = "0.6", package = "gtk4" } +gtk = { version = "0.6", package = "gtk4", features = ["v4_8"] } image = { version = "0.24" } kifu-core = { path = "../core" } tokio = { version = "1.26", features = [ "full" ] } diff --git a/kifu/gtk/config b/kifu/gtk/config index 6ad4a86..a387288 100644 --- a/kifu/gtk/config +++ b/kifu/gtk/config @@ -1 +1,7 @@ -{"Me":{"name":"Savanni","rank":{"Kyu":10}},"DatabasePath":"../core/fixtures/five_games"} +{ + "Me":{ + "name":"Savanni", + "rank":{"Kyu":10} + }, + "DatabasePath": "kifu/core/fixtures/five_games" +} diff --git a/kifu/gtk/src/ui/game_database.rs b/kifu/gtk/src/ui/game_database.rs new file mode 100644 index 0000000..0113a70 --- /dev/null +++ b/kifu/gtk/src/ui/game_database.rs @@ -0,0 +1,96 @@ +use glib::{Object, Properties}; +use gtk::{glib, prelude::*, subclass::prelude::*}; +use std::{cell::RefCell, rc::Rc}; + +#[derive(Default)] +pub struct IntegerObjectPrivate { + number: Rc>, +} + +#[glib::object_subclass] +impl ObjectSubclass for IntegerObjectPrivate { + const NAME: &'static str = "IntegerObject"; + type Type = IntegerObject; +} + +impl ObjectImpl for IntegerObjectPrivate {} + +glib::wrapper! { + pub struct IntegerObject(ObjectSubclass); +} + +impl IntegerObject { + pub fn new(number: i32) -> Self { + let s: Self = Object::builder().build(); + *s.imp().number.borrow_mut() = number; + s + } + + pub fn number(&self) -> i32 { + self.imp().number.borrow().clone() + } +} + +pub struct GameDatabasePrivate { + list_view: gtk::ListView, +} + +impl Default for GameDatabasePrivate { + fn default() -> Self { + let vector: Vec = (0..=500).map(IntegerObject::new).collect(); + let model = gio::ListStore::new(glib::types::Type::OBJECT); + model.extend_from_slice(&vector); + let factory = gtk::SignalListItemFactory::new(); + factory.connect_setup(move |_, list_item| { + let label = gtk::Label::new(None); + list_item + .downcast_ref::() + .expect("Needs to be a ListItem") + .set_child(Some(&label)); + }); + factory.connect_bind(move |_, list_item| { + let integer_object = list_item + .downcast_ref::() + .expect("Needs to be ListItem") + .item() + .and_downcast::() + .expect("The item has to be an IntegerObject."); + + let label = list_item + .downcast_ref::() + .expect("Needs to be ListItem") + .child() + .and_downcast::() + .expect("The child has to be an Label."); + + label.set_label(&integer_object.number().to_string()); + }); + + let selection_model = gtk::SingleSelection::new(Some(model)); + let list_view = gtk::ListView::new(Some(selection_model), Some(factory)); + Self { list_view } + } +} + +#[glib::object_subclass] +impl ObjectSubclass for GameDatabasePrivate { + const NAME: &'static str = "GameDatabase"; + type Type = GameDatabase; + type ParentType = gtk::Box; +} + +impl ObjectImpl for GameDatabasePrivate {} +impl WidgetImpl for GameDatabasePrivate {} +impl BoxImpl for GameDatabasePrivate {} + +glib::wrapper! { + pub struct GameDatabase(ObjectSubclass) @extends gtk::Widget, gtk::Box; +} + +impl GameDatabase { + pub fn new() -> Self { + let s: Self = Object::builder().build(); + s.append(&s.imp().list_view); + s + } +} diff --git a/kifu/gtk/src/ui/home.rs b/kifu/gtk/src/ui/home.rs index 8070a1d..fd71d9a 100644 --- a/kifu/gtk/src/ui/home.rs +++ b/kifu/gtk/src/ui/home.rs @@ -1,12 +1,16 @@ -use crate::ui::GamePreview; -use crate::CoreApi; -use glib::Object; +use crate::{ui::GamePreview, CoreApi}; +use glib::{Object, Properties}; use gtk::{glib, prelude::*, subclass::prelude::*}; use kifu_core::{ - ui::{HomeView, PlayerElement}, + ui::{GamePreviewElement, HomeView, PlayerElement}, CoreRequest, CreateGameRequest, HotseatPlayerRequest, PlayerInfoRequest, }; -use std::{cell::RefCell, rc::Rc}; +use std::{ + cell::{Cell, RefCell}, + rc::Rc, +}; + +use super::GameDatabase; struct PlayerDataEntryPrivate { name: gtk::Text, @@ -83,6 +87,44 @@ impl PlayerDataEntry { } } +pub struct DatabaseGamePrivate { + game: Rc>, +} + +impl Default for DatabaseGamePrivate { + fn default() -> Self { + Self { + game: Rc::new(RefCell::new(GamePreviewElement { + date: vec![], + black_player: "".to_owned(), + black_rank: None, + white_player: "".to_owned(), + white_rank: None, + })), + } + } +} + +#[glib::object_subclass] +impl ObjectSubclass for DatabaseGamePrivate { + const NAME: &'static str = "DatabaseGame"; + type Type = DatabaseGame; +} + +impl ObjectImpl for DatabaseGamePrivate {} + +glib::wrapper! { + pub struct DatabaseGame(ObjectSubclass); +} + +impl DatabaseGame { + pub fn new(preview: GamePreviewElement) -> Self { + let s: Self = Object::builder().build(); + *s.imp().game.borrow_mut() = preview; + s + } +} + pub struct HomePrivate { black_player: Rc>>, white_player: Rc>>, @@ -127,6 +169,9 @@ impl Home { let new_game_button = gtk::Button::builder().label(&view.start_game.label).build(); s.attach(&new_game_button, 2, 2, 1, 1); + let database = GameDatabase::new(); + s.attach(&database, 0, 3, 2, 2); + new_game_button.connect_clicked({ move |_| { let black_player = black_player.clone(); @@ -139,12 +184,6 @@ impl Home { } }); - let game_list = gtk::Box::new(gtk::Orientation::Vertical, 0); - s.attach(&game_list, 1, 3, 2, 1); - view.games - .iter() - .for_each(|game_preview| game_list.append(&GamePreview::new(game_preview.clone()))); - s } } diff --git a/kifu/gtk/src/ui/mod.rs b/kifu/gtk/src/ui/mod.rs index d3b9c14..4c4ca47 100644 --- a/kifu/gtk/src/ui/mod.rs +++ b/kifu/gtk/src/ui/mod.rs @@ -1,6 +1,9 @@ mod chat; pub use chat::Chat; +mod game_database; +pub use game_database::GameDatabase; + mod game_preview; pub use game_preview::GamePreview;