Gustav Schubert 25 Posted February 8, 2021 (edited) I think the VCL version of MedGray contains a typo: // Search for MedGray in unit System.UITypes: MedGray = TColor($A4A0A0); MedGray = Alpha or TAlphaColor($A0A0A0); See (also) the following docwiki topics: RADStudio/Sydney/en/Colors_in_the_VCL RADStudio/Sydney/en/Colors_in_FireMonkey Already known: Gray is darker than DarkGray, this is ok ( I learned it from Stackoverflow). Use Dimgray if you want a darker gray than Gray. The default background color of a Window is not a named color in TAlphaColorRec. Duplicate color values in TAlphaColorRec are by design. There is an open RSP (29269) which complains about duplicated color values in System.UITypes.TAlphaColorRec. Questions: Are color values other then web colors allowed to have a name in TAlphaColorRec? If so, what color names would you like to be included, for convenience? QuickSilver = Alpha or TAlphaColor($A0A0A0); // Mediumgrey or Mediumgray or MedGray? WindowWhite = Alpha or TAlphaColor($F0F0F0); // ButtonFace or BtnFace or Buttonface or Windowgray? I never used MedGray, but I need a WindowWhite in FMX. I intend to specify a reduced set of named colors for use in my application. I need those colors to have a good name. I will have VCL, FMX, and LCL versions of my very own TRggColors, which will be available under the same name to client code in VCL and FMX. Gray would be ok. ( Not sure about DarkGray. ) Mediumgray will look nice next to Lightgray. Not sure about WindowWhite. ( This topic is about accessing color values by name for drawing to the canvas of the platform, without creating noise in the diff, and without stopping at surprises. ) Edited February 9, 2021 by Gustav Schubert corrected WindowWhite = $FFF0F0F0 Share this post Link to post
Guest Posted February 8, 2021 (edited) if your doubt is "find A name for your colors const", try this site: Chir.ag by Chirag Mehta the have created this site for easy find your colors names, include using Hex values! And others goods! https://chir.ag/projects/name-that-color/#E0E0E0 Here, you can have another options like a little app https://www.raymond.cc/blog/how-to-find-out-the-name-of-a-color/ hug Edited February 8, 2021 by Guest Share this post Link to post
Gustav Schubert 25 Posted February 8, 2021 My problem is that I cannot find the FMX version of clBtnFace in TAlphaColorRec. (WindowWhite) Btw, by now I have decided that grey has lost! I know this is a little unfair, but only a little, and I am not really sorry, mainly because the chance was there, with FMX, in the beginning. As far as the DarkGray problem is concerned, any suggestion for a more appropiate name? I would consider a French name too, for my internal cross platform TRggColors helper. Share this post Link to post
Guest Posted February 9, 2021 (edited) 4 hours ago, Gustav Schubert said: I cannot find the FMX version of clBtnFace in TAlphaColorRec. (WindowWhite) Dont forget that FMX is based in Styles (VCL too) :))) Themes, that control many visual aspect! VCL and FMX is 2 frameworks made by 2 different teams! clBtnFace does not exist, but "$FFF0F0F0", yes! procedure TForm1.Button2Click(Sender: TObject); begin // init value on design = $FF8A2BE2 = 4287245282 // // FMX - Blueviolet = 4293980400 = $FF8A2BE2 // VCL - clBtnFace (FMX $FFF0F0F0 = 4293980400) // { if (Label1.TextSettings.FontColor = 4293980400) then Label1.TextSettings.FontColor := 4287245282 else Label1.TextSettings.FontColor := 4293980400; } // if (Label1.TextSettings.FontColor = $FFF0F0F0) then Label1.TextSettings.FontColor := $FF8A2BE2 else Label1.TextSettings.FontColor := $FFF0F0F0; end; hug Edited February 9, 2021 by Guest Share this post Link to post
Gustav Schubert 25 Posted February 9, 2021 (edited) I am dealing with two missing colors, one ambiguous color (MedGray), one misleading color (DarkGray), and duplicated color values (gray vs. grey). Joke: I suggest that the wiki pages add two buttons, "sort by gray" and "sort by grey". In my test program I show 10 overlapping rectangles (FMX) or shapes (VCL) to verify my understanding of the color values. The second 'color name' in the following output is returned from AlphaColorToString(color) or ColorToString(color). #FFF0F0F0 - default color for a Window background in FMX. #FFE0E0E0 - default value of Rectangle1.Fill.Color in FMX. // FormatString := '%d: [%20s]: %12s = %x = (%d, %d, %d)'; Testprogram output for FMX: 0: [ Whitesmoke F5 245]: Whitesmoke = FFF5F5F5 = (245, 245, 245) 1: [ WindowWhite F0 240]: #FFF0F0F0 = FFF0F0F0 = (240, 240, 240) 2: [ ChinaWhite E0 224]: #FFE0E0E0 = FFE0E0E0 = (224, 224, 224) 3: [ Gainsboro DC 220]: Gainsboro = FFDCDCDC = (220, 220, 220) 4: [ Lightgray D3 211]: Lightgray = FFD3D3D3 = (211, 211, 211) 5: [ Silver C0 192]: Silver = FFC0C0C0 = (192, 192, 192) 6: [ Darkgray A9 169]: Darkgray = FFA9A9A9 = (169, 169, 169) 7: [ MedGray A0 160]: #FFA0A0A0 = FFA0A0A0 = (160, 160, 160) 8: [ Gray 80 128]: Gray = FF808080 = (128, 128, 128) 9: [ Dimgray 69 105]: Dimgray = FF696969 = (105, 105, 105) Testprogram output for VCL colors: 0: [ Whitesmoke F5 245]: $00F5F5F5 = F5F5F5 = (245, 245, 245) 1: [ WindowWhite F0 240]: $00F0F0F0 = F0F0F0 = (240, 240, 240) 2: [ ChinaWhite E0 224]: $00E0E0E0 = E0E0E0 = (224, 224, 224) 3: [ Gainsboro DC 220]: $00DCDCDC = DCDCDC = (220, 220, 220) 4: [ Lightgray D3 211]: $00D3D3D3 = D3D3D3 = (211, 211, 211) 5: [ Silver C0 192]: clSilver = C0C0C0 = (192, 192, 192) 6: [ Darkgray A9 169]: $00A9A9A9 = A9A9A9 = (169, 169, 169) 7: [ MedGray A0 160]: clMedGray = A4A0A0 = (160, 160, 164) 8: [ Gray 80 128]: clGray = 808080 = (128, 128, 128) 9: [ Dimgray 69 105]: $00696969 = 696969 = (105, 105, 105) Color names according to chir.ag: F5 245 Wild Sand approx. (Whitesmoke) F0 240 Gallery approx. (clBtnFace, "WindowWhite") E0 224 Alto approx. () DC 220 Alto approx.(Gainsboro) D3 211 Alto approx. (Lightgray) C0 192 Silver solid (Silver) A9 169 Silver Chalice approx. (Darkgray) A0 160 Silver Chalice approx. (MedGray FMX) 80 128 Gray solid (Gray) 69 105 Dove Gray approx. (DimGray) A0A0A4 Santas Gray approx. (MedGray VCL) clBtnFace is not a named color: https://encycolorpedia.com/named https://colorate.azurewebsites.net/Color/F0F0F0 Edited February 9, 2021 by Gustav Schubert formatting Share this post Link to post
Gustav Schubert 25 Posted February 9, 2021 I only want to use colors that are defined in TAlphaColorRec, and which return the name from AlphaColorToString. This is what I want to figure out. Share this post Link to post
Guest Posted February 9, 2021 (edited) look this: in Delphi, you can find the "color name" is exist a "const defined in "System.UIConst (FMC) / System.UITypes (VCL) "! in fact, the "names" is "arbitrared" by language, not for a color itself! you see? See at: System.Classes.pas, line: 4205, function IntToIdent(Int: Integer; var Ident: string; const Map: array of TIdentMapEntry): Boolean; Map is the "magic"! Map: array of TIdentMapEntry TIdentMapEntry = record ... feeded by some other point in system! maybe some API function... Syste.pas, line 26225, procedure _UStrAsg(var Dest: UnicodeString; const Source: UnicodeString); // globals (need copy) ... procedure TForm1.btn_TAlphaColor_in_A_R_G_B_valuesClick(Sender: TObject); var lMyAlphaColorRec: TAlphaColorRec; lMyAlphaColors : TAlphaColors; // iColor : integer; begin Memo1.Lines.Clear; // { no result } lMyAlphaColorRec.Create($FFF0F0F0); // clBtnFace (VCL) { iColor := } lMyAlphaColors.ColorToRGB($FFF0F0F0); // clBtnFace (VCL) // Label1.TextSettings.FontColor := { RGBtoBGR( } lMyAlphaColors.Color; // ); // Label2.TextSettings.FontColor := { RGBtoBGR( } lMyAlphaColorRec.Color; // ); // Memo1.Lines.Add('Using TAlphaColorRec:'); Memo1.Lines.Add(Format('A=%d, R=%d, G=%d, B=%d, AlphaColor=%s', [ { } lMyAlphaColorRec.A, { } lMyAlphaColorRec.R, { } lMyAlphaColorRec.G, { } lMyAlphaColorRec.B, { } AlphaColorToString(lMyAlphaColorRec.Color) { } ])); // Memo1.Lines.Add('Using TAlphaColors:'); Memo1.Lines.Add(Format('A=%d, R=%d, G=%d, B=%d, AlphaColor=%s', { } [lMyAlphaColors.A, { } lMyAlphaColors.R, { } lMyAlphaColors.G, { } lMyAlphaColors.B, { } AlphaColorToString(lMyAlphaColors.Color) { } ])); end; procedure TForm1.btnLabels_with_claAqua_default_colorsClick(Sender: TObject); begin Label1.TextSettings.FontColor := claAqua; // TAlphaColors.claAqua // Label2.TextSettings.FontColor := claAqua; // TAlphaColors.claAqua end; What you can to, it's a create your "array" with your colors names and values pertinent! Like this: type TMyAlphaColorsNames = record Name: string; Color: TAlphaColor; end; procedure TForm1.btnLabels_with_claAqua_default_colorsClick(Sender: TObject); var lMyAlphaColorsNames: array [0 .. 1] of TMyAlphaColorsNames; begin lMyAlphaColorsNames[0].Name := 'clBtnFace'; lMyAlphaColorsNames[0].Color := $FFF0F0F0; lMyAlphaColorsNames[1].Name := 'Aqua'; lMyAlphaColorsNames[1].Color := claAqua; // Label1.Text := lMyAlphaColorsNames[0].Name; Label1.TextSettings.FontColor := lMyAlphaColorsNames[0].Color; // Label2.Text := lMyAlphaColorsNames[1].Name; Label2.TextSettings.FontColor := lMyAlphaColorsNames[1].Color; end; hug Edited February 9, 2021 by Guest Share this post Link to post
Gustav Schubert 25 Posted February 9, 2021 This is from my application: A0B0 := TRggLine.Create('A0B0'); L := A0B0; //L.StrokeColor := TAlphaColors.Gray; // FMX only L.StrokeColor := TRggColors.Gray; // VCL and FMX and LCL L.Point1 := A0; L.Point2 := B0; Add(L); I am designing a color palette (from well known color names) and I am thinking about color names to be included. The user (myself, to begin with) is expected to specify names that can be remembered. I took TAlphaColorRec as a starting point, and I am free to fix any potential problems. For example: F0F0F0 (BtnFace) is not a named color, not in the realm of Delphi FMX. Should Embarcadero give a name to that color, and which? How about MedGray and DarkGray. What to do with the duplicated colors, keep them? Want is your opinion, of the palette of named colors in Delphi? Share this post Link to post
Guest Posted February 9, 2021 (edited) 35 minutes ago, Gustav Schubert said: Want is your opinion, of the palette of named colors in Delphi? First, let's remember that Embarcadero bought the Borland estate (CodeGear, InPrise, etc ... other names for the Borland estate throughout its existence). Therefore, many things could not just disappear! There were many companies that used Delphi and CBuilder, for example! So, see that the pyramid would be collapsed if the base was destroyed! Second, many of the names, classes, components, interfaces, etc ... were and still are "inherited" from the MSWindows APIs. And, now from other platforms, such as: Android, Linux, macOS, iOS, etc ... who knows what will come around! Python is already a reality, PHP, Java too, etc ... Third, as inheritance makes sense, when it comes to having a standard required by operating systems, then, I couldn't just "determine" what would be created or what name it would have! It was necessary to meet the requirements of MSWindows, at that time ... and so, it continues today! Imposition of the market, or simply, rules of Capitalism in action! If, what you intend to create is only for your use! So, you are the one who determines what will be created and how it will be defined! If, on the contrary, you intend to distribute to other professional developers or not, then the rule changes! You must serve the market, and not just your expectations! Unless you buy the entire computer technology market and start dictating the market, as many companies have done in the past! IBM dictated rules in mainframes, Microsoft in operating systems, etc ... But we have already seen that this is no longer valid! With globalization and the unrestricted use of the internet, we can no longer think of ourselves, but of the whole! Regarding whether or not to have duplicate "color names", the most sensible answer is: NO! Duplicity generates mistakes, many times, imperceptible! If you check the source files of RAD Studio (Delphi, for example), you will see that this happens! Therefore, it is advisable to use "name-space" for types, for example: System.faDirectory in System.SysUtils TFileAttribute.faDirectory in System.IOUtils note that "faDirectory" is used by default when you do not use "System.IOUtils" in the "Uses" and "TFileAttribute" clause to determine the enumeration where the "faDirectory" value comes from! So, nobody, especially when they are on a team with many minds thinking, will be free of this type of error! So, my advice is: For colors with equal values, choose only one to use, or, at best, make the next name refer to the previous one, such as: caBtnFace = $ xxxxxxxx; myColorBtnFace = caBtnFace; Now, I can have both references in my list of choice, however, for a better layout, when assembling the color list, you could check if the value already exists in the list, and if so, then do not add the new name / value. Understood? It would be wiser than having two names for the same color value! Regarding the names you will use, try to be sensible here too! If you can try to follow the universal rules for naming your color list! Not to mention that you can have the list of your constants or even your class with the definitions for the colors, using the platform identifiers: {$ IF DEFINED (MSWINDOWS)} ... here you can try verify if "FMX" or "VCL" project --- please see on Help which as global vars for each one {$ ENDIF} {$ IF DEFINED (ANDROID)} // etc... {$ ENDIF} But it is always recommended to have units for framework! And, ultimately, you could have a single for more than one framework! For example, RTL can be used by VCL or FMX projects! However, specific classes for FMX are not defined in the units for VCL! hug Edited February 9, 2021 by Guest Share this post Link to post
Gustav Schubert 25 Posted February 9, 2021 BtnFace-F0F0F0 is the most important color in the Delphi universe. A great opportunity still exists for Embarcadero to give this unnamed color a proper place in the encyclopedia of color names. All that is needed is to include it in TAlphaColorRec, and return the name from the AlphaColorToString function. Since there are duplicate names already (defined for some of the gray values), it does not matter much to add one more, and another one for E0E0E0, and an alternative name for DarkGray. Maybe they are reading this and will act. Then I could just clone the TAlphaColorRec and delete everything I do not want. All the standard functions like AlphaColorToString would work for me out of the box. I don't know if that idea was the reason why I posted here. Sometimes it is a bit fuzzy. But thank you for giving me the opportunity to explain my point! mfg Share this post Link to post
Guest Posted February 9, 2021 (edited) u're wellcome! note: if possible, rate my answers. hug Edited February 9, 2021 by Guest Share this post Link to post
Gustav Schubert 25 Posted February 11, 2021 Analysis of the day: 140 web colors + 1 Alpha + 1 Null + 7 Grey duplicats + 6 (LtGray, MedGray, DkGray, MoneyGreen, LegacySkyBlue, Cream) ----- 155 named colors in TAlphaColorRec in System.UITypes ===== 140 web color // see https://www.w3schools.com/cssref/css_colors.asp + 1 Null (claNull) + 7 Grey duplicates // claDarkgrey, claDarkslategrey, claDimgrey, claGrey, claLightgrey, claLightslategrey, claSlategrey ----- 148 global cla Constants in System.UIConsts ===== The 148 named color constants can be iterated over using AlphaColors array, which is private in System.UIConsts. You are supposed to do it with the help of procedure GetAlphaColorValues(Proc: TGetStrProc); See constructor of FMX.Colors.TRTLColors for an example of how to use it. The problem with GetAlphaColorValues is described in RSP-30408. A TWebColors type similar to TAlphaColors but with only 140 entries would be nice. FFF0F0F0 is still a candidate for inclusion in TAlphaColorRec (to be dropped later). I no longer want E0E0E0 (only used as default color for TRectangle.Fill). 1 Share this post Link to post
Guest Posted February 11, 2021 ok. if possible, when ready, share your project-color. hug Share this post Link to post
Gustav Schubert 25 Posted February 15, 2021 (edited) Actually, there are 138 unique color values in the 140 web colors, because of Aqua = Cyan and Fuchsia = Magenta. AlphaColors array in System.UIConsts has a 'unique constraint' on the Name but not on the Value. Definitions of Cream and LegacySkyBlue are wrong in FMX. // Colors do not match - verified with pipette in MS Paint. Rectangle1.Fill.Color := TAlphaColors.Cream; // FMX Shape1.Brush.Color := TColors.Cream; // VCL Reason: TAlphaColorRec Red = Alpha or TAlphaColor($FF0000); // correct MoneyGreen = TAlphaColor($FFC0DCC0); // symmetry LegacySkyBlue = Alpha or TAlphaColor($F0CAA6); // wrong Cream = Alpha or TAlphaColor($F0FBFF); // wrong {$IFDEF BIGENDIAN} (A, R, G, B: System.Byte); {$ELSE} (B, G, R, A: System.Byte); {$ENDIF} TColorRec Red = TColor($0000FF); // correct MoneyGreen = TColor($C0DCC0); // the original LegacySkyBlue = TColor($F0CAA6); // the original Cream = TColor($F0FBFF); // the original {$IFDEF BIGENDIAN} (A, B, G, R: System.Byte); {$ELSE} (R, G, B, A: System.Byte); {$ENDIF} Test program: program CreamTest; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.UIConsts, System.UITypes; var c: TAlphaColor; cr: TColorRec; acr: TAlphaColorRec; i: Integer; begin try cr.Color := TColors.Red; acr.Color := TAlphaColors.Red; Assert(cr.R = acr.R); Assert(cr.G = acr.G); Assert(cr.B = acr.B); WriteLn('Red test ok.'); // Green and Blue are ok as well WriteLn; cr.Color := TColors.Cream; acr.Color := TAlphaColors.Cream; Assert(cr.R = acr.B); Assert(cr.G = acr.G); Assert(cr.B = acr.R); WriteLn('Verified: R and B are swapped for Cream!'); cr.Color := TColors.LegacySkyBlue; acr.Color := TAlphaColors.LegacySkyBlue; Assert(cr.R = acr.B); Assert(cr.G = acr.G); Assert(cr.B = acr.R); WriteLn('Verified: R and B are swapped for LegacySkyBlue!'); WriteLn; WriteLn('Cream Test begins'); cr.Color := TColors.Cream; acr.Color := TAlphaColors.Cream; i := 0; if cr.R <> acr.R then begin WriteLn('R is wrong.'); Inc(i); end; if cr.B <> acr.B then begin WriteLn('B is wrong.'); Inc(i); end; if i = 0 then WriteLn('Test ok.') else WriteLn('Cream test failed.'); WriteLn; WriteLn('AlphaColorToString Tests:'); WriteLn('Aqua', '=', AlphaColorToString(TAlphaColors.Aqua)); WriteLn('Cyan', '=', AlphaColorToString(TAlphaColors.Cyan)); WriteLn('Fuchsia', '=', AlphaColorToString(TAlphaColors.Fuchsia)); WriteLn('Magenta', '=', AlphaColorToString(TAlphaColors.Magenta)); WriteLn('MoneyGreen', '=', AlphaColorToString(TAlphaColors.MoneyGreen)); WriteLn('LegacySkyBlue', '=', AlphaColorToString(TAlphaColors.LegacySkyBlue)); WriteLn('Cream', '=', AlphaColorToString(TAlphaColors.Cream)); WriteLn; WriteLn('ColorToString Tests:'); WriteLn('Aqua', '=', ColorToString(TColors.Aqua)); WriteLn('Cyan', '=', ColorToString(TColors.Cyan)); WriteLn('Fuchsia', '=', ColorToString(TColors.Fuchsia)); WriteLn('Magenta', '=', ColorToString(TColors.Magenta)); WriteLn('MoneyGreen', '=', ColorToString(TColors.MoneyGreen)); WriteLn('LegacySkyBlue', '=', ColorToString(TColors.LegacySkyBlue)); WriteLn('Cream', '=', ColorToString(TColors.Cream)); ReadLn; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. Output: Red test ok. Verified: R and B are swapped for Cream! Verified: R and B are swapped for LegacySkyBlue! Cream Test begins R is wrong. B is wrong. Cream test failed. AlphaColorToString Tests: Aqua=Aqua Cyan=Aqua Fuchsia=Fuchsia Magenta=Fuchsia MoneyGreen=#FFC0DCC0 LegacySkyBlue=#FFF0CAA6 Cream=#FFF0FBFF ColorToString Tests: Aqua=clAqua Cyan=clAqua Fuchsia=clFuchsia Magenta=clFuchsia MoneyGreen=clMoneyGreen LegacySkyBlue=clSkyBlue Cream=clCream I am playing with colors, but not yet used in any feature of the app: ( https://github.com/federgraph/RiggVar-RG38/blob/master/FB/RiggVar.FB.Color.pas ) Edited February 15, 2021 by Gustav Schubert typo Share this post Link to post
Gustav Schubert 25 Posted February 25, 2021 Update: There are now 141 web colors (139 unique). The relatively new web color is Rebeccapurple, not (yet) included in TAlphaColorRec. In my temporary capacity as an expert on LegacySkyBlue I have reported to Quality: RSP-32781. And I have uploaded FrmColor.pas (the main form in RG69.dpr) as a test for my TRggWebColorListBox runtime component. ( The component can show colors in a sort order that is NOT alphabetically, and filter by group of web colors. ) Share this post Link to post