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" |
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 gtk_drag_dest_set(tabstrip_.get(), GTK_DEST_DEFAULT_ALL, | 743 gtk_drag_dest_set(tabstrip_.get(), GTK_DEST_DEFAULT_ALL, |
744 NULL, 0, | 744 NULL, 0, |
745 static_cast<GdkDragAction>( | 745 static_cast<GdkDragAction>( |
746 GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK)); | 746 GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK)); |
747 static const int targets[] = { ui::TEXT_URI_LIST, | 747 static const int targets[] = { ui::TEXT_URI_LIST, |
748 ui::NETSCAPE_URL, | 748 ui::NETSCAPE_URL, |
749 ui::TEXT_PLAIN, | 749 ui::TEXT_PLAIN, |
750 -1 }; | 750 -1 }; |
751 ui::SetDestTargetList(tabstrip_.get(), targets); | 751 ui::SetDestTargetList(tabstrip_.get(), targets); |
752 | 752 |
| 753 g_signal_connect(tabstrip_.get(), "map", |
| 754 G_CALLBACK(OnMapThunk), this); |
753 g_signal_connect(tabstrip_.get(), "expose-event", | 755 g_signal_connect(tabstrip_.get(), "expose-event", |
754 G_CALLBACK(OnExposeThunk), this); | 756 G_CALLBACK(OnExposeThunk), this); |
755 g_signal_connect(tabstrip_.get(), "size-allocate", | 757 g_signal_connect(tabstrip_.get(), "size-allocate", |
756 G_CALLBACK(OnSizeAllocateThunk), this); | 758 G_CALLBACK(OnSizeAllocateThunk), this); |
757 g_signal_connect(tabstrip_.get(), "drag-motion", | 759 g_signal_connect(tabstrip_.get(), "drag-motion", |
758 G_CALLBACK(OnDragMotionThunk), this); | 760 G_CALLBACK(OnDragMotionThunk), this); |
759 g_signal_connect(tabstrip_.get(), "drag-drop", | 761 g_signal_connect(tabstrip_.get(), "drag-drop", |
760 G_CALLBACK(OnDragDropThunk), this); | 762 G_CALLBACK(OnDragDropThunk), this); |
761 g_signal_connect(tabstrip_.get(), "drag-leave", | 763 g_signal_connect(tabstrip_.get(), "drag-leave", |
762 G_CALLBACK(OnDragLeaveThunk), this); | 764 G_CALLBACK(OnDragLeaveThunk), this); |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 // Don't animate the first tab; it looks weird. | 1001 // Don't animate the first tab; it looks weird. |
1000 if (GetTabCount() > 1) { | 1002 if (GetTabCount() > 1) { |
1001 StartInsertTabAnimation(index); | 1003 StartInsertTabAnimation(index); |
1002 // We added the tab at 0x0, we need to force an animation step otherwise | 1004 // We added the tab at 0x0, we need to force an animation step otherwise |
1003 // if GTK paints before the animation event the tab is painted at 0x0 | 1005 // if GTK paints before the animation event the tab is painted at 0x0 |
1004 // which is most likely not where it should be positioned. | 1006 // which is most likely not where it should be positioned. |
1005 active_animation_->AnimationProgressed(NULL); | 1007 active_animation_->AnimationProgressed(NULL); |
1006 } else { | 1008 } else { |
1007 Layout(); | 1009 Layout(); |
1008 } | 1010 } |
| 1011 |
| 1012 ReStack(); |
1009 } | 1013 } |
1010 | 1014 |
1011 void TabStripGtk::TabDetachedAt(TabContentsWrapper* contents, int index) { | 1015 void TabStripGtk::TabDetachedAt(TabContentsWrapper* contents, int index) { |
1012 GenerateIdealBounds(); | 1016 GenerateIdealBounds(); |
1013 StartRemoveTabAnimation(index, contents->tab_contents()); | 1017 StartRemoveTabAnimation(index, contents->tab_contents()); |
1014 // Have to do this _after_ calling StartRemoveTabAnimation, so that any | 1018 // Have to do this _after_ calling StartRemoveTabAnimation, so that any |
1015 // previous remove is completed fully and index is valid in sync with the | 1019 // previous remove is completed fully and index is valid in sync with the |
1016 // model index. | 1020 // model index. |
1017 GetTabAt(index)->set_closing(true); | 1021 GetTabAt(index)->set_closing(true); |
1018 } | 1022 } |
1019 | 1023 |
| 1024 void TabStripGtk::ActiveTabChanged(TabContentsWrapper* old_contents, |
| 1025 TabContentsWrapper* new_contents, |
| 1026 int index, |
| 1027 bool user_gesture) { |
| 1028 ReStack(); |
| 1029 } |
| 1030 |
1020 void TabStripGtk::TabSelectionChanged(const TabStripSelectionModel& old_model) { | 1031 void TabStripGtk::TabSelectionChanged(const TabStripSelectionModel& old_model) { |
1021 // We have "tiny tabs" if the tabs are so tiny that the unselected ones are | 1032 // We have "tiny tabs" if the tabs are so tiny that the unselected ones are |
1022 // a different size to the selected ones. | 1033 // a different size to the selected ones. |
1023 bool tiny_tabs = current_unselected_width_ != current_selected_width_; | 1034 bool tiny_tabs = current_unselected_width_ != current_selected_width_; |
1024 if (!IsAnimating() && (!needs_resize_layout_ || tiny_tabs)) | 1035 if (!IsAnimating() && (!needs_resize_layout_ || tiny_tabs)) |
1025 Layout(); | 1036 Layout(); |
1026 | 1037 |
1027 if (model_->active_index() >= 0) | 1038 if (model_->active_index() >= 0) |
1028 GetTabAt(model_->active_index())->SchedulePaint(); | 1039 GetTabAt(model_->active_index())->SchedulePaint(); |
1029 | 1040 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1068 int to_index) { | 1079 int to_index) { |
1069 gfx::Rect start_bounds = GetIdealBounds(from_index); | 1080 gfx::Rect start_bounds = GetIdealBounds(from_index); |
1070 TabGtk* tab = GetTabAt(from_index); | 1081 TabGtk* tab = GetTabAt(from_index); |
1071 tab_data_.erase(tab_data_.begin() + from_index); | 1082 tab_data_.erase(tab_data_.begin() + from_index); |
1072 TabData data = {tab, gfx::Rect()}; | 1083 TabData data = {tab, gfx::Rect()}; |
1073 tab->set_mini(model_->IsMiniTab(to_index)); | 1084 tab->set_mini(model_->IsMiniTab(to_index)); |
1074 tab->SetBlocked(model_->IsTabBlocked(to_index)); | 1085 tab->SetBlocked(model_->IsTabBlocked(to_index)); |
1075 tab_data_.insert(tab_data_.begin() + to_index, data); | 1086 tab_data_.insert(tab_data_.begin() + to_index, data); |
1076 GenerateIdealBounds(); | 1087 GenerateIdealBounds(); |
1077 StartMoveTabAnimation(from_index, to_index); | 1088 StartMoveTabAnimation(from_index, to_index); |
| 1089 ReStack(); |
1078 } | 1090 } |
1079 | 1091 |
1080 void TabStripGtk::TabChangedAt(TabContentsWrapper* contents, int index, | 1092 void TabStripGtk::TabChangedAt(TabContentsWrapper* contents, int index, |
1081 TabChangeType change_type) { | 1093 TabChangeType change_type) { |
1082 // Index is in terms of the model. Need to make sure we adjust that index in | 1094 // Index is in terms of the model. Need to make sure we adjust that index in |
1083 // case we have an animation going. | 1095 // case we have an animation going. |
1084 TabGtk* tab = GetTabAtAdjustForAnimation(index); | 1096 TabGtk* tab = GetTabAtAdjustForAnimation(index); |
1085 if (change_type == TITLE_NOT_LOADING) { | 1097 if (change_type == TITLE_NOT_LOADING) { |
1086 if (tab->mini() && !tab->IsActive()) | 1098 if (tab->mini() && !tab->IsActive()) |
1087 tab->StartMiniTabTitleAnimation(); | 1099 tab->StartMiniTabTitleAnimation(); |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1573 | 1585 |
1574 GdkScreen* screen = gdk_screen_get_default(); | 1586 GdkScreen* screen = gdk_screen_get_default(); |
1575 GdkDisplay* display = gdk_screen_get_display(screen); | 1587 GdkDisplay* display = gdk_screen_get_display(screen); |
1576 gint x, y; | 1588 gint x, y; |
1577 gdk_display_get_pointer(display, NULL, &x, &y, NULL); | 1589 gdk_display_get_pointer(display, NULL, &x, &y, NULL); |
1578 gfx::Point cursor_point(x, y); | 1590 gfx::Point cursor_point(x, y); |
1579 | 1591 |
1580 return bds.Contains(cursor_point); | 1592 return bds.Contains(cursor_point); |
1581 } | 1593 } |
1582 | 1594 |
| 1595 void TabStripGtk::ReStack() { |
| 1596 if (!GTK_WIDGET_REALIZED(tabstrip_.get())) { |
| 1597 // If the window isn't realized yet, we can't stack them yet. It will be |
| 1598 // done by the OnMap signal handler. |
| 1599 return; |
| 1600 } |
| 1601 int tab_count = GetTabCount(); |
| 1602 TabGtk* active_tab = NULL; |
| 1603 for (int i = tab_count - 1; i >= 0; --i) { |
| 1604 TabGtk* tab = GetTabAt(i); |
| 1605 if (tab->IsActive()) |
| 1606 active_tab = tab; |
| 1607 else |
| 1608 tab->Raise(); |
| 1609 } |
| 1610 if (active_tab) |
| 1611 active_tab->Raise(); |
| 1612 } |
| 1613 |
| 1614 |
1583 void TabStripGtk::AddMessageLoopObserver() { | 1615 void TabStripGtk::AddMessageLoopObserver() { |
1584 if (!added_as_message_loop_observer_) { | 1616 if (!added_as_message_loop_observer_) { |
1585 MessageLoopForUI::current()->AddObserver(this); | 1617 MessageLoopForUI::current()->AddObserver(this); |
1586 added_as_message_loop_observer_ = true; | 1618 added_as_message_loop_observer_ = true; |
1587 } | 1619 } |
1588 } | 1620 } |
1589 | 1621 |
1590 void TabStripGtk::RemoveMessageLoopObserver() { | 1622 void TabStripGtk::RemoveMessageLoopObserver() { |
1591 if (added_as_message_loop_observer_) { | 1623 if (added_as_message_loop_observer_) { |
1592 MessageLoopForUI::current()->RemoveObserver(this); | 1624 MessageLoopForUI::current()->RemoveObserver(this); |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1930 active_animation_.reset(NULL); | 1962 active_animation_.reset(NULL); |
1931 | 1963 |
1932 // Reset the animation state of each tab. | 1964 // Reset the animation state of each tab. |
1933 for (int i = 0, count = GetTabCount(); i < count; ++i) | 1965 for (int i = 0, count = GetTabCount(); i < count; ++i) |
1934 GetTabAt(i)->set_animating_mini_change(false); | 1966 GetTabAt(i)->set_animating_mini_change(false); |
1935 | 1967 |
1936 if (layout) | 1968 if (layout) |
1937 Layout(); | 1969 Layout(); |
1938 } | 1970 } |
1939 | 1971 |
| 1972 void TabStripGtk::OnMap(GtkWidget* widget) { |
| 1973 ReStack(); |
| 1974 } |
| 1975 |
1940 gboolean TabStripGtk::OnExpose(GtkWidget* widget, GdkEventExpose* event) { | 1976 gboolean TabStripGtk::OnExpose(GtkWidget* widget, GdkEventExpose* event) { |
1941 if (gdk_region_empty(event->region)) | 1977 if (gdk_region_empty(event->region)) |
1942 return TRUE; | 1978 return TRUE; |
1943 | 1979 |
1944 // If we're only repainting favicons, optimize the paint path and only draw | 1980 // If we're only repainting favicons, optimize the paint path and only draw |
1945 // the favicons. | 1981 // the favicons. |
1946 GdkRectangle* rects; | 1982 GdkRectangle* rects; |
1947 gint num_rects; | 1983 gint num_rects; |
1948 gdk_region_get_rectangles(event->region, &rects, &num_rects); | 1984 gdk_region_get_rectangles(event->region, &rects, &num_rects); |
1949 qsort(rects, num_rects, sizeof(GdkRectangle), CompareGdkRectangles); | 1985 qsort(rects, num_rects, sizeof(GdkRectangle), CompareGdkRectangles); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2136 | 2172 |
2137 // Let the middle mouse button initiate clicks as well. | 2173 // Let the middle mouse button initiate clicks as well. |
2138 gtk_util::SetButtonTriggersNavigation(button->widget()); | 2174 gtk_util::SetButtonTriggersNavigation(button->widget()); |
2139 g_signal_connect(button->widget(), "clicked", | 2175 g_signal_connect(button->widget(), "clicked", |
2140 G_CALLBACK(OnNewTabClickedThunk), this); | 2176 G_CALLBACK(OnNewTabClickedThunk), this); |
2141 gtk_widget_set_can_focus(button->widget(), FALSE); | 2177 gtk_widget_set_can_focus(button->widget(), FALSE); |
2142 gtk_fixed_put(GTK_FIXED(tabstrip_.get()), button->widget(), 0, 0); | 2178 gtk_fixed_put(GTK_FIXED(tabstrip_.get()), button->widget(), 0, 0); |
2143 | 2179 |
2144 return button; | 2180 return button; |
2145 } | 2181 } |
OLD | NEW |