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_
|