|  | /* | 
|  | * Copyright 2016 Google Inc. | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  |  | 
|  | #include "include/core/SkCanvas.h" | 
|  | #include "include/core/SkString.h" | 
|  | #include "samplecode/Sample.h" | 
|  |  | 
|  | #if SK_SUPPORT_GPU | 
|  | #   include "include/gpu/GrDirectContext.h" | 
|  | #else | 
|  | class GrDirectContext; | 
|  | #endif | 
|  |  | 
|  | ////////////////////////////////////////////////////////////////////////////// | 
|  |  | 
|  | void Sample::setSize(SkScalar width, SkScalar height) { | 
|  | width = std::max(0.0f, width); | 
|  | height = std::max(0.0f, height); | 
|  |  | 
|  | if (fWidth != width || fHeight != height) | 
|  | { | 
|  | fWidth = width; | 
|  | fHeight = height; | 
|  | this->onSizeChange(); | 
|  | } | 
|  | } | 
|  |  | 
|  | void Sample::draw(SkCanvas* canvas) { | 
|  | if (fWidth && fHeight) { | 
|  | SkRect    r; | 
|  | r.setLTRB(0, 0, fWidth, fHeight); | 
|  | if (canvas->quickReject(r)) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | SkAutoCanvasRestore    as(canvas, true); | 
|  | int sc = canvas->save(); | 
|  |  | 
|  | if (!fHaveCalledOnceBeforeDraw) { | 
|  | fHaveCalledOnceBeforeDraw = true; | 
|  | this->onOnceBeforeDraw(); | 
|  | } | 
|  | this->onDrawBackground(canvas); | 
|  |  | 
|  | SkAutoCanvasRestore acr(canvas, true); | 
|  | this->onDrawContent(canvas); | 
|  | #if SK_SUPPORT_GPU | 
|  | // Ensure the context doesn't combine GrDrawOps across draw loops. | 
|  | if (auto direct = GrAsDirectContext(canvas->recordingContext())) { | 
|  | direct->flushAndSubmit(); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | canvas->restoreToCount(sc); | 
|  | } | 
|  | } | 
|  |  | 
|  | //////////////////////////////////////////////////////////////////////////// | 
|  |  | 
|  | bool Sample::mouse(SkPoint point, skui::InputState clickState, skui::ModifierKey modifierKeys) { | 
|  | auto dispatch = [this](Click* c) { | 
|  | return c->fHasFunc ? c->fFunc(c) : this->onClick(c); | 
|  | }; | 
|  |  | 
|  | switch (clickState) { | 
|  | case skui::InputState::kDown: | 
|  | fClick = nullptr; | 
|  | fClick.reset(this->onFindClickHandler(point.x(), point.y(), modifierKeys)); | 
|  | if (!fClick) { | 
|  | return false; | 
|  | } | 
|  | fClick->fPrev = fClick->fCurr = fClick->fOrig = point; | 
|  | fClick->fState = skui::InputState::kDown; | 
|  | fClick->fModifierKeys = modifierKeys; | 
|  | dispatch(fClick.get()); | 
|  | return true; | 
|  | case skui::InputState::kMove: | 
|  | if (fClick) { | 
|  | fClick->fPrev = fClick->fCurr; | 
|  | fClick->fCurr = point; | 
|  | fClick->fState = skui::InputState::kMove; | 
|  | fClick->fModifierKeys = modifierKeys; | 
|  | return dispatch(fClick.get()); | 
|  | } | 
|  | return false; | 
|  | case skui::InputState::kUp: | 
|  | if (fClick) { | 
|  | fClick->fPrev = fClick->fCurr; | 
|  | fClick->fCurr = point; | 
|  | fClick->fState = skui::InputState::kUp; | 
|  | fClick->fModifierKeys = modifierKeys; | 
|  | bool result = dispatch(fClick.get()); | 
|  | fClick = nullptr; | 
|  | return result; | 
|  | } | 
|  | return false; | 
|  | default: | 
|  | // Ignore other cases | 
|  | SkASSERT(false); | 
|  | break; | 
|  | } | 
|  | SkASSERT(false); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | ////////////////////////////////////////////////////////////////////// | 
|  |  | 
|  | void Sample::onSizeChange() {} | 
|  |  | 
|  | Sample::Click* Sample::onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) { | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | bool Sample::onClick(Click*) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void Sample::onDrawBackground(SkCanvas* canvas) { | 
|  | canvas->drawColor(fBGColor); | 
|  | } | 
|  |  | 
|  | // need to explicitly declare this, or we get some weird infinite loop llist | 
|  | template SampleRegistry* SampleRegistry::gHead; |