2008-04-14 16:52:59 <timj@imendio.com>
[hildon] / src / hildon-color-button.c
index 81d0dcc..0a57a1e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * This file is part of hildon-libs
+ * This file is a part of hildon
  *
  * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
  *
@@ -8,7 +8,7 @@
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
  * as published by the Free Software Foundation; version 2.1 of
- * the License.
+ * the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
 
 /**
  * SECTION:hildon-color-button
- * @short_description: A widget to open HildonColorChooserDialog
+ * @short_description: A widget to open HildonColorChooserDialog.
  * @see_also: #HildonColorChooserDialog, #HildonColorPopup
  *
  * HildonColorButton is a widget to open a HildonColorChooserDialog.
  * The selected color is shown in the button.
  * The selected color is a property of the button.
  * The property name is "color" and its type is GtkColor.
+ * 
+ * <example>
+ * <title>HildonColorButton example</title>
+ * <programlisting>
+ * HildonColorButton *cbutton;
+ * GtkColor *color;
+ * <!-- -->
+ * cbutton = hildon_color_button_new();
+ * gtk_object_get( GTK_OBJECT(cbutton), "color", color );
+ * </programlisting>
+ * </example>
+ * 
  */
 
-#include <config.h>
-#include "hildon-color-button.h"
-#include <gtk/gtkbutton.h>
-#include <gtk/gtkalignment.h>
-#include <gtk/gtkdrawingarea.h>
-#include <gtk/gtksignal.h>
-#include <gdk/gdkkeysyms.h>
-#include "hildon-defines.h"
-#include "hildon-color-chooser-dialog.h"
-
-#define HILDON_COLOR_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE\
-              ((obj), HILDON_TYPE_COLOR_BUTTON, HildonColorButtonPrivate))
-
-#define COLOR_FILLED_HEIGHT 22
-#define COLOR_FILLED_WIDTH  22
-
-#define COLOR_BUTTON_WIDTH  52
-#define COLOR_BUTTON_HEIGHT 48
-
-/* the outer border color */
-#define OUTER_BORDER_RED   0
-#define OUTER_BORDER_BLUE  0
-#define OUTER_BORDER_GREEN 0
-#define OUTER_BORDER_THICKNESS 1
-
-/* the inner border color */
-#define INNER_BORDER_RED   65535
-#define INNER_BORDER_BLUE  65535
-#define INNER_BORDER_GREEN 65535
-#define INNER_BORDER_THICKNESS 2
-
-struct _HildonColorButtonPrivate 
-{
-  GtkWidget *dialog;
+#ifdef                                          HAVE_CONFIG_H
+#include                                        <config.h>
+#endif
+
+#include                                        "hildon-color-button.h"
+#include                                        <gtk/gtkbutton.h>
+#include                                        <gtk/gtkalignment.h>
+#include                                        <gtk/gtkdrawingarea.h>
+#include                                        <gtk/gtksignal.h>
+#include                                        <gdk/gdkkeysyms.h>
+#include                                        "hildon-defines.h"
+#include                                        "hildon-color-chooser-dialog.h"
+#include                                        "hildon-color-button-private.h"
+
+#define                                         COLOR_FILLED_HEIGHT 22
+
+#define                                         COLOR_FILLED_WIDTH 22
+
+#define                                         COLOR_BUTTON_WIDTH 52
+
+#define                                         COLOR_BUTTON_HEIGHT 48
+
+#define                                         OUTER_BORDER_RED 0
+
+#define                                         OUTER_BORDER_BLUE 0
+
+#define                                         OUTER_BORDER_GREEN 0
+
+#define                                         OUTER_BORDER_THICKNESS 1
+
+#define                                         INNER_BORDER_RED 65535
+
+#define                                         INNER_BORDER_BLUE 65535
 
-  GdkColor color;
-  GdkGC *gc;
+#define                                         INNER_BORDER_GREEN 65535
+
+#define                                         INNER_BORDER_THICKNESS 2
+
+enum
+{
+    SETUP_DIALOG,
+    LAST_SIGNAL
 };
 
-enum 
+enum
 {
-  PROP_NONE,
-  PROP_COLOR
+    PROP_0,
+    PROP_COLOR,
+    PROP_POPUP_SHOWN
 };
 
 static void
-hildon_color_button_class_init(HildonColorButtonClass *klass);
+hildon_color_button_class_init                  (HildonColorButtonClass *klass);
+
 static void
-hildon_color_button_init(HildonColorButton *color_button);
+hildon_color_button_init                        (HildonColorButton *color_button);
 
 static void
-hildon_color_button_finalize(GObject *object);
+hildon_color_button_finalize                    (GObject *object);
+
 static void
-hildon_color_button_set_property(GObject *object, guint param_id,
-                                 const GValue *value, GParamSpec *pspec);
+hildon_color_button_set_property                (GObject *object, 
+                                                 guint param_id,
+                                                 const GValue *value, 
+                                                 GParamSpec *pspec);
+
 static void
-hildon_color_button_get_property(GObject *object, guint param_id,
-                                        GValue *value, GParamSpec *pspec);
+hildon_color_button_get_property                (GObject *object, 
+                                                 guint param_id,
+                                                 GValue *value, 
+                                                 GParamSpec *pspec);
+
 static void
-hildon_color_button_realize(GtkWidget *widget);
+hildon_color_button_realize                     (GtkWidget *widget);
+
 static void
-hildon_color_button_unrealize(GtkWidget *widget);
+hildon_color_button_unrealize                   (GtkWidget *widget);
+
 static void
-hildon_color_button_clicked(GtkButton *button);
+hildon_color_button_clicked                     (GtkButton *button);
+
 static gboolean
-hildon_color_button_key_pressed(GtkWidget * button, 
-                                GdkEventKey * event,
-                                gpointer data);
+hildon_color_button_key_pressed                 (GtkWidget *button, 
+                                                 GdkEventKey *event,
+                                                 gpointer data);
+
 static gint
-hildon_color_field_expose_event(GtkWidget *widget, GdkEventExpose *event,
-                                HildonColorButton *cb);
+hildon_color_field_expose_event                 (GtkWidget *widget, 
+                                                 GdkEventExpose *event,
+                                                 HildonColorButton *cb);
 
 static gboolean
-hildon_color_button_mnemonic_activate( GtkWidget *widget,
-                                       gboolean group_cycling );
+hildon_color_button_mnemonic_activate           (GtkWidget *widget,
+                                                 gboolean group_cycling);
 
 static void
-draw_grid (GdkDrawable *drawable, GdkGC *gc, 
-           int x, int y, 
-           gint w, gint h);
+draw_grid                                       (GdkDrawable *drawable, 
+                                                 GdkGC *gc, 
+                                                 int x, 
+                                                 int y, 
+                                                 gint w, 
+                                                 gint h);
 
-static gpointer parent_class = NULL;
+static gpointer                                 parent_class = NULL;
+static guint                                    signals [LAST_SIGNAL] = { 0, };
 
-GType
-hildon_color_button_get_type(void)
+/**
+ * hildon_color_button_get_type:
+ *
+ * Initializes and returns the type of a hildon color button.
+ *
+ * @Returns: GType of #HildonColorButton.
+ */
+GType G_GNUC_CONST
+hildon_color_button_get_type                    (void)
 {
-  static GType color_button_type = 0;
-  
-  if (!color_button_type)
+    static GType color_button_type = 0;
+
+    if (! color_button_type)
     {
-      static const GTypeInfo color_button_info =
-      {
-        sizeof (HildonColorButtonClass),
-        NULL,           /* base_init */
-        NULL,           /* base_finalize */
-        (GClassInitFunc) hildon_color_button_class_init,
-        NULL,           /* class_finalize */
-        NULL,           /* class_data */
-        sizeof (HildonColorButton),
-        0,              /* n_preallocs */
-        (GInstanceInitFunc) hildon_color_button_init,
-      };
-      
-      color_button_type =
-        g_type_register_static (GTK_TYPE_BUTTON, "HildonColorButton",
-                                &color_button_info, 0);
+        static const GTypeInfo color_button_info =
+        {
+            sizeof (HildonColorButtonClass),
+            NULL,           /* base_init */
+            NULL,           /* base_finalize */
+            (GClassInitFunc) hildon_color_button_class_init,
+            NULL,           /* class_finalize */
+            NULL,           /* class_data */
+            sizeof (HildonColorButton),
+            0,              /* n_preallocs */
+            (GInstanceInitFunc) hildon_color_button_init,
+        };
+
+        color_button_type = g_type_register_static (GTK_TYPE_BUTTON, "HildonColorButton",
+                &color_button_info, 0);
     }
-  
-  return color_button_type;
+
+    return color_button_type;
 }
 
 static void
-hildon_color_button_class_init(HildonColorButtonClass *klass)
+hildon_color_button_class_init                  (HildonColorButtonClass *klass)
 {
-  GObjectClass *gobject_class;
-  GtkButtonClass *button_class;
-  GtkWidgetClass *widget_class;
-  
-  gobject_class = G_OBJECT_CLASS (klass);
-  button_class = GTK_BUTTON_CLASS (klass);
-  widget_class = GTK_WIDGET_CLASS (klass);
-  
-  parent_class = g_type_class_peek_parent (klass);
-
-  gobject_class->get_property = hildon_color_button_get_property;
-  gobject_class->set_property = hildon_color_button_set_property;
-  gobject_class->finalize = hildon_color_button_finalize;
-  widget_class->realize = hildon_color_button_realize;
-  widget_class->unrealize = hildon_color_button_unrealize;
-  button_class->clicked = hildon_color_button_clicked;
-  widget_class->mnemonic_activate = hildon_color_button_mnemonic_activate;
-  
-  /**
-   * HildonColorButton:color:
-   *
-   * The selected color.
-   */
-  g_object_class_install_property (gobject_class, PROP_COLOR,
-                                   g_param_spec_boxed ("color",
-                                     "Current Color",
-                                     "The selected color",
-                                     GDK_TYPE_COLOR,
-                                     G_PARAM_READWRITE));
-
-  g_type_class_add_private (gobject_class, sizeof (HildonColorButtonPrivate));
+    GObjectClass *gobject_class;
+    GtkButtonClass *button_class;
+    GtkWidgetClass *widget_class;
+
+    gobject_class = G_OBJECT_CLASS (klass);
+    button_class = GTK_BUTTON_CLASS (klass);
+    widget_class = GTK_WIDGET_CLASS (klass);
+    
+    parent_class = g_type_class_peek_parent (klass);
+
+    gobject_class->get_property     = hildon_color_button_get_property;
+    gobject_class->set_property     = hildon_color_button_set_property;
+    gobject_class->finalize         = hildon_color_button_finalize;
+    widget_class->realize           = hildon_color_button_realize;
+    widget_class->unrealize         = hildon_color_button_unrealize;
+    button_class->clicked           = hildon_color_button_clicked;
+    widget_class->mnemonic_activate = hildon_color_button_mnemonic_activate;
+
+   signals[SETUP_DIALOG] =
+       g_signal_new ("setup-dialog",
+                     G_TYPE_FROM_CLASS (klass),
+                     G_SIGNAL_RUN_LAST,
+                     0,
+                     NULL, NULL,
+                     gtk_marshal_VOID__OBJECT,
+                     G_TYPE_NONE, 1,
+                     HILDON_TYPE_COLOR_CHOOSER_DIALOG);
+
+    /**
+     * HildonColorButton:color:
+     *
+     * The currently selected color.
+     */
+    g_object_class_install_property (gobject_class, PROP_COLOR,
+            g_param_spec_boxed ("color",
+                "Current Color",
+                "The selected color",
+                GDK_TYPE_COLOR,
+                G_PARAM_READWRITE));
+
+    /**
+     * HildonColorButton:popup-shown:
+     *
+     * If the color selection dialog is currently popped-up (visible)
+     */
+    g_object_class_install_property (gobject_class, PROP_POPUP_SHOWN,
+            g_param_spec_boolean ("popup-shown",
+                "IsPopped",
+                "If the color selection dialog is popped up",
+                FALSE,
+                G_PARAM_READABLE));
+
+    g_type_class_add_private (gobject_class, sizeof (HildonColorButtonPrivate));
 }
 
-/* Draw a dotted grid over the specified area to make it look 
+/* FIXME Draw a dotted grid over the specified area to make it look 
  * insensitive. Actually, we should generate that pixbuf once and 
  * just render it over later... */
 static void
-draw_grid (GdkDrawable *drawable, GdkGC *gc, 
-           int x, int y,
-           gint w, gint h)
+draw_grid                                       (GdkDrawable *drawable, 
+                                                 GdkGC *gc, 
+                                                 int x, 
+                                                 int y,
+                                                 gint w, 
+                                                 gint h)
 {
-  int currentx;
-  int currenty;
-  for (currenty = y; currenty <= h; currenty++)
-      for (currentx = ((currenty % 2 == 0) ? x : x + 1); currentx <= w; currentx += 2)
-        gdk_draw_point (drawable, gc, currentx, currenty);
+    int currentx;
+    int currenty;
+    for (currenty = y; currenty <= h; currenty++)
+        for (currentx = ((currenty % 2 == 0) ? x : x + 1); currentx <= w; currentx += 2)
+            gdk_draw_point (drawable, gc, currentx, currenty);
 }
 
 /* Handle exposure events for the color picker's drawing area */
 static gint
-hildon_color_field_expose_event(GtkWidget *widget, GdkEventExpose *event,
-                                HildonColorButton *cb)
+hildon_color_field_expose_event                 (GtkWidget *widget, 
+                                                 GdkEventExpose *event,
+                                                 HildonColorButton *cb)
 {
+    HildonColorButtonPrivate *priv = HILDON_COLOR_BUTTON_GET_PRIVATE (cb);
     GdkColor outer_border, inner_border;
 
+    g_assert (priv);
+
     /* Create the outer border color */
     outer_border.pixel = 0;
     outer_border.red   = OUTER_BORDER_RED;
@@ -215,219 +285,250 @@ hildon_color_field_expose_event(GtkWidget *widget, GdkEventExpose *event,
     inner_border.green = INNER_BORDER_GREEN;
 
     /* serve the outer border color to the Graphic Context */
-    gdk_gc_set_rgb_fg_color(cb->priv->gc, &outer_border);
+    gdk_gc_set_rgb_fg_color (priv->gc, &outer_border);
     /* draw the outer border as a filled rectangle */
-    gdk_draw_rectangle(widget->window,
-                       (GTK_WIDGET_IS_SENSITIVE (widget)) ?  cb->priv->gc : widget->style->bg_gc [GTK_STATE_INSENSITIVE],
-                       TRUE,
-                       0, 
-                       0,
-                       widget->allocation.width,
-                       widget->allocation.height);
+    gdk_draw_rectangle (widget->window,
+            (GTK_WIDGET_IS_SENSITIVE (widget)) ?  priv->gc : widget->style->bg_gc [GTK_STATE_INSENSITIVE],
+            TRUE,
+            0, 
+            0,
+            widget->allocation.width,
+            widget->allocation.height);
 
     /* serve the inner border color to the Graphic Context */
-    gdk_gc_set_rgb_fg_color(cb->priv->gc, &inner_border);
+    gdk_gc_set_rgb_fg_color (priv->gc, &inner_border);
+
     /* draw the inner border as a filled rectangle */
-    gdk_draw_rectangle(widget->window,
-                       cb->priv->gc,
-                       TRUE,
-                       OUTER_BORDER_THICKNESS, 
-                       OUTER_BORDER_THICKNESS,
-                       widget->allocation.width - (OUTER_BORDER_THICKNESS * 2),
-                       widget->allocation.height - (OUTER_BORDER_THICKNESS * 2));
+    gdk_draw_rectangle (widget->window,
+            priv->gc,
+            TRUE,
+            OUTER_BORDER_THICKNESS, 
+            OUTER_BORDER_THICKNESS,
+            widget->allocation.width - (OUTER_BORDER_THICKNESS * 2),
+            widget->allocation.height - (OUTER_BORDER_THICKNESS * 2));
 
     /* serve the actual color to the Graphic Context */
-    gdk_gc_set_rgb_fg_color(cb->priv->gc, &cb->priv->color);
+    gdk_gc_set_rgb_fg_color(priv->gc, &priv->color);
+
     /* draw the actual rectangle */
     gdk_draw_rectangle(widget->window,
-                       cb->priv->gc,
-                       TRUE,
-                       INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
-                       INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
-                       widget->allocation.width - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2),
-                       widget->allocation.height - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2));
+            priv->gc,
+            TRUE,
+            INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
+            INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
+            widget->allocation.width - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2),
+            widget->allocation.height - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2));
 
     if (! GTK_WIDGET_IS_SENSITIVE (widget)) {
-            draw_grid (GDK_DRAWABLE (widget->window), widget->style->bg_gc [GTK_STATE_INSENSITIVE], 
-                       INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
-                       INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
-                       widget->allocation.width  - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2) + 2,
-                       widget->allocation.height - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2) + 2);
+        draw_grid (GDK_DRAWABLE (widget->window), widget->style->bg_gc [GTK_STATE_INSENSITIVE], 
+                INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
+                INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
+                widget->allocation.width  - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2) + 2,
+                widget->allocation.height - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2) + 2);
     }
 
     return FALSE;
 }
 
 static void
