Gehirnakrobatik rund um TPageControl

Rund um die LCL und andere Komponenten
charlytango
Beiträge: 1080
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Gehirnakrobatik rund um TPageControl

Beitrag von charlytango »

Seit etlichen Jahren benutze ich durchaus zur Zufriedenstellung TDINotebook als Navigations und Ordnungsoberfläche für meine Applikationen.
Das Teil ist von TExtendedNotebook abgeleitet (das wiederum TPagecontrol als Vorfahren hat), hat einige Macken aber auch viel Brauchbares.

Was aber irgendwie aus der Zeit gefallen zu sein scheint ist, dass direkt auf den Tabreitern kein "x" (bzw eine entsprechende Grafik) aufscheint mit dem man den entsprechenden Reiter schließen kann.

Ich hätte gerne neben den in TDINotebook verfügbaren Funktionen zumindest ein X bzw noch besser eine hübsche austauschbare Grafik mit einem Hover Effekt (man wird ja noch träumen dürfen) auf den Tabs.

Weil meine Fähigkeiten dafür scheinbar nicht ausreichen habe ich das Thema einigen KIs vorgeworfen (Grok, Perplexity, Claude) die mir sehr beeindruckende Codes geliefert haben indem sie auch TDINotebook erweitert haben. (also so 1500 Zeilen oder so).
Wirklich hervorragend strukturiert und auch mit entsprechenden Erklärungen.

nur....

Der Code funktioniert nicht ;-) --> das soll hier keine KI Diskussion werden.

Im Gegenteil, ich will im nahenden "Urlaub" eure brachliegenden Gehirne anzapfen, möglicherweise könnt ihr mir ja weiter helfen. Alles was dabei heraus kommt soll natürlich auch euch zur Verfügung stehen.

Scheinbar ist es nicht allzu leicht denn sonst gäbe es das schon, als Beispiel ist eine Szene aus Firefox angehängt
Dateianhänge
Screenshot 2025-06-04 160505.png
Screenshot 2025-06-04 160505.png (158.55 KiB) 852 mal betrachtet

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6845
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Gehirnakrobatik rund um TPageControl

Beitrag von af0815 »

Hat nicht Lazarus selbst sowas in den Quellen, wenn ich mir den Sourceeditor ansehe!?
Sowas meinst du.

Wenn die TDINotebook gefällt, warum wechseln ? Oder brauchst du TDINotebook erweitert?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

charlytango
Beiträge: 1080
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Gehirnakrobatik rund um TPageControl

Beitrag von charlytango »

af0815 hat geschrieben: Mi 4. Jun 2025, 16:38 Hat nicht Lazarus selbst sowas in den Quellen, wenn ich mir den Sourceeditor ansehe!?
Sowas meinst du.
Nein nicht wirklich. TPagecontrol/TExtendedNotebook kann zwar links auf dem Tabreiter ein Image einblenden, rechts auf dem Tab ein X zum Schließen gibt es nicht (zumindest kenn ich keine Komponente die das kann)
Die Browser scheinen übrigens mit gleichen Tabgrößen zu tricksen, offensichtlich ist es dann einfacher rechts im Tab etwas einzufügen.
af0815 hat geschrieben: Mi 4. Jun 2025, 16:38 Oder brauchst du TDINotebook erweitert?
Yep 8)

Edit: Bin aber auch schon mit einem einfachen Beispiel zufrieden ggg

Sieben
Beiträge: 292
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: Gehirnakrobatik rund um TPageControl

Beitrag von Sieben »

Option nboShowCloseButtons bei TPageControl...?

charlytango
Beiträge: 1080
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Gehirnakrobatik rund um TPageControl

Beitrag von charlytango »

Sieben hat geschrieben: Mi 4. Jun 2025, 17:25 Option nboShowCloseButtons bei TPageControl...?
scheinbar nein -- unter Windows keine Änderung.

nboShowCloseButtons
Enables close buttons on each tab control page. Requires support in the native tab control for a given platform.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6845
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Gehirnakrobatik rund um TPageControl

Beitrag von af0815 »

Schaut danach aus, das das von einer Betriebsystemkomponente abgeleitet ist. Jetzt ist die Frage kann die das ? Wenn nicht, dann schaut's öde aus.
Mal wieder in den Code der LCL schauen, wie das dort funktioniert.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Sieben
Beiträge: 292
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: Gehirnakrobatik rund um TPageControl

Beitrag von Sieben »

