NSImage problems - objective-c

Trying to draw a pattern inside a NSView subclass. I am trying to draw this using NSColor and its method colorWithPatternImage, however when I draw that on the screen the texture keeps moving when resizing the window.
The following code is associated with my custom drawing:
[[NSColor colorWithPatternImage:[NSImage imageNamed:#"texture"]] set];
NSRectFillUsingOperation([self bounds],NSCompositeSourceOver);
I have only tested this on 10.7.
thanks

Related

cocoa - draw image in NSView

I'm having difficulties understanding why the below code doesn't work, what I want to achieve is an image being displayed in the top left corner of a NSView, but nothing is showing...
NSImage *map0 = [NSImage imageNamed:#"map0.png"];
NSRect rect = NSMakeRect(0, 0, 400, 400);
[map0 drawInRect:rect fromRect:NSZeroRect operation:NSCompositeSourceAtop fraction:1.0f];
[map drawRect:rect];
EDIT:
map is the NSView into which I would like to draw the image into
You never call drawRect: directly. This routine has various pre-conditions that are provided by Cocoa, such as the creation of a CGContextRef. You implement drawRect:. Cocoa calls it.
Your drawInRect:fromRect:operation:fraction: call should be put into the drawRect: of map, which should be a subclass of NSView. This specific problem is usually better solved with an NSImageView rather than a custom NSView, but if the drawing is more complex, then a custom NSView is appropriate.

Drawing Transparent Images

I created a custom view to a button, as I need to implement some highlighting when the mouse is over. The class is very simple, and I already implemented mouseEntered: as well as mouseExited:. The view was registered for tracking in the init method (not sure if it's the best place).
The problem is drawing. I keep an ivar mouseOver, set to YES on mouse enter and NO on mouse exited. The other ivar is for the image, called image. The difference between mouse over or not when it comes to drawing, is the transparency. Here is my drawRect::
- (void)drawRect:(NSRect)dirtyRect
{
[image drawAtPoint:NSMakePoint(0.0,0.0)
fromRect:dirtyRect
operation:NSCompositeCopy
fraction:((mouseOver) ? 1.0 : 0.0)];
}
It works nicely, but only when the mouse first entered, apparently. I guess the problem is that the view is not cleared before drawing the other image. I tried adding:
[[NSColor clearColor] set];
NSRectFillUsingOperation(dirtyRect, NSCompositeClear);
But without success. How can I fix this?
[NSColor clearColor] is a purely transparent color. You probably want to fill using a color with some opacity, like, say, [NSColor whiteColor].

Stopping transparent drawing going all the way through NSViews

I'm doing some simple drawing in my NSView's drawRect with code like this
[[NSColor colorWithCalibratedWhite:0.250 alpha:0.700] set];
NSRectFill(dRect);
This drawing is being done in a nested view and I'm finding that the transparency goes all the way through the parent view and window showing some of the screen beneath it.
How do I get it so the transparency only goes through to the parent view (or any drawing that was done in that frame before it?
Thanks!
You really shouldn't be using NSRectFill to draw a transparent color. A call to
NSRectFill(rect);
is really just a shortcut to
NSRectFillUsingOperation(rect, NSCompositeCopy);
NSCompositeCopy doesn't perform compositing, so you can get unexpected results when a transparent NSColor is set.
Try using this instead:
[[NSColor colorWithCalibratedWhite:0.250 alpha:0.700] set];
[NSBezierPath fillRect:rect];
That should draw the transparency properly, with the underlying drawing visible.

Custom NSScrollers having weird effect from Core Animation

I am making custom NSScrollers for use in NSScrollView. But when any of the superviews of the NSScroller gets Core Animation enabled. I get this drawing issue that's a huge nuisance. Whenever i scroll into the corners of the scroll view the scrollers clip. But if a scroller starts out drawing in the corner, the scroller part stays in that corner. What could be causing this problem? I have too much code to show on here. But here is my drawing code:
NSRect knobRect = [self rectForPart:NSScrollerKnob];
NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:knobRect
xRadius:CornerRadius
yRadius:CornerRadius];
[path setLineWidth:2];
[[NSColor colorWithDeviceRed:0.114 green:0.114 blue:0.114 alpha:0.3] set];
[path fill];
[[NSColor colorWithDeviceWhite:1.0
alpha:0.100] set];
// Clip drawing to this path; draw nothing outwith the path.
[path addClip];
[path stroke];
I already tried to get rid of everything except the fill but it didnt work. This issue goes away if I call setNeedsDisplay:YES on the super view when setFloatValue is called.
Clipping Issue http://idkz.org/b814ee5c875c9f44cc2d1345e4489420
it seems that the answer to the problem seems to be to call:
[self setArrowsPosition:NSScrollerArrowsNone];
And it magically works :D
Edit, but I get a similar effect when I drag the scrollbar. :'( Is there anyway to clear the graphics without redrawing the scrollview itself? :(
You probably found this out by know, but in your case, the following piece should solve your drawing issue:
-(BOOL)isOpaque {
return NO;
}

Custom NSView Fill Paints Over Bottom Bar

I have a window which has a custom NSView and has a bottom bar with controls on it, one of which is an NSColorWheel.
For simplicity sake the Window is 332px high, with the custom NSView being 300px high and the bottom bar being 32px high.
The bottom bar is created as part of my awakeFromNib when the app loads the window using the following code:
[[self window] setAutorecalculatesContentBorderThickness:YES forEdge:NSMinYEdge];
[[self window] setContentBorderThickness: 32.0 forEdge: NSMinYEdge];
In my custom NSView class I fill the rectangle with color. Everything works fine when the app loads using the following in my NSView class:
- (void)drawRect:(NSRect)dirtyRect
{
dirtyRect = [self bounds];
NSColor * mNewColor = [NSColor blackColor];
[mNewColor set];
[NSBezierPath fillRect:dirtyRect];
}
However, if I subsequently call a method that changes the color of the custom NSView when a color wheel in the bottom bar is changed, the bottom bar gets overwritten with the color. The following code illustrates this method (this code is in the custom NSView class:
- (void)changeBackgroundColor:(NSNotification *)notification
{
NSLog(#"Changed background color");
NSRect mRect = [self bounds];
NSColor * mNewColor = [theColorWell color];
[mNewColor set];
[NSBezierPath fillRect:mRect];
[self setNeedsDisplay:YES];
}
Resizing the window instantly corrects the problem, but obviously I don't want the user to have to resize the window for an obvious bug!
What I don't understand is why my bounds appear to be mapping to the parent window and not the custom NSView when I call setNeedsDisplay and yet the bound correctly adjust when I resize the window using the mouse (even if just by 1 pixel).
Do I somehow need to account for the bottom bar on the redraw?
Any and all help much appreciated.
You should do all your drawing in the drawRect: method of your custom NSView. Cocoa automatically sets up the graphics context for you when it calls this method - things may not draw correctly if you perform drawing operations in other methods.
Your code in drawRect: could set the colour to the the current background colour as specified by your NSColorWell and fill the dirtyRect rectangle with this.
Then in the other method just call [self setNeedsDisplay:YES]; and then drawRect: will automatically be called to redraw the view.
See here for more information: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CocoaViewsGuide/SubclassingNSView/SubclassingNSView.html#//apple_ref/doc/uid/TP40002978-CH7-SW4 (in particular the Drawing View Content section)