/*
   _mcolormap001.pkg - may, 22 '98 - by Marc Barilley
   color selection interface

  User callable function :
    proto _CRcolorMap = fun [Chn ObjWin I I S fun [I] I I] ColorMap;;
      parameters are :
        channel (can't be nil)
        parent window
        x coord (can't be nil nor negative)
        y coord (can't be nil nor negative)
        title
        end callback
        initial color (if nil then black r=0 g=0 b=0)

  files needed :
    locked/lib/const.pkg
    locked/lib/_mcolormap.bmp
    locked/lib/opencross.bmp
*/

/* colormap struct */
struct ColorMap= [
  chColorMap :  Chn,
  winColorMap : ObjWin,         /* main window   */
  bwinColorMap : ObjWin,        /* color window  */
  swinColorMap : ObjWin,        /* sample window */
  rwinColorMap : ObjWin,        /* ruler window  */
  cursorColorMap : ObjCursor,
  bcursorColorMap : ObjBitmap,
  backColorMap :    ObjBitmap,
  workColorMap :    ObjBitmap,
  rulerColorMap :   ObjBitmap,
  sampleColorMap :  ObjBitmap,
  rColorMap :   ObjText,
  gColorMap :   ObjText,
  bColorMap :   ObjText,
  hColorMap :   ObjText,
  sColorMap :   ObjText,
  vColorMap :   ObjText,
  oldhColorMap : I,
  oldsColorMap : I,
  endColorMap : fun [I] I
  ] mkColorMap;;


proto rflHLine = fun [ObjText ColorMap] ObjText;;
proto rflSLine = fun [ObjText ColorMap] ObjText;;
proto rflVLine = fun [ObjText ColorMap] ObjText;;
proto rflRLine = fun [ObjText ColorMap] ObjText;;
proto rflGLine = fun [ObjText ColorMap] ObjText;;
proto rflBLine = fun [ObjText ColorMap] ObjText;;

/* conversion */
fun hsv2rgb (h, s, v) = /* rgb 24bits, 0 <= h <= 360, 0 <= s <= 1, 0 <= v <= 1 */
  set v= v*.itof 255;
	if s==itof 0
	then
		(ftoi v)+((ftoi v)<<8)+((ftoi v)<<16)
	else
	{
		while h >=. itof 360 do set h = h -. itof 360;
		while h <. itof 0 do set h = h +. itof 360;
		set h = h /. itof 60;

		let ftoi h -> i in
		let h -. itof i -> f in
		let v *. ((itof 1) -. s) -> p in
		let v *. ((itof 1) -. s *. f) -> q in
		let v *. ((itof 1) -. s *. ((itof 1) -. f)) -> t in
		if i==0
		then
			(ftoi v)+((ftoi t)<<8)+((ftoi p)<<16)
	  else if i==1
	  then
			(ftoi q)+((ftoi v)<<8)+((ftoi p)<<16)
	  else if i==2
	  then
			(ftoi p)+((ftoi v)<<8)+((ftoi t)<<16)
	  else if i==3
	  then
			(ftoi p)+((ftoi q)<<8)+((ftoi v)<<16)
	  else if i==4
	  then
			(ftoi t)+((ftoi p)<<8)+((ftoi v)<<16)
	  else if i==5
	  then
			(ftoi v)+((ftoi p)<<8)+((ftoi q)<<16)
	  else
	    nil
	};;

fun rgb2hsv (c) = /* c = 24 bits color */
  let (c>>16) & 255 -> b in
  let (c>>8) &  255 -> g in
  let c & 255 -> r in
  let
  	if r>g
  	then
  	  if b>r
  	  then
  	    b
  	  else
  	    r
  	else
  	  if b>g
  	  then
  	    b
  	  else
  	    g
  -> mx in
  let
  	if r<g
  	then
  	  if b<r
  	  then
  	    b
  	  else
  	    r
  	else
  	  if b<g
  	  then
  	    b
  	  else
  	    g
  -> mn in
  let itof mx-mn -> delta in
  let
  	if mx==0
  	then
  	  itof 0
  	else
  		(itof mx-mn) /. itof mx
  -> s in
  let
    if (s>.itof 0) || (s<.itof 0) || (delta>.itof 0) || (delta<.itof 0) /* s != 0 || delta != 0 */
    then
      (itof 60) *.
    		if r==mx
    		then
    		  (itof g-b)/.delta
    		else if g==mx
    		then
    		  (itof 2)+.(itof b-r)/.delta
    		else (itof 4)+.(itof r-g)/.delta
    else
      itof 0
  -> h in 
  [
    /* h */
    if h<.itof 0 then h+.itof 360 else h
    /* s */
    s
    /* v */
    (itof mx)/.itof 255
  ];;


