• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/browser/ui/tabs/dock_info.h"
6 
7 #include <stdlib.h>
8 
9 #include "base/logging.h"
10 
11 namespace {
12 
13 // Distance in pixels between the hotspot and when the hint should be shown.
14 const int kHotSpotDeltaX = 120;
15 const int kHotSpotDeltaY = 120;
16 
17 // Size of the popup window.
18 const int kPopupWidth = 70;
19 const int kPopupHeight = 70;
20 
21 }  // namespace
22 
23 // static
IsCloseToPoint(const gfx::Point & screen_loc,int x,int y,bool * in_enable_area)24 bool DockInfo::IsCloseToPoint(const gfx::Point& screen_loc,
25                               int x,
26                               int y,
27                               bool* in_enable_area) {
28   int delta_x = abs(x - screen_loc.x());
29   int delta_y = abs(y - screen_loc.y());
30   *in_enable_area = (delta_x < kPopupWidth / 2 && delta_y < kPopupHeight / 2);
31   return *in_enable_area || (delta_x < kHotSpotDeltaX &&
32                              delta_y < kHotSpotDeltaY);
33 }
34 
35 // static
IsCloseToMonitorPoint(const gfx::Point & screen_loc,int x,int y,DockInfo::Type type,bool * in_enable_area)36 bool DockInfo::IsCloseToMonitorPoint(const gfx::Point& screen_loc,
37                                      int x,
38                                      int y,
39                                      DockInfo::Type type,
40                                      bool* in_enable_area) {
41   // Because the monitor relative positions are aligned with the edge of the
42   // monitor these need to be handled differently.
43   int delta_x = abs(x - screen_loc.x());
44   int delta_y = abs(y - screen_loc.y());
45 
46   int enable_delta_x = kPopupWidth / 2;
47   int enable_delta_y = kPopupHeight / 2;
48   int hot_spot_delta_x = kHotSpotDeltaX;
49   int hot_spot_delta_y = kHotSpotDeltaY;
50 
51   switch (type) {
52     case DockInfo::LEFT_HALF:
53     case DockInfo::RIGHT_HALF:
54       enable_delta_x += enable_delta_x;
55       hot_spot_delta_x += hot_spot_delta_x;
56       break;
57 
58 
59     case DockInfo::MAXIMIZE: {
60       // Make the maximize height smaller than the tab height to avoid showing
61       // the dock indicator when close to maximized browser.
62       hot_spot_delta_y = GetHotSpotDeltaY();
63       enable_delta_y = hot_spot_delta_y / 2;
64       break;
65     }
66     case DockInfo::BOTTOM_HALF:
67       enable_delta_y += enable_delta_y;
68       hot_spot_delta_y += hot_spot_delta_y;
69       break;
70 
71     default:
72       NOTREACHED();
73       return false;
74   }
75   *in_enable_area = (delta_x < enable_delta_x && delta_y < enable_delta_y);
76   bool result = (*in_enable_area || (delta_x < hot_spot_delta_x &&
77                                      delta_y < hot_spot_delta_y));
78   if (type != DockInfo::MAXIMIZE)
79     return result;
80 
81   // Make the hot spot/enable spot for maximized windows the whole top of the
82   // monitor.
83   int max_delta_y = abs(screen_loc.y() - y);
84   *in_enable_area = (*in_enable_area || (max_delta_y < enable_delta_y));
85   return *in_enable_area || (max_delta_y < hot_spot_delta_y);
86 }
87 
88 // static
popup_width()89 int DockInfo::popup_width() {
90   return kPopupWidth;
91 }
92 
93 // static
popup_height()94 int DockInfo::popup_height() {
95   return kPopupHeight;
96 }
97 
IsValidForPoint(const gfx::Point & screen_point)98 bool DockInfo::IsValidForPoint(const gfx::Point& screen_point) {
99   if (type_ == NONE)
100     return false;
101 
102   if (window_) {
103     return IsCloseToPoint(screen_point, hot_spot_.x(), hot_spot_.y(),
104                           &in_enable_area_);
105   }
106 
107   return monitor_bounds_.Contains(screen_point) &&
108           IsCloseToMonitorPoint(screen_point, hot_spot_.x(),
109                                 hot_spot_.y(), type_, &in_enable_area_);
110 }
111 
GetNewWindowBounds(gfx::Rect * new_window_bounds,bool * maximize_new_window) const112 bool DockInfo::GetNewWindowBounds(gfx::Rect* new_window_bounds,
113                                   bool* maximize_new_window) const {
114   if (type_ == NONE || !in_enable_area_)
115     return false;
116 
117   gfx::Rect window_bounds;
118   if (window_ && !GetWindowBounds(&window_bounds))
119     return false;
120 
121   int half_m_width = (monitor_bounds_.right() - monitor_bounds_.x()) / 2;
122   int half_m_height = (monitor_bounds_.bottom() - monitor_bounds_.y()) / 2;
123 
124   *maximize_new_window = false;
125 
126   switch (type_) {
127     case LEFT_OF_WINDOW:
128       new_window_bounds->SetRect(monitor_bounds_.x(), window_bounds.y(),
129                                  half_m_width, window_bounds.height());
130       break;
131 
132     case RIGHT_OF_WINDOW:
133       new_window_bounds->SetRect(monitor_bounds_.x() + half_m_width,
134                                  window_bounds.y(), half_m_width,
135                                  window_bounds.height());
136       break;
137 
138     case TOP_OF_WINDOW:
139       new_window_bounds->SetRect(window_bounds.x(), monitor_bounds_.y(),
140                                  window_bounds.width(), half_m_height);
141       break;
142 
143     case BOTTOM_OF_WINDOW:
144       new_window_bounds->SetRect(window_bounds.x(),
145                                  monitor_bounds_.y() + half_m_height,
146                                  window_bounds.width(), half_m_height);
147       break;
148 
149     case LEFT_HALF:
150       new_window_bounds->SetRect(monitor_bounds_.x(), monitor_bounds_.y(),
151                                  half_m_width, monitor_bounds_.height());
152       break;
153 
154     case RIGHT_HALF:
155       new_window_bounds->SetRect(monitor_bounds_.right() - half_m_width,
156           monitor_bounds_.y(), half_m_width, monitor_bounds_.height());
157       break;
158 
159     case BOTTOM_HALF:
160       new_window_bounds->SetRect(monitor_bounds_.x(),
161                                  monitor_bounds_.y() + half_m_height,
162                                  monitor_bounds_.width(), half_m_height);
163       break;
164 
165     case MAXIMIZE:
166       *maximize_new_window = true;
167       break;
168 
169     default:
170       NOTREACHED();
171   }
172   return true;
173 }
174 
AdjustOtherWindowBounds() const175 void DockInfo::AdjustOtherWindowBounds() const {
176   if (!in_enable_area_)
177     return;
178 
179   gfx::Rect window_bounds;
180   if (!window_ || !GetWindowBounds(&window_bounds))
181     return;
182 
183   gfx::Rect other_window_bounds;
184   int half_m_width = (monitor_bounds_.right() - monitor_bounds_.x()) / 2;
185   int half_m_height = (monitor_bounds_.bottom() - monitor_bounds_.y()) / 2;
186 
187   switch (type_) {
188     case LEFT_OF_WINDOW:
189       other_window_bounds.SetRect(monitor_bounds_.x() + half_m_width,
190                                   window_bounds.y(), half_m_width,
191                                   window_bounds.height());
192       break;
193 
194     case RIGHT_OF_WINDOW:
195       other_window_bounds.SetRect(monitor_bounds_.x(), window_bounds.y(),
196                                   half_m_width, window_bounds.height());
197       break;
198 
199     case TOP_OF_WINDOW:
200       other_window_bounds.SetRect(window_bounds.x(),
201                                   monitor_bounds_.y() + half_m_height,
202                                   window_bounds.width(), half_m_height);
203       break;
204 
205     case BOTTOM_OF_WINDOW:
206       other_window_bounds.SetRect(window_bounds.x(), monitor_bounds_.y(),
207                                   window_bounds.width(), half_m_height);
208       break;
209 
210     default:
211       return;
212   }
213 
214   SizeOtherWindowTo(other_window_bounds);
215 }
216 
GetPopupRect() const217 gfx::Rect DockInfo::GetPopupRect() const {
218   int x = hot_spot_.x() - popup_width() / 2;
219   int y = hot_spot_.y() - popup_height() / 2;
220   switch (type_) {
221     case LEFT_OF_WINDOW:
222     case RIGHT_OF_WINDOW:
223     case TOP_OF_WINDOW:
224     case BOTTOM_OF_WINDOW: {
225       // Constrain the popup to the monitor's bounds.
226       gfx::Rect ideal_bounds(x, y, popup_width(), popup_height());
227       ideal_bounds.AdjustToFit(monitor_bounds_);
228       return ideal_bounds;
229     }
230     case DockInfo::MAXIMIZE:
231       y += popup_height() / 2;
232       break;
233     case DockInfo::LEFT_HALF:
234       x += popup_width() / 2;
235       break;
236     case DockInfo::RIGHT_HALF:
237       x -= popup_width() / 2;
238       break;
239     case DockInfo::BOTTOM_HALF:
240       y -= popup_height() / 2;
241       break;
242 
243     default:
244       NOTREACHED();
245   }
246   return gfx::Rect(x, y, popup_width(), popup_height());
247 }
248 
CheckMonitorPoint(const gfx::Point & screen_loc,int x,int y,Type type)249 bool DockInfo::CheckMonitorPoint(const gfx::Point& screen_loc,
250                                  int x,
251                                  int y,
252                                  Type type) {
253   if (IsCloseToMonitorPoint(screen_loc, x, y, type, &in_enable_area_)) {
254     hot_spot_.SetPoint(x, y);
255     type_ = type;
256     return true;
257   }
258   return false;
259 }
260