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 "display-types.h"
24 
25 #include "config/gimpdisplayoptions.h"
26 
27 #include "core/gimpimage.h"
28 
29 #include "widgets/gimpdockcolumns.h"
30 #include "widgets/gimprender.h"
31 #include "widgets/gimpwidgets-utils.h"
32 
33 #include "gimpcanvas.h"
34 #include "gimpcanvasitem.h"
35 #include "gimpdisplay.h"
36 #include "gimpdisplayshell.h"
37 #include "gimpdisplayshell-actions.h"
38 #include "gimpdisplayshell-appearance.h"
39 #include "gimpdisplayshell-expose.h"
40 #include "gimpdisplayshell-selection.h"
41 #include "gimpdisplayshell-scroll.h"
42 #include "gimpdisplayshell-scrollbars.h"
43 #include "gimpimagewindow.h"
44 #include "gimpstatusbar.h"
45 
46 
47 /*  local function prototypes  */
48 
49 static GimpDisplayOptions * appearance_get_options (GimpDisplayShell *shell);
50 
51 
52 /*  public functions  */
53 
54 void
gimp_display_shell_appearance_update(GimpDisplayShell * shell)55 gimp_display_shell_appearance_update (GimpDisplayShell *shell)
56 {
57   GimpDisplayOptions *options;
58   GimpImageWindow    *window;
59 
60   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
61 
62   options = appearance_get_options (shell);
63   window  = gimp_display_shell_get_window (shell);
64 
65   if (window)
66     {
67       GimpDockColumns *left_docks;
68       GimpDockColumns *right_docks;
69       gboolean         fullscreen;
70       gboolean         has_grip;
71 
72       fullscreen = gimp_image_window_get_fullscreen (window);
73 
74       gimp_display_shell_set_action_active (shell, "view-fullscreen",
75                                             fullscreen);
76 
77       left_docks  = gimp_image_window_get_left_docks (window);
78       right_docks = gimp_image_window_get_right_docks (window);
79 
80       has_grip = (! fullscreen &&
81                   ! (left_docks  && gimp_dock_columns_get_docks (left_docks)) &&
82                   ! (right_docks && gimp_dock_columns_get_docks (right_docks)));
83 
84       gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (shell->statusbar),
85                                          has_grip);
86     }
87 
88   gimp_display_shell_set_show_menubar        (shell,
89                                               options->show_menubar);
90   gimp_display_shell_set_show_statusbar      (shell,
91                                               options->show_statusbar);
92 
93   gimp_display_shell_set_show_rulers         (shell,
94                                               options->show_rulers);
95   gimp_display_shell_set_show_scrollbars     (shell,
96                                               options->show_scrollbars);
97   gimp_display_shell_set_show_selection      (shell,
98                                               options->show_selection);
99   gimp_display_shell_set_show_layer          (shell,
100                                               options->show_layer_boundary);
101   gimp_display_shell_set_show_canvas         (shell,
102                                               options->show_canvas_boundary);
103   gimp_display_shell_set_show_guides         (shell,
104                                               options->show_guides);
105   gimp_display_shell_set_show_grid           (shell,
106                                               options->show_grid);
107   gimp_display_shell_set_show_sample_points  (shell,
108                                               options->show_sample_points);
109   gimp_display_shell_set_padding             (shell,
110                                               options->padding_mode,
111                                               &options->padding_color);
112   gimp_display_shell_set_padding_in_show_all (shell,
113                                               options->padding_in_show_all);
114 }
115 
116 void
gimp_display_shell_set_show_menubar(GimpDisplayShell * shell,gboolean show)117 gimp_display_shell_set_show_menubar (GimpDisplayShell *shell,
118                                      gboolean          show)
119 {
120   GimpDisplayOptions *options;
121   GimpImageWindow    *window;
122 
123   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
124 
125   options = appearance_get_options (shell);
126   window  = gimp_display_shell_get_window (shell);
127 
128   g_object_set (options, "show-menubar", show, NULL);
129 
130   if (window && gimp_image_window_get_active_shell (window) == shell)
131     {
132       gimp_image_window_keep_canvas_pos (gimp_display_shell_get_window (shell));
133       gimp_image_window_set_show_menubar (window, show);
134     }
135 
136   gimp_display_shell_set_action_active (shell, "view-show-menubar", show);
137 }
138 
139 gboolean
gimp_display_shell_get_show_menubar(GimpDisplayShell * shell)140 gimp_display_shell_get_show_menubar (GimpDisplayShell *shell)
141 {
142   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
143 
144   return appearance_get_options (shell)->show_menubar;
145 }
146 
147 void
gimp_display_shell_set_show_statusbar(GimpDisplayShell * shell,gboolean show)148 gimp_display_shell_set_show_statusbar (GimpDisplayShell *shell,
149                                        gboolean          show)
150 {
151   GimpDisplayOptions *options;
152 
153   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
154 
155   options = appearance_get_options (shell);
156 
157   g_object_set (options, "show-statusbar", show, NULL);
158 
159   gimp_image_window_keep_canvas_pos (gimp_display_shell_get_window (shell));
160   gimp_statusbar_set_visible (GIMP_STATUSBAR (shell->statusbar), show);
161 
162   gimp_display_shell_set_action_active (shell, "view-show-statusbar", show);
163 }
164 
165 gboolean
gimp_display_shell_get_show_statusbar(GimpDisplayShell * shell)166 gimp_display_shell_get_show_statusbar (GimpDisplayShell *shell)
167 {
168   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
169 
170   return appearance_get_options (shell)->show_statusbar;
171 }
172 
173 void
gimp_display_shell_set_show_rulers(GimpDisplayShell * shell,gboolean show)174 gimp_display_shell_set_show_rulers (GimpDisplayShell *shell,
175                                     gboolean          show)
176 {
177   GimpDisplayOptions *options;
178 
179   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
180 
181   options = appearance_get_options (shell);
182 
183   g_object_set (options, "show-rulers", show, NULL);
184 
185   gimp_image_window_keep_canvas_pos (gimp_display_shell_get_window (shell));
186   gtk_widget_set_visible (shell->origin, show);
187   gtk_widget_set_visible (shell->hrule, show);
188   gtk_widget_set_visible (shell->vrule, show);
189 
190   gimp_display_shell_set_action_active (shell, "view-show-rulers", show);
191 }
192 
193 gboolean
gimp_display_shell_get_show_rulers(GimpDisplayShell * shell)194 gimp_display_shell_get_show_rulers (GimpDisplayShell *shell)
195 {
196   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
197 
198   return appearance_get_options (shell)->show_rulers;
199 }
200 
201 void
gimp_display_shell_set_show_scrollbars(GimpDisplayShell * shell,gboolean show)202 gimp_display_shell_set_show_scrollbars (GimpDisplayShell *shell,
203                                         gboolean          show)
204 {
205   GimpDisplayOptions *options;
206 
207   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
208 
209   options = appearance_get_options (shell);
210 
211   g_object_set (options, "show-scrollbars", show, NULL);
212 
213   gimp_image_window_keep_canvas_pos (gimp_display_shell_get_window (shell));
214   gtk_widget_set_visible (shell->nav_ebox, show);
215   gtk_widget_set_visible (shell->hsb, show);
216   gtk_widget_set_visible (shell->vsb, show);
217   gtk_widget_set_visible (shell->quick_mask_button, show);
218   gtk_widget_set_visible (shell->zoom_button, show);
219 
220   gimp_display_shell_set_action_active (shell, "view-show-scrollbars", show);
221 }
222 
223 gboolean
gimp_display_shell_get_show_scrollbars(GimpDisplayShell * shell)224 gimp_display_shell_get_show_scrollbars (GimpDisplayShell *shell)
225 {
226   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
227 
228   return appearance_get_options (shell)->show_scrollbars;
229 }
230 
231 void
gimp_display_shell_set_show_selection(GimpDisplayShell * shell,gboolean show)232 gimp_display_shell_set_show_selection (GimpDisplayShell *shell,
233                                        gboolean          show)
234 {
235   GimpDisplayOptions *options;
236 
237   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
238 
239   options = appearance_get_options (shell);
240 
241   g_object_set (options, "show-selection", show, NULL);
242 
243   gimp_display_shell_selection_set_show (shell, show);
244 
245   gimp_display_shell_set_action_active (shell, "view-show-selection", show);
246 }
247 
248 gboolean
gimp_display_shell_get_show_selection(GimpDisplayShell * shell)249 gimp_display_shell_get_show_selection (GimpDisplayShell *shell)
250 {
251   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
252 
253   return appearance_get_options (shell)->show_selection;
254 }
255 
256 void
gimp_display_shell_set_show_layer(GimpDisplayShell * shell,gboolean show)257 gimp_display_shell_set_show_layer (GimpDisplayShell *shell,
258                                    gboolean          show)
259 {
260   GimpDisplayOptions *options;
261 
262   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
263 
264   options = appearance_get_options (shell);
265 
266   g_object_set (options, "show-layer-boundary", show, NULL);
267 
268   gimp_canvas_item_set_visible (shell->layer_boundary, show);
269 
270   gimp_display_shell_set_action_active (shell, "view-show-layer-boundary", show);
271 }
272 
273 gboolean
gimp_display_shell_get_show_layer(GimpDisplayShell * shell)274 gimp_display_shell_get_show_layer (GimpDisplayShell *shell)
275 {
276   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
277 
278   return appearance_get_options (shell)->show_layer_boundary;
279 }
280 
281 void
gimp_display_shell_set_show_canvas(GimpDisplayShell * shell,gboolean show)282 gimp_display_shell_set_show_canvas (GimpDisplayShell *shell,
283                                     gboolean          show)
284 {
285   GimpDisplayOptions *options;
286 
287   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
288 
289   options = appearance_get_options (shell);
290 
291   g_object_set (options, "show-canvas-boundary", show, NULL);
292 
293   gimp_canvas_item_set_visible (shell->canvas_boundary,
294                                 show && shell->show_all);
295 
296   gimp_display_shell_set_action_active (shell, "view-show-canvas-boundary", show);
297 }
298 
299 gboolean
gimp_display_shell_get_show_canvas(GimpDisplayShell * shell)300 gimp_display_shell_get_show_canvas (GimpDisplayShell *shell)
301 {
302   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
303 
304   return appearance_get_options (shell)->show_canvas_boundary;
305 }
306 
307 void
gimp_display_shell_update_show_canvas(GimpDisplayShell * shell)308 gimp_display_shell_update_show_canvas (GimpDisplayShell *shell)
309 {
310   GimpDisplayOptions *options;
311 
312   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
313 
314   options = appearance_get_options (shell);
315 
316   gimp_canvas_item_set_visible (shell->canvas_boundary,
317                                 options->show_canvas_boundary &&
318                                 shell->show_all);
319 }
320 
321 void
gimp_display_shell_set_show_guides(GimpDisplayShell * shell,gboolean show)322 gimp_display_shell_set_show_guides (GimpDisplayShell *shell,
323                                     gboolean          show)
324 {
325   GimpDisplayOptions *options;
326 
327   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
328 
329   options = appearance_get_options (shell);
330 
331   g_object_set (options, "show-guides", show, NULL);
332 
333   gimp_canvas_item_set_visible (shell->guides, show);
334 
335   gimp_display_shell_set_action_active (shell, "view-show-guides", show);
336 }
337 
338 gboolean
gimp_display_shell_get_show_guides(GimpDisplayShell * shell)339 gimp_display_shell_get_show_guides (GimpDisplayShell *shell)
340 {
341   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
342 
343   return appearance_get_options (shell)->show_guides;
344 }
345 
346 void
gimp_display_shell_set_show_grid(GimpDisplayShell * shell,gboolean show)347 gimp_display_shell_set_show_grid (GimpDisplayShell *shell,
348                                   gboolean          show)
349 {
350   GimpDisplayOptions *options;
351 
352   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
353 
354   options = appearance_get_options (shell);
355 
356   g_object_set (options, "show-grid", show, NULL);
357 
358   gimp_canvas_item_set_visible (shell->grid, show);
359 
360   gimp_display_shell_set_action_active (shell, "view-show-grid", show);
361 }
362 
363 gboolean
gimp_display_shell_get_show_grid(GimpDisplayShell * shell)364 gimp_display_shell_get_show_grid (GimpDisplayShell *shell)
365 {
366   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
367 
368   return appearance_get_options (shell)->show_grid;
369 }
370 
371 void
gimp_display_shell_set_show_sample_points(GimpDisplayShell * shell,gboolean show)372 gimp_display_shell_set_show_sample_points (GimpDisplayShell *shell,
373                                            gboolean          show)
374 {
375   GimpDisplayOptions *options;
376 
377   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
378 
379   options = appearance_get_options (shell);
380 
381   g_object_set (options, "show-sample-points", show, NULL);
382 
383   gimp_canvas_item_set_visible (shell->sample_points, show);
384 
385   gimp_display_shell_set_action_active (shell, "view-show-sample-points", show);
386 }
387 
388 gboolean
gimp_display_shell_get_show_sample_points(GimpDisplayShell * shell)389 gimp_display_shell_get_show_sample_points (GimpDisplayShell *shell)
390 {
391   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
392 
393   return appearance_get_options (shell)->show_sample_points;
394 }
395 
396 void
gimp_display_shell_set_snap_to_grid(GimpDisplayShell * shell,gboolean snap)397 gimp_display_shell_set_snap_to_grid (GimpDisplayShell *shell,
398                                      gboolean          snap)
399 {
400   GimpDisplayOptions *options;
401 
402   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
403 
404   options = appearance_get_options (shell);
405 
406   g_object_set (options, "snap-to-grid", snap, NULL);
407 }
408 
409 gboolean
gimp_display_shell_get_snap_to_grid(GimpDisplayShell * shell)410 gimp_display_shell_get_snap_to_grid (GimpDisplayShell *shell)
411 {
412   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
413 
414   return appearance_get_options (shell)->snap_to_grid;
415 }
416 
417 void
gimp_display_shell_set_snap_to_guides(GimpDisplayShell * shell,gboolean snap)418 gimp_display_shell_set_snap_to_guides (GimpDisplayShell *shell,
419                                        gboolean          snap)
420 {
421   GimpDisplayOptions *options;
422 
423   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
424 
425   options = appearance_get_options (shell);
426 
427   g_object_set (options, "snap-to-guides", snap, NULL);
428 }
429 
430 gboolean
gimp_display_shell_get_snap_to_guides(GimpDisplayShell * shell)431 gimp_display_shell_get_snap_to_guides (GimpDisplayShell *shell)
432 {
433   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
434 
435   return appearance_get_options (shell)->snap_to_guides;
436 }
437 
438 void
gimp_display_shell_set_snap_to_canvas(GimpDisplayShell * shell,gboolean snap)439 gimp_display_shell_set_snap_to_canvas (GimpDisplayShell *shell,
440                                        gboolean          snap)
441 {
442   GimpDisplayOptions *options;
443 
444   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
445 
446   options = appearance_get_options (shell);
447 
448   g_object_set (options, "snap-to-canvas", snap, NULL);
449 }
450 
451 gboolean
gimp_display_shell_get_snap_to_canvas(GimpDisplayShell * shell)452 gimp_display_shell_get_snap_to_canvas (GimpDisplayShell *shell)
453 {
454   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
455 
456   return appearance_get_options (shell)->snap_to_canvas;
457 }
458 
459 void
gimp_display_shell_set_snap_to_vectors(GimpDisplayShell * shell,gboolean snap)460 gimp_display_shell_set_snap_to_vectors (GimpDisplayShell *shell,
461                                         gboolean          snap)
462 {
463   GimpDisplayOptions *options;
464 
465   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
466 
467   options = appearance_get_options (shell);
468 
469   g_object_set (options, "snap-to-path", snap, NULL);
470 }
471 
472 gboolean
gimp_display_shell_get_snap_to_vectors(GimpDisplayShell * shell)473 gimp_display_shell_get_snap_to_vectors (GimpDisplayShell *shell)
474 {
475   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
476 
477   return appearance_get_options (shell)->snap_to_path;
478 }
479 
480 void
gimp_display_shell_set_padding(GimpDisplayShell * shell,GimpCanvasPaddingMode padding_mode,const GimpRGB * padding_color)481 gimp_display_shell_set_padding (GimpDisplayShell      *shell,
482                                 GimpCanvasPaddingMode  padding_mode,
483                                 const GimpRGB         *padding_color)
484 {
485   GimpDisplayOptions *options;
486   GimpRGB             color;
487 
488   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
489   g_return_if_fail (padding_color != NULL);
490 
491   options = appearance_get_options (shell);
492   color   = *padding_color;
493 
494   switch (padding_mode)
495     {
496     case GIMP_CANVAS_PADDING_MODE_DEFAULT:
497       if (shell->canvas)
498         {
499           GtkStyle *style;
500 
501           gtk_widget_ensure_style (shell->canvas);
502 
503           style = gtk_widget_get_style (shell->canvas);
504 
505           gimp_rgb_set_gdk_color (&color, style->bg + GTK_STATE_NORMAL);
506         }
507       break;
508 
509     case GIMP_CANVAS_PADDING_MODE_LIGHT_CHECK:
510       color = *gimp_render_light_check_color ();
511       break;
512 
513     case GIMP_CANVAS_PADDING_MODE_DARK_CHECK:
514       color = *gimp_render_dark_check_color ();
515       break;
516 
517     case GIMP_CANVAS_PADDING_MODE_CUSTOM:
518     case GIMP_CANVAS_PADDING_MODE_RESET:
519       break;
520     }
521 
522   g_object_set (options,
523                 "padding-mode",  padding_mode,
524                 "padding-color", &color,
525                 NULL);
526 
527   gimp_canvas_set_bg_color (GIMP_CANVAS (shell->canvas), &color);
528 
529   gimp_display_shell_set_action_color (shell, "view-padding-color-menu",
530                                        &options->padding_color);
531 }
532 
533 void
gimp_display_shell_get_padding(GimpDisplayShell * shell,GimpCanvasPaddingMode * padding_mode,GimpRGB * padding_color)534 gimp_display_shell_get_padding (GimpDisplayShell       *shell,
535                                 GimpCanvasPaddingMode  *padding_mode,
536                                 GimpRGB                *padding_color)
537 {
538   GimpDisplayOptions *options;
539 
540   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
541 
542   options = appearance_get_options (shell);
543 
544   if (padding_mode)
545     *padding_mode = options->padding_mode;
546 
547   if (padding_color)
548     *padding_color = options->padding_color;
549 }
550 
551 void
gimp_display_shell_set_padding_in_show_all(GimpDisplayShell * shell,gboolean keep)552 gimp_display_shell_set_padding_in_show_all (GimpDisplayShell *shell,
553                                             gboolean          keep)
554 {
555   GimpDisplayOptions *options;
556 
557   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
558 
559   options = appearance_get_options (shell);
560 
561   if (options->padding_in_show_all != keep)
562     {
563       g_object_set (options, "padding-in-show-all", keep, NULL);
564 
565       if (shell->display)
566         {
567           gimp_display_shell_scroll_clamp_and_update (shell);
568           gimp_display_shell_scrollbars_update (shell);
569 
570           gimp_display_shell_expose_full (shell);
571         }
572 
573       gimp_display_shell_set_action_active (shell,
574                                             "view-padding-color-in-show-all",
575                                             keep);
576 
577       g_object_notify (G_OBJECT (shell), "infinite-canvas");
578     }
579 }
580 
581 gboolean
gimp_display_shell_get_padding_in_show_all(GimpDisplayShell * shell)582 gimp_display_shell_get_padding_in_show_all (GimpDisplayShell *shell)
583 {
584   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
585 
586   return appearance_get_options (shell)->padding_in_show_all;
587 }
588 
589 
590 /*  private functions  */
591 
592 static GimpDisplayOptions *
appearance_get_options(GimpDisplayShell * shell)593 appearance_get_options (GimpDisplayShell *shell)
594 {
595   if (gimp_display_get_image (shell->display))
596     {
597       GimpImageWindow *window = gimp_display_shell_get_window (shell);
598 
599       if (window && gimp_image_window_get_fullscreen (window))
600         return shell->fullscreen_options;
601       else
602         return shell->options;
603     }
604 
605   return shell->no_image_options;
606 }
607