diff options
Diffstat (limited to '')
-rw-r--r-- | libgimpwidgets/gimpbutton.c | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/libgimpwidgets/gimpbutton.c b/libgimpwidgets/gimpbutton.c new file mode 100644 index 0000000..67039ac --- /dev/null +++ b/libgimpwidgets/gimpbutton.c @@ -0,0 +1,165 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpbutton.c + * Copyright (C) 2000-2008 Michael Natterer <mitch@gimp.org> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "gimpwidgetstypes.h" + +#include "gimpbutton.h" +#include "gimp3migration.h" + + +/** + * SECTION: gimpbutton + * @title: GimpButton + * @short_description: A #GtkButton with a little extra functionality. + * + * #GimpButton adds an extra signal to the #GtkButton widget that + * allows the callback to distinguish a normal click from a click that + * was performed with modifier keys pressed. + **/ + + +enum +{ + EXTENDED_CLICKED, + LAST_SIGNAL +}; + + +static gboolean gimp_button_button_press (GtkWidget *widget, + GdkEventButton *event); +static void gimp_button_clicked (GtkButton *button); + + +G_DEFINE_TYPE (GimpButton, gimp_button, GTK_TYPE_BUTTON) + +#define parent_class gimp_button_parent_class + +static guint button_signals[LAST_SIGNAL] = { 0 }; + + +static void +gimp_button_class_init (GimpButtonClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GtkButtonClass *button_class = GTK_BUTTON_CLASS (klass); + + /** + * GimpButton::extended-clicked: + * @gimpbutton: the object that received the signal. + * @arg1: the state of modifier keys when the button was clicked + * + * This signal is emitted when the button is clicked with a modifier + * key pressed. + **/ + button_signals[EXTENDED_CLICKED] = + g_signal_new ("extended-clicked", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GimpButtonClass, extended_clicked), + NULL, NULL, + g_cclosure_marshal_VOID__FLAGS, + G_TYPE_NONE, 1, + GDK_TYPE_MODIFIER_TYPE); + + widget_class->button_press_event = gimp_button_button_press; + + button_class->clicked = gimp_button_clicked; +} + +static void +gimp_button_init (GimpButton *button) +{ + button->press_state = 0; +} + +/** + * gimp_button_new: + * + * Creates a new #GimpButton widget. + * + * Returns: A pointer to the new #GimpButton widget. + **/ +GtkWidget * +gimp_button_new (void) +{ + return g_object_new (GIMP_TYPE_BUTTON, NULL); +} + +/** + * gimp_button_extended_clicked: + * @button: a #GimpButton. + * @state: a state as found in #GdkEventButton->state, e.g. #GDK_SHIFT_MASK. + * + * Emits the button's "extended_clicked" signal. + **/ +void +gimp_button_extended_clicked (GimpButton *button, + GdkModifierType state) +{ + g_return_if_fail (GIMP_IS_BUTTON (button)); + + g_signal_emit (button, button_signals[EXTENDED_CLICKED], 0, state); +} + +static gboolean +gimp_button_button_press (GtkWidget *widget, + GdkEventButton *bevent) +{ + GimpButton *button = GIMP_BUTTON (widget); + + if (bevent->button == 1) + { + button->press_state = bevent->state; + } + else + { + button->press_state = 0; + } + + return GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, bevent); +} + +static void +gimp_button_clicked (GtkButton *button) +{ + if (GIMP_BUTTON (button)->press_state & + (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK | + gtk_widget_get_modifier_mask (GTK_WIDGET (button), + GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR) | + gtk_widget_get_modifier_mask (GTK_WIDGET (button), + GDK_MODIFIER_INTENT_EXTEND_SELECTION) | + gtk_widget_get_modifier_mask (GTK_WIDGET (button), + GDK_MODIFIER_INTENT_MODIFY_SELECTION))) + { + g_signal_stop_emission_by_name (button, "clicked"); + + gimp_button_extended_clicked (GIMP_BUTTON (button), + GIMP_BUTTON (button)->press_state); + } + else if (GTK_BUTTON_CLASS (parent_class)->clicked) + { + GTK_BUTTON_CLASS (parent_class)->clicked (button); + } +} |