├── README.md ├── cpp ├── Anim.cpp ├── Anim.h ├── base_engine.cpp ├── base_engine.h ├── cpp.hint ├── dllmain.cpp ├── framework.h ├── imconfig.h ├── imgui.cpp ├── imgui.h ├── imgui.ini ├── imgui_demo.cpp ├── imgui_dll.cpp ├── imgui_dll.h ├── imgui_dll.vcxproj ├── imgui_dll.vcxproj.filters ├── imgui_dll.vcxproj.user ├── imgui_draw.cpp ├── imgui_impl_dx11.cpp ├── imgui_impl_dx11.h ├── imgui_impl_win32.cpp ├── imgui_impl_win32.h ├── imgui_internal.h ├── imgui_widgets.cpp ├── imstb_rectpack.h ├── imstb_textedit.h ├── imstb_truetype.h ├── pch.cpp ├── pch.h └── test ├── dll_64 └── imgui.dll ├── example └── viewport_hide_main_window.au3 ├── imgui-au3-example.au3 ├── imgui.au3 ├── imgui.dll └── tools ├── README.md └── imgui-au3-setup.au3 /README.md: -------------------------------------------------------------------------------- 1 | # imgui-autoit 2 | 3 | ### Introduction 4 | - ImGui is an open source library that make fancy User Interfaces running on DirectX or OpenGL, you can check it [here](https://github.com/ocornut/imgui) 5 | - The hardest part I thought when I started writing this is: How am I gonna make it FAST? Because AutoIt is... you know, slow. 6 | - When i finally put the code to work, suprisingly, i got it runs at max fps, you can create thousands of items and it's still fine. 7 | - So I decided to convert the whole ImGui library to AutoIt, function by function. 8 | 9 | ### Requirements 10 | - This library requires you to have [DirectX](https://www.microsoft.com/en-us/download/confirmation.aspx?id=35) installed. 11 | 12 | ### Features 13 | - Has more than +270 functions converted from ImGui (compiled dll). 14 | - Has 90% of the capability of what you can do in C++. 15 | - Usable ImGuiIO and ImGuiStyle as a struct. 16 | 17 | ### Preview 18 | 19 | 20 | 21 | ### Usage 22 | ```autoit 23 | #include 24 | #include "ImGui.au3" 25 | 26 | ; Create a window 27 | Local $hwnd = _ImGui_GUICreate("AutoIt ImGui", 1024, 768) 28 | _WinAPI_ShowWindow($hwnd) 29 | 30 | ; Set style color 31 | _ImGui_StyleColorsLight() 32 | ;~ _ImGui_StyleColorsDark() 33 | 34 | Local $f_value = 5 35 | While 1 36 | 37 | ; when the user click close button on the window, this will return false 38 | if Not _ImGui_PeekMsg() Then Exit 39 | 40 | ; must call 41 | _ImGui_BeginFrame() 42 | 43 | _ImGui_Begin("Another window") 44 | 45 | _ImGui_Text("Hello there..") 46 | 47 | If _ImGui_Button("click me") Then $f_value = 5 48 | 49 | _ImGui_SliderFloat("slider", $f_value, 2, 20) 50 | If _ImGui_IsItemHovered() Then _ImGui_ToolTip("what r u doing?") 51 | 52 | _ImGui_End() 53 | 54 | ; must call 55 | _ImGui_EndFrame() 56 | Wend 57 | 58 | ``` 59 | 60 | ### Donation 61 | This project is under development, it still has a lot of features being developed, it's a very big help of your donation to keep the project running, please contact me anytime you feel like it!
62 | Discord: [thedemons#8671](https://discord.com/users/269920976236576769) 63 | -------------------------------------------------------------------------------- /cpp/Anim.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef ANIM_LIB_H 3 | #define ANIM_LIB_H 4 | 5 | #define NDEBUG 6 | #pragma once 7 | #include 8 | #include 9 | #include 10 | 11 | #include "imgui.h" 12 | #include "imgui_impl_dx11.h" 13 | #include "imgui_impl_win32.h" 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #pragma comment(lib, "urlmon.lib") 23 | #pragma comment(lib,"d3d11.lib") 24 | #pragma comment(lib,"d3dx11.lib") 25 | 26 | typedef DWORD D3DCOLOR; 27 | typedef void (*PageDrawFunction) (int&); 28 | 29 | struct THREAD_DOWNLOAD_PARAM { 30 | char url[1024*10]; 31 | ImTextureID* image; 32 | int seed; 33 | }; 34 | 35 | 36 | struct BEGIN_ANIM_PARAM { 37 | float (*fx_func)(float start, float end, float perc); 38 | float destination; 39 | float anim_duration; 40 | bool loop; 41 | bool reverse; 42 | float delay; 43 | }; 44 | 45 | class Anim 46 | { 47 | 48 | private: 49 | 50 | float start; 51 | float dest; 52 | float duration; 53 | bool reversing; 54 | bool allow_user_reverse; 55 | bool reset_after_loop; 56 | bool gonna_reverse; 57 | bool gonna_loop; 58 | clock_t reverse_from; 59 | clock_t time_started; 60 | clock_t last_finish; 61 | float anim_diff; 62 | float pause_afteranim_duration; 63 | float (*calfx)(float start, float end, float perc); 64 | 65 | 66 | std::vector waiting_list; 67 | 68 | public: 69 | float value; 70 | 71 | 72 | Anim(); 73 | 74 | float get(); 75 | 76 | void begin_animation(float (*fx_func)(float start, float end, float perc), 77 | float destination, float anim_duration, bool loop, bool reverse, float delay); 78 | void end_animation(); 79 | void stop_loop(bool wait_reverse = true); 80 | 81 | bool isintask(); 82 | void reverse(); 83 | void setpause_afteranim(float pause_time); 84 | void setresetvalue_afterloop(bool reset); 85 | void linear(float destination, float anim_duration, bool loop = false, bool reverse = false, float delay = 0.f); 86 | void bounce_back(float destination, float anim_duration, bool loop = false, bool reverse = false, float delay = 0.f); 87 | void smooth(float destination, float anim_duration, bool loop = false, bool reverse = false, float delay = 0.f); 88 | void accelerate(float destination, float anim_duration, bool loop = false, bool reverse = false, float delay = 0.f); 89 | void sinking(float destination, float anim_duration, bool loop = false, bool reverse = false, float delay = 0.f); 90 | 91 | }; 92 | 93 | 94 | ImTextureID DownloadImage(std::string url); 95 | void set_d3d_device(ID3D11Device* d3d11_device); 96 | 97 | 98 | 99 | namespace perlin { 100 | extern int numX; 101 | extern int numY; 102 | extern int numOctaves; 103 | extern double persistence ; 104 | 105 | extern int primeIndex; 106 | 107 | extern int primes[10][3]; 108 | 109 | double Noise(int i, int x, int y); 110 | double SmoothedNoise(int i, int x, int y); 111 | double Interpolate(double a, double b, double x); 112 | double InterpolatedNoise(int i, double x, double y); 113 | double ValueNoise_2D(double x, double y); 114 | } 115 | 116 | 117 | 118 | namespace ukit { 119 | 120 | 121 | struct element_anim { 122 | Anim box; 123 | Anim color; 124 | Anim anim_0; 125 | Anim anim_1; 126 | Anim anim_2; 127 | Anim* anims; 128 | D3DCOLOR temp_color; 129 | }; 130 | struct element_properties { 131 | element_anim ele_anim; 132 | bool MouseClicked[5]; 133 | bool MouseDown[5]; 134 | bool MouseReleased[5]; 135 | bool mouse_hovered; 136 | bool mouse_left; 137 | bool clicked; 138 | bool isHovering; 139 | float fvalue; 140 | int ivalue; 141 | int ivalue_1; 142 | int ivalue_2; 143 | bool bvalue; 144 | bool bvalue_1; 145 | 146 | std::vector ivalues; 147 | }; 148 | 149 | void refresh(); 150 | ImVec2 CalculateImgFit(ImVec2 size, ImVec2 fit, bool clipping, ImVec2* offset = 0, ImVec2* uv_min = 0, ImVec2* uv_max = 0); 151 | ImVec2 GetImageDimension(ImTextureID image); 152 | ImVec2 DrawImageFit(ImDrawList* drwl, ImTextureID image, ImVec2 pos, ImVec2 size, bool clipping = true, bool clipping_centered = true, float rounding = 0.f, ImU32 tint_col = 0xFFFFFFFF, ImDrawCornerFlags rounding_corners = 0); 153 | D3DCOLOR ColorGradient(D3DCOLOR c1, D3DCOLOR c2, float trans, bool abgr2argb = true); 154 | float ColorBrightness(D3DCOLOR color); 155 | D3DCOLOR ColorDim(D3DCOLOR color, float dim); 156 | D3DCOLOR ABGR2ARGB(D3DCOLOR color); 157 | 158 | element_properties* GetLastItemProperties(); 159 | bool IsLastItemHovering(); 160 | bool IsLastItemMouseHovered(); 161 | bool IsLastItemMouseLeft(); 162 | bool IsLastItemClicked(); 163 | 164 | void KeepAlive(const char* text_id); 165 | bool AddButton(ImDrawList* drwl, const char* text, float text_size, ImVec2 pos, 166 | ImVec2 size, D3DCOLOR background, D3DCOLOR text_color, float rounding = 0.f); 167 | 168 | bool AddOptions(ImDrawList* drwl, const char* text, const char** options, int count, int*selected, ImVec2 pos, 169 | ImVec2 size, D3DCOLOR background, D3DCOLOR background_hover, D3DCOLOR text_color, D3DCOLOR text_color_hover, float rounding = 0.f, D3DCOLOR outline = 0, D3DCOLOR outline_hover = 0); 170 | 171 | bool AddMagicButton(ImDrawList* drwl, const char* text, float text_size, float shake, ImVec2 pos, 172 | ImVec2 size, D3DCOLOR background, D3DCOLOR text_color, D3DCOLOR outline = 0); 173 | 174 | bool AddMagicButtonRound(ImDrawList* drwl, const char* text, float text_size, float shake, ImVec2 center, 175 | float radius, D3DCOLOR background, D3DCOLOR text_color, D3DCOLOR outline = 0); 176 | 177 | void AddLoadingRoundMatrix(ImDrawList* drwl, const char *text_id, 178 | ImVec2 center, float radius, float thickness, D3DCOLOR color); 179 | void AddProgressRound(ImDrawList* drwl, const char *text_id, 180 | ImVec2 center, float radius, float progress, D3DCOLOR color = ukit::ABGR2ARGB(0xFF00bb6e), float anim_delay=1000.f); 181 | void DrawMSCheatLogo(ImDrawList* drwl, ImVec2 center, float radius, float thickness, D3DCOLOR color, float fill_color = 0.f, D3DCOLOR logo_color = 0); 182 | bool AddCheckMark(ImDrawList* drwl, const char* text_id, bool is_active, 183 | ImVec2 center, float radius, D3DCOLOR color, float thickness, float anim_time=500.f); 184 | 185 | void AddSpinningBalls(ImDrawList* drwl, const char* text_id, 186 | ImVec2 center, int count, float radius, float width, D3DCOLOR color, float duration); 187 | 188 | void DrawPages(const char* text_id, ImVec2 size, PageDrawFunction* pages_draw_functions, int pages_count, int& current_page, bool vertical=false); 189 | } 190 | 191 | 192 | #endif 193 | 194 | 195 | -------------------------------------------------------------------------------- /cpp/base_engine.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "base_engine.h" 4 | 5 | bool msg_closed = false; 6 | ID3D11Device* g_pd3dDevice = NULL; 7 | ID3D11DeviceContext* g_pd3dDeviceContext = NULL; 8 | IDXGISwapChain* g_pSwapChain = NULL; 9 | ID3D11RenderTargetView* g_mainRenderTargetView = NULL; 10 | HWND main_hwnd = NULL; 11 | WNDCLASSEX main_hwnd_wc; 12 | // Helper functions 13 | 14 | void ImGuiSetStyle() 15 | { 16 | //static ImGuiStyle* style = &ImGui::GetStyle(); 17 | //ImVec4* colors = style->Colors; 18 | 19 | //colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1); 20 | //colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1); 21 | //colors[ImGuiCol_WindowBg] = ImVec4(0.1f, 0.1f, 0.1f, 1.f); 22 | //colors[ImGuiCol_ChildWindowBg] = ImVec4(0.1f, 0.1f, 0.1f, 1); 23 | 24 | //colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); 25 | //colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 1); 26 | 27 | //colors[ImGuiCol_Border] = ImVec4(0.3, 0.3, 0.3, 1); 28 | //colors[ImGuiCol_BorderShadow] = ImVec4(1, 1, 1, 1); 29 | 30 | //colors[ImGuiCol_FrameBg] = ImVec4(0xFF2b2b2b); 31 | //colors[ImGuiCol_FrameBgHovered] = ImVec4(0xFF3b3b3b); 32 | //colors[ImGuiCol_FrameBgActive] = ImVec4(0xFF3f3f3f); 33 | 34 | //colors[ImGuiCol_TitleBg] = ImVec4(0.1f, 0.1f, 0.1f, 1.00f); 35 | //colors[ImGuiCol_TitleBgActive] = ImVec4(0.04f, 0.04f, 0.04f, 1); 36 | //colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 1); 37 | 38 | //colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1); 39 | //colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 1); 40 | //colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.31f, 0.31f, 0.31f, 1); 41 | //colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.41f, 0.41f, 0.41f, 1); 42 | //colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.51f, 0.51f, 0.51f, 1); 43 | //colors[ImGuiCol_CheckMark] = ImVec4(0xFF00AA5e); 44 | ////colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); 45 | //colors[ImGuiCol_SliderGrab] = ImVec4(0.f, 0.53f, 0.33f, 1); 46 | //colors[ImGuiCol_SliderGrabActive] = ImVec4(0.f, 0.73f, 0.43f, 1); 47 | 48 | //colors[ImGuiCol_Button] = ImVec4(0xFF00AA5e); 49 | //colors[ImGuiCol_ButtonHovered] = ImVec4(0XFF00c76e); 50 | //colors[ImGuiCol_ButtonActive] = ImVec4(0xFf009150); 51 | 52 | //colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 1); 53 | //colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1); 54 | //colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1); 55 | //colors[ImGuiCol_Separator] = colors[ImGuiCol_Border]; 56 | //colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 1); 57 | //colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1); 58 | //colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 1); 59 | //colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1); 60 | //colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 1); 61 | //colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 1); 62 | //colors[ImGuiCol_TabHovered] = ImVec4(0.f, 0.73f, 0.43f, 1); 63 | ////colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered]; 64 | //colors[ImGuiCol_TabActive] = ImVec4(0.f, 0.73f, 0.43f, 1.00f); 65 | ////colors[ImGuiCol_TabActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); 66 | ////colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f); 67 | //colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 1); 68 | //colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 1); 69 | //colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); 70 | //colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); 71 | //colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); 72 | //colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); 73 | //colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); 74 | //colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); 75 | //colors[ImGuiCol_NavHighlight] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); 76 | //colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 1); 77 | //colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 1); 78 | //colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 1); 79 | } 80 | // Helper functions 81 | 82 | bool CreateDeviceD3D(HWND hWnd) 83 | { 84 | // Setup swap chain 85 | DXGI_SWAP_CHAIN_DESC sd; 86 | ZeroMemory(&sd, sizeof(sd)); 87 | sd.BufferCount = 2; 88 | sd.BufferDesc.Width = 0; 89 | sd.BufferDesc.Height = 0; 90 | sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 91 | sd.BufferDesc.RefreshRate.Numerator = 60; 92 | sd.BufferDesc.RefreshRate.Denominator = 1; 93 | sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; 94 | sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 95 | sd.OutputWindow = hWnd; 96 | sd.SampleDesc.Count = 1; 97 | sd.SampleDesc.Quality = 0; 98 | sd.Windowed = TRUE; 99 | sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; 100 | 101 | UINT createDeviceFlags = 0; 102 | //createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; 103 | D3D_FEATURE_LEVEL featureLevel; 104 | const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, }; 105 | if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK) 106 | return false; 107 | 108 | set_d3d_device(g_pd3dDevice); 109 | CreateRenderTarget(); 110 | return true; 111 | } 112 | 113 | void CleanupDeviceD3D() 114 | { 115 | CleanupRenderTarget(); 116 | if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = NULL; } 117 | if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = NULL; } 118 | if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } 119 | } 120 | 121 | void CreateRenderTarget() 122 | { 123 | ID3D11Texture2D* pBackBuffer; 124 | g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); 125 | g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_mainRenderTargetView); 126 | pBackBuffer->Release(); 127 | } 128 | 129 | void CleanupRenderTarget() 130 | { 131 | if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = NULL; } 132 | } 133 | 134 | #ifndef WM_DPICHANGED 135 | #define WM_DPICHANGED 0x02E0 // From Windows SDK 8.1+ headers 136 | #endif 137 | 138 | // Win32 message handler 139 | extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 140 | LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 141 | { 142 | if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) 143 | return true; 144 | 145 | switch (msg) 146 | { 147 | case WM_SIZE: 148 | if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED) 149 | { 150 | CleanupRenderTarget(); 151 | g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, 0); 152 | CreateRenderTarget(); 153 | } 154 | return 0; 155 | case WM_SYSCOMMAND: 156 | if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu 157 | return 0; 158 | break; 159 | case WM_CLOSE: 160 | msg_closed = true; 161 | return 0; 162 | case WM_DESTROY: 163 | ::PostQuitMessage(0); 164 | return 0; 165 | case WM_CHAR: 166 | //printf("%c\n", wParam); 167 | break; 168 | case WM_KEYUP: 169 | //printf("%c\n", wParam); 170 | break; 171 | //if (wParam == 8) printf("fuck\n"); 172 | //break; 173 | case WM_DPICHANGED: 174 | if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_DpiEnableScaleViewports) 175 | { 176 | //const int dpi = HIWORD(wParam); 177 | //printf("WM_DPICHANGED to %d (%.0f%%)\n", dpi, (float)dpi / 96.0f * 100.0f); 178 | const RECT* suggested_rect = (RECT*)lParam; 179 | ::SetWindowPos(hWnd, NULL, suggested_rect->left, suggested_rect->top, suggested_rect->right - suggested_rect->left, suggested_rect->bottom - suggested_rect->top, SWP_NOZORDER | SWP_NOACTIVATE); 180 | } 181 | break; 182 | } 183 | return ::DefWindowProc(hWnd, msg, wParam, lParam); 184 | } 185 | 186 | -------------------------------------------------------------------------------- /cpp/base_engine.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef BASE_ENGINE_H 4 | #define BASE_ENGINE_H 5 | #pragma-once 6 | #include "pch.h" 7 | 8 | static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); } 9 | // Data 10 | extern bool msg_closed; 11 | extern HWND main_hwnd; 12 | extern WNDCLASSEX main_hwnd_wc; 13 | extern ID3D11Device* g_pd3dDevice; 14 | extern ID3D11DeviceContext* g_pd3dDeviceContext; 15 | extern IDXGISwapChain* g_pSwapChain; 16 | extern ID3D11RenderTargetView* g_mainRenderTargetView; 17 | 18 | void ImGuiSetStyle(); 19 | 20 | // Forward declarations of helper functions 21 | bool CreateDeviceD3D(HWND hWnd); 22 | void CleanupDeviceD3D(); 23 | void CreateRenderTarget(); 24 | void CleanupRenderTarget(); 25 | LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 26 | 27 | 28 | #endif // ! BASE_ENGINE_H 29 | -------------------------------------------------------------------------------- /cpp/cpp.hint: -------------------------------------------------------------------------------- 1 | #define IMGUIDLL_API __declspec(dllexport) 2 | #define IMGUIDLL_API __declspec(dllimport) 3 | -------------------------------------------------------------------------------- /cpp/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : Defines the entry point for the DLL application. 2 | #include "pch.h" 3 | 4 | #include 5 | #include 6 | 7 | 8 | BOOL APIENTRY DllMain(HMODULE hModule, 9 | DWORD ul_reason_for_call, 10 | LPVOID lpReserved 11 | ) 12 | { 13 | 14 | switch (ul_reason_for_call) 15 | { 16 | case DLL_PROCESS_ATTACH: { 17 | } 18 | case DLL_THREAD_ATTACH: 19 | case DLL_THREAD_DETACH: 20 | case DLL_PROCESS_DETACH: 21 | break; 22 | } 23 | return TRUE; 24 | } 25 | 26 | 27 | bool bEnableViewPort = false; 28 | 29 | ImU32 ARGB2ABGR(ImU32 color) { 30 | ImU32 result = color; 31 | *(BYTE*)((char*)&result) = ((color >> 16) & 0xff); 32 | *(BYTE*)((char*)&result + 2) = ((color) & 0xff); 33 | return result; 34 | } 35 | ImVec4 GetVec4Color(ImU32 color) { 36 | return ImGui::ColorConvertU32ToFloat4(ARGB2ABGR(color)); 37 | } 38 | 39 | std::string wstr_utf8(const std::wstring& str) 40 | { 41 | std::wstring_convert> myconv; 42 | return myconv.to_bytes(str); 43 | } 44 | std::wstring utf8_wstr(const std::string& str) 45 | { 46 | std::wstring_convert> myconv; 47 | return myconv.from_bytes(str); 48 | } 49 | 50 | 51 | 52 | EXTERN_DLL_EXPORT void EnableViewports(bool enable) { 53 | bEnableViewPort = enable; 54 | } 55 | 56 | EXTERN_DLL_EXPORT HWND GUICreate(wchar_t* title, int w, int h, int x, int y) { 57 | 58 | if (x == -1 || y == -1) { 59 | RECT rc; 60 | GetWindowRect(GetDesktopWindow(), &rc); 61 | if (x == -1) x = int(rc.right / 2 - w / 2); 62 | if (y == -1) y = int(rc.bottom / 2 - h / 2); 63 | } 64 | 65 | main_hwnd_wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL }; 66 | ::RegisterClassEx(&main_hwnd_wc); 67 | main_hwnd = ::CreateWindow(main_hwnd_wc.lpszClassName, title, WS_OVERLAPPEDWINDOW, x, y, w, h, NULL, NULL, main_hwnd_wc.hInstance, NULL); 68 | 69 | 70 | 71 | 72 | // Initialize Direct3D 73 | if (!CreateDeviceD3D(main_hwnd)) 74 | { 75 | CleanupDeviceD3D(); 76 | ::UnregisterClass(main_hwnd_wc.lpszClassName, main_hwnd_wc.hInstance); 77 | return 0; 78 | } 79 | \ 80 | ImGui::CreateContext(); 81 | ImGuiIO& io = ImGui::GetIO(); (void)io; 82 | 83 | //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls 84 | //io.ConfigFlags |= ImGuiConfigFlags_NavNoCaptureKeyboard; // Enable Keyboard Controls 85 | 86 | if (bEnableViewPort) io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; 87 | //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls 88 | 89 | //io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking 90 | //io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows 91 | 92 | //io.ConfigViewportsNoAutoMerge = true; 93 | //io.ConfigViewportsNoTaskBarIcon = true; 94 | //io.ConfigViewportsNoDefaultParent = true; 95 | //io.ConfigDockingAlwaysTabBar = true; 96 | //io.ConfigDockingTransparentPayload = true; 97 | //io.ConfigFlags |= ImGuiConfigFlags_DpiEnableScaleFonts; // FIXME-DPI: THIS CURRENTLY DOESN'T WORK AS EXPECTED. DON'T USE IN USER APP! 98 | //io.ConfigFlags |= ImGuiConfigFlags_DpiEnableScaleViewports; // FIXME-DPI 99 | 100 | //auto pStyle = &ImGui::GetStyle(); 101 | //pStyle->WindowTitleAlign = ImVec2(0.5f, 0.5f); 102 | //if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 103 | //{ 104 | // pStyle->WindowRounding = 0.0f; 105 | //} 106 | 107 | //pStyle->Colors[ImGuiCol_WindowBg].w = 1.0f; 108 | auto fontAtlas = ImGui::GetIO().Fonts; 109 | fontAtlas->ClearFonts(); 110 | 111 | auto glyphRange = fontAtlas->GetGlyphRangesVietnamese(); 112 | fontAtlas->AddFontFromFileTTF("C:\\Windows\\Fonts\\calibri.ttf", 15.5f, 0, glyphRange); 113 | 114 | //ImGuiSetStyle(); 115 | ImGui::StyleColorsDark(); 116 | 117 | ImGui_ImplWin32_Init(main_hwnd); 118 | ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext); 119 | return main_hwnd; 120 | 121 | } 122 | EXTERN_DLL_EXPORT bool PeekMsg() { 123 | 124 | static MSG msg; 125 | ZeroMemory(&msg, sizeof(msg)); 126 | if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) 127 | { 128 | ::TranslateMessage(&msg); 129 | ::DispatchMessage(&msg); 130 | } 131 | bool is_closed = msg_closed; 132 | msg_closed = false; 133 | return !is_closed; 134 | } 135 | EXTERN_DLL_EXPORT void BeginFrame() { 136 | 137 | ImGui_ImplDX11_NewFrame(); 138 | ImGui_ImplWin32_NewFrame(); 139 | ImGui::NewFrame(); 140 | } 141 | EXTERN_DLL_EXPORT void EndFrame(ImU32 clear_color) { 142 | 143 | ImVec4 col = GetVec4Color(clear_color); 144 | ImGui::Render(); 145 | g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); 146 | g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, (float*)&col); 147 | 148 | 149 | ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); 150 | 151 | 152 | if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 153 | { 154 | ImGui::UpdatePlatformWindows(); 155 | ImGui::RenderPlatformWindowsDefault(); 156 | } 157 | 158 | 159 | 160 | g_pSwapChain->Present(1, 0); // Present with vsync 161 | //g_pSwapChain->Present(0, 0); // Present without vsync 162 | } 163 | EXTERN_DLL_EXPORT void ShutDown() { 164 | 165 | 166 | // Cleanup 167 | ImGui_ImplDX11_Shutdown(); 168 | ImGui_ImplWin32_Shutdown(); 169 | ImGui::DestroyContext(); 170 | 171 | CleanupDeviceD3D(); 172 | ::DestroyWindow(main_hwnd); 173 | ::UnregisterClass(main_hwnd_wc.lpszClassName, main_hwnd_wc.hInstance); 174 | 175 | } 176 | 177 | EXTERN_DLL_EXPORT void Begin(const wchar_t* name, bool* open, int flags) { 178 | ImGui::Begin(wstr_utf8(name).c_str(), open, flags); 179 | } 180 | 181 | EXTERN_DLL_EXPORT void Text(const wchar_t* text) { 182 | ImGui::TextUnformatted(wstr_utf8(text).c_str()); 183 | } 184 | 185 | EXTERN_DLL_EXPORT void SameLine(float offset_from_start_x, float spacing) { 186 | ImGui::SameLine(offset_from_start_x, spacing); 187 | } 188 | 189 | EXTERN_DLL_EXPORT bool Button(const wchar_t* text, float w, float h) { 190 | return ImGui::Button(wstr_utf8(text).c_str(), { w, h }); 191 | } 192 | 193 | EXTERN_DLL_EXPORT bool Checkbox(const wchar_t* text, bool* v) { 194 | return ImGui::Checkbox(wstr_utf8(text).c_str(), v); 195 | } 196 | 197 | EXTERN_DLL_EXPORT bool SliderFloat(const wchar_t* text, float *v, float v_min, float v_max, const wchar_t* format, float power) { 198 | return ImGui::SliderFloat(wstr_utf8(text).c_str(), v, v_min, v_max, wstr_utf8(format).c_str(), power); 199 | } 200 | 201 | EXTERN_DLL_EXPORT bool InputText(const wchar_t* label, wchar_t* buf, int buf_size, int flags, ImGuiInputTextCallback callback, void* user_data) { 202 | std::string str = wstr_utf8(buf); 203 | char *buffer = new char[buf_size+1]; 204 | ZeroMemory(buffer, buf_size + 1); 205 | 206 | memcpy(buffer, str.c_str(), str.length()); 207 | 208 | bool result = ImGui::InputText(wstr_utf8(label).c_str(), buffer, buf_size, flags, callback, user_data); 209 | 210 | std::wstring new_str = utf8_wstr(buffer); 211 | memcpy(buf, new_str.c_str(), new_str.length()*2 + 1); 212 | delete[] buffer; 213 | return result; 214 | 215 | } 216 | EXTERN_DLL_EXPORT bool InputTextMultiline(const wchar_t* label, wchar_t* buf, size_t buf_size, float size_x, float size_y, ImGuiInputTextFlags flags, void* callback, void* user_data) { 217 | std::string str = wstr_utf8(buf); 218 | char* buffer = new char[buf_size + 1]; 219 | ZeroMemory(buffer, buf_size + 1); 220 | 221 | memcpy(buffer, str.c_str(), str.length()); 222 | 223 | bool result = ImGui::InputTextMultiline(wstr_utf8(label).c_str(), buffer, buf_size, { size_x, size_y }, flags, (ImGuiInputTextCallback)callback, user_data); 224 | std::wstring new_str = utf8_wstr(buffer); 225 | memcpy(buf, new_str.c_str(), new_str.length() * 2 + 1); 226 | delete[] buffer; 227 | 228 | return result; 229 | } 230 | 231 | 232 | EXTERN_DLL_EXPORT bool InputTextWithHint(const wchar_t* label, const wchar_t* hint, wchar_t* buf, size_t buf_size, ImGuiInputTextFlags flags) { 233 | std::string str = wstr_utf8(buf); 234 | char* buffer = new char[buf_size + 1]; 235 | ZeroMemory(buffer, buf_size + 1); 236 | 237 | memcpy(buffer, str.c_str(), str.length()); 238 | 239 | bool result = ImGui::InputTextWithHint(wstr_utf8(label).c_str(), wstr_utf8(hint).c_str(), buffer, buf_size, flags); 240 | std::wstring new_str = utf8_wstr(buffer); 241 | memcpy(buf, new_str.c_str(), new_str.length() * 2 + 1); 242 | delete[] buffer; 243 | 244 | return result; 245 | } 246 | 247 | EXTERN_DLL_EXPORT bool BeginChild(const wchar_t* text, float w, float h, bool border, int flags) { 248 | return ImGui::BeginChild(wstr_utf8(text).c_str(), { w, h }, border, flags); 249 | } 250 | 251 | EXTERN_DLL_EXPORT void EndChild() { 252 | return ImGui::EndChild(); 253 | } 254 | 255 | EXTERN_DLL_EXPORT void End() { 256 | ImGui::End(); 257 | } 258 | 259 | EXTERN_DLL_EXPORT void ShowDemoWindow() { 260 | 261 | ImGui::ShowDemoWindow(); 262 | } 263 | EXTERN_DLL_EXPORT void DrawTest() { 264 | 265 | //printf("%d\n", ImGui::GetIO().KeyMap[ImGuiKey_Backspace]); 266 | static char fpsInfo[255]; 267 | sprintf_s(fpsInfo, "FPS: %.f", ImGui::GetIO().Framerate); 268 | ImGui::GetOverlayDrawList()->AddText({ 10, 5 }, 0xFFDDDDDD, fpsInfo); 269 | } 270 | 271 | EXTERN_DLL_EXPORT void StyleColorsDark() { 272 | return ImGui::StyleColorsDark(); 273 | } 274 | EXTERN_DLL_EXPORT void StyleColorsLight() { 275 | return ImGui::StyleColorsLight(); 276 | } 277 | EXTERN_DLL_EXPORT void StyleColorsClassic() { 278 | return ImGui::StyleColorsClassic(); 279 | } 280 | EXTERN_DLL_EXPORT bool IsWindowAppearing() { 281 | return ImGui::IsWindowAppearing(); 282 | } 283 | EXTERN_DLL_EXPORT void SetWindowFocus() { 284 | return ImGui::SetWindowFocus(); 285 | } 286 | EXTERN_DLL_EXPORT void SetWindowCollapsedByName(const wchar_t* name, bool collapsed, ImGuiCond cond) { 287 | return ImGui::SetWindowCollapsed(wstr_utf8(name).c_str(), collapsed, cond); 288 | } 289 | EXTERN_DLL_EXPORT bool IsWindowCollapsed() { 290 | return ImGui::IsWindowCollapsed(); 291 | } 292 | EXTERN_DLL_EXPORT bool IsWindowFocused(ImGuiFocusedFlags flags) { 293 | return ImGui::IsWindowFocused(flags); 294 | } 295 | EXTERN_DLL_EXPORT bool IsWindowHovered(ImGuiHoveredFlags flags) { 296 | return ImGui::IsWindowHovered(0); 297 | } 298 | 299 | EXTERN_DLL_EXPORT void* GetWindowDrawList() { 300 | return ImGui::GetWindowDrawList(); 301 | } 302 | EXTERN_DLL_EXPORT void* GetBackgroundDrawList() { 303 | return ImGui::GetBackgroundDrawList(); 304 | } 305 | EXTERN_DLL_EXPORT void* GetForegroundDrawList() { 306 | return ImGui::GetForegroundDrawList(); 307 | } 308 | EXTERN_DLL_EXPORT void* GetOverlayDrawList() { 309 | return ImGui::GetOverlayDrawList(); 310 | } 311 | EXTERN_DLL_EXPORT void GetWindowPos(float* x, float* y) { 312 | ImVec2 pos = ImGui::GetWindowPos(); 313 | *x = pos.x; 314 | *y = pos.y; 315 | } 316 | EXTERN_DLL_EXPORT void GetWindowSize(float* x, float* y) { 317 | ImVec2 pos = ImGui::GetWindowSize(); 318 | *x = pos.x; 319 | *y = pos.y; 320 | } 321 | EXTERN_DLL_EXPORT void SetNextWindowPos(float x, float y, ImGuiCond cond, float pivot_x, float pivot_y){ 322 | ImGui::SetNextWindowPos({ x,y }, cond, {pivot_x,pivot_y}); 323 | } 324 | EXTERN_DLL_EXPORT void SetNextWindowSize(float x, float y, ImGuiCond cond){ 325 | ImGui::SetNextWindowSize({ x,y }, cond); 326 | } 327 | 328 | EXTERN_DLL_EXPORT void SetNextWindowSizeConstraints(float size_min_x, float size_min_y, float size_max_x, float size_max_y) { 329 | return ImGui::SetNextWindowSizeConstraints({ size_min_x, size_min_y }, { size_max_x, size_max_y }); 330 | } 331 | 332 | EXTERN_DLL_EXPORT void SetNextWindowContentSize(float size_x, float size_y) { 333 | ImGui::SetNextWindowContentSize({ size_x, size_y }); 334 | } 335 | EXTERN_DLL_EXPORT void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) { 336 | ImGui::SetNextWindowCollapsed(collapsed, cond); 337 | } 338 | EXTERN_DLL_EXPORT void SetNextWindowFocus() { 339 | ImGui::SetNextWindowFocus(); 340 | } 341 | 342 | 343 | 344 | 345 | EXTERN_DLL_EXPORT void SetNextWindowBgAlpha(float alpha){ 346 | return ImGui::SetNextWindowBgAlpha(alpha); 347 | } 348 | EXTERN_DLL_EXPORT void SetNextWindowViewport(ImGuiID id) { 349 | return ImGui::SetNextWindowViewport(id); 350 | } 351 | EXTERN_DLL_EXPORT void SetWindowPosition(float pos_x, float pos_y, ImGuiCond cond){ 352 | return ImGui::SetWindowPos({ pos_x, pos_y}, cond); 353 | } 354 | EXTERN_DLL_EXPORT void SetWindowSize(float size_x, float size_y, ImGuiCond cond){ 355 | return ImGui::SetWindowSize({ size_x, size_y}, cond); 356 | } 357 | EXTERN_DLL_EXPORT void SetWindowCollapsed(bool collapsed, ImGuiCond cond){ 358 | return ImGui::SetWindowCollapsed(collapsed, cond); 359 | } 360 | EXTERN_DLL_EXPORT void SetWindowFontScale(float scale){ 361 | return ImGui::SetWindowFontScale(scale); 362 | } 363 | EXTERN_DLL_EXPORT void SetWindowPosByName(const wchar_t* name, float pos_x, float pos_y, ImGuiCond cond){ 364 | return ImGui::SetWindowPos(wstr_utf8(name).c_str(), { pos_x, pos_y}, cond); 365 | } 366 | 367 | EXTERN_DLL_EXPORT void SetWindowSizeByName(const wchar_t* name, float size_x, float size_y, ImGuiCond cond){ 368 | return ImGui::SetWindowSize(wstr_utf8(name).c_str(), { size_x, size_y}, cond); 369 | } 370 | EXTERN_DLL_EXPORT void SetWindowFocusByName(const wchar_t* name){ 371 | return ImGui::SetWindowFocus(wstr_utf8(name).c_str()); 372 | } 373 | EXTERN_DLL_EXPORT void GetContentRegionMax(float* x, float* y){ 374 | ImVec2 pos = ImGui::GetContentRegionMax(); *x = pos.x; *y = pos.y; 375 | } 376 | EXTERN_DLL_EXPORT void GetContentRegionAvail(float* x, float* y){ 377 | ImVec2 pos = ImGui::GetContentRegionAvail(); *x = pos.x; *y = pos.y; 378 | } 379 | EXTERN_DLL_EXPORT void GetWindowContentRegionMin(float* x, float* y){ 380 | ImVec2 pos = ImGui::GetWindowContentRegionMin(); *x = pos.x; *y = pos.y; 381 | } 382 | EXTERN_DLL_EXPORT void GetWindowContentRegionMax(float* x, float* y){ 383 | ImVec2 pos = ImGui::GetWindowContentRegionMax(); *x = pos.x; *y = pos.y; 384 | } 385 | EXTERN_DLL_EXPORT void GetItemRectMin(float* x, float* y){ 386 | ImVec2 pos = ImGui::GetItemRectMin(); *x = pos.x; *y = pos.y; 387 | } 388 | EXTERN_DLL_EXPORT void GetItemRectMax(float* x, float* y){ 389 | ImVec2 pos = ImGui::GetItemRectMax(); *x = pos.x; *y = pos.y; 390 | } 391 | EXTERN_DLL_EXPORT void GetItemRectSize(float* x, float* y){ 392 | ImVec2 pos = ImGui::GetItemRectSize(); *x = pos.x; *y = pos.y; 393 | } 394 | EXTERN_DLL_EXPORT void GetMousePos(float* x, float* y){ 395 | ImVec2 pos = ImGui::GetMousePos(); *x = pos.x; *y = pos.y; 396 | } 397 | EXTERN_DLL_EXPORT void GetMousePosOnOpeningCurrentPopup(float* x, float* y){ 398 | ImVec2 pos = ImGui::GetMousePosOnOpeningCurrentPopup(); *x = pos.x; *y = pos.y; 399 | } 400 | EXTERN_DLL_EXPORT void GetMouseDragDelta(ImGuiMouseButton button, float lock_threshold, float* x, float* y){ 401 | ImVec2 pos = ImGui::GetMouseDragDelta(button, lock_threshold); *x = pos.x; *y = pos.y; 402 | } 403 | EXTERN_DLL_EXPORT void ImageGetSize(ImTextureID image, float *x, float*y){ 404 | ImVec2 pos = ukit::GetImageDimension(image); *x = pos.x; *y = pos.y; 405 | } 406 | 407 | EXTERN_DLL_EXPORT float GetWindowContentRegionWidth( ){ 408 | return ImGui::GetWindowContentRegionWidth(); 409 | } 410 | EXTERN_DLL_EXPORT float GetScrollX( ){ 411 | return ImGui::GetScrollX(); 412 | } 413 | EXTERN_DLL_EXPORT float GetScrollY( ){ 414 | return ImGui::GetScrollY(); 415 | } 416 | EXTERN_DLL_EXPORT float GetScrollMaxX( ){ 417 | return ImGui::GetScrollMaxX(); 418 | } 419 | EXTERN_DLL_EXPORT float GetScrollMaxY( ){ 420 | return ImGui::GetScrollMaxY(); 421 | } 422 | EXTERN_DLL_EXPORT void SetScrollX(float scroll_x){ 423 | return ImGui::SetScrollX(scroll_x); 424 | } 425 | EXTERN_DLL_EXPORT void SetScrollY(float scroll_y){ 426 | return ImGui::SetScrollY(scroll_y); 427 | } 428 | EXTERN_DLL_EXPORT void SetScrollHereX(float center_x_ratio){ 429 | return SetScrollHereX(center_x_ratio); 430 | } 431 | EXTERN_DLL_EXPORT void SetScrollHereY(float center_y_ratio){ 432 | return SetScrollHereY(center_y_ratio); 433 | } 434 | EXTERN_DLL_EXPORT void SetScrollFromPosX(float local_x, float center_x_ratio){ 435 | return ImGui::SetScrollFromPosX(local_x, center_x_ratio); 436 | } 437 | EXTERN_DLL_EXPORT void SetScrollFromPosY(float local_y, float center_y_ratio){ 438 | return ImGui::SetScrollFromPosY(local_y, center_y_ratio); 439 | } 440 | 441 | EXTERN_DLL_EXPORT void PushFont(void* font){ 442 | return ImGui::PushFont((ImFont*)font); 443 | } 444 | EXTERN_DLL_EXPORT void PopFont( ){ 445 | return ImGui::PopFont(); 446 | } 447 | EXTERN_DLL_EXPORT void PushStyleColor(ImGuiCol idx, ImU32 col){ 448 | return ImGui::PushStyleColor(idx, col); 449 | } 450 | EXTERN_DLL_EXPORT void PopStyleColor(int count){ 451 | return ImGui::PopStyleColor(count); 452 | } 453 | EXTERN_DLL_EXPORT void PushStyleVar(ImGuiStyleVar idx, float val){ 454 | return ImGui::PushStyleVar(idx, val); 455 | } 456 | EXTERN_DLL_EXPORT void PushStyleVarPos(ImGuiStyleVar idx, float val_x, float val_y){ 457 | return ImGui::PushStyleVar(idx, { val_x, val_y}); 458 | } 459 | EXTERN_DLL_EXPORT void PopStyleVar(int count){ 460 | return ImGui::PopStyleVar(count); 461 | } 462 | EXTERN_DLL_EXPORT ImFont* GetFont( ){ 463 | return ImGui::GetFont(); 464 | } 465 | EXTERN_DLL_EXPORT float GetFontSize( ){ 466 | return ImGui::GetFontSize(); 467 | } 468 | 469 | EXTERN_DLL_EXPORT void GetFontTexUvWhitePixel(float* x, float* y) { 470 | ImVec2 pos = ImGui::GetFontTexUvWhitePixel(); *x = pos.x; *y = pos.y; 471 | } 472 | EXTERN_DLL_EXPORT ImU32 GetColorU32(ImGuiCol idx, float alpha_mul){ 473 | return ImGui::GetColorU32(idx, alpha_mul); 474 | } 475 | EXTERN_DLL_EXPORT void PushItemWidth(float item_width){ 476 | return ImGui::PushItemWidth(item_width); 477 | } 478 | EXTERN_DLL_EXPORT void PopItemWidth( ){ 479 | return ImGui::PopItemWidth(); 480 | } 481 | EXTERN_DLL_EXPORT void SetNextItemWidth(float item_width){ 482 | return ImGui::SetNextItemWidth(item_width); 483 | } 484 | EXTERN_DLL_EXPORT float CalcItemWidth( ){ 485 | return ImGui::CalcItemWidth(); 486 | } 487 | EXTERN_DLL_EXPORT void PushTextWrapPos(float wrap_pos_x){ 488 | return ImGui::PushTextWrapPos(wrap_pos_x); 489 | } 490 | EXTERN_DLL_EXPORT void PopTextWrapPos( ){ 491 | return ImGui::PopTextWrapPos(); 492 | } 493 | EXTERN_DLL_EXPORT void PushAllowKeyboardFocus(bool allow_keyboard_focus){ 494 | return ImGui::PushAllowKeyboardFocus(allow_keyboard_focus); 495 | } 496 | EXTERN_DLL_EXPORT void PopAllowKeyboardFocus( ){ 497 | return ImGui::PopAllowKeyboardFocus(); 498 | } 499 | EXTERN_DLL_EXPORT void PushButtonRepeat(bool repeat){ 500 | return ImGui::PushButtonRepeat(repeat); 501 | } 502 | EXTERN_DLL_EXPORT void PopButtonRepeat( ){ 503 | return ImGui::PopButtonRepeat(); 504 | } 505 | EXTERN_DLL_EXPORT void Separator( ){ 506 | return ImGui::Separator(); 507 | } 508 | EXTERN_DLL_EXPORT void NewLine( ){ 509 | return ImGui::NewLine(); 510 | } 511 | EXTERN_DLL_EXPORT void Spacing( ){ 512 | return ImGui::Spacing(); 513 | } 514 | EXTERN_DLL_EXPORT void Dummy(float size_x, float size_y){ 515 | return ImGui::Dummy({ size_x, size_y}); 516 | } 517 | EXTERN_DLL_EXPORT void Indent(float indent_w){ 518 | return ImGui::Indent(indent_w); 519 | } 520 | EXTERN_DLL_EXPORT void Unindent(float indent_w){ 521 | return ImGui::Unindent(indent_w); 522 | } 523 | EXTERN_DLL_EXPORT void BeginGroup( ){ 524 | return ImGui::BeginGroup(); 525 | } 526 | EXTERN_DLL_EXPORT void EndGroup( ){ 527 | return ImGui::EndGroup(); 528 | } 529 | 530 | EXTERN_DLL_EXPORT void GetCursorPosition(float* x, float* y) { 531 | ImVec2 pos = ImGui::GetCursorPos(); *x = pos.x; *y = pos.y; 532 | } 533 | 534 | 535 | EXTERN_DLL_EXPORT void SetCursorPosition(float local_pos_x, float local_pos_y){ 536 | return ImGui::SetCursorPos({ local_pos_x, local_pos_y}); 537 | } 538 | 539 | EXTERN_DLL_EXPORT void GetCursorStartPos(float* x, float* y) { 540 | ImVec2 pos = ImGui::GetCursorStartPos(); *x = pos.x; *y = pos.y; 541 | } 542 | EXTERN_DLL_EXPORT void GetCursorScreenPos(float* x, float* y) { 543 | ImVec2 pos = ImGui::GetCursorScreenPos(); *x = pos.x; *y = pos.y; 544 | }EXTERN_DLL_EXPORT void SetCursorScreenPos(float pos_x, float pos_y){ 545 | return ImGui::SetCursorScreenPos({ pos_x, pos_y}); 546 | } 547 | EXTERN_DLL_EXPORT void AlignTextToFramePadding( ){ 548 | return ImGui::AlignTextToFramePadding(); 549 | } 550 | EXTERN_DLL_EXPORT float GetTextLineHeight( ){ 551 | return ImGui::GetTextLineHeight(); 552 | } 553 | EXTERN_DLL_EXPORT float GetTextLineHeightWithSpacing( ){ 554 | return ImGui::GetTextLineHeightWithSpacing(); 555 | } 556 | EXTERN_DLL_EXPORT float GetFrameHeight( ){ 557 | return ImGui::GetFrameHeight(); 558 | } 559 | EXTERN_DLL_EXPORT float GetFrameHeightWithSpacing( ){ 560 | return ImGui::GetFrameHeightWithSpacing(); 561 | } 562 | EXTERN_DLL_EXPORT void PushID(const wchar_t* str_id){ 563 | return ImGui::PushID(wstr_utf8(str_id).c_str()); 564 | } 565 | EXTERN_DLL_EXPORT void PopID( ){ 566 | return ImGui::PopID(); 567 | } 568 | EXTERN_DLL_EXPORT ImGuiID GetID(const wchar_t* str_id){ 569 | return ImGui::GetID(wstr_utf8(str_id).c_str()); 570 | } 571 | EXTERN_DLL_EXPORT void TextColored(ImU32 col, const wchar_t* text){ 572 | return ImGui::TextColored(GetVec4Color(col), wstr_utf8(text).c_str()); 573 | } 574 | EXTERN_DLL_EXPORT void TextDisabled(const wchar_t* text){ 575 | return ImGui::TextDisabled(wstr_utf8(text).c_str()); 576 | } 577 | EXTERN_DLL_EXPORT void TextWrapped(const wchar_t* text){ 578 | return ImGui::TextWrapped(wstr_utf8(text).c_str()); 579 | } 580 | EXTERN_DLL_EXPORT void LabelText(const wchar_t* label, const wchar_t* text){ 581 | return ImGui::LabelText(wstr_utf8(label).c_str(), wstr_utf8(text).c_str()); 582 | } 583 | EXTERN_DLL_EXPORT void BulletText(const wchar_t* text){ 584 | return ImGui::BulletText(wstr_utf8(text).c_str()); 585 | } 586 | EXTERN_DLL_EXPORT bool SmallButton(const wchar_t* label){ 587 | return ImGui::SmallButton(wstr_utf8(label).c_str()); 588 | } 589 | EXTERN_DLL_EXPORT bool InvisibleButton(const wchar_t* str_id, float size_x, float size_y){ 590 | return ImGui::InvisibleButton(wstr_utf8(str_id).c_str(), { size_x, size_y}); 591 | } 592 | EXTERN_DLL_EXPORT bool ArrowButton(const wchar_t* str_id, ImGuiDir dir){ 593 | return ImGui::ArrowButton(wstr_utf8(str_id).c_str(), dir); 594 | } 595 | EXTERN_DLL_EXPORT void Image(ImTextureID user_texture_id, float size_x, float size_y, float uv0_x, float uv0_y, float uv1_x, float uv1_y, ImU32 tint_col, ImU32 border_col){ 596 | return ImGui::Image(user_texture_id, { size_x, size_y}, { uv0_x, uv0_y}, { uv1_x, uv1_y}, GetVec4Color(tint_col), GetVec4Color(border_col)); 597 | } 598 | EXTERN_DLL_EXPORT void ImageFit(ImTextureID user_texture_id, float size_x, float size_y, bool clipping, float rounding, ImU32 tint_col, ImDrawCornerFlags rounding_corners){ 599 | ImVec2 imgSize = ukit::DrawImageFit(ImGui::GetWindowDrawList(), user_texture_id, ImGui::GetCursorScreenPos(), { size_x, size_y }, clipping, true, rounding, tint_col, rounding_corners); 600 | ImGui::InvisibleButton("hidden_image", imgSize); 601 | } 602 | EXTERN_DLL_EXPORT bool ImageButton(ImTextureID user_texture_id, float size_x, float size_y, float uv0_x, float uv0_y, float uv1_x, float uv1_y, int frame_padding, ImU32 bg_col, ImU32 tint_col){ 603 | return ImGui::ImageButton(user_texture_id, { size_x, size_y}, { uv0_x, uv0_y}, { uv1_x, uv1_y}, frame_padding, GetVec4Color(bg_col), GetVec4Color(tint_col)); 604 | } 605 | EXTERN_DLL_EXPORT bool CheckboxFlags(const wchar_t* label, unsigned int* flags, unsigned int flags_value){ 606 | return ImGui::CheckboxFlags(wstr_utf8(label).c_str(), flags, flags_value); 607 | } 608 | EXTERN_DLL_EXPORT bool RadioButton(const wchar_t* label, int* v, int v_button){ 609 | return ImGui::RadioButton(wstr_utf8(label).c_str(), v, v_button); 610 | } 611 | EXTERN_DLL_EXPORT void ProgressBar(float fraction, float size_arg_x, float size_arg_y, const wchar_t* overlay){ 612 | return ImGui::ProgressBar(fraction, { size_arg_x, size_arg_y}, (overlay == 0 ? 0 : wstr_utf8(overlay).c_str())); 613 | } 614 | EXTERN_DLL_EXPORT void Bullet( ){ 615 | return ImGui::Bullet(); 616 | } 617 | EXTERN_DLL_EXPORT bool BeginCombo(const wchar_t* label, const wchar_t* preview_value, ImGuiComboFlags flags){ 618 | return ImGui::BeginCombo(wstr_utf8(label).c_str(), wstr_utf8(preview_value).c_str(), flags); 619 | } 620 | EXTERN_DLL_EXPORT void EndCombo( ){ 621 | return ImGui::EndCombo(); 622 | } 623 | 624 | 625 | EXTERN_DLL_EXPORT void AddLine(ImDrawList* pDrawlist, float p1_x, float p1_y, float p2_x, float p2_y, ImU32 col, float thickness){ 626 | return pDrawlist->AddLine({ p1_x, p1_y}, { p2_x, p2_y}, ARGB2ABGR(col), thickness); 627 | } 628 | EXTERN_DLL_EXPORT void AddRect(ImDrawList* pDrawlist, float p_min_x, float p_min_y, float p_max_x, float p_max_y, ImU32 col, float rounding, ImDrawCornerFlags rounding_corners, float thickness){ 629 | return pDrawlist->AddRect({ p_min_x, p_min_y}, { p_max_x, p_max_y}, ARGB2ABGR(col), rounding, rounding_corners, thickness); 630 | } 631 | EXTERN_DLL_EXPORT void AddRectFilled(ImDrawList* pDrawlist, float p_min_x, float p_min_y, float p_max_x, float p_max_y, ImU32 col, float rounding, ImDrawCornerFlags rounding_corners){ 632 | return pDrawlist->AddRectFilled({ p_min_x, p_min_y}, { p_max_x, p_max_y}, ARGB2ABGR(col), rounding, rounding_corners); 633 | } 634 | EXTERN_DLL_EXPORT void AddBezierCurve(ImDrawList* pDrawlist, float p1_x, float p1_y, float p2_x, float p2_y, float p3_x, float p3_y, float p4_x, float p4_y, ImU32 col, float thickness, int num_segments){ 635 | return pDrawlist->AddBezierCurve({ p1_x, p1_y}, { p2_x, p2_y}, { p3_x, p3_y}, { p4_x, p4_y}, ARGB2ABGR(col), thickness, num_segments); 636 | } 637 | EXTERN_DLL_EXPORT void AddCircle(ImDrawList* pDrawlist, float center_x, float center_y, float radius, ImU32 col, int num_segments, float thickness){ 638 | return pDrawlist->AddCircle({ center_x, center_y}, radius, ARGB2ABGR(col), num_segments, thickness); 639 | } 640 | EXTERN_DLL_EXPORT void AddCircleFilled(ImDrawList* pDrawlist, float center_x, float center_y, float radius, ImU32 col, int num_segments){ 641 | return pDrawlist->AddCircleFilled({ center_x, center_y}, radius, ARGB2ABGR(col), num_segments); 642 | } 643 | EXTERN_DLL_EXPORT void AddConvexPolyFilled(ImDrawList* pDrawlist, ImVec2* points, int points_count, ImU32 col) { 644 | return pDrawlist->AddConvexPolyFilled(points, points_count, ARGB2ABGR(col)); 645 | } 646 | EXTERN_DLL_EXPORT void AddImage(ImDrawList* pDrawlist, ImTextureID user_texture_id, float p_min_x, float p_min_y, float p_max_x, float p_max_y, float uv_min_x, float uv_min_y, float uv_max_x, float uv_max_y, ImU32 col){ 647 | return pDrawlist->AddImage(user_texture_id, { p_min_x, p_min_y}, { p_max_x, p_max_y}, { uv_min_x, uv_min_y}, { uv_max_x, uv_max_y}, ARGB2ABGR(col)); 648 | } 649 | EXTERN_DLL_EXPORT void AddImageFit(ImDrawList* pDrawlist, ImTextureID user_texture_id, float pos_x, float pos_y, float size_x, float size_y, bool clipping, float rounding, ImU32 tint_col, ImDrawCornerFlags rounding_corners){ 650 | 651 | ukit::DrawImageFit(pDrawlist, user_texture_id, { pos_x, pos_y }, { size_x, size_y }, clipping, true, rounding, tint_col, rounding_corners); 652 | } 653 | EXTERN_DLL_EXPORT void AddImageQuad(ImDrawList* pDrawlist, ImTextureID user_texture_id, float p1_x, float p1_y, float p2_x, float p2_y, float p3_x, float p3_y, float p4_x, float p4_y, float uv1_x, float uv1_y, float uv2_x, float uv2_y, float uv3_x, float uv3_y, float uv4_x, float uv4_y, ImU32 col){ 654 | return pDrawlist->AddImageQuad(user_texture_id, { p1_x, p1_y}, { p2_x, p2_y}, { p3_x, p3_y}, { p4_x, p4_y}, { uv1_x, uv1_y}, { uv2_x, uv2_y}, { uv3_x, uv3_y}, { uv4_x, uv4_y}, col); 655 | } 656 | EXTERN_DLL_EXPORT void AddImageRounded(ImDrawList* pDrawlist, ImTextureID user_texture_id, float p_min_x, float p_min_y, float p_max_x, float p_max_y, float uv_min_x, float uv_min_y, float uv_max_x, float uv_max_y, ImU32 col, float rounding, ImDrawCornerFlags rounding_corners){ 657 | return pDrawlist->AddImageRounded(user_texture_id, { p_min_x, p_min_y}, { p_max_x, p_max_y}, { uv_min_x, uv_min_y}, { uv_max_x, uv_max_y}, ARGB2ABGR(col), rounding, rounding_corners); 658 | } 659 | EXTERN_DLL_EXPORT void AddNgon(ImDrawList* pDrawlist, float center_x, float center_y, float radius, ImU32 col, int num_segments, float thickness){ 660 | return pDrawlist->AddNgon({ center_x, center_y}, radius, ARGB2ABGR(col), num_segments, thickness); 661 | } 662 | EXTERN_DLL_EXPORT void AddNgonFilled(ImDrawList* pDrawlist, float center_x, float center_y, float radius, ImU32 col, int num_segments){ 663 | return pDrawlist->AddNgonFilled({ center_x, center_y}, radius, ARGB2ABGR(col), num_segments); 664 | } 665 | EXTERN_DLL_EXPORT void AddPolyline(ImDrawList* pDrawlist, ImVec2* points, const int points_count, ImU32 col, bool closed, float thickness) { 666 | return pDrawlist->AddPolyline(points, points_count, ARGB2ABGR(col), closed, thickness); 667 | } 668 | EXTERN_DLL_EXPORT void AddQuad(ImDrawList* pDrawlist, float p1_x, float p1_y, float p2_x, float p2_y, float p3_x, float p3_y, float p4_x, float p4_y, ImU32 col, float thickness){ 669 | return pDrawlist->AddQuad({ p1_x, p1_y}, { p2_x, p2_y}, { p3_x, p3_y}, { p4_x, p4_y}, ARGB2ABGR(col), thickness); 670 | } 671 | EXTERN_DLL_EXPORT void AddQuadFilled(ImDrawList* pDrawlist, float p1_x, float p1_y, float p2_x, float p2_y, float p3_x, float p3_y, float p4_x, float p4_y, ImU32 col){ 672 | return pDrawlist->AddQuadFilled({ p1_x, p1_y}, { p2_x, p2_y}, { p3_x, p3_y}, { p4_x, p4_y}, ARGB2ABGR(col)); 673 | } 674 | EXTERN_DLL_EXPORT void AddRectFilledMultiColor(ImDrawList* pDrawlist, float p_min_x, float p_min_y, float p_max_x, float p_max_y, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left) { 675 | return pDrawlist->AddRectFilledMultiColor({ p_min_x, p_min_y }, { p_max_x, p_max_y }, col_upr_left, col_upr_right, col_bot_right, col_bot_left); 676 | } 677 | EXTERN_DLL_EXPORT void AddText(ImDrawList* pDrawlist, ImFont* font, float font_size, float pos_x, float pos_y, ImU32 col, const wchar_t* text, float wrap_width) { 678 | return pDrawlist->AddText(font, font_size, { pos_x, pos_y }, ARGB2ABGR(col), wstr_utf8(text).c_str(), 0, wrap_width); 679 | } 680 | EXTERN_DLL_EXPORT void AddTriangle(ImDrawList* pDrawlist, float p1_x, float p1_y, float p2_x, float p2_y, float p3_x, float p3_y, ImU32 col, float thickness) { 681 | return pDrawlist->AddTriangle({ p1_x, p1_y }, { p2_x, p2_y }, { p3_x, p3_y }, col, thickness); 682 | } 683 | EXTERN_DLL_EXPORT void AddTriangleFilled(ImDrawList* pDrawlist, float p1_x, float p1_y, float p2_x, float p2_y, float p3_x, float p3_y, ImU32 col) { 684 | return pDrawlist->AddTriangleFilled({ p1_x, p1_y }, { p2_x, p2_y }, { p3_x, p3_y }, col); 685 | } 686 | 687 | EXTERN_DLL_EXPORT void PathClear(ImDrawList* pDrawlist) { 688 | return pDrawlist->PathClear(); 689 | } 690 | EXTERN_DLL_EXPORT void PathLineTo(ImDrawList* pDrawlist, float pos_x, float pos_y) { 691 | return pDrawlist->PathLineTo({ pos_x, pos_y }); 692 | } 693 | EXTERN_DLL_EXPORT void PathLineToMergeDuplicate(ImDrawList* pDrawlist, float pos_x, float pos_y) { 694 | return pDrawlist->PathLineToMergeDuplicate({ pos_x, pos_y }); 695 | } 696 | EXTERN_DLL_EXPORT void PathFillConvex(ImDrawList* pDrawlist, ImU32 col) { 697 | return pDrawlist->PathFillConvex(ARGB2ABGR(col)); 698 | } 699 | EXTERN_DLL_EXPORT void PathStroke(ImDrawList* pDrawlist, ImU32 col, boolean closed, float thickness) { 700 | return pDrawlist->PathStroke(ARGB2ABGR(col), closed, thickness); 701 | } 702 | EXTERN_DLL_EXPORT void PathArcTo(ImDrawList* pDrawlist, float center_x, float center_y, float radius, float a_min, float a_max, int num_segments) { 703 | return pDrawlist->PathArcTo({ center_x, center_y }, radius, a_min, a_max, num_segments); 704 | } 705 | EXTERN_DLL_EXPORT void PathArcToFast(ImDrawList* pDrawlist, float center_x, float center_y, float radius, int a_min_of_12, int a_max_of_12) { 706 | return pDrawlist->PathArcToFast({ center_x, center_y }, radius, a_min_of_12, a_max_of_12); 707 | } 708 | EXTERN_DLL_EXPORT void PathBezierCurveTo(ImDrawList* pDrawlist, float p2_x, float p2_y, float p3_x, float p3_y, float p4_x, float p4_y, int num_segments) { 709 | return pDrawlist->PathBezierCurveTo({ p2_x, p2_y }, { p3_x, p3_y }, { p4_x, p4_y }, num_segments); 710 | } 711 | EXTERN_DLL_EXPORT void PathRect(ImDrawList* pDrawlist, float rect_min_x, float rect_min_y, float rect_max_x, float rect_max_y, float rounding, ImDrawCornerFlags rounding_corners) { 712 | return pDrawlist->PathRect({ rect_min_x, rect_min_y }, { rect_max_x, rect_max_y }, rounding, rounding_corners); 713 | } 714 | 715 | 716 | EXTERN_DLL_EXPORT void* GetIO() { 717 | return &ImGui::GetIO(); 718 | } 719 | EXTERN_DLL_EXPORT void* GetStyle() { 720 | return &ImGui::GetStyle(); 721 | } 722 | EXTERN_DLL_EXPORT void SetStyleColor(ImGuiCol idx, ImU32 col) { 723 | ImGui::GetStyle().Colors[idx] = GetVec4Color(col); 724 | } 725 | EXTERN_DLL_EXPORT bool Selectable(const wchar_t* label, bool selected, ImGuiSelectableFlags flags, float size_arg_x, float size_arg_y){ 726 | return ImGui::Selectable(wstr_utf8(label).c_str(), selected, flags, { size_arg_x, size_arg_y}); 727 | } 728 | EXTERN_DLL_EXPORT void SetItemDefaultFocus( ){ 729 | return ImGui::SetItemDefaultFocus(); 730 | } 731 | EXTERN_DLL_EXPORT void Columns(int columns_count, const wchar_t* id, bool border){ 732 | return ImGui::Columns(columns_count, wstr_utf8(id).c_str(), border); 733 | } 734 | EXTERN_DLL_EXPORT void NextColumn( ){ 735 | return ImGui::NextColumn(); 736 | } 737 | EXTERN_DLL_EXPORT int GetColumnIndex( ){ 738 | return ImGui::GetColumnIndex(); 739 | } 740 | EXTERN_DLL_EXPORT float GetColumnWidth(int column_index){ 741 | return ImGui::GetColumnWidth(column_index); 742 | } 743 | EXTERN_DLL_EXPORT void SetColumnWidth(int column_index, float width){ 744 | return ImGui::SetColumnWidth(column_index, width); 745 | } 746 | EXTERN_DLL_EXPORT float GetColumnOffset(int column_index){ 747 | return ImGui::GetColumnOffset(column_index); 748 | } 749 | EXTERN_DLL_EXPORT void SetColumnOffset(int column_index, float offset){ 750 | return ImGui::SetColumnOffset(column_index, offset); 751 | } 752 | EXTERN_DLL_EXPORT int GetColumnsCount( ){ 753 | return ImGui::GetColumnsCount(); 754 | } 755 | 756 | EXTERN_DLL_EXPORT bool DragFloat(const wchar_t* label, float* v, float v_speed, float v_min, float v_max, const wchar_t* format, float power){ 757 | static float a = 5.f; 758 | return ImGui::DragFloat(wstr_utf8(label).c_str(), &a, v_speed, v_min, v_max, wstr_utf8(format).c_str(), power); 759 | } 760 | EXTERN_DLL_EXPORT bool DragInt(const wchar_t* label, int* v, float v_speed, int v_min, int v_max, const wchar_t* format){ 761 | return ImGui::DragInt(wstr_utf8(label).c_str(), v, v_speed, v_min, v_max, wstr_utf8(format).c_str()); 762 | } 763 | EXTERN_DLL_EXPORT bool SliderAngle(const wchar_t* label, float* v_rad, float v_degrees_min, float v_degrees_max, const wchar_t* format){ 764 | return ImGui::SliderAngle(wstr_utf8(label).c_str(), v_rad, v_degrees_min, v_degrees_max, wstr_utf8(format).c_str()); 765 | } 766 | EXTERN_DLL_EXPORT bool VSliderFloat(const wchar_t* label, float size_x, float size_y, float* v, float v_min, float v_max, const wchar_t* format, float power){ 767 | return ImGui::VSliderFloat(wstr_utf8(label).c_str(), { size_x, size_y}, v, v_min, v_max, wstr_utf8(format).c_str(), power); 768 | } 769 | EXTERN_DLL_EXPORT bool VSliderInt(const wchar_t* label, float size_x, float size_y, int* v, int v_min, int v_max, const wchar_t* format){ 770 | return ImGui::VSliderInt(wstr_utf8(label).c_str(), { size_x, size_y}, v, v_min, v_max, wstr_utf8(format).c_str()); 771 | } 772 | EXTERN_DLL_EXPORT bool InputFloat(const wchar_t* label, float* v, float step, float step_fast, const wchar_t* format, ImGuiInputTextFlags flags){ 773 | return ImGui::InputFloat(wstr_utf8(label).c_str(), v, step, step_fast, wstr_utf8(format).c_str(), flags); 774 | } 775 | EXTERN_DLL_EXPORT bool InputInt(const wchar_t* label, int* v, int step, int step_fast, ImGuiInputTextFlags flags){ 776 | return ImGui::InputInt(wstr_utf8(label).c_str(), v, step, step_fast, flags); 777 | } 778 | EXTERN_DLL_EXPORT bool InputDouble(const wchar_t* label, double* v, double step, double step_fast, const wchar_t* format, ImGuiInputTextFlags flags){ 779 | return ImGui::InputDouble(wstr_utf8(label).c_str(), v, step, step_fast, wstr_utf8(format).c_str(), flags); 780 | } 781 | EXTERN_DLL_EXPORT bool TreeNode(const wchar_t* label){ 782 | return ImGui::TreeNode(wstr_utf8(label).c_str()); 783 | } 784 | EXTERN_DLL_EXPORT bool TreeNodeEx(const wchar_t* label, ImGuiTreeNodeFlags flags){ 785 | return ImGui::TreeNodeEx(wstr_utf8(label).c_str(), flags); 786 | } 787 | EXTERN_DLL_EXPORT void TreePush(const wchar_t* str_id){ 788 | return ImGui::TreePush(wstr_utf8(str_id).c_str()); 789 | } 790 | EXTERN_DLL_EXPORT void TreePop( ){ 791 | return ImGui::TreePop(); 792 | } 793 | EXTERN_DLL_EXPORT float GetTreeNodeToLabelSpacing( ){ 794 | return ImGui::GetTreeNodeToLabelSpacing(); 795 | } 796 | EXTERN_DLL_EXPORT bool CollapsingHeader(const wchar_t* label, ImGuiTreeNodeFlags flags){ 797 | return ImGui::CollapsingHeader(wstr_utf8(label).c_str(), flags); 798 | } 799 | EXTERN_DLL_EXPORT bool CollapsingHeaderEx(const wchar_t* label, bool* p_open, ImGuiTreeNodeFlags flags){ 800 | return ImGui::CollapsingHeader(wstr_utf8(label).c_str(), p_open, flags); 801 | } 802 | EXTERN_DLL_EXPORT void SetNextItemOpen(bool is_open, ImGuiCond cond){ 803 | return ImGui::SetNextItemOpen(is_open, cond); 804 | } 805 | EXTERN_DLL_EXPORT bool ListBox(const wchar_t* label, int* current_item, wchar_t* items, int* items_count, int height_items){ 806 | //ImGui::ListBox() 807 | int count = *items_count; 808 | int offset = 0; 809 | int total_len = 0; 810 | for (int i = 0; i < count; i++) total_len += items_count[i + 1]; 811 | 812 | char** buffer = new char*[count]; 813 | 814 | for (int i = 0; i < count; i++) { 815 | int t_len = items_count[i + 1]; 816 | buffer[i] = new char[t_len]; 817 | 818 | memcpy(buffer[i], wstr_utf8(&items[offset]).c_str(), t_len); 819 | offset += t_len; 820 | } 821 | 822 | bool result = ImGui::ListBox(wstr_utf8(label).c_str(), current_item, buffer, count, height_items); 823 | return result; 824 | } 825 | EXTERN_DLL_EXPORT bool ListBoxHeader(const wchar_t* label, float size_arg_x, float size_arg_y){ 826 | return ImGui::ListBoxHeader(wstr_utf8(label).c_str(), { size_arg_x, size_arg_y}); 827 | } 828 | EXTERN_DLL_EXPORT bool ListBoxHeaderEx(const wchar_t* label, int items_count, int height_in_items){ 829 | return ImGui::ListBoxHeader(wstr_utf8(label).c_str(), items_count, height_in_items); 830 | } 831 | EXTERN_DLL_EXPORT void ListBoxFooter( ){ 832 | return ImGui::ListBoxFooter(); 833 | } 834 | EXTERN_DLL_EXPORT void PlotLines(const wchar_t* label, const float* values, int values_count, int values_offset, const wchar_t* overlay_text, float scale_min, float scale_max, float graph_size_x, float graph_size_y, int stride){ 835 | return ImGui::PlotLines((label == 0 ? 0 : wstr_utf8(label).c_str()), values, values_count, values_offset, (overlay_text == 0 ? 0 : wstr_utf8(overlay_text).c_str()), scale_min, scale_max, { graph_size_x, graph_size_y}, stride); 836 | } 837 | EXTERN_DLL_EXPORT void PlotHistogram(const wchar_t* label, const float* values, int values_count, int values_offset, const wchar_t* overlay_text, float scale_min, float scale_max, float graph_size_x, float graph_size_y, int stride){ 838 | return ImGui::PlotHistogram((label == 0 ? 0 : wstr_utf8(label).c_str()), values, values_count, values_offset, (overlay_text == 0 ? 0 : wstr_utf8(overlay_text).c_str()), scale_min, scale_max, { graph_size_x, graph_size_y}, stride); 839 | } 840 | 841 | EXTERN_DLL_EXPORT void ValueBool(const wchar_t* prefix, bool b){ 842 | return ImGui::Value((prefix == 0 ? 0 : wstr_utf8(prefix).c_str()), b); 843 | } 844 | EXTERN_DLL_EXPORT void ValueInt(const wchar_t* prefix, int v){ 845 | return ImGui::Value((prefix == 0 ? 0 : wstr_utf8(prefix).c_str()), v); 846 | } 847 | EXTERN_DLL_EXPORT void ValueFloat(const wchar_t* prefix, float v, const wchar_t* float_format){ 848 | return ImGui::Value((prefix == 0 ? 0 : wstr_utf8(prefix).c_str()), v, (float_format == 0 ? 0 : wstr_utf8(float_format).c_str())); 849 | } 850 | EXTERN_DLL_EXPORT bool BeginMenuBar( ){ 851 | return ImGui::BeginMenuBar(); 852 | } 853 | EXTERN_DLL_EXPORT void EndMenuBar( ){ 854 | return ImGui::EndMenuBar(); 855 | } 856 | EXTERN_DLL_EXPORT bool BeginMainMenuBar( ){ 857 | return ImGui::BeginMainMenuBar(); 858 | } 859 | EXTERN_DLL_EXPORT void EndMainMenuBar( ){ 860 | return ImGui::EndMainMenuBar(); 861 | } 862 | EXTERN_DLL_EXPORT bool BeginMenu(const wchar_t* label, bool enabled){ 863 | return ImGui::BeginMenu((label == 0 ? 0 : wstr_utf8(label).c_str()), enabled); 864 | } 865 | EXTERN_DLL_EXPORT void EndMenu_( ){ 866 | return ImGui::EndMenu(); 867 | } 868 | EXTERN_DLL_EXPORT bool MenuItem(const wchar_t* label, const wchar_t* shortcut, bool selected, bool enabled){ 869 | return ImGui::MenuItem((label == 0 ? 0 : wstr_utf8(label).c_str()), (shortcut == 0 ? 0 : wstr_utf8(shortcut).c_str()), selected, enabled); 870 | } 871 | EXTERN_DLL_EXPORT bool MenuItemEx(const wchar_t* label, const wchar_t* shortcut, bool* p_selected, bool enabled){ 872 | return ImGui::MenuItem((label == 0 ? 0 : wstr_utf8(label).c_str()), (shortcut == 0 ? 0 : wstr_utf8(shortcut).c_str()), p_selected, enabled); 873 | } 874 | EXTERN_DLL_EXPORT void BeginTooltip( ){ 875 | return ImGui::BeginTooltip(); 876 | } 877 | EXTERN_DLL_EXPORT void EndTooltip( ){ 878 | return ImGui::EndTooltip(); 879 | } 880 | EXTERN_DLL_EXPORT void SetTooltip(const wchar_t* text){ 881 | return ImGui::SetTooltip((text == 0 ? 0 : wstr_utf8(text).c_str())); 882 | } 883 | EXTERN_DLL_EXPORT bool BeginPopup(const wchar_t* str_id, ImGuiWindowFlags flags){ 884 | return ImGui::BeginPopup((str_id == 0 ? 0 : wstr_utf8(str_id).c_str()), flags); 885 | } 886 | EXTERN_DLL_EXPORT bool BeginPopupModal(const wchar_t* name, bool* p_open, ImGuiWindowFlags flags){ 887 | return ImGui::BeginPopupModal((name == 0 ? 0 : wstr_utf8(name).c_str()), p_open, flags); 888 | } 889 | EXTERN_DLL_EXPORT void EndPopup( ){ 890 | return ImGui::EndPopup(); 891 | } 892 | EXTERN_DLL_EXPORT void OpenPopup(const wchar_t* str_id, ImGuiPopupFlags popup_flags){ 893 | return ImGui::OpenPopup((str_id == 0 ? 0 : wstr_utf8(str_id).c_str()), popup_flags); 894 | } 895 | EXTERN_DLL_EXPORT bool OpenPopupContextItem(const wchar_t* str_id, ImGuiPopupFlags popup_flags){ 896 | return ImGui::OpenPopupContextItem((str_id == 0 ? 0 : wstr_utf8(str_id).c_str()), popup_flags); 897 | } 898 | EXTERN_DLL_EXPORT void CloseCurrentPopup( ){ 899 | return ImGui::CloseCurrentPopup(); 900 | } 901 | EXTERN_DLL_EXPORT bool BeginPopupContextItem(const wchar_t* str_id, ImGuiPopupFlags popup_flags){ 902 | return ImGui::BeginPopupContextItem((str_id == 0 ? 0 : wstr_utf8(str_id).c_str()), popup_flags); 903 | } 904 | EXTERN_DLL_EXPORT bool BeginPopupContextWindow(const wchar_t* str_id, ImGuiPopupFlags popup_flags){ 905 | return ImGui::BeginPopupContextWindow((str_id == 0 ? 0 : wstr_utf8(str_id).c_str()), popup_flags); 906 | } 907 | EXTERN_DLL_EXPORT bool BeginPopupContextVoid(const wchar_t* str_id, ImGuiPopupFlags popup_flags){ 908 | return ImGui::BeginPopupContextVoid((str_id == 0 ? 0 : wstr_utf8(str_id).c_str()), popup_flags); 909 | } 910 | EXTERN_DLL_EXPORT bool IsPopupOpen(const wchar_t* str_id, ImGuiPopupFlags popup_flags){ 911 | return ImGui::IsPopupOpen((str_id == 0 ? 0 : wstr_utf8(str_id).c_str()), popup_flags); 912 | } 913 | EXTERN_DLL_EXPORT bool BeginTabBar(const wchar_t* str_id, ImGuiTabBarFlags flags){ 914 | return ImGui::BeginTabBar((str_id == 0 ? 0 : wstr_utf8(str_id).c_str()), flags); 915 | } 916 | EXTERN_DLL_EXPORT void EndTabBar( ){ 917 | return ImGui::EndTabBar(); 918 | } 919 | EXTERN_DLL_EXPORT bool BeginTabItem(const wchar_t* label, bool* p_open, ImGuiTabItemFlags flags){ 920 | return ImGui::BeginTabItem((label == 0 ? 0 : wstr_utf8(label).c_str()), p_open, flags); 921 | } 922 | EXTERN_DLL_EXPORT void EndTabItem( ){ 923 | return ImGui::EndTabItem(); 924 | } 925 | EXTERN_DLL_EXPORT void SetTabItemClosed(const wchar_t* label){ 926 | return ImGui::SetTabItemClosed((label == 0 ? 0 : wstr_utf8(label).c_str())); 927 | } 928 | EXTERN_DLL_EXPORT void DockSpace(ImGuiID id, float size_arg_x, float size_arg_y, ImGuiDockNodeFlags flags){ 929 | return ImGui::DockSpace(id, { size_arg_x, size_arg_y}, flags); 930 | } 931 | EXTERN_DLL_EXPORT ImGuiID DockSpaceOverViewport(ImGuiViewport* viewport, ImGuiDockNodeFlags dockspace_flags){ 932 | return ImGui::DockSpaceOverViewport(viewport, dockspace_flags); 933 | } 934 | EXTERN_DLL_EXPORT void SetNextWindowDockID(ImGuiID id, ImGuiCond cond){ 935 | return ImGui::SetNextWindowDockID(id, cond); 936 | } 937 | EXTERN_DLL_EXPORT void SetNextWindowClass(ImGuiWindowClass* window_class){ 938 | return ImGui::SetNextWindowClass(window_class); 939 | } 940 | EXTERN_DLL_EXPORT ImGuiID GetWindowDockID( ){ 941 | return ImGui::GetWindowDockID(); 942 | } 943 | EXTERN_DLL_EXPORT bool IsWindowDocked( ){ 944 | return ImGui::IsWindowDocked(); 945 | } 946 | EXTERN_DLL_EXPORT bool BeginDragDropSource(ImGuiDragDropFlags flags){ 947 | return ImGui::BeginDragDropSource(flags); 948 | } 949 | EXTERN_DLL_EXPORT void PushClipRect(float clip_rect_min_x, float clip_rect_min_y, float clip_rect_max_x, float clip_rect_max_y, boolean intersect_with_current_clip_rect){ 950 | return ImGui::PushClipRect({ clip_rect_min_x, clip_rect_min_y}, { clip_rect_max_x, clip_rect_max_y}, intersect_with_current_clip_rect); 951 | } 952 | EXTERN_DLL_EXPORT void PopClipRect( ){ 953 | return ImGui::PopClipRect(); 954 | } 955 | EXTERN_DLL_EXPORT void SetKeyboardFocusHere(int offset){ 956 | return ImGui::SetKeyboardFocusHere(offset); 957 | } 958 | EXTERN_DLL_EXPORT bool IsItemHovered(ImGuiHoveredFlags flags){ 959 | return ImGui::IsItemHovered(flags); 960 | } 961 | EXTERN_DLL_EXPORT bool IsItemActive( ){ 962 | return ImGui::IsItemActive(); 963 | } 964 | EXTERN_DLL_EXPORT bool IsItemFocused( ){ 965 | return ImGui::IsItemFocused(); 966 | } 967 | EXTERN_DLL_EXPORT bool IsItemVisible( ){ 968 | return ImGui::IsItemVisible(); 969 | } 970 | EXTERN_DLL_EXPORT bool IsItemEdited( ){ 971 | return ImGui::IsItemEdited(); 972 | } 973 | EXTERN_DLL_EXPORT bool IsItemActivated( ){ 974 | return ImGui::IsItemActivated(); 975 | } 976 | EXTERN_DLL_EXPORT bool IsItemDeactivated( ){ 977 | return ImGui::IsItemDeactivated(); 978 | } 979 | EXTERN_DLL_EXPORT bool IsItemDeactivatedAfterEdit( ){ 980 | return ImGui::IsItemDeactivatedAfterEdit(); 981 | } 982 | EXTERN_DLL_EXPORT bool IsItemToggledOpen( ){ 983 | return ImGui::IsItemToggledOpen(); 984 | } 985 | EXTERN_DLL_EXPORT bool IsAnyItemHovered( ){ 986 | return ImGui::IsAnyItemHovered(); 987 | } 988 | EXTERN_DLL_EXPORT bool IsAnyItemActive( ){ 989 | return ImGui::IsAnyItemActive(); 990 | } 991 | EXTERN_DLL_EXPORT bool IsAnyItemFocused( ){ 992 | return ImGui::IsAnyItemFocused(); 993 | } 994 | EXTERN_DLL_EXPORT void SetItemAllowOverlap( ){ 995 | return ImGui::SetItemAllowOverlap(); 996 | } 997 | EXTERN_DLL_EXPORT bool IsItemClicked(ImGuiMouseButton mouse_button){ 998 | return ImGui::IsItemClicked(mouse_button); 999 | } 1000 | EXTERN_DLL_EXPORT bool IsRectVisible(float size_x, float size_y){ 1001 | return ImGui::IsRectVisible({ size_x, size_y}); 1002 | } 1003 | EXTERN_DLL_EXPORT bool IsRectVisibleEx(float rect_min_x, float rect_min_y, float rect_max_x, float rect_max_y){ 1004 | return ImGui::IsRectVisible({ rect_min_x, rect_min_y}, { rect_max_x, rect_max_y}); 1005 | } 1006 | EXTERN_DLL_EXPORT double GetTime( ){ 1007 | return ImGui::GetTime(); 1008 | } 1009 | EXTERN_DLL_EXPORT int GetFrameCount( ){ 1010 | return ImGui::GetFrameCount(); 1011 | }EXTERN_DLL_EXPORT bool BeginChildFrame(ImGuiID id, float size_x, float size_y, ImGuiWindowFlags extra_flags){ 1012 | return ImGui::BeginChildFrame(id, { size_x, size_y}, extra_flags); 1013 | } 1014 | EXTERN_DLL_EXPORT void EndChildFrame( ){ 1015 | return ImGui::EndChildFrame(); 1016 | } 1017 | EXTERN_DLL_EXPORT void CalcTextSize(const wchar_t* text, boolean hide_text_after_double_hash, float wrap_width, float*x, float*y){ 1018 | ImVec2 size = ImGui::CalcTextSize((text == 0 ? 0 : wstr_utf8(text).c_str()), 0, hide_text_after_double_hash, wrap_width); 1019 | *x = size.x; *y = size.y; 1020 | } 1021 | EXTERN_DLL_EXPORT int GetKeyIndex(ImGuiKey imgui_key){ 1022 | return ImGui::GetKeyIndex(imgui_key); 1023 | } 1024 | EXTERN_DLL_EXPORT bool IsKeyDown(int user_key_index){ 1025 | return ImGui::IsKeyDown(user_key_index); 1026 | } 1027 | EXTERN_DLL_EXPORT bool IsKeyPressed(int user_key_index, boolean repeat){ 1028 | return ImGui::IsKeyPressed(user_key_index, repeat); 1029 | } 1030 | EXTERN_DLL_EXPORT bool IsKeyReleased(int user_key_index){ 1031 | return ImGui::IsKeyReleased(user_key_index); 1032 | } 1033 | EXTERN_DLL_EXPORT int GetKeyPressedAmount(int key_index, float repeat_delay, float repeat_rate){ 1034 | return ImGui::GetKeyPressedAmount(key_index, repeat_delay, repeat_rate); 1035 | } 1036 | EXTERN_DLL_EXPORT void CaptureKeyboardFromApp(boolean capture){ 1037 | return ImGui::CaptureKeyboardFromApp(capture); 1038 | } 1039 | EXTERN_DLL_EXPORT bool IsMouseDown(ImGuiMouseButton button){ 1040 | return ImGui::IsMouseDown(button); 1041 | } 1042 | EXTERN_DLL_EXPORT bool IsMouseClicked(ImGuiMouseButton button, boolean repeat){ 1043 | return ImGui::IsMouseClicked(button, repeat); 1044 | } 1045 | EXTERN_DLL_EXPORT bool IsMouseReleased(ImGuiMouseButton button){ 1046 | return ImGui::IsMouseReleased(button); 1047 | } 1048 | EXTERN_DLL_EXPORT bool IsMouseHoveringRect(float r_min_x, float r_min_y, float r_max_x, float r_max_y, boolean clip){ 1049 | return ImGui::IsMouseHoveringRect({ r_min_x, r_min_y}, { r_max_x, r_max_y}, clip); 1050 | } 1051 | EXTERN_DLL_EXPORT bool IsMousePosValid( ){ 1052 | return ImGui::IsMousePosValid(); 1053 | } 1054 | EXTERN_DLL_EXPORT bool IsAnyMouseDown( ){ 1055 | return ImGui::IsAnyMouseDown(); 1056 | } 1057 | EXTERN_DLL_EXPORT bool IsMouseDragging(ImGuiMouseButton button, float lock_threshold){ 1058 | return ImGui::IsMouseDragging(button, lock_threshold); 1059 | } 1060 | EXTERN_DLL_EXPORT void ResetMouseDragDelta(ImGuiMouseButton button){ 1061 | return ImGui::ResetMouseDragDelta(button); 1062 | } 1063 | EXTERN_DLL_EXPORT ImGuiMouseCursor GetMouseCursor( ){ 1064 | return ImGui::GetMouseCursor(); 1065 | } 1066 | EXTERN_DLL_EXPORT void SetMouseCursor(ImGuiMouseCursor cursor_type){ 1067 | return ImGui::SetMouseCursor(cursor_type); 1068 | } 1069 | EXTERN_DLL_EXPORT void CaptureMouseFromApp(boolean capture){ 1070 | return ImGui::CaptureMouseFromApp(capture); 1071 | } 1072 | EXTERN_DLL_EXPORT void LoadIniSettingsFromDisk(const wchar_t* ini_filename){ 1073 | return ImGui::LoadIniSettingsFromDisk((ini_filename == 0 ? 0 : wstr_utf8(ini_filename).c_str())); 1074 | } 1075 | EXTERN_DLL_EXPORT void SaveIniSettingsToDisk(const wchar_t* ini_filename){ 1076 | return ImGui::SaveIniSettingsToDisk((ini_filename == 0 ? 0 : wstr_utf8(ini_filename).c_str())); 1077 | } 1078 | EXTERN_DLL_EXPORT ImGuiViewport* GetMainViewport( ){ 1079 | return ImGui::GetMainViewport(); 1080 | } 1081 | EXTERN_DLL_EXPORT void UpdatePlatformWindows( ){ 1082 | return ImGui::UpdatePlatformWindows(); 1083 | } 1084 | EXTERN_DLL_EXPORT void RenderPlatformWindowsDefault(void* platform_render_arg, void* renderer_render_arg){ 1085 | return ImGui::RenderPlatformWindowsDefault(platform_render_arg, renderer_render_arg); 1086 | } 1087 | EXTERN_DLL_EXPORT void DestroyPlatformWindows( ){ 1088 | return ImGui::DestroyPlatformWindows(); 1089 | } 1090 | 1091 | EXTERN_DLL_EXPORT ImTextureID ImageFromURL(const char* url) { 1092 | return DownloadImage(url); 1093 | } 1094 | 1095 | std::map MapImageFromFile; 1096 | EXTERN_DLL_EXPORT ImTextureID ImageFromFile(const wchar_t* path) { 1097 | 1098 | auto find = MapImageFromFile.find(path); 1099 | if ( find == MapImageFromFile.end()) { 1100 | ID3D11ShaderResourceView* texture; 1101 | HRESULT result2; 1102 | HRESULT result1 = D3DX11CreateShaderResourceViewFromFileW(g_pd3dDevice, path, NULL, NULL, &texture, &result2); 1103 | ImTextureID tid = texture; 1104 | 1105 | if (result1 != S_OK) return 0; 1106 | 1107 | MapImageFromFile[path] = tid; 1108 | return tid; 1109 | } 1110 | else { 1111 | return find->second; 1112 | } 1113 | }EXTERN_DLL_EXPORT ImGuiViewport* GetWindowViewport( ){ 1114 | return ImGui::GetWindowViewport(); 1115 | } 1116 | EXTERN_DLL_EXPORT float GetWindowDpiScale( ){ 1117 | return ImGui::GetWindowDpiScale(); 1118 | } 1119 | EXTERN_DLL_EXPORT float GetWindowWidth( ){ 1120 | return ImGui::GetWindowWidth(); 1121 | } 1122 | EXTERN_DLL_EXPORT float GetWindowHeight( ){ 1123 | return ImGui::GetWindowHeight(); 1124 | } 1125 | EXTERN_DLL_EXPORT bool DragFloatN(int n, const wchar_t* label, float* v, float v_speed, float v_min, float v_max, const wchar_t* format, float power){ 1126 | switch (n) { 1127 | case 2: 1128 | return ImGui::DragFloat2(wstr_utf8(label).c_str(), v, v_speed, v_min, v_max, wstr_utf8(format).c_str(), power); 1129 | case 3: 1130 | return ImGui::DragFloat3(wstr_utf8(label).c_str(), v, v_speed, v_min, v_max, wstr_utf8(format).c_str(), power); 1131 | case 4: 1132 | return ImGui::DragFloat4(wstr_utf8(label).c_str(), v, v_speed, v_min, v_max, wstr_utf8(format).c_str(), power); 1133 | } 1134 | return false; 1135 | } 1136 | EXTERN_DLL_EXPORT bool DragFloatRange2(const wchar_t* label, float* v_current_min, float* v_current_max, float v_speed, float v_min, float v_max, const wchar_t* format, const wchar_t* format_max, float power){ 1137 | return ImGui::DragFloatRange2((label == 0 ? 0 : wstr_utf8(label).c_str()), v_current_min, v_current_max, v_speed, v_min, v_max, (format == 0 ? 0 : wstr_utf8(format).c_str()), (format_max == 0 ? 0 : wstr_utf8(format_max).c_str()), power); 1138 | } 1139 | 1140 | EXTERN_DLL_EXPORT bool DragIntN(int n, const wchar_t* label, int* v, float v_speed, int v_min, int v_max, const wchar_t* format) { 1141 | switch (n) { 1142 | case 2: 1143 | return ImGui::DragInt2(wstr_utf8(label).c_str(), v, v_speed, v_min, v_max, wstr_utf8(format).c_str()); 1144 | case 3: 1145 | return ImGui::DragInt3(wstr_utf8(label).c_str(), v, v_speed, v_min, v_max, wstr_utf8(format).c_str()); 1146 | case 4: 1147 | return ImGui::DragInt4(wstr_utf8(label).c_str(), v, v_speed, v_min, v_max, wstr_utf8(format).c_str()); 1148 | } 1149 | return false; 1150 | } 1151 | EXTERN_DLL_EXPORT bool DragIntRange2(const wchar_t* label, int* v_current_min, int* v_current_max, float v_speed, int v_min, int v_max, const wchar_t* format, const wchar_t* format_max){ 1152 | return ImGui::DragIntRange2((label == 0 ? 0 : wstr_utf8(label).c_str()), v_current_min, v_current_max, v_speed, v_min, v_max, (format == 0 ? 0 : wstr_utf8(format).c_str()), (format_max == 0 ? 0 : wstr_utf8(format_max).c_str())); 1153 | } 1154 | 1155 | EXTERN_DLL_EXPORT bool SliderFloatN(int n, const wchar_t* label, float* v, float v_min, float v_max, const wchar_t* format, float power) { 1156 | switch (n) { 1157 | case 2: 1158 | return ImGui::SliderFloat2(wstr_utf8(label).c_str(), v, v_min, v_max, wstr_utf8(format).c_str(), power); 1159 | case 3: 1160 | return ImGui::SliderFloat3(wstr_utf8(label).c_str(), v, v_min, v_max, wstr_utf8(format).c_str(), power); 1161 | case 4: 1162 | return ImGui::SliderFloat4(wstr_utf8(label).c_str(), v, v_min, v_max, wstr_utf8(format).c_str(), power); 1163 | } 1164 | return false; 1165 | } 1166 | 1167 | EXTERN_DLL_EXPORT bool SliderInt(const wchar_t* label, int* v, int v_min, int v_max, const wchar_t* format) { 1168 | return ImGui::SliderInt(wstr_utf8(label).c_str(), v, v_min, v_max, wstr_utf8(format).c_str()); 1169 | } 1170 | EXTERN_DLL_EXPORT bool SliderIntN(int n, const wchar_t* label, int* v, int v_min, int v_max, const wchar_t* format) { 1171 | switch (n) { 1172 | case 2: 1173 | return ImGui::SliderInt2(wstr_utf8(label).c_str(), v, v_min, v_max, wstr_utf8(format).c_str()); 1174 | case 3: 1175 | return ImGui::SliderInt3(wstr_utf8(label).c_str(), v, v_min, v_max, wstr_utf8(format).c_str()); 1176 | case 4: 1177 | return ImGui::SliderInt4(wstr_utf8(label).c_str(), v, v_min, v_max, wstr_utf8(format).c_str()); 1178 | } 1179 | return false; 1180 | } 1181 | 1182 | 1183 | 1184 | 1185 | EXTERN_DLL_EXPORT bool InputFloatN(int n, const wchar_t* label, float* v, const wchar_t* format, ImGuiInputTextFlags flags) { 1186 | switch (n) { 1187 | case 2: 1188 | return ImGui::InputFloat2(wstr_utf8(label).c_str(), v, wstr_utf8(format).c_str(), flags); 1189 | case 3: 1190 | return ImGui::InputFloat3(wstr_utf8(label).c_str(), v, wstr_utf8(format).c_str(), flags); 1191 | case 4: 1192 | return ImGui::InputFloat4(wstr_utf8(label).c_str(), v, wstr_utf8(format).c_str(), flags); 1193 | } 1194 | return false; 1195 | } 1196 | 1197 | EXTERN_DLL_EXPORT bool InputIntN(int n, const wchar_t* label, int* v, ImGuiInputTextFlags flags) { 1198 | switch (n) { 1199 | case 2: 1200 | return ImGui::InputInt2(wstr_utf8(label).c_str(), v, flags); 1201 | case 3: 1202 | return ImGui::InputInt3(wstr_utf8(label).c_str(), v, flags); 1203 | case 4: 1204 | return ImGui::InputInt4(wstr_utf8(label).c_str(), v, flags); 1205 | } 1206 | return false; 1207 | } 1208 | 1209 | 1210 | EXTERN_DLL_EXPORT bool ColorEdit(const wchar_t *label, ImU32* color, ImGuiColorEditFlags flags){ 1211 | ImVec4 col = GetVec4Color(*color); 1212 | bool result = ImGui::ColorEdit4(wstr_utf8(label).c_str(), (float*)&col, flags); 1213 | *color = col; 1214 | return result; 1215 | } 1216 | EXTERN_DLL_EXPORT bool ColorPicker(const wchar_t *label, ImU32* color, ImGuiColorEditFlags flags){ 1217 | ImVec4 col = GetVec4Color(*color); 1218 | bool result = ImGui::ColorPicker4(wstr_utf8(label).c_str(), (float*)&col, flags); 1219 | *color = col; 1220 | return result; 1221 | }EXTERN_DLL_EXPORT float GetCursorPosX( ){ 1222 | return ImGui::GetCursorPosX(); 1223 | } 1224 | EXTERN_DLL_EXPORT float GetCursorPosY( ){ 1225 | return ImGui::GetCursorPosY(); 1226 | } 1227 | EXTERN_DLL_EXPORT void SetCursorPosX(float x){ 1228 | return ImGui::SetCursorPosX(x); 1229 | } 1230 | EXTERN_DLL_EXPORT void SetCursorPosY(float y){ 1231 | return ImGui::SetCursorPosY(y); 1232 | } 1233 | -------------------------------------------------------------------------------- /cpp/framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 4 | // Windows Header Files 5 | #include 6 | -------------------------------------------------------------------------------- /cpp/imconfig.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // COMPILE-TIME OPTIONS FOR DEAR IMGUI 3 | // Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure. 4 | // You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions. 5 | //----------------------------------------------------------------------------- 6 | // A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/branch with your modifications to imconfig.h) 7 | // B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h" 8 | // If you do so you need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include 9 | // the imgui*.cpp files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures. 10 | // Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. 11 | // Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using. 12 | //----------------------------------------------------------------------------- 13 | 14 | #pragma once 15 | 16 | //---- Define assertion handler. Defaults to calling assert(). 17 | // If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement. 18 | //#define IM_ASSERT(_EXPR) MyAssert(_EXPR) 19 | //#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts 20 | 21 | //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows 22 | // Using dear imgui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility. 23 | //#define IMGUI_API __declspec( dllexport ) 24 | //#define IMGUI_API __declspec( dllimport ) 25 | 26 | //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names. 27 | //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS 28 | 29 | //---- Disable all of Dear ImGui or don't implement standard windows. 30 | // It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp. 31 | //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. 32 | //#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended. 33 | //#define IMGUI_DISABLE_METRICS_WINDOW // Disable debug/metrics window: ShowMetricsWindow() will be empty. 34 | 35 | //---- Don't implement some functions to reduce linkage requirements. 36 | //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. 37 | //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow. 38 | //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime). 39 | //#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default). 40 | //#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf) 41 | //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself. 42 | //#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function. 43 | //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). 44 | 45 | //---- Include imgui_user.h at the end of imgui.h as a convenience 46 | //#define IMGUI_INCLUDE_IMGUI_USER_H 47 | 48 | //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another) 49 | //#define IMGUI_USE_BGRA_PACKED_COLOR 50 | 51 | //---- Use 32-bit for ImWchar (default is 16-bit) to support full unicode code points. 52 | //#define IMGUI_USE_WCHAR32 53 | 54 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version 55 | // By default the embedded implementations are declared static and not available outside of imgui cpp files. 56 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" 57 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" 58 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION 59 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION 60 | 61 | //---- Unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined, use the much faster STB sprintf library implementation of vsnprintf instead of the one from the default C library. 62 | // Note that stb_sprintf.h is meant to be provided by the user and available in the include path at compile time. Also, the compatibility checks of the arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf. 63 | // #define IMGUI_USE_STB_SPRINTF 64 | 65 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. 66 | // This will be inlined as part of ImVec2 and ImVec4 class declarations. 67 | /* 68 | #define IM_VEC2_CLASS_EXTRA \ 69 | ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ 70 | operator MyVec2() const { return MyVec2(x,y); } 71 | 72 | #define IM_VEC4_CLASS_EXTRA \ 73 | ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ 74 | operator MyVec4() const { return MyVec4(x,y,z,w); } 75 | */ 76 | 77 | //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices. 78 | // Your renderer back-end will need to support it (most example renderer back-ends support both 16/32-bit indices). 79 | // Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer. 80 | // Read about ImGuiBackendFlags_RendererHasVtxOffset for details. 81 | //#define ImDrawIdx unsigned int 82 | 83 | //---- Override ImDrawCallback signature (will need to modify renderer back-ends accordingly) 84 | //struct ImDrawList; 85 | //struct ImDrawCmd; 86 | //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data); 87 | //#define ImDrawCallback MyImDrawCallback 88 | 89 | //---- Debug Tools: Macro to break in Debugger 90 | // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.) 91 | //#define IM_DEBUG_BREAK IM_ASSERT(0) 92 | //#define IM_DEBUG_BREAK __debugbreak() 93 | 94 | //---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(), 95 | // (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.) 96 | // This adds a small runtime cost which is why it is not enabled by default. 97 | //#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX 98 | 99 | //---- Debug Tools: Enable slower asserts 100 | //#define IMGUI_DEBUG_PARANOID 101 | 102 | //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. 103 | /* 104 | namespace ImGui 105 | { 106 | void MyFunction(const char* name, const MyMatrix44& v); 107 | } 108 | */ 109 | -------------------------------------------------------------------------------- /cpp/imgui.ini: -------------------------------------------------------------------------------- 1 | [Window][Debug##Default] 2 | Pos=60,60 3 | Size=400,400 4 | Collapsed=0 5 | 6 | [Window][test] 7 | Pos=176,83 8 | Size=1469,787 9 | Collapsed=0 10 | 11 | [Window][Thông tin thửa đất] 12 | Pos=944,21 13 | Size=240,145 14 | Collapsed=0 15 | DockId=0x00000003,0 16 | 17 | [Window][Thông tin thửa đất2] 18 | Pos=712,21 19 | Size=472,640 20 | Collapsed=0 21 | 22 | [Window][BKDockSpace] 23 | Pos=0,0 24 | Size=1920,1017 25 | Collapsed=0 26 | 27 | [Window][Bản đồ] 28 | Pos=0,21 29 | Size=942,640 30 | Collapsed=0 31 | DockId=0x00000001,0 32 | 33 | [Window][Danh sách các thửa đất] 34 | Pos=944,168 35 | Size=240,493 36 | Collapsed=0 37 | DockId=0x00000004,0 38 | 39 | [Window][Biểu mẫu] 40 | Pos=165,151 41 | Size=378,168 42 | Collapsed=0 43 | 44 | [Window][menu_window] 45 | Pos=287,108 46 | Size=53,32 47 | Collapsed=0 48 | 49 | [Window][On Screen [ ] [ ] --- 0x0] 50 | Pos=270,138 51 | Size=836,457 52 | Collapsed=0 53 | 54 | [Window][Victim list] 55 | Pos=0,754 56 | Size=961,263 57 | Collapsed=0 58 | DockId=0x00000005,0 59 | 60 | [Window][On Screen [DESKTOP-F0KAGCN] [10.168.154.112] --- 1718x858] 61 | Pos=210,62 62 | Size=1682,886 63 | Collapsed=0 64 | DockId=0x00000001,0 65 | 66 | [Window][gotya] 67 | Pos=0,20 68 | Size=1184,470 69 | Collapsed=0 70 | DockId=0x00000001,0 71 | 72 | [Window][CONSOLE] 73 | Pos=963,754 74 | Size=957,263 75 | Collapsed=0 76 | DockId=0x00000006,0 77 | 78 | [Window][Screen Remote] 79 | Pos=0,20 80 | Size=1920,732 81 | Collapsed=0 82 | DockId=0x00000001,0 83 | 84 | [Window][victim list] 85 | Pos=889,20 86 | Size=295,527 87 | Collapsed=0 88 | DockId=0x0000000C,0 89 | 90 | [Window][screen remote] 91 | Pos=0,20 92 | Size=1623,821 93 | Collapsed=0 94 | DockId=0x0000000B,0 95 | 96 | [Window][console] 97 | Pos=0,549 98 | Size=1184,112 99 | Collapsed=0 100 | DockId=0x0000000A,0 101 | 102 | [Window][@screen_remote] 103 | Pos=0,20 104 | Size=1410,840 105 | Collapsed=0 106 | DockId=0x0000000D,0 107 | 108 | [Window][@victim_list] 109 | Pos=1412,20 110 | Size=508,637 111 | Collapsed=0 112 | DockId=0x00000010,0 113 | 114 | [Window][@console] 115 | Pos=0,862 116 | Size=918,155 117 | Collapsed=0 118 | DockId=0x0000000E,0 119 | 120 | [Window][@admin_tools] 121 | Pos=920,862 122 | Size=490,155 123 | Collapsed=0 124 | DockId=0x0000000F,0 125 | 126 | [Window][@file_explorer] 127 | Pos=1412,659 128 | Size=508,358 129 | Collapsed=0 130 | DockId=0x00000011,0 131 | 132 | [Window][@consoleqq] 133 | Pos=762,252 134 | Size=199,83 135 | Collapsed=0 136 | 137 | [Window][Issue #1453] 138 | Pos=350,260 139 | Size=345,152 140 | Collapsed=0 141 | 142 | [Window][__changenickname] 143 | Pos=419,304 144 | Size=415,154 145 | Collapsed=0 146 | 147 | [Window][@change nickname] 148 | Pos=458,280 149 | Size=250,60 150 | Collapsed=0 151 | 152 | [Docking][Data] 153 | DockSpace ID=0x1FFEE512 Window=0xFFB0BD4B Pos=0,20 Size=1920,997 Split=X Selected=0xC75028AF 154 | DockNode ID=0x00000012 Parent=0x1FFEE512 SizeRef=869,997 Split=Y 155 | DockNode ID=0x00000009 Parent=0x00000012 SizeRef=1920,821 Split=Y 156 | DockNode ID=0x00000007 Parent=0x00000009 SizeRef=1920,470 Split=X 157 | DockNode ID=0x00000001 Parent=0x00000007 SizeRef=942,640 Split=X Selected=0x315A5DD9 158 | DockNode ID=0x0000000B Parent=0x00000001 SizeRef=1623,777 Split=Y Selected=0xB40C35AF 159 | DockNode ID=0x0000000D Parent=0x0000000B SizeRef=1582,840 CentralNode=1 Selected=0xB40C35AF 160 | DockNode ID=0x00000013 Parent=0x0000000B SizeRef=1582,155 Split=X Selected=0x6AE1E5FE 161 | DockNode ID=0x0000000E Parent=0x00000013 SizeRef=918,254 Selected=0xE7D00D4C 162 | DockNode ID=0x0000000F Parent=0x00000013 SizeRef=490,254 Selected=0x6AE1E5FE 163 | DockNode ID=0x0000000C Parent=0x00000001 SizeRef=295,777 Selected=0x131F395F 164 | DockNode ID=0x00000002 Parent=0x00000007 SizeRef=240,640 Split=Y Selected=0x4958B5D4 165 | DockNode ID=0x00000003 Parent=0x00000002 SizeRef=349,145 Selected=0x4958B5D4 166 | DockNode ID=0x00000004 Parent=0x00000002 SizeRef=349,493 Selected=0xE1A13178 167 | DockNode ID=0x00000008 Parent=0x00000009 SizeRef=1920,169 Split=X Selected=0x9583B688 168 | DockNode ID=0x00000005 Parent=0x00000008 SizeRef=592,169 Selected=0x9583B688 169 | DockNode ID=0x00000006 Parent=0x00000008 SizeRef=590,169 Selected=0x094631AC 170 | DockNode ID=0x0000000A Parent=0x00000012 SizeRef=1920,174 Selected=0x3603CFB6 171 | DockNode ID=0x00000014 Parent=0x1FFEE512 SizeRef=313,997 Split=Y Selected=0x48AC8E32 172 | DockNode ID=0x00000010 Parent=0x00000014 SizeRef=621,637 Selected=0x48AC8E32 173 | DockNode ID=0x00000011 Parent=0x00000014 SizeRef=621,358 Selected=0xC9D9EBC7 174 | 175 | -------------------------------------------------------------------------------- /cpp/imgui_dll.cpp: -------------------------------------------------------------------------------- 1 | // imgui_dll.cpp : Defines the exported functions for the DLL. 2 | // 3 | 4 | #include "pch.h" 5 | #include "framework.h" 6 | #include "imgui_dll.h" 7 | 8 | 9 | // This is an example of an exported variable 10 | IMGUIDLL_API int nimguidll=0; 11 | 12 | // This is an example of an exported function. 13 | IMGUIDLL_API int fnimguidll(void) 14 | { 15 | return 0; 16 | } 17 | 18 | // This is the constructor of a class that has been exported. 19 | Cimguidll::Cimguidll() 20 | { 21 | return; 22 | } 23 | -------------------------------------------------------------------------------- /cpp/imgui_dll.h: -------------------------------------------------------------------------------- 1 | // The following ifdef block is the standard way of creating macros which make exporting 2 | // from a DLL simpler. All files within this DLL are compiled with the IMGUIDLL_EXPORTS 3 | // symbol defined on the command line. This symbol should not be defined on any project 4 | // that uses this DLL. This way any other project whose source files include this file see 5 | // IMGUIDLL_API functions as being imported from a DLL, whereas this DLL sees symbols 6 | // defined with this macro as being exported. 7 | #ifdef IMGUIDLL_EXPORTS 8 | #define IMGUIDLL_API __declspec(dllexport) 9 | #else 10 | #define IMGUIDLL_API __declspec(dllimport) 11 | #endif 12 | 13 | // This class is exported from the dll 14 | class IMGUIDLL_API Cimguidll { 15 | public: 16 | Cimguidll(void); 17 | // TODO: add your methods here. 18 | }; 19 | 20 | extern IMGUIDLL_API int nimguidll; 21 | 22 | IMGUIDLL_API int fnimguidll(void); 23 | -------------------------------------------------------------------------------- /cpp/imgui_dll.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {CBDD3AB9-F6EA-4674-8C33-8DED899A1EFD} 24 | Win32Proj 25 | imguidll 26 | 10.0.16299.0 27 | 28 | 29 | 30 | DynamicLibrary 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | DynamicLibrary 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | DynamicLibrary 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | IMGUIDLL 75 | true 76 | 77 | 78 | IMGUIDLL 79 | true 80 | 81 | 82 | IMGUIDLL 83 | false 84 | 85 | 86 | imgui 87 | false 88 | 89 | 90 | 91 | Use 92 | Level3 93 | true 94 | WIN32;_DEBUG;IMGUIDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 95 | true 96 | pch.h 97 | 98 | 99 | Windows 100 | true 101 | false 102 | 103 | 104 | 105 | 106 | Use 107 | Level3 108 | true 109 | _DEBUG;IMGUIDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 110 | true 111 | pch.h 112 | 113 | 114 | Windows 115 | true 116 | false 117 | 118 | 119 | 120 | 121 | NotUsing 122 | Level3 123 | true 124 | true 125 | true 126 | WIN32;NDEBUG;IMGUIDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 127 | true 128 | pch.h 129 | ..\..;..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include; 130 | MultiThreaded 131 | 132 | 133 | Windows 134 | true 135 | true 136 | true 137 | false 138 | $(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories) 139 | d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) 140 | $(OutDir)\imgui.dll 141 | 142 | 143 | 144 | 145 | NotUsing 146 | Level3 147 | true 148 | true 149 | true 150 | NDEBUG;IMGUIDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 151 | true 152 | pch.h 153 | ..\..;..;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include; 154 | MultiThreaded 155 | false 156 | 157 | 158 | Windows 159 | true 160 | true 161 | true 162 | false 163 | $(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories) 164 | d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | Create 195 | Create 196 | Create 197 | Create 198 | 199 | 200 | 201 | 202 | 203 | -------------------------------------------------------------------------------- /cpp/imgui_dll.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 10 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 11 | 12 | 13 | {ff31c20c-f8b2-479e-9851-ec8cb1fe0b6c} 14 | 15 | 16 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 17 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | imgui\Header Files 26 | 27 | 28 | imgui\Header Files 29 | 30 | 31 | imgui\Header Files 32 | 33 | 34 | imgui 35 | 36 | 37 | imgui 38 | 39 | 40 | imgui 41 | 42 | 43 | imgui 44 | 45 | 46 | imgui 47 | 48 | 49 | imgui 50 | 51 | 52 | imgui 53 | 54 | 55 | 56 | 57 | Source Files 58 | 59 | 60 | Source Files 61 | 62 | 63 | Source Files 64 | 65 | 66 | imgui 67 | 68 | 69 | imgui 70 | 71 | 72 | imgui 73 | 74 | 75 | imgui 76 | 77 | 78 | imgui 79 | 80 | 81 | imgui 82 | 83 | 84 | imgui 85 | 86 | 87 | imgui 88 | 89 | 90 | -------------------------------------------------------------------------------- /cpp/imgui_dll.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /cpp/imgui_impl_dx11.cpp: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer for DirectX11 2 | // This needs to be used along with a Platform Binding (e.g. Win32) 3 | 4 | // Implemented features: 5 | // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! 6 | // [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. 7 | // [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. 8 | 9 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 10 | // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp 11 | // https://github.com/ocornut/imgui 12 | 13 | // CHANGELOG 14 | // (minor and older changes stripped away, please see git history for details) 15 | // 2020-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. 16 | // 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled). 17 | // 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore. 18 | // 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. 19 | // 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. 20 | // 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile(). 21 | // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. 22 | // 2018-08-01: DirectX11: Querying for IDXGIFactory instead of IDXGIFactory1 to increase compatibility. 23 | // 2018-07-13: DirectX11: Fixed unreleased resources in Init and Shutdown functions. 24 | // 2018-06-08: Misc: Extracted imgui_impl_dx11.cpp/.h away from the old combined DX11+Win32 example. 25 | // 2018-06-08: DirectX11: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. 26 | // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself. 27 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 28 | // 2016-05-07: DirectX11: Disabling depth-write. 29 | 30 | #include "imgui.h" 31 | #include "imgui_impl_dx11.h" 32 | 33 | // DirectX 34 | #include 35 | #include 36 | #include 37 | #ifdef _MSC_VER 38 | #pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below. 39 | #endif 40 | 41 | // DirectX data 42 | static ID3D11Device* g_pd3dDevice = NULL; 43 | static ID3D11DeviceContext* g_pd3dDeviceContext = NULL; 44 | static IDXGIFactory* g_pFactory = NULL; 45 | static ID3D11Buffer* g_pVB = NULL; 46 | static ID3D11Buffer* g_pIB = NULL; 47 | static ID3D11VertexShader* g_pVertexShader = NULL; 48 | static ID3D11InputLayout* g_pInputLayout = NULL; 49 | static ID3D11Buffer* g_pVertexConstantBuffer = NULL; 50 | static ID3D11PixelShader* g_pPixelShader = NULL; 51 | static ID3D11SamplerState* g_pFontSampler = NULL; 52 | static ID3D11ShaderResourceView*g_pFontTextureView = NULL; 53 | static ID3D11RasterizerState* g_pRasterizerState = NULL; 54 | static ID3D11BlendState* g_pBlendState = NULL; 55 | static ID3D11DepthStencilState* g_pDepthStencilState = NULL; 56 | static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000; 57 | 58 | struct VERTEX_CONSTANT_BUFFER 59 | { 60 | float mvp[4][4]; 61 | }; 62 | 63 | // Forward Declarations 64 | static void ImGui_ImplDX11_InitPlatformInterface(); 65 | static void ImGui_ImplDX11_ShutdownPlatformInterface(); 66 | 67 | static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx) 68 | { 69 | // Setup viewport 70 | D3D11_VIEWPORT vp; 71 | memset(&vp, 0, sizeof(D3D11_VIEWPORT)); 72 | vp.Width = draw_data->DisplaySize.x; 73 | vp.Height = draw_data->DisplaySize.y; 74 | vp.MinDepth = 0.0f; 75 | vp.MaxDepth = 1.0f; 76 | vp.TopLeftX = vp.TopLeftY = 0; 77 | ctx->RSSetViewports(1, &vp); 78 | 79 | // Setup shader and vertex buffers 80 | unsigned int stride = sizeof(ImDrawVert); 81 | unsigned int offset = 0; 82 | ctx->IASetInputLayout(g_pInputLayout); 83 | ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); 84 | ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); 85 | ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 86 | ctx->VSSetShader(g_pVertexShader, NULL, 0); 87 | ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer); 88 | ctx->PSSetShader(g_pPixelShader, NULL, 0); 89 | ctx->PSSetSamplers(0, 1, &g_pFontSampler); 90 | ctx->GSSetShader(NULL, NULL, 0); 91 | ctx->HSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used.. 92 | ctx->DSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used.. 93 | ctx->CSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used.. 94 | 95 | // Setup blend state 96 | const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f }; 97 | ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff); 98 | ctx->OMSetDepthStencilState(g_pDepthStencilState, 0); 99 | ctx->RSSetState(g_pRasterizerState); 100 | } 101 | 102 | // Render function 103 | // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) 104 | void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) 105 | { 106 | // Avoid rendering when minimized 107 | if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) 108 | return; 109 | 110 | ID3D11DeviceContext* ctx = g_pd3dDeviceContext; 111 | 112 | // Create and grow vertex/index buffers if needed 113 | if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) 114 | { 115 | if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } 116 | g_VertexBufferSize = draw_data->TotalVtxCount + 5000; 117 | D3D11_BUFFER_DESC desc; 118 | memset(&desc, 0, sizeof(D3D11_BUFFER_DESC)); 119 | desc.Usage = D3D11_USAGE_DYNAMIC; 120 | desc.ByteWidth = g_VertexBufferSize * sizeof(ImDrawVert); 121 | desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; 122 | desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 123 | desc.MiscFlags = 0; 124 | if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVB) < 0) 125 | return; 126 | } 127 | if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount) 128 | { 129 | if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } 130 | g_IndexBufferSize = draw_data->TotalIdxCount + 10000; 131 | D3D11_BUFFER_DESC desc; 132 | memset(&desc, 0, sizeof(D3D11_BUFFER_DESC)); 133 | desc.Usage = D3D11_USAGE_DYNAMIC; 134 | desc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx); 135 | desc.BindFlags = D3D11_BIND_INDEX_BUFFER; 136 | desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 137 | if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pIB) < 0) 138 | return; 139 | } 140 | 141 | // Upload vertex/index data into a single contiguous GPU buffer 142 | D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource; 143 | if (ctx->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK) 144 | return; 145 | if (ctx->Map(g_pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK) 146 | return; 147 | ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData; 148 | ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData; 149 | for (int n = 0; n < draw_data->CmdListsCount; n++) 150 | { 151 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 152 | memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); 153 | memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); 154 | vtx_dst += cmd_list->VtxBuffer.Size; 155 | idx_dst += cmd_list->IdxBuffer.Size; 156 | } 157 | ctx->Unmap(g_pVB, 0); 158 | ctx->Unmap(g_pIB, 0); 159 | 160 | // Setup orthographic projection matrix into our constant buffer 161 | // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. 162 | { 163 | D3D11_MAPPED_SUBRESOURCE mapped_resource; 164 | if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) 165 | return; 166 | VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData; 167 | float L = draw_data->DisplayPos.x; 168 | float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; 169 | float T = draw_data->DisplayPos.y; 170 | float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; 171 | float mvp[4][4] = 172 | { 173 | { 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, 174 | { 0.0f, 2.0f/(T-B), 0.0f, 0.0f }, 175 | { 0.0f, 0.0f, 0.5f, 0.0f }, 176 | { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, 177 | }; 178 | memcpy(&constant_buffer->mvp, mvp, sizeof(mvp)); 179 | ctx->Unmap(g_pVertexConstantBuffer, 0); 180 | } 181 | 182 | // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!) 183 | struct BACKUP_DX11_STATE 184 | { 185 | UINT ScissorRectsCount, ViewportsCount; 186 | D3D11_RECT ScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; 187 | D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; 188 | ID3D11RasterizerState* RS; 189 | ID3D11BlendState* BlendState; 190 | FLOAT BlendFactor[4]; 191 | UINT SampleMask; 192 | UINT StencilRef; 193 | ID3D11DepthStencilState* DepthStencilState; 194 | ID3D11ShaderResourceView* PSShaderResource; 195 | ID3D11SamplerState* PSSampler; 196 | ID3D11PixelShader* PS; 197 | ID3D11VertexShader* VS; 198 | ID3D11GeometryShader* GS; 199 | UINT PSInstancesCount, VSInstancesCount, GSInstancesCount; 200 | ID3D11ClassInstance *PSInstances[256], *VSInstances[256], *GSInstances[256]; // 256 is max according to PSSetShader documentation 201 | D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology; 202 | ID3D11Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer; 203 | UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset; 204 | DXGI_FORMAT IndexBufferFormat; 205 | ID3D11InputLayout* InputLayout; 206 | }; 207 | BACKUP_DX11_STATE old; 208 | old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; 209 | ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects); 210 | ctx->RSGetViewports(&old.ViewportsCount, old.Viewports); 211 | ctx->RSGetState(&old.RS); 212 | ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask); 213 | ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef); 214 | ctx->PSGetShaderResources(0, 1, &old.PSShaderResource); 215 | ctx->PSGetSamplers(0, 1, &old.PSSampler); 216 | old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256; 217 | ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount); 218 | ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount); 219 | ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer); 220 | ctx->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount); 221 | 222 | ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology); 223 | ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset); 224 | ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); 225 | ctx->IAGetInputLayout(&old.InputLayout); 226 | 227 | // Setup desired DX state 228 | ImGui_ImplDX11_SetupRenderState(draw_data, ctx); 229 | 230 | // Render command lists 231 | // (Because we merged all buffers into a single one, we maintain our own offset into them) 232 | int global_idx_offset = 0; 233 | int global_vtx_offset = 0; 234 | ImVec2 clip_off = draw_data->DisplayPos; 235 | for (int n = 0; n < draw_data->CmdListsCount; n++) 236 | { 237 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 238 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) 239 | { 240 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; 241 | if (pcmd->UserCallback != NULL) 242 | { 243 | // User callback, registered via ImDrawList::AddCallback() 244 | // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) 245 | if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) 246 | ImGui_ImplDX11_SetupRenderState(draw_data, ctx); 247 | else 248 | pcmd->UserCallback(cmd_list, pcmd); 249 | } 250 | else 251 | { 252 | // Apply scissor/clipping rectangle 253 | const D3D11_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) }; 254 | ctx->RSSetScissorRects(1, &r); 255 | 256 | // Bind texture, Draw 257 | ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->TextureId; 258 | ctx->PSSetShaderResources(0, 1, &texture_srv); 259 | ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset); 260 | } 261 | } 262 | global_idx_offset += cmd_list->IdxBuffer.Size; 263 | global_vtx_offset += cmd_list->VtxBuffer.Size; 264 | } 265 | 266 | // Restore modified DX state 267 | ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects); 268 | ctx->RSSetViewports(old.ViewportsCount, old.Viewports); 269 | ctx->RSSetState(old.RS); if (old.RS) old.RS->Release(); 270 | ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release(); 271 | ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release(); 272 | ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release(); 273 | ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release(); 274 | ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release(); 275 | for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release(); 276 | ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release(); 277 | ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release(); 278 | ctx->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release(); 279 | for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release(); 280 | ctx->IASetPrimitiveTopology(old.PrimitiveTopology); 281 | ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release(); 282 | ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release(); 283 | ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); 284 | } 285 | 286 | static void ImGui_ImplDX11_CreateFontsTexture() 287 | { 288 | // Build texture atlas 289 | ImGuiIO& io = ImGui::GetIO(); 290 | unsigned char* pixels; 291 | int width, height; 292 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); 293 | 294 | // Upload texture to graphics system 295 | { 296 | D3D11_TEXTURE2D_DESC desc; 297 | ZeroMemory(&desc, sizeof(desc)); 298 | desc.Width = width; 299 | desc.Height = height; 300 | desc.MipLevels = 1; 301 | desc.ArraySize = 1; 302 | desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 303 | desc.SampleDesc.Count = 1; 304 | desc.Usage = D3D11_USAGE_DEFAULT; 305 | desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; 306 | desc.CPUAccessFlags = 0; 307 | 308 | ID3D11Texture2D* pTexture = NULL; 309 | D3D11_SUBRESOURCE_DATA subResource; 310 | subResource.pSysMem = pixels; 311 | subResource.SysMemPitch = desc.Width * 4; 312 | subResource.SysMemSlicePitch = 0; 313 | g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture); 314 | 315 | // Create texture view 316 | D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 317 | ZeroMemory(&srvDesc, sizeof(srvDesc)); 318 | srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 319 | srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; 320 | srvDesc.Texture2D.MipLevels = desc.MipLevels; 321 | srvDesc.Texture2D.MostDetailedMip = 0; 322 | g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView); 323 | pTexture->Release(); 324 | } 325 | 326 | // Store our identifier 327 | io.Fonts->TexID = (ImTextureID)g_pFontTextureView; 328 | 329 | // Create texture sampler 330 | { 331 | D3D11_SAMPLER_DESC desc; 332 | ZeroMemory(&desc, sizeof(desc)); 333 | desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; 334 | desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; 335 | desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; 336 | desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; 337 | desc.MipLODBias = 0.f; 338 | desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; 339 | desc.MinLOD = 0.f; 340 | desc.MaxLOD = 0.f; 341 | g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler); 342 | } 343 | } 344 | 345 | bool ImGui_ImplDX11_CreateDeviceObjects() 346 | { 347 | if (!g_pd3dDevice) 348 | return false; 349 | if (g_pFontSampler) 350 | ImGui_ImplDX11_InvalidateDeviceObjects(); 351 | 352 | // By using D3DCompile() from / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A) 353 | // If you would like to use this DX11 sample code but remove this dependency you can: 354 | // 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution] 355 | // 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL. 356 | // See https://github.com/ocornut/imgui/pull/638 for sources and details. 357 | 358 | // Create the vertex shader 359 | { 360 | static const char* vertexShader = 361 | "cbuffer vertexBuffer : register(b0) \ 362 | {\ 363 | float4x4 ProjectionMatrix; \ 364 | };\ 365 | struct VS_INPUT\ 366 | {\ 367 | float2 pos : POSITION;\ 368 | float4 col : COLOR0;\ 369 | float2 uv : TEXCOORD0;\ 370 | };\ 371 | \ 372 | struct PS_INPUT\ 373 | {\ 374 | float4 pos : SV_POSITION;\ 375 | float4 col : COLOR0;\ 376 | float2 uv : TEXCOORD0;\ 377 | };\ 378 | \ 379 | PS_INPUT main(VS_INPUT input)\ 380 | {\ 381 | PS_INPUT output;\ 382 | output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\ 383 | output.col = input.col;\ 384 | output.uv = input.uv;\ 385 | return output;\ 386 | }"; 387 | 388 | ID3DBlob* vertexShaderBlob; 389 | if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &vertexShaderBlob, NULL))) 390 | return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! 391 | if (g_pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK) 392 | { 393 | vertexShaderBlob->Release(); 394 | return false; 395 | } 396 | 397 | // Create the input layout 398 | D3D11_INPUT_ELEMENT_DESC local_layout[] = 399 | { 400 | { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, 401 | { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, 402 | { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, 403 | }; 404 | if (g_pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) 405 | { 406 | vertexShaderBlob->Release(); 407 | return false; 408 | } 409 | vertexShaderBlob->Release(); 410 | 411 | // Create the constant buffer 412 | { 413 | D3D11_BUFFER_DESC desc; 414 | desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); 415 | desc.Usage = D3D11_USAGE_DYNAMIC; 416 | desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; 417 | desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 418 | desc.MiscFlags = 0; 419 | g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVertexConstantBuffer); 420 | } 421 | } 422 | 423 | // Create the pixel shader 424 | { 425 | static const char* pixelShader = 426 | "struct PS_INPUT\ 427 | {\ 428 | float4 pos : SV_POSITION;\ 429 | float4 col : COLOR0;\ 430 | float2 uv : TEXCOORD0;\ 431 | };\ 432 | sampler sampler0;\ 433 | Texture2D texture0;\ 434 | \ 435 | float4 main(PS_INPUT input) : SV_Target\ 436 | {\ 437 | float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \ 438 | return out_col; \ 439 | }"; 440 | 441 | ID3DBlob* pixelShaderBlob; 442 | if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &pixelShaderBlob, NULL))) 443 | return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! 444 | if (g_pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK) 445 | { 446 | pixelShaderBlob->Release(); 447 | return false; 448 | } 449 | pixelShaderBlob->Release(); 450 | } 451 | 452 | // Create the blending setup 453 | { 454 | D3D11_BLEND_DESC desc; 455 | ZeroMemory(&desc, sizeof(desc)); 456 | desc.AlphaToCoverageEnable = false; 457 | desc.RenderTarget[0].BlendEnable = true; 458 | desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; 459 | desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; 460 | desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; 461 | desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; 462 | desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; 463 | desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; 464 | desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; 465 | g_pd3dDevice->CreateBlendState(&desc, &g_pBlendState); 466 | } 467 | 468 | // Create the rasterizer state 469 | { 470 | D3D11_RASTERIZER_DESC desc; 471 | ZeroMemory(&desc, sizeof(desc)); 472 | desc.FillMode = D3D11_FILL_SOLID; 473 | desc.CullMode = D3D11_CULL_NONE; 474 | desc.ScissorEnable = true; 475 | desc.DepthClipEnable = true; 476 | g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState); 477 | } 478 | 479 | // Create depth-stencil State 480 | { 481 | D3D11_DEPTH_STENCIL_DESC desc; 482 | ZeroMemory(&desc, sizeof(desc)); 483 | desc.DepthEnable = false; 484 | desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; 485 | desc.DepthFunc = D3D11_COMPARISON_ALWAYS; 486 | desc.StencilEnable = false; 487 | desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; 488 | desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; 489 | desc.BackFace = desc.FrontFace; 490 | g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState); 491 | } 492 | 493 | ImGui_ImplDX11_CreateFontsTexture(); 494 | 495 | return true; 496 | } 497 | 498 | void ImGui_ImplDX11_InvalidateDeviceObjects() 499 | { 500 | if (!g_pd3dDevice) 501 | return; 502 | 503 | if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; } 504 | if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well. 505 | if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } 506 | if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } 507 | 508 | if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; } 509 | if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; } 510 | if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; } 511 | if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; } 512 | if (g_pVertexConstantBuffer) { g_pVertexConstantBuffer->Release(); g_pVertexConstantBuffer = NULL; } 513 | if (g_pInputLayout) { g_pInputLayout->Release(); g_pInputLayout = NULL; } 514 | if (g_pVertexShader) { g_pVertexShader->Release(); g_pVertexShader = NULL; } 515 | } 516 | 517 | bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context) 518 | { 519 | // Setup back-end capabilities flags 520 | ImGuiIO& io = ImGui::GetIO(); 521 | io.BackendRendererName = "imgui_impl_dx11"; 522 | io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. 523 | io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional) 524 | 525 | // Get factory from device 526 | IDXGIDevice* pDXGIDevice = NULL; 527 | IDXGIAdapter* pDXGIAdapter = NULL; 528 | IDXGIFactory* pFactory = NULL; 529 | 530 | if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK) 531 | if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK) 532 | if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK) 533 | { 534 | g_pd3dDevice = device; 535 | g_pd3dDeviceContext = device_context; 536 | g_pFactory = pFactory; 537 | } 538 | if (pDXGIDevice) pDXGIDevice->Release(); 539 | if (pDXGIAdapter) pDXGIAdapter->Release(); 540 | g_pd3dDevice->AddRef(); 541 | g_pd3dDeviceContext->AddRef(); 542 | 543 | if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 544 | ImGui_ImplDX11_InitPlatformInterface(); 545 | 546 | return true; 547 | } 548 | 549 | void ImGui_ImplDX11_Shutdown() 550 | { 551 | ImGui_ImplDX11_ShutdownPlatformInterface(); 552 | ImGui_ImplDX11_InvalidateDeviceObjects(); 553 | if (g_pFactory) { g_pFactory->Release(); g_pFactory = NULL; } 554 | if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } 555 | if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = NULL; } 556 | } 557 | 558 | void ImGui_ImplDX11_NewFrame() 559 | { 560 | if (!g_pFontSampler) 561 | ImGui_ImplDX11_CreateDeviceObjects(); 562 | } 563 | 564 | //-------------------------------------------------------------------------------------------------------- 565 | // MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT 566 | // This is an _advanced_ and _optional_ feature, allowing the back-end to create and handle multiple viewports simultaneously. 567 | // If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. 568 | //-------------------------------------------------------------------------------------------------------- 569 | 570 | // Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data. 571 | struct ImGuiViewportDataDx11 572 | { 573 | IDXGISwapChain* SwapChain; 574 | ID3D11RenderTargetView* RTView; 575 | 576 | ImGuiViewportDataDx11() { SwapChain = NULL; RTView = NULL; } 577 | ~ImGuiViewportDataDx11() { IM_ASSERT(SwapChain == NULL && RTView == NULL); } 578 | }; 579 | 580 | static void ImGui_ImplDX11_CreateWindow(ImGuiViewport* viewport) 581 | { 582 | ImGuiViewportDataDx11* data = IM_NEW(ImGuiViewportDataDx11)(); 583 | viewport->RendererUserData = data; 584 | 585 | // PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*). 586 | // Some back-end will leave PlatformHandleRaw NULL, in which case we assume PlatformHandle will contain the HWND. 587 | HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle; 588 | IM_ASSERT(hwnd != 0); 589 | 590 | // Create swap chain 591 | DXGI_SWAP_CHAIN_DESC sd; 592 | ZeroMemory(&sd, sizeof(sd)); 593 | sd.BufferDesc.Width = (UINT)viewport->Size.x; 594 | sd.BufferDesc.Height = (UINT)viewport->Size.y; 595 | sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 596 | sd.SampleDesc.Count = 1; 597 | sd.SampleDesc.Quality = 0; 598 | sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 599 | sd.BufferCount = 1; 600 | sd.OutputWindow = hwnd; 601 | sd.Windowed = TRUE; 602 | sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; 603 | sd.Flags = 0; 604 | 605 | IM_ASSERT(data->SwapChain == NULL && data->RTView == NULL); 606 | g_pFactory->CreateSwapChain(g_pd3dDevice, &sd, &data->SwapChain); 607 | 608 | // Create the render target 609 | if (data->SwapChain) 610 | { 611 | ID3D11Texture2D* pBackBuffer; 612 | data->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); 613 | g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &data->RTView); 614 | pBackBuffer->Release(); 615 | } 616 | } 617 | 618 | static void ImGui_ImplDX11_DestroyWindow(ImGuiViewport* viewport) 619 | { 620 | // The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it. 621 | if (ImGuiViewportDataDx11* data = (ImGuiViewportDataDx11*)viewport->RendererUserData) 622 | { 623 | if (data->SwapChain) 624 | data->SwapChain->Release(); 625 | data->SwapChain = NULL; 626 | if (data->RTView) 627 | data->RTView->Release(); 628 | data->RTView = NULL; 629 | IM_DELETE(data); 630 | } 631 | viewport->RendererUserData = NULL; 632 | } 633 | 634 | static void ImGui_ImplDX11_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) 635 | { 636 | ImGuiViewportDataDx11* data = (ImGuiViewportDataDx11*)viewport->RendererUserData; 637 | if (data->RTView) 638 | { 639 | data->RTView->Release(); 640 | data->RTView = NULL; 641 | } 642 | if (data->SwapChain) 643 | { 644 | ID3D11Texture2D* pBackBuffer = NULL; 645 | data->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0); 646 | data->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); 647 | if (pBackBuffer == NULL) { fprintf(stderr, "ImGui_ImplDX11_SetWindowSize() failed creating buffers.\n"); return; } 648 | g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &data->RTView); 649 | pBackBuffer->Release(); 650 | } 651 | } 652 | 653 | static void ImGui_ImplDX11_RenderWindow(ImGuiViewport* viewport, void*) 654 | { 655 | ImGuiViewportDataDx11* data = (ImGuiViewportDataDx11*)viewport->RendererUserData; 656 | ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); 657 | g_pd3dDeviceContext->OMSetRenderTargets(1, &data->RTView, NULL); 658 | if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear)) 659 | g_pd3dDeviceContext->ClearRenderTargetView(data->RTView, (float*)&clear_color); 660 | ImGui_ImplDX11_RenderDrawData(viewport->DrawData); 661 | } 662 | 663 | static void ImGui_ImplDX11_SwapBuffers(ImGuiViewport* viewport, void*) 664 | { 665 | ImGuiViewportDataDx11* data = (ImGuiViewportDataDx11*)viewport->RendererUserData; 666 | data->SwapChain->Present(0, 0); // Present without vsync 667 | } 668 | 669 | static void ImGui_ImplDX11_InitPlatformInterface() 670 | { 671 | ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); 672 | platform_io.Renderer_CreateWindow = ImGui_ImplDX11_CreateWindow; 673 | platform_io.Renderer_DestroyWindow = ImGui_ImplDX11_DestroyWindow; 674 | platform_io.Renderer_SetWindowSize = ImGui_ImplDX11_SetWindowSize; 675 | platform_io.Renderer_RenderWindow = ImGui_ImplDX11_RenderWindow; 676 | platform_io.Renderer_SwapBuffers = ImGui_ImplDX11_SwapBuffers; 677 | } 678 | 679 | static void ImGui_ImplDX11_ShutdownPlatformInterface() 680 | { 681 | ImGui::DestroyPlatformWindows(); 682 | } 683 | -------------------------------------------------------------------------------- /cpp/imgui_impl_dx11.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer for DirectX11 2 | // This needs to be used along with a Platform Binding (e.g. Win32) 3 | 4 | // Implemented features: 5 | // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! 6 | // [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. 7 | // [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices. 8 | 9 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 10 | // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. 11 | // https://github.com/ocornut/imgui 12 | 13 | #pragma once 14 | #include "imgui.h" // IMGUI_IMPL_API 15 | 16 | struct ID3D11Device; 17 | struct ID3D11DeviceContext; 18 | 19 | IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context); 20 | IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown(); 21 | IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame(); 22 | IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data); 23 | 24 | // Use if you want to reset your rendering device without losing Dear ImGui state. 25 | IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects(); 26 | IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects(); 27 | -------------------------------------------------------------------------------- /cpp/imgui_impl_win32.cpp: -------------------------------------------------------------------------------- 1 | // dear imgui: Platform Binding for Windows (standard windows API for 32 and 64 bits applications) 2 | // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) 3 | 4 | // Implemented features: 5 | // [X] Platform: Clipboard support (for Win32 this is actually part of core imgui) 6 | // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 7 | // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). 8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 9 | // [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. 10 | 11 | #include "imgui.h" 12 | #include "imgui_impl_win32.h" 13 | #ifndef WIN32_LEAN_AND_MEAN 14 | #define WIN32_LEAN_AND_MEAN 15 | #endif 16 | #include 17 | #include 18 | #include 19 | 20 | // CHANGELOG 21 | // (minor and older changes stripped away, please see git history for details) 22 | // 2018-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. 23 | // 2019-05-11: Inputs: Don't filter value from WM_CHAR before calling AddInputCharacter(). 24 | // 2019-01-17: Misc: Using GetForegroundWindow()+IsChild() instead of GetActiveWindow() to be compatible with windows created in a different thread or parent. 25 | // 2019-01-17: Inputs: Added support for mouse buttons 4 and 5 via WM_XBUTTON* messages. 26 | // 2019-01-15: Inputs: Added support for XInput gamepads (if ImGuiConfigFlags_NavEnableGamepad is set by user application). 27 | // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. 28 | // 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. 29 | // 2018-06-10: Inputs: Fixed handling of mouse wheel messages to support fine position messages (typically sent by track-pads). 30 | // 2018-06-08: Misc: Extracted imgui_impl_win32.cpp/.h away from the old combined DX9/DX10/DX11/DX12 examples. 31 | // 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors and ImGuiBackendFlags_HasSetMousePos flags + honor ImGuiConfigFlags_NoMouseCursorChange flag. 32 | // 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). 33 | // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. 34 | // 2018-02-06: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set). 35 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 36 | // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. 37 | // 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert. 38 | // 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag. 39 | // 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read. 40 | // 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging. 41 | // 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCursor is set. 42 | 43 | // Win32 Data 44 | static HWND g_hWnd = 0; 45 | static INT64 g_Time = 0; 46 | static INT64 g_TicksPerSecond = 0; 47 | static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT; 48 | static bool g_HasGamepad = false; 49 | static bool g_WantUpdateHasGamepad = true; 50 | static bool g_WantUpdateMonitors = true; 51 | 52 | // Forward Declarations 53 | static void ImGui_ImplWin32_InitPlatformInterface(); 54 | static void ImGui_ImplWin32_ShutdownPlatformInterface(); 55 | static void ImGui_ImplWin32_UpdateMonitors(); 56 | 57 | // Functions 58 | bool ImGui_ImplWin32_Init(void* hwnd) 59 | { 60 | if (!::QueryPerformanceFrequency((LARGE_INTEGER *)&g_TicksPerSecond)) 61 | return false; 62 | if (!::QueryPerformanceCounter((LARGE_INTEGER *)&g_Time)) 63 | return false; 64 | 65 | // Setup back-end capabilities flags 66 | ImGuiIO& io = ImGui::GetIO(); 67 | io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) 68 | io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) 69 | io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) 70 | io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can set io.MouseHoveredViewport correctly (optional, not easy) 71 | io.BackendPlatformName = "imgui_impl_win32"; 72 | 73 | // Our mouse update function expect PlatformHandle to be filled for the main viewport 74 | g_hWnd = (HWND)hwnd; 75 | ImGuiViewport* main_viewport = ImGui::GetMainViewport(); 76 | main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (void*)g_hWnd; 77 | if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 78 | ImGui_ImplWin32_InitPlatformInterface(); 79 | 80 | // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime. 81 | io.KeyMap[ImGuiKey_Tab] = VK_TAB; 82 | io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; 83 | io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; 84 | io.KeyMap[ImGuiKey_UpArrow] = VK_UP; 85 | io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN; 86 | io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR; 87 | io.KeyMap[ImGuiKey_PageDown] = VK_NEXT; 88 | io.KeyMap[ImGuiKey_Home] = VK_HOME; 89 | io.KeyMap[ImGuiKey_End] = VK_END; 90 | io.KeyMap[ImGuiKey_Insert] = VK_INSERT; 91 | io.KeyMap[ImGuiKey_Delete] = VK_DELETE; 92 | io.KeyMap[ImGuiKey_Backspace] = VK_BACK; 93 | io.KeyMap[ImGuiKey_Space] = VK_SPACE; 94 | io.KeyMap[ImGuiKey_Enter] = VK_RETURN; 95 | io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE; 96 | io.KeyMap[ImGuiKey_KeyPadEnter] = VK_RETURN; 97 | io.KeyMap[ImGuiKey_A] = 'A'; 98 | io.KeyMap[ImGuiKey_C] = 'C'; 99 | io.KeyMap[ImGuiKey_V] = 'V'; 100 | io.KeyMap[ImGuiKey_X] = 'X'; 101 | io.KeyMap[ImGuiKey_Y] = 'Y'; 102 | io.KeyMap[ImGuiKey_Z] = 'Z'; 103 | 104 | return true; 105 | } 106 | 107 | void ImGui_ImplWin32_Shutdown() 108 | { 109 | ImGui_ImplWin32_ShutdownPlatformInterface(); 110 | g_hWnd = (HWND)0; 111 | } 112 | 113 | static bool ImGui_ImplWin32_UpdateMouseCursor() 114 | { 115 | ImGuiIO& io = ImGui::GetIO(); 116 | if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) 117 | return false; 118 | 119 | ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); 120 | if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor) 121 | { 122 | // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor 123 | ::SetCursor(NULL); 124 | } 125 | else 126 | { 127 | // Show OS mouse cursor 128 | LPTSTR win32_cursor = IDC_ARROW; 129 | switch (imgui_cursor) 130 | { 131 | case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break; 132 | case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break; 133 | case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break; 134 | case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break; 135 | case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break; 136 | case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break; 137 | case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break; 138 | case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break; 139 | } 140 | ::SetCursor(::LoadCursor(NULL, win32_cursor)); 141 | } 142 | return true; 143 | } 144 | 145 | // This code supports multi-viewports (multiple OS Windows mapped into different Dear ImGui viewports) 146 | // Because of that, it is a little more complicated than your typical single-viewport binding code! 147 | static void ImGui_ImplWin32_UpdateMousePos() 148 | { 149 | ImGuiIO& io = ImGui::GetIO(); 150 | 151 | // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) 152 | // (When multi-viewports are enabled, all imgui positions are same as OS positions) 153 | if (io.WantSetMousePos) 154 | { 155 | POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; 156 | if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) == 0) 157 | ::ClientToScreen(g_hWnd, &pos); 158 | ::SetCursorPos(pos.x, pos.y); 159 | } 160 | 161 | io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); 162 | io.MouseHoveredViewport = 0; 163 | 164 | // Set imgui mouse position 165 | POINT mouse_screen_pos; 166 | if (!::GetCursorPos(&mouse_screen_pos)) 167 | return; 168 | if (HWND focused_hwnd = ::GetForegroundWindow()) 169 | { 170 | if (::IsChild(focused_hwnd, g_hWnd)) 171 | focused_hwnd = g_hWnd; 172 | if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 173 | { 174 | // Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor) 175 | // This is the position you can get with GetCursorPos(). In theory adding viewport->Pos is also the reverse operation of doing ScreenToClient(). 176 | if (ImGui::FindViewportByPlatformHandle((void*)focused_hwnd) != NULL) 177 | io.MousePos = ImVec2((float)mouse_screen_pos.x, (float)mouse_screen_pos.y); 178 | } 179 | else 180 | { 181 | // Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window.) 182 | // This is the position you can get with GetCursorPos() + ScreenToClient() or from WM_MOUSEMOVE. 183 | if (focused_hwnd == g_hWnd) 184 | { 185 | POINT mouse_client_pos = mouse_screen_pos; 186 | ::ScreenToClient(focused_hwnd, &mouse_client_pos); 187 | io.MousePos = ImVec2((float)mouse_client_pos.x, (float)mouse_client_pos.y); 188 | } 189 | } 190 | } 191 | 192 | // (Optional) When using multiple viewports: set io.MouseHoveredViewport to the viewport the OS mouse cursor is hovering. 193 | // Important: this information is not easy to provide and many high-level windowing library won't be able to provide it correctly, because 194 | // - This is _ignoring_ viewports with the ImGuiViewportFlags_NoInputs flag (pass-through windows). 195 | // - This is _regardless_ of whether another viewport is focused or being dragged from. 196 | // If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the back-end, imgui will ignore this field and infer the information by relying on the 197 | // rectangles and last focused time of every viewports it knows about. It will be unaware of foreign windows that may be sitting between or over your windows. 198 | if (HWND hovered_hwnd = ::WindowFromPoint(mouse_screen_pos)) 199 | if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hovered_hwnd)) 200 | if ((viewport->Flags & ImGuiViewportFlags_NoInputs) == 0) // FIXME: We still get our NoInputs window with WM_NCHITTEST/HTTRANSPARENT code when decorated? 201 | io.MouseHoveredViewport = viewport->ID; 202 | } 203 | 204 | #ifdef _MSC_VER 205 | #pragma comment(lib, "xinput") 206 | #endif 207 | 208 | // Gamepad navigation mapping 209 | static void ImGui_ImplWin32_UpdateGamepads() 210 | { 211 | ImGuiIO& io = ImGui::GetIO(); 212 | memset(io.NavInputs, 0, sizeof(io.NavInputs)); 213 | if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) 214 | return; 215 | 216 | // Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow. 217 | // Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE. 218 | if (g_WantUpdateHasGamepad) 219 | { 220 | XINPUT_CAPABILITIES caps; 221 | g_HasGamepad = (XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS); 222 | g_WantUpdateHasGamepad = false; 223 | } 224 | 225 | XINPUT_STATE xinput_state; 226 | io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; 227 | if (g_HasGamepad && XInputGetState(0, &xinput_state) == ERROR_SUCCESS) 228 | { 229 | const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad; 230 | io.BackendFlags |= ImGuiBackendFlags_HasGamepad; 231 | 232 | #define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; } 233 | #define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; } 234 | MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); // Cross / A 235 | MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); // Circle / B 236 | MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); // Square / X 237 | MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); // Triangle / Y 238 | MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); // D-Pad Left 239 | MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); // D-Pad Right 240 | MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); // D-Pad Up 241 | MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); // D-Pad Down 242 | MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB 243 | MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB 244 | MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB 245 | MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB 246 | MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768); 247 | MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); 248 | MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); 249 | MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767); 250 | #undef MAP_BUTTON 251 | #undef MAP_ANALOG 252 | } 253 | } 254 | 255 | void ImGui_ImplWin32_NewFrame() 256 | { 257 | ImGuiIO& io = ImGui::GetIO(); 258 | IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame()."); 259 | 260 | // Setup display size (every frame to accommodate for window resizing) 261 | RECT rect; 262 | ::GetClientRect(g_hWnd, &rect); 263 | io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); 264 | if (g_WantUpdateMonitors) 265 | ImGui_ImplWin32_UpdateMonitors(); 266 | 267 | // Setup time step 268 | INT64 current_time; 269 | ::QueryPerformanceCounter((LARGE_INTEGER *)¤t_time); 270 | io.DeltaTime = (float)(current_time - g_Time) / g_TicksPerSecond; 271 | g_Time = current_time; 272 | 273 | // Read keyboard modifiers inputs 274 | io.KeyCtrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; 275 | io.KeyShift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; 276 | io.KeyAlt = (::GetKeyState(VK_MENU) & 0x8000) != 0; 277 | io.KeySuper = false; 278 | // io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below. 279 | 280 | // Update OS mouse position 281 | ImGui_ImplWin32_UpdateMousePos(); 282 | 283 | // Update OS mouse cursor with the cursor requested by imgui 284 | ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); 285 | if (g_LastMouseCursor != mouse_cursor) 286 | { 287 | g_LastMouseCursor = mouse_cursor; 288 | ImGui_ImplWin32_UpdateMouseCursor(); 289 | } 290 | 291 | // Update game controllers (if enabled and available) 292 | ImGui_ImplWin32_UpdateGamepads(); 293 | } 294 | 295 | // Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions. 296 | #ifndef WM_MOUSEHWHEEL 297 | #define WM_MOUSEHWHEEL 0x020E 298 | #endif 299 | #ifndef DBT_DEVNODES_CHANGED 300 | #define DBT_DEVNODES_CHANGED 0x0007 301 | #endif 302 | 303 | // Process Win32 mouse/keyboard inputs. 304 | // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. 305 | // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. 306 | // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. 307 | // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. 308 | // PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds. 309 | // PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. 310 | #include 311 | IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 312 | { 313 | if (ImGui::GetCurrentContext() == NULL) 314 | return 0; 315 | 316 | ImGuiIO& io = ImGui::GetIO(); 317 | switch (msg) 318 | { 319 | case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: 320 | case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: 321 | case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: 322 | case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: 323 | { 324 | int button = 0; 325 | if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; } 326 | if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; } 327 | if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; } 328 | if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } 329 | if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL) 330 | ::SetCapture(hwnd); 331 | io.MouseDown[button] = true; 332 | return 0; 333 | } 334 | case WM_LBUTTONUP: 335 | case WM_RBUTTONUP: 336 | case WM_MBUTTONUP: 337 | case WM_XBUTTONUP: 338 | { 339 | int button = 0; 340 | if (msg == WM_LBUTTONUP) { button = 0; } 341 | if (msg == WM_RBUTTONUP) { button = 1; } 342 | if (msg == WM_MBUTTONUP) { button = 2; } 343 | if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } 344 | io.MouseDown[button] = false; 345 | if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd) 346 | ::ReleaseCapture(); 347 | return 0; 348 | } 349 | case WM_MOUSEWHEEL: 350 | io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; 351 | return 0; 352 | case WM_MOUSEHWHEEL: 353 | io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; 354 | return 0; 355 | case WM_KEYDOWN: 356 | case WM_SYSKEYDOWN: 357 | if (wParam < 256) 358 | io.KeysDown[wParam] = 1; 359 | return 0; 360 | case WM_KEYUP: 361 | case WM_SYSKEYUP: 362 | 363 | if (wParam < 256){ 364 | //if (wParam == 8) printf("%f", io.KeysDownDuration[wParam]); 365 | //if (io.KeysDownDuration[wParam] == -1) io.KeysDownDuration[wParam] = 0.5; 366 | io.KeysDown[wParam] = 0; 367 | } 368 | return 0; 369 | case WM_CHAR: 370 | // You can also use ToAscii()+GetKeyboardState() to retrieve characters. 371 | io.AddInputCharacter((unsigned int)wParam); 372 | return 0; 373 | case WM_SETCURSOR: 374 | if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor()) 375 | return 1; 376 | return 0; 377 | case WM_DEVICECHANGE: 378 | if ((UINT)wParam == DBT_DEVNODES_CHANGED) 379 | g_WantUpdateHasGamepad = true; 380 | return 0; 381 | case WM_DISPLAYCHANGE: 382 | g_WantUpdateMonitors = true; 383 | return 0; 384 | } 385 | return 0; 386 | } 387 | 388 | //-------------------------------------------------------------------------------------------------------- 389 | // DPI handling 390 | // Those in theory should be simple calls but Windows has multiple ways to handle DPI, and most of them 391 | // require recent Windows versions at runtime or recent Windows SDK at compile-time. Neither we want to depend on. 392 | // So we dynamically select and load those functions to avoid dependencies. This is the scheme successfully 393 | // used by GLFW (from which we borrowed some of the code here) and other applications aiming to be portable. 394 | //--------------------------------------------------------------------------------------------------------- 395 | // At this point ImGui_ImplWin32_EnableDpiAwareness() is just a helper called by main.cpp, we don't call it automatically. 396 | //--------------------------------------------------------------------------------------------------------- 397 | 398 | static BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp) 399 | { 400 | OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0,{ 0 }, sp }; 401 | DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR; 402 | ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL); 403 | cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL); 404 | cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); 405 | return VerifyVersionInfoW(&osvi, mask, cond); 406 | } 407 | #define IsWindows8Point1OrGreater() IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0) // _WIN32_WINNT_WINBLUE 408 | #define IsWindows10OrGreater() IsWindowsVersionOrGreater(HIBYTE(0x0A00), LOBYTE(0x0A00), 0) // _WIN32_WINNT_WIN10 409 | 410 | #ifndef DPI_ENUMS_DECLARED 411 | typedef enum { PROCESS_DPI_UNAWARE = 0, PROCESS_SYSTEM_DPI_AWARE = 1, PROCESS_PER_MONITOR_DPI_AWARE = 2 } PROCESS_DPI_AWARENESS; 412 | typedef enum { MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2, MDT_DEFAULT = MDT_EFFECTIVE_DPI } MONITOR_DPI_TYPE; 413 | #endif 414 | #ifndef _DPI_AWARENESS_CONTEXTS_ 415 | DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); 416 | #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE (DPI_AWARENESS_CONTEXT)-3 417 | #endif 418 | #ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 419 | #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 (DPI_AWARENESS_CONTEXT)-4 420 | #endif 421 | typedef HRESULT(WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); // Shcore.lib+dll, Windows 8.1 422 | typedef HRESULT(WINAPI * PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); // Shcore.lib+dll, Windows 8.1 423 | typedef DPI_AWARENESS_CONTEXT(WINAPI * PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib+dll, Windows 10 v1607 (Creators Update) 424 | 425 | void ImGui_ImplWin32_EnableDpiAwareness() 426 | { 427 | // if (IsWindows10OrGreater()) // FIXME-DPI: This needs a manifest to succeed. Instead we try to grab the function pointer. 428 | { 429 | static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process 430 | if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = (PFN_SetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "SetThreadDpiAwarenessContext")) 431 | { 432 | SetThreadDpiAwarenessContextFn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); 433 | return; 434 | } 435 | } 436 | if (IsWindows8Point1OrGreater()) 437 | { 438 | static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process 439 | if (PFN_SetProcessDpiAwareness SetProcessDpiAwarenessFn = (PFN_SetProcessDpiAwareness)::GetProcAddress(shcore_dll, "SetProcessDpiAwareness")) 440 | SetProcessDpiAwarenessFn(PROCESS_PER_MONITOR_DPI_AWARE); 441 | } 442 | else 443 | { 444 | SetProcessDPIAware(); 445 | } 446 | } 447 | 448 | #ifdef _MSC_VER 449 | #pragma comment(lib, "gdi32") // GetDeviceCaps() 450 | #endif 451 | 452 | float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor) 453 | { 454 | UINT xdpi = 96, ydpi = 96; 455 | if (::IsWindows8Point1OrGreater()) 456 | { 457 | static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process 458 | if (PFN_GetDpiForMonitor GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor")) 459 | GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi); 460 | } 461 | else 462 | { 463 | const HDC dc = ::GetDC(NULL); 464 | xdpi = ::GetDeviceCaps(dc, LOGPIXELSX); 465 | ydpi = ::GetDeviceCaps(dc, LOGPIXELSY); 466 | ::ReleaseDC(NULL, dc); 467 | } 468 | IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert! 469 | return xdpi / 96.0f; 470 | } 471 | 472 | float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd) 473 | { 474 | HMONITOR monitor = ::MonitorFromWindow((HWND)hwnd, MONITOR_DEFAULTTONEAREST); 475 | return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor); 476 | } 477 | 478 | //-------------------------------------------------------------------------------------------------------- 479 | // IME (Input Method Editor) basic support for e.g. Asian language users 480 | //-------------------------------------------------------------------------------------------------------- 481 | 482 | #if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS) && !defined(__GNUC__) 483 | #define HAS_WIN32_IME 1 484 | #include 485 | #ifdef _MSC_VER 486 | #pragma comment(lib, "imm32") 487 | #endif 488 | static void ImGui_ImplWin32_SetImeInputPos(ImGuiViewport* viewport, ImVec2 pos) 489 | { 490 | COMPOSITIONFORM cf = { CFS_FORCE_POSITION,{ (LONG)(pos.x - viewport->Pos.x), (LONG)(pos.y - viewport->Pos.y) },{ 0, 0, 0, 0 } }; 491 | if (HWND hwnd = (HWND)viewport->PlatformHandle) 492 | if (HIMC himc = ::ImmGetContext(hwnd)) 493 | { 494 | ::ImmSetCompositionWindow(himc, &cf); 495 | ::ImmReleaseContext(hwnd, himc); 496 | } 497 | } 498 | #else 499 | #define HAS_WIN32_IME 0 500 | #endif 501 | 502 | //-------------------------------------------------------------------------------------------------------- 503 | // MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT 504 | // This is an _advanced_ and _optional_ feature, allowing the back-end to create and handle multiple viewports simultaneously. 505 | // If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first.. 506 | //-------------------------------------------------------------------------------------------------------- 507 | 508 | struct ImGuiViewportDataWin32 509 | { 510 | HWND Hwnd; 511 | bool HwndOwned; 512 | DWORD DwStyle; 513 | DWORD DwExStyle; 514 | 515 | ImGuiViewportDataWin32() { Hwnd = NULL; HwndOwned = false; DwStyle = DwExStyle = 0; } 516 | ~ImGuiViewportDataWin32() { IM_ASSERT(Hwnd == NULL); } 517 | }; 518 | 519 | static void ImGui_ImplWin32_GetWin32StyleFromViewportFlags(ImGuiViewportFlags flags, DWORD* out_style, DWORD* out_ex_style) 520 | { 521 | if (flags & ImGuiViewportFlags_NoDecoration) 522 | *out_style = WS_POPUP; 523 | else 524 | *out_style = WS_OVERLAPPEDWINDOW; 525 | 526 | if (flags & ImGuiViewportFlags_NoTaskBarIcon) 527 | *out_ex_style = WS_EX_TOOLWINDOW; 528 | else 529 | *out_ex_style = WS_EX_APPWINDOW; 530 | 531 | if (flags & ImGuiViewportFlags_TopMost) 532 | *out_ex_style |= WS_EX_TOPMOST; 533 | } 534 | 535 | static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport) 536 | { 537 | ImGuiViewportDataWin32* data = IM_NEW(ImGuiViewportDataWin32)(); 538 | viewport->PlatformUserData = data; 539 | 540 | // Select style and parent window 541 | ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &data->DwStyle, &data->DwExStyle); 542 | HWND parent_window = NULL; 543 | if (viewport->ParentViewportId != 0) 544 | if (ImGuiViewport* parent_viewport = ImGui::FindViewportByID(viewport->ParentViewportId)) 545 | parent_window = (HWND)parent_viewport->PlatformHandle; 546 | 547 | // Create window 548 | RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) }; 549 | ::AdjustWindowRectEx(&rect, data->DwStyle, FALSE, data->DwExStyle); 550 | data->Hwnd = ::CreateWindowEx( 551 | data->DwExStyle, _T("ImGui Platform"), _T("Untitled"), data->DwStyle, // Style, class name, window name 552 | rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, // Window area 553 | parent_window, NULL, ::GetModuleHandle(NULL), NULL); // Parent window, Menu, Instance, Param 554 | data->HwndOwned = true; 555 | viewport->PlatformRequestResize = false; 556 | viewport->PlatformHandle = viewport->PlatformHandleRaw = data->Hwnd; 557 | } 558 | 559 | static void ImGui_ImplWin32_DestroyWindow(ImGuiViewport* viewport) 560 | { 561 | if (ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData) 562 | { 563 | if (::GetCapture() == data->Hwnd) 564 | { 565 | // Transfer capture so if we started dragging from a window that later disappears, we'll still receive the MOUSEUP event. 566 | ::ReleaseCapture(); 567 | ::SetCapture(g_hWnd); 568 | } 569 | if (data->Hwnd && data->HwndOwned) 570 | ::DestroyWindow(data->Hwnd); 571 | data->Hwnd = NULL; 572 | IM_DELETE(data); 573 | } 574 | viewport->PlatformUserData = viewport->PlatformHandle = NULL; 575 | } 576 | 577 | static void ImGui_ImplWin32_ShowWindow(ImGuiViewport* viewport) 578 | { 579 | ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData; 580 | IM_ASSERT(data->Hwnd != 0); 581 | if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing) 582 | ::ShowWindow(data->Hwnd, SW_SHOWNA); 583 | else 584 | ::ShowWindow(data->Hwnd, SW_SHOW); 585 | } 586 | 587 | static void ImGui_ImplWin32_UpdateWindow(ImGuiViewport* viewport) 588 | { 589 | // (Optional) Update Win32 style if it changed _after_ creation. 590 | // Generally they won't change unless configuration flags are changed, but advanced uses (such as manually rewriting viewport flags) make this useful. 591 | ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData; 592 | IM_ASSERT(data->Hwnd != 0); 593 | DWORD new_style; 594 | DWORD new_ex_style; 595 | ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &new_style, &new_ex_style); 596 | 597 | // Only reapply the flags that have been changed from our point of view (as other flags are being modified by Windows) 598 | if (data->DwStyle != new_style || data->DwExStyle != new_ex_style) 599 | { 600 | data->DwStyle = new_style; 601 | data->DwExStyle = new_ex_style; 602 | ::SetWindowLong(data->Hwnd, GWL_STYLE, data->DwStyle); 603 | ::SetWindowLong(data->Hwnd, GWL_EXSTYLE, data->DwExStyle); 604 | RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) }; 605 | ::AdjustWindowRectEx(&rect, data->DwStyle, FALSE, data->DwExStyle); // Client to Screen 606 | ::SetWindowPos(data->Hwnd, NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); 607 | ::ShowWindow(data->Hwnd, SW_SHOWNA); // This is necessary when we alter the style 608 | viewport->PlatformRequestMove = viewport->PlatformRequestResize = true; 609 | } 610 | } 611 | 612 | static ImVec2 ImGui_ImplWin32_GetWindowPos(ImGuiViewport* viewport) 613 | { 614 | ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData; 615 | IM_ASSERT(data->Hwnd != 0); 616 | POINT pos = { 0, 0 }; 617 | ::ClientToScreen(data->Hwnd, &pos); 618 | return ImVec2((float)pos.x, (float)pos.y); 619 | } 620 | 621 | static void ImGui_ImplWin32_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos) 622 | { 623 | ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData; 624 | IM_ASSERT(data->Hwnd != 0); 625 | RECT rect = { (LONG)pos.x, (LONG)pos.y, (LONG)pos.x, (LONG)pos.y }; 626 | ::AdjustWindowRectEx(&rect, data->DwStyle, FALSE, data->DwExStyle); 627 | ::SetWindowPos(data->Hwnd, NULL, rect.left, rect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); 628 | } 629 | 630 | static ImVec2 ImGui_ImplWin32_GetWindowSize(ImGuiViewport* viewport) 631 | { 632 | ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData; 633 | IM_ASSERT(data->Hwnd != 0); 634 | RECT rect; 635 | ::GetClientRect(data->Hwnd, &rect); 636 | return ImVec2(float(rect.right - rect.left), float(rect.bottom - rect.top)); 637 | } 638 | 639 | static void ImGui_ImplWin32_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) 640 | { 641 | ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData; 642 | IM_ASSERT(data->Hwnd != 0); 643 | RECT rect = { 0, 0, (LONG)size.x, (LONG)size.y }; 644 | ::AdjustWindowRectEx(&rect, data->DwStyle, FALSE, data->DwExStyle); // Client to Screen 645 | ::SetWindowPos(data->Hwnd, NULL, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); 646 | } 647 | 648 | static void ImGui_ImplWin32_SetWindowFocus(ImGuiViewport* viewport) 649 | { 650 | ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData; 651 | IM_ASSERT(data->Hwnd != 0); 652 | ::BringWindowToTop(data->Hwnd); 653 | ::SetForegroundWindow(data->Hwnd); 654 | ::SetFocus(data->Hwnd); 655 | } 656 | 657 | static bool ImGui_ImplWin32_GetWindowFocus(ImGuiViewport* viewport) 658 | { 659 | ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData; 660 | IM_ASSERT(data->Hwnd != 0); 661 | return ::GetForegroundWindow() == data->Hwnd; 662 | } 663 | 664 | static bool ImGui_ImplWin32_GetWindowMinimized(ImGuiViewport* viewport) 665 | { 666 | ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData; 667 | IM_ASSERT(data->Hwnd != 0); 668 | return ::IsIconic(data->Hwnd) != 0; 669 | } 670 | 671 | static void ImGui_ImplWin32_SetWindowTitle(ImGuiViewport* viewport, const char* title) 672 | { 673 | // ::SetWindowTextA() doesn't properly handle UTF-8 so we explicitely convert our string. 674 | ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData; 675 | IM_ASSERT(data->Hwnd != 0); 676 | int n = ::MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0); 677 | ImVector title_w; 678 | title_w.resize(n); 679 | ::MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w.Data, n); 680 | ::SetWindowTextW(data->Hwnd, title_w.Data); 681 | } 682 | 683 | static void ImGui_ImplWin32_SetWindowAlpha(ImGuiViewport* viewport, float alpha) 684 | { 685 | ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData; 686 | IM_ASSERT(data->Hwnd != 0); 687 | IM_ASSERT(alpha >= 0.0f && alpha <= 1.0f); 688 | if (alpha < 1.0f) 689 | { 690 | DWORD style = ::GetWindowLongW(data->Hwnd, GWL_EXSTYLE) | WS_EX_LAYERED; 691 | ::SetWindowLongW(data->Hwnd, GWL_EXSTYLE, style); 692 | ::SetLayeredWindowAttributes(data->Hwnd, 0, (BYTE)(255 * alpha), LWA_ALPHA); 693 | } 694 | else 695 | { 696 | DWORD style = ::GetWindowLongW(data->Hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED; 697 | ::SetWindowLongW(data->Hwnd, GWL_EXSTYLE, style); 698 | } 699 | } 700 | 701 | static float ImGui_ImplWin32_GetWindowDpiScale(ImGuiViewport* viewport) 702 | { 703 | ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData; 704 | IM_ASSERT(data->Hwnd != 0); 705 | return ImGui_ImplWin32_GetDpiScaleForHwnd(data->Hwnd); 706 | } 707 | 708 | // FIXME-DPI: Testing DPI related ideas 709 | static void ImGui_ImplWin32_OnChangedViewport(ImGuiViewport* viewport) 710 | { 711 | (void)viewport; 712 | #if 0 713 | ImGuiStyle default_style; 714 | //default_style.WindowPadding = ImVec2(0, 0); 715 | //default_style.WindowBorderSize = 0.0f; 716 | //default_style.ItemSpacing.y = 3.0f; 717 | //default_style.FramePadding = ImVec2(0, 0); 718 | default_style.ScaleAllSizes(viewport->DpiScale); 719 | ImGuiStyle& style = ImGui::GetStyle(); 720 | style = default_style; 721 | #endif 722 | } 723 | 724 | static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 725 | { 726 | if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) 727 | return true; 728 | 729 | if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hWnd)) 730 | { 731 | switch (msg) 732 | { 733 | case WM_CLOSE: 734 | viewport->PlatformRequestClose = true; 735 | return 0; 736 | case WM_MOVE: 737 | viewport->PlatformRequestMove = true; 738 | break; 739 | case WM_SIZE: 740 | viewport->PlatformRequestResize = true; 741 | break; 742 | case WM_MOUSEACTIVATE: 743 | if (viewport->Flags & ImGuiViewportFlags_NoFocusOnClick) 744 | return MA_NOACTIVATE; 745 | break; 746 | case WM_NCHITTEST: 747 | // Let mouse pass-through the window. This will allow the back-end to set io.MouseHoveredViewport properly (which is OPTIONAL). 748 | // The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging. 749 | // If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in 750 | // your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system. 751 | if (viewport->Flags & ImGuiViewportFlags_NoInputs) 752 | return HTTRANSPARENT; 753 | break; 754 | } 755 | } 756 | 757 | return DefWindowProc(hWnd, msg, wParam, lParam); 758 | } 759 | 760 | static BOOL CALLBACK ImGui_ImplWin32_UpdateMonitors_EnumFunc(HMONITOR monitor, HDC, LPRECT, LPARAM) 761 | { 762 | MONITORINFO info = { 0 }; 763 | info.cbSize = sizeof(MONITORINFO); 764 | if (!::GetMonitorInfo(monitor, &info)) 765 | return TRUE; 766 | ImGuiPlatformMonitor imgui_monitor; 767 | imgui_monitor.MainPos = ImVec2((float)info.rcMonitor.left, (float)info.rcMonitor.top); 768 | imgui_monitor.MainSize = ImVec2((float)(info.rcMonitor.right - info.rcMonitor.left), (float)(info.rcMonitor.bottom - info.rcMonitor.top)); 769 | imgui_monitor.WorkPos = ImVec2((float)info.rcWork.left, (float)info.rcWork.top); 770 | imgui_monitor.WorkSize = ImVec2((float)(info.rcWork.right - info.rcWork.left), (float)(info.rcWork.bottom - info.rcWork.top)); 771 | imgui_monitor.DpiScale = ImGui_ImplWin32_GetDpiScaleForMonitor(monitor); 772 | ImGuiPlatformIO& io = ImGui::GetPlatformIO(); 773 | if (info.dwFlags & MONITORINFOF_PRIMARY) 774 | io.Monitors.push_front(imgui_monitor); 775 | else 776 | io.Monitors.push_back(imgui_monitor); 777 | return TRUE; 778 | } 779 | 780 | static void ImGui_ImplWin32_UpdateMonitors() 781 | { 782 | ImGui::GetPlatformIO().Monitors.resize(0); 783 | ::EnumDisplayMonitors(NULL, NULL, ImGui_ImplWin32_UpdateMonitors_EnumFunc, NULL); 784 | g_WantUpdateMonitors = false; 785 | } 786 | 787 | static void ImGui_ImplWin32_InitPlatformInterface() 788 | { 789 | WNDCLASSEX wcex; 790 | wcex.cbSize = sizeof(WNDCLASSEX); 791 | wcex.style = CS_HREDRAW | CS_VREDRAW; 792 | wcex.lpfnWndProc = ImGui_ImplWin32_WndProcHandler_PlatformWindow; 793 | wcex.cbClsExtra = 0; 794 | wcex.cbWndExtra = 0; 795 | wcex.hInstance = ::GetModuleHandle(NULL); 796 | wcex.hIcon = NULL; 797 | wcex.hCursor = NULL; 798 | wcex.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1); 799 | wcex.lpszMenuName = NULL; 800 | wcex.lpszClassName = _T("ImGui Platform"); 801 | wcex.hIconSm = NULL; 802 | ::RegisterClassEx(&wcex); 803 | 804 | ImGui_ImplWin32_UpdateMonitors(); 805 | 806 | // Register platform interface (will be coupled with a renderer interface) 807 | ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); 808 | platform_io.Platform_CreateWindow = ImGui_ImplWin32_CreateWindow; 809 | platform_io.Platform_DestroyWindow = ImGui_ImplWin32_DestroyWindow; 810 | platform_io.Platform_ShowWindow = ImGui_ImplWin32_ShowWindow; 811 | platform_io.Platform_SetWindowPos = ImGui_ImplWin32_SetWindowPos; 812 | platform_io.Platform_GetWindowPos = ImGui_ImplWin32_GetWindowPos; 813 | platform_io.Platform_SetWindowSize = ImGui_ImplWin32_SetWindowSize; 814 | platform_io.Platform_GetWindowSize = ImGui_ImplWin32_GetWindowSize; 815 | platform_io.Platform_SetWindowFocus = ImGui_ImplWin32_SetWindowFocus; 816 | platform_io.Platform_GetWindowFocus = ImGui_ImplWin32_GetWindowFocus; 817 | platform_io.Platform_GetWindowMinimized = ImGui_ImplWin32_GetWindowMinimized; 818 | platform_io.Platform_SetWindowTitle = ImGui_ImplWin32_SetWindowTitle; 819 | platform_io.Platform_SetWindowAlpha = ImGui_ImplWin32_SetWindowAlpha; 820 | platform_io.Platform_UpdateWindow = ImGui_ImplWin32_UpdateWindow; 821 | platform_io.Platform_GetWindowDpiScale = ImGui_ImplWin32_GetWindowDpiScale; // FIXME-DPI 822 | platform_io.Platform_OnChangedViewport = ImGui_ImplWin32_OnChangedViewport; // FIXME-DPI 823 | #if HAS_WIN32_IME 824 | platform_io.Platform_SetImeInputPos = ImGui_ImplWin32_SetImeInputPos; 825 | #endif 826 | 827 | // Register main window handle (which is owned by the main application, not by us) 828 | ImGuiViewport* main_viewport = ImGui::GetMainViewport(); 829 | ImGuiViewportDataWin32* data = IM_NEW(ImGuiViewportDataWin32)(); 830 | data->Hwnd = g_hWnd; 831 | data->HwndOwned = false; 832 | main_viewport->PlatformUserData = data; 833 | main_viewport->PlatformHandle = (void*)g_hWnd; 834 | } 835 | 836 | static void ImGui_ImplWin32_ShutdownPlatformInterface() 837 | { 838 | ::UnregisterClass(_T("ImGui Platform"), ::GetModuleHandle(NULL)); 839 | } 840 | -------------------------------------------------------------------------------- /cpp/imgui_impl_win32.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Platform Binding for Windows (standard windows API for 32 and 64 bits applications) 2 | // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) 3 | 4 | // Implemented features: 5 | // [X] Platform: Clipboard support (for Win32 this is actually part of core imgui) 6 | // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 7 | // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). 8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 9 | // [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. 10 | 11 | #pragma once 12 | 13 | IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd); 14 | IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown(); 15 | IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame(); 16 | 17 | // DPI-related helpers (which run and compile without requiring 8.1 or 10, neither Windows version, neither associated SDK) 18 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness(); 19 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd 20 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor 21 | 22 | // Handler for Win32 messages, update mouse/keyboard data. 23 | // You may or not need this for your implementation, but it can serve as reference for handling inputs. 24 | // Intentionally commented out to avoid dragging dependencies on types. You can COPY this line into your .cpp code instead. 25 | /* 26 | IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 27 | */ 28 | -------------------------------------------------------------------------------- /cpp/imstb_rectpack.h: -------------------------------------------------------------------------------- 1 | // [DEAR IMGUI] 2 | // This is a slightly modified version of stb_rect_pack.h 1.00. 3 | // Those changes would need to be pushed into nothings/stb: 4 | // - Added STBRP__CDECL 5 | // Grep for [DEAR IMGUI] to find the changes. 6 | 7 | // stb_rect_pack.h - v1.00 - public domain - rectangle packing 8 | // Sean Barrett 2014 9 | // 10 | // Useful for e.g. packing rectangular textures into an atlas. 11 | // Does not do rotation. 12 | // 13 | // Not necessarily the awesomest packing method, but better than 14 | // the totally naive one in stb_truetype (which is primarily what 15 | // this is meant to replace). 16 | // 17 | // Has only had a few tests run, may have issues. 18 | // 19 | // More docs to come. 20 | // 21 | // No memory allocations; uses qsort() and assert() from stdlib. 22 | // Can override those by defining STBRP_SORT and STBRP_ASSERT. 23 | // 24 | // This library currently uses the Skyline Bottom-Left algorithm. 25 | // 26 | // Please note: better rectangle packers are welcome! Please 27 | // implement them to the same API, but with a different init 28 | // function. 29 | // 30 | // Credits 31 | // 32 | // Library 33 | // Sean Barrett 34 | // Minor features 35 | // Martins Mozeiko 36 | // github:IntellectualKitty 37 | // 38 | // Bugfixes / warning fixes 39 | // Jeremy Jaussaud 40 | // Fabian Giesen 41 | // 42 | // Version history: 43 | // 44 | // 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles 45 | // 0.99 (2019-02-07) warning fixes 46 | // 0.11 (2017-03-03) return packing success/fail result 47 | // 0.10 (2016-10-25) remove cast-away-const to avoid warnings 48 | // 0.09 (2016-08-27) fix compiler warnings 49 | // 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0) 50 | // 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0) 51 | // 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort 52 | // 0.05: added STBRP_ASSERT to allow replacing assert 53 | // 0.04: fixed minor bug in STBRP_LARGE_RECTS support 54 | // 0.01: initial release 55 | // 56 | // LICENSE 57 | // 58 | // See end of file for license information. 59 | 60 | ////////////////////////////////////////////////////////////////////////////// 61 | // 62 | // INCLUDE SECTION 63 | // 64 | 65 | #ifndef STB_INCLUDE_STB_RECT_PACK_H 66 | #define STB_INCLUDE_STB_RECT_PACK_H 67 | 68 | #define STB_RECT_PACK_VERSION 1 69 | 70 | #ifdef STBRP_STATIC 71 | #define STBRP_DEF static 72 | #else 73 | #define STBRP_DEF extern 74 | #endif 75 | 76 | #ifdef __cplusplus 77 | extern "C" { 78 | #endif 79 | 80 | typedef struct stbrp_context stbrp_context; 81 | typedef struct stbrp_node stbrp_node; 82 | typedef struct stbrp_rect stbrp_rect; 83 | 84 | #ifdef STBRP_LARGE_RECTS 85 | typedef int stbrp_coord; 86 | #else 87 | typedef unsigned short stbrp_coord; 88 | #endif 89 | 90 | STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); 91 | // Assign packed locations to rectangles. The rectangles are of type 92 | // 'stbrp_rect' defined below, stored in the array 'rects', and there 93 | // are 'num_rects' many of them. 94 | // 95 | // Rectangles which are successfully packed have the 'was_packed' flag 96 | // set to a non-zero value and 'x' and 'y' store the minimum location 97 | // on each axis (i.e. bottom-left in cartesian coordinates, top-left 98 | // if you imagine y increasing downwards). Rectangles which do not fit 99 | // have the 'was_packed' flag set to 0. 100 | // 101 | // You should not try to access the 'rects' array from another thread 102 | // while this function is running, as the function temporarily reorders 103 | // the array while it executes. 104 | // 105 | // To pack into another rectangle, you need to call stbrp_init_target 106 | // again. To continue packing into the same rectangle, you can call 107 | // this function again. Calling this multiple times with multiple rect 108 | // arrays will probably produce worse packing results than calling it 109 | // a single time with the full rectangle array, but the option is 110 | // available. 111 | // 112 | // The function returns 1 if all of the rectangles were successfully 113 | // packed and 0 otherwise. 114 | 115 | struct stbrp_rect 116 | { 117 | // reserved for your use: 118 | int id; 119 | 120 | // input: 121 | stbrp_coord w, h; 122 | 123 | // output: 124 | stbrp_coord x, y; 125 | int was_packed; // non-zero if valid packing 126 | 127 | }; // 16 bytes, nominally 128 | 129 | 130 | STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes); 131 | // Initialize a rectangle packer to: 132 | // pack a rectangle that is 'width' by 'height' in dimensions 133 | // using temporary storage provided by the array 'nodes', which is 'num_nodes' long 134 | // 135 | // You must call this function every time you start packing into a new target. 136 | // 137 | // There is no "shutdown" function. The 'nodes' memory must stay valid for 138 | // the following stbrp_pack_rects() call (or calls), but can be freed after 139 | // the call (or calls) finish. 140 | // 141 | // Note: to guarantee best results, either: 142 | // 1. make sure 'num_nodes' >= 'width' 143 | // or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' 144 | // 145 | // If you don't do either of the above things, widths will be quantized to multiples 146 | // of small integers to guarantee the algorithm doesn't run out of temporary storage. 147 | // 148 | // If you do #2, then the non-quantized algorithm will be used, but the algorithm 149 | // may run out of temporary storage and be unable to pack some rectangles. 150 | 151 | STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem); 152 | // Optionally call this function after init but before doing any packing to 153 | // change the handling of the out-of-temp-memory scenario, described above. 154 | // If you call init again, this will be reset to the default (false). 155 | 156 | 157 | STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic); 158 | // Optionally select which packing heuristic the library should use. Different 159 | // heuristics will produce better/worse results for different data sets. 160 | // If you call init again, this will be reset to the default. 161 | 162 | enum 163 | { 164 | STBRP_HEURISTIC_Skyline_default=0, 165 | STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, 166 | STBRP_HEURISTIC_Skyline_BF_sortHeight 167 | }; 168 | 169 | 170 | ////////////////////////////////////////////////////////////////////////////// 171 | // 172 | // the details of the following structures don't matter to you, but they must 173 | // be visible so you can handle the memory allocations for them 174 | 175 | struct stbrp_node 176 | { 177 | stbrp_coord x,y; 178 | stbrp_node *next; 179 | }; 180 | 181 | struct stbrp_context 182 | { 183 | int width; 184 | int height; 185 | int align; 186 | int init_mode; 187 | int heuristic; 188 | int num_nodes; 189 | stbrp_node *active_head; 190 | stbrp_node *free_head; 191 | stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' 192 | }; 193 | 194 | #ifdef __cplusplus 195 | } 196 | #endif 197 | 198 | #endif 199 | 200 | ////////////////////////////////////////////////////////////////////////////// 201 | // 202 | // IMPLEMENTATION SECTION 203 | // 204 | 205 | #ifdef STB_RECT_PACK_IMPLEMENTATION 206 | #ifndef STBRP_SORT 207 | #include 208 | #define STBRP_SORT qsort 209 | #endif 210 | 211 | #ifndef STBRP_ASSERT 212 | #include 213 | #define STBRP_ASSERT assert 214 | #endif 215 | 216 | // [DEAR IMGUI] Added STBRP__CDECL 217 | #ifdef _MSC_VER 218 | #define STBRP__NOTUSED(v) (void)(v) 219 | #define STBRP__CDECL __cdecl 220 | #else 221 | #define STBRP__NOTUSED(v) (void)sizeof(v) 222 | #define STBRP__CDECL 223 | #endif 224 | 225 | enum 226 | { 227 | STBRP__INIT_skyline = 1 228 | }; 229 | 230 | STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic) 231 | { 232 | switch (context->init_mode) { 233 | case STBRP__INIT_skyline: 234 | STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight); 235 | context->heuristic = heuristic; 236 | break; 237 | default: 238 | STBRP_ASSERT(0); 239 | } 240 | } 241 | 242 | STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem) 243 | { 244 | if (allow_out_of_mem) 245 | // if it's ok to run out of memory, then don't bother aligning them; 246 | // this gives better packing, but may fail due to OOM (even though 247 | // the rectangles easily fit). @TODO a smarter approach would be to only 248 | // quantize once we've hit OOM, then we could get rid of this parameter. 249 | context->align = 1; 250 | else { 251 | // if it's not ok to run out of memory, then quantize the widths 252 | // so that num_nodes is always enough nodes. 253 | // 254 | // I.e. num_nodes * align >= width 255 | // align >= width / num_nodes 256 | // align = ceil(width/num_nodes) 257 | 258 | context->align = (context->width + context->num_nodes-1) / context->num_nodes; 259 | } 260 | } 261 | 262 | STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes) 263 | { 264 | int i; 265 | #ifndef STBRP_LARGE_RECTS 266 | STBRP_ASSERT(width <= 0xffff && height <= 0xffff); 267 | #endif 268 | 269 | for (i=0; i < num_nodes-1; ++i) 270 | nodes[i].next = &nodes[i+1]; 271 | nodes[i].next = NULL; 272 | context->init_mode = STBRP__INIT_skyline; 273 | context->heuristic = STBRP_HEURISTIC_Skyline_default; 274 | context->free_head = &nodes[0]; 275 | context->active_head = &context->extra[0]; 276 | context->width = width; 277 | context->height = height; 278 | context->num_nodes = num_nodes; 279 | stbrp_setup_allow_out_of_mem(context, 0); 280 | 281 | // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) 282 | context->extra[0].x = 0; 283 | context->extra[0].y = 0; 284 | context->extra[0].next = &context->extra[1]; 285 | context->extra[1].x = (stbrp_coord) width; 286 | #ifdef STBRP_LARGE_RECTS 287 | context->extra[1].y = (1<<30); 288 | #else 289 | context->extra[1].y = 65535; 290 | #endif 291 | context->extra[1].next = NULL; 292 | } 293 | 294 | // find minimum y position if it starts at x1 295 | static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste) 296 | { 297 | stbrp_node *node = first; 298 | int x1 = x0 + width; 299 | int min_y, visited_width, waste_area; 300 | 301 | STBRP__NOTUSED(c); 302 | 303 | STBRP_ASSERT(first->x <= x0); 304 | 305 | #if 0 306 | // skip in case we're past the node 307 | while (node->next->x <= x0) 308 | ++node; 309 | #else 310 | STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency 311 | #endif 312 | 313 | STBRP_ASSERT(node->x <= x0); 314 | 315 | min_y = 0; 316 | waste_area = 0; 317 | visited_width = 0; 318 | while (node->x < x1) { 319 | if (node->y > min_y) { 320 | // raise min_y higher. 321 | // we've accounted for all waste up to min_y, 322 | // but we'll now add more waste for everything we've visted 323 | waste_area += visited_width * (node->y - min_y); 324 | min_y = node->y; 325 | // the first time through, visited_width might be reduced 326 | if (node->x < x0) 327 | visited_width += node->next->x - x0; 328 | else 329 | visited_width += node->next->x - node->x; 330 | } else { 331 | // add waste area 332 | int under_width = node->next->x - node->x; 333 | if (under_width + visited_width > width) 334 | under_width = width - visited_width; 335 | waste_area += under_width * (min_y - node->y); 336 | visited_width += under_width; 337 | } 338 | node = node->next; 339 | } 340 | 341 | *pwaste = waste_area; 342 | return min_y; 343 | } 344 | 345 | typedef struct 346 | { 347 | int x,y; 348 | stbrp_node **prev_link; 349 | } stbrp__findresult; 350 | 351 | static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height) 352 | { 353 | int best_waste = (1<<30), best_x, best_y = (1 << 30); 354 | stbrp__findresult fr; 355 | stbrp_node **prev, *node, *tail, **best = NULL; 356 | 357 | // align to multiple of c->align 358 | width = (width + c->align - 1); 359 | width -= width % c->align; 360 | STBRP_ASSERT(width % c->align == 0); 361 | 362 | // if it can't possibly fit, bail immediately 363 | if (width > c->width || height > c->height) { 364 | fr.prev_link = NULL; 365 | fr.x = fr.y = 0; 366 | return fr; 367 | } 368 | 369 | node = c->active_head; 370 | prev = &c->active_head; 371 | while (node->x + width <= c->width) { 372 | int y,waste; 373 | y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste); 374 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL 375 | // bottom left 376 | if (y < best_y) { 377 | best_y = y; 378 | best = prev; 379 | } 380 | } else { 381 | // best-fit 382 | if (y + height <= c->height) { 383 | // can only use it if it first vertically 384 | if (y < best_y || (y == best_y && waste < best_waste)) { 385 | best_y = y; 386 | best_waste = waste; 387 | best = prev; 388 | } 389 | } 390 | } 391 | prev = &node->next; 392 | node = node->next; 393 | } 394 | 395 | best_x = (best == NULL) ? 0 : (*best)->x; 396 | 397 | // if doing best-fit (BF), we also have to try aligning right edge to each node position 398 | // 399 | // e.g, if fitting 400 | // 401 | // ____________________ 402 | // |____________________| 403 | // 404 | // into 405 | // 406 | // | | 407 | // | ____________| 408 | // |____________| 409 | // 410 | // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned 411 | // 412 | // This makes BF take about 2x the time 413 | 414 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) { 415 | tail = c->active_head; 416 | node = c->active_head; 417 | prev = &c->active_head; 418 | // find first node that's admissible 419 | while (tail->x < width) 420 | tail = tail->next; 421 | while (tail) { 422 | int xpos = tail->x - width; 423 | int y,waste; 424 | STBRP_ASSERT(xpos >= 0); 425 | // find the left position that matches this 426 | while (node->next->x <= xpos) { 427 | prev = &node->next; 428 | node = node->next; 429 | } 430 | STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); 431 | y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); 432 | if (y + height <= c->height) { 433 | if (y <= best_y) { 434 | if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) { 435 | best_x = xpos; 436 | STBRP_ASSERT(y <= best_y); 437 | best_y = y; 438 | best_waste = waste; 439 | best = prev; 440 | } 441 | } 442 | } 443 | tail = tail->next; 444 | } 445 | } 446 | 447 | fr.prev_link = best; 448 | fr.x = best_x; 449 | fr.y = best_y; 450 | return fr; 451 | } 452 | 453 | static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height) 454 | { 455 | // find best position according to heuristic 456 | stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); 457 | stbrp_node *node, *cur; 458 | 459 | // bail if: 460 | // 1. it failed 461 | // 2. the best node doesn't fit (we don't always check this) 462 | // 3. we're out of memory 463 | if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) { 464 | res.prev_link = NULL; 465 | return res; 466 | } 467 | 468 | // on success, create new node 469 | node = context->free_head; 470 | node->x = (stbrp_coord) res.x; 471 | node->y = (stbrp_coord) (res.y + height); 472 | 473 | context->free_head = node->next; 474 | 475 | // insert the new node into the right starting point, and 476 | // let 'cur' point to the remaining nodes needing to be 477 | // stiched back in 478 | 479 | cur = *res.prev_link; 480 | if (cur->x < res.x) { 481 | // preserve the existing one, so start testing with the next one 482 | stbrp_node *next = cur->next; 483 | cur->next = node; 484 | cur = next; 485 | } else { 486 | *res.prev_link = node; 487 | } 488 | 489 | // from here, traverse cur and free the nodes, until we get to one 490 | // that shouldn't be freed 491 | while (cur->next && cur->next->x <= res.x + width) { 492 | stbrp_node *next = cur->next; 493 | // move the current node to the free list 494 | cur->next = context->free_head; 495 | context->free_head = cur; 496 | cur = next; 497 | } 498 | 499 | // stitch the list back in 500 | node->next = cur; 501 | 502 | if (cur->x < res.x + width) 503 | cur->x = (stbrp_coord) (res.x + width); 504 | 505 | #ifdef _DEBUG 506 | cur = context->active_head; 507 | while (cur->x < context->width) { 508 | STBRP_ASSERT(cur->x < cur->next->x); 509 | cur = cur->next; 510 | } 511 | STBRP_ASSERT(cur->next == NULL); 512 | 513 | { 514 | int count=0; 515 | cur = context->active_head; 516 | while (cur) { 517 | cur = cur->next; 518 | ++count; 519 | } 520 | cur = context->free_head; 521 | while (cur) { 522 | cur = cur->next; 523 | ++count; 524 | } 525 | STBRP_ASSERT(count == context->num_nodes+2); 526 | } 527 | #endif 528 | 529 | return res; 530 | } 531 | 532 | // [DEAR IMGUI] Added STBRP__CDECL 533 | static int STBRP__CDECL rect_height_compare(const void *a, const void *b) 534 | { 535 | const stbrp_rect *p = (const stbrp_rect *) a; 536 | const stbrp_rect *q = (const stbrp_rect *) b; 537 | if (p->h > q->h) 538 | return -1; 539 | if (p->h < q->h) 540 | return 1; 541 | return (p->w > q->w) ? -1 : (p->w < q->w); 542 | } 543 | 544 | // [DEAR IMGUI] Added STBRP__CDECL 545 | static int STBRP__CDECL rect_original_order(const void *a, const void *b) 546 | { 547 | const stbrp_rect *p = (const stbrp_rect *) a; 548 | const stbrp_rect *q = (const stbrp_rect *) b; 549 | return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); 550 | } 551 | 552 | #ifdef STBRP_LARGE_RECTS 553 | #define STBRP__MAXVAL 0xffffffff 554 | #else 555 | #define STBRP__MAXVAL 0xffff 556 | #endif 557 | 558 | STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) 559 | { 560 | int i, all_rects_packed = 1; 561 | 562 | // we use the 'was_packed' field internally to allow sorting/unsorting 563 | for (i=0; i < num_rects; ++i) { 564 | rects[i].was_packed = i; 565 | } 566 | 567 | // sort according to heuristic 568 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare); 569 | 570 | for (i=0; i < num_rects; ++i) { 571 | if (rects[i].w == 0 || rects[i].h == 0) { 572 | rects[i].x = rects[i].y = 0; // empty rect needs no space 573 | } else { 574 | stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); 575 | if (fr.prev_link) { 576 | rects[i].x = (stbrp_coord) fr.x; 577 | rects[i].y = (stbrp_coord) fr.y; 578 | } else { 579 | rects[i].x = rects[i].y = STBRP__MAXVAL; 580 | } 581 | } 582 | } 583 | 584 | // unsort 585 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order); 586 | 587 | // set was_packed flags and all_rects_packed status 588 | for (i=0; i < num_rects; ++i) { 589 | rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); 590 | if (!rects[i].was_packed) 591 | all_rects_packed = 0; 592 | } 593 | 594 | // return the all_rects_packed status 595 | return all_rects_packed; 596 | } 597 | #endif 598 | 599 | /* 600 | ------------------------------------------------------------------------------ 601 | This software is available under 2 licenses -- choose whichever you prefer. 602 | ------------------------------------------------------------------------------ 603 | ALTERNATIVE A - MIT License 604 | Copyright (c) 2017 Sean Barrett 605 | Permission is hereby granted, free of charge, to any person obtaining a copy of 606 | this software and associated documentation files (the "Software"), to deal in 607 | the Software without restriction, including without limitation the rights to 608 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 609 | of the Software, and to permit persons to whom the Software is furnished to do 610 | so, subject to the following conditions: 611 | The above copyright notice and this permission notice shall be included in all 612 | copies or substantial portions of the Software. 613 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 614 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 615 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 616 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 617 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 618 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 619 | SOFTWARE. 620 | ------------------------------------------------------------------------------ 621 | ALTERNATIVE B - Public Domain (www.unlicense.org) 622 | This is free and unencumbered software released into the public domain. 623 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 624 | software, either in source code form or as a compiled binary, for any purpose, 625 | commercial or non-commercial, and by any means. 626 | In jurisdictions that recognize copyright laws, the author or authors of this 627 | software dedicate any and all copyright interest in the software to the public 628 | domain. We make this dedication for the benefit of the public at large and to 629 | the detriment of our heirs and successors. We intend this dedication to be an 630 | overt act of relinquishment in perpetuity of all present and future rights to 631 | this software under copyright law. 632 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 633 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 634 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 635 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 636 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 637 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 638 | ------------------------------------------------------------------------------ 639 | */ 640 | -------------------------------------------------------------------------------- /cpp/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: source file corresponding to the pre-compiled header 2 | 3 | #include "pch.h" 4 | 5 | // When you are using pre-compiled headers, this source file is necessary for compilation to succeed. 6 | -------------------------------------------------------------------------------- /cpp/pch.h: -------------------------------------------------------------------------------- 1 | // pch.h: This is a precompiled header file. 2 | // Files listed below are compiled only once, improving build performance for future builds. 3 | // This also affects IntelliSense performance, including code completion and many code browsing features. 4 | // However, files listed here are ALL re-compiled if any one of them is updated between builds. 5 | // Do not add files here that you will be updating frequently as this negates the performance advantage. 6 | 7 | #ifndef PCH_H 8 | #define PCH_H 9 | 10 | #define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport) 11 | 12 | // add headers that you want to pre-compile here 13 | #include "framework.h" 14 | #include 15 | 16 | #define NDEBUG 17 | #include "imgui.h" 18 | #include "imgui_impl_win32.h" 19 | #include "imgui_impl_dx11.h" 20 | #include 21 | 22 | #define DIRECTINPUT_VERSION 0x0800 23 | #include 24 | #include 25 | 26 | 27 | #include "Anim.h" 28 | #include "base_engine.h" 29 | #endif //PCH_H 30 | -------------------------------------------------------------------------------- /cpp/test: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /dll_64/imgui.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thedemons/imgui-autoit/70fae1a0e20bc39dc2c5bd3f7a48b6b6c006db03/dll_64/imgui.dll -------------------------------------------------------------------------------- /example/viewport_hide_main_window.au3: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "imgui.au3" 4 | 5 | 6 | _ImGui_EnableViewports() 7 | 8 | Local $hwnd = _ImGui_GUICreate("Example multiple viewports - Hide main window", 1, 1, -100, -100, 0, $WS_EX_TOOLWINDOW) 9 | _WinAPI_ShowWindow($hwnd) 10 | 11 | _ImGui_StyleColorsLight() 12 | 13 | Local $io = _ImGui_GetIO() 14 | $io.ConfigWindowsMoveFromTitleBarOnly = True ; // Only drag window by title bar 15 | 16 | Local $is_first_run = True 17 | 18 | While 1 19 | 20 | if Not _ImGui_PeekMsg() Then Exit 21 | 22 | _ImGui_BeginFrame() 23 | 24 | If Not _ImGui_Begin("Test", True, $ImGuiWindowFlags_NoCollapse) Then Exit 25 | 26 | If $is_first_run Then 27 | $is_first_run = False 28 | Local $win_size[] = [800, 600] 29 | Local $win_pos_x = (@DesktopWidth - $win_size[0]) / 2 30 | Local $win_pos_y = (@DesktopHeight - $win_size[1]) / 2 31 | _ImGui_SetWindowPos($win_pos_x, $win_pos_y) 32 | _ImGui_SetWindowSize($win_size[0], $win_size[1]) 33 | EndIf 34 | 35 | _ImGui_Text("Hello") 36 | _ImGui_End() 37 | 38 | _ImGui_EndFrame() 39 | Wend 40 | -------------------------------------------------------------------------------- /imgui-au3-example.au3: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "imgui.au3" 5 | 6 | 7 | _ImGui_EnableViewports() 8 | $hwnd = _ImGui_GUICreate("AutoIt ImGui", 1024, 768) 9 | _WinAPI_ShowWindow($hwnd) 10 | ;~ GUISetState(@SW_SHOW, $Hwnd) 11 | 12 | _ImGui_StyleColorsLight() 13 | 14 | $io = _ImGui_GetIO() 15 | $imstyle = _ImGui_GetStyle() 16 | 17 | _ImGui_SetWindowTitleAlign(0.5, 0.5) 18 | _ImGui_EnableDocking() 19 | 20 | 21 | Local $i_list_view = 0 22 | Local $i_radio_theme = 0 23 | Local $f_slider = 5 24 | Local $label_radio_theme[] = ["Light", "Dark", "Classic"] 25 | Local $username = "" 26 | Local $password = "" 27 | Local $str_status = "" 28 | Local $b_show_demo_window = False 29 | Local $b_show_another_window = False 30 | 31 | 32 | While 1 33 | 34 | ; when the user click close button on the window, this will return false 35 | if Not _ImGui_PeekMsg() Then Exit 36 | 37 | ; must call 38 | _ImGui_BeginFrame() 39 | 40 | ; Begin a new window 41 | _ImGui_Begin("Demo ImGui-AutoIt") 42 | 43 | _ImGui_Text("Chọn theme") 44 | 45 | ; Put next item to the same line (don't line break) 46 | _ImGui_SameLine(); 47 | 48 | Local $old_theme = $i_radio_theme 49 | _ImGui_RadioButton("Light", $i_radio_theme, 0) 50 | _ImGui_SameLine(); 51 | _ImGui_RadioButton("Dark", $i_radio_theme, 1) 52 | _ImGui_SameLine(); 53 | _ImGui_RadioButton("Classic", $i_radio_theme, 2) 54 | _ImGui_SameLine(); 55 | 56 | 57 | if _ImGui_BeginCombo("##combo_theme", $label_radio_theme[$i_radio_theme]) Then 58 | 59 | for $i = 0 To UBound($label_radio_theme) - 1 60 | 61 | Local $selected = ($i_radio_theme == $i) ; if $i_radio_theme = $i then $selected = True 62 | if _ImGui_Selectable($label_radio_theme[$i], $selected) Then 63 | $i_radio_theme = $i 64 | _ImGui_SetItemDefaultFocus() 65 | EndIf 66 | Next 67 | 68 | _ImGui_EndCombo() 69 | EndIf 70 | 71 | If $old_theme <> $i_radio_theme Then 72 | Switch $i_radio_theme 73 | Case 0 74 | _ImGui_StyleColorsLight() 75 | Case 1 76 | _ImGui_StyleColorsDark() 77 | Case 2 78 | _ImGui_StyleColorsClassic() 79 | EndSwitch 80 | EndIf 81 | 82 | 83 | Local $winSize = _ImGui_GetWindowSize() 84 | 85 | _ImGui_Separator() 86 | 87 | ; Download an image 88 | Local $img = _ImGui_ImageFromURL("https://aommaster.com/blog/wp-content/uploads/2014/07/AutoItlogo.png") 89 | If $img Then 90 | 91 | ; Get window size 92 | Local $win_size = _ImGui_GetWindowSize() 93 | 94 | ; Draw the image 95 | _ImGui_ImageFit($img, $win_size[0] - 10, 140) 96 | EndIf 97 | 98 | _ImGui_NewLine() 99 | 100 | If _ImGui_CheckBox("Show demo window", $b_show_demo_window) Then _ImGui_EnableViewports($b_show_demo_window) 101 | _ImGui_CheckBox("Show another window", $b_show_another_window) 102 | if _ImGui_IsItemHovered() Then _ImGui_ToolTip("what's up") 103 | 104 | ; Seperate the window into 2 columns 105 | _ImGui_Columns(2) 106 | 107 | ; Set the width for the column 0 108 | _ImGui_SetColumnWidth(0, $winSize[0]*0.7) 109 | 110 | ; like line break 111 | _ImGui_NewLine() 112 | 113 | ; put "##" before labels to hide then, remember to call _ImGui_PushItemWidth(-1) to expand the widget 114 | _ImGui_PushItemWidth(-1) 115 | _ImGui_InputTextWithHint("##username", "username", $username, $ImGuiInputTextFlags_CharsNoBlank) 116 | _ImGui_InputTextWithHint("##password", "password", $password, $ImGuiInputTextFlags_Password) 117 | _ImGui_PopItemWidth() 118 | 119 | if $str_status <> "" then _ImGui_TextColored($str_status, 0xFF33BB44) 120 | 121 | ; go to the next column 122 | _ImGui_NextColumn() 123 | _ImGui_NewLine() 124 | 125 | ; _ImGui_Button return true if being clicked 126 | if _ImGui_Button("LOGIN", -1, 40) Then $str_status = ($str_status == "" ? "Login success" : "") 127 | 128 | 129 | _ImGui_Columns(1) 130 | _ImGui_NewLine() 131 | 132 | ; begin a child window inside the main window 133 | _ImGui_BeginChild("##child_list_view1", $winSize*0.6, $winSize[1] *0.3, true, $ImGuiWindowFlags_ChildWindow) 134 | for $i = 0 To 10 135 | if _ImGui_Selectable("Selectable - " & $i, $i = $i_list_view) Then 136 | $i_list_view = $i 137 | EndIf 138 | Next 139 | _ImGui_EndChild() 140 | 141 | ; call after done with _ImGui_Begin 142 | _ImGui_End() 143 | 144 | If $b_show_another_window Then 145 | 146 | _ImGui_Begin("Another window") 147 | _ImGui_Text("Hello there..") 148 | if _ImGui_Button("close me") Then $b_show_another_window = False 149 | _ImGui_End() 150 | EndIf 151 | 152 | If $b_show_demo_window Then _ImGui_ShowDemoWindow() 153 | 154 | ; must call 155 | _ImGui_EndFrame() 156 | 157 | WEnd -------------------------------------------------------------------------------- /imgui.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thedemons/imgui-autoit/70fae1a0e20bc39dc2c5bd3f7a48b6b6c006db03/imgui.dll -------------------------------------------------------------------------------- /tools/README.md: -------------------------------------------------------------------------------- 1 | 2 | ### Usage 3 | - Run this to add auto-complete feature for ImGui in SciTE editor 4 | --------------------------------------------------------------------------------