GUI: macro editor (kind of) and order view

This commit is contained in:
tildearrow 2021-12-12 04:21:09 -05:00
parent dcbb41bc2f
commit 4b32599237
4 changed files with 233 additions and 10 deletions

View file

@ -1,11 +1,15 @@
#include "gui.h"
#include "SDL_events.h"
#include "SDL_video.h"
#include "fonts.h"
#include "../ta-log.h"
#include "imgui.h"
#include "misc/cpp/imgui_stdlib.h"
#include <cstdio>
#include <fmt/printf.h>
const int _ZERO=0;
const int _ONE=1;
const int _THREE=3;
const int _SEVEN=7;
const int _FIFTEEN=15;;
@ -26,6 +30,23 @@ bool FurnaceGUI::loop() {
while (SDL_PollEvent(&ev)) {
ImGui_ImplSDL2_ProcessEvent(&ev);
switch (ev.type) {
case SDL_MOUSEMOTION:
if (macroDragActive) {
// do macro drag here!
if (macroDragLen>0) {
int x=(ev.motion.x-macroDragStart.x)*macroDragLen/macroDragAreaSize.x;
if (x<0) x=0;
if (x>=macroDragLen) x=macroDragLen-1;
int y=round(macroDragMax-((ev.motion.y-macroDragStart.y)*(double(macroDragMax-macroDragMin)/(double)macroDragAreaSize.y)));
if (y>macroDragMax) y=macroDragMax;
if (y<macroDragMin) y=macroDragMin;
macroDragTarget[x]=y;
}
}
break;
case SDL_MOUSEBUTTONUP:
macroDragActive=false;
break;
case SDL_QUIT:
quit=true;
return true;
@ -68,6 +89,39 @@ bool FurnaceGUI::loop() {
}
ImGui::End();
char selID[16];
if (ImGui::Begin("Orders")) {
ImGui::BeginTable("OrdersTable",1+e->getChannelCount(e->song.system));
ImGui::TableNextRow();
ImGui::TableNextColumn();
for (int i=0; i<e->getChannelCount(e->song.system); i++) {
ImGui::TableNextColumn();
ImGui::Text("%s",e->getChannelShortName(i));
}
for (int i=0; i<e->song.ordersLen; i++) {
ImGui::TableNextRow();
if (e->getOrder()==i) ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0,0x40ffffff);
ImGui::TableNextColumn();
snprintf(selID,16,"%.2x##O_S%.2x",i,i);
if (ImGui::Selectable(selID)) {
e->setOrder(i);
}
for (int j=0; j<e->getChannelCount(e->song.system); j++) {
ImGui::TableNextColumn();
snprintf(selID,16,"%.2x##O_%.2x_%.2x",e->song.orders.ord[j][i],j,i);
if (ImGui::Selectable(selID)) {
if (e->song.orders.ord[j][i]<0x7f) e->song.orders.ord[j][i]++;
}
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
if (e->song.orders.ord[j][i]>0) e->song.orders.ord[j][i]--;
}
}
}
ImGui::EndTable();
}
ImGui::End();
if (ImGui::Begin("Instruments")) {
for (int i=0; i<e->song.ins.size(); i++) {
DivInstrument* ins=e->song.ins[i];
@ -84,7 +138,7 @@ bool FurnaceGUI::loop() {
} else {
DivInstrument* ins=e->song.ins[curIns];
ImGui::InputText("Name",&ins->name);
ImGui::Checkbox("FM",&ins->mode);
if (e->isFMSystem(e->song.system)) ImGui::Checkbox("FM",&ins->mode);
if (ins->mode) { // FM
ImGui::SliderScalar("Algorithm",ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN);
@ -123,12 +177,74 @@ bool FurnaceGUI::loop() {
ImGui::PopID();
}
} else { // STD
float asFloat[128];
float loopIndicator[128];
// volume macro
ImGui::Separator();
ImGui::Text("Volume Macro");
for (int i=0; i<ins->std.volMacroLen; i++) {
asFloat[i]=ins->std.volMacro[i];
loopIndicator[i]=(ins->std.volMacroLoop!=-1 && i>=ins->std.volMacroLoop);
}
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0.0f,0.0f));
int volMax=e->getMaxVolume();
ImGui::PlotHistogram("##IVolMacro",asFloat,ins->std.volMacroLen,0,NULL,0,volMax,ImVec2(400.0f*dpiScale,200.0f*dpiScale));
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
macroDragStart=ImGui::GetItemRectMin();
macroDragAreaSize=ImVec2(400.0f*dpiScale,200.0f*dpiScale);
macroDragMin=0;
macroDragMax=volMax;
macroDragLen=ins->std.volMacroLen;
macroDragActive=true;
macroDragTarget=ins->std.volMacro;
printf("Start.\n");
}
ImGui::PlotHistogram("##IVolMacroLoop",loopIndicator,ins->std.volMacroLen,0,NULL,0,1,ImVec2(400.0f*dpiScale,16.0f*dpiScale));
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
macroLoopDragStart=ImGui::GetItemRectMin();
macroLoopDragAreaSize=ImVec2(400.0f*dpiScale,16.0f*dpiScale);
macroLoopDragLen=ins->std.volMacroLen;
macroLoopDragTarget=&ins->std.volMacroLoop;
macroLoopDragActive=true;
}
ImGui::PopStyleVar();
if (ImGui::InputScalar("Length##IVolMacroL",ImGuiDataType_U8,&ins->std.volMacroLen,&_ONE,&_THREE)) {
if (ins->std.volMacroLen>127) ins->std.volMacroLen=127;
}
// arp macro
ImGui::Separator();
ImGui::Text("Arpeggio Macro");
for (int i=0; i<ins->std.arpMacroLen; i++) {
asFloat[i]=ins->std.arpMacro[i];
}
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0.0f,0.0f));
ImGui::PlotHistogram("##IArpMacro",asFloat,ins->std.arpMacroLen,0,NULL,-92,82,ImVec2(400.0f*dpiScale,200.0f*dpiScale));
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
macroDragStart=ImGui::GetItemRectMin();
macroDragAreaSize=ImVec2(400.0f*dpiScale,200.0f*dpiScale);
macroDragMin=-92;
macroDragMax=82;
macroDragLen=ins->std.arpMacroLen;
macroDragActive=true;
macroDragTarget=ins->std.arpMacro;
printf("Start.\n");
}
ImGui::PopStyleVar();
if (ImGui::InputScalar("Length##IArpMacroL",ImGuiDataType_U8,&ins->std.arpMacroLen,&_ONE,&_THREE)) {
if (ins->std.arpMacroLen>127) ins->std.arpMacroLen=127;
}
}
}
}
ImGui::End();
if (ImGui::Begin("Pattern")) {
ImGui::Text("TODO");
}
ImGui::End();
SDL_RenderClear(sdlRend);
ImGui::Render();
ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData());
@ -138,11 +254,17 @@ bool FurnaceGUI::loop() {
}
bool FurnaceGUI::init() {
float dpiScaleF;
sdlWin=SDL_CreateWindow("Furnace",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,scrW*dpiScale,scrH*dpiScale,SDL_WINDOW_RESIZABLE|SDL_WINDOW_ALLOW_HIGHDPI);
if (sdlWin==NULL) {
logE("could not open window!\n");
return false;
}
SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(sdlWin),&dpiScaleF,NULL,NULL);
dpiScale=round(dpiScaleF/96.0f);
if (dpiScale<1) dpiScale=1;
SDL_SetWindowSize(sdlWin,scrW*dpiScale,scrH*dpiScale);
sdlRend=SDL_CreateRenderer(sdlWin,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC|SDL_RENDERER_TARGETTEXTURE);
@ -178,5 +300,12 @@ FurnaceGUI::FurnaceGUI():
scrH(800),
dpiScale(1),
curIns(0),
curOctave(3) {
curOctave(3),
macroDragStart(0,0),
macroDragAreaSize(0,0),
macroDragTarget(NULL),
macroDragLen(0),
macroDragMin(0),
macroDragMax(0),
macroDragActive(false) {
}

View file

@ -21,6 +21,19 @@ class FurnaceGUI {
int curIns, curOctave;
ImVec2 macroDragStart;
ImVec2 macroDragAreaSize;
int* macroDragTarget;
int macroDragLen;
int macroDragMin, macroDragMax;
bool macroDragActive;
ImVec2 macroLoopDragStart;
ImVec2 macroLoopDragAreaSize;
signed char* macroLoopDragTarget;
int macroLoopDragLen;
bool macroLoopDragActive;
public:
void bindEngine(DivEngine* eng);
bool loop();