blob: d52ddc9fcdd099c7077c4766f5bbc04813ad14c1 [file] [log] [blame]
[email protected]5e495462008-11-20 23:07:411// Copyright (c) 2006-2008 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.
4
5#include "chrome/browser/dock_info.h"
6
[email protected]56657692009-06-06 00:21:367#if defined(TOOLKIT_VIEWS)
[email protected]e00e0cc22009-03-10 22:38:498#include "chrome/browser/views/tabs/tab.h"
[email protected]56657692009-06-06 00:21:369#else
10#include "chrome/browser/gtk/tabs/tab_gtk.h"
11#endif
[email protected]5e495462008-11-20 23:07:4112
13namespace {
14
15// Distance in pixels between the hotspot and when the hint should be shown.
[email protected]e00e0cc22009-03-10 22:38:4916const int kHotSpotDeltaX = 120;
17const int kHotSpotDeltaY = 120;
[email protected]5e495462008-11-20 23:07:4118
[email protected]e00e0cc22009-03-10 22:38:4919// Size of the popup window.
20const int kPopupWidth = 70;
21const int kPopupHeight = 70;
[email protected]5e495462008-11-20 23:07:4122
[email protected]a105d2d2009-05-15 03:05:1123} // namespace
24
25// static
26DockInfo::Factory* DockInfo::factory_ = NULL;
27
28// static
29bool DockInfo::IsCloseToPoint(const gfx::Point& screen_loc,
30 int x,
31 int y,
32 bool* in_enable_area) {
[email protected]5e495462008-11-20 23:07:4133 int delta_x = abs(x - screen_loc.x());
34 int delta_y = abs(y - screen_loc.y());
[email protected]e00e0cc22009-03-10 22:38:4935 *in_enable_area = (delta_x < kPopupWidth / 2 && delta_y < kPopupHeight / 2);
[email protected]5e495462008-11-20 23:07:4136 return *in_enable_area || (delta_x < kHotSpotDeltaX &&
37 delta_y < kHotSpotDeltaY);
38}
39
[email protected]a105d2d2009-05-15 03:05:1140// static
41bool DockInfo::IsCloseToMonitorPoint(const gfx::Point& screen_loc,
42 int x,
43 int y,
44 DockInfo::Type type,
45 bool* in_enable_area) {
[email protected]5e495462008-11-20 23:07:4146 // Because the monitor relative positions are aligned with the edge of the
47 // monitor these need to be handled differently.
48 int delta_x = abs(x - screen_loc.x());
49 int delta_y = abs(y - screen_loc.y());
50
[email protected]e00e0cc22009-03-10 22:38:4951 int enable_delta_x = kPopupWidth / 2;
52 int enable_delta_y = kPopupHeight / 2;
[email protected]5e495462008-11-20 23:07:4153 int hot_spot_delta_x = kHotSpotDeltaX;
54 int hot_spot_delta_y = kHotSpotDeltaY;
55
56 switch (type) {
57 case DockInfo::LEFT_HALF:
58 case DockInfo::RIGHT_HALF:
59 enable_delta_x += enable_delta_x;
60 hot_spot_delta_x += hot_spot_delta_x;
61 break;
62
63
[email protected]e00e0cc22009-03-10 22:38:4964 case DockInfo::MAXIMIZE: {
65 // Make the maximize height smaller than the tab height to avoid showing
66 // the dock indicator when close to maximized browser.
[email protected]56657692009-06-06 00:21:3667#if defined(TOOLKIT_VIEWS)
[email protected]e00e0cc22009-03-10 22:38:4968 hot_spot_delta_y = Tab::GetMinimumUnselectedSize().height() - 1;
[email protected]56657692009-06-06 00:21:3669#else
70 hot_spot_delta_y = TabGtk::GetMinimumUnselectedSize().height() - 1;
71#endif
[email protected]e00e0cc22009-03-10 22:38:4972 enable_delta_y = hot_spot_delta_y / 2;
73 break;
74 }
[email protected]5e495462008-11-20 23:07:4175 case DockInfo::BOTTOM_HALF:
76 enable_delta_y += enable_delta_y;
77 hot_spot_delta_y += hot_spot_delta_y;
78 break;
79
80 default:
81 NOTREACHED();
82 return false;
83 }
84 *in_enable_area = (delta_x < enable_delta_x && delta_y < enable_delta_y);
85 bool result = (*in_enable_area || (delta_x < hot_spot_delta_x &&
86 delta_y < hot_spot_delta_y));
87 if (type != DockInfo::MAXIMIZE)
88 return result;
89
[email protected]e00e0cc22009-03-10 22:38:4990 // Make the hot spot/enable spot for maximized windows the whole top of the
91 // monitor.
[email protected]5e495462008-11-20 23:07:4192 int max_delta_y = abs(screen_loc.y() - y);
[email protected]e00e0cc22009-03-10 22:38:4993 *in_enable_area = (*in_enable_area || (max_delta_y < enable_delta_y));
94 return *in_enable_area || (max_delta_y < hot_spot_delta_y);
[email protected]dc3785502008-12-19 14:58:4095}
96
[email protected]e00e0cc22009-03-10 22:38:4997// static
98int DockInfo::popup_width() {
99 return kPopupWidth;
100}
101
102// static
103int DockInfo::popup_height() {
104 return kPopupHeight;
105}
106
[email protected]5e495462008-11-20 23:07:41107bool DockInfo::IsValidForPoint(const gfx::Point& screen_point) {
108 if (type_ == NONE)
109 return false;
110
[email protected]a105d2d2009-05-15 03:05:11111 if (window_) {
[email protected]5e495462008-11-20 23:07:41112 return IsCloseToPoint(screen_point, hot_spot_.x(), hot_spot_.y(),
113 &in_enable_area_);
114 }
115
116 return monitor_bounds_.Contains(screen_point) &&
117 IsCloseToMonitorPoint(screen_point, hot_spot_.x(),
118 hot_spot_.y(), type_, &in_enable_area_);
119}
120
121bool DockInfo::GetNewWindowBounds(gfx::Rect* new_window_bounds,
122 bool* maximize_new_window) const {
123 if (type_ == NONE || !in_enable_area_)
124 return false;
125
[email protected]a105d2d2009-05-15 03:05:11126 gfx::Rect window_bounds;
127 if (window_ && !GetWindowBounds(&window_bounds))
[email protected]5e495462008-11-20 23:07:41128 return false;
129
130 int half_m_width = (monitor_bounds_.right() - monitor_bounds_.x()) / 2;
131 int half_m_height = (monitor_bounds_.bottom() - monitor_bounds_.y()) / 2;
[email protected]5e495462008-11-20 23:07:41132
133 *maximize_new_window = false;
134
135 switch (type_) {
136 case LEFT_OF_WINDOW:
[email protected]a105d2d2009-05-15 03:05:11137 new_window_bounds->SetRect(monitor_bounds_.x(), window_bounds.y(),
138 half_m_width, window_bounds.height());
[email protected]5e495462008-11-20 23:07:41139 break;
140
141 case RIGHT_OF_WINDOW:
142 new_window_bounds->SetRect(monitor_bounds_.x() + half_m_width,
[email protected]a105d2d2009-05-15 03:05:11143 window_bounds.y(), half_m_width,
144 window_bounds.height());
[email protected]5e495462008-11-20 23:07:41145 break;
146
147 case TOP_OF_WINDOW:
[email protected]a105d2d2009-05-15 03:05:11148 new_window_bounds->SetRect(window_bounds.x(), monitor_bounds_.y(),
149 window_bounds.width(), half_m_height);
[email protected]5e495462008-11-20 23:07:41150 break;
151
152 case BOTTOM_OF_WINDOW:
[email protected]a105d2d2009-05-15 03:05:11153 new_window_bounds->SetRect(window_bounds.x(),
[email protected]5e495462008-11-20 23:07:41154 monitor_bounds_.y() + half_m_height,
[email protected]a105d2d2009-05-15 03:05:11155 window_bounds.width(), half_m_height);
[email protected]5e495462008-11-20 23:07:41156 break;
157
158 case LEFT_HALF:
159 new_window_bounds->SetRect(monitor_bounds_.x(), monitor_bounds_.y(),
160 half_m_width, monitor_bounds_.height());
161 break;
162
163 case RIGHT_HALF:
164 new_window_bounds->SetRect(monitor_bounds_.right() - half_m_width,
165 monitor_bounds_.y(), half_m_width, monitor_bounds_.height());
166 break;
167
168 case BOTTOM_HALF:
169 new_window_bounds->SetRect(monitor_bounds_.x(),
170 monitor_bounds_.y() + half_m_height,
171 monitor_bounds_.width(), half_m_height);
172 break;
173
174 case MAXIMIZE:
175 *maximize_new_window = true;
176 break;
177
178 default:
179 NOTREACHED();
180 }
181 return true;
182}
183
184void DockInfo::AdjustOtherWindowBounds() const {
185 if (!in_enable_area_)
186 return;
187
[email protected]a105d2d2009-05-15 03:05:11188 gfx::Rect window_bounds;
189 if (!window_ || !GetWindowBounds(&window_bounds))
[email protected]5e495462008-11-20 23:07:41190 return;
191
192 gfx::Rect other_window_bounds;
193 int half_m_width = (monitor_bounds_.right() - monitor_bounds_.x()) / 2;
194 int half_m_height = (monitor_bounds_.bottom() - monitor_bounds_.y()) / 2;
195
196 switch (type_) {
197 case LEFT_OF_WINDOW:
198 other_window_bounds.SetRect(monitor_bounds_.x() + half_m_width,
[email protected]a105d2d2009-05-15 03:05:11199 window_bounds.y(), half_m_width,
200 window_bounds.height());
[email protected]5e495462008-11-20 23:07:41201 break;
202
203 case RIGHT_OF_WINDOW:
[email protected]a105d2d2009-05-15 03:05:11204 other_window_bounds.SetRect(monitor_bounds_.x(), window_bounds.y(),
205 half_m_width, window_bounds.height());
[email protected]5e495462008-11-20 23:07:41206 break;
207
208 case TOP_OF_WINDOW:
[email protected]a105d2d2009-05-15 03:05:11209 other_window_bounds.SetRect(window_bounds.x(),
[email protected]5e495462008-11-20 23:07:41210 monitor_bounds_.y() + half_m_height,
[email protected]a105d2d2009-05-15 03:05:11211 window_bounds.width(), half_m_height);
[email protected]5e495462008-11-20 23:07:41212 break;
213
214 case BOTTOM_OF_WINDOW:
[email protected]a105d2d2009-05-15 03:05:11215 other_window_bounds.SetRect(window_bounds.x(), monitor_bounds_.y(),
216 window_bounds.width(), half_m_height);
[email protected]5e495462008-11-20 23:07:41217 break;
218
219 default:
220 return;
221 }
222
[email protected]a105d2d2009-05-15 03:05:11223 SizeOtherWindowTo(other_window_bounds);
[email protected]5e495462008-11-20 23:07:41224}
225
[email protected]e00e0cc22009-03-10 22:38:49226gfx::Rect DockInfo::GetPopupRect() const {
227 int x = hot_spot_.x() - popup_width() / 2;
228 int y = hot_spot_.y() - popup_height() / 2;
229 switch (type_) {
230 case LEFT_OF_WINDOW:
231 case RIGHT_OF_WINDOW:
232 case TOP_OF_WINDOW:
233 case BOTTOM_OF_WINDOW: {
234 // Constrain the popup to the monitor's bounds.
235 gfx::Rect ideal_bounds(x, y, popup_width(), popup_height());
236 ideal_bounds = ideal_bounds.AdjustToFit(monitor_bounds_);
237 return ideal_bounds;
238 }
239 case DockInfo::MAXIMIZE:
240 y += popup_height() / 2;
241 break;
242 case DockInfo::LEFT_HALF:
243 x += popup_width() / 2;
244 break;
245 case DockInfo::RIGHT_HALF:
246 x -= popup_width() / 2;
247 break;
248 case DockInfo::BOTTOM_HALF:
249 y -= popup_height() / 2;
250 break;
251
252 default:
253 NOTREACHED();
254 }
255 return gfx::Rect(x, y, popup_width(), popup_height());
256}
257
258bool DockInfo::CheckMonitorPoint(const gfx::Point& screen_loc,
[email protected]5e495462008-11-20 23:07:41259 int x,
260 int y,
261 Type type) {
[email protected]e00e0cc22009-03-10 22:38:49262 if (IsCloseToMonitorPoint(screen_loc, x, y, type, &in_enable_area_)) {
[email protected]5e495462008-11-20 23:07:41263 hot_spot_.SetPoint(x, y);
264 type_ = type;
265 return true;
266 }
267 return false;
268}