| Index: chrome/browser/ui/views/tabs/tab_strip.cc
|
| diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc
|
| index ca534a13b30b2d4ba8a10c52620ce3a782b72e03..effca95055c413ea016e978ddac04e8e33201322 100644
|
| --- a/chrome/browser/ui/views/tabs/tab_strip.cc
|
| +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
|
| @@ -267,16 +267,17 @@ class ResetDraggingStateDelegate
|
| DISALLOW_COPY_AND_ASSIGN(ResetDraggingStateDelegate);
|
| };
|
|
|
| -// If |dest| contains the point |point_in_source| the event handler from |dest|
|
| +// If |dest| contains the rect |rect_in_source| the event handler from |dest|
|
| // is returned. Otherwise NULL is returned.
|
| -views::View* ConvertPointToViewAndGetEventHandler(
|
| +views::View* ConvertRectToViewAndGetEventHandler(
|
| views::View* source,
|
| views::View* dest,
|
| - const gfx::Point& point_in_source) {
|
| - gfx::Point dest_point(point_in_source);
|
| - views::View::ConvertPointToTarget(source, dest, &dest_point);
|
| - return dest->HitTestPoint(dest_point) ?
|
| - dest->GetEventHandlerForPoint(dest_point) : NULL;
|
| + const gfx::Rect& rect_in_source,
|
| + views::View::EventType type) {
|
| + gfx::Rect dest_rect(rect_in_source);
|
| + views::View::ConvertRectToTarget(source, dest, &dest_rect);
|
| + return dest->HitTestRect(dest_rect) ?
|
| + dest->GetEventHandler(dest_rect, type) : NULL;
|
| }
|
|
|
| } // namespace
|
| @@ -298,6 +299,10 @@ class NewTabButton : public views::ImageButton {
|
| background_offset_ = offset;
|
| }
|
|
|
| + View* GetEventHandler(const gfx::Rect& rect, EventType type) OVERRIDE {
|
| + return View::GetEventHandler(rect, type);
|
| + }
|
| +
|
| protected:
|
| // Overridden from views::View:
|
| virtual bool HasHitTestMask() const OVERRIDE;
|
| @@ -1342,11 +1347,43 @@ void TabStrip::GetAccessibleState(ui::AccessibleViewState* state) {
|
| state->role = ui::AccessibilityTypes::ROLE_PAGETABLIST;
|
| }
|
|
|
| -views::View* TabStrip::GetEventHandlerForPoint(const gfx::Point& point) {
|
| +double CoverageProportion(const gfx::Rect& rect_one,
|
| + const gfx::Rect& rect_two) {
|
| + gfx::Rect intersection = rect_one.Intersect(rect_two);
|
| + double rect_one_area = rect_one.size().GetArea();
|
| + double rect_two_area = rect_two.size().GetArea();
|
| + double intersection_area = intersection.size().GetArea();
|
| + if ((rect_one_area <= 0) || (rect_two_area <= 0))
|
| + return 0.0;
|
| + if (rect_one_area > rect_two_area)
|
| + return intersection_area / rect_two_area;
|
| + else
|
| + return intersection_area / rect_one_area;
|
| +}
|
| +
|
| +views::View* TabStrip::GetEventHandler(const gfx::Rect& rect,
|
| + EventType type) {
|
| +#if defined(OS_WIN)
|
| + if (ui::IsMouseEventFromTouch(WM_MOUSEMOVE) &&
|
| + (type == EVENT_HANDLER_TYPE_MOUSE)) {
|
| + // This MOUSE event was actually generated from a touch.
|
| + // Views doesn't currently enable Windows OS touch.
|
| + int touch_size = 24;
|
| + return GetEventHandler(gfx::Rect(rect.x()-touch_size, rect.y()-touch_size,
|
| + touch_size*2, touch_size*2),
|
| + EVENT_HANDLER_TYPE_TOUCH);
|
| + }
|
| +#endif
|
| +
|
| + View* closest_view = NULL;
|
| + View* closest_untouched_view = NULL;
|
| + double max_proportion = 0;
|
| + int closest_distance = INT_MAX;
|
| +
|
| if (!touch_layout_.get()) {
|
| // Return any view that isn't a Tab or this TabStrip immediately. We don't
|
| // want to interfere.
|
| - views::View* v = View::GetEventHandlerForPoint(point);
|
| + views::View* v = View::GetEventHandler(rect, type);
|
| if (v && v != this && v->GetClassName() != Tab::kViewClassName)
|
| return v;
|
|
|
| @@ -1356,21 +1393,24 @@ views::View* TabStrip::GetEventHandlerForPoint(const gfx::Point& point) {
|
| // left-adjacent Tab, so we look ahead for it as we walk.
|
| for (int i = 0; i < tab_count(); ++i) {
|
| Tab* next_tab = i < (tab_count() - 1) ? tab_at(i + 1) : NULL;
|
| - if (next_tab && next_tab->IsActive() && IsPointInTab(next_tab, point))
|
| + if (next_tab && next_tab->IsActive() && IsRectInTab(next_tab, rect))
|
| return next_tab;
|
| - if (IsPointInTab(tab_at(i), point))
|
| + if (IsRectInTab(tab_at(i), rect))
|
| return tab_at(i);
|
| }
|
| } else {
|
| + // Test for new tab button....
|
| if (newtab_button_->visible()) {
|
| views::View* view =
|
| - ConvertPointToViewAndGetEventHandler(this, newtab_button_, point);
|
| + ConvertRectToViewAndGetEventHandler(
|
| + this, newtab_button_, rect, type);
|
| if (view)
|
| return view;
|
| }
|
| - Tab* tab = FindTabForEvent(point);
|
| + // Otherwise, check for other tabs....
|
| + Tab* tab = FindTabForEvent(rect);
|
| if (tab)
|
| - return ConvertPointToViewAndGetEventHandler(this, tab, point);
|
| + return ConvertRectToViewAndGetEventHandler(this, tab, rect, type);
|
| }
|
| return this;
|
| }
|
| @@ -2452,6 +2492,13 @@ bool TabStrip::IsPointInTab(Tab* tab,
|
| return tab->HitTestPoint(point_in_tab_coords);
|
| }
|
|
|
| +bool TabStrip::IsRectInTab(Tab* tab,
|
| + const gfx::Rect& rect_in_tabstrip_coords) {
|
| + gfx::Rect rect_in_tab_coords(rect_in_tabstrip_coords);
|
| + View::ConvertRectToTarget(this, tab, &rect_in_tab_coords);
|
| + return tab->HitTestRect(rect_in_tab_coords);
|
| +}
|
| +
|
| int TabStrip::GetStartXForNormalTabs() const {
|
| int mini_tab_count = GetMiniTabCount();
|
| if (mini_tab_count == 0)
|
| @@ -2460,6 +2507,20 @@ int TabStrip::GetStartXForNormalTabs() const {
|
| kMiniToNonMiniGap;
|
| }
|
|
|
| +Tab* TabStrip::FindTabForEvent(const gfx::Rect& rect) {
|
| + DCHECK(touch_layout_.get());
|
| + int active_tab_index = touch_layout_->active_index();
|
| + Tab* tab = NULL;
|
| + if (active_tab_index != -1) {
|
| + tab = FindTabForEventFrom(rect, active_tab_index, -1);
|
| + if (!tab)
|
| + tab = FindTabForEventFrom(rect, active_tab_index + 1, 1);
|
| + } else if (tab_count()) {
|
| + tab = FindTabForEventFrom(rect, 0, 1);
|
| + }
|
| + return tab;
|
| +}
|
| +
|
| Tab* TabStrip::FindTabForEvent(const gfx::Point& point) {
|
| DCHECK(touch_layout_.get());
|
| int active_tab_index = touch_layout_->active_index();
|
| @@ -2474,6 +2535,19 @@ Tab* TabStrip::FindTabForEvent(const gfx::Point& point) {
|
| return tab;
|
| }
|
|
|
| +Tab* TabStrip::FindTabForEventFrom(const gfx::Rect& rect,
|
| + int start,
|
| + int delta) {
|
| + // |start| equals tab_count() when there are only pinned tabs.
|
| + if (start == tab_count())
|
| + start += delta;
|
| + for (int i = start; i >= 0 && i < tab_count(); i += delta) {
|
| + if (IsRectInTab(tab_at(i), rect))
|
| + return tab_at(i);
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| Tab* TabStrip::FindTabForEventFrom(const gfx::Point& point,
|
| int start,
|
| int delta) {
|
|
|