Commit 60d524b3 authored by Lucas Beeler's avatar Lucas Beeler

Introduces the new MediaPage class that treats photos and videos uniformly. As...

Introduces the new MediaPage class that treats photos and videos uniformly. As a consequence, allows editing titles and setting ratings for videos. Closes #2584.
parent e0fd446e
...@@ -128,7 +128,8 @@ SRC_FILES = \ ...@@ -128,7 +128,8 @@ SRC_FILES = \
Tombstone.vala \ Tombstone.vala \
MetadataWriter.vala \ MetadataWriter.vala \
Application.vala \ Application.vala \
DelayedQueue.vala DelayedQueue.vala \
MediaPage.vala
ifndef LINUX ifndef LINUX
SRC_FILES += \ SRC_FILES += \
...@@ -156,6 +157,7 @@ RESOURCE_FILES = \ ...@@ -156,6 +157,7 @@ RESOURCE_FILES = \
tags.ui \ tags.ui \
trash.ui \ trash.ui \
offline.ui \ offline.ui \
media.ui \
shotwell.glade shotwell.glade
SYS_INTEGRATION_FILES = \ SYS_INTEGRATION_FILES = \
......
This diff is collapsed.
...@@ -437,19 +437,19 @@ public class EditTitleCommand : SingleDataSourceCommand { ...@@ -437,19 +437,19 @@ public class EditTitleCommand : SingleDataSourceCommand {
private string new_title; private string new_title;
private string? old_title; private string? old_title;
public EditTitleCommand(LibraryPhoto photo, string new_title) { public EditTitleCommand(MediaSource source, string new_title) {
base(photo, Resources.EDIT_TITLE_LABEL, Resources.EDIT_TITLE_TOOLTIP); base(source, Resources.EDIT_TITLE_LABEL, Resources.EDIT_TITLE_TOOLTIP);
this.new_title = new_title; this.new_title = new_title;
old_title = photo.get_title(); old_title = source.get_title();
} }
public override void execute() { public override void execute() {
((LibraryPhoto) source).set_title(new_title); ((MediaSource) source).set_title(new_title);
} }
public override void undo() { public override void undo() {
((LibraryPhoto) source).set_title(old_title); ((MediaSource) source).set_title(old_title);
} }
} }
...@@ -863,22 +863,22 @@ public class SetRatingSingleCommand : SingleDataSourceCommand { ...@@ -863,22 +863,22 @@ public class SetRatingSingleCommand : SingleDataSourceCommand {
set_direct = false; set_direct = false;
incrementing = is_incrementing; incrementing = is_incrementing;
last_rating = ((LibraryPhoto)source).get_rating(); last_rating = ((MediaSource) source).get_rating();
} }
public override void execute() { public override void execute() {
if (set_direct) if (set_direct)
((LibraryPhoto) source).set_rating(new_rating); ((MediaSource) source).set_rating(new_rating);
else { else {
if (incrementing) if (incrementing)
((LibraryPhoto) source).increase_rating(); ((MediaSource) source).increase_rating();
else else
((LibraryPhoto) source).decrease_rating(); ((MediaSource) source).decrease_rating();
} }
} }
public override void undo() { public override void undo() {
((LibraryPhoto) source).set_rating(last_rating); ((MediaSource) source).set_rating(last_rating);
} }
} }
...@@ -915,7 +915,7 @@ public class SetRatingCommand : MultipleDataSourceCommand { ...@@ -915,7 +915,7 @@ public class SetRatingCommand : MultipleDataSourceCommand {
foreach (DataView view in iter) { foreach (DataView view in iter) {
DataSource source = view.get_source(); DataSource source = view.get_source();
last_rating_map[source] = ((LibraryPhoto)source).get_rating(); last_rating_map[source] = ((MediaSource) source).get_rating();
} }
} }
...@@ -935,12 +935,12 @@ public class SetRatingCommand : MultipleDataSourceCommand { ...@@ -935,12 +935,12 @@ public class SetRatingCommand : MultipleDataSourceCommand {
public override void execute_on_source(DataSource source) { public override void execute_on_source(DataSource source) {
if (set_direct) if (set_direct)
((LibraryPhoto) source).set_rating(new_rating); ((MediaSource) source).set_rating(new_rating);
else { else {
if (incrementing) if (incrementing)
((LibraryPhoto) source).increase_rating(); ((MediaSource) source).increase_rating();
else else
((LibraryPhoto) source).decrease_rating(); ((MediaSource) source).decrease_rating();
} }
// TODO: Replace this system with a mass set rating function (like Photo.set_event_many) // TODO: Replace this system with a mass set rating function (like Photo.set_event_many)
...@@ -951,7 +951,7 @@ public class SetRatingCommand : MultipleDataSourceCommand { ...@@ -951,7 +951,7 @@ public class SetRatingCommand : MultipleDataSourceCommand {
} }
public override void undo_on_source(DataSource source) { public override void undo_on_source(DataSource source) {
((LibraryPhoto) source).set_rating(last_rating_map[source]); ((MediaSource) source).set_rating(last_rating_map[source]);
if (++action_count % 50 == 0) { if (++action_count % 50 == 0) {
LibraryPhoto.global.thaw_notifications(); LibraryPhoto.global.thaw_notifications();
......
...@@ -445,7 +445,7 @@ public class Config { ...@@ -445,7 +445,7 @@ public class Config {
public void get_library_photos_sort(out bool sort_order, out int sort_by) { public void get_library_photos_sort(out bool sort_order, out int sort_by) {
sort_order = get_bool("/apps/shotwell/preferences/ui/library_photos_sort_ascending", false); sort_order = get_bool("/apps/shotwell/preferences/ui/library_photos_sort_ascending", false);
sort_by = get_int("/apps/shotwell/preferences/ui/library_photos_sort_by", CollectionPage.SortBy.EXPOSURE_DATE); sort_by = get_int("/apps/shotwell/preferences/ui/library_photos_sort_by", MediaPage.SortBy.EXPOSURE_DATE);
} }
public bool set_library_photos_sort(bool sort_order, int sort_by) { public bool set_library_photos_sort(bool sort_order, int sort_by) {
...@@ -455,7 +455,7 @@ public class Config { ...@@ -455,7 +455,7 @@ public class Config {
public void get_event_photos_sort(out bool sort_order, out int sort_by) { public void get_event_photos_sort(out bool sort_order, out int sort_by) {
sort_order = get_bool("/apps/shotwell/preferences/ui/event_photos_sort_ascending", true); sort_order = get_bool("/apps/shotwell/preferences/ui/event_photos_sort_ascending", true);
sort_by = get_int("/apps/shotwell/preferences/ui/event_photos_sort_by", CollectionPage.SortBy.EXPOSURE_DATE); sort_by = get_int("/apps/shotwell/preferences/ui/event_photos_sort_by", MediaPage.SortBy.EXPOSURE_DATE);
} }
public bool set_event_photos_sort(bool sort_order, int sort_by) { public bool set_event_photos_sort(bool sort_order, int sort_by) {
......
...@@ -951,6 +951,16 @@ public abstract class MediaSource : ThumbnailSource { ...@@ -951,6 +951,16 @@ public abstract class MediaSource : ThumbnailSource {
} }
public abstract File get_file(); public abstract File get_file();
public abstract string? get_title();
public abstract void set_title(string? title);
public abstract Rating get_rating();
public abstract void set_rating(Rating rating);
public abstract void increase_rating();
public abstract void decrease_rating();
public abstract Dimensions get_dimensions();
} }
public abstract class PhotoSource : MediaSource { public abstract class PhotoSource : MediaSource {
...@@ -960,8 +970,6 @@ public abstract class PhotoSource : MediaSource { ...@@ -960,8 +970,6 @@ public abstract class PhotoSource : MediaSource {
public abstract time_t get_exposure_time(); public abstract time_t get_exposure_time();
public abstract Dimensions get_dimensions();
public abstract uint64 get_filesize(); public abstract uint64 get_filesize();
public abstract PhotoMetadata? get_metadata(); public abstract PhotoMetadata? get_metadata();
......
...@@ -2555,7 +2555,11 @@ public class VideoTable : DatabaseTable { ...@@ -2555,7 +2555,11 @@ public class VideoTable : DatabaseTable {
public void set_exposure_time(VideoID video_id, time_t time) throws DatabaseError { public void set_exposure_time(VideoID video_id, time_t time) throws DatabaseError {
update_int64_by_id_2(video_id.id, "exposure_time", (int64) time); update_int64_by_id_2(video_id.id, "exposure_time", (int64) time);
} }
public void set_rating(VideoID video_id, Rating rating) throws DatabaseError {
update_int64_by_id_2(video_id.id, "rating", rating.serialize());
}
public void remove_by_file(File file) throws DatabaseError { public void remove_by_file(File file) throws DatabaseError {
Sqlite.Statement stmt; Sqlite.Statement stmt;
int res = db.prepare_v2("DELETE FROM VideoTable WHERE filename=?", -1, out stmt); int res = db.prepare_v2("DELETE FROM VideoTable WHERE filename=?", -1, out stmt);
......
...@@ -435,7 +435,7 @@ public class EventPage : CollectionPage { ...@@ -435,7 +435,7 @@ public class EventPage : CollectionPage {
init_page_context_menu("/EventContextMenu"); init_page_context_menu("/EventContextMenu");
// hide this command in CollectionPage, as it does not apply here // hide this command in CollectionPage, as it does not apply here
set_item_hidden("/CollectionMenuBar/EventsMenu/JumpToEvent"); set_item_hidden("/MediaMenuBar/MenubarExtrasPlaceholder/EventsMenu/JumpToEvent");
set_item_hidden("/CollectionContextMenu/ContextJumpToEvent"); set_item_hidden("/CollectionContextMenu/ContextJumpToEvent");
Event.global.items_altered.connect(on_events_altered); Event.global.items_altered.connect(on_events_altered);
...@@ -481,7 +481,7 @@ public class EventPage : CollectionPage { ...@@ -481,7 +481,7 @@ public class EventPage : CollectionPage {
} }
protected override void on_photos_menu() { protected override void on_photos_menu() {
set_item_sensitive("/CollectionMenuBar/PhotosMenu/MakePrimary", set_item_sensitive("/MediaMenuBar/PhotosMenu/MakePrimary",
get_view().get_selected_count() == 1); get_view().get_selected_count() == 1);
base.on_photos_menu(); base.on_photos_menu();
......
...@@ -432,7 +432,7 @@ public class LibraryWindow : AppWindow { ...@@ -432,7 +432,7 @@ public class LibraryWindow : AppWindow {
Config.get_instance().set_sidebar_position(client_paned.position); Config.get_instance().set_sidebar_position(client_paned.position);
Config.get_instance().set_photo_thumbnail_scale(CollectionPage.get_photo_thumbnail_scale()); Config.get_instance().set_photo_thumbnail_scale(MediaPage.get_global_thumbnail_scale());
base.on_quit(); base.on_quit();
} }
......
This diff is collapsed.
...@@ -83,6 +83,30 @@ public abstract class PageStub : Object, SidebarPage { ...@@ -83,6 +83,30 @@ public abstract class PageStub : Object, SidebarPage {
public abstract class Page : Gtk.ScrolledWindow, SidebarPage { public abstract class Page : Gtk.ScrolledWindow, SidebarPage {
private const int CONSIDER_CONFIGURE_HALTED_MSEC = 400; private const int CONSIDER_CONFIGURE_HALTED_MSEC = 400;
protected struct InjectedUIElement {
public string name;
public string action;
public Gtk.UIManagerItemType kind;
private InjectedUIElement(string name, string action, Gtk.UIManagerItemType kind) {
this.name = name;
this.action = action;
this.kind = kind;
}
public static InjectedUIElement create_menu_item(string name, string action) {
return InjectedUIElement(name, action, Gtk.UIManagerItemType.MENUITEM);
}
public static InjectedUIElement create_menu(string name, string action) {
return InjectedUIElement(name, action, Gtk.UIManagerItemType.MENU);
}
public static InjectedUIElement create_separator() {
return InjectedUIElement("", "", Gtk.UIManagerItemType.SEPARATOR);
}
}
public Gtk.UIManager ui = new Gtk.UIManager(); public Gtk.UIManager ui = new Gtk.UIManager();
public Gtk.ActionGroup action_group = null; public Gtk.ActionGroup action_group = null;
public Gtk.ActionGroup common_action_group = null; public Gtk.ActionGroup common_action_group = null;
...@@ -476,6 +500,13 @@ public abstract class Page : Gtk.ScrolledWindow, SidebarPage { ...@@ -476,6 +500,13 @@ public abstract class Page : Gtk.ScrolledWindow, SidebarPage {
} }
} }
protected void init_ui_inject_elements(string where, InjectedUIElement[] elements) {
foreach (InjectedUIElement element in elements) {
ui.add_ui(ui.new_merge_id(), where, element.name, element.action, element.kind,
false);
}
}
protected void init_ui_start(string ui_filename, string action_group_name, protected void init_ui_start(string ui_filename, string action_group_name,
Gtk.ActionEntry[]? entries = null, Gtk.ToggleActionEntry[]? toggle_entries = null) { Gtk.ActionEntry[]? entries = null, Gtk.ToggleActionEntry[]? toggle_entries = null) {
init_load_ui(ui_filename); init_load_ui(ui_filename);
......
...@@ -1416,13 +1416,13 @@ public abstract class Photo : PhotoSource { ...@@ -1416,13 +1416,13 @@ public abstract class Photo : PhotoSource {
notify_altered(new Alteration("metadata", "master-dirty")); notify_altered(new Alteration("metadata", "master-dirty"));
} }
public Rating get_rating() { public override Rating get_rating() {
lock (row) { lock (row) {
return row.rating; return row.rating;
} }
} }
public void set_rating(Rating rating) { public override void set_rating(Rating rating) {
bool committed = false; bool committed = false;
lock (row) { lock (row) {
...@@ -1437,13 +1437,13 @@ public abstract class Photo : PhotoSource { ...@@ -1437,13 +1437,13 @@ public abstract class Photo : PhotoSource {
notify_altered(new Alteration("metadata", "rating")); notify_altered(new Alteration("metadata", "rating"));
} }
public void increase_rating() { public override void increase_rating() {
lock (row) { lock (row) {
set_rating(row.rating.increase()); set_rating(row.rating.increase());
} }
} }
public void decrease_rating() { public override void decrease_rating() {
lock (row) { lock (row) {
set_rating(row.rating.decrease()); set_rating(row.rating.decrease());
} }
...@@ -1607,13 +1607,13 @@ public abstract class Photo : PhotoSource { ...@@ -1607,13 +1607,13 @@ public abstract class Photo : PhotoSource {
} }
} }
public string? get_title() { public override string? get_title() {
lock (row) { lock (row) {
return row.title; return row.title;
} }
} }
public void set_title(string? title) { public override void set_title(string? title) {
bool committed; bool committed;
lock (row) { lock (row) {
committed = PhotoTable.get_instance().set_title(row.photo_id, title); committed = PhotoTable.get_instance().set_title(row.photo_id, title);
......
...@@ -93,17 +93,17 @@ public class TagPage : CollectionPage { ...@@ -93,17 +93,17 @@ public class TagPage : CollectionPage {
protected override void on_tags_menu() { protected override void on_tags_menu() {
int selected_count = get_view().get_selected_count(); int selected_count = get_view().get_selected_count();
set_item_display("/CollectionMenuBar/TagsMenu/DeleteTag", set_item_display("/MediaMenuBar/MenubarExtrasPlaceholder/TagsMenu/DeleteTag",
Resources.delete_tag_menu(tag.get_name()), Resources.delete_tag_menu(tag.get_name()),
Resources.delete_tag_tooltip(tag.get_name(), tag.get_photos_count()), Resources.delete_tag_tooltip(tag.get_name(), tag.get_photos_count()),
true); true);
set_item_display("/CollectionMenuBar/TagsMenu/RenameTag", set_item_display("/MediaMenuBar/MenubarExtrasPlaceholder/TagsMenu/RenameTag",
Resources.rename_tag_menu(tag.get_name()), Resources.rename_tag_menu(tag.get_name()),
Resources.rename_tag_tooltip(tag.get_name()), Resources.rename_tag_tooltip(tag.get_name()),
true); true);
set_item_display("/CollectionMenuBar/TagsMenu/RemoveTagFromPhotos", set_item_display("/MediaMenuBar/MenubarExtrasPlaceholder/TagsMenu/RemoveTagFromPhotos",
Resources.untag_photos_menu(tag.get_name(), selected_count), Resources.untag_photos_menu(tag.get_name(), selected_count),
Resources.untag_photos_tooltip(tag.get_name(), selected_count), Resources.untag_photos_tooltip(tag.get_name(), selected_count),
selected_count > 0); selected_count > 0);
......
...@@ -35,31 +35,27 @@ public class Thumbnail : CheckerboardItem { ...@@ -35,31 +35,27 @@ public class Thumbnail : CheckerboardItem {
// was showing up in sysprof // was showing up in sysprof
private bool exposure = false; private bool exposure = false;
public Thumbnail(LibraryPhoto photo, int scale = DEFAULT_SCALE) { public Thumbnail(MediaSource source, int scale = DEFAULT_SCALE) {
base(photo, photo.get_dimensions().get_scaled(scale, true), photo.get_name()); base(source, source.get_dimensions(), source.get_name());
this.video = null; if (source is LibraryPhoto) {
this.photo = photo; this.video = null;
this.photo = (LibraryPhoto) source;
Tag.global.container_contents_altered.connect(on_tag_contents_altered);
Tag.global.items_altered.connect(on_tags_altered);
} else if (source is Video) {
this.video = (Video) source;
this.photo = null;
}
this.scale = scale; this.scale = scale;
original_dim = photo.get_dimensions(); original_dim = source.get_dimensions();
dim = original_dim.get_scaled(scale, true); dim = original_dim.get_scaled(scale, true);
// if the photo's tags changes, update it here LibraryPhoto.global.items_altered.connect(on_sources_altered);
Tag.global.container_contents_altered.connect(on_tag_contents_altered); Video.global.items_altered.connect(on_sources_altered);
Tag.global.items_altered.connect(on_tags_altered);
LibraryPhoto.global.items_altered.connect(on_photos_altered);
}
public Thumbnail.for_video(Video video, int scale = DEFAULT_SCALE) {
base(video, video.get_frame_dimensions().get_scaled(scale, true), video.get_name());
this.video = video;
this.photo = null;
this.scale = scale;
original_dim = video.get_frame_dimensions();
dim = original_dim.get_scaled(scale, true);
} }
~Thumbnail() { ~Thumbnail() {
...@@ -68,7 +64,8 @@ public class Thumbnail : CheckerboardItem { ...@@ -68,7 +64,8 @@ public class Thumbnail : CheckerboardItem {
Tag.global.container_contents_altered.disconnect(on_tag_contents_altered); Tag.global.container_contents_altered.disconnect(on_tag_contents_altered);
Tag.global.items_altered.disconnect(on_tags_altered); Tag.global.items_altered.disconnect(on_tags_altered);
LibraryPhoto.global.items_altered.disconnect(on_photos_altered); LibraryPhoto.global.items_altered.disconnect(on_sources_altered);
Video.global.items_altered.disconnect(on_sources_altered);
} }
private void update_tags() { private void update_tags() {
...@@ -114,18 +111,18 @@ public class Thumbnail : CheckerboardItem { ...@@ -114,18 +111,18 @@ public class Thumbnail : CheckerboardItem {
} }
private void update_title() { private void update_title() {
string title = (is_video()) ? video.get_name() : photo.get_name(); string title = get_media_source().get_name();
if (is_string_empty(title)) if (is_string_empty(title))
clear_title(); clear_title();
else else
set_title(title); set_title(title);
} }
private void on_photos_altered(Gee.Map<DataObject, Alteration> map) { private void on_sources_altered(Gee.Map<DataObject, Alteration> map) {
if (!exposure || !map.has_key(photo)) if (!exposure || !map.has_key(get_media_source()))
return; return;
if ((!is_video()) && map.get(photo).has_detail("metadata", "name")) if (map.get(get_media_source()).has_detail("metadata", "name"))
update_title(); update_title();
} }
...@@ -138,6 +135,13 @@ public class Thumbnail : CheckerboardItem { ...@@ -138,6 +135,13 @@ public class Thumbnail : CheckerboardItem {
return video; return video;
} }
public MediaSource get_media_source() {
if (is_video())
return video;
else
return photo;
}
// //
// Comparators // Comparators
// //
...@@ -409,6 +413,6 @@ public class Thumbnail : CheckerboardItem { ...@@ -409,6 +413,6 @@ public class Thumbnail : CheckerboardItem {
} }
public Rating get_rating() { public Rating get_rating() {
return (is_video()) ? Rating.UNRATED : photo.get_rating(); return get_media_source().get_rating();
} }
} }
...@@ -365,9 +365,75 @@ public class Video : VideoSource { ...@@ -365,9 +365,75 @@ public class Video : VideoSource {
} }
public override string get_name() { public override string get_name() {
lock (backing_row) {
if (!is_string_empty(backing_row.title))
return backing_row.title;
}
return get_basename(); return get_basename();
} }
public override string? get_title() {
lock (backing_row) {
return backing_row.title;
}
}
public override void set_title(string? title) {
lock (backing_row) {
if (backing_row.title == title)
return;
try {
VideoTable.get_instance().set_title(backing_row.video_id, title);
} catch (DatabaseError e) {
AppWindow.database_error(e);
return;
}
// if we didn't short-circuit return in the catch clause above, then the change was
// successfully committed to the database, so update it in the in-memory row cache
backing_row.title = title;
}
notify_altered(new Alteration("metadata", "name"));
}
public override Rating get_rating() {
lock (backing_row) {
return backing_row.rating;
}
}
public override void set_rating(Rating rating) {
lock (backing_row) {
if ((!rating.is_valid()) || (rating == backing_row.rating))
return;
try {
VideoTable.get_instance().set_rating(get_video_id(), rating);
} catch (DatabaseError e) {
AppWindow.database_error(e);
return;
}
// if we didn't short-circuit return in the catch clause above, then the change was
// successfully committed to the database, so update it in the in-memory row cache
backing_row.rating = rating;
}
notify_altered(new Alteration("metadata", "rating"));
}
public override void increase_rating() {
lock (backing_row) {
set_rating(backing_row.rating.increase());
}
}
public override void decrease_rating() {
lock (backing_row) {
set_rating(backing_row.rating.decrease());
}
}
public string get_basename() { public string get_basename() {
lock (backing_row) { lock (backing_row) {
return Filename.display_basename(backing_row.filepath); return Filename.display_basename(backing_row.filepath);
...@@ -397,6 +463,10 @@ public class Video : VideoSource { ...@@ -397,6 +463,10 @@ public class Video : VideoSource {
return Dimensions(backing_row.width, backing_row.height); return Dimensions(backing_row.width, backing_row.height);
} }
} }
public override Dimensions get_dimensions() {
return get_frame_dimensions();
}
public uint64 get_filesize() { public uint64 get_filesize() {
lock (backing_row) { lock (backing_row) {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* See the COPYING file in this distribution. * See the COPYING file in this distribution.
*/ */
public class VideosPage : CheckerboardPage { public class VideosPage : MediaPage {
public class Stub : PageStub { public class Stub : PageStub {
public Stub() { public Stub() {
} }
...@@ -24,19 +24,28 @@ public class VideosPage : CheckerboardPage { ...@@ -24,19 +24,28 @@ public class VideosPage : CheckerboardPage {
private class VideoView : Thumbnail { private class VideoView : Thumbnail {
public VideoView(Video video) { public VideoView(Video video) {
base.for_video(video); base(video);
} }
} }
private Gtk.HScale slider = null;
private int scale;
private ExporterUI exporter = null; private ExporterUI exporter = null;
public VideosPage() { public VideosPage() {
base (_("Videos")); base (_("Videos"));
init_ui("videos.ui", "/VideosMenuBar", "VideosActionGroup", create_actions(), // add actions and customize MediaPage UI elements for videos
create_toggle_actions()); action_group.add_actions(create_actions(), this);
action_group.get_action("PlayVideo").is_important = true;
action_group.get_action("PhotosMenu").set_label(_("Vi_deos"));
action_group.get_action("FilterPhotos").set_label(_("_Filter Videos"));
action_group.get_action("SortPhotos").set_label(_("Sort _Videos"));
action_group.get_action("DisplayUnratedOrHigher").set_label(_("_All Videos"));
// inject menu extras
init_ui_inject_elements("/MediaMenuBar/EditMenu/EditExtrasPlaceholder",
create_edit_menu_injectables());
init_ui_inject_elements("/MediaMenuBar/PhotosMenu/PhotosExtrasExternalsPlaceholder",
create_videos_menu_injectables());
Gtk.Toolbar toolbar = get_toolbar(); Gtk.Toolbar toolbar = get_toolbar();
...@@ -52,76 +61,60 @@ public class VideosPage : CheckerboardPage { ...@@ -52,76 +61,60 @@ public class VideosPage : CheckerboardPage {
separator.set_draw(false); separator.set_draw(false);
toolbar.insert(separator, -1); toolbar.insert(separator, -1);
// thumbnail size slider
slider = new Gtk.HScale(CollectionPage.get_global_slider_adjustment());
slider.value_changed.connect(on_slider_changed);
slider.set_draw_value(false);