Code

moving trunk for module inkscape
[inkscape.git] / src / dialogs / eek-preview.cpp
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  */
4 /* ***** BEGIN LICENSE BLOCK *****
5  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6  *
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/
11  *
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
15  * License.
16  *
17  * The Original Code is Eek Preview Stuffs.
18  *
19  * The Initial Developer of the Original Code is
20  * Jon A. Cruz.
21  * Portions created by the Initial Developer are Copyright (C) 2005
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
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.
37  *
38  * ***** END LICENSE BLOCK ***** */
40 #include <gtk/gtk.h>
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 )
55 {
56     preview->_r = r;
57     preview->_g = g;
58     preview->_b = b;
59 }
62 GType eek_preview_get_type(void)
63 {
64     static GType preview_type = 0;
66     if (!preview_type) {
67       static const GTypeInfo preview_info = {
68           sizeof( EekPreviewClass ),
69           NULL, /* base_init */
70           NULL, /* base_finalize */
71           (GClassInitFunc)eek_preview_class_init,
72           NULL, /* class_finalize */
73           NULL, /* class_data */
74           sizeof( EekPreview ),
75           0,    /* n_preallocs */
76           (GInstanceInitFunc)eek_preview_init,
77           NULL /* value_table */
78       };
81       preview_type = g_type_register_static( GTK_TYPE_DRAWING_AREA, "EekPreview", &preview_info, (GTypeFlags)0 );
82     }
84     return preview_type;
85 }
87 GtkWidget* eek_preview_area_new(void)
88 {
89     return NULL;
90 }
92 static void eek_preview_size_request( GtkWidget* widget, GtkRequisition* req )
93 {
94     gint width = 0;
95     gint height = 0;
96     EekPreview* preview = EEK_PREVIEW(widget);
97     gboolean worked = gtk_icon_size_lookup( preview->_size, &width, &height );
98     if ( !worked ) {
99         width = 16;
100         height = 16;
101     }
102     if ( preview->_view == VIEW_TYPE_LIST ) {
103         width *= 3;
104     }
105     req->width = width;
106     req->height = height;
109 enum {
110   CLICKED_SIGNAL,
111   ALTCLICKED_SIGNAL,
112   LAST_SIGNAL
113 };
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" : "---" ); */
122     gint insetX = 0;
123     gint insetY = 0;
125 /*
126     gint lower = widget->allocation.width;
127     lower = (widget->allocation.height < lower) ? widget->allocation.height : lower;
128     if ( lower > 16 ) {
129         insetX++;
130         if ( lower > 18 ) {
131             insetX++;
132             if ( lower > 22 ) {
133                 insetX++;
134                 if ( lower > 24 ) {
135                     insetX++;
136                     if ( lower > 32 ) {
137                         insetX++;
138                     }
139                 }
140             }
141         }
142         insetY = insetX;
143     }
144 */
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,
151                                 widget->window,
152                                 (GtkStateType)GTK_WIDGET_STATE(widget),
153                                 GTK_SHADOW_NONE,
154                                 NULL,
155                                 widget,
156                                 NULL,
157                                 0, 0,
158                                 widget->allocation.width, widget->allocation.height);
159         }
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,
169                             gc,
170                             TRUE,
171                             insetX, insetY,
172                             widget->allocation.width - (insetX * 2), widget->allocation.height - (insetY * 2) );
174         if ( GTK_WIDGET_HAS_FOCUS(widget) ) {
175             gtk_paint_focus( style,
176                              widget->window,
177                              GTK_STATE_NORMAL,
178                              NULL, /* GdkRectangle *area, */
179                              widget,
180                              NULL,
181                              0 + 1, 0 + 1,
182                              widget->allocation.width - 2, widget->allocation.height - 2 );
183         }
184     }
187     return FALSE;
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 );
197     }
198     return FALSE;
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 );
207     }
208     return FALSE;
211 /*
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;
216     return blip;
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;
223     return blip;
225 */
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);
234         }
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 );
240             }
241         }
242     }
244     return FALSE;
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;
256             if ( isAlt ) {
257                 g_signal_emit( widget, eek_preview_signals[ALTCLICKED_SIGNAL], 0, 2 );
258             } else {
259                 g_signal_emit( widget, eek_preview_signals[CLICKED_SIGNAL], 0 );
260             }
261         }
262     }
263     return FALSE;
266 gboolean eek_preview_key_press_event( GtkWidget* widget, GdkEventKey* event)
268     g_message("TICK");
269     return FALSE;
272 gboolean eek_preview_key_release_event( GtkWidget* widget, GdkEventKey* event)
274     g_message("tock");
275     return FALSE;
278 static void eek_preview_get_property( GObject *object,
279                                       guint property_id,
280                                       GValue *value,
281                                       GParamSpec *pspec)
283     GObjectClass* gobjClass = G_OBJECT_CLASS(parent_class);
284     switch ( property_id ) {
285         case FOCUS_PROP_ID:
286         {
287             EekPreview* preview = EEK_PREVIEW( object );
288             g_value_set_boolean( value, preview->_takesFocus );
289         }
290         break;
291         default:
292         {
293             if ( gobjClass->get_property ) {
294                 gobjClass->get_property( object, property_id, value, pspec );
295             }
296         }
297     }
300 static void eek_preview_set_property( GObject *object,
301                                       guint property_id,
302                                       const GValue *value,
303                                       GParamSpec *pspec)
305     GObjectClass* gobjClass = G_OBJECT_CLASS(parent_class);
306     switch ( property_id ) {
307         case FOCUS_PROP_ID:
308         {
309             EekPreview* preview = EEK_PREVIEW( object );
310             gboolean val = g_value_get_boolean( value );
311             if ( val != preview->_takesFocus ) {
312                 preview->_takesFocus = val;
313             }
314         }
315         break;
316         default:
317         {
318             if ( gobjClass->set_property ) {
319                 gobjClass->set_property( object, property_id, value, pspec );
320             }
321         }
322     }
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;
330     return blip;
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;*/
370     /* selection */
371     /*widgetClass->selection_get = ;*/
372     /*widgetClass->selection_received = ;*/
375     /* drag source: */
376     /*widgetClass->drag_begin = ;*/
377     /*widgetClass->drag_end = ;*/
378     /*widgetClass->drag_data_get = ;*/
379     /*widgetClass->drag_data_delete = ;*/
381     /* drag target: */
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 ),
402                       NULL, NULL,
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 ),
410                       NULL, NULL,
411                       g_cclosure_marshal_VOID__INT, G_TYPE_NONE,
412                       1, G_TYPE_INT );
415     g_object_class_install_property( gobjClass,
416                                      FOCUS_PROP_ID,
417                                      g_param_spec_boolean(
418                                          "focus-on-click",
419                                          NULL,
420                                          "flag to grab focus when clicked",
421                                          TRUE,
422                                          (GParamFlags)(G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
423                                          )
424         );
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;
436     }
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
458                           | GDK_KEY_PRESS_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 );*/
466     preview->_r = 0x80;
467     preview->_g = 0x80;
468     preview->_b = 0xcc;
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;
478 /*
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 );
487 */
489 /*   GTK_STATE_ACTIVE, */
490 /*   GTK_STATE_PRELIGHT, */
491 /*   GTK_STATE_SELECTED, */
492 /*   GTK_STATE_INSENSITIVE */
494   if ( 0 ) {
495     GdkColor color = {0,0,0,0};
497     color.red = 0xffff;
498     color.green = 0;
499     color.blue = 0xffff;
500     gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
501     gtk_widget_modify_bg(widg, GTK_STATE_ACTIVE, &color);
503     color.red = 0;
504     color.green = 0xffff;
505     color.blue = 0;
506     gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
507     gtk_widget_modify_bg(widg, GTK_STATE_SELECTED, &color);
509     color.red = 0xffff;
510     color.green = 0;
511     color.blue = 0;
512     gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
513     gtk_widget_modify_bg( widg, GTK_STATE_PRELIGHT, &color );
514   }
518 GtkWidget* eek_preview_new(void)
520     return GTK_WIDGET( g_object_new( EEK_PREVIEW_TYPE, NULL ) );