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 |