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

Side by Side Diff: chrome/views/custom_frame_window.cc

Issue 19484: Fix various problems with constrained windows and/or custom frame windows:... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 10 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/constrained_window_impl.cc ('k') | no next file » | 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/views/custom_frame_window.h" 5 #include "chrome/views/custom_frame_window.h"
6 6
7 #include "base/gfx/point.h" 7 #include "base/gfx/point.h"
8 #include "base/gfx/size.h" 8 #include "base/gfx/size.h"
9 #include "base/win_util.h" 9 #include "base/win_util.h"
10 #include "chrome/app/theme/theme_resources.h" 10 #include "chrome/app/theme/theme_resources.h"
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 209
210 static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT]; 210 static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT];
211 211
212 DISALLOW_EVIL_CONSTRUCTORS(InactiveWindowResources); 212 DISALLOW_EVIL_CONSTRUCTORS(InactiveWindowResources);
213 }; 213 };
214 214
215 // static 215 // static
216 SkBitmap* ActiveWindowResources::standard_frame_bitmaps_[]; 216 SkBitmap* ActiveWindowResources::standard_frame_bitmaps_[];
217 SkBitmap* InactiveWindowResources::standard_frame_bitmaps_[]; 217 SkBitmap* InactiveWindowResources::standard_frame_bitmaps_[];
218 218
219
220 /////////////////////////////////////////////////////////////////////////////// 219 ///////////////////////////////////////////////////////////////////////////////
221 // 220 //
222 // DefaultNonClientView 221 // DefaultNonClientView
223 // 222 //
224 // A ChromeView that provides the "frame" for CustomFrameWindows. This means 223 // A ChromeView that provides the "frame" for CustomFrameWindows. This means
225 // rendering the non-standard window caption, border, and controls. 224 // rendering the non-standard window caption, border, and controls.
226 // 225 //
227 //////////////////////////////////////////////////////////////////////////////// 226 ////////////////////////////////////////////////////////////////////////////////
228 class DefaultNonClientView : public NonClientView, 227 class DefaultNonClientView : public NonClientView,
229 public BaseButton::ButtonListener { 228 public BaseButton::ButtonListener {
(...skipping 14 matching lines...) Expand all
244 // View overrides: 243 // View overrides:
245 virtual void Paint(ChromeCanvas* canvas); 244 virtual void Paint(ChromeCanvas* canvas);
246 virtual void Layout(); 245 virtual void Layout();
247 virtual gfx::Size GetPreferredSize(); 246 virtual gfx::Size GetPreferredSize();
248 virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); 247 virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
249 248
250 // BaseButton::ButtonListener implementation: 249 // BaseButton::ButtonListener implementation:
251 virtual void ButtonPressed(BaseButton* sender); 250 virtual void ButtonPressed(BaseButton* sender);
252 251
253 private: 252 private:
254 // Updates the system menu icon button. 253 // Returns the thickness of the border that makes up the window frame edges.
255 void SetWindowIcon(SkBitmap window_icon); 254 // This does not include any client edge.
255 int FrameBorderThickness() const;
256
257 // Returns the thickness of the entire nonclient left, right, and bottom
258 // borders, including both the window frame and any client edge.
259 int NonClientBorderThickness() const;
256 260
257 // Returns the height of the entire nonclient top border, including the window 261 // Returns the height of the entire nonclient top border, including the window
258 // frame, any title area, and any connected client edge. 262 // frame, any title area, and any connected client edge.
259 int NonClientTopBorderHeight() const; 263 int NonClientTopBorderHeight() const;
260 264
265 // A bottom border, and, in restored mode, a client edge are drawn at the
266 // bottom of the titlebar. This returns the total height drawn.
267 int BottomEdgeThicknessWithinNonClientHeight() const;
268
269 // Calculates multiple values related to title layout. Returns the height of
270 // the entire titlebar including any connected client edge.
271 int TitleCoordinates(int* title_top_spacing,
272 int* title_thickness) const;
273
261 // Paint various sub-components of this view. 274 // Paint various sub-components of this view.
262 void PaintRestoredFrameBorder(ChromeCanvas* canvas); 275 void PaintRestoredFrameBorder(ChromeCanvas* canvas);
263 void PaintMaximizedFrameBorder(ChromeCanvas* canvas); 276 void PaintMaximizedFrameBorder(ChromeCanvas* canvas);
264 void PaintTitleBar(ChromeCanvas* canvas); 277 void PaintTitleBar(ChromeCanvas* canvas);
265 void PaintClientEdge(ChromeCanvas* canvas); 278 void PaintRestoredClientEdge(ChromeCanvas* canvas);
266 279
267 // Layout various sub-components of this view. 280 // Layout various sub-components of this view.
268 void LayoutWindowControls(); 281 void LayoutWindowControls();
269 void LayoutTitleBar(); 282 void LayoutTitleBar();
270 void LayoutClientView(); 283 void LayoutClientView();
271 284
272 // Returns the resource collection to be used when rendering the window. 285 // Returns the resource collection to be used when rendering the window.
273 WindowResources* resources() const { 286 WindowResources* resources() const {
274 return container_->is_active() || paint_as_active() ? active_resources_ 287 return container_->is_active() || paint_as_active() ? active_resources_
275 : inactive_resources_; 288 : inactive_resources_;
(...skipping 24 matching lines...) Expand all
300 static WindowResources* inactive_resources_; 313 static WindowResources* inactive_resources_;
301 static ChromeFont title_font_; 314 static ChromeFont title_font_;
302 315
303 DISALLOW_EVIL_CONSTRUCTORS(DefaultNonClientView); 316 DISALLOW_EVIL_CONSTRUCTORS(DefaultNonClientView);
304 }; 317 };
305 318
306 // static 319 // static
307 WindowResources* DefaultNonClientView::active_resources_ = NULL; 320 WindowResources* DefaultNonClientView::active_resources_ = NULL;
308 WindowResources* DefaultNonClientView::inactive_resources_ = NULL; 321 WindowResources* DefaultNonClientView::inactive_resources_ = NULL;
309 ChromeFont DefaultNonClientView::title_font_; 322 ChromeFont DefaultNonClientView::title_font_;
310 static const int kWindowControlsTopOffset = 1; 323
311 static const int kWindowControlsRightOffset = 5; 324 namespace {
312 static const int kWindowControlsTopZoomedOffset = 1; 325 // The frame border is only visible in restored mode and is hardcoded to 4 px on
313 static const int kWindowControlsRightZoomedOffset = 5; 326 // each side regardless of the system window border size.
314 static const int kWindowTopMarginZoomed = 1; 327 const int kFrameBorderThickness = 4;
315 static const int kWindowIconLeftOffset = 5; 328 // Various edges of the frame border have a 1 px shadow along their edges; in a
316 static const int kWindowIconTopOffset = 5; 329 // few cases we shift elements based on this amount for visual appeal.
317 static const int kTitleTopOffset = 6; 330 const int kFrameShadowThickness = 1;
318 static const int kWindowIconTitleSpacing = 3; 331 // While resize areas on Windows are normally the same size as the window
319 static const int kTitleBottomSpacing = 6; 332 // borders, our top area is shrunk by 1 px to make it easier to move the window
320 static const int kNoTitleTopSpacing = 8; 333 // around with our thinner top grabbable strip. (Incidentally, our side and
321 static const int kResizeAreaSize = 5; 334 // bottom resize areas don't match the frame border thickness either -- they
322 static const int kResizeAreaNorthSize = 3; 335 // span the whole nonclient area, so there's no "dead zone" for the mouse.)
323 static const int kResizeAreaCornerSize = 16; 336 const int kTopResizeAdjust = 1;
324 static const int kWindowHorizontalBorderSize = 4; 337 // In the window corners, the resize areas don't actually expand bigger, but the
325 static const int kWindowVerticalBorderSize = 4; 338 // 16 px at the end of each edge triggers diagonal resizing.
339 const int kResizeAreaCornerSize = 16;
340 // The titlebar never shrinks to less than 18 px tall, plus the height of the
341 // frame border and any bottom edge.
342 const int kTitlebarMinimumHeight = 18;
343 // The icon is inset 2 px from the left frame border.
344 const int kIconLeftSpacing = 2;
345 // The icon takes up 16/25th of the available titlebar height. (This is
346 // expressed as two ints to avoid precision losses leading to off-by-one pixel
347 // errors.)
348 const int kIconHeightFractionNumerator = 16;
349 const int kIconHeightFractionDenominator = 25;
350 // The icon never shrinks below 16 px on a side.
351 const int kIconMinimumSize = 16;
352 // Because our frame border has a different "3D look" than Windows', with a less
353 // cluttered top edge, we need to shift the icon up by 1 px in restored mode so
354 // it looks more centered.
355 const int kIconRestoredAdjust = 1;
356 // There is a 4 px gap between the icon and the title text.
357 const int kIconTitleSpacing = 4;
358 // The title text starts 2 px below the bottom of the top frame border.
359 const int kTitleTopSpacing = 2;
360 // There is a 5 px gap between the title text and the caption buttons.
361 const int kTitleCaptionSpacing = 5;
362 // The caption buttons are always drawn 1 px down from the visible top of the
363 // window (the true top in restored mode, or the top of the screen in maximized
364 // mode).
365 const int kCaptionTopSpacing = 1;
366 }
326 367
327 /////////////////////////////////////////////////////////////////////////////// 368 ///////////////////////////////////////////////////////////////////////////////
328 // DefaultNonClientView, public: 369 // DefaultNonClientView, public:
329 370
330 DefaultNonClientView::DefaultNonClientView( 371 DefaultNonClientView::DefaultNonClientView(
331 CustomFrameWindow* container) 372 CustomFrameWindow* container)
332 : NonClientView(), 373 : NonClientView(),
333 client_view_(NULL), 374 client_view_(NULL),
334 close_button_(new Button), 375 close_button_(new Button),
335 restore_button_(new Button), 376 restore_button_(new Button),
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 420
380 DefaultNonClientView::~DefaultNonClientView() { 421 DefaultNonClientView::~DefaultNonClientView() {
381 } 422 }
382 423
383 /////////////////////////////////////////////////////////////////////////////// 424 ///////////////////////////////////////////////////////////////////////////////
384 // DefaultNonClientView, CustomFrameWindow::NonClientView implementation: 425 // DefaultNonClientView, CustomFrameWindow::NonClientView implementation:
385 426
386 gfx::Rect DefaultNonClientView::CalculateClientAreaBounds(int width, 427 gfx::Rect DefaultNonClientView::CalculateClientAreaBounds(int width,
387 int height) const { 428 int height) const {
388 int top_height = NonClientTopBorderHeight(); 429 int top_height = NonClientTopBorderHeight();
389 int border_thickness = kWindowHorizontalBorderSize; 430 int border_thickness = NonClientBorderThickness();
390 return gfx::Rect(border_thickness, top_height, 431 return gfx::Rect(border_thickness, top_height,
391 std::max(0, width - (2 * border_thickness)), 432 std::max(0, width - (2 * border_thickness)),
392 std::max(0, height - top_height - kWindowVerticalBorderSize)); 433 std::max(0, height - top_height - border_thickness));
393 } 434 }
394 435
395 gfx::Size DefaultNonClientView::CalculateWindowSizeForClientSize( 436 gfx::Size DefaultNonClientView::CalculateWindowSizeForClientSize(
396 int width, 437 int width,
397 int height) const { 438 int height) const {
398 return gfx::Size(width + (2 * kWindowHorizontalBorderSize), 439 int border_thickness = NonClientBorderThickness();
399 height + NonClientTopBorderHeight() + kWindowVerticalBorderSize); 440 return gfx::Size(width + (2 * border_thickness),
441 height + NonClientTopBorderHeight() + border_thickness);
400 } 442 }
401 443
402 CPoint DefaultNonClientView::GetSystemMenuPoint() const { 444 CPoint DefaultNonClientView::GetSystemMenuPoint() const {
403 // TODO(pkasting): This is wrong; Windows native runs the menu at the bottom 445 // TODO(pkasting): This is wrong; Windows native runs the menu at the bottom
404 // of the titlebar, not the bottom of the window icon. 446 // of the titlebar, not the bottom of the window icon.
405 CPoint system_menu_point(system_menu_button_->x(), 447 CPoint system_menu_point(system_menu_button_->x(),
406 system_menu_button_->y() + system_menu_button_->height()); 448 system_menu_button_->y() + system_menu_button_->height());
407 MapWindowPoints(container_->GetHWND(), HWND_DESKTOP, &system_menu_point, 1); 449 MapWindowPoints(container_->GetHWND(), HWND_DESKTOP, &system_menu_point, 1);
408 return system_menu_point; 450 return system_menu_point;
409 } 451 }
(...skipping 14 matching lines...) Expand all
424 if (maximize_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( 466 if (maximize_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(
425 point)) 467 point))
426 return HTMAXBUTTON; 468 return HTMAXBUTTON;
427 if (minimize_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( 469 if (minimize_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(
428 point)) 470 point))
429 return HTMINBUTTON; 471 return HTMINBUTTON;
430 if (system_menu_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( 472 if (system_menu_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(
431 point)) 473 point))
432 return HTSYSMENU; 474 return HTSYSMENU;
433 475
434 int window_component = GetHTComponentForFrame(point, kResizeAreaNorthSize, 476 int window_component = GetHTComponentForFrame(point, FrameBorderThickness(),
435 kResizeAreaSize, kResizeAreaCornerSize, 477 NonClientBorderThickness(), kResizeAreaCornerSize,
436 container_->window_delegate()->CanResize()); 478 container_->window_delegate()->CanResize());
437 // Fall back to the caption if no other component matches. 479 // Fall back to the caption if no other component matches.
438 return ((window_component == HTNOWHERE) && bounds().Contains(point)) ? 480 return ((window_component == HTNOWHERE) && bounds().Contains(point)) ?
439 HTCAPTION : window_component; 481 HTCAPTION : window_component;
440 } 482 }
441 483
442 void DefaultNonClientView::GetWindowMask(const gfx::Size& size, 484 void DefaultNonClientView::GetWindowMask(const gfx::Size& size,
443 gfx::Path* window_mask) { 485 gfx::Path* window_mask) {
444 DCHECK(window_mask); 486 DCHECK(window_mask);
445 487
(...skipping 29 matching lines...) Expand all
475 517
476 /////////////////////////////////////////////////////////////////////////////// 518 ///////////////////////////////////////////////////////////////////////////////
477 // DefaultNonClientView, View overrides: 519 // DefaultNonClientView, View overrides:
478 520
479 void DefaultNonClientView::Paint(ChromeCanvas* canvas) { 521 void DefaultNonClientView::Paint(ChromeCanvas* canvas) {
480 if (container_->IsMaximized()) 522 if (container_->IsMaximized())
481 PaintMaximizedFrameBorder(canvas); 523 PaintMaximizedFrameBorder(canvas);
482 else 524 else
483 PaintRestoredFrameBorder(canvas); 525 PaintRestoredFrameBorder(canvas);
484 PaintTitleBar(canvas); 526 PaintTitleBar(canvas);
485 PaintClientEdge(canvas); 527 if (!container_->IsMaximized())
528 PaintRestoredClientEdge(canvas);
486 } 529 }
487 530
488 void DefaultNonClientView::Layout() { 531 void DefaultNonClientView::Layout() {
489 LayoutWindowControls(); 532 LayoutWindowControls();
490 LayoutTitleBar(); 533 LayoutTitleBar();
491 LayoutClientView(); 534 LayoutClientView();
492 } 535 }
493 536
494 gfx::Size DefaultNonClientView::GetPreferredSize() { 537 gfx::Size DefaultNonClientView::GetPreferredSize() {
495 gfx::Size prefsize(container_->client_view()->GetPreferredSize()); 538 gfx::Size prefsize(container_->client_view()->GetPreferredSize());
496 prefsize.Enlarge(2 * kWindowHorizontalBorderSize, 539 int border_thickness = NonClientBorderThickness();
497 NonClientTopBorderHeight() + kWindowVerticalBorderSize); 540 prefsize.Enlarge(2 * border_thickness,
541 NonClientTopBorderHeight() + border_thickness);
498 return prefsize; 542 return prefsize;
499 } 543 }
500 544
501 void DefaultNonClientView::ViewHierarchyChanged(bool is_add, 545 void DefaultNonClientView::ViewHierarchyChanged(bool is_add,
502 View* parent, 546 View* parent,
503 View* child) { 547 View* child) {
504 // Add our Client View as we are added to the Widget so that if we are 548 // Add our Client View as we are added to the Widget so that if we are
505 // subsequently resized all the parent-child relationships are established. 549 // subsequently resized all the parent-child relationships are established.
506 if (is_add && GetWidget() && child == this) 550 if (is_add && GetWidget() && child == this)
507 AddChildView(container_->client_view()); 551 AddChildView(container_->client_view());
508 } 552 }
509 553
510 /////////////////////////////////////////////////////////////////////////////// 554 ///////////////////////////////////////////////////////////////////////////////
511 // DefaultNonClientView, BaseButton::ButtonListener implementation: 555 // DefaultNonClientView, BaseButton::ButtonListener implementation:
512 556
513 void DefaultNonClientView::ButtonPressed(BaseButton* sender) { 557 void DefaultNonClientView::ButtonPressed(BaseButton* sender) {
514 if (sender == close_button_) 558 if (sender == close_button_)
515 container_->ExecuteSystemMenuCommand(SC_CLOSE); 559 container_->ExecuteSystemMenuCommand(SC_CLOSE);
516 else if (sender == minimize_button_) 560 else if (sender == minimize_button_)
517 container_->ExecuteSystemMenuCommand(SC_MINIMIZE); 561 container_->ExecuteSystemMenuCommand(SC_MINIMIZE);
518 else if (sender == maximize_button_) 562 else if (sender == maximize_button_)
519 container_->ExecuteSystemMenuCommand(SC_MAXIMIZE); 563 container_->ExecuteSystemMenuCommand(SC_MAXIMIZE);
520 else if (sender == restore_button_) 564 else if (sender == restore_button_)
521 container_->ExecuteSystemMenuCommand(SC_RESTORE); 565 container_->ExecuteSystemMenuCommand(SC_RESTORE);
522 } 566 }
523 567
524 /////////////////////////////////////////////////////////////////////////////// 568 ///////////////////////////////////////////////////////////////////////////////
525 // DefaultNonClientView, private: 569 // DefaultNonClientView, private:
526 570
571 int DefaultNonClientView::FrameBorderThickness() const {
572 return container_->IsMaximized() ?
573 GetSystemMetrics(SM_CXSIZEFRAME) : kFrameBorderThickness;
574 }
575
576 int DefaultNonClientView::NonClientBorderThickness() const {
577 // In maximized mode, we don't show a client edge.
578 return FrameBorderThickness() +
579 (container_->IsMaximized() ? 0 : kClientEdgeThickness);
580 }
581
527 int DefaultNonClientView::NonClientTopBorderHeight() const { 582 int DefaultNonClientView::NonClientTopBorderHeight() const {
528 return kTitleTopOffset + title_font_.height() + kTitleBottomSpacing; 583 int title_top_spacing, title_thickness;
584 return TitleCoordinates(&title_top_spacing, &title_thickness);
585 }
586
587 int DefaultNonClientView::BottomEdgeThicknessWithinNonClientHeight() const {
588 return kFrameShadowThickness +
589 (container_->IsMaximized() ? 0 : kClientEdgeThickness);
590 }
591
592 int DefaultNonClientView::TitleCoordinates(int* title_top_spacing,
593 int* title_thickness) const {
594 int frame_thickness = FrameBorderThickness();
595 int min_titlebar_height = kTitlebarMinimumHeight + frame_thickness;
596 *title_top_spacing = frame_thickness + kTitleTopSpacing;
597 // The bottom spacing should be the same apparent height as the top spacing.
598 // Because the actual top spacing height varies based on the system border
599 // thickness, we calculate this based on the restored top spacing and then
600 // adjust for maximized mode. We also don't include the frame shadow here,
601 // since while it's part of the bottom spacing it will be added in at the end.
602 int title_bottom_spacing =
603 kFrameBorderThickness + kTitleTopSpacing - kFrameShadowThickness;
604 if (container_->IsMaximized()) {
605 // When we maximize, the top border appears to be chopped off; shift the
606 // title down to stay centered within the remaining space.
607 int title_adjust = (kFrameBorderThickness / 2);
608 *title_top_spacing += title_adjust;
609 title_bottom_spacing -= title_adjust;
610 }
611 *title_thickness = std::max(title_font_.height(),
612 min_titlebar_height - *title_top_spacing - title_bottom_spacing);
613 return *title_top_spacing + *title_thickness + title_bottom_spacing +
614 BottomEdgeThicknessWithinNonClientHeight();
529 } 615 }
530 616
531 void DefaultNonClientView::PaintRestoredFrameBorder(ChromeCanvas* canvas) { 617 void DefaultNonClientView::PaintRestoredFrameBorder(ChromeCanvas* canvas) {
532 SkBitmap* top_left_corner = resources()->GetPartBitmap(FRAME_TOP_LEFT_CORNER); 618 SkBitmap* top_left_corner = resources()->GetPartBitmap(FRAME_TOP_LEFT_CORNER);
533 SkBitmap* top_right_corner = 619 SkBitmap* top_right_corner =
534 resources()->GetPartBitmap(FRAME_TOP_RIGHT_CORNER); 620 resources()->GetPartBitmap(FRAME_TOP_RIGHT_CORNER);
535 SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE); 621 SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE);
536 SkBitmap* right_edge = resources()->GetPartBitmap(FRAME_RIGHT_EDGE); 622 SkBitmap* right_edge = resources()->GetPartBitmap(FRAME_RIGHT_EDGE);
537 SkBitmap* left_edge = resources()->GetPartBitmap(FRAME_LEFT_EDGE); 623 SkBitmap* left_edge = resources()->GetPartBitmap(FRAME_LEFT_EDGE);
538 SkBitmap* bottom_left_corner = 624 SkBitmap* bottom_left_corner =
(...skipping 29 matching lines...) Expand all
568 654
569 // Left. 655 // Left.
570 canvas->TileImageInt(*left_edge, 0, top_left_corner->height(), 656 canvas->TileImageInt(*left_edge, 0, top_left_corner->height(),
571 left_edge->width(), 657 left_edge->width(),
572 height() - top_left_corner->height() - bottom_left_corner->height()); 658 height() - top_left_corner->height() - bottom_left_corner->height());
573 } 659 }
574 660
575 void DefaultNonClientView::PaintMaximizedFrameBorder( 661 void DefaultNonClientView::PaintMaximizedFrameBorder(
576 ChromeCanvas* canvas) { 662 ChromeCanvas* canvas) {
577 SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE); 663 SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE);
578 canvas->TileImageInt(*top_edge, 0, 0, width(), top_edge->height()); 664 canvas->TileImageInt(*top_edge, 0, FrameBorderThickness(), width(),
665 top_edge->height());
666
667 // The bottom of the titlebar actually comes from the top of the Client Edge
668 // graphic, with the actual client edge clipped off the bottom.
669 SkBitmap* titlebar_bottom = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP);
670 int edge_height = titlebar_bottom->height() - kClientEdgeThickness;
671 canvas->TileImageInt(*titlebar_bottom, 0,
672 container_->client_view()->y() - edge_height, width(), edge_height);
579 } 673 }
580 674
581 void DefaultNonClientView::PaintTitleBar(ChromeCanvas* canvas) { 675 void DefaultNonClientView::PaintTitleBar(ChromeCanvas* canvas) {
582 WindowDelegate* d = container_->window_delegate(); 676 WindowDelegate* d = container_->window_delegate();
583 canvas->DrawStringInt(d->GetWindowTitle(), title_font_, SK_ColorWHITE, 677 canvas->DrawStringInt(d->GetWindowTitle(), title_font_, SK_ColorWHITE,
584 MirroredLeftPointForRect(title_bounds_), title_bounds_.y(), 678 MirroredLeftPointForRect(title_bounds_), title_bounds_.y(),
585 title_bounds_.width(), title_bounds_.height()); 679 title_bounds_.width(), title_bounds_.height());
586 } 680 }
587 681
588 void DefaultNonClientView::PaintClientEdge(ChromeCanvas* canvas) { 682 void DefaultNonClientView::PaintRestoredClientEdge(ChromeCanvas* canvas) {
589 gfx::Rect client_area_bounds = container_->client_view()->bounds(); 683 gfx::Rect client_area_bounds = container_->client_view()->bounds();
590 int client_area_top = client_area_bounds.y(); 684 int client_area_top = client_area_bounds.y();
591 685
592 SkBitmap* top_left = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT); 686 SkBitmap* top_left = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT);
593 SkBitmap* top = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP); 687 SkBitmap* top = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP);
594 SkBitmap* top_right = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_RIGHT); 688 SkBitmap* top_right = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_RIGHT);
595 SkBitmap* right = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_RIGHT); 689 SkBitmap* right = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_RIGHT);
596 SkBitmap* bottom_right = 690 SkBitmap* bottom_right =
597 resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_RIGHT); 691 resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_RIGHT);
598 SkBitmap* bottom = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM); 692 SkBitmap* bottom = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM);
599 SkBitmap* bottom_left = 693 SkBitmap* bottom_left =
600 resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_LEFT); 694 resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_LEFT);
601 SkBitmap* left = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_LEFT); 695 SkBitmap* left = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_LEFT);
602 696
603 // Top. 697 // Top.
604 // This next calculation is necessary because the top center bitmap is shorter 698 // This next calculation is necessary because the top center bitmap is shorter
605 // than the top left and right bitmaps. We need their top edges to line up, 699 // than the top left and right bitmaps. We need their top edges to line up,
606 // and we need the left and right edges to start below the corners' bottoms. 700 // and we need the left and right edges to start below the corners' bottoms.
607 int top_edge_y = client_area_top - top->height(); 701 int top_edge_y = client_area_top - top->height();
608 client_area_top = top_edge_y + top_left->height(); 702 client_area_top = top_edge_y + top_left->height();
609 canvas->DrawBitmapInt(*top_left, client_area_bounds.x() - top_left->width(), 703 canvas->DrawBitmapInt(*top_left, client_area_bounds.x() - top_left->width(),
610 top_edge_y); 704 top_edge_y);
611 canvas->TileImageInt(*top, client_area_bounds.x(), top_edge_y, 705 canvas->TileImageInt(*top, client_area_bounds.x(), top_edge_y,
612 client_area_bounds.width(), top->height()); 706 client_area_bounds.width(), top->height());
613 canvas->DrawBitmapInt(*top_right, client_area_bounds.right(), top_edge_y); 707 canvas->DrawBitmapInt(*top_right, client_area_bounds.right(), top_edge_y);
614 708
615 // Right. 709 // Right.
710 int client_area_bottom =
711 std::max(client_area_top, client_area_bounds.bottom());
712 int client_area_height = client_area_bottom - client_area_top;
616 canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top, 713 canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top,
617 right->width(), client_area_bounds.height()); 714 right->width(), client_area_height);
618 715
619 // Bottom. 716 // Bottom.
620 canvas->DrawBitmapInt(*bottom_right, client_area_bounds.right(), 717 canvas->DrawBitmapInt(*bottom_right, client_area_bounds.right(),
621 client_area_bounds.bottom()); 718 client_area_bottom);
622 canvas->TileImageInt(*bottom, client_area_bounds.x(), 719 canvas->TileImageInt(*bottom, client_area_bounds.x(), client_area_bottom,
623 client_area_bounds.bottom(),
624 client_area_bounds.width(), bottom_right->height()); 720 client_area_bounds.width(), bottom_right->height());
625 canvas->DrawBitmapInt(*bottom_left, 721 canvas->DrawBitmapInt(*bottom_left,
626 client_area_bounds.x() - bottom_left->width(), 722 client_area_bounds.x() - bottom_left->width(), client_area_bottom);
627 client_area_bounds.bottom());
628 723
629 // Left. 724 // Left.
630 canvas->TileImageInt(*left, client_area_bounds.x() - left->width(), 725 canvas->TileImageInt(*left, client_area_bounds.x() - left->width(),
631 client_area_top, left->width(), client_area_bounds.height()); 726 client_area_top, left->width(), client_area_height);
632 } 727 }
633 728
634 void DefaultNonClientView::LayoutWindowControls() { 729 void DefaultNonClientView::LayoutWindowControls() {
635 close_button_->SetImageAlignment(Button::ALIGN_LEFT, Button::ALIGN_BOTTOM); 730 close_button_->SetImageAlignment(Button::ALIGN_LEFT, Button::ALIGN_BOTTOM);
636 // Maximized buttons start at window top so that even if their images aren't 731 // Maximized buttons start at window top so that even if their images aren't
637 // drawn flush with the screen edge, they still obey Fitts' Law. 732 // drawn flush with the screen edge, they still obey Fitts' Law.
638 bool is_maximized = container_->IsMaximized(); 733 bool is_maximized = container_->IsMaximized();
639 int caption_y = is_maximized ? 0 : kWindowControlsTopOffset; 734 int frame_thickness = FrameBorderThickness();
640 int top_extra_height = is_maximized ? kWindowControlsTopZoomedOffset : 0; 735 int caption_y = is_maximized ? frame_thickness : kCaptionTopSpacing;
736 int top_extra_height = is_maximized ? kCaptionTopSpacing : 0;
641 // There should always be the same number of non-shadow pixels visible to the 737 // There should always be the same number of non-shadow pixels visible to the
642 // side of the caption buttons. In maximized mode we extend the rightmost 738 // side of the caption buttons. In maximized mode we extend the rightmost
643 // button to the screen corner to obey Fitts' Law. 739 // button to the screen corner to obey Fitts' Law.
644 int right_extra_width = is_maximized ? kWindowControlsRightZoomedOffset : 0; 740 int right_extra_width = is_maximized ?
741 (kFrameBorderThickness - kFrameShadowThickness) : 0;
645 int right_spacing = is_maximized ? 742 int right_spacing = is_maximized ?
646 kWindowControlsRightZoomedOffset : kWindowControlsRightOffset; 743 (GetSystemMetrics(SM_CXSIZEFRAME) + right_extra_width) : frame_thickness;
647 gfx::Size close_button_size = close_button_->GetPreferredSize(); 744 gfx::Size close_button_size = close_button_->GetPreferredSize();
648 close_button_->SetBounds(width() - close_button_size.width() - right_spacing, 745 close_button_->SetBounds(width() - close_button_size.width() - right_spacing,
649 caption_y, 746 caption_y,
650 close_button_size.width() + right_extra_width, 747 close_button_size.width() + right_extra_width,
651 close_button_size.height() + top_extra_height); 748 close_button_size.height() + top_extra_height);
652 749
653 // When the window is restored, we show a maximized button; otherwise, we show 750 // When the window is restored, we show a maximized button; otherwise, we show
654 // a restore button. 751 // a restore button.
655 bool is_restored = !is_maximized && !container_->IsMinimized(); 752 bool is_restored = !is_maximized && !container_->IsMinimized();
656 views::Button* invisible_button = is_restored ? 753 views::Button* invisible_button = is_restored ?
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 788
692 close_button_->SetImage(Button::BS_NORMAL, 789 close_button_->SetImage(Button::BS_NORMAL,
693 active_resources_->GetPartBitmap(normal_part)); 790 active_resources_->GetPartBitmap(normal_part));
694 close_button_->SetImage(Button::BS_HOT, 791 close_button_->SetImage(Button::BS_HOT,
695 active_resources_->GetPartBitmap(hot_part)); 792 active_resources_->GetPartBitmap(hot_part));
696 close_button_->SetImage(Button::BS_PUSHED, 793 close_button_->SetImage(Button::BS_PUSHED,
697 active_resources_->GetPartBitmap(pushed_part)); 794 active_resources_->GetPartBitmap(pushed_part));
698 } 795 }
699 796
700 void DefaultNonClientView::LayoutTitleBar() { 797 void DefaultNonClientView::LayoutTitleBar() {
701 int top_offset = container_->IsMaximized() ? kWindowTopMarginZoomed : 0; 798 // Always lay out the icon, even when it's not present, so we can lay out the
702 WindowDelegate* d = container_->window_delegate(); 799 // window title based on its position.
800 int frame_thickness = FrameBorderThickness();
801 int icon_x = frame_thickness + kIconLeftSpacing;
703 802
704 // Size the window icon, if visible. 803 // The usable height of the titlebar area is the total height minus the top
705 if (d->ShouldShowWindowIcon()) { 804 // resize border and any edge area we draw at its bottom.
706 system_menu_button_->SetVisible(true); 805 int title_top_spacing, title_thickness;
707 gfx::Size ps = system_menu_button_->GetPreferredSize(); 806 int top_height = TitleCoordinates(&title_top_spacing, &title_thickness);
708 system_menu_button_->SetBounds( 807 int available_height = top_height - frame_thickness -
709 kWindowIconLeftOffset, kWindowIconTopOffset + top_offset, ps.width(), 808 BottomEdgeThicknessWithinNonClientHeight();
710 ps.height()); 809
711 } else { 810 // The icon takes up a constant fraction of the available height, down to a
712 // Put the menu in the right place at least even if it is hidden so we 811 // minimum size, and is always an even number of pixels on a side (presumably
713 // can size the title based on its position. 812 // to make scaled icons look better). It's centered within the usable height.
714 system_menu_button_->SetBounds(kWindowIconLeftOffset, 813 int icon_size = std::max((available_height * kIconHeightFractionNumerator /
715 kWindowIconTopOffset, 0, 0); 814 kIconHeightFractionDenominator) / 2 * 2, kIconMinimumSize);
716 } 815 int icon_y = ((available_height - icon_size) / 2) + frame_thickness;
816
817 // Hack: Our frame border has a different "3D look" than Windows'. Theirs has
818 // a more complex gradient on the top that they push their icon/title below;
819 // then the maximized window cuts this off and the icon/title are centered in
820 // the remaining space. Because the apparent shape of our border is simpler,
821 // using the same positioning makes things look slightly uncentered with
822 // restored windows, so we come up to compensate.
823 if (!container_->IsMaximized())
824 icon_y -= kIconRestoredAdjust;
825
826 views::WindowDelegate* d = container_->window_delegate();
827 if (!d->ShouldShowWindowIcon())
828 icon_size = 0;
829 system_menu_button_->SetBounds(icon_x, icon_y, icon_size, icon_size);
717 830
718 // Size the title. 831 // Size the title.
719 gfx::Rect system_menu_bounds = system_menu_button_->bounds(); 832 int icon_right = icon_x + icon_size;
720 int spacing = d->ShouldShowWindowIcon() ? kWindowIconTitleSpacing : 0; 833 int title_x =
721 int title_right = should_show_minmax_buttons_ ? 834 icon_right + (d->ShouldShowWindowIcon() ? kIconTitleSpacing : 0);
722 minimize_button_->x() : close_button_->x(); 835 int title_right = (should_show_minmax_buttons_ ?
723 int title_left = system_menu_bounds.right() + spacing; 836 minimize_button_->x() : close_button_->x()) - kTitleCaptionSpacing;
724 title_bounds_.SetRect(title_left, kTitleTopOffset + top_offset, 837 title_bounds_.SetRect(title_x,
725 std::max(0, static_cast<int>(title_right - system_menu_bounds.right())), 838 title_top_spacing + ((title_thickness - title_font_.height()) / 2),
726 title_font_.height()); 839 std::max(0, title_right - title_x), title_font_.height());
727
728 // Center the icon within the height of the title if the title is taller.
729 int delta_y = title_bounds_.height() - system_menu_button_->height();
730 if (delta_y > 0) {
731 int new_y = title_bounds_.y() + static_cast<int>(delta_y / 2);
732 system_menu_button_->SetBounds(system_menu_button_->x(), new_y,
733 system_menu_button_->width(),
734 system_menu_button_->height());
735 }
736 } 840 }
737 841
738 void DefaultNonClientView::LayoutClientView() { 842 void DefaultNonClientView::LayoutClientView() {
739 container_->client_view()->SetBounds(CalculateClientAreaBounds(width(), 843 container_->client_view()->SetBounds(CalculateClientAreaBounds(width(),
740 height())); 844 height()));
741 } 845 }
742 846
743 // static 847 // static
744 void DefaultNonClientView::InitClass() { 848 void DefaultNonClientView::InitClass() {
745 static bool initialized = false; 849 static bool initialized = false;
746 if (!initialized) { 850 if (!initialized) {
747 active_resources_ = new ActiveWindowResources; 851 active_resources_ = new ActiveWindowResources;
748 inactive_resources_ = new InactiveWindowResources; 852 inactive_resources_ = new InactiveWindowResources;
853
749 title_font_ = win_util::GetWindowTitleFont(); 854 title_font_ = win_util::GetWindowTitleFont();
855
750 initialized = true; 856 initialized = true;
751 } 857 }
752 } 858 }
753 859
754 /////////////////////////////////////////////////////////////////////////////// 860 ///////////////////////////////////////////////////////////////////////////////
755 // NonClientViewLayout 861 // NonClientViewLayout
756 862
757 class NonClientViewLayout : public LayoutManager { 863 class NonClientViewLayout : public LayoutManager {
758 public: 864 public:
759 // The size of the default window border and padding used by Windows Vista 865 // The size of the default window border and padding used by Windows Vista
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
1261 if ((GetKeyState(VK_CONTROL) & 0x80) == 0x80) 1367 if ((GetKeyState(VK_CONTROL) & 0x80) == 0x80)
1262 message_flags |= MK_CONTROL; 1368 message_flags |= MK_CONTROL;
1263 if ((GetKeyState(VK_SHIFT) & 0x80) == 0x80) 1369 if ((GetKeyState(VK_SHIFT) & 0x80) == 0x80)
1264 message_flags |= MK_SHIFT; 1370 message_flags |= MK_SHIFT;
1265 message_flags |= flags; 1371 message_flags |= flags;
1266 ProcessMousePressed(temp, message_flags, false); 1372 ProcessMousePressed(temp, message_flags, false);
1267 } 1373 }
1268 1374
1269 } // namespace views 1375 } // namespace views
1270 1376
OLDNEW
« no previous file with comments | « chrome/browser/views/constrained_window_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698