Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(389)

Side by Side Diff: chrome/browser/ui/cocoa/omnibox/omnibox_popup_matrix.mm

Issue 1099403005: [AiS] changing mac omnibox suggestions form NSMatrix to NSTableView (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Reduced cell redraw on hover Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/ui/cocoa/omnibox/omnibox_popup_matrix.h" 5 #import "chrome/browser/ui/cocoa/omnibox/omnibox_popup_matrix.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/mac/foundation_util.h"
8 #import "chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.h" 9 #import "chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.h"
9 10
10 namespace { 11 namespace {
11 12
12 // NSEvent -buttonNumber for middle mouse button. 13 // NSEvent -buttonNumber for middle mouse button.
13 const NSInteger kMiddleButtonNumber = 2; 14 const NSInteger kMiddleButtonNumber = 2;
14 15
15 } // namespace 16 } // namespace
16 17
17 @interface OmniboxPopupMatrix() 18 @implementation OmniboxPopupTableController
19
20 - (id)init {
21 if ((self = [super init])) {
22 array_.reset([[NSMutableArray alloc] init]);
23 hovered_index_ = -1;
24 }
25 return self;
26 }
27
28 - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView {
29 return [array_ count];
30 }
31
32 - (id)tableView:(NSTableView*)aTableView
33 objectValueForTableColumn:(NSTableColumn*)aTableColumn
34 row:(NSInteger)rowIndex {
35 return [array_ objectAtIndex:rowIndex];
36 }
37
38 - (void)tableView:(NSTableView*)aTableView
groby-ooo-7-16 2015/05/07 02:39:59 I don't think we use the "aSmalltalkProperty" nota
dschuyler 2015/05/07 20:53:10 Done.
39 willDisplayCell:(id)aCell
40 forTableColumn:(NSTableColumn*)aTableColumn
41 row:(NSInteger)rowIndex {
42 OmniboxPopupCell* popupCell =
43 base::mac::ObjCCastStrict<OmniboxPopupCell>(aCell);
44 NSDictionary* dictionary = [array_ objectAtIndex:rowIndex];
45
46 NSImage* image = [dictionary objectForKey:@"image"];
47 [popupCell setImage:image];
48
49 AutocompleteMatchWrapper* acm = [dictionary objectForKey:@"match"];
50 [popupCell setMatch:acm->match_];
51
52 [popupCell
53 setState:([aTableView selectedRow] == rowIndex) ? NSOnState : NSOffState];
54 [popupCell highlight:(hovered_index_ == rowIndex)
55 withFrame:[aTableView bounds]
56 inView:aTableView];
57 }
58
59 - (NSInteger)highlightedRow {
60 return hovered_index_;
61 }
62
63 - (NSRect)rectForRow:(NSInteger)rowIndex {
64 NSRect rect = NSZeroRect;
65 if (rowIndex != -1) {
66 rect = [[[array_ objectAtIndex:rowIndex] objectForKey:@"rect"] rectValue];
67 }
68 return rect;
69 }
70
71 - (void)highlightRowAt:(NSInteger)rowIndex withView:(NSView*)view {
72 hovered_index_ = rowIndex;
73 }
74
75 - (void)setDataArray:(NSArray*)array {
76 hovered_index_ = -1;
77 array_.reset([array retain]);
78 }
79
80 - (CGFloat)tableView:(NSTableView*)tableView heightOfRow:(NSInteger)row {
81 NSRect rect = [[[array_ objectAtIndex:row] objectForKey:@"rect"] rectValue];
82 return rect.size.height;
83 }
84
85 @end
86
87 @interface OmniboxPopupMatrix ()
18 - (void)resetTrackingArea; 88 - (void)resetTrackingArea;
19 - (void)highlightRowAt:(NSInteger)rowIndex;
20 - (void)highlightRowUnder:(NSEvent*)theEvent; 89 - (void)highlightRowUnder:(NSEvent*)theEvent;
21 - (BOOL)selectCellForEvent:(NSEvent*)theEvent; 90 - (BOOL)selectCellForEvent:(NSEvent*)theEvent;
22 @end 91 @end
23 92
24 @implementation OmniboxPopupMatrix 93 @implementation OmniboxPopupMatrix
25 94
26 - (id)initWithDelegate:(OmniboxPopupMatrixDelegate*)delegate { 95 - (id)initWithDelegate:(OmniboxPopupMatrixDelegate*)delegate {
groby-ooo-7-16 2015/05/07 02:39:59 It's not really a MatrixDelegate any more, is it?
dschuyler 2015/05/07 20:53:10 The Delegate names will change to observer.
27 if ((self = [super initWithFrame:NSZeroRect])) { 96 if ((self = [super initWithFrame:NSZeroRect])) {
28 delegate_ = delegate; 97 delegate_ = delegate;
29 [self setCellClass:[OmniboxPopupCell class]]; 98 controller_.reset([[OmniboxPopupTableController alloc] init]);
99
100 base::scoped_nsobject<NSTableColumn> column(
101 [[NSTableColumn alloc] initWithIdentifier:@"MainCell"]);
102 [column setDataCell:[[[OmniboxPopupCell alloc] init] autorelease]];
103 [self addTableColumn:column];
104
105 [self setDelegate:controller_];
106 [self setDataSource:controller_];
30 107
31 // Cells pack with no spacing. 108 // Cells pack with no spacing.
32 [self setIntercellSpacing:NSMakeSize(0.0, 0.0)]; 109 [self setIntercellSpacing:NSMakeSize(0.0, 0.0)];
33 110
34 [self setDrawsBackground:YES]; 111 [self setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone];
35 [self setBackgroundColor:[NSColor controlBackgroundColor]]; 112 [self setBackgroundColor:[NSColor controlBackgroundColor]];
36 [self renewRows:0 columns:1];
37 [self setAllowsEmptySelection:YES]; 113 [self setAllowsEmptySelection:YES];
38 [self setMode:NSRadioModeMatrix]; 114 [self deselectAll:self];
39 [self deselectAllCells];
40 115
41 [self resetTrackingArea]; 116 [self resetTrackingArea];
42 } 117 }
43 return self; 118 return self;
44 } 119 }
45 120
46 - (void)setDelegate:(OmniboxPopupMatrixDelegate*)delegate { 121 - (void)setTheDelegate:(OmniboxPopupMatrixDelegate*)delegate {
47 delegate_ = delegate; 122 delegate_ = delegate;
48 } 123 }
49 124
50 - (NSInteger)highlightedRow {
51 NSArray* cells = [self cells];
52 const NSUInteger count = [cells count];
53 for(NSUInteger i = 0; i < count; ++i) {
54 if ([[cells objectAtIndex:i] isHighlighted]) {
55 return i;
56 }
57 }
58 return -1;
59 }
60
61 - (void)updateTrackingAreas { 125 - (void)updateTrackingAreas {
62 [self resetTrackingArea]; 126 [self resetTrackingArea];
63 [super updateTrackingAreas]; 127 [super updateTrackingAreas];
64 } 128 }
65 129
66 // Callbacks from tracking area. 130 // Callbacks from tracking area.
67 - (void)mouseEntered:(NSEvent*)theEvent { 131 - (void)mouseEntered:(NSEvent*)theEvent {
68 [self highlightRowUnder:theEvent]; 132 [self highlightRowUnder:theEvent];
69 } 133 }
70 134
71 - (void)mouseMoved:(NSEvent*)theEvent { 135 - (void)mouseMoved:(NSEvent*)theEvent {
72 [self highlightRowUnder:theEvent]; 136 [self highlightRowUnder:theEvent];
73 } 137 }
74 138
75 - (void)mouseExited:(NSEvent*)theEvent { 139 - (void)mouseExited:(NSEvent*)theEvent {
76 [self highlightRowAt:-1]; 140 [controller_ highlightRowAt:-1 withView:self];
77 } 141 }
78 142
79 // The tracking area events aren't forwarded during a drag, so handle 143 // The tracking area events aren't forwarded during a drag, so handle
80 // highlighting manually for middle-click and middle-drag. 144 // highlighting manually for middle-click and middle-drag.
81 - (void)otherMouseDown:(NSEvent*)theEvent { 145 - (void)otherMouseDown:(NSEvent*)theEvent {
82 if ([theEvent buttonNumber] == kMiddleButtonNumber) { 146 if ([theEvent buttonNumber] == kMiddleButtonNumber) {
83 [self highlightRowUnder:theEvent]; 147 [self highlightRowUnder:theEvent];
84 } 148 }
85 [super otherMouseDown:theEvent]; 149 [super otherMouseDown:theEvent];
86 } 150 }
87 151
88 - (void)otherMouseDragged:(NSEvent*)theEvent { 152 - (void)otherMouseDragged:(NSEvent*)theEvent {
89 if ([theEvent buttonNumber] == kMiddleButtonNumber) { 153 if ([theEvent buttonNumber] == kMiddleButtonNumber) {
90 [self highlightRowUnder:theEvent]; 154 [self highlightRowUnder:theEvent];
91 } 155 }
92 [super otherMouseDragged:theEvent]; 156 [super otherMouseDragged:theEvent];
93 } 157 }
94 158
95 - (void)otherMouseUp:(NSEvent*)theEvent { 159 - (void)otherMouseUp:(NSEvent*)theEvent {
96 // Only intercept middle button. 160 // Only intercept middle button.
97 if ([theEvent buttonNumber] != kMiddleButtonNumber) { 161 if ([theEvent buttonNumber] != kMiddleButtonNumber) {
98 [super otherMouseUp:theEvent]; 162 [super otherMouseUp:theEvent];
99 return; 163 return;
100 } 164 }
101 165
102 // -otherMouseDragged: should always have been called at this location, but 166 // -otherMouseDragged: should always have been called at this location, but
103 // make sure the user is getting the right feedback. 167 // make sure the user is getting the right feedback.
104 [self highlightRowUnder:theEvent]; 168 [self highlightRowUnder:theEvent];
105 169
106 const NSInteger highlightedRow = [self highlightedRow]; 170 const NSInteger highlightedRow = [controller_ highlightedRow];
107 if (highlightedRow != -1) { 171 if (highlightedRow != -1) {
108 DCHECK(delegate_); 172 DCHECK(delegate_);
109 delegate_->OnMatrixRowMiddleClicked(self, highlightedRow); 173 delegate_->OnMatrixRowMiddleClicked(self, highlightedRow);
110 } 174 }
111 } 175 }
112 176
113 // Track the mouse until released, keeping the cell under the mouse selected. 177 // Track the mouse until released, keeping the cell under the mouse selected.
114 // If the mouse wanders off-view, revert to the originally-selected cell. If 178 // If the mouse wanders off-view, revert to the originally-selected cell. If
115 // the mouse is released over a cell, call the delegate to open the row's URL. 179 // the mouse is released over a cell, call the delegate to open the row's URL.
116 - (void)mouseDown:(NSEvent*)theEvent { 180 - (void)mouseDown:(NSEvent*)theEvent {
117 NSCell* selectedCell = [self selectedCell]; 181 NSCell* selectedCell = [self selectedCell];
118 182
119 // Clear any existing highlight. 183 // Clear any existing highlight.
120 [self highlightRowAt:-1]; 184 [controller_ highlightRowAt:-1 withView:self];
121 185
122 do { 186 do {
123 if (![self selectCellForEvent:theEvent]) { 187 if (![self selectCellForEvent:theEvent]) {
124 [self selectCell:selectedCell]; 188 [self selectCell:selectedCell];
125 } 189 }
126 190
127 const NSUInteger mask = NSLeftMouseUpMask | NSLeftMouseDraggedMask; 191 const NSUInteger mask = NSLeftMouseUpMask | NSLeftMouseDraggedMask;
128 theEvent = [[self window] nextEventMatchingMask:mask]; 192 theEvent = [[self window] nextEventMatchingMask:mask];
129 } while ([theEvent type] == NSLeftMouseDragged); 193 } while ([theEvent type] == NSLeftMouseDragged);
130 194
131 // Do not message the delegate if released outside view. 195 // Do not message the delegate if released outside view.
132 if (![self selectCellForEvent:theEvent]) { 196 if (![self selectCellForEvent:theEvent]) {
133 [self selectCell:selectedCell]; 197 [self selectCell:selectedCell];
134 } else { 198 } else {
135 const NSInteger selectedRow = [self selectedRow]; 199 const NSInteger selectedRow = [self selectedRow];
136 200
137 // No row could be selected if the model failed to update. 201 // No row could be selected if the model failed to update.
138 if (selectedRow == -1) { 202 if (selectedRow == -1) {
139 NOTREACHED(); 203 NOTREACHED();
140 return; 204 return;
141 } 205 }
142 206
143 DCHECK(delegate_); 207 DCHECK(delegate_);
144 delegate_->OnMatrixRowClicked(self, selectedRow); 208 delegate_->OnMatrixRowClicked(self, selectedRow);
145 } 209 }
146 } 210 }
147 211
212 - (void)selectRowAt:(NSInteger)rowIndex {
213 NSIndexSet* indexSet = [NSIndexSet indexSetWithIndex:rowIndex];
214 [self selectRowIndexes:indexSet byExtendingSelection:NO];
215 }
216
217 - (NSInteger)highlightedRow {
218 return [controller_ highlightedRow];
219 }
220
221 - (void)setDataArray:(NSArray*)array {
222 [controller_ setDataArray:array];
223 }
224
148 - (void)resetTrackingArea { 225 - (void)resetTrackingArea {
149 if (trackingArea_.get()) 226 if (trackingArea_.get())
150 [self removeTrackingArea:trackingArea_.get()]; 227 [self removeTrackingArea:trackingArea_.get()];
151 228
152 trackingArea_.reset([[CrTrackingArea alloc] 229 trackingArea_.reset([[CrTrackingArea alloc]
153 initWithRect:[self frame] 230 initWithRect:[self frame]
154 options:NSTrackingMouseEnteredAndExited | 231 options:NSTrackingMouseEnteredAndExited |
155 NSTrackingMouseMoved | 232 NSTrackingMouseMoved |
156 NSTrackingActiveInActiveApp | 233 NSTrackingActiveInActiveApp |
157 NSTrackingInVisibleRect 234 NSTrackingInVisibleRect
158 owner:self 235 owner:self
159 userInfo:nil]); 236 userInfo:nil]);
160 [self addTrackingArea:trackingArea_.get()]; 237 [self addTrackingArea:trackingArea_.get()];
161 } 238 }
162 239
163 - (void)highlightRowAt:(NSInteger)rowIndex {
164 // highlightCell will be nil if rowIndex is out of range, so no cell will be
165 // highlighted.
166 NSCell* highlightCell = [self cellAtRow:rowIndex column:0];
167
168 for (NSCell* cell in [self cells]) {
169 [cell setHighlighted:(cell == highlightCell)];
170 }
171 }
172
173 - (void)highlightRowUnder:(NSEvent*)theEvent { 240 - (void)highlightRowUnder:(NSEvent*)theEvent {
174 NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil]; 241 NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
175 NSInteger row, column; 242 NSInteger oldRow = [controller_ highlightedRow];
176 if ([self getRow:&row column:&column forPoint:point]) { 243 NSInteger newRow = [self rowAtPoint:point];
177 [self highlightRowAt:row]; 244 if (oldRow != newRow) {
178 } else { 245 [controller_ highlightRowAt:newRow withView:self];
179 [self highlightRowAt:-1]; 246 [self setNeedsDisplayInRect:[controller_ rectForRow:oldRow]];
247 [self setNeedsDisplayInRect:[controller_ rectForRow:newRow]];
180 } 248 }
181 } 249 }
182 250
183 // Select cell under |theEvent|, returning YES if a selection is made.
184 - (BOOL)selectCellForEvent:(NSEvent*)theEvent { 251 - (BOOL)selectCellForEvent:(NSEvent*)theEvent {
185 NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil]; 252 NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
186 253
187 NSInteger row, column; 254 NSInteger row = [self rowAtPoint:point];
188 if ([self getRow:&row column:&column forPoint:point]) { 255 [self selectRowAt:row];
189 DCHECK_EQ(column, 0); 256 if (row != -1) {
190 DCHECK(delegate_); 257 DCHECK(delegate_);
191 delegate_->OnMatrixRowSelected(self, row); 258 delegate_->OnMatrixRowSelected(self, row);
192 return YES; 259 return YES;
193 } 260 }
194 return NO; 261 return NO;
195 } 262 }
196 263
197 @end 264 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698