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 <gegl.h>
21 #include <gtk/gtk.h>
22 
23 #include "libgimpmath/gimpmath.h"
24 #include "libgimpwidgets/gimpwidgets.h"
25 
26 #include "actions-types.h"
27 
28 #include "core/gimp.h"
29 #include "core/gimpcontext.h"
30 #include "core/gimpgradient.h"
31 
32 #include "widgets/gimpgradienteditor.h"
33 #include "widgets/gimphelp-ids.h"
34 #include "widgets/gimpuimanager.h"
35 #include "widgets/gimpviewabledialog.h"
36 
37 #include "gradient-editor-commands.h"
38 
39 #include "gimp-intl.h"
40 
41 
42 /*  local function prototypes  */
43 
44 static void   gradient_editor_split_uniform_response (GtkWidget           *widget,
45                                                       gint                 response_id,
46                                                       GimpGradientEditor  *editor);
47 static void   gradient_editor_replicate_response     (GtkWidget           *widget,
48                                                       gint                 response_id,
49                                                       GimpGradientEditor  *editor);
50 
51 
52 /*  public functions */
53 
54 void
gradient_editor_left_color_cmd_callback(GimpAction * action,GVariant * value,gpointer data)55 gradient_editor_left_color_cmd_callback (GimpAction *action,
56                                          GVariant   *value,
57                                          gpointer    data)
58 {
59   GimpGradientEditor *editor = GIMP_GRADIENT_EDITOR (data);
60 
61   gimp_gradient_editor_edit_left_color (editor);
62 }
63 
64 void
gradient_editor_left_color_type_cmd_callback(GimpAction * action,GVariant * value,gpointer data)65 gradient_editor_left_color_type_cmd_callback (GimpAction *action,
66                                               GVariant   *value,
67                                               gpointer    data)
68 {
69   GimpGradientEditor  *editor = GIMP_GRADIENT_EDITOR (data);
70   GimpGradient        *gradient;
71   GimpGradientSegment *left;
72   GimpGradientColor    color_type;
73 
74   color_type = (GimpGradientColor) g_variant_get_int32 (value);
75 
76   gimp_gradient_editor_get_selection (editor, &gradient, &left, NULL);
77 
78   if (gradient        &&
79       color_type >= 0 &&
80       color_type !=
81       gimp_gradient_segment_get_left_color_type (gradient, left))
82     {
83       GimpRGB color;
84 
85       gimp_gradient_segment_get_left_flat_color (gradient,
86                                                  GIMP_DATA_EDITOR (editor)->context,
87                                                  left, &color);
88 
89       gimp_data_freeze (GIMP_DATA (gradient));
90 
91       gimp_gradient_segment_set_left_color_type (gradient, left, color_type);
92 
93       if (color_type == GIMP_GRADIENT_COLOR_FIXED)
94         gimp_gradient_segment_set_left_color (gradient, left, &color);
95 
96       gimp_data_thaw (GIMP_DATA (gradient));
97     }
98 }
99 
100 void
gradient_editor_load_left_cmd_callback(GimpAction * action,GVariant * value,gpointer data)101 gradient_editor_load_left_cmd_callback (GimpAction *action,
102                                         GVariant   *value,
103                                         gpointer    data)
104 {
105   GimpGradientEditor  *editor      = GIMP_GRADIENT_EDITOR (data);
106   GimpDataEditor      *data_editor = GIMP_DATA_EDITOR (data);
107   GimpGradient        *gradient;
108   GimpGradientSegment *left;
109   GimpGradientSegment *right;
110   GimpGradientSegment *seg;
111   GimpRGB              color;
112   GimpGradientColor    color_type = GIMP_GRADIENT_COLOR_FIXED;
113   gint                 index      = g_variant_get_int32 (value);
114 
115   gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
116 
117   switch (index)
118     {
119     case GRADIENT_EDITOR_COLOR_NEIGHBOR_ENDPOINT:
120       if (left->prev != NULL)
121         seg = left->prev;
122       else
123         seg = gimp_gradient_segment_get_last (left);
124 
125       color      = seg->right_color;
126       color_type = seg->right_color_type;
127       break;
128 
129     case GRADIENT_EDITOR_COLOR_OTHER_ENDPOINT:
130       color      = right->right_color;
131       color_type = right->right_color_type;
132       break;
133 
134     case GRADIENT_EDITOR_COLOR_FOREGROUND:
135       gimp_context_get_foreground (data_editor->context, &color);
136       break;
137 
138     case GRADIENT_EDITOR_COLOR_BACKGROUND:
139       gimp_context_get_background (data_editor->context, &color);
140       break;
141 
142     default: /* Load a color */
143       color = editor->saved_colors[index - GRADIENT_EDITOR_COLOR_FIRST_CUSTOM];
144       break;
145     }
146 
147   gimp_data_freeze (GIMP_DATA (gradient));
148 
149   gimp_gradient_segment_range_blend (gradient, left, right,
150                                      &color,
151                                      &right->right_color,
152                                      TRUE, TRUE);
153   gimp_gradient_segment_set_left_color_type (gradient, left, color_type);
154 
155   gimp_data_thaw (GIMP_DATA (gradient));
156 }
157 
158 void
gradient_editor_save_left_cmd_callback(GimpAction * action,GVariant * value,gpointer data)159 gradient_editor_save_left_cmd_callback (GimpAction *action,
160                                         GVariant   *value,
161                                         gpointer    data)
162 {
163   GimpGradientEditor  *editor = GIMP_GRADIENT_EDITOR (data);
164   GimpGradient        *gradient;
165   GimpGradientSegment *left;
166   gint                 index = g_variant_get_int32 (value);
167 
168   gimp_gradient_editor_get_selection (editor, &gradient, &left, NULL);
169 
170   gimp_gradient_segment_get_left_color (gradient, left,
171                                         &editor->saved_colors[index]);
172 }
173 
174 void
gradient_editor_right_color_cmd_callback(GimpAction * action,GVariant * value,gpointer data)175 gradient_editor_right_color_cmd_callback (GimpAction *action,
176                                           GVariant   *value,
177                                           gpointer    data)
178 {
179   GimpGradientEditor *editor = GIMP_GRADIENT_EDITOR (data);
180 
181   gimp_gradient_editor_edit_right_color (editor);
182 }
183 
184 void
gradient_editor_right_color_type_cmd_callback(GimpAction * action,GVariant * value,gpointer data)185 gradient_editor_right_color_type_cmd_callback (GimpAction *action,
186                                                GVariant   *value,
187                                                gpointer    data)
188 {
189   GimpGradientEditor  *editor = GIMP_GRADIENT_EDITOR (data);
190   GimpGradient        *gradient;
191   GimpGradientSegment *right;
192   GimpGradientColor    color_type;
193 
194   color_type = (GimpGradientColor) g_variant_get_int32 (value);
195 
196   gimp_gradient_editor_get_selection (editor, &gradient, NULL, &right);
197 
198   if (gradient        &&
199       color_type >= 0 &&
200       color_type !=
201       gimp_gradient_segment_get_right_color_type (gradient, right))
202     {
203       GimpRGB color;
204 
205       gimp_gradient_segment_get_right_flat_color (gradient,
206                                                   GIMP_DATA_EDITOR (editor)->context,
207                                                   right, &color);
208 
209       gimp_data_freeze (GIMP_DATA (gradient));
210 
211       gimp_gradient_segment_set_right_color_type (gradient, right, color_type);
212 
213       if (color_type == GIMP_GRADIENT_COLOR_FIXED)
214         gimp_gradient_segment_set_right_color (gradient, right, &color);
215 
216       gimp_data_thaw (GIMP_DATA (gradient));
217     }
218 }
219 
220 void
gradient_editor_load_right_cmd_callback(GimpAction * action,GVariant * value,gpointer data)221 gradient_editor_load_right_cmd_callback (GimpAction *action,
222                                          GVariant   *value,
223                                          gpointer    data)
224 {
225   GimpGradientEditor  *editor      = GIMP_GRADIENT_EDITOR (data);
226   GimpDataEditor      *data_editor = GIMP_DATA_EDITOR (data);
227   GimpGradient        *gradient;
228   GimpGradientSegment *left;
229   GimpGradientSegment *right;
230   GimpGradientSegment *seg;
231   GimpRGB              color;
232   GimpGradientColor    color_type = GIMP_GRADIENT_COLOR_FIXED;
233   gint                 index      = g_variant_get_int32 (value);
234 
235   gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
236 
237   switch (index)
238     {
239     case GRADIENT_EDITOR_COLOR_NEIGHBOR_ENDPOINT:
240       if (right->next != NULL)
241         seg = right->next;
242       else
243         seg = gimp_gradient_segment_get_first (right);
244 
245       color      = seg->left_color;
246       color_type = seg->left_color_type;
247       break;
248 
249     case GRADIENT_EDITOR_COLOR_OTHER_ENDPOINT:
250       color      = left->left_color;
251       color_type = left->left_color_type;
252       break;
253 
254     case GRADIENT_EDITOR_COLOR_FOREGROUND:
255       gimp_context_get_foreground (data_editor->context, &color);
256       break;
257 
258     case GRADIENT_EDITOR_COLOR_BACKGROUND:
259       gimp_context_get_background (data_editor->context, &color);
260       break;
261 
262     default: /* Load a color */
263       color = editor->saved_colors[index - GRADIENT_EDITOR_COLOR_FIRST_CUSTOM];
264       break;
265     }
266 
267   gimp_data_freeze (GIMP_DATA (gradient));
268 
269   gimp_gradient_segment_range_blend (gradient, left, right,
270                                      &left->left_color,
271                                      &color,
272                                      TRUE, TRUE);
273   gimp_gradient_segment_set_right_color_type (gradient, left, color_type);
274 
275   gimp_data_thaw (GIMP_DATA (gradient));
276 }
277 
278 void
gradient_editor_save_right_cmd_callback(GimpAction * action,GVariant * value,gpointer data)279 gradient_editor_save_right_cmd_callback (GimpAction *action,
280                                          GVariant   *value,
281                                          gpointer    data)
282 {
283   GimpGradientEditor  *editor = GIMP_GRADIENT_EDITOR (data);
284   GimpGradient        *gradient;
285   GimpGradientSegment *right;
286   gint                 index = g_variant_get_int32 (value);
287 
288   gimp_gradient_editor_get_selection (editor, &gradient, NULL, &right);
289 
290   gimp_gradient_segment_get_right_color (gradient, right,
291                                          &editor->saved_colors[index]);
292 }
293 
294 void
gradient_editor_blending_func_cmd_callback(GimpAction * action,GVariant * value,gpointer data)295 gradient_editor_blending_func_cmd_callback (GimpAction *action,
296                                             GVariant   *value,
297                                             gpointer    data)
298 {
299   GimpGradientEditor      *editor = GIMP_GRADIENT_EDITOR (data);
300   GimpGradient            *gradient;
301   GimpGradientSegment     *left;
302   GimpGradientSegment     *right;
303   GEnumClass              *enum_class = NULL;
304   GimpGradientSegmentType  type;
305 
306   type = (GimpGradientSegmentType) g_variant_get_int32 (value);
307 
308   gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
309 
310   enum_class = g_type_class_ref (GIMP_TYPE_GRADIENT_SEGMENT_TYPE);
311 
312   if (gradient && g_enum_get_value (enum_class, type))
313     {
314       gimp_gradient_segment_range_set_blending_function (gradient,
315                                                          left, right,
316                                                          type);
317     }
318 
319   g_type_class_unref (enum_class);
320 }
321 
322 void
gradient_editor_coloring_type_cmd_callback(GimpAction * action,GVariant * value,gpointer data)323 gradient_editor_coloring_type_cmd_callback (GimpAction *action,
324                                             GVariant   *value,
325                                             gpointer    data)
326 {
327   GimpGradientEditor       *editor = GIMP_GRADIENT_EDITOR (data);
328   GimpGradient             *gradient;
329   GimpGradientSegment      *left;
330   GimpGradientSegment      *right;
331   GEnumClass               *enum_class = NULL;
332   GimpGradientSegmentColor  color;
333 
334   color = (GimpGradientSegmentColor) g_variant_get_int32 (value);
335 
336   gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
337 
338   enum_class = g_type_class_ref (GIMP_TYPE_GRADIENT_SEGMENT_COLOR);
339 
340   if (gradient && g_enum_get_value (enum_class, color))
341     {
342       gimp_gradient_segment_range_set_coloring_type (gradient,
343                                                      left, right,
344                                                      color);
345     }
346 
347   g_type_class_unref (enum_class);
348 }
349 
350 void
gradient_editor_flip_cmd_callback(GimpAction * action,GVariant * value,gpointer data)351 gradient_editor_flip_cmd_callback (GimpAction *action,
352                                    GVariant   *value,
353                                    gpointer    data)
354 {
355   GimpGradientEditor  *editor = GIMP_GRADIENT_EDITOR (data);
356   GimpGradient        *gradient;
357   GimpGradientSegment *left;
358   GimpGradientSegment *right;
359 
360   gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
361 
362   gimp_gradient_segment_range_flip (gradient,
363                                     left, right,
364                                     &left, &right);
365 
366   gimp_gradient_editor_set_selection (editor, left, right);
367 }
368 
369 void
gradient_editor_replicate_cmd_callback(GimpAction * action,GVariant * value,gpointer data)370 gradient_editor_replicate_cmd_callback (GimpAction *action,
371                                         GVariant   *value,
372                                         gpointer    data)
373 {
374   GimpGradientEditor  *editor      = GIMP_GRADIENT_EDITOR (data);
375   GimpDataEditor      *data_editor = GIMP_DATA_EDITOR (data);
376   GimpGradient        *gradient;
377   GimpGradientSegment *left;
378   GimpGradientSegment *right;
379   GtkWidget           *dialog;
380   GtkWidget           *vbox;
381   GtkWidget           *label;
382   GtkWidget           *scale;
383   GtkAdjustment       *scale_data;
384   const gchar         *title;
385   const gchar         *desc;
386 
387   gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
388 
389   if (left == right)
390     {
391       title = _("Replicate Segment");
392       desc  = _("Replicate Gradient Segment");
393     }
394   else
395     {
396       title = _("Replicate Selection");
397       desc  = _("Replicate Gradient Selection");
398     }
399 
400   dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (gradient),
401                                      data_editor->context,
402                                      title,
403                                      "gimp-gradient-segment-replicate",
404                                      GIMP_ICON_GRADIENT, desc,
405                                      GTK_WIDGET (editor),
406                                      gimp_standard_help_func,
407                                      GIMP_HELP_GRADIENT_EDITOR_REPLICATE,
408 
409                                      _("_Cancel"),    GTK_RESPONSE_CANCEL,
410                                      _("_Replicate"), GTK_RESPONSE_OK,
411 
412                                      NULL);
413 
414   gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
415                                            GTK_RESPONSE_OK,
416                                            GTK_RESPONSE_CANCEL,
417                                            -1);
418 
419   g_signal_connect (dialog, "response",
420                     G_CALLBACK (gradient_editor_replicate_response),
421                     editor);
422 
423   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
424   gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
425   gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
426                       vbox, TRUE, TRUE, 0);
427   gtk_widget_show (vbox);
428 
429   /*  Instructions  */
430   if (left == right)
431     label = gtk_label_new (_("Select the number of times\n"
432                              "to replicate the selected segment."));
433   else
434     label = gtk_label_new (_("Select the number of times\n"
435                              "to replicate the selection."));
436 
437   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
438   gtk_widget_show (label);
439 
440   /*  Scale  */
441   scale_data = GTK_ADJUSTMENT (gtk_adjustment_new (2.0, 2.0, 21.0, 1.0, 1.0, 1.0));
442 
443   scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, scale_data);
444   gtk_scale_set_digits (GTK_SCALE (scale), 0);
445   gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
446   gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, TRUE, 4);
447   gtk_widget_show (scale);
448 
449   g_object_set_data (G_OBJECT (dialog), "adjustment", scale_data);
450 
451   gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE);
452   gimp_ui_manager_update (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)),
453                           gimp_editor_get_popup_data (GIMP_EDITOR (editor)));
454 
455   gtk_widget_show (dialog);
456 }
457 
458 void
gradient_editor_split_midpoint_cmd_callback(GimpAction * action,GVariant * value,gpointer data)459 gradient_editor_split_midpoint_cmd_callback (GimpAction *action,
460                                              GVariant   *value,
461                                              gpointer    data)
462 {
463   GimpGradientEditor  *editor      = GIMP_GRADIENT_EDITOR (data);
464   GimpDataEditor      *data_editor = GIMP_DATA_EDITOR (data);
465   GimpGradient        *gradient;
466   GimpGradientSegment *left;
467   GimpGradientSegment *right;
468 
469   gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
470 
471   gimp_gradient_segment_range_split_midpoint (gradient,
472                                               data_editor->context,
473                                               left, right,
474                                               editor->blend_color_space,
475                                               &left, &right);
476 
477   gimp_gradient_editor_set_selection (editor, left, right);
478 }
479 
480 void
gradient_editor_split_uniformly_cmd_callback(GimpAction * action,GVariant * value,gpointer data)481 gradient_editor_split_uniformly_cmd_callback (GimpAction *action,
482                                               GVariant   *value,
483                                               gpointer    data)
484 {
485   GimpGradientEditor  *editor      = GIMP_GRADIENT_EDITOR (data);
486   GimpDataEditor      *data_editor = GIMP_DATA_EDITOR (data);
487   GimpGradient        *gradient;
488   GimpGradientSegment *left;
489   GimpGradientSegment *right;
490   GtkWidget           *dialog;
491   GtkWidget           *vbox;
492   GtkWidget           *label;
493   GtkWidget           *scale;
494   GtkAdjustment       *scale_data;
495   const gchar         *title;
496   const gchar         *desc;
497 
498   gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
499 
500   if (left == right)
501     {
502       title = _("Split Segment Uniformly");
503       desc  = _("Split Gradient Segment Uniformly");
504     }
505   else
506     {
507       title = _("Split Segments Uniformly");
508       desc  = _("Split Gradient Segments Uniformly");
509     }
510 
511   dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (gradient),
512                                      data_editor->context,
513                                      title,
514                                      "gimp-gradient-segment-split-uniformly",
515                                      GIMP_ICON_GRADIENT, desc,
516                                      GTK_WIDGET (editor),
517                                      gimp_standard_help_func,
518                                      GIMP_HELP_GRADIENT_EDITOR_SPLIT_UNIFORM,
519 
520                                      _("_Cancel"), GTK_RESPONSE_CANCEL,
521                                      _("_Split"),  GTK_RESPONSE_OK,
522 
523                                      NULL);
524 
525   gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
526                                            GTK_RESPONSE_OK,
527                                            GTK_RESPONSE_CANCEL,
528                                            -1);
529 
530   g_signal_connect (dialog, "response",
531                     G_CALLBACK (gradient_editor_split_uniform_response),
532                     editor);
533 
534   /*  The main vbox  */
535   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
536   gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
537   gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
538                       vbox, TRUE, TRUE, 0);
539   gtk_widget_show (vbox);
540 
541   /*  Instructions  */
542   if (left == right)
543     label = gtk_label_new (_("Select the number of uniform parts\n"
544                              "in which to split the selected segment."));
545   else
546     label = gtk_label_new (_("Select the number of uniform parts\n"
547                              "in which to split the segments in the selection."));
548 
549   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
550   gtk_widget_show (label);
551 
552   /*  Scale  */
553   scale_data = GTK_ADJUSTMENT (gtk_adjustment_new (2.0, 2.0, 21.0, 1.0, 1.0, 1.0));
554 
555   scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, scale_data);
556   gtk_scale_set_digits (GTK_SCALE (scale), 0);
557   gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
558   gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 4);
559   gtk_widget_show (scale);
560 
561   g_object_set_data (G_OBJECT (dialog), "adjustment", scale_data);
562 
563   gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE);
564   gimp_ui_manager_update (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)),
565                           gimp_editor_get_popup_data (GIMP_EDITOR (editor)));
566 
567   gtk_widget_show (dialog);
568 }
569 
570 void
gradient_editor_delete_cmd_callback(GimpAction * action,GVariant * value,gpointer data)571 gradient_editor_delete_cmd_callback (GimpAction *action,
572                                      GVariant   *value,
573                                      gpointer    data)
574 {
575   GimpGradientEditor  *editor = GIMP_GRADIENT_EDITOR (data);
576   GimpGradient        *gradient;
577   GimpGradientSegment *left;
578   GimpGradientSegment *right;
579 
580   gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
581 
582   gimp_gradient_segment_range_delete (gradient,
583                                       left, right,
584                                       &left, &right);
585 
586   gimp_gradient_editor_set_selection (editor, left, right);
587 }
588 
589 void
gradient_editor_recenter_cmd_callback(GimpAction * action,GVariant * value,gpointer data)590 gradient_editor_recenter_cmd_callback (GimpAction *action,
591                                        GVariant   *value,
592                                        gpointer    data)
593 {
594   GimpGradientEditor  *editor = GIMP_GRADIENT_EDITOR (data);
595   GimpGradient        *gradient;
596   GimpGradientSegment *left;
597   GimpGradientSegment *right;
598 
599   gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
600 
601   gimp_gradient_segment_range_recenter_handles (gradient, left, right);
602 }
603 
604 void
gradient_editor_redistribute_cmd_callback(GimpAction * action,GVariant * value,gpointer data)605 gradient_editor_redistribute_cmd_callback (GimpAction *action,
606                                            GVariant   *value,
607                                            gpointer    data)
608 {
609   GimpGradientEditor  *editor = GIMP_GRADIENT_EDITOR (data);
610   GimpGradient        *gradient;
611   GimpGradientSegment *left;
612   GimpGradientSegment *right;
613 
614   gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
615 
616   gimp_gradient_segment_range_redistribute_handles (gradient, left, right);
617 }
618 
619 void
gradient_editor_blend_color_cmd_callback(GimpAction * action,GVariant * value,gpointer data)620 gradient_editor_blend_color_cmd_callback (GimpAction *action,
621                                           GVariant   *value,
622                                           gpointer    data)
623 {
624   GimpGradientEditor  *editor = GIMP_GRADIENT_EDITOR (data);
625   GimpGradient        *gradient;
626   GimpGradientSegment *left;
627   GimpGradientSegment *right;
628 
629   gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
630 
631   gimp_gradient_segment_range_blend (gradient, left, right,
632                                      &left->left_color,
633                                      &right->right_color,
634                                      TRUE, FALSE);
635 }
636 
637 void
gradient_editor_blend_opacity_cmd_callback(GimpAction * action,GVariant * value,gpointer data)638 gradient_editor_blend_opacity_cmd_callback (GimpAction *action,
639                                             GVariant   *value,
640                                             gpointer    data)
641 {
642   GimpGradientEditor  *editor = GIMP_GRADIENT_EDITOR (data);
643   GimpGradient        *gradient;
644   GimpGradientSegment *left;
645   GimpGradientSegment *right;
646 
647   gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
648 
649   gimp_gradient_segment_range_blend (gradient, left, right,
650                                      &left->left_color,
651                                      &right->right_color,
652                                      FALSE, TRUE);
653 }
654 
655 void
gradient_editor_zoom_cmd_callback(GimpAction * action,GVariant * value,gpointer data)656 gradient_editor_zoom_cmd_callback (GimpAction *action,
657                                    GVariant   *value,
658                                    gpointer    data)
659 {
660   GimpGradientEditor *editor    = GIMP_GRADIENT_EDITOR (data);
661   GimpZoomType        zoom_type = (GimpZoomType) g_variant_get_int32 (value);
662 
663   gimp_gradient_editor_zoom (editor, zoom_type);
664 }
665 
666 
667 /*  private functions  */
668 
669 static void
gradient_editor_split_uniform_response(GtkWidget * widget,gint response_id,GimpGradientEditor * editor)670 gradient_editor_split_uniform_response (GtkWidget          *widget,
671                                         gint                response_id,
672                                         GimpGradientEditor *editor)
673 {
674   GtkAdjustment *adjustment;
675   gint           split_parts;
676 
677   adjustment = g_object_get_data (G_OBJECT (widget), "adjustment");
678 
679   split_parts = RINT (gtk_adjustment_get_value (adjustment));
680 
681   gtk_widget_destroy (widget);
682   gtk_widget_set_sensitive (GTK_WIDGET (editor), TRUE);
683   gimp_ui_manager_update (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)),
684                           gimp_editor_get_popup_data (GIMP_EDITOR (editor)));
685 
686   if (response_id == GTK_RESPONSE_OK)
687     {
688       GimpDataEditor      *data_editor = GIMP_DATA_EDITOR (editor);
689       GimpGradient        *gradient;
690       GimpGradientSegment *left;
691       GimpGradientSegment *right;
692 
693       gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
694 
695       gimp_gradient_segment_range_split_uniform (gradient,
696                                                  data_editor->context,
697                                                  left, right,
698                                                  split_parts,
699                                                  editor->blend_color_space,
700                                                  &left, &right);
701 
702       gimp_gradient_editor_set_selection (editor, left, right);
703     }
704 }
705 
706 static void
gradient_editor_replicate_response(GtkWidget * widget,gint response_id,GimpGradientEditor * editor)707 gradient_editor_replicate_response (GtkWidget          *widget,
708                                     gint                response_id,
709                                     GimpGradientEditor *editor)
710 {
711   GtkAdjustment *adjustment;
712   gint           replicate_times;
713 
714   adjustment = g_object_get_data (G_OBJECT (widget), "adjustment");
715 
716   replicate_times = RINT (gtk_adjustment_get_value (adjustment));
717 
718   gtk_widget_destroy (widget);
719   gtk_widget_set_sensitive (GTK_WIDGET (editor), TRUE);
720   gimp_ui_manager_update (gimp_editor_get_ui_manager (GIMP_EDITOR (editor)),
721                           gimp_editor_get_popup_data (GIMP_EDITOR (editor)));
722 
723   if (response_id == GTK_RESPONSE_OK)
724     {
725       GimpGradient        *gradient;
726       GimpGradientSegment *left;
727       GimpGradientSegment *right;
728 
729       gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
730 
731       gimp_gradient_segment_range_replicate (gradient,
732                                              left, right,
733                                              replicate_times,
734                                              &left, &right);
735 
736       gimp_gradient_editor_set_selection (editor, left, right);
737     }
738 }
739