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 begin
MainWin := TQtMainWindow(Application.MainForm.Handle); MainWin := TQtMainWindow(Application.MainForm.Handle);
MainWin.Activate; MainWin.Activate;
QMenuBar_setActiveAction(QMenuBarH(MainWin.MenuBar.Widget), Action); QMenuBar_setActiveAction(QMenuBarH(MainWin.GetMenuBar.Widget), Action);
end; end;
end; end;

View File

@ -636,6 +636,7 @@ type
TQtMainWindow = class(TQtWidget) TQtMainWindow = class(TQtWidget)
private private
FMenuBar: TQtMenuBar;
FBlocked: Boolean; FBlocked: Boolean;
FFirstPaintEvent: boolean; FFirstPaintEvent: boolean;
FIsFrameWindow: Boolean; FIsFrameWindow: Boolean;
@ -654,7 +655,6 @@ type
IsMainForm: Boolean; IsMainForm: Boolean;
MDIAreaHandle: TQtMDIArea; // valid only if we are fsMDIForm MDIAreaHandle: TQtMDIArea; // valid only if we are fsMDIForm
MDIChildArea: TQtMDIArea; // valid only if we are fsMDIChild MDIChildArea: TQtMDIArea; // valid only if we are fsMDIChild
MenuBar: TQtMenuBar;
ToolBar: TQtToolBar; ToolBar: TQtToolBar;
{$IFDEF QTSCROLLABLEFORMS} {$IFDEF QTSCROLLABLEFORMS}
ScrollArea: TQtWindowArea; ScrollArea: TQtWindowArea;
@ -666,6 +666,7 @@ type
procedure Activate; override; procedure Activate; override;
function CanAdjustClientRectOnResize: Boolean; override; function CanAdjustClientRectOnResize: Boolean; override;
function GetMenuBar: TQtMenuBar;
function getAcceptDropFiles: Boolean; override; function getAcceptDropFiles: Boolean; override;
function GetContainerWidget: QWidgetH; override; function GetContainerWidget: QWidgetH; override;
procedure grabMouse; override; procedure grabMouse; override;
@ -6791,10 +6792,10 @@ begin
ARet.Y := 0; ARet.Y := 0;
AParam.X := APt.X; AParam.X := APt.X;
AParam.Y := APt.Y; 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 begin
QWidget_mapToGlobal(TQtMainWindow(FOwner).MenuBar.Widget, @ARet, @AParam); QWidget_mapToGlobal(TQtMainWindow(FOwner).FMenuBar.Widget, @ARet, @AParam);
inc(ARet.Y, QWidget_height(TQtMainWindow(FOwner).MenuBar.Widget)); inc(ARet.Y, QWidget_height(TQtMainWindow(FOwner).FMenuBar.Widget));
Result.X := ARet.X; Result.X := ARet.X;
Result.Y := ARet.Y; Result.Y := ARet.Y;
end else end else
@ -7019,15 +7020,6 @@ begin
Result := QMainWindow_create(nil, QtWindow); 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 if (Application.MainForm <> nil) and
(Application.MainForm.FormStyle = fsMDIForm) and (Application.MainForm.FormStyle = fsMDIForm) and
@ -7096,19 +7088,6 @@ begin
QWidget_setMouseTracking(Result, True); QWidget_setMouseTracking(Result, True);
end; 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} {$IFDEF QTSCROLLABLEFORMS}
if QWidget_windowType(Result) = QtSplashScreen then if QWidget_windowType(Result) = QtSplashScreen then
FCentralWidget := QWidget_create(Result) FCentralWidget := QWidget_create(Result)
@ -7165,20 +7144,20 @@ end;
------------------------------------------------------------------------------} ------------------------------------------------------------------------------}
destructor TQtMainWindow.Destroy; destructor TQtMainWindow.Destroy;
begin 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 {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 Events are attached in TQtWSCustomForm.CreateHandle
Sometimes in various combinations we can 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.} Now it's totally safe.}
if QtWidgetSet.IsValidHandle(HWND(MenuBar)) then if QtWidgetSet.IsValidHandle(HWND(FMenuBar)) then
begin begin
MenuBar.DetachEvents; FMenuBar.DetachEvents;
if FOwnWidget and (MenuBar.Widget <> nil) then if FOwnWidget and (FMenuBar.Widget <> nil) then
QObject_deleteLater(MenuBar.Widget); QObject_deleteLater(FMenuBar.Widget);
MenuBar.Widget := nil; FMenuBar.Widget := nil;
FreeThenNil(MenuBar); FreeThenNil(FMenuBar);
end; end;
if MDIAreaHandle <> nil then if MDIAreaHandle <> nil then
@ -7256,6 +7235,38 @@ begin
{$ENDIF} {$ENDIF}
end; 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; function TQtMainWindow.getAcceptDropFiles: Boolean;
begin begin
Result := QWidget_acceptDrops(Widget); Result := QWidget_acceptDrops(Widget);
@ -7311,9 +7322,9 @@ begin
Result := ScrollArea.getClientOffset Result := ScrollArea.getClientOffset
else else
Result := inherited getClientOffset; Result := inherited getClientOffset;
if Assigned(ScrollArea) and Assigned(MenuBar) and if Assigned(ScrollArea) and Assigned(FMenuBar) and
(MenuBar.getVisible) then (FMenuBar.getVisible) then
inc(Result.Y, MenuBar.getHeight); inc(Result.Y, FMenuBar.getHeight);
{$ELSE} {$ELSE}
Result:=inherited getClientOffset; Result:=inherited getClientOffset;
{$ENDIF} {$ENDIF}
@ -16109,6 +16120,10 @@ begin
end; end;
function TQtMenu.actionHandle: QActionH; function TQtMenu.actionHandle: QActionH;
{$IFDEF DARWIN}
var
S: string;
{$ENDIF}
begin begin
if FActionHandle = nil then if FActionHandle = nil then
begin begin
@ -16118,6 +16133,13 @@ begin
FActionEventFilter := nil; FActionEventFilter := nil;
end; end;
FActionHandle := QMenu_menuAction(QMenuH(Widget)); 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); FActionEventFilter := QObject_hook_create(FActionHandle);
QObject_hook_hook_events(FActionEventFilter, @ActionEventFilter); QObject_hook_hook_events(FActionEventFilter, @ActionEventFilter);
end; end;
@ -16274,9 +16296,7 @@ var
QtK1, QtK2: integer; QtK1, QtK2: integer;
KeySequence: QKeySequenceH; KeySequence: QKeySequenceH;
{$IFDEF DARWIN} {$IFDEF DARWIN}
// WStr: WideString;
APrefs, AQuit: QKeySequenceH; APrefs, AQuit: QKeySequenceH;
S: String;
{$ENDIF} {$ENDIF}
begin begin
QtK1 := 0; QtK1 := 0;
@ -16298,19 +16318,14 @@ begin
{$IFDEF DARWIN} {$IFDEF DARWIN}
APrefs := QKeySequence_Create(QKeySequencePreferences); APrefs := QKeySequence_Create(QKeySequencePreferences);
AQuit := QKeySequence_Create(QKeySequenceQuit); 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 if QKeySequence_matches(KeySequence, APrefs) = QKeySequenceExactMatch then
QAction_setMenuRole(FActionHandle, QActionPreferencesRole) QAction_setMenuRole(FActionHandle, QActionPreferencesRole)
else else
if QKeySequence_matches(KeySequence, AQuit) = QKeySequenceExactMatch then if QKeySequence_matches(KeySequence, AQuit) = QKeySequenceExactMatch then
QAction_setMenuRole(FActionHandle, QActionQuitRole) QAction_setMenuRole(FActionHandle, QActionQuitRole)
else else
QAction_setMenuRole(FActionHandle, QActionNoRole); if QAction_menuRole(FActionHandle) = QActionTextHeuristicRole then
QAction_setMenuRole(FActionHandle, QActionNoRole);
QKeySequence_Destroy(APrefs); QKeySequence_Destroy(APrefs);
QKeySequence_Destroy(AQuit); QKeySequence_Destroy(AQuit);
{$ENDIF} {$ENDIF}
@ -18285,7 +18300,7 @@ begin
Parent := nil; Parent := nil;
Result := QWidget_create(Parent, QtToolTip); Result := QWidget_create(Parent, QtToolTip);
FDeleteLater := True; FDeleteLater := True;
MenuBar := nil; FMenuBar := nil;
{$IFDEF QTSCROLLABLEFORMS} {$IFDEF QTSCROLLABLEFORMS}
ScrollArea := nil; ScrollArea := nil;
{$ENDIF} {$ENDIF}
@ -19748,17 +19763,17 @@ begin
WidgetToNotify := QApplication_widgetAt(@p); WidgetToNotify := QApplication_widgetAt(@p);
if (WidgetToNotify <> nil) then if (WidgetToNotify <> nil) then
begin begin
if TQtMainWindow(Self).MenuBar.Widget <> nil then if TQtMainWindow(Self).FMenuBar.Widget <> nil then
begin begin
QMouseEvent_Pos(QMouseEventH(Event), @p); 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); pt := Point(P.X, P.Y);
if LCLIntf.PtInRect(R, pt) then if LCLIntf.PtInRect(R, pt) then
begin begin
Action := QMenuBar_actionAt(QMenuBarH(TQtMainWindow(Self).MenuBar.Widget), @p); Action := QMenuBar_actionAt(QMenuBarH(TQtMainWindow(Self).FMenuBar.Widget), @p);
if Action <> nil then if Action <> nil then
begin begin
QCoreApplication_notify(QCoreApplication_instance(), TQtMainWindow(Self).MenuBar.Widget, Event); QCoreApplication_notify(QCoreApplication_instance(), TQtMainWindow(Self).FMenuBar.Widget, Event);
QEvent_accept(Event); QEvent_accept(Event);
Result := True; Result := True;
end; end;

View File

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

View File

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

View File

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