From e655cdf6d3d5a56212d0a300bd9aa0e4f07b1a57 Mon Sep 17 00:00:00 2001 From: shweet Date: Wed, 19 Nov 2025 15:20:26 -0500 Subject: [PATCH] some nice tooltip stuff --- src/anm2/anm2_type.h | 8 +-- src/imgui/documents.cpp | 2 + src/imgui/window/animations.cpp | 8 +-- src/imgui/window/spritesheets.cpp | 36 +++++----- src/imgui/window/timeline.cpp | 105 ++++++++++++++++++++++++++---- workshop/metadata.xml | 2 +- 6 files changed, 121 insertions(+), 40 deletions(-) diff --git a/src/anm2/anm2_type.h b/src/anm2/anm2_type.h index 455aa16..91fecc7 100644 --- a/src/anm2/anm2_type.h +++ b/src/anm2/anm2_type.h @@ -26,10 +26,10 @@ namespace anm2ed::anm2 #define TYPE_LIST \ X(NONE, "", "", resource::icon::NONE, glm::vec4(), glm::vec4(), glm::vec4()) \ - X(ROOT, "Root", "RootAnimation", resource::icon::ROOT, ROOT_COLOR, ROOT_COLOR_ACTIVE, ROOT_COLOR_HOVERED) \ - X(LAYER, "Layer", "LayerAnimation", resource::icon::LAYER, LAYER_COLOR, LAYER_COLOR_ACTIVE, LAYER_COLOR_HOVERED) \ - X(NULL_, "Null", "NullAnimation", resource::icon::NULL_, NULL_COLOR, NULL_COLOR_ACTIVE, NULL_COLOR_HOVERED) \ - X(TRIGGER, "Triggers", "Triggers", resource::icon::TRIGGERS, TRIGGER_COLOR, TRIGGER_COLOR_ACTIVE, \ + X(ROOT, "Root", "Root", resource::icon::ROOT, ROOT_COLOR, ROOT_COLOR_ACTIVE, ROOT_COLOR_HOVERED) \ + X(LAYER, "Layer", "Layer Animation", resource::icon::LAYER, LAYER_COLOR, LAYER_COLOR_ACTIVE, LAYER_COLOR_HOVERED) \ + X(NULL_, "Null", "Null Animation", resource::icon::NULL_, NULL_COLOR, NULL_COLOR_ACTIVE, NULL_COLOR_HOVERED) \ + X(TRIGGER, "Trigger", "Triggers", resource::icon::TRIGGERS, TRIGGER_COLOR, TRIGGER_COLOR_ACTIVE, \ TRIGGER_COLOR_HOVERED) enum Type diff --git a/src/imgui/documents.cpp b/src/imgui/documents.cpp index 748fab4..959eb46 100644 --- a/src/imgui/documents.cpp +++ b/src/imgui/documents.cpp @@ -100,6 +100,8 @@ namespace anm2ed::imgui ImGui::EndTabItem(); } + ImGui::SetItemTooltip("%s", document.path.c_str()); + ImGui::PopFont(); } diff --git a/src/imgui/window/animations.cpp b/src/imgui/window/animations.cpp index a51c152..da170a4 100644 --- a/src/imgui/window/animations.cpp +++ b/src/imgui/window/animations.cpp @@ -94,13 +94,7 @@ namespace anm2ed::imgui ImGui::TextUnformatted(animation.name.c_str()); ImGui::PopFont(); - if (isDefault) - { - - ImGui::PushFont(resources.fonts[font::ITALICS].get(), font::SIZE); - ImGui::TextUnformatted("(Default Animation)"); - ImGui::PopFont(); - } + if (isDefault) ImGui::TextUnformatted("(Default Animation)"); ImGui::Text("Length: %d", animation.frameNum); ImGui::Text("Loop: %s", animation.isLoop ? "true" : "false"); diff --git a/src/imgui/window/spritesheets.cpp b/src/imgui/window/spritesheets.cpp index 5e09e60..d8f07eb 100644 --- a/src/imgui/window/spritesheets.cpp +++ b/src/imgui/window/spritesheets.cpp @@ -111,15 +111,13 @@ namespace anm2ed::imgui } auto viewport = ImGui::GetMainViewport(); - auto textureSize = texture.size.x * texture.size.y > (viewport->Size.x * viewport->Size.y) * 0.5f - ? to_vec2(viewport->Size) * 0.5f - : vec2(texture.size); - auto aspectRatio = (float)texture.size.x / texture.size.y; - - if (textureSize.x / textureSize.y > aspectRatio) - textureSize.x = textureSize.y * aspectRatio; - else - textureSize.y = textureSize.x / aspectRatio; + auto maxPreviewSize = to_vec2(viewport->Size) * 0.5f; + vec2 textureSize = vec2(glm::max(texture.size.x, 1), glm::max(texture.size.y, 1)); + if (textureSize.x > maxPreviewSize.x || textureSize.y > maxPreviewSize.y) + { + auto scale = glm::min(maxPreviewSize.x / textureSize.x, maxPreviewSize.y / textureSize.y); + textureSize *= scale; + } auto textWidth = ImGui::CalcTextSize(pathCStr).x; auto tooltipPadding = style.WindowPadding.x * 4.0f; @@ -132,21 +130,29 @@ namespace anm2ed::imgui if (ImGui::BeginItemTooltip()) { ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2()); - if (ImGui::BeginChild("##Spritesheet Tooltip Image Child", to_imvec2(textureSize), - ImGuiChildFlags_Borders)) - ImGui::Image(texture.id, ImGui::GetContentRegionAvail()); + auto childFlags = ImGuiChildFlags_Borders | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY; + auto noScrollFlags = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse; + if (ImGui::BeginChild("##Spritesheet Tooltip Image Child", to_imvec2(textureSize), childFlags, + noScrollFlags)) + ImGui::Image(texture.id, to_imvec2(textureSize)); ImGui::EndChild(); ImGui::PopStyleVar(); ImGui::SameLine(); - if (ImGui::BeginChild("##Spritesheet Info Tooltip Child")) + auto infoChildFlags = ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY; + if (ImGui::BeginChild("##Spritesheet Info Tooltip Child", ImVec2(0, 0), infoChildFlags, noScrollFlags)) { ImGui::PushFont(resources.fonts[font::BOLD].get(), font::SIZE); ImGui::TextUnformatted(pathCStr); ImGui::PopFont(); + ImGui::Text("ID: %d", id); - ImGui::Text("Size: %d x %d", texture.size.x, texture.size.y); + + if (!spritesheet.texture.is_valid()) + ImGui::Text("This spritesheet isn't valid!\nLoad an existing, valid texture."); + else + ImGui::Text("Size: %d x %d", texture.size.x, texture.size.y); } ImGui::EndChild(); @@ -155,7 +161,7 @@ namespace anm2ed::imgui ImGui::PopStyleVar(2); auto imageSize = to_imvec2(vec2(spritesheetChildSize.y)); - aspectRatio = (float)texture.size.x / texture.size.y; + auto aspectRatio = (float)texture.size.x / texture.size.y; if (imageSize.x / imageSize.y > aspectRatio) imageSize.x = imageSize.y * aspectRatio; diff --git a/src/imgui/window/timeline.cpp b/src/imgui/window/timeline.cpp index ef9577b..59e4499 100644 --- a/src/imgui/window/timeline.cpp +++ b/src/imgui/window/timeline.cpp @@ -6,6 +6,7 @@ #include +#include "math_.h" #include "toast.h" #include "vector_.h" @@ -77,6 +78,7 @@ namespace anm2ed::imgui constexpr auto FRAME_MULTIPLE = 5; constexpr auto FRAME_DRAG_PAYLOAD_ID = "Frame Drag Drop"; + constexpr auto FRAME_TOOLTIP_HOVER_DELAY = 0.75f; // Extra delay for frame info tooltip. constexpr auto HELP_FORMAT = R"(- Press {} to decrement time. - Press {} to increment time. @@ -812,25 +814,102 @@ namespace anm2ed::imgui ImGui::PopStyleColor(4); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.WindowPadding); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing); + auto& imguiStyle = ImGui::GetStyle(); + auto previousTooltipFlags = imguiStyle.HoverFlagsForTooltipMouse; + auto previousTooltipDelay = imguiStyle.HoverDelayNormal; + imguiStyle.HoverFlagsForTooltipMouse = ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayNormal | + ImGuiHoveredFlags_AllowWhenDisabled | + ImGuiHoveredFlags_NoSharedDelay; + imguiStyle.HoverDelayNormal = FRAME_TOOLTIP_HOVER_DELAY; + bool showFrameTooltip = ImGui::BeginItemTooltip(); + imguiStyle.HoverFlagsForTooltipMouse = previousTooltipFlags; + imguiStyle.HoverDelayNormal = previousTooltipDelay; + + if (showFrameTooltip) + { + + if (type != anm2::TRIGGER) + { + ImGui::PushFont(resources.fonts[font::BOLD].get(), font::SIZE); + ImGui::Text("%s Frame", anm2::TYPE_STRINGS[type]); + ImGui::PopFont(); + + auto float_text = [&](std::string label, float& value) + { + std::string useFormat = math::float_format_get(value); + std::string format(label + ": " + useFormat); + ImGui::Text(format.c_str(), value); + }; + + auto vec2_text = [&](std::string label, vec2& value) + { + std::string useFormat = math::vec2_format_get(value); + std::string format(label + ": " + useFormat + ", " + useFormat); + ImGui::Text(format.c_str(), value.x, value.y); + }; + + ImGui::Text("Index: %i", (int)i); + + if (type == anm2::LAYER) + { + vec2_text("Crop", frame.crop); + vec2_text("Size", frame.size); + } + + vec2_text("Position", frame.size); + + if (type == anm2::LAYER) vec2_text("Pivot", frame.pivot); + + vec2_text("Scale", frame.scale); + float_text("Rotation", frame.rotation); + ImGui::Text("Duration: %i", frame.duration); + ImGui::Text("Tint: %i, %i, %i, %i", math::float_to_uint8(frame.tint.r), + math::float_to_uint8(frame.tint.g), math::float_to_uint8(frame.tint.b), + math::float_to_uint8(frame.tint.a)); + ImGui::Text("Color Offset: %i, %i, %i", math::float_to_uint8(frame.tint.r), + math::float_to_uint8(frame.tint.g), math::float_to_uint8(frame.tint.b)); + ImGui::Text("Visible: %s", frame.isVisible ? "true" : "false"); + ImGui::Text("Interpolated: %s", frame.isInterpolated ? "true" : "false"); + } + else + { + ImGui::PushFont(resources.fonts[font::BOLD].get(), font::SIZE); + ImGui::Text("%s", anm2::TYPE_STRINGS[type]); + ImGui::PopFont(); + + ImGui::Text("At Frame: %i", frame.atFrame); + ImGui::Text("Event: %s", document.event.labels[frame.eventID + 1]); + ImGui::Text("Sound: %s", document.sound.labels[frame.soundID + 1]); + } + + ImGui::EndTooltip(); + } + ImGui::PopStyleVar(2); + if (ImGui::IsItemHovered() && ImGui::IsMouseDown(ImGuiMouseButton_Left)) { - if (type == anm2::TRIGGER || ImGui::IsKeyDown(ImGuiMod_Ctrl)) + if (ImGui::IsMouseDown(ImGuiMouseButton_Left)) { - draggedFrame = &frame; - draggedFrameIndex = (int)i; - draggedFrameStart = hoveredTime; - if (type != anm2::TRIGGER) draggedFrameStartDuration = draggedFrame->duration; + if (type == anm2::TRIGGER || ImGui::IsKeyDown(ImGuiMod_Ctrl)) + { + draggedFrame = &frame; + draggedFrameIndex = (int)i; + draggedFrameStart = hoveredTime; + if (type != anm2::TRIGGER) draggedFrameStartDuration = draggedFrame->duration; + } } } if (type != anm2::TRIGGER) { - if (!draggedFrame && ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceNoPreviewTooltip)) - { - frameDragDrop = {}; - frameDragDrop.type = type; - frameDragDrop.itemID = id; - frameDragDrop.animationIndex = reference.animationIndex; + if (!draggedFrame && ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceNoPreviewTooltip)) + { + frameDragDrop = {}; + frameDragDrop.type = type; + frameDragDrop.itemID = id; + frameDragDrop.animationIndex = reference.animationIndex; auto append_valid_indices = [&](const auto& container) { @@ -870,8 +949,8 @@ namespace anm2ed::imgui ImGui::EndDragDropSource(); } - if (!draggedFrame && ImGui::BeginDragDropTarget()) - { + if (!draggedFrame && ImGui::BeginDragDropTarget()) + { if (auto payload = ImGui::AcceptDragDropPayload(FRAME_DRAG_PAYLOAD_ID)) { auto source = static_cast(payload->Data); diff --git a/workshop/metadata.xml b/workshop/metadata.xml index b73043e..c74d345 100644 --- a/workshop/metadata.xml +++ b/workshop/metadata.xml @@ -40,6 +40,6 @@ Alternatively, if you have subscribed to the mod, you can find the latest releas [h3]Happy animating![/h3] [img]https://files.catbox.moe/4auc1c.gif[/img] - 2.4 + 2.5 Public