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

Side by Side Diff: chrome/browser/ui/cocoa/infobars/media_stream_infobar_controller.mm

Issue 10802090: fixed the distorted behavior on the mediastreaminfobar on Mac (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: ready for review. Created 8 years, 5 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/infobars/media_stream_infobar_controller.h" 5 #import "chrome/browser/ui/cocoa/infobars/media_stream_infobar_controller.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 #include <string> 8 #include <string>
9 9
10 #import "base/sys_string_conversions.h" 10 #import "base/sys_string_conversions.h"
11 #include "base/utf_string_conversions.h" 11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/media/media_stream_devices_menu_model.h" 12 #include "chrome/browser/media/media_stream_devices_menu_model.h"
13 #include "chrome/browser/ui/cocoa/hover_close_button.h" 13 #include "chrome/browser/ui/cocoa/hover_close_button.h"
14 #include "chrome/browser/ui/cocoa/infobars/infobar.h" 14 #include "chrome/browser/ui/cocoa/infobars/infobar.h"
15 #import "chrome/browser/ui/cocoa/infobars/infobar_utilities.h"
15 #include "chrome/browser/ui/media_stream_infobar_delegate.h" 16 #include "chrome/browser/ui/media_stream_infobar_delegate.h"
16 #include "grit/generated_resources.h" 17 #include "grit/generated_resources.h"
17 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" 18 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
18 #include "ui/base/l10n/l10n_util.h" 19 #include "ui/base/l10n/l10n_util.h"
19 20
21 using InfoBarUtilities::CreateLabel;
22 using InfoBarUtilities::MoveControl;
23 using InfoBarUtilities::VerifyControlOrderAndSpacing;
20 using l10n_util::GetNSStringWithFixup; 24 using l10n_util::GetNSStringWithFixup;
21 25
22 static const CGFloat kSpaceBetweenControls = 8; 26 static const CGFloat kSpaceBetweenControls = 8;
Scott Hess - ex-Googler 2012/07/25 18:28:15 Should use of this also be replaced by spaceBetwee
no longer working on chromium 2012/07/26 10:17:47 removed
23 27
24 InfoBar* MediaStreamInfoBarDelegate::CreateInfoBar(InfoBarTabHelper* owner) { 28 InfoBar* MediaStreamInfoBarDelegate::CreateInfoBar(InfoBarTabHelper* owner) {
25 MediaStreamInfoBarController* infobar_controller = 29 MediaStreamInfoBarController* infobar_controller =
26 [[MediaStreamInfoBarController alloc] initWithDelegate:this 30 [[MediaStreamInfoBarController alloc] initWithDelegate:this
27 owner:owner]; 31 owner:owner];
28 return new InfoBar(infobar_controller, this); 32 return new InfoBar(infobar_controller, this);
29 } 33 }
30 34
31 namespace { 35 namespace {
32 36
33 // Puts |toMove| to the right or left of |anchor|. 37 // Puts |toMove| to the right or left of |anchor|.
34 void SizeAndPlaceControl(NSView* toModify, NSView* anchor, bool after) { 38 void SizeAndPlaceControl(NSView* toModify, NSView* anchor, bool after) {
Scott Hess - ex-Googler 2012/07/25 18:28:15 AFAICT, this is the only user of kSpaceBetweenCont
no longer working on chromium 2012/07/26 10:17:47 Good catch. They are removed now.
35 [GTMUILocalizerAndLayoutTweaker sizeToFitView:toModify]; 39 [GTMUILocalizerAndLayoutTweaker sizeToFitView:toModify];
36 NSRect toModifyFrame = [toModify frame]; 40 NSRect toModifyFrame = [toModify frame];
37 NSRect anchorFrame = [anchor frame]; 41 NSRect anchorFrame = [anchor frame];
38 if (after) { 42 if (after) {
39 toModifyFrame.origin.x = NSMaxX(anchorFrame) + kSpaceBetweenControls; 43 toModifyFrame.origin.x = NSMaxX(anchorFrame) + kSpaceBetweenControls;
40 } else { 44 } else {
41 toModifyFrame.origin.x = NSMinX(anchorFrame) - kSpaceBetweenControls - 45 toModifyFrame.origin.x = NSMinX(anchorFrame) - kSpaceBetweenControls -
42 NSWidth(toModifyFrame); 46 NSWidth(toModifyFrame);
43 } 47 }
44 [toModify setFrame:toModifyFrame]; 48 [toModify setFrame:toModifyFrame];
45 } 49 }
46 50
47 } // namespace 51 } // namespace
48 52
49 53
50 @interface MediaStreamInfoBarController(Private) 54 @interface MediaStreamInfoBarController(Private)
51 55
52 // Adds text for all buttons and text fields. 56 // Adds text for all buttons and text fields.
53 - (void)setLabelTexts; 57 - (void)setLabelTexts;
54 58
55 // Populates the device menu with device id:s. 59 // Populates the device menu with device id:s.
56 - (void)rebuildDeviceMenu; 60 - (void)rebuildDeviceMenu:(BOOL)hideTitle;
57 61
58 // Arranges all buttons and pup-up menu relative each other. 62 // Arranges all buttons and pup-up menu relative each other.
59 - (void)arrangeInfobarLayout; 63 - (void)arrangeInfobarLayout;
60 64
65 // Create all the components for the infobar.
66 - (void)constructView;
67
68 // Used for setting the correct styles on each label and button.
69 - (NSArray*)allControls;
70
61 @end 71 @end
62 72
63 73
64 @implementation MediaStreamInfoBarController 74 @implementation MediaStreamInfoBarController
65 75
66 - (id)initWithDelegate:(MediaStreamInfoBarDelegate*)delegate 76 - (id)initWithDelegate:(MediaStreamInfoBarDelegate*)delegate
67 owner:(InfoBarTabHelper*)owner { 77 owner:(InfoBarTabHelper*)owner {
68 if (self = [super initWithDelegate:delegate owner:owner]) { 78 if (self = [super initWithDelegate:delegate owner:owner]) {
69 deviceMenuModel_.reset(new MediaStreamDevicesMenuModel(delegate)); 79 deviceMenuModel_.reset(new MediaStreamDevicesMenuModel(delegate));
70
71 label1_.reset([[NSTextField alloc] init]);
72 [label1_ setEditable:NO];
73 [label1_ setDrawsBackground:NO];
74 [label1_ setBordered:NO];
75
76 [okButton_ setBezelStyle:NSTexturedRoundedBezelStyle];
77 [cancelButton_ setBezelStyle:NSTexturedRoundedBezelStyle];
78
79 deviceMenu_.reset([[NSPopUpButton alloc] init]);
80 [deviceMenu_ setBezelStyle:NSTexturedRoundedBezelStyle];
81 [deviceMenu_ setAutoresizingMask:NSViewMaxXMargin];
82 [[deviceMenu_ cell] setArrowPosition:NSPopUpArrowAtBottom];
83 NSMenu* menu = [deviceMenu_ menu];
84 [menu setDelegate:nil];
85 [menu setAutoenablesItems:NO];
86 } 80 }
87 return self; 81 return self;
88 } 82 }
89 83
90 - (void)dealloc { 84 - (void)dealloc {
91 [[NSNotificationCenter defaultCenter] removeObserver:self]; 85 [[NSNotificationCenter defaultCenter] removeObserver:self];
92 [deviceMenu_ removeAllItems]; 86 [deviceMenu_ removeAllItems];
93 [super dealloc]; 87 [super dealloc];
94 } 88 }
95 89
(...skipping 17 matching lines...) Expand all
113 - (void)cancel:(id)sender { 107 - (void)cancel:(id)sender {
114 static_cast<MediaStreamInfoBarDelegate*>([self delegate])->Deny(); 108 static_cast<MediaStreamInfoBarDelegate*>([self delegate])->Deny();
115 109
116 // Remove the infobar, we're done. 110 // Remove the infobar, we're done.
117 [super removeSelf]; 111 [super removeSelf];
118 } 112 }
119 113
120 - (IBAction)deviceMenuChanged:(id)item { 114 - (IBAction)deviceMenuChanged:(id)item {
121 // Notify the menu model about the change and rebuild the menu. 115 // Notify the menu model about the change and rebuild the menu.
122 deviceMenuModel_->ExecuteCommand([item tag]); 116 deviceMenuModel_->ExecuteCommand([item tag]);
123 [self rebuildDeviceMenu]; 117 [self rebuildDeviceMenu:NO];
124 } 118 }
125 119
126 - (void)addAdditionalControls { 120 - (void)addAdditionalControls {
127 // Get a frame to use as inital frame for all buttons. 121 // Create all the components for the infobar.
128 NSRect initFrame = [okButton_ frame]; 122 [self constructView];
129 123
130 // Setup up the text label and add the device menu to the infobar. 124 // Get layout information from the NIB.
131 // TODO(mflodman) Use |label_| instead. 125 NSRect cancelButtonFrame = [cancelButton_ frame];
132 [label1_ setFrame:[label_ frame]]; 126 NSRect okButtonFrame = [okButton_ frame];
133 [[label_ superview] replaceSubview:label_ with:label1_.get()];
134 label_.reset();
135 127
136 [deviceMenu_ setFrame:initFrame]; 128 spaceBetweenControls_ = NSMaxX(cancelButtonFrame) < NSMinX(okButtonFrame) ?
137 [infoBarView_ addSubview:deviceMenu_]; 129 NSMinX(okButtonFrame) - NSMaxX(cancelButtonFrame) :
138 130 NSMinX(cancelButtonFrame) - NSMaxX(okButtonFrame);
Scott Hess - ex-Googler 2012/07/25 18:28:15 There are cases in our UI where the effective boun
no longer working on chromium 2012/07/26 10:17:47 The condition is to guarantee that the spaceBetwee
Scott Hess - ex-Googler 2012/07/26 19:39:41 Hmm. I read the condition as making sure that it
139 // Add text to all buttons and the text field.
140 [self setLabelTexts];
141 131
142 // Arrange the initial layout. 132 // Arrange the initial layout.
143 [self arrangeInfobarLayout]; 133 [self arrangeInfobarLayout];
144 134
145 // Build the device popup menu. 135 // Add and configure controls that are visible in all modes.
146 [self rebuildDeviceMenu]; 136 [deviceMenu_ setAutoresizingMask:NSViewMinXMargin];
Scott Hess - ex-Googler 2012/07/25 18:28:15 Can this line move to the initialization section i
no longer working on chromium 2012/07/26 10:17:47 Done.
137 // Add "options" popup z-ordered below all other controls so when we
138 // resize the toolbar it doesn't hide them.
139 [infoBarView_ addSubview:deviceMenu_
140 positioned:NSWindowBelow
141 relativeTo:nil];
Scott Hess - ex-Googler 2012/07/25 18:28:15 Logically, this feels like it belongs somewhere el
no longer working on chromium 2012/07/26 10:17:47 Done.
142 [GTMUILocalizerAndLayoutTweaker sizeToFitView:deviceMenu_];
Scott Hess - ex-Googler 2012/07/25 18:28:15 This seems like it might be contrary to your -size
no longer working on chromium 2012/07/26 10:17:47 removed this -sizeToFit function here.
147 143
148 // Make sure we get notified of infobar view size changes. 144 // Make sure we get notified of infobar view size changes.
149 // TODO(mflodman) Find if there is a way to use 'setAutorezingMask' instead. 145 // TODO(mflodman) Find if there is a way to use 'setAutorezingMask' instead.
150 [infoBarView_ setPostsFrameChangedNotifications:YES]; 146 [infoBarView_ setPostsFrameChangedNotifications:YES];
151 [[NSNotificationCenter defaultCenter] 147 [[NSNotificationCenter defaultCenter]
152 addObserver:self 148 addObserver:self
153 selector:@selector(didChangeFrame:) 149 selector:@selector(didChangeFrame:)
154 name:NSViewFrameDidChangeNotification 150 name:NSViewFrameDidChangeNotification
155 object:infoBarView_]; 151 object:infoBarView_];
156 } 152 }
(...skipping 24 matching lines...) Expand all
181 [okButton_ setTitle:GetNSStringWithFixup(IDS_MEDIA_CAPTURE_ALLOW)]; 177 [okButton_ setTitle:GetNSStringWithFixup(IDS_MEDIA_CAPTURE_ALLOW)];
182 [cancelButton_ setTitle:GetNSStringWithFixup(IDS_MEDIA_CAPTURE_DENY)]; 178 [cancelButton_ setTitle:GetNSStringWithFixup(IDS_MEDIA_CAPTURE_DENY)];
183 179
184 // Populating |deviceMenu_| is handled separately. 180 // Populating |deviceMenu_| is handled separately.
185 } 181 }
186 182
187 - (void)arrangeInfobarLayout { 183 - (void)arrangeInfobarLayout {
188 // Set correct size for text frame. 184 // Set correct size for text frame.
189 [GTMUILocalizerAndLayoutTweaker sizeToFitView:label1_]; 185 [GTMUILocalizerAndLayoutTweaker sizeToFitView:label1_];
190 186
191 // Place |okButton_| to the right of the text field. 187 // From left to right: label_, okButton_, cancelButton_ and deviceMenu_.
Scott Hess - ex-Googler 2012/07/25 18:28:15 The comment implies that it's label, cancel, ok.
no longer working on chromium 2012/07/26 10:17:47 thanks. In linux and windows, the cancel button is
192 SizeAndPlaceControl(okButton_, label1_, true); 188 MoveControl(label1_, cancelButton_, spaceBetweenControls_, true);
189 MoveControl(cancelButton_, okButton_, spaceBetweenControls_, true);
193 190
194 // Place |cancelButton| to the right of [okButton_|. 191 // Build the device option popup menu.
195 SizeAndPlaceControl(cancelButton_, okButton_, true); 192 [deviceMenu_ setHidden:NO];
193 [self rebuildDeviceMenu:NO];
194 [[deviceMenu_ cell] setArrowPosition:NSPopUpArrowAtBottom];
195 [deviceMenu_ sizeToFit];
196 MoveControl(closeButton_, deviceMenu_, spaceBetweenControls_, false);
196 197
197 // |deviceMenu_| is floating to the right, besides |closeButton_|. 198 // Hide the deviceMenu_ in case there is overlap.
Scott Hess - ex-Googler 2012/07/25 18:28:15 I think the comment could be clearer, it's only hi
no longer working on chromium 2012/07/26 10:17:47 Done.
198 SizeAndPlaceControl(deviceMenu_, closeButton_, false); 199 if (!VerifyControlOrderAndSpacing(okButton_, deviceMenu_)) {
200 [self rebuildDeviceMenu:YES];
Scott Hess - ex-Googler 2012/07/25 18:28:15 I think that this would make more sense if you had
no longer working on chromium 2012/07/26 10:17:47 Good idea, then we don't need to rebuild the menu
201 NSRect oldFrame = [deviceMenu_ frame];
202 oldFrame.size.width = NSHeight(oldFrame);
203 [deviceMenu_ setFrame:oldFrame];
Scott Hess - ex-Googler 2012/07/25 18:28:15 Does -sizeToFit work here? Or does that allow thi
no longer working on chromium 2012/07/26 10:17:47 Thanks for pointing it out. -sizeToFit works the s
204 [[deviceMenu_ cell] setArrowPosition:NSPopUpArrowAtCenter];
205 MoveControl(closeButton_, deviceMenu_, spaceBetweenControls_, false);
206 if (!VerifyControlOrderAndSpacing(okButton_, deviceMenu_)) {
207 [deviceMenu_ setHidden:YES];
208 }
209 }
199 } 210 }
200 211
201 - (void)rebuildDeviceMenu { 212 - (void)constructView {
213 // Use the ok button frame as inital frame for all components.
214 NSRect initFrame = [okButton_ frame];
215
216 // Setup up the text label and add the device menu to the infobar.
217 // TODO(mflodman) Use |label_| instead.
218 label1_.reset([[NSTextField alloc] init]);
219 [label1_ setEditable:NO];
220 [label1_ setDrawsBackground:NO];
221 [label1_ setBordered:NO];
222 [label1_ setFrame:[label_ frame]];
223 [[label_ superview] replaceSubview:label_ with:label1_.get()];
224 label_.reset();
225
226 deviceMenu_.reset([[NSPopUpButton alloc] initWithFrame:initFrame
227 pullsDown:YES]);
228 [deviceMenu_ setBezelStyle:NSTexturedRoundedBezelStyle];
229 NSMenu* menu = [deviceMenu_ menu];
230 [menu setDelegate:nil];
231 [menu setAutoenablesItems:NO];
232
233 // Add text to all buttons and the text field.
234 [self setLabelTexts];
235
236 // Set each of the label and buttons to the NSTexturedRoundedBezelStyle
237 // (metal-looking) style.
238 NSArray* allControls = [self allControls];
Scott Hess - ex-Googler 2012/07/25 18:28:15 Is -allControls used anywhere else. As things cur
no longer working on chromium 2012/07/26 10:17:47 Done.
239 for (NSControl* control in allControls) {
240 if (![control isKindOfClass:[NSButton class]])
241 continue;
242 NSButton* button = (NSButton*)control;
243 [button setBezelStyle:NSTexturedRoundedBezelStyle];
244 if ([button isKindOfClass:[NSPopUpButton class]]) {
245 [[button cell] setArrowPosition:NSPopUpArrowAtBottom];
Scott Hess - ex-Googler 2012/07/25 18:28:15 My guess is that at one point you had deviceMenu_
no longer working on chromium 2012/07/26 10:17:47 sorry for the uncleaned debug code, I had moved th
246 }
247 }
248 }
249
250 - (NSArray*)allControls {
251 return [NSArray arrayWithObjects:label1_.get(), okButton_,
252 cancelButton_, nil];
253 }
254
255 - (void)rebuildDeviceMenu:(BOOL)hideTitle {
202 // Remove all old menu items and rebuild from scratch. 256 // Remove all old menu items and rebuild from scratch.
203 [deviceMenu_ removeAllItems]; 257 [deviceMenu_ removeAllItems];
204 NSMenu* menu = [deviceMenu_ menu]; 258 NSMenu* menu = [deviceMenu_ menu];
205 259
206 // Add title item. 260 // Add title item.
207 NSString* menuTitle = GetNSStringWithFixup( 261 NSString* menuTitle = hideTitle ? @"" : GetNSStringWithFixup(
208 IDS_MEDIA_CAPTURE_DEVICES_MENU_TITLE); 262 IDS_MEDIA_CAPTURE_DEVICES_MENU_TITLE);
209 NSMenuItem* titleItem = 263 NSMenuItem* titleItem =
210 [menu addItemWithTitle:menuTitle 264 [menu addItemWithTitle:menuTitle
211 action:NULL 265 action:NULL
212 keyEquivalent:@""]; 266 keyEquivalent:@""];
213 [titleItem setState:NSOffState]; 267 [titleItem setState:NSOffState];
214 268
215 [menu addItem:[NSMenuItem separatorItem]]; 269 [menu addItem:[NSMenuItem separatorItem]];
216 270
217 // Add all capture devices. 271 // Add all capture devices.
(...skipping 15 matching lines...) Expand all
233 } 287 }
234 } 288 }
235 [GTMUILocalizerAndLayoutTweaker sizeToFitView:deviceMenu_]; 289 [GTMUILocalizerAndLayoutTweaker sizeToFitView:deviceMenu_];
236 } 290 }
237 291
238 - (void)didChangeFrame:(NSNotification*)notification { 292 - (void)didChangeFrame:(NSNotification*)notification {
239 [self arrangeInfobarLayout]; 293 [self arrangeInfobarLayout];
240 } 294 }
241 295
242 @end // implementation MediaStreamInfoBarController 296 @end // implementation MediaStreamInfoBarController
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698