OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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/aura_shell/default_container_layout_manager.h" | |
6 | |
7 #include "ash/wm/show_state_controller.h" | |
8 #include "ui/aura/client/aura_constants.h" | |
9 #include "ui/aura/event.h" | |
10 #include "ui/aura/root_window.h" | |
11 #include "ui/aura/screen_aura.h" | |
12 #include "ui/aura/window.h" | |
13 #include "ui/aura/window_observer.h" | |
14 #include "ui/aura_shell/property_util.h" | |
15 #include "ui/aura_shell/window_util.h" | |
16 #include "ui/aura_shell/workspace/workspace.h" | |
17 #include "ui/aura_shell/workspace/workspace_manager.h" | |
18 #include "ui/base/ui_base_types.h" | |
19 #include "ui/gfx/rect.h" | |
20 #include "ui/views/widget/native_widget_aura.h" | |
21 | |
22 namespace aura_shell { | |
23 namespace internal { | |
24 | |
25 //////////////////////////////////////////////////////////////////////////////// | |
26 // DefaultContainerLayoutManager, public: | |
27 | |
28 DefaultContainerLayoutManager::DefaultContainerLayoutManager( | |
29 WorkspaceManager* workspace_manager) | |
30 : workspace_manager_(workspace_manager), | |
31 show_state_controller_(new ShowStateController(workspace_manager)) { | |
32 } | |
33 | |
34 DefaultContainerLayoutManager::~DefaultContainerLayoutManager() {} | |
35 | |
36 void DefaultContainerLayoutManager::PrepareForMoveOrResize( | |
37 aura::Window* drag, | |
38 aura::MouseEvent* event) { | |
39 workspace_manager_->set_ignored_window(drag); | |
40 } | |
41 | |
42 void DefaultContainerLayoutManager::CancelMoveOrResize( | |
43 aura::Window* drag, | |
44 aura::MouseEvent* event) { | |
45 workspace_manager_->set_ignored_window(NULL); | |
46 } | |
47 | |
48 void DefaultContainerLayoutManager::ProcessMove( | |
49 aura::Window* drag, | |
50 aura::MouseEvent* event) { | |
51 // TODO(oshima): Just zooming out may (and will) move/swap window without | |
52 // a users's intent. We probably should scroll viewport, but that may not | |
53 // be enough. See crbug.com/101826 for more discussion. | |
54 workspace_manager_->SetOverview(true); | |
55 | |
56 gfx::Point point_in_owner = event->location(); | |
57 aura::Window::ConvertPointToWindow( | |
58 drag, | |
59 workspace_manager_->contents_view(), | |
60 &point_in_owner); | |
61 // TODO(oshima): We should support simply moving to another | |
62 // workspace when the destination workspace has enough room to accomodate. | |
63 aura::Window* rotate_target = | |
64 workspace_manager_->FindRotateWindowForLocation(point_in_owner); | |
65 if (rotate_target) | |
66 workspace_manager_->RotateWindows(drag, rotate_target); | |
67 } | |
68 | |
69 void DefaultContainerLayoutManager::EndMove( | |
70 aura::Window* drag, | |
71 aura::MouseEvent* evnet) { | |
72 // TODO(oshima): finish moving window between workspaces. | |
73 workspace_manager_->set_ignored_window(NULL); | |
74 Workspace* workspace = workspace_manager_->FindBy(drag); | |
75 workspace->Layout(NULL); | |
76 workspace->Activate(); | |
77 workspace_manager_->SetOverview(false); | |
78 } | |
79 | |
80 void DefaultContainerLayoutManager::EndResize( | |
81 aura::Window* drag, | |
82 aura::MouseEvent* evnet) { | |
83 workspace_manager_->set_ignored_window(NULL); | |
84 Workspace* workspace = workspace_manager_->GetActiveWorkspace(); | |
85 if (workspace) | |
86 workspace->Layout(NULL); | |
87 workspace_manager_->SetOverview(false); | |
88 } | |
89 | |
90 //////////////////////////////////////////////////////////////////////////////// | |
91 // DefaultContainerLayoutManager, aura::LayoutManager implementation: | |
92 | |
93 void DefaultContainerLayoutManager::OnWindowResized() { | |
94 // Workspace is updated via RootWindowObserver::OnRootWindowResized. | |
95 } | |
96 | |
97 void DefaultContainerLayoutManager::OnWindowAddedToLayout(aura::Window* child) { | |
98 if (child->type() != aura::client::WINDOW_TYPE_NORMAL || | |
99 child->transient_parent()) { | |
100 return; | |
101 } | |
102 | |
103 if (!child->GetProperty(aura::client::kShowStateKey)) | |
104 child->SetIntProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); | |
105 | |
106 child->AddObserver(show_state_controller_.get()); | |
107 | |
108 Workspace* workspace = workspace_manager_->GetActiveWorkspace(); | |
109 if (workspace) { | |
110 aura::Window* active = aura_shell::GetActiveWindow(); | |
111 // Active window may not be in the default container layer. | |
112 if (!workspace->Contains(active)) | |
113 active = NULL; | |
114 if (workspace->AddWindowAfter(child, active)) | |
115 return; | |
116 } | |
117 // Create new workspace if new |child| doesn't fit to current workspace. | |
118 Workspace* new_workspace = workspace_manager_->CreateWorkspace(); | |
119 new_workspace->AddWindowAfter(child, NULL); | |
120 new_workspace->Activate(); | |
121 } | |
122 | |
123 void DefaultContainerLayoutManager::OnWillRemoveWindowFromLayout( | |
124 aura::Window* child) { | |
125 child->RemoveObserver(show_state_controller_.get()); | |
126 ClearRestoreBounds(child); | |
127 | |
128 Workspace* workspace = workspace_manager_->FindBy(child); | |
129 if (!workspace) | |
130 return; | |
131 workspace->RemoveWindow(child); | |
132 if (workspace->is_empty()) | |
133 delete workspace; | |
134 } | |
135 | |
136 void DefaultContainerLayoutManager::OnChildWindowVisibilityChanged( | |
137 aura::Window* child, | |
138 bool visible) { | |
139 NOTIMPLEMENTED(); | |
140 } | |
141 | |
142 void DefaultContainerLayoutManager::SetChildBounds( | |
143 aura::Window* child, | |
144 const gfx::Rect& requested_bounds) { | |
145 gfx::Rect adjusted_bounds = requested_bounds; | |
146 | |
147 // First, calculate the adjusted bounds. | |
148 if (child->type() != aura::client::WINDOW_TYPE_NORMAL || | |
149 workspace_manager_->layout_in_progress() || | |
150 child->transient_parent()) { | |
151 // Use the requested bounds as is. | |
152 } else if (child == workspace_manager_->ignored_window()) { | |
153 // If a drag window is requesting bounds, make sure its attached to | |
154 // the workarea's top and fits within the total drag area. | |
155 gfx::Rect drag_area = workspace_manager_->GetDragAreaBounds(); | |
156 adjusted_bounds.set_y(drag_area.y()); | |
157 adjusted_bounds = adjusted_bounds.AdjustToFit(drag_area); | |
158 } else { | |
159 Workspace* workspace = workspace_manager_->FindBy(child); | |
160 gfx::Rect work_area = workspace->GetWorkAreaBounds(); | |
161 adjusted_bounds.set_origin( | |
162 gfx::Point(child->GetTargetBounds().x(), work_area.y())); | |
163 adjusted_bounds = adjusted_bounds.AdjustToFit(work_area); | |
164 } | |
165 | |
166 ui::WindowShowState show_state = static_cast<ui::WindowShowState>( | |
167 child->GetIntProperty(aura::client::kShowStateKey)); | |
168 | |
169 // Second, check if the window is either maximized or in fullscreen mode. | |
170 if (show_state == ui::SHOW_STATE_MAXIMIZED || | |
171 show_state == ui::SHOW_STATE_FULLSCREEN) { | |
172 // If the request is not from workspace manager, | |
173 // remember the requested bounds. | |
174 if (!workspace_manager_->layout_in_progress()) | |
175 SetRestoreBounds(child, adjusted_bounds); | |
176 | |
177 Workspace* workspace = workspace_manager_->FindBy(child); | |
178 if (show_state == ui::SHOW_STATE_MAXIMIZED) | |
179 adjusted_bounds = workspace->GetWorkAreaBounds(); | |
180 else | |
181 adjusted_bounds = workspace->bounds(); | |
182 // Don't | |
183 if (child->GetTargetBounds() == adjusted_bounds) | |
184 return; | |
185 } | |
186 SetChildBoundsDirect(child, adjusted_bounds); | |
187 } | |
188 | |
189 } // namespace internal | |
190 } // namespace aura_shell | |
OLD | NEW |