/* ending */
fun rflOkColorMap (wn, cm)=
  _DScursor cm.cursorColorMap;
  _DSbitmap cm.bcursorColorMap;
  _DSbitmap cm.backColorMap;
  _DSbitmap cm.workColorMap;
  _DSbitmap cm.rulerColorMap;
  _DSbitmap cm.sampleColorMap;
  let atoi _GETtext cm.rColorMap -> r in
  let atoi _GETtext cm.gColorMap -> g in
  let atoi _GETtext cm.bColorMap -> b in
  {
    _DSwindow cm.winColorMap;
    exec cm.endColorMap with [r + (g<<8) + (b<<16)]
  };
  set cm=nil;;

fun rflDestroyColorMap (wn, cm)=
  _DScursor cm.cursorColorMap;
  _DSbitmap cm.bcursorColorMap;
  _DSbitmap cm.backColorMap;
  _DSbitmap cm.workColorMap;
  _DSbitmap cm.rulerColorMap;
  _DSbitmap cm.sampleColorMap;
  exec cm.endColorMap with [nil];
  set cm=nil;;

fun rflCancelColorMap (wn, cm)=
  _DScursor cm.cursorColorMap;
  _DSbitmap cm.bcursorColorMap;
  _DSbitmap cm.backColorMap;
  _DSbitmap cm.workColorMap;
  _DSbitmap cm.rulerColorMap;
  _DSbitmap cm.sampleColorMap;
  _DSwindow cm.winColorMap;
  exec cm.endColorMap with [nil];
  set cm=nil;;

/* sample window */
fun rflPaintSColorMap (wn, cm)=
  _BLTbitmap wn cm.sampleColorMap 0 0;;

/* ruler */
fun fillRuler (h, v, cm)=
  let (itof 1) /. itof 100 -> delta in
  let itof 1 -> float_1 in
  let itof 0 -> float_0 in
  let itof 200 -> float_200 in
  {
    let float_1 -> v in while v >. float_0 do
    {
      let hsv2rgb h float_1 v -> c in
        _DRAWrectangle cm.rulerColorMap 0 ftoi v*.float_200 10 3 DRAW_SOLID 1 c DRAW_SOLID c;
      set v = v -. delta;
    };
    _DRAWrectangle cm.rulerColorMap 10 0 20 200 DRAW_SOLID 1 0xffffff DRAW_SOLID 0xffffff;
    let ftoi v*.itof 200 -> av in
    let mktab 3 [10 av] -> t in
    {
      set t.(0) = [20 av-5];
      set t.(2) = [20 av+5];
      _DRAWpoly16 cm.rulerColorMap 3 t DRAW_SOLID 1 0 DRAW_SOLID 0;
    }
  };
  _PAINTwindow cm.rwinColorMap;;

fun rflPaintRColorMap (wn, cm)=
  _BLTbitmap wn cm.rulerColorMap 0 0;;

fun rflClickRColorMap (wn, cm, x, y, b)=
  let atoi _GETtext cm.hColorMap -> h in
  let atoi _GETtext cm.sColorMap -> s in
  let hsv2rgb itof h (itof s)/.itof 100 (itof y)/.itof 200 -> c in
  {
    _FILLbitmap cm.sampleColorMap c;
    _PAINTwindow cm.swinColorMap;
    /* fill the ruler */
    fillRuler itof h (itof y)/.itof 200 cm;
    /* set correct text */
    _SETtext cm.vColorMap itoa y/2;
    /* draw bitmaps in the window */
    _PAINTwindow cm.winColorMap;
    /* set correct text */
    _CBtext cm.rColorMap nil nil;
    _CBtext cm.gColorMap nil nil;
    _CBtext cm.bColorMap nil nil;
    _SETtext cm.rColorMap itoa c&255;
    _SETtext cm.gColorMap itoa (c>>8)&255;
    _SETtext cm.bColorMap itoa (c>>16)&255;
    _CBtext cm.rColorMap @rflRLine cm;
    _CBtext cm.gColorMap @rflGLine cm;
    _CBtext cm.bColorMap @rflBLine cm;
  };;

