2011-08-21 5 views
18

क्या NSButtons या अन्य कोको इंटरफेस तत्वों में छवियों जैसे एनएसआईमेज को आकर्षित करने का कोई तरीका है? enter image description here enter image description hereNSButtons (गहराई के साथ) में छवियों की तरह एनएसआईमेज कैसे आकर्षित करें?

एप्पल पीडीएफ के उपयोग करता काला माउस के साथ: enter image description here

+0

एक 'NSButtonCell' का उपयोग –

उत्तर

56

आप बस जब आप एक बटन में अपनी खुद की छवियों का उपयोग इस आशय लागू किया जा चाहते हैं, [myImage setTemplate:YES] का उपयोग

यहाँ उदाहरण हैं । इस स्क्रीन के बाहर इस स्क्रीन के बाहर छवियों को आकर्षित करने का कोई अंतर्निहित तरीका नहीं है जिसमें आपके स्क्रीनशॉट में दिखाया गया शैली है।

हालांकि आप कोर ग्राफिक्स का उपयोग कर प्रभाव को दोहरा सकते हैं। यदि आप बारीकी से देखते हैं, तो प्रभाव में एक क्षैतिज ढाल, एक सफेद ड्रॉप छाया और एक अंधेरे भीतरी छाया होती है (बाद वाला सबसे कठिन होता है)। एक दृश्य में

//NSImage+EtchedDrawing.h: 
@interface NSImage (EtchedImageDrawing)  
- (void)drawEtchedInRect:(NSRect)rect; 
@end 

//NSImage+EtchedDrawing.m: 
@implementation NSImage (EtchedImageDrawing) 

- (void)drawEtchedInRect:(NSRect)rect 
{ 
    NSSize size = rect.size; 
    CGFloat dropShadowOffsetY = size.width <= 64.0 ? -1.0 : -2.0; 
    CGFloat innerShadowBlurRadius = size.width <= 32.0 ? 1.0 : 4.0; 

    CGContextRef c = [[NSGraphicsContext currentContext] graphicsPort]; 

    //save the current graphics state 
    CGContextSaveGState(c); 

    //Create mask image: 
    NSRect maskRect = rect; 
    CGImageRef maskImage = [self CGImageForProposedRect:&maskRect context:[NSGraphicsContext currentContext] hints:nil]; 

    //Draw image and white drop shadow: 
    CGContextSetShadowWithColor(c, CGSizeMake(0, dropShadowOffsetY), 0, CGColorGetConstantColor(kCGColorWhite)); 
    [self drawInRect:maskRect fromRect:NSMakeRect(0, 0, self.size.width, self.size.height) operation:NSCompositeSourceOver fraction:1.0]; 

    //Clip drawing to mask: 
    CGContextClipToMask(c, NSRectToCGRect(maskRect), maskImage); 

    //Draw gradient: 
    NSGradient *gradient = [[[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceWhite:0.5 alpha:1.0] 
                  endingColor:[NSColor colorWithDeviceWhite:0.25 alpha:1.0]] autorelease]; 
    [gradient drawInRect:maskRect angle:90.0]; 
    CGContextSetShadowWithColor(c, CGSizeMake(0, -1), innerShadowBlurRadius, CGColorGetConstantColor(kCGColorBlack)); 

    //Draw inner shadow with inverted mask: 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef maskContext = CGBitmapContextCreate(NULL, CGImageGetWidth(maskImage), CGImageGetHeight(maskImage), 8, CGImageGetWidth(maskImage) * 4, colorSpace, kCGImageAlphaPremultipliedLast); 
    CGColorSpaceRelease(colorSpace); 
    CGContextSetBlendMode(maskContext, kCGBlendModeXOR); 
    CGContextDrawImage(maskContext, maskRect, maskImage); 
    CGContextSetRGBFillColor(maskContext, 1.0, 1.0, 1.0, 1.0); 
    CGContextFillRect(maskContext, maskRect); 
    CGImageRef invertedMaskImage = CGBitmapContextCreateImage(maskContext); 
    CGContextDrawImage(c, maskRect, invertedMaskImage); 
    CGImageRelease(invertedMaskImage); 
    CGContextRelease(maskContext); 

    //restore the graphics state 
    CGContextRestoreGState(c); 
} 

@end 

उदाहरण उपयोग:

आप NSImage पर एक वर्ग के रूप में यह लागू हो सकता है

- (void)drawRect:(NSRect)dirtyRect 
{ 
    [[NSColor colorWithDeviceWhite:0.8 alpha:1.0] set]; 
    NSRectFill(self.bounds); 

    NSImage *image = [NSImage imageNamed:@"MyIcon.pdf"]; 
    [image drawEtchedInRect:self.bounds]; 
} 

यह आपको निम्न परिणाम देना होगा (विभिन्न आकारों में दिखाया गया है): Screenshot

आपको दो छायाओं के ढाल रंगों और ऑफसेट/धुंध त्रिज्या के साथ थोड़ा प्रयोग करने की आवश्यकता हो सकती है मूल प्रभाव के करीब टी।

+1

आकर्षित करने के लिए वाह धन्यवाद! यह वही है जो मैं कोशिश कर रहा था। – Flocked

+0

मैंने ग्राफिक्स स्थिति को सहेजने और पुनर्स्थापित करने के लिए कॉल जोड़कर अपना कोड संपादित किया। यदि आप ऐसा नहीं करते हैं, तो वर्तमान संदर्भ इस ड्राइंग विधि को कॉल करने के बाद एक अलग राज्य में होगा, जो अपेक्षित व्यवहार नहीं है। –

+2

