PDA

View Full Version : Fullscreen app using NSTextView




SRossi
May 27, 2009, 03:39 AM
Hello all,

I have searched the internet on a stub of code or so that may help me allow to switch between fullscreen and windowed mode. I have set up a menu item to allow me to change to fullscreen but now i am stuck.

What i am looking for is a start or any help so that i can display the NSTextView in full screen and allow the user to continue editing text on it.

Any help will be appreciated.

Thanks in advance

Stephen



allbrokeup
May 27, 2009, 03:52 AM
In your MainView's M file (the one that is direct to the Full Screen Window) include this:

- (BOOL) canBecomeKeyWindow
{
return YES;
}

That will allow everything to be activated and made editable again. Text Fields and Views tend to disable themselves for some odd reason. :D
If there is anything else you need, just reply or PM.

SRossi
May 27, 2009, 05:04 AM
Thanks man.

Can you point me in the direction I should go with the fullscreen coding, as I am beat in what to do. I have learned about using carbon to hide the menu and dock but as for making the text view appear I have no knowledge to where to start or that.

Thanks

Stephen

robbieduncan
May 27, 2009, 05:09 AM
Thanks man.

Can you point me in the direction I should go with the fullscreen coding, as I am beat in what to do. I have learned about using carbon to hide the menu and dock but as for making the text view appear I have no knowledge to where to start or that.

Thanks

Stephen

Create a title-bar-less window the size of the screen, position correctly and add the NSTextView to it. Basically read the NSWindow documentation.

SRossi
May 27, 2009, 05:41 AM
Create a title-bar-less window the size of the screen, position correctly and add the NSTextView to it. Basically read the NSWindow documentation.

Right I understand what you are saying but do I take the NSWindow of the MyDocument.xib and set it to a NSWindow variable in MyDocument.h?

I have found a tutorial on cocoadevcentral but thats using a panel, would I need to create a panel and add a NSTextView or just use the existing MyDocument.xib window?

Sorry for being a bit stupid im just totally lost.

Stephen

robbieduncan
May 27, 2009, 05:47 AM
I wasn't suggesting you do anything in Interface Builder at all. I would suggest that you have different windows for full screen and windowed mode. Your full-screen window would be created entirely in code with the appropriate styleMask (http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSWindow_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSBorderlessWindowMask).

SRossi
May 27, 2009, 06:23 AM
I wasn't suggesting you do anything in Interface Builder at all. I would suggest that you have different windows for full screen and windowed mode. Your full-screen window would be created entirely in code with the appropriate styleMask (http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSWindow_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSBorderlessWindowMask).

Ahhhh I get you now so what I have to do is create a boarderless window, then add my textView into it. Thanks for your help :). If I have any other problems i'll post them up.

Can I ask though how is it that I add a NSTextView to my new window?

Thanks

Stephen

robbieduncan
May 27, 2009, 06:37 AM
Ahhhh I get you now so what I have to do is create a boarderless window, then add my textView into it. Thanks for your help :). If I have any other problems i'll post them up.

Can I ask though how is it that I add a NSTextView to my new window?

Thanks

Stephen

Get the contentView of the window then add your NSTextView instance as a subView.

SRossi
May 27, 2009, 07:34 AM
Right I have done some code, I dont wether I am correct yet as it isn't running
my program at all. But can anyone see if there is anything wrong with my code.

iWriteDelegate.h
#import <AppKit/AppKit.h>


@interface iWriteDelegate : NSObject
{
BOOL fullScreen;
NSWindow *mainWindow;
}
- (IBAction)fullScreen:(id)sender;

- (void)showFullScreen;
- (void)exitFullScreen;

- (BOOL)isFullScreen;
- (void)setFullScreen:(BOOL)sender;
@end

iWriteDelegate.m
#import "iWriteDelegate.h"
#import "MyDocument.h"

@implementation iWriteDelegate

- (IBAction)fullScreen:(id)sender
{
BOOL inFullScreen = [self isFullScreen];

if (inFullScreen = YES) {
[self exitFullScreen];
} else {
[self showFullScreen];
}
}

- (void)showFullScreen
{
[self setFullScreen:YES];

int WindowLevel;
NSRect screenRect;

if (CGDisplayCapture(kCGDirectMainDisplay) != kCGErrorSuccess) {
NSLog(@"Couldnt capture the main display!");
}

WindowLevel = CGShieldingWindowLevel();

screenRect = [[NSScreen mainScreen] frame];

mainWindow = [[NSWindow alloc] initWithContentRect:screenRect
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO screen:[NSScreen mainScreen]];

[mainWindow setLevel:WindowLevel];

[mainWindow setBackgroundColor:[NSColor blackColor]];

NSRect cFrame = [[mainWindow contentView] frame];

NSTextView *theTextView = [[NSTextView alloc] initWithFrame:cFrame];
[mainWindow setContentView:theTextView];
[mainWindow makeKeyAndOrderFront:nil];
[mainWindow makeFirstResponder:theTextView];

[theTextView insertText:mString];

}

- (void)exitFullScreen
{
[mainWindow orderOut:self];
[self setFullScreen:NO];

if (CGDisplayRelease(kCGDirectMainDisplay) != kCGErrorSuccess) {
NSLog(@"Couldnt release the displays");
}
}

- (BOOL)isFullScreen
{
return fullScreen;
}

- (void)setFullScreen:(BOOL)sender
{
fullScreen = sender;
}

@end

It is not posting any errors it just wont open my application think it is trying to open it in fullscreen to start with.

Thanks in advance.

Stephen

Thomas Harte
May 27, 2009, 07:38 AM
Get the contentView of the window then add your NSTextView instance as a subView.
An alternative, which is more or less exactly what I'm doing is to set up everything you want for your ordinary window in Interface Builder, then to do something like:


NSView *content = [normalWindow contentView];
[content retain];
[normalWindow setContentView:nil];
[fullScreenWindow setContentView:content];
[content release];


Which should transfer the content you drew in Interface Builder from the NIB window to the one you just created, applying all the sizing criteria you set there. It's a slightly longer-than-one-line switch because an NSView can belong to only one window at a time and setContentView: will release the previous NSView.

EDIT: sorry, we appear to have posted near simultaneously. Do you set the initial value of fullScreen anywhere?

SRossi
May 27, 2009, 07:54 AM
EDIT: sorry, we appear to have posted near simultaneously. Do you set the initial value of fullScreen anywhere?


Right i have set it to NO in an initialize function in iWriteDelegate.m but it still is not opening my application.

Thanks for your help

Stephen

Thomas Harte
May 27, 2009, 08:57 AM
Well, I don't seem to be able to make the full screen window able to become first responder (which is also a problem I'm having in my own code), but by going the Interface Builder route and otherwise copying most of your code, the attached and should happily switch some window contents between windowed mode and fullscreen (on command+enter, since command+f is already taken by one of the standard Edit menu entries).

Application delegate code (also in the archive) is:

#import "IWriteAppDelegate.h"

@interface IWriteWindow: NSWindow
{
}
@end

@implementation IWriteWindow

- (BOOL)acceptsFirstResponder
{
NSLog(@"accepts\n");
return YES;
}

@end


@implementation IWriteAppDelegate
- (BOOL)isFullScreen
{
return fullScreen;
}

- (void)setFullScreen:(BOOL)sender
{
fullScreen = sender;
}

- (void)exitFullScreen
{
[self setFullScreen:NO];

NSView *content = [fullScreenWindow contentView];
[content retain];
[fullScreenWindow setContentView:nil];
[desktopWindow setContentView:content];
[content release];

[fullScreenWindow orderOut:self];
[fullScreenWindow release];
if(CGDisplayRelease(kCGDirectMainDisplay) != kCGErrorSuccess)
{
NSLog(@"Couldn't release the display");
}
}

- (void)enterFullScreen
{
[self setFullScreen:YES];

int windowLevel;
NSRect screenRect;

if(CGDisplayCapture(kCGDirectMainDisplay) != kCGErrorSuccess)
{
NSLog(@"Couldn't capture the main display!");
}

windowLevel = CGShieldingWindowLevel();
screenRect = [[NSScreen mainScreen] frame];

NSView *content = [desktopWindow contentView];
[content retain];
[desktopWindow setContentView:nil];

fullScreenWindow = [[IWriteWindow alloc] initWithContentRect:screenRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO screen:[NSScreen mainScreen]];
[fullScreenWindow setContentView:content];
[content release];

[fullScreenWindow makeKeyAndOrderFront:nil];
[fullScreenWindow makeFirstResponder:content];
[fullScreenWindow setLevel:windowLevel];
}

- (IBAction)toggleFullScreen:(id)sender {

if([self isFullScreen])
[self exitFullScreen];
else
[self enterFullScreen];
}

- (void)applicationDidFinishLaunching:(NSNotification *) note
{
fullScreen = NO;
}

@end

SRossi
May 27, 2009, 09:01 AM
Words cannot express how much that has helped me :D

Thanks soo much, if there is anything you need help with please ask :D

Thanks sooo much

Stephen

Thomas Harte
May 27, 2009, 09:03 AM
Words cannot express how much that has helped me :D

Thanks soo much, if there is anything you need help with please ask :D

Thanks sooo much

Stephen
If you do figure out how to get the borderless window to become key (it's the reason I've subclassed NSWindow, albeit not successful with respect to the goal), I'd be really grateful if you could post it! Sadly I have to return to work for the rest of the afternoon...

kainjow
May 27, 2009, 09:05 AM
If you only need 10.5+ compatibility, just use the new API:

NSView *view = [[self window] contentView];
if ([view isInFullScreenMode])
[view exitFullScreenModeWithOptions:nil];
else
[view enterFullScreenMode:[NSScreen mainScreen] withOptions:nil];

robbieduncan
May 27, 2009, 09:07 AM
If you do figure out how to get the borderless window to become key (it's the reason I've subclassed NSWindow, albeit not successful with respect to the goal), I'd be really grateful if you could post it! Sadly I have to return to work for the rest of the afternoon...

