Using NSImage as patterned/repeated background in NSWindow - objective-c

I want to display NSImage as repeated background in NSWindow. I am using this code:
_window.backgroundColor = [NSColor colorWithPatternImage:[NSImage imageNamed:#"image.png"]];
The problem arises on resizing, because only the new area (at the bottom and the right) of the window is redisplayed and the background origin is in the bottom-left corner. That results in image gliching:
Current workaround is to redisplay window on resize:
_window.delegate = self;
...
- (void)windowDidResize:(NSNotification *)notification {
[_window display];
}
My questions are:
Is there a way to automatically display all background on resizing (i.e. without usign windowDidResize:)?
Can background origin be changed to upper-left correr (so that new area on resizing will seamlessly continue existing one)?

Related

Why UITextfield setBackground UIColor White turn to transparent?

I am writing an app and I want to make a textfield background turn white.
So far this is my code:
- (void)viewDidLoad
{
UITextField *txtfield = UsernameTextField;
[txtfield setBackgroundColor:[UIColor colorWithWhite:1 alpha:0.5] ];
txtfield.layer.borderColor = [UIColor blackColor].CGColor;
txtfield.layer.borderWidth = 1;
txtfield.borderStyle = UITextBorderStyleRoundedRect;
[super viewDidLoad];
// Do any additional setup after loading the view.
}
But this code have a result like this:
and i tried this code , to increast alpha
[txtfield setBackgroundColor:[UIColor colorWithWhite:1 alpha:0.8] ];
still the same
and also i see this post
iPhone UITextField background color
and i tried
but it still the same
Why textfield wont turn to white?
First thing first you should
[super viewDidLoad] should be the first statement in - (void)viewDidLoad after initialising parent child should do initialise.
Second
Please check the order of views put on view controller bring UsernameTextField to top of all views or you can call [self.view bringSubviewToFront:txtfield] in code
Third
Only by setting alpha to 1.0 you can see complete white background.
and finally is you still don't get it resolved then there is some changes you did in xib/storyboard view. So to reset just delete textfield and add it again.
In order to change background color it's important to set the border to None
txtfield.borderStyle = UITextBorderStyleNone;
Details: Changing background colour within a TextField in Interface Builder
iPhone UITextField background color
From Apple Doc:
When set, the image referred to by this property replaces the standard appearance controlled by the borderStyle property. Background images are drawn in the border rectangle portion of the text field. Images you use for the text field’s background should be able to stretch to fit.

Window resizing problems in Xcode example

I've downloaded Apple's example GLEssentials. Then added a programmatically window resizing in a method awakeFromNib in GLEssentialsWindowController class implementation:
-(void) awakeFromNib
{
NSRect rect = [view convertRectToBacking:NSMakeRect(0,0,500,500)];
[self.window setFrame:rect display:YES animate:NO];
}
Here comes the most of fun. When I doing such simple operation on my working iMac there is no problems at all. Window size becomes what I expected.
But when I doing this operation on my MacBook window resizes to value stored in .xib file. Then I manually resize window to some new size and quit from application. Then launch it again. Window resizes to the size that this window had at the last launch right before it was closed.
Any suggestions?
As I understood, NSOpenGLView class calls resize method even after window is initialized, that's why the only solution to do not allow window to resize right after awakeFromNib event is remove resizable mask from window styles:
[window setStyleMask:[window styleMask] & ~NSResizableWindowMask];
So the final solution will look like:
- (void) awakeFromNib
{
[self.window setStyleMask:[self.window styleMask] & ~NSResizableWindowMask];
NSRect rect = [view convertRectToBacking:NSMakeRect(0,0,500,500)];
[self.window setFrame:rect display:YES animate:NO];
}
So the target window will be resized to 500 x 500, and doesn't matter what the size was stored in .xib file.

Is there Any way to imitate Lion's Launchpad?

I have been struggling to imitate Launchpad.
At the beginning I thought about making NSWindow bgcolor transparent:
//make NSWindow's bgcolor transparent
[window setOpaque:NO];
[window setBackgroundColor:[NSColor clearColor]];
But now I realized it's way more ideal to
capture wallpaper
blur it and make it bg-image for NSWindow or a view
Rather than hiding all the opened windows and menubar, which was the first idea I had have come with (Still not sure with better, if you had any better idea...).
Capture & blur wallpaper used by a user
Make it background image for nswindow or a view
Fade-in to fullscreen view
Click somewhere blank or press ESC to fade-out
Are those possible to achieve without using private APIs?
Sorry if it's not clear my poor English.
Simply I'm trying to imitate Launchpad-styled full screen.
Thanks for any advice.
To get an image of the desktop background, use:
NSURL *imageURL = [[NSWorkspace sharedWorkspace] desktopImageuRLForScreen:[NSScreen mainScreen]
NSImage *theDekstopImage = [[NSImage alloc] initWithContentsOfURL:imageURL];
You can blur the image using CIFilter. Here's a Apple doc describing how to apply filters.
And then you can load that image into a color and set that as the background color for the window. Additionally, set the window to have no style mask (no close buttons, title frame, etc.), cover the screen, and be in front of everything except the dock:
[yourWindow setBackgroundColor:[NSColor colorWithPatternImage:theDesktopImage]];
[yourWindow setStyleMask:NSBorderlessWindowMask];
[yourWindow setLevel:kCGDockWindowLevel - 1];
[yourWindow setFrame:[[NSScreen mainScreen] frame] display:YES];
To have the window fade in, you can use NSWindow's animator proxy. (Replace 1.0 with 0.0 to make it fade out.)
[[yourWindow animator] setAlphaValue:1.0];
Of course you could customize that a bit more with things like CoreAnimation, but this should work just fine.
To handle background clicking, I suggest making a subclass of NSView where you -orderOut: your window on -mouseDown:. Then put an instance of that subclass that spans the entire frame of your window.
Also, NSViews sometimes don't respond to key events, so you can add an event listener to detect any time the escape key is pressed while your app is active:
[NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask handler:(NSEvent *ev)^ {
if([ev keyCode] == 0x53) {
[yourWindow orderOut:self];
}
return ev;
}

Drawing a Window at Coordinates or Drawing outside of NSStatus Item

I am trying to display something off the side of a NSStatusItem. I think I could do this in two ways:
Display a transparent window with the image I need at the coordinates of the mouse cursor.
OR
Use a custom NSStatusItem and move the controls/images in the view to the left so they are actually off the status item
The problem is, setting the NSRect frame negative (-200,0,100,50) doesn't seem to actually work. So, how can I render things outside of the bounds of the status item (think the CSS overflow property) or render a transparent window at specific coordinates?
The system will prevent you from drawing outside the status item, but using a transparent window will work.
NSRect rect; //The location of the window
NSWindow *win = [[NSWindow alloc] initWithContentRect:rect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES];
[win setOpaque:NO];
[win setBackgroundColor:[NSColor clearColor]];
//or
[win setContentView:myView];
Here, myView is a custom view which will be the background of the window. In order for the window to be transparent, you either have to set the background color to clear or use a custom content view which only draws where it is not transparent. You will probably want to use a floating window so that it stays on top. Be careful not to cover up something important because your window could intercept events intended for something underneath it.

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)