| Index: chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller.mm
|
| diff --git a/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller.mm b/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller.mm
|
| index 73edf1c474abe7b67a648877b7f260a4e0921975..e2858cdd61e6293af69d41a920ae64b9e74b018f 100644
|
| --- a/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller.mm
|
| +++ b/chrome/browser/ui/cocoa/media_picker/desktop_media_picker_controller.mm
|
| @@ -16,7 +16,9 @@
|
| #import "chrome/browser/ui/cocoa/key_equivalent_constants.h"
|
| #import "chrome/browser/ui/cocoa/media_picker/desktop_media_picker_item.h"
|
| #include "chrome/common/chrome_switches.h"
|
| +#include "chrome/grit/chromium_strings.h"
|
| #include "chrome/grit/generated_resources.h"
|
| +#include "chrome/grit/google_chrome_strings.h"
|
| #include "content/public/browser/browser_thread.h"
|
| #include "content/public/browser/render_frame_host.h"
|
| #include "content/public/browser/web_contents.h"
|
| @@ -28,23 +30,50 @@
|
| #include "ui/base/l10n/l10n_util.h"
|
| #include "ui/gfx/image/image_skia_util_mac.h"
|
|
|
| +using content::DesktopMediaID;
|
| +
|
| namespace {
|
|
|
| -const int kInitialContentWidth = 620;
|
| -const int kMinimumContentWidth = 500;
|
| -const int kMinimumContentHeight = 390;
|
| -const int kThumbnailWidth = 150;
|
| -const int kThumbnailHeight = 150;
|
| -const int kFramePadding = 20;
|
| -const int kControlSpacing = 10;
|
| -const int kExcessButtonPadding = 6;
|
| +const CGFloat kInitialContentWidth = 620;
|
| +const CGFloat kMinimumContentWidth = 500;
|
| +const CGFloat kMinimumContentHeight = 390;
|
| +const CGFloat kThumbnailWidth = 150;
|
| +const CGFloat kThumbnailHeight = 150;
|
| +const CGFloat kSingleScreenWidth = 300;
|
| +const CGFloat kSingleScreenHeight = 300;
|
| +const CGFloat kFramePadding = 20;
|
| +const CGFloat kControlSpacing = 10;
|
| +const CGFloat kExcessButtonPadding = 6;
|
| +const CGFloat kRowHeight = 20;
|
| +const CGFloat kRowWidth = 500;
|
| +const CGFloat kIconWidth = 20;
|
| +const CGFloat kPaddedWidth = kInitialContentWidth - (kFramePadding * 2);
|
| +const CGFloat kFontSize = 13;
|
| +
|
| +NSString* const kIconId = @"icon";
|
| +NSString* const kTitleId = @"title";
|
|
|
| } // namespace
|
|
|
| -@interface DesktopMediaPickerController (Private)
|
| +@interface DesktopMediaPickerController ()
|
|
|
| // Populate the window with controls and views.
|
| -- (void)initializeContentsWithAppName:(const base::string16&)appName;
|
| +- (void)initializeContentsWithAppName:(const base::string16&)appName
|
| + targetName:(const base::string16&)targetName
|
| + requestAudio:(bool)requestAudio;
|
| +
|
| +// Add |NSSegmentControl| for source type switch.
|
| +- (void)createTypeButtonAtOrigin:(NSPoint)origin;
|
| +
|
| +// Add |IKImageBrowerView| for screen and window source view.
|
| +// Add |NSTableView| for tab source view.
|
| +- (void)createSourceViewsAtOrigin:(NSPoint)origin;
|
| +
|
| +// Add check box for audio sharing.
|
| +- (void)createAudioCheckboxAtOrigin:(NSPoint)origin;
|
| +
|
| +// Create the share and cancel button.
|
| +- (void)createActionButtonsAtOrigin:(NSPoint)origin;
|
|
|
| // Create a |NSTextField| with label traits given |width|. Frame height is
|
| // automatically adjusted to fit.
|
| @@ -54,21 +83,33 @@ const int kExcessButtonPadding = 6;
|
| // Create a button with |title|, with size adjusted to fit.
|
| - (NSButton*)createButtonWithTitle:(NSString*)title;
|
|
|
| +- (IKImageBrowserView*)createImageBrowserWithSize:(NSSize)size;
|
| +
|
| // Report result by invoking |doneCallback_|. The callback is invoked only on
|
| // the first call to |reportResult:|. Subsequent calls will be no-ops.
|
| -- (void)reportResult:(content::DesktopMediaID)sourceID;
|
| +- (void)reportResult:(DesktopMediaID)sourceID;
|
|
|
| // Action handlers.
|
| - (void)sharePressed:(id)sender;
|
| - (void)cancelPressed:(id)sender;
|
|
|
| +// Helper functions to get source type, or get data entities based on source
|
| +// type.
|
| +- (DesktopMediaID::Type)selectedSourceType;
|
| +- (DesktopMediaID::Type)sourceTypeForList:(DesktopMediaList*)list;
|
| +- (DesktopMediaID::Type)sourceTypeForBrowser:(id)browser;
|
| +- (id)browserViewForType:(DesktopMediaID::Type)sourceType;
|
| +- (NSMutableArray*)itemSetForType:(DesktopMediaID::Type)sourceType;
|
| +- (NSInteger)selectedIndexForType:(DesktopMediaID::Type)sourceType;
|
| +- (void)setTabBrowserIndex:(NSInteger)index;
|
| +
|
| @end
|
|
|
| @implementation DesktopMediaPickerController
|
|
|
| -- (id)initWithScreenList:(std::unique_ptr<DesktopMediaList>)screen_list
|
| - windowList:(std::unique_ptr<DesktopMediaList>)window_list
|
| - tabList:(std::unique_ptr<DesktopMediaList>)tab_list
|
| +- (id)initWithScreenList:(std::unique_ptr<DesktopMediaList>)screenList
|
| + windowList:(std::unique_ptr<DesktopMediaList>)windowList
|
| + tabList:(std::unique_ptr<DesktopMediaList>)tabList
|
| parent:(NSWindow*)parent
|
| callback:(const DesktopMediaPicker::DoneCallback&)callback
|
| appName:(const base::string16&)appName
|
| @@ -85,27 +126,28 @@ const int kExcessButtonPadding = 6;
|
| if ((self = [super initWithWindow:window])) {
|
| [parent addChildWindow:window ordered:NSWindowAbove];
|
| [window setDelegate:self];
|
| + if (screenList) {
|
| + screenList_ = std::move(screenList);
|
| + screenItems_.reset([[NSMutableArray alloc] init]);
|
| + }
|
| +
|
| + if (windowList) {
|
| + windowList_ = std::move(windowList);
|
| + windowList_->SetViewDialogWindowId(
|
| + DesktopMediaID(DesktopMediaID::TYPE_WINDOW, [window windowNumber]));
|
| + windowItems_.reset([[NSMutableArray alloc] init]);
|
| + }
|
| +
|
| + if (tabList) {
|
| + tabList_ = std::move(tabList);
|
| + tabItems_.reset([[NSMutableArray alloc] init]);
|
| + }
|
| +
|
| [self initializeContentsWithAppName:appName
|
| targetName:targetName
|
| requestAudio:requestAudio];
|
| - std::vector<std::unique_ptr<DesktopMediaList>> media_lists;
|
| - if (screen_list)
|
| - media_lists.push_back(std::move(screen_list));
|
| -
|
| - if (window_list)
|
| - media_lists.push_back(std::move(window_list));
|
| -
|
| - if (tab_list)
|
| - media_lists.push_back(std::move(tab_list));
|
| -
|
| - if (media_lists.size() > 1)
|
| - media_list_.reset(new CombinedDesktopMediaList(media_lists));
|
| - else
|
| - media_list_ = std::move(media_lists[0]);
|
| - media_list_->SetViewDialogWindowId(content::DesktopMediaID(
|
| - content::DesktopMediaID::TYPE_WINDOW, [window windowNumber]));
|
| doneCallback_ = callback;
|
| - items_.reset([[NSMutableArray alloc] init]);
|
| +
|
| bridge_.reset(new DesktopMediaPickerBridge(self));
|
| }
|
| return self;
|
| @@ -114,8 +156,12 @@ const int kExcessButtonPadding = 6;
|
| - (void)dealloc {
|
| [shareButton_ setTarget:nil];
|
| [cancelButton_ setTarget:nil];
|
| - [sourceBrowser_ setDelegate:nil];
|
| - [sourceBrowser_ setDataSource:nil];
|
| + [screenBrowser_ setDelegate:nil];
|
| + [screenBrowser_ setDataSource:nil];
|
| + [windowBrowser_ setDelegate:nil];
|
| + [windowBrowser_ setDataSource:nil];
|
| + [tabBrowser_ setDataSource:nil];
|
| + [tabBrowser_ setDelegate:nil];
|
| [[self window] close];
|
| [super dealloc];
|
| }
|
| @@ -124,15 +170,13 @@ const int kExcessButtonPadding = 6;
|
| targetName:(const base::string16&)targetName
|
| requestAudio:(bool)requestAudio {
|
| // Use flipped coordinates to facilitate manual layout.
|
| - const CGFloat kPaddedWidth = kInitialContentWidth - (kFramePadding * 2);
|
| base::scoped_nsobject<FlippedView> content(
|
| [[FlippedView alloc] initWithFrame:NSZeroRect]);
|
| [[self window] setContentView:content];
|
| NSPoint origin = NSMakePoint(kFramePadding, kFramePadding);
|
|
|
| // Set the dialog's title.
|
| - NSString* titleText = l10n_util::GetNSStringF(
|
| - IDS_DESKTOP_MEDIA_PICKER_TITLE_DEPRECATED, appName);
|
| + NSString* titleText = l10n_util::GetNSString(IDS_DESKTOP_MEDIA_PICKER_TITLE);
|
| [[self window] setTitle:titleText];
|
|
|
| // Set the dialog's description.
|
| @@ -150,52 +194,156 @@ const int kExcessButtonPadding = 6;
|
| [content addSubview:description];
|
| origin.y += NSHeight([description frame]) + kControlSpacing;
|
|
|
| - // Create the image browser.
|
| - sourceBrowser_.reset([[IKImageBrowserView alloc] initWithFrame:NSZeroRect]);
|
| - NSUInteger cellStyle = IKCellsStyleShadowed | IKCellsStyleTitled;
|
| - [sourceBrowser_ setDelegate:self];
|
| - [sourceBrowser_ setDataSource:self];
|
| - [sourceBrowser_ setCellsStyleMask:cellStyle];
|
| - [sourceBrowser_ setCellSize:NSMakeSize(kThumbnailWidth, kThumbnailHeight)];
|
| - [sourceBrowser_ setAllowsMultipleSelection:NO];
|
| -
|
| - // Create a scroll view to host the image browser.
|
| - NSRect imageBrowserScrollFrame = NSMakeRect(
|
| - origin.x, origin.y, kPaddedWidth, 350);
|
| - base::scoped_nsobject<NSScrollView> imageBrowserScroll(
|
| - [[NSScrollView alloc] initWithFrame:imageBrowserScrollFrame]);
|
| - [imageBrowserScroll setHasVerticalScroller:YES];
|
| - [imageBrowserScroll setDocumentView:sourceBrowser_];
|
| - [imageBrowserScroll setBorderType:NSBezelBorder];
|
| - [imageBrowserScroll setAutoresizingMask:
|
| - NSViewWidthSizable | NSViewHeightSizable];
|
| - [content addSubview:imageBrowserScroll];
|
| - origin.y += NSHeight(imageBrowserScrollFrame) + kControlSpacing;
|
| -
|
| - // Create a checkbox for audio sharing.
|
| + [self createTypeButtonAtOrigin:origin];
|
| + origin.y += NSHeight([sourceTypeControl_ frame]) + kControlSpacing;
|
| +
|
| + [self createSourceViewsAtOrigin:origin];
|
| + origin.y += NSHeight([imageBrowserScroll_ frame]) + kControlSpacing;
|
| +
|
| if (requestAudio) {
|
| - audioShareCheckbox_.reset([[NSButton alloc] initWithFrame:NSZeroRect]);
|
| - [audioShareCheckbox_ setFrameOrigin:origin];
|
| - [audioShareCheckbox_
|
| - setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin];
|
| - [audioShareCheckbox_ setButtonType:NSSwitchButton];
|
| - audioShareState_ = NSOnState;
|
| - [audioShareCheckbox_
|
| - setTitle:l10n_util::GetNSString(IDS_DESKTOP_MEDIA_PICKER_AUDIO_SHARE)];
|
| - [audioShareCheckbox_ sizeToFit];
|
| - [audioShareCheckbox_ setEnabled:NO];
|
| - [audioShareCheckbox_
|
| - setToolTip:l10n_util::GetNSString(
|
| - IDS_DESKTOP_MEDIA_PICKER_AUDIO_SHARE_TOOLTIP_MAC)];
|
| - [content addSubview:audioShareCheckbox_];
|
| + [self createAudioCheckboxAtOrigin:origin];
|
| origin.y += NSHeight([audioShareCheckbox_ frame]) + kControlSpacing;
|
| }
|
|
|
| + [self createActionButtonsAtOrigin:origin];
|
| + origin.y +=
|
| + kFramePadding + (NSHeight([cancelButton_ frame]) - kExcessButtonPadding);
|
| +
|
| + // Resize window to fit.
|
| + [content setAutoresizesSubviews:NO];
|
| + [[self window] setContentSize:NSMakeSize(kInitialContentWidth, origin.y)];
|
| + [[self window] setContentMinSize:NSMakeSize(kMinimumContentWidth,
|
| + kMinimumContentHeight)];
|
| + [content setAutoresizesSubviews:YES];
|
| +
|
| + // Initialize the type selection at the first segment.
|
| + [sourceTypeControl_ setSelected:YES forSegment:0];
|
| + [self typeButtonPressed:sourceTypeControl_];
|
| + [[self window]
|
| + makeFirstResponder:[self browserViewForType:[self selectedSourceType]]];
|
| +}
|
| +
|
| +- (void)createTypeButtonAtOrigin:(NSPoint)origin {
|
| + // Create segmented button.
|
| + sourceTypeControl_.reset(
|
| + [[NSSegmentedControl alloc] initWithFrame:NSZeroRect]);
|
| +
|
| + NSInteger segmentCount =
|
| + (screenList_ ? 1 : 0) + (windowList_ ? 1 : 0) + (tabList_ ? 1 : 0);
|
| + [sourceTypeControl_ setSegmentCount:segmentCount];
|
| + NSInteger segmentIndex = 0;
|
| +
|
| + if (screenList_) {
|
| + [sourceTypeControl_
|
| + setLabel:l10n_util::GetNSString(
|
| + IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_SCREEN)
|
| + forSegment:segmentIndex];
|
| +
|
| + [[sourceTypeControl_ cell] setTag:DesktopMediaID::TYPE_SCREEN
|
| + forSegment:segmentIndex];
|
| + ++segmentIndex;
|
| + }
|
| +
|
| + if (windowList_) {
|
| + [sourceTypeControl_
|
| + setLabel:l10n_util::GetNSString(
|
| + IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_WINDOW)
|
| + forSegment:segmentIndex];
|
| + [[sourceTypeControl_ cell] setTag:DesktopMediaID::TYPE_WINDOW
|
| + forSegment:segmentIndex];
|
| + ++segmentIndex;
|
| + }
|
| +
|
| + if (tabList_) {
|
| + [sourceTypeControl_ setLabel:l10n_util::GetNSString(
|
| + IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_TAB)
|
| + forSegment:segmentIndex];
|
| + [[sourceTypeControl_ cell] setTag:DesktopMediaID::TYPE_WEB_CONTENTS
|
| + forSegment:segmentIndex];
|
| + }
|
| + [sourceTypeControl_ setTarget:self];
|
| + [sourceTypeControl_ setAction:@selector(typeButtonPressed:)];
|
| +
|
| + [[sourceTypeControl_ cell] setTrackingMode:NSSegmentSwitchTrackingSelectOne];
|
| +
|
| + [[[self window] contentView] addSubview:sourceTypeControl_];
|
| +
|
| + [sourceTypeControl_ sizeToFit];
|
| + [sourceTypeControl_ setAutoresizingMask:NSViewMaxXMargin | NSViewMinXMargin];
|
| + CGFloat controlWidth = NSWidth([sourceTypeControl_ frame]);
|
| + CGFloat controlHeight = NSHeight([sourceTypeControl_ frame]);
|
| + NSRect centerFrame = NSMakeRect((kInitialContentWidth - controlWidth) / 2,
|
| + origin.y, controlWidth, controlHeight);
|
| +
|
| + [sourceTypeControl_ setFrame:NSIntegralRect(centerFrame)];
|
| +}
|
| +
|
| +- (void)createSourceViewsAtOrigin:(NSPoint)origin {
|
| + if (screenList_) {
|
| + screenBrowser_.reset([[self
|
| + createImageBrowserWithSize:NSMakeSize(kSingleScreenWidth,
|
| + kSingleScreenHeight)] retain]);
|
| + }
|
| +
|
| + if (windowList_) {
|
| + windowBrowser_.reset([
|
| + [self createImageBrowserWithSize:NSMakeSize(kThumbnailWidth,
|
| + kThumbnailHeight)] retain]);
|
| + }
|
| +
|
| + if (tabList_) {
|
| + tabBrowser_.reset([[NSTableView alloc] initWithFrame:NSZeroRect]);
|
| + [tabBrowser_ setDelegate:self];
|
| + [tabBrowser_ setDataSource:self];
|
| + [tabBrowser_ setAllowsMultipleSelection:NO];
|
| + [tabBrowser_ setRowHeight:kRowHeight];
|
| + [tabBrowser_ setDoubleAction:@selector(sharePressed:)];
|
| + base::scoped_nsobject<NSTableColumn> iconColumn(
|
| + [[NSTableColumn alloc] initWithIdentifier:kIconId]);
|
| + [iconColumn setEditable:NO];
|
| + [iconColumn setWidth:kIconWidth];
|
| + [tabBrowser_ addTableColumn:iconColumn];
|
| + base::scoped_nsobject<NSTableColumn> titleColumn(
|
| + [[NSTableColumn alloc] initWithIdentifier:kTitleId]);
|
| + [titleColumn setEditable:NO];
|
| + [titleColumn setWidth:kRowWidth];
|
| + [tabBrowser_ addTableColumn:titleColumn];
|
| + [tabBrowser_ setHeaderView:nil];
|
| + }
|
| +
|
| + // Create a scroll view to host the image browsers.
|
| + NSRect imageBrowserScrollFrame =
|
| + NSMakeRect(origin.x, origin.y, kPaddedWidth, 350);
|
| + imageBrowserScroll_.reset(
|
| + [[NSScrollView alloc] initWithFrame:imageBrowserScrollFrame]);
|
| + [imageBrowserScroll_ setHasVerticalScroller:YES];
|
| + [imageBrowserScroll_ setBorderType:NSBezelBorder];
|
| + [imageBrowserScroll_
|
| + setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
| + [[[self window] contentView] addSubview:imageBrowserScroll_];
|
| +}
|
| +
|
| +- (void)createAudioCheckboxAtOrigin:(NSPoint)origin {
|
| + audioShareCheckbox_.reset([[NSButton alloc] initWithFrame:NSZeroRect]);
|
| + [audioShareCheckbox_ setFrameOrigin:origin];
|
| + [audioShareCheckbox_ setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin];
|
| + [audioShareCheckbox_ setButtonType:NSSwitchButton];
|
| + [audioShareCheckbox_ setState:NSOnState];
|
| + [audioShareCheckbox_
|
| + setTitle:l10n_util::GetNSString(IDS_DESKTOP_MEDIA_PICKER_AUDIO_SHARE)];
|
| + [audioShareCheckbox_ sizeToFit];
|
| + [[[self window] contentView] addSubview:audioShareCheckbox_];
|
| +}
|
| +
|
| +- (void)createActionButtonsAtOrigin:(NSPoint)origin {
|
| + FlippedView* content = [[self window] contentView];
|
| +
|
| // Create the share button.
|
| - shareButton_ = [self createButtonWithTitle:l10n_util::GetNSString(
|
| - IDS_DESKTOP_MEDIA_PICKER_SHARE)];
|
| + shareButton_ =
|
| + [self createButtonWithTitle:l10n_util::GetNSString(
|
| + IDS_DESKTOP_MEDIA_PICKER_SHARE)];
|
| origin.x = kInitialContentWidth - kFramePadding -
|
| - (NSWidth([shareButton_ frame]) - kExcessButtonPadding);
|
| + (NSWidth([shareButton_ frame]) - kExcessButtonPadding);
|
| [shareButton_ setEnabled:NO];
|
| [shareButton_ setFrameOrigin:origin];
|
| [shareButton_ setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin];
|
| @@ -208,48 +356,88 @@ const int kExcessButtonPadding = 6;
|
| cancelButton_ =
|
| [self createButtonWithTitle:l10n_util::GetNSString(IDS_CANCEL)];
|
| origin.x -= kControlSpacing +
|
| - (NSWidth([cancelButton_ frame]) - (kExcessButtonPadding * 2));
|
| + (NSWidth([cancelButton_ frame]) - (kExcessButtonPadding * 2));
|
| [cancelButton_ setFrameOrigin:origin];
|
| [cancelButton_ setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin];
|
| [cancelButton_ setTarget:self];
|
| [cancelButton_ setKeyEquivalent:kKeyEquivalentEscape];
|
| [cancelButton_ setAction:@selector(cancelPressed:)];
|
| [content addSubview:cancelButton_];
|
| - origin.y += kFramePadding +
|
| - (NSHeight([cancelButton_ frame]) - kExcessButtonPadding);
|
| +}
|
|
|
| - // Resize window to fit.
|
| - [[[self window] contentView] setAutoresizesSubviews:NO];
|
| - [[self window] setContentSize:NSMakeSize(kInitialContentWidth, origin.y)];
|
| - [[self window] setContentMinSize:
|
| - NSMakeSize(kMinimumContentWidth, kMinimumContentHeight)];
|
| - [[[self window] contentView] setAutoresizesSubviews:YES];
|
| +- (NSTextField*)createTextFieldWithText:(NSString*)text
|
| + frameWidth:(CGFloat)width {
|
| + NSRect frame = NSMakeRect(0, 0, width, 1);
|
| + base::scoped_nsobject<NSTextField> textField(
|
| + [[NSTextField alloc] initWithFrame:frame]);
|
| + [textField setEditable:NO];
|
| + [textField setSelectable:YES];
|
| + [textField setDrawsBackground:NO];
|
| + [textField setBezeled:NO];
|
| + [textField setStringValue:text];
|
| + [textField setFont:[NSFont systemFontOfSize:kFontSize]];
|
| + [textField setAutoresizingMask:NSViewWidthSizable];
|
| + [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:textField];
|
| + return textField.autorelease();
|
| +}
|
|
|
| - // Make sourceBrowser_ get keyboard focus.
|
| - [[self window] makeFirstResponder:sourceBrowser_];
|
| +- (NSButton*)createButtonWithTitle:(NSString*)title {
|
| + base::scoped_nsobject<NSButton> button(
|
| + [[NSButton alloc] initWithFrame:NSZeroRect]);
|
| + [button setButtonType:NSMomentaryPushInButton];
|
| + [button setBezelStyle:NSRoundedBezelStyle];
|
| + [button setTitle:title];
|
| + [GTMUILocalizerAndLayoutTweaker sizeToFitView:button];
|
| + return button.autorelease();
|
| }
|
|
|
| +- (IKImageBrowserView*)createImageBrowserWithSize:(NSSize)size {
|
| + NSUInteger cellStyle = IKCellsStyleShadowed | IKCellsStyleTitled;
|
| + base::scoped_nsobject<IKImageBrowserView> browser(
|
| + [[IKImageBrowserView alloc] initWithFrame:NSZeroRect]);
|
| + [browser setDelegate:self];
|
| + [browser setDataSource:self];
|
| + [browser setCellsStyleMask:cellStyle];
|
| + [browser setCellSize:size];
|
| + [browser setAllowsMultipleSelection:NO];
|
| + return browser.autorelease();
|
| +}
|
| +
|
| +#pragma mark Event Actions
|
| +
|
| - (void)showWindow:(id)sender {
|
| - // Signal the media_list to start sending thumbnails. |bridge_| is used as the
|
| - // observer, and will forward notifications to this object.
|
| - media_list_->SetThumbnailSize(gfx::Size(kThumbnailWidth, kThumbnailHeight));
|
| - media_list_->StartUpdating(bridge_.get());
|
| + // Signal the source lists to start sending thumbnails. |bridge_| is used as
|
| + // the observer, and will forward notifications to this object.
|
| + if (screenList_) {
|
| + screenList_->SetThumbnailSize(
|
| + gfx::Size(kSingleScreenWidth, kSingleScreenHeight));
|
| + screenList_->StartUpdating(bridge_.get());
|
| + }
|
| +
|
| + if (windowList_) {
|
| + windowList_->SetThumbnailSize(gfx::Size(kThumbnailWidth, kThumbnailHeight));
|
| + windowList_->StartUpdating(bridge_.get());
|
| + }
|
| +
|
| + if (tabList_) {
|
| + tabList_->SetThumbnailSize(gfx::Size(kIconWidth, kRowHeight));
|
| + tabList_->StartUpdating(bridge_.get());
|
| + }
|
|
|
| [self.window center];
|
| [super showWindow:sender];
|
| }
|
|
|
| -- (void)reportResult:(content::DesktopMediaID)sourceID {
|
| +- (void)reportResult:(DesktopMediaID)sourceID {
|
| if (doneCallback_.is_null()) {
|
| return;
|
| }
|
|
|
| - sourceID.audio_share = [audioShareCheckbox_ isEnabled] &&
|
| + sourceID.audio_share = ![audioShareCheckbox_ isHidden] &&
|
| [audioShareCheckbox_ state] == NSOnState;
|
|
|
| - if (sourceID.type == content::DesktopMediaID::TYPE_WEB_CONTENTS) {
|
| - // Activate the selected tab and bring the browser window for the selected
|
| - // tab to the front.
|
| + // If the media source is an tab, activate it.
|
| + if (sourceID.type == DesktopMediaID::TYPE_WEB_CONTENTS) {
|
| content::WebContents* tab = content::WebContents::FromRenderFrameHost(
|
| content::RenderFrameHost::FromID(
|
| sourceID.web_contents_id.render_process_id,
|
| @@ -271,43 +459,119 @@ const int kExcessButtonPadding = 6;
|
| }
|
|
|
| - (void)sharePressed:(id)sender {
|
| - NSIndexSet* indexes = [sourceBrowser_ selectionIndexes];
|
| - NSUInteger selectedIndex = [indexes firstIndex];
|
| - DesktopMediaPickerItem* item =
|
| - [items_ objectAtIndex:selectedIndex];
|
| + DesktopMediaID::Type selectedType = [self selectedSourceType];
|
| + NSMutableArray* items = [self itemSetForType:selectedType];
|
| + NSInteger selectedIndex = [self selectedIndexForType:selectedType];
|
| + DesktopMediaPickerItem* item = [items objectAtIndex:selectedIndex];
|
| [self reportResult:[item sourceID]];
|
| [self close];
|
| }
|
|
|
| - (void)cancelPressed:(id)sender {
|
| - [self reportResult:content::DesktopMediaID()];
|
| + [self reportResult:DesktopMediaID()];
|
| [self close];
|
| }
|
|
|
| -- (NSTextField*)createTextFieldWithText:(NSString*)text
|
| - frameWidth:(CGFloat)width {
|
| - NSRect frame = NSMakeRect(0, 0, width, 1);
|
| - base::scoped_nsobject<NSTextField> textField(
|
| - [[NSTextField alloc] initWithFrame:frame]);
|
| - [textField setEditable:NO];
|
| - [textField setSelectable:YES];
|
| - [textField setDrawsBackground:NO];
|
| - [textField setBezeled:NO];
|
| - [textField setStringValue:text];
|
| - [textField setFont:[NSFont systemFontOfSize:13]];
|
| - [textField setAutoresizingMask:NSViewWidthSizable];
|
| - [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:textField];
|
| - return textField.autorelease();
|
| +- (void)typeButtonPressed:(id)sender {
|
| + DesktopMediaID::Type selectedType = [self selectedSourceType];
|
| + id browser = [self browserViewForType:selectedType];
|
| +
|
| + [audioShareCheckbox_
|
| + setHidden:selectedType != DesktopMediaID::TYPE_WEB_CONTENTS];
|
| + [imageBrowserScroll_ setDocumentView:browser];
|
| +
|
| + if (selectedType == DesktopMediaID::TYPE_WEB_CONTENTS) {
|
| + NSInteger selectedIndex = [self selectedIndexForType:selectedType];
|
| + [tabBrowser_ reloadData];
|
| + [self setTabBrowserIndex:selectedIndex];
|
| + } else {
|
| + [browser reloadData];
|
| + [self imageBrowserSelectionDidChange:browser];
|
| + }
|
| }
|
|
|
| -- (NSButton*)createButtonWithTitle:(NSString*)title {
|
| - base::scoped_nsobject<NSButton> button(
|
| - [[NSButton alloc] initWithFrame:NSZeroRect]);
|
| - [button setButtonType:NSMomentaryPushInButton];
|
| - [button setBezelStyle:NSRoundedBezelStyle];
|
| - [button setTitle:title];
|
| - [GTMUILocalizerAndLayoutTweaker sizeToFitView:button];
|
| - return button.autorelease();
|
| +#pragma mark Data Retrieve Helper
|
| +
|
| +- (DesktopMediaID::Type)selectedSourceType {
|
| + NSInteger segment = [sourceTypeControl_ selectedSegment];
|
| + return static_cast<DesktopMediaID::Type>(
|
| + [[sourceTypeControl_ cell] tagForSegment:segment]);
|
| +}
|
| +
|
| +- (DesktopMediaID::Type)sourceTypeForList:(DesktopMediaList*)list {
|
| + if (list == screenList_.get())
|
| + return DesktopMediaID::TYPE_SCREEN;
|
| + if (list == windowList_.get())
|
| + return DesktopMediaID::TYPE_WINDOW;
|
| + return DesktopMediaID::TYPE_WEB_CONTENTS;
|
| +}
|
| +
|
| +- (DesktopMediaID::Type)sourceTypeForBrowser:(id)browser {
|
| + if (browser == screenBrowser_.get())
|
| + return DesktopMediaID::TYPE_SCREEN;
|
| + if (browser == windowBrowser_.get())
|
| + return DesktopMediaID::TYPE_WINDOW;
|
| + return DesktopMediaID::TYPE_WEB_CONTENTS;
|
| +}
|
| +
|
| +- (id)browserViewForType:(DesktopMediaID::Type)sourceType {
|
| + switch (sourceType) {
|
| + case DesktopMediaID::TYPE_SCREEN:
|
| + return screenBrowser_;
|
| + case DesktopMediaID::TYPE_WINDOW:
|
| + return windowBrowser_;
|
| + case DesktopMediaID::TYPE_WEB_CONTENTS:
|
| + return tabBrowser_;
|
| + case DesktopMediaID::TYPE_NONE:
|
| + NOTREACHED();
|
| + return nil;
|
| + }
|
| +}
|
| +
|
| +- (NSMutableArray*)itemSetForType:(DesktopMediaID::Type)sourceType {
|
| + switch (sourceType) {
|
| + case DesktopMediaID::TYPE_SCREEN:
|
| + return screenItems_;
|
| + case DesktopMediaID::TYPE_WINDOW:
|
| + return windowItems_;
|
| + case DesktopMediaID::TYPE_WEB_CONTENTS:
|
| + return tabItems_;
|
| + case DesktopMediaID::TYPE_NONE:
|
| + NOTREACHED();
|
| + return nil;
|
| + }
|
| +}
|
| +
|
| +- (NSInteger)selectedIndexForType:(DesktopMediaID::Type)sourceType {
|
| + NSIndexSet* indexes = nil;
|
| + switch (sourceType) {
|
| + case DesktopMediaID::TYPE_SCREEN:
|
| + indexes = [screenBrowser_ selectionIndexes];
|
| + break;
|
| + case DesktopMediaID::TYPE_WINDOW:
|
| + indexes = [windowBrowser_ selectionIndexes];
|
| + break;
|
| + case DesktopMediaID::TYPE_WEB_CONTENTS:
|
| + indexes = [tabBrowser_ selectedRowIndexes];
|
| + break;
|
| + case DesktopMediaID::TYPE_NONE:
|
| + NOTREACHED();
|
| + }
|
| +
|
| + if ([indexes count] == 0)
|
| + return -1;
|
| + return [indexes firstIndex];
|
| +}
|
| +
|
| +- (void)setTabBrowserIndex:(NSInteger)index {
|
| + NSIndexSet* indexes;
|
| +
|
| + if (index < 0)
|
| + indexes = [NSIndexSet indexSet];
|
| + else
|
| + indexes = [NSIndexSet indexSetWithIndex:index];
|
| +
|
| + [tabBrowser_ selectRowIndexes:indexes byExtendingSelection:NO];
|
| }
|
|
|
| #pragma mark NSWindowDelegate
|
| @@ -315,7 +579,7 @@ const int kExcessButtonPadding = 6;
|
| - (void)windowWillClose:(NSNotification*)notification {
|
| // Report the result if it hasn't been reported yet. |reportResult:| ensures
|
| // that the result is only reported once.
|
| - [self reportResult:content::DesktopMediaID()];
|
| + [self reportResult:DesktopMediaID()];
|
|
|
| // Remove self from the parent.
|
| NSWindow* window = [self window];
|
| @@ -325,82 +589,102 @@ const int kExcessButtonPadding = 6;
|
| #pragma mark IKImageBrowserDataSource
|
|
|
| - (NSUInteger)numberOfItemsInImageBrowser:(IKImageBrowserView*)browser {
|
| - return [items_ count];
|
| + DesktopMediaID::Type sourceType = [self sourceTypeForBrowser:browser];
|
| + NSMutableArray* items = [self itemSetForType:sourceType];
|
| + return [items count];
|
| }
|
|
|
| -- (id)imageBrowser:(IKImageBrowserView *)browser
|
| - itemAtIndex:(NSUInteger)index {
|
| - return [items_ objectAtIndex:index];
|
| +- (id)imageBrowser:(IKImageBrowserView*)browser itemAtIndex:(NSUInteger)index {
|
| + DesktopMediaID::Type sourceType = [self sourceTypeForBrowser:browser];
|
| + NSMutableArray* items = [self itemSetForType:sourceType];
|
| + return [items objectAtIndex:index];
|
| }
|
|
|
| #pragma mark IKImageBrowserDelegate
|
|
|
| -- (void)imageBrowser:(IKImageBrowserView *)browser
|
| - cellWasDoubleClickedAtIndex:(NSUInteger)index {
|
| - DesktopMediaPickerItem* item = [items_ objectAtIndex:index];
|
| +- (void)imageBrowser:(IKImageBrowserView*)browser
|
| + cellWasDoubleClickedAtIndex:(NSUInteger)index {
|
| + DesktopMediaPickerItem* item;
|
| + if (browser == screenBrowser_)
|
| + item = [screenItems_ objectAtIndex:index];
|
| + else
|
| + item = [windowItems_ objectAtIndex:index];
|
| [self reportResult:[item sourceID]];
|
| [self close];
|
| }
|
|
|
| - (void)imageBrowserSelectionDidChange:(IKImageBrowserView*)browser {
|
| - NSIndexSet* indexes = [sourceBrowser_ selectionIndexes];
|
| -
|
| + DesktopMediaID::Type selectedType = [self selectedSourceType];
|
| + NSInteger selectedIndex = [self selectedIndexForType:selectedType];
|
| // Enable or disable the OK button based on whether we have a selection.
|
| - [shareButton_ setEnabled:([indexes count] > 0)];
|
| + [shareButton_ setEnabled:(selectedIndex >= 0)];
|
| +}
|
| +
|
| +#pragma mark NSTableViewDataSource
|
| +
|
| +- (NSInteger)numberOfRowsInTableView:(NSTableView*)table {
|
| + return [tabItems_ count];
|
| +}
|
|
|
| - // Enable or disable the checkbox based on whether we can support audio for
|
| - // the selected source.
|
| - // On Mac, the checkbox will enabled for tab sharing, namely
|
| - // TYPE_WEB_CONTENTS.
|
| - if ([indexes count] == 0) {
|
| - if ([audioShareCheckbox_ isEnabled]) {
|
| - [audioShareCheckbox_ setEnabled:NO];
|
| - audioShareState_ = [audioShareCheckbox_ state];
|
| - [audioShareCheckbox_ setState:NSOffState];
|
| +#pragma mark NSTableViewDelegate
|
| +
|
| +- (NSView*)tableView:(NSTableView*)table
|
| + viewForTableColumn:(NSTableColumn*)column
|
| + row:(NSInteger)rowIndex {
|
| + if ([[column identifier] isEqualToString:kIconId]) {
|
| + NSImage* image = [[tabItems_ objectAtIndex:rowIndex] imageRepresentation];
|
| + base::scoped_nsobject<NSImageView> iconView(
|
| + [[table makeViewWithIdentifier:kIconId owner:self] retain]);
|
| + if (!iconView) {
|
| + iconView.reset([[NSImageView alloc]
|
| + initWithFrame:NSMakeRect(0, 0, kIconWidth, kRowWidth)]);
|
| + [iconView setIdentifier:kIconId];
|
| }
|
| - [audioShareCheckbox_
|
| - setToolTip:l10n_util::GetNSString(
|
| - IDS_DESKTOP_MEDIA_PICKER_AUDIO_SHARE_TOOLTIP_MAC)];
|
| - return;
|
| + [iconView setImage:image];
|
| + return iconView.autorelease();
|
| }
|
|
|
| - NSUInteger selectedIndex = [indexes firstIndex];
|
| - DesktopMediaPickerItem* item = [items_ objectAtIndex:selectedIndex];
|
| - switch ([item sourceID].type) {
|
| - case content::DesktopMediaID::TYPE_SCREEN:
|
| - case content::DesktopMediaID::TYPE_WINDOW:
|
| - if ([audioShareCheckbox_ isEnabled]) {
|
| - [audioShareCheckbox_ setEnabled:NO];
|
| - audioShareState_ = [audioShareCheckbox_ state];
|
| - [audioShareCheckbox_ setState:NSOffState];
|
| - }
|
| - [audioShareCheckbox_
|
| - setToolTip:l10n_util::GetNSString(
|
| - IDS_DESKTOP_MEDIA_PICKER_AUDIO_SHARE_TOOLTIP_MAC)];
|
| - break;
|
| - case content::DesktopMediaID::TYPE_WEB_CONTENTS:
|
| - if (![audioShareCheckbox_ isEnabled]) {
|
| - [audioShareCheckbox_ setEnabled:YES];
|
| - [audioShareCheckbox_ setState:audioShareState_];
|
| - }
|
| - [audioShareCheckbox_ setToolTip:@""];
|
| - break;
|
| - case content::DesktopMediaID::TYPE_NONE:
|
| - NOTREACHED();
|
| + NSString* string = [[tabItems_ objectAtIndex:rowIndex] imageTitle];
|
| + base::scoped_nsobject<NSTextField> titleView(
|
| + [[table makeViewWithIdentifier:kTitleId owner:self] retain]);
|
| + if (!titleView) {
|
| + titleView.reset(
|
| + [[self createTextFieldWithText:string frameWidth:kMinimumContentWidth]
|
| + retain]);
|
| + [titleView setIdentifier:kTitleId];
|
| + } else {
|
| + [titleView setStringValue:string];
|
| }
|
| + return titleView.autorelease();
|
| +}
|
| +
|
| +- (void)tableViewSelectionDidChange:(NSNotification*)notification {
|
| + NSIndexSet* indexes = [tabBrowser_ selectedRowIndexes];
|
| +
|
| + // Enable or disable the OK button based on whether we have a selection.
|
| + [shareButton_ setEnabled:([indexes count] > 0)];
|
| }
|
|
|
| #pragma mark DesktopMediaPickerObserver
|
|
|
| -- (void)sourceAddedAtIndex:(int)index {
|
| - const DesktopMediaList::Source& source = media_list_->GetSource(index);
|
| +- (void)sourceAddedForList:(DesktopMediaList*)list atIndex:(int)index {
|
| + DesktopMediaID::Type sourceType = [self sourceTypeForList:list];
|
| + NSMutableArray* items = [self itemSetForType:sourceType];
|
| + id browser = [self browserViewForType:sourceType];
|
| + NSInteger selectedIndex = [self selectedIndexForType:sourceType];
|
| + if (selectedIndex >= index)
|
| + ++selectedIndex;
|
| +
|
| + const DesktopMediaList::Source& source = list->GetSource(index);
|
| NSString* imageTitle = base::SysUTF16ToNSString(source.name);
|
| base::scoped_nsobject<DesktopMediaPickerItem> item(
|
| [[DesktopMediaPickerItem alloc] initWithSourceId:source.id
|
| imageUID:++lastImageUID_
|
| imageTitle:imageTitle]);
|
| - [items_ insertObject:item atIndex:index];
|
| - [sourceBrowser_ reloadData];
|
| + [items insertObject:item atIndex:index];
|
| + [browser reloadData];
|
| + if (sourceType == DesktopMediaID::TYPE_WEB_CONTENTS)
|
| + [self setTabBrowserIndex:selectedIndex];
|
|
|
| NSString* autoselectSource = base::SysUTF8ToNSString(
|
| base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
|
| @@ -412,38 +696,85 @@ const int kExcessButtonPadding = 6;
|
| }
|
| }
|
|
|
| -- (void)sourceRemovedAtIndex:(int)index {
|
| - if ([[sourceBrowser_ selectionIndexes] containsIndex:index]) {
|
| +- (void)sourceRemovedForList:(DesktopMediaList*)list atIndex:(int)index {
|
| + DesktopMediaID::Type sourceType = [self sourceTypeForList:list];
|
| + NSMutableArray* items = [self itemSetForType:sourceType];
|
| + id browser = [self browserViewForType:sourceType];
|
| +
|
| + if (sourceType == DesktopMediaID::TYPE_WEB_CONTENTS) {
|
| + NSInteger selectedIndex = [self selectedIndexForType:sourceType];
|
| + if (selectedIndex > index)
|
| + --selectedIndex;
|
| + else if (selectedIndex == index)
|
| + selectedIndex = -1;
|
| + [tabItems_ removeObjectAtIndex:index];
|
| + [tabBrowser_ reloadData];
|
| + [self setTabBrowserIndex:selectedIndex];
|
| + return;
|
| + }
|
| +
|
| + if ([[browser selectionIndexes] containsIndex:index]) {
|
| // Selected item was removed. Clear selection.
|
| - [sourceBrowser_ setSelectionIndexes:[NSIndexSet indexSet]
|
| - byExtendingSelection:FALSE];
|
| + [browser setSelectionIndexes:[NSIndexSet indexSet] byExtendingSelection:NO];
|
| }
|
| - [items_ removeObjectAtIndex:index];
|
| - [sourceBrowser_ reloadData];
|
| + [items removeObjectAtIndex:index];
|
| + [browser reloadData];
|
| }
|
|
|
| -- (void)sourceMovedFrom:(int)oldIndex to:(int)newIndex {
|
| +- (void)sourceMovedForList:(DesktopMediaList*)list
|
| + from:(int)oldIndex
|
| + to:(int)newIndex {
|
| + DesktopMediaID::Type sourceType = [self sourceTypeForList:list];
|
| + NSMutableArray* items = [self itemSetForType:sourceType];
|
| + id browser = [self browserViewForType:sourceType];
|
| + NSInteger selectedIndex = [self selectedIndexForType:sourceType];
|
| + if (selectedIndex > oldIndex && selectedIndex <= newIndex)
|
| + --selectedIndex;
|
| + else if (selectedIndex < oldIndex && selectedIndex >= newIndex)
|
| + ++selectedIndex;
|
| + else if (selectedIndex == oldIndex)
|
| + selectedIndex = newIndex;
|
| +
|
| base::scoped_nsobject<DesktopMediaPickerItem> item(
|
| - [[items_ objectAtIndex:oldIndex] retain]);
|
| - [items_ removeObjectAtIndex:oldIndex];
|
| - [items_ insertObject:item atIndex:newIndex];
|
| - [sourceBrowser_ reloadData];
|
| + [[items objectAtIndex:oldIndex] retain]);
|
| + [items removeObjectAtIndex:oldIndex];
|
| + [items insertObject:item atIndex:newIndex];
|
| + [browser reloadData];
|
| +
|
| + if (sourceType == DesktopMediaID::TYPE_WEB_CONTENTS)
|
| + [self setTabBrowserIndex:selectedIndex];
|
| }
|
|
|
| -- (void)sourceNameChangedAtIndex:(int)index {
|
| - DesktopMediaPickerItem* item = [items_ objectAtIndex:index];
|
| - const DesktopMediaList::Source& source = media_list_->GetSource(index);
|
| +- (void)sourceNameChangedForList:(DesktopMediaList*)list atIndex:(int)index {
|
| + DesktopMediaID::Type sourceType = [self sourceTypeForList:list];
|
| + NSMutableArray* items = [self itemSetForType:sourceType];
|
| + id browser = [self browserViewForType:sourceType];
|
| + NSInteger selectedIndex = [self selectedIndexForType:sourceType];
|
| +
|
| + DesktopMediaPickerItem* item = [items objectAtIndex:index];
|
| + const DesktopMediaList::Source& source = list->GetSource(index);
|
| [item setImageTitle:base::SysUTF16ToNSString(source.name)];
|
| - [sourceBrowser_ reloadData];
|
| + [browser reloadData];
|
| + if (sourceType == DesktopMediaID::TYPE_WEB_CONTENTS)
|
| + [self setTabBrowserIndex:selectedIndex];
|
| }
|
|
|
| -- (void)sourceThumbnailChangedAtIndex:(int)index {
|
| - const DesktopMediaList::Source& source = media_list_->GetSource(index);
|
| +- (void)sourceThumbnailChangedForList:(DesktopMediaList*)list
|
| + atIndex:(int)index {
|
| + DesktopMediaID::Type sourceType = [self sourceTypeForList:list];
|
| + NSMutableArray* items = [self itemSetForType:sourceType];
|
| + id browser = [self browserViewForType:sourceType];
|
| + NSInteger selectedIndex = [self selectedIndexForType:sourceType];
|
| +
|
| + const DesktopMediaList::Source& source = list->GetSource(index);
|
| NSImage* image = gfx::NSImageFromImageSkia(source.thumbnail);
|
|
|
| - DesktopMediaPickerItem* item = [items_ objectAtIndex:index];
|
| + DesktopMediaPickerItem* item = [items objectAtIndex:index];
|
| [item setImageRepresentation:image];
|
| - [sourceBrowser_ reloadData];
|
| + [browser reloadData];
|
| +
|
| + if (sourceType == DesktopMediaID::TYPE_WEB_CONTENTS)
|
| + [self setTabBrowserIndex:selectedIndex];
|
| }
|
|
|
| @end // @interface DesktopMediaPickerController
|
|
|