1
0
Fork 0
mirror of https://github.com/ocornut/imgui.git synced 2026-01-18 01:14:19 +00:00

Merge pull request #1 from ocornut/master

Merge
This commit is contained in:
Tomoki "T_S" SHISHIKURA 2014-10-01 13:48:21 +09:00
commit 3bec9e782e
4 changed files with 201 additions and 137 deletions

View file

@ -168,11 +168,9 @@ LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
io.AddInputCharacter((unsigned short)wParam);
return true;
case WM_DESTROY:
{
Cleanup();
PostQuitMessage(0);
return 0;
}
Cleanup();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
@ -180,14 +178,14 @@ LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
// Notify OS Input Method Editor of text input position (e.g. when using Japanese/Chinese inputs, otherwise this isn't needed)
static void ImImpl_ImeSetInputScreenPosFn(int x, int y)
{
if (HIMC himc = ImmGetContext(hWnd))
{
COMPOSITIONFORM cf;
cf.ptCurrentPos.x = x;
cf.ptCurrentPos.y = y;
cf.dwStyle = CFS_FORCE_POSITION;
ImmSetCompositionWindow(himc, &cf);
}
if (HIMC himc = ImmGetContext(hWnd))
{
COMPOSITIONFORM cf;
cf.ptCurrentPos.x = x;
cf.ptCurrentPos.y = y;
cf.dwStyle = CFS_FORCE_POSITION;
ImmSetCompositionWindow(himc, &cf);
}
}
void InitImGui()
@ -218,7 +216,7 @@ void InitImGui()
io.KeyMap[ImGuiKey_Z] = 'Z';
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
io.ImeSetInputScreenPosFn = ImImpl_ImeSetInputScreenPosFn;
io.ImeSetInputScreenPosFn = ImImpl_ImeSetInputScreenPosFn;
// Create the vertex buffer
if (g_pd3dDevice->CreateVertexBuffer(10000 * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0)
@ -310,36 +308,31 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
UpdateImGui();
// 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] = 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)
// 1. Show a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
{
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);
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] = 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 another simple window
// 2. Show another simple window, this time using an explicit Begin/End pair
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
@ -347,6 +340,13 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
ImGui::End();
}
// 3. Show the ImGui test window. Most of the sample 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);
}
// Rendering
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false);
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);

View file

