Chromium Code Reviews| 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 eb375155012bad08e1cda40a3f2e932e5092a1f2..7e87f0ff4020974c8e9fd7d427a3c7a90f841f1b 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; |
| @@ -1340,11 +1345,41 @@ 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, |
|
girard
2012/09/18 16:58:52
Move this into the anonymous namespace at the top
|
| + 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 == MOUSE)) { |
| + // This MOUSE event was actually generated from a touch. |
| + // Views doesn't currently enable Windows OS touch. |
| + int touch_size = 24; |
|
tdanderson
2012/09/18 19:19:02
I'm not sure where this 24 comes from. Can you ple
|
| + return GetEventHandler(gfx::Rect(rect.x()-touch_size, rect.y()-touch_size, |
| + touch_size*2, touch_size*2), TOUCH); |
| + } |
| +#endif |
| + |
| + View* closest_view = NULL; |
| + View* closest_untouched_view = NULL; |
| + double max_proportion = 0; |
| + int closest_distance = INT_MAX; |
|
tdanderson
2012/09/18 19:19:02
Are you planning on using these in the same way as
|
| + |
| 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; |
| @@ -1354,21 +1389,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) |
|
girard
2012/09/18 16:58:52
This should only return if MOUSE. Otherwise conti
|
| return view; |
| } |
| - Tab* tab = FindTabForEvent(point); |
| + // Otherwise, check for other tabs.... |
| + Tab* tab = FindTabForEvent(rect); |
|
girard
2012/09/18 16:58:52
This logic should be expanded here, so we can cons
|
| if (tab) |
| - return ConvertPointToViewAndGetEventHandler(this, tab, point); |
| + return ConvertRectToViewAndGetEventHandler(this, tab, rect, type); |
|
girard
2012/09/18 16:58:52
Ditto.
|
| } |
| return this; |
| } |
| @@ -2352,6 +2390,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) |
| @@ -2360,6 +2405,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(); |
| @@ -2374,6 +2433,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) { |