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

Unified Diff: ash/wm/panel_layout_manager.cc

Issue 10173016: Stack panels so that part of them will always be visible. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 8 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ash/wm/panel_layout_manager.h ('k') | ash/wm/panel_layout_manager_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ash/wm/panel_layout_manager.cc
diff --git a/ash/wm/panel_layout_manager.cc b/ash/wm/panel_layout_manager.cc
index f741154d787135c96e46942cac6ff7950de64b6f..4ab7032c2953446a95d9cab06ba598500f292ec1 100644
--- a/ash/wm/panel_layout_manager.cc
+++ b/ash/wm/panel_layout_manager.cc
@@ -10,6 +10,7 @@
#include "ash/shell.h"
#include "ash/wm/property_util.h"
#include "base/auto_reset.h"
+#include "ui/aura/client/activation_client.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
@@ -32,18 +33,20 @@ namespace internal {
////////////////////////////////////////////////////////////////////////////////
// PanelLayoutManager public implementation:
-
PanelLayoutManager::PanelLayoutManager(aura::Window* panel_container)
: panel_container_(panel_container),
in_layout_(false),
dragged_panel_(NULL),
- launcher_(NULL) {
+ launcher_(NULL),
+ last_active_panel_(NULL) {
DCHECK(panel_container);
+ Shell::GetRootWindow()->AddObserver(this);
}
PanelLayoutManager::~PanelLayoutManager() {
if (launcher_)
launcher_->RemoveIconObserver(this);
+ Shell::GetRootWindow()->RemoveObserver(this);
}
void PanelLayoutManager::StartDragging(aura::Window* panel) {
@@ -92,7 +95,6 @@ void PanelLayoutManager::ToggleMinimize(aura::Window* panel) {
////////////////////////////////////////////////////////////////////////////////
// PanelLayoutManager, aura::LayoutManager implementation:
-
void PanelLayoutManager::OnWindowResized() {
Relayout();
}
@@ -111,6 +113,9 @@ void PanelLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
if (dragged_panel_ == child)
dragged_panel_ = NULL;
+ if (last_active_panel_ == child)
+ last_active_panel_ = NULL;
+
Relayout();
}
@@ -156,15 +161,27 @@ void PanelLayoutManager::SetChildBounds(aura::Window* child,
}
////////////////////////////////////////////////////////////////////////////////
-// PanelLayoutManager, aura::LauncherIconObserver implementation:
-
+// PanelLayoutManager, ash::LauncherIconObserver implementation:
void PanelLayoutManager::OnLauncherIconPositionsChanged() {
Relayout();
}
////////////////////////////////////////////////////////////////////////////////
-// PanelLayoutManager private implementation:
+// PanelLayoutManager, aura::WindowObserver implementation:
+void PanelLayoutManager::OnWindowPropertyChanged(aura::Window* window,
+ const void* key,
+ intptr_t old) {
+ if (key == aura::client::kRootWindowActiveWindowKey) {
+ aura::Window* active = window->GetProperty(
+ aura::client::kRootWindowActiveWindowKey);
+ if (active && active->type() == aura::client::WINDOW_TYPE_PANEL)
+ UpdateStacking(active);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// PanelLayoutManager private implementation:
void PanelLayoutManager::Relayout() {
if (in_layout_)
return;
@@ -172,31 +189,87 @@ void PanelLayoutManager::Relayout() {
ash::Shell* shell = ash::Shell::GetInstance();
+ aura::Window* active_panel = NULL;
for (PanelList::iterator iter = panel_windows_.begin();
iter != panel_windows_.end(); ++iter) {
- aura::Window* panel_win = *iter;
- if (!panel_win->IsVisible() || panel_win == dragged_panel_)
+ aura::Window* panel = *iter;
+ if (!panel->IsVisible() || panel == dragged_panel_)
continue;
gfx::Rect icon_bounds =
- shell->launcher()->GetScreenBoundsOfItemIconForWindow(panel_win);
+ shell->launcher()->GetScreenBoundsOfItemIconForWindow(panel);
// An empty rect indicates that there is no icon for the panel in the
// launcher. Just use the current bounds, as there's no icon to draw the
// panel above.
+ // TODO(dcheng): Need to anchor to overflow icon.
if (icon_bounds.IsEmpty())
continue;
+ if (panel->HasFocus()) {
+ DCHECK(!active_panel);
+ active_panel = panel;
+ }
+
gfx::Point icon_origin = icon_bounds.origin();
aura::Window::ConvertPointToWindow(panel_container_->GetRootWindow(),
panel_container_, &icon_origin);
- gfx::Rect bounds = panel_win->bounds();
+ // TODO(dcheng): Need to clamp to screen edges.
+ gfx::Rect bounds = panel->bounds();
bounds.set_x(
icon_origin.x() + icon_bounds.width() / 2 - bounds.width() / 2);
bounds.set_y(icon_origin.y() - bounds.height());
- SetChildBoundsDirect(panel_win, bounds);
+ SetChildBoundsDirect(panel, bounds);
}
+
+ UpdateStacking(active_panel);
+}
+
+void PanelLayoutManager::UpdateStacking(aura::Window* active_panel) {
+ if (!active_panel) {
+ if (!last_active_panel_)
+ return;
+ active_panel = last_active_panel_;
+ }
+
+ // We want to to stack the panels like a deck of cards:
+ // ,--,--,--,-------.--.--.
+ // | | | | | | |
+ // | | | | | | |
+ //
+ // We use the middle of each panel to figure out how to stack the panels. This
+ // allows us to update the stacking when a panel is being dragged around by
+ // the titlebar--even though it doesn't update the launcher icon positions, we
+ // still want the visual effect.
+ std::map<int, aura::Window*> window_ordering;
+ for (PanelList::const_iterator it = panel_windows_.begin();
+ it != panel_windows_.end(); ++it) {
+ gfx::Rect bounds = (*it)->bounds();
+ window_ordering.insert(std::make_pair(bounds.x() + bounds.width() / 2,
+ *it));
+ }
+
+ aura::Window* previous_panel = NULL;
+ for (std::map<int, aura::Window*>::const_iterator it =
+ window_ordering.begin();
+ it != window_ordering.end() && it->second != active_panel; ++it) {
+ if (previous_panel)
+ panel_container_->StackChildAbove(it->second, previous_panel);
+ previous_panel = it->second;
+ }
+
+ previous_panel = NULL;
+ for (std::map<int, aura::Window*>::const_reverse_iterator it =
+ window_ordering.rbegin();
+ it != window_ordering.rend() && it->second != active_panel; ++it) {
+ if (previous_panel)
+ panel_container_->StackChildAbove(it->second, previous_panel);
+ previous_panel = it->second;
+ }
+
+ panel_container_->StackChildAtTop(active_panel);
+ last_active_panel_ = active_panel;
}
} // namespace internal
« no previous file with comments | « ash/wm/panel_layout_manager.h ('k') | ash/wm/panel_layout_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698