1 /* GIMP - The GNU Image Manipulation Program
2  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3  *
4  * gimpcellrendererbutton.c
5  * Copyright (C) 2016 Michael Natterer <mitch@gimp.org>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  */
20 
21 #include <config.h>
22 
23 #include <gtk/gtk.h>
24 
25 #include "widgets-types.h"
26 
27 #include "core/gimpmarshal.h"
28 
29 #include "gimpcellrendererbutton.h"
30 
31 
32 enum
33 {
34   CLICKED,
35   LAST_SIGNAL
36 };
37 
38 
39 static gboolean gimp_cell_renderer_button_activate (GtkCellRenderer     *cell,
40                                                     GdkEvent            *event,
41                                                     GtkWidget           *widget,
42                                                     const gchar         *path,
43                                                     GdkRectangle        *background_area,
44                                                     GdkRectangle        *cell_area,
45                                                     GtkCellRendererState flags);
46 
47 
48 G_DEFINE_TYPE (GimpCellRendererButton, gimp_cell_renderer_button,
49                GTK_TYPE_CELL_RENDERER_PIXBUF)
50 
51 #define parent_class gimp_cell_renderer_button_parent_class
52 
53 static guint button_cell_signals[LAST_SIGNAL] = { 0 };
54 
55 
56 static void
gimp_cell_renderer_button_class_init(GimpCellRendererButtonClass * klass)57 gimp_cell_renderer_button_class_init (GimpCellRendererButtonClass *klass)
58 {
59   GObjectClass         *object_class = G_OBJECT_CLASS (klass);
60   GtkCellRendererClass *cell_class   = GTK_CELL_RENDERER_CLASS (klass);
61 
62   /**
63    * GimpCellRendererButton::clicked:
64    * @cell:
65    * @path:
66    * @state:
67    *
68    * Called on a button cell when it is clicked.
69    **/
70   button_cell_signals[CLICKED] =
71     g_signal_new ("clicked",
72                   G_OBJECT_CLASS_TYPE (object_class),
73                   G_SIGNAL_RUN_LAST,
74                   G_STRUCT_OFFSET (GimpCellRendererButtonClass, clicked),
75                   NULL, NULL,
76                   gimp_marshal_VOID__STRING_FLAGS,
77                   G_TYPE_NONE, 2,
78                   G_TYPE_STRING,
79                   GDK_TYPE_MODIFIER_TYPE);
80 
81   cell_class->activate = gimp_cell_renderer_button_activate;
82 
83   klass->clicked       = NULL;
84 }
85 
86 static void
gimp_cell_renderer_button_init(GimpCellRendererButton * cell_button)87 gimp_cell_renderer_button_init (GimpCellRendererButton *cell_button)
88 {
89   g_object_set (cell_button,
90                 "mode",       GTK_CELL_RENDERER_MODE_ACTIVATABLE,
91                 "xpad",       2,
92                 "ypad",       2,
93                 "stock-size", GTK_ICON_SIZE_BUTTON,
94                 NULL);
95 }
96 
97 static gboolean
gimp_cell_renderer_button_activate(GtkCellRenderer * cell,GdkEvent * event,GtkWidget * widget,const gchar * path,GdkRectangle * background_area,GdkRectangle * cell_area,GtkCellRendererState flags)98 gimp_cell_renderer_button_activate (GtkCellRenderer      *cell,
99                                     GdkEvent             *event,
100                                     GtkWidget            *widget,
101                                     const gchar          *path,
102                                     GdkRectangle         *background_area,
103                                     GdkRectangle         *cell_area,
104                                     GtkCellRendererState  flags)
105 {
106   GimpCellRendererButton *cell_button = GIMP_CELL_RENDERER_BUTTON (cell);
107   GdkModifierType         state       = 0;
108 
109   if (event && ((GdkEventAny *) event)->type == GDK_BUTTON_PRESS)
110     state = ((GdkEventButton *) event)->state;
111 
112   if (! event ||
113       (((GdkEventAny *) event)->type == GDK_BUTTON_PRESS &&
114        ((GdkEventButton *) event)->button == 1))
115     {
116       gimp_cell_renderer_button_clicked (cell_button, path, state);
117 
118       return TRUE;
119     }
120 
121   return FALSE;
122 }
123 
124 
125 /*  public functions  */
126 
127 GtkCellRenderer *
gimp_cell_renderer_button_new(void)128 gimp_cell_renderer_button_new (void)
129 {
130   return g_object_new (GIMP_TYPE_CELL_RENDERER_BUTTON, NULL);
131 }
132 
133 void
gimp_cell_renderer_button_clicked(GimpCellRendererButton * cell,const gchar * path,GdkModifierType state)134 gimp_cell_renderer_button_clicked (GimpCellRendererButton *cell,
135                                    const gchar            *path,
136                                    GdkModifierType         state)
137 {
138   g_return_if_fail (GIMP_IS_CELL_RENDERER_BUTTON (cell));
139   g_return_if_fail (path != NULL);
140 
141   g_signal_emit (cell, button_cell_signals[CLICKED], 0, path, state);
142 }
143