diff --git a/extern/imgui_patched/imgui.cpp b/extern/imgui_patched/imgui.cpp index 71aee9354..7fb9469d1 100644 --- a/extern/imgui_patched/imgui.cpp +++ b/extern/imgui_patched/imgui.cpp @@ -3513,6 +3513,26 @@ void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, } } +// MODIFIED: Render a rectangle shaped with optional rounding and borders on DrawList +void ImGui::RenderFrameDrawList(ImDrawList* dl, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, float rounding) +{ + ImGuiContext& g = *GImGui; + if (g.Style.FrameShading>0.0f) { + ImVec4 fill_colPre=ImGui::ColorConvertU32ToFloat4(fill_col); + fill_colPre.w*=1.0f-g.Style.FrameShading; + ImU32 fill_col1=ImGui::ColorConvertFloat4ToU32(fill_colPre); + dl->AddRectFilledMultiColor(p_min, p_max, fill_col, fill_col, fill_col1, fill_col1, rounding); + } else { + dl->AddRectFilled(p_min, p_max, fill_col, rounding); + } + const float border_size = g.Style.FrameBorderSize; + if (border && border_size > 0.0f) + { + dl->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, 0, border_size); + dl->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, 0, border_size); + } +} + void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding) { ImGuiContext& g = *GImGui; diff --git a/extern/imgui_patched/imgui_internal.h b/extern/imgui_patched/imgui_internal.h index 2c8057bd7..a9272ab33 100644 --- a/extern/imgui_patched/imgui_internal.h +++ b/extern/imgui_patched/imgui_internal.h @@ -3449,6 +3449,7 @@ namespace ImGui IMGUI_API void RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL); IMGUI_API void RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float clip_max_x, float ellipsis_max_x, const char* text, const char* text_end, const ImVec2* text_size_if_known); IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); + IMGUI_API void RenderFrameDrawList(ImDrawList* dl, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); // MODIFIED - draw list version of RenderFrame IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f); IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, ImDrawFlags flags = 0); IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_TypeDefault); // Navigation highlight diff --git a/src/gui/pattern.cpp b/src/gui/pattern.cpp index 17e4c3968..5d0e80895 100644 --- a/src/gui/pattern.cpp +++ b/src/gui/pattern.cpp @@ -28,6 +28,17 @@ #include "../utfutils.h" #include +struct DelayedLabel { + float posCenter, posY; + ImVec2 textSize; + const char* label; + DelayedLabel(float pc, float py, ImVec2 ts, const char* l): + posCenter(pc), + posY(py), + textSize(ts), + label(l) {} +}; + inline float randRange(float min, float max) { return min+((float)rand()/(float)RAND_MAX)*(max-min); } @@ -1136,22 +1147,30 @@ void FurnaceGUI::drawPattern() { } } // HACK: rendering here would cause the pairs to be drawn behind the pattern for some reason... + // ...so we capture the table's window draw list... tdl=ImGui::GetWindowDrawList(); ImGui::EndTable(); } + // ...and then use it here ImGui::PushFont(mainFont); if (patChannelPairs && e->isRunning() && tdl!=NULL) { // pair hints float pos=0.0f; float posCenter=0.0f; float posMin=FLT_MAX; float posMax=-FLT_MAX; - float posY=chanHeadBottom; ImVec2 textSize; + unsigned int floors[4][4]; // bit array + std::vector delayedLabels; + + memset(floors,0,4*4*sizeof(unsigned int)); for (int i=0; icurSubSong->chanShow[i]) { continue; } @@ -1164,11 +1183,34 @@ void FurnaceGUI::drawPattern() { continue; } isPaired=true; - break; + if ((unsigned int)pairChpairMax) pairMax=pairCh; } if (!isPaired) continue; + float posY=chanHeadBottom; + + // find a free floor + while (curFloor<4) { + bool free=true; + for (unsigned int j=pairMin; j<=pairMax; j++) { + const unsigned int j0=j>>5; + const unsigned int j1=1U<<(j&31); + if (floors[curFloor][j0]&j1) { + free=false; + break; + } + } + if (free) break; + curFloor++; + } + if (curFloor<4) { + // occupy floor + floors[curFloor][pairMin>>5]|=1U<<(pairMin&31); + floors[curFloor][pairMax>>5]|=1U<<(pairMax&31); + } + pos=(patChanX[i+1]+patChanX[i])*0.5; posCenter=pos; posMin=pos; @@ -1180,8 +1222,11 @@ void FurnaceGUI::drawPattern() { } else { textSize=ImGui::CalcTextSize(pairs.label); } + + posY+=(textSize.y+ImGui::GetStyle().ItemSpacing.y)*curFloor; + tdl->AddLine( - ImVec2(pos,posY), + ImVec2(pos,chanHeadBottom), ImVec2(pos,posY+textSize.y), ImGui::GetColorU32(uiColors[GUI_COLOR_PATTERN_PAIR]), 2.0f*dpiScale @@ -1200,7 +1245,7 @@ void FurnaceGUI::drawPattern() { if (posposMax) posMax=pos; tdl->AddLine( - ImVec2(pos,posY), + ImVec2(pos,chanHeadBottom), ImVec2(pos,posY+textSize.y), ImGui::GetColorU32(uiColors[GUI_COLOR_PATTERN_PAIR]), 2.0f*dpiScale @@ -1230,21 +1275,26 @@ void FurnaceGUI::drawPattern() { 2.0f*dpiScale ); - ImGui::RenderFrame( - ImVec2(posCenter-textSize.x*0.5-6.0f*dpiScale,posY+textSize.y*0.5-3.0f*dpiScale), - ImVec2(posCenter+textSize.x*0.5+6.0f*dpiScale,posY+textSize.y*1.5+3.0f*dpiScale), - ImGui::GetColorU32(ImGuiCol_FrameBg), - true, - ImGui::GetStyle().FrameRounding - ); - - tdl->AddText( - ImVec2(posCenter-textSize.x*0.5,posY+textSize.y*0.5), - ImGui::GetColorU32(ImGuiCol_Text), - pairs.label - ); + delayedLabels.push_back(DelayedLabel(posCenter,posY,textSize,pairs.label)); } } + + for (DelayedLabel& i: delayedLabels) { + ImGui::RenderFrameDrawList( + tdl, + ImVec2(i.posCenter-i.textSize.x*0.5-6.0f*dpiScale,i.posY+i.textSize.y*0.5-3.0f*dpiScale), + ImVec2(i.posCenter+i.textSize.x*0.5+6.0f*dpiScale,i.posY+i.textSize.y*1.5+3.0f*dpiScale), + ImGui::GetColorU32(ImGuiCol_FrameBg), + true, + ImGui::GetStyle().FrameRounding + ); + + tdl->AddText( + ImVec2(i.posCenter-i.textSize.x*0.5,i.posY+i.textSize.y*0.5), + ImGui::GetColorU32(ImGuiCol_Text), + i.label + ); + } } ImGui::PopFont();