-hildon_color_button_init(HildonColorButton *cb)
+hildon_color_button_init                        (HildonColorButton *cb)
 {
-  GtkWidget *align;
-  GtkWidget *drawing_area;
-  
-  cb->priv = HILDON_COLOR_BUTTON_GET_PRIVATE(cb);
-
-  cb->priv->dialog = NULL;
-  cb->priv->gc = NULL;
-
-  gtk_widget_push_composite_child();
-  
-  /* create widgets and pixbuf */
-  align = gtk_alignment_new(0.5, 0.5, 0, 0); /*composite widget*/
-
-  drawing_area = gtk_drawing_area_new(); /*composite widget*/
-
-  /* setting minimum sizes */
-  gtk_widget_set_size_request(GTK_WIDGET(cb), COLOR_BUTTON_WIDTH,
-                              COLOR_BUTTON_HEIGHT);
-  gtk_widget_set_size_request(GTK_WIDGET(drawing_area),
-                              COLOR_FILLED_WIDTH, COLOR_FILLED_HEIGHT);
-
-  /* Connect the callback function for exposure event */
-  g_signal_connect(drawing_area, "expose-event",
-                   G_CALLBACK(hildon_color_field_expose_event), cb);
-
-  /* Connect to callback function for key press event */
-  g_signal_connect(G_OBJECT(cb), "key-press-event",
-                  G_CALLBACK(hildon_color_button_key_pressed), cb);
-  
-  /* packing */
-  gtk_container_add(GTK_CONTAINER(align), drawing_area);
-  gtk_container_add(GTK_CONTAINER(cb), align);
-  
-  gtk_widget_show_all(align);
-  
-  gtk_widget_pop_composite_child();
+    GtkWidget *align;
+    GtkWidget *drawing_area;
+    HildonColorButtonPrivate *priv = HILDON_COLOR_BUTTON_GET_PRIVATE (cb);
+
+    priv->dialog = NULL;
+    priv->gc = NULL;
+    priv->popped = FALSE;
+
+    gtk_widget_push_composite_child ();
+
+    /* create widgets and pixbuf */
+    align = gtk_alignment_new (0.5, 0.5, 0, 0); /* composite widget */
+
+    drawing_area = gtk_drawing_area_new (); /* composite widget */
+
+    /* setting minimum sizes */
+    gtk_widget_set_size_request (GTK_WIDGET (cb), COLOR_BUTTON_WIDTH,
+            COLOR_BUTTON_HEIGHT);
+
+    gtk_widget_set_size_request (GTK_WIDGET(drawing_area),
+            COLOR_FILLED_WIDTH, COLOR_FILLED_HEIGHT);
+
+    /* Connect the callback function for exposure event */
+    g_signal_connect (drawing_area, "expose-event",
+            G_CALLBACK (hildon_color_field_expose_event), cb);
+
+    /* Connect to callback function for key press event */
+    g_signal_connect (G_OBJECT(cb), "key-press-event",
+            G_CALLBACK(hildon_color_button_key_pressed), cb);
+
+    /* packing */
+    gtk_container_add (GTK_CONTAINER (align), drawing_area);
+    gtk_container_add (GTK_CONTAINER (cb), align);
+
+    gtk_widget_show_all (align);
+
+    gtk_widget_pop_composite_child ();
 }
 
 /* Free memory used by HildonColorButton */
 static void
