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 "grit/ui_resources.h" 8 #include "third_party/skia/include/core/SkCanvas.h" 9 #include "third_party/skia/include/core/SkColor.h" 10 #include "ui/base/theme_provider.h" 11 #include "ui/gfx/canvas.h" 12 #include "ui/views/view.h" 13 14 namespace views { 15 16 FrameBackground::FrameBackground() 17 : frame_color_(0), 18 theme_image_(NULL), 19 theme_overlay_image_(NULL), 20 top_area_height_(0), 21 left_edge_(NULL), 22 top_edge_(NULL), 23 right_edge_(NULL), 24 bottom_edge_(NULL), 25 top_left_corner_(NULL), 26 top_right_corner_(NULL), 27 bottom_left_corner_(NULL), 28 bottom_right_corner_(NULL), 29 maximized_top_left_(NULL), 30 maximized_top_right_(NULL), 31 maximized_top_offset_(0), 32 theme_background_y_(0) { 33 } 34 35 FrameBackground::~FrameBackground() { 36 } 37 38 void FrameBackground::SetSideImages(const gfx::ImageSkia* left, 39 const gfx::ImageSkia* top, 40 const gfx::ImageSkia* right, 41 const gfx::ImageSkia* bottom) { 42 left_edge_ = left; 43 top_edge_ = top; 44 right_edge_ = right; 45 bottom_edge_ = bottom; 46 } 47 48 void FrameBackground::SetCornerImages(const gfx::ImageSkia* top_left, 49 const gfx::ImageSkia* top_right, 50 const gfx::ImageSkia* bottom_left, 51 const gfx::ImageSkia* bottom_right) { 52 top_left_corner_ = top_left; 53 top_right_corner_ = top_right; 54 bottom_left_corner_ = bottom_left; 55 bottom_right_corner_ = bottom_right; 56 } 57 58 void FrameBackground::PaintRestored(gfx::Canvas* canvas, View* view) const { 59 // Fill with the frame color first so we have a constant background for 60 // areas not covered by the theme image. 61 PaintFrameColor(canvas, view); 62 63 // Draw the theme frame. 64 canvas->TileImageInt(*theme_image_, 65 0, 0, view->width(), theme_image_->height()); 66 67 // Draw the theme frame overlay, if available. 68 if (theme_overlay_image_) 69 canvas->DrawImageInt(*theme_overlay_image_, 0, 0); 70 71 // Draw the top corners and edge, scaling the corner images down if they 72 // are too big and relative to the vertical space available. 73 int top_left_height = 74 std::min(top_left_corner_->height(), 75 view->height() - bottom_left_corner_->height()); 76 canvas->DrawImageInt(*top_left_corner_, 77 0, 0, top_left_corner_->width(), top_left_height, 78 0, 0, top_left_corner_->width(), top_left_height, 79 false); 80 canvas->TileImageInt(*top_edge_, 81 top_left_corner_->width(), 82 0, 83 view->width() - top_left_corner_->width() - top_right_corner_->width(), 84 top_edge_->height()); 85 int top_right_height = 86 std::min(top_right_corner_->height(), 87 view->height() - bottom_right_corner_->height()); 88 canvas->DrawImageInt(*top_right_corner_, 89 0, 0, 90 top_right_corner_->width(), top_right_height, 91 view->width() - top_right_corner_->width(), 0, 92 top_right_corner_->width(), top_right_height, 93 false); 94 95 // Right edge. 96 int right_edge_height = 97 view->height() - top_right_height - bottom_right_corner_->height(); 98 canvas->TileImageInt(*right_edge_, 99 view->width() - right_edge_->width(), 100 top_right_height, 101 right_edge_->width(), 102 right_edge_height); 103 104 // Bottom corners and edge. 105 canvas->DrawImageInt(*bottom_right_corner_, 106 view->width() - bottom_right_corner_->width(), 107 view->height() - bottom_right_corner_->height()); 108 canvas->TileImageInt( 109 *bottom_edge_, 110 bottom_left_corner_->width(), 111 view->height() - bottom_edge_->height(), 112 view->width() - bottom_left_corner_->width() 113 - bottom_right_corner_->width(), 114 bottom_edge_->height()); 115 canvas->DrawImageInt(*bottom_left_corner_, 0, 116 view->height() - bottom_left_corner_->height()); 117 118 // Left edge. 119 int left_edge_height = 120 view->height() - top_left_height - bottom_left_corner_->height(); 121 canvas->TileImageInt(*left_edge_, 122 0, top_left_height, 123 left_edge_->width(), left_edge_height); 124 } 125 126 void FrameBackground::PaintMaximized(gfx::Canvas* canvas, View* view) const { 127 // We will be painting from top_offset to top_offset + theme_frame_height. If 128 // this is less than top_area_height_, we need to paint the frame color 129 // to fill in the area beneath the image. 130 // TODO(jamescook): I'm not sure this is correct, as it doesn't seem to fully 131 // account for the top_offset, but this is how it worked before. 132 int theme_frame_bottom = maximized_top_offset_ + theme_image_->height(); 133 if (top_area_height_ > theme_frame_bottom) { 134 canvas->FillRect(gfx::Rect(0, 0, view->width(), top_area_height_), 135 frame_color_); 136 } 137 138 int left_offset = 0; 139 int right_offset = 0; 140 141 // Draw top-left and top-right corners to give maximized ChromeOS windows 142 // a rounded appearance. 143 if (maximized_top_left_ || maximized_top_right_) { 144 // If we have either a left or right we should have both. 145 DCHECK(maximized_top_left_ && maximized_top_right_); 146 left_offset = maximized_top_left_->width(); 147 right_offset = maximized_top_right_->width(); 148 canvas->DrawImageInt(*maximized_top_left_, 0, 0); 149 canvas->DrawImageInt(*maximized_top_right_, 150 view->width() - right_offset, 0); 151 } 152 153 // Draw the theme frame. 154 canvas->TileImageInt(*theme_image_, 155 left_offset, 156 maximized_top_offset_, 157 view->width() - (left_offset + right_offset), 158 theme_image_->height()); 159 // Draw the theme frame overlay, if available. 160 if (theme_overlay_image_) 161 canvas->DrawImageInt(*theme_overlay_image_, 0, theme_background_y_); 162 } 163 164 void FrameBackground::PaintFrameColor(gfx::Canvas* canvas, View* view) const { 165 // Fill the top area. 166 canvas->FillRect(gfx::Rect(0, 0, view->width(), top_area_height_), 167 frame_color_); 168 169 // If the window is very short, we're done. 170 int remaining_height = view->height() - top_area_height_; 171 if (remaining_height <= 0) 172 return; 173 174 // Fill down the sides. 175 canvas->FillRect(gfx::Rect(0, top_area_height_, left_edge_->width(), 176 remaining_height), frame_color_); 177 canvas->FillRect(gfx::Rect(view->width() - right_edge_->width(), 178 top_area_height_, right_edge_->width(), 179 remaining_height), frame_color_); 180 181 // If the window is very narrow, we're done. 182 int center_width = 183 view->width() - left_edge_->width() - right_edge_->width(); 184 if (center_width <= 0) 185 return; 186 187 // Fill the bottom area. 188 canvas->FillRect(gfx::Rect(left_edge_->width(), 189 view->height() - bottom_edge_->height(), 190 center_width, bottom_edge_->height()), 191 frame_color_); 192 } 193 194 } // namespace views 195