Dann hier mal ein Thread und eine Komponente, die dir vielleicht ein paar Start- oder Anhaltspunkte zum 'Selberzeichnen' liefern. Wie TCustomGrid den SortArrow auf seine Header zeichnet wäre evt auch noch ein geeigneter Anlaufpunkt.

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

Re: Gehirnakrobatik rund um TPageControl

Beitrag von wp_xyz »

Die Komponente ATTabs im ATFlatControls kann das auf jeden Fall (vom OPM installierbar). Allerdings würde ich ein paar Stunden brauchen, die richtige Farbeinstellung zu finden, unter den vielen, vielen Properties, denn die Default-Parameter sind nichts nach meinem Geschmack. (https://wiki.freepascal.org/ATTabs)

Eine andere Möglichkeit wäre JvTabBar aus dem JVCL-Paket (auch im OPM: Entweder installierst du dir alles, was aber ein ziemlich Dinosaurier ist, oder du wählst im OPM nur die Packages JvCoreLazD, JvStdCtrlsLazD und JvPageCompsLazD an (ich hoffe ich habe nichts vergessen...)).
Zuletzt geändert von wp_xyz am Mi 4. Jun 2025, 18:39, insgesamt 2-mal geändert.

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

Re: Gehirnakrobatik rund um TPageControl

Beitrag von wp_xyz »

[ sorry, versehentlicher Doppel-Post ]

charlytango
Beiträge: 1080
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Gehirnakrobatik rund um TPageControl

Beitrag von charlytango »

Ich weiss nicht ob ATTabs so ganz mein Fall ist
wp_xyz hat geschrieben: Mi 4. Jun 2025, 18:36 Eine andere Möglichkeit wäre JvTabBar aus dem JVCL-Paket
Aber JvTabBar mit der Demo JvTabBar_Pagelist ist schon eine charmante Sache, besonders wenn ein bestimmter User da auch gleich die Bildschirmskalierung eingebaut hat ;-)

Im Moment ist dann halt eine PageList und eine TabBar zu synchronisieren und dann mit den Fähigkeiten von TDINotebook zu ergänzen.
Wobei mir die Idee mit den TabBarPaintern zur Farbgebung schon sehr gefällt. So etwas würde ich mir übergreifend für alle Lazarus-Controls wünschen (frommer Wunsch)

charlytango
Beiträge: 1080
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Gehirnakrobatik rund um TPageControl

Beitrag von charlytango »

Also, ich hab mal die Demo hergenommen und habe versucht per Code einen Tab anzulegen (was gelungen ist) und in die korrespondierende Seite der zugeordneten TjvPagelist eine TForm "einzukleben" oder "einzudocken" oder auch anders zuzuordnen (woran ich kläglich gescheitert bin)

Die Logik scheint irgendwie ziemlich anders zu sein als bei TPageControl.

@af0815
Stand der Versuche liegt bei falls sich jemand darüber her machen mag;-)
Dateianhänge
JvTabBarDemo_PageList.zip
(42.34 KiB) 143-mal heruntergeladen

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

Re: Gehirnakrobatik rund um TPageControl

Beitrag von wp_xyz »

Nachdem ich den Punkt am Ende von " aForm.Parent := JvTabBar1.PageList.;" entfernt habe, läuft es...

Wenn dir die TJvPageList unheimlich ist: du kannst auch ein ganz normales Notebook als Seitencontainer nehmen. Du musst dann nur ein paar Event-Handler schreiben, um das Notebook synschron zu halten, z.B. wenn ein anderes Tab ausgewählt wird, musst man das auch im Notebook machen, usw. Bei der Pagelist ist sowas schon eingebaut.

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

Re: Gehirnakrobatik rund um TPageControl

Beitrag von fliegermichl »

Man kann auch bissi basteln. (Habe ich im internationalen Forum gefunden und etwas ergänzt - FormCreate)

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls,
  LCLIntf, LCLType, StdCtrls;

type
  {$IFDEF WINDOWS}
  { TPageControl }
  TPageControl = class(ComCtrls.TPageControl)
  private
    const btnSize = 10;

  protected
    procedure MouseDown(Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer); override;
    procedure PaintWindow(DC: HDC); override;
  end;
  {$ENDIF}

  { TForm1 }
  TForm1 = class(TForm)
    ImageList1: TImageList;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    TabSheet3: TTabSheet;
    procedure FormCreate(Sender: TObject);
  private
    bmp : TBitMap;
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{$IFDEF WINDOWS}
procedure TPageControl.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
var R : TRect;
begin
  inherited MouseDown(Button, Shift, X, Y);
  if Button = mbLeft then
  begin
    R := TabRect(ActivePageIndex);
    if PtInRect(Classes.Rect(R.Right - btnSize - 4, R.Top + 2,
                             R.Right - 4, R.Top + btnSize + 2),
                Classes.Point(X, Y))
    then ActivePage.Free;
  end;
