Logo Search packages:      
Sourcecode: v-sim version File versions  Download package

gtk_colorComboBoxWidget.c

/*   EXTRAITS DE LA LICENCE
      Copyright CEA, contributeurs : Luc BILLARD et Damien
      CALISTE, laboratoire L_Sim, (2001-2005)
  
      Adresse mèl :
      BILLARD, non joignable par mèl ;
      CALISTE, damien P caliste AT cea P fr.

      Ce logiciel est un programme informatique servant à visualiser des
      structures atomiques dans un rendu pseudo-3D. 

      Ce logiciel est régi par la licence CeCILL soumise au droit français et
      respectant les principes de diffusion des logiciels libres. Vous pouvez
      utiliser, modifier et/ou redistribuer ce programme sous les conditions
      de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA 
      sur le site "http://www.cecill.info".

      Le fait que vous puissiez accéder à cet en-tête signifie que vous avez 
      pris connaissance de la licence CeCILL, et que vous en avez accepté les
      termes (cf. le fichier Documentation/licence.fr.txt fourni avec ce logiciel).
*/

/*   LICENCE SUM UP
      Copyright CEA, contributors : Luc BILLARD et Damien
      CALISTE, laboratoire L_Sim, (2001-2005)

      E-mail address:
      BILLARD, not reachable any more ;
      CALISTE, damien P caliste AT cea P fr.

      This software is a computer program whose purpose is to visualize atomic
      configurations in 3D.

      This software is governed by the CeCILL  license under French law and
      abiding by the rules of distribution of free software.  You can  use, 
      modify and/ or redistribute the software under the terms of the CeCILL
      license as circulated by CEA, CNRS and INRIA at the following URL
      "http://www.cecill.info". 

      The fact that you are presently reading this means that you have had
      knowledge of the CeCILL license and that you accept its terms. You can
      find a copy of this licence shipped with this software at Documentation/licence.en.txt.
*/
#include <gtk/gtksignal.h>
#include <gtk/gtkcombobox.h>
#include <gtk/gtkcelllayout.h>
#include <gtk/gtkcellrenderertext.h>
#include <gtk/gtkcellrendererpixbuf.h>
#include <gtk/gtkcolorseldialog.h>
#include <gtk/gtkexpander.h>
#include <gtk/gtktable.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkhscale.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtkimage.h>

#include "gtk_colorComboBoxWidget.h"
#include <visu_tools.h>

enum {
  COLOR_SELECTED_SIGNAL,
  COLOR_VALUE_CHANGED_SIGNAL,
  MATERIAL_VALUE_CHANGED_SIGNAL,
  LAST_SIGNAL
};

/* This enum is used to access the column of the GtkListStore
   that contains the informations of stroed colors. */
enum
  {
    /* This has a pointer to a 16x16 image to represent the color,
       including the alpha channel. */
    COLUMN_COLOR_PIXBUF_ALPHA,
    /* This has a pointer to a 16x16 image to represent the color,
       without the alpha channel. */
    COLUMN_COLOR_PIXBUF,
    /* This is a pointer to a label that describes the color :
       "(n_red;n_green;n_blue;n_alpha)" with n_xxx from 0 to 255. */
    COLUMN_COLOR_LABEL_ALPHA,
    /* This is the same label than above but without the alpha value. */
    COLUMN_COLOR_LABEL,
    /* This a pointer to the #Color as defined in visuTools.h */
    COLUMN_COLOR_POINTER_TO,

    N_COLUMN_COLOR
  };

/* Store a tree model to remember colors. */
#define COLOR_BOX_WIDTH  16
#define COLOR_BOX_HEIGHT 16
#define COLOR_BOX_BITS   8

/* Labels for the ranges part. */
#define RED_ELE_LABEL   _("R:")
#define GREEN_ELE_LABEL _("G:")
#define BLUE_ELE_LABEL  _("B:")
#define ALPHA_ELE_LABEL _("Alph:")
#define AMB_ELE_LABEL   _("amb:")
#define DIF_ELE_LABEL   _("dif:")
#define SHI_ELE_LABEL   _("shi:")
#define SPE_ELE_LABEL   _("spe:")
#define EMI_ELE_LABEL   _("emi:")

static void colorComboBox_class_init          (ColorComboBoxClass *klass);
static void colorComboBox_init                (ColorComboBox *colorComboBox);
static void colorComboBox_changed             (GtkWidget *widget, ColorComboBox *colorComboBox);
static void colorComboBox_dispose             (GObject *obj);
static void colorComboBox_finalize            (GObject *obj);

static guint colorComboBox_signals[LAST_SIGNAL] = { 0 };
static GObjectClass *parent_class = NULL;

struct ColorComboBox_struct
{
  GtkComboBox comboColor;
  Color* previouslySelectedColor;

  gboolean withRanges;
  GtkWidget *expandRanges;
  GtkWidget *rgbRanges[4];
  GtkWidget *materialRanges[nb_material];
  gulong rgbSignals[4];
  gulong materialSignals[nb_material];
  gulong comboSignal;
  GtkWidget *addButton;

  gboolean hasAlphaChannel;

  /* Memory gestion. */
  gboolean dispose_has_run;
};

struct ColorComboBoxClass_struct
{
  GtkComboBoxClass parent_class;

  void (*colorComboBox) (ColorComboBox *colorCombo);

  /* This listStore contains all the colors
     known by widgets of this class. It is used
     as TreeModel for the combobox in the widget. */
  GtkListStore *listStoredColors;

  gulong colorAddedSignalId;
};

/* Local callbacks. */
static void colorComboBox_materialChanged(GtkRange *rg, gpointer data);
static void colorComboBox_rgbChanged(GtkRange *rg, gpointer data);
static void colorComboBox_addButtonClicked(GtkButton *button, gpointer data);

