1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * gimpbrushfactoryview.c
5 * Copyright (C) 2001 Michael Natterer <mitch@gimp.org>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #include <gegl.h>
24 #include <gtk/gtk.h>
25
26 #include "libgimpwidgets/gimpwidgets.h"
27
28 #include "widgets-types.h"
29
30 #include "core/gimpcontainer.h"
31 #include "core/gimpcontext.h"
32 #include "core/gimpbrush.h"
33 #include "core/gimpbrushgenerated.h"
34 #include "core/gimpdatafactory.h"
35
36 #include "gimpbrushfactoryview.h"
37 #include "gimpcontainerview.h"
38 #include "gimpeditor.h"
39 #include "gimpmenufactory.h"
40 #include "gimpspinscale.h"
41 #include "gimpviewrenderer.h"
42
43 #include "gimp-intl.h"
44
45
46 static void gimp_brush_factory_view_dispose (GObject *object);
47
48 static void gimp_brush_factory_view_select_item (GimpContainerEditor *editor,
49 GimpViewable *viewable);
50
51 static void gimp_brush_factory_view_spacing_changed (GimpBrush *brush,
52 GimpBrushFactoryView *view);
53 static void gimp_brush_factory_view_spacing_update (GtkAdjustment *adjustment,
54 GimpBrushFactoryView *view);
55
56
G_DEFINE_TYPE(GimpBrushFactoryView,gimp_brush_factory_view,GIMP_TYPE_DATA_FACTORY_VIEW)57 G_DEFINE_TYPE (GimpBrushFactoryView, gimp_brush_factory_view,
58 GIMP_TYPE_DATA_FACTORY_VIEW)
59
60 #define parent_class gimp_brush_factory_view_parent_class
61
62
63 static void
64 gimp_brush_factory_view_class_init (GimpBrushFactoryViewClass *klass)
65 {
66 GObjectClass *object_class = G_OBJECT_CLASS (klass);
67 GimpContainerEditorClass *editor_class = GIMP_CONTAINER_EDITOR_CLASS (klass);
68
69 object_class->dispose = gimp_brush_factory_view_dispose;
70
71 editor_class->select_item = gimp_brush_factory_view_select_item;
72 }
73
74 static void
gimp_brush_factory_view_init(GimpBrushFactoryView * view)75 gimp_brush_factory_view_init (GimpBrushFactoryView *view)
76 {
77 view->spacing_adjustment =
78 GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 1.0, 5000.0,
79 1.0, 10.0, 0.0));
80
81 view->spacing_scale = gimp_spin_scale_new (view->spacing_adjustment,
82 _("Spacing"), 1);
83 gimp_spin_scale_set_scale_limits (GIMP_SPIN_SCALE (view->spacing_scale),
84 1.0, 200.0);
85 gimp_help_set_help_data (view->spacing_scale,
86 _("Percentage of width of brush"),
87 NULL);
88
89 g_signal_connect (view->spacing_adjustment, "value-changed",
90 G_CALLBACK (gimp_brush_factory_view_spacing_update),
91 view);
92 }
93
94 static void
gimp_brush_factory_view_dispose(GObject * object)95 gimp_brush_factory_view_dispose (GObject *object)
96 {
97 GimpBrushFactoryView *view = GIMP_BRUSH_FACTORY_VIEW (object);
98 GimpContainerEditor *editor = GIMP_CONTAINER_EDITOR (object);
99
100 if (view->spacing_changed_handler_id)
101 {
102 GimpDataFactory *factory;
103 GimpContainer *container;
104
105 factory = gimp_data_factory_view_get_data_factory (GIMP_DATA_FACTORY_VIEW (editor));
106 container = gimp_data_factory_get_container (factory);
107
108 gimp_container_remove_handler (container,
109 view->spacing_changed_handler_id);
110
111 view->spacing_changed_handler_id = 0;
112 }
113
114 G_OBJECT_CLASS (parent_class)->dispose (object);
115 }
116
117 GtkWidget *
gimp_brush_factory_view_new(GimpViewType view_type,GimpDataFactory * factory,GimpContext * context,gboolean change_brush_spacing,gint view_size,gint view_border_width,GimpMenuFactory * menu_factory)118 gimp_brush_factory_view_new (GimpViewType view_type,
119 GimpDataFactory *factory,
120 GimpContext *context,
121 gboolean change_brush_spacing,
122 gint view_size,
123 gint view_border_width,
124 GimpMenuFactory *menu_factory)
125 {
126 GimpBrushFactoryView *factory_view;
127 GimpContainerEditor *editor;
128
129 g_return_val_if_fail (GIMP_IS_DATA_FACTORY (factory), NULL);
130 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
131 g_return_val_if_fail (view_size > 0 &&
132 view_size <= GIMP_VIEWABLE_MAX_PREVIEW_SIZE, NULL);
133 g_return_val_if_fail (view_border_width >= 0 &&
134 view_border_width <= GIMP_VIEW_MAX_BORDER_WIDTH,
135 NULL);
136 g_return_val_if_fail (menu_factory == NULL ||
137 GIMP_IS_MENU_FACTORY (menu_factory), NULL);
138
139 factory_view = g_object_new (GIMP_TYPE_BRUSH_FACTORY_VIEW,
140 "view-type", view_type,
141 "data-factory", factory,
142 "context", context,
143 "view-size", view_size,
144 "view-border-width", view_border_width,
145 "menu-factory", menu_factory,
146 "menu-identifier", "<Brushes>",
147 "ui-path", "/brushes-popup",
148 "action-group", "brushes",
149 NULL);
150
151 factory_view->change_brush_spacing = change_brush_spacing;
152
153 editor = GIMP_CONTAINER_EDITOR (factory_view);
154
155 gimp_editor_add_action_button (GIMP_EDITOR (editor->view),
156 "brushes", "brushes-open-as-image",
157 NULL);
158
159 gtk_box_pack_end (GTK_BOX (editor->view), factory_view->spacing_scale,
160 FALSE, FALSE, 0);
161 gtk_widget_show (factory_view->spacing_scale);
162
163 factory_view->spacing_changed_handler_id =
164 gimp_container_add_handler (gimp_data_factory_get_container (factory), "spacing-changed",
165 G_CALLBACK (gimp_brush_factory_view_spacing_changed),
166 factory_view);
167
168 return GTK_WIDGET (factory_view);
169 }
170
171 static void
gimp_brush_factory_view_select_item(GimpContainerEditor * editor,GimpViewable * viewable)172 gimp_brush_factory_view_select_item (GimpContainerEditor *editor,
173 GimpViewable *viewable)
174 {
175 GimpBrushFactoryView *view = GIMP_BRUSH_FACTORY_VIEW (editor);
176 GimpContainer *container;
177 gboolean spacing_sensitive = FALSE;
178
179 if (GIMP_CONTAINER_EDITOR_CLASS (parent_class)->select_item)
180 GIMP_CONTAINER_EDITOR_CLASS (parent_class)->select_item (editor, viewable);
181
182 container = gimp_container_view_get_container (editor->view);
183
184 if (viewable && gimp_container_have (container, GIMP_OBJECT (viewable)))
185 {
186 GimpBrush *brush = GIMP_BRUSH (viewable);
187
188 spacing_sensitive = TRUE;
189
190 g_signal_handlers_block_by_func (view->spacing_adjustment,
191 gimp_brush_factory_view_spacing_update,
192 view);
193
194 gtk_adjustment_set_value (view->spacing_adjustment,
195 gimp_brush_get_spacing (brush));
196
197 g_signal_handlers_unblock_by_func (view->spacing_adjustment,
198 gimp_brush_factory_view_spacing_update,
199 view);
200 }
201
202 gtk_widget_set_sensitive (view->spacing_scale, spacing_sensitive);
203 }
204
205 static void
gimp_brush_factory_view_spacing_changed(GimpBrush * brush,GimpBrushFactoryView * view)206 gimp_brush_factory_view_spacing_changed (GimpBrush *brush,
207 GimpBrushFactoryView *view)
208 {
209 GimpContainerEditor *editor = GIMP_CONTAINER_EDITOR (view);
210 GimpContext *context;
211
212 context = gimp_container_view_get_context (editor->view);
213
214 if (brush == gimp_context_get_brush (context))
215 {
216 g_signal_handlers_block_by_func (view->spacing_adjustment,
217 gimp_brush_factory_view_spacing_update,
218 view);
219
220 gtk_adjustment_set_value (view->spacing_adjustment,
221 gimp_brush_get_spacing (brush));
222
223 g_signal_handlers_unblock_by_func (view->spacing_adjustment,
224 gimp_brush_factory_view_spacing_update,
225 view);
226 }
227 }
228
229 static void
gimp_brush_factory_view_spacing_update(GtkAdjustment * adjustment,GimpBrushFactoryView * view)230 gimp_brush_factory_view_spacing_update (GtkAdjustment *adjustment,
231 GimpBrushFactoryView *view)
232 {
233 GimpContainerEditor *editor = GIMP_CONTAINER_EDITOR (view);
234 GimpContext *context;
235 GimpBrush *brush;
236
237 context = gimp_container_view_get_context (editor->view);
238
239 brush = gimp_context_get_brush (context);
240
241 if (brush && view->change_brush_spacing)
242 {
243 g_signal_handlers_block_by_func (brush,
244 gimp_brush_factory_view_spacing_changed,
245 view);
246
247 gimp_brush_set_spacing (brush, gtk_adjustment_get_value (adjustment));
248
249 g_signal_handlers_unblock_by_func (brush,
250 gimp_brush_factory_view_spacing_changed,
251 view);
252 }
253 }
254