Recent

Author Topic: Colored Buttons - Quick Hack  (Read 4154 times)

winni

  • Hero Member
  • *****
  • Posts: 3197
Colored Buttons - Quick Hack
« on: October 24, 2019, 12:05:56 am »
Hi!

There is always the question for colored buttons. The answer is NO - with the standard components. There are very impressive buttons in BGRAcontrols and other libs, but sometime you want a simple and quick solution. That's what I did.

I "misstreat" the BitButton. A little.

I use the glyph inside the TBitbtn and paint the deserved color on it.
The I write the caption on the glyph.
I store the caption string in the tag property and set the caption to length=0.
If I would not do that, the Button will try to write the caption a second time - not nice.

So at design time

* set all properties like always
* color and  font  are respected
* set Margin and Spacing to Zero
* dont care ,about Layout - it is not used

All you have to do is to init the BitButton with this procedure:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Bitinit(B : TBitBtn);
  2. var R : Trect;
  3.     cap: string;
  4.     dx,dy : integer;
  5.     P: Pstring;
  6.  begin
  7.   if B.Caption <> '' then
  8.     begin
  9.              cap := B.Caption;
  10.              B.Tag := PtrInt(@cap);
  11.              B.Caption := '';
  12.    end else // already done
  13.     begin
  14.              P := Pointer(B.Tag);
  15.             if B.Tag <> 0 then cap := P^ else cap := '???';
  16.     end;
  17.  
  18.   B.glyph.SetSize(B.width,B.height);
  19.   R := Rect(0,0,B.width,B.height);
  20.   B.Glyph.Canvas.brush.Color := B.Color;
  21.   B.Glyph.Canvas.FillRect(R);
  22.  
  23.   B.Glyph.Canvas.Font := B.Font;
  24.   dx :=(B.glyph.Width - B.Glyph.Canvas.TextWidth(cap)) div 2;
  25.   dy := (B.glyph.Height - B.Glyph.Canvas.TextHeight(cap)) div 2;
  26.   B.Glyph.Canvas.TextOut(dx,dy,cap);
  27. end;
  28.  

Then everything is fixed. As the glyph is a TBitmap you dont have to care about repainting - it is done automatic by the TBitmap.

If you have only on Button then use

Code: Pascal  [Select][+][-]
  1. Bitinit(BitBtn1);

If you have some more TBitBtn on your Form, you can do the init in a loop in FormCreate:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var i : integer;
  3. begin
  4.   for i := 0 to ComponentCount - 1 do
  5.     begin
  6.       if Components[i] is TBitBtn then
  7.                                              BitInit (TBitBtn(Components[i]));
  8.         end;// i
  9. end;
  10.  

Little image attached.

Have some fun with colored Buttons!

Winni

lainz

  • Hero Member
  • *****
  • Posts: 4460
    • https://lainz.github.io/
Re: Colored Buttons - Quick Hack
« Reply #1 on: October 24, 2019, 02:18:17 am »
Nice hack =)

You can also use a TSpeedButton, and add OnPaint event:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.SpeedButton1Paint(Sender: TObject);
  2. var
  3.   btn: TSpeedButton;
  4.   style: TTextStyle;
  5. begin
  6.   btn := TSpeedButton(Sender);
  7.   btn.Canvas.Brush.Color := clRed;
  8.   btn.Canvas.Rectangle(10, 10, btn.Width - 10, btn.Height - 10);
  9.   btn.Canvas.Font.Color := clBlack;
  10.   style.Alignment:=taCenter;
  11.   style.Layout:=tlCenter;
  12.   btn.Canvas.TextRect(Rect(0, 0, btn.Width, btn.Height), 0, 0, btn.Caption, style);
  13. end;  
« Last Edit: October 24, 2019, 02:19:49 am by lainz »

papsim

  • Newbie
  • Posts: 4
Re: Colored Buttons - Quick Hack
« Reply #2 on: October 24, 2019, 07:20:00 am »
Kudos to all developers of Lazarus and packages.

Coming from the old DOS world with monochrome monitors
and loving color, yes, Buttons were a problem.

My solution is to use a TBCPanel from BgraControls coupled with
a Label, and playing with the background to give 3D or 2D looks.

Sample Project attached.

Regards.

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: Colored Buttons - Quick Hack
« Reply #3 on: October 24, 2019, 09:20:08 am »
Hmm ok. While we're at it, why not use a TPanel?

