color_chooser_view.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
1f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// Use of this source code is governed by a BSD-style license that can be 3f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// found in the LICENSE file. 4f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 5f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "ui/views/color_chooser/color_chooser_view.h" 6f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 7f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "base/logging.h" 8f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "base/strings/string_number_conversions.h" 9f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "base/strings/stringprintf.h" 10f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "base/strings/utf_string_conversions.h" 11f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "ui/base/events/event.h" 12f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "ui/base/keycodes/keyboard_codes.h" 13f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "ui/gfx/canvas.h" 14f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "ui/views/background.h" 15f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "ui/views/border.h" 16f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "ui/views/color_chooser/color_chooser_listener.h" 17f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "ui/views/controls/textfield/textfield.h" 18f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "ui/views/controls/textfield/textfield_controller.h" 19f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "ui/views/layout/box_layout.h" 20f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "ui/views/layout/grid_layout.h" 21f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project#include "ui/views/widget/widget.h" 22f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 23f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectnamespace { 24f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 25f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectconst int kHueBarWidth = 20; 26f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectconst int kSaturationValueSize = 200; 27f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectconst int kMarginWidth = 5; 28f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectconst int kSaturationValueIndicatorSize = 6; 29f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectconst int kHueIndicatorSize = 5; 30f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectconst int kBorderWidth = 1; 31f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectconst int kTextfieldLengthInChars = 14; 32f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 33f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectstring16 GetColorText(SkColor color) { 34f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return ASCIIToUTF16(base::StringPrintf("#%02x%02x%02x", 35f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project SkColorGetR(color), 36f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project SkColorGetG(color), 37f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project SkColorGetB(color))); 38f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project} 39f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 40f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectbool GetColorFromText(const string16& text, SkColor* result) { 41f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (text.size() != 6 && !(text.size() == 7 && text[0] == '#')) 42f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return false; 43f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 44f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project std::string input = UTF16ToUTF8((text.size() == 6) ? text : text.substr(1)); 45f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project std::vector<uint8> hex; 46f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (!base::HexStringToBytes(input, &hex)) 47f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return false; 48f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 49f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project *result = SkColorSetRGB(hex[0], hex[1], hex[2]); 50f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return true; 51f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project} 52f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 53f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// A view that processes mouse events and gesture events using a common 54f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// interface. 55f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectclass LocatedEventHandlerView : public views::View { 56f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project public: 57f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual ~LocatedEventHandlerView() {} 58f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 59f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project protected: 60f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project LocatedEventHandlerView() {} 61f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 62f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // Handles an event (mouse or gesture) at the specified location. 63f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual void ProcessEventAtLocation(const gfx::Point& location) = 0; 64f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 65f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // views::View overrides: 66f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE { 67f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project ProcessEventAtLocation(event.location()); 68f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return true; 69f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 70f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 71f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE { 72f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project ProcessEventAtLocation(event.location()); 73f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return true; 74f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 75f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 76f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { 77f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (event->type() == ui::ET_GESTURE_TAP || 78f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project event->type() == ui::ET_GESTURE_TAP_DOWN || 79f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project event->IsScrollGestureEvent()) { 80f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project ProcessEventAtLocation(event->location()); 81f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project event->SetHandled(); 82f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 83f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 84f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 85f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project DISALLOW_COPY_AND_ASSIGN(LocatedEventHandlerView); 86f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project}; 87f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 88f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project} // namespace 89f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 90f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectnamespace views { 91f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 92f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 93f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ColorChooserView::HueView 94f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// 95f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// The class to choose the hue of the color. It draws a vertical bar and 96f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// the indicator for the currently selected hue. 97f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectclass ColorChooserView::HueView : public LocatedEventHandlerView { 98f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project public: 99f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project explicit HueView(ColorChooserView* chooser_view); 100f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 101f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project void OnHueChanged(SkScalar hue); 102f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 103f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private: 104f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // LocatedEventHandlerView overrides: 105f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual void ProcessEventAtLocation(const gfx::Point& point) OVERRIDE; 106f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 107f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // View overrides: 108f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual gfx::Size GetPreferredSize() OVERRIDE; 109f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; 110f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 111f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project ColorChooserView* chooser_view_; 112f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project int level_; 113f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 114f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project DISALLOW_COPY_AND_ASSIGN(HueView); 115f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project}; 116f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 117f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source ProjectColorChooserView::HueView::HueView(ColorChooserView* chooser_view) 118f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project : chooser_view_(chooser_view), 119f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project level_(0) { 120f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project set_focusable(false); 121f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project} 122f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 123f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectvoid ColorChooserView::HueView::OnHueChanged(SkScalar hue) { 124f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project SkScalar height = SkIntToScalar(kSaturationValueSize - 1); 125f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project SkScalar hue_max = SkIntToScalar(360); 126f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project int level = SkScalarDiv(SkScalarMul(hue_max - hue, height), hue_max); 127f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project level += kBorderWidth; 128f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (level_ != level) { 129f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project level_ = level; 130f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project SchedulePaint(); 131f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 132f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project} 133f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 134void ColorChooserView::HueView::ProcessEventAtLocation( 135 const gfx::Point& point) { 136 level_ = std::max(kBorderWidth, 137 std::min(height() - 1 - kBorderWidth, point.y())); 138 int base_height = kSaturationValueSize - 1; 139 chooser_view_->OnHueChosen(SkScalarDiv( 140 SkScalarMul(SkIntToScalar(360), 141 SkIntToScalar(base_height - (level_ - kBorderWidth))), 142 SkIntToScalar(base_height))); 143 SchedulePaint(); 144} 145 146gfx::Size ColorChooserView::HueView::GetPreferredSize() { 147 // We put indicators on the both sides of the hue bar. 148 return gfx::Size(kHueBarWidth + kHueIndicatorSize * 2 + kBorderWidth * 2, 149 kSaturationValueSize + kBorderWidth * 2); 150} 151 152void ColorChooserView::HueView::OnPaint(gfx::Canvas* canvas) { 153 SkScalar hsv[3]; 154 // In the hue bar, saturation and value for the color should be always 100%. 155 hsv[1] = SK_Scalar1; 156 hsv[2] = SK_Scalar1; 157 158 canvas->FillRect(gfx::Rect(kHueIndicatorSize, 0, 159 kHueBarWidth + kBorderWidth, height() - 1), 160 SK_ColorGRAY); 161 int base_left = kHueIndicatorSize + kBorderWidth; 162 for (int y = 0; y < kSaturationValueSize; ++y) { 163 hsv[0] = SkScalarDiv(SkScalarMul(SkIntToScalar(360), 164 SkIntToScalar( 165 kSaturationValueSize - 1 - y)), 166 SkIntToScalar(kSaturationValueSize - 1)); 167 canvas->FillRect(gfx::Rect(base_left, y + kBorderWidth, kHueBarWidth, 1), 168 SkHSVToColor(hsv)); 169 } 170 171 // Put the triangular indicators besides. 172 SkPath left_indicator_path; 173 SkPath right_indicator_path; 174 left_indicator_path.moveTo( 175 SK_ScalarHalf, SkIntToScalar(level_ - kHueIndicatorSize)); 176 left_indicator_path.lineTo( 177 kHueIndicatorSize, SkIntToScalar(level_)); 178 left_indicator_path.lineTo( 179 SK_ScalarHalf, SkIntToScalar(level_ + kHueIndicatorSize)); 180 left_indicator_path.lineTo( 181 SK_ScalarHalf, SkIntToScalar(level_ - kHueIndicatorSize)); 182 right_indicator_path.moveTo( 183 SkIntToScalar(width()) - SK_ScalarHalf, 184 SkIntToScalar(level_ - kHueIndicatorSize)); 185 right_indicator_path.lineTo( 186 SkIntToScalar(width() - kHueIndicatorSize) - SK_ScalarHalf, 187 SkIntToScalar(level_)); 188 right_indicator_path.lineTo( 189 SkIntToScalar(width()) - SK_ScalarHalf, 190 SkIntToScalar(level_ + kHueIndicatorSize)); 191 right_indicator_path.lineTo( 192 SkIntToScalar(width()) - SK_ScalarHalf, 193 SkIntToScalar(level_ - kHueIndicatorSize)); 194 195 SkPaint indicator_paint; 196 indicator_paint.setColor(SK_ColorBLACK); 197 indicator_paint.setStyle(SkPaint::kFill_Style); 198 canvas->DrawPath(left_indicator_path, indicator_paint); 199 canvas->DrawPath(right_indicator_path, indicator_paint); 200} 201 202//////////////////////////////////////////////////////////////////////////////// 203// ColorChooserView::SaturationValueView 204// 205// The class to choose the saturation and the value of the color. It draws 206// a square area and the indicator for the currently selected saturation and 207// value. 208class ColorChooserView::SaturationValueView : public LocatedEventHandlerView { 209 public: 210 explicit SaturationValueView(ColorChooserView* chooser_view); 211 212 void OnHueChanged(SkScalar hue); 213 void OnSaturationValueChanged(SkScalar saturation, SkScalar value); 214 215 private: 216 // LocatedEventHandlerView overrides: 217 virtual void ProcessEventAtLocation(const gfx::Point& point) OVERRIDE; 218 219 // View overrides: 220 virtual gfx::Size GetPreferredSize() OVERRIDE; 221 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; 222 223 ColorChooserView* chooser_view_; 224 SkScalar hue_; 225 gfx::Point marker_position_; 226 227 DISALLOW_COPY_AND_ASSIGN(SaturationValueView); 228}; 229 230ColorChooserView::SaturationValueView::SaturationValueView( 231 ColorChooserView* chooser_view) 232 : chooser_view_(chooser_view), 233 hue_(0) { 234 set_focusable(false); 235 set_border(Border::CreateSolidBorder(kBorderWidth, SK_ColorGRAY)); 236} 237 238void ColorChooserView::SaturationValueView::OnHueChanged(SkScalar hue) { 239 if (hue_ != hue) { 240 hue_ = hue; 241 SchedulePaint(); 242 } 243} 244 245void ColorChooserView::SaturationValueView::OnSaturationValueChanged( 246 SkScalar saturation, 247 SkScalar value) { 248 SkScalar scalar_size = SkIntToScalar(kSaturationValueSize - 1); 249 int x = SkScalarFloorToInt(SkScalarMul(saturation, scalar_size)) + 250 kBorderWidth; 251 int y = SkScalarFloorToInt(SkScalarMul(SK_Scalar1 - value, scalar_size)) + 252 kBorderWidth; 253 if (gfx::Point(x, y) == marker_position_) 254 return; 255 256 marker_position_.set_x(x); 257 marker_position_.set_y(y); 258 SchedulePaint(); 259} 260 261void ColorChooserView::SaturationValueView::ProcessEventAtLocation( 262 const gfx::Point& point) { 263 SkScalar scalar_size = SkIntToScalar(kSaturationValueSize - 1); 264 SkScalar saturation = SkScalarDiv( 265 SkIntToScalar(point.x() - kBorderWidth), scalar_size); 266 SkScalar value = SK_Scalar1 - SkScalarDiv( 267 SkIntToScalar(point.y() - kBorderWidth), scalar_size); 268 saturation = SkScalarPin(saturation, 0, SK_Scalar1); 269 value = SkScalarPin(value, 0, SK_Scalar1); 270 OnSaturationValueChanged(saturation, value); 271 chooser_view_->OnSaturationValueChosen(saturation, value); 272} 273 274gfx::Size ColorChooserView::SaturationValueView::GetPreferredSize() { 275 return gfx::Size(kSaturationValueSize + kBorderWidth * 2, 276 kSaturationValueSize + kBorderWidth * 2); 277} 278 279void ColorChooserView::SaturationValueView::OnPaint(gfx::Canvas* canvas) { 280 SkScalar hsv[3]; 281 hsv[0] = hue_; 282 SkScalar scalar_size = SkIntToScalar(kSaturationValueSize - 1); 283 for (int x = kBorderWidth; x < width() - kBorderWidth; ++x) { 284 hsv[1] = SkScalarDiv(SkIntToScalar(x), scalar_size); 285 for (int y = kBorderWidth; y < height() - kBorderWidth; ++y) { 286 hsv[2] = SK_Scalar1 - SkScalarDiv(SkIntToScalar(y), scalar_size); 287 canvas->FillRect(gfx::Rect(x, y, 1, 1), SkHSVToColor(255, hsv)); 288 } 289 } 290 291 // The background is very dark at the bottom of the view. Use a white 292 // marker in that case. 293 SkColor indicator_color = 294 (marker_position_.y() > width() * 3 / 4) ? SK_ColorWHITE : SK_ColorBLACK; 295 canvas->FillRect( 296 gfx::Rect(marker_position_.x(), 297 marker_position_.y() - kSaturationValueIndicatorSize, 298 1, kSaturationValueIndicatorSize * 2 + 1), 299 indicator_color); 300 canvas->FillRect( 301 gfx::Rect(marker_position_.x() - kSaturationValueIndicatorSize, 302 marker_position_.y(), 303 kSaturationValueIndicatorSize * 2 + 1, 1), 304 indicator_color); 305 OnPaintBorder(canvas); 306} 307 308//////////////////////////////////////////////////////////////////////////////// 309// ColorChooserView::SelectedColorPatchView 310// 311// A view to simply show the selected color in a rectangle. 312class ColorChooserView::SelectedColorPatchView : public views::View { 313 public: 314 SelectedColorPatchView(); 315 316 void SetColor(SkColor color); 317 318 private: 319 DISALLOW_COPY_AND_ASSIGN(SelectedColorPatchView); 320}; 321 322ColorChooserView::SelectedColorPatchView::SelectedColorPatchView() { 323 set_focusable(false); 324 SetVisible(true); 325 set_border(Border::CreateSolidBorder(kBorderWidth, SK_ColorGRAY)); 326} 327 328void ColorChooserView::SelectedColorPatchView::SetColor(SkColor color) { 329 if (!background()) 330 set_background(Background::CreateSolidBackground(color)); 331 else 332 background()->SetNativeControlColor(color); 333 SchedulePaint(); 334} 335 336//////////////////////////////////////////////////////////////////////////////// 337// ColorChooserView 338// 339 340ColorChooserView::ColorChooserView(ColorChooserListener* listener, 341 SkColor initial_color) 342 : listener_(listener) { 343 DCHECK(listener_); 344 345 set_focusable(false); 346 set_background(Background::CreateSolidBackground(SK_ColorLTGRAY)); 347 SetLayoutManager(new BoxLayout(BoxLayout::kVertical, kMarginWidth, 348 kMarginWidth, kMarginWidth)); 349 350 View* container = new View(); 351 container->SetLayoutManager(new BoxLayout(BoxLayout::kHorizontal, 0, 0, 352 kMarginWidth)); 353 saturation_value_ = new SaturationValueView(this); 354 container->AddChildView(saturation_value_); 355 hue_ = new HueView(this); 356 container->AddChildView(hue_); 357 AddChildView(container); 358 359 View* container2 = new View(); 360 GridLayout* layout = new GridLayout(container2); 361 container2->SetLayoutManager(layout); 362 ColumnSet* columns = layout->AddColumnSet(0); 363 columns->AddColumn( 364 GridLayout::LEADING, GridLayout::FILL, 0, GridLayout::USE_PREF, 0, 0); 365 columns->AddPaddingColumn(0, kMarginWidth); 366 columns->AddColumn( 367 GridLayout::FILL, GridLayout::FILL, 1, GridLayout::USE_PREF, 0, 0); 368 layout->StartRow(0, 0); 369 textfield_ = new Textfield(); 370 textfield_->SetController(this); 371 textfield_->set_default_width_in_chars(kTextfieldLengthInChars); 372 layout->AddView(textfield_); 373 selected_color_patch_ = new SelectedColorPatchView(); 374 layout->AddView(selected_color_patch_); 375 AddChildView(container2); 376 377 OnColorChanged(initial_color); 378} 379 380ColorChooserView::~ColorChooserView() { 381} 382 383void ColorChooserView::OnColorChanged(SkColor color) { 384 SkColorToHSV(color, hsv_); 385 hue_->OnHueChanged(hsv_[0]); 386 saturation_value_->OnHueChanged(hsv_[0]); 387 saturation_value_->OnSaturationValueChanged(hsv_[1], hsv_[2]); 388 selected_color_patch_->SetColor(color); 389 textfield_->SetText(GetColorText(color)); 390} 391 392void ColorChooserView::OnHueChosen(SkScalar hue) { 393 hsv_[0] = hue; 394 SkColor color = SkHSVToColor(255, hsv_); 395 if (listener_) 396 listener_->OnColorChosen(color); 397 saturation_value_->OnHueChanged(hue); 398 selected_color_patch_->SetColor(color); 399 textfield_->SetText(GetColorText(color)); 400} 401 402void ColorChooserView::OnSaturationValueChosen(SkScalar saturation, 403 SkScalar value) { 404 hsv_[1] = saturation; 405 hsv_[2] = value; 406 SkColor color = SkHSVToColor(255, hsv_); 407 if (listener_) 408 listener_->OnColorChosen(color); 409 selected_color_patch_->SetColor(color); 410 textfield_->SetText(GetColorText(color)); 411} 412 413View* ColorChooserView::GetInitiallyFocusedView() { 414 return textfield_; 415} 416 417ui::ModalType ColorChooserView::GetModalType() const { 418 return ui::MODAL_TYPE_WINDOW; 419} 420 421void ColorChooserView::WindowClosing() { 422 if (listener_) 423 listener_->OnColorChooserDialogClosed(); 424} 425 426View* ColorChooserView::GetContentsView() { 427 return this; 428} 429 430void ColorChooserView::ContentsChanged(Textfield* sender, 431 const string16& new_contents) { 432 SkColor color = SK_ColorBLACK; 433 if (GetColorFromText(new_contents, &color)) { 434 SkColorToHSV(color, hsv_); 435 if (listener_) 436 listener_->OnColorChosen(color); 437 hue_->OnHueChanged(hsv_[0]); 438 saturation_value_->OnHueChanged(hsv_[0]); 439 saturation_value_->OnSaturationValueChanged(hsv_[1], hsv_[2]); 440 selected_color_patch_->SetColor(color); 441 } 442} 443 444bool ColorChooserView::HandleKeyEvent(Textfield* sender, 445 const ui::KeyEvent& key_event) { 446 if (key_event.key_code() != ui::VKEY_RETURN && 447 key_event.key_code() != ui::VKEY_ESCAPE) 448 return false; 449 450 GetWidget()->Close(); 451 return true; 452} 453 454} // namespace views 455