|
|
@@ -382,8 +382,9 @@ struct Marbles : Module { |
|
|
|
lights[T_DEJA_VU_LIGHT].setBrightness(t_deja_vu); |
|
|
|
lights[X_DEJA_VU_LIGHT].setBrightness(x_deja_vu); |
|
|
|
|
|
|
|
lights[T_MODE_LIGHTS + 0].setBrightness(t_mode == 0 || t_mode == 1); |
|
|
|
lights[T_MODE_LIGHTS + 1].setBrightness(t_mode == 1 || t_mode == 2); |
|
|
|
int t_mode3 = t_mode % 3; |
|
|
|
lights[T_MODE_LIGHTS + 0].setBrightness(t_mode3 == 0 || t_mode3 == 1); |
|
|
|
lights[T_MODE_LIGHTS + 1].setBrightness(t_mode3 == 1 || t_mode3 == 2); |
|
|
|
|
|
|
|
lights[X_MODE_LIGHTS + 0].setBrightness(x_mode == 0 || x_mode == 1); |
|
|
|
lights[X_MODE_LIGHTS + 1].setBrightness(x_mode == 1 || x_mode == 2); |
|
|
@@ -525,6 +526,38 @@ struct CKD6Light : BASE { |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
MenuItem* createIndexMenu(int* ptr, std::string name, std::vector<std::string> labels) { |
|
|
|
struct IndexItem : MenuItem { |
|
|
|
int* ptr; |
|
|
|
int index; |
|
|
|
void onAction(const event::Action& e) override { |
|
|
|
*ptr = index; |
|
|
|
} |
|
|
|
}; |
|
|
|
struct Item : MenuItem { |
|
|
|
int* ptr; |
|
|
|
std::vector<std::string> labels; |
|
|
|
Menu* createChildMenu() override { |
|
|
|
Menu* menu = new Menu(); |
|
|
|
for (int i = 0; i < (int) labels.size(); i++) { |
|
|
|
IndexItem* item = createMenuItem<IndexItem>(labels[i], CHECKMARK(*ptr == i)); |
|
|
|
item->ptr = ptr; |
|
|
|
item->index = i; |
|
|
|
menu->addChild(item); |
|
|
|
} |
|
|
|
return menu; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
int index = *ptr; |
|
|
|
std::string label = (0 <= index && index < (int) labels.size()) ? labels[index] : ""; |
|
|
|
Item* item = createMenuItem<Item>(name, label); |
|
|
|
item->ptr = ptr; |
|
|
|
item->labels = labels; |
|
|
|
return item; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
struct MarblesWidget : ModuleWidget { |
|
|
|
MarblesWidget(Marbles* module) { |
|
|
|
setModule(module); |
|
|
@@ -588,94 +621,66 @@ struct MarblesWidget : ModuleWidget { |
|
|
|
void appendContextMenu(Menu* menu) override { |
|
|
|
Marbles* module = dynamic_cast<Marbles*>(this->module); |
|
|
|
|
|
|
|
struct ScaleItem : MenuItem { |
|
|
|
Marbles* module; |
|
|
|
int scale; |
|
|
|
void onAction(const event::Action& e) override { |
|
|
|
module->x_scale = scale; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
menu->addChild(new MenuSeparator); |
|
|
|
menu->addChild(createMenuLabel("Scales")); |
|
|
|
const std::string scaleLabels[] = { |
|
|
|
|
|
|
|
menu->addChild(createIndexMenu(&module->t_mode, "t mode", { |
|
|
|
"Complementary Bernoulli", |
|
|
|
"Clusters", |
|
|
|
"Drums", |
|
|
|
"Independent Bernoulli", |
|
|
|
"Divider", |
|
|
|
"Three states", |
|
|
|
"Markov", |
|
|
|
})); |
|
|
|
|
|
|
|
menu->addChild(createIndexMenu(&module->t_range, "t range", { |
|
|
|
"1/4x", |
|
|
|
"1x", |
|
|
|
"4x", |
|
|
|
})); |
|
|
|
|
|
|
|
menu->addChild(createIndexMenu(&module->x_mode, "X mode", { |
|
|
|
"Identical", |
|
|
|
"Bump", |
|
|
|
"Tilt", |
|
|
|
})); |
|
|
|
|
|
|
|
menu->addChild(createIndexMenu(&module->x_range, "X range", { |
|
|
|
"Narrow", |
|
|
|
"Positive", |
|
|
|
"Full", |
|
|
|
})); |
|
|
|
|
|
|
|
menu->addChild(createIndexMenu(&module->x_scale, "Scales", { |
|
|
|
"Major", |
|
|
|
"Minor", |
|
|
|
"Pentatonic", |
|
|
|
"Pelog", |
|
|
|
"Raag Bhairav That", |
|
|
|
"Raag Shri", |
|
|
|
}; |
|
|
|
for (int i = 0; i < (int) LENGTHOF(scaleLabels); i++) { |
|
|
|
ScaleItem* item = createMenuItem<ScaleItem>(scaleLabels[i], CHECKMARK(module->x_scale == i)); |
|
|
|
item->module = module; |
|
|
|
item->scale = i; |
|
|
|
menu->addChild(item); |
|
|
|
} |
|
|
|
})); |
|
|
|
|
|
|
|
struct XClockSourceInternal : MenuItem { |
|
|
|
Marbles* module; |
|
|
|
int source; |
|
|
|
void onAction(const event::Action& e) override { |
|
|
|
module->x_clock_source_internal = source; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
menu->addChild(new MenuSeparator); |
|
|
|
menu->addChild(createMenuLabel("Internal X clock source")); |
|
|
|
const std::string sourceLabels[] = { |
|
|
|
menu->addChild(createIndexMenu(&module->x_clock_source_internal, "Internal X clock source", { |
|
|
|
"T₁ → X₁, T₂ → X₂, T₃ → X₃", |
|
|
|
"T₁ → X₁, X₂, X₃", |
|
|
|
"T₂ → X₁, X₂, X₃", |
|
|
|
"T₃ → X₁, X₂, X₃", |
|
|
|
}; |
|
|
|
for (int i = 0; i < (int) LENGTHOF(sourceLabels); i++) { |
|
|
|
XClockSourceInternal* item = createMenuItem<XClockSourceInternal>(sourceLabels[i], CHECKMARK(module->x_clock_source_internal == i)); |
|
|
|
item->module = module; |
|
|
|
item->source = i; |
|
|
|
menu->addChild(item); |
|
|
|
} |
|
|
|
|
|
|
|
struct YDividerIndexItem : MenuItem { |
|
|
|
Marbles* module; |
|
|
|
int index; |
|
|
|
void onAction(const event::Action& e) override { |
|
|
|
module->y_divider_index = index; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
struct YDividerItem : MenuItem { |
|
|
|
Marbles* module; |
|
|
|
Menu* createChildMenu() override { |
|
|
|
Menu* menu = new Menu(); |
|
|
|
const std::string yDividerRatioLabels[] = { |
|
|
|
"1/64", |
|
|
|
"1/48", |
|
|
|
"1/32", |
|
|
|
"1/24", |
|
|
|
"1/16", |
|
|
|
"1/12", |
|
|
|
"1/8", |
|
|
|
"1/6", |
|
|
|
"1/4", |
|
|
|
"1/3", |
|
|
|
"1/2", |
|
|
|
"1", |
|
|
|
}; |
|
|
|
for (int i = 0; i < (int) LENGTHOF(yDividerRatioLabels); i++) { |
|
|
|
YDividerIndexItem* item = createMenuItem<YDividerIndexItem>(yDividerRatioLabels[i], CHECKMARK(module->y_divider_index == i)); |
|
|
|
item->module = module; |
|
|
|
item->index = i; |
|
|
|
menu->addChild(item); |
|
|
|
} |
|
|
|
return menu; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
menu->addChild(new MenuSeparator); |
|
|
|
YDividerItem* yDividerItem = createMenuItem<YDividerItem>("Y divider ratio"); |
|
|
|
yDividerItem->module = module; |
|
|
|
menu->addChild(yDividerItem); |
|
|
|
})); |
|
|
|
|
|
|
|
menu->addChild(createIndexMenu(&module->y_divider_index, "Y divider ratio", { |
|
|
|
"1/64", |
|
|
|
"1/48", |
|
|
|
"1/32", |
|
|
|
"1/24", |
|
|
|
"1/16", |
|
|
|
"1/12", |
|
|
|
"1/8", |
|
|
|
"1/6", |
|
|
|
"1/4", |
|
|
|
"1/3", |
|
|
|
"1/2", |
|
|
|
"1", |
|
|
|
})); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|