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

ash / components / arc / compat_mode / compat_mode_button_controller.h [blame]

// 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_COMPONENTS_ARC_COMPAT_MODE_COMPAT_MODE_BUTTON_CONTROLLER_H_
#define ASH_COMPONENTS_ARC_COMPAT_MODE_COMPAT_MODE_BUTTON_CONTROLLER_H_

#include <memory>
#include <optional>

#include "ash/components/arc/compat_mode/resize_toggle_menu.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"

namespace ash {
enum class ArcResizeLockType;
}  // namespace ash

namespace aura {
class Window;
}  // namespace aura

namespace chromeos {
class FrameHeader;
}  // namespace chromeos

namespace arc {

class ArcResizeLockPrefDelegate;

class CompatModeButtonController {
 public:
  // Struct that represents the state for the `CompatModeButton` or a similar
  // view.
  struct ButtonState {
    ButtonState();
    explicit ButtonState(bool enable);
    ButtonState(bool enable, const std::u16string& tooltip_text);
    ButtonState(const ButtonState& other);
    ~ButtonState();

    bool enable;  // Whether to enable the button.
    std::optional<std::u16string> tooltip_text;  // The button's tooltip text.
  };

  CompatModeButtonController();
  CompatModeButtonController(const CompatModeButtonController&) = delete;
  CompatModeButtonController& operator=(const CompatModeButtonController&) =
      delete;
  virtual ~CompatModeButtonController();

  // virtual for unittest.
  virtual void Update(aura::Window* window);

  // virtual for unittest.
  virtual void OnButtonPressed();

  // Clears the `pref_delegate_`. Called when `ArcResizeLockManager` keyed
  // service is shutting down, so the delegate isn't being freed with invalid
  // memory.
  void ClearPrefDelegate();

  // Sets `pref_delegate_` to `delegate`, ensuring that it was not already set.
  void SetPrefDelegate(ArcResizeLockPrefDelegate* pref_delegate);

  // Using the `window`'s `ash::kArcResizeLockTypeKey` window property, returns
  // the updated `ButtonState` for the `CompatModeButton`, or a similar view. If
  // the button should not be updated, then it returns `std::nullopt`.
  std::optional<ButtonState> GetButtonState(const aura::Window* window) const;

  void UpdateArrowIcon(aura::Window* window, bool widget_visibility);

  // Displays the resize toggle menu using the given `window`'s frame view as
  // the widget. The given `on_bubble_widget_closing_callback` handles any
  // special logic needed when the resize toggle menu closes.
  void ShowResizeToggleMenu(
      aura::Window* window,
      base::OnceClosure on_bubble_widget_closing_callback);

  base::WeakPtr<CompatModeButtonController> GetWeakPtr();

 private:
  // virtual for unittest.
  virtual chromeos::FrameHeader* GetFrameHeader(aura::Window* window);

  void UpdateAshAccelerator(aura::Window* window);

  void ToggleResizeToggleMenu(aura::Window* window);

  std::unique_ptr<ResizeToggleMenu> resize_toggle_menu_;

  raw_ptr<ArcResizeLockPrefDelegate> pref_delegate_;

  bool visible_when_button_pressed_{false};

  base::WeakPtrFactory<CompatModeButtonController> weak_ptr_factory_{this};
};

}  // namespace arc

#endif  // ASH_COMPONENTS_ARC_COMPAT_MODE_COMPAT_MODE_BUTTON_CONTROLLER_H_