summaryrefslogtreecommitdiff
path: root/athena/wm/window_overview_mode.cc
diff options
context:
space:
mode:
Diffstat (limited to 'athena/wm/window_overview_mode.cc')
-rw-r--r--athena/wm/window_overview_mode.cc93
1 files changed, 80 insertions, 13 deletions
diff --git a/athena/wm/window_overview_mode.cc b/athena/wm/window_overview_mode.cc
index 8c98bcb019..16f889cab3 100644
--- a/athena/wm/window_overview_mode.cc
+++ b/athena/wm/window_overview_mode.cc
@@ -17,6 +17,7 @@
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/events/event_handler.h"
#include "ui/gfx/transform.h"
+#include "ui/wm/core/shadow.h"
namespace {
@@ -30,6 +31,8 @@ struct WindowOverviewState {
// The current overview state of the window. 0.f means the window is at the
// topmost position. 1.f means the window is at the bottom-most position.
float progress;
+
+ scoped_ptr<wm::Shadow> shadow;
};
} // namespace
@@ -140,7 +143,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
top_transform.Scale(kMinScale, kMinScale);
gfx::Transform bottom_transform;
- int bottom = container_size.height() - (index * kGapBetweenWindowsBottom);
+ int bottom = GetScrollableHeight() - (index * kGapBetweenWindowsBottom);
x_translate = container_size.width() * (1 - kMaxScale) / 2.;
bottom_transform.Translate(x_translate, bottom - window->bounds().y());
bottom_transform.Scale(kMaxScale, kMaxScale);
@@ -149,6 +152,7 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
state->top = top_transform;
state->bottom = bottom_transform;
state->progress = 0.f;
+ state->shadow = CreateShadowForWindow(window);
window->SetProperty(kWindowOverviewState, state);
}
}
@@ -187,6 +191,15 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
}
}
+ scoped_ptr<wm::Shadow> CreateShadowForWindow(aura::Window* window) {
+ scoped_ptr<wm::Shadow> shadow(new wm::Shadow());
+ shadow->Init(wm::Shadow::STYLE_ACTIVE);
+ shadow->SetContentBounds(gfx::Rect(window->bounds().size()));
+ shadow->layer()->SetVisible(true);
+ window->layer()->Add(shadow->layer());
+ return shadow.Pass();
+ }
+
aura::Window* SelectWindowAt(ui::LocatedEvent* event) {
CHECK_EQ(container_, event->target());
// Find the old targeter to find the target of the event.
@@ -205,24 +218,78 @@ class WindowOverviewModeImpl : public WindowOverviewMode,
return target;
}
+ // Scroll the window list by |delta_y| amount. |delta_y| is negative when
+ // scrolling up; and positive when scrolling down.
+ void DoScroll(float delta_y) {
+ const float kEpsilon = 1e-3f;
+ aura::Window::Windows windows = container_->children();
+ float delta_y_p = std::abs(delta_y) / GetScrollableHeight();
+ if (delta_y < 0) {
+ // Scroll up. Start with the top-most (i.e. behind-most in terms of
+ // z-index) window, and try to scroll them up.
+ for (aura::Window::Windows::iterator iter = windows.begin();
+ delta_y_p > kEpsilon && iter != windows.end();
+ ++iter) {
+ aura::Window* window = (*iter);
+ WindowOverviewState* state = window->GetProperty(kWindowOverviewState);
+ if (state->progress > kEpsilon) {
+ // It is possible to scroll |window| up. Scroll it up, and update
+ // |delta_y_p| for the next window.
+ float apply = delta_y_p * state->progress;
+ SetWindowProgress(window, std::max(0.f, state->progress - apply * 3));
+ delta_y_p -= apply;
+ }
+ }
+ } else {
+ // Scroll down. Start with the bottom-most (i.e. front-most in terms of
+ // z-index) window, and try to scroll them down.
+ for (aura::Window::Windows::reverse_iterator iter = windows.rbegin();
+ delta_y_p > kEpsilon && iter != windows.rend();
+ ++iter) {
+ aura::Window* window = (*iter);
+ WindowOverviewState* state = window->GetProperty(kWindowOverviewState);
+ if (1.f - state->progress > kEpsilon) {
+ // It is possible to scroll |window| down. Scroll it down, and update
+ // |delta_y_p| for the next window.
+ SetWindowProgress(window, std::min(1.f, state->progress + delta_y_p));
+ delta_y_p /= 2.f;
+ }
+ }
+ }
+ }
+
+ int GetScrollableHeight() const {
+ const float kScrollableFraction = 0.65f;
+ return container_->bounds().height() * kScrollableFraction;
+ }
+
// ui::EventHandler:
virtual void OnMouseEvent(ui::MouseEvent* mouse) OVERRIDE {
- if (mouse->type() != ui::ET_MOUSE_PRESSED)
- return;
- aura::Window* select = SelectWindowAt(mouse);
- if (select) {
- mouse->SetHandled();
- delegate_->OnSelectWindow(select);
+ if (mouse->type() == ui::ET_MOUSE_PRESSED) {
+ aura::Window* select = SelectWindowAt(mouse);
+ if (select) {
+ mouse->SetHandled();
+ delegate_->OnSelectWindow(select);
+ }
+ } else if (mouse->type() == ui::ET_MOUSEWHEEL) {
+ DoScroll(static_cast<ui::MouseWheelEvent*>(mouse)->y_offset());
}
}
+ virtual void OnScrollEvent(ui::ScrollEvent* scroll) OVERRIDE {
+ if (scroll->type() == ui::ET_SCROLL)
+ DoScroll(scroll->y_offset());
+ }
+
virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE {
- if (gesture->type() != ui::ET_GESTURE_TAP)
- return;
- aura::Window* select = SelectWindowAt(gesture);
- if (select) {
- gesture->SetHandled();
- delegate_->OnSelectWindow(select);
+ if (gesture->type() == ui::ET_GESTURE_TAP) {
+ aura::Window* select = SelectWindowAt(gesture);
+ if (select) {
+ gesture->SetHandled();
+ delegate_->OnSelectWindow(select);
+ }
+ } else if (gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) {
+ DoScroll(gesture->details().scroll_y());
}
}