1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
4
/* ***** BEGIN LICENSE BLOCK *****
5
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
7
* The contents of this file are subject to the Mozilla Public License Version
8
* 1.1 (the "License"); you may not use this file except in compliance with
9
* the License. You may obtain a copy of the License at
10
* http://www.mozilla.org/MPL/
12
* Software distributed under the License is distributed on an "AS IS" basis,
13
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14
* for the specific language governing rights and limitations under the
17
* The Original Code is Eek Preview Stuffs.
19
* The Initial Developer of the Original Code is
21
* Portions created by the Initial Developer are Copyright (C) 2005
22
* the Initial Developer. All Rights Reserved.
26
* Alternatively, the contents of this file may be used under the terms of
27
* either the GNU General Public License Version 2 or later (the "GPL"), or
28
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
* in which case the provisions of the GPL or the LGPL are applicable instead
30
* of those above. If you wish to allow use of your version of this file only
31
* under the terms of either the GPL or the LGPL, and not to allow others to
32
* use your version of this file under the terms of the MPL, indicate your
33
* decision by deleting the provisions above and replace them with the notice
34
* and other provisions required by the GPL or the LGPL. If you do not delete
35
* the provisions above, a recipient may use your version of this file under
36
* the terms of any one of the MPL, the GPL or the LGPL.
38
* ***** END LICENSE BLOCK ***** */
41
#include "eek-preview.h"
43
#define PRIME_BUTTON_MAGIC_NUMBER 1
45
#define FOCUS_PROP_ID 1
49
static void eek_preview_class_init( EekPreviewClass *klass );
50
static void eek_preview_init( EekPreview *preview );
52
static GtkWidgetClass* parent_class = 0;
54
void eek_preview_set_color( EekPreview* preview, int r, int g, int b )
62
GType eek_preview_get_type(void)
64
static GType preview_type = 0;
67
static const GTypeInfo preview_info = {
68
sizeof( EekPreviewClass ),
70
NULL, /* base_finalize */
71
(GClassInitFunc)eek_preview_class_init,
72
NULL, /* class_finalize */
73
NULL, /* class_data */
76
(GInstanceInitFunc)eek_preview_init,
77
NULL /* value_table */
81
preview_type = g_type_register_static( GTK_TYPE_DRAWING_AREA, "EekPreview", &preview_info, (GTypeFlags)0 );
87
GtkWidget* eek_preview_area_new(void)
92
static void eek_preview_size_request( GtkWidget* widget, GtkRequisition* req )
96
EekPreview* preview = EEK_PREVIEW(widget);
97
gboolean worked = gtk_icon_size_lookup( preview->_size, &width, &height );
102
if ( preview->_view == VIEW_TYPE_LIST ) {
106
req->height = height;
116
static guint eek_preview_signals[LAST_SIGNAL] = { 0 };
119
gboolean eek_preview_expose_event( GtkWidget* widget, GdkEventExpose* event )
121
/* g_message("Exposed!!! %s", GTK_WIDGET_HAS_FOCUS(widget) ? "XXX" : "---" ); */
126
gint lower = widget->allocation.width;
127
lower = (widget->allocation.height < lower) ? widget->allocation.height : lower;
146
if ( GTK_WIDGET_DRAWABLE( widget ) ) {
147
GtkStyle* style = gtk_widget_get_style( widget );
149
if ( insetX > 0 || insetY > 0 ) {
150
gtk_paint_flat_box( style,
152
(GtkStateType)GTK_WIDGET_STATE(widget),
158
widget->allocation.width, widget->allocation.height);
161
GdkGC *gc = gdk_gc_new( widget->window );
162
EekPreview* preview = EEK_PREVIEW(widget);
163
GdkColor fg = {0, preview->_r, preview->_g, preview->_b};
164
gdk_colormap_alloc_color( gdk_colormap_get_system(), &fg, FALSE, TRUE );
166
gdk_gc_set_foreground( gc, &fg );
168
gdk_draw_rectangle( widget->window,
172
widget->allocation.width - (insetX * 2), widget->allocation.height - (insetY * 2) );
174
if ( GTK_WIDGET_HAS_FOCUS(widget) ) {
175
gtk_paint_focus( style,
178
NULL, /* GdkRectangle *area, */
182
widget->allocation.width - 2, widget->allocation.height - 2 );
191
static gboolean eek_preview_enter_cb( GtkWidget* widget, GdkEventCrossing* event )
193
if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) {
194
EekPreview* preview = EEK_PREVIEW(widget);
195
preview->_within = TRUE;
196
gtk_widget_set_state( widget, preview->_hot ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT );
201
static gboolean eek_preview_leave_cb( GtkWidget* widget, GdkEventCrossing* event )
203
if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) {
204
EekPreview* preview = EEK_PREVIEW(widget);
205
preview->_within = FALSE;
206
gtk_widget_set_state( widget, GTK_STATE_NORMAL );
212
static gboolean eek_preview_focus_in_event( GtkWidget* widget, GdkEventFocus* event )
214
g_message("focus IN");
215
gboolean blip = parent_class->focus_in_event ? parent_class->focus_in_event(widget, event) : FALSE;
219
static gboolean eek_preview_focus_out_event( GtkWidget* widget, GdkEventFocus* event )
221
g_message("focus OUT");
222
gboolean blip = parent_class->focus_out_event ? parent_class->focus_out_event(widget, event) : FALSE;
227
static gboolean eek_preview_button_press_cb( GtkWidget* widget, GdkEventButton* event )
229
if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) {
230
EekPreview* preview = EEK_PREVIEW(widget);
232
if ( preview->_takesFocus && !GTK_WIDGET_HAS_FOCUS(widget) ) {
233
gtk_widget_grab_focus(widget);
236
if ( event->button == PRIME_BUTTON_MAGIC_NUMBER ) {
237
preview->_hot = TRUE;
238
if ( preview->_within ) {
239
gtk_widget_set_state( widget, GTK_STATE_ACTIVE );
247
static gboolean eek_preview_button_release_cb( GtkWidget* widget, GdkEventButton* event )
249
if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) {
250
EekPreview* preview = EEK_PREVIEW(widget);
251
preview->_hot = FALSE;
252
gtk_widget_set_state( widget, GTK_STATE_NORMAL );
253
if ( preview->_within && event->button == PRIME_BUTTON_MAGIC_NUMBER ) {
254
gboolean isAlt = (event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK;
257
g_signal_emit( widget, eek_preview_signals[ALTCLICKED_SIGNAL], 0, 2 );
259
g_signal_emit( widget, eek_preview_signals[CLICKED_SIGNAL], 0 );
266
gboolean eek_preview_key_press_event( GtkWidget* widget, GdkEventKey* event)
272
gboolean eek_preview_key_release_event( GtkWidget* widget, GdkEventKey* event)
278
static void eek_preview_get_property( GObject *object,
283
GObjectClass* gobjClass = G_OBJECT_CLASS(parent_class);
284
switch ( property_id ) {
287
EekPreview* preview = EEK_PREVIEW( object );
288
g_value_set_boolean( value, preview->_takesFocus );
293
if ( gobjClass->get_property ) {
294
gobjClass->get_property( object, property_id, value, pspec );
300
static void eek_preview_set_property( GObject *object,
305
GObjectClass* gobjClass = G_OBJECT_CLASS(parent_class);
306
switch ( property_id ) {
309
EekPreview* preview = EEK_PREVIEW( object );
310
gboolean val = g_value_get_boolean( value );
311
if ( val != preview->_takesFocus ) {
312
preview->_takesFocus = val;
318
if ( gobjClass->set_property ) {
319
gobjClass->set_property( object, property_id, value, pspec );
326
static gboolean eek_preview_popup_menu( GtkWidget* widget )
328
/* g_message("Do the popup!"); */
329
gboolean blip = parent_class->popup_menu ? parent_class->popup_menu(widget) : FALSE;
334
static void eek_preview_class_init( EekPreviewClass *klass )
336
GObjectClass* gobjClass = G_OBJECT_CLASS(klass);
337
/*GtkObjectClass* objectClass = (GtkObjectClass*)klass;*/
338
GtkWidgetClass* widgetClass = (GtkWidgetClass*)klass;
340
gobjClass->set_property = eek_preview_set_property;
341
gobjClass->get_property = eek_preview_get_property;
343
/*objectClass->destroy = eek_preview_destroy;*/
345
parent_class = (GtkWidgetClass*)g_type_class_peek_parent( klass );
347
/*widgetClass->map = ;*/
348
/*widgetClass->unmap = ;*/
349
/*widgetClass->realize = ;*/
350
/*widgetClass->unrealize = ;*/
351
widgetClass->size_request = eek_preview_size_request;
352
/*widgetClass->size_allocate = ;*/
353
/*widgetClass->state_changed = ;*/
354
/*widgetClass->style_set = ;*/
355
/*widgetClass->grab_notify = ;*/
357
widgetClass->button_press_event = eek_preview_button_press_cb;
358
widgetClass->button_release_event = eek_preview_button_release_cb;
359
/*widgetClass->delete_event = ;*/
360
/*widgetClass->destroy_event = ;*/
361
widgetClass->expose_event = eek_preview_expose_event;
362
/* widgetClass->key_press_event = eek_preview_key_press_event; */
363
/* widgetClass->key_release_event = eek_preview_key_release_event; */
364
widgetClass->enter_notify_event = eek_preview_enter_cb;
365
widgetClass->leave_notify_event = eek_preview_leave_cb;
366
/*widgetClass->configure_event = ;*/
367
/*widgetClass->focus_in_event = eek_preview_focus_in_event;*/
368
/*widgetClass->focus_out_event = eek_preview_focus_out_event;*/
371
/*widgetClass->selection_get = ;*/
372
/*widgetClass->selection_received = ;*/
376
/*widgetClass->drag_begin = ;*/
377
/*widgetClass->drag_end = ;*/
378
/*widgetClass->drag_data_get = ;*/
379
/*widgetClass->drag_data_delete = ;*/
382
/*widgetClass->drag_leave = ;*/
383
/*widgetClass->drag_motion = ;*/
384
/*widgetClass->drag_drop = ;*/
385
/*widgetClass->drag_data_received = ;*/
387
/* For keybindings: */
388
widgetClass->popup_menu = eek_preview_popup_menu;
389
/*widgetClass->show_help = ;*/
391
/* Accessibility support: */
392
/*widgetClass->get_accessible = ;*/
393
/*widgetClass->screen_changed = ;*/
394
/*widgetClass->can_activate_accel = ;*/
397
eek_preview_signals[CLICKED_SIGNAL] =
398
g_signal_new( "clicked",
399
G_TYPE_FROM_CLASS( klass ),
400
(GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
401
G_STRUCT_OFFSET( EekPreviewClass, clicked ),
403
g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0 );
405
eek_preview_signals[ALTCLICKED_SIGNAL] =
406
g_signal_new( "alt-clicked",
407
G_TYPE_FROM_CLASS( klass ),
408
(GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
409
G_STRUCT_OFFSET( EekPreviewClass, clicked ),
411
g_cclosure_marshal_VOID__INT, G_TYPE_NONE,
415
g_object_class_install_property( gobjClass,
417
g_param_spec_boolean(
420
"flag to grab focus when clicked",
422
(GParamFlags)(G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
427
gboolean eek_preview_get_focus_on_click( EekPreview* preview )
429
return preview->_takesFocus;
432
void eek_preview_set_focus_on_click( EekPreview* preview, gboolean focus_on_click )
434
if ( focus_on_click != preview->_takesFocus ) {
435
preview->_takesFocus = focus_on_click;
439
void eek_preview_set_details( EekPreview* preview, PreviewStyle prevstyle, ViewType view, GtkIconSize size )
441
preview->_prevstyle = prevstyle;
442
preview->_view = view;
443
preview->_size = size;
445
gtk_widget_queue_draw(GTK_WIDGET(preview));
448
static void eek_preview_init( EekPreview *preview )
450
GtkWidget* widg = GTK_WIDGET(preview);
451
GTK_WIDGET_SET_FLAGS( widg, GTK_CAN_FOCUS );
452
GTK_WIDGET_SET_FLAGS( widg, GTK_RECEIVES_DEFAULT );
454
gtk_widget_set_sensitive( widg, TRUE );
456
gtk_widget_add_events(widg, GDK_BUTTON_PRESS_MASK
457
| GDK_BUTTON_RELEASE_MASK
459
| GDK_KEY_RELEASE_MASK
460
| GDK_FOCUS_CHANGE_MASK
461
| GDK_ENTER_NOTIFY_MASK
462
| GDK_LEAVE_NOTIFY_MASK );
464
/* gtk_widget_add_events( widg, GDK_ALL_EVENTS_MASK );*/
470
preview->_hot = FALSE;
471
preview->_within = FALSE;
472
preview->_takesFocus = FALSE;
474
preview->_prevstyle = PREVIEW_STYLE_ICON;
475
preview->_view = VIEW_TYPE_LIST;
476
preview->_size = GTK_ICON_SIZE_BUTTON;
479
GdkColor color = {0};
480
color.red = (255 << 8) | 255;
482
GdkColor whack = {0};
483
whack.green = (255 << 8) | 255;
485
gtk_widget_modify_bg( widg, GTK_STATE_NORMAL, &color );
486
gtk_widget_modify_bg( widg, GTK_STATE_PRELIGHT, &whack );
489
/* GTK_STATE_ACTIVE, */
490
/* GTK_STATE_PRELIGHT, */
491
/* GTK_STATE_SELECTED, */
492
/* GTK_STATE_INSENSITIVE */
495
GdkColor color = {0,0,0,0};
500
gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
501
gtk_widget_modify_bg(widg, GTK_STATE_ACTIVE, &color);
504
color.green = 0xffff;
506
gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
507
gtk_widget_modify_bg(widg, GTK_STATE_SELECTED, &color);
512
gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
513
gtk_widget_modify_bg( widg, GTK_STATE_PRELIGHT, &color );
518
GtkWidget* eek_preview_new(void)
520
return GTK_WIDGET( g_object_new( EEK_PREVIEW_TYPE, NULL ) );