1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /*
4 * GThumb
5 *
6 * Copyright (C) 2019 Free Software Foundation, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include <config.h>
23 #include <gtk/gtk.h>
24 #include "glib-utils.h"
25 #include "gth-property-view.h"
26 #include "gth-sidebar-section.h"
27 #include "gtk-utils.h"
28
29
30 struct _GthSidebarSectionPrivate {
31 GtkWidget *void_view;
32 GtkWidget *expander;
33 GthPropertyView *view;
34 GthFileData *file_data;
35 gboolean dirty;
36 };
37
38
G_DEFINE_TYPE_WITH_CODE(GthSidebarSection,gth_sidebar_section,GTK_TYPE_BOX,G_ADD_PRIVATE (GthSidebarSection))39 G_DEFINE_TYPE_WITH_CODE (GthSidebarSection,
40 gth_sidebar_section,
41 GTK_TYPE_BOX,
42 G_ADD_PRIVATE (GthSidebarSection))
43
44
45 static void
46 gth_sidebar_section_finalize (GObject *object)
47 {
48 GthSidebarSection *self = GTH_SIDEBAR_SECTION (object);
49
50 _g_object_unref (self->priv->file_data);
51 G_OBJECT_CLASS (gth_sidebar_section_parent_class)->finalize (object);
52 }
53
54
55 static void
gth_sidebar_section_class_init(GthSidebarSectionClass * klass)56 gth_sidebar_section_class_init (GthSidebarSectionClass *klass)
57 {
58 GObjectClass *object_class;
59
60 object_class = (GObjectClass *) klass;
61 object_class->finalize = gth_sidebar_section_finalize;
62 }
63
64
65 static void
gth_sidebar_section_init(GthSidebarSection * self)66 gth_sidebar_section_init (GthSidebarSection *self)
67 {
68 self->priv = gth_sidebar_section_get_instance_private (self);
69 self->priv->void_view = NULL;
70 self->priv->expander = NULL;
71 self->priv->view = NULL;
72 self->priv->dirty = FALSE;
73 }
74
75
76 static void
_gth_sidebar_section_update_view(GthSidebarSection * self)77 _gth_sidebar_section_update_view (GthSidebarSection *self)
78 {
79 gth_property_view_set_file (self->priv->view, self->priv->file_data);
80 self->priv->dirty = FALSE;
81 }
82
83
84 static void
expander_expanded_cb(GObject * object,GParamSpec * param_spec,gpointer user_data)85 expander_expanded_cb (GObject *object,
86 GParamSpec *param_spec,
87 gpointer user_data)
88 {
89 GthSidebarSection *self = user_data;
90
91 if (gtk_expander_get_expanded (GTK_EXPANDER (self->priv->expander))) {
92 if (self->priv->dirty)
93 _gth_sidebar_section_update_view (self);
94 }
95 }
96
97
98 static void
_gth_sidebar_section_add_view(GthSidebarSection * self,GthPropertyView * view)99 _gth_sidebar_section_add_view (GthSidebarSection *self,
100 GthPropertyView *view)
101 {
102 GtkWidget *exp;
103 GtkWidget *exp_label;
104 GtkWidget *exp_content;
105 GtkWidget *icon;
106 GtkWidget *label;
107
108 self->priv->view = view;
109 _gtk_widget_set_margin (GTK_WIDGET (view), 1, 2, 1, 2);
110 gtk_widget_show (GTK_WIDGET (view));
111
112 self->priv->expander = exp = gtk_expander_new (NULL);
113 exp_label = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
114 _gtk_widget_set_margin (GTK_WIDGET (exp_label), 3, 2, 3, 2);
115 icon = gtk_image_new_from_icon_name (gth_property_view_get_icon (view), GTK_ICON_SIZE_MENU);
116 label = gtk_label_new (gth_property_view_get_name (view));
117 gtk_box_pack_start (GTK_BOX (exp_label), icon, FALSE, FALSE, 0);
118 gtk_box_pack_start (GTK_BOX (exp_label), label, FALSE, FALSE, 0);
119
120 gtk_widget_show_all (exp_label);
121 gtk_expander_set_label_widget (GTK_EXPANDER (exp), exp_label);
122
123 self->priv->void_view = gtk_frame_new (NULL);
124 gtk_frame_set_shadow_type (GTK_FRAME (self->priv->void_view), GTK_SHADOW_IN);
125 gtk_style_context_add_class (gtk_widget_get_style_context (self->priv->void_view), GTK_STYLE_CLASS_VIEW);
126 _gtk_widget_set_margin (self->priv->void_view, 0, 2, 0, 2);
127 gtk_widget_hide (self->priv->void_view);
128
129 icon = gtk_image_new_from_icon_name ("action-unavailable-symbolic", GTK_ICON_SIZE_LARGE_TOOLBAR);
130 gtk_widget_set_sensitive (icon, FALSE);
131 _gtk_widget_set_margin (icon, 10, 0, 10, 0);
132 gtk_style_context_add_class (gtk_widget_get_style_context (icon), "void-view");
133 gtk_widget_show (icon);
134 gtk_container_add (GTK_CONTAINER (self->priv->void_view), icon);
135
136 exp_content = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
137 gtk_box_pack_start (GTK_BOX (exp_content), GTK_WIDGET (view), FALSE, FALSE, 0);
138 gtk_box_pack_start (GTK_BOX (exp_content), self->priv->void_view, FALSE, FALSE, 0);
139 gtk_widget_show (exp_content);
140
141 gtk_expander_set_expanded (GTK_EXPANDER (exp), TRUE);
142 gtk_container_add (GTK_CONTAINER (exp), exp_content);
143 gtk_widget_show (exp);
144 gtk_box_pack_start (GTK_BOX (self), exp, FALSE, FALSE, 0);
145
146 g_signal_connect (exp,
147 "notify::expanded",
148 G_CALLBACK (expander_expanded_cb),
149 self);
150 }
151
152
153 GtkWidget *
gth_sidebar_section_new(GthPropertyView * view)154 gth_sidebar_section_new (GthPropertyView *view)
155 {
156 GthSidebarSection *sidebar;
157
158 sidebar = g_object_new (GTH_TYPE_SIDEBAR_SECTION,
159 "orientation", GTK_ORIENTATION_VERTICAL,
160 "vexpand", FALSE,
161 NULL);
162 _gth_sidebar_section_add_view (sidebar, view);
163
164 return (GtkWidget *) sidebar;
165 }
166
167
168 static gboolean
_gth_sidebar_section_visible(GthSidebarSection * self)169 _gth_sidebar_section_visible (GthSidebarSection *self)
170 {
171 return gtk_expander_get_expanded (GTK_EXPANDER (self->priv->expander));
172 }
173
174
175 gboolean
gth_sidebar_section_set_file(GthSidebarSection * self,GthFileData * file_data)176 gth_sidebar_section_set_file (GthSidebarSection *self,
177 GthFileData *file_data)
178 {
179 gboolean can_view;
180
181 _g_object_unref (self->priv->file_data);
182 self->priv->file_data = NULL;
183 if (file_data != NULL)
184 self->priv->file_data = _g_object_ref (file_data);
185
186 can_view = (self->priv->file_data != NULL) && gth_property_view_can_view (self->priv->view, self->priv->file_data);
187 gtk_widget_set_visible (GTK_WIDGET (self), can_view);
188
189 if (! can_view)
190 self->priv->dirty = FALSE;
191 else if (! _gth_sidebar_section_visible (self))
192 self->priv->dirty = TRUE;
193 else
194 _gth_sidebar_section_update_view (self);
195
196 return can_view;
197 }
198
199
200 void
gth_sidebar_section_set_expanded(GthSidebarSection * self,gboolean expanded)201 gth_sidebar_section_set_expanded (GthSidebarSection *self,
202 gboolean expanded)
203 {
204 gtk_expander_set_expanded (GTK_EXPANDER (self->priv->expander), expanded);
205 }
206
207
208 gboolean
gth_sidebar_section_get_expanded(GthSidebarSection * self)209 gth_sidebar_section_get_expanded (GthSidebarSection *self)
210 {
211 return gtk_expander_get_expanded (GTK_EXPANDER (self->priv->expander));
212 }
213
214
215 const char *
gth_sidebar_section_get_id(GthSidebarSection * self)216 gth_sidebar_section_get_id (GthSidebarSection *self)
217 {
218 return G_OBJECT_CLASS_NAME (G_OBJECT_GET_CLASS (self->priv->view));
219 }
220