[libegg/spread-table-dnd: 46/78] Added EggPlaceholder object to use inside the EggSpreadTableDnd during drag'n'drop operations.



commit 6903123bb5ebad06b25d238c81f45c28f4a7dc42
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date:   Fri Apr 1 17:18:04 2011 +0900

    Added EggPlaceholder object to use inside the EggSpreadTableDnd during drag'n'drop operations.

 libegg/spreadtable/Makefile.am      |    6 +-
 libegg/spreadtable/eggplaceholder.c |  209 +++++++++++++++++++++++++++++++++++
 libegg/spreadtable/eggplaceholder.h |   53 +++++++++
 3 files changed, 266 insertions(+), 2 deletions(-)
---
diff --git a/libegg/spreadtable/Makefile.am b/libegg/spreadtable/Makefile.am
index 4d228c9..941e5e7 100644
--- a/libegg/spreadtable/Makefile.am
+++ b/libegg/spreadtable/Makefile.am
@@ -12,11 +12,13 @@ libegg_spreadtable_la_LIBADD = $(EGG_30_LIBS)
 
 EGGSOURCES = \
 	eggspreadtable.c \
-	eggspreadtablednd.c
+	eggspreadtablednd.c \
+	eggplaceholder.c
 
 EGGHEADERS = \
 	eggspreadtable.h \
-	eggspreadtablednd.h
+	eggspreadtablednd.h \
+	eggplaceholder.h
 
 libegg_spreadtable_la_SOURCES = $(EGGSOURCES)
 