fun rflUnclickRColorMap (wn, cm, x, y, b)=
0;;

fun rflCursorMoveRColorMap (wn, cm, x, y, b)=
  if b == 1
  then
  {
    if y<0 then set y = 0 else nil;
    if y>200 then set y = 200 else nil;
    let atoi _GETtext cm.hColorMap -> h in
    let atoi _GETtext cm.sColorMap -> s in
    let hsv2rgb itof h (itof s)/.itof 100 (itof y)/.itof 200 -> c in
    {
      _FILLbitmap cm.sampleColorMap c;
      _PAINTwindow cm.swinColorMap;
      /* fill the ruler */
      fillRuler itof h (itof y)/.itof 200 cm;
      /* set correct text */
      _SETtext cm.vColorMap itoa (y/2);
      /* draw bitmaps in the window */
      _PAINTwindow cm.winColorMap;
      /* set correct text */
      _CBtext cm.rColorMap nil nil;
      _CBtext cm.gColorMap nil nil;
      _CBtext cm.bColorMap nil nil;
      _SETtext cm.rColorMap itoa c&255;
      _SETtext cm.gColorMap itoa (c>>8)&255;
      _SETtext cm.bColorMap itoa (c>>16)&255;
      _CBtext cm.rColorMap @rflRLine cm;
      _CBtext cm.gColorMap @rflGLine cm;
      _CBtext cm.bColorMap @rflBLine cm;
    }
  }
  else
    nil;;

/* color window */
fun rflPaintBColorMap (wn, cm)=
  _BLTbitmap wn cm.workColorMap 0 0;;

fun rflClickBColorMap (wn, cm, x, y, b)=
  if b==1
  then
  {
    /* erase old pointer */
    _CPbitmap16
      cm.workColorMap cm.oldhColorMap-15 cm.oldsColorMap-15 
      cm.backColorMap cm.oldhColorMap-15 cm.oldsColorMap-15 31 31 nil;
    set cm.oldhColorMap = x;
    set cm.oldsColorMap = y;
    /* fill the ruler */
    fillRuler itof x (itof atoi _GETtext cm.vColorMap)/.(itof 100) cm;
    /* draw bitmap in the window */
    _PAINTwindow cm.winColorMap;
    _PAINTwindow cm.bwinColorMap;
    /* set correct text */
    _CBtext cm.hColorMap nil nil;
    _CBtext cm.sColorMap nil nil;
    _CBtext cm.rColorMap nil nil;
    _CBtext cm.gColorMap nil nil;
    _CBtext cm.bColorMap nil nil;
    let hsv2rgb itof x (itof y)/.itof 200 (itof atoi _GETtext cm.vColorMap)/.itof 100 -> c in
    {
      _FILLbitmap cm.sampleColorMap c;
      _SETtext cm.rColorMap itoa c&255;
      _SETtext cm.gColorMap itoa (c>>8)&255;
      _SETtext cm.bColorMap itoa (c>>16)&255;
    };
    _SETtext cm.hColorMap itoa x;
    _SETtext cm.sColorMap itoa y/2;
    _CBtext cm.hColorMap @rflHLine cm;
    _CBtext cm.sColorMap @rflSLine cm;
    _CBtext cm.rColorMap @rflRLine cm;
    _CBtext cm.gColorMap @rflGLine cm;
    _CBtext cm.bColorMap @rflBLine cm;
    _PAINTwindow cm.swinColorMap;
  }
  else
    nil;;

