blob: e388de96db00393c268d96908e09cae4d258614e [file] [log] [blame]
// Copyright 2021 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 ASH_CAPTURE_MODE_CAPTURE_MODE_SETTINGS_VIEW_H_
#define ASH_CAPTURE_MODE_CAPTURE_MODE_SETTINGS_VIEW_H_
#include "ash/ash_export.h"
#include "ash/capture_mode/capture_mode_camera_controller.h"
#include "ash/capture_mode/capture_mode_menu_group.h"
#include "ash/capture_mode/capture_mode_session_focus_cycler.h"
#include "base/callback_forward.h"
#include "base/containers/flat_map.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/view.h"
namespace views {
class Separator;
} // namespace views
namespace ash {
class CaptureModeBarView;
class CaptureModeMenuGroup;
class CaptureModeSession;
// All the options in the CaptureMode settings view.
enum CaptureSettingsOption {
kAudioOff = 0,
kAudioMicrophone,
kDownloadsFolder,
kCustomFolder,
kCameraOff,
kCameraDevicesBegin,
};
// A view that acts as the content view of the capture mode settings menu
// widget. It is the content view of settings widget and it contains
// `CaptureModeMenuGroup` for each setting, save to, audio input etc.
class ASH_EXPORT CaptureModeSettingsView
: public views::View,
public CaptureModeMenuGroup::Delegate,
public CaptureModeCameraController::Observer {
public:
METADATA_HEADER(CaptureModeSettingsView);
CaptureModeSettingsView(CaptureModeSession* session,
bool is_in_projector_mode);
CaptureModeSettingsView(const CaptureModeSettingsView&) = delete;
CaptureModeSettingsView& operator=(const CaptureModeSettingsView&) = delete;
~CaptureModeSettingsView() override;
// Gets the ideal bounds in screen coordinates of the settings widget on
// the given |capture_mode_bar_view|. If |content_view| is not null, it will
// be used to get the preferred size to calculate the final bounds. Otherwise,
// a default size will be used.
static gfx::Rect GetBounds(CaptureModeBarView* capture_mode_bar_view,
CaptureModeSettingsView* content_view = nullptr);
// Called when the folder, in which the captured files will be saved, may have
// changed. This may result in adding or removing a menu option for the folder
// that was added or removed. This means that the preferred size of this view
// can possibly change, and therefore it's the responsibility of the caller to
// to set the proper bounds on the widget.
void OnCaptureFolderMayHaveChanged();
// Called when we change the setting to force-use the default downloads folder
// as the save folder. This results in updating which folder menu option is
// currently selected.
void OnDefaultCaptureFolderSelectionChanged();
// Gets the highlightable `CaptureModeOption` and `CaptureModeMenuItem` inside
// this view.
std::vector<CaptureModeSessionFocusCycler::HighlightableView*>
GetHighlightableItems();
// CaptureModeMenuGroup::Delegate:
void OnOptionSelected(int option_id) const override;
bool IsOptionChecked(int option_id) const override;
bool IsOptionEnabled(int option_id) const override;
// CaptureModeCameraController::Observer:
void OnAvailableCamerasChanged(const CameraInfoList& cameras) override;
void OnSelectedCameraChanged(const CameraId& camera_id) override;
// For tests only:
CaptureModeMenuGroup* GetAudioInputMenuGroupForTesting() {
return audio_input_menu_group_;
}
views::View* GetMicrophoneOptionForTesting();
views::View* GetOffOptionForTesting();
private:
friend class CaptureModeSettingsTestApi;
// Called when the "Select folder" menu item in the |save_to_menu_group_| is
// pressed. It opens the folder selection dialog so that user can pick a
// location in which captured files will be saved.
void OnSelectFolderMenuItemPressed();
// Called back when the check for custom folder's availability is done, with
// `available` indicating whether the custom folder is available or not. We
// will check the custom folder's availability every time when
// `OnCaptureFolderMayHaveChanged` is triggered and custom folder is not
// empty.
void OnCustomFolderAvailabilityChecked(bool available);
// Finds the camera id by the given `option_id` from the
// `option_camera_id_map_` if any. Otherwise, return nullptr.
const CameraId* FindCameraIdByOptionId(int option_id) const;
// Adds all camera options (including the option for `kCameraOff`) for the
// given `cameras` to the `camera_menu_group_`. It deletes all options in
// `camera_menu_group_` before adding options. Called when initializing `this`
// or `OnAvailableCamerasChanged` is triggered. It will also trigger
// `UpdateCameraMenuGroupVisibility` at the end.
// Note that camera options are only added when `cameras` is not empty.
// When cameras are disabled by policy (i.e. `managed_by_policy` is true),
// only the "Off" option is added. Users are not allowed to choose any cameras
// in that case.
void AddCameraOptions(const CameraInfoList& cameras, bool managed_by_policy);
void UpdateCameraMenuGroupVisibility(bool visible);
// A reference to the session that owns this view indirectly by owning its
// containing widget.
CaptureModeSession* const capture_mode_session_; // Not null;
// "Audio input" menu group that users can select an audio input from for
// screen capture recording. It has "Off" and "Microphone" options for now.
// "Off" is the default one which means no audio input selected.
CaptureModeMenuGroup* audio_input_menu_group_ = nullptr;
// The separator between audio input and camera menus.
views::Separator* separator_1_ = nullptr;
// Camera menu group that users can select a camera device from for selfie
// cam while video recording. It has an `Off` option and options for all
// available camera devices. `Off` is the default one which means no camera is
// selected.
CaptureModeMenuGroup* camera_menu_group_ = nullptr;
// A mapping from option id to camera id for camera devices.
base::flat_map<int, CameraId> option_camera_id_map_;
// Can be null when in Projector mode, since then it's not needed as the
// "Save-to" menu group will not be added at all.
views::Separator* separator_2_ = nullptr;
// "Save to" menu group that users can select a folder to save the captured
// files to. It will include the "Downloads" folder as the default one and
// one more folder selected by users.
// This menu group is not added when in Projector mode, since the folder
// selection here doesn't affect where Projector saves the videos, and hence
// it doesn't make sense to show this option. In this case, it remains null.
CaptureModeMenuGroup* save_to_menu_group_ = nullptr;
// If not set, custom folder is not set. If true, customer folder is set and
// available. If false, customer folder is set but unavailable.
absl::optional<bool> is_custom_folder_available_;
// If set, it will be called when the settings menu is refreshed.
base::OnceClosure on_settings_menu_refreshed_callback_for_test_;
base::WeakPtrFactory<CaptureModeSettingsView> weak_ptr_factory_{this};
};
} // namespace ash
#endif // ASH_CAPTURE_MODE_CAPTURE_MODE_SETTINGS_VIEW_H_