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

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: attempt to fix athena build Created 6 years, 3 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..494da416b781607326a047a77fcf01be0404a27c
--- /dev/null
+++ b/chrome/browser/ui/views/link_disambiguation/link_disambiguation_popup.cc
@@ -0,0 +1,198 @@
+// 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 "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/display.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/screen.h"
+#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/controls/image_view.h"
+
+class LinkDisambiguationPopup::ZoomBubbleView
+ : public views::BubbleDelegateView {
+ public:
+ ZoomBubbleView(const gfx::Rect& target_rect,
+ const gfx::ImageSkia* zoomed_skia_image,
+ const aura::Window* content,
+ LinkDisambiguationPopup* popup,
+ const base::Callback<void(ui::GestureEvent*)>& gesture_cb,
+ const base::Callback<void(ui::MouseEvent*)>& mouse_cb);
+
+ void Close();
+
+ private:
+ // views::View overrides
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
+ virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
+ virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE;
+
+ // WidgetObserver overrides
+ virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE;
+
+ const float scale_;
+ const aura::Window* content_;
+ const base::Callback<void(ui::GestureEvent*)> gesture_cb_;
+ const base::Callback<void(ui::MouseEvent*)> mouse_cb_;
+ LinkDisambiguationPopup* popup_;
+ const gfx::Rect target_rect_;
+
+ DISALLOW_COPY_AND_ASSIGN(ZoomBubbleView);
+};
+
+LinkDisambiguationPopup::ZoomBubbleView::ZoomBubbleView(
+ const gfx::Rect& target_rect,
+ const gfx::ImageSkia* zoomed_skia_image,
+ const aura::Window* content,
+ LinkDisambiguationPopup* popup,
+ const base::Callback<void(ui::GestureEvent*)>& gesture_cb,
+ const base::Callback<void(ui::MouseEvent*)>& mouse_cb)
+ : BubbleDelegateView(NULL, views::BubbleBorder::FLOAT),
+ scale_(static_cast<float>(zoomed_skia_image->width()) /
+ static_cast<float>(target_rect.width())),
+ content_(content),
+ gesture_cb_(gesture_cb),
+ mouse_cb_(mouse_cb),
+ popup_(popup),
+ target_rect_(target_rect) {
+ 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() {
+ if (GetWidget())
+ GetWidget()->Close();
+}
+
+gfx::Size LinkDisambiguationPopup::ZoomBubbleView::GetPreferredSize() const {
+ return target_rect_.size();
+}
+
+void LinkDisambiguationPopup::ZoomBubbleView::OnMouseEvent(
+ ui::MouseEvent* event) {
+ // Transform mouse event back to coordinate system of the web content window
+ // before providing to the callback.
+ gfx::PointF xform_location(
+ (event->location().x() / scale_) + target_rect_.x(),
+ (event->location().y() / scale_) + target_rect_.y());
+ ui::MouseEvent xform_event(event->type(), xform_location, xform_location,
+ event->flags(), event->changed_button_flags());
+ mouse_cb_.Run(&xform_event);
+ event->SetHandled();
+
+ // If user completed a click we can close the window.
+ if (event->type() == ui::EventType::ET_MOUSE_RELEASED)
+ Close();
+}
+
+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 (event->type() == ui::EventType::ET_GESTURE_TAP)
+ Close();
+}
+
+void LinkDisambiguationPopup::ZoomBubbleView::OnWidgetClosing(
+ views::Widget* widget) {
+ popup_->InvalidateBubbleView();
+}
+
+LinkDisambiguationPopup::LinkDisambiguationPopup()
+ : content_(NULL),
+ view_(NULL) {
+}
+
+LinkDisambiguationPopup::~LinkDisambiguationPopup() {
+ Close();
+}
+
+void LinkDisambiguationPopup::Show(
+ const SkBitmap& zoomed_bitmap,
+ const gfx::Rect& target_rect,
+ const gfx::NativeView content,
+ const base::Callback<void(ui::GestureEvent*)>& gesture_cb,
+ const base::Callback<void(ui::MouseEvent*)>& mouse_cb) {
+ content_ = content;
+
+ view_ = new ZoomBubbleView(
+ target_rect,
+ gfx::Image::CreateFrom1xBitmap(zoomed_bitmap).ToImageSkia(),
+ content_,
+ this,
+ gesture_cb,
+ mouse_cb);
+
+ // Center the zoomed bubble over the target rectangle, constrained to the
+ // work area in the current display. 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.width() / 2),
+ target_rect.y() + (target_rect.height() / 2));
+ if (screen_position_client)
+ screen_position_client->ConvertPointToScreen(content_, &target_screen);
+ gfx::Rect window_bounds(
+ target_screen.x() - (zoomed_bitmap.width() / 2),
+ target_screen.y() - (zoomed_bitmap.height() / 2),
+ zoomed_bitmap.width(),
+ zoomed_bitmap.height());
+ const gfx::Display display =
+ gfx::Screen::GetScreenFor(content)->GetDisplayNearestWindow(content);
+ window_bounds.AdjustToFit(display.work_area());
+ view_->GetWidget()->SetBounds(window_bounds);
+ view_->GetWidget()->Show();
+}
+
+void LinkDisambiguationPopup::Close() {
+ if (view_) {
+ view_->Close();
+ view_ = NULL;
+ }
+}
+
+void LinkDisambiguationPopup::InvalidateBubbleView() {
+ view_ = NULL;
+}

Powered by Google App Engine
This is Rietveld 408576698