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

Side by Side Diff: content/renderer/disambiguation_popup_helper.cc

Issue 10885004: Implement disambiguation popup (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Rebase, change event.boundingBox to event.data.tap Created 8 years, 2 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
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/disambiguation_popup_helper.h"
6
7 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
8
9 using WebKit::WebRect;
10 using WebKit::WebVector;
11
12 namespace {
13
14 // The amount of padding to add to the disambiguation popup to show
15 // content around the possible elements, adding some context.
16 const int kDisambiguationPopupPadding = 8;
17
18 // Constants used for fitting the disambiguation popup inside the bounds of
19 // the view. Note that there are mirror constants in PopupZoomer.java.
20 const int kDisambiguationPopupBoundsMargin = 25;
21
22 // The smallest allowable touch target used for disambiguation popup.
23 // This value is used to determine the minimum amount we need to scale to
24 // make all targets touchable.
25 const int kDisambiguationPopupMinimumTouchSize = 40;
26 const float kDisambiguationPopupMaxScale = 5.0;
27 const float kDisambiguationPopupMinScale = 2.0;
28
29 // Compute the scaling factor to ensure the smallest touch candidate reaches
30 // a certain clickable size after zooming
31 float FindOptimalScaleFactor(const WebVector<WebRect>& target_rects) {
32 using std::min;
33 using std::max;
34 if (!target_rects.size()) // shall never reach
35 return kDisambiguationPopupMinScale;
36 int smallest_target = min(target_rects[0].width, target_rects[0].height);
37 for (size_t i = 1; i < target_rects.size(); i++) {
38 smallest_target = min(smallest_target, target_rects[i].width);
39 smallest_target = min(smallest_target, target_rects[i].height);
40 }
41 smallest_target = max(smallest_target, 1);
42 return min(kDisambiguationPopupMaxScale, max(kDisambiguationPopupMinScale,
43 static_cast<float>(kDisambiguationPopupMinimumTouchSize)
44 / smallest_target));
45 }
46
47 void TrimEdges(int *e1, int *e2, int max_combined) {
48 if (*e1 + *e2 <= max_combined)
49 return;
50
51 if (std::min(*e1, *e2) * 2 >= max_combined)
52 *e1 = *e2 = max_combined / 2;
53 else if (*e1 > *e2)
54 *e1 = max_combined - *e2;
55 else
56 *e2 = max_combined - *e1;
57 }
58
59 // Ensure the disambiguation popup fits inside the screen,
60 // clip the edges farthest to the touch point if needed.
61 gfx::Rect CropZoomArea(const gfx::Rect& zoom_rect,
62 const gfx::Size& viewport_size,
63 const gfx::Point& touch_point,
64 float scale) {
65 gfx::Size max_size = viewport_size;
66 max_size.Enlarge(-2 * kDisambiguationPopupBoundsMargin,
67 -2 * kDisambiguationPopupBoundsMargin);
68 max_size = max_size.Scale(1.0 / scale);
69
70 int left = touch_point.x() - zoom_rect.x();
71 int right = zoom_rect.right() - touch_point.x();
72 int top = touch_point.y() - zoom_rect.y();
73 int bottom = zoom_rect.bottom() - touch_point.y();
74 TrimEdges(&left, &right, max_size.width());
75 TrimEdges(&top, &bottom, max_size.height());
76
77 return gfx::Rect(touch_point.x() - left,
78 touch_point.y() - top,
79 left + right,
80 top + bottom);
81 }
82
83 } // unnamed namespace
84
85 float DisambiguationPopupHelper::ComputeZoomAreaAndScaleFactor(
darin (slow to review) 2012/10/08 21:03:46 There's enough code in here that I think you could
trchen 2012/10/11 23:54:05 Added 3 simple test cases. However all it does is
86 const gfx::Rect& tap_rect,
87 const WebVector<WebRect>& target_rects,
88 const gfx::Size& viewport_size,
89 gfx::Rect* zoom_rect) {
90 *zoom_rect = tap_rect;
91 for (size_t i = 0; i < target_rects.size(); i++)
92 *zoom_rect = zoom_rect->Union(gfx::Rect(target_rects[i]));
93 zoom_rect->Inset(-kDisambiguationPopupPadding, -kDisambiguationPopupPadding);
94 *zoom_rect = zoom_rect->Intersect(gfx::Rect(viewport_size));
95
96 float scale = FindOptimalScaleFactor(target_rects);
97 *zoom_rect = CropZoomArea(
98 *zoom_rect, viewport_size, tap_rect.CenterPoint(), scale);
99
100 return scale;
101 }
102
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698