forked from openkylin/gimp
891 lines
32 KiB
C
891 lines
32 KiB
C
/* GIMP - The GNU Image Manipulation Program
|
||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||
*
|
||
* Measure tool
|
||
* Copyright (C) 1999-2003 Sven Neumann <sven@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 <https://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "config.h"
|
||
|
||
#include <gegl.h>
|
||
#include <gtk/gtk.h>
|
||
#include <gdk/gdkkeysyms.h>
|
||
|
||
#include "libgimpbase/gimpbase.h"
|
||
#include "libgimpmath/gimpmath.h"
|
||
#include "libgimpwidgets/gimpwidgets.h"
|
||
|
||
#include "tools-types.h"
|
||
|
||
#include "core/gimpimage.h"
|
||
#include "core/gimpimage-guides.h"
|
||
#include "core/gimpimage-undo.h"
|
||
#include "core/gimpimage-undo-push.h"
|
||
#include "core/gimpprogress.h"
|
||
#include "core/gimp-transform-utils.h"
|
||
|
||
#include "widgets/gimphelp-ids.h"
|
||
#include "widgets/gimpwidgets-utils.h"
|
||
|
||
#include "display/gimpdisplay.h"
|
||
#include "display/gimpdisplayshell.h"
|
||
#include "display/gimpdisplayshell-appearance.h"
|
||
#include "display/gimptoolcompass.h"
|
||
#include "display/gimptoolgui.h"
|
||
|
||
#include "gimpmeasureoptions.h"
|
||
#include "gimpmeasuretool.h"
|
||
#include "gimptoolcontrol.h"
|
||
|
||
#include "gimp-intl.h"
|
||
|
||
|
||
/* local function prototypes */
|
||
|
||
static void gimp_measure_tool_control (GimpTool *tool,
|
||
GimpToolAction action,
|
||
GimpDisplay *display);
|
||
static void gimp_measure_tool_modifier_key (GimpTool *tool,
|
||
GdkModifierType key,
|
||
gboolean press,
|
||
GdkModifierType state,
|
||
GimpDisplay *display);
|
||
static void gimp_measure_tool_button_press (GimpTool *tool,
|
||
const GimpCoords *coords,
|
||
guint32 time,
|
||
GdkModifierType state,
|
||
GimpButtonPressType press_type,
|
||
GimpDisplay *display);
|
||
static void gimp_measure_tool_button_release (GimpTool *tool,
|
||
const GimpCoords *coords,
|
||
guint32 time,
|
||
GdkModifierType state,
|
||
GimpButtonReleaseType release_type,
|
||
GimpDisplay *display);
|
||
static void gimp_measure_tool_motion (GimpTool *tool,
|
||
const GimpCoords *coords,
|
||
guint32 time,
|
||
GdkModifierType state,
|
||
GimpDisplay *display);
|
||
|
||
static void gimp_measure_tool_recalc_matrix (GimpTransformTool *tr_tool);
|
||
static gchar * gimp_measure_tool_get_undo_desc (GimpTransformTool *tr_tool);
|
||
|
||
static void gimp_measure_tool_compass_changed (GimpToolWidget *widget,
|
||
GimpMeasureTool *measure);
|
||
static void gimp_measure_tool_compass_response(GimpToolWidget *widget,
|
||
gint response_id,
|
||
GimpMeasureTool *measure);
|
||
static void gimp_measure_tool_compass_status (GimpToolWidget *widget,
|
||
const gchar *status,
|
||
GimpMeasureTool *measure);
|
||
static void gimp_measure_tool_compass_create_guides
|
||
(GimpToolWidget *widget,
|
||
gint x,
|
||
gint y,
|
||
gboolean horizontal,
|
||
gboolean vertical,
|
||
GimpMeasureTool *measure);
|
||
|
||
static void gimp_measure_tool_start (GimpMeasureTool *measure,
|
||
GimpDisplay *display,
|
||
const GimpCoords *coords);
|
||
static void gimp_measure_tool_halt (GimpMeasureTool *measure);
|
||
|
||
static GimpToolGui * gimp_measure_tool_dialog_new (GimpMeasureTool *measure);
|
||
static void gimp_measure_tool_dialog_update (GimpMeasureTool *measure,
|
||
GimpDisplay *display);
|
||
|
||
static void gimp_measure_tool_straighten_button_clicked
|
||
(GtkWidget *button,
|
||
GimpMeasureTool *measure);
|
||
|
||
G_DEFINE_TYPE (GimpMeasureTool, gimp_measure_tool, GIMP_TYPE_TRANSFORM_TOOL)
|
||
|
||
#define parent_class gimp_measure_tool_parent_class
|
||
|
||
|
||
void
|
||
gimp_measure_tool_register (GimpToolRegisterCallback callback,
|
||
gpointer data)
|
||
{
|
||
(* callback) (GIMP_TYPE_MEASURE_TOOL,
|
||
GIMP_TYPE_MEASURE_OPTIONS,
|
||
gimp_measure_options_gui,
|
||
0,
|
||
"gimp-measure-tool",
|
||
_("Measure"),
|
||
_("Measure Tool: Measure distances and angles"),
|
||
N_("_Measure"), "<shift>M",
|
||
NULL, GIMP_HELP_TOOL_MEASURE,
|
||
GIMP_ICON_TOOL_MEASURE,
|
||
data);
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_class_init (GimpMeasureToolClass *klass)
|
||
{
|
||
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
|
||
GimpTransformToolClass *tr_class = GIMP_TRANSFORM_TOOL_CLASS (klass);
|
||
|
||
tool_class->control = gimp_measure_tool_control;
|
||
tool_class->modifier_key = gimp_measure_tool_modifier_key;
|
||
tool_class->button_press = gimp_measure_tool_button_press;
|
||
tool_class->button_release = gimp_measure_tool_button_release;
|
||
tool_class->motion = gimp_measure_tool_motion;
|
||
|
||
tr_class->recalc_matrix = gimp_measure_tool_recalc_matrix;
|
||
tr_class->get_undo_desc = gimp_measure_tool_get_undo_desc;
|
||
|
||
tr_class->undo_desc = C_("undo-type", "Straighten");
|
||
tr_class->progress_text = _("Straightening");
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_init (GimpMeasureTool *measure)
|
||
{
|
||
GimpTool *tool = GIMP_TOOL (measure);
|
||
|
||
gimp_tool_control_set_handle_empty_image (tool->control, TRUE);
|
||
gimp_tool_control_set_active_modifiers (tool->control,
|
||
GIMP_TOOL_ACTIVE_MODIFIERS_SEPARATE);
|
||
gimp_tool_control_set_precision (tool->control,
|
||
GIMP_CURSOR_PRECISION_PIXEL_BORDER);
|
||
gimp_tool_control_set_cursor (tool->control,
|
||
GIMP_CURSOR_CROSSHAIR_SMALL);
|
||
gimp_tool_control_set_tool_cursor (tool->control,
|
||
GIMP_TOOL_CURSOR_MEASURE);
|
||
|
||
gimp_draw_tool_set_default_status (GIMP_DRAW_TOOL (tool),
|
||
_("Click-Drag to create a line"));
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_control (GimpTool *tool,
|
||
GimpToolAction action,
|
||
GimpDisplay *display)
|
||
{
|
||
GimpMeasureTool *measure = GIMP_MEASURE_TOOL (tool);
|
||
|
||
switch (action)
|
||
{
|
||
case GIMP_TOOL_ACTION_PAUSE:
|
||
case GIMP_TOOL_ACTION_RESUME:
|
||
break;
|
||
|
||
case GIMP_TOOL_ACTION_HALT:
|
||
gimp_measure_tool_halt (measure);
|
||
break;
|
||
|
||
case GIMP_TOOL_ACTION_COMMIT:
|
||
break;
|
||
}
|
||
|
||
GIMP_TOOL_CLASS (parent_class)->control (tool, action, display);
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_modifier_key (GimpTool *tool,
|
||
GdkModifierType key,
|
||
gboolean press,
|
||
GdkModifierType state,
|
||
GimpDisplay *display)
|
||
{
|
||
GimpMeasureOptions *options = GIMP_MEASURE_TOOL_GET_OPTIONS (tool);
|
||
|
||
if (key == gimp_get_toggle_behavior_mask ())
|
||
{
|
||
switch (options->orientation)
|
||
{
|
||
case GIMP_COMPASS_ORIENTATION_HORIZONTAL:
|
||
g_object_set (options,
|
||
"orientation", GIMP_COMPASS_ORIENTATION_VERTICAL,
|
||
NULL);
|
||
break;
|
||
|
||
case GIMP_COMPASS_ORIENTATION_VERTICAL:
|
||
g_object_set (options,
|
||
"orientation", GIMP_COMPASS_ORIENTATION_HORIZONTAL,
|
||
NULL);
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_button_press (GimpTool *tool,
|
||
const GimpCoords *coords,
|
||
guint32 time,
|
||
GdkModifierType state,
|
||
GimpButtonPressType press_type,
|
||
GimpDisplay *display)
|
||
{
|
||
GimpMeasureTool *measure = GIMP_MEASURE_TOOL (tool);
|
||
GimpMeasureOptions *options = GIMP_MEASURE_TOOL_GET_OPTIONS (tool);
|
||
GimpDisplayShell *shell = gimp_display_get_shell (display);
|
||
GimpImage *image = gimp_display_get_image (display);
|
||
|
||
if (tool->display && display != tool->display)
|
||
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, tool->display);
|
||
|
||
if (! measure->widget)
|
||
{
|
||
measure->supress_guides = TRUE;
|
||
|
||
gimp_measure_tool_start (measure, display, coords);
|
||
|
||
gimp_tool_widget_hover (measure->widget, coords, state, TRUE);
|
||
}
|
||
|
||
if (gimp_tool_widget_button_press (measure->widget, coords, time, state,
|
||
press_type))
|
||
{
|
||
measure->grab_widget = measure->widget;
|
||
}
|
||
|
||
/* create the info window if necessary */
|
||
if (! measure->gui)
|
||
{
|
||
if (options->use_info_window ||
|
||
! gimp_display_shell_get_show_statusbar (shell))
|
||
{
|
||
measure->gui = gimp_measure_tool_dialog_new (measure);
|
||
g_object_add_weak_pointer (G_OBJECT (measure->gui),
|
||
(gpointer) &measure->gui);
|
||
}
|
||
}
|
||
|
||
if (measure->gui)
|
||
{
|
||
gimp_tool_gui_set_shell (measure->gui, shell);
|
||
gimp_tool_gui_set_viewable (measure->gui, GIMP_VIEWABLE (image));
|
||
|
||
gimp_measure_tool_dialog_update (measure, display);
|
||
}
|
||
|
||
gimp_tool_control_activate (tool->control);
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_button_release (GimpTool *tool,
|
||
const GimpCoords *coords,
|
||
guint32 time,
|
||
GdkModifierType state,
|
||
GimpButtonReleaseType release_type,
|
||
GimpDisplay *display)
|
||
{
|
||
GimpMeasureTool *measure = GIMP_MEASURE_TOOL (tool);
|
||
|
||
gimp_tool_control_halt (tool->control);
|
||
|
||
if (measure->grab_widget)
|
||
{
|
||
gimp_tool_widget_button_release (measure->grab_widget,
|
||
coords, time, state, release_type);
|
||
measure->grab_widget = NULL;
|
||
}
|
||
|
||
measure->supress_guides = FALSE;
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_motion (GimpTool *tool,
|
||
const GimpCoords *coords,
|
||
guint32 time,
|
||
GdkModifierType state,
|
||
GimpDisplay *display)
|
||
{
|
||
GimpMeasureTool *measure = GIMP_MEASURE_TOOL (tool);
|
||
|
||
if (measure->grab_widget)
|
||
{
|
||
gimp_tool_widget_motion (measure->grab_widget, coords, time, state);
|
||
}
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_recalc_matrix (GimpTransformTool *tr_tool)
|
||
{
|
||
GimpMeasureTool *measure = GIMP_MEASURE_TOOL (tr_tool);
|
||
gdouble angle;
|
||
|
||
if (measure->n_points < 2)
|
||
{
|
||
tr_tool->transform_valid = FALSE;
|
||
|
||
return;
|
||
}
|
||
|
||
g_object_get (measure->widget,
|
||
"pixel-angle", &angle,
|
||
NULL);
|
||
|
||
gimp_matrix3_identity (&tr_tool->transform);
|
||
gimp_transform_matrix_rotate_center (&tr_tool->transform,
|
||
measure->x[0], measure->y[0],
|
||
angle);
|
||
|
||
tr_tool->transform_valid = TRUE;
|
||
}
|
||
|
||
static gchar *
|
||
gimp_measure_tool_get_undo_desc (GimpTransformTool *tr_tool)
|
||
{
|
||
GimpMeasureTool *measure = GIMP_MEASURE_TOOL (tr_tool);
|
||
GimpCompassOrientation orientation;
|
||
gdouble angle;
|
||
|
||
g_object_get (measure->widget,
|
||
"effective-orientation", &orientation,
|
||
"pixel-angle", &angle,
|
||
NULL);
|
||
|
||
angle = gimp_rad_to_deg (fabs (angle));
|
||
|
||
switch (orientation)
|
||
{
|
||
case GIMP_COMPASS_ORIENTATION_AUTO:
|
||
return g_strdup_printf (C_("undo-type",
|
||
"Straighten by %-3.3g°"),
|
||
angle);
|
||
|
||
case GIMP_COMPASS_ORIENTATION_HORIZONTAL:
|
||
return g_strdup_printf (C_("undo-type",
|
||
"Straighten Horizontally by %-3.3g°"),
|
||
angle);
|
||
|
||
case GIMP_COMPASS_ORIENTATION_VERTICAL:
|
||
return g_strdup_printf (C_("undo-type",
|
||
"Straighten Vertically by %-3.3g°"),
|
||
angle);
|
||
}
|
||
|
||
g_return_val_if_reached (NULL);
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_compass_changed (GimpToolWidget *widget,
|
||
GimpMeasureTool *measure)
|
||
{
|
||
GimpMeasureOptions *options = GIMP_MEASURE_TOOL_GET_OPTIONS (measure);
|
||
|
||
g_object_get (widget,
|
||
"n-points", &measure->n_points,
|
||
"x1", &measure->x[0],
|
||
"y1", &measure->y[0],
|
||
"x2", &measure->x[1],
|
||
"y2", &measure->y[1],
|
||
"x3", &measure->x[2],
|
||
"y3", &measure->y[2],
|
||
NULL);
|
||
|
||
gtk_widget_set_sensitive (options->straighten_button, measure->n_points >= 2);
|
||
gimp_measure_tool_dialog_update (measure, GIMP_TOOL (measure)->display);
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_compass_response (GimpToolWidget *widget,
|
||
gint response_id,
|
||
GimpMeasureTool *measure)
|
||
{
|
||
GimpTool *tool = GIMP_TOOL (measure);
|
||
|
||
if (response_id == GIMP_TOOL_WIDGET_RESPONSE_CANCEL)
|
||
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, tool->display);
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_compass_status (GimpToolWidget *widget,
|
||
const gchar *status,
|
||
GimpMeasureTool *measure)
|
||
{
|
||
GimpTool *tool = GIMP_TOOL (measure);
|
||
|
||
if (! status)
|
||
{
|
||
/* replace status bar hint by distance and angle */
|
||
gimp_measure_tool_dialog_update (measure, tool->display);
|
||
}
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_compass_create_guides (GimpToolWidget *widget,
|
||
gint x,
|
||
gint y,
|
||
gboolean horizontal,
|
||
gboolean vertical,
|
||
GimpMeasureTool *measure)
|
||
{
|
||
GimpDisplay *display = GIMP_TOOL (measure)->display;
|
||
GimpImage *image = gimp_display_get_image (display);
|
||
|
||
if (measure->supress_guides)
|
||
return;
|
||
|
||
if (x < 0 || x > gimp_image_get_width (image))
|
||
vertical = FALSE;
|
||
|
||
if (y < 0 || y > gimp_image_get_height (image))
|
||
horizontal = FALSE;
|
||
|
||
if (horizontal || vertical)
|
||
{
|
||
if (horizontal && vertical)
|
||
gimp_image_undo_group_start (image,
|
||
GIMP_UNDO_GROUP_GUIDE,
|
||
_("Add Guides"));
|
||
|
||
if (horizontal)
|
||
gimp_image_add_hguide (image, y, TRUE);
|
||
|
||
if (vertical)
|
||
gimp_image_add_vguide (image, x, TRUE);
|
||
|
||
if (horizontal && vertical)
|
||
gimp_image_undo_group_end (image);
|
||
|
||
gimp_image_flush (image);
|
||
}
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_start (GimpMeasureTool *measure,
|
||
GimpDisplay *display,
|
||
const GimpCoords *coords)
|
||
{
|
||
GimpTool *tool = GIMP_TOOL (measure);
|
||
GimpDisplayShell *shell = gimp_display_get_shell (display);
|
||
GimpMeasureOptions *options = GIMP_MEASURE_TOOL_GET_OPTIONS (tool);
|
||
|
||
measure->n_points = 1;
|
||
measure->x[0] = coords->x;
|
||
measure->y[0] = coords->y;
|
||
measure->x[1] = 0;
|
||
measure->y[1] = 0;
|
||
measure->x[2] = 0;
|
||
measure->y[2] = 0;
|
||
|
||
measure->widget = gimp_tool_compass_new (shell,
|
||
options->orientation,
|
||
measure->n_points,
|
||
measure->x[0],
|
||
measure->y[0],
|
||
measure->x[1],
|
||
measure->y[1],
|
||
measure->x[2],
|
||
measure->y[2]);
|
||
|
||
gimp_draw_tool_set_widget (GIMP_DRAW_TOOL (tool), measure->widget);
|
||
|
||
g_object_bind_property (options, "orientation",
|
||
measure->widget, "orientation",
|
||
G_BINDING_DEFAULT);
|
||
|
||
g_signal_connect (measure->widget, "changed",
|
||
G_CALLBACK (gimp_measure_tool_compass_changed),
|
||
measure);
|
||
g_signal_connect (measure->widget, "response",
|
||
G_CALLBACK (gimp_measure_tool_compass_response),
|
||
measure);
|
||
g_signal_connect (measure->widget, "status",
|
||
G_CALLBACK (gimp_measure_tool_compass_status),
|
||
measure);
|
||
g_signal_connect (measure->widget, "create-guides",
|
||
G_CALLBACK (gimp_measure_tool_compass_create_guides),
|
||
measure);
|
||
g_signal_connect (options->straighten_button, "clicked",
|
||
G_CALLBACK (gimp_measure_tool_straighten_button_clicked),
|
||
measure);
|
||
|
||
tool->display = display;
|
||
|
||
gimp_draw_tool_start (GIMP_DRAW_TOOL (measure), display);
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_halt (GimpMeasureTool *measure)
|
||
{
|
||
GimpMeasureOptions *options = GIMP_MEASURE_TOOL_GET_OPTIONS (measure);
|
||
GimpTool *tool = GIMP_TOOL (measure);
|
||
|
||
if (options->straighten_button)
|
||
{
|
||
gtk_widget_set_sensitive (options->straighten_button, FALSE);
|
||
|
||
g_signal_handlers_disconnect_by_func (
|
||
options->straighten_button,
|
||
G_CALLBACK (gimp_measure_tool_straighten_button_clicked),
|
||
measure);
|
||
}
|
||
|
||
if (tool->display)
|
||
gimp_tool_pop_status (tool, tool->display);
|
||
|
||
if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (measure)))
|
||
gimp_draw_tool_stop (GIMP_DRAW_TOOL (measure));
|
||
|
||
gimp_draw_tool_set_widget (GIMP_DRAW_TOOL (tool), NULL);
|
||
g_clear_object (&measure->widget);
|
||
|
||
g_clear_object (&measure->gui);
|
||
|
||
tool->display = NULL;
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_dialog_update (GimpMeasureTool *measure,
|
||
GimpDisplay *display)
|
||
{
|
||
GimpDisplayShell *shell = gimp_display_get_shell (display);
|
||
GimpImage *image = gimp_display_get_image (display);
|
||
gint ax, ay;
|
||
gint bx, by;
|
||
gint pixel_width;
|
||
gint pixel_height;
|
||
gdouble unit_width;
|
||
gdouble unit_height;
|
||
gdouble pixel_distance;
|
||
gdouble unit_distance;
|
||
gdouble inch_distance;
|
||
gdouble pixel_angle;
|
||
gdouble unit_angle;
|
||
gdouble xres;
|
||
gdouble yres;
|
||
gchar format[128];
|
||
gint unit_distance_digits = 0;
|
||
gint unit_width_digits;
|
||
gint unit_height_digits;
|
||
|
||
/* calculate distance and angle */
|
||
ax = measure->x[1] - measure->x[0];
|
||
ay = measure->y[1] - measure->y[0];
|
||
|
||
if (measure->n_points == 3)
|
||
{
|
||
bx = measure->x[2] - measure->x[0];
|
||
by = measure->y[2] - measure->y[0];
|
||
}
|
||
else
|
||
{
|
||
bx = 0;
|
||
by = 0;
|
||
}
|
||
|
||
pixel_width = ABS (ax - bx);
|
||
pixel_height = ABS (ay - by);
|
||
|
||
gimp_image_get_resolution (image, &xres, &yres);
|
||
|
||
unit_width = gimp_pixels_to_units (pixel_width, shell->unit, xres);
|
||
unit_height = gimp_pixels_to_units (pixel_height, shell->unit, yres);
|
||
|
||
pixel_distance = sqrt (SQR (ax - bx) + SQR (ay - by));
|
||
inch_distance = sqrt (SQR ((gdouble) (ax - bx) / xres) +
|
||
SQR ((gdouble) (ay - by) / yres));
|
||
unit_distance = gimp_unit_get_factor (shell->unit) * inch_distance;
|
||
|
||
g_object_get (measure->widget,
|
||
"pixel-angle", &pixel_angle,
|
||
"unit-angle", &unit_angle,
|
||
NULL);
|
||
|
||
pixel_angle = fabs (pixel_angle * 180.0 / G_PI);
|
||
unit_angle = fabs (unit_angle * 180.0 / G_PI);
|
||
|
||
/* Compute minimum digits to display accurate values, so that
|
||
* every pixel shows a different value in unit.
|
||
*/
|
||
if (inch_distance)
|
||
unit_distance_digits = gimp_unit_get_scaled_digits (shell->unit,
|
||
pixel_distance /
|
||
inch_distance);
|
||
unit_width_digits = gimp_unit_get_scaled_digits (shell->unit, xres);
|
||
unit_height_digits = gimp_unit_get_scaled_digits (shell->unit, yres);
|
||
|
||
if (shell->unit == GIMP_UNIT_PIXEL)
|
||
{
|
||
gimp_tool_replace_status (GIMP_TOOL (measure), display,
|
||
"%.1f %s, %.2f\302\260 (%d × %d)",
|
||
pixel_distance, _("pixels"), pixel_angle,
|
||
pixel_width, pixel_height);
|
||
}
|
||
else
|
||
{
|
||
g_snprintf (format, sizeof (format),
|
||
"%%.%df %s, %%.2f\302\260 (%%.%df × %%.%df)",
|
||
unit_distance_digits,
|
||
gimp_unit_get_plural (shell->unit),
|
||
unit_width_digits,
|
||
unit_height_digits);
|
||
|
||
gimp_tool_replace_status (GIMP_TOOL (measure), display, format,
|
||
unit_distance, unit_angle,
|
||
unit_width, unit_height);
|
||
}
|
||
|
||
if (measure->gui)
|
||
{
|
||
gchar buf[128];
|
||
|
||
/* Distance */
|
||
g_snprintf (buf, sizeof (buf), "%.1f", pixel_distance);
|
||
gtk_label_set_text (GTK_LABEL (measure->distance_label[0]), buf);
|
||
|
||
if (shell->unit != GIMP_UNIT_PIXEL)
|
||
{
|
||
g_snprintf (format, sizeof (format), "%%.%df",
|
||
unit_distance_digits);
|
||
g_snprintf (buf, sizeof (buf), format, unit_distance);
|
||
gtk_label_set_text (GTK_LABEL (measure->distance_label[1]), buf);
|
||
|
||
gtk_label_set_text (GTK_LABEL (measure->unit_label[0]),
|
||
gimp_unit_get_plural (shell->unit));
|
||
}
|
||
else
|
||
{
|
||
gtk_label_set_text (GTK_LABEL (measure->distance_label[1]), NULL);
|
||
gtk_label_set_text (GTK_LABEL (measure->unit_label[0]), NULL);
|
||
}
|
||
|
||
/* Angle */
|
||
g_snprintf (buf, sizeof (buf), "%.2f", pixel_angle);
|
||
gtk_label_set_text (GTK_LABEL (measure->angle_label[0]), buf);
|
||
|
||
if (fabs (unit_angle - pixel_angle) > 0.01)
|
||
{
|
||
g_snprintf (buf, sizeof (buf), "%.2f", unit_angle);
|
||
gtk_label_set_text (GTK_LABEL (measure->angle_label[1]), buf);
|
||
|
||
gtk_label_set_text (GTK_LABEL (measure->unit_label[1]), "\302\260");
|
||
}
|
||
else
|
||
{
|
||
gtk_label_set_text (GTK_LABEL (measure->angle_label[1]), NULL);
|
||
gtk_label_set_text (GTK_LABEL (measure->unit_label[1]), NULL);
|
||
}
|
||
|
||
/* Width */
|
||
g_snprintf (buf, sizeof (buf), "%d", pixel_width);
|
||
gtk_label_set_text (GTK_LABEL (measure->width_label[0]), buf);
|
||
|
||
if (shell->unit != GIMP_UNIT_PIXEL)
|
||
{
|
||
g_snprintf (format, sizeof (format), "%%.%df",
|
||
unit_width_digits);
|
||
g_snprintf (buf, sizeof (buf), format, unit_width);
|
||
gtk_label_set_text (GTK_LABEL (measure->width_label[1]), buf);
|
||
|
||
gtk_label_set_text (GTK_LABEL (measure->unit_label[2]),
|
||
gimp_unit_get_plural (shell->unit));
|
||
}
|
||
else
|
||
{
|
||
gtk_label_set_text (GTK_LABEL (measure->width_label[1]), NULL);
|
||
gtk_label_set_text (GTK_LABEL (measure->unit_label[2]), NULL);
|
||
}
|
||
|
||
g_snprintf (buf, sizeof (buf), "%d", pixel_height);
|
||
gtk_label_set_text (GTK_LABEL (measure->height_label[0]), buf);
|
||
|
||
/* Height */
|
||
if (shell->unit != GIMP_UNIT_PIXEL)
|
||
{
|
||
g_snprintf (format, sizeof (format), "%%.%df",
|
||
unit_height_digits);
|
||
g_snprintf (buf, sizeof (buf), format, unit_height);
|
||
gtk_label_set_text (GTK_LABEL (measure->height_label[1]), buf);
|
||
|
||
gtk_label_set_text (GTK_LABEL (measure->unit_label[3]),
|
||
gimp_unit_get_plural (shell->unit));
|
||
}
|
||
else
|
||
{
|
||
gtk_label_set_text (GTK_LABEL (measure->height_label[1]), NULL);
|
||
gtk_label_set_text (GTK_LABEL (measure->unit_label[3]), NULL);
|
||
}
|
||
|
||
gimp_tool_gui_show (measure->gui);
|
||
}
|
||
}
|
||
|
||
static GimpToolGui *
|
||
gimp_measure_tool_dialog_new (GimpMeasureTool *measure)
|
||
{
|
||
GimpTool *tool = GIMP_TOOL (measure);
|
||
GimpDisplayShell *shell;
|
||
GimpToolGui *gui;
|
||
GtkWidget *table;
|
||
GtkWidget *label;
|
||
|
||
g_return_val_if_fail (tool->display != NULL, NULL);
|
||
|
||
shell = gimp_display_get_shell (tool->display);
|
||
|
||
gui = gimp_tool_gui_new (tool->tool_info,
|
||
NULL,
|
||
_("Measure Distances and Angles"),
|
||
NULL, NULL,
|
||
gtk_widget_get_screen (GTK_WIDGET (shell)),
|
||
gimp_widget_get_monitor (GTK_WIDGET (shell)),
|
||
TRUE,
|
||
|
||
_("_Close"), GTK_RESPONSE_CLOSE,
|
||
|
||
NULL);
|
||
|
||
gimp_tool_gui_set_auto_overlay (gui, TRUE);
|
||
gimp_tool_gui_set_focus_on_map (gui, FALSE);
|
||
|
||
g_signal_connect (gui, "response",
|
||
G_CALLBACK (g_object_unref),
|
||
NULL);
|
||
|
||
table = gtk_table_new (4, 5, TRUE);
|
||
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
|
||
gtk_table_set_row_spacings (GTK_TABLE (table), 6);
|
||
gtk_box_pack_start (GTK_BOX (gimp_tool_gui_get_vbox (gui)), table,
|
||
TRUE, TRUE, 0);
|
||
gtk_widget_show (table);
|
||
|
||
|
||
label = gtk_label_new (_("Distance:"));
|
||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
|
||
gtk_widget_show (label);
|
||
|
||
measure->distance_label[0] = label = gtk_label_new ("0.0");
|
||
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 0, 1);
|
||
gtk_widget_show (label);
|
||
|
||
label = gtk_label_new (_("pixels"));
|
||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 0, 1);
|
||
gtk_widget_show (label);
|
||
|
||
measure->distance_label[1] = label = gtk_label_new ("0.0");
|
||
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 3, 4, 0, 1);
|
||
gtk_widget_show (label);
|
||
|
||
measure->unit_label[0] = label = gtk_label_new (NULL);
|
||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 4, 5, 0, 1);
|
||
gtk_widget_show (label);
|
||
|
||
|
||
label = gtk_label_new (_("Angle:"));
|
||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
|
||
gtk_widget_show (label);
|
||
|
||
measure->angle_label[0] = label = gtk_label_new ("0.0");
|
||
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 1, 2);
|
||
gtk_widget_show (label);
|
||
|
||
label = gtk_label_new ("\302\260");
|
||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 1, 2);
|
||
gtk_widget_show (label);
|
||
|
||
measure->angle_label[1] = label = gtk_label_new (NULL);
|
||
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 3, 4, 1, 2);
|
||
gtk_widget_show (label);
|
||
|
||
measure->unit_label[1] = label = gtk_label_new (NULL);
|
||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 4, 5, 1, 2);
|
||
gtk_widget_show (label);
|
||
|
||
|
||
label = gtk_label_new (_("Width:"));
|
||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3);
|
||
gtk_widget_show (label);
|
||
|
||
measure->width_label[0] = label = gtk_label_new ("0.0");
|
||
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 2, 3);
|
||
gtk_widget_show (label);
|
||
|
||
label = gtk_label_new (_("pixels"));
|
||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 2, 3);
|
||
gtk_widget_show (label);
|
||
|
||
measure->width_label[1] = label = gtk_label_new ("0.0");
|
||
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 3, 4, 2, 3);
|
||
gtk_widget_show (label);
|
||
|
||
measure->unit_label[2] = label = gtk_label_new (NULL);
|
||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 4, 5, 2, 3);
|
||
gtk_widget_show (label);
|
||
|
||
|
||
label = gtk_label_new (_("Height:"));
|
||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 3, 4);
|
||
gtk_widget_show (label);
|
||
|
||
measure->height_label[0] = label = gtk_label_new ("0.0");
|
||
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 3, 4);
|
||
gtk_widget_show (label);
|
||
|
||
label = gtk_label_new (_("pixels"));
|
||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 3, 4);
|
||
gtk_widget_show (label);
|
||
|
||
measure->height_label[1] = label = gtk_label_new ("0.0");
|
||
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 3, 4, 3, 4);
|
||
gtk_widget_show (label);
|
||
|
||
measure->unit_label[3] = label = gtk_label_new (NULL);
|
||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||
gtk_table_attach_defaults (GTK_TABLE (table), label, 4, 5, 3, 4);
|
||
gtk_widget_show (label);
|
||
|
||
return gui;
|
||
}
|
||
|
||
static void
|
||
gimp_measure_tool_straighten_button_clicked (GtkWidget *button,
|
||
GimpMeasureTool *measure)
|
||
{
|
||
GimpTool *tool = GIMP_TOOL (measure);
|
||
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (measure);
|
||
|
||
if (gimp_transform_tool_transform (tr_tool, tool->display))
|
||
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, tool->display);
|
||
}
|