Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2011-10

How to obtain the color of a component?

18 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Felipe Monteiro de Carvalho

Hello,

Is there any easy way to obtain the color of a component taking into considerating all the factors? aka, propagating ParentColor, resolving clDefault, etc.

I have my TCDPageControl on top of a form, but for TCDPageControl.Color I get just clDefault, which turns out to be black. =( using Parent.GetDefaultColor(dcBrush) also returned black in Windows...

If there is no easy way maybe we should add one?

Felipe Monteiro de Carvalho

Reply by email

Hans-Peter Diettrich
to Felipe Monteiro de Carvalho
Show quoted text 10 lines
Hello, Is there any easy way to obtain the color of a component taking into considerating all the factors? aka, propagating ParentColor, resolving clDefault, etc. I have my TCDPageControl on top of a form, but for TCDPageControl.Color I get just clDefault, which turns out to be black. =( using Parent.GetDefaultColor(dcBrush) also returned black in Windows...

There was a complaint about different colors at designtime and runtime, in a Delphi group. The real color can depend on the active theme, you only can determine it at runtime.

If there is no easy way maybe we should add one?

I don't know how, but I'd try Canvas or Brush.Color...

DoDi

Reply by email

Howard Page-Clark
to Felipe Monteiro de Carvalho: Is there any easy way to obtain the color of a component taking into considerating all…
Felipe Monteiro de Carvalho wrote 13 lines
Hello, Is there any easy way to obtain the color of a component taking into considerating all the factors? aka, propagating ParentColor, resolving clDefault, etc. I have my TCDPageControl on top of a form, but for TCDPageControl.Color I get just clDefault, which turns out to be black. =( using Parent.GetDefaultColor(dcBrush) also returned black in Windows... If there is no easy way maybe we should add one?

I think it is possible since clDefault is TColor($20000000) and clBlack is TColor($000000) there are situations where the most significant bits of clDefault are lost and the two colours become identical. I've found that the Object Inspector's default component editor for colours seems at times to initialise colours to $000000 whatever the component's constructor may have directed.
In these situations I've resorted to overriding the Loaded method to set the desired value.

Howard

Reply by email

Graeme Geldenhuys
to Felipe Monteiro de Carvalho: Is there any easy way to obtain the color of a component taking into considerating all…
Felipe Monteiro de Carvalho wrote 5 lines
I have my TCDPageControl on top of a form, but for TCDPageControl.Color I get just clDefault, which turns out to be black. =( using Parent.GetDefaultColor(dcBrush) also returned black in Windows...

In fpGUI have have a fpgColorToRGBColor() - this will lookup and translate (if required) "color aliases" to real RGB values. If memory serves me right, Delphi (and probably Lazarus too) has a similar call? Try something like ColorToRGB(CDPageControl1.Color) and see if that does the trick.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Paul Ishenin
to Felipe Monteiro de Carvalho: Is there any easy way to obtain the color of a component taking into considerating all…
Felipe Monteiro de Carvalho wrote
Is there any easy way to obtain the color of a component taking into considerating all the factors? aka, propagating ParentColor, resolving clDefault, etc.
     if AControl.Color = clDefault then
       AColor := AControl.GetDefaultColor(dctBrush)
     else
       AColor := AControl.Color;

Also you can check brush color: TWinControl.Brush.Color.

I have my TCDPageControl on top of a form, but for TCDPageControl.Color I get just clDefault, which turns out to be black. =( using Parent.GetDefaultColor(dcBrush) also returned black in Windows...

Why do you use Parent. ?

If there is no easy way maybe we should add one?

If color is default it means that it may not have a solid example what color does a button has on themed windows if it is painted using bitmap? Same for other widgetsets. No way to detect the real color if it is default.

Best regards,
Paul Ishenin.

Reply by email

Felipe Monteiro de Carvalho
to Paul Ishenin
Paul Ishenin wrote
Why do you use Parent. ?

That's the whole reason why I have this control in question here is TCDPageControl, which is a custom drawn page control, therefore I have no background color of my own (although the user might specify one), there are no native themes for my control nor clDefault makes any sense for it, I just want to obtain the color of my parent, so that I can make my control paint the same color that he has, which is the form in this case, but it could be anything.

Now, regarding your suggestion, no it does not work:

procedure TCDCustomTabControlDrawerWinCE.DrawToIntfImage(ADest: TFPImageCanvas;
  FPImg: TLazIntfImage);
var
  lColor: TColor;
  lFPColor: TFPColor;
  x, y: Integer;
begin
  if CDTabControl.Color = clDefault then
    lColor := CDTabControl.GetDefaultColor(dctBrush) <-- I get black!
  else lColor := ColorToRGB(CDTabControl.Color);
  // Background
  lFPColor := TColorToFPColor(lColor);
  FPImg.FillPixels(lFPColor);
end;
Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
to Graeme Geldenhuys: In fpGUI have have a fpgColorToRGBColor() - this will lookup and translate (if required)…
Graeme Geldenhuys wrote 5 lines
In fpGUI have have a fpgColorToRGBColor() - this will lookup and translate (if required) "color aliases" to real RGB values. If memory serves me right, Delphi (and probably Lazarus too) has a similar call? Try something like ColorToRGB(CDPageControl1.Color) and see if that does the trick.

Yes, that's how it worked before clDefault was introduced, but clDefault has no meaning at all, it depends on the control! And if you pass clDefault around by means of ParentColor, for example, then you loose the information of which control originally specified it. Also, it seams that on my Windows I get no information to which color clDefault is for my form.

Maybe we should have instead created 1 color for each native control, like: clFormDefault, clPageControlDefault, etc.

Felipe Monteiro de Carvalho

Reply by email

Paul Ishenin
to Felipe Monteiro de Carvalho: That's the whole reason why I have this control in question here is TCDPageControl,…

21.10.2011 16:01, Felipe Monteiro de Carvalho ?????:

On Fri, Oct 21, 2011 at 9:47 AM, Paul Ishenin wrote: if CDTabControl.Color = clDefault then lColor := CDTabControl.GetDefaultColor(dctBrush)<-- I get black! else lColor := ColorToRGB(CDTabControl.Color);

The call to CDTabControl.GetDefaultColor(dctBrush) can return a system color too, so there is the same need to ColorToRGB() for this case.

if CDTabControl.Color = clDefault then
   lColor := ColorToRGB(CDTabControl.GetDefaultColor(dctBrush))
else
   lColor := ColorToRGB(CDTabControl.Color);

This should work ^.

Best regards,
Paul Ishenin.

Reply by email

Felipe Monteiro de Carvalho
to Paul Ishenin: 21.10.2011 16:01, Felipe Monteiro de Carvalho ?????: The call to…
Paul Ishenin wrote 6 lines
if CDTabControl.Color = clDefault then ?lColor := ColorToRGB(CDTabControl.GetDefaultColor(dctBrush)) else ?lColor := ColorToRGB(CDTabControl.Color); This should work ^.

Ok, thanks, this indeed works =) I did not expect GetDefaultColor to resolve ParentColor, but it does.

But I still think we introduced a "gotcha" in the sense that GetColor no longer returns a good color solving clDefault.

Maybe GetColor should call GetDefaultColor if the color is clDefault?

Felipe Monteiro de Carvalho

Reply by email

Paul Ishenin
to Felipe Monteiro de Carvalho: I think that it would work like this: function TWinControl.GetColor: TColor begin if…

21.10.2011 16:21, Felipe Monteiro de Carvalho ?????:

Show quoted text 10 lines
On Fri, Oct 21, 2011 at 10:14 AM, Paul Ishenin wrote: > How ParentColor property will work in this case? I think that it would work like this: function TWinControl.GetColor: TColor begin if ParentColor and (Parent nil) then Result := Parent.Color else Result := FColor; end;

Yes. You have a TButton with ParentColor = True. Have 2 special colors: one for form, one for button. With your proposal button will show in form color.

Also think how to implement that colors on widgetset side. How widgetset should handle a situation when you set clDefaultPageControl color to TButton?

Best regards,
Paul Ishenin.

Reply by email

Felipe Monteiro de Carvalho
to Paul Ishenin
Paul Ishenin wrote
GetColor should return the color assigned to a control. In other case you will have many problems with object inspector and form saving.

Indeed ... In this case I propose something like this:

function TControl.GetColorResolvingParent: TColor;
begin
  if Color = clDefault then
    Result := GetDefaultColor(dctBrush)
  else
    Result := Color;
end;
function TControl.GetRGBColor: TColor;
begin
    Result := ColorToRGB(GetColorResolvingParent);
end;

What do you think? Using the if ... else everywhere that wants to obtain the color is really not great. Proposals for naming this?

Felipe Monteiro de Carvalho

Reply by email

Graeme Geldenhuys
to Felipe Monteiro de Carvalho: On Fri, Oct 21, 2011 at 9:25 AM, Graeme Geldenhuys Yes, that's how it worked before…
Felipe Monteiro de Carvalho wrote
Yes, that's how it worked before clDefault was introduced, but

OK, I now understand what you mean. All other "alias colors" (eg: clBackground, clButtonFace) etc have actual RGB lookup values at runtime, but clDefault I guess not. Indeed a problem.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

zeljko
to Graeme Geldenhuys: In fpGUI have have a fpgColorToRGBColor() - this will lookup and translate (if required)…
Graeme Geldenhuys wrote 11 lines
On 2011-10-20 17:57, Felipe Monteiro de Carvalho wrote: > I have my TCDPageControl on top of a form, but for > TCDPageControl.Color I get just clDefault, which turns out to be > black. =( using Parent.GetDefaultColor(dcBrush) also returned black in > Windows... In fpGUI have have a fpgColorToRGBColor() - this will lookup and translate (if required) "color aliases" to real RGB values. If memory serves me right, Delphi (and probably Lazarus too) has a similar call? Try something like ColorToRGB(CDPageControl1.Color) and see if that does the trick.

Better solution would be CDPageControl1.Brush.Color, since CDPageControl1.Color can be clDefault and then you'll get nothing.

zeljko
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20111021/74fd4b7d/attachment.html>

Reply by email

Hans-Peter Diettrich
to Felipe Monteiro de Carvalho: On Fri, Oct 21, 2011 at 9:25 AM, Graeme Geldenhuys Yes, that's how it worked before…
Maybe we should have instead created 1 color for each native control, like: clFormDefault, clPageControlDefault, etc.

For that purpose we already have clScrollBar etc., see Graphics.pp 270 ff.

At least on Windows the user can specify freely the colors for the most common window elements. See: Control Panel - Display Properties - Appearance - Advanced Appearance. AFAIK all platforms have something like Themes for similar purpose.

A GUI designer should not try to assume or supply specific colors for all these elements.

DoDi

Reply by email

Felipe Monteiro de Carvalho
to Felipe Monteiro de Carvalho: Indeed ... In this case I propose something like this: function…
Felipe Monteiro de Carvalho wrote 12 lines
function TControl.GetColorResolvingParent: TColor; begin ?if Color = clDefault then ? ?Result := GetDefaultColor(dctBrush) ?else ? ?Result := Color; end; function TControl.GetRGBColor: TColor; begin ? ?Result := ColorToRGB(GetColorResolvingParent); end;

These now exist in rev 33093

Felipe Monteiro de Carvalho

Reply by email