chromium/chrome/browser/ui/views/tabs/tab_container_impl.cc

// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/tabs/tab_container_impl.h"

#include <memory>

#include "base/bits.h"
#include "base/containers/adapters.h"
#include "base/ranges/algorithm.h"
#include "base/types/to_address.h"
#include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/tabs/features.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/views/frame/browser_root_view.h"
#include "chrome/browser/ui/views/tabs/tab.h"
#include "chrome/browser/ui/views/tabs/tab_drag_context.h"
#include "chrome/browser/ui/views/tabs/tab_drag_controller.h"
#include "chrome/browser/ui/views/tabs/tab_group_header.h"
#include "chrome/browser/ui/views/tabs/tab_group_highlight.h"
#include "chrome/browser/ui/views/tabs/tab_group_underline.h"
#include "chrome/browser/ui/views/tabs/tab_group_views.h"
#include "chrome/browser/ui/views/tabs/tab_hover_card_controller.h"
#include "chrome/browser/ui/views/tabs/tab_scrolling_animation.h"
#include "chrome/browser/ui/views/tabs/tab_slot_animation_delegate.h"
#include "chrome/browser/ui/views/tabs/tab_strip.h"
#include "chrome/browser/ui/views/tabs/tab_strip_controller.h"
#include "chrome/browser/ui/views/tabs/tab_style_views.h"
#include "chrome/browser/ui/views/tabs/z_orderable_tab_container_element.h"
#include "chrome/grit/theme_resources.h"
#include "components/tab_groups/tab_group_id.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/display/screen.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/scroll_view.h"
#include "ui/views/mouse_watcher_view_host.h"
#include "ui/views/rect_based_targeting_utils.h"
#include "ui/views/view_utils.h"

namespace {

// Size of the drop indicator.
int g_drop_indicator_width =;
int g_drop_indicator_height =;

int GetDropArrowImageResourceId(bool is_down) {}

}  // namespace

///////////////////////////////////////////////////////////////////////////////
// TabContainerImpl::RemoveTabDelegate
//
// AnimationDelegate used when removing a tab. Does the necessary cleanup when
// done.
class TabContainerImpl::RemoveTabDelegate : public TabSlotAnimationDelegate {};

TabContainerImpl::RemoveTabDelegate::RemoveTabDelegate(
    TabContainer* tab_container,
    Tab* tab)
    :{}

void TabContainerImpl::RemoveTabDelegate::AnimationEnded(
    const gfx::Animation* animation) {}

void TabContainerImpl::RemoveTabDelegate::AnimationCanceled(
    const gfx::Animation* animation) {}

TabContainerImpl::TabContainerImpl(
    TabContainerController& controller,
    TabHoverCardController* hover_card_controller,
    TabDragContextBase* drag_context,
    TabSlotController& tab_slot_controller,
    views::View* scroll_contents_view)
    :{}

TabContainerImpl::~TabContainerImpl() {}

void TabContainerImpl::SetAvailableWidthCallback(
    base::RepeatingCallback<int()> available_width_callback) {}

Tab* TabContainerImpl::AddTab(std::unique_ptr<Tab> tab,
                              int model_index,
                              TabPinned pinned) {}

void TabContainerImpl::MoveTab(int from_model_index, int to_model_index) {}

void TabContainerImpl::RemoveTab(int model_index, bool was_active) {}

void TabContainerImpl::SetTabPinned(int model_index, TabPinned pinned) {}

void TabContainerImpl::SetActiveTab(std::optional<size_t> prev_active_index,
                                    std::optional<size_t> new_active_index) {}

Tab* TabContainerImpl::RemoveTabFromViewModel(int model_index) {}

Tab* TabContainerImpl::AddTabToViewModel(Tab* tab,
                                         int model_index,
                                         TabPinned pinned) {}

void TabContainerImpl::ReturnTabSlotView(TabSlotView* view) {}

void TabContainerImpl::ScrollTabToVisible(int model_index) {}

void TabContainerImpl::ScrollTabContainerByOffset(int offset) {}

void TabContainerImpl::OnGroupCreated(const tab_groups::TabGroupId& group) {}

