[gnome-color-manager] Show much more detail in the color picker UI and allow the user to choose a RGB colorspace



commit 0b4393970626347b8c1e2c9d26f66326fa823c8d
Author: Richard Hughes <richard hughsie com>
Date:   Tue Apr 27 22:14:25 2010 +0100

    Show much more detail in the color picker UI and allow the user to choose a RGB colorspace

 data/gcm-picker.ui |   48 ++++++++++-
 po/POTFILES.in     |    1 +
 src/Makefile.am    |    1 +
 src/gcm-picker.c   |  231 ++++++++++++++++++++++++++++++++++++++++++++++++----
 4 files changed, 264 insertions(+), 17 deletions(-)
---
diff --git a/data/gcm-picker.ui b/data/gcm-picker.ui
index ca3575f..6849fed 100644
--- a/data/gcm-picker.ui
+++ b/data/gcm-picker.ui
@@ -232,6 +232,49 @@
                         <property name="position">3</property>
                       </packing>
                     </child>
+                    <child>
+                      <object class="GtkHBox" id="hbox_error">
+                        <property name="visible">True</property>
+                        <property name="spacing">12</property>
+                        <child>
+                          <object class="GtkHBox" id="hbox_error_align">
+                            <property name="visible">True</property>
+                            <child>
+                              <object class="GtkLabel" id="label_error_title">
+                                <property name="visible">True</property>
+                                <property name="label" translatable="yes" comments="This shows the error in the conversion to RGB.">Error:</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label_error">
+                            <property name="visible">True</property>
+                            <property name="selectable">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">4</property>
+                      </packing>
+                    </child>
                   </object>
                 </child>
                 <child type="label">
@@ -303,10 +346,11 @@
   </object>
   <object class="GtkSizeGroup" id="sizegroup_titles">
     <widgets>
-      <widget name="hbox_rgb_align"/>
-      <widget name="hbox_colorspace_align"/>
       <widget name="hbox_xyz_align"/>
       <widget name="hbox_lab_align"/>
+      <widget name="hbox_colorspace_align"/>
+      <widget name="hbox_rgb_align"/>
+      <widget name="hbox_error_align"/>
     </widgets>
   </object>
 </interface>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5f40e5c..44d141f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -13,6 +13,7 @@ src/gcm-colorimeter.c
 src/gcm-device-xrandr.c
 src/gcm-dump-edid.c
 src/gcm-dump-profile.c
+src/gcm-enum.c
 src/gcm-fix-profile.c
 src/gcm-import.c
 src/gcm-inspect.c
diff --git a/src/Makefile.am b/src/Makefile.am
index aac8966..df069f3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,6 +19,7 @@ INCLUDES =						\
 	$(GUDEV_CFLAGS)					\
 	-DBINDIR=\"$(bindir)\"				\
 	-DSBINDIR=\"$(sbindir)\"			\
+	-DDATADIR=\"$(datadir)\"			\
 	-DSYSCONFDIR=\""$(sysconfdir)"\"		\
 	-DVERSION="\"$(VERSION)\""			\
 	-DLOCALEDIR=\""$(localedir)"\"			\
diff --git a/src/gcm-picker.c b/src/gcm-picker.c
index 4c056f8..cd7862e 100644
--- a/src/gcm-picker.c
+++ b/src/gcm-picker.c
@@ -33,8 +33,9 @@
 
 #include "egg-debug.h"
 
-#include "gcm-colorimeter.h"
 #include "gcm-calibrate-argyll.h"
+#include "gcm-colorimeter.h"
+#include "gcm-profile-store.h"
 #include "gcm-utils.h"
 #include "gcm-xyz.h"
 
@@ -42,6 +43,15 @@ static GtkBuilder *builder = NULL;
 static GtkWidget *info_bar_hardware = NULL;
 static GtkWidget *info_bar_hardware_label = NULL;
 static GcmCalibrate *calibrate = NULL;
+static GcmProfileStore *profile_store = NULL;
+static const gchar *profile_filename = NULL;
+static gboolean done_measure = FALSE;
+
+enum {
+	GCM_PREFS_COMBO_COLUMN_TEXT,
+	GCM_PREFS_COMBO_COLUMN_PROFILE,
+	GCM_PREFS_COMBO_COLUMN_LAST
+};
 
 /**
  * gcm_picker_set_pixbuf_color:
@@ -80,6 +90,10 @@ gcm_picker_measure_cb (GtkWidget *widget, gpointer data)
 	gboolean ret;
 	GError *error = NULL;
 
+	/* reset the image */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "image_preview"));
+	gtk_image_set_from_file (GTK_IMAGE (widget), DATADIR "/icons/hicolor/64x64/apps/gnome-color-manager.png");
+
 	/* get value */
 	window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_picker"));
 	ret = gcm_calibrate_spotread (calibrate, window, &error);
