From b6b85a7add5fad8863431b037be43194478ded01 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Wed, 22 Mar 2023 18:17:35 -0400 Subject: [PATCH] Add the chat area --- kifu/kifu-core/src/ui/mod.rs | 2 +- kifu/kifu-gtk/Cargo.toml | 4 ++ kifu/kifu-gtk/src/bin/screenplay.rs | 75 +++++++++--------------- kifu/kifu-gtk/src/lib.rs | 1 + kifu/kifu-gtk/src/ui/mod.rs | 88 +++++++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 49 deletions(-) create mode 100644 kifu/kifu-gtk/src/lib.rs create mode 100644 kifu/kifu-gtk/src/ui/mod.rs diff --git a/kifu/kifu-core/src/ui/mod.rs b/kifu/kifu-core/src/ui/mod.rs index 76ac480..7b1eba3 100644 --- a/kifu/kifu-core/src/ui/mod.rs +++ b/kifu/kifu-core/src/ui/mod.rs @@ -1,4 +1,4 @@ pub mod playing_field; mod types; -pub use types::PlayerCardElement; +pub use types::{ChatElement, PlayerCardElement}; diff --git a/kifu/kifu-gtk/Cargo.toml b/kifu/kifu-gtk/Cargo.toml index 0805e7f..4e9d149 100644 --- a/kifu/kifu-gtk/Cargo.toml +++ b/kifu/kifu-gtk/Cargo.toml @@ -12,3 +12,7 @@ gtk = { version = "0.6", package = "gtk4" } kifu-core = { path = "../kifu-core" } tokio = { version = "1.26", features = [ "full" ] } screenplay = { path = "../../screenplay" } + +[[bin]] +name = "kifu-gtk" +path = "src/main.rs" diff --git a/kifu/kifu-gtk/src/bin/screenplay.rs b/kifu/kifu-gtk/src/bin/screenplay.rs index d2ac680..ad3a4d0 100644 --- a/kifu/kifu-gtk/src/bin/screenplay.rs +++ b/kifu/kifu-gtk/src/bin/screenplay.rs @@ -1,62 +1,41 @@ use glib::Object; use gtk::{prelude::*, subclass::prelude::*}; -use kifu_core::{ui::PlayerCardElement, Color}; +use kifu_core::{ui::ChatElement, ui::PlayerCardElement, Color}; +use kifu_gtk::ui::{Chat, PlayerCard}; use screenplay::{Screen, Screenplay}; use std::{cell::RefCell, rc::Rc}; -#[derive(Default)] -pub struct PlayerCardPrivate { - player_name: gtk::Label, - clock: gtk::Label, -} - -#[glib::object_subclass] -impl ObjectSubclass for PlayerCardPrivate { - const NAME: &'static str = "PlayerCard"; - type Type = PlayerCard; - type ParentType = gtk::Box; -} - -impl ObjectImpl for PlayerCardPrivate {} -impl WidgetImpl for PlayerCardPrivate {} -impl BoxImpl for PlayerCardPrivate {} - -glib::wrapper! { - pub struct PlayerCard(ObjectSubclass) @extends gtk::Box, gtk::Widget, @implements gtk::Orientable; -} - -impl PlayerCard { - pub fn new(element: PlayerCardElement) -> PlayerCard { - let s: Self = Object::builder().build(); - s.set_orientation(gtk::Orientation::Vertical); - s.imp() - .player_name - .set_text(&format!("{} ({})", element.name, element.rank)); - s.imp().clock.set_text(&element.clock); - - s.append(&s.imp().player_name); - s.append(&s.imp().clock); - s - } -} - fn main() { let app = gtk::Application::builder() .application_id("com.luminescent-dreams.kifu-gtk.screenplay") .build(); app.connect_activate(|app| { - let screens = vec![Screen { - title: "PlayerCard".to_owned(), - widget: PlayerCard::new(PlayerCardElement { - color: Color::Black, - name: "Opal".to_owned(), - rank: "10 kyu".to_owned(), - clock: "25:00".to_owned(), - }) - .upcast::(), - adjustments: vec![], - }]; + let screens = vec![ + Screen { + title: "PlayerCard".to_owned(), + widget: PlayerCard::new(PlayerCardElement { + color: Color::Black, + name: "Opal".to_owned(), + rank: "10 kyu".to_owned(), + clock: "25:00".to_owned(), + }) + .upcast::(), + adjustments: vec![], + }, + Screen { + title: "ChatArea".to_owned(), + widget: Chat::new(ChatElement { + messages: vec![ + "message 1".to_owned(), + "message 2".to_owned(), + "message 3".to_owned(), + ], + }) + .upcast::(), + adjustments: vec![], + }, + ]; let screenplay = Screenplay::new(&app, screens).unwrap(); }); diff --git a/kifu/kifu-gtk/src/lib.rs b/kifu/kifu-gtk/src/lib.rs new file mode 100644 index 0000000..6bae95d --- /dev/null +++ b/kifu/kifu-gtk/src/lib.rs @@ -0,0 +1 @@ +pub mod ui; diff --git a/kifu/kifu-gtk/src/ui/mod.rs b/kifu/kifu-gtk/src/ui/mod.rs new file mode 100644 index 0000000..a6e992c --- /dev/null +++ b/kifu/kifu-gtk/src/ui/mod.rs @@ -0,0 +1,88 @@ +use crate::ui; +use glib::Object; +use gtk::{prelude::*, subclass::prelude::*}; +use kifu_core::{ui::ChatElement, ui::PlayerCardElement, Color}; +use std::{cell::RefCell, rc::Rc}; + +#[derive(Default)] +pub struct PlayerCardPrivate { + player_name: gtk::Label, + clock: gtk::Label, +} + +#[glib::object_subclass] +impl ObjectSubclass for PlayerCardPrivate { + const NAME: &'static str = "PlayerCard"; + type Type = PlayerCard; + type ParentType = gtk::Box; +} + +impl ObjectImpl for PlayerCardPrivate {} +impl WidgetImpl for PlayerCardPrivate {} +impl BoxImpl for PlayerCardPrivate {} + +glib::wrapper! { + pub struct PlayerCard(ObjectSubclass) @extends gtk::Box, gtk::Widget, @implements gtk::Orientable; +} + +impl PlayerCard { + pub fn new(element: PlayerCardElement) -> PlayerCard { + let s: Self = Object::builder().build(); + s.set_orientation(gtk::Orientation::Vertical); + s.imp() + .player_name + .set_text(&format!("{} ({})", element.name, element.rank)); + s.imp().clock.set_text(&element.clock); + + s.append(&s.imp().player_name); + s.append(&s.imp().clock); + s + } +} + +#[derive(Default)] +pub struct ChatPrivate { + chat_history: gtk::Box, + entry: gtk::Entry, +} + +#[glib::object_subclass] +impl ObjectSubclass for ChatPrivate { + const NAME: &'static str = "Chat"; + type Type = Chat; + type ParentType = gtk::Box; +} + +impl ObjectImpl for ChatPrivate { + fn constructed(&self) { + self.chat_history + .set_orientation(gtk::Orientation::Vertical); + } +} +impl WidgetImpl for ChatPrivate {} +impl BoxImpl for ChatPrivate {} + +glib::wrapper! { + pub struct Chat(ObjectSubclass) @extends gtk::Box, gtk::Widget, @implements gtk::Orientable; +} + +impl Chat { + pub fn new(element: ChatElement) -> Chat { + let s: Self = Object::builder().build(); + s.set_orientation(gtk::Orientation::Vertical); + + s.append(&s.imp().chat_history); + s.append(&s.imp().entry); + + element.messages.into_iter().for_each(|msg| { + s.imp().chat_history.append( + >k::Label::builder() + .label(&msg) + .halign(gtk::Align::Start) + .build(), + ) + }); + + s + } +}