Home | History | Annotate | Download | only in window
      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