2010-07-21 21 views
5

Tôi muốn nhân rộng nền của ngăn xếp ngăn xếp trong chế độ lưới và danh sách. Nền là mờ màu đen với một hiệu ứng mờ ảo:Áp dụng bộ lọc nền CIFilter khi cửa sổ máy chủ trong suốt

Example of dock stack in grid mode http://www.thecustommac.com/wp-content/uploads/2009/09/stack-highlight.jpg

Vấn đề là [CALayer backgroundFilters] chỉ áp dụng cho nội dung trong cửa sổ, các bộ lọc không được áp dụng cho nội dung trong cửa sổ khác. Đây là mã của tôi:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    //make window transparent 
    self.window.backgroundColor = [NSColor clearColor]; 
    [self.window setOpaque:NO]; 
    [self.window setHasShadow:NO]; 
    [self.window setStyleMask:NSBorderlessWindowMask]; 


    //make the content view layer hosting 
    CALayer *rootLayer = [CALayer layer]; 
    [[self.window contentView] setLayer:rootLayer]; 
    [[self.window contentView] setWantsLayer:YES]; 


    //blur the background contents - NOT WORKING! 
    [rootLayer setBackgroundColor:CGColorCreateGenericGray(0.0, .716)]; 

    CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"]; 
    [blurFilter setDefaults]; 
    [rootLayer setBackgroundFilters:[NSArray arrayWithObject: blurFilter]]; 
} 

Tôi không thể nghĩ cách khác để đạt được hiệu ứng này. (Tôi đã xem Dịch vụ Hiển thị để xem có bất kỳ chức năng hữu ích nào nhưng tôi không thể thấy bất kỳ chức năng nào.)

Bất kỳ ý tưởng nào?

Trả lời

9

Có API riêng tư khả dụng này. Đây là mã mẫu của Rob Keniger:

Trong 10.5, bạn có thể thêm bất kỳ bộ lọc hình ảnh lõi nào vào một cửa sổ bằng cách sử dụng chức năng riêng 'CGSAddWindowFilter'.

typedef void * CGSConnectionID; 

extern OSStatus CGSNewConnection(const void **attr, CGSConnectionID *id); 

- (void)enableBlurForWindow:(NSWindow *)window 
{ 

CGSConnectionID _myConnection; 
uint32_t __compositingFilter; 

int __compositingType = 1; // Apply filter to contents underneath the window, then draw window normally on top 

/* Make a new connection to CoreGraphics, alternatively you could use the main connection*/ 

CGSNewConnection(NULL , &_myConnection); 

/* The following creates a new CoreImage filter, then sets its options with a dictionary of values*/ 

CGSNewCIFilterByName (_myConnection, (CFStringRef)@"CIGaussianBlur", &__compositingFilter); 
NSDictionary *optionsDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:3.0] forKey:@"inputRadius"]; 
CGSSetCIFilterValuesFromDictionary(_myConnection, __compositingFilter, (CFDictionaryRef)optionsDict); 

/* Now just switch on the filter for the window */ 

CGSAddWindowFilter(_myConnection, [window windowNumber], __compositingFilter, __compositingType); 
} 
+0

Tuyệt vời, cảm ơn bạn rất nhiều! –

+0

FWIW, thao tác này không còn xuất hiện ở Yosemite nữa. :-(CGSNewCIFilterByName() trả về kCGErrorNotImplemented –

1

Mã của bạn có một số lỗi, đây là mã mà chỉ hoạt động:

typedef void * CGSConnection; 
extern OSStatus CGSNewConnection(const void **attributes, CGSConnection * id); 

-(void)enableBlurForWindow:(NSWindow *)window { 

    CGSConnection thisConnection; 
    NSUInteger compositingFilter; 
    NSInteger compositingType = 1 << 0; 

    // Make a new connection to Core Graphics 
    CGSNewConnection(NULL, &thisConnection); 

    // Create a Core Image filter and set it up 
    CGSNewCIFilterByName(thisConnection, (CFStringRef)@"CIGaussianBlur", &compositingFilter); 
    NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:2] forKey:@"inputRadius"]; 
    CGSSetCIFilterValuesFromDictionary(thisConnection, compositingFilter, (__bridge CFDictionaryRef)options); 

    // Apply the filter to the window 
    CGSAddWindowFilter(thisConnection, [window windowNumber], compositingFilter, compositingType); 
} 

Sau đó, sử dụng nó:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 
    [_window setOpaque:NO]; 

    [_window setBackgroundColor: [NSColor colorWithCalibratedHue:0.568 saturation:0.388 brightness:0.941 alpha:0.6]]; 

    [self enableBlurForWindow:_window]; 
} 
+0

Điều này không còn hoạt động trong XCode7.1 theo như tôi có thể nói. Mặc dù tôi đã thêm CoreGraphics.framework và '#import 'CoreGraphics/CoreGraphics.h" ', mã không biên dịch được vì nó không thể tìm thấy 'CGSNewCIFilterByName',' CGSSetCIFilterValuesFromDictionary' và 'CGSAddWindowFilter'. Tôi cũng đã thiết lập dự án của mình để chạy 10.8 OSX, nhưng sau đó thay đổi thành 10.10 OSX để xem liệu có biên dịch hay không, và điều đó cũng thất bại. – Volomike

1

Các bộ lọc không được sử dụng bởi các lớp gốc : Từ tài liệu:

/* An array of filters that are applied to the background of the layer. 
* The root layer ignores this property. Animatable. */ 

@property(copy) NSArray *backgroundFilters; 
Các vấn đề liên quan