/* Local methods. */
void addColorToModel(GtkTreeIter *iter, ColorComboBoxClass* klass, Color* color);
void onNewColorAvailable(GObject *obj, Color* newColor, gpointer data);


GType colorComboBox_get_type(void)
{
  static GType colorComboBox_type = 0;

  if (!colorComboBox_type)
    {
      static const GTypeInfo colorComboBox_info =
      {
        sizeof (ColorComboBoxClass),
        NULL, /* base_init */
        NULL, /* base_finalize */
        (GClassInitFunc) colorComboBox_class_init,
        NULL, /* class_finalize */
        NULL, /* class_data */
        sizeof (ColorComboBox),
        0,
        (GInstanceInitFunc) colorComboBox_init,
        NULL
      };
      colorComboBox_type = g_type_register_static (GTK_TYPE_COMBO_BOX, "ColorComboBox",
                                       &colorComboBox_info, 0);
      DBG_fprintf(stderr, "Gtk ColorComboBox : creating the type ColorComboBox %d.\n",
              (int)colorComboBox_type);
    }

  return colorComboBox_type;
}

static void colorComboBox_class_init(ColorComboBoxClass *klass)
{
  GtkTreeIter iter;
  GList *colorLst;
  
  DBG_fprintf(stderr, "Gtk ColorComboBox : creating the class of the widget.\n");

  parent_class = g_type_class_peek_parent(klass);

  DBG_fprintf(stderr, "                     - adding new signals ;\n");
  colorComboBox_signals[COLOR_SELECTED_SIGNAL] =
    g_signal_new ("color-selected",
              G_TYPE_FROM_CLASS (klass),
              G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
              G_STRUCT_OFFSET (ColorComboBoxClass, colorComboBox),
              NULL, 
              NULL,                
              g_cclosure_marshal_VOID__POINTER,
              G_TYPE_NONE, 1, G_TYPE_POINTER);
  colorComboBox_signals[COLOR_VALUE_CHANGED_SIGNAL] =
    g_signal_new ("color-value-changed",
              G_TYPE_FROM_CLASS (klass),
              G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
              G_STRUCT_OFFSET (ColorComboBoxClass, colorComboBox),
              NULL, 
              NULL,                
              g_cclosure_marshal_VOID__UINT,
              G_TYPE_NONE, 1, G_TYPE_UINT);
  colorComboBox_signals[MATERIAL_VALUE_CHANGED_SIGNAL] =
    g_signal_new ("material-value-changed",
              G_TYPE_FROM_CLASS (klass),
              G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
              G_STRUCT_OFFSET (ColorComboBoxClass, colorComboBox),
              NULL, 
              NULL,                
              g_cclosure_marshal_VOID__UINT,
              G_TYPE_NONE, 1, G_TYPE_UINT);

  DBG_fprintf(stderr, "                     - initializing the listStore of colors.\n");
  /* Init the listStore of colors. */
  klass->listStoredColors = gtk_list_store_new (N_COLUMN_COLOR,
                                    GDK_TYPE_PIXBUF,
                                    GDK_TYPE_PIXBUF,
                                    G_TYPE_STRING,
                                    G_TYPE_STRING,
                                    G_TYPE_POINTER);
  gtk_list_store_append(klass->listStoredColors, &iter);
  gtk_list_store_set(klass->listStoredColors, &iter,
                 COLUMN_COLOR_PIXBUF_ALPHA, NULL,
                 COLUMN_COLOR_PIXBUF      , NULL,
                 COLUMN_COLOR_LABEL_ALPHA , _("New / modify"),
                 COLUMN_COLOR_LABEL       , _("New / modify"),
                 COLUMN_COLOR_POINTER_TO  , NULL,
                 -1);
  klass->colorAddedSignalId = g_signal_connect(G_OBJECT(visu), "colorNewAvailable",
                                     G_CALLBACK(onNewColorAvailable),
                                     (gpointer)klass);
  colorLst = colorGet_storedColors();
  while (colorLst)
    {
      addColorToModel(&iter, klass, (Color*)colorLst->data);
      colorLst = g_list_next(colorLst);
    }

}

static void colorComboBox_dispose(GObject *obj)
{
  DBG_fprintf(stderr, "Gtk ColorComboBox : dispose object %p.\n", (gpointer)obj);

  if (COLOR_COMBOX(obj)->dispose_has_run)
    return;

  COLOR_COMBOX(obj)->dispose_has_run = TRUE;
  /* Chain up to the parent class */
  G_OBJECT_CLASS(parent_class)->dispose(obj);
}
static void colorComboBox_finalize(GObject *obj)
{
  ColorComboBox *colorComboBox;

  g_return_if_fail(obj);

  DBG_fprintf(stderr, "Gtk ColorComboBox : finalize object %p.\n", (gpointer)obj);

  colorComboBox = COLOR_COMBOX(obj);
  if (colorComboBox->expandRanges)
    gtk_widget_destroy(colorComboBox->expandRanges);

  /* Chain up to the parent class */
  G_OBJECT_CLASS(parent_class)->finalize(obj);

  DBG_fprintf(stderr, "Gtk ColorComboBox : freeing ... OK.\n");
}


static void colorComboBox_init(ColorComboBox *colorComboBox)
{
  DBG_fprintf(stderr, "Gtk ColorComboBox : initializing new object (%p).\n",
            (gpointer)colorComboBox);

  colorComboBox->hasAlphaChannel = TRUE;
  colorComboBox->dispose_has_run = FALSE;
  colorComboBox->previouslySelectedColor = colorGet_byId(0);
}

