Show a list of games in the library #64
|
@ -1,36 +1,45 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sgf::{
|
use sgf::go::Game;
|
||||||
go::{Game, Rank},
|
|
||||||
Date,
|
|
||||||
};
|
|
||||||
use typeshare::typeshare;
|
use typeshare::typeshare;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
#[typeshare]
|
#[typeshare]
|
||||||
pub struct GamePreviewElement {
|
pub struct GamePreviewElement {
|
||||||
pub date: Vec<Date>,
|
pub date: Vec<String>,
|
||||||
pub black_player: String,
|
pub black_player: String,
|
||||||
pub black_rank: Option<Rank>,
|
|
||||||
pub white_player: String,
|
pub white_player: String,
|
||||||
pub white_rank: Option<Rank>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GamePreviewElement {
|
impl GamePreviewElement {
|
||||||
pub fn new(game: &Game) -> GamePreviewElement {
|
pub fn new(game: &Game) -> GamePreviewElement {
|
||||||
|
let black_player = match game.info.black_player {
|
||||||
|
Some(ref black_player) => black_player.clone(),
|
||||||
|
None => "unknown".to_owned(),
|
||||||
|
};
|
||||||
|
let white_player = match game.info.white_player {
|
||||||
|
Some(ref white_player) => white_player.clone(),
|
||||||
|
None => "unknown".to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let black_player = match game.info.black_rank {
|
||||||
|
Some(rank) => format!("{} ({})", black_player, rank.to_string()),
|
||||||
|
None => black_player,
|
||||||
|
};
|
||||||
|
|
||||||
|
let white_player = match game.info.white_rank {
|
||||||
|
Some(rank) => format!("{} ({})", white_player, rank.to_string()),
|
||||||
|
None => white_player,
|
||||||
|
};
|
||||||
|
|
||||||
GamePreviewElement {
|
GamePreviewElement {
|
||||||
date: game.info.date.clone(),
|
date: game
|
||||||
black_player: game
|
|
||||||
.info
|
.info
|
||||||
.black_player
|
.date
|
||||||
.clone()
|
.iter()
|
||||||
.unwrap_or("black_player".to_owned()),
|
.map(|dt| dt.to_string())
|
||||||
black_rank: game.info.black_rank.clone(),
|
.collect::<Vec<String>>(),
|
||||||
white_player: game
|
black_player,
|
||||||
.info
|
white_player,
|
||||||
.white_player
|
|
||||||
.clone()
|
|
||||||
.unwrap_or("white_player".to_owned()),
|
|
||||||
white_rank: game.info.white_rank.clone(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,12 @@ use gtk::{glib, prelude::*, subclass::prelude::*};
|
||||||
use kifu_core::ui::GamePreviewElement;
|
use kifu_core::ui::GamePreviewElement;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct GamePreviewPrivate;
|
pub struct GamePreviewPrivate {
|
||||||
|
title: gtk::Label,
|
||||||
|
black_player: gtk::Label,
|
||||||
|
white_player: gtk::Label,
|
||||||
|
date: gtk::Label,
|
||||||
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
impl ObjectSubclass for GamePreviewPrivate {
|
impl ObjectSubclass for GamePreviewPrivate {
|
||||||
|
@ -21,22 +26,23 @@ glib::wrapper! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GamePreview {
|
impl GamePreview {
|
||||||
pub fn new(element: GamePreviewElement) -> GamePreview {
|
pub fn new() -> GamePreview {
|
||||||
let s: Self = Object::builder().build();
|
let s: Self = Object::builder().build();
|
||||||
s.set_orientation(gtk::Orientation::Horizontal);
|
s.set_orientation(gtk::Orientation::Horizontal);
|
||||||
|
|
||||||
println!("game_preview: {:?}", element);
|
s.append(&s.imp().date);
|
||||||
let black_player = match element.black_rank {
|
s.append(&s.imp().title);
|
||||||
Some(rank) => format!("{} ({})", element.black_player, rank.to_string()),
|
s.append(&s.imp().black_player);
|
||||||
None => element.black_player,
|
s.append(&s.imp().white_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
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_game(&self, element: GamePreviewElement) {
|
||||||
|
self.imp().black_player.set_text(&element.black_player);
|
||||||
|
self.imp().white_player.set_text(&element.white_player);
|
||||||
|
if let Some(date) = element.date.first() {
|
||||||
|
self.imp().date.set_text(&date);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::ui::GamePreview;
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use gtk::{glib, prelude::*, subclass::prelude::*};
|
use gtk::{glib, prelude::*, subclass::prelude::*};
|
||||||
use kifu_core::ui::GamePreviewElement;
|
use kifu_core::ui::GamePreviewElement;
|
||||||
|
@ -45,41 +46,31 @@ impl Default for GameDatabasePrivate {
|
||||||
let factory = gtk::SignalListItemFactory::new();
|
let factory = gtk::SignalListItemFactory::new();
|
||||||
|
|
||||||
factory.connect_setup(move |_, list_item| {
|
factory.connect_setup(move |_, list_item| {
|
||||||
let label = gtk::Label::new(Some("some kind of text"));
|
let preview = GamePreview::new();
|
||||||
list_item
|
list_item
|
||||||
.downcast_ref::<gtk::ListItem>()
|
.downcast_ref::<gtk::ListItem>()
|
||||||
.expect("Needs to be a ListItem")
|
.expect("Needs to be a ListItem")
|
||||||
.set_child(Some(&label));
|
.set_child(Some(&preview));
|
||||||
});
|
});
|
||||||
factory.connect_bind(move |_, list_item| {
|
factory.connect_bind(move |_, list_item| {
|
||||||
let game_object = list_item
|
let game_element = list_item
|
||||||
.downcast_ref::<gtk::ListItem>()
|
.downcast_ref::<gtk::ListItem>()
|
||||||
.expect("Needs to be ListItem")
|
.expect("Needs to be ListItem")
|
||||||
.item()
|
.item()
|
||||||
.and_downcast::<GameObject>()
|
.and_downcast::<GameObject>()
|
||||||
.expect("The item has to be an IntegerObject.");
|
.expect("The item has to be a GameObject.");
|
||||||
|
|
||||||
let label = list_item
|
let preview = list_item
|
||||||
.downcast_ref::<gtk::ListItem>()
|
.downcast_ref::<gtk::ListItem>()
|
||||||
.expect("Needs to be ListItem")
|
.expect("Needs to be ListItem")
|
||||||
.child()
|
.child()
|
||||||
.and_downcast::<gtk::Label>()
|
.and_downcast::<GamePreview>()
|
||||||
.expect("The child has to be an Label.");
|
.expect("The child has to be a GamePreview object.");
|
||||||
|
|
||||||
label.set_label(
|
match game_element.game() {
|
||||||
format!(
|
Some(game) => preview.set_game(game),
|
||||||
"{} vs. {}",
|
None => (),
|
||||||
game_object
|
};
|
||||||
.game()
|
|
||||||
.map(|g| g.black_player)
|
|
||||||
.unwrap_or("black".to_owned()),
|
|
||||||
game_object
|
|
||||||
.game()
|
|
||||||
.map(|g| g.white_player)
|
|
||||||
.unwrap_or("white".to_owned())
|
|
||||||
)
|
|
||||||
.as_ref(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let selection_model = gtk::NoSelection::new(Some(model.clone()));
|
let selection_model = gtk::NoSelection::new(Some(model.clone()));
|
|
@ -1,12 +1,12 @@
|
||||||
mod chat;
|
mod chat;
|
||||||
pub use chat::Chat;
|
pub use chat::Chat;
|
||||||
|
|
||||||
mod game_database;
|
|
||||||
pub use game_database::GameDatabase;
|
|
||||||
|
|
||||||
mod game_preview;
|
mod game_preview;
|
||||||
pub use game_preview::GamePreview;
|
pub use game_preview::GamePreview;
|
||||||
|
|
||||||
|
mod library;
|
||||||
|
pub use library::GameDatabase;
|
||||||
|
|
||||||
mod player_card;
|
mod player_card;
|
||||||
pub use player_card::PlayerCard;
|
pub use player_card::PlayerCard;
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,16 @@ pub enum Date {
|
||||||
Date(chrono::NaiveDate),
|
Date(chrono::NaiveDate),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Date {
|
||||||
|
pub fn to_string(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Date::Year(y) => format!("{}", y),
|
||||||
|
Date::YearMonth(y, m) => format!("{}-{}", y, m),
|
||||||
|
Date::Date(date) => format!("{}-{}-{}", date.year(), date.month(), date.day()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
impl TryFrom<&str> for Date {
|
impl TryFrom<&str> for Date {
|
||||||
type Error = String;
|
type Error = String;
|
||||||
|
|
Loading…
Reference in New Issue