[dia] Bug #591525 - independence of color and alpha editing



commit c3f689f65e17d529a92a9de3f5709bfed0edefe7
Author: Hans Breuer <hans breuer org>
Date:   Sun Apr 3 17:30:46 2011 +0200

    Bug #591525 - independence of color and alpha editing
    
    The alpha value is not any longer part of the color menu.
    Instead there is an additional color button reflecting the
    set alpha value and allowing to edit color and transparency.
    
    For places where alpha is not useful the DiaColorSelection
    can be instantiated without showing alpha at all.
    
    This is basically solving my objections raised in
    https://bugzilla.gnome.org/show_bug.cgi?id=591525#c16

 lib/prop_attr.c |    1 +
 lib/widgets.c   |  219 +++++++++++++++++++++++++++++++++++++++++++-----------
 lib/widgets.h   |    2 +-
 3 files changed, 176 insertions(+), 46 deletions(-)
---
diff --git a/lib/prop_attr.c b/lib/prop_attr.c
index 9fb83d6..8b891bc 100644
--- a/lib/prop_attr.c
+++ b/lib/prop_attr.c
@@ -297,6 +297,7 @@ static WIDGET *
 colorprop_get_widget(ColorProperty *prop, PropDialog *dialog)
 { 
   GtkWidget *ret = dia_color_selector_new();
+  dia_color_selector_set_use_alpha (ret, TRUE);
   prophandler_connect(&prop->common, G_OBJECT(ret), "value-changed");
   return ret;
 }
