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 #include "chrome/browser/media/desktop_media_picker.h" | 5 #include "chrome/browser/ui/views/desktop_media_picker_views.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "chrome/browser/media/desktop_media_list.h" | 8 #include "chrome/browser/media/desktop_media_list.h" |
9 #include "chrome/browser/media/desktop_media_list_observer.h" | |
10 #include "chrome/browser/ui/ash/ash_util.h" | 9 #include "chrome/browser/ui/ash/ash_util.h" |
11 #include "chrome/browser/ui/views/constrained_window_views.h" | 10 #include "chrome/browser/ui/views/constrained_window_views.h" |
12 #include "components/web_modal/popup_manager.h" | 11 #include "components/web_modal/popup_manager.h" |
13 #include "content/public/browser/browser_thread.h" | 12 #include "content/public/browser/browser_thread.h" |
14 #include "grit/generated_resources.h" | 13 #include "grit/generated_resources.h" |
15 #include "ui/aura/window_tree_host.h" | 14 #include "ui/aura/window_tree_host.h" |
16 #include "ui/base/l10n/l10n_util.h" | 15 #include "ui/base/l10n/l10n_util.h" |
17 #include "ui/events/event_constants.h" | 16 #include "ui/events/event_constants.h" |
18 #include "ui/events/keycodes/keyboard_codes.h" | 17 #include "ui/events/keycodes/keyboard_codes.h" |
19 #include "ui/gfx/canvas.h" | 18 #include "ui/gfx/canvas.h" |
20 #include "ui/native_theme/native_theme.h" | 19 #include "ui/native_theme/native_theme.h" |
21 #include "ui/views/background.h" | 20 #include "ui/views/background.h" |
22 #include "ui/views/bubble/bubble_frame_view.h" | 21 #include "ui/views/bubble/bubble_frame_view.h" |
23 #include "ui/views/controls/image_view.h" | 22 #include "ui/views/controls/image_view.h" |
24 #include "ui/views/controls/label.h" | 23 #include "ui/views/controls/label.h" |
25 #include "ui/views/controls/scroll_view.h" | 24 #include "ui/views/controls/scroll_view.h" |
26 #include "ui/views/layout/box_layout.h" | |
27 #include "ui/views/layout/layout_constants.h" | 25 #include "ui/views/layout/layout_constants.h" |
28 #include "ui/views/widget/widget.h" | 26 #include "ui/views/widget/widget.h" |
29 #include "ui/views/window/dialog_client_view.h" | 27 #include "ui/views/window/dialog_client_view.h" |
30 #include "ui/views/window/dialog_delegate.h" | |
31 #include "ui/wm/core/shadow_types.h" | 28 #include "ui/wm/core/shadow_types.h" |
32 | 29 |
33 using content::DesktopMediaID; | 30 using content::DesktopMediaID; |
34 | 31 |
35 namespace { | 32 namespace { |
36 | 33 |
37 const int kThumbnailWidth = 160; | 34 const int kThumbnailWidth = 160; |
38 const int kThumbnailHeight = 100; | 35 const int kThumbnailHeight = 100; |
39 const int kThumbnailMargin = 10; | 36 const int kThumbnailMargin = 10; |
40 const int kLabelHeight = 40; | 37 const int kLabelHeight = 40; |
41 const int kListItemWidth = kThumbnailMargin * 2 + kThumbnailWidth; | 38 const int kListItemWidth = kThumbnailMargin * 2 + kThumbnailWidth; |
42 const int kListItemHeight = | 39 const int kListItemHeight = |
43 kThumbnailMargin * 2 + kThumbnailHeight + kLabelHeight; | 40 kThumbnailMargin * 2 + kThumbnailHeight + kLabelHeight; |
44 const int kListColumns = 3; | 41 const int kListColumns = 3; |
45 const int kTotalListWidth = kListColumns * kListItemWidth; | 42 const int kTotalListWidth = kListColumns * kListItemWidth; |
46 | 43 |
47 const int kDesktopMediaSourceViewGroupId = 1; | 44 const int kDesktopMediaSourceViewGroupId = 1; |
48 | 45 |
49 const char kDesktopMediaSourceViewClassName[] = | 46 const char kDesktopMediaSourceViewClassName[] = |
50 "DesktopMediaPicker_DesktopMediaSourceView"; | 47 "DesktopMediaPicker_DesktopMediaSourceView"; |
51 | 48 |
52 content::DesktopMediaID::Id AcceleratedWidgetToDesktopMediaId( | 49 DesktopMediaID::Id AcceleratedWidgetToDesktopMediaId( |
53 gfx::AcceleratedWidget accelerated_widget) { | 50 gfx::AcceleratedWidget accelerated_widget) { |
54 #if defined(OS_WIN) | 51 #if defined(OS_WIN) |
55 return reinterpret_cast<content::DesktopMediaID::Id>(accelerated_widget); | 52 return reinterpret_cast<DesktopMediaID::Id>(accelerated_widget); |
56 #else | 53 #else |
57 return static_cast<content::DesktopMediaID::Id>(accelerated_widget); | 54 return static_cast<DesktopMediaID::Id>(accelerated_widget); |
58 #endif | 55 #endif |
59 } | 56 } |
60 | 57 |
61 int GetMediaListViewHeightForRows(size_t rows) { | 58 int GetMediaListViewHeightForRows(size_t rows) { |
62 return kListItemHeight * rows; | 59 return kListItemHeight * rows; |
63 } | 60 } |
64 | 61 |
65 class DesktopMediaListView; | 62 } // namespace |
66 class DesktopMediaPickerDialogView; | |
67 class DesktopMediaPickerViews; | |
68 | |
69 // View used for each item in DesktopMediaListView. Shows a single desktop media | |
70 // source as a thumbnail with the title under it. | |
71 class DesktopMediaSourceView : public views::View { | |
72 public: | |
73 DesktopMediaSourceView(DesktopMediaListView* parent, | |
74 DesktopMediaID source_id); | |
75 virtual ~DesktopMediaSourceView(); | |
76 | |
77 // Updates thumbnail and title from |source|. | |
78 void SetName(const base::string16& name); | |
79 void SetThumbnail(const gfx::ImageSkia& thumbnail); | |
80 | |
81 // Id for the source shown by this View. | |
82 const DesktopMediaID& source_id() const { | |
83 return source_id_; | |
84 } | |
85 | |
86 // Returns true if the source is selected. | |
87 bool is_selected() const { return selected_; } | |
88 | |
89 // Updates selection state of the element. If |selected| is true then also | |
90 // calls SetSelected(false) for the source view that was selected before that | |
91 // (if any). | |
92 void SetSelected(bool selected); | |
93 | |
94 // views::View interface. | |
95 virtual const char* GetClassName() const OVERRIDE; | |
96 virtual void Layout() OVERRIDE; | |
97 virtual views::View* GetSelectedViewForGroup(int group) OVERRIDE; | |
98 virtual bool IsGroupFocusTraversable() const OVERRIDE; | |
99 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; | |
100 virtual void OnFocus() OVERRIDE; | |
101 virtual void OnBlur() OVERRIDE; | |
102 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; | |
103 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; | |
104 | |
105 private: | |
106 DesktopMediaListView* parent_; | |
107 DesktopMediaID source_id_; | |
108 | |
109 views::ImageView* image_view_; | |
110 views::Label* label_; | |
111 | |
112 bool selected_; | |
113 | |
114 DISALLOW_COPY_AND_ASSIGN(DesktopMediaSourceView); | |
115 }; | |
116 | |
117 // View that shows list of desktop media sources available from | |
118 // DesktopMediaList. | |
119 class DesktopMediaListView : public views::View, | |
120 public DesktopMediaListObserver { | |
121 public: | |
122 DesktopMediaListView(DesktopMediaPickerDialogView* parent, | |
123 scoped_ptr<DesktopMediaList> media_list); | |
124 virtual ~DesktopMediaListView(); | |
125 | |
126 void StartUpdating(content::DesktopMediaID::Id dialog_window_id); | |
127 | |
128 // Called by DesktopMediaSourceView when selection has changed. | |
129 void OnSelectionChanged(); | |
130 | |
131 // Called by DesktopMediaSourceView when a source has been double-clicked. | |
132 void OnDoubleClick(); | |
133 | |
134 // Returns currently selected source. | |
135 DesktopMediaSourceView* GetSelection(); | |
136 | |
137 // views::View overrides. | |
138 virtual gfx::Size GetPreferredSize() const OVERRIDE; | |
139 virtual void Layout() OVERRIDE; | |
140 virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE; | |
141 | |
142 private: | |
143 // DesktopMediaList::Observer interface | |
144 virtual void OnSourceAdded(int index) OVERRIDE; | |
145 virtual void OnSourceRemoved(int index) OVERRIDE; | |
146 virtual void OnSourceMoved(int old_index, int new_index) OVERRIDE; | |
147 virtual void OnSourceNameChanged(int index) OVERRIDE; | |
148 virtual void OnSourceThumbnailChanged(int index) OVERRIDE; | |
149 | |
150 DesktopMediaPickerDialogView* parent_; | |
151 scoped_ptr<DesktopMediaList> media_list_; | |
152 | |
153 DISALLOW_COPY_AND_ASSIGN(DesktopMediaListView); | |
154 }; | |
155 | |
156 // Dialog view used for DesktopMediaPickerViews. | |
157 class DesktopMediaPickerDialogView : public views::DialogDelegateView { | |
158 public: | |
159 DesktopMediaPickerDialogView(content::WebContents* parent_web_contents, | |
160 gfx::NativeWindow context, | |
161 gfx::NativeWindow parent_window, | |
162 DesktopMediaPickerViews* parent, | |
163 const base::string16& app_name, | |
164 const base::string16& target_name, | |
165 scoped_ptr<DesktopMediaList> media_list); | |
166 virtual ~DesktopMediaPickerDialogView(); | |
167 | |
168 // Called by parent (DesktopMediaPickerViews) when it's destroyed. | |
169 void DetachParent(); | |
170 | |
171 // Called by DesktopMediaListView. | |
172 void OnSelectionChanged(); | |
173 void OnDoubleClick(); | |
174 | |
175 // views::View overrides. | |
176 virtual gfx::Size GetPreferredSize() const OVERRIDE; | |
177 virtual void Layout() OVERRIDE; | |
178 | |
179 // views::DialogDelegateView overrides. | |
180 virtual ui::ModalType GetModalType() const OVERRIDE; | |
181 virtual base::string16 GetWindowTitle() const OVERRIDE; | |
182 virtual bool IsDialogButtonEnabled(ui::DialogButton button) const OVERRIDE; | |
183 virtual base::string16 GetDialogButtonLabel( | |
184 ui::DialogButton button) const OVERRIDE; | |
185 virtual bool Accept() OVERRIDE; | |
186 virtual void DeleteDelegate() OVERRIDE; | |
187 | |
188 void OnMediaListRowsChanged(); | |
189 | |
190 private: | |
191 DesktopMediaPickerViews* parent_; | |
192 base::string16 app_name_; | |
193 | |
194 views::Label* label_; | |
195 views::ScrollView* scroll_view_; | |
196 DesktopMediaListView* list_view_; | |
197 | |
198 DISALLOW_COPY_AND_ASSIGN(DesktopMediaPickerDialogView); | |
199 }; | |
200 | |
201 // Implementation of DesktopMediaPicker for Views. | |
202 class DesktopMediaPickerViews : public DesktopMediaPicker { | |
203 public: | |
204 DesktopMediaPickerViews(); | |
205 virtual ~DesktopMediaPickerViews(); | |
206 | |
207 void NotifyDialogResult(DesktopMediaID source); | |
208 | |
209 // DesktopMediaPicker overrides. | |
210 virtual void Show(content::WebContents* web_contents, | |
211 gfx::NativeWindow context, | |
212 gfx::NativeWindow parent, | |
213 const base::string16& app_name, | |
214 const base::string16& target_name, | |
215 scoped_ptr<DesktopMediaList> media_list, | |
216 const DoneCallback& done_callback) OVERRIDE; | |
217 | |
218 private: | |
219 DoneCallback callback_; | |
220 | |
221 // The |dialog_| is owned by the corresponding views::Widget instance. | |
222 // When DesktopMediaPickerViews is destroyed the |dialog_| is destroyed | |
223 // asynchronously by closing the widget. | |
224 DesktopMediaPickerDialogView* dialog_; | |
225 | |
226 DISALLOW_COPY_AND_ASSIGN(DesktopMediaPickerViews); | |
227 }; | |
228 | 63 |
229 DesktopMediaSourceView::DesktopMediaSourceView( | 64 DesktopMediaSourceView::DesktopMediaSourceView( |
230 DesktopMediaListView* parent, | 65 DesktopMediaListView* parent, |
231 DesktopMediaID source_id) | 66 DesktopMediaID source_id) |
232 : parent_(parent), | 67 : parent_(parent), |
233 source_id_(source_id), | 68 source_id_(source_id), |
234 image_view_(new views::ImageView()), | 69 image_view_(new views::ImageView()), |
235 label_(new views::Label()), | 70 label_(new views::Label()), |
236 selected_(false) { | 71 selected_(false) { |
237 AddChildView(image_view_); | 72 AddChildView(image_view_); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 DesktopMediaListView::DesktopMediaListView( | 198 DesktopMediaListView::DesktopMediaListView( |
364 DesktopMediaPickerDialogView* parent, | 199 DesktopMediaPickerDialogView* parent, |
365 scoped_ptr<DesktopMediaList> media_list) | 200 scoped_ptr<DesktopMediaList> media_list) |
366 : parent_(parent), | 201 : parent_(parent), |
367 media_list_(media_list.Pass()) { | 202 media_list_(media_list.Pass()) { |
368 media_list_->SetThumbnailSize(gfx::Size(kThumbnailWidth, kThumbnailHeight)); | 203 media_list_->SetThumbnailSize(gfx::Size(kThumbnailWidth, kThumbnailHeight)); |
369 } | 204 } |
370 | 205 |
371 DesktopMediaListView::~DesktopMediaListView() {} | 206 DesktopMediaListView::~DesktopMediaListView() {} |
372 | 207 |
373 void DesktopMediaListView::StartUpdating( | 208 void DesktopMediaListView::StartUpdating(DesktopMediaID::Id dialog_window_id) { |
374 content::DesktopMediaID::Id dialog_window_id) { | |
375 media_list_->SetViewDialogWindowId(dialog_window_id); | 209 media_list_->SetViewDialogWindowId(dialog_window_id); |
376 media_list_->StartUpdating(this); | 210 media_list_->StartUpdating(this); |
377 } | 211 } |
378 | 212 |
379 void DesktopMediaListView::OnSelectionChanged() { | 213 void DesktopMediaListView::OnSelectionChanged() { |
380 parent_->OnSelectionChanged(); | 214 parent_->OnSelectionChanged(); |
381 } | 215 } |
382 | 216 |
383 void DesktopMediaListView::OnDoubleClick() { | 217 void DesktopMediaListView::OnDoubleClick() { |
384 parent_->OnDoubleClick(); | 218 parent_->OnDoubleClick(); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 // by a root window. | 391 // by a root window. |
558 views::Widget* widget = NULL; | 392 views::Widget* widget = NULL; |
559 if (parent_web_contents) | 393 if (parent_web_contents) |
560 widget = CreateWebModalDialogViews(this, parent_web_contents); | 394 widget = CreateWebModalDialogViews(this, parent_web_contents); |
561 else | 395 else |
562 widget = DialogDelegate::CreateDialogWidget(this, context, parent_window); | 396 widget = DialogDelegate::CreateDialogWidget(this, context, parent_window); |
563 | 397 |
564 // DesktopMediaList needs to know the ID of the picker window which | 398 // DesktopMediaList needs to know the ID of the picker window which |
565 // matches the ID it gets from the OS. Depending on the OS and configuration | 399 // matches the ID it gets from the OS. Depending on the OS and configuration |
566 // we get this ID differently. | 400 // we get this ID differently. |
567 content::DesktopMediaID::Id dialog_window_id = 0; | 401 DesktopMediaID::Id dialog_window_id = 0; |
568 | 402 |
569 // If there is |parent_window| or |parent_web_contents|, the picker window | 403 // If there is |parent_window| or |parent_web_contents|, the picker window |
570 // is embedded in the parent and does not have its own native window id, so we | 404 // is embedded in the parent and does not have its own native window id, so we |
571 // do not filter in that case. | 405 // do not filter in that case. |
572 if (!parent_window && !parent_web_contents) { | 406 if (!parent_window && !parent_web_contents) { |
573 #if defined(USE_ASH) | 407 #if defined(USE_ASH) |
574 if (chrome::IsNativeWindowInAsh(widget->GetNativeWindow())) { | 408 if (chrome::IsNativeWindowInAsh(widget->GetNativeWindow())) { |
575 dialog_window_id = content::DesktopMediaID::RegisterAuraWindow( | 409 dialog_window_id = |
576 widget->GetNativeWindow()).id; | 410 DesktopMediaID::RegisterAuraWindow(widget->GetNativeWindow()).id; |
577 DCHECK_NE(dialog_window_id, 0); | 411 DCHECK_NE(dialog_window_id, 0); |
578 } | 412 } |
579 #endif | 413 #endif |
580 | 414 |
581 if (dialog_window_id == 0) { | 415 if (dialog_window_id == 0) { |
582 dialog_window_id = AcceleratedWidgetToDesktopMediaId( | 416 dialog_window_id = AcceleratedWidgetToDesktopMediaId( |
583 widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget()); | 417 widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget()); |
584 } | 418 } |
585 } | 419 } |
586 | 420 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 | 521 |
688 void DesktopMediaPickerDialogView::OnMediaListRowsChanged() { | 522 void DesktopMediaPickerDialogView::OnMediaListRowsChanged() { |
689 gfx::Rect widget_bound = GetWidget()->GetWindowBoundsInScreen(); | 523 gfx::Rect widget_bound = GetWidget()->GetWindowBoundsInScreen(); |
690 | 524 |
691 int new_height = widget_bound.height() - scroll_view_->height() + | 525 int new_height = widget_bound.height() - scroll_view_->height() + |
692 scroll_view_->GetPreferredSize().height(); | 526 scroll_view_->GetPreferredSize().height(); |
693 | 527 |
694 GetWidget()->CenterWindow(gfx::Size(widget_bound.width(), new_height)); | 528 GetWidget()->CenterWindow(gfx::Size(widget_bound.width(), new_height)); |
695 } | 529 } |
696 | 530 |
| 531 DesktopMediaSourceView* |
| 532 DesktopMediaPickerDialogView::GetMediaSourceViewForTesting(int index) const { |
| 533 if (list_view_->child_count() <= index) |
| 534 return NULL; |
| 535 |
| 536 return reinterpret_cast<DesktopMediaSourceView*>(list_view_->child_at(index)); |
| 537 } |
| 538 |
697 DesktopMediaPickerViews::DesktopMediaPickerViews() : dialog_(NULL) { | 539 DesktopMediaPickerViews::DesktopMediaPickerViews() : dialog_(NULL) { |
698 } | 540 } |
699 | 541 |
700 DesktopMediaPickerViews::~DesktopMediaPickerViews() { | 542 DesktopMediaPickerViews::~DesktopMediaPickerViews() { |
701 if (dialog_) { | 543 if (dialog_) { |
702 dialog_->DetachParent(); | 544 dialog_->DetachParent(); |
703 dialog_->GetWidget()->Close(); | 545 dialog_->GetWidget()->Close(); |
704 } | 546 } |
705 } | 547 } |
706 | 548 |
(...skipping 18 matching lines...) Expand all Loading... |
725 DCHECK(!callback_.is_null()); | 567 DCHECK(!callback_.is_null()); |
726 | 568 |
727 // Notify the |callback_| asynchronously because it may need to destroy | 569 // Notify the |callback_| asynchronously because it may need to destroy |
728 // DesktopMediaPicker. | 570 // DesktopMediaPicker. |
729 content::BrowserThread::PostTask( | 571 content::BrowserThread::PostTask( |
730 content::BrowserThread::UI, FROM_HERE, | 572 content::BrowserThread::UI, FROM_HERE, |
731 base::Bind(callback_, source)); | 573 base::Bind(callback_, source)); |
732 callback_.Reset(); | 574 callback_.Reset(); |
733 } | 575 } |
734 | 576 |
735 } // namespace | |
736 | |
737 // static | 577 // static |
738 scoped_ptr<DesktopMediaPicker> DesktopMediaPicker::Create() { | 578 scoped_ptr<DesktopMediaPicker> DesktopMediaPicker::Create() { |
739 return scoped_ptr<DesktopMediaPicker>(new DesktopMediaPickerViews()); | 579 return scoped_ptr<DesktopMediaPicker>(new DesktopMediaPickerViews()); |
740 } | 580 } |
OLD | NEW |