bug 235864, close tab button does not give mouse hover feedback. r=smorgan, sr=pink. Patch by Aaron Schulman (aschulm@gmail.com)

This commit is contained in:
hwaara%gmail.com 2006-05-12 16:50:39 +00:00
parent cddae0bdc9
commit b380a0fb06
9 changed files with 275 additions and 7 deletions

Binary file not shown.

View File

@ -44,13 +44,14 @@
@class BrowserTabItemContainerView;
@class TruncatingTextAndImageCell;
@class TabButtonCell;
@class RolloverImageButton;
@interface BrowserTabViewItem : IconTabViewItem
{
NSRect mLastDrawRect; // cached draw rect, used for dragging location
BrowserTabItemContainerView* mTabContentsView;
NSProgressIndicator* mProgressWheel; // STRONG ref
NSButton* mCloseButton; // STRING ref
RolloverImageButton* mCloseButton; // STRONG ref
NSMenuItem* mMenuItem; // STRONG ref
BOOL mDraggable;
int mTag;
@ -71,7 +72,7 @@
// call before removing to clean up close button and progress spinner
- (void)willBeRemoved:(BOOL)remove;
- (NSButton *)closeButton;
- (RolloverImageButton *)closeButton;
- (NSMenuItem *)menuItem;
- (void) willDeselect;
- (void) willSelect;
@ -79,5 +80,6 @@
+ (NSImage*)closeIcon;
+ (NSImage*)closeIconPressed;
+ (NSImage*)closeIconHover;
@end

View File

@ -48,6 +48,7 @@
#import "BrowserWindowController.h"
#import "TruncatingTextAndImageCell.h"
#import "TabButtonCell.h"
#import "RolloverImageButton.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).
@ -335,10 +336,11 @@ const int kMenuTruncationChars = 60;
#endif
// 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 = [[RolloverImageButton alloc] initWithFrame:NSMakeRect(0, 0, 16, 16)];
[mCloseButton setTitle:NSLocalizedString(@"CloseTabButtonTitle", @"")]; // doesn't show, but used for accessibility
[mCloseButton setImage:[BrowserTabViewItem closeIcon]];
[mCloseButton setAlternateImage:[BrowserTabViewItem closeIconPressed]];
[mCloseButton setHoverImage:[BrowserTabViewItem closeIconHover]];
[mCloseButton setImagePosition:NSImageOnly];
[mCloseButton setBezelStyle:NSShadowlessSquareBezelStyle];
[mCloseButton setBordered:NO];
@ -508,7 +510,7 @@ const int kMenuTruncationChars = 60;
#endif
}
- (NSButton *) closeButton
- (RolloverImageButton *) closeButton
{
return mCloseButton;
}
@ -552,6 +554,14 @@ const int kMenuTruncationChars = 60;
return sCloseIconPressed;
}
+ (NSImage*)closeIconHover
{
static NSImage* sCloseIconHover = nil;
if ( !sCloseIconHover )
sCloseIconHover = [[NSImage imageNamed:@"tab_close_hover"] retain];
return sCloseIconHover;
}
#define NO_TOOLTIPS_ON_TABS 1
#ifdef NO_TOOLTIPS_ON_TABS

View File