diff --git a/lib/widgets.c b/lib/widgets.c
index dc2745c..6aa0ceb 100644
--- a/lib/widgets.c
+++ b/lib/widgets.c
@@ -521,6 +521,124 @@ dia_line_style_selector_set_linestyle (DiaLineStyleSelector *as,
 
 
 /************* DiaColorSelector: ***************/
+struct _DiaColorSelector
+{
+  GtkHBox         hbox; /* just contaning the other two widgets */
+  DiaDynamicMenu *ddm; /* the widget previously alone */
+  GtkColorButton *color_button; /* to reflect alpha */
+  gboolean        use_alpha;
+};
+struct _DiaColorSelectorClass
+{
+  GtkHBoxClass parent_class;
+};
+enum {
+  DIA_COLORSEL_VALUE_CHANGED,
+  DIA_COLORSEL_LAST_SIGNAL
+};
+static guint dia_colorsel_signals[DIA_COLORSEL_LAST_SIGNAL] = { 0 };
+
+static GtkWidget *dia_color_selector_menu_new (DiaColorSelector *cs);
+
+static void
+dia_color_selector_class_init (DiaColorSelector *class)
+{
+  dia_colorsel_signals[DIA_COLORSEL_VALUE_CHANGED]
+      = g_signal_new("value_changed",
+		     G_TYPE_FROM_CLASS(class),
+		     G_SIGNAL_RUN_FIRST,
+		     0, NULL, NULL,
+		     g_cclosure_marshal_VOID__VOID,
+		     G_TYPE_NONE, 0);
+}
+static void
+dia_color_selector_color_set (GtkColorButton *button, gpointer user_data)
+{
+  DiaColorSelector *cs = DIACOLORSELECTOR(user_data);
+  gchar *entry;
+  GdkColor gcol;
+
+  gtk_color_button_get_color (button, &gcol);
+
+  entry = g_strdup_printf("#%02X%02X%02X", gcol.red/256, gcol.green/256, gcol.blue/256);
+  dia_dynamic_menu_select_entry(cs->ddm, entry);
+  g_free(entry);
+
+  g_signal_emit (G_OBJECT (cs), dia_colorsel_signals[DIA_COLORSEL_VALUE_CHANGED], 0);
+}
+static void
+dia_color_selector_value_changed (DiaDynamicMenu *ddm, gpointer user_data)
+{
+  DiaColorSelector *cs = DIACOLORSELECTOR(user_data);
+  gchar *entry = dia_dynamic_menu_get_entry(cs->ddm);
+  GdkColor gcol;
+
+  gdk_color_parse (entry, &gcol);
+  g_free(entry);
+  gtk_color_button_set_color (cs->color_button, &gcol);
+
+  g_signal_emit (G_OBJECT (cs), dia_colorsel_signals[DIA_COLORSEL_VALUE_CHANGED], 0);
+}
+static void
+dia_color_selector_init (DiaColorSelector *cs)
+{
+  cs->ddm = DIA_DYNAMIC_MENU(dia_color_selector_menu_new(cs));
+  cs->color_button = GTK_COLOR_BUTTON (gtk_color_button_new ());
+  
+  gtk_widget_show (GTK_WIDGET (cs->ddm));
+
+  /* default off */
+  gtk_color_button_set_use_alpha (cs->color_button, cs->use_alpha);
+  /* delegate color changes to compound object */
+  g_signal_connect (G_OBJECT (cs->color_button), "color-set", 
+		    G_CALLBACK (dia_color_selector_color_set), cs);
+  /* listen to menu selction to update the button */
+  g_signal_connect (G_OBJECT (cs->ddm), "value-changed",
+		    G_CALLBACK (dia_color_selector_value_changed), cs);
+
+  if (cs->use_alpha)
+    gtk_widget_show (GTK_WIDGET (cs->color_button));
+
+  gtk_box_pack_start(GTK_BOX(cs), GTK_WIDGET(cs->ddm), TRUE, TRUE, 0);
+  gtk_box_pack_start(GTK_BOX(cs), GTK_WIDGET(cs->color_button), TRUE, TRUE, 0);
+}
+void
+dia_color_selector_set_use_alpha (GtkWidget *widget, gboolean use_alpha)
+{
+  DiaColorSelector *cs = DIACOLORSELECTOR(widget);
+
+  if (use_alpha)
+    gtk_widget_show (GTK_WIDGET (cs->color_button));
+  else
+    gtk_widget_hide (GTK_WIDGET (cs->color_button));
+  cs->use_alpha = use_alpha;
+  gtk_color_button_set_use_alpha (cs->color_button, cs->use_alpha);
+}
+GType
+dia_color_selector_get_type (void)
+{
+  static GType dcs_type = 0;
+
+  if (!dcs_type) {
+    static const GTypeInfo dcs_info = {
+      sizeof (DiaColorSelectorClass),
+      (GBaseInitFunc)NULL,
+      (GBaseFinalizeFunc)NULL,
+      (GClassInitFunc) dia_color_selector_class_init,
+      NULL, /* class_finalize */
+      NULL, /* class_data */
+      sizeof (DiaColorSelector),
+      0, /* n_preallocs */
+      (GInstanceInitFunc) dia_color_selector_init
+    };
+    
+    dcs_type = g_type_register_static (gtk_hbox_get_type (),
+				       "DiaColorSelector", 
+				       &dcs_info, 0);
+  }
+  
+  return dcs_type;
+}
 
 static GtkWidget *
 dia_color_selector_create_string_item(DiaDynamicMenu *ddm, gchar *string)
@@ -552,7 +670,7 @@ dia_color_selector_create_string_item(DiaDynamicMenu *ddm, gchar *string)
 static void
 dia_color_selector_more_ok(GtkWidget *ok, gpointer userdata)
 {
-  DiaDynamicMenu *ddm = g_object_get_data(G_OBJECT(userdata), "ddm");
+  DiaColorSelector *cs = g_object_get_data(G_OBJECT(userdata), "dia-cs");
   GtkWidget *colorsel = GTK_WIDGET(userdata);
   GdkColor gcol;
   guint galpha;
@@ -567,9 +685,12 @@ dia_color_selector_more_ok(GtkWidget *ok, gpointer userdata)
         GTK_COLOR_SELECTION(
             GTK_COLOR_SELECTION_DIALOG(colorsel)->colorsel));
 
-  entry = g_strdup_printf("#%02X%02X%02X%02X", gcol.red/256, gcol.green/256, gcol.blue/256, galpha/256);
-  dia_dynamic_menu_select_entry(ddm, entry);
+  entry = g_strdup_printf("#%02X%02X%02X", gcol.red/256, gcol.green/256, gcol.blue/256);
+  dia_dynamic_menu_select_entry(cs->ddm, entry);
   g_free(entry);
+  /* update color button */
+  gtk_color_button_set_color (cs->color_button, &gcol);
+  gtk_color_button_set_alpha (cs->color_button, galpha);
 
   gtk_widget_destroy(colorsel);
 }
