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

Unified 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: Rename IPCs, move popup size calculation to helper class Created 8 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: content/renderer/disambiguation_popup_helper.cc
diff --git a/content/renderer/disambiguation_popup_helper.cc b/content/renderer/disambiguation_popup_helper.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1501f7e815e0e1ce7abd5f7aeb35c2010cfb61a8
--- /dev/null
+++ b/content/renderer/disambiguation_popup_helper.cc
@@ -0,0 +1,97 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/disambiguation_popup_helper.h"
+
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
+
+using namespace WebKit;
darin (slow to review) 2012/08/31 23:00:16 nit: google style guide does not allow 'using name
+
+// The amount of padding to add to the disambiguation popup to show
+// content around the possible elements, adding some context.
+static const int kDisambiguationPopupPadding = 8;
darin (slow to review) 2012/08/31 23:00:16 nit: instead of 'static' variables and functions,
+
+// Constants used for fitting the disambiguation popup inside the bounds of
+// the view. Note that there are mirror constants in PopupZoomer.java.
+static const int kDisambiguationPopupBoundsMargin = 25;
+
+// The smallest allowable touch target used for disambiguation popup.
+// This value is used to determine the minimum amount we need to scale to
+// make all targets touchable.
+static const int kDisambiguationPopupMinimumTouchSize = 40;
+static const float kDisambiguationPopupMaxScale = 5.0;
+static const float kDisambiguationPopupMinScale = 2.0;
+
+// Compute the scaling factor to ensure the smallest touch candidate reaches
+// a certain clickable size after zooming
+static float FindOptimalScaleFactor(const WebVector<WebRect>& target_rects) {
+ using std::min;
+ using std::max;
+ if (!target_rects.size()) // shall never reach
+ return kDisambiguationPopupMinScale;
+ int smallest_target = min(target_rects[0].width, target_rects[0].height);
+ for (size_t i = 1; i < target_rects.size(); i++) {
+ smallest_target = min(smallest_target, target_rects[i].width);
+ smallest_target = min(smallest_target, target_rects[i].height);
+ }
+ smallest_target = max(smallest_target, 1);
+ return min(kDisambiguationPopupMaxScale, max(kDisambiguationPopupMinScale,
+ static_cast<float>(kDisambiguationPopupMinimumTouchSize)
+ / smallest_target));
+}
+
+static void TrimEdges(int *e1, int *e2, int max_combined) {
+ if (*e1 + *e2 <= max_combined)
+ return;
+
+ if (std::min(*e1, *e2) * 2 >= max_combined) {
+ *e1 = *e2 = max_combined / 2;
+ } else if (*e1 > *e2) {
+ *e1 = max_combined - *e2;
+ } else
darin (slow to review) 2012/08/31 23:00:16 nit: add {}'s for the last else clause to be consi
+ *e2 = max_combined - *e1;
+}
+
+// Ensure the disambiguation popup fits inside the screen,
+// clip the edges farthest to the touch point if needed.
+static gfx::Rect CropZoomArea(const gfx::Rect& zoom_rect,
+ const gfx::Size& viewport_size,
darin (slow to review) 2012/08/31 23:00:16 nit: indentation
+ const gfx::Point& touch_point,
+ float scale) {
+ gfx::Size max_size = viewport_size;
+ max_size.Enlarge(-2 * kDisambiguationPopupBoundsMargin,
+ -2 * kDisambiguationPopupBoundsMargin);
+ max_size = max_size.Scale(1.0 / scale);
+
+ int left = touch_point.x() - zoom_rect.x();
+ int right = zoom_rect.right() - touch_point.x();
+ int top = touch_point.y() - zoom_rect.y();
+ int bottom = zoom_rect.bottom() - touch_point.y();
+ TrimEdges(&left, &right, max_size.width());
+ TrimEdges(&top, &bottom, max_size.height());
+
+ return gfx::Rect(touch_point.x() - left,
+ touch_point.y() - top,
darin (slow to review) 2012/08/31 23:00:16 nit: indentation
+ left + right,
+ top + bottom);
+}
+
+float DisambiguationPopupHelper::ComputeZoomAreaAndScaleFactor(
+ gfx::Rect& zoom_rect,
+ const gfx::Rect& tap_rect,
+ const WebKit::WebVector<WebKit::WebRect>& target_rects,
+ const gfx::Size& viewport_size) {
+ zoom_rect = tap_rect;
+ for (size_t i = 0; i < target_rects.size(); i++)
+ zoom_rect = zoom_rect.Union(gfx::Rect(target_rects[i]));
+ zoom_rect.Inset(-kDisambiguationPopupPadding, -kDisambiguationPopupPadding);
+ zoom_rect = zoom_rect.Intersect(gfx::Rect(viewport_size));
+
+ float scale = FindOptimalScaleFactor(target_rects);
+ zoom_rect = CropZoomArea(
+ zoom_rect, viewport_size, tap_rect.CenterPoint(), scale);
+
+ return scale;
+}
+

Powered by Google App Engine
This is Rietveld 408576698