2012-05-07 15 views
4

Mac Os FinderのドロップボックスのようなアイコンオーバーレイをSIMBLプラグインと統合して管理しています! I swizzleメソッドを使用して、いくつかのファインダ関数をオーバーライドします。ここでSIMBL swizzling in finder

は私のスウィズル方法である:

void PluginSwizzleInstanceMethod(Class cls, SEL oldSel, SEL newSel) 
{ 
    Method mnew = class_getInstanceMethod(cls, newSel); 
    Method mold = class_getInstanceMethod(cls, oldSel); 
    method_exchangeImplementations(mnew, mold); 
} 

だから、一瞬のために私はこのようなdrawWithFrameメソッドオーバーライドする:すべての私のアイコンはなく、私のデスクトップまたはビューに表示されている

Class cls = NSClassFromString(@"TIconAndTextCell"); 
SEL oldSel = @selector(drawWithFrame:inView:); 
SEL newSel = @selector(PluginDrawWithFrame:inView:); 
PluginSwizzleInstanceMethod(cls, oldSel, newSel); 

をアイコンとしてアイテムを表示しています... なぜですか?

あなたが経験したように、Finderがで異なるアイコンを描画します。

は、私はちょうどデスクトップのためのいくつかのものを行うために管理し、私は誰かのためにまだ関連だ場合には投稿します、

答えて

2

をありがとうデスクトップ。
その責任を負うクラスは、TDesktopIconです。
たとえば、drawIconInContext:メソッドをオーバーライドしてthumbnailImageプロパティをNSImage *に設定すると、アイコンを変更できます。各項目のURLを取得する

- (void) FO_drawIconInContext:(struct CGContext *)arg1 { 
    NSImage *image; 
    // set image... 
    [(TDesktopIcon*)self setThumbnailImage:image]; 
    [self FO_drawIconInContext:arg1]; 
} 

はTIconAndTextCellまたはIKImageBrowserCellのようにまっすぐ進むようではなかったです。

URLを取得するには、TDesktopViewControllerのprepareToDrawNode:メソッドをオーバーライドする必要があります。次のように あなたはARG1からURLを取得します:

- (void) FO_prepareToDrawNode:(const struct TFENode *)arg1 { 
    struct OpaqueNodeRef *opr = arg1->fNodeRef; 
    struct FINode *fiNode = [FINode nodeFromNodeRef:opr]; 
    NSURL *url = [fiNode previewItemURL]; 
    // save url somewhere (I use NSUserDefaults) 
    [self FO_prepareToDrawNode:arg1]; 
} 

はたぶんもっと良い方法がありますが、それは私が考え出したものだ...

+0

このコードの影響を確認しましたか?その本当に興味深い...画像を置き換えるように思えるのは、ファインダーが他のオーバーレイをアイコンに書き込むときに奇妙な問題を引き起こすようです...デスクトップ上のアイコンの半分を元のアイコンを適切に描くことができますが、それらは – Orbitus007

+0

どのようにマーベリックスでこれを行うには? – Ali

2

はそれを手に入れました! (このコードは10.7しか働いていません)最終画像がサムネイル画像にレンダリングされる前にアイコンが描画されていたので問題が発生していました。オーバーレイはいつもそこにあった...それは私が間違っていた描画操作の順序だった...!

私もターゲット・ノードの名前を持っている...あなたは

// 
// DesktopViewIconOverlay.h 
// FinderIconOverlayExample 
// 
// Created by Orbitus007 on 2/20/13. 
// 
// 

#import <Foundation/Foundation.h> 
#import <Quartz/Quartz.h> 
#import "Finder.h" 

@interface DesktopViewIconOverlay : NSObject 

+ (void)pluginLoad; 
- (void) FO_prepareToDrawNode:(const struct TFENode *)arg1; 
- (void) FO_drawIconInContext:(struct CGContext *)arg1; 

@end 

// 
// DesktopViewIconOverlay.m 
// FinderIconOverlayExample 
// 
// Created by Orbitus007 on 2/20/13. 
// 
// 

