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
  110
  111
  112
  113
  114

ash / system / video_conference / bubble / toggle_effects_view.h [blame]

// Copyright 2022 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_SYSTEM_VIDEO_CONFERENCE_BUBBLE_TOGGLE_EFFECTS_VIEW_H_
#define ASH_SYSTEM_VIDEO_CONFERENCE_BUBBLE_TOGGLE_EFFECTS_VIEW_H_

#include "ash/system/video_conference/effects/video_conference_tray_effects_manager.h"
#include "base/memory/raw_ptr.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/view.h"

namespace gfx {
struct VectorIcon;
}  // namespace gfx

namespace ui {
class Event;
}  // namespace ui

namespace views {
class FlexLayout;
class ImageView;
class Label;
}  // namespace views

namespace ash {
enum class VcEffectId;
class VideoConferenceTrayController;

namespace video_conference {

// A single toggle button for a video conference effect, combined with a text
// label. WARNING: `callback` provided must not destroy the button or the bubble
// (i.e. close the bubble) as it would result in a crash in `OnButtonClicked()`.
class ToggleEffectsButton : public views::Button,
                            public VideoConferenceTrayEffectsManager::Observer {
  METADATA_HEADER(ToggleEffectsButton, views::Button)

 public:
  ToggleEffectsButton(views::Button::PressedCallback callback,
                      const gfx::VectorIcon* vector_icon,
                      bool toggle_state,
                      const std::u16string& label_text,
                      const int accessible_name_id,
                      std::optional<int> container_id,
                      const VcEffectId effect_id,
                      int num_button_per_row);

  ToggleEffectsButton(const ToggleEffectsButton&) = delete;
  ToggleEffectsButton& operator=(const ToggleEffectsButton&) = delete;

  ~ToggleEffectsButton() override;

  // VideoConferenceTrayEffectsManager::Observer:
  void OnEffectChanged(VcEffectId effect_id, bool is_on) override;

  views::FlexLayout* layout() { return layout_; }

  views::ImageView* icon() { return icon_; }

 private:
  // Callback for clicking the button.
  void OnButtonClicked(const ui::Event& event);

  // Update the color of icon/label and background.
  void UpdateColorsAndBackground();

  // Update the tooltip text.
  void UpdateTooltip();

  views::Button::PressedCallback callback_;

  // Indicates the toggled state of the button.
  bool toggled_ = false;

  // The effect id associated to the effect of this button.
  const VcEffectId effect_id_;

  // Owned by the views hierarchy.
  raw_ptr<views::ImageView> icon_ = nullptr;
  raw_ptr<views::Label> label_ = nullptr;

  raw_ptr<const gfx::VectorIcon> vector_icon_;
  const int accessible_name_id_;

  raw_ptr<views::FlexLayout> layout_ = nullptr;

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

// The toggle effects view, that resides in the video conference bubble. It
// functions as a "factory" that constructs and hosts rows of buttons, with each
// button managing the on/off state for an individual effect. The buttons are
// constructed from effects data gathered from `VcEffectsDelegate` objects that
// host the individual effects and are registered with the
// `VideoConferenceTrayEffectsManager`, which is in turn owned by the passed-in
// controller.
class ToggleEffectsView : public views::View {
  METADATA_HEADER(ToggleEffectsView, views::View)

 public:
  explicit ToggleEffectsView(VideoConferenceTrayController* controller);
  ToggleEffectsView(const ToggleEffectsView&) = delete;
  ToggleEffectsView& operator=(const ToggleEffectsView&) = delete;
  ~ToggleEffectsView() override = default;
};

}  // namespace video_conference

}  // namespace ash

#endif  // ASH_SYSTEM_VIDEO_CONFERENCE_BUBBLE_TOGGLE_EFFECTS_VIEW_H_