GUI: new pattern renderer, part 26

it's ready (98%)
before deploying I am going to add a pop-up though
This commit is contained in:
tildearrow 2026-01-07 13:22:11 -05:00
parent 1c5acdf40a
commit e61832ed71
3 changed files with 63 additions and 19 deletions

View file

@ -3794,11 +3794,13 @@ void FurnaceGUI::pointMotion(int x, int y, int xrel, int yrel) {
if (y>patWindowPos.y+patWindowSize.y-2.0f*dpiScale) {
addScroll(1);
}
if (x<patWindowPos.x+(mobileUI?40.0f:4.0f)*dpiScale) {
addScrollX(-1);
}
if (x>patWindowPos.x+patWindowSize.x-(mobileUI?40.0f:4.0f)*dpiScale) {
addScrollX(1);
if (!selectingFull) {
if (x<patWindowPos.x+(mobileUI?40.0f:4.0f)*dpiScale) {
addScrollX(-1);
}
if (x>patWindowPos.x+patWindowSize.x-(mobileUI?40.0f:4.0f)*dpiScale) {
addScrollX(1);
}
}
}
if (macroDragActive || macroLoopDragActive || waveDragActive || sampleDragActive || orderScrollLocked) {
@ -5176,6 +5178,7 @@ bool FurnaceGUI::loop() {
if (!selectingFull) cursor=selEnd;
finishSelection();
if (!mobileUI) {
// TODO: don't demand if selectingFull?
demandScrollX=true;
if (cursor.xCoarse==selStart.xCoarse && cursor.xFine==selStart.xFine && cursor.y==selStart.y && cursor.order==selStart.order &&
cursor.xCoarse==selEnd.xCoarse && cursor.xFine==selEnd.xFine && cursor.y==selEnd.y && cursor.order==selEnd.order) {

View file

@ -964,11 +964,6 @@ void FurnaceGUI::drawPatternNew() {
ImGui::EndGroup();
}
/*if (e->hasExtValue()) {
ImGui::TextColored(uiColors[GUI_COLOR_EE_VALUE]," %.2X",e->getExtValue());
}*/
//// BORDERS.
for (int i=0; i<=chans; i++) {
if (i<chans) {
@ -1014,6 +1009,8 @@ void FurnaceGUI::drawPatternNew() {
ImRect rect=ImRect(minArea,maxArea);
// pattern view
// TODO: optimize further. too many comparisons are being done for each cell.
// perhaps pre-calculate starting row?
dl->PushClipRect(ImVec2(topRows.x+sizeRows.x,topHeaders.y+sizeHeaders.y),winRect.Max,true);
ImGui::SetCursorScreenPos(top);
ImGui::ItemSize(size,ImGui::GetStyle().FramePadding.y);
@ -1022,13 +1019,6 @@ void FurnaceGUI::drawPatternNew() {
SelectionPoint pointer=SelectionPoint(-1,0,-1,-1);
ImVec2 pointerPos=ImGui::GetMousePos()-ImVec2(top.x,0);
// special value for row index
// TODO: just no. not ever.
/*
if (pointerPos.x>=top.x && pointerPos.x<patChanX[0]) {
pointer.xCoarse=-2;
}*/
for (int i=0; i<chans; i++) {
if (!e->curSubSong->chanShow[i]) continue;
if (pointerPos.x>=patChanX[i] && pointerPos.x<patChanX[i+1]) {
@ -1100,6 +1090,7 @@ void FurnaceGUI::drawPatternNew() {
ImRect(dl->GetClipRectMin(),dl->GetClipRectMax()).Contains(ImGui::GetMousePos())
);
/*
String debugText=fmt::sprintf(
"NPR DEBUG (xC:xF, o/y)\n"
"pointer: %d:%d, %d/%d %s\n"
@ -1112,6 +1103,7 @@ void FurnaceGUI::drawPatternNew() {
selEnd.xCoarse,selEnd.xFine,selEnd.order,selEnd.y
);
dl->AddText(top+ImGui::GetCurrentWindow()->Scroll,0xffffffff,debugText.c_str());
*/
// row highlights
{
@ -1417,7 +1409,6 @@ void FurnaceGUI::drawPatternNew() {
// test for selection
if (hovered) {
//dl->AddText(top+ImVec2(0,lineHeight)+ImGui::GetCurrentWindow()->Scroll,0xffffffff,"Hovered!!!!!!!");
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
startSelection(pointer.xCoarse,pointer.xFine,pointer.y,pointer.order);
}
@ -1439,12 +1430,32 @@ void FurnaceGUI::drawPatternNew() {
ImGui::ItemSize(sizeRows,ImGui::GetStyle().FramePadding.y);
if (ImGui::ItemAdd(rectRows,ImGui::GetID("PatternRows"),NULL,ImGuiItemFlags_AllowOverlap)) {
// pattern rows
int selOrd=-1;
int selRow=-1;
bool hoveredRow=(
ImGui::IsWindowHovered() &&
ImRect(dl->GetClipRectMin(),dl->GetClipRectMax()).Contains(ImGui::GetMousePos())
);
int ord=firstOrd;
int row=firstRow;
pos=topRows;
SETUP_ORDER_ALPHA;
for (int j=0; j<totalRows; j++) {
if (ord>=0 && ord<e->curSubSong->ordersLen && (settings.viewPrevPattern || ord==curOrder)) {
// test cursor pos (so many comparisons!)
if (hoveredRow && (!orderLock || ord==curOrder) && ImRect(pos,pos+ImVec2(sizeRows.x,lineHeight)).Contains(ImGui::GetMousePos()) && selOrd<0 && selRow<0) {
dl->AddRectFilled(
pos,
pos+ImVec2(sizeRows.x,lineHeight),
ImGui::ColorConvertFloat4ToU32(uiColors[GUI_COLOR_PATTERN_SELECTION_HOVER])
);
selOrd=ord;
selRow=row;
}
if (settings.patRowsBase) {
snprintf(id,63," %2X",row);
} else {
@ -1468,6 +1479,21 @@ void FurnaceGUI::drawPatternNew() {
ImGui::ColorConvertFloat4ToU32(ImGui::GetStyle().Colors[ImGuiCol_TableBorderLight]),
PAT_BORDER_SIZE
);
// test for selection
if (selOrd>=0 && selRow>=0) {
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
startSelection(0,0,selRow,selOrd,true);
}
updateSelection(0,0,selRow,selOrd,true);
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && CHECK_LONG_HOLD) {
ImGui::InhibitInertialScroll();
NOTIFY_LONG_HOLD;
mobilePatSel=true;
}
}
}
dl->PopClipRect();
@ -1729,6 +1755,21 @@ void FurnaceGUI::drawPatternNew() {
}
}
// EExx value indicator
if (e->hasExtValue()) {
pos=ImVec2(topRows.x+sizeRows.x+6.0f*dpiScale,topHeaders.y+sizeHeaders.y+6.0f*dpiScale);
ImGui::RenderFrameDrawList(
dl,
pos,
pos+ImGui::GetStyle().FramePadding*2.0f+twoChars,
ImGui::GetColorU32(ImGuiCol_FrameBg,0.75f),
true,
ImGui::GetStyle().FrameRounding
);
snprintf(id,63,"%.2X",e->getExtValue());
dl->AddText(pos+ImGui::GetStyle().FramePadding,ImGui::GetColorU32(uiColors[GUI_COLOR_EE_VALUE]),id);
}
// let's draw a warning if the instrument cannot be previewed
if (failedNoteOn) {
ImVec2 winCenter=ImGui::GetWindowPos()+ImGui::GetWindowSize()*0.5f;

View file

@ -812,7 +812,7 @@ void FurnaceGUI::drawPattern() {
ImGui::ItemSize(size,ImGui::GetStyle().FramePadding.y);
if (ImGui::ItemAdd(rect,ImGui::GetID(chanID))) {
bool hovered=ImGui::ItemHoverable(rect,ImGui::GetID(chanID),0);
ImU32 col=(hovered || (mobileUI && ImGui::IsMouseDown(ImGuiMouseButton_Left)))?ImGui::GetColorU32(ImGuiCol_HeaderHovered):ImGui::GetColorU32(ImGuiCol_Header);
ImU32 col=hovered?ImGui::GetColorU32(ImGuiCol_HeaderHovered):ImGui::GetColorU32(ImGuiCol_Header);
dl->AddRectFilled(rect.Min,rect.Max,col);
dl->AddTextNoHashHide(ImVec2(minLabelArea.x,rect.Min.y),ImGui::GetColorU32(channelTextColor(i)),chanID);
}