Compare commits

...

9 Commits
v1.04 ... v1.05

6 changed files with 359 additions and 241 deletions

View File

@ -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)
@ -271,6 +220,35 @@ void InitImGui()
}
}
INT64 ticks_per_second = 0;
INT64 time = 0;
void UpdateImGui()
{
ImGuiIO& io = ImGui::GetIO();
// Setup timestep
INT64 current_time;
QueryPerformanceCounter((LARGE_INTEGER *)&current_time);
io.DeltaTime = (float)(current_time - time) / ticks_per_second;
time = current_time;
// Setup inputs
// (we already got mouse position, buttons, wheel from the window message callback)
BYTE keystate[256];
GetKeyboardState(keystate);
for (int i = 0; i < 256; i++)
io.KeysDown[i] = (keystate[i] & 0x80) != 0;
io.KeyCtrl = (keystate[VK_CONTROL] & 0x80) != 0;
io.KeyShift = (keystate[VK_SHIFT] & 0x80) != 0;
// io.MousePos : filled by WM_MOUSEMOVE event
// io.MouseDown : filled by WM_*BUTTON* events
// io.MouseWheel : filled by WM_MOUSEWHEEL events
// Start the frame
ImGui::NewFrame();
}
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
// Register the window class
@ -280,101 +258,91 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
// Create the application's window
hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX9 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
INT64 ticks_per_second, time;
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
return 1;
if (!QueryPerformanceCounter((LARGE_INTEGER *)&time))
return 1;
// Initialize Direct3D
if (InitD3D(hWnd) >= 0)
if (InitD3D(hWnd) < 0)
{
if (g_pVB)
g_pVB->Release();
UnregisterClass(L"ImGui Example", wc.hInstance);
return 1;
}
// Show the window
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
InitImGui();
// Enter the message loop
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{
// Show the window
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
InitImGui();
// Enter the message loop
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
continue;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
continue;
}
// 1) ImGui start frame, setup time delta & inputs
ImGuiIO& io = ImGui::GetIO();
INT64 current_time;
QueryPerformanceCounter((LARGE_INTEGER *)&current_time);
io.DeltaTime = (float)(current_time - time) / ticks_per_second;
time = current_time;
BYTE keystate[256];
GetKeyboardState(keystate);
for (int i = 0; i < 256; i++)
io.KeysDown[i] = (keystate[i] & 0x80) != 0;
io.KeyCtrl = (keystate[VK_CONTROL] & 0x80) != 0;
io.KeyShift = (keystate[VK_SHIFT] & 0x80) != 0;
// io.MousePos : filled by WM_MOUSEMOVE event
// io.MouseDown : filled by WM_*BUTTON* events
// io.MouseWheel : filled by WM_MOUSEWHEEL events
ImGui::NewFrame();
UpdateImGui();
// 2) ImGui usage
static bool show_test_window = true;
static bool show_another_window = false;
static float f;
ImGui::Text("Hello, world!");
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
show_test_window ^= ImGui::Button("Test Window");
show_another_window ^= ImGui::Button("Another Window");
// Create a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
static bool show_test_window = true;
static bool show_another_window = false;
static float f;
ImGui::Text("Hello, world!");
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
show_test_window ^= ImGui::Button("Test Window");
show_another_window ^= ImGui::Button("Another Window");
// Calculate and show framerate
static float ms_per_frame[120] = { 0 };
static int ms_per_frame_idx = 0;
static float ms_per_frame_accum = 0.0f;
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
ms_per_frame[ms_per_frame_idx] = io.DeltaTime * 1000.0f;
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
const float ms_per_frame_avg = ms_per_frame_accum / 120;
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
// Calculate and show framerate
static float ms_per_frame[120] = { 0 };
static int ms_per_frame_idx = 0;
static float ms_per_frame_accum = 0.0f;
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f;
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
const float ms_per_frame_avg = ms_per_frame_accum / 120;
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
if (show_test_window)
{
// More example code in ShowTestWindow()
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
ImGui::ShowTestWindow(&show_test_window);
}
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
ImGui::Text("Hello");
ImGui::End();
}
// 3) Rendering
// Clear frame buffer
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false);
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, false);
g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(204, 153, 153), 1.0f, 0);
if (g_pd3dDevice->BeginScene() >= 0)
{
// Render ImGui
ImGui::Render();
g_pd3dDevice->EndScene();
}
g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
// Show the ImGui test window
// Most of user example code is in ImGui::ShowTestWindow()
if (show_test_window)
{
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
ImGui::ShowTestWindow(&show_test_window);
}
ImGui::Shutdown();
}
// Show another simple window
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
ImGui::Text("Hello");
ImGui::End();
}
// Rendering
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false);
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, false);
g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(204, 153, 153), 1.0f, 0);
if (g_pd3dDevice->BeginScene() >= 0)
{
ImGui::Render();
g_pd3dDevice->EndScene();
}
g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}
ImGui::Shutdown();
if (g_pVB)
g_pVB->Release();

