7 public struct ColorRGB { float r, g, b; };
8 public struct ColorRGBAf
14 set { this = ColorRGBAf { value.color.r/255.0f, value.color.g/255.0f, value.color.b/255.0f, value.a/255.0f }; }
15 get { return ColorAlpha { (byte)(a * 255), Color { (byte)(r * 255), (byte)(g * 255), (byte)(b * 255) } }; }
19 set { this = ColorRGBAf { value.r/255.0f, value.g/255.0f, value.b/255.0f, 1.0f }; }
20 get { return Color { (byte)(r * 255), (byte)(g * 255), (byte)(b * 255) }; }
24 public class Color : uint
27 byte r:8:16, g:8:8, b:8:0;
30 get { value = ColorRGB { r/255.0f, g/255.0f, b/255.0f }; }
31 set { return Color { (byte)(value.r*255), (byte)(value.g*255), (byte)(value.b*255) }; }
34 bool OnSaveEdit(DropBox dropBox, void * object)
36 return dropBox.Save();
39 Window OnEdit(Window dataBox, Window master, int x, int y, int w, int h, Window control)
43 ColorDropBox colorDropBox
45 dataBox, master = master, editText = true, //position = Point { x + 24, y }, /*clientSize.h = */size.h = h, size.w = w - 24,
46 anchor = { left = 24, top = 0, right = 0, bottom = 0 },
47 color = this, control = control
49 colorDropBox.Create();
53 char tempString[MAX_F_STRING];
55 bool needClass = false;
57 result = OnGetString(tempString, null, &needClass);
58 if(result) string = result;
60 colorDropBox.contents = string;
61 // This is to highlight text on DataBox::Refresh
62 colorDropBox.editBox.SelectAll();
66 char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
69 if((string = ((DefinedColor)this).class::OnGetString(stringOutput, null, needClass)) ||
70 (string = ((SystemColor)this).class::OnGetString(stringOutput, null, needClass)))
72 if(needClass) *needClass = false;
84 colorValue = value.OnGetString(tempString, null, &subNeedClass);
85 strcpy(stringOutput, "r = "); strcat(stringOutput, colorValue);
88 memset(tempString, 0, 256);
92 colorValue = value.OnGetString(tempString, null, &subNeedClass);
93 strcat(stringOutput, ", g = "); strcat(stringOutput, colorValue);
96 memset(tempString, 0, 256);
100 colorValue = value.OnGetString(tempString, null, &subNeedClass);
101 strcat(stringOutput, ", b = "); strcat(stringOutput, colorValue);
106 bool OnGetDataFromString(char * string)
108 if(!atoi(string) && (((DefinedColor)this).class::OnGetDataFromString(string) ||
109 ((SystemColor)this).class::OnGetDataFromString(string)))
112 return class::OnGetDataFromString(string);
115 void OnDisplay(Surface surface, int x, int y, int width, char * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
117 char tempString[1024] = "";
118 bool needClass = false;
119 // TODO: This isn't an ideal way of obtaining the clipped height, will fail on hidden areas
120 // This doesn't seem to help anymore?
121 // - Makes SavingDataBox draw at 2 different spots depending if active or not.
122 // - Color property in IDE is fine as well
123 // - How is it on Linux?
124 int yOffset = 0;//(1+surface.box.bottom - surface.box.top - 17)/2;
125 char * string = OnGetString(tempString, null, &needClass);
126 surface.WriteTextDots(alignment, x + 24, y + 1, width - 24, string, strlen(string));
130 surface.SetBackground(white);
131 surface.Area(x - 4, y, x + 20, y + 15);
133 surface.SetBackground(this);
134 surface.Area(x, y + 2, x+17, y+13);
135 surface.SetForeground(black);
136 surface.Rectangle(x-1, y + 1, x + 18, y + 14);
140 public struct ColorHSV
149 float r = value.r, g = value.g, b = value.b;
150 float minV, maxV, diff,dr,dg,db;
165 dr = (maxV - r)/diff;
166 dg = (maxV - g)/diff;
167 db = (maxV - b)/diff;
170 if R=V then -- between yellow and magenta [degrees]
172 else if G=V then -- between cyan and yellow
173 H=120.0+60.0*(B-R)/Delta
174 else -- between magenta and cyan
175 H=240.0+60.0*(R-G)/Delta
191 this.h = h * Degrees { 60 };
198 float deg = (float)(this.h / 60);
199 float h = (deg == 6) ? 0 : deg, s = this.s / 100, v = this.v / 100;
203 float q = v*(1-(s*f));
204 float t = v*(1-s*(1-f));
208 case 0: r = v; g = t; b = p; break;
209 case 1: r = q; g = v; b = p; break;
210 case 2: r = p; g = v; b = t; break;
211 case 3: r = p; g = q; b = v; break;
212 case 4: r = t; g = p; b = v; break;
213 case 5: r = v; g = p; b = q; break;
215 // TODO: Figure out where this is needed
216 r = Max(Min(r, 1),0);
217 g = Max(Min(g, 1),0);
218 b = Max(Min(b, 1),0);
227 public struct ColorLab
235 float r = value.r, g = value.g, b = value.b;
238 r = (float)pow((r + 0.055)/1.055, 2.4);
239 g = (float)pow((g + 0.055)/1.055, 2.4);
240 b = (float)pow((b + 0.055)/1.055, 2.4);
243 float x = r * 0.412453f + g * 0.357580f + b * 0.180423f;
244 float y = r * 0.212671f + g * 0.715160f + b * 0.072169f;
245 float z = r * 0.019334f + g * 0.119193f + b * 0.950227f;
251 x = (x > 0.008856f) ? (float)pow(x, 1.0f/3) : (7.787f * x + 16/116.0f);
252 y2 = (y > 0.008856f) ? (float)pow(y, 1.0f/3) : (7.787f * y + 16/116.0f);
253 z = (z > 0.008856f) ? (float)pow(z, 1.0f/3) : (7.787f * z + 16/116.0f);
259 this.a = 500 * (x - y2);
260 this.b = 200 * (y2 - z);
266 float x,y,z,r,g,b, P;
270 if(l > 903.3f * 0.008856f)
281 P = (903.3f * y + 16) / 116;
288 x = (116 * x - 16) / 903.3f;
290 z = P - this.b / 200;
294 z = (116 * z - 16) / 903.3f;
301 r = x * 3.240479f + y * -1.537150f + z *-0.498535f;
302 g = x *-0.969256f + y * 1.875992f + z * 0.041556f;
303 b = x * 0.055648f + y * -0.204043f + z * 1.057311f;
305 r = (r > 0.00304f) ? (1.055f * (float)pow(r, 1/2.4) - 0.055f) : (12.92f * r);
306 g = (g > 0.00304f) ? (1.055f * (float)pow(g, 1/2.4) - 0.055f) : (12.92f * g);
307 b = (b > 0.00304f) ? (1.055f * (float)pow(b, 1/2.4) - 0.055f) : (12.92f * b);
309 // TODO: Figure out where this is needed
310 r = Max(Min(r, 1),0);
311 g = Max(Min(g, 1),0);
312 b = Max(Min(b, 1),0);
321 public struct ColorCMYK
328 float c = 1 - value.r;
329 float m = 1 - value.g;
330 float y = 1 - value.b;
331 float k = Min(Min(c,m), y);
333 this.c = this.m = this.y = 0;
336 this.c = (c-k)/(1-k) * 100;
337 this.m = (m-k)/(1-k) * 100;
338 this.y = (y-k)/(1-k) * 100;
345 float k = this.k/100;
346 value.r = 1 - ((c / 100) * (1-k) + k);
347 value.g = 1 - ((m / 100) * (1-k) + k);
348 value.b = 1 - ((y / 100) * (1-k) + k);
350 // TODO: Figure out where this is needed
351 value.r = Max(Min(value.r, 1),0);
352 value.g = Max(Min(value.g, 1),0);
353 value.b = Max(Min(value.b, 1),0);
358 public class Color565 : uint16
366 set { return Color565 { value.r >> 3, value.g >> 2, value.b >> 3 }; }
367 get { return Color { r << 3, g << 2, b << 3 }; }
371 public class Color555 : uint16
379 set { return Color555 { value.r >> 3, value.g >> 3, value.b >> 3 }; }
380 get { return Color { r << 3, g << 3, b << 3 }; }
384 public class Color444 : uint16
392 set { return Color444 { value.r >> 4, value.g >> 4, value.b >> 4 }; }
393 get { return Color { r << 4, g << 4, b << 4 }; }
397 public class ColorAlpha
405 set { return ColorAlpha { 255, value }; }
406 get { return color; }
410 set { return ColorAlpha { value.a, Color { value.r, value.g, value.b } }; }
411 get { return ColorRGBA { color.r, color.g, color.b, a }; }
415 public class ColorRGBA
424 set { return ColorRGBA { value.color.r, value.color.g, value.color.b, value.a }; }
425 get { return ColorAlpha { a, Color { r, g, b } }; }
429 set { return ColorRGBA { value.r, value.g, value.b, 255 }; }
430 get { return Color { r, g, b }; }
434 public enum DefinedColor : Color
436 black = Color { 0, 0, 0 },
437 dimGray = Color { 105, 105, 105 },
438 gray = Color { 128, 128, 128 },
439 darkGray = Color { 169, 169, 165 },
440 silver = Color { 192, 192, 192 },
441 lightGray = Color { 211, 211, 211 },
442 gainsboro = Color { 220, 220, 220 },
443 whiteSmoke = Color { 245, 245, 245 },
444 white = Color { 255, 255, 255 },
445 rosyBrown = Color { 188, 143, 143 },
446 indianRed = Color { 205, 92, 92 },
447 brown = Color { 165, 42, 42 },
448 fireBrick = Color { 178, 34, 34 },
449 lightCoral = Color { 240, 128, 128 },
450 maroon = Color { 128, 0, 0 },
451 darkRed = Color { 139, 0, 0 },
452 red = Color { 255, 0, 0 },
453 snow = Color { 255, 250, 250 },
454 mistyRose = Color { 255, 228, 225 },
455 salmon = Color { 250, 128, 114 },
456 tomato = Color { 255, 99, 71 },
457 darkSalmon = Color { 233, 150, 122 },
458 coral = Color { 255, 127, 80 },
459 orangeRed = Color { 255, 69, 0 },
460 lightSalmon = Color { 255, 160, 122 },
461 sienna = Color { 160, 82, 45 },
462 seaShell = Color { 255, 245, 238 },
463 chocolate = Color { 210, 105, 30 },
464 saddleBrown = Color { 139, 69, 19 },
465 sandyBrown = Color { 244, 164, 96 },
466 peachPuff = Color { 255, 218, 185 },
467 peru = Color { 205, 133, 63 },
468 linen = Color { 250, 240, 230 },
469 bisque = Color { 255, 228, 196 },
470 darkOrange = Color { 255, 140, 0 },
471 burlyWood = Color { 222, 184, 135 },
472 tan = Color { 210, 180, 140 },
473 antiqueWhite = Color { 250, 235, 215 },
474 navajoWhite = Color { 255, 222, 173 },
475 blanchedAlmond = Color { 255, 235, 205 },
476 papayaWhip = Color { 255, 239, 213 },
477 mocassin = Color { 255, 228, 181 },
478 orange = Color { 255, 165, 0 },
479 wheat = Color { 245, 222, 179 },
480 oldLace = Color { 253, 245, 230 },
481 floralWhite = Color { 255, 250, 240 },
482 darkGoldenrod = Color { 184, 134, 11 },
483 goldenrod = Color { 218, 165, 32 },
484 cornsilk = Color { 255, 248, 220 },
485 gold = Color { 255, 215, 0 },
486 khaki = Color { 240, 230, 140 },
487 lemonChiffon = Color { 255, 250, 205 },
488 paleGoldenrod = Color { 238, 232, 170 },
489 darkKhaki = Color { 189, 183, 107 },
490 beige = Color { 245, 245, 220 },
491 lightGoldenRodYellow= Color { 250, 250, 210 },
492 olive = Color { 128, 128, 0 },
493 yellow = Color { 255, 255, 0 },
494 lightYellow = Color { 255, 255, 224 },
495 ivory = Color { 255, 255, 240 },
496 oliveDrab = Color { 107, 142, 35 },
497 yellowGreen = Color { 154, 205, 50 },
498 darkOliveGreen = Color { 85, 107, 47 },
499 greenYellow = Color { 173, 255, 47 },
500 chartreuse = Color { 127, 255, 0 },
501 lawnGreen = Color { 124, 252, 0 },
502 darkSeaGreen = Color { 143, 188, 139 },
503 forestGreen = Color { 34, 139, 34 },
504 limeGreen = Color { 50, 205, 50 },
505 lightGreen = Color { 144, 238, 144 },
506 paleGreen = Color { 152, 251, 152 },
507 darkGreen = Color { 0, 100, 0 },
508 green = Color { 0, 128, 0 },
509 lime = Color { 0, 255, 0 },
510 honeyDew = Color { 240, 255, 240 },
511 seaGreen = Color { 46, 139, 87 },
512 mediumSeaGreen = Color { 60, 179, 113 },
513 springGreen = Color { 0, 255, 127 },
514 mintCream = Color { 245, 255, 250 },
515 mediumSpringGreen = Color { 0, 250, 154 },
516 mediumAquaMarine = Color { 102, 205, 170 },
517 aquamarine = Color { 127, 255, 212 },
518 turquoise = Color { 64, 224, 208 },
519 lightSeaGreen = Color { 32, 178, 170 },
520 mediumTurquoise = Color { 72, 209, 204 },
521 darkSlateGray = Color { 47, 79, 79 },
522 paleTurquoise = Color { 175, 238, 238 },
523 teal = Color { 0, 128, 128 },
524 darkCyan = Color { 0, 139, 139 },
525 aqua = Color { 0, 255, 255 },
526 cyan = Color { 0, 255, 255 },
527 lightCyan = Color { 224, 255, 255 },
528 azure = Color { 240, 255, 255 },
529 darkTurquoise = Color { 0, 206, 209 },
530 cadetBlue = Color { 95, 158, 160 },
531 powderBlue = Color { 176, 224, 230 },
532 lightBlue = Color { 173, 216, 230 },
533 deepSkyBlue = Color { 0, 191, 255 },
534 skyBlue = Color { 135, 206, 235 },
535 lightSkyBlue = Color { 135, 206, 250 },
536 steelBlue = Color { 70, 130, 180 },
537 aliceBlue = Color { 240, 248, 255 },
538 dodgerBlue = Color { 30, 144, 255 },
539 slateGray = Color { 112, 128, 144 },
540 lightSlateGray = Color { 119, 136, 153 },
541 lightSteelBlue = Color { 176, 196, 222 },
542 cornflowerBlue = Color { 100, 149, 237 },
543 royalBlue = Color { 65, 105, 225 },
544 midnightBlue = Color { 25, 25, 112 },
545 lavender = Color { 230, 230, 250 },
546 navy = Color { 0, 0, 128 },
547 darkBlue = Color { 0, 0, 139 },
548 mediumBlue = Color { 0, 0, 205 },
549 blue = Color { 0, 0, 255 },
550 ghostWhite = Color { 248, 248, 255 },
551 slateBlue = Color { 106, 90, 205 },
552 darkSlateBlue = Color { 72, 61, 139 },
553 mediumSlateBlue = Color { 123, 104, 238 },
554 mediumPurple = Color { 147, 112, 219 },
555 blueViolet = Color { 138, 43, 226 },
556 indigo = Color { 75, 0, 130 },
557 darkOrchid = Color { 153, 50, 204 },
558 darkViolet = Color { 148, 0, 211 },
559 mediumOrchid = Color { 186, 85, 211 },
560 thistle = Color { 216, 191, 216 },
561 plum = Color { 221, 160, 221 },
562 violet = Color { 238, 130, 238 },
563 purple = Color { 128, 0, 128 },
564 darkMagenta = Color { 139, 0, 139 },
565 magenta = Color { 255, 0, 255 },
566 fuschia = Color { 255, 0, 255 },
567 orchid = Color { 218, 112, 214 },
568 mediumVioletRed = Color { 199, 21, 133 },
569 deepPink = Color { 255, 20, 147 },
570 hotPink = Color { 255, 155, 180 },
571 lavenderBlush = Color { 255, 240, 245 },
572 paleVioletRed = Color { 219, 112, 147 },
573 crimson = Color { 220, 20, 60 },
574 pink = Color { 255, 192, 203 },
575 lightPink = Color { 255, 182, 193 }
578 // TODO: We really should improve on this, only formColor has been used so far
579 public enum SystemColor : Color
581 // activeBorder = Color { 212, 208, 200 },
582 formColor = Color { 229, 234, 245 },
583 activeBorder = Color { 229, 234, 245 },
584 control = Color { 212, 208, 200 },
585 controlLight = Color { 212, 208, 200 },
586 inactiveBorder = Color { 212, 208, 200 },
587 inactiveCaptionText = Color { 212, 208, 200 },
588 menu = Color { 212, 208, 200 },
589 scrollBar = Color { 212, 208, 200 }
592 private class ColorValue : Color
594 void OnDisplay(Surface surface, int x, int y, int width, char * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
596 // surface.WriteTextDots(alignment, x + 24, y + 1, width - 24, string, strlen(string));
597 surface.SetBackground(this);
598 surface.Area(x, y + 4, x+19, y+11);
600 surface.SetForeground(black);
601 surface.Rectangle(x-1, y + 3, x + 20, y + 12);
605 // TODO: ColorSelected was declared as non static
606 /*static */class ColorDropBox : DropBox
613 DataField sysColorField { dataType = "ColorValue", width = 20 };
614 DataField sysColorName { };
615 DataField definedColorField { dataType = "ColorValue", width = 20 };
616 DataField definedColorName { };
620 system.AddField(sysColorField);
621 system.AddField(sysColorName);
622 defined.AddField(definedColorField);
623 defined.AddField(definedColorName);
628 master = this, interim = true, autoCreate = false, minSize = { 204, 222 },
629 background = formColor, borderStyle = contour|bevel;
631 bool OnKeyDown(Key key, unichar ch)
633 ColorDropBox colorDropBox = (ColorDropBox)master;
634 if((SmartKey)key == enter)
636 if(!colorDropBox.ColorSelected(colorDropBox.listBox, colorDropBox.listBox.currentRow, 0))
641 return colorDropBox.OnKeyDown(key, ch);
647 bool ColorSelected(ListBox listBox, DataRow row, Modifiers mods)
649 Color color = row ? row.GetData(null) : black;
652 ((DataBox)parent).SetData(&color, false);
657 char tempString[1024] = "";
658 bool needClass = false;
659 char * string = color.OnGetString(tempString, null, &needClass);
662 OnKeyDown(escape, 0);
666 //OnKeyDown(escape, 0);
667 //master.OnKeyDown(escape, 0);
674 master = this, parent = pullDown,
676 hasVertScroll = true,
677 anchor = Anchor { left = 0, top = 16, right = 0, bottom = 0 },
678 NotifySelect = ColorSelected
682 master = this, parent = pullDown,
684 hasVertScroll = true,
685 anchor = Anchor { left = 0, top = 16, right = 0, bottom = 0 },
686 NotifySelect = ColorSelected
691 text = $"Select Color",
698 master = this, parent = pullDown,
701 position = Point { 0, 0 },
705 // isRadio = true, bitmap = null;
707 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
709 dialog.color = color;
711 OnKeyDown(escape, 0);
714 //OnKeyDown(Escape, 0);
715 //master.OnKeyDown(Escape, 0);
718 if(dialog.Modal() == ok)
720 color = dialog.color;
721 ((DataBox)master).SetData(&color, false);
723 char tempString[1024] = "";
724 bool needClass = false;
725 char * string = color.OnGetString(tempString, null, &needClass);
735 master = this, parent = pullDown,
739 position = Point { 68, 0 },
745 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
747 system.visible = false;
748 defined.visible = true;
755 master = this, parent = pullDown,
759 position = Point { 136, 0 },
765 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
767 defined.visible = false;
768 system.visible = true;
776 char tempString[256];
777 pullDown.size.w = size.w + 24;
784 DataRow currentRow = null;
787 for(item = ((EnumClassData)class(DefinedColor).data).values.first; item; item = item.next)
789 DataRow row = defined.AddRow();
790 row.SetData(definedColorField, (Color)(uint)item.data);
791 strcpy(tempString, item.name);
792 tempString[0] = (char)toupper(tempString[0]);
793 row.SetData(definedColorName, tempString);
794 // TOCHECK: A uint cast is necessary here, the void * was causing ColorRGB conversion to be called
795 if(!found && (Color)(uint)item.data == color)
802 defined.currentRow = currentRow;
807 DataRow currentRow = null;
810 for(item = ((EnumClassData)class(SystemColor).data).values.first; item; item = item.next)
812 DataRow row = system.AddRow();
813 row.SetData(sysColorField, (Color)(uint)item.data);
814 strcpy(tempString, item.name);
815 tempString[0] = (char)toupper(tempString[0]);
816 row.SetData(sysColorName, tempString);
818 // TOCHECK: A uint cast is necessary here, the void * was causing ColorRGB conversion to be called
819 if(!found && (Color)(uint)item.data == color)
826 system.currentRow = currentRow;
830 defined.visible = false;
831 system.visible = true;
832 systemButton.checked = true;
837 system.visible = false;
838 defined.visible = true;
839 definedButton.checked = true;
846 void OnCloseDropDown(Window pullDown)
848 // TOFIX: Patch for update bug
853 bool DataBox::NotifyTextEntry(ColorDropBox colorDropBox, char * string, bool save)
858 if(color.OnGetDataFromString(string))
859 SetData(&color, false);
863 char tempString[1024] = "";
864 bool needClass = false;
865 char * string = colorDropBox.color.OnGetString(tempString,null, &needClass);
866 colorDropBox.contents = string;