Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/views/tabs/tab_strip.h" | 5 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 12 #include "base/stl_util-inl.h" | 12 #include "base/stl_util-inl.h" |
| 13 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
| 14 #include "chrome/browser/defaults.h" | |
| 15 #include "chrome/browser/tabs/tab_strip_selection_model.h" | 14 #include "chrome/browser/tabs/tab_strip_selection_model.h" |
| 16 #include "chrome/browser/themes/theme_service.h" | 15 #include "chrome/browser/themes/theme_service.h" |
| 17 #include "chrome/browser/ui/view_ids.h" | 16 #include "chrome/browser/ui/view_ids.h" |
| 18 #include "chrome/browser/ui/views/tabs/tab.h" | 17 #include "chrome/browser/ui/views/tabs/tab.h" |
| 19 #include "chrome/browser/ui/views/tabs/tab_strip_controller.h" | 18 #include "chrome/browser/ui/views/tabs/tab_strip_controller.h" |
| 20 #include "grit/generated_resources.h" | 19 #include "grit/generated_resources.h" |
| 21 #include "grit/theme_resources.h" | 20 #include "grit/theme_resources.h" |
| 22 #include "grit/theme_resources_standard.h" | 21 #include "grit/theme_resources_standard.h" |
| 23 #include "ui/base/accessibility/accessible_view_state.h" | 22 #include "ui/base/accessibility/accessible_view_state.h" |
| 24 #include "ui/base/animation/animation_container.h" | 23 #include "ui/base/animation/animation_container.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 70 | 69 |
| 71 namespace { | 70 namespace { |
| 72 | 71 |
| 73 /////////////////////////////////////////////////////////////////////////////// | 72 /////////////////////////////////////////////////////////////////////////////// |
| 74 // NewTabButton | 73 // NewTabButton |
| 75 // | 74 // |
| 76 // A subclass of button that hit-tests to the shape of the new tab button. | 75 // A subclass of button that hit-tests to the shape of the new tab button. |
| 77 | 76 |
| 78 class NewTabButton : public views::ImageButton { | 77 class NewTabButton : public views::ImageButton { |
| 79 public: | 78 public: |
| 80 explicit NewTabButton(views::ButtonListener* listener) | 79 explicit NewTabButton(TabStrip* tab_strip, views::ButtonListener* listener) |
| 81 : views::ImageButton(listener) { | 80 : views::ImageButton(listener), tab_strip_(tab_strip) { |
|
sky
2011/07/14 20:38:20
When you can't fit all the initializers on a singl
Roger Tawa OOO till Jul 10th
2011/07/14 21:09:28
Done.
| |
| 82 } | 81 } |
| 83 virtual ~NewTabButton() {} | 82 virtual ~NewTabButton() {} |
| 84 | 83 |
| 85 protected: | 84 protected: |
| 86 // Overridden from views::View: | 85 // Overridden from views::View: |
| 87 virtual bool HasHitTestMask() const { | 86 virtual bool HasHitTestMask() const { |
| 88 // When the button is sized to the top of the tab strip we want the user to | 87 // When the button is sized to the top of the tab strip we want the user to |
| 89 // be able to click on complete bounds, and so don't return a custom hit | 88 // be able to click on complete bounds, and so don't return a custom hit |
| 90 // mask. | 89 // mask. |
| 91 return !browser_defaults::kSizeTabButtonToTopOfTabStrip; | 90 return !tab_strip_->SizeTabButtonToTopOfTabStrip(); |
| 92 } | 91 } |
| 93 virtual void GetHitTestMask(gfx::Path* path) const { | 92 virtual void GetHitTestMask(gfx::Path* path) const { |
| 94 DCHECK(path); | 93 DCHECK(path); |
| 95 | 94 |
| 96 SkScalar w = SkIntToScalar(width()); | 95 SkScalar w = SkIntToScalar(width()); |
| 97 | 96 |
| 98 // These values are defined by the shape of the new tab bitmap. Should that | 97 // These values are defined by the shape of the new tab bitmap. Should that |
| 99 // bitmap ever change, these values will need to be updated. They're so | 98 // bitmap ever change, these values will need to be updated. They're so |
| 100 // custom it's not really worth defining constants for. | 99 // custom it's not really worth defining constants for. |
| 101 path->moveTo(0, 1); | 100 path->moveTo(0, 1); |
| 102 path->lineTo(w - 7, 1); | 101 path->lineTo(w - 7, 1); |
| 103 path->lineTo(w - 4, 4); | 102 path->lineTo(w - 4, 4); |
| 104 path->lineTo(w, 16); | 103 path->lineTo(w, 16); |
| 105 path->lineTo(w - 1, 17); | 104 path->lineTo(w - 1, 17); |
| 106 path->lineTo(7, 17); | 105 path->lineTo(7, 17); |
| 107 path->lineTo(4, 13); | 106 path->lineTo(4, 13); |
| 108 path->lineTo(0, 1); | 107 path->lineTo(0, 1); |
| 109 path->close(); | 108 path->close(); |
| 110 } | 109 } |
| 111 | 110 |
| 112 private: | 111 private: |
| 112 // Tab strip that contains this button. | |
| 113 TabStrip* tab_strip_; | |
| 114 | |
| 113 DISALLOW_COPY_AND_ASSIGN(NewTabButton); | 115 DISALLOW_COPY_AND_ASSIGN(NewTabButton); |
| 114 }; | 116 }; |
| 115 | 117 |
| 116 } // namespace | 118 } // namespace |
| 117 | 119 |
| 118 /////////////////////////////////////////////////////////////////////////////// | 120 /////////////////////////////////////////////////////////////////////////////// |
| 119 // TabStrip, public: | 121 // TabStrip, public: |
| 120 | 122 |
| 121 // static | 123 // static |
| 122 const int TabStrip::mini_to_non_mini_gap_ = 3; | 124 const int TabStrip::mini_to_non_mini_gap_ = 3; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 143 // crash in the case where the user closes the window after closing a tab | 145 // crash in the case where the user closes the window after closing a tab |
| 144 // but before moving the mouse. | 146 // but before moving the mouse. |
| 145 RemoveMessageLoopObserver(); | 147 RemoveMessageLoopObserver(); |
| 146 | 148 |
| 147 // The children (tabs) may callback to us from their destructor. Delete them | 149 // The children (tabs) may callback to us from their destructor. Delete them |
| 148 // so that if they call back we aren't in a weird state. | 150 // so that if they call back we aren't in a weird state. |
| 149 RemoveAllChildViews(true); | 151 RemoveAllChildViews(true); |
| 150 } | 152 } |
| 151 | 153 |
| 152 void TabStrip::InitTabStripButtons() { | 154 void TabStrip::InitTabStripButtons() { |
| 153 newtab_button_ = new NewTabButton(this); | 155 newtab_button_ = new NewTabButton(this, this); |
| 154 if (browser_defaults::kSizeTabButtonToTopOfTabStrip) { | |
| 155 newtab_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, | |
| 156 views::ImageButton::ALIGN_BOTTOM); | |
| 157 } | |
| 158 LoadNewTabButtonImage(); | 156 LoadNewTabButtonImage(); |
| 159 newtab_button_->SetAccessibleName( | 157 newtab_button_->SetAccessibleName( |
| 160 l10n_util::GetStringUTF16(IDS_ACCNAME_NEWTAB)); | 158 l10n_util::GetStringUTF16(IDS_ACCNAME_NEWTAB)); |
| 161 AddChildView(newtab_button_); | 159 AddChildView(newtab_button_); |
| 162 } | 160 } |
| 163 | 161 |
| 164 gfx::Rect TabStrip::GetNewTabButtonBounds() { | 162 gfx::Rect TabStrip::GetNewTabButtonBounds() { |
| 165 return newtab_button_->bounds(); | 163 return newtab_button_->bounds(); |
| 166 } | 164 } |
| 167 | 165 |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 474 } | 472 } |
| 475 | 473 |
| 476 bool TabStrip::ShouldHighlightCloseButtonAfterRemove() { | 474 bool TabStrip::ShouldHighlightCloseButtonAfterRemove() { |
| 477 return in_tab_close_; | 475 return in_tab_close_; |
| 478 } | 476 } |
| 479 | 477 |
| 480 void TabStrip::DoLayout() { | 478 void TabStrip::DoLayout() { |
| 481 BaseTabStrip::DoLayout(); | 479 BaseTabStrip::DoLayout(); |
| 482 | 480 |
| 483 // It is possible we don't have a new tab button yet. | 481 // It is possible we don't have a new tab button yet. |
| 484 if (newtab_button_) | 482 if (newtab_button_) { |
| 483 if (SizeTabButtonToTopOfTabStrip()) { | |
| 484 newtab_button_bounds_.set_height( | |
| 485 kNewTabButtonHeight + kNewTabButtonVOffset); | |
| 486 newtab_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, | |
| 487 views::ImageButton::ALIGN_BOTTOM); | |
| 488 } else { | |
| 489 newtab_button_bounds_.set_height(kNewTabButtonHeight); | |
| 490 newtab_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, | |
| 491 views::ImageButton::ALIGN_TOP); | |
| 492 } | |
| 485 newtab_button_->SetBoundsRect(newtab_button_bounds_); | 493 newtab_button_->SetBoundsRect(newtab_button_bounds_); |
| 494 } | |
| 486 } | 495 } |
| 487 | 496 |
| 488 void TabStrip::LayoutDraggedTabsAt(const std::vector<BaseTab*>& tabs, | 497 void TabStrip::LayoutDraggedTabsAt(const std::vector<BaseTab*>& tabs, |
| 489 BaseTab* active_tab, | 498 BaseTab* active_tab, |
| 490 const gfx::Point& location, | 499 const gfx::Point& location, |
| 491 bool initial_drag) { | 500 bool initial_drag) { |
| 492 std::vector<gfx::Rect> bounds; | 501 std::vector<gfx::Rect> bounds; |
| 493 CalculateBoundsForDraggedTabs(tabs, &bounds); | 502 CalculateBoundsForDraggedTabs(tabs, &bounds); |
| 494 DCHECK_EQ(tabs.size(), bounds.size()); | 503 DCHECK_EQ(tabs.size(), bounds.size()); |
| 495 int active_tab_model_index = GetModelIndexOfBaseTab(active_tab); | 504 int active_tab_model_index = GetModelIndexOfBaseTab(active_tab); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 555 if (sender == newtab_button_) | 564 if (sender == newtab_button_) |
| 556 controller()->CreateNewTab(); | 565 controller()->CreateNewTab(); |
| 557 } | 566 } |
| 558 | 567 |
| 559 /////////////////////////////////////////////////////////////////////////////// | 568 /////////////////////////////////////////////////////////////////////////////// |
| 560 // TabStrip, private: | 569 // TabStrip, private: |
| 561 | 570 |
| 562 void TabStrip::Init() { | 571 void TabStrip::Init() { |
| 563 set_id(VIEW_ID_TAB_STRIP); | 572 set_id(VIEW_ID_TAB_STRIP); |
| 564 newtab_button_bounds_.SetRect(0, 0, kNewTabButtonWidth, kNewTabButtonHeight); | 573 newtab_button_bounds_.SetRect(0, 0, kNewTabButtonWidth, kNewTabButtonHeight); |
| 565 if (browser_defaults::kSizeTabButtonToTopOfTabStrip) { | |
| 566 newtab_button_bounds_.set_height( | |
| 567 kNewTabButtonHeight + kNewTabButtonVOffset); | |
| 568 } | |
| 569 if (drop_indicator_width == 0) { | 574 if (drop_indicator_width == 0) { |
| 570 // Direction doesn't matter, both images are the same size. | 575 // Direction doesn't matter, both images are the same size. |
| 571 SkBitmap* drop_image = GetDropArrowImage(true); | 576 SkBitmap* drop_image = GetDropArrowImage(true); |
| 572 drop_indicator_width = drop_image->width(); | 577 drop_indicator_width = drop_image->width(); |
| 573 drop_indicator_height = drop_image->height(); | 578 drop_indicator_height = drop_image->height(); |
| 574 } | 579 } |
| 575 } | 580 } |
| 576 | 581 |
| 582 bool TabStrip::SizeTabButtonToTopOfTabStrip() { | |
|
sky
2011/07/14 20:38:20
Make position match position in header.
Roger Tawa OOO till Jul 10th
2011/07/14 21:09:28
Done.
| |
| 583 return controller()->SizeTabButtonToTopOfTabStrip(); | |
| 584 } | |
| 585 | |
| 577 void TabStrip::LoadNewTabButtonImage() { | 586 void TabStrip::LoadNewTabButtonImage() { |
| 578 ui::ThemeProvider* tp = GetThemeProvider(); | 587 ui::ThemeProvider* tp = GetThemeProvider(); |
| 579 | 588 |
| 580 // If we don't have a theme provider yet, it means we do not have a | 589 // If we don't have a theme provider yet, it means we do not have a |
| 581 // root view, and are therefore in a test. | 590 // root view, and are therefore in a test. |
| 582 bool in_test = false; | 591 bool in_test = false; |
| 583 if (tp == NULL) { | 592 if (tp == NULL) { |
| 584 tp = new views::DefaultThemeProvider(); | 593 tp = new views::DefaultThemeProvider(); |
| 585 in_test = true; | 594 in_test = true; |
| 586 } | 595 } |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 931 set_ideal_bounds(i, | 940 set_ideal_bounds(i, |
| 932 gfx::Rect(rounded_tab_x, 0, Round(end_of_tab) - rounded_tab_x, | 941 gfx::Rect(rounded_tab_x, 0, Round(end_of_tab) - rounded_tab_x, |
| 933 tab_height)); | 942 tab_height)); |
| 934 tab_x = end_of_tab + kTabHOffset; | 943 tab_x = end_of_tab + kTabHOffset; |
| 935 last_was_mini = tab->data().mini; | 944 last_was_mini = tab->data().mini; |
| 936 } | 945 } |
| 937 } | 946 } |
| 938 | 947 |
| 939 // Update bounds of new tab button. | 948 // Update bounds of new tab button. |
| 940 int new_tab_x; | 949 int new_tab_x; |
| 941 int new_tab_y = browser_defaults::kSizeTabButtonToTopOfTabStrip ? | 950 int new_tab_y = SizeTabButtonToTopOfTabStrip() ? 0 : kNewTabButtonVOffset; |
| 942 0 : kNewTabButtonVOffset; | |
| 943 if (abs(Round(unselected) - Tab::GetStandardSize().width()) > 1 && | 951 if (abs(Round(unselected) - Tab::GetStandardSize().width()) > 1 && |
| 944 !in_tab_close_) { | 952 !in_tab_close_) { |
| 945 // We're shrinking tabs, so we need to anchor the New Tab button to the | 953 // We're shrinking tabs, so we need to anchor the New Tab button to the |
| 946 // right edge of the TabStrip's bounds, rather than the right edge of the | 954 // right edge of the TabStrip's bounds, rather than the right edge of the |
| 947 // right-most Tab, otherwise it'll bounce when animating. | 955 // right-most Tab, otherwise it'll bounce when animating. |
| 948 new_tab_x = width() - newtab_button_bounds_.width(); | 956 new_tab_x = width() - newtab_button_bounds_.width(); |
| 949 } else { | 957 } else { |
| 950 new_tab_x = Round(tab_x - kTabHOffset) + kNewTabButtonHOffset; | 958 new_tab_x = Round(tab_x - kTabHOffset) + kNewTabButtonHOffset; |
| 951 } | 959 } |
| 952 newtab_button_bounds_.set_origin(gfx::Point(new_tab_x, new_tab_y)); | 960 newtab_button_bounds_.set_origin(gfx::Point(new_tab_x, new_tab_y)); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1026 } | 1034 } |
| 1027 return mini_count; | 1035 return mini_count; |
| 1028 } | 1036 } |
| 1029 | 1037 |
| 1030 bool TabStrip::IsPointInTab(Tab* tab, | 1038 bool TabStrip::IsPointInTab(Tab* tab, |
| 1031 const gfx::Point& point_in_tabstrip_coords) { | 1039 const gfx::Point& point_in_tabstrip_coords) { |
| 1032 gfx::Point point_in_tab_coords(point_in_tabstrip_coords); | 1040 gfx::Point point_in_tab_coords(point_in_tabstrip_coords); |
| 1033 View::ConvertPointToView(this, tab, &point_in_tab_coords); | 1041 View::ConvertPointToView(this, tab, &point_in_tab_coords); |
| 1034 return tab->HitTest(point_in_tab_coords); | 1042 return tab->HitTest(point_in_tab_coords); |
| 1035 } | 1043 } |
| OLD | NEW |