diff --git a/lib/libimhex/include/hex/ui/imgui_imhex_extensions.h b/lib/libimhex/include/hex/ui/imgui_imhex_extensions.h index 62822f11d..d8610154a 100644 --- a/lib/libimhex/include/hex/ui/imgui_imhex_extensions.h +++ b/lib/libimhex/include/hex/ui/imgui_imhex_extensions.h @@ -295,7 +295,7 @@ namespace ImGuiExt { bool DimmedIconToggle(const char *icon, bool *v); bool DimmedIconToggle(const char *iconOn, const char *iconOff, bool *v); - void TextOverlay(const char *text, ImVec2 pos); + void TextOverlay(const char *text, ImVec2 pos, float maxWidth = -1); bool BeginBox(); void EndBox(); diff --git a/lib/libimhex/source/ui/imgui_imhex_extensions.cpp b/lib/libimhex/source/ui/imgui_imhex_extensions.cpp index 48de49aff..599853716 100644 --- a/lib/libimhex/source/ui/imgui_imhex_extensions.cpp +++ b/lib/libimhex/source/ui/imgui_imhex_extensions.cpp @@ -1164,8 +1164,8 @@ namespace ImGuiExt { return toggled; } - void TextOverlay(const char *text, ImVec2 pos) { - const auto textSize = CalcTextSize(text); + void TextOverlay(const char *text, ImVec2 pos, float maxWidth) { + const auto textSize = CalcTextSize(text, nullptr, false, maxWidth); const auto textPos = pos - textSize / 2; const auto margin = GetStyle().FramePadding * 2; const auto textRect = ImRect(textPos - margin, textPos + textSize + margin); @@ -1174,7 +1174,7 @@ namespace ImGuiExt { drawList->AddRectFilled(textRect.Min, textRect.Max, GetColorU32(ImGuiCol_WindowBg) | 0xFF000000); drawList->AddRect(textRect.Min, textRect.Max, GetColorU32(ImGuiCol_Border)); - drawList->AddText(textPos, GetColorU32(ImGuiCol_Text), text); + drawList->AddText(nullptr, 0.0F, textPos, GetColorU32(ImGuiCol_Text), text, nullptr, maxWidth); } bool BeginBox() { diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index d47b5bd97..0acd9de74 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -961,6 +961,9 @@ "hex.builtin.view.pattern_editor.menu.replace_all": "Replace All", "hex.builtin.view.pattern_editor.name": "Pattern editor", "hex.builtin.view.pattern_editor.no_in_out_vars": "Define some global variables with the 'in' or 'out' specifier for them to appear here.", + "hex.builtin.view.pattern_editor.no_sections": "Create additional output sections to display and decode processed data by using the std::mem::create_section function.", + "hex.builtin.view.pattern_editor.no_virtual_files": "Visualize regions of data as a virtual folder structure by adding them using the hex::core::add_virtual_file function.", + "hex.builtin.view.pattern_editor.no_env_vars": "The content of Environment Variables created here can be accessed from Pattern scripts using the std::env function.", "hex.builtin.view.pattern_editor.no_results": "no results", "hex.builtin.view.pattern_editor.of": "of", "hex.builtin.view.pattern_editor.open_pattern": "Open pattern", diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index 9dbc4bbdf..3a609c522 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -1094,6 +1094,10 @@ namespace hex::plugin::builtin { static u32 envVarCounter = 1; if (ImGui::BeginChild("##env_vars", size, true, ImGuiWindowFlags_AlwaysVerticalScrollbar)) { + if (envVars.size() <= 1) { + ImGuiExt::TextOverlay("hex.builtin.view.pattern_editor.no_env_vars"_lang, ImGui::GetWindowPos() + ImGui::GetWindowSize() / 2, ImGui::GetWindowWidth() * 0.7); + } + if (ImGui::BeginTable("##env_vars_table", 4, ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_BordersInnerH)) { ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthStretch, 0.1F); ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch, 0.4F); @@ -1197,63 +1201,63 @@ namespace hex::plugin::builtin { void ViewPatternEditor::drawVariableSettings(ImVec2 size, std::map &patternVariables) { if (ImGui::BeginChild("##settings", size, true, ImGuiWindowFlags_AlwaysVerticalScrollbar)) { if (patternVariables.empty()) { - ImGuiExt::TextFormattedCentered("hex.builtin.view.pattern_editor.no_in_out_vars"_lang); - } else { - if (ImGui::BeginTable("##in_out_vars_table", 2, ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_RowBg)) { - ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch, 0.25F); - ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch, 0.75F); + ImGuiExt::TextOverlay("hex.builtin.view.pattern_editor.no_in_out_vars"_lang, ImGui::GetWindowPos() + ImGui::GetWindowSize() / 2, ImGui::GetWindowWidth() * 0.7); + } - for (auto &[name, variable] : patternVariables) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); + if (ImGui::BeginTable("##in_out_vars_table", 2, ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_RowBg)) { + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch, 0.25F); + ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch, 0.75F); - ImGui::TextUnformatted(name.c_str()); + for (auto &[name, variable] : patternVariables) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); - ImGui::TableNextColumn(); + ImGui::TextUnformatted(name.c_str()); - ImGui::PushItemWidth(-1); - if (variable.outVariable) { - ImGuiExt::TextFormattedSelectable("{}", variable.value.toString(true).c_str()); - } else if (variable.inVariable) { - const std::string label { "##" + name }; + ImGui::TableNextColumn(); - if (pl::core::Token::isSigned(variable.type)) { - i64 value = hex::get_or(variable.value, 0); - if (ImGui::InputScalar(label.c_str(), ImGuiDataType_S64, &value)) - m_hasUnevaluatedChanges = true; - variable.value = i128(value); - } else if (pl::core::Token::isUnsigned(variable.type)) { - u64 value = hex::get_or(variable.value, 0); - if (ImGui::InputScalar(label.c_str(), ImGuiDataType_U64, &value)) - m_hasUnevaluatedChanges = true; - variable.value = u128(value); - } else if (pl::core::Token::isFloatingPoint(variable.type)) { - auto value = hex::get_or(variable.value, 0.0); - if (ImGui::InputScalar(label.c_str(), ImGuiDataType_Double, &value)) - m_hasUnevaluatedChanges = true; - variable.value = value; - } else if (variable.type == pl::core::Token::ValueType::Boolean) { - auto value = hex::get_or(variable.value, false); - if (ImGui::Checkbox(label.c_str(), &value)) - m_hasUnevaluatedChanges = true; - variable.value = value; - } else if (variable.type == pl::core::Token::ValueType::Character) { - std::array buffer = { hex::get_or(variable.value, '\x00') }; - if (ImGui::InputText(label.c_str(), buffer.data(), buffer.size())) - m_hasUnevaluatedChanges = true; - variable.value = buffer[0]; - } else if (variable.type == pl::core::Token::ValueType::String) { - std::string buffer = hex::get_or(variable.value, ""); - if (ImGui::InputText(label.c_str(), buffer)) - m_hasUnevaluatedChanges = true; - variable.value = buffer; - } + ImGui::PushItemWidth(-1); + if (variable.outVariable) { + ImGuiExt::TextFormattedSelectable("{}", variable.value.toString(true).c_str()); + } else if (variable.inVariable) { + const std::string label { "##" + name }; + + if (pl::core::Token::isSigned(variable.type)) { + i64 value = hex::get_or(variable.value, 0); + if (ImGui::InputScalar(label.c_str(), ImGuiDataType_S64, &value)) + m_hasUnevaluatedChanges = true; + variable.value = i128(value); + } else if (pl::core::Token::isUnsigned(variable.type)) { + u64 value = hex::get_or(variable.value, 0); + if (ImGui::InputScalar(label.c_str(), ImGuiDataType_U64, &value)) + m_hasUnevaluatedChanges = true; + variable.value = u128(value); + } else if (pl::core::Token::isFloatingPoint(variable.type)) { + auto value = hex::get_or(variable.value, 0.0); + if (ImGui::InputScalar(label.c_str(), ImGuiDataType_Double, &value)) + m_hasUnevaluatedChanges = true; + variable.value = value; + } else if (variable.type == pl::core::Token::ValueType::Boolean) { + auto value = hex::get_or(variable.value, false); + if (ImGui::Checkbox(label.c_str(), &value)) + m_hasUnevaluatedChanges = true; + variable.value = value; + } else if (variable.type == pl::core::Token::ValueType::Character) { + std::array buffer = { hex::get_or(variable.value, '\x00') }; + if (ImGui::InputText(label.c_str(), buffer.data(), buffer.size())) + m_hasUnevaluatedChanges = true; + variable.value = buffer[0]; + } else if (variable.type == pl::core::Token::ValueType::String) { + std::string buffer = hex::get_or(variable.value, ""); + if (ImGui::InputText(label.c_str(), buffer)) + m_hasUnevaluatedChanges = true; + variable.value = buffer; } - ImGui::PopItemWidth(); } - - ImGui::EndTable(); + ImGui::PopItemWidth(); } + + ImGui::EndTable(); } } ImGui::EndChild(); @@ -1270,6 +1274,10 @@ namespace hex::plugin::builtin { ImGui::TableHeadersRow(); + if (sections.empty()) { + ImGuiExt::TextOverlay("hex.builtin.view.pattern_editor.no_sections"_lang, ImGui::GetWindowPos() + ImGui::GetWindowSize() / 2, ImGui::GetWindowWidth() * 0.7); + } + if (TRY_LOCK(ContentRegistry::PatternLanguage::getRuntimeLock())) { for (auto &[id, section] : sections) { if (section.name.empty()) @@ -1364,6 +1372,10 @@ namespace hex::plugin::builtin { virtualFilePointers.emplace_back(&file); if (ImGui::BeginTable("Virtual File Tree", 1, ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, size)) { + if (virtualFiles.empty()) { + ImGuiExt::TextOverlay("hex.builtin.view.pattern_editor.no_virtual_files"_lang, ImGui::GetWindowPos() + ImGui::GetWindowSize() / 2, ImGui::GetWindowWidth() * 0.7); + } + ImGui::TableSetupColumn("##path", ImGuiTableColumnFlags_WidthStretch); levelId = 1; drawVirtualFileTree(virtualFilePointers); @@ -1376,7 +1388,6 @@ namespace hex::plugin::builtin { void ViewPatternEditor::drawDebugger(ImVec2 size) { const auto &runtime = ContentRegistry::PatternLanguage::getRuntime(); - if (ImGui::BeginChild("##debugger", size, true)) { auto &evaluator = runtime.getInternals().evaluator; m_breakpoints = m_textEditor.GetBreakpoints(); diff --git a/plugins/ui/source/ui/pattern_drawer.cpp b/plugins/ui/source/ui/pattern_drawer.cpp index 6ca26bd9f..00c44e86a 100644 --- a/plugins/ui/source/ui/pattern_drawer.cpp +++ b/plugins/ui/source/ui/pattern_drawer.cpp @@ -1442,7 +1442,7 @@ namespace hex::ui { m_jumpToPattern = nullptr; if (m_favoritesUpdateTask.isRunning()) { - ImGuiExt::TextOverlay("hex.ui.pattern_drawer.updating"_lang, ImGui::GetWindowPos() + ImGui::GetWindowSize() / 2); + ImGuiExt::TextOverlay("hex.ui.pattern_drawer.updating"_lang, ImGui::GetWindowPos() + ImGui::GetWindowSize() / 2, ImGui::GetWindowWidth() * 0.5); } }