Render the playing field #35

Merged
savanni merged 3 commits from feature/kifu-render-playing-area into main 2023-03-25 03:59:22 +00:00
11 changed files with 190 additions and 24 deletions

View File

@ -1,11 +1,6 @@
use crate::types::AppState; use crate::types::AppState;
use crate::ui::playing_field::{playing_field, PlayingFieldView}; use crate::ui::{playing_field, PlayingFieldView};
use std::{ use std::sync::{Arc, RwLock};
sync::{Arc, RwLock},
thread,
time::Duration,
};
use tokio::sync::mpsc::{channel, Receiver, Sender};
pub enum Request { pub enum Request {
PlayingField, PlayingField,

View File

@ -4,5 +4,5 @@ mod api;
pub use api::{CoreApp, Request, Response}; pub use api::{CoreApp, Request, Response};
mod types; mod types;
pub use types::Color; pub use types::{Color, Size};
pub mod ui; pub mod ui;

View File

@ -6,6 +6,12 @@ pub enum Color {
White, White,
} }
#[derive(Clone, Debug)]
pub struct Size {
pub width: u8,
pub height: u8,
}
pub(crate) struct AppState { pub(crate) struct AppState {
game: Option<GameState>, game: Option<GameState>,
} }

View File

@ -1,4 +1,5 @@
pub mod playing_field; mod playing_field;
pub use playing_field::{playing_field, PlayingFieldView};
mod types; mod types;
pub use types::{ChatElement, PlayerCardElement}; pub use types::{ChatElement, GameBoardElement, PlayerCardElement, TextFieldElement};

View File

@ -1,4 +1,4 @@
use crate::types::Color; use crate::types::{Color, Size};
use crate::ui::types; use crate::ui::types;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -16,7 +16,7 @@ pub fn playing_field() -> PlayingFieldView {
(0..19).for_each(|_| spaces.push(Vec::new())); (0..19).for_each(|_| spaces.push(Vec::new()));
let board = types::GameBoardElement { let board = types::GameBoardElement {
size: types::Size { size: Size {
width: 19, width: 19,
height: 19, height: 19,
}, },

View File

@ -1,4 +1,4 @@
use crate::types::Color; use crate::types::{Color, Size};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Jitter { pub struct Jitter {
@ -6,12 +6,6 @@ pub struct Jitter {
pub y: i8, pub y: i8,
} }
#[derive(Clone, Debug)]
pub struct Size {
pub width: u8,
pub height: u8,
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct StoneElement { pub struct StoneElement {
pub color: Color, pub color: Color,

View File

@ -3,6 +3,9 @@ name = "kifu-gtk"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[features]
screenplay = []
# 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]
@ -16,3 +19,8 @@ screenplay = { path = "../../screenplay" }
[[bin]] [[bin]]
name = "kifu-gtk" name = "kifu-gtk"
path = "src/main.rs" path = "src/main.rs"
[[bin]]
name = "screenplay"
path = "src/bin/screenplay.rs"
required-features = [ "screenplay" ]

View File

@ -1,9 +1,10 @@
use glib::Object;
use gtk::{prelude::*, subclass::prelude::*}; use gtk::{prelude::*, subclass::prelude::*};
use kifu_core::{ui::ChatElement, ui::PlayerCardElement, Color}; use kifu_core::{
use kifu_gtk::ui::{Chat, PlayerCard}; ui::{ChatElement, PlayerCardElement, PlayingFieldView},
Color,
};
use kifu_gtk::ui::{playing_field_view, Chat, PlayerCard, PlayingField};
use screenplay::{Screen, Screenplay}; use screenplay::{Screen, Screenplay};
use std::{cell::RefCell, rc::Rc};
fn main() { fn main() {
let app = gtk::Application::builder() let app = gtk::Application::builder()
@ -35,8 +36,13 @@ fn main() {
.upcast::<gtk::Widget>(), .upcast::<gtk::Widget>(),
adjustments: vec![], adjustments: vec![],
}, },
Screen {
title: "PlayingField".to_owned(),
widget: PlayingField::new(playing_field_view()).upcast::<gtk::Widget>(),
adjustments: vec![],
},
]; ];
let screenplay = Screenplay::new(&app, screens).unwrap(); Screenplay::new(&app, screens).unwrap();
}); });
app.run(); app.run();

View File

@ -0,0 +1,30 @@
use glib::Object;
use gtk::{prelude::*, subclass::prelude::*};
#[derive(Default)]
pub struct GobanPrivate;
#[glib::object_subclass]
impl ObjectSubclass for GobanPrivate {
const NAME: &'static str = "Goban";
type Type = Goban;
type ParentType = gtk::DrawingArea;
}
impl ObjectImpl for GobanPrivate {}
impl WidgetImpl for GobanPrivate {}
impl DrawingAreaImpl for GobanPrivate {}
glib::wrapper! {
pub struct Goban(ObjectSubclass<GobanPrivate>) @extends gtk::DrawingArea, gtk::Widget;
}
impl Goban {
pub fn new() -> Self {
let s: Self = Object::builder().build();
s.set_width_request(1024);
s.set_height_request(768);
s
}
}

View File

@ -3,3 +3,12 @@ pub use player_card::PlayerCard;
mod chat; mod chat;
pub use chat::Chat; pub use chat::Chat;
mod playing_field;
pub use playing_field::PlayingField;
mod goban;
pub use goban::Goban;
#[cfg(feature = "screenplay")]
pub use playing_field::playing_field_view;

View File

@ -0,0 +1,117 @@
use crate::ui::{Chat, Goban, PlayerCard};
use glib::Object;
use gtk::{prelude::*, subclass::prelude::*};
use kifu_core::{
ui::{ChatElement, GameBoardElement, PlayerCardElement, PlayingFieldView, TextFieldElement},
Color, Size,
};
use std::{cell::RefCell, rc::Rc};
/*
#[derive(Clone, Debug)]
pub struct PlayingFieldView {
pub board: types::GameBoardElement,
pub player_card_black: types::PlayerCardElement,
pub player_card_white: types::PlayerCardElement,
pub chat: types::ChatElement,
pub message: types::TextFieldElement,
pub current_player: Color,
}
*/
#[derive(Default)]
pub struct PlayingFieldPrivate {
player_card_white: Rc<RefCell<Option<PlayerCard>>>,
player_card_black: Rc<RefCell<Option<PlayerCard>>>,
chat: Rc<RefCell<Option<Chat>>>,
}
#[glib::object_subclass]
impl ObjectSubclass for PlayingFieldPrivate {
const NAME: &'static str = "PlayingField";
type Type = PlayingField;
type ParentType = gtk::Grid;
fn new() -> Self {
Self {
player_card_white: Rc::new(RefCell::new(None)),
player_card_black: Rc::new(RefCell::new(None)),
chat: Rc::new(RefCell::new(None)),
}
}
}
impl ObjectImpl for PlayingFieldPrivate {}
impl WidgetImpl for PlayingFieldPrivate {}
impl GridImpl for PlayingFieldPrivate {}
glib::wrapper! {
pub struct PlayingField(ObjectSubclass<PlayingFieldPrivate>) @extends gtk::Grid, gtk::Widget;
}
impl PlayingField {
pub fn new(view: PlayingFieldView) -> PlayingField {
let s: Self = Object::builder().build();
let goban = Goban::new();
let player_card_white = PlayerCard::new(view.player_card_white);
let player_card_black = PlayerCard::new(view.player_card_black);
let chat = Chat::new(view.chat);
s.attach(&goban, 1, 1, 1, 2);
s.attach(&player_card_black, 2, 1, 1, 1);
s.attach(&player_card_white, 3, 1, 1, 1);
s.attach(&chat, 2, 2, 2, 1);
*s.imp().player_card_white.borrow_mut() = Some(player_card_white);
*s.imp().player_card_black.borrow_mut() = Some(player_card_black);
*s.imp().chat.borrow_mut() = Some(chat);
s
}
}
#[cfg(feature = "screenplay")]
pub fn playing_field_view() -> PlayingFieldView {
let mut spaces = Vec::new();
(0..19).for_each(|_| spaces.push(Vec::new()));
let board = GameBoardElement {
size: Size {
width: 19,
height: 19,
},
spaces,
};
let player_card_black = PlayerCardElement {
color: Color::Black,
name: "Savanni".to_owned(),
rank: "10k".to_owned(),
clock: "24:53".to_owned(),
};
let player_card_white = PlayerCardElement {
color: Color::White,
name: "Opal".to_owned(),
rank: "10k".to_owned(),
clock: "25:00".to_owned(),
};
let chat = ChatElement {
messages: vec![
"[22:05] Savanni: oops".to_owned(),
"[22:06] Opal: you know I'll take advantage of that, right?".to_owned(),
],
};
let message = TextFieldElement {};
PlayingFieldView {
board,
player_card_black,
player_card_white,
chat,
message,
current_player: Color::White,
}
}