blob: 0b2d4aec7555dd05a6bd5646bb627e84114351b2 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/window/frame_background.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/theme_provider.h"
#include "ui/gfx/canvas.h"
#include "ui/views/view.h"
namespace views {
FrameBackground::FrameBackground()
: frame_color_(0),
theme_image_(NULL),
theme_overlay_image_(NULL),
top_area_height_(0),
left_edge_(NULL),
top_edge_(NULL),
right_edge_(NULL),
bottom_edge_(NULL),
top_left_corner_(NULL),
top_right_corner_(NULL),
bottom_left_corner_(NULL),
bottom_right_corner_(NULL),
maximized_top_inset_(0) {
}
FrameBackground::~FrameBackground() {
}
void FrameBackground::SetSideImages(const gfx::ImageSkia* left,
const gfx::ImageSkia* top,
const gfx::ImageSkia* right,
const gfx::ImageSkia* bottom) {
left_edge_ = left;
top_edge_ = top;
right_edge_ = right;
bottom_edge_ = bottom;
}
void FrameBackground::SetCornerImages(const gfx::ImageSkia* top_left,
const gfx::ImageSkia* top_right,
const gfx::ImageSkia* bottom_left,
const gfx::ImageSkia* bottom_right) {
top_left_corner_ = top_left;
top_right_corner_ = top_right;
bottom_left_corner_ = bottom_left;
bottom_right_corner_ = bottom_right;
}
void FrameBackground::PaintRestored(gfx::Canvas* canvas,
const View* view) const {
// Fill with the frame color first so we have a constant background for
// areas not covered by the theme image.
PaintFrameColor(canvas, view);
// Draw the theme frame.
canvas->TileImageInt(*theme_image_,
0, 0, view->width(), theme_image_->height());
// Draw the theme frame overlay, if available.
if (theme_overlay_image_)
canvas->DrawImageInt(*theme_overlay_image_, 0, 0);
// Draw the top corners and edge, scaling the corner images down if they
// are too big and relative to the vertical space available.
int top_left_height =
std::min(top_left_corner_->height(),
view->height() - bottom_left_corner_->height());
canvas->DrawImageInt(*top_left_corner_,
0, 0, top_left_corner_->width(), top_left_height,
0, 0, top_left_corner_->width(), top_left_height,
false);
canvas->TileImageInt(*top_edge_,
top_left_corner_->width(),
0,
view->width() - top_left_corner_->width() - top_right_corner_->width(),
top_edge_->height());
int top_right_height =
std::min(top_right_corner_->height(),
view->height() - bottom_right_corner_->height());
canvas->DrawImageInt(*top_right_corner_,
0, 0,
top_right_corner_->width(), top_right_height,
view->width() - top_right_corner_->width(), 0,
top_right_corner_->width(), top_right_height,
false);
// Right edge.
int right_edge_height =
view->height() - top_right_height - bottom_right_corner_->height();
canvas->TileImageInt(*right_edge_,
view->width() - right_edge_->width(),
top_right_height,
right_edge_->width(),
right_edge_height);
// Bottom corners and edge.
canvas->DrawImageInt(*bottom_right_corner_,
view->width() - bottom_right_corner_->width(),
view->height() - bottom_right_corner_->height());
canvas->TileImageInt(
*bottom_edge_,
bottom_left_corner_->width(),
view->height() - bottom_edge_->height(),
view->width() - bottom_left_corner_->width()
- bottom_right_corner_->width(),
bottom_edge_->height());
canvas->DrawImageInt(*bottom_left_corner_, 0,
view->height() - bottom_left_corner_->height());
// Left edge.
int left_edge_height =
view->height() - top_left_height - bottom_left_corner_->height();
canvas->TileImageInt(*left_edge_,
0, top_left_height,
left_edge_->width(), left_edge_height);
}
void FrameBackground::PaintMaximized(gfx::Canvas* canvas,
const View* view) const {
// We will be painting from -|maximized_top_inset_| to
// -|maximized_top_inset_| + |theme_image_|->height(). If this is less than
// |top_area_height_|, we need to paint the frame color to fill in the area
// beneath the image.
int theme_frame_bottom = -maximized_top_inset_ + theme_image_->height();
if (top_area_height_ > theme_frame_bottom) {
canvas->FillRect(gfx::Rect(0, 0, view->width(), top_area_height_),
frame_color_);
}
// Draw the theme frame.
canvas->TileImageInt(*theme_image_,
0,
-maximized_top_inset_,
view->width(),
theme_image_->height());
// Draw the theme frame overlay, if available.
if (theme_overlay_image_)
canvas->DrawImageInt(*theme_overlay_image_, 0, -maximized_top_inset_);
}
void FrameBackground::PaintFrameColor(gfx::Canvas* canvas,
const View* view) const {
// Fill the top area.
canvas->FillRect(gfx::Rect(0, 0, view->width(), top_area_height_),
frame_color_);
// If the window is very short, we're done.
int remaining_height = view->height() - top_area_height_;
if (remaining_height <= 0)
return;
// Fill down the sides.
canvas->FillRect(gfx::Rect(0, top_area_height_, left_edge_->width(),
remaining_height), frame_color_);
canvas->FillRect(gfx::Rect(view->width() - right_edge_->width(),
top_area_height_, right_edge_->width(),
remaining_height), frame_color_);
// If the window is very narrow, we're done.
int center_width =
view->width() - left_edge_->width() - right_edge_->width();
if (center_width <= 0)
return;
// Fill the bottom area.
canvas->FillRect(gfx::Rect(left_edge_->width(),
view->height() - bottom_edge_->height(),
center_width, bottom_edge_->height()),
frame_color_);
}
} // namespace views