summaryrefslogtreecommitdiff
path: root/iup/srccontrols/color
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2009-11-04 11:56:41 -0800
committerPixel <pixel@nobis-crew.org>2009-11-04 11:59:33 -0800
commitd577d991b97ae2b5ee1af23641bcffc3f83af5b2 (patch)
tree590639d50205d1bcfaff2a7d2dc6ebf3f373c7ed /iup/srccontrols/color
Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux.
Diffstat (limited to 'iup/srccontrols/color')
-rwxr-xr-xiup/srccontrols/color/iup_colorbrowser.c849
-rwxr-xr-xiup/srccontrols/color/iup_colorbrowserdlg.c1120
-rwxr-xr-xiup/srccontrols/color/iup_colorhsi.c358
-rwxr-xr-xiup/srccontrols/color/iup_colorhsi.h44
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