1
/* The GIMP -- an image manipulation program
2
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
4
* gimpcellrendererviewable.c
5
* Copyright (C) 2003 Michael Natterer <mitch@gimp.org>
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 2 of the License, or
10
* (at your option) any later version.
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.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
#include "widgets-types.h"
28
#include "core/gimpmarshal.h"
29
#include "core/gimpviewable.h"
31
#include "gimpcellrendererviewable.h"
32
#include "gimpview-popup.h"
33
#include "gimpviewrenderer.h"
49
static void gimp_cell_renderer_viewable_class_init (GimpCellRendererViewableClass *klass);
50
static void gimp_cell_renderer_viewable_init (GimpCellRendererViewable *cell);
52
static void gimp_cell_renderer_viewable_finalize (GObject *object);
53
static void gimp_cell_renderer_viewable_get_property (GObject *object,
57
static void gimp_cell_renderer_viewable_set_property (GObject *object,
61
static void gimp_cell_renderer_viewable_get_size (GtkCellRenderer *cell,
63
GdkRectangle *rectangle,
68
static void gimp_cell_renderer_viewable_render (GtkCellRenderer *cell,
71
GdkRectangle *background_area,
72
GdkRectangle *cell_area,
73
GdkRectangle *expose_area,
74
GtkCellRendererState flags);
75
static gboolean gimp_cell_renderer_viewable_activate (GtkCellRenderer *cell,
79
GdkRectangle *background_area,
80
GdkRectangle *cell_area,
81
GtkCellRendererState flags);
84
static guint viewable_cell_signals[LAST_SIGNAL] = { 0 };
86
static GtkCellRendererClass *parent_class = NULL;
90
gimp_cell_renderer_viewable_get_type (void)
92
static GType cell_type = 0;
96
static const GTypeInfo cell_info =
98
sizeof (GimpCellRendererViewableClass),
100
NULL, /* base_finalize */
101
(GClassInitFunc) gimp_cell_renderer_viewable_class_init,
102
NULL, /* class_finalize */
103
NULL, /* class_data */
104
sizeof (GimpCellRendererViewable),
106
(GInstanceInitFunc) gimp_cell_renderer_viewable_init,
109
cell_type = g_type_register_static (GTK_TYPE_CELL_RENDERER,
110
"GimpCellRendererViewable",
118
gimp_cell_renderer_viewable_class_init (GimpCellRendererViewableClass *klass)
120
GObjectClass *object_class = G_OBJECT_CLASS (klass);
121
GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass);
123
parent_class = g_type_class_peek_parent (klass);
125
viewable_cell_signals[CLICKED] =
126
g_signal_new ("clicked",
127
G_OBJECT_CLASS_TYPE (object_class),
129
G_STRUCT_OFFSET (GimpCellRendererViewableClass, clicked),
131
gimp_marshal_VOID__STRING_FLAGS,
134
GDK_TYPE_MODIFIER_TYPE);
136
object_class->finalize = gimp_cell_renderer_viewable_finalize;
137
object_class->get_property = gimp_cell_renderer_viewable_get_property;
138
object_class->set_property = gimp_cell_renderer_viewable_set_property;
140
cell_class->get_size = gimp_cell_renderer_viewable_get_size;
141
cell_class->render = gimp_cell_renderer_viewable_render;
142
cell_class->activate = gimp_cell_renderer_viewable_activate;
144
klass->clicked = NULL;
146
g_object_class_install_property (object_class,
148
g_param_spec_object ("renderer",
150
GIMP_TYPE_VIEW_RENDERER,
155
gimp_cell_renderer_viewable_init (GimpCellRendererViewable *cellviewable)
157
GTK_CELL_RENDERER (cellviewable)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
161
gimp_cell_renderer_viewable_finalize (GObject *object)
163
GimpCellRendererViewable *cell = GIMP_CELL_RENDERER_VIEWABLE (object);
167
g_object_unref (cell->renderer);
168
cell->renderer = NULL;
171
G_OBJECT_CLASS (parent_class)->finalize (object);
175
gimp_cell_renderer_viewable_get_property (GObject *object,
180
GimpCellRendererViewable *cell = GIMP_CELL_RENDERER_VIEWABLE (object);
185
g_value_set_object (value, cell->renderer);
189
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
195
gimp_cell_renderer_viewable_set_property (GObject *object,
200
GimpCellRendererViewable *cell = GIMP_CELL_RENDERER_VIEWABLE (object);
206
GimpViewRenderer *renderer;
208
renderer = (GimpViewRenderer *) g_value_dup_object (value);
210
g_object_unref (cell->renderer);
211
cell->renderer = renderer;
216
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
222
gimp_cell_renderer_viewable_get_size (GtkCellRenderer *cell,
224
GdkRectangle *cell_area,
230
GimpCellRendererViewable *cellviewable;
232
gint view_height = 0;
236
cellviewable = GIMP_CELL_RENDERER_VIEWABLE (cell);
238
if (cellviewable->renderer)
240
view_width = (cellviewable->renderer->width +
241
2 * cellviewable->renderer->border_width);
242
view_height = (cellviewable->renderer->height +
243
2 * cellviewable->renderer->border_width);
246
calc_width = (gint) cell->xpad * 2 + view_width;
247
calc_height = (gint) cell->ypad * 2 + view_height;
249
if (x_offset) *x_offset = 0;
250
if (y_offset) *y_offset = 0;
252
if (cell_area && view_width > 0 && view_height > 0)
256
*x_offset = (((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ?
257
1.0 - cell->xalign : cell->xalign) *
258
(cell_area->width - calc_width - 2 * cell->xpad));
259
*x_offset = (MAX (*x_offset, 0) + cell->xpad);
263
*y_offset = (cell->yalign *
264
(cell_area->height - calc_height - 2 * cell->ypad));
265
*y_offset = (MAX (*y_offset, 0) + cell->ypad);
269
if (width) *width = calc_width;
270
if (height) *height = calc_height;
274
gimp_cell_renderer_viewable_render (GtkCellRenderer *cell,
277
GdkRectangle *background_area,
278
GdkRectangle *cell_area,
279
GdkRectangle *expose_area,
280
GtkCellRendererState flags)
282
GimpCellRendererViewable *cellviewable;
284
cellviewable = GIMP_CELL_RENDERER_VIEWABLE (cell);
286
if (cellviewable->renderer)
288
if (! (flags & GTK_CELL_RENDERER_SELECTED))
290
/* this is an ugly hack. The cell state should be passed to
291
* the view renderer, so that it can adjust its border.
292
* (or something like this) */
293
if (cellviewable->renderer->border_type == GIMP_VIEW_BORDER_WHITE)
294
gimp_view_renderer_set_border_type (cellviewable->renderer,
295
GIMP_VIEW_BORDER_BLACK);
297
gimp_view_renderer_remove_idle (cellviewable->renderer);
300
gimp_view_renderer_draw (cellviewable->renderer, window, widget,
301
cell_area, expose_area);
306
gimp_cell_renderer_viewable_activate (GtkCellRenderer *cell,
310
GdkRectangle *background_area,
311
GdkRectangle *cell_area,
312
GtkCellRendererState flags)
314
GimpCellRendererViewable *cellviewable;
316
cellviewable = GIMP_CELL_RENDERER_VIEWABLE (cell);
318
if (cellviewable->renderer)
320
GdkModifierType state = 0;
322
if (event && ((GdkEventAny *) event)->type == GDK_BUTTON_PRESS)
323
state = ((GdkEventButton *) event)->state;
326
(((GdkEventAny *) event)->type == GDK_BUTTON_PRESS &&
327
((GdkEventButton *) event)->button == 1))
329
gimp_cell_renderer_viewable_clicked (cellviewable, path, state);
339
gimp_cell_renderer_viewable_new (void)
341
return g_object_new (GIMP_TYPE_CELL_RENDERER_VIEWABLE, NULL);
345
gimp_cell_renderer_viewable_clicked (GimpCellRendererViewable *cell,
347
GdkModifierType state)
351
g_return_if_fail (GIMP_IS_CELL_RENDERER_VIEWABLE (cell));
352
g_return_if_fail (path != NULL);
354
g_signal_emit (cell, viewable_cell_signals[CLICKED], 0, path, state);
356
event = gtk_get_current_event ();
360
GdkEventButton *bevent = (GdkEventButton *) event;
362
if (bevent->type == GDK_BUTTON_PRESS &&
363
(bevent->button == 1 || bevent->button == 2))
365
gimp_view_popup_show (gtk_get_event_widget (event),
367
cell->renderer->viewable,
368
cell->renderer->width,
369
cell->renderer->height,
370
cell->renderer->dot_for_dot);
373
gdk_event_free (event);