Code

Only build static libraries for subdirs than actually contain libraries,
[inkscape.git] / src / dialogs / eek-preview.cpp
index d2ac8db5de4cc3242c6f4cccb560d520363b2da5..1c1adf54331641f66445df4954dea02b34ef061c 100644 (file)
@@ -1,5 +1,5 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
+/** @file
+ * @brief EEK preview stuff
  */
 /* ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
@@ -36,6 +36,9 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
 
 #include <gtk/gtk.h>
 #include "eek-preview.h"
 
 #define FOCUS_PROP_ID 1
 
+/* Keep in sycn with last value in eek-preview.h */
+#define PREVIEW_SIZE_LAST PREVIEW_SIZE_HUGE
+#define PREVIEW_SIZE_NEXTFREE (PREVIEW_SIZE_HUGE + 1)
 
+#define PREVIEW_MAX_RATIO 500
 
 static void eek_preview_class_init( EekPreviewClass *klass );
 static void eek_preview_init( EekPreview *preview );
@@ -53,15 +60,26 @@ static GtkWidgetClass* parent_class = 0;
 
 void eek_preview_set_color( EekPreview* preview, int r, int g, int b )
 {
-    if ( (preview->_r = r)
-         || (preview->_g = g)
-         || (preview->_b = b) ) {
-        preview->_r = r;
-        preview->_g = g;
-        preview->_b = b;
-
-        gtk_widget_queue_draw(GTK_WIDGET(preview));
+    preview->_r = r;
+    preview->_g = g;
+    preview->_b = b;
+
+    gtk_widget_queue_draw(GTK_WIDGET(preview));
+}
+
+
+void eek_preview_set_pixbuf( EekPreview* preview, GdkPixbuf* pixbuf )
+{
+    preview->_previewPixbuf = pixbuf;
+
+    gtk_widget_queue_draw(GTK_WIDGET(preview));
+
+    if (preview->_scaled) {
+        g_object_unref(preview->_scaled);
+        preview->_scaled = 0;
     }
+    preview->_scaledW = gdk_pixbuf_get_width(preview->_previewPixbuf);
+    preview->_scaledH = gdk_pixbuf_get_height(preview->_previewPixbuf);
 }
 
 
@@ -90,9 +108,41 @@ GType eek_preview_get_type(void)
     return preview_type;
 }
 
-GtkWidget* eek_preview_area_new(void)
+static gboolean setupDone = FALSE;
+static GtkRequisition sizeThings[PREVIEW_SIZE_NEXTFREE];
+
+void eek_preview_set_size_mappings( guint count, GtkIconSize const* sizes )
 {
-    return NULL;
+    gint width = 0;
+    gint height = 0;
+    gint smallest = 512;
+    gint largest = 0;
+    guint i = 0;
+    guint delta = 0;
+
+    for ( i = 0; i < count; ++i ) {
+        gboolean worked = gtk_icon_size_lookup( sizes[i], &width, &height );
+        if ( worked ) {
+            if ( width < smallest ) {
+                smallest = width;
+            }
+            if ( width > largest ) {
+                largest = width;
+            }
+        }
+    }
+
+    smallest = (smallest * 3) / 4;
+
+    delta = largest - smallest;
+
+    for ( i = 0; i < G_N_ELEMENTS(sizeThings); ++i ) {
+        guint val = smallest + ( (i * delta) / (G_N_ELEMENTS(sizeThings) - 1) );
+        sizeThings[i].width = val;
+        sizeThings[i].height = val;
+    }
+
+    setupDone = TRUE;
 }
 
 static void eek_preview_size_request( GtkWidget* widget, GtkRequisition* req )
@@ -100,14 +150,32 @@ static void eek_preview_size_request( GtkWidget* widget, GtkRequisition* req )
     gint width = 0;
     gint height = 0;
     EekPreview* preview = EEK_PREVIEW(widget);
-    gboolean worked = gtk_icon_size_lookup( preview->_size, &width, &height );
-    if ( !worked ) {
-        width = 16;
-        height = 16;
+
+    if ( !setupDone ) {
+        GtkIconSize sizes[] = {
+            GTK_ICON_SIZE_MENU,
+            GTK_ICON_SIZE_SMALL_TOOLBAR,
+            GTK_ICON_SIZE_LARGE_TOOLBAR,
+            GTK_ICON_SIZE_BUTTON,
+            GTK_ICON_SIZE_DIALOG
+        };
+        eek_preview_set_size_mappings( G_N_ELEMENTS(sizes), sizes );
     }
+
+    width = sizeThings[preview->_size].width;
+    height = sizeThings[preview->_size].height;
+
     if ( preview->_view == VIEW_TYPE_LIST ) {
         width *= 3;
     }
+
+    if ( preview->_ratio != 100 ) {
+        width = (width * preview->_ratio) / 100;
+        if ( width < 0 ) {
+            width = 1;
+        }
+    }
+
     req->width = width;
     req->height = height;
 }
