|  |  | 
|  | /* | 
|  | * Copyright 2011 Google Inc. | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  | #include "SkView.h" | 
|  | #include "SkCanvas.h" | 
|  | #include "SkPaint.h" | 
|  | #include "SkGradientShader.h" | 
|  | #include "SkColorPalette.h" | 
|  |  | 
|  | SkColorPalette::SkColorPalette() { | 
|  | fSlotRect = SkRect::MakeWH(SkIntToScalar(50), SkIntToScalar(20)); | 
|  | fGradientRect = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100)); | 
|  | fSelected = 0; | 
|  | fCurrColor = 0xFF000000; | 
|  |  | 
|  | fColors[0] = SK_ColorWHITE; | 
|  | fColors[1] = SK_ColorBLACK; | 
|  | fColors[2] = SK_ColorRED; | 
|  | fColors[3] = SK_ColorGREEN; | 
|  | fColors[4] = SK_ColorBLUE; | 
|  | } | 
|  |  | 
|  | bool SkColorPalette::onEvent(const SkEvent& evt) { | 
|  | return this->INHERITED::onEvent(evt); | 
|  | } | 
|  |  | 
|  | void SkColorPalette::onDraw(SkCanvas* canvas) { | 
|  | canvas->drawColor(SK_ColorWHITE); | 
|  |  | 
|  | SkPaint paint; | 
|  | paint.setAntiAlias(true); | 
|  |  | 
|  | canvas->translate(PalettePadding, PalettePadding); | 
|  |  | 
|  | for (int i = 0; i < PaletteSlots; ++i) { | 
|  | if (fSelected == i) { | 
|  | paint.setStrokeWidth(SkIntToScalar(3)); | 
|  | } | 
|  | else { | 
|  | paint.setStrokeWidth(1); | 
|  | } | 
|  |  | 
|  | paint.setStyle(SkPaint::kStroke_Style); | 
|  | paint.setColor(SK_ColorBLACK); | 
|  | canvas->drawRect(fSlotRect, paint); | 
|  | paint.setStyle(SkPaint::kFill_Style); | 
|  | paint.setColor(fColors[i]); | 
|  | canvas->drawRect(fSlotRect, paint); | 
|  | canvas->translate(0, fSlotRect.height() + PalettePadding); | 
|  | } | 
|  | paint.setStrokeWidth(0); | 
|  | canvas->translate(0, PalettePadding); | 
|  | SkPoint p = SkPoint::Make(0,0); | 
|  | SkPoint q = SkPoint::Make(this->width(), 0); | 
|  | SkPoint pts[] = {p, q}; | 
|  |  | 
|  | SkColor colors[] = { SK_ColorRED, SK_ColorYELLOW, SK_ColorGREEN, | 
|  | SK_ColorCYAN, SK_ColorBLUE, SK_ColorMAGENTA,SK_ColorRED}; | 
|  | SkScalar colorPositions[] = { 0, 0.2, 0.4, 0.5, 0.6, 0.8, 1.0}; | 
|  |  | 
|  |  | 
|  | SkShader* shader1 = SkGradientShader::CreateLinear(pts, colors, colorPositions,7, | 
|  | SkShader::kMirror_TileMode); | 
|  | paint.setShader(shader1)->unref(); | 
|  |  | 
|  | canvas->drawRect(fGradientRect, paint); | 
|  |  | 
|  | //this->INHERITED::onDraw(canvas); | 
|  | } | 
|  |  | 
|  | SkView::Click* SkColorPalette::onFindClickHandler(SkScalar x, SkScalar y) { | 
|  | return new Click(this); | 
|  | } | 
|  |  | 
|  | bool SkColorPalette::onClick(SkView::Click* click) { | 
|  | SkPoint curr = click->fCurr; | 
|  | //SkDebugf("click %f %f \n", curr.fX, curr.fY); | 
|  | int selected = selectSlot(curr); | 
|  | if (selected >= 0) { | 
|  | switch (click->fState) { | 
|  | case SkView::Click::kDown_State: | 
|  | case SkView::Click::kMoved_State: | 
|  | case SkView::Click::kUp_State: | 
|  | fSelected = selected; | 
|  | fCurrColor = fColors[fSelected]; | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  | return true; | 
|  | } | 
|  | else{ | 
|  | //account for padding | 
|  | curr.fX -= PalettePadding; | 
|  | curr.fY -= 2 * PalettePadding + (fSlotRect.height() + PalettePadding) * PaletteSlots; | 
|  | if (curr.fX < 0 || curr.fX > fGradientRect.width() || | 
|  | curr.fY < 0 || curr.fY > fGradientRect.height()) { | 
|  | return false; | 
|  | } | 
|  | else { | 
|  | switch (click->fState) { | 
|  | case SkView::Click::kDown_State: | 
|  | case SkView::Click::kMoved_State: | 
|  | case SkView::Click::kUp_State: | 
|  | fColors[fSelected] = selectColorFromGradient(curr); | 
|  | fCurrColor = fColors[fSelected]; | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  | return true; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void SkColorPalette::onSizeChange() { | 
|  | fGradientRect = SkRect::MakeWH(this->width() - 2*PalettePadding, | 
|  | this->width() - 2*PalettePadding); | 
|  | this->INHERITED::onSizeChange(); | 
|  | } | 
|  |  | 
|  | int SkColorPalette::selectSlot(SkPoint& cursorPosition) { | 
|  | //account for padding | 
|  | cursorPosition.fX -= PalettePadding; | 
|  | cursorPosition.fY -= PalettePadding; | 
|  |  | 
|  | if (cursorPosition.fX < 0 || cursorPosition.fX > fSlotRect.width() || | 
|  | cursorPosition.fY < 0 || cursorPosition.fY > (fSlotRect.height() + PalettePadding) * PaletteSlots) { | 
|  | return -1; | 
|  | } | 
|  | int index = cursorPosition.fY/(fSlotRect.height() + PalettePadding); | 
|  | int offset = (int)cursorPosition.fY%((int)fSlotRect.height() + PalettePadding); | 
|  | if (offset <= fSlotRect.height()) { | 
|  | return index; | 
|  | } | 
|  | else { | 
|  | return -1; | 
|  | } | 
|  | } | 
|  |  | 
|  | SkColor SkColorPalette::selectColorFromGradient(SkPoint& cursorPosition) { | 
|  | float h = cursorPosition.fX/fGradientRect.width(); | 
|  | float s = 1.0 - cursorPosition.fY/fGradientRect.height(); | 
|  | float v = 1.0; | 
|  | float _h,r,g,b; | 
|  | float _1, _2, _3; | 
|  | int _i; | 
|  |  | 
|  | _h = h * 6; | 
|  | _i = (int)_h; | 
|  | _1 = v * (1 - s); | 
|  | _2 = v * (1 - s * (_h - _i)); | 
|  | _3 = v * (1 - s * (1 - (_h - _i))); | 
|  |  | 
|  | if (_i == 0) { | 
|  | r = v; | 
|  | g = _3; | 
|  | b = _1; | 
|  | } | 
|  | else if (_i == 1) { | 
|  | r = _2; | 
|  | g = v; | 
|  | b = _1; | 
|  | } | 
|  | else if (_i == 2) { | 
|  | r = _1; | 
|  | g = v; | 
|  | b = _3; | 
|  | } | 
|  | else if (_i == 3) { | 
|  | r = _1; | 
|  | g = _2; | 
|  | b = v; | 
|  | } | 
|  | else if (_i == 4) { | 
|  | r = _3; | 
|  | g = _1; | 
|  | b = v; | 
|  | } | 
|  | else { | 
|  | r = v; | 
|  | g = _1; | 
|  | b = _2; | 
|  | }; | 
|  |  | 
|  | SkColor retval = 0xFF000000; | 
|  | retval += ((int)(r * 255) << 16); | 
|  | retval += ((int)(g * 255) << 8); | 
|  | retval += (int)(b * 255); | 
|  | return retval; | 
|  | } |