| /* | |
| * 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::animate(double nanos) { | |
| if (!fHaveCalledOnceBeforeDraw) { | |
| fHaveCalledOnceBeforeDraw = true; | |
| this->onOnceBeforeDraw(); | |
| } | |
| return this->onAnimate(nanos); | |
| } | |
| //////////////////////////////////////////////////////////////////////////// | |
| 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; |