static void buildWidgets(ColorComboBox *colorComboBox)
{
  GObjectClass *klass;
  GtkCellRenderer *renderer;
  GtkWidget *vboxExpand, *table, *label, *hbox, *image;
  char *rgb[4];
  char *rgbName[4] = {"scroll_r", "scroll_g", "scroll_b", "scroll_a"};
  char *material[5];
  int i, j;

  klass = G_OBJECT_GET_CLASS(colorComboBox);
  gtk_combo_box_set_model(GTK_COMBO_BOX(colorComboBox),
                    GTK_TREE_MODEL(COLOR_COMBOX_CLASS(klass)->listStoredColors));
  renderer = gtk_cell_renderer_pixbuf_new();
  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(colorComboBox), renderer, FALSE);
  if (colorComboBox->hasAlphaChannel)
    gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(colorComboBox), renderer,
                          "pixbuf", COLUMN_COLOR_PIXBUF_ALPHA);
  else
    gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(colorComboBox), renderer,
                          "pixbuf", COLUMN_COLOR_PIXBUF);
  renderer = gtk_cell_renderer_text_new();
  g_object_set(G_OBJECT(renderer), "scale", 0.67, NULL);
  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(colorComboBox), renderer, FALSE);
  if (colorComboBox->hasAlphaChannel)
    gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(colorComboBox), renderer,
                          "text", COLUMN_COLOR_LABEL_ALPHA);
  else
    gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(colorComboBox), renderer,
                          "text", COLUMN_COLOR_LABEL);

  gtk_combo_box_set_active(GTK_COMBO_BOX(colorComboBox), 1);

  colorComboBox->expandRanges = (GtkWidget*)0;
  if (colorComboBox->withRanges)
    {
      rgb[0] = RED_ELE_LABEL;
      rgb[1] = GREEN_ELE_LABEL;
      rgb[2] = BLUE_ELE_LABEL;
      rgb[3] = ALPHA_ELE_LABEL;
      material[0] = AMB_ELE_LABEL;
      material[1] = DIF_ELE_LABEL;
      material[2] = SHI_ELE_LABEL;
      material[3] = SPE_ELE_LABEL;
      material[4] = EMI_ELE_LABEL;

      colorComboBox->expandRanges = gtk_expander_new(_("More options"));
      gtk_expander_set_expanded(GTK_EXPANDER(colorComboBox->expandRanges), FALSE);

      vboxExpand = gtk_vbox_new(FALSE, 0);
      gtk_container_add(GTK_CONTAINER(colorComboBox->expandRanges), vboxExpand);

      hbox = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(vboxExpand), hbox, FALSE, FALSE, 5);

      table = gtk_table_new(3, 2, FALSE);
      gtk_box_pack_start(GTK_BOX(hbox), table, TRUE, TRUE, 0);
      gtk_widget_show(table);
      for (i = 0; i < 3; i++)
      {
        label = gtk_label_new(rgb[i]);
        gtk_table_attach(GTK_TABLE(table), label, 0, 1, i, i + 1,
                     GTK_SHRINK, GTK_SHRINK, 5, 0);
        colorComboBox->rgbRanges[i] = gtk_hscale_new_with_range(0., 1., 0.001);
        gtk_scale_set_value_pos(GTK_SCALE(colorComboBox->rgbRanges[i]),
                          GTK_POS_RIGHT);
        gtk_widget_set_name(colorComboBox->rgbRanges[i], rgbName[i]);
        gtk_table_attach(GTK_TABLE(table), colorComboBox->rgbRanges[i],
                     1, 2, i, i + 1,
                     GTK_EXPAND | GTK_FILL, GTK_SHRINK, 5, 0);
      }
      colorComboBox->addButton = gtk_button_new();
      gtk_box_pack_start(GTK_BOX(hbox), colorComboBox->addButton, FALSE, FALSE, 2);
      image = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_BUTTON);
      gtk_container_add(GTK_CONTAINER(colorComboBox->addButton), image);

      table = gtk_table_new(3, 4, FALSE);
      gtk_box_pack_start(GTK_BOX(vboxExpand), table, FALSE, FALSE, 5);
      for (i = 0; i < 2; i++)
      {
        for (j = 0; j < 2; j++)
          {
            label = gtk_label_new(material[i * 2 + j]);
            gtk_misc_set_alignment(GTK_MISC(label), 1., 0.5);
            gtk_table_attach(GTK_TABLE(table), label, j * 2, j * 2 + 1, i, i + 1,
                         GTK_SHRINK, GTK_SHRINK, 1, 0);
            colorComboBox->materialRanges[i * 2 + j] =
            gtk_hscale_new_with_range(0., 1., 0.01);
            gtk_scale_set_value_pos(GTK_SCALE(colorComboBox->materialRanges[i * 2 + j]),
                              GTK_POS_RIGHT);
            gtk_widget_set_name(colorComboBox->materialRanges[i * 2 +j], "scroll_mat");
            gtk_table_attach(GTK_TABLE(table), colorComboBox->materialRanges[i * 2 + j],
                         2 * j + 1, 2 * j + 2, i, i + 1,
                         GTK_EXPAND | GTK_FILL, GTK_SHRINK, 1, 0);
          }
      }
      label = gtk_label_new(material[4]);
      gtk_misc_set_alignment(GTK_MISC(label), 1., 0.5);
      gtk_table_attach(GTK_TABLE(table), label, 0, 1, i, i + 1,
                   GTK_SHRINK, GTK_SHRINK, 1, 0);
      colorComboBox->materialRanges[4] =
      gtk_hscale_new_with_range(0., 1., 0.01);
      gtk_scale_set_value_pos(GTK_SCALE(colorComboBox->materialRanges[4]),
                        GTK_POS_RIGHT);
      gtk_widget_set_name(colorComboBox->materialRanges[4], "scroll_mat");
      gtk_table_attach(GTK_TABLE(table), colorComboBox->materialRanges[4],
                   1, 2, i, i + 1,
                   GTK_EXPAND | GTK_FILL, GTK_SHRINK, 1, 0);
      label = gtk_label_new(rgb[3]);
      gtk_misc_set_alignment(GTK_MISC(label), 1., 0.5);
      gtk_table_attach(GTK_TABLE(table), label, 2, 3, i, i + 1,
                   GTK_SHRINK, GTK_SHRINK, 5, 0);
      colorComboBox->rgbRanges[3] = gtk_hscale_new_with_range(0., 1., 0.01);
      gtk_scale_set_value_pos(GTK_SCALE(colorComboBox->rgbRanges[3]),
                        GTK_POS_RIGHT);
      gtk_widget_set_name(colorComboBox->rgbRanges[3], rgbName[3]);
      gtk_table_attach(GTK_TABLE(table), colorComboBox->rgbRanges[3],
                   3, 4, i, i + 1,
                   GTK_EXPAND | GTK_FILL, GTK_SHRINK, 1, 0);
      /* Attach the callbacks. */
      for (i = 0; i < 4; i++)
      colorComboBox->rgbSignals[i] = 
        g_signal_connect(G_OBJECT(colorComboBox->rgbRanges[i]), "value-changed",
                     G_CALLBACK(colorComboBox_rgbChanged), (gpointer)colorComboBox);
      for (i = 0; i < nb_material; i++)
      colorComboBox->materialSignals[i] =
        g_signal_connect(G_OBJECT(colorComboBox->materialRanges[i]), "value-changed",
                     G_CALLBACK(colorComboBox_materialChanged), (gpointer)colorComboBox);
      g_signal_connect(G_OBJECT(colorComboBox->addButton), "clicked",
                   G_CALLBACK(colorComboBox_addButtonClicked), (gpointer)colorComboBox);
    }
  colorComboBox->comboSignal = g_signal_connect(G_OBJECT(colorComboBox), "changed",
                                    G_CALLBACK(colorComboBox_changed),
                                    (gpointer)colorComboBox);
}

GtkWidget* colorComboBox_newWithRanges(gboolean hasAlphaChannel)
{
  ColorComboBox *colorComboBox;

  DBG_fprintf(stderr, "Gtk ColorComboBox : creating new object with alpha & ranges : %d.\n",
            hasAlphaChannel);

  colorComboBox = COLOR_COMBOX(g_object_new(colorComboBox_get_type (), NULL));
  colorComboBox->hasAlphaChannel = hasAlphaChannel;
  colorComboBox->withRanges = TRUE;

  buildWidgets(colorComboBox);

  return GTK_WIDGET(colorComboBox);
}

GtkWidget* colorComboBox_new(gboolean hasAlphaChannel)
{
  ColorComboBox *colorComboBox;

  DBG_fprintf(stderr, "Gtk ColorComboBox : creating new object with alpha : %d.\n",
            hasAlphaChannel);

  colorComboBox = COLOR_COMBOX(g_object_new(colorComboBox_get_type (), NULL));
  colorComboBox->hasAlphaChannel = hasAlphaChannel;
  colorComboBox->withRanges = FALSE;

  buildWidgets(colorComboBox);

  return GTK_WIDGET(colorComboBox);
}

void colorComboBoxSet_expanded(ColorComboBox *colorComboBox, gboolean value)
{
  g_return_if_fail(IS_COLOR_COMBOX(colorComboBox));
  g_return_if_fail(colorComboBox->withRanges);

  gtk_expander_set_expanded(GTK_EXPANDER(colorComboBox->expandRanges), value);
}
GtkWidget* colorComboBoxGet_rangesWidgets(ColorComboBox *colorComboBox)
{
  g_return_val_if_fail(IS_COLOR_COMBOX(colorComboBox), (GtkWidget*)0);

  return colorComboBox->expandRanges;
}

static void colorComboBox_changed(GtkWidget *widget, ColorComboBox *colorComboBox)
{
  int selected, i;
  GdkColor gdkcolor;
  guint alpha;
  GtkWidget *selection;
  gint code;
  float rgba[4];
  GtkTreeIter iter;
  GObjectClass *klass;
  Color *color;

  selected = gtk_combo_box_get_active(GTK_COMBO_BOX(colorComboBox));
  DBG_fprintf(stderr, "Gtk ColorComboBox : internal combobox changed signal -> %d.\n", selected);
  if (selected < 0)
    {
      if (colorComboBox->withRanges)
      gtk_widget_set_sensitive(colorComboBox->addButton, TRUE);
      colorComboBox->previouslySelectedColor = (Color*)0;
      return;
    }

  if (colorComboBox->withRanges)
    gtk_widget_set_sensitive(colorComboBox->addButton, FALSE);

  if (selected != 0)
    {
      gtk_combo_box_get_active_iter(GTK_COMBO_BOX(colorComboBox), &iter);
      klass = G_OBJECT_GET_CLASS(colorComboBox);
      gtk_tree_model_get(GTK_TREE_MODEL(COLOR_COMBOX_CLASS(klass)->listStoredColors), &iter,
                     COLUMN_COLOR_POINTER_TO, &color,
                     -1);
      if (color != colorComboBox->previouslySelectedColor)
      {
        colorComboBox->previouslySelectedColor = color;
        /* Set the ranges. */
        if (colorComboBox->withRanges)
          for (i = 0; i <4; i++)
            {
            g_signal_handler_block(G_OBJECT(colorComboBox->rgbRanges[i]),
                               colorComboBox->rgbSignals[i]);
            gtk_range_set_value(GTK_RANGE(colorComboBox->rgbRanges[i]),
                            (gdouble)color->rgba[i]);
            g_signal_handler_unblock(G_OBJECT(colorComboBox->rgbRanges[i]),
                               colorComboBox->rgbSignals[i]);
            }
        DBG_fprintf(stderr, "Gtk ColorComboBox : emitting 'color-selected' signal.\n");
        g_signal_emit(G_OBJECT(colorComboBox),
                  colorComboBox_signals[COLOR_SELECTED_SIGNAL], 0, (gpointer)color, NULL);
      }
      else
      DBG_fprintf(stderr, "Gtk ColorComboBox : aborting 'color-selected' signal.\n");
      return;
    }
  if (colorComboBox->previouslySelectedColor)
    {
      gdkcolor.red = 
      (guint16)((colorComboBox->previouslySelectedColor->rgba[0]) * 65535.);
      gdkcolor.green =
      (guint16)((colorComboBox->previouslySelectedColor->rgba[1]) * 65535.);
      gdkcolor.blue =
      (guint16)((colorComboBox->previouslySelectedColor->rgba[2]) * 65535.);
      alpha = (guint16)((colorComboBox->previouslySelectedColor->rgba[3]) * 65535.);
    }
  else
    {
      gdkcolor.red = (guint16)0.;
      gdkcolor.green = (guint16)0.;
      gdkcolor.blue = (guint16)0.;
      alpha = 65535.;
    }

  /* Create the selection. */
  selection = gtk_color_selection_dialog_new(_("Select a color"));
  gtk_color_selection_set_has_opacity_control(GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(selection)->colorsel), colorComboBox->hasAlphaChannel);
/*   createColorSelectionCustomList(GTK_COLOR_SELECTION_DIALOG(selection)); */

  /* Initialise its values. */
  if (colorComboBox->hasAlphaChannel)
    gtk_color_selection_set_current_alpha(GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(selection)->colorsel), alpha);
  gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(selection)->colorsel), &gdkcolor);

  /* Run the dialog window. */
  code = gtk_dialog_run(GTK_DIALOG(selection));
  if (code == GTK_RESPONSE_OK || code == GTK_RESPONSE_ACCEPT)
    {
      gtk_color_selection_get_current_color(GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(selection)->colorsel), &gdkcolor);
      rgba[0] = (float)gdkcolor.red / 65535.;
      rgba[1] = (float)gdkcolor.green / 65535.;
      rgba[2] = (float)gdkcolor.blue / 65535.;
      rgba[3] = (float)gtk_color_selection_get_current_alpha(GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(selection)->colorsel)) / 65535.;

      klass = G_OBJECT_GET_CLASS(colorComboBox);
      g_signal_handler_block(G_OBJECT(visu), COLOR_COMBOX_CLASS(klass)->colorAddedSignalId);
      color = colorAdd_floatRGBA(rgba, &selected);
      g_signal_handler_unblock(G_OBJECT(visu), COLOR_COMBOX_CLASS(klass)->colorAddedSignalId);
      addColorToModel(&iter, COLOR_COMBOX_CLASS(klass), color);
      gtk_combo_box_set_active_iter(GTK_COMBO_BOX(colorComboBox), &iter);
    }
  else
    {
      /* Return the combobox to the previously selected color. */
      colorComboBoxSet_selectionByColor(colorComboBox, colorComboBox->previouslySelectedColor);
    }
  gtk_widget_destroy(selection);
}

static void colorComboBox_materialChanged(GtkRange *rg, gpointer data)
{
  int i;
  ColorComboBox *colorComboBox;

  g_return_if_fail(IS_COLOR_COMBOX(data));

  colorComboBox = COLOR_COMBOX(data);
  DBG_fprintf(stderr, "Gtk ColorComboBox : internal material range changed signal.\n");

  DBG_fprintf(stderr, "Gtk ColorComboBox : emitting 'material-value-changed' signal.\n");
  for (i = 0; i < nb_material; i++)
    if (GTK_WIDGET(rg) == colorComboBox->materialRanges[i])
      {
      g_signal_emit(G_OBJECT(colorComboBox),
                  colorComboBox_signals[MATERIAL_VALUE_CHANGED_SIGNAL], 0,
                  (Material)i, NULL);
      return;
      }
  g_warning("Internal error, unrecognized range.");
}
static void colorComboBox_rgbChanged(GtkRange *rg, gpointer data)
{
  int i;
  ColorComboBox *colorComboBox;
  float *rgba;

  g_return_if_fail(IS_COLOR_COMBOX(data));

  colorComboBox = COLOR_COMBOX(data);
  DBG_fprintf(stderr, "Gtk ColorComboBox : internal color range changed signal.\n");
  rgba = colorComboBoxGet_color(colorComboBox);
  colorGet_byValues(&i, rgba[0], rgba[1], rgba[2], rgba[3]);
  if (i < 0)
    gtk_combo_box_set_active(GTK_COMBO_BOX(colorComboBox), -1);
  else
    gtk_combo_box_set_active(GTK_COMBO_BOX(colorComboBox), i + 1);
  g_free(rgba);

  DBG_fprintf(stderr, "Gtk ColorComboBox : emitting 'color-value-changed' signal.\n");
  for (i = 0; i < 4; i++)
    if (GTK_WIDGET(rg) == colorComboBox->rgbRanges[i])
      {
      g_signal_emit(G_OBJECT(colorComboBox),
                  colorComboBox_signals[COLOR_VALUE_CHANGED_SIGNAL], 0,
                  (Material)i, NULL);
      return;
      }
  g_warning("Internal error, unrecognized range.");
}
static void colorComboBox_addButtonClicked(GtkButton *button, gpointer data)
{
  GtkTreeIter iter;
  GObjectClass *klass;
  Color *color;
  ColorComboBox *colorComboBox;
  float *rgba;
  int selected;

  g_return_if_fail(IS_COLOR_COMBOX(data));
  colorComboBox = COLOR_COMBOX(data);

  DBG_fprintf(stderr, "Gtk ColorComboBox : adding a new color from ranges.\n");

  rgba = colorComboBoxGet_color(colorComboBox);
  klass = G_OBJECT_GET_CLASS(colorComboBox);
  g_signal_handler_block(G_OBJECT(visu), COLOR_COMBOX_CLASS(klass)->colorAddedSignalId);
  color = colorAdd_floatRGBA(rgba, &selected);
  g_signal_handler_unblock(G_OBJECT(visu), COLOR_COMBOX_CLASS(klass)->colorAddedSignalId);
  addColorToModel(&iter, COLOR_COMBOX_CLASS(klass), color);
  gtk_combo_box_set_active_iter(GTK_COMBO_BOX(colorComboBox), &iter);
  g_free(rgba);
}

GdkPixbuf* colorComboBoxBuild_colorStamp(Color *color, gboolean alpha)
{
  GdkPixbuf *pixbufColorBox;
  int rowstride, x, y;
  guchar *pixels, *p;
  float grey;

  pixbufColorBox = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE,
                          COLOR_BOX_BITS,
                          COLOR_BOX_WIDTH,
                          COLOR_BOX_HEIGHT);
  rowstride = gdk_pixbuf_get_rowstride(pixbufColorBox);
  pixels = gdk_pixbuf_get_pixels(pixbufColorBox);
  for (y = 0; y < COLOR_BOX_HEIGHT; y++)
    for (x = 0; x < COLOR_BOX_WIDTH; x++)
      {
      p = pixels + y * rowstride + x * 3;
      if (x < COLOR_BOX_WIDTH / 2)
        {
          if (y < COLOR_BOX_HEIGHT / 2)
            grey = 0.75;
          else
            grey = 0.5;
        }
      else
        {
          if (y < COLOR_BOX_HEIGHT / 2)
            grey = 0.5;
          else
            grey = 0.75;
        }
      if (alpha)
        {
          p[0] = (guchar)((color->rgba[0] * color->rgba[3] +
                       (1. - color->rgba[3]) * grey) * 255.);
          p[1] = (guchar)((color->rgba[1] * color->rgba[3] +
                       (1. - color->rgba[3]) * grey) * 255.);
          p[2] = (guchar)((color->rgba[2] * color->rgba[3] +
                       (1. - color->rgba[3]) * grey) * 255.);
        }
      else
        {
          p[0] = (guchar)(color->rgba[0] * 255.);
          p[1] = (guchar)(color->rgba[1] * 255.);
          p[2] = (guchar)(color->rgba[2] * 255.);
        }
      }
  return pixbufColorBox;
}

void addColorToModel(GtkTreeIter *iter, ColorComboBoxClass* klass, Color* color)
{
  char str[20], strAlpha[20];
  GdkPixbuf *pixbufColorBox;
  GdkPixbuf *pixbufColorAlphaBox;

  if (!color || !klass)
    return;
  sprintf(strAlpha, "(%3d;%3d;%3d;%3d)", (int)(color->rgba[0] * 255.),
        (int)(color->rgba[1] * 255.),
        (int)(color->rgba[2] * 255.),
        (int)(color->rgba[3] * 255.));
  sprintf(str, "(%3d;%3d;%3d)", (int)(color->rgba[0] * 255.),
        (int)(color->rgba[1] * 255.),
        (int)(color->rgba[2] * 255.));
  pixbufColorAlphaBox = colorComboBoxBuild_colorStamp(color, TRUE);
  pixbufColorBox = colorComboBoxBuild_colorStamp(color, FALSE);
  gtk_list_store_append(klass->listStoredColors, iter);
  gtk_list_store_set(klass->listStoredColors, iter,
                 COLUMN_COLOR_PIXBUF_ALPHA, pixbufColorAlphaBox,
                 COLUMN_COLOR_PIXBUF      , pixbufColorBox,
                 COLUMN_COLOR_LABEL_ALPHA , strAlpha,
                 COLUMN_COLOR_LABEL       , str,
                 COLUMN_COLOR_POINTER_TO  , (gpointer)color,
                 -1);
  DBG_fprintf(stderr, "Gtk ColorComboBox : appending a new color '%s' at position '%s'.\n",
            strAlpha, gtk_tree_model_get_string_from_iter(GTK_TREE_MODEL(COLOR_COMBOX_CLASS(klass)->listStoredColors), iter));
}

gboolean colorComboBoxSet_selectionByColor(ColorComboBox* colorComboBox, Color *color)
{
  GtkTreeIter iter;
  gboolean validIter;
  GObjectClass *klass;
  GtkListStore *model;
  Color *tmpColor;

  g_return_val_if_fail(color && IS_COLOR_COMBOX(colorComboBox), FALSE);

  DBG_fprintf(stderr, "Gtk ColorComboBox : select a new color %p.\n", (gpointer)color);
  klass = G_OBJECT_GET_CLASS(colorComboBox);
  model = GTK_LIST_STORE(COLOR_COMBOX_CLASS(klass)->listStoredColors);
  validIter = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
  while (validIter)
    {
      gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
                   COLUMN_COLOR_POINTER_TO, &tmpColor,
                   -1);
      if (tmpColor == color)
      {
        gtk_combo_box_set_active_iter(GTK_COMBO_BOX(colorComboBox), &iter);
        return TRUE;
      }
      validIter = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
    }
  return FALSE;
}
void colorComboBoxSet_color(ColorComboBox *colorComboBox, float rgba[4],
                      gboolean raiseSignal)
{
  int pos, i;

  colorGet_byValues(&pos, rgba[0], rgba[1], rgba[2], rgba[3]);
  if (pos < 0)
    {
      gtk_combo_box_set_active(GTK_COMBO_BOX(colorComboBox), -1);
      if (raiseSignal)
      for (i = 0; i < 4; i++)
        gtk_range_set_value(GTK_RANGE(colorComboBox->rgbRanges[i]),
                        (gdouble)rgba[i]);
      else
      for (i = 0; i < 4; i++)
        {
          g_signal_handler_block(G_OBJECT(colorComboBox->rgbRanges[i]),
                           colorComboBox->rgbSignals[i]);
          gtk_range_set_value(GTK_RANGE(colorComboBox->rgbRanges[i]),
                        (gdouble)rgba[i]);
          g_signal_handler_unblock(G_OBJECT(colorComboBox->rgbRanges[i]),
                             colorComboBox->rgbSignals[i]);
        }
    }
  else
    {
      if (raiseSignal)
      gtk_combo_box_set_active(GTK_COMBO_BOX(colorComboBox), pos + 1);
      else
      {
        g_signal_handler_block(G_OBJECT(colorComboBox),
                         colorComboBox->comboSignal);
        gtk_combo_box_set_active(GTK_COMBO_BOX(colorComboBox), pos + 1);
        g_signal_handler_unblock(G_OBJECT(colorComboBox),
                           colorComboBox->comboSignal);
        for (i = 0; i < 4; i++)
          {
            g_signal_handler_block(G_OBJECT(colorComboBox->rgbRanges[i]),
                             colorComboBox->rgbSignals[i]);
            gtk_range_set_value(GTK_RANGE(colorComboBox->rgbRanges[i]),
                          (gdouble)rgba[i]);
            g_signal_handler_unblock(G_OBJECT(colorComboBox->rgbRanges[i]),
                               colorComboBox->rgbSignals[i]);
          }
      }
    }
}


