OLD | NEW |
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/media_picker/desktop_media_picker_controller.h" | 5 #import "chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #import "base/mac/bundle_locations.h" | 11 #import "base/mac/bundle_locations.h" |
12 #include "base/strings/sys_string_conversions.h" | 12 #include "base/strings/sys_string_conversions.h" |
13 #include "chrome/browser/media/combined_desktop_media_list.h" | 13 #include "chrome/browser/media/combined_desktop_media_list.h" |
14 #import "chrome/browser/ui/cocoa/key_equivalent_constants.h" | 14 #import "chrome/browser/ui/cocoa/key_equivalent_constants.h" |
15 #import "chrome/browser/ui/cocoa/media_picker/desktop_media_picker_item.h" | 15 #import "chrome/browser/ui/cocoa/media_picker/desktop_media_picker_item.h" |
16 #include "chrome/common/chrome_switches.h" | 16 #include "chrome/common/chrome_switches.h" |
| 17 #include "chrome/grit/chromium_strings.h" |
17 #include "chrome/grit/generated_resources.h" | 18 #include "chrome/grit/generated_resources.h" |
| 19 #include "chrome/grit/google_chrome_strings.h" |
18 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
19 #include "content/public/browser/render_frame_host.h" | 21 #include "content/public/browser/render_frame_host.h" |
20 #include "content/public/browser/web_contents.h" | 22 #include "content/public/browser/web_contents.h" |
21 #include "content/public/browser/web_contents_delegate.h" | 23 #include "content/public/browser/web_contents_delegate.h" |
22 #include "grit/components_strings.h" | 24 #include "grit/components_strings.h" |
23 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTw
eaker.h" | 25 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTw
eaker.h" |
24 #import "ui/base/cocoa/flipped_view.h" | 26 #import "ui/base/cocoa/flipped_view.h" |
25 #import "ui/base/cocoa/window_size_constants.h" | 27 #import "ui/base/cocoa/window_size_constants.h" |
26 #include "ui/base/l10n/l10n_util.h" | 28 #include "ui/base/l10n/l10n_util.h" |
27 #include "ui/gfx/image/image_skia_util_mac.h" | 29 #include "ui/gfx/image/image_skia_util_mac.h" |
28 | 30 |
| 31 using content::DesktopMediaID; |
| 32 |
29 namespace { | 33 namespace { |
30 | 34 |
31 const int kInitialContentWidth = 620; | 35 const CGFloat kInitialContentWidth = 620; |
32 const int kMinimumContentWidth = 500; | 36 const CGFloat kMinimumContentWidth = 500; |
33 const int kMinimumContentHeight = 390; | 37 const CGFloat kMinimumContentHeight = 390; |
34 const int kThumbnailWidth = 150; | 38 const CGFloat kThumbnailWidth = 150; |
35 const int kThumbnailHeight = 150; | 39 const CGFloat kThumbnailHeight = 150; |
36 const int kFramePadding = 20; | 40 const CGFloat kSingleScreenWidth = 300; |
37 const int kControlSpacing = 10; | 41 const CGFloat kSingleScreenHeight = 300; |
38 const int kExcessButtonPadding = 6; | 42 const CGFloat kFramePadding = 20; |
| 43 const CGFloat kControlSpacing = 10; |
| 44 const CGFloat kExcessButtonPadding = 6; |
| 45 const CGFloat kRowHeight = 20; |
| 46 const CGFloat kRowWidth = 500; |
| 47 const CGFloat kIconWidth = 20; |
| 48 const CGFloat kPaddedWidth = kInitialContentWidth - (kFramePadding * 2); |
| 49 const CGFloat kFontSize = 13; |
| 50 |
| 51 NSString* const kIconId = @"icon"; |
| 52 NSString* const kTitleId = @"title"; |
39 | 53 |
40 } // namespace | 54 } // namespace |
41 | 55 |
42 @interface DesktopMediaPickerController (Private) | 56 @interface DesktopMediaPickerController () |
43 | 57 |
44 // Populate the window with controls and views. | 58 // Populate the window with controls and views. |
45 - (void)initializeContentsWithAppName:(const base::string16&)appName; | 59 - (void)initializeContentsWithAppName:(const base::string16&)appName |
| 60 targetName:(const base::string16&)targetName |
| 61 requestAudio:(bool)requestAudio; |
| 62 |
| 63 // Add |NSSegmentControl| for source type switch. |
| 64 - (void)createTypeButtonAtOrigin:(NSPoint)origin; |
| 65 |
| 66 // Add |IKImageBrowerView| for screen and window source view. |
| 67 // Add |NSTableView| for tab source view. |
| 68 - (void)createSourceViewsAtOrigin:(NSPoint)origin; |
| 69 |
| 70 // Add check box for audio sharing. |
| 71 - (void)createAudioCheckboxAtOrigin:(NSPoint)origin; |
| 72 |
| 73 // Create the share and cancel button. |
| 74 - (void)createActionButtonsAtOrigin:(NSPoint)origin; |
46 | 75 |
47 // Create a |NSTextField| with label traits given |width|. Frame height is | 76 // Create a |NSTextField| with label traits given |width|. Frame height is |
48 // automatically adjusted to fit. | 77 // automatically adjusted to fit. |
49 - (NSTextField*)createTextFieldWithText:(NSString*)text | 78 - (NSTextField*)createTextFieldWithText:(NSString*)text |
50 frameWidth:(CGFloat)width; | 79 frameWidth:(CGFloat)width; |
51 | 80 |
52 // Create a button with |title|, with size adjusted to fit. | 81 // Create a button with |title|, with size adjusted to fit. |
53 - (NSButton*)createButtonWithTitle:(NSString*)title; | 82 - (NSButton*)createButtonWithTitle:(NSString*)title; |
54 | 83 |
| 84 - (IKImageBrowserView*)createImageBrowserWithSize:(NSSize)size; |
| 85 |
55 // Report result by invoking |doneCallback_|. The callback is invoked only on | 86 // Report result by invoking |doneCallback_|. The callback is invoked only on |
56 // the first call to |reportResult:|. Subsequent calls will be no-ops. | 87 // the first call to |reportResult:|. Subsequent calls will be no-ops. |
57 - (void)reportResult:(content::DesktopMediaID)sourceID; | 88 - (void)reportResult:(DesktopMediaID)sourceID; |
58 | 89 |
59 // Action handlers. | 90 // Action handlers. |
60 - (void)sharePressed:(id)sender; | 91 - (void)sharePressed:(id)sender; |
61 - (void)cancelPressed:(id)sender; | 92 - (void)cancelPressed:(id)sender; |
62 | 93 |
| 94 // Helper functions to get source type, or get data entities based on source |
| 95 // type. |
| 96 - (DesktopMediaID::Type)selectedSourceType; |
| 97 - (DesktopMediaID::Type)sourceTypeForList:(DesktopMediaList*)list; |
| 98 - (DesktopMediaID::Type)sourceTypeForBrowser:(id)browser; |
| 99 - (id)browserViewForType:(DesktopMediaID::Type)sourceType; |
| 100 - (NSMutableArray*)itemSetForType:(DesktopMediaID::Type)sourceType; |
| 101 - (NSInteger)selectedIndexForType:(DesktopMediaID::Type)sourceType; |
| 102 - (void)setTabBrowserIndex:(NSInteger)index; |
| 103 |
63 @end | 104 @end |
64 | 105 |
65 @implementation DesktopMediaPickerController | 106 @implementation DesktopMediaPickerController |
66 | 107 |
67 - (id)initWithScreenList:(std::unique_ptr<DesktopMediaList>)screen_list | 108 - (id)initWithScreenList:(std::unique_ptr<DesktopMediaList>)screenList |
68 windowList:(std::unique_ptr<DesktopMediaList>)window_list | 109 windowList:(std::unique_ptr<DesktopMediaList>)windowList |
69 tabList:(std::unique_ptr<DesktopMediaList>)tab_list | 110 tabList:(std::unique_ptr<DesktopMediaList>)tabList |
70 parent:(NSWindow*)parent | 111 parent:(NSWindow*)parent |
71 callback:(const DesktopMediaPicker::DoneCallback&)callback | 112 callback:(const DesktopMediaPicker::DoneCallback&)callback |
72 appName:(const base::string16&)appName | 113 appName:(const base::string16&)appName |
73 targetName:(const base::string16&)targetName | 114 targetName:(const base::string16&)targetName |
74 requestAudio:(bool)requestAudio { | 115 requestAudio:(bool)requestAudio { |
75 const NSUInteger kStyleMask = | 116 const NSUInteger kStyleMask = |
76 NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask; | 117 NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask; |
77 base::scoped_nsobject<NSWindow> window( | 118 base::scoped_nsobject<NSWindow> window( |
78 [[NSWindow alloc] initWithContentRect:ui::kWindowSizeDeterminedLater | 119 [[NSWindow alloc] initWithContentRect:ui::kWindowSizeDeterminedLater |
79 styleMask:kStyleMask | 120 styleMask:kStyleMask |
80 backing:NSBackingStoreBuffered | 121 backing:NSBackingStoreBuffered |
81 defer:NO]); | 122 defer:NO]); |
82 | 123 |
83 if ((self = [super initWithWindow:window])) { | 124 if ((self = [super initWithWindow:window])) { |
84 [parent addChildWindow:window ordered:NSWindowAbove]; | 125 [parent addChildWindow:window ordered:NSWindowAbove]; |
85 [window setDelegate:self]; | 126 [window setDelegate:self]; |
| 127 if (screenList) { |
| 128 screenList_ = std::move(screenList); |
| 129 screenItems_.reset([[NSMutableArray alloc] init]); |
| 130 } |
| 131 |
| 132 if (windowList) { |
| 133 windowList_ = std::move(windowList); |
| 134 windowList_->SetViewDialogWindowId( |
| 135 DesktopMediaID(DesktopMediaID::TYPE_WINDOW, [window windowNumber])); |
| 136 windowItems_.reset([[NSMutableArray alloc] init]); |
| 137 } |
| 138 |
| 139 if (tabList) { |
| 140 tabList_ = std::move(tabList); |
| 141 tabItems_.reset([[NSMutableArray alloc] init]); |
| 142 } |
| 143 |
86 [self initializeContentsWithAppName:appName | 144 [self initializeContentsWithAppName:appName |
87 targetName:targetName | 145 targetName:targetName |
88 requestAudio:requestAudio]; | 146 requestAudio:requestAudio]; |
89 std::vector<std::unique_ptr<DesktopMediaList>> media_lists; | 147 doneCallback_ = callback; |
90 if (screen_list) | |
91 media_lists.push_back(std::move(screen_list)); | |
92 | 148 |
93 if (window_list) | |
94 media_lists.push_back(std::move(window_list)); | |
95 | |
96 if (tab_list) | |
97 media_lists.push_back(std::move(tab_list)); | |
98 | |
99 if (media_lists.size() > 1) | |
100 media_list_.reset(new CombinedDesktopMediaList(media_lists)); | |
101 else | |
102 media_list_ = std::move(media_lists[0]); | |
103 media_list_->SetViewDialogWindowId(content::DesktopMediaID( | |
104 content::DesktopMediaID::TYPE_WINDOW, [window windowNumber])); | |
105 doneCallback_ = callback; | |
106 items_.reset([[NSMutableArray alloc] init]); | |
107 bridge_.reset(new DesktopMediaPickerBridge(self)); | 149 bridge_.reset(new DesktopMediaPickerBridge(self)); |
108 } | 150 } |
109 return self; | 151 return self; |
110 } | 152 } |
111 | 153 |
112 - (void)dealloc { | 154 - (void)dealloc { |
113 [shareButton_ setTarget:nil]; | 155 [shareButton_ setTarget:nil]; |
114 [cancelButton_ setTarget:nil]; | 156 [cancelButton_ setTarget:nil]; |
115 [sourceBrowser_ setDelegate:nil]; | 157 [screenBrowser_ setDelegate:nil]; |
116 [sourceBrowser_ setDataSource:nil]; | 158 [screenBrowser_ setDataSource:nil]; |
| 159 [windowBrowser_ setDelegate:nil]; |
| 160 [windowBrowser_ setDataSource:nil]; |
| 161 [tabBrowser_ setDataSource:nil]; |
| 162 [tabBrowser_ setDelegate:nil]; |
117 [[self window] close]; | 163 [[self window] close]; |
118 [super dealloc]; | 164 [super dealloc]; |
119 } | 165 } |
120 | 166 |
121 - (void)initializeContentsWithAppName:(const base::string16&)appName | 167 - (void)initializeContentsWithAppName:(const base::string16&)appName |
122 targetName:(const base::string16&)targetName | 168 targetName:(const base::string16&)targetName |
123 requestAudio:(bool)requestAudio { | 169 requestAudio:(bool)requestAudio { |
124 // Use flipped coordinates to facilitate manual layout. | 170 // Use flipped coordinates to facilitate manual layout. |
125 const CGFloat kPaddedWidth = kInitialContentWidth - (kFramePadding * 2); | |
126 base::scoped_nsobject<FlippedView> content( | 171 base::scoped_nsobject<FlippedView> content( |
127 [[FlippedView alloc] initWithFrame:NSZeroRect]); | 172 [[FlippedView alloc] initWithFrame:NSZeroRect]); |
128 [[self window] setContentView:content]; | 173 [[self window] setContentView:content]; |
129 NSPoint origin = NSMakePoint(kFramePadding, kFramePadding); | 174 NSPoint origin = NSMakePoint(kFramePadding, kFramePadding); |
130 | 175 |
131 // Set the dialog's title. | 176 // Set the dialog's title. |
132 NSString* titleText = l10n_util::GetNSStringF( | 177 NSString* titleText = l10n_util::GetNSString(IDS_DESKTOP_MEDIA_PICKER_TITLE); |
133 IDS_DESKTOP_MEDIA_PICKER_TITLE_DEPRECATED, appName); | |
134 [[self window] setTitle:titleText]; | 178 [[self window] setTitle:titleText]; |
135 | 179 |
136 // Set the dialog's description. | 180 // Set the dialog's description. |
137 NSString* descriptionText; | 181 NSString* descriptionText; |
138 if (appName == targetName) { | 182 if (appName == targetName) { |
139 descriptionText = l10n_util::GetNSStringF( | 183 descriptionText = l10n_util::GetNSStringF( |
140 IDS_DESKTOP_MEDIA_PICKER_TEXT, appName); | 184 IDS_DESKTOP_MEDIA_PICKER_TEXT, appName); |
141 } else { | 185 } else { |
142 descriptionText = l10n_util::GetNSStringF( | 186 descriptionText = l10n_util::GetNSStringF( |
143 IDS_DESKTOP_MEDIA_PICKER_TEXT_DELEGATED, appName, targetName); | 187 IDS_DESKTOP_MEDIA_PICKER_TEXT_DELEGATED, appName, targetName); |
144 } | 188 } |
145 NSTextField* description = [self createTextFieldWithText:descriptionText | 189 NSTextField* description = [self createTextFieldWithText:descriptionText |
146 frameWidth:kPaddedWidth]; | 190 frameWidth:kPaddedWidth]; |
147 [description setFrameOrigin:origin]; | 191 [description setFrameOrigin:origin]; |
148 [content addSubview:description]; | 192 [content addSubview:description]; |
149 origin.y += NSHeight([description frame]) + kControlSpacing; | 193 origin.y += NSHeight([description frame]) + kControlSpacing; |
150 | 194 |
151 // Create the image browser. | 195 [self createTypeButtonAtOrigin:origin]; |
152 sourceBrowser_.reset([[IKImageBrowserView alloc] initWithFrame:NSZeroRect]); | 196 origin.y += NSHeight([sourceTypeControl_ frame]) + kControlSpacing; |
153 NSUInteger cellStyle = IKCellsStyleShadowed | IKCellsStyleTitled; | |
154 [sourceBrowser_ setDelegate:self]; | |
155 [sourceBrowser_ setDataSource:self]; | |
156 [sourceBrowser_ setCellsStyleMask:cellStyle]; | |
157 [sourceBrowser_ setCellSize:NSMakeSize(kThumbnailWidth, kThumbnailHeight)]; | |
158 [sourceBrowser_ setAllowsMultipleSelection:NO]; | |
159 | 197 |
160 // Create a scroll view to host the image browser. | 198 [self createSourceViewsAtOrigin:origin]; |
161 NSRect imageBrowserScrollFrame = NSMakeRect( | 199 origin.y += NSHeight([imageBrowserScroll_ frame]) + kControlSpacing; |
162 origin.x, origin.y, kPaddedWidth, 350); | |
163 base::scoped_nsobject<NSScrollView> imageBrowserScroll( | |
164 [[NSScrollView alloc] initWithFrame:imageBrowserScrollFrame]); | |
165 [imageBrowserScroll setHasVerticalScroller:YES]; | |
166 [imageBrowserScroll setDocumentView:sourceBrowser_]; | |
167 [imageBrowserScroll setBorderType:NSBezelBorder]; | |
168 [imageBrowserScroll setAutoresizingMask: | |
169 NSViewWidthSizable | NSViewHeightSizable]; | |
170 [content addSubview:imageBrowserScroll]; | |
171 origin.y += NSHeight(imageBrowserScrollFrame) + kControlSpacing; | |
172 | 200 |
173 // Create a checkbox for audio sharing. | |
174 if (requestAudio) { | 201 if (requestAudio) { |
175 audioShareCheckbox_.reset([[NSButton alloc] initWithFrame:NSZeroRect]); | 202 [self createAudioCheckboxAtOrigin:origin]; |
176 [audioShareCheckbox_ setFrameOrigin:origin]; | |
177 [audioShareCheckbox_ | |
178 setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin]; | |
179 [audioShareCheckbox_ setButtonType:NSSwitchButton]; | |
180 audioShareState_ = NSOnState; | |
181 [audioShareCheckbox_ | |
182 setTitle:l10n_util::GetNSString(IDS_DESKTOP_MEDIA_PICKER_AUDIO_SHARE)]; | |
183 [audioShareCheckbox_ sizeToFit]; | |
184 [audioShareCheckbox_ setEnabled:NO]; | |
185 [audioShareCheckbox_ | |
186 setToolTip:l10n_util::GetNSString( | |
187 IDS_DESKTOP_MEDIA_PICKER_AUDIO_SHARE_TOOLTIP_MAC)]; | |
188 [content addSubview:audioShareCheckbox_]; | |
189 origin.y += NSHeight([audioShareCheckbox_ frame]) + kControlSpacing; | 203 origin.y += NSHeight([audioShareCheckbox_ frame]) + kControlSpacing; |
190 } | 204 } |
191 | 205 |
| 206 [self createActionButtonsAtOrigin:origin]; |
| 207 origin.y += |
| 208 kFramePadding + (NSHeight([cancelButton_ frame]) - kExcessButtonPadding); |
| 209 |
| 210 // Resize window to fit. |
| 211 [content setAutoresizesSubviews:NO]; |
| 212 [[self window] setContentSize:NSMakeSize(kInitialContentWidth, origin.y)]; |
| 213 [[self window] setContentMinSize:NSMakeSize(kMinimumContentWidth, |
| 214 kMinimumContentHeight)]; |
| 215 [content setAutoresizesSubviews:YES]; |
| 216 |
| 217 // Initialize the type selection at the first segment. |
| 218 [sourceTypeControl_ setSelected:YES forSegment:0]; |
| 219 [self typeButtonPressed:sourceTypeControl_]; |
| 220 [[self window] |
| 221 makeFirstResponder:[self browserViewForType:[self selectedSourceType]]]; |
| 222 } |
| 223 |
| 224 - (void)createTypeButtonAtOrigin:(NSPoint)origin { |
| 225 // Create segmented button. |
| 226 sourceTypeControl_.reset( |
| 227 [[NSSegmentedControl alloc] initWithFrame:NSZeroRect]); |
| 228 |
| 229 NSInteger segmentCount = |
| 230 (screenList_ ? 1 : 0) + (windowList_ ? 1 : 0) + (tabList_ ? 1 : 0); |
| 231 [sourceTypeControl_ setSegmentCount:segmentCount]; |
| 232 NSInteger segmentIndex = 0; |
| 233 |
| 234 if (screenList_) { |
| 235 [sourceTypeControl_ |
| 236 setLabel:l10n_util::GetNSString( |
| 237 IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_SCREEN) |
| 238 forSegment:segmentIndex]; |
| 239 |
| 240 [[sourceTypeControl_ cell] setTag:DesktopMediaID::TYPE_SCREEN |
| 241 forSegment:segmentIndex]; |
| 242 ++segmentIndex; |
| 243 } |
| 244 |
| 245 if (windowList_) { |
| 246 [sourceTypeControl_ |
| 247 setLabel:l10n_util::GetNSString( |
| 248 IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_WINDOW) |
| 249 forSegment:segmentIndex]; |
| 250 [[sourceTypeControl_ cell] setTag:DesktopMediaID::TYPE_WINDOW |
| 251 forSegment:segmentIndex]; |
| 252 ++segmentIndex; |
| 253 } |
| 254 |
| 255 if (tabList_) { |
| 256 [sourceTypeControl_ setLabel:l10n_util::GetNSString( |
| 257 IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_TAB) |
| 258 forSegment:segmentIndex]; |
| 259 [[sourceTypeControl_ cell] setTag:DesktopMediaID::TYPE_WEB_CONTENTS |
| 260 forSegment:segmentIndex]; |
| 261 } |
| 262 [sourceTypeControl_ setAction:@selector(typeButtonPressed:)]; |
| 263 |
| 264 [[sourceTypeControl_ cell] setTrackingMode:NSSegmentSwitchTrackingSelectOne]; |
| 265 |
| 266 [[[self window] contentView] addSubview:sourceTypeControl_]; |
| 267 |
| 268 [sourceTypeControl_ sizeToFit]; |
| 269 [sourceTypeControl_ setAutoresizingMask:NSViewMaxXMargin | NSViewMinXMargin]; |
| 270 CGFloat controlWidth = NSWidth([sourceTypeControl_ frame]); |
| 271 CGFloat controlHeight = NSHeight([sourceTypeControl_ frame]); |
| 272 NSRect centerFrame = NSMakeRect((kInitialContentWidth - controlWidth) / 2, |
| 273 origin.y, controlWidth, controlHeight); |
| 274 |
| 275 [sourceTypeControl_ setFrame:NSIntegralRect(centerFrame)]; |
| 276 } |
| 277 |
| 278 - (void)createSourceViewsAtOrigin:(NSPoint)origin { |
| 279 if (screenList_) { |
| 280 screenBrowser_.reset([[self |
| 281 createImageBrowserWithSize:NSMakeSize(kSingleScreenWidth, |
| 282 kSingleScreenHeight)] retain]); |
| 283 } |
| 284 |
| 285 if (windowList_) { |
| 286 windowBrowser_.reset([ |
| 287 [self createImageBrowserWithSize:NSMakeSize(kThumbnailWidth, |
| 288 kThumbnailHeight)] retain]); |
| 289 } |
| 290 |
| 291 if (tabList_) { |
| 292 tabBrowser_.reset([[NSTableView alloc] initWithFrame:NSZeroRect]); |
| 293 [tabBrowser_ setDelegate:self]; |
| 294 [tabBrowser_ setDataSource:self]; |
| 295 [tabBrowser_ setAllowsMultipleSelection:NO]; |
| 296 [tabBrowser_ setRowHeight:kRowHeight]; |
| 297 [tabBrowser_ setDoubleAction:@selector(sharePressed:)]; |
| 298 base::scoped_nsobject<NSTableColumn> iconColumn( |
| 299 [[NSTableColumn alloc] initWithIdentifier:kIconId]); |
| 300 [iconColumn setEditable:NO]; |
| 301 [iconColumn setWidth:kIconWidth]; |
| 302 [tabBrowser_ addTableColumn:iconColumn]; |
| 303 base::scoped_nsobject<NSTableColumn> titleColumn( |
| 304 [[NSTableColumn alloc] initWithIdentifier:kTitleId]); |
| 305 [titleColumn setEditable:NO]; |
| 306 [titleColumn setWidth:kRowWidth]; |
| 307 [tabBrowser_ addTableColumn:titleColumn]; |
| 308 [tabBrowser_ setHeaderView:nil]; |
| 309 } |
| 310 |
| 311 // Create a scroll view to host the image browsers. |
| 312 NSRect imageBrowserScrollFrame = |
| 313 NSMakeRect(origin.x, origin.y, kPaddedWidth, 350); |
| 314 imageBrowserScroll_.reset( |
| 315 [[NSScrollView alloc] initWithFrame:imageBrowserScrollFrame]); |
| 316 [imageBrowserScroll_ setHasVerticalScroller:YES]; |
| 317 [imageBrowserScroll_ setBorderType:NSBezelBorder]; |
| 318 [imageBrowserScroll_ |
| 319 setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; |
| 320 [[[self window] contentView] addSubview:imageBrowserScroll_]; |
| 321 } |
| 322 |
| 323 - (void)createAudioCheckboxAtOrigin:(NSPoint)origin { |
| 324 audioShareCheckbox_.reset([[NSButton alloc] initWithFrame:NSZeroRect]); |
| 325 [audioShareCheckbox_ setFrameOrigin:origin]; |
| 326 [audioShareCheckbox_ setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin]; |
| 327 [audioShareCheckbox_ setButtonType:NSSwitchButton]; |
| 328 [audioShareCheckbox_ setState:NSOnState]; |
| 329 [audioShareCheckbox_ |
| 330 setTitle:l10n_util::GetNSString(IDS_DESKTOP_MEDIA_PICKER_AUDIO_SHARE)]; |
| 331 [audioShareCheckbox_ sizeToFit]; |
| 332 [[[self window] contentView] addSubview:audioShareCheckbox_]; |
| 333 } |
| 334 |
| 335 - (void)createActionButtonsAtOrigin:(NSPoint)origin { |
| 336 FlippedView* content = [[self window] contentView]; |
| 337 |
192 // Create the share button. | 338 // Create the share button. |
193 shareButton_ = [self createButtonWithTitle:l10n_util::GetNSString( | 339 shareButton_ = |
194 IDS_DESKTOP_MEDIA_PICKER_SHARE)]; | 340 [self createButtonWithTitle:l10n_util::GetNSString( |
| 341 IDS_DESKTOP_MEDIA_PICKER_SHARE)]; |
195 origin.x = kInitialContentWidth - kFramePadding - | 342 origin.x = kInitialContentWidth - kFramePadding - |
196 (NSWidth([shareButton_ frame]) - kExcessButtonPadding); | 343 (NSWidth([shareButton_ frame]) - kExcessButtonPadding); |
197 [shareButton_ setEnabled:NO]; | 344 [shareButton_ setEnabled:NO]; |
198 [shareButton_ setFrameOrigin:origin]; | 345 [shareButton_ setFrameOrigin:origin]; |
199 [shareButton_ setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin]; | 346 [shareButton_ setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin]; |
200 [shareButton_ setTarget:self]; | 347 [shareButton_ setTarget:self]; |
201 [shareButton_ setKeyEquivalent:kKeyEquivalentReturn]; | 348 [shareButton_ setKeyEquivalent:kKeyEquivalentReturn]; |
202 [shareButton_ setAction:@selector(sharePressed:)]; | 349 [shareButton_ setAction:@selector(sharePressed:)]; |
203 [content addSubview:shareButton_]; | 350 [content addSubview:shareButton_]; |
204 | 351 |
205 // Create the cancel button. | 352 // Create the cancel button. |
206 cancelButton_ = | 353 cancelButton_ = |
207 [self createButtonWithTitle:l10n_util::GetNSString(IDS_CANCEL)]; | 354 [self createButtonWithTitle:l10n_util::GetNSString(IDS_CANCEL)]; |
208 origin.x -= kControlSpacing + | 355 origin.x -= kControlSpacing + |
209 (NSWidth([cancelButton_ frame]) - (kExcessButtonPadding * 2)); | 356 (NSWidth([cancelButton_ frame]) - (kExcessButtonPadding * 2)); |
210 [cancelButton_ setFrameOrigin:origin]; | 357 [cancelButton_ setFrameOrigin:origin]; |
211 [cancelButton_ setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin]; | 358 [cancelButton_ setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin]; |
212 [cancelButton_ setTarget:self]; | 359 [cancelButton_ setTarget:self]; |
213 [cancelButton_ setKeyEquivalent:kKeyEquivalentEscape]; | 360 [cancelButton_ setKeyEquivalent:kKeyEquivalentEscape]; |
214 [cancelButton_ setAction:@selector(cancelPressed:)]; | 361 [cancelButton_ setAction:@selector(cancelPressed:)]; |
215 [content addSubview:cancelButton_]; | 362 [content addSubview:cancelButton_]; |
216 origin.y += kFramePadding + | |
217 (NSHeight([cancelButton_ frame]) - kExcessButtonPadding); | |
218 | |
219 // Resize window to fit. | |
220 [[[self window] contentView] setAutoresizesSubviews:NO]; | |
221 [[self window] setContentSize:NSMakeSize(kInitialContentWidth, origin.y)]; | |
222 [[self window] setContentMinSize: | |
223 NSMakeSize(kMinimumContentWidth, kMinimumContentHeight)]; | |
224 [[[self window] contentView] setAutoresizesSubviews:YES]; | |
225 | |
226 // Make sourceBrowser_ get keyboard focus. | |
227 [[self window] makeFirstResponder:sourceBrowser_]; | |
228 } | 363 } |
229 | 364 |
| 365 - (NSTextField*)createTextFieldWithText:(NSString*)text |
| 366 frameWidth:(CGFloat)width { |
| 367 NSRect frame = NSMakeRect(0, 0, width, 1); |
| 368 base::scoped_nsobject<NSTextField> textField( |
| 369 [[NSTextField alloc] initWithFrame:frame]); |
| 370 [textField setEditable:NO]; |
| 371 [textField setSelectable:YES]; |
| 372 [textField setDrawsBackground:NO]; |
| 373 [textField setBezeled:NO]; |
| 374 [textField setStringValue:text]; |
| 375 [textField setFont:[NSFont systemFontOfSize:kFontSize]]; |
| 376 [textField setAutoresizingMask:NSViewWidthSizable]; |
| 377 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:textField]; |
| 378 return textField.autorelease(); |
| 379 } |
| 380 |
| 381 - (NSButton*)createButtonWithTitle:(NSString*)title { |
| 382 base::scoped_nsobject<NSButton> button( |
| 383 [[NSButton alloc] initWithFrame:NSZeroRect]); |
| 384 [button setButtonType:NSMomentaryPushInButton]; |
| 385 [button setBezelStyle:NSRoundedBezelStyle]; |
| 386 [button setTitle:title]; |
| 387 [GTMUILocalizerAndLayoutTweaker sizeToFitView:button]; |
| 388 return button.autorelease(); |
| 389 } |
| 390 |
| 391 - (IKImageBrowserView*)createImageBrowserWithSize:(NSSize)size { |
| 392 NSUInteger cellStyle = IKCellsStyleShadowed | IKCellsStyleTitled; |
| 393 base::scoped_nsobject<IKImageBrowserView> browser( |
| 394 [[IKImageBrowserView alloc] initWithFrame:NSZeroRect]); |
| 395 [browser setDelegate:self]; |
| 396 [browser setDataSource:self]; |
| 397 [browser setCellsStyleMask:cellStyle]; |
| 398 [browser setCellSize:size]; |
| 399 [browser setAllowsMultipleSelection:NO]; |
| 400 return browser.autorelease(); |
| 401 } |
| 402 |
| 403 #pragma mark Event Actions |
| 404 |
230 - (void)showWindow:(id)sender { | 405 - (void)showWindow:(id)sender { |
231 // Signal the media_list to start sending thumbnails. |bridge_| is used as the | 406 // Signal the source lists to start sending thumbnails. |bridge_| is used as |
232 // observer, and will forward notifications to this object. | 407 // the observer, and will forward notifications to this object. |
233 media_list_->SetThumbnailSize(gfx::Size(kThumbnailWidth, kThumbnailHeight)); | 408 if (screenList_) { |
234 media_list_->StartUpdating(bridge_.get()); | 409 screenList_->SetThumbnailSize( |
| 410 gfx::Size(kSingleScreenWidth, kSingleScreenHeight)); |
| 411 screenList_->StartUpdating(bridge_.get()); |
| 412 } |
| 413 |
| 414 if (windowList_) { |
| 415 windowList_->SetThumbnailSize(gfx::Size(kThumbnailWidth, kThumbnailHeight)); |
| 416 windowList_->StartUpdating(bridge_.get()); |
| 417 } |
| 418 |
| 419 if (tabList_) { |
| 420 tabList_->SetThumbnailSize(gfx::Size(kIconWidth, kRowHeight)); |
| 421 tabList_->StartUpdating(bridge_.get()); |
| 422 } |
235 | 423 |
236 [self.window center]; | 424 [self.window center]; |
237 [super showWindow:sender]; | 425 [super showWindow:sender]; |
238 } | 426 } |
239 | 427 |
240 - (void)reportResult:(content::DesktopMediaID)sourceID { | 428 - (void)reportResult:(DesktopMediaID)sourceID { |
241 if (doneCallback_.is_null()) { | 429 if (doneCallback_.is_null()) { |
242 return; | 430 return; |
243 } | 431 } |
244 | 432 |
245 sourceID.audio_share = [audioShareCheckbox_ isEnabled] && | 433 sourceID.audio_share = ![audioShareCheckbox_ isHidden] && |
246 [audioShareCheckbox_ state] == NSOnState; | 434 [audioShareCheckbox_ state] == NSOnState; |
247 | 435 |
248 // If the media source is an tab, activate it. | 436 // If the media source is an tab, activate it. |
249 if (sourceID.type == content::DesktopMediaID::TYPE_WEB_CONTENTS) { | 437 if (sourceID.type == DesktopMediaID::TYPE_WEB_CONTENTS) { |
250 content::WebContents* tab = content::WebContents::FromRenderFrameHost( | 438 content::WebContents* tab = content::WebContents::FromRenderFrameHost( |
251 content::RenderFrameHost::FromID( | 439 content::RenderFrameHost::FromID( |
252 sourceID.web_contents_id.render_process_id, | 440 sourceID.web_contents_id.render_process_id, |
253 sourceID.web_contents_id.main_render_frame_id)); | 441 sourceID.web_contents_id.main_render_frame_id)); |
254 if (tab) | 442 if (tab) |
255 tab->GetDelegate()->ActivateContents(tab); | 443 tab->GetDelegate()->ActivateContents(tab); |
256 } | 444 } |
257 | 445 |
258 // Notify the |callback_| asynchronously because it may release the | 446 // Notify the |callback_| asynchronously because it may release the |
259 // controller. | 447 // controller. |
260 content::BrowserThread::PostTask( | 448 content::BrowserThread::PostTask( |
261 content::BrowserThread::UI, FROM_HERE, | 449 content::BrowserThread::UI, FROM_HERE, |
262 base::Bind(doneCallback_, sourceID)); | 450 base::Bind(doneCallback_, sourceID)); |
263 doneCallback_.Reset(); | 451 doneCallback_.Reset(); |
264 } | 452 } |
265 | 453 |
266 - (void)sharePressed:(id)sender { | 454 - (void)sharePressed:(id)sender { |
267 NSIndexSet* indexes = [sourceBrowser_ selectionIndexes]; | 455 DesktopMediaID::Type selectedType = [self selectedSourceType]; |
268 NSUInteger selectedIndex = [indexes firstIndex]; | 456 NSMutableArray* items = [self itemSetForType:selectedType]; |
269 DesktopMediaPickerItem* item = | 457 NSInteger selectedIndex = [self selectedIndexForType:selectedType]; |
270 [items_ objectAtIndex:selectedIndex]; | 458 DesktopMediaPickerItem* item = [items objectAtIndex:selectedIndex]; |
271 [self reportResult:[item sourceID]]; | 459 [self reportResult:[item sourceID]]; |
272 [self close]; | 460 [self close]; |
273 } | 461 } |
274 | 462 |
275 - (void)cancelPressed:(id)sender { | 463 - (void)cancelPressed:(id)sender { |
276 [self reportResult:content::DesktopMediaID()]; | 464 [self reportResult:DesktopMediaID()]; |
277 [self close]; | 465 [self close]; |
278 } | 466 } |
279 | 467 |
280 - (NSTextField*)createTextFieldWithText:(NSString*)text | 468 - (void)typeButtonPressed:(id)sender { |
281 frameWidth:(CGFloat)width { | 469 DesktopMediaID::Type selectedType = [self selectedSourceType]; |
282 NSRect frame = NSMakeRect(0, 0, width, 1); | 470 id browser = [self browserViewForType:selectedType]; |
283 base::scoped_nsobject<NSTextField> textField( | 471 |
284 [[NSTextField alloc] initWithFrame:frame]); | 472 [audioShareCheckbox_ |
285 [textField setEditable:NO]; | 473 setHidden:selectedType != DesktopMediaID::TYPE_WEB_CONTENTS]; |
286 [textField setSelectable:YES]; | 474 [imageBrowserScroll_ setDocumentView:browser]; |
287 [textField setDrawsBackground:NO]; | 475 |
288 [textField setBezeled:NO]; | 476 if (selectedType == DesktopMediaID::TYPE_WEB_CONTENTS) { |
289 [textField setStringValue:text]; | 477 NSInteger selectedIndex = [self selectedIndexForType:selectedType]; |
290 [textField setFont:[NSFont systemFontOfSize:13]]; | 478 [tabBrowser_ reloadData]; |
291 [textField setAutoresizingMask:NSViewWidthSizable]; | 479 [self setTabBrowserIndex:selectedIndex]; |
292 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:textField]; | 480 } else { |
293 return textField.autorelease(); | 481 [browser reloadData]; |
| 482 [self imageBrowserSelectionDidChange:browser]; |
| 483 } |
294 } | 484 } |
295 | 485 |
296 - (NSButton*)createButtonWithTitle:(NSString*)title { | 486 #pragma mark Data Retrieve Helper |
297 base::scoped_nsobject<NSButton> button( | 487 |
298 [[NSButton alloc] initWithFrame:NSZeroRect]); | 488 - (DesktopMediaID::Type)selectedSourceType { |
299 [button setButtonType:NSMomentaryPushInButton]; | 489 NSInteger segment = [sourceTypeControl_ selectedSegment]; |
300 [button setBezelStyle:NSRoundedBezelStyle]; | 490 return static_cast<DesktopMediaID::Type>( |
301 [button setTitle:title]; | 491 [[sourceTypeControl_ cell] tagForSegment:segment]); |
302 [GTMUILocalizerAndLayoutTweaker sizeToFitView:button]; | 492 } |
303 return button.autorelease(); | 493 |
| 494 - (DesktopMediaID::Type)sourceTypeForList:(DesktopMediaList*)list { |
| 495 if (list == screenList_.get()) |
| 496 return DesktopMediaID::TYPE_SCREEN; |
| 497 if (list == windowList_.get()) |
| 498 return DesktopMediaID::TYPE_WINDOW; |
| 499 return DesktopMediaID::TYPE_WEB_CONTENTS; |
| 500 } |
| 501 |
| 502 - (DesktopMediaID::Type)sourceTypeForBrowser:(id)browser { |
| 503 if (browser == screenBrowser_.get()) |
| 504 return DesktopMediaID::TYPE_SCREEN; |
| 505 if (browser == windowBrowser_.get()) |
| 506 return DesktopMediaID::TYPE_WINDOW; |
| 507 return DesktopMediaID::TYPE_WEB_CONTENTS; |
| 508 } |
| 509 |
| 510 - (id)browserViewForType:(DesktopMediaID::Type)sourceType { |
| 511 switch (sourceType) { |
| 512 case DesktopMediaID::TYPE_SCREEN: |
| 513 return screenBrowser_; |
| 514 case DesktopMediaID::TYPE_WINDOW: |
| 515 return windowBrowser_; |
| 516 case DesktopMediaID::TYPE_WEB_CONTENTS: |
| 517 return tabBrowser_; |
| 518 case DesktopMediaID::TYPE_NONE: |
| 519 NOTREACHED(); |
| 520 return nil; |
| 521 } |
| 522 } |
| 523 |
| 524 - (NSMutableArray*)itemSetForType:(DesktopMediaID::Type)sourceType { |
| 525 switch (sourceType) { |
| 526 case DesktopMediaID::TYPE_SCREEN: |
| 527 return screenItems_; |
| 528 case DesktopMediaID::TYPE_WINDOW: |
| 529 return windowItems_; |
| 530 case DesktopMediaID::TYPE_WEB_CONTENTS: |
| 531 return tabItems_; |
| 532 case DesktopMediaID::TYPE_NONE: |
| 533 NOTREACHED(); |
| 534 return nil; |
| 535 } |
| 536 } |
| 537 |
| 538 - (NSInteger)selectedIndexForType:(DesktopMediaID::Type)sourceType { |
| 539 NSIndexSet* indexes = nil; |
| 540 switch (sourceType) { |
| 541 case DesktopMediaID::TYPE_SCREEN: |
| 542 indexes = [screenBrowser_ selectionIndexes]; |
| 543 break; |
| 544 case DesktopMediaID::TYPE_WINDOW: |
| 545 indexes = [windowBrowser_ selectionIndexes]; |
| 546 break; |
| 547 case DesktopMediaID::TYPE_WEB_CONTENTS: |
| 548 indexes = [tabBrowser_ selectedRowIndexes]; |
| 549 break; |
| 550 case DesktopMediaID::TYPE_NONE: |
| 551 NOTREACHED(); |
| 552 } |
| 553 |
| 554 if ([indexes count] == 0) |
| 555 return -1; |
| 556 return [indexes firstIndex]; |
| 557 } |
| 558 |
| 559 - (void)setTabBrowserIndex:(NSInteger)index { |
| 560 NSIndexSet* indexes; |
| 561 |
| 562 if (index < 0) |
| 563 indexes = [NSIndexSet indexSet]; |
| 564 else |
| 565 indexes = [NSIndexSet indexSetWithIndex:index]; |
| 566 |
| 567 [tabBrowser_ selectRowIndexes:indexes byExtendingSelection:NO]; |
304 } | 568 } |
305 | 569 |
306 #pragma mark NSWindowDelegate | 570 #pragma mark NSWindowDelegate |
307 | 571 |
308 - (void)windowWillClose:(NSNotification*)notification { | 572 - (void)windowWillClose:(NSNotification*)notification { |
309 // Report the result if it hasn't been reported yet. |reportResult:| ensures | 573 // Report the result if it hasn't been reported yet. |reportResult:| ensures |
310 // that the result is only reported once. | 574 // that the result is only reported once. |
311 [self reportResult:content::DesktopMediaID()]; | 575 [self reportResult:DesktopMediaID()]; |
312 | 576 |
313 // Remove self from the parent. | 577 // Remove self from the parent. |
314 NSWindow* window = [self window]; | 578 NSWindow* window = [self window]; |
315 [[window parentWindow] removeChildWindow:window]; | 579 [[window parentWindow] removeChildWindow:window]; |
316 } | 580 } |
317 | 581 |
318 #pragma mark IKImageBrowserDataSource | 582 #pragma mark IKImageBrowserDataSource |
319 | 583 |
320 - (NSUInteger)numberOfItemsInImageBrowser:(IKImageBrowserView*)browser { | 584 - (NSUInteger)numberOfItemsInImageBrowser:(IKImageBrowserView*)browser { |
321 return [items_ count]; | 585 DesktopMediaID::Type sourceType = [self sourceTypeForBrowser:browser]; |
| 586 NSMutableArray* items = [self itemSetForType:sourceType]; |
| 587 return [items count]; |
322 } | 588 } |
323 | 589 |
324 - (id)imageBrowser:(IKImageBrowserView *)browser | 590 - (id)imageBrowser:(IKImageBrowserView*)browser itemAtIndex:(NSUInteger)index { |
325 itemAtIndex:(NSUInteger)index { | 591 DesktopMediaID::Type sourceType = [self sourceTypeForBrowser:browser]; |
326 return [items_ objectAtIndex:index]; | 592 NSMutableArray* items = [self itemSetForType:sourceType]; |
| 593 return [items objectAtIndex:index]; |
327 } | 594 } |
328 | 595 |
329 #pragma mark IKImageBrowserDelegate | 596 #pragma mark IKImageBrowserDelegate |
330 | 597 |
331 - (void)imageBrowser:(IKImageBrowserView *)browser | 598 - (void)imageBrowser:(IKImageBrowserView*)browser |
332 cellWasDoubleClickedAtIndex:(NSUInteger)index { | 599 cellWasDoubleClickedAtIndex:(NSUInteger)index { |
333 DesktopMediaPickerItem* item = [items_ objectAtIndex:index]; | 600 DesktopMediaPickerItem* item; |
| 601 if (browser == screenBrowser_) |
| 602 item = [screenItems_ objectAtIndex:index]; |
| 603 else |
| 604 item = [windowItems_ objectAtIndex:index]; |
334 [self reportResult:[item sourceID]]; | 605 [self reportResult:[item sourceID]]; |
335 [self close]; | 606 [self close]; |
336 } | 607 } |
337 | 608 |
338 - (void)imageBrowserSelectionDidChange:(IKImageBrowserView*)browser { | 609 - (void)imageBrowserSelectionDidChange:(IKImageBrowserView*)browser { |
339 NSIndexSet* indexes = [sourceBrowser_ selectionIndexes]; | 610 DesktopMediaID::Type selectedType = [self selectedSourceType]; |
| 611 NSInteger selectedIndex = [self selectedIndexForType:selectedType]; |
| 612 // Enable or disable the OK button based on whether we have a selection. |
| 613 [shareButton_ setEnabled:(selectedIndex >= 0)]; |
| 614 } |
| 615 |
| 616 #pragma mark NSTableViewDataSource |
| 617 |
| 618 - (NSInteger)numberOfRowsInTableView:(NSTableView*)table { |
| 619 return [tabItems_ count]; |
| 620 } |
| 621 |
| 622 #pragma mark NSTableViewDelegate |
| 623 |
| 624 - (NSView*)tableView:(NSTableView*)table |
| 625 viewForTableColumn:(NSTableColumn*)column |
| 626 row:(NSInteger)rowIndex { |
| 627 if ([[column identifier] isEqualToString:kIconId]) { |
| 628 NSImage* image = [[tabItems_ objectAtIndex:rowIndex] imageRepresentation]; |
| 629 base::scoped_nsobject<NSImageView> iconView( |
| 630 [[table makeViewWithIdentifier:kIconId owner:self] retain]); |
| 631 if (!iconView) { |
| 632 iconView.reset([[NSImageView alloc] |
| 633 initWithFrame:NSMakeRect(0, 0, kIconWidth, kRowWidth)]); |
| 634 [iconView setIdentifier:kIconId]; |
| 635 } |
| 636 [iconView setImage:image]; |
| 637 return iconView.autorelease(); |
| 638 } |
| 639 |
| 640 NSString* string = [[tabItems_ objectAtIndex:rowIndex] imageTitle]; |
| 641 base::scoped_nsobject<NSTextField> titleView( |
| 642 [[table makeViewWithIdentifier:kTitleId owner:self] retain]); |
| 643 if (!titleView) { |
| 644 titleView.reset( |
| 645 [[self createTextFieldWithText:string frameWidth:kMinimumContentWidth] |
| 646 retain]); |
| 647 [titleView setIdentifier:kTitleId]; |
| 648 } else { |
| 649 [titleView setStringValue:string]; |
| 650 } |
| 651 return titleView.autorelease(); |
| 652 } |
| 653 |
| 654 - (void)tableViewSelectionDidChange:(NSNotification*)notification { |
| 655 NSIndexSet* indexes = [tabBrowser_ selectedRowIndexes]; |
340 | 656 |
341 // Enable or disable the OK button based on whether we have a selection. | 657 // Enable or disable the OK button based on whether we have a selection. |
342 [shareButton_ setEnabled:([indexes count] > 0)]; | 658 [shareButton_ setEnabled:([indexes count] > 0)]; |
343 | |
344 // Enable or disable the checkbox based on whether we can support audio for | |
345 // the selected source. | |
346 // On Mac, the checkbox will enabled for tab sharing, namely | |
347 // TYPE_WEB_CONTENTS. | |
348 if ([indexes count] == 0) { | |
349 if ([audioShareCheckbox_ isEnabled]) { | |
350 [audioShareCheckbox_ setEnabled:NO]; | |
351 audioShareState_ = [audioShareCheckbox_ state]; | |
352 [audioShareCheckbox_ setState:NSOffState]; | |
353 } | |
354 [audioShareCheckbox_ | |
355 setToolTip:l10n_util::GetNSString( | |
356 IDS_DESKTOP_MEDIA_PICKER_AUDIO_SHARE_TOOLTIP_MAC)]; | |
357 return; | |
358 } | |
359 | |
360 NSUInteger selectedIndex = [indexes firstIndex]; | |
361 DesktopMediaPickerItem* item = [items_ objectAtIndex:selectedIndex]; | |
362 switch ([item sourceID].type) { | |
363 case content::DesktopMediaID::TYPE_SCREEN: | |
364 case content::DesktopMediaID::TYPE_WINDOW: | |
365 if ([audioShareCheckbox_ isEnabled]) { | |
366 [audioShareCheckbox_ setEnabled:NO]; | |
367 audioShareState_ = [audioShareCheckbox_ state]; | |
368 [audioShareCheckbox_ setState:NSOffState]; | |
369 } | |
370 [audioShareCheckbox_ | |
371 setToolTip:l10n_util::GetNSString( | |
372 IDS_DESKTOP_MEDIA_PICKER_AUDIO_SHARE_TOOLTIP_MAC)]; | |
373 break; | |
374 case content::DesktopMediaID::TYPE_WEB_CONTENTS: | |
375 if (![audioShareCheckbox_ isEnabled]) { | |
376 [audioShareCheckbox_ setEnabled:YES]; | |
377 [audioShareCheckbox_ setState:audioShareState_]; | |
378 } | |
379 [audioShareCheckbox_ setToolTip:@""]; | |
380 break; | |
381 case content::DesktopMediaID::TYPE_NONE: | |
382 NOTREACHED(); | |
383 } | |
384 } | 659 } |
385 | 660 |
386 #pragma mark DesktopMediaPickerObserver | 661 #pragma mark DesktopMediaPickerObserver |
387 | 662 |
388 - (void)sourceAddedAtIndex:(int)index { | 663 - (void)sourceAddedForList:(DesktopMediaList*)list atIndex:(int)index { |
389 const DesktopMediaList::Source& source = media_list_->GetSource(index); | 664 DesktopMediaID::Type sourceType = [self sourceTypeForList:list]; |
| 665 NSMutableArray* items = [self itemSetForType:sourceType]; |
| 666 id browser = [self browserViewForType:sourceType]; |
| 667 NSInteger selectedIndex = [self selectedIndexForType:sourceType]; |
| 668 if (selectedIndex >= index) |
| 669 ++selectedIndex; |
| 670 |
| 671 const DesktopMediaList::Source& source = list->GetSource(index); |
390 NSString* imageTitle = base::SysUTF16ToNSString(source.name); | 672 NSString* imageTitle = base::SysUTF16ToNSString(source.name); |
391 base::scoped_nsobject<DesktopMediaPickerItem> item( | 673 base::scoped_nsobject<DesktopMediaPickerItem> item( |
392 [[DesktopMediaPickerItem alloc] initWithSourceId:source.id | 674 [[DesktopMediaPickerItem alloc] initWithSourceId:source.id |
393 imageUID:++lastImageUID_ | 675 imageUID:++lastImageUID_ |
394 imageTitle:imageTitle]); | 676 imageTitle:imageTitle]); |
395 [items_ insertObject:item atIndex:index]; | 677 [items insertObject:item atIndex:index]; |
396 [sourceBrowser_ reloadData]; | 678 [browser reloadData]; |
| 679 if (sourceType == DesktopMediaID::TYPE_WEB_CONTENTS) |
| 680 [self setTabBrowserIndex:selectedIndex]; |
397 | 681 |
398 NSString* autoselectSource = base::SysUTF8ToNSString( | 682 NSString* autoselectSource = base::SysUTF8ToNSString( |
399 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 683 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
400 switches::kAutoSelectDesktopCaptureSource)); | 684 switches::kAutoSelectDesktopCaptureSource)); |
401 | 685 |
402 if ([autoselectSource isEqualToString:imageTitle]) { | 686 if ([autoselectSource isEqualToString:imageTitle]) { |
403 [self reportResult:[item sourceID]]; | 687 [self reportResult:[item sourceID]]; |
404 [self close]; | 688 [self close]; |
405 } | 689 } |
406 } | 690 } |
407 | 691 |
408 - (void)sourceRemovedAtIndex:(int)index { | 692 - (void)sourceRemovedForList:(DesktopMediaList*)list atIndex:(int)index { |
409 if ([[sourceBrowser_ selectionIndexes] containsIndex:index]) { | 693 DesktopMediaID::Type sourceType = [self sourceTypeForList:list]; |
| 694 NSMutableArray* items = [self itemSetForType:sourceType]; |
| 695 id browser = [self browserViewForType:sourceType]; |
| 696 |
| 697 if (sourceType == DesktopMediaID::TYPE_WEB_CONTENTS) { |
| 698 NSInteger selectedIndex = [self selectedIndexForType:sourceType]; |
| 699 if (selectedIndex > index) |
| 700 --selectedIndex; |
| 701 else if (selectedIndex == index) |
| 702 selectedIndex = -1; |
| 703 [tabItems_ removeObjectAtIndex:index]; |
| 704 [tabBrowser_ reloadData]; |
| 705 [self setTabBrowserIndex:selectedIndex]; |
| 706 return; |
| 707 } |
| 708 |
| 709 if ([[browser selectionIndexes] containsIndex:index]) { |
410 // Selected item was removed. Clear selection. | 710 // Selected item was removed. Clear selection. |
411 [sourceBrowser_ setSelectionIndexes:[NSIndexSet indexSet] | 711 [browser setSelectionIndexes:[NSIndexSet indexSet] byExtendingSelection:NO]; |
412 byExtendingSelection:FALSE]; | |
413 } | 712 } |
414 [items_ removeObjectAtIndex:index]; | 713 [items removeObjectAtIndex:index]; |
415 [sourceBrowser_ reloadData]; | 714 [browser reloadData]; |
416 } | 715 } |
417 | 716 |
418 - (void)sourceMovedFrom:(int)oldIndex to:(int)newIndex { | 717 - (void)sourceMovedForList:(DesktopMediaList*)list |
| 718 from:(int)oldIndex |
| 719 to:(int)newIndex { |
| 720 DesktopMediaID::Type sourceType = [self sourceTypeForList:list]; |
| 721 NSMutableArray* items = [self itemSetForType:sourceType]; |
| 722 id browser = [self browserViewForType:sourceType]; |
| 723 NSInteger selectedIndex = [self selectedIndexForType:sourceType]; |
| 724 if (selectedIndex > oldIndex && selectedIndex <= newIndex) |
| 725 --selectedIndex; |
| 726 else if (selectedIndex < oldIndex && selectedIndex >= newIndex) |
| 727 ++selectedIndex; |
| 728 else if (selectedIndex == oldIndex) |
| 729 selectedIndex = newIndex; |
| 730 |
419 base::scoped_nsobject<DesktopMediaPickerItem> item( | 731 base::scoped_nsobject<DesktopMediaPickerItem> item( |
420 [[items_ objectAtIndex:oldIndex] retain]); | 732 [[items objectAtIndex:oldIndex] retain]); |
421 [items_ removeObjectAtIndex:oldIndex]; | 733 [items removeObjectAtIndex:oldIndex]; |
422 [items_ insertObject:item atIndex:newIndex]; | 734 [items insertObject:item atIndex:newIndex]; |
423 [sourceBrowser_ reloadData]; | 735 [browser reloadData]; |
| 736 |
| 737 if (sourceType == DesktopMediaID::TYPE_WEB_CONTENTS) |
| 738 [self setTabBrowserIndex:selectedIndex]; |
424 } | 739 } |
425 | 740 |
426 - (void)sourceNameChangedAtIndex:(int)index { | 741 - (void)sourceNameChangedForList:(DesktopMediaList*)list atIndex:(int)index { |
427 DesktopMediaPickerItem* item = [items_ objectAtIndex:index]; | 742 DesktopMediaID::Type sourceType = [self sourceTypeForList:list]; |
428 const DesktopMediaList::Source& source = media_list_->GetSource(index); | 743 NSMutableArray* items = [self itemSetForType:sourceType]; |
| 744 id browser = [self browserViewForType:sourceType]; |
| 745 NSInteger selectedIndex = [self selectedIndexForType:sourceType]; |
| 746 |
| 747 DesktopMediaPickerItem* item = [items objectAtIndex:index]; |
| 748 const DesktopMediaList::Source& source = list->GetSource(index); |
429 [item setImageTitle:base::SysUTF16ToNSString(source.name)]; | 749 [item setImageTitle:base::SysUTF16ToNSString(source.name)]; |
430 [sourceBrowser_ reloadData]; | 750 [browser reloadData]; |
| 751 if (sourceType == DesktopMediaID::TYPE_WEB_CONTENTS) |
| 752 [self setTabBrowserIndex:selectedIndex]; |
431 } | 753 } |
432 | 754 |
433 - (void)sourceThumbnailChangedAtIndex:(int)index { | 755 - (void)sourceThumbnailChangedForList:(DesktopMediaList*)list |
434 const DesktopMediaList::Source& source = media_list_->GetSource(index); | 756 atIndex:(int)index { |
| 757 DesktopMediaID::Type sourceType = [self sourceTypeForList:list]; |
| 758 NSMutableArray* items = [self itemSetForType:sourceType]; |
| 759 id browser = [self browserViewForType:sourceType]; |
| 760 NSInteger selectedIndex = [self selectedIndexForType:sourceType]; |
| 761 |
| 762 const DesktopMediaList::Source& source = list->GetSource(index); |
435 NSImage* image = gfx::NSImageFromImageSkia(source.thumbnail); | 763 NSImage* image = gfx::NSImageFromImageSkia(source.thumbnail); |
436 | 764 |
437 DesktopMediaPickerItem* item = [items_ objectAtIndex:index]; | 765 DesktopMediaPickerItem* item = [items objectAtIndex:index]; |
438 [item setImageRepresentation:image]; | 766 [item setImageRepresentation:image]; |
439 [sourceBrowser_ reloadData]; | 767 [browser reloadData]; |
| 768 |
| 769 if (sourceType == DesktopMediaID::TYPE_WEB_CONTENTS) |
| 770 [self setTabBrowserIndex:selectedIndex]; |
440 } | 771 } |
441 | 772 |
442 @end // @interface DesktopMediaPickerController | 773 @end // @interface DesktopMediaPickerController |
OLD | NEW |