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