Compare commits
No commits in common. "084a558740887bd40bc3ad40c574d7e2ee30a964" and "741f96360651410ad56ad1ab774af20f6610b355" have entirely different histories.
084a558740
...
741f963606
|
@ -71,7 +71,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "emseries"
|
name = "emseries"
|
||||||
version = "0.6.0"
|
version = "0.5.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"chrono-tz",
|
"chrono-tz",
|
||||||
|
|
|
@ -51,7 +51,6 @@ dependencies = [
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
|
||||||
"time",
|
"time",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"winapi",
|
"winapi",
|
||||||
|
@ -69,9 +68,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"nom",
|
"nom",
|
||||||
"serde",
|
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"typeshare",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -97,12 +94,6 @@ dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itoa"
|
|
||||||
version = "1.0.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.64"
|
version = "0.3.64"
|
||||||
|
@ -179,54 +170,6 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ryu"
|
|
||||||
version = "1.0.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde"
|
|
||||||
version = "1.0.164"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d"
|
|
||||||
dependencies = [
|
|
||||||
"serde_derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_derive"
|
|
||||||
version = "1.0.164"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.18",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_json"
|
|
||||||
version = "1.0.99"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
|
|
||||||
dependencies = [
|
|
||||||
"itoa",
|
|
||||||
"ryu",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "1.0.109"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.18"
|
version = "2.0.18"
|
||||||
|
@ -255,7 +198,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.18",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -269,28 +212,6 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "typeshare"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f44d1a2f454cb35fbe05b218c410792697e76bd868f48d3a418f2cd1a7d527d6"
|
|
||||||
dependencies = [
|
|
||||||
"chrono",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"typeshare-annotation",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "typeshare-annotation"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fc670d0e358428857cc3b4bf504c691e572fccaec9542ff09212d3f13d74b7a9"
|
|
||||||
dependencies = [
|
|
||||||
"quote",
|
|
||||||
"syn 1.0.109",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.9"
|
version = "1.0.9"
|
||||||
|
@ -324,7 +245,7 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.18",
|
"syn",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -346,7 +267,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.18",
|
"syn",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,8 +6,6 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = { version = "0.4", features = [ "serde" ] }
|
|
||||||
nom = { version = "7" }
|
nom = { version = "7" }
|
||||||
serde = { version = "1", features = [ "derive" ] }
|
|
||||||
thiserror = { version = "1"}
|
thiserror = { version = "1"}
|
||||||
typeshare = { version = "1" }
|
chrono = { version = "0.4" }
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use chrono::{Datelike, NaiveDate};
|
use chrono::{Datelike, NaiveDate};
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use typeshare::typeshare;
|
|
||||||
|
|
||||||
#[derive(Debug, Error, PartialEq)]
|
#[derive(Debug, Error, PartialEq)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
@ -16,8 +14,7 @@ pub enum Error {
|
||||||
Unsupported,
|
Unsupported,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Deserialize, Serialize)]
|
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
||||||
#[typeshare]
|
|
||||||
pub enum Date {
|
pub enum Date {
|
||||||
Year(i32),
|
Year(i32),
|
||||||
YearMonth(i32, u32),
|
YearMonth(i32, u32),
|
||||||
|
|
|
@ -72,8 +72,6 @@ use crate::{
|
||||||
date::{self, parse_date_field, Date},
|
date::{self, parse_date_field, Date},
|
||||||
tree::{parse_collection, ParseSizeError, Size},
|
tree::{parse_collection, ParseSizeError, Size},
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use typeshare::typeshare;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error<'a> {
|
pub enum Error<'a> {
|
||||||
|
@ -99,8 +97,7 @@ impl<'a> From<ParseSizeError> for Error<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
#[typeshare]
|
|
||||||
pub enum Rank {
|
pub enum Rank {
|
||||||
Kyu(u8),
|
Kyu(u8),
|
||||||
Dan(u8),
|
Dan(u8),
|
||||||
|
@ -121,12 +118,6 @@ impl TryFrom<&str> for Rank {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToString for Rank {
|
|
||||||
fn to_string(&self) -> String {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct GameTree {
|
pub struct GameTree {
|
||||||
pub file_format: i8,
|
pub file_format: i8,
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
mod date;
|
pub mod date;
|
||||||
pub use date::Date;
|
pub mod go;
|
||||||
|
pub mod tree;
|
||||||
mod go;
|
|
||||||
pub use go::{parse_sgf, GameTree, GameType, Rank};
|
|
||||||
|
|
||||||
mod tree;
|
|
||||||
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
|
||||||
"time",
|
"time",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"winapi",
|
"winapi",
|
||||||
|
@ -126,9 +125,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"nom",
|
"nom",
|
||||||
"serde",
|
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"typeshare",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
types::{AppState, GameState, Player, Rank},
|
types::{AppState, GameState, Player, Rank},
|
||||||
ui::{home, playing_field, HomeView, PlayingFieldView},
|
ui::{new_game, playing_field, NewGameView, PlayingFieldView},
|
||||||
Config, DatabasePath,
|
Config,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
@ -12,7 +12,8 @@ use typeshare::typeshare;
|
||||||
#[serde(tag = "type", content = "content")]
|
#[serde(tag = "type", content = "content")]
|
||||||
pub enum CoreRequest {
|
pub enum CoreRequest {
|
||||||
CreateGame(CreateGameRequest),
|
CreateGame(CreateGameRequest),
|
||||||
Home,
|
LaunchScreen,
|
||||||
|
NewGame,
|
||||||
PlayingField,
|
PlayingField,
|
||||||
PlayStone(PlayStoneRequest),
|
PlayStone(PlayStoneRequest),
|
||||||
StartGame,
|
StartGame,
|
||||||
|
@ -58,7 +59,7 @@ impl From<HotseatPlayerRequest> for Player {
|
||||||
#[typeshare]
|
#[typeshare]
|
||||||
#[serde(tag = "type", content = "content")]
|
#[serde(tag = "type", content = "content")]
|
||||||
pub enum CoreResponse {
|
pub enum CoreResponse {
|
||||||
HomeView(HomeView),
|
NewGameView(NewGameView),
|
||||||
PlayingFieldView(PlayingFieldView),
|
PlayingFieldView(PlayingFieldView),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,14 +71,8 @@ pub struct CoreApp {
|
||||||
|
|
||||||
impl CoreApp {
|
impl CoreApp {
|
||||||
pub fn new(config_path: std::path::PathBuf) -> Self {
|
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");
|
let config = Config::from_path(config_path).expect("configuration to open");
|
||||||
|
let state = Arc::new(RwLock::new(AppState::new()));
|
||||||
let db_path: DatabasePath = config.get();
|
|
||||||
let state = Arc::new(RwLock::new(AppState::new(db_path)));
|
|
||||||
|
|
||||||
println!("config: {:?}", config);
|
|
||||||
println!("games database: {:?}", state.read().unwrap().database.len());
|
|
||||||
|
|
||||||
Self { config, state }
|
Self { config, state }
|
||||||
}
|
}
|
||||||
|
@ -118,9 +113,8 @@ impl CoreApp {
|
||||||
let game_state = app_state.game.as_ref().unwrap();
|
let game_state = app_state.game.as_ref().unwrap();
|
||||||
CoreResponse::PlayingFieldView(playing_field(game_state))
|
CoreResponse::PlayingFieldView(playing_field(game_state))
|
||||||
}
|
}
|
||||||
CoreRequest::Home => {
|
CoreRequest::LaunchScreen => CoreResponse::NewGameView(new_game()),
|
||||||
CoreResponse::HomeView(home(self.state.read().unwrap().database.all_games()))
|
CoreRequest::NewGame => CoreResponse::NewGameView(new_game()),
|
||||||
}
|
|
||||||
CoreRequest::PlayingField => {
|
CoreRequest::PlayingField => {
|
||||||
let app_state = self.state.read().unwrap();
|
let app_state = self.state.read().unwrap();
|
||||||
let game = app_state.game.as_ref().unwrap();
|
let game = app_state.game.as_ref().unwrap();
|
||||||
|
|
|
@ -36,7 +36,6 @@ enum OptionNames {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum ConfigOption {
|
pub enum ConfigOption {
|
||||||
DatabasePath(DatabasePath),
|
DatabasePath(DatabasePath),
|
||||||
Me(Me),
|
Me(Me),
|
||||||
|
@ -97,14 +96,14 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set(&mut self, val: ConfigOption) {
|
fn set(&mut self, val: ConfigOption) {
|
||||||
let _ = match val {
|
let _ = match val {
|
||||||
ConfigOption::DatabasePath(_) => self.values.insert(OptionNames::DatabasePath, val),
|
ConfigOption::DatabasePath(_) => self.values.insert(OptionNames::DatabasePath, val),
|
||||||
ConfigOption::Me(_) => self.values.insert(OptionNames::Me, val),
|
ConfigOption::Me(_) => self.values.insert(OptionNames::Me, val),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get<'a, T>(&'a self) -> T
|
fn get<'a, T>(&'a self) -> T
|
||||||
where
|
where
|
||||||
T: From<&'a Self>,
|
T: From<&'a Self>,
|
||||||
{
|
{
|
||||||
|
@ -112,16 +111,9 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct DatabasePath(PathBuf);
|
pub struct DatabasePath(PathBuf);
|
||||||
|
|
||||||
impl std::ops::Deref for DatabasePath {
|
|
||||||
type Target = PathBuf;
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&Config> for DatabasePath {
|
impl From<&Config> for DatabasePath {
|
||||||
fn from(config: &Config) -> Self {
|
fn from(config: &Config) -> Self {
|
||||||
match config.values.get(&OptionNames::DatabasePath) {
|
match config.values.get(&OptionNames::DatabasePath) {
|
||||||
|
@ -131,7 +123,7 @@ impl From<&Config> for DatabasePath {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Me(Player);
|
pub struct Me(Player);
|
||||||
|
|
||||||
impl From<&Config> for Option<Me> {
|
impl From<&Config> for Option<Me> {
|
||||||
|
@ -145,54 +137,3 @@ impl From<&Config> for Option<Me> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Deref for Me {
|
|
||||||
type Target = Player;
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
use crate::types::Rank;
|
|
||||||
use cool_asserts::assert_matches;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_can_set_and_get_options() {
|
|
||||||
let mut config = Config::new(PathBuf::from("."));
|
|
||||||
config.set(ConfigOption::DatabasePath(DatabasePath(PathBuf::from(
|
|
||||||
"fixtures/five_games",
|
|
||||||
))));
|
|
||||||
config.set(ConfigOption::Me(Me(Player {
|
|
||||||
name: "Savanni".to_owned(),
|
|
||||||
rank: Some(Rank::Kyu(10)),
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_can_serialize_and_deserialize() {
|
|
||||||
let mut config = Config::new(PathBuf::from("."));
|
|
||||||
config.set(ConfigOption::DatabasePath(DatabasePath(PathBuf::from(
|
|
||||||
"fixtures/five_games",
|
|
||||||
))));
|
|
||||||
config.set(ConfigOption::Me(Me(Player {
|
|
||||||
name: "Savanni".to_owned(),
|
|
||||||
rank: Some(Rank::Kyu(10)),
|
|
||||||
})));
|
|
||||||
let s = serde_json::to_string(&config.values).unwrap();
|
|
||||||
println!("{}", s);
|
|
||||||
let values: HashMap<OptionNames, ConfigOption> = serde_json::from_str(s.as_ref()).unwrap();
|
|
||||||
println!("options: {:?}", values);
|
|
||||||
|
|
||||||
assert_matches!(values.get(&OptionNames::DatabasePath),
|
|
||||||
Some(ConfigOption::DatabasePath(db_path)) =>
|
|
||||||
assert_eq!(*db_path, config.get())
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_matches!(values.get(&OptionNames::Me), Some(ConfigOption::Me(val)) =>
|
|
||||||
assert_eq!(Some(val.clone()), config.get())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{ffi::OsStr, io::Read, os::unix::ffi::OsStrExt, path::PathBuf};
|
use std::{ffi::OsStr, io::Read, os::unix::ffi::OsStrExt, path::PathBuf};
|
||||||
|
|
||||||
use go_sgf::{parse_sgf, GameTree};
|
use go_sgf::go::{parse_sgf, GameTree, GameType};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
|
@ -17,7 +17,6 @@ impl From<std::io::Error> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Database {
|
pub struct Database {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
games: Vec<GameTree>,
|
games: Vec<GameTree>,
|
||||||
|
@ -50,10 +49,6 @@ impl Database {
|
||||||
Ok(Database { path, games })
|
Ok(Database { path, games })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.games.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn all_games(&self) -> impl Iterator<Item = &GameTree> {
|
pub fn all_games(&self) -> impl Iterator<Item = &GameTree> {
|
||||||
self.games.iter()
|
self.games.iter()
|
||||||
}
|
}
|
||||||
|
@ -63,7 +58,6 @@ impl Database {
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use cool_asserts::assert_matches;
|
use cool_asserts::assert_matches;
|
||||||
use go_sgf::{Date, GameType};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_reads_empty_database() {
|
fn it_reads_empty_database() {
|
||||||
|
@ -85,7 +79,7 @@ mod test {
|
||||||
Some(game) => {
|
Some(game) => {
|
||||||
assert_eq!(game.info.black_player, Some("Steve".to_owned()));
|
assert_eq!(game.info.black_player, Some("Steve".to_owned()));
|
||||||
assert_eq!(game.info.white_player, Some("Savanni".to_owned()));
|
assert_eq!(game.info.white_player, Some("Savanni".to_owned()));
|
||||||
assert_eq!(game.info.date, vec![Date::Date(chrono::NaiveDate::from_ymd_opt(2023, 4, 19).unwrap())]);
|
assert_eq!(game.info.date, vec![chrono::NaiveDate::from_ymd_opt(2023, 4, 19).unwrap()]);
|
||||||
assert_eq!(game.info.komi, Some(6.5));
|
assert_eq!(game.info.komi, Some(6.5));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -13,5 +13,4 @@ mod database;
|
||||||
|
|
||||||
mod types;
|
mod types;
|
||||||
pub use types::{BoardError, Color, Rank, Size};
|
pub use types::{BoardError, Color, Rank, Size};
|
||||||
|
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
api::PlayStoneRequest,
|
api::PlayStoneRequest,
|
||||||
board::{Board, Coordinate},
|
board::{Board, Coordinate},
|
||||||
config::DatabasePath,
|
|
||||||
database::Database,
|
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{path::PathBuf, time::Duration};
|
use std::time::Duration;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use typeshare::typeshare;
|
use typeshare::typeshare;
|
||||||
|
|
||||||
|
@ -45,14 +43,12 @@ impl Default for Size {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
pub game: Option<GameState>,
|
pub game: Option<GameState>,
|
||||||
pub database: Database,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppState {
|
impl AppState {
|
||||||
pub fn new(database_path: DatabasePath) -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
game: Some(GameState::new()),
|
game: Some(GameState::new()),
|
||||||
database: Database::open_path(database_path.to_path_buf()).unwrap(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +91,7 @@ impl From<Rank> for String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Player {
|
pub struct Player {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub rank: Option<Rank>,
|
pub rank: Option<Rank>,
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
use go_sgf::{Date, GameTree, Rank};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use typeshare::typeshare;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
||||||
#[typeshare]
|
|
||||||
pub struct GamePreviewElement {
|
|
||||||
pub date: Vec<Date>,
|
|
||||||
pub black_player: String,
|
|
||||||
pub black_rank: Option<Rank>,
|
|
||||||
pub white_player: String,
|
|
||||||
pub white_rank: Option<Rank>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GamePreviewElement {
|
|
||||||
pub fn new(game: &GameTree) -> GamePreviewElement {
|
|
||||||
GamePreviewElement {
|
|
||||||
date: game.info.date.clone(),
|
|
||||||
black_player: game
|
|
||||||
.info
|
|
||||||
.black_player
|
|
||||||
.clone()
|
|
||||||
.unwrap_or("black_player".to_owned()),
|
|
||||||
black_rank: game.info.black_rank.clone(),
|
|
||||||
white_player: game
|
|
||||||
.info
|
|
||||||
.white_player
|
|
||||||
.clone()
|
|
||||||
.unwrap_or("white_player".to_owned()),
|
|
||||||
white_rank: game.info.white_rank.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +1,2 @@
|
||||||
pub mod action;
|
pub mod action;
|
||||||
pub mod game_preview;
|
|
||||||
pub mod menu;
|
pub mod menu;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
mod elements;
|
mod elements;
|
||||||
pub use elements::{action::Action, game_preview::GamePreviewElement, menu::Menu};
|
pub use elements::{action::Action, menu::Menu};
|
||||||
|
|
||||||
mod playing_field;
|
mod playing_field;
|
||||||
pub use playing_field::{playing_field, PlayingFieldView};
|
pub use playing_field::{playing_field, PlayingFieldView};
|
||||||
|
@ -7,8 +7,8 @@ pub use playing_field::{playing_field, PlayingFieldView};
|
||||||
// mod launch_screen;
|
// mod launch_screen;
|
||||||
// pub use launch_screen::{launch_screen, LaunchScreenView};
|
// pub use launch_screen::{launch_screen, LaunchScreenView};
|
||||||
|
|
||||||
mod home;
|
mod new_game;
|
||||||
pub use home::{home, HomeView, HotseatPlayerElement, PlayerElement};
|
pub use new_game::{new_game, HotseatPlayerElement, NewGameView, PlayerElement};
|
||||||
|
|
||||||
mod types;
|
mod types;
|
||||||
pub use types::{
|
pub use types::{
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::ui::{Action, GamePreviewElement};
|
use crate::ui::Action;
|
||||||
use go_sgf::GameTree;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use typeshare::typeshare;
|
use typeshare::typeshare;
|
||||||
|
|
||||||
|
@ -49,14 +48,13 @@ pub struct BotPlayerElement {}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
#[typeshare]
|
#[typeshare]
|
||||||
pub struct HomeView {
|
pub struct NewGameView {
|
||||||
pub black_player: PlayerElement,
|
pub black_player: PlayerElement,
|
||||||
pub white_player: PlayerElement,
|
pub white_player: PlayerElement,
|
||||||
pub games: Vec<GamePreviewElement>,
|
|
||||||
pub start_game: Action<()>,
|
pub start_game: Action<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn home<'a>(games: impl Iterator<Item = &'a GameTree>) -> HomeView {
|
pub fn new_game() -> NewGameView {
|
||||||
let black_player = PlayerElement::Hotseat(HotseatPlayerElement {
|
let black_player = PlayerElement::Hotseat(HotseatPlayerElement {
|
||||||
placeholder: Some("black player".to_owned()),
|
placeholder: Some("black player".to_owned()),
|
||||||
default_rank: None,
|
default_rank: None,
|
||||||
|
@ -67,10 +65,9 @@ pub fn home<'a>(games: impl Iterator<Item = &'a GameTree>) -> HomeView {
|
||||||
default_rank: None,
|
default_rank: None,
|
||||||
ranks: rank_strings(),
|
ranks: rank_strings(),
|
||||||
});
|
});
|
||||||
HomeView {
|
NewGameView {
|
||||||
black_player,
|
black_player,
|
||||||
white_player,
|
white_player,
|
||||||
games: games.map(GamePreviewElement::new).collect(),
|
|
||||||
start_game: Action {
|
start_game: Action {
|
||||||
id: "start-game-action".to_owned(),
|
id: "start-game-action".to_owned(),
|
||||||
label: "New Game".to_owned(),
|
label: "New Game".to_owned(),
|
|
@ -121,8 +121,6 @@ dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
|
||||||
"time",
|
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
@ -444,7 +442,7 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"wasi",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -545,17 +543,6 @@ dependencies = [
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "go-sgf"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"chrono",
|
|
||||||
"nom",
|
|
||||||
"serde",
|
|
||||||
"thiserror",
|
|
||||||
"typeshare",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gobject-sys"
|
name = "gobject-sys"
|
||||||
version = "0.17.4"
|
version = "0.17.4"
|
||||||
|
@ -798,8 +785,6 @@ dependencies = [
|
||||||
name = "kifu-core"
|
name = "kifu-core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
|
||||||
"go-sgf",
|
|
||||||
"grid",
|
"grid",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -877,12 +862,6 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "minimal-lexical"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
|
@ -900,7 +879,7 @@ checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"wasi",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -919,16 +898,6 @@ version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
|
checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nom"
|
|
||||||
version = "7.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
"minimal-lexical",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-integer"
|
name = "num-integer"
|
||||||
version = "0.1.45"
|
version = "0.1.45"
|
||||||
|
@ -1361,17 +1330,6 @@ dependencies = [
|
||||||
"weezl",
|
"weezl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "time"
|
|
||||||
version = "0.1.45"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.26.0"
|
version = "1.26.0"
|
||||||
|
@ -1475,12 +1433,6 @@ version = "0.9.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasi"
|
|
||||||
version = "0.10.0+wasi-snapshot-preview1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
|
|
@ -2,7 +2,6 @@ release:
|
||||||
cargo build --release
|
cargo build --release
|
||||||
|
|
||||||
dev:
|
dev:
|
||||||
export CONFIG=.
|
|
||||||
cargo watch -x 'run --bin kifu-gtk'
|
cargo watch -x 'run --bin kifu-gtk'
|
||||||
|
|
||||||
screenplay:
|
screenplay:
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
{"Me":{"name":"Savanni","rank":{"Kyu":10}},"DatabasePath":"../core/fixtures/five_games"}
|
|
|
@ -2,7 +2,7 @@ use gtk::prelude::*;
|
||||||
use kifu_core::{CoreApp, CoreRequest, CoreResponse};
|
use kifu_core::{CoreApp, CoreRequest, CoreResponse};
|
||||||
use kifu_gtk::{
|
use kifu_gtk::{
|
||||||
perftrace,
|
perftrace,
|
||||||
ui::{Home, PlayingField},
|
ui::{NewGame, PlayingField},
|
||||||
CoreApi,
|
CoreApi,
|
||||||
};
|
};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
@ -10,10 +10,10 @@ use std::sync::{Arc, RwLock};
|
||||||
fn handle_response(api: CoreApi, window: gtk::ApplicationWindow, message: CoreResponse) {
|
fn handle_response(api: CoreApi, window: gtk::ApplicationWindow, message: CoreResponse) {
|
||||||
let playing_field = Arc::new(RwLock::new(None));
|
let playing_field = Arc::new(RwLock::new(None));
|
||||||
match message {
|
match message {
|
||||||
CoreResponse::HomeView(view) => perftrace("HomeView", || {
|
CoreResponse::NewGameView(view) => perftrace("NewGameView", || {
|
||||||
let api = api.clone();
|
let api = api.clone();
|
||||||
|
|
||||||
let new_game = Home::new(api, view);
|
let new_game = NewGame::new(api, view);
|
||||||
window.set_child(Some(&new_game));
|
window.set_child(Some(&new_game));
|
||||||
}),
|
}),
|
||||||
CoreResponse::PlayingFieldView(view) => perftrace("PlayingFieldView", || {
|
CoreResponse::PlayingFieldView(view) => perftrace("PlayingFieldView", || {
|
||||||
|
@ -44,17 +44,10 @@ fn main() {
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let config_path = std::env::var("CONFIG")
|
let user_home = std::env::var("HOME").expect("the user's home directory isn't set");
|
||||||
.and_then(|config| Ok(std::path::PathBuf::from(config)))
|
let mut config_path = std::path::PathBuf::from(user_home);
|
||||||
.or({
|
config_path.push(".config");
|
||||||
std::env::var("HOME").and_then(|base| {
|
config_path.push("kifu");
|
||||||
let mut config_path = std::path::PathBuf::from(base);
|
|
||||||
config_path.push(".config");
|
|
||||||
config_path.push("kifu");
|
|
||||||
Ok(config_path)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.expect("no config path could be found");
|
|
||||||
|
|
||||||
let core = CoreApp::new(config_path);
|
let core = CoreApp::new(config_path);
|
||||||
|
|
||||||
|
@ -94,7 +87,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
api.dispatch(CoreRequest::Home);
|
api.dispatch(CoreRequest::NewGame);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
use glib::Object;
|
|
||||||
use gtk::{glib, prelude::*, subclass::prelude::*};
|
|
||||||
use kifu_core::ui::GamePreviewElement;
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct GamePreviewPrivate;
|
|
||||||
|
|
||||||
#[glib::object_subclass]
|
|
||||||
impl ObjectSubclass for GamePreviewPrivate {
|
|
||||||
const NAME: &'static str = "GamePreview";
|
|
||||||
type Type = GamePreview;
|
|
||||||
type ParentType = gtk::Box;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ObjectImpl for GamePreviewPrivate {}
|
|
||||||
impl WidgetImpl for GamePreviewPrivate {}
|
|
||||||
impl BoxImpl for GamePreviewPrivate {}
|
|
||||||
|
|
||||||
glib::wrapper! {
|
|
||||||
pub struct GamePreview(ObjectSubclass<GamePreviewPrivate>) @extends gtk::Box, gtk::Widget, @implements gtk::Orientable;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GamePreview {
|
|
||||||
pub fn new(element: GamePreviewElement) -> GamePreview {
|
|
||||||
let s: Self = Object::builder().build();
|
|
||||||
s.set_orientation(gtk::Orientation::Horizontal);
|
|
||||||
|
|
||||||
println!("game_preview: {:?}", element);
|
|
||||||
let black_player = match element.black_rank {
|
|
||||||
Some(rank) => format!("{} ({})", element.black_player, rank.to_string()),
|
|
||||||
None => element.black_player,
|
|
||||||
};
|
|
||||||
let white_player = match element.white_rank {
|
|
||||||
Some(rank) => format!("{} ({})", element.white_player, rank.to_string()),
|
|
||||||
None => element.white_player,
|
|
||||||
};
|
|
||||||
s.append(>k::Label::new(Some(&black_player)));
|
|
||||||
s.append(>k::Label::new(Some(&white_player)));
|
|
||||||
|
|
||||||
s
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +1,14 @@
|
||||||
mod chat;
|
|
||||||
pub use chat::Chat;
|
|
||||||
|
|
||||||
mod game_preview;
|
|
||||||
pub use game_preview::GamePreview;
|
|
||||||
|
|
||||||
mod player_card;
|
mod player_card;
|
||||||
pub use player_card::PlayerCard;
|
pub use player_card::PlayerCard;
|
||||||
|
|
||||||
|
mod chat;
|
||||||
|
pub use chat::Chat;
|
||||||
|
|
||||||
mod playing_field;
|
mod playing_field;
|
||||||
pub use playing_field::PlayingField;
|
pub use playing_field::PlayingField;
|
||||||
|
|
||||||
mod home;
|
mod new_game;
|
||||||
pub use home::Home;
|
pub use new_game::NewGame;
|
||||||
|
|
||||||
mod board;
|
mod board;
|
||||||
pub use board::Board;
|
pub use board::Board;
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
use crate::ui::GamePreview;
|
|
||||||
use crate::CoreApi;
|
use crate::CoreApi;
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use gtk::{glib, prelude::*, subclass::prelude::*};
|
use gtk::{glib, prelude::*, subclass::prelude::*};
|
||||||
use kifu_core::{
|
use kifu_core::{
|
||||||
ui::{HomeView, PlayerElement},
|
ui::{NewGameView, PlayerElement},
|
||||||
CoreRequest, CreateGameRequest, HotseatPlayerRequest, PlayerInfoRequest,
|
CoreRequest, CreateGameRequest, HotseatPlayerRequest, PlayerInfoRequest,
|
||||||
};
|
};
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
@ -83,12 +82,12 @@ impl PlayerDataEntry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct HomePrivate {
|
pub struct NewGamePrivate {
|
||||||
black_player: Rc<RefCell<Option<PlayerDataEntry>>>,
|
black_player: Rc<RefCell<Option<PlayerDataEntry>>>,
|
||||||
white_player: Rc<RefCell<Option<PlayerDataEntry>>>,
|
white_player: Rc<RefCell<Option<PlayerDataEntry>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for HomePrivate {
|
impl Default for NewGamePrivate {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
black_player: Rc::new(RefCell::new(None)),
|
black_player: Rc::new(RefCell::new(None)),
|
||||||
|
@ -98,22 +97,22 @@ impl Default for HomePrivate {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
impl ObjectSubclass for HomePrivate {
|
impl ObjectSubclass for NewGamePrivate {
|
||||||
const NAME: &'static str = "Home";
|
const NAME: &'static str = "NewGame";
|
||||||
type Type = Home;
|
type Type = NewGame;
|
||||||
type ParentType = gtk::Grid;
|
type ParentType = gtk::Grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectImpl for HomePrivate {}
|
impl ObjectImpl for NewGamePrivate {}
|
||||||
impl WidgetImpl for HomePrivate {}
|
impl WidgetImpl for NewGamePrivate {}
|
||||||
impl GridImpl for HomePrivate {}
|
impl GridImpl for NewGamePrivate {}
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct Home(ObjectSubclass<HomePrivate>) @extends gtk::Grid, gtk::Widget;
|
pub struct NewGame(ObjectSubclass<NewGamePrivate>) @extends gtk::Grid, gtk::Widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Home {
|
impl NewGame {
|
||||||
pub fn new(api: CoreApi, view: HomeView) -> Home {
|
pub fn new(api: CoreApi, view: NewGameView) -> NewGame {
|
||||||
let s: Self = Object::builder().build();
|
let s: Self = Object::builder().build();
|
||||||
|
|
||||||
let black_player = PlayerDataEntry::new(view.black_player);
|
let black_player = PlayerDataEntry::new(view.black_player);
|
||||||
|
@ -139,12 +138,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
|
s
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue