/* colorsel.c
 * geg, a GTK+ Equation Grapher
 * David Bryant 1998
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /* HAVE_CONFIG_H */

#include <glib.h>
#include "colorsel.h"

/* locally global data */
static GtkWidget *wi;
static GtkColorSelectionDialog *di;
static GtkColorSelection *cs;
static gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data);
static void ok_event(GtkWidget *widget, gpointer data);
static void cancel_event(GtkWidget *widget, gpointer data);

/* delete_event, deletes the colorselection dialog window, called when       */
/* dialog is closed by window manager                                        */
static gint
delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
  gtk_widget_destroy(wi);
  wi = NULL;
  return(TRUE);
}

/* cancel_event, much the same as delete_event, called by cancel button      */
static void
cancel_event(GtkWidget *widget, gpointer data)
{
  gtk_widget_destroy(wi);
  wi = NULL;
}

/* ok_event, gets the color selection dialog's selected color and puts it in */
/* the preview widget, then it closes the dialog, it is the callback function*/
/* for the OK button                                                         */
static void
ok_event(GtkWidget *widget, gpointer data)
{
  GtkWidget *preview;
  gdouble values[3];
  
  preview = (GtkWidget *)data;

  gtk_color_selection_get_color(cs, values);

  show_color_in_preview(preview, values);

  gtk_widget_destroy(wi);
  wi = NULL;
}

/* colorsel_event, brings up a color selector dialog and sets the values of  */
/* the color to the values found in get_object_data(GTK_OBJECT(preview))     */
/* where preview = GtkWidget *data;                                          */
/* called by each of the little "..." buttons to the left of the previews    */
void
colorsel_event(GtkWidget *widget, gpointer data)
{
  GtkWidget *preview;
  gdouble *values;

  if(wi && wi->window) {
    gtk_widget_map(wi);
    gdk_window_raise(wi->window);
  }

  preview = (GtkWidget *)data;
  values = gtk_object_get_data(GTK_OBJECT(preview), ValuesKey);

  wi = gtk_color_selection_dialog_new("Select color");
  gtk_signal_connect(GTK_OBJECT(wi), "delete_event", GTK_SIGNAL_FUNC(delete_event), NULL);

  /* setup window properties */
  gtk_window_set_wmclass(GTK_WINDOW(wi), "color_selection", "Geg");
  gtk_window_set_policy(GTK_WINDOW(wi), FALSE, FALSE, FALSE);
  gtk_window_position(GTK_WINDOW(wi), GTK_WIN_POS_NONE);

  di = GTK_COLOR_SELECTION_DIALOG(wi);
  cs = GTK_COLOR_SELECTION(di->colorsel);

  /* hide the help button as we wont be using it */
  gtk_widget_hide(GTK_WIDGET(di->help_button));

  gtk_signal_connect(GTK_OBJECT(di->ok_button), "clicked", GTK_SIGNAL_FUNC(ok_event), preview);
  gtk_signal_connect(GTK_OBJECT(di->cancel_button), "clicked", GTK_SIGNAL_FUNC(cancel_event), NULL);

  gtk_color_selection_set_color(cs, values);
  gtk_color_selection_set_color(cs, values);

  gtk_widget_show(wi);
  gtk_grab_add(wi);
}

/* show_color_in_preview, paints the preview with the color specified by     */
/* the values and stores the values as data in preview's object              */
/* this function called explicitly when the user clicks OK in the color      */
/* selection dialog, and when the preferences dialog is being constructed    */
void
show_color_in_preview(GtkWidget *preview, gdouble values[])
{
  gint i, j, k;
  gint width, height;
  guchar *row;

  width = preview->allocation.width;
  height = preview->allocation.height;

  row = (guchar *)g_malloc(3 * width * sizeof(guchar));

  for(i = 0; i < height; i++) {
    for(j = 0, k = 0; j < width; j++) {
      row[k] = (guchar)(values[0] * 255);
      row[k + 1] = (guchar)(values[1] * 255);
      row[k + 2] = (guchar)(values[2] * 255);
      k += 3;
    }
    gtk_preview_draw_row(GTK_PREVIEW(preview), row, 0, i, width);
  }

  gtk_widget_queue_draw(preview);

  g_free(row);

  gtk_object_set_data(GTK_OBJECT(preview), ValuesKey, memcpy(g_new(gdouble, 3), values, 3 * sizeof(gdouble)));
}


syntax highlighted by Code2HTML, v. 0.9.1