@@ -89,30 +103,30 @@ gcm_picker_measure_cb (GtkWidget *widget, gpointer data)
 	}
 }
 
-#define TYPE_XYZ_DBL2        (COLORSPACE_SH(PT_XYZ)|CHANNELS_SH(3)|BYTES_SH(sizeof(gdouble)))
-
 /**
- * gpk_update_viewer_notify_network_state_cb:
+ * gcm_picker_refresh_results:
  **/
 static void
-gcm_picker_xyz_notify_cb (GcmCalibrate *calibrate_, GParamSpec *pspec, gpointer user_data)
+gcm_picker_refresh_results (void)
 {
 	GcmXyz *xyz = NULL;
 	GtkImage *image;
 	GtkLabel *label;
 	GdkPixbuf *pixbuf = NULL;
-	GtkWidget *widget;
 	gdouble color_xyz[3];
 	guint8 color_rgb[3];
 	gdouble color_lab[3];
+	gdouble color_error[3];
 	gchar *text_xyz = NULL;
 	gchar *text_lab = NULL;
 	gchar *text_rgb = NULL;
+	gchar *text_error = NULL;
 	cmsHPROFILE profile_xyz;
 	cmsHPROFILE profile_rgb;
 	cmsHPROFILE profile_lab;
 	cmsHTRANSFORM transform_rgb;
 	cmsHTRANSFORM transform_lab;
+	cmsHTRANSFORM transform_error;
 
 	/* get new value */
 	g_object_get (calibrate, "xyz", &xyz, NULL);
@@ -135,19 +149,22 @@ gcm_picker_xyz_notify_cb (GcmCalibrate *calibrate_, GParamSpec *pspec, gpointer
 
 	/* get profiles */
 	profile_xyz = cmsCreateXYZProfile ();
-	profile_rgb = cmsCreate_sRGBProfile ();
+	profile_rgb = cmsOpenProfileFromFile (profile_filename, "r");
 	profile_lab = cmsCreateLabProfile (cmsD50_xyY ());
 
-	/* create transform_rgb */
-	transform_rgb = cmsCreateTransform (profile_xyz, TYPE_XYZ_DBL2, profile_rgb, TYPE_RGB_8, INTENT_PERCEPTUAL, 0);
-	transform_lab = cmsCreateTransform (profile_xyz, TYPE_XYZ_DBL2, profile_lab, TYPE_Lab_DBL, INTENT_PERCEPTUAL, 0);
+	/* create transforms */
+	transform_rgb = cmsCreateTransform (profile_xyz, TYPE_XYZ_DBL, profile_rgb, TYPE_RGB_8, INTENT_PERCEPTUAL, 0);
+	transform_lab = cmsCreateTransform (profile_xyz, TYPE_XYZ_DBL, profile_lab, TYPE_Lab_DBL, INTENT_PERCEPTUAL, 0);
+	transform_error = cmsCreateTransform (profile_rgb, TYPE_RGB_8, profile_xyz, TYPE_XYZ_DBL, INTENT_PERCEPTUAL, 0);
 
 	cmsDoTransform (transform_rgb, color_xyz, color_rgb, 1);
 	cmsDoTransform (transform_lab, color_xyz, color_lab, 1);
+	cmsDoTransform (transform_error, color_rgb, color_error, 1);
 
 	/* destroy lcms state */
 	cmsDeleteTransform (transform_rgb);
 	cmsDeleteTransform (transform_lab);
+	cmsDeleteTransform (transform_error);
 	cmsCloseProfile (profile_xyz);
 	cmsCloseProfile (profile_rgb);
 	cmsCloseProfile (profile_lab);
@@ -164,13 +181,19 @@ gcm_picker_xyz_notify_cb (GcmCalibrate *calibrate_, GParamSpec *pspec, gpointer
 
 	/* set RGB */
 	label = GTK_LABEL (gtk_builder_get_object (builder, "label_rgb"));
-	text_rgb = g_strdup_printf ("%i, %i, %i", color_rgb[0], color_rgb[1], color_rgb[2]);
+	text_rgb = g_strdup_printf ("%i, %i, %i (#%02X%02X%02X)",
+				    color_rgb[0], color_rgb[1], color_rgb[2],
+				    color_rgb[0], color_rgb[1], color_rgb[2]);
 	gtk_label_set_label (label, text_rgb);
 	gcm_picker_set_pixbuf_color (pixbuf, color_rgb[0], color_rgb[1], color_rgb[2]);
 
-	/* set XYZ */
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "expander_results"));
-	gtk_expander_set_expanded (GTK_EXPANDER (widget), TRUE);
+	/* set error */
+	label = GTK_LABEL (gtk_builder_get_object (builder, "label_error"));
+	text_error = g_strdup_printf ("%.1f%%, %.1f%%, %.1f%%",
+				      ABS ((color_error[0] - color_xyz[0]) / color_xyz[0] * 100),
+				      ABS ((color_error[1] - color_xyz[1]) / color_xyz[1] * 100),
+				      ABS ((color_error[2] - color_xyz[2]) / color_xyz[2] * 100));
+	gtk_label_set_label (label, text_error);
 
 	/* set image */
 	image = GTK_IMAGE (gtk_builder_get_object (builder, "image_preview"));
@@ -179,6 +202,7 @@ gcm_picker_xyz_notify_cb (GcmCalibrate *calibrate_, GParamSpec *pspec, gpointer
 	g_free (text_xyz);
 	g_free (text_lab);
 	g_free (text_rgb);
+	g_free (text_error);
 	if (xyz != NULL)
 		g_object_unref (xyz);
 	if (pixbuf != NULL)
@@ -186,6 +210,25 @@ gcm_picker_xyz_notify_cb (GcmCalibrate *calibrate_, GParamSpec *pspec, gpointer
 }
 
 /**
+ * gcm_picker_xyz_notify_cb:
+ **/
+static void
+gcm_picker_xyz_notify_cb (GcmCalibrate *calibrate_, GParamSpec *pspec, gpointer user_data)
+{
+	GtkWidget *widget;
+
+	/* set expanded */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "expander_results"));
+	gtk_expander_set_expanded (GTK_EXPANDER (widget), TRUE);
+	gtk_widget_set_sensitive (widget, TRUE);
+
+	/* we've got results so make sure it's sensitive */
+	done_measure = TRUE;
+
+	gcm_picker_refresh_results ();
+}
+
+/**
  * gcm_picker_close_cb:
  **/
 static void
