Gtk3: implemented close buttons on notebook tabs.

This commit is contained in:
zeljan1 2025-03-30 18:26:39 +02:00
parent fa50636812
commit cec0a1fdbb
2 changed files with 46 additions and 5 deletions

View File

@ -415,8 +415,12 @@ type
TGtk3Page = class(TGtk3Container) TGtk3Page = class(TGtk3Container)
private private
FPageBox: PGtkBox;
FPageLabel: PGtkLabel; FPageLabel: PGtkLabel;
FCloseButton: PGtkButton;
strict private strict private
function GetCloseButtonVisible: boolean;
procedure SetCloseButtonVisible(AValue: boolean);
class procedure TabSheetLayoutSizeAllocate(AWidget: PGtkWidget; class procedure TabSheetLayoutSizeAllocate(AWidget: PGtkWidget;
AGdkRect: PGdkRectangle; Data: gpointer); cdecl; static; AGdkRect: PGdkRectangle; Data: gpointer); cdecl; static;
protected protected
@ -428,6 +432,7 @@ type
function ClientToScreen(var P:TPoint):boolean; override; function ClientToScreen(var P:TPoint):boolean; override;
function getClientOffset:TPoint; override; function getClientOffset:TPoint; override;
function getClientRect: TRect; override; function getClientRect: TRect; override;
property CloseButtonVisible: boolean read GetCloseButtonVisible write SetCloseButtonVisible;
end; end;
{ TGtk3NoteBook } { TGtk3NoteBook }
@ -5003,6 +5008,17 @@ begin
end; end;
end; end;
function TGtk3Page.GetCloseButtonVisible: boolean;
begin
Result := Assigned(FCloseButton) and FCloseButton^.is_visible;
end;
procedure TGtk3Page.SetCloseButtonVisible(AValue: boolean);
begin
if Assigned(FCloseButton) then
FCloseButton^.set_visible(AValue);
end;
class procedure TGtk3Page.TabSheetLayoutSizeAllocate( class procedure TGtk3Page.TabSheetLayoutSizeAllocate(
AWidget: PGtkWidget; AGdkRect: PGdkRectangle; Data: gpointer); cdecl; AWidget: PGtkWidget; AGdkRect: PGdkRectangle; Data: gpointer); cdecl;
var var
@ -5021,13 +5037,27 @@ begin
end; end;
function TGtk3Page.CreateWidget(const Params: TCreateParams): PGtkWidget; function TGtk3Page.CreateWidget(const Params: TCreateParams): PGtkWidget;
var
image: PGtkImage;
begin begin
FWidgetType := FWidgetType + [wtLayout]; FWidgetType := FWidgetType + [wtLayout];
FPageBox := TGtkBox.new(GTK_ORIENTATION_HORIZONTAL, 4);
FPageLabel:= TGtkLabel.new(PChar(Params.Caption)); FPageLabel:= TGtkLabel.new(PChar(Params.Caption));
FPageLabel^.set_use_underline(true); FPageLabel^.set_use_underline(true);
image := gtk_image_new_from_icon_name('window-close', GTK_ICON_SIZE_MENU);
FCloseButton := gtk_button_new();
gtk_button_set_relief(PGtkButton(FCloseButton), GTK_RELIEF_NONE);
gtk_container_add(PGtkContainer(FCloseButton), image);
gtk_widget_set_name(FCloseButton, 'tab-close-button'); // optional styling via css.
FPageBox^.pack_start(FPageLabel, False, False, 0);
FPageBox^.pack_start(FCloseButton, False, False, 0);
FPageBox^.show_all;
Self.FHasPaint:=true; Self.FHasPaint:=true;
// ref it to save it in case TabVisible is set to false // ref it to save it in case TabVisible is set to false
FPageLabel^.ref; FPageBox^.ref;
Result := TGtkBox.new(GTK_ORIENTATION_HORIZONTAL, 0); Result := TGtkBox.new(GTK_ORIENTATION_HORIZONTAL, 0);
FCentralWidget := TGtkLayout.new(nil, nil); FCentralWidget := TGtkLayout.new(nil, nil);
FCentralWidget^.set_app_paintable(True); FCentralWidget^.set_app_paintable(True);
@ -5043,7 +5073,7 @@ end;
procedure TGtk3Page.DestroyWidget; procedure TGtk3Page.DestroyWidget;
begin begin
// unref it to allow it to be destroyed // unref it to allow it to be destroyed
FPageLabel^.unref; FPageBox^.unref;
inherited DestroyWidget; inherited DestroyWidget;
end; end;
@ -5345,8 +5375,9 @@ begin
if IsWidgetOK then if IsWidgetOK then
begin begin
Gtk3Page := TGtk3Page(ACustomPage.Handle); Gtk3Page := TGtk3Page(ACustomPage.Handle);
Gtk3Page.CloseButtonVisible := nboShowCloseButtons in TCustomTabControl(LCLObject).Options;
with PGtkNoteBook(GetContainerWidget)^ do with PGtkNoteBook(GetContainerWidget)^ do
insert_page(Gtk3Page.Widget, Gtk3Page.FPageLabel, AIndex); insert_page(Gtk3Page.Widget, Gtk3Page.FPageBox, AIndex);
end; end;
end; end;

View File

@ -32,7 +32,7 @@ uses
LazLogger, LazLogger,
// widgetset // widgetset
WSComCtrls, WSLCLClasses, WSControls, WSProc, WSComCtrls, WSLCLClasses, WSControls, WSProc,
gtk3widgets; gtk3widgets, gtk3int;
type type
{ TGtk3WSCustomPage } { TGtk3WSCustomPage }
@ -1588,13 +1588,23 @@ end;
class procedure TGtk3WSCustomTabControl.UpdateProperties( class procedure TGtk3WSCustomTabControl.UpdateProperties(
const ATabControl: TCustomTabControl); const ATabControl: TCustomTabControl);
var
aPage: PGtkWidget;
aLCLPage: TGtk3Page;
i: Integer;
begin begin
if ATabControl is TTabControl then if ATabControl is TTabControl then
exit; exit;
// inherited UpdateProperties(ATabControl); // inherited UpdateProperties(ATabControl);
if not WSCheckHandleAllocated(ATabControl, 'ATabControl') then if not WSCheckHandleAllocated(ATabControl, 'ATabControl') then
Exit; Exit;
for i := 0 to PGtkNotebook(TGtk3NoteBook(ATabControl.Handle).GetContainerWidget)^.get_n_pages - 1 do
begin
aPage := PGtkNotebook(TGtk3NoteBook(ATabControl.Handle).GetContainerWidget)^.get_nth_page(i);
aLCLPage := TGtk3Page(HwndFromGtkWidget(aPage));
if Assigned(aLCLPage) then
aLCLPage.CloseButtonVisible := (nboShowCloseButtons in ATabControl.Options);
end;
if (nboHidePageListPopup in ATabControl.Options) then if (nboHidePageListPopup in ATabControl.Options) then
PGtkNotebook(TGtk3NoteBook(ATabControl.Handle).GetContainerWidget)^.popup_disable PGtkNotebook(TGtk3NoteBook(ATabControl.Handle).GetContainerWidget)^.popup_disable
else else