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

Unified Diff: chrome/browser/ui/views/ash/tab_scrubber.cc

Issue 11881042: highlight intermediate tabs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Disable tests for win7_aura Created 7 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/ui/views/ash/tab_scrubber.h ('k') | chrome/browser/ui/views/ash/tab_scrubber_browsertest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/views/ash/tab_scrubber.cc
diff --git a/chrome/browser/ui/views/ash/tab_scrubber.cc b/chrome/browser/ui/views/ash/tab_scrubber.cc
index 04258140fb3552325a1d1d6f24c55bf5c60dd4dc..68f6c148aeba7d0c4e496bb5c7673547306946d1 100644
--- a/chrome/browser/ui/views/ash/tab_scrubber.cc
+++ b/chrome/browser/ui/views/ash/tab_scrubber.cc
@@ -10,25 +10,20 @@
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/immersive_mode_controller.h"
#include "chrome/browser/ui/views/tabs/tab.h"
#include "chrome/browser/ui/views/tabs/tab_strip.h"
#include "chrome/common/chrome_notification_types.h"
+#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "ui/aura/window.h"
#include "ui/base/events/event.h"
#include "ui/base/events/event_utils.h"
+#include "ui/views/controls/glow_hover_controller.h"
namespace {
-Tab* GetTabAt(TabStrip* tab_strip, gfx::Point point) {
- for (int i = 0; i < tab_strip->tab_count(); ++i) {
- Tab* tab = tab_strip->tab_at(i);
- if (tab_strip->tab_at(i)->bounds().Contains(point))
- return tab;
- }
- return NULL;
-}
-
-const int kInitialTabOffset = 10;
+const int64 kActivationDelayMS = 200;
+const int64 kCancelImmersiveRevelDelayMS = 200;
}
// static
@@ -39,32 +34,64 @@ TabScrubber* TabScrubber::GetInstance() {
return instance;
}
+// static
+gfx::Point TabScrubber::GetStartPoint(
+ TabStrip* tab_strip,
+ int index,
+ TabScrubber::Direction direction) {
+ int initial_tab_offset = Tab::GetMiniWidth() / 2;
+ gfx::Rect tab_bounds = tab_strip->tab_at(index)->bounds();
+ float x = direction == LEFT ?
+ tab_bounds.x() + initial_tab_offset :
+ tab_bounds.right() - initial_tab_offset;
+ return gfx::Point(x, tab_bounds.CenterPoint().y());
+}
+
+bool TabScrubber::IsActivationPending() {
+ return activate_timer_.IsRunning();
+}
+
TabScrubber::TabScrubber()
: scrubbing_(false),
browser_(NULL),
- scroll_x_(-1),
- scroll_y_(-1) {
+ swipe_x_(-1),
+ swipe_y_(-1),
+ swipe_direction_(LEFT),
+ highlighted_tab_(-1),
+ activate_timer_(true, false),
+ activation_delay_(base::TimeDelta::FromMilliseconds(kActivationDelayMS)),
+ should_cancel_immersive_reveal_(false),
+ cancel_immersive_reveal_timer_(true, false),
+ weak_ptr_factory_(this) {
ash::Shell::GetInstance()->AddPreTargetHandler(this);
+ registrar_.Add(
+ this,
+ chrome::NOTIFICATION_BROWSER_CLOSING,
+ content::NotificationService::AllSources());
}
TabScrubber::~TabScrubber() {
+ // Note: The weak_ptr_factory_ should invalidate its weak pointers before
+ // any other members are destroyed.
+ weak_ptr_factory_.InvalidateWeakPtrs();
}
void TabScrubber::OnScrollEvent(ui::ScrollEvent* event) {
- if (event->type() == ui::ET_SCROLL_FLING_CANCEL) {
- if (scrubbing_)
- StopScrubbing();
+ if (event->type() == ui::ET_SCROLL_FLING_CANCEL ||
+ event->type() == ui::ET_SCROLL_FLING_START) {
+ FinishScrub(true);
+ CancelImmersiveReveal();
return;
}
- if (event->finger_count() != 3 ||
- event->type() != ui::ET_SCROLL)
+ if (event->finger_count() != 3)
return;
Browser* browser = GetActiveBrowser();
- if (!browser || (browser_ && browser != browser_)) {
- if (scrubbing_)
- StopScrubbing();
+ if (!browser || (scrubbing_ && browser_ && browser != browser_) ||
+ (highlighted_tab_ != -1 &&
+ highlighted_tab_ >= browser->tab_strip_model()->count())) {
+ FinishScrub(false);
return;
}
@@ -73,49 +100,142 @@ void TabScrubber::OnScrollEvent(ui::ScrollEvent* event) {
browser->window()->GetNativeWindow());
TabStrip* tab_strip = browser_view->tabstrip();
- float x_offset = -event->x_offset();
+ if (tab_strip->IsAnimating()) {
+ FinishScrub(false);
+ return;
+ }
+
+ // We are handling the event.
+ event->StopPropagation();
+
+ float x_offset = event->x_offset();
+ if (!ui::IsNaturalScrollEnabled())
+ x_offset = -x_offset;
+ int last_tab_index = highlighted_tab_ == -1 ?
+ browser->tab_strip_model()->active_index() : highlighted_tab_;
if (!scrubbing_) {
- scrubbing_ = true;
+ swipe_direction_ = (x_offset < 0) ? LEFT : RIGHT;
+ const gfx::Point start_point =
+ GetStartPoint(tab_strip,
+ browser->tab_strip_model()->active_index(),
+ swipe_direction_);
browser_ = browser;
- Tab* initial_tab =
- tab_strip->tab_at(browser_->tab_strip_model()->active_index());
- scroll_x_ = initial_tab->x();
- scroll_x_ += (x_offset < 0) ?
- kInitialTabOffset : initial_tab->width() - kInitialTabOffset;
- scroll_y_ = initial_tab->height() / 2;
- registrar_.Add(
- this,
- chrome::NOTIFICATION_BROWSER_CLOSING,
- content::Source<Browser>(browser_));
+ scrubbing_ = true;
+
+ swipe_x_ = start_point.x();
+ swipe_y_ = start_point.y();
+ ImmersiveModeController* immersive_controller =
+ browser_view->immersive_mode_controller();
+ CancelImmersiveReveal();
+ if (immersive_controller->enabled() &&
+ !immersive_controller->IsRevealed()) {
+ immersive_controller->MaybeStartReveal();
+ should_cancel_immersive_reveal_ = true;
+ }
+ tab_strip->AddObserver(this);
+ } else if (highlighted_tab_ == -1) {
+ Direction direction = (x_offset < 0) ? LEFT : RIGHT;
+ if (direction != swipe_direction_) {
+ const gfx::Point start_point =
+ GetStartPoint(tab_strip,
+ browser->tab_strip_model()->active_index(),
+ direction);
+ swipe_x_ = start_point.x();
+ swipe_y_ = start_point.y();
+ swipe_direction_ = direction;
+ }
}
- if (ui::IsNaturalScrollEnabled())
- scroll_x_ += event->x_offset();
- else
- scroll_x_ -= event->x_offset();
+ swipe_x_ += x_offset;
Tab* first_tab = tab_strip->tab_at(0);
+ int first_tab_center = first_tab->bounds().CenterPoint().x();
Tab* last_tab = tab_strip->tab_at(tab_strip->tab_count() - 1);
- if (scroll_x_ < first_tab->x())
- scroll_x_ = first_tab->x();
- if (scroll_x_ > last_tab->bounds().right())
- scroll_x_ = last_tab->bounds().right();
-
- gfx::Point tab_point(scroll_x_, scroll_y_);
- Tab* new_tab = GetTabAt(tab_strip, tab_point);
- if (new_tab && !new_tab->IsActive()) {
- int new_index = tab_strip->GetModelIndexOfTab(new_tab);
- browser->tab_strip_model()->ActivateTabAt(new_index, true);
- }
+ int last_tab_tab_center = last_tab->bounds().CenterPoint().x();
+ if (swipe_x_ < first_tab_center)
+ swipe_x_ = first_tab_center;
+ if (swipe_x_ > last_tab_tab_center)
+ swipe_x_ = last_tab_tab_center;
- event->StopPropagation();
+ Tab* initial_tab = tab_strip->tab_at(last_tab_index);
+ gfx::Point tab_point(swipe_x_, swipe_y_);
+ views::View::ConvertPointToTarget(tab_strip, initial_tab, &tab_point);
+ Tab* new_tab = tab_strip->GetTabAt(initial_tab, tab_point);
+ if (!new_tab)
+ return;
+
+ int new_index = tab_strip->GetModelIndexOfTab(new_tab);
+ if (new_index != highlighted_tab_) {
+ if (activate_timer_.IsRunning()) {
+ activate_timer_.Reset();
+ } else {
+ activate_timer_.Start(FROM_HERE,
+ activation_delay_,
+ base::Bind(&TabScrubber::FinishScrub,
+ weak_ptr_factory_.GetWeakPtr(),
+ true));
+ }
+ if (highlighted_tab_ != -1) {
+ Tab* tab = tab_strip->tab_at(highlighted_tab_);
+ tab->hover_controller()->HideImmediately();
+ }
+ if (new_index == browser->tab_strip_model()->active_index()) {
+ highlighted_tab_ = -1;
+ } else {
+ highlighted_tab_ = new_index;
+ new_tab->hover_controller()->Show(views::GlowHoverController::PRONOUNCED);
+ }
+ }
+ if (highlighted_tab_ != -1) {
+ gfx::Point hover_point(swipe_x_, swipe_y_);
+ views::View::ConvertPointToTarget(tab_strip, new_tab, &hover_point);
+ new_tab->hover_controller()->SetLocation(hover_point);
+ }
}
void TabScrubber::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
- DCHECK(type == chrome::NOTIFICATION_BROWSER_CLOSING &&
- content::Source<Browser>(source).ptr() == browser_);
- StopScrubbing();
+ if (content::Source<Browser>(source).ptr() == browser_)
+ FinishScrub(false);
+ browser_ = NULL;
+}
+
+void TabScrubber::TabStripAddedTabAt(TabStrip* tab_strip, int index) {
+ if (highlighted_tab_ == -1)
+ return;
+
+ if (index < highlighted_tab_)
+ ++highlighted_tab_;
+}
+
+void TabScrubber::TabStripMovedTab(TabStrip* tab_strip,
+ int from_index,
+ int to_index) {
+ if (highlighted_tab_ == -1)
+ return;
+
+ if (from_index == highlighted_tab_)
+ highlighted_tab_ = to_index;
+ else if (from_index < highlighted_tab_&& highlighted_tab_<= to_index)
+ --highlighted_tab_;
+ else if (from_index > highlighted_tab_ && highlighted_tab_ >= to_index)
+ ++highlighted_tab_;
+}
+
+void TabScrubber::TabStripRemovedTabAt(TabStrip* tab_strip, int index) {
+ if (highlighted_tab_ == -1)
+ return;
+ if (index == highlighted_tab_) {
+ FinishScrub(false);
+ return;
+ }
+ if (index < highlighted_tab_)
+ --highlighted_tab_;
+}
+
+void TabScrubber::TabStripDeleted(TabStrip* tab_strip) {
+ if (highlighted_tab_ == -1)
+ return;
}
Browser* TabScrubber::GetActiveBrowser() {
@@ -130,14 +250,42 @@ Browser* TabScrubber::GetActiveBrowser() {
return browser;
}
-void TabScrubber::StopScrubbing() {
- if (!scrubbing_)
- return;
+void TabScrubber::FinishScrub(bool activate) {
+ activate_timer_.Stop();
- registrar_.Remove(
- this,
- chrome::NOTIFICATION_BROWSER_CLOSING,
- content::Source<Browser>(browser_));
+ if (browser_) {
+ BrowserView* browser_view =
+ BrowserView::GetBrowserViewForNativeWindow(
+ browser_->window()->GetNativeWindow());
+ TabStrip* tab_strip = browser_view->tabstrip();
+ if (activate && highlighted_tab_ != -1) {
+ Tab* tab = tab_strip->tab_at(highlighted_tab_);
+ tab->hover_controller()->HideImmediately();
+ browser_->tab_strip_model()->ActivateTabAt(highlighted_tab_, true);
+ }
+ tab_strip->RemoveObserver(this);
+ if (!cancel_immersive_reveal_timer_.IsRunning() &&
+ should_cancel_immersive_reveal_) {
+ cancel_immersive_reveal_timer_.Start(
+ FROM_HERE,
+ base::TimeDelta::FromMilliseconds(kCancelImmersiveRevelDelayMS),
+ base:: Bind(&TabScrubber::CancelImmersiveReveal,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+ }
+ swipe_x_ = -1;
+ swipe_y_ = -1;
scrubbing_ = false;
- browser_ = NULL;
+ highlighted_tab_ = -1;
+}
+
+void TabScrubber::CancelImmersiveReveal() {
+ cancel_immersive_reveal_timer_.Stop();
+ if (browser_ && should_cancel_immersive_reveal_) {
+ BrowserView* browser_view =
+ BrowserView::GetBrowserViewForNativeWindow(
+ browser_->window()->GetNativeWindow());
+ browser_view->immersive_mode_controller()->CancelReveal();
+ }
+ should_cancel_immersive_reveal_ = false;
}
« no previous file with comments | « chrome/browser/ui/views/ash/tab_scrubber.h ('k') | chrome/browser/ui/views/ash/tab_scrubber_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698