Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(93)

Side by Side Diff: ash/wm/panel_layout_manager.cc

Issue 11363250: Allow Chrome apps to create Ash Panels (apps v2) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Multi-icon support Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ash/wm/panel_layout_manager.h" 5 #include "ash/wm/panel_layout_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 9
10 #include "ash/launcher/launcher.h" 10 #include "ash/launcher/launcher.h"
11 #include "ash/shell.h" 11 #include "ash/shell.h"
12 #include "ash/wm/frame_painter.h" 12 #include "ash/wm/frame_painter.h"
13 #include "ash/wm/property_util.h" 13 #include "ash/wm/property_util.h"
14 #include "ash/wm/window_animations.h"
15 #include "ash/wm/window_util.h"
14 #include "base/auto_reset.h" 16 #include "base/auto_reset.h"
15 #include "base/bind.h" 17 #include "base/bind.h"
16 #include "base/bind_helpers.h" 18 #include "base/bind_helpers.h"
17 #include "third_party/skia/include/core/SkColor.h" 19 #include "third_party/skia/include/core/SkColor.h"
18 #include "third_party/skia/include/core/SkPaint.h" 20 #include "third_party/skia/include/core/SkPaint.h"
19 #include "third_party/skia/include/core/SkPath.h" 21 #include "third_party/skia/include/core/SkPath.h"
20 #include "ui/aura/client/activation_client.h" 22 #include "ui/aura/client/activation_client.h"
21 #include "ui/aura/client/aura_constants.h" 23 #include "ui/aura/client/aura_constants.h"
24 #include "ui/aura/focus_manager.h"
22 #include "ui/aura/root_window.h" 25 #include "ui/aura/root_window.h"
23 #include "ui/aura/window.h" 26 #include "ui/aura/window.h"
24 #include "ui/gfx/canvas.h" 27 #include "ui/gfx/canvas.h"
25 #include "ui/gfx/rect.h" 28 #include "ui/gfx/rect.h"
26 #include "ui/views/background.h" 29 #include "ui/views/background.h"
27 #include "ui/views/widget/widget.h" 30 #include "ui/views/widget/widget.h"
28 31
29 namespace ash { 32 namespace ash {
30 namespace internal { 33 namespace internal {
31 34
32 namespace { 35 namespace {
33 const int kPanelMarginEdge = 4; 36 const int kPanelMarginEdge = 4;
34 const int kPanelMarginMiddle = 8; 37 const int kPanelMarginMiddle = 8;
35 38
36 const int kMinimizedHeight = 24;
37
38 const float kMaxHeightFactor = .80f; 39 const float kMaxHeightFactor = .80f;
39 const float kMaxWidthFactor = .50f; 40 const float kMaxWidthFactor = .50f;
40 41
41 // Callout arrow dimensions. 42 // Callout arrow dimensions.
42 const int kArrowWidth = 20; 43 const int kArrowWidth = 20;
43 const int kArrowHeight = 10; 44 const int kArrowHeight = 10;
44 45
45 class CalloutWidgetBackground : public views::Background { 46 class CalloutWidgetBackground : public views::Background {
46 public: 47 public:
47 CalloutWidgetBackground() {} 48 CalloutWidgetBackground() {}
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 if (launcher_) 101 if (launcher_)
101 launcher_->RemoveIconObserver(this); 102 launcher_->RemoveIconObserver(this);
102 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())-> 103 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())->
103 RemoveObserver(this); 104 RemoveObserver(this);
104 } 105 }
105 106
106 void PanelLayoutManager::StartDragging(aura::Window* panel) { 107 void PanelLayoutManager::StartDragging(aura::Window* panel) {
107 DCHECK(!dragged_panel_); 108 DCHECK(!dragged_panel_);
108 DCHECK(panel->parent() == panel_container_); 109 DCHECK(panel->parent() == panel_container_);
109 dragged_panel_ = panel; 110 dragged_panel_ = panel;
111 Relayout();
110 } 112 }
111 113
112 void PanelLayoutManager::FinishDragging() { 114 void PanelLayoutManager::FinishDragging() {
113 DCHECK(dragged_panel_); 115 DCHECK(dragged_panel_);
114 dragged_panel_ = NULL; 116 dragged_panel_ = NULL;
115 Relayout(); 117 Relayout();
116 } 118 }
117 119
118 void PanelLayoutManager::SetLauncher(ash::Launcher* launcher) { 120 void PanelLayoutManager::SetLauncher(ash::Launcher* launcher) {
119 launcher_ = launcher; 121 launcher_ = launcher;
120 launcher_->AddIconObserver(this); 122 launcher_->AddIconObserver(this);
121 } 123 }
122 124
123 void PanelLayoutManager::ToggleMinimize(aura::Window* panel) { 125 void PanelLayoutManager::ToggleMinimize(aura::Window* panel) {
124 DCHECK(panel->parent() == panel_container_); 126 DCHECK(panel->parent() == panel_container_);
125 if (panel->GetProperty(aura::client::kShowStateKey) == 127 if (panel->GetProperty(aura::client::kShowStateKey) ==
126 ui::SHOW_STATE_MINIMIZED) { 128 ui::SHOW_STATE_MINIMIZED) {
127 const gfx::Rect& old_bounds = panel->bounds();
128 panel->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); 129 panel->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
129
130 gfx::Rect new_bounds(old_bounds);
131 const gfx::Rect* restore_bounds = GetRestoreBoundsInScreen(panel);
132 if (restore_bounds) {
133 new_bounds.set_height(restore_bounds->height());
134 new_bounds.set_y(old_bounds.bottom() - restore_bounds->height());
135 SetChildBounds(panel, new_bounds);
136 ClearRestoreBounds(panel);
137 }
138 } else { 130 } else {
139 const gfx::Rect& old_bounds = panel->bounds();
140 panel->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); 131 panel->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
141 SetRestoreBoundsInParent(panel, old_bounds);
142 SetChildBounds(panel,
143 gfx::Rect(old_bounds.x(),
144 old_bounds.bottom() - kMinimizedHeight,
145 old_bounds.width(),
146 kMinimizedHeight));
147 } 132 }
148 Relayout();
149 } 133 }
150 134
151 //////////////////////////////////////////////////////////////////////////////// 135 ////////////////////////////////////////////////////////////////////////////////
152 // PanelLayoutManager, aura::LayoutManager implementation: 136 // PanelLayoutManager, aura::LayoutManager implementation:
153 void PanelLayoutManager::OnWindowResized() { 137 void PanelLayoutManager::OnWindowResized() {
154 Relayout(); 138 Relayout();
155 } 139 }
156 140
157 void PanelLayoutManager::OnWindowAddedToLayout(aura::Window* child) { 141 void PanelLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
158 if (child == callout_widget_->GetNativeWindow()) 142 if (child == callout_widget_->GetNativeWindow())
159 return; 143 return;
160 panel_windows_.push_back(child); 144 panel_windows_.push_back(child);
145 child->AddObserver(this);
161 Relayout(); 146 Relayout();
162 } 147 }
163 148
164 void PanelLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) { 149 void PanelLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
165 PanelList::iterator found = 150 PanelList::iterator found =
166 std::find(panel_windows_.begin(), panel_windows_.end(), child); 151 std::find(panel_windows_.begin(), panel_windows_.end(), child);
167 if (found != panel_windows_.end()) 152 if (found != panel_windows_.end())
168 panel_windows_.erase(found); 153 panel_windows_.erase(found);
154 child->RemoveObserver(this);
169 155
170 if (dragged_panel_ == child) 156 if (dragged_panel_ == child)
171 dragged_panel_ = NULL; 157 dragged_panel_ = NULL;
172 158
173 if (last_active_panel_ == child) 159 if (last_active_panel_ == child)
174 last_active_panel_ = NULL; 160 last_active_panel_ = NULL;
175 161
176 Relayout(); 162 Relayout();
177 } 163 }
178 164
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 //////////////////////////////////////////////////////////////////////////////// 206 ////////////////////////////////////////////////////////////////////////////////
221 // PanelLayoutManager, ash::LauncherIconObserver implementation: 207 // PanelLayoutManager, ash::LauncherIconObserver implementation:
222 208
223 void PanelLayoutManager::OnLauncherIconPositionsChanged() { 209 void PanelLayoutManager::OnLauncherIconPositionsChanged() {
224 // TODO: As this is called for every animation step now. Relayout needs to be 210 // TODO: As this is called for every animation step now. Relayout needs to be
225 // updated to use current icon position instead of use the ideal bounds so 211 // updated to use current icon position instead of use the ideal bounds so
226 // that the panels slide with their icons instead of jumping. 212 // that the panels slide with their icons instead of jumping.
227 Relayout(); 213 Relayout();
228 } 214 }
229 215
216 /////////////////////////////////////////////////////////////////////////////
217 // PanelLayoutManager, WindowObserver implementation:
218
219 void PanelLayoutManager::OnWindowPropertyChanged(aura::Window* window,
220 const void* key,
221 intptr_t old) {
222 if (key != aura::client::kShowStateKey)
223 return;
224 ui::WindowShowState new_state =
225 window->GetProperty(aura::client::kShowStateKey);
226 if (new_state == ui::SHOW_STATE_MINIMIZED)
227 MinimizePanel(window);
228 else
229 RestorePanel(window);
230 }
231
230 //////////////////////////////////////////////////////////////////////////////// 232 ////////////////////////////////////////////////////////////////////////////////
231 // PanelLayoutManager, aura::client::ActivationChangeObserver implementation: 233 // PanelLayoutManager, aura::client::ActivationChangeObserver implementation:
232 void PanelLayoutManager::OnWindowActivated(aura::Window* active, 234 void PanelLayoutManager::OnWindowActivated(aura::Window* active,
233 aura::Window* old_active) { 235 aura::Window* old_active) {
234 if (active && active->type() == aura::client::WINDOW_TYPE_PANEL) { 236 if (active && active->type() == aura::client::WINDOW_TYPE_PANEL) {
235 UpdateStacking(active); 237 UpdateStacking(active);
236 UpdateCallout(active); 238 UpdateCallout(active);
237 } else { 239 } else {
238 UpdateCallout(NULL); 240 UpdateCallout(NULL);
239 } 241 }
240 } 242 }
241 243
242 244
243 //////////////////////////////////////////////////////////////////////////////// 245 ////////////////////////////////////////////////////////////////////////////////
244 // PanelLayoutManager private implementation: 246 // PanelLayoutManager private implementation:
247
248 void PanelLayoutManager::MinimizePanel(aura::Window* panel) {
249 SetWindowVisibilityAnimationType(
250 panel, WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE);
sky 2012/11/20 02:05:05 I believe WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZ
stevenjb 2012/11/20 21:20:58 Ash panels (now aka Utility Windows) do have a lau
251 panel->Hide();
252 if (wm::IsActiveWindow(panel))
253 wm::DeactivateWindow(panel);
254 Relayout();
255 }
256
257 void PanelLayoutManager::RestorePanel(aura::Window* panel) {
258 panel->Show();
259 wm::ActivateWindow(panel);
sky 2012/11/20 02:05:05 Isn't this done else where?
stevenjb 2012/11/20 21:20:58 I did some investigating and determined that this
260 Relayout();
261 }
262
245 void PanelLayoutManager::Relayout() { 263 void PanelLayoutManager::Relayout() {
246 if (!launcher_ || !launcher_->widget()) 264 if (!launcher_ || !launcher_->widget())
247 return; 265 return;
248 266
249 if (in_layout_) 267 if (in_layout_)
250 return; 268 return;
251 AutoReset<bool> auto_reset_in_layout(&in_layout_, true); 269 AutoReset<bool> auto_reset_in_layout(&in_layout_, true);
252 270
253 int launcher_top = launcher_->widget()->GetWindowBoundsInScreen().y(); 271 int launcher_top = launcher_->widget()->GetWindowBoundsInScreen().y();
254 aura::Window* active_panel = NULL; 272 aura::Window* active_panel = NULL;
255 for (PanelList::iterator iter = panel_windows_.begin(); 273 for (PanelList::iterator iter = panel_windows_.begin();
256 iter != panel_windows_.end(); ++iter) { 274 iter != panel_windows_.end(); ++iter) {
257 aura::Window* panel = *iter; 275 aura::Window* panel = *iter;
258 if (!panel->IsVisible() || panel == dragged_panel_) 276 if (!panel->IsVisible() || panel == dragged_panel_)
259 continue; 277 continue;
260 278
261 gfx::Rect icon_bounds = 279 gfx::Rect icon_bounds =
262 launcher_->GetScreenBoundsOfItemIconForWindow(panel); 280 launcher_->GetScreenBoundsOfItemIconForWindow(panel);
263 281
264 // An empty rect indicates that there is no icon for the panel in the 282 // An empty rect indicates that there is no icon for the panel in the
265 // launcher. Just use the current bounds, as there's no icon to draw the 283 // launcher. Just use the current bounds, as there's no icon to draw the
266 // panel above. 284 // panel above.
267 // TODO(dcheng): Need to anchor to overflow icon. 285 // TODO(dcheng): Need to anchor to overflow icon.
268 if (icon_bounds.IsEmpty()) 286 if (icon_bounds.IsEmpty())
269 continue; 287 continue;
270 288
271 if (panel->HasFocus()) { 289 if (panel->HasFocus() ||
290 panel->Contains(panel->GetFocusManager()->GetFocusedWindow())) {
272 DCHECK(!active_panel); 291 DCHECK(!active_panel);
273 active_panel = panel; 292 active_panel = panel;
274 } 293 }
275 294
276 gfx::Point icon_origin = icon_bounds.origin(); 295 gfx::Point icon_origin = icon_bounds.origin();
277 aura::Window::ConvertPointToTarget(panel_container_->GetRootWindow(), 296 aura::Window::ConvertPointToTarget(panel_container_->GetRootWindow(),
278 panel_container_, &icon_origin); 297 panel_container_, &icon_origin);
279 298
280 // TODO(dcheng): Need to clamp to screen edges. 299 // TODO(dcheng): Need to clamp to screen edges.
281 gfx::Rect bounds = panel->bounds(); 300 gfx::Rect bounds = panel->bounds();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 } 351 }
333 352
334 panel_container_->StackChildAtTop(active_panel); 353 panel_container_->StackChildAtTop(active_panel);
335 last_active_panel_ = active_panel; 354 last_active_panel_ = active_panel;
336 } 355 }
337 356
338 void PanelLayoutManager::UpdateCallout(aura::Window* active_panel) { 357 void PanelLayoutManager::UpdateCallout(aura::Window* active_panel) {
339 weak_factory_.InvalidateWeakPtrs(); 358 weak_factory_.InvalidateWeakPtrs();
340 // TODO(dcheng): This doesn't account for panels in overflow. They should have 359 // TODO(dcheng): This doesn't account for panels in overflow. They should have
341 // a callout as well. 360 // a callout as well.
342 if (!active_panel || 361 if (!active_panel) {
343 launcher_->GetScreenBoundsOfItemIconForWindow(active_panel).IsEmpty()) {
344 callout_widget_->Hide(); 362 callout_widget_->Hide();
345 return; 363 return;
346 } 364 }
365 if (launcher_->GetScreenBoundsOfItemIconForWindow(active_panel).IsEmpty()) {
366 callout_widget_->Hide();
367 return;
368 }
347 MessageLoop::current()->PostTask( 369 MessageLoop::current()->PostTask(
348 FROM_HERE, 370 FROM_HERE,
349 base::Bind(&PanelLayoutManager::ShowCalloutHelper, 371 base::Bind(&PanelLayoutManager::ShowCalloutHelper,
350 weak_factory_.GetWeakPtr(), 372 weak_factory_.GetWeakPtr(),
351 active_panel)); 373 active_panel));
352 } 374 }
353 375
354 void PanelLayoutManager::ShowCalloutHelper(aura::Window* active_panel) { 376 void PanelLayoutManager::ShowCalloutHelper(aura::Window* active_panel) {
355 DCHECK(active_panel); 377 DCHECK(active_panel);
356 gfx::Rect bounds = active_panel->GetBoundsInRootWindow(); 378 gfx::Rect bounds = active_panel->GetBoundsInRootWindow();
357 gfx::Rect callout_bounds = callout_widget_->GetWindowBoundsInScreen(); 379 gfx::Rect callout_bounds = callout_widget_->GetWindowBoundsInScreen();
358 callout_bounds.set_x( 380 callout_bounds.set_x(
359 bounds.x() + (bounds.width() - callout_bounds.width()) / 2); 381 bounds.x() + (bounds.width() - callout_bounds.width()) / 2);
360 callout_bounds.set_y(bounds.bottom()); 382 callout_bounds.set_y(bounds.bottom());
361 SetChildBoundsDirect(callout_widget_->GetNativeWindow(), callout_bounds); 383 SetChildBoundsDirect(callout_widget_->GetNativeWindow(), callout_bounds);
362 panel_container_->StackChildAtTop(callout_widget_->GetNativeWindow()); 384 panel_container_->StackChildAtTop(callout_widget_->GetNativeWindow());
363 callout_widget_->Show(); 385 callout_widget_->Show();
364 } 386 }
365 387
366 } // namespace internal 388 } // namespace internal
367 } // namespace ash 389 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698