blob: 383f28ebebae03b8ccb3b205abd60e858dee6b92 [file] [log] [blame]
// Copyright 2025 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_DRAGGING_DRAG_SESSION_DATA_H_
#define CHROME_BROWSER_UI_VIEWS_TABS_DRAGGING_DRAG_SESSION_DATA_H_
#include <limits>
#include <memory>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "chrome/browser/ui/views/tabs/tab_slot_view.h"
#include "components/tab_groups/tab_group_id.h"
#include "components/tab_groups/tab_group_visual_data.h"
namespace content {
class WebContents;
}
class TabSlotView;
class TabDragContext;
// Stores the data associated with a group header that is being dragged.
struct GroupDragData final {
// The group that is being dragged.
tab_groups::TabGroupId group;
// The index of the tab within the group, if any, that was active when the
// drag began. Defaults to 0 if the active tab was outside the group, as we
// should fall back on activating the first tab during/after the drag.
int active_tab_index_within_group;
GroupDragData(tab_groups::TabGroupId group, int active_tab_index_within_group)
: group(group),
active_tab_index_within_group(active_tab_index_within_group) {}
};
// Stores the data associated with a single tab that is being dragged.
struct TabDragData final {
TabDragData(TabDragContext* source_context, TabSlotView* view);
TabDragData(const TabDragData&);
TabDragData& operator=(const TabDragData&);
~TabDragData();
TabDragData(TabDragData&&);
// This is the index of the tab in `source_context_` when the drag
// began. This is used to restore the previous state if the drag is aborted.
// Nullopt if this is a group header.
std::optional<int> source_model_index;
TabSlotView::ViewType view_type;
// The WebContents being dragged.
raw_ptr<content::WebContents> contents = nullptr;
// If attached this is the view in `attached_context_`.
raw_ptr<TabSlotView> attached_view = nullptr;
// Is the tab pinned?
bool pinned = false;
// Contains the information for the tab's group at the start of the drag.
struct TabGroupData {
tab_groups::TabGroupId group_id;
tab_groups::TabGroupVisualData group_visual_data;
};
// The information on the group the tab was in at the start of the drag, or
// nullopt if tab was not grouped.
std::optional<TabGroupData> tab_group_data = std::nullopt;
};
// Stores the data for the tabs and (if applicable) group header being dragged.
// This is the core configuration for a tab drag session.
struct DragSessionData final {
DragSessionData();
DragSessionData(const DragSessionData&);
DragSessionData& operator=(const DragSessionData&);
~DragSessionData();
DragSessionData(DragSessionData&&);
std::vector<TabDragData> tab_drag_data_;
// Data related to the dragged tab group, if any. This is only set if the
// drag originated from a group header, indicating that the entire group is
// being dragged together.
std::optional<GroupDragData> group_drag_data_ = std::nullopt;
// Index of the source view in `tab_drag_data_`. This is the view that the
// user started dragging.
size_t source_view_index_ = std::numeric_limits<size_t>::max();
std::optional<tab_groups::TabGroupId> group() const {
return group_drag_data_.has_value()
? std::make_optional(group_drag_data_.value().group)
: std::nullopt;
}
// Convenience for getting the TabDragData corresponding to the source view
// that the user started dragging.
const TabDragData* source_view_drag_data() const {
return &(tab_drag_data_[source_view_index_]);
}
// Convenience for `source_view_drag_data()->contents`.
content::WebContents* source_dragged_contents() const {
return source_view_drag_data()->contents;
}
// Returns the number of Tab views currently dragging.
// Excludes the TabGroupHeader view, if any.
int num_dragging_tabs() const {
int num_tabs = 0;
for (const TabDragData& tab_drag_datum : tab_drag_data_) {
if (tab_drag_datum.attached_view->GetTabSlotViewType() ==
TabSlotView::ViewType::kTab) {
num_tabs++;
}
}
return num_tabs;
}
std::vector<TabSlotView*> attached_views() const {
std::vector<TabSlotView*> attached_views;
for (const TabDragData& tab_data : tab_drag_data_) {
attached_views.push_back(tab_data.attached_view);
}
return attached_views;
}
};
#endif // CHROME_BROWSER_UI_VIEWS_TABS_DRAGGING_DRAG_SESSION_DATA_H_