@@ -128,6 +196,7 @@ gboolean eek_preview_expose_event( GtkWidget* widget, GdkEventExpose* event )
     gint insetX = 0;
     gint insetY = 0;
 
+    (void)event;
 /*
     gint lower = widget->allocation.width;
     lower = (widget->allocation.height < lower) ? widget->allocation.height : lower;
@@ -167,6 +236,7 @@ gboolean eek_preview_expose_event( GtkWidget* widget, GdkEventExpose* event )
         GdkGC *gc = gdk_gc_new( widget->window );
         EekPreview* preview = EEK_PREVIEW(widget);
         GdkColor fg = {0, preview->_r, preview->_g, preview->_b};
+
         gdk_colormap_alloc_color( gdk_colormap_get_system(), &fg, FALSE, TRUE );
 
         gdk_gc_set_foreground( gc, &fg );
@@ -210,11 +280,12 @@ gboolean eek_preview_expose_event( GtkWidget* widget, GdkEventExpose* event )
                                  );
             }
 
-            if ( area.height < possible.height ) {
-                area.y = possible.y + (possible.height - area.height);
-            }
-
             if ( preview->_linked & PREVIEW_LINK_OUT ) {
+                GdkRectangle otherArea = {area.x, area.y, area.width, area.height};
+                if ( otherArea.height < possible.height ) {
+                    otherArea.y = possible.y + (possible.height - otherArea.height);
+                }
+
                 gtk_paint_arrow( style,
                                  widget->window,
                                  (GtkStateType)widget->state,
@@ -224,12 +295,52 @@ gboolean eek_preview_expose_event( GtkWidget* widget, GdkEventExpose* event )
                                  NULL, /* detail */
                                  GTK_ARROW_UP,
                                  FALSE,
-                                 area.x, area.y,
-                                 area.width, area.height
+                                 otherArea.x, otherArea.y,
+                                 otherArea.width, otherArea.height
                                  );
             }
+
+            if ( preview->_linked & PREVIEW_LINK_OTHER ) {
+                GdkRectangle otherArea = {insetX, area.y, area.width, area.height};
+                if ( otherArea.height < possible.height ) {
+                    otherArea.y = possible.y + (possible.height - otherArea.height) / 2;
+                }
+
+                gtk_paint_arrow( style,
+                                 widget->window,
+                                 (GtkStateType)widget->state,
+                                 GTK_SHADOW_ETCHED_OUT,
+                                 NULL, /* clip area.  &area, */
+                                 widget, /* may be NULL */
+                                 NULL, /* detail */
+                                 GTK_ARROW_LEFT,
+                                 FALSE,
+                                 otherArea.x, otherArea.y,
+                                 otherArea.width, otherArea.height
+                                 );
+            }
+        }
+
+        if ( preview->_previewPixbuf ) {
+            GtkDrawingArea* da = &(preview->drawing);
+            GdkDrawable* drawable = (GdkDrawable*) (((GtkWidget*)da)->window);
+            gint w = 0;
+            gint h = 0;
+            gdk_drawable_get_size(drawable, &w, &h);
+            if ((w != preview->_scaledW) || (h != preview->_scaledH)) {
+                if (preview->_scaled) {
+                    g_object_unref(preview->_scaled);
+                }
+                preview->_scaled = gdk_pixbuf_scale_simple(preview->_previewPixbuf, w, h, GDK_INTERP_BILINEAR);
+                preview->_scaledW = w;
+                preview->_scaledH = h;
+            }
+
+            GdkPixbuf* pix = (preview->_scaled) ? preview->_scaled : preview->_previewPixbuf;
+            gdk_draw_pixbuf( drawable, 0, pix, 0, 0, 0, 0, w, h, GDK_RGB_DITHER_NONE, 0, 0 );
         }
 
