OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "mojo/services/window_manager/view_target.h" |
| 6 |
| 7 #include "mojo/converters/geometry/geometry_type_converters.h" |
| 8 #include "mojo/services/window_manager/view_targeter.h" |
| 9 #include "mojo/services/window_manager/window_manager_app.h" |
| 10 #include "third_party/mojo_services/src/view_manager/public/cpp/view.h" |
| 11 #include "third_party/mojo_services/src/view_manager/public/cpp/view_property.h" |
| 12 #include "ui/events/event.h" |
| 13 #include "ui/events/event_target_iterator.h" |
| 14 #include "ui/events/event_targeter.h" |
| 15 #include "ui/gfx/geometry/point3_f.h" |
| 16 #include "ui/gfx/geometry/rect.h" |
| 17 #include "ui/gfx/transform.h" |
| 18 |
| 19 namespace window_manager { |
| 20 |
| 21 namespace { |
| 22 |
| 23 DEFINE_OWNED_VIEW_PROPERTY_KEY(ViewTarget, kViewTargetKey, nullptr); |
| 24 |
| 25 // Provides a version which keeps a copy of the data (for when it has to be |
| 26 // derived instead of pointed at). |
| 27 template <typename T> |
| 28 class CopyingEventTargetIteratorImpl : public ui::EventTargetIterator { |
| 29 public: |
| 30 explicit CopyingEventTargetIteratorImpl(const std::vector<T*>& children) |
| 31 : children_(children), |
| 32 begin_(children_.rbegin()), |
| 33 end_(children_.rend()) {} |
| 34 ~CopyingEventTargetIteratorImpl() override {} |
| 35 |
| 36 ui::EventTarget* GetNextTarget() override { |
| 37 if (begin_ == end_) |
| 38 return nullptr; |
| 39 ui::EventTarget* target = *(begin_); |
| 40 ++begin_; |
| 41 return target; |
| 42 } |
| 43 |
| 44 private: |
| 45 typename std::vector<T*> children_; |
| 46 typename std::vector<T*>::const_reverse_iterator begin_; |
| 47 typename std::vector<T*>::const_reverse_iterator end_; |
| 48 }; |
| 49 |
| 50 } // namespace |
| 51 |
| 52 ViewTarget::~ViewTarget() { |
| 53 } |
| 54 |
| 55 // static |
| 56 ViewTarget* ViewTarget::TargetFromView(mojo::View* view) { |
| 57 if (!view) |
| 58 return nullptr; |
| 59 |
| 60 ViewTarget* target = view->GetLocalProperty(kViewTargetKey); |
| 61 if (target) |
| 62 return target; |
| 63 |
| 64 return new ViewTarget(view); |
| 65 } |
| 66 |
| 67 void ViewTarget::ConvertPointToTarget(const ViewTarget* source, |
| 68 const ViewTarget* target, |
| 69 gfx::Point* point) { |
| 70 // TODO(erg): Do we need to deal with |source| and |target| being in |
| 71 // different trees? |
| 72 DCHECK_EQ(source->GetRoot(), target->GetRoot()); |
| 73 if (source == target) |
| 74 return; |
| 75 |
| 76 const ViewTarget* root_target = source->GetRoot(); |
| 77 CHECK_EQ(root_target, target->GetRoot()); |
| 78 |
| 79 if (source != root_target) |
| 80 source->ConvertPointForAncestor(root_target, point); |
| 81 if (target != root_target) |
| 82 target->ConvertPointFromAncestor(root_target, point); |
| 83 } |
| 84 |
| 85 std::vector<ViewTarget*> ViewTarget::GetChildren() const { |
| 86 std::vector<ViewTarget*> targets; |
| 87 for (mojo::View* child : view_->children()) |
| 88 targets.push_back(TargetFromView(child)); |
| 89 return targets; |
| 90 } |
| 91 |
| 92 const ViewTarget* ViewTarget::GetParent() const { |
| 93 return TargetFromView(view_->parent()); |
| 94 } |
| 95 |
| 96 gfx::Rect ViewTarget::GetBounds() const { |
| 97 return view_->bounds().To<gfx::Rect>(); |
| 98 } |
| 99 |
| 100 bool ViewTarget::HasParent() const { |
| 101 return !!view_->parent(); |
| 102 } |
| 103 |
| 104 bool ViewTarget::IsVisible() const { |
| 105 return view_->visible(); |
| 106 } |
| 107 |
| 108 const ViewTarget* ViewTarget::GetRoot() const { |
| 109 const ViewTarget* root = this; |
| 110 for (const ViewTarget* parent = this; parent; parent = parent->GetParent()) |
| 111 root = parent; |
| 112 return root; |
| 113 } |
| 114 |
| 115 scoped_ptr<ViewTargeter> ViewTarget::SetEventTargeter( |
| 116 scoped_ptr<ViewTargeter> targeter) { |
| 117 scoped_ptr<ViewTargeter> old_targeter = targeter_.Pass(); |
| 118 targeter_ = targeter.Pass(); |
| 119 return old_targeter.Pass(); |
| 120 } |
| 121 |
| 122 bool ViewTarget::CanAcceptEvent(const ui::Event& event) { |
| 123 // We need to make sure that a touch cancel event and any gesture events it |
| 124 // creates can always reach the window. This ensures that we receive a valid |
| 125 // touch / gesture stream. |
| 126 if (event.IsEndingEvent()) |
| 127 return true; |
| 128 |
| 129 if (!view_->visible()) |
| 130 return false; |
| 131 |
| 132 // The top-most window can always process an event. |
| 133 if (!view_->parent()) |
| 134 return true; |
| 135 |
| 136 // In aura, we only accept events if this is a key event or if the user |
| 137 // supplied a TargetHandler, usually the aura::WindowDelegate. Here, we're |
| 138 // just forwarding events to other Views which may be in other processes, so |
| 139 // always accept. |
| 140 return true; |
| 141 } |
| 142 |
| 143 ui::EventTarget* ViewTarget::GetParentTarget() { |
| 144 return TargetFromView(view_->parent()); |
| 145 } |
| 146 |
| 147 scoped_ptr<ui::EventTargetIterator> ViewTarget::GetChildIterator() const { |
| 148 return scoped_ptr<ui::EventTargetIterator>( |
| 149 new CopyingEventTargetIteratorImpl<ViewTarget>(GetChildren())); |
| 150 } |
| 151 |
| 152 ui::EventTargeter* ViewTarget::GetEventTargeter() { |
| 153 return targeter_.get(); |
| 154 } |
| 155 |
| 156 void ViewTarget::ConvertEventToTarget(ui::EventTarget* target, |
| 157 ui::LocatedEvent* event) { |
| 158 event->ConvertLocationToTarget(this, static_cast<ViewTarget*>(target)); |
| 159 } |
| 160 |
| 161 ViewTarget::ViewTarget(mojo::View* view_to_wrap) : view_(view_to_wrap) { |
| 162 DCHECK(view_->GetLocalProperty(kViewTargetKey) == nullptr); |
| 163 view_->SetLocalProperty(kViewTargetKey, this); |
| 164 } |
| 165 |
| 166 bool ViewTarget::ConvertPointForAncestor(const ViewTarget* ancestor, |
| 167 gfx::Point* point) const { |
| 168 gfx::Vector2d offset; |
| 169 bool result = GetTargetOffsetRelativeTo(ancestor, &offset); |
| 170 *point += offset; |
| 171 return result; |
| 172 } |
| 173 |
| 174 bool ViewTarget::ConvertPointFromAncestor(const ViewTarget* ancestor, |
| 175 gfx::Point* point) const { |
| 176 gfx::Vector2d offset; |
| 177 bool result = GetTargetOffsetRelativeTo(ancestor, &offset); |
| 178 *point -= offset; |
| 179 return result; |
| 180 } |
| 181 |
| 182 bool ViewTarget::GetTargetOffsetRelativeTo(const ViewTarget* ancestor, |
| 183 gfx::Vector2d* offset) const { |
| 184 const ViewTarget* v = this; |
| 185 for (; v && v != ancestor; v = v->GetParent()) { |
| 186 gfx::Rect bounds = v->GetBounds(); |
| 187 *offset += gfx::Vector2d(bounds.x(), bounds.y()); |
| 188 } |
| 189 return v == ancestor; |
| 190 } |
| 191 |
| 192 } // namespace window_manager |
OLD | NEW |