@@ -242,7 +285,7 @@ gcm_picker_colorimeter_setup_ui (GcmColorimeter *colorimeter)
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_measure"));
 	gtk_widget_set_sensitive (widget, ret);
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "expander_results"));
-	gtk_widget_set_sensitive (widget, ret);
+	gtk_widget_set_sensitive (widget, ret && done_measure);
 	gtk_widget_set_visible (info_bar_hardware, !ret);
 }
 
@@ -298,6 +341,142 @@ gcm_picker_lcms_error_cb (gint error_code, const gchar *error_text)
 	return LCMS_ERRC_WARNING;
 }
 
+
+/**
+ * gcm_prefs_space_combo_changed_cb:
+ **/
+static void
+gcm_prefs_space_combo_changed_cb (GtkWidget *widget, gpointer data)
+{
+	gboolean ret;
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+	GcmProfile *profile = NULL;
+
+	/* no selection */
+	ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX(widget), &iter);
+	if (!ret)
+		goto out;
+
+	/* get profile */
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX(widget));
+	gtk_tree_model_get (model, &iter,
+			    GCM_PREFS_COMBO_COLUMN_PROFILE, &profile,
+			    -1);
+	if (profile == NULL)
+		goto out;
+
+	profile_filename = gcm_profile_get_filename (profile);
+	egg_debug ("changed picker space %s", profile_filename);
+	gcm_picker_refresh_results ();
+out:
+	if (profile != NULL)
+		g_object_unref (profile);
+}
+
+/**
+ * gcm_prefs_set_combo_simple_text:
+ **/
+static void
+gcm_prefs_set_combo_simple_text (GtkWidget *combo_box)
+{
+	GtkCellRenderer *renderer;
+	GtkListStore *store;
+
+	store = gtk_list_store_new (2, G_TYPE_STRING, GCM_TYPE_PROFILE);
+	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), GCM_PREFS_COMBO_COLUMN_TEXT, GTK_SORT_ASCENDING);
+	gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store));
+	g_object_unref (store);
+
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set (renderer,
+		      "ellipsize", PANGO_ELLIPSIZE_END,
+		      "wrap-mode", PANGO_WRAP_WORD_CHAR,
+		      "width-chars", 60,
+		      NULL);
+	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, TRUE);
+	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer,
+					"text", GCM_PREFS_COMBO_COLUMN_TEXT,
+					NULL);
+}
+
+/**
+ * gcm_prefs_combobox_add_profile:
+ **/
+static void
+gcm_prefs_combobox_add_profile (GtkWidget *widget, GcmProfile *profile, GtkTreeIter *iter)
+{
+	GtkTreeModel *model;
+	GtkTreeIter iter_tmp;
+	const gchar *description;
+
+	/* iter is optional */
+	if (iter == NULL)
+		iter = &iter_tmp;
+
+
+	/* also add profile */
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX(widget));
+	description = gcm_profile_get_description (profile);
+	gtk_list_store_append (GTK_LIST_STORE(model), iter);
+	gtk_list_store_set (GTK_LIST_STORE(model), iter,
+			    GCM_PREFS_COMBO_COLUMN_TEXT, description,
+			    GCM_PREFS_COMBO_COLUMN_PROFILE, profile,
+			    -1);
+}
+
+/**
+ * gcm_prefs_setup_space_combobox:
+ **/
+static void
+gcm_prefs_setup_space_combobox (GtkWidget *widget)
+{
+	GcmProfile *profile;
+	guint i;
+	const gchar *filename;
+	GcmColorspace colorspace;
+	gboolean has_profile = FALSE;
+	gboolean has_vcgt;
+	gboolean has_colorspace_description;
+	gchar *text = NULL;
+	GPtrArray *profile_array = NULL;
+	GtkTreeIter iter;
+
+	/* get new list */
+	profile_array = gcm_profile_store_get_array (profile_store);
+
+	/* update each list */
+	for (i=0; i<profile_array->len; i++) {
+		profile = g_ptr_array_index (profile_array, i);
+
+		/* only for correct kind */
+		has_vcgt = gcm_profile_get_has_vcgt (profile);
+		has_colorspace_description = gcm_profile_has_colorspace_description (profile);
+		colorspace = gcm_profile_get_colorspace (profile);
+		if (!has_vcgt && has_colorspace_description &&
+		    colorspace == GCM_COLORSPACE_RGB) {
+			gcm_prefs_combobox_add_profile (widget, profile, &iter);
+
+			/* set active option */
+			filename = gcm_profile_get_filename (profile);
+			if (g_strcmp0 (filename, profile_filename) == 0)
+				gtk_combo_box_set_active_iter (GTK_COMBO_BOX (widget), &iter);
+			has_profile = TRUE;
+		}
+	}
+	if (!has_profile) {
+		/* TRANSLATORS: this is when there are no profiles that can be used; the search term is either "RGB" or "CMYK" */
+		text = g_strdup_printf (_("No %s color spaces available"),
+					gcm_colorspace_to_localised_string (colorspace));
+		gtk_combo_box_append_text (GTK_COMBO_BOX(widget), text);
+		gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+		gtk_widget_set_sensitive (widget, FALSE);
+	}
+	if (profile_array != NULL)
+		g_ptr_array_unref (profile_array);
+	g_free (text);
+}
+
 /**
  * main:
  **/
