GUI: is the macro UI back yet

This commit is contained in:
tildearrow 2022-05-06 23:52:26 -05:00
parent b2953e00fe
commit aea7bf2112
2 changed files with 178 additions and 171 deletions

View file

@ -723,6 +723,34 @@ struct FurnaceGUISysCategory {
name(NULL) {} name(NULL) {}
}; };
struct FurnaceGUIMacroDesc {
DivInstrumentMacro* macro;
int min, max;
float height;
const char* displayName;
const char** bitfieldBits;
const char* modeName;
ImVec4 color;
unsigned int bitOffset;
bool isBitfield, blockMode;
String (*hoverFunc)(int,float);
FurnaceGUIMacroDesc(const char* name, DivInstrumentMacro* m, int macroMin, int macroMax, float macroHeight, ImVec4 col=ImVec4(1.0f,1.0f,1.0f,1.0f), bool block=false, const char* mName=NULL, String (*hf)(int,float)=NULL, bool bitfield=false, const char** bfVal=NULL, unsigned int bitOff=0):
macro(m),
min(macroMin),
max(macroMax),
height(macroHeight),
displayName(name),
bitfieldBits(bfVal),
modeName(mName),
color(col),
bitOffset(bitOff),
isBitfield(bitfield),
blockMode(block),
hoverFunc(hf) {
}
};
class FurnaceGUI { class FurnaceGUI {
DivEngine* e; DivEngine* e;
@ -1161,6 +1189,8 @@ class FurnaceGUI {
void patternRow(int i, bool isPlaying, float lineHeight, int chans, int ord, const DivPattern** patCache, bool inhibitSel); void patternRow(int i, bool isPlaying, float lineHeight, int chans, int ord, const DivPattern** patCache, bool inhibitSel);
void drawMacros(std::vector<FurnaceGUIMacroDesc>& macros);
void actualWaveList(); void actualWaveList();
void actualSampleList(); void actualSampleList();

View file

@ -1067,164 +1067,153 @@ void FurnaceGUI::drawGBEnv(unsigned char vol, unsigned char len, unsigned char s
#define PARAMETER MARK_MODIFIED; e->notifyInsChange(curIns); #define PARAMETER MARK_MODIFIED; e->notifyInsChange(curIns);
struct FurnaceGUIMacroDesc { void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
DivInstrumentMacro* macro; float asFloat[256];
int min, max; int asInt[256];
float height; float loopIndicator[256];
const char* displayName; int index=0;
const char** bitfieldBits;
const char* modeName;
ImVec4 color;
unsigned int bitOffset;
bool isBitfield, blockMode;
String (*hoverFunc)(int,float);
FurnaceGUIMacroDesc(const char* name, DivInstrumentMacro* m, int macroMin, int macroMax, float macroHeight, ImVec4 col=ImVec4(1.0f,1.0f,1.0f,1.0f), bool block=false, const char* mName=NULL, String (*hf)(int,float)=NULL, bool bitfield=false, const char** bfVal=NULL, unsigned int bitOff=0): float reservedSpace=ImGui::GetContentRegionAvail().x-28.0f*dpiScale;
macro(m),
min(macroMin), if (ImGui::BeginTable("MacroSpace",2)) {
max(macroMax), ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,0.0);
height(macroHeight), ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0);
displayName(name), ImGui::TableNextRow();
bitfieldBits(bfVal), ImGui::TableNextColumn();
modeName(mName), float lenAvail=ImGui::GetContentRegionAvail().x;
color(col), ImGui::Dummy(ImVec2(120.0f*dpiScale,dpiScale));
bitOffset(bitOff), ImGui::TableNextColumn();
isBitfield(bitfield), float availableWidth=ImGui::GetContentRegionAvail().x-reservedSpace;
blockMode(block), int totalFit=MIN(128,availableWidth/MAX(1,macroPointSize*dpiScale));
hoverFunc(hf) { if (macroDragScroll>128-totalFit) {
macroDragScroll=128-totalFit;
}
ImGui::SetNextItemWidth(availableWidth);
if (CWSliderInt("##MacroScroll",&macroDragScroll,0,128-totalFit,"")) {
if (macroDragScroll<0) macroDragScroll=0;
if (macroDragScroll>128-totalFit) macroDragScroll=128-totalFit;
} }
};
#define NORMAL_MACRO(macro,macroMin,macroHeight,macroName,displayName,displayHeight,displayLoop,bitfield,bfVal,drawSlider,sliderVal,sliderLow,sliderHigh,macroDispMin,bitOff,macroMode,macroModeMax,displayModeName,macroColor,mmlStr,macroAMin,macroAMax,hoverFunc,blockMode) \ // draw macros
ImGui::TableNextRow(); \ for (FurnaceGUIMacroDesc& i: macros) {
ImGui::TableNextColumn(); \ ImGui::PushID(index);
ImGui::Text("%s",displayName); \ ImGui::TableNextRow();
ImGui::SameLine(); \
if (ImGui::SmallButton(displayLoop?(ICON_FA_CHEVRON_UP "##IMacroOpen_" macroName):(ICON_FA_CHEVRON_DOWN "##IMacroOpen_" macroName))) { \ // description
displayLoop=!displayLoop; \ ImGui::TableNextColumn();
} \ ImGui::Text("%s",i.displayName);
if (displayLoop) { \ ImGui::SameLine();
ImGui::SetNextItemWidth(lenAvail); \ if (ImGui::SmallButton(i.macro->open?(ICON_FA_CHEVRON_UP "##IMacroOpen"):(ICON_FA_CHEVRON_DOWN "##IMacroOpen"))) {
if (ImGui::InputScalar("##IMacroLen_" macroName,ImGuiDataType_U8,&macro.len,&_ONE,&_THREE)) { MARK_MODIFIED \ i.macro->open=!i.macro->open;
if (macro.len>128) macro.len=128; \ }
} \ if (i.macro->open) {
if (macroMode) { \ ImGui::SetNextItemWidth(lenAvail);
bool modeVal=macro.mode; \ if (ImGui::InputScalar("##IMacroLen",ImGuiDataType_U8,&i.macro->len,&_ONE,&_THREE)) { MARK_MODIFIED
String modeName=fmt::sprintf("%s##IMacroMode_" macroName,displayModeName); \ if (i.macro->len>128) i.macro->len=128;
if (ImGui::Checkbox(modeName.c_str(),&modeVal)) { \ }
macro.mode=modeVal; \ if (i.modeName!=NULL) {
} \ bool modeVal=i.macro->mode;
} \ String modeName=fmt::sprintf("%s##IMacroMode",i.modeName);
} \ if (ImGui::Checkbox(modeName.c_str(),&modeVal)) {
ImGui::TableNextColumn(); \ i.macro->mode=modeVal;
for (int j=0; j<256; j++) { \ }
if (j+macroDragScroll>=macro.len) { \ }
asFloat[j]=0; \ }
asInt[j]=0; \
} else { \ // macro area
asFloat[j]=macro.val[j+macroDragScroll]+macroDispMin; \ ImGui::TableNextColumn();
asInt[j]=macro.val[j+macroDragScroll]+macroDispMin+bitOff; \ for (int j=0; j<256; j++) {
} \ if (j+macroDragScroll>=i.macro->len) {
if (j+macroDragScroll>=macro.len || (j+macroDragScroll>macro.rel && macro.loop<macro.rel)) { \ asFloat[j]=0;
loopIndicator[j]=0; \ asInt[j]=0;
} else { \ } else {
loopIndicator[j]=((macro.loop!=-1 && (j+macroDragScroll)>=macro.loop))|((macro.rel!=-1 && (j+macroDragScroll)==macro.rel)<<1); \ asFloat[j]=i.macro->val[j+macroDragScroll];
} \ asInt[j]=i.macro->val[j+macroDragScroll]+i.bitOffset;
} \ }
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0.0f,0.0f)); \ if (j+macroDragScroll>=i.macro->len || (j+macroDragScroll>i.macro->rel && i.macro->loop<i.macro->rel)) {
\ loopIndicator[j]=0;
if (bitfield) { \ } else {
PlotBitfield("##IMacro_" macroName,asInt,totalFit,0,bfVal,macroHeight,ImVec2(availableWidth,(displayLoop)?(displayHeight*dpiScale):(32.0f*dpiScale))); \ loopIndicator[j]=((i.macro->loop!=-1 && (j+macroDragScroll)>=i.macro->loop))|((i.macro->rel!=-1 && (j+macroDragScroll)==i.macro->rel)<<1);
} else { \ }
PlotCustom("##IMacro_" macroName,asFloat,totalFit,macroDragScroll,NULL,macroDispMin+macroMin,macroHeight+macroDispMin,ImVec2(availableWidth,(displayLoop)?(displayHeight*dpiScale):(32.0f*dpiScale)),sizeof(float),macroColor,macro.len-macroDragScroll,hoverFunc,blockMode); \ }
} \ ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0.0f,0.0f));
if (displayLoop && (ImGui::IsItemClicked(ImGuiMouseButton_Left) || ImGui::IsItemClicked(ImGuiMouseButton_Right))) { \
macroDragStart=ImGui::GetItemRectMin(); \ if (i.isBitfield) {
macroDragAreaSize=ImVec2(availableWidth,displayHeight*dpiScale); \ PlotBitfield("##IMacro",asInt,totalFit,0,i.bitfieldBits,i.max,ImVec2(availableWidth,(i.macro->open)?(i.height*dpiScale):(32.0f*dpiScale)));
macroDragMin=macroMin; \ } else {
macroDragMax=macroHeight; \ PlotCustom("##IMacro",asFloat,totalFit,macroDragScroll,NULL,i.min,i.max,ImVec2(availableWidth,(i.macro->open)?(i.height*dpiScale):(32.0f*dpiScale)),sizeof(float),i.color,i.macro->len-macroDragScroll,i.hoverFunc,i.blockMode);
macroDragBitOff=bitOff; \ }
macroDragBitMode=bitfield; \ if (i.macro->open && (ImGui::IsItemClicked(ImGuiMouseButton_Left) || ImGui::IsItemClicked(ImGuiMouseButton_Right))) {
macroDragInitialValueSet=false; \ macroDragStart=ImGui::GetItemRectMin();
macroDragInitialValue=false; \ macroDragAreaSize=ImVec2(availableWidth,i.height*dpiScale);
macroDragLen=totalFit; \ macroDragMin=i.min;
macroDragActive=true; \ macroDragMax=i.max;
macroDragTarget=macro.val; \ macroDragBitOff=i.bitOffset;
macroDragChar=false; \ macroDragBitMode=i.isBitfield;
macroDragLineMode=(bitfield)?false:ImGui::IsItemClicked(ImGuiMouseButton_Right); \ macroDragInitialValueSet=false;
macroDragLineInitial=ImVec2(0,0); \ macroDragInitialValue=false;
processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y); \ macroDragLen=totalFit;
} \ macroDragActive=true;
if (displayLoop) { \ macroDragTarget=i.macro->val;
if (ImGui::IsItemHovered() && ctrlWheeling) { \ macroDragChar=false;
macroPointSize+=wheelY; \ macroDragLineMode=(i.isBitfield)?false:ImGui::IsItemClicked(ImGuiMouseButton_Right);
if (macroPointSize<1) macroPointSize=1; \ macroDragLineInitial=ImVec2(0,0);
if (macroPointSize>256) macroPointSize=256; \ processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y);
} \ }
if (drawSlider) { \ if (i.macro->open) {
ImGui::SameLine(); \ if (ImGui::IsItemHovered() && ctrlWheeling) {
CWVSliderInt("##IMacroPos_" macroName,ImVec2(20.0f*dpiScale,displayHeight*dpiScale),sliderVal,sliderLow,sliderHigh); \ macroPointSize+=wheelY;
} \ if (macroPointSize<1) macroPointSize=1;
PlotCustom("##IMacroLoop_" macroName,loopIndicator,totalFit,macroDragScroll,NULL,0,2,ImVec2(availableWidth,12.0f*dpiScale),sizeof(float),macroColor,macro.len-macroDragScroll,&macroHoverLoop); \ if (macroPointSize>256) macroPointSize=256;
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) { \ }
macroLoopDragStart=ImGui::GetItemRectMin(); \ /*if (drawSlider) {
macroLoopDragAreaSize=ImVec2(availableWidth,12.0f*dpiScale); \ ImGui::SameLine();
macroLoopDragLen=totalFit; \ CWVSliderInt("##IMacroPos",ImVec2(20.0f*dpiScale,i.height*dpiScale),sliderVal,sliderLow,sliderHigh);
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) { \ }*/
macroLoopDragTarget=&macro.rel; \ PlotCustom("##IMacroLoop",loopIndicator,totalFit,macroDragScroll,NULL,0,2,ImVec2(availableWidth,12.0f*dpiScale),sizeof(float),i.color,i.macro->len-macroDragScroll,&macroHoverLoop);
} else { \ if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
macroLoopDragTarget=&macro.loop; \ macroLoopDragStart=ImGui::GetItemRectMin();
} \ macroLoopDragAreaSize=ImVec2(availableWidth,12.0f*dpiScale);
macroLoopDragActive=true; \ macroLoopDragLen=totalFit;
processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y); \ if (ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) {
} \ macroLoopDragTarget=&i.macro->rel;
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) { \ } else {
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) { \ macroLoopDragTarget=&i.macro->loop;
macro.rel=-1; \ }
} else { \ macroLoopDragActive=true;
macro.loop=-1; \ processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y);
} \ }
} \ if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
ImGui::SetNextItemWidth(availableWidth); \ if (ImGui::IsKeyDown(ImGuiKey_LeftShift) || ImGui::IsKeyDown(ImGuiKey_RightShift)) {
if (ImGui::InputText("##IMacroMML_" macroName,&mmlStr)) { \ i.macro->rel=-1;
decodeMMLStr(mmlStr,macro.val,macro.len,macro.loop,macroAMin,(bitfield)?((1<<(bitfield?macroAMax:0))-1):macroAMax,macro.rel); \ } else {
} \ i.macro->loop=-1;
if (!ImGui::IsItemActive()) { \ }
encodeMMLStr(mmlStr,macro.val,macro.len,macro.loop,macro.rel); \ }
} \ ImGui::SetNextItemWidth(availableWidth);
} \ String& mmlStr=mmlString[index];
if (ImGui::InputText("##IMacroMML",&mmlStr)) {
decodeMMLStr(mmlStr,i.macro->val,i.macro->len,i.macro->loop,i.min,(i.isBitfield)?((1<<(i.isBitfield?i.max:0))-1):i.max,i.macro->rel);
}
if (!ImGui::IsItemActive()) {
encodeMMLStr(mmlStr,i.macro->val,i.macro->len,i.macro->loop,i.macro->rel);
}
}
ImGui::PopStyleVar(); ImGui::PopStyleVar();
ImGui::PopID();
#define MACRO_BEGIN(reservedSpace) \ index++;
if (ImGui::BeginTable("MacroSpace",2)) { \
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,0.0); \
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0); \
ImGui::TableNextRow(); \
ImGui::TableNextColumn(); \
float lenAvail=ImGui::GetContentRegionAvail().x; \
ImGui::Dummy(ImVec2(120.0f*dpiScale,dpiScale)); \
ImGui::TableNextColumn(); \
float availableWidth=ImGui::GetContentRegionAvail().x-reservedSpace; \
int totalFit=MIN(128,availableWidth/MAX(1,macroPointSize*dpiScale)); \
if (macroDragScroll>128-totalFit) { \
macroDragScroll=128-totalFit; \
} \
ImGui::SetNextItemWidth(availableWidth); \
if (CWSliderInt("##MacroScroll",&macroDragScroll,0,128-totalFit,"")) { \
if (macroDragScroll<0) macroDragScroll=0; \
if (macroDragScroll>128-totalFit) macroDragScroll=128-totalFit; \
} }
#define MACRO_END \ ImGui::TableNextRow();
ImGui::TableNextRow(); \ ImGui::TableNextColumn();
ImGui::TableNextColumn(); \ ImGui::TableNextColumn();
ImGui::TableNextColumn(); \ ImGui::SetNextItemWidth(availableWidth);
ImGui::SetNextItemWidth(availableWidth); \ if (CWSliderInt("##MacroScroll",&macroDragScroll,0,128-totalFit,"")) {
if (CWSliderInt("##MacroScroll",&macroDragScroll,0,128-totalFit,"")) { \ if (macroDragScroll<0) macroDragScroll=0;
if (macroDragScroll<0) macroDragScroll=0; \ if (macroDragScroll>128-totalFit) macroDragScroll=128-totalFit;
if (macroDragScroll>128-totalFit) macroDragScroll=128-totalFit; \ }
} \ ImGui::EndTable();
ImGui::EndTable(); \ }
} }
#define DRUM_FREQ(name,db,df,prop) \ #define DRUM_FREQ(name,db,df,prop) \
@ -1352,9 +1341,6 @@ void FurnaceGUI::drawInsEdit() {
std::vector<FurnaceGUIMacroDesc> macroList; std::vector<FurnaceGUIMacroDesc> macroList;
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPZ) { if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPZ) {
char label[32]; char label[32];
float asFloat[256];
int asInt[256];
float loopIndicator[256];
int opCount=4; int opCount=4;
if (ins->type==DIV_INS_OPLL) opCount=2; if (ins->type==DIV_INS_OPLL) opCount=2;
if (ins->type==DIV_INS_OPL) opCount=(ins->fm.ops==4)?4:2; if (ins->type==DIV_INS_OPL) opCount=(ins->fm.ops==4)?4:2;
@ -2142,7 +2128,6 @@ void FurnaceGUI::drawInsEdit() {
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (ImGui::BeginTabItem("FM Macros")) { if (ImGui::BeginTabItem("FM Macros")) {
MACRO_BEGIN(0);
if (ins->type==DIV_INS_OPLL) { if (ins->type==DIV_INS_OPLL) {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SUS),&ins->std.algMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SUS),&ins->std.algMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FB),&ins->std.fbMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER])); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FB),&ins->std.fbMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER]));
@ -2170,14 +2155,13 @@ void FurnaceGUI::drawInsEdit() {
macroList.push_back(FurnaceGUIMacroDesc("LFO Shape",&ins->std.waveMacro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,macroLFOWaves)); macroList.push_back(FurnaceGUIMacroDesc("LFO Shape",&ins->std.waveMacro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,macroLFOWaves));
macroList.push_back(FurnaceGUIMacroDesc("OpMask",&ins->std.ex4Macro,0,4,128,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,fmOperatorBits)); macroList.push_back(FurnaceGUIMacroDesc("OpMask",&ins->std.ex4Macro,0,4,128,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,fmOperatorBits));
} }
MACRO_END; drawMacros(macroList);
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
for (int i=0; i<opCount; i++) { for (int i=0; i<opCount; i++) {
snprintf(label,31,"OP%d Macros",i+1); snprintf(label,31,"OP%d Macros",i+1);
if (ImGui::BeginTabItem(label)) { if (ImGui::BeginTabItem(label)) {
ImGui::PushID(i); ImGui::PushID(i);
MACRO_BEGIN(0);
int ordi=(opCount==4)?orderedOps[i]:i; int ordi=(opCount==4)?orderedOps[i]:i;
int maxTl=127; int maxTl=127;
if (ins->type==DIV_INS_OPLL) { if (ins->type==DIV_INS_OPLL) {
@ -2236,7 +2220,7 @@ void FurnaceGUI::drawInsEdit() {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SSG),&ins->std.opMacros[ordi].ssgMacro,0,4,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,ssgEnvBits)); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SSG),&ins->std.opMacros[ordi].ssgMacro,0,4,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,ssgEnvBits));
} }
} }
MACRO_END; drawMacros(macroList);
ImGui::PopID(); ImGui::PopID();
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
@ -2735,10 +2719,6 @@ void FurnaceGUI::drawInsEdit() {
} }
} }
if (ImGui::BeginTabItem("Macros")) { if (ImGui::BeginTabItem("Macros")) {
// TODO: rewrite all of this
float asFloat[256];
int asInt[256];
float loopIndicator[256];
const char* volumeLabel="Volume"; const char* volumeLabel="Volume";
int volMax=15; int volMax=15;
@ -3021,10 +3001,7 @@ void FurnaceGUI::drawInsEdit() {
macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.ex3Macro,0,4,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,suControlBits)); macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.ex3Macro,0,4,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,suControlBits));
} }
MACRO_BEGIN(28*dpiScale); drawMacros(macroList);
for (FurnaceGUIMacroDesc& i: macroList) {
}
MACRO_END;
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
ImGui::EndTabBar(); ImGui::EndTabBar();