Jump to content
Fudley

How to find the currently used theme color of a themed control

Recommended Posts

A number of controls are not themed, like TRectangle, TLine  and the svg.overridecolor on TkSvg. I would like to set these to match the current theme.

 

How can I find the currently used theme color of a control I know is themed,  so I can then apply it to the non-themed controls at runtime?

 

For instance 

  • TLabel themed fontcolor would do nicely to use for svg.overridecolor on TkSvg,.
  • TLabel themed fontcolor would work (for me) for TRectangle.stroke
  • TButtons themed fill color could be used for TRectangle.fill

 

For me, this would save oodles of work.

 

thanks all

 

Share this post


Link to post

Well it's a subject I was working on 07/2019 but reworking those days for a tutorial (and future book perhaps)

The trick is first to get the style used 

var sb: TFMXObject; 
begin
   if assigned(Scene) then
   begin
   if not Assigned(Scene.StyleBook) then
      sb := TStyleManager.ActiveStyleForScene(Scene)
    else
      sb := Scene.StyleBook.Style;

then once got you can search the needed properties

if assigned(sb) then
begin
// text color
aFMXObj := TStyleContainer(aFMXObj).FindStyleResource('labelstyle');
 if Assigned(aFMXObj) then
      aFMXObj := TLayout(aFMXObj).FindStyleResource('Text');
 if Assigned(aFMXObj) then
      Memo1.lines.Add(AlphaColorToString(TText(aFMXObj).TextSettings.FontColor));

end;

but for button color, it's a bit harder, you have 2 cases

  • Background is a TRectangle;
  • Background is  StyleObject (selection in a bitmap). 

Use the same scheme as exposed for text color (finding 'buttonstyle')  and then 'background'

if background object is a TRectangle then you can access fill.color property (take care type could be also a gradient ...) 

else (a FMXObject) I made a try here 


(by the way you can get button's text color(s) also)

 

Sorry if my links are for French readers.

 

P.S. read a some .style files to understand the principles

Edited by Serge_G
add a P.S.
  • Thanks 1

Share this post


Link to post

Serge_G

Thanks so much! that worked perfectly!!!!

Share this post


Link to post

With serge_g's help:


 

procedure TMyMainForm.ColorMyWorld;
var ThisComp             : TComponent;
    iComponentCount, 
    iThis             : integer;
    TextObj            : TText;
begin
  // gotstylelabel is a TLabel    
  TextObj := TText(gotstylelabel.FindStyleResource('text'));
  if Assigned(TextObj) then
  begin
     iComponentCount := ComponentCount; {form componentcount}
     try
       for iThis := 0 to iComponentCount-1 do
       begin
         ThisComp := Components[iThis];
         if ThisComp is TRectangle then
            TRectangle(ThisComp).Stroke.color     :=  TextObj.Color
         else if ThisComp is TLine then
              TLine(ThisComp).Stroke.color         :=  TextObj.Color
         else if ThisComp is TskSVG then
            TskSVG(ThisComp).svg.overrideColor     := TextObj.Color ;

       end;
     except
     end;

  end;

end

 

Share this post


Link to post

I found this does not effect embedded TFrames, so I wrote a frame-specific  TMyMainForm.ColorMyFramesWorld(aFrame:TFrame_) that does essentailly the same thing with the children of the frame.

 

TMyMainForm.ColorMyWorld;

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×