|
|
@@ -331,90 +331,102 @@ struct FramesWidget : ModuleWidget { |
|
|
|
} |
|
|
|
|
|
|
|
void appendContextMenu(Menu* menu) override { |
|
|
|
Frames* frames = dynamic_cast<Frames*>(module); |
|
|
|
assert(frames); |
|
|
|
Frames* module = dynamic_cast<Frames*>(this->module); |
|
|
|
assert(module); |
|
|
|
|
|
|
|
struct FramesCurveItem : MenuItem { |
|
|
|
Frames* frames; |
|
|
|
Frames* module; |
|
|
|
uint8_t channel; |
|
|
|
frames::EasingCurve curve; |
|
|
|
void onAction(const event::Action& e) override { |
|
|
|
frames->keyframer.mutable_settings(channel)->easing_curve = curve; |
|
|
|
module->keyframer.mutable_settings(channel)->easing_curve = curve; |
|
|
|
} |
|
|
|
void step() override { |
|
|
|
rightText = (frames->keyframer.mutable_settings(channel)->easing_curve == curve) ? "✔" : ""; |
|
|
|
rightText = (module->keyframer.mutable_settings(channel)->easing_curve == curve) ? "✔" : ""; |
|
|
|
MenuItem::step(); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
struct FramesResponseItem : MenuItem { |
|
|
|
Frames* frames; |
|
|
|
Frames* module; |
|
|
|
uint8_t channel; |
|
|
|
uint8_t response; |
|
|
|
void onAction(const event::Action& e) override { |
|
|
|
frames->keyframer.mutable_settings(channel)->response = response; |
|
|
|
module->keyframer.mutable_settings(channel)->response = response; |
|
|
|
} |
|
|
|
void step() override { |
|
|
|
rightText = (frames->keyframer.mutable_settings(channel)->response == response) ? "✔" : ""; |
|
|
|
rightText = (module->keyframer.mutable_settings(channel)->response == response) ? "✔" : ""; |
|
|
|
MenuItem::step(); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
struct FramesChannelSettingsItem : MenuItem { |
|
|
|
Frames* frames; |
|
|
|
Frames* module; |
|
|
|
uint8_t channel; |
|
|
|
Menu* createChildMenu() override { |
|
|
|
Menu* menu = new Menu(); |
|
|
|
|
|
|
|
menu->addChild(construct<MenuLabel>(&MenuLabel::text, string::f("Channel %d", channel + 1))); |
|
|
|
menu->addChild(new MenuSeparator); |
|
|
|
menu->addChild(createMenuLabel("Interpolation curve")); |
|
|
|
|
|
|
|
static const std::vector<std::string> curveLabels = { |
|
|
|
"Step", |
|
|
|
"Linear", |
|
|
|
"Accelerating", |
|
|
|
"Decelerating", |
|
|
|
"Departure/arrival", |
|
|
|
"Bouncing", |
|
|
|
}; |
|
|
|
for (int i = 0; i < (int) curveLabels.size(); i++) { |
|
|
|
menu->addChild(createCheckMenuItem(curveLabels[i], |
|
|
|
[=]() {return module->keyframer.mutable_settings(channel)->easing_curve == i;}, |
|
|
|
[=]() {module->keyframer.mutable_settings(channel)->easing_curve = (frames::EasingCurve) i;} |
|
|
|
)); |
|
|
|
} |
|
|
|
|
|
|
|
menu->addChild(construct<MenuLabel>(&MenuLabel::text, "Interpolation Curve")); |
|
|
|
menu->addChild(construct<FramesCurveItem>(&MenuItem::text, "Step", &FramesCurveItem::frames, frames, &FramesCurveItem::channel, channel, &FramesCurveItem::curve, frames::EASING_CURVE_STEP)); |
|
|
|
menu->addChild(construct<FramesCurveItem>(&MenuItem::text, "Linear", &FramesCurveItem::frames, frames, &FramesCurveItem::channel, channel, &FramesCurveItem::curve, frames::EASING_CURVE_LINEAR)); |
|
|
|
menu->addChild(construct<FramesCurveItem>(&MenuItem::text, "Accelerating", &FramesCurveItem::frames, frames, &FramesCurveItem::channel, channel, &FramesCurveItem::curve, frames::EASING_CURVE_IN_QUARTIC)); |
|
|
|
menu->addChild(construct<FramesCurveItem>(&MenuItem::text, "Decelerating", &FramesCurveItem::frames, frames, &FramesCurveItem::channel, channel, &FramesCurveItem::curve, frames::EASING_CURVE_OUT_QUARTIC)); |
|
|
|
menu->addChild(construct<FramesCurveItem>(&MenuItem::text, "Smooth Departure/Arrival", &FramesCurveItem::frames, frames, &FramesCurveItem::channel, channel, &FramesCurveItem::curve, frames::EASING_CURVE_SINE)); |
|
|
|
menu->addChild(construct<FramesCurveItem>(&MenuItem::text, "Bouncing", &FramesCurveItem::frames, frames, &FramesCurveItem::channel, channel, &FramesCurveItem::curve, frames::EASING_CURVE_BOUNCE)); |
|
|
|
menu->addChild(new MenuSeparator); |
|
|
|
menu->addChild(construct<MenuLabel>(&MenuLabel::text, "Response Curve")); |
|
|
|
menu->addChild(construct<FramesResponseItem>(&MenuItem::text, "Linear", &FramesResponseItem::frames, frames, &FramesResponseItem::channel, channel, &FramesResponseItem::response, 0)); |
|
|
|
menu->addChild(construct<FramesResponseItem>(&MenuItem::text, "Exponential", &FramesResponseItem::frames, frames, &FramesResponseItem::channel, channel, &FramesResponseItem::response, 255)); |
|
|
|
|
|
|
|
return menu; |
|
|
|
} |
|
|
|
}; |
|
|
|
menu->addChild(createMenuLabel("Response curve")); |
|
|
|
|
|
|
|
struct FramesClearItem : MenuItem { |
|
|
|
Frames* frames; |
|
|
|
void onAction(const event::Action& e) override { |
|
|
|
frames->keyframer.Clear(); |
|
|
|
} |
|
|
|
}; |
|
|
|
menu->addChild(createCheckMenuItem("Linear", |
|
|
|
[=]() {return module->keyframer.mutable_settings(channel)->response == 0;}, |
|
|
|
[=]() {module->keyframer.mutable_settings(channel)->response = 0;} |
|
|
|
)); |
|
|
|
menu->addChild(createCheckMenuItem("Exponential", |
|
|
|
[=]() {return module->keyframer.mutable_settings(channel)->response == 255;}, |
|
|
|
[=]() {module->keyframer.mutable_settings(channel)->response = 255;} |
|
|
|
)); |
|
|
|
|
|
|
|
struct FramesModeItem : MenuItem { |
|
|
|
Frames* frames; |
|
|
|
bool poly_lfo_mode; |
|
|
|
void onAction(const event::Action& e) override { |
|
|
|
frames->poly_lfo_mode = poly_lfo_mode; |
|
|
|
} |
|
|
|
void step() override { |
|
|
|
rightText = (frames->poly_lfo_mode == poly_lfo_mode) ? "✔" : ""; |
|
|
|
MenuItem::step(); |
|
|
|
return menu; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
menu->addChild(new MenuSeparator); |
|
|
|
menu->addChild(construct<MenuLabel>(&MenuLabel::text, "Channel Settings")); |
|
|
|
menu->addChild(createMenuLabel("Channel settings")); |
|
|
|
|
|
|
|
for (int i = 0; i < 4; i++) { |
|
|
|
menu->addChild(construct<FramesChannelSettingsItem>(&MenuItem::text, string::f("Channel %d", i + 1), &FramesChannelSettingsItem::frames, frames, &FramesChannelSettingsItem::channel, i)); |
|
|
|
FramesChannelSettingsItem* item = createMenuItem<FramesChannelSettingsItem>(string::f("Channel %d", i + 1)); |
|
|
|
item->module = module; |
|
|
|
item->channel = i; |
|
|
|
menu->addChild(item); |
|
|
|
} |
|
|
|
menu->addChild(construct<FramesClearItem>(&MenuItem::text, "Clear Keyframes", &FramesClearItem::frames, frames)); |
|
|
|
|
|
|
|
menu->addChild(createMenuItem("Clear keyframes", "", |
|
|
|
[=]() {module->keyframer.Clear();} |
|
|
|
)); |
|
|
|
|
|
|
|
menu->addChild(new MenuSeparator); |
|
|
|
menu->addChild(construct<MenuLabel>(&MenuLabel::text, "Mode")); |
|
|
|
menu->addChild(construct<FramesModeItem>(&MenuItem::text, "Keyframer", &FramesModeItem::frames, frames, &FramesModeItem::poly_lfo_mode, false)); |
|
|
|
menu->addChild(construct<FramesModeItem>(&MenuItem::text, "Poly LFO", &FramesModeItem::frames, frames, &FramesModeItem::poly_lfo_mode, true)); |
|
|
|
menu->addChild(createMenuLabel("Alternate modes")); |
|
|
|
|
|
|
|
static const std::vector<std::string> modeLabels = { |
|
|
|
"Keyframer", |
|
|
|
"Poly LFO", |
|
|
|
}; |
|
|
|
for (int i = 0; i < (int) modeLabels.size(); i++) { |
|
|
|
menu->addChild(createCheckMenuItem(modeLabels[i], |
|
|
|
[=]() {return module->poly_lfo_mode == i;}, |
|
|
|
[=]() {module->poly_lfo_mode = i;} |
|
|
|
)); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|