File: tab_group_header.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 (191 lines) | stat: -rw-r--r-- 6,648 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
186
187
188
189
190
191
// Copyright 2019 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_TABS_TAB_GROUP_HEADER_H_
#define CHROME_BROWSER_UI_VIEWS_TABS_TAB_GROUP_HEADER_H_

#include <string_view>

#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ref.h"
#include "base/time/time.h"
#include "chrome/browser/ui/views/tabs/tab_slot_view.h"
#include "components/tab_groups/tab_group_id.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/base/mojom/menu_source_type.mojom-forward.h"
#include "ui/views/context_menu_controller.h"
#include "ui/views/controls/focus_ring.h"
#include "ui/views/view_targeter_delegate.h"
#include "ui/views/widget/widget_observer.h"

class TabSlotController;
class TabGroupStyle;
struct TabSizeInfo;
class TabStyle;

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

// View for tab group headers in the tab strip, which are markers of group
// boundaries. There is one header for each group, which is included in the tab
// strip flow and positioned left of the leftmost tab in the group.
class TabGroupHeader : public TabSlotView,
                       public views::ContextMenuController,
                       public views::ViewTargeterDelegate {
  METADATA_HEADER(TabGroupHeader, TabSlotView)

 public:
  TabGroupHeader(TabSlotController& tab_slot_controller,
                 const tab_groups::TabGroupId& group,
                 const TabGroupStyle& style);
  TabGroupHeader(const TabGroupHeader&) = delete;
  TabGroupHeader& operator=(const TabGroupHeader&) = delete;
  ~TabGroupHeader() override;

  void Init(const tab_groups::TabGroupId& group);

  // TabSlotView:
  bool OnKeyPressed(const ui::KeyEvent& event) override;
  bool OnMousePressed(const ui::MouseEvent& event) override;
  bool OnMouseDragged(const ui::MouseEvent& event) override;
  void OnMouseReleased(const ui::MouseEvent& event) override;
  void OnMouseEntered(const ui::MouseEvent& event) override;
  void OnGestureEvent(ui::GestureEvent* event) override;
  void OnFocus() override;
  void OnThemeChanged() override;
  TabSlotView::ViewType GetTabSlotViewType() const override;
  TabSizeInfo GetTabSizeInfo() const override;
  gfx::Rect GetAnchorBoundsInScreen() const override;

  void OnGroupContentsChanged();

  // views::ContextMenuController:
  void ShowContextMenuForViewImpl(
      views::View* source,
      const gfx::Point& point,
      ui::mojom::MenuSourceType source_type) override;

  // views::ViewTargeterDelegate:
  bool DoesIntersectRect(const views::View* target,
                         const gfx::Rect& rect) const override;

  // Updates our visual state according to the tab_groups::TabGroupVisualData
  // for our group.
  // TODO(crbug.com/372296676): Make TabGroupHeader observe the group for
  // changes to cut down on the number of times we recalculate the view.
  void VisualsChanged();

  int GetCollapsedHeaderWidth() const;

  // Removes {editor_bubble_tracker_} from observing the widget.
  void RemoveObserverFromWidget(views::Widget* widget);

  // Enables or disables attention indicator on a tab group.
  void SetTabGroupNeedsAttention(bool needs_attention);

  // Returns whether the attention indicator should be shown.
  bool GetShowingAttentionIndicator();

  // Returns the title text for testing.
  std::u16string_view GetTitleTextForTesting() const;

  bool is_collapsed_for_testing() const { return is_collapsed_; }

 private:
  friend class TabGroupEditorBubbleViewDialogBrowserTest;
  FRIEND_TEST_ALL_PREFIXES(TabStripSaveBrowsertest, AttentionIndicatorIsShown);

  // Calculate the width for this View.
  int GetDesiredWidth() const;
  // Determines if the sync icon should be shown in the header.
  bool ShouldShowHeaderIcon() const;

  // Updates the local is_collapsed_ state.
  void SetCollapsedState();

  void UpdateTitleView();
  void UpdateSyncIconView();
  void UpdateAttentionIndicatorView();
  void UpdateIsCollapsed();

  // Creates a squircle (cross between a square and a circle).
  void CreateHeaderWithoutTitle();
  // Creates a round rect, similar to the shape of a tab when hovered but not
  // selected.
  void CreateHeaderWithTitle();

  void UpdateTooltipText();

  void UpdateAccessibleName();

  const raw_ref<TabSlotController> tab_slot_controller_;

  // The title chip for the tab group header which comprises of title text if
  // there is any, and a background color. The size and color of the chip are
  // set in VisualsChanged().
  const raw_ptr<views::View> title_chip_;

  // The title of the tab group. Text and color of the title are set in
  // VisualsChanged().
  const raw_ptr<views::Label> title_;

  // The sync icon that is displayed in the tab group header of saved groups in
  // the tabstrip.
  const raw_ptr<views::ImageView> sync_icon_;

  // The circle indicator rendered after the title when a tab group has
  // needs_attention_ set to true.
  const raw_ptr<views::ImageView> attention_indicator_;

  const raw_ref<const TabGroupStyle> group_style_;
  const raw_ptr<const TabStyle> tab_style_;

  // The current title of the group.
  std::u16string group_title_;

  // The current color of the group.
  SkColor color_;

  // Determines if we should show the header icon in front of the title.
  bool should_show_header_icon_;

  // Local saved collapsed state. When this differs from
  // `TabSlotController::IsGroupCollapsed()`, then the collapsed state has
  // changed in the model and we need to react to that.
  bool is_collapsed_;

  // Determines if the tab group should show the attention indicator.
  bool needs_attention_ = false;

  base::CallbackListSubscription title_text_changed_subscription_;

  // Tracks whether our editor bubble is open. At most one can be open
  // at once.
  class EditorBubbleTracker : public views::WidgetObserver {
   public:
    explicit EditorBubbleTracker(TabSlotController& tab_slot_controller);
    ~EditorBubbleTracker() override;

    void Opened(views::Widget* bubble_widget);
    bool is_open() const { return is_open_; }
    views::Widget* widget() const { return widget_; }

    // views::WidgetObserver:
    void OnWidgetDestroying(views::Widget* widget) override;

   private:
    bool is_open_ = false;
    raw_ptr<views::Widget, AcrossTasksDanglingUntriaged> widget_;
    // Outlives this because it's a dependency inversion interface for the
    // header's parent View.
    raw_ref<TabSlotController> tab_slot_controller_;
  };

  EditorBubbleTracker editor_bubble_tracker_;
};

#endif  // CHROME_BROWSER_UI_VIEWS_TABS_TAB_GROUP_HEADER_H_