Commit f09be52c authored by Michael Natterer's avatar Michael Natterer 😴

app: turn the transform preview into a GimpCanvasItem

And remove all the complicated handling code entirely. This makes
GimpTransformTool a lot less complex. As a nice side effect, the
preview is now always 100% in sync with the grid and handles.
parent 4d9952cf
......@@ -61,6 +61,8 @@ libappdisplay_a_sources = \
gimpcanvassamplepoint.h \
gimpcanvastextcursor.c \
gimpcanvastextcursor.h \
gimpcanvastransformpreview.c \
gimpcanvastransformpreview.h \
gimpcursorview.c \
gimpcursorview.h \
gimpdisplay.c \
......@@ -103,8 +105,6 @@ libappdisplay_a_sources = \
gimpdisplayshell-icon.h \
gimpdisplayshell-items.c \
gimpdisplayshell-items.h \
gimpdisplayshell-preview.c \
gimpdisplayshell-preview.h \
gimpdisplayshell-progress.c \
gimpdisplayshell-progress.h \
gimpdisplayshell-render.c \
......
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpcanvastransformpreview.h
* Copyright (C) 2011 Michael Natterer <mitch@gimp.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __GIMP_CANVAS_TRANSFORM_PREVIEW_H__
#define __GIMP_CANVAS_TRANSFORM_PREVIEW_H__
#include "tools/tools-types.h" /* eek */
#include "gimpcanvasitem.h"
#define GIMP_TYPE_CANVAS_TRANSFORM_PREVIEW (gimp_canvas_transform_preview_get_type ())
#define GIMP_CANVAS_TRANSFORM_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CANVAS_TRANSFORM_PREVIEW, GimpCanvasTransformPreview))
#define GIMP_CANVAS_TRANSFORM_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CANVAS_TRANSFORM_PREVIEW, GimpCanvasTransformPreviewClass))
#define GIMP_IS_CANVAS_TRANSFORM_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CANVAS_TRANSFORM_PREVIEW))
#define GIMP_IS_CANVAS_TRANSFORM_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CANVAS_TRANSFORM_PREVIEW))
#define GIMP_CANVAS_TRANSFORM_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CANVAS_TRANSFORM_PREVIEW, GimpCanvasTransformPreviewClass))
typedef struct _GimpCanvasTransformPreview GimpCanvasTransformPreview;
typedef struct _GimpCanvasTransformPreviewClass GimpCanvasTransformPreviewClass;
struct _GimpCanvasTransformPreview
{
GimpCanvasItem parent_instance;
};
struct _GimpCanvasTransformPreviewClass
{
GimpCanvasItemClass parent_class;
};
GType gimp_canvas_transform_preview_get_type (void) G_GNUC_CONST;
GimpCanvasItem * gimp_canvas_transform_preview_new (GimpDisplayShell *shell,
GimpTransformTool *transform_tool,
gdouble opacity);
#endif /* __GIMP_CANVAS_TRANSFORM_PREVIEW_H__ */
......@@ -283,23 +283,6 @@ gimp_display_shell_get_show_layer (GimpDisplayShell *shell)
return appearance_get_options (shell)->show_layer_boundary;
}
void
gimp_display_shell_set_show_transform (GimpDisplayShell *shell,
gboolean show)
{
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
shell->show_transform_preview = show;
}
gboolean
gimp_display_shell_get_show_transform (GimpDisplayShell *shell)
{
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
return shell->show_transform_preview;
}
void
gimp_display_shell_set_show_guides (GimpDisplayShell *shell,
gboolean show)
......
......@@ -45,10 +45,6 @@ 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_transform (GimpDisplayShell *shell,
gboolean show);
gboolean gimp_display_shell_get_show_transform (GimpDisplayShell *shell);
void gimp_display_shell_set_show_grid (GimpDisplayShell *shell,
gboolean show);
gboolean gimp_display_shell_get_show_grid (GimpDisplayShell *shell);
......
......@@ -38,7 +38,6 @@
#include "gimpdisplayshell-appearance.h"
#include "gimpdisplayshell-callbacks.h"
#include "gimpdisplayshell-draw.h"
#include "gimpdisplayshell-preview.h"
#include "gimpdisplayshell-scroll.h"
#include "gimpdisplayshell-selection.h"
#include "gimpdisplayshell-title.h"
......@@ -531,11 +530,6 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
/* finally, draw all the remaining image window stuff on top
*/
/* draw the transform tool preview */
cairo_save (cr);
gimp_display_shell_preview_transform (shell, cr);
cairo_restore (cr);
/* draw canvas items */
gimp_canvas_item_draw (shell->canvas_item, cr);
......
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __GIMP_DISPLAY_SHELL_PREVIEW_H__
#define __GIMP_DISPLAY_SHELL_PREVIEW_H__
void gimp_display_shell_preview_transform (GimpDisplayShell *shell,
cairo_t *cr);
#endif /* __GIMP_DISPLAY_SHELL_PREVIEW_H__ */
......@@ -179,7 +179,6 @@ struct _GimpDisplayShell
GimpTreeHandler *vectors_visible_handler;
gboolean zoom_on_resize;
gboolean show_transform_preview;
gboolean size_allocate_from_configure_event;
......
......@@ -381,8 +381,6 @@ rotate_angle_changed (GtkAdjustment *adj,
gimp_transform_tool_recalc (tr_tool, GIMP_TOOL (tr_tool)->display);
gimp_transform_tool_expose_preview (tr_tool);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
}
......@@ -408,8 +406,6 @@ rotate_center_changed (GtkWidget *widget,
gimp_transform_tool_recalc (tr_tool, GIMP_TOOL (tr_tool)->display);
gimp_transform_tool_expose_preview (tr_tool);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
}
}
......@@ -351,8 +351,6 @@ gimp_scale_tool_size_notify (GtkWidget *box,
gimp_transform_tool_recalc (tr_tool, GIMP_TOOL (tr_tool)->display);
gimp_transform_tool_expose_preview (tr_tool);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
}
}
......
......@@ -261,8 +261,6 @@ shear_x_mag_changed (GtkAdjustment *adj,
gimp_transform_tool_recalc (tr_tool, GIMP_TOOL (tr_tool)->display);
gimp_transform_tool_expose_preview (tr_tool);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
}
}
......@@ -284,8 +282,6 @@ shear_y_mag_changed (GtkAdjustment *adj,
gimp_transform_tool_recalc (tr_tool, GIMP_TOOL (tr_tool)->display);
gimp_transform_tool_expose_preview (tr_tool);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
}
}
......@@ -52,10 +52,9 @@
#include "widgets/gimpdialogfactory.h"
#include "display/gimpcanvasgroup.h"
#include "display/gimpcanvastransformpreview.h"
#include "display/gimpdisplay.h"
#include "display/gimpdisplayshell.h"
#include "display/gimpdisplayshell-appearance.h"
#include "display/gimpdisplayshell-expose.h"
#include "display/gimpdisplayshell-transform.h"
#include "display/gimptooldialog.h"
......@@ -144,8 +143,6 @@ static void gimp_transform_tool_grid_recalc (GimpTransformTool
static void gimp_transform_tool_handles_recalc (GimpTransformTool *tr_tool,
GimpDisplay *display);
static void gimp_transform_tool_force_expose_preview (GimpTransformTool *tr_tool);
static void gimp_transform_tool_response (GtkWidget *widget,
gint response_id,
GimpTransformTool *tr_tool);
......@@ -322,8 +319,6 @@ gimp_transform_tool_initialize (GimpTool *tool,
/* start drawing the bounding box and handles... */
gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), display);
gimp_transform_tool_expose_preview (tr_tool);
tr_tool->function = TRANSFORM_CREATING;
/* Save the current transformation info */
......@@ -422,9 +417,6 @@ gimp_transform_tool_button_release (GimpTool *tool,
/* recalculate the tool's transformation matrix */
gimp_transform_tool_recalc (tr_tool, display);
/* get rid of preview artifacts left outside the drawable's area */
gimp_transform_tool_expose_preview (tr_tool);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
......@@ -458,8 +450,6 @@ gimp_transform_tool_motion (GimpTool *tool,
tr_tool_class->motion (tr_tool, display);
gimp_transform_tool_recalc (tr_tool, display);
gimp_transform_tool_expose_preview (tr_tool);
}
tr_tool->lastx = tr_tool->curx;
......@@ -763,65 +753,6 @@ gimp_transform_tool_options_notify (GimpTool *tool,
}
}
if (! strcmp (pspec->name, "type") ||
! strcmp (pspec->name, "direction") ||
! strcmp (pspec->name, "preview-type") ||
! strcmp (pspec->name, "grid-type") ||
! strcmp (pspec->name, "grid-size") ||
! strcmp (pspec->name, "preview-opacity"))
{
GimpDisplayShell *shell = NULL;
if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tr_tool)))
shell = gimp_display_get_shell (GIMP_DRAW_TOOL (tr_tool)->display);
switch (tr_options->preview_type)
{
default:
case GIMP_TRANSFORM_PREVIEW_TYPE_OUTLINE:
if (shell)
{
gimp_display_shell_set_show_transform (shell, FALSE);
gimp_transform_tool_force_expose_preview (tr_tool);
}
break;
case GIMP_TRANSFORM_PREVIEW_TYPE_GRID:
if (shell)
{
gimp_display_shell_set_show_transform (shell, FALSE);
gimp_transform_tool_force_expose_preview (tr_tool);
}
break;
case GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE:
if (shell)
{
if (tr_options->type == GIMP_TRANSFORM_TYPE_LAYER &&
tr_options->direction == GIMP_TRANSFORM_FORWARD)
gimp_display_shell_set_show_transform (shell, TRUE);
else
gimp_display_shell_set_show_transform (shell, FALSE);
gimp_transform_tool_force_expose_preview (tr_tool);
}
break;
case GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE_GRID:
if (shell)
{
if (tr_options->type == GIMP_TRANSFORM_TYPE_LAYER &&
tr_options->direction == GIMP_TRANSFORM_FORWARD)
gimp_display_shell_set_show_transform (shell, TRUE);
else
gimp_display_shell_set_show_transform (shell, FALSE);
gimp_transform_tool_force_expose_preview (tr_tool);
}
break;
}
}
if (tr_tool->function != TRANSFORM_CREATING)
{
gimp_transform_tool_grid_recalc (tr_tool);
......@@ -840,10 +771,25 @@ gimp_transform_tool_options_notify (GimpTool *tool,
static void
gimp_transform_tool_draw (GimpDrawTool *draw_tool)
{
GimpTool *tool = GIMP_TOOL (draw_tool);
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (draw_tool);
GimpImage *image = gimp_display_get_image (tool->display);
gdouble z1, z2, z3, z4;
GimpTool *tool = GIMP_TOOL (draw_tool);
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (draw_tool);
GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tool);
GimpImage *image = gimp_display_get_image (tool->display);
gdouble z1, z2, z3, z4;
if ((options->preview_type == GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE ||
options->preview_type == GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE_GRID) &&
options->type == GIMP_TRANSFORM_TYPE_LAYER &&
options->direction == GIMP_TRANSFORM_FORWARD)
{
GimpCanvasItem *item;
item = gimp_canvas_transform_preview_new (gimp_display_get_shell (draw_tool->display),
tr_tool,
options->preview_opacity);
gimp_draw_tool_add_item (draw_tool, item);
g_object_unref (item);
}
if (tr_tool->use_grid)
{
......@@ -1381,110 +1327,13 @@ gimp_transform_tool_transform_bounding_box (GimpTransformTool *tr_tool)
&tr_tool->tcx, &tr_tool->tcy);
}
void
gimp_transform_tool_expose_preview (GimpTransformTool *tr_tool)
{
GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
if ((options->preview_type == GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE ||
options->preview_type == GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE_GRID) &&
options->type == GIMP_TRANSFORM_TYPE_LAYER &&
options->direction == GIMP_TRANSFORM_FORWARD)
{
gimp_transform_tool_force_expose_preview (tr_tool);
}
}
static void
gimp_transform_tool_force_expose_preview (GimpTransformTool *tr_tool)
{
static gint last_x = 0;
static gint last_y = 0;
static gint last_w = 0;
static gint last_h = 0;
GimpDisplayShell *shell;
gdouble dx[4], dy[4];
gint area_x, area_y, area_w, area_h;
gint i;
g_return_if_fail (GIMP_IS_TRANSFORM_TOOL (tr_tool));
if (! tr_tool->use_grid)
return;
/* we might be called as the result of cancelling the transform
* tool dialog, return silently because the draw tool may have
* already been stopped by gimp_transform_tool_halt()
*/
if (! gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tr_tool)))
return;
shell = gimp_display_get_shell (GIMP_DRAW_TOOL (tr_tool)->display);
gimp_display_shell_transform_xy_f (shell, tr_tool->tx1, tr_tool->ty1,
dx + 0, dy + 0);
gimp_display_shell_transform_xy_f (shell, tr_tool->tx2, tr_tool->ty2,
dx + 1, dy + 1);
gimp_display_shell_transform_xy_f (shell, tr_tool->tx3, tr_tool->ty3,
dx + 2, dy + 2);
gimp_display_shell_transform_xy_f (shell, tr_tool->tx4, tr_tool->ty4,
dx + 3, dy + 3);
/* find bounding box around preview */
area_x = area_w = (gint) dx[0];
area_y = area_h = (gint) dy[0];
for (i = 1; i < 4; i++)
{
if (dx[i] < area_x)
area_x = (gint) dx[i];
else if (dx[i] > area_w)
area_w = (gint) dx[i];
if (dy[i] < area_y)
area_y = (gint) dy[i];
else if (dy[i] > area_h)
area_h = (gint) dy[i];
}
area_w -= area_x;
area_h -= area_y;
gimp_display_shell_expose_area (shell,
MIN (area_x, last_x),
MIN (area_y, last_y),
MAX (area_w, last_w) + ABS (last_x - area_x),
MAX (area_h, last_h) + ABS (last_y - area_y));
/* area of last preview must be re-exposed to avoid leaving artifacts */
last_x = area_x;
last_y = area_y;
last_w = area_w;
last_h = area_h;
}
static void
gimp_transform_tool_halt (GimpTransformTool *tr_tool)
{
GimpTool *tool = GIMP_TOOL (tr_tool);
if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tr_tool)))
{
GimpDisplayShell *shell;
shell = gimp_display_get_shell (GIMP_DRAW_TOOL (tr_tool)->display);
if (gimp_display_shell_get_show_transform (shell))
{
gimp_display_shell_set_show_transform (shell, FALSE);
/* get rid of preview artifacts left outside the drawable's area */
gimp_transform_tool_expose_preview (tr_tool);
}
gimp_draw_tool_stop (GIMP_DRAW_TOOL (tr_tool));
}
gimp_draw_tool_stop (GIMP_DRAW_TOOL (tr_tool));
/* inactivate the tool */
tr_tool->function = TRANSFORM_CREATING;
......@@ -1704,16 +1553,6 @@ gimp_transform_tool_prepare (GimpTransformTool *tr_tool,
{
GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
GimpImage *image = gimp_display_get_image (display);
gboolean show_transform;
show_transform =
((options->preview_type == GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE ||
options->preview_type == GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE_GRID) &&
options->type == GIMP_TRANSFORM_TYPE_LAYER &&
options->direction == GIMP_TRANSFORM_FORWARD);
gimp_display_shell_set_show_transform (gimp_display_get_shell (display),
show_transform);
if (tr_tool->dialog)
{
......@@ -1772,9 +1611,6 @@ gimp_transform_tool_response (GtkWidget *widget,
/* recalculate the tool's transformation matrix */
gimp_transform_tool_recalc (tr_tool, tool->display);
/* get rid of preview artifacts left outside the drawable's area */
gimp_transform_tool_expose_preview (tr_tool);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
break;
......
......@@ -132,11 +132,10 @@ struct _GimpTransformToolClass
};
GType gimp_transform_tool_get_type (void) G_GNUC_CONST;
GType gimp_transform_tool_get_type (void) G_GNUC_CONST;
void gimp_transform_tool_recalc (GimpTransformTool *tr_tool,
GimpDisplay *display);
void gimp_transform_tool_expose_preview (GimpTransformTool *tr_tool);
void gimp_transform_tool_recalc (GimpTransformTool *tr_tool,
GimpDisplay *display);
#endif /* __GIMP_TRANSFORM_TOOL_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment