Window resizing problems in Xcode example - objective-c

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.

Related

OSX Fullscreen (Kiosk) Application with Custom Resolution

I have an OS X Metal application that I would like to run in fullscreen at a non-native resolution, e.g. my native resolution is 1920x1080 and I would like to render the app in fullscreen at 1024x768. (I don't believe that using Metal to draw things impacts this question other than I am unable to use the OpenGL-specific NSView functions.)
My renderer uses a back buffer with a hard-coded size of 1024x768.
When I create my window with bounds = 1024x768 I get a fullscreen window, but my content is drawn centered and it does not stretch to fill the whole screen.
When I create my window with bounds = 1920x1080 I get a fullscreen window, but my content is drawn in the upper-left corner and incorrectly scaled (because of the ratio mismatch between the two resolutions).
Using [NSView - enterFullScreenMode:withOptions:] yielded the same results. Setting [NSView autoresizingMask] didn't change anything either.
Ideally I want the window to be the size of the screen and have the low-resolution back buffer be stretched to fill the whole window. What am I missing that would allow me to do that?
The relevant app initialization from my NSResponder <NSApplicationDelegate>:
// Create the window
self.Window = [NSWindow alloc];
[self.Window initWithContentRect:bounds
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:YES];
// Create the view
self.View = [NSView alloc];
[self.View initWithFrame:bounds];
[self.View setWantsLayer:YES]; // The generated layer is CAMetalLayer
// Associate the view with the window
[self.Window setContentView:self.View];
// Misc
[self.Window makeKeyAndOrderFront:self.Window];
[self.Window setAcceptsMouseMovedEvents:YES];
[self.Window setHidesOnDeactivate:YES];
// Fullscreen
[self.Window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
[self.Window toggleFullScreen:nil];
[self.Window makeFirstResponder:self.View];
Thanks.
The layer that backs a view is constrained to have its frame equal to that view's bounds. By default, the drawableSize of a CAMetalLayer is equal to its bounds times its contents scale. However, you can set it to any size you desire by explicitly setting the layer's drawableSize.

How do I change the size of the scene in the .sks file?

I am trying to use the .sks file as a way of previewing what my app will look like. This is a Mac OSX app by the way.
I have changed the size of the window and SKScene programmatically in the AppDelegate.m file like this:
NSRect frame = [_window frame];
frame.size = CGSizeMake(1280, 740);
[_window setFrame: frame display: YES animate: NO];
[_window center]; //sets the window to the centre of the screen
GameScene *scene = [GameScene unarchiveFromFile:#"GameScene"];
scene.size = CGSizeMake(1280, 720);
It doesn't seem like the .sks file reflects any of this. I just can't any info on how to use .sks files. Thanks in advance.
I just realized that it's actually pretty easy. I don't know how I didn't notice this before. If you click on the .sks file and open the pane on the right side (it says "hide or show the utilities" when you mouse over it), then click on the scene inspector, you can change the width and height of the scene if the scene if your object of focus.

How to resize Window to dimension in VIew Controller for a OSX app?

I'm fairly new to Mac OSX Apps, but I'm trying to build an app with no status bar, and the dimensions are smaller. So what I did in my AppDelegate.m is:
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
self.mainViewController = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
[self.window.contentView addSubview:self.mainViewController.view];
[self.window setOpaque:NO];
[self.window setStyleMask:NSBorderlessWindowMask];
[self.window setBackgroundColor:[NSColor clearColor]];
self.mainViewController.view.frame = ((NSView*)self.window.contentView).bounds;
}
Now, what I really want to do, is to get my window to look like, what I've built in my interface builder (can't post pictures yet). I've tried shutting off all the autosizing elements but when I run the simulator I get a clipped version of my interface (the size changes every run). It seem like the frame size is getting miscalculated, but I've done everything from the interface builder. I can programmatically set the shapes of the view, but is there a way to shut off all resizing and simply portray the xib file as what I see in the interface builder?
There are two ways you could approach this problem.
You add an AutoresizingMask to your ViewController:
[self.mainViewController setAutoresizingMask:NSViewAutoresizingFlexibleWidth|NSViewAutoresizingFlexibleHeigt];
You disable window resizing in the Interface builder like by setting its minimum and maximum size. This can also be done in code.
Edit: Thanks to trojanfoe for pointing out that you can also uncheck Resize in the Attributes Inspector.
You can easily resize your window programatically. Here's how:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
NSRect frame;
frame.size.height = 200;
frame.size.width = 200;
[window setFrame:frame display:YES animate:YES];
}

Using NSImage as patterned/repeated background in NSWindow

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)?

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)