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 "chrome/browser/ui/panels/panel_resize_controller.h"
7 #include "base/logging.h"
8 #include "chrome/browser/ui/panels/panel.h"
9 #include "chrome/browser/ui/panels/panel_manager.h"
12 static bool ResizingLeft(panel::ResizingSides sides
) {
13 return sides
== panel::RESIZE_TOP_LEFT
||
14 sides
== panel::RESIZE_LEFT
||
15 sides
== panel::RESIZE_BOTTOM_LEFT
;
18 static bool ResizingRight(panel::ResizingSides sides
) {
19 return sides
== panel::RESIZE_TOP_RIGHT
||
20 sides
== panel::RESIZE_RIGHT
||
21 sides
== panel::RESIZE_BOTTOM_RIGHT
;
24 static bool ResizingTop(panel::ResizingSides sides
) {
25 return sides
== panel::RESIZE_TOP_LEFT
||
26 sides
== panel::RESIZE_TOP
||
27 sides
== panel::RESIZE_TOP_RIGHT
;
30 static bool ResizingBottom(panel::ResizingSides sides
) {
31 return sides
== panel::RESIZE_BOTTOM_RIGHT
||
32 sides
== panel::RESIZE_BOTTOM
||
33 sides
== panel::RESIZE_BOTTOM_LEFT
;
37 PanelResizeController::PanelResizeController(PanelManager
* panel_manager
)
38 : panel_manager_(panel_manager
),
39 resizing_panel_(NULL
),
40 sides_resized_(panel::RESIZE_NONE
) {
43 void PanelResizeController::StartResizing(Panel
* panel
,
44 const gfx::Point
& mouse_location
,
45 panel::ResizingSides sides
) {
46 DCHECK(!IsResizing());
47 DCHECK_NE(panel::RESIZE_NONE
, sides
);
49 panel::Resizability resizability
= panel
->CanResizeByMouse();
50 DCHECK_NE(panel::NOT_RESIZABLE
, resizability
);
51 panel::Resizability resizability_to_test
;
53 case panel::RESIZE_TOP_LEFT
:
54 resizability_to_test
= panel::RESIZABLE_TOP_LEFT
;
56 case panel::RESIZE_TOP
:
57 resizability_to_test
= panel::RESIZABLE_TOP
;
59 case panel::RESIZE_TOP_RIGHT
:
60 resizability_to_test
= panel::RESIZABLE_TOP_RIGHT
;
62 case panel::RESIZE_LEFT
:
63 resizability_to_test
= panel::RESIZABLE_LEFT
;
65 case panel::RESIZE_RIGHT
:
66 resizability_to_test
= panel::RESIZABLE_RIGHT
;
68 case panel::RESIZE_BOTTOM_LEFT
:
69 resizability_to_test
= panel::RESIZABLE_BOTTOM_LEFT
;
71 case panel::RESIZE_BOTTOM
:
72 resizability_to_test
= panel::RESIZABLE_BOTTOM
;
74 case panel::RESIZE_BOTTOM_RIGHT
:
75 resizability_to_test
= panel::RESIZABLE_BOTTOM_RIGHT
;
78 resizability_to_test
= panel::NOT_RESIZABLE
;
81 if ((resizability
& resizability_to_test
) == 0) {
82 DLOG(WARNING
) << "Resizing not allowed. Is this a test?";
86 mouse_location_at_start_
= mouse_location
;
87 bounds_at_start_
= panel
->GetBounds();
88 sides_resized_
= sides
;
89 resizing_panel_
= panel
;
90 resizing_panel_
->OnPanelStartUserResizing();
93 void PanelResizeController::Resize(const gfx::Point
& mouse_location
) {
95 panel::Resizability resizability
= resizing_panel_
->CanResizeByMouse();
96 if (panel::NOT_RESIZABLE
== resizability
) {
100 gfx::Rect bounds
= resizing_panel_
->GetBounds();
102 if (ResizingRight(sides_resized_
)) {
103 bounds
.set_width(std::max(bounds_at_start_
.width() +
104 mouse_location
.x() - mouse_location_at_start_
.x(), 0));
106 if (ResizingBottom(sides_resized_
)) {
107 bounds
.set_height(std::max(bounds_at_start_
.height() +
108 mouse_location
.y() - mouse_location_at_start_
.y(), 0));
110 if (ResizingLeft(sides_resized_
)) {
111 bounds
.set_width(std::max(bounds_at_start_
.width() +
112 mouse_location_at_start_
.x() - mouse_location
.x(), 0));
114 if (ResizingTop(sides_resized_
)) {
115 int new_height
= std::max(bounds_at_start_
.height() +
116 mouse_location_at_start_
.y() - mouse_location
.y(), 0);
117 int new_y
= bounds_at_start_
.bottom() - new_height
;
119 // Make sure that the panel's titlebar cannot be resized under the taskbar
120 // or OSX menu bar that is aligned to top screen edge.
121 gfx::Rect display_area
= panel_manager_
->display_settings_provider()->
122 GetDisplayAreaMatching(bounds
);
123 gfx::Rect work_area
= panel_manager_
->display_settings_provider()->
124 GetWorkAreaMatching(bounds
);
125 if (display_area
.y() <= mouse_location
.y() &&
126 mouse_location
.y() < work_area
.y()) {
127 new_height
-= work_area
.y() - new_y
;
130 bounds
.set_height(new_height
);
133 resizing_panel_
->IncreaseMaxSize(bounds
.size());
135 // This effectively only clamps using the min size, since the max_size was
137 bounds
.set_size(resizing_panel_
->ClampSize(bounds
.size()));
139 if (ResizingLeft(sides_resized_
))
140 bounds
.set_x(bounds_at_start_
.right() - bounds
.width());
142 if (ResizingTop(sides_resized_
))
143 bounds
.set_y(bounds_at_start_
.bottom() - bounds
.height());
145 if (bounds
!= resizing_panel_
->GetBounds()) {
146 resizing_panel_
->SetPanelBoundsInstantly(bounds
);
147 resizing_panel_
->OnWindowResizedByMouse(bounds
);
151 Panel
* PanelResizeController::EndResizing(bool cancelled
) {
152 DCHECK(IsResizing());
155 resizing_panel_
->SetPanelBoundsInstantly(bounds_at_start_
);
156 resizing_panel_
->OnWindowResizedByMouse(bounds_at_start_
);
159 // Do a thorough cleanup.
160 resizing_panel_
->OnPanelEndUserResizing();
161 Panel
* resized_panel
= resizing_panel_
;
162 resizing_panel_
= NULL
;
163 sides_resized_
= panel::RESIZE_NONE
;
164 bounds_at_start_
= gfx::Rect();
165 mouse_location_at_start_
= gfx::Point();
166 return resized_panel
;
169 void PanelResizeController::OnPanelClosed(Panel
* panel
) {
170 if (!resizing_panel_
)
173 // If the resizing panel is closed, abort the resize operation.
174 if (resizing_panel_
== panel
)