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; | |
23 | |
24 InfoBar* MediaStreamInfoBarDelegate::CreateInfoBar(InfoBarTabHelper* owner) { | 26 InfoBar* MediaStreamInfoBarDelegate::CreateInfoBar(InfoBarTabHelper* owner) { |
25 MediaStreamInfoBarController* infobar_controller = | 27 MediaStreamInfoBarController* infobar_controller = |
26 [[MediaStreamInfoBarController alloc] initWithDelegate:this | 28 [[MediaStreamInfoBarController alloc] initWithDelegate:this |
27 owner:owner]; | 29 owner:owner]; |
28 return new InfoBar(infobar_controller, this); | 30 return new InfoBar(infobar_controller, this); |
29 } | 31 } |
30 | 32 |
31 namespace { | |
32 | |
33 // Puts |toMove| to the right or left of |anchor|. | |
34 void SizeAndPlaceControl(NSView* toModify, NSView* anchor, bool after) { | |
35 [GTMUILocalizerAndLayoutTweaker sizeToFitView:toModify]; | |
36 NSRect toModifyFrame = [toModify frame]; | |
37 NSRect anchorFrame = [anchor frame]; | |
38 if (after) { | |
39 toModifyFrame.origin.x = NSMaxX(anchorFrame) + kSpaceBetweenControls; | |
40 } else { | |
41 toModifyFrame.origin.x = NSMinX(anchorFrame) - kSpaceBetweenControls - | |
42 NSWidth(toModifyFrame); | |
43 } | |
44 [toModify setFrame:toModifyFrame]; | |
45 } | |
46 | |
47 } // namespace | |
48 | |
49 | 33 |
50 @interface MediaStreamInfoBarController(Private) | 34 @interface MediaStreamInfoBarController(Private) |
51 | 35 |
52 // Adds text for all buttons and text fields. | 36 // Adds text for all buttons and text fields. |
53 - (void)setLabelTexts; | 37 - (void)setLabelTexts; |
54 | 38 |
55 // Populates the device menu with device id:s. | 39 // Populates the device menu with device id:s. |
56 - (void)rebuildDeviceMenu; | 40 - (void)rebuildDeviceMenu; |
57 | 41 |
58 // Arranges all buttons and pup-up menu relative each other. | 42 // Arranges all buttons and pup-up menu relative each other. |
59 - (void)arrangeInfobarLayout; | 43 - (void)arrangeInfobarLayout; |
60 | 44 |
| 45 // Create all the components for the infobar. |
| 46 - (void)constructView; |
| 47 |
| 48 - (void)showDeviceMenuTitle:(BOOL)showTitle; |
61 @end | 49 @end |
62 | 50 |
63 | 51 |
64 @implementation MediaStreamInfoBarController | 52 @implementation MediaStreamInfoBarController |
65 | 53 |
66 - (id)initWithDelegate:(MediaStreamInfoBarDelegate*)delegate | 54 - (id)initWithDelegate:(MediaStreamInfoBarDelegate*)delegate |
67 owner:(InfoBarTabHelper*)owner { | 55 owner:(InfoBarTabHelper*)owner { |
68 if (self = [super initWithDelegate:delegate owner:owner]) { | 56 if (self = [super initWithDelegate:delegate owner:owner]) { |
69 deviceMenuModel_.reset(new MediaStreamDevicesMenuModel(delegate)); | 57 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 } | 58 } |
87 return self; | 59 return self; |
88 } | 60 } |
89 | 61 |
90 - (void)dealloc { | 62 - (void)dealloc { |
91 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 63 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
92 [deviceMenu_ removeAllItems]; | 64 [deviceMenu_ removeAllItems]; |
93 [super dealloc]; | 65 [super dealloc]; |
94 } | 66 } |
95 | 67 |
(...skipping 21 matching lines...) Expand all Loading... |
117 [super removeSelf]; | 89 [super removeSelf]; |
118 } | 90 } |
119 | 91 |
120 - (IBAction)deviceMenuChanged:(id)item { | 92 - (IBAction)deviceMenuChanged:(id)item { |
121 // Notify the menu model about the change and rebuild the menu. | 93 // Notify the menu model about the change and rebuild the menu. |
122 deviceMenuModel_->ExecuteCommand([item tag]); | 94 deviceMenuModel_->ExecuteCommand([item tag]); |
123 [self rebuildDeviceMenu]; | 95 [self rebuildDeviceMenu]; |
124 } | 96 } |
125 | 97 |
126 - (void)addAdditionalControls { | 98 - (void)addAdditionalControls { |
127 // Get a frame to use as inital frame for all buttons. | 99 // Create all the components for the infobar. |
128 NSRect initFrame = [okButton_ frame]; | 100 [self constructView]; |
129 | 101 |
130 // Setup up the text label and add the device menu to the infobar. | 102 // Get layout information from the NIB. |
131 // TODO(mflodman) Use |label_| instead. | 103 NSRect cancelButtonFrame = [cancelButton_ frame]; |
132 [label1_ setFrame:[label_ frame]]; | 104 NSRect okButtonFrame = [okButton_ frame]; |
133 [[label_ superview] replaceSubview:label_ with:label1_.get()]; | |
134 label_.reset(); | |
135 | 105 |
136 [deviceMenu_ setFrame:initFrame]; | 106 // Verify Cancel button is on the left of OK button. |
137 [infoBarView_ addSubview:deviceMenu_]; | 107 DCHECK(NSMaxX(cancelButtonFrame) < NSMinX(okButtonFrame)); |
138 | 108 spaceBetweenControls_ = NSMinX(okButtonFrame) - NSMaxX(cancelButtonFrame); |
139 // Add text to all buttons and the text field. | |
140 [self setLabelTexts]; | |
141 | 109 |
142 // Arrange the initial layout. | 110 // Arrange the initial layout. |
143 [self arrangeInfobarLayout]; | 111 [self arrangeInfobarLayout]; |
144 | 112 |
145 // Build the device popup menu. | |
146 [self rebuildDeviceMenu]; | |
147 | |
148 // Make sure we get notified of infobar view size changes. | 113 // Make sure we get notified of infobar view size changes. |
149 // TODO(mflodman) Find if there is a way to use 'setAutorezingMask' instead. | 114 // TODO(mflodman) Find if there is a way to use 'setAutorezingMask' instead. |
150 [infoBarView_ setPostsFrameChangedNotifications:YES]; | 115 [infoBarView_ setPostsFrameChangedNotifications:YES]; |
151 [[NSNotificationCenter defaultCenter] | 116 [[NSNotificationCenter defaultCenter] |
152 addObserver:self | 117 addObserver:self |
153 selector:@selector(didChangeFrame:) | 118 selector:@selector(didChangeFrame:) |
154 name:NSViewFrameDidChangeNotification | 119 name:NSViewFrameDidChangeNotification |
155 object:infoBarView_]; | 120 object:infoBarView_]; |
156 } | 121 } |
157 | 122 |
(...skipping 23 matching lines...) Expand all Loading... |
181 [okButton_ setTitle:GetNSStringWithFixup(IDS_MEDIA_CAPTURE_ALLOW)]; | 146 [okButton_ setTitle:GetNSStringWithFixup(IDS_MEDIA_CAPTURE_ALLOW)]; |
182 [cancelButton_ setTitle:GetNSStringWithFixup(IDS_MEDIA_CAPTURE_DENY)]; | 147 [cancelButton_ setTitle:GetNSStringWithFixup(IDS_MEDIA_CAPTURE_DENY)]; |
183 | 148 |
184 // Populating |deviceMenu_| is handled separately. | 149 // Populating |deviceMenu_| is handled separately. |
185 } | 150 } |
186 | 151 |
187 - (void)arrangeInfobarLayout { | 152 - (void)arrangeInfobarLayout { |
188 // Set correct size for text frame. | 153 // Set correct size for text frame. |
189 [GTMUILocalizerAndLayoutTweaker sizeToFitView:label1_]; | 154 [GTMUILocalizerAndLayoutTweaker sizeToFitView:label1_]; |
190 | 155 |
191 // Place |okButton_| to the right of the text field. | 156 // From left to right: label_, cancelButton_ and okButton_. |
192 SizeAndPlaceControl(okButton_, label1_, true); | 157 MoveControl(label1_, cancelButton_, spaceBetweenControls_, true); |
| 158 MoveControl(cancelButton_, okButton_, spaceBetweenControls_, true); |
193 | 159 |
194 // Place |cancelButton| to the right of [okButton_|. | 160 // Build the device option popup menu. |
195 SizeAndPlaceControl(cancelButton_, okButton_, true); | 161 [deviceMenu_ setHidden:NO]; |
| 162 [self showDeviceMenuTitle:YES]; |
| 163 MoveControl(closeButton_, deviceMenu_, spaceBetweenControls_, false); |
196 | 164 |
197 // |deviceMenu_| is floating to the right, besides |closeButton_|. | 165 // Hide the title of deviceMenu_ or even the whole menu when it overlaps |
198 SizeAndPlaceControl(deviceMenu_, closeButton_, false); | 166 // with the okButton_. |
| 167 if (!VerifyControlOrderAndSpacing(okButton_, deviceMenu_)) { |
| 168 NSRect oldFrame = [deviceMenu_ frame]; |
| 169 oldFrame.size.width = NSHeight(oldFrame); |
| 170 [deviceMenu_ setFrame:oldFrame]; |
| 171 [self showDeviceMenuTitle:NO]; |
| 172 MoveControl(closeButton_, deviceMenu_, spaceBetweenControls_, false); |
| 173 if (!VerifyControlOrderAndSpacing(okButton_, deviceMenu_)) { |
| 174 [deviceMenu_ setHidden:YES]; |
| 175 } |
| 176 } |
| 177 } |
| 178 |
| 179 - (void)constructView { |
| 180 // Use the ok button frame as inital frame for all components. |
| 181 NSRect initFrame = [okButton_ frame]; |
| 182 |
| 183 // Setup the text label and add the device menu to the infobar. |
| 184 // TODO(mflodman) Use |label_| instead. |
| 185 label1_.reset([[NSTextField alloc] init]); |
| 186 [label1_ setEditable:NO]; |
| 187 [label1_ setDrawsBackground:NO]; |
| 188 [label1_ setBordered:NO]; |
| 189 [label1_ setFrame:[label_ frame]]; |
| 190 [[label_ superview] replaceSubview:label_ with:label1_]; |
| 191 label_.reset(); |
| 192 |
| 193 [okButton_ setBezelStyle:NSTexturedRoundedBezelStyle]; |
| 194 [cancelButton_ setBezelStyle:NSTexturedRoundedBezelStyle]; |
| 195 |
| 196 // Add text to all buttons and the text field. |
| 197 [self setLabelTexts]; |
| 198 |
| 199 // Setup the device options menu. |
| 200 deviceMenu_.reset([[NSPopUpButton alloc] initWithFrame:initFrame |
| 201 pullsDown:YES]); |
| 202 [deviceMenu_ setBezelStyle:NSTexturedRoundedBezelStyle]; |
| 203 [deviceMenu_ setAutoresizingMask:NSViewMinXMargin]; |
| 204 [self rebuildDeviceMenu]; |
| 205 [GTMUILocalizerAndLayoutTweaker sizeToFitView:deviceMenu_]; |
| 206 NSMenu* menu = [deviceMenu_ menu]; |
| 207 [menu setDelegate:nil]; |
| 208 [menu setAutoenablesItems:NO]; |
| 209 |
| 210 // Add "options" popup z-ordered below all other controls so when we |
| 211 // resize the toolbar it doesn't hide them. |
| 212 [infoBarView_ addSubview:deviceMenu_ |
| 213 positioned:NSWindowBelow |
| 214 relativeTo:nil]; |
199 } | 215 } |
200 | 216 |
201 - (void)rebuildDeviceMenu { | 217 - (void)rebuildDeviceMenu { |
202 // Remove all old menu items and rebuild from scratch. | 218 // Remove all old menu items and rebuild from scratch. |
203 [deviceMenu_ removeAllItems]; | 219 [deviceMenu_ removeAllItems]; |
204 NSMenu* menu = [deviceMenu_ menu]; | 220 NSMenu* menu = [deviceMenu_ menu]; |
205 | 221 |
206 // Add title item. | 222 // Add title item. |
207 NSString* menuTitle = GetNSStringWithFixup( | 223 NSString* menuTitle = GetNSStringWithFixup( |
208 IDS_MEDIA_CAPTURE_DEVICES_MENU_TITLE); | 224 IDS_MEDIA_CAPTURE_DEVICES_MENU_TITLE); |
(...skipping 16 matching lines...) Expand all Loading... |
225 action:@selector(deviceMenuChanged:) | 241 action:@selector(deviceMenuChanged:) |
226 keyEquivalent:@""]; | 242 keyEquivalent:@""]; |
227 [item setTarget:self]; | 243 [item setTarget:self]; |
228 [item setTag:deviceMenuModel_->GetCommandIdAt(i)]; | 244 [item setTag:deviceMenuModel_->GetCommandIdAt(i)]; |
229 if (deviceMenuModel_->IsItemCheckedAt(i)) { | 245 if (deviceMenuModel_->IsItemCheckedAt(i)) { |
230 [item setState:NSOnState]; | 246 [item setState:NSOnState]; |
231 } | 247 } |
232 [item setEnabled:deviceMenuModel_->IsEnabledAt(i)]; | 248 [item setEnabled:deviceMenuModel_->IsEnabledAt(i)]; |
233 } | 249 } |
234 } | 250 } |
235 [GTMUILocalizerAndLayoutTweaker sizeToFitView:deviceMenu_]; | 251 } |
| 252 |
| 253 - (void)showDeviceMenuTitle:(BOOL)showTitle { |
| 254 if (showTitle) { |
| 255 NSString* menuTitle = GetNSStringWithFixup( |
| 256 IDS_MEDIA_CAPTURE_DEVICES_MENU_TITLE); |
| 257 [[[deviceMenu_ menu] itemAtIndex:0] setTitle:menuTitle]; |
| 258 [[deviceMenu_ cell] setArrowPosition:NSPopUpArrowAtBottom]; |
| 259 [GTMUILocalizerAndLayoutTweaker sizeToFitView:deviceMenu_]; |
| 260 } else { |
| 261 [[[deviceMenu_ menu] itemAtIndex:0] setTitle:@""]; |
| 262 [[deviceMenu_ cell] setArrowPosition:NSPopUpArrowAtCenter]; |
| 263 } |
236 } | 264 } |
237 | 265 |
238 - (void)didChangeFrame:(NSNotification*)notification { | 266 - (void)didChangeFrame:(NSNotification*)notification { |
239 [self arrangeInfobarLayout]; | 267 [self arrangeInfobarLayout]; |
240 } | 268 } |
241 | 269 |
242 @end // implementation MediaStreamInfoBarController | 270 @end // implementation MediaStreamInfoBarController |
OLD | NEW |