View File

@ -5,7 +5,8 @@
#
CXXFLAGS=-framework OpenGL -framework Cocoa -framework IOKit
#CXXFLAGS+=-L/usr/local/Cellar/glew/1.10.0/lib -L/usr/local/Cellar/glfw3/3.0.4/lib
CXXFLAGS+=-I/usr/local/Cellar/glew/1.10.0/include -I/usr/local/Cellar/glfw3/3.0.4/include
CXXFLAGS+=-L/usr/local/Cellar/glew/1.10.0/lib -L/usr/local/Cellar/glfw3/3.0.4/lib
CXXFLAGS+=-lglew -lglfw3
CXXFLAGS+=-I../../
CXXFLAGS+= -D__APPLE__

View File

@ -19,7 +19,7 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
if (cmd_lists_count == 0)
return;
// Setup render state: alpha-blending enabled, no face culling, no depth testing
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
@ -29,11 +29,11 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
// Bind texture
// Setup texture
glBindTexture(GL_TEXTURE_2D, fontTex);
glEnable(GL_TEXTURE_2D);
// Setup matrices
// Setup orthographic projection matrix
const float width = ImGui::GetIO().DisplaySize.x;
const float height = ImGui::GetIO().DisplaySize.y;
glMatrixMode(GL_PROJECTION);
@ -73,24 +73,33 @@ static void ImImpl_SetClipboardTextFn(const char* text, const char* text_end)
if (!text_end)
text_end = text + strlen(text);
// Add a zero-terminator because glfw function doesn't take a size
char* buf = (char*)malloc(text_end - text + 1);
memcpy(buf, text, text_end-text);
buf[text_end-text] = '\0';
glfwSetClipboardString(window, buf);
free(buf);
if (*text_end == 0)
{
// Already got a zero-terminator at 'text_end', we don't need to add one
glfwSetClipboardString(window, text);
}
else
{
// Add a zero-terminator because glfw function doesn't take a size
char* buf = (char*)malloc(text_end - text + 1);
memcpy(buf, text, text_end-text);
buf[text_end-text] = '\0';
glfwSetClipboardString(window, buf);
free(buf);
}
}
// GLFW callbacks to get events
static void glfw_error_callback(int error, const char* description)
{
fputs(description, stderr);
}
static float mouse_wheel = 0.0f;
static void glfw_scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
mouse_wheel = (float)yoffset;
ImGuiIO& io = ImGui::GetIO();
io.MouseWheel = (yoffset != 0.0f) ? yoffset > 0.0f ? 1 : - 1 : 0; // Mouse wheel: -1,0,+1
}
static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
@ -173,37 +182,43 @@ void InitImGui()
stbi_image_free(tex_data);
}
void Shutdown()
void UpdateImGui()
{
ImGui::Shutdown();
glfwTerminate();
ImGuiIO& io = ImGui::GetIO();
// Setup timestep
static double time = 0.0f;
const double current_time = glfwGetTime();
io.DeltaTime = (float)(current_time - time);
time = current_time;
// Setup inputs
// (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents())
double mouse_x, mouse_y;
glfwGetCursorPos(window, &mouse_x, &mouse_y);
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
io.MouseDown[0] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0;
io.MouseDown[1] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0;
// Start the frame
ImGui::NewFrame();
}
// Application code
int main(int argc, char** argv)
{
InitGL();
InitImGui();
double time = glfwGetTime();
while (!glfwWindowShouldClose(window))
{
ImGuiIO& io = ImGui::GetIO();
io.MouseWheel = 0;
glfwPollEvents();
UpdateImGui();
// 1) ImGui start frame, setup time delta & inputs
const double current_time = glfwGetTime();
io.DeltaTime = (float)(current_time - time);
time = current_time;
double mouse_x, mouse_y;
glfwGetCursorPos(window, &mouse_x, &mouse_y);
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
io.MouseDown[0] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0;
io.MouseDown[1] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0;
io.MouseWheel = (mouse_wheel != 0) ? mouse_wheel > 0.0f ? 1 : - 1 : 0; // Mouse wheel: -1,0,+1
mouse_wheel = 0.0f;
ImGui::NewFrame();
// 2) ImGui usage
// Create a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
static bool show_test_window = true;
static bool show_another_window = false;
static float f;
@ -217,19 +232,21 @@ int main(int argc, char** argv)
static int ms_per_frame_idx = 0;
static float ms_per_frame_accum = 0.0f;
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
ms_per_frame[ms_per_frame_idx] = io.DeltaTime * 1000.0f;
ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f;
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
const float ms_per_frame_avg = ms_per_frame_accum / 120;
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
// Show the ImGui test window
// Most of user example code is in ImGui::ShowTestWindow()
if (show_test_window)
{
// More example code in ShowTestWindow()
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
ImGui::ShowTestWindow(&show_test_window);
}
// Show another simple window
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
@ -237,15 +254,15 @@ int main(int argc, char** argv)
ImGui::End();
}
// 3) Rendering
// Rendering
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
glClearColor(0.8f, 0.6f, 0.6f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ImGui::Render();
glfwSwapBuffers(window);
}
Shutdown();
ImGui::Shutdown();
glfwTerminate();
return 0;
}

