Here’s a tutorial on how to create a custom class to make any IB window a titleless one. I’ve modified code from this page (mostly originally from apple’s RoundTransparentWindow sample project, which is not supplied with xcode). I found it difficult at first to know what to do with all the bit’s an pieces, so I hope this clarifies the parts and process of getting this type of obj-c job done. I’ve written this as I created a new project, so it does work.
-
Create an applescript project.
-
Open your mainMenu.nib file, and create the window you wish to be displayed without a title. This can be an existing window, too
-
Click on your window, and then click on “Classes” in the “MainMenu.nib” window. You’ll see a hierarchical list of NS objects… NSWindow should be highlighted. If it isn’t, navigate through NSObject>NSResponder>NSWindow.
-
Click on the “Classes” menu in the IB main menu, and select “Subclass NSWindow”. A new subclass will appear to the right of NSWindow. Name it “CustomWindow”. With the new ‘CustomWindow’ subclass highlighted, click on the “Classes” main menu again, and select “Create Files for CustomWindow”. Make sure it intends to save “CustomWindow.h” and “Custom Window.m”, and then click “Choose” to create the cocoa files.
-
Select your window, and go to the “Custom Class” pane in the info window. You should see “CustomWindow” as an option. Select it, and save your interface.
-
Determine whether you want the user to be able to move the window.
-
Open “CustomWindow.h”. If you want to be able to position the window programatically and NOT allow the user to move it, do nothing. If you want to enable moving/dragging of the window, add the line:
NSPoint initialLocation;
… between the {} brackets. The file should look something like this…
[code]/* CustomWindow */
#import <Cocoa/Cocoa.h>
@interface CustomWindow : NSWindow
{
NSPoint initialLocation;
}
@end[/code]
8 ) Open “CustomWindow.m”. Read through the commends carefully for this file, as they state what each part does, and whether it’s necessary for making the window draggable.
[code]#import “CustomWindow.h”
#import <AppKit/AppKit.h>
@implementation CustomWindow
// This line initializes any window connected to the CustomWindow class as titleless…overriding the default AppKit init method.
-
(id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag {
// Call the NSWindow method to instantiate the window, but add the borderless mask to make it titleless
// Sets ‘result’ as a variable reference to the new window object
NSWindow* result = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
// Set the background color to clear so that (along with the setOpaque call below) we can see through the parts of the window that we’re not drawing into
// If you want to have a window with a non-rectangular shape, un-comment the next line.
//[result setBackgroundColor: [NSColor clearColor]];
// Note: You’ll need to provide an image in an image view in the window that will server as your ‘window’, otherwise the window will just be invisible.
// The next line makes the window float on top of all other windows. Uncomment it if you wish the window to remain on top of ALL other windows.
//[result setLevel: NSStatusWindowLevel];
// Note: this is useful for startup screens or other utility windows that only you should control
// Control the transparency of the entire window. 0 is totally transparent… 1 is totally opaque.
[result setAlphaValue:1.0];
// Control Opaqueness. Leave “YES” to make it a “normal” window.
// Set to “NO”, and use in conjunction with the ‘clearColor’ background color above to make a window with a custom graphic shape.
[result setOpaque:YES];
// Does the window has a shadow?
[result setHasShadow: YES];
// Automatically center the window? Position will be handled as any normal xcode window would be if this is not used.
//[result center];
return result;
}
// Custom windows that use the NSBorderlessWindowMask can’t become key by default. Therefore, controls in such windows
// won’t ever be enabled by default. Thus, we override this method to change that.
- (BOOL) canBecomeKeyWindow
{
return YES;
}
// IMPORTANT //
// Everything below here (except the “@end” at the end
can be omitted if you are not allowing dragging of the window.
// Make sure the “CustomWindow.h” file has the single line mentioned above if you ARE going to implement dragging.
// This code implements dragging of the window manually, because borderless windows can not be dragged by default.
-
(void)mouseDragged:(NSEvent *)theEvent
{
NSPoint currentLocation;
NSPoint newOrigin;
NSRect screenFrame = [[NSScreen mainScreen] frame];
NSRect windowFrame = [self frame];
currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
newOrigin.x = currentLocation.x - initialLocation.x;
newOrigin.y = currentLocation.y - initialLocation.y;
if( (newOrigin.y+windowFrame.size.height) > (screenFrame.origin.y+screenFrame.size.height) ){
newOrigin.y=screenFrame.origin.y + (screenFrame.size.height-windowFrame.size.height);
}
[self setFrameOrigin:newOrigin];
}
// Get the intital mouse location
-
(void)mouseDown:(NSEvent *)theEvent
{
NSRect windowFrame = [self frame];
initialLocation = [self convertBaseToScreen:[theEvent locationInWindow]];
initialLocation.x -= windowFrame.origin.x;
initialLocation.y -= windowFrame.origin.y;
}
// Don’t delete this last line by accident!!! //
@end[/code]
9) Build and run your application. You should have a titleless window.
The windows initialized using this setup respond to pretty much all normal applescript studio commands. The custom class just replaces the default values supplied by the appkit with the new ones making it conform to our needs. You obviously can’t click on the close button or other title bar buttons, so you must manually provide a mechanism for closing the window, etc. If enabled, the entire window is the draggable portion. You can drag the window from any part of the window as you would in the title bar of a normal window.
Good luck, and have fun…
j