Cocoa: support dynamic menu in Modern Form Style Tool Bar

This commit is contained in:
rich2014 2024-10-31 21:09:19 +08:00
parent b07267959f
commit 8f2d7ca2b5
2 changed files with 65 additions and 18 deletions

View File

@ -25,7 +25,7 @@ type
TCocoaToolBarItemCreator = function ( const identifier: String;
const items: TCocoaConfigToolBarItems ): NSToolbarItem;
TCocoaToolBarItemActionHandler = procedure ( const Sender: id );
TCocoaToolBarItemMenuOnGetMenu = function: TMenuItem;
TCocoaToolBarItemMenuOnGetMenu = procedure ( const menu: TMenu );
TCocoaToolBarItemSharingOnGetItems = function ( item: NSToolBarItem ): TStringArray;
type
@ -67,7 +67,8 @@ type
TCocoaConfigToolBarItemMenu = object( TCocoaConfigToolBarItemWithAction )
showsIndicator: Boolean;
menu: TMenuItem;
dynamic: Boolean; // dynamically load each time before displaying the menu
menu: TMenu;
onGetMenu: TCocoaToolBarItemMenuOnGetMenu;
end;

View File

@ -106,7 +106,8 @@ type
TCocoaConfigToolBarItemClassMenu = class( TCocoaConfigToolBarItemClassWithAction )
protected
_showsIndicator: Boolean;
_menu: TMenuItem;
_dynamic: Boolean;
_menu: TMenu;
_onGetMenu: TCocoaToolBarItemMenuOnGetMenu;
public
constructor Create( const itemConfig: TCocoaConfigToolBarItemMenu );
@ -175,10 +176,15 @@ type
TCocoaToolBarItemMenu = objcclass( NSMenuToolBarItem )
private
_handler: TCocoaToolBarItemActionHandler;
_dynamic: Boolean;
_onGetMenu: TCocoaToolBarItemMenuOnGetMenu;
procedure lclItemAction( sender: id ); message 'lclItemAction:';
public
procedure lclSetHandler( const handler: TCocoaToolBarItemActionHandler );
message 'lclSetHandler:';
procedure lclSetDynamic( const dynamic: Boolean ); message 'lclSetDynamic:';
procedure lclSetOnGetMenu( const onGetMenu: TCocoaToolBarItemMenuOnGetMenu);
message 'lclSetOnGetMenu:';
end;
{ TCocoaToolBarItemGroupWrapper }
@ -429,8 +435,24 @@ end;
{ TCocoaToolBarItemMenu }
procedure TCocoaToolBarItemMenu.lclItemAction(sender: id);
procedure popupDynamicMenu;
var
view: NSView;
menu: TPopupMenu;
begin
view:= self.valueForKey( NSSTR('_itemViewer') );
menu:= TPopupMenu.Create( nil );
_onGetMenu( menu );
NSMenu(menu.handle).popUpMenuPositioningItem_atLocation_inView(
nil, NSMakePoint(0,0), view );
menu.Free;
end;
begin
_handler( sender );
if _dynamic then
popupDynamicMenu
else
_handler( sender );
end;
procedure TCocoaToolBarItemMenu.lclSetHandler( const handler: TCocoaToolBarItemActionHandler );
@ -438,6 +460,17 @@ begin
_handler:= handler;
end;
procedure TCocoaToolBarItemMenu.lclSetDynamic(const dynamic: Boolean);
begin
_dynamic:= dynamic;
end;
procedure TCocoaToolBarItemMenu.lclSetOnGetMenu(
const onGetMenu: TCocoaToolBarItemMenuOnGetMenu);
begin
_onGetMenu:= onGetMenu;
end;
{ TCocoaToolBarItemGroupWrapper }
procedure TCocoaToolBarItemGroupWrapper.lclItemAction( const sender: id );
@ -714,6 +747,7 @@ constructor TCocoaConfigToolBarItemClassMenu.Create(
begin
self.toClassConfig( @itemConfig );
_showsIndicator:= itemConfig.showsIndicator;
_dynamic:= itemConfig.dynamic;
_menu:= itemConfig.menu;
_onGetMenu:= itemConfig.onGetMenu;
end;
@ -721,24 +755,36 @@ end;
function TCocoaConfigToolBarItemClassMenu.createItem: NSToolBarItem;
var
cocoaItem: TCocoaToolBarItemMenu;
cocoaMenu: NSMenu;
procedure createStaticMenu;
begin
if NOT Assigned(_onAction) then
cocoaItem.setAction( nil );
if NOT Assigned(_menu) then begin
if Assigned(_onGetMenu) then begin
_menu:= TMenu.Create( nil );
_onGetMenu( _menu );
end;
end;
if Assigned(_menu) then begin
cocoaItem.setMenu( NSMenu(_menu.Handle) );
end;
end;
begin
cocoaItem:= TCocoaToolBarItemMenu.alloc.initWithItemIdentifier( self.identifier );
self.setItemAttribs( cocoaItem );
if NOT Assigned(_onAction) then
cocoaItem.setAction( nil );
cocoaItem.lclSetDynamic( _dynamic );
cocoaItem.lclSetOnGetMenu( _onGetMenu );
// only static menu needs to be created in advance
// for dynamic menu, it's created in TCocoaToolBarItemMenu.lclItemAction()
if NOT _dynamic then
createStaticMenu;
cocoaItem.setShowsIndicator( _showsIndicator );
if NOT Assigned(_menu) then begin
if Assigned(_onGetMenu) then
_menu:= _onGetMenu();
end;
if Assigned(_menu) then begin
cocoaMenu:= NSMenuItem(_menu.Handle).submenu;
cocoaItem.setMenu( cocoaMenu );
end;
cocoaItem.autorelease;
Result:= cocoaItem;
end;