@@ -578,17 +699,21 @@ static void
 dia_color_selector_more_callback(GtkWidget *widget, gpointer userdata)
 {
   GtkColorSelectionDialog *dialog = GTK_COLOR_SELECTION_DIALOG (gtk_color_selection_dialog_new(_("Select color")));
-  DiaDynamicMenu *ddm = DIA_DYNAMIC_MENU(userdata);
+  DiaColorSelector *cs = DIACOLORSELECTOR(userdata);
   GtkColorSelection *colorsel = GTK_COLOR_SELECTION(dialog->colorsel);
   GString *palette = g_string_new ("");
 
-  gchar *old_color = dia_dynamic_menu_get_entry(ddm);
+  gchar *old_color = dia_dynamic_menu_get_entry(cs->ddm);
   GtkWidget *parent;
 
-  gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
+  gtk_color_selection_set_has_opacity_control(colorsel, cs->use_alpha);
 
+  if (cs->use_alpha) {
+    gtk_color_selection_set_previous_alpha (colorsel, 65535);
+    gtk_color_selection_set_current_alpha (colorsel, gtk_color_button_get_alpha (cs->color_button));
+  }
   /* Force history to the old place */
-  dia_dynamic_menu_select_entry(ddm, old_color);
+  dia_dynamic_menu_select_entry(cs->ddm, old_color);
 
   /* avoid crashing if the property dialog is closed before the color dialog */
   parent = widget;
@@ -599,39 +724,27 @@ dia_color_selector_more_callback(GtkWidget *widget, gpointer userdata)
     gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
   }
 
-  if (dia_dynamic_menu_get_default_entries(ddm) != NULL) {
+  if (dia_dynamic_menu_get_default_entries(cs->ddm) != NULL) {
     GList *tmplist;
     int index = 0;
     gboolean advance = TRUE;
 
-    for (tmplist = dia_dynamic_menu_get_default_entries(ddm); 
+    for (tmplist = dia_dynamic_menu_get_default_entries(cs->ddm); 
          tmplist != NULL || advance; 
          tmplist = g_list_next(tmplist)) {
       const gchar* spec;
-      guint r, g, b, a, old_a;
       GdkColor color;
 
       /* handle both lists */
       if (!tmplist && advance) {
         advance = FALSE;
-        tmplist = persistent_list_get_glist(dia_dynamic_menu_get_persistent_name(ddm));
+        tmplist = persistent_list_get_glist(dia_dynamic_menu_get_persistent_name(cs->ddm));
         if (!tmplist)
           break;
       }
 
-      if (sscanf((gchar *)tmplist->data,"#%02X%02X%02X%02X", &r, &g, &b, &a) != 4) {
-        /* We don't have alpha, default to 1.0 */
-        a = 65535;
-      } else {
-        a = (guint)((((float)a) / 255.0) * 65535.0);
-      }
-      if (sscanf(old_color,"#%02X%02X%02X%02X", &r, &g, &b, &old_a) != 4) {
-        /* We don't have alpha, default to 1.0 */
-        old_a = 65535;
-      } else {
-        old_a = (guint)((((float)old_a) / 255.0) * 65535.0);
-      }
-      spec = g_strndup((gchar *)tmplist->data, 7);
+      spec = tmplist->data;
+
       gdk_color_parse (spec, &color);
 #if 0
       /* the easy way if the Gtk Team would decide to make it public */
@@ -640,14 +753,11 @@ dia_color_selector_more_callback(GtkWidget *widget, gpointer userdata)
       g_string_append (palette, spec);
       g_string_append (palette, ":");
 #endif
-      if (0 == strcmp ((gchar *)tmplist->data, old_color) && a == old_a) {
+      if (0 == strcmp (spec, old_color)) {
         gtk_color_selection_set_previous_color (colorsel, &color);
         gtk_color_selection_set_current_color (colorsel, &color);
-        gtk_color_selection_set_previous_alpha (colorsel, a);
-        gtk_color_selection_set_current_alpha (colorsel, a);
       }
       index++;
-      g_free(spec);
     }
   }
 
@@ -661,14 +771,14 @@ dia_color_selector_more_callback(GtkWidget *widget, gpointer userdata)
   g_signal_connect (G_OBJECT (dialog->ok_button), "clicked",
 		    G_CALLBACK (dia_color_selector_more_ok), dialog);  
   g_signal_connect_swapped (G_OBJECT (dialog->cancel_button), "clicked",
-			    gtk_widget_destroy, G_OBJECT(dialog));
-  g_object_set_data(G_OBJECT(dialog), "ddm", ddm);
+			    G_CALLBACK(gtk_widget_destroy), G_OBJECT(dialog));
+  g_object_set_data(G_OBJECT(dialog), "dia-cs", cs);
 
   gtk_widget_show(GTK_WIDGET(dialog));
 }
 
-GtkWidget *
-dia_color_selector_new ()
+static GtkWidget *
+dia_color_selector_menu_new (DiaColorSelector *cs)
 {
   GtkWidget *otheritem = gtk_menu_item_new_with_label(_("More colorsâ?¦"));
   GtkWidget *ddm = dia_dynamic_menu_new(dia_color_selector_create_string_item,
@@ -676,40 +786,51 @@ dia_color_selector_new ()
 					GTK_MENU_ITEM(otheritem),
 					"color-menu");
   dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(ddm),
-				     "#000000FF");
+				     "#000000");
   dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(ddm),
