From 191cf445ef4e2d955de9bbce451997986cd7829d Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 8 Aug 2018 22:38:36 +0300 Subject: [PATCH 01/24] ShowWidget: Do not hardcode the episode listbox in the glade file --- podcasts-gtk/resources/gtk/show_widget.ui | 8 ++------ podcasts-gtk/src/widgets/show.rs | 7 ++++++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/podcasts-gtk/resources/gtk/show_widget.ui b/podcasts-gtk/resources/gtk/show_widget.ui index e27aaae..46fa22d 100644 --- a/podcasts-gtk/resources/gtk/show_widget.ui +++ b/podcasts-gtk/resources/gtk/show_widget.ui @@ -142,17 +142,13 @@ Sorry, we could not find a description for this show. - + True False 0 in - - True - False - none - + diff --git a/podcasts-gtk/src/widgets/show.rs b/podcasts-gtk/src/widgets/show.rs index 68e6191..6040cce 100644 --- a/podcasts-gtk/src/widgets/show.rs +++ b/podcasts-gtk/src/widgets/show.rs @@ -29,6 +29,7 @@ pub(crate) struct ShowWidget { scrolled_window: gtk::ScrolledWindow, cover: gtk::Image, description: gtk::Label, + frame: gtk::Frame, episodes: gtk::ListBox, show_id: Option, } @@ -38,7 +39,10 @@ impl Default for ShowWidget { let builder = gtk::Builder::new_from_resource("/org/gnome/Podcasts/gtk/show_widget.ui"); let container: gtk::Box = builder.get_object("container").unwrap(); let scrolled_window: gtk::ScrolledWindow = builder.get_object("scrolled_window").unwrap(); - let episodes = builder.get_object("episodes").unwrap(); + let frame: gtk::Frame = builder.get_object("frame").unwrap(); + let episodes = gtk::ListBox::new(); + episodes.show(); + frame.add(&episodes); let cover: gtk::Image = builder.get_object("cover").unwrap(); let description: gtk::Label = builder.get_object("description").unwrap(); @@ -48,6 +52,7 @@ impl Default for ShowWidget { scrolled_window, cover, description, + frame, episodes, show_id: None, } From 17b58b159ad87fdc6acdcf2009767d697537485c Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 8 Aug 2018 23:28:42 +0300 Subject: [PATCH 02/24] ShowWidget: Remove unsused menu from the glade file --- podcasts-gtk/resources/gtk/show_widget.ui | 41 ++++------------------- 1 file changed, 6 insertions(+), 35 deletions(-) diff --git a/podcasts-gtk/resources/gtk/show_widget.ui b/podcasts-gtk/resources/gtk/show_widget.ui index 46fa22d..6f075d5 100644 --- a/podcasts-gtk/resources/gtk/show_widget.ui +++ b/podcasts-gtk/resources/gtk/show_widget.ui @@ -3,20 +3,20 @@ Copyright (C) 2017 - 2018 -This file is part of Hammond. +This file is part of GNOME Podcasts. -Hammond is free software: you can redistribute it and/or modify +GNOME Podcasts is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -Hammond is distributed in the hope that it will be useful, +GNOME Podcasts is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with Hammond. If not, see . +along with GNOME Podcasts. If not, see . Authors: Jordan Petridis @@ -24,9 +24,9 @@ Tobias Bernard --> - + - + @@ -196,33 +196,4 @@ Sorry, we could not find a description for this show. - - False - bottom - - - True - False - 6 - 6 - 6 - 6 - vertical - - - True - True - True - Mark all episodes as listened - True - - - False - True - 0 - - - - - From ac7520593334ac354c29e5983c14ec44577823ad Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 02:16:38 +0300 Subject: [PATCH 03/24] ShowWidget: Initial prototype w/ libhandy::Column --- Cargo.lock | 132 ++++++++++++++ org.gnome.Podcasts.json | 10 ++ podcasts-gtk/Cargo.toml | 3 + podcasts-gtk/resources/gtk/episode_widget.ui | 1 - podcasts-gtk/resources/gtk/show_widget.ui | 170 ++++++------------- podcasts-gtk/src/main.rs | 4 +- podcasts-gtk/src/widgets/show.rs | 22 ++- 7 files changed, 216 insertions(+), 126 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73fd068..8c135bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -107,6 +107,11 @@ name = "bitflags" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "build_const" version = "0.2.1" @@ -377,6 +382,15 @@ dependencies = [ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "dbus" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "debug_unreachable" version = "0.1.1" @@ -514,6 +528,14 @@ dependencies = [ "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "error-chain" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "error-chain" version = "0.12.0" @@ -596,6 +618,11 @@ dependencies = [ "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "gcc" +version = "0.3.54" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "gdk" version = "0.8.0" @@ -1094,6 +1121,43 @@ dependencies = [ "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "libhandy" +version = "0.1.0" +source = "git+https://gitlab.gnome.org/jsparber/libhandy-rs#f174e76882896c32959d0d16fe11eaadfce1c674" +dependencies = [ + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "gdk 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gdk-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gio 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "gio-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gtk 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "gtk-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libhandy-sys 0.1.0 (git+https://gitlab.gnome.org/jsparber/libhandy-sys-rs)", + "notify-rust 3.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libhandy-sys" +version = "0.1.0" +source = "git+https://gitlab.gnome.org/jsparber/libhandy-sys-rs#2caa9f6e0b68d391a6cdb45123f85c73b9852553" +dependencies = [ + "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "glib-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gtk 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "gtk-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "libsqlite3-sys" version = "0.9.1" @@ -1145,6 +1209,25 @@ name = "mac" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "mac-notification-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", + "objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "maplit" version = "1.0.1" @@ -1310,6 +1393,16 @@ name = "nodrop" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "notify-rust" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dbus 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "mac-notification-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num-integer" version = "0.1.39" @@ -1348,6 +1441,32 @@ dependencies = [ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "objc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "objc 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "open" version = "1.2.1" @@ -1559,6 +1678,7 @@ dependencies = [ "html2text 0.1.8 (git+https://github.com/alatiera/rust-html2text)", "humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libhandy 0.1.0 (git+https://gitlab.gnome.org/jsparber/libhandy-rs)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "loggerv 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2527,6 +2647,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "85415d2594767338a74a30c1d370b2f3262ec1b4ed2d7bba5b3faf4de40467d9" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" +"checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" "checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9" "checksum bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e178b8e0e239e844b083d5a0d4a156b2654e67f9f80144d48398fcd736a24fb8" @@ -2556,6 +2677,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum crossbeam-utils 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ea52fab26a99d96cdff39d0ca75c9716125937f5dba2ab83923aaaf5928f684a" "checksum csv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71903184af9960c555e7f3b32ff17390d20ecaaf17d4f18c4a0993f2df8a49e3" "checksum csv-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4dd8e6d86f7ba48b4276ef1317edc8cc36167546d8972feb4a2b5fec0b374105" +"checksum dbus 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "58ec7b4cac6f79f36af1cd9cfdb9b935fc5a4e899f494ee03a3a6165f7d10b4b" "checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" "checksum derive_builder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c998e6ab02a828dd9735c18f154e14100e674ed08cb4e1938f0e4177543f439" "checksum derive_builder_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "735e24ee9e5fa8e16b86da5007856e97d592e11867e45d76e0c0d0a164a0b757" @@ -2573,6 +2695,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" "checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" "checksum encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98fd0f24d1fb71a4a6b9330c8ca04cbd4e7cc5d846b54ca74ff376bc7c9f798d" +"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" @@ -2584,6 +2707,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b" "checksum futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "884dbe32a6ae4cd7da5c6db9b78114449df9953b8d490c9d7e1b51720b922c62" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" +"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" "checksum gdk 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd30051ff3d908ff2fc7e5776ffe1c699821e043809f294c3a61004f11d6c3a9" "checksum gdk-pixbuf 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c2d2199eba47ebcb9977ce28179649bdd59305ef465c4e6f9b65aaa41c24e6b5" "checksum gdk-pixbuf-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df6a3b73e04fafc07f5ebc083f1096a773412e627828e1103a55e921f81187d8" @@ -2627,12 +2751,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" "checksum libflate 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "7d4b4c7aff5bac19b956f693d0ea0eade8066deb092186ae954fa6ba14daab98" +"checksum libhandy 0.1.0 (git+https://gitlab.gnome.org/jsparber/libhandy-rs)" = "" +"checksum libhandy-sys 0.1.0 (git+https://gitlab.gnome.org/jsparber/libhandy-sys-rs)" = "" "checksum libsqlite3-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9eb7b8e152b6a01be6a4a2917248381875758250dc3df5d46caf9250341dda" "checksum locale_config 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "14fbee0e39bc2dd6a2427c4fdea66e9826cc1fd09b0a0b7550359f5f6efe1dab" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "61bd98ae7f7b754bc53dca7d44b604f733c6bba044ea6f41bc8d89272d8161d2" "checksum loggerv 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ba6b0664956d197c6e0223870c1cd1ec4117aea282b4c0bd5ab01119d31d708d" "checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" +"checksum mac-notification-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a3639b6caa2db7443e5df80e12c450982f77fc3c140f53d6e48be91f965ea66" +"checksum malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" "checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43" "checksum markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfedc97d5a503e96816d10fedcd5b42f760b2e525ce2f7ec71f6a41780548475" "checksum matches 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "835511bab37c34c47da5cb44844bea2cfde0236db0b506f90ea4224482c9774a" @@ -2651,11 +2779,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" +"checksum notify-rust 3.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0e58d0671a337f5616ada6b4fca9d792948c5ab03e6ce9376f9b7f31aa31545c" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-rational 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e" "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" +"checksum objc 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9833ab0efe5361b1e2122a0544a5d3359576911a42cb098c2e59be8650807367" +"checksum objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +"checksum objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" "checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113" "checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985" "checksum openssl-sys 0.9.33 (registry+https://github.com/rust-lang/crates.io-index)" = "d8abc04833dcedef24221a91852931df2f63e3369ae003134e70aff3645775cc" diff --git a/org.gnome.Podcasts.json b/org.gnome.Podcasts.json index bbfba50..662d37a 100644 --- a/org.gnome.Podcasts.json +++ b/org.gnome.Podcasts.json @@ -35,6 +35,16 @@ } }, "modules" : [ + { + "name" : "libhandy", + "buildsystem" : "meson", + "sources" : [ + { + "type" : "git", + "url" : "https://source.puri.sm/Librem5/libhandy" + } + ] + }, { "name" : "gnome-podcasts", "buildsystem" : "meson", diff --git a/podcasts-gtk/Cargo.toml b/podcasts-gtk/Cargo.toml index 4abd3cd..57ed53d 100644 --- a/podcasts-gtk/Cargo.toml +++ b/podcasts-gtk/Cargo.toml @@ -38,6 +38,9 @@ version = "0.4.1" features = ["v2_50"] version = "0.4.1" +[dependencies.libhandy] +git = "https://gitlab.gnome.org/jsparber/libhandy-rs" + [dependencies.podcasts-data] path = "../podcasts-data" diff --git a/podcasts-gtk/resources/gtk/episode_widget.ui b/podcasts-gtk/resources/gtk/episode_widget.ui index 08f03b0..f89c41f 100644 --- a/podcasts-gtk/resources/gtk/episode_widget.ui +++ b/podcasts-gtk/resources/gtk/episode_widget.ui @@ -54,7 +54,6 @@ Tobias Bernard False Episode Title end - 55 True False 1 diff --git a/podcasts-gtk/resources/gtk/show_widget.ui b/podcasts-gtk/resources/gtk/show_widget.ui index 6f075d5..ee82af3 100644 --- a/podcasts-gtk/resources/gtk/show_widget.ui +++ b/podcasts-gtk/resources/gtk/show_widget.ui @@ -48,141 +48,77 @@ Tobias Bernard True False - + True False - True + 32 + 32 True + vertical + 6 True False - True vertical + 6 - + + True + False + 256 + image-x-generic-symbolic + + + False + False + 0 + + + + + True + True + never + 80 + + + True + False + none + + + True + False + center + center + This is embarrassing! +Sorry, we could not find a description for this show. + True + center + True + 70 + + + + + + + False + False + 1 + False False + 6 0 - - True - False - 32 - 32 - 32 - 32 - True - vertical - 6 - - - True - False - vertical - 6 - - - True - False - 256 - image-x-generic-symbolic - - - False - False - 0 - - - - - True - True - never - 80 - - - True - False - none - - - True - False - center - center - This is embarrassing! -Sorry, we could not find a description for this show. - True - center - True - 70 - - - - - - - False - False - 1 - - - - - False - False - 6 - 1 - - - - - True - False - 0 - in - - - - - - - - - False - False - 2 - - - - - False - True - 1 - - - - - True - False - True - vertical - - - - - - False - False - end - 2 - + diff --git a/podcasts-gtk/src/main.rs b/podcasts-gtk/src/main.rs index ef5364d..5f4b34e 100644 --- a/podcasts-gtk/src/main.rs +++ b/podcasts-gtk/src/main.rs @@ -61,8 +61,10 @@ extern crate pretty_assertions; extern crate chrono; extern crate crossbeam_channel; extern crate fragile; +extern crate gettextrs; extern crate html2text; extern crate humansize; +extern crate libhandy; extern crate loggerv; extern crate open; extern crate podcasts_data; @@ -73,8 +75,6 @@ extern crate reqwest; extern crate serde_json; extern crate url; -extern crate gettextrs; - use log::Level; use gtk::prelude::*; diff --git a/podcasts-gtk/src/widgets/show.rs b/podcasts-gtk/src/widgets/show.rs index 6040cce..c1a6179 100644 --- a/podcasts-gtk/src/widgets/show.rs +++ b/podcasts-gtk/src/widgets/show.rs @@ -1,11 +1,11 @@ use glib; -use gtk; -use gtk::prelude::*; +use gtk::{self, prelude::*, SelectionMode}; use crossbeam_channel::Sender; use failure::Error; use fragile::Fragile; use html2text; +use libhandy::{Column, ColumnExt}; use rayon; use podcasts_data::dbqueries; @@ -29,7 +29,6 @@ pub(crate) struct ShowWidget { scrolled_window: gtk::ScrolledWindow, cover: gtk::Image, description: gtk::Label, - frame: gtk::Frame, episodes: gtk::ListBox, show_id: Option, } @@ -39,10 +38,22 @@ impl Default for ShowWidget { let builder = gtk::Builder::new_from_resource("/org/gnome/Podcasts/gtk/show_widget.ui"); let container: gtk::Box = builder.get_object("container").unwrap(); let scrolled_window: gtk::ScrolledWindow = builder.get_object("scrolled_window").unwrap(); - let frame: gtk::Frame = builder.get_object("frame").unwrap(); + let sub_cont: gtk::Box = builder.get_object("sub_container").unwrap(); + let frame = gtk::Frame::new(None); let episodes = gtk::ListBox::new(); - episodes.show(); + episodes.set_selection_mode(SelectionMode::None); + + let column = Column::new(); + column.set_maximum_width(700); + // For some reason the Column is not seen as a gtk::container + // and therefore we can't call add() without the cast + let column = column.upcast::(); + let column = column.downcast::().unwrap(); + frame.add(&episodes); + column.add(&frame); + sub_cont.add(&column); + sub_cont.show_all(); let cover: gtk::Image = builder.get_object("cover").unwrap(); let description: gtk::Label = builder.get_object("description").unwrap(); @@ -52,7 +63,6 @@ impl Default for ShowWidget { scrolled_window, cover, description, - frame, episodes, show_id: None, } From 20ddc54edc24c472e65c7ae8ee067311ba1a8144 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 02:34:45 +0300 Subject: [PATCH 04/24] ShowWidget: Put the whole thing inside HdyColumn --- podcasts-gtk/resources/gtk/show_widget.ui | 121 ++++++++-------------- podcasts-gtk/src/widgets/show.rs | 21 ++-- 2 files changed, 58 insertions(+), 84 deletions(-) diff --git a/podcasts-gtk/resources/gtk/show_widget.ui b/podcasts-gtk/resources/gtk/show_widget.ui index ee82af3..c3610a9 100644 --- a/podcasts-gtk/resources/gtk/show_widget.ui +++ b/podcasts-gtk/resources/gtk/show_widget.ui @@ -30,106 +30,77 @@ Tobias Bernard - - 290 - 420 + True False + 32 + 32 + True vertical + 6 - - scrolled_window + True - True - True - never + False + vertical + 6 - + True False + 256 + image-x-generic-symbolic + + + False + False + 0 + + + + + True + True + never + 80 - + True False - 32 - 32 - True - vertical - 6 + none - + True False - vertical - 6 - - - True - False - 256 - image-x-generic-symbolic - - - False - False - 0 - - - - - True - True - never - 80 - - - True - False - none - - - True - False - center - center - This is embarrassing! -Sorry, we could not find a description for this show. - True - center - True - 70 - - - - - - - False - False - 1 - - + center + center + This is embarrasing! +Sorry, we could not find a description for this Show. + True + center + True + 70 - - False - False - 6 - 0 - - - - + + False + False + 1 + False - True + False + 6 0 + + + diff --git a/podcasts-gtk/src/widgets/show.rs b/podcasts-gtk/src/widgets/show.rs index c1a6179..73b5ff6 100644 --- a/podcasts-gtk/src/widgets/show.rs +++ b/podcasts-gtk/src/widgets/show.rs @@ -1,5 +1,5 @@ use glib; -use gtk::{self, prelude::*, SelectionMode}; +use gtk::{self, prelude::*, Orientation, SelectionMode}; use crossbeam_channel::Sender; use failure::Error; @@ -35,10 +35,15 @@ pub(crate) struct ShowWidget { impl Default for ShowWidget { fn default() -> Self { + let container = gtk::Box::new(Orientation::Horizontal, 0); + let scrolled_window = gtk::ScrolledWindow::new(None, None); + container.add(&scrolled_window); + let builder = gtk::Builder::new_from_resource("/org/gnome/Podcasts/gtk/show_widget.ui"); - let container: gtk::Box = builder.get_object("container").unwrap(); - let scrolled_window: gtk::ScrolledWindow = builder.get_object("scrolled_window").unwrap(); let sub_cont: gtk::Box = builder.get_object("sub_container").unwrap(); + let cover: gtk::Image = builder.get_object("cover").unwrap(); + let description: gtk::Label = builder.get_object("description").unwrap(); + let frame = gtk::Frame::new(None); let episodes = gtk::ListBox::new(); episodes.set_selection_mode(SelectionMode::None); @@ -51,13 +56,11 @@ impl Default for ShowWidget { let column = column.downcast::().unwrap(); frame.add(&episodes); - column.add(&frame); - sub_cont.add(&column); - sub_cont.show_all(); - - let cover: gtk::Image = builder.get_object("cover").unwrap(); - let description: gtk::Label = builder.get_object("description").unwrap(); + sub_cont.add(&frame); + column.add(&sub_cont); + scrolled_window.add(&column); + container.show_all(); ShowWidget { container, scrolled_window, From 7538e765378f18769d19af83624533b10f02c52a Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 04:21:12 +0300 Subject: [PATCH 05/24] Gtk: Abstract a BaseView Widget Currently it just re-exports its children with getters, but the idea is that it will also be able to handle the saving the state of its height adjustment later. --- podcasts-gtk/src/stacks/populated.rs | 8 +++--- podcasts-gtk/src/widgets/base_view.rs | 35 +++++++++++++++++++++++++++ podcasts-gtk/src/widgets/mod.rs | 2 ++ podcasts-gtk/src/widgets/show.rs | 31 +++++++++++++----------- 4 files changed, 58 insertions(+), 18 deletions(-) create mode 100644 podcasts-gtk/src/widgets/base_view.rs diff --git a/podcasts-gtk/src/stacks/populated.rs b/podcasts-gtk/src/stacks/populated.rs index ad58ba9..8745efd 100644 --- a/podcasts-gtk/src/stacks/populated.rs +++ b/podcasts-gtk/src/stacks/populated.rs @@ -39,7 +39,7 @@ impl PopulatedStack { let container = gtk::Box::new(gtk::Orientation::Horizontal, 0); stack.add_named(&populated.container, "shows"); - stack.add_named(&show.container, "widget"); + stack.add_named(show.container(), "widget"); container.add(&stack); container.show_all(); @@ -88,7 +88,7 @@ impl PopulatedStack { } pub(crate) fn replace_widget(&mut self, pd: Arc) -> Result<(), Error> { - let old = self.show.container.clone(); + let old = self.show.container().clone(); // save the ShowWidget vertical scrollbar alignment self.show.show_id().map(|id| self.show.save_vadjustment(id)); @@ -96,7 +96,7 @@ impl PopulatedStack { let new = ShowWidget::new(pd, self.sender.clone()); self.show = new; self.stack.remove(&old); - self.stack.add_named(&self.show.container, "widget"); + self.stack.add_named(self.show.container(), "widget"); // The current visible child might change depending on // removal and insertion in the gtk::Stack, so we have @@ -108,7 +108,7 @@ impl PopulatedStack { } pub(crate) fn update_widget(&mut self) -> Result<(), Error> { - let old = self.show.container.clone(); + let old = self.show.container().clone(); let id = self.show.show_id(); if id.is_none() { return Ok(()); diff --git a/podcasts-gtk/src/widgets/base_view.rs b/podcasts-gtk/src/widgets/base_view.rs new file mode 100644 index 0000000..8846767 --- /dev/null +++ b/podcasts-gtk/src/widgets/base_view.rs @@ -0,0 +1,35 @@ +use gtk::{self, prelude::*, Orientation}; + +#[derive(Debug, Clone)] +pub(crate) struct BaseView { + container: gtk::Box, + scrolled_window: gtk::ScrolledWindow, +} + +impl Default for BaseView { + fn default() -> Self { + let container = gtk::Box::new(Orientation::Horizontal, 0); + let scrolled_window = gtk::ScrolledWindow::new(None, None); + container.add(&scrolled_window); + container.show_all(); + + BaseView { + container, + scrolled_window, + } + } +} + +impl BaseView { + pub(crate) fn container(&self) -> >k::Box { + &self.container + } + + pub(crate) fn scrolled_window(&self) -> >k::ScrolledWindow { + &self.scrolled_window + } + + pub(crate) fn add>(&self, widget: &T) { + self.scrolled_window.add(widget); + } +} diff --git a/podcasts-gtk/src/widgets/mod.rs b/podcasts-gtk/src/widgets/mod.rs index 7ff0246..85aae87 100644 --- a/podcasts-gtk/src/widgets/mod.rs +++ b/podcasts-gtk/src/widgets/mod.rs @@ -1,5 +1,6 @@ mod aboutdialog; pub(crate) mod appnotif; +mod base_view; mod empty; mod episode; mod home_view; @@ -9,6 +10,7 @@ pub(crate) mod show_menu; mod shows_view; pub(crate) use self::aboutdialog::about_dialog; +pub(crate) use self::base_view::BaseView; pub(crate) use self::empty::EmptyView; pub(crate) use self::episode::EpisodeWidget; pub(crate) use self::home_view::HomeView; diff --git a/podcasts-gtk/src/widgets/show.rs b/podcasts-gtk/src/widgets/show.rs index 73b5ff6..50fa3f3 100644 --- a/podcasts-gtk/src/widgets/show.rs +++ b/podcasts-gtk/src/widgets/show.rs @@ -1,5 +1,5 @@ use glib; -use gtk::{self, prelude::*, Orientation, SelectionMode}; +use gtk::{self, prelude::*, SelectionMode}; use crossbeam_channel::Sender; use failure::Error; @@ -13,7 +13,7 @@ use podcasts_data::Show; use app::Action; use utils::{self, lazy_load}; -use widgets::{EpisodeWidget, ShowMenu}; +use widgets::{BaseView, EpisodeWidget, ShowMenu}; use std::rc::Rc; use std::sync::{Arc, Mutex}; @@ -25,8 +25,7 @@ lazy_static! { #[derive(Debug, Clone)] pub(crate) struct ShowWidget { - pub(crate) container: gtk::Box, - scrolled_window: gtk::ScrolledWindow, + view: BaseView, cover: gtk::Image, description: gtk::Label, episodes: gtk::ListBox, @@ -35,14 +34,11 @@ pub(crate) struct ShowWidget { impl Default for ShowWidget { fn default() -> Self { - let container = gtk::Box::new(Orientation::Horizontal, 0); - let scrolled_window = gtk::ScrolledWindow::new(None, None); - container.add(&scrolled_window); - let builder = gtk::Builder::new_from_resource("/org/gnome/Podcasts/gtk/show_widget.ui"); let sub_cont: gtk::Box = builder.get_object("sub_container").unwrap(); let cover: gtk::Image = builder.get_object("cover").unwrap(); let description: gtk::Label = builder.get_object("description").unwrap(); + let view = BaseView::default(); let frame = gtk::Frame::new(None); let episodes = gtk::ListBox::new(); @@ -58,12 +54,11 @@ impl Default for ShowWidget { frame.add(&episodes); sub_cont.add(&frame); column.add(&sub_cont); - scrolled_window.add(&column); + view.add(&column); + column.show_all(); - container.show_all(); ShowWidget { - container, - scrolled_window, + view, cover, description, episodes, @@ -95,6 +90,14 @@ impl ShowWidget { debug_assert!(res.is_ok()); } + pub(crate) fn container(&self) -> >k::Box { + self.view.container() + } + + pub(crate) fn scrolled_window(&self) -> >k::ScrolledWindow { + self.view.scrolled_window() + } + /// Set the show cover. fn set_cover(&self, pd: &Arc) -> Result<(), Error> { utils::set_image_from_path(&self.cover, pd.id(), 256) @@ -110,7 +113,7 @@ impl ShowWidget { pub(crate) fn save_vadjustment(&self, oldid: i32) -> Result<(), Error> { if let Ok(mut guard) = SHOW_WIDGET_VALIGNMENT.lock() { let adj = self - .scrolled_window + .scrolled_window() .get_vadjustment() .ok_or_else(|| format_err!("Could not get the adjustment"))?; *guard = Some((oldid, Fragile::new(adj))); @@ -138,7 +141,7 @@ impl ShowWidget { // Copy the vertical scrollbar adjustment from the old view into the new one. let res = fragile .try_get() - .map(|x| utils::smooth_scroll_to(&self.scrolled_window, &x)) + .map(|x| utils::smooth_scroll_to(self.scrolled_window(), &x)) .map_err(From::from); debug_assert!(res.is_ok()); From 4e59d648ef55fb2e62a62b9495f97c14af3014e6 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 04:46:59 +0300 Subject: [PATCH 06/24] HomeView: Use the new BaseView abstraction --- podcasts-gtk/resources/gtk/home_view.ui | 630 +++++++++++------------- podcasts-gtk/src/stacks/home.rs | 6 +- podcasts-gtk/src/widgets/home_view.rs | 27 +- 3 files changed, 298 insertions(+), 365 deletions(-) diff --git a/podcasts-gtk/resources/gtk/home_view.ui b/podcasts-gtk/resources/gtk/home_view.ui index 4d018bf..86e34c7 100644 --- a/podcasts-gtk/resources/gtk/home_view.ui +++ b/podcasts-gtk/resources/gtk/home_view.ui @@ -3,20 +3,20 @@ Copyright (C) 2017 - 2018 -This file is part of Hammond. +This file is part of GNOME Podcasts. -Hammond is free software: you can redistribute it and/or modify +GNOME Podcasts is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -Hammond is distributed in the hope that it will be useful, +GNOME Podcasts is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with Hammond. If not, see . +along with GNOME Podcasts. If not, see . Authors: Jordan Petridis @@ -24,376 +24,302 @@ Tobias Bernard --> - + - + - - container - 290 - 420 + True False + 32 + 32 + True vertical + 24 - - scrolled_window - True - True - never + + False + True + True + vertical + 6 - + True False + start + True + Today + + + + + + + False + False + 0 + + + + + True + False + True + 0 + in - + True False - - - True - False - True - vertical - - - - - - False - False - 0 - - - - - True - False - 32 - 32 - 32 - 32 - True - vertical - 24 - - - False - True - True - vertical - 6 - - - True - False - start - True - Today - - - - - - - False - False - 0 - - - - - True - False - True - 0 - in - - - True - False - True - none - - - - - - - - False - False - 1 - - - - - False - False - 0 - - - - - False - True - True - vertical - 6 - - - True - False - start - Yesterday - - - - - - - False - False - 0 - - - - - True - False - True - 0 - in - - - True - False - True - none - - - - - - - - False - False - 1 - - - - - False - False - 1 - - - - - False - True - True - vertical - 6 - - - True - False - start - This Week - - - - - - - False - False - 0 - - - - - True - False - True - 0 - in - - - True - False - True - none - - - - - - - - False - False - 1 - - - - - False - False - 2 - - - - - False - True - True - vertical - 6 - - - True - False - start - This Month - - - - - - - False - False - 0 - - - - - True - False - True - 0 - in - - - True - False - True - none - - - - - - - - False - False - 1 - - - - - False - False - 3 - - - - - False - True - True - vertical - 6 - - - True - False - start - True - Older - - - - - - - False - False - 0 - - - - - True - False - True - 0 - in - - - True - False - True - True - none - - - - - - - - False - False - 1 - - - - - False - False - 5 - - - - - False - True - 1 - - - - - True - False - True - vertical - - - - - - False - False - 2 - - + True + none + + + + + False + False + 1 + - True - True + False + False 0 + + + False + True + True + vertical + 6 + + + True + False + start + Yesterday + + + + + + + False + False + 0 + + + + + True + False + True + 0 + in + + + True + False + True + none + + + + + + + + False + False + 1 + + + + + False + False + 1 + + + + + False + True + True + vertical + 6 + + + True + False + start + This Week + + + + + + + False + False + 0 + + + + + True + False + True + 0 + in + + + True + False + True + none + + + + + + + + False + False + 1 + + + + + False + False + 2 + + + + + False + True + True + vertical + 6 + + + True + False + start + This Month + + + + + + + False + False + 0 + + + + + True + False + True + 0 + in + + + True + False + True + none + + + + + + + + False + False + 1 + + + + + False + False + 3 + + + + + False + True + True + vertical + 6 + + + True + False + start + True + Older + + + + + + + False + False + 0 + + + + + True + False + True + 0 + in + + + True + False + True + True + none + + + + + + + + False + False + 1 + + + + + False + False + 5 + + diff --git a/podcasts-gtk/src/stacks/home.rs b/podcasts-gtk/src/stacks/home.rs index 58b6743..9dce4cd 100644 --- a/podcasts-gtk/src/stacks/home.rs +++ b/podcasts-gtk/src/stacks/home.rs @@ -34,7 +34,7 @@ impl HomeStack { let stack = gtk::Stack::new(); let state = State::Empty; - stack.add_named(&episodes.container, "home"); + stack.add_named(episodes.container(), "home"); stack.add_named(&empty.container, "empty"); let mut home = HomeStack { @@ -67,14 +67,14 @@ impl HomeStack { fn replace_view(&mut self) -> Result<(), Error> { // Get the container of the view - let old = &self.episodes.container.clone(); + let old = &self.episodes.container().clone(); let eps = HomeView::new(self.sender.clone())?; // Remove the old widget and add the new one // during this the previous view is removed, // and the visible child falls back to empty view. self.stack.remove(old); - self.stack.add_named(&eps.container, "home"); + self.stack.add_named(eps.container(), "home"); // Keep the previous state. let s = self.state; // Set the visible child back to the previous one to avoid diff --git a/podcasts-gtk/src/widgets/home_view.rs b/podcasts-gtk/src/widgets/home_view.rs index 442b016..3cdacd5 100644 --- a/podcasts-gtk/src/widgets/home_view.rs +++ b/podcasts-gtk/src/widgets/home_view.rs @@ -11,7 +11,7 @@ use podcasts_data::EpisodeWidgetModel; use app::Action; use utils::{self, lazy_load_full}; -use widgets::EpisodeWidget; +use widgets::{BaseView, EpisodeWidget}; use std::cell::Cell; use std::rc::Rc; @@ -33,8 +33,7 @@ enum ListSplit { #[derive(Debug, Clone)] pub(crate) struct HomeView { - pub(crate) container: gtk::Box, - scrolled_window: gtk::ScrolledWindow, + view: BaseView, frame_parent: gtk::Box, today_box: gtk::Box, yday_box: gtk::Box, @@ -50,9 +49,8 @@ pub(crate) struct HomeView { impl Default for HomeView { fn default() -> Self { + let view = BaseView::default(); let builder = gtk::Builder::new_from_resource("/org/gnome/Podcasts/gtk/home_view.ui"); - let container: gtk::Box = builder.get_object("container").unwrap(); - let scrolled_window: gtk::ScrolledWindow = builder.get_object("scrolled_window").unwrap(); let frame_parent: gtk::Box = builder.get_object("frame_parent").unwrap(); let today_box: gtk::Box = builder.get_object("today_box").unwrap(); let yday_box: gtk::Box = builder.get_object("yday_box").unwrap(); @@ -65,9 +63,10 @@ impl Default for HomeView { let month_list: gtk::ListBox = builder.get_object("month_list").unwrap(); let rest_list: gtk::ListBox = builder.get_object("rest_list").unwrap(); + view.add(&frame_parent); + HomeView { - container, - scrolled_window, + view, frame_parent, today_box, yday_box, @@ -116,10 +115,18 @@ impl HomeView { }; lazy_load_full(episodes, func, callback); - view.container.show_all(); + view.container().show_all(); Ok(view) } + pub(crate) fn container(&self) -> >k::Box { + self.view.container() + } + + pub(crate) fn scrolled_window(&self) -> >k::ScrolledWindow { + self.view.scrolled_window() + } + /// Set scrolled window vertical adjustment. fn set_vadjustment(&self) -> Result<(), Error> { let guard = EPISODES_VIEW_VALIGNMENT @@ -130,7 +137,7 @@ impl HomeView { // Copy the vertical scrollbar adjustment from the old view into the new one. let res = fragile .try_get() - .map(|x| utils::smooth_scroll_to(&self.scrolled_window, &x)) + .map(|x| utils::smooth_scroll_to(self.scrolled_window(), &x)) .map_err(From::from); debug_assert!(res.is_ok()); @@ -144,7 +151,7 @@ impl HomeView { pub(crate) fn save_alignment(&self) -> Result<(), Error> { if let Ok(mut guard) = EPISODES_VIEW_VALIGNMENT.lock() { let adj = self - .scrolled_window + .scrolled_window() .get_vadjustment() .ok_or_else(|| format_err!("Could not get the adjustment"))?; *guard = Some(Fragile::new(adj)); From e4dd9f5bb35fd167b6a2409f63b02af4402694ef Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 04:54:06 +0300 Subject: [PATCH 07/24] HomeView: Use libhandy::Column for the main widget --- podcasts-gtk/src/widgets/home_view.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/podcasts-gtk/src/widgets/home_view.rs b/podcasts-gtk/src/widgets/home_view.rs index 3cdacd5..59878e9 100644 --- a/podcasts-gtk/src/widgets/home_view.rs +++ b/podcasts-gtk/src/widgets/home_view.rs @@ -6,6 +6,7 @@ use gtk::prelude::*; use crossbeam_channel::Sender; use fragile::Fragile; +use libhandy::{Column, ColumnExt}; use podcasts_data::dbqueries; use podcasts_data::EpisodeWidgetModel; @@ -63,7 +64,16 @@ impl Default for HomeView { let month_list: gtk::ListBox = builder.get_object("month_list").unwrap(); let rest_list: gtk::ListBox = builder.get_object("rest_list").unwrap(); - view.add(&frame_parent); + let column = Column::new(); + column.show(); + column.set_maximum_width(700); + // For some reason the Column is not seen as a gtk::container + // and therefore we can't call add() without the cast + let column = column.upcast::(); + let column = column.downcast::().unwrap(); + + column.add(&frame_parent); + view.add(&column); HomeView { view, From 7463e9d42cc67f8513b6747e2eb7d05582f862f0 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 05:35:51 +0300 Subject: [PATCH 08/24] ShowsView: Use BaseView abstraction --- podcasts-gtk/resources/gtk/shows_view.ui | 74 ------------------------ podcasts-gtk/resources/resources.xml | 3 +- podcasts-gtk/src/stacks/populated.rs | 6 +- podcasts-gtk/src/widgets/shows_view.rs | 45 +++++++++----- 4 files changed, 34 insertions(+), 94 deletions(-) delete mode 100644 podcasts-gtk/resources/gtk/shows_view.ui diff --git a/podcasts-gtk/resources/gtk/shows_view.ui b/podcasts-gtk/resources/gtk/shows_view.ui deleted file mode 100644 index 044233a..0000000 --- a/podcasts-gtk/resources/gtk/shows_view.ui +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - fb_parent - 290 - 420 - True - False - vertical - - - scrolled_window - True - True - - - True - False - - - True - False - center - start - 24 - 24 - True - 12 - 12 - 20 - none - - - - - - - True - True - 0 - - - - diff --git a/podcasts-gtk/resources/resources.xml b/podcasts-gtk/resources/resources.xml index e2cd94b..b67f496 100644 --- a/podcasts-gtk/resources/resources.xml +++ b/podcasts-gtk/resources/resources.xml @@ -7,7 +7,6 @@ gtk/empty_show.ui gtk/home_view.ui gtk/home_episode.ui - gtk/shows_view.ui gtk/shows_child.ui gtk/headerbar.ui gtk/inapp_notif.ui @@ -20,4 +19,4 @@ gtk/prefs.ui gtk/style.css - \ No newline at end of file + diff --git a/podcasts-gtk/src/stacks/populated.rs b/podcasts-gtk/src/stacks/populated.rs index 8745efd..67a91a8 100644 --- a/podcasts-gtk/src/stacks/populated.rs +++ b/podcasts-gtk/src/stacks/populated.rs @@ -38,7 +38,7 @@ impl PopulatedStack { let show = Rc::new(ShowWidget::default()); let container = gtk::Box::new(gtk::Orientation::Horizontal, 0); - stack.add_named(&populated.container, "shows"); + stack.add_named(populated.container(), "shows"); stack.add_named(show.container(), "widget"); container.add(&stack); container.show_all(); @@ -70,7 +70,7 @@ impl PopulatedStack { } pub(crate) fn replace_shows(&mut self) -> Result<(), Error> { - let old = &self.populated.container.clone(); + let old = &self.populated.container().clone(); debug!("Name: {:?}", WidgetExt::get_name(old)); self.populated @@ -81,7 +81,7 @@ impl PopulatedStack { let pop = ShowsView::new(self.sender.clone()); self.populated = pop; self.stack.remove(old); - self.stack.add_named(&self.populated.container, "shows"); + self.stack.add_named(self.populated.container(), "shows"); old.destroy(); Ok(()) diff --git a/podcasts-gtk/src/widgets/shows_view.rs b/podcasts-gtk/src/widgets/shows_view.rs index 668be0c..6866ca9 100644 --- a/podcasts-gtk/src/widgets/shows_view.rs +++ b/podcasts-gtk/src/widgets/shows_view.rs @@ -1,5 +1,4 @@ -use gtk; -use gtk::prelude::*; +use gtk::{self, prelude::*, Align, SelectionMode}; use crossbeam_channel::Sender; use failure::Error; @@ -10,6 +9,7 @@ use podcasts_data::Show; use app::Action; use utils::{self, get_ignored_shows, lazy_load, set_image_from_path}; +use widgets::BaseView; use std::cell::Cell; use std::rc::Rc; @@ -22,23 +22,30 @@ lazy_static! { #[derive(Debug, Clone)] pub(crate) struct ShowsView { - pub(crate) container: gtk::Box, - scrolled_window: gtk::ScrolledWindow, + view: BaseView, flowbox: gtk::FlowBox, } impl Default for ShowsView { fn default() -> Self { - let builder = gtk::Builder::new_from_resource("/org/gnome/Podcasts/gtk/shows_view.ui"); - let container: gtk::Box = builder.get_object("fb_parent").unwrap(); - let scrolled_window: gtk::ScrolledWindow = builder.get_object("scrolled_window").unwrap(); - let flowbox: gtk::FlowBox = builder.get_object("flowbox").unwrap(); + let view = BaseView::default(); + let flowbox = gtk::FlowBox::new(); - ShowsView { - container, - scrolled_window, - flowbox, - } + flowbox.show(); + flowbox.set_vexpand(true); + flowbox.set_hexpand(true); + flowbox.set_row_spacing(12); + flowbox.set_can_focus(false); + flowbox.set_margin_top(32); + flowbox.set_margin_bottom(32); + flowbox.set_homogeneous(true); + flowbox.set_column_spacing(12); + flowbox.set_valign(Align::Start); + flowbox.set_halign(Align::Center); + flowbox.set_selection_mode(SelectionMode::None); + view.add(&flowbox); + + ShowsView { view, flowbox } } } @@ -59,6 +66,14 @@ impl ShowsView { }); } + pub(crate) fn container(&self) -> >k::Box { + self.view.container() + } + + pub(crate) fn scrolled_window(&self) -> >k::ScrolledWindow { + self.view.scrolled_window() + } + /// Set scrolled window vertical adjustment. fn set_vadjustment(&self) -> Result<(), Error> { let guard = SHOWS_VIEW_VALIGNMENT @@ -69,7 +84,7 @@ impl ShowsView { // Copy the vertical scrollbar adjustment from the old view into the new one. let res = fragile .try_get() - .map(|x| utils::smooth_scroll_to(&self.scrolled_window, &x)) + .map(|x| utils::smooth_scroll_to(self.scrolled_window(), &x)) .map_err(From::from); debug_assert!(res.is_ok()); @@ -83,7 +98,7 @@ impl ShowsView { pub(crate) fn save_alignment(&self) -> Result<(), Error> { if let Ok(mut guard) = SHOWS_VIEW_VALIGNMENT.lock() { let adj = self - .scrolled_window + .scrolled_window() .get_vadjustment() .ok_or_else(|| format_err!("Could not get the adjustment"))?; *guard = Some(Fragile::new(adj)); From 8c25be7d0544bf4df3655e7ad2a4873ef7bcdd8e Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 05:44:04 +0300 Subject: [PATCH 09/24] BaseView: Set scroll policy --- podcasts-gtk/src/widgets/base_view.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/podcasts-gtk/src/widgets/base_view.rs b/podcasts-gtk/src/widgets/base_view.rs index 8846767..3ce5c2e 100644 --- a/podcasts-gtk/src/widgets/base_view.rs +++ b/podcasts-gtk/src/widgets/base_view.rs @@ -1,4 +1,4 @@ -use gtk::{self, prelude::*, Orientation}; +use gtk::{self, prelude::*, Orientation, PolicyType}; #[derive(Debug, Clone)] pub(crate) struct BaseView { @@ -10,6 +10,8 @@ impl Default for BaseView { fn default() -> Self { let container = gtk::Box::new(Orientation::Horizontal, 0); let scrolled_window = gtk::ScrolledWindow::new(None, None); + + scrolled_window.set_policy(PolicyType::Never, PolicyType::Automatic); container.add(&scrolled_window); container.show_all(); From c3121bef84e17c2b4da90ad7d3f9a3d0d1a2a965 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 06:05:05 +0300 Subject: [PATCH 10/24] ShowsChild: Remove the need for a .ui file Its a simple enough widget that can be written by hand and does not need a .ui builder file. --- podcasts-gtk/resources/gtk/shows_child.ui | 58 ----------------------- podcasts-gtk/resources/resources.xml | 1 - podcasts-gtk/src/widgets/shows_view.rs | 22 ++++----- 3 files changed, 8 insertions(+), 73 deletions(-) delete mode 100644 podcasts-gtk/resources/gtk/shows_child.ui diff --git a/podcasts-gtk/resources/gtk/shows_child.ui b/podcasts-gtk/resources/gtk/shows_child.ui deleted file mode 100644 index 1a7d5fd..0000000 --- a/podcasts-gtk/resources/gtk/shows_child.ui +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - 256 - 256 - True - False - center - center - vertical - - - True - False - center - center - 256 - image-x-generic-symbolic - 0 - - - False - True - 0 - - - - diff --git a/podcasts-gtk/resources/resources.xml b/podcasts-gtk/resources/resources.xml index b67f496..e04850a 100644 --- a/podcasts-gtk/resources/resources.xml +++ b/podcasts-gtk/resources/resources.xml @@ -7,7 +7,6 @@ gtk/empty_show.ui gtk/home_view.ui gtk/home_episode.ui - gtk/shows_child.ui gtk/headerbar.ui gtk/inapp_notif.ui gtk/hamburger.ui diff --git a/podcasts-gtk/src/widgets/shows_view.rs b/podcasts-gtk/src/widgets/shows_view.rs index 6866ca9..17436f9 100644 --- a/podcasts-gtk/src/widgets/shows_view.rs +++ b/podcasts-gtk/src/widgets/shows_view.rs @@ -140,28 +140,22 @@ fn on_child_activate(child: >k::FlowBoxChild, sender: &Sender) -> Resu Ok(()) } -#[derive(Debug)] +#[derive(Debug, Clone)] struct ShowsChild { - container: gtk::Box, cover: gtk::Image, child: gtk::FlowBoxChild, } impl Default for ShowsChild { fn default() -> Self { - let builder = gtk::Builder::new_from_resource("/org/gnome/Podcasts/gtk/shows_child.ui"); - - let container: gtk::Box = builder.get_object("fb_child").unwrap(); - let cover: gtk::Image = builder.get_object("pd_cover").unwrap(); - + let cover = gtk::Image::new_from_icon_name("image-x-generic-symbolic", -1); let child = gtk::FlowBoxChild::new(); - child.add(&container); - ShowsChild { - container, - cover, - child, - } + cover.set_pixel_size(256); + child.add(&cover); + child.show_all(); + + ShowsChild { cover, child } } } @@ -173,7 +167,7 @@ impl ShowsChild { } fn init(&self, pd: &Show) { - self.container.set_tooltip_text(pd.title()); + self.child.set_tooltip_text(pd.title()); WidgetExt::set_name(&self.child, &pd.id().to_string()); self.set_cover(pd.id()) From 70a24fba69d32e498fd9e3e1ae69b854b826541f Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 07:20:22 +0300 Subject: [PATCH 11/24] BaseView: implement a set_adjustments method Ment to replace the individual set_vadjustment of widgets. Also remove unused method from ShowWiget. --- podcasts-gtk/src/widgets/base_view.rs | 17 ++++++++++++++++- podcasts-gtk/src/widgets/show.rs | 14 +++----------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/podcasts-gtk/src/widgets/base_view.rs b/podcasts-gtk/src/widgets/base_view.rs index 3ce5c2e..faf6db9 100644 --- a/podcasts-gtk/src/widgets/base_view.rs +++ b/podcasts-gtk/src/widgets/base_view.rs @@ -1,4 +1,5 @@ -use gtk::{self, prelude::*, Orientation, PolicyType}; +use gtk::{self, prelude::*, Adjustment, Orientation, PolicyType}; +use utils::smooth_scroll_to; #[derive(Debug, Clone)] pub(crate) struct BaseView { @@ -34,4 +35,18 @@ impl BaseView { pub(crate) fn add>(&self, widget: &T) { self.scrolled_window.add(widget); } + + pub(crate) fn set_adjutment<'a, 'b>( + &self, + hadjustment: Option<&'a Adjustment>, + vadjustment: Option<&'b Adjustment>, + ) { + if let Some(h) = hadjustment { + smooth_scroll_to(&self.scrolled_window, h); + } + + if let Some(v) = vadjustment { + smooth_scroll_to(&self.scrolled_window, v); + } + } } diff --git a/podcasts-gtk/src/widgets/show.rs b/podcasts-gtk/src/widgets/show.rs index 50fa3f3..84f7fa2 100644 --- a/podcasts-gtk/src/widgets/show.rs +++ b/podcasts-gtk/src/widgets/show.rs @@ -94,10 +94,6 @@ impl ShowWidget { self.view.container() } - pub(crate) fn scrolled_window(&self) -> >k::ScrolledWindow { - self.view.scrolled_window() - } - /// Set the show cover. fn set_cover(&self, pd: &Arc) -> Result<(), Error> { utils::set_image_from_path(&self.cover, pd.id(), 256) @@ -113,6 +109,7 @@ impl ShowWidget { pub(crate) fn save_vadjustment(&self, oldid: i32) -> Result<(), Error> { if let Ok(mut guard) = SHOW_WIDGET_VALIGNMENT.lock() { let adj = self + .view .scrolled_window() .get_vadjustment() .ok_or_else(|| format_err!("Could not get the adjustment"))?; @@ -139,13 +136,8 @@ impl ShowWidget { }; // Copy the vertical scrollbar adjustment from the old view into the new one. - let res = fragile - .try_get() - .map(|x| utils::smooth_scroll_to(self.scrolled_window(), &x)) - .map_err(From::from); - - debug_assert!(res.is_ok()); - return res; + let vadj = fragile.try_get()?; + self.view.set_adjutment(None, Some(&vadj)); } Ok(()) From bcc1cfb67b400a94bbf12f935e6262380a676573 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 08:35:51 +0300 Subject: [PATCH 12/24] ShowWidget: handle vadjustment with BaseView Instead of using lazy_static to save the adjustment, pass it to the widget upon creation. If previous it doesn't exists pass None instead. --- podcasts-gtk/src/stacks/populated.rs | 11 +++-- podcasts-gtk/src/widgets/base_view.rs | 6 ++- podcasts-gtk/src/widgets/show.rs | 68 +++++++-------------------- 3 files changed, 31 insertions(+), 54 deletions(-) diff --git a/podcasts-gtk/src/stacks/populated.rs b/podcasts-gtk/src/stacks/populated.rs index 67a91a8..d7aa1f0 100644 --- a/podcasts-gtk/src/stacks/populated.rs +++ b/podcasts-gtk/src/stacks/populated.rs @@ -90,10 +90,15 @@ impl PopulatedStack { pub(crate) fn replace_widget(&mut self, pd: Arc) -> Result<(), Error> { let old = self.show.container().clone(); - // save the ShowWidget vertical scrollbar alignment - self.show.show_id().map(|id| self.show.save_vadjustment(id)); + // Get the ShowWidget vertical alignment + let vadj = self.show.get_vadjustment(); + let new = match self.show.show_id() { + // If the previous show was the same, restore the alignment + Some(id) if id == pd.id() => ShowWidget::new(pd, self.sender.clone(), vadj), + // else leave the valignemnt to default + _ => ShowWidget::new(pd.clone(), self.sender.clone(), None), + }; - let new = ShowWidget::new(pd, self.sender.clone()); self.show = new; self.stack.remove(&old); self.stack.add_named(self.show.container(), "widget"); diff --git a/podcasts-gtk/src/widgets/base_view.rs b/podcasts-gtk/src/widgets/base_view.rs index faf6db9..f9e901e 100644 --- a/podcasts-gtk/src/widgets/base_view.rs +++ b/podcasts-gtk/src/widgets/base_view.rs @@ -36,7 +36,7 @@ impl BaseView { self.scrolled_window.add(widget); } - pub(crate) fn set_adjutment<'a, 'b>( + pub(crate) fn set_adjutments<'a, 'b>( &self, hadjustment: Option<&'a Adjustment>, vadjustment: Option<&'b Adjustment>, @@ -49,4 +49,8 @@ impl BaseView { smooth_scroll_to(&self.scrolled_window, v); } } + + pub(crate) fn get_vadjustment(&self) -> Option { + self.scrolled_window().get_vadjustment() + } } diff --git a/podcasts-gtk/src/widgets/show.rs b/podcasts-gtk/src/widgets/show.rs index 84f7fa2..db485d3 100644 --- a/podcasts-gtk/src/widgets/show.rs +++ b/podcasts-gtk/src/widgets/show.rs @@ -1,5 +1,5 @@ use glib; -use gtk::{self, prelude::*, SelectionMode}; +use gtk::{self, prelude::*, Adjustment, SelectionMode}; use crossbeam_channel::Sender; use failure::Error; @@ -16,12 +16,7 @@ use utils::{self, lazy_load}; use widgets::{BaseView, EpisodeWidget, ShowMenu}; use std::rc::Rc; -use std::sync::{Arc, Mutex}; - -lazy_static! { - static ref SHOW_WIDGET_VALIGNMENT: Mutex)>> = - Mutex::new(None); -} +use std::sync::Arc; #[derive(Debug, Clone)] pub(crate) struct ShowWidget { @@ -68,7 +63,11 @@ impl Default for ShowWidget { } impl ShowWidget { - pub(crate) fn new(pd: Arc, sender: Sender) -> Rc { + pub(crate) fn new( + pd: Arc, + sender: Sender, + vadj: Option, + ) -> Rc { let mut pdw = ShowWidget::default(); pdw.init(&pd); @@ -76,7 +75,7 @@ impl ShowWidget { sender.send(Action::InitShowMenu(Fragile::new(menu))); let pdw = Rc::new(pdw); - let res = populate_listbox(&pdw, pd.clone(), sender); + let res = populate_listbox(&pdw, pd.clone(), sender, vadj); debug_assert!(res.is_ok()); pdw @@ -94,6 +93,10 @@ impl ShowWidget { self.view.container() } + pub(crate) fn get_vadjustment(&self) -> Option { + self.view.get_vadjustment() + } + /// Set the show cover. fn set_cover(&self, pd: &Arc) -> Result<(), Error> { utils::set_image_from_path(&self.cover, pd.id(), 256) @@ -105,44 +108,6 @@ impl ShowWidget { .set_markup(html2text::from_read(text.as_bytes(), 70).trim()); } - /// Save the scrollbar adjustment to the cache. - pub(crate) fn save_vadjustment(&self, oldid: i32) -> Result<(), Error> { - if let Ok(mut guard) = SHOW_WIDGET_VALIGNMENT.lock() { - let adj = self - .view - .scrolled_window() - .get_vadjustment() - .ok_or_else(|| format_err!("Could not get the adjustment"))?; - *guard = Some((oldid, Fragile::new(adj))); - debug!("Widget Alignment was saved with ID: {}.", oldid); - } - - Ok(()) - } - - /// Set scrolled window vertical adjustment. - fn set_vadjustment(&self, pd: &Arc) -> Result<(), Error> { - let guard = SHOW_WIDGET_VALIGNMENT - .lock() - .map_err(|err| format_err!("Failed to lock widget align mutex: {}", err))?; - - if let Some((oldid, ref fragile)) = *guard { - // Only copy the old scrollbar if both widgets represent the same podcast. - debug!("PID: {}", pd.id()); - debug!("OLDID: {}", oldid); - if pd.id() != oldid { - debug!("Early return"); - return Ok(()); - }; - - // Copy the vertical scrollbar adjustment from the old view into the new one. - let vadj = fragile.try_get()?; - self.view.set_adjutment(None, Some(&vadj)); - } - - Ok(()) - } - pub(crate) fn show_id(&self) -> Option { self.show_id } @@ -150,9 +115,11 @@ impl ShowWidget { /// Populate the listbox with the shows episodes. fn populate_listbox( + // FIXME: we are leaking strong refs here show: &Rc, pd: Arc, sender: Sender, + vadj: Option, ) -> Result<(), Error> { use crossbeam_channel::bounded; @@ -189,9 +156,10 @@ fn populate_listbox( EpisodeWidget::new(ep, &sender).container.clone() }); - let callback = clone!(pd, show_ => move || { - let res = show_.set_vadjustment(&pd); - debug_assert!(res.is_ok()); + let callback = clone!(show_, vadj => move || { + if let Some(ref v) = vadj { + show_.view.set_adjutments(None, Some(v)) + }; }); lazy_load(episodes, list.clone(), constructor, callback); From 5d467a22d0807ec516233b5b7f2b0a1ec92942b8 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 08:40:42 +0300 Subject: [PATCH 13/24] ShowWidget: make base view field publick There is no point to re-export BaseView's methods. --- podcasts-gtk/src/stacks/populated.rs | 10 +++++----- podcasts-gtk/src/widgets/show.rs | 10 +--------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/podcasts-gtk/src/stacks/populated.rs b/podcasts-gtk/src/stacks/populated.rs index d7aa1f0..23e4efe 100644 --- a/podcasts-gtk/src/stacks/populated.rs +++ b/podcasts-gtk/src/stacks/populated.rs @@ -39,7 +39,7 @@ impl PopulatedStack { let container = gtk::Box::new(gtk::Orientation::Horizontal, 0); stack.add_named(populated.container(), "shows"); - stack.add_named(show.container(), "widget"); + stack.add_named(show.view.container(), "widget"); container.add(&stack); container.show_all(); @@ -88,10 +88,10 @@ impl PopulatedStack { } pub(crate) fn replace_widget(&mut self, pd: Arc) -> Result<(), Error> { - let old = self.show.container().clone(); + let old = self.show.view.container().clone(); // Get the ShowWidget vertical alignment - let vadj = self.show.get_vadjustment(); + let vadj = self.show.view.get_vadjustment(); let new = match self.show.show_id() { // If the previous show was the same, restore the alignment Some(id) if id == pd.id() => ShowWidget::new(pd, self.sender.clone(), vadj), @@ -101,7 +101,7 @@ impl PopulatedStack { self.show = new; self.stack.remove(&old); - self.stack.add_named(self.show.container(), "widget"); + self.stack.add_named(self.show.view.container(), "widget"); // The current visible child might change depending on // removal and insertion in the gtk::Stack, so we have @@ -113,7 +113,7 @@ impl PopulatedStack { } pub(crate) fn update_widget(&mut self) -> Result<(), Error> { - let old = self.show.container().clone(); + let old = self.show.view.container().clone(); let id = self.show.show_id(); if id.is_none() { return Ok(()); diff --git a/podcasts-gtk/src/widgets/show.rs b/podcasts-gtk/src/widgets/show.rs index db485d3..173bb6e 100644 --- a/podcasts-gtk/src/widgets/show.rs +++ b/podcasts-gtk/src/widgets/show.rs @@ -20,7 +20,7 @@ use std::sync::Arc; #[derive(Debug, Clone)] pub(crate) struct ShowWidget { - view: BaseView, + pub(crate) view: BaseView, cover: gtk::Image, description: gtk::Label, episodes: gtk::ListBox, @@ -89,14 +89,6 @@ impl ShowWidget { debug_assert!(res.is_ok()); } - pub(crate) fn container(&self) -> >k::Box { - self.view.container() - } - - pub(crate) fn get_vadjustment(&self) -> Option { - self.view.get_vadjustment() - } - /// Set the show cover. fn set_cover(&self, pd: &Arc) -> Result<(), Error> { utils::set_image_from_path(&self.cover, pd.id(), 256) From 85aaaf80ac74509722dcfa824b83dbb8b08110f5 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 08:49:28 +0300 Subject: [PATCH 14/24] ShowsView: make base view field publick There is no point to re-export BaseView's methods. --- podcasts-gtk/src/stacks/populated.rs | 7 ++++--- podcasts-gtk/src/widgets/shows_view.rs | 14 ++++---------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/podcasts-gtk/src/stacks/populated.rs b/podcasts-gtk/src/stacks/populated.rs index 23e4efe..957b494 100644 --- a/podcasts-gtk/src/stacks/populated.rs +++ b/podcasts-gtk/src/stacks/populated.rs @@ -38,7 +38,7 @@ impl PopulatedStack { let show = Rc::new(ShowWidget::default()); let container = gtk::Box::new(gtk::Orientation::Horizontal, 0); - stack.add_named(populated.container(), "shows"); + stack.add_named(populated.view.container(), "shows"); stack.add_named(show.view.container(), "widget"); container.add(&stack); container.show_all(); @@ -70,7 +70,7 @@ impl PopulatedStack { } pub(crate) fn replace_shows(&mut self) -> Result<(), Error> { - let old = &self.populated.container().clone(); + let old = &self.populated.view.container().clone(); debug!("Name: {:?}", WidgetExt::get_name(old)); self.populated @@ -81,7 +81,8 @@ impl PopulatedStack { let pop = ShowsView::new(self.sender.clone()); self.populated = pop; self.stack.remove(old); - self.stack.add_named(self.populated.container(), "shows"); + self.stack + .add_named(self.populated.view.container(), "shows"); old.destroy(); Ok(()) diff --git a/podcasts-gtk/src/widgets/shows_view.rs b/podcasts-gtk/src/widgets/shows_view.rs index 17436f9..d4803e0 100644 --- a/podcasts-gtk/src/widgets/shows_view.rs +++ b/podcasts-gtk/src/widgets/shows_view.rs @@ -22,7 +22,7 @@ lazy_static! { #[derive(Debug, Clone)] pub(crate) struct ShowsView { - view: BaseView, + pub(crate) view: BaseView, flowbox: gtk::FlowBox, } @@ -66,14 +66,6 @@ impl ShowsView { }); } - pub(crate) fn container(&self) -> >k::Box { - self.view.container() - } - - pub(crate) fn scrolled_window(&self) -> >k::ScrolledWindow { - self.view.scrolled_window() - } - /// Set scrolled window vertical adjustment. fn set_vadjustment(&self) -> Result<(), Error> { let guard = SHOWS_VIEW_VALIGNMENT @@ -84,7 +76,7 @@ impl ShowsView { // Copy the vertical scrollbar adjustment from the old view into the new one. let res = fragile .try_get() - .map(|x| utils::smooth_scroll_to(self.scrolled_window(), &x)) + .map(|x| utils::smooth_scroll_to(self.view.scrolled_window(), &x)) .map_err(From::from); debug_assert!(res.is_ok()); @@ -98,6 +90,7 @@ impl ShowsView { pub(crate) fn save_alignment(&self) -> Result<(), Error> { if let Ok(mut guard) = SHOWS_VIEW_VALIGNMENT.lock() { let adj = self + .view .scrolled_window() .get_vadjustment() .ok_or_else(|| format_err!("Could not get the adjustment"))?; @@ -114,6 +107,7 @@ fn populate_flowbox(shows: &Rc) -> Result<(), Error> { let podcasts = dbqueries::get_podcasts_filter(&ignore)?; let constructor = move |parent| ShowsChild::new(&parent).child; + // FIXME: We are, possibly,leaking the strong ref here let callback = clone!(shows => move || { shows.set_vadjustment() .map_err(|err| error!("Failed to set ShowsView Alignment: {}", err)) From aa5195e5a9432d3922028acd2ee0dce9c5b18140 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 09:38:32 +0300 Subject: [PATCH 15/24] ShowsView: handle vadjustment with BaseView Instead of using lazy_static to save the adjustment, pass it to the widget upon creation. If its the first instance created, pass None instead. --- podcasts-gtk/src/stacks/populated.rs | 10 ++--- podcasts-gtk/src/widgets/shows_view.rs | 57 ++++---------------------- 2 files changed, 11 insertions(+), 56 deletions(-) diff --git a/podcasts-gtk/src/stacks/populated.rs b/podcasts-gtk/src/stacks/populated.rs index 957b494..f275699 100644 --- a/podcasts-gtk/src/stacks/populated.rs +++ b/podcasts-gtk/src/stacks/populated.rs @@ -34,7 +34,7 @@ impl PopulatedStack { pub(crate) fn new(sender: Sender) -> PopulatedStack { let stack = gtk::Stack::new(); let state = PopulatedState::View; - let populated = ShowsView::new(sender.clone()); + let populated = ShowsView::new(sender.clone(), None); let show = Rc::new(ShowWidget::default()); let container = gtk::Box::new(gtk::Orientation::Horizontal, 0); @@ -73,12 +73,8 @@ impl PopulatedStack { let old = &self.populated.view.container().clone(); debug!("Name: {:?}", WidgetExt::get_name(old)); - self.populated - .save_alignment() - .map_err(|err| error!("Failed to set episodes_view alignment: {}", err)) - .ok(); - - let pop = ShowsView::new(self.sender.clone()); + let vadj = self.populated.view.get_vadjustment(); + let pop = ShowsView::new(self.sender.clone(), vadj); self.populated = pop; self.stack.remove(old); self.stack diff --git a/podcasts-gtk/src/widgets/shows_view.rs b/podcasts-gtk/src/widgets/shows_view.rs index d4803e0..e4bace7 100644 --- a/podcasts-gtk/src/widgets/shows_view.rs +++ b/podcasts-gtk/src/widgets/shows_view.rs @@ -1,24 +1,18 @@ -use gtk::{self, prelude::*, Align, SelectionMode}; +use gtk::{self, prelude::*, Adjustment, Align, SelectionMode}; use crossbeam_channel::Sender; use failure::Error; -use fragile::Fragile; use podcasts_data::dbqueries; use podcasts_data::Show; use app::Action; -use utils::{self, get_ignored_shows, lazy_load, set_image_from_path}; +use utils::{get_ignored_shows, lazy_load, set_image_from_path}; use widgets::BaseView; use std::cell::Cell; use std::rc::Rc; use std::sync::Arc; -use std::sync::Mutex; - -lazy_static! { - static ref SHOWS_VIEW_VALIGNMENT: Mutex>> = Mutex::new(None); -} #[derive(Debug, Clone)] pub(crate) struct ShowsView { @@ -50,11 +44,11 @@ impl Default for ShowsView { } impl ShowsView { - pub(crate) fn new(sender: Sender) -> Rc { + pub(crate) fn new(sender: Sender, vadj: Option) -> Rc { let pop = Rc::new(ShowsView::default()); pop.init(sender); // Populate the flowbox with the Shows. - let res = populate_flowbox(&pop); + let res = populate_flowbox(&pop, vadj); debug_assert!(res.is_ok()); pop } @@ -65,53 +59,18 @@ impl ShowsView { debug_assert!(res.is_ok()); }); } - - /// Set scrolled window vertical adjustment. - fn set_vadjustment(&self) -> Result<(), Error> { - let guard = SHOWS_VIEW_VALIGNMENT - .lock() - .map_err(|err| format_err!("Failed to lock widget align mutex: {}", err))?; - - if let Some(ref fragile) = *guard { - // Copy the vertical scrollbar adjustment from the old view into the new one. - let res = fragile - .try_get() - .map(|x| utils::smooth_scroll_to(self.view.scrolled_window(), &x)) - .map_err(From::from); - - debug_assert!(res.is_ok()); - return res; - } - - Ok(()) - } - - /// Save the vertical scrollbar position. - pub(crate) fn save_alignment(&self) -> Result<(), Error> { - if let Ok(mut guard) = SHOWS_VIEW_VALIGNMENT.lock() { - let adj = self - .view - .scrolled_window() - .get_vadjustment() - .ok_or_else(|| format_err!("Could not get the adjustment"))?; - *guard = Some(Fragile::new(adj)); - info!("Saved episodes_view alignment."); - } - - Ok(()) - } } -fn populate_flowbox(shows: &Rc) -> Result<(), Error> { +fn populate_flowbox(shows: &Rc, vadj: Option) -> Result<(), Error> { let ignore = get_ignored_shows()?; let podcasts = dbqueries::get_podcasts_filter(&ignore)?; let constructor = move |parent| ShowsChild::new(&parent).child; // FIXME: We are, possibly,leaking the strong ref here let callback = clone!(shows => move || { - shows.set_vadjustment() - .map_err(|err| error!("Failed to set ShowsView Alignment: {}", err)) - .ok(); + if let Some(ref v) = vadj { + shows.view.set_adjutments(None, Some(v)) + }; }); let flowbox = shows.flowbox.clone(); From 056d971000a8fddfc0907cfe79d81f6f0863210c Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 09:47:54 +0300 Subject: [PATCH 16/24] HomeView: make base view field publick There is no point to re-export BaseView's methods. --- podcasts-gtk/src/stacks/home.rs | 6 +++--- podcasts-gtk/src/widgets/home_view.rs | 15 ++++----------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/podcasts-gtk/src/stacks/home.rs b/podcasts-gtk/src/stacks/home.rs index 9dce4cd..fd86085 100644 --- a/podcasts-gtk/src/stacks/home.rs +++ b/podcasts-gtk/src/stacks/home.rs @@ -34,7 +34,7 @@ impl HomeStack { let stack = gtk::Stack::new(); let state = State::Empty; - stack.add_named(episodes.container(), "home"); + stack.add_named(episodes.view.container(), "home"); stack.add_named(&empty.container, "empty"); let mut home = HomeStack { @@ -67,14 +67,14 @@ impl HomeStack { fn replace_view(&mut self) -> Result<(), Error> { // Get the container of the view - let old = &self.episodes.container().clone(); + let old = &self.episodes.view.container().clone(); let eps = HomeView::new(self.sender.clone())?; // Remove the old widget and add the new one // during this the previous view is removed, // and the visible child falls back to empty view. self.stack.remove(old); - self.stack.add_named(eps.container(), "home"); + self.stack.add_named(eps.view.container(), "home"); // Keep the previous state. let s = self.state; // Set the visible child back to the previous one to avoid diff --git a/podcasts-gtk/src/widgets/home_view.rs b/podcasts-gtk/src/widgets/home_view.rs index 59878e9..b11bbea 100644 --- a/podcasts-gtk/src/widgets/home_view.rs +++ b/podcasts-gtk/src/widgets/home_view.rs @@ -34,7 +34,7 @@ enum ListSplit { #[derive(Debug, Clone)] pub(crate) struct HomeView { - view: BaseView, + pub(crate) view: BaseView, frame_parent: gtk::Box, today_box: gtk::Box, yday_box: gtk::Box, @@ -125,18 +125,10 @@ impl HomeView { }; lazy_load_full(episodes, func, callback); - view.container().show_all(); + view.view.container().show_all(); Ok(view) } - pub(crate) fn container(&self) -> >k::Box { - self.view.container() - } - - pub(crate) fn scrolled_window(&self) -> >k::ScrolledWindow { - self.view.scrolled_window() - } - /// Set scrolled window vertical adjustment. fn set_vadjustment(&self) -> Result<(), Error> { let guard = EPISODES_VIEW_VALIGNMENT @@ -147,7 +139,7 @@ impl HomeView { // Copy the vertical scrollbar adjustment from the old view into the new one. let res = fragile .try_get() - .map(|x| utils::smooth_scroll_to(self.scrolled_window(), &x)) + .map(|x| utils::smooth_scroll_to(self.view.scrolled_window(), &x)) .map_err(From::from); debug_assert!(res.is_ok()); @@ -161,6 +153,7 @@ impl HomeView { pub(crate) fn save_alignment(&self) -> Result<(), Error> { if let Ok(mut guard) = EPISODES_VIEW_VALIGNMENT.lock() { let adj = self + .view .scrolled_window() .get_vadjustment() .ok_or_else(|| format_err!("Could not get the adjustment"))?; From 28f08ed19663cf0fdaac3b7f6f29d4901688b8b4 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 10:07:46 +0300 Subject: [PATCH 17/24] HomeView: handle vadjustment with BaseView Instead of using lazy_static to save the adjustment, pass it to the widget upon creation. If its the first instance created, pass None instead. --- podcasts-gtk/src/stacks/home.rs | 13 ++-- podcasts-gtk/src/widgets/home_view.rs | 87 +++++++++------------------ 2 files changed, 33 insertions(+), 67 deletions(-) diff --git a/podcasts-gtk/src/stacks/home.rs b/podcasts-gtk/src/stacks/home.rs index fd86085..252bd59 100644 --- a/podcasts-gtk/src/stacks/home.rs +++ b/podcasts-gtk/src/stacks/home.rs @@ -29,7 +29,7 @@ pub(crate) struct HomeStack { impl HomeStack { pub(crate) fn new(sender: Sender) -> Result { - let episodes = HomeView::new(sender.clone())?; + let episodes = HomeView::new(sender.clone(), None)?; let empty = EmptyView::new(); let stack = gtk::Stack::new(); let state = State::Empty; @@ -54,12 +54,6 @@ impl HomeStack { } pub(crate) fn update(&mut self) -> Result<(), Error> { - // Copy the vertical scrollbar adjustment from the old view. - self.episodes - .save_alignment() - .map_err(|err| error!("Failed to set episodes_view alignment: {}", err)) - .ok(); - self.replace_view()?; // Determine the actual state. self.determine_state().map_err(From::from) @@ -68,7 +62,10 @@ impl HomeStack { fn replace_view(&mut self) -> Result<(), Error> { // Get the container of the view let old = &self.episodes.view.container().clone(); - let eps = HomeView::new(self.sender.clone())?; + + // Copy the vertical scrollbar adjustment from the old view. + let vadj = self.episodes.view.get_vadjustment(); + let eps = HomeView::new(self.sender.clone(), vadj)?; // Remove the old widget and add the new one // during this the previous view is removed, diff --git a/podcasts-gtk/src/widgets/home_view.rs b/podcasts-gtk/src/widgets/home_view.rs index b11bbea..af85708 100644 --- a/podcasts-gtk/src/widgets/home_view.rs +++ b/podcasts-gtk/src/widgets/home_view.rs @@ -1,11 +1,9 @@ use chrono::prelude::*; use failure::Error; -use gtk; -use gtk::prelude::*; +use gtk::{self, prelude::*, Adjustment}; use crossbeam_channel::Sender; -use fragile::Fragile; use libhandy::{Column, ColumnExt}; use podcasts_data::dbqueries; use podcasts_data::EpisodeWidgetModel; @@ -16,12 +14,6 @@ use widgets::{BaseView, EpisodeWidget}; use std::cell::Cell; use std::rc::Rc; -use std::sync::Mutex; - -lazy_static! { - pub(crate) static ref EPISODES_VIEW_VALIGNMENT: Mutex>> = - Mutex::new(None); -} #[derive(Debug, Clone)] enum ListSplit { @@ -94,74 +86,51 @@ impl Default for HomeView { // TODO: REFACTOR ME impl HomeView { - pub(crate) fn new(sender: Sender) -> Result, Error> { + pub(crate) fn new( + sender: Sender, + vadj: Option, + ) -> Result, Error> { use self::ListSplit::*; - let view = Rc::new(HomeView::default()); + let home = Rc::new(HomeView::default()); let ignore = utils::get_ignored_shows()?; let episodes = dbqueries::get_episodes_widgets_filter_limit(&ignore, 100)?; let now_utc = Utc::now(); - let view_ = view.clone(); + let home_weak = Rc::downgrade(&home); let func = move |ep: EpisodeWidgetModel| { + let home = match home_weak.upgrade() { + Some(h) => h, + None => return, + }; + let epoch = ep.epoch(); let widget = HomeEpisode::new(ep, &sender); match split(&now_utc, i64::from(epoch)) { - Today => add_to_box(&widget, &view_.today_list, &view_.today_box), - Yday => add_to_box(&widget, &view_.yday_list, &view_.yday_box), - Week => add_to_box(&widget, &view_.week_list, &view_.week_box), - Month => add_to_box(&widget, &view_.month_list, &view_.month_box), - Rest => add_to_box(&widget, &view_.rest_list, &view_.rest_box), + Today => add_to_box(&widget, &home.today_list, &home.today_box), + Yday => add_to_box(&widget, &home.yday_list, &home.yday_box), + Week => add_to_box(&widget, &home.week_list, &home.week_box), + Month => add_to_box(&widget, &home.month_list, &home.month_box), + Rest => add_to_box(&widget, &home.rest_list, &home.rest_box), } }; - let view_ = view.clone(); + let home_weak = Rc::downgrade(&home); let callback = move || { - view_ - .set_vadjustment() - .map_err(|err| format!("{}", err)) - .ok(); + let home = match home_weak.upgrade() { + Some(h) => h, + None => return, + }; + + if let Some(ref v) = vadj { + home.view.set_adjutments(None, Some(v)) + }; }; lazy_load_full(episodes, func, callback); - view.view.container().show_all(); - Ok(view) - } - - /// Set scrolled window vertical adjustment. - fn set_vadjustment(&self) -> Result<(), Error> { - let guard = EPISODES_VIEW_VALIGNMENT - .lock() - .map_err(|err| format_err!("Failed to lock widget align mutex: {}", err))?; - - if let Some(ref fragile) = *guard { - // Copy the vertical scrollbar adjustment from the old view into the new one. - let res = fragile - .try_get() - .map(|x| utils::smooth_scroll_to(self.view.scrolled_window(), &x)) - .map_err(From::from); - - debug_assert!(res.is_ok()); - return res; - } - - Ok(()) - } - - /// Save the vertical scrollbar position. - pub(crate) fn save_alignment(&self) -> Result<(), Error> { - if let Ok(mut guard) = EPISODES_VIEW_VALIGNMENT.lock() { - let adj = self - .view - .scrolled_window() - .get_vadjustment() - .ok_or_else(|| format_err!("Could not get the adjustment"))?; - *guard = Some(Fragile::new(adj)); - info!("Saved episodes_view alignment."); - } - - Ok(()) + home.view.container().show_all(); + Ok(home) } } From e068cff37b5a4f1de308a96a339abafe0aa2f93f Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 9 Aug 2018 10:16:55 +0300 Subject: [PATCH 18/24] ShowWidget: Increase the description char limit --- podcasts-gtk/src/widgets/show.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/podcasts-gtk/src/widgets/show.rs b/podcasts-gtk/src/widgets/show.rs index 173bb6e..f4c985c 100644 --- a/podcasts-gtk/src/widgets/show.rs +++ b/podcasts-gtk/src/widgets/show.rs @@ -97,7 +97,7 @@ impl ShowWidget { /// Set the description text. fn set_description(&self, text: &str) { self.description - .set_markup(html2text::from_read(text.as_bytes(), 70).trim()); + .set_markup(html2text::from_read(text.as_bytes(), 90).trim()); } pub(crate) fn show_id(&self) -> Option { From fee3e320abfb46bee02ce8569e5c3c06bb6ee4ab Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 10 Aug 2018 15:43:19 +0300 Subject: [PATCH 19/24] ShowWidget: Move the listbox back to the glade file --- podcasts-gtk/resources/gtk/show_widget.ui | 29 ++++++++++++++++++++++- podcasts-gtk/src/widgets/show.rs | 9 ++----- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/podcasts-gtk/resources/gtk/show_widget.ui b/podcasts-gtk/resources/gtk/show_widget.ui index c3610a9..ab44499 100644 --- a/podcasts-gtk/resources/gtk/show_widget.ui +++ b/podcasts-gtk/resources/gtk/show_widget.ui @@ -100,7 +100,34 @@ Sorry, we could not find a description for this Show. - + + True + False + 0 + in + + + True + False + + + True + False + none + False + + + + + + + + + + True + True + 1 + diff --git a/podcasts-gtk/src/widgets/show.rs b/podcasts-gtk/src/widgets/show.rs index f4c985c..acdd588 100644 --- a/podcasts-gtk/src/widgets/show.rs +++ b/podcasts-gtk/src/widgets/show.rs @@ -1,5 +1,5 @@ use glib; -use gtk::{self, prelude::*, Adjustment, SelectionMode}; +use gtk::{self, prelude::*, Adjustment}; use crossbeam_channel::Sender; use failure::Error; @@ -33,12 +33,9 @@ impl Default for ShowWidget { let sub_cont: gtk::Box = builder.get_object("sub_container").unwrap(); let cover: gtk::Image = builder.get_object("cover").unwrap(); let description: gtk::Label = builder.get_object("description").unwrap(); + let episodes = builder.get_object("episodes").unwrap(); let view = BaseView::default(); - let frame = gtk::Frame::new(None); - let episodes = gtk::ListBox::new(); - episodes.set_selection_mode(SelectionMode::None); - let column = Column::new(); column.set_maximum_width(700); // For some reason the Column is not seen as a gtk::container @@ -46,8 +43,6 @@ impl Default for ShowWidget { let column = column.upcast::(); let column = column.downcast::().unwrap(); - frame.add(&episodes); - sub_cont.add(&frame); column.add(&sub_cont); view.add(&column); column.show_all(); From 223a3b46bffbc7d2602af4ec48f87ac4110414f9 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 10 Aug 2018 15:46:28 +0300 Subject: [PATCH 20/24] Headerbar: Elipsisize show title --- podcasts-gtk/resources/gtk/headerbar.ui | 146 ++++++++++++------------ 1 file changed, 74 insertions(+), 72 deletions(-) diff --git a/podcasts-gtk/resources/gtk/headerbar.ui b/podcasts-gtk/resources/gtk/headerbar.ui index 6dd061b..48115a1 100644 --- a/podcasts-gtk/resources/gtk/headerbar.ui +++ b/podcasts-gtk/resources/gtk/headerbar.ui @@ -3,20 +3,20 @@ Copyright (C) 2017 - 2018 -This file is part of Hammond. +This file is part of GNOEM Podcasts. -Hammond is free software: you can redistribute it and/or modify +GNOEM Podcasts is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -Hammond is distributed in the hope that it will be useful, +GNOEM Podcasts is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with Hammond. If not, see . +along with GNOEM Podcasts. If not, see . Authors: Jordan Petridis @@ -24,9 +24,9 @@ Tobias Bernard --> - + - + @@ -147,6 +147,43 @@ Tobias Bernard False True + + + True + False + vertical + + + True + False + center + center + + + False + True + 0 + + + + + False + True + Show Title + end + False + + + + + + False + True + 1 + + + + True @@ -191,72 +228,6 @@ Tobias Bernard 1 - - - False - True - - - False - - - False - True - 6 - 0 - - - - - False - Fetching new episodes - - - False - True - 1 - - - - - 3 - - - - - True - False - vertical - - - True - False - center - center - - - False - True - 0 - - - - - False - True - Show Title - - - - - - False - True - 1 - - - - True @@ -303,5 +274,36 @@ Tobias Bernard 2 + + + False + True + + + False + + + False + True + 6 + 0 + + + + + False + Fetching new episodes + + + False + True + 1 + + + + + 3 + + From 745064c5ce4d5e9e942feeaadf7376ee06dd992d Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 10 Aug 2018 15:47:20 +0300 Subject: [PATCH 21/24] AddPopOver: Remove deprication warning --- podcasts-gtk/resources/gtk/headerbar.ui | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/podcasts-gtk/resources/gtk/headerbar.ui b/podcasts-gtk/resources/gtk/headerbar.ui index 48115a1..5497721 100644 --- a/podcasts-gtk/resources/gtk/headerbar.ui +++ b/podcasts-gtk/resources/gtk/headerbar.ui @@ -41,10 +41,7 @@ Tobias Bernard True False center - 6 - 6 - 6 - 6 + 6 vertical 6 From 95b69956490be17243006bca62da603d134e30f0 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 10 Aug 2018 15:54:12 +0300 Subject: [PATCH 22/24] Headerbar: Elipsisize update label --- podcasts-gtk/resources/gtk/headerbar.ui | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/podcasts-gtk/resources/gtk/headerbar.ui b/podcasts-gtk/resources/gtk/headerbar.ui index 5497721..2879d0b 100644 --- a/podcasts-gtk/resources/gtk/headerbar.ui +++ b/podcasts-gtk/resources/gtk/headerbar.ui @@ -278,6 +278,8 @@ Tobias Bernard False + center + center False @@ -289,7 +291,10 @@ Tobias Bernard False + center + center Fetching new episodes + end False From 9e525727fdda4d5696bf7695bfd89c4292553210 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 10 Aug 2018 20:49:59 +0300 Subject: [PATCH 23/24] InAppNotif: allow the text to elipsize Also fixe deprications in the glae file, add license --- podcasts-gtk/resources/gtk/inapp_notif.ui | 42 +++++++++++++++++++---- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/podcasts-gtk/resources/gtk/inapp_notif.ui b/podcasts-gtk/resources/gtk/inapp_notif.ui index 9fd61f0..0b76e4f 100644 --- a/podcasts-gtk/resources/gtk/inapp_notif.ui +++ b/podcasts-gtk/resources/gtk/inapp_notif.ui @@ -1,7 +1,35 @@ - + - + + + + + + True False @@ -21,18 +49,20 @@ False center center - 3 - 3 + 3 + 3 6 + 150 True False center center - 12 - 12 + 12 + 12 An in-app action notification + start False From d5ea0d5a17ae39bf86979b219f8cb6e041bd7104 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 10 Aug 2018 21:14:49 +0300 Subject: [PATCH 24/24] HoveView and ShowWiget: Add margins around the listboxes --- podcasts-gtk/resources/gtk/home_view.ui | 10 ++++++++++ podcasts-gtk/resources/gtk/show_widget.ui | 2 ++ 2 files changed, 12 insertions(+) diff --git a/podcasts-gtk/resources/gtk/home_view.ui b/podcasts-gtk/resources/gtk/home_view.ui index 86e34c7..e64b1ba 100644 --- a/podcasts-gtk/resources/gtk/home_view.ui +++ b/podcasts-gtk/resources/gtk/home_view.ui @@ -67,6 +67,8 @@ Tobias Bernard True False + 6 + 6 True 0 in @@ -123,6 +125,8 @@ Tobias Bernard True False + 6 + 6 True 0 in @@ -179,6 +183,8 @@ Tobias Bernard True False + 6 + 6 True 0 in @@ -235,6 +241,8 @@ Tobias Bernard True False + 6 + 6 True 0 in @@ -292,6 +300,8 @@ Tobias Bernard True False + 6 + 6 True 0 in diff --git a/podcasts-gtk/resources/gtk/show_widget.ui b/podcasts-gtk/resources/gtk/show_widget.ui index ab44499..0eccaa1 100644 --- a/podcasts-gtk/resources/gtk/show_widget.ui +++ b/podcasts-gtk/resources/gtk/show_widget.ui @@ -103,6 +103,8 @@ Sorry, we could not find a description for this Show. True False + 6 + 6 0 in