File: pinned_toolbar_actions_container.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (185 lines) | stat: -rw-r--r-- 7,790 bytes parent folder | download | duplicates (4)
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// Copyright 2023 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_VIEWS_TOOLBAR_PINNED_TOOLBAR_ACTIONS_CONTAINER_H_
#define CHROME_BROWSER_UI_VIEWS_TOOLBAR_PINNED_TOOLBAR_ACTIONS_CONTAINER_H_

#include <memory>
#include <optional>
#include <set>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "chrome/browser/ui/toolbar/pinned_toolbar/pinned_toolbar_actions_model.h"
#include "chrome/browser/ui/views/toolbar/pinned_action_toolbar_button.h"
#include "chrome/browser/ui/views/toolbar/toolbar_controller.h"
#include "chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h"
#include "ui/actions/action_id.h"
#include "ui/actions/actions.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/drag_controller.h"

class BrowserView;

namespace views {
class ActionViewController;
}

// Container for pinned and epheremeral actions shown in the toolbar.
// Pinned actions are tracked by `pinned_buttons_`. Ephemeral actions are
// tracked by `popped_out_buttons_`. Pinned actions are determined by listening
// to PinnedToolbarActionsModel. Ephemeral actions are determined by external
// callers via the methods UpdateActionState() and  UpdateEphemeralAction().
class PinnedToolbarActionsContainer
    : public ToolbarIconContainerView,
      public PinnedToolbarActionsModel::Observer,
      public views::DragController,
      public ToolbarController::PinnedActionsDelegate {
  METADATA_HEADER(PinnedToolbarActionsContainer, ToolbarIconContainerView)

 public:
  explicit PinnedToolbarActionsContainer(BrowserView* browser_view);
  PinnedToolbarActionsContainer(const PinnedToolbarActionsContainer&) = delete;
  PinnedToolbarActionsContainer& operator=(
      const PinnedToolbarActionsContainer&) = delete;
  ~PinnedToolbarActionsContainer() override;

  // TODO(https://crbug.com/363743077): This method is almost but not quite
  // identical to ShowActionEphemerallyInToolbar(). This doesn't make sense and
  // one should be removed.
  void UpdateActionState(actions::ActionId id, bool is_active);
  // Updates whether the button is shown ephemerally in the toolbar (in the
  // popped out region unless also pinned) regardless of whether it is active.
  void ShowActionEphemerallyInToolbar(actions::ActionId id, bool show);
  void UpdatePinnedStateAndAnnounce(actions::ActionId id, bool pin);

  void MovePinnedActionBy(actions::ActionId action_id, int delta);

  // ToolbarIconContainerView:
  void UpdateAllIcons() override;

  // views::View:
  void OnThemeChanged() override;
  void AddedToWidget() override;
  bool GetDropFormats(int* formats,
                      std::set<ui::ClipboardFormatType>* format_types) override;
  bool AreDropTypesRequired() override;
  bool CanDrop(const ui::OSExchangeData& data) override;
  void OnDragEntered(const ui::DropTargetEvent& event) override;
  int OnDragUpdated(const ui::DropTargetEvent& event) override;
  void OnDragExited() override;
  views::View::DropCallback GetDropCallback(
      const ui::DropTargetEvent& event) override;

  // PinnedToolbarActionsModel::Observer:
  void OnActionAddedLocally(actions::ActionId id) override;
  void OnActionRemovedLocally(actions::ActionId id) override;
  void OnActionsChanged() override;

  // views::DragController:
  void WriteDragDataForView(View* sender,
                            const gfx::Point& press_pt,
                            ui::OSExchangeData* data) override;
  int GetDragOperationsForView(View* sender, const gfx::Point& p) override;
  bool CanStartDragForView(View* sender,
                           const gfx::Point& press_pt,
                           const gfx::Point& p) override;

  // ToolbarController::PinnedActionsDelegate:
  actions::ActionItem* GetActionItemFor(actions::ActionId id) override;
  bool IsOverflowed(actions::ActionId id) override;
  views::View* GetContainerView() override;
  bool ShouldAnyButtonsOverflow(gfx::Size available_size) const override;

  bool IsActionPinned(actions::ActionId id);
  bool IsActionPoppedOut(actions::ActionId id);
  bool IsActionPinnedOrPoppedOut(actions::ActionId id);

  // Returns the button associated with `id`. This does not return permanent
  // buttons which are currently invisible, an accessor for these can be
  // obtained on creation via `CreatePermanentButtonFor`.
  PinnedActionToolbarButton* GetButtonFor(actions::ActionId id);

  // Removes the popped out button if it should no longer remain in the toolbar.
  void MaybeRemovePoppedOutButtonFor(actions::ActionId id);

  // Ensures that if `id` is unpinned, the associated button object will not
  // get destroyed. This is useful for features which need to maintain a
  // persistent reference to the button.
  PinnedActionToolbarButton* CreatePermanentButtonFor(actions::ActionId id);

  const std::vector<actions::ActionId>& PinnedActionIds() const override;

 private:
  friend class PinnedSidePanelInteractiveTest;
  friend class PinnedToolbarActionsContainerTest;

  // A struct representing the position and action being dragged.
  struct DropInfo;

  PinnedActionToolbarButton* AddPoppedOutButtonFor(actions::ActionId id);
  void AddPinnedActionButtonFor(actions::ActionId id);
  void RemovePinnedActionButtonFor(actions::ActionId id);
  PinnedActionToolbarButton* GetPinnedButtonFor(actions::ActionId id);
  PinnedActionToolbarButton* GetPoppedOutButtonFor(actions::ActionId id);
  bool ShouldRemainPoppedOutInToolbar(PinnedActionToolbarButton* button);
  // Returns the size based on the layout manager's default flex specification.
  gfx::Size DefaultFlexRule(const views::SizeBounds& size_bounds);
  // Returns the total width of the `popped_out_buttons_` including margins
  // between them.
  int CalculatePoppedOutButtonsWidth();

  // Sorts child views to display them in the correct order.
  void ReorderViews();

  // Updates the container view to match the current state of the model.
  void UpdateViews();

  void RemoveButton(PinnedActionToolbarButton* button);
  void SetActionButtonIconVisibility(actions::ActionId id, bool visible);

  // Moves the dragged action `action_id`.
  void MovePinnedAction(
      actions::ActionId action_id,
      size_t index,
      base::ScopedClosureRunner cleanup,
      const ui::DropTargetEvent& event,
      ui::mojom::DragOperation& output_drag_op,
      std::unique_ptr<ui::LayerTreeOwner> drag_image_layer_owner);

  std::unique_ptr<PinnedActionToolbarButton> CreateOrGetButtonForAction(
      actions::ActionId id);

  // Performs clean up after dragging.
  void DragDropCleanup(actions::ActionId dragged_action_id);

  // Utility function for going from width to icon counts.
  size_t WidthToIconCount(int x_offset);

  const raw_ptr<BrowserView> browser_view_;

  std::unique_ptr<views::ActionViewController> action_view_controller_;
  std::vector<raw_ptr<PinnedActionToolbarButton, VectorExperimental>>
      pinned_buttons_;
  std::vector<raw_ptr<PinnedActionToolbarButton, VectorExperimental>>
      popped_out_buttons_;
  std::vector<std::unique_ptr<PinnedActionToolbarButton>> permanent_buttons_;
  raw_ptr<views::View> toolbar_divider_;
  raw_ptr<PinnedToolbarActionsModel> model_;

  base::ScopedObservation<PinnedToolbarActionsModel,
                          PinnedToolbarActionsModel::Observer>
      model_observation_{this};

  // The DropInfo for the current drag-and-drop operation, or a null pointer if
  // there is none.
  std::unique_ptr<DropInfo> drop_info_;

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

  base::WeakPtrFactory<PinnedToolbarActionsContainer> drop_weak_ptr_factory_{
      this};
};

#endif  // CHROME_BROWSER_UI_VIEWS_TOOLBAR_PINNED_TOOLBAR_ACTIONS_CONTAINER_H_