OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/services/window_manager/view_target.h" | 5 #include "mojo/services/window_manager/view_target.h" |
6 | 6 |
| 7 #include "mojo/converters/geometry/geometry_type_converters.h" |
7 #include "mojo/services/public/cpp/view_manager/view.h" | 8 #include "mojo/services/public/cpp/view_manager/view.h" |
| 9 #include "mojo/services/public/cpp/view_manager/view_property.h" |
| 10 #include "mojo/services/window_manager/view_targeter.h" |
8 #include "mojo/services/window_manager/window_manager_app.h" | 11 #include "mojo/services/window_manager/window_manager_app.h" |
9 #include "ui/events/event.h" | 12 #include "ui/events/event.h" |
10 #include "ui/events/event_target_iterator.h" | 13 #include "ui/events/event_target_iterator.h" |
11 #include "ui/events/event_targeter.h" | 14 #include "ui/events/event_targeter.h" |
| 15 #include "ui/gfx/geometry/rect.h" |
| 16 #include "ui/gfx/point3_f.h" |
| 17 #include "ui/gfx/transform.h" |
12 | 18 |
13 namespace mojo { | 19 namespace mojo { |
14 | 20 |
15 class ViewTargeter : public ui::EventTargeter {}; | 21 namespace { |
16 | 22 |
17 ViewTarget::ViewTarget(WindowManagerApp* app, View* view_to_wrap) | 23 DEFINE_OWNED_VIEW_PROPERTY_KEY(ViewTarget, kViewTargetKey, nullptr); |
18 : app_(app), | 24 |
19 view_(view_to_wrap) { | 25 } // namespace |
| 26 |
| 27 ViewTarget::~ViewTarget() { |
20 } | 28 } |
21 | 29 |
22 ViewTarget::~ViewTarget() { | 30 // static |
23 // We don't own our children or |view_|. | 31 ViewTarget* ViewTarget::TargetFromView(View* view) { |
| 32 if (!view) |
| 33 return nullptr; |
| 34 |
| 35 ViewTarget* target = view->GetLocalProperty(kViewTargetKey); |
| 36 if (target) |
| 37 return target; |
| 38 |
| 39 return new ViewTarget(view); |
| 40 } |
| 41 |
| 42 void ViewTarget::ConvertPointToTarget(const ViewTarget* source, |
| 43 const ViewTarget* target, |
| 44 gfx::Point* point) { |
| 45 // TODO(erg): Do we need to deal with |source| and |target| being in |
| 46 // different trees? |
| 47 DCHECK_EQ(source->GetRoot(), target->GetRoot()); |
| 48 if (source == target) |
| 49 return; |
| 50 |
| 51 const ViewTarget* root_target = source->GetRoot(); |
| 52 CHECK_EQ(root_target, target->GetRoot()); |
| 53 |
| 54 if (source != root_target) |
| 55 source->ConvertPointForAncestor(root_target, point); |
| 56 if (target != root_target) |
| 57 target->ConvertPointFromAncestor(root_target, point); |
| 58 } |
| 59 |
| 60 std::vector<ViewTarget*> ViewTarget::GetChildren() { |
| 61 std::vector<ViewTarget*> targets; |
| 62 for (View* child : view_->children()) |
| 63 targets.push_back(TargetFromView(child)); |
| 64 return targets; |
| 65 } |
| 66 |
| 67 const ViewTarget* ViewTarget::GetParent() const { |
| 68 return TargetFromView(view_->parent()); |
| 69 } |
| 70 |
| 71 gfx::Rect ViewTarget::GetBounds() const { |
| 72 return view_->bounds().To<gfx::Rect>(); |
24 } | 73 } |
25 | 74 |
26 bool ViewTarget::HasParent() const { | 75 bool ViewTarget::HasParent() const { |
27 return !!view_->parent(); | 76 return !!view_->parent(); |
28 } | 77 } |
29 | 78 |
30 bool ViewTarget::IsVisible() const { | 79 bool ViewTarget::IsVisible() const { |
31 return view_->visible(); | 80 return view_->visible(); |
32 } | 81 } |
33 | 82 |
34 void ViewTarget::AddChild(ViewTarget* view) { | 83 const ViewTarget* ViewTarget::GetRoot() const { |
35 children_.push_back(view); | 84 const ViewTarget* root = this; |
| 85 for (; root; root = root->GetParent()) { |
| 86 } |
| 87 return root; |
36 } | 88 } |
37 | 89 |
38 scoped_ptr<ViewTargeter> ViewTarget::SetEventTargeter( | 90 scoped_ptr<ViewTargeter> ViewTarget::SetEventTargeter( |
39 scoped_ptr<ViewTargeter> targeter) { | 91 scoped_ptr<ViewTargeter> targeter) { |
40 scoped_ptr<ViewTargeter> old_targeter = targeter_.Pass(); | 92 scoped_ptr<ViewTargeter> old_targeter = targeter_.Pass(); |
41 targeter_ = targeter.Pass(); | 93 targeter_ = targeter.Pass(); |
42 return old_targeter.Pass(); | 94 return old_targeter.Pass(); |
43 } | 95 } |
44 | 96 |
45 bool ViewTarget::CanAcceptEvent(const ui::Event& event) { | 97 bool ViewTarget::CanAcceptEvent(const ui::Event& event) { |
46 // We need to make sure that a touch cancel event and any gesture events it | 98 // We need to make sure that a touch cancel event and any gesture events it |
47 // creates can always reach the window. This ensures that we receive a valid | 99 // creates can always reach the window. This ensures that we receive a valid |
48 // touch / gesture stream. | 100 // touch / gesture stream. |
49 if (event.IsEndingEvent()) | 101 if (event.IsEndingEvent()) |
50 return true; | 102 return true; |
51 | 103 |
52 if (!view_->visible()) | 104 if (!view_->visible()) |
53 return false; | 105 return false; |
54 | 106 |
55 // The top-most window can always process an event. | 107 // The top-most window can always process an event. |
56 if (!view_->parent()) | 108 if (!view_->parent()) |
57 return true; | 109 return true; |
58 | 110 |
59 // For located events (i.e. mouse, touch etc.), an assumption is made that | 111 // In aura, we only accept events if this is a key event or if the user |
60 // windows that don't have a default event-handler cannot process the event | 112 // supplied a TargetHandler, usually the aura::WindowDelegate. Here, we're |
61 // (see more in GetWindowForPoint()). This assumption is not made for key | 113 // just forwarding events to other Views which may be in other processes, so |
62 // events. | 114 // always accept. |
63 return event.IsKeyEvent() || target_handler(); | 115 return true; |
64 } | 116 } |
65 | 117 |
66 ui::EventTarget* ViewTarget::GetParentTarget() { | 118 ui::EventTarget* ViewTarget::GetParentTarget() { |
67 if (!view_->parent()) { | 119 return TargetFromView(view_->parent()); |
68 // We are the root node. | |
69 return nullptr; | |
70 } | |
71 | |
72 return app_->GetViewTargetForViewId(view_->parent()->id()); | |
73 } | 120 } |
74 | 121 |
75 scoped_ptr<ui::EventTargetIterator> ViewTarget::GetChildIterator() const { | 122 scoped_ptr<ui::EventTargetIterator> ViewTarget::GetChildIterator() { |
76 return scoped_ptr<ui::EventTargetIterator>( | 123 return scoped_ptr<ui::EventTargetIterator>( |
77 new ui::EventTargetIteratorImpl<ViewTarget>(children_)); | 124 new ui::CopyingEventTargetIteratorImpl<ViewTarget>(GetChildren())); |
78 } | 125 } |
79 | 126 |
80 ui::EventTargeter* ViewTarget::GetEventTargeter() { | 127 ui::EventTargeter* ViewTarget::GetEventTargeter() { |
81 return targeter_.get(); | 128 return targeter_.get(); |
82 } | 129 } |
83 | 130 |
84 void ViewTarget::ConvertEventToTarget(ui::EventTarget* target, | 131 void ViewTarget::ConvertEventToTarget(ui::EventTarget* target, |
85 ui::LocatedEvent* event) { | 132 ui::LocatedEvent* event) { |
86 // TODO(erg): Actually doing enabling this line requires doing some partially | 133 event->ConvertLocationToTarget(this, static_cast<ViewTarget*>(target)); |
87 // specialized template cruft. Punt for now. | 134 } |
88 // | 135 |
89 // event->ConvertLocationToTarget(this, | 136 ViewTarget::ViewTarget(View* view_to_wrap) : view_(view_to_wrap) { |
90 // static_cast<ViewTarget*>(target)); | 137 DCHECK(view_->GetLocalProperty(kViewTargetKey) == nullptr); |
| 138 view_->SetLocalProperty(kViewTargetKey, this); |
| 139 } |
| 140 |
| 141 bool ViewTarget::ConvertPointForAncestor(const ViewTarget* ancestor, |
| 142 gfx::Point* point) const { |
| 143 gfx::Vector2d offset; |
| 144 bool result = GetTargetOffsetRelativeTo(ancestor, &offset); |
| 145 *point += offset; |
| 146 return result; |
| 147 } |
| 148 |
| 149 bool ViewTarget::ConvertPointFromAncestor(const ViewTarget* ancestor, |
| 150 gfx::Point* point) const { |
| 151 gfx::Vector2d offset; |
| 152 bool result = GetTargetOffsetRelativeTo(ancestor, &offset); |
| 153 *point -= offset; |
| 154 return result; |
| 155 } |
| 156 |
| 157 bool ViewTarget::GetTargetOffsetRelativeTo(const ViewTarget* ancestor, |
| 158 gfx::Vector2d* offset) const { |
| 159 const ViewTarget* v = this; |
| 160 for (; v && v != ancestor; v = v->GetParent()) { |
| 161 gfx::Rect bounds = v->GetBounds(); |
| 162 *offset += gfx::Vector2d(bounds.x(), bounds.y()); |
| 163 } |
| 164 return v == ancestor; |
91 } | 165 } |
92 | 166 |
93 } // namespace mojo | 167 } // namespace mojo |
OLD | NEW |