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/view_manager/node.h" | 5 #include "mojo/services/view_manager/node.h" |
6 | 6 |
7 #include "mojo/services/view_manager/node_delegate.h" | 7 #include "mojo/services/view_manager/node_delegate.h" |
8 #include "ui/aura/window_property.h" | |
9 #include "ui/base/cursor/cursor.h" | |
10 #include "ui/base/hit_test.h" | |
11 #include "ui/compositor/layer.h" | |
12 #include "ui/gfx/canvas.h" | |
13 #include "ui/gfx/image/image_skia.h" | |
14 #include "ui/gfx/native_widget_types.h" | |
15 | |
16 DECLARE_WINDOW_PROPERTY_TYPE(mojo::service::Node*); | |
17 | 8 |
18 namespace mojo { | 9 namespace mojo { |
19 namespace service { | 10 namespace service { |
20 | 11 |
21 DEFINE_WINDOW_PROPERTY_KEY(Node*, kNodeKey, NULL); | |
22 | |
23 Node::Node(NodeDelegate* delegate, const NodeId& id) | 12 Node::Node(NodeDelegate* delegate, const NodeId& id) |
24 : delegate_(delegate), | 13 : delegate_(delegate), |
25 id_(id), | 14 id_(id), |
26 window_(this) { | 15 parent_(NULL), |
16 visible_(true) { | |
27 DCHECK(delegate); // Must provide a delegate. | 17 DCHECK(delegate); // Must provide a delegate. |
28 window_.set_owned_by_parent(false); | |
29 window_.AddObserver(this); | |
30 window_.SetProperty(kNodeKey, this); | |
31 window_.Init(aura::WINDOW_LAYER_TEXTURED); | |
32 | |
33 // TODO(sky): this likely needs to be false and add a visibility API. | |
34 window_.Show(); | |
35 } | 18 } |
36 | 19 |
37 Node::~Node() { | 20 Node::~Node() { |
38 // This is implicitly done during deletion of the window, but we do it here so | 21 while (!children_.empty()) |
39 // that we're in a known state. | 22 children_.front()->parent()->Remove(children_.front()); |
40 if (window_.parent()) | 23 |
41 window_.parent()->RemoveChild(&window_); | 24 if (parent_) |
25 parent_->Remove(this); | |
42 | 26 |
43 delegate_->OnNodeDestroyed(this); | 27 delegate_->OnNodeDestroyed(this); |
44 } | 28 } |
45 | 29 |
46 // static | 30 void Node::Add(Node* child) { |
47 Node* Node::NodeForWindow(aura::Window* window) { | 31 // We assume validation checks happened already. |
48 return window->GetProperty(kNodeKey); | 32 DCHECK(child && child != this && !child->Contains(this)); |
jamesr
2014/08/26 04:51:25
nit: if one of these checks fail it'll be pretty h
sky
2014/08/26 13:10:54
Done (here and similar).
| |
49 } | 33 if (child->parent() == this) { |
34 if (children_.size() == 1) | |
35 return; // Already in the right position. | |
36 Reorder(child, children_.back(), ORDER_DIRECTION_ABOVE); | |
37 return; | |
38 } | |
50 | 39 |
51 const Node* Node::GetParent() const { | 40 const Node* old_parent = child->parent(); |
52 if (!window_.parent()) | 41 if (child->parent()) |
53 return NULL; | 42 child->parent()->RemoveImpl(child); |
54 return window_.parent()->GetProperty(kNodeKey); | |
55 } | |
56 | 43 |
57 void Node::Add(Node* child) { | 44 child->parent_ = this; |
58 window_.AddChild(&child->window_); | 45 children_.push_back(child); |
46 child->delegate_->OnNodeHierarchyChanged(child, this, old_parent); | |
59 } | 47 } |
60 | 48 |
61 void Node::Remove(Node* child) { | 49 void Node::Remove(Node* child) { |
62 window_.RemoveChild(&child->window_); | 50 // We assume validation checks happened else where. |
51 DCHECK(child && child != this && child->parent() == this); | |
52 | |
53 RemoveImpl(child); | |
54 child->delegate_->OnNodeHierarchyChanged(child, NULL, this); | |
63 } | 55 } |
64 | 56 |
65 void Node::Reorder(Node* child, Node* relative, OrderDirection direction) { | 57 void Node::Reorder(Node* child, Node* relative, OrderDirection direction) { |
66 if (direction == ORDER_DIRECTION_ABOVE) | 58 // We assume validation checks happened else where. |
67 window_.StackChildAbove(child->window(), relative->window()); | 59 DCHECK(child && child->parent() == this && children_.size() > 1); |
68 else if (direction == ORDER_DIRECTION_BELOW) | 60 children_.erase(std::find(children_.begin(), children_.end(), child)); |
69 window_.StackChildBelow(child->window(), relative->window()); | 61 Nodes::iterator i = std::find(children_.begin(), children_.end(), relative); |
62 if (direction == ORDER_DIRECTION_ABOVE) { | |
63 DCHECK(i != children_.end()); | |
64 children_.insert(++i, child); | |
65 } else if (direction == ORDER_DIRECTION_BELOW) { | |
66 DCHECK(i != children_.end()); | |
67 children_.insert(i, child); | |
68 } | |
69 } | |
70 | |
71 void Node::SetBounds(const gfx::Rect& bounds) { | |
72 if (bounds_ == bounds) | |
73 return; | |
74 | |
75 const gfx::Rect old_bounds = bounds_; | |
76 bounds_ = bounds; | |
77 delegate_->OnNodeBoundsChanged(this, old_bounds, bounds); | |
70 } | 78 } |
71 | 79 |
72 const Node* Node::GetRoot() const { | 80 const Node* Node::GetRoot() const { |
73 const aura::Window* window = &window_; | 81 const Node* node = this; |
74 while (window && window->parent()) | 82 while (node && node->parent()) |
75 window = window->parent(); | 83 node = node->parent(); |
76 return window->GetProperty(kNodeKey); | 84 return node; |
77 } | 85 } |
78 | 86 |
79 std::vector<const Node*> Node::GetChildren() const { | 87 std::vector<const Node*> Node::GetChildren() const { |
80 std::vector<const Node*> children; | 88 std::vector<const Node*> children; |
81 children.reserve(window_.children().size()); | 89 children.reserve(children_.size()); |
82 for (size_t i = 0; i < window_.children().size(); ++i) | 90 for (size_t i = 0; i < children_.size(); ++i) |
83 children.push_back(window_.children()[i]->GetProperty(kNodeKey)); | 91 children.push_back(children_[i]); |
84 return children; | 92 return children; |
85 } | 93 } |
86 | 94 |
87 std::vector<Node*> Node::GetChildren() { | 95 std::vector<Node*> Node::GetChildren() { |
88 std::vector<Node*> children; | 96 // TODO(sky): rename to children() and fix return type. |
89 children.reserve(window_.children().size()); | 97 return children_; |
90 for (size_t i = 0; i < window_.children().size(); ++i) | |
91 children.push_back(window_.children()[i]->GetProperty(kNodeKey)); | |
92 return children; | |
93 } | 98 } |
94 | 99 |
95 bool Node::Contains(const Node* node) const { | 100 bool Node::Contains(const Node* node) const { |
96 return node && window_.Contains(&(node->window_)); | 101 for (const Node* parent = node; parent; parent = parent->parent_) { |
97 } | 102 if (parent == this) |
98 | 103 return true; |
99 bool Node::IsVisible() const { | 104 } |
100 return window_.TargetVisibility(); | 105 return false; |
101 } | 106 } |
102 | 107 |
103 void Node::SetVisible(bool value) { | 108 void Node::SetVisible(bool value) { |
104 if (value) | 109 if (visible_ == value) |
105 window_.Show(); | 110 return; |
106 else | 111 |
107 window_.Hide(); | 112 visible_ = value; |
113 // TODO(sky): notification, including repaint. | |
108 } | 114 } |
109 | 115 |
110 void Node::SetBitmap(const SkBitmap& bitmap) { | 116 void Node::SetBitmap(const SkBitmap& bitmap) { |
111 bitmap_ = bitmap; | 117 bitmap_ = bitmap; |
112 window_.SchedulePaintInRect(gfx::Rect(window_.bounds().size())); | 118 delegate_->OnNodeBitmapChanged(this); |
113 } | 119 } |
114 | 120 |
115 void Node::OnWindowHierarchyChanged( | 121 void Node::RemoveImpl(Node* node) { |
116 const aura::WindowObserver::HierarchyChangeParams& params) { | 122 node->parent_ = NULL; |
117 if (params.target != &window_ || params.receiver != &window_) | 123 children_.erase(std::find(children_.begin(), children_.end(), node)); |
118 return; | |
119 const Node* new_parent = params.new_parent ? | |
120 params.new_parent->GetProperty(kNodeKey) : NULL; | |
121 const Node* old_parent = params.old_parent ? | |
122 params.old_parent->GetProperty(kNodeKey) : NULL; | |
123 // This check is needed because even the root Node's aura::Window has a | |
124 // parent, but the Node itself has no parent (so it's possible for us to | |
125 // receive this notification from aura when no logical Node hierarchy change | |
126 // has actually ocurred). | |
127 if (new_parent != old_parent) | |
128 delegate_->OnNodeHierarchyChanged(this, new_parent, old_parent); | |
129 } | |
130 | |
131 gfx::Size Node::GetMinimumSize() const { | |
132 return gfx::Size(); | |
133 } | |
134 | |
135 gfx::Size Node::GetMaximumSize() const { | |
136 return gfx::Size(); | |
137 } | |
138 | |
139 void Node::OnBoundsChanged(const gfx::Rect& old_bounds, | |
140 const gfx::Rect& new_bounds) { | |
141 delegate_->OnNodeBoundsChanged(this, old_bounds, new_bounds); | |
142 } | |
143 | |
144 gfx::NativeCursor Node::GetCursor(const gfx::Point& point) { | |
145 return gfx::kNullCursor; | |
146 } | |
147 | |
148 int Node::GetNonClientComponent(const gfx::Point& point) const { | |
149 return HTCAPTION; | |
150 } | |
151 | |
152 bool Node::ShouldDescendIntoChildForEventHandling( | |
153 aura::Window* child, | |
154 const gfx::Point& location) { | |
155 return true; | |
156 } | |
157 | |
158 bool Node::CanFocus() { | |
159 return true; | |
160 } | |
161 | |
162 void Node::OnCaptureLost() { | |
163 } | |
164 | |
165 void Node::OnPaint(gfx::Canvas* canvas) { | |
166 canvas->DrawImageInt(gfx::ImageSkia::CreateFrom1xBitmap(bitmap_), 0, 0); | |
167 } | |
168 | |
169 void Node::OnDeviceScaleFactorChanged(float device_scale_factor) { | |
170 } | |
171 | |
172 void Node::OnWindowDestroying(aura::Window* window) { | |
173 } | |
174 | |
175 void Node::OnWindowDestroyed(aura::Window* window) { | |
176 } | |
177 | |
178 void Node::OnWindowTargetVisibilityChanged(bool visible) { | |
179 } | |
180 | |
181 bool Node::HasHitTestMask() const { | |
182 return false; | |
183 } | |
184 | |
185 void Node::GetHitTestMask(gfx::Path* mask) const { | |
186 } | 124 } |
187 | 125 |
188 } // namespace service | 126 } // namespace service |
189 } // namespace mojo | 127 } // namespace mojo |
OLD | NEW |