@ -19,6 +19,7 @@
static GLFWwindow* window;
static GLuint fontTex;
static bool mousePressed[2] = { false, false };
static ImVec2 mousePosScale(1.0f, 1.0f);
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
@ -94,15 +95,15 @@ static void ImImpl_SetClipboardTextFn(const char* text)
// Notify OS Input Method Editor of text input position (e.g. when using Japanese/Chinese inputs, otherwise this isn't needed)
static void ImImpl_ImeSetInputScreenPosFn(int x, int y)
{
HWND hwnd = glfwGetWin32Window(window);
if (HIMC himc = ImmGetContext(hwnd))
{
COMPOSITIONFORM cf;
cf.ptCurrentPos.x = x;
cf.ptCurrentPos.y = y;
cf.dwStyle = CFS_FORCE_POSITION;
ImmSetCompositionWindow(himc, &cf);
}
HWND hwnd = glfwGetWin32Window(window);
if (HIMC himc = ImmGetContext(hwnd))
{
COMPOSITIONFORM cf;
cf.ptCurrentPos.x = x;
cf.ptCurrentPos.y = y;
cf.dwStyle = CFS_FORCE_POSITION;
ImmSetCompositionWindow(himc, &cf);
}
}
#endif
@ -112,6 +113,12 @@ static void glfw_error_callback(int error, const char* description)
fputs(description, stderr);
}
static void glfw_mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
if (action == GLFW_PRESS && button >= 0 && button < 2)
mousePressed[button] = true;
}
static void glfw_scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
ImGuiIO& io = ImGui::GetIO();
@ -147,6 +154,7 @@ void InitGL()
window = glfwCreateWindow(1280, 720, "ImGui OpenGL example", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, glfw_key_callback);
glfwSetMouseButtonCallback(window, glfw_mouse_button_callback);
glfwSetScrollCallback(window, glfw_scroll_callback);
glfwSetCharCallback(window, glfw_char_callback);
@ -188,7 +196,7 @@ void InitImGui()
io.SetClipboardTextFn = ImImpl_SetClipboardTextFn;
io.GetClipboardTextFn = ImImpl_GetClipboardTextFn;
#ifdef _MSC_VER
io.ImeSetInputScreenPosFn = ImImpl_ImeSetInputScreenPosFn;
io.ImeSetInputScreenPosFn = ImImpl_ImeSetInputScreenPosFn;
#endif
// Load font texture
@ -198,35 +206,35 @@ void InitImGui()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
#if 1
// Default font (embedded in code)
// Default font (embedded in code)
const void* png_data;
unsigned int png_size;
ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size);
int tex_x, tex_y, tex_comp;
void* tex_data = stbi_load_from_memory((const unsigned char*)png_data, (int)png_size, &tex_x, &tex_y, &tex_comp, 0);
IM_ASSERT(tex_data != NULL);
IM_ASSERT(tex_data != NULL);
#else
// Custom font from filesystem
io.Font = new ImBitmapFont();
io.Font->LoadFromFile("../../extra_fonts/mplus-2m-medium_18.fnt");
IM_ASSERT(io.Font->IsLoaded());
// Custom font from filesystem
io.Font = new ImBitmapFont();
io.Font->LoadFromFile("../../extra_fonts/mplus-2m-medium_18.fnt");
IM_ASSERT(io.Font->IsLoaded());
int tex_x, tex_y, tex_comp;
void* tex_data = stbi_load("../../extra_fonts/mplus-2m-medium_18.png", &tex_x, &tex_y, &tex_comp, 0);
IM_ASSERT(tex_data != NULL);
// Automatically find white pixel from the texture we just loaded
// (io.FontTexUvForWhite needs to contains UV coordinates pointing to a white pixel in order to render solid objects)
for (int tex_data_off = 0; tex_data_off < tex_x*tex_y; tex_data_off++)
if (((unsigned int*)tex_data)[tex_data_off] == 0xffffffff)
{
io.FontTexUvForWhite = ImVec2((float)(tex_data_off % tex_x)/(tex_x), (float)(tex_data_off / tex_x)/(tex_y));
break;
}
void* tex_data = stbi_load("../../extra_fonts/mplus-2m-medium_18.png", &tex_x, &tex_y, &tex_comp, 0);
IM_ASSERT(tex_data != NULL);
// Automatically find white pixel from the texture we just loaded
// (io.FontTexUvForWhite needs to contains UV coordinates pointing to a white pixel in order to render solid objects)
for (int tex_data_off = 0; tex_data_off < tex_x*tex_y; tex_data_off++)
if (((unsigned int*)tex_data)[tex_data_off] == 0xffffffff)
{
io.FontTexUvForWhite = ImVec2((float)(tex_data_off % tex_x)/(tex_x), (float)(tex_data_off / tex_x)/(tex_y));
break;
}
#endif
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_x, tex_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
stbi_image_free(tex_data);
stbi_image_free(tex_data);
}
void UpdateImGui()
@ -243,9 +251,9 @@ void UpdateImGui()
// (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 * mousePosScale.x, (float)mouse_y * mousePosScale.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.MousePos = ImVec2((float)mouse_x * mousePosScale.x, (float)mouse_y * mousePosScale.y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
io.MouseDown[0] = mousePressed[0] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
io.MouseDown[1] = mousePressed[1] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0;
// Start the frame
ImGui::NewFrame();
@ -260,40 +268,36 @@ int main(int argc, char** argv)
while (!glfwWindowShouldClose(window))
{
ImGuiIO& io = ImGui::GetIO();
mousePressed[0] = mousePressed[1] = false;
io.MouseWheel = 0;
glfwPollEvents();
UpdateImGui();
// 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] = 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)
// 1. Show a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
{
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);
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] = 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 another simple window
// 2. Show another simple window, this time using an explicit Begin/End pair
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
@ -301,6 +305,13 @@ int main(int argc, char** argv)
ImGui::End();
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (show_test_window)
{
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call this, because positions are saved in .ini file. Here we just want to make the demo initial state a bit more friendly!
ImGui::ShowTestWindow(&show_test_window);
}
// Rendering
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
glClearColor(0.8f, 0.6f, 0.6f, 1.0f);