fun rflUnclickBColorMap (wn, cm, x, y, b)=
  if b==1
  then
  {
    if x>360 then set x=360 else nil;
    if x<0 then set x=0 else nil;
    if y>200 then set y=200 else nil;
    if y<0 then set y=0 else nil;
    _fooS "rflUnclickBColorMap";
    /* trace new pointer */
    _CPbitmap16 cm.workColorMap x-15 y-15 cm.bcursorColorMap 1 1 27 27 0xffffff;
    set cm.oldhColorMap = x;
    set cm.oldsColorMap = y;
    _PAINTwindow cm.bwinColorMap;
  }
  else
    nil;;

fun rflCursorMoveBColorMap (wn, cm, x, y, b)=
  if b != 1
  then
    nil
  else
  {
    if x>360 then set x=360 else nil;
    if x<0 then set x=0 else nil;
    if y>200 then set y=200 else nil;
    if y<0 then set y=0 else nil;
    let hsv2rgb itof x (itof y)/.itof 200 (itof atoi _GETtext cm.vColorMap)/.itof 100 -> c in
    {
      _FILLbitmap cm.sampleColorMap c;
      _PAINTwindow cm.swinColorMap;
      /* fill the ruler */
      fillRuler itof x (itof atoi _GETtext cm.vColorMap)/.itof 100 cm;
      /* set correct text */
      _CBtext cm.hColorMap nil nil;
      _CBtext cm.sColorMap nil nil;
      _CBtext cm.rColorMap nil nil;
      _CBtext cm.gColorMap nil nil;
      _CBtext cm.bColorMap nil nil;
      _SETtext cm.rColorMap itoa c&255;
      _SETtext cm.gColorMap itoa (c>>8)&255;
      _SETtext cm.bColorMap itoa (c>>16)&255;
      _SETtext cm.hColorMap itoa x;
      _SETtext cm.sColorMap itoa y/2;
      _CBtext cm.hColorMap @rflHLine cm;
      _CBtext cm.sColorMap @rflSLine cm;
      _CBtext cm.rColorMap @rflRLine cm;
      _CBtext cm.gColorMap @rflGLine cm;
      _CBtext cm.bColorMap @rflBLine cm;
    }
  };;



fun rflRLine (l, cm)=
  let atoi _GETtext l -> r in
  let atoi _GETtext cm.gColorMap -> g in
  let atoi _GETtext cm.bColorMap -> b in
  let r+(g<<8)+(b<<16) -> c in
  let rgb2hsv c -> [fh fs fv] in
  let ftoi fh -> h in
  let ftoi (itof 100)*.fs -> s in
  let ftoi (itof 100)*.fv -> v in
  {
    _FILLbitmap cm.sampleColorMap c;
    _PAINTwindow cm.swinColorMap;
    /* erase old pointer */
    _CPbitmap16
      cm.workColorMap cm.oldhColorMap-16 cm.oldsColorMap-16
      cm.backColorMap cm.oldhColorMap-16 cm.oldsColorMap-16 32 32 nil;
    set cm.oldhColorMap = h;
    set cm.oldsColorMap = 2*s;
    /* trace new pointer */
    _CPbitmap16 cm.workColorMap h-15 2*s-15 cm.bcursorColorMap 1 1 31 31 0xffffff;
    /* fill the ruler */
    fillRuler fh fv cm;
    /* draw bitmap in the window */
    _PAINTwindow cm.bwinColorMap;
    /* set correct text */
    _CBtext cm.hColorMap nil nil;
    _CBtext cm.sColorMap nil nil;
    _CBtext cm.vColorMap nil nil;
    _SETtext cm.hColorMap itoa h;
    _SETtext cm.sColorMap itoa s;
    _SETtext cm.vColorMap itoa v;
    _CBtext cm.hColorMap @rflHLine cm;
    _CBtext cm.sColorMap @rflSLine cm;
    _CBtext cm.vColorMap @rflVLine cm;
  };;

