OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |