Construct a game preview component and render basic information into it

This commit is contained in:
Savanni D'Gerinel 2023-08-20 12:31:44 -04:00
parent a584fb4de3
commit e9ffab1187
5 changed files with 72 additions and 56 deletions

View File

@ -1,36 +1,45 @@
use serde::{Deserialize, Serialize};
use sgf::{
go::{Game, Rank},
Date,
};
use sgf::go::Game;
use typeshare::typeshare;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[typeshare]
pub struct GamePreviewElement {
pub date: Vec<Date>,
pub date: Vec<String>,
pub black_player: String,
pub black_rank: Option<Rank>,
pub white_player: String,
pub white_rank: Option<Rank>,
}
impl 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 {
date: game.info.date.clone(),
black_player: game
date: 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(),
.date
.iter()
.map(|dt| dt.to_string())
.collect::<Vec<String>>(),
black_player,
white_player,
}
}
}

View File

@ -3,7 +3,12 @@ use gtk::{glib, prelude::*, subclass::prelude::*};
use kifu_core::ui::GamePreviewElement;
#[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]
impl ObjectSubclass for GamePreviewPrivate {
@ -21,22 +26,23 @@ glib::wrapper! {
}
impl GamePreview {
pub fn new(element: GamePreviewElement) -> GamePreview {
pub fn new() -> 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(&gtk::Label::new(Some(&black_player)));
s.append(&gtk::Label::new(Some(&white_player)));
s.append(&s.imp().date);
s.append(&s.imp().title);
s.append(&s.imp().black_player);
s.append(&s.imp().white_player);
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);
}
}
}

View File

@ -1,3 +1,4 @@
use crate::ui::GamePreview;
use glib::Object;
use gtk::{glib, prelude::*, subclass::prelude::*};
use kifu_core::ui::GamePreviewElement;
@ -45,41 +46,31 @@ impl Default for GameDatabasePrivate {
let factory = gtk::SignalListItemFactory::new();
factory.connect_setup(move |_, list_item| {
let label = gtk::Label::new(Some("some kind of text"));
let preview = GamePreview::new();
list_item
.downcast_ref::<gtk::ListItem>()
.expect("Needs to be a ListItem")
.set_child(Some(&label));
.set_child(Some(&preview));
});
factory.connect_bind(move |_, list_item| {
let game_object = list_item
let game_element = list_item
.downcast_ref::<gtk::ListItem>()
.expect("Needs to be ListItem")
.item()
.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>()
.expect("Needs to be ListItem")
.child()
.and_downcast::<gtk::Label>()
.expect("The child has to be an Label.");
.and_downcast::<GamePreview>()
.expect("The child has to be a GamePreview object.");
label.set_label(
format!(
"{} vs. {}",
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(),
);
match game_element.game() {
Some(game) => preview.set_game(game),
None => (),
};
});
let selection_model = gtk::NoSelection::new(Some(model.clone()));

View File

@ -1,12 +1,12 @@
mod chat;
pub use chat::Chat;
mod game_database;
pub use game_database::GameDatabase;
mod game_preview;
pub use game_preview::GamePreview;
mod library;
pub use library::GameDatabase;
mod player_card;
pub use player_card::PlayerCard;

View File

@ -24,6 +24,16 @@ pub enum Date {
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 {
type Error = String;