1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_UI_VIEWS_DESKTOP_MEDIA_PICKER_VIEWS_H_
6#define CHROME_BROWSER_UI_VIEWS_DESKTOP_MEDIA_PICKER_VIEWS_H_
7
8#include "chrome/browser/media/desktop_media_list_observer.h"
9#include "chrome/browser/media/desktop_media_picker.h"
10#include "ui/views/window/dialog_delegate.h"
11
12namespace views {
13class ImageView;
14class Label;
15}  // namespace views
16
17class DesktopMediaPickerDialogView;
18class DesktopMediaPickerViews;
19class DesktopMediaSourceView;
20
21// View that shows a list of desktop media sources available from
22// DesktopMediaList.
23class DesktopMediaListView : public views::View,
24                             public DesktopMediaListObserver {
25 public:
26  DesktopMediaListView(DesktopMediaPickerDialogView* parent,
27                       scoped_ptr<DesktopMediaList> media_list);
28  virtual ~DesktopMediaListView();
29
30  void StartUpdating(content::DesktopMediaID::Id dialog_window_id);
31
32  // Called by DesktopMediaSourceView when selection has changed.
33  void OnSelectionChanged();
34
35  // Called by DesktopMediaSourceView when a source has been double-clicked.
36  void OnDoubleClick();
37
38  // Returns currently selected source.
39  DesktopMediaSourceView* GetSelection();
40
41  // views::View overrides.
42  virtual gfx::Size GetPreferredSize() const OVERRIDE;
43  virtual void Layout() OVERRIDE;
44  virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE;
45
46 private:
47  // DesktopMediaList::Observer interface
48  virtual void OnSourceAdded(int index) OVERRIDE;
49  virtual void OnSourceRemoved(int index) OVERRIDE;
50  virtual void OnSourceMoved(int old_index, int new_index) OVERRIDE;
51  virtual void OnSourceNameChanged(int index) OVERRIDE;
52  virtual void OnSourceThumbnailChanged(int index) OVERRIDE;
53
54  // Accepts whatever happens to be selected right now.
55  void AcceptSelection();
56
57  DesktopMediaPickerDialogView* parent_;
58  scoped_ptr<DesktopMediaList> media_list_;
59  base::WeakPtrFactory<DesktopMediaListView> weak_factory_;
60
61  DISALLOW_COPY_AND_ASSIGN(DesktopMediaListView);
62};
63
64// View used for each item in DesktopMediaListView. Shows a single desktop media
65// source as a thumbnail with the title under it.
66class DesktopMediaSourceView : public views::View {
67 public:
68  DesktopMediaSourceView(DesktopMediaListView* parent,
69                         content::DesktopMediaID source_id);
70  virtual ~DesktopMediaSourceView();
71
72  // Updates thumbnail and title from |source|.
73  void SetName(const base::string16& name);
74  void SetThumbnail(const gfx::ImageSkia& thumbnail);
75
76  // Id for the source shown by this View.
77  const content::DesktopMediaID& source_id() const { return source_id_; }
78
79  // Returns true if the source is selected.
80  bool is_selected() const { return selected_; }
81
82  // views::View interface.
83  virtual const char* GetClassName() const OVERRIDE;
84  virtual void Layout() OVERRIDE;
85  virtual views::View* GetSelectedViewForGroup(int group) OVERRIDE;
86  virtual bool IsGroupFocusTraversable() const OVERRIDE;
87  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
88  virtual void OnFocus() OVERRIDE;
89  virtual void OnBlur() OVERRIDE;
90  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
91  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
92
93 private:
94  // Updates selection state of the element. If |selected| is true then also
95  // calls SetSelected(false) for the source view that was selected before that
96  // (if any).
97  void SetSelected(bool selected);
98
99  DesktopMediaListView* parent_;
100  content::DesktopMediaID source_id_;
101
102  views::ImageView* image_view_;
103  views::Label* label_;
104
105  bool selected_;
106
107  DISALLOW_COPY_AND_ASSIGN(DesktopMediaSourceView);
108};
109
110// Dialog view used for DesktopMediaPickerViews.
111class DesktopMediaPickerDialogView : public views::DialogDelegateView {
112 public:
113  DesktopMediaPickerDialogView(content::WebContents* parent_web_contents,
114                               gfx::NativeWindow context,
115                               DesktopMediaPickerViews* parent,
116                               const base::string16& app_name,
117                               const base::string16& target_name,
118                               scoped_ptr<DesktopMediaList> media_list);
119  virtual ~DesktopMediaPickerDialogView();
120
121  // Called by parent (DesktopMediaPickerViews) when it's destroyed.
122  void DetachParent();
123
124  // Called by DesktopMediaListView.
125  void OnSelectionChanged();
126  void OnDoubleClick();
127
128  // views::View overrides.
129  virtual gfx::Size GetPreferredSize() const OVERRIDE;
130  virtual void Layout() OVERRIDE;
131
132  // views::DialogDelegateView overrides.
133  virtual ui::ModalType GetModalType() const OVERRIDE;
134  virtual base::string16 GetWindowTitle() const OVERRIDE;
135  virtual bool IsDialogButtonEnabled(ui::DialogButton button) const OVERRIDE;
136  virtual base::string16 GetDialogButtonLabel(
137      ui::DialogButton button) const OVERRIDE;
138  virtual bool Accept() OVERRIDE;
139  virtual void DeleteDelegate() OVERRIDE;
140
141  void OnMediaListRowsChanged();
142
143  DesktopMediaSourceView* GetMediaSourceViewForTesting(int index) const;
144
145 private:
146  DesktopMediaPickerViews* parent_;
147  base::string16 app_name_;
148
149  views::Label* label_;
150  views::ScrollView* scroll_view_;
151  DesktopMediaListView* list_view_;
152
153  DISALLOW_COPY_AND_ASSIGN(DesktopMediaPickerDialogView);
154};
155
156// Implementation of DesktopMediaPicker for Views.
157class DesktopMediaPickerViews : public DesktopMediaPicker {
158 public:
159  DesktopMediaPickerViews();
160  virtual ~DesktopMediaPickerViews();
161
162  void NotifyDialogResult(content::DesktopMediaID source);
163
164  // DesktopMediaPicker overrides.
165  virtual void Show(content::WebContents* web_contents,
166                    gfx::NativeWindow context,
167                    gfx::NativeWindow parent,
168                    const base::string16& app_name,
169                    const base::string16& target_name,
170                    scoped_ptr<DesktopMediaList> media_list,
171                    const DoneCallback& done_callback) OVERRIDE;
172
173  DesktopMediaPickerDialogView* GetDialogViewForTesting() const {
174    return dialog_;
175  }
176
177 private:
178  DoneCallback callback_;
179
180  // The |dialog_| is owned by the corresponding views::Widget instance.
181  // When DesktopMediaPickerViews is destroyed the |dialog_| is destroyed
182  // asynchronously by closing the widget.
183  DesktopMediaPickerDialogView* dialog_;
184
185  DISALLOW_COPY_AND_ASSIGN(DesktopMediaPickerViews);
186};
187
188#endif  // CHROME_BROWSER_UI_VIEWS_DESKTOP_MEDIA_PICKER_VIEWS_H_
189