diff --git a/mozilla/camino/Camino.xcode/project.pbxproj b/mozilla/camino/Camino.xcode/project.pbxproj index e3df3a25358..2f8acb8b357 100644 --- a/mozilla/camino/Camino.xcode/project.pbxproj +++ b/mozilla/camino/Camino.xcode/project.pbxproj @@ -1402,6 +1402,8 @@ 3F44AC7E05BDFB9E00CB4B08, 3F44AC7F05BDFB9E00CB4B08, 3F44AFED05BDFBA100CB4B08, + 3FE9A81B05E28BFA00B86211, + 3FE9A81C05E28BFA00B86211, ); isa = PBXResourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -5412,6 +5414,8 @@ 3F44AEB705BDFBA000CB4B08, 3F44AEB805BDFBA000CB4B08, 3F44AFF305BDFBA100CB4B08, + 3FE9A81D05E28BFA00B86211, + 3FE9A81E05E28BFA00B86211, ); isa = PBXResourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -8672,6 +8676,46 @@ refType = 4; sourceTree = ""; }; + 3FE9A81905E28BF900B86211 = { + isa = PBXFileReference; + lastKnownFileType = image.png; + name = tab_close_pressed.png; + path = resources/images/chrome/tab_close_pressed.png; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 3FE9A81A05E28BFA00B86211 = { + isa = PBXFileReference; + lastKnownFileType = image.png; + name = tab_close.png; + path = resources/images/chrome/tab_close.png; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 3FE9A81B05E28BFA00B86211 = { + fileRef = 3FE9A81905E28BF900B86211; + isa = PBXBuildFile; + settings = { + }; + }; + 3FE9A81C05E28BFA00B86211 = { + fileRef = 3FE9A81A05E28BFA00B86211; + isa = PBXBuildFile; + settings = { + }; + }; + 3FE9A81D05E28BFA00B86211 = { + fileRef = 3FE9A81905E28BF900B86211; + isa = PBXBuildFile; + settings = { + }; + }; + 3FE9A81E05E28BFA00B86211 = { + fileRef = 3FE9A81A05E28BFA00B86211; + isa = PBXBuildFile; + settings = { + }; + }; 3FECC78F05D1F68E0068E7ED = { children = ( 3F44AD8705BDFB9F00CB4B08, @@ -8989,6 +9033,8 @@ }; F50BC9A40239FA8D010001CA = { children = ( + 3FE9A81905E28BF900B86211, + 3FE9A81A05E28BFA00B86211, F540BD1A029ED15301026D5D, F540BD1C029ED17901026D5D, 3FAD95540461E43700A80005, diff --git a/mozilla/camino/src/browser/BrowserTabViewItem.h b/mozilla/camino/src/browser/BrowserTabViewItem.h index 01408d99117..8c912f8023b 100644 --- a/mozilla/camino/src/browser/BrowserTabViewItem.h +++ b/mozilla/camino/src/browser/BrowserTabViewItem.h @@ -47,6 +47,8 @@ { NSRect mLastDrawRect; // cached draw rect, used for dragging location BrowserTabItemContainerView* mTabContentsView; + NSProgressIndicator* mProgressWheel; // STRONG ref + NSButton* mCloseButton; // STRING ref BOOL mDraggable; int mTag; } @@ -56,4 +58,11 @@ - (int)tag; - (void)setTabIcon:(NSImage *)newIcon isDraggable:(BOOL)draggable; +// call to start and stop the progress animation on this tab +- (void)startLoadAnimation; +- (void)stopLoadAnimation; + ++ (NSImage*)closeIcon; ++ (NSImage*)closeIconPressed; + @end diff --git a/mozilla/camino/src/browser/BrowserTabViewItem.mm b/mozilla/camino/src/browser/BrowserTabViewItem.mm index f12234c6b8f..0aa34608a6c 100644 --- a/mozilla/camino/src/browser/BrowserTabViewItem.mm +++ b/mozilla/camino/src/browser/BrowserTabViewItem.mm @@ -46,6 +46,9 @@ #import "MainController.h" #import "BrowserWindowController.h" +// 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; @interface BrowserTabViewItem(Private) - (void)setTag:(int)tag; @@ -64,6 +67,7 @@ float mImagePadding; float mImageSpace; float mImageAlpha; + float mRightGutter; // leave space for an icon on the right } - (id)initTextCell:(NSString*)aString; @@ -72,6 +76,7 @@ - (void)setImagePadding:(float)padding; - (void)setImageSpace:(float)space; - (void)setImageAlpha:(float)alpha; +- (void)setRightGutter:(float)rightPadding; - (void)setImage:(NSImage *)anImage; - (NSImage *)image; @@ -87,6 +92,7 @@ mLabelStringWidth = -1; mImagePadding = 0; mImageSpace = 2; + mRightGutter = 0.0; } return self; } @@ -104,6 +110,7 @@ cell->mImage = [mImage retain]; cell->mTruncLabelString = nil; cell->mLabelStringWidth = -1; + cell->mRightGutter = mRightGutter; return cell; } @@ -128,7 +135,7 @@ // remove image space NSDivideRect(textRect, &imageRect, &textRect, mImageSpace, NSMinXEdge); - int cellWidth = (int)NSWidth(textRect); + int cellWidth = (int)NSWidth(textRect) - (int)mRightGutter; NSDictionary *cellAttributes = [[self attributedStringValue] attributesAtIndex:0 effectiveRange:nil]; if (mLabelStringWidth != cellWidth || !mTruncLabelString) @@ -191,6 +198,11 @@ mImageAlpha = alpha; } +- (void)setRightGutter:(float)rightPadding +{ + mRightGutter = rightPadding; +} + @end #pragma mark - @@ -219,13 +231,16 @@ { if ( (self = [super initWithFrame:frameRect]) ) { + const float kCloseButtonWidth = 16.0; // width of spinner/close button to right of text + mTabViewItem = tabViewItem; mLabelCell = [[NSTruncatingTextAndImageCell alloc] init]; [mLabelCell setControlSize:NSSmallControlSize]; // doesn't work? [mLabelCell setImagePadding:0.0]; [mLabelCell setImageSpace:2.0]; - + [mLabelCell setRightGutter:kCloseButtonWidth]; + [self registerForDraggedTypes:[NSArray arrayWithObjects: @"MozURLType", @"MozBookmarkType", NSStringPboardType, NSFilenamesPboardType, NSURLPboardType, nil]]; } @@ -444,6 +459,34 @@ mTabContentsView = [[BrowserTabItemContainerView alloc] initWithFrame:NSMakeRect(0, 0, 100, 16) andTabItem:self]; + + // create progress wheel. keep a strong ref as view goes in and out of view hierarchy. We + // cannot use |NSProgressIndicatorSpinningStyle| on 10.1, so don't bother even creating it + // and let all the calls to it be no-ops elsewhere in this class (prevents clutter, imho). + if (NSAppKitVersionNumber >= kJaguarAppKitVersion) { + mProgressWheel = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(0, 0, 16, 16)]; + [mProgressWheel setStyle:NSProgressIndicatorSpinningStyle]; + [mProgressWheel setUsesThreadedAnimation:YES]; + [mProgressWheel setDisplayedWhenStopped:NO]; + [mProgressWheel setAutoresizingMask:NSViewMinXMargin]; + } + else + mProgressWheel = nil; + + // create close button. keep a strong ref as view goes in and out of view hierarchy + mCloseButton = [[NSButton alloc] initWithFrame:NSMakeRect(0, 0, 16, 16)]; + [mCloseButton setImage:[BrowserTabViewItem closeIcon]]; + [mCloseButton setAlternateImage:[BrowserTabViewItem closeIconPressed]]; + [mCloseButton setImagePosition:NSImageOnly]; + [mCloseButton setBezelStyle:NSShadowlessSquareBezelStyle]; + [mCloseButton setBordered:NO]; + [mCloseButton setButtonType:NSMomentaryChangeButton]; + [mCloseButton setTarget:self]; + [mCloseButton setAction:@selector(closeTab)]; + [mCloseButton setAutoresizingMask:NSViewMinXMargin]; + + [[self tabView] setAutoresizesSubviews:YES]; + mDraggable = NO; } return self; @@ -461,6 +504,8 @@ // removed all its subviews. [mTabContentsView removeFromSuperview]; // may be noop [mTabContentsView release]; // balance our init + [mProgressWheel release]; + [mCloseButton release]; [super dealloc]; } @@ -479,6 +524,14 @@ return mTag; } +- (void)closeTab +{ + [[self view] windowClosed]; + [mCloseButton removeFromSuperview]; + [mProgressWheel removeFromSuperview]; + [[self tabView] removeTabViewItem:self]; +} + - (void)updateTabVisibility:(BOOL)nowVisible { if (nowVisible) @@ -496,6 +549,8 @@ - (void)relocateTabContents:(NSRect)inRect { [mTabContentsView setFrame:inRect]; + [mProgressWheel setFrame:NSMakeRect(inRect.size.width - 16, 0, 16, 16)]; + [mCloseButton setFrame:NSMakeRect(inRect.size.width - 16, 0, 16, 16)]; } - (BOOL)draggable @@ -509,11 +564,6 @@ mLastDrawRect = tabRect; } -- (NSSize)sizeOfLabel:(BOOL)shouldTruncateLabel -{ - return [super sizeOfLabel:shouldTruncateLabel]; -} - - (void)setLabel:(NSString *)label { NSAttributedString* labelString = [[[NSAttributedString alloc] initWithString:label attributes:mLabelAttributes] autorelease]; @@ -540,6 +590,46 @@ [[mTabContentsView labelCell] setImageAlpha:(draggable ? 1.0 : 0.6)]; } +#pragma mark - + +- (void)startLoadAnimation +{ + // remove close from tab view + [mCloseButton removeFromSuperview]; + + // add spinner to tab view and start animation + [mTabContentsView addSubview:mProgressWheel]; + [mProgressWheel startAnimation:self]; +} + +- (void)stopLoadAnimation +{ + // stop animation and remove spinner from tab view + [mProgressWheel stopAnimation:self]; + [mProgressWheel removeFromSuperview]; + + // add close button to tab view + [mTabContentsView addSubview:mCloseButton]; +} + +#pragma mark - + ++ (NSImage*)closeIcon +{ + static NSImage* sCloseIcon = nil; + if ( !sCloseIcon ) + sCloseIcon = [[NSImage imageNamed:@"tab_close"] retain]; + return sCloseIcon; +} + ++ (NSImage*)closeIconPressed +{ + static NSImage* sCloseIconPressed = nil; + if ( !sCloseIconPressed ) + sCloseIconPressed = [[NSImage imageNamed:@"tab_close_pressed"] retain]; + return sCloseIconPressed; +} + #define NO_TOOLTIPS_ON_TABS 1 #ifdef NO_TOOLTIPS_ON_TABS diff --git a/mozilla/camino/src/browser/BrowserWrapper.mm b/mozilla/camino/src/browser/BrowserWrapper.mm index 2eef38a1707..43f316e3458 100644 --- a/mozilla/camino/src/browser/BrowserWrapper.mm +++ b/mozilla/camino/src/browser/BrowserWrapper.mm @@ -340,6 +340,8 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged"; [mLoadingStatusString autorelease]; mLoadingStatusString = [NSLocalizedString(@"TabLoading", @"") retain]; [mStatus setStringValue:mLoadingStatusString]; + + [(BrowserTabViewItem*)mTabItem startLoadAnimation]; NS_IF_RELEASE(mBlockedSites); [mWindowController showPopupBlocked:NO]; @@ -383,6 +385,8 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged"; else { [mStatus setStringValue:mLoadingStatusString]; } + + [(BrowserTabViewItem*)mTabItem stopLoadAnimation]; mProgress = 1.0; mIsBusy = NO;