mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
ADD: add Favorite Finder Color Tags Menu View to ContextMenu on macOS (showing only, not clickable yet)
This commit is contained in:
parent
c0b4c5521f
commit
97149bfbf5
4 changed files with 259 additions and 13 deletions
|
|
@ -6,10 +6,13 @@ unit uDarwinFinder;
|
|||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, LCLType,
|
||||
uDarwinFinderModel, uDebug,
|
||||
Classes, SysUtils, LCLType, Menus,
|
||||
uDarwinFinderModel,
|
||||
MacOSAll, CocoaAll, CocoaConst, CocoaTextEdits, CocoaUtils, Cocoa_Extra;
|
||||
|
||||
const
|
||||
FINDER_FAVORITE_TAGS_MENU_ITEM_CAPTION = #$EF#$BF#$BC'FinderFavoriteTags';
|
||||
|
||||
const
|
||||
TAG_POPOVER_WIDTH = 228.0;
|
||||
TAG_POPOVER_HEIGHT = 303.0;
|
||||
|
|
@ -30,6 +33,8 @@ type
|
|||
public
|
||||
class procedure popoverFileTags(
|
||||
const path: String; const positioningView: NSView; const edge: NSRectEdge );
|
||||
class procedure attachFinderTagsMenu(
|
||||
const path: String; const lclMenu: TPopupMenu );
|
||||
private
|
||||
class procedure drawTagName( const tagName: NSString;
|
||||
const fontSize: CGFloat; const color: NSColor; const rect: NSRect );
|
||||
|
|
@ -140,6 +145,39 @@ type
|
|||
procedure updateLayout; message 'doublecmd_updateLayout';
|
||||
end;
|
||||
|
||||
{ TFinderFavoriteTagMenuItemControl }
|
||||
|
||||
TFinderFavoriteTagMenuItemControl = objcclass( NSControl )
|
||||
private
|
||||
_finderTag: TFinderTag;
|
||||
_trackingArea: NSTrackingArea;
|
||||
_using: Boolean;
|
||||
_hover: Boolean;
|
||||
public
|
||||
procedure setFinderTag( const finderTag: TFinderTag ); message 'doublecmd_setFinderTag:';
|
||||
procedure setUsing( const using: Boolean ); message 'doublecmd_setUsing:';
|
||||
public
|
||||
procedure dealloc; override;
|
||||
procedure updateTrackingAreas; override;
|
||||
procedure drawRect(dirtyRect: NSRect); override;
|
||||
procedure mouseEntered(theEvent: NSEvent); override;
|
||||
procedure mouseExited(theEvent: NSEvent); override;
|
||||
procedure mouseUp(theEvent: NSEvent); override;
|
||||
end;
|
||||
|
||||
{ TFinderFavoriteTagsMenuView }
|
||||
|
||||
TFinderFavoriteTagsMenuView = objcclass( NSView )
|
||||
private
|
||||
_favoriteTags: NSArray;
|
||||
_url: NSURL;
|
||||
public
|
||||
procedure setPath( const path: NSString ); message 'doublecmd_setPath:';
|
||||
procedure setFavoriteTags( const favoriteTags: NSArray ); message 'doublecmd_setFavoriteTags:';
|
||||
public
|
||||
procedure dealloc; override;
|
||||
end;
|
||||
|
||||
{ TCocoaTokenAttachmentCell }
|
||||
|
||||
function TCocoaTokenAttachmentCell.isSelected: Boolean;
|
||||
|
|
@ -770,6 +808,24 @@ begin
|
|||
panel.showPopover( positioningView, edge );
|
||||
end;
|
||||
|
||||
class procedure uDarwinFinderUtil.attachFinderTagsMenu( const path: String;
|
||||
const lclMenu: TPopupMenu );
|
||||
var
|
||||
lclItem: TMenuItem;
|
||||
cocoaItem: NSMenuItem;
|
||||
menuView: TFinderFavoriteTagsMenuView;
|
||||
begin
|
||||
lclItem:= lclMenu.Items.Find( FINDER_FAVORITE_TAGS_MENU_ITEM_CAPTION );
|
||||
if lclItem = nil then
|
||||
Exit;
|
||||
|
||||
cocoaItem:= NSMenuItem(lclItem.Handle);
|
||||
menuView:= TFinderFavoriteTagsMenuView.alloc.initWithFrame( NSMakeRect(0,0,200,30) );
|
||||
menuView.setPath( StrToNSString(path) );
|
||||
menuView.setFavoriteTags( uDarwinFinderModelUtil.favoriteTags );
|
||||
cocoaItem.setView( menuView );
|
||||
end;
|
||||
|
||||
class procedure uDarwinFinderUtil.drawTagName( const tagName: NSString;
|
||||
const fontSize: CGFloat; const color: NSColor; const rect: NSRect );
|
||||
var
|
||||
|
|
@ -793,5 +849,168 @@ begin
|
|||
attributes.release;
|
||||
end;
|
||||
|
||||
{ TFinderFavoriteTagMenuItemControl }
|
||||
|
||||
procedure TFinderFavoriteTagMenuItemControl.setFinderTag(
|
||||
const finderTag: TFinderTag);
|
||||
begin
|
||||
_finderTag:= finderTag;
|
||||
end;
|
||||
|
||||
procedure TFinderFavoriteTagMenuItemControl.setUsing(const using: Boolean);
|
||||
begin
|
||||
_using:= using;
|
||||
end;
|
||||
|
||||
procedure TFinderFavoriteTagMenuItemControl.dealloc;
|
||||
begin
|
||||
if Assigned(_trackingArea) then begin
|
||||
self.removeTrackingArea( _trackingArea );
|
||||
_trackingArea.release;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TFinderFavoriteTagMenuItemControl.updateTrackingAreas;
|
||||
const
|
||||
options: NSTrackingAreaOptions = NSTrackingMouseEnteredAndExited
|
||||
or NSTrackingActiveAlways;
|
||||
begin
|
||||
if Assigned(_trackingArea) then begin
|
||||
self.removeTrackingArea( _trackingArea );
|
||||
_trackingArea.release;
|
||||
end;
|
||||
|
||||
_trackingArea:= NSTrackingArea.alloc.initWithRect_options_owner_userInfo(
|
||||
self.bounds,
|
||||
options,
|
||||
self,
|
||||
nil );
|
||||
self.addTrackingArea( _trackingArea );
|
||||
end;
|
||||
|
||||
procedure TFinderFavoriteTagMenuItemControl.drawRect(dirtyRect: NSRect);
|
||||
procedure drawCircle;
|
||||
var
|
||||
rect: NSRect;
|
||||
path: NSBezierPath;
|
||||
begin
|
||||
rect:= NSMakeRect( 0, 0, 20, 20 );
|
||||
if NOT _hover then
|
||||
rect:= NSInsetRect( rect, 2, 2 );
|
||||
|
||||
_finderTag.color.set_;
|
||||
path:= NSBezierPath.bezierPathWithOvalInRect( rect );
|
||||
path.fill;
|
||||
end;
|
||||
|
||||
procedure drawState;
|
||||
var
|
||||
stateString: NSString;
|
||||
stateRect: NSRect;
|
||||
stateFontSize: CGFloat;
|
||||
attributes: NSMutableDictionary;
|
||||
begin
|
||||
stateRect:= NSMakeRect( 5, 6, 100, 20 );
|
||||
stateFontSize:= 11;
|
||||
if _hover then begin
|
||||
if _using then begin
|
||||
stateString:= StrToNSString( 'x' );
|
||||
stateRect.origin.x:= stateRect.origin.x + 1;
|
||||
stateFontSize:= 14;
|
||||
end else begin
|
||||
stateString:= StrToNSString( '+' );
|
||||
stateFontSize:= 15;
|
||||
end;
|
||||
end else begin
|
||||
if _using then
|
||||
stateString:= StrToNSString( '✓' )
|
||||
else
|
||||
stateString:= nil;
|
||||
end;
|
||||
|
||||
if stateString = nil then
|
||||
Exit;
|
||||
|
||||
attributes:= NSMutableDictionary.new;
|
||||
attributes.setValue_forKey( NSFont.systemFontOfSize(stateFontSize), NSFontAttributeName );
|
||||
attributes.setValue_forKey( NSColor.whiteColor, NSForegroundColorAttributeName );
|
||||
|
||||
stateString.drawWithRect_options_attributes( stateRect, 0, attributes );
|
||||
|
||||
attributes.release;
|
||||
end;
|
||||
|
||||
begin
|
||||
drawCircle;
|
||||
drawState;
|
||||
end;
|
||||
|
||||
procedure TFinderFavoriteTagMenuItemControl.mouseEntered(theEvent: NSEvent);
|
||||
begin
|
||||
inherited mouseEntered(theEvent);
|
||||
_hover:= True;
|
||||
self.setNeedsDisplay_( True );
|
||||
end;
|
||||
|
||||
procedure TFinderFavoriteTagMenuItemControl.mouseExited(theEvent: NSEvent);
|
||||
begin
|
||||
inherited mouseExited(theEvent);
|
||||
_hover:= False;
|
||||
self.setNeedsDisplay_( True );
|
||||
end;
|
||||
|
||||
procedure TFinderFavoriteTagMenuItemControl.mouseUp(theEvent: NSEvent);
|
||||
begin
|
||||
self.sendAction_to( self.action, self.target );
|
||||
end;
|
||||
|
||||
{ TFinderFavoriteTagsMenuView }
|
||||
|
||||
procedure TFinderFavoriteTagsMenuView.setPath(const path: NSString);
|
||||
begin
|
||||
_url:= NSURL.alloc.initFileURLWithPath( path );
|
||||
end;
|
||||
|
||||
procedure TFinderFavoriteTagsMenuView.setFavoriteTags(const favoriteTags: NSArray
|
||||
);
|
||||
var
|
||||
finderTag: TFinderTag;
|
||||
itemControl: TFinderFavoriteTagMenuItemControl;
|
||||
itemRect: NSRect;
|
||||
fileTagNames: NSArray;
|
||||
|
||||
function createItemControl: TFinderFavoriteTagMenuItemControl;
|
||||
var
|
||||
using: Boolean;
|
||||
begin
|
||||
using:= fileTagNames.containsObject( finderTag.name );
|
||||
Result:= TFinderFavoriteTagMenuItemControl.alloc.initWithFrame( itemRect );
|
||||
Result.setFinderTag( finderTag );
|
||||
Result.setUsing( using );
|
||||
end;
|
||||
|
||||
procedure createSubviews;
|
||||
begin
|
||||
fileTagNames:= uDarwinFinderModelUtil.getTagNamesOfFile( _url );
|
||||
itemRect:= NSMakeRect( 16, 4, 24, 20 );
|
||||
for finderTag in _favoriteTags do begin
|
||||
itemControl:= createItemControl;
|
||||
self.addSubview( itemControl );
|
||||
itemControl.release;
|
||||
itemRect.origin.x:= itemRect.origin.x + 24;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
_favoriteTags:= favoriteTags;
|
||||
createSubviews;
|
||||
end;
|
||||
|
||||
procedure TFinderFavoriteTagsMenuView.dealloc;
|
||||
begin
|
||||
Inherited;
|
||||
_url.release;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
|||
|
|
@ -144,9 +144,10 @@ type TMacosServiceMenuHelper = class
|
|||
private
|
||||
oldMenuPopupHandler: TNotifyEvent;
|
||||
serviceSubMenuCaption: String;
|
||||
tagFilePath: String;
|
||||
procedure attachServicesMenu( Sender:TObject);
|
||||
public
|
||||
procedure PopUp( menu:TPopupMenu; caption:String );
|
||||
procedure PopUp( const menu: TPopupMenu; const caption: String; const path: String );
|
||||
end;
|
||||
|
||||
procedure InitNSServiceProvider(
|
||||
|
|
@ -240,33 +241,40 @@ begin
|
|||
NSAppearance.setCurrentAppearance( appearance );
|
||||
end;
|
||||
|
||||
procedure TMacosServiceMenuHelper.attachServicesMenu( Sender:TObject);
|
||||
procedure TMacosServiceMenuHelper.attachServicesMenu( Sender: TObject );
|
||||
var
|
||||
menu: TPopupMenu;
|
||||
servicesItem: TMenuItem;
|
||||
subMenu: TCocoaMenu;
|
||||
begin
|
||||
menu:= TPopupMenu(Sender);
|
||||
|
||||
// call the previous OnMenuPopupHandler and restore it
|
||||
if Assigned(oldMenuPopupHandler) then oldMenuPopupHandler( Sender );
|
||||
OnMenuPopupHandler:= oldMenuPopupHandler;
|
||||
oldMenuPopupHandler:= nil;
|
||||
|
||||
// attach the Services Sub Menu by calling NSApplication.setServicesMenu()
|
||||
servicesItem:= TPopupMenu(Sender).Items.Find(serviceSubMenuCaption);
|
||||
servicesItem:= menu.Items.Find(serviceSubMenuCaption);
|
||||
if servicesItem<>nil then
|
||||
begin
|
||||
subMenu:= TCocoaMenu.alloc.initWithTitle(NSString.string_);
|
||||
TCocoaMenuItem(servicesItem.Handle).setSubmenu( subMenu );
|
||||
NSApp.setServicesMenu( NSMenu(servicesItem.Handle) );
|
||||
end;
|
||||
|
||||
uDarwinFinderUtil.attachFinderTagsMenu( self.tagFilePath, menu );
|
||||
end;
|
||||
|
||||
procedure TMacosServiceMenuHelper.PopUp( menu:TPopupMenu; caption:String );
|
||||
procedure TMacosServiceMenuHelper.PopUp( const menu: TPopupMenu;
|
||||
const caption: String; const path: String );
|
||||
begin
|
||||
// because the menu item handle will be destroyed in TPopupMenu.PopUp()
|
||||
// we can only call NSApplication.setServicesMenu() in OnMenuPopupHandler()
|
||||
oldMenuPopupHandler:= OnMenuPopupHandler;
|
||||
OnMenuPopupHandler:= attachServicesMenu;
|
||||
serviceSubMenuCaption:= caption;
|
||||
tagFilePath:= path;
|
||||
menu.PopUp();
|
||||
end;
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ uses
|
|||
uOSUtils, uFileProcs, uShellExecute, uLng, uPixMapManager, uMyUnix, uOSForms,
|
||||
fMain, fFileProperties, DCOSUtils, DCStrUtils, uExts, uArchiveFileSourceUtil, uSysFolders
|
||||
{$IF DEFINED(DARWIN)}
|
||||
, LCLStrConsts, MacOSAll, CocoaAll, uMyDarwin
|
||||
, LCLStrConsts, MacOSAll, CocoaAll, uMyDarwin, uDarwinFinder
|
||||
{$ELSEIF NOT DEFINED(HAIKU)}
|
||||
, uKeyFile, uMimeActions
|
||||
{$IF DEFINED(LINUX)}
|
||||
|
|
@ -642,6 +642,10 @@ begin
|
|||
Self.Items.Add(mi);
|
||||
|
||||
addDelimiterMenuItem( self );
|
||||
mi:=TMenuItem.Create(Self);
|
||||
mi.Caption:= FINDER_FAVORITE_TAGS_MENU_ITEM_CAPTION;
|
||||
Self.Items.Add(mi);
|
||||
|
||||
mi:=TMenuItem.Create(Self);
|
||||
mi.Caption:= 'Edit Finder Tags...';
|
||||
mi.OnClick:= self.EditFinderTagsAction;
|
||||
|
|
|
|||
|
|
@ -737,7 +737,7 @@ end;
|
|||
|
||||
procedure ShowContextMenu(Parent: TWinControl; var Files : TFiles; X, Y : Integer;
|
||||
Background: Boolean; CloseEvent: TNotifyEvent; UserWishForContextMenu:TUserWishForContextMenu = uwcmComplete);
|
||||
{$IFDEF MSWINDOWS}
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
begin
|
||||
if Assigned(Files) and (Files.Count = 0) then
|
||||
begin
|
||||
|
|
@ -756,6 +756,26 @@ begin
|
|||
FreeAndNil(ShellContextMenu);
|
||||
end;
|
||||
end;
|
||||
{$ELSEIF DEFINED(DARWIN)}
|
||||
var
|
||||
filepath: String;
|
||||
begin
|
||||
if Files.Count = 0 then
|
||||
begin
|
||||
FreeAndNil(Files);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
filepath:= Files[0].FullPath;
|
||||
|
||||
// Free previous created menu
|
||||
FreeAndNil(ShellContextMenu);
|
||||
// Create new context menu
|
||||
ShellContextMenu:= TShellContextMenu.Create(nil, Files, Background, UserWishForContextMenu);
|
||||
ShellContextMenu.OnClose := CloseEvent;
|
||||
// Show context menu
|
||||
MacosServiceMenuHelper.PopUp( ShellContextMenu, rsMacOSMenuServices, filepath );
|
||||
end;
|
||||
{$ELSE}
|
||||
begin
|
||||
if Files.Count = 0 then
|
||||
|
|
@ -769,12 +789,7 @@ begin
|
|||
// Create new context menu
|
||||
ShellContextMenu:= TShellContextMenu.Create(nil, Files, Background, UserWishForContextMenu);
|
||||
ShellContextMenu.OnClose := CloseEvent;
|
||||
// Show context menu
|
||||
{$IF DEFINED(DARWIN)}
|
||||
MacosServiceMenuHelper.PopUp( ShellContextMenu, rsMacOSMenuServices );
|
||||
{$ELSE}
|
||||
ShellContextMenu.PopUp(X, Y);
|
||||
{$ENDIF}
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue