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