feat: Added support for creating views and drawing ImGui elemts from C#
This commit is contained in:
parent
a3f550c585
commit
e3565d5bcb
@ -64,8 +64,15 @@ namespace ImHex
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.LoadFromStream(new MemoryStream(File.ReadAllBytes(file)));
|
try
|
||||||
|
{
|
||||||
|
context.LoadFromStream(new MemoryStream(File.ReadAllBytes(file)));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine("[.NET Script] Failed to load assembly: " + file + " - " + e.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the script assembly
|
// Load the script assembly
|
||||||
|
@ -7,7 +7,7 @@ function(add_dotnet_assembly name)
|
|||||||
file(GLOB_RECURSE sources ${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.cs)
|
file(GLOB_RECURSE sources ${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.cs)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../../${name}.dll
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/../../${name}.dll
|
||||||
COMMAND ${DOTNET_EXECUTABLE} build ${CMAKE_CURRENT_SOURCE_DIR}/${name}/${name}.csproj --nologo -c Release -o ${CMAKE_CURRENT_BINARY_DIR}/../.. && ${CMAKE_COMMAND} -DOUTPUT_RUNTIMECONFIG="\"${OUTPUT_RUNTIMECONFIG}\"" -P ${CMAKE_CURRENT_SOURCE_DIR}/post_process_runtimeconfig.cmake
|
COMMAND ${DOTNET_EXECUTABLE} build ${CMAKE_CURRENT_SOURCE_DIR}/${name}/${name}.csproj -nologo -consoleLoggerParameters:NoSummary -verbosity:quiet -c Release -o ${CMAKE_CURRENT_BINARY_DIR}/../.. && ${CMAKE_COMMAND} -DOUTPUT_RUNTIMECONFIG="\"${OUTPUT_RUNTIMECONFIG}\"" -P ${CMAKE_CURRENT_SOURCE_DIR}/post_process_runtimeconfig.cmake
|
||||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}/${name}.csproj ${sources}
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}/${name}.csproj ${sources}
|
||||||
COMMENT "Building ${name}.dll"
|
COMMENT "Building ${name}.dll"
|
||||||
)
|
)
|
||||||
|
@ -94,6 +94,7 @@ private:
|
|||||||
SCRIPT_API(void registerProvider, const char *typeName, const char *name, ScriptDataProvider::ReadFunction readFunc, ScriptDataProvider::WriteFunction writeFunc, ScriptDataProvider::GetSizeFunction getSizeFunc) {
|
SCRIPT_API(void registerProvider, const char *typeName, const char *name, ScriptDataProvider::ReadFunction readFunc, ScriptDataProvider::WriteFunction writeFunc, ScriptDataProvider::GetSizeFunction getSizeFunc) {
|
||||||
auto typeNameString = std::string(typeName);
|
auto typeNameString = std::string(typeName);
|
||||||
auto nameString = std::string(name);
|
auto nameString = std::string(name);
|
||||||
|
|
||||||
hex::ContentRegistry::Provider::impl::add(typeNameString, [typeNameString, nameString, readFunc, writeFunc, getSizeFunc] -> std::unique_ptr<hex::prv::Provider> {
|
hex::ContentRegistry::Provider::impl::add(typeNameString, [typeNameString, nameString, readFunc, writeFunc, getSizeFunc] -> std::unique_ptr<hex::prv::Provider> {
|
||||||
auto provider = std::make_unique<ScriptDataProvider>();
|
auto provider = std::make_unique<ScriptDataProvider>();
|
||||||
provider->setTypeName(typeNameString);
|
provider->setTypeName(typeNameString);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <script_api.hpp>
|
#include <script_api.hpp>
|
||||||
|
#include <hex/api/content_registry.hpp>
|
||||||
|
|
||||||
#include <hex/api/imhex_api.hpp>
|
#include <hex/api/imhex_api.hpp>
|
||||||
#include <hex/api/event_manager.hpp>
|
#include <hex/api/event_manager.hpp>
|
||||||
@ -7,8 +8,10 @@
|
|||||||
#include <hex/ui/popup.hpp>
|
#include <hex/ui/popup.hpp>
|
||||||
|
|
||||||
#include <hex/helpers/utils.hpp>
|
#include <hex/helpers/utils.hpp>
|
||||||
|
#include <hex/ui/view.hpp>
|
||||||
|
|
||||||
#include <popups/popup_notification.hpp>
|
#include <popups/popup_notification.hpp>
|
||||||
|
#include <toasts/toast_notification.hpp>
|
||||||
|
|
||||||
using namespace hex;
|
using namespace hex;
|
||||||
|
|
||||||
@ -140,4 +143,40 @@ SCRIPT_API(void showYesNoQuestionBox, const char *title, const char *message, bo
|
|||||||
|
|
||||||
*result = s_yesNoQuestionBoxResult.value();
|
*result = s_yesNoQuestionBoxResult.value();
|
||||||
s_yesNoQuestionBoxResult.reset();
|
s_yesNoQuestionBoxResult.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
SCRIPT_API(void showToast, const char *message, u32 type) {
|
||||||
|
switch (type) {
|
||||||
|
case 0:
|
||||||
|
ui::ToastInfo::open(message);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ui::ToastWarning::open(message);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ui::ToastError::open(message);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SCRIPT_API(void* getImGuiContext) {
|
||||||
|
return ImGui::GetCurrentContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ScriptView : public View::Window {
|
||||||
|
public:
|
||||||
|
using DrawFunction = void(*)();
|
||||||
|
ScriptView(const char *icon, const char *name, DrawFunction function) : View::Window(UnlocalizedString(name), icon), m_drawFunction(function) { }
|
||||||
|
void drawContent() override {
|
||||||
|
m_drawFunction();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
DrawFunction m_drawFunction;
|
||||||
|
};
|
||||||
|
|
||||||
|
SCRIPT_API(void registerView, const char *icon, const char *name, void *drawFunction) {
|
||||||
|
ContentRegistry::Views::add<ScriptView>(icon, name, ScriptView::DrawFunction(drawFunction));
|
||||||
}
|
}
|
@ -2,20 +2,18 @@
|
|||||||
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace ImHex
|
namespace ImHex
|
||||||
{
|
{
|
||||||
public class Bookmarks
|
public class Bookmarks
|
||||||
{
|
{
|
||||||
[DllImport(Library.Name)]
|
[DllImport(Library.Name)]
|
||||||
private static extern void createBookmarkV1(UInt64 address, UInt64 size, UInt32 color, [MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string description);
|
private static extern void createBookmarkV1(UInt64 address, UInt64 size, UInt32 color, byte[] name, byte[] description);
|
||||||
|
|
||||||
public static void CreateBookmark(long address, long size, Color color, string name = "", string description = "")
|
public static void CreateBookmark(long address, long size, Color color, string name = "", string description = "")
|
||||||
{
|
{
|
||||||
unsafe
|
createBookmarkV1((UInt64)address, (UInt64)size, (UInt32)(0xA0 << 24 | color.B << 16 | color.G << 8 | color.R), Encoding.UTF8.GetBytes(name), Encoding.UTF8.GetBytes(description));
|
||||||
{
|
|
||||||
createBookmarkV1((UInt64)address, (UInt64)size, (UInt32)(0xA0 << 24 | color.B << 16 | color.G << 8 | color.R), name, description);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace ImHex
|
namespace ImHex
|
||||||
{
|
{
|
||||||
@ -36,7 +37,7 @@ namespace ImHex
|
|||||||
public class Memory
|
public class Memory
|
||||||
{
|
{
|
||||||
private static List<IProvider> _registeredProviders = new();
|
private static List<IProvider> _registeredProviders = new();
|
||||||
private static List<Delegate> _registeredProviderDelegates = new();
|
private static List<Delegate> _registeredDelegates = new();
|
||||||
|
|
||||||
private delegate void DataAccessDelegate(UInt64 address, IntPtr buffer, UInt64 size);
|
private delegate void DataAccessDelegate(UInt64 address, IntPtr buffer, UInt64 size);
|
||||||
private delegate UInt64 GetSizeDelegate();
|
private delegate UInt64 GetSizeDelegate();
|
||||||
@ -51,7 +52,7 @@ namespace ImHex
|
|||||||
private static extern bool getSelectionV1(IntPtr start, IntPtr end);
|
private static extern bool getSelectionV1(IntPtr start, IntPtr end);
|
||||||
|
|
||||||
[DllImport(Library.Name)]
|
[DllImport(Library.Name)]
|
||||||
private static extern int registerProviderV1([MarshalAs(UnmanagedType.LPStr)] string typeName, [MarshalAs(UnmanagedType.LPStr)] string name, IntPtr readFunction, IntPtr writeFunction, IntPtr getSizeFunction);
|
private static extern void registerProviderV1(byte[] typeName, byte[] name, IntPtr readFunction, IntPtr writeFunction, IntPtr getSizeFunction);
|
||||||
|
|
||||||
|
|
||||||
public static byte[] Read(ulong address, ulong size)
|
public static byte[] Read(ulong address, ulong size)
|
||||||
@ -95,22 +96,22 @@ namespace ImHex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int RegisterProvider<T>() where T : IProvider, new()
|
public static void RegisterProvider<T>() where T : IProvider, new()
|
||||||
{
|
{
|
||||||
_registeredProviders.Add(new T());
|
_registeredProviders.Add(new T());
|
||||||
|
|
||||||
ref var provider = ref CollectionsMarshal.AsSpan(_registeredProviders)[^1];
|
ref var provider = ref CollectionsMarshal.AsSpan(_registeredProviders)[^1];
|
||||||
|
|
||||||
_registeredProviderDelegates.Add(new DataAccessDelegate(provider.readRaw));
|
_registeredDelegates.Add(new DataAccessDelegate(provider.readRaw));
|
||||||
_registeredProviderDelegates.Add(new DataAccessDelegate(provider.writeRaw));
|
_registeredDelegates.Add(new DataAccessDelegate(provider.writeRaw));
|
||||||
_registeredProviderDelegates.Add(new GetSizeDelegate(provider.getSize));
|
_registeredDelegates.Add(new GetSizeDelegate(provider.getSize));
|
||||||
|
|
||||||
return registerProviderV1(
|
registerProviderV1(
|
||||||
_registeredProviders[^1].getTypeName(),
|
Encoding.UTF8.GetBytes(provider.getTypeName()),
|
||||||
_registeredProviders[^1].getName(),
|
Encoding.UTF8.GetBytes(provider.getName()),
|
||||||
Marshal.GetFunctionPointerForDelegate(_registeredProviderDelegates[^3]),
|
Marshal.GetFunctionPointerForDelegate(_registeredDelegates[^3]),
|
||||||
Marshal.GetFunctionPointerForDelegate(_registeredProviderDelegates[^2]),
|
Marshal.GetFunctionPointerForDelegate(_registeredDelegates[^2]),
|
||||||
Marshal.GetFunctionPointerForDelegate(_registeredProviderDelegates[^1])
|
Marshal.GetFunctionPointerForDelegate(_registeredDelegates[^1])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#pragma warning disable SYSLIB1054
|
#pragma warning disable SYSLIB1054
|
||||||
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@ -8,21 +7,31 @@ namespace ImHex
|
|||||||
{
|
{
|
||||||
public class UI
|
public class UI
|
||||||
{
|
{
|
||||||
[DllImport(Library.Name)]
|
private delegate void DrawContentDelegate();
|
||||||
private static extern void showMessageBoxV1([MarshalAs(UnmanagedType.LPStr)] string message);
|
|
||||||
|
private static List<Delegate> _registeredDelegates = new();
|
||||||
|
|
||||||
[DllImport(Library.Name)]
|
[DllImport(Library.Name)]
|
||||||
private static extern void showInputTextBoxV1([MarshalAs(UnmanagedType.LPStr)] string title, [MarshalAs(UnmanagedType.LPStr)] string message, StringBuilder buffer, int bufferSize);
|
private static extern void showMessageBoxV1(byte[] message);
|
||||||
|
|
||||||
[DllImport(Library.Name)]
|
[DllImport(Library.Name)]
|
||||||
private static extern unsafe void showYesNoQuestionBoxV1([MarshalAs(UnmanagedType.LPStr)] string title, [MarshalAs(UnmanagedType.LPStr)] string message, bool* result);
|
private static extern void showInputTextBoxV1(byte[] title, byte[] message, StringBuilder buffer, int bufferSize);
|
||||||
|
|
||||||
|
[DllImport(Library.Name)]
|
||||||
|
private static extern unsafe void showYesNoQuestionBoxV1(byte[] title, byte[] message, bool* result);
|
||||||
|
|
||||||
|
[DllImport(Library.Name)]
|
||||||
|
private static extern void showToastV1(byte[] message, UInt32 type);
|
||||||
|
|
||||||
|
[DllImport(Library.Name)]
|
||||||
|
private static extern IntPtr getImGuiContextV1();
|
||||||
|
|
||||||
|
[DllImport(Library.Name)]
|
||||||
|
private static extern void registerViewV1(byte[] icon, byte[] name, IntPtr drawFunction);
|
||||||
|
|
||||||
public static void ShowMessageBox(string message)
|
public static void ShowMessageBox(string message)
|
||||||
{
|
{
|
||||||
unsafe
|
showMessageBoxV1(Encoding.UTF8.GetBytes(message));
|
||||||
{
|
|
||||||
showMessageBoxV1(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ShowYesNoQuestionBox(string title, string message)
|
public static bool ShowYesNoQuestionBox(string title, string message)
|
||||||
@ -30,23 +39,47 @@ namespace ImHex
|
|||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
showYesNoQuestionBoxV1(title, message, &result);
|
showYesNoQuestionBoxV1(Encoding.UTF8.GetBytes(title), Encoding.UTF8.GetBytes(message), &result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string? ShowInputTextBox(string title, string message, int maxSize)
|
public static string? ShowInputTextBox(string title, string message, int maxSize)
|
||||||
{
|
{
|
||||||
unsafe
|
StringBuilder buffer = new(maxSize);
|
||||||
{
|
showInputTextBoxV1(Encoding.UTF8.GetBytes(title), Encoding.UTF8.GetBytes(message), buffer, buffer.Capacity);
|
||||||
StringBuilder buffer = new(maxSize);
|
|
||||||
showInputTextBoxV1(title, message, buffer, buffer.Capacity);
|
|
||||||
|
|
||||||
if (buffer.Length == 0 || buffer[0] == '\x00')
|
if (buffer.Length == 0 || buffer[0] == '\x00')
|
||||||
return null;
|
return null;
|
||||||
else
|
else
|
||||||
return buffer.ToString();
|
return buffer.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ToastType
|
||||||
|
{
|
||||||
|
Info = 0,
|
||||||
|
Warning = 1,
|
||||||
|
Error = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowToast(string message, ToastType type = ToastType.Info)
|
||||||
|
{
|
||||||
|
showToastV1(Encoding.UTF8.GetBytes(message), (UInt32)type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IntPtr GetImGuiContext()
|
||||||
|
{
|
||||||
|
return getImGuiContextV1();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RegisterView(byte[] icon, string name, Action function)
|
||||||
|
{
|
||||||
|
_registeredDelegates.Add(new DrawContentDelegate(function));
|
||||||
|
registerViewV1(
|
||||||
|
icon,
|
||||||
|
Encoding.UTF8.GetBytes(name),
|
||||||
|
Marshal.GetFunctionPointerForDelegate(_registeredDelegates[^1])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,12 @@
|
|||||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="ImGui.NET" Version="1.89.7.1" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\ImHexLibrary\ImHexLibrary.csproj" />
|
<ProjectReference Include="..\ImHexLibrary\ImHexLibrary.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="ImGui.NET" Version="1.90.1.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
Loading…
Reference in New Issue
Block a user