| 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 |