1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#include "SkView.h"
9#include "SkCanvas.h"
10#include "SkPaint.h"
11#include "SkGradientShader.h"
12#include "SkColorPalette.h"
13
14SkColorPalette::SkColorPalette() {
15    fSlotRect = SkRect::MakeWH(SkIntToScalar(50), SkIntToScalar(20));
16    fGradientRect = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100));
17    fSelected = 0;
18    fCurrColor = 0xFF000000;
19
20    fColors[0] = SK_ColorWHITE;
21    fColors[1] = SK_ColorBLACK;
22    fColors[2] = SK_ColorRED;
23    fColors[3] = SK_ColorGREEN;
24    fColors[4] = SK_ColorBLUE;
25}
26
27bool SkColorPalette::onEvent(const SkEvent& evt) {
28    return this->INHERITED::onEvent(evt);
29}
30
31void SkColorPalette::onDraw(SkCanvas* canvas) {
32    canvas->drawColor(SK_ColorWHITE);
33
34    SkPaint paint;
35    paint.setAntiAlias(true);
36
37    canvas->translate(PalettePadding, PalettePadding);
38
39    for (int i = 0; i < PaletteSlots; ++i) {
40        if (fSelected == i) {
41            paint.setStrokeWidth(SkIntToScalar(3));
42        }
43        else {
44            paint.setStrokeWidth(1);
45        }
46
47        paint.setStyle(SkPaint::kStroke_Style);
48        paint.setColor(SK_ColorBLACK);
49        canvas->drawRect(fSlotRect, paint);
50        paint.setStyle(SkPaint::kFill_Style);
51        paint.setColor(fColors[i]);
52        canvas->drawRect(fSlotRect, paint);
53        canvas->translate(0, fSlotRect.height() + PalettePadding);
54    }
55    paint.setStrokeWidth(0);
56    canvas->translate(0, PalettePadding);
57    SkPoint p = SkPoint::Make(0,0);
58    SkPoint q = SkPoint::Make(this->width(), 0);
59    SkPoint pts[] = {p, q};
60
61    SkColor colors[] = { SK_ColorRED, SK_ColorYELLOW, SK_ColorGREEN,
62        SK_ColorCYAN, SK_ColorBLUE, SK_ColorMAGENTA,SK_ColorRED};
63    SkScalar colorPositions[] = { 0, 0.2, 0.4, 0.5, 0.6, 0.8, 1.0};
64
65
66    SkShader* shader1 = SkGradientShader::CreateLinear(pts, colors, colorPositions,7,
67                                                       SkShader::kMirror_TileMode);
68    paint.setShader(shader1)->unref();
69
70    canvas->drawRect(fGradientRect, paint);
71
72    //this->INHERITED::onDraw(canvas);
73}
74
75SkView::Click* SkColorPalette::onFindClickHandler(SkScalar x, SkScalar y) {
76    return new Click(this);
77}
78
79bool SkColorPalette::onClick(SkView::Click* click) {
80    SkPoint curr = click->fCurr;
81    //SkDebugf("click %f %f \n", curr.fX, curr.fY);
82    int selected = selectSlot(curr);
83    if (selected >= 0) {
84        switch (click->fState) {
85            case SkView::Click::kDown_State:
86            case SkView::Click::kMoved_State:
87            case SkView::Click::kUp_State:
88                fSelected = selected;
89                fCurrColor = fColors[fSelected];
90                break;
91            default:
92                break;
93        }
94        return true;
95    }
96    else{
97        //account for padding
98        curr.fX -= PalettePadding;
99        curr.fY -= 2 * PalettePadding + (fSlotRect.height() + PalettePadding) * PaletteSlots;
100        if (curr.fX < 0 || curr.fX > fGradientRect.width() ||
101            curr.fY < 0 || curr.fY > fGradientRect.height()) {
102            return false;
103        }
104        else {
105            switch (click->fState) {
106                case SkView::Click::kDown_State:
107                case SkView::Click::kMoved_State:
108                case SkView::Click::kUp_State:
109                    fColors[fSelected] = selectColorFromGradient(curr);
110                    fCurrColor = fColors[fSelected];
111                    break;
112                default:
113                    break;
114            }
115            return true;
116        }
117    }
118}
119
120void SkColorPalette::onSizeChange() {
121    fGradientRect = SkRect::MakeWH(this->width() - 2*PalettePadding,
122                                   this->width() - 2*PalettePadding);
123    this->INHERITED::onSizeChange();
124}
125
126int SkColorPalette::selectSlot(SkPoint& cursorPosition) {
127    //account for padding
128    cursorPosition.fX -= PalettePadding;
129    cursorPosition.fY -= PalettePadding;
130
131    if (cursorPosition.fX < 0 || cursorPosition.fX > fSlotRect.width() ||
132        cursorPosition.fY < 0 || cursorPosition.fY > (fSlotRect.height() + PalettePadding) * PaletteSlots) {
133        return -1;
134    }
135    int index = cursorPosition.fY/(fSlotRect.height() + PalettePadding);
136    int offset = (int)cursorPosition.fY%((int)fSlotRect.height() + PalettePadding);
137    if (offset <= fSlotRect.height()) {
138        return index;
139    }
140    else {
141        return -1;
142    }
143}
144
145SkColor SkColorPalette::selectColorFromGradient(SkPoint& cursorPosition) {
146    float h = cursorPosition.fX/fGradientRect.width();
147    float s = 1.0 - cursorPosition.fY/fGradientRect.height();
148    float v = 1.0;
149    float _h,r,g,b;
150    float _1, _2, _3;
151    int _i;
152
153    _h = h * 6;
154    _i = (int)_h;
155    _1 = v * (1 - s);
156    _2 = v * (1 - s * (_h - _i));
157    _3 = v * (1 - s * (1 - (_h - _i)));
158
159    if (_i == 0) {
160        r = v;
161        g = _3;
162        b = _1;
163    }
164    else if (_i == 1) {
165        r = _2;
166        g = v;
167        b = _1;
168    }
169    else if (_i == 2) {
170        r = _1;
171        g = v;
172        b = _3;
173    }
174    else if (_i == 3) {
175        r = _1;
176        g = _2;
177        b = v;
178    }
179    else if (_i == 4) {
180        r = _3;
181        g = _1;
182        b = v;
183    }
184    else {
185        r = v;
186        g = _1;
187        b = _2;
188    };
189
190    SkColor retval = 0xFF000000;
191    retval += ((int)(r * 255) << 16);
192    retval += ((int)(g * 255) << 8);
193    retval += (int)(b * 255);
194    return retval;
195}
196