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
12namespace chromeos {
13
14namespace rounded_view {
15
16// Corner radius of the RoundedView.
17const SkScalar kCornerRadius = SkIntToScalar(5);
18
19// Stroke width to be used by the RoundedView.
20const SkScalar kStrokeWidth = SkIntToScalar(1);
21
22// Color of the inner frame of the RoundedView.
23const SkColor kInnerFrameColor = SK_ColorWHITE;
24
25// Color of the outer frame of the RoundedView.
26const 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|.
32template<typename C>
33class RoundedView: public C {
34 public:
35  // Empty constructor.
36  RoundedView() {}
37
38  // Constructors.
39  template<typename D>
40  explicit RoundedView(const D &value) : C(value) {}
41  template<typename D1, typename D2>
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
60template <typename C>
61void 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
72template <typename C>
73SkPath 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
88template <typename C>
89SkRect 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
98template <typename C>
99void 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