• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2010 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 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_ROUNDED_VIEW_H_
6 #define CHROME_BROWSER_CHROMEOS_LOGIN_ROUNDED_VIEW_H_
7 
8 #include "ui/gfx/canvas.h"
9 #include "ui/gfx/canvas_skia.h"
10 #include "ui/gfx/rect.h"
11 
12 namespace chromeos {
13 
14 namespace rounded_view {
15 
16 // Corner radius of the RoundedView.
17 const SkScalar kCornerRadius = SkIntToScalar(5);
18 
19 // Stroke width to be used by the RoundedView.
20 const SkScalar kStrokeWidth = SkIntToScalar(1);
21 
22 // Color of the inner frame of the RoundedView.
23 const SkColor kInnerFrameColor = SK_ColorWHITE;
24 
25 // Color of the outer frame of the RoundedView.
26 const SkColor kOuterFrameColor = 0xFF555555;
27 
28 }  // namespace rounded_view
29 
30 // Class that sets up the round rectangle as a clip region of the view.
31 // |C| - class inherited from |views::View|.
32 template<typename C>
33 class RoundedView: public C {
34  public:
35   // Empty constructor.
RoundedView()36   RoundedView() {}
37 
38   // Constructors.
39   template<typename D>
RoundedView(const D & value)40   explicit RoundedView(const D &value) : C(value) {}
41   template<typename D1, typename D2>
RoundedView(const D1 & val1,const D2 & val2)42   RoundedView(const D1& val1, const D2& val2) : C(val1, val2) {}
43 
44   // Overrides views::View.
45   virtual void Paint(gfx::Canvas* canvas);
46 
47  protected:
48   // Returns the path that will be used for a clip.
49   virtual SkPath GetClipPath() const;
50 
51   // Returns maximal rectangle in the view.
52   virtual SkRect GetViewRect() const;
53 
54   // Draws custom frame for the view.
55   virtual void DrawFrame(gfx::Canvas* canvas);
56 };
57 
58 // RoundedView implementation.
59 
60 template <typename C>
Paint(gfx::Canvas * canvas)61 void RoundedView<C>::Paint(gfx::Canvas* canvas) {
62   // Setup clip region.
63   canvas->Save();
64   canvas->AsCanvasSkia()->clipPath(GetClipPath());
65   // Do original painting.
66   C::Paint(canvas);
67   canvas->Restore();
68   // Add frame.
69   DrawFrame(canvas);
70 }
71 
72 template <typename C>
GetClipPath()73 SkPath RoundedView<C>::GetClipPath() const {
74   SkPath round_view;
75   SkRect view_rect = GetViewRect();
76   view_rect.inset(2 * rounded_view::kStrokeWidth,
77                   2 * rounded_view::kStrokeWidth);
78   // 3 is used instead of 2 to avoid empty points between the clip and
79   // the frame.
80   round_view.addRoundRect(
81       view_rect,
82       rounded_view::kCornerRadius - 3 * rounded_view::kStrokeWidth,
83       rounded_view::kCornerRadius - 3 * rounded_view::kStrokeWidth);
84 
85   return round_view;
86 }
87 
88 template <typename C>
GetViewRect()89 SkRect RoundedView<C>::GetViewRect() const {
90   SkRect view_rect;
91   view_rect.iset(this->x(),
92                  this->y(),
93                  this->x() + this->width(),
94                  this->y() + this->height());
95   return view_rect;
96 }
97 
98 template <typename C>
DrawFrame(gfx::Canvas * canvas)99 void RoundedView<C>::DrawFrame(gfx::Canvas* canvas) {
100   SkPaint paint;
101   paint.setStyle(SkPaint::kStroke_Style);
102   paint.setStrokeWidth(rounded_view::kStrokeWidth);
103   paint.setAntiAlias(true);
104   SkRect view_rect = GetViewRect();
105 
106   // Used to make nested rounded rects look better.
107   const SkScalar kOriginShift = 1.0;
108   const SkScalar kDelta = 0.3;
109 
110   // Draw inner frame.
111   view_rect.fLeft -= kOriginShift;
112   view_rect.fTop -= kOriginShift;
113   view_rect.inset(rounded_view::kStrokeWidth, rounded_view::kStrokeWidth);
114   paint.setColor(rounded_view::kInnerFrameColor);
115   canvas->AsCanvasSkia()->
116       drawRoundRect(view_rect,
117                     rounded_view::kCornerRadius - rounded_view::kStrokeWidth,
118                     rounded_view::kCornerRadius - rounded_view::kStrokeWidth,
119                     paint);
120 
121   // Draw outer frame.
122   view_rect.fLeft -= kDelta;
123   view_rect.fTop -= kDelta;
124   view_rect.offset(rounded_view::kStrokeWidth - kDelta,
125                    rounded_view::kStrokeWidth - kDelta);
126   paint.setColor(rounded_view::kOuterFrameColor);
127   canvas->AsCanvasSkia()->drawRoundRect(view_rect, rounded_view::kCornerRadius,
128                                         rounded_view::kCornerRadius, paint);
129 }
130 
131 }
132 
133 #endif  // CHROME_BROWSER_CHROMEOS_LOGIN_ROUNDED_VIEW_H_
134