diff --git a/kifu/kifu-core/src/api.rs b/kifu/kifu-core/src/api.rs index 6f389ed..eb90866 100644 --- a/kifu/kifu-core/src/api.rs +++ b/kifu/kifu-core/src/api.rs @@ -1,11 +1,6 @@ use crate::types::AppState; -use crate::ui::playing_field::{playing_field, PlayingFieldView}; -use std::{ - sync::{Arc, RwLock}, - thread, - time::Duration, -}; -use tokio::sync::mpsc::{channel, Receiver, Sender}; +use crate::ui::{playing_field, PlayingFieldView}; +use std::sync::{Arc, RwLock}; pub enum Request { PlayingField, diff --git a/kifu/kifu-core/src/lib.rs b/kifu/kifu-core/src/lib.rs index 46f29ba..a13d2c8 100644 --- a/kifu/kifu-core/src/lib.rs +++ b/kifu/kifu-core/src/lib.rs @@ -4,5 +4,5 @@ mod api; pub use api::{CoreApp, Request, Response}; mod types; -pub use types::Color; +pub use types::{Color, Size}; pub mod ui; diff --git a/kifu/kifu-core/src/types.rs b/kifu/kifu-core/src/types.rs index 8d2fec7..a15f37e 100644 --- a/kifu/kifu-core/src/types.rs +++ b/kifu/kifu-core/src/types.rs @@ -6,6 +6,12 @@ pub enum Color { White, } +#[derive(Clone, Debug)] +pub struct Size { + pub width: u8, + pub height: u8, +} + pub(crate) struct AppState { game: Option, } diff --git a/kifu/kifu-core/src/ui/mod.rs b/kifu/kifu-core/src/ui/mod.rs index 7b1eba3..1948529 100644 --- a/kifu/kifu-core/src/ui/mod.rs +++ b/kifu/kifu-core/src/ui/mod.rs @@ -1,4 +1,5 @@ -pub mod playing_field; +mod playing_field; +pub use playing_field::{playing_field, PlayingFieldView}; mod types; -pub use types::{ChatElement, PlayerCardElement}; +pub use types::{ChatElement, GameBoardElement, PlayerCardElement, TextFieldElement}; diff --git a/kifu/kifu-core/src/ui/playing_field.rs b/kifu/kifu-core/src/ui/playing_field.rs index ea97ea5..437e07c 100644 --- a/kifu/kifu-core/src/ui/playing_field.rs +++ b/kifu/kifu-core/src/ui/playing_field.rs @@ -1,4 +1,4 @@ -use crate::types::Color; +use crate::types::{Color, Size}; use crate::ui::types; #[derive(Clone, Debug)] @@ -16,7 +16,7 @@ pub fn playing_field() -> PlayingFieldView { (0..19).for_each(|_| spaces.push(Vec::new())); let board = types::GameBoardElement { - size: types::Size { + size: Size { width: 19, height: 19, }, diff --git a/kifu/kifu-core/src/ui/types.rs b/kifu/kifu-core/src/ui/types.rs index a0727ad..cb6b690 100644 --- a/kifu/kifu-core/src/ui/types.rs +++ b/kifu/kifu-core/src/ui/types.rs @@ -1,4 +1,4 @@ -use crate::types::Color; +use crate::types::{Color, Size}; #[derive(Clone, Debug)] pub struct Jitter { @@ -6,12 +6,6 @@ pub struct Jitter { pub y: i8, } -#[derive(Clone, Debug)] -pub struct Size { - pub width: u8, - pub height: u8, -} - #[derive(Clone, Debug)] pub struct StoneElement { pub color: Color, diff --git a/kifu/kifu-gtk/Cargo.toml b/kifu/kifu-gtk/Cargo.toml index 4e9d149..1f7487f 100644 --- a/kifu/kifu-gtk/Cargo.toml +++ b/kifu/kifu-gtk/Cargo.toml @@ -3,6 +3,9 @@ name = "kifu-gtk" version = "0.1.0" edition = "2021" +[features] +screenplay = [] + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] @@ -16,3 +19,8 @@ screenplay = { path = "../../screenplay" } [[bin]] name = "kifu-gtk" path = "src/main.rs" + +[[bin]] +name = "screenplay" +path = "src/bin/screenplay.rs" +required-features = [ "screenplay" ] diff --git a/kifu/kifu-gtk/src/bin/screenplay.rs b/kifu/kifu-gtk/src/bin/screenplay.rs index ad3a4d0..28f16cb 100644 --- a/kifu/kifu-gtk/src/bin/screenplay.rs +++ b/kifu/kifu-gtk/src/bin/screenplay.rs @@ -1,9 +1,10 @@ -use glib::Object; use gtk::{prelude::*, subclass::prelude::*}; -use kifu_core::{ui::ChatElement, ui::PlayerCardElement, Color}; -use kifu_gtk::ui::{Chat, PlayerCard}; +use kifu_core::{ + ui::{ChatElement, PlayerCardElement, PlayingFieldView}, + Color, +}; +use kifu_gtk::ui::{playing_field_view, Chat, PlayerCard, PlayingField}; use screenplay::{Screen, Screenplay}; -use std::{cell::RefCell, rc::Rc}; fn main() { let app = gtk::Application::builder() @@ -35,8 +36,13 @@ fn main() { .upcast::(), adjustments: vec![], }, + Screen { + title: "PlayingField".to_owned(), + widget: PlayingField::new(playing_field_view()).upcast::(), + adjustments: vec![], + }, ]; - let screenplay = Screenplay::new(&app, screens).unwrap(); + Screenplay::new(&app, screens).unwrap(); }); app.run(); diff --git a/kifu/kifu-gtk/src/ui/goban.rs b/kifu/kifu-gtk/src/ui/goban.rs new file mode 100644 index 0000000..6c30670 --- /dev/null +++ b/kifu/kifu-gtk/src/ui/goban.rs @@ -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) @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 + } +} diff --git a/kifu/kifu-gtk/src/ui/mod.rs b/kifu/kifu-gtk/src/ui/mod.rs index fe589f6..49630c7 100644 --- a/kifu/kifu-gtk/src/ui/mod.rs +++ b/kifu/kifu-gtk/src/ui/mod.rs @@ -3,3 +3,12 @@ pub use player_card::PlayerCard; mod 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; diff --git a/kifu/kifu-gtk/src/ui/playing_field.rs b/kifu/kifu-gtk/src/ui/playing_field.rs new file mode 100644 index 0000000..0dc4be6 --- /dev/null +++ b/kifu/kifu-gtk/src/ui/playing_field.rs @@ -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>>, + player_card_black: Rc>>, + chat: Rc>>, +} + +#[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) @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, + } +}