Author: abrander
Date: 2009-06-25 23:52:12 +0200 (Thu, 25 Jun 2009)
New Revision: 2508

Added:
   trunk/src/rs-loupe.c
   trunk/src/rs-loupe.h
Log:
Added RSLoupe.

Added: trunk/src/rs-loupe.c
===================================================================
--- trunk/src/rs-loupe.c                                (rev 0)
+++ trunk/src/rs-loupe.c        2009-06-25 21:52:12 UTC (rev 2508)
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2006-2009 Anders Brander <[email protected]> and 
+ * Anders Kvist <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
USA.
+ */
+
+#include <rawstudio.h>
+#include "rs-loupe.h"
+
+G_DEFINE_TYPE (RSLoupe, rs_loupe, GTK_TYPE_WINDOW)
+
+static gboolean expose(GtkWidget *widget, GdkEventExpose *event, RSLoupe 
*loupe);
+static void move(RSLoupe *loupe);
+static void redraw(RSLoupe *loupe);
+
+static void
+rs_loupe_finalize(GObject *object)
+{
+       RSLoupe *loupe = RS_LOUPE(object);
+
+       if (loupe->filter)
+               g_object_unref(loupe->filter);
+
+       G_OBJECT_CLASS (rs_loupe_parent_class)->finalize (object);
+}
+
+static void
+rs_loupe_class_init(RSLoupeClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->finalize = rs_loupe_finalize;
+}
+
+static void
+rs_loupe_init(RSLoupe *loupe)
+{
+       /* Initialize window */
+       gtk_window_resize(GTK_WINDOW(loupe), 400, 400);
+       gtk_window_set_keep_above(GTK_WINDOW(loupe), TRUE);
+
+       g_object_set(GTK_WINDOW(loupe),
+               "accept-focus", FALSE,
+               "decorated", FALSE,
+               "deletable", FALSE,
+               "focus-on-map", TRUE,
+               "skip-pager-hint", TRUE,
+               "skip-taskbar-hint", TRUE,
+               "type", GTK_WINDOW_POPUP,
+               NULL);
+
+       loupe->canvas = gtk_drawing_area_new();
+       gtk_container_add(GTK_CONTAINER(loupe), loupe->canvas);
+
+       g_signal_connect(loupe->canvas, "expose-event", G_CALLBACK(expose), 
loupe);
+}
+
+/**
+ * Instantiates a new RSLoupe
+ * @return A new RSLoupe
+ */
+RSLoupe *
+rs_loupe_new(void)
+{
+       return g_object_new(RS_TYPE_LOUPE, NULL);
+}
+
+/**
+ * Set the RSFilter a RSLoupe will get its image data from
+ * @param loupe A RSLoupe
+ * @param filter A RSFilter
+ */
+void
+rs_loupe_set_filter(RSLoupe *loupe, RSFilter *filter)
+{
+       g_assert(RS_IS_LOUPE(loupe));
+       g_assert(RS_IS_FILTER(filter));
+
+       if (loupe->filter)
+               g_object_unref(loupe->filter);
+
+       loupe->filter = g_object_ref(filter);
+}
+
+/**
+ * Set center coordinate of the RSLoupe, this will be clamped to filter size
+ * @param loupe A RSLoupe
+ * @param center_x Center of loupe on the X-axis
+ * @param center_y Center of loupe on the Y-axis
+ */
+void
+rs_loupe_set_coord(RSLoupe *loupe, gint center_x, gint center_y)
+{
+       g_assert(RS_IS_LOUPE(loupe));
+
+       loupe->center_x = center_x;
+       loupe->center_y = center_y;
+
+       move(loupe);
+       redraw(loupe);
+}
+
+static gboolean
+expose(GtkWidget *widget, GdkEventExpose *event, RSLoupe *loupe)
+{
+       /* We always draw the full frame */
+       if (event->count > 0)
+               return TRUE;
+
+       redraw(loupe);
+
+       return TRUE;
+}
+
+static void
+move(RSLoupe *loupe)
+{
+       const gint distance_to_window = 50;
+       const gint distance_to_border = 20;
+
+       /* Get cursor position */
+       gint cursor_x=0, cursor_y=0;
+       gdk_display_get_pointer(gdk_display_get_default(), NULL, &cursor_x, 
&cursor_y, NULL);
+
+       /* Get window size */
+       gint window_width, window_height;
+       gtk_window_get_size(GTK_WINDOW(loupe), &window_width, &window_height);
+
+       /* Get screen size */
+       GdkScreen *screen = gdk_screen_get_default();
+       const gint screen_width = gdk_screen_get_width(screen);
+       const gint screen_height = gdk_screen_get_height(screen);
+
+       if (loupe->left)
+       {
+               if ((cursor_x - window_width - distance_to_window) < 
distance_to_border)
+                       loupe->left = !loupe->left;
+       }
+       else
+       {
+               if ((cursor_x + window_width + distance_to_window) > 
(screen_width - distance_to_border))
+                       loupe->left = !loupe->left;
+       }
+
+       if (loupe->atop)
+       {
+               if ((cursor_y - window_height - distance_to_window) < 
distance_to_border)
+                       loupe->atop = !loupe->atop;
+       }
+       else
+       {
+               if ((cursor_y + window_height + distance_to_window) > 
(screen_height - distance_to_border))
+                       loupe->atop = !loupe->atop;
+       }
+       gint place_x, place_y;
+
+       if (loupe->left)
+               place_x = cursor_x - window_width - distance_to_window;
+       else
+               place_x = cursor_x + distance_to_window;
+
+       if (loupe->atop)
+               place_y = cursor_y - window_height - distance_to_window;
+       else
+               place_y = cursor_y + distance_to_window;
+
+       gtk_window_move(GTK_WINDOW(loupe), place_x, place_y);
+}
+
+static void
+redraw(RSLoupe *loupe)
+{
+       if (!loupe->filter)
+               return;
+
+       if (!GTK_WIDGET_DRAWABLE(loupe->canvas))
+               return;
+
+       GdkDrawable *drawable = GDK_DRAWABLE(loupe->canvas->window);
+       GdkGC *gc = gdk_gc_new(drawable);
+
+       const gint width = rs_filter_get_width(loupe->filter);
+       const gint height = rs_filter_get_height(loupe->filter);
+
+       /* Get window size */
+       gint window_width, window_height;
+       gtk_window_get_size(GTK_WINDOW(loupe), &window_width, &window_height);
+
+       /* Create request ROI */
+       RS_FILTER_PARAM param;
+       GdkRectangle request;
+       request.x = CLAMP(loupe->center_x - window_width/2, 0, 
width-window_width-1);
+       request.y = CLAMP(loupe->center_y - window_height/2, 0, 
height-window_height-1);
+       request.width = window_width;
+       request.height = window_height;
+       param.roi = &request;
+
+       GdkPixbuf *buffer = rs_filter_get_image8(loupe->filter, &param);
+       gdk_draw_pixbuf(drawable, gc, buffer, request.x, request.y, 0, 0, 
request.width, request.height, GDK_RGB_DITHER_NONE, 0, 0);
+
+       g_object_unref(buffer);
+       g_object_unref(gc);
+}

