Unable to resize NSPanel after initial sizing - resize

I want to resize an NSPanel when a user dismisses an item. I can initially size it perfectly:
[super awakeFromNib];
_mustNotAutoSize=FALSE;
// Make a fully skinned panel
NSPanel *panel = (id)[self window];
[panel setAcceptsMouseMovedEvents:YES];
[panel setLevel:NSPopUpMenuWindowLevel];
[panel setOpaque:NO];
[panel setBackgroundColor:[NSColor clearColor]];
[panel setOpaque:YES];
[panel setBackgroundColor:[NSColor blueColor]];
// Resize panel
NSRect panelRect = [[self window] frame];
int nR=[self numberOfReminders];
float desiredHeight=nR*(52.0)+BORDER_INSET*2+ARROW_HEIGHT+ 22.0;
if(desiredHeight>POPUP_HEIGHT)desiredHeight=POPUP_HEIGHT;
if(desiredHeight<50.0)desiredHeight=50.0;
panelRect.size.height = desiredHeight;
[[self window] setFrame:panelRect display:NO];
But when I reduce the number of items later and call a resizing function, it does not work:
- (void)sizePanelBasedOnReminders
{
NSWindow *panel = [self window];
NSRect panelRect = [panel frame];
NSLog(#"Panel height is starting at: %f",panelRect.size.height);
int nR=[self numberOfReminders];
float desiredHeight=nR*(52.0)+BORDER_INSET*2+ARROW_HEIGHT+ 22.0;
if(desiredHeight>POPUP_HEIGHT)desiredHeight=POPUP_HEIGHT;
if(desiredHeight<BORDER_INSET*2+ARROW_HEIGHT+ 22.0)desiredHeight=BORDER_INSET*2+ARROW_HEIGHT+ 22.0;
panelRect.size.height = desiredHeight;
NSLog(#"Panel height is changing to: %f",panelRect.size.height);
[panel setFrame:panelRect display:YES];
}
Any ideas?
2013-04-12 11:27:47.997 LoveBug[44016:303] Deleted row is: 0
2013-04-12 11:27:47.997 LoveBug[44016:303] Panel height is starting at: 400.000000
2013-04-12 11:27:47.998 LoveBug[44016:303] Numberofitems called, return 6
2013-04-12 11:27:47.998 LoveBug[44016:303] Panel height is changing to: 352.000000
2013-04-12 11:27:48.628 LoveBug[44016:303] Sending 0
2013-04-12 11:27:48.629 LoveBug[44016:303] Deleted row is: 0
2013-04-12 11:27:48.629 LoveBug[44016:303] Panel height is starting at: 352.000000
2013-04-12 11:27:48.630 LoveBug[44016:303] Numberofitems called, return 5
2013-04-12 11:27:48.630 LoveBug[44016:303] Panel height is changing to: 300.000000
2013-04-12 11:27:49.156 LoveBug[44016:303] Sending 0
2013-04-12 11:27:49.156 LoveBug[44016:303] Deleted row is: 0
2013-04-12 11:27:49.157 LoveBug[44016:303] Panel height is starting at: 300.000000
2013-04-12 11:27:49.157 LoveBug[44016:303] Numberofitems called, return 4
2013-04-12 11:27:49.158 LoveBug[44016:303] Panel height is changing to: 248.000000

Related

Objective C : Getting the height and width of a UIView accurately

I having problems getting an accurate reading for heights and widths. So I made this quick and dirty app to test the situation.
Here is the code:
#interface wwfpViewController ()
#property (nonatomic, strong) UIView * box;
#property (nonatomic, strong) UILabel * info;
#end
#implementation wwfpViewController
#synthesize box,info;
- (void)viewDidLoad {
[super viewDidLoad];
box=[[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[box setBackgroundColor:[UIColor darkGrayColor]];
[box setAutoresizesSubviews:YES];
[box setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
info=[[UILabel alloc] initWithFrame:CGRectMake(10, 10, 300, 300)];
[info setTextColor:[UIColor whiteColor]];
[info setBackgroundColor:[UIColor blackColor]];
[info setLineBreakMode:NSLineBreakByWordWrapping];
[info setNumberOfLines:10];
[info setText:#"..."];
[self.view addSubview:box];
[box addSubview:info];
[self updateInfo];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(updateView:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
}
- (void) updateInfo {
CGFloat selfHeight=self.view.frame.size.height;
CGFloat selfWidth=self.view.frame.size.width;
CGFloat boxHeight=box.frame.size.height;
CGFloat boxWidth=box.frame.size.width;
int deviceOrientation=[[UIDevice currentDevice] orientation];
int statusOrientation=[[UIApplication sharedApplication] statusBarOrientation];
NSString * str=[NSString stringWithFormat:#"[height x width] \nself: [%f x %f] \nbox: [%f x %f] \ndevice: %d status: %d",selfHeight,selfWidth,boxHeight,boxWidth,deviceOrientation,statusOrientation];
[info setText:str];
}
- (void) updateView: (NSNotification*) notify {
[self updateInfo];
}
#end
When I test this on an iPad, initially in portrait mode, the info label reports the following:
[height x width]
self: [1004.000000 x 768.000000]
box: [1004.000000 x 768.000000]
device: 0 status: 1
This is correct!
And then when I rotate the iPad to landscape, I get these readings:
[height x width]
self: [768.000000 x 1004.000000]
box: [1004.000000 x 768.000000]
device: 3 status: 3
Actual height x width: 748 x 1024
But when I test this on the iPad when its in landscape orientation, the info label reports:
[height x width]
self: [1024.000000 x 748.000000]
box: [1024.000000 x 748.000000]
device: 0 status: 3
Actual height x width: 748 x 1024
Then when I rotate the iPad to portrait, I get these readings:
[height x width]
self: [748.000000 x 1024.000000]
box: [748.000000 x 1024.000000]
device: 1 status: 1
Actual height x width: 1004 x 768
I rotate it back to landscape and then I get these readings:
[height x width]
self: [768.000000 x 1004.000000]
box: [1004.000000 x 768.000000]
device: 3 status: 3
Actual height x width: 748 x 1024
In all cases the box UIView covers the entire screen, so it is auto adjusting to the orientation changes correctly. These results are consistent from the simulator and testing it on an actual iPad, and I have similar experiences on an iPhone.
After this, I have a few questions:
What am I doing wrong?
Why is the height and width for self.view different from the height and width for box when the two look visually identical?
How can I accurately obtain the overall height and width of the screen or a view, irrespective of orientation changes.
Because [UIDevice ... orientation] reports as zero the first time it is used, should I just ignore it altogether and just stick with [UIApplication ... statusBarOrientation]?
Check the bounds of the views rather than the frame:
CGFloat selfHeight=self.view.bounds.size.height;
CGFloat selfWidth=self.view.bounds.size.width;
CGFloat boxHeight=box.bounds.size.height;
CGFloat boxWidth=box.bounds.size.width;
Also, I would use the UIViewController method for orientation changes and remove the NSNotificationCenter observer.
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[self updateInfo];
}
Finally, the first call to get the correct size should be in viewWillAppear as it will be incorrect in viewDidLoad:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self updateInfo];
}
I tried your code and found one mistake here.
Cause of bug- You didn't make app navigationController based in appdelegate. Set your window's rootViewController to navigationController don't know why but viewController's based view doesn't give the correct frame.
My Opinion- Don't use notification here when you have already a method -(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation which is call after orientation changed. Well You are using notification then NP this is just my opinion.
One more thing I would like to say
box = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
Why don't you simply do
box = [[UIView alloc] initWithFrame:self.view.bounds];
Your Code is okay. Just set your window's rootViewController to navigationController OR tabbarController.
This is Sample Code.
From Apple docs
Discussion When a view’s bounds change, that view automatically
resizes its subviews according to each subview’s autoresizing mask.
You specify the value of this mask by combining the constants
described in UIViewAutoresizing using the C bitwise OR operator.
Combining these constants lets you specify which dimensions of the
view should grow or shrink relative to the superview. The default
value of this property is UIViewAutoresizingNone, which indicates that
the view should not be resized at all.
When more than one option along the same axis is set, the default
behavior is to distribute the size difference proportionally among the
flexible portions. The larger the flexible portion, relative to the
other flexible portions, the more it is likely to grow. For example,
suppose this property includes the UIViewAutoresizingFlexibleWidth and
UIViewAutoresizingFlexibleRightMargin constants but does not include
the UIViewAutoresizingFlexibleLeftMargin constant, thus indicating
that the width of the view’s left margin is fixed but that the view’s
width and right margin may change. Thus, the view appears anchored to
the left side of its superview while both the view width and the gap
to the right of the view increase.
If the autoresizing behaviors do not offer the precise layout that you
need for your views, you can use a custom container view and override
its layoutSubviews method to position your subviews more precisely.
It probably has to do with autoresizing masks read more about it here.
myview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
Working for me
I've made macros vWidth and vHeight that will handle all of this logic properly, with fallbacks:
#define sWidth [[UIScreen mainScreen] bounds].size.width
#define sHeight [[UIScreen mainScreen] bounds].size.height
#define vWidth (\
(^float (void){\
BOOL isClassMethod = [[self class] respondsToSelector:_cmd];\
if (isClassMethod) {\
return sWidth;\
} else {\
float __vWidth = ([self isKindOfClass:[UIViewController class]]?((UIViewController *)self).view.frame.size.width:((UIView *)self).frame.size.width);\
if (!__vWidth) {\
__vWidth = ([self isKindOfClass:[UIViewController class]]?((UIViewController *)self).view.superview.frame.size.width:((UIView *)self).superview.frame.size.width);\
}\
if (!__vWidth) {\
__vWidth = sWidth;\
}\
return __vWidth;\
}\
})()\
)
#define vHeight (\
(^float (void){\
BOOL isClassMethod = [[self class] respondsToSelector:_cmd];\
if (isClassMethod) {\
return sHeight;\
} else {\
float __vHeight = ([self isKindOfClass:[UIViewController class]]?((UIViewController *)self).view.frame.size.height:((UIView *)self).frame.size.height);\
if (!__vHeight) {\
__vHeight = ([self isKindOfClass:[UIViewController class]]?((UIViewController *)self).view.superview.frame.size.height:((UIView *)self).superview.frame.size.height);\
}\
if (!__vHeight) {\
__vHeight = sHeight;\
}\
return __vHeight;\
}\
})()\
)

NSSplitView Fixed Splitter on Window Resize?

I'm having a bit of difficulty getting a NSSplitView to behave itself.
What I have at the moment is:
NSWindow
NSView
NSSplitView
navView <NSView>
contentView <NSView>
The problem I'm having is with the splitter shifting position when I resize the window.
In the split view delegate I've already got:
-(CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMaximumPosition ofSubviewAt:(NSInteger)dividerIndex{
return 200;
}
-(CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMinimumPosition ofSubviewAt:(NSInteger)dividerIndex{
return 200;
}
Despite this the splitter still moved when I resize the window.
if I click ont he splitter, it snaps back to 200px as it should. How can I stop this from moving?
I've tried Autolayout, which is a bit of a nightmare to use, so I've literally disabled it and manually tried to do it with no joy..
Any ideas?
I wrote the above code for Swift and extended it with the possibility to define, whether the left or the right view has to be preferred:
var preferringLeftSideOfSplitView = true
func splitView(splitView: NSSplitView, resizeSubviewsWithOldSize oldSize: NSSize) {
var dividerThickness = splitView.dividerThickness
var leftRect = splitView.subviews[0].frame
var rightRect = splitView.subviews[1].frame
// Resizing and placing the left view
splitView.subviews[0].setFrameOrigin(NSMakePoint(0, 0))
if self.preferringLeftSideOfSplitView == true {
splitView.subviews[0].setFrameSize(NSMakeSize(leftRect.width, splitView.frame.size.height))
} else {
splitView.subviews[0].setFrameSize(NSMakeSize(splitView.frame.size.width - rightRect.width - dividerThickness, splitView.frame.size.height))
}
// Resizing and placing the right view
if self.preferringLeftSideOfSplitView == true {
splitView.subviews[1].setFrameOrigin(NSMakePoint(leftRect.size.width + dividerThickness, 0))
splitView.subviews[1].setFrameSize(NSMakeSize(splitView.frame.size.width - leftRect.size.width - dividerThickness, splitView.frame.size.height))
} else {
splitView.subviews[1].setFrameOrigin(NSMakePoint(splitView.frame.size.width - rightRect.width, 0))
splitView.subviews[1].setFrameSize(NSMakeSize(rightRect.size.width, splitView.frame.size.height))
}
}
I've worked it out...
-(void)splitView:(NSSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize
{
CGFloat dividerThickness = [sender dividerThickness];
NSRect leftRect = [[[sender subviews] objectAtIndex:0] frame];
NSRect rightRect = [[[sender subviews] objectAtIndex:1] frame];
NSRect newFrame = [sender frame];
leftRect.size.height = newFrame.size.height;
leftRect.origin = NSMakePoint(0, 0);
rightRect.size.width = newFrame.size.width - leftRect.size.width
- dividerThickness;
rightRect.size.height = newFrame.size.height;
rightRect.origin.x = leftRect.size.width + dividerThickness;
[[[sender subviews] objectAtIndex:0] setFrame:leftRect];
[[[sender subviews] objectAtIndex:1] setFrame:rightRect];
}
- (BOOL)splitView:(NSSplitView *)aSplitView shouldAdjustSizeOfSubview:(NSView *)subview
{
return subview == rightView;
}
add this to your delegate.
if your NSSplitView would contain lefView and rightView, this keeps leftView at a fixed width, and rightView will resize, when resizing the main window.

NSWindow doesn't respond until click

I've got an image editor window. After drag event I minimize my window to miniature in the bottom left corner, after drop on the miniature I return window back. Above the miniature I change cursor to operationNotAllowedCursor.
The problem is: NSWindow does not change the cursor on miniature after the first draggingEntered (after the second and more everything's fine). Moreover, after drop on the miniature NSWindow does not receive any events until a click on any area of it.
Code for minimizing window (in NSWindow subclass):
-(void)minimize
{
const double miniSize = 240;
MSDraggingMiniature *mini = [[MSDraggingMiniature alloc] init];
[mini setMiniImage:[[MSScreenMaker getInstance] makeEditorScreen:(int)[self windowNumber]]];
_mainContentView = self.contentView;
_oldFrame = [self frame];
[self setStyleMask:NSBorderlessWindowMask];
self.contentView = mini;
NSRect drect = [[self screen] frame];
double width, height;
if (self.frame.size.width < self.frame.size.height) {
height = miniSize;
width = self.frame.size.width / self.frame.size.height * miniSize;
} else {
width = miniSize;
height = self.frame.size.height / self.frame.size.width * miniSize;
}
_anima = MSEditorResizeAnimationMinimize;
[self setFrame:NSMakeRect(drect.origin.x + 20, drect.origin.y + 20 , width, height) display:YES animate:YES];
}
-(void)deminimize
{
self.contentView = _mainContentView;
[self setStyleMask:NSTitledWindowMask];
_anima = MSEditorResizeAnimationDeminimize;
[self setFrame:_oldFrame display:YES animate:YES];
[self makeKeyWindow];
[self makeMainWindow];
}
After lots of variants I found the answer. It seems that area, acting like Dragging Source, must be just NSView, not a subclass of NSButton, which I had.
I rewrote my Dragging Source class - now everything works fine.

cocoa:How to make the icon has been relying on the right?

this window status bar.How to make the icon has been relying on the right ? Resize the window , it automatically to the right .
-(void)composeInterface{
NSView *themeFrame=[[self.window contentView] superview];
NSRect themeFrameRect = [themeFrame frame];
NSRect accessoryViewFrame =[self.statusBarBtn frame];
NSRect newFrame = NSMakeRect(30,
themeFrameRect.size.height - accessoryViewFrame.size.height,
accessoryViewFrame.size.width,
accessoryViewFrame.size.height);
[self.statusBarBtn setFrame:newFrame];
// [self.statusBarBtn setFrameOrigin:NSMakePoint(0, 0)];
// [self.statusBarBtn setAutoresizingMask:323];
[themeFrame addSubview:self.statusBarBtn];
}
If You want that Your icon will be aligned to the right You need to change it's Autosizing to align right. You need to do it like this in Size Inspector :
Or just use -setAutoresizingMask like this:
[self.statusBarBtn setAutoresizingMask:333]; //NOT 323
Furthermore Your newFrame's x possition is set to 30, so the icon will be in the left side.
Change this:
NSRect newFrame = NSMakeRect(30,
themeFrameRect.size.height - accessoryViewFrame.size.height,
accessoryViewFrame.size.width,
accessoryViewFrame.size.height);
To this:
NSRect newFrame = NSMakeRect(themeFrameRect.size.width - accessoryViewFrame.size.width,
themeFrameRect.size.height - accessoryViewFrame.size.height,
accessoryViewFrame.size.width,
accessoryViewFrame.size.height);

Is it possible to draw in the label area of NSToolbar?

I have a NSToolbarItem that uses a view similar to the Xcode status view. It currently has no label, but I can't figure out a way to draw into the area where the item label would normally be drawn. I would like the view to extend into that area just as the Xcode status view does. I know the very bottom portion of pixels of NSToolbar is out of bounds, but I have seen other applications draw into the label area. Any ideas?
Edit: For clarification, this is the status view I'm referring to in Xcode:
I want the bounds of my view to extend past the label area of the toolbar just as the view in Xcode does.
The Xcode status view is not an NSToolbarItem is a custom NSView inserted in the NSToolbar.
If you log
NSLog(#" %#", [[self.window.contentView superview] subviews]);
You will get
NSToolbarView doesn't autoresize it's subviews so you have issues with centering it.
And [self.window.contentView superview] doesn't contain the toolbarview when full screen.
You can add the view you want in the center of the toolbar to the [self.window.contentView superview] when not in fullscreen and position it properly. It will autoresize and stay centered.
When switching to full screen remove it from [self.window.contentView superview] and add it to NSToolbarView in the center that way it stays in the toolbar and it also moves down with the toolbar when you reveal the status bar.
You can get the toolbar view by iterating thru the subviews or with a private method
[[self.window toolbar] performSelector:#selector(_toolbarView)];
Update:
I did a little more digging with the debugger and I found out that this is what Xcode does. At least while not in full screen.
thealch3m1st$ sudo lldb
(lldb) process attach -p 11478
Process 11478 stopped
Executable module set to "/Applications/Xcode.app/Contents/MacOS/Xcode".
Architecture set to: x86_64.
(lldb) po [NSApplication sharedApplication]
(id) $0 = 0x000000040013f5e0 <IDEApplication: 0x40013f5e0>
(lldb) po [$0 mainWindow]
(id) $1 = 0x0000000000000000 <nil>
(lldb) po [$0 windows]
(id) $2 = 0x0000000408278460 <__NSArrayM 0x408278460>(
<IDEWelcomeWindow: 0x40141c1e0>,
<IDEWorkspaceWindow: 0x401ef2780>,
<NSComboBoxWindow: 0x402019be0>,
<NSWindow: 0x4022adc60>,
<IDEOrganizerWindow: 0x402951b20>
)
(lldb) po [$0 windows]
(id) $3 = 0x0000000408820300 <__NSArrayM 0x408820300>(
<IDEWelcomeWindow: 0x40141c1e0>,
<IDEWorkspaceWindow: 0x401ef2780>,
<NSComboBoxWindow: 0x402019be0>,
<NSWindow: 0x4022adc60>,
<IDEOrganizerWindow: 0x402951b20>
)
(lldb) [$3 objectAtIndex:1]
error: '[$3' is not a valid command.
(lldb) po [$3 objectAtIndex:1]
(id) $4 = 0x0000000401ef2780 <IDEWorkspaceWindow: 0x401ef2780>
(lldb) po [$4 contentView]
(id) $5 = 0x0000000401ef0920 <NSView: 0x401ef0920>
(lldb) po [$5 superview]
(id) $6 = 0x0000000401ef2e20 <NSThemeFrame: 0x401ef2e20>
(lldb) po [$6 subviews]
(id) $7 = 0x0000000401ef3800 <__NSArrayM 0x401ef3800>(
<_NSThemeCloseWidget: 0x401ef3120>,
<_NSThemeWidget: 0x401ef3b80>,
<_NSThemeWidget: 0x401ef40e0>,
<NSView: 0x401ef0920>,
<IDEActivityView: 0x4020cd700>,
<_NSThemeFullScreenButton: 0x402017b20>,
(<NSToolbarView: 0x4020192e0>: Xcode.IDEKit.ToolbarDefinition.Workspace),
<DVTDualProxyWindowTitleView: 0x40225e0a0>,
<NSThemeDocumentButton: 0x402698020>
)
(lldb) po [$7 objectAtIndex:4]
(id) $8 = 0x00000004020cd700 <IDEActivityView: 0x4020cd700>
(lldb) [$8 setHidden:YES]
error: '[$8' is not a valid command.
(lldb) po [$8 setHidden:YES]
(id) $9 = 0x0000000000000000 <nil>
(lldb) continue
Process 11478 resuming
(lldb)
And the activity view is gone :)
While in full screen however. It doesn't add it to NSToolbarView it adds it to NSNextStepFrame which is NSToolbarView's superview. The toolbar is not contained in the window's contentview superview when in full screen. I think it has something to do with full screen behavior and spaces.
You have to subclass NSToolbarItem:
- (id)initWithItemIdentifier:(NSString *)itemIdentifier {
self = [super initWithItemIdentifier:itemIdentifier];
if (self) {
self.hideLabel = NO;
}
return self;
}
- (NSView *)view {
NSView *view = [super view];
if (self.hideLabel) {
CGRect frame = view.frame;
frame.size.height = 45.0f;
frame.origin.y = 8.0f;
view.frame = frame;
}
return view;
}
- (NSString *)label {
return self.hideLabel ? #"" : [super label];
}
Create a toolbar:
NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:#"Toolbar"];
toolbar.delegate = self;
self.window.toolbar = toolbar;
Use NSToolbarDelegate to fill your toolbar with items:
- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar {
return [NSArray arrayWithObjects:#"Button", #"LCD", NSToolbarFlexibleSpaceItemIdentifier, NSToolbarSpaceItemIdentifier, nil];
}
- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar {
return [NSArray arrayWithObjects:#"Button", NSToolbarFlexibleSpaceItemIdentifier, #"LCD", NSToolbarFlexibleSpaceItemIdentifier, NSToolbarSpaceItemIdentifier, nil];
}
- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag {
MyToolbarItem *item = [[MyToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
if ([itemIdentifier isEqualToString:#"LCD"]) {
item.view = self.lcdView;
item.hideLabel = YES;
} else if ([itemIdentifier isEqualToString:#"Button"]) {
item.label = NSLocalizedString(#"Button", nil);
item.image = [NSImage imageNamed:#"Button"];
item.hideLabel = NO;
}
return item;
}
The lcd view should be (in this case) 32 points high before you hand it over to the toolbar item. If it's bigger, the toolbar will be too high.
The Xcode status view is actually a separate window floating over the toolbar. (This is easily tested: press ⇧⌘4 and press space to take a screen shot of a window, and hover the mouse over it.)
This code installs a window floating on top of the toolbar.
-(void)applicationWillFinishLaunching:(NSNotification *)aNotification {
NSRect winframe = [self.window frame];
NSRect viewrect = NSMakeRect(0, 0, 400, 50);
NSRect winrect = viewrect;
winrect.origin.x = NSMidX(winframe) - NSMidX(winrect);
winrect.origin.y = NSHeight(winframe) - NSHeight(winrect) - 18;
NSWindow* win = [[[NSWindow alloc] initWithContentRect:winrect styleMask: NSBorderlessWindowMask backing: NSBackingStoreBuffered defer: NO] autorelease];
[win setBackgroundColor:[NSColor clearColor]];
[win setOpaque:NO];
[win setIgnoresMouseEvents:YES];
MyStatusView* v = [[[MyStatusView alloc] initWithFrame:viewrect] autorelease];
[win setContentView: v];
[self.window addChildWindow:win ordered:NSWindowAbove];
}
The iTunes-XCode-LCD that extends in the label area is not a NSToolbarItem. Since NSToolbar isn't a NSView, you cannot add a subview to a NSToolbar instance.
But you can add a custom view directly in the window frame, that can be accessed through the contentView.superview property path of the NSWindow instance!
I.e. make your own subclass of NSWindowController and put some code like this in the 'windowDidLoad' method:
- (void)windowDidLoad
{
[super windowDidLoad];
NSImage *image = [NSImage imageNamed:#"lcd"];
NSRect lcdFrameRect = NSMakeRect(self.window.frame.size.width / 2 - image.size.width/2, self.window.frame.size.height - image.size.height - 20,
image.size.width, image.size.height);
NSImageView *lcdView = [[NSImageView alloc] initWithFrame: lcdFrameRect];
[lcdView setImage: image];
lcdView.autoresizingMask = NSViewMinYMargin | NSViewMinXMargin | NSViewMaxXMargin;
NSView * contentView = self.window.contentView;
[contentView.superview addSubview: lcdView];
}
This code will not work in Lion's full-screen mode, since the frame window isn't drawn when in fullscreen. To fix this, the view can be moved in a floating window, child of the main one (just check the NSWindow addChildWindow:ordered: method).