Lazarus

Programming => LCL => Topic started by: Nicole on September 30, 2022, 08:47:57 am

Title: Pagecontrol - Panels - style
Post by: Nicole on September 30, 2022, 08:47:57 am
Code: Pascal  [Select][+][-]
  1. PageControl_Main.Font.Color:=myDarkColor;

sets all fonts of my TSpeedButtons in all TabSheets of my TPageControl to myDarkColor.

Is there a way to set the fonts of all TPanels, TStatic text etc the same way?

The idea is: Change all the styles of my TPageContol on one place.
Title: Re: Pagecontrol - Panels - style
Post by: Gald on September 30, 2022, 09:02:05 am
You can use a for loop for each component, TSpeedButton, TPanel, TStaticText, etc.
Title: Re: Pagecontrol - Panels - style
Post by: Nicole on September 30, 2022, 10:11:53 am
thank you.
Can you kindly provide an example how this may look?
Title: Re: Pagecontrol - Panels - style
Post by: wp on September 30, 2022, 02:26:04 pm
Be warned when attempting to change colors: Since many LCL controls are drawn by the widgetset (=OS) you have little control over colors - for some controls it works, for others it does not. If you want complete control over colors you must use a third-party, owner-drawn collection of controls. There are some libs in OPM, but I have never seen a collection with is as complete as the built-in LCL controls (but I did not look too carefully).

My advice: Leave colors alone, and let the widgetset do its work. This way you get a consistent look of your application. If you want dark mode, switch your OS to dark mode and you will get it for free (Unfortunately the dark mode of windows even in Win 11 22H2 is still kind of mysterious for standard GUI applications = not working).
Title: Re: Pagecontrol - Panels - style
Post by: Nicole on September 30, 2022, 03:34:36 pm
Hm, is there no way out?

Not sure, if this works in recent Delphi version like this anymore.
I attach you a screenshot. This was what I used since long: I did not care for any color with it.
Suddenly the topic is back again.

Is there nothing comparable in Lazarus?
It is really nice and gives the programmer time for more important issues.
Title: Re: Pagecontrol - Panels - style
Post by: KodeZwerg on September 30, 2022, 03:40:55 pm
I do not know if I understand you correct, but you could (from my point of view) :
a) setup your main form and let created controls grab main forms setup
b) iterate over all components and setup whatever you want to set up

for b) you could do things like this:
Code: Pascal  [Select][+][-]
  1. procedure TFormName.DoSomethingSpecial;
  2. var
  3.   i: Integer;
  4. begin
  5.   for i := Pred(Self.ComponentCount ) downto 0 do
  6.     begin
  7.       try
  8.         Self.Components[i].Font := ...FontVariable...
  9.       except
  10.       end;
  11.     end;
  12. end;
Title: Re: Pagecontrol - Panels - style
Post by: wp on September 30, 2022, 04:04:54 pm
Hm, is there no way out?

Not sure, if this works in recent Delphi version like this anymore.
I attach you a screenshot. This was what I used since long: I did not care for any color with it.
Suddenly the topic is back again.

Is there nothing comparable in Lazarus?
It is really nice and gives the programmer time for more important issues.
What you see here is FireMonkey, a component library in addition to Delphi's VCL with its own controls. Lazarus does not have an equivalent. Well, not exactly: there is the Customdrawn widgetset, which you can select in the project options > Additions and overrides > Select widgetset (maybe you must also install the package "customdrawn", https://wiki.freepascal.org/Lazarus_Custom_Drawn_Controls) - but this is unmaintained half-finished work and I never was able to create something useful with it. As I said, you must look for a third-party library which draws the controls without the widgetset (BGRA, for example) and you must use these controls in your application and hope that all the controls that you need are supported. When it is only a few components that you want to "re-color" you might also look at the ExCtrls library on CCR which tries to mimic the original LCL controls, but in a way that some restrictions due to the widgetset are by-passed (https://wiki.lazarus.freepascal.org/ExCtrls). To be honest - this is also unfinished work, but at least maintained (by myself).
Title: Re: Pagecontrol - Panels - style
Post by: Nicole on September 30, 2022, 04:22:05 pm
Thank you for your answers.

@KodeZwerg:
Components.Font
does not work for me

@wp
I like the look of ExCtrls much.
The more I look at it, the more I like it.
But not sure, if I shall take more complexity into my project.
I'll think it over.
Title: Re: Pagecontrol - Panels - style
Post by: KodeZwerg on September 30, 2022, 04:28:48 pm
@KodeZwerg:
Components.Font
does not work for me
I love that kind of error report... "does not work".... good.
Title: Re: Pagecontrol - Panels - style
Post by: Nicole on September 30, 2022, 04:53:26 pm
I cannot combine component with font, see attach.
If I enforce it, there is an error-message.
Title: Re: Pagecontrol - Panels - style
Post by: wp on September 30, 2022, 05:07:19 pm
The loop in KodeZwerg's code iterates through the elements of a form considering them in the light of their most elemental class, TComponent - every class that is added to a TForm must be a TComponent at least, and the Components[] "array" lists them. Each element of Components was created as a higher class, though,  and you can access the properties of the higher class by type-casting the Components[] to that higher class. TControl descends from TComponent and is the first class which has a font. Therefore, you at first must check whether the current component is a TControl and then you can access its Font by considering TControl(Components[]).
Code: Pascal  [Select][+][-]
  1.     procedure TFormName.DoSomethingSpecial;
  2.     var
  3.       i: Integer;
  4.     begin
  5.       for i := 0 to Pred(ComponentCount) do
  6.         if Components[i] is TControl then
  7.           TControl(Components[i]).Font.Style := [fsBold];
  8.     end;
