blob: bf516a8000535b31e3a6a2945f7ab3e9f023adfa [file] [log] [blame]
Ruiqi Maof5101492018-06-29 14:32:21 -04001/*
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
Kevin Lubickd9699322018-10-30 15:08:53 -040010#include "Resources.h"
Ruiqi Maof5101492018-06-29 14:32:21 -040011#include "SkAnimTimer.h"
12#include "SkOSPath.h"
Ruiqi Maof5101492018-06-29 14:32:21 -040013#include "imgui.h"
Kevin Lubickd9699322018-10-30 15:08:53 -040014#include "nima/NimaActor.h"
Ruiqi Maof5101492018-06-29 14:32:21 -040015
16#include <algorithm>
17#include <cmath>
18
19using namespace sk_app;
20using namespace nima;
21
Ruiqi Maof5101492018-06-29 14:32:21 -040022// 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>.
25static 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
Ruiqi Maof5101492018-06-29 14:32:21 -040031//////////////////////////////////////////////////////////////////////////////////////////////////
32
33NIMASlide::NIMASlide(const SkString& name, const SkString& path)
34 : fBasePath()
35 , fActor(nullptr)
Kevin Lubickd9699322018-10-30 15:08:53 -040036 , fAnimationIndex(0)
Ruiqi Maof5101492018-06-29 14:32:21 -040037 , fPlaying(true)
38 , fTime(0.0f)
Kevin Lubickd9699322018-10-30 15:08:53 -040039 , fRenderFlags(0) {
Ruiqi Maof5101492018-06-29 14:32:21 -040040 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
52NIMASlide::~NIMASlide() {}
53
Ben Wagner21151122018-09-04 18:35:20 -040054SkISize NIMASlide::getDimensions() const {
55 return SkISize::MakeEmpty(); // TODO
56}
57
Ruiqi Maof5101492018-06-29 14:32:21 -040058void NIMASlide::draw(SkCanvas* canvas) {
59 canvas->save();
60
Ruiqi Mao9a6e42f2018-07-09 14:16:56 -040061 for (int i = 0; i < 10; i ++) {
62 for (int j = 0; j < 10; j ++) {
63 canvas->save();
Ruiqi Maof5101492018-06-29 14:32:21 -040064
Ruiqi Mao9a6e42f2018-07-09 14:16:56 -040065 canvas->translate(1250 - 250 * i, 1250 - 250 * j);
66 canvas->scale(0.5, -0.5);
67
68 // Render the actor.
Kevin Lubickd9699322018-10-30 15:08:53 -040069 fActor->setAnimation(fAnimationIndex);
Ruiqi Mao46656e22018-07-20 14:18:50 -040070 fActor->render(canvas, fRenderFlags);
Ruiqi Mao9a6e42f2018-07-09 14:16:56 -040071
72 canvas->restore();
73 }
74 }
Ruiqi Maof5101492018-06-29 14:32:21 -040075
76 canvas->restore();
77
78 // Render the GUI.
79 this->renderGUI();
80}
81
82void NIMASlide::load(SkScalar winWidth, SkScalar winHeight) {
83 this->resetActor();
84}
85
86void NIMASlide::unload() {
87 // Discard resources.
Ruiqi Maof5101492018-06-29 14:32:21 -040088 fActor.reset(nullptr);
89}
90
91bool NIMASlide::animate(const SkAnimTimer& timer) {
92 // Apply the animation.
Kevin Lubickd9699322018-10-30 15:08:53 -040093 if (fActor) {
94 float time = std::fmod(timer.secs(), fActor->duration());
95 fActor->seek(time);
Ruiqi Maof5101492018-06-29 14:32:21 -040096 }
97 return true;
98}
99
100bool NIMASlide::onChar(SkUnichar c) {
101 return false;
102}
103
104bool NIMASlide::onMouse(SkScalar x, SkScalar y, Window::InputState state, uint32_t modifiers) {
105 return false;
106}
107
108void NIMASlide::resetActor() {
109 // Create the actor.
Kevin Lubickd9699322018-10-30 15:08:53 -0400110 std::string nimaPath = fBasePath + ".nima";
111 std::string texturePath = fBasePath + ".png";
Ruiqi Maof5101492018-06-29 14:32:21 -0400112
Kevin Lubickd9699322018-10-30 15:08:53 -0400113 fActor = std::make_unique<NimaActor>(nimaPath, texturePath);
Ruiqi Maof5101492018-06-29 14:32:21 -0400114}
115
116void NIMASlide::renderGUI() {
Ruiqi Mao46656e22018-07-20 14:18:50 -0400117 ImGui::SetNextWindowSize(ImVec2(300, 0));
Ruiqi Maof5101492018-06-29 14:32:21 -0400118 ImGui::Begin("NIMA");
119
120 // List of animations.
Kevin Lubickd9699322018-10-30 15:08:53 -0400121 auto animations = const_cast<std::vector<std::string>&>(fActor->getAnimationNames());
Ruiqi Maof5101492018-06-29 14:32:21 -0400122 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);
Kevin Lubickd9699322018-10-30 15:08:53 -0400144 ImGui::SliderFloat("Time", &fTime, 0.0f, fActor->duration(), "Time: %.3f");
Ruiqi Maof5101492018-06-29 14:32:21 -0400145
146 // Backend control.
Ruiqi Mao46656e22018-07-20 14:18:50 -0400147 int useImmediate = SkToBool(fRenderFlags & kImmediate_RenderFlag);
Ruiqi Maof5101492018-06-29 14:32:21 -0400148 ImGui::Spacing();
Ruiqi Mao46656e22018-07-20 14:18:50 -0400149 ImGui::RadioButton("Skia Backend", &useImmediate, 0);
150 ImGui::RadioButton("Immediate Backend", &useImmediate, 1);
151 if (useImmediate) {
152 fRenderFlags |= kImmediate_RenderFlag;
Ruiqi Maof5101492018-06-29 14:32:21 -0400153 } else {
Ruiqi Mao46656e22018-07-20 14:18:50 -0400154 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;
Ruiqi Maof5101492018-06-29 14:32:21 -0400175 }
176
177 ImGui::End();
178}