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