-hildon_color_button_finalize(GObject *object)
+hildon_color_button_finalize                    (GObject *object)
 {
-  HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
+    HildonColorButtonPrivate *priv = HILDON_COLOR_BUTTON_GET_PRIVATE (object);
+    g_assert (priv);
 
-  if (cb->priv->dialog)
-  {
-    gtk_widget_destroy(cb->priv->dialog);
-    cb->priv->dialog = NULL;
-  }
+    if (priv->dialog)
+    {
+        gtk_widget_destroy (priv->dialog);
+        priv->dialog = NULL;
+    }
 
-  if( G_OBJECT_CLASS(parent_class)->finalize )
-    G_OBJECT_CLASS(parent_class)->finalize(object);
+    if (G_OBJECT_CLASS (parent_class)->finalize)
+        G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 static void
-hildon_color_button_realize(GtkWidget *widget)
+hildon_color_button_realize                     (GtkWidget *widget)
 {
-  HildonColorButton *cb = HILDON_COLOR_BUTTON(widget);
+    HildonColorButtonPrivate *priv = HILDON_COLOR_BUTTON_GET_PRIVATE (widget);
+    g_assert (priv);
 
-  GTK_WIDGET_CLASS(parent_class)->realize(widget);
+    GTK_WIDGET_CLASS (parent_class)->realize (widget);
 
-  cb->priv->gc = gdk_gc_new(widget->window);
+    priv->gc = gdk_gc_new (widget->window);
 }
 
 static void
-hildon_color_button_unrealize(GtkWidget *widget)
+hildon_color_button_unrealize                   (GtkWidget *widget)
 {
-  HildonColorButton *cb = HILDON_COLOR_BUTTON(widget);
+    HildonColorButtonPrivate *priv = HILDON_COLOR_BUTTON_GET_PRIVATE (widget);
+    g_assert (priv);
 
-  g_object_unref(cb->priv->gc);
-  cb->priv->gc = NULL;
+    if (priv->gc != NULL) { 
+        g_object_unref (priv->gc);
+        priv->gc = NULL;
+    }
 
-  GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
+    GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
 }
 
 /* Make the widget sensitive with the keyboard event */
 static gboolean
-hildon_color_button_mnemonic_activate( GtkWidget *widget,
-                                       gboolean group_cycling )
+hildon_color_button_mnemonic_activate           (GtkWidget *widget,
+                                                 gboolean group_cycling)
 {
-  gtk_widget_grab_focus( widget );
-  return TRUE;
+    gtk_widget_grab_focus (widget);
+    return TRUE;
 }
 
 /* Popup a color selector dialog on button click */
 static void
-hildon_color_button_clicked(GtkButton *button)
+hildon_color_button_clicked                     (GtkButton *button)
 {
-  HildonColorButton *cb = HILDON_COLOR_BUTTON(button);
-  HildonColorChooserDialog *cs_dialog = HILDON_COLOR_CHOOSER_DIALOG(cb->priv->dialog);
-  
-  /* Popup the color selector dialog */
-  if (!cs_dialog)
-  {
-    /* The dialog hasn't been created yet, do it. */
-    GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(cb));
-    cb->priv->dialog = hildon_color_chooser_dialog_new();
-    cs_dialog = HILDON_COLOR_CHOOSER_DIALOG(cb->priv->dialog);
-    if (parent)
-      gtk_window_set_transient_for(GTK_WINDOW(cs_dialog), GTK_WINDOW(parent));
-  }
-
-  /* Set the initial color for the color selector dialog */
-  hildon_color_chooser_dialog_set_color(cs_dialog, &cb->priv->color);
-  /* Update the color for color button if selection was made */
-  if (gtk_dialog_run(GTK_DIALOG(cs_dialog)) == GTK_RESPONSE_OK)
-  {
-    hildon_color_chooser_dialog_get_color(cs_dialog, &cb->priv->color);
-    hildon_color_button_set_color( HILDON_COLOR_BUTTON( button ), 
-            &(cb->priv->color) );
-  } 
-
-  gtk_widget_hide(GTK_WIDGET(cs_dialog));
+    HildonColorButton *cb = HILDON_COLOR_BUTTON (button);
+    HildonColorButtonPrivate *priv = HILDON_COLOR_BUTTON_GET_PRIVATE (button);
+    HildonColorChooserDialog *cs_dialog;
+    
+    g_assert (priv);
+    
+    cs_dialog = (HildonColorChooserDialog *) priv->dialog;
+
+    /* Popup the color selector dialog */
+    if (! cs_dialog)
+    {
+        /* The dialog hasn't been created yet, do it */
+        GtkWidget *parent = gtk_widget_get_toplevel (GTK_WIDGET(cb));
+        priv->dialog = hildon_color_chooser_dialog_new ();
+        cs_dialog = HILDON_COLOR_CHOOSER_DIALOG (priv->dialog);
+        if (parent)
+            gtk_window_set_transient_for (GTK_WINDOW (cs_dialog), GTK_WINDOW (parent));
+
+        g_signal_emit (button, signals[SETUP_DIALOG], 0, priv->dialog);
+    }
+
+    /* Set the initial color for the color selector dialog */
+    hildon_color_chooser_dialog_set_color (cs_dialog, &priv->color);
+
+    /* Update the color for color button if selection was made */
+    priv->popped = TRUE;
+    if (gtk_dialog_run (GTK_DIALOG (cs_dialog)) == GTK_RESPONSE_OK)
+    {
+        hildon_color_chooser_dialog_get_color (cs_dialog, &priv->color);
+        hildon_color_button_set_color (HILDON_COLOR_BUTTON (button), &priv->color);
+        // FIXME A queue-draw should be enough here (not set needed)
+    } 
+
+    gtk_widget_hide (GTK_WIDGET(cs_dialog));
+    priv->popped = FALSE;
 }
 
