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 #include "chrome/browser/media/desktop_media_picker.h" | 5 #include "chrome/browser/media/desktop_media_picker.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" | 9 #include "chrome/browser/media/desktop_media_list_observer.h" |
| 10 #include "chrome/browser/ui/ash/ash_util.h" | 10 #include "chrome/browser/ui/ash/ash_util.h" |
| 11 #include "components/web_modal/web_contents_modal_dialog_host.h" | |
| 12 #include "components/web_modal/web_contents_modal_dialog_manager.h" | |
| 13 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" | |
| 11 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
| 12 #include "grit/generated_resources.h" | 15 #include "grit/generated_resources.h" |
| 13 #include "ui/aura/window_tree_host.h" | 16 #include "ui/aura/window_tree_host.h" |
| 14 #include "ui/base/l10n/l10n_util.h" | 17 #include "ui/base/l10n/l10n_util.h" |
| 15 #include "ui/events/keycodes/keyboard_codes.h" | 18 #include "ui/events/keycodes/keyboard_codes.h" |
| 16 #include "ui/gfx/canvas.h" | 19 #include "ui/gfx/canvas.h" |
| 17 #include "ui/native_theme/native_theme.h" | 20 #include "ui/native_theme/native_theme.h" |
| 18 #include "ui/views/background.h" | 21 #include "ui/views/background.h" |
| 19 #include "ui/views/controls/image_view.h" | 22 #include "ui/views/controls/image_view.h" |
| 20 #include "ui/views/controls/label.h" | 23 #include "ui/views/controls/label.h" |
| 21 #include "ui/views/controls/scroll_view.h" | 24 #include "ui/views/controls/scroll_view.h" |
| 22 #include "ui/views/layout/box_layout.h" | 25 #include "ui/views/layout/box_layout.h" |
| 23 #include "ui/views/layout/layout_constants.h" | 26 #include "ui/views/layout/layout_constants.h" |
| 24 #include "ui/views/widget/widget.h" | 27 #include "ui/views/widget/widget.h" |
| 25 #include "ui/views/window/dialog_client_view.h" | 28 #include "ui/views/window/dialog_client_view.h" |
| 26 #include "ui/views/window/dialog_delegate.h" | 29 #include "ui/views/window/dialog_delegate.h" |
| 27 #include "ui/wm/core/shadow_types.h" | 30 #include "ui/wm/core/shadow_types.h" |
| 28 | 31 |
| 29 using content::DesktopMediaID; | 32 using content::DesktopMediaID; |
| 33 using web_modal::WebContentsModalDialogManager; | |
| 34 using web_modal::WebContentsModalDialogManagerDelegate; | |
| 30 | 35 |
| 31 namespace { | 36 namespace { |
| 32 | 37 |
| 33 const int kThumbnailWidth = 160; | 38 const int kThumbnailWidth = 160; |
| 34 const int kThumbnailHeight = 100; | 39 const int kThumbnailHeight = 100; |
| 35 const int kThumbnailMargin = 10; | 40 const int kThumbnailMargin = 10; |
| 36 const int kLabelHeight = 40; | 41 const int kLabelHeight = 40; |
| 37 const int kListItemWidth = kThumbnailMargin * 2 + kThumbnailWidth; | 42 const int kListItemWidth = kThumbnailMargin * 2 + kThumbnailWidth; |
| 38 const int kListItemHeight = | 43 const int kListItemHeight = |
| 39 kThumbnailMargin * 2 + kThumbnailHeight + kLabelHeight; | 44 kThumbnailMargin * 2 + kThumbnailHeight + kLabelHeight; |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 140 | 145 |
| 141 DesktopMediaPickerDialogView* parent_; | 146 DesktopMediaPickerDialogView* parent_; |
| 142 scoped_ptr<DesktopMediaList> media_list_; | 147 scoped_ptr<DesktopMediaList> media_list_; |
| 143 | 148 |
| 144 DISALLOW_COPY_AND_ASSIGN(DesktopMediaListView); | 149 DISALLOW_COPY_AND_ASSIGN(DesktopMediaListView); |
| 145 }; | 150 }; |
| 146 | 151 |
| 147 // Dialog view used for DesktopMediaPickerViews. | 152 // Dialog view used for DesktopMediaPickerViews. |
| 148 class DesktopMediaPickerDialogView : public views::DialogDelegateView { | 153 class DesktopMediaPickerDialogView : public views::DialogDelegateView { |
| 149 public: | 154 public: |
| 150 DesktopMediaPickerDialogView(gfx::NativeWindow context, | 155 DesktopMediaPickerDialogView(content::WebContents* parent_web_contents, |
| 156 gfx::NativeWindow context, | |
| 151 gfx::NativeWindow parent_window, | 157 gfx::NativeWindow parent_window, |
| 152 DesktopMediaPickerViews* parent, | 158 DesktopMediaPickerViews* parent, |
| 153 const base::string16& app_name, | 159 const base::string16& app_name, |
| 154 const base::string16& target_name, | 160 const base::string16& target_name, |
| 155 scoped_ptr<DesktopMediaList> media_list); | 161 scoped_ptr<DesktopMediaList> media_list); |
| 156 virtual ~DesktopMediaPickerDialogView(); | 162 virtual ~DesktopMediaPickerDialogView(); |
| 157 | 163 |
| 158 // Called by parent (DesktopMediaPickerViews) when it's destroyed. | 164 // Called by parent (DesktopMediaPickerViews) when it's destroyed. |
| 159 void DetachParent(); | 165 void DetachParent(); |
| 160 | 166 |
| 161 // Called by DesktopMediaListView. | 167 // Called by DesktopMediaListView. |
| 162 void OnSelectionChanged(); | 168 void OnSelectionChanged(); |
| 163 void OnDoubleClick(); | 169 void OnDoubleClick(); |
| 164 | 170 |
| 165 // views::View overrides. | 171 // views::View overrides. |
| 166 virtual gfx::Size GetPreferredSize() OVERRIDE; | 172 virtual gfx::Size GetPreferredSize() OVERRIDE; |
| 167 virtual void Layout() OVERRIDE; | 173 virtual void Layout() OVERRIDE; |
| 168 | 174 |
| 169 // views::DialogDelegateView overrides. | 175 // views::DialogDelegateView overrides. |
| 170 virtual base::string16 GetWindowTitle() const OVERRIDE; | 176 virtual base::string16 GetWindowTitle() const OVERRIDE; |
| 171 virtual bool IsDialogButtonEnabled(ui::DialogButton button) const OVERRIDE; | 177 virtual bool IsDialogButtonEnabled(ui::DialogButton button) const OVERRIDE; |
| 172 virtual base::string16 GetDialogButtonLabel( | 178 virtual base::string16 GetDialogButtonLabel( |
| 173 ui::DialogButton button) const OVERRIDE; | 179 ui::DialogButton button) const OVERRIDE; |
| 174 virtual bool Accept() OVERRIDE; | 180 virtual bool Accept() OVERRIDE; |
| 175 virtual void DeleteDelegate() OVERRIDE; | 181 virtual void DeleteDelegate() OVERRIDE; |
| 182 virtual views::Widget* GetWidget() OVERRIDE; | |
| 176 | 183 |
| 177 private: | 184 private: |
| 178 DesktopMediaPickerViews* parent_; | 185 DesktopMediaPickerViews* parent_; |
| 179 base::string16 app_name_; | 186 base::string16 app_name_; |
| 180 | 187 |
| 181 views::Label* label_; | 188 views::Label* label_; |
| 182 views::ScrollView* scroll_view_; | 189 views::ScrollView* scroll_view_; |
| 183 DesktopMediaListView* list_view_; | 190 DesktopMediaListView* list_view_; |
| 191 views::Widget* widget_; | |
|
sky
2014/05/23 00:03:02
Why do you need to cache widget_ and override GetW
zel
2014/05/23 17:51:44
Done.
| |
| 184 | 192 |
| 185 DISALLOW_COPY_AND_ASSIGN(DesktopMediaPickerDialogView); | 193 DISALLOW_COPY_AND_ASSIGN(DesktopMediaPickerDialogView); |
| 186 }; | 194 }; |
| 187 | 195 |
| 188 // Implementation of DesktopMediaPicker for Views. | 196 // Implementation of DesktopMediaPicker for Views. |
| 189 class DesktopMediaPickerViews : public DesktopMediaPicker { | 197 class DesktopMediaPickerViews : public DesktopMediaPicker { |
| 190 public: | 198 public: |
| 191 DesktopMediaPickerViews(); | 199 DesktopMediaPickerViews(); |
| 192 virtual ~DesktopMediaPickerViews(); | 200 virtual ~DesktopMediaPickerViews(); |
| 193 | 201 |
| 194 void NotifyDialogResult(DesktopMediaID source); | 202 void NotifyDialogResult(DesktopMediaID source); |
| 195 | 203 |
| 196 // DesktopMediaPicker overrides. | 204 // DesktopMediaPicker overrides. |
| 197 virtual void Show(gfx::NativeWindow context, | 205 virtual void Show(content::WebContents* web_contents, |
| 206 gfx::NativeWindow context, | |
| 198 gfx::NativeWindow parent, | 207 gfx::NativeWindow parent, |
| 199 const base::string16& app_name, | 208 const base::string16& app_name, |
| 200 const base::string16& target_name, | 209 const base::string16& target_name, |
| 201 scoped_ptr<DesktopMediaList> media_list, | 210 scoped_ptr<DesktopMediaList> media_list, |
| 202 const DoneCallback& done_callback) OVERRIDE; | 211 const DoneCallback& done_callback) OVERRIDE; |
| 203 | 212 |
| 204 private: | 213 private: |
| 205 DoneCallback callback_; | 214 DoneCallback callback_; |
| 206 | 215 |
| 207 // The |dialog_| is owned by the corresponding views::Widget instance. | 216 // The |dialog_| is owned by the corresponding views::Widget instance. |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 478 } | 487 } |
| 479 | 488 |
| 480 void DesktopMediaListView::OnSourceThumbnailChanged(int index) { | 489 void DesktopMediaListView::OnSourceThumbnailChanged(int index) { |
| 481 const DesktopMediaList::Source& source = media_list_->GetSource(index); | 490 const DesktopMediaList::Source& source = media_list_->GetSource(index); |
| 482 DesktopMediaSourceView* source_view = | 491 DesktopMediaSourceView* source_view = |
| 483 static_cast<DesktopMediaSourceView*>(child_at(index)); | 492 static_cast<DesktopMediaSourceView*>(child_at(index)); |
| 484 source_view->SetThumbnail(source.thumbnail); | 493 source_view->SetThumbnail(source.thumbnail); |
| 485 } | 494 } |
| 486 | 495 |
| 487 DesktopMediaPickerDialogView::DesktopMediaPickerDialogView( | 496 DesktopMediaPickerDialogView::DesktopMediaPickerDialogView( |
| 497 content::WebContents* parent_web_contents, | |
| 488 gfx::NativeWindow context, | 498 gfx::NativeWindow context, |
| 489 gfx::NativeWindow parent_window, | 499 gfx::NativeWindow parent_window, |
| 490 DesktopMediaPickerViews* parent, | 500 DesktopMediaPickerViews* parent, |
| 491 const base::string16& app_name, | 501 const base::string16& app_name, |
| 492 const base::string16& target_name, | 502 const base::string16& target_name, |
| 493 scoped_ptr<DesktopMediaList> media_list) | 503 scoped_ptr<DesktopMediaList> media_list) |
| 494 : parent_(parent), | 504 : parent_(parent), |
| 495 app_name_(app_name), | 505 app_name_(app_name), |
| 496 label_(new views::Label()), | 506 label_(new views::Label()), |
| 497 scroll_view_(views::ScrollView::CreateScrollViewWithBorder()), | 507 scroll_view_(views::ScrollView::CreateScrollViewWithBorder()), |
| 498 list_view_(new DesktopMediaListView(this, media_list.Pass())) { | 508 list_view_(new DesktopMediaListView(this, media_list.Pass())), |
| 509 widget_(NULL) { | |
| 499 if (app_name == target_name) { | 510 if (app_name == target_name) { |
| 500 label_->SetText( | 511 label_->SetText( |
| 501 l10n_util::GetStringFUTF16(IDS_DESKTOP_MEDIA_PICKER_TEXT, app_name)); | 512 l10n_util::GetStringFUTF16(IDS_DESKTOP_MEDIA_PICKER_TEXT, app_name)); |
| 502 } else { | 513 } else { |
| 503 label_->SetText(l10n_util::GetStringFUTF16( | 514 label_->SetText(l10n_util::GetStringFUTF16( |
| 504 IDS_DESKTOP_MEDIA_PICKER_TEXT_DELEGATED, app_name, target_name)); | 515 IDS_DESKTOP_MEDIA_PICKER_TEXT_DELEGATED, app_name, target_name)); |
| 505 } | 516 } |
| 506 label_->SetMultiLine(true); | 517 label_->SetMultiLine(true); |
| 507 label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 518 label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 508 AddChildView(label_); | 519 AddChildView(label_); |
| 509 | 520 |
| 510 scroll_view_->SetContents(list_view_); | 521 scroll_view_->SetContents(list_view_); |
| 511 AddChildView(scroll_view_); | 522 AddChildView(scroll_view_); |
| 512 | 523 |
| 513 DialogDelegate::CreateDialogWidget(this, context, parent_window); | 524 WebContentsModalDialogManager* web_contents_modal_dialog_manager = |
| 525 WebContentsModalDialogManager::FromWebContents(parent_web_contents); | |
| 526 DCHECK(web_contents_modal_dialog_manager); | |
| 527 WebContentsModalDialogManagerDelegate* delegate = | |
| 528 web_contents_modal_dialog_manager->delegate(); | |
| 529 DCHECK(delegate); | |
| 530 widget_ = views::Widget::CreateWindowAsFramelessChild( | |
| 531 this, | |
| 532 delegate->GetWebContentsModalDialogHost()->GetHostView()); | |
| 514 | 533 |
| 515 // DesktopMediaList needs to know the ID of the picker window which | 534 // DesktopMediaList needs to know the ID of the picker window which |
| 516 // matches the ID it gets from the OS. Depending on the OS and configuration | 535 // matches the ID it gets from the OS. Depending on the OS and configuration |
| 517 // we get this ID differently. | 536 // we get this ID differently. |
| 518 content::DesktopMediaID::Id dialog_window_id = 0; | 537 content::DesktopMediaID::Id dialog_window_id = 0; |
| 519 | 538 |
| 520 #if defined(USE_ASH) | 539 #if defined(USE_ASH) |
| 521 if (chrome::IsNativeWindowInAsh(GetWidget()->GetNativeWindow())) { | 540 if (chrome::IsNativeWindowInAsh(GetWidget()->GetNativeWindow())) { |
| 522 dialog_window_id = content::DesktopMediaID::RegisterAuraWindow( | 541 dialog_window_id = content::DesktopMediaID::RegisterAuraWindow( |
| 523 GetWidget()->GetNativeWindow()).id; | 542 GetWidget()->GetNativeWindow()).id; |
| 524 } else | 543 } else |
| 525 #endif | 544 #endif |
| 526 { | 545 { |
| 527 dialog_window_id = AcceleratedWidgetToDesktopMediaId( | 546 dialog_window_id = AcceleratedWidgetToDesktopMediaId( |
| 528 GetWidget()->GetNativeWindow()->GetHost()-> | 547 GetWidget()->GetNativeWindow()->GetHost()-> |
| 529 GetAcceleratedWidget()); | 548 GetAcceleratedWidget()); |
| 530 } | 549 } |
| 531 | 550 |
| 532 list_view_->StartUpdating(dialog_window_id); | 551 list_view_->StartUpdating(dialog_window_id); |
| 533 | 552 |
| 534 GetWidget()->Show(); | 553 web_contents_modal_dialog_manager->ShowModalDialog( |
| 554 GetWidget()->GetNativeView()); | |
| 535 } | 555 } |
| 536 | 556 |
| 537 DesktopMediaPickerDialogView::~DesktopMediaPickerDialogView() {} | 557 DesktopMediaPickerDialogView::~DesktopMediaPickerDialogView() {} |
| 538 | 558 |
| 559 views::Widget* DesktopMediaPickerDialogView::GetWidget() { | |
| 560 return widget_; | |
| 561 } | |
| 562 | |
| 539 void DesktopMediaPickerDialogView::DetachParent() { | 563 void DesktopMediaPickerDialogView::DetachParent() { |
| 540 parent_ = NULL; | 564 parent_ = NULL; |
| 541 } | 565 } |
| 542 | 566 |
| 543 gfx::Size DesktopMediaPickerDialogView::GetPreferredSize() { | 567 gfx::Size DesktopMediaPickerDialogView::GetPreferredSize() { |
| 544 return gfx::Size(600, 500); | 568 return gfx::Size(600, 500); |
| 545 } | 569 } |
| 546 | 570 |
| 547 void DesktopMediaPickerDialogView::Layout() { | 571 void DesktopMediaPickerDialogView::Layout() { |
| 548 gfx::Rect rect = GetLocalBounds(); | 572 gfx::Rect rect = GetLocalBounds(); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 612 : dialog_(NULL) { | 636 : dialog_(NULL) { |
| 613 } | 637 } |
| 614 | 638 |
| 615 DesktopMediaPickerViews::~DesktopMediaPickerViews() { | 639 DesktopMediaPickerViews::~DesktopMediaPickerViews() { |
| 616 if (dialog_) { | 640 if (dialog_) { |
| 617 dialog_->DetachParent(); | 641 dialog_->DetachParent(); |
| 618 dialog_->GetWidget()->Close(); | 642 dialog_->GetWidget()->Close(); |
| 619 } | 643 } |
| 620 } | 644 } |
| 621 | 645 |
| 622 void DesktopMediaPickerViews::Show(gfx::NativeWindow context, | 646 void DesktopMediaPickerViews::Show(content::WebContents* web_contents, |
| 647 gfx::NativeWindow context, | |
| 623 gfx::NativeWindow parent, | 648 gfx::NativeWindow parent, |
| 624 const base::string16& app_name, | 649 const base::string16& app_name, |
| 625 const base::string16& target_name, | 650 const base::string16& target_name, |
| 626 scoped_ptr<DesktopMediaList> media_list, | 651 scoped_ptr<DesktopMediaList> media_list, |
| 627 const DoneCallback& done_callback) { | 652 const DoneCallback& done_callback) { |
| 628 callback_ = done_callback; | 653 callback_ = done_callback; |
| 629 dialog_ = new DesktopMediaPickerDialogView( | 654 dialog_ = new DesktopMediaPickerDialogView( |
| 630 context, parent, this, app_name, target_name, media_list.Pass()); | 655 web_contents, context, parent, this, app_name, target_name, |
| 656 media_list.Pass()); | |
| 631 } | 657 } |
| 632 | 658 |
| 633 void DesktopMediaPickerViews::NotifyDialogResult( | 659 void DesktopMediaPickerViews::NotifyDialogResult( |
| 634 DesktopMediaID source) { | 660 DesktopMediaID source) { |
| 635 // Once this method is called the |dialog_| will close and destroy itself. | 661 // Once this method is called the |dialog_| will close and destroy itself. |
| 636 dialog_->DetachParent(); | 662 dialog_->DetachParent(); |
| 637 dialog_ = NULL; | 663 dialog_ = NULL; |
| 638 | 664 |
| 639 DCHECK(!callback_.is_null()); | 665 DCHECK(!callback_.is_null()); |
| 640 | 666 |
| 641 // Notify the |callback_| asynchronously because it may need to destroy | 667 // Notify the |callback_| asynchronously because it may need to destroy |
| 642 // DesktopMediaPicker. | 668 // DesktopMediaPicker. |
| 643 content::BrowserThread::PostTask( | 669 content::BrowserThread::PostTask( |
| 644 content::BrowserThread::UI, FROM_HERE, | 670 content::BrowserThread::UI, FROM_HERE, |
| 645 base::Bind(callback_, source)); | 671 base::Bind(callback_, source)); |
| 646 callback_.Reset(); | 672 callback_.Reset(); |
| 647 } | 673 } |
| 648 | 674 |
| 649 } // namespace | 675 } // namespace |
| 650 | 676 |
| 651 // static | 677 // static |
| 652 scoped_ptr<DesktopMediaPicker> DesktopMediaPicker::Create() { | 678 scoped_ptr<DesktopMediaPicker> DesktopMediaPicker::Create() { |
| 653 return scoped_ptr<DesktopMediaPicker>(new DesktopMediaPickerViews()); | 679 return scoped_ptr<DesktopMediaPicker>(new DesktopMediaPickerViews()); |
| 654 } | 680 } |
| OLD | NEW |