Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3624)

Unified Diff: chrome/browser/ui/views/tabs/tab_strip.cc

Issue 10213011: Attempt 3 at a better touch tabstrip. There is still a bunch to do, (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove Tab::GetTouchModeMinimumSize Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/ui/views/tabs/tab_strip.h ('k') | chrome/browser/ui/views/tabs/tab_strip_controller.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/views/tabs/tab_strip.cc
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc
index 0377d6af1b292721aae728ac05fb3e25b8cbcd36..5f1fb9e1cd0b26f088eabc57fa5d3afc33d22d22 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -23,6 +23,7 @@
#include "chrome/browser/ui/views/tabs/tab.h"
#include "chrome/browser/ui/views/tabs/tab_drag_controller.h"
#include "chrome/browser/ui/views/tabs/tab_strip_controller.h"
+#include "chrome/browser/ui/views/tabs/touch_tab_strip_layout.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "grit/theme_resources_standard.h"
@@ -89,8 +90,11 @@ static inline int Round(double x) {
return static_cast<int>(floor(x + 0.5));
}
-// Max width reserved for stacked tabs along a particular edge.
-static const double kMaxEdgeStackWidth = 24;
+// Max number of stacked tabs.
+static const int kMaxStackedCount = 4;
+
+// Padding between stacked tabs.
+static const int kStackedPadding = 6;
namespace {
@@ -387,10 +391,7 @@ TabStrip::TabStrip(TabStripController* controller)
in_tab_close_(false),
animation_container_(new ui::AnimationContainer()),
attaching_dragged_tab_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(bounds_animator_(this)),
- first_visible_tab_index_(0),
- num_visible_tabs_(0),
- stacking_(TouchModeSupport::IsTouchOptimized()) {
+ ALLOW_THIS_IN_INITIALIZER_LIST(bounds_animator_(this)) {
Init();
}
@@ -429,12 +430,25 @@ void TabStrip::StopAllHighlighting() {
tab_at(i)->StopPulse();
}
-void TabStrip::AddTabAt(int model_index, const TabRendererData& data) {
+void TabStrip::AddTabAt(int model_index,
+ const TabRendererData& data,
+ bool is_active) {
BaseTab* tab = CreateTab();
tab->SetData(data);
UpdateTabsClosingMap(model_index, 1);
tabs_.Add(tab, model_index);
AddChildView(tab);
+
+ if (touch_layout_.get()) {
+ GenerateIdealBoundsForMiniTabs(NULL);
+ int add_types = 0;
+ if (data.mini)
+ add_types |= TouchTabStripLayout::kAddTypeMini;
+ if (is_active)
+ add_types |= TouchTabStripLayout::kAddTypeActive;
+ touch_layout_->AddTab(model_index, add_types, GetStartXForNormalTabs());
+ }
+
// Don't animate the first tab, it looks weird, and don't animate anything
// if the containing window isn't visible yet.
if (tab_count() > 1 && GetWidget() && GetWidget()->IsVisible())
@@ -443,10 +457,22 @@ void TabStrip::AddTabAt(int model_index, const TabRendererData& data) {
DoLayout();
}
-void TabStrip::MoveTab(int from_model_index, int to_model_index) {
+void TabStrip::MoveTab(int from_model_index,
+ int to_model_index,
+ const TabRendererData& data) {
DCHECK_GT(tabs_.view_size(), 0);
BaseTab* last_tab = tab_at(tab_count() - 1);
- tabs_.Move(from_model_index, to_model_index);
+ tab_at(from_model_index)->SetData(data);
+ if (touch_layout_.get()) {
+ tabs_.Move(from_model_index, to_model_index);
+ int mini_tab_count = 0;
+ int start_x = GenerateIdealBoundsForMiniTabs(&mini_tab_count);
+ touch_layout_->MoveTab(
+ from_model_index, to_model_index, controller_->GetActiveIndex(),
+ start_x, mini_tab_count);
+ } else {
+ tabs_.Move(from_model_index, to_model_index);
+ }
StartMoveTabAnimation();
if (TabDragController::IsAttachedTo(this) &&
(last_tab != tab_at(tab_count() - 1) || last_tab->dragging())) {
@@ -455,16 +481,21 @@ void TabStrip::MoveTab(int from_model_index, int to_model_index) {
}
void TabStrip::RemoveTabAt(int model_index) {
- if (stacking_) {
- int count = tab_count() - 1;
- if (first_visible_tab_index_ + num_visible_tabs_ > count)
- first_visible_tab_index_ = std::max(0, first_visible_tab_index_ - 1);
- }
-
- if (in_tab_close_ && model_index != GetModelCount())
+ if (touch_layout_.get()) {
+ BaseTab* tab = tab_at(model_index);
+ tab->set_closing(true);
+ int old_x = tabs_.ideal_bounds(model_index).x();
+ // We still need to paint the tab until we actually remove it. Put it in
+ // tabs_closing_map_ so we can find it.
+ RemoveTabFromViewModel(model_index);
+ touch_layout_->RemoveTab(model_index, GenerateIdealBoundsForMiniTabs(NULL),
+ old_x);
+ ScheduleRemoveTabAnimation(tab);
+ } else if (in_tab_close_ && model_index != GetModelCount()) {
StartMouseInitiatedRemoveTabAnimation(model_index);
- else
+ } else {
StartRemoveTabAnimation(model_index);
+ }
}
void TabStrip::SetTabData(int model_index, const TabRendererData& data) {
@@ -473,6 +504,11 @@ void TabStrip::SetTabData(int model_index, const TabRendererData& data) {
tab->SetData(data);
if (mini_state_changed) {
+ if (touch_layout_.get()) {
+ int mini_tab_count = 0;
+ int start_x = GenerateIdealBoundsForMiniTabs(&mini_tab_count);
+ touch_layout_->SetXAndMiniCount(start_x, mini_tab_count);
+ }
if (GetWidget() && GetWidget()->IsVisible())
StartMiniTabAnimation();
else
@@ -509,16 +545,19 @@ void TabStrip::PrepareForCloseAt(int model_index) {
void TabStrip::SetSelection(const TabStripSelectionModel& old_selection,
const TabStripSelectionModel& new_selection) {
- // Make sure the active tab is visible.
- EnsureModelIndexIsVisible(new_selection.active());
-
- // We have "tiny tabs" if the tabs are so tiny that the unselected ones are
- // a different size to the selected ones.
- bool tiny_tabs = current_unselected_width_ != current_selected_width_;
- if (!IsAnimating() && (!in_tab_close_ || tiny_tabs)) {
- DoLayout();
- } else {
+ if (touch_layout_.get()) {
+ touch_layout_->SetActiveIndex(new_selection.active());
SchedulePaint();
+ AnimateToIdealBounds();
+ } else {
+ // We have "tiny tabs" if the tabs are so tiny that the unselected ones are
+ // a different size to the selected ones.
+ bool tiny_tabs = current_unselected_width_ != current_selected_width_;
+ if (!IsAnimating() && (!in_tab_close_ || tiny_tabs)) {
+ DoLayout();
+ } else {
+ SchedulePaint();
+ }
}
TabStripSelectionModel::SelectedIndices no_longer_selected;
@@ -576,14 +615,15 @@ bool TabStrip::IsActiveDropTarget() const {
return false;
}
-bool TabStrip::IsStacking() const {
- return stacking_;
-}
-
const TabStripSelectionModel& TabStrip::GetSelectionModel() {
return controller_->GetSelectionModel();
}
+bool TabStrip::SupportsMultipleSelection() {
+ // TODO: currently only allow single selection in touch layout mode.
+ return touch_layout_.get() == NULL;
+}
+
void TabStrip::SelectTab(BaseTab* tab) {
int model_index = GetModelIndexOfBaseTab(tab);
if (IsValidModelIndex(model_index))
@@ -821,12 +861,13 @@ void TabStrip::PaintChildren(gfx::Canvas* canvas) {
std::vector<Tab*> selected_tabs;
bool is_dragging = false;
int active_tab_index = -1;
+ bool stacking = touch_layout_.get() != NULL;
PaintClosingTabs(canvas, tab_count());
for (int i = tab_count() - 1; i >= 0; --i) {
Tab* tab = tab_at(i);
- if (tab->dragging() && !stacking_) {
+ if (tab->dragging() && !stacking) {
is_dragging = true;
if (tab->IsActive()) {
active_tab = tab;
@@ -836,7 +877,7 @@ void TabStrip::PaintChildren(gfx::Canvas* canvas) {
}
} else if (!tab->IsActive()) {
if (!tab->IsSelected()) {
- if (!stacking_)
+ if (!stacking)
tab->Paint(canvas);
} else {
// TODO(scottmg): Multiple selection may be incorrect in touch mode.
@@ -850,7 +891,7 @@ void TabStrip::PaintChildren(gfx::Canvas* canvas) {
}
// Draw from the left and then the right if we're in touch mode.
- if (stacking_ && active_tab_index >= 0) {
+ if (stacking && active_tab_index >= 0) {
for (int i = 0; i < active_tab_index; ++i) {
Tab* tab = tab_at(i);
tab->Paint(canvas);
@@ -920,9 +961,8 @@ gfx::Size TabStrip::GetPreferredSize() {
// plus the new tab button. Don't base it on the actual number of tabs because
// it's undesirable to have the minimum window size change when a new tab is
// opened.
- int needed_width = Tab::GetMinimumSelectedSize().width();
- needed_width += kNewTabButtonHOffset - kTabHOffset;
- needed_width += newtab_button_bounds_.width();
+ int needed_width = Tab::GetMinimumSelectedSize().width() - kTabHOffset +
+ new_tab_button_width();
return gfx::Size(needed_width, Tab::GetMinimumUnselectedSize().height());
}
@@ -967,34 +1007,44 @@ void TabStrip::GetAccessibleState(ui::AccessibleViewState* state) {
}
views::View* TabStrip::GetEventHandlerForPoint(const gfx::Point& point) {
- // Return any view that isn't a Tab or this TabStrip immediately. We don't
- // want to interfere.
- views::View* v = View::GetEventHandlerForPoint(point);
- if (v && v != this && v->GetClassName() != Tab::kViewClassName)
- return v;
-
- // The view order doesn't match the ordering we paint in. |tabs_| contains
- // the overall order.
- for (int i = 0; i < tab_count(); ++i) {
- Tab* next_tab = i < (tab_count() - 1) ? tab_at(i + 1) : NULL;
- if (next_tab && next_tab->IsActive() && IsPointInTab(next_tab, point))
- return next_tab;
- Tab* tab = tab_at(i);
- if (IsPointInTab(tab, point))
- return tab;
+ if (!touch_layout_.get()) {
+ // Return any view that isn't a Tab or this TabStrip immediately. We don't
+ // want to interfere.
+ views::View* v = View::GetEventHandlerForPoint(point);
+ if (v && v != this && v->GetClassName() != Tab::kViewClassName)
+ return v;
+
+ // The display order doesn't necessarily match the child list order, so we
+ // walk the display list hit-testing Tabs. Since the active tab always
+ // renders on top of adjacent tabs, it needs to be hit-tested before any
+ // left-adjacent Tab, so we look ahead for it as we walk.
+ for (int i = 0; i < tab_count(); ++i) {
+ Tab* next_tab = i < (tab_count() - 1) ? tab_at(i + 1) : NULL;
+ if (next_tab && next_tab->IsActive() && IsPointInTab(next_tab, point))
+ return next_tab;
+ if (IsPointInTab(tab_at(i), point))
+ return tab_at(i);
+ }
+ } else {
+ int active_tab_index = touch_layout_->active_index();
+ if (active_tab_index != -1) {
+ Tab* tab = FindTabForEvent(point, active_tab_index, -1);
+ if (!tab)
+ tab = FindTabForEvent(point, active_tab_index + 1, 1);
+ if (tab) {
+ gfx::Point point_in_tab_coords(point);
+ View::ConvertPointToView(this, tab, &point_in_tab_coords);
+ return tab->GetEventHandlerForPoint(point_in_tab_coords);
+ }
+ }
}
-
return this;
}
int TabStrip::GetMiniTabCount() const {
int mini_count = 0;
- for (int i = 0; i < tab_count(); ++i) {
- if (tab_at(i)->data().mini)
- mini_count++;
- else
- return mini_count;
- }
+ while (mini_count < tab_count() && tab_at(mini_count)->data().mini)
+ mini_count++;
return mini_count;
}
@@ -1009,13 +1059,6 @@ void TabStrip::ButtonPressed(views::Button* sender, const views::Event& event) {
///////////////////////////////////////////////////////////////////////////////
// TabStrip, protected:
-void TabStrip::ViewHierarchyChanged(bool is_add,
- views::View* parent,
- views::View* child) {
- if (is_add && child == this)
- InitTabStripButtons();
-}
-
// Overridden to support automation. See automation_proxy_uitest.cc.
const views::View* TabStrip::GetViewByID(int view_id) const {
if (tab_count() > 0) {
@@ -1060,21 +1103,26 @@ void TabStrip::GetCurrentTabWidths(double* unselected_width,
void TabStrip::Init() {
set_id(VIEW_ID_TAB_STRIP);
newtab_button_bounds_.SetRect(0, 0, kNewTabButtonWidth, kNewTabButtonHeight);
- if (drop_indicator_width == 0) {
- // Direction doesn't matter, both images are the same size.
- SkBitmap* drop_image = GetDropArrowImage(true);
- drop_indicator_width = drop_image->width();
- drop_indicator_height = drop_image->height();
- }
-}
-
-void TabStrip::InitTabStripButtons() {
newtab_button_ = new NewTabButton(this, this);
newtab_button_->SetTooltipText(
l10n_util::GetStringUTF16(IDS_TOOLTIP_NEW_TAB));
newtab_button_->SetAccessibleName(
l10n_util::GetStringUTF16(IDS_ACCNAME_NEWTAB));
AddChildView(newtab_button_);
+ if (drop_indicator_width == 0) {
+ // Direction doesn't matter, both images are the same size.
+ SkBitmap* drop_image = GetDropArrowImage(true);
+ drop_indicator_width = drop_image->width();
+ drop_indicator_height = drop_image->height();
+ }
+ if (TouchModeSupport::IsTouchOptimized()) {
+ touch_layout_.reset(new TouchTabStripLayout(
+ Tab::GetStandardSize(),
+ kTabHOffset,
+ kStackedPadding,
+ kMaxStackedCount,
+ &tabs_));
+ }
}
BaseTab* TabStrip::CreateTab() {
@@ -1121,6 +1169,10 @@ void TabStrip::StartRemoveTabAnimation(int model_index) {
RemoveTabFromViewModel(model_index);
+ ScheduleRemoveTabAnimation(tab);
+}
+
+void TabStrip::ScheduleRemoveTabAnimation(BaseTab* tab) {
// Start an animation for the tabs.
GenerateIdealBounds();
AnimateToIdealBounds();
@@ -1157,7 +1209,7 @@ void TabStrip::StopAnimating(bool layout) {
void TabStrip::AnimateToIdealBounds() {
for (int i = 0; i < tab_count(); ++i) {
Tab* tab = tab_at(i);
- if (!tab->closing() && !tab->dragging())
+ if (!tab->dragging())
bounds_animator_.AnimateViewTo(tab, ideal_bounds(i));
}
@@ -1173,34 +1225,35 @@ void TabStrip::DoLayout() {
StopAnimating(false);
+ if (touch_layout_.get())
+ touch_layout_->SetWidth(size().width() - new_tab_button_width());
+
GenerateIdealBounds();
views::ViewModelUtils::SetViewBoundsToIdealBounds(tabs_);
SchedulePaint();
- // It is possible we don't have a new tab button yet.
- if (newtab_button_) {
- if (SizeTabButtonToTopOfTabStrip()) {
- newtab_button_bounds_.set_height(
- kNewTabButtonHeight + kNewTabButtonVOffset);
- newtab_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT,
- views::ImageButton::ALIGN_BOTTOM);
- } else {
- newtab_button_bounds_.set_height(kNewTabButtonHeight);
- newtab_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT,
- views::ImageButton::ALIGN_TOP);
- }
- newtab_button_->SetBoundsRect(newtab_button_bounds_);
+ if (SizeTabButtonToTopOfTabStrip()) {
+ newtab_button_bounds_.set_height(
+ kNewTabButtonHeight + kNewTabButtonVOffset);
+ newtab_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT,
+ views::ImageButton::ALIGN_BOTTOM);
+ } else {
+ newtab_button_bounds_.set_height(kNewTabButtonHeight);
+ newtab_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT,
+ views::ImageButton::ALIGN_TOP);
}
+ newtab_button_->SetBoundsRect(newtab_button_bounds_);
}
void TabStrip::LayoutDraggedTabsAt(const std::vector<BaseTab*>& tabs,
BaseTab* active_tab,
const gfx::Point& location,
bool initial_drag) {
- if (stacking_) {
- LayoutDraggedTabsAtWithStacking(active_tab, location);
+ if (touch_layout_.get()) {
+ touch_layout_->DragActiveTab(location.x() - active_tab->bounds().x());
+ DoLayout();
return;
}
// Immediately hide the new tab button if the last tab is being dragged.
@@ -1231,13 +1284,6 @@ void TabStrip::LayoutDraggedTabsAt(const std::vector<BaseTab*>& tabs,
}
}
-void TabStrip::LayoutDraggedTabsAtWithStacking(
- BaseTab* active_tab,
- const gfx::Point& location) {
- // TODO: this is wrong.
- active_tab->SetX(location.x());
-}
-
void TabStrip::CalculateBoundsForDraggedTabs(const std::vector<BaseTab*>& tabs,
std::vector<gfx::Rect>* bounds) {
int x = 0;
@@ -1379,8 +1425,7 @@ void TabStrip::OwnDragController(TabDragController* controller) {
}
void TabStrip::DestroyDragController() {
- if (newtab_button_)
- newtab_button_->SetVisible(true);
+ newtab_button_->SetVisible(true);
drag_controller_.reset();
}
@@ -1388,46 +1433,6 @@ TabDragController* TabStrip::ReleaseDragController() {
return drag_controller_.release();
}
-int TabStrip::NumNonClosingTabs(int index1, int index2) const {
- int count = 0;
- for (int i = index1; i < index2; ++i) {
- if (!tab_at(i)->closing())
- count++;
- }
- return count;
-}
-
-void TabStrip::UpdateNumVisibleTabs(int non_closing_tab_count,
- int width,
- double tab_size) {
- num_visible_tabs_ = (width + kTabHOffset) / (tab_size + kTabHOffset);
- num_visible_tabs_ = std::max(1, num_visible_tabs_);
- // Make sure the first_visible_tab_index_ is valid.
- // TODO: this isn't quite right, it doesn't take into account closing tabs.
- first_visible_tab_index_ =
- std::min(first_visible_tab_index_, non_closing_tab_count -
- num_visible_tabs_);
- first_visible_tab_index_ = std::max(0, first_visible_tab_index_);
-}
-
-void TabStrip::EnsureModelIndexIsVisible(int model_index) {
- if (!stacking_ || model_index == TabStripSelectionModel::kUnselectedIndex)
- return;
-
- int original = first_visible_tab_index_;
- int active_index = model_index;
- if (active_index < first_visible_tab_index_)
- first_visible_tab_index_ = active_index;
- else if (active_index >= first_visible_tab_index_ + num_visible_tabs_)
- first_visible_tab_index_ = active_index - num_visible_tabs_ + 1;
-
- if (original != first_visible_tab_index_) {
- PrepareForAnimation();
- GenerateIdealBounds();
- AnimateToIdealBounds();
- }
-}
-
void TabStrip::GetDesiredTabWidths(int tab_count,
int mini_tab_count,
double* unselected_width,
@@ -1447,8 +1452,7 @@ void TabStrip::GetDesiredTabWidths(int tab_count,
// Determine how much space we can actually allocate to tabs.
int available_width;
if (available_width_for_tabs_ < 0) {
- available_width = width();
- available_width -= (kNewTabButtonHOffset + newtab_button_bounds_.width());
+ available_width = width() - new_tab_button_width();
} else {
// Interesting corner case: if |available_width_for_tabs_| > the result
// of the calculation in the conditional arm above, the strip is in
@@ -1718,64 +1722,43 @@ void TabStrip::PrepareForAnimation() {
}
void TabStrip::GenerateIdealBounds() {
- int non_closing_tab_count = 0;
- int mini_tab_count = 0;
- for (int i = 0; i < tab_count(); ++i) {
- BaseTab* tab = tab_at(i);
- if (!tab->closing()) {
- ++non_closing_tab_count;
- if (tab->data().mini)
- mini_tab_count++;
- }
+ int new_tab_y = SizeTabButtonToTopOfTabStrip() ? 0 : kNewTabButtonVOffset;
+
+ if (touch_layout_.get()) {
+ if (tabs_.view_size() == 0)
+ return;
+
+ int new_tab_x = tabs_.ideal_bounds(tabs_.view_size() - 1).right() +
+ kNewTabButtonHOffset;
+ newtab_button_bounds_.set_origin(gfx::Point(new_tab_x, new_tab_y));
+ return;
}
double unselected, selected;
- GetDesiredTabWidths(non_closing_tab_count, mini_tab_count, &unselected,
- &selected);
-
+ GetDesiredTabWidths(tab_count(), GetMiniTabCount(), &unselected, &selected);
current_unselected_width_ = unselected;
current_selected_width_ = selected;
// NOTE: This currently assumes a tab's height doesn't differ based on
// selected state or the number of tabs in the strip!
int tab_height = Tab::GetStandardSize().height();
- double tab_x = 0;
- bool last_was_mini = false;
- for (int i = 0; i < tab_count(); ++i) {
+ int first_non_mini_index = 0;
+ double tab_x = GenerateIdealBoundsForMiniTabs(&first_non_mini_index);
+ for (int i = first_non_mini_index; i < tab_count(); ++i) {
Tab* tab = tab_at(i);
- if (!tab->closing()) {
- double tab_width = unselected;
- if (tab->data().mini) {
- tab_width = Tab::GetMiniWidth();
- } else {
- if (last_was_mini) {
- // Give a bigger gap between mini and non-mini tabs.
- tab_x += kMiniToNonMiniGap;
- }
- if (tab->IsActive())
- tab_width = selected;
- }
- double end_of_tab = tab_x + tab_width;
- int rounded_tab_x = Round(tab_x);
- set_ideal_bounds(i,
- gfx::Rect(rounded_tab_x, 0, Round(end_of_tab) - rounded_tab_x,
- tab_height));
- tab_x = end_of_tab + kTabHOffset;
- last_was_mini = tab->data().mini;
- }
- }
-
- // If we're in stacking mode, update the positions now that we have
- // appropriate widths.
- if (stacking_ && tab_x - kTabHOffset >
- width() - newtab_button_bounds_.width()) {
- tab_x = GenerateIdealBoundsWithStacking(
- mini_tab_count, non_closing_tab_count, tab_x, selected);
+ DCHECK(!tab->data().mini);
+ double tab_width = tab->IsActive() ? selected : unselected;
+ double end_of_tab = tab_x + tab_width;
+ int rounded_tab_x = Round(tab_x);
+ set_ideal_bounds(
+ i,
+ gfx::Rect(rounded_tab_x, 0, Round(end_of_tab) - rounded_tab_x,
+ tab_height));
+ tab_x = end_of_tab + kTabHOffset;
}
// Update bounds of new tab button.
int new_tab_x;
- int new_tab_y = SizeTabButtonToTopOfTabStrip() ? 0 : kNewTabButtonVOffset;
if (abs(Round(unselected) - Tab::GetStandardSize().width()) > 1 &&
!in_tab_close_) {
// We're shrinking tabs, so we need to anchor the New Tab button to the
@@ -1788,104 +1771,25 @@ void TabStrip::GenerateIdealBounds() {
newtab_button_bounds_.set_origin(gfx::Point(new_tab_x, new_tab_y));
}
-double TabStrip::GenerateIdealBoundsWithStacking(int mini_tab_count,
- int non_closing_tab_count,
- double new_tab_x,
- double selected_size) {
- if (non_closing_tab_count == mini_tab_count)
- return new_tab_x;
-
- // Pinned tabs always have their desired size, and don't stack. We rely on
- // GenerateIdealBounds to have positioned pinned tabs already, so don't move
- // them.
- int tab_index = 0;
- double next_x = 0;
- for (; tab_index < tab_count(); ++tab_index) {
- BaseTab* tab = tab_at(tab_index);
- if (!tab->closing() && !tab->data().mini) {
- next_x = ideal_bounds(tab_index).x();
- break;
- }
- }
- if (tab_index == tab_count())
- return new_tab_x;
-
- // Always reserve kMaxEdgeStackWidth on each side for stacking. We don't
- // later try to adjust as it can lead to tabs bouncing around.
- int available_width = width() -
- (kNewTabButtonHOffset + newtab_button_bounds_.width()) - next_x -
- 2 * kMaxEdgeStackWidth;
- if (available_width <= 0)
- return new_tab_x;
- UpdateNumVisibleTabs(non_closing_tab_count, available_width, selected_size);
- int stacked_leading_index = tab_index;
- int stacked_trailing_index = first_visible_tab_index_;
- for (int visible_count = 0;
- stacked_trailing_index < tab_count() &&
- visible_count < num_visible_tabs_; ++stacked_trailing_index) {
- if (!tab_at(stacked_trailing_index)->closing())
- visible_count++;
- }
- int stacked_leading_count =
- NumNonClosingTabs(stacked_leading_index, first_visible_tab_index_);
- int stacked_trailing_count =
- NumNonClosingTabs(stacked_trailing_index, tab_count());
-
- // Stacked tabs to the left.
- if (stacked_leading_count > 0) {
- double stacked_offset =
- kMaxEdgeStackWidth / static_cast<double>(stacked_leading_count);
- for (; tab_index < first_visible_tab_index_; ++tab_index) {
- if (tab_at(tab_index)->closing())
- continue;
- gfx::Rect bounds = ideal_bounds(tab_index);
- bounds.set_x(next_x);
- set_ideal_bounds(tab_index, bounds);
- next_x += stacked_offset;
- }
- } else {
- tab_index = first_visible_tab_index_;
- }
-
- if (stacked_leading_count > 0 && stacked_trailing_count == 0) {
- // If there are no stacked tabs on the right and there is extra space, give
- // it to the last stacked tab on the left.
- next_x += available_width + kMaxEdgeStackWidth -
- (num_visible_tabs_ * selected_size +
- std::max(num_visible_tabs_ - 1, 0) * kTabHOffset);
- }
-
- // Totally visible tabs.
- for (int visible_count = 0;
- tab_index < tab_count() && visible_count < num_visible_tabs_;
- tab_index++) {
- if (tab_at(tab_index)->closing())
- continue;
- gfx::Rect bounds = ideal_bounds(tab_index);
- bounds.set_x(next_x);
- next_x = bounds.right() + kTabHOffset;
- set_ideal_bounds(tab_index, bounds);
- visible_count++;
- }
-
- // Stacked tabs to the right.
- if (stacked_trailing_count == 0)
- return next_x;
-
- double stacked_offset =
- kMaxEdgeStackWidth / static_cast<double>(stacked_trailing_count);
- next_x = width() - (kNewTabButtonHOffset + newtab_button_bounds_.width()) -
- (stacked_trailing_count - 1) * stacked_offset - selected_size;
- for (; tab_index < tab_count(); ++tab_index) {
- if (tab_at(tab_index)->closing())
- continue;
- gfx::Rect bounds = ideal_bounds(tab_index);
- bounds.set_x(next_x);
- set_ideal_bounds(tab_index, bounds);
- next_x += stacked_offset;
+int TabStrip::GenerateIdealBoundsForMiniTabs(int* first_non_mini_index) {
+ int next_x = 0;
+ int mini_width = Tab::GetMiniWidth();
+ int tab_height = Tab::GetStandardSize().height();
+ int index = 0;
+ for (; index < tab_count() && tab_at(index)->data().mini; ++index) {
+ set_ideal_bounds(index,
+ gfx::Rect(next_x, 0, mini_width, tab_height));
+ next_x += mini_width + kTabHOffset;
}
+ if (index > 0 && index < tab_count())
+ next_x += kMiniToNonMiniGap;
+ if (first_non_mini_index)
+ *first_non_mini_index = index;
+ return next_x;
+}
- return next_x + kTabHOffset;
+int TabStrip::new_tab_button_width() const {
+ return kNewTabButtonWidth + kNewTabButtonHOffset;
}
void TabStrip::StartResizeLayoutAnimation() {
@@ -1953,3 +1857,19 @@ bool TabStrip::IsPointInTab(Tab* tab,
View::ConvertPointToView(this, tab, &point_in_tab_coords);
return tab->HitTest(point_in_tab_coords);
}
+
+int TabStrip::GetStartXForNormalTabs() const {
+ int mini_tab_count = GetMiniTabCount();
+ if (mini_tab_count == 0)
+ return 0;
+ return mini_tab_count * (Tab::GetMiniWidth() + kTabHOffset) +
+ kMiniToNonMiniGap;
+}
+
+Tab* TabStrip::FindTabForEvent(const gfx::Point& point, int start, int delta) {
+ for (int i = start; i >= 0 && i < tab_count(); i += delta) {
+ if (IsPointInTab(tab_at(i), point))
+ return tab_at(i);
+ }
+ return NULL;
+}
« no previous file with comments | « chrome/browser/ui/views/tabs/tab_strip.h ('k') | chrome/browser/ui/views/tabs/tab_strip_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698