-/* Popup a color selector dialog on hardkey Select press */
+/* Popup a color selector dialog on hardkey Select press.
+ * FIXME This is a bit hacky, should work without thi. Check. */
 static gboolean
-hildon_color_button_key_pressed(GtkWidget * button, 
-                                GdkEventKey * event,
-                                gpointer data)
+hildon_color_button_key_pressed                 (GtkWidget *button, 
+                                                 GdkEventKey *event,
+                                                 gpointer data)
 {
-  g_return_val_if_fail (HILDON_IS_COLOR_BUTTON(button), FALSE);
+    g_return_val_if_fail (HILDON_IS_COLOR_BUTTON (button), FALSE);
 
-  if (event->keyval == HILDON_HARDKEY_SELECT)
-  {
-    hildon_color_button_clicked(GTK_BUTTON(button));
-    return TRUE;
-  }
-  
-  return FALSE;
+    if (event->keyval == HILDON_HARDKEY_SELECT)
+    {
+        hildon_color_button_clicked (GTK_BUTTON (button));
+        return TRUE;
+    }
+
+    return FALSE;
 }
 
-/* Set_property function for HildonColorButtonClass initialization */
 static void
-hildon_color_button_set_property(GObject *object, guint param_id,
-                                 const GValue *value, GParamSpec *pspec)
+hildon_color_button_set_property                (GObject *object, 
+                                                 guint param_id,
+                                                 const GValue *value, 
+                                                 GParamSpec *pspec)
 {
-  HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
+    HildonColorButton *cb = HILDON_COLOR_BUTTON (object);
+    HildonColorButtonPrivate *priv = HILDON_COLOR_BUTTON_GET_PRIVATE (cb);
+    g_assert (priv);
 
-  switch (param_id) 
+    switch (param_id) 
     {
-    case PROP_COLOR:
-      cb->priv->color = *(GdkColor*)g_value_get_boxed(value);
-      gtk_widget_queue_draw(GTK_WIDGET(cb));
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
-      break;
+
+        case PROP_COLOR:
+            priv->color = *(GdkColor *) g_value_get_boxed (value); 
+            gtk_widget_queue_draw (GTK_WIDGET (cb));
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+            break;
     }
 }
 
