From cc828c417af2d93fae9335bf81b81b45c4a3fcf1 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Thu, 24 Aug 2023 21:56:03 -0400 Subject: [PATCH 1/4] Change the layout/app_window to an ordinary object with necessary objects --- kifu/gtk/src/main.rs | 23 +++++-------- kifu/gtk/src/ui/layout.rs | 71 --------------------------------------- kifu/gtk/src/ui/mod.rs | 58 ++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 86 deletions(-) delete mode 100644 kifu/gtk/src/ui/layout.rs diff --git a/kifu/gtk/src/main.rs b/kifu/gtk/src/main.rs index 3217134..614b1dc 100644 --- a/kifu/gtk/src/main.rs +++ b/kifu/gtk/src/main.rs @@ -2,12 +2,12 @@ use adw::prelude::*; use kifu_core::{CoreApp, CoreRequest, CoreResponse}; use kifu_gtk::{ perftrace, - ui::{ConfigurationPage, Home, Layout, PlayingField}, + ui::{AppWindow, ConfigurationPage, Home, PlayingField}, CoreApi, }; use std::sync::{Arc, RwLock}; -fn handle_response(api: CoreApi, layout: Layout, message: CoreResponse) { +fn handle_response(api: CoreApi, app_window: &AppWindow, message: CoreResponse) { let playing_field = Arc::new(RwLock::new(None)); match message { CoreResponse::ConfigurationView(view) => perftrace("ConfigurationView", || { @@ -22,7 +22,7 @@ fn handle_response(api: CoreApi, layout: Layout, message: CoreResponse) { let api = api.clone(); let home = Home::new(api, view); - layout.set_content(&home); + app_window.set_content(&home); }), CoreResponse::PlayingFieldView(view) => perftrace("PlayingFieldView", || { let api = api.clone(); @@ -31,7 +31,7 @@ fn handle_response(api: CoreApi, layout: Layout, message: CoreResponse) { if playing_field.is_none() { perftrace("creating a new playing field", || { let field = PlayingField::new(api, view); - layout.set_content(&field); + app_window.set_content(&field); *playing_field = Some(field); }) } else { @@ -87,6 +87,8 @@ fn main() { let (gtk_tx, gtk_rx) = gtk::glib::MainContext::channel::(gtk::glib::PRIORITY_DEFAULT); + let app_window = AppWindow::new(&app); + let api = CoreApi { gtk_tx, rt: runtime.clone(), @@ -102,22 +104,13 @@ fn main() { }); app.add_action(&action_config); - let window = adw::ApplicationWindow::builder() - .application(app) - .width_request(800) - .height_request(500) - .build(); - - let layout = Layout::new(); - window.set_content(Some(&layout)); - - window.present(); + app_window.window.present(); gtk_rx.attach(None, { let api = api.clone(); move |message| { perftrace("handle_response", || { - handle_response(api.clone(), layout.clone(), message) + handle_response(api.clone(), &app_window, message) }); Continue(true) } diff --git a/kifu/gtk/src/ui/layout.rs b/kifu/gtk/src/ui/layout.rs deleted file mode 100644 index 5057bfc..0000000 --- a/kifu/gtk/src/ui/layout.rs +++ /dev/null @@ -1,71 +0,0 @@ -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>, -} - -impl Default for LayoutPrivate { - fn default() -> Self { - let header = adw::HeaderBar::builder() - .title_widget(>k::Label::new(Some("Kifu"))) - .build(); - - let app_menu = gio::Menu::new(); - let menu_item = gio::MenuItem::new(Some("Configuration"), Some("app.show-config")); - app_menu.append_item(&menu_item); - - let hamburger = gtk::MenuButton::builder() - .icon_name("open-menu-symbolic") - .build(); - hamburger.set_menu_model(Some(&app_menu)); - - header.pack_end(&hamburger); - - 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) @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) { - let mut widget = self.imp().content.borrow_mut(); - - self.remove(&*widget); - *widget = content.clone().upcast::(); - self.append(&*widget); - } -} diff --git a/kifu/gtk/src/ui/mod.rs b/kifu/gtk/src/ui/mod.rs index de1c5fe..30cd24d 100644 --- a/kifu/gtk/src/ui/mod.rs +++ b/kifu/gtk/src/ui/mod.rs @@ -1,3 +1,7 @@ +use adw::prelude::*; +use glib::IsA; +use gtk::prelude::*; + mod chat; pub use chat::Chat; @@ -27,3 +31,57 @@ pub use board::Board; #[cfg(feature = "screenplay")] pub use playing_field::playing_field_view; + +pub struct AppWindow { + pub window: adw::ApplicationWindow, + pub header: adw::HeaderBar, + pub content: adw::Bin, +} + +impl AppWindow { + pub fn new(app: &adw::Application) -> Self { + let header = adw::HeaderBar::builder() + .title_widget(>k::Label::new(Some("Kifu"))) + .build(); + + let app_menu = gio::Menu::new(); + let menu_item = gio::MenuItem::new(Some("Configuration"), Some("app.show-config")); + app_menu.append_item(&menu_item); + + let hamburger = gtk::MenuButton::builder() + .icon_name("open-menu-symbolic") + .build(); + hamburger.set_menu_model(Some(&app_menu)); + + header.pack_end(&hamburger); + + let content = adw::Bin::new(); + content.set_child(Some( + &adw::StatusPage::builder().title("Nothing here").build(), + )); + + let layout = gtk::Box::builder() + .orientation(gtk::Orientation::Vertical) + .build(); + layout.append(&header); + layout.append(&content); + + let window = adw::ApplicationWindow::builder() + .application(app) + .width_request(800) + .height_request(500) + .build(); + + window.set_content(Some(&layout)); + + Self { + window, + header, + content, + } + } + + pub fn set_content(&self, content: &impl IsA) { + self.content.set_child(Some(content)); + } +} -- 2.44.1 From 16c8dcb682cdc7cb104ea2a5ee26d16dd7fd00da Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Thu, 24 Aug 2023 22:10:05 -0400 Subject: [PATCH 2/4] Add a CSS stylesheet --- kifu/gtk/build.rs | 2 +- ...esources.gresources.xml => gresources.xml} | 1 + kifu/gtk/resources/style.css | 1 + kifu/gtk/src/ui/mod.rs | 33 +++++++++++++------ 4 files changed, 26 insertions(+), 11 deletions(-) rename kifu/gtk/resources/{resources.gresources.xml => gresources.xml} (85%) create mode 100644 kifu/gtk/resources/style.css diff --git a/kifu/gtk/build.rs b/kifu/gtk/build.rs index 18b1e1e..6e5a750 100644 --- a/kifu/gtk/build.rs +++ b/kifu/gtk/build.rs @@ -1,7 +1,7 @@ fn main() { glib_build_tools::compile_resources( &["resources"], - "resources/resources.gresources.xml", + "resources/gresources.xml", "com.luminescent-dreams.kifu-gtk.gresource", ); } diff --git a/kifu/gtk/resources/resources.gresources.xml b/kifu/gtk/resources/gresources.xml similarity index 85% rename from kifu/gtk/resources/resources.gresources.xml rename to kifu/gtk/resources/gresources.xml index 31ca0a0..557a5ba 100644 --- a/kifu/gtk/resources/resources.gresources.xml +++ b/kifu/gtk/resources/gresources.xml @@ -2,5 +2,6 @@ wood_texture.jpg + style.css diff --git a/kifu/gtk/resources/style.css b/kifu/gtk/resources/style.css new file mode 100644 index 0000000..c8af75c --- /dev/null +++ b/kifu/gtk/resources/style.css @@ -0,0 +1 @@ +@define_color accent_color: @purple_5; diff --git a/kifu/gtk/src/ui/mod.rs b/kifu/gtk/src/ui/mod.rs index 30cd24d..c1f1034 100644 --- a/kifu/gtk/src/ui/mod.rs +++ b/kifu/gtk/src/ui/mod.rs @@ -1,6 +1,7 @@ use adw::prelude::*; +use gio::resources_lookup_data; use glib::IsA; -use gtk::prelude::*; +use gtk::{prelude::*, STYLE_PROVIDER_PRIORITY_USER}; mod chat; pub use chat::Chat; @@ -14,9 +15,6 @@ 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; @@ -40,6 +38,27 @@ pub struct AppWindow { impl AppWindow { pub fn new(app: &adw::Application) -> Self { + let window = adw::ApplicationWindow::builder() + .application(app) + .width_request(800) + .height_request(500) + .build(); + + let stylesheet = String::from_utf8( + resources_lookup_data( + "/com/luminescent-dreams/kifu-gtk/style.css", + gio::ResourceLookupFlags::NONE, + ) + .expect("stylesheet should just be available") + .to_vec(), + ) + .expect("to parse stylesheet"); + + let provider = gtk::CssProvider::new(); + provider.load_from_data(&stylesheet); + let content = window.style_context(); + content.add_provider(&provider, STYLE_PROVIDER_PRIORITY_USER); + let header = adw::HeaderBar::builder() .title_widget(>k::Label::new(Some("Kifu"))) .build(); @@ -66,12 +85,6 @@ impl AppWindow { layout.append(&header); layout.append(&content); - let window = adw::ApplicationWindow::builder() - .application(app) - .width_request(800) - .height_request(500) - .build(); - window.set_content(Some(&layout)); Self { -- 2.44.1 From 562d4871a179cdcf4291356437776627753cf80a Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Thu, 24 Aug 2023 22:33:36 -0400 Subject: [PATCH 3/4] Create padding within the content view --- kifu/gtk/resources/style.css | 4 +++- kifu/gtk/src/ui/home.rs | 5 ++++- kifu/gtk/src/ui/mod.rs | 6 +++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/kifu/gtk/resources/style.css b/kifu/gtk/resources/style.css index c8af75c..4282dcd 100644 --- a/kifu/gtk/resources/style.css +++ b/kifu/gtk/resources/style.css @@ -1 +1,3 @@ -@define_color accent_color: @purple_5; +.content { + padding: 8px; +} diff --git a/kifu/gtk/src/ui/home.rs b/kifu/gtk/src/ui/home.rs index c9a166b..daf0691 100644 --- a/kifu/gtk/src/ui/home.rs +++ b/kifu/gtk/src/ui/home.rs @@ -131,7 +131,10 @@ impl Home { players.append(&white_player); *s.imp().white_player.borrow_mut() = Some(white_player.clone()); - let new_game_button = gtk::Button::builder().label(&view.start_game.label).build(); + let new_game_button = gtk::Button::builder() + .css_classes(vec!["suggested-action"]) + .label(&view.start_game.label) + .build(); s.append(&new_game_button); let library = Library::new(); diff --git a/kifu/gtk/src/ui/mod.rs b/kifu/gtk/src/ui/mod.rs index c1f1034..5b5bfcd 100644 --- a/kifu/gtk/src/ui/mod.rs +++ b/kifu/gtk/src/ui/mod.rs @@ -56,8 +56,8 @@ impl AppWindow { let provider = gtk::CssProvider::new(); provider.load_from_data(&stylesheet); - let content = window.style_context(); - content.add_provider(&provider, STYLE_PROVIDER_PRIORITY_USER); + let context = window.style_context(); + context.add_provider(&provider, STYLE_PROVIDER_PRIORITY_USER); let header = adw::HeaderBar::builder() .title_widget(>k::Label::new(Some("Kifu"))) @@ -74,7 +74,7 @@ impl AppWindow { header.pack_end(&hamburger); - let content = adw::Bin::new(); + let content = adw::Bin::builder().css_classes(vec!["content"]).build(); content.set_child(Some( &adw::StatusPage::builder().title("Nothing here").build(), )); -- 2.44.1 From 14891218776392403c0d279330a5a75ec7c5b6f3 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Fri, 25 Aug 2023 00:07:29 -0400 Subject: [PATCH 4/4] Get the width of the application back under control --- Cargo.lock | 60 +++++++++++++++++---------------- kifu/gtk/Cargo.toml | 6 ++-- kifu/gtk/config | 2 +- kifu/gtk/src/ui/library.rs | 69 +++++++++++++++++++++++++++++++++----- 4 files changed, 96 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1967a17..d933eae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -55,9 +55,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -158,9 +158,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "libc", ] @@ -427,9 +427,9 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] @@ -803,9 +803,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "gio" @@ -1051,9 +1051,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ "bytes", "fnv", @@ -1349,6 +1349,7 @@ dependencies = [ "image", "kifu-core", "libadwaita", + "pango", "sgf", "tokio", ] @@ -1577,9 +1578,9 @@ dependencies = [ [[package]] name = "object" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" dependencies = [ "memchr", ] @@ -1987,9 +1988,9 @@ checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ "base64", "bytes", @@ -2133,18 +2134,18 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.183" +version = "1.0.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" +checksum = "9f5db24220c009de9bd45e69fb2938f4b6d2df856aa9304ce377b3180f83b7c1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.183" +version = "1.0.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" +checksum = "5ad697f7e0b65af4983a4ce8f56ed5b357e8d3c36651bf6a7e13639c17b8e670" dependencies = [ "proc-macro2", "quote", @@ -2211,15 +2212,15 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "siphasher" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] @@ -2840,20 +2841,21 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d09770118a7eb1ccaf4a594a221334119a44a814fcb0d31c5b85e83e97227a97" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" dependencies = [ "memchr", ] [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys", ] [[package]] diff --git a/kifu/gtk/Cargo.toml b/kifu/gtk/Cargo.toml index 9e60660..14d015a 100644 --- a/kifu/gtk/Cargo.toml +++ b/kifu/gtk/Cargo.toml @@ -13,12 +13,12 @@ adw = { version = "0.4", package = "libadwaita", features = [ "v1_2" ] } cairo-rs = { version = "0.17" } gio = { version = "0.17" } glib = { version = "0.17" } -gtk = { version = "0.6", package = "gtk4", features = ["v4_8"] } +gtk = { version = "0.6", package = "gtk4", features = [ "v4_8" ] } image = { version = "0.24" } kifu-core = { path = "../core" } -tokio = { version = "1.26", features = [ "full" ] } -# screenplay = { path = "../../screenplay" } +pango = { version = "*" } sgf = { path = "../../sgf" } +tokio = { version = "1.26", features = [ "full" ] } [build-dependencies] glib-build-tools = "0.17" diff --git a/kifu/gtk/config b/kifu/gtk/config index a387288..d7c6367 100644 --- a/kifu/gtk/config +++ b/kifu/gtk/config @@ -3,5 +3,5 @@ "name":"Savanni", "rank":{"Kyu":10} }, - "DatabasePath": "kifu/core/fixtures/five_games" + "DatabasePath": "/home/savanni/Documents/50 Ludoj/53 Kifu" } diff --git a/kifu/gtk/src/ui/library.rs b/kifu/gtk/src/ui/library.rs index 9fc24ce..a2b42c6 100644 --- a/kifu/gtk/src/ui/library.rs +++ b/kifu/gtk/src/ui/library.rs @@ -1,4 +1,5 @@ use crate::ui::GamePreview; +use adw::{prelude::*, subclass::prelude::*}; use glib::Object; use gtk::{glib, prelude::*, subclass::prelude::*}; use kifu_core::ui::GamePreviewElement; @@ -35,7 +36,7 @@ impl GameObject { pub struct LibraryPrivate { model: gio::ListStore, - list_view: gtk::ListView, + list_view: gtk::ColumnView, } impl Default for LibraryPrivate { @@ -43,6 +44,8 @@ impl Default for LibraryPrivate { let vector: Vec = vec![]; let model = gio::ListStore::new(glib::types::Type::OBJECT); model.extend_from_slice(&vector); + + /* let factory = gtk::SignalListItemFactory::new(); factory.connect_setup(move |_, list_item| { @@ -72,10 +75,60 @@ impl Default for LibraryPrivate { None => (), }; }); + */ let selection_model = gtk::NoSelection::new(Some(model.clone())); - let list_view = gtk::ListView::new(Some(selection_model), Some(factory)); - list_view.set_hexpand(true); + let list_view = gtk::ColumnView::builder().model(&selection_model).build(); + + fn make_factory(bind: F) -> gtk::SignalListItemFactory + where + F: Fn(GamePreviewElement) -> String + 'static, + { + let factory = gtk::SignalListItemFactory::new(); + factory.connect_setup(|_, list_item| { + list_item + .downcast_ref::() + .unwrap() + .set_child(Some( + >k::Label::builder() + .halign(gtk::Align::Start) + .ellipsize(pango::EllipsizeMode::End) + .build(), + )) + }); + factory.connect_bind(move |_, list_item| { + let list_item = list_item.downcast_ref::().unwrap(); + let game = list_item.item().and_downcast::().unwrap(); + let preview = list_item.child().and_downcast::().unwrap(); + match game.game() { + Some(game) => preview.set_text(&bind(game)), + None => (), + }; + }); + factory + } + + list_view.append_column(>k::ColumnViewColumn::new( + Some("date"), + Some(make_factory(|g| g.date)), + )); + list_view.append_column(>k::ColumnViewColumn::new( + Some("title"), + Some(make_factory(|g| g.name)), + )); + list_view.append_column(>k::ColumnViewColumn::new( + Some("black"), + Some(make_factory(|g| g.black_player)), + )); + list_view.append_column(>k::ColumnViewColumn::new( + Some("white"), + Some(make_factory(|g| g.white_player)), + )); + list_view.append_column(>k::ColumnViewColumn::new( + Some("result"), + Some(make_factory(|g| g.result)), + )); + Self { model, list_view } } } @@ -84,22 +137,22 @@ impl Default for LibraryPrivate { impl ObjectSubclass for LibraryPrivate { const NAME: &'static str = "Library"; type Type = Library; - type ParentType = gtk::Box; + type ParentType = adw::Bin; } impl ObjectImpl for LibraryPrivate {} impl WidgetImpl for LibraryPrivate {} -impl BoxImpl for LibraryPrivate {} +impl BinImpl for LibraryPrivate {} glib::wrapper! { - pub struct Library(ObjectSubclass) @extends gtk::Widget, gtk::Box; + pub struct Library(ObjectSubclass) @extends adw::Bin, gtk::Widget; } impl Library { pub fn new() -> Self { let s: Self = Object::builder().build(); - s.set_hexpand(true); - s.append(&s.imp().list_view); + + s.set_child(Some(&s.imp().list_view)); s } -- 2.44.1