diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index eb0966672..0b09c82cd 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -99,55 +99,6 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c } } -// Get text data in Win32 clipboard -static const char* ImImpl_GetClipboardTextFn() -{ - static char* buf_local = NULL; - if (buf_local) - { - free(buf_local); - buf_local = NULL; - } - - if (!OpenClipboard(NULL)) - return NULL; - - HANDLE buf_handle = GetClipboardData(CF_TEXT); - if (buf_handle == NULL) - return NULL; - - if (char* buf_global = (char*)GlobalLock(buf_handle)) - buf_local = strdup(buf_global); - GlobalUnlock(buf_handle); - CloseClipboard(); - - return buf_local; -} - -// Set text data in Win32 clipboard -static void ImImpl_SetClipboardTextFn(const char* text, const char* text_end) -{ - if (!OpenClipboard(NULL)) - return; - - if (!text_end) - text_end = text + strlen(text); - - const int buf_length = (text_end - text) + 1; - HGLOBAL buf_handle = GlobalAlloc(GMEM_MOVEABLE, buf_length * sizeof(char)); - if (buf_handle == NULL) - return; - - char* buf_global = (char *)GlobalLock(buf_handle); - memcpy(buf_global, text, text_end - text); - buf_global[text_end - text] = 0; - GlobalUnlock(buf_handle); - - EmptyClipboard(); - SetClipboardData(CF_TEXT, buf_handle); - CloseClipboard(); -} - HRESULT InitD3D(HWND hWnd) { if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION))) @@ -250,8 +201,6 @@ void InitImGui() io.KeyMap[ImGuiKey_Z] = 'Z'; io.RenderDrawListsFn = ImImpl_RenderDrawLists; - io.SetClipboardTextFn = ImImpl_SetClipboardTextFn; - io.GetClipboardTextFn = ImImpl_GetClipboardTextFn; // Create the vertex buffer if (g_pd3dDevice->CreateVertexBuffer(10000 * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0) diff --git a/imconfig.h b/imconfig.h index 60229d70c..f5d971ee1 100644 --- a/imconfig.h +++ b/imconfig.h @@ -4,15 +4,18 @@ #pragma once -//----- Define your own ImVector<> type if you don't want to use the provided implementation defined in imgui.h +// Define your own ImVector<> type if you don't want to use the provided implementation defined in imgui.h //#include //#define ImVector std::vector //#define ImVector MyVector -//----- Define assertion handler. Default to calling assert(). +// Define assertion handler. Default to calling assert(). // #define IM_ASSERT(_EXPR) MyAssert(_EXPR) -//----- Define implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4. +// Tell ImGui to not implement default clipboard handlers for Windows (so as not to link with OpenClipboard(), etc.) +// #define IMGUI_DONT_IMPLEMENT_WINDOWS_CLIPBOARD_FUNCTIONS + +// Define implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4. /* #define IM_VEC2_CLASS_EXTRA \ ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ @@ -23,8 +26,8 @@ operator MyVec4() const { return MyVec4(x,y,z,w); } */ -//----- Freely implement extra functions within the ImGui:: namespace. -//----- e.g. you can create variants of the ImGui::Value() helper for your low-level math types. +// Freely implement extra functions within the ImGui:: namespace. +// e.g. you can create variants of the ImGui::Value() helper for your low-level math types. /* namespace ImGui { diff --git a/imgui.cpp b/imgui.cpp index 7ff6bd02d..adca912f6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -196,6 +196,17 @@ static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs); }; // namespace ImGui +//----------------------------------------------------------------------------- +// Platform dependant helpers +//----------------------------------------------------------------------------- + +#ifdef _MSC_VER +#ifndef IMGUI_DONT_IMPLEMENT_WINDOWS_CLIPBOARD_FUNCTIONS +static const char* GetClipboardTextFn_DefaultImplWindows(); +static void SetClipboardTextFn_DefaultImplWindows(const char* text, const char* text_end); +#endif +#endif + //----------------------------------------------------------------------------- // User facing structures //----------------------------------------------------------------------------- @@ -268,6 +279,14 @@ ImGuiIO::ImGuiIO() MousePosPrev = ImVec2(-1,-1); MouseDoubleClickTime = 0.30f; MouseDoubleClickMaxDist = 6.0f; + + // Platform dependant default implementations +#ifdef _MSC_VER +#ifndef IMGUI_DONT_IMPLEMENT_WINDOWS_CLIPBOARD_FUNCTIONS + GetClipboardTextFn = GetClipboardTextFn_DefaultImplWindows; + SetClipboardTextFn = SetClipboardTextFn_DefaultImplWindows; +#endif +#endif } // Pass in translated ASCII characters for text input. @@ -287,8 +306,7 @@ void ImGuiIO::AddInputCharacter(char c) // Helpers //----------------------------------------------------------------------------- -#undef ARRAYSIZE -#define ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) +#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) #undef PI const float PI = 3.14159265358979323846f; @@ -795,7 +813,7 @@ void ImGuiTextFilter::Draw(const char* label, float width) width = ImMax(window->Pos.x + ImGui::GetWindowContentRegionMax().x - window->DC.CursorPos.x - (label_size.x + GImGui.Style.ItemSpacing.x*4), 10.0f); } ImGui::PushItemWidth(width); - ImGui::InputText(label, InputBuf, ARRAYSIZE(InputBuf)); + ImGui::InputText(label, InputBuf, IM_ARRAYSIZE(InputBuf)); ImGui::PopItemWidth(); Build(); } @@ -1057,7 +1075,7 @@ static void LoadSettings() if (line_start[0] == '[' && line_end > line_start && line_end[-1] == ']') { char name[64]; - ImFormatString(name, ARRAYSIZE(name), "%.*s", line_end-line_start-2, line_start+1); + ImFormatString(name, IM_ARRAYSIZE(name), "%.*s", line_end-line_start-2, line_start+1); settings = FindWindowSettings(name); } else if (settings) @@ -1172,7 +1190,7 @@ void NewFrame() else g.IO.MouseDelta = g.IO.MousePos - g.IO.MousePosPrev; g.IO.MousePosPrev = g.IO.MousePos; - for (size_t i = 0; i < ARRAYSIZE(g.IO.MouseDown); i++) + for (size_t i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) { g.IO.MouseDownTime[i] = g.IO.MouseDown[i] ? (g.IO.MouseDownTime[i] < 0.0f ? 0.0f : g.IO.MouseDownTime[i] + g.IO.DeltaTime) : -1.0f; g.IO.MouseClicked[i] = (g.IO.MouseDownTime[i] == 0.0f); @@ -1192,7 +1210,7 @@ void NewFrame() } } } - for (size_t i = 0; i < ARRAYSIZE(g.IO.KeysDown); i++) + for (size_t i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) g.IO.KeysDownTime[i] = g.IO.KeysDown[i] ? (g.IO.KeysDownTime[i] < 0.0f ? 0.0f : g.IO.KeysDownTime[i] + g.IO.DeltaTime) : -1.0f; // Clear reference to active widget if the widget isn't alive anymore @@ -1605,7 +1623,7 @@ static bool IsKeyPressedMap(ImGuiKey key, bool repeat) bool IsKeyPressed(int key_index, bool repeat) { ImGuiState& g = GImGui; - IM_ASSERT(key_index >= 0 && key_index < ARRAYSIZE(g.IO.KeysDown)); + IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown)); const float t = g.IO.KeysDownTime[key_index]; if (t == 0.0f) return true; @@ -1623,7 +1641,7 @@ bool IsKeyPressed(int key_index, bool repeat) bool IsMouseClicked(int button, bool repeat) { ImGuiState& g = GImGui; - IM_ASSERT(button >= 0 && button < ARRAYSIZE(g.IO.MouseDown)); + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); const float t = g.IO.MouseDownTime[button]; if (t == 0.0f) return true; @@ -1641,7 +1659,7 @@ bool IsMouseClicked(int button, bool repeat) bool IsMouseDoubleClicked(int button) { ImGuiState& g = GImGui; - IM_ASSERT(button >= 0 && button < ARRAYSIZE(g.IO.MouseDown)); + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); return g.IO.MouseDoubleClicked[button]; } @@ -1661,7 +1679,7 @@ void SetTooltip(const char* fmt, ...) ImGuiState& g = GImGui; va_list args; va_start(args, fmt); - ImFormatStringV(g.Tooltip, ARRAYSIZE(g.Tooltip), fmt, args); + ImFormatStringV(g.Tooltip, IM_ARRAYSIZE(g.Tooltip), fmt, args); va_end(args); } @@ -1714,7 +1732,7 @@ void BeginChild(const char* str_id, ImVec2 size, bool border, ImGuiWindowFlags e flags |= extra_flags; char title[256]; - ImFormatString(title, ARRAYSIZE(title), "%s.%s", window->Name, str_id); + ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s", window->Name, str_id); const float alpha = (flags & ImGuiWindowFlags_ComboBox) ? 1.0f : 0.0f; ImGui::Begin(title, NULL, size, alpha, flags); @@ -2335,7 +2353,7 @@ void TextV(const char* fmt, va_list args) return; static char buf[1024]; - const char* text_end = buf + ImFormatStringV(buf, ARRAYSIZE(buf), fmt, args); + const char* text_end = buf + ImFormatStringV(buf, IM_ARRAYSIZE(buf), fmt, args); TextUnformatted(buf, text_end); } @@ -2470,7 +2488,7 @@ void LabelText(const char* label, const char* fmt, ...) va_list args; va_start(args, fmt); const char* text_begin = &buf[0]; - const char* text_end = text_begin + ImFormatStringV(buf, ARRAYSIZE(buf), fmt, args); + const char* text_end = text_begin + ImFormatStringV(buf, IM_ARRAYSIZE(buf), fmt, args); va_end(args); const ImVec2 text_size = CalcTextSize(label); @@ -2778,7 +2796,7 @@ void BulletText(const char* fmt, ...) va_list args; va_start(args, fmt); const char* text_begin = buf; - const char* text_end = text_begin + ImFormatStringV(buf, ARRAYSIZE(buf), fmt, args); + const char* text_end = text_begin + ImFormatStringV(buf, IM_ARRAYSIZE(buf), fmt, args); va_end(args); const float line_height = window->FontSize(); @@ -2800,7 +2818,7 @@ bool TreeNode(const char* str_id, const char* fmt, ...) static char buf[1024]; va_list args; va_start(args, fmt); - ImFormatStringV(buf, ARRAYSIZE(buf), fmt, args); + ImFormatStringV(buf, IM_ARRAYSIZE(buf), fmt, args); va_end(args); if (!str_id || !str_id[0]) @@ -2821,7 +2839,7 @@ bool TreeNode(const void* ptr_id, const char* fmt, ...) static char buf[1024]; va_list args; va_start(args, fmt); - ImFormatStringV(buf, ARRAYSIZE(buf), fmt, args); + ImFormatStringV(buf, IM_ARRAYSIZE(buf), fmt, args); va_end(args); if (!ptr_id) @@ -3014,12 +3032,12 @@ bool SliderFloat(const char* label, float* v, float v_min, float v_max, const ch if (start_text_input || (g.ActiveId == id && id == g.SliderAsInputTextId)) { char text_buf[64]; - ImFormatString(text_buf, ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v); + ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v); g.ActiveId = g.SliderAsInputTextId; g.HoveredId = 0; window->FocusItemUnregister(); // Our replacement slider will override the focus ID (that we needed to declare previously to allow for a TAB focus to happen before we got selected) - value_changed = ImGui::InputText(label, text_buf, ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_AlignCenter); + value_changed = ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_AlignCenter); if (g.SliderAsInputTextId == 0) { // First frame @@ -3127,7 +3145,7 @@ bool SliderFloat(const char* label, float* v, float v_min, float v_max, const ch } char value_buf[64]; - ImFormatString(value_buf, ARRAYSIZE(value_buf), display_format, *v); + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); RenderText(ImVec2(slider_bb.GetCenter().x-CalcTextSize(value_buf).x*0.5f, frame_bb.Min.y + style.FramePadding.y), value_buf); RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, slider_bb.Min.y), label); @@ -3596,11 +3614,11 @@ bool InputFloat(const char* label, float *v, float step, float step_fast, int de char buf[64]; if (decimal_precision < 0) - ImFormatString(buf, ARRAYSIZE(buf), "%f", *v); // Ideally we'd have a minimum decimal precision of 1 to visually denote that it is a float, while hiding non-significant digits? + ImFormatString(buf, IM_ARRAYSIZE(buf), "%f", *v); // Ideally we'd have a minimum decimal precision of 1 to visually denote that it is a float, while hiding non-significant digits? else - ImFormatString(buf, ARRAYSIZE(buf), "%.*f", decimal_precision, *v); + ImFormatString(buf, IM_ARRAYSIZE(buf), "%.*f", decimal_precision, *v); bool value_changed = false; - if (ImGui::InputText("", buf, ARRAYSIZE(buf), ImGuiInputTextFlags_CharsDecimal|ImGuiInputTextFlags_AlignCenter|ImGuiInputTextFlags_AutoSelectAll)) + if (ImGui::InputText("", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsDecimal|ImGuiInputTextFlags_AlignCenter|ImGuiInputTextFlags_AutoSelectAll)) { ApplyNumericalTextInput(buf, v); value_changed = true; @@ -3705,7 +3723,7 @@ bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlag bool cancel_edit = false; if (g.ActiveId == id) { - edit_state.BufSize = buf_size < ARRAYSIZE(edit_state.Text) ? buf_size : ARRAYSIZE(edit_state.Text); + edit_state.BufSize = buf_size < IM_ARRAYSIZE(edit_state.Text) ? buf_size : IM_ARRAYSIZE(edit_state.Text); edit_state.Font = window->Font(); edit_state.FontSize = window->FontSize(); @@ -3788,7 +3806,7 @@ bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlag else if (g.IO.InputCharacters[0]) { // Text input - for (int n = 0; n < ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++) + for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++) { const char c = g.IO.InputCharacters[n]; if (c) @@ -4220,7 +4238,7 @@ bool ColorEdit4(const char* label, float col[4], bool alpha) else sprintf(buf, "#%02X%02X%02X", ix, iy, iz); ImGui::PushItemWidth(w_slider_all - g.Style.ItemInnerSpacing.x); - value_changed |= ImGui::InputText("##Text", buf, ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal); + value_changed |= ImGui::InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal); ImGui::PopItemWidth(); char* p = buf; while (*p == '#' || *p == ' ' || *p == '\t') @@ -4700,9 +4718,9 @@ void ImDrawList::AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, i static bool circle_vtx_builds = false; if (!circle_vtx_builds) { - for (int i = 0; i < ARRAYSIZE(circle_vtx); i++) + for (int i = 0; i < IM_ARRAYSIZE(circle_vtx); i++) { - const float a = ((float)i / (float)ARRAYSIZE(circle_vtx)) * 2*PI; + const float a = ((float)i / (float)IM_ARRAYSIZE(circle_vtx)) * 2*PI; circle_vtx[i].x = cos(a + PI); circle_vtx[i].y = sin(a + PI); } @@ -4714,8 +4732,8 @@ void ImDrawList::AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, i ReserveVertices((a_max-a_min) * 3); for (int a = a_min; a < a_max; a++) { - AddVtx(center + circle_vtx[a % ARRAYSIZE(circle_vtx)] * rad, col); - AddVtx(center + circle_vtx[(a+1) % ARRAYSIZE(circle_vtx)] * rad, col); + AddVtx(center + circle_vtx[a % IM_ARRAYSIZE(circle_vtx)] * rad, col); + AddVtx(center + circle_vtx[(a+1) % IM_ARRAYSIZE(circle_vtx)] * rad, col); AddVtx(center + third_point_offset, col); } } @@ -4723,7 +4741,7 @@ void ImDrawList::AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, i { ReserveVertices((a_max-a_min) * 6); for (int a = a_min; a < a_max; a++) - AddVtxLine(center + circle_vtx[a % ARRAYSIZE(circle_vtx)] * rad, center + circle_vtx[(a+1) % ARRAYSIZE(circle_vtx)] * rad, col); + AddVtxLine(center + circle_vtx[a % IM_ARRAYSIZE(circle_vtx)] * rad, center + circle_vtx[(a+1) % IM_ARRAYSIZE(circle_vtx)] * rad, col); } } @@ -5161,6 +5179,66 @@ void ImBitmapFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& c } } +//----------------------------------------------------------------------------- +// PLATFORM DEPENDANT HELPERS +//----------------------------------------------------------------------------- + +#ifdef _MSC_VER +#ifndef IMGUI_DONT_IMPLEMENT_WINDOWS_CLIPBOARD_FUNCTIONS + +#define WIN32_LEAN_AND_MEAN +#include + +static const char* GetClipboardTextFn_DefaultImplWindows() +{ + static char* buf_local = NULL; + if (buf_local) + { + free(buf_local); + buf_local = NULL; + } + + if (!OpenClipboard(NULL)) + return NULL; + + HANDLE buf_handle = GetClipboardData(CF_TEXT); + if (buf_handle == NULL) + return NULL; + + if (char* buf_global = (char*)GlobalLock(buf_handle)) + buf_local = strdup(buf_global); + GlobalUnlock(buf_handle); + CloseClipboard(); + + return buf_local; +} + +static void SetClipboardTextFn_DefaultImplWindows(const char* text, const char* text_end) +{ + if (!OpenClipboard(NULL)) + return; + + if (!text_end) + text_end = text + strlen(text); + + const int buf_length = (text_end - text) + 1; + HGLOBAL buf_handle = GlobalAlloc(GMEM_MOVEABLE, buf_length * sizeof(char)); + if (buf_handle == NULL) + return; + + char* buf_global = (char *)GlobalLock(buf_handle); + memcpy(buf_global, text, text_end - text); + buf_global[text_end - text] = 0; + GlobalUnlock(buf_handle); + + EmptyClipboard(); + SetClipboardData(CF_TEXT, buf_handle); + CloseClipboard(); +} + +#endif // #ifndef IMGUI_DONT_IMPLEMENT_WINDOWS_CLIPBOARD_FUNCTIONS +#endif // #ifdef _MSC_VER + //----------------------------------------------------------------------------- // HELP //----------------------------------------------------------------------------- @@ -5339,12 +5417,12 @@ void ShowTestWindow(bool* open) const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK" }; static int item2 = -1; - ImGui::Combo("combo scroll", &item2, items, ARRAYSIZE(items)); + ImGui::Combo("combo scroll", &item2, items, IM_ARRAYSIZE(items)); static char str0[128] = "Hello, world!"; static int i0=123; static float f0=0.001f; - ImGui::InputText("string", str0, ARRAYSIZE(str0)); + ImGui::InputText("string", str0, IM_ARRAYSIZE(str0)); ImGui::InputInt("input int", &i0); ImGui::InputFloat("input float", &f0, 0.01f, 1.0f); @@ -5387,7 +5465,7 @@ void ShowTestWindow(bool* open) if (ImGui::CollapsingHeader("Graphs widgets")) { static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; - ImGui::PlotLines("Frame Times", arr, ARRAYSIZE(arr)); + ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr)); static bool pause; static ImVector values; if (values.empty()) { values.resize(100); memset(&values.front(), 0, values.size()*sizeof(float)); } @@ -5408,7 +5486,7 @@ void ShowTestWindow(bool* open) ImGui::PlotLines("Frame Times", &values.front(), (int)values.size(), values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,70)); ImGui::SameLine(); ImGui::Checkbox("pause", &pause); - ImGui::PlotHistogram("Histogram", arr, ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,70)); + ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,70)); } if (ImGui::CollapsingHeader("Widgets on same line")) @@ -5498,7 +5576,7 @@ void ShowTestWindow(bool* open) for (int i = 0; i < 100; i++) { char buf[32]; - ImFormatString(buf, ARRAYSIZE(buf), "%08x", i*5731); + ImFormatString(buf, IM_ARRAYSIZE(buf), "%08x", i*5731); ImGui::Button(buf); ImGui::NextColumn(); } @@ -5597,7 +5675,7 @@ void ShowTestWindow(bool* open) static ImGuiTextFilter filter; filter.Draw(); const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" }; - for (size_t i = 0; i < ARRAYSIZE(lines); i++) + for (size_t i = 0; i < IM_ARRAYSIZE(lines); i++) if (filter.PassFilter(lines[i])) ImGui::BulletText("%s", lines[i]); }