#import "DesktopViewIconOverlay.h" 
#import "FinderIconOverlayExample.h" 
#include <objc/objc.h> 
#include <objc/runtime.h> 
#import <Quartz/Quartz.h> 
#import "TFENodeHelper.h" 

static TFENodeHelper *gNodeHelper; 





@implementation DesktopViewIconOverlay 

+ (void)pluginLoad 
{ 



    // Create helper object 
    gNodeHelper = [[TFENodeHelper alloc] init]; 
    if (gNodeHelper == nil) { 
     NSLog(@"Failed to instantiate 'TFENodeHelper' class"); 
     return; 
    } 


    Method old, new; 
    Class self_class = [self class]; 
    Class finder_class = [objc_getClass("TDesktopIcon") class]; 

    class_addMethod(finder_class, @selector(FO_drawIconInContext:), 
        class_getMethodImplementation(self_class, @selector(FO_drawIconInContext:)),"[email protected]:@"); 

    old = class_getInstanceMethod(finder_class, @selector(drawIconInContext:)); 
    new = class_getInstanceMethod(finder_class, @selector(FO_drawIconInContext:)); 
    method_exchangeImplementations(old, new); 


    finder_class = [objc_getClass("TDesktopViewController") class]; 


    class_addMethod(finder_class, @selector(FO_prepareToDrawNode:), 
        class_getMethodImplementation(self_class, @selector(FO_prepareToDrawNode:)),"[email protected]:@"); 

    old = class_getInstanceMethod(finder_class, @selector(prepareToDrawNode:)); 
    new = class_getInstanceMethod(finder_class, @selector(FO_prepareToDrawNode:)); 
    method_exchangeImplementations(old, new); 

} 


- (void) FO_prepareToDrawNode:(const struct TFENode *)arg1 { 

    NSString *path = [gNodeHelper pathForNode:arg1]; 
    NSLog(@"Path = %@", path); 
    [[NSUserDefaults standardUserDefaults] setValue:path forKey:@"TDesktopIconURL"]; 

    //struct OpaqueNodeRef *opr = arg1->fNodeRef; 

    //NSLog(@"path = %@", [[FINode nodeWithFENode:arg1] fullPath]); 

    //id fiNode = [FINode nodeFromNodeRef:opr]; 
    //NSURL *url = [fiNode previewItemURL]; 
    //[[NSUserDefaults standardUserDefaults] setValue:[url path] forKey:@"TDesktopIconURL"]; 
    //NSLog(@"sending ", arg1->fNodeRef); 
    // save url somewhere (I use NSUserDefaults) 
    [self FO_prepareToDrawNode:arg1]; 
} 