void onNewColorAvailable(GObject *obj, Color* newColor, gpointer data)
{
  ColorComboBoxClass *klass;
  GtkTreeIter iter;

  if (!data)
    {
      fprintf(stderr, "INTERNAL ERROR! 'onNewColorAvailable' has been"
            " called without 'data' argument.\n");
    }

  DBG_fprintf(stderr, "Gtk ColorComboBoxClass : catch the 'colorNewAvailable' signal.\n");
  klass = COLOR_COMBOX_CLASS(data);
  addColorToModel(&iter, klass, newColor);
}

GdkPixbuf* colorComboBoxGet_selectedPixbuf(ColorComboBox *colorComboBox)
{
  gboolean validIter;
  GtkTreeIter iter;
  GdkPixbuf *pixbuf;
  GObjectClass *klass;

  if (!colorComboBox)
    {
      fprintf(stderr, "WARNING! 'colorComboBoxGet_selectedPixbuf' has been"
            " called with a null 'colorComboBox' argument.\n");
      return (GdkPixbuf*)0;
    }
  validIter = gtk_combo_box_get_active_iter(GTK_COMBO_BOX(colorComboBox), &iter);
  if (!validIter)
    return (GdkPixbuf*)0;

  pixbuf = (GdkPixbuf*)0;
  klass = G_OBJECT_GET_CLASS(colorComboBox);
  if (colorComboBox->hasAlphaChannel)
    gtk_tree_model_get(GTK_TREE_MODEL(COLOR_COMBOX_CLASS(klass)->listStoredColors), &iter,
                   COLUMN_COLOR_PIXBUF_ALPHA, &pixbuf,
                   -1);
  else
    gtk_tree_model_get(GTK_TREE_MODEL(COLOR_COMBOX_CLASS(klass)->listStoredColors), &iter,
                   COLUMN_COLOR_PIXBUF, &pixbuf,
                   -1);
  return pixbuf;
}
Color* colorComboBoxGet_selectedColor(ColorComboBox *colorComboBox)
{
  gboolean validIter;
  GtkTreeIter iter;
  Color *color;
  GObjectClass *klass;

  if (!colorComboBox)
    {
      fprintf(stderr, "WARNING! 'colorComboBoxGet_selectedColor' has been"
            " called with a null 'colorComboBox' argument.\n");
      return (Color*)0;
    }
  validIter = gtk_combo_box_get_active_iter(GTK_COMBO_BOX(colorComboBox), &iter);
  if (!validIter)
    return (Color*)0;

  color = (Color*)0;
  klass = G_OBJECT_GET_CLASS(colorComboBox);
  gtk_tree_model_get(GTK_TREE_MODEL(COLOR_COMBOX_CLASS(klass)->listStoredColors), &iter,
                 COLUMN_COLOR_POINTER_TO, &color,
                 -1);
  return color;
}

GdkPixbuf* colorComboBoxGet_pixbufFromColor(ColorComboBox *colorComboBox, Color *color)
{
  GtkTreeIter iter;
  gboolean validIter;
  GdkPixbuf *pixbuf;
  Color *cl;
  GtkListStore *model;

  if (!colorComboBox)
    {
      fprintf(stderr, "WARNING! 'colorComboBoxGet_pixbufFromColor' has"
            " been called with a null 'colorComboBox' argument.\n");
      return (GdkPixbuf*)0;
    }
  if (!color)
    return (GdkPixbuf*)0;

  model = COLOR_COMBOX_CLASS(G_OBJECT_GET_CLASS(colorComboBox))->listStoredColors;
  validIter = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
  while (validIter)
    {
      pixbuf = (GdkPixbuf*)0;
      cl = (Color*)0;
      if (colorComboBox->hasAlphaChannel)
      gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
                     COLUMN_COLOR_PIXBUF_ALPHA, &pixbuf,
                     COLUMN_COLOR_POINTER_TO, &cl,
                     -1);
      else
      gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
                     COLUMN_COLOR_PIXBUF, &pixbuf,
                     COLUMN_COLOR_POINTER_TO, &cl,
                     -1);
      if (color == cl)
      return pixbuf;
      validIter = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
    }
  return (GdkPixbuf*)0;
}

void colorComboBoxSet_material(ColorComboBox *colorComboBox, float material[5],
                         gboolean raiseSignal)
{
  int i;

  g_return_if_fail(IS_COLOR_COMBOX(colorComboBox));
  g_return_if_fail(colorComboBox->withRanges);

  if (raiseSignal)
    for (i = 0; i < nb_material; i++)
      gtk_range_set_value(GTK_RANGE(colorComboBox->materialRanges[i]),
                    (gdouble)material[i]);
  else
    for (i = 0; i < nb_material; i++)
      {
      g_signal_handler_block(G_OBJECT(colorComboBox->materialRanges[i]),
                         colorComboBox->materialSignals[i]);
      gtk_range_set_value(GTK_RANGE(colorComboBox->materialRanges[i]),
                      (gdouble)material[i]);
      g_signal_handler_unblock(G_OBJECT(colorComboBox->materialRanges[i]),
                         colorComboBox->materialSignals[i]);
      }
}

