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

Side by Side Diff: chrome/browser/ui/cocoa/website_settings/chooser_bubble_ui_cocoa.mm

Issue 2748443005: Rename website_settings UI folders to permission_bubble. (Closed)
Patch Set: Rebase. Created 3 years, 9 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
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "chrome/browser/ui/cocoa/website_settings/chooser_bubble_ui_cocoa.h"
6
7 #include <stddef.h>
8
9 #include <algorithm>
10 #include <cmath>
11
12 #include "base/mac/scoped_nsobject.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/strings/sys_string_conversions.h"
15 #include "chrome/browser/chooser_controller/chooser_controller.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_window.h"
18 #import "chrome/browser/ui/cocoa/base_bubble_controller.h"
19 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
20 #import "chrome/browser/ui/cocoa/browser_window_utils.h"
21 #import "chrome/browser/ui/cocoa/device_chooser_content_view_cocoa.h"
22 #import "chrome/browser/ui/cocoa/info_bubble_view.h"
23 #import "chrome/browser/ui/cocoa/info_bubble_window.h"
24 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
25 #include "chrome/browser/ui/website_settings/chooser_bubble_delegate.h"
26 #include "components/bubble/bubble_controller.h"
27 #include "content/public/browser/native_web_keyboard_event.h"
28 #include "ui/base/cocoa/cocoa_base_utils.h"
29 #include "ui/base/cocoa/window_size_constants.h"
30
31 std::unique_ptr<BubbleUi> ChooserBubbleDelegate::BuildBubbleUi() {
32 return base::MakeUnique<ChooserBubbleUiCocoa>(browser_,
33 std::move(chooser_controller_));
34 }
35
36 @interface ChooserBubbleUiController
37 : BaseBubbleController<NSTableViewDataSource, NSTableViewDelegate> {
38 @private
39 // Bridge to the C++ class that created this object.
40 ChooserBubbleUiCocoa* bridge_; // Weak.
41 bool buttonPressed_;
42
43 base::scoped_nsobject<DeviceChooserContentViewCocoa>
44 deviceChooserContentView_;
45 NSTableView* tableView_; // Weak.
46 NSButton* connectButton_; // Weak.
47 NSButton* cancelButton_; // Weak.
48
49 Browser* browser_; // Weak.
50 }
51
52 // Designated initializer. |browser| and |bridge| must both be non-nil.
53 - (id)initWithBrowser:(Browser*)browser
54 chooserController:(std::unique_ptr<ChooserController>)chooserController
55 bridge:(ChooserBubbleUiCocoa*)bridge;
56
57 // Makes the bubble visible.
58 - (void)show;
59
60 // Will reposition the bubble based in case the anchor or parent should change.
61 - (void)updateAnchorPosition;
62
63 // Will calculate the expected anchor point for this bubble.
64 // Should only be used outside this class for tests.
65 - (NSPoint)getExpectedAnchorPoint;
66
67 // Returns true if the browser has support for the location bar.
68 // Should only be used outside this class for tests.
69 - (bool)hasLocationBar;
70
71 // Update |tableView_| when chooser options changed.
72 - (void)updateTableView;
73
74 // Determines if the bubble has an anchor in a corner or no anchor at all.
75 - (info_bubble::BubbleArrowLocation)getExpectedArrowLocation;
76
77 // Returns the expected parent for this bubble.
78 - (NSWindow*)getExpectedParentWindow;
79
80 // Called when the "Connect" button is pressed.
81 - (void)onConnect:(id)sender;
82
83 // Called when the "Cancel" button is pressed.
84 - (void)onCancel:(id)sender;
85
86 @end
87
88 @implementation ChooserBubbleUiController
89
90 - (id)initWithBrowser:(Browser*)browser
91 chooserController:(std::unique_ptr<ChooserController>)chooserController
92 bridge:(ChooserBubbleUiCocoa*)bridge {
93 DCHECK(browser);
94 DCHECK(chooserController);
95 DCHECK(bridge);
96
97 browser_ = browser;
98
99 base::scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc]
100 initWithContentRect:ui::kWindowSizeDeterminedLater
101 styleMask:NSBorderlessWindowMask
102 backing:NSBackingStoreBuffered
103 defer:NO]);
104 [window setAllowedAnimations:info_bubble::kAnimateNone];
105 [window setReleasedWhenClosed:NO];
106 if ((self = [super initWithWindow:window
107 parentWindow:[self getExpectedParentWindow]
108 anchoredAt:NSZeroPoint])) {
109 [self setShouldCloseOnResignKey:YES];
110 [self setShouldOpenAsKeyWindow:YES];
111 [[self bubble] setArrowLocation:[self getExpectedArrowLocation]];
112 bridge_ = bridge;
113 NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
114 [center addObserver:self
115 selector:@selector(parentWindowDidMove:)
116 name:NSWindowDidMoveNotification
117 object:[self getExpectedParentWindow]];
118
119 base::string16 chooserTitle = chooserController->GetTitle();
120 deviceChooserContentView_.reset([[DeviceChooserContentViewCocoa alloc]
121 initWithChooserTitle:base::SysUTF16ToNSString(chooserTitle)
122 chooserController:std::move(chooserController)]);
123
124 tableView_ = [deviceChooserContentView_ tableView];
125 connectButton_ = [deviceChooserContentView_ connectButton];
126 cancelButton_ = [deviceChooserContentView_ cancelButton];
127
128 [connectButton_ setTarget:self];
129 [connectButton_ setAction:@selector(onConnect:)];
130 [cancelButton_ setTarget:self];
131 [cancelButton_ setAction:@selector(onCancel:)];
132 [tableView_ setDelegate:self];
133 [tableView_ setDataSource:self];
134
135 [[[self window] contentView] addSubview:deviceChooserContentView_.get()];
136 }
137
138 return self;
139 }
140
141 - (void)windowWillClose:(NSNotification*)notification {
142 [[NSNotificationCenter defaultCenter]
143 removeObserver:self
144 name:NSWindowDidMoveNotification
145 object:nil];
146 if (!buttonPressed_)
147 [deviceChooserContentView_ close];
148 bridge_->OnBubbleClosing();
149 [super windowWillClose:notification];
150 }
151
152 - (void)parentWindowWillToggleFullScreen:(NSNotification*)notification {
153 // Override the base class implementation, which would have closed the bubble.
154 }
155
156 - (void)parentWindowDidResize:(NSNotification*)notification {
157 [self setAnchorPoint:[self getExpectedAnchorPoint]];
158 }
159
160 - (void)parentWindowDidMove:(NSNotification*)notification {
161 DCHECK(bridge_);
162 [self setAnchorPoint:[self getExpectedAnchorPoint]];
163 }
164
165 - (void)show {
166 NSRect bubbleFrame =
167 [[self window] frameRectForContentRect:[deviceChooserContentView_ frame]];
168 if ([[self window] isVisible]) {
169 // Unfortunately, calling -setFrame followed by -setFrameOrigin (called
170 // within -setAnchorPoint) causes flickering. Avoid the flickering by
171 // manually adjusting the new frame's origin so that the top left stays the
172 // same, and only calling -setFrame.
173 NSRect currentWindowFrame = [[self window] frame];
174 bubbleFrame.origin = currentWindowFrame.origin;
175 bubbleFrame.origin.y = bubbleFrame.origin.y +
176 currentWindowFrame.size.height -
177 bubbleFrame.size.height;
178 [[self window] setFrame:bubbleFrame display:YES];
179 } else {
180 [[self window] setFrame:bubbleFrame display:NO];
181 [self setAnchorPoint:[self getExpectedAnchorPoint]];
182 [self showWindow:nil];
183 [[self window] makeFirstResponder:nil];
184 [[self window] setInitialFirstResponder:tableView_];
185 }
186 }
187
188 - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView {
189 return [deviceChooserContentView_ numberOfOptions];
190 }
191
192 - (NSView*)tableView:(NSTableView*)tableView
193 viewForTableColumn:(NSTableColumn*)tableColumn
194 row:(NSInteger)row {
195 return [deviceChooserContentView_ createTableRowView:row].autorelease();
196 }
197
198 - (BOOL)tableView:(NSTableView*)aTableView
199 shouldEditTableColumn:(NSTableColumn*)aTableColumn
200 row:(NSInteger)rowIndex {
201 return NO;
202 }
203
204 - (CGFloat)tableView:(NSTableView*)tableView heightOfRow:(NSInteger)row {
205 return [deviceChooserContentView_ tableRowViewHeight:row];
206 }
207
208 - (void)updateTableView {
209 [deviceChooserContentView_ updateTableView];
210 }
211
212 - (void)tableViewSelectionDidChange:(NSNotification*)aNotification {
213 [deviceChooserContentView_ updateContentRowColor];
214 [connectButton_ setEnabled:[tableView_ numberOfSelectedRows] > 0];
215 }
216
217 // Selection changes (while the mouse button is still down).
218 - (void)tableViewSelectionIsChanging:(NSNotification*)aNotification {
219 [deviceChooserContentView_ updateContentRowColor];
220 [connectButton_ setEnabled:[tableView_ numberOfSelectedRows] > 0];
221 }
222
223 - (void)updateAnchorPosition {
224 [self setParentWindow:[self getExpectedParentWindow]];
225 [self setAnchorPoint:[self getExpectedAnchorPoint]];
226 }
227
228 - (NSPoint)getExpectedAnchorPoint {
229 NSPoint anchor;
230 if ([self hasLocationBar]) {
231 LocationBarViewMac* locationBar =
232 [[[self getExpectedParentWindow] windowController] locationBarBridge];
233 anchor = locationBar->GetPageInfoBubblePoint();
234 } else {
235 // Center the bubble if there's no location bar.
236 NSRect contentFrame = [[[self getExpectedParentWindow] contentView] frame];
237 anchor = NSMakePoint(NSMidX(contentFrame), NSMaxY(contentFrame));
238 }
239
240 return ui::ConvertPointFromWindowToScreen([self getExpectedParentWindow],
241 anchor);
242 }
243
244 - (bool)hasLocationBar {
245 return browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
246 }
247
248 - (info_bubble::BubbleArrowLocation)getExpectedArrowLocation {
249 return [self hasLocationBar] ? info_bubble::kTopLeading
250 : info_bubble::kNoArrow;
251 }
252
253 - (NSWindow*)getExpectedParentWindow {
254 DCHECK(browser_->window());
255 return browser_->window()->GetNativeWindow();
256 }
257
258 + (CGFloat)matchWidthsOf:(NSView*)viewA andOf:(NSView*)viewB {
259 NSRect frameA = [viewA frame];
260 NSRect frameB = [viewB frame];
261 CGFloat width = std::max(NSWidth(frameA), NSWidth(frameB));
262 [viewA setFrameSize:NSMakeSize(width, NSHeight(frameA))];
263 [viewB setFrameSize:NSMakeSize(width, NSHeight(frameB))];
264 return width;
265 }
266
267 + (void)alignCenterOf:(NSView*)viewA verticallyToCenterOf:(NSView*)viewB {
268 NSRect frameA = [viewA frame];
269 NSRect frameB = [viewB frame];
270 frameA.origin.y =
271 NSMinY(frameB) + std::floor((NSHeight(frameB) - NSHeight(frameA)) / 2);
272 [viewA setFrameOrigin:frameA.origin];
273 }
274
275 - (void)onConnect:(id)sender {
276 buttonPressed_ = true;
277 [deviceChooserContentView_ accept];
278 if (self.bubbleReference)
279 self.bubbleReference->CloseBubble(BUBBLE_CLOSE_ACCEPTED);
280 [self close];
281 }
282
283 - (void)onCancel:(id)sender {
284 buttonPressed_ = true;
285 [deviceChooserContentView_ cancel];
286 if (self.bubbleReference)
287 self.bubbleReference->CloseBubble(BUBBLE_CLOSE_CANCELED);
288 [self close];
289 }
290
291 @end
292
293 ChooserBubbleUiCocoa::ChooserBubbleUiCocoa(
294 Browser* browser,
295 std::unique_ptr<ChooserController> chooser_controller)
296 : browser_(browser),
297 chooser_bubble_ui_controller_(nil) {
298 DCHECK(browser_);
299 DCHECK(chooser_controller);
300 chooser_bubble_ui_controller_ = [[ChooserBubbleUiController alloc]
301 initWithBrowser:browser_
302 chooserController:std::move(chooser_controller)
303 bridge:this];
304 }
305
306 ChooserBubbleUiCocoa::~ChooserBubbleUiCocoa() {
307 if (chooser_bubble_ui_controller_) {
308 [chooser_bubble_ui_controller_ close];
309 chooser_bubble_ui_controller_ = nil;
310 }
311 }
312
313 void ChooserBubbleUiCocoa::Show(BubbleReference bubble_reference) {
314 [chooser_bubble_ui_controller_ setBubbleReference:bubble_reference];
315 [chooser_bubble_ui_controller_ show];
316 [chooser_bubble_ui_controller_ updateTableView];
317 }
318
319 void ChooserBubbleUiCocoa::Close() {
320 if (chooser_bubble_ui_controller_) {
321 [chooser_bubble_ui_controller_ close];
322 chooser_bubble_ui_controller_ = nil;
323 }
324 }
325
326 void ChooserBubbleUiCocoa::UpdateAnchorPosition() {
327 if (chooser_bubble_ui_controller_)
328 [chooser_bubble_ui_controller_ updateAnchorPosition];
329 }
330
331 void ChooserBubbleUiCocoa::OnBubbleClosing() {
332 chooser_bubble_ui_controller_ = nil;
333 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698