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

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, add unittests, fix style nits 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 #include "ui/gfx/size_conversions.h"
9
10 using WebKit::WebRect;
11 using WebKit::WebVector;
12
13 namespace {
14
15 // The amount of padding to add to the disambiguation popup to show
16 // content around the possible elements, adding some context.
17 const int kDisambiguationPopupPadding = 8;
18
19 // Constants used for fitting the disambiguation popup inside the bounds of
20 // the view. Note that there are mirror constants in PopupZoomer.java.
21 const int kDisambiguationPopupBoundsMargin = 25;
22
23 // The smallest allowable touch target used for disambiguation popup.
24 // This value is used to determine the minimum amount we need to scale to
25 // make all targets touchable.
26 const int kDisambiguationPopupMinimumTouchSize = 40;
27 const float kDisambiguationPopupMaxScale = 5.0;
28 const float kDisambiguationPopupMinScale = 2.0;
29
30 // Compute the scaling factor to ensure the smallest touch candidate reaches
31 // a certain clickable size after zooming
32 float FindOptimalScaleFactor(const WebVector<WebRect>& target_rects) {
33 using std::min;
34 using std::max;
35 if (!target_rects.size()) // shall never reach
36 return kDisambiguationPopupMinScale;
37 int smallest_target = min(target_rects[0].width, target_rects[0].height);
38 for (size_t i = 1; i < target_rects.size(); i++) {
39 smallest_target = min(smallest_target, target_rects[i].width);
40 smallest_target = min(smallest_target, target_rects[i].height);
41 }
42 smallest_target = max(smallest_target, 1);
43 return min(kDisambiguationPopupMaxScale, max(kDisambiguationPopupMinScale,
44 static_cast<float>(kDisambiguationPopupMinimumTouchSize)
45 / smallest_target));
46 }
47
48 void TrimEdges(int *e1, int *e2, int max_combined) {
49 if (*e1 + *e2 <= max_combined)
50 return;
51
52 if (std::min(*e1, *e2) * 2 >= max_combined)
53 *e1 = *e2 = max_combined / 2;
54 else if (*e1 > *e2)
55 *e1 = max_combined - *e2;
56 else
57 *e2 = max_combined - *e1;
58 }
59
60 // Ensure the disambiguation popup fits inside the screen,
61 // clip the edges farthest to the touch point if needed.
62 gfx::Rect CropZoomArea(const gfx::Rect& zoom_rect,
63 const gfx::Size& viewport_size,
64 const gfx::Point& touch_point,
65 float scale) {
66 gfx::Size max_size = viewport_size;
darin (slow to review) 2012/10/17 19:14:01 nit: indent by 2 spaces
trchen 2012/10/17 22:25:08 Done.
67 max_size.Enlarge(-2 * kDisambiguationPopupBoundsMargin,
68 -2 * kDisambiguationPopupBoundsMargin);
69 max_size = ToCeiledSize(max_size.Scale(1.0 / scale));
70
71 int left = touch_point.x() - zoom_rect.x();
72 int right = zoom_rect.right() - touch_point.x();
73 int top = touch_point.y() - zoom_rect.y();
74 int bottom = zoom_rect.bottom() - touch_point.y();
75 TrimEdges(&left, &right, max_size.width());
76 TrimEdges(&top, &bottom, max_size.height());
77
78 return gfx::Rect(touch_point.x() - left,
79 touch_point.y() - top,
80 left + right,
81 top + bottom);
82 }
83
84 } // unnamed namespace
85
86 namespace content {
87
88 float DisambiguationPopupHelper::ComputeZoomAreaAndScaleFactor(
89 const gfx::Rect& tap_rect,
90 const WebVector<WebRect>& target_rects,
91 const gfx::Size& viewport_size,
92 gfx::Rect* zoom_rect) {
93 *zoom_rect = tap_rect;
94 for (size_t i = 0; i < target_rects.size(); i++)
95 *zoom_rect = zoom_rect->Union(gfx::Rect(target_rects[i]));
96 zoom_rect->Inset(-kDisambiguationPopupPadding, -kDisambiguationPopupPadding);
97 *zoom_rect = zoom_rect->Intersect(gfx::Rect(viewport_size));
98
99 float scale = FindOptimalScaleFactor(target_rects);
100 *zoom_rect = CropZoomArea(
101 *zoom_rect, viewport_size, tap_rect.CenterPoint(), scale);
102
103 return scale;
104 }
105
106 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698