fun rflGLine (l, cm)=
  let atoi _GETtext cm.rColorMap -> r in
  let atoi _GETtext l -> g in
  let atoi _GETtext cm.bColorMap -> b in
  let r+(g<<8)+(b<<16) -> c in
  let rgb2hsv c -> [fh fs fv] in
  let ftoi fh -> h in
  let ftoi (itof 100)*.fs -> s in
  let ftoi (itof 100)*.fv -> v in
  {
    _FILLbitmap cm.sampleColorMap c;
    _PAINTwindow cm.swinColorMap;
    /* erase old pointer */
    _CPbitmap16
      cm.workColorMap cm.oldhColorMap-15 cm.oldsColorMap-15
      cm.backColorMap cm.oldhColorMap-15 cm.oldsColorMap-15 32 32 nil;
    set cm.oldhColorMap = h;
    set cm.oldsColorMap = 2*s;
    /* trace new pointer */
    _CPbitmap16 cm.workColorMap h-15 2*s-15 cm.bcursorColorMap 1 1 31 31 0xffffff;
    /* fill the ruler */
    fillRuler fh fv cm;
    /* draw bitmap in the window */
    _PAINTwindow cm.bwinColorMap;
    /* set correct text */
    _CBtext cm.hColorMap nil nil;
    _CBtext cm.sColorMap nil nil;
    _CBtext cm.vColorMap nil nil;
    _SETtext cm.hColorMap itoa h;
    _SETtext cm.sColorMap itoa s;
    _SETtext cm.vColorMap itoa v;
    _CBtext cm.hColorMap @rflHLine cm;
    _CBtext cm.sColorMap @rflSLine cm;
    _CBtext cm.vColorMap @rflVLine cm;
  };;

fun rflBLine (l, cm)=
  let atoi _GETtext cm.rColorMap -> r in
  let atoi _GETtext cm.gColorMap -> g in
  let atoi _GETtext l -> b in
  let r+(g<<8)+(b<<16) -> c in
  let rgb2hsv c -> [fh fs fv] in
  let ftoi fh -> h in
  let ftoi (itof 100)*.fs -> s in
  let ftoi (itof 100)*.fv -> v in
  {
    _FILLbitmap cm.sampleColorMap c;
    _PAINTwindow cm.swinColorMap;
    /* erase old pointer */
    _CPbitmap16
      cm.workColorMap cm.oldhColorMap-16 cm.oldsColorMap-16
      cm.backColorMap cm.oldhColorMap-16 cm.oldsColorMap-16 32 32 nil;
    set cm.oldhColorMap = h;
    set cm.oldsColorMap = 2*s;
    /* trace new pointer */
    _CPbitmap16 cm.workColorMap h-15 2*s-15 cm.bcursorColorMap 1 1 31 31 0xffffff;
    /* fill the ruler */
    fillRuler fh fv cm;
    /* draw bitmap in the window */
    _PAINTwindow cm.bwinColorMap;
    /* set correct text */
    _CBtext cm.hColorMap nil nil;
    _CBtext cm.sColorMap nil nil;
    _CBtext cm.vColorMap nil nil;
    _SETtext cm.hColorMap itoa h;
    _SETtext cm.sColorMap itoa s;
    _SETtext cm.vColorMap itoa v;
    _CBtext cm.hColorMap @rflHLine cm;
    _CBtext cm.sColorMap @rflSLine cm;
    _CBtext cm.vColorMap @rflVLine cm;
  };;

fun rflHLine (l, cm)=
  let atoi _GETtext l -> h in
  let atoi _GETtext cm.sColorMap -> s in
  let atoi _GETtext cm.vColorMap -> v in
  let hsv2rgb itof h (itof s)/.itof 100 (itof v)/.itof 100 -> c in
  {
    _FILLbitmap cm.sampleColorMap c;
    _PAINTwindow cm.swinColorMap;
    /* erase old pointer */
    _CPbitmap16
      cm.workColorMap cm.oldhColorMap-16 cm.oldsColorMap-16
      cm.backColorMap cm.oldhColorMap-16 cm.oldsColorMap-16 32 32 nil;
    set cm.oldhColorMap = h;
    /* trace new pointer */
    _CPbitmap16 cm.workColorMap h-15 2*s-15 cm.bcursorColorMap 1 1 31 31 0xffffff;
    /* fill the ruler */
    fillRuler itof h (itof v)/.itof 100 cm;
    /* draw bitmap in the window */
    _PAINTwindow cm.bwinColorMap;
    /* set correct text */
    _CBtext cm.rColorMap nil nil;
    _CBtext cm.gColorMap nil nil;
    _CBtext cm.bColorMap nil nil;
    _SETtext cm.rColorMap itoa c&255;
    _SETtext cm.gColorMap itoa (c>>8)&255;
    _SETtext cm.bColorMap itoa (c>>16)&255;
    _CBtext cm.rColorMap @rflRLine cm;
    _CBtext cm.gColorMap @rflGLine cm;
    _CBtext cm.bColorMap @rflBLine cm;
  };;

