[gnome-control-center/gbsneto/background: 19/20] background: Manage recent backgrounds
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/gbsneto/background: 19/20] background: Manage recent backgrounds
- Date: Sun, 26 May 2019 02:09:33 +0000 (UTC)
commit fd4dc524f1a6f79e47a913a2515ee12a35bbd767
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Fri May 24 14:02:10 2019 -0300
background: Manage recent backgrounds
This is the last missing bit from the new Background panel, and
puts the source added in the previous commit (BgRecentSource)
in use.
Nothing gloriously difficult is done here:
* Add a headerbar button to open the file selector.
* Hook it up in CcBackgroundChooser
* Add a "Delete Background" button to the popover.
panels/background/cc-background-chooser.c | 199 +++++++++++++++++++++++++++--
panels/background/cc-background-chooser.h | 2 +
panels/background/cc-background-chooser.ui | 64 ++++++++++
panels/background/cc-background-panel.c | 27 ++++
panels/background/cc-background-panel.ui | 48 +------
5 files changed, 289 insertions(+), 51 deletions(-)
---
diff --git a/panels/background/cc-background-chooser.c b/panels/background/cc-background-chooser.c
index 070164ce1..ccf57964c 100644
--- a/panels/background/cc-background-chooser.c
+++ b/panels/background/cc-background-chooser.c
@@ -20,8 +20,11 @@
#define G_LOG_DOMAIN "cc-background-chooser"
+#include <glib/gi18n.h>
+
#include "bg-colors-source.h"
#include "bg-pictures-source.h"
+#include "bg-recent-source.h"
#include "bg-wallpapers-source.h"
#include "cc-background-chooser.h"
@@ -30,9 +33,15 @@ struct _CcBackgroundChooser
GtkBox parent;
GtkFlowBox *flowbox;
+ GtkWidget *popover_recent_box;
+ GtkWidget *recent_box;
+ GtkFlowBox *recent_flowbox;
GtkPopover *selection_popover;
+ gboolean recent_selected;
+
BgWallpapersSource *wallpapers_source;
+ BgRecentSource *recent_source;
};
G_DEFINE_TYPE (CcBackgroundChooser, cc_background_chooser, GTK_TYPE_BOX)
@@ -51,13 +60,17 @@ emit_background_chosen (CcBackgroundChooser *self,
{
g_autoptr(GList) list = NULL;
CcBackgroundItem *item;
+ GtkFlowBox *flowbox;
- list = gtk_flow_box_get_selected_children (self->flowbox);
+ flowbox = self->recent_selected ? self->recent_flowbox : self->flowbox;
+ list = gtk_flow_box_get_selected_children (flowbox);
g_assert (g_list_length (list) == 1);
item = g_object_get_data (list->data, "item");
g_signal_emit (self, signals[BACKGROUND_CHOSEN], 0, item, flags);
+
+ gtk_flow_box_unselect_all (flowbox);
}
static GtkWidget*
@@ -65,20 +78,20 @@ create_widget_func (gpointer model_item,
gpointer user_data)
{
g_autoptr(GdkPixbuf) pixbuf = NULL;
- CcBackgroundChooser *self;
CcBackgroundItem *item;
GtkWidget *overlay;
GtkWidget *child;
GtkWidget *image;
GtkWidget *icon;
+ BgSource *source;
- self = CC_BACKGROUND_CHOOSER (user_data);
+ source = BG_SOURCE (user_data);
item = CC_BACKGROUND_ITEM (model_item);
pixbuf = cc_background_item_get_thumbnail (item,
- bg_source_get_thumbnail_factory (BG_SOURCE
(self->wallpapers_source)),
- bg_source_get_thumbnail_width (BG_SOURCE
(self->wallpapers_source)),
- bg_source_get_thumbnail_height (BG_SOURCE
(self->wallpapers_source)),
- bg_source_get_scale_factor (BG_SOURCE
(self->wallpapers_source)));
+ bg_source_get_thumbnail_factory (source),
+ bg_source_get_thumbnail_width (source),
+ bg_source_get_thumbnail_height (source),
+ bg_source_get_scale_factor (source));
image = gtk_image_new_from_pixbuf (pixbuf);
gtk_widget_show (image);
@@ -109,6 +122,18 @@ create_widget_func (gpointer model_item,
return child;
}
+static void
+update_recent_visibility (CcBackgroundChooser *self)
+{
+ GListStore *store;
+ gboolean has_items;
+
+ store = bg_source_get_liststore (BG_SOURCE (self->recent_source));
+ has_items = g_list_model_get_n_items (G_LIST_MODEL (store)) != 0;
+
+ gtk_widget_set_visible (self->recent_box, has_items);
+}
+
static void
setup_flowbox (CcBackgroundChooser *self)
{
@@ -119,8 +144,38 @@ setup_flowbox (CcBackgroundChooser *self)
gtk_flow_box_bind_model (self->flowbox,
G_LIST_MODEL (store),
create_widget_func,
- self,
+ self->wallpapers_source,
+ NULL);
+
+ store = bg_source_get_liststore (BG_SOURCE (self->recent_source));
+
+ gtk_flow_box_bind_model (self->recent_flowbox,
+ G_LIST_MODEL (store),
+ create_widget_func,
+ self->recent_source,
NULL);
+
+ update_recent_visibility (self);
+ g_signal_connect_object (store,
+ "items-changed",
+ G_CALLBACK (update_recent_visibility),
+ self,
+ G_CONNECT_SWAPPED);
+}
+
+static void
+on_delete_background_clicked_cb (GtkButton *button,
+ CcBackgroundChooser *self)
+{
+ g_autoptr(GList) list = NULL;
+ CcBackgroundItem *item;
+
+ list = gtk_flow_box_get_selected_children (self->recent_flowbox);
+ g_assert (g_list_length (list) == 1);
+
+ item = g_object_get_data (list->data, "item");
+
+ bg_recent_source_remove_item (self->recent_source, item);
}
static void
@@ -152,10 +207,79 @@ on_item_activated_cb (GtkFlowBox *flowbox,
GtkFlowBoxChild *child,
CcBackgroundChooser *self)
{
+ self->recent_selected = flowbox == self->recent_flowbox;
+ gtk_widget_set_visible (self->popover_recent_box, self->recent_selected);
+
gtk_popover_set_relative_to (self->selection_popover, GTK_WIDGET (child));
gtk_popover_popup (self->selection_popover);
}
+static void
+on_file_chooser_response_cb (GtkDialog *filechooser,
+ gint response,
+ CcBackgroundChooser *self)
+{
+ g_autofree gchar *filename = NULL;
+
+ if (response != GTK_RESPONSE_ACCEPT)
+ goto out;
+
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser));
+
+ bg_recent_source_add_file (self->recent_source, filename);
+
+out:
+ gtk_widget_destroy (GTK_WIDGET (filechooser));
+}
+
+static void
+on_file_chooser_selection_changed_cb (GtkFileChooser *chooser,
+ GnomeDesktopThumbnailFactory *thumbnail_factory)
+{
+ g_autofree gchar *uri = NULL;
+
+ uri = gtk_file_chooser_get_uri (chooser);
+
+ if (uri)
+ {
+ g_autoptr(GFileInfo) file_info = NULL;
+ g_autoptr(GdkPixbuf) pixbuf = NULL;
+ g_autofree gchar *mime_type = NULL;
+ g_autoptr(GFile) file = NULL;
+ GtkWidget *preview;
+
+ preview = gtk_file_chooser_get_preview_widget (chooser);
+
+ file = g_file_new_for_uri (uri);
+ file_info = g_file_query_info (file,
+ "standard::*",
+ G_FILE_QUERY_INFO_NONE,
+ NULL,
+ NULL);
+
+ if (file_info && g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY)
+ mime_type = g_strdup (g_file_info_get_content_type (file_info));
+
+ if (mime_type)
+ {
+ pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (thumbnail_factory,
+ uri,
+ mime_type);
+ }
+
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser),
+ GTK_RESPONSE_ACCEPT,
+ pixbuf != NULL);
+
+ if (pixbuf)
+ gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
+ else
+ gtk_image_set_from_icon_name (GTK_IMAGE (preview), "dialog-question", GTK_ICON_SIZE_DIALOG);
+ }
+
+ gtk_file_chooser_set_preview_widget_active (chooser, TRUE);
+}
+
/* GObject overrides */
static void
@@ -163,6 +287,7 @@ cc_background_chooser_finalize (GObject *object)
{
CcBackgroundChooser *self = (CcBackgroundChooser *)object;
+ g_clear_object (&self->recent_source);
g_clear_object (&self->wallpapers_source);
G_OBJECT_CLASS (cc_background_chooser_parent_class)->finalize (object);
@@ -188,8 +313,12 @@ cc_background_chooser_class_init (CcBackgroundChooserClass *klass)
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/control-center/background/cc-background-chooser.ui");
gtk_widget_class_bind_template_child (widget_class, CcBackgroundChooser, flowbox);
+ gtk_widget_class_bind_template_child (widget_class, CcBackgroundChooser, popover_recent_box);
+ gtk_widget_class_bind_template_child (widget_class, CcBackgroundChooser, recent_box);
+ gtk_widget_class_bind_template_child (widget_class, CcBackgroundChooser, recent_flowbox);
gtk_widget_class_bind_template_child (widget_class, CcBackgroundChooser, selection_popover);
+ gtk_widget_class_bind_template_callback (widget_class, on_delete_background_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, on_item_activated_cb);
gtk_widget_class_bind_template_callback (widget_class, on_selection_desktop_lock_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, on_selection_desktop_clicked_cb);
@@ -201,6 +330,60 @@ cc_background_chooser_init (CcBackgroundChooser *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
+ self->recent_source = bg_recent_source_new (GTK_WIDGET (self));
self->wallpapers_source = bg_wallpapers_source_new (GTK_WIDGET (self));
setup_flowbox (self);
}
+
+void
+cc_background_chooser_select_file (CcBackgroundChooser *self)
+{
+ g_autoptr(GnomeDesktopThumbnailFactory) factory = NULL;
+ GtkFileFilter *filter;
+ GtkWidget *filechooser;
+ GtkWindow *toplevel;
+ GtkWidget *preview;
+
+ g_return_if_fail (CC_IS_BACKGROUND_CHOOSER (self));
+
+ toplevel = (GtkWindow*) gtk_widget_get_toplevel (GTK_WIDGET (self));
+ filechooser = gtk_file_chooser_dialog_new (_("Select a picture"),
+ toplevel,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ _("_Cancel"), GTK_RESPONSE_CANCEL,
+ _("_Open"), GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_window_set_modal (GTK_WINDOW (filechooser), TRUE);
+
+ preview = gtk_image_new ();
+ gtk_widget_set_size_request (preview, 256, -1);
+ gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (filechooser), preview);
+ gtk_file_chooser_set_use_preview_label (GTK_FILE_CHOOSER (filechooser), FALSE);
+ gtk_widget_show (preview);
+
+ factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
+ g_signal_connect_after (filechooser,
+ "selection-changed",
+ G_CALLBACK (on_file_chooser_selection_changed_cb),
+ factory);
+
+ g_object_set_data_full (G_OBJECT (filechooser),
+ "factory",
+ g_object_ref (factory),
+ g_object_unref);
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_add_pixbuf_formats (filter);
+ gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (filechooser), filter);
+
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (filechooser),
+ g_get_user_special_dir (G_USER_DIRECTORY_PICTURES));
+
+ g_signal_connect_object (filechooser,
+ "response",
+ G_CALLBACK (on_file_chooser_response_cb),
+ self,
+ 0);
+
+ gtk_window_present (GTK_WINDOW (filechooser));
+}
diff --git a/panels/background/cc-background-chooser.h b/panels/background/cc-background-chooser.h
index 6d88785e7..ced15191b 100644
--- a/panels/background/cc-background-chooser.h
+++ b/panels/background/cc-background-chooser.h
@@ -34,4 +34,6 @@ typedef enum
#define CC_TYPE_BACKGROUND_CHOOSER (cc_background_chooser_get_type())
G_DECLARE_FINAL_TYPE (CcBackgroundChooser, cc_background_chooser, CC, BACKGROUND_CHOOSER, GtkBox)
+void cc_background_chooser_select_file (CcBackgroundChooser *self);
+
G_END_DECLS
diff --git a/panels/background/cc-background-chooser.ui b/panels/background/cc-background-chooser.ui
index 12e111a20..8e96e5691 100644
--- a/panels/background/cc-background-chooser.ui
+++ b/panels/background/cc-background-chooser.ui
@@ -29,6 +29,43 @@
<style>
<class name="view" />
</style>
+
+ <!-- Recent -->
+ <child>
+ <object class="GtkBox" id="recent_box">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="orientation">vertical</property>
+ <property name="halign">center</property>
+
+ <child>
+ <object class="GtkFlowBox" id="recent_flowbox">
+ <property name="visible">True</property>
+ <property name="margin">12</property>
+ <property name="column-spacing">12</property>
+ <property name="row-spacing">12</property>
+ <property name="homogeneous">True</property>
+ <property name="halign">center</property>
+ <property name="min-children-per-line">1</property>
+ <property name="max-children-per-line">8</property>
+ <property name="activate-on-single-click">True</property>
+ <property name="selection-mode">single</property>
+ <signal name="child-activated" handler="on_item_activated_cb"
object="CcBackgroundChooser" swapped="no" />
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkSeparator">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
<child>
<object class="GtkFlowBox" id="flowbox">
<property name="visible">True</property>
@@ -85,6 +122,33 @@
<signal name="clicked" handler="on_selection_lock_clicked_cb" object="CcBackgroundChooser"
swapped="no" />
</object>
</child>
+
+ <!-- Recent items section -->
+ <child>
+ <object class="GtkBox" id="popover_recent_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkSeparator">
+ <property name="visible">True</property>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Delete Background</property>
+ <signal name="clicked" handler="on_delete_background_clicked_cb"
object="CcBackgroundChooser" swapped="no" />
+ <style>
+ <class name="destructive-action" />
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
</object>
</child>
</object>
diff --git a/panels/background/cc-background-panel.c b/panels/background/cc-background-panel.c
index c4d32a1ec..ab62fdcf6 100644
--- a/panels/background/cc-background-panel.c
+++ b/panels/background/cc-background-panel.c
@@ -61,6 +61,8 @@ struct _CcBackgroundPanel
GCancellable *copy_cancellable;
+ CcBackgroundChooser *background_chooser;
+ GtkWidget *add_picture_button;
GtkWidget *bottom_hbox;
CcBackgroundPreview *desktop_preview;
CcBackgroundPreview *lock_screen_preview;
@@ -389,12 +391,33 @@ on_chooser_background_chosen_cb (CcBackgroundChooser *chooser,
set_background (self, self->lock_settings, item);
}
+static void
+on_add_picture_button_clicked_cb (GtkWidget *button,
+ CcBackgroundPanel *self)
+{
+ cc_background_chooser_select_file (self->background_chooser);
+}
+
static const char *
cc_background_panel_get_help_uri (CcPanel *panel)
{
return "help:gnome-help/look-background";
}
+static void
+cc_background_panel_constructed (GObject *object)
+{
+ CcBackgroundPanel *self;
+ CcShell *shell;
+
+ self = CC_BACKGROUND_PANEL (object);
+ shell = cc_panel_get_shell (CC_PANEL (self));
+
+ cc_shell_embed_widget_in_header (shell, self->add_picture_button, GTK_POS_RIGHT);
+
+ G_OBJECT_CLASS (cc_background_panel_parent_class)->constructed (object);
+}
+
static void
cc_background_panel_dispose (GObject *object)
{
@@ -436,16 +459,20 @@ cc_background_panel_class_init (CcBackgroundPanelClass *klass)
panel_class->get_help_uri = cc_background_panel_get_help_uri;
+ object_class->constructed = cc_background_panel_constructed;
object_class->dispose = cc_background_panel_dispose;
object_class->finalize = cc_background_panel_finalize;
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/control-center/background/cc-background-panel.ui");
+ gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, add_picture_button);
+ gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, background_chooser);
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, bottom_hbox);
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, desktop_preview);
gtk_widget_class_bind_template_child (widget_class, CcBackgroundPanel, lock_screen_preview);
gtk_widget_class_bind_template_callback (widget_class, on_chooser_background_chosen_cb);
+ gtk_widget_class_bind_template_callback (widget_class, on_add_picture_button_clicked_cb);
}
static void
diff --git a/panels/background/cc-background-panel.ui b/panels/background/cc-background-panel.ui
index e606e01d9..066d3874a 100644
--- a/panels/background/cc-background-panel.ui
+++ b/panels/background/cc-background-panel.ui
@@ -72,48 +72,10 @@
</child>
</template>
- <object class="GtkListStore" id="sources-liststore">
- <columns>
- <!-- column-name source-name -->
- <column type="gchararray"/>
- <!-- column-name source-id -->
- <column type="guint"/>
- <!-- column-name source-pointer -->
- <column type="gpointer"/>
- </columns>
- </object>
- <object class="GtkListStore" id="style-liststore">
- <columns>
- <!-- column-name name -->
- <column type="gchararray"/>
- <!-- column-name value -->
- <column type="gint"/>
- </columns>
- <data>
- <row>
- <col id="0" translatable="yes" context="background, style">Tile</col>
- <col id="1">1</col>
- </row>
- <row>
- <col id="0" translatable="yes" context="background, style">Zoom</col>
- <col id="1">5</col>
- </row>
- <row>
- <col id="0" translatable="yes" context="background, style">Center</col>
- <col id="1">2</col>
- </row>
- <row>
- <col id="0" translatable="yes" context="background, style">Scale</col>
- <col id="1">3</col>
- </row>
- <row>
- <col id="0" translatable="yes" context="background, style">Fill</col>
- <col id="1">4</col>
- </row>
- <row>
- <col id="0" translatable="yes" context="background, style">Span</col>
- <col id="1">6</col>
- </row>
- </data>
+ <!-- Header button -->
+ <object class="GtkButton" id="add_picture_button">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Add Picture…</property>
+ <signal name="clicked" handler="on_add_picture_button_clicked_cb" object="CcBackgroundPanel"
swapped="no" />
</object>
</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]