I want to customize NSSliderCell, but I'm getting strange glitch.
Here is what it should looks like (zoomed):
It draws ok, but when I'm drugging the knob, left bar starts look weird (looks like part of knob's shadow is left from previous frame):
Once I stop drugging the knob, slider becomes normal again.
Here is the code:
#implementation VolumeSliderCell
NSImage *knobImage = nil;
NSImage *leftBarLeftCapImage = nil;
NSImage *leftBarFillImage = nil;
NSImage *rightBarFillImage = nil;
NSImage *rightBarRightCapImage = nil;
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
knobImage = [NSImage imageNamed:#"volume_knob.png"];
leftBarLeftCapImage = [NSImage imageNamed:#"volume_leftbar_leftcap.png"];
leftBarFillImage = [NSImage imageNamed:#"volume_leftbar_fill.png"];
rightBarFillImage = [NSImage imageNamed:#"volume_rightbar_fill.png"];
rightBarRightCapImage = [NSImage imageNamed:#"volume_rightbar_rightcap.png"];
}
return self;
}
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
//NSRect cellFrame = [self controlView].bounds;
//[[self controlView] setNeedsDisplayInRect:cellFrame];
[self drawBarInside:cellFrame flipped:[controlView isFlipped]];
[self drawKnob:cellFrame];
}
- (void)drawKnob:(NSRect)knobRect
{
[NSGraphicsContext saveGraphicsState];
CGRect bounds = [self controlView].bounds;
CGFloat value = ([self doubleValue] - [self minValue])/ ([self maxValue] - [self minValue]);
CGRect rect = CGRectMake(value * (bounds.size.width - [knobImage size].width), (bounds.size.height - [knobImage size].height) / 2, [knobImage size].width, [knobImage size].height);
[knobImage drawInRect:CGRectIntegral(rect)];
[NSGraphicsContext restoreGraphicsState];
}
- (void)drawBarInside:(NSRect)aRect flipped:(BOOL)flipped
{
[NSGraphicsContext saveGraphicsState];
CGRect bounds = [self controlView].bounds;
CGFloat value = ([self doubleValue] - [self minValue])/ ([self maxValue] - [self minValue]);
CGRect leftRect = CGRectMake([knobImage size].width / 2, (bounds.size.height - [leftBarFillImage size].height) / 2, value * (bounds.size.width - [knobImage size].width), [leftBarFillImage size].height);
CGRect rightRect = CGRectMake(leftRect.origin.x + leftRect.size.width, (bounds.size.height - [leftBarFillImage size].height) / 2, bounds.size.width - (leftRect.origin.x + leftRect.size.width + [knobImage size].width / 2), [leftBarFillImage size].height);
if (rightRect.size.width < 0)
{
rightRect.size.width = 0;
}
NSDrawThreePartImage(CGRectIntegral(leftRect), leftBarLeftCapImage, leftBarFillImage, nil, NO, NSCompositeSourceOver, 1.0, YES);
NSDrawThreePartImage(CGRectIntegral(rightRect), nil, rightBarFillImage, rightBarRightCapImage, NO, NSCompositeSourceOver, 1.0, YES);
[NSGraphicsContext restoreGraphicsState];
}
What's wrong?
Related
I am trying to draw a box in custom view. I have the points for the corners of the box and they are scaled. If I put a small rectangle at each vertex on the box and the resize the window it works perfectly. If I use [path stroke] to draw the lines between the vertices and then resize the window, I end up with a mess as the box is redrawn as the window gets resized, so instead of a single box in a resized window I get all the boxes that were redrawn. I have not found a way to clear the custom view of all the intermediary drawings. Any help would be appreciated. Also, I am really new at this.
#import <Cocoa/Cocoa.h>
#interface PointDisplay : NSView
{
NSBezierPath *pathForLine;
NSMutableArray *pointList;
float originalWidth;
float originalHeight;
}
#end
import "PointDisplay.h"
#implementation PointDisplay
- (id)initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
if (self)
{
int opts = (NSTrackingActiveAlways | NSTrackingInVisibleRect | NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved);
NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:[self bounds]
options:opts
owner:self
userInfo:nil];
[self addTrackingArea:area];
pathForLine = [[NSBezierPath alloc] init];
pointList = [[NSMutableArray alloc] init];
NSRect originalRect = [self bounds];
originalWidth = originalRect.size.width;
originalHeight = originalRect.size.height;
}
return self;
}
- (void)drawRect:(NSRect)dirtyRect
{
[super drawRect:dirtyRect];
NSRect myRect = [self bounds];
float widthNow = myRect.size.width;
float heightNow = myRect.size.height;
[[NSColor greenColor] set];
[NSBezierPath fillRect:myRect];
int rectWidth = 10, rectHeight = 10;
float lineWidth = 3.0;
if (pointList.count != 0)
{
NSPoint myPoint = [pointList[0] locationInWindow];
myPoint = [self convertPoint:myPoint fromView:nil];
myPoint.x = (myPoint.x - rectWidth / 2) * widthNow / originalWidth;
myPoint.y = (myPoint.y - rectHeight / 2) * heightNow / originalHeight;
[pathForLine moveToPoint:myPoint];
NSRect anotherRect = NSMakeRect(myPoint.x, myPoint.y, rectWidth, rectHeight);
[[NSColor redColor] set];
[pathForLine setLineWidth:lineWidth + .5 * ((int)lineWidth % 2)];
//[[NSBezierPath bezierPathWithRect:anotherRect] stroke];
for (int i = 1; i < pointList.count; i++)
{
myPoint = [pointList[i] locationInWindow];
myPoint = [self convertPoint:myPoint fromView:nil];
myPoint.x = (myPoint.x - 5) * widthNow / originalWidth;
myPoint.y = (myPoint.y - 5) * heightNow / originalHeight;
anotherRect = NSMakeRect(myPoint.x, myPoint.y, 10, 10);
[pathForLine lineToPoint:myPoint];
[pathForLine stroke];
//[[NSBezierPath bezierPathWithRect:anotherRect] fill];
}
}
}
#pragma mark Mouse events
- (void)mouseUp:(NSEvent *)theEvent
{
[pointList addObject:theEvent];
[self setNeedsDisplay:YES];
}
- (void)mouseExited:(NSEvent *)theEvent
{
[pathForLine closePath];
[pathForLine stroke];
[self setNeedsDisplay:YES];
}
#end
OK, here's my situation :
I'm trying a HUD-like custom-controls collection, SNRHUDKit.
I'm specifically using SNRHUDWindow as my main window class
No matter what, although it actually works, I can't get the NSWindow (or NSPanel - doesn't make much difference) to resize, when the user drags its lower-right corner.
The code for SNRHUDWindow is :
//
// SNRHUDWindow.m
// SNRHUDKit
//
// Created by Indragie Karunaratne on 12-01-22.
// Copyright (c) 2012 indragie.com. All rights reserved.
//
#import "SNRHUDWindow.h"
#import "NSBezierPath+MCAdditions.h"
#define SNRWindowTitlebarHeight 22.f
#define SNRWindowBorderColor [NSColor blackColor]
#define SNRWindowTopColor [NSColor colorWithDeviceWhite:0.240 alpha:0.960]
#define SNRWindowBottomColor [NSColor colorWithDeviceWhite:0.150 alpha:0.960]
#define SNRWindowHighlightColor [NSColor colorWithDeviceWhite:1.000 alpha:0.200]
#define SNRWindowCornerRadius 5.f
#define SNRWindowTitleFont [NSFont systemFontOfSize:11.f]
#define SNRWindowTitleColor [NSColor colorWithDeviceWhite:0.700 alpha:1.000]
#define SNRWindowTitleShadowOffset NSMakeSize(0.f, 1.f)
#define SNRWindowTitleShadowBlurRadius 1.f
#define SNRWindowTitleShadowColor [NSColor blackColor]
#define SNRWindowButtonSize NSMakeSize(18.f, 18.f)
#define SNRWindowButtonEdgeMargin 5.f
#define SNRWindowButtonBorderColor [NSColor colorWithDeviceWhite:0.040 alpha:1.000]
#define SNRWindowButtonGradientBottomColor [NSColor colorWithDeviceWhite:0.070 alpha:1.000]
#define SNRWindowButtonGradientTopColor [NSColor colorWithDeviceWhite:0.220 alpha:1.000]
#define SNRWindowButtonDropShadowColor [NSColor colorWithDeviceWhite:1.000 alpha:0.100]
#define SNRWindowButtonCrossColor [NSColor colorWithDeviceWhite:0.450 alpha:1.000]
#define SNRWindowButtonCrossInset 1.f
#define SNRWindowButtonHighlightOverlayColor [NSColor colorWithDeviceWhite:0.000 alpha:0.300]
#define SNRWindowButtonInnerShadowColor [NSColor colorWithDeviceWhite:1.000 alpha:0.100]
#define SNRWindowButtonInnerShadowOffset NSMakeSize(0.f, 0.f)
#define SNRWindowButtonInnerShadowBlurRadius 1.f
#interface SNRHUDWindowButtonCell : NSButtonCell
#end
#interface SNRHUDWindowFrameView : NSView
- (void)snr_drawTitleInRect:(NSRect)rect;
#end
#implementation SNRHUDWindow {
NSView *__customContentView;
}
- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
{
if ((self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:bufferingType defer:deferCreation])) {
[self setOpaque:NO];
[self setBackgroundColor:[NSColor clearColor]];
[self setMovableByWindowBackground:YES];
[self setLevel:NSFloatingWindowLevel];
}
return self;
}
- (NSRect)contentRectForFrameRect:(NSRect)windowFrame
{
windowFrame.origin = NSZeroPoint;
windowFrame.size.height -= SNRWindowTitlebarHeight;
return windowFrame;
}
+ (NSRect)frameRectForContentRect:(NSRect)windowContentRect
styleMask:(NSUInteger)windowStyle
{
windowContentRect.size.height += SNRWindowTitlebarHeight;
return windowContentRect;
}
- (NSRect)frameRectForContentRect:(NSRect)windowContent
{
windowContent.size.height += SNRWindowTitlebarHeight;
return windowContent;
}
- (void)setContentView:(NSView *)aView
{
if ([__customContentView isEqualTo:aView]) {
return;
}
NSRect bounds = [self frame];
bounds.origin = NSZeroPoint;
SNRHUDWindowFrameView *frameView = [super contentView];
if (!frameView) {
frameView = [[SNRHUDWindowFrameView alloc] initWithFrame:bounds];
NSSize buttonSize = SNRWindowButtonSize;
NSRect buttonRect = NSMakeRect(SNRWindowButtonEdgeMargin, NSMaxY(frameView.bounds) -(SNRWindowButtonEdgeMargin + buttonSize.height), buttonSize.width, buttonSize.height);
NSButton *closeButton = [[NSButton alloc] initWithFrame:buttonRect];
[closeButton setCell:[[SNRHUDWindowButtonCell alloc] init]];
[closeButton setButtonType:NSMomentaryChangeButton];
[closeButton setTarget:self];
[closeButton setAction:#selector(close)];
[closeButton setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin];
[frameView addSubview:closeButton];
[super setContentView:frameView];
}
if (__customContentView) {
[__customContentView removeFromSuperview];
}
__customContentView = aView;
[__customContentView setFrame:[self contentRectForFrameRect:bounds]];
[__customContentView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[frameView addSubview:__customContentView];
}
- (NSView *)contentView
{
return __customContentView;
}
- (void)setTitle:(NSString *)aString
{
[super setTitle:aString];
[[super contentView] setNeedsDisplay:YES];
}
- (BOOL)canBecomeKeyWindow
{
return YES;
}
#end
#implementation SNRHUDWindowFrameView
- (void)drawRect:(NSRect)dirtyRect
{
NSRect drawingRect = NSInsetRect(self.bounds, 0.5f, 0.5f);
NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:drawingRect xRadius:SNRWindowCornerRadius yRadius:SNRWindowCornerRadius];
[NSGraphicsContext saveGraphicsState];
[path addClip];
// Fill in the title bar with a gradient background
NSRect titleBarRect = NSMakeRect(0.f, NSMaxY(self.bounds) - SNRWindowTitlebarHeight, self.bounds.size.width, SNRWindowTitlebarHeight);
NSGradient *titlebarGradient = [[NSGradient alloc] initWithStartingColor:SNRWindowBottomColor endingColor:SNRWindowTopColor];
[titlebarGradient drawInRect:titleBarRect angle:90.f];
// Draw the window title
[self snr_drawTitleInRect:titleBarRect];
// Rest of the window has a solid fill
NSRect bottomRect = NSMakeRect(0.f, 0.f, self.bounds.size.width, self.bounds.size.height - SNRWindowTitlebarHeight);
[SNRWindowBottomColor set];
[NSBezierPath fillRect:bottomRect];
// Draw the highlight line around the top edge of the window
// Outset the width of the rectangle by 0.5px so that the highlight "bleeds" around the rounded corners
// Outset the height by 1px so that the line is drawn right below the border
NSRect highlightRect = NSInsetRect(drawingRect, 0.f, 0.5f);
// Make the height of the highlight rect something bigger than the bounds so that it won't show up on the bottom
highlightRect.size.height += 50.f;
highlightRect.origin.y -= 50.f;
NSBezierPath *highlightPath = [NSBezierPath bezierPathWithRoundedRect:highlightRect xRadius:SNRWindowCornerRadius yRadius:SNRWindowCornerRadius];
[SNRWindowHighlightColor set];
[highlightPath stroke];
[NSGraphicsContext restoreGraphicsState];
[SNRWindowBorderColor set];
[path stroke];
}
- (void)snr_drawTitleInRect:(NSRect)titleBarRect
{
NSString *title = [[self window] title];
if (!title) { return; }
NSShadow *shadow = [NSShadow new];
[shadow setShadowColor:SNRWindowTitleShadowColor];
[shadow setShadowOffset:SNRWindowTitleShadowOffset];
[shadow setShadowBlurRadius:SNRWindowTitleShadowBlurRadius];
NSMutableParagraphStyle *style = [NSMutableParagraphStyle new];
[style setAlignment:NSCenterTextAlignment];
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:SNRWindowTitleColor, NSForegroundColorAttributeName, SNRWindowTitleFont, NSFontAttributeName, shadow, NSShadowAttributeName, style, NSParagraphStyleAttributeName, nil];
NSAttributedString *attrTitle = [[NSAttributedString alloc] initWithString:title attributes:attributes];
NSSize titleSize = attrTitle.size;
NSRect titleRect = NSMakeRect(0.f, NSMidY(titleBarRect) - (titleSize.height / 2.f), titleBarRect.size.width, titleSize.height);
[attrTitle drawInRect:NSIntegralRect(titleRect)];
}
#end
#implementation SNRHUDWindowButtonCell
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
NSRect drawingRect = NSInsetRect(cellFrame, 1.5f, 1.5f);
drawingRect.origin.y = 0.5f;
NSRect dropShadowRect = drawingRect;
dropShadowRect.origin.y += 1.f;
// Draw the drop shadow so that the bottom edge peeks through
NSBezierPath *dropShadow = [NSBezierPath bezierPathWithOvalInRect:dropShadowRect];
[SNRWindowButtonDropShadowColor set];
[dropShadow stroke];
// Draw the main circle w/ gradient & border on top of it
NSBezierPath *circle = [NSBezierPath bezierPathWithOvalInRect:drawingRect];
NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:SNRWindowButtonGradientBottomColor endingColor:SNRWindowButtonGradientTopColor];
[gradient drawInBezierPath:circle angle:270.f];
[SNRWindowButtonBorderColor set];
[circle stroke];
// Draw the cross
NSBezierPath *cross = [NSBezierPath bezierPath];
CGFloat boxDimension = floor(drawingRect.size.width * cos(45.f)) - SNRWindowButtonCrossInset;
CGFloat origin = round((drawingRect.size.width - boxDimension) / 2.f);
NSRect boxRect = NSMakeRect(1.f + origin, origin, boxDimension, boxDimension);
NSPoint bottomLeft = NSMakePoint(boxRect.origin.x, NSMaxY(boxRect));
NSPoint topRight = NSMakePoint(NSMaxX(boxRect), boxRect.origin.y);
NSPoint bottomRight = NSMakePoint(topRight.x, bottomLeft.y);
NSPoint topLeft = NSMakePoint(bottomLeft.x, topRight.y);
[cross moveToPoint:bottomLeft];
[cross lineToPoint:topRight];
[cross moveToPoint:bottomRight];
[cross lineToPoint:topLeft];
[SNRWindowButtonCrossColor set];
[cross setLineWidth:2.f];
[cross stroke];
// Draw the inner shadow
NSShadow *shadow = [[NSShadow alloc] init];
[shadow setShadowColor:SNRWindowButtonInnerShadowColor];
[shadow setShadowBlurRadius:SNRWindowButtonInnerShadowBlurRadius];
[shadow setShadowOffset:SNRWindowButtonInnerShadowOffset];
NSRect shadowRect = drawingRect;
shadowRect.size.height = origin;
[NSGraphicsContext saveGraphicsState];
[NSBezierPath clipRect:shadowRect];
[circle fillWithInnerShadow:shadow];
[NSGraphicsContext restoreGraphicsState];
if ([self isHighlighted]) {
[SNRWindowButtonHighlightOverlayColor set];
[circle fill];
}
}
#end
Any ideas what could be responsible for the NSPanel losing its resizing ability?
I'm using this framework as well, and the reason that resizing doesn't work by default is this line in the initWithContentRect method:
if ((self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:bufferingType defer:deferCreation])) {
As you can see, instead of passing the windowStyle bitmask provided to super's init method, it passes through just NSBorderlessWindowMask. A bit of sniffing around shows that for resizing to be possible at all, the styleMask must have NSResizableWindowMask included in the bitmask.
So, changing the line to
if ((self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask|NSResizableWindowMask backing:bufferingType defer:deferCreation])) {
should solve your problem.
I am using NSButtonCell subclass to display checkbox , image and label in same cell. Now i want to edit label in outlineView on double click or on enter key.
NSButtonCell subclass:
- (void)dealloc {
[image release];
image = nil;
[super dealloc];
}
-(id)copyWithZone:(NSZone *)zone {
ImageAndTextAndCheckBox *cell = (ImageAndTextAndCheckBox *)[super copyWithZone:zone];
cell->image = [image retain];
return cell;
}
- (void)setImage:(NSImage *)anImage {
if (anImage != image) {
[image release];
image = [anImage retain];
[image setSize:NSMakeSize(kIconImageSize, kIconImageSize)];
}
}
- (NSImage *)image {
return image;
}
#define KNImageAndTextButtonCellPadding 5 // Distance between the end of the image and the start of the text.
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
// Draw the original button first, then the image.
//shift check box to right
NSRect newCellFrame = cellFrame;
newCellFrame.origin.x = newCellFrame.origin.x + 5;
cellFrame = newCellFrame;
[super drawWithFrame:cellFrame inView:controlView];
if (image != nil) {
NSRect imageFrame;
NSSize imageSize = [image size];
NSDivideRect(cellFrame, &imageFrame, &cellFrame, KNImageAndTextButtonCellPadding + imageSize.width, NSMinXEdge);
imageFrame.origin.x += imageFrame.size.width;
imageFrame.size = imageSize;
if ([controlView isFlipped]) {
imageFrame.origin.y += ceil((cellFrame.size.height + imageFrame.size.height) / 2);
} else {
imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2);
}
BOOL oldFlipped = [image isFlipped];
[image setFlipped:![controlView isFlipped]];
[image compositeToPoint:imageFrame.origin operation:NSCompositeSourceOver];
[image setFlipped:oldFlipped];
}
}
-(BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)untilMouseUp {
// Make sure that the mouse only gets tracked if it is clicked on the check box, otherwise
// the row will be checked/unchecked whenever the user clicks on any part of the cell (which is bad).
if ([theEvent clickCount] > 1)
{
NSLog(#"do double-click action" );
}
else
{
NSLog(#"do single-click action" );
}
NSPoint event_location = [theEvent locationInWindow];
NSPoint localPoint = [controlView convertPoint:event_location fromView:nil];
//shift check box mouse event to right
NSRect newCellFrame = cellFrame;
newCellFrame.origin.x = newCellFrame.origin.x + 5;
cellFrame = newCellFrame;
if (localPoint.x <= cellFrame.origin.x + 16) {
return [super trackMouse:theEvent inRect:cellFrame ofView:controlView untilMouseUp:untilMouseUp];
} else {
return NO;
}
}
-(NSRect)drawTitle:(NSAttributedString *)title withFrame:(NSRect)frame inView:(NSView *)controlView {
// Adjust the rect so we don't interfere with the image's location
if (image != nil) {
//NSLog(#"orig %f %f %f %f", frame.size.width,frame.size.height,frame.origin.x,frame.origin.y);
NSRect newFrame = NSOffsetRect(frame, [[self image] size].width + KNImageAndTextButtonCellPadding, 0);
newFrame.size.width -= ([[self image] size].width + KNImageAndTextButtonCellPadding);
//NSLog(#"drawTitle %f %f %f %f", newFrame.size.width,newFrame.size.height,newFrame.origin.x,newFrame.origin.y);
return [super drawTitle:title withFrame:newFrame inView:controlView];
} else {
return [super drawTitle:title withFrame:frame inView:controlView];
}
}
- (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject event:(NSEvent *)theEvent {
NSLog(#"%#", anObject);
// id node = [anObject itemAtRow: [anObject selectedRow]];
// int length = [[node relativePath] length];
NSRect newFrame = NSOffsetRect(aRect, KNImageAndTextButtonCellPadding+kIconImageSize+ 16, 0);
newFrame.size.width -= (KNImageAndTextButtonCellPadding+kIconImageSize+ 16);
[super editWithFrame:newFrame inView:controlView editor:textObj delegate:anObject event:theEvent];
}
I am getting always 1 (boolean value) in
- (void)outlineView:(NSOutlineView *)ov
setObjectValue:(id)obj
forTableColumn:(NSTableColumn *)tableColumn
byItem:(id)item
NSOutlineView delegate method.(because of NSButtonCell) but i want to edit label.
How can i edit label?
How to handle double click ?
Before pressing enter key:
After
How to change color text? its displaying white color.
it should be like (with checkbox)
Can anyone please help me out?
I want to add an icon to the NSTabViewItem with some text.
Please help me with the code in drawLabel:inRect: method.
- (id)initWithCoder:(NSCoder *)decoder
{
[super initWithCoder:decoder];
tabCell = [[NSBrowserCell alloc] initImageCell:[NSImage
imageNamed:#"xyz"]];
[tabCell setLeaf:YES];
[tabCell setFont:[[self tabView] font]];
[tabCell setStringValue: [self label]];
return self;
}
- (void)drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect
{
{ // modify the rect a tad so the cell draws properly..
tabRect.origin.y += 2;
tabRect.size.width += 16;
}
[tabCell drawWithFrame:tabRect inView:[self tabView]];
}
- (NSSize)sizeOfLabel:(BOOL)shouldTruncateLabel
{
NSSize superSize = [super sizeOfLabel:shouldTruncateLabel];
NSImage *icon = [tabCell image];
superSize.width += [icon size].width-4;
return superSize;
}
I am able to add an icon to the NSTabViewItem but the icon is coming out of the tab because of its big size. How can I maintain the size of icon to stay within the TabViewItem?
Not sure, if your problem got resolve, i had similar use case,and i am using drawLabel and appending image in that,
refer the code snippet,
- (void)drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect{
NSImage *pImage = [self getImage];
[[NSGraphicsContext currentContext] saveGraphicsState];
NSAffineTransform* xform = [NSAffineTransform transform];
[xform translateXBy:0.0 yBy: tabRect.size.height];
[xform scaleXBy:1.0 yBy:-1.0];
[xform concat];
if(pImage){
[pImage drawInRect:NSMakeRect(tabRect.origin.x-8,-6,16, 16)fromRect:NSZeroRect
operation:NSCompositeSourceOver
fraction:opacity];
}
[[NSGraphicsContext currentContext] restoreGraphicsState];
[super drawLabel:shouldTruncateLabel inRect:tabRect];
NSLog(#" Inside drawRect text (%#)",[self labeltitle]);
}
This code works for me (Swift 3):
import Foundation
import Cocoa
class MyTabViewItem : NSTabViewItem
{
let iconWidth:CGFloat = 16
override func sizeOfLabel(_ shouldTruncateLabel: Bool) -> NSSize
{
var superSize: NSSize = super.sizeOfLabel(shouldTruncateLabel)
superSize.width += iconWidth
return superSize
}
override func drawLabel(_ shouldTruncateLabel: Bool, in tabRect: NSRect)
{
let icon: NSImage? = NSImage(named:"Eye")
if icon != nil
{
let opacity:CGFloat = 0.5
icon?.draw(in: NSMakeRect(tabRect.origin.x + tabRect.width - iconWidth + 4, 8, iconWidth, iconWidth), from: NSZeroRect, operation: NSCompositeSourceOver, fraction: opacity)
}
super.drawLabel(shouldTruncateLabel, in: tabRect)
}
}
Not fully tested, you may have to change some of the constants if the iconWidth changes.
Based on Amitg2k12's example with some additions:
- (id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (self) {
[self setToolTip:[self label]];
[self setLabel:#" "];
}
return self;
}
- (NSSize)sizeOfLabel:(BOOL)computeMin {
return NSMakeSize(16, 18);
}
- (void)drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect {
NSImage *image = [self image];
NSRect destRect = NSMakeRect(tabRect.origin.x, tabRect.origin.y + 2, 16, 16);
[[NSGraphicsContext currentContext] saveGraphicsState];
NSAffineTransform *affineTransform = [NSAffineTransform transform];
[affineTransform translateXBy:NSMaxX(destRect) yBy:NSMinY(destRect)];
[affineTransform scaleXBy:1.0 yBy:-1.0];
[affineTransform concat];
if(image) {
[image drawInRect:NSMakeRect(-NSWidth(destRect), -NSHeight(destRect), 16, 16) fromRect:NSZeroRect
operation:NSCompositeSourceOver
fraction:1.0f];
}
[[NSGraphicsContext currentContext] restoreGraphicsState];
[super drawLabel:shouldTruncateLabel inRect:tabRect];
}
#end
I would like to zoom and rotate an UIImageView. Here is my code:
#synthesize immagine, velocita, locationManager, direzione;
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{
double degrees = newHeading.magneticHeading;
double radians = degrees * M_PI / 180;
[UIView animateWithDuration:0.05 animations:^{
self.immagine.transform = CGAffineTransformMakeRotation(-radians);
}];
}
-(UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView {
return immagine;
}
- (void)viewDidLoad
{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate=self;
locationManager.desiredAccuracy=kCLLocationAccuracyBestForNavigation;
[scrollView setDelegate:self];
[scrollView setContentSize:CGSizeMake(320, 460)];
immagine = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"mappa1"]];
immagine.frame = CGRectMake(0, 0, 320, 460);
immagine.contentMode = UIViewContentModeScaleAspectFit;
[scrollView addSubview:immagine];
locationManager.headingFilter = kCLHeadingFilterNone;
[locationManager startUpdatingHeading];
[super viewDidLoad];
}
But when I'm zooming, the UIImageView exit from the View. Can anyone help me? Thanks in advance!
I have problem like this and these two function will solve your problem
- (void)twoFingerPinch:(UIPinchGestureRecognizer *)recognizer
{
CGRect originalFrame=recognizer.view.frame;
CGRect newFrame=CGRectMake(originalFrame.origin.x, originalFrame.origin.y, originalFrame.size.width*recognizer.scale, originalFrame.size.height*recognizer.scale);
if (newFrame.size.width>70&&newFrame.size.width<150)
{
recognizer.view.frame=newFrame;
}
}
- (void)twoFingersRotate:(UIRotationGestureRecognizer *)recognizer
{
[self.view bringSubviewToFront:[(UIRotationGestureRecognizer*)recognizer view]];
if([(UIRotationGestureRecognizer*)recognizer state] == UIGestureRecognizerStateEnded) {
lastRotation = 0.0;
return;
}
CGFloat rotation = 0.0 - (lastRotation - [(UIRotationGestureRecognizer*)recognizer rotation]);
CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)recognizer view].transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform,rotation);
[[(UIRotationGestureRecognizer*)recognizer view] setTransform:newTransform];
lastRotation = [(UIRotationGestureRecognizer*)recognizer rotation];
// recognizer.view.transform=CGAffineTransformMakeRotation(([recognizer rotation] * 180) / M_PI);
}