1999-06-20 10:13:34 +00:00
|
|
|
|
|
|
|
#include <AppKit/NSColor.h>
|
1999-06-21 06:43:31 +00:00
|
|
|
#include <AppKit/NSFont.h>
|
|
|
|
#include <AppKit/NSGraphics.h>
|
1999-06-20 10:13:34 +00:00
|
|
|
#include <AppKit/NSImage.h>
|
1999-06-19 11:44:32 +00:00
|
|
|
#include <AppKit/NSTabView.h>
|
1999-06-21 01:02:53 +00:00
|
|
|
#include <AppKit/NSTabViewItem.h>
|
1999-06-20 10:13:34 +00:00
|
|
|
#include <AppKit/PSOperators.h>
|
1999-06-19 11:44:32 +00:00
|
|
|
|
|
|
|
@implementation NSTabView
|
|
|
|
- (id)initWithFrame:(NSRect)rect
|
|
|
|
{
|
|
|
|
[super initWithFrame:rect];
|
|
|
|
|
|
|
|
// setup variables
|
|
|
|
|
|
|
|
tab_items = [NSMutableArray new];
|
1999-06-20 10:13:34 +00:00
|
|
|
tab_font = [NSFont systemFontOfSize:12];
|
1999-07-09 21:04:00 +00:00
|
|
|
tab_selected = nil;
|
1999-06-19 11:44:32 +00:00
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
// tab management.
|
|
|
|
|
|
|
|
- (void)addTabViewItem:(NSTabViewItem *)tabViewItem
|
|
|
|
{
|
1999-06-20 10:13:34 +00:00
|
|
|
[tabViewItem _setTabView:self];
|
1999-06-19 11:44:32 +00:00
|
|
|
[tab_items insertObject:tabViewItem atIndex:[tab_items count]];
|
1999-07-26 06:44:26 +00:00
|
|
|
|
|
|
|
if ([tab_delegate respondsToSelector:
|
|
|
|
@selector(tabViewDidChangeNumberOfTabViewItems:)])
|
|
|
|
{
|
|
|
|
[tab_delegate tabViewDidChangeNumberOfTabViewItems:self];
|
|
|
|
}
|
1999-06-19 11:44:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)insertTabViewItem:(NSTabViewItem *)tabViewItem
|
|
|
|
atIndex:(int)index
|
|
|
|
{
|
1999-06-20 10:13:34 +00:00
|
|
|
[tabViewItem _setTabView:self];
|
1999-06-19 11:44:32 +00:00
|
|
|
[tab_items insertObject:tabViewItem atIndex:index];
|
1999-07-26 06:44:26 +00:00
|
|
|
|
|
|
|
if ([tab_delegate respondsToSelector:
|
|
|
|
@selector(tabViewDidChangeNumberOfTabViewItems:)])
|
|
|
|
{
|
|
|
|
[tab_delegate tabViewDidChangeNumberOfTabViewItems:self];
|
|
|
|
}
|
1999-06-19 11:44:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)removeTabViewItem:(NSTabViewItem *)tabViewItem
|
|
|
|
{
|
|
|
|
int i = [tab_items indexOfObject:tabViewItem];
|
|
|
|
|
|
|
|
if (i == -1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
[tab_items removeObjectAtIndex:i];
|
1999-07-26 06:44:26 +00:00
|
|
|
|
|
|
|
if ([tab_delegate respondsToSelector:
|
|
|
|
@selector(tabViewDidChangeNumberOfTabViewItems:)])
|
|
|
|
{
|
|
|
|
[tab_delegate tabViewDidChangeNumberOfTabViewItems:self];
|
|
|
|
}
|
1999-06-19 11:44:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (int)indexOfTabViewItem:(NSTabViewItem *)tabViewItem
|
|
|
|
{
|
|
|
|
return [tab_items indexOfObject:tabViewItem];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (int)indexOfTabViewItemWithIdentifier:(id)identifier
|
|
|
|
{
|
1999-07-26 06:44:26 +00:00
|
|
|
int howMany = [tab_items count];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i=0;i<howMany;i++)
|
|
|
|
{
|
|
|
|
id anItem = [tab_items objectAtIndex:i];
|
|
|
|
|
|
|
|
if ([[anItem identifier] isEqual:identifier])
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
return NSNotFound;
|
1999-06-19 11:44:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (int)numberOfTabViewItems
|
|
|
|
{
|
|
|
|
return [tab_items count];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSTabViewItem *)tabViewItemAtIndex:(int)index
|
|
|
|
{
|
|
|
|
return [tab_items objectAtIndex:index];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *)tabViewItems
|
|
|
|
{
|
|
|
|
return (NSArray *)tab_items;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)selectFirstTabViewItem:(id)sender
|
|
|
|
{
|
|
|
|
[self selectTabViewItemAtIndex:0];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)selectLastTabViewItem:(id)sender
|
|
|
|
{
|
|
|
|
[self selectTabViewItem:[tab_items lastObject]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)selectNextTabViewItem:(id)sender
|
|
|
|
{
|
|
|
|
[self selectTabViewItemAtIndex:tab_selected_item+1];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)selectPreviousTabViewItem:(id)sender
|
|
|
|
{
|
|
|
|
[self selectTabViewItemAtIndex:tab_selected_item-1];
|
|
|
|
}
|
|
|
|
|
1999-07-26 06:44:26 +00:00
|
|
|
- (NSTabViewItem *)selectedTabViewItem
|
|
|
|
{
|
|
|
|
return [tab_items objectAtIndex:tab_selected_item];
|
|
|
|
}
|
|
|
|
|
1999-06-19 11:44:32 +00:00
|
|
|
- (void)selectTabViewItem:(NSTabViewItem *)tabViewItem
|
|
|
|
{
|
1999-07-26 06:44:26 +00:00
|
|
|
BOOL canSelect = YES;
|
|
|
|
|
|
|
|
if ([tab_delegate respondsToSelector:
|
|
|
|
@selector(tabView:shouldSelectTabViewItem:)])
|
|
|
|
{
|
|
|
|
canSelect = [tab_delegate tabView:self
|
|
|
|
shouldSelectTabViewItem:tabViewItem];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (canSelect)
|
|
|
|
{
|
|
|
|
if (tab_selected)
|
|
|
|
{
|
|
|
|
[tab_selected _setTabState:NSBackgroundTab];
|
|
|
|
if ([tab_selected view])
|
|
|
|
[[tab_selected view] removeFromSuperview];
|
|
|
|
}
|
|
|
|
|
|
|
|
tab_selected = tabViewItem;
|
|
|
|
|
|
|
|
if ([tab_delegate respondsToSelector:
|
|
|
|
@selector(tabView:willSelectTabViewItem:)])
|
|
|
|
{
|
|
|
|
[tab_delegate tabView:self willSelectTabViewItem:tab_selected];
|
|
|
|
}
|
|
|
|
|
|
|
|
[tab_selected _setTabState:NSSelectedTab];
|
|
|
|
if ([tab_selected view])
|
|
|
|
[self addSubview:[tab_selected view]];
|
|
|
|
|
|
|
|
if ([tab_delegate respondsToSelector:
|
|
|
|
@selector(tabView:didSelectTabViewItem:)])
|
|
|
|
{
|
|
|
|
[tab_delegate tabView:self didSelectTabViewItem:tab_selected];
|
|
|
|
}
|
|
|
|
}
|
1999-06-19 11:44:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)selectTabViewItemAtIndex:(int)index
|
|
|
|
{
|
1999-07-26 06:44:26 +00:00
|
|
|
[self selectTabViewItem:[tab_items objectAtIndex:index]];
|
1999-06-19 11:44:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)takeSelectedTabViewItemFromSender:(id)sender
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setFont:(NSFont *)font
|
|
|
|
{
|
|
|
|
ASSIGN(tab_font, font);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSFont *)font
|
|
|
|
{
|
|
|
|
return tab_font;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setTabViewType:(NSTabViewType)tabViewType
|
|
|
|
{
|
|
|
|
tab_type = tabViewType;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSTabViewType)tabViewType
|
|
|
|
{
|
|
|
|
return tab_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setDrawsBackground:(BOOL)flag
|
|
|
|
{
|
|
|
|
tab_draws_background = flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) drawsBackground
|
|
|
|
{
|
|
|
|
return tab_draws_background;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setAllowsTruncatedLabels:(BOOL)allowTruncatedLabels
|
|
|
|
{
|
|
|
|
tab_truncated_label = allowTruncatedLabels;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)allowsTruncatedLabels
|
|
|
|
{
|
|
|
|
return tab_truncated_label;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setDelegate:(id)anObject
|
|
|
|
{
|
1999-07-26 06:44:26 +00:00
|
|
|
tab_delegate = anObject;
|
1999-06-19 11:44:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (id)delegate
|
|
|
|
{
|
|
|
|
return tab_delegate;
|
|
|
|
}
|
|
|
|
|
|
|
|
// content and size
|
|
|
|
|
|
|
|
- (NSSize)minimumSize
|
|
|
|
{
|
|
|
|
return NSZeroSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSRect)contentRect
|
|
|
|
{
|
1999-07-10 01:49:18 +00:00
|
|
|
NSRect cRect = [self frame];
|
|
|
|
|
|
|
|
cRect.origin.x = 2;
|
|
|
|
cRect.origin.y = 2;
|
|
|
|
cRect.size.height -= 4;
|
|
|
|
cRect.size.width -= 4;
|
|
|
|
|
|
|
|
cRect.size.height -= 21;
|
|
|
|
|
|
|
|
return cRect;
|
1999-06-19 11:44:32 +00:00
|
|
|
}
|
|
|
|
|
1999-06-20 10:13:34 +00:00
|
|
|
// Drawing.
|
|
|
|
|
|
|
|
- (void)drawRect:(NSRect)rect
|
|
|
|
{
|
|
|
|
NSGraphicsContext *ctxt = GSCurrentContext();
|
|
|
|
float borderThickness;
|
|
|
|
int howMany = [tab_items count];
|
1999-06-21 01:02:53 +00:00
|
|
|
int i;
|
|
|
|
NSRect previousRect;
|
1999-07-26 06:44:26 +00:00
|
|
|
int previousState = 0;
|
1999-06-20 10:13:34 +00:00
|
|
|
|
|
|
|
DPSgsave(ctxt);
|
|
|
|
|
|
|
|
switch (tab_type) {
|
|
|
|
case NSTopTabsBezelBorder:
|
|
|
|
rect.size.height -= 20;
|
|
|
|
NSDrawButton(rect, rect);
|
|
|
|
borderThickness = 2;
|
|
|
|
break;
|
|
|
|
case NSNoTabsBezelBorder:
|
|
|
|
NSDrawButton(rect, rect);
|
|
|
|
borderThickness = 2;
|
|
|
|
break;
|
|
|
|
case NSNoTabsLineBorder:
|
|
|
|
NSFrameRect(rect);
|
|
|
|
borderThickness = 1;
|
|
|
|
break;
|
|
|
|
case NSNoTabsNoBorder:
|
|
|
|
borderThickness = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
1999-06-21 01:02:53 +00:00
|
|
|
for (i=0;i<howMany;i++) {
|
|
|
|
// where da tab be at?
|
|
|
|
NSSize s;
|
|
|
|
NSRect r;
|
|
|
|
NSPoint iP;
|
|
|
|
NSTabViewItem *anItem = [tab_items objectAtIndex:i];
|
|
|
|
NSTabState itemState;
|
|
|
|
|
|
|
|
itemState = [anItem tabState];
|
|
|
|
|
|
|
|
s = [anItem sizeOfLabel:NO];
|
|
|
|
|
|
|
|
if (i == 0) {
|
|
|
|
|
|
|
|
iP.x = rect.origin.x;
|
|
|
|
iP.y = rect.size.height;
|
|
|
|
|
1999-07-09 22:35:13 +00:00
|
|
|
if (itemState == NSSelectedTab) {
|
|
|
|
iP.y -= 1;
|
|
|
|
[[NSImage imageNamed:@"common_TabSelectedLeft.tiff"]
|
1999-06-21 01:02:53 +00:00
|
|
|
compositeToPoint:iP operation: NSCompositeSourceOver];
|
1999-07-09 22:35:13 +00:00
|
|
|
}
|
1999-06-21 01:02:53 +00:00
|
|
|
else if (itemState == NSBackgroundTab)
|
|
|
|
[[NSImage imageNamed:@"common_TabUnSelectedLeft.tiff"]
|
|
|
|
compositeToPoint:iP operation: NSCompositeSourceOver];
|
|
|
|
else
|
|
|
|
NSLog(@"Not finished yet. Luff ya.\n");
|
|
|
|
|
|
|
|
r.origin.x = rect.origin.x + 13;
|
|
|
|
r.origin.y = rect.size.height;
|
|
|
|
r.size.width = s.width;
|
1999-06-23 23:27:16 +00:00
|
|
|
r.size.height = 15;
|
|
|
|
|
|
|
|
DPSsetlinewidth(ctxt,1);
|
|
|
|
DPSsetgray(ctxt,1);
|
|
|
|
DPSmoveto(ctxt, r.origin.x, r.origin.y+16);
|
|
|
|
DPSrlineto(ctxt, r.size.width, 0);
|
|
|
|
DPSstroke(ctxt);
|
1999-06-21 01:02:53 +00:00
|
|
|
|
|
|
|
[anItem drawLabel:NO inRect:r];
|
|
|
|
|
|
|
|
previousRect = r;
|
|
|
|
previousState = itemState;
|
|
|
|
} else {
|
|
|
|
iP.x = previousRect.origin.x + previousRect.size.width;
|
|
|
|
iP.y = rect.size.height;
|
|
|
|
|
|
|
|
if (itemState == NSSelectedTab) {
|
|
|
|
iP.y -= 1;
|
|
|
|
[[NSImage imageNamed:@"common_TabUnSelectToSelectedJunction.tiff"]
|
|
|
|
compositeToPoint:iP operation: NSCompositeSourceOver];
|
|
|
|
}
|
|
|
|
else if (itemState == NSBackgroundTab) {
|
|
|
|
if (previousState == NSSelectedTab) {
|
|
|
|
iP.y -= 1;
|
|
|
|
[[NSImage imageNamed:@"common_TabSelectedToUnSelectedJunction.tiff"]
|
|
|
|
compositeToPoint:iP operation: NSCompositeSourceOver];
|
|
|
|
iP.y += 1;
|
|
|
|
} else {
|
|
|
|
[[NSImage imageNamed:@"common_TabUnSelectedJunction.tiff"]
|
|
|
|
compositeToPoint:iP operation: NSCompositeSourceOver];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
NSLog(@"Not finished yet. Luff ya.\n");
|
|
|
|
|
|
|
|
r.origin.x = iP.x + 13;
|
|
|
|
r.origin.y = rect.size.height;
|
|
|
|
r.size.width = s.width;
|
1999-06-23 23:27:16 +00:00
|
|
|
r.size.height = 15;
|
|
|
|
|
|
|
|
DPSsetlinewidth(ctxt,1);
|
|
|
|
DPSsetgray(ctxt,1);
|
|
|
|
DPSmoveto(ctxt, r.origin.x, r.origin.y+16);
|
|
|
|
DPSrlineto(ctxt, r.size.width, 0);
|
|
|
|
DPSstroke(ctxt);
|
1999-06-21 01:02:53 +00:00
|
|
|
|
|
|
|
[anItem drawLabel:NO inRect:r];
|
|
|
|
|
|
|
|
previousRect = r;
|
|
|
|
previousState = itemState;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == howMany-1) {
|
|
|
|
iP.x += s.width + 13;
|
|
|
|
|
|
|
|
if ([anItem tabState] == NSSelectedTab)
|
|
|
|
[[NSImage imageNamed:@"common_TabSelectedRight.tiff"]
|
|
|
|
compositeToPoint:iP operation: NSCompositeSourceOver];
|
|
|
|
else if ([anItem tabState] == NSBackgroundTab)
|
|
|
|
[[NSImage imageNamed:@"common_TabUnSelectedRight.tiff"]
|
|
|
|
compositeToPoint:iP operation: NSCompositeSourceOver];
|
|
|
|
else
|
|
|
|
NSLog(@"Not finished yet. Luff ya.\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-06-20 10:13:34 +00:00
|
|
|
DPSgrestore(ctxt);
|
|
|
|
}
|
|
|
|
|
1999-06-19 11:44:32 +00:00
|
|
|
// Event handling.
|
|
|
|
|
|
|
|
- (NSTabViewItem *)tabViewItemAtPoint:(NSPoint)point
|
|
|
|
{
|
1999-07-09 21:04:00 +00:00
|
|
|
int howMany = [tab_items count];
|
|
|
|
int i;
|
|
|
|
|
1999-07-10 01:09:40 +00:00
|
|
|
point = [self convertPoint:point fromView:nil];
|
|
|
|
|
1999-07-09 21:04:00 +00:00
|
|
|
for (i=0;i<howMany;i++) {
|
|
|
|
NSTabViewItem *anItem = [tab_items objectAtIndex:i];
|
|
|
|
|
|
|
|
if(NSPointInRect(point,[anItem _tabRect]))
|
|
|
|
return anItem;
|
|
|
|
}
|
|
|
|
|
1999-06-19 11:44:32 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
1999-06-21 01:53:43 +00:00
|
|
|
- (NSView*) hitTest: (NSPoint)aPoint
|
1999-06-21 02:16:37 +00:00
|
|
|
{
|
1999-07-09 21:04:00 +00:00
|
|
|
NSTabViewItem *anItem = [self tabViewItemAtPoint:aPoint];
|
|
|
|
|
1999-07-26 06:44:26 +00:00
|
|
|
if (anItem && ![anItem isEqual:tab_selected])
|
|
|
|
{
|
|
|
|
[self selectTabViewItem:anItem];
|
1999-07-10 01:49:18 +00:00
|
|
|
}
|
1999-07-09 21:04:00 +00:00
|
|
|
|
|
|
|
[self setNeedsDisplay:YES];
|
|
|
|
|
|
|
|
return [super hitTest:aPoint];
|
1999-06-21 02:16:37 +00:00
|
|
|
}
|
1999-06-21 01:53:43 +00:00
|
|
|
|
1999-06-19 11:44:32 +00:00
|
|
|
// Coding.
|
|
|
|
|
|
|
|
- (void) encodeWithCoder: (NSCoder*)aCoder
|
|
|
|
{
|
|
|
|
[super encodeWithCoder: aCoder];
|
|
|
|
|
|
|
|
[aCoder encodeObject:tab_items];
|
|
|
|
[aCoder encodeObject:tab_font];
|
|
|
|
[aCoder encodeValueOfObjCType: @encode(NSTabViewType) at: &tab_type];
|
|
|
|
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &tab_draws_background];
|
|
|
|
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &tab_truncated_label];
|
|
|
|
[aCoder encodeObject:tab_delegate];
|
|
|
|
[aCoder encodeValueOfObjCType: "i" at: &tab_selected_item];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithCoder: (NSCoder*)aDecoder
|
|
|
|
{
|
|
|
|
[super initWithCoder: aDecoder];
|
|
|
|
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(id) at: &tab_items];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(id) at: &tab_font];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(NSTabViewType) at:&tab_type];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &tab_draws_background];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &tab_truncated_label];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(id) at: &tab_delegate];
|
|
|
|
[aDecoder decodeValueOfObjCType: "i" at: &tab_selected_item];
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
@end
|