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