- (void) FO_drawIconInContext:(struct CGContext *)arg1 
{ 
    [self FO_drawIconInContext:arg1]; 

    NSString *iconPath = [[NSUserDefaults standardUserDefaults] valueForKey:@"TDesktopIconURL"]; 
    NSLog(@"recieved %@", iconPath); 

    if (![iconPath isEqualToString:@"/Users/h0xff/Desktop/Restart Finder.app"]) 
     return; 

    NSString *imagePath = @"/Users/h0xff/Desktop/020513_icons/128_synced_green.png"; 
    NSImage *overlay = [[NSImage alloc] initWithContentsOfFile:imagePath]; 

    NSImage *mainImage = [(TDesktopIcon*)self thumbnailImage]; 

    float width = 256.0; 
    float height = 256.0; 

    NSImage *finalImage = [[NSImage alloc] initWithSize:NSMakeSize(width, height)]; 

    [finalImage lockFocus]; 

    // draw the base image 
    [mainImage drawInRect:NSMakeRect(0, 0, width, height) 
       fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; 

    // draw the overlay image at some offset point 
    [overlay drawInRect:NSMakeRect(0, 0, [overlay size].width/1.5, [overlay size].height/1.5) 
       fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; 

    [finalImage unlockFocus]; 


    // set image... 
    [(TDesktopIcon*)self setThumbnailImage:finalImage]; 
    [self FO_drawIconInContext:arg1]; 
} 

@end 

このコードはアレクセイZhuchkovおよび他の多くから派生した... filePathににTFENodeを翻訳しTFENodeHelperクラスが必要です。..あなたが何か持っていれば質問してください!

// 
// TFENodeHelper.h 
// FinderMenu 
// 
// Helper class to get full path from TFENode 
// 
// Created by Alexey Zhuchkov on 11/4/12. 
// Copyright (c) 2012 InfiniteLabs. All rights reserved. 
// 

#import <Foundation/Foundation.h> 

// Forward declarations 
struct TFENode; 

typedef enum { 
    TFENodeCtorTypeUnknown, 
    TFENodeCtorTypeNodeWithFENode, // nodeWithFENode 
    TFENodeCtorTypeNodeFromNodeRef, // nodeFromNodeRef 
} TFENodeCtorType; 

typedef enum { 
    TFENodePathMethodTypeUnknown, 
    TFENodePathMethodTypeFullPath, // fullPath 
    TFENodePathMethodTypePreviewItemURL, // previewItemURL 
} TFENodePathMethodType; 

@interface TFENodeHelper : NSObject { 
    @private 
    Class _class; 
    TFENodeCtorType _ctorType; 
    TFENodePathMethodType _pathMethodType; 
} 

- (NSString *)pathForNode:(const struct TFENode *)node; 
@end 


// 
// TFENodeHelper.m 
// FinderMenu 
// 
// Created by Alexey Zhuchkov on 11/4/12. 
// Copyright (c) 2012 InfiniteLabs. All rights reserved. 
// 

#import "TFENodeHelper.h" 

#import <objc/runtime.h> 

#import "Finder.h" 

@implementation TFENodeHelper 

- (id)init { 
    self = [super init]; 
    if (self) { 
     _class = NSClassFromString(@"FINode"); 
     _ctorType = TFENodeCtorTypeUnknown; 
     _pathMethodType = TFENodePathMethodTypeUnknown; 

     if (_class) { 
      if (class_getClassMethod(_class, @selector(nodeWithFENode:))) { 
       _ctorType = TFENodeCtorTypeNodeWithFENode; 
      } else if (class_getClassMethod(_class, @selector(nodeFromNodeRef:))) { 
       _ctorType = TFENodeCtorTypeNodeFromNodeRef; 
      } 

      if (class_getInstanceMethod(_class, @selector(fullPath))) { 
       _pathMethodType = TFENodePathMethodTypeFullPath; 
      } else if (class_getInstanceMethod(_class, @selector(previewItemURL))) { 
       _pathMethodType = TFENodePathMethodTypePreviewItemURL; 
      } 
     } 

     if (!_class 
      || (_ctorType == TFENodePathMethodTypeUnknown) 
      || (_pathMethodType == TFENodePathMethodTypeUnknown)) { 

      [self release]; 
      return nil; 
     } 
    } 
    return self; 
} 

- (NSString *)pathForNode:(const struct TFENode *)node { 
    FINode *fiNode = nil; 
    NSString *path = nil; 
    switch (_ctorType) { 
     case TFENodeCtorTypeNodeWithFENode: 
      fiNode = [_class nodeWithFENode:node]; 
      break; 
     case TFENodeCtorTypeNodeFromNodeRef: 
      fiNode = [_class nodeFromNodeRef:node->fNodeRef]; 
      break; 
     default: 
      break; 
    } 

    NSURL *url; 
    if (fiNode) { 
     switch (_pathMethodType) { 
      case TFENodePathMethodTypeFullPath: 
       path = [fiNode fullPath]; 
       break; 
      case TFENodePathMethodTypePreviewItemURL: 
       url = [fiNode previewItemURL]; 
       path = [url path]; 
      default: 
       break; 
     } 
    } 

    return path; 
} 

@end 
関連する問題