OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/frame/app_panel_browser_frame_view.h" | 5 #include "chrome/browser/ui/views/frame/app_panel_browser_frame_view.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
9 #include "chrome/browser/ui/views/frame/browser_frame.h" | 9 #include "chrome/browser/ui/views/frame/browser_frame.h" |
10 #include "chrome/browser/ui/views/frame/browser_view.h" | 10 #include "chrome/browser/ui/views/frame/browser_view.h" |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), | 139 return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), |
140 std::max(0, client_bounds.y() - top_height), | 140 std::max(0, client_bounds.y() - top_height), |
141 client_bounds.width() + (2 * border_thickness), | 141 client_bounds.width() + (2 * border_thickness), |
142 client_bounds.height() + top_height + border_thickness); | 142 client_bounds.height() + top_height + border_thickness); |
143 } | 143 } |
144 | 144 |
145 int AppPanelBrowserFrameView::NonClientHitTest(const gfx::Point& point) { | 145 int AppPanelBrowserFrameView::NonClientHitTest(const gfx::Point& point) { |
146 if (!bounds().Contains(point)) | 146 if (!bounds().Contains(point)) |
147 return HTNOWHERE; | 147 return HTNOWHERE; |
148 | 148 |
149 int frame_component = | 149 int frame_component = frame_->client_view()->NonClientHitTest(point); |
150 frame_->GetWindow()->client_view()->NonClientHitTest(point); | |
151 | 150 |
152 // See if we're in the sysmenu region. (We check the ClientView first to be | 151 // See if we're in the sysmenu region. (We check the ClientView first to be |
153 // consistent with OpaqueBrowserFrameView; it's not really necessary here.) | 152 // consistent with OpaqueBrowserFrameView; it's not really necessary here.) |
154 gfx::Rect sysmenu_rect(IconBounds()); | 153 gfx::Rect sysmenu_rect(IconBounds()); |
155 // In maximized mode we extend the rect to the screen corner to take advantage | 154 // In maximized mode we extend the rect to the screen corner to take advantage |
156 // of Fitts' Law. | 155 // of Fitts' Law. |
157 if (frame_->GetWindow()->IsMaximized()) | 156 if (frame_->IsMaximized()) |
158 sysmenu_rect.SetRect(0, 0, sysmenu_rect.right(), sysmenu_rect.bottom()); | 157 sysmenu_rect.SetRect(0, 0, sysmenu_rect.right(), sysmenu_rect.bottom()); |
159 sysmenu_rect.set_x(GetMirroredXForRect(sysmenu_rect)); | 158 sysmenu_rect.set_x(GetMirroredXForRect(sysmenu_rect)); |
160 if (sysmenu_rect.Contains(point)) | 159 if (sysmenu_rect.Contains(point)) |
161 return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; | 160 return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; |
162 | 161 |
163 if (frame_component != HTNOWHERE) | 162 if (frame_component != HTNOWHERE) |
164 return frame_component; | 163 return frame_component; |
165 | 164 |
166 // Then see if the point is within any of the window controls. | 165 // Then see if the point is within any of the window controls. |
167 if (close_button_->IsVisible() && | 166 if (close_button_->IsVisible() && |
168 close_button_->GetMirroredBounds().Contains(point)) | 167 close_button_->GetMirroredBounds().Contains(point)) |
169 return HTCLOSE; | 168 return HTCLOSE; |
170 | 169 |
171 int window_component = GetHTComponentForFrame(point, | 170 int window_component = GetHTComponentForFrame(point, |
172 NonClientBorderThickness(), NonClientBorderThickness(), | 171 NonClientBorderThickness(), NonClientBorderThickness(), |
173 kResizeAreaCornerSize, kResizeAreaCornerSize, | 172 kResizeAreaCornerSize, kResizeAreaCornerSize, |
174 frame_->GetWindow()->window_delegate()->CanResize()); | 173 frame_->window_delegate()->CanResize()); |
175 // Fall back to the caption if no other component matches. | 174 // Fall back to the caption if no other component matches. |
176 return (window_component == HTNOWHERE) ? HTCAPTION : window_component; | 175 return (window_component == HTNOWHERE) ? HTCAPTION : window_component; |
177 } | 176 } |
178 | 177 |
179 void AppPanelBrowserFrameView::GetWindowMask(const gfx::Size& size, | 178 void AppPanelBrowserFrameView::GetWindowMask(const gfx::Size& size, |
180 gfx::Path* window_mask) { | 179 gfx::Path* window_mask) { |
181 DCHECK(window_mask); | 180 DCHECK(window_mask); |
182 | 181 |
183 if (frame_->GetWindow()->IsMaximized()) | 182 if (frame_->IsMaximized()) |
184 return; | 183 return; |
185 | 184 |
186 // Redefine the window visible region for the new size. | 185 // Redefine the window visible region for the new size. |
187 window_mask->moveTo(0, 3); | 186 window_mask->moveTo(0, 3); |
188 window_mask->lineTo(1, 2); | 187 window_mask->lineTo(1, 2); |
189 window_mask->lineTo(1, 1); | 188 window_mask->lineTo(1, 1); |
190 window_mask->lineTo(2, 1); | 189 window_mask->lineTo(2, 1); |
191 window_mask->lineTo(3, 0); | 190 window_mask->lineTo(3, 0); |
192 | 191 |
193 window_mask->lineTo(SkIntToScalar(size.width() - 3), 0); | 192 window_mask->lineTo(SkIntToScalar(size.width() - 3), 0); |
(...skipping 18 matching lines...) Expand all Loading... |
212 | 211 |
213 void AppPanelBrowserFrameView::UpdateWindowIcon() { | 212 void AppPanelBrowserFrameView::UpdateWindowIcon() { |
214 window_icon_->SchedulePaint(); | 213 window_icon_->SchedulePaint(); |
215 } | 214 } |
216 | 215 |
217 | 216 |
218 /////////////////////////////////////////////////////////////////////////////// | 217 /////////////////////////////////////////////////////////////////////////////// |
219 // AppPanelBrowserFrameView, views::View overrides: | 218 // AppPanelBrowserFrameView, views::View overrides: |
220 | 219 |
221 void AppPanelBrowserFrameView::OnPaint(gfx::Canvas* canvas) { | 220 void AppPanelBrowserFrameView::OnPaint(gfx::Canvas* canvas) { |
222 views::Window* window = frame_->GetWindow(); | 221 if (frame_->IsMaximized()) |
223 if (window->IsMaximized()) | |
224 PaintMaximizedFrameBorder(canvas); | 222 PaintMaximizedFrameBorder(canvas); |
225 else | 223 else |
226 PaintRestoredFrameBorder(canvas); | 224 PaintRestoredFrameBorder(canvas); |
227 PaintTitleBar(canvas); | 225 PaintTitleBar(canvas); |
228 if (!window->IsMaximized()) | 226 if (!frame_->IsMaximized()) |
229 PaintRestoredClientEdge(canvas); | 227 PaintRestoredClientEdge(canvas); |
230 } | 228 } |
231 | 229 |
232 void AppPanelBrowserFrameView::Layout() { | 230 void AppPanelBrowserFrameView::Layout() { |
233 LayoutWindowControls(); | 231 LayoutWindowControls(); |
234 LayoutTitleBar(); | 232 LayoutTitleBar(); |
235 client_view_bounds_ = CalculateClientAreaBounds(width(), height()); | 233 client_view_bounds_ = CalculateClientAreaBounds(width(), height()); |
236 } | 234 } |
237 | 235 |
238 /////////////////////////////////////////////////////////////////////////////// | 236 /////////////////////////////////////////////////////////////////////////////// |
239 // AppPanelBrowserFrameView, views::ButtonListener implementation: | 237 // AppPanelBrowserFrameView, views::ButtonListener implementation: |
240 | 238 |
241 void AppPanelBrowserFrameView::ButtonPressed(views::Button* sender, | 239 void AppPanelBrowserFrameView::ButtonPressed(views::Button* sender, |
242 const views::Event& event) { | 240 const views::Event& event) { |
243 if (sender == close_button_) | 241 if (sender == close_button_) |
244 frame_->GetWindow()->CloseWindow(); | 242 frame_->Close(); |
245 } | 243 } |
246 | 244 |
247 /////////////////////////////////////////////////////////////////////////////// | 245 /////////////////////////////////////////////////////////////////////////////// |
248 // AppPanelBrowserFrameView, TabIconView::TabContentsProvider implementation: | 246 // AppPanelBrowserFrameView, TabIconView::TabContentsProvider implementation: |
249 | 247 |
250 bool AppPanelBrowserFrameView::ShouldTabIconViewAnimate() const { | 248 bool AppPanelBrowserFrameView::ShouldTabIconViewAnimate() const { |
251 // This function is queried during the creation of the window as the | 249 // This function is queried during the creation of the window as the |
252 // TabIconView we host is initialized, so we need to NULL check the selected | 250 // TabIconView we host is initialized, so we need to NULL check the selected |
253 // TabContents because in this condition there is not yet a selected tab. | 251 // TabContents because in this condition there is not yet a selected tab. |
254 TabContents* current_tab = browser_view_->GetSelectedTabContents(); | 252 TabContents* current_tab = browser_view_->GetSelectedTabContents(); |
255 return current_tab ? current_tab->is_loading() : false; | 253 return current_tab ? current_tab->is_loading() : false; |
256 } | 254 } |
257 | 255 |
258 SkBitmap AppPanelBrowserFrameView::GetFaviconForTabIconView() { | 256 SkBitmap AppPanelBrowserFrameView::GetFaviconForTabIconView() { |
259 return frame_->GetWindow()->window_delegate()->GetWindowIcon(); | 257 return frame_->window_delegate()->GetWindowIcon(); |
260 } | 258 } |
261 | 259 |
262 /////////////////////////////////////////////////////////////////////////////// | 260 /////////////////////////////////////////////////////////////////////////////// |
263 // AppPanelBrowserFrameView, private: | 261 // AppPanelBrowserFrameView, private: |
264 | 262 |
265 int AppPanelBrowserFrameView::FrameBorderThickness() const { | 263 int AppPanelBrowserFrameView::FrameBorderThickness() const { |
266 return frame_->GetWindow()->IsMaximized() ? 0 : kFrameBorderThickness; | 264 return frame_->IsMaximized() ? 0 : kFrameBorderThickness; |
267 } | 265 } |
268 | 266 |
269 int AppPanelBrowserFrameView::NonClientBorderThickness() const { | 267 int AppPanelBrowserFrameView::NonClientBorderThickness() const { |
270 return FrameBorderThickness() + | 268 return FrameBorderThickness() + |
271 (frame_->GetWindow()->IsMaximized() ? 0 : kClientEdgeThickness); | 269 (frame_->IsMaximized() ? 0 : kClientEdgeThickness); |
272 } | 270 } |
273 | 271 |
274 int AppPanelBrowserFrameView::NonClientTopBorderHeight() const { | 272 int AppPanelBrowserFrameView::NonClientTopBorderHeight() const { |
275 return std::max(FrameBorderThickness() + IconSize(), | 273 return std::max(FrameBorderThickness() + IconSize(), |
276 FrameBorderThickness() + kCaptionButtonHeightWithPadding) + | 274 FrameBorderThickness() + kCaptionButtonHeightWithPadding) + |
277 TitlebarBottomThickness(); | 275 TitlebarBottomThickness(); |
278 } | 276 } |
279 | 277 |
280 int AppPanelBrowserFrameView::TitlebarBottomThickness() const { | 278 int AppPanelBrowserFrameView::TitlebarBottomThickness() const { |
281 return kTitlebarTopAndBottomEdgeThickness + | 279 return kTitlebarTopAndBottomEdgeThickness + |
282 (frame_->GetWindow()->IsMaximized() ? 0 : kClientEdgeThickness); | 280 (frame_->IsMaximized() ? 0 : kClientEdgeThickness); |
283 } | 281 } |
284 | 282 |
285 int AppPanelBrowserFrameView::IconSize() const { | 283 int AppPanelBrowserFrameView::IconSize() const { |
286 #if defined(OS_WIN) | 284 #if defined(OS_WIN) |
287 // This metric scales up if either the titlebar height or the titlebar font | 285 // This metric scales up if either the titlebar height or the titlebar font |
288 // size are increased. | 286 // size are increased. |
289 return GetSystemMetrics(SM_CYSMICON); | 287 return GetSystemMetrics(SM_CYSMICON); |
290 #else | 288 #else |
291 return std::max(BrowserFrame::GetTitleFont().height(), kIconMinimumSize); | 289 return std::max(BrowserFrame::GetTitleFont().height(), kIconMinimumSize); |
292 #endif | 290 #endif |
293 } | 291 } |
294 | 292 |
295 gfx::Rect AppPanelBrowserFrameView::IconBounds() const { | 293 gfx::Rect AppPanelBrowserFrameView::IconBounds() const { |
296 int size = IconSize(); | 294 int size = IconSize(); |
297 int frame_thickness = FrameBorderThickness(); | 295 int frame_thickness = FrameBorderThickness(); |
298 // Our frame border has a different "3D look" than Windows'. Theirs has a | 296 // Our frame border has a different "3D look" than Windows'. Theirs has a |
299 // more complex gradient on the top that they push their icon/title below; | 297 // more complex gradient on the top that they push their icon/title below; |
300 // then the maximized window cuts this off and the icon/title are centered | 298 // then the maximized window cuts this off and the icon/title are centered |
301 // in the remaining space. Because the apparent shape of our border is | 299 // in the remaining space. Because the apparent shape of our border is |
302 // simpler, using the same positioning makes things look slightly uncentered | 300 // simpler, using the same positioning makes things look slightly uncentered |
303 // with restored windows, so when the window is restored, instead of | 301 // with restored windows, so when the window is restored, instead of |
304 // calculating the remaining space from below the frame border, we calculate | 302 // calculating the remaining space from below the frame border, we calculate |
305 // from below the top border-plus-padding. | 303 // from below the top border-plus-padding. |
306 int unavailable_px_at_top = frame_->GetWindow()->IsMaximized() ? | 304 int unavailable_px_at_top = frame_->IsMaximized() ? |
307 frame_thickness : kTitlebarTopAndBottomEdgeThickness; | 305 frame_thickness : kTitlebarTopAndBottomEdgeThickness; |
308 // When the icon is shorter than the minimum space we reserve for the caption | 306 // When the icon is shorter than the minimum space we reserve for the caption |
309 // button, we vertically center it. We want to bias rounding to put extra | 307 // button, we vertically center it. We want to bias rounding to put extra |
310 // space above the icon, since the 3D edge (+ client edge, for restored | 308 // space above the icon, since the 3D edge (+ client edge, for restored |
311 // windows) below looks (to the eye) more like additional space than does the | 309 // windows) below looks (to the eye) more like additional space than does the |
312 // border + padding (or nothing at all, for maximized windows) above; hence | 310 // border + padding (or nothing at all, for maximized windows) above; hence |
313 // the +1. | 311 // the +1. |
314 int y = unavailable_px_at_top + (NonClientTopBorderHeight() - | 312 int y = unavailable_px_at_top + (NonClientTopBorderHeight() - |
315 unavailable_px_at_top - size - TitlebarBottomThickness() + 1) / 2; | 313 unavailable_px_at_top - size - TitlebarBottomThickness() + 1) / 2; |
316 return gfx::Rect(frame_thickness + kIconLeftSpacing, y, size, size); | 314 return gfx::Rect(frame_thickness + kIconLeftSpacing, y, size, size); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 | 392 |
395 SkBitmap* frame_image = rb.GetBitmapNamed(IDR_FRAME_APP_PANEL); | 393 SkBitmap* frame_image = rb.GetBitmapNamed(IDR_FRAME_APP_PANEL); |
396 canvas->TileImageInt(*frame_image, 0, FrameBorderThickness(), width(), | 394 canvas->TileImageInt(*frame_image, 0, FrameBorderThickness(), width(), |
397 frame_image->height()); | 395 frame_image->height()); |
398 | 396 |
399 // The bottom of the titlebar actually comes from the top of the Client Edge | 397 // The bottom of the titlebar actually comes from the top of the Client Edge |
400 // graphic, with the actual client edge clipped off the bottom. | 398 // graphic, with the actual client edge clipped off the bottom. |
401 SkBitmap* titlebar_bottom = rb.GetBitmapNamed(IDR_APP_TOP_CENTER); | 399 SkBitmap* titlebar_bottom = rb.GetBitmapNamed(IDR_APP_TOP_CENTER); |
402 int edge_height = titlebar_bottom->height() - kClientEdgeThickness; | 400 int edge_height = titlebar_bottom->height() - kClientEdgeThickness; |
403 canvas->TileImageInt(*titlebar_bottom, 0, | 401 canvas->TileImageInt(*titlebar_bottom, 0, |
404 frame_->GetWindow()->client_view()->y() - edge_height, | 402 frame_->client_view()->y() - edge_height, |
405 width(), edge_height); | 403 width(), edge_height); |
406 } | 404 } |
407 | 405 |
408 void AppPanelBrowserFrameView::PaintTitleBar(gfx::Canvas* canvas) { | 406 void AppPanelBrowserFrameView::PaintTitleBar(gfx::Canvas* canvas) { |
409 // The window icon is painted by the TabIconView. | 407 // The window icon is painted by the TabIconView. |
410 views::WindowDelegate* d = frame_->GetWindow()->window_delegate(); | 408 views::WindowDelegate* d = frame_->window_delegate(); |
411 canvas->DrawStringInt(d->GetWindowTitle(), BrowserFrame::GetTitleFont(), | 409 canvas->DrawStringInt(d->GetWindowTitle(), BrowserFrame::GetTitleFont(), |
412 SK_ColorBLACK, GetMirroredXForRect(title_bounds_), title_bounds_.y(), | 410 SK_ColorBLACK, GetMirroredXForRect(title_bounds_), title_bounds_.y(), |
413 title_bounds_.width(), title_bounds_.height()); | 411 title_bounds_.width(), title_bounds_.height()); |
414 } | 412 } |
415 | 413 |
416 void AppPanelBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { | 414 void AppPanelBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { |
417 gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height()); | 415 gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height()); |
418 int client_area_top = client_area_bounds.y(); | 416 int client_area_top = client_area_bounds.y(); |
419 | 417 |
420 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 418 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 canvas->DrawRectInt(ResourceBundle::toolbar_color, | 458 canvas->DrawRectInt(ResourceBundle::toolbar_color, |
461 client_area_bounds.x() - kClientEdgeThickness, | 459 client_area_bounds.x() - kClientEdgeThickness, |
462 client_area_top - kClientEdgeThickness, | 460 client_area_top - kClientEdgeThickness, |
463 client_area_bounds.width() + kClientEdgeThickness, | 461 client_area_bounds.width() + kClientEdgeThickness, |
464 client_area_bottom - client_area_top + kClientEdgeThickness); | 462 client_area_bottom - client_area_top + kClientEdgeThickness); |
465 } | 463 } |
466 | 464 |
467 void AppPanelBrowserFrameView::LayoutWindowControls() { | 465 void AppPanelBrowserFrameView::LayoutWindowControls() { |
468 close_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, | 466 close_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, |
469 views::ImageButton::ALIGN_BOTTOM); | 467 views::ImageButton::ALIGN_BOTTOM); |
470 bool is_maximized = frame_->GetWindow()->IsMaximized(); | 468 bool is_maximized = frame_->IsMaximized(); |
471 // There should always be the same number of non-border pixels visible to the | 469 // There should always be the same number of non-border pixels visible to the |
472 // side of the close button. In maximized mode we extend the button to the | 470 // side of the close button. In maximized mode we extend the button to the |
473 // screen corner to obey Fitts' Law. | 471 // screen corner to obey Fitts' Law. |
474 int right_extra_width = is_maximized ? kCloseButtonFrameBorderSpacing : 0; | 472 int right_extra_width = is_maximized ? kCloseButtonFrameBorderSpacing : 0; |
475 gfx::Size close_button_size = close_button_->GetPreferredSize(); | 473 gfx::Size close_button_size = close_button_->GetPreferredSize(); |
476 int close_button_y = | 474 int close_button_y = |
477 (NonClientTopBorderHeight() - close_button_size.height()) / 2; | 475 (NonClientTopBorderHeight() - close_button_size.height()) / 2; |
478 int top_extra_height = is_maximized ? close_button_y : 0; | 476 int top_extra_height = is_maximized ? close_button_y : 0; |
479 close_button_->SetBounds(width() - FrameBorderThickness() - | 477 close_button_->SetBounds(width() - FrameBorderThickness() - |
480 kCloseButtonFrameBorderSpacing - close_button_size.width(), | 478 kCloseButtonFrameBorderSpacing - close_button_size.width(), |
(...skipping 22 matching lines...) Expand all Loading... |
503 } | 501 } |
504 | 502 |
505 gfx::Rect AppPanelBrowserFrameView::CalculateClientAreaBounds(int width, | 503 gfx::Rect AppPanelBrowserFrameView::CalculateClientAreaBounds(int width, |
506 int height) const { | 504 int height) const { |
507 int top_height = NonClientTopBorderHeight(); | 505 int top_height = NonClientTopBorderHeight(); |
508 int border_thickness = NonClientBorderThickness(); | 506 int border_thickness = NonClientBorderThickness(); |
509 return gfx::Rect(border_thickness, top_height, | 507 return gfx::Rect(border_thickness, top_height, |
510 std::max(0, width - (2 * border_thickness)), | 508 std::max(0, width - (2 * border_thickness)), |
511 std::max(0, height - top_height - border_thickness)); | 509 std::max(0, height - top_height - border_thickness)); |
512 } | 510 } |
OLD | NEW |