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 "ash/magnifier/partial_magnification_controller.h" | |
6 | |
7 #include "ash/shell.h" | |
8 #include "ui/aura/event_filter.h" | |
9 #include "ui/aura/root_window.h" | |
10 #include "ui/aura/shared/compound_event_filter.h" | |
11 #include "ui/aura/window.h" | |
12 #include "ui/aura/window_observer.h" | |
13 #include "ui/aura/window_property.h" | |
14 #include "ui/gfx/point3.h" | |
15 #include "ui/gfx/screen.h" | |
16 #include "ui/compositor/layer.h" | |
17 #include "ui/views/widget/widget.h" | |
18 #include "ui/views/widget/widget_delegate.h" | |
19 | |
20 namespace { | |
21 | |
22 const float kMinPartialMagnifiedScaleThreshold = 1.1f; | |
23 const int kZoomInset = 16; | |
24 const int kMagnifierWidth = 200; | |
25 const int kMagnifierHeight = 200; | |
oshima
2012/09/13 16:35:31
doument
Zachary Kuznia
2012/10/09 09:02:36
Done.
| |
26 | |
27 } // namespace | |
28 | |
29 namespace ash { | |
30 namespace internal { | |
31 | |
32 class ZoomDelegateView : public views::WidgetDelegateView { | |
33 public: | |
34 explicit ZoomDelegateView(); | |
oshima
2012/09/13 16:35:31
remove explicit
Zachary Kuznia
2012/10/09 09:02:36
Done.
| |
35 virtual ~ZoomDelegateView(); | |
36 | |
37 // views::View overrides | |
38 virtual gfx::Size GetPreferredSize() OVERRIDE; | |
39 virtual void Layout() OVERRIDE; | |
40 | |
41 // views::WidgetZoomDelegateView overrides: | |
42 virtual bool CanActivate() const OVERRIDE { | |
43 return false; | |
44 } | |
45 | |
46 private: | |
47 | |
48 DISALLOW_COPY_AND_ASSIGN(ZoomDelegateView); | |
49 }; | |
50 | |
51 ZoomDelegateView::ZoomDelegateView() { | |
52 } | |
53 | |
54 ZoomDelegateView::~ZoomDelegateView() { | |
55 } | |
56 | |
57 gfx::Size ZoomDelegateView::GetPreferredSize() { | |
58 return child_count() > 0 ? child_at(0)->GetPreferredSize() : gfx::Size(); | |
59 } | |
60 | |
61 void ZoomDelegateView::Layout() { | |
62 if (child_count() == 0) | |
63 return; | |
64 child_at(0)->SetBounds(0, 0, width(), height()); | |
65 } | |
66 | |
67 | |
68 //////////////////////////////////////////////////////////////////////////////// | |
69 // PartialMagnificationControllerImpl: | |
70 | |
71 class PartialMagnificationControllerImpl | |
72 : public PartialMagnificationController, | |
73 public aura::EventFilter, | |
74 public aura::WindowObserver { | |
75 public: | |
76 PartialMagnificationControllerImpl(); | |
77 virtual ~PartialMagnificationControllerImpl(); | |
78 | |
79 // PartialMagnificationController overrides: | |
80 virtual void SetEnabled(bool enabled) OVERRIDE; | |
81 virtual bool IsEnabled() OVERRIDE; | |
82 virtual void SetScale(float scale) OVERRIDE; | |
83 virtual float GetScale() const OVERRIDE { return scale_; } | |
84 | |
85 private: | |
86 void OnMouseMove(const gfx::Point& location); | |
87 | |
88 // Switch PartialMagnified RootWindow to |new_root_window|. This does | |
89 // following: | |
90 // - Remove the magnifier from the current root window. | |
91 // - Create a magnifier in the new root_window |new_root_window|. | |
92 // - Switch the target window from current window to |new_root_window|. | |
93 void SwitchTargetRootWindow(aura::RootWindow* new_root_window); | |
94 | |
95 // Removes self as observer of old root window, sets the root window, and adds | |
96 // self as observer of the new window. | |
97 void SetRootWindow(aura::RootWindow* root_window); | |
98 | |
99 // Return true if the magnification scale > kMinPartialMagnifiedScaleThreshold | |
100 bool IsPartialMagnified() const; | |
101 | |
102 // Cleans up the window if needed. | |
103 void CloseMagnifierWindow(); | |
104 | |
105 // aura::EventFilter overrides: | |
106 virtual bool PreHandleKeyEvent(aura::Window* target, | |
107 ui::KeyEvent* event) OVERRIDE; | |
108 virtual bool PreHandleMouseEvent(aura::Window* target, | |
109 ui::MouseEvent* event) OVERRIDE; | |
110 virtual ui::TouchStatus PreHandleTouchEvent( | |
111 aura::Window* target, | |
112 ui::TouchEvent* event) OVERRIDE; | |
113 virtual ui::EventResult PreHandleGestureEvent( | |
114 aura::Window* target, | |
115 ui::GestureEvent* event) OVERRIDE; | |
116 | |
117 // Overridden from WindowObserver: | |
118 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE; | |
119 | |
120 aura::RootWindow* root_window_; | |
121 | |
122 // True if the magnified window is in motion of zooming or un-zooming effect. | |
123 // Otherwise, false. | |
124 bool is_on_zooming_; | |
125 | |
126 bool is_enabled_; | |
127 | |
128 // Current scale, origin (left-top) position of the magnification window. | |
129 float scale_; | |
130 gfx::Point origin_; | |
131 | |
132 aura::Window* zoom_window_; | |
133 views::Widget* zoom_widget_; | |
134 | |
135 DISALLOW_COPY_AND_ASSIGN(PartialMagnificationControllerImpl); | |
136 }; | |
137 | |
138 //////////////////////////////////////////////////////////////////////////////// | |
139 // PartialMagnificationControllerImpl: | |
140 | |
141 PartialMagnificationControllerImpl::PartialMagnificationControllerImpl() | |
142 : root_window_(NULL), | |
143 is_on_zooming_(false), | |
144 is_enabled_(false), | |
145 scale_(kNonPartialMagnifiedScale), | |
146 zoom_window_(NULL), | |
147 zoom_widget_(NULL) { | |
148 Shell::GetInstance()->AddEnvEventFilter(this); | |
149 } | |
150 | |
151 PartialMagnificationControllerImpl::~PartialMagnificationControllerImpl() { | |
152 CloseMagnifierWindow(); | |
153 | |
154 Shell::GetInstance()->RemoveEnvEventFilter(this); | |
155 } | |
156 | |
157 void PartialMagnificationControllerImpl::OnMouseMove( | |
158 const gfx::Point& location) { | |
159 int x = location.x(); | |
160 int y = location.y(); | |
oshima
2012/09/13 16:35:31
or you can use gfx::Point::Offset. up to you.
Zachary Kuznia
2012/10/09 09:02:36
Done.
| |
161 | |
162 if (zoom_window_) | |
163 zoom_widget_->SetBounds(gfx::Rect(x - kMagnifierWidth / 2, | |
164 y - kMagnifierHeight / 2, | |
165 kMagnifierWidth, kMagnifierHeight)); | |
166 } | |
167 | |
168 bool PartialMagnificationControllerImpl::IsPartialMagnified() const { | |
169 return scale_ >= kMinPartialMagnifiedScaleThreshold; | |
170 } | |
171 | |
172 void PartialMagnificationControllerImpl::CloseMagnifierWindow() { | |
173 if (zoom_window_) { | |
174 zoom_widget_->Close(); | |
175 delete zoom_window_; | |
176 zoom_window_ = NULL; | |
177 zoom_widget_ = NULL; | |
178 } | |
179 } | |
180 | |
181 void PartialMagnificationControllerImpl::SwitchTargetRootWindow( | |
182 aura::RootWindow* new_root_window) { | |
183 if (new_root_window == root_window_) | |
184 return; | |
185 | |
186 float scale = GetScale(); | |
187 | |
188 SetScale(1.0f); | |
189 SetRootWindow(new_root_window); | |
190 SetScale(scale); | |
191 } | |
192 | |
193 void PartialMagnificationControllerImpl::SetRootWindow( | |
194 aura::RootWindow* root_window) { | |
195 if (root_window_) | |
196 root_window_->RemoveObserver(this); | |
197 | |
198 root_window_ = root_window; | |
199 if (root_window_) | |
200 root_window_->AddObserver(this); | |
201 } | |
202 | |
203 | |
204 //////////////////////////////////////////////////////////////////////////////// | |
205 // PartialMagnificationControllerImpl: | |
206 // PartialMagnificationController implementation | |
207 | |
208 void PartialMagnificationControllerImpl::SetScale(float scale) { | |
209 if (!is_enabled_) | |
210 return; | |
211 | |
212 scale_ = scale; | |
213 | |
214 if (IsPartialMagnified()) { | |
215 if (!zoom_window_) { | |
216 if (!root_window_) | |
217 SetRootWindow(ash::Shell::GetActiveRootWindow()); | |
oshima
2012/09/13 16:35:31
Don't you want to use root window where the mouse
Zachary Kuznia
2012/10/09 09:02:36
What is the proper way to get that window? Check
| |
218 | |
219 gfx::Point mouse(root_window_->GetLastMouseLocationInRoot()); | |
220 | |
221 zoom_window_ = new aura::Window(NULL); | |
222 zoom_window_->Init(ui::LAYER_NOT_DRAWN); | |
223 root_window_->AddChild(zoom_window_); | |
oshima
2012/09/13 16:35:31
to which container this will be added? Will this s
Zachary Kuznia
2012/10/09 09:02:36
It's added after the containers, so that it should
| |
224 | |
225 zoom_widget_ = new views::Widget; | |
226 views::Widget::InitParams params( | |
227 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); | |
228 params.transparent = true; | |
229 params.parent = zoom_window_; | |
230 ZoomDelegateView* delegate_view = new ZoomDelegateView; | |
231 params.delegate = delegate_view; | |
232 zoom_widget_->Init(params); | |
233 zoom_widget_->SetBounds(gfx::Rect(mouse.x() - kMagnifierWidth / 2, | |
234 mouse.y() - kMagnifierHeight / 2, | |
235 kMagnifierWidth, kMagnifierHeight)); | |
236 zoom_widget_->set_focus_on_creation(false); | |
237 zoom_widget_->SetContentsView(delegate_view); | |
238 zoom_widget_->Show(); | |
239 zoom_window_->layer()->SetBounds(gfx::Rect(0, 0, | |
240 kMagnifierWidth, | |
241 kMagnifierHeight)); | |
242 zoom_window_->Show(); | |
243 | |
244 zoom_widget_->GetNativeView()->layer()->SetBackgroundZoom( | |
245 (kMagnifierWidth - (kMagnifierWidth / scale_)) / 2, | |
246 (kMagnifierHeight - (kMagnifierHeight / scale_)) / 2, | |
247 scale_, | |
248 kZoomInset); | |
249 } | |
250 } else { | |
251 CloseMagnifierWindow(); | |
252 } | |
253 } | |
254 | |
255 void PartialMagnificationControllerImpl::SetEnabled(bool enabled) { | |
256 if (enabled) { | |
257 is_enabled_ = enabled; | |
258 SetScale(kDefaultPartialMagnifiedScale); | |
259 } else { | |
260 SetScale(kNonPartialMagnifiedScale); | |
261 is_enabled_ = enabled; | |
262 } | |
263 } | |
264 | |
265 bool PartialMagnificationControllerImpl::IsEnabled() { | |
266 return is_enabled_; | |
267 } | |
268 | |
269 | |
270 //////////////////////////////////////////////////////////////////////////////// | |
271 // PartialMagnificationControllerImpl: aura::EventFilter implementation | |
272 | |
273 bool PartialMagnificationControllerImpl::PreHandleKeyEvent( | |
274 aura::Window* target, | |
275 ui::KeyEvent* event) { | |
276 return false; | |
277 } | |
278 | |
279 bool PartialMagnificationControllerImpl::PreHandleMouseEvent( | |
280 aura::Window* target, | |
281 ui::MouseEvent* event) { | |
282 if (event->type() == ui::ET_SCROLL && event->IsAltDown()) { | |
283 ui::ScrollEvent* scroll_event = static_cast<ui::ScrollEvent*>(event); | |
284 if (scroll_event->y_offset() > 0) | |
285 SetScale(kDefaultPartialMagnifiedScale); | |
286 else | |
287 SetScale(1); | |
288 | |
289 return true; | |
290 } | |
291 | |
292 if (IsPartialMagnified() && event->type() == ui::ET_MOUSE_MOVED) { | |
293 aura::RootWindow* current_root = target->GetRootWindow(); | |
oshima
2012/09/13 16:35:31
IIRC, target can be on different root when input i
Zachary Kuznia
2012/10/09 09:02:36
It seems to work properly with menus.
| |
294 gfx::Rect root_bounds = current_root->bounds(); | |
295 | |
296 if (root_bounds.Contains(event->root_location())) { | |
297 if (current_root != root_window_) | |
298 SwitchTargetRootWindow(current_root); | |
299 | |
300 OnMouseMove(event->root_location()); | |
301 } | |
302 } | |
303 | |
304 return false; | |
305 } | |
306 | |
307 ui::TouchStatus PartialMagnificationControllerImpl::PreHandleTouchEvent( | |
308 aura::Window* target, | |
309 ui::TouchEvent* event) { | |
310 return ui::TOUCH_STATUS_UNKNOWN; | |
311 } | |
312 | |
313 ui::EventResult PartialMagnificationControllerImpl::PreHandleGestureEvent( | |
314 aura::Window* target, | |
315 ui::GestureEvent* event) { | |
316 return ui::ER_UNHANDLED; | |
317 } | |
318 | |
319 //////////////////////////////////////////////////////////////////////////////// | |
320 // PartialMagnificationControllerImpl: aura::WindowObserver implementation | |
321 | |
322 void PartialMagnificationControllerImpl::OnWindowDestroying( | |
323 aura::Window* window) { | |
324 aura::RootWindow* new_root_window = ash::Shell::GetActiveRootWindow(); | |
325 | |
326 if (new_root_window == root_window_) | |
327 new_root_window = ash::Shell::GetPrimaryRootWindow(); | |
328 | |
329 if (new_root_window == root_window_) | |
330 new_root_window = NULL; | |
331 | |
332 SetRootWindow(new_root_window); | |
333 } | |
334 | |
335 //////////////////////////////////////////////////////////////////////////////// | |
336 // PartialMagnificationController: | |
337 | |
338 // static | |
339 PartialMagnificationController* | |
340 PartialMagnificationController::CreateInstance() { | |
341 return new PartialMagnificationControllerImpl(); | |
342 } | |
343 | |
344 } // namespace internal | |
345 } // namespace ash | |
OLD | NEW |