22
22
#include "config.h"
26
24
#include <gtk/gtk.h>
28
#include "libgimpbase/gimpbase.h"
29
#include "libgimpwidgets/gimpwidgets.h"
31
26
#include "widgets-types.h"
28
#include "config/gimpguiconfig.h"
33
30
#include "core/gimp.h"
31
#include "core/gimpcontainer.h"
34
32
#include "core/gimpcontext.h"
35
#include "core/gimpimage.h"
36
#include "core/gimplist.h"
37
#include "core/gimptoolinfo.h"
39
34
#include "gimpdialogfactory.h"
40
35
#include "gimpimagedock.h"
41
#include "gimpcontainercombobox.h"
42
#include "gimpcontainerview.h"
43
#include "gimpdockable.h"
44
#include "gimpdockbook.h"
45
#include "gimphelp-ids.h"
46
36
#include "gimpmenufactory.h"
47
#include "gimpsessioninfo.h"
48
37
#include "gimpuimanager.h"
50
#include "gimp-intl.h"
53
#define DEFAULT_MINIMAL_WIDTH 250
54
#define DEFAULT_MENU_PREVIEW_SIZE GTK_ICON_SIZE_SMALL_TOOLBAR
57
static void gimp_image_dock_class_init (GimpImageDockClass *klass);
58
static void gimp_image_dock_init (GimpImageDock *dock);
60
static GObject * gimp_image_dock_constructor (GType type,
62
GObjectConstructParam *params);
63
static void gimp_image_dock_destroy (GtkObject *object);
65
static void gimp_image_dock_style_set (GtkWidget *widget,
66
GtkStyle *prev_style);
68
static void gimp_image_dock_setup (GimpDock *dock,
69
const GimpDock *template);
70
static void gimp_image_dock_set_aux_info (GimpDock *dock,
72
static GList *gimp_image_dock_get_aux_info (GimpDock *dock);
73
static void gimp_image_dock_book_added (GimpDock *dock,
74
GimpDockbook *dockbook);
75
static void gimp_image_dock_book_removed (GimpDock *dock,
76
GimpDockbook *dockbook);
78
static void gimp_image_dock_dockbook_changed (GimpDockbook *dockbook,
79
GimpDockable *dockable,
81
static void gimp_image_dock_update_title (GimpImageDock *dock);
83
static void gimp_image_dock_factory_display_changed (GimpContext *context,
86
static void gimp_image_dock_factory_image_changed (GimpContext *context,
89
static void gimp_image_dock_display_changed (GimpContext *context,
92
static void gimp_image_dock_image_changed (GimpContext *context,
95
static void gimp_image_dock_auto_clicked (GtkWidget *widget,
97
static void gimp_image_dock_image_flush (GimpImage *gimage,
101
static GimpDockClass *parent_class = NULL;
105
gimp_image_dock_get_type (void)
107
static GType dock_type = 0;
111
static const GTypeInfo dock_info =
113
sizeof (GimpImageDockClass),
114
NULL, /* base_init */
115
NULL, /* base_finalize */
116
(GClassInitFunc) gimp_image_dock_class_init,
117
NULL, /* class_finalize */
118
NULL, /* class_data */
119
sizeof (GimpImageDock),
121
(GInstanceInitFunc) gimp_image_dock_init,
124
dock_type = g_type_register_static (GIMP_TYPE_DOCK,
40
static GObject * gimp_image_dock_constructor (GType type,
42
GObjectConstructParam *params);
44
static void gimp_image_dock_destroy (GtkObject *object);
46
static void gimp_image_dock_display_changed (GimpContext *context,
49
static void gimp_image_dock_image_flush (GimpImage *image,
52
static void gimp_image_dock_notify_transient (GimpConfig *config,
57
G_DEFINE_TYPE (GimpImageDock, gimp_image_dock, GIMP_TYPE_DOCK)
59
#define parent_class gimp_image_dock_parent_class
133
63
gimp_image_dock_class_init (GimpImageDockClass *klass)
135
GObjectClass *object_class;
136
GtkObjectClass *gtk_object_class;
137
GtkWidgetClass *widget_class;
138
GimpDockClass *dock_class;
140
object_class = G_OBJECT_CLASS (klass);
141
gtk_object_class = GTK_OBJECT_CLASS (klass);
142
widget_class = GTK_WIDGET_CLASS (klass);
143
dock_class = GIMP_DOCK_CLASS (klass);
145
parent_class = g_type_class_peek_parent (klass);
65
GObjectClass *object_class = G_OBJECT_CLASS (klass);
66
GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
147
68
object_class->constructor = gimp_image_dock_constructor;
149
70
gtk_object_class->destroy = gimp_image_dock_destroy;
151
widget_class->style_set = gimp_image_dock_style_set;
153
dock_class->setup = gimp_image_dock_setup;
154
dock_class->set_aux_info = gimp_image_dock_set_aux_info;
155
dock_class->get_aux_info = gimp_image_dock_get_aux_info;
156
dock_class->book_added = gimp_image_dock_book_added;
157
dock_class->book_removed = gimp_image_dock_book_removed;
159
gtk_widget_class_install_style_property (widget_class,
160
g_param_spec_int ("minimal_width",
164
DEFAULT_MINIMAL_WIDTH,
166
gtk_widget_class_install_style_property (widget_class,
167
g_param_spec_enum ("menu_preview_size",
170
DEFAULT_MENU_PREVIEW_SIZE,
72
klass->ui_manager_name = "<Dock>";
175
76
gimp_image_dock_init (GimpImageDock *dock)
179
dock->image_container = NULL;
180
dock->display_container = NULL;
181
dock->show_image_menu = FALSE;
182
dock->auto_follow_active = TRUE;
183
dock->update_title_idle_id = 0;
185
hbox = gtk_hbox_new (FALSE, 2);
186
gtk_box_pack_start (GTK_BOX (GIMP_DOCK (dock)->main_vbox), hbox,
188
gtk_box_reorder_child (GTK_BOX (GIMP_DOCK (dock)->main_vbox), hbox, 0);
190
if (dock->show_image_menu)
191
gtk_widget_show (hbox);
193
dock->image_combo = gimp_container_combo_box_new (NULL, NULL, 16, 1);
194
gtk_box_pack_start (GTK_BOX (hbox), dock->image_combo, TRUE, TRUE, 0);
195
gtk_widget_show (dock->image_combo);
197
g_signal_connect (dock->image_combo, "destroy",
198
G_CALLBACK (gtk_widget_destroyed),
201
gimp_help_set_help_data (dock->image_combo, NULL, GIMP_HELP_DOCK_IMAGE_MENU);
203
dock->auto_button = gtk_toggle_button_new_with_label (_("Auto"));
204
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dock->auto_button),
205
dock->auto_follow_active);
206
gtk_box_pack_start (GTK_BOX (hbox), dock->auto_button, FALSE, FALSE, 0);
207
gtk_widget_show (dock->auto_button);
209
g_signal_connect (dock->auto_button, "clicked",
210
G_CALLBACK (gimp_image_dock_auto_clicked),
213
gimp_help_set_help_data (dock->auto_button,
214
_("When enabled the dialog automatically "
215
"follows the image you are working on."),
216
GIMP_HELP_DOCK_AUTO_BUTTON);
78
dock->ui_manager = NULL;
79
dock->image_flush_handler_id = 0;
269
141
dock->ui_manager = NULL;
272
/* remove the image menu and the auto button manually here because
273
* of weird cross-connections with GimpDock's context
275
if (GIMP_DOCK (dock)->main_vbox &&
277
dock->image_combo->parent)
279
gtk_container_remove (GTK_CONTAINER (GIMP_DOCK (dock)->main_vbox),
280
dock->image_combo->parent);
283
144
GTK_OBJECT_CLASS (parent_class)->destroy (object);
287
gimp_image_dock_style_set (GtkWidget *widget,
288
GtkStyle *prev_style)
290
GimpImageDock *image_dock;
292
GtkIconSize menu_preview_size;
294
gint menu_preview_width = 18;
295
gint menu_preview_height = 18;
296
gint focus_line_width;
300
image_dock = GIMP_IMAGE_DOCK (widget);
302
if (GTK_WIDGET_CLASS (parent_class)->style_set)
303
GTK_WIDGET_CLASS (parent_class)->style_set (widget, prev_style);
305
gtk_widget_style_get (widget,
306
"minimal_width", &minimal_width,
307
"menu_preview_size", &menu_preview_size,
310
screen = gtk_widget_get_screen (image_dock->image_combo);
311
gtk_icon_size_lookup_for_settings (gtk_settings_get_for_screen (screen),
314
&menu_preview_height);
316
gtk_widget_style_get (image_dock->auto_button,
317
"focus_line_width", &focus_line_width,
318
"focus_padding", &focus_padding,
321
ythickness = image_dock->auto_button->style->ythickness;
323
gtk_widget_set_size_request (widget, minimal_width, -1);
325
gimp_container_view_set_preview_size (GIMP_CONTAINER_VIEW (image_dock->image_combo),
326
menu_preview_height, 1);
328
gtk_widget_set_size_request (image_dock->auto_button, -1,
329
menu_preview_height +
330
2 * (1 /* CHILD_SPACING */ +
337
gimp_image_dock_setup (GimpDock *dock,
338
const GimpDock *template)
340
if (GIMP_IS_IMAGE_DOCK (template))
342
gboolean auto_follow_active;
343
gboolean show_image_menu;
345
auto_follow_active = GIMP_IMAGE_DOCK (template)->auto_follow_active;
346
show_image_menu = GIMP_IMAGE_DOCK (template)->show_image_menu;
348
gimp_image_dock_set_auto_follow_active (GIMP_IMAGE_DOCK (dock),
350
gimp_image_dock_set_show_image_menu (GIMP_IMAGE_DOCK (dock),
355
#define AUX_INFO_SHOW_IMAGE_MENU "show-image-menu"
356
#define AUX_INFO_FOLLOW_ACTIVE_IMAGE "follow-active-image"
359
gimp_image_dock_set_aux_info (GimpDock *dock,
362
GimpImageDock *image_dock = GIMP_IMAGE_DOCK (dock);
364
gboolean menu_shown = image_dock->show_image_menu;
365
gboolean auto_follow = image_dock->auto_follow_active;
367
for (list = aux_info; list; list = g_list_next (list))
369
GimpSessionInfoAux *aux = list->data;
371
if (! strcmp (aux->name, AUX_INFO_SHOW_IMAGE_MENU))
373
menu_shown = ! g_ascii_strcasecmp (aux->value, "true");
375
else if (! strcmp (aux->name, AUX_INFO_FOLLOW_ACTIVE_IMAGE))
377
auto_follow = ! g_ascii_strcasecmp (aux->value, "true");
381
if (menu_shown != image_dock->show_image_menu)
382
gimp_image_dock_set_show_image_menu (image_dock, menu_shown);
384
if (auto_follow != image_dock->auto_follow_active)
385
gimp_image_dock_set_auto_follow_active (image_dock, auto_follow);
389
gimp_image_dock_get_aux_info (GimpDock *dock)
391
GimpImageDock *image_dock = GIMP_IMAGE_DOCK (dock);
392
GList *aux_info = NULL;
393
GimpSessionInfoAux *aux;
395
aux = gimp_session_info_aux_new (AUX_INFO_SHOW_IMAGE_MENU,
396
image_dock->show_image_menu ?
398
aux_info = g_list_append (aux_info, aux);
400
aux = gimp_session_info_aux_new (AUX_INFO_FOLLOW_ACTIVE_IMAGE,
401
image_dock->auto_follow_active ?
403
aux_info = g_list_append (aux_info, aux);
409
gimp_image_dock_book_added (GimpDock *dock,
410
GimpDockbook *dockbook)
412
g_signal_connect (dockbook, "dockable_added",
413
G_CALLBACK (gimp_image_dock_dockbook_changed),
415
g_signal_connect (dockbook, "dockable_removed",
416
G_CALLBACK (gimp_image_dock_dockbook_changed),
418
g_signal_connect (dockbook, "dockable_reordered",
419
G_CALLBACK (gimp_image_dock_dockbook_changed),
422
gimp_image_dock_update_title (GIMP_IMAGE_DOCK (dock));
424
GIMP_DOCK_CLASS (parent_class)->book_added (dock, dockbook);
428
gimp_image_dock_book_removed (GimpDock *dock,
429
GimpDockbook *dockbook)
431
g_signal_handlers_disconnect_by_func (dockbook,
432
gimp_image_dock_dockbook_changed,
435
gimp_image_dock_update_title (GIMP_IMAGE_DOCK (dock));
437
GIMP_DOCK_CLASS (parent_class)->book_removed (dock, dockbook);
441
gimp_image_dock_new (GimpDialogFactory *dialog_factory,
442
GimpContainer *image_container,
443
GimpContainer *display_container)
445
GimpImageDock *image_dock;
446
GimpContext *context;
448
gint menu_preview_width;
449
gint menu_preview_height;
451
g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (dialog_factory), NULL);
452
g_return_val_if_fail (GIMP_IS_CONTAINER (image_container), NULL);
453
g_return_val_if_fail (GIMP_IS_CONTAINER (display_container), NULL);
455
context = gimp_context_new (dialog_factory->context->gimp,
456
"Dock Context", NULL);
458
image_dock = g_object_new (GIMP_TYPE_IMAGE_DOCK,
460
"dialog-factory", dialog_factory,
463
image_dock->image_container = image_container;
464
image_dock->display_container = display_container;
466
image_dock->image_flush_handler_id =
467
gimp_container_add_handler (image_container, "flush",
468
G_CALLBACK (gimp_image_dock_image_flush),
471
gimp_help_connect (GTK_WIDGET (image_dock), gimp_standard_help_func,
472
GIMP_HELP_DOCK, NULL);
474
gimp_context_define_properties (context,
475
GIMP_CONTEXT_ALL_PROPS_MASK &
476
~(GIMP_CONTEXT_IMAGE_MASK |
477
GIMP_CONTEXT_DISPLAY_MASK),
479
gimp_context_set_parent (context, dialog_factory->context);
481
if (image_dock->auto_follow_active)
483
if (gimp_context_get_display (dialog_factory->context))
484
gimp_context_copy_property (dialog_factory->context, context,
485
GIMP_CONTEXT_PROP_DISPLAY);
487
gimp_context_copy_property (dialog_factory->context, context,
488
GIMP_CONTEXT_PROP_IMAGE);
491
g_signal_connect_object (dialog_factory->context, "display_changed",
492
G_CALLBACK (gimp_image_dock_factory_display_changed),
495
g_signal_connect_object (dialog_factory->context, "image_changed",
496
G_CALLBACK (gimp_image_dock_factory_image_changed),
500
g_signal_connect_object (context, "display_changed",
501
G_CALLBACK (gimp_image_dock_display_changed),
504
g_signal_connect_object (context, "image_changed",
505
G_CALLBACK (gimp_image_dock_image_changed),
509
screen = gtk_widget_get_screen (GTK_WIDGET (image_dock));
510
gtk_icon_size_lookup_for_settings (gtk_settings_get_for_screen (screen),
511
DEFAULT_MENU_PREVIEW_SIZE,
513
&menu_preview_height);
515
g_object_set (image_dock->image_combo,
516
"container", image_container,
520
return GTK_WIDGET (image_dock);
524
gimp_image_dock_set_auto_follow_active (GimpImageDock *image_dock,
525
gboolean auto_follow_active)
527
g_return_if_fail (GIMP_IS_IMAGE_DOCK (image_dock));
529
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (image_dock->auto_button),
530
auto_follow_active ? TRUE : FALSE);
534
gimp_image_dock_set_show_image_menu (GimpImageDock *image_dock,
537
g_return_if_fail (GIMP_IS_IMAGE_DOCK (image_dock));
540
gtk_widget_show (image_dock->image_combo->parent);
148
gimp_image_dock_display_changed (GimpContext *context,
152
gimp_ui_manager_update (dock->ui_manager, display);
154
if (GIMP_GUI_CONFIG (context->gimp->config)->transient_docks)
156
GtkWindow *parent = NULL;
159
g_object_get (display, "shell", &parent, NULL);
161
gtk_window_set_transient_for (GTK_WINDOW (dock), parent);
164
g_object_unref (parent);
169
gimp_image_dock_image_flush (GimpImage *image,
172
if (image == gimp_context_get_image (GIMP_DOCK (dock)->context))
174
GimpObject *display = gimp_context_get_display (GIMP_DOCK (dock)->context);
177
gimp_ui_manager_update (dock->ui_manager, display);
182
gimp_image_dock_notify_transient (GimpConfig *config,
186
if (GIMP_GUI_CONFIG (config)->transient_docks)
188
gimp_image_dock_display_changed (dock->context,
189
gimp_context_get_display (dock->context),
190
GIMP_IMAGE_DOCK (dock));
542
gtk_widget_hide (image_dock->image_combo->parent);
544
image_dock->show_image_menu = show ? TRUE : FALSE;
548
gimp_image_dock_dockbook_changed (GimpDockbook *dockbook,
549
GimpDockable *dockable,
552
gimp_image_dock_update_title (dock);
556
gimp_image_dock_update_title_idle (GimpImageDock *image_dock)
561
title = g_string_new (NULL);
563
for (list = GIMP_DOCK (image_dock)->dockbooks;
565
list = g_list_next (list))
567
GimpDockbook *dockbook = list->data;
571
children = gtk_container_get_children (GTK_CONTAINER (dockbook));
573
for (child = children; child; child = g_list_next (child))
575
GimpDockable *dockable = child->data;
577
g_string_append (title, dockable->name);
579
if (g_list_next (child))
580
g_string_append (title, ", ");
583
g_list_free (children);
585
if (g_list_next (list))
586
g_string_append (title, " | ");
589
gtk_window_set_title (GTK_WINDOW (image_dock), title->str);
591
g_string_free (title, TRUE);
593
image_dock->update_title_idle_id = 0;
599
gimp_image_dock_update_title (GimpImageDock *image_dock)
601
if (image_dock->update_title_idle_id)
602
g_source_remove (image_dock->update_title_idle_id);
604
image_dock->update_title_idle_id =
605
g_idle_add ((GSourceFunc) gimp_image_dock_update_title_idle,
610
gimp_image_dock_factory_display_changed (GimpContext *context,
614
GimpImageDock *image_dock = GIMP_IMAGE_DOCK (dock);
616
if (display && image_dock->auto_follow_active)
617
gimp_context_set_display (dock->context, display);
621
gimp_image_dock_factory_image_changed (GimpContext *context,
625
GimpImageDock *image_dock = GIMP_IMAGE_DOCK (dock);
627
/* won't do anything if we already set the display above */
628
if (gimage && image_dock->auto_follow_active)
629
gimp_context_set_image (dock->context, gimage);
633
gimp_image_dock_display_changed (GimpContext *context,
637
GimpImageDock *image_dock = GIMP_IMAGE_DOCK (dock);
639
gimp_ui_manager_update (image_dock->ui_manager, display);
643
gimp_image_dock_image_changed (GimpContext *context,
647
GimpImageDock *image_dock = GIMP_IMAGE_DOCK (dock);
649
if (gimage == NULL &&
650
gimp_container_num_children (image_dock->image_container) > 0)
652
gimage = GIMP_IMAGE (gimp_container_get_child_by_index (image_dock->image_container, 0));
656
/* this invokes this function recursively but we don't enter
657
* the if() branch the second time
659
gimp_context_set_image (context, gimage);
661
/* stop the emission of the original signal (the emission of
662
* the recursive signal is finished)
664
g_signal_stop_emission_by_name (context, "image_changed");
667
else if (gimage != NULL &&
668
gimp_container_num_children (image_dock->display_container) > 0)
671
GimpImage *gdisp_gimage;
672
gboolean find_display = TRUE;
674
gdisp = gimp_context_get_display (context);
678
g_object_get (gdisp, "image", &gdisp_gimage, NULL);
682
g_object_unref (gdisp_gimage);
684
if (gdisp_gimage == gimage)
685
find_display = FALSE;
693
for (list = GIMP_LIST (image_dock->display_container)->list;
695
list = g_list_next (list))
697
gdisp = GIMP_OBJECT (list->data);
699
g_object_get (gdisp, "image", &gdisp_gimage, NULL);
703
g_object_unref (gdisp_gimage);
705
if (gdisp_gimage == gimage)
707
/* this invokes this function recursively but we
708
* don't enter the if(find_display) branch the
711
gimp_context_set_display (context, gdisp);
713
/* don't stop signal emission here because the
714
* context's image was not changed by the
726
gimp_image_dock_auto_clicked (GtkWidget *widget,
729
GimpImageDock *image_dock = GIMP_IMAGE_DOCK (dock);
731
gimp_toggle_button_update (widget, &image_dock->auto_follow_active);
733
if (image_dock->auto_follow_active)
735
if (gimp_context_get_display (dock->dialog_factory->context))
736
gimp_context_copy_property (dock->dialog_factory->context,
738
GIMP_CONTEXT_PROP_DISPLAY);
740
gimp_context_copy_property (dock->dialog_factory->context,
742
GIMP_CONTEXT_PROP_IMAGE);
747
gimp_image_dock_image_flush (GimpImage *gimage,
750
GimpImageDock *image_dock = GIMP_IMAGE_DOCK (dock);
751
GimpImage *dock_image;
753
dock_image = gimp_context_get_image (dock->context);
755
if (dock_image == gimage)
757
GimpObject *display = gimp_context_get_display (dock->context);
760
gimp_ui_manager_update (image_dock->ui_manager, display);
194
gtk_window_set_transient_for (GTK_WINDOW (dock), NULL);