Title: Re: Pagecontrol - Panels - style
Post by: KodeZwerg on September 30, 2022, 05:07:38 pm
I cannot combine component with font, see attach.
If I enforce it, there is an error-message.
My bad, here is a quick fix
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   i: Integer;
  4.   LFont: TFont;
  5. begin
  6.   LFont := TFont.Create;
  7.   try
  8.     LFont.Name := 'Arial';
  9.     LFont.Color := clGreen;
  10.     LFont.Size := 11;
  11.     for i := 0 to Pred(Self.ComponentCount) do
  12.       begin
  13.         try
  14.           TControl(Self.Components[i]).Font := LFont;
  15.         except
  16.         end;
  17.       end;
  18.   finally
  19.     LFont.Free;
  20.   end;
  21. end;
Title: Re: Pagecontrol - Panels - style
Post by: Nicole on September 30, 2022, 05:46:56 pm
MUST it be on create?
I made a method from it and get:

Code: Pascal  [Select][+][-]
  1. [Window Title]
  2. Fehler
  3.  
  4. [Content]
  5. Projekt project_T hat Exception-Klasse »External: ACCESS VIOLATION« ausgelöst mit der Meldung:
  6. Access violation reading from address $FFFFFFFFFFFFFFFF.
  7.  
  8.  In Datei 'control.inc' in Zeile 3460:
  9. if FFont.IsEqual(Value) then exit;
  10.  
  11. [Ok]

it is this line

Code: Pascal  [Select][+][-]
  1. TControl(Self.Components[i]).Font := LFont;
Title: Re: Pagecontrol - Panels - style
Post by: Nicole on September 30, 2022, 06:06:30 pm
@Werner, thank you for the code. The loop works fine.

Unfortunately (in my case) it does "the same" as this:
Code: Pascal  [Select][+][-]
  1.  PageControl_Main.Font.Color:=AColor;

What I have at the moment are these lines

Code: Pascal  [Select][+][-]
  1.    For i:=0 to PageControl_Main.PageCount - 1 do
  2.      PageControl_Main.Pages[i].Color:=DarkRedColor;
  3.  
  4.    PageControl_Main.Font.Color:=DarkRedColor;

Those lines color the TFrames and TSpeedButtons nicely (see screenshot with the Button).

My problem are (see screenshot as well):
RadioBoxes and Checkboxes.

I attach you a screenshot with the radiobox:
The font stay black and are hardly readably.
Do I set the background to a brighter color, then the label stays darkRed with black fonts,
- hardly readably.

I want the red style and white fonts, like the lines, which "jump" to white.

So the screenshot shows you:
One "wanted" speedbutton and two "not wanted" RadioBoxes

Title: Re: Pagecontrol - Panels - style
Post by: KodeZwerg on September 30, 2022, 06:21:05 pm
MUST it be on create?
I made a method from it and get:

Code: Pascal  [Select][+][-]
  1. [Window Title]
  2. Fehler
  3.  
  4. [Content]
  5. Projekt project_T hat Exception-Klasse »External: ACCESS VIOLATION« ausgelöst mit der Meldung:
  6. Access violation reading from address $FFFFFFFFFFFFFFFF.
  7.  
  8.  In Datei 'control.inc' in Zeile 3460:
  9. if FFont.IsEqual(Value) then exit;
  10.  
  11. [Ok]

it is this line

Code: Pascal  [Select][+][-]
  1. TControl(Self.Components[i]).Font := LFont;

Since I do not know how or where you initialize LFont, another example.
Full working source:
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     Label1: TLabel;
  17.     Label2: TLabel;
  18.     Label3: TLabel;
  19.     Label4: TLabel;
  20.     Panel1: TPanel;
  21.     Panel2: TPanel;
  22.     procedure Button1Click(Sender: TObject);
  23.     procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  24.     procedure FormCreate(Sender: TObject);
  25.   private
  26.     FFont: TFont;
  27.     procedure ApplyFonts;
  28.   public
  29.  
  30.   end;
  31.  
  32. var
  33.   Form1: TForm1;
  34.  
  35. implementation
  36.  
  37. {$R *.lfm}
  38.  
  39. { TForm1 }
  40.  
  41. procedure TForm1.FormCreate(Sender: TObject);
  42. begin
  43.   FFont := nil;
  44. end;
  45.  
  46. procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  47. begin
  48.   if FFont <> nil then
  49.     FFont.Free;
  50.   CloseAction := caFree;
  51. end;
  52.  
  53. procedure TForm1.Button1Click(Sender: TObject);
  54. begin
  55.   ApplyFonts;
  56. end;
  57.  
  58. procedure TForm1.ApplyFonts;
  59. var
  60.   i: Integer;
  61. begin
  62.   if FFont = nil then
  63.     FFont := TFont.Create;
  64.   try
  65.     FFont.Name := 'Arial';
  66.     FFont.Color := clGreen;
  67.     FFont.Size := 11;
  68.     for i := 0 to Pred(Self.ComponentCount) do
  69.       begin
  70.         try
  71.           TControl(Self.Components[i]).Font := FFont;
  72.         except
  73.         end;
  74.       end;
  75.   finally
  76.   end;
  77. end;
  78.  
  79. end.
