1 /* GIMP - The GNU Image Manipulation Program
2  * Copyright (C) 1995 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 <stdlib.h>
21 #include <string.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/gimp.h"
31 #include "core/gimpbrush.h"
32 #include "core/gimpcontext.h"
33 #include "core/gimpgradient.h"
34 #include "core/gimppattern.h"
35 
36 #include "gimpdnd.h"
37 #include "gimpview.h"
38 #include "gimptoolbox.h"
39 #include "gimptoolbox-indicator-area.h"
40 #include "gimpwidgets-utils.h"
41 #include "gimpwindowstrategy.h"
42 
43 #include "gimp-intl.h"
44 
45 
46 #define CELL_SIZE        24  /*  The size of the previews                  */
47 #define GRAD_CELL_WIDTH  52  /*  The width of the gradient preview         */
48 #define GRAD_CELL_HEIGHT 12  /*  The height of the gradient preview        */
49 #define CELL_SPACING      2  /*  How much between brush and pattern cells  */
50 
51 
52 static void
brush_preview_clicked(GtkWidget * widget,GdkModifierType state,GimpToolbox * toolbox)53 brush_preview_clicked (GtkWidget       *widget,
54                        GdkModifierType  state,
55                        GimpToolbox     *toolbox)
56 {
57   GimpContext *context = gimp_toolbox_get_context (toolbox);
58 
59   gimp_window_strategy_show_dockable_dialog (GIMP_WINDOW_STRATEGY (gimp_get_window_strategy (context->gimp)),
60                                              context->gimp,
61                                              gimp_dock_get_dialog_factory (GIMP_DOCK (toolbox)),
62                                              gtk_widget_get_screen (widget),
63                                              gimp_widget_get_monitor (widget),
64                                              "gimp-brush-grid|gimp-brush-list");
65 }
66 
67 static void
brush_preview_drop_brush(GtkWidget * widget,gint x,gint y,GimpViewable * viewable,gpointer data)68 brush_preview_drop_brush (GtkWidget    *widget,
69                           gint          x,
70                           gint          y,
71                           GimpViewable *viewable,
72                           gpointer      data)
73 {
74   GimpContext *context = GIMP_CONTEXT (data);
75 
76   gimp_context_set_brush (context, GIMP_BRUSH (viewable));
77 }
78 
79 static void
pattern_preview_clicked(GtkWidget * widget,GdkModifierType state,GimpToolbox * toolbox)80 pattern_preview_clicked (GtkWidget       *widget,
81                          GdkModifierType  state,
82                          GimpToolbox     *toolbox)
83 {
84   GimpContext *context = gimp_toolbox_get_context (toolbox);
85 
86   gimp_window_strategy_show_dockable_dialog (GIMP_WINDOW_STRATEGY (gimp_get_window_strategy (context->gimp)),
87                                              context->gimp,
88                                              gimp_dock_get_dialog_factory (GIMP_DOCK (toolbox)),
89                                              gtk_widget_get_screen (widget),
90                                              gimp_widget_get_monitor (widget),
91                                              "gimp-pattern-grid|gimp-pattern-list");
92 }
93 
94 static void
pattern_preview_drop_pattern(GtkWidget * widget,gint x,gint y,GimpViewable * viewable,gpointer data)95 pattern_preview_drop_pattern (GtkWidget    *widget,
96                               gint          x,
97                               gint          y,
98                               GimpViewable *viewable,
99                               gpointer      data)
100 {
101   GimpContext *context = GIMP_CONTEXT (data);
102 
103   gimp_context_set_pattern (context, GIMP_PATTERN (viewable));
104 }
105 
106 static void
gradient_preview_clicked(GtkWidget * widget,GdkModifierType state,GimpToolbox * toolbox)107 gradient_preview_clicked (GtkWidget       *widget,
108                           GdkModifierType  state,
109                           GimpToolbox     *toolbox)
110 {
111   GimpContext *context = gimp_toolbox_get_context (toolbox);
112 
113   gimp_window_strategy_show_dockable_dialog (GIMP_WINDOW_STRATEGY (gimp_get_window_strategy (context->gimp)),
114                                              context->gimp,
115                                              gimp_dock_get_dialog_factory (GIMP_DOCK (toolbox)),
116                                              gtk_widget_get_screen (widget),
117                                              gimp_widget_get_monitor (widget),
118                                              "gimp-gradient-list|gimp-gradient-grid");
119 }
120 
121 static void
gradient_preview_drop_gradient(GtkWidget * widget,gint x,gint y,GimpViewable * viewable,gpointer data)122 gradient_preview_drop_gradient (GtkWidget    *widget,
123                                 gint          x,
124                                 gint          y,
125                                 GimpViewable *viewable,
126                                 gpointer      data)
127 {
128   GimpContext *context = GIMP_CONTEXT (data);
129 
130   gimp_context_set_gradient (context, GIMP_GRADIENT (viewable));
131 }
132 
133 
134 /*  public functions  */
135 
136 GtkWidget *
gimp_toolbox_indicator_area_create(GimpToolbox * toolbox)137 gimp_toolbox_indicator_area_create (GimpToolbox *toolbox)
138 {
139   GimpContext *context;
140   GtkWidget   *indicator_table;
141   GtkWidget   *brush_view;
142   GtkWidget   *pattern_view;
143   GtkWidget   *gradient_view;
144 
145   g_return_val_if_fail (GIMP_IS_TOOLBOX (toolbox), NULL);
146 
147   context = gimp_toolbox_get_context (toolbox);
148 
149   indicator_table = gtk_table_new (2, 2, FALSE);
150   gtk_table_set_row_spacings (GTK_TABLE (indicator_table), CELL_SPACING);
151   gtk_table_set_col_spacings (GTK_TABLE (indicator_table), CELL_SPACING);
152 
153   /*  brush view  */
154 
155   brush_view =
156     gimp_view_new_full_by_types (context,
157                                  GIMP_TYPE_VIEW, GIMP_TYPE_BRUSH,
158                                  CELL_SIZE, CELL_SIZE, 1,
159                                  FALSE, TRUE, TRUE);
160   gimp_view_set_viewable (GIMP_VIEW (brush_view),
161                           GIMP_VIEWABLE (gimp_context_get_brush (context)));
162   gtk_table_attach_defaults (GTK_TABLE (indicator_table), brush_view,
163                              0, 1, 0, 1);
164   gtk_widget_show (brush_view);
165 
166   gimp_help_set_help_data (brush_view,
167                            _("The active brush.\n"
168                              "Click to open the Brush Dialog."), NULL);
169 
170   g_signal_connect_object (context, "brush-changed",
171                            G_CALLBACK (gimp_view_set_viewable),
172                            brush_view,
173                            G_CONNECT_SWAPPED);
174 
175   g_signal_connect (brush_view, "clicked",
176                     G_CALLBACK (brush_preview_clicked),
177                     toolbox);
178 
179   gimp_dnd_viewable_dest_add (brush_view,
180                               GIMP_TYPE_BRUSH,
181                               brush_preview_drop_brush,
182                               context);
183 
184   /*  pattern view  */
185 
186   pattern_view =
187     gimp_view_new_full_by_types (context,
188                                  GIMP_TYPE_VIEW, GIMP_TYPE_PATTERN,
189                                  CELL_SIZE, CELL_SIZE, 1,
190                                  FALSE, TRUE, TRUE);
191   gimp_view_set_viewable (GIMP_VIEW (pattern_view),
192                           GIMP_VIEWABLE (gimp_context_get_pattern (context)));
193 
194   gtk_table_attach_defaults (GTK_TABLE (indicator_table), pattern_view,
195                              1, 2, 0, 1);
196   gtk_widget_show (pattern_view);
197 
198   gimp_help_set_help_data (pattern_view,
199                            _("The active pattern.\n"
200                              "Click to open the Pattern Dialog."), NULL);
201 
202   g_signal_connect_object (context, "pattern-changed",
203                            G_CALLBACK (gimp_view_set_viewable),
204                            pattern_view,
205                            G_CONNECT_SWAPPED);
206 
207   g_signal_connect (pattern_view, "clicked",
208                     G_CALLBACK (pattern_preview_clicked),
209                     toolbox);
210 
211   gimp_dnd_viewable_dest_add (pattern_view,
212                               GIMP_TYPE_PATTERN,
213                               pattern_preview_drop_pattern,
214                               context);
215 
216   /*  gradient view  */
217 
218   gradient_view =
219     gimp_view_new_full_by_types (context,
220                                  GIMP_TYPE_VIEW, GIMP_TYPE_GRADIENT,
221                                  GRAD_CELL_WIDTH, GRAD_CELL_HEIGHT, 1,
222                                  FALSE, TRUE, TRUE);
223   gimp_view_set_viewable (GIMP_VIEW (gradient_view),
224                           GIMP_VIEWABLE (gimp_context_get_gradient (context)));
225 
226   gtk_table_attach_defaults (GTK_TABLE (indicator_table), gradient_view,
227                              0, 2, 1, 2);
228   gtk_widget_show (gradient_view);
229 
230   gimp_help_set_help_data (gradient_view,
231                            _("The active gradient.\n"
232                              "Click to open the Gradient Dialog."), NULL);
233 
234   g_signal_connect_object (context, "gradient-changed",
235                            G_CALLBACK (gimp_view_set_viewable),
236                            gradient_view,
237                            G_CONNECT_SWAPPED);
238 
239   g_signal_connect (gradient_view, "clicked",
240                     G_CALLBACK (gradient_preview_clicked),
241                     toolbox);
242 
243   gimp_dnd_viewable_dest_add (gradient_view,
244                               GIMP_TYPE_GRADIENT,
245                               gradient_preview_drop_gradient,
246                               context);
247 
248   gtk_widget_show (indicator_table);
249 
250   return indicator_table;
251 }
252