ColorPicker.cs 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System;
  4. using bs;
  5. namespace bs.Editor
  6. {
  7. /** @addtogroup Windows
  8. * @{
  9. */
  10. /// <summary>
  11. /// A color picker window that allows the user to select from a gamut of colors.
  12. /// </summary>
  13. [DefaultSize(270, 400)]
  14. public class ColorPicker : ModalWindow
  15. {
  16. private const int SliderIndividualWidth = 150;
  17. private const int SliderIndividualHeight = 15;
  18. private const int ColorBoxWidth = 200;
  19. private const int ColorBoxHeight = 200;
  20. private const int SliderSideWidth = 40;
  21. private const int SliderSideHeight = 200;
  22. // Value used by Photoshop
  23. private const float MaxOverexposedValue = 191 / 255.0f;
  24. private const float MaxExposureRange = 10.0f;
  25. private float colRed, colGreen, colBlue;
  26. private float colRedHDR, colGreenHDR, colBlueHDR;
  27. private float colHue, colSaturation, colValue;
  28. private float colAlpha = 1.0f;
  29. private float exposure = 0.0f;
  30. private bool hdr = false;
  31. private ColorSlider1DHorz sliderR, sliderG, sliderB, sliderA;
  32. private ColorSlider2D colorBox;
  33. private ColorSlider1DVert sideSlider;
  34. private ColorBoxMode colorBoxMode = ColorBoxMode.BG_R;
  35. private SliderMode sliderMode = SliderMode.HSV;
  36. private GUIColorField guiColor;
  37. private GUITexture guiSlider2DTex;
  38. private GUITexture guiSliderVertTex;
  39. private GUITexture guiSliderRHorzTex;
  40. private GUITexture guiSliderGHorzTex;
  41. private GUITexture guiSliderBHorzTex;
  42. private GUITexture guiSliderAHorzTex;
  43. private GUIButton guiColorBoxBtn;
  44. private GUIButton guiColorModeBtn;
  45. private GUISliderV guiSliderVert;
  46. private GUISliderH guiSliderRHorz;
  47. private GUISliderH guiSliderGHorz;
  48. private GUISliderH guiSliderBHorz;
  49. private GUISliderH guiSliderAHorz;
  50. private GUITexture guiSlider2DHandle;
  51. private GUILabel guiLabelR;
  52. private GUILabel guiLabelG;
  53. private GUILabel guiLabelB;
  54. private GUILabel guiLabelA;
  55. private GUIIntField guiInputR;
  56. private GUIIntField guiInputG;
  57. private GUIIntField guiInputB;
  58. private GUIIntField guiInputA;
  59. private GUILabel guiLabelExposure;
  60. private GUISliderH guiSliderExposure;
  61. private GUIFloatField guiInputExposure;
  62. private GUIButton guiOK;
  63. private GUIButton guiCancel;
  64. private Action<bool, Color> closedCallback;
  65. /// <summary>
  66. /// Determines color gamut shown in the color box.
  67. /// </summary>
  68. public enum ColorBoxMode
  69. {
  70. BG_R,
  71. BR_G,
  72. RG_B,
  73. SV_H,
  74. HV_S,
  75. HS_V
  76. }
  77. /// <summary>
  78. /// Determines color gamut shown in the horizontal sliders.
  79. /// </summary>
  80. public enum SliderMode
  81. {
  82. RGB,
  83. HSV
  84. }
  85. /// <summary>
  86. /// Returns currently selected color as RGBA values.
  87. /// </summary>
  88. public Color SelectedColor
  89. {
  90. get
  91. {
  92. if(hdr)
  93. return new Color(colRedHDR, colGreenHDR, colBlueHDR, colAlpha);
  94. return new Color(colRed, colGreen, colBlue, colAlpha);
  95. }
  96. }
  97. /// <summary>
  98. /// Currently selected color, suitable for GUI display;
  99. /// </summary>
  100. private Color GUIColor
  101. {
  102. get
  103. {
  104. Color color = new Color(colRed, colGreen, colBlue, colAlpha);
  105. if (hdr)
  106. return color.Gamma;
  107. return color;
  108. }
  109. }
  110. /// <summary>
  111. /// Shows the color picker window.
  112. /// </summary>
  113. /// <param name="closedCallback">Optional callback to trigger when the user selects a color or cancels out
  114. /// of the dialog.</param>
  115. /// <param name="hdr">If true, the color intensity can be selected along with the color itself.</param>
  116. /// <returns>A. instance of the color picker window.</returns>
  117. public static ColorPicker Show(bool hdr = false, Action<bool, Color> closedCallback = null)
  118. {
  119. ColorPicker picker = new ColorPicker(Color.Black, hdr, closedCallback);
  120. return picker;
  121. }
  122. /// <summary>
  123. /// Shows the color picker window and sets the initial color to show.
  124. /// </summary>
  125. /// <param name="color">Initial color to display.</param>
  126. /// <param name="hdr">If true, the color intensity can be selected along with the color itself.</param>
  127. /// <param name="closedCallback">Optional callback to trigger when the user selects a color or cancels out
  128. /// of the dialog.</param>
  129. /// <returns>A. instance of the color picker window.</returns>
  130. public static ColorPicker Show(Color color, bool hdr = false, Action<bool, Color> closedCallback = null)
  131. {
  132. ColorPicker picker = new ColorPicker(color, hdr, closedCallback);
  133. return picker;
  134. }
  135. /// <summary>
  136. /// Constructs a new color picker window.
  137. /// </summary>
  138. /// <param name="color">Initial color to display.</param>
  139. /// <param name="hdr">If true, the color intensity can be selected along with the color itself.</param>
  140. /// <param name="closedCallback">Optional callback to trigger when the user selects a color or cancels out
  141. /// of the dialog.</param>
  142. protected ColorPicker(Color color, bool hdr, Action<bool, Color> closedCallback = null)
  143. : base(false)
  144. {
  145. Title = new LocEdString("Color Picker");
  146. colRedHDR = color.r;
  147. colGreenHDR = color.g;
  148. colBlueHDR = color.b;
  149. colAlpha = color.a;
  150. this.hdr = hdr;
  151. HDRToLDR();
  152. RGBToHSV();
  153. this.closedCallback = closedCallback;
  154. }
  155. private void OnInitialize()
  156. {
  157. guiColor = new GUIColorField();
  158. guiColor.SetWidth(100);
  159. guiSlider2DTex = new GUITexture(null, GUIOption.FixedHeight(ColorBoxHeight), GUIOption.FixedWidth(ColorBoxWidth));
  160. guiSliderVertTex = new GUITexture(null, GUIOption.FixedHeight(SliderSideHeight), GUIOption.FixedWidth(SliderSideWidth));
  161. guiSliderRHorzTex = new GUITexture(null, GUIOption.FixedHeight(SliderIndividualHeight));
  162. guiSliderGHorzTex = new GUITexture(null, GUIOption.FixedHeight(SliderIndividualHeight));
  163. guiSliderBHorzTex = new GUITexture(null, GUIOption.FixedHeight(SliderIndividualHeight));
  164. guiSliderAHorzTex = new GUITexture(null, GUIOption.FixedHeight(SliderIndividualHeight));
  165. guiColorBoxBtn = new GUIButton(colorBoxMode.ToString());
  166. guiColorModeBtn = new GUIButton(sliderMode.ToString());
  167. guiSliderVert = new GUISliderV(EditorStylesInternal.ColorSliderVert);
  168. guiSliderRHorz = new GUISliderH(EditorStylesInternal.ColorSliderHorz);
  169. guiSliderGHorz = new GUISliderH(EditorStylesInternal.ColorSliderHorz);
  170. guiSliderBHorz = new GUISliderH(EditorStylesInternal.ColorSliderHorz);
  171. guiSliderAHorz = new GUISliderH(EditorStylesInternal.ColorSliderHorz);
  172. guiSlider2DHandle = new GUITexture(null, EditorStylesInternal.ColorSlider2DHandle);
  173. guiLabelR = new GUILabel(new LocEdString("R"));
  174. guiLabelG = new GUILabel(new LocEdString("G"));
  175. guiLabelB = new GUILabel(new LocEdString("B"));
  176. guiLabelA = new GUILabel(new LocEdString("A"));
  177. guiInputR = new GUIIntField();
  178. guiInputG = new GUIIntField();
  179. guiInputB = new GUIIntField();
  180. guiInputA = new GUIIntField();
  181. guiOK = new GUIButton(new LocEdString("OK"));
  182. guiCancel = new GUIButton(new LocEdString("Cancel"));
  183. guiColorBoxBtn.OnClick += OnColorBoxModeChanged;
  184. guiColorModeBtn.OnClick += OnSliderModeChanged;
  185. guiSliderVert.OnChanged += OnSliderVertChanged;
  186. guiSliderRHorz.OnChanged += OnSliderRHorzChanged;
  187. guiSliderGHorz.OnChanged += OnSliderGHorzChanged;
  188. guiSliderBHorz.OnChanged += OnSliderBHorzChanged;
  189. guiSliderAHorz.OnChanged += OnSliderAHorzChanged;
  190. guiInputR.OnChanged += OnInputRChanged;
  191. guiInputG.OnChanged += OnInputGChanged;
  192. guiInputB.OnChanged += OnInputBChanged;
  193. guiInputA.OnChanged += OnInputAChanged;
  194. guiOK.OnClick += OnOK;
  195. guiCancel.OnClick += OnCancel;
  196. if (hdr)
  197. {
  198. guiSliderExposure = new GUISliderH();
  199. guiSliderExposure.SetRange(-MaxExposureRange, MaxExposureRange);
  200. guiSliderExposure.OnChanged += OnSliderExposureChanged;
  201. guiLabelExposure = new GUILabel(new LocEdString("Exposure"));
  202. guiInputExposure = new GUIFloatField();
  203. guiInputExposure.SetRange(-MaxExposureRange, MaxExposureRange);
  204. guiInputExposure.OnChanged += OnInputExposureChanged;
  205. }
  206. GUIPanel mainPanel = GUI.AddPanel(0);
  207. mainPanel.SetWidth(ContentWidth);
  208. mainPanel.SetHeight(ContentHeight);
  209. GUILayout v0 = mainPanel.AddLayoutY();
  210. v0.AddSpace(5);
  211. GUILayout h0 = v0.AddLayoutX();
  212. h0.AddSpace(10);
  213. h0.AddElement(guiColor);
  214. h0.AddFlexibleSpace();
  215. h0.AddElement(guiColorBoxBtn);
  216. h0.AddElement(guiColorModeBtn);
  217. h0.AddSpace(10);
  218. v0.AddSpace(10);
  219. GUILayout h1 = v0.AddLayoutX();
  220. h1.AddSpace(10);
  221. h1.AddElement(guiSlider2DTex);
  222. h1.AddFlexibleSpace();
  223. h1.AddElement(guiSliderVertTex);
  224. h1.AddSpace(10);
  225. v0.AddSpace(10);
  226. GUILayout h2 = v0.AddLayoutX();
  227. h2.AddSpace(10);
  228. h2.AddElement(guiLabelR);
  229. h2.AddFlexibleSpace();
  230. h2.AddElement(guiSliderRHorzTex);
  231. h2.AddFlexibleSpace();
  232. h2.AddElement(guiInputR);
  233. h2.AddSpace(10);
  234. v0.AddSpace(5);
  235. GUILayout h3 = v0.AddLayoutX();
  236. h3.AddSpace(10);
  237. h3.AddElement(guiLabelG);
  238. h3.AddFlexibleSpace();
  239. h3.AddElement(guiSliderGHorzTex);
  240. h3.AddFlexibleSpace();
  241. h3.AddElement(guiInputG);
  242. h3.AddSpace(10);
  243. v0.AddSpace(5);
  244. GUILayout h4 = v0.AddLayoutX();
  245. h4.AddSpace(10);
  246. h4.AddElement(guiLabelB);
  247. h4.AddFlexibleSpace();
  248. h4.AddElement(guiSliderBHorzTex);
  249. h4.AddFlexibleSpace();
  250. h4.AddElement(guiInputB);
  251. h4.AddSpace(10);
  252. v0.AddSpace(5);
  253. GUILayout h5 = v0.AddLayoutX();
  254. h5.AddSpace(10);
  255. h5.AddElement(guiLabelA);
  256. h5.AddFlexibleSpace();
  257. h5.AddElement(guiSliderAHorzTex);
  258. h5.AddFlexibleSpace();
  259. h5.AddElement(guiInputA);
  260. h5.AddSpace(10);
  261. if (hdr)
  262. {
  263. v0.AddSpace(5);
  264. GUILayout hExposure = v0.AddLayoutX();
  265. hExposure.AddSpace(10);
  266. hExposure.AddElement(guiLabelExposure);
  267. hExposure.AddFlexibleSpace();
  268. hExposure.AddElement(guiSliderExposure);
  269. hExposure.AddFlexibleSpace();
  270. hExposure.AddElement(guiInputExposure);
  271. hExposure.AddSpace(10);
  272. }
  273. v0.AddSpace(10);
  274. GUILayout h6 = v0.AddLayoutX();
  275. h6.AddFlexibleSpace();
  276. h6.AddElement(guiOK);
  277. h6.AddSpace(10);
  278. h6.AddElement(guiCancel);
  279. h6.AddFlexibleSpace();
  280. v0.AddSpace(5);
  281. GUIPanel overlay = GUI.AddPanel(-1);
  282. overlay.SetWidth(ContentWidth);
  283. overlay.SetHeight(ContentHeight);
  284. overlay.AddElement(guiSliderVert);
  285. overlay.AddElement(guiSliderRHorz);
  286. overlay.AddElement(guiSliderGHorz);
  287. overlay.AddElement(guiSliderBHorz);
  288. overlay.AddElement(guiSliderAHorz);
  289. overlay.AddElement(guiSlider2DHandle);
  290. colorBox = new ColorSlider2D(guiSlider2DTex, guiSlider2DHandle, ColorBoxWidth, ColorBoxHeight);
  291. sideSlider = new ColorSlider1DVert(guiSliderVertTex, guiSliderVert, SliderSideWidth, SliderSideHeight);
  292. sliderR = new ColorSlider1DHorz(guiSliderRHorzTex, guiSliderRHorz, SliderIndividualWidth, SliderIndividualHeight);
  293. sliderG = new ColorSlider1DHorz(guiSliderGHorzTex, guiSliderGHorz, SliderIndividualWidth, SliderIndividualHeight);
  294. sliderB = new ColorSlider1DHorz(guiSliderBHorzTex, guiSliderBHorz, SliderIndividualWidth, SliderIndividualHeight);
  295. sliderA = new ColorSlider1DHorz(guiSliderAHorzTex, guiSliderAHorz, SliderIndividualWidth, SliderIndividualHeight);
  296. colorBox.OnValueChanged += OnColorBoxValueChanged;
  297. Color startA = new Color(0, 0, 0, 1);
  298. Color stepA = new Color(1, 1, 1, 0);
  299. sliderA.UpdateTexture(startA, stepA, false, false);
  300. guiInputA.SetRange(0, 255);
  301. guiInputA.Value = 255;
  302. guiSliderAHorz.Percent = 1.0f;
  303. guiColor.Value = GUIColor;
  304. UpdateInputBoxValues();
  305. Update2DSliderValues();
  306. Update1DSliderValues();
  307. UpdateSliderMode();
  308. Update2DSliderTextures();
  309. Update1DSliderTextures();
  310. }
  311. private void OnEditorUpdate()
  312. {
  313. Vector2I windowPos = ScreenToWindowPos(Input.PointerPosition);
  314. colorBox.UpdateInput(windowPos);
  315. }
  316. /// <summary>
  317. /// Fills a 2D area with colors using the provided starting point and gradients.
  318. /// </summary>
  319. /// <param name="width">Width of the area to fill.</param>
  320. /// <param name="height">Height of the area to fill.</param>
  321. /// <param name="colors">Array to contain the output. Must be of
  322. /// <paramref name="width"/>*<paramref name="height"/> size.</param>
  323. /// <param name="start">Initial color in the top-left corner of the area.</param>
  324. /// <param name="rightGradient">Gradient towards which the colors increase to the right of the area.</param>
  325. /// <param name="downGradient">Gradient towards which the colors increase to the bottom of the area.</param>
  326. private static void FillArea(int width, int height, Color[] colors, Color start, Color rightGradient, Color downGradient)
  327. {
  328. Color rightDelta = new Color(0, 0, 0, 0);
  329. if (width > 1)
  330. rightDelta = rightGradient / (width - 1);
  331. Color downDelta = new Color(0, 0, 0, 0);
  332. if (height > 1)
  333. downDelta = downGradient / (height - 1);
  334. Color verticalColor = start;
  335. for (int y = 0; y < height; y++)
  336. {
  337. int rowIdx = (height - y - 1) * width;
  338. Color currentColor = verticalColor;
  339. for (int x = 0; x < width; x++)
  340. {
  341. colors[rowIdx + x] = currentColor;
  342. currentColor += rightDelta;
  343. }
  344. verticalColor += downDelta;
  345. }
  346. }
  347. /// <summary>
  348. /// Decomposes a HDR RGB color into a normalized RGB color and an exposure value.
  349. /// </summary>
  350. /// <param name="hdrColor">Input HDR color to decompose.</param>
  351. /// <param name="exposure">Output exposure value of the color.</param>
  352. /// <returns>Output normalized RGB color.</returns>
  353. private static Color DecomposeHDR(Color hdrColor, out float exposure)
  354. {
  355. // Note: Replicating Photoshop's behaviour
  356. float maxColorComponent = MathEx.Max(hdrColor.r, hdrColor.g, hdrColor.b);
  357. if (maxColorComponent == 0.0f || (maxColorComponent >= 1.0f / 255.0f && maxColorComponent < 1.0f))
  358. {
  359. exposure = 0.0f;
  360. return hdrColor;
  361. }
  362. else
  363. {
  364. float scaleFactor = MaxOverexposedValue / maxColorComponent;
  365. exposure = MathEx.Log(1.0f / scaleFactor) / MathEx.Log(2);
  366. Color output = new Color();
  367. output.r = MathEx.Min(MaxOverexposedValue, scaleFactor * hdrColor.r);
  368. output.g = MathEx.Min(MaxOverexposedValue, scaleFactor * hdrColor.g);
  369. output.b = MathEx.Min(MaxOverexposedValue, scaleFactor * hdrColor.b);
  370. output.a = hdrColor.a;
  371. return output;
  372. }
  373. }
  374. /// <summary>
  375. /// Converts the currently selected HDR RGB color into normalized [0-1] range. This is a no-op if HDR is not
  376. /// enabled on the slider.
  377. /// </summary>
  378. void HDRToLDR()
  379. {
  380. if (hdr)
  381. {
  382. Color ldrColor = DecomposeHDR(
  383. new Color(colRedHDR, colGreenHDR, colBlueHDR, colAlpha),
  384. out exposure);
  385. colRed = ldrColor.r;
  386. colGreen = ldrColor.g;
  387. colBlue = ldrColor.b;
  388. }
  389. else
  390. {
  391. colRed = colRedHDR;
  392. colGreen = colGreenHDR;
  393. colBlue = colBlueHDR;
  394. }
  395. }
  396. /// <summary>
  397. /// Converts the currently selected RGB color to an HDR color using the current exposure value.
  398. /// </summary>
  399. void LDRToHDR()
  400. {
  401. if (hdr)
  402. {
  403. colRedHDR = colRed * MathEx.Pow(2.0f, exposure);
  404. colGreenHDR = colGreen * MathEx.Pow(2.0f, exposure);
  405. colBlueHDR = colBlue * MathEx.Pow(2.0f, exposure);
  406. }
  407. else
  408. {
  409. colRedHDR = colRed;
  410. colGreenHDR = colGreen;
  411. colBlueHDR = colBlue;
  412. }
  413. }
  414. /// <summary>
  415. /// Converts the currently selected color from HSV to RGB color space.
  416. /// </summary>
  417. void HSVToRGB()
  418. {
  419. Color hsv = new Color(colHue, colSaturation, colValue);
  420. Color rgb = Color.HSV2RGB(hsv);
  421. colRed = rgb.r;
  422. colGreen = rgb.g;
  423. colBlue = rgb.b;
  424. }
  425. /// <summary>
  426. /// Converts the currently selected color from RGB to HSV color space.
  427. /// </summary>
  428. void RGBToHSV()
  429. {
  430. Color rgb = new Color(colRed, colGreen, colBlue);
  431. Color hsv = Color.RGB2HSV(rgb);
  432. colHue = hsv.r;
  433. colSaturation = hsv.g;
  434. colValue = hsv.b;
  435. }
  436. /// <summary>
  437. /// Triggered when the user selects a new mode for the color box, changing the gamut of colors displayed in the box.
  438. /// </summary>
  439. void OnColorBoxModeChanged()
  440. {
  441. int maxModes = Enum.GetNames(colorBoxMode.GetType()).Length;
  442. colorBoxMode = (ColorBoxMode)(((int)colorBoxMode + 1) % maxModes);
  443. guiColorBoxBtn.SetContent(colorBoxMode.ToString());
  444. Update2DSliderTextures();
  445. Update2DSliderValues();
  446. }
  447. /// <summary>
  448. /// Triggered when the user selects a new mode for the side slider, changing the gamut of colors displayed in the
  449. /// slider.
  450. /// </summary>
  451. void OnSliderModeChanged()
  452. {
  453. int maxModes = Enum.GetNames(sliderMode.GetType()).Length;
  454. sliderMode = (SliderMode)(((int)sliderMode + 1) % maxModes);
  455. UpdateSliderMode();
  456. guiColorModeBtn.SetContent(sliderMode.ToString());
  457. UpdateInputBoxValues();
  458. Update1DSliderTextures();
  459. Update1DSliderValues();
  460. }
  461. /// <summary>
  462. /// Triggered when the user selects a color in the color box.
  463. /// </summary>
  464. /// <param name="value">Location on the color box that was selected.</param>
  465. void OnColorBoxValueChanged(Vector2 value)
  466. {
  467. switch (colorBoxMode)
  468. {
  469. case ColorBoxMode.BG_R:
  470. colBlue = value.x;
  471. colGreen = value.y;
  472. RGBToHSV();
  473. break;
  474. case ColorBoxMode.BR_G:
  475. colBlue = value.x;
  476. colRed = value.y;
  477. RGBToHSV();
  478. break;
  479. case ColorBoxMode.RG_B:
  480. colRed = value.x;
  481. colGreen = value.y;
  482. RGBToHSV();
  483. break;
  484. case ColorBoxMode.SV_H:
  485. colSaturation = value.x;
  486. colValue = value.y;
  487. HSVToRGB();
  488. break;
  489. case ColorBoxMode.HV_S:
  490. colHue = value.x;
  491. colValue = value.y;
  492. HSVToRGB();
  493. break;
  494. case ColorBoxMode.HS_V:
  495. colHue = value.x;
  496. colSaturation = value.y;
  497. HSVToRGB();
  498. break;
  499. }
  500. LDRToHDR();
  501. guiColor.Value = GUIColor;
  502. UpdateInputBoxValues();
  503. Update1DSliderTextures();
  504. Update1DSliderValues();
  505. UpdateSideSliderTexture();
  506. Vector2 xy;
  507. float z;
  508. GetColorBoxValues(out xy, out z);
  509. guiSliderVert.Percent = 1.0f - z;
  510. }
  511. /// <summary>
  512. /// Triggered when the user moves the side slider.
  513. /// </summary>
  514. /// <param name="percent">New value of the slider.</param>
  515. void OnSliderVertChanged(float percent)
  516. {
  517. percent = 1.0f - percent;
  518. switch (colorBoxMode)
  519. {
  520. case ColorBoxMode.BG_R:
  521. colRed = percent;
  522. RGBToHSV();
  523. break;
  524. case ColorBoxMode.BR_G:
  525. colGreen = percent;
  526. RGBToHSV();
  527. break;
  528. case ColorBoxMode.RG_B:
  529. colBlue = percent;
  530. RGBToHSV();
  531. break;
  532. case ColorBoxMode.SV_H:
  533. colHue = percent;
  534. HSVToRGB();
  535. break;
  536. case ColorBoxMode.HV_S:
  537. colSaturation = percent;
  538. HSVToRGB();
  539. break;
  540. case ColorBoxMode.HS_V:
  541. colValue = percent;
  542. HSVToRGB();
  543. break;
  544. }
  545. LDRToHDR();
  546. guiColor.Value = GUIColor;
  547. UpdateInputBoxValues();
  548. Update1DSliderTextures();
  549. Update1DSliderValues();
  550. }
  551. /// <summary>
  552. /// Triggered when the user moves the horizontal Red/Hue slider.
  553. /// </summary>
  554. /// <param name="percent">New value of the slider.</param>
  555. void OnSliderRHorzChanged(float percent)
  556. {
  557. bool isHSV = sliderMode == SliderMode.HSV;
  558. if (isHSV)
  559. {
  560. colHue = percent;
  561. HSVToRGB();
  562. }
  563. else
  564. {
  565. colRed = percent;
  566. RGBToHSV();
  567. }
  568. LDRToHDR();
  569. guiColor.Value = GUIColor;
  570. UpdateInputBoxValues();
  571. Update2DSliderTextures();
  572. Update2DSliderValues();
  573. }
  574. /// <summary>
  575. /// Triggered when the user moves the horizontal Green/Saturation slider.
  576. /// </summary>
  577. /// <param name="percent">New value of the slider.</param>
  578. void OnSliderGHorzChanged(float percent)
  579. {
  580. bool isHSV = sliderMode == SliderMode.HSV;
  581. if (isHSV)
  582. {
  583. colSaturation = percent;
  584. HSVToRGB();
  585. }
  586. else
  587. {
  588. colGreen = percent;
  589. RGBToHSV();
  590. }
  591. LDRToHDR();
  592. guiColor.Value = GUIColor;
  593. UpdateInputBoxValues();
  594. Update2DSliderTextures();
  595. Update2DSliderValues();
  596. }
  597. /// <summary>
  598. /// Triggered when the user moves the horizontal Blue/Value slider.
  599. /// </summary>
  600. /// <param name="percent">New value of the slider.</param>
  601. void OnSliderBHorzChanged(float percent)
  602. {
  603. bool isHSV = sliderMode == SliderMode.HSV;
  604. if (isHSV)
  605. {
  606. colValue = percent;
  607. HSVToRGB();
  608. }
  609. else
  610. {
  611. colBlue = percent;
  612. RGBToHSV();
  613. }
  614. LDRToHDR();
  615. guiColor.Value = GUIColor;
  616. UpdateInputBoxValues();
  617. Update2DSliderTextures();
  618. Update2DSliderValues();
  619. }
  620. /// <summary>
  621. /// Triggered when the user moves the horizontal alpha slider.
  622. /// </summary>
  623. /// <param name="percent">New value of the slider.</param>
  624. void OnSliderAHorzChanged(float percent)
  625. {
  626. colAlpha = percent;
  627. guiColor.Value = GUIColor;
  628. guiInputA.Value = MathEx.RoundToInt(colAlpha * 255.0f);
  629. }
  630. /// <summary>
  631. /// Triggered when the user inputs new value in the Red/Hue input box.
  632. /// </summary>
  633. /// <param name="value">New value in the input box.</param>
  634. void OnInputRChanged(int value)
  635. {
  636. bool isHSV = sliderMode == SliderMode.HSV;
  637. if (isHSV)
  638. {
  639. colHue = value/359.0f;
  640. HSVToRGB();
  641. }
  642. else
  643. {
  644. colRed = value/255.0f;
  645. RGBToHSV();
  646. }
  647. LDRToHDR();
  648. guiColor.Value = GUIColor;
  649. Update1DSliderValues();
  650. Update2DSliderTextures();
  651. Update2DSliderValues();
  652. }
  653. /// <summary>
  654. /// Triggered when the user inputs new value in the Green/Saturation input box.
  655. /// </summary>
  656. /// <param name="value">New value in the input box.</param>
  657. void OnInputGChanged(int value)
  658. {
  659. bool isHSV = sliderMode == SliderMode.HSV;
  660. if (isHSV)
  661. {
  662. colSaturation = value / 255.0f;
  663. HSVToRGB();
  664. }
  665. else
  666. {
  667. colGreen = value / 255.0f;
  668. RGBToHSV();
  669. }
  670. LDRToHDR();
  671. guiColor.Value = GUIColor;
  672. Update1DSliderValues();
  673. Update2DSliderTextures();
  674. Update2DSliderValues();
  675. }
  676. /// <summary>
  677. /// Triggered when the user inputs new value in the Blue/Value input box.
  678. /// </summary>
  679. /// <param name="value">New value in the input box.</param>
  680. void OnInputBChanged(int value)
  681. {
  682. bool isHSV = sliderMode == SliderMode.HSV;
  683. if (isHSV)
  684. {
  685. colValue = value / 255.0f;
  686. HSVToRGB();
  687. }
  688. else
  689. {
  690. colBlue = value / 255.0f;
  691. RGBToHSV();
  692. }
  693. LDRToHDR();
  694. guiColor.Value = GUIColor;
  695. Update1DSliderValues();
  696. Update2DSliderTextures();
  697. Update2DSliderValues();
  698. }
  699. /// <summary>
  700. /// Triggered when the user inputs new value in the alpha input box.
  701. /// </summary>
  702. /// <param name="value">New value in the input box.</param>
  703. void OnInputAChanged(int value)
  704. {
  705. colAlpha = value/255.0f;
  706. guiColor.Value = GUIColor;
  707. guiSliderAHorz.Percent = colAlpha;
  708. }
  709. /// <summary>
  710. /// Triggered when the exposure slider changes.
  711. /// </summary>
  712. /// <param name="value">New exposure value.</param>
  713. void OnSliderExposureChanged(float value)
  714. {
  715. exposure = value;
  716. LDRToHDR();
  717. guiSliderExposure.Value = value;
  718. }
  719. /// <summary>
  720. /// Triggered when user inputs new value in the exposure input box.
  721. /// </summary>
  722. /// <param name="value">New exposure value.</param>
  723. void OnInputExposureChanged(float value)
  724. {
  725. exposure = value;
  726. LDRToHDR();
  727. guiInputExposure.Value = value;
  728. }
  729. /// <summary>
  730. /// Triggered when the user selects a color and closes the dialog.
  731. /// </summary>
  732. void OnOK()
  733. {
  734. if (closedCallback != null)
  735. closedCallback(true, SelectedColor);
  736. Close();
  737. }
  738. /// <summary>
  739. /// Triggered when the user cancels color selection and closes the dialog.
  740. /// </summary>
  741. void OnCancel()
  742. {
  743. if (closedCallback != null)
  744. closedCallback(false, SelectedColor);
  745. Close();
  746. }
  747. /// <summary>
  748. /// Updates Red/Green/Blue or Hue/Saturation/Value labels and input box ranges depending on currently active mode.
  749. /// </summary>
  750. void UpdateSliderMode()
  751. {
  752. if (sliderMode == SliderMode.RGB)
  753. {
  754. guiLabelR.SetContent(new LocEdString("R"));
  755. guiLabelG.SetContent(new LocEdString("G"));
  756. guiLabelB.SetContent(new LocEdString("B"));
  757. guiInputR.SetRange(0, 255);
  758. guiInputG.SetRange(0, 255);
  759. guiInputB.SetRange(0, 255);
  760. }
  761. else
  762. {
  763. guiLabelR.SetContent(new LocEdString("H"));
  764. guiLabelG.SetContent(new LocEdString("S"));
  765. guiLabelB.SetContent(new LocEdString("V"));
  766. guiInputR.SetRange(0, 359);
  767. guiInputG.SetRange(0, 255);
  768. guiInputB.SetRange(0, 255);
  769. }
  770. }
  771. /// <summary>
  772. /// Updates Red/Green/Blue or Hue/Saturation/Value input boxes with currently selected color.
  773. /// </summary>
  774. void UpdateInputBoxValues()
  775. {
  776. bool isHSV = sliderMode == SliderMode.HSV;
  777. if (isHSV)
  778. {
  779. guiInputR.Value = MathEx.RoundToInt(colHue * 359.0f);
  780. guiInputG.Value = MathEx.RoundToInt(colSaturation * 255.0f);
  781. guiInputB.Value = MathEx.RoundToInt(colValue * 255.0f);
  782. }
  783. else
  784. {
  785. guiInputR.Value = MathEx.RoundToInt(colRed * 255.0f);
  786. guiInputG.Value = MathEx.RoundToInt(colGreen * 255.0f);
  787. guiInputB.Value = MathEx.RoundToInt(colBlue * 255.0f);
  788. }
  789. if (hdr)
  790. guiInputExposure.Value = exposure;
  791. }
  792. /// <summary>
  793. /// Updates Red/Green/Blue or Hue/Saturation/Value sliders with currently selected color.
  794. /// </summary>
  795. void Update1DSliderValues()
  796. {
  797. bool isHSV = sliderMode == SliderMode.HSV;
  798. if (isHSV)
  799. {
  800. guiSliderRHorz.Percent = colHue;
  801. guiSliderGHorz.Percent = colSaturation;
  802. guiSliderBHorz.Percent = colValue;
  803. }
  804. else
  805. {
  806. guiSliderRHorz.Percent = colRed;
  807. guiSliderGHorz.Percent = colGreen;
  808. guiSliderBHorz.Percent = colBlue;
  809. }
  810. if (hdr)
  811. guiSliderExposure.Value = exposure;
  812. }
  813. /// <summary>
  814. /// Returns the current color in the form of color box and side slider coordinates.
  815. /// </summary>
  816. /// <param name="xy">Coordinates on the color box the current color is located on.</param>
  817. /// <param name="z">Coordinates on the side slider the current color is located on.</param>
  818. void GetColorBoxValues(out Vector2 xy, out float z)
  819. {
  820. xy = Vector2.Zero;
  821. z = 0.0f;
  822. switch (colorBoxMode)
  823. {
  824. case ColorBoxMode.BG_R:
  825. xy.x = colBlue;
  826. xy.y = colGreen;
  827. z = colRed;
  828. break;
  829. case ColorBoxMode.BR_G:
  830. xy.x = colBlue;
  831. xy.y = colRed;
  832. z = colGreen;
  833. break;
  834. case ColorBoxMode.RG_B:
  835. xy.x = colRed;
  836. xy.y = colGreen;
  837. z = colBlue;
  838. break;
  839. case ColorBoxMode.SV_H:
  840. xy.x = colSaturation;
  841. xy.y = colValue;
  842. z = colHue;
  843. break;
  844. case ColorBoxMode.HV_S:
  845. xy.x = colHue;
  846. xy.y = colValue;
  847. z = colSaturation;
  848. break;
  849. case ColorBoxMode.HS_V:
  850. xy.x = colHue;
  851. xy.y = colSaturation;
  852. z = colValue;
  853. break;
  854. }
  855. }
  856. /// <summary>
  857. /// Updates values of the color box and side slider according to the current color.
  858. /// </summary>
  859. void Update2DSliderValues()
  860. {
  861. Vector2 xy = Vector2.Zero;
  862. float z = 0.0f;
  863. GetColorBoxValues(out xy, out z);
  864. colorBox.SetValue(xy);
  865. guiSliderVert.Percent = z;
  866. }
  867. /// <summary>
  868. /// Generates textures to display for all horizontal (RGB/HSV) sliders depending on active slider mode.
  869. /// </summary>
  870. void Update1DSliderTextures()
  871. {
  872. bool isHSV = sliderMode == SliderMode.HSV;
  873. if (isHSV)
  874. {
  875. Color startH = new Color(0, 1, 1);
  876. Color stepH = new Color(1, 0, 0, 0);
  877. sliderR.UpdateTexture(startH, stepH, true, false);
  878. Color startS = new Color(colHue, 0, MathEx.Max(colValue, 0.2f));
  879. Color stepS = new Color(0, 1, 0, 0);
  880. sliderG.UpdateTexture(startS, stepS, true, false);
  881. Color startV = new Color(colHue, colSaturation, 0);
  882. Color stepV = new Color(0, 0, 1, 0);
  883. sliderB.UpdateTexture(startV, stepV, true, false);
  884. }
  885. else
  886. {
  887. Color startR = new Color(0, colGreen, colBlue);
  888. Color stepR = new Color(1, 0, 0, 0);
  889. sliderR.UpdateTexture(startR, stepR, false, hdr);
  890. Color startG = new Color(colRed, 0, colBlue);
  891. Color stepG = new Color(0, 1, 0, 0);
  892. sliderG.UpdateTexture(startG, stepG, false, hdr);
  893. Color startB = new Color(colRed, colGreen, 0);
  894. Color stepB = new Color(0, 0, 1, 0);
  895. sliderB.UpdateTexture(startB, stepB, false, hdr);
  896. }
  897. }
  898. /// <summary>
  899. /// Generates a texture for the side slider depending on active color box mode.
  900. /// </summary>
  901. void UpdateSideSliderTexture()
  902. {
  903. switch (colorBoxMode)
  904. {
  905. case ColorBoxMode.BG_R:
  906. sideSlider.UpdateTexture(new Color(0, colGreen, colBlue, 1), new Color(1, 0, 0, 0), false, hdr);
  907. break;
  908. case ColorBoxMode.BR_G:
  909. sideSlider.UpdateTexture(new Color(colRed, 0, colBlue, 1), new Color(0, 1, 0, 0), false, hdr);
  910. break;
  911. case ColorBoxMode.RG_B:
  912. sideSlider.UpdateTexture(new Color(colRed, colGreen, 0, 1), new Color(0, 0, 1, 0), false, hdr);
  913. break;
  914. case ColorBoxMode.SV_H:
  915. sideSlider.UpdateTexture(new Color(0, 1, 1, 1), new Color(1, 0, 0, 0), true, false);
  916. break;
  917. case ColorBoxMode.HV_S:
  918. sideSlider.UpdateTexture(new Color(colHue, 0, MathEx.Max(colValue, 0.2f), 1), new Color(0, 1, 0, 0), true, false);
  919. break;
  920. case ColorBoxMode.HS_V:
  921. sideSlider.UpdateTexture(new Color(colHue, colSaturation, 0, 1), new Color(0, 0, 1, 0), true, false);
  922. break;
  923. }
  924. }
  925. /// <summary>
  926. /// Generates textures for the color box and the side slider depending on active color box mode.
  927. /// </summary>
  928. void Update2DSliderTextures()
  929. {
  930. UpdateSideSliderTexture();
  931. float[] valueLookup = new float[] { colRed, colGreen, colBlue, colHue, colSaturation, colValue };
  932. colorBox.UpdateTexture(colorBoxMode, valueLookup[(int)colorBoxMode]);
  933. }
  934. /// <summary>
  935. /// Manages GUI for a 1D horizontal slider (used RGB/HSV display).
  936. /// </summary>
  937. public class ColorSlider1DHorz
  938. {
  939. private const int SLIDER_X_OFFSET = 3;
  940. private const int SLIDER_Y_OFFSET = 5;
  941. private int width, height;
  942. private Texture texture;
  943. private SpriteTexture spriteTexture;
  944. private GUITexture guiTexture;
  945. private GUISliderH guiSlider;
  946. /// <summary>
  947. /// Creates a new horizontal slider.
  948. /// </summary>
  949. /// <param name="guiTexture">GUI element to display the slider color range on.</param>
  950. /// <param name="guiSlider">Slider rendered on top of the texture that may be moved by the user to select a
  951. /// color.</param>
  952. /// <param name="width">Width of the slider in pixels.</param>
  953. /// <param name="height">Height of the slider in pixels.</param>
  954. public ColorSlider1DHorz(GUITexture guiTexture, GUISliderH guiSlider, int width, int height)
  955. {
  956. this.width = width;
  957. this.height = height;
  958. this.guiTexture = guiTexture;
  959. this.guiSlider = guiSlider;
  960. texture = Texture.Create2D(width, height);
  961. spriteTexture = new SpriteTexture(texture);
  962. }
  963. /// <summary>
  964. /// Updates the displayed texture with specified color information.
  965. /// </summary>
  966. /// <param name="start">Initial color on the left of the slider.</param>
  967. /// <param name="step">Final color to the right of the slider.</param>
  968. /// <param name="isHSV">Determines are the provided colors in RGB or HSV space.</param>
  969. /// <param name="isLinear">True if the provided colors are in linear color space.</param>
  970. public void UpdateTexture(Color start, Color step, bool isHSV, bool isLinear)
  971. {
  972. Color[] colors = new Color[width * height];
  973. FillArea(width, height, colors, start, step, new Color(0, 0, 0, 0));
  974. if (isHSV)
  975. {
  976. for (int i = 0; i < colors.Length; i++)
  977. colors[i] = Color.HSV2RGB(colors[i]);
  978. }
  979. else
  980. {
  981. // If RGB, convert to gamma space if needed
  982. if (isLinear)
  983. {
  984. for (int i = 0; i < colors.Length; i++)
  985. colors[i] = colors[i].Gamma;
  986. }
  987. }
  988. texture.SetPixels(colors);
  989. guiTexture.SetTexture(spriteTexture);
  990. Rect2I sliderBounds = guiTexture.Bounds;
  991. sliderBounds.x -= SLIDER_X_OFFSET;
  992. sliderBounds.width += SLIDER_X_OFFSET * 2;
  993. sliderBounds.y -= SLIDER_Y_OFFSET;
  994. sliderBounds.height += SLIDER_Y_OFFSET;
  995. guiSlider.Bounds = sliderBounds;
  996. }
  997. }
  998. /// <summary>
  999. /// Manages GUI for a 1D vertical slider (side slider along with the color box).
  1000. /// </summary>
  1001. public class ColorSlider1DVert
  1002. {
  1003. private const int SLIDER_X_OFFSET = 5;
  1004. private const int SLIDER_Y_OFFSET = 3;
  1005. private int width, height;
  1006. private Texture texture;
  1007. private SpriteTexture spriteTexture;
  1008. private GUITexture guiTexture;
  1009. private GUISliderV guiSlider;
  1010. /// <summary>
  1011. /// Creates a new vertical slider.
  1012. /// </summary>
  1013. /// <param name="guiTexture">GUI element to display the slider color range on.</param>
  1014. /// <param name="guiSlider">Slider rendered on top of the texture that may be moved by the user to select a
  1015. /// color.</param>
  1016. /// <param name="width">Width of the slider in pixels.</param>
  1017. /// <param name="height">Height of the slider in pixels.</param>
  1018. public ColorSlider1DVert(GUITexture guiTexture, GUISliderV guiSlider, int width, int height)
  1019. {
  1020. this.width = width;
  1021. this.height = height;
  1022. this.guiTexture = guiTexture;
  1023. this.guiSlider = guiSlider;
  1024. texture = Texture.Create2D(width, height);
  1025. spriteTexture = new SpriteTexture(texture);
  1026. }
  1027. /// <summary>
  1028. /// Updates the displayed texture with specified color information.
  1029. /// </summary>
  1030. /// <param name="start">Initial color on the top of the slider.</param>
  1031. /// <param name="step">Final color to the bottom of the slider.</param>
  1032. /// <param name="isHSV">Determines are the provided colors in RGB or HSV space.</param>
  1033. /// <param name="isLinear">True if the provided colors are in linear color space.</param>
  1034. public void UpdateTexture(Color start, Color step, bool isHSV, bool isLinear)
  1035. {
  1036. Color[] colors = new Color[width * height];
  1037. FillArea(width, height, colors, start, new Color(0, 0, 0, 0), step);
  1038. if (isHSV)
  1039. {
  1040. for (int i = 0; i < colors.Length; i++)
  1041. colors[i] = Color.HSV2RGB(colors[i]);
  1042. }
  1043. else
  1044. {
  1045. // If RGB, convert to gamma space if needed
  1046. if (isLinear)
  1047. {
  1048. for (int i = 0; i < colors.Length; i++)
  1049. colors[i] = colors[i].Gamma;
  1050. }
  1051. }
  1052. texture.SetPixels(colors);
  1053. guiTexture.SetTexture(spriteTexture);
  1054. Rect2I sliderBounds = guiTexture.Bounds;
  1055. sliderBounds.x -= SLIDER_X_OFFSET;
  1056. sliderBounds.width += SLIDER_X_OFFSET;
  1057. sliderBounds.y -= SLIDER_Y_OFFSET;
  1058. sliderBounds.height += SLIDER_Y_OFFSET * 2;
  1059. guiSlider.Bounds = sliderBounds;
  1060. }
  1061. }
  1062. /// <summary>
  1063. /// Manages GUI for a 2D color box, as well as manually handling color box input. Color box serves as a 2D sliders
  1064. /// as you can portion of it to select a color.
  1065. /// </summary>
  1066. public class ColorSlider2D
  1067. {
  1068. private int width, height;
  1069. private Texture texture;
  1070. private SpriteTexture spriteTexture;
  1071. private GUITexture guiTexture;
  1072. private GUITexture guiSliderHandle;
  1073. private Vector2 oldValue = new Vector2(-1, -1);
  1074. public delegate void OnValueChangedDelegate(Vector2 value);
  1075. public event OnValueChangedDelegate OnValueChanged;
  1076. /// <summary>
  1077. /// Creates a new color box.
  1078. /// </summary>
  1079. /// <param name="guiTexture">GUI element to display the 2D color range on.</param>
  1080. /// <param name="guiSliderHandle">Texture to be used for displaying the position of the currently selected
  1081. /// color.</param>
  1082. /// <param name="width">Width of the slider in pixels.</param>
  1083. /// <param name="height">Height of the slider in pixels.</param>
  1084. public ColorSlider2D(GUITexture guiTexture, GUITexture guiSliderHandle, int width, int height)
  1085. {
  1086. this.width = width;
  1087. this.height = height;
  1088. this.guiTexture = guiTexture;
  1089. this.guiSliderHandle = guiSliderHandle;
  1090. texture = Texture.Create2D(width, height);
  1091. spriteTexture = new SpriteTexture(texture);
  1092. }
  1093. /// <summary>
  1094. /// Updates the texture displayed on the color box.
  1095. /// </summary>
  1096. /// <param name="mode">Mode determining the color gamut shown in the color box.</param>
  1097. /// <param name="value">Value of the third component (normally retrieved from the separate side slider).</param>
  1098. public void UpdateTexture(ColorBoxMode mode, float value)
  1099. {
  1100. Color[] colors = new Color[width * height];
  1101. switch (mode)
  1102. {
  1103. case ColorBoxMode.BG_R:
  1104. FillArea(width, height, colors, new Color(value, 0, 0, 1), new Color(0, 0, 1, 0), new Color(0, 1, 0, 0));
  1105. break;
  1106. case ColorBoxMode.BR_G:
  1107. FillArea(width, height, colors, new Color(0, value, 0, 1), new Color(0, 0, 1, 0), new Color(1, 0, 0, 0));
  1108. break;
  1109. case ColorBoxMode.RG_B:
  1110. FillArea(width, height, colors, new Color(0, 0, value, 1), new Color(1, 0, 0, 0), new Color(0, 1, 0, 0));
  1111. break;
  1112. case ColorBoxMode.SV_H:
  1113. FillArea(width, height, colors, new Color(value, 0, 0, 1), new Color(0, 1, 0, 0), new Color(0, 0, 1, 0));
  1114. for (int i = 0; i < colors.Length; i++)
  1115. colors[i] = Color.HSV2RGB(colors[i]);
  1116. break;
  1117. case ColorBoxMode.HV_S:
  1118. FillArea(width, height, colors, new Color(0, value, 0, 1), new Color(1, 0, 0, 0), new Color(0, 0, 1, 0));
  1119. for (int i = 0; i < colors.Length; i++)
  1120. colors[i] = Color.HSV2RGB(colors[i]);
  1121. break;
  1122. case ColorBoxMode.HS_V:
  1123. FillArea(width, height, colors, new Color(0, 0, value, 1), new Color(1, 0, 0, 0), new Color(0, 1, 0, 0));
  1124. for (int i = 0; i < colors.Length; i++)
  1125. colors[i] = Color.HSV2RGB(colors[i]);
  1126. break;
  1127. }
  1128. texture.SetPixels(colors);
  1129. guiTexture.SetTexture(spriteTexture);
  1130. }
  1131. /// <summary>
  1132. /// Handles input over the color box, moving the handle as needed.
  1133. /// </summary>
  1134. /// <param name="windowPos">Position of the pointer relative to the color picker window.</param>
  1135. public void UpdateInput(Vector2I windowPos)
  1136. {
  1137. if (Input.IsPointerButtonHeld(PointerButton.Left))
  1138. {
  1139. Rect2I bounds = guiTexture.Bounds;
  1140. if (bounds.Contains(windowPos))
  1141. {
  1142. Vector2 newValue = Vector2.Zero;
  1143. newValue.x = (windowPos.x - bounds.x) / (float)bounds.width;
  1144. newValue.y = 1.0f - (windowPos.y - bounds.y) / (float)bounds.height;
  1145. SetValue(newValue);
  1146. }
  1147. }
  1148. }
  1149. /// <summary>
  1150. /// Moves the handle to a specific location on the color box and selects that color.
  1151. /// </summary>
  1152. /// <param name="value">Coordinates relative to the color box.</param>
  1153. public void SetValue(Vector2 value)
  1154. {
  1155. Vector2 pos = value;
  1156. pos.y = 1.0f - pos.y;
  1157. if (oldValue == value)
  1158. return;
  1159. Rect2I handleBounds = guiSliderHandle.Bounds;
  1160. Rect2I boxBounds = guiTexture.Bounds;
  1161. handleBounds.x = boxBounds.x + MathEx.RoundToInt(pos.x * boxBounds.width) - handleBounds.width / 2;
  1162. handleBounds.y = boxBounds.y + MathEx.RoundToInt(pos.y * boxBounds.height) - handleBounds.height / 2;
  1163. guiSliderHandle.Bounds = handleBounds;
  1164. oldValue = value;
  1165. if (OnValueChanged != null)
  1166. OnValueChanged(value);
  1167. }
  1168. }
  1169. }
  1170. /** @} */
  1171. }