diff --git a/plugins/builtin/source/content/command_palette_commands.cpp b/plugins/builtin/source/content/command_palette_commands.cpp index 788ab624c..4ca04fba8 100644 --- a/plugins/builtin/source/content/command_palette_commands.cpp +++ b/plugins/builtin/source/content/command_palette_commands.cpp @@ -8,7 +8,7 @@ namespace hex::plugin::builtin { hex::ContentRegistry::CommandPaletteCommands::add( hex::ContentRegistry::CommandPaletteCommands::Type::SymbolCommand, - "#", "Calculator", + "#", "hex.builtin.command.calc.desc"_lang, [](auto input) { hex::MathEvaluator evaluator; evaluator.registerStandardVariables(); @@ -29,9 +29,9 @@ namespace hex::plugin::builtin { hex::ContentRegistry::CommandPaletteCommands::add( hex::ContentRegistry::CommandPaletteCommands::Type::KeywordCommand, - "/web", "Website lookup", + "/web", "hex.builtin.command.web.desc"_lang, [](auto input) { - return hex::format("Navigate to '%s'", input.data()); + return hex::format("hex.builtin.command.web.result"_lang, input.data()); }, [](auto input) { hex::openWebpage(input); diff --git a/plugins/builtin/source/content/data_inspector.cpp b/plugins/builtin/source/content/data_inspector.cpp index 109172734..03bc1789c 100644 --- a/plugins/builtin/source/content/data_inspector.cpp +++ b/plugins/builtin/source/content/data_inspector.cpp @@ -20,7 +20,7 @@ namespace hex::plugin::builtin { using Style = hex::ContentRegistry::DataInspector::NumberDisplayStyle; - hex::ContentRegistry::DataInspector::add("Binary (8 bit)", sizeof(u8), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.binary"_lang, sizeof(u8), [](auto buffer, auto endian, auto style) { std::string binary; for (u8 i = 0; i < 8; i++) binary += ((buffer[0] << i) & 0x80) == 0 ? '0' : '1'; @@ -28,76 +28,76 @@ namespace hex::plugin::builtin { return [binary] { ImGui::TextUnformatted(binary.c_str()); }; }); - hex::ContentRegistry::DataInspector::add("uint8_t", sizeof(u8), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.u8"_lang, sizeof(u8), [](auto buffer, auto endian, auto style) { auto format = (style == Style::Decimal) ? "%u" : ((style == Style::Hexadecimal) ? "0x%X" : "0o%o"); auto value = hex::format(format, *reinterpret_cast(buffer.data())); return [value] { ImGui::TextUnformatted(value.c_str()); }; }); - hex::ContentRegistry::DataInspector::add("int8_t", sizeof(s8), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.s8"_lang, sizeof(s8), [](auto buffer, auto endian, auto style) { auto format = (style == Style::Decimal) ? "%d" : ((style == Style::Hexadecimal) ? "0x%X" : "0o%o"); auto value = hex::format(format, *reinterpret_cast(buffer.data())); return [value] { ImGui::TextUnformatted(value.c_str()); }; }); - hex::ContentRegistry::DataInspector::add("uint16_t", sizeof(u16), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.u16"_lang, sizeof(u16), [](auto buffer, auto endian, auto style) { auto format = (style == Style::Decimal) ? "%u" : ((style == Style::Hexadecimal) ? "0x%X" : "0o%o"); auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); return [value] { ImGui::TextUnformatted(value.c_str()); }; }); - hex::ContentRegistry::DataInspector::add("int16_t", sizeof(s16), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.s16"_lang, sizeof(s16), [](auto buffer, auto endian, auto style) { auto format = (style == Style::Decimal) ? "%d" : ((style == Style::Hexadecimal) ? "0x%X" : "0o%o"); auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); return [value] { ImGui::TextUnformatted(value.c_str()); }; }); - hex::ContentRegistry::DataInspector::add("uint32_t", sizeof(u32), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.u32"_lang, sizeof(u32), [](auto buffer, auto endian, auto style) { auto format = (style == Style::Decimal) ? "%u" : ((style == Style::Hexadecimal) ? "0x%X" : "0o%o"); auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); return [value] { ImGui::TextUnformatted(value.c_str()); }; }); - hex::ContentRegistry::DataInspector::add("int32_t", sizeof(s32), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.s32"_lang, sizeof(s32), [](auto buffer, auto endian, auto style) { auto format = (style == Style::Decimal) ? "%d" : ((style == Style::Hexadecimal) ? "0x%X" : "0o%o"); auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); return [value] { ImGui::TextUnformatted(value.c_str()); }; }); - hex::ContentRegistry::DataInspector::add("uint64_t", sizeof(u64), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.u64"_lang, sizeof(u64), [](auto buffer, auto endian, auto style) { auto format = (style == Style::Decimal) ? "%llu" : ((style == Style::Hexadecimal) ? "0x%llX" : "0o%llo"); auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); return [value] { ImGui::TextUnformatted(value.c_str()); }; }); - hex::ContentRegistry::DataInspector::add("int64_t", sizeof(s64), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.s64"_lang, sizeof(s64), [](auto buffer, auto endian, auto style) { auto format = (style == Style::Decimal) ? "%lld" : ((style == Style::Hexadecimal) ? "0x%llX" : "0o%llo"); auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); return [value] { ImGui::TextUnformatted(value.c_str()); }; }); - hex::ContentRegistry::DataInspector::add("float (32 bit)", sizeof(float), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.float"_lang, sizeof(float), [](auto buffer, auto endian, auto style) { auto value = hex::format("%e", hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); return [value] { ImGui::TextUnformatted(value.c_str()); }; }); - hex::ContentRegistry::DataInspector::add("double (64 bit)", sizeof(double), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.double"_lang, sizeof(double), [](auto buffer, auto endian, auto style) { auto value = hex::format("%e", hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); return [value] { ImGui::TextUnformatted(value.c_str()); }; }); - hex::ContentRegistry::DataInspector::add("ASCII Character", sizeof(char8_t), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.ascii"_lang, sizeof(char8_t), [](auto buffer, auto endian, auto style) { auto value = hex::format("'%s'", makePrintable(*reinterpret_cast(buffer.data())).c_str()); return [value] { ImGui::TextUnformatted(value.c_str()); }; }); - hex::ContentRegistry::DataInspector::add("Wide Character", sizeof(char16_t), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.wide"_lang, sizeof(char16_t), [](auto buffer, auto endian, auto style) { auto c = *reinterpret_cast(buffer.data()); auto value = hex::format("'%lc'", c == 0 ? '\x01' : hex::changeEndianess(c, endian)); return [value] { ImGui::TextUnformatted(value.c_str()); }; }); - hex::ContentRegistry::DataInspector::add("UTF-8 code point", sizeof(char8_t) * 4, [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.utf8"_lang, sizeof(char8_t) * 4, [](auto buffer, auto endian, auto style) { char utf8Buffer[5] = { 0 }; char codepointString[5] = { 0 }; u32 codepoint = 0; @@ -116,7 +116,7 @@ namespace hex::plugin::builtin { #if defined(OS_WINDOWS) && defined(ARCH_64_BIT) - hex::ContentRegistry::DataInspector::add("__time32_t", sizeof(__time32_t), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.time32"_lang, sizeof(__time32_t), [](auto buffer, auto endian, auto style) { auto endianAdjustedTime = hex::changeEndianess(*reinterpret_cast<__time32_t*>(buffer.data()), endian); std::tm * ptm = _localtime32(&endianAdjustedTime); char timeBuffer[32]; @@ -129,7 +129,7 @@ namespace hex::plugin::builtin { return [value] { ImGui::TextUnformatted(value.c_str()); }; }); - hex::ContentRegistry::DataInspector::add("__time64_t", sizeof(__time64_t), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.time64"_lang, sizeof(__time64_t), [](auto buffer, auto endian, auto style) { auto endianAdjustedTime = hex::changeEndianess(*reinterpret_cast<__time64_t*>(buffer.data()), endian); std::tm * ptm = _localtime64(&endianAdjustedTime); char timeBuffer[64]; @@ -144,7 +144,7 @@ namespace hex::plugin::builtin { #else - hex::ContentRegistry::DataInspector::add("time_t", sizeof(time_t), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.time"_lang, sizeof(time_t), [](auto buffer, auto endian, auto style) { auto endianAdjustedTime = hex::changeEndianess(*reinterpret_cast(buffer.data()), endian); std::tm * ptm = localtime(&endianAdjustedTime); char timeBuffer[64]; @@ -159,7 +159,7 @@ namespace hex::plugin::builtin { #endif - hex::ContentRegistry::DataInspector::add("GUID", sizeof(GUID), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.guid"_lang, sizeof(GUID), [](auto buffer, auto endian, auto style) { GUID guid; std::memcpy(&guid, buffer.data(), sizeof(GUID)); auto value = hex::format("%s{%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}", @@ -173,7 +173,7 @@ namespace hex::plugin::builtin { return [value] { ImGui::TextUnformatted(value.c_str()); }; }); - hex::ContentRegistry::DataInspector::add("RGBA Color", sizeof(u32), [](auto buffer, auto endian, auto style) { + hex::ContentRegistry::DataInspector::add("hex.builtin.inspector.rgba8"_lang, sizeof(u32), [](auto buffer, auto endian, auto style) { ImColor value(hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); return [value] { diff --git a/plugins/builtin/source/content/data_processor_nodes.cpp b/plugins/builtin/source/content/data_processor_nodes.cpp index 00604eb3c..0d86d5d91 100644 --- a/plugins/builtin/source/content/data_processor_nodes.cpp +++ b/plugins/builtin/source/content/data_processor_nodes.cpp @@ -8,7 +8,9 @@ namespace hex::plugin::builtin { class NodeNullptr : public dp::Node { public: - NodeNullptr() : Node("Nullptr", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "") }) {} + NodeNullptr() : Node("hex.builtin.nodes.constants.nullptr.header"_lang, { + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "hex.builtin.nodes.constants.nullptr.output"_lang) + }) {} void process() override { this->setBufferOnOutput(0, { }); @@ -17,13 +19,15 @@ namespace hex::plugin::builtin { class NodeBuffer : public dp::Node { public: - NodeBuffer() : Node("Buffer", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "") }) {} + NodeBuffer() : Node("hex.builtin.nodes.constants.buffer.header"_lang, { + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "hex.builtin.nodes.constants.buffer.output"_lang) + }) {} void drawNode() override { constexpr int StepSize = 1, FastStepSize = 10; ImGui::PushItemWidth(100); - ImGui::InputScalar("Size", ImGuiDataType_U32, &this->m_size, &StepSize, &FastStepSize); + ImGui::InputScalar("hex.builtin.nodes.constants.buffer.size"_lang, ImGuiDataType_U32, &this->m_size, &StepSize, &FastStepSize); ImGui::PopItemWidth(); } @@ -41,7 +45,9 @@ namespace hex::plugin::builtin { class NodeString : public dp::Node { public: - NodeString() : Node("String", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "") }) { + NodeString() : Node("hex.builtin.nodes.constants.string.header"_lang, { + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "hex.builtin.nodes.constants.string.output"_lang) + }) { this->m_value.resize(0xFFF, 0x00); } @@ -66,7 +72,9 @@ namespace hex::plugin::builtin { class NodeInteger : public dp::Node { public: - NodeInteger() : Node("Integer", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "") }) {} + NodeInteger() : Node("hex.builtin.nodes.constants.int.header"_lang, { + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.constants.int.output"_lang) + }) {} void drawNode() override { ImGui::TextUnformatted("0x"); ImGui::SameLine(0, 0); @@ -88,7 +96,9 @@ namespace hex::plugin::builtin { class NodeFloat : public dp::Node { public: - NodeFloat() : Node("Float", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Float, "") }) {} + NodeFloat() : Node("hex.builtin.nodes.constants.float.header"_lang, { + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Float, "hex.builtin.nodes.constants.float.output"_lang) + }) {} void drawNode() override { ImGui::PushItemWidth(100); @@ -110,10 +120,11 @@ namespace hex::plugin::builtin { class NodeRGBA8 : public dp::Node { public: - NodeRGBA8() : Node("RGBA8 Color", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "Red"), - dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "Green"), - dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "Blue"), - dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "Alpha")}) {} + NodeRGBA8() : Node("hex.builtin.nodes.constants.rgba8.header"_lang, + { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.constants.rgba8.output.r"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.constants.rgba8.output.g"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.constants.rgba8.output.b"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.constants.rgba8.output.a"_lang)}) {} void drawNode() override { ImGui::PushItemWidth(200); @@ -135,7 +146,7 @@ namespace hex::plugin::builtin { class NodeComment : public dp::Node { public: - NodeComment() : Node("Comment", { }) { + NodeComment() : Node("hex.builtin.nodes.constants.comment.header"_lang, { }) { this->m_comment.resize(0xFFF, 0x00); } @@ -154,7 +165,9 @@ namespace hex::plugin::builtin { class NodeDisplayInteger : public dp::Node { public: - NodeDisplayInteger() : Node("Display Integer", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Value") }) {} + NodeDisplayInteger() : Node("hex.builtin.nodes.display.int.header"_lang, { + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.display.int.input"_lang) + }) {} void drawNode() override { ImGui::PushItemWidth(150); @@ -178,7 +191,9 @@ namespace hex::plugin::builtin { class NodeDisplayFloat : public dp::Node { public: - NodeDisplayFloat() : Node("Display Float", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Float, "Value") }) {} + NodeDisplayFloat() : Node("hex.builtin.nodes.display.float.header"_lang, { + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Float, "hex.builtin.nodes.display.float.input"_lang) + }) {} void drawNode() override { ImGui::PushItemWidth(150); @@ -203,7 +218,9 @@ namespace hex::plugin::builtin { class NodeBitwiseNOT : public dp::Node { public: - NodeBitwiseNOT() : Node("Bitwise NOT", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "Input"), dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "Output") }) {} + NodeBitwiseNOT() : Node("hex.builtin.nodes.bitwise.not.header"_lang, { + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.bitwise.not.input"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "hex.builtin.nodes.bitwise.not.output"_lang) }) {} void process() override { auto input = this->getBufferOnInput(0); @@ -218,7 +235,10 @@ namespace hex::plugin::builtin { class NodeBitwiseAND : public dp::Node { public: - NodeBitwiseAND() : Node("Bitwise AND", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "Input A"), dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "Input B"), dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "Output") }) {} + NodeBitwiseAND() : Node("hex.builtin.nodes.bitwise.and.header"_lang, { + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.bitwise.and.input.a"_lang), + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.bitwise.and.input.b"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "hex.builtin.nodes.bitwise.and.output"_lang) }) {} void process() override { auto inputA = this->getBufferOnInput(0); @@ -235,7 +255,10 @@ namespace hex::plugin::builtin { class NodeBitwiseOR : public dp::Node { public: - NodeBitwiseOR() : Node("Bitwise OR", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "Input A"), dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "Input B"), dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "Output") }) {} + NodeBitwiseOR() : Node("hex.builtin.nodes.bitwise.or.header"_lang, { + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.bitwise.or.input.a"_lang), + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.bitwise.or.input.b"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "hex.builtin.nodes.bitwise.or.output"_lang) }) {} void process() override { auto inputA = this->getBufferOnInput(0); @@ -252,7 +275,10 @@ namespace hex::plugin::builtin { class NodeBitwiseXOR : public dp::Node { public: - NodeBitwiseXOR() : Node("Bitwise XOR", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "Input A"), dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "Input B"), dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "Output") }) {} + NodeBitwiseXOR() : Node("hex.builtin.nodes.bitwise.xor.header"_lang, { + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.bitwise.xor.input.a"_lang), + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.bitwise.xor.input.b"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "hex.builtin.nodes.bitwise.xor.output"_lang) }) {} void process() override { auto inputA = this->getBufferOnInput(0); @@ -269,9 +295,10 @@ namespace hex::plugin::builtin { class NodeReadData : public dp::Node { public: - NodeReadData() : Node("Read Data", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Address"), - dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Size"), - dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "Data") + NodeReadData() : Node("hex.builtin.nodes.data_access.read.header"_lang, { + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.data_access.read.address"_lang), + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.data_access.read.size"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "hex.builtin.nodes.data_access.read.data"_lang) }) { } void process() override { @@ -289,7 +316,9 @@ namespace hex::plugin::builtin { class NodeWriteData : public dp::Node { public: - NodeWriteData() : Node("Write Data", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Address"), dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "Data") }) {} + NodeWriteData() : Node("hex.builtin.nodes.data_access.write.header"_lang, { + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.data_access.write.address"_lang), + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.data_access.write.data"_lang) }) {} void process() override { auto address = this->getIntegerOnInput(0); @@ -301,7 +330,9 @@ namespace hex::plugin::builtin { class NodeCastIntegerToBuffer : public dp::Node { public: - NodeCastIntegerToBuffer() : Node("Integer to Buffer", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "In"), dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "Out") }) {} + NodeCastIntegerToBuffer() : Node("hex.builtin.nodes.casting.int_to_buffer.header"_lang, { + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.casting.int_to_buffer.input"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "hex.builtin.nodes.casting.int_to_buffer.output"_lang) }) {} void process() override { auto input = this->getIntegerOnInput(0); @@ -315,7 +346,9 @@ namespace hex::plugin::builtin { class NodeCastBufferToInteger : public dp::Node { public: - NodeCastBufferToInteger() : Node("Buffer to Integer", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "In"), dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "Out") }) {} + NodeCastBufferToInteger() : Node("hex.builtin.nodes.casting.buffer_to_int.header"_lang, { + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.casting.buffer_to_int.input"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.casting.buffer_to_int.output"_lang) }) {} void process() override { auto input = this->getBufferOnInput(0); @@ -329,10 +362,11 @@ namespace hex::plugin::builtin { class NodeIf : public dp::Node { public: - NodeIf() : Node("If", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Condition"), - dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "True"), - dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "False"), - dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "Output") }) {} + NodeIf() : Node("ex.builtin.nodes.control_flow.if.header"_lang, + { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.if.condition"_lang), + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.control_flow.if.true"_lang), + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.control_flow.if.false"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "hex.builtin.nodes.control_flow.if.output"_lang) }) {} void process() override { auto cond = this->getIntegerOnInput(0); @@ -349,9 +383,10 @@ namespace hex::plugin::builtin { class NodeEquals : public dp::Node { public: - NodeEquals() : Node("Equals", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Input A"), - dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Input B"), - dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "Output") }) {} + NodeEquals() : Node("hex.builtin.nodes.control_flow.equals.header"_lang, + { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.equals.input.a"_lang), + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.equals.input.b"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.equals.output"_lang) }) {} void process() override { auto inputA = this->getIntegerOnInput(0); @@ -363,8 +398,9 @@ namespace hex::plugin::builtin { class NodeNot : public dp::Node { public: - NodeNot() : Node("Not", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Input"), - dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "Output") }) {} + NodeNot() : Node("hex.builtin.nodes.control_flow.not.header"_lang, + { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.not.input"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.not.output"_lang) }) {} void process() override { auto input = this->getIntegerOnInput(0); @@ -375,9 +411,10 @@ namespace hex::plugin::builtin { class NodeGreaterThan : public dp::Node { public: - NodeGreaterThan() : Node("Greater Than", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Input A"), - dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Input B"), - dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "Output") }) {} + NodeGreaterThan() : Node("hex.builtin.nodes.control_flow.gt.header"_lang, + { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.gt.input.a"_lang), + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.gt.input.b"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.gt.output"_lang) }) {} void process() override { auto inputA = this->getIntegerOnInput(0); @@ -389,9 +426,10 @@ namespace hex::plugin::builtin { class NodeLessThan : public dp::Node { public: - NodeLessThan() : Node("Less Than", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Input A"), - dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Input B"), - dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "Output") }) {} + NodeLessThan() : Node("hex.builtin.nodes.control_flow.lt.header"_lang, + { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.lt.input.a"_lang), + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.lt.input.b"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.lt.output"_lang) }) {} void process() override { auto inputA = this->getIntegerOnInput(0); @@ -403,9 +441,10 @@ namespace hex::plugin::builtin { class NodeBoolAND : public dp::Node { public: - NodeBoolAND() : Node("Boolean AND", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Input A"), - dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Input B"), - dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "Output") }) {} + NodeBoolAND() : Node("hex.builtin.nodes.control_flow.and.header"_lang, + { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.and.input.a"_lang), + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.and.input.b"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.and.output"_lang) }) {} void process() override { auto inputA = this->getIntegerOnInput(0); @@ -417,9 +456,10 @@ namespace hex::plugin::builtin { class NodeBoolOR : public dp::Node { public: - NodeBoolOR() : Node("Boolean OR", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Input A"), - dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "Input B"), - dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "Output") }) {} + NodeBoolOR() : Node("hex.builtin.nodes.control_flow.or.header"_lang, + { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.or.input.a"_lang), + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.or.input.b"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.control_flow.or.output"_lang) }) {} void process() override { auto inputA = this->getIntegerOnInput(0); @@ -431,16 +471,17 @@ namespace hex::plugin::builtin { class NodeCryptoAESDecrypt : public dp::Node { public: - NodeCryptoAESDecrypt() : Node("Decrypt AES", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "Key"), - dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "IV"), - dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "Nonce"), - dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "Input"), - dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "Output") }) {} + NodeCryptoAESDecrypt() : Node("hex.builtin.nodes.crypto.aes.header"_lang, + { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.crypto.aes.key"_lang), + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.crypto.aes.iv"_lang), + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.crypto.aes.nonce"_lang), + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.crypto.aes.input"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "hex.builtin.nodes.crypto.aes.output"_lang) }) {} void drawNode() override { ImGui::PushItemWidth(100); - ImGui::Combo("Mode", &this->m_mode, "ECB\0CBC\0CFB128\0CTR\0GCM\0CCM\0OFB\0"); - ImGui::Combo("Key Length", &this->m_keyLength, "128 Bits\000192 Bits\000256 Bits\000"); + ImGui::Combo("hex.builtin.nodes.crypto.aes.mode"_lang, &this->m_mode, "ECB\0CBC\0CFB128\0CTR\0GCM\0CCM\0OFB\0"); + ImGui::Combo("hex.builtin.nodes.crypto.aes.key_length"_lang, &this->m_keyLength, "128 Bits\000192 Bits\000256 Bits\000"); ImGui::PopItemWidth(); } @@ -473,9 +514,9 @@ namespace hex::plugin::builtin { class NodeDecodingBase64 : public dp::Node { public: - NodeDecodingBase64() : Node("Base64 Decoder", { - dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "In"), - dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "Out") }) {} + NodeDecodingBase64() : Node("hex.builtin.nodes.decoding.base64.header"_lang, { + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.decoding.base64.input"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "hex.builtin.nodes.decoding.base64.output"_lang) }) {} void process() override { auto input = this->getBufferOnInput(0); @@ -488,9 +529,9 @@ namespace hex::plugin::builtin { class NodeDecodingHex : public dp::Node { public: - NodeDecodingHex() : Node("Hexadecimal Decoder", { - dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "In"), - dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "Out") }) {} + NodeDecodingHex() : Node("hex.builtin.nodes.decoding.hex.header"_lang, { + dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.decoding.hex.input"_lang), + dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "hex.builtin.nodes.decoding.hex.output"_lang) }) {} void process() override { auto input = this->getBufferOnInput(0); @@ -525,40 +566,40 @@ namespace hex::plugin::builtin { }; void registerDataProcessorNodes() { - ContentRegistry::DataProcessorNode::add("Constants", "Integer"); - ContentRegistry::DataProcessorNode::add("Constants", "Float"); - ContentRegistry::DataProcessorNode::add("Constants", "Nullptr"); - ContentRegistry::DataProcessorNode::add("Constants", "Buffer"); - ContentRegistry::DataProcessorNode::add("Constants", "String"); - ContentRegistry::DataProcessorNode::add("Constants", "RGBA8 Color"); - ContentRegistry::DataProcessorNode::add("Constants", "Comment"); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.constants"_lang, "hex.builtin.nodes.constants.int"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.constants"_lang, "hex.builtin.nodes.constants.float"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.constants"_lang, "hex.builtin.nodes.constants.nullptr"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.constants"_lang, "hex.builtin.nodes.constants.buffer"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.constants"_lang, "hex.builtin.nodes.constants.string"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.constants"_lang, "hex.builtin.nodes.constants.rgba8"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.constants"_lang, "hex.builtin.nodes.constants.comment"_lang); - ContentRegistry::DataProcessorNode::add("Display", "Integer"); - ContentRegistry::DataProcessorNode::add("Display", "Float"); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.display"_lang, "hex.builtin.nodes.display.int"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.display"_lang, "hex.builtin.nodes.display.float"_lang); - ContentRegistry::DataProcessorNode::add("Data Access", "Read"); - ContentRegistry::DataProcessorNode::add("Data Access", "Write"); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.data_access"_lang, "hex.builtin.nodes.data_access.read"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.data_access"_lang, "hex.builtin.nodes.data_access.write"_lang); - ContentRegistry::DataProcessorNode::add("Casting", "Integer to Buffer"); - ContentRegistry::DataProcessorNode::add("Casting", "Buffer to Integer"); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.casting"_lang, "hex.builtin.nodes.casting.int_to_buffer"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.casting"_lang, "hex.builtin.nodes.casting.buffer_to_int"_lang); - ContentRegistry::DataProcessorNode::add("Control Flow", "If"); - ContentRegistry::DataProcessorNode::add("Control Flow", "Equals"); - ContentRegistry::DataProcessorNode::add("Control Flow", "Not"); - ContentRegistry::DataProcessorNode::add("Control Flow", "Greater Than"); - ContentRegistry::DataProcessorNode::add("Control Flow", "Less Than"); - ContentRegistry::DataProcessorNode::add("Control Flow", "AND"); - ContentRegistry::DataProcessorNode::add("Control Flow", "OR"); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.control_flow"_lang, "hex.builtin.nodes.control_flow.if"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.control_flow"_lang, "hex.builtin.nodes.control_flow.equals"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.control_flow"_lang, "hex.builtin.nodes.control_flow.not"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.control_flow"_lang, "hex.builtin.nodes.control_flow.gt"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.control_flow"_lang, "hex.builtin.nodes.control_flow.lt"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.control_flow"_lang, "hex.builtin.nodes.control_flow.and"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.control_flow"_lang, "hex.builtin.nodes.control_flow.or"_lang); - ContentRegistry::DataProcessorNode::add("Bitwise Operations", "AND"); - ContentRegistry::DataProcessorNode::add("Bitwise Operations", "OR"); - ContentRegistry::DataProcessorNode::add("Bitwise Operations", "XOR"); - ContentRegistry::DataProcessorNode::add("Bitwise Operations", "NOT"); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.bitwise"_lang, "hex.builtin.nodes.bitwise.and"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.bitwise"_lang, "hex.builtin.nodes.bitwise.or"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.bitwise"_lang, "hex.builtin.nodes.bitwise.xor"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.bitwise"_lang, "hex.builtin.nodes.bitwise.not"_lang); - ContentRegistry::DataProcessorNode::add("Decoding", "Base64"); - ContentRegistry::DataProcessorNode::add("Decoding", "Hexadecimal"); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.decoding"_lang, "hex.builtin.nodes.decoding.base64"_lang); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.decoding"_lang, "hex.builtin.nodes.decoding.hex"_lang); - ContentRegistry::DataProcessorNode::add("Crypto", "AES"); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.crypto"_lang, "hex.builtin.nodes.crypto.aes"_lang); } } \ No newline at end of file diff --git a/plugins/builtin/source/content/settings_entries.cpp b/plugins/builtin/source/content/settings_entries.cpp index 4aa02caac..cd4c7dacb 100644 --- a/plugins/builtin/source/content/settings_entries.cpp +++ b/plugins/builtin/source/content/settings_entries.cpp @@ -6,7 +6,7 @@ namespace hex::plugin::builtin { ContentRegistry::Settings::add("Interface", "Color theme", 0, [](nlohmann::json &setting) { static int selection = setting; - if (ImGui::Combo("##color_theme", &selection, "Dark\0Light\0Classic\0")) { + if (ImGui::Combo("Color theme", &selection, "Dark\0Light\0Classic\0")) { setting = selection; return true; } @@ -37,7 +37,7 @@ namespace hex::plugin::builtin { }(); - if (ImGui::Combo("##language", &selection, languageNames.data(), languageNames.size())) { + if (ImGui::Combo("Language", &selection, languageNames.data(), languageNames.size())) { u16 index = 0; for (auto &[languageCode, languageName] : languages){ diff --git a/plugins/builtin/source/content/tools_entries.cpp b/plugins/builtin/source/content/tools_entries.cpp index 6982e9084..d481948a8 100644 --- a/plugins/builtin/source/content/tools_entries.cpp +++ b/plugins/builtin/source/content/tools_entries.cpp @@ -13,11 +13,11 @@ namespace hex::plugin::builtin { static std::vector mangledBuffer(0xF'FFFF, 0x00); static std::string demangledName; - if (ImGui::InputText("Mangled name", mangledBuffer.data(), 0xF'FFFF)) { + if (ImGui::InputText("hex.builtin.tools.demangler.mangled"_lang, mangledBuffer.data(), 0xF'FFFF)) { demangledName = llvm::demangle(mangledBuffer.data()); } - ImGui::InputText("Demangled name", demangledName.data(), demangledName.size(), ImGuiInputTextFlags_ReadOnly); + ImGui::InputText("hex.builtin.tools.demangler.demangled"_lang, demangledName.data(), demangledName.size(), ImGuiInputTextFlags_ReadOnly); ImGui::NewLine(); } @@ -70,7 +70,7 @@ namespace hex::plugin::builtin { } ImGui::EndTable(); - ImGui::Checkbox("Show octal", &asciiTableShowOctal); + ImGui::Checkbox("hex.builtin.tools.ascii_table.octal"_lang, &asciiTableShowOctal); ImGui::NewLine(); } @@ -82,9 +82,9 @@ namespace hex::plugin::builtin { bool shouldInvalidate; - shouldInvalidate = ImGui::InputText("Regex pattern", regexPattern.data(), regexPattern.size()); - shouldInvalidate = ImGui::InputText("Replace pattern", replacePattern.data(), replacePattern.size()) || shouldInvalidate; - shouldInvalidate = ImGui::InputTextMultiline("Input", regexInput.data(), regexInput.size()) || shouldInvalidate; + shouldInvalidate = ImGui::InputText("hex.builtin.tools.regex_replacer.pattern"_lang, regexPattern.data(), regexPattern.size()); + shouldInvalidate = ImGui::InputText("hex.builtin.tools.regex_replacer.replace"_lang, replacePattern.data(), replacePattern.size()) || shouldInvalidate; + shouldInvalidate = ImGui::InputTextMultiline("hex.builtin.tools.regex_replacer.input"_lang, regexInput.data(), regexInput.size()) || shouldInvalidate; if (shouldInvalidate) { try { @@ -92,7 +92,7 @@ namespace hex::plugin::builtin { } catch (std::regex_error&) {} } - ImGui::InputTextMultiline("Output", regexOutput.data(), regexOutput.size(), ImVec2(0, 0), ImGuiInputTextFlags_ReadOnly); + ImGui::InputTextMultiline("hex.builtin.tools.regex_replacer.input"_lang, regexOutput.data(), regexOutput.size(), ImVec2(0, 0), ImGuiInputTextFlags_ReadOnly); ImGui::NewLine(); } @@ -100,7 +100,7 @@ namespace hex::plugin::builtin { static std::array pickedColor = { 0 }; ImGui::SetNextItemWidth(300.0F); - ImGui::ColorPicker4("Color Picker", pickedColor.data(), + ImGui::ColorPicker4("hex.builtin.tools.color"_lang, pickedColor.data(), ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHex); ImGui::NewLine(); } @@ -155,7 +155,7 @@ namespace hex::plugin::builtin { return std::move(evaluator); }(); - if (ImGui::InputText("Input", mathInput.data(), mathInput.size(), ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) { + if (ImGui::InputText("hex.builtin.tools.input"_lang, mathInput.data(), mathInput.size(), ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) { ImGui::SetKeyboardFocusHere(); std::optional result; @@ -174,25 +174,25 @@ namespace hex::plugin::builtin { } if (!lastMathError.empty()) - ImGui::TextColored(ImColor(0xA00040FF), "Last Error: %s", lastMathError.c_str()); + ImGui::TextColored(ImColor(0xA00040FF), "hex.builtin.tools.error"_lang, lastMathError.c_str()); else ImGui::NewLine(); enum class MathDisplayType { Standard, Scientific, Engineering, Programmer } mathDisplayType; if (ImGui::BeginTabBar("##mathFormatTabBar")) { - if (ImGui::BeginTabItem("Standard")) { + if (ImGui::BeginTabItem("hex.builtin.tools.format.standard"_lang)) { mathDisplayType = MathDisplayType::Standard; ImGui::EndTabItem(); } - if (ImGui::BeginTabItem("Scientific")) { + if (ImGui::BeginTabItem("hex.builtin.tools.format.scientific"_lang)) { mathDisplayType = MathDisplayType::Scientific; ImGui::EndTabItem(); } - if (ImGui::BeginTabItem("Engineering")) { + if (ImGui::BeginTabItem("hex.builtin.tools.format.engineering"_lang)) { mathDisplayType = MathDisplayType::Engineering; ImGui::EndTabItem(); } - if (ImGui::BeginTabItem("Programmer")) { + if (ImGui::BeginTabItem("hex.builtin.tools.format.programmer"_lang)) { mathDisplayType = MathDisplayType::Programmer; ImGui::EndTabItem(); } @@ -208,7 +208,7 @@ namespace hex::plugin::builtin { ImGui::TableNextColumn(); if (ImGui::BeginTable("##mathHistory", 1, ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(0, 400))) { ImGui::TableSetupScrollFreeze(0, 1); - ImGui::TableSetupColumn("History"); + ImGui::TableSetupColumn("hex.builtin.tools.history"_lang); ImGuiListClipper clipper; clipper.Begin(mathHistory.size()); @@ -252,8 +252,8 @@ namespace hex::plugin::builtin { ImGui::TableNextColumn(); if (ImGui::BeginTable("##mathVariables", 2, ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(0, 400))) { ImGui::TableSetupScrollFreeze(0, 1); - ImGui::TableSetupColumn("Name"); - ImGui::TableSetupColumn("Value"); + ImGui::TableSetupColumn("hex.builtin.tools.name"_lang); + ImGui::TableSetupColumn("hex.builtin.tools.value"_lang); ImGui::TableHeadersRow(); for (const auto &[name, value] : mathEvaluator.getVariables()) { @@ -322,31 +322,31 @@ namespace hex::plugin::builtin { }; u8 base = 10; - if (ImGui::InputText("DEC", buffer[0], 20 + 1, ImGuiInputTextFlags_CallbackCharFilter, CharFilter, &base)) + if (ImGui::InputText("hex.builtin.tools.base_converter.dec"_lang, buffer[0], 20 + 1, ImGuiInputTextFlags_CallbackCharFilter, CharFilter, &base)) ConvertBases(base); base = 16; - if (ImGui::InputText("HEX", buffer[1], 16 + 1, ImGuiInputTextFlags_CallbackCharFilter, CharFilter, &base)) + if (ImGui::InputText("hex.builtin.tools.base_converter.hex"_lang, buffer[1], 16 + 1, ImGuiInputTextFlags_CallbackCharFilter, CharFilter, &base)) ConvertBases(base); base = 8; - if (ImGui::InputText("OCT", buffer[2], 22 + 1, ImGuiInputTextFlags_CallbackCharFilter, CharFilter, &base)) + if (ImGui::InputText("hex.builtin.tools.base_converter.oct"_lang, buffer[2], 22 + 1, ImGuiInputTextFlags_CallbackCharFilter, CharFilter, &base)) ConvertBases(base); base = 2; - if (ImGui::InputText("BIN", buffer[3], 64 + 1, ImGuiInputTextFlags_CallbackCharFilter, CharFilter, &base)) + if (ImGui::InputText("hex.builtin.tools.base_converter.bin"_lang, buffer[3], 64 + 1, ImGuiInputTextFlags_CallbackCharFilter, CharFilter, &base)) ConvertBases(base); } } void registerToolEntries() { - ContentRegistry::Tools::add("Itanium/MSVC demangler", drawDemangler); - ContentRegistry::Tools::add("ASCII table", drawASCIITable); - ContentRegistry::Tools::add("Regex replacer", drawRegexReplacer); - ContentRegistry::Tools::add("Color picker", drawColorPicker); - ContentRegistry::Tools::add("Calculator", drawMathEvaluator); - ContentRegistry::Tools::add("Base Converter", drawBaseConverter); + ContentRegistry::Tools::add("hex.builtin.tools.demangler"_lang, drawDemangler); + ContentRegistry::Tools::add("hex.builtin.tools.ascii_table"_lang, drawASCIITable); + ContentRegistry::Tools::add("hex.builtin.tools.regex_replacer"_lang, drawRegexReplacer); + ContentRegistry::Tools::add("hex.builtin.tools.color"_lang, drawColorPicker); + ContentRegistry::Tools::add("hex.builtin.tools.calc"_lang, drawMathEvaluator); + ContentRegistry::Tools::add("hex.builtin.tools.base_converter"_lang, drawBaseConverter); } } \ No newline at end of file diff --git a/plugins/builtin/source/lang/en_US.cpp b/plugins/builtin/source/lang/en_US.cpp index 5917203ca..a52511da9 100644 --- a/plugins/builtin/source/lang/en_US.cpp +++ b/plugins/builtin/source/lang/en_US.cpp @@ -6,6 +6,424 @@ namespace hex::plugin::builtin { ContentRegistry::Language::registerLanguage("English (US)", "en-US"); ContentRegistry::Language::addLocalizations("en-US", { + /* ImHex default functionality */ + { "hex.menu.file", "File" }, + { "hex.menu.edit", "Edit" }, + { "hex.menu.view", "View" }, + { "hex.menu.view.fps", "Display FPS" }, + { "hex.menu.view.demo", "Show ImGui Demo" }, + { "hex.menu.help", "Help" }, + + { "hex.welcome.header.main", "Welcome to ImHex" }, + { "hex.welcome.header.start", "Start" }, + { "hex.welcome.start.open_file", "Open File" }, + { "hex.welcome.start.open_project", "Open Project" }, + { "hex.welcome.start.recent", "Recent Files" }, + { "hex.welcome.header.help", "Help" }, + { "hex.welcome.help.repo", "GitHub Repository" }, + { "hex.welcome.help.repo.link", "https://github.com/WerWolv/ImHex" }, + { "hex.welcome.help.gethelp", "Get Help" }, + { "hex.welcome.help.gethelp.link", "https://github.com/WerWolv/ImHex/discussions/categories/get-help" }, + { "hex.welcome.header.customize", "Customize" }, + { "hex.welcome.customize.settings.title", "Settings" }, + { "hex.welcome.customize.settings.desc", "Change preferences of ImHex" }, + { "hex.welcome.header.learn", "Learn" }, + { "hex.welcome.learn.latest.title", "Latest Release" }, + { "hex.welcome.learn.latest.desc", "Get the latest version of ImHex or read the current changelog" }, + { "hex.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" }, + { "hex.welcome.learn.pattern.title", "Pattern Language Documentation" }, + { "hex.welcome.learn.pattern.desc", "Learn how to write ImHex patterns with our extensive documentation" }, + { "hex.welcome.learn.pattern.link", "https://github.com/WerWolv/ImHex/wiki/Pattern-Language-Guide" }, + { "hex.welcome.learn.plugins.title", "Plugins API\"" }, + { "hex.welcome.learn.plugins.desc", "Extend ImHex with additional features using plugins" }, + { "hex.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" }, + + { "hex.common.little_endian", "Little Endian" }, + { "hex.common.big_endian", "Big Endian" }, + { "hex.common.decimal", "Decimal" }, + { "hex.common.hexadecimal", "Hexadecimal" }, + { "hex.common.octal", "Octal" }, + { "hex.common.error", "Error" }, + { "hex.common.address", "Address" }, + { "hex.common.size", "Size" }, + { "hex.common.region", "Region" }, + { "hex.common.match_selection", "Match Selection" }, + { "hex.common.yes", "Yes" }, + { "hex.common.no", "No" }, + { "hex.common.load", "Load" }, + { "hex.common.cancel", "Cancel" }, + { "hex.common.set", "Set" }, + + { "hex.view.bookmarks.name", "Bookmarks" }, + { "hex.view.bookmarks.default_title", "Bookmark [0x%lX - 0x%lX]" }, + { "hex.view.bookmarks.no_bookmarks", "No bookmarks created yet. Add one with Edit -> Add Bookmark" }, + { "hex.view.bookmarks.title.info", "Information" }, + { "hex.view.bookmarks.address", "0x%08lx : 0x%08lx (%lu bytes)" }, + { "hex.view.bookmarks.button.jump", "Jump to" }, + { "hex.view.bookmarks.button.remove", "Remove" }, + { "hex.view.bookmarks.header.name", "Name" }, + { "hex.view.bookmarks.header.color", "Color" }, + { "hex.view.bookmarks.header.comment", "Comment" }, + + { "hex.view.command_palette.name", "Command Palette" }, + + { "hex.view.data_inspector.name", "Data Inspector" }, + { "hex.view.data_inspector.table.name", "Name" }, + { "hex.view.data_inspector.table.value", "Value" }, + + { "hex.view.data_processor.name", "Data Processor" }, + { "hex.view.data_processor.menu.remove_selection", "Remove Selected" }, + { "hex.view.data_processor.menu.remove_node", "Remove Node" }, + { "hex.view.data_processor.menu.remove_link", "Remove Link" }, + + { "hex.view.disassembler.name", "Disassembler" }, + { "hex.view.disassembler.position", "Position" }, + { "hex.view.disassembler.base", "Base address" }, + { "hex.view.disassembler.region", "Code region" }, + { "hex.view.disassembler.settings.header", "Settings" }, + { "hex.view.disassembler.arch", "Architecture" }, + { "hex.view.disassembler.arm.arm", "ARM mode" }, + { "hex.view.disassembler.arm.thumb", "Thumb mode" }, + { "hex.view.disassembler.arm.default", "Default mode" }, + { "hex.view.disassembler.arm.cortex_m", "Cortex-M mode" }, + { "hex.view.disassembler.arm.armv8", "ARMv8 mode" }, + + { "hex.view.disassembler.mips.mips32", "MIPS32 mode" }, + { "hex.view.disassembler.mips.mips64", "MIPS64 mode" }, + { "hex.view.disassembler.mips.mips32R6", "MIPS32R6 mode" }, + { "hex.view.disassembler.mips.micro", "Micro mode" }, + + { "hex.view.disassembler.x86.16bit", "16-bit mode" }, + { "hex.view.disassembler.x86.32bit", "32-bit mode" }, + { "hex.view.disassembler.x86.64bit", "64-bit mode" }, + + { "hex.view.disassembler.ppc.32bit", "32-bit mode" }, + { "hex.view.disassembler.ppc.64bit", "64-bit mode" }, + + { "hex.view.disassembler.sparc.v9", "Sparc V9 mode" }, + + { "hex.view.disassembler.disassemble", "Disassemble" }, + { "hex.view.disassembler.disassembly.title", "Disassembly" }, + { "hex.view.disassembler.disassembly.address", "Address" }, + { "hex.view.disassembler.disassembly.offset", "Offset" }, + { "hex.view.disassembler.disassembly.bytes", "Byte" }, + + { "hex.view.hashes.name", "Hashes" }, + { "hex.view.hashes.settings", "Settings" }, + { "hex.view.hashes.function", "Hash function" }, + { "hex.view.hashes.iv", "Initial value" }, + { "hex.view.hashes.poly", "Polynomial" }, + { "hex.view.hashes.result", "Result" }, + + { "hex.view.help.title", "Help" }, + { "hex.view.help.about.title", "About" }, + { "hex.view.help.about.translator", "Translated by WerWolv" }, + { "hex.view.help.about.source", "Source code available on GitHub:" }, + { "hex.view.help.about.donations", "Donations" }, + { "hex.view.help.about.thanks", "If you like my work, please consider donating to keep the project going. Thanks a lot <3" }, + { "hex.view.help.about.libs", "Libraries used" }, + + { "hex.view.hexeditor.title", "Hex editor" }, + { "hex.view.hexeditor.save_changes", "Save Changes" }, + { "hex.view.hexeditor.open_file", "Open File" }, + { "hex.view.hexeditor.open_project", "Open Project" }, + { "hex.view.hexeditor.save_project", "Save Project" }, + { "hex.view.hexeditor.save_data", "Save Data" }, + { "hex.view.hexeditor.open_base64", "Open Base64 File" }, + { "hex.view.hexeditor.page", "Page %d / %d" }, + { "hex.view.hexeditor.save_as", "Save As" }, + { "hex.view.hexeditor.save_changes.title", "Save Changes" }, + { "hex.view.hexeditor.save_changes.desc", "You have unsaved changes made to your Project.\nAre you sure you want to exit?" }, + { "hex.view.hexeditor.script.title", "Load File with Loader Script" }, + { "hex.view.hexeditor.script.desc", "Load a file using a Python loader script." }, + { "hex.view.hexeditor.script.script", "Script" }, + { "hex.view.hexeditor.script.script.title", "Loader Script: Open Script" }, + { "hex.view.hexeditor.script.file", "File" }, + { "hex.view.hexeditor.script.file.title", "Loader Script: Open File" }, + + { "hex.view.hexeditor.menu.file.open_file", "Open File..." }, + { "hex.view.hexeditor.menu.file.save", "Save" }, + { "hex.view.hexeditor.menu.file.save_as", "Save As..." }, + { "hex.view.hexeditor.menu.file.open_project", "Open Project..." }, + { "hex.view.hexeditor.menu.file.save_project", "Save Project..." }, + { "hex.view.hexeditor.menu.file.import", "Import..." }, + { "hex.view.hexeditor.menu.file.import.base64", "Base64 File" }, + { "hex.view.hexeditor.base64.import_error", "File is not in a valid Base64 format!" }, + { "hex.view.hexeditor.file_open_error", "Failed to open file!" }, + { "hex.view.hexeditor.menu.file.import.ips", "IPS Patch" }, + { "hex.view.hexeditor.menu.file.import.ips32", "IPS32 Patch" }, + { "hex.view.hexeditor.menu.file.import.script", "File with Loader Script" }, + + { "hex.view.hexeditor.menu.file.export", "Export..." }, + { "hex.view.hexeditor.menu.file.export.title", "Export File" }, + { "hex.view.hexeditor.menu.file.export.ips", "IPS Patch" }, + { "hex.view.hexeditor.menu.file.export.ips32", "IPS32 Patch" }, + { "hex.view.hexeditor.menu.file.search", "Search" }, + { "hex.view.hexeditor.search.string", "String" }, + { "hex.view.hexeditor.search.hex", "Hex" }, + { "hex.view.hexeditor.search.find", "Find" }, + { "hex.view.hexeditor.search.find_next", "Find next" }, + { "hex.view.hexeditor.search.find_prev", "Find previous" }, + { "hex.view.hexeditor.menu.file.goto", "Goto" }, + { "hex.view.hexeditor.goto.offset.current", "Current" }, + { "hex.view.hexeditor.goto.offset.begin", "Begin" }, + { "hex.view.hexeditor.goto.offset.end", "End" }, + { "hex.view.hexeditor.error.read_only", "Couldn't get write access. File opened in read-only mode." }, + { "hex.view.hexeditor.error.open", "Filed to open file!" }, + { "hex.view.hexeditor.menu.edit.copy", "Copy as..." }, + { "hex.view.hexeditor.copy.bytes", "Bytes" }, + { "hex.view.hexeditor.copy.hex", "Hex String" }, + { "hex.view.hexeditor.copy.c", "C Array" }, + { "hex.view.hexeditor.copy.cpp", "C++ Array" }, + { "hex.view.hexeditor.copy.csharp", "C# Array" }, + { "hex.view.hexeditor.copy.rust", "Rust Array" }, + { "hex.view.hexeditor.copy.python", "Python Array" }, + { "hex.view.hexeditor.copy.java", "Java Array" }, + { "hex.view.hexeditor.copy.js", "JavaScript Array" }, + { "hex.view.hexeditor.copy.ascii", "ASCII Art" }, + { "hex.view.hexeditor.copy.html", "HTML" }, + { "hex.view.hexeditor.menu.edit.bookmark", "Create bookmark" }, + { "hex.view.hexeditor.menu.edit.set_base", "Set base address" }, + + { "hex.view.information.title", "Data Information" }, + { "hex.view.information.analyze", "Analyze current page" }, + { "hex.view.information.region", "analyzed region" }, + { "hex.view.information.description", "Description:" }, + { "hex.view.information.mime", "MIME Type:" }, + { "hex.view.information.distribution", "Byte distribution" }, + { "hex.view.information.entropy", "Entropy" }, + { "hex.view.information.block_size", "Block size" }, + { "hex.view.information.block_size.desc", "2046 blocks of %lu bytes" }, + { "hex.view.information.file_entropy", "File entropy" }, + { "hex.view.information.highest_entropy", "Highest entropy block" }, + { "hex.view.information.encrypted", "This data is most likely encrypted or compressed!" }, + + { "hex.view.patches.title", "Patches" }, + { "hex.view.patches.offset", "Offset" }, + { "hex.view.patches.orig", "Original value" }, + { "hex.view.patches.patch", "Patched value"}, + { "hex.view.patches.remove", "Remove patch" }, + + { "hex.view.pattern.title", "Pattern editor" }, + { "hex.view.pattern.accept_pattern", "Accept pattern" }, + { "hex.view.pattern.accept_pattern.desc", "One or more patterns compatible with this data type has been found" }, + { "hex.view.pattern.accept_pattern.patterns", "Patterns" }, + { "hex.view.pattern.accept_pattern.question", "Do you want to apply the selected pattern?" }, + { "hex.view.pattern.menu.file.load_pattern", "Load pattern..." }, + { "hex.view.pattern.open_pattern", "Open pattern" }, + + { "hex.view.pattern_data.title", "Pattern Data" }, + { "hex.view.pattern_data.name", "Name" }, + { "hex.view.pattern_data.color", "Color" }, + { "hex.view.pattern_data.offset", "Offset" }, + { "hex.view.pattern_data.size", "Size" }, + { "hex.view.pattern_data.type", "Type" }, + { "hex.view.pattern_data.value", "Value" }, + + { "hex.view.settings.title", "Settings" }, + + { "hex.view.strings.title", "Strings" }, + { "hex.view.strings.copy", "Copy string" }, + { "hex.view.strings.demangle", "Demangle" }, + { "hex.view.strings.min_length", "Minimum length" }, + { "hex.view.strings.filter", "Filter" }, + { "hex.view.strings.extract", "Extract" }, + { "hex.view.strings.offset", "Offset" }, + { "hex.view.strings.size", "Size" }, + { "hex.view.strings.string", "String" }, + { "hex.view.strings.demangle.title", "Demangled name" }, + { "hex.view.strings.demangle.copy", "Copy" }, + + { "hex.view.tools.title", "Tools" }, + + /* Builtin plugin features */ + + { "hex.builtin.command.calc.desc", "Calculator" }, + { "hex.builtin.command.web.desc", "Website lookup" }, + { "hex.builtin.command.web.result", "Navigate to '%s'"}, + + { "hex.builtin.inspector.binary", "Binary (8 bit)" }, + { "hex.builtin.inspector.u8", "uint8_t" }, + { "hex.builtin.inspector.s8", "int8_t" }, + { "hex.builtin.inspector.u16", "uint16_t" }, + { "hex.builtin.inspector.s16", "int16_t" }, + { "hex.builtin.inspector.u32", "uint32_t" }, + { "hex.builtin.inspector.s32", "int32_t" }, + { "hex.builtin.inspector.u64", "uint64_t" }, + { "hex.builtin.inspector.s64", "int64_t" }, + { "hex.builtin.inspector.float", "float (32 bit)" }, + { "hex.builtin.inspector.double", "double (64 bit)" }, + { "hex.builtin.inspector.ascii", "ASCII Character" }, + { "hex.builtin.inspector.wide", "Wide Character" }, + { "hex.builtin.inspector.utf8", "UTF-8 code point" }, + { "hex.builtin.inspector.time32", "__time32_t" }, + { "hex.builtin.inspector.time64", "__time64_t" }, + { "hex.builtin.inspector.time", "time_t" }, + { "hex.builtin.inspector.guid", "GUID" }, + { "hex.builtin.inspector.rgba8", "RGBA8 color" }, + + { "hex.builtin.nodes.constants", "Constants" }, + { "hex.builtin.nodes.constants.int", "Integer" }, + { "hex.builtin.nodes.constants.int.header", "Integer" }, + { "hex.builtin.nodes.constants.int.output", "" }, + { "hex.builtin.nodes.constants.float", "Float" }, + { "hex.builtin.nodes.constants.float.header", "Float" }, + { "hex.builtin.nodes.constants.float.output", "" }, + { "hex.builtin.nodes.constants.nullptr", "Nullptr" }, + { "hex.builtin.nodes.constants.nullptr.header", "Nullptr" }, + { "hex.builtin.nodes.constants.nullptr.output", "" }, + { "hex.builtin.nodes.constants.buffer", "Buffer" }, + { "hex.builtin.nodes.constants.buffer.header", "Buffer" }, + { "hex.builtin.nodes.constants.buffer.size", "Size" }, + { "hex.builtin.nodes.constants.buffer.output", "" }, + { "hex.builtin.nodes.constants.string", "String" }, + { "hex.builtin.nodes.constants.string.header", "String" }, + { "hex.builtin.nodes.constants.string.output", "" }, + { "hex.builtin.nodes.constants.rgba8", "RGBA8 color" }, + { "hex.builtin.nodes.constants.rgba8.header", "RGBA8 color" }, + { "hex.builtin.nodes.constants.rgba8.output.r", "Red" }, + { "hex.builtin.nodes.constants.rgba8.output.g", "Green" }, + { "hex.builtin.nodes.constants.rgba8.output.b", "Blue" }, + { "hex.builtin.nodes.constants.rgba8.output.a", "Alpha" }, + { "hex.builtin.nodes.constants.comment", "Comment" }, + { "hex.builtin.nodes.constants.comment.header", "Comment" }, + + { "hex.builtin.nodes.display", "Display" }, + { "hex.builtin.nodes.display.int", "Integer" }, + { "hex.builtin.nodes.display.int.header", "Integer display" }, + { "hex.builtin.nodes.display.int.input", "Value" }, + { "hex.builtin.nodes.display.float", "Float" }, + { "hex.builtin.nodes.display.float.header", "Float display" }, + { "hex.builtin.nodes.display.float.input", "Value" }, + + { "hex.builtin.nodes.data_access", "Data access" }, + { "hex.builtin.nodes.data_access.read", "Read" }, + { "hex.builtin.nodes.data_access.read.header", "Read" }, + { "hex.builtin.nodes.data_access.read.address", "Address" }, + { "hex.builtin.nodes.data_access.read.size", "Size" }, + { "hex.builtin.nodes.data_access.read.data", "Data" }, + { "hex.builtin.nodes.data_access.write", "Write" }, + { "hex.builtin.nodes.data_access.write.header", "Write" }, + { "hex.builtin.nodes.data_access.write.address", "Address" }, + { "hex.builtin.nodes.data_access.write.data", "Data" }, + + { "hex.builtin.nodes.casting", "Data conversion" }, + { "hex.builtin.nodes.casting.int_to_buffer", "Integer to Buffer" }, + { "hex.builtin.nodes.casting.int_to_buffer.header", "Integer to Buffer" }, + { "hex.builtin.nodes.casting.int_to_buffer.input", "In" }, + { "hex.builtin.nodes.casting.int_to_buffer.output", "Out" }, + { "hex.builtin.nodes.casting.buffer_to_int", "Buffer to Integer" }, + { "hex.builtin.nodes.casting.buffer_to_int.header", "Buffer to Integer" }, + { "hex.builtin.nodes.casting.buffer_to_int.input", "In" }, + { "hex.builtin.nodes.casting.buffer_to_int.output", "Out" }, + + { "hex.builtin.nodes.control_flow", "Control flow" }, + { "hex.builtin.nodes.control_flow.if", "If" }, + { "hex.builtin.nodes.control_flow.if.header", "If" }, + { "hex.builtin.nodes.control_flow.if.condition", "Condition" }, + { "hex.builtin.nodes.control_flow.if.true", "True" }, + { "hex.builtin.nodes.control_flow.if.false", "False" }, + { "hex.builtin.nodes.control_flow.if.output", "Output" }, + { "hex.builtin.nodes.control_flow.equals", "Equals" }, + { "hex.builtin.nodes.control_flow.equals.header", "Equals" }, + { "hex.builtin.nodes.control_flow.equals.input.a", "Input A" }, + { "hex.builtin.nodes.control_flow.equals.input.b", "Input B" }, + { "hex.builtin.nodes.control_flow.equals.output", "Output" }, + { "hex.builtin.nodes.control_flow.not", "Not" }, + { "hex.builtin.nodes.control_flow.not.header", "Not" }, + { "hex.builtin.nodes.control_flow.not.input", "Input" }, + { "hex.builtin.nodes.control_flow.not.output", "Output" }, + { "hex.builtin.nodes.control_flow.gt", "Greater than" }, + { "hex.builtin.nodes.control_flow.gt.header", "Greater than" }, + { "hex.builtin.nodes.control_flow.gt.input.a", "Input A" }, + { "hex.builtin.nodes.control_flow.gt.input.b", "Input B" }, + { "hex.builtin.nodes.control_flow.gt.output", "Output" }, + { "hex.builtin.nodes.control_flow.lt", "Less than" }, + { "hex.builtin.nodes.control_flow.lt.header", "Less than" }, + { "hex.builtin.nodes.control_flow.lt.input.a", "Input A" }, + { "hex.builtin.nodes.control_flow.lt.input.b", "Input B" }, + { "hex.builtin.nodes.control_flow.lt.output", "Output" }, + { "hex.builtin.nodes.control_flow.and", "AND" }, + { "hex.builtin.nodes.control_flow.and.header", "Boolean AND" }, + { "hex.builtin.nodes.control_flow.and.input.a", "Input A" }, + { "hex.builtin.nodes.control_flow.and.input.b", "Input B" }, + { "hex.builtin.nodes.control_flow.and.output", "Output" }, + { "hex.builtin.nodes.control_flow.or", "OR" }, + { "hex.builtin.nodes.control_flow.or.header", "Boolean OR" }, + { "hex.builtin.nodes.control_flow.or.input.a", "Input A" }, + { "hex.builtin.nodes.control_flow.or.input.b", "Input B" }, + { "hex.builtin.nodes.control_flow.or.output", "Output" }, + + { "hex.builtin.nodes.bitwise", "Bitwise operations" }, + { "hex.builtin.nodes.bitwise.and", "AND" }, + { "hex.builtin.nodes.bitwise.and.header", "Bitwise AND" }, + { "hex.builtin.nodes.bitwise.and.input.a", "Input A" }, + { "hex.builtin.nodes.bitwise.and.input.b", "Input B" }, + { "hex.builtin.nodes.bitwise.and.output", "Output" }, + { "hex.builtin.nodes.bitwise.or", "OR" }, + { "hex.builtin.nodes.bitwise.or.header", "Bitwise OR" }, + { "hex.builtin.nodes.bitwise.or.input.a", "Input A" }, + { "hex.builtin.nodes.bitwise.or.input.b", "Input B" }, + { "hex.builtin.nodes.bitwise.or.output", "Output" }, + { "hex.builtin.nodes.bitwise.xor", "XOR" }, + { "hex.builtin.nodes.bitwise.xor.header", "Bitwise XOR" }, + { "hex.builtin.nodes.bitwise.xor.input.a", "Input A" }, + { "hex.builtin.nodes.bitwise.xor.input.b", "Input B" }, + { "hex.builtin.nodes.bitwise.xor.output", "Output" }, + { "hex.builtin.nodes.bitwise.not", "NOT" }, + { "hex.builtin.nodes.bitwise.not.header", "Bitwise NOT" }, + { "hex.builtin.nodes.bitwise.not.input", "Input" }, + { "hex.builtin.nodes.bitwise.not.output", "Output" }, + + { "hex.builtin.nodes.decoding", "Decoding" }, + { "hex.builtin.nodes.decoding.base64", "Base64" }, + { "hex.builtin.nodes.decoding.base64.header", "Base64 decoder" }, + { "hex.builtin.nodes.decoding.base64.input", "In" }, + { "hex.builtin.nodes.decoding.base64.output", "Out" }, + { "hex.builtin.nodes.decoding.hex", "Hexadecimal" }, + { "hex.builtin.nodes.decoding.hex.header", "Hexadecimal decoder" }, + { "hex.builtin.nodes.decoding.hex.input", "In" }, + { "hex.builtin.nodes.decoding.hex.output", "Out" }, + + { "hex.builtin.nodes.crypto", "Cryptography" }, + { "hex.builtin.nodes.crypto.aes", "AES Decryptor" }, + { "hex.builtin.nodes.crypto.aes.header", "AES Decryptor" }, + { "hex.builtin.nodes.crypto.aes.key", "Key" }, + { "hex.builtin.nodes.crypto.aes.iv", "IV" }, + { "hex.builtin.nodes.crypto.aes.nonce", "Nonce" }, + { "hex.builtin.nodes.crypto.aes.input", "Input" }, + { "hex.builtin.nodes.crypto.aes.output", "Output" }, + { "hex.builtin.nodes.crypto.aes.mode", "Mode" }, + { "hex.builtin.nodes.crypto.aes.key_length", "Key length" }, + + + + { "hex.builtin.tools.demangler", "Itanium/MSVC demangler" }, + { "hex.builtin.tools.demangler.mangled", "Mangled name" }, + { "hex.builtin.tools.demangler.demangled", "Demangled name" }, + { "hex.builtin.tools.ascii_table", "ASCII table" }, + { "hex.builtin.tools.ascii_table.octal", "Show octal" }, + { "hex.builtin.tools.regex_replacer", "Regex replacer" }, + { "hex.builtin.tools.regex_replacer.pattern", "Regex pattern" }, + { "hex.builtin.tools.regex_replacer.replace", "Replace pattern" }, + { "hex.builtin.tools.regex_replacer.input", "Input" }, + { "hex.builtin.tools.regex_replacer.output", "Output" }, + { "hex.builtin.tools.color", "Color picker" }, + { "hex.builtin.tools.calc", "Calculator" }, + { "hex.builtin.tools.input", "Input" }, + { "hex.builtin.tools.format.standard", "Standard" }, + { "hex.builtin.tools.format.scientific", "Scientific" }, + { "hex.builtin.tools.format.engineering", "Engineering" }, + { "hex.builtin.tools.format.programmer", "Programmer" }, + { "hex.builtin.tools.error", "Last error: '%s'" }, + { "hex.builtin.tools.history", "History" }, + { "hex.builtin.tools.name", "Name" }, + { "hex.builtin.tools.value", "Value" }, + { "hex.builtin.tools.base_converter", "Base converter" }, + { "hex.builtin.tools.base_converter.dec", "DEC" }, + { "hex.builtin.tools.base_converter.hex", "HEX" }, + { "hex.builtin.tools.base_converter.oct", "OCT" }, + { "hex.builtin.tools.base_converter.bin", "BIN" }, }); } diff --git a/plugins/builtin/source/plugin_builtin.cpp b/plugins/builtin/source/plugin_builtin.cpp index eab411f4b..23deaeeb6 100644 --- a/plugins/builtin/source/plugin_builtin.cpp +++ b/plugins/builtin/source/plugin_builtin.cpp @@ -2,6 +2,8 @@ namespace hex::plugin::builtin { + void registerLanguageEnUS(); + void registerDataInspectorEntries(); void registerToolEntries(); void registerPatternLanguageFunctions(); @@ -9,22 +11,20 @@ namespace hex::plugin::builtin { void registerSettings(); void registerDataProcessorNodes(); - void registerLanguageEnUS(); - } IMHEX_PLUGIN_SETUP { using namespace hex::plugin::builtin; + registerLanguageEnUS(); + registerDataInspectorEntries(); registerToolEntries(); registerPatternLanguageFunctions(); registerCommandPaletteCommands(); registerSettings(); registerDataProcessorNodes(); - - registerLanguageEnUS(); } diff --git a/plugins/libimhex/include/hex/helpers/lang.hpp b/plugins/libimhex/include/hex/helpers/lang.hpp index 79fc0a879..36312acdb 100644 --- a/plugins/libimhex/include/hex/helpers/lang.hpp +++ b/plugins/libimhex/include/hex/helpers/lang.hpp @@ -34,6 +34,14 @@ namespace hex { std::string m_unlocalizedString; }; + std::string operator+(const std::string &&left, const LangEntry &&right); + std::string operator+(const LangEntry &&left, const std::string &&right); + std::string operator+(const std::string_view &&left, const LangEntry &&right); + std::string operator+(const LangEntry &&left, const std::string_view &&right); + std::string operator+(const char *left, const LangEntry &&right); + std::string operator+(const LangEntry &&left, const char *right); + std::string operator+(const LangEntry &&left, const LangEntry &&right); + namespace lang_literals { inline LangEntry operator""_lang(const char *string, size_t) { diff --git a/plugins/libimhex/source/api/content_registry.cpp b/plugins/libimhex/source/api/content_registry.cpp index 09d3d514f..cbb86186e 100644 --- a/plugins/libimhex/source/api/content_registry.cpp +++ b/plugins/libimhex/source/api/content_registry.cpp @@ -201,6 +201,8 @@ namespace hex { void ContentRegistry::Language::addLocalizations(std::string_view languageCode, const LanguageDefinition &definition) { getLanguageDefinitions()[languageCode.data()].push_back(definition); + + EventManager::post(hex::Events::SettingsChanged, {}); } std::map& ContentRegistry::Language::getLanguages() { diff --git a/plugins/libimhex/source/helpers/lang.cpp b/plugins/libimhex/source/helpers/lang.cpp index bac42d263..d0703cc12 100644 --- a/plugins/libimhex/source/helpers/lang.cpp +++ b/plugins/libimhex/source/helpers/lang.cpp @@ -27,6 +27,34 @@ namespace hex { return get().data(); } + std::string operator+(const std::string &&left, const LangEntry &&right) { + return left + static_cast(right); + } + + std::string operator+(const LangEntry &&left, const std::string &&right) { + return static_cast(left) + right; + } + + std::string operator+(const LangEntry &&left, const LangEntry &&right) { + return static_cast(left) + static_cast(right); + } + + std::string operator+(const std::string_view &&left, const LangEntry &&right) { + return std::string(left) + static_cast(right); + } + + std::string operator+(const LangEntry &&left, const std::string_view &&right) { + return static_cast(left) + std::string(right); + } + + std::string operator+(const char *left, const LangEntry &&right) { + return left + static_cast(right); + } + + std::string operator+(const LangEntry &&left, const char *right) { + return static_cast(left) + right; + } + std::string_view LangEntry::get() const { auto &lang = SharedData::loadedLanguageStrings; if (lang.find(this->m_unlocalizedString) != lang.end()) diff --git a/source/views/view_bookmarks.cpp b/source/views/view_bookmarks.cpp index 7be09d9a3..b1f3f7e42 100644 --- a/source/views/view_bookmarks.cpp +++ b/source/views/view_bookmarks.cpp @@ -7,7 +7,7 @@ namespace hex { - ViewBookmarks::ViewBookmarks() : View("Bookmarks") { + ViewBookmarks::ViewBookmarks() : View("hex.view.bookmarks.name"_lang) { View::subscribeEvent(Events::AddBookmark, [](auto userData) { auto bookmark = std::any_cast(userData); bookmark.comment.resize(0xF'FFFF); @@ -15,7 +15,7 @@ namespace hex { if (bookmark.name.empty()) { bookmark.name.resize(64); std::memset(bookmark.name.data(), 0x00, 64); - std::strcpy(bookmark.name.data(), hex::format("Bookmark [0x%lX - 0x%lX]", + std::strcpy(bookmark.name.data(), hex::format("hex.view.bookmarks.default_title"_lang, bookmark.region.address, bookmark.region.address + bookmark.region.size - 1).c_str()); } @@ -44,7 +44,7 @@ namespace hex { } void ViewBookmarks::drawContent() { - if (ImGui::Begin("Bookmarks", &this->getWindowOpenState())) { + if (ImGui::Begin("hex.view.bookmarks.name"_lang, &this->getWindowOpenState())) { if (ImGui::BeginChild("##scrolling")) { auto &bookmarks = ImHexApi::Bookmarks::getEntries(); @@ -52,7 +52,7 @@ namespace hex { if (bookmarks.empty()) { ImGui::NewLine(); ImGui::Indent(30); - ImGui::TextWrapped("No bookmarks created yet. Add one with Edit -> Add Bookmark"); + ImGui::TextWrapped("%s", static_cast("hex.view.bookmarks.no_bookmarks"_lang)); } u32 id = 1; @@ -69,9 +69,9 @@ namespace hex { ImGui::PushStyleColor(ImGuiCol_HeaderActive, color); ImGui::PushStyleColor(ImGuiCol_HeaderHovered, u32(hoverColor)); if (ImGui::CollapsingHeader((std::string(name.data()) + "###" + std::to_string((u64)comment.data())).c_str())) { - ImGui::TextUnformatted("Information"); + ImGui::TextUnformatted("hex.view.bookmarks.title.info"_lang); ImGui::Separator(); - ImGui::Text("0x%08lx : 0x%08lx (%lu bytes)", region.address, region.address + region.size - 1, region.size); + ImGui::Text("hex.view.bookmarks.address"_lang, region.address, region.address + region.size - 1, region.size); { u8 bytes[10] = { 0 }; @@ -89,22 +89,22 @@ namespace hex { ImGui::TextColored(ImColor(0xFF9BC64D), bytesString.c_str()); } - if (ImGui::Button("Jump to")) + if (ImGui::Button("hex.view.bookmarks.button.jump"_lang)) View::postEvent(Events::SelectionChangeRequest, region); ImGui::SameLine(0, 15); - if (ImGui::Button("Remove")) + if (ImGui::Button("hex.view.bookmarks.button.remove"_lang)) bookmarkToRemove = iter; ImGui::NewLine(); - ImGui::TextUnformatted("Name"); + ImGui::TextUnformatted("hex.view.bookmarks.header.name"_lang); ImGui::Separator(); ImGui::InputText("##nameInput", std::string(name.data()).data(), 64); ImGui::SameLine(); - ImGui::ColorEdit4("Color", (float*)&headerColor.Value, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoAlpha); + ImGui::ColorEdit4("hex.view.bookmarks.header.color"_lang, (float*)&headerColor.Value, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoAlpha); color = headerColor; ImGui::NewLine(); - ImGui::TextUnformatted("Comment"); + ImGui::TextUnformatted("hex.view.bookmarks.header.comment"_lang); ImGui::Separator(); ImGui::InputTextMultiline("##colorInput", std::string(comment.data()).data(), 0xF'FFFF); ImGui::NewLine(); diff --git a/source/views/view_command_palette.cpp b/source/views/view_command_palette.cpp index 4121390be..476ba36bd 100644 --- a/source/views/view_command_palette.cpp +++ b/source/views/view_command_palette.cpp @@ -4,7 +4,7 @@ namespace hex { - ViewCommandPalette::ViewCommandPalette() : View("Command Palette") { + ViewCommandPalette::ViewCommandPalette() : View("hex.view.command_palette.name"_lang) { this->m_commandBuffer.resize(1024, 0x00); } @@ -17,7 +17,7 @@ namespace hex { if (!this->m_commandPaletteOpen) return; ImGui::SetNextWindowPos(ImVec2(SharedData::windowPos.x + SharedData::windowSize.x * 0.5F, SharedData::windowPos.y), ImGuiCond_Always, ImVec2(0.5F,0.0F)); - if (ImGui::BeginPopup("Command Palette")) { + if (ImGui::BeginPopup("hex.view.command_palette.name"_lang)) { if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape))) ImGui::CloseCurrentPopup(); @@ -70,7 +70,7 @@ namespace hex { bool ViewCommandPalette::handleShortcut(int key, int mods) { if (key == GLFW_KEY_P && mods == (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL)) { View::doLater([this] { - ImGui::OpenPopup("Command Palette"); + ImGui::OpenPopup("hex.view.command_palette.name"_lang); this->m_commandPaletteOpen = true; this->m_justOpened = true; }); diff --git a/source/views/view_data_inspector.cpp b/source/views/view_data_inspector.cpp index 855032373..f8e89f068 100644 --- a/source/views/view_data_inspector.cpp +++ b/source/views/view_data_inspector.cpp @@ -10,7 +10,7 @@ namespace hex { using NumberDisplayStyle = ContentRegistry::DataInspector::NumberDisplayStyle; - ViewDataInspector::ViewDataInspector() : View("Data Inspector") { + ViewDataInspector::ViewDataInspector() : View("hex.view.data_inspector.name"_lang) { View::subscribeEvent(Events::RegionSelected, [this](auto userData) { auto region = std::any_cast(userData); @@ -54,7 +54,7 @@ namespace hex { } - if (ImGui::Begin("Data Inspector", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { + if (ImGui::Begin("hex.view.data_inspector.name"_lang, &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { auto provider = SharedData::currentProvider; if (provider != nullptr && provider->isReadable()) { @@ -62,8 +62,8 @@ namespace hex { ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg, ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * (this->m_cachedData.size() + 1)))) { ImGui::TableSetupScrollFreeze(0, 1); - ImGui::TableSetupColumn("Name"); - ImGui::TableSetupColumn("Value"); + ImGui::TableSetupColumn("hex.view.data_inspector.table.name"_lang); + ImGui::TableSetupColumn("hex.view.data_inspector.table.value"_lang); ImGui::TableHeadersRow(); @@ -80,27 +80,27 @@ namespace hex { ImGui::NewLine(); - if (ImGui::RadioButton("Little Endian", this->m_endian == std::endian::little)) { + if (ImGui::RadioButton("hex.common.little_endian"_lang, this->m_endian == std::endian::little)) { this->m_endian = std::endian::little; this->m_shouldInvalidate = true; } ImGui::SameLine(); - if (ImGui::RadioButton("Big Endian", this->m_endian == std::endian::big)) { + if (ImGui::RadioButton("hex.common.big_endian"_lang, this->m_endian == std::endian::big)) { this->m_endian = std::endian::big; this->m_shouldInvalidate = true; } - if (ImGui::RadioButton("Decimal", this->m_numberDisplayStyle == NumberDisplayStyle::Decimal)) { + if (ImGui::RadioButton("hex.common.decimal"_lang, this->m_numberDisplayStyle == NumberDisplayStyle::Decimal)) { this->m_numberDisplayStyle = NumberDisplayStyle::Decimal; this->m_shouldInvalidate = true; } ImGui::SameLine(); - if (ImGui::RadioButton("Hexadecimal", this->m_numberDisplayStyle == NumberDisplayStyle::Hexadecimal)) { + if (ImGui::RadioButton("hex.common.hexadecimal"_lang, this->m_numberDisplayStyle == NumberDisplayStyle::Hexadecimal)) { this->m_numberDisplayStyle = NumberDisplayStyle::Hexadecimal; this->m_shouldInvalidate = true; } ImGui::SameLine(); - if (ImGui::RadioButton("Octal", this->m_numberDisplayStyle == NumberDisplayStyle::Octal)) { + if (ImGui::RadioButton("hex.common.octal"_lang, this->m_numberDisplayStyle == NumberDisplayStyle::Octal)) { this->m_numberDisplayStyle = NumberDisplayStyle::Octal; this->m_shouldInvalidate = true; } diff --git a/source/views/view_data_processor.cpp b/source/views/view_data_processor.cpp index 31cdf5cf7..5e24db2df 100644 --- a/source/views/view_data_processor.cpp +++ b/source/views/view_data_processor.cpp @@ -6,7 +6,7 @@ namespace hex { - ViewDataProcessor::ViewDataProcessor() : View("Data Processor") { + ViewDataProcessor::ViewDataProcessor() : View("hex.view.data_processor.name"_lang) { imnodes::Initialize(); imnodes::PushAttributeFlag(imnodes::AttributeFlags_EnableLinkDetachWithDragClick); imnodes::PushAttributeFlag(imnodes::AttributeFlags_EnableLinkCreationOnSnap); @@ -126,7 +126,7 @@ namespace hex { } void ViewDataProcessor::drawContent() { - if (ImGui::Begin("Data Processor", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { + if (ImGui::Begin("hex.view.data_processor.name"_lang, &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { if (ImGui::IsMouseReleased(ImGuiMouseButton_Right) && ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows)) { imnodes::ClearNodeSelection(); @@ -146,7 +146,7 @@ namespace hex { dp::Node *node = nullptr; if (imnodes::NumSelectedNodes() > 0 || imnodes::NumSelectedLinks() > 0) { - if (ImGui::MenuItem("Remove selected")) { + if (ImGui::MenuItem("hex.view.data_processor.name"_lang)) { std::vector ids; ids.resize(imnodes::NumSelectedNodes()); imnodes::GetSelectedNodes(ids.data()); @@ -203,14 +203,14 @@ namespace hex { } if (ImGui::BeginPopup("Node Menu")) { - if (ImGui::MenuItem("Remove Node")) + if (ImGui::MenuItem("hex.view.data_processor.menu.remove_node"_lang)) this->eraseNodes({ this->m_rightClickedId }); ImGui::EndPopup(); } if (ImGui::BeginPopup("Link Menu")) { - if (ImGui::MenuItem("Remove Link")) + if (ImGui::MenuItem("hex.view.data_processor.menu.remove_link"_lang)) this->eraseLink(this->m_rightClickedId); ImGui::EndPopup(); @@ -220,7 +220,7 @@ namespace hex { int nodeId; if (imnodes::IsNodeHovered(&nodeId) && this->m_currNodeError.has_value() && this->m_currNodeError->first->getID() == nodeId) { ImGui::BeginTooltip(); - ImGui::TextUnformatted("Error"); + ImGui::TextUnformatted("hex.common.error"_lang); ImGui::Separator(); ImGui::TextUnformatted(this->m_currNodeError->second.c_str()); ImGui::EndTooltip(); diff --git a/source/views/view_disassembler.cpp b/source/views/view_disassembler.cpp index 45f89ac72..e6fba7d51 100644 --- a/source/views/view_disassembler.cpp +++ b/source/views/view_disassembler.cpp @@ -9,7 +9,7 @@ using namespace std::literals::string_literals; namespace hex { - ViewDisassembler::ViewDisassembler() : View("Disassembler") { + ViewDisassembler::ViewDisassembler() : View("hex.view.disassembler.name"_lang) { View::subscribeEvent(Events::DataChanged, [this](auto){ this->m_shouldInvalidate = true; }); @@ -93,30 +93,30 @@ namespace hex { } - if (ImGui::Begin("Disassembler", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { + if (ImGui::Begin("hex.view.disassembler.name"_lang, &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { auto provider = SharedData::currentProvider; if (provider != nullptr && provider->isReadable()) { - ImGui::TextUnformatted("Position"); + ImGui::TextUnformatted("hex.view.disassembler.position"_lang); ImGui::Separator(); - ImGui::InputScalar("Base address", ImGuiDataType_U64, &this->m_baseAddress, nullptr, nullptr, "%08llX", ImGuiInputTextFlags_CharsHexadecimal); - ImGui::InputScalarN("Code region", ImGuiDataType_U64, this->m_codeRegion, 2, nullptr, nullptr, "%08llX", ImGuiInputTextFlags_CharsHexadecimal); - ImGui::Checkbox("Match selection", &this->m_shouldMatchSelection); + ImGui::InputScalar("hex.view.disassembler.base"_lang, ImGuiDataType_U64, &this->m_baseAddress, nullptr, nullptr, "%08llX", ImGuiInputTextFlags_CharsHexadecimal); + ImGui::InputScalarN("hex.view.disassembler.region"_lang, ImGuiDataType_U64, this->m_codeRegion, 2, nullptr, nullptr, "%08llX", ImGuiInputTextFlags_CharsHexadecimal); + ImGui::Checkbox("hex.common.match_selection"_lang, &this->m_shouldMatchSelection); ImGui::NewLine(); - ImGui::TextUnformatted("Settings"); + ImGui::TextUnformatted("hex.view.disassembler.settings.header"_lang); ImGui::Separator(); - ImGui::Combo("Architecture", reinterpret_cast(&this->m_architecture), Disassembler::ArchitectureNames, Disassembler::getArchitectureSupportedCount()); + ImGui::Combo("hex.view.disassembler.arch"_lang, reinterpret_cast(&this->m_architecture), Disassembler::ArchitectureNames, Disassembler::getArchitectureSupportedCount()); if (ImGui::BeginChild("modes", ImVec2(0, 100), true)) { - if (ImGui::RadioButton("Little Endian", this->m_littleEndianMode)) + if (ImGui::RadioButton("hex.common.little_endian"_lang, this->m_littleEndianMode)) this->m_littleEndianMode = true; ImGui::SameLine(); - if (ImGui::RadioButton("Big Endian", !this->m_littleEndianMode)) + if (ImGui::RadioButton("hex.common.big_endian"_lang, !this->m_littleEndianMode)) this->m_littleEndianMode = false; ImGui::NewLine(); @@ -132,19 +132,19 @@ namespace hex { if (this->m_modeBasicARM == cs_mode(0)) this->m_modeBasicARM = CS_MODE_ARM; - if (ImGui::RadioButton("ARM mode", this->m_modeBasicARM == CS_MODE_ARM)) + if (ImGui::RadioButton("hex.view.disassembler.arm.arm"_lang, this->m_modeBasicARM == CS_MODE_ARM)) this->m_modeBasicARM = CS_MODE_ARM; ImGui::SameLine(); - if (ImGui::RadioButton("Thumb mode", this->m_modeBasicARM == CS_MODE_THUMB)) + if (ImGui::RadioButton("hex.view.disassembler.arm.thumb"_lang, this->m_modeBasicARM == CS_MODE_THUMB)) this->m_modeBasicARM = CS_MODE_THUMB; - if (ImGui::RadioButton("Default mode", (this->m_modeExtraARM & (CS_MODE_MCLASS | CS_MODE_V8)) == 0)) + if (ImGui::RadioButton("hex.view.disassembler.arm.default"_lang, (this->m_modeExtraARM & (CS_MODE_MCLASS | CS_MODE_V8)) == 0)) this->m_modeExtraARM = cs_mode(0); ImGui::SameLine(); - if (ImGui::RadioButton("Cortex-M mode", (this->m_modeExtraARM & (CS_MODE_MCLASS | CS_MODE_V8)) == CS_MODE_MCLASS)) + if (ImGui::RadioButton("hex.view.disassembler.arm.cortex_m"_lang, (this->m_modeExtraARM & (CS_MODE_MCLASS | CS_MODE_V8)) == CS_MODE_MCLASS)) this->m_modeExtraARM = CS_MODE_MCLASS; ImGui::SameLine(); - if (ImGui::RadioButton("ARMv8 mode", (this->m_modeExtraARM & (CS_MODE_MCLASS | CS_MODE_V8)) == CS_MODE_V8)) + if (ImGui::RadioButton("hex.view.disassembler.arm.armv8"_lang, (this->m_modeExtraARM & (CS_MODE_MCLASS | CS_MODE_V8)) == CS_MODE_V8)) this->m_modeExtraARM = CS_MODE_V8; break; case Architecture::MIPS: @@ -157,16 +157,16 @@ namespace hex { if (this->m_modeBasicMIPS == cs_mode(0)) this->m_modeBasicMIPS = CS_MODE_MIPS32; - if (ImGui::RadioButton("MIPS32 mode", this->m_modeBasicMIPS == CS_MODE_MIPS32)) + if (ImGui::RadioButton("hex.view.disassembler.mips.mips32"_lang, this->m_modeBasicMIPS == CS_MODE_MIPS32)) this->m_modeBasicMIPS = CS_MODE_MIPS32; ImGui::SameLine(); - if (ImGui::RadioButton("MIPS64 mode", this->m_modeBasicMIPS == CS_MODE_MIPS64)) + if (ImGui::RadioButton("hex.view.disassembler.mips.mips64"_lang, this->m_modeBasicMIPS == CS_MODE_MIPS64)) this->m_modeBasicMIPS = CS_MODE_MIPS64; ImGui::SameLine(); - if (ImGui::RadioButton("MIPS32R6 mode", this->m_modeBasicMIPS == CS_MODE_MIPS32R6)) + if (ImGui::RadioButton("hex.view.disassembler.mips.mips32R6"_lang, this->m_modeBasicMIPS == CS_MODE_MIPS32R6)) this->m_modeBasicMIPS = CS_MODE_MIPS32R6; - ImGui::Checkbox("Micro Mode", &this->m_micoMode); + ImGui::Checkbox("hex.view.disassembler.mips.micro"_lang, &this->m_micoMode); break; case Architecture::X86: this->m_modeBasicARM = cs_mode(0); @@ -179,13 +179,13 @@ namespace hex { if (this->m_modeBasicX86 == cs_mode(0)) this->m_modeBasicX86 = CS_MODE_16; - if (ImGui::RadioButton("16-bit mode", this->m_modeBasicX86 == CS_MODE_16)) + if (ImGui::RadioButton("hex.view.disassembler.x86.16bit"_lang, this->m_modeBasicX86 == CS_MODE_16)) this->m_modeBasicX86 = CS_MODE_16; ImGui::SameLine(); - if (ImGui::RadioButton("32-bit mode", this->m_modeBasicX86 == CS_MODE_32)) + if (ImGui::RadioButton("hex.view.disassembler.x86.32bit"_lang, this->m_modeBasicX86 == CS_MODE_32)) this->m_modeBasicX86 = CS_MODE_32; ImGui::SameLine(); - if (ImGui::RadioButton("64-bit mode", this->m_modeBasicX86 == CS_MODE_64)) + if (ImGui::RadioButton("hex.view.disassembler.x86.64bit"_lang, this->m_modeBasicX86 == CS_MODE_64)) this->m_modeBasicX86 = CS_MODE_64; break; case Architecture::PPC: @@ -199,10 +199,10 @@ namespace hex { if (m_modeBasicPPC == cs_mode(0)) this->m_modeBasicPPC = CS_MODE_32; - if (ImGui::RadioButton("32-bit mode", this->m_modeBasicPPC == CS_MODE_32)) + if (ImGui::RadioButton("hex.view.disassembler.ppc.32bit"_lang, this->m_modeBasicPPC == CS_MODE_32)) this->m_modeBasicPPC = CS_MODE_32; ImGui::SameLine(); - if (ImGui::RadioButton("64-bit mode", this->m_modeBasicPPC == CS_MODE_64)) + if (ImGui::RadioButton("hex.view.disassembler.ppc.64bit"_lang, this->m_modeBasicPPC == CS_MODE_64)) this->m_modeBasicPPC = CS_MODE_64; break; case Architecture::SPARC: @@ -213,7 +213,7 @@ namespace hex { this->m_modeBasicPPC = cs_mode(0); this->m_micoMode = false; - ImGui::Checkbox("Sparc V9 mode", &this->m_sparcV9Mode); + ImGui::Checkbox("hex.view.disassembler.sparc.v9"_lang, &this->m_sparcV9Mode); break; case Architecture::ARM64: case Architecture::SYSZ: @@ -236,19 +236,19 @@ namespace hex { ImGui::EndChild(); ImGui::SetCursorPosX((ImGui::GetContentRegionAvail().x - 300) / 2); - if (ImGui::Button("Disassemble", ImVec2(300, 20))) + if (ImGui::Button("hex.view.disassembler.disassemble"_lang, ImVec2(300, 20))) this->m_shouldInvalidate = true; ImGui::NewLine(); - ImGui::TextUnformatted("Disassembly"); + ImGui::TextUnformatted("hex.view.disassembler.disassembly.title"_lang); ImGui::Separator(); if (ImGui::BeginTable("##disassembly", 4, ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_Reorderable)) { ImGui::TableSetupScrollFreeze(0, 1); - ImGui::TableSetupColumn("Address"); - ImGui::TableSetupColumn("Offset"); - ImGui::TableSetupColumn("Bytes"); - ImGui::TableSetupColumn("Disassembly"); + ImGui::TableSetupColumn("hex.view.disassembler.disassembly.address"_lang); + ImGui::TableSetupColumn("hex.view.disassembler.disassembly.offset"_lang); + ImGui::TableSetupColumn("hex.view.disassembler.disassembly.bytes"_lang); + ImGui::TableSetupColumn("hex.view.disassembler.disassembly.title"_lang); ImGuiListClipper clipper; clipper.Begin(this->m_disassembly.size()); diff --git a/source/views/view_hashes.cpp b/source/views/view_hashes.cpp index a56422d68..9bbaa38d8 100644 --- a/source/views/view_hashes.cpp +++ b/source/views/view_hashes.cpp @@ -9,7 +9,7 @@ namespace hex { - ViewHashes::ViewHashes() : View("Hashes") { + ViewHashes::ViewHashes() : View("hex.view.hashes.name"_lang) { View::subscribeEvent(Events::DataChanged, [this](auto) { this->m_shouldInvalidate = true; }); @@ -38,26 +38,26 @@ namespace hex { } void ViewHashes::drawContent() { - if (ImGui::Begin("Hashing", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { + if (ImGui::Begin("hex.view.hashes.name"_lang, &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { ImGui::BeginChild("##scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav); auto provider = SharedData::currentProvider; if (provider != nullptr && provider->isAvailable()) { - ImGui::TextUnformatted("Region"); + ImGui::TextUnformatted("hex.common.region"_lang); ImGui::Separator(); ImGui::InputScalarN("##nolabel", ImGuiDataType_U64, this->m_hashRegion, 2, nullptr, nullptr, "%08X", ImGuiInputTextFlags_CharsHexadecimal); if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true; - ImGui::Checkbox("Match selection", &this->m_shouldMatchSelection); + ImGui::Checkbox("hex.common.match_selection"_lang, &this->m_shouldMatchSelection); if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true; ImGui::NewLine(); - ImGui::TextUnformatted("Settings"); + ImGui::TextUnformatted("hex.view.hashes.settings"_lang); ImGui::Separator(); - if (ImGui::Combo("Hash Function", &this->m_currHashFunction, HashFunctionNames,sizeof(HashFunctionNames) / sizeof(const char *))) + if (ImGui::Combo("hex.view.hashes.function"_lang, &this->m_currHashFunction, HashFunctionNames,sizeof(HashFunctionNames) / sizeof(const char *))) this->m_shouldInvalidate = true; size_t dataSize = provider->getSize(); @@ -72,10 +72,10 @@ namespace hex { { static int polynomial = 0, init = 0; - ImGui::InputInt("Initial Value", &init, 0, 0, ImGuiInputTextFlags_CharsHexadecimal); + ImGui::InputInt("hex.view.hashes.iv"_lang, &init, 0, 0, ImGuiInputTextFlags_CharsHexadecimal); if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true; - ImGui::InputInt("Polynomial", &polynomial, 0, 0, ImGuiInputTextFlags_CharsHexadecimal); + ImGui::InputInt("hex.view.hashes.poly"_lang, &polynomial, 0, 0, ImGuiInputTextFlags_CharsHexadecimal); if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true; ImGui::NewLine(); @@ -88,7 +88,7 @@ namespace hex { char buffer[sizeof(result) * 2 + 1]; snprintf(buffer, sizeof(buffer), "%04X", result); - ImGui::TextUnformatted("Result"); + ImGui::TextUnformatted("hex.view.hashes.result"_lang); ImGui::Separator(); ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } @@ -97,10 +97,10 @@ namespace hex { { static int polynomial = 0, init = 0; - ImGui::InputInt("Initial Value", &init, 0, 0, ImGuiInputTextFlags_CharsHexadecimal); + ImGui::InputInt("hex.view.hashes.iv"_lang, &init, 0, 0, ImGuiInputTextFlags_CharsHexadecimal); if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true; - ImGui::InputInt("Polynomial", &polynomial, 0, 0, ImGuiInputTextFlags_CharsHexadecimal); + ImGui::InputInt("hex.view.hashes.poly"_lang, &polynomial, 0, 0, ImGuiInputTextFlags_CharsHexadecimal); if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true; ImGui::NewLine(); @@ -113,7 +113,7 @@ namespace hex { char buffer[sizeof(result) * 2 + 1]; snprintf(buffer, sizeof(buffer), "%08X", result); - ImGui::TextUnformatted("Result"); + ImGui::TextUnformatted("hex.view.hashes.result"_lang); ImGui::Separator(); ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } @@ -129,7 +129,7 @@ namespace hex { formatBigHexInt(result, buffer, sizeof(buffer)); ImGui::NewLine(); - ImGui::TextUnformatted("Result"); + ImGui::TextUnformatted("hex.view.hashes.result"_lang); ImGui::Separator(); ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } @@ -145,7 +145,7 @@ namespace hex { formatBigHexInt(result, buffer, sizeof(buffer)); ImGui::NewLine(); - ImGui::TextUnformatted("Result"); + ImGui::TextUnformatted("hex.view.hashes.result"_lang); ImGui::Separator(); ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } @@ -161,7 +161,7 @@ namespace hex { formatBigHexInt(result, buffer, sizeof(buffer)); ImGui::NewLine(); - ImGui::TextUnformatted("Result"); + ImGui::TextUnformatted("hex.view.hashes.result"_lang); ImGui::Separator(); ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } @@ -177,7 +177,7 @@ namespace hex { formatBigHexInt(result, buffer, sizeof(buffer)); ImGui::NewLine(); - ImGui::TextUnformatted("Result"); + ImGui::TextUnformatted("hex.view.hashes.result"_lang); ImGui::Separator(); ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } @@ -193,7 +193,7 @@ namespace hex { formatBigHexInt(result, buffer, sizeof(buffer)); ImGui::NewLine(); - ImGui::TextUnformatted("Result"); + ImGui::TextUnformatted("hex.view.hashes.result"_lang); ImGui::Separator(); ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } @@ -209,7 +209,7 @@ namespace hex { formatBigHexInt(result, buffer, sizeof(buffer)); ImGui::NewLine(); - ImGui::TextUnformatted("Result"); + ImGui::TextUnformatted("hex.view.hashes.result"_lang); ImGui::Separator(); ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } diff --git a/source/views/view_help.cpp b/source/views/view_help.cpp index 5f4141a46..4d5733506 100644 --- a/source/views/view_help.cpp +++ b/source/views/view_help.cpp @@ -29,26 +29,27 @@ namespace hex { void ViewHelp::drawAboutPopup() { - if (ImGui::BeginPopupModal("About", &this->m_aboutWindowOpen, ImGuiWindowFlags_AlwaysAutoResize)) { + if (ImGui::BeginPopupModal("hex.view.help.about.title"_lang, &this->m_aboutWindowOpen, ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::Text("ImHex Hex Editor v%s by WerWolv -", IMHEX_VERSION); #if defined(GIT_BRANCH) && defined(GIT_COMMIT_HASH) ImGui::SameLine(); if (ImGui::Hyperlink(hex::format("%s@%s", GIT_BRANCH, GIT_COMMIT_HASH).c_str())) hex::openWebpage("https://github.com/WerWolv/ImHex/commit/" GIT_COMMIT_HASH); #endif + ImGui::TextUnformatted("hex.view.help.about.translator"_lang); - ImGui::TextUnformatted("Source code available on GitHub:"); ImGui::SameLine(); + ImGui::TextUnformatted("hex.view.help.about.source"_lang); ImGui::SameLine(); if (ImGui::Hyperlink("WerWolv/ImHex")) hex::openWebpage("https://github.com/WerWolv/ImHex"); ImGui::NewLine(); - ImGui::Text("Donations"); + ImGui::Text("hex.view.help.about.donations"_lang); ImGui::Separator(); constexpr const char* Links[] = { "https://werwolv.net/donate", "https://www.patreon.com/werwolv", "https://github.com/sponsors/WerWolv" }; - ImGui::TextWrapped("If you like my work, please consider donating to keep the project going. Thanks a lot <3"); + ImGui::TextWrapped("hex.view.help.about.thanks"_lang); ImGui::NewLine(); @@ -58,7 +59,7 @@ namespace hex { } ImGui::NewLine(); - ImGui::Text("Libraries used"); + ImGui::Text("hex.view.help.about.libs"_lang); ImGui::Separator(); ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.2F, 0.2F, 0.2F, 0.3F)); ImGui::BulletText("ImGui by ocornut"); diff --git a/source/views/view_hexeditor.cpp b/source/views/view_hexeditor.cpp index 9b53aa531..3cdc2bed1 100644 --- a/source/views/view_hexeditor.cpp +++ b/source/views/view_hexeditor.cpp @@ -17,7 +17,7 @@ namespace hex { ViewHexEditor::ViewHexEditor(std::vector &patternData) - : View("Hex Editor"), m_patternData(patternData) { + : View("hex.view.hexeditor.title"_lang), m_patternData(patternData) { this->m_memoryEditor.ReadFn = [](const ImU8 *data, size_t off) -> ImU8 { auto provider = SharedData::currentProvider; @@ -130,7 +130,7 @@ namespace hex { if (ProjectFile::hasUnsavedChanges()) { glfwSetWindowShouldClose(window, GLFW_FALSE); - View::doLater([] { ImGui::OpenPopup("Save Changes"); }); + View::doLater([] { ImGui::OpenPopup("hex.view.hexeditor.save_changes"_lang); }); } }); @@ -143,12 +143,12 @@ namespace hex { View::subscribeEvent(Events::OpenWindow, [this](auto name) { if (std::any_cast(name) == std::string("Open File")) { - View::openFileBrowser("Open File", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) { + View::openFileBrowser("hex.view.hexeditor.open_file"_lang, imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) { this->openFile(path); this->getWindowOpenState() = true; }); } else if (std::any_cast(name) == std::string("Open Project")) { - View::openFileBrowser("Open Project", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ".hexproj", [this](auto path) { + View::openFileBrowser("hex.view.hexeditor.open_project"_lang, imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ".hexproj", [this](auto path) { ProjectFile::load(path); View::postEvent(Events::ProjectFileLoad); this->getWindowOpenState() = true; @@ -166,15 +166,15 @@ namespace hex { size_t dataSize = (provider == nullptr || !provider->isReadable()) ? 0x00 : provider->getSize(); - this->m_memoryEditor.DrawWindow("Hex Editor", &this->getWindowOpenState(), this, dataSize, dataSize == 0 ? 0x00 : provider->getBaseAddress()); + this->m_memoryEditor.DrawWindow("hex.view.hexeditor.title"_lang, &this->getWindowOpenState(), this, dataSize, dataSize == 0 ? 0x00 : provider->getBaseAddress()); if (dataSize != 0x00) { - if (ImGui::Begin("Hex Editor")) { + if (ImGui::Begin("hex.view.hexeditor.title"_lang)) { if (ImGui::IsMouseReleased(ImGuiMouseButton_Right) && ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows)) - ImGui::OpenPopup("Edit"); + ImGui::OpenPopup("hex.menu.edit"_lang); - if (ImGui::BeginPopup("Edit")) { + if (ImGui::BeginPopup("hex.menu.edit"_lang)) { this->drawEditPopup(); ImGui::EndPopup(); } @@ -182,7 +182,7 @@ namespace hex { ImGui::SameLine(); ImGui::Spacing(); ImGui::SameLine(); - ImGui::Text("Page %d / %d", provider->getCurrentPage() + 1, provider->getPageCount()); + ImGui::Text("hex.view.hexeditor.page"_lang, provider->getCurrentPage() + 1, provider->getPageCount()); ImGui::SameLine(); if (ImGui::ArrowButton("prevPage", ImGuiDir_Left)) { @@ -215,7 +215,7 @@ namespace hex { } static void saveAs() { - View::openFileBrowser("Save As", imgui_addons::ImGuiFileBrowser::DialogMode::SAVE, "*.*", [](auto path) { + View::openFileBrowser("hex.view.hexeditor.save_as"_lang, imgui_addons::ImGuiFileBrowser::DialogMode::SAVE, "*.*", [](auto path) { FILE *file = fopen(path.c_str(), "wb"); if (file != nullptr) { @@ -241,10 +241,9 @@ namespace hex { void ViewHexEditor::drawAlwaysVisible() { auto provider = SharedData::currentProvider; - if (ImGui::BeginPopupModal("Save Changes", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { - constexpr auto Message = "You have unsaved changes made to your Project.\nAre you sure you want to exit?"; + if (ImGui::BeginPopupModal("hex.view.hexeditor.save_changes.title"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::NewLine(); - ImGui::TextUnformatted(Message); + ImGui::TextUnformatted("hex.view.hexeditor.save_changes.desc"_lang); ImGui::NewLine(); confirmButtons("Yes", "No", [] { View::postEvent(Events::CloseImHex); }, [] { ImGui::CloseCurrentPopup(); }); @@ -255,23 +254,22 @@ namespace hex { ImGui::EndPopup(); } - if (ImGui::BeginPopupModal("Load File with Loader Script", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { - constexpr auto Message = "Load a file using a Python loader script."; + if (ImGui::BeginPopupModal("hex.view.hexeditor.script.title"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::SetCursorPosX(10); - ImGui::TextWrapped(Message); + ImGui::TextWrapped("hex.view.hexeditor.script.desc"_lang); ImGui::NewLine(); ImGui::InputText("##nolabel", this->m_loaderScriptScriptPath.data(), this->m_loaderScriptScriptPath.length(), ImGuiInputTextFlags_ReadOnly); ImGui::SameLine(); - if (ImGui::Button("Script")) { - View::openFileBrowser("Loader Script: Open Script", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ".py", [this](auto path) { + if (ImGui::Button("hex.view.hexeditor.script.script"_lang)) { + View::openFileBrowser("hex.view.hexeditor.script.script.title"_lang, imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ".py", [this](auto path) { this->m_loaderScriptScriptPath = path; }); } ImGui::InputText("##nolabel", this->m_loaderScriptFilePath.data(), this->m_loaderScriptFilePath.length(), ImGuiInputTextFlags_ReadOnly); ImGui::SameLine(); - if (ImGui::Button("File")) { - View::openFileBrowser("Loader Script: Open File", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) { + if (ImGui::Button("hex.view.hexeditor.script.file"_lang)) { + View::openFileBrowser("hex.view.hexeditor.script.file.title"_lang, imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) { this->m_loaderScriptFilePath = path; }); } @@ -280,7 +278,7 @@ namespace hex { ImGui::NewLine(); - confirmButtons("Load", "Cancel", + confirmButtons("hex.common.load"_lang, "hex.common.cancel"_lang, [this, &provider] { if (!this->m_loaderScriptScriptPath.empty() && !this->m_loaderScriptFilePath.empty()) { this->openFile(this->m_loaderScriptFilePath); @@ -299,11 +297,11 @@ namespace hex { } - if (ImGui::BeginPopupModal("Set base address", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::InputText("Address", this->m_baseAddressBuffer, 16, ImGuiInputTextFlags_CharsHexadecimal); + if (ImGui::BeginPopupModal("hex.view.hexeditor.menu.edit.set_base"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::InputText("hex.common.address"_lang, this->m_baseAddressBuffer, 16, ImGuiInputTextFlags_CharsHexadecimal); ImGui::NewLine(); - confirmButtons("Set", "Cancel", + confirmButtons("hex.common.set"_lang, "hex.common.cancel"_lang, [this, &provider]{ provider->setBaseAddress(strtoull(this->m_baseAddressBuffer, nullptr, 16)); ImGui::CloseCurrentPopup(); @@ -321,38 +319,38 @@ namespace hex { void ViewHexEditor::drawMenu() { auto provider = SharedData::currentProvider; - if (ImGui::BeginMenu("File")) { - if (ImGui::MenuItem("Open File...", "CTRL + O")) { + if (ImGui::BeginMenu("hex.menu.file"_lang)) { + if (ImGui::MenuItem("hex.view.hexeditor.menu.file.open_file"_lang, "CTRL + O")) { - View::openFileBrowser("Open File", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) { + View::openFileBrowser("hex.view.hexeditor.open_file"_lang, imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) { this->openFile(path); this->getWindowOpenState() = true; }); } - if (ImGui::MenuItem("Save", "CTRL + S", false, provider != nullptr && provider->isWritable())) { + if (ImGui::MenuItem("hex.view.hexeditor.menu.file.save"_lang, "CTRL + S", false, provider != nullptr && provider->isWritable())) { save(); } - if (ImGui::MenuItem("Save As...", "CTRL + SHIFT + S", false, provider != nullptr && provider->isWritable())) { + if (ImGui::MenuItem("hex.view.hexeditor.menu.file.save_as"_lang, "CTRL + SHIFT + S", false, provider != nullptr && provider->isWritable())) { saveAs(); } ImGui::Separator(); - if (ImGui::MenuItem("Open Project", "")) { - View::openFileBrowser("Open Project", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ".hexproj", [this](auto path) { + if (ImGui::MenuItem("hex.view.hexeditor.menu.file.open_project"_lang, "")) { + View::openFileBrowser("hex.view.hexeditor.menu.file.open_project"_lang, imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ".hexproj", [this](auto path) { ProjectFile::load(path); View::postEvent(Events::ProjectFileLoad); this->getWindowOpenState() = true; }); } - if (ImGui::MenuItem("Save Project", "", false, provider != nullptr && provider->isWritable())) { + if (ImGui::MenuItem("hex.view.hexeditor.menu.file.save_project"_lang, "", false, provider != nullptr && provider->isWritable())) { View::postEvent(Events::ProjectFileStore); if (ProjectFile::getProjectFilePath() == "") { - View::openFileBrowser("Save Project", imgui_addons::ImGuiFileBrowser::DialogMode::SAVE, ".hexproj", [](auto path) { + View::openFileBrowser("hex.view.hexeditor.save_project"_lang, imgui_addons::ImGuiFileBrowser::DialogMode::SAVE, ".hexproj", [](auto path) { ProjectFile::store(path); }); } @@ -362,10 +360,10 @@ namespace hex { ImGui::Separator(); - if (ImGui::BeginMenu("Import...")) { - if (ImGui::MenuItem("Base64 File")) { + if (ImGui::BeginMenu("hex.view.hexeditor.menu.file.import"_lang)) { + if (ImGui::MenuItem("hex.view.hexeditor.menu.file.import.base64"_lang)) { - View::openFileBrowser("Open Base64 File", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) { + View::openFileBrowser("hex.view.hexeditor.menu.file.import.base64"_lang, imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) { std::vector base64; this->loadFromFile(path, base64); @@ -373,19 +371,19 @@ namespace hex { this->m_dataToSave = crypt::decode64(base64); if (this->m_dataToSave.empty()) - View::showErrorPopup("File is not in a valid Base64 format!"); + View::showErrorPopup("hex.view.hexeditor.base64.import_error"_lang); else - ImGui::OpenPopup("Save Data"); + ImGui::OpenPopup("hex.view.hexeditor.save_data"_lang); this->getWindowOpenState() = true; - } else View::showErrorPopup("Failed to open file!"); + } else View::showErrorPopup("hex.view.hexeditor.file_open_error"_lang); }); } ImGui::Separator(); - if (ImGui::MenuItem("IPS Patch")) { + if (ImGui::MenuItem("hex.view.hexeditor.menu.file.import.ips"_lang)) { - View::openFileBrowser("Apply IPS Patch", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) { + View::openFileBrowser("hex.view.hexeditor.open_file"_lang, imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) { auto patchData = hex::readFile(path); auto patch = hex::loadIPSPatch(patchData); @@ -398,8 +396,8 @@ namespace hex { } - if (ImGui::MenuItem("IPS32 Patch")) { - View::openFileBrowser("Apply IPS32 Patch", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) { + if (ImGui::MenuItem("hex.view.hexeditor.menu.file.import.ips32"_lang)) { + View::openFileBrowser("hex.view.hexeditor.open_file"_lang, imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, "*.*", [this](auto path) { auto patchData = hex::readFile(path); auto patch = hex::loadIPS32Patch(patchData); @@ -410,17 +408,17 @@ namespace hex { }); } - if (ImGui::MenuItem("File with Loader Script")) { + if (ImGui::MenuItem("hex.view.hexeditor.menu.file.import.script"_lang)) { this->m_loaderScriptFilePath.clear(); this->m_loaderScriptScriptPath.clear(); - View::doLater([]{ ImGui::OpenPopup("Load File with Loader Script"); }); + View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.script.title"_lang); }); } ImGui::EndMenu(); } - if (ImGui::BeginMenu("Export...", provider != nullptr && provider->isWritable())) { - if (ImGui::MenuItem("IPS Patch")) { + if (ImGui::BeginMenu("hex.view.hexeditor.menu.file.export"_lang, provider != nullptr && provider->isWritable())) { + if (ImGui::MenuItem("hex.view.hexeditor.menu.file.export.ips"_lang)) { Patches patches = provider->getPatches(); if (!patches.contains(0x00454F45) && patches.contains(0x00454F46)) { u8 value = 0; @@ -429,11 +427,11 @@ namespace hex { } this->m_dataToSave = generateIPSPatch(patches); - View::openFileBrowser("Export File", imgui_addons::ImGuiFileBrowser::DialogMode::SAVE, "*.*", [this](auto path) { + View::openFileBrowser("hex.view.hexeditor.menu.file.export.title"_lang, imgui_addons::ImGuiFileBrowser::DialogMode::SAVE, "*.*", [this](auto path) { this->saveToFile(path, this->m_dataToSave); }); } - if (ImGui::MenuItem("IPS32 Patch")) { + if (ImGui::MenuItem("hex.view.hexeditor.menu.file.export.ips32"_lang)) { Patches patches = provider->getPatches(); if (!patches.contains(0x00454F45) && patches.contains(0x45454F46)) { u8 value = 0; @@ -442,7 +440,7 @@ namespace hex { } this->m_dataToSave = generateIPS32Patch(patches); - View::openFileBrowser("Export File", imgui_addons::ImGuiFileBrowser::DialogMode::SAVE, "*.*", [this](auto path) { + View::openFileBrowser("hex.view.hexeditor.menu.file.export.title"_lang, imgui_addons::ImGuiFileBrowser::DialogMode::SAVE, "*.*", [this](auto path) { this->saveToFile(path, this->m_dataToSave); }); } @@ -454,20 +452,20 @@ namespace hex { ImGui::Separator(); - if (ImGui::MenuItem("Search", "CTRL + F")) { + if (ImGui::MenuItem("hex.view.hexeditor.menu.file.search"_lang, "CTRL + F")) { this->getWindowOpenState() = true; - View::doLater([]{ ImGui::OpenPopup("Search"); }); + View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.menu.file.search"_lang); }); } - if (ImGui::MenuItem("Goto", "CTRL + G")) { + if (ImGui::MenuItem("hex.view.hexeditor.menu.file.goto"_lang, "CTRL + G")) { this->getWindowOpenState() = true; - View::doLater([]{ ImGui::OpenPopup("Goto"); }); + View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.menu.file.goto"_lang); }); } ImGui::EndMenu(); } - if (ImGui::BeginMenu("Edit")) { + if (ImGui::BeginMenu("hex.menu.edit"_lang)) { this->drawEditPopup(); ImGui::EndMenu(); } @@ -481,13 +479,13 @@ namespace hex { saveAs(); return true; } else if (mods == GLFW_MOD_CONTROL && key == GLFW_KEY_F) { - View::doLater([]{ ImGui::OpenPopup("Search"); }); + View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.menu.file.search"_lang); }); return true; } else if (mods == GLFW_MOD_CONTROL && key == GLFW_KEY_G) { - View::doLater([]{ ImGui::OpenPopup("Goto"); }); + View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.menu.file.goto"_lang); }); return true; } else if (mods == GLFW_MOD_CONTROL && key == GLFW_KEY_O) { - View::doLater([]{ ImGui::OpenPopup("Open File"); }); + View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.open_file"_lang); }); return true; } else if (mods == (GLFW_MOD_CONTROL | GLFW_MOD_ALT) && key == GLFW_KEY_C) { this->copyBytes(); @@ -510,13 +508,13 @@ namespace hex { provider = new prv::FileProvider(path); if (!provider->isWritable()) { this->m_memoryEditor.ReadOnly = true; - View::showErrorPopup("Couldn't get write access. File opened in read-only mode."); + View::showErrorPopup("hex.view.hexeditor.error.read_only"_lang); } else { this->m_memoryEditor.ReadOnly = false; } if (!provider->isAvailable()) { - View::showErrorPopup("Failed to open file!"); + View::showErrorPopup("hex.view.hexeditor.error.open"_lang); return; } @@ -918,11 +916,11 @@ R"( } }; - if (ImGui::BeginPopupContextVoid("Search")) { - ImGui::TextUnformatted("Search"); + if (ImGui::BeginPopupContextVoid("hex.view.hexeditor.menu.file.search"_lang)) { + ImGui::TextUnformatted("hex.view.hexeditor.menu.file.search"_lang); if (ImGui::BeginTabBar("searchTabs")) { char *currBuffer; - if (ImGui::BeginTabItem("String")) { + if (ImGui::BeginTabItem("hex.view.hexeditor.search.string"_lang)) { this->m_searchFunction = findString; this->m_lastSearchBuffer = &this->m_lastStringSearch; currBuffer = this->m_searchStringBuffer; @@ -932,7 +930,7 @@ R"( ImGui::EndTabItem(); } - if (ImGui::BeginTabItem("Hex")) { + if (ImGui::BeginTabItem("hex.view.hexeditor.search.hex"_lang)) { this->m_searchFunction = findHex; this->m_lastSearchBuffer = &this->m_lastHexSearch; currBuffer = this->m_searchHexBuffer; @@ -943,16 +941,16 @@ R"( ImGui::EndTabItem(); } - if (ImGui::Button("Find")) + if (ImGui::Button("hex.view.hexeditor.search.find"_lang)) Find(currBuffer); if (this->m_lastSearchBuffer->size() > 0) { - if ((ImGui::Button("Find Next"))) + if ((ImGui::Button("hex.view.hexeditor.search.find_next"_lang))) FindNext(); ImGui::SameLine(); - if ((ImGui::Button("Find Prev"))) + if ((ImGui::Button("hex.view.hexeditor.search.find_prev"_lang))) FindPrevious(); } @@ -967,11 +965,11 @@ R"( void ViewHexEditor::drawGotoPopup() { auto provider = SharedData::currentProvider; - if (ImGui::BeginPopup("Goto")) { - ImGui::TextUnformatted("Goto"); + if (ImGui::BeginPopup("hex.view.hexeditor.menu.file.goto"_lang)) { + ImGui::TextUnformatted("hex.view.hexeditor.menu.file.goto"_lang); if (ImGui::BeginTabBar("gotoTabs")) { s64 newOffset = 0; - if (ImGui::BeginTabItem("Begin")) { + if (ImGui::BeginTabItem("hex.view.hexeditor.goto.offset.begin"_lang)) { ImGui::InputScalar("##nolabel", ImGuiDataType_U64, &this->m_gotoAddress, nullptr, nullptr, "%llx", ImGuiInputTextFlags_CharsHexadecimal); if (this->m_gotoAddress >= provider->getActualSize()) @@ -981,7 +979,7 @@ R"( ImGui::EndTabItem(); } - if (ImGui::BeginTabItem("Current")) { + if (ImGui::BeginTabItem("hex.view.hexeditor.goto.offset.current"_lang)) { ImGui::InputScalar("##nolabel", ImGuiDataType_S64, &this->m_gotoAddress, nullptr, nullptr, "%llx", ImGuiInputTextFlags_CharsHexadecimal); if (this->m_memoryEditor.DataPreviewAddr == -1 || this->m_memoryEditor.DataPreviewAddrEnd == -1) { @@ -1002,7 +1000,7 @@ R"( ImGui::EndTabItem(); } - if (ImGui::BeginTabItem("End")) { + if (ImGui::BeginTabItem("hex.view.hexeditor.goto.offset.end"_lang)) { ImGui::InputScalar("##nolabel", ImGuiDataType_U64, &this->m_gotoAddress, nullptr, nullptr, "%llx", ImGuiInputTextFlags_CharsHexadecimal); if (this->m_gotoAddress >= provider->getActualSize()) @@ -1013,7 +1011,7 @@ R"( ImGui::EndTabItem(); } - if (ImGui::Button("Goto")) { + if (ImGui::Button("hex.view.hexeditor.menu.file.goto"_lang)) { provider->setCurrentPage(std::floor(newOffset / double(prv::Provider::PageSize))); this->m_memoryEditor.GotoAddr = newOffset; this->m_memoryEditor.DataPreviewAddr = newOffset; @@ -1028,40 +1026,40 @@ R"( } void ViewHexEditor::drawEditPopup() { - if (ImGui::BeginMenu("Copy as...", this->m_memoryEditor.DataPreviewAddr != -1 && this->m_memoryEditor.DataPreviewAddrEnd != -1)) { - if (ImGui::MenuItem("Bytes", "CTRL + ALT + C")) + if (ImGui::BeginMenu("hex.view.hexeditor.menu.edit.copy"_lang, this->m_memoryEditor.DataPreviewAddr != -1 && this->m_memoryEditor.DataPreviewAddrEnd != -1)) { + if (ImGui::MenuItem("hex.view.hexeditor.copy.bytes"_lang, "CTRL + ALT + C")) this->copyBytes(); - if (ImGui::MenuItem("Hex String", "CTRL + SHIFT + C")) + if (ImGui::MenuItem("hex.view.hexeditor.copy.hex"_lang, "CTRL + SHIFT + C")) this->copyString(); ImGui::Separator(); - if (ImGui::MenuItem("C Array")) + if (ImGui::MenuItem("hex.view.hexeditor.copy.c"_lang)) this->copyLanguageArray(Language::C); - if (ImGui::MenuItem("C++ Array")) + if (ImGui::MenuItem("hex.view.hexeditor.copy.cpp"_lang)) this->copyLanguageArray(Language::Cpp); - if (ImGui::MenuItem("C# Array")) + if (ImGui::MenuItem("hex.view.hexeditor.copy.csharp"_lang)) this->copyLanguageArray(Language::CSharp); - if (ImGui::MenuItem("Rust Array")) + if (ImGui::MenuItem("hex.view.hexeditor.copy.rust"_lang)) this->copyLanguageArray(Language::Rust); - if (ImGui::MenuItem("Python Array")) + if (ImGui::MenuItem("hex.view.hexeditor.copy.python"_lang)) this->copyLanguageArray(Language::Python); - if (ImGui::MenuItem("Java Array")) + if (ImGui::MenuItem("hex.view.hexeditor.copy.java"_lang)) this->copyLanguageArray(Language::Java); - if (ImGui::MenuItem("JavaScript Array")) + if (ImGui::MenuItem("hex.view.hexeditor.copy.js"_lang)) this->copyLanguageArray(Language::JavaScript); ImGui::Separator(); - if (ImGui::MenuItem("Editor View")) + if (ImGui::MenuItem("hex.view.hexeditor.copy.ascii"_lang)) this->copyHexView(); - if (ImGui::MenuItem("HTML")) + if (ImGui::MenuItem("hex.view.hexeditor.copy.html"_lang)) this->copyHexViewHTML(); ImGui::EndMenu(); } - if (ImGui::MenuItem("Create bookmark", nullptr, false, this->m_memoryEditor.DataPreviewAddr != -1 && this->m_memoryEditor.DataPreviewAddrEnd != -1)) { + if (ImGui::MenuItem("hex.view.hexeditor.menu.edit.bookmark"_lang, nullptr, false, this->m_memoryEditor.DataPreviewAddr != -1 && this->m_memoryEditor.DataPreviewAddrEnd != -1)) { size_t start = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); size_t end = std::max(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); @@ -1069,9 +1067,9 @@ R"( } auto provider = SharedData::currentProvider; - if (ImGui::MenuItem("Set base address", nullptr, false, provider != nullptr && provider->isReadable())) { + if (ImGui::MenuItem("hex.view.hexeditor.menu.edit.set_base"_lang, nullptr, false, provider != nullptr && provider->isReadable())) { std::memset(this->m_baseAddressBuffer, 0x00, sizeof(this->m_baseAddressBuffer)); - View::doLater([]{ ImGui::OpenPopup("Set base address"); }); + View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.menu.edit.set_base"_lang); }); } } diff --git a/source/views/view_information.cpp b/source/views/view_information.cpp index 1daa81508..1a88e25a3 100644 --- a/source/views/view_information.cpp +++ b/source/views/view_information.cpp @@ -13,7 +13,7 @@ namespace hex { - ViewInformation::ViewInformation() : View("Information") { + ViewInformation::ViewInformation() : View("hex.view.information.title"_lang) { View::subscribeEvent(Events::DataChanged, [this](auto) { this->m_dataValid = false; this->m_highestBlockEntropy = 0; @@ -45,7 +45,7 @@ namespace hex { } void ViewInformation::drawContent() { - if (ImGui::Begin("Data Information", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { + if (ImGui::Begin("hex.view.information.title"_lang, &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { ImGui::BeginChild("##scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav); auto provider = SharedData::currentProvider; @@ -125,7 +125,7 @@ namespace hex { ImGui::NewLine(); - if (ImGui::Button("Analyze current page")) + if (ImGui::Button("hex.view.information.analyze"_lang)) this->m_shouldInvalidate = true; ImGui::NewLine(); @@ -138,20 +138,20 @@ namespace hex { ImGui::LabelText(name.c_str(), "%s", value.c_str()); } - ImGui::LabelText("Analyzed region", "0x%llx - 0x%llx", this->m_analyzedRegion.first, this->m_analyzedRegion.second); + ImGui::LabelText("hex.view.information.region"_lang, "0x%llx - 0x%llx", this->m_analyzedRegion.first, this->m_analyzedRegion.second); ImGui::NewLine(); ImGui::Separator(); ImGui::NewLine(); if (!this->m_fileDescription.empty()) { - ImGui::TextUnformatted("Description:"); + ImGui::TextUnformatted("hex.view.information.description"_lang); ImGui::TextWrapped("%s", this->m_fileDescription.c_str()); ImGui::NewLine(); } if (!this->m_mimeType.empty()) { - ImGui::TextUnformatted("MIME Type:"); + ImGui::TextUnformatted("hex.view.information.mime"_lang); ImGui::TextWrapped("%s", this->m_mimeType.c_str()); ImGui::NewLine(); } @@ -159,25 +159,25 @@ namespace hex { ImGui::Separator(); ImGui::NewLine(); - ImGui::Text("Byte Distribution"); + ImGui::Text("hex.view.information.distribution"_lang); ImGui::PlotHistogram("##nolabel", this->m_valueCounts.data(), 256, 0, nullptr, FLT_MAX, FLT_MAX,ImVec2(0, 100)); ImGui::NewLine(); ImGui::Separator(); ImGui::NewLine(); - ImGui::Text("Entropy"); + ImGui::Text("hex.view.information.entropy"_lang); ImGui::PlotLines("##nolabel", this->m_blockEntropy.data(), this->m_blockEntropy.size(), 0, nullptr, FLT_MAX, FLT_MAX, ImVec2(0, 100)); ImGui::NewLine(); - ImGui::LabelText("Block size", "2048 blocks of %lu bytes", this->m_blockSize); - ImGui::LabelText("Average entropy", "%.8f", this->m_averageEntropy); - ImGui::LabelText("Highest entropy block", "%.8f", this->m_highestBlockEntropy); + ImGui::LabelText("hex.view.information.block_size"_lang, "hex.view.information.block_size.desc"_lang, this->m_blockSize); + ImGui::LabelText("hex.view.information.file_entropy"_lang, "%.8f", this->m_averageEntropy); + ImGui::LabelText("hex.view.information.highest_entropy"_lang, "%.8f", this->m_highestBlockEntropy); if (this->m_averageEntropy > 0.83 && this->m_highestBlockEntropy > 0.9) { ImGui::NewLine(); - ImGui::TextColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F),"This data is most likely encrypted or compressed!"); + ImGui::TextColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F),"hex.view.information.encrypted"_lang); } } diff --git a/source/views/view_patches.cpp b/source/views/view_patches.cpp index 03fcc6009..e5a265f07 100644 --- a/source/views/view_patches.cpp +++ b/source/views/view_patches.cpp @@ -11,7 +11,7 @@ using namespace std::literals::string_literals; namespace hex { - ViewPatches::ViewPatches() : View("Patches") { + ViewPatches::ViewPatches() : View("hex.view.patches.title"_lang) { View::subscribeEvent(Events::ProjectFileStore, [](auto) { auto provider = SharedData::currentProvider; if (provider != nullptr) @@ -31,7 +31,7 @@ namespace hex { } void ViewPatches::drawContent() { - if (ImGui::Begin("Patches", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { + if (ImGui::Begin("hex.view.patches.title"_lang, &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { auto provider = SharedData::currentProvider; if (provider != nullptr && provider->isReadable()) { @@ -39,9 +39,9 @@ namespace hex { if (ImGui::BeginTable("##patchesTable", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) { ImGui::TableSetupScrollFreeze(0, 1); - ImGui::TableSetupColumn("Offset"); - ImGui::TableSetupColumn("Previous Value"); - ImGui::TableSetupColumn("Patched Value"); + ImGui::TableSetupColumn("hex.view.patches.offset"_lang); + ImGui::TableSetupColumn("hex.view.patches.orig"_lang); + ImGui::TableSetupColumn("hex.view.patches.patch"_lang); ImGui::TableHeadersRow(); @@ -73,7 +73,7 @@ namespace hex { } if (ImGui::BeginPopup("PatchContextMenu")) { - if (ImGui::MenuItem("Remove")) { + if (ImGui::MenuItem("hex.view.patches.remove"_lang)) { patches.erase(this->m_selectedPatch); ProjectFile::markDirty(); } diff --git a/source/views/view_pattern.cpp b/source/views/view_pattern.cpp index 25b5b02ce..c6b18e74f 100644 --- a/source/views/view_pattern.cpp +++ b/source/views/view_pattern.cpp @@ -74,7 +74,7 @@ namespace hex { } - ViewPattern::ViewPattern(std::vector &patternData) : View("Pattern"), m_patternData(patternData) { + ViewPattern::ViewPattern(std::vector &patternData) : View("hex.view.pattern.title"_lang), m_patternData(patternData) { this->m_patternLanguageRuntime = new lang::PatternLanguage(); this->m_textEditor.SetLanguageDefinition(PatternLanguage()); @@ -165,7 +165,7 @@ namespace hex { if (!this->m_possiblePatternFiles.empty()) { this->m_selectedPatternFile = 0; - View::doLater([] { ImGui::OpenPopup("Accept Pattern"); }); + View::doLater([] { ImGui::OpenPopup("hex.view.pattern.accept_pattern"_lang); }); } }); @@ -200,9 +200,9 @@ namespace hex { } void ViewPattern::drawMenu() { - if (ImGui::BeginMenu("File")) { - if (ImGui::MenuItem("Load pattern...")) { - View::openFileBrowser("Open Hex Pattern", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ".hexpat", [this](auto path) { + if (ImGui::BeginMenu("hex.menu.file"_lang)) { + if (ImGui::MenuItem("hex.view.pattern.menu.file.load_pattern"_lang)) { + View::openFileBrowser("hex.view.pattern.open_pattern"_lang, imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ".hexpat", [this](auto path) { this->loadPatternFile(path); }); } @@ -211,13 +211,13 @@ namespace hex { } void ViewPattern::drawContent() { - if (ImGui::Begin("Pattern", &this->getWindowOpenState(), ImGuiWindowFlags_None | ImGuiWindowFlags_NoCollapse)) { + if (ImGui::Begin("hex.view.pattern.title"_lang, &this->getWindowOpenState(), ImGuiWindowFlags_None | ImGuiWindowFlags_NoCollapse)) { auto provider = SharedData::currentProvider; if (provider != nullptr && provider->isAvailable()) { auto textEditorSize = ImGui::GetContentRegionAvail(); textEditorSize.y *= 4.0/5.0; - this->m_textEditor.Render("Pattern", textEditorSize, true); + this->m_textEditor.Render("hex.view.pattern.title"_lang, textEditorSize, true); auto consoleSize = ImGui::GetContentRegionAvail(); ImGui::PushStyleColor(ImGuiCol_ChildBg, this->m_textEditor.GetPalette()[u32(TextEditor::PaletteIndex::Background)]); @@ -260,8 +260,8 @@ namespace hex { } void ViewPattern::drawAlwaysVisible() { - if (ImGui::BeginPopupModal("Accept Pattern", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::TextWrapped("One or more patterns compatible with this data type has been found"); + if (ImGui::BeginPopupModal("hex.view.pattern.accept_pattern"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::TextWrapped("hex.view.pattern.accept_pattern.desc"_lang); char *entries[this->m_possiblePatternFiles.size()]; @@ -269,12 +269,12 @@ namespace hex { entries[i] = this->m_possiblePatternFiles[i].data(); } - ImGui::ListBox("Patterns", &this->m_selectedPatternFile, entries, IM_ARRAYSIZE(entries), 4); + ImGui::ListBox("hex.view.pattern.accept_pattern.patterns"_lang, &this->m_selectedPatternFile, entries, IM_ARRAYSIZE(entries), 4); ImGui::NewLine(); - ImGui::Text("Do you want to load it?"); + ImGui::Text("hex.view.pattern.accept_pattern.question"_lang); - confirmButtons("Yes", "No", [this]{ + confirmButtons("hex.common.yes"_lang, "hex.common.no"_lang, [this]{ this->loadPatternFile("patterns/" + this->m_possiblePatternFiles[this->m_selectedPatternFile]); ImGui::CloseCurrentPopup(); }, []{ diff --git a/source/views/view_pattern_data.cpp b/source/views/view_pattern_data.cpp index 3c4deab17..039983e23 100644 --- a/source/views/view_pattern_data.cpp +++ b/source/views/view_pattern_data.cpp @@ -6,7 +6,7 @@ namespace hex { ViewPatternData::ViewPatternData(std::vector &patternData) - : View("Pattern Data"), m_patternData(patternData) { + : View("hex.view.pattern_data.title"_lang), m_patternData(patternData) { this->subscribeEvent(Events::PatternChanged, [this](auto data) { this->m_sortedPatternData.clear(); @@ -20,12 +20,12 @@ namespace hex { static bool beginPatternDataTable(prv::Provider* &provider, const std::vector &patterns, std::vector &sortedPatterns) { if (ImGui::BeginTable("##patterndatatable", 6, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) { ImGui::TableSetupScrollFreeze(0, 1); - ImGui::TableSetupColumn("Name", 0, -1, ImGui::GetID("name")); - ImGui::TableSetupColumn("Color", 0, -1, ImGui::GetID("color")); - ImGui::TableSetupColumn("Offset", 0, -1, ImGui::GetID("offset")); - ImGui::TableSetupColumn("Size", 0, -1, ImGui::GetID("size")); - ImGui::TableSetupColumn("Type", 0, -1, ImGui::GetID("type")); - ImGui::TableSetupColumn("Value", 0, -1, ImGui::GetID("value")); + ImGui::TableSetupColumn("hex.view.pattern_data.name"_lang, 0, -1, ImGui::GetID("name")); + ImGui::TableSetupColumn("hex.view.pattern_data.color"_lang, 0, -1, ImGui::GetID("color")); + ImGui::TableSetupColumn("hex.view.pattern_data.offset"_lang, 0, -1, ImGui::GetID("offset")); + ImGui::TableSetupColumn("hex.view.pattern_data.size"_lang, 0, -1, ImGui::GetID("size")); + ImGui::TableSetupColumn("hex.view.pattern_data.type"_lang, 0, -1, ImGui::GetID("type")); + ImGui::TableSetupColumn("hex.view.pattern_data.value"_lang, 0, -1, ImGui::GetID("value")); auto sortSpecs = ImGui::TableGetSortSpecs(); @@ -49,7 +49,7 @@ namespace hex { } void ViewPatternData::drawContent() { - if (ImGui::Begin("Pattern Data", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { + if (ImGui::Begin("hex.view.pattern_data.title"_lang, &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { auto provider = SharedData::currentProvider; if (provider != nullptr && provider->isReadable()) { diff --git a/source/views/view_settings.cpp b/source/views/view_settings.cpp index 91a1cd0a1..3389d6db6 100644 --- a/source/views/view_settings.cpp +++ b/source/views/view_settings.cpp @@ -4,10 +4,10 @@ namespace hex { - ViewSettings::ViewSettings() : View("Settings") { + ViewSettings::ViewSettings() : View("hex.view.settings.title"_lang) { View::subscribeEvent(Events::OpenWindow, [this](auto name) { - if (std::any_cast(name) == std::string("Preferences")) { - View::doLater([]{ ImGui::OpenPopup("Preferences"); }); + if (std::any_cast(name) == std::string("hex.view.settings.title"_lang)) { + View::doLater([]{ ImGui::OpenPopup("hex.view.settings.title"_lang); }); this->getWindowOpenState() = true; } }); @@ -21,16 +21,13 @@ namespace hex { ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX)); - if (ImGui::BeginPopupModal("Preferences", &this->getWindowOpenState(), ImGuiWindowFlags_AlwaysAutoResize)) { + if (ImGui::BeginPopupModal("hex.view.settings.title"_lang, &this->getWindowOpenState(), ImGuiWindowFlags_AlwaysAutoResize)) { for (auto &[category, entries] : ContentRegistry::Settings::getEntries()) { ImGui::TextUnformatted(category.c_str()); ImGui::Separator(); for (auto &[name, callback] : entries) { - ImGui::TextUnformatted(name.c_str()); - ImGui::SameLine(); if (callback(ContentRegistry::Settings::getSettingsData()[category][name])) View::postEvent(Events::SettingsChanged); - ImGui::NewLine(); } ImGui::NewLine(); } @@ -41,9 +38,9 @@ namespace hex { } void ViewSettings::drawMenu() { - if (ImGui::BeginMenu("Help")) { - if (ImGui::MenuItem("Preferences")) { - View::doLater([]{ ImGui::OpenPopup("Preferences"); }); + if (ImGui::BeginMenu("hex.menu.help"_lang)) { + if (ImGui::MenuItem("hex.view.settings.title"_lang)) { + View::doLater([]{ ImGui::OpenPopup("hex.view.settings.title"_lang); }); this->getWindowOpenState() = true; } ImGui::EndMenu(); diff --git a/source/views/view_strings.cpp b/source/views/view_strings.cpp index e3990ca00..5ac226ed4 100644 --- a/source/views/view_strings.cpp +++ b/source/views/view_strings.cpp @@ -11,7 +11,7 @@ using namespace std::literals::string_literals; namespace hex { - ViewStrings::ViewStrings() : View("Strings") { + ViewStrings::ViewStrings() : View("hex.view.strings.title"_lang) { View::subscribeEvent(Events::DataChanged, [this](auto){ this->m_foundStrings.clear(); }); @@ -32,14 +32,14 @@ namespace hex { this->m_selectedString = foundString.string; } if (ImGui::BeginPopup("StringContextMenu")) { - if (ImGui::MenuItem("Copy string")) { + if (ImGui::MenuItem("hex.view.strings.copy"_lang)) { ImGui::SetClipboardText(this->m_selectedString.c_str()); } ImGui::Separator(); - if (ImGui::MenuItem("Demangle")) { + if (ImGui::MenuItem("hex.view.strings.demangle"_lang)) { this->m_demangledName = llvm::demangle(this->m_selectedString); if (!this->m_demangledName.empty()) - View::doLater([]{ ImGui::OpenPopup("Demangled Name"); }); + View::doLater([]{ ImGui::OpenPopup("hex.view.strings.demangle.title"_lang); }); } ImGui::EndPopup(); } @@ -86,11 +86,11 @@ namespace hex { if (ImGui::Begin("Strings", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { if (provider != nullptr && provider->isReadable()) { - if (ImGui::InputInt("Minimum length", &this->m_minimumLength, 1, 0)) + if (ImGui::InputInt("hex.view.strings.min_length"_lang, &this->m_minimumLength, 1, 0)) this->m_shouldInvalidate = true; - ImGui::InputText("Filter", this->m_filter, 0xFFFF); - if (ImGui::Button("Extract")) + ImGui::InputText("hex.view.strings.filter"_lang, this->m_filter, 0xFFFF); + if (ImGui::Button("hex.view.strings.extract"_lang)) this->m_shouldInvalidate = true; ImGui::Separator(); @@ -100,26 +100,26 @@ namespace hex { ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) { ImGui::TableSetupScrollFreeze(0, 1); - ImGui::TableSetupColumn("Offset", 0, -1, ImGui::GetID("offset")); - ImGui::TableSetupColumn("Size", 0, -1, ImGui::GetID("size")); - ImGui::TableSetupColumn("String", 0, -1, ImGui::GetID("string")); + ImGui::TableSetupColumn("hex.view.strings.offset"_lang, 0, -1, ImGui::GetID("offset")); + ImGui::TableSetupColumn("hex.view.strings.size"_lang, 0, -1, ImGui::GetID("size")); + ImGui::TableSetupColumn("hex.view.strings.string"_lang, 0, -1, ImGui::GetID("string")); auto sortSpecs = ImGui::TableGetSortSpecs(); if (sortSpecs->SpecsDirty) { std::sort(this->m_foundStrings.begin(), this->m_foundStrings.end(), [&sortSpecs](FoundString &left, FoundString &right) -> bool { - if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("offset")) { + if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("hex.view.strings.offset"_lang)) { if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending) return left.offset > right.offset; else return left.offset < right.offset; - } else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("size")) { + } else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("hex.view.strings.size"_lang)) { if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending) return left.size > right.size; else return left.size < right.size; - } else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("string")) { + } else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("hex.view.strings.string"_lang)) { if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending) return left.string > right.string; else @@ -170,14 +170,14 @@ namespace hex { } ImGui::End(); - if (ImGui::BeginPopup("Demangled Name")) { + if (ImGui::BeginPopup("hex.view.strings.demangle.title"_lang)) { if (ImGui::BeginChild("##scrolling", ImVec2(500, 150))) { - ImGui::Text("Demangled Name"); + ImGui::Text("hex.view.strings.demangle.title"_lang); ImGui::Separator(); ImGui::TextWrapped("%s", this->m_demangledName.c_str()); ImGui::EndChild(); ImGui::NewLine(); - if (ImGui::Button("Copy")) + if (ImGui::Button("hex.view.strings.demangle.copy"_lang)) ImGui::SetClipboardText(this->m_demangledName.c_str()); } ImGui::EndPopup(); diff --git a/source/views/view_tools.cpp b/source/views/view_tools.cpp index a5d0e9e6b..fc515b83f 100644 --- a/source/views/view_tools.cpp +++ b/source/views/view_tools.cpp @@ -4,12 +4,12 @@ namespace hex { - ViewTools::ViewTools() : View("Tools") { } + ViewTools::ViewTools() : View("hex.view.tools.title"_lang) { } ViewTools::~ViewTools() { } void ViewTools::drawContent() { - if (ImGui::Begin("Tools", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { + if (ImGui::Begin("hex.view.tools.title"_lang, &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { for (const auto& [name, function] : ContentRegistry::Tools::getEntries()) { if (ImGui::CollapsingHeader(name.c_str())) { function(); diff --git a/source/window.cpp b/source/window.cpp index becc3afec..d139ac8ba 100644 --- a/source/window.cpp +++ b/source/window.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -20,8 +21,6 @@ namespace hex { - constexpr auto MenuBarItems = { "File", "Edit", "View", "Help" }; - void *ImHexSettingsHandler_ReadOpenFn(ImGuiContext *ctx, ImGuiSettingsHandler *, const char *) { return ctx; // Unused, but the return value has to be non-null } @@ -39,7 +38,7 @@ namespace hex { buf->appendf("[%s][General]\n", handler->TypeName); for (auto &view : ContentRegistry::Views::getEntries()) { - buf->appendf("%s=%d\n", view->getName().data(), view->getWindowOpenState()); + buf->appendf("%s=%d\n", typeid(*view).name(), view->getWindowOpenState()); } buf->append("\n"); @@ -51,7 +50,6 @@ namespace hex { this->initGLFW(); this->initImGui(); - this->initPlugins(); ImGui::GetStyle().Colors[ImGuiCol_DockingEmptyBg] = ImGui::GetStyle().Colors[ImGuiCol_WindowBg]; EventManager::subscribe(Events::SettingsChanged, this, [](auto) -> std::any { @@ -126,6 +124,8 @@ namespace hex { for (const auto &path : ContentRegistry::Settings::read("ImHex", "RecentFiles")) this->m_recentFiles.push_back(path); + + this->initPlugins(); } Window::~Window() { @@ -200,7 +200,6 @@ namespace hex { } void Window::frameBegin() { - printf("%s\n", static_cast("hello.world"_lang)); glfwPollEvents(); ImGui_ImplOpenGL3_NewFrame(); @@ -227,13 +226,15 @@ namespace hex { if (ImGui::BeginMenuBar()) { + auto MenuBarItems = { "hex.menu.file"_lang, "hex.menu.edit"_lang, "hex.menu.view"_lang, "hex.menu.help"_lang }; + for (auto menu : MenuBarItems) if (ImGui::BeginMenu(menu)) ImGui::EndMenu(); - if (ImGui::BeginMenu("View")) { + if (ImGui::BeginMenu("hex.menu.view"_lang)) { for (auto &view : ContentRegistry::Views::getEntries()) { if (view->hasViewMenuItemEntry()) - ImGui::MenuItem((std::string(view->getName()) + " View").c_str(), "", &view->getWindowOpenState()); + ImGui::MenuItem((std::string(view->getName()) + " " + "hex.menu.view"_lang).c_str(), "", &view->getWindowOpenState()); } ImGui::EndMenu(); } @@ -242,11 +243,11 @@ namespace hex { view->drawMenu(); } - if (ImGui::BeginMenu("View")) { + if (ImGui::BeginMenu("hex.menu.view"_lang)) { ImGui::Separator(); - ImGui::MenuItem("Display FPS", "", &this->m_fpsVisible); + ImGui::MenuItem("hex.menu.view.fps"_lang, "", &this->m_fpsVisible); #ifdef DEBUG - ImGui::MenuItem("Demo View", "", &this->m_demoWindowOpen); + ImGui::MenuItem("hex.menu.view.demo"_lang, "", &this->m_demoWindowOpen); #endif ImGui::EndMenu(); } @@ -314,7 +315,7 @@ namespace hex { } void Window::drawWelcomeScreen() { - ImGui::UnderlinedText("Welcome to ImHex!", ImGui::GetStyleColorVec4(ImGuiCol_HeaderActive)); + ImGui::UnderlinedText("hex.welcome.header.main"_lang, ImGui::GetStyleColorVec4(ImGuiCol_HeaderActive)); ImGui::NewLine(); @@ -324,16 +325,16 @@ namespace hex { if (ImGui::BeginTable("Welcome Left", 1, ImGuiTableFlags_NoBordersInBody, ImVec2(availableSpace.x / 2, availableSpace.y))) { ImGui::TableNextRow(ImGuiTableRowFlags_None, 100); ImGui::TableNextColumn(); - ImGui::Text("Start"); + ImGui::Text("hex.welcome.header.start"_lang); { - if (ImGui::BulletHyperlink("Open File")) + if (ImGui::BulletHyperlink("hex.welcome.start.open_file"_lang)) EventManager::post(Events::OpenWindow, "Open File"); - if (ImGui::BulletHyperlink("Open Project")) + if (ImGui::BulletHyperlink("hex.welcome.start.open_project"_lang)) EventManager::post(Events::OpenWindow, "Open Project"); } ImGui::TableNextRow(ImGuiTableRowFlags_None, 100); ImGui::TableNextColumn(); - ImGui::Text("Recent"); + ImGui::Text("hex.welcome.start.recent"_lang); { if (!this->m_recentFiles.empty()) { for (auto &path : this->m_recentFiles) { @@ -346,10 +347,10 @@ namespace hex { } ImGui::TableNextRow(ImGuiTableRowFlags_None, 100); ImGui::TableNextColumn(); - ImGui::Text("Help"); + ImGui::Text("hex.welcome.header.help"_lang); { - if (ImGui::BulletHyperlink("GitHub Repository")) hex::openWebpage("https://github.com/WerWolv/ImHex"); - if (ImGui::BulletHyperlink("Get help")) hex::openWebpage("https://github.com/WerWolv/ImHex/discussions/categories/get-help"); + if (ImGui::BulletHyperlink("hex.welcome.help.repo"_lang)) hex::openWebpage("hex.welcome.help.repo.link"_lang); + if (ImGui::BulletHyperlink("hex.welcome.help.gethelp"_lang)) hex::openWebpage("hex.welcome.help.gethelp.link"_lang); } ImGui::EndTable(); @@ -358,21 +359,21 @@ namespace hex { if (ImGui::BeginTable("Welcome Right", 1, ImGuiTableFlags_NoBordersInBody, ImVec2(availableSpace.x / 2, availableSpace.y))) { ImGui::TableNextRow(ImGuiTableRowFlags_None, 100); ImGui::TableNextColumn(); - ImGui::Text("Customize"); + ImGui::Text("hex.welcome.header.customize"_lang); { - if (ImGui::DescriptionButton("Settings", "Change preferences of ImHex", ImVec2(ImGui::GetContentRegionAvail().x * 0.8f, 0))) + if (ImGui::DescriptionButton("hex.welcome.customize.settings.title"_lang, "hex.welcome.customize.settings.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8f, 0))) EventManager::post(Events::OpenWindow, "Preferences"); } ImGui::TableNextRow(ImGuiTableRowFlags_None, 100); ImGui::TableNextColumn(); - ImGui::Text("Learn"); + ImGui::Text("hex.welcome.header.learn"_lang); { - if (ImGui::DescriptionButton("Latest Release", "Get the latest version of ImHex or read the current changelog", ImVec2(ImGui::GetContentRegionAvail().x * 0.8, 0))) - hex::openWebpage("https://github.com/WerWolv/ImHex/releases/latest"); - if (ImGui::DescriptionButton("Pattern Language Documentation", "Learn how to write ImHex patterns with our extensive documentation", ImVec2(ImGui::GetContentRegionAvail().x * 0.8, 0))) - hex::openWebpage("https://github.com/WerWolv/ImHex/wiki/Pattern-Language-Guide"); - if (ImGui::DescriptionButton("Plugins API", "Extend ImHex with additional features using plugins", ImVec2(ImGui::GetContentRegionAvail().x * 0.8, 0))) - hex::openWebpage("https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide"); + if (ImGui::DescriptionButton("hex.welcome.learn.latest.title"_lang, "hex.welcome.learn.latest.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8, 0))) + hex::openWebpage("hex.welcome.learn.latest.link"_lang); + if (ImGui::DescriptionButton("hex.welcome.learn.pattern.title"_lang, "hex.welcome.learn.pattern.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8, 0))) + hex::openWebpage("hex.welcome.learn.pattern.link"_lang); + if (ImGui::DescriptionButton("hex.welcome.learn.plugins.title"_lang, "hex.welcome.learn.plugins.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x * 0.8, 0))) + hex::openWebpage("hex.welcome.learn.plugins.link"_lang); } ImGui::EndTable();