chromium/chrome/browser/ui/chromeos/read_write_cards/read_write_cards_ui_controller.h

// 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 CHROME_BROWSER_UI_CHROMEOS_READ_WRITE_CARDS_READ_WRITE_CARDS_UI_CONTROLLER_H_
#define CHROME_BROWSER_UI_CHROMEOS_READ_WRITE_CARDS_READ_WRITE_CARDS_UI_CONTROLLER_H_

#include <optional>

#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/ui/views/editor_menu/utils/pre_target_handler.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/view_observer.h"
#include "ui/views/view_tracker.h"
#include "ui/views/widget/unique_widget_ptr.h"

namespace views {
class View;
class Widget;
}  // namespace views

namespace chromeos {

class ReadWriteCardsView;

// The controller that manages all the behaviors of the UI widget containing
// some of the read write cards (currently these are quick answers and mahi
// cards).
class ReadWriteCardsUiController
    : public views::ViewObserver,
      public chromeos::editor_menu::PreTargetHandler::Delegate {
 public:
  static constexpr char kWidgetName[] = "ReadWriteCardsWidget";

  ReadWriteCardsUiController();

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

  ~ReadWriteCardsUiController() override;

  // Sets/removes a view for quick answers ui. This view will be added into this
  // widget and used to calculate widget bounds. This can be either
  // `QuickAnswersView` or `UserConsentView`.
  // TODO(b/331271987): Use `views::View`.
  ReadWriteCardsView* SetQuickAnswersUi(
      std::unique_ptr<ReadWriteCardsView> view);
  void RemoveQuickAnswersUi();

  // Sets/removes mahi views. This view will be added into this widget and used
  // to calculate widget bounds.
  views::View* SetMahiUi(std::unique_ptr<views::View> view);
  void RemoveMahiUi();

  ReadWriteCardsView* GetQuickAnswersUiForTest();
  views::View* GetMahiUiForTest();

  void SetContextMenuBounds(const gfx::Rect& context_menu_bounds);

  // chromeos::editor_menu::PreTargetHandler::Delegate:
  views::View* GetRootView() override;
  std::vector<views::View*> GetTraversableViewsByUpDownKeys() override;

  chromeos::editor_menu::PreTargetHandler& pre_target_handler() {
    return pre_target_handler_.value();
  }

  const gfx::Rect& context_menu_bounds() const { return context_menu_bounds_; }

  views::Widget* widget_for_test() const { return widget_.get(); }

  bool widget_above_context_menu_for_test() {
    return widget_above_context_menu_;
  }

 private:
  // views::ViewObserver:
  void OnViewIsDeleting(views::View* observed_view) override;
  void OnViewLayoutInvalidated(views::View* view) override;

  // Initializes `widget_` if necessary.
  void MaybeCreateWidget();

  // Hides `widget_` if necessary.
  void MaybeHideWidget();

  // Reorder the child views inside `widget_`, depending on if the widget is
  // above or below the context menu.
  void ReorderChildViews();

  // Re-layout if widget is shown.
  void MaybeRelayout();

  // Re-layout a widget and views. This includes updating the widget bounds and
  // reorder child views, if needed.
  void Relayout();

  ReadWriteCardsView* quick_answers_ui() {
    return quick_answers_ui_observation_.GetSource();
  }
  views::View* mahi_ui() { return mahi_ui_observation_.GetSource(); }

  base::ScopedObservation<ReadWriteCardsView, ReadWriteCardsUiController>
      quick_answers_ui_observation_{this};
  base::ScopedObservation<views::View, ReadWriteCardsUiController>
      mahi_ui_observation_{this};

  std::optional<chromeos::editor_menu::PreTargetHandler> pre_target_handler_;

  // Indicates whether the widget is placed above or below the context menu.
  bool widget_above_context_menu_ = false;

  views::UniqueWidgetPtr widget_;

  // The bounds of the context menu, used to calculate the widget bounds.
  gfx::Rect context_menu_bounds_;
};

}  // namespace chromeos

#endif  // CHROME_BROWSER_UI_CHROMEOS_READ_WRITE_CARDS_READ_WRITE_CARDS_UI_CONTROLLER_H_