OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 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 "ui/views/widget/native_widget_layer_reorderer_aura.h" | |
6 | |
7 #include <map> | |
8 #include <vector> | |
9 | |
10 #include "ui/aura/window.h" | |
11 #include "ui/views/view.h" | |
12 #include "ui/views/view_constants_aura.h" | |
13 | |
14 namespace views { | |
15 | |
16 namespace { | |
17 | |
18 // Sets |hosted_windows| to a mapping of the views with an attached window to | |
19 // the window that they are attached to. Only views attached to a child of | |
20 // |parent_window| are returned. | |
21 void GetViewsWithAttachedWindow( | |
22 const aura::Window& parent_window, | |
23 std::map<views::View*, aura::Window*>* hosted_windows) { | |
24 const std::vector<aura::Window*>& child_windows = parent_window.children(); | |
25 for (size_t i = 0; i < child_windows.size(); ++i) { | |
26 aura::Window* child = child_windows[i]; | |
27 View* host_view = child->GetProperty(kHostViewKey); | |
28 if (host_view) | |
29 (*hosted_windows)[host_view] = child; | |
30 } | |
31 } | |
32 | |
33 // Sets |order| to the list of views whose layer / attached window's layer | |
34 // is a child of |parent_layer|. |order| is sorted in ascending z-order of | |
35 // the views. | |
36 // |hosts| are the views with an attached window whose layer is a child of | |
37 // |parent_layer|. | |
38 void GetOrderOfViewsWithLayers( | |
39 views::View* view, | |
40 ui::Layer* parent_layer, | |
41 const std::map<views::View*, aura::Window*>& hosts, | |
42 std::vector<views::View*>* order) { | |
43 DCHECK(view); | |
44 DCHECK(parent_layer); | |
45 DCHECK(order); | |
46 if (view->layer() && view->layer()->parent() == parent_layer) { | |
47 order->push_back(view); | |
48 // |hosts| may contain a child of |view|. | |
49 } else if (hosts.find(view) != hosts.end()) { | |
pkotwicz
2013/05/23 02:28:07
I think that this is ok because |hosts| is small i
| |
50 order->push_back(view); | |
51 } | |
52 | |
53 for (int i = 0; i < view->child_count(); ++i) | |
54 GetOrderOfViewsWithLayers(view->child_at(i), parent_layer, hosts, order); | |
55 } | |
56 | |
57 } // namespace | |
58 | |
59 NativeWidgetLayerReordererAura::NativeWidgetLayerReordererAura( | |
60 aura::Window* window, | |
61 View* root_view) | |
62 : window_(window), | |
63 root_view_(root_view) { | |
64 window_->AddObserver(this); | |
65 const std::vector<aura::Window*>& child_windows = window_->children(); | |
66 for (size_t i = 0; i < child_windows.size(); ++i) | |
67 child_windows[i]->AddObserver(this); | |
68 } | |
69 | |
70 NativeWidgetLayerReordererAura::~NativeWidgetLayerReordererAura() { | |
71 if (window_) | |
72 StopObserving(window_); | |
73 } | |
74 | |
75 void NativeWidgetLayerReordererAura::ReorderLayers() { | |
76 DCHECK(window_); | |
77 | |
78 std::map<View*, aura::Window*> hosted_windows; | |
79 GetViewsWithAttachedWindow(*window_, &hosted_windows); | |
80 | |
81 // Compute the desired z-order of the layers based on the order of the views | |
82 // with layers and views with attached windows in the view tree. | |
83 std::vector<View*> view_with_layer_order; | |
84 GetOrderOfViewsWithLayers(root_view_, window_->layer(), hosted_windows, | |
85 &view_with_layer_order); | |
86 | |
87 if (view_with_layer_order.empty()) | |
88 return; | |
89 | |
90 // Find the bottommost window with a NULL layer delegate below which the | |
91 // reordered windows and layers should be stacked. |stack_below_window| should | |
92 // be NULL if the reordered windows and layers should be stacked at the top. | |
93 const std::vector<aura::Window*>& child_windows = window_->children(); | |
94 aura::Window* stack_below_window = NULL; | |
95 for (size_t i = 0; i < child_windows.size(); ++i) { | |
96 aura::Window* child = child_windows[i]; | |
97 if (!child->layer()->delegate()) { | |
98 stack_below_window = child; | |
99 break; | |
100 } | |
101 } | |
102 | |
103 // Reorder the layers and windows. | |
104 for (size_t i = 0; i < view_with_layer_order.size(); ++i) { | |
105 View* view = view_with_layer_order[i]; | |
106 ui::Layer* layer = view->layer(); | |
107 aura::Window* window = NULL; | |
108 | |
109 std::map<View*, aura::Window*>::iterator hosted_window_it = | |
110 hosted_windows.find(view); | |
111 if (hosted_window_it != hosted_windows.end()) { | |
112 window = hosted_window_it->second; | |
113 layer = window->layer(); | |
114 } | |
115 | |
116 DCHECK(layer); | |
117 if (stack_below_window) { | |
118 if (window) | |
119 window_->StackChildBelow(window, stack_below_window); | |
120 window_->layer()->StackBelow(layer, stack_below_window->layer()); | |
121 } else { | |
122 if (window) | |
123 window_->StackChildAtTop(window); | |
124 window_->layer()->StackAtTop(layer); | |
125 } | |
126 } | |
127 } | |
128 | |
129 void NativeWidgetLayerReordererAura::StopObserving(aura::Window* window) { | |
130 window->RemoveObserver(this); | |
131 if (window_ == window){ | |
132 const std::vector<aura::Window*>& child_windows = window_->children(); | |
133 for (size_t i = 0; i < child_windows.size(); ++i) | |
134 child_windows[i]->RemoveObserver(this); | |
135 window_ = NULL; | |
136 } | |
137 } | |
138 | |
139 void NativeWidgetLayerReordererAura::OnWindowAdded(aura::Window* new_window) { | |
140 if (new_window->parent() == window_) { | |
141 new_window->AddObserver(this); | |
142 ReorderLayers(); | |
143 } | |
144 } | |
145 | |
146 void NativeWidgetLayerReordererAura::OnWillRemoveWindow(aura::Window* window) { | |
147 if (window->parent() == window_) | |
148 StopObserving(window); | |
149 } | |
150 | |
151 void NativeWidgetLayerReordererAura::OnWindowPropertyChanged( | |
152 aura::Window* window, | |
153 const void* key, | |
154 intptr_t old) { | |
155 if (window != window_ && key == kHostViewKey) | |
156 ReorderLayers(); | |
157 } | |
158 | |
159 void NativeWidgetLayerReordererAura::OnWindowDestroying(aura::Window* window) { | |
160 StopObserving(window); | |
161 } | |
162 | |
163 } // namespace views | |
OLD | NEW |