gfx/skia/trunk/src/views/SkWidgets.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1
michael@0 2 /*
michael@0 3 * Copyright 2011 Google Inc.
michael@0 4 *
michael@0 5 * Use of this source code is governed by a BSD-style license that can be
michael@0 6 * found in the LICENSE file.
michael@0 7 */
michael@0 8 #include "SkWidget.h"
michael@0 9 #include "SkCanvas.h"
michael@0 10 #include "SkKey.h"
michael@0 11 #include "SkParsePaint.h"
michael@0 12 #include "SkSystemEventTypes.h"
michael@0 13 #include "SkTextBox.h"
michael@0 14
michael@0 15 #if 0
michael@0 16
michael@0 17 #ifdef SK_DEBUG
michael@0 18 static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[])
michael@0 19 {
michael@0 20 const char* value = dom.findAttr(node, attr);
michael@0 21 if (value)
michael@0 22 SkDebugf("unknown attribute %s=\"%s\"\n", attr, value);
michael@0 23 }
michael@0 24 #else
michael@0 25 #define assert_no_attr(dom, node, attr)
michael@0 26 #endif
michael@0 27
michael@0 28 #include "SkAnimator.h"
michael@0 29 #include "SkTime.h"
michael@0 30
michael@0 31 ///////////////////////////////////////////////////////////////////////////////
michael@0 32
michael@0 33 enum SkinType {
michael@0 34 kPushButton_SkinType,
michael@0 35 kStaticText_SkinType,
michael@0 36
michael@0 37 kSkinTypeCount
michael@0 38 };
michael@0 39
michael@0 40 struct SkinSuite {
michael@0 41 SkinSuite();
michael@0 42 ~SkinSuite()
michael@0 43 {
michael@0 44 for (int i = 0; i < kSkinTypeCount; i++)
michael@0 45 delete fAnimators[i];
michael@0 46 }
michael@0 47
michael@0 48 SkAnimator* get(SkinType);
michael@0 49
michael@0 50 private:
michael@0 51 SkAnimator* fAnimators[kSkinTypeCount];
michael@0 52 };
michael@0 53
michael@0 54 SkinSuite::SkinSuite()
michael@0 55 {
michael@0 56 static const char kSkinPath[] = "skins/";
michael@0 57
michael@0 58 static const char* gSkinNames[] = {
michael@0 59 "pushbutton_skin.xml",
michael@0 60 "statictext_skin.xml"
michael@0 61 };
michael@0 62
michael@0 63 for (unsigned i = 0; i < SK_ARRAY_COUNT(gSkinNames); i++)
michael@0 64 {
michael@0 65 size_t len = strlen(gSkinNames[i]);
michael@0 66 SkString path(sizeof(kSkinPath) - 1 + len);
michael@0 67
michael@0 68 memcpy(path.writable_str(), kSkinPath, sizeof(kSkinPath) - 1);
michael@0 69 memcpy(path.writable_str() + sizeof(kSkinPath) - 1, gSkinNames[i], len);
michael@0 70
michael@0 71 fAnimators[i] = new SkAnimator;
michael@0 72 if (!fAnimators[i]->decodeURI(path.c_str()))
michael@0 73 {
michael@0 74 delete fAnimators[i];
michael@0 75 fAnimators[i] = NULL;
michael@0 76 }
michael@0 77 }
michael@0 78 }
michael@0 79
michael@0 80 SkAnimator* SkinSuite::get(SkinType st)
michael@0 81 {
michael@0 82 SkASSERT((unsigned)st < kSkinTypeCount);
michael@0 83 return fAnimators[st];
michael@0 84 }
michael@0 85
michael@0 86 static SkinSuite* gSkinSuite;
michael@0 87
michael@0 88 static SkAnimator* get_skin_animator(SkinType st)
michael@0 89 {
michael@0 90 #if 0
michael@0 91 if (gSkinSuite == NULL)
michael@0 92 gSkinSuite = new SkinSuite;
michael@0 93 return gSkinSuite->get(st);
michael@0 94 #else
michael@0 95 return NULL;
michael@0 96 #endif
michael@0 97 }
michael@0 98
michael@0 99 ///////////////////////////////////////////////////////////////////////////////
michael@0 100
michael@0 101 void SkWidget::Init()
michael@0 102 {
michael@0 103 }
michael@0 104
michael@0 105 void SkWidget::Term()
michael@0 106 {
michael@0 107 delete gSkinSuite;
michael@0 108 }
michael@0 109
michael@0 110 void SkWidget::onEnabledChange()
michael@0 111 {
michael@0 112 this->inval(NULL);
michael@0 113 }
michael@0 114
michael@0 115 void SkWidget::postWidgetEvent()
michael@0 116 {
michael@0 117 if (!fEvent.isType("") && this->hasListeners())
michael@0 118 {
michael@0 119 this->prepareWidgetEvent(&fEvent);
michael@0 120 this->postToListeners(fEvent);
michael@0 121 }
michael@0 122 }
michael@0 123
michael@0 124 void SkWidget::prepareWidgetEvent(SkEvent*)
michael@0 125 {
michael@0 126 // override in subclass to add any additional fields before posting
michael@0 127 }
michael@0 128
michael@0 129 void SkWidget::onInflate(const SkDOM& dom, const SkDOM::Node* node)
michael@0 130 {
michael@0 131 this->INHERITED::onInflate(dom, node);
michael@0 132
michael@0 133 if ((node = dom.getFirstChild(node, "event")) != NULL)
michael@0 134 fEvent.inflate(dom, node);
michael@0 135 }
michael@0 136
michael@0 137 ///////////////////////////////////////////////////////////////////////////////
michael@0 138
michael@0 139 size_t SkHasLabelWidget::getLabel(SkString* str) const
michael@0 140 {
michael@0 141 if (str)
michael@0 142 *str = fLabel;
michael@0 143 return fLabel.size();
michael@0 144 }
michael@0 145
michael@0 146 size_t SkHasLabelWidget::getLabel(char buffer[]) const
michael@0 147 {
michael@0 148 if (buffer)
michael@0 149 memcpy(buffer, fLabel.c_str(), fLabel.size());
michael@0 150 return fLabel.size();
michael@0 151 }
michael@0 152
michael@0 153 void SkHasLabelWidget::setLabel(const SkString& str)
michael@0 154 {
michael@0 155 this->setLabel(str.c_str(), str.size());
michael@0 156 }
michael@0 157
michael@0 158 void SkHasLabelWidget::setLabel(const char label[])
michael@0 159 {
michael@0 160 this->setLabel(label, strlen(label));
michael@0 161 }
michael@0 162
michael@0 163 void SkHasLabelWidget::setLabel(const char label[], size_t len)
michael@0 164 {
michael@0 165 if (!fLabel.equals(label, len))
michael@0 166 {
michael@0 167 fLabel.set(label, len);
michael@0 168 this->onLabelChange();
michael@0 169 }
michael@0 170 }
michael@0 171
michael@0 172 void SkHasLabelWidget::onLabelChange()
michael@0 173 {
michael@0 174 // override in subclass
michael@0 175 }
michael@0 176
michael@0 177 void SkHasLabelWidget::onInflate(const SkDOM& dom, const SkDOM::Node* node)
michael@0 178 {
michael@0 179 this->INHERITED::onInflate(dom, node);
michael@0 180
michael@0 181 const char* text = dom.findAttr(node, "label");
michael@0 182 if (text)
michael@0 183 this->setLabel(text);
michael@0 184 }
michael@0 185
michael@0 186 /////////////////////////////////////////////////////////////////////////////////////
michael@0 187
michael@0 188 void SkButtonWidget::setButtonState(State state)
michael@0 189 {
michael@0 190 if (fState != state)
michael@0 191 {
michael@0 192 fState = state;
michael@0 193 this->onButtonStateChange();
michael@0 194 }
michael@0 195 }
michael@0 196
michael@0 197 void SkButtonWidget::onButtonStateChange()
michael@0 198 {
michael@0 199 this->inval(NULL);
michael@0 200 }
michael@0 201
michael@0 202 void SkButtonWidget::onInflate(const SkDOM& dom, const SkDOM::Node* node)
michael@0 203 {
michael@0 204 this->INHERITED::onInflate(dom, node);
michael@0 205
michael@0 206 int index;
michael@0 207 if ((index = dom.findList(node, "buttonState", "off,on,unknown")) >= 0)
michael@0 208 this->setButtonState((State)index);
michael@0 209 }
michael@0 210
michael@0 211 /////////////////////////////////////////////////////////////////////////////////////
michael@0 212
michael@0 213 bool SkPushButtonWidget::onEvent(const SkEvent& evt)
michael@0 214 {
michael@0 215 if (evt.isType(SK_EventType_Key) && evt.getFast32() == kOK_SkKey)
michael@0 216 {
michael@0 217 this->postWidgetEvent();
michael@0 218 return true;
michael@0 219 }
michael@0 220 return this->INHERITED::onEvent(evt);
michael@0 221 }
michael@0 222
michael@0 223 static const char* computeAnimatorState(int enabled, int focused, SkButtonWidget::State state)
michael@0 224 {
michael@0 225 if (!enabled)
michael@0 226 return "disabled";
michael@0 227 if (state == SkButtonWidget::kOn_State)
michael@0 228 {
michael@0 229 SkASSERT(focused);
michael@0 230 return "enabled-pressed";
michael@0 231 }
michael@0 232 if (focused)
michael@0 233 return "enabled-focused";
michael@0 234 return "enabled";
michael@0 235 }
michael@0 236
michael@0 237 #include "SkBlurMask.h"
michael@0 238 #include "SkBlurMaskFilter.h"
michael@0 239 #include "SkEmbossMaskFilter.h"
michael@0 240
michael@0 241 static void create_emboss(SkPaint* paint, SkScalar radius, bool focus, bool pressed)
michael@0 242 {
michael@0 243 SkEmbossMaskFilter::Light light;
michael@0 244
michael@0 245 light.fDirection[0] = SK_Scalar1/2;
michael@0 246 light.fDirection[1] = SK_Scalar1/2;
michael@0 247 light.fDirection[2] = SK_Scalar1/3;
michael@0 248 light.fAmbient = 0x48;
michael@0 249 light.fSpecular = 0x80;
michael@0 250
michael@0 251 if (pressed)
michael@0 252 {
michael@0 253 light.fDirection[0] = -light.fDirection[0];
michael@0 254 light.fDirection[1] = -light.fDirection[1];
michael@0 255 }
michael@0 256 if (focus)
michael@0 257 light.fDirection[2] += SK_Scalar1/4;
michael@0 258
michael@0 259 SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(radius);
michael@0 260 paint->setMaskFilter(new SkEmbossMaskFilter(sigma, light))->unref();
michael@0 261 }
michael@0 262
michael@0 263 void SkPushButtonWidget::onDraw(SkCanvas* canvas)
michael@0 264 {
michael@0 265 this->INHERITED::onDraw(canvas);
michael@0 266
michael@0 267 SkString label;
michael@0 268 this->getLabel(&label);
michael@0 269
michael@0 270 SkAnimator* anim = get_skin_animator(kPushButton_SkinType);
michael@0 271
michael@0 272 if (anim)
michael@0 273 {
michael@0 274 SkEvent evt("user");
michael@0 275
michael@0 276 evt.setString("id", "prime");
michael@0 277 evt.setScalar("prime-width", this->width());
michael@0 278 evt.setScalar("prime-height", this->height());
michael@0 279 evt.setString("prime-text", label);
michael@0 280 evt.setString("prime-state", computeAnimatorState(this->isEnabled(), this->hasFocus(), this->getButtonState()));
michael@0 281
michael@0 282 (void)anim->doUserEvent(evt);
michael@0 283 SkPaint paint;
michael@0 284 anim->draw(canvas, &paint, SkTime::GetMSecs());
michael@0 285 }
michael@0 286 else
michael@0 287 {
michael@0 288 SkRect r;
michael@0 289 SkPaint p;
michael@0 290
michael@0 291 r.set(0, 0, this->width(), this->height());
michael@0 292 p.setAntiAliasOn(true);
michael@0 293 p.setColor(SK_ColorBLUE);
michael@0 294 create_emboss(&p, SkIntToScalar(12)/5, this->hasFocus(), this->getButtonState() == kOn_State);
michael@0 295 canvas->drawRoundRect(r, SkScalarHalf(this->height()), SkScalarHalf(this->height()), p);
michael@0 296 p.setMaskFilter(NULL);
michael@0 297
michael@0 298 p.setTextAlign(SkPaint::kCenter_Align);
michael@0 299
michael@0 300 SkTextBox box;
michael@0 301 box.setMode(SkTextBox::kOneLine_Mode);
michael@0 302 box.setSpacingAlign(SkTextBox::kCenter_SpacingAlign);
michael@0 303 box.setBox(0, 0, this->width(), this->height());
michael@0 304
michael@0 305 // if (this->getButtonState() == kOn_State)
michael@0 306 // p.setColor(SK_ColorRED);
michael@0 307 // else
michael@0 308 p.setColor(SK_ColorWHITE);
michael@0 309
michael@0 310 box.draw(canvas, label.c_str(), label.size(), p);
michael@0 311 }
michael@0 312 }
michael@0 313
michael@0 314 SkView::Click* SkPushButtonWidget::onFindClickHandler(SkScalar x, SkScalar y, unsigned modi)
michael@0 315 {
michael@0 316 this->acceptFocus();
michael@0 317 return new Click(this);
michael@0 318 }
michael@0 319
michael@0 320 bool SkPushButtonWidget::onClick(Click* click)
michael@0 321 {
michael@0 322 SkRect r;
michael@0 323 State state = kOff_State;
michael@0 324
michael@0 325 this->getLocalBounds(&r);
michael@0 326 if (r.contains(click->fCurr))
michael@0 327 {
michael@0 328 if (click->fState == Click::kUp_State)
michael@0 329 this->postWidgetEvent();
michael@0 330 else
michael@0 331 state = kOn_State;
michael@0 332 }
michael@0 333 this->setButtonState(state);
michael@0 334 return true;
michael@0 335 }
michael@0 336
michael@0 337 //////////////////////////////////////////////////////////////////////////////////////////
michael@0 338
michael@0 339 SkStaticTextView::SkStaticTextView(U32 flags) : SkView(flags)
michael@0 340 {
michael@0 341 fMargin.set(0, 0);
michael@0 342 fMode = kFixedSize_Mode;
michael@0 343 fSpacingAlign = SkTextBox::kStart_SpacingAlign;
michael@0 344 }
michael@0 345
michael@0 346 SkStaticTextView::~SkStaticTextView()
michael@0 347 {
michael@0 348 }
michael@0 349
michael@0 350 void SkStaticTextView::computeSize()
michael@0 351 {
michael@0 352 if (fMode == kAutoWidth_Mode)
michael@0 353 {
michael@0 354 SkScalar width = fPaint.measureText(fText.c_str(), fText.size(), NULL, NULL);
michael@0 355 this->setWidth(width + fMargin.fX * 2);
michael@0 356 }
michael@0 357 else if (fMode == kAutoHeight_Mode)
michael@0 358 {
michael@0 359 SkScalar width = this->width() - fMargin.fX * 2;
michael@0 360 int lines = width > 0 ? SkTextLineBreaker::CountLines(fText.c_str(), fText.size(), fPaint, width) : 0;
michael@0 361
michael@0 362 SkScalar before, after;
michael@0 363 (void)fPaint.measureText(0, NULL, &before, &after);
michael@0 364
michael@0 365 this->setHeight(lines * (after - before) + fMargin.fY * 2);
michael@0 366 }
michael@0 367 }
michael@0 368
michael@0 369 void SkStaticTextView::setMode(Mode mode)
michael@0 370 {
michael@0 371 SkASSERT((unsigned)mode < kModeCount);
michael@0 372
michael@0 373 if (fMode != mode)
michael@0 374 {
michael@0 375 fMode = SkToU8(mode);
michael@0 376 this->computeSize();
michael@0 377 }
michael@0 378 }
michael@0 379
michael@0 380 void SkStaticTextView::setSpacingAlign(SkTextBox::SpacingAlign align)
michael@0 381 {
michael@0 382 fSpacingAlign = SkToU8(align);
michael@0 383 this->inval(NULL);
michael@0 384 }
michael@0 385
michael@0 386 void SkStaticTextView::getMargin(SkPoint* margin) const
michael@0 387 {
michael@0 388 if (margin)
michael@0 389 *margin = fMargin;
michael@0 390 }
michael@0 391
michael@0 392 void SkStaticTextView::setMargin(SkScalar dx, SkScalar dy)
michael@0 393 {
michael@0 394 if (fMargin.fX != dx || fMargin.fY != dy)
michael@0 395 {
michael@0 396 fMargin.set(dx, dy);
michael@0 397 this->computeSize();
michael@0 398 this->inval(NULL);
michael@0 399 }
michael@0 400 }
michael@0 401
michael@0 402 size_t SkStaticTextView::getText(SkString* text) const
michael@0 403 {
michael@0 404 if (text)
michael@0 405 *text = fText;
michael@0 406 return fText.size();
michael@0 407 }
michael@0 408
michael@0 409 size_t SkStaticTextView::getText(char text[]) const
michael@0 410 {
michael@0 411 if (text)
michael@0 412 memcpy(text, fText.c_str(), fText.size());
michael@0 413 return fText.size();
michael@0 414 }
michael@0 415
michael@0 416 void SkStaticTextView::setText(const SkString& text)
michael@0 417 {
michael@0 418 this->setText(text.c_str(), text.size());
michael@0 419 }
michael@0 420
michael@0 421 void SkStaticTextView::setText(const char text[])
michael@0 422 {
michael@0 423 this->setText(text, strlen(text));
michael@0 424 }
michael@0 425
michael@0 426 void SkStaticTextView::setText(const char text[], size_t len)
michael@0 427 {
michael@0 428 if (!fText.equals(text, len))
michael@0 429 {
michael@0 430 fText.set(text, len);
michael@0 431 this->computeSize();
michael@0 432 this->inval(NULL);
michael@0 433 }
michael@0 434 }
michael@0 435
michael@0 436 void SkStaticTextView::getPaint(SkPaint* paint) const
michael@0 437 {
michael@0 438 if (paint)
michael@0 439 *paint = fPaint;
michael@0 440 }
michael@0 441
michael@0 442 void SkStaticTextView::setPaint(const SkPaint& paint)
michael@0 443 {
michael@0 444 if (fPaint != paint)
michael@0 445 {
michael@0 446 fPaint = paint;
michael@0 447 this->computeSize();
michael@0 448 this->inval(NULL);
michael@0 449 }
michael@0 450 }
michael@0 451
michael@0 452 void SkStaticTextView::onDraw(SkCanvas* canvas)
michael@0 453 {
michael@0 454 this->INHERITED::onDraw(canvas);
michael@0 455
michael@0 456 if (fText.isEmpty())
michael@0 457 return;
michael@0 458
michael@0 459 SkTextBox box;
michael@0 460
michael@0 461 box.setMode(fMode == kAutoWidth_Mode ? SkTextBox::kOneLine_Mode : SkTextBox::kLineBreak_Mode);
michael@0 462 box.setSpacingAlign(this->getSpacingAlign());
michael@0 463 box.setBox(fMargin.fX, fMargin.fY, this->width() - fMargin.fX, this->height() - fMargin.fY);
michael@0 464 box.draw(canvas, fText.c_str(), fText.size(), fPaint);
michael@0 465 }
michael@0 466
michael@0 467 void SkStaticTextView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
michael@0 468 {
michael@0 469 this->INHERITED::onInflate(dom, node);
michael@0 470
michael@0 471 int index;
michael@0 472 if ((index = dom.findList(node, "mode", "fixed,auto-width,auto-height")) >= 0)
michael@0 473 this->setMode((Mode)index);
michael@0 474 else
michael@0 475 assert_no_attr(dom, node, "mode");
michael@0 476
michael@0 477 if ((index = dom.findList(node, "spacing-align", "start,center,end")) >= 0)
michael@0 478 this->setSpacingAlign((SkTextBox::SpacingAlign)index);
michael@0 479 else
michael@0 480 assert_no_attr(dom, node, "mode");
michael@0 481
michael@0 482 SkScalar s[2];
michael@0 483 if (dom.findScalars(node, "margin", s, 2))
michael@0 484 this->setMargin(s[0], s[1]);
michael@0 485 else
michael@0 486 assert_no_attr(dom, node, "margin");
michael@0 487
michael@0 488 const char* text = dom.findAttr(node, "text");
michael@0 489 if (text)
michael@0 490 this->setText(text);
michael@0 491
michael@0 492 if ((node = dom.getFirstChild(node, "paint")) != NULL)
michael@0 493 SkPaint_Inflate(&fPaint, dom, node);
michael@0 494 }
michael@0 495
michael@0 496 /////////////////////////////////////////////////////////////////////////////////////////////////////
michael@0 497
michael@0 498 #include "SkImageDecoder.h"
michael@0 499
michael@0 500 SkBitmapView::SkBitmapView(U32 flags) : SkView(flags)
michael@0 501 {
michael@0 502 }
michael@0 503
michael@0 504 SkBitmapView::~SkBitmapView()
michael@0 505 {
michael@0 506 }
michael@0 507
michael@0 508 bool SkBitmapView::getBitmap(SkBitmap* bitmap) const
michael@0 509 {
michael@0 510 if (bitmap)
michael@0 511 *bitmap = fBitmap;
michael@0 512 return fBitmap.colorType() != kUnknown_SkColorType;
michael@0 513 }
michael@0 514
michael@0 515 void SkBitmapView::setBitmap(const SkBitmap* bitmap, bool viewOwnsPixels)
michael@0 516 {
michael@0 517 if (bitmap)
michael@0 518 {
michael@0 519 fBitmap = *bitmap;
michael@0 520 fBitmap.setOwnsPixels(viewOwnsPixels);
michael@0 521 }
michael@0 522 }
michael@0 523
michael@0 524 bool SkBitmapView::loadBitmapFromFile(const char path[])
michael@0 525 {
michael@0 526 SkBitmap bitmap;
michael@0 527
michael@0 528 if (SkImageDecoder::DecodeFile(path, &bitmap))
michael@0 529 {
michael@0 530 this->setBitmap(&bitmap, true);
michael@0 531 bitmap.setOwnsPixels(false);
michael@0 532 return true;
michael@0 533 }
michael@0 534 return false;
michael@0 535 }
michael@0 536
michael@0 537 void SkBitmapView::onDraw(SkCanvas* canvas)
michael@0 538 {
michael@0 539 if (fBitmap.colorType() != kUnknown_SkColorType &&
michael@0 540 fBitmap.width() && fBitmap.height())
michael@0 541 {
michael@0 542 SkAutoCanvasRestore restore(canvas, true);
michael@0 543 SkPaint p;
michael@0 544
michael@0 545 p.setFilterType(SkPaint::kBilinear_FilterType);
michael@0 546 canvas->scale( this->width() / fBitmap.width(),
michael@0 547 this->height() / fBitmap.height(),
michael@0 548 0, 0);
michael@0 549 canvas->drawBitmap(fBitmap, 0, 0, p);
michael@0 550 }
michael@0 551 }
michael@0 552
michael@0 553 void SkBitmapView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
michael@0 554 {
michael@0 555 this->INHERITED::onInflate(dom, node);
michael@0 556
michael@0 557 const char* src = dom.findAttr(node, "src");
michael@0 558 if (src)
michael@0 559 (void)this->loadBitmapFromFile(src);
michael@0 560 }
michael@0 561
michael@0 562 #endif

mercurial