Compare commits

..

2 Commits

11 changed files with 186 additions and 22 deletions

2
Cargo.lock generated
View File

@ -910,7 +910,7 @@ dependencies = [
"gdk4",
"gio",
"glib",
"glib-build-tools",
"glib-build-tools 0.16.3",
"gtk4",
"libadwaita",
"serde",

View File

@ -30,6 +30,7 @@ macro_rules! define_config {
}
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
#[serde(untagged)]
pub enum ConfigOption {
$($name($struct)),+
}

View File

@ -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);

View File

@ -1,14 +1,18 @@
use crate::{
ui::types;
};
use crate::ui::{home, library_view, HomeView, LibraryView};
use serde::{Deserialize, Serialize};
use typeshare::typeshare;
#[typeshare]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum LaunchScreenView {
CreateGame(CreateGameView)
pub struct LaunchScreenView {
home: HomeView,
library: LibraryView,
}
// This will be called when the Kifu application starts.
pub fn launch_screen() -> LaunchScreenView {
pub fn launch_screen_view() -> LaunchScreenView {
LaunchScreenView {
home: home(vec![].into_iter()),
library: library_view(),
}
}

View File

@ -0,0 +1,10 @@
use serde::{Deserialize, Serialize};
use typeshare::typeshare;
#[typeshare]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct LibraryView;
pub fn library_view() -> LibraryView {
LibraryView
}

View File

@ -4,8 +4,11 @@ pub use elements::{action::Action, game_preview::GamePreviewElement, menu::Menu}
mod playing_field;
pub use playing_field::{playing_field, PlayingFieldView};
// mod launch_screen;
// pub use launch_screen::{launch_screen, LaunchScreenView};
mod launch_screen;
pub use launch_screen::{launch_screen_view, LaunchScreenView};
mod library_view;
pub use library_view::{library_view, LibraryView};
mod home;
pub use home::{home, HomeView, HotseatPlayerElement, PlayerElement};

View File

@ -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" ] }

View File

@ -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"
}

View File

@ -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<RefCell<i32>>,
}
#[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<IntegerObjectPrivate>);
}
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<IntegerObject> = (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::<gtk::ListItem>()
.expect("Needs to be a ListItem")
.set_child(Some(&label));
});
factory.connect_bind(move |_, list_item| {
let integer_object = list_item
.downcast_ref::<gtk::ListItem>()
.expect("Needs to be ListItem")
.item()
.and_downcast::<IntegerObject>()
.expect("The item has to be an IntegerObject.");
let label = list_item
.downcast_ref::<gtk::ListItem>()
.expect("Needs to be ListItem")
.child()
.and_downcast::<gtk::Label>()
.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<GameDatabasePrivate>) @extends gtk::Widget, gtk::Box;
}
impl GameDatabase {
pub fn new() -> Self {
let s: Self = Object::builder().build();
s.append(&s.imp().list_view);
s
}
}

View File

@ -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<RefCell<GamePreviewElement>>,
}
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<DatabaseGamePrivate>);
}
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<RefCell<Option<PlayerDataEntry>>>,
white_player: Rc<RefCell<Option<PlayerDataEntry>>>,
@ -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
}
}

View File

@ -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;