зеркало из https://github.com/mozilla/gecko-dev.git
remove 16-tab limit. add overflow menu (chevron). bug 261134
This commit is contained in:
Родитель
58e0659db2
Коммит
ee2dfe111b
|
@ -1692,6 +1692,7 @@
|
|||
E010866D06BCA2E500BD5DE0,
|
||||
E010866E06BCA2E500BD5DE0,
|
||||
E010866F06BCA2E500BD5DE0,
|
||||
3FF71AE00710A6800081B5D7,
|
||||
);
|
||||
isa = PBXResourcesBuildPhase;
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -5625,6 +5626,7 @@
|
|||
E010867406BCA2E500BD5DE0,
|
||||
E010867506BCA2E500BD5DE0,
|
||||
E010867606BCA2E500BD5DE0,
|
||||
3FF71AE10710A6800081B5D7,
|
||||
);
|
||||
isa = PBXResourcesBuildPhase;
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -9216,6 +9218,26 @@
|
|||
settings = {
|
||||
};
|
||||
};
|
||||
3FF71ADF0710A67F0081B5D7 = {
|
||||
isa = PBXFileReference;
|
||||
lastKnownFileType = image.tiff;
|
||||
name = tab_overflow.tif;
|
||||
path = resources/images/chrome/tab_overflow.tif;
|
||||
refType = 2;
|
||||
sourceTree = SOURCE_ROOT;
|
||||
};
|
||||
3FF71AE00710A6800081B5D7 = {
|
||||
fileRef = 3FF71ADF0710A67F0081B5D7;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
3FF71AE10710A6800081B5D7 = {
|
||||
fileRef = 3FF71ADF0710A67F0081B5D7;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
//3F0
|
||||
//3F1
|
||||
//3F2
|
||||
|
@ -10002,6 +10024,7 @@
|
|||
3FF08F1206E7D3C2001C9B19,
|
||||
3FF08F1306E7D3C2001C9B19,
|
||||
3FF08F1406E7D3C2001C9B19,
|
||||
3FF71ADF0710A67F0081B5D7,
|
||||
E091C0D006225EA3007D9E8F,
|
||||
F540BD1A029ED15301026D5D,
|
||||
F540BD1C029ED17901026D5D,
|
||||
|
|
Двоичный файл не отображается.
|
@ -47,19 +47,25 @@
|
|||
IBOutlet BrowserTabView *mTabView;
|
||||
|
||||
TabButtonCell *mActiveTabButton; // active tab button, mainly useful for handling drags (STRONG)
|
||||
NSButton *mOverflowButton; // button for overflow menu if we've got more tabs than space (STRONG)
|
||||
NSMenu *mOverflowMenu; // menu for tab overflow (STRONG);
|
||||
|
||||
// drag tracking
|
||||
NSPoint mLastClickPoint;
|
||||
BOOL mDragStarted;
|
||||
NSView *mDragDest;
|
||||
TabButtonCell *mDragDestButton;
|
||||
|
||||
BOOL mOverflowTabs;
|
||||
NSMutableArray *mTrackingCells; // cells which currently have tracking rects in this view
|
||||
}
|
||||
|
||||
// destroy the tab bar and recreate it from the tabview
|
||||
-(void)rebuildTabBar;
|
||||
// return the height the tab bar should be
|
||||
-(float)tabBarHeight;
|
||||
-(BrowserTabViewItem*)tabViewItemAtPoint:(NSPoint)location;
|
||||
- (void)windowClosed;
|
||||
- (IBAction)overflowMenu:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -47,25 +47,34 @@
|
|||
-(TabButtonCell*)buttonAtPoint:(NSPoint)clickPoint;
|
||||
-(void)registerTabButtonsForTracking;
|
||||
-(void)unregisterTabButtonsForTracking;
|
||||
-(void)initOverflowMenu;
|
||||
-(NSRect)tabsRect;
|
||||
@end
|
||||
|
||||
static NSImage *gBackgroundImage = nil;
|
||||
static NSImage *gTabButtonDividerImage = nil;
|
||||
static NSImage *gTabOverflowImage = nil;
|
||||
static const float kTabBarDefaultHeight = 22.0;
|
||||
|
||||
@implementation BrowserTabBarView
|
||||
|
||||
static const int kTabBarMargin = 5; // left/right margin for tab bar
|
||||
static const float kMinTabWidth = 42.0; // tabs smaller than this are useless... tabs this small may be useless
|
||||
static const float kMinTabWidth = 100.0; // the smallest tabs that will be drawn
|
||||
static const float kMaxTabWidth = 175.0; // the widest tabs that will be drawn
|
||||
|
||||
static const int kTabDragThreshold = 3; // distance a drag must go before we start dnd
|
||||
|
||||
static const float kOverflowButtonWidth = 16;
|
||||
static const float kOverflowButtonHeight = 16;
|
||||
static const int kOverflowButtonMargin = 1;
|
||||
|
||||
-(id)initWithFrame:(NSRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
mActiveTabButton = nil;
|
||||
mOverflowButton = nil;
|
||||
mOverflowTabs = NO;
|
||||
// this will not likely have any result here
|
||||
[self rebuildTabBar];
|
||||
[self registerForDraggedTypes:[NSArray arrayWithObjects: @"MozURLType", @"MozBookmarkType", NSStringPboardType,
|
||||
|
@ -82,7 +91,10 @@ static const int kTabDragThreshold = 3; // distance a drag must go before we s
|
|||
|
||||
-(void)dealloc
|
||||
{
|
||||
[mTrackingCells release];
|
||||
[mActiveTabButton release];
|
||||
[mOverflowButton release];
|
||||
[mOverflowMenu release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -93,7 +105,10 @@ static const int kTabDragThreshold = 3; // distance a drag must go before we s
|
|||
[self loadImages];
|
||||
|
||||
// determine the frame of the active tab button and fill the rest of the bar in with the background
|
||||
NSRect activeTabButtonFrame = [mActiveTabButton frame];
|
||||
NSRect activeTabButtonFrame = [mActiveTabButton frame];
|
||||
NSRect tabsRect = [self tabsRect];
|
||||
// if any of the active tab would be outside the drawable area, fill it in
|
||||
if (NSMaxX(activeTabButtonFrame) > NSMaxX(tabsRect)) activeTabButtonFrame.size.width = 0.0;
|
||||
[self drawTabBarBackgroundInRect:rect withActiveTabRect:activeTabButtonFrame];
|
||||
NSArray *tabItems = [mTabView tabViewItems];
|
||||
NSEnumerator *tabEnumerator = [tabItems objectEnumerator];
|
||||
|
@ -104,7 +119,7 @@ static const int kTabDragThreshold = 3; // distance a drag must go before we s
|
|||
BrowserTabViewItem *nextTab = [tabEnumerator nextObject];
|
||||
|
||||
NSRect tabButtonFrame = [tabButton frame];
|
||||
if (NSIntersectsRect(tabButtonFrame,rect))
|
||||
if (NSIntersectsRect(tabButtonFrame,rect) && NSMaxX(tabButtonFrame) <= NSMaxX(tabsRect))
|
||||
[tabButton drawWithFrame:tabButtonFrame inView:self];
|
||||
// draw the first divider.
|
||||
if ((prevButton == nil) && ([tab tabState] != NSSelectedTab))
|
||||
|
@ -119,7 +134,9 @@ static const int kTabDragThreshold = 3; // distance a drag must go before we s
|
|||
{
|
||||
[super setFrame:frameRect];
|
||||
// tab buttons probably need to be resized if the frame changes
|
||||
[self unregisterTabButtonsForTracking];
|
||||
[self layoutButtons];
|
||||
[self registerTabButtonsForTracking];
|
||||
}
|
||||
|
||||
-(NSMenu*)menuForEvent:(NSEvent*)theEvent
|
||||
|
@ -134,7 +151,7 @@ static const int kTabDragThreshold = 3; // distance a drag must go before we s
|
|||
{
|
||||
NSPoint clickPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
TabButtonCell *clickedTabButton = [self buttonAtPoint:clickPoint];
|
||||
|
||||
|
||||
mLastClickPoint = clickPoint;
|
||||
|
||||
if (clickedTabButton && ![clickedTabButton willTrackMouse:theEvent inRect:[clickedTabButton frame] ofView:self])
|
||||
|
@ -220,6 +237,8 @@ static const int kTabDragThreshold = 3; // distance a drag must go before we s
|
|||
gBackgroundImage = [[NSImage imageNamed:@"tab_bar_bg"] retain];
|
||||
if (!gTabButtonDividerImage)
|
||||
gTabButtonDividerImage = [[NSImage imageNamed:@"tab_button_divider"] retain];
|
||||
if (!gTabOverflowImage)
|
||||
gTabOverflowImage = [[NSImage imageNamed:@"tab_overflow"] retain];
|
||||
}
|
||||
|
||||
// construct the tab bar based on the current state of mTabView;
|
||||
|
@ -233,11 +252,20 @@ static const int kTabDragThreshold = 3; // distance a drag must go before we s
|
|||
[self registerTabButtonsForTracking];
|
||||
}
|
||||
|
||||
- (void)windowClosed
|
||||
{
|
||||
// remove all tracking rects because this view is implicitly retained when they're registered
|
||||
[self unregisterTabButtonsForTracking];
|
||||
}
|
||||
|
||||
// allows tab button cells to react to mouse events
|
||||
-(void)registerTabButtonsForTracking
|
||||
{
|
||||
if ([self window]) {
|
||||
NSArray * tabItems = [mTabView tabViewItems];
|
||||
if(mTrackingCells) [self unregisterTabButtonsForTracking];
|
||||
mTrackingCells = [NSMutableArray arrayWithCapacity:[tabItems count]];
|
||||
[mTrackingCells retain];
|
||||
NSEnumerator *tabEnumerator = [tabItems objectEnumerator];
|
||||
|
||||
NSPoint local = [[self window] convertScreenToBase:[NSEvent mouseLocation]];
|
||||
|
@ -246,8 +274,13 @@ static const int kTabDragThreshold = 3; // distance a drag must go before we s
|
|||
BrowserTabViewItem *tab = nil;
|
||||
while (tab = [tabEnumerator nextObject]) {
|
||||
TabButtonCell * tabButton = [tab tabButtonCell];
|
||||
NSRect trackingRect = [tabButton frame];
|
||||
[tabButton addTrackingRectInView: self withFrame:trackingRect cursorLocation:local];
|
||||
if (tabButton) {
|
||||
[mTrackingCells addObject:tabButton];
|
||||
NSRect trackingRect = [tabButton frame];
|
||||
// only track tabs that are onscreen
|
||||
if (NSMaxX(trackingRect) <= NSMaxX([self tabsRect]))
|
||||
[tabButton addTrackingRectInView: self withFrame:trackingRect cursorLocation:local];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -255,11 +288,14 @@ static const int kTabDragThreshold = 3; // distance a drag must go before we s
|
|||
// causes tab buttons to stop reacting to mouse events
|
||||
-(void)unregisterTabButtonsForTracking
|
||||
{
|
||||
NSArray * tabItems = [mTabView tabViewItems];
|
||||
NSEnumerator *tabEnumerator = [tabItems objectEnumerator];
|
||||
BrowserTabViewItem *tab = nil;
|
||||
while (tab = [tabEnumerator nextObject])
|
||||
[[tab tabButtonCell] removeTrackingRectFromView: self];
|
||||
if (mTrackingCells) {
|
||||
NSEnumerator *tabEnumerator = [mTrackingCells objectEnumerator];
|
||||
TabButtonCell *tab = nil;
|
||||
while (tab = (TabButtonCell *)[tabEnumerator nextObject])
|
||||
[tab removeTrackingRectFromView: self];
|
||||
[mTrackingCells release];
|
||||
mTrackingCells = nil;
|
||||
}
|
||||
}
|
||||
|
||||
// returns the height the tab bar should be if drawn
|
||||
|
@ -282,8 +318,21 @@ static const int kTabDragThreshold = 3; // distance a drag must go before we s
|
|||
const int numTabs = [mTabView numberOfTabViewItems];
|
||||
float tabWidth = kMaxTabWidth;
|
||||
|
||||
// calculate the largest tabs that would fit
|
||||
// calculate the largest tabs that would fit... [self tabsRect] may not be correct until mOverflowTabs is set here.
|
||||
float maxWidth = floor((NSWidth([self bounds]) - (2*kTabBarMargin))/numTabs);
|
||||
// if tabs will overflow, leave space for the button
|
||||
if (maxWidth < kMinTabWidth) {
|
||||
mOverflowTabs = YES;
|
||||
NSRect tabsRect = [self tabsRect];
|
||||
for (int i = 1; i < numTabs; i++) {
|
||||
maxWidth = floor(NSWidth(tabsRect)/(numTabs - i));
|
||||
if (maxWidth >= kMinTabWidth) break;
|
||||
}
|
||||
// because the specific tabs which overflow may change, empty the menu and rebuild it as tabs are laid out
|
||||
[self initOverflowMenu];
|
||||
} else {
|
||||
mOverflowTabs = NO;
|
||||
}
|
||||
// if our tabs are currently larger than that, shrink them to the larger of kMinTabWidth or maxWidth
|
||||
if (tabWidth > maxWidth)
|
||||
tabWidth = (maxWidth > kMinTabWidth ? maxWidth : kMinTabWidth);
|
||||
|
@ -299,25 +348,80 @@ static const int kTabDragThreshold = 3; // distance a drag must go before we s
|
|||
buttonSize.width = tabWidth;
|
||||
buttonSize.height = kTabBarDefaultHeight;
|
||||
NSPoint buttonOrigin = NSMakePoint(xCoord,0);
|
||||
// TODO: take care of tabs that run off the end... right now we're the same as Firebird, except I think we
|
||||
// hit our tab limit before we'll run off the end of the average user's windows given the current kMinTabWidth
|
||||
[tabButtonCell setFrame:NSMakeRect(buttonOrigin.x,buttonOrigin.y,buttonSize.width,buttonSize.height)];
|
||||
// If the tab ran off the edge, suppress its close button
|
||||
if (buttonOrigin.x + buttonSize.width > NSMaxX([self bounds]))
|
||||
[tabButtonCell hideCloseButton];
|
||||
// tell the button whether it needs to draw the right side dividing line
|
||||
if (NSSelectedTab == [tab tabState]) {
|
||||
if ([tab tabState] == NSSelectedTab) {
|
||||
[tabButtonCell setDrawDivider:NO];
|
||||
[prevTabButton setDrawDivider:NO];
|
||||
} else {
|
||||
[tabButtonCell setDrawDivider:YES];
|
||||
}
|
||||
// If the tab ran off the edge, suppress its close button, make sure the divider is drawn, and add it to the menu
|
||||
if (buttonOrigin.x + buttonSize.width > NSMaxX([self tabsRect])) {
|
||||
[tabButtonCell hideCloseButton];
|
||||
// push the tab off the edge of the view to keep it from grabbing clicks if there is an area
|
||||
// between the overflow menu and the last tab which is within tabsRect due to rounding
|
||||
[tabButtonCell setFrame:NSMakeRect(NSMaxX([self bounds]),buttonOrigin.y,buttonSize.width,buttonSize.height)];
|
||||
// if the tab prior to the overflow is not selected, it must draw a divider
|
||||
if([[prevTabButton tabViewItem] tabState] != NSSelectedTab) [prevTabButton setDrawDivider:YES];
|
||||
[mOverflowMenu addItem:[tab menuItem]];
|
||||
}
|
||||
prevTabButton = tabButtonCell;
|
||||
xCoord += (int)tabWidth;
|
||||
}
|
||||
// if tabs overflowed, position and display the overflow button
|
||||
if (mOverflowTabs) {
|
||||
[mOverflowButton setFrame:NSMakeRect(NSMaxX([self tabsRect]) + kOverflowButtonMargin,
|
||||
([self tabBarHeight] - kOverflowButtonHeight)/2,kOverflowButtonWidth,kOverflowButtonHeight)];
|
||||
[self addSubview:mOverflowButton];
|
||||
} else {
|
||||
[mOverflowButton removeFromSuperview];
|
||||
}
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
-(void)initOverflowMenu
|
||||
{
|
||||
if (!mOverflowButton) {
|
||||
// if it hasn't been created yet, create an NSPopUpButton and retain a strong reference
|
||||
mOverflowButton = [[NSButton alloc] initWithFrame:NSMakeRect(0,0,kOverflowButtonWidth,kOverflowButtonHeight)];
|
||||
if (!gTabOverflowImage) [self loadImages];
|
||||
[mOverflowButton setImage:gTabOverflowImage];
|
||||
[mOverflowButton setImagePosition:NSImageOnly];
|
||||
[mOverflowButton setBezelStyle:NSShadowlessSquareBezelStyle];
|
||||
[mOverflowButton setBordered:NO];
|
||||
[[mOverflowButton cell] setHighlightsBy:NSNoCellMask];
|
||||
[mOverflowButton setTarget:self];
|
||||
[mOverflowButton setAction:@selector(overflowMenu:)];
|
||||
[(NSButtonCell *)[mOverflowButton cell]sendActionOn:NSLeftMouseDownMask];
|
||||
}
|
||||
if (!mOverflowMenu) {
|
||||
// create an empty NSMenu for later use and retain a strong reference
|
||||
mOverflowMenu = [[NSMenu alloc] init];
|
||||
[mOverflowMenu addItemWithTitle:@"" action:NULL keyEquivalent:@""];
|
||||
}
|
||||
// remove any items on the menu other than the dummy item
|
||||
for (int i = [mOverflowMenu numberOfItems]; i > 1; i--)
|
||||
[mOverflowMenu removeItemAtIndex:i-1];
|
||||
}
|
||||
|
||||
- (IBAction)overflowMenu:(id)sender
|
||||
{
|
||||
NSPopUpButtonCell *popupCell = [[[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:YES] autorelease];
|
||||
[popupCell setMenu:mOverflowMenu];
|
||||
[popupCell trackMouse:[NSApp currentEvent] inRect:[sender bounds] ofView:sender untilMouseUp:YES];
|
||||
}
|
||||
|
||||
// returns an NSRect of the area where tab widgets may be drawn
|
||||
-(NSRect)tabsRect
|
||||
{
|
||||
NSRect rect = [self bounds];
|
||||
rect.origin.x += kTabBarMargin;
|
||||
rect.size.width -= 2 * kTabBarMargin + (mOverflowTabs ? kOverflowButtonWidth : 0.0);
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// NSDraggingDestination destination methods
|
||||
|
|
|
@ -49,4 +49,6 @@
|
|||
- (BrowserTabViewItem*)itemWithTag:(int)tag;
|
||||
- (void)refreshTabBar:(BOOL)rebuild;
|
||||
|
||||
- (void)windowClosed;
|
||||
|
||||
@end
|
||||
|
|
|
@ -248,6 +248,20 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)windowClosed
|
||||
{
|
||||
// Loop over all tabs, and tell them that the window is closed. This
|
||||
// stops gecko from going any further on any of its open connections
|
||||
// and breaks all the necessary cycles between Gecko and the BrowserWrapper.
|
||||
int numTabs = [self numberOfTabViewItems];
|
||||
for (int i = 0; i < numTabs; i++) {
|
||||
NSTabViewItem* item = [self tabViewItemAtIndex: i];
|
||||
[[item view] windowClosed];
|
||||
}
|
||||
|
||||
// Tell the tab bar the window is closed so it will perform any needed cleanup
|
||||
[mTabBar windowClosed];
|
||||
}
|
||||
|
||||
- (BOOL)tabsVisible
|
||||
{
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
BrowserTabItemContainerView* mTabContentsView;
|
||||
NSProgressIndicator* mProgressWheel; // STRONG ref
|
||||
NSButton* mCloseButton; // STRING ref
|
||||
NSMenuItem* mMenuItem; // STRONG ref
|
||||
BOOL mDraggable;
|
||||
int mTag;
|
||||
}
|
||||
|
@ -70,6 +71,10 @@
|
|||
- (void)willBeRemoved:(BOOL)remove;
|
||||
|
||||
- (NSButton *)closeButton;
|
||||
- (NSMenuItem *)menuItem;
|
||||
- (void) willDeselect;
|
||||
- (void) willSelect;
|
||||
- (void) selectTab:(id)sender;
|
||||
|
||||
+ (NSImage*)closeIcon;
|
||||
+ (NSImage*)closeIconPressed;
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
// we cannot use the spinner before 10.2, so don't allow it. This is the
|
||||
// version of appkit in 10.2 (taken from the 10.3 SDK headers which we cannot use).
|
||||
const double kJaguarAppKitVersion = 663;
|
||||
// truncate menuitem title to the same width as the bookmarks menu
|
||||
const int kMenuTruncationChars = 60;
|
||||
|
||||
@interface BrowserTabViewItem(Private)
|
||||
- (void)setTag:(int)tag;
|
||||
|
@ -107,6 +109,8 @@ const double kJaguarAppKitVersion = 663;
|
|||
{
|
||||
[mLabelCell release];
|
||||
[mTabButtonCell release];
|
||||
// needs to be nil so that [super dealloc]'s call to setMenu doesn't cause us to call setMenu on an invalid object
|
||||
mTabButtonCell = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -340,7 +344,12 @@ const double kJaguarAppKitVersion = 663;
|
|||
[mCloseButton setTarget:self];
|
||||
[mCloseButton setAction:@selector(closeTab)];
|
||||
[mCloseButton setAutoresizingMask:NSViewMinXMargin];
|
||||
[mCloseButton retain];
|
||||
|
||||
// create a menu item, to be used when there are more tabs than screen real estate. keep a strong ref
|
||||
// since it will be added to and removed from the menu repeatedly
|
||||
mMenuItem = [[NSMenuItem alloc] initWithTitle:[self label] action:@selector(selectTab:) keyEquivalent:@""];
|
||||
[mMenuItem setTarget:self];
|
||||
[mMenuItem retain];
|
||||
|
||||
[[self tabView] setAutoresizesSubviews:YES];
|
||||
|
||||
|
@ -363,6 +372,7 @@ const double kJaguarAppKitVersion = 663;
|
|||
[mTabContentsView release]; // balance our init
|
||||
[mProgressWheel release];
|
||||
[mCloseButton release];
|
||||
[mMenuItem release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -423,6 +433,7 @@ const double kJaguarAppKitVersion = 663;
|
|||
{
|
||||
NSAttributedString* labelString = [[[NSAttributedString alloc] initWithString:label attributes:mLabelAttributes] autorelease];
|
||||
[[mTabContentsView labelCell] setAttributedStringValue:labelString];
|
||||
[mMenuItem setTitle:[label stringByTruncatingTo:kMenuTruncationChars at:kTruncateAtMiddle]];
|
||||
[(BrowserTabView *)[self tabView] refreshTabBar:NO];
|
||||
|
||||
[super setLabel:label];
|
||||
|
@ -447,6 +458,7 @@ const double kJaguarAppKitVersion = 663;
|
|||
{
|
||||
[super setTabIcon:newIcon];
|
||||
[[mTabContentsView labelCell] setImage:mTabIcon];
|
||||
[mMenuItem setImage:mTabIcon];
|
||||
[(BrowserTabView *)[self tabView] refreshTabBar:NO];
|
||||
}
|
||||
|
||||
|
@ -500,6 +512,27 @@ const double kJaguarAppKitVersion = 663;
|
|||
return mCloseButton;
|
||||
}
|
||||
|
||||
- (NSMenuItem *) menuItem
|
||||
{
|
||||
return mMenuItem;
|
||||
}
|
||||
|
||||
- (void) selectTab:(id)sender
|
||||
{
|
||||
[[self tabView] selectTabViewItem:self];
|
||||
}
|
||||
|
||||
// called by delegate when a tab will be deselected
|
||||
- (void) willDeselect
|
||||
{
|
||||
[mMenuItem setState:NSOffState];
|
||||
}
|
||||
// called by delegate when a tab will be selected
|
||||
- (void) willSelect
|
||||
{
|
||||
[mMenuItem setState:NSOnState];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
+ (NSImage*)closeIcon
|
||||
|
|
|
@ -126,7 +126,7 @@ static NSString *NavigatorWindowFrameSaveName = @"NavigatorWindow";
|
|||
// hardcoded defaults.
|
||||
static NSArray* sToolbarDefaults = nil;
|
||||
|
||||
#define kMaxBrowserWindowTabs 16
|
||||
#define kMaxBrowserWindowTabs 0
|
||||
|
||||
enum BWCOpenDest {
|
||||
kDestinationNewWindow = 0,
|
||||
|
@ -504,14 +504,8 @@ enum BWCOpenDest {
|
|||
NS_IF_RELEASE(mURIFixer);
|
||||
} // matters
|
||||
|
||||
// Loop over all tabs, and tell them that the window is closed. This
|
||||
// stops gecko from going any further on any of its open connections
|
||||
// and breaks all the necessary cycles between Gecko and the BrowserWrapper.
|
||||
int numTabs = [mTabBrowser numberOfTabViewItems];
|
||||
for (int i = 0; i < numTabs; i++) {
|
||||
NSTabViewItem* item = [mTabBrowser tabViewItemAtIndex: i];
|
||||
[[item view] windowClosed];
|
||||
}
|
||||
// Tell the BrowserTabView the window is closed
|
||||
[mTabBrowser windowClosed];
|
||||
|
||||
// if the bookmark manager is visible when we close the window, all hell
|
||||
// breaks loose in the autorelease pool and when we try to show another
|
||||
|
@ -2406,6 +2400,18 @@ enum BWCOpenDest {
|
|||
[mBrowserView makePrimaryBrowserView: mURLBar status: mStatus windowController: self];
|
||||
}
|
||||
|
||||
- (void)tabView:(NSTabView *)aTabView willSelectTabViewItem:(NSTabViewItem *)aTabViewItem
|
||||
{
|
||||
// we'll get called for the sidebar tabs as well. ignore any calls coming from
|
||||
// there, we're only interested in the browser tabs.
|
||||
if (aTabView != mTabBrowser)
|
||||
return;
|
||||
if ([aTabView isKindOfClass:[BrowserTabView class]] && [aTabViewItem isKindOfClass:[BrowserTabViewItem class]]) {
|
||||
[(BrowserTabViewItem *)[aTabView selectedTabViewItem] willDeselect];
|
||||
[(BrowserTabViewItem *)aTabViewItem willSelect];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)tabViewDidChangeNumberOfTabViewItems:(NSTabView *)aTabView
|
||||
{
|
||||
[[NSApp delegate] fixCloseMenuItemKeyEquivalents];
|
||||
|
|
|
@ -89,8 +89,11 @@
|
|||
NSView *view = [userData objectForKey:@"view"];
|
||||
mMouseWithin = YES;
|
||||
// only act on the mouseEntered if the view is active or accepts the first mouse click
|
||||
if ([[view window] isKeyWindow] || [view acceptsFirstMouse:theEvent])
|
||||
if ([[view window] isKeyWindow] || [view acceptsFirstMouse:theEvent]) {
|
||||
[view setNeedsDisplayInRect:[self frame]];
|
||||
// calling displayIfNeeded prevents the "lag" observed when displaying rollover events
|
||||
[view displayIfNeeded];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseExited:(NSEvent*)theEvent
|
||||
|
@ -99,8 +102,11 @@
|
|||
NSView *view = [userData objectForKey:@"view"];
|
||||
mMouseWithin = NO;
|
||||
// only act on the mouseExited if the view is active or accepts the first mouse click
|
||||
if ([[view window] isKeyWindow] || [view acceptsFirstMouse:theEvent])
|
||||
if ([[view window] isKeyWindow] || [view acceptsFirstMouse:theEvent]) {
|
||||
[view setNeedsDisplayInRect:[self frame]];
|
||||
// calling displayIfNeeded prevents the "lag" observed when displaying rollover events
|
||||
[view displayIfNeeded];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setDragTarget:(BOOL)isDragTarget
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
@interface TabButtonCell : RolloverTrackingCell {
|
||||
BrowserTabViewItem *mTabViewItem;
|
||||
BOOL mNeedsDivider;
|
||||
NSButton * mCloseButton;
|
||||
}
|
||||
|
||||
-(id)initFromTabViewItem:(BrowserTabViewItem*)tabViewItem;
|
||||
|
|
|
@ -64,16 +64,15 @@ static NSImage * tabButtonDividerImage = nil;
|
|||
-(id)initFromTabViewItem:(BrowserTabViewItem *)tabViewItem
|
||||
{
|
||||
[super init];
|
||||
mTabViewItem = [tabViewItem retain];
|
||||
mTabViewItem = tabViewItem;
|
||||
mNeedsDivider = YES;
|
||||
return self;
|
||||
}
|
||||
|
||||
// XXX does the menu need released here??
|
||||
-(void)dealloc
|
||||
{
|
||||
[[mTabViewItem closeButton] removeFromSuperview];
|
||||
[mTabViewItem release];
|
||||
[mCloseButton removeFromSuperview];
|
||||
[mCloseButton release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -102,7 +101,11 @@ static NSImage * tabButtonDividerImage = nil;
|
|||
// we have bigger problems
|
||||
|
||||
NSSize textSize = [mTabViewItem sizeOfLabel:NO];
|
||||
NSSize buttonSize = [[mTabViewItem closeButton] frame].size;
|
||||
|
||||
// retain a reference to the close button; otherwise we can't be sure it's removed from the view hierarchy
|
||||
// during our d'tor, when mTabViewItem will be invalid.
|
||||
if (!mCloseButton) mCloseButton = [[mTabViewItem closeButton] retain];
|
||||
NSSize buttonSize = [mCloseButton frame].size;
|
||||
|
||||
// center based on the larger of the two heights if there's a difference
|
||||
float maxHeight = textSize.height > buttonSize.height ? textSize.height : buttonSize.height;
|
||||
|
@ -148,13 +151,10 @@ static NSImage * tabButtonDividerImage = nil;
|
|||
rect.origin.y += kTabBottomPad;
|
||||
NSRectFill(rect);
|
||||
}
|
||||
NSButton *closeButton = [mTabViewItem closeButton];
|
||||
if (controlView != [closeButton superview]) {
|
||||
[controlView addSubview:closeButton];
|
||||
if (controlView != [mCloseButton superview]) {
|
||||
[controlView addSubview:mCloseButton];
|
||||
}
|
||||
[closeButton setFrame:buttonRect];
|
||||
// XXX is this necessary, or even good?
|
||||
[closeButton setNeedsDisplay:YES];
|
||||
[mCloseButton setFrame:buttonRect];
|
||||
[labelCell drawInteriorWithFrame:labelRect inView:controlView];
|
||||
}
|
||||
|
||||
|
@ -170,9 +170,8 @@ static NSImage * tabButtonDividerImage = nil;
|
|||
|
||||
-(void)hideCloseButton
|
||||
{
|
||||
NSButton * closeButton = [mTabViewItem closeButton];
|
||||
if ([closeButton superview] != nil)
|
||||
[closeButton removeFromSuperview];
|
||||
if ([mCloseButton superview] != nil)
|
||||
[mCloseButton removeFromSuperview];
|
||||
}
|
||||
|
||||
-(void)setDrawDivider:(BOOL)willDraw
|
||||
|
|
Загрузка…
Ссылка в новой задаче