void TabContainerImpl::OnGroupEditorOpened(
    const tab_groups::TabGroupId& group) {}

void TabContainerImpl::OnGroupContentsChanged(
    const tab_groups::TabGroupId& group) {}

void TabContainerImpl::OnGroupVisualsChanged(
    const tab_groups::TabGroupId& group,
    const tab_groups::TabGroupVisualData* old_visuals,
    const tab_groups::TabGroupVisualData* new_visuals) {}

void TabContainerImpl::OnGroupMoved(const tab_groups::TabGroupId& group) {}

void TabContainerImpl::ToggleTabGroup(
    const tab_groups::TabGroupId& group,
    bool is_collapsing,
    ToggleTabGroupCollapsedStateOrigin origin) {}

void TabContainerImpl::OnGroupClosed(const tab_groups::TabGroupId& group) {}

void TabContainerImpl::UpdateTabGroupVisuals(tab_groups::TabGroupId group_id) {}

void TabContainerImpl::NotifyTabGroupEditorBubbleOpened() {}

void TabContainerImpl::NotifyTabGroupEditorBubbleClosed() {}

// TODO(tbergquist): This should really return an optional<size_t>.
std::optional<int> TabContainerImpl::GetModelIndexOf(
    const TabSlotView* slot_view) const {}

Tab* TabContainerImpl::GetTabAtModelIndex(int index) const {}

int TabContainerImpl::GetTabCount() const {}

// TODO(tbergquist): This should really return an optional<size_t>.
std::optional<int> TabContainerImpl::GetModelIndexOfFirstNonClosingTab(
    Tab* tab) const {}

void TabContainerImpl::UpdateHoverCard(
    Tab* tab,
    TabSlotController::HoverCardUpdateType update_type) {}

void TabContainerImpl::HandleLongTap(ui::GestureEvent* event) {}

bool TabContainerImpl::IsRectInContentArea(const gfx::Rect& rect) {}

std::optional<ZOrderableTabContainerElement>
TabContainerImpl::GetLeadingElementForZOrdering() const {}

std::optional<ZOrderableTabContainerElement>
TabContainerImpl::GetTrailingElementForZOrdering() const {}

void TabContainerImpl::OnTabSlotAnimationProgressed(TabSlotView* view) {}

void TabContainerImpl::InvalidateIdealBounds() {}

void TabContainerImpl::AnimateToIdealBounds() {}

bool TabContainerImpl::IsAnimating() const {}

void TabContainerImpl::CancelAnimation() {}

void TabContainerImpl::CompleteAnimationAndLayout() {}

int TabContainerImpl::GetAvailableWidthForTabContainer() const {}

void TabContainerImpl::EnterTabClosingMode(std::optional<int> override_width,
                                           CloseTabSource source) {}

void TabContainerImpl::ExitTabClosingMode() {}

void TabContainerImpl::SetTabSlotVisibility() {}

bool TabContainerImpl::InTabClose() {}

TabGroupViews* TabContainerImpl::GetGroupViews(
    tab_groups::TabGroupId group_id) const {}

const std::map<tab_groups::TabGroupId, std::unique_ptr<TabGroupViews>>&
TabContainerImpl::get_group_views_for_testing() const {}

int TabContainerImpl::GetActiveTabWidth() const {}

int TabContainerImpl::GetInactiveTabWidth() const {}

gfx::Rect TabContainerImpl::GetIdealBounds(int model_index) const {}

gfx::Rect TabContainerImpl::GetIdealBounds(tab_groups::TabGroupId group) const {}

void TabContainerImpl::Layout(PassKey) {}

void TabContainerImpl::PaintChildren(const views::PaintInfo& paint_info) {}

gfx::Size TabContainerImpl::GetMinimumSize() const {}

gfx::Size TabContainerImpl::CalculatePreferredSize(
    const views::SizeBounds& available_size) const {}

views::View* TabContainerImpl::GetTooltipHandlerForPoint(
    const gfx::Point& point) {}

std::optional<BrowserRootView::DropIndex> TabContainerImpl::GetDropIndex(
    const ui::DropTargetEvent& event) {}

views::View* TabContainerImpl::GetViewForDrop() {}

