1 /*
2  * Photos - access, organize and share your photos on GNOME
3  * Copyright © 2015 – 2019 Red Hat, Inc.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 
20 #include "config.h"
21 
22 #include <gio/gio.h>
23 
24 #include "photos-edit-palette.h"
25 #include "photos-edit-palette-row.h"
26 #include "photos-tool.h"
27 #include "photos-utils.h"
28 
29 
30 struct _PhotosEditPalette
31 {
32   GtkListBox parent_instance;
33   GIOExtensionPoint *extension_point;
34   GList *tools;
35 };
36 
37 enum
38 {
39   TOOL_CHANGED,
40   LAST_SIGNAL
41 };
42 
43 static guint signals[LAST_SIGNAL] = { 0 };
44 
45 
46 G_DEFINE_TYPE (PhotosEditPalette, photos_edit_palette, GTK_TYPE_LIST_BOX);
47 
48 
49 static gint
photos_edit_palette_extensions_sort_func(gconstpointer a,gconstpointer b)50 photos_edit_palette_extensions_sort_func (gconstpointer a, gconstpointer b)
51 {
52   GIOExtension *extension_a = (GIOExtension *) a;
53   GIOExtension *extension_b = (GIOExtension *) b;
54   gint priority_a;
55   gint priority_b;
56 
57   priority_a = g_io_extension_get_priority (extension_a);
58   priority_b = g_io_extension_get_priority (extension_b);
59   return priority_a - priority_b;
60 }
61 
62 
63 static void
photos_edit_palette_hide_requested(PhotosEditPalette * self)64 photos_edit_palette_hide_requested (PhotosEditPalette *self)
65 {
66   g_signal_emit (self, signals[TOOL_CHANGED], 0, NULL);
67 }
68 
69 
70 static void
photos_edit_palette_row_activated(GtkListBox * box,GtkListBoxRow * row)71 photos_edit_palette_row_activated (GtkListBox *box, GtkListBoxRow *row)
72 {
73   PhotosEditPalette *self = PHOTOS_EDIT_PALETTE (box);
74   GtkListBoxRow *other_row;
75   PhotosTool *tool;
76   gint i;
77 
78   photos_edit_palette_row_show_details (PHOTOS_EDIT_PALETTE_ROW (row));
79 
80   for (i = 0; (other_row = gtk_list_box_get_row_at_index (box, i)) != NULL; i++)
81     {
82       if (other_row == row)
83         continue;
84 
85       photos_edit_palette_row_hide_details (PHOTOS_EDIT_PALETTE_ROW (other_row));
86     }
87 
88   tool = photos_edit_palette_row_get_tool (PHOTOS_EDIT_PALETTE_ROW (row));
89   g_signal_emit (self, signals[TOOL_CHANGED], 0, tool);
90 }
91 
92 
93 static void
photos_edit_palette_dispose(GObject * object)94 photos_edit_palette_dispose (GObject *object)
95 {
96   PhotosEditPalette *self = PHOTOS_EDIT_PALETTE (object);
97 
98   g_list_free_full (self->tools, g_object_unref);
99   self->tools = NULL;
100 
101   G_OBJECT_CLASS (photos_edit_palette_parent_class)->dispose (object);
102 }
103 
104 
105 static void
photos_edit_palette_init(PhotosEditPalette * self)106 photos_edit_palette_init (PhotosEditPalette *self)
107 {
108   gtk_list_box_set_selection_mode (GTK_LIST_BOX (self), GTK_SELECTION_NONE);
109   gtk_list_box_set_header_func (GTK_LIST_BOX (self), photos_utils_list_box_header_func, NULL, NULL);
110 
111   self->extension_point = g_io_extension_point_lookup (PHOTOS_TOOL_EXTENSION_POINT_NAME);
112 
113   gtk_widget_show_all (GTK_WIDGET (self));
114 }
115 
116 
117 static void
photos_edit_palette_class_init(PhotosEditPaletteClass * class)118 photos_edit_palette_class_init (PhotosEditPaletteClass *class)
119 {
120   GObjectClass *object_class = G_OBJECT_CLASS (class);
121   GtkListBoxClass *list_box_class = GTK_LIST_BOX_CLASS (class);
122 
123   object_class->dispose = photos_edit_palette_dispose;
124   list_box_class->row_activated = photos_edit_palette_row_activated;
125 
126   signals[TOOL_CHANGED] = g_signal_new ("tool-changed",
127                                         G_TYPE_FROM_CLASS (class),
128                                         G_SIGNAL_RUN_LAST,
129                                         0,
130                                         NULL, /* accumulator */
131                                         NULL, /* accu_data */
132                                         g_cclosure_marshal_VOID__OBJECT,
133                                         G_TYPE_NONE,
134                                         1,
135                                         PHOTOS_TYPE_TOOL);
136 }
137 
138 
139 GtkWidget *
photos_edit_palette_new(void)140 photos_edit_palette_new (void)
141 {
142   return g_object_new (PHOTOS_TYPE_EDIT_PALETTE, NULL);
143 }
144 
145 
146 void
photos_edit_palette_hide_details(PhotosEditPalette * self)147 photos_edit_palette_hide_details (PhotosEditPalette *self)
148 {
149   GtkListBoxRow *row;
150   gint i;
151 
152   for (i = 0; (row = gtk_list_box_get_row_at_index (GTK_LIST_BOX (self), i)) != NULL; i++)
153     photos_edit_palette_row_hide_details (PHOTOS_EDIT_PALETTE_ROW (row));
154 
155   g_signal_emit (self, signals[TOOL_CHANGED], 0, NULL);
156 }
157 
158 
159 void
photos_edit_palette_show(PhotosEditPalette * self)160 photos_edit_palette_show (PhotosEditPalette *self)
161 {
162   g_autoptr (GList) extensions = NULL;
163   GList *l;
164   g_autoptr (GtkSizeGroup) size_group = NULL;
165 
166   gtk_container_foreach (GTK_CONTAINER (self), (GtkCallback) gtk_widget_destroy, NULL);
167   g_list_free_full (self->tools, g_object_unref);
168   self->tools = NULL;
169 
170   extensions = g_io_extension_point_get_extensions (self->extension_point);
171   extensions = g_list_copy (extensions);
172   extensions = g_list_sort (extensions, photos_edit_palette_extensions_sort_func);
173 
174   size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
175 
176   for (l = extensions; l != NULL; l = l->next)
177     {
178       GIOExtension *extension = (GIOExtension *) l->data;
179       GType type;
180       GtkWidget *row;
181       g_autoptr (PhotosTool) tool = NULL;
182 
183       type = g_io_extension_get_type (extension);
184       tool = PHOTOS_TOOL (g_object_new (type, NULL));
185       self->tools = g_list_prepend (self->tools, g_object_ref (tool));
186 
187       row = photos_edit_palette_row_new (tool, size_group);
188       gtk_container_add (GTK_CONTAINER (self), row);
189       photos_edit_palette_row_show (PHOTOS_EDIT_PALETTE_ROW (row));
190 
191       g_signal_connect_swapped (tool, "hide-requested", G_CALLBACK (photos_edit_palette_hide_requested), self);
192     }
193 
194   gtk_widget_show_all (GTK_WIDGET (self));
195 }
196