• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
FrameBackground()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 
~FrameBackground()35 FrameBackground::~FrameBackground() {
36 }
37 
SetSideImages(const gfx::ImageSkia * left,const gfx::ImageSkia * top,const gfx::ImageSkia * right,const gfx::ImageSkia * bottom)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 
SetCornerImages(const gfx::ImageSkia * top_left,const gfx::ImageSkia * top_right,const gfx::ImageSkia * bottom_left,const gfx::ImageSkia * bottom_right)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 
PaintRestored(gfx::Canvas * canvas,View * view) const58 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 
PaintMaximized(gfx::Canvas * canvas,View * view) const126 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 
PaintFrameColor(gfx::Canvas * canvas,View * view) const164 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