Added: trunk/src/rs-loupe.h
===================================================================
--- trunk/src/rs-loupe.h                                (rev 0)
+++ trunk/src/rs-loupe.h        2009-06-25 21:52:12 UTC (rev 2508)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2006-2009 Anders Brander <[email protected]> and 
+ * Anders Kvist <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
USA.
+ */
+
+#ifndef RS_LOUPE_H
+#define RS_LOUPE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define RS_TYPE_LOUPE rs_loupe_get_type()
+#define RS_LOUPE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RS_TYPE_LOUPE, 
RSLoupe))
+#define RS_LOUPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), 
RS_TYPE_LOUPE, RSLoupeClass))
+#define RS_IS_LOUPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RS_TYPE_LOUPE))
+#define RS_IS_LOUPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), 
RS_TYPE_LOUPE))
+#define RS_LOUPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), 
RS_TYPE_LOUPE, RSLoupeClass))
+
+typedef struct {
+       GtkWindow parent;
+       RSFilter *filter;
+       GtkWidget *canvas;
+       gint center_x;
+       gint center_y;
+       gboolean left;
+       gboolean atop;
+} RSLoupe;
+
+typedef struct {
+       GtkWindowClass parent_class;
+} RSLoupeClass;
+
+GType rs_loupe_get_type(void);
+
+/**
+ * Instantiates a new RSLoupe
+ * @return A new RSLoupe
+ */
+RSLoupe *rs_loupe_new(void);
+
+/**
+ * Set the RSFilter a RSLoupe will get its image data from
+ * @param loupe A RSLoupe
+ * @param filter A RSFilter
+ */
+void rs_loupe_set_filter(RSLoupe *loupe, RSFilter *filter);
+
+/**
+ * Set center coordinate of the RSLoupe, this will be clamped to filter size
+ * @param loupe A RSLoupe
+ * @param center_x Center of loupe on the X-axis
+ * @param center_y Center of loupe on the Y-axis
+ */
+void rs_loupe_set_coord(RSLoupe *loupe, gint center_x, gint center_y);
+
+G_END_DECLS
+
+#endif /* RS_LOUPE_H */


_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit

Reply via email to