diff --git a/app/actions/view-actions.c b/app/actions/view-actions.c index 9cd102f874..6e86605f8a 100644 --- a/app/actions/view-actions.c +++ b/app/actions/view-actions.c @@ -238,6 +238,13 @@ static const GimpToggleActionEntry view_toggle_actions[] = TRUE, GIMP_HELP_VIEW_SHOW_LAYER_BOUNDARY }, + { "view-show-canvas-boundary", NULL, + NC_("view-action", "Show Canvas Bounda_ry"), NULL, + NC_("view-action", "Draw a border around the canvas"), + view_toggle_canvas_boundary_cmd_callback, + TRUE, + GIMP_HELP_VIEW_SHOW_CANVAS_BOUNDARY }, + { "view-show-guides", NULL, NC_("view-action", "Show _Guides"), "T", NC_("view-action", "Display the image's guides"), @@ -1005,25 +1012,27 @@ view_actions_update (GimpActionGroup *group, SET_ACTIVE ("view-softproof-gamut-check", gammut); SET_SENSITIVE ("view-color-management-reset", image); - SET_SENSITIVE ("view-show-selection", image); - SET_ACTIVE ("view-show-selection", display && options->show_selection); - SET_SENSITIVE ("view-show-layer-boundary", image); - SET_ACTIVE ("view-show-layer-boundary", display && options->show_layer_boundary); - SET_SENSITIVE ("view-show-guides", image); - SET_ACTIVE ("view-show-guides", display && options->show_guides); - SET_SENSITIVE ("view-show-grid", image); - SET_ACTIVE ("view-show-grid", display && options->show_grid); - SET_SENSITIVE ("view-show-sample-points", image); - SET_ACTIVE ("view-show-sample-points", display && options->show_sample_points); + SET_SENSITIVE ("view-show-selection", image); + SET_ACTIVE ("view-show-selection", display && options->show_selection); + SET_SENSITIVE ("view-show-layer-boundary", image); + SET_ACTIVE ("view-show-layer-boundary", display && options->show_layer_boundary); + SET_SENSITIVE ("view-show-canvas-boundary", image); + SET_ACTIVE ("view-show-canvas-boundary", display && options->show_canvas_boundary); + SET_SENSITIVE ("view-show-guides", image); + SET_ACTIVE ("view-show-guides", display && options->show_guides); + SET_SENSITIVE ("view-show-grid", image); + SET_ACTIVE ("view-show-grid", display && options->show_grid); + SET_SENSITIVE ("view-show-sample-points", image); + SET_ACTIVE ("view-show-sample-points", display && options->show_sample_points); - SET_SENSITIVE ("view-snap-to-guides", image); - SET_ACTIVE ("view-snap-to-guides", display && options->snap_to_guides); - SET_SENSITIVE ("view-snap-to-grid", image); - SET_ACTIVE ("view-snap-to-grid", display && options->snap_to_grid); - SET_SENSITIVE ("view-snap-to-canvas", image); - SET_ACTIVE ("view-snap-to-canvas", display && options->snap_to_canvas); - SET_SENSITIVE ("view-snap-to-vectors", image); - SET_ACTIVE ("view-snap-to-vectors", display && options->snap_to_path); + SET_SENSITIVE ("view-snap-to-guides", image); + SET_ACTIVE ("view-snap-to-guides", display && options->snap_to_guides); + SET_SENSITIVE ("view-snap-to-grid", image); + SET_ACTIVE ("view-snap-to-grid", display && options->snap_to_grid); + SET_SENSITIVE ("view-snap-to-canvas", image); + SET_ACTIVE ("view-snap-to-canvas", display && options->snap_to_canvas); + SET_SENSITIVE ("view-snap-to-vectors", image); + SET_ACTIVE ("view-snap-to-vectors", display && options->snap_to_path); SET_SENSITIVE ("view-padding-color-theme", image); SET_SENSITIVE ("view-padding-color-light-check", image); diff --git a/app/actions/view-commands.c b/app/actions/view-commands.c index 1f8749b4d2..634bfc1410 100644 --- a/app/actions/view-commands.c +++ b/app/actions/view-commands.c @@ -858,6 +858,23 @@ view_toggle_layer_boundary_cmd_callback (GimpAction *action, } } +void +view_toggle_canvas_boundary_cmd_callback (GimpAction *action, + GVariant *value, + gpointer data) +{ + GimpDisplayShell *shell; + gboolean active; + return_if_no_shell (shell, data); + + active = g_variant_get_boolean (value); + + if (active != gimp_display_shell_get_show_canvas (shell)) + { + gimp_display_shell_set_show_canvas (shell, active); + } +} + void view_toggle_menubar_cmd_callback (GimpAction *action, GVariant *value, diff --git a/app/actions/view-commands.h b/app/actions/view-commands.h index c28a24ef2e..8afbba7527 100644 --- a/app/actions/view-commands.h +++ b/app/actions/view-commands.h @@ -126,6 +126,9 @@ void view_toggle_selection_cmd_callback (GimpAction *action, void view_toggle_layer_boundary_cmd_callback (GimpAction *action, GVariant *value, gpointer data); +void view_toggle_canvas_boundary_cmd_callback (GimpAction *action, + GVariant *value, + gpointer data); void view_toggle_menubar_cmd_callback (GimpAction *action, GVariant *value, gpointer data); diff --git a/app/config/gimpdisplayoptions.c b/app/config/gimpdisplayoptions.c index 9e5a316c16..201ff0bf0c 100644 --- a/app/config/gimpdisplayoptions.c +++ b/app/config/gimpdisplayoptions.c @@ -47,6 +47,7 @@ enum PROP_SHOW_SCROLLBARS, PROP_SHOW_SELECTION, PROP_SHOW_LAYER_BOUNDARY, + PROP_SHOW_CANVAS_BOUNDARY, PROP_SHOW_GUIDES, PROP_SHOW_GRID, PROP_SHOW_SAMPLE_POINTS, @@ -148,6 +149,13 @@ gimp_display_options_class_init (GimpDisplayOptionsClass *klass) TRUE, GIMP_PARAM_STATIC_STRINGS); + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_CANVAS_BOUNDARY, + "show-canvas-boundary", + "Show canvas boundary", + SHOW_CANVAS_BOUNDARY_BLURB, + TRUE, + GIMP_PARAM_STATIC_STRINGS); + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_GUIDES, "show-guides", "Show guides", @@ -266,6 +274,13 @@ gimp_display_options_fullscreen_class_init (GimpDisplayOptionsFullscreenClass *k FALSE, GIMP_PARAM_STATIC_STRINGS); + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_CANVAS_BOUNDARY, + "show-canvas-boundary", + "Show canvas boundary", + SHOW_CANVAS_BOUNDARY_BLURB, + FALSE, + GIMP_PARAM_STATIC_STRINGS); + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_GUIDES, "show-guides", "Show guides", @@ -367,6 +382,13 @@ gimp_display_options_no_image_class_init (GimpDisplayOptionsNoImageClass *klass) FALSE, GIMP_PARAM_STATIC_STRINGS); + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_CANVAS_BOUNDARY, + "show-canvas-boundary", + "Show canvas boundary", + SHOW_CANVAS_BOUNDARY_BLURB, + FALSE, + GIMP_PARAM_STATIC_STRINGS); + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_GUIDES, "show-guides", "Show guides", @@ -451,6 +473,9 @@ gimp_display_options_set_property (GObject *object, case PROP_SHOW_LAYER_BOUNDARY: options->show_layer_boundary = g_value_get_boolean (value); break; + case PROP_SHOW_CANVAS_BOUNDARY: + options->show_canvas_boundary = g_value_get_boolean (value); + break; case PROP_SHOW_GUIDES: options->show_guides = g_value_get_boolean (value); break; @@ -513,6 +538,9 @@ gimp_display_options_get_property (GObject *object, case PROP_SHOW_LAYER_BOUNDARY: g_value_set_boolean (value, options->show_layer_boundary); break; + case PROP_SHOW_CANVAS_BOUNDARY: + g_value_set_boolean (value, options->show_canvas_boundary); + break; case PROP_SHOW_GUIDES: g_value_set_boolean (value, options->show_guides); break; diff --git a/app/config/gimpdisplayoptions.h b/app/config/gimpdisplayoptions.h index d04baa7bd1..5d666f7891 100644 --- a/app/config/gimpdisplayoptions.h +++ b/app/config/gimpdisplayoptions.h @@ -48,6 +48,7 @@ struct _GimpDisplayOptions gboolean show_scrollbars; gboolean show_selection; gboolean show_layer_boundary; + gboolean show_canvas_boundary; gboolean show_guides; gboolean show_grid; gboolean show_sample_points; diff --git a/app/config/gimprc-blurbs.h b/app/config/gimprc-blurbs.h index 5b1178237f..2b3adf7a2e 100644 --- a/app/config/gimprc-blurbs.h +++ b/app/config/gimprc-blurbs.h @@ -406,6 +406,10 @@ _("When enabled, the selection is visible by default. This can also be " \ _("When enabled, the layer boundary is visible by default. This can also " \ "be toggled with the \"View->Show Layer Boundary\" command.") +#define SHOW_CANVAS_BOUNDARY_BLURB \ +_("When enabled, the canvas boundary is visible by default. This can also " \ + "be toggled with the \"View->Show Canvas Boundary\" command.") + #define SHOW_GUIDES_BLURB \ _("When enabled, the guides are visible by default. This can also be " \ "toggled with the \"View->Show Guides\" command.") diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c index 7f34d81fde..6da91070cf 100644 --- a/app/dialogs/preferences-dialog.c +++ b/app/dialogs/preferences-dialog.c @@ -963,6 +963,9 @@ prefs_display_options_frame_add (Gimp *gimp, prefs_check_button_add (object, "show-layer-boundary", _("Show _layer boundary"), GTK_BOX (checks_vbox)); + prefs_check_button_add (object, "show-canvas-boundary", + _("Show can_vas boundary"), + GTK_BOX (checks_vbox)); prefs_check_button_add (object, "show-guides", _("Show _guides"), GTK_BOX (checks_vbox)); diff --git a/app/display/Makefile.am b/app/display/Makefile.am index eda865265d..f5585917bf 100644 --- a/app/display/Makefile.am +++ b/app/display/Makefile.am @@ -40,6 +40,8 @@ libappdisplay_a_sources = \ gimpcanvasboundary.h \ gimpcanvasbufferpreview.c \ gimpcanvasbufferpreview.h \ + gimpcanvascanvasboundary.c \ + gimpcanvascanvasboundary.h \ gimpcanvascorner.c \ gimpcanvascorner.h \ gimpcanvascursor.c \ diff --git a/app/display/gimpcanvas-style.c b/app/display/gimpcanvas-style.c index 3baed36c82..8d479618fd 100644 --- a/app/display/gimpcanvas-style.c +++ b/app/display/gimpcanvas-style.c @@ -68,6 +68,9 @@ static const GimpRGB layer_group_bg = { 0.0, 1.0, 1.0, 1.0 }; static const GimpRGB layer_mask_fg = { 0.0, 0.0, 0.0, 1.0 }; static const GimpRGB layer_mask_bg = { 0.0, 1.0, 0.0, 1.0 }; +static const GimpRGB canvas_fg = { 0.0, 0.0, 0.0, 1.0 }; +static const GimpRGB canvas_bg = { 1.0, 0.5, 0.0, 1.0 }; + static const GimpRGB selection_out_fg = { 1.0, 1.0, 1.0, 1.0 }; static const GimpRGB selection_out_bg = { 0.5, 0.5, 0.5, 1.0 }; @@ -290,6 +293,29 @@ gimp_canvas_set_layer_style (GtkWidget *canvas, cairo_pattern_destroy (pattern); } +void +gimp_canvas_set_canvas_style (GtkWidget *canvas, + cairo_t *cr, + gdouble offset_x, + gdouble offset_y) +{ + cairo_pattern_t *pattern; + + g_return_if_fail (GTK_IS_WIDGET (canvas)); + g_return_if_fail (cr != NULL); + + cairo_set_line_width (cr, 1.0); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); + + pattern = gimp_cairo_pattern_create_stipple (&canvas_fg, + &canvas_bg, + 0, + offset_x, offset_y); + + cairo_set_source (cr, pattern); + cairo_pattern_destroy (pattern); +} + void gimp_canvas_set_selection_out_style (GtkWidget *canvas, cairo_t *cr, diff --git a/app/display/gimpcanvas-style.h b/app/display/gimpcanvas-style.h index 85d35078b9..3a37b988b8 100644 --- a/app/display/gimpcanvas-style.h +++ b/app/display/gimpcanvas-style.h @@ -45,6 +45,10 @@ void gimp_canvas_set_layer_style (GtkWidget *canvas, GimpLayer *layer, gdouble offset_x, gdouble offset_y); +void gimp_canvas_set_canvas_style (GtkWidget *canvas, + cairo_t *cr, + gdouble offset_x, + gdouble offset_y); void gimp_canvas_set_selection_out_style (GtkWidget *canvas, cairo_t *cr, gdouble offset_x, diff --git a/app/display/gimpcanvascanvasboundary.c b/app/display/gimpcanvascanvasboundary.c new file mode 100644 index 0000000000..01ac5a35f1 --- /dev/null +++ b/app/display/gimpcanvascanvasboundary.c @@ -0,0 +1,270 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpcanvascanvasboundary.c + * Copyright (C) 2019 Ell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include +#include + +#include "libgimpbase/gimpbase.h" +#include "libgimpmath/gimpmath.h" + +#include "display-types.h" + +#include "core/gimpimage.h" + +#include "gimpcanvas-style.h" +#include "gimpcanvascanvasboundary.h" +#include "gimpdisplayshell.h" + + +enum +{ + PROP_0, + PROP_IMAGE +}; + + +typedef struct _GimpCanvasCanvasBoundaryPrivate GimpCanvasCanvasBoundaryPrivate; + +struct _GimpCanvasCanvasBoundaryPrivate +{ + GimpImage *image; +}; + +#define GET_PRIVATE(canvas_boundary) \ + ((GimpCanvasCanvasBoundaryPrivate *) gimp_canvas_canvas_boundary_get_instance_private ((GimpCanvasCanvasBoundary *) (canvas_boundary))) + + +/* local function prototypes */ + +static void gimp_canvas_canvas_boundary_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_canvas_canvas_boundary_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +static void gimp_canvas_canvas_boundary_finalize (GObject *object); +static void gimp_canvas_canvas_boundary_draw (GimpCanvasItem *item, + cairo_t *cr); +static cairo_region_t * gimp_canvas_canvas_boundary_get_extents (GimpCanvasItem *item); +static void gimp_canvas_canvas_boundary_stroke (GimpCanvasItem *item, + cairo_t *cr); + + +G_DEFINE_TYPE_WITH_PRIVATE (GimpCanvasCanvasBoundary, gimp_canvas_canvas_boundary, + GIMP_TYPE_CANVAS_RECTANGLE) + +#define parent_class gimp_canvas_canvas_boundary_parent_class + + +static void +gimp_canvas_canvas_boundary_class_init (GimpCanvasCanvasBoundaryClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GimpCanvasItemClass *item_class = GIMP_CANVAS_ITEM_CLASS (klass); + + object_class->set_property = gimp_canvas_canvas_boundary_set_property; + object_class->get_property = gimp_canvas_canvas_boundary_get_property; + object_class->finalize = gimp_canvas_canvas_boundary_finalize; + + item_class->draw = gimp_canvas_canvas_boundary_draw; + item_class->get_extents = gimp_canvas_canvas_boundary_get_extents; + item_class->stroke = gimp_canvas_canvas_boundary_stroke; + + g_object_class_install_property (object_class, PROP_IMAGE, + g_param_spec_object ("image", NULL, NULL, + GIMP_TYPE_IMAGE, + GIMP_PARAM_READWRITE)); +} + +static void +gimp_canvas_canvas_boundary_init (GimpCanvasCanvasBoundary *canvas_boundary) +{ +} + +static void +gimp_canvas_canvas_boundary_finalize (GObject *object) +{ + GimpCanvasCanvasBoundaryPrivate *private = GET_PRIVATE (object); + + if (private->image) + g_object_remove_weak_pointer (G_OBJECT (private->image), + (gpointer) &private->image); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gimp_canvas_canvas_boundary_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpCanvasCanvasBoundaryPrivate *private = GET_PRIVATE (object); + + switch (property_id) + { + case PROP_IMAGE: + if (private->image) + g_object_remove_weak_pointer (G_OBJECT (private->image), + (gpointer) &private->image); + private->image = g_value_get_object (value); /* don't ref */ + if (private->image) + g_object_add_weak_pointer (G_OBJECT (private->image), + (gpointer) &private->image); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_canvas_canvas_boundary_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpCanvasCanvasBoundaryPrivate *private = GET_PRIVATE (object); + + switch (property_id) + { + case PROP_IMAGE: + g_value_set_object (value, private->image); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_canvas_canvas_boundary_draw (GimpCanvasItem *item, + cairo_t *cr) +{ + GimpCanvasCanvasBoundaryPrivate *private = GET_PRIVATE (item); + + if (private->image) + GIMP_CANVAS_ITEM_CLASS (parent_class)->draw (item, cr); +} + +static cairo_region_t * +gimp_canvas_canvas_boundary_get_extents (GimpCanvasItem *item) +{ + GimpCanvasCanvasBoundaryPrivate *private = GET_PRIVATE (item); + + if (private->image) + return GIMP_CANVAS_ITEM_CLASS (parent_class)->get_extents (item); + + return NULL; +} + +static void +gimp_canvas_canvas_boundary_stroke (GimpCanvasItem *item, + cairo_t *cr) +{ + GimpDisplayShell *shell = gimp_canvas_item_get_shell (item); + + gimp_canvas_set_canvas_style (gimp_canvas_item_get_canvas (item), cr, + shell->offset_x, shell->offset_y); + cairo_stroke (cr); +} + +GimpCanvasItem * +gimp_canvas_canvas_boundary_new (GimpDisplayShell *shell) +{ + g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL); + + return g_object_new (GIMP_TYPE_CANVAS_CANVAS_BOUNDARY, + "shell", shell, + NULL); +} + +void +gimp_canvas_canvas_boundary_set_image (GimpCanvasCanvasBoundary *boundary, + GimpImage *image) +{ + GimpCanvasCanvasBoundaryPrivate *private; + + g_return_if_fail (GIMP_IS_CANVAS_CANVAS_BOUNDARY (boundary)); + g_return_if_fail (image == NULL || GIMP_IS_IMAGE (image)); + + private = GET_PRIVATE (boundary); + + if (image != private->image) + { + gimp_canvas_item_begin_change (GIMP_CANVAS_ITEM (boundary)); + + if (image) + { + g_object_set (boundary, + "x", (gdouble) 0, + "y", (gdouble) 0, + "width", (gdouble) gimp_image_get_width (image), + "height", (gdouble) gimp_image_get_height (image), + NULL); + } + + g_object_set (boundary, + "image", image, + NULL); + + gimp_canvas_item_end_change (GIMP_CANVAS_ITEM (boundary)); + } + else if (image && image == private->image) + { + gint lx, ly, lw, lh; + gdouble x, y, w ,h; + + lx = 0; + ly = 0; + lw = gimp_image_get_width (image); + lh = gimp_image_get_height (image); + + g_object_get (boundary, + "x", &x, + "y", &y, + "width", &w, + "height", &h, + NULL); + + if (lx != (gint) x || + ly != (gint) y || + lw != (gint) w || + lh != (gint) h) + { + gimp_canvas_item_begin_change (GIMP_CANVAS_ITEM (boundary)); + + g_object_set (boundary, + "x", (gdouble) lx, + "y", (gdouble) ly, + "width", (gdouble) lw, + "height", (gdouble) lh, + NULL); + + gimp_canvas_item_end_change (GIMP_CANVAS_ITEM (boundary)); + } + } +} diff --git a/app/display/gimpcanvascanvasboundary.h b/app/display/gimpcanvascanvasboundary.h new file mode 100644 index 0000000000..c8fe16f79f --- /dev/null +++ b/app/display/gimpcanvascanvasboundary.h @@ -0,0 +1,58 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpcanvascanvasvboundary.h + * Copyright (C) 2019 Ell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __GIMP_CANVAS_CANVAS_BOUNDARY_H__ +#define __GIMP_CANVAS_CANVAS_BOUNDARY_H__ + + +#include "gimpcanvasrectangle.h" + + +#define GIMP_TYPE_CANVAS_CANVAS_BOUNDARY (gimp_canvas_canvas_boundary_get_type ()) +#define GIMP_CANVAS_CANVAS_BOUNDARY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CANVAS_CANVAS_BOUNDARY, GimpCanvasCanvasBoundary)) +#define GIMP_CANVAS_CANVAS_BOUNDARY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CANVAS_CANVAS_BOUNDARY, GimpCanvasCanvasBoundaryClass)) +#define GIMP_IS_CANVAS_CANVAS_BOUNDARY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CANVAS_CANVAS_BOUNDARY)) +#define GIMP_IS_CANVAS_CANVAS_BOUNDARY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CANVAS_CANVAS_BOUNDARY)) +#define GIMP_CANVAS_CANVAS_BOUNDARY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CANVAS_CANVAS_BOUNDARY, GimpCanvasCanvasBoundaryClass)) + + +typedef struct _GimpCanvasCanvasBoundary GimpCanvasCanvasBoundary; +typedef struct _GimpCanvasCanvasBoundaryClass GimpCanvasCanvasBoundaryClass; + +struct _GimpCanvasCanvasBoundary +{ + GimpCanvasRectangle parent_instance; +}; + +struct _GimpCanvasCanvasBoundaryClass +{ + GimpCanvasRectangleClass parent_class; +}; + + +GType gimp_canvas_canvas_boundary_get_type (void) G_GNUC_CONST; + +GimpCanvasItem * gimp_canvas_canvas_boundary_new (GimpDisplayShell *shell); + +void gimp_canvas_canvas_boundary_set_image (GimpCanvasCanvasBoundary *boundary, + GimpImage *image); + + +#endif /* __GIMP_CANVAS_CANVAS_BOUNDARY_H__ */ diff --git a/app/display/gimpdisplayshell-appearance.c b/app/display/gimpdisplayshell-appearance.c index 7b677c47ce..f81b506916 100644 --- a/app/display/gimpdisplayshell-appearance.c +++ b/app/display/gimpdisplayshell-appearance.c @@ -95,6 +95,8 @@ gimp_display_shell_appearance_update (GimpDisplayShell *shell) options->show_selection); gimp_display_shell_set_show_layer (shell, options->show_layer_boundary); + gimp_display_shell_set_show_canvas (shell, + options->show_canvas_boundary); gimp_display_shell_set_show_guides (shell, options->show_guides); gimp_display_shell_set_show_grid (shell, @@ -271,6 +273,46 @@ gimp_display_shell_get_show_layer (GimpDisplayShell *shell) return appearance_get_options (shell)->show_layer_boundary; } +void +gimp_display_shell_set_show_canvas (GimpDisplayShell *shell, + gboolean show) +{ + GimpDisplayOptions *options; + + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + + options = appearance_get_options (shell); + + g_object_set (options, "show-canvas-boundary", show, NULL); + + gimp_canvas_item_set_visible (shell->canvas_boundary, + show && shell->show_all); + + gimp_display_shell_set_action_active (shell, "view-show-canvas-boundary", show); +} + +gboolean +gimp_display_shell_get_show_canvas (GimpDisplayShell *shell) +{ + g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE); + + return appearance_get_options (shell)->show_canvas_boundary; +} + +void +gimp_display_shell_update_show_canvas (GimpDisplayShell *shell) +{ + GimpDisplayOptions *options; + + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + + options = appearance_get_options (shell); + + gimp_canvas_item_set_visible (shell->canvas_boundary, + options->show_canvas_boundary && + shell->show_all); +} + void gimp_display_shell_set_show_guides (GimpDisplayShell *shell, gboolean show) diff --git a/app/display/gimpdisplayshell-appearance.h b/app/display/gimpdisplayshell-appearance.h index b9ab81e548..80ceb2c945 100644 --- a/app/display/gimpdisplayshell-appearance.h +++ b/app/display/gimpdisplayshell-appearance.h @@ -45,6 +45,11 @@ void gimp_display_shell_set_show_layer (GimpDisplayShell *sh gboolean show); gboolean gimp_display_shell_get_show_layer (GimpDisplayShell *shell); +void gimp_display_shell_set_show_canvas (GimpDisplayShell *shell, + gboolean show); +gboolean gimp_display_shell_get_show_canvas (GimpDisplayShell *shell); +void gimp_display_shell_update_show_canvas (GimpDisplayShell *shell); + void gimp_display_shell_set_show_grid (GimpDisplayShell *shell, gboolean show); gboolean gimp_display_shell_get_show_grid (GimpDisplayShell *shell); diff --git a/app/display/gimpdisplayshell-handlers.c b/app/display/gimpdisplayshell-handlers.c index 9a66244c13..86b9cd45fe 100644 --- a/app/display/gimpdisplayshell-handlers.c +++ b/app/display/gimpdisplayshell-handlers.c @@ -48,6 +48,7 @@ #include "widgets/gimpwidgets-utils.h" +#include "gimpcanvascanvasboundary.h" #include "gimpcanvasguide.h" #include "gimpcanvaslayerboundary.h" #include "gimpcanvaspath.h" @@ -387,6 +388,9 @@ gimp_display_shell_connect (GimpDisplayShell *shell) gimp_canvas_layer_boundary_set_layer (GIMP_CANVAS_LAYER_BOUNDARY (shell->layer_boundary), gimp_image_get_active_layer (image)); + gimp_canvas_canvas_boundary_set_image (GIMP_CANVAS_CANVAS_BOUNDARY (shell->canvas_boundary), + image); + if (shell->show_all) { gimp_image_inc_show_all_count (image); @@ -421,6 +425,9 @@ gimp_display_shell_disconnect (GimpDisplayShell *shell) gimp_canvas_layer_boundary_set_layer (GIMP_CANVAS_LAYER_BOUNDARY (shell->layer_boundary), NULL); + gimp_canvas_canvas_boundary_set_image (GIMP_CANVAS_CANVAS_BOUNDARY (shell->canvas_boundary), + NULL); + g_signal_handlers_disconnect_by_func (color_config, gimp_display_shell_color_config_notify_handler, shell); diff --git a/app/display/gimpdisplayshell-items.c b/app/display/gimpdisplayshell-items.c index d4f5b1fa5b..caa381adde 100644 --- a/app/display/gimpdisplayshell-items.c +++ b/app/display/gimpdisplayshell-items.c @@ -27,6 +27,7 @@ #include "display-types.h" +#include "gimpcanvascanvasboundary.h" #include "gimpcanvascursor.h" #include "gimpcanvasgrid.h" #include "gimpcanvaslayerboundary.h" @@ -84,6 +85,11 @@ gimp_display_shell_items_init (GimpDisplayShell *shell) gimp_display_shell_add_item (shell, shell->sample_points); g_object_unref (shell->sample_points); + shell->canvas_boundary = gimp_canvas_canvas_boundary_new (shell); + gimp_canvas_item_set_visible (shell->canvas_boundary, FALSE); + gimp_display_shell_add_item (shell, shell->canvas_boundary); + g_object_unref (shell->canvas_boundary); + shell->layer_boundary = gimp_canvas_layer_boundary_new (shell); gimp_canvas_item_set_visible (shell->layer_boundary, FALSE); gimp_display_shell_add_item (shell, shell->layer_boundary); @@ -122,14 +128,15 @@ gimp_display_shell_items_free (GimpDisplayShell *shell) g_clear_object (&shell->canvas_item); - shell->passe_partout = NULL; - shell->preview_items = NULL; - shell->vectors = NULL; - shell->grid = NULL; - shell->guides = NULL; - shell->sample_points = NULL; - shell->layer_boundary = NULL; - shell->tool_items = NULL; + shell->passe_partout = NULL; + shell->preview_items = NULL; + shell->vectors = NULL; + shell->grid = NULL; + shell->guides = NULL; + shell->sample_points = NULL; + shell->canvas_boundary = NULL; + shell->layer_boundary = NULL; + shell->tool_items = NULL; } if (shell->unrotated_item) diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c index 6d5df4794c..66267812f2 100644 --- a/app/display/gimpdisplayshell.c +++ b/app/display/gimpdisplayshell.c @@ -57,6 +57,7 @@ #include "tools/tool_manager.h" #include "gimpcanvas.h" +#include "gimpcanvascanvasboundary.h" #include "gimpcanvaslayerboundary.h" #include "gimpdisplay.h" #include "gimpdisplayshell.h" @@ -1849,6 +1850,8 @@ gimp_display_shell_set_show_all (GimpDisplayShell *shell, gimp_display_update_bounding_box (shell->display); + gimp_display_shell_update_show_canvas (shell); + gimp_display_shell_scroll_clamp_and_update (shell); gimp_display_shell_scrollbars_update (shell); @@ -1929,6 +1932,9 @@ gimp_display_shell_flush (GimpDisplayShell *shell, gimp_canvas_layer_boundary_set_layer (GIMP_CANVAS_LAYER_BOUNDARY (shell->layer_boundary), gimp_image_get_active_layer (gimp_display_get_image (shell->display))); + gimp_canvas_canvas_boundary_set_image (GIMP_CANVAS_CANVAS_BOUNDARY (shell->canvas_boundary), + gimp_display_get_image (shell->display)); + if (window && gimp_image_window_get_active_shell (window) == shell) { GimpUIManager *manager = gimp_image_window_get_ui_manager (window); diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h index d331a762df..e14ec6548f 100644 --- a/app/display/gimpdisplayshell.h +++ b/app/display/gimpdisplayshell.h @@ -124,6 +124,7 @@ struct _GimpDisplayShell GimpCanvasItem *grid; /* item proxy of the grid */ GimpCanvasItem *guides; /* item proxies of guides */ GimpCanvasItem *sample_points; /* item proxies of sample points */ + GimpCanvasItem *canvas_boundary; /* item for the cabvas boundary */ GimpCanvasItem *layer_boundary; /* item for the layer boundary */ GimpCanvasItem *tool_items; /* tools items, below the cursor */ GimpCanvasItem *cursor; /* item for the software cursor */ diff --git a/app/widgets/gimphelp-ids.h b/app/widgets/gimphelp-ids.h index ccf29203ee..0b62ac276b 100644 --- a/app/widgets/gimphelp-ids.h +++ b/app/widgets/gimphelp-ids.h @@ -105,6 +105,7 @@ #define GIMP_HELP_VIEW_COLOR_MANAGEMENT "gimp-view-color-management" #define GIMP_HELP_VIEW_SHOW_SELECTION "gimp-view-show-selection" #define GIMP_HELP_VIEW_SHOW_LAYER_BOUNDARY "gimp-view-show-layer-boundary" +#define GIMP_HELP_VIEW_SHOW_CANVAS_BOUNDARY "gimp-view-show-canvas-boundary" #define GIMP_HELP_VIEW_SHOW_GUIDES "gimp-view-show-guides" #define GIMP_HELP_VIEW_SHOW_GRID "gimp-view-show-grid" #define GIMP_HELP_VIEW_SHOW_SAMPLE_POINTS "gimp-view-show-sample-points" diff --git a/menus/image-menu.xml.in b/menus/image-menu.xml.in index cfa9cfd4d4..74ff410016 100644 --- a/menus/image-menu.xml.in +++ b/menus/image-menu.xml.in @@ -332,6 +332,7 @@ +