diff --git a/libegg/spreadtable/eggplaceholder.c b/libegg/spreadtable/eggplaceholder.c
new file mode 100644
index 0000000..c0dbb3d
--- /dev/null
+++ b/libegg/spreadtable/eggplaceholder.c
@@ -0,0 +1,209 @@
+
+#include "eggplaceholder.h"
+
+/* GObjectClass */
+static void      egg_placeholder_finalize             (GObject    *object);
+
+/* GtkWidgetClass */
+static void      egg_placeholder_get_preferred_width  (GtkWidget  *widget,
+						       gint       *min_width,
+						       gint       *nat_width);
+static void      egg_placeholder_get_preferred_height (GtkWidget  *widget,
+						       gint       *min_height,
+						       gint       *nat_height);
+
+#define ANIMATION_STEP 0.15F  /* How much percentage of the size to animate per iteration */
+#define ANIMATION_FREQ 20     /* At what frequency in millisecs to animate */
+
+enum {
+  SIGNAL_ANIMATION_DONE,
+  NUM_SIGNALS
+};
+
+static guint placeholder_signals[NUM_SIGNALS] = { 0, };
+
+struct _EggPlaceholderPrivate
+{
+  gint           width;
+  gint           height;
+
+  GtkOrientation animation_orientation; /* Whether we are animating in/out horizontally or vertically */
+  gdouble        animation_percent;     /* A multiplier between 0 and 1 representing the current progress */
+  guint          animation_id;          /* The GSource id for the animation timeout */
+  EggPlaceholderAnimDirection animation_direction;  /* Whether the placeholder is animating in or out */
+};
+
+G_DEFINE_TYPE (EggPlaceholder, egg_placeholder, GTK_TYPE_DRAWING_AREA)
+
+static void egg_placeholder_class_init (EggPlaceholderClass * klass)
+{
+  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->finalize = egg_placeholder_finalize;
+
+  widget_class->get_preferred_width  = egg_placeholder_get_preferred_width;
+  widget_class->get_preferred_height = egg_placeholder_get_preferred_height;
+
+  placeholder_signals[SIGNAL_ANIMATION_DONE] = 
+    g_signal_new ("animation-done",
+		  G_OBJECT_CLASS_TYPE (klass),
+		  G_SIGNAL_RUN_FIRST,
+		  0, NULL, NULL,
+		  g_cclosure_marshal_VOID__VOID,
+		  G_TYPE_NONE, 0);
+
+  g_type_class_add_private (klass, sizeof (EggPlaceholderPrivate));
+}
+
+static void
+egg_placeholder_init (EggPlaceholder * placeholder)
+{
+  placeholder->priv = 
+    G_TYPE_INSTANCE_GET_PRIVATE (placeholder,
+				 EGG_TYPE_PLACEHOLDER,
+				 EggPlaceholderPrivate);
+
+  placeholder->priv->animation_percent = 1.0F;
+
+  /* Default visible, avoid cluttering code in eggspreadtablednd.c */
+  gtk_widget_show (GTK_WIDGET (placeholder));
+}
+
+static void
+egg_placeholder_finalize (GObject * object)
+{
+  EggPlaceholder *placeholder = EGG_PLACEHOLDER (object);
+
+  if (placeholder->priv->animation_id > 0)
+    {
+      g_source_remove (placeholder->priv->animation_id);
+      placeholder->priv->animation_id = 0;
+    }
+
+  G_OBJECT_CLASS (egg_placeholder_parent_class)->finalize (object);
+}
+
+static void
+egg_placeholder_get_preferred_width (GtkWidget  *widget,
+				     gint       *min_width,
+				     gint       *nat_width)
+{
+  EggPlaceholder *placeholder = EGG_PLACEHOLDER (widget);
+  gint            width;
+
+  if (placeholder->priv->animation_orientation == GTK_ORIENTATION_HORIZONTAL)
+    width = placeholder->priv->width * placeholder->priv->animation_percent;
+  else
+    width = placeholder->priv->width;
+
+  *min_width = *nat_width = width;
+}
+
+static void
+egg_placeholder_get_preferred_height (GtkWidget  *widget,
+				      gint       *min_height,
+				      gint       *nat_height)
+{
+  EggPlaceholder *placeholder = EGG_PLACEHOLDER (widget);
+  gint            height;
+
+  if (placeholder->priv->animation_orientation == GTK_ORIENTATION_VERTICAL)
+    height = placeholder->priv->height * placeholder->priv->animation_percent;
+  else
+    height = placeholder->priv->height;
+
+  *min_height = *nat_height = height;
+}
+
+static gboolean 
+placeholder_animate (EggPlaceholder *placeholder)
+{
+  if (placeholder->priv->animation_direction == EGG_PLACEHOLDER_ANIM_IN)
+    placeholder->priv->animation_percent += ANIMATION_STEP;
+  else
+    placeholder->priv->animation_percent -= ANIMATION_STEP;
+
+  placeholder->priv->animation_percent =
+    CLAMP (placeholder->priv->animation_percent, 0.0, 1.0);
+
+  gtk_widget_queue_resize (GTK_WIDGET (placeholder));
+
+  if (placeholder->priv->animation_percent == 1.0 ||
+      placeholder->priv->animation_percent == 0.0)
+    {
+      placeholder->priv->animation_id = 0;
+      placeholder->priv->animation_direction = EGG_PLACEHOLDER_ANIM_NONE;
+
+      g_signal_emit (placeholder, placeholder_signals[SIGNAL_ANIMATION_DONE], 0);
+
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+void
+egg_placeholder_animate_in (EggPlaceholder *placeholder,
+			    GtkOrientation  orientation)
+{
+  g_return_if_fail (EGG_IS_PLACEHOLDER (placeholder));
+
+  placeholder->priv->animation_orientation = orientation;
+  placeholder->priv->animation_direction   = EGG_PLACEHOLDER_ANIM_IN;
+
+  if (placeholder->priv->animation_id == 0)
+    placeholder->priv->animation_percent = 0.0F;
+
+  if (placeholder->priv->animation_id == 0)
+    placeholder->priv->animation_id = 
+      gdk_threads_add_timeout (ANIMATION_FREQ, 
+			       (GSourceFunc)placeholder_animate, 
+			       placeholder);
+
+  gtk_widget_queue_resize (GTK_WIDGET (placeholder));
+}
+
+void
+egg_placeholder_animate_out (EggPlaceholder *placeholder,
+			     GtkOrientation  orientation)
+{
+  g_return_if_fail (EGG_IS_PLACEHOLDER (placeholder));
+
+  placeholder->priv->animation_orientation = orientation;
+  placeholder->priv->animation_direction   = EGG_PLACEHOLDER_ANIM_OUT;
+
+  if (placeholder->priv->animation_id == 0)
+    placeholder->priv->animation_percent = 1.0F;
+
+  if (placeholder->priv->animation_id == 0)
+    placeholder->priv->animation_id = 
+      gdk_threads_add_timeout (ANIMATION_FREQ, 
+			       (GSourceFunc)placeholder_animate, 
+			       placeholder);
+
+  gtk_widget_queue_resize (GTK_WIDGET (placeholder));
+}
+
+
+EggPlaceholderAnimDirection 
+egg_placeholder_get_animating (EggPlaceholder *placeholder)
+{
+  g_return_val_if_fail (EGG_IS_PLACEHOLDER (placeholder),
+			EGG_PLACEHOLDER_ANIM_NONE);
+
+  return placeholder->priv->animation_direction;
+}
+
+
+GtkWidget *
+egg_placeholder_new (gint width, 
+		     gint height)
+{
+  EggPlaceholder *placeholder = g_object_new (EGG_TYPE_PLACEHOLDER, NULL);
+
+  placeholder->priv->width  = width;
+  placeholder->priv->height = height;
+
+  return GTK_WIDGET (placeholder);
+}
diff --git a/libegg/spreadtable/eggplaceholder.h b/libegg/spreadtable/eggplaceholder.h
new file mode 100644
index 0000000..496cdff
--- /dev/null
+++ b/libegg/spreadtable/eggplaceholder.h
@@ -0,0 +1,53 @@
+ 
+#ifndef __EGG_PLACEHOLDER_H__
+#define __EGG_PLACEHOLDER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define EGG_TYPE_PLACEHOLDER            (egg_placeholder_get_type ())
+#define EGG_PLACEHOLDER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_PLACEHOLDER, EggPlaceholder))
+#define EGG_PLACEHOLDER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_PLACEHOLDER, EggPlaceholderClass))
+#define EGG_IS_PLACEHOLDER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_PLACEHOLDER))
+#define EGG_IS_PLACEHOLDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_PLACEHOLDER))
+#define EGG_PLACEHOLDER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_PLACEHOLDER, EggPlaceholderClass))
+
+typedef struct _EggPlaceholder        EggPlaceholder;
+typedef struct _EggPlaceholderClass   EggPlaceholderClass;
+typedef struct _EggPlaceholderPrivate EggPlaceholderPrivate;
+
+
+typedef enum {
+  EGG_PLACEHOLDER_ANIM_NONE,
+  EGG_PLACEHOLDER_ANIM_IN,
+  EGG_PLACEHOLDER_ANIM_OUT
+} EggPlaceholderAnimDirection;
+
+
+struct _EggPlaceholder
+{
+  GtkDrawingArea drawing_area;
+	
+  EggPlaceholderPrivate *priv;
+};
+
+struct _EggPlaceholderClass
+{
+  GtkDrawingAreaClass parent_class;
+};
+
+GType         egg_placeholder_get_type        (void) G_GNUC_CONST;
+
+GtkWidget    *egg_placeholder_new             (gint            width,
+					       gint            height);
+void          egg_placeholder_animate_in      (EggPlaceholder *placeholder,
+					       GtkOrientation  orientation);
+void          egg_placeholder_animate_out     (EggPlaceholder *placeholder,
+					       GtkOrientation  orientation);
+
+EggPlaceholderAnimDirection egg_placeholder_get_animating (EggPlaceholder *placeholder);
+
+G_END_DECLS
+
+#endif /* __EGG_PLACEHOLDER_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]