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.

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

mercurial