fun rflSLine (l, cm)=
  let atoi _GETtext cm.hColorMap -> h in
  let atoi _GETtext l -> s in
  let atoi _GETtext cm.vColorMap -> v in
  let hsv2rgb itof h (itof s)/.itof 100 (itof v)/.itof 100 -> c in
  {
    _FILLbitmap cm.sampleColorMap c;
    _PAINTwindow cm.swinColorMap;
    /* erase old pointer */
    _CPbitmap16
      cm.workColorMap cm.oldhColorMap-16 cm.oldsColorMap-16
      cm.backColorMap cm.oldhColorMap-16 cm.oldsColorMap-16 32 32 nil;
    set cm.oldsColorMap = 2*s;
    /* trace new pointer */
    _CPbitmap16 cm.workColorMap h-15 2*s-15 cm.bcursorColorMap 1 1 31 31 0xffffff;
    /* fill the ruler */
    fillRuler itof h (itof v)/.itof 100 cm;
    /* draw bitmap in the window */
    _PAINTwindow cm.bwinColorMap;
    /* set correct text */
    _CBtext cm.rColorMap nil nil;
    _CBtext cm.gColorMap nil nil;
    _CBtext cm.bColorMap nil nil;
    _SETtext cm.rColorMap itoa c&255;
    _SETtext cm.gColorMap itoa (c>>8)&255;
    _SETtext cm.bColorMap itoa (c>>16)&255;
    _CBtext cm.rColorMap @rflRLine cm;
    _CBtext cm.gColorMap @rflGLine cm;
    _CBtext cm.bColorMap @rflBLine cm;
  };;

fun rflVLine (l, cm)=
  let atoi _GETtext cm.hColorMap -> h in
  let atoi _GETtext cm.sColorMap -> s in
  let atoi _GETtext l -> v in
  let hsv2rgb itof h (itof s)/.itof 100 (itof v)/.itof 100 -> c in
  {
    /* fill the ruler */
    fillRuler itof h (itof v)/.itof 100 cm;
    /* sample */
    _FILLbitmap cm.sampleColorMap c;
    _PAINTwindow cm.swinColorMap;
    /* set correct text */
    _CBtext cm.rColorMap nil nil;
    _CBtext cm.gColorMap nil nil;
    _CBtext cm.bColorMap nil nil;
    _SETtext cm.rColorMap itoa c&255;
    _SETtext cm.gColorMap itoa (c>>8)&255;
    _SETtext cm.bColorMap itoa (c>>16)&255;
    _CBtext cm.rColorMap @rflRLine cm;
    _CBtext cm.gColorMap @rflGLine cm;
    _CBtext cm.bColorMap @rflBLine cm;
  };;