Code: Delphi  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Panel1: TPanel;
  16.     procedure Panel1Click(Sender: TObject);
  17.     procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton;
  18.       Shift: TShiftState; X, Y: Integer);
  19.     procedure Panel1MouseEnter(Sender: TObject);
  20.     procedure Panel1MouseLeave(Sender: TObject);
  21.     procedure Panel1MouseUp(Sender: TObject; Button: TMouseButton;
  22.       Shift: TShiftState; X, Y: Integer);
  23.   private
  24.  
  25.   public
  26.  
  27.   end;
  28.  
  29. var
  30.   Form1: TForm1;
  31.  
  32. implementation
  33.  
  34. {$R *.lfm}
  35.  
  36. const
  37.   clNormal = $9393ff;
  38.   clHover = $8080ff;
  39.   clDown = $4040d0;
  40.  
  41. { TForm1 }
  42.  
  43. procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
  44.   Shift: TShiftState; X, Y: Integer);
  45. begin
  46.   if Button = mbLeft then
  47.   begin
  48.     Panel1.Color := clDown;
  49.     Panel1.BevelOuter:= bvLowered;
  50.   end;
  51. end;
  52.  
  53. procedure TForm1.Panel1Click(Sender: TObject);
  54. begin
  55.   ShowMessage('You clicked me');
  56. end;
  57.  
  58. procedure TForm1.Panel1MouseEnter(Sender: TObject);
  59. begin
  60.   Panel1.Color := clHover;
  61. end;
  62.  
  63. procedure TForm1.Panel1MouseLeave(Sender: TObject);
  64. begin
  65.   Panel1.Color := clNormal;
  66. end;
  67.  
  68. procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton;
  69.   Shift: TShiftState; X, Y: Integer);
  70. begin
  71.   if Button = mbLeft then
  72.   begin
  73.     Panel1.Color := clHover;
  74.     Panel1.BevelOuter:= bvRaised;
  75.   end;
  76. end;
  77.  
  78. end.
Conscience is the debugger of the mind

Thaddy

  • Hero Member
  • *****
  • Posts: 14213
  • Probably until I exterminate Putin.
Re: Colored Buttons - Quick Hack
« Reply #4 on: October 24, 2019, 09:22:29 am »
I "misstreat" the BitButton. A little.
That's a known work-around since Delphi 1, winni! It is also platform because this is Windows only: without theming it is a restriction of  Windows button widget.
Glad to see I am not the only one re-inventing wheels every now and then .... :o :-[
« Last Edit: October 24, 2019, 09:47:42 am by Thaddy »
Specialize a type, not a var.

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Colored Buttons - Quick Hack
« Reply #5 on: October 24, 2019, 10:21:46 am »
@Thaddy

Developed and tested on Linux yesterday. So: Windows only????

The blind man talks about colors.

Winni


lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Colored Buttons - Quick Hack
« Reply #6 on: October 24, 2019, 10:33:45 am »
Developed and tested on Linux yesterday. So: Windows only????

He probably means that in Linux you shouldn't have any problem setting Color for buttons, so the "workaround" is useful only for Windows. That is, it's a solution to a known Windows-only problem.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Colored Buttons - Quick Hack
« Reply #7 on: October 24, 2019, 10:51:09 am »
@Lucamar

That was right: On elder Linux versions the simple TButtons could get colored.

With my current version this is not possible anymore (Suse Tumbleweed, 64 Bit, gtk2).

That's why I made that. Yesterday!

Winni

Thaddy

  • Hero Member
  • *****
  • Posts: 14213
  • Probably until I exterminate Putin.
Re: Colored Buttons - Quick Hack
« Reply #8 on: October 24, 2019, 11:12:32 am »
@winni
I have no problem at all to set the colors on Raspbian Buster (most recent Debian).
Specialize a type, not a var.

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Colored Buttons - Quick Hack
« Reply #9 on: October 24, 2019, 11:27:47 am »
@Thaddy

Hmm - just tested again: only gray. So this might be a problem (again) with KDE Plasma !?
It is full of errors.

Winni

Thaddy

  • Hero Member
  • *****
  • Posts: 14213
  • Probably until I exterminate Putin.
Re: Colored Buttons - Quick Hack
« Reply #10 on: October 24, 2019, 11:30:11 am »
Yes, KDE can be a problem but you wrote you were using GTK?
Specialize a type, not a var.

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Colored Buttons - Quick Hack
« Reply #11 on: October 24, 2019, 06:48:47 pm »
Hm, unclear question.

I mean:

Project --> Preferences -->Compiler --> Configuration
shows:

LCL-Widgetset: "gtk2"

zeljko

  • Hero Member
  • *****
  • Posts: 1594
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: Colored Buttons - Quick Hack
« Reply #12 on: October 24, 2019, 07:44:26 pm »
With qt/qt5 you can change TButton/TBitBtn color to anything on win,linux and mac.

 

TinyPortal © 2005-2018