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/gtk/tabs/tab_strip_gtk.h" | 5 #include "chrome/browser/ui/gtk/tabs/tab_strip_gtk.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/i18n/rtl.h" | 9 #include "base/i18n/rtl.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
12 #include "chrome/browser/autocomplete/autocomplete.h" | 12 #include "chrome/browser/autocomplete/autocomplete.h" |
13 #include "chrome/browser/autocomplete/autocomplete_classifier.h" | 13 #include "chrome/browser/autocomplete/autocomplete_classifier.h" |
14 #include "chrome/browser/autocomplete/autocomplete_match.h" | 14 #include "chrome/browser/autocomplete/autocomplete_match.h" |
15 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/browser/tabs/tab_strip_model_delegate.h" | 16 #include "chrome/browser/tabs/tab_strip_model_delegate.h" |
17 #include "chrome/browser/themes/theme_service.h" | 17 #include "chrome/browser/themes/theme_service.h" |
18 #include "chrome/browser/ui/browser.h" | 18 #include "chrome/browser/ui/browser.h" |
19 #include "chrome/browser/ui/browser_navigator.h" | 19 #include "chrome/browser/ui/browser_navigator.h" |
20 #include "chrome/browser/ui/gtk/browser_window_gtk.h" | 20 #include "chrome/browser/ui/gtk/browser_window_gtk.h" |
21 #include "chrome/browser/ui/gtk/custom_button.h" | 21 #include "chrome/browser/ui/gtk/custom_button.h" |
22 #include "chrome/browser/ui/gtk/gtk_theme_service.h" | 22 #include "chrome/browser/ui/gtk/gtk_theme_service.h" |
23 #include "chrome/browser/ui/gtk/gtk_util.h" | 23 #include "chrome/browser/ui/gtk/gtk_util.h" |
24 #include "chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.h" | 24 #include "chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.h" |
| 25 #include "chrome/browser/ui/gtk/tabs/tab_strip_menu_controller.h" |
25 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 26 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
26 #include "content/browser/tab_contents/tab_contents.h" | 27 #include "content/browser/tab_contents/tab_contents.h" |
27 #include "content/common/notification_service.h" | 28 #include "content/common/notification_service.h" |
28 #include "content/common/notification_type.h" | 29 #include "content/common/notification_type.h" |
29 #include "grit/app_resources.h" | 30 #include "grit/app_resources.h" |
30 #include "grit/theme_resources.h" | 31 #include "grit/theme_resources.h" |
31 #include "grit/theme_resources_standard.h" | 32 #include "grit/theme_resources_standard.h" |
32 #include "ui/base/animation/animation_delegate.h" | 33 #include "ui/base/animation/animation_delegate.h" |
33 #include "ui/base/animation/slide_animation.h" | 34 #include "ui/base/animation/slide_animation.h" |
34 #include "ui/base/dragdrop/gtk_dnd_util.h" | 35 #include "ui/base/dragdrop/gtk_dnd_util.h" |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 static double GetCurrentTabWidth(TabStripGtk* tabstrip, | 162 static double GetCurrentTabWidth(TabStripGtk* tabstrip, |
162 TabStripGtk::TabAnimation* animation, | 163 TabStripGtk::TabAnimation* animation, |
163 int index) { | 164 int index) { |
164 TabGtk* tab = tabstrip->GetTabAt(index); | 165 TabGtk* tab = tabstrip->GetTabAt(index); |
165 double tab_width; | 166 double tab_width; |
166 if (tab->mini()) { | 167 if (tab->mini()) { |
167 tab_width = TabGtk::GetMiniWidth(); | 168 tab_width = TabGtk::GetMiniWidth(); |
168 } else { | 169 } else { |
169 double unselected, selected; | 170 double unselected, selected; |
170 tabstrip->GetCurrentTabWidths(&unselected, &selected); | 171 tabstrip->GetCurrentTabWidths(&unselected, &selected); |
171 tab_width = tab->IsSelected() ? selected : unselected; | 172 tab_width = tab->IsActive() ? selected : unselected; |
172 } | 173 } |
173 | 174 |
174 if (animation) { | 175 if (animation) { |
175 double specified_tab_width = animation->GetWidthForTab(index); | 176 double specified_tab_width = animation->GetWidthForTab(index); |
176 if (specified_tab_width != -1) | 177 if (specified_tab_width != -1) |
177 tab_width = specified_tab_width; | 178 tab_width = specified_tab_width; |
178 } | 179 } |
179 | 180 |
180 return tab_width; | 181 return tab_width; |
181 } | 182 } |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 double delta = target_width - start_width; | 296 double delta = target_width - start_width; |
296 if (delta > 0) | 297 if (delta > 0) |
297 return start_width + (delta * animation_.GetCurrentValue()); | 298 return start_width + (delta * animation_.GetCurrentValue()); |
298 | 299 |
299 return start_width; | 300 return start_width; |
300 } | 301 } |
301 | 302 |
302 if (tabstrip_->GetTabAt(index)->mini()) | 303 if (tabstrip_->GetTabAt(index)->mini()) |
303 return TabGtk::GetMiniWidth(); | 304 return TabGtk::GetMiniWidth(); |
304 | 305 |
305 if (tabstrip_->GetTabAt(index)->IsSelected()) { | 306 if (tabstrip_->GetTabAt(index)->IsActive()) { |
306 double delta = end_selected_width_ - start_selected_width_; | 307 double delta = end_selected_width_ - start_selected_width_; |
307 return start_selected_width_ + (delta * animation_.GetCurrentValue()); | 308 return start_selected_width_ + (delta * animation_.GetCurrentValue()); |
308 } | 309 } |
309 | 310 |
310 double delta = end_unselected_width_ - start_unselected_width_; | 311 double delta = end_unselected_width_ - start_unselected_width_; |
311 return start_unselected_width_ + (delta * animation_.GetCurrentValue()); | 312 return start_unselected_width_ + (delta * animation_.GetCurrentValue()); |
312 } | 313 } |
313 | 314 |
314 private: | 315 private: |
315 int index_; | 316 int index_; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 if (tab->mini()) | 377 if (tab->mini()) |
377 return TabGtk::GetMiniWidth(); | 378 return TabGtk::GetMiniWidth(); |
378 | 379 |
379 if (tabstrip_->available_width_for_tabs_ != -1 && | 380 if (tabstrip_->available_width_for_tabs_ != -1 && |
380 index_ != tabstrip_->GetTabCount() - 1) { | 381 index_ != tabstrip_->GetTabCount() - 1) { |
381 return TabStripGtk::TabAnimation::GetWidthForTab(index); | 382 return TabStripGtk::TabAnimation::GetWidthForTab(index); |
382 } | 383 } |
383 | 384 |
384 // All other tabs are sized according to the start/end widths specified at | 385 // All other tabs are sized according to the start/end widths specified at |
385 // the start of the animation. | 386 // the start of the animation. |
386 if (tab->IsSelected()) { | 387 if (tab->IsActive()) { |
387 double delta = end_selected_width_ - start_selected_width_; | 388 double delta = end_selected_width_ - start_selected_width_; |
388 return start_selected_width_ + (delta * animation_.GetCurrentValue()); | 389 return start_selected_width_ + (delta * animation_.GetCurrentValue()); |
389 } | 390 } |
390 | 391 |
391 double delta = end_unselected_width_ - start_unselected_width_; | 392 double delta = end_unselected_width_ - start_unselected_width_; |
392 return start_unselected_width_ + (delta * animation_.GetCurrentValue()); | 393 return start_unselected_width_ + (delta * animation_.GetCurrentValue()); |
393 } | 394 } |
394 | 395 |
395 virtual void AnimationEnded(const ui::Animation* animation) { | 396 virtual void AnimationEnded(const ui::Animation* animation) { |
396 tabstrip_->RemoveTabAt(index_); | 397 tabstrip_->RemoveTabAt(index_); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 virtual int GetDuration() const { | 485 virtual int GetDuration() const { |
485 return kResizeLayoutAnimationDurationMs; | 486 return kResizeLayoutAnimationDurationMs; |
486 } | 487 } |
487 | 488 |
488 virtual double GetWidthForTab(int index) const { | 489 virtual double GetWidthForTab(int index) const { |
489 TabGtk* tab = tabstrip_->GetTabAt(index); | 490 TabGtk* tab = tabstrip_->GetTabAt(index); |
490 | 491 |
491 if (tab->mini()) | 492 if (tab->mini()) |
492 return TabGtk::GetMiniWidth(); | 493 return TabGtk::GetMiniWidth(); |
493 | 494 |
494 if (tab->IsSelected()) { | 495 if (tab->IsActive()) { |
495 return animation_.CurrentValueBetween(start_selected_width_, | 496 return animation_.CurrentValueBetween(start_selected_width_, |
496 end_selected_width_); | 497 end_selected_width_); |
497 } | 498 } |
498 | 499 |
499 return animation_.CurrentValueBetween(start_unselected_width_, | 500 return animation_.CurrentValueBetween(start_unselected_width_, |
500 end_unselected_width_); | 501 end_unselected_width_); |
501 } | 502 } |
502 | 503 |
503 private: | 504 private: |
504 // We need to start from the current widths of the Tabs as they were last | 505 // We need to start from the current widths of the Tabs as they were last |
505 // laid out, _not_ the last known good state, which is what'll be done if we | 506 // laid out, _not_ the last known good state, which is what'll be done if we |
506 // don't measure the Tab sizes here and just go with the default TabAnimation | 507 // don't measure the Tab sizes here and just go with the default TabAnimation |
507 // behavior... | 508 // behavior... |
508 void InitStartState() { | 509 void InitStartState() { |
509 for (int i = 0; i < tabstrip_->GetTabCount(); ++i) { | 510 for (int i = 0; i < tabstrip_->GetTabCount(); ++i) { |
510 TabGtk* current_tab = tabstrip_->GetTabAt(i); | 511 TabGtk* current_tab = tabstrip_->GetTabAt(i); |
511 if (!current_tab->mini()) { | 512 if (!current_tab->mini()) { |
512 if (current_tab->IsSelected()) { | 513 if (current_tab->IsActive()) { |
513 start_selected_width_ = current_tab->width(); | 514 start_selected_width_ = current_tab->width(); |
514 } else { | 515 } else { |
515 start_unselected_width_ = current_tab->width(); | 516 start_unselected_width_ = current_tab->width(); |
516 } | 517 } |
517 } | 518 } |
518 } | 519 } |
519 } | 520 } |
520 | 521 |
521 DISALLOW_COPY_AND_ASSIGN(ResizeLayoutAnimation); | 522 DISALLOW_COPY_AND_ASSIGN(ResizeLayoutAnimation); |
522 }; | 523 }; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 static_cast<double>(TabGtk::GetMiniWidth())); | 557 static_cast<double>(TabGtk::GetMiniWidth())); |
557 } else { | 558 } else { |
558 return animation_.CurrentValueBetween( | 559 return animation_.CurrentValueBetween( |
559 static_cast<double>(TabGtk::GetMiniWidth()), | 560 static_cast<double>(TabGtk::GetMiniWidth()), |
560 end_selected_width_); | 561 end_selected_width_); |
561 } | 562 } |
562 } else if (tab->mini()) { | 563 } else if (tab->mini()) { |
563 return TabGtk::GetMiniWidth(); | 564 return TabGtk::GetMiniWidth(); |
564 } | 565 } |
565 | 566 |
566 if (tab->IsSelected()) { | 567 if (tab->IsActive()) { |
567 return animation_.CurrentValueBetween(start_selected_width_, | 568 return animation_.CurrentValueBetween(start_selected_width_, |
568 end_selected_width_); | 569 end_selected_width_); |
569 } | 570 } |
570 | 571 |
571 return animation_.CurrentValueBetween(start_unselected_width_, | 572 return animation_.CurrentValueBetween(start_unselected_width_, |
572 end_unselected_width_); | 573 end_unselected_width_); |
573 } | 574 } |
574 | 575 |
575 private: | 576 private: |
576 // Index of the tab whose mini-state changed. | 577 // Index of the tab whose mini-state changed. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 | 655 |
655 virtual double GetWidthForTab(int index) const { | 656 virtual double GetWidthForTab(int index) const { |
656 TabGtk* tab = tabstrip_->GetTabAt(index); | 657 TabGtk* tab = tabstrip_->GetTabAt(index); |
657 | 658 |
658 if (index == to_index_) | 659 if (index == to_index_) |
659 return animation_.CurrentValueBetween(0, target_bounds_.width()); | 660 return animation_.CurrentValueBetween(0, target_bounds_.width()); |
660 | 661 |
661 if (tab->mini()) | 662 if (tab->mini()) |
662 return TabGtk::GetMiniWidth(); | 663 return TabGtk::GetMiniWidth(); |
663 | 664 |
664 if (tab->IsSelected()) { | 665 if (tab->IsActive()) { |
665 return animation_.CurrentValueBetween(start_selected_width_, | 666 return animation_.CurrentValueBetween(start_selected_width_, |
666 end_selected_width_); | 667 end_selected_width_); |
667 } | 668 } |
668 | 669 |
669 return animation_.CurrentValueBetween(start_unselected_width_, | 670 return animation_.CurrentValueBetween(start_unselected_width_, |
670 end_unselected_width_); | 671 end_unselected_width_); |
671 } | 672 } |
672 | 673 |
673 private: | 674 private: |
674 // The tab being moved. | 675 // The tab being moved. |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1007 | 1008 |
1008 void TabStripGtk::TabDetachedAt(TabContentsWrapper* contents, int index) { | 1009 void TabStripGtk::TabDetachedAt(TabContentsWrapper* contents, int index) { |
1009 GenerateIdealBounds(); | 1010 GenerateIdealBounds(); |
1010 StartRemoveTabAnimation(index, contents->tab_contents()); | 1011 StartRemoveTabAnimation(index, contents->tab_contents()); |
1011 // Have to do this _after_ calling StartRemoveTabAnimation, so that any | 1012 // Have to do this _after_ calling StartRemoveTabAnimation, so that any |
1012 // previous remove is completed fully and index is valid in sync with the | 1013 // previous remove is completed fully and index is valid in sync with the |
1013 // model index. | 1014 // model index. |
1014 GetTabAt(index)->set_closing(true); | 1015 GetTabAt(index)->set_closing(true); |
1015 } | 1016 } |
1016 | 1017 |
1017 void TabStripGtk::ActiveTabChanged(TabContentsWrapper* old_contents, | 1018 void TabStripGtk::TabSelectionChanged(const TabStripSelectionModel& old_model) { |
1018 TabContentsWrapper* new_contents, | |
1019 int index, | |
1020 bool user_gesture) { | |
1021 DCHECK(index >= 0 && index < static_cast<int>(GetTabCount())); | |
1022 | |
1023 // We have "tiny tabs" if the tabs are so tiny that the unselected ones are | 1019 // We have "tiny tabs" if the tabs are so tiny that the unselected ones are |
1024 // a different size to the selected ones. | 1020 // a different size to the selected ones. |
1025 bool tiny_tabs = current_unselected_width_ != current_selected_width_; | 1021 bool tiny_tabs = current_unselected_width_ != current_selected_width_; |
1026 if (!IsAnimating() && (!needs_resize_layout_ || tiny_tabs)) | 1022 if (!IsAnimating() && (!needs_resize_layout_ || tiny_tabs)) |
1027 Layout(); | 1023 Layout(); |
1028 | 1024 |
1029 GetTabAt(index)->SchedulePaint(); | 1025 if (model_->active_index() >= 0) |
| 1026 GetTabAt(model_->active_index())->SchedulePaint(); |
1030 | 1027 |
1031 int old_index = model_->GetIndexOfTabContents(old_contents); | 1028 if (old_model.active() >= 0) { |
1032 if (old_index >= 0) { | 1029 GetTabAt(old_model.active())->SchedulePaint(); |
1033 GetTabAt(old_index)->SchedulePaint(); | 1030 GetTabAt(old_model.active())->StopMiniTabTitleAnimation(); |
1034 GetTabAt(old_index)->StopMiniTabTitleAnimation(); | 1031 } |
| 1032 |
| 1033 std::vector<int> indices_affected; |
| 1034 std::insert_iterator<std::vector<int> > it1(indices_affected, |
| 1035 indices_affected.begin()); |
| 1036 std::set_symmetric_difference( |
| 1037 old_model.selected_indices().begin(), |
| 1038 old_model.selected_indices().end(), |
| 1039 model_->selection_model().selected_indices().begin(), |
| 1040 model_->selection_model().selected_indices().end(), |
| 1041 it1); |
| 1042 for (std::vector<int>::iterator it = indices_affected.begin(); |
| 1043 it != indices_affected.end(); ++it) { |
| 1044 // SchedulePaint() has already been called for the active tab and |
| 1045 // the previously active tab (if it still exists). |
| 1046 if (*it != model_->active_index() && *it != old_model.active()) |
| 1047 GetTabAtAdjustForAnimation(*it)->SchedulePaint(); |
| 1048 } |
| 1049 |
| 1050 TabStripSelectionModel::SelectedIndices no_longer_selected; |
| 1051 std::insert_iterator<std::vector<int> > it2(no_longer_selected, |
| 1052 no_longer_selected.begin()); |
| 1053 std::set_difference(old_model.selected_indices().begin(), |
| 1054 old_model.selected_indices().end(), |
| 1055 model_->selection_model().selected_indices().begin(), |
| 1056 model_->selection_model().selected_indices().end(), |
| 1057 it2); |
| 1058 for (std::vector<int>::iterator it = no_longer_selected.begin(); |
| 1059 it != no_longer_selected.end(); ++it) { |
| 1060 GetTabAtAdjustForAnimation(*it)->StopMiniTabTitleAnimation(); |
1035 } | 1061 } |
1036 } | 1062 } |
1037 | 1063 |
1038 void TabStripGtk::TabMoved(TabContentsWrapper* contents, | 1064 void TabStripGtk::TabMoved(TabContentsWrapper* contents, |
1039 int from_index, | 1065 int from_index, |
1040 int to_index) { | 1066 int to_index) { |
1041 gfx::Rect start_bounds = GetIdealBounds(from_index); | 1067 gfx::Rect start_bounds = GetIdealBounds(from_index); |
1042 TabGtk* tab = GetTabAt(from_index); | 1068 TabGtk* tab = GetTabAt(from_index); |
1043 tab_data_.erase(tab_data_.begin() + from_index); | 1069 tab_data_.erase(tab_data_.begin() + from_index); |
1044 TabData data = {tab, gfx::Rect()}; | 1070 TabData data = {tab, gfx::Rect()}; |
1045 tab->set_mini(model_->IsMiniTab(to_index)); | 1071 tab->set_mini(model_->IsMiniTab(to_index)); |
1046 tab->SetBlocked(model_->IsTabBlocked(to_index)); | 1072 tab->SetBlocked(model_->IsTabBlocked(to_index)); |
1047 tab_data_.insert(tab_data_.begin() + to_index, data); | 1073 tab_data_.insert(tab_data_.begin() + to_index, data); |
1048 GenerateIdealBounds(); | 1074 GenerateIdealBounds(); |
1049 StartMoveTabAnimation(from_index, to_index); | 1075 StartMoveTabAnimation(from_index, to_index); |
1050 } | 1076 } |
1051 | 1077 |
1052 void TabStripGtk::TabChangedAt(TabContentsWrapper* contents, int index, | 1078 void TabStripGtk::TabChangedAt(TabContentsWrapper* contents, int index, |
1053 TabChangeType change_type) { | 1079 TabChangeType change_type) { |
1054 // Index is in terms of the model. Need to make sure we adjust that index in | 1080 // Index is in terms of the model. Need to make sure we adjust that index in |
1055 // case we have an animation going. | 1081 // case we have an animation going. |
1056 TabGtk* tab = GetTabAtAdjustForAnimation(index); | 1082 TabGtk* tab = GetTabAtAdjustForAnimation(index); |
1057 if (change_type == TITLE_NOT_LOADING) { | 1083 if (change_type == TITLE_NOT_LOADING) { |
1058 if (tab->mini() && !tab->IsSelected()) | 1084 if (tab->mini() && !tab->IsActive()) |
1059 tab->StartMiniTabTitleAnimation(); | 1085 tab->StartMiniTabTitleAnimation(); |
1060 // We'll receive another notification of the change asynchronously. | 1086 // We'll receive another notification of the change asynchronously. |
1061 return; | 1087 return; |
1062 } | 1088 } |
1063 tab->UpdateData(contents->tab_contents(), | 1089 tab->UpdateData(contents->tab_contents(), |
1064 model_->IsAppTab(index), | 1090 model_->IsAppTab(index), |
1065 change_type == LOADING_ONLY); | 1091 change_type == LOADING_ONLY); |
1066 tab->UpdateFromModel(); | 1092 tab->UpdateFromModel(); |
1067 } | 1093 } |
1068 | 1094 |
(...skipping 21 matching lines...) Expand all Loading... |
1090 } | 1116 } |
1091 | 1117 |
1092 void TabStripGtk::TabBlockedStateChanged(TabContentsWrapper* contents, | 1118 void TabStripGtk::TabBlockedStateChanged(TabContentsWrapper* contents, |
1093 int index) { | 1119 int index) { |
1094 GetTabAt(index)->SetBlocked(model_->IsTabBlocked(index)); | 1120 GetTabAt(index)->SetBlocked(model_->IsTabBlocked(index)); |
1095 } | 1121 } |
1096 | 1122 |
1097 //////////////////////////////////////////////////////////////////////////////// | 1123 //////////////////////////////////////////////////////////////////////////////// |
1098 // TabStripGtk, TabGtk::TabDelegate implementation: | 1124 // TabStripGtk, TabGtk::TabDelegate implementation: |
1099 | 1125 |
1100 bool TabStripGtk::IsTabSelected(const TabGtk* tab) const { | 1126 bool TabStripGtk::IsTabActive(const TabGtk* tab) const { |
1101 if (tab->closing()) | 1127 if (tab->closing()) |
1102 return false; | 1128 return false; |
1103 | 1129 |
1104 return GetIndexOfTab(tab) == model_->active_index(); | 1130 return GetIndexOfTab(tab) == model_->active_index(); |
1105 } | 1131 } |
1106 | 1132 |
| 1133 bool TabStripGtk::IsTabSelected(const TabGtk* tab) const { |
| 1134 if (tab->closing()) |
| 1135 return false; |
| 1136 |
| 1137 return model_->IsTabSelected(GetIndexOfTab(tab)); |
| 1138 } |
| 1139 |
1107 bool TabStripGtk::IsTabDetached(const TabGtk* tab) const { | 1140 bool TabStripGtk::IsTabDetached(const TabGtk* tab) const { |
1108 if (drag_controller_.get()) | 1141 if (drag_controller_.get()) |
1109 return drag_controller_->IsTabDetached(tab); | 1142 return drag_controller_->IsTabDetached(tab); |
1110 return false; | 1143 return false; |
1111 } | 1144 } |
1112 | 1145 |
1113 void TabStripGtk::GetCurrentTabWidths(double* unselected_width, | 1146 void TabStripGtk::GetCurrentTabWidths(double* unselected_width, |
1114 double* selected_width) const { | 1147 double* selected_width) const { |
1115 *unselected_width = current_unselected_width_; | 1148 *unselected_width = current_unselected_width_; |
1116 *selected_width = current_selected_width_; | 1149 *selected_width = current_selected_width_; |
1117 } | 1150 } |
1118 | 1151 |
1119 bool TabStripGtk::IsTabPinned(const TabGtk* tab) const { | 1152 bool TabStripGtk::IsTabPinned(const TabGtk* tab) const { |
1120 if (tab->closing()) | 1153 if (tab->closing()) |
1121 return false; | 1154 return false; |
1122 | 1155 |
1123 return model_->IsTabPinned(GetIndexOfTab(tab)); | 1156 return model_->IsTabPinned(GetIndexOfTab(tab)); |
1124 } | 1157 } |
1125 | 1158 |
1126 void TabStripGtk::SelectTab(TabGtk* tab) { | 1159 void TabStripGtk::ActivateTab(TabGtk* tab) { |
1127 int index = GetIndexOfTab(tab); | 1160 int index = GetIndexOfTab(tab); |
1128 if (model_->ContainsIndex(index)) | 1161 if (model_->ContainsIndex(index)) |
1129 model_->ActivateTabAt(index, true); | 1162 model_->ActivateTabAt(index, true); |
1130 } | 1163 } |
1131 | 1164 |
| 1165 void TabStripGtk::ToggleTabSelection(TabGtk* tab) { |
| 1166 int index = GetIndexOfTab(tab); |
| 1167 model_->ToggleSelectionAt(index); |
| 1168 } |
| 1169 |
| 1170 void TabStripGtk::ExtendTabSelection(TabGtk* tab) { |
| 1171 int index = GetIndexOfTab(tab); |
| 1172 if (model_->ContainsIndex(index)) |
| 1173 model_->ExtendSelectionTo(index); |
| 1174 } |
| 1175 |
1132 void TabStripGtk::CloseTab(TabGtk* tab) { | 1176 void TabStripGtk::CloseTab(TabGtk* tab) { |
1133 int tab_index = GetIndexOfTab(tab); | 1177 int tab_index = GetIndexOfTab(tab); |
1134 if (model_->ContainsIndex(tab_index)) { | 1178 if (model_->ContainsIndex(tab_index)) { |
1135 TabGtk* last_tab = GetTabAt(GetTabCount() - 1); | 1179 TabGtk* last_tab = GetTabAt(GetTabCount() - 1); |
1136 // Limit the width available to the TabStrip for laying out Tabs, so that | 1180 // Limit the width available to the TabStrip for laying out Tabs, so that |
1137 // Tabs are not resized until a later time (when the mouse pointer leaves | 1181 // Tabs are not resized until a later time (when the mouse pointer leaves |
1138 // the TabStrip). | 1182 // the TabStrip). |
1139 available_width_for_tabs_ = GetAvailableWidthForTabs(last_tab); | 1183 available_width_for_tabs_ = GetAvailableWidthForTabs(last_tab); |
1140 needs_resize_layout_ = true; | 1184 needs_resize_layout_ = true; |
1141 // We hook into the message loop in order to receive mouse move events when | 1185 // We hook into the message loop in order to receive mouse move events when |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1208 } | 1252 } |
1209 | 1253 |
1210 bool TabStripGtk::HasAvailableDragActions() const { | 1254 bool TabStripGtk::HasAvailableDragActions() const { |
1211 return model_->delegate()->GetDragActions() != 0; | 1255 return model_->delegate()->GetDragActions() != 0; |
1212 } | 1256 } |
1213 | 1257 |
1214 ui::ThemeProvider* TabStripGtk::GetThemeProvider() { | 1258 ui::ThemeProvider* TabStripGtk::GetThemeProvider() { |
1215 return theme_service_; | 1259 return theme_service_; |
1216 } | 1260 } |
1217 | 1261 |
| 1262 TabStripMenuController* TabStripGtk::GetTabStripMenuControllerForTab( |
| 1263 TabGtk* tab) { |
| 1264 return new TabStripMenuController(tab, model(), GetIndexOfTab(tab)); |
| 1265 } |
| 1266 |
1218 /////////////////////////////////////////////////////////////////////////////// | 1267 /////////////////////////////////////////////////////////////////////////////// |
1219 // TabStripGtk, MessageLoop::Observer implementation: | 1268 // TabStripGtk, MessageLoop::Observer implementation: |
1220 | 1269 |
1221 void TabStripGtk::WillProcessEvent(GdkEvent* event) { | 1270 void TabStripGtk::WillProcessEvent(GdkEvent* event) { |
1222 // Nothing to do. | 1271 // Nothing to do. |
1223 } | 1272 } |
1224 | 1273 |
1225 void TabStripGtk::DidProcessEvent(GdkEvent* event) { | 1274 void TabStripGtk::DidProcessEvent(GdkEvent* event) { |
1226 switch (event->type) { | 1275 switch (event->type) { |
1227 case GDK_MOTION_NOTIFY: | 1276 case GDK_MOTION_NOTIFY: |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1340 | 1389 |
1341 // NOTE: This currently assumes a tab's height doesn't differ based on | 1390 // NOTE: This currently assumes a tab's height doesn't differ based on |
1342 // selected state or the number of tabs in the strip! | 1391 // selected state or the number of tabs in the strip! |
1343 int tab_height = TabGtk::GetStandardSize().height(); | 1392 int tab_height = TabGtk::GetStandardSize().height(); |
1344 double tab_x = tab_start_x(); | 1393 double tab_x = tab_start_x(); |
1345 for (int i = 0; i < tab_count; ++i) { | 1394 for (int i = 0; i < tab_count; ++i) { |
1346 TabGtk* tab = GetTabAt(i); | 1395 TabGtk* tab = GetTabAt(i); |
1347 double tab_width = unselected; | 1396 double tab_width = unselected; |
1348 if (tab->mini()) | 1397 if (tab->mini()) |
1349 tab_width = TabGtk::GetMiniWidth(); | 1398 tab_width = TabGtk::GetMiniWidth(); |
1350 else if (tab->IsSelected()) | 1399 else if (tab->IsActive()) |
1351 tab_width = selected; | 1400 tab_width = selected; |
1352 double end_of_tab = tab_x + tab_width; | 1401 double end_of_tab = tab_x + tab_width; |
1353 int rounded_tab_x = Round(tab_x); | 1402 int rounded_tab_x = Round(tab_x); |
1354 gfx::Rect state(rounded_tab_x, 0, Round(end_of_tab) - rounded_tab_x, | 1403 gfx::Rect state(rounded_tab_x, 0, Round(end_of_tab) - rounded_tab_x, |
1355 tab_height); | 1404 tab_height); |
1356 tab_data_.at(i).ideal_bounds = state; | 1405 tab_data_.at(i).ideal_bounds = state; |
1357 tab_x = end_of_tab + GetTabHOffset(i + 1); | 1406 tab_x = end_of_tab + GetTabHOffset(i + 1); |
1358 } | 1407 } |
1359 } | 1408 } |
1360 | 1409 |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1484 available_width_for_tabs_ = -1; | 1533 available_width_for_tabs_ = -1; |
1485 int mini_tab_count = GetMiniTabCount(); | 1534 int mini_tab_count = GetMiniTabCount(); |
1486 if (mini_tab_count == GetTabCount()) { | 1535 if (mini_tab_count == GetTabCount()) { |
1487 // Only mini tabs, we know the tab widths won't have changed (all mini-tabs | 1536 // Only mini tabs, we know the tab widths won't have changed (all mini-tabs |
1488 // have the same width), so there is nothing to do. | 1537 // have the same width), so there is nothing to do. |
1489 return false; | 1538 return false; |
1490 } | 1539 } |
1491 TabGtk* first_tab = GetTabAt(mini_tab_count); | 1540 TabGtk* first_tab = GetTabAt(mini_tab_count); |
1492 double unselected, selected; | 1541 double unselected, selected; |
1493 GetDesiredTabWidths(GetTabCount(), mini_tab_count, &unselected, &selected); | 1542 GetDesiredTabWidths(GetTabCount(), mini_tab_count, &unselected, &selected); |
1494 int w = Round(first_tab->IsSelected() ? selected : unselected); | 1543 int w = Round(first_tab->IsActive() ? selected : unselected); |
1495 | 1544 |
1496 // We only want to run the animation if we're not already at the desired | 1545 // We only want to run the animation if we're not already at the desired |
1497 // size. | 1546 // size. |
1498 if (abs(first_tab->width() - w) > 1) { | 1547 if (abs(first_tab->width() - w) > 1) { |
1499 StartResizeLayoutAnimation(); | 1548 StartResizeLayoutAnimation(); |
1500 return true; | 1549 return true; |
1501 } | 1550 } |
1502 | 1551 |
1503 return false; | 1552 return false; |
1504 } | 1553 } |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1913 newtab_button_->widget(), event); | 1962 newtab_button_->widget(), event); |
1914 | 1963 |
1915 // Paint the tabs in reverse order, so they stack to the left. | 1964 // Paint the tabs in reverse order, so they stack to the left. |
1916 TabGtk* selected_tab = NULL; | 1965 TabGtk* selected_tab = NULL; |
1917 int tab_count = GetTabCount(); | 1966 int tab_count = GetTabCount(); |
1918 for (int i = tab_count - 1; i >= 0; --i) { | 1967 for (int i = tab_count - 1; i >= 0; --i) { |
1919 TabGtk* tab = GetTabAt(i); | 1968 TabGtk* tab = GetTabAt(i); |
1920 // We must ask the _Tab's_ model, not ourselves, because in some situations | 1969 // We must ask the _Tab's_ model, not ourselves, because in some situations |
1921 // the model will be different to this object, e.g. when a Tab is being | 1970 // the model will be different to this object, e.g. when a Tab is being |
1922 // removed after its TabContents has been destroyed. | 1971 // removed after its TabContents has been destroyed. |
1923 if (!tab->IsSelected()) { | 1972 if (!tab->IsActive()) { |
1924 gtk_container_propagate_expose(GTK_CONTAINER(tabstrip_.get()), | 1973 gtk_container_propagate_expose(GTK_CONTAINER(tabstrip_.get()), |
1925 tab->widget(), event); | 1974 tab->widget(), event); |
1926 } else { | 1975 } else { |
1927 selected_tab = tab; | 1976 selected_tab = tab; |
1928 } | 1977 } |
1929 } | 1978 } |
1930 | 1979 |
1931 // Paint the selected tab last, so it overlaps all the others. | 1980 // Paint the selected tab last, so it overlaps all the others. |
1932 if (selected_tab) { | 1981 if (selected_tab) { |
1933 gtk_container_propagate_expose(GTK_CONTAINER(tabstrip_.get()), | 1982 gtk_container_propagate_expose(GTK_CONTAINER(tabstrip_.get()), |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2076 | 2125 |
2077 // Let the middle mouse button initiate clicks as well. | 2126 // Let the middle mouse button initiate clicks as well. |
2078 gtk_util::SetButtonTriggersNavigation(button->widget()); | 2127 gtk_util::SetButtonTriggersNavigation(button->widget()); |
2079 g_signal_connect(button->widget(), "clicked", | 2128 g_signal_connect(button->widget(), "clicked", |
2080 G_CALLBACK(OnNewTabClickedThunk), this); | 2129 G_CALLBACK(OnNewTabClickedThunk), this); |
2081 GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS); | 2130 GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS); |
2082 gtk_fixed_put(GTK_FIXED(tabstrip_.get()), button->widget(), 0, 0); | 2131 gtk_fixed_put(GTK_FIXED(tabstrip_.get()), button->widget(), 0, 0); |
2083 | 2132 |
2084 return button; | 2133 return button; |
2085 } | 2134 } |
OLD | NEW |