OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/views/tabs/tab_strip.h" | 5 #include "chrome/browser/views/tabs/tab_strip.h" |
6 | 6 |
7 #include "app/drag_drop_types.h" | 7 #include "app/drag_drop_types.h" |
8 #include "app/gfx/canvas.h" | 8 #include "app/gfx/canvas.h" |
9 #include "app/gfx/path.h" | 9 #include "app/gfx/path.h" |
10 #include "app/l10n_util.h" | 10 #include "app/l10n_util.h" |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 | 492 |
493 // TODO(beng): remove this if it doesn't work to fix the TabSelectedAt bug. | 493 // TODO(beng): remove this if it doesn't work to fix the TabSelectedAt bug. |
494 drag_controller_.reset(NULL); | 494 drag_controller_.reset(NULL); |
495 | 495 |
496 // Make sure we unhook ourselves as a message loop observer so that we don't | 496 // Make sure we unhook ourselves as a message loop observer so that we don't |
497 // crash in the case where the user closes the window after closing a tab | 497 // crash in the case where the user closes the window after closing a tab |
498 // but before moving the mouse. | 498 // but before moving the mouse. |
499 RemoveMessageLoopObserver(); | 499 RemoveMessageLoopObserver(); |
500 } | 500 } |
501 | 501 |
502 int TabStrip::GetPreferredHeight() { | |
503 return GetPreferredSize().height(); | |
504 } | |
505 | |
506 bool TabStrip::CanProcessInputEvents() const { | 502 bool TabStrip::CanProcessInputEvents() const { |
507 return !IsAnimating(); | 503 return !IsAnimating(); |
508 } | 504 } |
509 | 505 |
510 bool TabStrip::PointIsWithinWindowCaption(const gfx::Point& point) { | |
511 views::View* v = GetViewForPoint(point); | |
512 | |
513 // If there is no control at this location, claim the hit was in the title | |
514 // bar to get a move action. | |
515 if (v == this) | |
516 return true; | |
517 | |
518 // Check to see if the point is within the non-button parts of the new tab | |
519 // button. The button has a non-rectangular shape, so if it's not in the | |
520 // visual portions of the button we treat it as a click to the caption. | |
521 gfx::Point point_in_newtab_coords(point); | |
522 View::ConvertPointToView(this, newtab_button_, &point_in_newtab_coords); | |
523 if (newtab_button_->bounds().Contains(point) && | |
524 !newtab_button_->HitTest(point_in_newtab_coords)) { | |
525 return true; | |
526 } | |
527 | |
528 // All other regions, including the new Tab button, should be considered part | |
529 // of the containing Window's client area so that regular events can be | |
530 // processed for them. | |
531 return false; | |
532 } | |
533 | |
534 bool TabStrip::IsCompatibleWith(TabStrip* other) { | |
535 return model_->profile() == other->model()->profile(); | |
536 } | |
537 | |
538 bool TabStrip::IsAnimating() const { | |
539 return active_animation_.get() != NULL; | |
540 } | |
541 | |
542 void TabStrip::DestroyDragController() { | 506 void TabStrip::DestroyDragController() { |
543 if (IsDragSessionActive()) | 507 if (IsDragSessionActive()) |
544 drag_controller_.reset(NULL); | 508 drag_controller_.reset(NULL); |
545 } | 509 } |
546 | 510 |
547 void TabStrip::DestroyDraggedSourceTab(Tab* tab) { | 511 void TabStrip::DestroyDraggedSourceTab(Tab* tab) { |
548 // We could be running an animation that references this Tab. | 512 // We could be running an animation that references this Tab. |
549 if (active_animation_.get()) | 513 if (active_animation_.get()) |
550 active_animation_->Stop(); | 514 active_animation_->Stop(); |
551 // Make sure we leave the tab_data_ vector in a consistent state, otherwise | 515 // Make sure we leave the tab_data_ vector in a consistent state, otherwise |
(...skipping 14 matching lines...) Expand all Loading... |
566 // the stopping of the active animation above may have left the TabStrip in a | 530 // the stopping of the active animation above may have left the TabStrip in a |
567 // bad (visual) state. | 531 // bad (visual) state. |
568 Layout(); | 532 Layout(); |
569 } | 533 } |
570 | 534 |
571 gfx::Rect TabStrip::GetIdealBounds(int index) { | 535 gfx::Rect TabStrip::GetIdealBounds(int index) { |
572 DCHECK(index >= 0 && index < GetTabCount()); | 536 DCHECK(index >= 0 && index < GetTabCount()); |
573 return tab_data_.at(index).ideal_bounds; | 537 return tab_data_.at(index).ideal_bounds; |
574 } | 538 } |
575 | 539 |
576 void TabStrip::UpdateLoadingAnimations() { | |
577 for (int i = 0, index = 0; i < GetTabCount(); ++i, ++index) { | |
578 Tab* current_tab = GetTabAt(i); | |
579 if (current_tab->closing()) { | |
580 --index; | |
581 } else { | |
582 TabContents* contents = model_->GetTabContentsAt(index); | |
583 if (!contents || !contents->is_loading()) { | |
584 current_tab->ValidateLoadingAnimation(Tab::ANIMATION_NONE); | |
585 } else if (contents->waiting_for_response()) { | |
586 current_tab->ValidateLoadingAnimation(Tab::ANIMATION_WAITING); | |
587 } else { | |
588 current_tab->ValidateLoadingAnimation(Tab::ANIMATION_LOADING); | |
589 } | |
590 } | |
591 } | |
592 } | |
593 | |
594 void TabStrip::SetBackgroundOffset(gfx::Point offset) { | |
595 int tab_count = GetTabCount(); | |
596 for (int i = 0; i < tab_count; ++i) | |
597 GetTabAt(i)->SetBackgroundOffset(offset); | |
598 } | |
599 | |
600 void TabStrip::InitTabStripButtons() { | 540 void TabStrip::InitTabStripButtons() { |
601 newtab_button_ = new NewTabButton(this); | 541 newtab_button_ = new NewTabButton(this); |
602 LoadNewTabButtonImage(); | 542 LoadNewTabButtonImage(); |
603 newtab_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_NEWTAB)); | 543 newtab_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_NEWTAB)); |
604 AddChildView(newtab_button_); | 544 AddChildView(newtab_button_); |
605 } | 545 } |
606 | 546 |
607 /////////////////////////////////////////////////////////////////////////////// | 547 /////////////////////////////////////////////////////////////////////////////// |
608 // TabStrip, views::View overrides: | 548 // TabStrip, views::View overrides: |
609 | 549 |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 } | 714 } |
775 | 715 |
776 // No need to do any floating view stuff, we don't use them in the TabStrip. | 716 // No need to do any floating view stuff, we don't use them in the TabStrip. |
777 return this; | 717 return this; |
778 } | 718 } |
779 | 719 |
780 void TabStrip::ThemeChanged() { | 720 void TabStrip::ThemeChanged() { |
781 LoadNewTabButtonImage(); | 721 LoadNewTabButtonImage(); |
782 } | 722 } |
783 | 723 |
| 724 void TabStrip::ViewHierarchyChanged(bool is_add, |
| 725 views::View* parent, |
| 726 views::View* child) { |
| 727 if (is_add && child == this) |
| 728 InitTabStripButtons(); |
| 729 } |
| 730 |
| 731 |
784 /////////////////////////////////////////////////////////////////////////////// | 732 /////////////////////////////////////////////////////////////////////////////// |
785 // TabStrip, TabStripModelObserver implementation: | 733 // TabStrip, TabStripModelObserver implementation: |
786 | 734 |
787 void TabStrip::TabInsertedAt(TabContents* contents, | 735 void TabStrip::TabInsertedAt(TabContents* contents, |
788 int index, | 736 int index, |
789 bool foreground) { | 737 bool foreground) { |
790 DCHECK(contents); | 738 DCHECK(contents); |
791 DCHECK(index == TabStripModel::kNoTab || model_->ContainsIndex(index)); | 739 DCHECK(index == TabStripModel::kNoTab || model_->ContainsIndex(index)); |
792 | 740 |
793 if (active_animation_.get()) | 741 if (active_animation_.get()) |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1076 case GDK_MOTION_NOTIFY: | 1024 case GDK_MOTION_NOTIFY: |
1077 case GDK_LEAVE_NOTIFY: | 1025 case GDK_LEAVE_NOTIFY: |
1078 HandleGlobalMouseMoveEvent(); | 1026 HandleGlobalMouseMoveEvent(); |
1079 break; | 1027 break; |
1080 default: | 1028 default: |
1081 break; | 1029 break; |
1082 } | 1030 } |
1083 } | 1031 } |
1084 #endif | 1032 #endif |
1085 | 1033 |
| 1034 //////////////////////////////////////////////////////////////////////////////// |
| 1035 // TabStrip, TabStripWrapper implementation: |
| 1036 |
| 1037 int TabStrip::GetPreferredHeight() { |
| 1038 return GetPreferredSize().height(); |
| 1039 } |
| 1040 |
| 1041 bool TabStrip::IsAnimating() const { |
| 1042 return active_animation_.get() != NULL; |
| 1043 } |
| 1044 |
| 1045 void TabStrip::SetBackgroundOffset(gfx::Point offset) { |
| 1046 int tab_count = GetTabCount(); |
| 1047 for (int i = 0; i < tab_count; ++i) |
| 1048 GetTabAt(i)->SetBackgroundOffset(offset); |
| 1049 } |
| 1050 |
| 1051 bool TabStrip::PointIsWithinWindowCaption(const gfx::Point& point) { |
| 1052 views::View* v = GetViewForPoint(point); |
| 1053 |
| 1054 // If there is no control at this location, claim the hit was in the title |
| 1055 // bar to get a move action. |
| 1056 if (v == this) |
| 1057 return true; |
| 1058 |
| 1059 // Check to see if the point is within the non-button parts of the new tab |
| 1060 // button. The button has a non-rectangular shape, so if it's not in the |
| 1061 // visual portions of the button we treat it as a click to the caption. |
| 1062 gfx::Point point_in_newtab_coords(point); |
| 1063 View::ConvertPointToView(this, newtab_button_, &point_in_newtab_coords); |
| 1064 if (newtab_button_->bounds().Contains(point) && |
| 1065 !newtab_button_->HitTest(point_in_newtab_coords)) { |
| 1066 return true; |
| 1067 } |
| 1068 |
| 1069 // All other regions, including the new Tab button, should be considered part |
| 1070 // of the containing Window's client area so that regular events can be |
| 1071 // processed for them. |
| 1072 return false; |
| 1073 } |
| 1074 |
| 1075 bool TabStrip::IsDragSessionActive() const { |
| 1076 return drag_controller_.get() != NULL; |
| 1077 } |
| 1078 |
| 1079 bool TabStrip::IsCompatibleWith(TabStripWrapper* other) const { |
| 1080 return model_->profile() == other->AsTabStrip()->model()->profile(); |
| 1081 } |
| 1082 |
| 1083 void TabStrip::SetDraggedTabBounds(int tab_index, const gfx::Rect& tab_bounds) { |
| 1084 } |
| 1085 |
| 1086 void TabStrip::UpdateLoadingAnimations() { |
| 1087 for (int i = 0, index = 0; i < GetTabCount(); ++i, ++index) { |
| 1088 Tab* current_tab = GetTabAt(i); |
| 1089 if (current_tab->closing()) { |
| 1090 --index; |
| 1091 } else { |
| 1092 TabContents* contents = model_->GetTabContentsAt(index); |
| 1093 if (!contents || !contents->is_loading()) { |
| 1094 current_tab->ValidateLoadingAnimation(Tab::ANIMATION_NONE); |
| 1095 } else if (contents->waiting_for_response()) { |
| 1096 current_tab->ValidateLoadingAnimation(Tab::ANIMATION_WAITING); |
| 1097 } else { |
| 1098 current_tab->ValidateLoadingAnimation(Tab::ANIMATION_LOADING); |
| 1099 } |
| 1100 } |
| 1101 } |
| 1102 } |
| 1103 |
| 1104 views::View* TabStrip::GetView() { |
| 1105 return this; |
| 1106 } |
| 1107 |
| 1108 BrowserTabStrip* TabStrip::AsBrowserTabStrip() { |
| 1109 return NULL; |
| 1110 } |
| 1111 |
| 1112 TabStrip* TabStrip::AsTabStrip() { |
| 1113 return this; |
| 1114 } |
| 1115 |
1086 /////////////////////////////////////////////////////////////////////////////// | 1116 /////////////////////////////////////////////////////////////////////////////// |
1087 // TabStrip, private: | 1117 // TabStrip, private: |
1088 | 1118 |
1089 void TabStrip::Init() { | 1119 void TabStrip::Init() { |
1090 model_->AddObserver(this); | 1120 model_->AddObserver(this); |
1091 newtab_button_size_.SetSize(kNewTabButtonWidth, kNewTabButtonHeight); | 1121 newtab_button_size_.SetSize(kNewTabButtonWidth, kNewTabButtonHeight); |
1092 if (drop_indicator_width == 0) { | 1122 if (drop_indicator_width == 0) { |
1093 // Direction doesn't matter, both images are the same size. | 1123 // Direction doesn't matter, both images are the same size. |
1094 SkBitmap* drop_image = GetDropArrowImage(true); | 1124 SkBitmap* drop_image = GetDropArrowImage(true); |
1095 drop_indicator_width = drop_image->width(); | 1125 drop_indicator_width = drop_image->width(); |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1601 &TabStrip::ResizeLayoutTabs), | 1631 &TabStrip::ResizeLayoutTabs), |
1602 kResizeTabsTimeMs); | 1632 kResizeTabsTimeMs); |
1603 } | 1633 } |
1604 } else { | 1634 } else { |
1605 // Mouse moved quickly out of the tab strip and then into it again, so | 1635 // Mouse moved quickly out of the tab strip and then into it again, so |
1606 // cancel the timer so that the strip doesn't move when the mouse moves | 1636 // cancel the timer so that the strip doesn't move when the mouse moves |
1607 // back over it. | 1637 // back over it. |
1608 resize_layout_factory_.RevokeAll(); | 1638 resize_layout_factory_.RevokeAll(); |
1609 } | 1639 } |
1610 } | 1640 } |
OLD | NEW |