BrowserRootView::DropTarget* TabContainerImpl::GetDropTarget(
    gfx::Point loc_in_local_coords) {}

void TabContainerImpl::HandleDragUpdate(
    const std::optional<BrowserRootView::DropIndex>& index) {}

void TabContainerImpl::HandleDragExited() {}

views::View* TabContainerImpl::TargetForRect(views::View* root,
                                             const gfx::Rect& rect) {}

void TabContainerImpl::MouseMovedOutOfHost() {}

void TabContainerImpl::OnBoundsAnimatorProgressed(
    views::BoundsAnimator* animator) {}

void TabContainerImpl::OnBoundsAnimatorDone(views::BoundsAnimator* animator) {}

// TabContainerImpl::DropArrow:
// ----------------------------------------------------------

TabContainerImpl::DropArrow::DropArrow(const BrowserRootView::DropIndex& index,
                                       bool point_down,
                                       views::Widget* context)
    :{}

TabContainerImpl::DropArrow::~DropArrow() {}

void TabContainerImpl::DropArrow::SetPointDown(bool down) {}

void TabContainerImpl::DropArrow::SetWindowBounds(const gfx::Rect& bounds) {}

void TabContainerImpl::DropArrow::OnWidgetDestroying(views::Widget* widget) {}

views::ViewModelT<Tab>* TabContainerImpl::GetTabsViewModel() {}

std::optional<gfx::Rect> TabContainerImpl::GetVisibleContentRect() {}

void TabContainerImpl::AnimateScrollToShowXCoordinate(const int start_edge,
                                                      const int target_edge) {}

void TabContainerImpl::AnimateTabSlotViewTo(TabSlotView* tab_slot_view,
                                            const gfx::Rect& target_bounds) {}

void TabContainerImpl::UpdateIdealBounds() {}

void TabContainerImpl::SnapToIdealBounds() {}

int TabContainerImpl::CalculateAvailableWidthForTabs() const {}

void TabContainerImpl::StartInsertTabAnimation(int model_index) {}

void TabContainerImpl::StartRemoveTabAnimation(Tab* tab,
                                               int former_model_index) {}

gfx::Rect TabContainerImpl::GetTargetBoundsForClosingTab(
    Tab* tab,
    int former_model_index) const {}

int TabContainerImpl::GetIdealTrailingX() const {}

std::optional<int> TabContainerImpl::GetMidAnimationTrailingX() const {}

void TabContainerImpl::CloseTabInViewModel(int index) {}

void TabContainerImpl::OnTabRemoved(Tab* tab) {}

void TabContainerImpl::OnTabCloseAnimationCompleted(Tab* tab) {}

void TabContainerImpl::UpdateClosingModeOnRemovedTab(int model_index,
                                                     bool was_active) {}

void TabContainerImpl::ResizeLayoutTabs() {}

void TabContainerImpl::ResizeLayoutTabsFromTouch() {}

void TabContainerImpl::StartResizeLayoutTabsFromTouchTimer() {}

bool TabContainerImpl::IsDragSessionActive() const {}

bool TabContainerImpl::IsDragSessionEnding() const {}

void TabContainerImpl::AddMessageLoopObserver() {}

void TabContainerImpl::RemoveMessageLoopObserver() {}

void TabContainerImpl::OrderTabSlotView(TabSlotView* slot_view) {}

bool TabContainerImpl::IsPointInTab(
    Tab* tab,
    const gfx::Point& point_in_tabstrip_coords) {}

Tab* TabContainerImpl::FindTabHitByPoint(const gfx::Point& point) {}

bool TabContainerImpl::ShouldTabBeVisible(const Tab* tab) const {}

gfx::Rect TabContainerImpl::GetDropBounds(int drop_index,
                                          bool drop_before,
                                          bool drop_in_group,
                                          bool* is_beneath) {}

void TabContainerImpl::SetDropArrow(
    const std::optional<BrowserRootView::DropIndex>& index) {}

void TabContainerImpl::UpdateAccessibleTabIndices() {}

bool TabContainerImpl::IsValidModelIndex(int model_index) const {}

BEGIN_METADATA()