Add local and remote favorites

This commit is contained in:
burnintuna 2026-07-22 01:24:37 +09:00
parent 5f9b5d9796
commit 490c925f62
4 changed files with 357 additions and 28 deletions

View file

@ -23,6 +23,11 @@ pub struct ViewerWindow;
pub type SiblingNavigator = Rc<dyn Fn(bool) -> bool>;
pub struct FavoriteControl {
pub active: bool,
pub toggle: Rc<dyn Fn() -> bool>,
}
impl ViewerWindow {
pub fn open(
application: &gtk::Application,
@ -30,6 +35,7 @@ impl ViewerWindow {
database: Rc<Database>,
fast_image_loading: bool,
sibling_navigator: Option<SiblingNavigator>,
favorite_control: FavoriteControl,
) {
let title = source.display_name.clone();
let window = gtk::ApplicationWindow::builder()
@ -40,6 +46,8 @@ impl ViewerWindow {
.build();
let header = gtk::HeaderBar::new();
header.set_title_widget(Some(&gtk::Label::new(Some(&title))));
let favorite_button = gtk::Button::with_label(favorite_label(favorite_control.active));
header.pack_end(&favorite_button);
window.set_titlebar(Some(&header));
let root = gtk::Box::new(gtk::Orientation::Vertical, 0);
@ -152,6 +160,8 @@ impl ViewerWindow {
direction_dropdown,
fast_image_loading,
sibling_navigator,
favorite_button,
favorite_toggle: favorite_control.toggle,
state: RefCell::new(ViewerState {
pages: Vec::new(),
anchor: 0,
@ -228,6 +238,8 @@ struct ViewerController {
direction_dropdown: gtk::DropDown,
fast_image_loading: bool,
sibling_navigator: Option<SiblingNavigator>,
favorite_button: gtk::Button,
favorite_toggle: Rc<dyn Fn() -> bool>,
state: RefCell<ViewerState>,
}
@ -252,6 +264,11 @@ impl ViewerController {
self.direction_dropdown
.connect_selected_notify(move |_| controller.render());
let controller = Rc::clone(self);
self.favorite_button.connect_clicked(move |_| {
let active = (controller.favorite_toggle)();
controller.favorite_button.set_label(favorite_label(active));
});
let controller = Rc::clone(self);
self.page_seek.connect_value_changed(move |scale| {
if let Some(index) =
page_seek_index(scale.value(), controller.state.borrow().pages.len())
@ -927,6 +944,7 @@ impl MediaViewerWindow {
source: ArchiveSource,
kind: EntryKind,
sibling_navigator: Option<SiblingNavigator>,
favorite_control: FavoriteControl,
) {
let title = source.display_name.clone();
let window = gtk::ApplicationWindow::builder()
@ -937,6 +955,8 @@ impl MediaViewerWindow {
.build();
let header = gtk::HeaderBar::new();
header.set_title_widget(Some(&gtk::Label::new(Some(&title))));
let favorite_button = gtk::Button::with_label(favorite_label(favorite_control.active));
header.pack_end(&favorite_button);
window.set_titlebar(Some(&header));
let root = gtk::Box::new(gtk::Orientation::Vertical, 0);
@ -974,6 +994,8 @@ impl MediaViewerWindow {
stack,
status_label,
sibling_navigator,
favorite_button,
favorite_toggle: favorite_control.toggle,
});
if let Some(stream) = controller.video.media_stream() {
let status_label = controller.status_label.clone();
@ -1006,6 +1028,8 @@ struct MediaViewerController {
stack: gtk::Stack,
status_label: gtk::Label,
sibling_navigator: Option<SiblingNavigator>,
favorite_button: gtk::Button,
favorite_toggle: Rc<dyn Fn() -> bool>,
}
impl MediaViewerController {
@ -1032,6 +1056,11 @@ impl MediaViewerController {
_ => glib::Propagation::Proceed,
});
self.window.add_controller(keys);
let controller = Rc::clone(self);
self.favorite_button.connect_clicked(move |_| {
let active = (controller.favorite_toggle)();
controller.favorite_button.set_label(favorite_label(active));
});
}
fn open_sibling(&self, forward: bool) {
@ -1098,6 +1127,14 @@ impl MediaViewerController {
}
}
fn favorite_label(active: bool) -> &'static str {
if active {
"즐겨찾기 제거"
} else {
"즐겨찾기 추가"
}
}
fn page_picture() -> gtk::Picture {
let picture = gtk::Picture::new();
picture.set_content_fit(gtk::ContentFit::Contain);