Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(597)

Side by Side Diff: chrome/browser/gtk/tabs/tab_strip_gtk.cc

Issue 165272: Add a first attempt at a compact location bar and a status bar. The status ba... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/gtk/tabs/tab_strip_gtk.h ('k') | chrome/browser/views/compact_navigation_bar.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/gtk/tabs/tab_strip_gtk.h" 5 #include "chrome/browser/gtk/tabs/tab_strip_gtk.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "app/gfx/canvas_paint.h" 9 #include "app/gfx/canvas_paint.h"
10 #include "app/l10n_util.h" 10 #include "app/l10n_util.h"
11 #include "app/resource_bundle.h" 11 #include "app/resource_bundle.h"
12 #include "app/slide_animation.h" 12 #include "app/slide_animation.h"
13 #include "base/gfx/gtk_util.h" 13 #include "base/gfx/gtk_util.h"
14 #include "base/gfx/point.h" 14 #include "base/gfx/point.h"
15 #include "chrome/browser/browser_theme_provider.h" 15 #include "chrome/browser/browser_theme_provider.h"
16 #include "chrome/browser/gtk/custom_button.h" 16 #include "chrome/browser/gtk/custom_button.h"
17 #include "chrome/browser/gtk/gtk_dnd_util.h" 17 #include "chrome/browser/gtk/gtk_dnd_util.h"
18 #include "chrome/browser/gtk/gtk_theme_provider.h" 18 #include "chrome/browser/gtk/gtk_theme_provider.h"
19 #include "chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h" 19 #include "chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h"
20 #include "chrome/browser/profile.h" 20 #include "chrome/browser/profile.h"
21 #include "chrome/browser/tab_contents/tab_contents.h" 21 #include "chrome/browser/tab_contents/tab_contents.h"
22 #include "chrome/common/gtk_util.h" 22 #include "chrome/common/gtk_util.h"
23 #include "chrome/common/notification_service.h" 23 #include "chrome/common/notification_service.h"
24 #include "chrome/common/notification_type.h" 24 #include "chrome/common/notification_type.h"
25 #include "grit/app_resources.h" 25 #include "grit/app_resources.h"
26 #include "grit/theme_resources.h" 26 #include "grit/theme_resources.h"
27 27
28 #if defined(OS_CHROMEOS)
29 #include "chrome/browser/browser.h"
30 #include "chrome/browser/browser_list.h"
31 #include "chrome/browser/gtk/browser_window_gtk.h"
32 #include "chrome/browser/metrics/user_metrics.h"
33 #include "chrome/browser/views/tabs/tab_overview_types.h"
34 #include "chrome/common/x11_util.h"
35 #endif
36
37 namespace { 28 namespace {
38 29
39 const int kDefaultAnimationDurationMs = 100; 30 const int kDefaultAnimationDurationMs = 100;
40 const int kResizeLayoutAnimationDurationMs = 166; 31 const int kResizeLayoutAnimationDurationMs = 166;
41 const int kReorderAnimationDurationMs = 166; 32 const int kReorderAnimationDurationMs = 166;
42 const int kAnimateToBoundsDurationMs = 150; 33 const int kAnimateToBoundsDurationMs = 150;
43 const int kPinnedTabAnimationDurationMs = 166; 34 const int kPinnedTabAnimationDurationMs = 166;
44 35
45 const int kNewTabButtonHOffset = -5; 36 const int kNewTabButtonHOffset = -5;
46 const int kNewTabButtonVOffset = 5; 37 const int kNewTabButtonVOffset = 5;
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 G_CALLBACK(OnDragMotion), this); 703 G_CALLBACK(OnDragMotion), this);
713 g_signal_connect(G_OBJECT(tabstrip_.get()), "drag-drop", 704 g_signal_connect(G_OBJECT(tabstrip_.get()), "drag-drop",
714 G_CALLBACK(OnDragDrop), this); 705 G_CALLBACK(OnDragDrop), this);
715 g_signal_connect(G_OBJECT(tabstrip_.get()), "drag-leave", 706 g_signal_connect(G_OBJECT(tabstrip_.get()), "drag-leave",
716 G_CALLBACK(OnDragLeave), this); 707 G_CALLBACK(OnDragLeave), this);
717 g_signal_connect(G_OBJECT(tabstrip_.get()), "drag-data-received", 708 g_signal_connect(G_OBJECT(tabstrip_.get()), "drag-data-received",
718 G_CALLBACK(OnDragDataReceived), this); 709 G_CALLBACK(OnDragDataReceived), this);
719 710
720 newtab_button_.reset(MakeNewTabButton()); 711 newtab_button_.reset(MakeNewTabButton());
721 712
722 #if defined(OS_CHROMEOS)
723 tab_overview_button_.reset(MakeTabOverviewButton());
724 #endif
725
726 gtk_widget_show_all(tabstrip_.get()); 713 gtk_widget_show_all(tabstrip_.get());
727 714
728 bounds_ = GetInitialWidgetBounds(tabstrip_.get()); 715 bounds_ = GetInitialWidgetBounds(tabstrip_.get());
729 716
730 if (drop_indicator_width == 0) { 717 if (drop_indicator_width == 0) {
731 // Direction doesn't matter, both images are the same size. 718 // Direction doesn't matter, both images are the same size.
732 GdkPixbuf* drop_image = GetDropArrowImage(true); 719 GdkPixbuf* drop_image = GetDropArrowImage(true);
733 drop_indicator_width = gdk_pixbuf_get_width(drop_image); 720 drop_indicator_width = gdk_pixbuf_get_width(drop_image);
734 drop_indicator_height = gdk_pixbuf_get_height(drop_image); 721 drop_indicator_height = gdk_pixbuf_get_height(drop_image);
735 } 722 }
(...skipping 19 matching lines...) Expand all
755 int tab_right = 0; 742 int tab_right = 0;
756 for (int i = 0; i < tab_count; ++i) { 743 for (int i = 0; i < tab_count; ++i) {
757 const gfx::Rect& bounds = tab_data_.at(i).ideal_bounds; 744 const gfx::Rect& bounds = tab_data_.at(i).ideal_bounds;
758 TabGtk* tab = GetTabAt(i); 745 TabGtk* tab = GetTabAt(i);
759 SetTabBounds(tab, bounds); 746 SetTabBounds(tab, bounds);
760 tab_right = bounds.right(); 747 tab_right = bounds.right();
761 tab_right += GetTabHOffset(i + 1); 748 tab_right += GetTabHOffset(i + 1);
762 } 749 }
763 750
764 LayoutNewTabButton(static_cast<double>(tab_right), current_unselected_width_); 751 LayoutNewTabButton(static_cast<double>(tab_right), current_unselected_width_);
765 #if defined(OS_CHROMEOS)
766 LayoutTabOverviewButton();
767 #endif
768 gtk_widget_queue_draw(tabstrip_.get()); 752 gtk_widget_queue_draw(tabstrip_.get());
769 } 753 }
770 754
771 void TabStripGtk::SchedulePaint() { 755 void TabStripGtk::SchedulePaint() {
772 gtk_widget_queue_draw(tabstrip_.get()); 756 gtk_widget_queue_draw(tabstrip_.get());
773 } 757 }
774 758
775 void TabStripGtk::SetBounds(const gfx::Rect& bounds) { 759 void TabStripGtk::SetBounds(const gfx::Rect& bounds) {
776 bounds_ = bounds; 760 bounds_ = bounds;
777 } 761 }
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
1234 1218
1235 void TabStripGtk::LayoutNewTabButton(double last_tab_right, 1219 void TabStripGtk::LayoutNewTabButton(double last_tab_right,
1236 double unselected_width) { 1220 double unselected_width) {
1237 gfx::Rect bounds(0, kNewTabButtonVOffset, 1221 gfx::Rect bounds(0, kNewTabButtonVOffset,
1238 newtab_button_->width(), newtab_button_->height()); 1222 newtab_button_->width(), newtab_button_->height());
1239 int delta = abs(Round(unselected_width) - TabGtk::GetStandardSize().width()); 1223 int delta = abs(Round(unselected_width) - TabGtk::GetStandardSize().width());
1240 if (delta > 1 && !resize_layout_scheduled_) { 1224 if (delta > 1 && !resize_layout_scheduled_) {
1241 // We're shrinking tabs, so we need to anchor the New Tab button to the 1225 // We're shrinking tabs, so we need to anchor the New Tab button to the
1242 // right edge of the TabStrip's bounds, rather than the right edge of the 1226 // right edge of the TabStrip's bounds, rather than the right edge of the
1243 // right-most Tab, otherwise it'll bounce when animating. 1227 // right-most Tab, otherwise it'll bounce when animating.
1244 #if defined(OS_CHROMEOS)
1245 bounds.set_x(bounds_.width() - newtab_button_->width() -
1246 tab_overview_button_->width());
1247 #else
1248 bounds.set_x(bounds_.width() - newtab_button_->width()); 1228 bounds.set_x(bounds_.width() - newtab_button_->width());
1249 #endif
1250 } else { 1229 } else {
1251 bounds.set_x(Round(last_tab_right - kTabHOffset) + kNewTabButtonHOffset); 1230 bounds.set_x(Round(last_tab_right - kTabHOffset) + kNewTabButtonHOffset);
1252 } 1231 }
1253 bounds.set_x(gtk_util::MirroredLeftPointForRect(tabstrip_.get(), bounds)); 1232 bounds.set_x(gtk_util::MirroredLeftPointForRect(tabstrip_.get(), bounds));
1254 1233
1255 gtk_fixed_move(GTK_FIXED(tabstrip_.get()), newtab_button_->widget(), 1234 gtk_fixed_move(GTK_FIXED(tabstrip_.get()), newtab_button_->widget(),
1256 bounds.x(), bounds.y()); 1235 bounds.x(), bounds.y());
1257 } 1236 }
1258 1237
1259 #if defined OS_CHROMEOS
1260 void TabStripGtk::LayoutTabOverviewButton() {
1261 gtk_fixed_move(GTK_FIXED(tabstrip_.get()), tab_overview_button_->widget(),
1262 bounds_.width() - tab_overview_button_->width(), 0);
1263 }
1264 #endif
1265
1266 void TabStripGtk::GetDesiredTabWidths(int tab_count, 1238 void TabStripGtk::GetDesiredTabWidths(int tab_count,
1267 int pinned_tab_count, 1239 int pinned_tab_count,
1268 double* unselected_width, 1240 double* unselected_width,
1269 double* selected_width) const { 1241 double* selected_width) const {
1270 DCHECK(tab_count >= 0 && pinned_tab_count >= 0 && 1242 DCHECK(tab_count >= 0 && pinned_tab_count >= 0 &&
1271 pinned_tab_count <= tab_count); 1243 pinned_tab_count <= tab_count);
1272 const double min_unselected_width = 1244 const double min_unselected_width =
1273 TabGtk::GetMinimumUnselectedSize().width(); 1245 TabGtk::GetMinimumUnselectedSize().width();
1274 const double min_selected_width = 1246 const double min_selected_width =
1275 TabGtk::GetMinimumSelectedSize().width(); 1247 TabGtk::GetMinimumSelectedSize().width();
1276 1248
1277 *unselected_width = min_unselected_width; 1249 *unselected_width = min_unselected_width;
1278 *selected_width = min_selected_width; 1250 *selected_width = min_selected_width;
1279 1251
1280 if (tab_count == 0) { 1252 if (tab_count == 0) {
1281 // Return immediately to avoid divide-by-zero below. 1253 // Return immediately to avoid divide-by-zero below.
1282 return; 1254 return;
1283 } 1255 }
1284 1256
1285 // Determine how much space we can actually allocate to tabs. 1257 // Determine how much space we can actually allocate to tabs.
1286 int available_width = tabstrip_->allocation.width; 1258 int available_width = tabstrip_->allocation.width;
1287 if (available_width_for_tabs_ < 0) { 1259 if (available_width_for_tabs_ < 0) {
1288 available_width = bounds_.width(); 1260 available_width = bounds_.width();
1289 available_width -= 1261 available_width -=
1290 (kNewTabButtonHOffset + newtab_button_->width()); 1262 (kNewTabButtonHOffset + newtab_button_->width());
1291 #if defined(OS_CHROMEOS)
1292 available_width -= tab_overview_button_->width();
1293 #endif
1294 } else { 1263 } else {
1295 // Interesting corner case: if |available_width_for_tabs_| > the result 1264 // Interesting corner case: if |available_width_for_tabs_| > the result
1296 // of the calculation in the conditional arm above, the strip is in 1265 // of the calculation in the conditional arm above, the strip is in
1297 // overflow. We can either use the specified width or the true available 1266 // overflow. We can either use the specified width or the true available
1298 // width here; the first preserves the consistent "leave the last tab under 1267 // width here; the first preserves the consistent "leave the last tab under
1299 // the user's mouse so they can close many tabs" behavior at the cost of 1268 // the user's mouse so they can close many tabs" behavior at the cost of
1300 // prolonging the glitchy appearance of the overflow state, while the second 1269 // prolonging the glitchy appearance of the overflow state, while the second
1301 // gets us out of overflow as soon as possible but forces the user to move 1270 // gets us out of overflow as soon as possible but forces the user to move
1302 // their mouse for a few tabs' worth of closing. We choose visual 1271 // their mouse for a few tabs' worth of closing. We choose visual
1303 // imperfection over behavioral imperfection and select the first option. 1272 // imperfection over behavioral imperfection and select the first option.
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
1670 double tab_width = TabAnimation::GetCurrentTabWidth(this, animation, i); 1639 double tab_width = TabAnimation::GetCurrentTabWidth(this, animation, i);
1671 double end_of_tab = tab_x + tab_width; 1640 double end_of_tab = tab_x + tab_width;
1672 int rounded_tab_x = Round(tab_x); 1641 int rounded_tab_x = Round(tab_x);
1673 TabGtk* tab = GetTabAt(i); 1642 TabGtk* tab = GetTabAt(i);
1674 gfx::Rect bounds(rounded_tab_x, 0, Round(end_of_tab) - rounded_tab_x, 1643 gfx::Rect bounds(rounded_tab_x, 0, Round(end_of_tab) - rounded_tab_x,
1675 tab_height); 1644 tab_height);
1676 SetTabBounds(tab, bounds); 1645 SetTabBounds(tab, bounds);
1677 tab_x = end_of_tab + GetTabHOffset(i + 1); 1646 tab_x = end_of_tab + GetTabHOffset(i + 1);
1678 } 1647 }
1679 LayoutNewTabButton(tab_x, unselected_width); 1648 LayoutNewTabButton(tab_x, unselected_width);
1680 #if defined(OS_CHROMEOS)
1681 LayoutTabOverviewButton();
1682 #endif
1683 gtk_widget_queue_draw(tabstrip_.get()); 1649 gtk_widget_queue_draw(tabstrip_.get());
1684 } 1650 }
1685 1651
1686 void TabStripGtk::StartInsertTabAnimation(int index) { 1652 void TabStripGtk::StartInsertTabAnimation(int index) {
1687 // The TabStrip can now use its entire width to lay out Tabs. 1653 // The TabStrip can now use its entire width to lay out Tabs.
1688 available_width_for_tabs_ = -1; 1654 available_width_for_tabs_ = -1;
1689 if (active_animation_.get()) 1655 if (active_animation_.get())
1690 active_animation_->Stop(); 1656 active_animation_->Stop();
1691 active_animation_.reset(new InsertTabAnimation(this, index)); 1657 active_animation_.reset(new InsertTabAnimation(this, index));
1692 active_animation_->Start(); 1658 active_animation_->Start();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1771 event->area.x = 0; 1737 event->area.x = 0;
1772 event->area.y = 0; 1738 event->area.y = 0;
1773 event->area.width = tabstrip->bounds_.width(); 1739 event->area.width = tabstrip->bounds_.width();
1774 event->area.height = tabstrip->bounds_.height(); 1740 event->area.height = tabstrip->bounds_.height();
1775 gdk_region_union_with_rect(event->region, &event->area); 1741 gdk_region_union_with_rect(event->region, &event->area);
1776 1742
1777 // Paint the New Tab button. 1743 // Paint the New Tab button.
1778 gtk_container_propagate_expose(GTK_CONTAINER(tabstrip->tabstrip_.get()), 1744 gtk_container_propagate_expose(GTK_CONTAINER(tabstrip->tabstrip_.get()),
1779 tabstrip->newtab_button_->widget(), event); 1745 tabstrip->newtab_button_->widget(), event);
1780 1746
1781 #if defined(OS_CHROMEOS)
1782 // Paint the tab overview button.
1783 gtk_container_propagate_expose(GTK_CONTAINER(tabstrip->tabstrip_.get()),
1784 tabstrip->tab_overview_button_->widget(), event);
1785 #endif
1786
1787 // Paint the tabs in reverse order, so they stack to the left. 1747 // Paint the tabs in reverse order, so they stack to the left.
1788 TabGtk* selected_tab = NULL; 1748 TabGtk* selected_tab = NULL;
1789 int tab_count = tabstrip->GetTabCount(); 1749 int tab_count = tabstrip->GetTabCount();
1790 for (int i = tab_count - 1; i >= 0; --i) { 1750 for (int i = tab_count - 1; i >= 0; --i) {
1791 TabGtk* tab = tabstrip->GetTabAt(i); 1751 TabGtk* tab = tabstrip->GetTabAt(i);
1792 // We must ask the _Tab's_ model, not ourselves, because in some situations 1752 // We must ask the _Tab's_ model, not ourselves, because in some situations
1793 // the model will be different to this object, e.g. when a Tab is being 1753 // the model will be different to this object, e.g. when a Tab is being
1794 // removed after its TabContents has been destroyed. 1754 // removed after its TabContents has been destroyed.
1795 if (!tab->IsSelected()) { 1755 if (!tab->IsSelected()) {
1796 gtk_container_propagate_expose(GTK_CONTAINER(tabstrip->tabstrip_.get()), 1756 gtk_container_propagate_expose(GTK_CONTAINER(tabstrip->tabstrip_.get()),
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1904 CustomDrawButton* button = new CustomDrawButton(IDR_NEWTAB_BUTTON, 1864 CustomDrawButton* button = new CustomDrawButton(IDR_NEWTAB_BUTTON,
1905 IDR_NEWTAB_BUTTON_P, IDR_NEWTAB_BUTTON_H, 0); 1865 IDR_NEWTAB_BUTTON_P, IDR_NEWTAB_BUTTON_H, 0);
1906 1866
1907 g_signal_connect(G_OBJECT(button->widget()), "clicked", 1867 g_signal_connect(G_OBJECT(button->widget()), "clicked",
1908 G_CALLBACK(OnNewTabClicked), this); 1868 G_CALLBACK(OnNewTabClicked), this);
1909 GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS); 1869 GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS);
1910 gtk_fixed_put(GTK_FIXED(tabstrip_.get()), button->widget(), 0, 0); 1870 gtk_fixed_put(GTK_FIXED(tabstrip_.get()), button->widget(), 0, 0);
1911 1871
1912 return button; 1872 return button;
1913 } 1873 }
1914
1915 #if defined(OS_CHROMEOS)
1916 CustomDrawButton* TabStripGtk::MakeTabOverviewButton() {
1917 CustomDrawButton* button =
1918 new CustomDrawButton(IDR_TAB_OVERVIEW_BUTTON_ICON, 0, 0, 0);
1919
1920 g_signal_connect(G_OBJECT(button->widget()), "clicked",
1921 G_CALLBACK(OnTabOverviewButtonClicked), this);
1922 GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS);
1923 gtk_fixed_put(GTK_FIXED(tabstrip_.get()), button->widget(), 0, 0);
1924
1925 return button;
1926 }
1927
1928 // static
1929 void TabStripGtk::OnTabOverviewButtonClicked(GtkWidget* widget,
1930 TabStripGtk* tabstrip) {
1931 Browser* browser = BrowserList::GetLastActive();
1932 DCHECK(browser); // In order for the user to click on the tab there should
1933 // be an active browser.
1934 TabOverviewTypes::Message message;
1935 message.set_type(TabOverviewTypes::Message::WM_SWITCH_TO_OVERVIEW_MODE);
1936 GtkWidget* browser_widget = GTK_WIDGET(
1937 static_cast<BrowserWindowGtk*>(browser->window())->GetNativeHandle());
1938 message.set_param(0, x11_util::GetX11WindowFromGtkWidget(browser_widget));
1939 TabOverviewTypes::instance()->SendMessage(message);
1940
1941 UserMetrics::RecordAction(L"TabOverview_PressedTabOverviewButton",
1942 tabstrip->model_->profile());
1943 }
1944 #endif
OLDNEW
« no previous file with comments | « chrome/browser/gtk/tabs/tab_strip_gtk.h ('k') | chrome/browser/views/compact_navigation_bar.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698