iup-stack/cd/test/cdtest/colorbar.c

567 lines
19 KiB
C
Raw Normal View History

2023-02-20 16:44:45 +00:00
/*=========================================================================*/
/* 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 <cd_old.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;
}