blob: 9057f9b363ee5c11f7f1ff78a932e297657cd267 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_DESKTOP_CAPTURE_DESKTOP_MEDIA_LIST_CONTROLLER_H_
#define CHROME_BROWSER_UI_VIEWS_DESKTOP_CAPTURE_DESKTOP_MEDIA_LIST_CONTROLLER_H_
#include <memory>
#include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
#include "chrome/browser/media/webrtc/desktop_media_list.h"
#include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
#include "chrome/browser/ui/views/desktop_capture/desktop_media_source_view.h"
#include "ui/views/view.h"
#include "ui/views/view_observer.h"
class DesktopMediaPickerDialogView;
// This class is the controller for a View that displays a DesktopMediaList. It
// is responsible for:
// * Observing a DesktopMediaList
// * Updating its controlled view when that DesktopMediaList changes
// * Providing access to the state of its controlled view to the dialog
// * Proxying between its controlled view's callbacks and the dialog's
// callbacks
class DesktopMediaListController : public DesktopMediaListObserver,
public views::ViewObserver {
public:
// The interface implemented by a controlled view or one of its helper classes
// to listen for updates to the source list.
class SourceListListener {
public:
virtual void OnSourceAdded(size_t index) = 0;
virtual void OnSourceRemoved(size_t index) = 0;
virtual void OnSourceMoved(size_t old_index, size_t new_index) = 0;
virtual void OnSourceNameChanged(size_t index) = 0;
virtual void OnSourceThumbnailChanged(size_t index) = 0;
};
// The abstract interface implemented by any view controlled by this
// controller.
class ListView : public views::View {
public:
// Returns the DesktopMediaID of the selected element of this list, or
// nullopt if no element is selected.
virtual base::Optional<content::DesktopMediaID> GetSelection() = 0;
// Returns the SourceListListener to use to notify this ListView of changes
// to the backing DesktopMediaList.
virtual SourceListListener* GetSourceListListener() = 0;
protected:
ListView() = default;
~ListView() override = default;
};
DesktopMediaListController(DesktopMediaPickerDialogView* dialog,
std::unique_ptr<DesktopMediaList> media_list);
~DesktopMediaListController() override;
// Create this controller's corresponding View. There can only be one View per
// controller; attempting to call this method twice on the same
// DesktopMediaListController is not allowed.
std::unique_ptr<views::View> CreateView(
DesktopMediaSourceViewStyle generic_style,
DesktopMediaSourceViewStyle single_style,
const base::string16& accessible_name);
std::unique_ptr<views::View> CreateTabListView(
const base::string16& accessible_name);
// Starts observing the DesktopMediaList given earlier, ignoring any entries
// whose id matches dialog_window_id.
void StartUpdating(content::DesktopMediaID dialog_window_id);
// Focuses this controller's view.
void FocusView();
// Returns the DesktopMediaID corresponding to the current selection in this
// controller's view, if there is one.
base::Optional<content::DesktopMediaID> GetSelection() const;
// These three methods are called by the view to inform the controller of
// events. The first two indicate changes in the visual state of the view; the
// last indicates that the user performed an action on the source view that
// should serve to accept the entire dialog.
void OnSourceListLayoutChanged();
void OnSourceSelectionChanged();
void AcceptSource();
// Returns the view that should receive initial focus in the dialog if this
// controller's source list is the one being shown.
views::View* GetViewForInitialFocus();
// These methods are used by the view (or its subviews) to query and
// update the underlying DesktopMediaList.
size_t GetSourceCount() const;
const DesktopMediaList::Source& GetSource(size_t index) const;
void SetThumbnailSize(const gfx::Size& size);
private:
friend class DesktopMediaPickerViewsTestApi;
// This method is used as a callback to support source auto-selection, which
// is used in some tests; it acts as though the user had selected (in the
// view) the element corresponding to the given source and accepted the
// dialog.
void AcceptSpecificSource(content::DesktopMediaID source);
// DesktopMediaListObserver:
void OnSourceAdded(DesktopMediaList* list, int index) override;
void OnSourceRemoved(DesktopMediaList* list, int index) override;
void OnSourceMoved(DesktopMediaList* list,
int old_index,
int new_index) override;
void OnSourceNameChanged(DesktopMediaList* list, int index) override;
void OnSourceThumbnailChanged(DesktopMediaList* list, int index) override;
// ViewObserver:
void OnViewIsDeleting(views::View* view) override;
DesktopMediaPickerDialogView* dialog_;
std::unique_ptr<DesktopMediaList> media_list_;
ListView* view_ = nullptr;
ScopedObserver<views::View, views::ViewObserver> view_observer_{this};
base::WeakPtrFactory<DesktopMediaListController> weak_factory_{this};
};
#endif // CHROME_BROWSER_UI_VIEWS_DESKTOP_CAPTURE_DESKTOP_MEDIA_LIST_CONTROLLER_H_