Watch carefully where I do what. It does not matter how you do aslong as it is in a straightforward way.
Title: Re: Pagecontrol - Panels - style
Post by: wp on September 30, 2022, 06:25:48 pm
As I wrote above, this is not possible with the standard LCL TRadioButtons. The same as in Delphi's VCL, BTW. Basically this should be documented on page Restrictions of the object inspector (or in the Restriction Browser in menu View), but I would not swear that these entries are up-to-date.
Title: Re: Pagecontrol - Panels - style
Post by: Lulu on September 30, 2022, 09:59:14 pm
Hi, to customize font's color on TCheckBox and TRadioButton, I do the following:
You can then modify the font color of the TLabel as your needs.
Attached a simple project to demonstrate.
Title: Re: Pagecontrol - Panels - style
Post by: KodeZwerg on October 01, 2022, 11:39:47 am
Hi, to customize font's color on TCheckBox and TRadioButton, I do the following:
When I would do that, I would SubClass and OwnerDraw.

My own try for a full working Windows DarkTheme support (created in Delphi not FPC!) is available here https://www.delphipraxis.net/207862-kodezwergs-real-theme-beispiel.html (https://www.delphipraxis.net/207862-kodezwergs-real-theme-beispiel.html)
It actually really react on OS changes for that matter but my own try looks not that pretty like if you would use Styles.
Title: Re: Pagecontrol - Panels - style
Post by: KodeZwerg on October 01, 2022, 03:19:42 pm
As I wrote above, this is not possible with the standard LCL TRadioButtons. The same as in Delphi's VCL, BTW. Basically this should be documented on page Restrictions of the object inspector (or in the Restriction Browser in menu View), but I would not swear that these entries are up-to-date.
No.
I proof it with images.
Title: Re: Pagecontrol - Panels - style
Post by: VisualLab on October 01, 2022, 03:24:10 pm
Hmm... Maybe it would be easier and safer:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.ApplyFonts;
  2. var
  3.   i: Integer;
  4. begin
  5.   if FFont = nil
  6.    then FFont := TFont.Create;
  7.   try
  8.     FFont.Name := 'Arial';
  9.     FFont.Color := clGreen;
  10.     FFont.Size := 11;
  11.     for i := 0 to Pred(Self.ControlCount) do
  12.       begin
  13.         try
  14.           TControl(Self.Controls[i]).Font := FFont;
  15.         except
  16.         end;
  17.       end;
  18.   finally
  19.   end;
  20. end;
  21.  

As it concerns the program window (TForm), it has a list of controls (Controls property) and their quantity (ControlCount property). It inherits them from the TWinControl class.
Title: Re: Pagecontrol - Panels - style
Post by: wp on October 01, 2022, 03:39:14 pm
As I wrote above, this is not possible with the standard LCL TRadioButtons. The same as in Delphi's VCL, BTW. Basically this should be documented on page Restrictions of the object inspector (or in the Restriction Browser in menu View), but I would not swear that these entries are up-to-date.
No.
I proof it with images.
Well, you turn off theme-services, and if you do this it works out of the box: Just set TRadioButton.Color and TRadioButton.Font.Color in the Object Inspector. Since the OI runs WITH theme services you do not get a visual feedback, but when the program runs the background and text colors have taken the corresponding values. Of course, only without theme-services. This results in the Win95 look. If you like that - fine; if you don't the same problem again.
Title: Re: Pagecontrol - Panels - style
Post by: KodeZwerg on October 01, 2022, 04:01:50 pm
@wp: I do agree your current post but not the post where you said it is not possible. That without themes it works out of box i do know, my method is just a general helper without need to type "radiobutton1.color, radiobutton1.font.color etc..." i can throw in whatever control and it works "out-of-box" :))
Title: [solved] Re: Pagecontrol - Panels - style
Post by: Nicole on October 03, 2022, 09:14:54 am
I installed BGRAD in the meanwhil and tried it, - and to sum it up: I will uninstall it.
There seems to be no RadioBox,  demos I cannot find.

ExCtrls is downloading at the moment for the next try.

PS
 - done-
Thank you KodeZwerg.
I solved it by exctrl
and thank all others for the answers as well!
TinyPortal © 2005-2018