diff options
Diffstat (limited to 'iup/srccontrols/color')
-rwxr-xr-x | iup/srccontrols/color/iup_colorbrowser.c | 849 | ||||
-rwxr-xr-x | iup/srccontrols/color/iup_colorbrowserdlg.c | 1120 | ||||
-rwxr-xr-x | iup/srccontrols/color/iup_colorhsi.c | 358 | ||||
-rwxr-xr-x | iup/srccontrols/color/iup_colorhsi.h | 44 |
4 files changed, 2371 insertions, 0 deletions
diff --git a/iup/srccontrols/color/iup_colorbrowser.c b/iup/srccontrols/color/iup_colorbrowser.c new file mode 100755 index 0000000..82b4a88 --- /dev/null +++ b/iup/srccontrols/color/iup_colorbrowser.c @@ -0,0 +1,849 @@ +/** \file +* \brief ColorBrowser Control. +* +* See Copyright Notice in "iup.h" +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include "iup.h" +#include "iupcbs.h" +#include "iupkey.h" + +#include <cd.h> +#include <cdiup.h> +#include <cdirgb.h> + +#include "iup_object.h" +#include "iup_attrib.h" +#include "iup_str.h" +#include "iup_drv.h" +#include "iup_stdcontrols.h" +#include "iup_controls.h" +#include "iup_cdutil.h" + +#include "iup_colorhsi.h" + + +#ifndef min +#define min(a, b) ( (a < b) ? (a) : (b) ) +#endif + +#define ICB_DEG2RAD 0.01745329252f /* degrees to radians (rad = ICB_DEG2RAD * deg) */ +#define ICB_DEFAULTSIZE 181 /* default size */ +#define ICB_SPACE 4 /* size of the spacing */ +#define ICB_HUEWIDTH 18 /* width of the hue ring */ +#define ICB_MARKSIZE 6 /* size of the cursor mark */ +enum {ICB_INSIDE_NONE, ICB_INSIDE_HUE, ICB_INSIDE_SI}; + + +struct _IcontrolData +{ + iupCanvas canvas; /* from IupCanvas (must reserve it) */ + + /* mouse interaction state */ + int h_down, + si_down; + + /* cursor positioning */ + int h_x, h_y, + si_x, si_y; + + /* HSI-XY coordinate convertion */ + int xc, yc, /* center */ + R, /* maximum radius available inside the size of the control */ + Ix, /* x coordinate where S is 0 */ + Iy1, /* y coordinate where I is 0 */ + Iy2, /* y coordinate where I is 1 */ + SxMax; /* x coordinate where S is 1 and I = 0.5 */ + + /* visual appearance control */ + int w, h; + int has_focus; + long bgcolor; + + /* attributes */ + float hue, /* 0<=H<=359 */ + saturation, /* 0<=S<=1 */ + intensity; /* 0<=I<=1 */ + unsigned char red, green, blue; /* 0<=x<=255 */ + + cdCanvas *cddbuffer; + cdCanvas *cdcanvas; +}; + + +static float iColorBrowserSXmax(Ihandle* ih, int y) +{ + if (y == ih->data->yc) + return (float)(ih->data->SxMax - ih->data->Ix); + else if (y < ih->data->yc) + { + float D2 = (ih->data->Iy2 - ih->data->Iy1)/2.0f; + return ((float)(ih->data->SxMax - ih->data->Ix)*(y-ih->data->yc + D2))/D2; + } + else + { + float D2 = (ih->data->Iy2 - ih->data->Iy1)/2.0f; + return -((float)(ih->data->SxMax - ih->data->Ix)*(y-ih->data->yc - D2))/D2; + } +} + +static float iColorBrowserCalcIntensity(Ihandle* ih, int y) +{ + return (float)(y - ih->data->Iy1)/(float)(ih->data->Iy2 - ih->data->Iy1); +} + +static float iColorBrowserCalcSaturation(Ihandle* ih, int x, float sx_max) +{ + if (sx_max == 0) + return 0; + else + return (float)(x - ih->data->Ix)/sx_max; +} + +/* Rotate points of 60 degrees */ +static void iColorBrowserRotatePoints(float *x1, float *y1, float *x2, float *y2, int xc, int yc) +{ + float xt, yt; + float nxt, nyt; + static const float s60 = 0.8660254f; + static const float c60 = 0.5f; + + xt = *x1 - xc; + yt = *y1 - yc; + nxt = xt * c60 - yt * s60; + nyt = xt * s60 + yt * c60; + *x1 = nxt + xc; + *y1 = nyt + yc; + + xt = *x2 - xc; + yt = *y2 - yc; + nxt = xt * c60 - yt * s60; + nyt = xt * s60 + yt * c60; + *x2 = nxt + xc; + *y2 = nyt + yc; +} + +static void iColorBrowserRenderImageHue(Ihandle* ih) +{ + int x, y, active = 1; + unsigned char *red, *green, *blue; + unsigned char bg_red, bg_green, bg_blue; + if (!ih->data->cddbuffer) + return; + + cdCanvasBackground(ih->data->cddbuffer, ih->data->bgcolor); + cdCanvasClear(ih->data->cddbuffer); + + if (!iupdrvIsActive(ih)) + active = 0; + + if (ih->data->has_focus) + cdDrawFocusRect(ih->data->cddbuffer, 0, 0, ih->data->w-1, ih->data->h-1); + + red = cdRedImage(ih->data->cddbuffer); + green = cdGreenImage(ih->data->cddbuffer); + blue = cdBlueImage(ih->data->cddbuffer); + + cdDecodeColor(ih->data->bgcolor, &bg_red, &bg_green, &bg_blue); + + for (y = 0; y < ih->data->h; y++) + { + float sx_max = iColorBrowserSXmax(ih, y); + + for (x = 0; x < ih->data->w; x++) + { + int xl, yl; + float radius, diff1, diff2; + + if (y > ih->data->Iy1 && + y < ih->data->Iy2 && + x > ih->data->Ix && + x < ih->data->Ix+(int)sx_max) + continue; + + xl = x - ih->data->xc; + yl = y - ih->data->yc; + radius = sqrtf(xl*xl + yl*yl); + + diff1 = radius - (ih->data->R-ICB_SPACE-ICB_HUEWIDTH); + diff2 = (ih->data->R-ICB_SPACE) - radius; + + if (diff1>0 && diff2>0) + { + float h, s, i; + int offset = y*ih->data->w + x; + unsigned char* r = red + offset; + unsigned char* g = green + offset; + unsigned char* b = blue + offset; + + h = atan2f(yl, xl); + h = (float)(h * CD_RAD2DEG); + s = 1.0f; /* maximum saturation */ + i = 0.5f; /* choose I where S is maximum */ + + iupColorHSI2RGB(h, s, i, r, g, b); + + if (diff1<1 || diff2<1) /* anti-aliasing */ + { + float diff = (float)(diff1<1? diff1: diff2); + *r = (unsigned char)((*r)*diff + bg_red*(1.0f-diff)); + *g = (unsigned char)((*g)*diff + bg_green*(1.0f-diff)); + *b = (unsigned char)((*b)*diff + bg_blue*(1.0f-diff)); + } + + if (!active) + { + *r = cdIupLIGTHER(*r); + *g = cdIupLIGTHER(*g); + *b = cdIupLIGTHER(*b); + } + } + } + } + + if (active) + { + float x1, x2, y1, y2; + unsigned char shade_lr, shade_lg, shade_lb, + shade_dr, shade_dg, shade_db; + shade_dr = (unsigned char)((2 * bg_red) / 3); + shade_dg = (unsigned char)((2 * bg_green) / 3); + shade_db = (unsigned char)((2 * bg_blue) / 3); + shade_lr = (unsigned char)((255 + bg_red) / 2); + shade_lg = (unsigned char)((255 + bg_green) / 2); + shade_lb = (unsigned char)((255 + bg_blue) / 2); + cdCanvasForeground(ih->data->cddbuffer, cdEncodeColor(shade_dr, shade_dg, shade_db)); + x1 = (float)(ih->data->xc-ih->data->R+ICB_SPACE); y1 = (float)ih->data->yc; x2 = (float)(x1+ICB_HUEWIDTH/2); y2 = (float)ih->data->yc; + cdCanvasLine(ih->data->cddbuffer, (int) x1, (int) y1, (int) x2, (int) y2); + iColorBrowserRotatePoints(&x1, &y1, &x2, &y2, ih->data->xc, ih->data->yc); + cdCanvasForeground(ih->data->cddbuffer, cdEncodeColor(shade_lr, shade_lg, shade_lb)); + cdCanvasLine(ih->data->cddbuffer, (int) x1, (int) y1, (int) x2, (int) y2); + iColorBrowserRotatePoints(&x1, &y1, &x2, &y2, ih->data->xc, ih->data->yc); + cdCanvasForeground(ih->data->cddbuffer, cdEncodeColor(shade_dr, shade_dg, shade_db)); + cdCanvasLine(ih->data->cddbuffer, (int) x1, (int) y1, (int) x2, (int) y2); + iColorBrowserRotatePoints(&x1, &y1, &x2, &y2, ih->data->xc, ih->data->yc); + cdCanvasForeground(ih->data->cddbuffer, cdEncodeColor(shade_lr, shade_lg, shade_lb)); + cdCanvasLine(ih->data->cddbuffer, (int) x1, (int) y1, (int) x2, (int) y2); + iColorBrowserRotatePoints(&x1, &y1, &x2, &y2, ih->data->xc, ih->data->yc); + cdCanvasForeground(ih->data->cddbuffer, cdEncodeColor(shade_dr, shade_dg, shade_db)); + cdCanvasLine(ih->data->cddbuffer, (int) x1, (int) y1, (int) x2, (int) y2); + iColorBrowserRotatePoints(&x1, &y1, &x2, &y2, ih->data->xc, ih->data->yc); + cdCanvasLine(ih->data->cddbuffer, (int) x1, (int) y1, (int) x2, (int) y2); + } +} + +static void iColorBrowserRenderImageSI(Ihandle* ih) +{ + int x, y, active = 1; + unsigned char *red, *green, *blue; + unsigned char bg_red, bg_green, bg_blue; + float angle, cos_angle, sin_angle; + if (!ih->data->cddbuffer) + return; + + if (!iupdrvIsActive(ih)) + active = 0; + + red = cdRedImage(ih->data->cddbuffer); + green = cdGreenImage(ih->data->cddbuffer); + blue = cdBlueImage(ih->data->cddbuffer); + + cdDecodeColor(ih->data->bgcolor, &bg_red, &bg_green, &bg_blue); + + angle = ih->data->hue * ICB_DEG2RAD; + cos_angle = cosf(angle); + sin_angle = sinf(angle); + + for (y = 0; y < ih->data->h; y++) + { + float sx_max, i; + + if (y < ih->data->Iy1) + continue; + else if (y > ih->data->Iy2) + continue; + + sx_max = iColorBrowserSXmax(ih, y); + i = iColorBrowserCalcIntensity(ih, y); + + for (x = 0; x < ih->data->w; x++) + { + if (x < ih->data->Ix) + continue; + else if (x > ih->data->Ix+(int)sx_max) + continue; + + { + int offset = y*ih->data->w + x; + unsigned char* r = red + offset; + unsigned char* g = green + offset; + unsigned char* b = blue + offset; + float s, diff; + + s = iColorBrowserCalcSaturation(ih, x, sx_max); + + iupColorHSI2RGB(ih->data->hue, s, i, r, g, b); + + diff = sx_max - (float)(x - ih->data->Ix); + if (diff<1.0f) /* anti-aliasing */ + { + *r = (unsigned char)((*r)*diff + bg_red*(1.0f-diff)); + *g = (unsigned char)((*g)*diff + bg_green*(1.0f-diff)); + *b = (unsigned char)((*b)*diff + bg_blue*(1.0f-diff)); + } + + if (!active) + { + *r = cdIupLIGTHER(*r); + *g = cdIupLIGTHER(*g); + *b = cdIupLIGTHER(*b); + } + } + } + } +} + +static void iColorBrowserUpdateCursorSI(Ihandle* ih) +{ + int x; + int y = (int)(ih->data->intensity*(ih->data->Iy2 - ih->data->Iy1)) + ih->data->Iy1; + ih->data->si_y = iupROUND(y); + x = (int)(ih->data->saturation*iColorBrowserSXmax(ih, ih->data->si_y)) + ih->data->Ix; + ih->data->si_x = iupROUND(x); +} + +static void iColorBrowserSetCursorSI(Ihandle* ih, int x, int y) +{ + float sx_max; + + if (y < ih->data->Iy1) + ih->data->si_y = ih->data->Iy1; + else if (y > ih->data->Iy2) + ih->data->si_y = ih->data->Iy2; + else + ih->data->si_y = y; + + sx_max = iColorBrowserSXmax(ih, ih->data->si_y); + + if (x < ih->data->Ix) + ih->data->si_x = ih->data->Ix; + else if (x > ih->data->Ix+sx_max) + ih->data->si_x = ih->data->Ix+(int)sx_max; + else + ih->data->si_x = x; + + ih->data->intensity = iColorBrowserCalcIntensity(ih, ih->data->si_y); + ih->data->saturation = iColorBrowserCalcSaturation(ih, ih->data->si_x, sx_max); + + if (ih->data->saturation == -0.0f) + ih->data->saturation = 0; + if (ih->data->intensity == -0.0f) + ih->data->intensity = 0; +} + +static void iColorBrowserUpdateCursorHue(Ihandle* ih) +{ + int rc = ih->data->R-ICB_SPACE-ICB_HUEWIDTH/2; + float angle = ih->data->hue * ICB_DEG2RAD; + float cos_angle = cosf(angle); + float sin_angle = sinf(angle); + float x = rc*cos_angle + ih->data->xc; + float y = rc*sin_angle + ih->data->yc; + ih->data->h_x = iupROUND(x); + ih->data->h_y = iupROUND(y); +} + +static void iColorBrowserSetCursorHue(Ihandle* ih, int x, int y) +{ + int xl = x - ih->data->xc; + int yl = y - ih->data->yc; + ih->data->hue = (float)(atan2f(yl, xl) * CD_RAD2DEG); + ih->data->hue = fmodf(ih->data->hue, 360.0f); + if (ih->data->hue < 0.0f) + ih->data->hue += 360.0f; + + iColorBrowserUpdateCursorHue(ih); +} + +static int iColorBrowserCheckInside(Ihandle* ih, int x, int y) +{ + int xl = x - ih->data->xc; + int yl = y - ih->data->yc; + float radius = sqrtf(xl*xl + yl*yl); + + if (radius < ih->data->R-ICB_SPACE-ICB_HUEWIDTH-ICB_SPACE) + return ICB_INSIDE_SI; + + if (radius > ih->data->R-ICB_SPACE-ICB_HUEWIDTH && + radius < ih->data->R-ICB_SPACE) + return ICB_INSIDE_HUE; + + return ICB_INSIDE_NONE; +} + +static void iColorBrowserHSI2RGB(Ihandle* ih) +{ + iupColorHSI2RGB(ih->data->hue, ih->data->saturation, ih->data->intensity, + &(ih->data->red), &(ih->data->green), &(ih->data->blue)); +} + +static void iColorBrowserRGB2HSI(Ihandle* ih) +{ + iupColorRGB2HSI(ih->data->red, ih->data->green, ih->data->blue, + &(ih->data->hue), &(ih->data->saturation), &(ih->data->intensity)); +} + +static void iColorBrowserUpdateDisplay(Ihandle* ih) +{ + if (!ih->data->cddbuffer) + return; + + cdCanvasFlush(ih->data->cddbuffer); /* swap the RGB to the display canvas */ + + if (iupdrvIsActive(ih)) + { + cdCanvasForeground(ih->data->cdcanvas, CD_GRAY); + cdCanvasArc(ih->data->cdcanvas, ih->data->h_x+1, ih->data->h_y, ICB_MARKSIZE, ICB_MARKSIZE, 0, 360); + cdCanvasArc(ih->data->cdcanvas, ih->data->si_x+1, ih->data->si_y, ICB_MARKSIZE, ICB_MARKSIZE, 0, 360); + cdCanvasForeground(ih->data->cdcanvas, CD_WHITE); + cdCanvasArc(ih->data->cdcanvas, ih->data->h_x, ih->data->h_y, ICB_MARKSIZE, ICB_MARKSIZE, 0, 360); + cdCanvasArc(ih->data->cdcanvas, ih->data->si_x, ih->data->si_y, ICB_MARKSIZE, ICB_MARKSIZE, 0, 360); + } + else + { + cdCanvasForeground(ih->data->cdcanvas, CD_DARK_GRAY); + cdCanvasSector(ih->data->cdcanvas, ih->data->h_x, ih->data->h_y, ICB_MARKSIZE+1, ICB_MARKSIZE+1, 0, 360); + cdCanvasSector(ih->data->cdcanvas, ih->data->si_x, ih->data->si_y, ICB_MARKSIZE+1, ICB_MARKSIZE+1, 0, 360); + } +} + +static void iColorBrowserCallChangeCb(Ihandle* ih) +{ + IFnccc change_cb = (IFnccc) IupGetCallback(ih, "CHANGE_CB"); + if (change_cb) + change_cb(ih, ih->data->red, ih->data->green, ih->data->blue); + + iupBaseCallValueChangedCb(ih); +} + +static void iColorBrowserCallDragCb(Ihandle* ih) +{ + IFnccc drag_cb = (IFnccc) IupGetCallback(ih, "DRAG_CB"); + if (drag_cb) + drag_cb(ih, ih->data->red, ih->data->green, ih->data->blue); + + iupBaseCallValueChangedCb(ih); +} + +static int iColorBrowserHmouse(Ihandle* ih, int x, int y, int drag) +{ + iColorBrowserSetCursorHue(ih, x, y); + iColorBrowserHSI2RGB(ih); + /* must update the Si area */ + iColorBrowserRenderImageSI(ih); + iColorBrowserUpdateDisplay(ih); + + if (drag) + iColorBrowserCallDragCb(ih); + else + iColorBrowserCallChangeCb(ih); + + return IUP_DEFAULT; +} + +static int iColorBrowserSImouse(Ihandle* ih, int x, int y, int drag) +{ + iColorBrowserSetCursorSI(ih, x, y); + iColorBrowserHSI2RGB(ih); + iColorBrowserUpdateDisplay(ih); + + if (drag) + iColorBrowserCallDragCb(ih); + else + iColorBrowserCallChangeCb(ih); + + return IUP_DEFAULT; +} + + +/******************************************************************/ + + +static int iColorBrowserButton_CB(Ihandle* ih, int b, int press, int x, int y) +{ + if (b != IUP_BUTTON1) + return IUP_DEFAULT; + + cdCanvasUpdateYAxis(ih->data->cdcanvas, &y); + + if (press) + { + int inside = iColorBrowserCheckInside(ih, x, y); + + if (!ih->data->h_down && inside==ICB_INSIDE_HUE) + { + iColorBrowserHmouse(ih, x, y, 1); + ih->data->h_down = 1; + } + + if (!ih->data->si_down && inside==ICB_INSIDE_SI) + { + iColorBrowserSImouse(ih, x, y, 1); + ih->data->si_down = 1; + } + } + else + { + if (ih->data->h_down) + { + iColorBrowserHmouse(ih, x, y, 0); + ih->data->h_down = 0; + } + + if (ih->data->si_down) + { + iColorBrowserSImouse(ih, x, y, 0); + ih->data->si_down = 0; + } + } + + return IUP_DEFAULT; +} + +/* Callback for the mouse motion in the canvas */ +static int iColorBrowserMotion_CB(Ihandle* ih, int x, int y, char *status) +{ + if (!iup_isbutton1(status)) + { + ih->data->h_down = 0; + ih->data->si_down = 0; + return IUP_DEFAULT; + } + + if (ih->data->h_down) + { + cdCanvasUpdateYAxis(ih->data->cdcanvas, &y); + iColorBrowserHmouse(ih, x, y, 1); + } + else if (ih->data->si_down) + { + cdCanvasUpdateYAxis(ih->data->cdcanvas, &y); + iColorBrowserSImouse(ih, x, y, 1); + } + + return IUP_DEFAULT; +} + +static int iColorBrowserFocus_CB(Ihandle* ih, int focus) +{ + ih->data->has_focus = focus; + iColorBrowserRenderImageHue(ih); + iColorBrowserRenderImageSI(ih); + iColorBrowserUpdateDisplay(ih); + return IUP_DEFAULT; +} + +static void iColorBrowserUpdateSize(Ihandle* ih) +{ + int T, D; + + /* update canvas size */ + cdCanvasActivate(ih->data->cddbuffer); + cdCanvasGetSize(ih->data->cddbuffer, &ih->data->w, &ih->data->h, NULL, NULL); + + ih->data->R = min(ih->data->w, ih->data->h)/2; + ih->data->xc = ih->data->w/2; + ih->data->yc = ih->data->h/2; + T = ih->data->R-ICB_SPACE-ICB_HUEWIDTH-ICB_SPACE; + ih->data->Ix = ih->data->xc - T/2; /* cos(60)=0.5 */ + D = (int)(2*T*0.866); /* sin(60)=0.866 */ + ih->data->Iy1 = ih->data->yc - D/2; + ih->data->Iy2 = ih->data->Iy1 + D; + ih->data->SxMax = ih->data->xc + T; +} + +static int iColorBrowserResize_CB(Ihandle* ih) +{ + if (!ih->data->cddbuffer) + { + /* update canvas size */ + cdCanvasActivate(ih->data->cdcanvas); + + /* this can fail if canvas size is zero */ + ih->data->cddbuffer = cdCreateCanvas(CD_DBUFFERRGB, ih->data->cdcanvas); + } + + if (!ih->data->cddbuffer) + return IUP_DEFAULT; + + /* update size */ + iColorBrowserUpdateSize(ih); + + iColorBrowserUpdateCursorHue(ih); + iColorBrowserUpdateCursorSI(ih); + + /* update render */ + iColorBrowserRenderImageHue(ih); + iColorBrowserRenderImageSI(ih); + + return IUP_DEFAULT; +} + +static int iColorBrowserRedraw_CB(Ihandle* ih) +{ + iColorBrowserUpdateDisplay(ih); + return IUP_DEFAULT; +} + +static int iColorBrowserWheel_CB(Ihandle* ih, float delta) +{ + ih->data->hue += delta; + + iColorBrowserUpdateCursorHue(ih); + iColorBrowserHSI2RGB(ih); + /* must update the Si area */ + iColorBrowserRenderImageSI(ih); + iColorBrowserUpdateDisplay(ih); + iColorBrowserCallChangeCb(ih); + + return IUP_DEFAULT; +} + +static int iColorBrowserKeypress_CB(Ihandle* ih, int c, int press) +{ + int x, y, changing_hue = 0; + + if (!press) + return IUP_DEFAULT; + + x = ih->data->si_x; + y = ih->data->si_y; + + switch (c) + { + case K_UP: + y++; + break; + case K_DOWN: + y--; + break; + case K_RIGHT: + x++; + break; + case K_LEFT: + x--; + break; + case K_PGUP: + ih->data->hue += 1.0f; + changing_hue = 1; + break; + case K_PGDN: + ih->data->hue -= 1.0f; + changing_hue = 1; break; + case K_HOME: + ih->data->hue = 0.0f; + changing_hue = 1; + break; + case K_END: + ih->data->hue = 180.0f; + changing_hue = 1; + break; + default: + return IUP_DEFAULT; + } + + if (changing_hue) + { + iColorBrowserUpdateCursorHue(ih); + /* must update the Si area */ + iColorBrowserRenderImageSI(ih); + } + else + iColorBrowserSetCursorSI(ih, x, y); + + iColorBrowserHSI2RGB(ih); + + iColorBrowserUpdateDisplay(ih); + iColorBrowserCallChangeCb(ih); + + return IUP_IGNORE; /* to avoid arrow keys being processed by the system */ +} + + +/*********************************************************************************/ + + +static char* iColorBrowserGetHSIAttrib(Ihandle* ih) +{ + char* buffer = iupStrGetMemory(100); + sprintf(buffer, "%f %f %f", (double)ih->data->hue, (double)ih->data->saturation, (double)ih->data->intensity); + return buffer; +} + +static int iColorBrowserSetHSIAttrib(Ihandle* ih, const char* value) +{ + float old_hue = ih->data->hue, + old_saturation = ih->data->saturation, + old_intensity = ih->data->intensity; + + if (!iupStrToHSI(value, &ih->data->hue, &ih->data->saturation, &ih->data->intensity)) + return 0; + + if (ih->data->cddbuffer) + { + if (old_hue != ih->data->hue) + iColorBrowserUpdateCursorHue(ih); + if (old_saturation != ih->data->saturation || old_intensity != ih->data->intensity) + iColorBrowserUpdateCursorSI(ih); + iColorBrowserHSI2RGB(ih); + iColorBrowserRenderImageSI(ih); + iColorBrowserUpdateDisplay(ih); + } + + return 0; +} + +static char* iColorBrowserGetRGBAttrib(Ihandle* ih) +{ + char* buffer = iupStrGetMemory(20); + sprintf(buffer, "%d %d %d", (int) ih->data->red, (int) ih->data->green, (int) ih->data->blue); + return buffer; +} + +static int iColorBrowserSetRGBAttrib(Ihandle* ih, const char* value) +{ + unsigned char r, g, b; + if (!iupStrToRGB(value, &r, &g, &b)) + return 0; + + ih->data->red = r; + ih->data->green = g; + ih->data->blue = b; + iColorBrowserRGB2HSI(ih); + + if (ih->data->cddbuffer) + { + iColorBrowserUpdateCursorHue(ih); + iColorBrowserUpdateCursorSI(ih); + iColorBrowserRenderImageSI(ih); + iColorBrowserUpdateDisplay(ih); + } + + return 0; +} + +static int iColorBrowserSetBgColorAttrib(Ihandle* ih, const char* value) +{ + if (!value) + value = iupControlBaseGetParentBgColor(ih); + ih->data->bgcolor = cdIupConvertColor(value); + + if (ih->data->cddbuffer) + { + iColorBrowserRenderImageHue(ih); + iColorBrowserRenderImageSI(ih); + iColorBrowserUpdateDisplay(ih); + } + return 1; +} + +static int iColorBrowserSetActiveAttrib(Ihandle* ih, const char* value) +{ + iupBaseSetActiveAttrib(ih, value); + iColorBrowserUpdateDisplay(ih); + return 0; /* do not store value in hash table */ +} + + +/****************************************************************************/ + + +static int iColorBrowserMapMethod(Ihandle* ih) +{ + ih->data->cdcanvas = cdCreateCanvas(CD_IUP, ih); + if (!ih->data->cdcanvas) + return IUP_ERROR; + + /* this can fail if canvas size is zero */ + ih->data->cddbuffer = cdCreateCanvas(CD_DBUFFERRGB, ih->data->cdcanvas); + + if (ih->data->cddbuffer) + iColorBrowserUpdateSize(ih); + + return IUP_NOERROR; +} + +static void iColorBrowserUnMapMethod(Ihandle* ih) +{ + if (ih->data->cddbuffer) + cdKillCanvas(ih->data->cddbuffer); + + if (ih->data->cdcanvas) + cdKillCanvas(ih->data->cdcanvas); +} + +static int iColorBrowserCreateMethod(Ihandle* ih, void **params) +{ + (void)params; + + /* free the data allocated by IupCanvas */ + if (ih->data) free(ih->data); + ih->data = iupALLOCCTRLDATA(); + + /* change the IupCanvas default values */ + IupSetfAttribute(ih, "RASTERSIZE", "%dx%d", ICB_DEFAULTSIZE, ICB_DEFAULTSIZE); + iupAttribSetStr(ih, "BORDER", "NO"); + ih->expand = IUP_EXPAND_NONE; + + /* IupCanvas callbacks */ + IupSetCallback(ih, "ACTION", (Icallback)iColorBrowserRedraw_CB); + IupSetCallback(ih, "RESIZE_CB", (Icallback)iColorBrowserResize_CB); + IupSetCallback(ih, "BUTTON_CB", (Icallback)iColorBrowserButton_CB); + IupSetCallback(ih, "MOTION_CB", (Icallback)iColorBrowserMotion_CB); + IupSetCallback(ih, "FOCUS_CB", (Icallback)iColorBrowserFocus_CB); + IupSetCallback(ih, "KEYPRESS_CB", (Icallback)iColorBrowserKeypress_CB); + IupSetCallback(ih, "WHEEL_CB", (Icallback)iColorBrowserWheel_CB); + + return IUP_NOERROR; +} + +Iclass* iupColorBrowserGetClass(void) +{ + Iclass* ic = iupClassNew(iupCanvasGetClass()); + + ic->name = "colorbrowser"; + ic->format = NULL; /* no parameters */ + ic->nativetype = IUP_TYPECANVAS; + ic->childtype = IUP_CHILDNONE; + ic->is_interactive = 1; + + /* Class functions */ + ic->Create = iColorBrowserCreateMethod; + ic->Map = iColorBrowserMapMethod; + ic->UnMap = iColorBrowserUnMapMethod; + + /* IupColorBrowser Callbacks */ + iupClassRegisterCallback(ic, "DRAG_CB", "ccc"); + iupClassRegisterCallback(ic, "CHANGE_CB", "ccc"); + iupClassRegisterCallback(ic, "VALUECHANGED_CB", ""); + + /* IupColorBrowser only */ + iupClassRegisterAttribute(ic, "RGB", iColorBrowserGetRGBAttrib, iColorBrowserSetRGBAttrib, "255 0 0", NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); /* force new default value */ + iupClassRegisterAttribute(ic, "HSI", iColorBrowserGetHSIAttrib, iColorBrowserSetHSIAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + + /* Overwrite IupCanvas Attributes */ + iupClassRegisterAttribute(ic, "ACTIVE", iupBaseGetActiveAttrib, iColorBrowserSetActiveAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_DEFAULT); + iupClassRegisterAttribute(ic, "BGCOLOR", iupControlBaseGetBgColorAttrib, iColorBrowserSetBgColorAttrib, NULL, "255 255 255", IUPAF_NO_INHERIT); /* overwrite canvas implementation, set a system default to force a new default */ + + return ic; +} + +Ihandle *IupColorBrowser(void) +{ + return IupCreate("colorbrowser"); +} diff --git a/iup/srccontrols/color/iup_colorbrowserdlg.c b/iup/srccontrols/color/iup_colorbrowserdlg.c new file mode 100755 index 0000000..65e4d37 --- /dev/null +++ b/iup/srccontrols/color/iup_colorbrowserdlg.c @@ -0,0 +1,1120 @@ +/** \file + * \brief IupColorDlg pre-defined dialog control + * + * See Copyright Notice in "iup.h" + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "iup.h" +#include "iupcbs.h" +#include "iupkey.h" +#include "iupcontrols.h" + +#include <cd.h> +#include <cdiup.h> +#include <cddbuf.h> +#include <cdirgb.h> + +#include "iup_object.h" +#include "iup_attrib.h" +#include "iup_str.h" +#include "iup_strmessage.h" +#include "iup_drv.h" +#include "iup_stdcontrols.h" +#include "iup_controls.h" +#include "iup_cdutil.h" +#include "iup_register.h" +#include "iup_register.h" +#include "iup_image.h" +#include "iup_colorhsi.h" +#include "iup_childtree.h" + + +const char* default_colortable_cells[20] = +{ + "0 0 0", "64 64 64", "128 128 128", "144 144 144", "0 128 128", "128 0 128", "128 128 0", "128 0 0", "0 128 0", "0 0 128", + "255 255 255", "240 240 240", "224 224 224", "192 192 192", "0 255 255", "255 0 255", "255 255 0", "255 0 0", "0 255 0", "0 0 255" +}; + +typedef struct _IcolorDlgData +{ + int status; + + long previous_color, color; + + float hue, saturation, intensity; + unsigned char red, green, blue, alpha; + + Ihandle *red_txt, *green_txt, *blue_txt, *alpha_txt; + Ihandle *hue_txt, *intensity_txt, *saturation_txt; + Ihandle *color_browser, *color_cnv, *colorhex_txt; + Ihandle *colortable_cbar, *alpha_val; + Ihandle *help_bt; + + cdCanvas* color_cdcanvas, *color_cddbuffer; +} IcolorDlgData; + + +static void iColorBrowserDlgColorCnvRepaint(IcolorDlgData* colordlg_data) +{ + int x, y, w, h, width, height, box_size = 10; + + if (!colordlg_data->color_cddbuffer) + return; + + cdCanvasGetSize(colordlg_data->color_cddbuffer, &width, &height, NULL, NULL); + + cdCanvasBackground(colordlg_data->color_cddbuffer, CD_WHITE); + cdCanvasClear(colordlg_data->color_cddbuffer); + + w = (width+box_size-1)/box_size; + h = (height+box_size-1)/box_size; + + cdCanvasForeground(colordlg_data->color_cddbuffer, CD_GRAY); + + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + if (((x%2) && (y%2)) || (((x+1)%2) && ((y+1)%2))) + { + int xmin, xmax, ymin, ymax; + + xmin = x*box_size; + xmax = xmin+box_size; + ymin = y*box_size; + ymax = ymin+box_size; + + cdCanvasBox(colordlg_data->color_cddbuffer, xmin, xmax, ymin, ymax); + } + } + } + + cdCanvasForeground(colordlg_data->color_cddbuffer, colordlg_data->previous_color); + cdCanvasBox(colordlg_data->color_cddbuffer, 0, width/2, 0, height); + + cdCanvasForeground(colordlg_data->color_cddbuffer, colordlg_data->color); + cdCanvasBox(colordlg_data->color_cddbuffer, width/2+1, width, 0, height); + + cdCanvasFlush(colordlg_data->color_cddbuffer); +} + +static void iColorBrowserDlgHSI2RGB(IcolorDlgData* colordlg_data) +{ + iupColorHSI2RGB(colordlg_data->hue, colordlg_data->saturation, colordlg_data->intensity, + &colordlg_data->red, &colordlg_data->green, &colordlg_data->blue); +} + +static void iColorBrowserDlgRGB2HSI(IcolorDlgData* colordlg_data) +{ + iupColorRGB2HSI(colordlg_data->red, colordlg_data->green, colordlg_data->blue, + &(colordlg_data->hue), &(colordlg_data->saturation), &(colordlg_data->intensity)); +} + +static void iColorBrowserDlgHex_TXT_Update(IcolorDlgData* colordlg_data) +{ + IupSetfAttribute(colordlg_data->colorhex_txt, "VALUE", "#%02X%02X%02X", (int)colordlg_data->red, (int)colordlg_data->green, (int)colordlg_data->blue); +} + +static int iupStrHexToRGB(const char *str, unsigned char *r, unsigned char *g, unsigned char *b) +{ + unsigned int ri = 0, gi = 0, bi = 0; + if (!str) return 0; + if (sscanf(str, "#%2X%2X%2X", &ri, &gi, &bi) != 3) return 0; + if (ri > 255 || gi > 255 || bi > 255) return 0; + *r = (unsigned char)ri; + *g = (unsigned char)gi; + *b = (unsigned char)bi; + return 1; +} + +/*************************************************\ +* Updates text fields with the current HSI values * +\*************************************************/ +static void iColorBrowserDlgHSI_TXT_Update(IcolorDlgData* colordlg_data) +{ + IupSetfAttribute(colordlg_data->hue_txt, "VALUE", "%d", iupROUND(colordlg_data->hue)); + IupSetfAttribute(colordlg_data->saturation_txt, "VALUE", "%d", iupROUND(colordlg_data->saturation * 100)); + IupSetfAttribute(colordlg_data->intensity_txt, "VALUE", "%d", iupROUND(colordlg_data->intensity * 100)); +} + +/*************************************************\ +* Updates text fields with the current RGB values * +\*************************************************/ +static void iColorBrowserDlgRGB_TXT_Update(IcolorDlgData* colordlg_data) +{ + IupSetfAttribute(colordlg_data->red_txt, "VALUE", "%d", (int) colordlg_data->red); + IupSetfAttribute(colordlg_data->green_txt, "VALUE", "%d", (int) colordlg_data->green); + IupSetfAttribute(colordlg_data->blue_txt, "VALUE", "%d", (int) colordlg_data->blue); +} + +static void iColorBrowserDlgBrowserRGB_Update(IcolorDlgData* colordlg_data) +{ + IupSetfAttribute(colordlg_data->color_browser, "RGB", "%d %d %d", colordlg_data->red, colordlg_data->green, colordlg_data->blue); +} + +static void iColorBrowserDlgBrowserHSI_Update(IcolorDlgData* colordlg_data) +{ + IupSetfAttribute(colordlg_data->color_browser, "HSI", "%f %f %f", (double)colordlg_data->hue, (double)colordlg_data->saturation, (double)colordlg_data->intensity); +} + +/*****************************************\ +* Sets the RGB color in the Color Canvas * +\*****************************************/ +static void iColorBrowserDlgColor_Update(IcolorDlgData* colordlg_data) +{ + colordlg_data->color = cdEncodeColor(colordlg_data->red, colordlg_data->green, colordlg_data->blue); + colordlg_data->color = cdEncodeAlpha(colordlg_data->color, colordlg_data->alpha); + iColorBrowserDlgColorCnvRepaint(colordlg_data); +} + +static void iColorBrowserDlgHSIChanged(IcolorDlgData* colordlg_data) +{ + iColorBrowserDlgHSI2RGB(colordlg_data); + iColorBrowserDlgBrowserHSI_Update(colordlg_data); + iColorBrowserDlgHex_TXT_Update(colordlg_data); + iColorBrowserDlgRGB_TXT_Update(colordlg_data); + iColorBrowserDlgColor_Update(colordlg_data); +} + +static void iColorBrowserDlgRGBChanged(IcolorDlgData* colordlg_data) +{ + iColorBrowserDlgRGB2HSI(colordlg_data); + iColorBrowserDlgBrowserRGB_Update(colordlg_data); + iColorBrowserDlgHex_TXT_Update(colordlg_data); + iColorBrowserDlgHSI_TXT_Update(colordlg_data); + iColorBrowserDlgColor_Update(colordlg_data); +} + +/***********************************************\ +* Initializes the default values to the element * +\***********************************************/ +static void iColorBrowserDlgInit_Defaults(IcolorDlgData* colordlg_data) +{ + char* str = iupStrGetMemory(100); + Ihandle* box; + int i; + + IupSetAttribute(colordlg_data->color_browser, "RGB", "0 0 0"); + + IupSetAttribute(colordlg_data->red_txt, "VALUE", "0"); + IupSetAttribute(colordlg_data->green_txt, "VALUE", "0"); + IupSetAttribute(colordlg_data->blue_txt, "VALUE", "0"); + + IupSetAttribute(colordlg_data->hue_txt, "VALUE", "0"); + IupSetAttribute(colordlg_data->saturation_txt, "VALUE", "0"); + IupSetAttribute(colordlg_data->intensity_txt, "VALUE", "0"); + + IupSetAttribute(colordlg_data->colorhex_txt, "VALUE", "#000000"); + + colordlg_data->alpha = 255; + IupSetAttribute(colordlg_data->alpha_val, "VALUE", "255"); + IupSetAttribute(colordlg_data->alpha_txt, "VALUE", "255"); + + box = IupGetParent(colordlg_data->alpha_val); + IupSetAttribute(box, "FLOATING", "YES"); + IupSetAttribute(box, "VISIBLE", "NO"); + + box = IupGetParent(colordlg_data->colortable_cbar); + IupSetAttribute(box, "FLOATING", "YES"); + IupSetAttribute(box, "VISIBLE", "NO"); + + box = IupGetParent(colordlg_data->colorhex_txt); + IupSetAttribute(box, "FLOATING", "YES"); + IupSetAttribute(box, "VISIBLE", "NO"); + + for(i = 0; i < 20; i++) + { + sprintf(str, "CELL%d", i); + IupSetAttribute(colordlg_data->colortable_cbar, str, default_colortable_cells[i]); + } +} + + +/**************************************************************************************************************/ +/* Internal Callbacks */ +/**************************************************************************************************************/ + + +static int iColorBrowserDlgButtonOK_CB(Ihandle* ih) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + colordlg_data->status = 1; + return IUP_CLOSE; +} + +static int iColorBrowserDlgButtonCancel_CB(Ihandle* ih) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + colordlg_data->status = 0; + return IUP_CLOSE; +} + +static int iColorBrowserDlgButtonHelp_CB(Ihandle* ih) +{ + Icallback cb = IupGetCallback(IupGetDialog(ih), "HELP_CB"); + if (cb && cb(ih) == IUP_CLOSE) + { + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + colordlg_data->status = 0; + return IUP_CLOSE; + } + return IUP_DEFAULT; +} + +static int iColorBrowserDlgColorCnvRedraw_CB(Ihandle* ih) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + if (!colordlg_data->color_cddbuffer) + return IUP_DEFAULT; + + cdCanvasActivate(colordlg_data->color_cddbuffer); + + iColorBrowserDlgColorCnvRepaint(colordlg_data); + + return IUP_DEFAULT; +} + +static int iColorBrowserDlgRedAction_CB(Ihandle* ih, int c, char *value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + int vi; + + if (iupStrToInt(value, &vi)) + { + colordlg_data->red = (unsigned char)vi; + iColorBrowserDlgRGBChanged(colordlg_data); + } + + (void)c; + return IUP_DEFAULT; +} + +static int iColorBrowserDlgRedSpin_CB(Ihandle* ih, int vi) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + colordlg_data->red = (unsigned char)vi; + iColorBrowserDlgRGBChanged(colordlg_data); + + return IUP_DEFAULT; +} + +static int iColorBrowserDlgGreenAction_CB(Ihandle* ih, int c, char *value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + int vi; + + if (iupStrToInt(value, &vi)) + { + colordlg_data->green = (unsigned char)vi; + iColorBrowserDlgRGBChanged(colordlg_data); + } + + (void)c; + return IUP_DEFAULT; +} + +static int iColorBrowserDlgGreenSpin_CB(Ihandle* ih, int vi) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + colordlg_data->green = (unsigned char)vi; + iColorBrowserDlgRGBChanged(colordlg_data); + + return IUP_DEFAULT; +} + +static int iColorBrowserDlgBlueAction_CB(Ihandle* ih, int c, char *value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + int vi; + + if (iupStrToInt(value, &vi)) + { + colordlg_data->blue = (unsigned char)vi; + iColorBrowserDlgRGBChanged(colordlg_data); + } + + (void)c; + return IUP_DEFAULT; +} + +static int iColorBrowserDlgBlueSpin_CB(Ihandle* ih, int vi) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + colordlg_data->blue = (unsigned char)vi; + iColorBrowserDlgRGBChanged(colordlg_data); + + return IUP_DEFAULT; +} + +static int iColorBrowserDlgHueAction_CB(Ihandle* ih, int c, char *value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + int vi; + + if (iupStrToInt(value, &vi)) + { + colordlg_data->hue = (float)vi; + iColorBrowserDlgHSIChanged(colordlg_data); + } + + (void)c; + return IUP_DEFAULT; +} + +static int iColorBrowserDlgHueSpin_CB(Ihandle* ih, int vi) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + colordlg_data->hue = (float)vi; + iColorBrowserDlgHSIChanged(colordlg_data); + + return IUP_DEFAULT; +} + +static int iColorBrowserDlgSaturationAction_CB(Ihandle* ih, int c, char *value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + int vi; + + if (iupStrToInt(value, &vi)) + { + colordlg_data->saturation = (float)vi/100.0f; + iColorBrowserDlgHSIChanged(colordlg_data); + } + + (void)c; + return IUP_DEFAULT; +} + +static int iColorBrowserDlgSaturationSpin_CB(Ihandle* ih, int vi) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + colordlg_data->saturation = (float)vi/100.0f; + iColorBrowserDlgHSIChanged(colordlg_data); + + return IUP_DEFAULT; +} + +static int iColorBrowserDlgIntensityAction_CB(Ihandle* ih, int c, char *value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + int vi; + + if (iupStrToInt(value, &vi)) + { + colordlg_data->intensity = (float)vi/100.0f; + iColorBrowserDlgHSIChanged(colordlg_data); + } + + (void)c; + return IUP_DEFAULT; +} + +static int iColorBrowserDlgIntensitySpin_CB(Ihandle* ih, int vi) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + colordlg_data->intensity = (float)vi/100.0f; + iColorBrowserDlgHSIChanged(colordlg_data); + + return IUP_DEFAULT; +} + +static int iColorBrowserDlgHexAction_CB(Ihandle* ih, int c, char* value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + if (iupStrHexToRGB(value, &colordlg_data->red, &colordlg_data->green, &colordlg_data->blue)) + { + iColorBrowserDlgRGB2HSI(colordlg_data); + iColorBrowserDlgBrowserRGB_Update(colordlg_data); + iColorBrowserDlgHSI_TXT_Update(colordlg_data); + iColorBrowserDlgRGB_TXT_Update(colordlg_data); + iColorBrowserDlgColor_Update(colordlg_data); + } + + (void)c; + return IUP_DEFAULT; +} + +static int iColorBrowserDlgColorSelDrag_CB(Ihandle* ih, unsigned char r, unsigned char g, unsigned char b) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + colordlg_data->red = r; + colordlg_data->green = g; + colordlg_data->blue = b; + + iColorBrowserDlgRGB2HSI(colordlg_data); + iColorBrowserDlgHex_TXT_Update(colordlg_data); + iColorBrowserDlgHSI_TXT_Update(colordlg_data); + iColorBrowserDlgRGB_TXT_Update(colordlg_data); + + colordlg_data->color = cdEncodeColor(colordlg_data->red,colordlg_data->green,colordlg_data->blue); + colordlg_data->color = cdEncodeAlpha(colordlg_data->color, colordlg_data->alpha); + iColorBrowserDlgColorCnvRepaint(colordlg_data); + + return IUP_DEFAULT; +} + +static int iColorBrowserDlgAlphaVal_CB(Ihandle* ih, double val) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + colordlg_data->alpha = (unsigned char)val; + IupSetfAttribute(colordlg_data->alpha_txt, "VALUE", "%d", (int)colordlg_data->alpha); + + colordlg_data->color = cdEncodeAlpha(colordlg_data->color, colordlg_data->alpha); + iColorBrowserDlgColorCnvRepaint(colordlg_data); + + return IUP_DEFAULT; +} + +static int iColorBrowserDlgAlphaAction_CB(Ihandle* ih, int c, char* value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + int vi; + + if (iupStrToInt(value, &vi)) + { + colordlg_data->alpha = (unsigned char)vi; + IupSetfAttribute(colordlg_data->alpha_val, "VALUE", "%d", (int)colordlg_data->alpha); + + colordlg_data->color = cdEncodeAlpha(colordlg_data->color, colordlg_data->alpha); + iColorBrowserDlgColorCnvRepaint(colordlg_data); + } + + (void)c; + return IUP_DEFAULT; +} + +static int iColorBrowserDlgAlphaSpin_CB(Ihandle* ih, int vi) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + colordlg_data->alpha = (unsigned char)vi; + IupSetfAttribute(colordlg_data->alpha_val, "VALUE", "%d", (int)colordlg_data->alpha); + + colordlg_data->color = cdEncodeAlpha(colordlg_data->color, colordlg_data->alpha); + iColorBrowserDlgColorCnvRepaint(colordlg_data); + + return IUP_DEFAULT; +} + +static int iColorBrowserDlgColorTableSelect_CB(Ihandle* ih, int cell, int type) +{ + char* str = iupStrGetMemory(30); + + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + sprintf(str, "CELL%d", cell); + iupStrToRGB(IupGetAttribute(ih, str), &colordlg_data->red, &colordlg_data->green, &colordlg_data->blue); + + iColorBrowserDlgRGB_TXT_Update(colordlg_data); + iColorBrowserDlgRGBChanged(colordlg_data); + + (void)type; + return IUP_DEFAULT; +} + +static int iColorBrowserDlgColorCnvButton_CB(Ihandle* ih, int b, int press, int x, int y) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + int width; + (void)y; + + if (b != IUP_BUTTON1 || !press || !colordlg_data->color_cddbuffer) + return IUP_DEFAULT; + + cdCanvasGetSize(colordlg_data->color_cddbuffer, &width, NULL, NULL, NULL); + + if (x < width/2) + { + /* reset color to previous */ + colordlg_data->red = cdRed(colordlg_data->previous_color); + colordlg_data->green = cdGreen(colordlg_data->previous_color); + colordlg_data->blue = cdBlue(colordlg_data->previous_color); + colordlg_data->alpha = cdAlpha(colordlg_data->previous_color); + + IupSetfAttribute(colordlg_data->alpha_txt, "VALUE", "%d", (int)colordlg_data->alpha); + IupSetfAttribute(colordlg_data->alpha_val, "VALUE", "%d", (int)colordlg_data->alpha); + + iColorBrowserDlgRGB_TXT_Update(colordlg_data); + iColorBrowserDlgRGBChanged(colordlg_data); + } + + return IUP_DEFAULT; +} + +static int iColorBrowserDlgColorCnvMap_CB(Ihandle* ih) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + /* Create Canvas */ + colordlg_data->color_cdcanvas = cdCreateCanvas(CD_IUP, colordlg_data->color_cnv); + + if (!colordlg_data->color_cdcanvas) + return IUP_DEFAULT; + + /* this can fail if canvas size is zero */ + colordlg_data->color_cddbuffer = cdCreateCanvas(CD_DBUFFERRGB, colordlg_data->color_cdcanvas); + return IUP_DEFAULT; +} + +static int iColorBrowserDlgColorCnvUnMap_CB(Ihandle* ih) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + if (colordlg_data->color_cddbuffer) + cdKillCanvas(colordlg_data->color_cddbuffer); + + if (colordlg_data->color_cdcanvas) + cdKillCanvas(colordlg_data->color_cdcanvas); + + return IUP_DEFAULT; +} + + +/**************************************************************************************************************/ +/* Attributes */ +/**************************************************************************************************************/ + + +static char* iColorBrowserDlgGetStatusAttrib(Ihandle* ih) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + if (colordlg_data->status) + return "1"; + else + return NULL; +} + +static int iColorBrowserDlgSetShowHelpAttrib(Ihandle* ih, const char* value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + IupSetAttribute(colordlg_data->help_bt, "VISIBLE", iupStrBoolean(value)? "YES": "NO"); + return 1; +} + +static int iColorBrowserDlgSetShowHexAttrib(Ihandle* ih, const char* value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + /* valid only before map */ + if (ih->handle) + return 1; + + if (iupStrBoolean(value)) + { + Ihandle* box = IupGetParent(colordlg_data->colorhex_txt); + IupSetAttribute(box, "FLOATING", NULL); + IupSetAttribute(box, "VISIBLE", "YES"); + } + + return 1; +} + +static int iColorBrowserDlgSetShowColorTableAttrib(Ihandle* ih, const char* value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + /* valid only before map */ + if (ih->handle) + return 1; + + if (iupStrBoolean(value)) + { + Ihandle* box = IupGetParent(colordlg_data->colortable_cbar); + IupSetAttribute(box, "FLOATING", NULL); + IupSetAttribute(box, "VISIBLE", "YES"); + } + + return 1; +} + +static int iColorBrowserDlgSetShowAlphaAttrib(Ihandle* ih, const char* value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + /* valid only before map */ + if (ih->handle) + return 1; + + if (iupStrBoolean(value)) + { + Ihandle* box = IupGetParent(colordlg_data->alpha_val); + IupSetAttribute(box, "FLOATING", NULL); + IupSetAttribute(box, "VISIBLE", "YES"); + } + + return 1; +} + +static int iColorBrowserDlgSetAlphaAttrib(Ihandle* ih, const char* value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + int alpha; + if (iupStrToInt(value, &alpha)) + { + colordlg_data->alpha = (unsigned char)alpha; + IupSetfAttribute(colordlg_data->alpha_txt, "VALUE", "%d", (int)colordlg_data->alpha); + IupSetfAttribute(colordlg_data->alpha_val, "VALUE", "%d", (int)colordlg_data->alpha); + + colordlg_data->color = cdEncodeAlpha(colordlg_data->color, colordlg_data->alpha); + colordlg_data->previous_color = cdEncodeAlpha(colordlg_data->previous_color, colordlg_data->alpha); + iColorBrowserDlgColorCnvRepaint(colordlg_data); + + if (!ih->handle) /* do it only before map */ + IupSetAttribute(ih, "SHOWALPHA", "YES"); + } + + return 1; +} + +static char* iColorBrowserDlgGetAlphaAttrib(Ihandle* ih) +{ + char* buffer = iupStrGetMemory(100); + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + sprintf(buffer, "%d", (int)colordlg_data->alpha); + return buffer; +} + +static int iColorBrowserDlgSetValueAttrib(Ihandle* ih, const char* value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + int ret = iupStrToRGBA(value, &colordlg_data->red, &colordlg_data->green, &colordlg_data->blue, &colordlg_data->alpha); + if (!ret) + return 0; + + colordlg_data->previous_color = cdEncodeColor(colordlg_data->red, colordlg_data->green, colordlg_data->blue); + colordlg_data->previous_color = cdEncodeAlpha(colordlg_data->previous_color, colordlg_data->alpha); + + if (ret == 4) + { + IupSetfAttribute(colordlg_data->alpha_txt, "VALUE", "%d", (int)colordlg_data->alpha); + IupSetfAttribute(colordlg_data->alpha_val, "VALUE", "%d", (int)colordlg_data->alpha); + + if (!ih->handle) /* do it only before map */ + IupSetAttribute(ih, "SHOWALPHA", "YES"); + } + + iColorBrowserDlgRGB_TXT_Update(colordlg_data); + iColorBrowserDlgRGBChanged(colordlg_data); + + return 0; +} + +static char* iColorBrowserDlgGetValueAttrib(Ihandle* ih) +{ + char* buffer = iupStrGetMemory(100); + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + if (iupAttribGetBoolean(ih, "SHOWALPHA")) + sprintf(buffer, "%d %d %d %d", (int)colordlg_data->red, (int)colordlg_data->green, (int)colordlg_data->blue, (int)colordlg_data->alpha); + else + sprintf(buffer, "%d %d %d", (int)colordlg_data->red, (int)colordlg_data->green, (int)colordlg_data->blue); + return buffer; +} + +static int iupStrToHSI_Int(const char *str, int *h, int *s, int *i) +{ + int fh, fs, fi; + if (!str) return 0; + if (sscanf(str, "%d %d %d", &fh, &fs, &fi) != 3) return 0; + if (fh > 359 || fs > 100 || fi > 100) return 0; + if (fh < 0 || fs < 0 || fi < 0) return 0; + *h = fh; + *s = fs; + *i = fi; + return 1; +} + +static int iColorBrowserDlgSetValueHSIAttrib(Ihandle* ih, const char* value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + int hue, saturation, intensity; + + if (!iupStrToHSI_Int(value, &hue, &saturation, &intensity)) + return 0; + + colordlg_data->hue = (float)hue; + colordlg_data->saturation = (float)saturation/100.0f; + colordlg_data->intensity = (float)intensity/100.0f; + + iColorBrowserDlgHSI2RGB(colordlg_data); + colordlg_data->previous_color = cdEncodeColor(colordlg_data->red, colordlg_data->green, colordlg_data->blue); + colordlg_data->previous_color = cdEncodeAlpha(colordlg_data->previous_color, colordlg_data->alpha); + + iColorBrowserDlgHSIChanged(colordlg_data); + return 0; +} + +static char* iColorBrowserDlgGetValueHSIAttrib(Ihandle* ih) +{ + char* buffer = iupStrGetMemory(100); + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + sprintf(buffer, "%d %d %d", (int)colordlg_data->hue, (int)(colordlg_data->saturation*100), (int)(colordlg_data->intensity*100)); + return buffer; +} + +static int iColorBrowserDlgSetValueHexAttrib(Ihandle* ih, const char* value) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + if (!iupStrHexToRGB(value, &colordlg_data->red, &colordlg_data->green, &colordlg_data->blue)) + return 0; + + colordlg_data->previous_color = cdEncodeColor(colordlg_data->red, colordlg_data->green, colordlg_data->blue); + colordlg_data->previous_color = cdEncodeAlpha(colordlg_data->previous_color, colordlg_data->alpha); + + iColorBrowserDlgRGB2HSI(colordlg_data); + iColorBrowserDlgBrowserRGB_Update(colordlg_data); + iColorBrowserDlgHSI_TXT_Update(colordlg_data); + iColorBrowserDlgRGB_TXT_Update(colordlg_data); + iColorBrowserDlgColor_Update(colordlg_data); + return 0; +} + +static char* iColorBrowserDlgGetValueHexAttrib(Ihandle* ih) +{ + char* buffer = iupStrGetMemory(100); + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + sprintf(buffer, "#%02X%02X%02X", (int)colordlg_data->red, (int)colordlg_data->green, (int)colordlg_data->blue); + return buffer; +} + +static char* iColorBrowserDlgGetColorTableAttrib(Ihandle* ih) +{ + int i, inc, off = 0; + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + char* color_str, attrib_str[30]; + char* str = iupStrGetMemory(300); + for (i=0; i < 20; i++) + { + sprintf(attrib_str, "CELL%d", i); + color_str = IupGetAttribute(colordlg_data->colortable_cbar, attrib_str); + inc = strlen(color_str); + memcpy(str+off, color_str, inc); + memcpy(str+off+inc, ";", 1); + off += inc+1; + } + str[off-1] = 0; /* remove last separator */ + return str; +} + +static int iColorBrowserDlgSetColorTableAttrib(Ihandle* ih, const char* value) +{ + int i = 0; + unsigned char r, g, b; + char str[30]; + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + + if (!ih->handle) /* do it only before map */ + iColorBrowserDlgSetShowColorTableAttrib(ih, "YES"); + + while (value && *value && i < 20) + { + if (iupStrToRGB(value, &r, &g, &b)) + { + sprintf(str, "CELL%d", i); + IupSetfAttribute(colordlg_data->colortable_cbar, str, "%d %d %d", (int)r, (int)g, (int)b); + } + + value = strchr(value, ';'); + if (value) value++; + i++; + } + + return 1; +} + + +/**************************************************************************************************************/ +/* Methods */ +/**************************************************************************************************************/ + +static int iColorBrowserDlgMapMethod(Ihandle* ih) +{ + if (!IupGetCallback(ih, "HELP_CB")) + { + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + IupSetAttribute(colordlg_data->help_bt, "VISIBLE", "NO"); + } + + return IUP_NOERROR; +} + +static void iColorBrowserDlgDestroyMethod(Ihandle* ih) +{ + IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA"); + free(colordlg_data); +} + +static int iColorBrowserDlgCreateMethod(Ihandle* ih, void** params) +{ + Ihandle *ok_bt, *cancel_bt; + Ihandle *rgb_vb, *hsi_vb, *clr_vb; + Ihandle *lin1, *lin2, *col1, *col2; + + IcolorDlgData* colordlg_data = (IcolorDlgData*)malloc(sizeof(IcolorDlgData)); + memset(colordlg_data, 0, sizeof(IcolorDlgData)); + iupAttribSetStr(ih, "_IUP_GC_DATA", (char*)colordlg_data); + + /* ======================================================================= */ + /* BUTTONS ============================================================= */ + /* ======================================================================= */ + ok_bt = IupButton("OK", NULL); /* Ok Button */ + IupSetAttribute(ok_bt, "PADDING", "20x0"); + IupSetCallback (ok_bt, "ACTION", (Icallback)iColorBrowserDlgButtonOK_CB); + IupSetAttributeHandle(ih, "DEFAULTENTER", ok_bt); + + cancel_bt = IupButton(iupStrMessageGet("IUP_CANCEL"), NULL); /* Cancel Button */ + IupSetAttribute(cancel_bt, "PADDING", "20x0"); + IupSetCallback (cancel_bt, "ACTION", (Icallback)iColorBrowserDlgButtonCancel_CB); + IupSetAttributeHandle(ih, "DEFAULTESC", cancel_bt); + + colordlg_data->help_bt = IupButton(iupStrMessageGet("IUP_HELP"), NULL); /* Help Button */ + IupSetAttribute(colordlg_data->help_bt, "PADDING", "20x0"); + IupSetCallback (colordlg_data->help_bt, "ACTION", (Icallback)iColorBrowserDlgButtonHelp_CB); + + /* ======================================================================= */ + /* COLOR =============================================================== */ + /* ======================================================================= */ + colordlg_data->color_browser = IupColorBrowser(); + IupSetAttribute(colordlg_data->color_browser, "EXPAND", "YES"); + IupSetCallback(colordlg_data->color_browser, "DRAG_CB", (Icallback)iColorBrowserDlgColorSelDrag_CB); + IupSetCallback(colordlg_data->color_browser, "CHANGE_CB", (Icallback)iColorBrowserDlgColorSelDrag_CB); + + colordlg_data->color_cnv = IupCanvas(NULL); /* Canvas of the color */ + IupSetAttribute(colordlg_data->color_cnv, "SIZE", "x12"); + IupSetAttribute(colordlg_data->color_cnv, "CANFOCUS", "NO"); + IupSetAttribute(colordlg_data->color_cnv, "EXPAND", "HORIZONTAL"); + IupSetCallback (colordlg_data->color_cnv, "ACTION", (Icallback)iColorBrowserDlgColorCnvRedraw_CB); + IupSetCallback (colordlg_data->color_cnv, "MAP_CB", (Icallback)iColorBrowserDlgColorCnvMap_CB); + IupSetCallback (colordlg_data->color_cnv, "UNMAP_CB", (Icallback)iColorBrowserDlgColorCnvUnMap_CB); + IupSetCallback (colordlg_data->color_cnv, "BUTTON_CB", (Icallback)iColorBrowserDlgColorCnvButton_CB); + + colordlg_data->colorhex_txt = IupText(NULL); /* Hex of the color */ + IupSetAttribute(colordlg_data->colorhex_txt, "VISIBLECOLUMNS", "7"); + IupSetCallback (colordlg_data->colorhex_txt, "ACTION", (Icallback)iColorBrowserDlgHexAction_CB); + IupSetAttribute(colordlg_data->colorhex_txt, "MASK", "#[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]"); + + /* ======================================================================= */ + /* ALPHA TRANSPARENCY ================================================== */ + /* ======================================================================= */ + colordlg_data->alpha_val = IupVal("HORIZONTAL"); + IupSetAttribute(colordlg_data->alpha_val, "EXPAND", "HORIZONTAL"); + IupSetAttribute(colordlg_data->alpha_val, "MIN", "0"); + IupSetAttribute(colordlg_data->alpha_val, "MAX", "255"); + IupSetAttribute(colordlg_data->alpha_val, "VALUE", "255"); + IupSetAttribute(colordlg_data->alpha_val, "SIZE", "80x12"); + IupSetCallback (colordlg_data->alpha_val, "MOUSEMOVE_CB", (Icallback)iColorBrowserDlgAlphaVal_CB); + IupSetCallback (colordlg_data->alpha_val, "BUTTON_PRESS_CB", (Icallback)iColorBrowserDlgAlphaVal_CB); + IupSetCallback (colordlg_data->alpha_val, "BUTTON_RELEASE_CB", (Icallback)iColorBrowserDlgAlphaVal_CB); + + colordlg_data->alpha_txt = IupText(NULL); /* Alpha value */ + IupSetAttribute(colordlg_data->alpha_txt, "VISIBLECOLUMNS", "3"); + IupSetAttribute(colordlg_data->alpha_txt, "SPIN", "YES"); + IupSetAttribute(colordlg_data->alpha_txt, "SPINMIN", "0"); + IupSetAttribute(colordlg_data->alpha_txt, "SPINMAX", "255"); + IupSetAttribute(colordlg_data->alpha_txt, "SPININC", "1"); + IupSetCallback (colordlg_data->alpha_txt, "ACTION", (Icallback)iColorBrowserDlgAlphaAction_CB); + IupSetCallback (colordlg_data->alpha_txt, "SPIN_CB", (Icallback)iColorBrowserDlgAlphaSpin_CB); + IupSetAttribute(colordlg_data->alpha_txt, "MASKINT", "0:255"); + + /* ======================================================================= */ + /* COLOR TABLE ========================================================= */ + /* ======================================================================= */ + colordlg_data->colortable_cbar = IupColorbar(); + IupSetAttribute(colordlg_data->colortable_cbar, "ORIENTATION", "HORIZONTAL"); + IupSetAttribute(colordlg_data->colortable_cbar, "NUM_PARTS", "2"); + IupSetAttribute(colordlg_data->colortable_cbar, "NUM_CELLS", "20"); + IupSetAttribute(colordlg_data->colortable_cbar, "SHOW_PREVIEW", "NO"); + IupSetAttribute(colordlg_data->colortable_cbar, "SIZE", "138x22"); + IupSetAttribute(colordlg_data->colortable_cbar, "SQUARED", "NO"); + IupSetCallback (colordlg_data->colortable_cbar, "SELECT_CB", (Icallback)iColorBrowserDlgColorTableSelect_CB); + + /* ======================================================================= */ + /* RGB TEXT FIELDS ===================================================== */ + /* ======================================================================= */ + colordlg_data->red_txt = IupText(NULL); /* Red value */ + IupSetAttribute(colordlg_data->red_txt, "VISIBLECOLUMNS", "3"); + IupSetAttribute(colordlg_data->red_txt, "SPIN", "YES"); + IupSetAttribute(colordlg_data->red_txt, "SPINMIN", "0"); + IupSetAttribute(colordlg_data->red_txt, "SPINMAX", "255"); + IupSetAttribute(colordlg_data->red_txt, "SPININC", "1"); + IupSetCallback (colordlg_data->red_txt, "ACTION", (Icallback)iColorBrowserDlgRedAction_CB); + IupSetCallback (colordlg_data->red_txt, "SPIN_CB", (Icallback)iColorBrowserDlgRedSpin_CB); + IupSetAttribute(colordlg_data->red_txt, "MASKINT", "0:255"); + + colordlg_data->green_txt = IupText(NULL); /* Green value */ + IupSetAttribute(colordlg_data->green_txt, "VISIBLECOLUMNS", "3"); + IupSetAttribute(colordlg_data->green_txt, "SPIN", "YES"); + IupSetAttribute(colordlg_data->green_txt, "SPINMIN", "0"); + IupSetAttribute(colordlg_data->green_txt, "SPINMAX", "255"); + IupSetAttribute(colordlg_data->green_txt, "SPININC", "1"); + IupSetCallback (colordlg_data->green_txt, "ACTION", (Icallback)iColorBrowserDlgGreenAction_CB); + IupSetCallback (colordlg_data->green_txt, "SPIN_CB", (Icallback)iColorBrowserDlgGreenSpin_CB); + IupSetAttribute(colordlg_data->green_txt, "MASKINT", "0:255"); + + colordlg_data->blue_txt = IupText(NULL); /* Blue value */ + IupSetAttribute(colordlg_data->blue_txt, "VISIBLECOLUMNS", "3"); + IupSetAttribute(colordlg_data->blue_txt, "SPIN", "YES"); + IupSetAttribute(colordlg_data->blue_txt, "SPINMIN", "0"); + IupSetAttribute(colordlg_data->blue_txt, "SPINMAX", "255"); + IupSetAttribute(colordlg_data->blue_txt, "SPININC", "1"); + IupSetCallback (colordlg_data->blue_txt, "ACTION", (Icallback)iColorBrowserDlgBlueAction_CB); + IupSetCallback (colordlg_data->blue_txt, "SPIN_CB", (Icallback)iColorBrowserDlgBlueSpin_CB); + IupSetAttribute(colordlg_data->blue_txt, "MASKINT", "0:255"); + + /* ======================================================================= */ + /* HSI TEXT FIELDS ===================================================== */ + /* ======================================================================= */ + colordlg_data->hue_txt = IupText(NULL); /* Hue value */ + IupSetAttribute(colordlg_data->hue_txt, "VISIBLECOLUMNS", "3"); + IupSetAttribute(colordlg_data->hue_txt, "SPIN", "YES"); + IupSetAttribute(colordlg_data->hue_txt, "SPINMIN", "0"); + IupSetAttribute(colordlg_data->hue_txt, "SPINMAX", "359"); + IupSetAttribute(colordlg_data->hue_txt, "SPINWRAP", "YES"); + IupSetAttribute(colordlg_data->hue_txt, "SPININC", "1"); + IupSetCallback(colordlg_data->hue_txt, "ACTION", (Icallback)iColorBrowserDlgHueAction_CB); + IupSetCallback(colordlg_data->hue_txt, "SPIN_CB", (Icallback)iColorBrowserDlgHueSpin_CB); + IupSetAttribute(colordlg_data->hue_txt, "MASKINT", "0:359"); + + colordlg_data->saturation_txt = IupText(NULL); /* Saturation value */ + IupSetAttribute(colordlg_data->saturation_txt, "VISIBLECOLUMNS", "3"); + IupSetAttribute(colordlg_data->saturation_txt, "SPIN", "YES"); + IupSetAttribute(colordlg_data->saturation_txt, "SPINMIN", "0"); + IupSetAttribute(colordlg_data->saturation_txt, "SPINMAX", "100"); + IupSetAttribute(colordlg_data->saturation_txt, "SPININC", "1"); + IupSetCallback(colordlg_data->saturation_txt, "ACTION", (Icallback)iColorBrowserDlgSaturationAction_CB); + IupSetCallback(colordlg_data->saturation_txt, "SPIN_CB", (Icallback)iColorBrowserDlgSaturationSpin_CB); + IupSetAttribute(colordlg_data->saturation_txt, "MASKINT", "0:100"); + + colordlg_data->intensity_txt = IupText(NULL); /* Intensity value */ + IupSetAttribute(colordlg_data->intensity_txt, "VISIBLECOLUMNS", "3"); + IupSetAttribute(colordlg_data->intensity_txt, "SPIN", "YES"); + IupSetAttribute(colordlg_data->intensity_txt, "SPINMIN", "0"); + IupSetAttribute(colordlg_data->intensity_txt, "SPINMAX", "100"); + IupSetAttribute(colordlg_data->intensity_txt, "SPININC", "1"); + IupSetCallback(colordlg_data->intensity_txt, "ACTION", (Icallback)iColorBrowserDlgIntensityAction_CB); + IupSetCallback(colordlg_data->intensity_txt, "SPIN_CB", (Icallback)iColorBrowserDlgIntensitySpin_CB); + IupSetAttribute(colordlg_data->intensity_txt, "MASKINT", "0:100"); + + /* =================== */ + /* 1st line = Controls */ + /* =================== */ + + col1 = IupVbox(colordlg_data->color_browser, IupSetAttributes(IupHbox(colordlg_data->color_cnv, NULL), "MARGIN=30x0"),NULL); + + hsi_vb = IupVbox(IupSetAttributes(IupHbox(IupLabel(iupStrMessageGet("IUP_HUE")), + colordlg_data->hue_txt, + NULL), "ALIGNMENT=ACENTER"), + IupSetAttributes(IupHbox(IupLabel(iupStrMessageGet("IUP_SATURATION")), + colordlg_data->saturation_txt, + NULL), "ALIGNMENT=ACENTER"), + IupSetAttributes(IupHbox(IupLabel(iupStrMessageGet("IUP_INTENSITY")), + colordlg_data->intensity_txt, + NULL), "ALIGNMENT=ACENTER"), + NULL); + IupSetAttribute(hsi_vb, "GAP", "5"); + + rgb_vb = IupVbox(IupSetAttributes(IupHbox(IupLabel(iupStrMessageGet("IUP_RED")), + colordlg_data->red_txt, + NULL), "ALIGNMENT=ACENTER"), + IupSetAttributes(IupHbox(IupLabel(iupStrMessageGet("IUP_GREEN")), + colordlg_data->green_txt, + NULL), "ALIGNMENT=ACENTER"), + IupSetAttributes(IupHbox(IupLabel(iupStrMessageGet("IUP_BLUE")), + colordlg_data->blue_txt, + NULL), "ALIGNMENT=ACENTER"), + NULL); + IupSetAttribute(rgb_vb, "GAP", "5"); + + clr_vb = IupVbox(IupSetAttributes(IupHbox(IupLabel(iupStrMessageGet("IUP_OPACITY")), + colordlg_data->alpha_txt, colordlg_data->alpha_val, + NULL), "ALIGNMENT=ACENTER"), + IupSetAttributes(IupHbox(IupLabel("He&xa:"), + colordlg_data->colorhex_txt, + NULL), "ALIGNMENT=ACENTER"), + IupSetAttributes(IupVbox(IupLabel(iupStrMessageGet("IUP_PALETTE")), + colordlg_data->colortable_cbar, + NULL), "GAP=3"), + NULL); + IupSetAttribute(clr_vb, "GAP", "5"); + IupSetAttribute(clr_vb, "EXPAND", "YES"); + + IupDestroy(IupSetAttributes(IupNormalizer(IupGetChild(IupGetChild(hsi_vb, 0), 0), /* Hue Label */ + IupGetChild(IupGetChild(hsi_vb, 1), 0), /* Saturation Label */ + IupGetChild(IupGetChild(hsi_vb, 2), 0), /* Intensity Label */ + IupGetChild(IupGetChild(clr_vb, 0), 0), /* Opacity Label */ + IupGetChild(IupGetChild(clr_vb, 1), 0), /* Hexa Label */ + NULL), "NORMALIZE=HORIZONTAL")); + + IupDestroy(IupSetAttributes(IupNormalizer(IupGetChild(IupGetChild(rgb_vb, 0), 0), /* Red Label */ + IupGetChild(IupGetChild(rgb_vb, 1), 0), /* Green Label */ + IupGetChild(IupGetChild(rgb_vb, 2), 0), /* Blue Label */ + NULL), "NORMALIZE=HORIZONTAL")); + + col2 = IupVbox(IupSetAttributes(IupHbox(hsi_vb, IupFill(), rgb_vb, NULL), "EXPAND=YES"), + IupSetAttributes(IupLabel(NULL), "SEPARATOR=HORIZONTAL"), + clr_vb, + NULL); + IupSetAttributes(col2, "EXPAND=NO, GAP=10"); + + lin1 = IupHbox(col1, col2, NULL); + IupSetAttribute(lin1, "GAP", "10"); + IupSetAttribute(lin1, "MARGIN", "0x0"); + + /* ================== */ + /* 2nd line = Buttons */ + /* ================== */ + + lin2 = IupHbox(IupFill(), ok_bt, cancel_bt, colordlg_data->help_bt, NULL); + IupSetAttribute(lin2, "GAP", "5"); + IupSetAttribute(lin2, "MARGIN", "0x0"); + IupSetAttribute(lin2, "NORMALIZESIZE", "HORIZONTAL"); + + /* Do not use IupAppend because we set childtype=IUP_CHILDNONE */ + iupChildTreeAppend(ih, IupSetAttributes(IupVbox(lin1, IupSetAttributes(IupLabel(NULL), "SEPARATOR=HORIZONTAL"), lin2, NULL), "MARGIN=10x10, GAP=10")); + + iColorBrowserDlgInit_Defaults(colordlg_data); + + (void)params; + return IUP_NOERROR; +} + +Iclass* iupColorBrowserDlgGetClass(void) +{ + Iclass* ic = iupClassNew(iupDialogGetClass()); + + ic->Create = iColorBrowserDlgCreateMethod; + ic->Destroy = iColorBrowserDlgDestroyMethod; + ic->Map = iColorBrowserDlgMapMethod; + + ic->name = "colordlg"; /* this will hide the GTK and Windows implementations */ + ic->nativetype = IUP_TYPEDIALOG; + ic->is_interactive = 1; + ic->childtype = IUP_CHILDNONE; + + iupClassRegisterAttribute(ic, "COLORTABLE", iColorBrowserDlgGetColorTableAttrib, iColorBrowserDlgSetColorTableAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "STATUS", iColorBrowserDlgGetStatusAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "VALUE", iColorBrowserDlgGetValueAttrib, iColorBrowserDlgSetValueAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "ALPHA", iColorBrowserDlgGetAlphaAttrib, iColorBrowserDlgSetAlphaAttrib, IUPAF_SAMEASSYSTEM, "255", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "VALUEHSI", iColorBrowserDlgGetValueHSIAttrib, iColorBrowserDlgSetValueHSIAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "VALUEHEX", iColorBrowserDlgGetValueHexAttrib, iColorBrowserDlgSetValueHexAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "SHOWALPHA", NULL, iColorBrowserDlgSetShowAlphaAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "SHOWCOLORTABLE", NULL, iColorBrowserDlgSetShowColorTableAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "SHOWHEX", NULL, iColorBrowserDlgSetShowHexAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "SHOWHELP", NULL, iColorBrowserDlgSetShowHelpAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + + return ic; +} diff --git a/iup/srccontrols/color/iup_colorhsi.c b/iup/srccontrols/color/iup_colorhsi.c new file mode 100755 index 0000000..ce5e71f --- /dev/null +++ b/iup/srccontrols/color/iup_colorhsi.c @@ -0,0 +1,358 @@ +/** \file + * \brief HSI Color Manipulation + * Copied and adapted from IM + * + * See Copyright Notice in "iup.h" + */ + + +#include <math.h> +#include <stdio.h> +#include "iup_colorhsi.h" + +static const float rad60 = 1.0471975f; +static const float rad120 = 2.0943951f; +static const float rad180 = 3.1415926f; +static const float rad240 = 4.1887902f; +static const float rad300 = 5.2359877f; +static const float rad360 = 6.2831853f; +static const float sqrt3 = 1.7320508f; +static const float rad2deg = 57.2957795131f; + +static float costab[361]; +static float sintab[361]; +static int init_tab = 0; + +static void iColorBuildTables(void) +{ + int theta; + for (theta=0; theta<=360; theta++) + { + float th = ((float)theta)/rad2deg; + costab[theta] = cosf(th); + sintab[theta] = sinf(th); + } + init_tab = 1; +} + +static void iColorSinCos(float H, float *sinH, float *cosH) +{ + int theta; + + H *= rad2deg; + theta = (int)(H + 0.5f); /* Round */ + + if (!init_tab) + iColorBuildTables(); + + if (theta<0) theta = 0; + if (theta>360) theta = 360; + + *cosH = costab[theta]; + *sinH = sintab[theta]; +} + +static float iColorNormHue(float H) +{ + while (H < 0.0f) + H += rad360; + + if (H > rad360) + H = fmodf(H, rad360); + + return H; +} + +static unsigned char iColorQuantize(float value) +{ + if (value >= 1.0f) return 255; + if (value <= 0.0f) return 0; + return (unsigned char)(value*256); +} + +static float iColorReconstruct(unsigned char value) +{ + if (value <= 0) return 0.0f; + if (value >= 255) return 1.0f; + return (((float)value + 0.5f)/256.0f); +} + +static void iColorSmax01(float h, float hr, float hb, float hg, float *h0, float *h1) +{ + if (h < rad60) + { + *h0 = hb; + *h1 = hr; + } + else if (h < rad120) + { + *h0 = hb; + *h1 = hg; + } + else if (h < rad180) + { + *h0 = hr; + *h1 = hg; + } + else if (h < rad240) + { + *h0 = hr; + *h1 = hb; + } + else if (h < rad300) + { + *h0 = hg; + *h1 = hb; + } + else + { + *h0 = hg; + *h1 = hr; + } +} + +/* Given H and I, returns S max, but s is in u,v space. */ +static float iColorHSI_Smax(float h, float cosH, float sinH, float i) +{ + float hr, hb, hg, imax, h0, h1; + + /* i here is normalized between 0-1 */ + + if (i == 0.0f || i == 1.0f) + return 0.0f; + + /* Making r=0, g=0, b=0, r=1, g=1 or b=1 in the parametric equations and + writting s in function of H and I. */ + + /* at bottom */ + if (i <= 1.0f/3.0f) + { + /* face B=0 */ + if (h < rad120) + { + hb = (cosH + sinH*sqrt3)/3.0f; + return i/hb; + } + + /* face R=0 */ + if (h < rad240) + { + hr = -cosH/1.5f; + return i/hr; + } + + /* face G=0 (h < rad360) */ + { + hg = (cosH - sinH*sqrt3)/3.0f; + return i/hg; + } + } + + /* at top */ + if (i >= 2.0f/3.0f) + { + /* face R=1 */ + if (h < rad60 || h > rad300) + { + hr = cosH/1.5f; + return (1.0f-i)/hr; + } + + /* face G=1 */ + if (h < rad180) + { + hg = (-cosH + sinH*sqrt3)/3.0f; + return (1.0f-i)/hg; + } + + /* face B=1 (h > rad180 && h < rad300) */ + { + hb = (-cosH - sinH*sqrt3)/3.0f; + return (1.0f-i)/hb; + } + } + + /* in the middle */ + hr = cosH/1.5f; + hg = (-cosH + sinH*sqrt3)/3.0f; + hb = (-cosH - sinH*sqrt3)/3.0f; + + iColorSmax01(h, hr, hb, hg, &h0, &h1); + + if (h == 0.0f || h == rad120 || h == rad240) + imax = 1.0f/3.0f; + else if (h == rad60 || h == rad180 || h == rad300) + imax = 2.0f/3.0f; + else + imax = h0/(h0 - h1); + + if (i < imax) + return -i/h0; + else + return (1.0f-i)/h1; +} + +/* Given H, returns I where S is max, + BUT the maximum S here is 1 at the corners of the cube. */ +static float iColorHSI_ImaxS(float h, float cosH, float sinH) +{ + float i, h0, h1; + float hr, hb, hg; + + /* i here is normalized between 0-1 */ + + if (h == 0.0f || h == rad120 || h == rad240) + return 1.0f/3.0f; + + if (h == rad60 || h == rad180 || h == rad300) + return 2.0f/3.0f; + + hr = cosH/1.5f; + hg = (-cosH + sinH*sqrt3)/3.0f; + hb = (-cosH - sinH*sqrt3)/3.0f; + + iColorSmax01(h, hr, hb, hg, &h0, &h1); + + i = h0/(h0 - h1); + + return i; +} + +static void iColorRGB2HSI(float r, float g, float b, float *h, float *s, float *i) +{ + float v, u, ImaxS; + + /* Parametric equations */ + v = r - (g + b)/2.0f; + u = (g - b) * (sqrt3/2.0f); + + *i = (r + g + b)/3; /* already normalized to 0-1 */ + + *s = sqrtf(v*v + u*u); /* s is between 0-1, BUT it is linear in the cube and it is in u,v space. */ + + if (*s == 0.0f) + { + /* *h = <any> (left unchanged) */ + ImaxS = 1.0f/3.0f; + } + else + { + float Smax; + float H, cosH, sinH; + + H = atan2f(u, v); + H = iColorNormHue(H); + *h = H * rad2deg; + + iColorSinCos(H, &sinH, &cosH); + + /* must scale S from 0-Smax to 0-1 */ + Smax = iColorHSI_Smax(H, cosH, sinH, *i); + if (Smax == 0.0f) + *s = 0.0f; + else + { + if (*s > Smax) /* because of round problems when calculating s and Smax */ + *s = Smax; + *s /= Smax; + } + + ImaxS = iColorHSI_ImaxS((float)H, cosH, sinH); + } + + /* must convert I from linear scale to non-linear scale. USED ONLY FOR THE COLORBROWSER */ + if (*i < 0.5f) /* half I is I=ImaxS, not I=0.5 */ + *i = ((*i)*0.5f)/ImaxS; + else + *i = (((*i) - ImaxS)*0.5f)/(1.0f - ImaxS) + 0.5f; +} + +static void iColorHSI2RGB(float h, float s, float i, float *r, float *g, float *b) +{ + float cosH, sinH, H, v, u; + float Smax, ImaxS; + + if (i < 0) i = 0; + else if (i > 1) i = 1; + + if (s < 0) s = 0; + else if (s > 1) s = 1; + + if (s == 0.0f || i == 1.0f || i == 0.0f || (int)h == 360) + { + *r = i; + *g = i; + *b = i; + return; + } + + H = h/rad2deg; + H = iColorNormHue(H); + + iColorSinCos(H, &sinH, &cosH); + + /* must convert I from non-linear scale to linear scale. USED ONLY FOR THE COLORBROWSER */ + ImaxS = iColorHSI_ImaxS(H, cosH, sinH); + if (i < 0.5f) /* half I is I=ImaxS, not I=0.5 */ + i = ImaxS * (i / 0.5f); + else + i = (1.0f - ImaxS) * (i - 0.5f)/0.5f + ImaxS; + + /* must scale S from 0-1 to 0-Smax */ + Smax = iColorHSI_Smax(H, cosH, sinH, i); + s *= Smax; + if (s > 1.0f) /* because of round problems when calculating s and Smax */ + s = 1.0f; + + v = s * cosH; + u = s * sinH; + + /* Inverse of the Parametric equations, using i normalized to 0-1 */ + *r = i + v/1.5f; + *g = i - (v - u*sqrt3)/3.0f; + *b = i - (v + u*sqrt3)/3.0f; + + /* fix round errors */ + if (*r < 0.0f) *r = 0; + if (*g < 0.0f) *g = 0; + if (*b < 0.0f) *b = 0; + + if (*r > 1.0f) *r = 1.0f; + if (*g > 1.0f) *g = 1.0f; + if (*b > 1.0f) *b = 1.0f; +} + +/*********************************************************************************************/ + +void iupColorRGB2HSI(unsigned char r, unsigned char g, unsigned char b, float *h, float *s, float *i) +{ + float fr = iColorReconstruct(r); + float fg = iColorReconstruct(g); + float fb = iColorReconstruct(b); + + iColorRGB2HSI(fr, fg, fb, h, s, i); +} + +void iupColorHSI2RGB(float h, float s, float i, unsigned char *r, unsigned char *g, unsigned char *b) +{ + float fr, fg, fb; + + iColorHSI2RGB(h, s, i, &fr, &fg, &fb); + + *r = iColorQuantize(fr); + *g = iColorQuantize(fg); + *b = iColorQuantize(fb); +} + +int iupStrToHSI(const char *str, float *h, float *s, float *i) +{ + float fh, fs, fi; + if (!str) return 0; + if (sscanf(str, "%f %f %f", &fh, &fs, &fi) != 3) return 0; + if (fh > 359 || fs > 1 || fi > 1) return 0; + if (fh < 0 || fs < 0 || fi < 0) return 0; + *h = fh; + *s = fs; + *i = fi; + return 1; +} diff --git a/iup/srccontrols/color/iup_colorhsi.h b/iup/srccontrols/color/iup_colorhsi.h new file mode 100755 index 0000000..b29ea48 --- /dev/null +++ b/iup/srccontrols/color/iup_colorhsi.h @@ -0,0 +1,44 @@ +/** \file + * \brief HSI Color Manipulation + * Copied and adapted from IM + * + * See Copyright Notice in "iup.h" + */ + +#ifndef __IUP_COLORHSI_H +#define __IUP_COLORHSI_H + +#if defined(__cplusplus) +extern "C" { +#endif + +/* 0<=H<=359 */ +/* 0<=S<=1 */ +/* 0<=I<=1 */ + + +/* Converts from RGB to HSI. + */ +void iupColorRGB2HSI(unsigned char r, unsigned char g, unsigned char b, float *h, float *s, float *i); + +/* Converts from HSI to RGB. + */ +void iupColorHSI2RGB(float h, float s, float i, unsigned char *r, unsigned char *g, unsigned char *b); + +int iupStrToHSI(const char *str, float *h, float *s, float *i); + +#ifdef IUP_DEFMATHFLOAT +#define atan2f(_X, _Y) ((float)atan2((double)_X, (double)_Y)) +#define cosf(_X) ((float)cos((double)_X)) +#define fmodf(_X, _Y) ((float)fmod((double)_X, (double)_Y)) +#define sinf(_X) ((float)sin((double)_X)) +#define sqrtf(_X) ((float)sqrt((double)_X)) +#endif + + + +#if defined(__cplusplus) +} +#endif + +#endif |