Die Funktionen zur Farbauswahl wurden bereits in den Beispielen vorgestellt, und dort auch benutzt. Es exitieren vier Funktionen zur Farbwahl, je zwei zum Einstellen der Hintergrund- und Vordergrundfarbe. Zur Wahl steht jeweils eine Funktion zur Auswahl eines vordefinierten Farbwertes, bzw. die direkte Angabe eines RGB Wertes:
j_setcolor(int japi_object, int r, int g, int b) j_setcolorbg(int japi_object, int r, int g, int b) j_setnamedcolor(int japi_object, int farbe); j_setnamedcolorbg(int japi_object, int farbe);
Die beiden ersten Funktionen setzen die Farben für Vordergrund und Hintergrund durch RGB Werte. Jeder Kanal kann einen Wert von 0 bis 255 annehmen. Die nächsten beiden Funktionen setzen vordefinierte Farben. Die Variable ''farbe'' kann dabei einen Wert von 0 bis 15 annehmen. Diese 16 Farben entsprechen dem alten CGA Farbmodell und sind wie folgt zugeordnet:
J_BLACK 0 J_WHITE 1 J_RED 2 J_GREEN 3 J_BLUE 4 J_CYAN 5 J_MAGENTA 6 J_YELLOW 7 J_ORANGE 8 J_GREEN_YELLOW 9 J_GREEN_CYAN 10 J_BLUE_CYAN 11 J_BLUE_MAGENTA 12 J_RED_MAGENTA 13 J_DARK_GRAY 14 J_LIGHT_GRAY 15
Die Angabe eines RGB Wertes ist unabhängig von der tatsächlichen Farbtiefe des Bildschirms. Die Umrechnung von der übergebenen 24 Bit Farbtiefe auf die vorhandene Farbtiefe erfolgt automatisch. Der JAPI Kernel wählt dann die jeweils ''"ahnlichste'' Farbe aus.
Da diese Funktionen in den vorangegangenen Beispielen bereits ausführlich benutzt und beschrieben wurden, erübrigt sich an dieser Stelle eigentlich ein Beispielprogramm. Wir wollen stattdessen die Gelegenheit nutzen, hier die Japilib durch ein selbsgeschriebene Farbdialog Element zu erweitern.
Eine Farbauswahl Dalogbox (auch Colorpicker genannt) soll die Möglichkeit bieten über drei Farbregler eine Farbe einzustellen, und dessen RGB Werte an das aufrufende Programm zurückliefern. Der Aufruf der Dialogbox sollte demnach wie folgt erfolgen:
j_colordialog(frame, &red, &green, &blue);
Neben der Farbeinstellung sollte die Dialogbox folgende Eigenschaften haben:
Aus diesen Forderungen ergibt sich folgendes Layout:
Die Dialogbox erhält einen Borderlayoutmanager, der im Zentrum einen Canvas zu Farbdarstellung enthählt. Die RGB Scollbars werden in den linken Bereich des Borderlayouts positioniert. Dieser Bereich erhält nun ebenfalls einen Borderlayoutmanager. In dessen Kopfteil werden drei Labels, die die RGB Zahlenwerte darstellen, in einem Gridlayoutmanager positioniert. In den zentralen Bereich dieses zweiten Borderlayoutmanager werden die Scrollbars positioniert. Auch hierbei wird wiederum ein Gridlayout verwendet. Die beiden Button ''OK'' und ''Cancel'' werden in einem Flowlayoutmanager im Fussbereich der äußeren Borderlayout angeordnet.
Durch diese Anordnung hat das Labelfeld immer die gleiche Größe, und alle Label sind gleich groß. Das Scrollbarfeld hat eine konstante Breite aber immer die volle Höhe des Dialograhmens. Die Button liegen immer zentriert im Fußbereich. Der verbleibende Rest wird komplett dem Canvas zugeordnet.
Hier zunächst das komplette Listing der Funktion j_colordialog()
/* aus Example colordialog.c */ int j_colordialog(int frame, int *r, int *g, int *b) { int dialog,obj=0; int rscroll,gscroll,bscroll; int rlabel,glabel,blabel; int panel1,panel2,canvas; int ok,cancel; int xpos,ypos; unsigned char str[256]; int retval=J_FALSE; j_disable(frame); dialog = j_dialog(frame,"Colorpicker"); j_borderlayout(dialog); panel1=j_panel(dialog); j_borderpos(panel1,J_LEFT); j_borderlayout(panel1); panel2=j_panel(panel1); j_borderpos(panel2,J_TOP); j_gridlayout(panel2,0,3); rlabel=j_label(panel2,"255"); glabel=j_label(panel2,"255"); blabel=j_label(panel2,"255"); panel2=j_panel(panel1); j_gridlayout(panel2,0,3); rscroll=j_vscrollbar(panel2); gscroll=j_vscrollbar(panel2); bscroll=j_vscrollbar(panel2); j_setmax(rscroll,265); j_setmax(gscroll,265); j_setmax(bscroll,265); j_setnamedcolorbg(rscroll,J_RED); j_setnamedcolorbg(gscroll,J_GREEN); j_setnamedcolorbg(bscroll,J_BLUE); j_setvalue(rscroll,*r); j_setvalue(gscroll,*g); j_setvalue(bscroll,*b); panel1=j_panel(dialog); j_borderpos(panel1,J_BOTTOM); j_flowlayout(panel1,J_HORIZONTAL); ok = j_button(panel1," OK "); cancel = j_button(panel1,"Cancel"); canvas=j_canvas(dialog,200,200); j_pack(dialog); j_getpos(frame,&xpos,&ypos); xpos += j_getwidth(frame)/2-j_getwidth(dialog)/2; ypos += j_getheight(frame)/2-j_getheight(dialog)/2; j_setpos(dialog,xpos,ypos); j_show(dialog); while((obj!=cancel) && (obj != dialog)) { j_setcolorbg(canvas,j_getvalue(rscroll),j_getvalue(gscroll),j_getvalue(bscroll)); sprintf(str,"%3d",j_getvalue(rscroll)); j_settext(rlabel,str); sprintf(str,"%3d",j_getvalue(gscroll)); j_settext(glabel,str); sprintf(str,"%3d",j_getvalue(bscroll)); j_settext(blabel,str); obj = j_nextaction(); if(obj==ok) { retval=J_TRUE; *r = j_getvalue(rscroll); *g = j_getvalue(gscroll); *b = j_getvalue(bscroll); break; } } j_dispose(dialog); j_enable(frame); return(retval); }
Der Aufruf der Funktion:
j_disable(frame);
sorgt dafür, das vom aufrufenden Programm keine Events mehr kommen können. Dies ermöglicht uns, in der Funktion eine eigene Eventloop zu programmieren. Der Aufbau des Layout dürfte selbsterklärend sein. Die Maximalwerte der Scrollbars werden auf den wert 265 gesetzt. Dadurch ergibt sich, abzüglich der Hoehe des Schiebereglers von 10, ein maximal erreichbarer Wert von 255. Damit die Dialogbox immer mittig im aufrufenden Frame erscheint, wird die Position der Dialogbox mit folgenden Funktionsaufrufen gesetzt:
j_getpos(frame,&xpos,&ypos); xpos += j_getwidth(frame)/2-j_getwidth(dialog)/2; ypos += j_getheight(frame)/2-j_getheight(dialog)/2; j_setpos(dialog,xpos,ypos);
Dabei wird zunächst die Schirmposition des Frames ermittelt. Als der Hälfte der Breite von Frame und Colordialogbox kann die horizontale Position ermittelt werden. Die vertikale Position errechnet suich analog.
In der Eventloop wird bei jedem Event die Werte der drei Scrollbars ermittelt und die Farbe des Canvas sowie die Inhalte der Labels neu gesetzt. Diese Programmierung ist sicherlich ineffizient un könnte durch das Abfangen der Scrollbar Events verbessert werden. Da der Overhead jedoch nicht so groß ist, soll dies hier genügen.
Abschließend wird der Colordialog entfernt, und der aufrufende Frame wieder enabled:
j_dispose(dialog); j_enable(frame);
Das folgende Beispiel nutzt den Colordialog, um seine Hintergrundfarbe einzustellen (Abbildung 5.1):
/* Example colordialog.c */ : frame = j_frame(""); menubar = j_menubar(frame); file = j_menu(menubar,"File"); color = j_menuitem(file,"Color"); quit = j_menuitem(file,"Quit"); r=g=b=0; j_setcolorbg(frame,r,g,b); j_show(frame); while(1) { obj = j_nextaction(); if(obj==color) if(j_colordialog(frame,&r,&g,&b)==J_TRUE) j_setcolorbg(frame,r,g,b); if((obj==quit) || (obj == frame)) break; } :