File: tab_group_editor_bubble_view.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (235 lines) | stat: -rw-r--r-- 8,983 bytes parent folder | download | duplicates (3)
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
// 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_EDITOR_BUBBLE_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_TABS_TAB_GROUP_EDITOR_BUBBLE_VIEW_H_

#include <optional>
#include <string>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "chrome/browser/ui/views/tabs/tab_group_header.h"
#include "components/tab_groups/tab_group_color.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/base/mojom/menu_source_type.mojom-forward.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/controls/textfield/textfield_controller.h"

class Browser;

namespace tab_groups {
enum class TabGroupColorId;
class TabGroupId;
}  // namespace tab_groups

namespace views {
class Separator;
}  // namespace views

class ColorPickerView;
class TabGroupHeader;
class ManageSharingRow;

// A dialog for changing a tab group's visual parameters.
class TabGroupEditorBubbleView : public views::BubbleDialogDelegateView,
                                 public TabStripModelObserver {
  METADATA_HEADER(TabGroupEditorBubbleView, views::BubbleDialogDelegateView)

 public:
  static constexpr int TAB_GROUP_HEADER_CXMENU_SAVE_GROUP = 1;
  static constexpr int TAB_GROUP_HEADER_CXMENU_NEW_TAB_IN_GROUP = 2;
  static constexpr int TAB_GROUP_HEADER_CXMENU_UNGROUP = 3;
  static constexpr int TAB_GROUP_HEADER_CXMENU_MANAGE_SHARING = 4;
  static constexpr int TAB_GROUP_HEADER_CXMENU_SHARE = 5;
  static constexpr int TAB_GROUP_HEADER_CXMENU_CLOSE_GROUP = 6;
  static constexpr int TAB_GROUP_HEADER_CXMENU_DELETE_GROUP = 7;
  static constexpr int TAB_GROUP_HEADER_CXMENU_LEAVE_GROUP = 8;
  static constexpr int TAB_GROUP_HEADER_CXMENU_MOVE_GROUP_TO_NEW_WINDOW = 9;
  static constexpr int TAB_GROUP_HEADER_CXMENU_RECENT_ACTIVITY = 10;

  using Colors =
      std::vector<std::pair<tab_groups::TabGroupColorId, std::u16string>>;

  // Shows the editor for `group`. Returns a *non-owning* pointer to the
  // bubble's widget.
  static views::Widget* Show(
      Browser* browser,
      const tab_groups::TabGroupId& group,
      TabGroupHeader* header_view,
      std::optional<gfx::Rect> anchor_rect = std::nullopt,
      // If not provided, will be set to `header_view`.
      views::View* anchor_view = nullptr,
      bool stop_context_menu_propagation = false);

  // views::BubbleDialogDelegateView:
  views::View* GetInitiallyFocusedView() override;
  gfx::Rect GetAnchorRect() const override;
  // This needs to be added as it does not know the correct theme color until it
  // is added to widget.
  void AddedToWidget() override;

 private:
  TabGroupEditorBubbleView(Browser* browser,
                           const tab_groups::TabGroupId& group,
                           views::View* anchor_view,
                           std::optional<gfx::Rect> anchor_rect,
                           bool stop_context_menu_propagation);
  ~TabGroupEditorBubbleView() override;

  // TabStripModelObserver:
  void OnTabGroupChanged(const TabGroupChange& change) override;

  void UpdateGroup();
  std::u16string GetTextForCloseButton() const;

  // Returns whether the user has the appropriate profile and the
  // enabled features to save/share groups.
  bool CanSaveGroups() const;
  bool CanShareGroups() const;

  // Returns whether the user has permissions to create shared groups.
  bool IsAllowedToCreateSharedGroup() const;

  bool IsGroupSaved() const;
  bool IsGroupShared() const;
  bool ShouldShowSavedFooter() const;
  // Returns true if the user created the group. Returns false in cases where
  // the user was invited to join the group.
  bool OwnsGroup() const;

  // When certain settings change, the menu items need to be updated, this
  // method destroys the children of the view, and then recreates them in the
  // correct order/visibility.
  void RebuildMenuContents();
  void UpdateMenuContentsVisibility();

  std::unique_ptr<views::Separator> BuildSeparator();
  std::unique_ptr<ColorPickerView> BuildColorPicker();
  std::unique_ptr<views::LabelButton> BuildNewTabInGroupButton();
  std::unique_ptr<views::LabelButton> BuildUngroupButton();
  std::unique_ptr<views::LabelButton> BuildCloseGroupButton();
  std::unique_ptr<views::LabelButton> BuildDeleteGroupButton();
  std::unique_ptr<views::LabelButton> BuildLeaveGroupButton();
  std::unique_ptr<views::LabelButton> BuildMoveGroupToNewWindowButton();
  std::unique_ptr<ManageSharingRow> BuildManageSharingButton();
  std::unique_ptr<views::LabelButton> BuildShareGroupButton();
  std::unique_ptr<views::LabelButton> BuildRecentActivityButton();

  void NewTabInGroupPressed();
  void UngroupPressed();
  void ShareOrManagePressed();
  void CloseGroupPressed();
  void DeleteGroupPressed();
  void LeaveGroupPressed();
  void MoveGroupToNewWindowPressed();
  void RecentActivityPressed();

  // The action for moving a group to a new window is only enabled when the
  // tabstrip contains more than just the tabs in the current group.
  bool CanMoveGroupToNewWindow();

  // If the saved tab group service exists, this method disconnects the group
  // from the saved tab group so that actions can be performed on the group
  // without updating the saved group. If the service doesnt exist, it does
  // nothing.
  void MaybeDisconnectSavedGroup();

  // Closes all of the tabs in the tab group in the tabstrip. If the tab group
  // Is the only thing in the tabstrip, adds a new tab first so that the window
  // isn't closed.
  void DeleteGroupFromTabstrip();

  void OnBubbleClose();

  // Creates the set of tab group colors to display and returns the color that
  // is initially selected.
  tab_groups::TabGroupColorId InitColorSet();

  // the implementation of the ungroup command. This method is static so that
  // it can be called from dialogs as a callback.
  static void Ungroup(const Browser* browser, tab_groups::TabGroupId group);

  class TitleFieldController : public views::TextfieldController {
   public:
    explicit TitleFieldController(TabGroupEditorBubbleView* parent)
        : parent_(parent) {}
    ~TitleFieldController() override = default;

    // views::TextfieldController:
    void ContentsChanged(views::Textfield* sender,
                         const std::u16string& new_contents) override;
    bool HandleKeyEvent(views::Textfield* sender,
                        const ui::KeyEvent& key_event) override;

   private:
    const raw_ptr<TabGroupEditorBubbleView> parent_;
  };

  class TitleField : public views::Textfield {
    METADATA_HEADER(TitleField, views::Textfield)

   public:
    explicit TitleField(bool stop_context_menu_propagation)
        : stop_context_menu_propagation_(stop_context_menu_propagation) {}
    ~TitleField() override = default;

    // views::Textfield:
    void ShowContextMenu(const gfx::Point& p,
                         ui::mojom::MenuSourceType source_type) override;

   private:
    // Whether the context menu should be hidden the first time it shows.
    // Needed because there is no easy way to stop the propagation of a
    // ShowContextMenu event, which is sometimes used to open the bubble
    // itself.
    bool stop_context_menu_propagation_;
  };
  std::unique_ptr<TitleField> BuildTitleField(const std::u16string& title);
  std::u16string GetGroupTitle();

  class Footer : public views::View {
    METADATA_HEADER(Footer, views::View)
   public:
    explicit Footer(const Browser* browser_);
    ~Footer() override = default;

    static void OpenLearnMorePage(const Browser* browser_);
  };

  TitleFieldController title_field_controller_;
  Colors colors_;

  const raw_ptr<Browser> browser_;
  const tab_groups::TabGroupId group_;

  // Ptr access to specific children. Must be cleared and reset by
  // RebuildMenuContents.
  raw_ptr<TitleField> title_field_ = nullptr;
  raw_ptr<ColorPickerView> color_selector_ = nullptr;
  raw_ptr<Footer> footer_ = nullptr;
  raw_ptr<ManageSharingRow> manage_shared_group_button_ = nullptr;
  raw_ptr<views::ImageView> save_group_icon_ = nullptr;
  raw_ptr<views::Label> save_group_label_ = nullptr;

  // The different menu items, used for referring back to specific children for
  // styling.
  std::vector<raw_ptr<views::LabelButton>> simple_menu_items_;

  // If true will use the `anchor_rect_` provided in the constructor, otherwise
  // fall back to using the anchor view bounds.
  const bool use_set_anchor_rect_;

  // The first title shown to the user when the bubble dialog is opened. Used
  // for logging whether the user changes the title.
  std::u16string title_at_opening_;

  // Stored value for constructor param.
  bool stop_context_menu_propagation_;
};

#endif  // CHROME_BROWSER_UI_VIEWS_TABS_TAB_GROUP_EDITOR_BUBBLE_VIEW_H_