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