Runde Ecken bei Panel?

Rund um die LCL und andere Komponenten
Antworten
Benutzeravatar
Aidex
Beiträge: 60
Registriert: Do 24. Sep 2020, 07:02
OS, Lazarus, FPC: Win10 64bit, Laz v2.0.10
CPU-Target: AMD64

Runde Ecken bei Panel?

Beitrag von Aidex »

Hallo und frohe Weihnachten!

Ich nutze Lazarus 2.0.10 auf Windows 10.
Ist es möglich einem Panel einen Border mit abgerundeten Ecken zu verpassen? Oder ein Bevel oder irgendwas mit runden Ecken?

Ich hatte mir früher mal eine Grafik-Routine programmiert, die einen Rand mit runden Ecken in ein Bitmap zeichnet. Aber das hat den Nachteil, dass man für ein Fenster, auf dem viele unterschiedlich große Panels sind, dann auch ebensoviele Bitmaps braucht. Das ist weder ressourcenschonend noch schnell (z.B. hackelig beim Scrollen einer langen Liste aus Panels mit runden Ecken).

Deshalb meine Frage, ob jemand etwas besseres weiß?
Danke und Grüße, Jörg

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Runde Ecken bei Panel?

Beitrag von wp_xyz »

Vielleicht nicht optimal, aber so geht's:
  • Ein Standard-Panel aufs Formular setzen
  • BevelOuter auf bvNone setzen, so dass das Panel keinen sichtbaren Rahmen mehr hat
  • Einen Handler für das OnPaint-Ereignis des Panels schreiben, der die Canvas-Methode RoundRect aufruft; diese erhält als letzte Parameter den Rundungsradius. Etwa so:

Code: Alles auswählen

procedure TForm1.Panel1Paint(Sender: TObject);
const
  R = 10;  // Rundungsradius
var
  panel: TPanel;
begin
  if not (Sender is TPanel) then exit;
  panel := TPanel(Sender);
  panel.Canvas.Brush.Style := bsClear;
  panel.Canvas.Pen.Color := clSilver;
  panel.Canvas.RoundRect(0, 0, panel.ClientWidth, panel.ClientHeight, R, R)
end; 
Diese Routine ist allgemein gehalten und kann auch als OnPaint Eventhandler für andere Panels eingetragen werden.

Benutzeravatar
Aidex
Beiträge: 60
Registriert: Do 24. Sep 2020, 07:02
OS, Lazarus, FPC: Win10 64bit, Laz v2.0.10
CPU-Target: AMD64

Re: Runde Ecken bei Panel?

Beitrag von Aidex »

Das ist ein guter Tipp!
Besten Dank!

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Runde Ecken bei Panel?

Beitrag von fliegermichl »

Du kannst jede Komponente (also auch Formulare und Panels) in eine beliebige Form bringen.
Schau dir mal das Beispiel unter <Lazarus>/examples/shapedcontrols an.

Benutzeravatar
Aidex
Beiträge: 60
Registriert: Do 24. Sep 2020, 07:02
OS, Lazarus, FPC: Win10 64bit, Laz v2.0.10
CPU-Target: AMD64

Re: Runde Ecken bei Panel?

Beitrag von Aidex »

Shaped ist auch ein guter Tipp! Danke!
Bisher kannte ich es nur für Fenster.
Da .SetShape() jedoch stumpf den Rest abschneidet, inkl. Umrandung und Inhalt, könnte man es zusätzlich zu einem selbstgezeichneten, abgerundeten Border/Bevel verwenden.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Runde Ecken bei Panel?

Beitrag von Winni »

Hi!

Mit SetShape kann man viel Spaß haben.

Falls jemand ne Komponente in Kreisform braucht:

Code: Alles auswählen

procedure TForm1.ShapeCircle(AControl: TWinControl);
const Deg2Rad = pi/180;
var
ABitmap: TBitmap;
Points: array of TPoint;
sinus,cosinus : single;
center : TPoint;
radius,i : integer;
begin
  ABitmap := TBitmap.Create;
  ABitmap.Monochrome := True;
  ABitmap.Width := AControl.Width;
  ABitmap.Height := AControl.Height;
  center := Point(ABitmap.Width div 2, ABitmap.height div 2);
  radius := min(Center.x, center.y)-2;

  with ABitmap.Canvas do
  begin
    Brush.Color := clBlack; // transparent color
    FillRect(0, 0, ABitmap.Width, ABitmap.Height);
    Pen.Color := clWhite; // mask color
    Pen.width := radius div 50 + 1;
    //showMessage (IntToStr(Radius)+' / '+IntToStr(Pen.width));
  end;
  SetLength(Points, 360);
  For i := 0 to 360-1 do
     begin
     sincos (i*Deg2Rad,sinus,cosinus);
     Points[i] := Point(round(cosinus*radius)+center.x,
                        round(sinus*radius)+center.y);
     ABitmap.Canvas.Line(center,Points[i]);
		 end;
  AControl.SetShape(ABitmap);
  ABitmap.Free;
end;
8ung! Wenn man SetShape auf eine Form anwendet, geht der TitleBar flöten!
Also rechtzeitig dafür sorgen, dass die Form bewegt oder geschlossen werden kann!

Winni
Dateianhänge
CirclePanel.png
CirclePanel.png (2.42 KiB) 1674 mal betrachtet

Antworten