+
         if ( GTK_WIDGET_HAS_FOCUS(widget) ) {
             gtk_paint_focus( style,
                              widget->window,
@@ -324,12 +435,16 @@ static gboolean eek_preview_button_release_cb( GtkWidget* widget, GdkEventButton
 
 gboolean eek_preview_key_press_event( GtkWidget* widget, GdkEventKey* event)
 {
+    (void)widget;
+    (void)event;
     g_message("TICK");
     return FALSE;
 }
 
 gboolean eek_preview_key_release_event( GtkWidget* widget, GdkEventKey* event)
 {
+    (void)widget;
+    (void)event;
     g_message("tock");
     return FALSE;
 }
@@ -485,7 +600,7 @@ static void eek_preview_class_init( EekPreviewClass *klass )
 
 void eek_preview_set_linked( EekPreview* splat, LinkType link )
 {
-    link = (LinkType)(link & PREVIEW_LINK_BOTH);
+    link = (LinkType)(link & PREVIEW_LINK_ALL);
     if ( link != (LinkType)splat->_linked ) {
         splat->_linked = link;
 
@@ -510,12 +625,21 @@ void eek_preview_set_focus_on_click( EekPreview* preview, gboolean focus_on_clic
     }
 }
 
-void eek_preview_set_details( EekPreview* preview, PreviewStyle prevstyle, ViewType view, GtkIconSize size )
+void eek_preview_set_details( EekPreview* preview, PreviewStyle prevstyle, ViewType view, PreviewSize size, guint ratio )
 {
     preview->_prevstyle = prevstyle;
     preview->_view = view;
+
+    if ( size > PREVIEW_SIZE_LAST ) {
+        size = PREVIEW_SIZE_LAST;
+    }
     preview->_size = size;
 
+    if ( ratio > PREVIEW_MAX_RATIO ) {
+        ratio = PREVIEW_MAX_RATIO;
+    }
+    preview->_ratio = ratio;
+
     gtk_widget_queue_draw(GTK_WIDGET(preview));
 }
 
@@ -540,6 +664,8 @@ static void eek_preview_init( EekPreview *preview )
     preview->_r = 0x80;
     preview->_g = 0x80;
     preview->_b = 0xcc;
+    preview->_scaledW = 0;
+    preview->_scaledH = 0;
 
     preview->_hot = FALSE;
     preview->_within = FALSE;
@@ -547,7 +673,11 @@ static void eek_preview_init( EekPreview *preview )
 
     preview->_prevstyle = PREVIEW_STYLE_ICON;
     preview->_view = VIEW_TYPE_LIST;
-    preview->_size = GTK_ICON_SIZE_BUTTON;
+    preview->_size = PREVIEW_SIZE_SMALL;
+    preview->_ratio = 100;
+
+    preview->_previewPixbuf = 0;
+    preview->_scaled = 0;
 
 /*
     GdkColor color = {0};
@@ -565,27 +695,27 @@ static void eek_preview_init( EekPreview *preview )
 /*   GTK_STATE_SELECTED, */
 /*   GTK_STATE_INSENSITIVE */
 
-  if ( 0 ) {
-    GdkColor color = {0,0,0,0};
-
-    color.red = 0xffff;
-    color.green = 0;
-    color.blue = 0xffff;
-    gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
-    gtk_widget_modify_bg(widg, GTK_STATE_ACTIVE, &color);
-
-    color.red = 0;
-    color.green = 0xffff;
-    color.blue = 0;
-    gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
-    gtk_widget_modify_bg(widg, GTK_STATE_SELECTED, &color);
-
-    color.red = 0xffff;
-    color.green = 0;
-    color.blue = 0;
-    gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
-    gtk_widget_modify_bg( widg, GTK_STATE_PRELIGHT, &color );
-  }
+    if ( 0 ) {
+        GdkColor color = {0,0,0,0};
+
+        color.red = 0xffff;
+        color.green = 0;
+        color.blue = 0xffff;
+        gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
+        gtk_widget_modify_bg(widg, GTK_STATE_ACTIVE, &color);
+
+        color.red = 0;
+        color.green = 0xffff;
+        color.blue = 0;
+        gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
+        gtk_widget_modify_bg(widg, GTK_STATE_SELECTED, &color);
+
+        color.red = 0xffff;
+        color.green = 0;
+        color.blue = 0;
+        gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
+        gtk_widget_modify_bg( widg, GTK_STATE_PRELIGHT, &color );
+    }
 }
 
 
@@ -594,3 +724,13 @@ GtkWidget* eek_preview_new(void)
     return GTK_WIDGET( g_object_new( EEK_PREVIEW_TYPE, NULL ) );
 }
 
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :