mirror of https://github.com/GNOME/gimp.git
app: add TRANSFORM_GRIDS propgui controller
... which is similar to the TRANSFORM_GRID controller, supporting multiple transformation matrices. Implement the TRANSFORM_GRIDS controller in GimpFilterTool, using the new GimpToolWidgetGroup to display multiple transform grids.
This commit is contained in:
parent
4ef06b9922
commit
5e953ece85
|
@ -31,6 +31,7 @@ typedef enum
|
|||
GIMP_CONTROLLER_TYPE_LINE,
|
||||
GIMP_CONTROLLER_TYPE_SLIDER_LINE,
|
||||
GIMP_CONTROLLER_TYPE_TRANSFORM_GRID,
|
||||
GIMP_CONTROLLER_TYPE_TRANSFORM_GRIDS,
|
||||
GIMP_CONTROLLER_TYPE_GYROSCOPE
|
||||
} GimpControllerType;
|
||||
|
||||
|
@ -77,53 +78,57 @@ typedef struct
|
|||
|
||||
/* function types */
|
||||
|
||||
typedef void (* GimpPickerCallback) (gpointer data,
|
||||
gpointer identifier,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
const Babl *sample_format,
|
||||
const GimpRGB *color);
|
||||
typedef void (* GimpPickerCallback) (gpointer data,
|
||||
gpointer identifier,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
const Babl *sample_format,
|
||||
const GimpRGB *color);
|
||||
|
||||
typedef void (* GimpControllerLineCallback) (gpointer data,
|
||||
GeglRectangle *area,
|
||||
gdouble x1,
|
||||
gdouble y1,
|
||||
gdouble x2,
|
||||
gdouble y2);
|
||||
typedef void (* GimpControllerSliderLineCallback) (gpointer data,
|
||||
GeglRectangle *area,
|
||||
gdouble x1,
|
||||
gdouble y1,
|
||||
gdouble x2,
|
||||
gdouble y2,
|
||||
const GimpControllerSlider *sliders,
|
||||
gint n_sliders);
|
||||
typedef void (* GimpControllerTransformGridCallback) (gpointer data,
|
||||
GeglRectangle *area,
|
||||
const GimpMatrix3 *transform);
|
||||
typedef void (* GimpControllerGyroscopeCallback) (gpointer data,
|
||||
GeglRectangle *area,
|
||||
gdouble yaw,
|
||||
gdouble pitch,
|
||||
gdouble roll,
|
||||
gdouble zoom,
|
||||
gboolean invert);
|
||||
typedef void (* GimpControllerLineCallback) (gpointer data,
|
||||
GeglRectangle *area,
|
||||
gdouble x1,
|
||||
gdouble y1,
|
||||
gdouble x2,
|
||||
gdouble y2);
|
||||
typedef void (* GimpControllerSliderLineCallback) (gpointer data,
|
||||
GeglRectangle *area,
|
||||
gdouble x1,
|
||||
gdouble y1,
|
||||
gdouble x2,
|
||||
gdouble y2,
|
||||
const GimpControllerSlider *sliders,
|
||||
gint n_sliders);
|
||||
typedef void (* GimpControllerTransformGridCallback) (gpointer data,
|
||||
GeglRectangle *area,
|
||||
const GimpMatrix3 *transform);
|
||||
typedef void (* GimpControllerTransformGridsCallback) (gpointer data,
|
||||
GeglRectangle *area,
|
||||
const GimpMatrix3 *transforms,
|
||||
gint n_transforms);
|
||||
typedef void (* GimpControllerGyroscopeCallback) (gpointer data,
|
||||
GeglRectangle *area,
|
||||
gdouble yaw,
|
||||
gdouble pitch,
|
||||
gdouble roll,
|
||||
gdouble zoom,
|
||||
gboolean invert);
|
||||
|
||||
|
||||
typedef GtkWidget * (* GimpCreatePickerFunc) (gpointer creator,
|
||||
const gchar *property_name,
|
||||
const gchar *icon_name,
|
||||
const gchar *tooltip,
|
||||
gboolean pick_abyss,
|
||||
GimpPickerCallback callback,
|
||||
gpointer callback_data);
|
||||
typedef GtkWidget * (* GimpCreatePickerFunc) (gpointer creator,
|
||||
const gchar *property_name,
|
||||
const gchar *icon_name,
|
||||
const gchar *tooltip,
|
||||
gboolean pick_abyss,
|
||||
GimpPickerCallback callback,
|
||||
gpointer callback_data);
|
||||
|
||||
typedef GCallback (* GimpCreateControllerFunc) (gpointer creator,
|
||||
GimpControllerType controller_type,
|
||||
const gchar *status_title,
|
||||
GCallback callback,
|
||||
gpointer callback_data,
|
||||
gpointer *set_func_data);
|
||||
typedef GCallback (* GimpCreateControllerFunc) (gpointer creator,
|
||||
GimpControllerType controller_type,
|
||||
const gchar *status_title,
|
||||
GCallback callback,
|
||||
gpointer callback_data,
|
||||
gpointer *set_func_data);
|
||||
|
||||
|
||||
#endif /* __PROPGUI_TYPES_H__ */
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
@ -26,12 +28,14 @@
|
|||
|
||||
#include "tools-types.h"
|
||||
|
||||
#include "core/gimpcontainer.h"
|
||||
#include "core/gimpitem.h"
|
||||
|
||||
#include "display/gimpdisplay.h"
|
||||
#include "display/gimptoolgyroscope.h"
|
||||
#include "display/gimptoolline.h"
|
||||
#include "display/gimptooltransformgrid.h"
|
||||
#include "display/gimptoolwidgetgroup.h"
|
||||
|
||||
#include "gimpfilteroptions.h"
|
||||
#include "gimpfiltertool.h"
|
||||
|
@ -52,41 +56,48 @@ struct _Controller
|
|||
|
||||
/* local function prototypes */
|
||||
|
||||
static void gimp_filter_tool_set_line (Controller *controller,
|
||||
GeglRectangle *area,
|
||||
gdouble x1,
|
||||
gdouble y1,
|
||||
gdouble x2,
|
||||
gdouble y2);
|
||||
static void gimp_filter_tool_line_changed (GimpToolWidget *widget,
|
||||
Controller *controller);
|
||||
static void gimp_filter_tool_set_line (Controller *controller,
|
||||
GeglRectangle *area,
|
||||
gdouble x1,
|
||||
gdouble y1,
|
||||
gdouble x2,
|
||||
gdouble y2);
|
||||
static void gimp_filter_tool_line_changed (GimpToolWidget *widget,
|
||||
Controller *controller);
|
||||
|
||||
static void gimp_filter_tool_set_slider_line (Controller *controller,
|
||||
GeglRectangle *area,
|
||||
gdouble x1,
|
||||
gdouble y1,
|
||||
gdouble x2,
|
||||
gdouble y2,
|
||||
const GimpControllerSlider *sliders,
|
||||
gint n_sliders);
|
||||
static void gimp_filter_tool_slider_line_changed (GimpToolWidget *widget,
|
||||
Controller *controller);
|
||||
static void gimp_filter_tool_set_slider_line (Controller *controller,
|
||||
GeglRectangle *area,
|
||||
gdouble x1,
|
||||
gdouble y1,
|
||||
gdouble x2,
|
||||
gdouble y2,
|
||||
const GimpControllerSlider *sliders,
|
||||
gint n_sliders);
|
||||
static void gimp_filter_tool_slider_line_changed (GimpToolWidget *widget,
|
||||
Controller *controller);
|
||||
|
||||
static void gimp_filter_tool_set_transform_grid (Controller *controller,
|
||||
GeglRectangle *area,
|
||||
const GimpMatrix3 *matrix);
|
||||
static void gimp_filter_tool_transform_grid_changed (GimpToolWidget *widget,
|
||||
Controller *controller);
|
||||
static void gimp_filter_tool_set_transform_grid (Controller *controller,
|
||||
GeglRectangle *area,
|
||||
const GimpMatrix3 *transform);
|
||||
static void gimp_filter_tool_transform_grid_changed (GimpToolWidget *widget,
|
||||
Controller *controller);
|
||||
|
||||
static void gimp_filter_tool_set_gyroscope (Controller *controller,
|
||||
GeglRectangle *area,
|
||||
gdouble yaw,
|
||||
gdouble pitch,
|
||||
gdouble roll,
|
||||
gdouble zoom,
|
||||
gboolean invert);
|
||||
static void gimp_filter_tool_gyroscope_changed (GimpToolWidget *widget,
|
||||
Controller *controller);
|
||||
static void gimp_filter_tool_set_transform_grids (Controller *controller,
|
||||
GeglRectangle *area,
|
||||
const GimpMatrix3 *transforms,
|
||||
gint n_transforms);
|
||||
static void gimp_filter_tool_transform_grids_changed (GimpToolWidget *widget,
|
||||
Controller *controller);
|
||||
|
||||
static void gimp_filter_tool_set_gyroscope (Controller *controller,
|
||||
GeglRectangle *area,
|
||||
gdouble yaw,
|
||||
gdouble pitch,
|
||||
gdouble roll,
|
||||
gdouble zoom,
|
||||
gboolean invert);
|
||||
static void gimp_filter_tool_gyroscope_changed (GimpToolWidget *widget,
|
||||
Controller *controller);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
@ -192,6 +203,22 @@ gimp_filter_tool_create_widget (GimpFilterTool *filter_tool,
|
|||
}
|
||||
break;
|
||||
|
||||
case GIMP_CONTROLLER_TYPE_TRANSFORM_GRIDS:
|
||||
{
|
||||
controller->widget = gimp_tool_widget_group_new (shell);
|
||||
|
||||
gimp_tool_widget_group_set_auto_raise (
|
||||
GIMP_TOOL_WIDGET_GROUP (controller->widget), TRUE);
|
||||
|
||||
g_signal_connect (controller->widget, "changed",
|
||||
G_CALLBACK (gimp_filter_tool_transform_grids_changed),
|
||||
controller);
|
||||
|
||||
*set_func = (GCallback) gimp_filter_tool_set_transform_grids;
|
||||
*set_func_data = controller;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_CONTROLLER_TYPE_GYROSCOPE:
|
||||
{
|
||||
GeglRectangle area;
|
||||
|
@ -224,6 +251,40 @@ gimp_filter_tool_create_widget (GimpFilterTool *filter_tool,
|
|||
return controller->widget;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_filter_tool_reset_transform_grid (GimpToolWidget *widget,
|
||||
GimpFilterTool *filter_tool)
|
||||
{
|
||||
GimpMatrix3 *transform;
|
||||
gint off_x, off_y;
|
||||
GeglRectangle area;
|
||||
gdouble x1, y1;
|
||||
gdouble x2, y2;
|
||||
gdouble pivot_x, pivot_y;
|
||||
|
||||
g_object_get (widget,
|
||||
"transform", &transform,
|
||||
NULL);
|
||||
|
||||
gimp_filter_tool_get_drawable_area (filter_tool, &off_x, &off_y, &area);
|
||||
|
||||
x1 = off_x + area.x;
|
||||
y1 = off_y + area.y;
|
||||
x2 = x1 + area.width;
|
||||
y2 = y1 + area.height;
|
||||
|
||||
gimp_matrix3_transform_point (transform,
|
||||
(x1 + x2) / 2.0, (y1 + y2) / 2.0,
|
||||
&pivot_x, &pivot_y);
|
||||
|
||||
g_object_set (widget,
|
||||
"pivot-x", pivot_x,
|
||||
"pivot-y", pivot_y,
|
||||
NULL);
|
||||
|
||||
g_free (transform);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_filter_tool_reset_widget (GimpFilterTool *filter_tool,
|
||||
GimpToolWidget *widget)
|
||||
|
@ -242,42 +303,33 @@ gimp_filter_tool_reset_widget (GimpFilterTool *filter_tool,
|
|||
{
|
||||
case GIMP_CONTROLLER_TYPE_TRANSFORM_GRID:
|
||||
{
|
||||
GimpMatrix3 *transform;
|
||||
gint off_x, off_y;
|
||||
GeglRectangle area;
|
||||
gdouble x1, y1;
|
||||
gdouble x2, y2;
|
||||
gdouble pivot_x, pivot_y;
|
||||
|
||||
g_object_get (controller->widget,
|
||||
"transform", &transform,
|
||||
NULL);
|
||||
|
||||
gimp_filter_tool_get_drawable_area (filter_tool, &off_x, &off_y, &area);
|
||||
|
||||
x1 = off_x + area.x;
|
||||
y1 = off_y + area.y;
|
||||
x2 = x1 + area.width;
|
||||
y2 = y1 + area.height;
|
||||
|
||||
gimp_matrix3_transform_point (transform,
|
||||
(x1 + x2) / 2.0, (y1 + y2) / 2.0,
|
||||
&pivot_x, &pivot_y);
|
||||
|
||||
g_signal_handlers_block_by_func (controller->widget,
|
||||
gimp_filter_tool_transform_grid_changed,
|
||||
controller);
|
||||
|
||||
g_object_set (controller->widget,
|
||||
"pivot-x", pivot_x,
|
||||
"pivot-y", pivot_y,
|
||||
NULL);
|
||||
gimp_filter_tool_reset_transform_grid (controller->widget, filter_tool);
|
||||
|
||||
g_signal_handlers_unblock_by_func (controller->widget,
|
||||
gimp_filter_tool_transform_grid_changed,
|
||||
controller);
|
||||
}
|
||||
break;
|
||||
|
||||
g_free (transform);
|
||||
case GIMP_CONTROLLER_TYPE_TRANSFORM_GRIDS:
|
||||
{
|
||||
g_signal_handlers_block_by_func (controller->widget,
|
||||
gimp_filter_tool_transform_grids_changed,
|
||||
controller);
|
||||
|
||||
gimp_container_foreach (
|
||||
gimp_tool_widget_group_get_children (
|
||||
GIMP_TOOL_WIDGET_GROUP (controller->widget)),
|
||||
(GFunc) gimp_filter_tool_reset_transform_grid,
|
||||
filter_tool);
|
||||
|
||||
g_signal_handlers_unblock_by_func (controller->widget,
|
||||
gimp_filter_tool_transform_grids_changed,
|
||||
controller);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -516,6 +568,166 @@ gimp_filter_tool_transform_grid_changed (GimpToolWidget *widget,
|
|||
g_free (transform);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_filter_tool_set_transform_grids (Controller *controller,
|
||||
GeglRectangle *area,
|
||||
const GimpMatrix3 *transforms,
|
||||
gint n_transforms)
|
||||
{
|
||||
GimpTool *tool = GIMP_TOOL (controller->filter_tool);
|
||||
GimpDisplayShell *shell = gimp_display_get_shell (tool->display);
|
||||
GimpDrawable *drawable = tool->drawable;
|
||||
GimpContainer *grids;
|
||||
GimpToolWidget *grid = NULL;
|
||||
gdouble x1 = area->x;
|
||||
gdouble y1 = area->y;
|
||||
gdouble x2 = area->x + area->width;
|
||||
gdouble y2 = area->y + area->height;
|
||||
GimpMatrix3 matrix;
|
||||
gint i;
|
||||
|
||||
g_signal_handlers_block_by_func (controller->widget,
|
||||
gimp_filter_tool_transform_grids_changed,
|
||||
controller);
|
||||
|
||||
if (drawable)
|
||||
{
|
||||
gint off_x, off_y;
|
||||
|
||||
gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
|
||||
|
||||
x1 += off_x;
|
||||
y1 += off_y;
|
||||
x2 += off_x;
|
||||
y2 += off_y;
|
||||
}
|
||||
|
||||
grids = gimp_tool_widget_group_get_children (
|
||||
GIMP_TOOL_WIDGET_GROUP (controller->widget));
|
||||
|
||||
if (n_transforms > gimp_container_get_n_children (grids))
|
||||
{
|
||||
gimp_matrix3_identity (&matrix);
|
||||
|
||||
for (i = gimp_container_get_n_children (grids); i < n_transforms; i++)
|
||||
{
|
||||
gdouble pivot_x;
|
||||
gdouble pivot_y;
|
||||
|
||||
grid = gimp_tool_transform_grid_new (shell, &matrix, x1, y1, x2, y2);
|
||||
|
||||
if (i > 0 && ! memcmp (&transforms[i], &transforms[i - 1],
|
||||
sizeof (GimpMatrix3)))
|
||||
{
|
||||
g_object_get (gimp_container_get_last_child (grids),
|
||||
"pivot-x", &pivot_x,
|
||||
"pivot-y", &pivot_y,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
pivot_x = (x1 + x2) / 2.0;
|
||||
pivot_y = (y1 + y2) / 2.0;
|
||||
|
||||
gimp_matrix3_transform_point (&transforms[i],
|
||||
pivot_x, pivot_y,
|
||||
&pivot_x, &pivot_y);
|
||||
}
|
||||
|
||||
g_object_set (grid,
|
||||
"pivot-x", pivot_x,
|
||||
"pivot-y", pivot_y,
|
||||
"inside-function", GIMP_TRANSFORM_FUNCTION_MOVE,
|
||||
"outside-function", GIMP_TRANSFORM_FUNCTION_ROTATE,
|
||||
"use-corner-handles", TRUE,
|
||||
"use-perspective-handles", TRUE,
|
||||
"use-side-handles", TRUE,
|
||||
"use-shear-handles", TRUE,
|
||||
"use-pivot-handle", TRUE,
|
||||
NULL);
|
||||
|
||||
gimp_container_add (grids, GIMP_OBJECT (grid));
|
||||
|
||||
g_object_unref (grid);
|
||||
}
|
||||
|
||||
gimp_tool_widget_set_focus (grid, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (gimp_container_get_n_children (grids) > n_transforms)
|
||||
gimp_container_remove (grids, gimp_container_get_last_child (grids));
|
||||
}
|
||||
|
||||
for (i = 0; i < n_transforms; i++)
|
||||
{
|
||||
gimp_matrix3_identity (&matrix);
|
||||
gimp_matrix3_translate (&matrix, -x1, -y1);
|
||||
gimp_matrix3_mult (&transforms[i], &matrix);
|
||||
gimp_matrix3_translate (&matrix, +x1, +y1);
|
||||
|
||||
g_object_set (gimp_container_get_child_by_index (grids, i),
|
||||
"transform", &matrix,
|
||||
"x1", x1,
|
||||
"y1", y1,
|
||||
"x2", x2,
|
||||
"y2", y2,
|
||||
NULL);
|
||||
}
|
||||
|
||||
g_signal_handlers_unblock_by_func (controller->widget,
|
||||
gimp_filter_tool_transform_grids_changed,
|
||||
controller);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_filter_tool_transform_grids_changed (GimpToolWidget *widget,
|
||||
Controller *controller)
|
||||
{
|
||||
GimpFilterTool *filter_tool = controller->filter_tool;
|
||||
GimpControllerTransformGridsCallback transform_grids_callback;
|
||||
GimpContainer *grids;
|
||||
gint off_x, off_y;
|
||||
GeglRectangle area;
|
||||
GimpMatrix3 *transforms;
|
||||
gint n_transforms;
|
||||
gint i;
|
||||
|
||||
transform_grids_callback =
|
||||
(GimpControllerTransformGridsCallback) controller->creator_callback;
|
||||
|
||||
grids = gimp_tool_widget_group_get_children (
|
||||
GIMP_TOOL_WIDGET_GROUP (controller->widget));
|
||||
|
||||
gimp_filter_tool_get_drawable_area (filter_tool, &off_x, &off_y, &area);
|
||||
|
||||
n_transforms = gimp_container_get_n_children (grids);
|
||||
transforms = g_new (GimpMatrix3, n_transforms);
|
||||
|
||||
for (i = 0; i < n_transforms; i++)
|
||||
{
|
||||
GimpMatrix3 *transform;
|
||||
|
||||
g_object_get (gimp_container_get_child_by_index (grids, i),
|
||||
"transform", &transform,
|
||||
NULL);
|
||||
|
||||
gimp_matrix3_identity (&transforms[i]);
|
||||
gimp_matrix3_translate (&transforms[i],
|
||||
+(off_x + area.x), +(off_y + area.y));
|
||||
gimp_matrix3_mult (transform, &transforms[i]);
|
||||
gimp_matrix3_translate (&transforms[i],
|
||||
-(off_x + area.x), -(off_y + area.y));
|
||||
|
||||
g_free (transform);
|
||||
}
|
||||
|
||||
transform_grids_callback (controller->creator_data,
|
||||
&area, transforms, n_transforms);
|
||||
|
||||
g_free (transforms);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_filter_tool_set_gyroscope (Controller *controller,
|
||||
GeglRectangle *area,
|
||||
|
|
Loading…
Reference in New Issue