fun _CRcolorMap (ch, father, x, y, title, end, color)=
  if (ch==nil) || (x==nil) || (y==nil) || (x<0) || (y<0)
  then
    nil
  else
    let if title==nil then "" else title -> title in
    let
      if color==nil
        then [0 0 0]
        else [(color>>16)&255 (color>>8)&255 color&255]
    ->[bc gc rc] in
    let rgb2hsv color -> [hc sc vc] in
    let _CRwindow ch father x  y 400 310 WN_MENU+WN_MINBOX title -> win in
    let _CRwindow ch win   5   5 360 204 WN_DOWN+WN_CHILD title -> bwin in
    let _CRwindow ch win   5 215  40  40 WN_DOWN+WN_CHILD title -> swin in
    let _CRwindow ch win 368   5  22 204 WN_DOWN+WN_CHILD title -> rwin in
    let _CRbitmap ch 360 200 -> work in
    let _FILLbitmap _CRbitmap ch 20 200 0xbfbfbf -> ruler in
    let _CRbitmap ch 40 40 -> sample in
    let _LDbitmap ch _checkpack "locked/lib/_mcolormap.bmp" -> back in
    let _LDbitmap ch _checkpack "locked/lib/opencross.bmp" -> bcursor in
    let _CRcursor ch bcursor 16 16 0x000000 0xff0000 -> cursor in
    let _CReditLine ch win  75 215 75 20 ET_NUMBER|ET_DOWN|ET_ALIGN_RIGHT itoa ftoi hc -> h in
    let _CReditLine ch win 195 215 75 20 ET_NUMBER|ET_DOWN|ET_ALIGN_RIGHT itoa ftoi (sc*.itof 100) -> s in
    let _CReditLine ch win 315 215 75 20 ET_NUMBER|ET_DOWN|ET_ALIGN_RIGHT itoa ftoi (vc*.itof 100) -> v in
    let _CReditLine ch win  75 240 75 20 ET_NUMBER|ET_DOWN|ET_ALIGN_RIGHT itoa rc -> r in
    let _CReditLine ch win 195 240 75 20 ET_NUMBER|ET_DOWN|ET_ALIGN_RIGHT itoa gc -> g in
    let _CReditLine ch win 315 240 75 20 ET_NUMBER|ET_DOWN|ET_ALIGN_RIGHT itoa bc -> b in
    let mkColorMap [ch win bwin swin rwin cursor bcursor back work ruler sample r g b h s v ftoi hc 2*ftoi (sc*.itof 100) end] -> cm in
    let _CBbutton _CRbutton ch win  80 285 80 20 0 "Ok" @rflOkColorMap cm -> ok in
    let _CBbutton _CRbutton ch win 240 285 80 20 0 "Cancel" @rflCancelColorMap cm -> cancel in
    {
      _CRtext ch win  50 215 20 20 ET_ALIGN_CENTER "H";
      _CRtext ch win 160 215 30 20 ET_ALIGN_CENTER "S";
      _CRtext ch win 280 215 30 20 ET_ALIGN_CENTER "V";
      _CRtext ch win  50 240 20 20 ET_ALIGN_CENTER "R";
      _CRtext ch win 160 240 30 20 ET_ALIGN_CENTER "G";
      _CRtext ch win 280 240 30 20 ET_ALIGN_CENTER "B";
      /* editlines reflexes */
      _CBtext cm.hColorMap @rflHLine cm;
      _CBtext cm.sColorMap @rflSLine cm;
      _CBtext cm.vColorMap @rflVLine cm;
      _CBtext cm.rColorMap @rflRLine cm;
      _CBtext cm.gColorMap @rflGLine cm;
      _CBtext cm.bColorMap @rflBLine cm;
      /* ruler window */
      _CBwinPaint   rwin @rflPaintRColorMap cm;
      _CBwinClick   rwin @rflClickRColorMap cm;
      _CBwinUnclick rwin @rflUnclickRColorMap cm;
      _CBcursorMove rwin @rflCursorMoveRColorMap cm;
      fillRuler hc vc cm;
      /* samle window */
      _FILLbitmap sample color;
      _CBwinPaint   swin @rflPaintSColorMap cm;
      /* workwindow reflexes */
      _CBwinPaint   bwin @rflPaintBColorMap cm;
      _CBwinClick   bwin @rflClickBColorMap cm;
      _CBwinUnclick bwin @rflUnclickBColorMap cm;
      _CBcursorMove bwin @rflCursorMoveBColorMap cm;
      _CPbitmap16 work 0 0 back 0 0 360 200 nil;
      /* trace pointer on work */
      _CPbitmap16 work (ftoi hc)-15 (2*ftoi sc*.itof 100)-15 bcursor 1 1 31 31 0xffffff;
      /* draw bitmaps in the window */
      _PAINTwindow win;
      _PAINTwindow bwin;
      _PAINTwindow swin;
      cm
    };;