1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109

ash / annotator / annotations_overlay_controller.h [blame]

// Copyright 2024 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_ANNOTATOR_ANNOTATIONS_OVERLAY_CONTROLLER_H_
#define ASH_ANNOTATOR_ANNOTATIONS_OVERLAY_CONTROLLER_H_

#include <memory>
#include <optional>

#include "ash/ash_export.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "ui/aura/window_observer.h"
#include "ui/display/display_observer.h"
#include "ui/display/screen.h"
#include "ui/views/widget/unique_widget_ptr.h"
#include "ui/views/widget/widget.h"

namespace aura {
class Window;
}  // namespace aura

namespace gfx{
class Rect;
}

namespace ash {

class AnnotationsOverlayView;

// Constructs and owns the widget that will be used as an overlay on top of the
// underlying surface to host annotations.
class ASH_EXPORT AnnotationsOverlayController
    : public aura::WindowObserver,
      public display::DisplayObserver {
 public:
  // Constructs the overlay widget, and adds it as a child of `window`.
  // `partial_region_bounds` are initial region bounds selected by the user. Set
  // only if the surface for annotating is a region.
  AnnotationsOverlayController(aura::Window* window,
                               std::optional<gfx::Rect> partial_region_bounds);
  AnnotationsOverlayController(const AnnotationsOverlayController&) = delete;
  AnnotationsOverlayController& operator=(const AnnotationsOverlayController&) =
      delete;
  ~AnnotationsOverlayController() override;

  bool is_enabled() const { return is_enabled_; }

  // Toggles the overlay on or off.
  void Toggle();

  // Gets the underlying window of `overlay_widget_`.
  aura::Window* GetOverlayNativeWindow();

  // aura::WindowObserver:
  void OnWindowBoundsChanged(aura::Window* window,
                             const gfx::Rect& old_bounds,
                             const gfx::Rect& new_bounds,
                             ui::PropertyChangeReason reason) override;
  void OnWindowDestroying(aura::Window* window) override;

  // display::DisplayObserver:
  void OnDisplayMetricsChanged(const display::Display& display,
                               uint32_t metrics) override;

 private:
  // Starts or stops showing the overlay on top of the surface.
  void Start();
  void Stop();

  // Updates the z-order of the `overlay_widget_`'s native window.
  void UpdateWidgetStacking();

  // Sets the bounds of the overlay widget. The given bounds should be relative
  // to the parent `window`.
  void SetBounds(const gfx::Rect& bounds_in_parent);

  // Returns the bounds that should be used for the annotations overlay widget
  // relative to its parent `window_`.
  gfx::Rect GetOverlayWidgetBounds() const;

  // Resets the observations and raw pointers.
  void Reset();

  // The overlay widget and its contents view.
  views::UniqueWidgetPtr overlay_widget_ = std::make_unique<views::Widget>();
  raw_ptr<AnnotationsOverlayView> annotations_overlay_view_ = nullptr;

  // Whether the overlay is currently enabled and showing on top of the recorded
  // surface.
  bool is_enabled_ = false;

  // Window on top of which the overlay is shown.
  raw_ptr<aura::Window> window_ = nullptr;

  // User-selected region bounds for video recording. This field must be
  // provided and cannot be empty if in region video recording mode.
  std::optional<gfx::Rect> partial_region_bounds_;

  base::ScopedObservation<display::Screen, display::DisplayObserver>
      display_observation_{this};
  base::ScopedObservation<aura::Window, aura::WindowObserver>
      window_observation_{this};
};

}  // namespace ash

#endif  // ASH_ANNOTATOR_ANNOTATIONS_OVERLAY_CONTROLLER_H_