ShowWidget: Move listbox population to widgets/show.rs
This commit is contained in:
parent
a0154c5919
commit
b8995d838a
@ -223,13 +223,17 @@ Tobias Bernard
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkFrame" id="episodes">
|
<object class="GtkFrame">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="label_xalign">0</property>
|
<property name="label_xalign">0</property>
|
||||||
<property name="shadow_type">in</property>
|
<property name="shadow_type">in</property>
|
||||||
<child>
|
<child>
|
||||||
<placeholder/>
|
<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>
|
||||||
<child type="label_item">
|
<child type="label_item">
|
||||||
<placeholder/>
|
<placeholder/>
|
||||||
|
|||||||
@ -5,16 +5,14 @@ use gtk::prelude::*;
|
|||||||
use failure::Error;
|
use failure::Error;
|
||||||
use humansize::FileSize;
|
use humansize::FileSize;
|
||||||
use open;
|
use open;
|
||||||
use rayon;
|
|
||||||
use take_mut;
|
use take_mut;
|
||||||
|
|
||||||
use hammond_data::dbqueries;
|
use hammond_data::dbqueries;
|
||||||
use hammond_data::utils::get_download_folder;
|
use hammond_data::utils::get_download_folder;
|
||||||
use hammond_data::{EpisodeWidgetQuery, Podcast};
|
use hammond_data::EpisodeWidgetQuery;
|
||||||
|
|
||||||
use app::Action;
|
use app::Action;
|
||||||
use manager;
|
use manager;
|
||||||
use utils::lazy_load;
|
|
||||||
use widgets::episode_states::*;
|
use widgets::episode_states::*;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
@ -366,47 +364,3 @@ fn total_size_helper(
|
|||||||
// let mut ep = dbqueries::get_episode_from_rowid(episode_id)?.into();
|
// let mut ep = dbqueries::get_episode_from_rowid(episode_id)?.into();
|
||||||
// delete_local_content(&mut ep).map_err(From::from).map(|_| ())
|
// delete_local_content(&mut ep).map_err(From::from).map(|_| ())
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pub fn episodes_listbox(pd: Arc<Podcast>, sender: Sender<Action>) -> Result<gtk::ListBox, Error> {
|
|
||||||
use crossbeam_channel::bounded;
|
|
||||||
use crossbeam_channel::TryRecvError::*;
|
|
||||||
|
|
||||||
let count = dbqueries::get_pd_episodes_count(&pd)?;
|
|
||||||
|
|
||||||
let (sender_, receiver) = bounded(1);
|
|
||||||
rayon::spawn(move || {
|
|
||||||
let episodes = dbqueries::get_pd_episodeswidgets(&pd).unwrap();
|
|
||||||
// The receiver can be dropped if there's an early return
|
|
||||||
// like on show without episodes for example.
|
|
||||||
sender_.send(episodes).ok();
|
|
||||||
});
|
|
||||||
|
|
||||||
let list = gtk::ListBox::new();
|
|
||||||
list.set_visible(true);
|
|
||||||
list.set_selection_mode(gtk::SelectionMode::None);
|
|
||||||
|
|
||||||
if count == 0 {
|
|
||||||
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/empty_show.ui");
|
|
||||||
let container: gtk::Box = builder.get_object("empty_show").unwrap();
|
|
||||||
list.add(&container);
|
|
||||||
return Ok(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk::idle_add(clone!(list => move || {
|
|
||||||
let episodes = match receiver.try_recv() {
|
|
||||||
Ok(e) => e,
|
|
||||||
Err(Empty) => return glib::Continue(true),
|
|
||||||
Err(Disconnected) => return glib::Continue(false),
|
|
||||||
};
|
|
||||||
|
|
||||||
let constructor = clone!(sender => move |ep| {
|
|
||||||
EpisodeWidget::new(ep, sender.clone()).container
|
|
||||||
});
|
|
||||||
|
|
||||||
lazy_load(episodes, list.clone(), constructor, || {});
|
|
||||||
|
|
||||||
glib::Continue(false)
|
|
||||||
}));
|
|
||||||
|
|
||||||
Ok(list)
|
|
||||||
}
|
|
||||||
|
|||||||
@ -13,8 +13,8 @@ use hammond_data::Podcast;
|
|||||||
|
|
||||||
use app::Action;
|
use app::Action;
|
||||||
use appnotif::InAppNotification;
|
use appnotif::InAppNotification;
|
||||||
use utils;
|
use utils::{self, lazy_load};
|
||||||
use widgets::episode::episodes_listbox;
|
use widgets::EpisodeWidget;
|
||||||
|
|
||||||
use std::sync::mpsc::{SendError, Sender};
|
use std::sync::mpsc::{SendError, Sender};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -28,7 +28,7 @@ pub struct ShowWidget {
|
|||||||
link: gtk::Button,
|
link: gtk::Button,
|
||||||
settings: gtk::MenuButton,
|
settings: gtk::MenuButton,
|
||||||
unsub: gtk::Button,
|
unsub: gtk::Button,
|
||||||
episodes: gtk::Frame,
|
episodes: gtk::ListBox,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ShowWidget {
|
impl Default for ShowWidget {
|
||||||
@ -36,7 +36,7 @@ impl Default for ShowWidget {
|
|||||||
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/show_widget.ui");
|
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/show_widget.ui");
|
||||||
let container: gtk::Box = builder.get_object("container").unwrap();
|
let container: gtk::Box = builder.get_object("container").unwrap();
|
||||||
let scrolled_window: gtk::ScrolledWindow = builder.get_object("scrolled_window").unwrap();
|
let scrolled_window: gtk::ScrolledWindow = builder.get_object("scrolled_window").unwrap();
|
||||||
let episodes: gtk::Frame = builder.get_object("episodes").unwrap();
|
let episodes = builder.get_object("episodes").unwrap();
|
||||||
|
|
||||||
let cover: gtk::Image = builder.get_object("cover").unwrap();
|
let cover: gtk::Image = builder.get_object("cover").unwrap();
|
||||||
let description: gtk::Label = builder.get_object("description").unwrap();
|
let description: gtk::Label = builder.get_object("description").unwrap();
|
||||||
@ -75,9 +75,12 @@ impl ShowWidget {
|
|||||||
on_unsub_button_clicked(pd.clone(), bttn, sender.clone());
|
on_unsub_button_clicked(pd.clone(), bttn, sender.clone());
|
||||||
}));
|
}));
|
||||||
|
|
||||||
self.setup_listbox(pd.clone(), sender.clone());
|
|
||||||
self.set_description(pd.description());
|
self.set_description(pd.description());
|
||||||
|
|
||||||
|
self.populate_listbox(pd.clone(), sender.clone())
|
||||||
|
.map_err(|err| error!("Failed to populate the listbox: {}", err))
|
||||||
|
.ok();
|
||||||
|
|
||||||
self.set_cover(pd.clone())
|
self.set_cover(pd.clone())
|
||||||
.map_err(|err| error!("Failed to set a cover: {}", err))
|
.map_err(|err| error!("Failed to set a cover: {}", err))
|
||||||
.ok();
|
.ok();
|
||||||
@ -106,12 +109,6 @@ impl ShowWidget {
|
|||||||
self.settings.set_popover(&show_menu);
|
self.settings.set_popover(&show_menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Populate the listbox with the shows episodes.
|
|
||||||
fn setup_listbox(&self, pd: Arc<Podcast>, sender: Sender<Action>) {
|
|
||||||
let listbox = episodes_listbox(pd, sender.clone());
|
|
||||||
listbox.ok().map(|l| self.episodes.add(&l));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the show cover.
|
/// Set the show cover.
|
||||||
fn set_cover(&self, pd: Arc<Podcast>) -> Result<(), Error> {
|
fn set_cover(&self, pd: Arc<Podcast>) -> Result<(), Error> {
|
||||||
utils::set_image_from_path(&self.cover, Arc::new(pd.into()), 128)
|
utils::set_image_from_path(&self.cover, Arc::new(pd.into()), 128)
|
||||||
@ -126,6 +123,48 @@ impl ShowWidget {
|
|||||||
pub fn set_vadjustment(&self, vadjustment: >k::Adjustment) {
|
pub fn set_vadjustment(&self, vadjustment: >k::Adjustment) {
|
||||||
self.scrolled_window.set_vadjustment(vadjustment)
|
self.scrolled_window.set_vadjustment(vadjustment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Populate the listbox with the shows episodes.
|
||||||
|
fn populate_listbox(&self, pd: Arc<Podcast>, sender: Sender<Action>) -> Result<(), Error> {
|
||||||
|
use crossbeam_channel::bounded;
|
||||||
|
use crossbeam_channel::TryRecvError::*;
|
||||||
|
|
||||||
|
let count = dbqueries::get_pd_episodes_count(&pd)?;
|
||||||
|
|
||||||
|
let (sender_, receiver) = bounded(1);
|
||||||
|
rayon::spawn(move || {
|
||||||
|
let episodes = dbqueries::get_pd_episodeswidgets(&pd).unwrap();
|
||||||
|
// The receiver can be dropped if there's an early return
|
||||||
|
// like on show without episodes for example.
|
||||||
|
sender_.send(episodes).ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
if count == 0 {
|
||||||
|
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/empty_show.ui");
|
||||||
|
let container: gtk::Box = builder.get_object("empty_show").unwrap();
|
||||||
|
self.episodes.add(&container);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let list = self.episodes.clone();
|
||||||
|
gtk::idle_add(move || {
|
||||||
|
let episodes = match receiver.try_recv() {
|
||||||
|
Ok(e) => e,
|
||||||
|
Err(Empty) => return glib::Continue(true),
|
||||||
|
Err(Disconnected) => return glib::Continue(false),
|
||||||
|
};
|
||||||
|
|
||||||
|
let constructor = clone!(sender => move |ep| {
|
||||||
|
EpisodeWidget::new(ep, sender.clone()).container
|
||||||
|
});
|
||||||
|
|
||||||
|
lazy_load(episodes, list.clone(), constructor, || {});
|
||||||
|
|
||||||
|
glib::Continue(false)
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_unsub_button_clicked(pd: Arc<Podcast>, unsub_button: >k::Button, sender: Sender<Action>) {
|
fn on_unsub_button_clicked(pd: Arc<Podcast>, unsub_button: >k::Button, sender: Sender<Action>) {
|
||||||
@ -148,7 +187,7 @@ fn on_unsub_button_clicked(pd: Arc<Podcast>, unsub_button: >k::Button, sender:
|
|||||||
unsub_button.set_sensitive(true);
|
unsub_button.set_sensitive(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_played_button_clicked(pd: Arc<Podcast>, episodes: >k::Frame, sender: Sender<Action>) {
|
fn on_played_button_clicked(pd: Arc<Podcast>, episodes: >k::ListBox, sender: Sender<Action>) {
|
||||||
if dim_titles(episodes).is_none() {
|
if dim_titles(episodes).is_none() {
|
||||||
error!("Something went horribly wrong when dimming the titles.");
|
error!("Something went horribly wrong when dimming the titles.");
|
||||||
warn!("RUN WHILE YOU STILL CAN!");
|
warn!("RUN WHILE YOU STILL CAN!");
|
||||||
@ -229,13 +268,8 @@ pub fn remove_show_notif(pd: Arc<Podcast>, sender: Sender<Action>) -> InAppNotif
|
|||||||
// `for row in listbox { ep = row.get_episode(); ep.dim_title(); }`
|
// `for row in listbox { ep = row.get_episode(); ep.dim_title(); }`
|
||||||
// But now I can't think of a better way to do it than hardcoding the title
|
// But now I can't think of a better way to do it than hardcoding the title
|
||||||
// position relative to the EpisodeWidget container gtk::Box.
|
// position relative to the EpisodeWidget container gtk::Box.
|
||||||
fn dim_titles(episodes: >k::Frame) -> Option<()> {
|
fn dim_titles(episodes: >k::ListBox) -> Option<()> {
|
||||||
let listbox = episodes
|
let children = episodes.get_children();
|
||||||
.get_children()
|
|
||||||
.remove(0)
|
|
||||||
.downcast::<gtk::ListBox>()
|
|
||||||
.ok()?;
|
|
||||||
let children = listbox.get_children();
|
|
||||||
|
|
||||||
for row in children {
|
for row in children {
|
||||||
let row = row.downcast::<gtk::ListBoxRow>().ok()?;
|
let row = row.downcast::<gtk::ListBoxRow>().ok()?;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user