diff --git a/PretextView.cpp b/PretextView.cpp index c89dd74..f26fc1b 100644 --- a/PretextView.cpp +++ b/PretextView.cpp @@ -560,6 +560,26 @@ Mouse_Move; global_variable tool_tip Tool_Tip_Move; +global_variable +point2f +MetaData_Help_Pos; + +global_variable +point2f +MetaData_Help_Size; + +global_variable +point2f +MetaData_Help_Drag_Offset; + +global_variable +u08 +MetaData_Help_Pos_Set = 0; + +global_variable +u08 +MetaData_Help_Drag = 0; + global_variable edit_pixels @@ -2898,6 +2918,18 @@ MouseMove(GLFWwindow* window, f64 x, f64 y) u32 redisplay = 0; + if (MetaData_Help_Drag && MetaData_Edit_Mode && !UI_On) + { + s32 w, h; + glfwGetWindowSize(window, &w, &h); + MetaData_Help_Pos.x = (f32)x - MetaData_Help_Drag_Offset.x; + MetaData_Help_Pos.y = (f32)y - MetaData_Help_Drag_Offset.y; + MetaData_Help_Pos.x = my_Max(0.0f, my_Min(MetaData_Help_Pos.x, (f32)w - MetaData_Help_Size.x)); + MetaData_Help_Pos.y = my_Max(0.0f, my_Min(MetaData_Help_Pos.y, (f32)h - MetaData_Help_Size.y)); + MetaData_Help_Pos_Set = 1; + redisplay = 1; + } + if (UI_On) { } @@ -3252,10 +3284,10 @@ Mouse(GLFWwindow* window, s32 button, s32 action, s32 mods) MouseMove(window, x, y); if (!Edit_Pixels.editing) UpdateScaffolds(); } - else if (button == GLFW_MOUSE_BUTTON_MIDDLE && Edit_Mode && action == GLFW_RELEASE && !Edit_Pixels.editing) + else if (button == GLFW_MOUSE_BUTTON_MIDDLE && Edit_Mode && action == GLFW_RELEASE && Edit_Pixels.selecting) { - Edit_Pixels.editing = 1; Edit_Pixels.selecting = 0; + if (!Edit_Pixels.editing) Edit_Pixels.editing = 1; MouseMove(window, x, y); } else if (button == GLFW_MOUSE_BUTTON_MIDDLE && Edit_Mode && action == GLFW_PRESS && !Edit_Pixels.editing) @@ -3314,14 +3346,31 @@ Mouse(GLFWwindow* window, s32 button, s32 action, s32 mods) } else if (button == primaryMouse && MetaData_Edit_Mode && action == GLFW_PRESS) { - MetaData_Edit_State = 1; - MouseMove(window, x, y); + if (MetaData_Help_Pos_Set && + x >= MetaData_Help_Pos.x && + y >= MetaData_Help_Pos.y && + x <= (MetaData_Help_Pos.x + MetaData_Help_Size.x) && + y <= (MetaData_Help_Pos.y + MetaData_Help_Size.y)) + { + MetaData_Help_Drag = 1; + MetaData_Help_Drag_Offset.x = (f32)x - MetaData_Help_Pos.x; + MetaData_Help_Drag_Offset.y = (f32)y - MetaData_Help_Pos.y; + } + else + { + MetaData_Edit_State = 1; + MouseMove(window, x, y); + } } else if (button == GLFW_MOUSE_BUTTON_MIDDLE && MetaData_Edit_Mode && action == GLFW_PRESS) { MetaData_Edit_State = 2; MouseMove(window, x, y); } + else if (button == primaryMouse && MetaData_Help_Drag && action == GLFW_RELEASE) + { + MetaData_Help_Drag = 0; + } else if ((button == GLFW_MOUSE_BUTTON_MIDDLE || button == primaryMouse) && MetaData_Edit_Mode && action == GLFW_RELEASE) { MetaData_Edit_State = 0; @@ -5247,10 +5296,24 @@ Render() { glUseProgram(Flat_Shader->shaderProgram); glUniform4fv(Flat_Shader->colorLocation, 1, (f32 *)&MetaData_Mode_Data->bg); - vert[0].x = width - spacing - textWidth; vert[0].y = height - spacing - textBoxHeight; - vert[1].x = width - spacing - textWidth; vert[1].y = height - spacing; - vert[2].x = width - spacing; vert[2].y = height - spacing; - vert[3].x = width - spacing; vert[3].y = height - spacing - textBoxHeight; + MetaData_Help_Size.x = textWidth; + MetaData_Help_Size.y = textBoxHeight; + if (!MetaData_Help_Pos_Set) + { + MetaData_Help_Pos.x = width - spacing - textWidth; + MetaData_Help_Pos.y = height - spacing - textBoxHeight; + MetaData_Help_Pos_Set = 1; + } + MetaData_Help_Pos.x = my_Max(0.0f, my_Min(MetaData_Help_Pos.x, width - textWidth)); + MetaData_Help_Pos.y = my_Max(0.0f, my_Min(MetaData_Help_Pos.y, height - textBoxHeight)); + + const f32 boxX = MetaData_Help_Pos.x; + const f32 boxY = MetaData_Help_Pos.y; + + vert[0].x = boxX; vert[0].y = boxY; + vert[1].x = boxX; vert[1].y = boxY + textBoxHeight; + vert[2].x = boxX + textWidth; vert[2].y = boxY + textBoxHeight; + vert[3].x = boxX + textWidth; vert[3].y = boxY; glBindBuffer(GL_ARRAY_BUFFER, Waypoint_Data->vbos[ptr]); glBufferSubData(GL_ARRAY_BUFFER, 0, 4 * sizeof(vertex), vert); @@ -5261,8 +5324,8 @@ Render() { for (u32 i=0; i< helpTexts.size() ; i++) { fonsDrawText( FontStash_Context, - width - spacing - textWidth, - height - spacing - textBoxHeight + (lh + 1.0f) * i, + boxX, + boxY + (lh + 1.0f) * i, helpTexts[i].c_str(), 0); } @@ -5292,9 +5355,114 @@ Render() { fonsVertMetrics(FontStash_Context, 0, 0, &lh); fonsSetColor(FontStash_Context, FourFloatColorToU32(Tool_Tip->fg)); - // Extension info, extra lines + // Extension + scaffold/tag info, extra lines u32 nExtra = 0; f32 longestExtraLineLength = 0.0f; + char scaffLine[64]; + char tagLine[256]; + const u32 nPix = Number_of_Pixels_1D ? Number_of_Pixels_1D - 1 : 0; + const u32 tooltipPixelX = my_Min(Tool_Tip_Move.pixels.x, nPix); + const u32 tooltipPixelY = my_Min(Tool_Tip_Move.pixels.y, nPix); + const u32 tooltipPixel = tooltipPixelX; + const u32 scaffId = Map_State->scaffIds[tooltipPixel]; + stbsp_snprintf(scaffLine, sizeof(scaffLine), "Scaffold: %u", scaffId); + longestExtraLineLength = my_Max( + longestExtraLineLength, + fonsTextBounds(FontStash_Context, 0, 0, scaffLine, 0, NULL)); + ++nExtra; + + { + u64 flags = Map_State->metaDataFlags[tooltipPixel]; + if (Contigs && tooltipPixel < Number_of_Pixels_1D) + { + u32 contigId = Map_State->contigIds[tooltipPixel]; + if (contigId < Contigs->numberOfContigs) + { + u64 *flagPtr = (Contigs->contigs_arr + contigId)->metaDataFlags; + if (flagPtr) flags = *flagPtr; + } + } + if (!flags) + { + stbsp_snprintf(tagLine, sizeof(tagLine), "Tags: "); + } + else + { + const u32 maxShown = 6; + char tagsBuffer[192]; + const size_t tagsBufferSize = sizeof(tagsBuffer); + tagsBuffer[0] = '\0'; + u32 tagCount = 0; + u32 shownCount = 0; + size_t tagsLen = 0; + ForLoop(ArrayCount(Meta_Data->tags)) + { + if (!(flags & (1ULL << index))) continue; + ++tagCount; + if (shownCount >= maxShown) continue; + const char *tagName = (const char *)Meta_Data->tags[index]; + char fallback[16]; + if (!tagName || !tagName[0]) + { + stbsp_snprintf(fallback, sizeof(fallback), "Tag%u", index + 1); + tagName = fallback; + } + if (tagsLen + 1 >= tagsBufferSize) break; + if (shownCount) + { + size_t remaining = tagsBufferSize - tagsLen; + int wrote = stbsp_snprintf( + tagsBuffer + tagsLen, + remaining, + ", "); + if (wrote < 0) break; + if ((size_t)wrote >= remaining) + { + tagsLen = tagsBufferSize - 1; + tagsBuffer[tagsLen] = '\0'; + break; + } + tagsLen += (size_t)wrote; + } + { + size_t remaining = tagsBufferSize - tagsLen; + int wrote = stbsp_snprintf( + tagsBuffer + tagsLen, + remaining, + "%s", + tagName); + if (wrote < 0) break; + if ((size_t)wrote >= remaining) + { + tagsLen = tagsBufferSize - 1; + tagsBuffer[tagsLen] = '\0'; + break; + } + tagsLen += (size_t)wrote; + } + ++shownCount; + } + if (tagCount > shownCount) + { + stbsp_snprintf( + tagLine, + sizeof(tagLine), + "Tags: %s +%u more", + tagsBuffer, + tagCount - shownCount); + } + else + { + stbsp_snprintf(tagLine, sizeof(tagLine), "Tags: %s", tagsBuffer); + } + } + } + longestExtraLineLength = my_Max( + longestExtraLineLength, + fonsTextBounds(FontStash_Context, 0, 0, tagLine, 0, NULL)); + ++nExtra; + + const u32 extraFixedLines = 2; { if (Extensions.head) { @@ -5309,7 +5477,7 @@ Render() { if (gph->on) { glBindBuffer(GL_TEXTURE_BUFFER, Contact_Matrix->pixelRearrangmentLookupBuffer); - u32 *buffer = (u32 *)glMapBufferRange(GL_TEXTURE_BUFFER, Tool_Tip_Move.pixels.x * sizeof(u32), sizeof(u32), GL_MAP_READ_BIT); + u32 *buffer = (u32 *)glMapBufferRange(GL_TEXTURE_BUFFER, tooltipPixelX * sizeof(u32), sizeof(u32), GL_MAP_READ_BIT); stbsp_snprintf(buff, sizeof(buff), "%s: %$d", (char *)gph->name, gph->data[*buffer]); ++nExtra; @@ -5329,10 +5497,10 @@ Render() { textBoxHeight *= (3.0f + (f32)nExtra); textBoxHeight += (2.0f + (f32)nExtra); - u32 id1 = GetOriginalContigBaseId(Map_State->originalContigIds[Tool_Tip_Move.pixels.x]); - u32 id2 = GetOriginalContigBaseId(Map_State->originalContigIds[Tool_Tip_Move.pixels.y]); - u32 coord1 = Map_State->contigRelCoords[Tool_Tip_Move.pixels.x]; - u32 coord2 = Map_State->contigRelCoords[Tool_Tip_Move.pixels.y]; + u32 id1 = GetOriginalContigBaseId(Map_State->originalContigIds[tooltipPixelX]); + u32 id2 = GetOriginalContigBaseId(Map_State->originalContigIds[tooltipPixelY]); + u32 coord1 = Map_State->contigRelCoords[tooltipPixelX]; + u32 coord2 = Map_State->contigRelCoords[tooltipPixelY]; f64 bpPerPixel = (f64)Total_Genome_Length / (f64)Number_of_Pixels_1D; @@ -5377,6 +5545,10 @@ Render() { ModelYToScreen(-Tool_Tip_Move.worldCoords.y) + spacing + lh + 1.0f, line2, 0); fonsDrawText(FontStash_Context, ModelXToScreen(Tool_Tip_Move.worldCoords.x) + spacing, ModelYToScreen(-Tool_Tip_Move.worldCoords.y) + spacing + (2.0f * lh) + 2.0f, line3, 0); + fonsDrawText(FontStash_Context, ModelXToScreen(Tool_Tip_Move.worldCoords.x) + spacing, + ModelYToScreen(-Tool_Tip_Move.worldCoords.y) + spacing + (3.0f * (lh + 1.0f)), scaffLine, 0); + fonsDrawText(FontStash_Context, ModelXToScreen(Tool_Tip_Move.worldCoords.x) + spacing, + ModelYToScreen(-Tool_Tip_Move.worldCoords.y) + spacing + (4.0f * (lh + 1.0f)), tagLine, 0); { if (Extensions.head) @@ -5393,12 +5565,12 @@ Render() { if (gph->on) { glBindBuffer(GL_TEXTURE_BUFFER, Contact_Matrix->pixelRearrangmentLookupBuffer); - u32 *buffer = (u32 *)glMapBufferRange(GL_TEXTURE_BUFFER, Tool_Tip_Move.pixels.x * sizeof(u32), sizeof(u32), GL_MAP_READ_BIT); + u32 *buffer = (u32 *)glMapBufferRange(GL_TEXTURE_BUFFER, tooltipPixelX * sizeof(u32), sizeof(u32), GL_MAP_READ_BIT); stbsp_snprintf(buff, sizeof(buff), "%s: %$d", (char *)gph->name, gph->data[*buffer]); fonsDrawText(FontStash_Context, ModelXToScreen(Tool_Tip_Move.worldCoords.x) + spacing, - ModelYToScreen(-Tool_Tip_Move.worldCoords.y) + spacing + ((2.0f + (f32)(++count)) * (lh + 1.0f)), buff, 0); + ModelYToScreen(-Tool_Tip_Move.worldCoords.y) + spacing + ((2.0f + (f32)extraFixedLines + (f32)(++count)) * (lh + 1.0f)), buff, 0); glUnmapBuffer(GL_TEXTURE_BUFFER); glBindBuffer(GL_TEXTURE_BUFFER, 0); @@ -6324,6 +6496,9 @@ LoadFile(const char *filePath, memory_arena *arena, char **fileName, u64 *header Edit_Pixels.editing = 0; Global_Mode = mode_normal; + MetaData_Help_Pos_Set = 0; + MetaData_Help_Drag = 0; + Extensions = {}; // delete the memory collected by new @@ -9593,10 +9768,10 @@ KeyBoard(GLFWwindow* window, s32 key, s32 scancode, s32 action, s32 mods) glfwGetCursorPos(window, &x, &y); MouseMove(window, x, y); } - else if (Edit_Mode && !Edit_Pixels.editing && action == GLFW_RELEASE) + else if (Edit_Mode && Edit_Pixels.selecting && action == GLFW_RELEASE) { - Edit_Pixels.editing = 1; Edit_Pixels.selecting = 0; + if (!Edit_Pixels.editing) Edit_Pixels.editing = 1; f64 x, y; glfwGetCursorPos(window, &x, &y); MouseMove(window, x, y);