View File

@ -4,15 +4,22 @@
#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 <vector>
//#define ImVector std::vector
//#define ImVector MyVector
//----- Define assertion handler. Default to calling assert().
// #define IM_ASSERT(_EXPR) MyAssert(_EXPR)
//---- Define assertion handler. Defaults to calling assert().
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
//----- Define implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4.
//---- Don't implement default clipboard handlers for Windows (so as not to link with OpenClipboard(), etc.)
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS
//---- If you are loading a custom font, ImGui expect to find a pure white pixel at (0,0)
// Change it's UV coordinate here if you can't have a white pixel at (0,0)
//#define IMGUI_FONT_TEX_UV_FOR_WHITE ImVec2(0.f/256.f,0.f/256.f)
//---- 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 +30,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
{

236
imgui.cpp
View File

@ -101,7 +101,7 @@
- if you want to use a different font than the default
- create bitmap font data using BMFont. allocate ImGui::GetIO().Font and use ->LoadFromFile()/LoadFromMemory(), set ImGui::GetIO().FontHeight
- load your texture yourself. texture *MUST* have white pixel at UV coordinate 'IMDRAW_TEX_UV_FOR_WHITE' (you can #define it in imconfig.h), this is used by solid objects.
- load your texture yourself. texture *MUST* have white pixel at UV coordinate 'IMGUI_FONT_TEX_UV_FOR_WHITE' (you can #define it in imconfig.h), this is used by solid objects.
- tip: the construct 'if (IMGUI_ONCE_UPON_A_FRAME)' will evaluate to true only once a frame, you can use it to add custom UI in the middle of a deep nested inner loop in your code.
- tip: you can call Render() multiple times (e.g for VR renders), up to you to communicate the extra state to your RenderDrawListFn function.
@ -113,6 +113,7 @@
- window: autofit is losing its purpose when user relies on any dynamic layout (window width multiplier, column). maybe just discard autofit?
- window: support horizontal scroll
- window: fix resize grip scaling along with Rounding style setting
- window/style: add global alpha modifier (not just "fill_alpha")
- widgets: switching from "widget-label" to "label-widget" would make it more convenient to integrate widgets in trees
- widgets: clip text? hover clipped text shows it in a tooltip or in-place overlay
- main: make IsHovered() more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes
@ -145,7 +146,6 @@
- filters: handle wildcards (with implicit leading/trailing *), regexps
- shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus)
- keyboard: full keyboard navigation and focus
- clipboard: add a default "local" implementation of clipboard functions (user will only need to override them to connect to OS clipboard)
- misc: not thread-safe
- optimisation/render: use indexed rendering
- optimisation/render: move clip-rect to vertex data? would allow merging all commands
@ -153,8 +153,6 @@
- optimisation: turn some the various stack vectors into statically-sized arrays
- optimisation: better clipping for multi-component widgets
- optimisation: specialize for height based clipping first (assume widgets never go up + height tests before width tests?)
- optimisation/portability: provide ImVector style implementation
- optimisation/portability: remove dependency on <algorithm>
*/
#include "imgui.h"
@ -196,6 +194,13 @@ static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs);
}; // namespace ImGui
//-----------------------------------------------------------------------------
// Platform dependant default implementations
//-----------------------------------------------------------------------------
static const char* GetClipboardTextFn_DefaultImpl();
static void SetClipboardTextFn_DefaultImpl(const char* text, const char* text_end);
//-----------------------------------------------------------------------------
// User facing structures
//-----------------------------------------------------------------------------
@ -268,6 +273,10 @@ ImGuiIO::ImGuiIO()
MousePosPrev = ImVec2(-1,-1);
MouseDoubleClickTime = 0.30f;
MouseDoubleClickMaxDist = 6.0f;
// Platform dependant default implementations
GetClipboardTextFn = GetClipboardTextFn_DefaultImpl;
SetClipboardTextFn = SetClipboardTextFn_DefaultImpl;
}
// Pass in translated ASCII characters for text input.
@ -287,8 +296,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;
@ -421,7 +429,7 @@ static void ImConvertColorRGBtoHSV(float r, float g, float b, float& out_h, floa
}
const float chroma = r - (g < b ? g : b);
out_h = abs(K + (g - b) / (6.f * chroma + 1e-20f));
out_h = fabsf(K + (g - b) / (6.f * chroma + 1e-20f));
out_s = chroma / (r + 1e-20f);
out_v = r;
}
@ -498,6 +506,7 @@ struct ImGuiDrawContext
float PrevLineHeight;
float LogLineHeight;
int TreeDepth;
ImGuiAabb LastItemAabb;
bool LastItemHovered;
ImVector<ImGuiWindow*> ChildWindows;
ImVector<bool> AllowKeyboardFocus;
@ -520,6 +529,7 @@ struct ImGuiDrawContext
CurrentLineHeight = PrevLineHeight = 0.0f;
LogLineHeight = -1.0f;
TreeDepth = 0;
LastItemAabb = ImGuiAabb(0.0f,0.0f,0.0f,0.0f);
LastItemHovered = false;
StateStorage = NULL;
OpenNextNode = -1;
@ -609,6 +619,7 @@ struct ImGuiState
ImGuiStorage ColorEditModeStorage; // for user selection
ImGuiID ActiveComboID;
char Tooltip[1024];
char* PrivateClipboard; // if no custom clipboard handler is defined
// Logging
bool LogEnabled;
@ -632,6 +643,7 @@ struct ImGuiState
SliderAsInputTextId = 0;
ActiveComboID = 0;
memset(Tooltip, 0, sizeof(Tooltip));
PrivateClipboard = NULL;
LogEnabled = false;
LogFile = NULL;
LogAutoExpandMaxDepth = 2;
@ -795,7 +807,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 +1069,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 +1184,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 +1204,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
@ -1292,6 +1304,12 @@ void Shutdown()
g.IO.Font = NULL;
}
if (g.PrivateClipboard)
{
free(g.PrivateClipboard);
g.PrivateClipboard = NULL;
}
g.Initialized = false;
}
@ -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];
}
@ -1656,12 +1674,24 @@ bool IsHovered()
return window->DC.LastItemHovered;
}
ImVec2 GetItemBoxMin()
{
ImGuiWindow* window = GetCurrentWindow();
return window->DC.LastItemAabb.Min;
}
ImVec2 GetItemBoxMax()
{
ImGuiWindow* window = GetCurrentWindow();
return window->DC.LastItemAabb.Max;
}
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 +1744,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);
@ -1803,15 +1833,13 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin
parent_window->DC.ChildWindows.push_back(window);
window->Pos = window->PosFloat = parent_window->DC.CursorPos;
window->SizeFull = size;
if (!(flags & ImGuiWindowFlags_ComboBox))
ImGui::PushClipRect(parent_window->ClipRectStack.back());
else
ImGui::PushClipRect(ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y));
}
// Outer clipping rectangle
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_ComboBox))
ImGui::PushClipRect(g.CurrentWindowStack[g.CurrentWindowStack.size()-2]->ClipRectStack.back());
else
{
ImGui::PushClipRect(ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y));
}
// ID stack
window->IDStack.resize(0);
@ -2052,8 +2080,16 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin
ImGui::CloseWindowButton(open);
}
}
else
{
// Outer clipping rectangle
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_ComboBox))
ImGui::PushClipRect(g.CurrentWindowStack[g.CurrentWindowStack.size()-2]->ClipRectStack.back());
else
ImGui::PushClipRect(ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y));
}
// Clip rectangle
// Innter clipping rectangle
// We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame
const ImGuiAabb title_bar_aabb = window->TitleBarAabb();
ImVec4 clip_rect(title_bar_aabb.Min.x+0.5f, title_bar_aabb.Max.y+0.5f, window->Aabb().Max.x-1.5f, window->Aabb().Max.y-1.5f);
@ -2335,7 +2371,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 +2506,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 +2814,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 +2836,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 +2857,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)
@ -2981,8 +3017,8 @@ bool SliderFloat(const char* label, float* v, float v_min, float v_max, const ch
if (v_min * v_max < 0.0f)
{
// Different sign
const float linear_dist_min_to_0 = powf(abs(0.0f - v_min), 1.0f/power);
const float linear_dist_max_to_0 = powf(abs(v_max - 0.0f), 1.0f/power);
const float linear_dist_min_to_0 = powf(fabsf(0.0f - v_min), 1.0f/power);
const float linear_dist_max_to_0 = powf(fabsf(v_max - 0.0f), 1.0f/power);
linear_zero_pos = linear_dist_min_to_0 / (linear_dist_min_to_0+linear_dist_max_to_0);
}
else
@ -3014,12 +3050,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
@ -3052,7 +3088,7 @@ bool SliderFloat(const char* label, float* v, float v_min, float v_max, const ch
if (!is_unbound)
{
const float normalized_pos = ImClamp((g.IO.MousePos.x - slider_effective_x1) / slider_effective_w, 0.0f, 1.0f);
// Linear slider
//float new_value = ImLerp(v_min, v_max, normalized_pos);
@ -3068,9 +3104,11 @@ bool SliderFloat(const char* label, float* v, float v_min, float v_max, const ch
else
{
// Positive: rescale to the positive range before powering
float a = normalized_pos;
if (abs(linear_zero_pos - 1.0f) > 1.e-6)
a = (a - linear_zero_pos) / (1.0f - linear_zero_pos);
float a;
if (fabsf(linear_zero_pos - 1.0f) > 1.e-6)
a = (normalized_pos - linear_zero_pos) / (1.0f - linear_zero_pos);
else
a = normalized_pos;
a = powf(a, power);
new_value = ImLerp(ImMax(v_min,0.0f), v_max, a);
}
@ -3127,7 +3165,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 +3634,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 +3743,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 +3826,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 +4258,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')
@ -4378,6 +4416,7 @@ bool IsClipped(ImVec2 item_size)
static bool ClipAdvance(const ImGuiAabb& bb)
{
ImGuiWindow* window = GetCurrentWindow();
window->DC.LastItemAabb = bb;
if (ImGui::IsClipped(bb))
{
window->DC.LastItemHovered = false;
@ -4667,7 +4706,7 @@ void ImDrawList::AddVtx(const ImVec2& pos, ImU32 col)
{
vtx_write->pos = pos;
vtx_write->col = col;
vtx_write->uv = IMDRAW_TEX_UV_FOR_WHITE;
vtx_write->uv = IMGUI_FONT_TEX_UV_FOR_WHITE;
vtx_write++;
}
@ -4700,9 +4739,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 +4753,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 +4762,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);
}
}
@ -4732,10 +4771,10 @@ void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float roun
if ((col >> 24) == 0)
return;
//const float r = ImMin(rounding, ImMin(abs(b.x-a.x), abs(b.y-a.y))*0.5f);
//const float r = ImMin(rounding, ImMin(fabsf(b.x-a.x), fabsf(b.y-a.y))*0.5f);
float r = rounding;
r = ImMin(r, abs(b.x-a.x) * ( ((rounding_corners&(1|2))==(1|2)) || ((rounding_corners&(4|8))==(4|8)) ? 0.5f : 1.0f ));
r = ImMin(r, abs(b.y-a.y) * ( ((rounding_corners&(1|8))==(1|8)) || ((rounding_corners&(2|4))==(2|4)) ? 0.5f : 1.0f ));
r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners&(1|2))==(1|2)) || ((rounding_corners&(4|8))==(4|8)) ? 0.5f : 1.0f ));
r = ImMin(r, fabsf(b.y-a.y) * ( ((rounding_corners&(1|8))==(1|8)) || ((rounding_corners&(2|4))==(2|4)) ? 0.5f : 1.0f ));
if (r == 0.0f || rounding_corners == 0)
{
@ -4765,10 +4804,10 @@ void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, floa
if ((col >> 24) == 0)
return;
//const float r = ImMin(rounding, ImMin(abs(b.x-a.x), abs(b.y-a.y))*0.5f);
//const float r = ImMin(rounding, ImMin(fabsf(b.x-a.x), fabsf(b.y-a.y))*0.5f);
float r = rounding;
r = ImMin(r, abs(b.x-a.x) * ( ((rounding_corners&(1|2))==(1|2)) || ((rounding_corners&(4|8))==(4|8)) ? 0.5f : 1.0f ));
r = ImMin(r, abs(b.y-a.y) * ( ((rounding_corners&(1|8))==(1|8)) || ((rounding_corners&(2|4))==(2|4)) ? 0.5f : 1.0f ));
r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners&(1|2))==(1|2)) || ((rounding_corners&(4|8))==(4|8)) ? 0.5f : 1.0f ));
r = ImMin(r, fabsf(b.y-a.y) * ( ((rounding_corners&(1|8))==(1|8)) || ((rounding_corners&(2|4))==(2|4)) ? 0.5f : 1.0f ));
if (r == 0.0f || rounding_corners == 0)
{
@ -5161,6 +5200,81 @@ void ImBitmapFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& c
}
}
//-----------------------------------------------------------------------------
// PLATFORM DEPENDANT HELPERS
//-----------------------------------------------------------------------------
#if defined(_MSC_VER) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// Win32 API clipboard implementation
static const char* GetClipboardTextFn_DefaultImpl()
{
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;
}
// Win32 API clipboard implementation
static void SetClipboardTextFn_DefaultImpl(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();
}
#else
// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
static const char* GetClipboardTextFn_DefaultImpl()
{
return GImGui.PrivateClipboard;
}
// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
static void SetClipboardTextFn_DefaultImpl(const char* text, const char* text_end)
{
if (GImGui.PrivateClipboard)
{
free(GImGui.PrivateClipboard);
GImGui.PrivateClipboard = NULL;
}
if (!text_end)
text_end = text + strlen(text);
GImGui.PrivateClipboard = (char*)malloc(text_end - text + 1);
memcpy(GImGui.PrivateClipboard, text, text_end - text);
GImGui.PrivateClipboard[text_end - text] = 0;
}
#endif
//-----------------------------------------------------------------------------
// HELP
//-----------------------------------------------------------------------------
@ -5339,12 +5453,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 +5501,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<float> values; if (values.empty()) { values.resize(100); memset(&values.front(), 0, values.size()*sizeof(float)); }
@ -5408,7 +5522,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 +5612,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 +5711,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]);
}

