123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- // Copyright 2022 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_CAMERA_PREVIEW_VIEW_H_
- #define ASH_CAPTURE_MODE_CAPTURE_MODE_CAMERA_PREVIEW_VIEW_H_
- #include "ash/accessibility/accessibility_controller_impl.h"
- #include "ash/accessibility/accessibility_observer.h"
- #include "ash/capture_mode/camera_video_frame_renderer.h"
- #include "ash/capture_mode/capture_mode_button.h"
- #include "ash/capture_mode/capture_mode_camera_controller.h"
- #include "ash/capture_mode/capture_mode_session_focus_cycler.h"
- #include "base/memory/weak_ptr.h"
- #include "base/scoped_observation.h"
- #include "mojo/public/cpp/bindings/remote.h"
- #include "ui/base/metadata/metadata_header_macros.h"
- #include "ui/gfx/geometry/size.h"
- #include "ui/views/view.h"
- namespace media {
- struct VideoCaptureFormat;
- } // namespace media
- namespace video_capture::mojom {
- class VideoSource;
- } // namespace video_capture::mojom
- namespace views {
- class NativeViewHost;
- } // namespace views
- namespace ash {
- class CaptureModeCameraController;
- class ScopedA11yOverrideWindowSetter;
- // Resize button inside the camera preview view.
- class CameraPreviewResizeButton : public CaptureModeButton {
- public:
- METADATA_HEADER(CameraPreviewResizeButton);
- CameraPreviewResizeButton(CameraPreviewView* camera_preview_view,
- views::Button::PressedCallback callback,
- const gfx::VectorIcon& icon);
- CameraPreviewResizeButton(const CameraPreviewResizeButton&) = delete;
- CameraPreviewResizeButton& operator=(const CameraPreviewResizeButton&) =
- delete;
- ~CameraPreviewResizeButton() override;
- // CaptureModeSessionFocusCycler::HighlightableView:
- void PseudoFocus() override;
- void PseudoBlur() override;
- private:
- CameraPreviewView* const camera_preview_view_; // not owned.
- };
- // A view that acts as the contents view of the camera preview widget. It will
- // be responsible for painting the latest camera video frame inside its bounds.
- class CameraPreviewView
- : public views::View,
- public CaptureModeSessionFocusCycler::HighlightableView,
- public AccessibilityObserver {
- public:
- METADATA_HEADER(CameraPreviewView);
- CameraPreviewView(
- CaptureModeCameraController* camera_controller,
- const CameraId& camera_id,
- mojo::Remote<video_capture::mojom::VideoSource> camera_video_source,
- const media::VideoCaptureFormat& capture_format,
- bool should_flip_frames_horizontally);
- CameraPreviewView(const CameraPreviewView&) = delete;
- CameraPreviewView& operator=(const CameraPreviewView&) = delete;
- ~CameraPreviewView() override;
- const CameraId& camera_id() const { return camera_id_; }
- CameraPreviewResizeButton* resize_button() const { return resize_button_; }
- bool is_collapsible() const { return is_collapsible_; }
- bool should_flip_frames_horizontally() const {
- return camera_video_renderer_.should_flip_frames_horizontally();
- }
- // Sets this camera preview collapsability to the given `value`, which will
- // update the resize button visibility.
- void SetIsCollapsible(bool value);
- // Returns true if the `event` has been handled by CameraPrevieView. It
- // happens if it is control+arrow keys, which will be used to move the camera
- // preview to different snap positions.
- bool MaybeHandleKeyEvent(const ui::KeyEvent* event);
- // Called to update visibility of the `resize_button_` when necessary.
- void RefreshResizeButtonVisibility();
- // Updates the a11y override window when focus state changes on the camera
- // preview. The a11y override window will be set to nullptr if neither the
- // camera preview nor the resize button has focus. This is done to make sure
- // a11y focus can be moved to others appropriately.
- void UpdateA11yOverrideWindow();
- // Removes the focus from camera preview when necessary. Happens if mouse
- // pressing outside of the camera preview when it has focus. A11y override
- // window will be updated as well.
- void MaybeBlurFocus(const ui::MouseEvent& event);
- // views::View:
- void AddedToWidget() override;
- bool OnMousePressed(const ui::MouseEvent& event) override;
- bool OnMouseDragged(const ui::MouseEvent& event) override;
- void OnMouseReleased(const ui::MouseEvent& event) override;
- void OnGestureEvent(ui::GestureEvent* event) override;
- void OnMouseEntered(const ui::MouseEvent& event) override;
- void OnMouseExited(const ui::MouseEvent& event) override;
- void Layout() override;
- void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
- // CaptureModeSessionFocusCycler::HighlightableView:
- views::View* GetView() override;
- std::unique_ptr<views::HighlightPathGenerator> CreatePathGenerator() override;
- // AccessibilityObserver:
- void OnAccessibilityStatusChanged() override;
- void OnAccessibilityControllerShutdown() override;
- base::OneShotTimer* resize_button_hide_timer_for_test() {
- return &resize_button_hide_timer_;
- }
- private:
- friend class CameraPreviewResizeButton;
- friend class CaptureModeTestApi;
- // Called when the resize button is clicked or touched.
- void OnResizeButtonPressed();
- // Updates the icon of the `resize_button_` based on value of
- // `is_camera_preview_collapsed()` inferred from the `camera_controller`.
- void UpdateResizeButton();
- // Updates the tooltip of the `resize_button_`. The `resize_button_` can be an
- // expand button or collapse button.
- void UpdateResizeButtonTooltip();
- // Located events within the bounds of this view should be sent to, and
- // handled by this view only (e.g. for drag and drop). They should not be sent
- // to any native window hosting the camera video frames, otherwise we will
- // lose those events. This function disable event targeting for the
- // `camera_video_host_view_` and all the native windows it is hosting.
- void DisableEventHandlingInCameraVideoHostHierarchy();
- // Fades in or out the `resize_button_` and updates its visibility
- // accordingly.
- void FadeInResizeButton();
- void FadeOutResizeButton();
- // Called when the mouse exits the camera preview, after the latest tap inside
- // the camera preview or when focus being removed from the resize button to
- // start the `resize_button_hide_timer_`.
- void ScheduleRefreshResizeButtonVisibility();
- // Returns the target opacity for resize button.
- float CalculateResizeButtonTargetOpacity();
- // Removes the focus from the camera preview and updates the a11y override
- // window.
- void BlurA11yFocus();
- CaptureModeCameraController* const camera_controller_;
- // The ID of the camera for which this preview was created.
- const CameraId camera_id_;
- // Renders the camera video frames into its `host_window()`.
- CameraVideoFrameRenderer camera_video_renderer_;
- // The view that hosts the native window `host_window()` of the
- // `camera_video_renderer_` into this view's hierarchy.
- views::NativeViewHost* const camera_video_host_view_;
- CameraPreviewResizeButton* const resize_button_;
- // Started when the mouse exits the camera preview or after the latest tap
- // inside the camera preview. Runs RefreshResizeButtonVisibility() to fade out
- // the resize button if possible.
- base::OneShotTimer resize_button_hide_timer_;
- // True if the size of the preview in the expanded state is big enough to
- // allow it to be collapsible.
- bool is_collapsible_ = true;
- // True only while handling a gesture tap event on this view.
- bool has_been_tapped_ = false;
- base::ScopedObservation<AccessibilityControllerImpl, AccessibilityObserver>
- accessibility_observation_{this};
- // Helps to update the current a11y override window. It will be the native
- // window of the camera preview or nullptr, depends on whether the camera
- // preview has focus or not. Accessibility features will focus on the window
- // after it is set. Once `this` goes out of scope, the a11y override window is
- // set to nullptr.
- std::unique_ptr<ScopedA11yOverrideWindowSetter> scoped_a11y_overrider_;
- base::WeakPtrFactory<CameraPreviewView> weak_ptr_factory_{this};
- };
- } // namespace ash
- #endif // ASH_CAPTURE_MODE_CAPTURE_MODE_CAMERA_PREVIEW_VIEW_H_
|