Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: chrome/browser/views/frame/opaque_non_client_view.cc

Issue 18804: OpaqueNonClientView cleanup (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/views/frame/opaque_non_client_view.h ('k') | chrome/common/gfx/chrome_canvas.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // 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 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/views/frame/opaque_non_client_view.h" 5 #include "chrome/browser/views/frame/opaque_non_client_view.h"
6 6
7 #include "chrome/app/theme/theme_resources.h" 7 #include "chrome/app/theme/theme_resources.h"
8 #include "chrome/browser/tab_contents/tab_contents.h" 8 #include "chrome/browser/tab_contents/tab_contents.h"
9 #include "chrome/browser/views/frame/browser_view.h" 9 #include "chrome/browser/views/frame/browser_view.h"
10 #include "chrome/browser/views/tabs/tab_strip.h" 10 #include "chrome/browser/views/tabs/tab_strip.h"
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 } 262 }
263 initialized = true; 263 initialized = true;
264 } 264 }
265 } 265 }
266 266
267 static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT]; 267 static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT];
268 static ChromeFont title_font_; 268 static ChromeFont title_font_;
269 269
270 DISALLOW_EVIL_CONSTRUCTORS(OTRInactiveWindowResources); 270 DISALLOW_EVIL_CONSTRUCTORS(OTRInactiveWindowResources);
271 }; 271 };
272
272 // static 273 // static
273 SkBitmap* ActiveWindowResources::standard_frame_bitmaps_[]; 274 SkBitmap* ActiveWindowResources::standard_frame_bitmaps_[];
274 SkBitmap* InactiveWindowResources::standard_frame_bitmaps_[]; 275 SkBitmap* InactiveWindowResources::standard_frame_bitmaps_[];
275 SkBitmap* OTRActiveWindowResources::standard_frame_bitmaps_[]; 276 SkBitmap* OTRActiveWindowResources::standard_frame_bitmaps_[];
276 SkBitmap* OTRInactiveWindowResources::standard_frame_bitmaps_[]; 277 SkBitmap* OTRInactiveWindowResources::standard_frame_bitmaps_[];
277 278
278 views::WindowResources* OpaqueNonClientView::active_resources_ = NULL; 279 views::WindowResources* OpaqueNonClientView::active_resources_ = NULL;
279 views::WindowResources* OpaqueNonClientView::inactive_resources_ = NULL; 280 views::WindowResources* OpaqueNonClientView::inactive_resources_ = NULL;
280 views::WindowResources* OpaqueNonClientView::active_otr_resources_ = NULL; 281 views::WindowResources* OpaqueNonClientView::active_otr_resources_ = NULL;
281 views::WindowResources* OpaqueNonClientView::inactive_otr_resources_ = NULL; 282 views::WindowResources* OpaqueNonClientView::inactive_otr_resources_ = NULL;
282 SkBitmap OpaqueNonClientView::distributor_logo_; 283 SkBitmap OpaqueNonClientView::distributor_logo_;
283 SkBitmap OpaqueNonClientView::app_top_left_; 284 SkBitmap OpaqueNonClientView::app_top_left_;
284 SkBitmap OpaqueNonClientView::app_top_center_; 285 SkBitmap OpaqueNonClientView::app_top_center_;
285 SkBitmap OpaqueNonClientView::app_top_right_; 286 SkBitmap OpaqueNonClientView::app_top_right_;
286 ChromeFont OpaqueNonClientView::title_font_; 287 ChromeFont OpaqueNonClientView::title_font_;
287 288
288 // The distance between the top of the window and the top of the window 289 namespace {
289 // controls when the window is restored. 290 // The frame border is only visible in restored mode and is hardcoded to 4 px on
290 static const int kWindowControlsTopOffset = 1; 291 // each side regardless of the system window border size.
291 // The distance between the right edge of the window and the right edge of the 292 const int kFrameBorderThickness = 4;
292 // right-most window control when the window is restored. 293 // In maximized mode, where no frame border is otherwise visible, we draw a
293 static const int kWindowControlsRightOffset = 4; 294 // different, 1 px high border along the bottom of the screen.
294 // The distance between the bottom of the window's top border and the top of the 295 const int kFrameBorderMaximizedExtraBottomThickness = 1;
295 // window controls' images when the window is maximized. We extend the 296 // Various edges of the frame border have a 1 px shadow along their edges; in a
296 // clickable area all the way to the top of the window to obey Fitts' Law. 297 // few cases we shift elements based on this amount for visual appeal.
297 static const int kWindowControlsZoomedTopExtraHeight = 1; 298 const int kFrameShadowThickness = 1;
298 // The distance between right edge of the right-most window control and the left 299 // Besides the frame border, there's another 11 px of empty space atop the
299 // edge of the window's right border when the window is maximized. 300 // window in restored mode, to use to drag the window around.
300 static const int kWindowControlsZoomedRightOffset = 3; 301 const int kNonClientRestoredExtraThickness = 11;
301 // The distance between the left edge of the window and the left edge of the 302 // In restored mode, we draw a 1 px edge around the content area inside the
302 // window icon when a title-bar is showing and the window is restored. 303 // frame border.
303 static const int kWindowIconLeftOffset = 6; 304 const int kClientEdgeThickness = 1;
304 // The distance between the right edge of the window's left border and the left 305 // While resize areas on Windows are normally the same size as the window
305 // edge of the window icon when a title-bar is showing and the window is 306 // borders, our top area is shrunk by 1 px to make it easier to move the window
306 // maximized. 307 // around with our thinner top grabbable strip. (Incidentally, our side and
307 static const int kWindowIconZoomedLeftOffset = 2; 308 // bottom resize areas don't match the frame border thickness either -- they
308 // The proportion of vertical space the icon takes up after subtracting the top 309 // span the whole nonclient area, so there's no "dead zone" for the mouse.)
309 // and bottom borders of the titlebar (expressed as two values to avoid 310 const int kTopResizeAdjust = 1;
310 // floating point representation errors that goof up the calculation). 311 // In the window corners, the resize areas don't actually expand bigger, but the
311 static const int kWindowIconFractionNumerator = 16; 312 // 16 px at the end of each edge triggers diagonal resizing.
312 static const int kWindowIconFractionDenominator = 25; 313 const int kResizeAreaCornerSize = 16;
313 // The distance between the top edge of the window and the top edge of the 314 // The titlebar never shrinks to less than 19 px tall, plus the height of the
314 // window title when a title-bar is showing and the window is restored. 315 // frame border.
315 static const int kWindowTitleTopOffset = 6; 316 const int kTitlebarMinimumHeight = 19;
316 // The distance between the bottom edge of the window's top border and the top 317 // The icon is inset 2 px from the left frame border.
317 // edge of the window title when a title-bar is showing and the window is 318 const int kIconLeftSpacing = 2;
318 // maximized. 319 // The icon takes up 16/25th of the available titlebar height. (This is
319 static const int kWindowTitleZoomedTopOffset = 4; 320 // expressed as two ints to avoid precision losses leading to off-by-one pixel
320 // The distance between the window icon and the window title when a title-bar 321 // errors.)
321 // is showing. 322 const int kIconHeightFractionNumerator = 16;
322 static const int kWindowIconTitleSpacing = 4; 323 const int kIconHeightFractionDenominator = 25;
323 // The distance between the right edge of the title text bounding box and the 324 // The icon never shrinks below 16 px on a side.
324 // left edge of the distributor logo. 325 const int kIconMinimumSize = 16;
325 static const int kTitleLogoSpacing = 5; 326 // Because our frame border has a different "3D look" than Windows', with a less
326 // The distance between the bottom of the title text and the TabStrip when a 327 // cluttered top edge, we need to shift the icon up by 1 px in restored mode so
327 // title-bar is showing and the window is restored. 328 // it looks more centered.
328 static const int kTitleBottomSpacing = 7; 329 const int kIconRestoredAdjust = 1;
329 // The distance between the bottom of the title text and the TabStrip when a 330 // There is a 4 px gap between the icon and the title text.
330 // title-bar is showing and the window is maximized. 331 const int kIconTitleSpacing = 4;
331 static const int kTitleZoomedBottomSpacing = 5; 332 // The title text starts 2 px below the bottom of the top frame border.
332 // The distance between the top edge of the window and the TabStrip when there 333 const int kTitleTopSpacing = 2;
333 // is no title-bar showing, and the window is restored. 334 // There is a 5 px gap between the title text and the distributor logo (if
334 static const int kNoTitleTopSpacing = 15; 335 // present) or caption buttons.
335 // The number of pixels to crop off the bottom of the images making up the top 336 const int kTitleLogoSpacing = 5;
336 // client edge when the window is maximized, so we only draw a shadowed titlebar 337 // In maximized mode, the OTR avatar starts 2 px below the top of the screen, so
337 // and not a grey client area border below it. 338 // that it doesn't extend into the "3D edge" portion of the titlebar.
338 static const int kClientEdgeZoomedBottomCrop = 1; 339 const int kOTRMaximizedTopSpacing = 2;
339 // The amount of horizontal and vertical distance from a corner of the window 340 // The OTR avatar ends 2 px above the bottom of the tabstrip (which, given the
340 // within which a mouse-drive resize operation will resize the window in two 341 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the
341 // dimensions. 342 // user).
342 static const int kResizeAreaCornerSize = 16; 343 const int kOTRBottomSpacing = 2;
343 // The width of the sizing border on the left and right edge of the window. 344 // There are 2 px on each side of the OTR avatar (between the frame border and
344 static const int kWindowHorizontalBorderSize = 5; 345 // it on the left, and between it and the tabstrip on the right).
345 // The height of the sizing border at the top edge of the window 346 const int kOTRSideSpacing = 2;
346 static const int kWindowVerticalBorderTopSize = 3; 347 // In restored mode, the New Tab button isn't at the same height as the caption
347 // The height of the sizing border on the bottom edge of the window when the 348 // buttons, but the space will look cluttered if it actually slides under them,
348 // window is restored. 349 // so we stop it when the gap between the two is down to 5 px.
349 static const int kWindowVerticalBorderBottomSize = 5; 350 const int kNewTabCaptionRestoredSpacing = 5;
350 // The additional height beyond the system-provided thickness of the border on 351 // In maximized mode, where the New Tab button and the caption buttons are at
351 // the bottom edge of the window when the window is maximized. 352 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid
352 static const int kWindowVerticalBorderZoomedBottomSize = 1; 353 // looking too cluttered.
353 // The minimum width and height of the window icon that appears at the top left 354 const int kNewTabCaptionMaximizedSpacing = 16;
354 // of pop-up and app windows. 355 // When there's a distributor logo, we leave a 7 px gap between it and the
355 static const int kWindowIconMinimumSize = 16; 356 // caption buttons.
356 // The minimum height reserved for the window title font. 357 const int kLogoCaptionSpacing = 7;
357 static const int kWindowTitleMinimumHeight = 11; 358 // The caption buttons are always drawn 1 px down from the visible top of the
358 // The horizontal distance of the right edge of the distributor logo from the 359 // window (the true top in restored mode, or the top of the screen in maximized
359 // left edge of the left-most window control. 360 // mode).
360 static const int kDistributorLogoHorizontalOffset = 7; 361 const int kCaptionTopSpacing = 1;
361 // The vertical distance of the top of the distributor logo from the top edge 362 }
362 // of the window.
363 static const int kDistributorLogoVerticalOffset = 3;
364 // The distance between the left edge of the window and the OTR avatar icon when
365 // the window is restored.
366 static const int kOTRLeftOffset = 7;
367 // The distance between the right edge of the window's left border and the OTR
368 // avatar icon when the window is maximized.
369 static const int kOTRZoomedLeftOffset = 2;
370 // The distance between the top edge of the client area and the OTR avatar icon
371 // when the window is maximized.
372 static const int kOTRZoomedTopSpacing = 2;
373 // The distance between the bottom of the OTR avatar icon and the bottom of the
374 // tabstrip.
375 static const int kOTRBottomSpacing = 2;
376 // The number of pixels to crop off the top of the OTR image when the window is
377 // maximized.
378 static const int kOTRZoomedTopCrop = 4;
379 // Horizontal distance between the right edge of the OTR avatar icon and the
380 // left edge of the tabstrip.
381 static const int kOTRTabStripSpacing = 2;
382 // Horizontal distance between the right edge of the new tab icon and the left
383 // edge of the window minimize icon when the window is restored.
384 static const int kNewTabIconMinimizeSpacing = 5;
385 // Horizontal distance between the right edge of the new tab icon and the left
386 // edge of the window minimize icon when the window is maximized.
387 static const int kNewTabIconMinimizeZoomedSpacing = 16;
388 363
389 /////////////////////////////////////////////////////////////////////////////// 364 ///////////////////////////////////////////////////////////////////////////////
390 // OpaqueNonClientView, public: 365 // OpaqueNonClientView, public:
391 366
392 OpaqueNonClientView::OpaqueNonClientView(OpaqueFrame* frame, 367 OpaqueNonClientView::OpaqueNonClientView(OpaqueFrame* frame,
393 BrowserView* browser_view) 368 BrowserView* browser_view)
394 : NonClientView(), 369 : NonClientView(),
395 minimize_button_(new views::Button), 370 minimize_button_(new views::Button),
396 maximize_button_(new views::Button), 371 maximize_button_(new views::Button),
397 restore_button_(new views::Button), 372 restore_button_(new views::Button),
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 // Loading fonts is expensive. 455 // Loading fonts is expensive.
481 if (browser_view_->ShouldShowWindowTitle()) 456 if (browser_view_->ShouldShowWindowTitle())
482 InitAppWindowResources(); 457 InitAppWindowResources();
483 } 458 }
484 459
485 OpaqueNonClientView::~OpaqueNonClientView() { 460 OpaqueNonClientView::~OpaqueNonClientView() {
486 } 461 }
487 462
488 gfx::Rect OpaqueNonClientView::GetWindowBoundsForClientBounds( 463 gfx::Rect OpaqueNonClientView::GetWindowBoundsForClientBounds(
489 const gfx::Rect& client_bounds) { 464 const gfx::Rect& client_bounds) {
490 int top_height = CalculateNonClientTopHeight(); 465 int top_height = NonClientTopBorderHeight();
491 int horizontal_border = HorizontalBorderSize(); 466 int border_width = NonClientBorderWidth();
492 int window_x = std::max(0, client_bounds.x() - horizontal_border); 467 int window_x = std::max(0, client_bounds.x() - border_width);
493 int window_y = std::max(0, client_bounds.y() - top_height); 468 int window_y = std::max(0, client_bounds.y() - top_height);
494 int window_w = client_bounds.width() + (2 * horizontal_border); 469 int window_w = client_bounds.width() + (2 * border_width);
495 int window_h = 470 int window_h =
496 client_bounds.height() + top_height + VerticalBorderBottomSize(); 471 client_bounds.height() + top_height + NonClientBottomBorderHeight();
497 return gfx::Rect(window_x, window_y, window_w, window_h); 472 return gfx::Rect(window_x, window_y, window_w, window_h);
498 } 473 }
499 474
500 gfx::Rect OpaqueNonClientView::GetBoundsForTabStrip(TabStrip* tabstrip) { 475 gfx::Rect OpaqueNonClientView::GetBoundsForTabStrip(TabStrip* tabstrip) {
501 int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ? 476 int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ?
502 (otr_avatar_bounds_.right() + kOTRTabStripSpacing) : 477 (otr_avatar_bounds_.right() + kOTRSideSpacing) : NonClientBorderWidth();
503 HorizontalBorderSize();
504 int tabstrip_width = minimize_button_->x() - tabstrip_x - 478 int tabstrip_width = minimize_button_->x() - tabstrip_x -
505 (frame_->IsMaximized() ? 479 (frame_->IsMaximized() ?
506 kNewTabIconMinimizeZoomedSpacing : kNewTabIconMinimizeSpacing); 480 kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing);
507 return gfx::Rect(tabstrip_x, CalculateNonClientTopHeight(), 481 return gfx::Rect(tabstrip_x, NonClientTopBorderHeight(),
508 std::max(0, tabstrip_width), tabstrip->GetPreferredHeight()); 482 std::max(0, tabstrip_width), tabstrip->GetPreferredHeight());
509 } 483 }
510 484
511 void OpaqueNonClientView::UpdateWindowIcon() { 485 void OpaqueNonClientView::UpdateWindowIcon() {
512 if (window_icon_) 486 if (window_icon_)
513 window_icon_->Update(); 487 window_icon_->Update();
514 } 488 }
515 489
516 /////////////////////////////////////////////////////////////////////////////// 490 ///////////////////////////////////////////////////////////////////////////////
517 // OpaqueNonClientView, TabIconView::TabContentsProvider implementation: 491 // OpaqueNonClientView, TabIconView::TabContentsProvider implementation:
518 492
519 bool OpaqueNonClientView::ShouldTabIconViewAnimate() const { 493 bool OpaqueNonClientView::ShouldTabIconViewAnimate() const {
520 // This function is queried during the creation of the window as the 494 // This function is queried during the creation of the window as the
521 // TabIconView we host is initialized, so we need to NULL check the selected 495 // TabIconView we host is initialized, so we need to NULL check the selected
522 // TabContents because in this condition there is not yet a selected tab. 496 // TabContents because in this condition there is not yet a selected tab.
523 TabContents* current_tab = browser_view_->GetSelectedTabContents(); 497 TabContents* current_tab = browser_view_->GetSelectedTabContents();
524 return current_tab ? current_tab->is_loading() : false; 498 return current_tab ? current_tab->is_loading() : false;
525 } 499 }
526 500
527 SkBitmap OpaqueNonClientView::GetFavIconForTabIconView() { 501 SkBitmap OpaqueNonClientView::GetFavIconForTabIconView() {
528 return frame_->window_delegate()->GetWindowIcon(); 502 return frame_->window_delegate()->GetWindowIcon();
529 } 503 }
530 504
531 /////////////////////////////////////////////////////////////////////////////// 505 ///////////////////////////////////////////////////////////////////////////////
532 // OpaqueNonClientView, views::BaseButton::ButtonListener implementation: 506 // OpaqueNonClientView, views::BaseButton::ButtonListener implementation:
533 507
534 void OpaqueNonClientView::ButtonPressed(views::BaseButton* sender) { 508 void OpaqueNonClientView::ButtonPressed(views::BaseButton* sender) {
535 if (sender == minimize_button_) { 509 if (sender == minimize_button_)
536 frame_->ExecuteSystemMenuCommand(SC_MINIMIZE); 510 frame_->ExecuteSystemMenuCommand(SC_MINIMIZE);
537 } else if (sender == maximize_button_) { 511 else if (sender == maximize_button_)
538 frame_->ExecuteSystemMenuCommand(SC_MAXIMIZE); 512 frame_->ExecuteSystemMenuCommand(SC_MAXIMIZE);
539 } else if (sender == restore_button_) { 513 else if (sender == restore_button_)
540 frame_->ExecuteSystemMenuCommand(SC_RESTORE); 514 frame_->ExecuteSystemMenuCommand(SC_RESTORE);
541 } else if (sender == close_button_) { 515 else if (sender == close_button_)
542 frame_->ExecuteSystemMenuCommand(SC_CLOSE); 516 frame_->ExecuteSystemMenuCommand(SC_CLOSE);
543 }
544 } 517 }
545 518
546 /////////////////////////////////////////////////////////////////////////////// 519 ///////////////////////////////////////////////////////////////////////////////
547 // OpaqueNonClientView, views::NonClientView implementation: 520 // OpaqueNonClientView, views::NonClientView implementation:
548 521
549 gfx::Rect OpaqueNonClientView::CalculateClientAreaBounds(int width, 522 gfx::Rect OpaqueNonClientView::CalculateClientAreaBounds(int width,
550 int height) const { 523 int height) const {
551 int top_margin = CalculateNonClientTopHeight(); 524 int top_height = NonClientTopBorderHeight();
552 int horizontal_border = HorizontalBorderSize(); 525 int border_width = NonClientBorderWidth();
553 return gfx::Rect(horizontal_border, top_margin, 526 return gfx::Rect(border_width, top_height,
554 std::max(0, width - (2 * horizontal_border)), 527 std::max(0, width - (2 * border_width)),
555 std::max(0, height - top_margin - VerticalBorderBottomSize())); 528 std::max(0, height - top_height - NonClientBottomBorderHeight()));
556 } 529 }
557 530
558 gfx::Size OpaqueNonClientView::CalculateWindowSizeForClientSize( 531 gfx::Size OpaqueNonClientView::CalculateWindowSizeForClientSize(
559 int width, 532 int width,
560 int height) const { 533 int height) const {
561 return gfx::Size(width + (2 * HorizontalBorderSize()), 534 return gfx::Size(width + (2 * NonClientBorderWidth()),
562 height + CalculateNonClientTopHeight() + VerticalBorderBottomSize()); 535 height + NonClientTopBorderHeight() + NonClientBottomBorderHeight());
563 } 536 }
564 537
565 CPoint OpaqueNonClientView::GetSystemMenuPoint() const { 538 CPoint OpaqueNonClientView::GetSystemMenuPoint() const {
566 CPoint system_menu_point(icon_bounds_.x(), icon_bounds_.bottom()); 539 CPoint system_menu_point(icon_bounds_.x(), icon_bounds_.bottom());
567 MapWindowPoints(frame_->GetHWND(), HWND_DESKTOP, &system_menu_point, 1); 540 MapWindowPoints(frame_->GetHWND(), HWND_DESKTOP, &system_menu_point, 1);
568 return system_menu_point; 541 return system_menu_point;
569 } 542 }
570 543
571 int OpaqueNonClientView::NonClientHitTest(const gfx::Point& point) { 544 int OpaqueNonClientView::NonClientHitTest(const gfx::Point& point) {
572 // First see if it's within the grow box area, since that overlaps the client 545 // First see if it's within the grow box area, since that overlaps the client
(...skipping 11 matching lines...) Expand all
584 if (maximize_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( 557 if (maximize_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(
585 point)) 558 point))
586 return HTMAXBUTTON; 559 return HTMAXBUTTON;
587 if (minimize_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( 560 if (minimize_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(
588 point)) 561 point))
589 return HTMINBUTTON; 562 return HTMINBUTTON;
590 if (window_icon_ && 563 if (window_icon_ &&
591 window_icon_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(point)) 564 window_icon_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(point))
592 return HTSYSMENU; 565 return HTSYSMENU;
593 566
594 int window_component = GetHTComponentForFrame(point, HorizontalBorderSize(), 567 int window_component = GetHTComponentForFrame(point,
595 kResizeAreaCornerSize, kWindowVerticalBorderTopSize, 568 TopResizeHeight(), NonClientBorderWidth(), NonClientBottomBorderHeight(),
596 frame_->window_delegate()->CanResize()); 569 kResizeAreaCornerSize, frame_->window_delegate()->CanResize());
597 // Fall back to the caption if no other component matches. 570 // Fall back to the caption if no other component matches.
598 if ((window_component == HTNOWHERE) && bounds().Contains(point)) 571 return ((window_component == HTNOWHERE) && bounds().Contains(point)) ?
599 window_component = HTCAPTION; 572 HTCAPTION : window_component;
600 return window_component;
601 } 573 }
602 574
603 void OpaqueNonClientView::GetWindowMask(const gfx::Size& size, 575 void OpaqueNonClientView::GetWindowMask(const gfx::Size& size,
604 gfx::Path* window_mask) { 576 gfx::Path* window_mask) {
605 DCHECK(window_mask); 577 DCHECK(window_mask);
606 578
607 // Redefine the window visible region for the new size. 579 // Redefine the window visible region for the new size.
608 window_mask->moveTo(0, 3); 580 window_mask->moveTo(0, 3);
609 window_mask->lineTo(1, 2); 581 window_mask->lineTo(1, 2);
610 window_mask->lineTo(1, 1); 582 window_mask->lineTo(1, 1);
(...skipping 23 matching lines...) Expand all
634 // The close button isn't affected by this constraint. 606 // The close button isn't affected by this constraint.
635 } 607 }
636 608
637 /////////////////////////////////////////////////////////////////////////////// 609 ///////////////////////////////////////////////////////////////////////////////
638 // OpaqueNonClientView, views::View overrides: 610 // OpaqueNonClientView, views::View overrides:
639 611
640 void OpaqueNonClientView::Paint(ChromeCanvas* canvas) { 612 void OpaqueNonClientView::Paint(ChromeCanvas* canvas) {
641 if (frame_->IsMaximized()) 613 if (frame_->IsMaximized())
642 PaintMaximizedFrameBorder(canvas); 614 PaintMaximizedFrameBorder(canvas);
643 else 615 else
644 PaintFrameBorder(canvas); 616 PaintRestoredFrameBorder(canvas);
645 PaintDistributorLogo(canvas); 617 PaintDistributorLogo(canvas);
646 PaintTitleBar(canvas); 618 PaintTitleBar(canvas);
647 PaintToolbarBackground(canvas); 619 PaintToolbarBackground(canvas);
648 PaintOTRAvatar(canvas); 620 PaintOTRAvatar(canvas);
649 if (frame_->IsMaximized()) 621 if (!frame_->IsMaximized())
650 PaintMaximizedClientEdge(canvas); 622 PaintRestoredClientEdge(canvas);
651 else
652 PaintClientEdge(canvas);
653 } 623 }
654 624
655 void OpaqueNonClientView::Layout() { 625 void OpaqueNonClientView::Layout() {
656 LayoutWindowControls(); 626 LayoutWindowControls();
657 LayoutDistributorLogo(); 627 LayoutDistributorLogo();
658 LayoutTitleBar(); 628 LayoutTitleBar();
659 LayoutOTRAvatar(); 629 LayoutOTRAvatar();
660 LayoutClientView(); 630 LayoutClientView();
661 } 631 }
662 632
663 gfx::Size OpaqueNonClientView::GetPreferredSize() { 633 gfx::Size OpaqueNonClientView::GetPreferredSize() {
664 gfx::Size prefsize(frame_->client_view()->GetPreferredSize()); 634 gfx::Size prefsize(frame_->client_view()->GetPreferredSize());
665 prefsize.Enlarge(2 * HorizontalBorderSize(), 635 prefsize.Enlarge(2 * NonClientBorderWidth(),
666 CalculateNonClientTopHeight() + VerticalBorderBottomSize()); 636 NonClientTopBorderHeight() + NonClientBottomBorderHeight());
667 return prefsize; 637 return prefsize;
668 } 638 }
669 639
670 views::View* OpaqueNonClientView::GetViewForPoint(const gfx::Point& point, 640 views::View* OpaqueNonClientView::GetViewForPoint(const gfx::Point& point,
671 bool can_create_floating) { 641 bool can_create_floating) {
672 // We override this function because the ClientView can overlap the non - 642 // We override this function because the ClientView can overlap the non -
673 // client view, making it impossible to click on the window controls. We need 643 // client view, making it impossible to click on the window controls. We need
674 // to ensure the window controls are checked _first_. 644 // to ensure the window controls are checked _first_.
675 views::View* views[] = { close_button_, restore_button_, maximize_button_, 645 views::View* views[] =
676 minimize_button_ }; 646 { close_button_, restore_button_, maximize_button_, minimize_button_ };
677 for (int i = 0; i < arraysize(views); ++i) { 647 for (int i = 0; i < arraysize(views); ++i) {
678 if (!views[i]->IsVisible()) 648 if (!views[i]->IsVisible())
679 continue; 649 continue;
680 // Apply mirroring transformation on view bounds for RTL chrome. 650 // Apply mirroring transformation on view bounds for RTL chrome.
681 if (views[i]->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(point)) 651 if (views[i]->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(point))
682 return views[i]; 652 return views[i];
683 } 653 }
684 return View::GetViewForPoint(point, can_create_floating); 654 return View::GetViewForPoint(point, can_create_floating);
685 } 655 }
686 656
(...skipping 29 matching lines...) Expand all
716 return false; 686 return false;
717 } 687 }
718 688
719 void OpaqueNonClientView::SetAccessibleName(const std::wstring& name) { 689 void OpaqueNonClientView::SetAccessibleName(const std::wstring& name) {
720 accessible_name_ = name; 690 accessible_name_ = name;
721 } 691 }
722 692
723 /////////////////////////////////////////////////////////////////////////////// 693 ///////////////////////////////////////////////////////////////////////////////
724 // OpaqueNonClientView, private: 694 // OpaqueNonClientView, private:
725 695
726 int OpaqueNonClientView::CalculateNonClientTopHeight() const { 696 int OpaqueNonClientView::FrameBorderWidth() const {
727 bool show_title = frame_->window_delegate()->ShouldShowWindowTitle(); 697 return frame_->IsMaximized() ?
728 int title_height = std::max(title_font_.height(), kWindowTitleMinimumHeight); 698 GetSystemMetrics(SM_CXSIZEFRAME) : kFrameBorderThickness;
729 if (frame_->IsMaximized()) {
730 int top_height = GetSystemMetrics(SM_CYSIZEFRAME);
731 if (show_title) {
732 top_height += kWindowTitleZoomedTopOffset + title_height +
733 kTitleZoomedBottomSpacing;
734 }
735 if (!browser_view_->IsToolbarVisible())
736 top_height -= kClientEdgeZoomedBottomCrop;
737 return top_height;
738 }
739 return show_title ?
740 (kWindowTitleTopOffset + title_height + kTitleBottomSpacing) :
741 kNoTitleTopSpacing;
742 } 699 }
743 700
744 int OpaqueNonClientView::HorizontalBorderSize() const { 701 int OpaqueNonClientView::FrameTopBorderHeight() const {
745 return frame_->IsMaximized() ? 702 return frame_->IsMaximized() ?
746 GetSystemMetrics(SM_CXSIZEFRAME) : kWindowHorizontalBorderSize; 703 GetSystemMetrics(SM_CYSIZEFRAME) : kFrameBorderThickness;
747 } 704 }
748 705
749 int OpaqueNonClientView::VerticalBorderBottomSize() const { 706 int OpaqueNonClientView::TopResizeHeight() const {
750 return frame_->IsMaximized() ? (GetSystemMetrics(SM_CYSIZEFRAME) + 707 return FrameTopBorderHeight() - kTopResizeAdjust;
751 kWindowVerticalBorderZoomedBottomSize) : kWindowVerticalBorderBottomSize;
752 } 708 }
753 709
754 void OpaqueNonClientView::PaintFrameBorder(ChromeCanvas* canvas) { 710 int OpaqueNonClientView::NonClientBorderWidth() const {
711 // In maximized mode, we don't show a client edge.
712 return FrameBorderWidth() +
713 (frame_->IsMaximized() ? 0 : kClientEdgeThickness);
714 }
715
716 int OpaqueNonClientView::NonClientTopBorderHeight() const {
717 if (!frame_->window_delegate()->ShouldShowWindowTitle()) {
718 return FrameTopBorderHeight() +
719 (frame_->IsMaximized() ? 0 : kNonClientRestoredExtraThickness);
720 }
721
722 int title_top_spacing, title_thickness;
723 return TitleCoordinates(&title_top_spacing, &title_thickness);
724 }
725
726 int OpaqueNonClientView::NonClientBottomBorderHeight() const {
727 // In maximized mode, we don't show a client edge, but the frame border is
728 // extended slightly.
729 return frame_->IsMaximized() ? (GetSystemMetrics(SM_CYSIZEFRAME) +
730 kFrameBorderMaximizedExtraBottomThickness) :
731 (kFrameBorderThickness + kClientEdgeThickness);
732 }
733
734 int OpaqueNonClientView::ClientEdgeThicknessWithinNonClientHeight() const {
735 return (frame_->IsMaximized() || browser_view_->IsToolbarVisible()) ?
736 0 : kClientEdgeThickness;
737 }
738
739 int OpaqueNonClientView::TitleCoordinates(int* title_top_spacing,
740 int* title_thickness) const {
741 int top_height = FrameTopBorderHeight();
742 int min_titlebar_height = kTitlebarMinimumHeight + top_height;
743 *title_top_spacing = top_height + kTitleTopSpacing;
744 // The bottom spacing should be the same apparent height as the top spacing.
745 // Because the actual top spacing height varies based on the system border
746 // thickness, we calculate this based on the restored top spacing and then
747 // adjust for maximized mode.
748 int title_bottom_spacing = kFrameBorderThickness + kTitleTopSpacing;
749 if (frame_->IsMaximized()) {
750 // When we maximize, the top border appears to be chopped off; shift the
751 // title down to stay centered within the remaining space.
752 int title_adjust = (kFrameBorderThickness / 2);
753 *title_top_spacing += title_adjust;
754 title_bottom_spacing -= title_adjust;
755 }
756 *title_thickness = std::max(title_font_.height(),
757 min_titlebar_height - *title_top_spacing - title_bottom_spacing);
758 return *title_top_spacing + *title_thickness + title_bottom_spacing +
759 ClientEdgeThicknessWithinNonClientHeight();
760 }
761
762 void OpaqueNonClientView::PaintRestoredFrameBorder(ChromeCanvas* canvas) {
755 SkBitmap* top_left_corner = 763 SkBitmap* top_left_corner =
756 resources()->GetPartBitmap(FRAME_TOP_LEFT_CORNER); 764 resources()->GetPartBitmap(FRAME_TOP_LEFT_CORNER);
757 SkBitmap* top_right_corner = 765 SkBitmap* top_right_corner =
758 resources()->GetPartBitmap(FRAME_TOP_RIGHT_CORNER); 766 resources()->GetPartBitmap(FRAME_TOP_RIGHT_CORNER);
759 SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE); 767 SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE);
760 SkBitmap* right_edge = resources()->GetPartBitmap(FRAME_RIGHT_EDGE); 768 SkBitmap* right_edge = resources()->GetPartBitmap(FRAME_RIGHT_EDGE);
761 SkBitmap* left_edge = resources()->GetPartBitmap(FRAME_LEFT_EDGE); 769 SkBitmap* left_edge = resources()->GetPartBitmap(FRAME_LEFT_EDGE);
762 SkBitmap* bottom_left_corner = 770 SkBitmap* bottom_left_corner =
763 resources()->GetPartBitmap(FRAME_BOTTOM_LEFT_CORNER); 771 resources()->GetPartBitmap(FRAME_BOTTOM_LEFT_CORNER);
764 SkBitmap* bottom_right_corner = 772 SkBitmap* bottom_right_corner =
765 resources()->GetPartBitmap(FRAME_BOTTOM_RIGHT_CORNER); 773 resources()->GetPartBitmap(FRAME_BOTTOM_RIGHT_CORNER);
766 SkBitmap* bottom_edge = resources()->GetPartBitmap(FRAME_BOTTOM_EDGE); 774 SkBitmap* bottom_edge = resources()->GetPartBitmap(FRAME_BOTTOM_EDGE);
767 775
768 // Top. 776 // Top.
769 canvas->DrawBitmapInt(*top_left_corner, 0, 0); 777 canvas->DrawBitmapInt(*top_left_corner, 0, 0);
770 canvas->TileImageInt(*top_edge, top_left_corner->width(), 0, 778 canvas->TileImageInt(*top_edge, top_left_corner->width(), 0,
771 width() - top_right_corner->width(), top_edge->height()); 779 width() - top_right_corner->width(), top_edge->height());
772 canvas->DrawBitmapInt(*top_right_corner, 780 canvas->DrawBitmapInt(*top_right_corner,
773 width() - top_right_corner->width(), 0); 781 width() - top_right_corner->width(), 0);
782 // Note: When we don't have a toolbar, we need to draw some kind of bottom
783 // edge here. Because the App Window graphics we use for this have an
784 // attached client edge and their sizing algorithm is a little involved, we do
785 // all this in PaintRestoredClientEdge().
774 786
775 // Right. 787 // Right.
776 canvas->TileImageInt(*right_edge, width() - right_edge->width(), 788 canvas->TileImageInt(*right_edge, width() - right_edge->width(),
777 top_right_corner->height(), right_edge->width(), 789 top_right_corner->height(), right_edge->width(),
778 height() - top_right_corner->height() - 790 height() - top_right_corner->height() -
779 bottom_right_corner->height()); 791 bottom_right_corner->height());
780 792
781 // Bottom. 793 // Bottom.
782 canvas->DrawBitmapInt(*bottom_right_corner, 794 canvas->DrawBitmapInt(*bottom_right_corner,
783 width() - bottom_right_corner->width(), 795 width() - bottom_right_corner->width(),
784 height() - bottom_right_corner->height()); 796 height() - bottom_right_corner->height());
785 canvas->TileImageInt(*bottom_edge, bottom_left_corner->width(), 797 canvas->TileImageInt(*bottom_edge, bottom_left_corner->width(),
786 height() - bottom_edge->height(), 798 height() - bottom_edge->height(),
787 width() - bottom_left_corner->width() - 799 width() - bottom_left_corner->width() -
788 bottom_right_corner->width(), 800 bottom_right_corner->width(),
789 bottom_edge->height()); 801 bottom_edge->height());
790 canvas->DrawBitmapInt(*bottom_left_corner, 0, 802 canvas->DrawBitmapInt(*bottom_left_corner, 0,
791 height() - bottom_left_corner->height()); 803 height() - bottom_left_corner->height());
792 804
793 // Left. 805 // Left.
794 canvas->TileImageInt(*left_edge, 0, top_left_corner->height(), 806 canvas->TileImageInt(*left_edge, 0, top_left_corner->height(),
795 left_edge->width(), 807 left_edge->width(),
796 height() - top_left_corner->height() - bottom_left_corner->height()); 808 height() - top_left_corner->height() - bottom_left_corner->height());
797 } 809 }
798 810
799 void OpaqueNonClientView::PaintMaximizedFrameBorder(ChromeCanvas* canvas) { 811 void OpaqueNonClientView::PaintMaximizedFrameBorder(ChromeCanvas* canvas) {
800 SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_MAXIMIZED_TOP_EDGE); 812 SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_MAXIMIZED_TOP_EDGE);
801 int frame_thickness = GetSystemMetrics(SM_CYSIZEFRAME); 813 canvas->TileImageInt(*top_edge, 0, FrameTopBorderHeight(), width(),
802 canvas->TileImageInt(*top_edge, 0, frame_thickness, width(),
803 top_edge->height()); 814 top_edge->height());
804 815
816 if (!browser_view_->IsToolbarVisible()) {
817 // There's no toolbar to edge the frame border, so we need to draw a bottom
818 // edge. The App Window graphic we use for this has a built in client edge,
819 // so we clip it off the bottom.
820 int edge_height = app_top_center_.height() - kClientEdgeThickness;
821 canvas->TileImageInt(app_top_center_, 0,
822 frame_->client_view()->y() - edge_height, width(), edge_height);
823 }
824
805 SkBitmap* bottom_edge = 825 SkBitmap* bottom_edge =
806 resources()->GetPartBitmap(FRAME_MAXIMIZED_BOTTOM_EDGE); 826 resources()->GetPartBitmap(FRAME_MAXIMIZED_BOTTOM_EDGE);
827 // We draw the bottom edge of this image.
807 canvas->TileImageInt(*bottom_edge, 0, 828 canvas->TileImageInt(*bottom_edge, 0,
808 height() - bottom_edge->height() - frame_thickness, width(), 829 bottom_edge->height() - kFrameBorderMaximizedExtraBottomThickness, 0,
809 bottom_edge->height()); 830 height() - NonClientBottomBorderHeight(), width(),
831 kFrameBorderMaximizedExtraBottomThickness);
810 } 832 }
811 833
812 void OpaqueNonClientView::PaintDistributorLogo(ChromeCanvas* canvas) { 834 void OpaqueNonClientView::PaintDistributorLogo(ChromeCanvas* canvas) {
813 // The distributor logo is only painted when the frame is not maximized and 835 // The distributor logo is only painted when the frame is not maximized and
814 // when we actually have a logo. 836 // when we actually have a logo.
815 if (!frame_->IsMaximized() && !distributor_logo_.empty()) { 837 if (!frame_->IsMaximized() && !distributor_logo_.empty()) {
816 int logo_x = MirroredLeftPointForRect(logo_bounds_); 838 int logo_x = MirroredLeftPointForRect(logo_bounds_);
817 canvas->DrawBitmapInt(distributor_logo_, logo_x, logo_bounds_.y()); 839 canvas->DrawBitmapInt(distributor_logo_, logo_x, logo_bounds_.y());
818 } 840 }
819 } 841 }
820 842
821 void OpaqueNonClientView::PaintTitleBar(ChromeCanvas* canvas) { 843 void OpaqueNonClientView::PaintTitleBar(ChromeCanvas* canvas) {
822 // The window icon is painted by the TabIconView. 844 // The window icon is painted by the TabIconView.
823 views::WindowDelegate* d = frame_->window_delegate(); 845 views::WindowDelegate* d = frame_->window_delegate();
824 if (d->ShouldShowWindowTitle()) { 846 if (d->ShouldShowWindowTitle()) {
825 canvas->DrawStringInt(d->GetWindowTitle(), title_font_, SK_ColorWHITE, 847 canvas->DrawStringInt(d->GetWindowTitle(), title_font_, SK_ColorWHITE,
826 MirroredLeftPointForRect(title_bounds_), title_bounds_.y(), 848 MirroredLeftPointForRect(title_bounds_), title_bounds_.y(),
827 title_bounds_.width(), title_bounds_.height()); 849 title_bounds_.width(), title_bounds_.height());
828 /* TODO(pkasting): 850 /* TODO(pkasting): If this window is active, we should also draw a drop
829 if (app window && active) 851 * shadow on the title. This is tricky, because we don't want to hardcode a
830 Draw Drop Shadow; 852 * shadow color (since we want to work with various themes), but we can't
831 */ 853 * alpha-blend either (since the Windows text APIs don't really do this).
854 * So we'd need to sample the background color at the right location and
855 * synthesize a good shadow color. */
832 } 856 }
833 } 857 }
834 858
835 void OpaqueNonClientView::PaintToolbarBackground(ChromeCanvas* canvas) { 859 void OpaqueNonClientView::PaintToolbarBackground(ChromeCanvas* canvas) {
836 if (!browser_view_->IsToolbarVisible() && !browser_view_->IsTabStripVisible()) 860 if (!browser_view_->IsToolbarVisible() && !browser_view_->IsTabStripVisible())
837 return; 861 return;
838 862
839 gfx::Rect toolbar_bounds(browser_view_->GetToolbarBounds()); 863 gfx::Rect toolbar_bounds(browser_view_->GetToolbarBounds());
840 gfx::Point toolbar_origin(toolbar_bounds.origin()); 864 gfx::Point toolbar_origin(toolbar_bounds.origin());
841 View::ConvertPointToView(frame_->client_view(), this, &toolbar_origin); 865 View::ConvertPointToView(frame_->client_view(), this, &toolbar_origin);
842 toolbar_bounds.set_origin(toolbar_origin); 866 toolbar_bounds.set_origin(toolbar_origin);
843 867
844 SkBitmap* toolbar_left = 868 SkBitmap* toolbar_left =
845 resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT); 869 resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT);
846 canvas->DrawBitmapInt(*toolbar_left, 870 canvas->DrawBitmapInt(*toolbar_left,
847 toolbar_bounds.x() - toolbar_left->width(), 871 toolbar_bounds.x() - toolbar_left->width(),
848 toolbar_bounds.y()); 872 toolbar_bounds.y());
849 873
850 SkBitmap* toolbar_center = 874 SkBitmap* toolbar_center =
851 resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP); 875 resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP);
852 canvas->TileImageInt(*toolbar_center, toolbar_bounds.x(), toolbar_bounds.y(), 876 canvas->TileImageInt(*toolbar_center, toolbar_bounds.x(), toolbar_bounds.y(),
853 toolbar_bounds.width(), toolbar_center->height()); 877 toolbar_bounds.width(), toolbar_center->height());
854 878
855 canvas->DrawBitmapInt( 879 canvas->DrawBitmapInt(
856 *resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_RIGHT), 880 *resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_RIGHT),
857 toolbar_bounds.right(), toolbar_bounds.y()); 881 toolbar_bounds.right(), toolbar_bounds.y());
858 } 882 }
859 883
860 void OpaqueNonClientView::PaintOTRAvatar(ChromeCanvas* canvas) { 884 void OpaqueNonClientView::PaintOTRAvatar(ChromeCanvas* canvas) {
861 if (browser_view_->ShouldShowOffTheRecordAvatar()) { 885 if (!browser_view_->ShouldShowOffTheRecordAvatar())
862 int src_y = frame_->IsMaximized() ? kOTRZoomedTopCrop : 0; 886 return;
863 canvas->DrawBitmapInt(browser_view_->GetOTRAvatarIcon(), 0, src_y, 887
864 otr_avatar_bounds_.width(), otr_avatar_bounds_.height(), 888 SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon();
865 MirroredLeftPointForRect(otr_avatar_bounds_), otr_avatar_bounds_.y(), 889 canvas->DrawBitmapInt(otr_avatar_icon, 0,
866 otr_avatar_bounds_.width(), otr_avatar_bounds_.height(), false); 890 (otr_avatar_icon.height() - otr_avatar_bounds_.height()) / 2,
867 } 891 otr_avatar_bounds_.width(), otr_avatar_bounds_.height(),
892 MirroredLeftPointForRect(otr_avatar_bounds_), otr_avatar_bounds_.y(),
893 otr_avatar_bounds_.width(), otr_avatar_bounds_.height(), false);
868 } 894 }
869 895
870 void OpaqueNonClientView::PaintClientEdge(ChromeCanvas* canvas) { 896 void OpaqueNonClientView::PaintRestoredClientEdge(ChromeCanvas* canvas) {
897 int client_area_top = frame_->client_view()->y();
898
871 // The toolbar draws a client edge along its own bottom edge when it's 899 // The toolbar draws a client edge along its own bottom edge when it's
872 // visible. However, it only draws this for the width of the actual client 900 // visible. However, it only draws this for the width of the actual client
873 // area, leaving a gap at the left and right edges: 901 // area, leaving a gap at the left and right edges:
874 // 902 //
875 // | Toolbar | <-- part of toolbar 903 // | Toolbar | <-- part of toolbar
876 // ----- (toolbar client edge) ----- <-- gap 904 // ----- (toolbar client edge) ----- <-- gap
877 // | Client area | <-- right client edge 905 // | Client area | <-- right client edge
878 // 906 //
879 // To address this, we extend the left and right client edges up one pixel to 907 // To address this, we extend the left and right client edges up to fill the
880 // fill the gap, by pretending the toolbar is one pixel shorter than it really 908 // gap, by pretending the toolbar is shorter than it really is.
881 // is.
882 // 909 //
883 // Note: We can get away with this hackery because we only draw a top edge 910 // Note: We can get away with this hackery because we only draw a top edge
884 // when there is no toolbar. If we tried to draw a top edge over the 911 // when there is no toolbar. If we tried to draw a client edge over the
885 // toolbar's top edge, we'd need a different solution. 912 // toolbar's bottom edge, we'd need a different solution.
886 gfx::Rect toolbar_bounds = browser_view_->GetToolbarBounds(); 913 if (browser_view_->IsToolbarVisible()) {
887 if (browser_view_->IsToolbarVisible()) 914 client_area_top +=
888 toolbar_bounds.set_height(std::max(0, toolbar_bounds.height() - 1)); 915 browser_view_->GetToolbarBounds().bottom() - kClientEdgeThickness;
889 int client_area_top = frame_->client_view()->y() + toolbar_bounds.bottom(); 916 }
890 917
891 // When we don't have a toolbar to draw a top edge for us, draw a top edge. 918 // When we don't have a toolbar to draw a top edge for us, draw a top edge.
892 gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height()); 919 gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height());
893 if (!browser_view_->IsToolbarVisible()) { 920 if (!browser_view_->IsToolbarVisible()) {
894 // This is necessary because the top center bitmap is shorter than the top 921 // This is necessary because the top center bitmap is shorter than the top
895 // left and right bitmaps. We need their top edges to line up, and we 922 // left and right bitmaps. We need their top edges to line up, and we
896 // need the left and right edges to start below the corners' bottoms. 923 // need the left and right edges to start below the corners' bottoms.
897 int top_edge_y = client_area_top - app_top_center_.height(); 924 int top_edge_y = client_area_top - app_top_center_.height();
898 client_area_top = top_edge_y + app_top_left_.height(); 925 client_area_top = top_edge_y + app_top_left_.height();
899 canvas->DrawBitmapInt(app_top_left_, 926 canvas->DrawBitmapInt(app_top_left_,
900 client_area_bounds.x() - app_top_left_.width(), 927 client_area_bounds.x() - app_top_left_.width(),
901 top_edge_y); 928 top_edge_y);
902 canvas->TileImageInt(app_top_center_, client_area_bounds.x(), top_edge_y, 929 canvas->TileImageInt(app_top_center_, client_area_bounds.x(), top_edge_y,
903 client_area_bounds.width(), app_top_center_.height()); 930 client_area_bounds.width(), app_top_center_.height());
904 canvas->DrawBitmapInt(app_top_right_, client_area_bounds.right(), 931 canvas->DrawBitmapInt(app_top_right_, client_area_bounds.right(),
905 top_edge_y); 932 top_edge_y);
906 } 933 }
907 934
908 int client_area_bottom = 935 int client_area_bottom =
909 std::max(client_area_top, height() - VerticalBorderBottomSize()); 936 std::max(client_area_top, height() - NonClientBottomBorderHeight());
910 int client_area_height = client_area_bottom - client_area_top; 937 int client_area_height = client_area_bottom - client_area_top;
911 SkBitmap* right = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_RIGHT); 938 SkBitmap* right = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_RIGHT);
912 canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top, 939 canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top,
913 right->width(), client_area_height); 940 right->width(), client_area_height);
914 941
915 canvas->DrawBitmapInt( 942 canvas->DrawBitmapInt(
916 *resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_RIGHT), 943 *resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_RIGHT),
917 client_area_bounds.right(), client_area_bottom); 944 client_area_bounds.right(), client_area_bottom);
918 945
919 SkBitmap* bottom = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM); 946 SkBitmap* bottom = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM);
920 canvas->TileImageInt(*bottom, client_area_bounds.x(), 947 canvas->TileImageInt(*bottom, client_area_bounds.x(),
921 client_area_bottom, client_area_bounds.width(), 948 client_area_bottom, client_area_bounds.width(),
922 bottom->height()); 949 bottom->height());
923 950
924 SkBitmap* bottom_left = 951 SkBitmap* bottom_left =
925 resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_LEFT); 952 resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_LEFT);
926 canvas->DrawBitmapInt(*bottom_left, 953 canvas->DrawBitmapInt(*bottom_left,
927 client_area_bounds.x() - bottom_left->width(), client_area_bottom); 954 client_area_bounds.x() - bottom_left->width(), client_area_bottom);
928 955
929 SkBitmap* left = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_LEFT); 956 SkBitmap* left = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_LEFT);
930 canvas->TileImageInt(*left, client_area_bounds.x() - left->width(), 957 canvas->TileImageInt(*left, client_area_bounds.x() - left->width(),
931 client_area_top, left->width(), client_area_height); 958 client_area_top, left->width(), client_area_height);
932 } 959 }
933 960
934 void OpaqueNonClientView::PaintMaximizedClientEdge(ChromeCanvas* canvas) {
935 if (browser_view_->IsToolbarVisible())
936 return; // The toolbar draws its own client edge, which is sufficient.
937
938 int edge_height = app_top_center_.height() - kClientEdgeZoomedBottomCrop;
939 canvas->TileImageInt(app_top_center_, 0,
940 frame_->client_view()->y() - edge_height, width(), edge_height);
941 }
942
943 void OpaqueNonClientView::LayoutWindowControls() { 961 void OpaqueNonClientView::LayoutWindowControls() {
944 // TODO(pkasting): This function is almost identical to 962 // TODO(pkasting): This function is almost identical to
945 // DefaultNonClientView::LayoutWindowControls(), they should be combined. 963 // DefaultNonClientView::LayoutWindowControls(), they should be combined.
946 close_button_->SetImageAlignment(views::Button::ALIGN_LEFT, 964 close_button_->SetImageAlignment(views::Button::ALIGN_LEFT,
947 views::Button::ALIGN_BOTTOM); 965 views::Button::ALIGN_BOTTOM);
948 // Maximized buttons start at window top so that even if their images aren't 966 // Maximized buttons start at window top so that even if their images aren't
949 // drawn flush with the screen edge, they still obey Fitts' Law. 967 // drawn flush with the screen edge, they still obey Fitts' Law.
950 bool is_maximized = frame_->IsMaximized(); 968 bool is_maximized = frame_->IsMaximized();
951 int top_offset = is_maximized ? 0 : kWindowControlsTopOffset; 969 int caption_y = is_maximized ? FrameTopBorderHeight() : kCaptionTopSpacing;
952 int top_extra_height = is_maximized ? 970 int top_extra_height = is_maximized ? kCaptionTopSpacing : 0;
953 (GetSystemMetrics(SM_CYSIZEFRAME) + kWindowControlsZoomedTopExtraHeight) : 971 // There should always be the same number of non-shadow pixels visible to the
954 0; 972 // side of the caption buttons. In maximized mode we extend the rightmost
955 int right_offset = is_maximized ? 973 // button to the screen corner to obey Fitts' Law.
956 (GetSystemMetrics(SM_CXSIZEFRAME) + kWindowControlsZoomedRightOffset) : 974 int right_extra_width = is_maximized ?
957 kWindowControlsRightOffset; 975 (kFrameBorderThickness - kFrameShadowThickness) : 0;
976 int right_spacing = is_maximized ? (GetSystemMetrics(SM_CXSIZEFRAME) +
977 right_extra_width) : FrameBorderWidth();
958 gfx::Size close_button_size = close_button_->GetPreferredSize(); 978 gfx::Size close_button_size = close_button_->GetPreferredSize();
959 close_button_->SetBounds( 979 close_button_->SetBounds(width() - close_button_size.width() - right_spacing,
960 (width() - close_button_size.width() - right_offset), 980 caption_y,
961 top_offset, 981 close_button_size.width() + right_extra_width,
962 (is_maximized ? 982 close_button_size.height() + top_extra_height);
963 // We extend the maximized close button to the screen corner to obey
964 // Fitts' Law.
965 (close_button_size.width() + kWindowControlsZoomedRightOffset) :
966 close_button_size.width()),
967 (close_button_size.height() + top_extra_height));
968 983
969 // When the window is restored, we show a maximized button; otherwise, we show 984 // When the window is restored, we show a maximized button; otherwise, we show
970 // a restore button. 985 // a restore button.
971 bool is_restored = !is_maximized && !frame_->IsMinimized(); 986 bool is_restored = !is_maximized && !frame_->IsMinimized();
972 views::Button* invisible_button = is_restored ? 987 views::Button* invisible_button = is_restored ?
973 restore_button_ : maximize_button_; 988 restore_button_ : maximize_button_;
974 invisible_button->SetVisible(false); 989 invisible_button->SetVisible(false);
975 990
976 views::Button* visible_button = is_restored ? 991 views::Button* visible_button = is_restored ?
977 maximize_button_ : restore_button_; 992 maximize_button_ : restore_button_;
978 visible_button->SetVisible(true); 993 visible_button->SetVisible(true);
979 visible_button->SetImageAlignment(views::Button::ALIGN_LEFT, 994 visible_button->SetImageAlignment(views::Button::ALIGN_LEFT,
980 views::Button::ALIGN_BOTTOM); 995 views::Button::ALIGN_BOTTOM);
981 gfx::Size visible_button_size = visible_button->GetPreferredSize(); 996 gfx::Size visible_button_size = visible_button->GetPreferredSize();
982 visible_button->SetBounds(close_button_->x() - visible_button_size.width(), 997 visible_button->SetBounds(close_button_->x() - visible_button_size.width(),
983 top_offset, 998 caption_y,
984 visible_button_size.width(), 999 visible_button_size.width(),
985 visible_button_size.height() + top_extra_height); 1000 visible_button_size.height() + top_extra_height);
986 1001
987 minimize_button_->SetVisible(true); 1002 minimize_button_->SetVisible(true);
988 minimize_button_->SetImageAlignment(views::Button::ALIGN_LEFT, 1003 minimize_button_->SetImageAlignment(views::Button::ALIGN_LEFT,
989 views::Button::ALIGN_BOTTOM); 1004 views::Button::ALIGN_BOTTOM);
990 gfx::Size minimize_button_size = minimize_button_->GetPreferredSize(); 1005 gfx::Size minimize_button_size = minimize_button_->GetPreferredSize();
991 minimize_button_->SetBounds( 1006 minimize_button_->SetBounds(
992 visible_button->x() - minimize_button_size.width(), 1007 visible_button->x() - minimize_button_size.width(), caption_y,
993 top_offset,
994 minimize_button_size.width(), 1008 minimize_button_size.width(),
995 minimize_button_size.height() + top_extra_height); 1009 minimize_button_size.height() + top_extra_height);
996 } 1010 }
997 1011
998 void OpaqueNonClientView::LayoutDistributorLogo() { 1012 void OpaqueNonClientView::LayoutDistributorLogo() {
999 logo_bounds_.SetRect(minimize_button_->x() - distributor_logo_.width() - 1013 // Always lay out the logo, even when it's not present, so we can lay out the
1000 kDistributorLogoHorizontalOffset, kDistributorLogoVerticalOffset, 1014 // window title based on its position.
1001 distributor_logo_.width(), distributor_logo_.height()); 1015 int logo_x = minimize_button_->x() - (distributor_logo_.empty() ?
1016 0 : (distributor_logo_.width() + kLogoCaptionSpacing));
1017 logo_bounds_.SetRect(logo_x, TopResizeHeight(), distributor_logo_.width(),
1018 distributor_logo_.height());
1002 } 1019 }
1003 1020
1004 void OpaqueNonClientView::LayoutTitleBar() { 1021 void OpaqueNonClientView::LayoutTitleBar() {
1005 // Size the window icon, even if it is hidden so we can size the title based 1022 // Always lay out the icon, even when it's not present, so we can lay out the
1006 // on its position. 1023 // window title based on its position.
1007 int left_offset = frame_->IsMaximized() ? 1024 int icon_x = FrameBorderWidth() + kIconLeftSpacing;
1008 (GetSystemMetrics(SM_CXSIZEFRAME) + kWindowIconZoomedLeftOffset) :
1009 kWindowIconLeftOffset;
1010 1025
1011 // The usable height of the titlebar area is the total height minus the top 1026 // The usable height of the titlebar area is the total height minus the top
1012 // resize border, the one shadow pixel at the bottom, and any client edge area 1027 // resize border, the one shadow pixel at the bottom, and any client edge area
1013 // we draw below that shadow pixel (only in restored mode). 1028 // we draw below that shadow pixel.
1014 // TODO(pkasting): Clean up this "4" hack. 1029 int title_top_spacing, title_thickness;
1015 int top_border_height = 1030 int top_height = TitleCoordinates(&title_top_spacing, &title_thickness);
1016 frame_->IsMaximized() ? GetSystemMetrics(SM_CYSIZEFRAME) : 4; 1031 int top_border_height = FrameTopBorderHeight();
1017 int available_height = CalculateNonClientTopHeight() - top_border_height - 1; 1032 int available_height = top_height - top_border_height -
1018 if (!frame_->IsMaximized()) 1033 kFrameShadowThickness - ClientEdgeThicknessWithinNonClientHeight();
1019 available_height -= kClientEdgeZoomedBottomCrop;
1020 1034
1021 // The icon takes up a constant fraction of the available height, down to a 1035 // The icon takes up a constant fraction of the available height, down to a
1022 // minimum size, and is always an even number of pixels on a side (presumably 1036 // minimum size, and is always an even number of pixels on a side (presumably
1023 // to make scaled icons look better). It's centered within the usable height. 1037 // to make scaled icons look better). It's centered within the usable height.
1024 int icon_size = std::max((available_height * kWindowIconFractionNumerator / 1038 int icon_size = std::max((available_height * kIconHeightFractionNumerator /
1025 kWindowIconFractionDenominator) / 2 * 2, kWindowIconMinimumSize); 1039 kIconHeightFractionDenominator) / 2 * 2, kIconMinimumSize);
1026 int icon_top_offset = 1040 int icon_y = ((available_height - icon_size) / 2) + top_border_height;
1027 ((available_height - icon_size) / 2) + top_border_height;
1028 1041
1029 // Hack: Our frame border has a different "3D look" than Windows'. Theirs has 1042 // Hack: Our frame border has a different "3D look" than Windows'. Theirs has
1030 // a more complex gradient on the top that they push their icon/title below; 1043 // a more complex gradient on the top that they push their icon/title below;
1031 // then the maximized window cuts this off and the icon/title are centered in 1044 // then the maximized window cuts this off and the icon/title are centered in
1032 // the remaining space. Because the apparent shape of our border is simpler, 1045 // the remaining space. Because the apparent shape of our border is simpler,
1033 // using the same positioning makes things look slightly uncentered with 1046 // using the same positioning makes things look slightly uncentered with
1034 // restored windows, so we come up one pixel to compensate. 1047 // restored windows, so we come up to compensate.
1035 if (!frame_->IsMaximized()) 1048 if (!frame_->IsMaximized())
1036 --icon_top_offset; 1049 icon_y -= kIconRestoredAdjust;
1037 1050
1038 views::WindowDelegate* d = frame_->window_delegate(); 1051 views::WindowDelegate* d = frame_->window_delegate();
1039 if (!d->ShouldShowWindowIcon()) 1052 if (!d->ShouldShowWindowIcon())
1040 icon_size = 0; 1053 icon_size = 0;
1041 icon_bounds_.SetRect(left_offset, icon_top_offset, icon_size, icon_size); 1054 icon_bounds_.SetRect(icon_x, icon_y, icon_size, icon_size);
1042 if (window_icon_) 1055 if (window_icon_)
1043 window_icon_->SetBounds(icon_bounds_); 1056 window_icon_->SetBounds(icon_bounds_);
1044 1057
1045 // Size the title, if visible. 1058 // Size the title, if visible.
1046 if (d->ShouldShowWindowTitle()) { 1059 if (d->ShouldShowWindowTitle()) {
1047 int title_right = logo_bounds_.x() - kTitleLogoSpacing;
1048 int icon_right = icon_bounds_.right(); 1060 int icon_right = icon_bounds_.right();
1049 int title_left = 1061 int title_x =
1050 icon_right + (d->ShouldShowWindowIcon() ? kWindowIconTitleSpacing : 0); 1062 icon_right + (d->ShouldShowWindowIcon() ? kLogoCaptionSpacing : 0);
1051 int title_top_offset = frame_->IsMaximized() ? 1063 title_bounds_.SetRect(title_x,
1052 (GetSystemMetrics(SM_CYSIZEFRAME) + kWindowTitleZoomedTopOffset) : 1064 title_top_spacing + ((title_thickness - title_font_.height()) / 2),
1053 kWindowTitleTopOffset; 1065 std::max(0, logo_bounds_.x() - kTitleLogoSpacing - icon_right),
1054 if (title_font_.height() < kWindowTitleMinimumHeight) { 1066 title_font_.height());
1055 title_top_offset +=
1056 (kWindowTitleMinimumHeight - title_font_.height()) / 2;
1057 }
1058 title_bounds_.SetRect(title_left, title_top_offset,
1059 std::max(0, title_right - icon_right), title_font_.height());
1060 } 1067 }
1061 } 1068 }
1062 1069
1063 void OpaqueNonClientView::LayoutOTRAvatar() { 1070 void OpaqueNonClientView::LayoutOTRAvatar() {
1064 SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); 1071 SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon();
1065 int non_client_height = CalculateNonClientTopHeight(); 1072 int top_height = NonClientTopBorderHeight();
1066 int otr_bottom = non_client_height + browser_view_->GetTabStripHeight() - 1073 int tabstrip_height = browser_view_->GetTabStripHeight() - kOTRBottomSpacing;
1067 kOTRBottomSpacing; 1074 int otr_bottom = top_height + tabstrip_height;
1068 int otr_x, otr_y, otr_height; 1075 int otr_height = frame_->IsMaximized() ?
1069 if (frame_->IsMaximized()) { 1076 (tabstrip_height - kOTRMaximizedTopSpacing) :
1070 otr_x = GetSystemMetrics(SM_CXSIZEFRAME) + kOTRZoomedLeftOffset; 1077 otr_avatar_icon.height();
1071 otr_y = non_client_height + kOTRZoomedTopSpacing; 1078 int otr_y = otr_bottom - otr_height;
1072 otr_height = otr_bottom - otr_y; 1079 otr_avatar_bounds_.SetRect(NonClientBorderWidth() + kOTRSideSpacing, otr_y,
1073 } else { 1080 otr_avatar_icon.width(), otr_height);
1074 otr_x = kOTRLeftOffset;
1075 otr_height = otr_avatar_icon.height();
1076 otr_y = otr_bottom - otr_height;
1077 }
1078 otr_avatar_bounds_.SetRect(otr_x, otr_y, otr_avatar_icon.width(), otr_height);
1079 } 1081 }
1080 1082
1081 void OpaqueNonClientView::LayoutClientView() { 1083 void OpaqueNonClientView::LayoutClientView() {
1082 frame_->client_view()->SetBounds(CalculateClientAreaBounds(width(), 1084 frame_->client_view()->SetBounds(CalculateClientAreaBounds(width(),
1083 height())); 1085 height()));
1084 } 1086 }
1085 1087
1086 // static 1088 // static
1087 void OpaqueNonClientView::InitClass() { 1089 void OpaqueNonClientView::InitClass() {
1088 static bool initialized = false; 1090 static bool initialized = false;
(...skipping 15 matching lines...) Expand all
1104 } 1106 }
1105 1107
1106 // static 1108 // static
1107 void OpaqueNonClientView::InitAppWindowResources() { 1109 void OpaqueNonClientView::InitAppWindowResources() {
1108 static bool initialized = false; 1110 static bool initialized = false;
1109 if (!initialized) { 1111 if (!initialized) {
1110 title_font_ = win_util::GetWindowTitleFont(); 1112 title_font_ = win_util::GetWindowTitleFont();
1111 initialized = true; 1113 initialized = true;
1112 } 1114 }
1113 } 1115 }
OLDNEW
« no previous file with comments | « chrome/browser/views/frame/opaque_non_client_view.h ('k') | chrome/common/gfx/chrome_canvas.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698