As described here (http://www.cocoadev.com/index.pl?BorderlessWindow) I think you need to override the canBecomeKeyWindow method in your NSWindow subclass to return YES.

Thomas Harte
May 27, 2009, 09:12 AM
As described here (http://www.cocoadev.com/index.pl?BorderlessWindow) I think you need to override the canBecomeKeyWindow method in your NSWindow subclass to return YES.
I thought I'd tried that immediately before acceptsFirstResponder, I guess I typed something incorrectly and was insufficiently thorough in my investigation of that. Thanks!

kainjow> does that give the Quicktime-style full screen transition animation? I guess you could use [view respondsToSelector:@selector(enterFullScreenMode:withOptions:)] to determine whether the 10.5 API is available at runtime?

EDIT: no animation, but presumably the following is smart?
#import "IWriteAppDelegate.h"

@interface IWriteWindow: NSWindow
{
}
@end

@implementation IWriteWindow

- (BOOL)canBecomeKeyWindow
{
return YES;
}

@end


@implementation IWriteAppDelegate
- (BOOL)isFullScreen
{
return fullScreen;
}

- (void)setFullScreen:(BOOL)sender
{
fullScreen = sender;
}

- (void)exitFullScreen
{
[self setFullScreen:NO];

if(fullScreenWindow)
{
NSView *content = [fullScreenWindow contentView];
[content retain];
[fullScreenWindow setContentView:nil];
[desktopWindow setContentView:content];
[content release];

[fullScreenWindow orderOut:self];
[fullScreenWindow release]; fullScreenWindow = nil;
if(CGDisplayRelease(kCGDirectMainDisplay) != kCGErrorSuccess)
{
NSLog(@"Couldn't release the display");
}
}
else
{
[[desktopWindow contentView] exitFullScreenModeWithOptions:nil];
}
}

- (void)enterFullScreen
{
[self setFullScreen:YES];

NSView *content = [desktopWindow contentView];
if([content respondsToSelector:@selector(enterFullScreenMode:withOptions:)])
{
[content enterFullScreenMode:[NSScreen mainScreen] withOptions:nil];
}
else
{
int windowLevel;
NSRect screenRect;

if(CGDisplayCapture(kCGDirectMainDisplay) != kCGErrorSuccess)
{
NSLog(@"Couldn't capture the main display!");
}

windowLevel = CGShieldingWindowLevel();
screenRect = [[NSScreen mainScreen] frame];

[content retain];
[desktopWindow setContentView:nil];

fullScreenWindow = [[IWriteWindow alloc] initWithContentRect:screenRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO screen:[NSScreen mainScreen]];
[fullScreenWindow setContentView:content];
[content release];

[fullScreenWindow makeKeyAndOrderFront:nil];
[fullScreenWindow makeFirstResponder:content];
[fullScreenWindow setLevel:windowLevel];
}
}

- (IBAction)toggleFullScreen:(id)sender {

if([self isFullScreen])
[self exitFullScreen];
else
[self enterFullScreen];
}

- (void)applicationDidFinishLaunching:(NSNotification *) note
{
fullScreen = NO;
fullScreenWindow = nil;
}

@end

SRossi
May 27, 2009, 09:18 AM
If you only need 10.5+ compatibility, just use the new API:


My lecturer was only got 10.4 unfortunately as in why i never went down using the new API.

Although thanks.

Stephen

kainjow
May 27, 2009, 09:23 AM
kainjow> does that give the Quicktime-style full screen transition animation? I guess you could use [view respondsToSelector:@selector(enterFullScreenMode:withOptions:)] to determine whether the 10.5 API is available at runtime?

It doesn't, and although there are options you can pass I didn't see anything related to that effect. Probably would have to use the CGDisplay functions for that I imagine.

respondsToSelector could definitely be used if you need to build for 10.4 but want to use the new API for 10.5+ users, but if you have code that works on 10.4 I would just use that instead.

robbieduncan
May 27, 2009, 09:27 AM
If you want animation in the 10.4 compatible code set the full screen/borderless window to the size/position of the initial window and then call the setFrame:display:animate: (http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSWindow_Class/Reference/Reference.html#//apple_ref/occ/instm/NSWindow/setFrame:display:animate:) method. If your contents are set to auto-size it should look pretty sweet :)

SRossi
May 27, 2009, 10:10 AM
Could that code be implemented into a Cocoa Document based application? If so where would I implement it?

Thanks

Stephen

Thomas Harte
May 27, 2009, 10:18 AM
Oh, yep, got that in the code I have back at home from a few days ago that made me so willing and able to help out here so quickly. It's not identical to Quicktime since in that the viewer frame resizes with the content but fades away as the desktop goes with it, whereas with a CGDisplayCapture the background is just blanked out instantly, but it looks pretty good. And the animation is blocking, for want of a better word, so you don't even have to jump through hoops to figure out when to switch the content view back to the normal window when exiting full screen.

Something else I preferred to the code posted here was to use [[[[desktopWindow screen] deviceDescription] @"NSScreenNumber"] unsignedIntValue] to get the value for CGDisplayCapture rather than always capturing the main screen; it should cause a window to become full screen on whichever display that the majority of it is on. NSScreenNumber still doesn't seem to be in the official docs, but per various resources located by Google has been present since at least 2003. Probably best to include a fallback though.

EDIT: my home code is actually implemented in a multiple document application (as per my thread earlier in the week); I put it straight into my NSDocument derivative, having connected the full screen toggle from the menu bar to the first responder in that .xib, which leads to it being passed all the way down to the frontmost document.

SRossi
May 27, 2009, 10:29 AM
Aww cause I was connecting my toggle full screen menu item to a controller i created with new document files. Which is what arron hillegass done int his book.

But if i connect it to the first responder of mainmenu.xib i will be able to acces the main window?

Thanks

Stephen

Thomas Harte
May 27, 2009, 10:47 AM
Aww cause I was connecting my toggle full screen menu item to a controller i created with new document files. Which is what arron hillegass done int his book.

But if i connect it to the first responder of mainmenu.xib i will be able to acces the main window?
I'm really no expert; I've recently returned to Interface Builder/Xcode after several years of absence and am still a tiny bit lost with the 3.0 rejig. If what I say is contrary to almost any other source, it's probably smarter to trust the other source.

That said, my code does work fine. I'll try to remember to bring it to work (where I have the internet) tomorrow in case this thread is still ongoing.

SRossi
May 27, 2009, 10:52 AM
To be honest Thomas anything that you say I would believe because youve gave nothing but good advice all day :)

If you could do that id be grateful, sorry if im keeping you from your work.

Stephen

SRossi
May 27, 2009, 12:20 PM
Does anyone know how to get to use the NSwindow MyDocument.xib from the menu MainMen.xib.

Would i have to use the first responder to access it or what?

Thanks in advance again

Stephen

robbieduncan
May 28, 2009, 03:04 AM
Does anyone know how to get to use the NSwindow MyDocument.xib from the menu MainMen.xib.

Would i have to use the first responder to access it or what?

Thanks in advance again

Stephen

I'm not sure what you are asking? Normally an action message from a menu item gets passed to the first responder. If it does not respond to that message then the message gets passed down the responder chain. If a document window is the key window then the document object will receive the message.

I'd read this (http://developer.apple.com/documentation/Cocoa/Conceptual/EventOverview/Introduction/Introduction.html) document.

allbrokeup
May 28, 2009, 03:12 AM
To make the Borderless Window become Key (thus activating the Text View) pop in my piece of code from Post #02 into the NSWindow Subclass. If you like I can send you via PM my code to make a Borderless NSWindow in IB have a blurred underlay and be semi transparent. It shows the desktop, but its blurred since the Window is above everything. I'm not publicly releasing the code yet since I have to work out some stuff but it works great already.

Anything else you need, just PM or post here. Sorry for the time-delay. I'm in Australia.

AB

allbrokeup
May 28, 2009, 03:23 AM
For Accessing NSWindows from MyDocument in MainMenu.xib or vice-versa, do the following.


Import this above:

#import "FirstDocumentOutletsAndActionsViewController.h"

the original #import "OriginalDocumentOutletsAndActionsViewController.h" or whatever.

Pop this in an Action:

FirstDocument *firstNib = [[FirstDocument alloc] initWithNibName:@"MainMenu" bundle:[NSBundle mainBundle]];
SecondDocument *secondNib = [[SecondDocument alloc] initWithNibName:@"MyDocument" bundle:[NSBundle mainBundle]];

The above won't do anything by itself. What that does is allows the code in the NSWindow subclass to access the windows/outlets from the other Nib with its Controller.

Such as the following example:

Document 1:
-Window 1
-Controller
--Outlets
---window
---button

Document 2:
-Working Window
-NSWindow Subclass Controller
--Outlets and Actions
---GoFullScreen:
---EndFullScreen:

Xcode:

#import "FullScreenWindow.h"
#import "ControllerFromDocumentOne" //this allows things to be read, but not until you have my sample in.

- (void)awakeFromNib {
FirstDocument *firstNib = [[FirstDocument alloc] initWithNibName:@"MainMenu" bundle:[NSBundle mainBundle]];
SecondDocument *secondNib = [[SecondDocument alloc] initWithNibName:@"MyDocument" bundle:[NSBundle mainBundle]];
//In here, the code reads MyDocument.nib from your compiled App's bundle. Then, somewhere else along in your code you can reference to it or even copy it into the new window/control it from the source files you are working on.
}

- (IBAction)goFullScreen:(id)sender {
//do something here
}

Hope it helps,

AB

SRossi
May 28, 2009, 04:19 AM
Soo I should just post that code at the top of the new file I create to hold the action.

The second part should that be inserted into the .m file?

Here is my code soo far without the implementation.

Thanks

Stephen

Thomas Harte
May 28, 2009, 04:37 AM
As I said, I've been working on what amounts to the identical problem on my home machine (though I use a Mac at both home and work), my Xcode project + source and a separate built version of the application are attached. Just ignore the stuff related to my custom view, i.e. EBGFView.h/.m and SpinningTriangle.h/.m they need quite a bit of work and are not currently even in the model-view-controller paradigm.

As you can see, I've linked my toggle full screen menubar entry (which is command+f since I'll have no real text editing and hence didn't need most of the default edit menu) to the first responder, then devolved all the window swapping stuff (with an attempt at a transition animation and logic to grab whichever display the window is on rather than always the main one if that can be determined) to my NSDocument derivative (in MyDocument.h/.m). That I'm using and subsequently defining a custom view for animated OpenGL content with keyboard input is not really relevant to most of this thread and its current implementation is definitely less than ideal for a whole bunch of reasons.

I guess that if you start a new document based application, you should have a couple of .m files main.m which I've never heard of a reason to change and the NSDocument derivative, which can do all the necessary window switching.

I'll try to take a look at your code later rather than just posting my own completely alternative set.

allbrokeup
May 28, 2009, 04:50 AM
In the action that drives your application to Full Screen. This is because you need to access the window from the other NIB in your source files. You could probably still put the "NSBundle mainBundle" bits in the AwakeFromNib caller, but the other bit you definitely need to put in the Action that drives the app to Full Screen.

Also, you are writing this for college? iWrite, nice name. But if they have used Mac's before now, I would change the UI substantially since it practically mimics TextEdit at the moment.....:D

AB

SRossi
May 28, 2009, 05:32 AM
Thanks people.

Thomas i'lllook over your code when I get home in college the now.

AllBrooke I get what you are meaning now. Illl try and implement it when I get home as my college doesn't have macs.

Yes it is for my lecturer, he said he doesnt mind if its looking like TextEdit as long as the code is diffrent from the one found in the Developer/Examples/AppKit/TextEdit.

Thanks fro all your help so far

Stephen

SRossi
May 28, 2009, 12:39 PM
Right i have now set up my MyDocument.h to look like this:

@interface MyDocument : NSDocument
{
IBOutlet NSTextView *textView;
NSAttributedString *mString;

IBOutlet NSWindow *targetWindow;

BOOL fullScreen;
NSWindow *fullScreenWindow;
}
- (NSAttributedString *)string;
- (void)setString:(NSAttributedString *)value;
@end



And my MyDocument.m to look like this:

@interface IWriteWindow : NSWindow {
}

@end

@implementation IWriteWindow

- (BOOL)canBecomeKeyWindow
{
return YES;
}

@end



@implementation MyDocument

- (id)init
{
self = [super init];
if (self) {

}

if (mString == nil) {
mString =[[NSAttributedString alloc] initWithString:@""];
}

return self;
}

- (NSString *)windowNibName
{
// Override returning the nib file name of the document
// If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
return @"MyDocument";
}

- (void)windowControllerDidLoadNib:(NSWindowController *) aController
{
[super windowControllerDidLoadNib:aController];

fullScreen = NO;
[targetWindow setContentAspectRatio:NSMakeSize(4, 3)];

[textView setRulerVisible:YES];

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *colorAsData;
colorAsData = [defaults objectForKey:BNRTextViewBgColorKey];

[textView setBackgroundColor:[NSKeyedUnarchiver unarchiveObjectWithData:colorAsData]];

NSUserDefaults *textDefaults = [NSUserDefaults standardUserDefaults];
NSData *textColorAsData;
textColorAsData = [textDefaults objectForKey:BNRTextViewTextColorKey];

[textView setTextColor:[NSKeyedUnarchiver unarchiveObjectWithData:textColorAsData]];

if ([self string] != nil) {
[[textView textStorage] setAttributedString:[self string]];
}

}

- (NSRect)getTargetFrameForScreen:(NSScreen *)screen
{
NSRect screenFrame = [screen frame];
int screenWidth = (int)screenFrame.size.width;
int screenHeight = (int)screenFrame.size.height;
int targetWidth, targetHeight;

if (screenWidth * 3 != screenHeight * 4)
{
if (screenWidth * 3 > screenHeight * 4)
{
targetWidth = (screenHeight *4)/3;
targetHeight = screenWidth;
}
}
else
{
targetWidth = screenWidth;
targetHeight = screenHeight;
}

NSRect targetFrmae;
targetFrmae.size.width = targetWidth;
targetFrmae.size.width = targetHeight;
targetFrmae.origin.x = (screenFrame.size.width - targetFrmae.size.width) * 0.5;
targetFrmae.origin.y = (screenFrame.size.height - targetFrmae.size.height) * 0.5;

return targetFrmae;
}

- (void)toggleFullScreen:(NSMenuItem *)menuItem
{
if (!fullScreen)
{
NSScreen *targetScreen = [targetWindow screen];
NSView *content = [targetWindow contentView];

fullScreenWindow = [[IWriteWindow alloc]
initWithContentRect:[targetWindow contentRectForFrameRect:[targetWindow frame]]
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO
screen:targetScreen];

[content retain];
[targetWindow setContentView:nil];
[fullScreenWindow setContentView:content];
[content release];

[fullScreenWindow makeKeyAndOrderFront:nil];
[fullScreenWindow setDelegate:self];

[targetWindow orderOut:nil];

int windowLevel = CGShieldingWindowLevel();
NSNumber *screenNumber = [[[targetWindow screen] deviceDescription] objectForKey:@"NSScreenNumber"];
CGDisplayCapture(screenNumber ? [screenNumber unsignedLongValue] : kCGDirectMainDisplay);
[fullScreenWindow setLevel:windowLevel];

[fullScreenWindow setFrame:[self getTargetFrameForScreen:targetScreen] display:YES animate:YES];

fullScreen = YES;
}
else
{
NSNumber *screenNumber = [[[fullScreenWindow screen] deviceDescription] objectForKey:@"NSScreenNumber"];
CGDisplayRelease(screenNumber ? [screenNumber unsignedLongValue] : kCGDirectMainDisplay);

[fullScreenWindow setFrame:[targetWindow contentRectForFrameRect:[targetWindow frame]] display:YES animate:YES];

NSView *content = [fullScreenWindow contentView];
[content retain];
[fullScreenWindow setContentView:nil];
[targetWindow setContentView:content];
[content release];

[targetWindow makeKeyAndOrderFront:nil];

[fullScreenWindow release];

fullScreenWindow = nil;

fullScreen = NO;
}
}

- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
{
NSData *data;
[self setString:[textView textStorage]];
data = [NSArchiver archivedDataWithRootObject:[self string]];
return data;
}

- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
{
NSAttributedString *tempString = [NSUnarchiver unarchiveObjectWithData:data];
[self setString:tempString];
return YES;
}

- (NSAttributedString *)string
{
return [[mString retain] autorelease];
}

- (void)setString:(NSAttributedString *)newValue
{
if (mString != newValue) {
if (mString) [mString release];
mString = [newValue copy];
}
}

- (void)textDidChange:(NSNotification *)notification
{
[self setString:[textView textStorage]];
}

@end


Now my application will open in fullscreen but the textview disappers after a second and im left with a blank screen any help?

And Thomas thanks soo much for your application code helped me sooo much :)

AllBrooke I couldn't seem to get your code to work perhaps I was implementing it wrong??

Thanks :)

