desktop_media_picker_views.cc revision ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16
1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Copyright 2013 The Chromium Authors. All rights reserved. 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Use of this source code is governed by a BSD-style license that can be 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// found in the LICENSE file. 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/browser/media/desktop_media_picker.h" 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ash/shell.h" 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "base/callback.h" 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "chrome/browser/media/desktop_media_picker_model.h" 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "content/public/browser/browser_thread.h" 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "grit/generated_resources.h" 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/base/keycodes/keyboard_codes.h" 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/base/l10n/l10n_util.h" 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/native_theme/native_theme.h" 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/views/controls/image_view.h" 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/views/controls/label.h" 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/views/controls/scroll_view.h" 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/views/corewm/shadow_types.h" 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/views/focus_border.h" 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/views/layout/box_layout.h" 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/views/layout/layout_constants.h" 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/views/widget/widget.h" 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/views/window/dialog_client_view.h" 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ui/views/window/dialog_delegate.h" 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverusing content::DesktopMediaID; 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernamespace { 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst int kThumbnailWidth = 160; 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst int kThumbnailHeight = 100; 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst int kThumbnailMargin = 10; 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst int kLabelHeight = 40; 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst int kListItemWidth = kThumbnailMargin * 2 + kThumbnailWidth; 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst int kListItemHeight = 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver kThumbnailMargin * 2 + kThumbnailHeight + kLabelHeight; 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst int kListColumns = 3; 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst int kTotalListWidth = kListColumns * kListItemWidth; 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst int kDesktopMediaSourceViewGroupId = 1; 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst char kDesktopMediaSourceViewClassName[] = 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "DesktopMediaPicker_DesktopMediaSourceView"; 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass DesktopMediaListView; 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass DesktopMediaPickerDialogView; 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass DesktopMediaPickerViews; 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// View used for each item in DesktopMediaListView. Shows a single desktop media 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// source as a thumbnail with the title under it. 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass DesktopMediaSourceView : public views::View { 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public: 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaSourceView(DesktopMediaListView* parent, 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaID source_id); 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual ~DesktopMediaSourceView(); 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Updates thumbnail and title from |source|. 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver void SetName(const string16& name); 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver void SetThumbnail(const gfx::ImageSkia& thumbnail); 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Id for the source shown by this View. 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver const DesktopMediaID& source_id() const { 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return source_id_; 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Returns true if the source is selected. 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver bool is_selected() const { return selected_; } 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Updates selection state of the element. If |selected| is true then also 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // calls SetSelected(false) for the source view that was selected before that 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // (if any). 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver void SetSelected(bool selected); 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // views::View interface. 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual const char* GetClassName() const OVERRIDE; 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual void Layout() OVERRIDE; 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual views::View* GetSelectedViewForGroup(int group) OVERRIDE; 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual bool IsGroupFocusTraversable() const OVERRIDE; 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual void OnFocus() OVERRIDE; 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver private: 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaListView* parent_; 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaID source_id_; 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver views::ImageView* image_view_; 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver views::Label* label_; 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver bool selected_; 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DISALLOW_COPY_AND_ASSIGN(DesktopMediaSourceView); 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}; 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// View that shows list of desktop media sources available from 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// DesktopMediaPickerModel. 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass DesktopMediaListView : public views::View, 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public DesktopMediaPickerModel::Observer { 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public: 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaListView(DesktopMediaPickerDialogView* parent, 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver scoped_ptr<DesktopMediaPickerModel> model); 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual ~DesktopMediaListView(); 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Called by DesktopMediaSourceView when selection has changed. 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver void OnSelectionChanged(); 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Returns currently selected source. 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaSourceView* GetSelection(); 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // views::View overrides. 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual gfx::Size GetPreferredSize() OVERRIDE; 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual void Layout() OVERRIDE; 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE; 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver private: 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // DesktopMediaPickerModel::Observer interface 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual void OnSourceAdded(int index) OVERRIDE; 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual void OnSourceRemoved(int index) OVERRIDE; 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual void OnSourceNameChanged(int index) OVERRIDE; 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual void OnSourceThumbnailChanged(int index) OVERRIDE; 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaPickerDialogView* parent_; 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver scoped_ptr<DesktopMediaPickerModel> model_; 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DISALLOW_COPY_AND_ASSIGN(DesktopMediaListView); 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}; 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Dialog view used for DesktopMediaPickerViews. 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass DesktopMediaPickerDialogView : public views::DialogDelegateView { 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public: 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaPickerDialogView(gfx::NativeWindow context, 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver gfx::NativeWindow parent_window, 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaPickerViews* parent, 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver const string16& app_name, 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver scoped_ptr<DesktopMediaPickerModel> model); 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual ~DesktopMediaPickerDialogView(); 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Called by parent (DesktopMediaPickerViews) when it's destroyed. 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver void DetachParent(); 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Called by DesktopMediaListView. 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver void OnSelectionChanged(); 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // views::View overrides. 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual gfx::Size GetPreferredSize() OVERRIDE; 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual void Layout() OVERRIDE; 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // views::DialogDelegateView overrides. 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual base::string16 GetWindowTitle() const OVERRIDE; 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual bool IsDialogButtonEnabled(ui::DialogButton button) const OVERRIDE; 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual bool Accept() OVERRIDE; 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual void DeleteDelegate() OVERRIDE; 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver private: 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaPickerViews* parent_; 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver string16 app_name_; 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver views::Label* label_; 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver views::ScrollView* scroll_view_; 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaListView* list_view_; 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DISALLOW_COPY_AND_ASSIGN(DesktopMediaPickerDialogView); 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}; 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Implementation of DesktopMediaPicker for Views. 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass DesktopMediaPickerViews : public DesktopMediaPicker { 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public: 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaPickerViews(); 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual ~DesktopMediaPickerViews(); 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver void NotifyDialogResult(DesktopMediaID source); 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // DesktopMediaPicker overrides. 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver virtual void Show(gfx::NativeWindow context, 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver gfx::NativeWindow parent, 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver const string16& app_name, 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver scoped_ptr<DesktopMediaPickerModel> model, 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver const DoneCallback& done_callback) OVERRIDE; 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver private: 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DoneCallback callback_; 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // The |dialog_| is owned by the corresponding views::Widget instance. 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // When DesktopMediaPickerViews is destroyed the |dialog_| is destroyed 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // asynchronously by closing the widget. 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaPickerDialogView* dialog_; 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DISALLOW_COPY_AND_ASSIGN(DesktopMediaPickerViews); 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}; 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 190324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDesktopMediaSourceView::DesktopMediaSourceView( 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaListView* parent, 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaID source_id) 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : parent_(parent), 194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver source_id_(source_id), 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver image_view_(new views::ImageView()), 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver label_(new views::Label()), 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver selected_(false) { 198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver AddChildView(image_view_); 199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver AddChildView(label_); 200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver set_focusable(true); 201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 203324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDesktopMediaSourceView::~DesktopMediaSourceView() {} 204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid DesktopMediaSourceView::SetName(const string16& name) { 206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver label_->SetText(name); 207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid DesktopMediaSourceView::SetThumbnail(const gfx::ImageSkia& thumbnail) { 210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver image_view_->SetImage(thumbnail); 211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid DesktopMediaSourceView::SetSelected(bool selected) { 214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (selected == selected_) 215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver selected_ = selected; 217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (selected) { 219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Unselect all other sources. 220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Views neighbours; 221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parent()->GetViewsInGroup(GetGroup(), &neighbours); 222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (Views::iterator i(neighbours.begin()); i != neighbours.end(); ++i) { 223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (*i != this) { 224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DCHECK_EQ((*i)->GetClassName(), kDesktopMediaSourceViewClassName); 225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaSourceView* source_view = 226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver static_cast<DesktopMediaSourceView*>(*i); 227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver source_view->SetSelected(false); 228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver const SkColor bg_color = GetNativeTheme()->GetSystemColor( 232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ui::NativeTheme::kColorId_FocusedMenuItemBackgroundColor); 233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver set_background(views::Background::CreateSolidBackground(bg_color)); 234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parent_->OnSelectionChanged(); 236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else { 237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver set_background(NULL); 238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SchedulePaint(); 241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst char* DesktopMediaSourceView::GetClassName() const { 244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return kDesktopMediaSourceViewClassName; 245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid DesktopMediaSourceView::Layout() { 248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver image_view_->SetBounds(kThumbnailMargin, kThumbnailMargin, 249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver kThumbnailWidth, kThumbnailHeight); 250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver label_->SetBounds(kThumbnailMargin, kThumbnailHeight + kThumbnailMargin, 251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver kThumbnailWidth, kLabelHeight); 252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver set_focus_border(views::FocusBorder::CreateDashedFocusBorder( 254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver kThumbnailMargin / 2, kThumbnailMargin / 2, 255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver kThumbnailMargin / 2, kThumbnailMargin / 2)); 256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverviews::View* DesktopMediaSourceView::GetSelectedViewForGroup(int group) { 259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Views neighbours; 260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parent()->GetViewsInGroup(group, &neighbours); 261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (neighbours.empty()) 262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; 263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (Views::iterator i(neighbours.begin()); i != neighbours.end(); ++i) { 265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DCHECK_EQ((*i)->GetClassName(), kDesktopMediaSourceViewClassName); 266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaSourceView* source_view = 267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver static_cast<DesktopMediaSourceView*>(*i); 268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (source_view->selected_) 269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return source_view; 270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; 272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverbool DesktopMediaSourceView::IsGroupFocusTraversable() const { 275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; 276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid DesktopMediaSourceView::OnFocus() { 279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver View::OnFocus(); 280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SetSelected(true); 281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ScrollRectToVisible(gfx::Rect(size())); 282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverbool DesktopMediaSourceView::OnMousePressed(const ui::MouseEvent& event) { 285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver RequestFocus(); 286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return true; 287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 289324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDesktopMediaListView::DesktopMediaListView( 290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaPickerDialogView* parent, 291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver scoped_ptr<DesktopMediaPickerModel> model) 292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : parent_(parent), 293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver model_(model.Pass()) { 294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver model_->SetThumbnailSize(gfx::Size(kThumbnailWidth, kThumbnailHeight)); 295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver model_->StartUpdating(this); 296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 298324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDesktopMediaListView::~DesktopMediaListView() { 299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid DesktopMediaListView::OnSelectionChanged() { 302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parent_->OnSelectionChanged(); 303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 305324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDesktopMediaSourceView* DesktopMediaListView::GetSelection() { 306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (int i = 0; i < child_count(); ++i) { 307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaSourceView* source_view = 308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver static_cast<DesktopMediaSourceView*>(child_at(i)); 309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DCHECK_EQ(source_view->GetClassName(), kDesktopMediaSourceViewClassName); 310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (source_view->is_selected()) 311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return source_view; 312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; 314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvergfx::Size DesktopMediaListView::GetPreferredSize() { 317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int total_rows = (child_count() + kListColumns - 1) / kListColumns; 318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return gfx::Size(kTotalListWidth, kListItemHeight * total_rows); 319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid DesktopMediaListView::Layout() { 322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int x = 0; 323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int y = 0; 324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (int i = 0; i < child_count(); ++i) { 326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (x + kListItemWidth > kTotalListWidth) { 327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver x = 0; 328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver y += kListItemHeight; 329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver View* source_view = child_at(i); 332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver source_view->SetBounds(x, y, kListItemWidth, kListItemHeight); 333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver x += kListItemWidth; 335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver y += kListItemHeight; 339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SetSize(gfx::Size(kTotalListWidth, y)); 340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverbool DesktopMediaListView::OnKeyPressed(const ui::KeyEvent& event) { 343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int position_increment = 0; 344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver switch (event.key_code()) { 345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case ui::VKEY_UP: 346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver position_increment = -kListColumns; 347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break; 348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case ui::VKEY_DOWN: 349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver position_increment = kListColumns; 350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break; 351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case ui::VKEY_LEFT: 352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver position_increment = -1; 353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break; 354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case ui::VKEY_RIGHT: 355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver position_increment = 1; 356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break; 357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver default: 358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; 359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (position_increment != 0) { 363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaSourceView* selected = GetSelection(); 364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DesktopMediaSourceView* new_selected = NULL; 365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (selected) { 367 int index = GetIndexOf(selected); 368 int new_index = index + position_increment; 369 if (new_index >= child_count()) 370 new_index = child_count() - 1; 371 else if (new_index < 0) 372 new_index = 0; 373 if (index != new_index) { 374 new_selected = 375 static_cast<DesktopMediaSourceView*>(child_at(new_index)); 376 } 377 } else if (has_children()) { 378 new_selected = static_cast<DesktopMediaSourceView*>(child_at(0)); 379 } 380 381 if (new_selected) { 382 GetFocusManager()->SetFocusedView(new_selected); 383 } 384 385 return true; 386 } 387 388 return false; 389} 390 391void DesktopMediaListView::OnSourceAdded(int index) { 392 const DesktopMediaPickerModel::Source& source = model_->source(index); 393 DesktopMediaSourceView* source_view = 394 new DesktopMediaSourceView(this, source.id); 395 source_view->SetName(source.name); 396 source_view->SetGroup(kDesktopMediaSourceViewGroupId); 397 AddChildViewAt(source_view, index); 398 Layout(); 399} 400 401void DesktopMediaListView::OnSourceRemoved(int index) { 402 DesktopMediaSourceView* view = 403 static_cast<DesktopMediaSourceView*>(child_at(index)); 404 DCHECK(view); 405 DCHECK_EQ(view->GetClassName(), kDesktopMediaSourceViewClassName); 406 bool was_selected = view->is_selected(); 407 RemoveChildView(view); 408 delete view; 409 410 if (was_selected) 411 OnSelectionChanged(); 412 413 PreferredSizeChanged(); 414} 415 416void DesktopMediaListView::OnSourceNameChanged(int index) { 417 const DesktopMediaPickerModel::Source& source = model_->source(index); 418 DesktopMediaSourceView* source_view = 419 static_cast<DesktopMediaSourceView*>(child_at(index)); 420 source_view->SetName(source.name); 421} 422 423void DesktopMediaListView::OnSourceThumbnailChanged(int index) { 424 const DesktopMediaPickerModel::Source& source = model_->source(index); 425 DesktopMediaSourceView* source_view = 426 static_cast<DesktopMediaSourceView*>(child_at(index)); 427 source_view->SetThumbnail(source.thumbnail); 428} 429 430DesktopMediaPickerDialogView::DesktopMediaPickerDialogView( 431 gfx::NativeWindow context, 432 gfx::NativeWindow parent_window, 433 DesktopMediaPickerViews* parent, 434 const string16& app_name, 435 scoped_ptr<DesktopMediaPickerModel> model) 436 : parent_(parent), 437 app_name_(app_name), 438 label_(new views::Label()), 439 scroll_view_(views::ScrollView::CreateScrollViewWithBorder()), 440 list_view_(new DesktopMediaListView(this, model.Pass())) { 441 label_->SetText( 442 l10n_util::GetStringFUTF16(IDS_DESKTOP_MEDIA_PICKER_TEXT, app_name_)); 443 label_->SetMultiLine(true); 444 label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 445 AddChildView(label_); 446 447 scroll_view_->SetContents(list_view_); 448 AddChildView(scroll_view_); 449 450 DialogDelegate::CreateDialogWidget(this, context, parent_window); 451 GetWidget()->Show(); 452} 453 454DesktopMediaPickerDialogView::~DesktopMediaPickerDialogView() {} 455 456void DesktopMediaPickerDialogView::DetachParent() { 457 parent_ = NULL; 458} 459 460gfx::Size DesktopMediaPickerDialogView::GetPreferredSize() { 461 return gfx::Size(600, 500); 462} 463 464void DesktopMediaPickerDialogView::Layout() { 465 gfx::Rect rect = GetLocalBounds(); 466 rect.Inset(views::kPanelHorizMargin, views::kPanelVertMargin); 467 468 gfx::Rect label_rect(rect.x(), rect.y(), rect.width(), 469 label_->GetHeightForWidth(rect.width())); 470 label_->SetBoundsRect(label_rect); 471 472 int scroll_view_top = label_rect.bottom() + views::kPanelVerticalSpacing; 473 scroll_view_->SetBounds( 474 rect.x(), scroll_view_top, 475 rect.width(), rect.height() - scroll_view_top); 476} 477 478base::string16 DesktopMediaPickerDialogView::GetWindowTitle() const { 479 return l10n_util::GetStringFUTF16(IDS_DESKTOP_MEDIA_PICKER_TITLE, app_name_); 480} 481 482bool DesktopMediaPickerDialogView::IsDialogButtonEnabled( 483 ui::DialogButton button) const { 484 if (button == ui::DIALOG_BUTTON_OK) 485 return list_view_->GetSelection() != NULL; 486 return true; 487} 488 489bool DesktopMediaPickerDialogView::Accept() { 490 DesktopMediaSourceView* selection = list_view_->GetSelection(); 491 492 // Ok button should only be enabled when a source is selected. 493 DCHECK(selection); 494 495 DesktopMediaID source; 496 if (selection) 497 source = selection->source_id(); 498 499 if (parent_) 500 parent_->NotifyDialogResult(source); 501 502 // Return true to close the window. 503 return true; 504} 505 506void DesktopMediaPickerDialogView::DeleteDelegate() { 507 // If the dialog is being closed then notify the parent about it. 508 if (parent_) 509 parent_->NotifyDialogResult(DesktopMediaID()); 510 delete this; 511} 512 513void DesktopMediaPickerDialogView::OnSelectionChanged() { 514 GetDialogClientView()->UpdateDialogButtons(); 515} 516 517DesktopMediaPickerViews::DesktopMediaPickerViews() 518 : dialog_(NULL) { 519} 520 521DesktopMediaPickerViews::~DesktopMediaPickerViews() { 522 if (dialog_) { 523 dialog_->DetachParent(); 524 dialog_->GetWidget()->Close(); 525 } 526} 527 528void DesktopMediaPickerViews::Show(gfx::NativeWindow context, 529 gfx::NativeWindow parent, 530 const string16& app_name, 531 scoped_ptr<DesktopMediaPickerModel> model, 532 const DoneCallback& done_callback) { 533 callback_ = done_callback; 534 dialog_ = new DesktopMediaPickerDialogView( 535 context, parent, this, app_name, model.Pass()); 536} 537 538void DesktopMediaPickerViews::NotifyDialogResult( 539 DesktopMediaID source) { 540 // Once this method is called the |dialog_| will close and destroy itself. 541 dialog_->DetachParent(); 542 dialog_ = NULL; 543 544 DCHECK(!callback_.is_null()); 545 546 // Notify the |callback_| asynchronously because it may need to destroy 547 // DesktopMediaPicker. 548 content::BrowserThread::PostTask( 549 content::BrowserThread::UI, FROM_HERE, 550 base::Bind(callback_, source)); 551 callback_.Reset(); 552} 553 554} // namespace 555 556// static 557scoped_ptr<DesktopMediaPicker> DesktopMediaPicker::Create() { 558 return scoped_ptr<DesktopMediaPicker>(new DesktopMediaPickerViews()); 559} 560