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

Side by Side 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, 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2014 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 "chrome/browser/ui/views/link_disambiguation/link_disambiguation_popup. h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "ui/aura/client/screen_position_client.h"
10 #include "ui/events/event.h"
11 #include "ui/events/event_processor.h"
12 #include "ui/events/event_utils.h"
13 #include "ui/events/gesture_event_details.h"
14 #include "ui/gfx/image/image_skia.h"
15 #include "ui/views/bubble/bubble_delegate.h"
16 #include "ui/views/controls/image_view.h"
17
18 class LinkDisambiguationPopup::ZoomBubbleView
19 : public views::BubbleDelegateView {
20 public:
21 typedef base::Callback<void(void)> InvalidationCallback;
22
23 ZoomBubbleView(const gfx::Rect& target_rect,
24 const gfx::ImageSkia* zoomed_skia_image,
25 const aura::Window* content,
26 InvalidationCallback invalidation_cb,
27 content::WebContentsViewDelegate::GestureCallback gesture_cb);
28
29 void Close();
30
31 private:
32 // views::View overrides
33 virtual gfx::Size GetPreferredSize() const OVERRIDE;
34 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
35
36 // WidgetObserver overrides
37 virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
38
39 float scale_;
40 const aura::Window* content_;
41 content::WebContentsViewDelegate::GestureCallback gesture_cb_;
42 InvalidationCallback invalidation_cb_;
43 gfx::Rect target_rect_;
sky 2014/07/30 21:50:36 const
luken 2014/07/31 01:41:46 Done.
44 };
sky 2014/07/30 21:50:36 DISALLOW...
luken 2014/07/31 01:41:47 Done.
45
46 LinkDisambiguationPopup::ZoomBubbleView::ZoomBubbleView(
47 const gfx::Rect& target_rect,
48 const gfx::ImageSkia* zoomed_skia_image,
49 const aura::Window* content,
50 InvalidationCallback invalidation_cb,
51 content::WebContentsViewDelegate::GestureCallback gesture_cb)
52 : BubbleDelegateView(NULL, views::BubbleBorder::FLOAT),
53 scale_(0.0f),
54 content_(content),
55 gesture_cb_(gesture_cb),
56 invalidation_cb_(invalidation_cb),
57 target_rect_(target_rect) {
58 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.
59 static_cast<float>(target_rect.width());
60
61 views::ImageView* image_view = new views::ImageView();
62 image_view->SetBounds(
63 0, 0, zoomed_skia_image->width(), zoomed_skia_image->height());
64 image_view->SetImage(zoomed_skia_image);
65
66 AddChildView(image_view);
67
68 views::BubbleDelegateView::CreateBubble(this);
69 }
70
71 void LinkDisambiguationPopup::ZoomBubbleView::Close() {
72 invalidation_cb_.Run();
73 if (GetWidget())
74 GetWidget()->Close();
75 }
76
77 gfx::Size LinkDisambiguationPopup::ZoomBubbleView::GetPreferredSize() const {
78 return target_rect_.size();
79 }
80
81 void LinkDisambiguationPopup::ZoomBubbleView::OnGestureEvent(
82 ui::GestureEvent* event) {
83 // If we receive gesture events that are outside of our bounds we close
84 // ourselves, as perhaps the user has decided on a different part of the page.
85 if (event->location().x() > bounds().width() ||
86 event->location().y() > bounds().height()) {
87 Close();
88 return;
89 }
90
91 // Scale the gesture event back to the size of the original |target_rect_|,
92 // and then offset it to be relative to that |target_rect_| before sending
93 // it back to the callback.
94 gfx::PointF xform_location(
95 (event->location().x() / scale_) + target_rect_.x(),
96 (event->location().y() / scale_) + target_rect_.y());
97 ui::GestureEventDetails xform_details(event->details());
98 xform_details.set_bounding_box(gfx::RectF(
99 (event->details().bounding_box().x() / scale_) + target_rect_.x(),
100 (event->details().bounding_box().y() / scale_) + target_rect_.y(),
101 event->details().bounding_box().width() / scale_,
102 event->details().bounding_box().height() / scale_));
103 ui::GestureEvent xform_event(xform_location.x(),
104 xform_location.y(),
105 event->flags(),
106 event->time_stamp(),
107 xform_details);
108 gesture_cb_.Run(&xform_event);
109 event->SetHandled();
110
111 // If we completed a tap we close ourselves, as the web content will navigate
112 // if the user hit a link.
113 if (xform_event.type() == ui::EventType::ET_GESTURE_TAP)
114 Close();
115 }
116
117 void LinkDisambiguationPopup::ZoomBubbleView::OnWidgetDestroying(
118 views::Widget* widget) {
119 invalidation_cb_.Run();
120 }
121
122 LinkDisambiguationPopup::LinkDisambiguationPopup() : view_(NULL) {
sky 2014/07/30 21:50:36 initialize content_.
luken 2014/07/31 01:41:47 Done.
123 }
124
125 LinkDisambiguationPopup::~LinkDisambiguationPopup() {
126 Close();
127 }
128
129 void LinkDisambiguationPopup::Show(
130 const SkBitmap& zoomed_bitmap,
131 const gfx::Rect& target_rect,
132 const gfx::NativeView content,
133 content::WebContentsViewDelegate::GestureCallback callback) {
134 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
135 if (zoomed_image_.IsEmpty())
136 return;
137 content_ = content;
138
139 view_ = new ZoomBubbleView(
140 target_rect,
141 zoomed_image_.ToImageSkia(),
142 content_,
143 base::Bind(&LinkDisambiguationPopup::InvalidateBubbleView,
144 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.
145 callback);
146
147 // Center the zoomed bubble over the target rectangle. Since |target_rect|
148 // is provided in |content_| coordinate system, we must convert it into
149 // Screen coordinates for correct window positioning.
150 aura::client::ScreenPositionClient* screen_position_client =
151 aura::client::GetScreenPositionClient(content_->GetRootWindow());
152 gfx::Point target_screen(target_rect.x(), target_rect.y());
153 if (screen_position_client)
154 screen_position_client->ConvertPointToScreen(content_, &target_screen);
155 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.
156 int bounds_y = std::max(0, target_screen.y() - (zoomed_image_.Height() / 2));
157 view_->GetWidget()->SetBounds(gfx::Rect(
158 bounds_x, bounds_y, zoomed_image_.Width(), zoomed_image_.Height()));
159 view_->GetWidget()->Show();
160 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.
161 }
162
163 void LinkDisambiguationPopup::Close() {
164 if (view_) {
165 view_->Close();
166 view_ = NULL;
167 }
168 }
169
170 void LinkDisambiguationPopup::InvalidateBubbleView() {
171 view_ = NULL;
172 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698