Home | History | Annotate | Download | only in login
      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