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"
10 #include "ui/base/hit_test.h"
13 bool ResizingLeft(int component
) {
14 return component
== HTTOPLEFT
||
15 component
== HTLEFT
||
16 component
== HTBOTTOMLEFT
;
19 bool ResizingRight(int component
) {
20 return component
== HTTOPRIGHT
||
21 component
== HTRIGHT
||
22 component
== HTBOTTOMRIGHT
;
25 bool ResizingTop(int component
) {
26 return component
== HTTOPLEFT
||
28 component
== HTTOPRIGHT
;
31 bool ResizingBottom(int component
) {
32 return component
== HTBOTTOMRIGHT
||
33 component
== HTBOTTOM
||
34 component
== HTBOTTOMLEFT
;
38 PanelResizeController::PanelResizeController(PanelManager
* panel_manager
)
39 : panel_manager_(panel_manager
),
40 resizing_panel_(NULL
),
41 component_(HTNOWHERE
) {
44 void PanelResizeController::StartResizing(Panel
* panel
,
45 const gfx::Point
& mouse_location
,
47 DCHECK(!IsResizing());
48 DCHECK_NE(HTNOWHERE
, component
);
50 panel::Resizability resizability
= panel
->CanResizeByMouse();
51 DCHECK_NE(panel::NOT_RESIZABLE
, resizability
);
52 panel::Resizability resizability_to_test
;
55 resizability_to_test
= panel::RESIZABLE_TOP_LEFT
;
58 resizability_to_test
= panel::RESIZABLE_TOP
;
61 resizability_to_test
= panel::RESIZABLE_TOP_RIGHT
;
64 resizability_to_test
= panel::RESIZABLE_LEFT
;
67 resizability_to_test
= panel::RESIZABLE_RIGHT
;
70 resizability_to_test
= panel::RESIZABLE_BOTTOM_LEFT
;
73 resizability_to_test
= panel::RESIZABLE_BOTTOM
;
76 resizability_to_test
= panel::RESIZABLE_BOTTOM_RIGHT
;
79 resizability_to_test
= panel::NOT_RESIZABLE
;
82 if ((resizability
& resizability_to_test
) == 0) {
83 DLOG(WARNING
) << "Resizing not allowed. Is this a test?";
87 mouse_location_at_start_
= mouse_location
;
88 bounds_at_start_
= panel
->GetBounds();
89 component_
= component
;
90 resizing_panel_
= panel
;
91 resizing_panel_
->OnPanelStartUserResizing();
94 void PanelResizeController::Resize(const gfx::Point
& mouse_location
) {
96 panel::Resizability resizability
= resizing_panel_
->CanResizeByMouse();
97 if (panel::NOT_RESIZABLE
== resizability
) {
101 gfx::Rect bounds
= resizing_panel_
->GetBounds();
103 if (ResizingRight(component_
)) {
104 bounds
.set_width(std::max(bounds_at_start_
.width() +
105 mouse_location
.x() - mouse_location_at_start_
.x(), 0));
107 if (ResizingBottom(component_
)) {
108 bounds
.set_height(std::max(bounds_at_start_
.height() +
109 mouse_location
.y() - mouse_location_at_start_
.y(), 0));
111 if (ResizingLeft(component_
)) {
112 bounds
.set_width(std::max(bounds_at_start_
.width() +
113 mouse_location_at_start_
.x() - mouse_location
.x(), 0));
115 if (ResizingTop(component_
)) {
116 int new_height
= std::max(bounds_at_start_
.height() +
117 mouse_location_at_start_
.y() - mouse_location
.y(), 0);
118 int new_y
= bounds_at_start_
.bottom() - new_height
;
120 // Make sure that the panel's titlebar cannot be resized under the taskbar
121 // or OSX menu bar that is aligned to top screen edge.
122 gfx::Rect display_area
= panel_manager_
->display_settings_provider()->
123 GetDisplayAreaMatching(bounds
);
124 gfx::Rect work_area
= panel_manager_
->display_settings_provider()->
125 GetWorkAreaMatching(bounds
);
126 if (display_area
.y() <= mouse_location
.y() &&
127 mouse_location
.y() < work_area
.y()) {
128 new_height
-= work_area
.y() - new_y
;
131 bounds
.set_height(new_height
);
134 resizing_panel_
->IncreaseMaxSize(bounds
.size());
136 // This effectively only clamps using the min size, since the max_size was
138 bounds
.set_size(resizing_panel_
->ClampSize(bounds
.size()));
140 if (ResizingLeft(component_
))
141 bounds
.set_x(bounds_at_start_
.right() - bounds
.width());
143 if (ResizingTop(component_
))
144 bounds
.set_y(bounds_at_start_
.bottom() - bounds
.height());
146 if (bounds
!= resizing_panel_
->GetBounds()) {
147 resizing_panel_
->SetPanelBoundsInstantly(bounds
);
148 resizing_panel_
->OnWindowResizedByMouse(bounds
);
152 Panel
* PanelResizeController::EndResizing(bool cancelled
) {
153 DCHECK(IsResizing());
156 resizing_panel_
->SetPanelBoundsInstantly(bounds_at_start_
);
157 resizing_panel_
->OnWindowResizedByMouse(bounds_at_start_
);
160 // Do a thorough cleanup.
161 resizing_panel_
->OnPanelEndUserResizing();
162 Panel
* resized_panel
= resizing_panel_
;
163 resizing_panel_
= NULL
;
164 component_
= HTNOWHERE
;
165 bounds_at_start_
= gfx::Rect();
166 mouse_location_at_start_
= gfx::Point();
167 return resized_panel
;
170 void PanelResizeController::OnPanelClosed(Panel
* panel
) {
171 if (!resizing_panel_
)
174 // If the resizing panel is closed, abort the resize operation.
175 if (resizing_panel_
== panel
)