2012-05-07 5 views
4

Mac Os Finder의 dropbox와 같은 아이콘 오버레이를 SIMBL 플러그인과 통합 관리합니다! I swizzle 메서드를 사용하여 일부 finder 함수를 재정의합니다.SIMBL swinder in finder

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

내 모든 아이콘 표시가 아니라 내 바탕 화면 또는 뷰에있다 :이 같은 drawWithFrame 메소드를 오버라이드 (override) 순간 그래서

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

: 여기

내 스위 즐 방법 그 아이콘을 아이콘으로 보여줍니다 ... 왜? 당신이 경험 그래서

, 파인더는 다르게 아이콘을 그립니다

난 그냥 바탕 화면에 대한 몇 가지 물건을 관리, 그래서 난 아직도 누군가를 위해 관련이 경우에 게시합니다

답변

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을 가져 오려면 prepareToDrawNode : 메서드를 TDesktopViewController으로 재정의해야합니다.

+0

이 코드의 효과를 보았습니까? 그 재미있는 ... 이미지를 바꾸는 것 같아서 파인더가 다른 오버레이를 아이콘에 쓸 때 이상한 문제를 일으킬 것 같습니다 ... 바탕 화면에서 아이콘의 절반을 제대로 가져 와서 원본 아이콘을 제대로 그릴 수 있지만 모두에 오버레이가 있습니다. 그들 – Orbitus007

+0

매버릭스에서 어떻게해야할까요? – Ali

2

가있어 ...

- (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]; 
} 

어쩌면 더 나은 방법이 있지만 내가 알아 낸 내용은 다음과 같습니다 당신은 ARG1에서 URL을 얻을 다음과 같이! (이 코드는 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