Set up a configuration UI #66
|
@ -39,11 +39,16 @@ impl Database {
|
|||
.unwrap()
|
||||
.read_to_string(&mut buffer)
|
||||
.unwrap();
|
||||
for sgf in parse_sgf(&buffer).unwrap() {
|
||||
match sgf {
|
||||
Game::Go(game) => games.push(game),
|
||||
Game::Unsupported(_) => {}
|
||||
match parse_sgf(&buffer) {
|
||||
Ok(sgfs) => {
|
||||
for sgf in sgfs {
|
||||
match sgf {
|
||||
Game::Go(game) => games.push(game),
|
||||
Game::Unsupported(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => println!("Error parsing {:?}: {:?}", entry.path(), err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ impl GamePreviewElement {
|
|||
Some(GameResult::Draw) => "Draw".to_owned(),
|
||||
Some(GameResult::Black(ref win)) => format!("Black by {}", format_win(win)),
|
||||
Some(GameResult::White(ref win)) => format!("White by {}", format_win(win)),
|
||||
Some(GameResult::Unknown(ref text)) => format!("Unknown: {}", text),
|
||||
None => "".to_owned(),
|
||||
};
|
||||
|
||||
|
|
|
@ -2,19 +2,19 @@ use adw::prelude::*;
|
|||
use kifu_core::{CoreApp, CoreRequest, CoreResponse};
|
||||
use kifu_gtk::{
|
||||
perftrace,
|
||||
ui::{Home, PlayingField},
|
||||
ui::{Home, Layout, PlayingField},
|
||||
CoreApi,
|
||||
};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
fn handle_response(api: CoreApi, window: adw::ApplicationWindow, message: CoreResponse) {
|
||||
fn handle_response(api: CoreApi, layout: Layout, message: CoreResponse) {
|
||||
let playing_field = Arc::new(RwLock::new(None));
|
||||
match message {
|
||||
CoreResponse::HomeView(view) => perftrace("HomeView", || {
|
||||
let api = api.clone();
|
||||
|
||||
let home = Home::new(api, view);
|
||||
window.set_content(Some(&home));
|
||||
layout.set_content(&home);
|
||||
}),
|
||||
CoreResponse::PlayingFieldView(view) => perftrace("PlayingFieldView", || {
|
||||
let api = api.clone();
|
||||
|
@ -23,7 +23,7 @@ fn handle_response(api: CoreApi, window: adw::ApplicationWindow, message: CoreRe
|
|||
if playing_field.is_none() {
|
||||
perftrace("creating a new playing field", || {
|
||||
let field = PlayingField::new(api, view);
|
||||
window.set_content(Some(&field));
|
||||
layout.set_content(&field);
|
||||
*playing_field = Some(field);
|
||||
})
|
||||
} else {
|
||||
|
@ -101,13 +101,17 @@ fn main() {
|
|||
.width_request(800)
|
||||
.height_request(500)
|
||||
.build();
|
||||
|
||||
let layout = Layout::new();
|
||||
window.set_content(Some(&layout));
|
||||
|
||||
window.present();
|
||||
|
||||
gtk_rx.attach(None, {
|
||||
let api = api.clone();
|
||||
move |message| {
|
||||
perftrace("handle_response", || {
|
||||
handle_response(api.clone(), window.clone(), message)
|
||||
handle_response(api.clone(), layout.clone(), message)
|
||||
});
|
||||
Continue(true)
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ impl GamePreview {
|
|||
let s: Self = Object::builder().build();
|
||||
s.set_orientation(gtk::Orientation::Horizontal);
|
||||
s.set_homogeneous(true);
|
||||
s.set_hexpand(true);
|
||||
s.set_hexpand(false);
|
||||
|
||||
s.append(&s.imp().date);
|
||||
s.append(&s.imp().title);
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
use glib::Object;
|
||||
use gtk::{prelude::*, subclass::prelude::*};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
// Deprecated even from day 1. We want to use ToolbarView as soon as it's available in the versions
|
||||
// of Libadwaita available in NixOS.
|
||||
pub struct LayoutPrivate {
|
||||
pub header: adw::HeaderBar,
|
||||
pub content: Rc<RefCell<gtk::Widget>>,
|
||||
}
|
||||
|
||||
impl Default for LayoutPrivate {
|
||||
fn default() -> Self {
|
||||
let header = adw::HeaderBar::builder()
|
||||
.title_widget(>k::Label::new(Some("Placeholder Title")))
|
||||
.show_start_title_buttons(true)
|
||||
.show_end_title_buttons(true)
|
||||
.build();
|
||||
let content = adw::StatusPage::builder().title("Nothing here").build();
|
||||
|
||||
Self {
|
||||
header,
|
||||
content: Rc::new(RefCell::new(content.into())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for LayoutPrivate {
|
||||
const NAME: &'static str = "Layout";
|
||||
type Type = Layout;
|
||||
type ParentType = gtk::Box;
|
||||
}
|
||||
|
||||
impl ObjectImpl for LayoutPrivate {}
|
||||
impl WidgetImpl for LayoutPrivate {}
|
||||
impl BoxImpl for LayoutPrivate {}
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct Layout(ObjectSubclass<LayoutPrivate>) @extends gtk::Box, gtk::Widget, @implements gtk::Orientable;
|
||||
}
|
||||
|
||||
impl Layout {
|
||||
pub fn new() -> Self {
|
||||
let s: Self = Object::builder().build();
|
||||
s.set_orientation(gtk::Orientation::Vertical);
|
||||
s.set_homogeneous(false);
|
||||
s.append(&s.imp().header);
|
||||
s.append(&*s.imp().content.borrow());
|
||||
|
||||
s
|
||||
}
|
||||
|
||||
pub fn set_content(&self, content: &impl IsA<gtk::Widget>) {
|
||||
let mut widget = self.imp().content.borrow_mut();
|
||||
|
||||
self.remove(&*widget);
|
||||
*widget = content.clone().upcast::<gtk::Widget>();
|
||||
self.append(&*widget);
|
||||
}
|
||||
}
|
|
@ -7,6 +7,9 @@ pub use game_preview::GamePreview;
|
|||
mod library;
|
||||
pub use library::Library;
|
||||
|
||||
mod layout;
|
||||
pub use layout::Layout;
|
||||
|
||||
mod player_card;
|
||||
pub use player_card::PlayerCard;
|
||||
|
||||
|
|
|
@ -242,6 +242,7 @@ pub enum GameResult {
|
|||
Draw,
|
||||
Black(Win),
|
||||
White(Win),
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for GameResult {
|
||||
|
@ -256,7 +257,7 @@ impl TryFrom<&str> for GameResult {
|
|||
let res = match parts[0].to_ascii_lowercase().as_str() {
|
||||
"b" => GameResult::Black,
|
||||
"w" => GameResult::White,
|
||||
_ => panic!("unknown result format"),
|
||||
_ => return Ok(GameResult::Unknown(parts[0].to_owned())),
|
||||
};
|
||||
match parts[1].to_ascii_lowercase().as_str() {
|
||||
"r" | "resign" => Ok(res(Win::Resignation)),
|
||||
|
|
Loading…
Reference in New Issue