1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19
20 #include <gegl.h>
21 #include <gtk/gtk.h>
22
23 #include "libgimpwidgets/gimpwidgets.h"
24
25 #include "widgets-types.h"
26
27 #include "config/gimpconfig-utils.h"
28
29 #include "core/gimp.h"
30 #include "core/gimpcontainer.h"
31 #include "core/gimpcontext.h"
32 #include "core/gimpdatafactory.h"
33
34 #include "gimpcontainerentry.h"
35 #include "gimpdialogfactory.h"
36 #include "gimppropwidgets.h"
37 #include "gimpview.h"
38 #include "gimpviewablebutton.h"
39 #include "gimpviewablebox.h"
40 #include "gimpviewrenderergradient.h"
41 #include "gimpwidgets-utils.h"
42 #include "gimpwindowstrategy.h"
43
44 #include "gimp-intl.h"
45
46
47 /* local function prototypes */
48
49 static GtkWidget * gimp_viewable_box_new (GimpContainer *container,
50 GimpContext *context,
51 const gchar *label,
52 gint spacing,
53 GimpViewType view_type,
54 GimpViewSize button_view_size,
55 GimpViewSize view_size,
56 const gchar *dialog_identifier,
57 const gchar *dialog_icon_name,
58 const gchar *dialog_tooltip,
59 const gchar *editor_id,
60 const gchar *editor_tooltip);
61 static GtkWidget * view_props_connect (GtkWidget *box,
62 GimpContext *context,
63 const gchar *view_type_prop,
64 const gchar *view_size_prop);
65 static void gimp_viewable_box_edit_clicked (GtkWidget *widget,
66 GimpViewableButton *button);
67 static void gimp_gradient_box_reverse_notify (GObject *object,
68 GParamSpec *pspec,
69 GimpView *view);
70 static void gimp_gradient_box_blend_notify (GObject *object,
71 GParamSpec *pspec,
72 GimpView *view);
73
74
75 /* brush boxes */
76
77 static GtkWidget *
brush_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,GimpViewType view_type,GimpViewSize view_size,const gchar * editor_id,const gchar * editor_tooltip)78 brush_box_new (GimpContainer *container,
79 GimpContext *context,
80 const gchar *label,
81 gint spacing,
82 GimpViewType view_type,
83 GimpViewSize view_size,
84 const gchar *editor_id,
85 const gchar *editor_tooltip)
86 {
87 if (! container)
88 container = gimp_data_factory_get_container (context->gimp->brush_factory);
89
90 return gimp_viewable_box_new (container, context, label, spacing,
91 view_type, GIMP_VIEW_SIZE_SMALL, view_size,
92 "gimp-brush-grid|gimp-brush-list",
93 GIMP_ICON_BRUSH,
94 _("Open the brush selection dialog"),
95 editor_id, editor_tooltip);
96 }
97
98 GtkWidget *
gimp_brush_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing)99 gimp_brush_box_new (GimpContainer *container,
100 GimpContext *context,
101 const gchar *label,
102 gint spacing)
103 {
104 g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
105 NULL);
106 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
107
108 return brush_box_new (container, context, label, spacing,
109 GIMP_VIEW_TYPE_GRID, GIMP_VIEW_SIZE_SMALL,
110 NULL, NULL);
111 }
112
113 GtkWidget *
gimp_prop_brush_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,const gchar * view_type_prop,const gchar * view_size_prop,const gchar * editor_id,const gchar * editor_tooltip)114 gimp_prop_brush_box_new (GimpContainer *container,
115 GimpContext *context,
116 const gchar *label,
117 gint spacing,
118 const gchar *view_type_prop,
119 const gchar *view_size_prop,
120 const gchar *editor_id,
121 const gchar *editor_tooltip)
122 {
123 GimpViewType view_type;
124 GimpViewSize view_size;
125
126 g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
127 NULL);
128 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
129
130 g_object_get (context,
131 view_type_prop, &view_type,
132 view_size_prop, &view_size,
133 NULL);
134
135 return view_props_connect (brush_box_new (container, context, label, spacing,
136 view_type, view_size,
137 editor_id, editor_tooltip),
138 context,
139 view_type_prop, view_size_prop);
140 }
141
142
143 /* dynamics boxes */
144
145 static GtkWidget *
dynamics_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,GimpViewType view_type,GimpViewSize view_size,const gchar * editor_id,const gchar * editor_tooltip)146 dynamics_box_new (GimpContainer *container,
147 GimpContext *context,
148 const gchar *label,
149 gint spacing,
150 GimpViewType view_type,
151 GimpViewSize view_size,
152 const gchar *editor_id,
153 const gchar *editor_tooltip)
154 {
155 if (! container)
156 container = gimp_data_factory_get_container (context->gimp->dynamics_factory);
157
158 return gimp_viewable_box_new (container, context, label, spacing,
159 view_type, GIMP_VIEW_SIZE_SMALL, view_size,
160 "gimp-dynamics-list|gimp-dynamics-grid",
161 GIMP_ICON_DYNAMICS,
162 _("Open the dynamics selection dialog"),
163 editor_id, editor_tooltip);
164 }
165
166 GtkWidget *
gimp_dynamics_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing)167 gimp_dynamics_box_new (GimpContainer *container,
168 GimpContext *context,
169 const gchar *label,
170 gint spacing)
171 {
172 g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
173 NULL);
174 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
175
176 return dynamics_box_new (container, context, label, spacing,
177 GIMP_VIEW_TYPE_LIST, GIMP_VIEW_SIZE_SMALL,
178 NULL, NULL);
179 }
180
181 GtkWidget *
gimp_prop_dynamics_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,const gchar * view_type_prop,const gchar * view_size_prop,const gchar * editor_id,const gchar * editor_tooltip)182 gimp_prop_dynamics_box_new (GimpContainer *container,
183 GimpContext *context,
184 const gchar *label,
185 gint spacing,
186 const gchar *view_type_prop,
187 const gchar *view_size_prop,
188 const gchar *editor_id,
189 const gchar *editor_tooltip)
190 {
191 GimpViewType view_type;
192 GimpViewSize view_size;
193
194 g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
195 NULL);
196 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
197
198 g_object_get (context,
199 view_type_prop, &view_type,
200 view_size_prop, &view_size,
201 NULL);
202
203 return view_props_connect (dynamics_box_new (container, context, label,
204 spacing,
205 view_type, view_size,
206 editor_id, editor_tooltip),
207 context,
208 view_type_prop, view_size_prop);
209 }
210
211
212 /* brush boxes */
213
214 static GtkWidget *
mybrush_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,GimpViewType view_type,GimpViewSize view_size)215 mybrush_box_new (GimpContainer *container,
216 GimpContext *context,
217 const gchar *label,
218 gint spacing,
219 GimpViewType view_type,
220 GimpViewSize view_size)
221 {
222 if (! container)
223 container = gimp_data_factory_get_container (context->gimp->mybrush_factory);
224
225 return gimp_viewable_box_new (container, context, label, spacing,
226 view_type, GIMP_VIEW_SIZE_LARGE, view_size,
227 "gimp-mypaint-brush-grid|gimp-mypaint-brush-list",
228 GIMP_ICON_BRUSH,
229 _("Open the MyPaint brush selection dialog"),
230 NULL, NULL);
231 }
232
233 GtkWidget *
gimp_mybrush_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing)234 gimp_mybrush_box_new (GimpContainer *container,
235 GimpContext *context,
236 const gchar *label,
237 gint spacing)
238 {
239 g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
240 NULL);
241 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
242
243 return mybrush_box_new (container, context, label, spacing,
244 GIMP_VIEW_TYPE_GRID, GIMP_VIEW_SIZE_LARGE);
245 }
246
247 GtkWidget *
gimp_prop_mybrush_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,const gchar * view_type_prop,const gchar * view_size_prop)248 gimp_prop_mybrush_box_new (GimpContainer *container,
249 GimpContext *context,
250 const gchar *label,
251 gint spacing,
252 const gchar *view_type_prop,
253 const gchar *view_size_prop)
254 {
255 GimpViewType view_type = GIMP_VIEW_TYPE_GRID;
256 GimpViewSize view_size = GIMP_VIEW_SIZE_LARGE;
257
258 g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
259 NULL);
260 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
261
262 if (view_type_prop && view_size_prop)
263 g_object_get (context,
264 view_type_prop, &view_type,
265 view_size_prop, &view_size,
266 NULL);
267
268 return view_props_connect (mybrush_box_new (container, context, label, spacing,
269 view_type, view_size),
270 context,
271 view_type_prop, view_size_prop);
272 }
273
274
275 /* pattern boxes */
276
277 static GtkWidget *
pattern_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,GimpViewType view_type,GimpViewSize view_size)278 pattern_box_new (GimpContainer *container,
279 GimpContext *context,
280 const gchar *label,
281 gint spacing,
282 GimpViewType view_type,
283 GimpViewSize view_size)
284 {
285 if (! container)
286 container = gimp_data_factory_get_container (context->gimp->pattern_factory);
287
288 return gimp_viewable_box_new (container, context, label, spacing,
289 view_type, GIMP_VIEW_SIZE_SMALL, view_size,
290 "gimp-pattern-grid|gimp-pattern-list",
291 GIMP_ICON_PATTERN,
292 _("Open the pattern selection dialog"),
293 NULL, NULL);
294 }
295
296 GtkWidget *
gimp_pattern_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing)297 gimp_pattern_box_new (GimpContainer *container,
298 GimpContext *context,
299 const gchar *label,
300 gint spacing)
301 {
302 g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
303 NULL);
304 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
305
306 return pattern_box_new (container, context, label, spacing,
307 GIMP_VIEW_TYPE_GRID, GIMP_VIEW_SIZE_SMALL);
308 }
309
310 GtkWidget *
gimp_prop_pattern_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,const gchar * view_type_prop,const gchar * view_size_prop)311 gimp_prop_pattern_box_new (GimpContainer *container,
312 GimpContext *context,
313 const gchar *label,
314 gint spacing,
315 const gchar *view_type_prop,
316 const gchar *view_size_prop)
317 {
318 GimpViewType view_type;
319 GimpViewSize view_size;
320
321 g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
322 NULL);
323 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
324
325 g_object_get (context,
326 view_type_prop, &view_type,
327 view_size_prop, &view_size,
328 NULL);
329
330 return view_props_connect (pattern_box_new (container, context, label, spacing,
331 view_type, view_size),
332 context,
333 view_type_prop, view_size_prop);
334 }
335
336
337 /* gradient boxes */
338
339 static GtkWidget *
gradient_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,GimpViewType view_type,GimpViewSize view_size,const gchar * reverse_prop,const gchar * blend_color_space_prop,const gchar * editor_id,const gchar * editor_tooltip)340 gradient_box_new (GimpContainer *container,
341 GimpContext *context,
342 const gchar *label,
343 gint spacing,
344 GimpViewType view_type,
345 GimpViewSize view_size,
346 const gchar *reverse_prop,
347 const gchar *blend_color_space_prop,
348 const gchar *editor_id,
349 const gchar *editor_tooltip)
350 {
351 GtkWidget *hbox;
352 GtkWidget *button;
353 GList *children;
354
355 if (! container)
356 container = gimp_data_factory_get_container (context->gimp->gradient_factory);
357
358 hbox = gimp_viewable_box_new (container, context, label, spacing,
359 view_type, GIMP_VIEW_SIZE_SMALL, view_size,
360 "gimp-gradient-list|gimp-gradient-grid",
361 GIMP_ICON_GRADIENT,
362 _("Open the gradient selection dialog"),
363 editor_id, editor_tooltip);
364
365 children = gtk_container_get_children (GTK_CONTAINER (hbox));
366 button = children->data;
367 g_list_free (children);
368
369 GIMP_VIEWABLE_BUTTON (button)->button_view_size = GIMP_VIEW_SIZE_SMALL;
370
371 if (reverse_prop)
372 {
373 GtkWidget *toggle;
374 GtkWidget *view;
375 GtkWidget *image;
376 gchar *signal_name;
377
378 toggle = gimp_prop_check_button_new (G_OBJECT (context), reverse_prop,
379 NULL);
380 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (toggle), FALSE);
381 gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
382 gtk_box_reorder_child (GTK_BOX (hbox), toggle, 1);
383 gtk_widget_show (toggle);
384
385 gimp_help_set_help_data (toggle, _("Reverse"), NULL);
386
387 image = gtk_image_new_from_icon_name (GIMP_ICON_OBJECT_FLIP_HORIZONTAL,
388 GTK_ICON_SIZE_MENU);
389 /* gimp_prop_check_button_new() adds the property nick as label of
390 * the button by default. */
391 gtk_container_remove (GTK_CONTAINER (toggle),
392 gtk_bin_get_child (GTK_BIN (toggle)));
393 gtk_container_add (GTK_CONTAINER (toggle), image);
394 gtk_widget_show (image);
395
396 view = gtk_bin_get_child (GTK_BIN (button));
397
398 signal_name = g_strconcat ("notify::", reverse_prop, NULL);
399 g_signal_connect_object (context, signal_name,
400 G_CALLBACK (gimp_gradient_box_reverse_notify),
401 G_OBJECT (view), 0);
402 g_free (signal_name);
403
404 gimp_gradient_box_reverse_notify (G_OBJECT (context),
405 NULL,
406 GIMP_VIEW (view));
407 }
408
409 if (blend_color_space_prop)
410 {
411 GtkWidget *view;
412 gchar *signal_name;
413
414 view = gtk_bin_get_child (GTK_BIN (button));
415
416 signal_name = g_strconcat ("notify::", blend_color_space_prop, NULL);
417 g_signal_connect_object (context, signal_name,
418 G_CALLBACK (gimp_gradient_box_blend_notify),
419 G_OBJECT (view), 0);
420 g_free (signal_name);
421
422 gimp_gradient_box_blend_notify (G_OBJECT (context),
423 NULL,
424 GIMP_VIEW (view));
425 }
426
427 return hbox;
428 }
429
430 GtkWidget *
gimp_gradient_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,const gchar * reverse_prop,const gchar * blend_color_space_prop)431 gimp_gradient_box_new (GimpContainer *container,
432 GimpContext *context,
433 const gchar *label,
434 gint spacing,
435 const gchar *reverse_prop,
436 const gchar *blend_color_space_prop)
437 {
438 g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
439 NULL);
440 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
441
442 return gradient_box_new (container, context, label, spacing,
443 GIMP_VIEW_TYPE_LIST, GIMP_VIEW_SIZE_LARGE,
444 reverse_prop, blend_color_space_prop,
445 NULL, NULL);
446 }
447
448 GtkWidget *
gimp_prop_gradient_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,const gchar * view_type_prop,const gchar * view_size_prop,const gchar * reverse_prop,const gchar * blend_color_space_prop,const gchar * editor_id,const gchar * editor_tooltip)449 gimp_prop_gradient_box_new (GimpContainer *container,
450 GimpContext *context,
451 const gchar *label,
452 gint spacing,
453 const gchar *view_type_prop,
454 const gchar *view_size_prop,
455 const gchar *reverse_prop,
456 const gchar *blend_color_space_prop,
457 const gchar *editor_id,
458 const gchar *editor_tooltip)
459 {
460 GimpViewType view_type;
461 GimpViewSize view_size;
462
463 g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
464 NULL);
465 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
466
467 g_object_get (context,
468 view_type_prop, &view_type,
469 view_size_prop, &view_size,
470 NULL);
471
472 return view_props_connect (gradient_box_new (container, context, label, spacing,
473 view_type, view_size,
474 reverse_prop,
475 blend_color_space_prop,
476 editor_id, editor_tooltip),
477 context,
478 view_type_prop, view_size_prop);
479 }
480
481
482 /* palette boxes */
483
484 static GtkWidget *
palette_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,GimpViewType view_type,GimpViewSize view_size,const gchar * editor_id,const gchar * editor_tooltip)485 palette_box_new (GimpContainer *container,
486 GimpContext *context,
487 const gchar *label,
488 gint spacing,
489 GimpViewType view_type,
490 GimpViewSize view_size,
491 const gchar *editor_id,
492 const gchar *editor_tooltip)
493 {
494 if (! container)
495 container = gimp_data_factory_get_container (context->gimp->palette_factory);
496
497 return gimp_viewable_box_new (container, context, label, spacing,
498 view_type, GIMP_VIEW_SIZE_MEDIUM, view_size,
499 "gimp-palette-list|gimp-palette-grid",
500 GIMP_ICON_PALETTE,
501 _("Open the palette selection dialog"),
502 editor_id, editor_tooltip);
503 }
504
505 GtkWidget *
gimp_palette_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing)506 gimp_palette_box_new (GimpContainer *container,
507 GimpContext *context,
508 const gchar *label,
509 gint spacing)
510 {
511 g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
512 NULL);
513 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
514
515 return palette_box_new (container, context, label, spacing,
516 GIMP_VIEW_TYPE_LIST, GIMP_VIEW_SIZE_MEDIUM,
517 NULL, NULL);
518 }
519
520 GtkWidget *
gimp_prop_palette_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,const gchar * view_type_prop,const gchar * view_size_prop,const gchar * editor_id,const gchar * editor_tooltip)521 gimp_prop_palette_box_new (GimpContainer *container,
522 GimpContext *context,
523 const gchar *label,
524 gint spacing,
525 const gchar *view_type_prop,
526 const gchar *view_size_prop,
527 const gchar *editor_id,
528 const gchar *editor_tooltip)
529 {
530 GimpViewType view_type;
531 GimpViewSize view_size;
532
533 g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
534 NULL);
535 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
536
537 g_object_get (context,
538 view_type_prop, &view_type,
539 view_size_prop, &view_size,
540 NULL);
541
542 return view_props_connect (palette_box_new (container, context, label, spacing,
543 view_type, view_size,
544 editor_id, editor_tooltip),
545 context,
546 view_type_prop, view_size_prop);
547 }
548
549
550 /* font boxes */
551
552 static GtkWidget *
font_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,GimpViewType view_type,GimpViewSize view_size)553 font_box_new (GimpContainer *container,
554 GimpContext *context,
555 const gchar *label,
556 gint spacing,
557 GimpViewType view_type,
558 GimpViewSize view_size)
559 {
560 if (! container)
561 container = gimp_data_factory_get_container (context->gimp->font_factory);
562
563 return gimp_viewable_box_new (container, context, label, spacing,
564 view_type, GIMP_VIEW_SIZE_SMALL, view_size,
565 "gimp-font-list|gimp-font-grid",
566 GIMP_ICON_FONT,
567 _("Open the font selection dialog"),
568 NULL, NULL);
569 }
570
571 GtkWidget *
gimp_font_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing)572 gimp_font_box_new (GimpContainer *container,
573 GimpContext *context,
574 const gchar *label,
575 gint spacing)
576 {
577 g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
578 NULL);
579 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
580
581 return font_box_new (container, context, label, spacing,
582 GIMP_VIEW_TYPE_LIST, GIMP_VIEW_SIZE_SMALL);
583 }
584
585 GtkWidget *
gimp_prop_font_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,const gchar * view_type_prop,const gchar * view_size_prop)586 gimp_prop_font_box_new (GimpContainer *container,
587 GimpContext *context,
588 const gchar *label,
589 gint spacing,
590 const gchar *view_type_prop,
591 const gchar *view_size_prop)
592 {
593 GimpViewType view_type;
594 GimpViewSize view_size;
595
596 g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container),
597 NULL);
598 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
599
600 g_object_get (context,
601 view_type_prop, &view_type,
602 view_size_prop, &view_size,
603 NULL);
604
605 return view_props_connect (font_box_new (container, context, label, spacing,
606 view_type, view_size),
607 context,
608 view_type_prop, view_size_prop);
609 }
610
611
612 /* private functions */
613
614 static GtkWidget *
gimp_viewable_box_new(GimpContainer * container,GimpContext * context,const gchar * label,gint spacing,GimpViewType view_type,GimpViewSize button_view_size,GimpViewSize view_size,const gchar * dialog_identifier,const gchar * dialog_icon_name,const gchar * dialog_tooltip,const gchar * editor_id,const gchar * editor_tooltip)615 gimp_viewable_box_new (GimpContainer *container,
616 GimpContext *context,
617 const gchar *label,
618 gint spacing,
619 GimpViewType view_type,
620 GimpViewSize button_view_size,
621 GimpViewSize view_size,
622 const gchar *dialog_identifier,
623 const gchar *dialog_icon_name,
624 const gchar *dialog_tooltip,
625 const gchar *editor_id,
626 const gchar *editor_tooltip)
627 {
628 GtkWidget *hbox;
629 GtkWidget *button;
630 GtkWidget *vbox;
631 GtkWidget *l;
632 GtkWidget *entry;
633
634 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, spacing);
635
636 button = gimp_viewable_button_new (container, context,
637 view_type, button_view_size, view_size, 1,
638 gimp_dialog_factory_get_singleton (),
639 dialog_identifier,
640 dialog_icon_name,
641 dialog_tooltip);
642
643 gimp_view_renderer_set_size_full (GIMP_VIEW (GIMP_VIEWABLE_BUTTON (button)->view)->renderer,
644 button_view_size, button_view_size, 1);
645
646 g_object_set_data (G_OBJECT (hbox), "viewable-button", button);
647
648 gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
649 gtk_widget_show (button);
650
651 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
652 gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
653 gtk_widget_show (vbox);
654
655 if (label)
656 {
657 l = gtk_label_new_with_mnemonic (label);
658 gtk_label_set_xalign (GTK_LABEL (l), 0.0);
659 gtk_box_pack_start (GTK_BOX (vbox), l, FALSE, FALSE, 0);
660 gtk_widget_show (l);
661 }
662
663 entry = gimp_container_entry_new (container, context, view_size, 1);
664
665 /* set a silly smally size request on the entry to disable
666 * GtkEntry's minimal width of 150 pixels.
667 */
668 gtk_entry_set_width_chars (GTK_ENTRY (entry), 4);
669 gtk_box_pack_end (GTK_BOX (vbox), entry, label ? FALSE : TRUE, FALSE, 0);
670 gtk_widget_show (entry);
671
672 if (editor_id)
673 {
674 GtkWidget *edit_button;
675 GtkWidget *image;
676
677 edit_button = gtk_button_new ();
678 gtk_button_set_relief (GTK_BUTTON (edit_button), GTK_RELIEF_NONE);
679 gtk_box_pack_end (GTK_BOX (hbox), edit_button, FALSE, FALSE, 0);
680 gtk_widget_show (edit_button);
681
682 if (editor_tooltip)
683 gimp_help_set_help_data (edit_button, editor_tooltip, NULL);
684
685 image = gtk_image_new_from_icon_name (GIMP_ICON_EDIT,
686 GTK_ICON_SIZE_BUTTON);
687 gtk_misc_set_alignment (GTK_MISC (image), 0.5, 1.0);
688 gtk_container_add (GTK_CONTAINER (edit_button), image);
689 gtk_widget_show (image);
690
691 g_object_set_data_full (G_OBJECT (button),
692 "gimp-viewable-box-editor",
693 g_strdup (editor_id),
694 (GDestroyNotify) g_free);
695
696 g_signal_connect (edit_button, "clicked",
697 G_CALLBACK (gimp_viewable_box_edit_clicked),
698 button);
699 }
700
701 return hbox;
702 }
703
704 static GtkWidget *
view_props_connect(GtkWidget * box,GimpContext * context,const gchar * view_type_prop,const gchar * view_size_prop)705 view_props_connect (GtkWidget *box,
706 GimpContext *context,
707 const gchar *view_type_prop,
708 const gchar *view_size_prop)
709 {
710 GtkWidget *button = g_object_get_data (G_OBJECT (box), "viewable-button");
711
712 if (view_type_prop)
713 gimp_config_connect_full (G_OBJECT (context), G_OBJECT (button),
714 view_type_prop, "popup-view-type");
715
716 if (view_size_prop)
717 gimp_config_connect_full (G_OBJECT (context), G_OBJECT (button),
718 view_size_prop, "popup-view-size");
719
720 return box;
721 }
722
723 static void
gimp_viewable_box_edit_clicked(GtkWidget * widget,GimpViewableButton * button)724 gimp_viewable_box_edit_clicked (GtkWidget *widget,
725 GimpViewableButton *button)
726 {
727 const gchar *editor_id = g_object_get_data (G_OBJECT (button),
728 "gimp-viewable-box-editor");
729
730 gimp_window_strategy_show_dockable_dialog (GIMP_WINDOW_STRATEGY (gimp_get_window_strategy (button->context->gimp)),
731 button->context->gimp,
732 gimp_dialog_factory_get_singleton (),
733 gtk_widget_get_screen (widget),
734 gimp_widget_get_monitor (widget),
735 editor_id);
736 }
737
738 static void
gimp_gradient_box_reverse_notify(GObject * object,GParamSpec * pspec,GimpView * view)739 gimp_gradient_box_reverse_notify (GObject *object,
740 GParamSpec *pspec,
741 GimpView *view)
742 {
743 GimpViewRendererGradient *rendergrad;
744 gboolean reverse;
745
746 rendergrad = GIMP_VIEW_RENDERER_GRADIENT (view->renderer);
747
748 g_object_get (object, "gradient-reverse", &reverse, NULL);
749
750 gimp_view_renderer_gradient_set_reverse (rendergrad, reverse);
751 }
752
753 static void
gimp_gradient_box_blend_notify(GObject * object,GParamSpec * pspec,GimpView * view)754 gimp_gradient_box_blend_notify (GObject *object,
755 GParamSpec *pspec,
756 GimpView *view)
757 {
758 GimpViewRendererGradient *rendergrad;
759 GimpGradientBlendColorSpace blend_color_space;
760
761 rendergrad = GIMP_VIEW_RENDERER_GRADIENT (view->renderer);
762
763 g_object_get (object,
764 "gradient-blend-color-space", &blend_color_space,
765 NULL);
766
767 gimp_view_renderer_gradient_set_blend_color_space (rendergrad,
768 blend_color_space);
769 }
770