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

Unified Diff: chrome/browser/ui/views/link_disambiguation/link_disambiguation_popup.cc

Issue 351683002: Adds link disambiguation popup support to Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: making interface changes windows-only Created 6 years, 5 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: chrome/browser/ui/views/link_disambiguation/link_disambiguation_popup.cc
diff --git a/chrome/browser/ui/views/link_disambiguation/link_disambiguation_popup.cc b/chrome/browser/ui/views/link_disambiguation/link_disambiguation_popup.cc
new file mode 100644
index 0000000000000000000000000000000000000000..aefc089132edfdb2a61f4dfd0054f2f3863242b9
--- /dev/null
+++ b/chrome/browser/ui/views/link_disambiguation/link_disambiguation_popup.cc
@@ -0,0 +1,172 @@
+// Copyright (c) 2014 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 "chrome/browser/ui/views/link_disambiguation/link_disambiguation_popup.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "ui/aura/client/screen_position_client.h"
+#include "ui/events/event.h"
+#include "ui/events/event_processor.h"
+#include "ui/events/event_utils.h"
+#include "ui/events/gesture_event_details.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/controls/image_view.h"
+
+class LinkDisambiguationPopup::ZoomBubbleView
+ : public views::BubbleDelegateView {
+ public:
+ typedef base::Callback<void(void)> InvalidationCallback;
+
+ ZoomBubbleView(const gfx::Rect& target_rect,
+ const gfx::ImageSkia* zoomed_skia_image,
+ const aura::Window* content,
+ InvalidationCallback invalidation_cb,
+ content::WebContentsViewDelegate::GestureCallback gesture_cb);
+
+ void Close();
+
+ private:
+ // views::View overrides
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
+ virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
+
+ // WidgetObserver overrides
+ virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
+
+ float scale_;
+ const aura::Window* content_;
+ content::WebContentsViewDelegate::GestureCallback gesture_cb_;
+ InvalidationCallback invalidation_cb_;
+ gfx::Rect target_rect_;
sky 2014/07/30 21:50:36 const
luken 2014/07/31 01:41:46 Done.
+};
sky 2014/07/30 21:50:36 DISALLOW...
luken 2014/07/31 01:41:47 Done.
+
+LinkDisambiguationPopup::ZoomBubbleView::ZoomBubbleView(
+ const gfx::Rect& target_rect,
+ const gfx::ImageSkia* zoomed_skia_image,
+ const aura::Window* content,
+ InvalidationCallback invalidation_cb,
+ content::WebContentsViewDelegate::GestureCallback gesture_cb)
+ : BubbleDelegateView(NULL, views::BubbleBorder::FLOAT),
+ scale_(0.0f),
+ content_(content),
+ gesture_cb_(gesture_cb),
+ invalidation_cb_(invalidation_cb),
+ target_rect_(target_rect) {
+ scale_ = static_cast<float>(zoomed_skia_image->width()) /
sky 2014/07/30 21:50:36 set in member initializer list.
luken 2014/07/31 01:41:47 Done.
+ static_cast<float>(target_rect.width());
+
+ views::ImageView* image_view = new views::ImageView();
+ image_view->SetBounds(
+ 0, 0, zoomed_skia_image->width(), zoomed_skia_image->height());
+ image_view->SetImage(zoomed_skia_image);
+
+ AddChildView(image_view);
+
+ views::BubbleDelegateView::CreateBubble(this);
+}
+
+void LinkDisambiguationPopup::ZoomBubbleView::Close() {
+ invalidation_cb_.Run();
+ if (GetWidget())
+ GetWidget()->Close();
+}
+
+gfx::Size LinkDisambiguationPopup::ZoomBubbleView::GetPreferredSize() const {
+ return target_rect_.size();
+}
+
+void LinkDisambiguationPopup::ZoomBubbleView::OnGestureEvent(
+ ui::GestureEvent* event) {
+ // If we receive gesture events that are outside of our bounds we close
+ // ourselves, as perhaps the user has decided on a different part of the page.
+ if (event->location().x() > bounds().width() ||
+ event->location().y() > bounds().height()) {
+ Close();
+ return;
+ }
+
+ // Scale the gesture event back to the size of the original |target_rect_|,
+ // and then offset it to be relative to that |target_rect_| before sending
+ // it back to the callback.
+ gfx::PointF xform_location(
+ (event->location().x() / scale_) + target_rect_.x(),
+ (event->location().y() / scale_) + target_rect_.y());
+ ui::GestureEventDetails xform_details(event->details());
+ xform_details.set_bounding_box(gfx::RectF(
+ (event->details().bounding_box().x() / scale_) + target_rect_.x(),
+ (event->details().bounding_box().y() / scale_) + target_rect_.y(),
+ event->details().bounding_box().width() / scale_,
+ event->details().bounding_box().height() / scale_));
+ ui::GestureEvent xform_event(xform_location.x(),
+ xform_location.y(),
+ event->flags(),
+ event->time_stamp(),
+ xform_details);
+ gesture_cb_.Run(&xform_event);
+ event->SetHandled();
+
+ // If we completed a tap we close ourselves, as the web content will navigate
+ // if the user hit a link.
+ if (xform_event.type() == ui::EventType::ET_GESTURE_TAP)
+ Close();
+}
+
+void LinkDisambiguationPopup::ZoomBubbleView::OnWidgetDestroying(
+ views::Widget* widget) {
+ invalidation_cb_.Run();
+}
+
+LinkDisambiguationPopup::LinkDisambiguationPopup() : view_(NULL) {
sky 2014/07/30 21:50:36 initialize content_.
luken 2014/07/31 01:41:47 Done.
+}
+
+LinkDisambiguationPopup::~LinkDisambiguationPopup() {
+ Close();
+}
+
+void LinkDisambiguationPopup::Show(
+ const SkBitmap& zoomed_bitmap,
+ const gfx::Rect& target_rect,
+ const gfx::NativeView content,
+ content::WebContentsViewDelegate::GestureCallback callback) {
+ zoomed_image_ = gfx::Image::CreateFrom1xBitmap(zoomed_bitmap);
sky 2014/07/30 21:50:36 You shouldn't need to cache this. Instead make Zoo
luken 2014/07/31 01:41:46 I stopped caching it, but ToImageSkia() returns a
sky 2014/07/31 15:37:40 You can still deref (assuming non-null) and pass t
+ if (zoomed_image_.IsEmpty())
+ return;
+ content_ = content;
+
+ view_ = new ZoomBubbleView(
+ target_rect,
+ zoomed_image_.ToImageSkia(),
+ content_,
+ base::Bind(&LinkDisambiguationPopup::InvalidateBubbleView,
+ base::Unretained(this)),
sky 2014/07/30 21:50:36 view_ may live longer than this. Also, I think usi
luken 2014/07/31 01:41:46 Done.
+ callback);
+
+ // Center the zoomed bubble over the target rectangle. Since |target_rect|
+ // is provided in |content_| coordinate system, we must convert it into
+ // Screen coordinates for correct window positioning.
+ aura::client::ScreenPositionClient* screen_position_client =
+ aura::client::GetScreenPositionClient(content_->GetRootWindow());
+ gfx::Point target_screen(target_rect.x(), target_rect.y());
+ if (screen_position_client)
+ screen_position_client->ConvertPointToScreen(content_, &target_screen);
+ int bounds_x = std::max(0, target_screen.x() - (zoomed_image_.Width() / 2));
sky 2014/07/30 21:50:36 Constrain to the work area, which is not necessari
luken 2014/07/31 01:41:47 Done.
+ int bounds_y = std::max(0, target_screen.y() - (zoomed_image_.Height() / 2));
+ view_->GetWidget()->SetBounds(gfx::Rect(
+ bounds_x, bounds_y, zoomed_image_.Width(), zoomed_image_.Height()));
+ view_->GetWidget()->Show();
+ view_->GetWidget()->SetCapture(view_);
sky 2014/07/30 21:50:36 Why do you need the capture here?
luken 2014/07/31 01:41:47 I don't. Removed.
+}
+
+void LinkDisambiguationPopup::Close() {
+ if (view_) {
+ view_->Close();
+ view_ = NULL;
+ }
+}
+
+void LinkDisambiguationPopup::InvalidateBubbleView() {
+ view_ = NULL;
+}

Powered by Google App Engine
This is Rietveld 408576698