float* colorComboBoxGet_material(ColorComboBox *colorComboBox)
{
  int i;
  float *values;

  g_return_val_if_fail(IS_COLOR_COMBOX(colorComboBox), (float*)0);
  g_return_val_if_fail(colorComboBox->withRanges, (float*)0);

  values = g_malloc(sizeof(float) * nb_material);
  for (i = 0; i < nb_material; i++)
    values[i] = (float)gtk_range_get_value(GTK_RANGE(colorComboBox->materialRanges[i]));

  return values;
}
float* colorComboBoxGet_color(ColorComboBox *colorComboBox)
{
  int i;
  float *values;

  g_return_val_if_fail(IS_COLOR_COMBOX(colorComboBox), (float*)0);
  g_return_val_if_fail(colorComboBox->withRanges, (float*)0);

  values = g_malloc(sizeof(float) * 4);
  for (i = 0; i < 4; i++)
    values[i] = (float)gtk_range_get_value(GTK_RANGE(colorComboBox->rgbRanges[i]));

  return values;
}


/* Under developpement method, not used at the present time. */
/* void createColorSelectionCustomList(GtkColorSelectionDialog *selection) */
/* { */
/*   GtkWidget *hbox; */
/*   GtkWidget *buttonF, *buttonB, *button; */
/*   GtkWidget *image; */
/*   GtkWidget *table; */
/*   GtkWidget *label; */
/*   GtkWidget *align; */
/*   gboolean validIter; */
/*   GdkPixbuf *pixbuf; */
/*   int i; */
/*   gboolean usedPrevNext; */
/*   #define N_SHOW_COLOR 15 */
/*   GtkTreeIter iter; */
/*   GtkWidget *imageGroup; */
/*   GtkTreeIter *iterStored; */
  
/*   hbox = gtk_hbox_new(FALSE, 0); */
/*   gtk_widget_show(hbox); */
/*   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(selection)->vbox), hbox, FALSE, FALSE, 2); */

/*   label = gtk_label_new(_("Stored colors:")); */
/*   gtk_misc_set_alignment(GTK_MISC(label), 0., 0.5); */
/*   gtk_widget_show(label); */
/*   gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 2); */
  
/*   button = gtk_button_new_from_stock(GTK_STOCK_REMOVE); */
/*   gtk_widget_show(button); */
/*   gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 2); */

/*   usedPrevNext = (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(listStoredColors), NULL) >= N_SHOW_COLOR); */

/*   hbox = gtk_hbox_new(FALSE, 0); */
/*   gtk_widget_show(hbox); */
/*   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(selection)->vbox), hbox, FALSE, FALSE, 2); */

/*   if (usedPrevNext) */
/*     { */
/*       buttonB = gtk_button_new (); */
/*       gtk_widget_show(buttonB); */
/*       gtk_box_pack_start(GTK_BOX(hbox), buttonB, FALSE, FALSE, 2); */
/*       image = gtk_image_new_from_stock(GTK_STOCK_GO_BACK, GTK_ICON_SIZE_BUTTON); */
/*       gtk_widget_show (image); */
/*       gtk_container_add(GTK_CONTAINER(buttonB), image); */
/*     } */

/*   align= gtk_alignment_new(0.5, 0.5, 0., 0.); */
/*   gtk_widget_show(align); */
/*   gtk_box_pack_start(GTK_BOX(hbox), align, FALSE, FALSE, 2); */
/*   table = gtk_table_new(1, 10, FALSE); */
/*   gtk_widget_show(table); */
/*   gtk_container_add(GTK_CONTAINER(align), table); */

/*   if (usedPrevNext) */
/*     { */
/*       buttonF = gtk_button_new (); */
/*       gtk_widget_show(buttonF); */
/*       gtk_box_pack_start(GTK_BOX(hbox), buttonF, FALSE, FALSE, 2); */
/*       image = gtk_image_new_from_stock(GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_BUTTON); */
/*       gtk_widget_show (image); */
/*       gtk_container_add(GTK_CONTAINER(buttonF), image); */
/*     } */

  /* Put all the colors. */
/*   imageGroup = (GtkWidget*)0; */
/*   i = 0; */
/*   validIter = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(listStoredColors), &iter); */
/*   while (validIter && i < N_SHOW_COLOR) */
/*     { */
/*       pixbuf = (GdkPixbuf*)0; */
/*       gtk_tree_model_get(GTK_TREE_MODEL(listStoredColors), */
/*                 &iter, COLUMN_COLOR_PIXBUF_ALPHA, */
/*                 &pixbuf, -1); */
/*       if (pixbuf) */
/*    { */
/*      if (!imageGroup) */
/*        { */
/*          imageGroup = gtk_radio_button_new(NULL); */
/*          button = imageGroup; */
/*        } */
/*      else */
/*        button = gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(imageGroup)); */
/*      gtk_widget_show(button); */
/*      gtk_table_attach(GTK_TABLE(table), button, i, i + 1, 0, 1, GTK_FILL, GTK_FILL, 2, 2); */
/*      image = gtk_image_new_from_pixbuf(pixbuf); */
/*      gtk_widget_show(image); */
/*      gtk_container_add(GTK_CONTAINER(button), image); */

/*      iterStored = gtk_tree_iter_copy(&iter); */
/*      i += 1; */
/*    } */
/*       validIter = gtk_tree_model_iter_next(GTK_TREE_MODEL(listStoredColors), &iter); */
/*     } */
/* } */

Generated by  Doxygen 1.6.0   Back to index