commit fa913abf749b617a8398a32e812e245c0093b5ba
parent ff852a76435d67afb8a8ea9a0dcce1a451c91c66
Author: Adam M <aemalone@gmail.com>
Date: Sun, 3 Jan 2021 21:15:11 -0600
Giant display of scrubbed frame when zelecting sero
Diffstat:
5 files changed, 169 insertions(+), 61 deletions(-)
diff --git a/src/Computerscare.hpp b/src/Computerscare.hpp
@@ -53,7 +53,7 @@ static const NVGcolor COLOR_COMPUTERSCARE_YELLOW = nvgRGB(0xE4, 0xC4, 0x21);
static const NVGcolor COLOR_COMPUTERSCARE_BLUE = nvgRGB(0x24, 0x44, 0xC1);
static const NVGcolor COLOR_COMPUTERSCARE_PINK = nvgRGB(0xAA, 0x18, 0x31);
static const NVGcolor COLOR_COMPUTERSCARE_TRANSPARENT = nvgRGBA(0x00, 0x00, 0x00, 0x00);
-static const NVGcolor BLACK=nvgRGB(0x00,0x00,0x00);
+static const NVGcolor BLACK = nvgRGB(0x00, 0x00, 0x00);
namespace rack {
@@ -113,7 +113,7 @@ struct InputBlockBackground : TransparentWidget {
nvgBeginPath(args.vg);
nvgRect(args.vg, box.pos.x, box.pos.y, box.size.x, box.size.y);
nvgStrokeColor(args.vg, COLOR_COMPUTERSCARE_BLUE);
- nvgStrokeWidth(args.vg,2.5);
+ nvgStrokeWidth(args.vg, 2.5);
nvgFillColor(args.vg, COLOR_COMPUTERSCARE_LIGHT_GREEN);
nvgFill(args.vg);
Widget::draw(args);
@@ -128,15 +128,15 @@ struct IsoButton : SvgSwitch {
}
};
struct SmallIsoButton : app::SvgSwitch {
- bool disabled=true;
- bool lastDisabled=false;
+ bool disabled = true;
+ bool lastDisabled = false;
std::vector<std::shared_ptr<Svg>> enabledFrames;
std::vector<std::shared_ptr<Svg>> disabledFrames;
SmallIsoButton() {
enabledFrames.push_back(APP->window->loadSvg(asset::plugin(pluginInstance, "res/computerscare-iso-button-small-up.svg")));
enabledFrames.push_back(APP->window->loadSvg(asset::plugin(pluginInstance, "res/computerscare-iso-button-small-down.svg")));
-
+
disabledFrames.push_back(APP->window->loadSvg(asset::plugin(pluginInstance, "res/computerscare-iso-button-small-up-grey.svg")));
disabledFrames.push_back(APP->window->loadSvg(asset::plugin(pluginInstance, "res/computerscare-iso-button-small-down-grey.svg")));
@@ -148,16 +148,16 @@ struct SmallIsoButton : app::SvgSwitch {
void step() override {
if (disabled != lastDisabled) {
- if(disabled) {
- frames[0]=disabledFrames[0];
- frames[1]=disabledFrames[1];
+ if (disabled) {
+ frames[0] = disabledFrames[0];
+ frames[1] = disabledFrames[1];
}
else {
- frames[0]=enabledFrames[0];
- frames[1]=enabledFrames[1];
+ frames[0] = enabledFrames[0];
+ frames[1] = enabledFrames[1];
}
onChange(*(new event::Change()));
- fb->dirty=true;
+ fb->dirty = true;
dirtyValue = -20.f;
lastDisabled = disabled;
@@ -383,14 +383,14 @@ struct ScrambleKnob : RoundKnob {
};
struct ScrambleSnapKnob : RoundKnob {
ScrambleSnapKnob() {
- snap=true;
+ snap = true;
shadow->opacity = 0.f;
setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/computerscare-scramble-knob.svg")));
}
};
struct ScrambleSnapKnobNoRandom : RoundKnob {
ScrambleSnapKnobNoRandom() {
- snap=true;
+ snap = true;
shadow->opacity = 0.f;
setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/computerscare-scramble-knob.svg")));
}
@@ -484,7 +484,7 @@ struct SmallLetterDisplay : Widget {
std::string defaultFontPath = "res/Oswald-Regular.ttf";
NVGcolor baseColor = COLOR_COMPUTERSCARE_TRANSPARENT;
NVGcolor textColor = nvgRGB(0x10, 0x10, 0x00);
- Vec textOffset = Vec(0,0);
+ Vec textOffset = Vec(0, 0);
float letterSpacing = 2.5;
int textAlign = 1;
diff --git a/src/ComputerscareBlank.cpp b/src/ComputerscareBlank.cpp
@@ -1,6 +1,8 @@
#include "Computerscare.hpp"
#include "ComputerscareResizableHandle.hpp"
#include "animatedGif.hpp"
+#include "CustomBlankFunctions.hpp"
+
#include <osdialog.h>
#include <iostream>
#include <fstream>
@@ -10,7 +12,6 @@
#define FONT_SIZE 13
-struct ComputerscareBlank;
struct ComputerscareBlank : ComputerscareMenuParamModule {
bool loading = true;
@@ -43,6 +44,11 @@ struct ComputerscareBlank : ComputerscareMenuParamModule {
int samplesDelay = 10000;
int speed = 100000;
int imageStatus = 0;
+ bool scrubbing = false;
+ int scrubFrame = 0;
+
+ int pingPongDirection = 1;
+
/*
uninitialized: 0
gif: 1
@@ -59,7 +65,7 @@ struct ComputerscareBlank : ComputerscareMenuParamModule {
float leftMessages[2][8] = {};
- int pingPongDirection = 1;
+
float speedFactor = 1.f;
@@ -121,6 +127,7 @@ struct ComputerscareBlank : ComputerscareMenuParamModule {
leftExpander.producerMessage = leftMessages[0];
leftExpander.consumerMessage = leftMessages[1];
+
}
void process(const ProcessArgs &args) override {
if (imageStatus == 1) {
@@ -144,6 +151,10 @@ struct ComputerscareBlank : ComputerscareMenuParamModule {
zeroOffset = messageFromExpander[7];
+ scrubbing = messageFromExpander[8];
+
+ updateScrubFrame();
+
if (clockConnected) {
bool clockTriggered = clockTrigger.process(messageFromExpander[2]);
if (clockMode == 0) {
@@ -199,7 +210,11 @@ struct ComputerscareBlank : ComputerscareMenuParamModule {
}
}
-
+ void updateScrubFrame() {
+ if (ready) {
+ scrubFrame = mapBlankFrameOffset(zeroOffset, numFrames);
+ }
+ }
void onReset() override {
zoomX = 1;
@@ -338,7 +353,12 @@ struct ComputerscareBlank : ComputerscareMenuParamModule {
prevFrame();
}
else if (animationMode == 2) {
- pingPongDirection == 1 ? nextFrame() : prevFrame();
+ if (pingPongDirection == 1) {
+
+ nextFrame();
+ } else {
+ prevFrame();
+ }
}
else if (animationMode == 4 ) {
goToRandomFrame();
@@ -348,17 +368,23 @@ struct ComputerscareBlank : ComputerscareMenuParamModule {
else {
prevFrame();
}
- if (currentFrame == numFrames - 1) {
- if (animationMode == 2 ) {
- pingPongDirection = -1;
+ if (animationMode == 2) {
+ //DEBUG("PRE ping current:%i,direction:%i", currentFrame, pingPongDirection);
+ if (pingPongDirection == 1) {
+ if (currentFrame == numFrames - 1) {
+ pingPongDirection = -1;
+ }
+ }
+ else {
+ if (currentFrame == 0) {
+ pingPongDirection = 1;
+ }
}
}
+
if (currentFrame == 0) {
int eb = params[END_BEHAVIOR].getValue();
- if (animationMode == 2) {
- pingPongDirection = 1;
- }
if (eb == 3 ) {
loadRandomGif();
}
@@ -379,10 +405,10 @@ struct ComputerscareBlank : ComputerscareMenuParamModule {
goToFrame(currentFrame - 1);
}
void goToFrame(int frameNum) {
- if (numFrames) {
+ if (numFrames && ready) {
sampleCounter = 0;
currentFrame = frameNum;
- mappedFrame = (currentFrame + ((int)floor(zeroOffset * numFrames))+numFrames) % numFrames;
+ mappedFrame = (currentFrame + mapBlankFrameOffset(zeroOffset, numFrames)) % numFrames;
currentFrame += numFrames;
currentFrame %= numFrames;
setCurrentFrameDelayFromTable();
@@ -670,8 +696,47 @@ struct PNGDisplay : TransparentWidget {
if (blankModule && blankModule->loadedJSON) {
if (blankModule->mappedFrame != currentFrame) {
currentFrame = blankModule->mappedFrame;
-
}
+ if (blankModule->scrubbing) {
+ currentFrame = blankModule->scrubFrame;
+ }
+ }
+ TransparentWidget::step();
+ }
+};
+
+struct GiantFrameDisplay : TransparentWidget {
+ ComputerscareBlank *module;
+ SmallLetterDisplay *description;
+ SmallLetterDisplay *frameDisplay;
+ GiantFrameDisplay() {
+ box.size = Vec(200,380);
+
+ description = new SmallLetterDisplay();
+ description->value = "Frame Zero, for EOC output and reset input";
+ description->fontSize = 24;
+ description->breakRowWidth = 200.f;
+ description->box.pos.y = box.size.y - 130;
+
+
+ frameDisplay = new SmallLetterDisplay();
+ frameDisplay->fontSize = 90;
+ frameDisplay->box.size = Vec(300, 120);
+ frameDisplay->textOffset = Vec(0, 50);
+ frameDisplay->box.pos.y = box.size.y - 200;
+ frameDisplay->breakRowWidth = 200.f;
+ frameDisplay->baseColor = nvgRGBAf(0.8, 0.8, 0.8, 0.7);
+
+
+
+ addChild(frameDisplay);
+ addChild(description);
+ TransparentWidget();
+ }
+ void step() {
+ if (module) {
+ visible = module->scrubbing;
+ frameDisplay->value = string::f("%i / %i", module->scrubFrame + 1, module->numFrames);
}
TransparentWidget::step();
}
@@ -720,15 +785,41 @@ struct ComputerscareBlankWidget : MenuParamModuleWidget {
addChild(leftHandle);
addChild(rightHandle);
+ frameDisplay = new GiantFrameDisplay();
+ frameDisplay->module = blankModule;
+ addChild(frameDisplay);
+
}
void appendContextMenu(Menu* menu) override {
ComputerscareBlank* blank = dynamic_cast<ComputerscareBlank*>(this->blankModule);
+
+ Strongbipper *modeMenu = new Strongbipper();
+ modeMenu->text = "Animation Mode";
+ modeMenu->rightText = RIGHT_ARROW;
+ modeMenu->param = blankModule->paramQuantities[ComputerscareBlank::ANIMATION_MODE];
+ modeMenu->options = blankModule->animationModeDescriptions;
+
+
+
+
+
+ Strongbipper *endMenu = new Strongbipper();
+ endMenu->text = "Animation End Behavior";
+ endMenu->rightText = RIGHT_ARROW;
+ endMenu->param = blankModule->paramQuantities[ComputerscareBlank::END_BEHAVIOR];
+ endMenu->options = blankModule->endBehaviorDescriptions;
+
+
+
menu->addChild(new MenuEntry);
//menu->addChild(construct<MenuLabel>(&MenuLabel::text, "Keyboard Controls:"));
+ menu->addChild(modeMenu);
+ menu->addChild(endMenu);
+
KeyboardControlChildMenu *kbMenu = new KeyboardControlChildMenu();
kbMenu->text = "Keyboard Controls";
kbMenu->rightText = RIGHT_ARROW;
@@ -778,23 +869,6 @@ struct ComputerscareBlankWidget : MenuParamModuleWidget {
- Strongbipper *modeMenu = new Strongbipper();
- modeMenu->text = "Animation Mode";
- modeMenu->rightText = RIGHT_ARROW;
- modeMenu->param = blankModule->paramQuantities[ComputerscareBlank::ANIMATION_MODE];
- modeMenu->options = blankModule->animationModeDescriptions;
-
- menu->addChild(modeMenu);
-
-
-
- Strongbipper *endMenu = new Strongbipper();
- endMenu->text = "Animation End Behavior";
- endMenu->rightText = RIGHT_ARROW;
- endMenu->param = blankModule->paramQuantities[ComputerscareBlank::END_BEHAVIOR];
- endMenu->options = blankModule->endBehaviorDescriptions;
-
- menu->addChild(endMenu);
@@ -920,7 +994,7 @@ struct ComputerscareBlankWidget : MenuParamModuleWidget {
TransparentWidget *display;
ComputerscareResizeHandle *leftHandle;
ComputerscareResizeHandle *rightHandle;
- SmallLetterDisplay* smallLetterDisplay;
+ GiantFrameDisplay* frameDisplay;
};
diff --git a/src/ComputerscareBlankExpander.cpp b/src/ComputerscareBlankExpander.cpp
@@ -1,24 +1,29 @@
#include "Computerscare.hpp"
+#include "CustomBlankFunctions.hpp"
struct ComputerscareBlankExpander;
- struct FrameOffsetParam : ParamQuantity {
- ComputerscareBlankExpander* module;
- int numFrames = -1;
- void setNumFrames(int num) { numFrames = num; }
- std::string getDisplayValueString() override {
- //return &module->params[paramId];
- float val = getValue();
- return string::f("%i", 1+((int) floor(val * numFrames )) % numFrames/*module->getFrameOffset()*/ );
- //return "Frame " +((std:: string)val);//+ ((int) floor(val * module->numFrames * 0.999)) % module->numFrames;
- }
- };
+
+struct FrameOffsetParam : ParamQuantity {
+ ComputerscareBlankExpander* module;
+ int numFrames = -1;
+ void setNumFrames(int num) { numFrames = num; }
+ std::string getDisplayValueString() override {
+ //return &module->params[paramId];
+ float val = getValue();
+ return string::f("%i", 1 + mapBlankFrameOffset(val,numFrames));
+ }
+};
+
+
struct ComputerscareBlankExpander : Module {
- float rightMessages[2][8] = {};
+ float rightMessages[2][10] = {};
bool isConnected = false;
float lastFrame = -1;
int numFrames = 1;
+ bool scrubbing = false;
+
enum ParamIds {
CLOCK_MODE,
@@ -83,7 +88,7 @@ struct ComputerscareBlankExpander : Module {
float currentFrame = messageFromMother[0];
int newNumFrames = messageFromMother[1];
- if(newNumFrames != numFrames) {
+ if (newNumFrames != numFrames) {
numFrames = newNumFrames;
frameOffsetQuantity->setNumFrames(numFrames);
}
@@ -111,6 +116,9 @@ struct ComputerscareBlankExpander : Module {
messageToSendToMother[7] = params[ZERO_OFFSET].getValue();
+ messageToSendToMother[8] = scrubbing;
+
+
outputs[EOC_OUTPUT].setVoltage(eocPulse.process(args.sampleTime) ? 10.f : 0.f);
outputs[EACH_FRAME_OUTPUT].setVoltage(eachFramePulse.process(args.sampleTime) ? 10.f : 0.f);
@@ -122,6 +130,23 @@ struct ComputerscareBlankExpander : Module {
// No mother module is connected.
}
}
+ void setScrubbing(bool scrub) {
+ scrubbing = scrub;
+ }
+};
+struct FrameScrubKnob : SmallKnob {
+ ComputerscareBlankExpander* module;
+ void onDragStart(const event::DragStart& e) override {
+ module->setScrubbing(true);
+ SmallKnob::onDragStart(e);
+ }
+ void onDragEnd(const event::DragEnd& e) override {
+ module->setScrubbing(false);
+ SmallKnob::onDragEnd(e);
+ }
+ void onDragMove(const event::DragMove& e) override {
+ SmallKnob::onDragMove(e);
+ };
};
struct ClockModeButton : app::SvgSwitch {
ClockModeButton() {
@@ -158,13 +183,16 @@ struct ComputerscareBlankExpanderWidget : ModuleWidget {
addOutput(createOutput<PointingUpPentagonPort>(Vec(2, outStartY), module, ComputerscareBlankExpander::EACH_FRAME_OUTPUT));
+ frameOffsetKnob = createParam<FrameScrubKnob>(Vec(6, outStartY + dY), module, ComputerscareBlankExpander::ZERO_OFFSET);
+ frameOffsetKnob->module = module;
- addParam(createParam<SmallKnob>(Vec(4, outStartY + dY), module, ComputerscareBlankExpander::ZERO_OFFSET));
- addOutput(createOutput<PointingUpPentagonPort>(Vec(2, outStartY + dY * 1.5), module, ComputerscareBlankExpander::EOC_OUTPUT));
+ addParam(frameOffsetKnob);
+ addOutput(createOutput<PointingUpPentagonPort>(Vec(2, outStartY + dY * 1.6), module, ComputerscareBlankExpander::EOC_OUTPUT));
}
void step() {
ModuleWidget::step();
}
+ FrameScrubKnob* frameOffsetKnob;
};
Model *modelComputerscareBlankExpander = createModel<ComputerscareBlankExpander, ComputerscareBlankExpanderWidget>("computerscare-blank-expander");
diff --git a/src/CustomBlankFunctions.hpp b/src/CustomBlankFunctions.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+inline int mapBlankFrameOffset(float uniformVal,int numFrames) {
+ return numFrames > 0 ? ((int) floor(uniformVal * numFrames )) % numFrames : 0;
+ }
+\ No newline at end of file
diff --git a/src/MenuParams.hpp b/src/MenuParams.hpp
@@ -69,7 +69,7 @@ struct MenuParam : MenuEntry {
}
speedParam->paramQuantity = param;
speedParam->box.pos = Vec(controlRightMargin, 0);
- box.size.y = 38;
+ box.size.y = 32;
johnLabel = construct<MenuLabel>(&MenuLabel::text, param->getLabel());
johnLabel->box.pos = Vec(speedParam->box.size.x + controlRightMargin * 2, 0);