/* * Rainbow * ------- * Display a rainbow of colours in a window. This program demonstrates the * use of colours, drawings, scrollbars and labels. */ #include #define CUBE_SIZE 6 /* colour cube edge length */ window w = NULL; /* the main window */ scrollbar s = NULL; /* to control the intensity */ label t = NULL; /* to display the intensity */ drawing d = NULL; /* where to draw the rainbow */ checkbox c[3]; /* colour axis checkboxes */ label v[3]; /* colour value displays */ int axis = 2; /* 0 = Red, 1 = Green, 2 = Blue axis */ int intensity = 255; /* intensity along colour axis */ char *name[3] = { "Red", "Green", "Blue" }; /* use the colour axis value to determine which colour (a,b,c) represents */ rgb axis_colour(int a, int b, int c) { rgb result = Black; /* the 'axis' variable determines which colour's intensity is */ /* controlled by the 'intensity' variable, here given as 'a' */ switch(axis) { case 0: result = rgb(a, b, c); break; case 1: result = rgb(c, a, b); break; case 2: result = rgb(b, c, a); break; } return result; } /* draw the rainbow on the drawing area */ void draw_rainbow(drawing d, rect r) { int x, y; int a, b, c; int size = 256/CUBE_SIZE; /* step through one 'face' of the 'colour cube' */ /* the 'a' colour is the chosen 'axis' colour */ /* the 'b' colour increases as x increases across the drawing */ /* the 'c' colour increases as y increases down the drawing */ /* the axis_colour function determines what 'a', 'b' and 'c' mean */ a = intensity; for (x=0; x < CUBE_SIZE; x++) { b = x * 255/(CUBE_SIZE-1); for (y=0; y < CUBE_SIZE; y++) { c = y * 255/(CUBE_SIZE-1); setcolour(axis_colour(a, b, c)); fillellipse(rect(x*size, y*size, size, size)); } } } /* handle a mouse movement over the window */ void clear_colour_display(drawing d, int buttons, point p) { /* clear the display of colour component values */ /* red component */ settext(v[0], ""); /* green component */ settext(v[1], ""); /* blue component */ settext(v[2], ""); } /* handle a mouse movement over the drawing area */ void set_colour_display(drawing d, int buttons, point p) { int a, b, c; rgb colour; char str[40]; a = intensity; b = p.x; c = p.y; /* find out what colour the mouse is over */ colour = axis_colour(a, b, c); /* determine and display the values of each colour component */ /* red component */ sprintf(str, "%d", (colour >> 16) & 255); settext(v[0], str); /* green component */ sprintf(str, "%d", (colour >> 8) & 255); settext(v[1], str); /* blue component */ sprintf(str, "%d", (colour) & 255); settext(v[2], str); } /* handle a scrollbar event which changes the intensity value */ void change_intensity(scrollbar s, int value) { int new_intensity; char str[40]; /* the top of the scrollbar represents 100%, the bottom 0% intensity */ new_intensity = 255 - value; /* if the new intensity is the same, we ignore the change */ if (new_intensity == intensity) return; /* change the intensity of the axis colour */ intensity = new_intensity; /* change the percentage displayed in the intensity label */ sprintf(str, "%d%%", (int)((long)intensity)*100/255); settext(t, str); /* draw the new rainbow */ draw(d); } /* handle a checkbox event which changes the colour axis */ void change_axis(checkbox chk) { /* uncheck the previously checked checkbox */ if (chk != c[axis]) uncheck(c[axis]); /* set the new colour axis from the 'value' stored in this checkbox */ axis = getvalue(chk); /* ensure the correct checkbox is checked */ check(c[axis]); /* draw the new rainbow */ draw(d); } /* the window's redraw function merely draws a box around the edge */ void draw_window(window w, rect r) { setcolour(Black); drawrect(rect(5,5,480,270)); } /* starting point of the program */ void main(void) { int i; /* create the window */ w = newwindow("Rainbow", rect(50,50,490,280), Titlebar + Closebox + Minimize + UsePalette); setredraw(w, draw_window); //setmousemove(w, clear_colour_display); /* create the drawing area and set a mouse movement callback */ d = newdrawing(rect(10,10,256,256), draw_rainbow); setmousemove(d, set_colour_display); /* create the scrollbar which controls colour intensity */ s = newscrollbar(rect(280,10,20,256), 255, 15, change_intensity); /* create the colour axis checkboxes */ newlabel("Colour Axis", rect(320,10,100,35), AlignLeft + Underline); for (i=0; i < 3; i++) { c[i] = newcheckbox(name[i], rect(330,50+i*40,90,35), change_axis); setvalue(c[i], i); v[i] = newlabel("0", rect(430,50+i*40,40,35), AlignRight); } check(c[axis]); /* create the intensity display */ newlabel("Intensity", rect(320,180,90,35), AlignLeft + Underline); t = newlabel("100%", rect(330,220,90,35), AlignLeft); /* show the window */ show(w); mainloop(); }