diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-19 01:19:15 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-19 01:19:15 +0000 |
commit | e7354bb9d013b913dedaa8a45e2243fb559cf60b (patch) | |
tree | d153ed2a1831d9158d5ccd4b33ed38d003605fc0 /chrome/browser/autocomplete/autocomplete_popup_view_mac.mm | |
parent | ee77fcf1bab6f960d3b452ce86703af602bcb6d6 (diff) | |
download | chromium_src-e7354bb9d013b913dedaa8a45e2243fb559cf60b.zip chromium_src-e7354bb9d013b913dedaa8a45e2243fb559cf60b.tar.gz chromium_src-e7354bb9d013b913dedaa8a45e2243fb559cf60b.tar.bz2 |
[Mac] Refactor omnibox popup to fix click-drag display.
Fix the confusion between highlighted and selected cells by
overriding |-mouseDown:| and directly implementing the desired
behaviors. Which are:
- while mouse is down in the view, the item under the mouse
looks selected, like it would if you used the arrow keys to
move it around (rather than highlighted).
- dragging off with mouse down reverts to previous
selection (the one matching the field's contents).
- releasing while mouse is off-view reverts to previous
selection.
- dragging back with mouse still down selects the cell under the
mouse.
Additionally, refactor to remove useless utility object. The
custom matrix now just messages the C++ object directly.
BUG=25435
TEST=See bug.
Review URL: http://codereview.chromium.org/646063
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39411 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/autocomplete/autocomplete_popup_view_mac.mm')
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_popup_view_mac.mm | 168 |
1 files changed, 76 insertions, 92 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm b/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm index b72eef3..4122cbb 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm +++ b/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm @@ -273,11 +273,16 @@ NSAttributedString* AutocompletePopupViewMac::MatchText( // highlighting the cell the mouse is over. @interface AutocompleteMatrix : NSMatrix { - SEL middleClickAction_; + @private + // Target for click and middle-click. + AutocompletePopupViewMac* popupView_; // weak, owns us. } -// Action to be called when the middle mouse button is released. -- (void)setMiddleClickAction:(SEL)anAction; +// Create a zero-size matrix initializing |popupView_|. +- initWithPopupView:(AutocompletePopupViewMac*)popupView; + +// Set |popupView_|. +- (void)setPopupView:(AutocompletePopupViewMac*)popupView; // Return the currently highlighted row. Returns -1 if no row is // highlighted. @@ -285,27 +290,6 @@ NSAttributedString* AutocompletePopupViewMac::MatchText( @end -// Thin Obj-C bridge class between the target of the popup window's -// AutocompleteMatrix and the AutocompletePopupView implementation. - -// TODO(shess): Now that I'm using AutocompleteMatrix, I could instead -// subvert the target/action stuff and have it message popup_view_ -// directly. - -@interface AutocompleteMatrixTarget : NSObject { - @private - AutocompletePopupViewMac* popup_view_; // weak, owns us. -} -- initWithPopupView:(AutocompletePopupViewMac*)view; - -// Tell popup model via popup_view_ about the selected row. -- (void)select:(id)sender; - -// Call |popup_view_| OnMiddleClick(). -- (void)middleSelect:(id)sender; - -@end - AutocompletePopupViewMac::AutocompletePopupViewMac( AutocompleteEditViewMac* edit_view, AutocompleteEditModel* edit_model, @@ -316,7 +300,6 @@ AutocompletePopupViewMac::AutocompletePopupViewMac( edit_view_(edit_view), bubble_positioner_(bubble_positioner), field_(field), - matrix_target_([[AutocompleteMatrixTarget alloc] initWithPopupView:this]), popup_(nil) { DCHECK(edit_view); DCHECK(edit_model); @@ -333,8 +316,9 @@ AutocompletePopupViewMac::~AutocompletePopupViewMac() { model_.reset(); // Break references to matrix_target_ before it is released. - NSMatrix* matrix = [popup_ contentView]; - [matrix setTarget:nil]; + AutocompleteMatrix* matrix = [popup_ contentView]; + DCHECK(matrix == nil || [matrix isKindOfClass:[AutocompleteMatrix class]]); + [matrix setPopupView:NULL]; } bool AutocompletePopupViewMac::IsOpen() const { @@ -356,11 +340,8 @@ void AutocompletePopupViewMac::CreatePopupIfNeeded() { [popup_ setHasShadow:YES]; [popup_ setLevel:NSNormalWindowLevel]; - AutocompleteMatrix* matrix = - [[[AutocompleteMatrix alloc] initWithFrame:NSZeroRect] autorelease]; - [matrix setTarget:matrix_target_]; - [matrix setAction:@selector(select:)]; - [matrix setMiddleClickAction:@selector(middleSelect:)]; + scoped_nsobject<AutocompleteMatrix> matrix( + [[AutocompleteMatrix alloc] initWithPopupView:this]); [popup_ setContentView:matrix]; } } @@ -458,27 +439,8 @@ AutocompletePopupModel* AutocompletePopupViewMac::GetModel() { return model_.get(); } -void AutocompletePopupViewMac::OnClick() { - const NSInteger selectedRow = [[popup_ contentView] selectedRow]; - - // -1 means no cells were selected. This can happen if the user - // clicked and then dragged their mouse off the popup before - // releasing, so reset the selection and ignore the event. - if (selectedRow == -1) { - PaintUpdatesNow(); - } else { - OpenURLForRow(selectedRow, false); - } -} - -void AutocompletePopupViewMac::OnMiddleClick() { - OpenURLForRow([[popup_ contentView] highlightedRow], true); -} - void AutocompletePopupViewMac::OpenURLForRow(int row, bool force_background) { - if (row == -1) { - return; - } + DCHECK_GE(row, 0); WindowOpenDisposition disposition = NEW_BACKGROUND_TAB; if (!force_background) { @@ -576,11 +538,11 @@ void AutocompletePopupViewMac::OpenURLForRow(int row, bool force_background) { options |= NSTrackingActiveInActiveApp; options |= NSTrackingInVisibleRect; - NSTrackingArea* trackingArea = - [[[NSTrackingArea alloc] initWithRect:[self frame] - options:options - owner:self - userInfo:nil] autorelease]; + scoped_nsobject<NSTrackingArea> trackingArea( + [[NSTrackingArea alloc] initWithRect:[self frame] + options:options + owner:self + userInfo:nil]); [self addTrackingArea:trackingArea]; } @@ -589,9 +551,11 @@ void AutocompletePopupViewMac::OpenURLForRow(int row, bool force_background) { [super updateTrackingAreas]; } -- initWithFrame:(NSRect)frame { - self = [super initWithFrame:frame]; +- initWithPopupView:(AutocompletePopupViewMac*)popupView { + self = [super initWithFrame:NSZeroRect]; if (self) { + popupView_ = popupView; + [self setCellClass:[AutocompleteButtonCell class]]; // Cells pack with no spacing. @@ -609,6 +573,10 @@ void AutocompletePopupViewMac::OpenURLForRow(int row, bool force_background) { return self; } +- (void)setPopupView:(AutocompletePopupViewMac*)popupView { + popupView_ = popupView; +} + - (void)highlightRowAt:(NSInteger)rowIndex { // highlightCell will be nil if rowIndex is out of range, so no cell // will be highlighted. @@ -666,8 +634,55 @@ void AutocompletePopupViewMac::OpenURLForRow(int row, bool force_background) { // location, but make sure the user is getting the right feedback. [self highlightRowUnder:theEvent]; - // This does the right thing if target is nil. - [NSApp sendAction:middleClickAction_ to:[self target] from:self]; + const NSInteger highlightedRow = [self highlightedRow]; + if (highlightedRow != -1) { + DCHECK(popupView_); + popupView_->OpenURLForRow(highlightedRow, true); + } +} + +// Select cell under |theEvent|, returning YES if a selection is made. +- (BOOL)selectCellForEvent:(NSEvent*)theEvent { + NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + + NSInteger row, column; + if ([self getRow:&row column:&column forPoint:point]) { + DCHECK_EQ(column, 0); + [self selectCellAtRow:row column:column]; + return YES; + } + return NO; +} + +// Track the mouse until released, keeping the cell under the mouse +// selected. If the mouse wanders off-view, revert to the +// originally-selected cell. If the mouse is released over a cell, +// call |popupView_| to open the row's URL. +- (void)mouseDown:(NSEvent*)theEvent { + NSCell* selectedCell = [self selectedCell]; + + // Clear any existing highlight. + [self highlightRowAt:-1]; + + do { + if (![self selectCellForEvent:theEvent]) { + [self selectCell:selectedCell]; + } + + const NSUInteger mask = NSLeftMouseUpMask | NSLeftMouseDraggedMask; + theEvent = [[self window] nextEventMatchingMask:mask]; + } while ([theEvent type] == NSLeftMouseDragged); + + // Do not message |popupView_| if released outside view. + if (![self selectCellForEvent:theEvent]) { + [self selectCell:selectedCell]; + } else { + const NSInteger selectedRow = [self selectedRow]; + DCHECK_GE(selectedRow, 0); + + DCHECK(popupView_); + popupView_->OpenURLForRow(selectedRow, false); + } } - (NSInteger)highlightedRow { @@ -681,10 +696,6 @@ void AutocompletePopupViewMac::OpenURLForRow(int row, bool force_background) { return -1; } -- (void)setMiddleClickAction:(SEL)anAction { - middleClickAction_ = anAction; -} - - (BOOL)isOpaque { return NO; } @@ -705,30 +716,3 @@ void AutocompletePopupViewMac::OpenURLForRow(int row, bool force_background) { } @end - -@implementation AutocompleteMatrixTarget - -- initWithPopupView:(AutocompletePopupViewMac*)view { - self = [super init]; - if (self) { - popup_view_ = view; - } - return self; -} - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [super dealloc]; -} - -- (void)select:(id)sender { - DCHECK(popup_view_); - popup_view_->OnClick(); -} - -- (void)middleSelect:(id)sender { - DCHECK(popup_view_); - popup_view_->OnMiddleClick(); -} - -@end |