@@ -421,12 +600,34 @@ main (int argc, char *argv[])
 	/* disable some ui if no hardware */
 	gcm_picker_colorimeter_setup_ui (colorimeter);
 
+	/* maintain a list of profiles */
+	profile_store = gcm_profile_store_new ();
+
+	/* default to AdobeRGB */
+	profile_filename = "/usr/share/color/icc/Argyll/ClayRGB1998.icm";
+
+	/* setup RGB combobox */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "combobox_colorspace"));
+	gcm_prefs_set_combo_simple_text (widget);
+	gcm_prefs_setup_space_combobox (widget);
+	g_signal_connect (G_OBJECT (widget), "changed",
+			  G_CALLBACK (gcm_prefs_space_combo_changed_cb), NULL);
+
+	/* setup results expander */
+	gcm_picker_refresh_results ();
+
+	/* setup initial preview window */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "image_preview"));
+	gtk_image_set_from_file (GTK_IMAGE (widget), DATADIR "/icons/hicolor/64x64/apps/gnome-color-manager.png");
+
 	/* wait */
 	gtk_widget_show (main_window);
 	g_main_loop_run (loop);
 
 out:
 	g_object_unref (unique_app);
+	if (profile_store != NULL)
+		g_object_unref (profile_store);
 	if (colorimeter != NULL)
 		g_object_unref (colorimeter);
 	if (calibrate != NULL)



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