Home | History | Annotate | Download | only in viewer
      1 /*
      2 * Copyright 2018 Google Inc.
      3 *
      4 * Use of this source code is governed by a BSD-style license that can be
      5 * found in the LICENSE file.
      6 */
      7 
      8 #include "NIMASlide.h"
      9 
     10 #include "Resources.h"
     11 #include "SkAnimTimer.h"
     12 #include "SkOSPath.h"
     13 #include "imgui.h"
     14 #include "nima/NimaActor.h"
     15 
     16 #include <algorithm>
     17 #include <cmath>
     18 
     19 using namespace sk_app;
     20 using namespace nima;
     21 
     22 // ImGui expects an array of const char* when displaying a ListBox. This function is for an
     23 // overload of ImGui::ListBox that takes a getter so that ListBox works with
     24 // std::vector<std::string>.
     25 static bool vector_getter(void* v, int index, const char** out) {
     26     auto vector = reinterpret_cast<std::vector<std::string>*>(v);
     27     *out = vector->at(index).c_str();
     28     return true;
     29 }
     30 
     31 //////////////////////////////////////////////////////////////////////////////////////////////////
     32 
     33 NIMASlide::NIMASlide(const SkString& name, const SkString& path)
     34         : fBasePath()
     35         , fActor(nullptr)
     36         , fAnimationIndex(0)
     37         , fPlaying(true)
     38         , fTime(0.0f)
     39         , fRenderFlags(0) {
     40     fName = name;
     41 
     42     // Get the path components.
     43     SkString baseName = SkOSPath::Basename(path.c_str());
     44     baseName.resize(baseName.size() - 5);
     45     SkString dirName = SkOSPath::Dirname(path.c_str());
     46     SkString basePath = SkOSPath::Join(dirName.c_str(), baseName.c_str());
     47 
     48     // Save the base path.
     49     fBasePath = std::string(basePath.c_str());
     50 }
     51 
     52 NIMASlide::~NIMASlide() {}
     53 
     54 SkISize NIMASlide::getDimensions() const {
     55     return SkISize::MakeEmpty(); // TODO
     56 }
     57 
     58 void NIMASlide::draw(SkCanvas* canvas) {
     59     canvas->save();
     60 
     61     for (int i = 0; i < 10; i ++) {
     62         for (int j = 0; j < 10; j ++) {
     63             canvas->save();
     64 
     65             canvas->translate(1250 - 250 * i, 1250 - 250 * j);
     66             canvas->scale(0.5, -0.5);
     67 
     68             // Render the actor.
     69             fActor->setAnimation(fAnimationIndex);
     70             fActor->render(canvas, fRenderFlags);
     71 
     72             canvas->restore();
     73         }
     74     }
     75 
     76     canvas->restore();
     77 
     78     // Render the GUI.
     79     this->renderGUI();
     80 }
     81 
     82 void NIMASlide::load(SkScalar winWidth, SkScalar winHeight) {
     83     this->resetActor();
     84 }
     85 
     86 void NIMASlide::unload() {
     87     // Discard resources.
     88     fActor.reset(nullptr);
     89 }
     90 
     91 bool NIMASlide::animate(const SkAnimTimer& timer) {
     92     // Apply the animation.
     93     if (fActor) {
     94         float time = std::fmod(timer.secs(), fActor->duration());
     95         fActor->seek(time);
     96     }
     97     return true;
     98 }
     99 
    100 bool NIMASlide::onChar(SkUnichar c) {
    101     return false;
    102 }
    103 
    104 bool NIMASlide::onMouse(SkScalar x, SkScalar y, Window::InputState state, uint32_t modifiers) {
    105     return false;
    106 }
    107 
    108 void NIMASlide::resetActor() {
    109     // Create the actor.
    110     std::string nimaPath = fBasePath + ".nima";
    111     std::string texturePath = fBasePath + ".png";
    112 
    113     fActor = std::make_unique<NimaActor>(nimaPath, texturePath);
    114 }
    115 
    116 void NIMASlide::renderGUI() {
    117     ImGui::SetNextWindowSize(ImVec2(300, 0));
    118     ImGui::Begin("NIMA");
    119 
    120     // List of animations.
    121     auto animations = const_cast<std::vector<std::string>&>(fActor->getAnimationNames());
    122     ImGui::PushItemWidth(-1);
    123     if (ImGui::ListBox("Animations",
    124                        &fAnimationIndex,
    125                        vector_getter,
    126                        reinterpret_cast<void*>(&animations),
    127                        animations.size(),
    128                        5)) {
    129         resetActor();
    130     }
    131 
    132     // Playback control.
    133     ImGui::Spacing();
    134     if (ImGui::Button("Play")) {
    135         fPlaying = true;
    136     }
    137     ImGui::SameLine();
    138     if (ImGui::Button("Pause")) {
    139         fPlaying = false;
    140     }
    141 
    142     // Time slider.
    143     ImGui::PushItemWidth(-1);
    144     ImGui::SliderFloat("Time", &fTime, 0.0f, fActor->duration(), "Time: %.3f");
    145 
    146     // Backend control.
    147     int useImmediate = SkToBool(fRenderFlags & kImmediate_RenderFlag);
    148     ImGui::Spacing();
    149     ImGui::RadioButton("Skia Backend", &useImmediate, 0);
    150     ImGui::RadioButton("Immediate Backend", &useImmediate, 1);
    151     if (useImmediate) {
    152         fRenderFlags |= kImmediate_RenderFlag;
    153     } else {
    154         fRenderFlags &= ~kImmediate_RenderFlag;
    155     }
    156 
    157     // Cache control.
    158     bool useCache = SkToBool(fRenderFlags & kCache_RenderFlag);
    159     ImGui::Spacing();
    160     ImGui::Checkbox("Cache Vertices", &useCache);
    161     if (useCache) {
    162         fRenderFlags |= kCache_RenderFlag;
    163     } else {
    164         fRenderFlags &= ~kCache_RenderFlag;
    165     }
    166 
    167     // Bounding box toggle.
    168     bool drawBounds = SkToBool(fRenderFlags & kBounds_RenderFlag);
    169     ImGui::Spacing();
    170     ImGui::Checkbox("Draw Bounds", &drawBounds);
    171     if (drawBounds) {
    172         fRenderFlags |= kBounds_RenderFlag;
    173     } else {
    174         fRenderFlags &= ~kBounds_RenderFlag;
    175     }
    176 
    177     ImGui::End();
    178 }
    179