mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-27 06:53:01 +00:00
GUI: add ability to see previous orders in the pattern
editor closes #161
This commit is contained in:
parent
810ee33d11
commit
09144b95f9
2 changed files with 366 additions and 240 deletions
599
src/gui/gui.cpp
599
src/gui/gui.cpp
|
@ -3103,6 +3103,246 @@ void FurnaceGUI::drawVolMeter() {
|
|||
ImGui::End();
|
||||
}
|
||||
|
||||
// draw a pattern row
|
||||
inline void FurnaceGUI::patternRow(int i, bool isPlaying, float lineHeight, int chans, int ord) {
|
||||
static char id[32];
|
||||
bool selectedRow=(i>=sel1.y && i<=sel2.y);
|
||||
ImGui::TableNextRow(0,lineHeight);
|
||||
ImGui::TableNextColumn();
|
||||
float cursorPosY=ImGui::GetCursorPos().y-ImGui::GetScrollY();
|
||||
// check if the row is visible
|
||||
if (cursorPosY<-lineHeight || cursorPosY>ImGui::GetWindowSize().y) {
|
||||
return;
|
||||
}
|
||||
// check if we are in range
|
||||
if (ord<0 || ord>=e->song.ordersLen) {
|
||||
return;
|
||||
}
|
||||
if (i<0 || i>=e->song.patLen) {
|
||||
return;
|
||||
}
|
||||
// check overflow highlight
|
||||
if (settings.overflowHighlight) {
|
||||
if (edit && cursor.y==i) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0,ImGui::GetColorU32(uiColors[GUI_COLOR_EDITING]));
|
||||
} else if (isPlaying && oldRow==i) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0,0x40ffffff);
|
||||
} else if (e->song.hilightB>0 && !(i%e->song.hilightB)) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0,ImGui::GetColorU32(uiColors[GUI_COLOR_PATTERN_HI_2]));
|
||||
} else if (e->song.hilightA>0 && !(i%e->song.hilightA)) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0,ImGui::GetColorU32(uiColors[GUI_COLOR_PATTERN_HI_1]));
|
||||
}
|
||||
}
|
||||
// row number
|
||||
if (settings.patRowsBase==1) {
|
||||
ImGui::TextColored(uiColors[GUI_COLOR_PATTERN_ROW_INDEX]," %.2X ",i);
|
||||
} else {
|
||||
ImGui::TextColored(uiColors[GUI_COLOR_PATTERN_ROW_INDEX],"%3d ",i);
|
||||
}
|
||||
// for each column
|
||||
for (int j=0; j<chans; j++) {
|
||||
// check if channel is not hidden
|
||||
if (!e->song.chanShow[j]) {
|
||||
patChanX[j]=ImGui::GetCursorPosX();
|
||||
continue;
|
||||
}
|
||||
int chanVolMax=e->getMaxVolumeChan(j);
|
||||
if (chanVolMax<1) chanVolMax=1;
|
||||
DivPattern* pat=e->song.pat[j].getPattern(e->song.orders.ord[j][ord],true);
|
||||
ImGui::TableNextColumn();
|
||||
patChanX[j]=ImGui::GetCursorPosX();
|
||||
|
||||
// check overflow highlight
|
||||
if (!settings.overflowHighlight) {
|
||||
if (edit && cursor.y==i) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,ImGui::GetColorU32(uiColors[GUI_COLOR_EDITING]));
|
||||
} else if (isPlaying && oldRow==i) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,0x40ffffff);
|
||||
} else if (e->song.hilightB>0 && !(i%e->song.hilightB)) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,ImGui::GetColorU32(uiColors[GUI_COLOR_PATTERN_HI_2]));
|
||||
} else if (e->song.hilightA>0 && !(i%e->song.hilightA)) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,ImGui::GetColorU32(uiColors[GUI_COLOR_PATTERN_HI_1]));
|
||||
}
|
||||
}
|
||||
|
||||
// selection highlight flags
|
||||
int sel1XSum=sel1.xCoarse*32+sel1.xFine;
|
||||
int sel2XSum=sel2.xCoarse*32+sel2.xFine;
|
||||
int j32=j*32;
|
||||
bool selectedNote=selectedRow && (j32>=sel1XSum && j32<=sel2XSum);
|
||||
bool selectedIns=selectedRow && (j32+1>=sel1XSum && j32+1<=sel2XSum);
|
||||
bool selectedVol=selectedRow && (j32+2>=sel1XSum && j32+2<=sel2XSum);
|
||||
bool cursorNote=(cursor.y==i && cursor.xCoarse==j && cursor.xFine==0);
|
||||
bool cursorIns=(cursor.y==i && cursor.xCoarse==j && cursor.xFine==1);
|
||||
bool cursorVol=(cursor.y==i && cursor.xCoarse==j && cursor.xFine==2);
|
||||
|
||||
// note
|
||||
sprintf(id,"%s##PN_%d_%d",noteName(pat->data[i][0],pat->data[i][1]),i,j);
|
||||
if (pat->data[i][0]==0 && pat->data[i][1]==0) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_INACTIVE]);
|
||||
} else {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_ACTIVE]);
|
||||
}
|
||||
if (cursorNote) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_CURSOR]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,uiColors[GUI_COLOR_PATTERN_CURSOR_ACTIVE]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_CURSOR_HOVER]);
|
||||
ImGui::Selectable(id,true,ImGuiSelectableFlags_NoPadWithHalfSpacing,threeChars);
|
||||
demandX=ImGui::GetCursorPosX();
|
||||
ImGui::PopStyleColor(3);
|
||||
} else {
|
||||
ImGui::Selectable(id,selectedNote,ImGuiSelectableFlags_NoPadWithHalfSpacing,threeChars);
|
||||
}
|
||||
if (ImGui::IsItemClicked()) {
|
||||
startSelection(j,0,i);
|
||||
}
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) {
|
||||
updateSelection(j,0,i);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
// the following is only visible when the channel is not collapsed
|
||||
if (!e->song.chanCollapse[j]) {
|
||||
// instrument
|
||||
if (pat->data[i][2]==-1) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_INACTIVE]);
|
||||
sprintf(id,"..##PI_%d_%d",i,j);
|
||||
} else {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_INS]);
|
||||
sprintf(id,"%.2X##PI_%d_%d",pat->data[i][2],i,j);
|
||||
}
|
||||
ImGui::SameLine(0.0f,0.0f);
|
||||
if (cursorIns) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_CURSOR]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,uiColors[GUI_COLOR_PATTERN_CURSOR_ACTIVE]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_CURSOR_HOVER]);
|
||||
ImGui::Selectable(id,true,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
demandX=ImGui::GetCursorPosX();
|
||||
ImGui::PopStyleColor(3);
|
||||
} else {
|
||||
ImGui::Selectable(id,selectedIns,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
}
|
||||
if (ImGui::IsItemClicked()) {
|
||||
startSelection(j,1,i);
|
||||
}
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) {
|
||||
updateSelection(j,1,i);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
// volume
|
||||
if (pat->data[i][3]==-1) {
|
||||
sprintf(id,"..##PV_%d_%d",i,j);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_INACTIVE]);
|
||||
} else {
|
||||
int volColor=(pat->data[i][3]*127)/chanVolMax;
|
||||
if (volColor>127) volColor=127;
|
||||
if (volColor<0) volColor=0;
|
||||
sprintf(id,"%.2X##PV_%d_%d",pat->data[i][3],i,j);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,volColors[volColor]);
|
||||
}
|
||||
ImGui::SameLine(0.0f,0.0f);
|
||||
if (cursorVol) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_CURSOR]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,uiColors[GUI_COLOR_PATTERN_CURSOR_ACTIVE]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_CURSOR_HOVER]);
|
||||
ImGui::Selectable(id,true,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
demandX=ImGui::GetCursorPosX();
|
||||
ImGui::PopStyleColor(3);
|
||||
} else {
|
||||
ImGui::Selectable(id,selectedVol,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
}
|
||||
if (ImGui::IsItemClicked()) {
|
||||
startSelection(j,2,i);
|
||||
}
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) {
|
||||
updateSelection(j,2,i);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
// effects
|
||||
for (int k=0; k<e->song.pat[j].effectRows; k++) {
|
||||
int index=4+(k<<1);
|
||||
bool selectedEffect=selectedRow && (j32+index-1>=sel1XSum && j32+index-1<=sel2XSum);
|
||||
bool selectedEffectVal=selectedRow && (j32+index>=sel1XSum && j32+index<=sel2XSum);
|
||||
bool cursorEffect=(cursor.y==i && cursor.xCoarse==j && cursor.xFine==index-1);
|
||||
bool cursorEffectVal=(cursor.y==i && cursor.xCoarse==j && cursor.xFine==index);
|
||||
|
||||
// effect
|
||||
if (pat->data[i][index]==-1) {
|
||||
sprintf(id,"..##PE%d_%d_%d",k,i,j);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_INACTIVE]);
|
||||
} else {
|
||||
sprintf(id,"%.2X##PE%d_%d_%d",pat->data[i][index],k,i,j);
|
||||
if (pat->data[i][index]<0x10) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[fxColors[pat->data[i][index]]]);
|
||||
} else if (pat->data[i][index]<0x20) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY]);
|
||||
} else if (pat->data[i][index]<0x30) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_SECONDARY]);
|
||||
} else if (pat->data[i][index]<0x48) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY]);
|
||||
} else if (pat->data[i][index]<0xc0) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_INVALID]);
|
||||
} else if (pat->data[i][index]<0xd0) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SPEED]);
|
||||
} else if (pat->data[i][index]<0xe0) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_INVALID]);
|
||||
} else if (pat->data[i][index]<0xf0) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[extFxColors[pat->data[i][index]-0xe0]]);
|
||||
} else {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_INVALID]);
|
||||
}
|
||||
}
|
||||
ImGui::SameLine(0.0f,0.0f);
|
||||
if (cursorEffect) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_CURSOR]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,uiColors[GUI_COLOR_PATTERN_CURSOR_ACTIVE]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_CURSOR_HOVER]);
|
||||
ImGui::Selectable(id,true,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
demandX=ImGui::GetCursorPosX();
|
||||
ImGui::PopStyleColor(3);
|
||||
} else {
|
||||
ImGui::Selectable(id,selectedEffect,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
}
|
||||
if (ImGui::IsItemClicked()) {
|
||||
startSelection(j,index-1,i);
|
||||
}
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) {
|
||||
updateSelection(j,index-1,i);
|
||||
}
|
||||
|
||||
// effect value
|
||||
if (pat->data[i][index+1]==-1) {
|
||||
sprintf(id,"..##PF%d_%d_%d",k,i,j);
|
||||
} else {
|
||||
sprintf(id,"%.2X##PF%d_%d_%d",pat->data[i][index+1],k,i,j);
|
||||
}
|
||||
ImGui::SameLine(0.0f,0.0f);
|
||||
if (cursorEffectVal) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_CURSOR]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,uiColors[GUI_COLOR_PATTERN_CURSOR_ACTIVE]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_CURSOR_HOVER]);
|
||||
ImGui::Selectable(id,true,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
demandX=ImGui::GetCursorPosX();
|
||||
ImGui::PopStyleColor(3);
|
||||
} else {
|
||||
ImGui::Selectable(id,selectedEffectVal,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
}
|
||||
if (ImGui::IsItemClicked()) {
|
||||
startSelection(j,index,i);
|
||||
}
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) {
|
||||
updateSelection(j,index,i);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
patChanX[chans]=ImGui::GetCursorPosX();
|
||||
}
|
||||
|
||||
void FurnaceGUI::drawPattern() {
|
||||
if (nextWindow==GUI_WINDOW_PATTERN) {
|
||||
patternOpen=true;
|
||||
|
@ -3111,9 +3351,9 @@ void FurnaceGUI::drawPattern() {
|
|||
}
|
||||
if (!patternOpen) return;
|
||||
if (e->isPlaying() && followPattern) cursor.y=oldRow;
|
||||
int demandX=0;
|
||||
SelectionPoint sel1=selStart;
|
||||
SelectionPoint sel2=selEnd;
|
||||
demandX=0;
|
||||
sel1=selStart;
|
||||
sel2=selEnd;
|
||||
if (sel2.y<sel1.y) {
|
||||
sel2.y^=sel1.y;
|
||||
sel1.y^=sel2.y;
|
||||
|
@ -3137,9 +3377,9 @@ void FurnaceGUI::drawPattern() {
|
|||
//ImGui::SetWindowSize(ImVec2(scrW*dpiScale,scrH*dpiScale));
|
||||
patWindowPos=ImGui::GetWindowPos();
|
||||
patWindowSize=ImGui::GetWindowSize();
|
||||
char id[32];
|
||||
//char id[32];
|
||||
ImGui::PushFont(patFont);
|
||||
unsigned char ord=e->isPlaying()?oldOrder:e->getOrder();
|
||||
int ord=e->isPlaying()?oldOrder:e->getOrder();
|
||||
oldOrder=e->getOrder();
|
||||
int chans=e->getTotalChannelCount();
|
||||
int displayChans=0;
|
||||
|
@ -3277,236 +3517,41 @@ void FurnaceGUI::drawPattern() {
|
|||
ImGui::TextColored(uiColors[GUI_COLOR_EE_VALUE]," %.2X",e->getExtValue());
|
||||
}
|
||||
float oneCharSize=ImGui::CalcTextSize("A").x;
|
||||
ImVec2 threeChars=ImVec2(oneCharSize*3.0f,lineHeight);
|
||||
ImVec2 twoChars=ImVec2(oneCharSize*2.0f,lineHeight);
|
||||
threeChars=ImVec2(oneCharSize*3.0f,lineHeight);
|
||||
twoChars=ImVec2(oneCharSize*2.0f,lineHeight);
|
||||
//ImVec2 oneChar=ImVec2(oneCharSize,lineHeight);
|
||||
int dummyRows=(ImGui::GetWindowSize().y/lineHeight)/2;
|
||||
for (int i=0; i<dummyRows-1; i++) {
|
||||
ImGui::TableNextRow(0,lineHeight);
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
for (int i=0; i<e->song.patLen; i++) {
|
||||
bool selectedRow=(i>=sel1.y && i<=sel2.y);
|
||||
ImGui::TableNextRow(0,lineHeight);
|
||||
if ((lineHeight*(i+dummyRows+1))-ImGui::GetScrollY()<0) {
|
||||
continue;
|
||||
dummyRows=(ImGui::GetWindowSize().y/lineHeight)/2;
|
||||
// オップナー2608 i owe you one more for this horrible code
|
||||
// previous pattern
|
||||
ImGui::BeginDisabled();
|
||||
if (settings.viewPrevPattern) {
|
||||
for (int i=0; i<dummyRows-1; i++) {
|
||||
patternRow(e->song.patLen+i-dummyRows+1,e->isPlaying(),lineHeight,chans,ord-1);
|
||||
}
|
||||
if ((lineHeight*(i+dummyRows))-ImGui::GetScrollY()>ImGui::GetWindowSize().y) {
|
||||
continue;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
bool isPlaying=e->isPlaying();
|
||||
if (settings.overflowHighlight) {
|
||||
if (edit && cursor.y==i) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0,ImGui::GetColorU32(uiColors[GUI_COLOR_EDITING]));
|
||||
} else if (isPlaying && oldRow==i) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0,0x40ffffff);
|
||||
} else if (e->song.hilightB>0 && !(i%e->song.hilightB)) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0,ImGui::GetColorU32(uiColors[GUI_COLOR_PATTERN_HI_2]));
|
||||
} else if (e->song.hilightA>0 && !(i%e->song.hilightA)) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0,ImGui::GetColorU32(uiColors[GUI_COLOR_PATTERN_HI_1]));
|
||||
}
|
||||
}
|
||||
if (settings.patRowsBase==1) {
|
||||
ImGui::TextColored(uiColors[GUI_COLOR_PATTERN_ROW_INDEX]," %.2X ",i);
|
||||
} else {
|
||||
ImGui::TextColored(uiColors[GUI_COLOR_PATTERN_ROW_INDEX],"%3d ",i);
|
||||
}
|
||||
for (int j=0; j<chans; j++) {
|
||||
if (!e->song.chanShow[j]) {
|
||||
patChanX[j]=ImGui::GetCursorPosX();
|
||||
continue;
|
||||
}
|
||||
int chanVolMax=e->getMaxVolumeChan(j);
|
||||
if (chanVolMax<1) chanVolMax=1;
|
||||
DivPattern* pat=e->song.pat[j].getPattern(e->song.orders.ord[j][ord],true);
|
||||
} else {
|
||||
for (int i=0; i<dummyRows-1; i++) {
|
||||
ImGui::TableNextRow(0,lineHeight);
|
||||
ImGui::TableNextColumn();
|
||||
patChanX[j]=ImGui::GetCursorPosX();
|
||||
|
||||
if (!settings.overflowHighlight) {
|
||||
if (edit && cursor.y==i) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,ImGui::GetColorU32(uiColors[GUI_COLOR_EDITING]));
|
||||
} else if (isPlaying && oldRow==i) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,0x40ffffff);
|
||||
} else if (e->song.hilightB>0 && !(i%e->song.hilightB)) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,ImGui::GetColorU32(uiColors[GUI_COLOR_PATTERN_HI_2]));
|
||||
} else if (e->song.hilightA>0 && !(i%e->song.hilightA)) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,ImGui::GetColorU32(uiColors[GUI_COLOR_PATTERN_HI_1]));
|
||||
}
|
||||
}
|
||||
|
||||
int sel1XSum=sel1.xCoarse*32+sel1.xFine;
|
||||
int sel2XSum=sel2.xCoarse*32+sel2.xFine;
|
||||
int j32=j*32;
|
||||
bool selectedNote=selectedRow && (j32>=sel1XSum && j32<=sel2XSum);
|
||||
bool selectedIns=selectedRow && (j32+1>=sel1XSum && j32+1<=sel2XSum);
|
||||
bool selectedVol=selectedRow && (j32+2>=sel1XSum && j32+2<=sel2XSum);
|
||||
bool cursorNote=(cursor.y==i && cursor.xCoarse==j && cursor.xFine==0);
|
||||
bool cursorIns=(cursor.y==i && cursor.xCoarse==j && cursor.xFine==1);
|
||||
bool cursorVol=(cursor.y==i && cursor.xCoarse==j && cursor.xFine==2);
|
||||
|
||||
sprintf(id,"%s##PN_%d_%d",noteName(pat->data[i][0],pat->data[i][1]),i,j);
|
||||
if (pat->data[i][0]==0 && pat->data[i][1]==0) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_INACTIVE]);
|
||||
} else {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_ACTIVE]);
|
||||
}
|
||||
if (cursorNote) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_CURSOR]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,uiColors[GUI_COLOR_PATTERN_CURSOR_ACTIVE]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_CURSOR_HOVER]);
|
||||
ImGui::Selectable(id,true,ImGuiSelectableFlags_NoPadWithHalfSpacing,threeChars);
|
||||
demandX=ImGui::GetCursorPosX();
|
||||
ImGui::PopStyleColor(3);
|
||||
} else {
|
||||
ImGui::Selectable(id,selectedNote,ImGuiSelectableFlags_NoPadWithHalfSpacing,threeChars);
|
||||
}
|
||||
if (ImGui::IsItemClicked()) {
|
||||
startSelection(j,0,i);
|
||||
}
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) {
|
||||
//ImGui::SetTooltip("N: %d O: %d",pat->data[i][0],pat->data[i][1]);
|
||||
updateSelection(j,0,i);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
if (!e->song.chanCollapse[j]) {
|
||||
if (pat->data[i][2]==-1) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_INACTIVE]);
|
||||
sprintf(id,"..##PI_%d_%d",i,j);
|
||||
} else {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_INS]);
|
||||
sprintf(id,"%.2X##PI_%d_%d",pat->data[i][2],i,j);
|
||||
}
|
||||
ImGui::SameLine(0.0f,0.0f);
|
||||
if (cursorIns) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_CURSOR]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,uiColors[GUI_COLOR_PATTERN_CURSOR_ACTIVE]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_CURSOR_HOVER]);
|
||||
ImGui::Selectable(id,true,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
demandX=ImGui::GetCursorPosX();
|
||||
ImGui::PopStyleColor(3);
|
||||
} else {
|
||||
ImGui::Selectable(id,selectedIns,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
}
|
||||
if (ImGui::IsItemClicked()) {
|
||||
startSelection(j,1,i);
|
||||
}
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) {
|
||||
updateSelection(j,1,i);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
if (pat->data[i][3]==-1) {
|
||||
sprintf(id,"..##PV_%d_%d",i,j);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_INACTIVE]);
|
||||
} else {
|
||||
int volColor=(pat->data[i][3]*127)/chanVolMax;
|
||||
if (volColor>127) volColor=127;
|
||||
if (volColor<0) volColor=0;
|
||||
sprintf(id,"%.2X##PV_%d_%d",pat->data[i][3],i,j);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,volColors[volColor]);
|
||||
}
|
||||
ImGui::SameLine(0.0f,0.0f);
|
||||
if (cursorVol) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_CURSOR]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,uiColors[GUI_COLOR_PATTERN_CURSOR_ACTIVE]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_CURSOR_HOVER]);
|
||||
ImGui::Selectable(id,true,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
demandX=ImGui::GetCursorPosX();
|
||||
ImGui::PopStyleColor(3);
|
||||
} else {
|
||||
ImGui::Selectable(id,selectedVol,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
}
|
||||
if (ImGui::IsItemClicked()) {
|
||||
startSelection(j,2,i);
|
||||
}
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) {
|
||||
updateSelection(j,2,i);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
for (int k=0; k<e->song.pat[j].effectRows; k++) {
|
||||
int index=4+(k<<1);
|
||||
bool selectedEffect=selectedRow && (j32+index-1>=sel1XSum && j32+index-1<=sel2XSum);
|
||||
bool selectedEffectVal=selectedRow && (j32+index>=sel1XSum && j32+index<=sel2XSum);
|
||||
bool cursorEffect=(cursor.y==i && cursor.xCoarse==j && cursor.xFine==index-1);
|
||||
bool cursorEffectVal=(cursor.y==i && cursor.xCoarse==j && cursor.xFine==index);
|
||||
if (pat->data[i][index]==-1) {
|
||||
sprintf(id,"..##PE%d_%d_%d",k,i,j);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_INACTIVE]);
|
||||
} else {
|
||||
sprintf(id,"%.2X##PE%d_%d_%d",pat->data[i][index],k,i,j);
|
||||
if (pat->data[i][index]<0x10) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[fxColors[pat->data[i][index]]]);
|
||||
} else if (pat->data[i][index]<0x20) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY]);
|
||||
} else if (pat->data[i][index]<0x30) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_SECONDARY]);
|
||||
} else if (pat->data[i][index]<0x48) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY]);
|
||||
} else if (pat->data[i][index]<0xc0) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_INVALID]);
|
||||
} else if (pat->data[i][index]<0xd0) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_SPEED]);
|
||||
} else if (pat->data[i][index]<0xe0) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_INVALID]);
|
||||
} else if (pat->data[i][index]<0xf0) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[extFxColors[pat->data[i][index]-0xe0]]);
|
||||
} else {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_INVALID]);
|
||||
}
|
||||
}
|
||||
ImGui::SameLine(0.0f,0.0f);
|
||||
if (cursorEffect) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_CURSOR]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,uiColors[GUI_COLOR_PATTERN_CURSOR_ACTIVE]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_CURSOR_HOVER]);
|
||||
ImGui::Selectable(id,true,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
demandX=ImGui::GetCursorPosX();
|
||||
ImGui::PopStyleColor(3);
|
||||
} else {
|
||||
ImGui::Selectable(id,selectedEffect,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
}
|
||||
if (ImGui::IsItemClicked()) {
|
||||
startSelection(j,index-1,i);
|
||||
}
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) {
|
||||
updateSelection(j,index-1,i);
|
||||
}
|
||||
if (pat->data[i][index+1]==-1) {
|
||||
sprintf(id,"..##PF%d_%d_%d",k,i,j);
|
||||
} else {
|
||||
sprintf(id,"%.2X##PF%d_%d_%d",pat->data[i][index+1],k,i,j);
|
||||
}
|
||||
ImGui::SameLine(0.0f,0.0f);
|
||||
if (cursorEffectVal) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_CURSOR]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderActive,uiColors[GUI_COLOR_PATTERN_CURSOR_ACTIVE]);
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_CURSOR_HOVER]);
|
||||
ImGui::Selectable(id,true,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
demandX=ImGui::GetCursorPosX();
|
||||
ImGui::PopStyleColor(3);
|
||||
} else {
|
||||
ImGui::Selectable(id,selectedEffectVal,ImGuiSelectableFlags_NoPadWithHalfSpacing,twoChars);
|
||||
}
|
||||
if (ImGui::IsItemClicked()) {
|
||||
startSelection(j,index,i);
|
||||
}
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) {
|
||||
updateSelection(j,index,i);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
patChanX[chans]=ImGui::GetCursorPosX();
|
||||
}
|
||||
for (int i=0; i<=dummyRows; i++) {
|
||||
ImGui::TableNextRow(0,lineHeight);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::EndDisabled();
|
||||
// active area
|
||||
for (int i=0; i<e->song.patLen; i++) {
|
||||
patternRow(i,e->isPlaying(),lineHeight,chans,ord);
|
||||
}
|
||||
// next pattern
|
||||
ImGui::BeginDisabled();
|
||||
if (settings.viewPrevPattern) {
|
||||
for (int i=0; i<=dummyRows; i++) {
|
||||
patternRow(i,e->isPlaying(),lineHeight,chans,ord+1);
|
||||
}
|
||||
} else {
|
||||
for (int i=0; i<=dummyRows; i++) {
|
||||
ImGui::TableNextRow(0,lineHeight);
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
oldRow=curRow;
|
||||
if (demandScrollX) {
|
||||
int totalDemand=demandX-ImGui::GetScrollX();
|
||||
|
@ -3528,33 +3573,102 @@ void FurnaceGUI::drawPattern() {
|
|||
// commands
|
||||
for (DivCommand& i: cmdStream) {
|
||||
if (i.cmd==DIV_CMD_PITCH) continue;
|
||||
if (i.cmd==DIV_CMD_NOTE_PORTA) continue;
|
||||
//if (i.cmd==DIV_CMD_NOTE_ON) continue;
|
||||
if (i.cmd==DIV_CMD_PRE_NOTE) continue;
|
||||
if (i.cmd==DIV_CMD_INSTRUMENT) continue;
|
||||
if (i.cmd==DIV_CMD_SAMPLE_BANK) continue;
|
||||
|
||||
float width=patChanX[i.chan+1]-patChanX[i.chan];
|
||||
float speedX=0.0f;
|
||||
float speedY=-18.0f;
|
||||
float grav=0.6f;
|
||||
float frict=1.0f;
|
||||
float life=255.0f;
|
||||
float lifeSpeed=8.0f;
|
||||
float spread=5.0f;
|
||||
int num=3;
|
||||
const char* partIcon=ICON_FA_MICROCHIP;
|
||||
ImU32* color=noteGrad;
|
||||
|
||||
if (i.cmd==DIV_CMD_VOLUME) {
|
||||
speedY=-18.0f-(10.0f*((float)i.value/(float)e->getMaxVolumeChan(i.chan)));
|
||||
partIcon=ICON_FA_VOLUME_UP;
|
||||
num=12.0f*((float)i.value/(float)e->getMaxVolumeChan(i.chan));
|
||||
switch (i.cmd) {
|
||||
case DIV_CMD_NOTE_ON:
|
||||
partIcon=ICON_FA_ASTERISK;
|
||||
life=64.0f;
|
||||
lifeSpeed=2.0f;
|
||||
break;
|
||||
case DIV_CMD_LEGATO:
|
||||
partIcon=ICON_FA_COG;
|
||||
color=insGrad;
|
||||
life=64.0f;
|
||||
lifeSpeed=2.0f;
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
case DIV_CMD_ENV_RELEASE:
|
||||
partIcon=ICON_FA_ASTERISK;
|
||||
speedX=0.0f;
|
||||
speedY=0.0f;
|
||||
grav=0.0f;
|
||||
life=24.0f;
|
||||
lifeSpeed=4.0f;
|
||||
break;
|
||||
case DIV_CMD_VOLUME:
|
||||
speedY=-18.0f-(10.0f*((float)i.value/(float)e->getMaxVolumeChan(i.chan)));
|
||||
partIcon=ICON_FA_VOLUME_UP;
|
||||
num=12.0f*((float)i.value/(float)e->getMaxVolumeChan(i.chan));
|
||||
color=volGrad;
|
||||
break;
|
||||
case DIV_CMD_PANNING: {
|
||||
if (i.value==0) {
|
||||
num=0;
|
||||
break;
|
||||
}
|
||||
float ratio=float(((i.value>>4)&15)-(i.value&15))/MAX(((i.value>>4)&15),(i.value&15));
|
||||
speedX=-22.0f*sin(ratio*M_PI*0.5);
|
||||
speedY=-22.0f*cos(ratio*M_PI*0.5);
|
||||
spread=5.0f+fabs(sin(ratio*M_PI*0.5))*7.0f;
|
||||
grav=0.0f;
|
||||
frict=0.96f;
|
||||
if (((i.value>>4)&15)==(i.value&15)) {
|
||||
partIcon=ICON_FA_ARROWS_H;
|
||||
} else if (ratio>0) {
|
||||
partIcon=ICON_FA_ARROW_LEFT;
|
||||
} else {
|
||||
partIcon=ICON_FA_ARROW_RIGHT;
|
||||
}
|
||||
num=9;
|
||||
color=panGrad;
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_SAMPLE_FREQ:
|
||||
speedX=0.0f;
|
||||
speedY=0.0f;
|
||||
grav=0.0f;
|
||||
frict=0.98;
|
||||
spread=19.0f;
|
||||
life=128.0f;
|
||||
lifeSpeed=3.0f;
|
||||
color=sysCmd2Grad;
|
||||
num=10+pow(i.value,0.6);
|
||||
break;
|
||||
default:
|
||||
color=sysCmd1Grad;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int j=0; j<num; j++) {
|
||||
particles.push_back(Particle(
|
||||
noteGrad,
|
||||
color,
|
||||
partIcon,
|
||||
off.x+patChanX[i.chan]+fmod(rand(),width),
|
||||
off.y+(ImGui::GetWindowHeight()*0.5f)+randRange(0,patFont->FontSize),
|
||||
randRange(-5,5),
|
||||
speedY+randRange(-5,5),
|
||||
0.6f,
|
||||
1.0f,
|
||||
255.0f,
|
||||
8.0f
|
||||
speedX+randRange(-spread,spread),
|
||||
speedY+randRange(-spread,spread),
|
||||
grav,
|
||||
frict,
|
||||
life-randRange(0,8),
|
||||
lifeSpeed
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -4139,6 +4253,11 @@ void FurnaceGUI::drawSettings() {
|
|||
settings.overflowHighlight=overflowHighlightB;
|
||||
}
|
||||
|
||||
bool viewPrevPatternB=settings.viewPrevPattern;
|
||||
if (ImGui::Checkbox("Display previous/next pattern",&viewPrevPatternB)) {
|
||||
settings.viewPrevPattern=viewPrevPatternB;
|
||||
}
|
||||
|
||||
bool germanNotationB=settings.germanNotation;
|
||||
if (ImGui::Checkbox("Use German notation",&germanNotationB)) {
|
||||
settings.germanNotation=germanNotationB;
|
||||
|
|
|
@ -591,6 +591,11 @@ class FurnaceGUI {
|
|||
float nextScroll, nextAddScroll;
|
||||
|
||||
ImVec2 patWindowPos, patWindowSize;
|
||||
|
||||
// pattern view specific
|
||||
ImVec2 threeChars, twoChars;
|
||||
SelectionPoint sel1, sel2;
|
||||
int dummyRows, demandX;
|
||||
|
||||
int oldOrdersLen;
|
||||
DivOrders oldOrders;
|
||||
|
@ -606,6 +611,8 @@ class FurnaceGUI {
|
|||
void updateWindowTitle();
|
||||
void prepareLayout();
|
||||
|
||||
void patternRow(int i, bool isPlaying, float lineHeight, int chans, int ord);
|
||||
|
||||
void drawEditControls();
|
||||
void drawSongInfo();
|
||||
void drawOrders();
|
||||
|
|
Loading…
Reference in a new issue