problem with colors



I need to display a bunch of colored rectangles, each of which could
have a different color. however, I'm unable to get more than 5 or 6
colors out of 256 tries. below is my test program (copied from
scribble-simple); can anyone see what I'm doing wrong? the palette
seems to be loading correctly, and in other tests produces a reasonable
spectrum.

is there a better way? I'm drawing cardiac activation maps, and I'll
eventually need 528 rectangles, with the ability to update the picture
when the user changes the input file.


/* example-start actMap actMap.c */

#include <stdio.h>
#include "gtk/gtk.h"

char *palette[256];

static GdkPixmap *pixmap = NULL;        /* Backing pixmap for drawing area */


/* Create a new backing pixmap of the appropriate size */
static gint
configure_event(GtkWidget *widget, GdkEventConfigure *event )
{
GtkRcStyle *rc_style;
GdkColor color;

        if (pixmap) gdk_pixmap_unref(pixmap);

        pixmap = gdk_pixmap_new(widget->window, widget->allocation.width,
                widget->allocation.height, -1);

        gdk_draw_rectangle (pixmap, widget->style->bg_gc[GTK_STATE_NORMAL],
                TRUE, 0, 0, widget->allocation.width, widget->allocation.height);

        return TRUE;
}

gint
delete_event( GtkWidget *widget, GdkEvent *event, gpointer data )
{
        gtk_main_quit();
        return(FALSE);
}

/* Draw a rectangle on the screen */

static void
drawRect(GtkWidget *widget, gpointer data)
{
GdkRectangle update_rect;
GtkRcStyle *rc_style;
GdkColor color;
gint i, j, num, temp;
char label[10];

        update_rect.width = 10;
        update_rect.height = 10;

        for (i = 0; i < 16; i++) {
                for (j = 0; j < 16; j++) {

                        update_rect.x = j * 20;
                        update_rect.y = i * 20;

                        gdk_color_parse (palette[(i * 16 + j)], &color);

/* After filling in your GdkColor, create a GtkRcStyle */

                        rc_style = gtk_rc_style_new ();

/* Set foreground (fg) color in normal state to color */
                        rc_style->fg[GTK_STATE_NORMAL] = color;

/* Indicate which colors the GtkRcStyle will affect; 
 * unflagged colors will follow the theme
 */
                        rc_style->color_flags[GTK_STATE_NORMAL] |= GTK_RC_FG;

                        gtk_widget_modify_style (widget, rc_style);

                        gdk_draw_rectangle (pixmap, widget->style->fg_gc[GTK_STATE_NORMAL],
                                TRUE, update_rect.x, update_rect.y, update_rect.width,
                                update_rect.height);

                        gtk_rc_style_unref (rc_style);
                        }
                }
}

/* Redraw the screen from the backing pixmap */
static gint
expose_event(GtkWidget *widget, GdkEventExpose *event )
{
        gdk_draw_pixmap(widget->window,
                widget->style->fg_gc[GTK_WIDGET_STATE (widget)], pixmap,
                event->area.x, event->area.y, event->area.x, event->area.y,
                event->area.width, event->area.height);

        return FALSE;
}


void
loadPalette()
{
gint i;
guint16 red, green, blue;

        for (i = 0; i < 256; i++) palette[i] = (char *)malloc(8 * sizeof(char));

        for (i = 0; i < 256; i++) {
                if (i < 48) {
                        red = 255 * (48 - i) / 48;
                        green = 0;
                        blue = 255;
                        }
                else if (i < 86) {
                        red = 0;
                        green = 255 * (i - 48) / 38;
                        blue = 255;
                        }
                else if (i < 116) {
                        red = 0;
                        green = 255;
                        blue = 255 * (116 - i) / 30;
                        }
                else if (i < 162) {
                        red = 255 * (i - 116) / 46;
                        green = 255;
                        blue = 0;
                        }
                else if (i < 208) {
                        red = 255;
                        green = 255 * (208 - i) / 46;
                        blue = 0;
                        }
                else {
                        red = 255;
                        green = 0;
                        blue = 0;
                        }
                sprintf(palette[i], "#%.2x%.2x%.2x", red, green, blue);
                }

/*
        for (i = 0; i < 256; i++)
                fprintf(stderr, "palette[%d] %s\n", i, palette[i]);
*/
}


int
main(int argc, char *argv[]) 
{
void loadPalette();
GtkWidget *window;
GtkWidget *drawing_area;
GtkWidget *quitB, *updateB;
GtkWidget *vbox;
gint i;
        

        /* Our init, don't forget this! :) */
        gtk_init (&argc, &argv);

        loadPalette();

/* Create our window */

        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

/* You should always remember to connect the delete_event signal
 * to the main window. This is very important for proper intuitive
 * behavior
 */
        gtk_signal_connect (GTK_OBJECT (window), "delete_event",
                        GTK_SIGNAL_FUNC (delete_event), NULL);
        
        vbox = gtk_vbox_new (FALSE, 0);
        gtk_container_add (GTK_CONTAINER (window), vbox);
        gtk_widget_show (vbox);

        drawing_area = gtk_drawing_area_new ();
        gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 350, 350);
        gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);

        gtk_widget_show (drawing_area);

/* Signals used to handle backing pixmap */

        gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
                (GtkSignalFunc) expose_event, NULL);
        gtk_signal_connect (GTK_OBJECT(drawing_area),"configure_event",
                (GtkSignalFunc) configure_event, NULL);

/* update button. */
        updateB = gtk_button_new_with_label ("Update");

/* Setup the signal to update the display when the button is clicked */
        gtk_signal_connect(GTK_OBJECT (updateB), "clicked",
                GTK_SIGNAL_FUNC (drawRect), NULL);

        gtk_box_pack_start (GTK_BOX (vbox), updateB, FALSE, FALSE, 0);

/* Our quit button. */
        quitB = gtk_button_new_with_label ("Quit");

/* Setup the signal to terminate the program when the button is clicked */
        gtk_signal_connect_object (GTK_OBJECT (quitB), "clicked",
                GTK_SIGNAL_FUNC (gtk_main_quit), GTK_OBJECT (window));

        gtk_box_pack_start (GTK_BOX (vbox), quitB, FALSE, FALSE, 0);

        gtk_widget_show (updateB);
        gtk_widget_show (quitB);

/* Showing the window last so everything pops up at once. */
        gtk_widget_show (window);
        
        drawRect(drawing_area, 0);

        /* And of course, our main function. */
        gtk_main ();

        /* Control returns here when gtk_main_quit() is called, but not when 
         * gtk_exit is used. */
        
        return(0);
}
/* example-end */
-- 
Ned Danieley (ned danieley duke edu)
Experimental Electrophysiology Laboratory
Box 90295, Duke University
Durham, NC  27708   (919) 660-5111




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