diff options
Diffstat (limited to 'cd/test/cdtest/colorbar.c')
-rwxr-xr-x | cd/test/cdtest/colorbar.c | 565 |
1 files changed, 565 insertions, 0 deletions
diff --git a/cd/test/cdtest/colorbar.c b/cd/test/cdtest/colorbar.c new file mode 100755 index 0000000..c83f539 --- /dev/null +++ b/cd/test/cdtest/colorbar.c @@ -0,0 +1,565 @@ +/*=========================================================================*/ +/* COLORBAR.C - 03/03/96 */ +/* Color Bar implementation. */ +/*=========================================================================*/ + +/*- Constantes: -----------------------------------------------------------*/ +#define NUMCOLORS 16 + +/*- Bibliotecas padrao usadas ---------------------------------------------*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> + +/*- Inclusao das bibliotecas IUP e CD: ------------------------------------*/ +#include <iup.h> +#include <cd.h> +#include <cdiup.h> +#include <iupkey.h> + +/*- Declaraccoes e Prototypes: --------------------------------------------*/ +#include "cdtest.h" + +#undef isdigit +#include <ctype.h> + + +/*- Globais: --------------------------------------------------------------*/ +static struct { + cdCanvas *bar_canvas; /* canvas da colorbar */ + cdCanvas *other_canvas; /* canvas ativo anteriormente */ + int w, h; /* dimensoes do canvas */ + int bgr, bgg, bgb; /* cor de fundo do dialogo pai */ + int bci, fci; /* indice das cores correntes */ + long *p_foreground, *p_background; /* variaveis do usuario */ + long colors[NUMCOLORS]; /* palheta interna */ + int bounds[2*(NUMCOLORS+1)]; /* fronteiras dos elementos da palheta */ +} colorbar; /* contexto da colorbar */ + +/*- Dialogo para mudancca da cor da palheta: ------------------------------*/ +static struct { + Ihandle *dialog; + Ihandle *red; + Ihandle *green; + Ihandle *blue; + Ihandle *alpha; + Ihandle *bt_ok; + Ihandle *bt_cancel; + int to_change; +} color_change; + +/*- Macros: ---------------------------------------------------------------*/ +#define ignore(_) (void)(_) + +/*-------------------------------------------------------------------------*/ +/* Filtra inteiros. */ +/*-------------------------------------------------------------------------*/ +static int integer(Ihandle *self, int c) +{ + ignore(self); + + if (isdigit(c)) { + return IUP_DEFAULT; + } + else if ((c==K_TAB) || (c==K_CR) || (c==K_LEFT) || + (c==K_RIGHT) || (c==K_DEL) || (c==K_BS) || (c==K_sTAB)) { + return IUP_DEFAULT; + } + else { + return IUP_IGNORE; + } +} + +/*-------------------------------------------------------------------------*/ +/* Retorna a cor de indice i. */ +/*-------------------------------------------------------------------------*/ +static long getcolor(int i) +{ + if (i<=NUMCOLORS) { + return colorbar.colors[i-1]; + } + else return 0; +} + +/*-------------------------------------------------------------------------*/ +/* Mostra a caixa de dialogo Color Change. */ +/*-------------------------------------------------------------------------*/ +static void color_change_show(int c) +{ + unsigned char r, g, b, a; + long color; + char s[4]; + + /* mostra o dialogo Color Change */ + IupShow(color_change.dialog); + + /* mostra a cor atual */ + color = getcolor(c); + cdDecodeColor(color, &r, &g, &b); + sprintf(s, "%d", r); + IupSetAttribute(color_change.red, IUP_VALUE, s); + sprintf(s, "%d", g); + IupSetAttribute(color_change.green, IUP_VALUE, s); + sprintf(s, "%d", b); + IupSetAttribute(color_change.blue, IUP_VALUE, s); + + a = cdDecodeAlpha(color); + sprintf(s, "%d", a); + IupSetAttribute(color_change.alpha, IUP_VALUE, s); + + /* salva cor a ser alterada no contexto */ + color_change.to_change = c; +} + + +/*-------------------------------------------------------------------------*/ +/* Cancela a operaccao de mudancca de cor. */ +/*-------------------------------------------------------------------------*/ +static int color_change_cancel(void) +{ + IupHide(color_change.dialog); + + return IUP_DEFAULT; +} + +/*-------------------------------------------------------------------------*/ +/* Determina as fronteiras dos elementos da palheta. */ +/*-------------------------------------------------------------------------*/ +static void bounds(int dx, int p, int *x) +{ + int i; /* contador dos intervalos */ + int j; /* indice do vetor x */ + int k; /* inicio do intervalo */ + int e; /* erro da aproximacao inteira */ + int _2p; /* dobro do numero de intervalos */ + int q; /* quociente da divisao inteira */ + int _2r; /* dobro do resto da divisao inteira */ + + /* inicializa as variaveis */ + k = 0; /* inicio do primeiro intervalo */ + j = 0; /* indice do vetor x */ + e = 0; /* inicializa o erro */ + _2p = p << 1; /* dobro do numero de intervalos */ + _2r = (dx % p) << 1; /* dobro do resto da divisao inteira */ + q = dx / p; /* quociente da divisao inteira */ + + /* gera o vetor de intervalos */ + for (i=0; i<p; i++) { /* para p intervalos */ + e += _2r; /* incrementa o erro */ + x[j++] = k; /* inicio do intervalo */ + if (e >= p) { /* estourou? */ + e -= _2p; /* ajusta o novo limite */ + k += q + 1; /* arredonda para cima */ + } + else { + k += q; /* arredonda para baixo */ + } + x[j++] = k - 2; /* fim do intervalo */ + } +} + +/*-------------------------------------------------------------------------*/ +/* Acha a cor onde o mouse foi clicado por busca binaria. Retorna zero se */ +/* o click foi fora de qualquer cor. */ +/*-------------------------------------------------------------------------*/ +static int findwhere(int x, int y, int c1, int c2) +{ + int mid; + + /* so pode ser este ou o click foi fora */ + if (c1 == c2) { + if ((x > colorbar.bounds[c1<<1]) && (x < colorbar.bounds[(c1<<1) + 1])) { + if ((y > 0) && (y < (colorbar.h-1))) return c1; + else return 0; + } + else return 0; + } + + /* elemento intermediario */ + mid = (c1 + c2)>>1; + + /* se o click estah a direita do elemento intermediario */ + if (x > colorbar.bounds[(mid<<1) + 1]) return findwhere(x, y, mid+1, c2); + + /* se estah a esquerda do elemento intermediario */ + else if (x < colorbar.bounds[mid<<1]) return findwhere(x, y, c1, mid-1); + + /* estah no meio do intermediario e a vertical estah legal, eh esse */ + else if ((y > 0) && (y < (colorbar.h-1))) return mid; + + /* o programa nunca chega aqui, mas o compilador fica feliz */ + return 0; +} + +/*-------------------------------------------------------------------------*/ +/* Desenha a moldura do elemento da palheta. */ +/*-------------------------------------------------------------------------*/ +static void hollowbox(int xmin, int xmax, int ymin, int ymax) +{ + cdForeground(cdEncodeColor(255, 255, 255)); + cdLine(xmin, ymin, xmax, ymin); + cdLine(xmax, ymin+1, xmax, ymax); + + cdForeground(cdEncodeColor(102, 102, 102)); + cdLine(xmin, ymin+1, xmin, ymax); + cdLine(xmin+1, ymax, xmax-1, ymax); +} + + +/*-------------------------------------------------------------------------*/ +/* Muda a cor de indice i e retorna a anterior. */ +/*-------------------------------------------------------------------------*/ +static long changecolor(int i, long color) +{ + long temp; + + if (i<=NUMCOLORS) { + temp = colorbar.colors[i-1]; + colorbar.colors[i-1] = color; + return temp; + } + else return 0; +} + + +/*-------------------------------------------------------------------------*/ +/* Inicializa o vetor de cores. */ +/*-------------------------------------------------------------------------*/ +static void resetcolors(void) +{ + colorbar.colors[ 0] = cdEncodeColor( 0, 0, 0); + colorbar.colors[ 1] = cdEncodeColor(153, 153, 153); + colorbar.colors[ 2] = cdEncodeColor(178, 178, 178); + colorbar.colors[ 3] = cdEncodeColor(255, 255, 255); + colorbar.colors[ 4] = cdEncodeColor(255, 255, 0); + colorbar.colors[ 5] = cdEncodeColor(255, 0, 0); + colorbar.colors[ 6] = cdEncodeColor(255, 0, 255); + colorbar.colors[ 7] = cdEncodeColor( 0, 255, 255); + colorbar.colors[ 8] = cdEncodeColor( 0, 0, 255); + colorbar.colors[ 9] = cdEncodeColor( 0, 255, 0); + colorbar.colors[10] = cdEncodeColor(128, 128, 0); + colorbar.colors[11] = cdEncodeColor(128, 0, 0); + colorbar.colors[12] = cdEncodeColor(128, 0, 128); + colorbar.colors[13] = cdEncodeColor( 0, 128, 128); + colorbar.colors[14] = cdEncodeColor( 0, 0, 128); + colorbar.colors[15] = cdEncodeColor( 0, 128, 0); +} + +/*-------------------------------------------------------------------------*/ +/* Desenha a ColorBar. */ +/*-------------------------------------------------------------------------*/ +static int fColorBarRepaint(void) +{ + int i; + double dt; + + /* salva o canvas ativo no momento */ + colorbar.other_canvas = cdActiveCanvas(); + + /* ativa o canvas da colorbar */ + if (cdActivate(colorbar.bar_canvas) == CD_ERROR) { + printf("Color Bar Error: Unable to activate canvas."); + return 1; + } + cdClear(); + + /* desenha as cores da palheta */ + for (i=2; i<=2*NUMCOLORS; i+=2) { + cdForeground(getcolor(i>>1)); + cdBox(colorbar.bounds[i], colorbar.bounds[i+1], 1, colorbar.h-1); + hollowbox(colorbar.bounds[i], colorbar.bounds[i+1], 1, colorbar.h-1); + } + + /* desenha o fedback */ + dt = (colorbar.w-1)/(NUMCOLORS+1); + /* desenha a cor de fundo */ + cdForeground(getcolor(colorbar.bci)); + cdBox(1, (int)(2.0*dt/3.0), 1, (int)(2.0*(colorbar.h-1)/3.0)); + hollowbox(1, (int)(2.0*dt/3.0), 1, (int)(2.0*(colorbar.h-1)/3.0)); + /* desenha a cor de frente */ + cdForeground(getcolor(colorbar.fci)); + cdBox((int)(dt/3.0), (int)(dt)-1, (int)((colorbar.h-1)/3.0)+1, colorbar.h-1); + hollowbox((int)(dt/3.0), (int)(dt)-1, (int)((colorbar.h-1)/3.0)+1, colorbar.h-1); + + /* restaura o canvas anteriormente ativo */ + cdActivate(colorbar.other_canvas); + + return IUP_DEFAULT; +} + +/*-------------------------------------------------------------------------*/ +/* Funcao associada ao botao do mouse. */ +/*-------------------------------------------------------------------------*/ +static int fColorBarButtonCB(Ihandle *self, int b, int e, int x, int y, char *r) +{ + int c; + + ignore(self); + ignore(r); + + /* salva o canvas ativo no momento */ + colorbar.other_canvas = cdActiveCanvas(); + + /* ativa o canvas da colorbar */ + if (cdActivate(colorbar.bar_canvas) == CD_ERROR) { + printf("Color Bar Error: Unable to activate canvas."); + return 1; + } + + /* converte para coordenadas do canvas */ + cdUpdateYAxis(&y); + + /* se o botao foi pressionado */ + if (e) { + + /* acha onde foi o click */ + c = findwhere(x, y, 1, 16); + + /* se o click foi dentro de alguma cor... */ + if (c != 0) { + + /* botao da esquerda eh mudancca de cor de foreground */ + if (b == IUP_BUTTON1) { + + /* se for double-click */ + if ((isdouble(r)) && (c == colorbar.fci) ) { + + /* mostra o dialogo */ + color_change_show(c); + } + + /* muda a cor de frente corrente */ + else { + + /* largura de cada celula */ + double dt; + unsigned char r, g, b; + + /* altera a variavel do usuario */ + *(colorbar.p_foreground) = getcolor(c); + + /* altera o indice da cor de frente corrente */ + colorbar.fci = c; + + cdDecodeColor(getcolor(colorbar.fci), &r, &g, &b); + sprintf(ctgc.status_line, "cdForeground(cdEncodeColor(%d, %d, %d))", (int)r, (int)g, (int)b); + set_status(); + + /* altera o feedback no primeiro elemento da palheta */ + dt = (colorbar.w-1)/(NUMCOLORS+1); + cdForeground(getcolor(colorbar.fci)); + cdBox((int)(dt/3.0), (int)(dt)-1, (int)((colorbar.h-1)/3.0)+1, colorbar.h-1); + hollowbox((int)(dt/3.0), (int)(dt)-1, (int)((colorbar.h-1)/3.0)+1, colorbar.h-1); + } + + } + + else if (b == IUP_BUTTON3) { + + /* largura de cada celula */ + double dt; + unsigned char r, g, b; + + /* altera a variavel do usuario */ + *(colorbar.p_background) = getcolor(c); + + /* altera o indice da cor de frente corrente */ + colorbar.bci = c; + + cdDecodeColor(getcolor(colorbar.bci), &r, &g, &b); + sprintf(ctgc.status_line, "cdBackground(cdEncodeColor(%d, %d, %d))", (int)r, (int)g, (int)b); + set_status(); + + /* altera o feedback no primeiro elemento da palheta */ + dt = (colorbar.w-1)/(NUMCOLORS+1); + cdForeground(getcolor(colorbar.bci)); + cdBox(1, (int)(2.0*dt/3.0), 1, (int)(2.0*(colorbar.h-1)/3.0)); + hollowbox(1, (int)(2.0*dt/3.0), 1, (int)(2.0*(colorbar.h-1)/3.0)); + cdForeground(getcolor(colorbar.fci)); + cdBox((int)(dt/3.0), (int)(dt)-1, (int)((colorbar.h-1)/3.0)+1, colorbar.h-1); + hollowbox((int)(dt/3.0), (int)(dt)-1, (int)((colorbar.h-1)/3.0)+1, colorbar.h-1); + } + + } + + } + + /* restaura o canvas anteriormente ativo */ + cdActivate(colorbar.other_canvas); + + return IUP_DEFAULT; +} + +/*-------------------------------------------------------------------------*/ +/* Callback associado ao resize do canvas. */ +/*-------------------------------------------------------------------------*/ +static int fColorBarResizeCB(Ihandle *self, int w, int h) +{ + ignore(self); + + /* atualiza as dimensoes do canvas */ + colorbar.w = w; + colorbar.h = h; + + /* atualiza as fronteiras dos elementos da palheta */ + bounds(colorbar.w, NUMCOLORS+1, colorbar.bounds); + + return IUP_DEFAULT; +} + +/*-------------------------------------------------------------------------*/ +/* Confirma a mudanca de cores. */ +/*-------------------------------------------------------------------------*/ +static int color_change_ok(void) +{ + int r, g, b, a; + long new_color; + + /* pega os novos valores */ + r = IupGetInt(color_change.red, IUP_VALUE); + g = IupGetInt(color_change.green, IUP_VALUE); + b = IupGetInt(color_change.blue, IUP_VALUE); + a = IupGetInt(color_change.alpha, IUP_VALUE); + + /* se todos forem validos */ + if ((r<256)&&(g<256)&&(b<256)) { + + /* esconde a caixa de dialogo */ + IupHide(color_change.dialog); + + /* atualiza a cor no contexto */ + new_color = cdEncodeColor((unsigned char)r, (unsigned char) g, (unsigned char) b); + new_color = cdEncodeAlpha(new_color, (unsigned char)a); + changecolor(color_change.to_change, new_color); + + colorbar.fci = color_change.to_change; + + /* redesenha a colorbar */ + fColorBarRepaint(); + + /* altera a variavel do usuario */ + *(colorbar.p_foreground) = new_color; + + } + + return IUP_DEFAULT; +} + +/*-------------------------------------------------------------------------*/ +/* Inicializa a ColorBar. */ +/*-------------------------------------------------------------------------*/ +void ColorBarClose(void) +{ + cdKillCanvas(colorbar.bar_canvas); + IupDestroy(color_change.dialog); +} + +int ColorBarInit(Ihandle *parent, Ihandle *canvas, long *foreground, long *background) +{ + char *bg_color; + + /* pega a cor de fundo do dialogo parente */ + bg_color = IupGetAttribute(parent, "BGCOLOR"); + if (bg_color == NULL) { + printf("Color Bar Error: Unable to get bg_color."); + return 0; + } + sscanf(bg_color, "%d %d %d", &colorbar.bgr, &colorbar.bgg, &colorbar.bgb); + + /* inicializa as cores de fundo e de frente defaults */ + colorbar.fci = 1; + colorbar.bci = 4; + + /* pega o enderecco das variaveis do usuario */ + colorbar.p_foreground = foreground; + colorbar.p_background = background; + + /* inicializa a palheta interna de cores */ + resetcolors(); + + /* cria o canvas do CD */ + colorbar.bar_canvas = cdCreateCanvas(CD_IUP, canvas); + if (colorbar.bar_canvas == NULL) { + printf("Color Bar Error: Unable to create canvas."); + return 0; + } + + /* salva o canvas ativo no momento */ + colorbar.other_canvas = cdActiveCanvas(); + + /* ativa o canvas da colorbar */ + if (cdActivate(colorbar.bar_canvas) == CD_ERROR) { + printf("Color Bar Error: Unable to activate canvas."); + return 0; + } + + /* pega as dimensoes do canvas pela primeira vez */ + cdGetCanvasSize(&colorbar.w, &colorbar.h, NULL, NULL); + + /* restaura o canvas anteriormente ativo */ + if (colorbar.other_canvas != NULL) cdActivate(colorbar.other_canvas); + + /* cria o vetor com as fronteiras dos elementos da palheta */ + bounds(colorbar.w, NUMCOLORS+1, colorbar.bounds); + + /* associa os callbacks */ + IupSetFunction("cmdColorBarButtonCB", (Icallback) fColorBarButtonCB); + IupSetFunction("cmdColorBarRepaint", (Icallback) fColorBarRepaint); + IupSetFunction("cmdColorBarResizeCB", (Icallback) fColorBarResizeCB); + + /* desenha a barra de cores pela primeira vez */ + fColorBarRepaint(); + + /* inicializa o dialogo de troca de cores da palheta */ + color_change.dialog = IupDialog( + IupVbox( + IupHbox( + IupLabel("R:"), + color_change.red = IupText("cmdInteger"), + IupLabel("G:"), + color_change.green = IupText("cmdInteger"), + IupLabel("B:"), + color_change.blue = IupText("cmdInteger"), + IupLabel("A:"), + color_change.alpha = IupText("cmdInteger"), + NULL + ), + IupHbox( + IupFill(), + color_change.bt_ok = IupButton("OK", "cmdColorChangeOK"), + color_change.bt_cancel = IupButton("Cancel", "cmdColorChangeCancel"), + IupFill(), + NULL + ), + NULL + ) + ); + + /* atributos do dialogo */ + IupSetAttribute(color_change.dialog, IUP_TITLE, "Color Change:"); + IupSetAttribute(color_change.dialog, IUP_MARGIN, "5x5"); + IupSetAttribute(color_change.dialog, IUP_GAP, "5"); + IupSetAttribute(color_change.dialog, "MAXBOX", "NO"); + IupSetAttribute(color_change.dialog, "MINBOX", "NO"); + IupSetAttribute(color_change.dialog, "PARENTDIALOG", "dlgMain"); + + /* atributos dos texts */ + IupSetFunction("cmdInteger", (Icallback) integer); + IupSetAttribute(color_change.red, "NC", "3"); + IupSetAttribute(color_change.green, "NC", "3"); + IupSetAttribute(color_change.blue, "NC", "3"); + IupSetAttribute(color_change.alpha, "NC", "3"); + IupSetAttribute(color_change.red, "SIZE", "24"); + IupSetAttribute(color_change.green, "SIZE", "24"); + IupSetAttribute(color_change.blue, "SIZE", "24"); + IupSetAttribute(color_change.alpha, "SIZE", "24"); + + /* atributos dos botoes */ + IupSetAttribute(color_change.bt_ok, IUP_SIZE, "30"); + IupSetAttribute(color_change.bt_cancel, IUP_SIZE, "30"); + IupSetFunction("cmdColorChangeCancel", (Icallback) color_change_cancel); + IupSetFunction("cmdColorChangeOK", (Icallback) color_change_ok); + + return 1; +} |