@ -159,7 +159,6 @@ static void RedistributeSpace(int resizeMask, float newWidth, /* in out */ float
[existingSubview retain];
[existingSubview removeFromSuperview];
[self addSubview:newSubview];
[newSubview setFrame:[self bounds]];

View File

@ -0,0 +1,47 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Chimera code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Aaron Schulman <aschulm@umd.edu>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#import <Cocoa/Cocoa.h>
@interface RolloverImageButton : NSButton {
@private
NSImage* mImage; //STRONG Refrence
NSImage* mHoverImage; //STRONG Refrence
NSTrackingRectTag mTrackingTag;
}
- (void)setHoverImage:(NSImage*)inImage;
@end

View File

@ -0,0 +1,207 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Camino code.
*
* The Initial Developer of the Original Code is
* Aaron Schulman <aschulm@umd.edu>
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Aaron Schulman <aschulm@umd.edu>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#import "RolloverImageButton.h"
@interface RolloverImageButton (Private)
- (void)updateImage:(BOOL)inIsInside;
- (BOOL)isMouseInside;
- (void)removeTrackingRectFromView:(NSView *)inView;
- (void)updateTrackingRectInSuperview;
@end
@implementation RolloverImageButton
- (id)initWithFrame:(NSRect)inFrame
{
if ((self = [super initWithFrame:inFrame])) {
mImage = nil;
mHoverImage = nil;
mTrackingTag = -1;
}
return self;
}
- (void)dealloc
{
[mImage release];
[mHoverImage release];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self];
[super dealloc];
}
- (void)removeFromSuperview
{
[self removeTrackingRectFromView:[self superview]];
[super removeFromSuperview];
}
- (void)viewDidMoveToWindow
{
[self updateTrackingRectInSuperview];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
// unregister the button from observering the current window just in case a tab moves from one window to another
[nc removeObserver:self];
if ([self window]) {
[nc addObserver:self selector:@selector(handleWindowIsKey:)
name:NSWindowDidBecomeKeyNotification object:[self window]];
[nc addObserver:self selector:@selector(handleWindowResignKey:)
name:NSWindowDidResignKeyNotification object:[self window]];
}
}
- (void)setFrame:(NSRect)inFrame
{
NSRect oldFrame = [self frame];
[super setFrame:inFrame];
if (!NSEqualRects(oldFrame, [self frame]))
[self updateTrackingRectInSuperview];
}
- (void)setFrameOrigin:(NSPoint)inOrigin
{
NSPoint oldOrigin = [self frame].origin;
[super setFrameOrigin:inOrigin];
if (!NSEqualPoints(oldOrigin,[self frame].origin))
[self updateTrackingRectInSuperview];
}
- (void)setFrameSize:(NSSize)inSize
{
NSSize oldSize = [self frame].size;
[super setFrameSize:inSize];
if (!NSEqualSizes(oldSize,[self frame].size))
[self updateTrackingRectInSuperview];
}
- (void)mouseEntered:(NSEvent*)theEvent
{
if (([[self window] isKeyWindow] || [self acceptsFirstMouse:theEvent])
&& [theEvent trackingNumber] == mTrackingTag)
[self updateImage:YES];
}
- (void)mouseExited:(NSEvent*)theEvent
{
if (([[self window] isKeyWindow] || [self acceptsFirstMouse:theEvent])
&& [theEvent trackingNumber] == mTrackingTag)
[self updateImage:NO];
}
- (void)mouseDown:(NSEvent*)theEvent
{
[self updateImage:NO];
[super mouseDown:theEvent];
// update button's image based on location of mouse after button has been released
[self updateImage:[self isMouseInside]];
}
- (BOOL)acceptsFirstMouse:(NSEvent*)theEvent
{
return NO;
}
- (void)setImage:(NSImage*)inImage
{
if (mImage != inImage) {
[mImage release];
mImage = [inImage retain];
[self updateImage:[self isMouseInside]];
}
}
- (void)setHoverImage:(NSImage*)inImage
{
if (mHoverImage != inImage) {
[mHoverImage release];
mHoverImage = [inImage retain];
[self updateImage:[self isMouseInside]];
}
}
- (void)handleWindowIsKey:(NSWindow *)inWindow
{
[self updateImage:[self isMouseInside]];
}
- (void)handleWindowResignKey:(NSWindow *)inWindow
{
[self updateImage:NO];
}
- (void)resetCursorRects
{
[self updateTrackingRectInSuperview];
}
@end
@implementation RolloverImageButton (Private)
- (void)updateImage:(BOOL)inIsInside
{
if (inIsInside)
[super setImage:mHoverImage];
else
[super setImage:mImage];
}
- (BOOL)isMouseInside
{
NSPoint mousePointInWindow = [[self window] convertScreenToBase:[NSEvent mouseLocation]];
NSPoint mousePointInView = [[self superview] convertPoint:mousePointInWindow fromView:nil];
return NSMouseInRect(mousePointInView, [self frame], NO);
}
- (void)removeTrackingRectFromView:(NSView *)inView
{
[inView removeTrackingRect:mTrackingTag];
mTrackingTag = -1;
}
- (void)updateTrackingRectInSuperview
{
if (mTrackingTag != -1)
[self removeTrackingRectFromView:[self superview]];
BOOL mouseInside = [self isMouseInside];
mTrackingTag = [[self superview] addTrackingRect:[self frame] owner:self userData:nil assumeInside:mouseInside];
[self updateImage:mouseInside];
}
@end

View File

@ -40,11 +40,13 @@
#import "RolloverTrackingCell.h"
#import "BrowserTabViewItem.h"
@class RolloverImageButton;
@interface TabButtonCell : RolloverTrackingCell
{
BrowserTabViewItem* mTabViewItem;
BOOL mNeedsDivider;
NSButton* mCloseButton;
RolloverImageButton* mCloseButton;
}
-(id)initFromTabViewItem:(BrowserTabViewItem*)tabViewItem;

View File

@ -40,6 +40,7 @@
#import "NSBezierPath+Utils.h"
#import "TabButtonCell.h"
#import "RolloverImageButton.h"
#import "TruncatingTextAndImageCell.h"
static const int kTabLeftMargin = 4; //distance between left edge and close button