Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / ash / wm / workspace / workspace_event_handler.cc
blob5839e2129c8364e5fdfdb0b504441d0b1ce3998e
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
3 // found in the LICENSE file.
5 #include "ash/wm/workspace/workspace_event_handler.h"
7 #include "ash/screen_ash.h"
8 #include "ash/shell.h"
9 #include "ash/shell_delegate.h"
10 #include "ash/wm/property_util.h"
11 #include "ash/wm/window_util.h"
12 #include "ash/wm/workspace/workspace_window_resizer.h"
13 #include "ui/aura/client/aura_constants.h"
14 #include "ui/aura/window.h"
15 #include "ui/aura/window_delegate.h"
16 #include "ui/base/events/event.h"
17 #include "ui/base/events/event_utils.h"
18 #include "ui/base/hit_test.h"
19 #include "ui/compositor/scoped_layer_animation_settings.h"
20 #include "ui/gfx/screen.h"
22 namespace ash {
23 namespace {
25 void SingleAxisMaximize(aura::Window* window, const gfx::Rect& maximize_rect) {
26 gfx::Rect bounds_in_screen =
27 ScreenAsh::ConvertRectToScreen(window->parent(), window->bounds());
29 SetRestoreBoundsInScreen(window, bounds_in_screen);
30 window->SetBounds(maximize_rect);
33 void SingleAxisUnmaximize(aura::Window* window,
34 const gfx::Rect& restore_bounds_in_screen) {
35 gfx::Rect restore_bounds = ScreenAsh::ConvertRectFromScreen(
36 window->parent(), restore_bounds_in_screen);
37 window->SetBounds(restore_bounds);
38 ClearRestoreBounds(window);
41 void ToggleMaximizedState(aura::Window* window) {
42 if (GetRestoreBoundsInScreen(window)) {
43 if (window->GetProperty(aura::client::kShowStateKey) ==
44 ui::SHOW_STATE_NORMAL) {
45 window->SetBounds(GetRestoreBoundsInParent(window));
46 ClearRestoreBounds(window);
47 } else {
48 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
50 } else if (wm::CanMaximizeWindow(window)) {
51 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
55 } // namespace
57 namespace internal {
59 WorkspaceEventHandler::WorkspaceEventHandler(aura::Window* owner)
60 : ToplevelWindowEventHandler(owner),
61 destroyed_(NULL) {
64 WorkspaceEventHandler::~WorkspaceEventHandler() {
65 if (destroyed_)
66 *destroyed_ = true;
69 void WorkspaceEventHandler::OnMouseEvent(ui::MouseEvent* event) {
70 aura::Window* target = static_cast<aura::Window*>(event->target());
71 switch (event->type()) {
72 case ui::ET_MOUSE_MOVED: {
73 int component =
74 target->delegate()->GetNonClientComponent(event->location());
75 multi_window_resize_controller_.Show(target, component,
76 event->location());
77 break;
79 case ui::ET_MOUSE_ENTERED:
80 break;
81 case ui::ET_MOUSE_CAPTURE_CHANGED:
82 case ui::ET_MOUSE_EXITED:
83 break;
84 case ui::ET_MOUSE_PRESSED: {
85 // Maximize behavior is implemented as post-target handling so the target
86 // can cancel it.
87 if (ui::EventCanceledDefaultHandling(*event)) {
88 ToplevelWindowEventHandler::OnMouseEvent(event);
89 return;
92 if (event->flags() & ui::EF_IS_DOUBLE_CLICK &&
93 target->delegate()->GetNonClientComponent(event->location()) ==
94 HTCAPTION) {
95 bool destroyed = false;
96 destroyed_ = &destroyed;
97 ash::Shell::GetInstance()->delegate()->RecordUserMetricsAction(
98 ash::UMA_TOGGLE_MAXIMIZE_CAPTION_CLICK);
99 ToggleMaximizedState(target);
100 if (destroyed)
101 return;
102 destroyed_ = NULL;
104 multi_window_resize_controller_.Hide();
105 HandleVerticalResizeDoubleClick(target, event);
106 break;
108 default:
109 break;
111 ToplevelWindowEventHandler::OnMouseEvent(event);
114 void WorkspaceEventHandler::OnGestureEvent(ui::GestureEvent* event) {
115 aura::Window* target = static_cast<aura::Window*>(event->target());
116 if (event->type() == ui::ET_GESTURE_TAP &&
117 event->details().tap_count() == 2 &&
118 target->delegate()->GetNonClientComponent(event->location()) ==
119 HTCAPTION) {
120 ash::Shell::GetInstance()->delegate()->RecordUserMetricsAction(
121 ash::UMA_TOGGLE_MAXIMIZE_CAPTION_GESTURE);
122 ToggleMaximizedState(target); // |this| may be destroyed from here.
123 event->StopPropagation();
124 return;
126 ToplevelWindowEventHandler::OnGestureEvent(event);
129 void WorkspaceEventHandler::HandleVerticalResizeDoubleClick(
130 aura::Window* target,
131 ui::MouseEvent* event) {
132 gfx::Rect max_size(target->delegate()->GetMaximumSize());
133 if (event->flags() & ui::EF_IS_DOUBLE_CLICK &&
134 !wm::IsWindowMaximized(target)) {
135 int component =
136 target->delegate()->GetNonClientComponent(event->location());
137 gfx::Rect work_area =
138 Shell::GetScreen()->GetDisplayNearestWindow(target).work_area();
139 const gfx::Rect* restore_bounds =
140 GetRestoreBoundsInScreen(target);
141 if (component == HTBOTTOM || component == HTTOP) {
142 // Don't maximize vertically if the window has a max height defined.
143 if (max_size.height() != 0)
144 return;
145 if (restore_bounds &&
146 (target->bounds().height() == work_area.height() &&
147 target->bounds().y() == work_area.y())) {
148 SingleAxisUnmaximize(target, *restore_bounds);
149 } else {
150 SingleAxisMaximize(target,
151 gfx::Rect(target->bounds().x(),
152 work_area.y(),
153 target->bounds().width(),
154 work_area.height()));
156 } else if (component == HTLEFT || component == HTRIGHT) {
157 // Don't maximize horizontally if the window has a max width defined.
158 if (max_size.width() != 0)
159 return;
160 if (restore_bounds &&
161 (target->bounds().width() == work_area.width() &&
162 target->bounds().x() == work_area.x())) {
163 SingleAxisUnmaximize(target, *restore_bounds);
164 } else {
165 SingleAxisMaximize(target,
166 gfx::Rect(work_area.x(),
167 target->bounds().y(),
168 work_area.width(),
169 target->bounds().height()));
175 } // namespace internal
176 } // namespace ash