Color Picker.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. #define CP_PROPS_RGB 0
  4. #define CP_PROPS_ALPHA 3
  5. #define CP_PROPS_RGBA 4
  6. #define CP_PROPS_HSB 5
  7. namespace EE{
  8. /******************************************************************************/
  9. static TextStyle ColorPickerTS;
  10. /******************************************************************************/
  11. void ColorPicker::SetTextStyle()
  12. {
  13. ColorPickerTS.reset(true).size=0.04f; ColorPickerTS.align.set(1, 0);
  14. }
  15. /******************************************************************************/
  16. ColorPicker::ColorPicker()
  17. {
  18. _real =false;
  19. _func_immediate=false;
  20. _func_user =null;
  21. _func =null;
  22. _rgba.set(1, 0, 0, 1);
  23. _hsb .set(0, 1, 1 );
  24. }
  25. /******************************************************************************/
  26. ColorPicker& ColorPicker::show()
  27. {
  28. if(hidden())setOld();
  29. super::show();
  30. return T;
  31. }
  32. ColorPicker& ColorPicker::mode(Bool real)
  33. {
  34. if(T._real!=real)
  35. {
  36. T._real=real;
  37. DATA_TYPE dt =(_real ? DATA_REAL : DATA_INT);
  38. Flt range=(_real ? 1.0f : 255),
  39. speed=(_real ? 0.4f : 40);
  40. REPA(_props)if(i!=CP_PROPS_RGBA)_props[i].range(0, range).mouseEditSpeed(speed).md.type=dt;
  41. toGui(true, true, true, false);
  42. }
  43. return T;
  44. }
  45. void ColorPicker::update(C GuiPC &gpc)
  46. {
  47. super::update(gpc);
  48. if(Gui.window()==this)
  49. {
  50. if((Kb.k(KB_ESC) || Kb.k(KB_NAV_BACK)) && Kb.k.first() || Ms.bp(2)){Kb.eatKey(); Ms.eat(2); hide();}
  51. }
  52. }
  53. /******************************************************************************/
  54. void ColorPicker::toGui(Bool rgb, Bool alpha, Bool hsb, Bool rgba)
  55. {
  56. if(rgb )REP(3)_props[CP_PROPS_RGB+i].toGui();
  57. if(alpha) _props[CP_PROPS_ALPHA].toGui();
  58. if(hsb )REP(3)_props[CP_PROPS_HSB+i].toGui();
  59. if(rgba ) _props[CP_PROPS_RGBA ].toGui();
  60. }
  61. void ColorPicker::setOld()
  62. {
  63. _old=_rgba;
  64. }
  65. void ColorPicker::_set(C Vec4 &color, SET_MODE mode)
  66. {
  67. if(T._rgba!=color)
  68. {
  69. T._rgba=color;
  70. T._hsb =RgbToHsb(color.xyz);
  71. if(mode!=QUIET)call();
  72. }
  73. }
  74. void ColorPicker::_setRGB(C Vec &rgb, SET_MODE mode)
  75. {
  76. if(T._rgba.xyz!=rgb)
  77. {
  78. T._rgba.xyz=rgb;
  79. T._hsb =RgbToHsb(rgb);
  80. if(mode!=QUIET)call();
  81. }
  82. }
  83. void ColorPicker::_setHSB(C Vec &hsb, SET_MODE mode)
  84. {
  85. if(T._hsb!=hsb)
  86. {
  87. T._hsb =hsb;
  88. T._rgba.xyz=HsbToRgb(hsb);
  89. if(mode!=QUIET)call();
  90. }
  91. }
  92. void ColorPicker::_setAlpha(Flt alpha, SET_MODE mode)
  93. {
  94. if(T._rgba.w!=alpha)
  95. {
  96. T._rgba.w=alpha;
  97. if(mode!=QUIET)call();
  98. }
  99. }
  100. ColorPicker& ColorPicker::set (C Vec4 &color, SET_MODE mode) {_set (color, mode); toGui( ); return T;}
  101. ColorPicker& ColorPicker::setRGB (C Vec &rgb , SET_MODE mode) {_setRGB (rgb , mode); toGui(true , false, true ); return T;}
  102. ColorPicker& ColorPicker::setHSB (C Vec &hsb , SET_MODE mode) {_setHSB (hsb , mode); toGui(true , false, true ); return T;}
  103. ColorPicker& ColorPicker::setAlpha( Flt alpha, SET_MODE mode) {_setAlpha(alpha, mode); toGui(false, true , false); return T;}
  104. /******************************************************************************/
  105. ColorPicker& ColorPicker::func(void (*func)(Ptr user), Ptr user, Bool immediate)
  106. {
  107. T._func =func;
  108. T._func_user =user;
  109. T._func_immediate=immediate;
  110. return T;
  111. }
  112. void ColorPicker::call()
  113. {
  114. if(_func)if(_func_immediate)_func(_func_user);else Gui.addFuncCall(_func, _func_user);
  115. }
  116. /******************************************************************************/
  117. void ColorPicker::SatLum::update(C GuiPC &gpc)
  118. {
  119. if(gpc.visible && gpc.enabled && visible() && enabled())
  120. {
  121. C Vec2 *pos=null; if(Gui.ms()==this && Ms.b(0))pos=&Ms.pos(); if(!pos)REPA(Touches)if(Touches[i].guiObj()==this && Touches[i].on())pos=&Touches[i].pos();
  122. if( pos)
  123. {
  124. ColorPicker &cp =*(ColorPicker*)user;
  125. Rect rect=T.rect()+gpc.offset;
  126. cp.setHSB(Vec(cp._hsb.x, LerpRS(rect.min.x, rect.max.x, pos->x), LerpRS(rect.min.y, rect.max.y, pos->y)));
  127. }
  128. }
  129. }
  130. void ColorPicker::SatLum::draw(C GuiPC &gpc)
  131. {
  132. if(gpc.visible && visible())
  133. {
  134. D.clip(gpc.clip);
  135. ColorPicker &cp =*(ColorPicker*)user;
  136. Rect rect=T.rect()+gpc.offset;
  137. Int steps=8;
  138. FREPD(y, steps)
  139. FREPD(x, steps)
  140. {
  141. Flt sx=Flt(x)/steps, sx1=Flt(x+1)/steps,
  142. sy=Flt(y)/steps, sy1=Flt(y+1)/steps;
  143. Color clu=ColorHSB(cp._hsb.x, sx , sy1),
  144. cru=ColorHSB(cp._hsb.x, sx1, sy1),
  145. crd=ColorHSB(cp._hsb.x, sx1, sy ),
  146. cld=ColorHSB(cp._hsb.x, sx , sy );
  147. Flt l=rect.lerpX(sx ),
  148. r=rect.lerpX(sx1),
  149. d=rect.lerpY(sy ),
  150. u=rect.lerpY(sy1);
  151. VI.tri(clu, cru, cld, Vec2(l, u), Vec2(r, u), Vec2(l, d));
  152. VI.tri(cru, crd, cld, Vec2(r, u), Vec2(r, d), Vec2(l, d));
  153. }
  154. VI.end();
  155. rect.draw(Gui.borderColor(), false);
  156. ALPHA_MODE alpha=D.alpha(ALPHA_INVERT); Circle(0.01f, rect.lerp(cp._hsb.y, cp._hsb.z)).draw(WHITE, false);
  157. D.alpha(alpha );
  158. }
  159. }
  160. void ColorPicker::Hue::update(C GuiPC &gpc)
  161. {
  162. if(gpc.visible && gpc.enabled && visible() && enabled())
  163. {
  164. C Vec2 *pos=null; if(Gui.ms()==this && Ms.b(0))pos=&Ms.pos(); if(!pos)REPA(Touches)if(Touches[i].guiObj()==this && Touches[i].on())pos=&Touches[i].pos();
  165. if( pos)
  166. {
  167. ColorPicker &cp =*(ColorPicker*)user;
  168. Rect rect=T.rect()+gpc.offset;
  169. cp.setHSB(Vec(LerpRS(rect.min.y, rect.max.y, pos->y), cp._hsb.y, cp._hsb.z));
  170. }
  171. }
  172. }
  173. void ColorPicker::Hue::draw(C GuiPC &gpc)
  174. {
  175. if(gpc.visible && visible())
  176. {
  177. D.clip(gpc.clip);
  178. ColorPicker &cp =*(ColorPicker*)user;
  179. Rect rect=T.rect()+gpc.offset;
  180. Int steps=6;
  181. Flt y =rect.min.y;
  182. Color prev =RED;
  183. FREP(steps)
  184. {
  185. Flt s =Flt(i+1)/steps, yn=rect.lerpY(s);
  186. Color next=ColorHue(s);
  187. Vec2 lu(rect.min.x, yn), ru(rect.max.x, yn),
  188. ld(rect.min.x, y ), rd(rect.max.x, y );
  189. VI.tri(next, next, prev, lu, ru, ld);
  190. VI.tri(next, prev, prev, ru, rd, ld);
  191. y=yn;
  192. prev=next;
  193. }
  194. VI.end();
  195. rect.draw(Gui.borderColor(), false);
  196. ALPHA_MODE alpha=D.alpha(ALPHA_INVERT); Rect(rect.lerp(0.5f, cp._hsb.x)).extend(rect.w()/2+0.01f, 0.008f).draw(WHITE, false);
  197. D.alpha(alpha );
  198. }
  199. }
  200. void ColorPicker::Colors::update(C GuiPC &gpc)
  201. {
  202. if(gpc.visible && gpc.enabled && visible() && enabled())
  203. {
  204. C Vec2 *pos=null; if(Gui.ms()==this && Ms.b(0))pos=&Ms.pos(); if(!pos)REPA(Touches)if(Touches[i].guiObj()==this && Touches[i].on())pos=&Touches[i].pos();
  205. if( pos)
  206. {
  207. ColorPicker &cp =*(ColorPicker*)user;
  208. Rect rect=T.rect()+gpc.offset;
  209. if(Cuts(*pos, Rect(rect.min.x, rect.min.y, rect.max.x, rect.centerY())))cp.set(cp._old);
  210. }
  211. }
  212. }
  213. void ColorPicker::Colors::draw(C GuiPC &gpc)
  214. {
  215. if(gpc.visible && visible())
  216. {
  217. D.clip(gpc.clip);
  218. ColorPicker &cp =*(ColorPicker*)user;
  219. Rect rect=T.rect()+gpc.offset;
  220. Rect(rect.min.x, rect.centerY(), rect.max.x, rect.max.y ).draw(Color(cp._rgba.xyz));
  221. Rect(rect.min.x, rect.min.y , rect.max.x, rect.centerY()).draw(Color(cp._old .xyz));
  222. rect.draw(Gui.borderColor(), false);
  223. }
  224. }
  225. /******************************************************************************/
  226. static void ColorRed (ColorPicker &cp, C Str &text) {Flt val=TextFlt(text); if(!cp._real)val/=255; cp._setRGB (Vec(val , cp._rgba.y, cp._rgba.z)); cp.toGui(false, false, true );} // update HSB, RGBA
  227. static void ColorGreen(ColorPicker &cp, C Str &text) {Flt val=TextFlt(text); if(!cp._real)val/=255; cp._setRGB (Vec(cp._rgba.x, val , cp._rgba.z)); cp.toGui(false, false, true );} // update HSB, RGBA
  228. static void ColorBlue (ColorPicker &cp, C Str &text) {Flt val=TextFlt(text); if(!cp._real)val/=255; cp._setRGB (Vec(cp._rgba.x, cp._rgba.y, val )); cp.toGui(false, false, true );} // update HSB, RGBA
  229. static void ColorAlpha(ColorPicker &cp, C Str &text) {Flt val=TextFlt(text); if(!cp._real)val/=255; cp._setAlpha( val ); cp.toGui(false, false, false );} // udpate RGBA
  230. static void ColorHue (ColorPicker &cp, C Str &text) {Flt val=TextFlt(text); if(!cp._real)val/=255; cp._setHSB (Vec(val , cp._hsb.y , cp._hsb.z )); cp.toGui(true , false, false );} // update RGB, RGBA
  231. static void ColorSat (ColorPicker &cp, C Str &text) {Flt val=TextFlt(text); if(!cp._real)val/=255; cp._setHSB (Vec(cp._hsb.x , val , cp._hsb.z )); cp.toGui(true , false, false );} // update RGB, RGBA
  232. static void ColorLum (ColorPicker &cp, C Str &text) {Flt val=TextFlt(text); if(!cp._real)val/=255; cp._setHSB (Vec(cp._hsb.x , cp._hsb.y , val )); cp.toGui(true , false, false );} // update RGB, RGBA
  233. static void ColorRGBA (ColorPicker &cp, C Str &text) {Color c; c.fromHex(text); cp._set (c.asVec4() ); cp.toGui(true , true , true , false);} // update RGB, HSB, ALPHA
  234. static Str ColorRed (C ColorPicker &cp) {return cp._real ? TextFlt(cp._rgba.x) : TextInt(Round(255*cp._rgba.x));}
  235. static Str ColorGreen(C ColorPicker &cp) {return cp._real ? TextFlt(cp._rgba.y) : TextInt(Round(255*cp._rgba.y));}
  236. static Str ColorBlue (C ColorPicker &cp) {return cp._real ? TextFlt(cp._rgba.z) : TextInt(Round(255*cp._rgba.z));}
  237. static Str ColorAlpha(C ColorPicker &cp) {return cp._real ? TextFlt(cp._rgba.w) : TextInt(Round(255*cp._rgba.w));}
  238. static Str ColorHue (C ColorPicker &cp) {return cp._real ? TextFlt(cp._hsb .x) : TextInt(Round(255*cp._hsb .x));}
  239. static Str ColorSat (C ColorPicker &cp) {return cp._real ? TextFlt(cp._hsb .y) : TextInt(Round(255*cp._hsb .y));}
  240. static Str ColorLum (C ColorPicker &cp) {return cp._real ? TextFlt(cp._hsb .z) : TextInt(Round(255*cp._hsb .z));}
  241. static Str ColorRGBA (C ColorPicker &cp) {return Color(cp._rgba).asHex();}
  242. static void Mode(ColorPicker &cp) {cp.mode(!cp._real);}
  243. /******************************************************************************/
  244. ColorPicker& ColorPicker::create(C Str &name)
  245. {
  246. SetTextStyle();
  247. Gui+=super::create(Rect_C(0, 0, 1.01f, 0.69f), S+"Color Picker"+(name.is() ? S+" - \""+name+'"' : S)); T.button[2].show();
  248. T+=_sat_lum.create(Rect_LU(0.04f, -0.04f , 0.555f, 0.555f ), this);
  249. T+=_hue .create(Rect_LU(_sat_lum.rect().ru()+Vec2(0.04f, 0), 0.05f, _sat_lum.rect().h()), this);
  250. T+=_color .create(Rect_LU(_hue .rect().ru()+Vec2(0.04f, 0), 0.14f, 0.14f ), this);
  251. T+=_tnew .create(Vec2 (_color .rect().max.x+0.01f, _color.rect().lerpY(0.75f)), "New", &ColorPickerTS);
  252. T+=_told .create(Vec2 (_color .rect().max.x+0.01f, _color.rect().lerpY(0.25f)), "Old", &ColorPickerTS);
  253. T+=_mode .create(Rect_U (Avg(_color.rect().min.x, clientWidth()-0.04f), _color.rect().min.y-0.01f, 0.2f, 0.04f), "Byte / Real").func(Mode, T).focusable(false); _mode.mode=BUTTON_TOGGLE;
  254. DATA_TYPE dt=DATA_INT;
  255. _props.del();
  256. ASSERT(CP_PROPS_RGB==0);
  257. _props.New().create("Red" , MemberDesc(dt).setFunc(ColorRed , ColorRed ));
  258. _props.New().create("Green", MemberDesc(dt).setFunc(ColorGreen, ColorGreen));
  259. _props.New().create("Blue" , MemberDesc(dt).setFunc(ColorBlue , ColorBlue ));
  260. ASSERT(CP_PROPS_ALPHA==3);
  261. _props.New().create("Alpha", MemberDesc(dt).setFunc(ColorAlpha, ColorAlpha));
  262. ASSERT(CP_PROPS_RGBA==4);
  263. Property &rgba=_props.New().create("RGBA", MemberDesc(DATA_STR).setFunc(ColorRGBA, ColorRGBA)).desc("Color in RRGGBBAA Hexadecimal format");
  264. ASSERT(CP_PROPS_HSB==5);
  265. _props.New().create("Hue", MemberDesc(dt).setFunc(ColorHue, ColorHue));
  266. _props.New().create("Sat", MemberDesc(dt).setFunc(ColorSat, ColorSat));
  267. _props.New().create("Lum", MemberDesc(dt).setFunc(ColorLum, ColorLum));
  268. REPAO(_props).autoData(this);
  269. Rect r=AddProperties(_props, T, Vec2(_color.rect().min.x, _mode.rect().min.y-0.01f), 0.045f, 0.15f, &ColorPickerTS);
  270. rgba.textline.maxLength(8).resize(Vec2(rgba.textline.rect().h(), 0));
  271. _real=true; mode(false);
  272. return T;
  273. }
  274. /******************************************************************************/
  275. }
  276. /******************************************************************************/