Merge branch 'alatiera/libhandy' into 'master'

Refactor views and use HdyColumn for views with that display `EpisodeWidget`s

Closes #70

See merge request World/podcasts!48
This commit is contained in:
Merge Bot, Bors Wannabe 2018-08-10 18:35:58 +00:00
commit 5a4bce2816
19 changed files with 839 additions and 990 deletions

132
Cargo.lock generated
View File

@ -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)" = "<none>"
"checksum libhandy-sys 0.1.0 (git+https://gitlab.gnome.org/jsparber/libhandy-sys-rs)" = "<none>"
"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"

View File

@ -35,6 +35,16 @@
}
},
"modules" : [
{
"name" : "libhandy",
"buildsystem" : "meson",
"sources" : [
{
"type" : "git",
"url" : "https://source.puri.sm/Librem5/libhandy"
}
]
},
{
"name" : "gnome-podcasts",
"buildsystem" : "meson",

View File

@ -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"

View File

@ -54,7 +54,6 @@ Tobias Bernard
<property name="can_focus">False</property>
<property name="label" translatable="yes">Episode Title</property>
<property name="ellipsize">end</property>
<property name="width_chars">55</property>
<property name="single_line_mode">True</property>
<property name="track_visited_links">False</property>
<property name="lines">1</property>

View File

@ -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 <http://www.gnu.org/licenses/>.
along with GNOEM Podcasts. If not, see <http://www.gnu.org/licenses/>.
Authors:
Jordan Petridis
@ -24,9 +24,9 @@ Tobias Bernard
-->
<interface>
<requires lib="gtk+" version="3.20"/>
<requires lib="gtk+" version="3.22"/>
<!-- interface-license-type gplv3 -->
<!-- interface-name Hammond -->
<!-- interface-name GNOEM Podcasts -->
<!-- interface-description A podcast client for the GNOME Desktop -->
<!-- interface-copyright 2017 - 2018 -->
<!-- interface-authors Jordan Petridis\nTobias Bernard -->
@ -41,10 +41,7 @@ Tobias Bernard
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="border_width">6</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
@ -147,6 +144,43 @@ Tobias Bernard
<object class="GtkHeaderBar" id="headerbar">
<property name="can_focus">False</property>
<property name="show_close_button">True</property>
<child type="title">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkStackSwitcher" id="switch">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="show_title">
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="label" translatable="yes">Show Title</property>
<property name="ellipsize">end</property>
<property name="track_visited_links">False</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkMenuButton" id="add_toggle">
<property name="visible">True</property>
@ -191,72 +225,6 @@ Tobias Bernard
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="update_notification">
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<child>
<object class="GtkSpinner" id="update_spinner">
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="padding">6</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="update_label">
<property name="can_focus">False</property>
<property name="label" translatable="yes">Fetching new episodes</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="position">3</property>
</packing>
</child>
<child type="title">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkStackSwitcher" id="switch">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="show_title">
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="label" translatable="yes">Show Title</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkMenuButton" id="hamburger">
<property name="visible">True</property>
@ -303,5 +271,41 @@ Tobias Bernard
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="update_notification">
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<child>
<object class="GtkSpinner" id="update_spinner">
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="padding">6</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="update_label">
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="label" translatable="yes">Fetching new episodes</property>
<property name="ellipsize">end</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="position">3</property>
</packing>
</child>
</object>
</interface>

View File

@ -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 <http://www.gnu.org/licenses/>.
along with GNOME Podcasts. If not, see <http://www.gnu.org/licenses/>.
Authors:
Jordan Petridis
@ -24,376 +24,312 @@ Tobias Bernard
-->
<interface>
<requires lib="gtk+" version="3.20"/>
<requires lib="gtk+" version="3.22"/>
<!-- interface-license-type gplv3 -->
<!-- interface-name Hammond -->
<!-- interface-name GNOME Podcasts -->
<!-- interface-description A podcast client for the GNOME Desktop -->
<!-- interface-copyright 2017 - 2018 -->
<!-- interface-authors Jordan Petridis\nTobias Bernard -->
<object class="GtkBox" id="container">
<property name="name">container</property>
<property name="width_request">290</property>
<property name="height_request">420</property>
<object class="GtkBox" id="frame_parent">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">32</property>
<property name="margin_bottom">32</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="spacing">24</property>
<child>
<object class="GtkScrolledWindow" id="scrolled_window">
<property name="name">scrolled_window</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
<object class="GtkBox" id="today_box">
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkViewport">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">Today</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.5"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkBox">
<object class="GtkListBox" id="today_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="frame_parent">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">32</property>
<property name="margin_right">32</property>
<property name="margin_top">32</property>
<property name="margin_bottom">32</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="spacing">24</property>
<child>
<object class="GtkBox" id="today_box">
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">Today</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.5"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkListBox" id="today_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="yday_box">
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Yesterday</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.5"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkListBox" id="yday_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="week_box">
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">This Week</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.5"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkListBox" id="week_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="month_box">
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">This Month</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.5"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkListBox" id="month_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkBox" id="rest_box">
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">Older</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.5"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkListBox" id="rest_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">5</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="yday_box">
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Yesterday</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.5"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkListBox" id="yday_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="week_box">
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">This Week</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.5"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkListBox" id="week_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="month_box">
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">This Month</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.5"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkListBox" id="month_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkBox" id="rest_box">
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">Older</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.5"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="hexpand">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkListBox" id="rest_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="no_show_all">True</property>
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">5</property>
</packing>
</child>
</object>
</interface>

View File

@ -1,7 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.21.0 -->
<!-- Generated with glade 3.22.0
Copyright (C) 2017 - 2018
This file is part of GNOME Podcast.
GNOME Podcast 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.
GNOME Podcast 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 GNOME Podcast. If not, see <http://www.gnu.org/licenses/>.
Authors:
Jordan Petridis
Tobias Bernard
-->
<interface>
<requires lib="gtk+" version="3.20"/>
<requires lib="gtk+" version="3.22"/>
<!-- interface-license-type gplv3 -->
<!-- interface-name GNOME Podcast -->
<!-- interface-description A podcast client for the GNOME Desktop -->
<!-- interface-copyright 2017 - 2018 -->
<!-- interface-authors Jordan Petridis\nTobias Bernard -->
<object class="GtkRevealer" id="revealer">
<property name="visible">True</property>
<property name="can_focus">False</property>
@ -21,18 +49,20 @@
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="margin_left">3</property>
<property name="margin_right">3</property>
<property name="margin_start">3</property>
<property name="margin_end">3</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="text">
<property name="width_request">150</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="margin_left">12</property>
<property name="margin_right">12</property>
<property name="margin_start">12</property>
<property name="margin_end">12</property>
<property name="label" translatable="yes">An in-app action notification</property>
<property name="ellipsize">start</property>
</object>
<packing>
<property name="expand">False</property>

View File

@ -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 <http://www.gnu.org/licenses/>.
along with GNOME Podcasts. If not, see <http://www.gnu.org/licenses/>.
Authors:
Jordan Petridis
@ -24,209 +24,112 @@ Tobias Bernard
-->
<interface domain="">
<requires lib="gtk+" version="3.20"/>
<requires lib="gtk+" version="3.22"/>
<!-- interface-license-type gplv3 -->
<!-- interface-name Hammond -->
<!-- interface-name GNOME Podcasts -->
<!-- interface-description A podcast client for the GNOME Desktop -->
<!-- interface-copyright 2017 - 2018 -->
<!-- interface-authors Jordan Petridis\nTobias Bernard -->
<object class="GtkBox" id="container">
<property name="width_request">290</property>
<property name="height_request">420</property>
<object class="GtkBox" id="sub_container">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">32</property>
<property name="margin_bottom">32</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow" id="scrolled_window">
<property name="name">scrolled_window</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="vexpand">True</property>
<property name="hscrollbar_policy">never</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can_default">True</property>
<property name="hexpand">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">32</property>
<property name="margin_right">32</property>
<property name="margin_top">32</property>
<property name="margin_bottom">32</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage" id="cover">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">256</property>
<property name="icon_name">image-x-generic-symbolic</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
<property name="min_content_height">80</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkLabel" id="description">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="label" translatable="yes">This is embarrassing!
Sorry, we could not find a description for this show.</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
<property name="wrap">True</property>
<property name="max_width_chars">70</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">6</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkListBox" id="episodes">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<object class="GtkPopover" id="show_menu">
<property name="can_focus">False</property>
<property name="position">bottom</property>
<property name="spacing">6</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkModelButton" id="mark_all_watched">
<object class="GtkImage" id="cover">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="text" translatable="yes">Mark all episodes as listened</property>
<property name="centered">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">256</property>
<property name="icon_name">image-x-generic-symbolic</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
<property name="min_content_height">80</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkLabel" id="description">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="label">This is embarrasing!
Sorry, we could not find a description for this Show.</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
<property name="wrap">True</property>
<property name="max_width_chars">70</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">6</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkAlignment">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkListBox" id="episodes">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
<property name="activate_on_single_click">False</property>
</object>
</child>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</interface>

View File

@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0
Copyright (C) 2017 - 2018
This file is part of Hammond.
Hammond 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,
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 <http://www.gnu.org/licenses/>.
Authors:
Jordan Petridis
Tobias Bernard
-->
<interface>
<requires lib="gtk+" version="3.20"/>
<!-- interface-license-type gplv3 -->
<!-- interface-name Hammond -->
<!-- interface-description A podcast client for the GNOME Desktop -->
<!-- interface-copyright 2017 - 2018 -->
<!-- interface-authors Jordan Petridis\nTobias Bernard -->
<object class="GtkBox" id="fb_child">
<property name="width_request">256</property>
<property name="height_request">256</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkImage" id="pd_cover">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="pixel_size">256</property>
<property name="icon_name">image-x-generic-symbolic</property>
<property name="icon_size">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</interface>

View File

@ -1,74 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0
Copyright (C) 2017 - 2018
This file is part of Hammond.
Hammond 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,
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 <http://www.gnu.org/licenses/>.
Authors:
Jordan Petridis
Tobias Bernard
-->
<interface>
<requires lib="gtk+" version="3.20"/>
<!-- interface-license-type gplv3 -->
<!-- interface-name Hammond -->
<!-- interface-description A podcast client for the GNOME Desktop -->
<!-- interface-copyright 2017 - 2018 -->
<!-- interface-authors Jordan Petridis\nTobias Bernard -->
<object class="GtkBox" id="fb_parent">
<property name="name">fb_parent</property>
<property name="width_request">290</property>
<property name="height_request">420</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow" id="scrolled_window">
<property name="name">scrolled_window</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkFlowBox" id="flowbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">start</property>
<property name="margin_top">24</property>
<property name="margin_bottom">24</property>
<property name="homogeneous">True</property>
<property name="column_spacing">12</property>
<property name="row_spacing">12</property>
<property name="max_children_per_line">20</property>
<property name="selection_mode">none</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</interface>

View File

@ -7,8 +7,6 @@
<file compressed="true" preprocess="xml-stripblanks">gtk/empty_show.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/home_view.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/home_episode.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/shows_view.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/shows_child.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/headerbar.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/inapp_notif.ui</file>
<file compressed="true" preprocess="xml-stripblanks">gtk/hamburger.ui</file>
@ -20,4 +18,4 @@
<file compressed="true" preprocess="xml-stripblanks">gtk/prefs.ui</file>
<file compressed="true">gtk/style.css</file>
</gresource>
</gresources>
</gresources>

View File

@ -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::*;

View File

@ -29,12 +29,12 @@ pub(crate) struct HomeStack {
impl HomeStack {
pub(crate) fn new(sender: Sender<Action>) -> Result<HomeStack, Error> {
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;
stack.add_named(&episodes.container, "home");
stack.add_named(episodes.view.container(), "home");
stack.add_named(&empty.container, "empty");
let mut home = HomeStack {
@ -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)
@ -67,14 +61,17 @@ impl HomeStack {
fn replace_view(&mut self) -> Result<(), Error> {
// Get the container of the view
let old = &self.episodes.container.clone();
let eps = HomeView::new(self.sender.clone())?;
let old = &self.episodes.view.container().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,
// 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

View File

@ -34,12 +34,12 @@ impl PopulatedStack {
pub(crate) fn new(sender: Sender<Action>) -> 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);
stack.add_named(&populated.container, "shows");
stack.add_named(&show.container, "widget");
stack.add_named(populated.view.container(), "shows");
stack.add_named(show.view.container(), "widget");
container.add(&stack);
container.show_all();
@ -70,33 +70,35 @@ 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
.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.add_named(&self.populated.container, "shows");
self.stack
.add_named(self.populated.view.container(), "shows");
old.destroy();
Ok(())
}
pub(crate) fn replace_widget(&mut self, pd: Arc<Show>) -> Result<(), Error> {
let old = self.show.container.clone();
let old = self.show.view.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.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),
// 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");
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
@ -108,7 +110,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(());

View File

@ -0,0 +1,56 @@
use gtk::{self, prelude::*, Adjustment, Orientation, PolicyType};
use utils::smooth_scroll_to;
#[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);
scrolled_window.set_policy(PolicyType::Never, PolicyType::Automatic);
container.add(&scrolled_window);
container.show_all();
BaseView {
container,
scrolled_window,
}
}
}
impl BaseView {
pub(crate) fn container(&self) -> &gtk::Box {
&self.container
}
pub(crate) fn scrolled_window(&self) -> &gtk::ScrolledWindow {
&self.scrolled_window
}
pub(crate) fn add<T: IsA<gtk::Widget>>(&self, widget: &T) {
self.scrolled_window.add(widget);
}
pub(crate) fn set_adjutments<'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);
}
}
pub(crate) fn get_vadjustment(&self) -> Option<Adjustment> {
self.scrolled_window().get_vadjustment()
}
}

View File

@ -1,26 +1,19 @@
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;
use app::Action;
use utils::{self, lazy_load_full};
use widgets::EpisodeWidget;
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<Option<Fragile<gtk::Adjustment>>> =
Mutex::new(None);
}
#[derive(Debug, Clone)]
enum ListSplit {
@ -33,8 +26,7 @@ enum ListSplit {
#[derive(Debug, Clone)]
pub(crate) struct HomeView {
pub(crate) container: gtk::Box,
scrolled_window: gtk::ScrolledWindow,
pub(crate) view: BaseView,
frame_parent: gtk::Box,
today_box: gtk::Box,
yday_box: gtk::Box,
@ -50,9 +42,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 +56,19 @@ 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();
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::<gtk::Widget>();
let column = column.downcast::<gtk::Container>().unwrap();
column.add(&frame_parent);
view.add(&column);
HomeView {
container,
scrolled_window,
view,
frame_parent,
today_box,
yday_box,
@ -85,73 +86,51 @@ impl Default for HomeView {
// TODO: REFACTOR ME
impl HomeView {
pub(crate) fn new(sender: Sender<Action>) -> Result<Rc<HomeView>, Error> {
pub(crate) fn new(
sender: Sender<Action>,
vadj: Option<Adjustment>,
) -> Result<Rc<HomeView>, 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.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.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
.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)
}
}

View File

@ -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;

View File

@ -1,11 +1,11 @@
use glib;
use gtk;
use gtk::prelude::*;
use gtk::{self, prelude::*, Adjustment};
use crossbeam_channel::Sender;
use failure::Error;
use fragile::Fragile;
use html2text;
use libhandy::{Column, ColumnExt};
use rayon;
use podcasts_data::dbqueries;
@ -13,20 +13,14 @@ 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};
lazy_static! {
static ref SHOW_WIDGET_VALIGNMENT: Mutex<Option<(i32, Fragile<gtk::Adjustment>)>> =
Mutex::new(None);
}
use std::sync::Arc;
#[derive(Debug, Clone)]
pub(crate) struct ShowWidget {
pub(crate) container: gtk::Box,
scrolled_window: gtk::ScrolledWindow,
pub(crate) view: BaseView,
cover: gtk::Image,
description: gtk::Label,
episodes: gtk::ListBox,
@ -36,16 +30,25 @@ pub(crate) struct ShowWidget {
impl Default for ShowWidget {
fn default() -> Self {
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 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 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::<gtk::Widget>();
let column = column.downcast::<gtk::Container>().unwrap();
column.add(&sub_cont);
view.add(&column);
column.show_all();
ShowWidget {
container,
scrolled_window,
view,
cover,
description,
episodes,
@ -55,7 +58,11 @@ impl Default for ShowWidget {
}
impl ShowWidget {
pub(crate) fn new(pd: Arc<Show>, sender: Sender<Action>) -> Rc<ShowWidget> {
pub(crate) fn new(
pd: Arc<Show>,
sender: Sender<Action>,
vadj: Option<Adjustment>,
) -> Rc<ShowWidget> {
let mut pdw = ShowWidget::default();
pdw.init(&pd);
@ -63,7 +70,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
@ -85,49 +92,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());
}
/// 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
.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<Show>) -> 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 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;
}
Ok(())
.set_markup(html2text::from_read(text.as_bytes(), 90).trim());
}
pub(crate) fn show_id(&self) -> Option<i32> {
@ -137,9 +102,11 @@ impl ShowWidget {
/// Populate the listbox with the shows episodes.
fn populate_listbox(
// FIXME: we are leaking strong refs here
show: &Rc<ShowWidget>,
pd: Arc<Show>,
sender: Sender<Action>,
vadj: Option<Adjustment>,
) -> Result<(), Error> {
use crossbeam_channel::bounded;
@ -176,9 +143,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);

View File

@ -1,53 +1,54 @@
use gtk;
use gtk::prelude::*;
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<Option<Fragile<gtk::Adjustment>>> = Mutex::new(None);
}
#[derive(Debug, Clone)]
pub(crate) struct ShowsView {
pub(crate) container: gtk::Box,
scrolled_window: gtk::ScrolledWindow,
pub(crate) 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 }
}
}
impl ShowsView {
pub(crate) fn new(sender: Sender<Action>) -> Rc<Self> {
pub(crate) fn new(sender: Sender<Action>, vadj: Option<Adjustment>) -> Rc<Self> {
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
}
@ -58,51 +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.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
.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<ShowsView>) -> Result<(), Error> {
fn populate_flowbox(shows: &Rc<ShowsView>, vadj: Option<Adjustment>) -> 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();
@ -125,28 +93,22 @@ fn on_child_activate(child: &gtk::FlowBoxChild, sender: &Sender<Action>) -> 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 }
}
}
@ -158,7 +120,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())