end;

procedure TPageControl.PaintWindow(DC: HDC);
var
  i : integer;
  R : TRect;
  bm : TBitmap;
begin
  inherited PaintWindow(DC);

  bm := TBitmap.Create;
  try
    bm.SetSize(16, 16);
    Images.GetBitmap(0, bm);

    for i := 0 to Pred(PageCount) do
    begin
      R := TabRect(i);
      // Код привязан к размеру ImageList-а = 16
      StretchBlt(DC, R.Right - btnSize - 4, R.Top + 2,
                 btnSize, btnSize, bm.Canvas.Handle, 0, 0, 16, 16, cmSrcCopy);
    end;
  finally
    bm.Free;
  end;
end;

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
const BtnSize = 16;
begin
  ImageList1 := TImageList.Create(Application);
  bmp := TBitmap.Create;
  bmp.Width := BtnSize;
  bmp.Height := BtnSize;
  bmp.Canvas.Brush.Color := clWhite;
  bmp.Canvas.Pen.Color := clWhite;
  bmp.Canvas.Rectangle(0, 0, BtnSize, BtnSize);
  bmp.Canvas.Pen.Color := clRed;
  bmp.Canvas.MoveTo(2, 2);
  bmp.Canvas.LineTo(BtnSize-2, BtnSize-2);
  bmp.Canvas.MoveTo(BtnSize-2, 2);
  bmp.Canvas.LineTo(2, BtnSize-2);
  ImageList1.Add(bmp, nil);
  PageControl1 := TPageControl.Create(Application);
  PageControl1.Parent := self;
  PageControl1.Align := alClient;
  TabSheet1 := PageControl1.AddTabSheet; TabSheet1.Caption := 'Seite 1   ';
  TabSheet2 := PageControl1.AddTabSheet; TabSheet2.Caption := 'TabSheet 2   ';
  TabSheet3 := PageControl1.AddTabSheet; TabSheet3.Caption := 'TabSheet 3   ';
  PageControl1.Images := ImageList1;
end;

{$ENDIF}

end.
Das sieht dann so aus:

screenshot.png
screenshot.png (6.76 KiB) 688 mal betrachtet

charlytango
Beiträge: 1080
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Gehirnakrobatik rund um TPageControl

Beitrag von charlytango »

erstmal danke - klappt.
wp_xyz hat geschrieben: Do 5. Jun 2025, 00:12 um das Notebook synschron zu halten,...... Bei der Pagelist ist sowas schon eingebaut.
Genau das wäre ja fein -- aber du hast recht, etwas unheimlich ist es schon, wieso ist der Parent die Liste und nicht die einzelne Seite?
Woher weiß die Liste auf welche Seite die TForm eingehängt werden soll?

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

Re: Gehirnakrobatik rund um TPageControl

Beitrag von wp_xyz »

charlytango hat geschrieben: Do 5. Jun 2025, 10:38 erstmal danke - klappt.
wp_xyz hat geschrieben: Do 5. Jun 2025, 00:12 um das Notebook synschron zu halten,...... Bei der Pagelist ist sowas schon eingebaut.
Genau das wäre ja fein -- aber du hast recht, etwas unheimlich ist es schon, wieso ist der Parent die Liste und nicht die einzelne Seite?
Woher weiß die Liste auf welche Seite die TForm eingehängt werden soll?
Das wird irgendwie intern so umgelenkt, dass die akutelle Seite zum Parent der von dir erzeugten Form wird. Wenn du das nicht willst, kannst du auch eine beliebige Seite direkt angeben:

Code: Alles auswählen

  aForm.Parent := TJvPageList(JvTabBar1.PageList).Pages[1];
Der Typecast ist nötig, weil TJvTabBar die PageList lediglich als TCustomControl deklariert. Das wiederum ist eine Folge davon, dass man jede beliebige "Seiten"-Komponente für die Pages verwenden kann, sie muss nur die Routinen des IPageList-Interface implementieren. Es gibt noch ein zweites Beispiel mit einer TJvNotebookPageList, die sich vom normalen TNotebook der LCL ableitet.

Ganz schön geschickt gemacht, das ganze...

Antworten