mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-03 21:40:20 +02:00
* Implemented cocoa TMainMenu support
* Implemented shortcut support in menus (Not all keys are supported yet) * Improved handling of sub-menus git-svn-id: trunk@43792 -
This commit is contained in:
parent
a491cb1360
commit
58b46afe02
@ -112,6 +112,8 @@ type
|
||||
procedure FreeStockItems;
|
||||
procedure FreeSysColorBrushes;
|
||||
|
||||
procedure SetMainMenu(const AMenu: HMENU);
|
||||
|
||||
{todo:}
|
||||
function DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor; override;
|
||||
procedure DCSetPixel(CanvasHandle: HDC; X, Y: integer; AColor: TGraphicsColor); override;
|
||||
|
@ -397,6 +397,12 @@ begin
|
||||
DeleteAndNilObject(FSysColorBrushes[i]);
|
||||
end;
|
||||
|
||||
procedure TCocoaWidgetSet.SetMainMenu(const AMenu: HMENU);
|
||||
begin
|
||||
if AMenu<>0 then
|
||||
NSApp.setMainMenu(NSMenu(AMenu));
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
Method: TCocoaWidgetSet.GetAppHandle
|
||||
Returns: Returns NSApp object, created via NSApplication.sharedApplication
|
||||
|
@ -6,8 +6,9 @@ unit CocoaUtils;
|
||||
interface
|
||||
|
||||
uses
|
||||
classes,
|
||||
MacOSAll, CocoaAll,
|
||||
Types, LCLType;
|
||||
Types, LCLType, LCLProc, menus;
|
||||
|
||||
const
|
||||
LCLEventSubTypeMessage = MaxShort - 1;
|
||||
@ -61,6 +62,8 @@ function NSColorToRGB(const Color: NSColor): TColorRef; inline;
|
||||
function NSColorToColorRef(const Color: NSColor): TColorRef;
|
||||
function ColorToNSColor(const Color: TColorRef): NSColor; inline;
|
||||
|
||||
procedure ShortcutToKeyEquivalent(const AShortCut: TShortcut; out Key: string; out shiftKeyMask: NSUInteger);
|
||||
|
||||
implementation
|
||||
|
||||
const
|
||||
@ -152,6 +155,29 @@ begin
|
||||
((Color shr 16) and $FF) / $FF, 1);
|
||||
end;
|
||||
|
||||
procedure ShortcutToKeyEquivalent(const AShortCut: TShortcut; out Key: string; out shiftKeyMask: NSUInteger);
|
||||
var
|
||||
w: word;
|
||||
s: TShiftState;
|
||||
begin
|
||||
ShortCutToKey(AShortCut, w, s);
|
||||
case w of
|
||||
VK_DELETE: key := char(NSDeleteCharacter);
|
||||
VK_OEM_2 : key := char(44);
|
||||
else
|
||||
key := lowercase(char(w and $ff));
|
||||
end;
|
||||
shiftKeyMask := 0;
|
||||
if ssShift in s then
|
||||
ShiftKeyMask := ShiftKeyMask + NSShiftKeyMask;
|
||||
if ssAlt in s then
|
||||
ShiftKeyMask := ShiftKeyMask + NSAlternateKeyMask;
|
||||
if ssCtrl in s then
|
||||
ShiftKeyMask := ShiftKeyMask + NSControlKeyMask;
|
||||
if ssMeta in s then
|
||||
ShiftKeyMask := ShiftKeyMask + NSCommandKeyMask;
|
||||
end;
|
||||
|
||||
function CFStringToStr(AString: CFStringRef; Encoding: CFStringEncoding = DEFAULT_CFSTRING_ENCODING): String;
|
||||
var
|
||||
Str: Pointer;
|
||||
|
@ -246,7 +246,26 @@ begin
|
||||
end;
|
||||
|
||||
procedure TLCLWindowCallback.Activate;
|
||||
var
|
||||
ACustForm: TCustomForm;
|
||||
begin
|
||||
ACustForm := Target as TCustomForm;
|
||||
|
||||
if (ACustForm.Menu <> nil) and
|
||||
(ACustForm.Menu.HandleAllocated) then
|
||||
begin
|
||||
if NSObject(ACustForm.Menu.Handle).isKindOfClass_(TCocoaMenuItem) then
|
||||
begin
|
||||
if TCocoaMenuItem(ACustForm.Menu.Handle).hasSubmenu then
|
||||
CocoaWidgetSet.SetMainMenu(HMENU(TCocoaMenuItem(ACustForm.Menu.Handle).submenu))
|
||||
else
|
||||
debugln('Warning: Menu does not have a valid handle.');
|
||||
end
|
||||
else
|
||||
CocoaWidgetSet.SetMainMenu(ACustForm.Menu.Handle);
|
||||
end
|
||||
else
|
||||
CocoaWidgetSet.SetMainMenu(0);
|
||||
LCLSendActivateMsg(Target, WA_ACTIVE, false);
|
||||
end;
|
||||
|
||||
|
@ -25,6 +25,8 @@ uses
|
||||
// Libs
|
||||
CocoaAll,
|
||||
MacOSAll,
|
||||
// RTL
|
||||
sysutils,
|
||||
// LCL
|
||||
Controls, Forms, Menus, Graphics, LCLType, LMessages, LCLProc, Classes,
|
||||
// Widgetset
|
||||
@ -113,7 +115,7 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
class function TCocoaWSMenu.CreateHandle(const AMenu: TMenu): HMENU;
|
||||
begin
|
||||
Result:=HMENU(TCocoaMenu.alloc.initWithTitle(NSString.alloc.initWithCString('hello world')));
|
||||
Result:=HMENU(TCocoaMenu.alloc.init) ;
|
||||
end;
|
||||
|
||||
{ TCocoaWSMenuItem }
|
||||
@ -129,15 +131,25 @@ var
|
||||
ParObj : NSObject;
|
||||
Parent : TCocoaMenu;
|
||||
item : NSMenuItem;
|
||||
ns : NSString;
|
||||
s : string;
|
||||
begin
|
||||
if not Assigned(AMenuItem) or (AMenuItem.Handle=0) or not Assigned(AMenuItem.Parent) or (AMenuItem.Parent.Handle=0) then Exit;
|
||||
ParObj:=NSObject(AMenuItem.Parent.Handle);
|
||||
|
||||
if ParObj.isKindOfClass_(NSMenuItem) then
|
||||
begin
|
||||
item:=NSMenuItem(AMenuItem.Handle);
|
||||
if not item.hasSubmenu then item.setSubmenu(TCocoaMenu.alloc.initWithTitle(NSSTR('')));
|
||||
Parent:=TCocoaMenu(item.submenu);
|
||||
if not NSMenuItem(ParObj).hasSubmenu then
|
||||
begin
|
||||
s := AMenuItem.Parent.Caption;
|
||||
DeleteAmpersands(s);
|
||||
ns := NSStringUtf8(pchar(s));
|
||||
Parent := TCocoaMenu.alloc.initWithTitle(ns);
|
||||
NSMenuItem(ParObj).setSubmenu(Parent);
|
||||
ns.release;
|
||||
end
|
||||
else
|
||||
Parent:=TCocoaMenu(NSMenuItem(ParObj).submenu);
|
||||
end else if ParObj.isKindOfClass_(NSMenu) then
|
||||
Parent:=TCocoaMenu(ParObj)
|
||||
else
|
||||
@ -157,7 +169,12 @@ end;
|
||||
class function TCocoaWSMenuItem.CreateHandle(const AMenuItem: TMenuItem): HMENU;
|
||||
var
|
||||
item : NSMenuItem;
|
||||
ANSMenu : NSMenu;
|
||||
s : string;
|
||||
ns : NSString;
|
||||
nsKey : NSString;
|
||||
key : string;
|
||||
ShiftSt : NSUInteger;
|
||||
begin
|
||||
if not Assigned(AMenuItem) then Exit;
|
||||
|
||||
@ -165,10 +182,24 @@ begin
|
||||
item := NSMenuItem.separatorItem
|
||||
else
|
||||
begin
|
||||
ns := NSStringUtf8(AMenuItem.Caption);
|
||||
s := AMenuItem.Caption;
|
||||
DeleteAmpersands(s);
|
||||
ShortcutToKeyEquivalent(AMenuItem.ShortCut, key, ShiftSt);
|
||||
|
||||
nsKey := NSString(CFStringCreateWithCString(nil, pointer(pchar(key)), kCFStringEncodingASCII));
|
||||
ns := NSStringUtf8(s);
|
||||
item := TCocoaMenuItem.alloc.initWithTitle_action_keyEquivalent(ns,
|
||||
objcselector('lclItemSelected:'), NSString.alloc.init);
|
||||
objcselector('lclItemSelected:'), nsKey);
|
||||
item.setKeyEquivalentModifierMask(ShiftSt);
|
||||
|
||||
if AMenuItem.IsInMenuBar then
|
||||
begin
|
||||
ANSMenu := TCocoaMenu.alloc.initWithTitle(ns);
|
||||
item.setSubmenu(ANSMenu);
|
||||
end;
|
||||
|
||||
ns.release;
|
||||
nsKey.release;
|
||||
item.setTarget(item);
|
||||
TCocoaMenuItem(item).menuItemCallback:=TLCLMenuItemCallback.Create(item, AMenuItem);
|
||||
item.setEnabled(AMenuItem.Enabled);
|
||||
@ -187,20 +218,29 @@ class procedure TCocoaWSMenuItem.DestroyHandle(const AMenuItem: TMenuItem);
|
||||
var
|
||||
callback: IMenuItemCallback;
|
||||
callbackObject: TObject;
|
||||
item: TCocoaMenuItem;
|
||||
item : NSObject;
|
||||
parItem : NSObject;
|
||||
begin
|
||||
if AMenuItem.Caption <> '-' then
|
||||
begin
|
||||
item := TCocoaMenuItem(AMenuItem.Handle);
|
||||
callback := item.lclGetCallback;
|
||||
if Assigned(callback) then
|
||||
begin
|
||||
callbackObject := callback.GetCallbackObject;
|
||||
callback := nil;
|
||||
item.lclClearCallback;
|
||||
callbackObject.Free;
|
||||
item:=NSObject(AMenuItem.Handle);
|
||||
if item.isKindOfClass_(TCocoaMenuItem) then
|
||||
begin
|
||||
callback := TCocoaMenuItem(item).lclGetCallback;
|
||||
if Assigned(callback) then
|
||||
begin
|
||||
callbackObject := callback.GetCallbackObject;
|
||||
callback := nil;
|
||||
TCocoaMenuItem(item).lclClearCallback;
|
||||
callbackObject.Free;
|
||||
end;
|
||||
parItem := TCocoaMenuItem(Item).parentItem;
|
||||
if assigned(parItem) and parItem.isKindOfClass_(NSMenuItem) then
|
||||
NSMenuItem(paritem).submenu.removeItem(NSMenuItem(item));
|
||||
Item.Release;
|
||||
AMenuItem.Handle := 0;
|
||||
end
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
@ -213,10 +253,15 @@ end;
|
||||
class procedure TCocoaWSMenuItem.SetCaption(const AMenuItem: TMenuItem; const ACaption: string);
|
||||
var
|
||||
ns : NSString;
|
||||
s: string;
|
||||
begin
|
||||
if not Assigned(AMenuItem) or (AMenuItem.Handle=0) then Exit;
|
||||
ns:=NSStringUtf8(ACaption);
|
||||
s := ACaption;
|
||||
DeleteAmpersands(s);
|
||||
ns:=NSStringUtf8(s);
|
||||
NSMenuItem(AMenuItem.Handle).setTitle(ns);
|
||||
if NSMenuItem(AMenuItem.Handle).hasSubmenu then
|
||||
NSMenuItem(AMenuItem.Handle).submenu.setTitle(ns);
|
||||
ns.release;
|
||||
end;
|
||||
|
||||
@ -229,8 +274,16 @@ end;
|
||||
------------------------------------------------------------------------------}
|
||||
class procedure TCocoaWSMenuItem.SetShortCut(const AMenuItem: TMenuItem;
|
||||
const ShortCutK1, ShortCutK2: TShortCut);
|
||||
var
|
||||
key: string;
|
||||
ShiftState: NSUInteger;
|
||||
ns: NSString;
|
||||
begin
|
||||
|
||||
ShortcutToKeyEquivalent(ShortCutK1, key, ShiftState);
|
||||
ns := NSString(CFStringCreateWithCString(nil, pointer(pchar(key)), kCFStringEncodingASCII));
|
||||
TCocoaMenuItem(AMenuItem.Handle).setKeyEquivalentModifierMask(ShiftState);
|
||||
TCocoaMenuItem(AMenuItem.Handle).setKeyEquivalent(ns);
|
||||
ns.release;
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user