25
imgui.h
View File

@ -232,6 +232,8 @@ namespace ImGui
void SetTooltip(const char* fmt, ...); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). (currently no contention handling, last call win)
void SetNewWindowDefaultPos(ImVec2 pos); // set position of window that do
bool IsHovered(); // was the last item active area hovered by mouse?
ImVec2 GetItemBoxMin(); // get bounding box of last item
ImVec2 GetItemBoxMax(); // get bounding box of last item
bool IsClipped(ImVec2 item_size); // to perform coarse clipping on user's side (as an optimisation)
bool IsKeyPressed(int key_index, bool repeat = true); // key_index into the keys_down[512] array, imgui doesn't know the semantic of each entry
bool IsMouseClicked(int button, bool repeat = false);
@ -382,10 +384,16 @@ struct ImGuiIO
bool FontAllowScaling; // = false // Set to allow scaling text with CTRL+Wheel.
float PixelCenterOffset; // = 0.5f // Set to 0.0f for DirectX <= 9, 0.5f for Direct3D >= 10 and OpenGL.
// Settings - Functions (fill once)
void (*RenderDrawListsFn)(ImDrawList** const draw_lists, int count); // Required
const char* (*GetClipboardTextFn)(); // Required for clipboard support
void (*SetClipboardTextFn)(const char* text, const char* text_end); // Required for clipboard support (nb- the string is *NOT* zero-terminated at 'text_end')
// Settings - Rendering function (REQUIRED)
// See example code if you are unsure of how to implement this.
void (*RenderDrawListsFn)(ImDrawList** const draw_lists, int count);
// Settings - Clipboard Support
// Override to provide your clipboard handlers.
// On Windows architecture, defaults to use the native Win32 clipboard, otherwise default to use a ImGui private clipboard.
// NB- for SetClipboardTextFn, the string is *NOT* zero-terminated at 'text_end'
const char* (*GetClipboardTextFn)();
void (*SetClipboardTextFn)(const char* text, const char* text_end);
// Input - Fill before calling NewFrame()
ImVec2 MousePos; // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
@ -507,8 +515,8 @@ struct ImDrawCmd
ImVec4 clip_rect;
};
#ifndef IMDRAW_TEX_UV_FOR_WHITE
#define IMDRAW_TEX_UV_FOR_WHITE ImVec2(0,0)
#ifndef IMGUI_FONT_TEX_UV_FOR_WHITE
#define IMGUI_FONT_TEX_UV_FOR_WHITE ImVec2(0.f,0.f)
#endif
// sizeof() == 20
@ -523,8 +531,11 @@ struct ImDrawVert
// User is responsible for providing a renderer for this in ImGuiIO::RenderDrawListFn
struct ImDrawList
{
ImVector<ImDrawCmd> commands;
// This is what you have to render
ImVector<ImDrawCmd> commands; // commands
ImVector<ImDrawVert> vtx_buffer; // each command consume ImDrawCmd::vtx_count of those
// [Internal to ImGui]
ImVector<ImVec4> clip_rect_stack; // [internal] clip rect stack while building the command-list (so text command can perform clipping early on)
ImDrawVert* vtx_write; // [internal] point within vtx_buffer after each add command (to avoid using the ImVector<> operators too much)