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. 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 60 template <typename C> 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> 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> 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> 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