-				     "#FFFFFFFF");
+				     "#FFFFFF");
   dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(ddm),
-				     "#FF0000FF");
+				     "#FF0000");
   dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(ddm),
-				     "#00FF00FF");
+				     "#00FF00");
   dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(ddm),
-				     "#0000FFFF");
+				     "#0000FF");
   g_signal_connect(G_OBJECT(otheritem), "activate",
-		   G_CALLBACK(dia_color_selector_more_callback), ddm);
+		   G_CALLBACK(dia_color_selector_more_callback), cs);
   gtk_widget_show(otheritem);
   return ddm;
 }
 
-
+GtkWidget *
+dia_color_selector_new ()
+{
+  return GTK_WIDGET ( gtk_type_new (dia_color_selector_get_type ()));
+}
 void
 dia_color_selector_get_color(GtkWidget *widget, Color *color)
 {
-  gchar *entry = dia_dynamic_menu_get_entry(DIA_DYNAMIC_MENU(widget));
-  gint r, g, b, a;
+  DiaColorSelector *cs = DIACOLORSELECTOR(widget);
+  gchar *entry = dia_dynamic_menu_get_entry(cs->ddm);
+  gint r, g, b;
 
-  sscanf(entry, "#%2x%2x%2x%2x", &r, &g, &b, &a);
+  sscanf(entry, "#%2x%2x%2x", &r, &g, &b);
   g_free(entry);
   color->red = r / 255.0;
   color->green = g / 255.0;
   color->blue = b / 255.0;
-  color->alpha = a / 255.0;
+
+  if (cs->use_alpha) {
+    color->alpha = gtk_color_button_get_alpha (cs->color_button) / 65535.0;
+  } else {
+    color->alpha = 1.0;
+  }
 }
 
 void
 dia_color_selector_set_color (GtkWidget *widget,
 			      const Color *color)
 {
+  DiaColorSelector *cs = DIACOLORSELECTOR(widget);
   gint red, green, blue, alpha;
   gchar *entry;
   red = color->red * 255;
@@ -724,9 +845,17 @@ dia_color_selector_set_color (GtkWidget *widget,
     blue = MIN(blue, 255);
     alpha = MIN(alpha, 255);
   }
-  entry = g_strdup_printf("#%02X%02X%02X%02X", red, green, blue, alpha);
-  dia_dynamic_menu_select_entry(DIA_DYNAMIC_MENU(widget), entry);
+  entry = g_strdup_printf("#%02X%02X%02X", red, green, blue);
+  dia_dynamic_menu_select_entry(DIA_DYNAMIC_MENU(cs->ddm), entry);
   g_free (entry);
+
+  if (cs->use_alpha) {
+    GdkColor gcol;
+
+    color_convert (color, &gcol);
+    gtk_color_button_set_color (cs->color_button, &gcol);
+    gtk_color_button_set_alpha (cs->color_button, MIN(color->alpha * 65535, 65535));
+  }
 }
 
 
diff --git a/lib/widgets.h b/lib/widgets.h
index 68a91cf..0f9f38e 100644
--- a/lib/widgets.h
+++ b/lib/widgets.h
@@ -55,9 +55,9 @@ void       dia_line_style_selector_set_linestyle (DiaLineStyleSelector *as,
 #define DIACOLORSELECTOR_CLASS(klass)  G_TYPE_CHECK_CLASS_CAST (klass, dia_color_selector_get_type (), DiaColorSelectorClass)
 #define IS_DIACOLORSELECTOR(obj)       G_TYPE_CHECK_INSTANCE_TYPE (obj, dia_color_selector_get_type ())
 
-/* FIXME: _get_type is not implemented */
 GType      dia_color_selector_get_type  (void);
 GtkWidget* dia_color_selector_new       (void);
+void       dia_color_selector_set_use_alpha (GtkWidget *cs, gboolean use_alpha);
 void       dia_color_selector_get_color (GtkWidget *cs, Color *color);
 void       dia_color_selector_set_color (GtkWidget *cs,
 					 const Color *color);



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