| // Copyright 2021 The Chromium Authors |
| // 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/containers/flat_map.h" |
| #include "base/functional/callback_forward.h" |
| #include "base/memory/raw_ptr.h" |
| #include "ui/base/metadata/metadata_header_macros.h" |
| #include "ui/views/controls/scroll_view.h" |
| |
| namespace views { |
| class Separator; |
| } // namespace views |
| |
| namespace ash { |
| |
| class CaptureModeBehavior; |
| class CaptureModeMenuGroup; |
| class CaptureModeSession; |
| class CaptureModeMenuToggleButton; |
| class SystemShadow; |
| |
| // All the options in the CaptureMode settings view. |
| enum CaptureSettingsOption { |
| kAudioOff = 0, |
| kAudioSystem, |
| kAudioMicrophone, |
| kAudioSystemAndMicrophone, |
| kDownloadsFolder, |
| kCustomFolder, |
| kCameraOff, |
| kCameraDevicesBegin, |
| }; |
| |
| // A view that acts as the content view of the capture mode settings menu |
| // widget. It allows the settings options to scroll when the menu height is |
| // constrained by the top of the screen. It contains `scroll_view_contents_` |
| // that parents a `CaptureModeMenuGroup` for each setting, save to, audio input, |
| // etc. |
| class ASH_EXPORT CaptureModeSettingsView |
| : public views::ScrollView, |
| public CaptureModeMenuGroup::Delegate, |
| public CaptureModeCameraController::Observer { |
| METADATA_HEADER(CaptureModeSettingsView, views::ScrollView) |
| |
| public: |
| CaptureModeSettingsView(CaptureModeSession* session, |
| CaptureModeBehavior* active_behavior); |
| 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; |
| |
| CaptureModeMenuToggleButton* demo_tools_menu_toggle_button_for_testing() { |
| return demo_tools_menu_toggle_button_; |
| } |
| |
| 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); |
| |
| void OnDemoToolsButtonToggled(); |
| |
| // A reference to the session that owns this view indirectly by owning its |
| // containing widget. |
| const raw_ptr<CaptureModeSession, DanglingUntriaged> |
| capture_mode_session_; // Not null; |
| |
| const raw_ptr<CaptureModeBehavior> active_behavior_; |
| |
| // "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. |
| raw_ptr<CaptureModeMenuGroup> audio_input_menu_group_ = nullptr; |
| |
| // The separator between audio input and camera menus. |
| raw_ptr<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. |
| raw_ptr<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_; |
| |
| // `demo_tools_menu_toggle_button_` will be used as the entry point to enable |
| // the capture mode demo tools feature. Currently |
| // `demo_tools_menu_toggle_button_` and `separator_2_` are guarded by the |
| // feature flag and will only be visible when the feature is enabled. |
| raw_ptr<views::Separator> separator_2_ = nullptr; |
| raw_ptr<CaptureModeMenuToggleButton> demo_tools_menu_toggle_button_ = nullptr; |
| |
| // Can be null if `ShouldSaveToSettingsBeIncluded()` is false for the active |
| // behavior of current capture mode session, since then it's not needed as the |
| // "Save-to" menu group will not be added at all. |
| raw_ptr<views::Separator> separator_3_ = 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 `ShouldSaveToSettingsBeIncluded()` is |
| // false for the active behavior of current capture mode session. |
| raw_ptr<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. |
| std::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_; |
| |
| std::unique_ptr<SystemShadow> shadow_; |
| |
| base::WeakPtrFactory<CaptureModeSettingsView> weak_ptr_factory_{this}; |
| }; |
| |
| } // namespace ash |
| |
| #endif // ASH_CAPTURE_MODE_CAPTURE_MODE_SETTINGS_VIEW_H_ |