1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/views/window/frame_background.h" 6 7 #include "third_party/skia/include/core/SkCanvas.h" 8 #include "third_party/skia/include/core/SkColor.h" 9 #include "ui/base/theme_provider.h" 10 #include "ui/gfx/canvas.h" 11 #include "ui/views/view.h" 12 13 namespace views { 14 15 FrameBackground::FrameBackground() 16 : frame_color_(0), 17 theme_image_(NULL), 18 theme_overlay_image_(NULL), 19 top_area_height_(0), 20 left_edge_(NULL), 21 top_edge_(NULL), 22 right_edge_(NULL), 23 bottom_edge_(NULL), 24 top_left_corner_(NULL), 25 top_right_corner_(NULL), 26 bottom_left_corner_(NULL), 27 bottom_right_corner_(NULL), 28 maximized_top_inset_(0) { 29 } 30 31 FrameBackground::~FrameBackground() { 32 } 33 34 void FrameBackground::SetSideImages(const gfx::ImageSkia* left, 35 const gfx::ImageSkia* top, 36 const gfx::ImageSkia* right, 37 const gfx::ImageSkia* bottom) { 38 left_edge_ = left; 39 top_edge_ = top; 40 right_edge_ = right; 41 bottom_edge_ = bottom; 42 } 43 44 void FrameBackground::SetCornerImages(const gfx::ImageSkia* top_left, 45 const gfx::ImageSkia* top_right, 46 const gfx::ImageSkia* bottom_left, 47 const gfx::ImageSkia* bottom_right) { 48 top_left_corner_ = top_left; 49 top_right_corner_ = top_right; 50 bottom_left_corner_ = bottom_left; 51 bottom_right_corner_ = bottom_right; 52 } 53 54 void FrameBackground::PaintRestored(gfx::Canvas* canvas, View* view) const { 55 // Fill with the frame color first so we have a constant background for 56 // areas not covered by the theme image. 57 PaintFrameColor(canvas, view); 58 59 // Draw the theme frame. 60 canvas->TileImageInt(*theme_image_, 61 0, 0, view->width(), theme_image_->height()); 62 63 // Draw the theme frame overlay, if available. 64 if (theme_overlay_image_) 65 canvas->DrawImageInt(*theme_overlay_image_, 0, 0); 66 67 // Draw the top corners and edge, scaling the corner images down if they 68 // are too big and relative to the vertical space available. 69 int top_left_height = 70 std::min(top_left_corner_->height(), 71 view->height() - bottom_left_corner_->height()); 72 canvas->DrawImageInt(*top_left_corner_, 73 0, 0, top_left_corner_->width(), top_left_height, 74 0, 0, top_left_corner_->width(), top_left_height, 75 false); 76 canvas->TileImageInt(*top_edge_, 77 top_left_corner_->width(), 78 0, 79 view->width() - top_left_corner_->width() - top_right_corner_->width(), 80 top_edge_->height()); 81 int top_right_height = 82 std::min(top_right_corner_->height(), 83 view->height() - bottom_right_corner_->height()); 84 canvas->DrawImageInt(*top_right_corner_, 85 0, 0, 86 top_right_corner_->width(), top_right_height, 87 view->width() - top_right_corner_->width(), 0, 88 top_right_corner_->width(), top_right_height, 89 false); 90 91 // Right edge. 92 int right_edge_height = 93 view->height() - top_right_height - bottom_right_corner_->height(); 94 canvas->TileImageInt(*right_edge_, 95 view->width() - right_edge_->width(), 96 top_right_height, 97 right_edge_->width(), 98 right_edge_height); 99 100 // Bottom corners and edge. 101 canvas->DrawImageInt(*bottom_right_corner_, 102 view->width() - bottom_right_corner_->width(), 103 view->height() - bottom_right_corner_->height()); 104 canvas->TileImageInt( 105 *bottom_edge_, 106 bottom_left_corner_->width(), 107 view->height() - bottom_edge_->height(), 108 view->width() - bottom_left_corner_->width() 109 - bottom_right_corner_->width(), 110 bottom_edge_->height()); 111 canvas->DrawImageInt(*bottom_left_corner_, 0, 112 view->height() - bottom_left_corner_->height()); 113 114 // Left edge. 115 int left_edge_height = 116 view->height() - top_left_height - bottom_left_corner_->height(); 117 canvas->TileImageInt(*left_edge_, 118 0, top_left_height, 119 left_edge_->width(), left_edge_height); 120 } 121 122 void FrameBackground::PaintMaximized(gfx::Canvas* canvas, View* view) const { 123 // We will be painting from -|maximized_top_inset_| to 124 // -|maximized_top_inset_| + |theme_image_|->height(). If this is less than 125 // |top_area_height_|, we need to paint the frame color to fill in the area 126 // beneath the image. 127 int theme_frame_bottom = -maximized_top_inset_ + theme_image_->height(); 128 if (top_area_height_ > theme_frame_bottom) { 129 canvas->FillRect(gfx::Rect(0, 0, view->width(), top_area_height_), 130 frame_color_); 131 } 132 133 // Draw the theme frame. 134 canvas->TileImageInt(*theme_image_, 135 0, 136 -maximized_top_inset_, 137 view->width(), 138 theme_image_->height()); 139 // Draw the theme frame overlay, if available. 140 if (theme_overlay_image_) 141 canvas->DrawImageInt(*theme_overlay_image_, 0, -maximized_top_inset_); 142 } 143 144 void FrameBackground::PaintFrameColor(gfx::Canvas* canvas, View* view) const { 145 // Fill the top area. 146 canvas->FillRect(gfx::Rect(0, 0, view->width(), top_area_height_), 147 frame_color_); 148 149 // If the window is very short, we're done. 150 int remaining_height = view->height() - top_area_height_; 151 if (remaining_height <= 0) 152 return; 153 154 // Fill down the sides. 155 canvas->FillRect(gfx::Rect(0, top_area_height_, left_edge_->width(), 156 remaining_height), frame_color_); 157 canvas->FillRect(gfx::Rect(view->width() - right_edge_->width(), 158 top_area_height_, right_edge_->width(), 159 remaining_height), frame_color_); 160 161 // If the window is very narrow, we're done. 162 int center_width = 163 view->width() - left_edge_->width() - right_edge_->width(); 164 if (center_width <= 0) 165 return; 166 167 // Fill the bottom area. 168 canvas->FillRect(gfx::Rect(left_edge_->width(), 169 view->height() - bottom_edge_->height(), 170 center_width, bottom_edge_->height()), 171 frame_color_); 172 } 173 174 } // namespace views 175