15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/color_chooser/color_chooser_view.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
95e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "skia/ext/refptr.h"
128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "third_party/skia/include/effects/SkGradientShader.h"
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/keycodes/keyboard_codes.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/background.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/border.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/color_chooser/color_chooser_listener.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/textfield/textfield.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/textfield/textfield_controller.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/box_layout.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/grid_layout.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kHueBarWidth = 20;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kSaturationValueSize = 200;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMarginWidth = 5;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kSaturationValueIndicatorSize = 6;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kHueIndicatorSize = 5;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBorderWidth = 1;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTextfieldLengthInChars = 14;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 GetColorText(SkColor color) {
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::ASCIIToUTF16(base::StringPrintf("#%02x%02x%02x",
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                               SkColorGetR(color),
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                               SkColorGetG(color),
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                               SkColorGetB(color)));
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool GetColorFromText(const base::string16& text, SkColor* result) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (text.size() != 6 && !(text.size() == 7 && text[0] == '#'))
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string input =
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::UTF16ToUTF8((text.size() == 6) ? text : text.substr(1));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<uint8> hex;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!base::HexStringToBytes(input, &hex))
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *result = SkColorSetRGB(hex[0], hex[1], hex[2]);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A view that processes mouse events and gesture events using a common
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// interface.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LocatedEventHandlerView : public views::View {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~LocatedEventHandlerView() {}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LocatedEventHandlerView() {}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles an event (mouse or gesture) at the specified location.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ProcessEventAtLocation(const gfx::Point& location) = 0;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::View overrides:
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProcessEventAtLocation(event.location());
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProcessEventAtLocation(event.location());
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->type() == ui::ET_GESTURE_TAP ||
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        event->type() == ui::ET_GESTURE_TAP_DOWN ||
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        event->IsScrollGestureEvent()) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProcessEventAtLocation(event->location());
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event->SetHandled();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LocatedEventHandlerView);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DrawGradientRect(const gfx::Rect& rect, SkColor start_color,
928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                      SkColor end_color, bool is_horizontal,
938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                      gfx::Canvas* canvas) {
948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  SkColor colors[2] = { start_color, end_color };
958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  SkPoint points[2];
968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  points[0].iset(0, 0);
978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (is_horizontal)
988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    points[1].iset(rect.width() + 1, 0);
998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  else
1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    points[1].iset(0, rect.height() + 1);
1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  skia::RefPtr<SkShader> shader(skia::AdoptRef(
1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      SkGradientShader::CreateLinear(points, colors, NULL, 2,
1038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                     SkShader::kClamp_TileMode)));
1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  SkPaint paint;
1058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  paint.setShader(shader.get());
1068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  canvas->DrawRect(rect, paint);
1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ColorChooserView::HueView
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The class to choose the hue of the color.  It draws a vertical bar and
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the indicator for the currently selected hue.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ColorChooserView::HueView : public LocatedEventHandlerView {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit HueView(ColorChooserView* chooser_view);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnHueChanged(SkScalar hue);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // LocatedEventHandlerView overrides:
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ProcessEventAtLocation(const gfx::Point& point) OVERRIDE;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // View overrides:
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual gfx::Size GetPreferredSize() const OVERRIDE;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ColorChooserView* chooser_view_;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int level_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HueView);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ColorChooserView::HueView::HueView(ColorChooserView* chooser_view)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : chooser_view_(chooser_view),
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      level_(0) {
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetFocusable(false);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserView::HueView::OnHueChanged(SkScalar hue) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar height = SkIntToScalar(kSaturationValueSize - 1);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar hue_max = SkIntToScalar(360);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int level = SkScalarDiv(SkScalarMul(hue_max - hue, height), hue_max);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  level += kBorderWidth;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (level_ != level) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    level_ = level;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SchedulePaint();
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserView::HueView::ProcessEventAtLocation(
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Point& point) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  level_ = std::max(kBorderWidth,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    std::min(height() - 1 - kBorderWidth, point.y()));
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int base_height = kSaturationValueSize - 1;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chooser_view_->OnHueChosen(SkScalarDiv(
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkScalarMul(SkIntToScalar(360),
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  SkIntToScalar(base_height - (level_ - kBorderWidth))),
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkIntToScalar(base_height)));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SchedulePaint();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size ColorChooserView::HueView::GetPreferredSize() const {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We put indicators on the both sides of the hue bar.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size(kHueBarWidth + kHueIndicatorSize * 2 + kBorderWidth * 2,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   kSaturationValueSize + kBorderWidth * 2);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserView::HueView::OnPaint(gfx::Canvas* canvas) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar hsv[3];
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In the hue bar, saturation and value for the color should be always 100%.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hsv[1] = SK_Scalar1;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hsv[2] = SK_Scalar1;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->FillRect(gfx::Rect(kHueIndicatorSize, 0,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             kHueBarWidth + kBorderWidth, height() - 1),
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SK_ColorGRAY);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int base_left = kHueIndicatorSize + kBorderWidth;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int y = 0; y < kSaturationValueSize; ++y) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hsv[0] = SkScalarDiv(SkScalarMul(SkIntToScalar(360),
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     SkIntToScalar(
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         kSaturationValueSize - 1 - y)),
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SkIntToScalar(kSaturationValueSize - 1));
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->FillRect(gfx::Rect(base_left, y + kBorderWidth, kHueBarWidth, 1),
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     SkHSVToColor(hsv));
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Put the triangular indicators besides.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPath left_indicator_path;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPath right_indicator_path;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  left_indicator_path.moveTo(
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SK_ScalarHalf, SkIntToScalar(level_ - kHueIndicatorSize));
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  left_indicator_path.lineTo(
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kHueIndicatorSize, SkIntToScalar(level_));
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  left_indicator_path.lineTo(
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SK_ScalarHalf, SkIntToScalar(level_ + kHueIndicatorSize));
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  left_indicator_path.lineTo(
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SK_ScalarHalf, SkIntToScalar(level_ - kHueIndicatorSize));
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  right_indicator_path.moveTo(
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkIntToScalar(width()) - SK_ScalarHalf,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkIntToScalar(level_ - kHueIndicatorSize));
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  right_indicator_path.lineTo(
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkIntToScalar(width() - kHueIndicatorSize) - SK_ScalarHalf,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkIntToScalar(level_));
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  right_indicator_path.lineTo(
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkIntToScalar(width()) - SK_ScalarHalf,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkIntToScalar(level_ + kHueIndicatorSize));
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  right_indicator_path.lineTo(
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkIntToScalar(width()) - SK_ScalarHalf,
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkIntToScalar(level_ - kHueIndicatorSize));
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint indicator_paint;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  indicator_paint.setColor(SK_ColorBLACK);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  indicator_paint.setStyle(SkPaint::kFill_Style);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->DrawPath(left_indicator_path, indicator_paint);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->DrawPath(right_indicator_path, indicator_paint);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ColorChooserView::SaturationValueView
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The class to choose the saturation and the value of the color.  It draws
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a square area and the indicator for the currently selected saturation and
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// value.
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ColorChooserView::SaturationValueView : public LocatedEventHandlerView {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit SaturationValueView(ColorChooserView* chooser_view);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnHueChanged(SkScalar hue);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnSaturationValueChanged(SkScalar saturation, SkScalar value);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // LocatedEventHandlerView overrides:
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ProcessEventAtLocation(const gfx::Point& point) OVERRIDE;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // View overrides:
241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual gfx::Size GetPreferredSize() const OVERRIDE;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ColorChooserView* chooser_view_;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar hue_;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point marker_position_;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SaturationValueView);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ColorChooserView::SaturationValueView::SaturationValueView(
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ColorChooserView* chooser_view)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : chooser_view_(chooser_view),
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hue_(0) {
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetFocusable(false);
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetBorder(Border::CreateSolidBorder(kBorderWidth, SK_ColorGRAY));
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserView::SaturationValueView::OnHueChanged(SkScalar hue) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (hue_ != hue) {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hue_ = hue;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SchedulePaint();
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserView::SaturationValueView::OnSaturationValueChanged(
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkScalar saturation,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkScalar value) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar scalar_size = SkIntToScalar(kSaturationValueSize - 1);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int x = SkScalarFloorToInt(SkScalarMul(saturation, scalar_size)) +
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kBorderWidth;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int y = SkScalarFloorToInt(SkScalarMul(SK_Scalar1 - value, scalar_size)) +
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kBorderWidth;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (gfx::Point(x, y) == marker_position_)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  marker_position_.set_x(x);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  marker_position_.set_y(y);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SchedulePaint();
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserView::SaturationValueView::ProcessEventAtLocation(
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Point& point) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar scalar_size = SkIntToScalar(kSaturationValueSize - 1);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar saturation = SkScalarDiv(
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkIntToScalar(point.x() - kBorderWidth), scalar_size);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar value = SK_Scalar1 - SkScalarDiv(
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkIntToScalar(point.y() - kBorderWidth), scalar_size);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  saturation = SkScalarPin(saturation, 0, SK_Scalar1);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  value = SkScalarPin(value, 0, SK_Scalar1);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnSaturationValueChanged(saturation, value);
2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  chooser_view_->OnSaturationValueChosen(saturation, value);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size ColorChooserView::SaturationValueView::GetPreferredSize() const {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size(kSaturationValueSize + kBorderWidth * 2,
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   kSaturationValueSize + kBorderWidth * 2);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserView::SaturationValueView::OnPaint(gfx::Canvas* canvas) {
3018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  gfx::Rect color_bounds = bounds();
3028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  color_bounds.Inset(GetInsets());
3038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Paints horizontal gradient first for saturation.
3058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  SkScalar hsv[3] = { hue_, SK_Scalar1, SK_Scalar1 };
3068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  SkScalar left_hsv[3] = { hue_, 0, SK_Scalar1 };
3078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DrawGradientRect(color_bounds, SkHSVToColor(255, left_hsv),
3088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                   SkHSVToColor(255, hsv), true /* is_horizontal */, canvas);
3098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Overlays vertical gradient for value.
3118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  SkScalar hsv_bottom[3] = { 0, SK_Scalar1, 0 };
3128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DrawGradientRect(color_bounds, SK_ColorTRANSPARENT,
3138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                   SkHSVToColor(255, hsv_bottom), false /* is_horizontal */,
3148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                   canvas);
3158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Draw the crosshair marker.
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The background is very dark at the bottom of the view.  Use a white
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // marker in that case.
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor indicator_color =
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (marker_position_.y() > width() * 3 / 4) ? SK_ColorWHITE : SK_ColorBLACK;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->FillRect(
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Rect(marker_position_.x(),
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                marker_position_.y() - kSaturationValueIndicatorSize,
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                1, kSaturationValueIndicatorSize * 2 + 1),
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      indicator_color);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->FillRect(
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Rect(marker_position_.x() - kSaturationValueIndicatorSize,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                marker_position_.y(),
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                kSaturationValueIndicatorSize * 2 + 1, 1),
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      indicator_color);
3318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnPaintBorder(canvas);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ColorChooserView::SelectedColorPatchView
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A view to simply show the selected color in a rectangle.
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ColorChooserView::SelectedColorPatchView : public views::View {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SelectedColorPatchView();
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetColor(SkColor color);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SelectedColorPatchView);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ColorChooserView::SelectedColorPatchView::SelectedColorPatchView() {
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetFocusable(false);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetVisible(true);
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetBorder(Border::CreateSolidBorder(kBorderWidth, SK_ColorGRAY));
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserView::SelectedColorPatchView::SetColor(SkColor color) {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!background())
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set_background(Background::CreateSolidBackground(color));
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    background()->SetNativeControlColor(color);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SchedulePaint();
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ColorChooserView
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ColorChooserView::ColorChooserView(ColorChooserListener* listener,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   SkColor initial_color)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : listener_(listener) {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(listener_);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetFocusable(false);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_background(Background::CreateSolidBackground(SK_ColorLTGRAY));
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetLayoutManager(new BoxLayout(BoxLayout::kVertical, kMarginWidth,
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 kMarginWidth, kMarginWidth));
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View* container = new View();
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container->SetLayoutManager(new BoxLayout(BoxLayout::kHorizontal, 0, 0,
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            kMarginWidth));
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  saturation_value_ = new SaturationValueView(this);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container->AddChildView(saturation_value_);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hue_ = new HueView(this);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container->AddChildView(hue_);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddChildView(container);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View* container2 = new View();
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GridLayout* layout = new GridLayout(container2);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container2->SetLayoutManager(layout);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ColumnSet* columns = layout->AddColumnSet(0);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns->AddColumn(
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GridLayout::LEADING, GridLayout::FILL, 0, GridLayout::USE_PREF, 0, 0);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns->AddPaddingColumn(0, kMarginWidth);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns->AddColumn(
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GridLayout::FILL, GridLayout::FILL, 1, GridLayout::USE_PREF, 0, 0);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->StartRow(0, 0);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  textfield_ = new Textfield();
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  textfield_->set_controller(this);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  textfield_->set_default_width_in_chars(kTextfieldLengthInChars);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddView(textfield_);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  selected_color_patch_ = new SelectedColorPatchView();
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddView(selected_color_patch_);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddChildView(container2);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnColorChanged(initial_color);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ColorChooserView::~ColorChooserView() {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserView::OnColorChanged(SkColor color) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(color, hsv_);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hue_->OnHueChanged(hsv_[0]);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  saturation_value_->OnHueChanged(hsv_[0]);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  saturation_value_->OnSaturationValueChanged(hsv_[1], hsv_[2]);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  selected_color_patch_->SetColor(color);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  textfield_->SetText(GetColorText(color));
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserView::OnHueChosen(SkScalar hue) {
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hsv_[0] = hue;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor color = SkHSVToColor(255, hsv_);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (listener_)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listener_->OnColorChosen(color);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  saturation_value_->OnHueChanged(hue);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  selected_color_patch_->SetColor(color);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  textfield_->SetText(GetColorText(color));
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserView::OnSaturationValueChosen(SkScalar saturation,
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               SkScalar value) {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hsv_[1] = saturation;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hsv_[2] = value;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor color = SkHSVToColor(255, hsv_);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (listener_)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listener_->OnColorChosen(color);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  selected_color_patch_->SetColor(color);
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  textfield_->SetText(GetColorText(color));
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ColorChooserView::CanMinimize() const {
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return false;
4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)View* ColorChooserView::GetInitiallyFocusedView() {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return textfield_;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::ModalType ColorChooserView::GetModalType() const {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ui::MODAL_TYPE_WINDOW;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserView::WindowClosing() {
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (listener_)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listener_->OnColorChooserDialogClosed();
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)View* ColorChooserView::GetContentsView() {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ColorChooserView::ContentsChanged(Textfield* sender,
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       const base::string16& new_contents) {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor color = SK_ColorBLACK;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetColorFromText(new_contents, &color)) {
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorToHSV(color, hsv_);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (listener_)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      listener_->OnColorChosen(color);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hue_->OnHueChanged(hsv_[0]);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    saturation_value_->OnHueChanged(hsv_[0]);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    saturation_value_->OnSaturationValueChanged(hsv_[1], hsv_[2]);
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    selected_color_patch_->SetColor(color);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ColorChooserView::HandleKeyEvent(Textfield* sender,
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const ui::KeyEvent& key_event) {
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (key_event.key_code() != ui::VKEY_RETURN &&
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      key_event.key_code() != ui::VKEY_ESCAPE)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetWidget()->Close();
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
486