Stephen

GorillaPaws
May 28, 2009, 01:06 PM
Here's a link to a video presentation (http://vimeo.com/4793853) by Aaron Hillegass at the Atlanta CocoaHeads meeting dealing with the text system. It might be helpful if you choose to expand your project. I learned a lot from it myself, so hopefully some of you guys will too.

SRossi
May 28, 2009, 01:46 PM
Aaron Hillegas is a great programmer wish I could go to one of his lectures :(

Thanks for that link helped me understand about attributed strings and so.

Thanks.

Stephen

SRossi
May 29, 2009, 04:26 AM
Does anyone understand why my NSTextView will fade away when i implement the code above?

Any help will be appreciated

Stephen

Thomas Harte
May 29, 2009, 05:16 AM
With respect to my code, you should probably replace or remove getTargetFrameForScreen for my purposes it is supposed to calculate the optimal 4:3 rectangle on a screen, in fact I've neglected to allow for the fact that secondary screens have an origin other than (0, 0), so the code will function incorrectly if you attempt to toggle to full screen any window on a secondary screen.

SRossi
May 29, 2009, 05:25 AM
So what is the frame that I should set for [fullScreenWindow setFrame: ... display:YES animate:YES]??

Thanks

Stephen

EDIT ... Got it I just removed that line and left me with the textView in the middle of the screen :)

Thanks soo much for your help Thomas :)

Stephen

Thomas Harte
May 29, 2009, 06:22 AM
Up to that line, the code should have:

(1) put a shield up on the view containing the majority of the original window;
(2) created a new, borderless window that is above the shield, the same size and in the same position as the content view of the original window;
(3) transferred the content of the original window to the new window;
(4) hidden the original window (which isn't necessary if you have a single screen, but if you have multiple screens then obviously part of the window may still be visible on a different screen).

That line requests an animated transition for the borderless window from its current dimensions to dimensions that fill the screen. I've used that other function, which isn't quite correct, to figure out how to fill as much of the screen as possible while still having the content appear with a 4:3 aspect ratio (you'll notice I also lock the content view of the normal window to 4:3 elsewhere, so you can't scale it to anything other than that aspect ratio).

You could use [targetScreen frame] in place of [self getTargetFrameForScreen:targetScreen] to say "resize to entirely fill the screen, whatever the aspect ratio".

SRossi
May 29, 2009, 06:41 AM
aww now that looks nice with the animation. Thanks soo much for all your help and that.

If you would like I can post up and you can have a look over what I have done or that.

Thnaks

Stephen