Files
gimp/app/tools/gimpdodgeburntool.c
Enrico Schröder d4316902a2 app: DodgeBurn/Convolve: Fix error in behavior of modifier keys
Fix for bug #632816: When holding shift key to go to LineDraw mode,
then pressing ctrl and releasing shift before ctrl, the release of
ctrl switches the function of DodgeBurn and Convolute tool. This patch
adds a variable to GimpDodgeBurnTool/GimpConvolveTool to only switch
said function on releasing ctrl when it has been toggled previously.
2011-04-04 00:38:01 +02:00

237 lines
8.0 KiB
C

/* 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/>.
*/
#include "config.h"
#include <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "paint/gimpdodgeburnoptions.h"
#include "widgets/gimphelp-ids.h"
#include "widgets/gimppropwidgets.h"
#include "widgets/gimpwidgets-utils.h"
#include "gimpdodgeburntool.h"
#include "gimppaintoptions-gui.h"
#include "gimptoolcontrol.h"
#include "gimp-intl.h"
static void gimp_dodge_burn_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *display);
static void gimp_dodge_burn_tool_cursor_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
GimpDisplay *display);
static void gimp_dodge_burn_tool_oper_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
gboolean proximity,
GimpDisplay *display);
static void gimp_dodge_burn_tool_status_update (GimpTool *tool,
GimpDodgeBurnType type);
static GtkWidget * gimp_dodge_burn_options_gui (GimpToolOptions *tool_options);
G_DEFINE_TYPE (GimpDodgeBurnTool, gimp_dodge_burn_tool, GIMP_TYPE_BRUSH_TOOL)
#define parent_class gimp_dodge_burn_tool_parent_class
void
gimp_dodge_burn_tool_register (GimpToolRegisterCallback callback,
gpointer data)
{
(* callback) (GIMP_TYPE_DODGE_BURN_TOOL,
GIMP_TYPE_DODGE_BURN_OPTIONS,
gimp_dodge_burn_options_gui,
GIMP_PAINT_OPTIONS_CONTEXT_MASK,
"gimp-dodge-burn-tool",
_("Dodge / Burn"),
_("Dodge / Burn Tool: Selectively lighten or darken using a brush"),
N_("Dod_ge / Burn"), "<shift>D",
NULL, GIMP_HELP_TOOL_DODGE_BURN,
GIMP_STOCK_TOOL_DODGE,
data);
}
static void
gimp_dodge_burn_tool_class_init (GimpDodgeBurnToolClass *klass)
{
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
tool_class->modifier_key = gimp_dodge_burn_tool_modifier_key;
tool_class->cursor_update = gimp_dodge_burn_tool_cursor_update;
tool_class->oper_update = gimp_dodge_burn_tool_oper_update;
}
static void
gimp_dodge_burn_tool_init (GimpDodgeBurnTool *dodgeburn)
{
GimpTool *tool = GIMP_TOOL (dodgeburn);
gimp_tool_control_set_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_DODGE);
gimp_tool_control_set_toggle_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_BURN);
gimp_dodge_burn_tool_status_update (tool, GIMP_BURN);
}
static void
gimp_dodge_burn_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *display)
{
GimpDodgeBurnTool *dodgeburn = GIMP_DODGE_BURN_TOOL (tool);
GimpDodgeBurnOptions *options = GIMP_DODGE_BURN_TOOL_GET_OPTIONS (tool);
if ((key == GDK_CONTROL_MASK &&
! (state & GDK_SHIFT_MASK) && /* leave stuff untouched in line draw mode */
press != dodgeburn->toggled)
||
(key == GDK_SHIFT_MASK && /* toggle back after keypresses CTRL(hold)-> */
! press && /* SHIFT(hold)->CTRL(release)->SHIFT(release) */
dodgeburn->toggled &&
! (state & GDK_CONTROL_MASK)))
{
dodgeburn->toggled = press;
switch (options->type)
{
case GIMP_DODGE:
g_object_set (options, "type", GIMP_BURN, NULL);
break;
case GIMP_BURN:
g_object_set (options, "type", GIMP_DODGE, NULL);
break;
default:
break;
}
}
GIMP_TOOL_CLASS (parent_class)->modifier_key (tool, key, press, state,
display);
}
static void
gimp_dodge_burn_tool_cursor_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
GimpDisplay *display)
{
GimpDodgeBurnOptions *options = GIMP_DODGE_BURN_TOOL_GET_OPTIONS (tool);
gimp_tool_control_set_toggled (tool->control, (options->type == GIMP_BURN));
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state,
display);
}
static void
gimp_dodge_burn_tool_oper_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
gboolean proximity,
GimpDisplay *display)
{
GimpDodgeBurnOptions *options = GIMP_DODGE_BURN_TOOL_GET_OPTIONS (tool);
gimp_dodge_burn_tool_status_update (tool, options->type);
GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, proximity,
display);
}
static void
gimp_dodge_burn_tool_status_update (GimpTool *tool,
GimpDodgeBurnType type)
{
GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (tool);
switch (type)
{
case GIMP_DODGE:
paint_tool->status = _("Click to dodge");
paint_tool->status_line = _("Click to dodge the line");
paint_tool->status_ctrl = _("%s to burn");
break;
case GIMP_BURN:
paint_tool->status = _("Click to burn");
paint_tool->status_line = _("Click to burn the line");
paint_tool->status_ctrl = _("%s to dodge");
break;
default:
break;
}
}
/* tool options stuff */
static GtkWidget *
gimp_dodge_burn_options_gui (GimpToolOptions *tool_options)
{
GObject *config = G_OBJECT (tool_options);
GtkWidget *vbox = gimp_paint_options_gui (tool_options);
GtkWidget *frame;
GtkWidget *scale;
gchar *str;
/* the type (dodge or burn) */
str = g_strdup_printf (_("Type (%s)"),
gimp_get_mod_string (GDK_CONTROL_MASK));
frame = gimp_prop_enum_radio_frame_new (config, "type",
str, 0, 0);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
g_free (str);
/* mode (highlights, midtones, or shadows) */
frame = gimp_prop_enum_radio_frame_new (config, "mode", _("Range"), 0, 0);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
/* the exposure scale */
scale = gimp_prop_spin_scale_new (config, "exposure",
_("Exposure"),
1.0, 10.0, 1);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
gtk_widget_show (scale);
return vbox;
}