134
imgui.cpp
View file

@ -1,4 +1,4 @@
// ImGui library v1.13
// ImGui library v1.14 wip
// See ImGui::ShowTestWindow() for sample code.
// Read 'Programmer guide' below for notes on how to setup ImGui in your codebase.
// Get latest version at https://github.com/ocornut/imgui
@ -185,11 +185,13 @@
- filters: set a current filter that tree node can automatically query to hide themselves
- 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)
- input: keyboard: full keyboard navigation and focus.
! keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing
- keyboard: full keyboard navigation and focus.
- input: support trackpad style scrolling & slider edit.
- tooltip: move to fit within screen (e.g. when mouse cursor is right of the screen).
- misc: not thread-safe
- misc: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon?
- style editor: add a button to print C code.
- style editor: add a button to output C code.
- optimisation/render: use indexed rendering
- optimisation/render: move clip-rect to vertex data? would allow merging all commands
- optimisation/render: merge command-lists with same clip-rect into one even if they aren't sequential? (as long as in-between clip rectangle don't overlap)?
@ -760,13 +762,16 @@ struct ImGuiWindow
float ItemWidthDefault;
ImGuiStorage StateStorage;
float FontWindowScale; // Scale multipler per-window
int FocusIdxCounter; // Start at -1 and increase as assigned via FocusItemRegister()
int FocusIdxRequestCurrent; // Item being requested for focus, rely on layout to be stable between the frame pressing TAB and the next frame
int FocusIdxRequestNext; // Item being requested for focus, for next update
ImDrawList* DrawList;
// Focus
int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister()
int FocusIdxTabCounter; // (same, but only count widgets which you can Tab through)
int FocusIdxAllRequestCurrent; // Item being requested for focus
int FocusIdxTabRequestCurrent; // Tab-able item being requested for focus
int FocusIdxAllRequestNext; // Item being requested for focus, for next update (relies on layout to be stable between the frame pressing TAB and the next frame)
int FocusIdxTabRequestNext; // "
public:
ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_size);
~ImGuiWindow();
@ -775,7 +780,7 @@ public:
ImGuiID GetID(const void* ptr);
void AddToRenderList();
bool FocusItemRegister(bool is_active, int* out_idx = NULL); // Return TRUE if focus is requested
bool FocusItemRegister(bool is_active); // Return true if focus is requested
void FocusItemUnregister();
ImGuiAabb Aabb() const { return ImGuiAabb(Pos, Pos+Size); }
@ -1017,12 +1022,12 @@ ImGuiWindow::ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_si
if (ImLength(Size) < 0.001f)
AutoFitFrames = 3;
FocusIdxCounter = -1;
FocusIdxRequestCurrent = IM_INT_MAX;
FocusIdxRequestNext = IM_INT_MAX;
DrawList = (ImDrawList*)ImGui::MemAlloc(sizeof(ImDrawList));
new(DrawList) ImDrawList();
FocusIdxAllCounter = FocusIdxTabCounter = -1;
FocusIdxAllRequestCurrent = FocusIdxTabRequestCurrent = IM_INT_MAX;
FocusIdxAllRequestNext = FocusIdxTabRequestNext = IM_INT_MAX;
}
ImGuiWindow::~ImGuiWindow()
@ -1050,31 +1055,38 @@ ImGuiID ImGuiWindow::GetID(const void* ptr)
return id;
}
bool ImGuiWindow::FocusItemRegister(bool is_active, int* out_idx)
bool ImGuiWindow::FocusItemRegister(bool is_active)
{
FocusIdxCounter++;
if (out_idx)
*out_idx = FocusIdxCounter;
ImGuiState& g = GImGui;
ImGuiWindow* window = GetCurrentWindow();
if (!window->DC.AllowKeyboardFocus.back())
return false;
// Process input at this point: TAB, Shift-TAB switch focus
if (FocusIdxRequestNext == IM_INT_MAX && is_active && ImGui::IsKeyPressedMap(ImGuiKey_Tab))
const bool allow_keyboard_focus = window->DC.AllowKeyboardFocus.back();
FocusIdxAllCounter++;
if (allow_keyboard_focus)
FocusIdxTabCounter++;
// Process keyboard input at this point: TAB, Shift-TAB switch focus
// We can always TAB out of a widget that doesn't allow tabbing in.
if (FocusIdxAllRequestNext == IM_INT_MAX && FocusIdxTabRequestNext == IM_INT_MAX && is_active && ImGui::IsKeyPressedMap(ImGuiKey_Tab))
{
// Modulo on index will be applied at the end of frame once we've got the total counter of items.
FocusIdxRequestNext = FocusIdxCounter + (g.IO.KeyShift ? -1 : +1);
FocusIdxTabRequestNext = FocusIdxTabCounter + (g.IO.KeyShift ? (allow_keyboard_focus ? -1 : 0) : +1);
}
const bool focus_requested = (FocusIdxCounter == FocusIdxRequestCurrent);
return focus_requested;
if (FocusIdxAllCounter == FocusIdxAllRequestCurrent)
return true;
if (allow_keyboard_focus)
if (FocusIdxTabCounter == FocusIdxTabRequestCurrent)
return true;
return false;
}
void ImGuiWindow::FocusItemUnregister()
{
FocusIdxCounter--;
FocusIdxAllCounter--;
FocusIdxTabCounter--;
}
void ImGuiWindow::AddToRenderList()
@ -1387,7 +1399,7 @@ void NewFrame()
// NB: Don't discard FocusedWindow if it isn't active, so that a window that go on/off programatically won't lose its keyboard focus.
if (g.ActiveId == 0 && g.FocusedWindow != NULL && g.FocusedWindow->Visible && IsKeyPressedMap(ImGuiKey_Tab, false))
{
g.FocusedWindow->FocusIdxRequestNext = 0;
g.FocusedWindow->FocusIdxTabRequestNext = 0;
}
// Mark all windows as not visible
@ -2094,18 +2106,17 @@ bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWin
else
window->ItemWidthDefault = 200.0f;
// Prepare for keyboard focus requests
if (window->FocusIdxRequestNext == IM_INT_MAX || window->FocusIdxCounter == -1)
{
window->FocusIdxRequestCurrent = IM_INT_MAX;
}
// Prepare for focus requests
if (window->FocusIdxAllRequestNext == IM_INT_MAX || window->FocusIdxAllCounter == -1)
window->FocusIdxAllRequestCurrent = IM_INT_MAX;
else
{
const int mod = window->FocusIdxCounter+1;
window->FocusIdxRequestCurrent = (window->FocusIdxRequestNext + mod) % mod;
}
window->FocusIdxCounter = -1;
window->FocusIdxRequestNext = IM_INT_MAX;
window->FocusIdxAllRequestCurrent = (window->FocusIdxAllRequestNext + (window->FocusIdxAllCounter+1)) % (window->FocusIdxAllCounter+1);
if (window->FocusIdxTabRequestNext == IM_INT_MAX || window->FocusIdxTabCounter == -1)
window->FocusIdxTabRequestCurrent = IM_INT_MAX;
else
window->FocusIdxTabRequestCurrent = (window->FocusIdxTabRequestNext + (window->FocusIdxTabCounter+1)) % (window->FocusIdxTabCounter+1);
window->FocusIdxAllCounter = window->FocusIdxTabCounter = -1;
window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = IM_INT_MAX;
ImGuiAabb title_bar_aabb = window->TitleBarAabb();
@ -2627,6 +2638,13 @@ void SetScrollPosHere()
window->NextScrollY = (window->DC.CursorPos.y + window->ScrollY) - (window->Pos.y + window->SizeFull.y * 0.5f) - (window->TitleBarHeight() + window->WindowPadding().y);
}
void SetKeyboardFocusHere(int offset)
{
ImGuiWindow* window = GetCurrentWindow();
window->FocusIdxAllRequestNext = window->FocusIdxAllCounter + 1 + offset;
window->FocusIdxTabRequestNext = IM_INT_MAX;
}
void SetTreeStateStorage(ImGuiStorage* tree)
{
ImGuiWindow* window = GetCurrentWindow();
@ -6021,9 +6039,6 @@ void ShowTestWindow(bool* open)
ImGui::Text("Thanks for clicking me!");
}
static bool check = true;
ImGui::Checkbox("checkbox", &check);
if (ImGui::TreeNode("Tree"))
{
for (size_t i = 0; i < 5; i++)
@ -6071,6 +6086,8 @@ void ShowTestWindow(bool* open)
ImGui::TreePop();
}
static bool check = true;
ImGui::Checkbox("checkbox", &check);
static int e = 0;
ImGui::RadioButton("radio a", &e, 0); ImGui::SameLine();
@ -6374,6 +6391,41 @@ void ShowTestWindow(bool* open)
ImGui::BulletText("%s", lines[i]);
}
if (ImGui::CollapsingHeader("Keyboard & Focus"))
{
if (ImGui::TreeNode("Tabbing"))
{
ImGui::Text("Use TAB/SHIFT+TAB to cycle thru keyboard editable fields.");
static char buf[32] = "dummy";
ImGui::InputText("1", buf, IM_ARRAYSIZE(buf));
ImGui::InputText("2", buf, IM_ARRAYSIZE(buf));
ImGui::InputText("3", buf, IM_ARRAYSIZE(buf));
ImGui::PushAllowKeyboardFocus(false);
ImGui::InputText("4 (tab skip)", buf, IM_ARRAYSIZE(buf));
//ImGui::SameLine(); ImGui::Text("(?)"); if (ImGui::IsHovered()) ImGui::SetTooltip("Use ImGui::PushAllowKeyboardFocus(bool)\nto disable tabbing through certain widgets.");
ImGui::PopAllowKeyboardFocus();
ImGui::InputText("5", buf, IM_ARRAYSIZE(buf));
ImGui::TreePop();
}
if (ImGui::TreeNode("Focus from code"))
{
bool focus_1 = ImGui::Button("Focus on 1"); ImGui::SameLine();
bool focus_2 = ImGui::Button("Focus on 2"); ImGui::SameLine();
bool focus_3 = ImGui::Button("Focus on 3");
static char buf[128] = "click on a button to set focus";
if (focus_1) ImGui::SetKeyboardFocusHere();
ImGui::InputText("1", buf, IM_ARRAYSIZE(buf));
if (focus_2) ImGui::SetKeyboardFocusHere();
ImGui::InputText("2", buf, IM_ARRAYSIZE(buf));
ImGui::PushAllowKeyboardFocus(false);
if (focus_3) ImGui::SetKeyboardFocusHere();
ImGui::InputText("3 (tab skip)", buf, IM_ARRAYSIZE(buf));
ImGui::PopAllowKeyboardFocus();
ImGui::TreePop();
}
}
if (ImGui::CollapsingHeader("Long text"))
{
static ImGuiTextBuffer log;

View file

@ -1,4 +1,4 @@
// ImGui library v1.13
// ImGui library v1.14 wip
// See .cpp file for commentary.
// See ImGui::ShowTestWindow() for sample code.
// Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase.
@ -153,12 +153,13 @@ namespace ImGui
ImDrawList* GetWindowDrawList(); // get rendering command-list if you want to append your own draw primitives.
void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontBaseScale if you want to scale all windows together.
void SetScrollPosHere(); // adjust scrolling position to center into the current cursor position.
void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use 'offset' to access sub components of a multiple component widget.
void SetTreeStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it).
ImGuiStorage* GetTreeStateStorage();
void PushItemWidth(float item_width);
void PopItemWidth();
float GetItemWidth();
void PushAllowKeyboardFocus(bool v);
void PushAllowKeyboardFocus(bool v); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets.
void PopAllowKeyboardFocus();
void PushStyleColor(ImGuiCol idx, const ImVec4& col);
void PopStyleColor();
@ -419,7 +420,7 @@ struct ImGuiIO
ImVec2 FontTexUvForWhite; // = (0.0f,0.0f) // Font texture must have a white pixel at this UV coordinate. Adjust if you are using custom texture.
float FontBaseScale; // = 1.0f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale()
bool FontAllowUserScaling; // = false // Set to allow scaling text with CTRL+Wheel.
ImWchar FontFallbackGlyph; // = '?' // Replacement glyph is one isn't found.
ImWchar FontFallbackGlyph; // = '?' // Replacement glyph is one isn't found.
float PixelCenterOffset; // = 0.0f // Try to set to 0.5f or 0.375f if rendering is blurry
//------------------------------------------------------------------