-/* Get_property function for HildonColorButtonClass initialization */
 static void
-hildon_color_button_get_property(GObject *object, guint param_id,
-                                 GValue *value, GParamSpec *pspec)
+hildon_color_button_get_property                (GObject *object, 
+                                                 guint param_id,
+                                                 GValue *value, 
+                                                 GParamSpec *pspec)
 {
-  HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
+    HildonColorButton *cb = HILDON_COLOR_BUTTON (object);
+    HildonColorButtonPrivate *priv = HILDON_COLOR_BUTTON_GET_PRIVATE (cb);
+    g_assert (priv);
 
-  switch (param_id) 
+    switch (param_id) 
     {
-    case PROP_COLOR:
-      g_value_set_boxed(value, &cb->priv->color);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
-      break;
+
+        case PROP_COLOR:
+            g_value_set_boxed (value, &priv->color);
+            break;
+
+        case PROP_POPUP_SHOWN:
+            g_value_set_boolean (value, priv->popped);
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+            break;
     }
 }
 
@@ -442,10 +543,10 @@ hildon_color_button_get_property(GObject *object, guint param_id,
  *
  * Returns: a new color button
  */
-GtkWidget *
-hildon_color_button_new(void)
+GtkWidget*
+hildon_color_button_new                         (void)
 {
-  return g_object_new( HILDON_TYPE_COLOR_BUTTON, NULL );
+    return g_object_new (HILDON_TYPE_COLOR_BUTTON, NULL);
 }
 
 /**
@@ -456,10 +557,10 @@ hildon_color_button_new(void)
  *
  * Returns: a new color button
  */
-GtkWidget *
-hildon_color_button_new_with_color(const GdkColor *color)
+GtkWidget*
+hildon_color_button_new_with_color              (const GdkColor *color)
 {
-  return g_object_new( HILDON_TYPE_COLOR_BUTTON, "color", color, NULL );
+    return g_object_new (HILDON_TYPE_COLOR_BUTTON, "color", color, NULL);
 }
 
 /**
@@ -470,21 +571,78 @@ hildon_color_button_new_with_color(const GdkColor *color)
  * Sets the color selected by the button.
  */
 void
-hildon_color_button_set_color( HildonColorButton *button, GdkColor *color )
+hildon_color_button_set_color                   (HildonColorButton *button, 
+                                                 GdkColor *color)
 {
-  g_object_set( G_OBJECT(button), "color", color, NULL );
+    g_return_if_fail (HILDON_IS_COLOR_BUTTON (button));
+
+    g_object_set (G_OBJECT (button), "color", color, NULL);
+}
+
+/**
+ * hildon_color_button_get_popup_shown
+ * @button: a #HildonColorButton
+ *
+ * This function checks if the color button has the color 
+ * selection dialog currently popped-up. 
+ * 
+ * Returns: TRUE if the dialog is popped-up (visible to user).
+ *
+ */
+gboolean
+hildon_color_button_get_popup_shown             (HildonColorButton *button)
+{
+    HildonColorButtonPrivate *priv = NULL; 
+    g_return_val_if_fail (HILDON_IS_COLOR_BUTTON (button), FALSE);
+
+    priv = HILDON_COLOR_BUTTON_GET_PRIVATE (button);
+    g_assert (priv);
+
+    return priv->popped;
+}
+
+/**
+ * hildon_color_button_popdown
+ * @button: a #HildonColorButton
+ *
+ * If the color selection dialog is currently popped-up (visible)
+ * it will be popped-down (hidden).
+ *
+ */
+void
+hildon_color_button_popdown                     (HildonColorButton *button)
+{
+    HildonColorButtonPrivate *priv = NULL; 
+    g_return_if_fail (HILDON_IS_COLOR_BUTTON (button));
+
+    priv = HILDON_COLOR_BUTTON_GET_PRIVATE (button);
+    g_assert (priv);
+
+    if (priv->popped && priv->dialog) {
+        gtk_dialog_response (GTK_DIALOG (priv->dialog), GTK_RESPONSE_CANCEL);
+    }
 }
 
 /**
  * hildon_color_button_get_color:
  * @button: a #HildonColorButton
+ * @color: a color #GdkColor to be fillled with the current color
  *
- * Returns: the color selected by the button
  */
-GdkColor *
-hildon_color_button_get_color( HildonColorButton *button )
+void
+hildon_color_button_get_color                   (HildonColorButton *button, 
+                                                 GdkColor *color)
 {
-  GdkColor *color = NULL;
-  g_object_get( G_OBJECT(button), "color", &color, NULL );
-  return color;
+    HildonColorButtonPrivate *priv = NULL; 
+    g_return_if_fail (HILDON_IS_COLOR_BUTTON (button));
+    g_return_if_fail (color != NULL);
+   
+    priv = HILDON_COLOR_BUTTON_GET_PRIVATE (button);
+    g_assert (priv);
+
+    color->red = priv->color.red;
+    color->green = priv->color.green;
+    color->blue = priv->color.blue;
+    color->pixel = priv->color.pixel;
 }
+