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 "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