summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm
diff options
context:
space:
mode:
authorshess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-19 01:19:15 +0000
committershess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-19 01:19:15 +0000
commite7354bb9d013b913dedaa8a45e2243fb559cf60b (patch)
treed153ed2a1831d9158d5ccd4b33ed38d003605fc0 /chrome/browser/autocomplete/autocomplete_popup_view_mac.mm
parentee77fcf1bab6f960d3b452ce86703af602bcb6d6 (diff)
downloadchromium_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.mm168
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