1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/wm/panel_layout_manager.h"
#include <algorithm>
#include "ash/launcher/launcher.h"
#include "ash/shell.h"
#include "base/auto_reset.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/gfx/rect.h"
#include "ui/views/widget/widget.h"
namespace {
const int kPanelMarginEdge = 4;
const int kPanelMarginMiddle = 8;
const float kMaxHeightFactor = .80;
const float kMaxWidthFactor = .50;
}
namespace ash {
namespace internal {
////////////////////////////////////////////////////////////////////////////////
// PanelLayoutManager public implementation:
PanelLayoutManager::PanelLayoutManager(aura::Window* panel_container)
: panel_container_(panel_container),
in_layout_(false) {
DCHECK(panel_container);
}
PanelLayoutManager::~PanelLayoutManager() {
}
////////////////////////////////////////////////////////////////////////////////
// PanelLayoutManager, aura::LayoutManager implementation:
void PanelLayoutManager::OnWindowResized() {
Relayout();
}
void PanelLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
panel_windows_.push_back(child);
Relayout();
}
void PanelLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
PanelList::iterator found =
std::find(panel_windows_.begin(), panel_windows_.end(), child);
if (found != panel_windows_.end())
panel_windows_.erase(found);
Relayout();
}
void PanelLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
bool visible) {
Relayout();
}
void PanelLayoutManager::SetChildBounds(aura::Window* child,
const gfx::Rect& requested_bounds) {
gfx::Rect bounds(requested_bounds);
const gfx::Rect& max_bounds = panel_container_->GetRootWindow()->bounds();
const int max_width = max_bounds.width() * kMaxWidthFactor;
const int max_height = max_bounds.height() * kMaxHeightFactor;
if (bounds.width() > max_width)
bounds.set_width(max_width);
if (bounds.height() > max_height)
bounds.set_height(max_height);
SetChildBoundsDirect(child, bounds);
Relayout();
}
////////////////////////////////////////////////////////////////////////////////
// PanelLayoutManager private implementation:
// This is a rough outline of a simple panel layout manager.
void PanelLayoutManager::Relayout() {
if (in_layout_)
return;
AutoReset<bool> auto_reset_in_layout(&in_layout_, true);
// Panels are currently laid out just above the launcher (if it exists),
// otherwise at the bottom of the root window.
int right, bottom;
ash::Shell* shell = ash::Shell::GetInstance();
if (shell->launcher() && shell->launcher()->widget()->IsVisible()) {
const gfx::Rect& bounds =
shell->launcher()->widget()->GetWindowScreenBounds();
right = bounds.width() - 1 - kPanelMarginEdge;
bottom = bounds.y() - 1;
} else {
const gfx::Rect& bounds = panel_container_->GetRootWindow()->bounds();
right = bounds.width() - 1 - kPanelMarginEdge;
bottom = bounds.bottom() - 1;
}
// Layout the panel windows right to left.
for (PanelList::iterator iter = panel_windows_.begin();
iter != panel_windows_.end(); ++iter) {
aura::Window* panel_win = *iter;
if (!panel_win->IsVisible())
continue;
int x = right - panel_win->bounds().width();
int y = bottom - panel_win->bounds().height();
gfx::Rect bounds(x, y,
panel_win->bounds().width(), panel_win->bounds().height());
SetChildBoundsDirect(panel_win, bounds);
right = x - kPanelMarginMiddle;
}
}
} // namespace internal
} // namespace ash
|