Qt5: completelly reworked menubar. Now it's created on demand.

This commit is contained in:
Željan Rikalo 2023-01-30 18:22:46 +01:00
parent 0bd7051152
commit e41c66e9f4
5 changed files with 86 additions and 78 deletions

View File

@ -1687,7 +1687,7 @@ begin
begin
MainWin := TQtMainWindow(Application.MainForm.Handle);
MainWin.Activate;
QMenuBar_setActiveAction(QMenuBarH(MainWin.MenuBar.Widget), Action);
QMenuBar_setActiveAction(QMenuBarH(MainWin.GetMenuBar.Widget), Action);
end;
end;

View File

@ -636,6 +636,7 @@ type
TQtMainWindow = class(TQtWidget)
private
FMenuBar: TQtMenuBar;
FBlocked: Boolean;
FFirstPaintEvent: boolean;
FIsFrameWindow: Boolean;
@ -654,7 +655,6 @@ type
IsMainForm: Boolean;
MDIAreaHandle: TQtMDIArea; // valid only if we are fsMDIForm
MDIChildArea: TQtMDIArea; // valid only if we are fsMDIChild
MenuBar: TQtMenuBar;
ToolBar: TQtToolBar;
{$IFDEF QTSCROLLABLEFORMS}
ScrollArea: TQtWindowArea;
@ -666,6 +666,7 @@ type
procedure Activate; override;
function CanAdjustClientRectOnResize: Boolean; override;
function GetMenuBar: TQtMenuBar;
function getAcceptDropFiles: Boolean; override;
function GetContainerWidget: QWidgetH; override;
procedure grabMouse; override;
@ -6791,10 +6792,10 @@ begin
ARet.Y := 0;
AParam.X := APt.X;
AParam.Y := APt.Y;
if Assigned(TQtMainWindow(FOwner).MenuBar) and TQtMainWindow(FOwner).MenuBar.getVisible then
if Assigned(TQtMainWindow(FOwner).FMenuBar) and TQtMainWindow(FOwner).FMenuBar.getVisible then
begin
QWidget_mapToGlobal(TQtMainWindow(FOwner).MenuBar.Widget, @ARet, @AParam);
inc(ARet.Y, QWidget_height(TQtMainWindow(FOwner).MenuBar.Widget));
QWidget_mapToGlobal(TQtMainWindow(FOwner).FMenuBar.Widget, @ARet, @AParam);
inc(ARet.Y, QWidget_height(TQtMainWindow(FOwner).FMenuBar.Widget));
Result.X := ARet.X;
Result.Y := ARet.Y;
end else
@ -7019,15 +7020,6 @@ begin
Result := QMainWindow_create(nil, QtWindow);
MenuBar := TQtMenuBar.Create({$IFDEF DARWIN}nil{$ELSE}Result{$ENDIF});
if not (csDesigning in LCLObject.ComponentState) then
MenuBar.FIsApplicationMainMenu := True
else
{$IFNDEF DARWIN}
MenuBar.setProperty(MenuBar.Widget,'lcldesignmenubar',1)
{$ENDIF}
;
if (Application.MainForm <> nil) and
(Application.MainForm.FormStyle = fsMDIForm) and
@ -7096,19 +7088,6 @@ begin
QWidget_setMouseTracking(Result, True);
end;
{$IFDEF DARWIN}
if TCustomForm(LCLObject).Menu <> nil then
MenuBar := TQtMenuBar.Create(Result);
if Assigned(MenuBar) then
begin
QMenuBar_setNativeMenuBar(QMenuBarH(MenuBar.Widget), False);
end;
{$ELSE}
MenuBar := TQtMenuBar.Create(Result);
if (csDesigning in LCLObject.ComponentState) then
MenuBar.setProperty(MenuBar.Widget,'lcldesignmenubar',1);
{$ENDIF}
{$IFDEF QTSCROLLABLEFORMS}
if QWidget_windowType(Result) = QtSplashScreen then
FCentralWidget := QWidget_create(Result)
@ -7165,20 +7144,20 @@ end;
------------------------------------------------------------------------------}
destructor TQtMainWindow.Destroy;
begin
// The main window takes care of the menubar handle
// The main window takes care of the FMenuBar handle
{handle validator is added since we added events to
menubar in r33309 (because of font changes).
FMenuBar in r33309 (because of font changes).
Events are attached in TQtWSCustomForm.CreateHandle
Sometimes in various combinations we can
crash here because MenuBar <> nil but not valid handle.
crash here because FMenuBar <> nil but not valid handle.
Now it's totally safe.}
if QtWidgetSet.IsValidHandle(HWND(MenuBar)) then
if QtWidgetSet.IsValidHandle(HWND(FMenuBar)) then
begin
MenuBar.DetachEvents;
if FOwnWidget and (MenuBar.Widget <> nil) then
QObject_deleteLater(MenuBar.Widget);
MenuBar.Widget := nil;
FreeThenNil(MenuBar);
FMenuBar.DetachEvents;
if FOwnWidget and (FMenuBar.Widget <> nil) then
QObject_deleteLater(FMenuBar.Widget);
FMenuBar.Widget := nil;
FreeThenNil(FMenuBar);
end;
if MDIAreaHandle <> nil then
@ -7256,6 +7235,38 @@ begin
{$ENDIF}
end;
function TQtMainWindow.GetMenuBar: TQtMenuBar;
var
AParent: QWidgetH;
begin
if not Assigned(FMenuBar) then
begin
{$IFDEF DARWIN}
if IsMainForm then
AParent := nil
else
AParent := Widget;
{$ELSE}
AParent := Widget;
{$ENDIF}
FMenuBar := TQtMenuBar.Create(AParent);
if not (csDesigning in LCLObject.ComponentState) then
FMenuBar.FIsApplicationMainMenu := {$IFDEF DARWIN}False{$ELSE}IsMainForm{$ENDIF}
else
{$IFNDEF DARWIN}
FMenuBar.setProperty(FMenuBar.Widget,'lcldesignmenubar',1)
{$ENDIF}
;
{$IFDEF DARWIN}
if (csDesigning in LCLObject.ComponentState) or not IsMainForm then
QMenuBar_setNativeMenuBar(QMenuBarH(MenuBar.Widget), False);
{$ENDIF}
FMenuBar.AttachEvents;
end;
Result := FMenuBar;
end;
function TQtMainWindow.getAcceptDropFiles: Boolean;
begin
Result := QWidget_acceptDrops(Widget);
@ -7311,9 +7322,9 @@ begin
Result := ScrollArea.getClientOffset
else
Result := inherited getClientOffset;
if Assigned(ScrollArea) and Assigned(MenuBar) and
(MenuBar.getVisible) then
inc(Result.Y, MenuBar.getHeight);
if Assigned(ScrollArea) and Assigned(FMenuBar) and
(FMenuBar.getVisible) then
inc(Result.Y, FMenuBar.getHeight);
{$ELSE}
Result:=inherited getClientOffset;
{$ENDIF}
@ -16109,6 +16120,10 @@ begin
end;
function TQtMenu.actionHandle: QActionH;
{$IFDEF DARWIN}
var
S: string;
{$ENDIF}
begin
if FActionHandle = nil then
begin
@ -16118,6 +16133,13 @@ begin
FActionEventFilter := nil;
end;
FActionHandle := QMenu_menuAction(QMenuH(Widget));
{$IFDEF DARWIN}
S := FMenuItem.Caption;
{$warning must find better way to map about role}
if S.StartsWith('about',True) then
QAction_setMenuRole(FActionHandle, QActionAboutRole);
{$ENDIF}
FActionEventFilter := QObject_hook_create(FActionHandle);
QObject_hook_hook_events(FActionEventFilter, @ActionEventFilter);
end;
@ -16274,9 +16296,7 @@ var
QtK1, QtK2: integer;
KeySequence: QKeySequenceH;
{$IFDEF DARWIN}
// WStr: WideString;
APrefs, AQuit: QKeySequenceH;
S: String;
{$ENDIF}
begin
QtK1 := 0;
@ -16298,19 +16318,14 @@ begin
{$IFDEF DARWIN}
APrefs := QKeySequence_Create(QKeySequencePreferences);
AQuit := QKeySequence_Create(QKeySequenceQuit);
// AAbout := QKeySequence_Create(QKeySequence);
S := FMenuItem.Caption;
{$warning must find better way to map about role}
if S.StartsWith('about',True) then
QAction_setMenuRole(FActionHandle, QActionAboutRole)
else
if QKeySequence_matches(KeySequence, APrefs) = QKeySequenceExactMatch then
QAction_setMenuRole(FActionHandle, QActionPreferencesRole)
else
if QKeySequence_matches(KeySequence, AQuit) = QKeySequenceExactMatch then
QAction_setMenuRole(FActionHandle, QActionQuitRole)
else
QAction_setMenuRole(FActionHandle, QActionNoRole);
if QAction_menuRole(FActionHandle) = QActionTextHeuristicRole then
QAction_setMenuRole(FActionHandle, QActionNoRole);
QKeySequence_Destroy(APrefs);
QKeySequence_Destroy(AQuit);
{$ENDIF}
@ -18285,7 +18300,7 @@ begin
Parent := nil;
Result := QWidget_create(Parent, QtToolTip);
FDeleteLater := True;
MenuBar := nil;
FMenuBar := nil;
{$IFDEF QTSCROLLABLEFORMS}
ScrollArea := nil;
{$ENDIF}
@ -19748,17 +19763,17 @@ begin
WidgetToNotify := QApplication_widgetAt(@p);
if (WidgetToNotify <> nil) then
begin
if TQtMainWindow(Self).MenuBar.Widget <> nil then
if TQtMainWindow(Self).FMenuBar.Widget <> nil then
begin
QMouseEvent_Pos(QMouseEventH(Event), @p);
QWidget_geometry(TQtMainWindow(Self).MenuBar.Widget, @R);
QWidget_geometry(TQtMainWindow(Self).FMenuBar.Widget, @R);
pt := Point(P.X, P.Y);
if LCLIntf.PtInRect(R, pt) then
begin
Action := QMenuBar_actionAt(QMenuBarH(TQtMainWindow(Self).MenuBar.Widget), @p);
Action := QMenuBar_actionAt(QMenuBarH(TQtMainWindow(Self).FMenuBar.Widget), @p);
if Action <> nil then
begin
QCoreApplication_notify(QCoreApplication_instance(), TQtMainWindow(Self).MenuBar.Widget, Event);
QCoreApplication_notify(QCoreApplication_instance(), TQtMainWindow(Self).FMenuBar.Widget, Event);
QEvent_accept(Event);
Result := True;
end;

View File

@ -6134,13 +6134,13 @@ begin
if AMenuWidget is TQtMenuBar then
begin
R := AWidget.LCLObject.ClientRect;
R1 := QtMainWindow.MenuBar.getGeometry;
R1 := QtMainWindow.GetMenuBar.getGeometry;
R1.Right := R.Right;
QtMenuBar.setGeometry(R1);
QtMainWindow.setMenuBar(QMenuBarH(QtMenuBar.Widget));
end
else
QtMainWindow.setMenuBar(QMenuBarH(QtMainWindow.MenuBar.Widget));
QtMainWindow.setMenuBar(QMenuBarH(QtMainWindow.GetMenuBar.Widget));
end;
end;

View File

@ -152,8 +152,6 @@ begin
if Assigned(QtFrame.ScrollArea) then
QtFrame.ScrollArea.AttachEvents;
{$ENDIF}
if Assigned(QtFrame.MenuBar) then
QtFrame.MenuBar.AttachEvents;
Result := TLCLIntfHandle(QtFrame);
end;
@ -256,9 +254,7 @@ begin
if Assigned(QtMainWindow.ScrollArea) then
QtMainWindow.ScrollArea.AttachEvents;
{$ENDIF}
if Assigned(QtMainWindow.MenuBar) then
QtMainWindow.MenuBar.AttachEvents;
if not IsFormDesign(AForm) and
(AForm.FormStyle in [fsMDIChild]) and
(Application.MainForm.FormStyle = fsMdiForm) then
@ -1037,21 +1033,18 @@ begin
if Assigned(TCustomForm(AWinControl).Menu) then
begin
AWin := TQtMainWindow(AWinControl.Handle);
if Assigned(AWin.MenuBar) then
begin
AWin.MenuBar.sizeHint(@ASize);
// geometry isn't updated yet
if ASize.cy < 10 then
ASize.cy := 0;
// we must use real geometry, and then exclude menubar height.
aClientRect := AWin.getGeometry;
OffsetRect(aClientRect, -aClientRect.Left, -aClientRect.Top);
dec(AClientRect.Bottom, ASize.cy);
{$IFDEF VerboseQtResize}
DebugLn('TQtWSCustomForm.getDefaultClientRect ',dbgsName(AWinControl),' ',dbgs(AWin.getClientBounds),' mnuBarHeight ',dbgs(AWin.MenuBar.getHeight),' ASize=',dbgs(ASize),' FINAL=',dbgs(AClientRect));
{$ENDIF}
Result := True;
end;
AWin.GetMenuBar.sizeHint(@ASize);
// geometry isn't updated yet
if ASize.cy < 10 then
ASize.cy := 0;
// we must use real geometry, and then exclude menubar height.
aClientRect := AWin.getGeometry;
OffsetRect(aClientRect, -aClientRect.Left, -aClientRect.Top);
dec(AClientRect.Bottom, ASize.cy);
{$IFDEF VerboseQtResize}
DebugLn('TQtWSCustomForm.getDefaultClientRect ',dbgsName(AWinControl),' ',dbgs(AWin.getClientBounds),' mnuBarHeight ',dbgs(AWin.MenuBar.getHeight),' ASize=',dbgs(ASize),' FINAL=',dbgs(AClientRect));
{$ENDIF}
Result := True;
end;
end;
end;

View File

@ -173,7 +173,7 @@ var
begin
{$ifdef VerboseQt}
WriteLn('trace:> [TQtWSMenuItem.CreateHandle] Caption: ', AMenuItem.Caption,
' Subitems: ' + IntToStr(AMenuItem.Count));
' Subitems: ' + IntToStr(AMenuItem.Count) +' HandleAllocated ? ', AMenuItem.HandleAllocated);
Write('trace:< [TQtWSMenuItem.CreateHandle]');
{$endif}
@ -442,9 +442,9 @@ begin
((AParent is TCustomForm) or (AParent is TCustomFrame)) then
begin
if (AParent is TCustomForm) then
MenuBar := TQtMainWindow(TCustomForm(AParent).Handle).MenuBar
MenuBar := TQtMainWindow(TCustomForm(AParent).Handle).GetMenuBar
else
MenuBar := TQtMainWindow(TCustomFrame(AParent).Handle).MenuBar;
MenuBar := TQtMainWindow(TCustomFrame(AParent).Handle).GetMenuBar;
Result := HMENU(MenuBar);
end else
begin