इसके अलावा, छवि नाम के अंत में 'टेम्पलेट' (पूंजी टी के साथ) डालने से कम कोड के साथ समान प्रभाव उत्पन्न होगा (बस आईबी में नाम सेट करें)। – spudwaffle

0

किसी भी रेक्ट के भीतर सही ढंग से आकर्षित करने के लिए, CGContextDrawImage और CGContextFillRect आंतरिक मुखौटा के लिए (0,0) की उत्पत्ति होनी चाहिए। फिर जब आप आंतरिक छाया के लिए छवि खींचते हैं तो आप मास्क रेक्ट का पुन: उपयोग कर सकते हैं। तो की तरह लग रही समाप्त होता है:

CGRect cgRect = CGRectMake(0, 0, maskRect.size.width, maskRect.size.height);  
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRef maskContext = CGBitmapContextCreate(NULL, CGImageGetWidth(maskImage), CGImageGetHeight(maskImage), 8, CGImageGetWidth(maskImage) * 4, colorSpace, kCGImageAlphaPremultipliedLast); 
CGColorSpaceRelease(colorSpace); 
CGContextSetBlendMode(maskContext , kCGBlendModeXOR); 
CGContextDrawImage(maskContext, cgRect, maskImage); 
CGContextSetRGBFillColor(maskContext, 1.0, 1.0, 1.0, 1.0); 
CGContextFillRect(maskContext, cgRect); 
CGImageRef invertedMaskImage = CGBitmapContextCreateImage(maskContext); 

CGContextDrawImage(context, maskRect, invertedMaskImage); 
CGImageRelease(invertedMaskImage); 
CGContextRelease(maskContext); 
CGContextRestoreGState(context); 

तुम भी छवि के बाहर चारों ओर 1px का बॉर्डर जाना है या छाया सही ढंग से काम नहीं करेगा।

4

यदि आपको एक निजी एपीआई कॉल करने में कोई फर्क नहीं पड़ता है, तो आप ऑपरेटिंग सिस्टम (कोरयूआई) को आपके लिए छायांकन कर सकते हैं।

typedef CFTypeRef CUIRendererRef; 
extern void CUIDraw(CUIRendererRef renderer, CGRect frame, CGContextRef context, CFDictionaryRef object, CFDictionaryRef *result); 

@interface NSWindow(CoreUIRendererPrivate) 
+ (CUIRendererRef)coreUIRenderer; 
@end 

और वास्तविक ड्राइंग के लिए:

CGRect drawRect = CGRectMake(x, y, width, height); 
CGImageRef cgimage = your_image; 

CFDictionaryRef dict = (CFDictionaryRef) [NSDictionary dictionaryWithObjectsAndKeys: 
     @"backgroundTypeRaised", @"backgroundTypeKey", 
     [NSNumber numberWithBool:YES], @"imageIsGrayscaleKey", 
     cgimage, @"imageReferenceKey", 
     @"normal", @"state", 
     @"image", @"widget", 
     [NSNumber numberWithBool:YES], @"is.flipped", 
     nil]; 
CUIDraw ([NSWindow coreUIRenderer], drawRect, cg, dict, nil); 
CGImageRelease (cgimage); 

यह cgimage की अल्फ़ा चैनल लेने के लिए और के रूप में टूलबार बटन पर देखा उभार प्रभाव लागू होगा आप कुछ घोषणाओं की जरूरत है। आपको "is.flipped" लाइन की आवश्यकता हो सकती है या नहीं। यदि आपका परिणाम उल्टा है तो इसे हटा दें।

kCUIPresentationStateKey = kCUIPresentationStateInactive:

रूपों का एक गुच्छा रहे हैं विंडो सक्रिय नहीं है, छवि हल्का हो जाएगा।

state = rollover: केवल पिछले विकल्प के साथ समझ में आता है। इसका मतलब है कि आप छवि पर होवर कर रहे हैं, विंडो निष्क्रिय है, लेकिन बटन संवेदनशील है (क्लिक-थ्रू सक्षम है)। यह गहरा हो जाएगा।

state = pressed: जब बटन दबाया जाता है तो होता है।आइकन थोड़ा गहरा हो जाता है।

बोनस टिप: इस तरह की चीजें खोजने के लिए, आप सिमब्लूएल प्लगइन CUITrace का उपयोग कर सकते हैं। यह लक्ष्य ऐप के सभी कोरयूआई आमंत्रणों को प्रिंट करता है। यदि आपको अपना खुद का देशी दिखने वाला यूआई आकर्षित करना है तो यह एक खजाना ट्रोव है।

2

यहां एक बहुत ही आसान समाधान है: बस एक सेल बनाएं और इसे आकर्षित करें। निजी एपीआई या कोर ग्राफिक्स के साथ चारों ओर कोई चकमा नहीं।

कोड निम्न के समान दिखाई दे सकता है:।

NSButtonCell *buttonCell = [[NSButtonCell alloc] initImageCell:image]; 
buttonCell.bordered = YES; 
buttonCell.bezelStyle = NSTexturedRoundedBezelStyle; 
// additional configuration 
[buttonCell drawInteriorWithFrame: someRect inView:self]; 

आप विभिन्न कोशिकाओं और विन्यास देखो पर निर्भर करता है कि आप (जैसे NSImageCellNSBackgroundStyleDark साथ है करने के लिए यदि आप एक चयनित तालिका में उलटा देखो चाहते हैं का उपयोग कर सकते पंक्ति देखें)

और एक बोनस के रूप में, यह स्वचालित रूप से ओएस एक्स के सभी संस्करणों पर सही दिखेगा