Compare commits

..

1 Commits

Author SHA1 Message Date
30f2ca893f WIP insert mode (2863)
missing cursor rendering (keep caret when on carriage return)
missing storage of insert state
2021-03-12 18:56:40 +01:00
58 changed files with 1107 additions and 1790 deletions

View File

@ -254,11 +254,10 @@ jobs:
EOF EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with large ImDrawIdx + pointer ImTextureID) - name: Build example_null (with large ImDrawIdx)
run: | run: |
cat > example_single_file.cpp <<'EOF' cat > example_single_file.cpp <<'EOF'
#define ImTextureID void*
#define ImDrawIdx unsigned int #define ImDrawIdx unsigned int
#define IMGUI_IMPLEMENTATION #define IMGUI_IMPLEMENTATION
#include "misc/single_file/imgui_single_file.h" #include "misc/single_file/imgui_single_file.h"

3
.gitignore vendored
View File

@ -26,9 +26,6 @@ ipch
*.VC.db *.VC.db
*.VC.VC.opendb *.VC.VC.opendb
## Commonly used CMake directories
/build*/
## Xcode artifacts ## Xcode artifacts
project.xcworkspace project.xcworkspace
xcuserdata xcuserdata

View File

@ -15,7 +15,6 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2021-05-19: Renderer: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-02-18: Change blending equation to preserve alpha in output buffer. // 2021-02-18: Change blending equation to preserve alpha in output buffer.
// 2020-08-10: Inputs: Fixed horizontal mouse wheel direction. // 2020-08-10: Inputs: Fixed horizontal mouse wheel direction.
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
@ -158,7 +157,7 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
else else
{ {
// Draw // Draw
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->GetTexID(); ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
al_set_clipping_rectangle(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y, pcmd->ClipRect.z - pcmd->ClipRect.x, pcmd->ClipRect.w - pcmd->ClipRect.y); al_set_clipping_rectangle(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y, pcmd->ClipRect.z - pcmd->ClipRect.x, pcmd->ClipRect.w - pcmd->ClipRect.y);
al_draw_prim(&vertices[0], g_VertexDecl, texture, idx_offset, idx_offset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST); al_draw_prim(&vertices[0], g_VertexDecl, texture, idx_offset, idx_offset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST);
} }

View File

@ -80,7 +80,7 @@ int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event)
if((AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_FINGER) if((AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_FINGER)
|| (AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_UNKNOWN)) || (AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_UNKNOWN))
{ {
io.MouseDown[0] = (event_action == AMOTION_EVENT_ACTION_DOWN); io.MouseDown[0] = (event_action == AMOTION_EVENT_ACTION_DOWN) ? true : false;
io.MousePos = ImVec2(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index)); io.MousePos = ImVec2(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index));
} }
break; break;
@ -88,9 +88,9 @@ int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event)
case AMOTION_EVENT_ACTION_BUTTON_RELEASE: case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
{ {
int32_t button_state = AMotionEvent_getButtonState(input_event); int32_t button_state = AMotionEvent_getButtonState(input_event);
io.MouseDown[0] = ((button_state & AMOTION_EVENT_BUTTON_PRIMARY) != 0); io.MouseDown[0] = (button_state & AMOTION_EVENT_BUTTON_PRIMARY) ? true : false;
io.MouseDown[1] = ((button_state & AMOTION_EVENT_BUTTON_SECONDARY) != 0); io.MouseDown[1] = (button_state & AMOTION_EVENT_BUTTON_SECONDARY) ? true : false;
io.MouseDown[2] = ((button_state & AMOTION_EVENT_BUTTON_TERTIARY) != 0); io.MouseDown[2] = (button_state & AMOTION_EVENT_BUTTON_TERTIARY) ? true : false;
} }
break; break;
case AMOTION_EVENT_ACTION_HOVER_MOVE: // Hovering: Tool moves while NOT pressed (such as a physical mouse) case AMOTION_EVENT_ACTION_HOVER_MOVE: // Hovering: Tool moves while NOT pressed (such as a physical mouse)

View File

@ -11,7 +11,6 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2021-05-19: DirectX10: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-02-18: DirectX10: Change blending equation to preserve alpha in output buffer. // 2021-02-18: DirectX10: Change blending equation to preserve alpha in output buffer.
// 2019-07-21: DirectX10: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData(). // 2019-07-21: DirectX10: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData().
// 2019-05-29: DirectX10: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. // 2019-05-29: DirectX10: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
@ -191,7 +190,7 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
DXGI_FORMAT IndexBufferFormat; DXGI_FORMAT IndexBufferFormat;
ID3D10InputLayout* InputLayout; ID3D10InputLayout* InputLayout;
}; };
BACKUP_DX10_STATE old = {}; BACKUP_DX10_STATE old;
old.ScissorRectsCount = old.ViewportsCount = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; old.ScissorRectsCount = old.ViewportsCount = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects); ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports); ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
@ -239,7 +238,7 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
ctx->RSSetScissorRects(1, &r); ctx->RSSetScissorRects(1, &r);
// Bind texture, Draw // Bind texture, Draw
ID3D10ShaderResourceView* texture_srv = (ID3D10ShaderResourceView*)pcmd->GetTexID(); ID3D10ShaderResourceView* texture_srv = (ID3D10ShaderResourceView*)pcmd->TextureId;
ctx->PSSetShaderResources(0, 1, &texture_srv); ctx->PSSetShaderResources(0, 1, &texture_srv);
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset); ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
} }
@ -294,7 +293,6 @@ static void ImGui_ImplDX10_CreateFontsTexture()
subResource.SysMemPitch = desc.Width * 4; subResource.SysMemPitch = desc.Width * 4;
subResource.SysMemSlicePitch = 0; subResource.SysMemSlicePitch = 0;
g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture); g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
IM_ASSERT(pTexture != NULL);
// Create texture view // Create texture view
D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc; D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc;

View File

@ -11,7 +11,6 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer. // 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
// 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled). // 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled).
// 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. // 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.
@ -199,7 +198,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
DXGI_FORMAT IndexBufferFormat; DXGI_FORMAT IndexBufferFormat;
ID3D11InputLayout* InputLayout; ID3D11InputLayout* InputLayout;
}; };
BACKUP_DX11_STATE old = {}; BACKUP_DX11_STATE old;
old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects); ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports); ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
@ -249,7 +248,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
ctx->RSSetScissorRects(1, &r); ctx->RSSetScissorRects(1, &r);
// Bind texture, Draw // Bind texture, Draw
ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID(); ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->TextureId;
ctx->PSSetShaderResources(0, 1, &texture_srv); ctx->PSSetShaderResources(0, 1, &texture_srv);
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset); ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
} }
@ -306,7 +305,6 @@ static void ImGui_ImplDX11_CreateFontsTexture()
subResource.SysMemPitch = desc.Width * 4; subResource.SysMemPitch = desc.Width * 4;
subResource.SysMemSlicePitch = 0; subResource.SysMemSlicePitch = 0;
g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture); g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
IM_ASSERT(pTexture != NULL);
// Create texture view // Create texture view
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;

View File

@ -15,7 +15,6 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2021-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-02-18: DirectX12: Change blending equation to preserve alpha in output buffer. // 2021-02-18: DirectX12: Change blending equation to preserve alpha in output buffer.
// 2021-01-11: DirectX12: Improve Windows 7 compatibility (for D3D12On7) by loading d3d12.dll dynamically. // 2021-01-11: DirectX12: Improve Windows 7 compatibility (for D3D12On7) by loading d3d12.dll dynamically.
// 2020-09-16: DirectX12: Avoid rendering calls with zero-sized scissor rectangle since it generates a validation layer warning. // 2020-09-16: DirectX12: Avoid rendering calls with zero-sized scissor rectangle since it generates a validation layer warning.
@ -240,9 +239,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
const D3D12_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) }; const D3D12_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) };
if (r.right > r.left && r.bottom > r.top) if (r.right > r.left && r.bottom > r.top)
{ {
D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {}; ctx->SetGraphicsRootDescriptorTable(1, *(D3D12_GPU_DESCRIPTOR_HANDLE*)&pcmd->TextureId);
texture_handle.ptr = (UINT64)(intptr_t)pcmd->GetTexID();
ctx->SetGraphicsRootDescriptorTable(1, texture_handle);
ctx->RSSetScissorRects(1, &r); ctx->RSSetScissorRects(1, &r);
ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
} }

View File

@ -11,9 +11,6 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2021-05-19: DirectX9: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-04-23: DirectX9: Explicitly setting up more graphics states to increase compatibility with unusual non-default states.
// 2021-03-18: DirectX9: Calling IDirect3DStateBlock9::Capture() after CreateStateBlock() as a workaround for state restoring issues (see #3857).
// 2021-03-03: DirectX9: Added support for IMGUI_USE_BGRA_PACKED_COLOR in user's imconfig file. // 2021-03-03: DirectX9: Added support for IMGUI_USE_BGRA_PACKED_COLOR in user's imconfig file.
// 2021-02-18: DirectX9: Change blending equation to preserve alpha in output buffer. // 2021-02-18: DirectX9: Change blending equation to preserve alpha in output buffer.
// 2019-05-29: DirectX9: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. // 2019-05-29: DirectX9: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
@ -68,13 +65,11 @@ static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient) // Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient)
g_pd3dDevice->SetPixelShader(NULL); g_pd3dDevice->SetPixelShader(NULL);
g_pd3dDevice->SetVertexShader(NULL); g_pd3dDevice->SetVertexShader(NULL);
g_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
g_pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
@ -82,12 +77,8 @@ static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
g_pd3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE); g_pd3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA); g_pd3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
g_pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); g_pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
g_pd3dDevice->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
g_pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
g_pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
g_pd3dDevice->SetRenderState(D3DRS_CLIPPING, TRUE);
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
@ -146,11 +137,6 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
IDirect3DStateBlock9* d3d9_state_block = NULL; IDirect3DStateBlock9* d3d9_state_block = NULL;
if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0) if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
return; return;
if (d3d9_state_block->Capture() < 0)
{
d3d9_state_block->Release();
return;
}
// Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to) // Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to)
D3DMATRIX last_world, last_view, last_projection; D3DMATRIX last_world, last_view, last_projection;
@ -158,25 +144,16 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
g_pd3dDevice->GetTransform(D3DTS_VIEW, &last_view); g_pd3dDevice->GetTransform(D3DTS_VIEW, &last_view);
g_pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection); g_pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection);
// Allocate buffers
CUSTOMVERTEX* vtx_dst;
ImDrawIdx* idx_dst;
if (g_pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0)
{
d3d9_state_block->Release();
return;
}
if (g_pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0)
{
g_pVB->Unlock();
d3d9_state_block->Release();
return;
}
// Copy and convert all vertices into a single contiguous buffer, convert colors to DX9 default format. // Copy and convert all vertices into a single contiguous buffer, convert colors to DX9 default format.
// FIXME-OPT: This is a minor waste of resource, the ideal is to use imconfig.h and // FIXME-OPT: This is a minor waste of resource, the ideal is to use imconfig.h and
// 1) to avoid repacking colors: #define IMGUI_USE_BGRA_PACKED_COLOR // 1) to avoid repacking colors: #define IMGUI_USE_BGRA_PACKED_COLOR
// 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; } // 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; }
CUSTOMVERTEX* vtx_dst;
ImDrawIdx* idx_dst;
if (g_pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0)
return;
if (g_pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0)
return;
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* cmd_list = draw_data->CmdLists[n];
@ -227,7 +204,7 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
else else
{ {
const 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) }; const 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) };
const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID(); const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->TextureId;
g_pd3dDevice->SetTexture(0, texture); g_pd3dDevice->SetTexture(0, texture);
g_pd3dDevice->SetScissorRect(&r); g_pd3dDevice->SetScissorRect(&r);
g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3); g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3);

View File

@ -113,13 +113,10 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int a
g_PrevUserCallbackKey(window, key, scancode, action, mods); g_PrevUserCallbackKey(window, key, scancode, action, mods);
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
if (key >= 0 && key < IM_ARRAYSIZE(io.KeysDown)) if (action == GLFW_PRESS)
{ io.KeysDown[key] = true;
if (action == GLFW_PRESS) if (action == GLFW_RELEASE)
io.KeysDown[key] = true; io.KeysDown[key] = false;
if (action == GLFW_RELEASE)
io.KeysDown[key] = false;
}
// Modifiers are not reliable across systems // Modifiers are not reliable across systems
io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL];

View File

@ -12,7 +12,6 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2021-05-19: Renderer: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter. // 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
// 2019-05-11: Inputs: Don't filter value from character callback before calling AddInputCharacter(). // 2019-05-11: Inputs: Don't filter value from character callback before calling AddInputCharacter().
// 2018-11-30: Misc: Setting up io.BackendPlatformName/io.BackendRendererName so they can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendPlatformName/io.BackendRendererName so they can be displayed in the About Window.
@ -88,7 +87,7 @@ void ImGui_Marmalade_RenderDrawData(ImDrawData* draw_data)
pCurrentMaterial->SetAlphaMode(CIwMaterial::ALPHA_BLEND); pCurrentMaterial->SetAlphaMode(CIwMaterial::ALPHA_BLEND);
pCurrentMaterial->SetDepthWriteMode(CIwMaterial::DEPTH_WRITE_NORMAL); pCurrentMaterial->SetDepthWriteMode(CIwMaterial::DEPTH_WRITE_NORMAL);
pCurrentMaterial->SetAlphaTestMode(CIwMaterial::ALPHATEST_DISABLED); pCurrentMaterial->SetAlphaTestMode(CIwMaterial::ALPHATEST_DISABLED);
pCurrentMaterial->SetTexture((CIwTexture*)pcmd->GetTexID()); pCurrentMaterial->SetTexture((CIwTexture*)pcmd->TextureId);
IwGxSetMaterial(pCurrentMaterial); IwGxSetMaterial(pCurrentMaterial);
IwGxDrawPrims(IW_GX_TRI_LIST, (uint16*)idx_buffer, pcmd->ElemCount); IwGxDrawPrims(IW_GX_TRI_LIST, (uint16*)idx_buffer, pcmd->ElemCount);
} }

View File

@ -11,7 +11,6 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2021-05-19: Metal: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-02-18: Metal: Change blending equation to preserve alpha in output buffer. // 2021-02-18: Metal: Change blending equation to preserve alpha in output buffer.
// 2021-01-25: Metal: Fixed texture storage mode when building on Mac Catalyst. // 2021-01-25: Metal: Fixed texture storage mode when building on Mac Catalyst.
// 2019-05-29: Metal: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. // 2019-05-29: Metal: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
@ -523,8 +522,8 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
// Bind texture, Draw // Bind texture, Draw
if (ImTextureID tex_id = pcmd->GetTexID()) if (pcmd->TextureId != NULL)
[commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(tex_id) atIndex:0]; [commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(pcmd->TextureId) atIndex:0];
[commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0]; [commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0];
[commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle [commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle

View File

@ -18,7 +18,6 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-01-03: OpenGL: Backup, setup and restore GL_SHADE_MODEL state, disable GL_STENCIL_TEST and disable GL_NORMAL_ARRAY client state to increase compatibility with legacy OpenGL applications. // 2021-01-03: OpenGL: Backup, setup and restore GL_SHADE_MODEL state, disable GL_STENCIL_TEST and disable GL_NORMAL_ARRAY client state to increase compatibility with legacy OpenGL applications.
// 2020-01-23: OpenGL: Backup, setup and restore GL_TEXTURE_ENV to increase compatibility with legacy OpenGL applications. // 2020-01-23: OpenGL: Backup, setup and restore GL_TEXTURE_ENV to increase compatibility with legacy OpenGL applications.
// 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. // 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
@ -185,7 +184,7 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
// Bind texture, Draw // Bind texture, Draw
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()); glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer);
} }
} }

View File

@ -13,8 +13,6 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-04-06: OpenGL: Don't try to read GL_CLIP_ORIGIN unless we're OpenGL 4.5 or greater.
// 2021-02-18: OpenGL: Change blending equation to preserve alpha in output buffer. // 2021-02-18: OpenGL: Change blending equation to preserve alpha in output buffer.
// 2021-01-03: OpenGL: Backup, setup and restore GL_STENCIL_TEST state. // 2021-01-03: OpenGL: Backup, setup and restore GL_STENCIL_TEST state.
// 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state. // 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state.
@ -264,14 +262,11 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
#endif #endif
// Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
#if defined(GL_CLIP_ORIGIN) #if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
bool clip_origin_lower_left = true; bool clip_origin_lower_left = true;
if (g_GlVersion >= 450) GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&current_clip_origin);
{ if (current_clip_origin == GL_UPPER_LEFT)
GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&current_clip_origin); clip_origin_lower_left = false;
if (current_clip_origin == GL_UPPER_LEFT)
clip_origin_lower_left = false;
}
#endif #endif
// Setup viewport, orthographic projection matrix // Setup viewport, orthographic projection matrix
@ -281,7 +276,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y; float T = draw_data->DisplayPos.y;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
#if defined(GL_CLIP_ORIGIN) #if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left
#endif #endif
const float ortho_projection[4][4] = const float ortho_projection[4][4] =
@ -408,7 +403,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
// Bind texture, Draw // Bind texture, Draw
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()); glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
if (g_GlVersion >= 320) if (g_GlVersion >= 320)
glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset); glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset);

View File

@ -18,7 +18,6 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2021-04-19: Inputs: Added a fix for keys remaining stuck in pressed state when CMD-tabbing into different application.
// 2021-01-27: Inputs: Added a fix for mouse position not being reported when mouse buttons other than left one are down. // 2021-01-27: Inputs: Added a fix for mouse position not being reported when mouse buttons other than left one are down.
// 2020-10-28: Inputs: Added a fix for handling keypad-enter key. // 2020-10-28: Inputs: Added a fix for handling keypad-enter key.
// 2020-05-25: Inputs: Added a fix for missing trackpad clicks when done with "soft tap". // 2020-05-25: Inputs: Added a fix for missing trackpad clicks when done with "soft tap".
@ -31,15 +30,12 @@
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
// 2018-07-07: Initial version. // 2018-07-07: Initial version.
@class ImFocusObserver;
// Data // Data
static CFAbsoluteTime g_Time = 0.0; static CFAbsoluteTime g_Time = 0.0;
static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {};
static bool g_MouseCursorHidden = false; static bool g_MouseCursorHidden = false;
static bool g_MouseJustPressed[ImGuiMouseButton_COUNT] = {}; static bool g_MouseJustPressed[ImGuiMouseButton_COUNT] = {};
static bool g_MouseDown[ImGuiMouseButton_COUNT] = {}; static bool g_MouseDown[ImGuiMouseButton_COUNT] = {};
static ImFocusObserver* g_FocusObserver = NULL;
// Undocumented methods for creating cursors. // Undocumented methods for creating cursors.
@interface NSCursor() @interface NSCursor()
@ -49,31 +45,6 @@ static ImFocusObserver* g_FocusObserver = NULL;
+ (id)_windowResizeEastWestCursor; + (id)_windowResizeEastWestCursor;
@end @end
static void resetKeys()
{
ImGuiIO& io = ImGui::GetIO();
memset(io.KeysDown, 0, sizeof(io.KeysDown));
io.KeyCtrl = io.KeyShift = io.KeyAlt = io.KeySuper = false;
}
@interface ImFocusObserver : NSObject
- (void)onApplicationBecomeInactive:(NSNotification*)aNotification;
@end
@implementation ImFocusObserver
- (void)onApplicationBecomeInactive:(NSNotification*)aNotification
{
// Unfocused applications do not receive input events, therefore we must manually
// release any pressed keys when application loses focus, otherwise they would remain
// stuck in a pressed state. https://github.com/ocornut/imgui/issues/3832
resetKeys();
}
@end
// Functions // Functions
bool ImGui_ImplOSX_Init() bool ImGui_ImplOSX_Init()
{ {
@ -152,18 +123,11 @@ bool ImGui_ImplOSX_Init()
return s_clipboard.Data; return s_clipboard.Data;
}; };
g_FocusObserver = [[ImFocusObserver alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:g_FocusObserver
selector:@selector(onApplicationBecomeInactive:)
name:NSApplicationDidResignActiveNotification
object:nil];
return true; return true;
} }
void ImGui_ImplOSX_Shutdown() void ImGui_ImplOSX_Shutdown()
{ {
g_FocusObserver = NULL;
} }
static void ImGui_ImplOSX_UpdateMouseCursorAndButtons() static void ImGui_ImplOSX_UpdateMouseCursorAndButtons()
@ -236,6 +200,13 @@ static int mapCharacterToKey(int c)
return -1; return -1;
} }
static void resetKeys()
{
ImGuiIO& io = ImGui::GetIO();
for (int n = 0; n < IM_ARRAYSIZE(io.KeysDown); n++)
io.KeysDown[n] = false;
}
bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();

View File

@ -17,7 +17,6 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2021-03-22: Rework global mouse pos availability check listing supported platforms explicitly, effectively fixing mouse access on Raspberry Pi. (#2837, #3950)
// 2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends. // 2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends.
// 2020-02-20: Inputs: Fixed mapping for ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2). // 2020-02-20: Inputs: Fixed mapping for ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2).
// 2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state). // 2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state).
@ -178,14 +177,8 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window)
g_MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); g_MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
g_MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO); g_MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
// Check and store if we are on a SDL backend that supports global mouse position // Check and store if we are on Wayland
// ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list) g_MouseCanUseGlobalState = strncmp(SDL_GetCurrentVideoDriver(), "wayland", 7) != 0;
const char* sdl_backend = SDL_GetCurrentVideoDriver();
const char* global_mouse_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" };
g_MouseCanUseGlobalState = false;
for (int n = 0; n < IM_ARRAYSIZE(global_mouse_whitelist); n++)
if (strncmp(sdl_backend, global_mouse_whitelist[n], strlen(global_mouse_whitelist[n])) == 0)
g_MouseCanUseGlobalState = true;
#ifdef _WIN32 #ifdef _WIN32
SDL_SysWMinfo wmInfo; SDL_SysWMinfo wmInfo;
@ -266,7 +259,7 @@ static void ImGui_ImplSDL2_UpdateMousePosAndButtons()
{ {
// SDL_GetMouseState() gives mouse position seemingly based on the last window entered/focused(?) // SDL_GetMouseState() gives mouse position seemingly based on the last window entered/focused(?)
// The creation of a new windows at runtime and SDL_CaptureMouse both seems to severely mess up with that, so we retrieve that position globally. // The creation of a new windows at runtime and SDL_CaptureMouse both seems to severely mess up with that, so we retrieve that position globally.
// Won't use this workaround on SDL backends that have no global mouse position, like Wayland or RPI // Won't use this workaround when on Wayland, as there is no global mouse position.
int wx, wy; int wx, wy;
SDL_GetWindowPosition(focused_window, &wx, &wy); SDL_GetWindowPosition(focused_window, &wx, &wy);
SDL_GetGlobalMouseState(&mx, &my); SDL_GetGlobalMouseState(&mx, &my);

View File

@ -22,7 +22,6 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2021-03-22: Vulkan: Fix mapped memory validation error when buffer sizes are not multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize.
// 2021-02-18: Vulkan: Change blending equation to preserve alpha in output buffer. // 2021-02-18: Vulkan: Change blending equation to preserve alpha in output buffer.
// 2021-01-27: Vulkan: Added support for custom function load and IMGUI_IMPL_VULKAN_NO_PROTOTYPES by using ImGui_ImplVulkan_LoadFunctions(). // 2021-01-27: Vulkan: Added support for custom function load and IMGUI_IMPL_VULKAN_NO_PROTOTYPES by using ImGui_ImplVulkan_LoadFunctions().
// 2020-11-11: Vulkan: Added support for specifying which subpass to reference during VkPipeline creation. // 2020-11-11: Vulkan: Added support for specifying which subpass to reference during VkPipeline creation.
@ -344,7 +343,7 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory
err = vkBindBufferMemory(v->Device, buffer, buffer_memory, 0); err = vkBindBufferMemory(v->Device, buffer, buffer_memory, 0);
check_vk_result(err); check_vk_result(err);
p_buffer_size = req.size; p_buffer_size = new_size;
} }
static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline pipeline, VkCommandBuffer command_buffer, ImGui_ImplVulkanH_FrameRenderBuffers* rb, int fb_width, int fb_height) static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline pipeline, VkCommandBuffer command_buffer, ImGui_ImplVulkanH_FrameRenderBuffers* rb, int fb_width, int fb_height)
@ -430,9 +429,9 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
// Upload vertex/index data into a single contiguous GPU buffer // Upload vertex/index data into a single contiguous GPU buffer
ImDrawVert* vtx_dst = NULL; ImDrawVert* vtx_dst = NULL;
ImDrawIdx* idx_dst = NULL; ImDrawIdx* idx_dst = NULL;
VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, rb->VertexBufferSize, 0, (void**)(&vtx_dst)); VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, vertex_size, 0, (void**)(&vtx_dst));
check_vk_result(err); check_vk_result(err);
err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, rb->IndexBufferSize, 0, (void**)(&idx_dst)); err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, index_size, 0, (void**)(&idx_dst));
check_vk_result(err); check_vk_result(err);
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {

View File

@ -12,9 +12,6 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2021-05-24: Add support for draw_data->FramebufferScale.
// 2021-05-19: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-05-16: Update to latest WebGPU specs (compatible with Emscripten 2.0.20 and Chrome Canary 92).
// 2021-02-18: Change blending equation to preserve alpha in output buffer. // 2021-02-18: Change blending equation to preserve alpha in output buffer.
// 2021-01-28: Initial version. // 2021-01-28: Initial version.
@ -25,16 +22,11 @@
#define HAS_EMSCRIPTEN_VERSION(major, minor, tiny) (__EMSCRIPTEN_major__ > (major) || (__EMSCRIPTEN_major__ == (major) && __EMSCRIPTEN_minor__ > (minor)) || (__EMSCRIPTEN_major__ == (major) && __EMSCRIPTEN_minor__ == (minor) && __EMSCRIPTEN_tiny__ >= (tiny))) #define HAS_EMSCRIPTEN_VERSION(major, minor, tiny) (__EMSCRIPTEN_major__ > (major) || (__EMSCRIPTEN_major__ == (major) && __EMSCRIPTEN_minor__ > (minor)) || (__EMSCRIPTEN_major__ == (major) && __EMSCRIPTEN_minor__ == (minor) && __EMSCRIPTEN_tiny__ >= (tiny)))
#if defined(__EMSCRIPTEN__) && !HAS_EMSCRIPTEN_VERSION(2, 0, 20)
#error "Requires at least emscripten 2.0.20"
#endif
// Dear ImGui prototypes from imgui_internal.h // Dear ImGui prototypes from imgui_internal.h
extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed = 0); extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed = 0);
// WebGPU data // WebGPU data
static WGPUDevice g_wgpuDevice = NULL; static WGPUDevice g_wgpuDevice = NULL;
static WGPUQueue g_defaultQueue = NULL;
static WGPUTextureFormat g_renderTargetFormat = WGPUTextureFormat_Undefined; static WGPUTextureFormat g_renderTargetFormat = WGPUTextureFormat_Undefined;
static WGPURenderPipeline g_pipelineState = NULL; static WGPURenderPipeline g_pipelineState = NULL;
@ -45,9 +37,9 @@ struct RenderResources
WGPUSampler Sampler; // Sampler for the font texture WGPUSampler Sampler; // Sampler for the font texture
WGPUBuffer Uniforms; // Shader uniforms WGPUBuffer Uniforms; // Shader uniforms
WGPUBindGroup CommonBindGroup; // Resources bind-group to bind the common resources to pipeline WGPUBindGroup CommonBindGroup; // Resources bind-group to bind the common resources to pipeline
WGPUBindGroupLayout ImageBindGroupLayout; // Bind group layout for image textures
ImGuiStorage ImageBindGroups; // Resources bind-group to bind the font/image resources to pipeline (this is a key->value map) ImGuiStorage ImageBindGroups; // Resources bind-group to bind the font/image resources to pipeline (this is a key->value map)
WGPUBindGroup ImageBindGroup; // Default font-resource of Dear ImGui WGPUBindGroup ImageBindGroup; // Default font-resource of Dear ImGui
WGPUBindGroupLayout ImageBindGroupLayout; // Cache layout used for the image bind group. Avoids allocating unnecessary JS objects when working with WebASM
}; };
static RenderResources g_resources; static RenderResources g_resources;
@ -249,8 +241,8 @@ static void SafeRelease(RenderResources& res)
SafeRelease(res.Sampler); SafeRelease(res.Sampler);
SafeRelease(res.Uniforms); SafeRelease(res.Uniforms);
SafeRelease(res.CommonBindGroup); SafeRelease(res.CommonBindGroup);
SafeRelease(res.ImageBindGroup);
SafeRelease(res.ImageBindGroupLayout); SafeRelease(res.ImageBindGroupLayout);
SafeRelease(res.ImageBindGroup);
}; };
static void SafeRelease(FrameResources& res) static void SafeRelease(FrameResources& res)
@ -304,21 +296,23 @@ static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPas
{ 0.0f, 0.0f, 0.5f, 0.0f }, { 0.0f, 0.0f, 0.5f, 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
}; };
wgpuQueueWriteBuffer(g_defaultQueue, g_resources.Uniforms, 0, mvp, sizeof(mvp)); wgpuQueueWriteBuffer(wgpuDeviceGetDefaultQueue(g_wgpuDevice), g_resources.Uniforms, 0, mvp, sizeof(mvp));
} }
// Setup viewport // Setup viewport
wgpuRenderPassEncoderSetViewport(ctx, 0, 0, draw_data->FramebufferScale.x * draw_data->DisplaySize.x, draw_data->FramebufferScale.y * draw_data->DisplaySize.y, 0, 1); wgpuRenderPassEncoderSetViewport(ctx, 0, 0, draw_data->DisplaySize.x, draw_data->DisplaySize.y, 0, 1);
// Bind shader and vertex buffers // Bind shader and vertex buffers
wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, 0); unsigned int stride = sizeof(ImDrawVert);
wgpuRenderPassEncoderSetIndexBuffer(ctx, fr->IndexBuffer, sizeof(ImDrawIdx) == 2 ? WGPUIndexFormat_Uint16 : WGPUIndexFormat_Uint32, 0, 0); unsigned int offset = 0;
wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, offset, fr->VertexBufferSize * stride);
wgpuRenderPassEncoderSetIndexBuffer(ctx, fr->IndexBuffer, sizeof(ImDrawIdx) == 2 ? WGPUIndexFormat_Uint16 : WGPUIndexFormat_Uint32, 0, fr->IndexBufferSize * sizeof(ImDrawIdx));
wgpuRenderPassEncoderSetPipeline(ctx, g_pipelineState); wgpuRenderPassEncoderSetPipeline(ctx, g_pipelineState);
wgpuRenderPassEncoderSetBindGroup(ctx, 0, g_resources.CommonBindGroup, 0, NULL); wgpuRenderPassEncoderSetBindGroup(ctx, 0, g_resources.CommonBindGroup, 0, NULL);
// Setup blend factor // Setup blend factor
WGPUColor blend_color = { 0.f, 0.f, 0.f, 0.f }; WGPUColor blend_color = { 0.f, 0.f, 0.f, 0.f };
wgpuRenderPassEncoderSetBlendConstant(ctx, &blend_color); wgpuRenderPassEncoderSetBlendColor(ctx, &blend_color);
} }
// Render function // Render function
@ -337,11 +331,7 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
// Create and grow vertex/index buffers if needed // Create and grow vertex/index buffers if needed
if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount) if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount)
{ {
if (fr->VertexBuffer) SafeRelease(fr->VertexBuffer);
{
wgpuBufferDestroy(fr->VertexBuffer);
wgpuBufferRelease(fr->VertexBuffer);
}
SafeRelease(fr->VertexBufferHost); SafeRelease(fr->VertexBufferHost);
fr->VertexBufferSize = draw_data->TotalVtxCount + 5000; fr->VertexBufferSize = draw_data->TotalVtxCount + 5000;
@ -361,11 +351,7 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
} }
if (fr->IndexBuffer == NULL || fr->IndexBufferSize < draw_data->TotalIdxCount) if (fr->IndexBuffer == NULL || fr->IndexBufferSize < draw_data->TotalIdxCount)
{ {
if (fr->IndexBuffer) SafeRelease(fr->IndexBuffer);
{
wgpuBufferDestroy(fr->IndexBuffer);
wgpuBufferRelease(fr->IndexBuffer);
}
SafeRelease(fr->IndexBufferHost); SafeRelease(fr->IndexBufferHost);
fr->IndexBufferSize = draw_data->TotalIdxCount + 10000; fr->IndexBufferSize = draw_data->TotalIdxCount + 10000;
@ -397,8 +383,8 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
} }
int64_t vb_write_size = ((char*)vtx_dst - (char*)fr->VertexBufferHost + 3) & ~3; int64_t vb_write_size = ((char*)vtx_dst - (char*)fr->VertexBufferHost + 3) & ~3;
int64_t ib_write_size = ((char*)idx_dst - (char*)fr->IndexBufferHost + 3) & ~3; int64_t ib_write_size = ((char*)idx_dst - (char*)fr->IndexBufferHost + 3) & ~3;
wgpuQueueWriteBuffer(g_defaultQueue, fr->VertexBuffer, 0, fr->VertexBufferHost, vb_write_size); wgpuQueueWriteBuffer(wgpuDeviceGetDefaultQueue(g_wgpuDevice), fr->VertexBuffer, 0, fr->VertexBufferHost, vb_write_size);
wgpuQueueWriteBuffer(g_defaultQueue, fr->IndexBuffer, 0, fr->IndexBufferHost, ib_write_size); wgpuQueueWriteBuffer(wgpuDeviceGetDefaultQueue(g_wgpuDevice), fr->IndexBuffer, 0, fr->IndexBufferHost, ib_write_size);
// Setup desired render state // Setup desired render state
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr); ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
@ -407,7 +393,6 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
// (Because we merged all buffers into a single one, we maintain our own offset into them) // (Because we merged all buffers into a single one, we maintain our own offset into them)
int global_vtx_offset = 0; int global_vtx_offset = 0;
int global_idx_offset = 0; int global_idx_offset = 0;
ImVec2 clip_scale = draw_data->FramebufferScale;
ImVec2 clip_off = draw_data->DisplayPos; ImVec2 clip_off = draw_data->DisplayPos;
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
@ -427,26 +412,24 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
else else
{ {
// Bind custom texture // Bind custom texture
ImTextureID tex_id = pcmd->GetTexID(); auto bind_group = g_resources.ImageBindGroups.GetVoidPtr(ImHashData(&pcmd->TextureId, sizeof(ImTextureID)));
ImGuiID tex_id_hash = ImHashData(&tex_id, sizeof(tex_id));
auto bind_group = g_resources.ImageBindGroups.GetVoidPtr(tex_id_hash);
if (bind_group) if (bind_group)
{ {
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, (WGPUBindGroup)bind_group, 0, NULL); wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, (WGPUBindGroup)bind_group, 0, NULL);
} }
else else
{ {
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(g_resources.ImageBindGroupLayout, (WGPUTextureView)tex_id); WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(g_resources.ImageBindGroupLayout, (WGPUTextureView)pcmd->TextureId);
g_resources.ImageBindGroups.SetVoidPtr(tex_id_hash, image_bind_group); g_resources.ImageBindGroups.SetVoidPtr(ImHashData(&pcmd->TextureId, sizeof(ImTextureID)), image_bind_group);
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, image_bind_group, 0, NULL); wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, image_bind_group, 0, NULL);
} }
// Apply Scissor, Bind texture, Draw // Apply Scissor, Bind texture, Draw
uint32_t clip_rect[4]; uint32_t clip_rect[4];
clip_rect[0] = (uint32_t)(clip_scale.x * (pcmd->ClipRect.x - clip_off.x)); clip_rect[0] = static_cast<uint32_t>(pcmd->ClipRect.x - clip_off.x);
clip_rect[1] = (uint32_t)(clip_scale.y * (pcmd->ClipRect.y - clip_off.y)); clip_rect[1] = static_cast<uint32_t>(pcmd->ClipRect.y - clip_off.y);
clip_rect[2] = (uint32_t)(clip_scale.x * (pcmd->ClipRect.z - clip_off.x)); clip_rect[2] = static_cast<uint32_t>(pcmd->ClipRect.z - clip_off.x);
clip_rect[3] = (uint32_t)(clip_scale.y * (pcmd->ClipRect.w - clip_off.y)); clip_rect[3] = static_cast<uint32_t>(pcmd->ClipRect.w - clip_off.y);
wgpuRenderPassEncoderSetScissorRect(pass_encoder, clip_rect[0], clip_rect[1], clip_rect[2] - clip_rect[0], clip_rect[3] - clip_rect[1]); wgpuRenderPassEncoderSetScissorRect(pass_encoder, clip_rect[0], clip_rect[1], clip_rect[2] - clip_rect[0], clip_rect[3] - clip_rect[1]);
wgpuRenderPassEncoderDrawIndexed(pass_encoder, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); wgpuRenderPassEncoderDrawIndexed(pass_encoder, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
} }
@ -456,6 +439,18 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
} }
} }
static WGPUBuffer ImGui_ImplWGPU_CreateBufferFromData(const WGPUDevice& device, const void* data, uint64_t size, WGPUBufferUsage usage)
{
WGPUBufferDescriptor descriptor = {};
descriptor.size = size;
descriptor.usage = usage | WGPUBufferUsage_CopyDst;
WGPUBuffer buffer = wgpuDeviceCreateBuffer(device, &descriptor);
WGPUQueue queue = wgpuDeviceGetDefaultQueue(g_wgpuDevice);
wgpuQueueWriteBuffer(queue, buffer, 0, data, size);
return buffer;
}
static void ImGui_ImplWGPU_CreateFontsTexture() static void ImGui_ImplWGPU_CreateFontsTexture()
{ {
// Build texture atlas // Build texture atlas
@ -471,7 +466,7 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
tex_desc.dimension = WGPUTextureDimension_2D; tex_desc.dimension = WGPUTextureDimension_2D;
tex_desc.size.width = width; tex_desc.size.width = width;
tex_desc.size.height = height; tex_desc.size.height = height;
tex_desc.size.depthOrArrayLayers = 1; tex_desc.size.depth = 1;
tex_desc.sampleCount = 1; tex_desc.sampleCount = 1;
tex_desc.format = WGPUTextureFormat_RGBA8Unorm; tex_desc.format = WGPUTextureFormat_RGBA8Unorm;
tex_desc.mipLevelCount = 1; tex_desc.mipLevelCount = 1;
@ -491,17 +486,34 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
// Upload texture data // Upload texture data
{ {
WGPUImageCopyTexture dst_view = {}; WGPUBuffer staging_buffer = ImGui_ImplWGPU_CreateBufferFromData(g_wgpuDevice, pixels, (uint32_t)(width * size_pp * height), WGPUBufferUsage_CopySrc);
dst_view.texture = g_resources.FontTexture;
dst_view.mipLevel = 0; WGPUBufferCopyView bufferCopyView = {};
dst_view.origin = { 0, 0, 0 }; bufferCopyView.buffer = staging_buffer;
dst_view.aspect = WGPUTextureAspect_All; bufferCopyView.layout.offset = 0;
WGPUTextureDataLayout layout = {}; bufferCopyView.layout.bytesPerRow = width * size_pp;
layout.offset = 0; bufferCopyView.layout.rowsPerImage = height;
layout.bytesPerRow = width * size_pp;
layout.rowsPerImage = height; WGPUTextureCopyView textureCopyView = {};
WGPUExtent3D size = { (uint32_t)width, (uint32_t)height, 1 }; textureCopyView.texture = g_resources.FontTexture;
wgpuQueueWriteTexture(g_defaultQueue, &dst_view, pixels, (uint32_t)(width * size_pp * height), &layout, &size); textureCopyView.mipLevel = 0;
textureCopyView.origin = { 0, 0, 0 };
#if !defined(__EMSCRIPTEN__) || HAS_EMSCRIPTEN_VERSION(2, 0, 14)
textureCopyView.aspect = WGPUTextureAspect_All;
#endif
WGPUExtent3D copySize = { (uint32_t)width, (uint32_t)height, 1 };
WGPUCommandEncoderDescriptor enc_desc = {};
WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(g_wgpuDevice, &enc_desc);
wgpuCommandEncoderCopyBufferToTexture(encoder, &bufferCopyView, &textureCopyView, &copySize);
WGPUCommandBufferDescriptor cmd_buf_desc = {};
WGPUCommandBuffer copy = wgpuCommandEncoderFinish(encoder, &cmd_buf_desc);
WGPUQueue queue = wgpuDeviceGetDefaultQueue(g_wgpuDevice);
wgpuQueueSubmit(queue, 1, &copy);
wgpuCommandEncoderRelease(encoder);
wgpuBufferRelease(staging_buffer);
} }
// Create the associated sampler // Create the associated sampler
@ -513,7 +525,9 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
sampler_desc.addressModeU = WGPUAddressMode_Repeat; sampler_desc.addressModeU = WGPUAddressMode_Repeat;
sampler_desc.addressModeV = WGPUAddressMode_Repeat; sampler_desc.addressModeV = WGPUAddressMode_Repeat;
sampler_desc.addressModeW = WGPUAddressMode_Repeat; sampler_desc.addressModeW = WGPUAddressMode_Repeat;
#if !defined(__EMSCRIPTEN__) || HAS_EMSCRIPTEN_VERSION(2, 0, 14)
sampler_desc.maxAnisotropy = 1; sampler_desc.maxAnisotropy = 1;
#endif
g_resources.Sampler = wgpuDeviceCreateSampler(g_wgpuDevice, &sampler_desc); g_resources.Sampler = wgpuDeviceCreateSampler(g_wgpuDevice, &sampler_desc);
} }
@ -543,82 +557,139 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
ImGui_ImplWGPU_InvalidateDeviceObjects(); ImGui_ImplWGPU_InvalidateDeviceObjects();
// Create render pipeline // Create render pipeline
WGPURenderPipelineDescriptor2 graphics_pipeline_desc = {}; WGPURenderPipelineDescriptor graphics_pipeline_desc = {};
graphics_pipeline_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; graphics_pipeline_desc.primitiveTopology = WGPUPrimitiveTopology_TriangleList;
graphics_pipeline_desc.primitive.stripIndexFormat = WGPUIndexFormat_Undefined; graphics_pipeline_desc.sampleCount = 1;
graphics_pipeline_desc.primitive.frontFace = WGPUFrontFace_CW; graphics_pipeline_desc.sampleMask = UINT_MAX;
graphics_pipeline_desc.primitive.cullMode = WGPUCullMode_None;
graphics_pipeline_desc.multisample.count = 1; WGPUBindGroupLayoutEntry common_bg_layout_entries[2] = {};
graphics_pipeline_desc.multisample.mask = UINT_MAX; common_bg_layout_entries[0].binding = 0;
graphics_pipeline_desc.multisample.alphaToCoverageEnabled = false; common_bg_layout_entries[0].visibility = WGPUShaderStage_Vertex;
graphics_pipeline_desc.layout = nullptr; // Use automatic layout generation #if !defined(__EMSCRIPTEN__) || HAS_EMSCRIPTEN_VERSION(2, 0, 14)
common_bg_layout_entries[0].buffer.type = WGPUBufferBindingType_Uniform;
#else
common_bg_layout_entries[0].type = WGPUBindingType_UniformBuffer;
#endif
common_bg_layout_entries[1].binding = 1;
common_bg_layout_entries[1].visibility = WGPUShaderStage_Fragment;
#if !defined(__EMSCRIPTEN__) || HAS_EMSCRIPTEN_VERSION(2, 0, 14)
common_bg_layout_entries[1].sampler.type = WGPUSamplerBindingType_Filtering;
#else
common_bg_layout_entries[1].type = WGPUBindingType_Sampler;
#endif
WGPUBindGroupLayoutEntry image_bg_layout_entries[1] = {};
image_bg_layout_entries[0].binding = 0;
image_bg_layout_entries[0].visibility = WGPUShaderStage_Fragment;
#if !defined(__EMSCRIPTEN__) || HAS_EMSCRIPTEN_VERSION(2, 0, 14)
image_bg_layout_entries[0].texture.sampleType = WGPUTextureSampleType_Float;
image_bg_layout_entries[0].texture.viewDimension = WGPUTextureViewDimension_2D;
#else
image_bg_layout_entries[0].type = WGPUBindingType_SampledTexture;
#endif
WGPUBindGroupLayoutDescriptor common_bg_layout_desc = {};
common_bg_layout_desc.entryCount = 2;
common_bg_layout_desc.entries = common_bg_layout_entries;
WGPUBindGroupLayoutDescriptor image_bg_layout_desc = {};
image_bg_layout_desc.entryCount = 1;
image_bg_layout_desc.entries = image_bg_layout_entries;
WGPUBindGroupLayout bg_layouts[2];
bg_layouts[0] = wgpuDeviceCreateBindGroupLayout(g_wgpuDevice, &common_bg_layout_desc);
bg_layouts[1] = wgpuDeviceCreateBindGroupLayout(g_wgpuDevice, &image_bg_layout_desc);
WGPUPipelineLayoutDescriptor layout_desc = {};
layout_desc.bindGroupLayoutCount = 2;
layout_desc.bindGroupLayouts = bg_layouts;
graphics_pipeline_desc.layout = wgpuDeviceCreatePipelineLayout(g_wgpuDevice, &layout_desc);
// Create the vertex shader // Create the vertex shader
WGPUProgrammableStageDescriptor vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__glsl_shader_vert_spv, sizeof(__glsl_shader_vert_spv) / sizeof(uint32_t)); WGPUProgrammableStageDescriptor vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__glsl_shader_vert_spv, sizeof(__glsl_shader_vert_spv) / sizeof(uint32_t));
graphics_pipeline_desc.vertex.module = vertex_shader_desc.module; graphics_pipeline_desc.vertexStage = vertex_shader_desc;
graphics_pipeline_desc.vertex.entryPoint = vertex_shader_desc.entryPoint;
// Vertex input configuration // Vertex input configuration
WGPUVertexAttribute attribute_desc[] = WGPUVertexAttributeDescriptor attribute_binding_desc[] =
{ {
{ WGPUVertexFormat_Float32x2, (uint64_t)IM_OFFSETOF(ImDrawVert, pos), 0 }, { WGPUVertexFormat_Float2, (uint64_t)IM_OFFSETOF(ImDrawVert, pos), 0 },
{ WGPUVertexFormat_Float32x2, (uint64_t)IM_OFFSETOF(ImDrawVert, uv), 1 }, { WGPUVertexFormat_Float2, (uint64_t)IM_OFFSETOF(ImDrawVert, uv), 1 },
{ WGPUVertexFormat_Unorm8x4, (uint64_t)IM_OFFSETOF(ImDrawVert, col), 2 }, { WGPUVertexFormat_UChar4Norm, (uint64_t)IM_OFFSETOF(ImDrawVert, col), 2 },
}; };
WGPUVertexBufferLayout buffer_layouts[1]; WGPUVertexBufferLayoutDescriptor buffer_binding_desc;
buffer_layouts[0].arrayStride = sizeof(ImDrawVert); buffer_binding_desc.arrayStride = sizeof(ImDrawVert);
buffer_layouts[0].stepMode = WGPUInputStepMode_Vertex; buffer_binding_desc.stepMode = WGPUInputStepMode_Vertex;
buffer_layouts[0].attributeCount = 3; buffer_binding_desc.attributeCount = 3;
buffer_layouts[0].attributes = attribute_desc; buffer_binding_desc.attributes = attribute_binding_desc;
graphics_pipeline_desc.vertex.bufferCount = 1; WGPUVertexStateDescriptor vertex_state_desc = {};
graphics_pipeline_desc.vertex.buffers = buffer_layouts; vertex_state_desc.indexFormat = WGPUIndexFormat_Undefined;
vertex_state_desc.vertexBufferCount = 1;
vertex_state_desc.vertexBuffers = &buffer_binding_desc;
graphics_pipeline_desc.vertexState = &vertex_state_desc;
// Create the pixel shader // Create the pixel shader
WGPUProgrammableStageDescriptor pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__glsl_shader_frag_spv, sizeof(__glsl_shader_frag_spv) / sizeof(uint32_t)); WGPUProgrammableStageDescriptor pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__glsl_shader_frag_spv, sizeof(__glsl_shader_frag_spv) / sizeof(uint32_t));
graphics_pipeline_desc.fragmentStage = &pixel_shader_desc;
// Create the blending setup // Create the blending setup
WGPUBlendState blend_state = {}; WGPUColorStateDescriptor color_state = {};
blend_state.alpha.operation = WGPUBlendOperation_Add; {
blend_state.alpha.srcFactor = WGPUBlendFactor_One; color_state.format = g_renderTargetFormat;
blend_state.alpha.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha; color_state.alphaBlend.operation = WGPUBlendOperation_Add;
blend_state.color.operation = WGPUBlendOperation_Add; color_state.alphaBlend.srcFactor = WGPUBlendFactor_One;
blend_state.color.srcFactor = WGPUBlendFactor_SrcAlpha; color_state.alphaBlend.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha;
blend_state.color.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha; color_state.colorBlend.operation = WGPUBlendOperation_Add;
color_state.colorBlend.srcFactor = WGPUBlendFactor_SrcAlpha;
color_state.colorBlend.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha;
color_state.writeMask = WGPUColorWriteMask_All;
WGPUColorTargetState color_state = {}; graphics_pipeline_desc.colorStateCount = 1;
color_state.format = g_renderTargetFormat; graphics_pipeline_desc.colorStates = &color_state;
color_state.blend = &blend_state; graphics_pipeline_desc.alphaToCoverageEnabled = false;
color_state.writeMask = WGPUColorWriteMask_All; }
WGPUFragmentState fragment_state = {}; // Create the rasterizer state
fragment_state.module = pixel_shader_desc.module; WGPURasterizationStateDescriptor raster_desc = {};
fragment_state.entryPoint = pixel_shader_desc.entryPoint; {
fragment_state.targetCount = 1; raster_desc.cullMode = WGPUCullMode_None;
fragment_state.targets = &color_state; raster_desc.frontFace = WGPUFrontFace_CW;
raster_desc.depthBias = 0;
graphics_pipeline_desc.fragment = &fragment_state; raster_desc.depthBiasClamp = 0;
raster_desc.depthBiasSlopeScale = 0;
graphics_pipeline_desc.rasterizationState = &raster_desc;
}
// Create depth-stencil State // Create depth-stencil State
WGPUDepthStencilState depth_stencil_state = {}; WGPUDepthStencilStateDescriptor depth_desc = {};
depth_stencil_state.depthBias = 0; {
depth_stencil_state.depthBiasClamp = 0; // Configure disabled state
depth_stencil_state.depthBiasSlopeScale = 0; depth_desc.format = WGPUTextureFormat_Undefined;
depth_desc.depthWriteEnabled = true;
depth_desc.depthCompare = WGPUCompareFunction_Always;
depth_desc.stencilReadMask = 0;
depth_desc.stencilWriteMask = 0;
depth_desc.stencilBack.compare = WGPUCompareFunction_Always;
depth_desc.stencilBack.failOp = WGPUStencilOperation_Keep;
depth_desc.stencilBack.depthFailOp = WGPUStencilOperation_Keep;
depth_desc.stencilBack.passOp = WGPUStencilOperation_Keep;
depth_desc.stencilFront.compare = WGPUCompareFunction_Always;
depth_desc.stencilFront.failOp = WGPUStencilOperation_Keep;
depth_desc.stencilFront.depthFailOp = WGPUStencilOperation_Keep;
depth_desc.stencilFront.passOp = WGPUStencilOperation_Keep;
// Configure disabled depth-stencil state // No depth buffer corresponds to no configuration
graphics_pipeline_desc.depthStencil = nullptr; graphics_pipeline_desc.depthStencilState = NULL;
}
g_pipelineState = wgpuDeviceCreateRenderPipeline2(g_wgpuDevice, &graphics_pipeline_desc); g_pipelineState = wgpuDeviceCreateRenderPipeline(g_wgpuDevice, &graphics_pipeline_desc);
ImGui_ImplWGPU_CreateFontsTexture(); ImGui_ImplWGPU_CreateFontsTexture();
ImGui_ImplWGPU_CreateUniformBuffer(); ImGui_ImplWGPU_CreateUniformBuffer();
// Create resource bind group // Create resource bind group
WGPUBindGroupLayout bg_layouts[2];
bg_layouts[0] = wgpuRenderPipelineGetBindGroupLayout(g_pipelineState, 0);
bg_layouts[1] = wgpuRenderPipelineGetBindGroupLayout(g_pipelineState, 1);
WGPUBindGroupEntry common_bg_entries[] = WGPUBindGroupEntry common_bg_entries[] =
{ {
{ 0, g_resources.Uniforms, 0, sizeof(Uniforms), 0, 0 }, { 0, g_resources.Uniforms, 0, sizeof(Uniforms), 0, 0 },
@ -630,10 +701,10 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
common_bg_descriptor.entryCount = sizeof(common_bg_entries) / sizeof(WGPUBindGroupEntry); common_bg_descriptor.entryCount = sizeof(common_bg_entries) / sizeof(WGPUBindGroupEntry);
common_bg_descriptor.entries = common_bg_entries; common_bg_descriptor.entries = common_bg_entries;
g_resources.CommonBindGroup = wgpuDeviceCreateBindGroup(g_wgpuDevice, &common_bg_descriptor); g_resources.CommonBindGroup = wgpuDeviceCreateBindGroup(g_wgpuDevice, &common_bg_descriptor);
g_resources.ImageBindGroupLayout = bg_layouts[1];
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bg_layouts[1], g_resources.FontTextureView); WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bg_layouts[1], g_resources.FontTextureView);
g_resources.ImageBindGroup = image_bind_group; g_resources.ImageBindGroup = image_bind_group;
g_resources.ImageBindGroupLayout = bg_layouts[1];
g_resources.ImageBindGroups.SetVoidPtr(ImHashData(&g_resources.FontTextureView, sizeof(ImTextureID)), image_bind_group); g_resources.ImageBindGroups.SetVoidPtr(ImHashData(&g_resources.FontTextureView, sizeof(ImTextureID)), image_bind_group);
SafeRelease(vertex_shader_desc.module); SafeRelease(vertex_shader_desc.module);
@ -666,7 +737,6 @@ bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextur
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
g_wgpuDevice = device; g_wgpuDevice = device;
g_defaultQueue = wgpuDeviceGetQueue(g_wgpuDevice);
g_renderTargetFormat = rt_format; g_renderTargetFormat = rt_format;
g_pFrameResources = new FrameResources[num_frames_in_flight]; g_pFrameResources = new FrameResources[num_frames_in_flight];
g_numFramesInFlight = num_frames_in_flight; g_numFramesInFlight = num_frames_in_flight;
@ -677,9 +747,9 @@ bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextur
g_resources.Sampler = NULL; g_resources.Sampler = NULL;
g_resources.Uniforms = NULL; g_resources.Uniforms = NULL;
g_resources.CommonBindGroup = NULL; g_resources.CommonBindGroup = NULL;
g_resources.ImageBindGroupLayout = NULL;
g_resources.ImageBindGroups.Data.reserve(100); g_resources.ImageBindGroups.Data.reserve(100);
g_resources.ImageBindGroup = NULL; g_resources.ImageBindGroup = NULL;
g_resources.ImageBindGroupLayout = NULL;
// Create buffers with a default size (they will later be grown as needed) // Create buffers with a default size (they will later be grown as needed)
for (int i = 0; i < num_frames_in_flight; i++) for (int i = 0; i < num_frames_in_flight; i++)
@ -701,7 +771,6 @@ void ImGui_ImplWGPU_Shutdown()
ImGui_ImplWGPU_InvalidateDeviceObjects(); ImGui_ImplWGPU_InvalidateDeviceObjects();
delete[] g_pFrameResources; delete[] g_pFrameResources;
g_pFrameResources = NULL; g_pFrameResources = NULL;
wgpuQueueRelease(g_defaultQueue);
g_wgpuDevice = NULL; g_wgpuDevice = NULL;
g_numFramesInFlight = 0; g_numFramesInFlight = 0;
g_frameIndex = UINT_MAX; g_frameIndex = UINT_MAX;

View File

@ -25,14 +25,13 @@
// Using XInput for gamepad (will load DLL dynamically) // Using XInput for gamepad (will load DLL dynamically)
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
#include <xinput.h> #include <XInput.h>
typedef DWORD (WINAPI *PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*); typedef DWORD (WINAPI *PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*);
typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*); typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
#endif #endif
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2021-03-23: Inputs: Clearing keyboard down array when losing focus (WM_KILLFOCUS).
// 2021-02-18: Added ImGui_ImplWin32_EnableAlphaCompositing(). Non Visual Studio users will need to link with dwmapi.lib (MinGW/gcc: use -ldwmapi). // 2021-02-18: Added ImGui_ImplWin32_EnableAlphaCompositing(). Non Visual Studio users will need to link with dwmapi.lib (MinGW/gcc: use -ldwmapi).
// 2021-02-17: Fixed ImGui_ImplWin32_EnableDpiAwareness() attempting to get SetProcessDpiAwareness from shcore.dll on Windows 8 whereas it is only supported on Windows 8.1. // 2021-02-17: Fixed ImGui_ImplWin32_EnableDpiAwareness() attempting to get SetProcessDpiAwareness from shcore.dll on Windows 8 whereas it is only supported on Windows 8.1.
// 2021-01-25: Inputs: Dynamically loading XInput DLL. // 2021-01-25: Inputs: Dynamically loading XInput DLL.
@ -135,7 +134,7 @@ bool ImGui_ImplWin32_Init(void* hwnd)
break; break;
} }
#endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD #endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
return true; return true;
} }
@ -149,7 +148,7 @@ void ImGui_ImplWin32_Shutdown()
g_XInputGetCapabilities = NULL; g_XInputGetCapabilities = NULL;
g_XInputGetState = NULL; g_XInputGetState = NULL;
#endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD #endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
g_hWnd = NULL; g_hWnd = NULL;
g_Time = 0; g_Time = 0;
g_TicksPerSecond = 0; g_TicksPerSecond = 0;
@ -194,7 +193,6 @@ static bool ImGui_ImplWin32_UpdateMouseCursor()
static void ImGui_ImplWin32_UpdateMousePos() static void ImGui_ImplWin32_UpdateMousePos()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(g_hWnd != 0);
// Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
if (io.WantSetMousePos) if (io.WantSetMousePos)
@ -374,9 +372,6 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
if (wParam < 256) if (wParam < 256)
io.KeysDown[wParam] = 0; io.KeysDown[wParam] = 0;
return 0; return 0;
case WM_KILLFOCUS:
memset(io.KeysDown, 0, sizeof(io.KeysDown));
return 0;
case WM_CHAR: case WM_CHAR:
// You can also use ToAscii()+GetKeyboardState() to retrieve characters. // You can also use ToAscii()+GetKeyboardState() to retrieve characters.
if (wParam > 0 && wParam < 0x10000) if (wParam > 0 && wParam < 0x10000)

View File

@ -17,8 +17,6 @@ your application or engine to easily integrate Dear ImGui.** Each backend is typ
An application usually combines 1 Platform backend + 1 Renderer backend + main Dear ImGui sources. An application usually combines 1 Platform backend + 1 Renderer backend + main Dear ImGui sources.
For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree/master/examples/example_win32_directx11) application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. There are 20+ examples in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder. See [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for details. For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree/master/examples/example_win32_directx11) application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. There are 20+ examples in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder. See [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for details.
**Once Dear ImGui is setup and running, run and refer to `ImGui::ShowDemoWindow()` in imgui_demo.cpp for usage of the end-user API.**
### What are backends ### What are backends

View File

@ -32,93 +32,9 @@ HOW TO UPDATE?
----------------------------------------------------------------------- -----------------------------------------------------------------------
VERSION 1.83 (Released 2011-05-24) VERSION 1.82 WIP (In Progresss)
----------------------------------------------------------------------- -----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.83
Breaking Changes:
- Backends: Obsoleted direct access to ImDrawCmd::TextureId in favor of calling ImDrawCmd::GetTexID(). (#3761) [@thedmd]
- If you are using official backends from the source tree: you have nothing to do.
- If you copied old backend code or using your own: change access to draw_cmd->TextureId to draw_cmd->GetTexID().
Why are we doing this?
- This change will be required in the future when adding support for incremental texture atlas updates.
- Please note this won't break soon, but we are making the change ahead of time.
Other Changes:
- Scrolling: Fix scroll tracking with e.g. SetScrollHereX/Y() when WindowPadding < ItemSpacing.
- Scrolling: Fix scroll snapping on edge of scroll region when both scrollbars are enabled.
- Scrolling: Fix mouse wheel axis swap when using SHIFT on macOS (system already does it). (#4010)
- Window: Fix IsWindowAppearing() from returning true twice in most cases. (#3982, #1497, #1061)
- Nav: Fixed toggling menu layer while an InputText() is active not stealing active id. (#787)
- Nav: Fixed pressing Escape to leave menu layer while in a popup or child window. (#787)
- Nav, InputText: Fixed accidental menu toggling while typing non-ascii characters using AltGR. [@rokups] (#370)
- Nav: Fixed using SetItemDefaultFocus() on windows with _NavFlattened flag. (#787)
- Nav: Fixed Tabbing initial activation from skipping the first item if it is tabbable through. (#787)
- Nav: Fixed fast CTRL+Tab (where keys are only held for one single frame) from properly enabling the
menu layer of target window if it doesn't have other active layers.
- Tables: Expose TableSetColumnEnabled() in public api. (#3935)
- Tables: Better preserve widths when columns count changes. (#4046)
- Tables: Sharing more memory buffers between tables, reducing general memory footprints. (#3740)
- TabBar: Fixed mouse reordering with very fast movements (e.g. crossing multiple tabs in a single
frame and then immediately standing still (would only affect automation/bots). [@rokups]
- Menus: made MenuItem() in a menu bar reflect the 'selected' argument with a highlight. (#4128) [@mattelegende]
- Drags, Sliders, Inputs: Specifying a NULL format to Float functions default them to "%.3f" to be
consistent with the compile-time default. (#3922)
- DragScalar: Add default value for v_speed argument to match higher-level functions. (#3922) [@eliasdaler]
- ColorEdit4: Alpha default to 255 (instead of 0) when omitted in hex input. (#3973) [@squadack]
- InputText: Do not filter private unicode codepoints (e.g. icons) when pasted from clipboard. (#4005) [@dougbinks]
- InputText: Align caret/cursor to pixel coordinates. (#4080) [@elvissteinjr]
- InputText: Fixed CTRL+Arrow or OSX double-click leaking the presence of spaces when ImGuiInputTextFlags_Password
is used. (#4155, #4156) [@michael-swan]
- LabelText: Fixed clipping of multi-line value text when label is single-line. (#4004)
- LabelText: Fixed vertical alignment of single-line value text when label is multi-line. (#4004)
- Combos: Changed the combo popup to use a different id to also using a context menu with the default item id.
Fixed using BeginPopupContextItem() with no parameter after a combo. (#4167)
- Popups: Added 'OpenPopup(ImGuiID id)' overload to facilitate calling from nested stacks. (#3993, #331) [@zlash]
- Tweak computation of io.Framerate so it is less biased toward high-values in the first 120 frames. (#4138)
- Optimization: Disabling some of MSVC most aggressive Debug runtime checks for some simple/low-level functions
(e.g. ImVec2, ImVector) leading to a 10-20% increase of performances with MSVC "default" Debug settings.
- ImDrawList: Add and use SSE-enabled ImRsqrt() in place of 1.0f / ImSqrt(). (#4091) [@wolfpld]
- ImDrawList: Fixed/improved thickness of thick strokes with sharp angles. (#4053, #3366, #2964, #2868, #2518, #2183)
Effectively introduced a regression in 1.67 (Jan 2019), and a fix in 1.70 (Apr 2019) but the fix wasn't actually on
par with original version. Now incorporating the correct revert.
- ImDrawList: Fixed PathArcTo() regression from 1.82 preventing use of counter-clockwise angles. (#4030, #3491) [@thedmd]
- Demo: Improved popups demo and comments.
- Metrics: Added "Fonts" section with same information as available in "Style Editor">"Fonts".
- Backends: SDL: Rework global mouse pos availability check listing supported platforms explicitly,
effectively fixing mouse access on Raspberry Pi. (#2837, #3950) [@lethal-guitar, @hinxx]
- Backends: Win32: Clearing keyboard down array when losing focus (WM_KILLFOCUS). (#2062, #3532, #3961)
[@1025798851]
- Backends: OSX: Fix keys remaining stuck when CMD-tabbing to a different application. (#3832) [@rokups]
- Backends: DirectX9: calling IDirect3DStateBlock9::Capture() after CreateStateBlock() which appears to
workaround/fix state restoring issues. Unknown exactly why so, bit of a cargo-cult fix. (#3857)
- Backends: DirectX9: explicitly setting up more graphics states to increase compatibility with unusual
non-default states. (#4063)
- Backends: DirectX10, DirectX11: fixed a crash when backing/restoring state if nothing is bound when
entering the rendering function. (#4045) [@Nemirtingas]
- Backends: GLFW: Adding bound check in KeyCallback because GLFW appears to send -1 on some setups. [#4124]
- Backends: Vulkan: Fix mapped memory Vulkan validation error when buffer sizes are not multiple of
VkPhysicalDeviceLimits::nonCoherentAtomSize. (#3957) [@AgentX1994]
- Backends: WebGPU: Update to latest specs (Chrome Canary 92 and Emscripten 2.0.20). (#4116, #3632) [@bfierz, @Kangz]
- Backends: OpenGL3: Don't try to read GL_CLIP_ORIGIN unless we're OpenGL 4.5. (#3998, #2366, #2186) [@s7jones]
- Examples: OpenGL: Add OpenGL ES 2.0 support to modern GL examples. (#2837, #3951) [@lethal-guitar, @hinxx]
- Examples: Vulkan: Rebuild swapchain on VK_SUBOPTIMAL_KHR. (#3881)
- Examples: Vulkan: Prefer using discrete GPU if there are more than one available. (#4012) [@rokups]
- Examples: SDL2: Link with shell32.lib required by SDL2main.lib since SDL 2.0.12. [#3988]
- Examples: Android: Make Android example build compatible with Gradle 7.0. (#3446)
- Docs: Improvements to description of using colored glyphs/emojis. (#4169, #3369)
- Docs: Improvements to minor mistakes in documentation comments (#3923) [@ANF-Studios]
-----------------------------------------------------------------------
VERSION 1.82 (Released 2021-02-15)
-----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.82
Breaking Changes: Breaking Changes:
- Removed redirecting functions/enums names that were marked obsolete in 1.66 (September 2018): - Removed redirecting functions/enums names that were marked obsolete in 1.66 (September 2018):
@ -159,9 +75,9 @@ Breaking Changes:
Other Changes: Other Changes:
- Window, Nav: Fixed crash when calling SetWindowFocus(NULL) at the time a new window appears. (#3865) [@nem0]
- Window: Shrink close button hit-testing region when it covers an abnormally high portion of the window visible - Window: Shrink close button hit-testing region when it covers an abnormally high portion of the window visible
area (e.g. when window is collapsed + moved in a corner) to facilitate moving the window away. (#3825) area (e.g. when window is collapsed + moved in a corner) to facilitate moving the window away. (#3825)
- Window, Nav: Fixed crash when calling SetWindowFocus(NULL) as the time a new window appears. (#3865) [@nem0]
- Nav: Various fixes for losing gamepad/keyboard navigation reference point when a window reappears or - Nav: Various fixes for losing gamepad/keyboard navigation reference point when a window reappears or
when it appears while gamepad/keyboard are not being used. (#787) when it appears while gamepad/keyboard are not being used. (#787)
- Drags: Fixed crash when using DragScalar() directly (not via common wrapper like DragFloat() etc.) - Drags: Fixed crash when using DragScalar() directly (not via common wrapper like DragFloat() etc.)
@ -170,27 +86,26 @@ Other Changes:
format specifier (e.g. using "%f123" as a format string). [@rokups] format specifier (e.g. using "%f123" as a format string). [@rokups]
- Drags, Sliders: Fixed a bug where using custom formatting flags (',$,_) supported by stb_sprintf.h - Drags, Sliders: Fixed a bug where using custom formatting flags (',$,_) supported by stb_sprintf.h
would cause incorrect value to be displayed. (#3604) [@rokups] would cause incorrect value to be displayed. (#3604) [@rokups]
- Drags, Sliders: Support ImGuiSliderFlags_Logarithmic flag with integers. Because why not? (#3786)
- Tables: Fixed unaligned accesses when using TableSetBgColor(ImGuiTableBgTarget_CellBg). (#3872) - Tables: Fixed unaligned accesses when using TableSetBgColor(ImGuiTableBgTarget_CellBg). (#3872)
- IsItemHovered(): fixed return value false positive when used after EndChild(), EndGroup() or widgets using - IsItemHovered(): fixed return value false positive when used after EndChild(), EndGroup() or widgets using
either of them, when the hovered location is located within a child window, e.g. InputTextMultiline(). either of them, when the hovered location is located within a child window, e.g. InputTextMultiline().
This is intended to have no side effects, but brace yourself for the possible comeback.. (#3851, #1370) This is intended to have no side effects, but brace yourself for the possible comeback.. (#3851, #1370)
- Drag and Drop: can use BeginDragDropSource() for other than the left mouse button as long as the item - Drag and Drop: can use BeginDragDropSource() for other than the left mouse button as long as the item
has an ID (for ID-less items will add new functionalities later). (#1637, #3885) has an ID (for ID-less items will add new functionalities later). (#1637, #3885)
- Added GetAllocatorFunctions() to facilitate sharing allocators accross DLL boundaries. (#3836)
- ImFontAtlas: Added 'bool TexPixelsUseColors' output to help backend decide of underlying texture format. (#3369) - ImFontAtlas: Added 'bool TexPixelsUseColors' output to help backend decide of underlying texture format. (#3369)
This can currently only ever be set by the Freetype renderer. This can currently only ever be set by the Freetype renderer.
- imgui_freetype: Added ImGuiFreeTypeBuilderFlags_Bitmap flag to request Freetype loading bitmap data. - imgui_freetype: Added ImGuiFreeTypeBuilderFlags_Bitmap flag to request Freetype loading bitmap data.
This may have an effect on size and must be called with correct size values. (#3879) [@metarutaiga] This may have an effect on size and must be called with correct size values. (#3879) [@metarutaiga]
- ImDrawList: PathArcTo() now supports "int num_segments = 0" (new default) and adaptively tessellate. - ImDrawList: PathArcTo() now supports "int num_segments = 0" (new default) and adaptively tesselate.
The adaptive tessellation uses look up tables, tends to be faster than old PathArcTo() while maintaining The adapative tesselation uses look up tables, tends to be faster than old PathArcTo() while maintaining
quality for large arcs (tessellation quality derived from "style.CircleTessellationMaxError") (#3491) [@thedmd] quality for large arcs (tesselation quality derived from "style.CircleTessellationMaxError") (#3491) [@thedmd]
- ImDrawList: PathArcToFast() also adaptively tessellate efficiently. This means that large rounded corners - ImDrawList: PathArcToFast() also adaptively tesselate efficiently. This means that large rounded corners
in e.g. hi-dpi settings will generally look better. (#3491) [@thedmd] in e.g. hi-dpi settings will generally look better. (#3491) [@thedmd]
- ImDrawList: AddCircle, AddCircleFilled(): Tweaked default segment count calculation to honor MaxError - ImDrawList: AddCircle, AddCircleFilled(): Tweaked default segment count calculation to honor MaxError
with more accuracy. Made default segment count always even for better looking result. (#3808) [@thedmd] with more accuracy. Made default segment count always even for better looking result. (#3808) [@thedmd]
- Misc: Added GetAllocatorFunctions() to facilitate sharing allocators across DLL boundaries. (#3836)
- Misc: Added 'debuggers/imgui.gdb' and 'debuggers/imgui.natstepfilter' (along with existing 'imgui.natvis') - Misc: Added 'debuggers/imgui.gdb' and 'debuggers/imgui.natstepfilter' (along with existing 'imgui.natvis')
scripts to configure popular debuggers into skipping trivial functions when using StepInto. [@rokups] scriptss to configure popular debuggers into skipping trivial functions when using StepInto. [@rokups]
- Backends: Android: Added native Android backend. (#3446) [@duddel] - Backends: Android: Added native Android backend. (#3446) [@duddel]
- Backends: Win32: Added ImGui_ImplWin32_EnableAlphaCompositing() to facilitate experimenting with - Backends: Win32: Added ImGui_ImplWin32_EnableAlphaCompositing() to facilitate experimenting with
alpha compositing and transparent windows. (#2766, #3447 etc.). alpha compositing and transparent windows. (#2766, #3447 etc.).
@ -200,7 +115,7 @@ Other Changes:
(#2693, #2764, #2766, #2873, #3447, #3813, #3816) [@ocornut, @thedmd, @ShawnM427, @Ubpa, @aiekick] (#2693, #2764, #2766, #2873, #3447, #3813, #3816) [@ocornut, @thedmd, @ShawnM427, @Ubpa, @aiekick]
- Backends: DX9: Fix to support IMGUI_USE_BGRA_PACKED_COLOR. (#3844) [@Xiliusha] - Backends: DX9: Fix to support IMGUI_USE_BGRA_PACKED_COLOR. (#3844) [@Xiliusha]
- Backends: DX9: Fix to support colored glyphs, using newly introduced 'TexPixelsUseColors' info. (#3844) - Backends: DX9: Fix to support colored glyphs, using newly introduced 'TexPixelsUseColors' info. (#3844)
- Examples: Android: Added Android + GL ES3 example. (#3446) [@duddel] - Examples: Android: Added Android + GL ES2 example. (#3446) [@duddel]
- Examples: Reworked setup of clear color to be compatible with transparent values. - Examples: Reworked setup of clear color to be compatible with transparent values.
- CI: Use a dedicated "scheduled" workflow to trigger scheduled builds. Forks may disable this workflow if - CI: Use a dedicated "scheduled" workflow to trigger scheduled builds. Forks may disable this workflow if
scheduled builds builds are not required. [@rokups] scheduled builds builds are not required. [@rokups]
@ -211,8 +126,6 @@ Other Changes:
VERSION 1.81 (Released 2021-02-10) VERSION 1.81 (Released 2021-02-10)
----------------------------------------------------------------------- -----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.81
Breaking Changes: Breaking Changes:
- ListBox helpers: - ListBox helpers:
@ -402,7 +315,6 @@ Other Changes:
- Examples: DirectX12: Move ImGui::Render() call above the first barrier to clarify its lack of effect on the graphics pipe. - Examples: DirectX12: Move ImGui::Render() call above the first barrier to clarify its lack of effect on the graphics pipe.
- CI: Fix testing for Windows DLL builds. (#3603, #3601) [@iboB] - CI: Fix testing for Windows DLL builds. (#3603, #3601) [@iboB]
- Docs: Improved the wiki and added a https://github.com/ocornut/imgui/wiki/Useful-Widgets page. [@Xipiryon] - Docs: Improved the wiki and added a https://github.com/ocornut/imgui/wiki/Useful-Widgets page. [@Xipiryon]
[2021/05/20: moved to https://github.com/ocornut/imgui/wiki/Useful-Extensions]
- Docs: Split examples/README.txt into docs/BACKENDS.md and docs/EXAMPLES.md, and improved them. - Docs: Split examples/README.txt into docs/BACKENDS.md and docs/EXAMPLES.md, and improved them.
- Docs: Consistently renamed all occurrences of "binding" and "back-end" to "backend" in comments and docs. - Docs: Consistently renamed all occurrences of "binding" and "back-end" to "backend" in comments and docs.
@ -429,7 +341,7 @@ Breaking Changes:
- Renamed ImGuiSliderFlags_ClampOnInput to ImGuiSliderFlags_AlwaysClamp. Kept redirection enum (will obsolete). - Renamed ImGuiSliderFlags_ClampOnInput to ImGuiSliderFlags_AlwaysClamp. Kept redirection enum (will obsolete).
- Renamed OpenPopupContextItem() back to OpenPopupOnItemClick(), REVERTED CHANGE FROM 1.77. - Renamed OpenPopupContextItem() back to OpenPopupOnItemClick(), REVERTED CHANGE FROM 1.77.
For variety of reason this is more self-explanatory and less error-prone. Kept inline redirection function. For variety of reason this is more self-explanatory and less error-prone. Kept inline redirection function.
- Removed return value from OpenPopupOnItemClick() - returned true on mouse release on an item - because it - Removed return value from OpenPopupOnItemClick() - returned true on mouse release on item - because it
is inconsistent with other popups API and makes others misleading. It's also and unnecessary: you can is inconsistent with other popups API and makes others misleading. It's also and unnecessary: you can
use IsWindowAppearing() after BeginPopup() for a similar result. use IsWindowAppearing() after BeginPopup() for a similar result.
@ -1369,7 +1281,7 @@ Breaking Changes:
- Removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already). - Removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already).
- Made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame). - Made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame).
If for some reason your time step calculation gives you a zero value, replace it with a arbitrarily small value! If for some reason your time step calculation gives you a zero value, replace it with a arbitrary small value!
Other Changes: Other Changes:

View File

@ -3,11 +3,7 @@ _(You may browse this at https://github.com/ocornut/imgui/blob/master/docs/EXAMP
## Dear ImGui: Examples ## Dear ImGui: Examples
**The [examples/](https://github.com/ocornut/imgui/blob/master/examples) folder example applications (standalone, ready-to-build) for variety of **The [examples/](https://github.com/ocornut/imgui/blob/master/examples) folder example applications (standalone, ready-to-build) for variety of
platforms and graphics APIs.** They all use standard backends from the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder (see [BACKENDS.md](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md)). platforms and graphics APIs.** They all use standard backends from the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder.
The purpose of Examples is to showcase integration with backends, let you try Dear ImGui, and guide you toward
integrating Dear ImGui in your own application/game/engine.
**Once Dear ImGui is setup and running, run and refer to `ImGui::ShowDemoWindow()` in imgui_demo.cpp for usage of the end-user API.**
You can find Windows binaries for some of those example applications at: You can find Windows binaries for some of those example applications at:
http://www.dearimgui.org/binaries http://www.dearimgui.org/binaries

View File

@ -16,12 +16,12 @@ or view this file with any Markdown viewer.
| [Which version should I get?](#q-which-version-should-i-get) | | [Which version should I get?](#q-which-version-should-i-get) |
| **Q&A: Integration** | | **Q&A: Integration** |
| **[How to get started?](#q-how-to-get-started)** | | **[How to get started?](#q-how-to-get-started)** |
| **[How can I tell whether to dispatch mouse/keyboard to Dear ImGui or my application?](#q-how-can-i-tell-whether-to-dispatch-mousekeyboard-to-dear-imgui-or-my-application)** | | **[How can I tell whether to dispatch mouse/keyboard to Dear ImGui or to my application?](#q-how-can-i-tell-whether-to-dispatch-mousekeyboard-to-dear-imgui-or-to-my-application)** |
| [How can I enable keyboard or gamepad controls?](#q-how-can-i-enable-keyboard-or-gamepad-controls) | | [How can I enable keyboard or gamepad controls?](#q-how-can-i-enable-keyboard-or-gamepad-controls) |
| [How can I use this on a machine without mouse, keyboard or screen? (input share, remote display)](#q-how-can-i-use-this-on-a-machine-without-mouse-keyboard-or-screen-input-share-remote-display) | | [How can I use this on a machine without mouse, keyboard or screen? (input share, remote display)](#q-how-can-i-use-this-on-a-machine-without-mouse-keyboard-or-screen-input-share-remote-display) |
| [I integrated Dear ImGui in my engine and little squares are showing instead of text...](#q-i-integrated-dear-imgui-in-my-engine-and-little-squares-are-showing-instead-of-text) | | [I integrated Dear ImGui in my engine and little squares are showing instead of text..](#q-i-integrated-dear-imgui-in-my-engine-and-little-squares-are-showing-instead-of-text) |
| [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) | | [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around..](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) |
| [I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-displaying-outside-their-expected-windows-boundaries) | | [I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries..](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-displaying-outside-their-expected-windows-boundaries) |
| **Q&A: Usage** | | **Q&A: Usage** |
| **[Why is my widget not reacting when I click on it?<br>How can I have widgets with an empty label?<br>How can I have multiple widgets with the same label?](#q-why-is-my-widget-not-reacting-when-i-click-on-it)** | | **[Why is my widget not reacting when I click on it?<br>How can I have widgets with an empty label?<br>How can I have multiple widgets with the same label?](#q-why-is-my-widget-not-reacting-when-i-click-on-it)** |
| [How can I display an image? What is ImTextureID, how does it work?](#q-how-can-i-display-an-image-what-is-imtextureid-how-does-it-work)| | [How can I display an image? What is ImTextureID, how does it work?](#q-how-can-i-display-an-image-what-is-imtextureid-how-does-it-work)|
@ -47,7 +47,7 @@ or view this file with any Markdown viewer.
### Q: Where is the documentation? ### Q: Where is the documentation?
**This library is poorly documented at the moment and expects the user to be acquainted with C/C++.** **This library is poorly documented at the moment and expects of the user to be acquainted with C/C++.**
- The [Wiki](https://github.com/ocornut/imgui/wiki) is a hub to many resources and links. - The [Wiki](https://github.com/ocornut/imgui/wiki) is a hub to many resources and links.
- Dozens of standalone example applications using e.g. OpenGL/DirectX are provided in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder to explain how to integrate Dear ImGui with your own engine/application. You can run those applications and explore them. - Dozens of standalone example applications using e.g. OpenGL/DirectX are provided in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder to explain how to integrate Dear ImGui with your own engine/application. You can run those applications and explore them.
- See demo code in [imgui_demo.cpp](https://github.com/ocornut/imgui/blob/master/imgui_demo.cpp) and particularly the `ImGui::ShowDemoWindow()` function. The demo covers most features of Dear ImGui, so you can read the code and see its output. - See demo code in [imgui_demo.cpp](https://github.com/ocornut/imgui/blob/master/imgui_demo.cpp) and particularly the `ImGui::ShowDemoWindow()` function. The demo covers most features of Dear ImGui, so you can read the code and see its output.
@ -55,7 +55,7 @@ or view this file with any Markdown viewer.
- See documentation and comments at the top of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp) + general API comments in [imgui.h](https://github.com/ocornut/imgui/blob/master/imgui.h). - See documentation and comments at the top of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp) + general API comments in [imgui.h](https://github.com/ocornut/imgui/blob/master/imgui.h).
- The [Glossary](https://github.com/ocornut/imgui/wiki/Glossary) page may be useful. - The [Glossary](https://github.com/ocornut/imgui/wiki/Glossary) page may be useful.
- The [Issues](https://github.com/ocornut/imgui/issues) and [Discussions](https://github.com/ocornut/imgui/discussions) sections can be searched for past questions and issues. - The [Issues](https://github.com/ocornut/imgui/issues) and [Discussions](https://github.com/ocornut/imgui/discussions) sections can be searched for past questions and issues.
- Your programming IDE is your friend, find the type or function declaration to find comments associated with it. - Your programming IDE is your friend, find the type or function declaration to find comments associated to it.
- The `ImGui::ShowMetricsWindow()` function exposes lots of internal information and tools. Although it is primary designed as a debugging tool, having access to that information tends to help understands concepts. - The `ImGui::ShowMetricsWindow()` function exposes lots of internal information and tools. Although it is primary designed as a debugging tool, having access to that information tends to help understands concepts.
##### [Return to Index](#index) ##### [Return to Index](#index)
@ -81,6 +81,9 @@ You may use the [docking](https://github.com/ocornut/imgui/tree/docking) branch
Many projects are using this branch and it is kept in sync with master regularly. Many projects are using this branch and it is kept in sync with master regularly.
You may merge in the [tables](https://github.com/ocornut/imgui/tree/tables) branch which includes:
- [Table features](https://github.com/ocornut/imgui/issues/2957)
##### [Return to Index](#index) ##### [Return to Index](#index)
---- ----
@ -98,7 +101,7 @@ The [Wiki](https://github.com/ocornut/imgui/wiki) is a hub to many resources and
--- ---
### Q: How can I tell whether to dispatch mouse/keyboard to Dear ImGui or my application? ### Q: How can I tell whether to dispatch mouse/keyboard to Dear ImGui or to my application?
You can read the `io.WantCaptureMouse`, `io.WantCaptureKeyboard` and `io.WantTextInput` flags from the ImGuiIO structure. You can read the `io.WantCaptureMouse`, `io.WantCaptureKeyboard` and `io.WantTextInput` flags from the ImGuiIO structure.
- When `io.WantCaptureMouse` is set, you need to discard/hide the mouse inputs from your underlying application. - When `io.WantCaptureMouse` is set, you need to discard/hide the mouse inputs from your underlying application.
@ -113,7 +116,7 @@ void MyLowLevelMouseButtonHandler(int button, bool down)
// (1) ALWAYS forward mouse data to ImGui! This is automatic with default backends. With your own backend: // (1) ALWAYS forward mouse data to ImGui! This is automatic with default backends. With your own backend:
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.MouseDown[button] = down; io.MouseDown[button] = down;
// (2) ONLY forward mouse data to your underlying app/game. // (2) ONLY forward mouse data to your underlying app/game.
if (!io.WantCaptureMouse) if (!io.WantCaptureMouse)
my_game->HandleMouseData(...); my_game->HandleMouseData(...);
@ -159,7 +162,7 @@ Console SDK also sometimes provide equivalent tooling or wrapper for Synergy-lik
--- ---
### Q: I integrated Dear ImGui in my engine and little squares are showing instead of text... ### Q: I integrated Dear ImGui in my engine and little squares are showing instead of text..
This usually means that: your font texture wasn't uploaded into GPU, or your shader or other rendering state are not reading from the right texture (e.g. texture wasn't bound). This usually means that: your font texture wasn't uploaded into GPU, or your shader or other rendering state are not reading from the right texture (e.g. texture wasn't bound).
If this happens using the standard backends it is probably that the texture failed to upload, which could happens if for some reason your texture is too big. Also see [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md). If this happens using the standard backends it is probably that the texture failed to upload, which could happens if for some reason your texture is too big. Also see [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md).
@ -167,8 +170,8 @@ If this happens using the standard backends it is probably that the texture fail
--- ---
### Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around... ### Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around..
### Q: I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries... ### Q: I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries..
You are probably mishandling the clipping rectangles in your render function. You are probably mishandling the clipping rectangles in your render function.
Each draw command needs the triangle rendered using the clipping rectangle provided in the ImDrawCmd structure (`ImDrawCmd->CllipRect`). Each draw command needs the triangle rendered using the clipping rectangle provided in the ImDrawCmd structure (`ImDrawCmd->CllipRect`).
Rectangles provided by Dear ImGui are defined as Rectangles provided by Dear ImGui are defined as
@ -370,7 +373,7 @@ ImGui::Image((void*)texture, ImVec2(texture->Width, texture->Height));
The renderer function called after ImGui::Render() will receive that same value that the user code passed: The renderer function called after ImGui::Render() will receive that same value that the user code passed:
```cpp ```cpp
// Cast ImTextureID / void* stored in the draw command as our texture type // Cast ImTextureID / void* stored in the draw command as our texture type
MyTexture* texture = (MyTexture*)pcmd->GetTexID(); MyTexture* texture = (MyTexture*)pcmd->TextureId;
MyEngineBindTexture2D(texture); MyEngineBindTexture2D(texture);
``` ```
Once you understand this design you will understand that loading image files and turning them into displayable textures is not within the scope of Dear ImGui. Once you understand this design you will understand that loading image files and turning them into displayable textures is not within the scope of Dear ImGui.
@ -651,11 +654,11 @@ There is an auto-generated [c-api for Dear ImGui (cimgui)](https://github.com/ci
# Q&A: Community # Q&A: Community
### Q: How can I help? ### Q: How can I help?
- Businesses: please reach out to `contact AT dearimgui.com` if you work in a place using Dear ImGui! We can discuss ways for your company to fund development via invoiced technical support, maintenance or sponsoring contacts. This is among the most useful thing you can do for Dear ImGui. With increased funding, we can hire more people working on this project. - Businesses: please reach out to `contact AT dearimgui.com` if you work in a place using Dear ImGui! We can discuss ways for your company to fund development via invoiced technical support, maintenance or sponsoring contacts. This is among the most useful thing you can do for Dear ImGui. With increased funding we can hire more people working on this project.
- Individuals: you can support continued maintenance and development via PayPal donations. See [README](https://github.com/ocornut/imgui/blob/master/docs/README.md). - Individuals: you can support continued maintenance and development via PayPal donations. See [README](https://github.com/ocornut/imgui/blob/master/docs/README.md).
- If you are experienced with Dear ImGui and C++, look at [GitHub Issues](https://github.com/ocornut/imgui/issues), [GitHub Discussions](https://github.com/ocornut/imgui/discussions), the [Wiki](https://github.com/ocornut/imgui/wiki), read [docs/TODO.txt](https://github.com/ocornut/imgui/blob/master/docs/TODO.txt) and see how you want to help and can help! - If you are experienced with Dear ImGui and C++, look at [GitHub Issues](https://github.com/ocornut/imgui/issues), [GitHub Discussions](https://github.com/ocornut/imgui/discussions), the [Wiki](https://github.com/ocornut/imgui/wiki), read [docs/TODO.txt](https://github.com/ocornut/imgui/blob/master/docs/TODO.txt) and see how you want to help and can help!
- Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere etc. - Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere etc.
You may post screenshot or links in the [gallery threads](https://github.com/ocornut/imgui/issues/3488). Visuals are ideal as they inspire other programmers. Disclosing your use of Dear ImGui helps the library grow credibility, and help other teams and programmers with taking decisions. You may post screenshot or links in the [gallery threads](https://github.com/ocornut/imgui/issues/3488). Visuals are ideal as they inspire other programmers. Disclosing your use of dear imgui help the library grow credibility, and help other teams and programmers with taking decisions.
- If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues or sometimes incomplete PR. - If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues or sometimes incomplete PR.
##### [Return to Index](#index) ##### [Return to Index](#index)

View File

@ -5,7 +5,7 @@ _(You may browse this at https://github.com/ocornut/imgui/blob/master/docs/FONTS
The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' (by Tristan Grimmer), The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' (by Tristan Grimmer),
a 13 pixels high, pixel-perfect font used by default. We embed it in the source code so you can use Dear ImGui without any file system access. ProggyClean does not scale smoothly, therefore it is recommended that you load your own file when using Dear ImGui in an application aiming to look nice and wanting to support multiple resolutions. a 13 pixels high, pixel-perfect font used by default. We embed it in the source code so you can use Dear ImGui without any file system access. ProggyClean does not scale smoothly, therefore it is recommended that you load your own file when using Dear ImGui in an application aiming to look nice and wanting to support multiple resolutions.
You may also load external .TTF/.OTF files. You may also load external .TTF/.OTF files.
In the [misc/fonts/](https://github.com/ocornut/imgui/tree/master/misc/fonts) folder you can find a few suggested fonts, provided as a convenience. In the [misc/fonts/](https://github.com/ocornut/imgui/tree/master/misc/fonts) folder you can find a few suggested fonts, provided as a convenience.
**Also read the FAQ:** https://www.dearimgui.org/faq (there is a Fonts section!) **Also read the FAQ:** https://www.dearimgui.org/faq (there is a Fonts section!)
@ -14,9 +14,8 @@ In the [misc/fonts/](https://github.com/ocornut/imgui/tree/master/misc/fonts) fo
- [Readme First](#readme-first) - [Readme First](#readme-first)
- [How should I handle DPI in my application?](#how-should-i-handle-dpi-in-my-application) - [How should I handle DPI in my application?](#how-should-i-handle-dpi-in-my-application)
- [Fonts Loading Instructions](#font-loading-instructions) - [Fonts Loading Instructions](#font-loading-instructions)
- [Using Icon Fonts](#using-icon-fonts) - [Using Icons](#using-icons)
- [Using FreeType Rasterizer (imgui_freetype)](#using-freetype-rasterizer-imgui_freetype) - [Using FreeType Rasterizer](#using-freetype-rasterizer)
- [Using Colorful Glyphs/Emojis](#using-colorful-glyphsemojis)
- [Using Custom Glyph Ranges](#using-custom-glyph-ranges) - [Using Custom Glyph Ranges](#using-custom-glyph-ranges)
- [Using Custom Colorful Icons](#using-custom-colorful-icons) - [Using Custom Colorful Icons](#using-custom-colorful-icons)
- [Using Font Data Embedded In Source Code](#using-font-data-embedded-in-source-code) - [Using Font Data Embedded In Source Code](#using-font-data-embedded-in-source-code)
@ -27,7 +26,7 @@ In the [misc/fonts/](https://github.com/ocornut/imgui/tree/master/misc/fonts) fo
--------------------------------------- ---------------------------------------
## Readme First ## Readme First
- All loaded fonts glyphs are rendered into a single texture atlas ahead of time. Calling either of `io.Fonts->GetTexDataAsAlpha8()`, `io.Fonts->GetTexDataAsRGBA32()` or `io.Fonts->Build()` will build the atlas. - All loaded fonts glyphs are rendered into a single texture atlas ahead of time. Calling either of `io.Fonts->GetTexDataAsAlpha8()`, `io.Fonts->GetTexDataAsRGBA32()` or `io.Fonts->Build()` will build the atlas.
- You can use the style editor `ImGui::ShowStyleEditor()` in the "Fonts" section to browse your fonts and understand what's going on if you have an issue. You can also reach it in `Demo->Tools->Style Editor->Fonts`: - You can use the style editor `ImGui::ShowStyleEditor()` in the "Fonts" section to browse your fonts and understand what's going on if you have an issue. You can also reach it in `Demo->Tools->Style Editor->Fonts`:
@ -161,13 +160,13 @@ Some solutions:
##### [Return to Index](#index) ##### [Return to Index](#index)
## Using Icon Fonts ## Using Icons
Using an icon font (such as [FontAwesome](http://fontawesome.io) or [OpenFontIcons](https://github.com/traverseda/OpenFontIcons)) is an easy and practical way to use icons in your Dear ImGui application. Using an icon font (such as [FontAwesome](http://fontawesome.io) or [OpenFontIcons](https://github.com/traverseda/OpenFontIcons)) is an easy and practical way to use icons in your Dear ImGui application.
A common pattern is to merge the icon font within your main font, so you can embed icons directly from your strings without having to change fonts back and forth. A common pattern is to merge the icon font within your main font, so you can embed icons directly from your strings without having to change fonts back and forth.
To refer to the icon UTF-8 codepoints from your C++ code, you may use those headers files created by Juliette Foucaut: https://github.com/juliettef/IconFontCppHeaders. To refer to the icon UTF-8 codepoints from your C++ code, you may use those headers files created by Juliette Foucaut: https://github.com/juliettef/IconFontCppHeaders.
So you can use `ICON_FA_SEARCH` as a string that will render as a "Search" icon. So you can use `ICON_FA_SEARCH` as a string that will render as a "Search" icon.
Example Setup: Example Setup:
@ -198,7 +197,7 @@ Here's an application using icons ("Avoyd", https://www.avoyd.com):
##### [Return to Index](#index) ##### [Return to Index](#index)
## Using FreeType Rasterizer (imgui_freetype) ## Using FreeType Rasterizer
- Dear ImGui uses imstb\_truetype.h to rasterize fonts (with optional oversampling). This technique and its implementation are not ideal for fonts rendered at small sizes, which may appear a little blurry or hard to read. - Dear ImGui uses imstb\_truetype.h to rasterize fonts (with optional oversampling). This technique and its implementation are not ideal for fonts rendered at small sizes, which may appear a little blurry or hard to read.
- There is an implementation of the ImFontAtlas builder using FreeType that you can use in the [misc/freetype/](https://github.com/ocornut/imgui/tree/master/misc/freetype) folder. - There is an implementation of the ImFontAtlas builder using FreeType that you can use in the [misc/freetype/](https://github.com/ocornut/imgui/tree/master/misc/freetype) folder.
@ -208,28 +207,6 @@ Here's an application using icons ("Avoyd", https://www.avoyd.com):
##### [Return to Index](#index) ##### [Return to Index](#index)
## Using Colorful Glyphs/Emojis
- Rendering of colored emojis is only supported by imgui_freetype with FreeType 2.10+.
- You will need to load fonts with the `ImGuiFreeTypeBuilderFlags_LoadColor` flag.
- Emojis are frequently encoded in upper Unicode layers (character codes >0x10000) and will need dear imgui compiled with `IMGUI_USE_WCHAR32`.
- Not all types of color fonts are supported by FreeType at the moment.
- Stateful Unicode features such as skin tone modifiers are not supported by the text renderer.
![colored glyphs](https://user-images.githubusercontent.com/8225057/106171241-9dc4ba80-6191-11eb-8a69-ca1467b206d1.png)
```cpp
io.Fonts->AddFontFromFileTTF("../../../imgui_dev/data/fonts/NotoSans-Regular.ttf", 16.0f);
static ImWchar ranges[] = { 0x1, 0x1FFFF, 0 };
static ImFontConfig cfg;
cfg.OversampleH = cfg.OversampleV = 1;
cfg.MergeMode = true;
cfg.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_LoadColor;
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\seguiemj.ttf", 16.0f, &cfg, ranges);
```
##### [Return to Index](#index)
## Using Custom Glyph Ranges ## Using Custom Glyph Ranges
You can use the `ImFontGlyphRangesBuilder` helper to create glyph ranges based on text input. For example: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs. You can use the `ImFontGlyphRangesBuilder` helper to create glyph ranges based on text input. For example: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs.
@ -249,7 +226,7 @@ io.Fonts->Build(); // Build the atlas while
## Using Custom Colorful Icons ## Using Custom Colorful Icons
As an alternative to rendering colorful glyphs using imgui_freetype with `ImGuiFreeTypeBuilderFlags_LoadColor`, you may allocate your own space in the texture atlas and write yourself into it. **(This is a BETA api, use if you are familiar with dear imgui and with your rendering backend)** **(This is a BETA api, use if you are familiar with dear imgui and with your rendering backend)**
- You can use the `ImFontAtlas::AddCustomRect()` and `ImFontAtlas::AddCustomRectFontGlyph()` api to register rectangles that will be packed into the font atlas texture. Register them before building the atlas, then call Build()`. - You can use the `ImFontAtlas::AddCustomRect()` and `ImFontAtlas::AddCustomRectFontGlyph()` api to register rectangles that will be packed into the font atlas texture. Register them before building the atlas, then call Build()`.
- You can then use `ImFontAtlas::GetCustomRectByIndex(int)` to query the position/size of your rectangle within the texture, and blit/copy any graphics data of your choice into those rectangles. - You can then use `ImFontAtlas::GetCustomRectByIndex(int)` to query the position/size of your rectangle within the texture, and blit/copy any graphics data of your choice into those rectangles.
@ -338,7 +315,7 @@ Some fonts files are available in the `misc/fonts/` folder:
<br>https://fonts.google.com/specimen/Roboto <br>https://fonts.google.com/specimen/Roboto
**Cousine-Regular.ttf**, by Steve Matteson **Cousine-Regular.ttf**, by Steve Matteson
<br>Digitized data copyright (c) 2010 Google Corporation. <br>Digitized data copyright (c) 2010 Google Corporation.
<br>Licensed under the SIL Open Font License, Version 1.1 <br>Licensed under the SIL Open Font License, Version 1.1
<br>https://fonts.google.com/specimen/Cousine <br>https://fonts.google.com/specimen/Cousine

View File

@ -105,7 +105,7 @@ Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcas
![screenshot demo](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png) ![screenshot demo](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png)
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let us know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here: You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let us know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here:
- [imgui-demo-binaries-20210331.zip](https://www.dearimgui.org/binaries/imgui-demo-binaries-20210331.zip) (Windows, 1.83 WIP, built 2021/03/31, master branch) or [older demo binaries](https://www.dearimgui.org/binaries). - [imgui-demo-binaries-20200918.zip](https://www.dearimgui.org/binaries/imgui-demo-binaries-20200918.zip) (Windows, 1.78 WIP, built 2020/09/18, master branch) or [older demo binaries](https://www.dearimgui.org/binaries).
The demo applications are not DPI aware so expect some blurriness on a 4K screen. For DPI awareness in your application, you can load/reload your font at different scale, and scale your style with `style.ScaleAllSizes()` (see [FAQ](https://www.dearimgui.org/faq)). The demo applications are not DPI aware so expect some blurriness on a 4K screen. For DPI awareness in your application, you can load/reload your font at different scale, and scale your style with `style.ScaleAllSizes()` (see [FAQ](https://www.dearimgui.org/faq)).
@ -125,7 +125,7 @@ Officially maintained backends/bindings (in repository):
- Frameworks: AGS/Adventure Game Studio, Amethyst, Blender, bsf, Cinder, Cocos2d-x, Diligent Engine, Flexium, GML/Game Maker Studio2, GLEQ, Godot, GTK3+OpenGL3, Irrlicht Engine, LÖVE+LUA, Magnum, Monogame, NanoRT, nCine, Nim Game Lib, Nintendo 3DS & Switch (homebrew), Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, Photoshop, px_render, Qt/QtDirect3D, SDL_Renderer, SFML, Sokol, Unity, Unreal Engine 4, vtk, VulkanHpp, VulkanSceneGraph, Win32 GDI, WxWidgets. - Frameworks: AGS/Adventure Game Studio, Amethyst, Blender, bsf, Cinder, Cocos2d-x, Diligent Engine, Flexium, GML/Game Maker Studio2, GLEQ, Godot, GTK3+OpenGL3, Irrlicht Engine, LÖVE+LUA, Magnum, Monogame, NanoRT, nCine, Nim Game Lib, Nintendo 3DS & Switch (homebrew), Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, Photoshop, px_render, Qt/QtDirect3D, SDL_Renderer, SFML, Sokol, Unity, Unreal Engine 4, vtk, VulkanHpp, VulkanSceneGraph, Win32 GDI, WxWidgets.
- Note that C bindings ([cimgui](https://github.com/cimgui/cimgui)) are auto-generated, you can use its json/lua output to generate bindings for other languages. - Note that C bindings ([cimgui](https://github.com/cimgui/cimgui)) are auto-generated, you can use its json/lua output to generate bindings for other languages.
[Useful Extensions/Widgets](https://github.com/ocornut/imgui/wiki/Useful-Extensions) wiki page: [Useful widgets and extensions](https://github.com/ocornut/imgui/wiki/Useful-Widgets) wiki page:
- Text editors, node editors, timeline editors, plotting, software renderers, remote network access, memory editors, gizmos etc. - Text editors, node editors, timeline editors, plotting, software renderers, remote network access, memory editors, gizmos etc.
Also see [Wiki](https://github.com/ocornut/imgui/wiki) for more links and ideas. Also see [Wiki](https://github.com/ocornut/imgui/wiki) for more links and ideas.
@ -143,7 +143,7 @@ Some of the goals for 2021 are:
For more user-submitted screenshots of projects using Dear ImGui, check out the [Gallery Threads](https://github.com/ocornut/imgui/issues/3488)! For more user-submitted screenshots of projects using Dear ImGui, check out the [Gallery Threads](https://github.com/ocornut/imgui/issues/3488)!
For a list of third-party widgets and extensions, check out the [Useful Extensions/Widgets](https://github.com/ocornut/imgui/wiki/Useful-Extensions) wiki page. For a list of third-party widgets and extensions, check out the [Useful Widgets](https://github.com/ocornut/imgui/wiki/Useful-Widgets) wiki page.
Custom engine Custom engine
[![screenshot game](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v149/gallery_TheDragonsTrap-01-thumb.jpg)](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png) [![screenshot game](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v149/gallery_TheDragonsTrap-01-thumb.jpg)](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
@ -196,13 +196,13 @@ Sponsors
Ongoing Dear ImGui development is currently financially supported by users and private sponsors: Ongoing Dear ImGui development is currently financially supported by users and private sponsors:
*Platinum-chocolate sponsors* *Platinum-chocolate sponsors*
- [Blizzard](https://careers.blizzard.com/en-us/openings/engineering/all/all/all/1), [Google](https://github.com/google/filament), [Nvidia](https://developer.nvidia.com/nvidia-omniverse) - [Blizzard](https://careers.blizzard.com/en-us/openings/engineering/all/all/all/1), [Google](https://github.com/google/filament), [Nvidia](https://developer.nvidia.com/nvidia-omniverse), [Ubisoft](https://montreal.ubisoft.com/en/ubisoft-sponsors-user-interface-library-for-c-dear-imgui/)
*Double-chocolate and Salty caramel sponsors* *Double-chocolate and Salty caramel sponsors*
- [Activision](https://careers.activision.com/c/programmingsoftware-engineering-jobs), [Aras Pranckevičius](https://aras-p.info), [Arkane Studios](https://www.arkane-studios.com), [Framefield](http://framefield.com), [Grinding Gear Games](https://www.grindinggear.com), [Kylotonn](https://www.kylotonn.com), [Next Level Games](https://www.nextlevelgames.com), [RAD Game Tools](http://www.radgametools.com/), [O-Net Communications (USA)](http://en.o-netcom.com), [Supercell](https://supercell.com), [Ubisoft](https://montreal.ubisoft.com/en/ubisoft-sponsors-user-interface-library-for-c-dear-imgui) - [Activision](https://careers.activision.com/c/programmingsoftware-engineering-jobs), [Aras Pranckevičius](https://aras-p.info), [Arkane Studios](https://www.arkane-studios.com), [Framefield](http://framefield.com), [Grinding Gear Games](https://www.grindinggear.com), [Kylotonn](https://www.kylotonn.com), [Next Level Games](https://www.nextlevelgames.com), [RAD Game Tools](http://www.radgametools.com/), [Supercell](http://www.supercell.com)
Please see [detailed list of Dear ImGui supporters](https://github.com/ocornut/imgui/wiki/Sponsors) for past sponsors. Please see [detailed list of Dear ImGui supporters](https://github.com/ocornut/imgui/wiki/Sponsors) for past sponsors.
From November 2014 to December 2019, ongoing development has also been financially supported by its users on Patreon and through individual donations. From November 2014 to December 2019, ongoing development has also been financially supported by its users on Patreon and through individual donations.
**THANK YOU to all past and present supporters for helping to keep this project alive and thriving!** **THANK YOU to all past and present supporters for helping to keep this project alive and thriving!**
@ -214,14 +214,12 @@ Dear ImGui is using software and services provided free of charge for open sourc
Credits Credits
------- -------
Developed by [Omar Cornut](https://www.miracleworld.net) and every direct or indirect [contributors](https://github.com/ocornut/imgui/graphs/contributors) to the GitHub. The early version of this library was developed with the support of [Media Molecule](https://www.mediamolecule.com) and first used internally on the game [Tearaway](https://tearaway.mediamolecule.com) (PS Vita). Developed by [Omar Cornut](http://www.miracleworld.net) and every direct or indirect [contributors](https://github.com/ocornut/imgui/graphs/contributors) to the GitHub. The early version of this library was developed with the support of [Media Molecule](http://www.mediamolecule.com) and first used internally on the game [Tearaway](http://tearaway.mediamolecule.com) (PS Vita).
Recurring contributors (2020): Omar Cornut [@ocornut](https://github.com/ocornut), Rokas Kupstys [@rokups](https://github.com/rokups), Ben Carter [@ShironekoBen](https://github.com/ShironekoBen). Recurring contributors (2020): Omar Cornut [@ocornut](https://github.com/ocornut), Rokas Kupstys [@rokups](https://github.com/rokups), Ben Carter [@ShironekoBen](https://github.com/ShironekoBen).
A large portion of work on automation systems, regression tests and other features are currently unpublished. A large portion of work on automation systems, regression tests and other features are currently unpublished.
Sponsoring, support contracts and other B2B transactions are hosted and handled by [Lizardcube](https://www.lizardcube.com). Omar: "I first discovered the IMGUI paradigm at [Q-Games](http://www.q-games.com) where Atman Binstock had dropped his own simple implementation in the codebase, which I spent quite some time improving and thinking about. It turned out that Atman was exposed to the concept directly by working with Casey. When I moved to Media Molecule I rewrote a new library trying to overcome the flaws and limitations of the first one I've worked with. It became this library and since then I have spent an unreasonable amount of time iterating and improving it."
Omar: "I first discovered the IMGUI paradigm at [Q-Games](https://www.q-games.com) where Atman Binstock had dropped his own simple implementation in the codebase, which I spent quite some time improving and thinking about. It turned out that Atman was exposed to the concept directly by working with Casey. When I moved to Media Molecule I rewrote a new library trying to overcome the flaws and limitations of the first one I've worked with. It became this library and since then I have spent an unreasonable amount of time iterating and improving it."
Embeds [ProggyClean.ttf](http://upperbounds.net) font by Tristan Grimmer (MIT license). Embeds [ProggyClean.ttf](http://upperbounds.net) font by Tristan Grimmer (MIT license).

View File

@ -352,7 +352,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- nav/windowing: Resizing window will currently fail with certain types of resizing constraints/callback applied - nav/windowing: Resizing window will currently fail with certain types of resizing constraints/callback applied
- focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622) - focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622)
- focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame) - focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame)
- focus: unable to use SetKeyboardFocusHere() on clipped widgets. (#787, #343) - focus: unable to use SetKeyboardFocusHere() on clipped widgets. (#787)
- inputs: we need an explicit flag about whether the imgui window is focused, to be able to distinguish focused key releases vs alt-tabbing all release behaviors. - inputs: we need an explicit flag about whether the imgui window is focused, to be able to distinguish focused key releases vs alt-tabbing all release behaviors.
- inputs: rework IO system to be able to pass actual ordered/timestamped events. use an event queue? (~#335, #71) - inputs: rework IO system to be able to pass actual ordered/timestamped events. use an event queue? (~#335, #71)

View File

@ -1,7 +1 @@
See BACKENDS and EXAMPLES files in the docs/ folder. See EXAMPLES and BACKENDS files in the docs/ folder.
Backends = Helper code to facilitate integration with platforms/graphics api (used by Examples + should be used by your app).
Examples = Standalone applications showcasing integration with platforms/graphics api.
Once Dear ImGui is running (in either examples or your own application/game/engine),
run and refer to ImGui::ShowDemoWindow() in imgui_demo.cpp for the end-user API.

View File

@ -1,12 +1,12 @@
buildscript { buildscript {
ext.kotlin_version = '1.4.31' ext.kotlin_version = '1.4.30'
repositories { repositories {
google() google()
mavenCentral() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.1.0' classpath 'com.android.tools.build:gradle:4.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
@ -15,7 +15,7 @@ buildscript {
allprojects { allprojects {
repositories { repositories {
google() google()
mavenCentral() jcenter()
} }
} }

View File

@ -147,7 +147,7 @@ static void main_loop(void* window)
wgpu_swap_chain_height = height; wgpu_swap_chain_height = height;
WGPUSwapChainDescriptor swap_chain_desc = {}; WGPUSwapChainDescriptor swap_chain_desc = {};
swap_chain_desc.usage = WGPUTextureUsage_RenderAttachment; swap_chain_desc.usage = WGPUTextureUsage_OutputAttachment;
swap_chain_desc.format = WGPUTextureFormat_RGBA8Unorm; swap_chain_desc.format = WGPUTextureFormat_RGBA8Unorm;
swap_chain_desc.width = width; swap_chain_desc.width = width;
swap_chain_desc.height = height; swap_chain_desc.height = height;
@ -202,11 +202,11 @@ static void main_loop(void* window)
// Rendering // Rendering
ImGui::Render(); ImGui::Render();
WGPURenderPassColorAttachment color_attachments = {}; WGPURenderPassColorAttachmentDescriptor color_attachments = {};
color_attachments.loadOp = WGPULoadOp_Clear; color_attachments.loadOp = WGPULoadOp_Clear;
color_attachments.storeOp = WGPUStoreOp_Store; color_attachments.storeOp = WGPUStoreOp_Store;
color_attachments.clearColor = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; color_attachments.clearColor = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };
color_attachments.view = wgpuSwapChainGetCurrentTextureView(wgpu_swap_chain); color_attachments.attachment = wgpuSwapChainGetCurrentTextureView(wgpu_swap_chain);
WGPURenderPassDescriptor render_pass_desc = {}; WGPURenderPassDescriptor render_pass_desc = {};
render_pass_desc.colorAttachmentCount = 1; render_pass_desc.colorAttachmentCount = 1;
render_pass_desc.colorAttachments = &color_attachments; render_pass_desc.colorAttachments = &color_attachments;
@ -221,7 +221,7 @@ static void main_loop(void* window)
WGPUCommandBufferDescriptor cmd_buffer_desc = {}; WGPUCommandBufferDescriptor cmd_buffer_desc = {};
WGPUCommandBuffer cmd_buffer = wgpuCommandEncoderFinish(encoder, &cmd_buffer_desc); WGPUCommandBuffer cmd_buffer = wgpuCommandEncoderFinish(encoder, &cmd_buffer_desc);
WGPUQueue queue = wgpuDeviceGetQueue(wgpu_device); WGPUQueue queue = wgpuDeviceGetDefaultQueue(wgpu_device);
wgpuQueueSubmit(queue, 1, &cmd_buffer); wgpuQueueSubmit(queue, 1, &cmd_buffer);
} }

View File

@ -14,10 +14,9 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -framework CoreVideo -framework QuartzCore LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -framework CoreVideo -framework QuartzCore
LIBS += -L/usr/local/lib -L/opt/homebrew/lib LIBS += -L/usr/local/lib -lglfw
LIBS += -lglfw
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include -I/opt/homebrew/include CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include
CXXFLAGS += -Wall -Wformat CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)

View File

@ -41,11 +41,11 @@ endif
ifeq ($(UNAME_S), Darwin) #APPLE ifeq ($(UNAME_S), Darwin) #APPLE
ECHO_MESSAGE = "Mac OS X" ECHO_MESSAGE = "Mac OS X"
LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
LIBS += -L/usr/local/lib -L/opt/local/lib -L/opt/homebrew/lib LIBS += -L/usr/local/lib -L/opt/local/lib
#LIBS += -lglfw3 #LIBS += -lglfw3
LIBS += -lglfw LIBS += -lglfw
CXXFLAGS += -I/usr/local/include -I/opt/local/include -I/opt/homebrew/include CXXFLAGS += -I/usr/local/include -I/opt/local/include
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif endif

View File

@ -21,19 +21,15 @@ SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui
SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
LINUX_GL_LIBS = -lGL
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS += -g -Wall -Wformat CXXFLAGS += -g -Wall -Wformat
LIBS = LIBS =
##--------------------------------------------------------------------- ##---------------------------------------------------------------------
## OPENGL LOADER / OPENGL ES ## OPENGL LOADER
##--------------------------------------------------------------------- ##---------------------------------------------------------------------
## See below for OpenGL ES option (no loader required) - comment out
## the following if you want to use OpenGL ES instead of Desktop GL.
## Using OpenGL loader: gl3w [default] ## Using OpenGL loader: gl3w [default]
SOURCES += ../libs/gl3w/GL/gl3w.c SOURCES += ../libs/gl3w/GL/gl3w.c
CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W
@ -60,18 +56,13 @@ CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W
# CXXFLAGS += -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING2 # CXXFLAGS += -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING2
# LIBS += -lglbinding # LIBS += -lglbinding
## Using OpenGL ES, no loader required
## This assumes a GL ES library available in the system, e.g. libGLESv2.so
# CXXFLAGS += -DIMGUI_IMPL_OPENGL_ES2
# LINUX_GL_LIBS = -lGLESv2
##--------------------------------------------------------------------- ##---------------------------------------------------------------------
## BUILD FLAGS PER PLATFORM ## BUILD FLAGS PER PLATFORM
##--------------------------------------------------------------------- ##---------------------------------------------------------------------
ifeq ($(UNAME_S), Linux) #LINUX ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux" ECHO_MESSAGE = "Linux"
LIBS += $(LINUX_GL_LIBS) `pkg-config --static --libs glfw3` LIBS += -lGL `pkg-config --static --libs glfw3`
CXXFLAGS += `pkg-config --cflags glfw3` CXXFLAGS += `pkg-config --cflags glfw3`
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
@ -80,11 +71,11 @@ endif
ifeq ($(UNAME_S), Darwin) #APPLE ifeq ($(UNAME_S), Darwin) #APPLE
ECHO_MESSAGE = "Mac OS X" ECHO_MESSAGE = "Mac OS X"
LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
LIBS += -L/usr/local/lib -L/opt/local/lib -L/opt/homebrew/lib LIBS += -L/usr/local/lib -L/opt/local/lib
#LIBS += -lglfw3 #LIBS += -lglfw3
LIBS += -lglfw LIBS += -lglfw
CXXFLAGS += -I/usr/local/include -I/opt/local/include -I/opt/homebrew/include CXXFLAGS += -I/usr/local/include -I/opt/local/include
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif endif

View File

@ -8,13 +8,11 @@
#include "imgui_impl_opengl3.h" #include "imgui_impl_opengl3.h"
#include <stdio.h> #include <stdio.h>
#if defined(IMGUI_IMPL_OPENGL_ES2)
#include <GLES2/gl2.h>
// About Desktop OpenGL function loaders: // About Desktop OpenGL function loaders:
// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers. // Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
// Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad). // Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own. // You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) #if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
#include <GL/gl3w.h> // Initialize with gl3wInit() #include <GL/gl3w.h> // Initialize with gl3wInit()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
#include <GL/glew.h> // Initialize with glewInit() #include <GL/glew.h> // Initialize with glewInit()
@ -59,13 +57,7 @@ int main(int, char**)
return 1; return 1;
// Decide GL+GLSL versions // Decide GL+GLSL versions
#if defined(IMGUI_IMPL_OPENGL_ES2) #ifdef __APPLE__
// GL ES 2.0 + GLSL 100
const char* glsl_version = "#version 100";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
#elif defined(__APPLE__)
// GL 3.2 + GLSL 150 // GL 3.2 + GLSL 150
const char* glsl_version = "#version 150"; const char* glsl_version = "#version 150";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);

View File

@ -122,22 +122,10 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus);
check_vk_result(err); check_vk_result(err);
// If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers // If a number >1 of GPUs got reported, you should find the best fit GPU for your purpose
// most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple // e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc.
// dedicated GPUs) is out of scope of this sample. // for sake of simplicity we'll just take the first one, assuming it has a graphics queue family.
int use_gpu = 0; g_PhysicalDevice = gpus[0];
for (int i = 0; i < (int)gpu_count; i++)
{
VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties(gpus[i], &properties);
if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
{
use_gpu = i;
break;
}
}
g_PhysicalDevice = gpus[use_gpu];
free(gpus); free(gpus);
} }
@ -265,7 +253,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore; VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) if (err == VK_ERROR_OUT_OF_DATE_KHR)
{ {
g_SwapChainRebuild = true; g_SwapChainRebuild = true;
return; return;
@ -338,7 +326,7 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
info.pSwapchains = &wd->Swapchain; info.pSwapchains = &wd->Swapchain;
info.pImageIndices = &wd->FrameIndex; info.pImageIndices = &wd->FrameIndex;
VkResult err = vkQueuePresentKHR(g_Queue, &info); VkResult err = vkQueuePresentKHR(g_Queue, &info);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) if (err == VK_ERROR_OUT_OF_DATE_KHR)
{ {
g_SwapChainRebuild = true; g_SwapChainRebuild = true;
return; return;

View File

@ -3,6 +3,6 @@
@set OUT_EXE=example_sdl_directx11 @set OUT_EXE=example_sdl_directx11
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /I "%DXSDK_DIR%Include" @set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /I "%DXSDK_DIR%Include"
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_dx11.cpp ..\..\imgui*.cpp @set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_dx11.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d11.lib d3dcompiler.lib shell32.lib @set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d11.lib d3dcompiler.lib
mkdir %OUT_DIR% mkdir %OUT_DIR%
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console

View File

@ -103,7 +103,7 @@ int main(int, char**)
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)) if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
done = true; done = true;
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window)) if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window))
{ {
// Release all outstanding references to the swap chain's buffers before resizing. // Release all outstanding references to the swap chain's buffers before resizing.
CleanupRenderTarget(); CleanupRenderTarget();
g_pSwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0); g_pSwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);

View File

@ -14,12 +14,12 @@ cl /Zi /MD /I.. /I..\.. /I%SDL2_DIR%\include main.cpp ..\..\backends\imgui_impl_
- On Linux and similar Unixes - On Linux and similar Unixes
``` ```
c++ `sdl2-config --cflags` -I .. -I ../.. -I ../../backends main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_opengl2.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL c++ `sdl2-config --cflags` -I .. -I ../.. main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_opengl2.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL
``` ```
- On Mac OS X - On Mac OS X
``` ```
brew install sdl2 brew install sdl2
c++ `sdl2-config --cflags` -I .. -I ../.. -I ../../backends main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_opengl2.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl c++ `sdl2-config --cflags` -I .. -I ../.. main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_opengl2.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl
``` ```

View File

@ -3,6 +3,6 @@
@set OUT_EXE=example_sdl_opengl2 @set OUT_EXE=example_sdl_opengl2
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include @set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_opengl2.cpp ..\..\imgui*.cpp @set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_opengl2.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib shell32.lib @set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib
mkdir %OUT_DIR% mkdir %OUT_DIR%
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console

View File

@ -21,19 +21,15 @@ SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui
SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
LINUX_GL_LIBS = -lGL
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS += -g -Wall -Wformat CXXFLAGS += -g -Wall -Wformat
LIBS = LIBS =
##--------------------------------------------------------------------- ##---------------------------------------------------------------------
## OPENGL LOADER / OPENGL ES ## OPENGL LOADER
##--------------------------------------------------------------------- ##---------------------------------------------------------------------
## See below for OpenGL ES option (no loader required) - comment out
## the following if you want to use OpenGL ES instead of Desktop GL.
## Using OpenGL loader: gl3w [default] ## Using OpenGL loader: gl3w [default]
SOURCES += ../libs/gl3w/GL/gl3w.c SOURCES += ../libs/gl3w/GL/gl3w.c
CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W
@ -60,21 +56,13 @@ CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W
# CXXFLAGS += -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING2 # CXXFLAGS += -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING2
# LIBS += -lglbinding # LIBS += -lglbinding
## Using OpenGL ES, no loader required
## This assumes a GL ES library available in the system, e.g. libGLESv2.so
# CXXFLAGS += -DIMGUI_IMPL_OPENGL_ES2
# LINUX_GL_LIBS = -lGLESv2
## If you're on a Raspberry Pi and want to use the legacy drivers,
## use the following instead:
# LINUX_GL_LIBS = -L/opt/vc/lib -lbrcmGLESv2
##--------------------------------------------------------------------- ##---------------------------------------------------------------------
## BUILD FLAGS PER PLATFORM ## BUILD FLAGS PER PLATFORM
##--------------------------------------------------------------------- ##---------------------------------------------------------------------
ifeq ($(UNAME_S), Linux) #LINUX ifeq ($(UNAME_S), Linux) #LINUX
ECHO_MESSAGE = "Linux" ECHO_MESSAGE = "Linux"
LIBS += $(LINUX_GL_LIBS) -ldl `sdl2-config --libs` LIBS += -lGL -ldl `sdl2-config --libs`
CXXFLAGS += `sdl2-config --cflags` CXXFLAGS += `sdl2-config --cflags`
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)

View File

@ -14,12 +14,12 @@ cl /Zi /MD /I.. /I..\.. /I%SDL2_DIR%\include /I..\libs\gl3w main.cpp ..\..\backe
- On Linux and similar Unixes - On Linux and similar Unixes
``` ```
c++ `sdl2-config --cflags` -I .. -I ../.. -I ../../backends -I ../libs/gl3w main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_opengl3.cpp ../../imgui*.cpp ../libs/gl3w/GL/gl3w.c `sdl2-config --libs` -lGL -ldl c++ `sdl2-config --cflags` -I .. -I ../.. -I ../libs/gl3w main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_opengl3.cpp ../../imgui*.cpp ../libs/gl3w/GL/gl3w.c `sdl2-config --libs` -lGL -ldl
``` ```
- On Mac OS X - On Mac OS X
``` ```
brew install sdl2 brew install sdl2
c++ `sdl2-config --cflags` -I .. -I ../.. -I ../../backends -I ../libs/gl3w main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_opengl3.cpp ../../imgui*.cpp ../libs/gl3w/GL/gl3w.c `sdl2-config --libs` -framework OpenGl -framework CoreFoundation c++ `sdl2-config --cflags` -I .. -I ../.. -I ../libs/gl3w main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_opengl3.cpp ../../imgui*.cpp ../libs/gl3w/GL/gl3w.c `sdl2-config --libs` -framework OpenGl -framework CoreFoundation
``` ```

View File

@ -3,6 +3,6 @@
@set OUT_EXE=example_sdl_opengl3 @set OUT_EXE=example_sdl_opengl3
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include /I..\libs\gl3w @set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include /I..\libs\gl3w
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c @set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c
@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib shell32.lib @set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib
mkdir %OUT_DIR% mkdir %OUT_DIR%
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console

View File

@ -10,13 +10,11 @@
#include <stdio.h> #include <stdio.h>
#include <SDL.h> #include <SDL.h>
#if defined(IMGUI_IMPL_OPENGL_ES2)
#include <GLES2/gl2.h>
// About Desktop OpenGL function loaders: // About Desktop OpenGL function loaders:
// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers. // Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
// Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad). // Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own. // You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) #if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
#include <GL/gl3w.h> // Initialize with gl3wInit() #include <GL/gl3w.h> // Initialize with gl3wInit()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
#include <GL/glew.h> // Initialize with glewInit() #include <GL/glew.h> // Initialize with glewInit()
@ -51,14 +49,7 @@ int main(int, char**)
} }
// Decide GL+GLSL versions // Decide GL+GLSL versions
#if defined(IMGUI_IMPL_OPENGL_ES2) #ifdef __APPLE__
// GL ES 2.0 + GLSL 100
const char* glsl_version = "#version 100";
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#elif defined(__APPLE__)
// GL 3.2 Core + GLSL 150 // GL 3.2 Core + GLSL 150
const char* glsl_version = "#version 150"; const char* glsl_version = "#version 150";
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac

View File

@ -1,10 +0,0 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
@set OUT_EXE=example_sdl_vulkan
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include /I %VULKAN_SDK%\include
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 /libpath:%VULKAN_SDK%\lib32 SDL2.lib SDL2main.lib shell32.lib vulkan-1.lib
@set OUT_DIR=Debug
mkdir %OUT_DIR%
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console

View File

@ -114,22 +114,10 @@ static void SetupVulkan(const char** extensions, uint32_t extensions_count)
err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus);
check_vk_result(err); check_vk_result(err);
// If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers // If a number >1 of GPUs got reported, you should find the best fit GPU for your purpose
// most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple // e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc.
// dedicated GPUs) is out of scope of this sample. // for sake of simplicity we'll just take the first one, assuming it has a graphics queue family.
int use_gpu = 0; g_PhysicalDevice = gpus[0];
for (int i = 0; i < (int)gpu_count; i++)
{
VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties(gpus[i], &properties);
if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
{
use_gpu = i;
break;
}
}
g_PhysicalDevice = gpus[use_gpu];
free(gpus); free(gpus);
} }
@ -257,7 +245,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore; VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) if (err == VK_ERROR_OUT_OF_DATE_KHR)
{ {
g_SwapChainRebuild = true; g_SwapChainRebuild = true;
return; return;
@ -330,7 +318,7 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
info.pSwapchains = &wd->Swapchain; info.pSwapchains = &wd->Swapchain;
info.pImageIndices = &wd->FrameIndex; info.pImageIndices = &wd->FrameIndex;
VkResult err = vkQueuePresentKHR(g_Queue, &info); VkResult err = vkQueuePresentKHR(g_Queue, &info);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) if (err == VK_ERROR_OUT_OF_DATE_KHR)
{ {
g_SwapChainRebuild = true; g_SwapChainRebuild = true;
return; return;

View File

@ -78,24 +78,21 @@ int main(int, char**)
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// Main loop // Main loop
bool done = false; MSG msg;
while (!done) ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{ {
// Poll and handle messages (inputs, window resize, etc.) // Poll and handle messages (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
MSG msg; if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{ {
::TranslateMessage(&msg); ::TranslateMessage(&msg);
::DispatchMessage(&msg); ::DispatchMessage(&msg);
if (msg.message == WM_QUIT) continue;
done = true;
} }
if (done)
break;
// Start the Dear ImGui frame // Start the Dear ImGui frame
ImGui_ImplDX10_NewFrame(); ImGui_ImplDX10_NewFrame();

View File

@ -78,24 +78,21 @@ int main(int, char**)
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// Main loop // Main loop
bool done = false; MSG msg;
while (!done) ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{ {
// Poll and handle messages (inputs, window resize, etc.) // Poll and handle messages (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
MSG msg; if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{ {
::TranslateMessage(&msg); ::TranslateMessage(&msg);
::DispatchMessage(&msg); ::DispatchMessage(&msg);
if (msg.message == WM_QUIT) continue;
done = true;
} }
if (done)
break;
// Start the Dear ImGui frame // Start the Dear ImGui frame
ImGui_ImplDX11_NewFrame(); ImGui_ImplDX11_NewFrame();

View File

@ -117,24 +117,21 @@ int main(int, char**)
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// Main loop // Main loop
bool done = false; MSG msg;
while (!done) ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{ {
// Poll and handle messages (inputs, window resize, etc.) // Poll and handle messages (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
MSG msg; if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{ {
::TranslateMessage(&msg); ::TranslateMessage(&msg);
::DispatchMessage(&msg); ::DispatchMessage(&msg);
if (msg.message == WM_QUIT) continue;
done = true;
} }
if (done)
break;
// Start the Dear ImGui frame // Start the Dear ImGui frame
ImGui_ImplDX12_NewFrame(); ImGui_ImplDX12_NewFrame();

View File

@ -76,24 +76,21 @@ int main(int, char**)
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// Main loop // Main loop
bool done = false; MSG msg;
while (!done) ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{ {
// Poll and handle messages (inputs, window resize, etc.) // Poll and handle messages (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
MSG msg; if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{ {
::TranslateMessage(&msg); ::TranslateMessage(&msg);
::DispatchMessage(&msg); ::DispatchMessage(&msg);
if (msg.message == WM_QUIT) continue;
done = true;
} }
if (done)
break;
// Start the Dear ImGui frame // Start the Dear ImGui frame
ImGui_ImplDX9_NewFrame(); ImGui_ImplDX9_NewFrame();

View File

@ -42,8 +42,7 @@
//#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). //#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).
//#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) //#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)
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself. //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies) //#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.
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle 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.
//#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(). //#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().
//---- Include imgui_user.h at the end of imgui.h as a convenience //---- Include imgui_user.h at the end of imgui.h as a convenience

652
imgui.cpp

File diff suppressed because it is too large Load Diff

64
imgui.h
View File

@ -1,4 +1,4 @@
// dear imgui, v1.83 // dear imgui, v1.82 WIP
// (headers) // (headers)
// Help: // Help:
@ -11,9 +11,9 @@
// - FAQ http://dearimgui.org/faq // - FAQ http://dearimgui.org/faq
// - Homepage & latest https://github.com/ocornut/imgui // - Homepage & latest https://github.com/ocornut/imgui
// - Releases & changelog https://github.com/ocornut/imgui/releases // - Releases & changelog https://github.com/ocornut/imgui/releases
// - Gallery https://github.com/ocornut/imgui/issues/3793 (please post your screenshots/video there!) // - Gallery https://github.com/ocornut/imgui/issues/3488 (please post your screenshots/video there!)
// - Wiki https://github.com/ocornut/imgui/wiki (lots of good stuff there)
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary // - Glossary https://github.com/ocornut/imgui/wiki/Glossary
// - Wiki https://github.com/ocornut/imgui/wiki
// - Issues & support https://github.com/ocornut/imgui/issues // - Issues & support https://github.com/ocornut/imgui/issues
// - Discussions https://github.com/ocornut/imgui/discussions // - Discussions https://github.com/ocornut/imgui/discussions
@ -60,8 +60,8 @@ Index of this file:
// Version // Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.83" #define IMGUI_VERSION "1.82 WIP"
#define IMGUI_VERSION_NUM 18300 #define IMGUI_VERSION_NUM 18104
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE #define IMGUI_HAS_TABLE
@ -100,20 +100,7 @@ Index of this file:
#define IM_FMTLIST(FMT) #define IM_FMTLIST(FMT)
#endif #endif
// Disable some of MSVC most aggressive Debug runtime checks in function header/footer (used in some simple/low-level functions)
#if defined(_MSC_VER) && !defined(__clang__) && !defined(IMGUI_DEBUG_PARANOID)
#define IM_MSVC_RUNTIME_CHECKS_OFF __pragma(runtime_checks("",off)) __pragma(check_stack(off)) __pragma(strict_gs_check(push,off))
#define IM_MSVC_RUNTIME_CHECKS_RESTORE __pragma(runtime_checks("",restore)) __pragma(check_stack()) __pragma(strict_gs_check(pop))
#else
#define IM_MSVC_RUNTIME_CHECKS_OFF
#define IM_MSVC_RUNTIME_CHECKS_RESTORE
#endif
// Warnings // Warnings
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable: 26495) // [Static Analyzer] Variable 'XXX' is uninitialized. Always initialize a member variable (type.6).
#endif
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wold-style-cast" #pragma clang diagnostic ignored "-Wold-style-cast"
@ -240,7 +227,6 @@ typedef unsigned long long ImU64; // 64-bit unsigned integer (post C++11)
#endif #endif
// 2D vector (often used to store positions or sizes) // 2D vector (often used to store positions or sizes)
IM_MSVC_RUNTIME_CHECKS_OFF
struct ImVec2 struct ImVec2
{ {
float x, y; float x, y;
@ -263,7 +249,6 @@ struct ImVec4
IM_VEC4_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4. IM_VEC4_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4.
#endif #endif
}; };
IM_MSVC_RUNTIME_CHECKS_RESTORE
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] Dear ImGui end-user API functions // [SECTION] Dear ImGui end-user API functions
@ -391,7 +376,7 @@ namespace ImGui
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); // modify a style float variable. always use this if you modify the style after NewFrame(). IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); // modify a style float variable. always use this if you modify the style after NewFrame().
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); // modify a style ImVec2 variable. always use this if you modify the style after NewFrame(). IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); // modify a style ImVec2 variable. always use this if you modify the style after NewFrame().
IMGUI_API void PopStyleVar(int count = 1); IMGUI_API void PopStyleVar(int count = 1);
IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus); // == tab stop enable. Allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets
IMGUI_API void PopAllowKeyboardFocus(); IMGUI_API void PopAllowKeyboardFocus();
IMGUI_API void PushButtonRepeat(bool repeat); // in 'repeat' mode, Button*() functions return repeated true in a typematic manner (using io.KeyRepeatDelay/io.KeyRepeatRate setting). Note that you can call IsItemActive() after any Button() to tell if the button is held in the current frame. IMGUI_API void PushButtonRepeat(bool repeat); // in 'repeat' mode, Button*() functions return repeated true in a typematic manner (using io.KeyRepeatDelay/io.KeyRepeatRate setting). Note that you can call IsItemActive() after any Button() to tell if the button is held in the current frame.
IMGUI_API void PopButtonRepeat(); IMGUI_API void PopButtonRepeat();
@ -522,8 +507,8 @@ namespace ImGui
IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d", ImGuiSliderFlags flags = 0); IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d", ImGuiSliderFlags flags = 0);
IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d", ImGuiSliderFlags flags = 0); IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d", ImGuiSliderFlags flags = 0);
IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d", const char* format_max = NULL, ImGuiSliderFlags flags = 0); IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d", const char* format_max = NULL, ImGuiSliderFlags flags = 0);
IMGUI_API bool DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed = 1.0f, const void* p_min = NULL, const void* p_max = NULL, const char* format = NULL, ImGuiSliderFlags flags = 0); IMGUI_API bool DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min = NULL, const void* p_max = NULL, const char* format = NULL, ImGuiSliderFlags flags = 0);
IMGUI_API bool DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed = 1.0f, const void* p_min = NULL, const void* p_max = NULL, const char* format = NULL, ImGuiSliderFlags flags = 0); IMGUI_API bool DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min = NULL, const void* p_max = NULL, const char* format = NULL, ImGuiSliderFlags flags = 0);
// Widgets: Regular Sliders // Widgets: Regular Sliders
// - CTRL+Click on any slider to turn them into an input box. Manually input values aren't clamped and can go off-bounds. // - CTRL+Click on any slider to turn them into an input box. Manually input values aren't clamped and can go off-bounds.
@ -629,14 +614,13 @@ namespace ImGui
// - Use BeginMenuBar() on a window ImGuiWindowFlags_MenuBar to append to its menu bar. // - Use BeginMenuBar() on a window ImGuiWindowFlags_MenuBar to append to its menu bar.
// - Use BeginMainMenuBar() to create a menu bar at the top of the screen and append to it. // - Use BeginMainMenuBar() to create a menu bar at the top of the screen and append to it.
// - Use BeginMenu() to create a menu. You can call BeginMenu() multiple time with the same identifier to append more items to it. // - Use BeginMenu() to create a menu. You can call BeginMenu() multiple time with the same identifier to append more items to it.
// - Not that MenuItem() keyboardshortcuts are displayed as a convenience but _not processed_ by Dear ImGui at the moment.
IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set on parent window). IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set on parent window).
IMGUI_API void EndMenuBar(); // only call EndMenuBar() if BeginMenuBar() returns true! IMGUI_API void EndMenuBar(); // only call EndMenuBar() if BeginMenuBar() returns true!
IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar. IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar.
IMGUI_API void EndMainMenuBar(); // only call EndMainMenuBar() if BeginMainMenuBar() returns true! IMGUI_API void EndMainMenuBar(); // only call EndMainMenuBar() if BeginMainMenuBar() returns true!
IMGUI_API bool BeginMenu(const char* label, bool enabled = true); // create a sub-menu entry. only call EndMenu() if this returns true! IMGUI_API bool BeginMenu(const char* label, bool enabled = true); // create a sub-menu entry. only call EndMenu() if this returns true!
IMGUI_API void EndMenu(); // only call EndMenu() if BeginMenu() returns true! IMGUI_API void EndMenu(); // only call EndMenu() if BeginMenu() returns true!
IMGUI_API bool MenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true); // return true when activated. IMGUI_API bool MenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true); // return true when activated. shortcuts are displayed for convenience but not processed by ImGui at the moment
IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL
// Tooltips // Tooltips
@ -666,20 +650,18 @@ namespace ImGui
// - CloseCurrentPopup(): use inside the BeginPopup()/EndPopup() scope to close manually. // - CloseCurrentPopup(): use inside the BeginPopup()/EndPopup() scope to close manually.
// - CloseCurrentPopup() is called by default by Selectable()/MenuItem() when activated (FIXME: need some options). // - CloseCurrentPopup() is called by default by Selectable()/MenuItem() when activated (FIXME: need some options).
// - Use ImGuiPopupFlags_NoOpenOverExistingPopup to avoid opening a popup if there's already one at the same level. This is equivalent to e.g. testing for !IsAnyPopupOpen() prior to OpenPopup(). // - Use ImGuiPopupFlags_NoOpenOverExistingPopup to avoid opening a popup if there's already one at the same level. This is equivalent to e.g. testing for !IsAnyPopupOpen() prior to OpenPopup().
// - Use IsWindowAppearing() after BeginPopup() to tell if a window just opened.
IMGUI_API void OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags = 0); // call to mark popup as open (don't call every frame!). IMGUI_API void OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags = 0); // call to mark popup as open (don't call every frame!).
IMGUI_API void OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags = 0); // id overload to facilitate calling from nested stacks IMGUI_API void OpenPopupOnItemClick(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // helper to open popup when clicked on last item. return true when just opened. (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors)
IMGUI_API void OpenPopupOnItemClick(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // helper to open popup when clicked on last item. Default to ImGuiPopupFlags_MouseButtonRight == 1. (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors)
IMGUI_API void CloseCurrentPopup(); // manually close the popup we have begin-ed into. IMGUI_API void CloseCurrentPopup(); // manually close the popup we have begin-ed into.
// Popups: open+begin combined functions helpers // Popups: open+begin combined functions helpers
// - Helpers to do OpenPopup+BeginPopup where the Open action is triggered by e.g. hovering an item and right-clicking. // - Helpers to do OpenPopup+BeginPopup where the Open action is triggered by e.g. hovering an item and right-clicking.
// - They are convenient to easily create context menus, hence the name. // - They are convenient to easily create context menus, hence the name.
// - IMPORTANT: Notice that BeginPopupContextXXX takes ImGuiPopupFlags just like OpenPopup() and unlike BeginPopup(). For full consistency, we may add ImGuiWindowFlags to the BeginPopupContextXXX functions in the future. // - IMPORTANT: Notice that BeginPopupContextXXX takes ImGuiPopupFlags just like OpenPopup() and unlike BeginPopup(). For full consistency, we may add ImGuiWindowFlags to the BeginPopupContextXXX functions in the future.
// - IMPORTANT: we exceptionally default their flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter, so if you add other flags remember to re-add the ImGuiPopupFlags_MouseButtonRight. // - IMPORTANT: we exceptionally default their flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter, so if you add other flags remember to re-add the ImGuiPopupFlags_MouseButtonRight.
IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked on last item. Use str_id==NULL to associate the popup to previous item. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp! IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp!
IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1);// open+begin popup when clicked on current window. IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1);// open+begin popup when clicked on current window.
IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked in void (where there are no windows). IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked in void (where there are no windows).
// Popups: query functions // Popups: test function
// - IsPopupOpen(): return true if the popup is open at the current BeginPopup() level of the popup stack. // - IsPopupOpen(): return true if the popup is open at the current BeginPopup() level of the popup stack.
// - IsPopupOpen() with ImGuiPopupFlags_AnyPopupId: return true if any popup is open at the current BeginPopup() level of the popup stack. // - IsPopupOpen() with ImGuiPopupFlags_AnyPopupId: return true if any popup is open at the current BeginPopup() level of the popup stack.
// - IsPopupOpen() with ImGuiPopupFlags_AnyPopupId + ImGuiPopupFlags_AnyPopupLevel: return true if any popup is open. // - IsPopupOpen() with ImGuiPopupFlags_AnyPopupId + ImGuiPopupFlags_AnyPopupLevel: return true if any popup is open.
@ -741,7 +723,6 @@ namespace ImGui
IMGUI_API int TableGetRowIndex(); // return current row index. IMGUI_API int TableGetRowIndex(); // return current row index.
IMGUI_API const char* TableGetColumnName(int column_n = -1); // return "" if column didn't have a name declared by TableSetupColumn(). Pass -1 to use current column. IMGUI_API const char* TableGetColumnName(int column_n = -1); // return "" if column didn't have a name declared by TableSetupColumn(). Pass -1 to use current column.
IMGUI_API ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1); // return column flags so you can query their Enabled/Visible/Sorted/Hovered status flags. Pass -1 to use current column. IMGUI_API ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1); // return column flags so you can query their Enabled/Visible/Sorted/Hovered status flags. Pass -1 to use current column.
IMGUI_API void TableSetColumnEnabled(int column_n, bool v);// change enabled/disabled state of a column, set to false to hide the column. Note that end-user can use the context menu to change this themselves (right-click in headers, or right-click in columns body with ImGuiTableFlags_ContextMenuInBody)
IMGUI_API void TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n = -1); // change the color of a cell, row, or column. See ImGuiTableBgTarget_ flags for details. IMGUI_API void TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n = -1); // change the color of a cell, row, or column. See ImGuiTableBgTarget_ flags for details.
// Legacy Columns API (2020: prefer using Tables!) // Legacy Columns API (2020: prefer using Tables!)
@ -796,7 +777,7 @@ namespace ImGui
IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of a window. IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of a window.
IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget.
// Item/Widgets Utilities and Query Functions // Item/Widgets Utilities
// - Most of the functions are referring to the previous Item that has been submitted. // - Most of the functions are referring to the previous Item that has been submitted.
// - See Demo Window under "Widgets->Querying Status" for an interactive visualization of most of those functions. // - See Demo Window under "Widgets->Querying Status" for an interactive visualization of most of those functions.
IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered? (and usable, aka not blocked by a popup, etc.). See ImGuiHoveredFlags for more options. IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered? (and usable, aka not blocked by a popup, etc.). See ImGuiHoveredFlags for more options.
@ -821,7 +802,7 @@ namespace ImGui
// - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows. // - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows.
// - In 'docking' branch with multi-viewport enabled, we extend this concept to have multiple active viewports. // - In 'docking' branch with multi-viewport enabled, we extend this concept to have multiple active viewports.
// - In the future we will extend this concept further to also represent Platform Monitor and support a "no main platform window" operation mode. // - In the future we will extend this concept further to also represent Platform Monitor and support a "no main platform window" operation mode.
IMGUI_API ImGuiViewport* GetMainViewport(); // return primary/default viewport. This can never be NULL. IMGUI_API ImGuiViewport* GetMainViewport(); // return primary/default viewport.
// Miscellaneous Utilities // Miscellaneous Utilities
IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped.
@ -891,7 +872,6 @@ namespace ImGui
IMGUI_API const char* SaveIniSettingsToMemory(size_t* out_ini_size = NULL); // return a zero-terminated string with the .ini data which you can save by your own mean. call when io.WantSaveIniSettings is set, then save data by your own mean and clear io.WantSaveIniSettings. IMGUI_API const char* SaveIniSettingsToMemory(size_t* out_ini_size = NULL); // return a zero-terminated string with the .ini data which you can save by your own mean. call when io.WantSaveIniSettings is set, then save data by your own mean and clear io.WantSaveIniSettings.
// Debug Utilities // Debug Utilities
// - This is used by the IMGUI_CHECKVERSION() macro.
IMGUI_API bool DebugCheckVersionAndDataLayout(const char* version_str, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_drawvert, size_t sz_drawidx); // This is called by IMGUI_CHECKVERSION() macro. IMGUI_API bool DebugCheckVersionAndDataLayout(const char* version_str, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_drawvert, size_t sz_drawidx); // This is called by IMGUI_CHECKVERSION() macro.
// Memory Allocators // Memory Allocators
@ -972,7 +952,10 @@ enum ImGuiInputTextFlags_
ImGuiInputTextFlags_NoUndoRedo = 1 << 16, // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID(). ImGuiInputTextFlags_NoUndoRedo = 1 << 16, // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID().
ImGuiInputTextFlags_CharsScientific = 1 << 17, // Allow 0123456789.+-*/eE (Scientific notation input) ImGuiInputTextFlags_CharsScientific = 1 << 17, // Allow 0123456789.+-*/eE (Scientific notation input)
ImGuiInputTextFlags_CallbackResize = 1 << 18, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this) ImGuiInputTextFlags_CallbackResize = 1 << 18, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this)
ImGuiInputTextFlags_CallbackEdit = 1 << 19 // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active) ImGuiInputTextFlags_CallbackEdit = 1 << 19, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active)
// [Internal]
ImGuiInputTextFlags_Multiline = 1 << 20, // For internal use by InputTextMultiline()
ImGuiInputTextFlags_NoMarkEdited = 1 << 21 // For internal use by functions using InputText() before reformatting data
// Obsolete names (will be removed soon) // Obsolete names (will be removed soon)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
@ -1648,7 +1631,6 @@ template<typename T> void IM_DELETE(T* p) { if (p) { p->~T(); ImGui::MemFree(p
// Do NOT use this class as a std::vector replacement in your own code! Many of the structures used by dear imgui can be safely initialized by a zero-memset. // Do NOT use this class as a std::vector replacement in your own code! Many of the structures used by dear imgui can be safely initialized by a zero-memset.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
IM_MSVC_RUNTIME_CHECKS_OFF
template<typename T> template<typename T>
struct ImVector struct ImVector
{ {
@ -1707,7 +1689,6 @@ struct ImVector
inline bool find_erase_unsorted(const T& v) { const T* it = find(v); if (it < Data + Size) { erase_unsorted(it); return true; } return false; } inline bool find_erase_unsorted(const T& v) { const T* it = find(v); if (it < Data + Size) { erase_unsorted(it); return true; } return false; }
inline int index_from_ptr(const T* it) const { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; return (int)off; } inline int index_from_ptr(const T* it) const { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; return (int)off; }
}; };
IM_MSVC_RUNTIME_CHECKS_RESTORE
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] ImGuiStyle // [SECTION] ImGuiStyle
@ -1864,7 +1845,7 @@ struct ImGuiIO
bool WantSaveIniSettings; // When manual .ini load/save is active (io.IniFilename == NULL), this will be set to notify your application that you can call SaveIniSettingsToMemory() and save yourself. Important: clear io.WantSaveIniSettings yourself after saving! bool WantSaveIniSettings; // When manual .ini load/save is active (io.IniFilename == NULL), this will be set to notify your application that you can call SaveIniSettingsToMemory() and save yourself. Important: clear io.WantSaveIniSettings yourself after saving!
bool NavActive; // Keyboard/Gamepad navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag. bool NavActive; // Keyboard/Gamepad navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag.
bool NavVisible; // Keyboard/Gamepad navigation is visible and allowed (will handle ImGuiKey_NavXXX events). bool NavVisible; // Keyboard/Gamepad navigation is visible and allowed (will handle ImGuiKey_NavXXX events).
float Framerate; // Rough estimate of application framerate, in frame per second. Solely for convenience. Rolling average estimation based on io.DeltaTime over 120 frames. float Framerate; // Application framerate estimate, in frame per second. Solely for convenience. Rolling average estimation based on io.DeltaTime over 120 frames.
int MetricsRenderVertices; // Vertices output during last call to Render() int MetricsRenderVertices; // Vertices output during last call to Render()
int MetricsRenderIndices; // Indices output during last call to Render() = number of triangles * 3 int MetricsRenderIndices; // Indices output during last call to Render() = number of triangles * 3
int MetricsRenderWindows; // Number of visible windows int MetricsRenderWindows; // Number of visible windows
@ -2243,9 +2224,6 @@ struct ImDrawCmd
void* UserCallbackData; // 4-8 // The draw callback code can access this. void* UserCallbackData; // 4-8 // The draw callback code can access this.
ImDrawCmd() { memset(this, 0, sizeof(*this)); } // Also ensure our padding fields are zeroed ImDrawCmd() { memset(this, 0, sizeof(*this)); } // Also ensure our padding fields are zeroed
// Since 1.83: returns ImTextureID associated with this draw call. Warning: DO NOT assume this is always same as 'TextureId' (we will change this function for an upcoming feature)
inline ImTextureID GetTexID() const { return TextureId; }
}; };
// Vertex index, default to 16-bit // Vertex index, default to 16-bit
@ -2840,10 +2818,6 @@ enum ImDrawCornerFlags_
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
#ifdef _MSC_VER
#pragma warning (pop)
#endif
// Include imgui_user.h at the end of imgui.h (convenient for user to only explicitly include vanilla imgui.h) // Include imgui_user.h at the end of imgui.h (convenient for user to only explicitly include vanilla imgui.h)
#ifdef IMGUI_INCLUDE_IMGUI_USER_H #ifdef IMGUI_INCLUDE_IMGUI_USER_H
#include "imgui_user.h" #include "imgui_user.h"

View File

@ -1,4 +1,4 @@
// dear imgui, v1.83 // dear imgui, v1.82 WIP
// (demo code) // (demo code)
// Help: // Help:
@ -6,9 +6,9 @@
// - Newcomers, read 'Programmer guide' in imgui.cpp for notes on how to setup Dear ImGui in your codebase. // - Newcomers, read 'Programmer guide' in imgui.cpp for notes on how to setup Dear ImGui in your codebase.
// - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp. All applications in examples/ are doing that. // - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp. All applications in examples/ are doing that.
// Read imgui.cpp for more details, documentation and comments. // Read imgui.cpp for more details, documentation and comments.
// Get the latest version at https://github.com/ocornut/imgui // Get latest version at https://github.com/ocornut/imgui
// Message to the person tempted to delete this file when integrating Dear ImGui into their codebase: // Message to the person tempted to delete this file when integrating Dear ImGui into their code base:
// Do NOT remove this file from your project! Think again! It is the most useful reference code that you and other // Do NOT remove this file from your project! Think again! It is the most useful reference code that you and other
// coders will want to refer to and call. Have the ImGui::ShowDemoWindow() function wired in an always-available // coders will want to refer to and call. Have the ImGui::ShowDemoWindow() function wired in an always-available
// debug menu of your game/app! Removing this file from your project is hindering access to documentation for everyone // debug menu of your game/app! Removing this file from your project is hindering access to documentation for everyone
@ -16,19 +16,19 @@
// Everything in this file will be stripped out by the linker if you don't call ImGui::ShowDemoWindow(). // Everything in this file will be stripped out by the linker if you don't call ImGui::ShowDemoWindow().
// If you want to link core Dear ImGui in your shipped builds but want a thorough guarantee that the demo will not be // If you want to link core Dear ImGui in your shipped builds but want a thorough guarantee that the demo will not be
// linked, you can setup your imconfig.h with #define IMGUI_DISABLE_DEMO_WINDOWS and those functions will be empty. // linked, you can setup your imconfig.h with #define IMGUI_DISABLE_DEMO_WINDOWS and those functions will be empty.
// In another situation, whenever you have Dear ImGui available you probably want this to be available for reference. // In other situation, whenever you have Dear ImGui available you probably want this to be available for reference.
// Thank you, // Thank you,
// -Your beloved friend, imgui_demo.cpp (which you won't delete) // -Your beloved friend, imgui_demo.cpp (which you won't delete)
// Message to beginner C/C++ programmers about the meaning of the 'static' keyword: // Message to beginner C/C++ programmers about the meaning of the 'static' keyword:
// In this demo code, we frequently use 'static' variables inside functions. A static variable persists across calls, // In this demo code, we frequently we use 'static' variables inside functions. A static variable persist across calls,
// so it is essentially like a global variable but declared inside the scope of the function. We do this as a way to // so it is essentially like a global variable but declared inside the scope of the function. We do this as a way to
// gather code and data in the same place, to make the demo source code faster to read, faster to write, and smaller // gather code and data in the same place, to make the demo source code faster to read, faster to write, and smaller
// in size. It also happens to be a convenient way of storing simple UI related information as long as your function // in size. It also happens to be a convenient way of storing simple UI related information as long as your function
// doesn't need to be reentrant or used in multiple threads. This might be a pattern you will want to use in your code, // doesn't need to be reentrant or used in multiple threads. This might be a pattern you will want to use in your code,
// but most of the real data you would be editing is likely going to be stored outside your functions. // but most of the real data you would be editing is likely going to be stored outside your functions.
// The Demo code in this file is designed to be easy to copy-and-paste into your application! // The Demo code in this file is designed to be easy to copy-and-paste in into your application!
// Because of this: // Because of this:
// - We never omit the ImGui:: prefix when calling functions, even though most code here is in the same namespace. // - We never omit the ImGui:: prefix when calling functions, even though most code here is in the same namespace.
// - We try to declare static variables in the local scope, as close as possible to the code using them. // - We try to declare static variables in the local scope, as close as possible to the code using them.
@ -54,7 +54,6 @@ Index of this file:
// - sub section: ShowDemoWindowTables() // - sub section: ShowDemoWindowTables()
// - sub section: ShowDemoWindowMisc() // - sub section: ShowDemoWindowMisc()
// [SECTION] About Window / ShowAboutWindow() // [SECTION] About Window / ShowAboutWindow()
// [SECTION] Font Viewer / ShowFontAtlas()
// [SECTION] Style Editor / ShowStyleEditor() // [SECTION] Style Editor / ShowStyleEditor()
// [SECTION] Example App: Main Menu Bar / ShowExampleAppMainMenuBar() // [SECTION] Example App: Main Menu Bar / ShowExampleAppMainMenuBar()
// [SECTION] Example App: Debug Console / ShowExampleAppConsole() // [SECTION] Example App: Debug Console / ShowExampleAppConsole()
@ -93,8 +92,7 @@ Index of this file:
// Visual Studio warnings // Visual Studio warnings
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen #pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2).
#endif #endif
// Clang/GCC warnings with -Weverything // Clang/GCC warnings with -Weverything
@ -1274,6 +1272,7 @@ static void ShowDemoWindowWidgets()
static ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput; static ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput;
HelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp because we don't want to include <string> in here)"); HelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp because we don't want to include <string> in here)");
ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly); ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly);
ImGui::CheckboxFlags("ImGuiInputTextFlags_AlwaysOverwrite", &flags, ImGuiInputTextFlags_AlwaysOverwrite);
ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", &flags, ImGuiInputTextFlags_AllowTabInput); ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", &flags, ImGuiInputTextFlags_AllowTabInput);
ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", &flags, ImGuiInputTextFlags_CtrlEnterForNewLine); ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", &flags, ImGuiInputTextFlags_CtrlEnterForNewLine);
ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16), flags); ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16), flags);
@ -1555,7 +1554,7 @@ static void ShowDemoWindowWidgets()
// Plot/Graph widgets are not very good. // Plot/Graph widgets are not very good.
// Consider writing your own, or using a third-party one, see: // Consider writing your own, or using a third-party one, see:
// - ImPlot https://github.com/epezent/implot // - ImPlot https://github.com/epezent/implot
// - others https://github.com/ocornut/imgui/wiki/Useful-Extensions // - others https://github.com/ocornut/imgui/wiki/Useful-Widgets
if (ImGui::TreeNode("Plots Widgets")) if (ImGui::TreeNode("Plots Widgets"))
{ {
static bool animate = true; static bool animate = true;
@ -1604,7 +1603,7 @@ static void ShowDemoWindowWidgets()
}; };
static int func_type = 0, display_count = 70; static int func_type = 0, display_count = 70;
ImGui::Separator(); ImGui::Separator();
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8); ImGui::SetNextItemWidth(100);
ImGui::Combo("func", &func_type, "Sin\0Saw\0"); ImGui::Combo("func", &func_type, "Sin\0Saw\0");
ImGui::SameLine(); ImGui::SameLine();
ImGui::SliderInt("Sample count", &display_count, 1, 400); ImGui::SliderInt("Sample count", &display_count, 1, 400);
@ -2394,7 +2393,7 @@ static void ShowDemoWindowLayout()
// the POV of the parent window). See 'Demo->Querying Status (Active/Focused/Hovered etc.)' for details. // the POV of the parent window). See 'Demo->Querying Status (Active/Focused/Hovered etc.)' for details.
{ {
static int offset_x = 0; static int offset_x = 0;
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8); ImGui::SetNextItemWidth(100);
ImGui::DragInt("Offset X", &offset_x, 1.0f, -1000, 1000); ImGui::DragInt("Offset X", &offset_x, 1.0f, -1000, 1000);
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (float)offset_x); ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (float)offset_x);
@ -2416,15 +2415,15 @@ static void ShowDemoWindowLayout()
if (ImGui::TreeNode("Widgets Width")) if (ImGui::TreeNode("Widgets Width"))
{ {
static float f = 0.0f;
static bool show_indented_items = true;
ImGui::Checkbox("Show indented items", &show_indented_items);
// Use SetNextItemWidth() to set the width of a single upcoming item. // Use SetNextItemWidth() to set the width of a single upcoming item.
// Use PushItemWidth()/PopItemWidth() to set the width of a group of items. // Use PushItemWidth()/PopItemWidth() to set the width of a group of items.
// In real code use you'll probably want to choose width values that are proportional to your font size // In real code use you'll probably want to choose width values that are proportional to your font size
// e.g. Using '20.0f * GetFontSize()' as width instead of '200.0f', etc. // e.g. Using '20.0f * GetFontSize()' as width instead of '200.0f', etc.
static float f = 0.0f;
static bool show_indented_items = true;
ImGui::Checkbox("Show indented items", &show_indented_items);
ImGui::Text("SetNextItemWidth/PushItemWidth(100)"); ImGui::Text("SetNextItemWidth/PushItemWidth(100)");
ImGui::SameLine(); HelpMarker("Fixed width."); ImGui::SameLine(); HelpMarker("Fixed width.");
ImGui::PushItemWidth(100); ImGui::PushItemWidth(100);
@ -2840,8 +2839,6 @@ static void ShowDemoWindowLayout()
{ {
for (int item = 0; item < 100; item++) for (int item = 0; item < 100; item++)
{ {
if (item > 0)
ImGui::SameLine();
if (enable_track && item == track_item) if (enable_track && item == track_item)
{ {
ImGui::TextColored(ImVec4(1, 1, 0, 1), "Item %d", item); ImGui::TextColored(ImVec4(1, 1, 0, 1), "Item %d", item);
@ -2851,6 +2848,7 @@ static void ShowDemoWindowLayout()
{ {
ImGui::Text("Item %d", item); ImGui::Text("Item %d", item);
} }
ImGui::SameLine();
} }
} }
float scroll_x = ImGui::GetScrollX(); float scroll_x = ImGui::GetScrollX();
@ -3194,84 +3192,46 @@ static void ShowDemoWindowPopups()
if (ImGui::TreeNode("Context menus")) if (ImGui::TreeNode("Context menus"))
{ {
HelpMarker("\"Context\" functions are simple helpers to associate a Popup to a given Item or Window identifier.");
// BeginPopupContextItem() is a helper to provide common/simple popup behavior of essentially doing: // BeginPopupContextItem() is a helper to provide common/simple popup behavior of essentially doing:
// if (id == 0) // if (IsItemHovered() && IsMouseReleased(ImGuiMouseButton_Right))
// id = GetItemID(); // Use last item id // OpenPopup(id);
// if (IsItemHovered() && IsMouseReleased(ImGuiMouseButton_Right)) // return BeginPopup(id);
// OpenPopup(id); // For more advanced uses you may want to replicate and customize this code.
// return BeginPopup(id); // See details in BeginPopupContextItem().
// For advanced advanced uses you may want to replicate and customize this code. static float value = 0.5f;
// See more details in BeginPopupContextItem(). ImGui::Text("Value = %.3f (<-- right-click here)", value);
if (ImGui::BeginPopupContextItem("item context menu"))
// Example 1
// When used after an item that has an ID (e.g. Button), we can skip providing an ID to BeginPopupContextItem(),
// and BeginPopupContextItem() will use the last item ID as the popup ID.
{ {
const char* names[5] = { "Label1", "Label2", "Label3", "Label4", "Label5" }; if (ImGui::Selectable("Set to zero")) value = 0.0f;
for (int n = 0; n < 5; n++) if (ImGui::Selectable("Set to PI")) value = 3.1415f;
{ ImGui::SetNextItemWidth(-FLT_MIN);
ImGui::Selectable(names[n]); ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f);
if (ImGui::BeginPopupContextItem()) // <-- use last item id as popup id ImGui::EndPopup();
{
ImGui::Text("This a popup for \"%s\"!", names[n]);
if (ImGui::Button("Close"))
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
}
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Right-click to open popup");
}
} }
// Example 2 // We can also use OpenPopupOnItemClick() which is the same as BeginPopupContextItem() but without the
// Popup on a Text() element which doesn't have an identifier: we need to provide an identifier to BeginPopupContextItem(). // Begin() call. So here we will make it that clicking on the text field with the right mouse button (1)
// Using an explicit identifier is also convenient if you want to activate the popups from different locations. // will toggle the visibility of the popup above.
ImGui::Text("(You can also right-click me to open the same popup as above.)");
ImGui::OpenPopupOnItemClick("item context menu", 1);
// When used after an item that has an ID (e.g.Button), we can skip providing an ID to BeginPopupContextItem().
// BeginPopupContextItem() will use the last item ID as the popup ID.
// In addition here, we want to include your editable label inside the button label.
// We use the ### operator to override the ID (read FAQ about ID for details)
static char name[32] = "Label1";
char buf[64];
sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label
ImGui::Button(buf);
if (ImGui::BeginPopupContextItem())
{ {
HelpMarker("Text() elements don't have stable identifiers so we need to provide one."); ImGui::Text("Edit name:");
static float value = 0.5f; ImGui::InputText("##edit", name, IM_ARRAYSIZE(name));
ImGui::Text("Value = %.3f <-- (1) right-click this value", value); if (ImGui::Button("Close"))
if (ImGui::BeginPopupContextItem("my popup")) ImGui::CloseCurrentPopup();
{ ImGui::EndPopup();
if (ImGui::Selectable("Set to zero")) value = 0.0f;
if (ImGui::Selectable("Set to PI")) value = 3.1415f;
ImGui::SetNextItemWidth(-FLT_MIN);
ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f);
ImGui::EndPopup();
}
// We can also use OpenPopupOnItemClick() to toggle the visibility of a given popup.
// Here we make it that right-clicking this other text element opens the same popup as above.
// The popup itself will be submitted by the code above.
ImGui::Text("(2) Or right-click this text");
ImGui::OpenPopupOnItemClick("my popup", ImGuiPopupFlags_MouseButtonRight);
// Back to square one: manually open the same popup.
if (ImGui::Button("(3) Or click this button"))
ImGui::OpenPopup("my popup");
}
// Example 3
// When using BeginPopupContextItem() with an implicit identifier (NULL == use last item ID),
// we need to make sure your item identifier is stable.
// In this example we showcase altering the item label while preserving its identifier, using the ### operator (see FAQ).
{
HelpMarker("Showcase using a popup ID linked to item ID, with the item having a changing label + stable ID using the ### operator.");
static char name[32] = "Label1";
char buf[64];
sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label
ImGui::Button(buf);
if (ImGui::BeginPopupContextItem())
{
ImGui::Text("Edit name:");
ImGui::InputText("##edit", name, IM_ARRAYSIZE(name));
if (ImGui::Button("Close"))
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
}
ImGui::SameLine(); ImGui::Text("(<-- right-click here)");
} }
ImGui::SameLine(); ImGui::Text("(<-- right-click here)");
ImGui::TreePop(); ImGui::TreePop();
} }
@ -5502,7 +5462,7 @@ static void ShowDemoWindowMisc()
ImGui::InputText("3", buf, IM_ARRAYSIZE(buf)); ImGui::InputText("3", buf, IM_ARRAYSIZE(buf));
ImGui::PushAllowKeyboardFocus(false); ImGui::PushAllowKeyboardFocus(false);
ImGui::InputText("4 (tab skip)", buf, IM_ARRAYSIZE(buf)); ImGui::InputText("4 (tab skip)", buf, IM_ARRAYSIZE(buf));
ImGui::SameLine(); HelpMarker("Item won't be cycled through when using TAB or Shift+Tab."); //ImGui::SameLine(); HelpMarker("Use ImGui::PushAllowKeyboardFocus(bool) to disable tabbing through certain widgets.");
ImGui::PopAllowKeyboardFocus(); ImGui::PopAllowKeyboardFocus();
ImGui::InputText("5", buf, IM_ARRAYSIZE(buf)); ImGui::InputText("5", buf, IM_ARRAYSIZE(buf));
ImGui::TreePop(); ImGui::TreePop();
@ -5528,7 +5488,6 @@ static void ShowDemoWindowMisc()
if (focus_3) ImGui::SetKeyboardFocusHere(); if (focus_3) ImGui::SetKeyboardFocusHere();
ImGui::InputText("3 (tab skip)", buf, IM_ARRAYSIZE(buf)); ImGui::InputText("3 (tab skip)", buf, IM_ARRAYSIZE(buf));
if (ImGui::IsItemActive()) has_focus = 3; if (ImGui::IsItemActive()) has_focus = 3;
ImGui::SameLine(); HelpMarker("Item won't be cycled through when using TAB or Shift+Tab.");
ImGui::PopAllowKeyboardFocus(); ImGui::PopAllowKeyboardFocus();
if (has_focus) if (has_focus)
@ -5744,15 +5703,31 @@ void ImGui::ShowAboutWindow(bool* p_open)
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] Font viewer / ShowFontAtlas() // [SECTION] Style Editor / ShowStyleEditor()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// - ShowStyleSelector()
// - ShowFontSelector() // - ShowFontSelector()
// - ShowFont() // - ShowStyleEditor()
// - ShowFontAtlas()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// This isn't worth putting in public API but we want Metrics to use it // Demo helper function to select among default colors. See ShowStyleEditor() for more advanced options.
namespace ImGui { void ShowFontAtlas(ImFontAtlas* atlas); } // Here we use the simplified Combo() api that packs items into a single literal string.
// Useful for quick combo boxes where the choices are known locally.
bool ImGui::ShowStyleSelector(const char* label)
{
static int style_idx = -1;
if (ImGui::Combo(label, &style_idx, "Dark\0Light\0Classic\0"))
{
switch (style_idx)
{
case 0: ImGui::StyleColorsDark(); break;
case 1: ImGui::StyleColorsLight(); break;
case 2: ImGui::StyleColorsClassic(); break;
}
return true;
}
return false;
}
// Demo helper function to select among loaded fonts. // Demo helper function to select among loaded fonts.
// Here we use the regular BeginCombo()/EndCombo() api which is more the more flexible one. // Here we use the regular BeginCombo()/EndCombo() api which is more the more flexible one.
@ -5781,7 +5756,7 @@ void ImGui::ShowFontSelector(const char* label)
} }
// [Internal] Display details for a single font, called by ShowStyleEditor(). // [Internal] Display details for a single font, called by ShowStyleEditor().
static void ShowFont(ImFont* font) static void NodeFont(ImFont* font)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGuiStyle& style = ImGui::GetStyle(); ImGuiStyle& style = ImGui::GetStyle();
@ -5791,13 +5766,9 @@ static void ShowFont(ImFont* font)
if (!font_details_opened) if (!font_details_opened)
return; return;
// Display preview text
ImGui::PushFont(font); ImGui::PushFont(font);
ImGui::Text("The quick brown fox jumps over the lazy dog"); ImGui::Text("The quick brown fox jumps over the lazy dog");
ImGui::PopFont(); ImGui::PopFont();
// Display details
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
ImGui::DragFloat("Font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f"); // Scale only this font ImGui::DragFloat("Font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f"); // Scale only this font
ImGui::SameLine(); HelpMarker( ImGui::SameLine(); HelpMarker(
"Note than the default embedded font is NOT meant to be scaled.\n\n" "Note than the default embedded font is NOT meant to be scaled.\n\n"
@ -5815,10 +5786,9 @@ static void ShowFont(ImFont* font)
if (const ImFontConfig* cfg = &font->ConfigData[config_i]) if (const ImFontConfig* cfg = &font->ConfigData[config_i])
ImGui::BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d, Offset: (%.1f,%.1f)", ImGui::BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d, Offset: (%.1f,%.1f)",
config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH, cfg->GlyphOffset.x, cfg->GlyphOffset.y); config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH, cfg->GlyphOffset.x, cfg->GlyphOffset.y);
// Display all glyphs of the fonts in separate pages of 256 characters
if (ImGui::TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size)) if (ImGui::TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size))
{ {
// Display all glyphs of the fonts in separate pages of 256 characters
const ImU32 glyph_col = ImGui::GetColorU32(ImGuiCol_Text); const ImU32 glyph_col = ImGui::GetColorU32(ImGuiCol_Text);
for (unsigned int base = 0; base <= IM_UNICODE_CODEPOINT_MAX; base += 256) for (unsigned int base = 0; base <= IM_UNICODE_CODEPOINT_MAX; base += 256)
{ {
@ -5873,50 +5843,6 @@ static void ShowFont(ImFont* font)
ImGui::TreePop(); ImGui::TreePop();
} }
void ImGui::ShowFontAtlas(ImFontAtlas* atlas)
{
for (int i = 0; i < atlas->Fonts.Size; i++)
{
ImFont* font = atlas->Fonts[i];
ImGui::PushID(font);
ShowFont(font);
ImGui::PopID();
}
if (ImGui::TreeNode("Atlas texture", "Atlas texture (%dx%d pixels)", atlas->TexWidth, atlas->TexHeight))
{
ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
ImVec4 border_col = ImVec4(1.0f, 1.0f, 1.0f, 0.5f);
ImGui::Image(atlas->TexID, ImVec2((float)atlas->TexWidth, (float)atlas->TexHeight), ImVec2(0, 0), ImVec2(1, 1), tint_col, border_col);
ImGui::TreePop();
}
}
//-----------------------------------------------------------------------------
// [SECTION] Style Editor / ShowStyleEditor()
//-----------------------------------------------------------------------------
// - ShowStyleSelector()
// - ShowStyleEditor()
//-----------------------------------------------------------------------------
// Demo helper function to select among default colors. See ShowStyleEditor() for more advanced options.
// Here we use the simplified Combo() api that packs items into a single literal string.
// Useful for quick combo boxes where the choices are known locally.
bool ImGui::ShowStyleSelector(const char* label)
{
static int style_idx = -1;
if (ImGui::Combo(label, &style_idx, "Dark\0Light\0Classic\0"))
{
switch (style_idx)
{
case 0: ImGui::StyleColorsDark(); break;
case 1: ImGui::StyleColorsLight(); break;
case 2: ImGui::StyleColorsClassic(); break;
}
return true;
}
return false;
}
void ImGui::ShowStyleEditor(ImGuiStyle* ref) void ImGui::ShowStyleEditor(ImGuiStyle* ref)
{ {
// You can pass in a reference ImGuiStyle structure to compare to, revert to and save to // You can pass in a reference ImGuiStyle structure to compare to, revert to and save to
@ -6073,7 +5999,21 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImFontAtlas* atlas = io.Fonts; ImFontAtlas* atlas = io.Fonts;
HelpMarker("Read FAQ and docs/FONTS.md for details on font loading."); HelpMarker("Read FAQ and docs/FONTS.md for details on font loading.");
ImGui::ShowFontAtlas(atlas); ImGui::PushItemWidth(120);
for (int i = 0; i < atlas->Fonts.Size; i++)
{
ImFont* font = atlas->Fonts[i];
ImGui::PushID(font);
NodeFont(font);
ImGui::PopID();
}
if (ImGui::TreeNode("Atlas texture", "Atlas texture (%dx%d pixels)", atlas->TexWidth, atlas->TexHeight))
{
ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
ImVec4 border_col = ImVec4(1.0f, 1.0f, 1.0f, 0.5f);
ImGui::Image(atlas->TexID, ImVec2((float)atlas->TexWidth, (float)atlas->TexHeight), ImVec2(0, 0), ImVec2(1, 1), tint_col, border_col);
ImGui::TreePop();
}
// Post-baking font scaling. Note that this is NOT the nice way of scaling fonts, read below. // Post-baking font scaling. Note that this is NOT the nice way of scaling fonts, read below.
// (we enforce hard clamping manually as by default DragFloat/SliderFloat allows CTRL+Click text to get out of bounds). // (we enforce hard clamping manually as by default DragFloat/SliderFloat allows CTRL+Click text to get out of bounds).
@ -6085,7 +6025,6 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
"rebuild the font atlas, and call style.ScaleAllSizes() on a reference ImGuiStyle structure.\n" "rebuild the font atlas, and call style.ScaleAllSizes() on a reference ImGuiStyle structure.\n"
"Using those settings here will give you poor quality results."); "Using those settings here will give you poor quality results.");
static float window_scale = 1.0f; static float window_scale = 1.0f;
ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
if (ImGui::DragFloat("window scale", &window_scale, 0.005f, MIN_SCALE, MAX_SCALE, "%.2f", ImGuiSliderFlags_AlwaysClamp)) // Scale only this window if (ImGui::DragFloat("window scale", &window_scale, 0.005f, MIN_SCALE, MAX_SCALE, "%.2f", ImGuiSliderFlags_AlwaysClamp)) // Scale only this window
ImGui::SetWindowFontScale(window_scale); ImGui::SetWindowFontScale(window_scale);
ImGui::DragFloat("global scale", &io.FontGlobalScale, 0.005f, MIN_SCALE, MAX_SCALE, "%.2f", ImGuiSliderFlags_AlwaysClamp); // Scale everything ImGui::DragFloat("global scale", &io.FontGlobalScale, 0.005f, MIN_SCALE, MAX_SCALE, "%.2f", ImGuiSliderFlags_AlwaysClamp); // Scale everything
@ -6105,7 +6044,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
HelpMarker("Faster lines using texture data. Require backend to render with bilinear filtering (not point/nearest filtering)."); HelpMarker("Faster lines using texture data. Require backend to render with bilinear filtering (not point/nearest filtering).");
ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill); ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
ImGui::PushItemWidth(ImGui::GetFontSize() * 8); ImGui::PushItemWidth(100);
ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f, "%.2f"); ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f, "%.2f");
if (style.CurveTessellationTol < 0.10f) style.CurveTessellationTol = 0.10f; if (style.CurveTessellationTol < 0.10f) style.CurveTessellationTol = 0.10f;

View File

@ -1,4 +1,4 @@
// dear imgui, v1.83 // dear imgui, v1.82 WIP
// (drawing and font code) // (drawing and font code)
/* /*
@ -54,12 +54,9 @@ Index of this file:
// Visual Studio warnings // Visual Studio warnings
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning (disable: 4127) // condition expression is constant #pragma warning (disable: 4127) // condition expression is constant
#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff) #pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff)
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen #pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#pragma warning (disable: 6255) // [Static Analyzer] _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead.
#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2).
#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). [MSVC Static Analyzer)
#endif #endif
// Clang/GCC warnings with -Weverything // Clang/GCC warnings with -Weverything
@ -108,9 +105,6 @@ namespace IMGUI_STB_NAMESPACE
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning (push) #pragma warning (push)
#pragma warning (disable: 4456) // declaration of 'xx' hides previous local declaration #pragma warning (disable: 4456) // declaration of 'xx' hides previous local declaration
#pragma warning (disable: 6011) // (stb_rectpack) Dereferencing NULL pointer 'cur->next'.
#pragma warning (disable: 6385) // (stb_truetype) Reading invalid data from 'buffer': the readable size is '_Old_3`kernel_width' bytes, but '3' bytes may be read.
#pragma warning (disable: 28182) // (stb_rectpack) Dereferencing NULL pointer. 'cur' contains the same NULL value as 'cur->next' did.
#endif #endif
#if defined(__clang__) #if defined(__clang__)
@ -151,7 +145,7 @@ namespace IMGUI_STB_NAMESPACE
#define STBTT_sqrt(x) ImSqrt(x) #define STBTT_sqrt(x) ImSqrt(x)
#define STBTT_pow(x,y) ImPow(x,y) #define STBTT_pow(x,y) ImPow(x,y)
#define STBTT_fabs(x) ImFabs(x) #define STBTT_fabs(x) ImFabs(x)
#define STBTT_ifloor(x) ((int)ImFloorSigned(x)) #define STBTT_ifloor(x) ((int)ImFloorStd(x))
#define STBTT_iceil(x) ((int)ImCeil(x)) #define STBTT_iceil(x) ((int)ImCeil(x))
#define STBTT_STATIC #define STBTT_STATIC
#define STB_TRUETYPE_IMPLEMENTATION #define STB_TRUETYPE_IMPLEMENTATION
@ -694,9 +688,8 @@ void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, c
// On AddPolyline() and AddConvexPolyFilled() we intentionally avoid using ImVec2 and superfluous function calls to optimize debug/non-inlined builds. // On AddPolyline() and AddConvexPolyFilled() we intentionally avoid using ImVec2 and superfluous function calls to optimize debug/non-inlined builds.
// Those macros expects l-values. // Those macros expects l-values.
#define IM_NORMALIZE2F_OVER_ZERO(VX,VY) do { float d2 = VX*VX + VY*VY; if (d2 > 0.0f) { float inv_len = ImRsqrt(d2); VX *= inv_len; VY *= inv_len; } } while (0) #define IM_NORMALIZE2F_OVER_ZERO(VX,VY) do { float d2 = VX*VX + VY*VY; if (d2 > 0.0f) { float inv_len = 1.0f / ImSqrt(d2); VX *= inv_len; VY *= inv_len; } } while (0)
#define IM_FIXNORMAL2F_MAX_INVLEN2 100.0f // 500.0f (see #4053, #3366) #define IM_FIXNORMAL2F(VX,VY) do { float d2 = VX*VX + VY*VY; if (d2 < 0.5f) d2 = 0.5f; float inv_lensq = 1.0f / d2; VX *= inv_lensq; VY *= inv_lensq; } while (0)
#define IM_FIXNORMAL2F(VX,VY) do { float d2 = VX*VX + VY*VY; if (d2 > 0.000001f) { float inv_len2 = 1.0f / d2; if (inv_len2 > IM_FIXNORMAL2F_MAX_INVLEN2) inv_len2 = IM_FIXNORMAL2F_MAX_INVLEN2; VX *= inv_len2; VY *= inv_len2; } } while (0)
// TODO: Thickness anti-aliased lines cap are missing their AA fringe. // TODO: Thickness anti-aliased lines cap are missing their AA fringe.
// We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds. // We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds.
@ -1044,6 +1037,7 @@ void ImDrawList::_PathArcToFastEx(const ImVec2& center, float radius, int a_min_
_Path.push_back(center); _Path.push_back(center);
return; return;
} }
IM_ASSERT(a_min_sample <= a_max_sample);
// Calculate arc auto segment step size // Calculate arc auto segment step size
if (a_step <= 0) if (a_step <= 0)
@ -1052,7 +1046,17 @@ void ImDrawList::_PathArcToFastEx(const ImVec2& center, float radius, int a_min_
// Make sure we never do steps larger than one quarter of the circle // Make sure we never do steps larger than one quarter of the circle
a_step = ImClamp(a_step, 1, IM_DRAWLIST_ARCFAST_TABLE_SIZE / 4); a_step = ImClamp(a_step, 1, IM_DRAWLIST_ARCFAST_TABLE_SIZE / 4);
const int sample_range = ImAbs(a_max_sample - a_min_sample); // Normalize a_min_sample to always start lie in [0..IM_DRAWLIST_ARCFAST_SAMPLE_MAX] range.
if (a_min_sample < 0)
{
int normalized_sample = a_min_sample % IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
if (normalized_sample < 0)
normalized_sample += IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
a_max_sample += (normalized_sample - a_min_sample);
a_min_sample = normalized_sample;
}
const int sample_range = a_max_sample - a_min_sample;
const int a_next_step = a_step; const int a_next_step = a_step;
int samples = sample_range + 1; int samples = sample_range + 1;
@ -1078,40 +1082,16 @@ void ImDrawList::_PathArcToFastEx(const ImVec2& center, float radius, int a_min_
ImVec2* out_ptr = _Path.Data + (_Path.Size - samples); ImVec2* out_ptr = _Path.Data + (_Path.Size - samples);
int sample_index = a_min_sample; int sample_index = a_min_sample;
if (sample_index < 0 || sample_index >= IM_DRAWLIST_ARCFAST_SAMPLE_MAX) for (int a = a_min_sample; a <= a_max_sample; a += a_step, sample_index += a_step, a_step = a_next_step)
{ {
sample_index = sample_index % IM_DRAWLIST_ARCFAST_SAMPLE_MAX; // a_step is clamped to IM_DRAWLIST_ARCFAST_SAMPLE_MAX, so we have guaranteed that it will not wrap over range twice or more
if (sample_index < 0) if (sample_index >= IM_DRAWLIST_ARCFAST_SAMPLE_MAX)
sample_index += IM_DRAWLIST_ARCFAST_SAMPLE_MAX; sample_index -= IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
}
if (a_max_sample >= a_min_sample) const ImVec2 s = _Data->ArcFastVtx[sample_index];
{ out_ptr->x = center.x + s.x * radius;
for (int a = a_min_sample; a <= a_max_sample; a += a_step, sample_index += a_step, a_step = a_next_step) out_ptr->y = center.y + s.y * radius;
{ out_ptr++;
// a_step is clamped to IM_DRAWLIST_ARCFAST_SAMPLE_MAX, so we have guaranteed that it will not wrap over range twice or more
if (sample_index >= IM_DRAWLIST_ARCFAST_SAMPLE_MAX)
sample_index -= IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const ImVec2 s = _Data->ArcFastVtx[sample_index];
out_ptr->x = center.x + s.x * radius;
out_ptr->y = center.y + s.y * radius;
out_ptr++;
}
}
else
{
for (int a = a_min_sample; a >= a_max_sample; a -= a_step, sample_index -= a_step, a_step = a_next_step)
{
// a_step is clamped to IM_DRAWLIST_ARCFAST_SAMPLE_MAX, so we have guaranteed that it will not wrap over range twice or more
if (sample_index < 0)
sample_index += IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const ImVec2 s = _Data->ArcFastVtx[sample_index];
out_ptr->x = center.x + s.x * radius;
out_ptr->y = center.y + s.y * radius;
out_ptr++;
}
} }
if (extra_max_sample) if (extra_max_sample)
@ -1136,6 +1116,7 @@ void ImDrawList::_PathArcToN(const ImVec2& center, float radius, float a_min, fl
_Path.push_back(center); _Path.push_back(center);
return; return;
} }
IM_ASSERT(a_min <= a_max);
// Note that we are adding a point at both a_min and a_max. // Note that we are adding a point at both a_min and a_max.
// If you are trying to draw a full closed circle you don't want the overlapping points! // If you are trying to draw a full closed circle you don't want the overlapping points!
@ -1155,6 +1136,7 @@ void ImDrawList::PathArcToFast(const ImVec2& center, float radius, int a_min_of_
_Path.push_back(center); _Path.push_back(center);
return; return;
} }
IM_ASSERT(a_min_of_12 <= a_max_of_12);
_PathArcToFastEx(center, radius, a_min_of_12 * IM_DRAWLIST_ARCFAST_SAMPLE_MAX / 12, a_max_of_12 * IM_DRAWLIST_ARCFAST_SAMPLE_MAX / 12, 0); _PathArcToFastEx(center, radius, a_min_of_12 * IM_DRAWLIST_ARCFAST_SAMPLE_MAX / 12, a_max_of_12 * IM_DRAWLIST_ARCFAST_SAMPLE_MAX / 12, 0);
} }
@ -1165,6 +1147,7 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
_Path.push_back(center); _Path.push_back(center);
return; return;
} }
IM_ASSERT(a_min <= a_max);
if (num_segments > 0) if (num_segments > 0)
{ {
@ -1175,33 +1158,28 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
// Automatic segment count // Automatic segment count
if (radius <= _Data->ArcFastRadiusCutoff) if (radius <= _Data->ArcFastRadiusCutoff)
{ {
const bool a_is_reverse = a_max < a_min;
// We are going to use precomputed values for mid samples. // We are going to use precomputed values for mid samples.
// Determine first and last sample in lookup table that belong to the arc. // Determine first and last sample in lookup table that belong to the arc.
const float a_min_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_min / (IM_PI * 2.0f); const int a_min_sample = (int)ImCeil(IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_min / (IM_PI * 2.0f));
const float a_max_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_max / (IM_PI * 2.0f); const int a_max_sample = (int)( IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_max / (IM_PI * 2.0f));
const int a_mid_samples = ImMax(a_max_sample - a_min_sample, 0);
const int a_min_sample = a_is_reverse ? (int)ImFloorSigned(a_min_sample_f) : (int)ImCeil(a_min_sample_f);
const int a_max_sample = a_is_reverse ? (int)ImCeil(a_max_sample_f) : (int)ImFloorSigned(a_max_sample_f);
const int a_mid_samples = a_is_reverse ? ImMax(a_min_sample - a_max_sample, 0) : ImMax(a_max_sample - a_min_sample, 0);
const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX; const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const float a_max_segment_angle = a_max_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX; const float a_max_segment_angle = a_max_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const bool a_emit_start = (a_min_segment_angle - a_min) != 0.0f; const bool a_emit_start = (a_min_segment_angle - a_min) > 0.0f;
const bool a_emit_end = (a_max - a_max_segment_angle) != 0.0f; const bool a_emit_end = (a_max - a_max_segment_angle) > 0.0f;
_Path.reserve(_Path.Size + (a_mid_samples + 1 + (a_emit_start ? 1 : 0) + (a_emit_end ? 1 : 0))); _Path.reserve(_Path.Size + (a_mid_samples + 1 + (a_emit_start ? 1 : 0) + (a_emit_end ? 1 : 0)));
if (a_emit_start) if (a_emit_start)
_Path.push_back(ImVec2(center.x + ImCos(a_min) * radius, center.y + ImSin(a_min) * radius)); _Path.push_back(ImVec2(center.x + ImCos(a_min) * radius, center.y + ImSin(a_min) * radius));
if (a_mid_samples > 0) if (a_max_sample >= a_min_sample)
_PathArcToFastEx(center, radius, a_min_sample, a_max_sample, 0); _PathArcToFastEx(center, radius, a_min_sample, a_max_sample, 0);
if (a_emit_end) if (a_emit_end)
_Path.push_back(ImVec2(center.x + ImCos(a_max) * radius, center.y + ImSin(a_max) * radius)); _Path.push_back(ImVec2(center.x + ImCos(a_max) * radius, center.y + ImSin(a_max) * radius));
} }
else else
{ {
const float arc_length = ImAbs(a_max - a_min); const float arc_length = a_max - a_min;
const int circle_segment_count = _CalcCircleAutoSegmentCount(radius); const int circle_segment_count = _CalcCircleAutoSegmentCount(radius);
const int arc_segment_count = ImMax((int)ImCeil(circle_segment_count * arc_length / (IM_PI * 2.0f)), (int)(2.0f * IM_PI / arc_length)); const int arc_segment_count = ImMax((int)ImCeil(circle_segment_count * arc_length / (IM_PI * 2.0f)), (int)(2.0f * IM_PI / arc_length));
_PathArcToN(center, radius, a_min, a_max, arc_segment_count); _PathArcToN(center, radius, a_min, a_max, arc_segment_count);
@ -3491,7 +3469,6 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
return text_size; return text_size;
} }
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const
{ {
const ImFontGlyph* glyph = FindGlyph(c); const ImFontGlyph* glyph = FindGlyph(c);
@ -3506,7 +3483,6 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
draw_list->PrimRectUV(ImVec2(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale), ImVec2(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); draw_list->PrimRectUV(ImVec2(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale), ImVec2(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col);
} }
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const
{ {
if (!text_end) if (!text_end)
@ -3776,7 +3752,7 @@ void ImGui::RenderMouseCursor(ImDrawList* draw_list, ImVec2 pos, float scale, Im
if (font_atlas->GetMouseCursorTexData(mouse_cursor, &offset, &size, &uv[0], &uv[2])) if (font_atlas->GetMouseCursorTexData(mouse_cursor, &offset, &size, &uv[0], &uv[2]))
{ {
pos -= offset; pos -= offset;
ImTextureID tex_id = font_atlas->TexID; const ImTextureID tex_id = font_atlas->TexID;
draw_list->PushTextureID(tex_id); draw_list->PushTextureID(tex_id);
draw_list->AddImage(tex_id, pos + ImVec2(1, 0) * scale, pos + (ImVec2(1, 0) + size) * scale, uv[2], uv[3], col_shadow); draw_list->AddImage(tex_id, pos + ImVec2(1, 0) * scale, pos + (ImVec2(1, 0) + size) * scale, uv[2], uv[3], col_shadow);
draw_list->AddImage(tex_id, pos + ImVec2(2, 0) * scale, pos + (ImVec2(2, 0) + size) * scale, uv[2], uv[3], col_shadow); draw_list->AddImage(tex_id, pos + ImVec2(2, 0) * scale, pos + (ImVec2(2, 0) + size) * scale, uv[2], uv[3], col_shadow);

View File

@ -1,4 +1,4 @@
// dear imgui, v1.83 // dear imgui, v1.82 WIP
// (internal structures/api) // (internal structures/api)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@ -51,19 +51,10 @@ Index of this file:
#include <math.h> // sqrtf, fabsf, fmodf, powf, floorf, ceilf, cosf, sinf #include <math.h> // sqrtf, fabsf, fmodf, powf, floorf, ceilf, cosf, sinf
#include <limits.h> // INT_MIN, INT_MAX #include <limits.h> // INT_MIN, INT_MAX
// Enable SSE intrinsics if available
#if defined __SSE__ || defined __x86_64__ || defined _M_X64
#define IMGUI_ENABLE_SSE
#include <immintrin.h>
#endif
// Visual Studio warnings // Visual Studio warnings
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning (push) #pragma warning (push)
#pragma warning (disable: 4251) // class 'xxx' needs to have dll-interface to be used by clients of struct 'xxx' // when IMGUI_API is set to__declspec(dllexport) #pragma warning (disable: 4251) // class 'xxx' needs to have dll-interface to be used by clients of struct 'xxx' // when IMGUI_API is set to__declspec(dllexport)
#pragma warning (disable: 26812) // The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). [MSVC Static Analyzer)
#pragma warning (disable: 26495) // [Static Analyzer] Variable 'XXX' is uninitialized. Always initialize a member variable (type.6).
#endif #endif
// Clang/GCC warnings with -Weverything // Clang/GCC warnings with -Weverything
@ -73,7 +64,6 @@ Index of this file:
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' #pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx'
#endif #endif
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' #pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants ok, for ImFloorSigned()
#pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h #pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h
#pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h #pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h
#pragma clang diagnostic ignored "-Wold-style-cast" #pragma clang diagnostic ignored "-Wold-style-cast"
@ -116,7 +106,7 @@ struct ImGuiGroupData; // Stacked storage data for BeginGroup()/End
struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box
struct ImGuiLastItemDataBackup; // Backup and restore IsItemHovered() internal data struct ImGuiLastItemDataBackup; // Backup and restore IsItemHovered() internal data
struct ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only struct ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only
struct ImGuiNavItemData; // Result of a gamepad/keyboard directional navigation move query result struct ImGuiNavMoveResult; // Result of a gamepad/keyboard directional navigation move query result
struct ImGuiMetricsConfig; // Storage for ShowMetricsWindow() and DebugNodeXXX() functions struct ImGuiMetricsConfig; // Storage for ShowMetricsWindow() and DebugNodeXXX() functions
struct ImGuiNextWindowData; // Storage for SetNextWindow** functions struct ImGuiNextWindowData; // Storage for SetNextWindow** functions
struct ImGuiNextItemData; // Storage for SetNextItem** functions struct ImGuiNextItemData; // Storage for SetNextItem** functions
@ -130,17 +120,15 @@ struct ImGuiTabBar; // Storage for a tab bar
struct ImGuiTabItem; // Storage for a tab item (within a tab bar) struct ImGuiTabItem; // Storage for a tab item (within a tab bar)
struct ImGuiTable; // Storage for a table struct ImGuiTable; // Storage for a table
struct ImGuiTableColumn; // Storage for one column of a table struct ImGuiTableColumn; // Storage for one column of a table
struct ImGuiTableTempData; // Temporary storage for one table (one per table in the stack), shared between tables.
struct ImGuiTableSettings; // Storage for a table .ini settings struct ImGuiTableSettings; // Storage for a table .ini settings
struct ImGuiTableColumnsSettings; // Storage for a column .ini settings struct ImGuiTableColumnsSettings; // Storage for a column .ini settings
struct ImGuiWindow; // Storage for one window struct ImGuiWindow; // Storage for one window
struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame, in practice we currently keep it for each window) struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame)
struct ImGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session) struct ImGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session)
// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists. // Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists.
typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical
typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag() typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag()
typedef int ImGuiItemAddFlags; // -> enum ImGuiItemAddFlags_ // Flags: for ItemAdd()
typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags
typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns() typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns()
typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight() typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight()
@ -239,13 +227,6 @@ namespace ImStb
#define IMGUI_CDECL #define IMGUI_CDECL
#endif #endif
// Warnings
#if defined(_MSC_VER) && !defined(__clang__)
#define IM_MSVC_WARNING_SUPPRESS(XXXX) __pragma(warning(suppress: XXXX))
#else
#define IM_MSVC_WARNING_SUPPRESS(XXXX)
#endif
// Debug Tools // Debug Tools
// Use 'Metrics->Tools->Item Picker' to break into the call-stack of a specific item. // Use 'Metrics->Tools->Item Picker' to break into the call-stack of a specific item.
#ifndef IM_DEBUG_BREAK #ifndef IM_DEBUG_BREAK
@ -333,7 +314,6 @@ IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, cons
// We are keeping those disabled by default so they don't leak in user space, to allow user enabling implicit cast operators between ImVec2 and their own types (using IM_VEC2_CLASS_EXTRA etc.) // We are keeping those disabled by default so they don't leak in user space, to allow user enabling implicit cast operators between ImVec2 and their own types (using IM_VEC2_CLASS_EXTRA etc.)
// We unfortunately don't have a unary- operator for ImVec2 because this would needs to be defined inside the class itself. // We unfortunately don't have a unary- operator for ImVec2 because this would needs to be defined inside the class itself.
#ifdef IMGUI_DEFINE_MATH_OPERATORS #ifdef IMGUI_DEFINE_MATH_OPERATORS
IM_MSVC_RUNTIME_CHECKS_OFF
static inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x * rhs, lhs.y * rhs); } static inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x * rhs, lhs.y * rhs); }
static inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x / rhs, lhs.y / rhs); } static inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x / rhs, lhs.y / rhs); }
static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); } static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); }
@ -349,7 +329,6 @@ static inline ImVec2& operator/=(ImVec2& lhs, const ImVec2& rhs)
static inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); } static inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); }
static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); } static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); }
static inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); } static inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); }
IM_MSVC_RUNTIME_CHECKS_RESTORE
#endif #endif
// Helpers: File System // Helpers: File System
@ -375,7 +354,6 @@ IMGUI_API ImU64 ImFileWrite(const void* data, ImU64 size, ImU64 coun
IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* mode, size_t* out_file_size = NULL, int padding_bytes = 0); IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* mode, size_t* out_file_size = NULL, int padding_bytes = 0);
// Helpers: Maths // Helpers: Maths
IM_MSVC_RUNTIME_CHECKS_OFF
// - Wrapper for standard libs functions. (Note that imgui_demo.cpp does _not_ use them to keep the code easy to copy) // - Wrapper for standard libs functions. (Note that imgui_demo.cpp does _not_ use them to keep the code easy to copy)
#ifndef IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS #ifndef IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS
#define ImFabs(X) fabsf(X) #define ImFabs(X) fabsf(X)
@ -386,23 +364,16 @@ IM_MSVC_RUNTIME_CHECKS_OFF
#define ImAcos(X) acosf(X) #define ImAcos(X) acosf(X)
#define ImAtan2(Y, X) atan2f((Y), (X)) #define ImAtan2(Y, X) atan2f((Y), (X))
#define ImAtof(STR) atof(STR) #define ImAtof(STR) atof(STR)
//#define ImFloorStd(X) floorf(X) // We use our own, see ImFloor() and ImFloorSigned() #define ImFloorStd(X) floorf(X) // We already uses our own ImFloor() { return (float)(int)v } internally so the standard one wrapper is named differently (it's used by e.g. stb_truetype)
#define ImCeil(X) ceilf(X) #define ImCeil(X) ceilf(X)
static inline float ImPow(float x, float y) { return powf(x, y); } // DragBehaviorT/SliderBehaviorT uses ImPow with either float/double and need the precision static inline float ImPow(float x, float y) { return powf(x, y); } // DragBehaviorT/SliderBehaviorT uses ImPow with either float/double and need the precision
static inline double ImPow(double x, double y) { return pow(x, y); } static inline double ImPow(double x, double y) { return pow(x, y); }
static inline float ImLog(float x) { return logf(x); } // DragBehaviorT/SliderBehaviorT uses ImLog with either float/double and need the precision static inline float ImLog(float x) { return logf(x); } // DragBehaviorT/SliderBehaviorT uses ImLog with either float/double and need the precision
static inline double ImLog(double x) { return log(x); } static inline double ImLog(double x) { return log(x); }
static inline int ImAbs(int x) { return x < 0 ? -x : x; }
static inline float ImAbs(float x) { return fabsf(x); } static inline float ImAbs(float x) { return fabsf(x); }
static inline double ImAbs(double x) { return fabs(x); } static inline double ImAbs(double x) { return fabs(x); }
static inline float ImSign(float x) { return (x < 0.0f) ? -1.0f : ((x > 0.0f) ? 1.0f : 0.0f); } // Sign operator - returns -1, 0 or 1 based on sign of argument static inline float ImSign(float x) { return (x < 0.0f) ? -1.0f : ((x > 0.0f) ? 1.0f : 0.0f); } // Sign operator - returns -1, 0 or 1 based on sign of argument
static inline double ImSign(double x) { return (x < 0.0) ? -1.0 : ((x > 0.0) ? 1.0 : 0.0); } static inline double ImSign(double x) { return (x < 0.0) ? -1.0 : ((x > 0.0) ? 1.0 : 0.0); }
#ifdef IMGUI_ENABLE_SSE
static inline float ImRsqrt(float x) { return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(x))); }
#else
static inline float ImRsqrt(float x) { return 1.0f / sqrtf(x); }
#endif
static inline double ImRsqrt(double x) { return 1.0 / sqrt(x); }
#endif #endif
// - ImMin/ImMax/ImClamp/ImLerp/ImSwap are used by widgets which support variety of types: signed/unsigned int/long long float/double // - ImMin/ImMax/ImClamp/ImLerp/ImSwap are used by widgets which support variety of types: signed/unsigned int/long long float/double
// (Exceptionally using templates here but we could also redefine them for those types) // (Exceptionally using templates here but we could also redefine them for those types)
@ -423,16 +394,14 @@ static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t)
static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; }
static inline float ImLengthSqr(const ImVec2& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y); } static inline float ImLengthSqr(const ImVec2& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y); }
static inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); } static inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); }
static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return ImRsqrt(d); return fail_value; } static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return 1.0f / ImSqrt(d); return fail_value; }
static inline float ImFloor(float f) { return (float)(int)(f); } static inline float ImFloor(float f) { return (float)(int)(f); }
static inline float ImFloorSigned(float f) { return (float)((f >= 0 || (int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf()
static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); } static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); }
static inline int ImModPositive(int a, int b) { return (a + b) % b; } static inline int ImModPositive(int a, int b) { return (a + b) % b; }
static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); } static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; } static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; }
static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
IM_MSVC_RUNTIME_CHECKS_RESTORE
// Helpers: Geometry // Helpers: Geometry
IMGUI_API ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t); IMGUI_API ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t);
@ -448,7 +417,6 @@ IMGUI_API ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy);
// Helper: ImVec1 (1D vector) // Helper: ImVec1 (1D vector)
// (this odd construct is used to facilitate the transition between 1D and 2D, and the maintenance of some branches/patches) // (this odd construct is used to facilitate the transition between 1D and 2D, and the maintenance of some branches/patches)
IM_MSVC_RUNTIME_CHECKS_OFF
struct ImVec1 struct ImVec1
{ {
float x; float x;
@ -502,7 +470,6 @@ struct IMGUI_API ImRect
bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; } bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; }
ImVec4 ToVec4() const { return ImVec4(Min.x, Min.y, Max.x, Max.y); } ImVec4 ToVec4() const { return ImVec4(Min.x, Min.y, Max.x, Max.y); }
}; };
IM_MSVC_RUNTIME_CHECKS_RESTORE
// Helper: ImBitArray // Helper: ImBitArray
inline bool ImBitArrayTestBit(const ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); return (arr[n >> 5] & mask) != 0; } inline bool ImBitArrayTestBit(const ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); return (arr[n >> 5] & mask) != 0; }
@ -522,12 +489,12 @@ inline void ImBitArraySetBitRange(ImU32* arr, int n, int n2) // Works on ran
} }
// Helper: ImBitArray class (wrapper over ImBitArray functions) // Helper: ImBitArray class (wrapper over ImBitArray functions)
// Store 1-bit per value. // Store 1-bit per value. NOT CLEARED by constructor.
template<int BITCOUNT> template<int BITCOUNT>
struct IMGUI_API ImBitArray struct IMGUI_API ImBitArray
{ {
ImU32 Storage[(BITCOUNT + 31) >> 5]; ImU32 Storage[(BITCOUNT + 31) >> 5];
ImBitArray() { ClearAllBits(); } ImBitArray() { }
void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); } void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); }
void SetAllBits() { memset(Storage, 255, sizeof(Storage)); } void SetAllBits() { memset(Storage, 255, sizeof(Storage)); }
bool TestBit(int n) const { IM_ASSERT(n < BITCOUNT); return ImBitArrayTestBit(Storage, n); } bool TestBit(int n) const { IM_ASSERT(n < BITCOUNT); return ImBitArrayTestBit(Storage, n); }
@ -727,51 +694,32 @@ enum ImGuiItemFlags_
ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false
ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // MenuItem/Selectable() automatically closes current Popup window ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // MenuItem/Selectable() automatically closes current Popup window
ImGuiItemFlags_MixedValue = 1 << 6, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets) ImGuiItemFlags_MixedValue = 1 << 6, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets)
ImGuiItemFlags_ReadOnly = 1 << 7 // false // [ALPHA] Allow hovering interactions but underlying value is not changed. ImGuiItemFlags_ReadOnly = 1 << 7, // false // [ALPHA] Allow hovering interactions but underlying value is not changed.
}; ImGuiItemFlags_Default_ = 0
// Flags for ItemAdd()
// FIXME-NAV: _Focusable is _ALMOST_ what you would expect to be called '_TabStop' but because SetKeyboardFocusHere() works on items with no TabStop we distinguish Focusable from TabStop.
enum ImGuiItemAddFlags_
{
ImGuiItemAddFlags_None = 0,
ImGuiItemAddFlags_Focusable = 1 << 0 // FIXME-NAV: In current/legacy scheme, Focusable+TabStop support are opt-in by widgets. We will transition it toward being opt-out, so this flag is expected to eventually disappear.
}; };
// Storage for LastItem data // Storage for LastItem data
enum ImGuiItemStatusFlags_ enum ImGuiItemStatusFlags_
{ {
ImGuiItemStatusFlags_None = 0, ImGuiItemStatusFlags_None = 0,
ImGuiItemStatusFlags_HoveredRect = 1 << 0, // Mouse position is within item rectangle (does NOT mean that the window is in correct z-order and can be hovered!, this is only one part of the most-common IsItemHovered test) ImGuiItemStatusFlags_HoveredRect = 1 << 0,
ImGuiItemStatusFlags_HasDisplayRect = 1 << 1, // window->DC.LastItemDisplayRect is valid ImGuiItemStatusFlags_HasDisplayRect = 1 << 1, // LastItemDisplayRect is valid
ImGuiItemStatusFlags_Edited = 1 << 2, // Value exposed by item was edited in the current frame (should match the bool return value of most widgets) ImGuiItemStatusFlags_Edited = 1 << 2, // Value exposed by item was edited in the current frame (should match the bool return value of most widgets)
ImGuiItemStatusFlags_ToggledSelection = 1 << 3, // Set when Selectable(), TreeNode() reports toggling a selection. We can't report "Selected", only state changes, in order to easily handle clipping with less issues. ImGuiItemStatusFlags_ToggledSelection = 1 << 3, // Set when Selectable(), TreeNode() reports toggling a selection. We can't report "Selected" because reporting the change allows us to handle clipping with less issues.
ImGuiItemStatusFlags_ToggledOpen = 1 << 4, // Set when TreeNode() reports toggling their open state. ImGuiItemStatusFlags_ToggledOpen = 1 << 4, // Set when TreeNode() reports toggling their open state.
ImGuiItemStatusFlags_HasDeactivated = 1 << 5, // Set if the widget/group is able to provide data for the ImGuiItemStatusFlags_Deactivated flag. ImGuiItemStatusFlags_HasDeactivated = 1 << 5, // Set if the widget/group is able to provide data for the ImGuiItemStatusFlags_Deactivated flag.
ImGuiItemStatusFlags_Deactivated = 1 << 6, // Only valid if ImGuiItemStatusFlags_HasDeactivated is set. ImGuiItemStatusFlags_Deactivated = 1 << 6, // Only valid if ImGuiItemStatusFlags_HasDeactivated is set.
ImGuiItemStatusFlags_HoveredWindow = 1 << 7, // Override the HoveredWindow test to allow cross-window hover testing. ImGuiItemStatusFlags_HoveredWindow = 1 << 7 // Override the HoveredWindow test to allow cross-window hover testing.
ImGuiItemStatusFlags_FocusedByCode = 1 << 8, // Set when the Focusable item just got focused from code.
ImGuiItemStatusFlags_FocusedByTabbing = 1 << 9, // Set when the Focusable item just got focused by Tabbing.
ImGuiItemStatusFlags_Focused = ImGuiItemStatusFlags_FocusedByCode | ImGuiItemStatusFlags_FocusedByTabbing
#ifdef IMGUI_ENABLE_TEST_ENGINE #ifdef IMGUI_ENABLE_TEST_ENGINE
, // [imgui_tests only] , // [imgui_tests only]
ImGuiItemStatusFlags_Openable = 1 << 20, // ImGuiItemStatusFlags_Openable = 1 << 10, //
ImGuiItemStatusFlags_Opened = 1 << 21, // ImGuiItemStatusFlags_Opened = 1 << 11, //
ImGuiItemStatusFlags_Checkable = 1 << 22, // ImGuiItemStatusFlags_Checkable = 1 << 12, //
ImGuiItemStatusFlags_Checked = 1 << 23 // ImGuiItemStatusFlags_Checked = 1 << 13 //
#endif #endif
}; };
// Extend ImGuiInputTextFlags_
enum ImGuiInputTextFlagsPrivate_
{
// [Internal]
ImGuiInputTextFlags_Multiline = 1 << 26, // For internal use by InputTextMultiline()
ImGuiInputTextFlags_NoMarkEdited = 1 << 27, // For internal use by functions using InputText() before reformatting data
ImGuiInputTextFlags_MergedItem = 1 << 28 // For internal use by TempInputText(), will skip calling ItemAdd(). Require bounding-box to strictly match.
};
// Extend ImGuiButtonFlags_ // Extend ImGuiButtonFlags_
enum ImGuiButtonFlagsPrivate_ enum ImGuiButtonFlagsPrivate_
{ {
@ -879,7 +827,6 @@ enum ImGuiInputSource
ImGuiInputSource_Keyboard, ImGuiInputSource_Keyboard,
ImGuiInputSource_Gamepad, ImGuiInputSource_Gamepad,
ImGuiInputSource_Nav, // Stored in g.ActiveIdSource only ImGuiInputSource_Nav, // Stored in g.ActiveIdSource only
ImGuiInputSource_Clipboard, // Currently only used by InputText()
ImGuiInputSource_COUNT ImGuiInputSource_COUNT
}; };
@ -1029,7 +976,8 @@ struct IMGUI_API ImGuiInputTextState
bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!) bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!)
bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection
bool Edited; // edited this frame bool Edited; // edited this frame
ImGuiInputTextFlags Flags; // copy of InputText() flags bool OverwriteMode; // toggle with INSERT key
ImGuiInputTextFlags UserFlags; // Temporarily set while we call user's callback
ImGuiInputTextCallback UserCallback; // " ImGuiInputTextCallback UserCallback; // "
void* UserCallbackData; // " void* UserCallbackData; // "
@ -1062,18 +1010,18 @@ struct ImGuiPopupData
ImGuiPopupData() { memset(this, 0, sizeof(*this)); OpenFrameCount = -1; } ImGuiPopupData() { memset(this, 0, sizeof(*this)); OpenFrameCount = -1; }
}; };
struct ImGuiNavItemData struct ImGuiNavMoveResult
{ {
ImGuiWindow* Window; // Init,Move // Best candidate window (result->ItemWindow->RootWindowForNav == request->Window) ImGuiWindow* Window; // Best candidate window
ImGuiID ID; // Init,Move // Best candidate item ID ImGuiID ID; // Best candidate ID
ImGuiID FocusScopeId; // Init,Move // Best candidate focus scope ID ImGuiID FocusScopeId; // Best candidate focus scope ID
ImRect RectRel; // Init,Move // Best candidate bounding box in window relative space float DistBox; // Best candidate box distance to current NavId
float DistBox; // Move // Best candidate box distance to current NavId float DistCenter; // Best candidate center distance to current NavId
float DistCenter; // Move // Best candidate center distance to current NavId float DistAxial;
float DistAxial; // Move // Best candidate axial distance to current NavId ImRect RectRel; // Best candidate bounding box in window relative space
ImGuiNavItemData() { Clear(); } ImGuiNavMoveResult() { Clear(); }
void Clear() { Window = NULL; ID = FocusScopeId = 0; RectRel = ImRect(); DistBox = DistCenter = DistAxial = FLT_MAX; } void Clear() { Window = NULL; ID = FocusScopeId = 0; DistBox = DistCenter = DistAxial = FLT_MAX; RectRel = ImRect(); }
}; };
enum ImGuiNextWindowDataFlags_ enum ImGuiNextWindowDataFlags_
@ -1233,21 +1181,14 @@ struct ImGuiViewportP : public ImGuiViewport
ImVec2 WorkOffsetMin; // Work Area: Offset from Pos to top-left corner of Work Area. Generally (0,0) or (0,+main_menu_bar_height). Work Area is Full Area but without menu-bars/status-bars (so WorkArea always fit inside Pos/Size!) ImVec2 WorkOffsetMin; // Work Area: Offset from Pos to top-left corner of Work Area. Generally (0,0) or (0,+main_menu_bar_height). Work Area is Full Area but without menu-bars/status-bars (so WorkArea always fit inside Pos/Size!)
ImVec2 WorkOffsetMax; // Work Area: Offset from Pos+Size to bottom-right corner of Work Area. Generally (0,0) or (0,-status_bar_height). ImVec2 WorkOffsetMax; // Work Area: Offset from Pos+Size to bottom-right corner of Work Area. Generally (0,0) or (0,-status_bar_height).
ImVec2 BuildWorkOffsetMin; // Work Area: Offset being built during current frame. Generally >= 0.0f. ImVec2 CurrWorkOffsetMin; // Work Area: Offset being built/increased during current frame
ImVec2 BuildWorkOffsetMax; // Work Area: Offset being built during current frame. Generally <= 0.0f. ImVec2 CurrWorkOffsetMax; // Work Area: Offset being built/decreased during current frame
ImGuiViewportP() { DrawListsLastFrame[0] = DrawListsLastFrame[1] = -1; DrawLists[0] = DrawLists[1] = NULL; } ImGuiViewportP() { DrawListsLastFrame[0] = DrawListsLastFrame[1] = -1; DrawLists[0] = DrawLists[1] = NULL; }
~ImGuiViewportP() { if (DrawLists[0]) IM_DELETE(DrawLists[0]); if (DrawLists[1]) IM_DELETE(DrawLists[1]); } ~ImGuiViewportP() { if (DrawLists[0]) IM_DELETE(DrawLists[0]); if (DrawLists[1]) IM_DELETE(DrawLists[1]); }
ImRect GetMainRect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
// Calculate work rect pos/size given a set of offset (we have 1 pair of offset for rect locked from last frame data, and 1 pair for currently building rect) ImRect GetWorkRect() const { return ImRect(WorkPos.x, WorkPos.y, WorkPos.x + WorkSize.x, WorkPos.y + WorkSize.y); }
ImVec2 CalcWorkRectPos(const ImVec2& off_min) const { return ImVec2(Pos.x + off_min.x, Pos.y + off_min.y); } void UpdateWorkRect() { WorkPos = ImVec2(Pos.x + WorkOffsetMin.x, Pos.y + WorkOffsetMin.y); WorkSize = ImVec2(ImMax(0.0f, Size.x - WorkOffsetMin.x + WorkOffsetMax.x), ImMax(0.0f, Size.y - WorkOffsetMin.y + WorkOffsetMax.y)); }
ImVec2 CalcWorkRectSize(const ImVec2& off_min, const ImVec2& off_max) const { return ImVec2(ImMax(0.0f, Size.x - off_min.x + off_max.x), ImMax(0.0f, Size.y - off_min.y + off_max.y)); }
void UpdateWorkRect() { WorkPos = CalcWorkRectPos(WorkOffsetMin); WorkSize = CalcWorkRectSize(WorkOffsetMin, WorkOffsetMax); } // Update public fields
// Helpers to retrieve ImRect (we don't need to store BuildWorkRect as every access tend to change it, hence the code asymmetry)
ImRect GetMainRect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
ImRect GetWorkRect() const { return ImRect(WorkPos.x, WorkPos.y, WorkPos.x + WorkSize.x, WorkPos.y + WorkSize.y); }
ImRect GetBuildWorkRect() const { ImVec2 pos = CalcWorkRectPos(BuildWorkOffsetMin); ImVec2 size = CalcWorkRectSize(BuildWorkOffsetMin, BuildWorkOffsetMax); return ImRect(pos.x, pos.y, pos.x + size.x, pos.y + size.y); }
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1371,12 +1312,11 @@ struct ImGuiContext
// Windows state // Windows state
ImVector<ImGuiWindow*> Windows; // Windows, sorted in display order, back to front ImVector<ImGuiWindow*> Windows; // Windows, sorted in display order, back to front
ImVector<ImGuiWindow*> WindowsFocusOrder; // Root windows, sorted in focus order, back to front. ImVector<ImGuiWindow*> WindowsFocusOrder; // Windows, sorted in focus order, back to front. (FIXME: We could only store root windows here! Need to sort out the Docking equivalent which is RootWindowDockStop and is unfortunately a little more dynamic)
ImVector<ImGuiWindow*> WindowsTempSortBuffer; // Temporary buffer used in EndFrame() to reorder windows so parents are kept before their child ImVector<ImGuiWindow*> WindowsTempSortBuffer; // Temporary buffer used in EndFrame() to reorder windows so parents are kept before their child
ImVector<ImGuiWindow*> CurrentWindowStack; ImVector<ImGuiWindow*> CurrentWindowStack;
ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow* ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow*
int WindowsActiveCount; // Number of unique windows submitted by frame int WindowsActiveCount; // Number of unique windows submitted by frame
ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING)
ImGuiWindow* CurrentWindow; // Window being drawn into ImGuiWindow* CurrentWindow; // Window being drawn into
ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs. ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs.
ImGuiWindow* HoveredWindowUnderMovingWindow; // Hovered window ignoring MovingWindow. Only set if MovingWindow is set. ImGuiWindow* HoveredWindowUnderMovingWindow; // Hovered window ignoring MovingWindow. Only set if MovingWindow is set.
@ -1386,7 +1326,6 @@ struct ImGuiContext
float WheelingWindowTimer; float WheelingWindowTimer;
// Item/widgets state and tracking information // Item/widgets state and tracking information
ImGuiItemFlags CurrentItemFlags; // == g.ItemFlagsStack.back()
ImGuiID HoveredId; // Hovered widget, filled during the frame ImGuiID HoveredId; // Hovered widget, filled during the frame
ImGuiID HoveredIdPreviousFrame; ImGuiID HoveredIdPreviousFrame;
bool HoveredIdAllowOverlap; bool HoveredIdAllowOverlap;
@ -1469,9 +1408,9 @@ struct ImGuiContext
ImGuiKeyModFlags NavMoveRequestKeyMods; ImGuiKeyModFlags NavMoveRequestKeyMods;
ImGuiDir NavMoveDir, NavMoveDirLast; // Direction of the move request (left/right/up/down), direction of the previous move request ImGuiDir NavMoveDir, NavMoveDirLast; // Direction of the move request (left/right/up/down), direction of the previous move request
ImGuiDir NavMoveClipDir; // FIXME-NAV: Describe the purpose of this better. Might want to rename? ImGuiDir NavMoveClipDir; // FIXME-NAV: Describe the purpose of this better. Might want to rename?
ImGuiNavItemData NavMoveResultLocal; // Best move request candidate within NavWindow ImGuiNavMoveResult NavMoveResultLocal; // Best move request candidate within NavWindow
ImGuiNavItemData NavMoveResultLocalVisibleSet; // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag) ImGuiNavMoveResult NavMoveResultLocalVisibleSet; // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag)
ImGuiNavItemData NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag) ImGuiNavMoveResult NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag)
ImGuiWindow* NavWrapRequestWindow; // Window which requested trying nav wrap-around. ImGuiWindow* NavWrapRequestWindow; // Window which requested trying nav wrap-around.
ImGuiNavMoveFlags NavWrapRequestFlags; // Wrap-around operation flags. ImGuiNavMoveFlags NavWrapRequestFlags; // Wrap-around operation flags.
@ -1484,13 +1423,13 @@ struct ImGuiContext
bool NavWindowingToggleLayer; bool NavWindowingToggleLayer;
// Legacy Focus/Tabbing system (older than Nav, active even if Nav is disabled, misnamed. FIXME-NAV: This needs a redesign!) // Legacy Focus/Tabbing system (older than Nav, active even if Nav is disabled, misnamed. FIXME-NAV: This needs a redesign!)
ImGuiWindow* TabFocusRequestCurrWindow; // ImGuiWindow* FocusRequestCurrWindow; //
ImGuiWindow* TabFocusRequestNextWindow; // ImGuiWindow* FocusRequestNextWindow; //
int TabFocusRequestCurrCounterRegular; // Any item being requested for focus, stored as an index (we on layout to be stable between the frame pressing TAB and the next frame, semi-ouch) int FocusRequestCurrCounterRegular; // Any item being requested for focus, stored as an index (we on layout to be stable between the frame pressing TAB and the next frame, semi-ouch)
int TabFocusRequestCurrCounterTabStop; // Tab item being requested for focus, stored as an index int FocusRequestCurrCounterTabStop; // Tab item being requested for focus, stored as an index
int TabFocusRequestNextCounterRegular; // Stored for next frame int FocusRequestNextCounterRegular; // Stored for next frame
int TabFocusRequestNextCounterTabStop; // " int FocusRequestNextCounterTabStop; // "
bool TabFocusPressed; // Set in NewFrame() when user pressed Tab bool FocusTabPressed; //
// Render // Render
float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list) float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list)
@ -1517,9 +1456,8 @@ struct ImGuiContext
// Table // Table
ImGuiTable* CurrentTable; ImGuiTable* CurrentTable;
int CurrentTableStackIdx;
ImPool<ImGuiTable> Tables; ImPool<ImGuiTable> Tables;
ImVector<ImGuiTableTempData> TablesTempDataStack; ImVector<ImGuiPtrOrIndex> CurrentTableStack;
ImVector<float> TablesLastTimeActive; // Last used timestamp of each tables (SOA, for efficient GC) ImVector<float> TablesLastTimeActive; // Last used timestamp of each tables (SOA, for efficient GC)
ImVector<ImDrawChannel> DrawChannelsTempMergeBuffer; ImVector<ImDrawChannel> DrawChannelsTempMergeBuffer;
@ -1586,7 +1524,6 @@ struct ImGuiContext
// Misc // Misc
float FramerateSecPerFrame[120]; // Calculate estimate of framerate for user over the last 2 seconds. float FramerateSecPerFrame[120]; // Calculate estimate of framerate for user over the last 2 seconds.
int FramerateSecPerFrameIdx; int FramerateSecPerFrameIdx;
int FramerateSecPerFrameCount;
float FramerateSecPerFrameAccum; float FramerateSecPerFrameAccum;
int WantCaptureMouseNextFrame; // Explicit capture via CaptureKeyboardFromApp()/CaptureMouseFromApp() sets those flags int WantCaptureMouseNextFrame; // Explicit capture via CaptureKeyboardFromApp()/CaptureMouseFromApp() sets those flags
int WantCaptureKeyboardNextFrame; int WantCaptureKeyboardNextFrame;
@ -1617,7 +1554,6 @@ struct ImGuiContext
WheelingWindow = NULL; WheelingWindow = NULL;
WheelingWindowTimer = 0.0f; WheelingWindowTimer = 0.0f;
CurrentItemFlags = ImGuiItemFlags_None;
HoveredId = HoveredIdPreviousFrame = 0; HoveredId = HoveredIdPreviousFrame = 0;
HoveredIdAllowOverlap = false; HoveredIdAllowOverlap = false;
HoveredIdUsingMouseWheel = HoveredIdPreviousFrameUsingMouseWheel = false; HoveredIdUsingMouseWheel = HoveredIdPreviousFrameUsingMouseWheel = false;
@ -1676,10 +1612,10 @@ struct ImGuiContext
NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f; NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f;
NavWindowingToggleLayer = false; NavWindowingToggleLayer = false;
TabFocusRequestCurrWindow = TabFocusRequestNextWindow = NULL; FocusRequestCurrWindow = FocusRequestNextWindow = NULL;
TabFocusRequestCurrCounterRegular = TabFocusRequestCurrCounterTabStop = INT_MAX; FocusRequestCurrCounterRegular = FocusRequestCurrCounterTabStop = INT_MAX;
TabFocusRequestNextCounterRegular = TabFocusRequestNextCounterTabStop = INT_MAX; FocusRequestNextCounterRegular = FocusRequestNextCounterTabStop = INT_MAX;
TabFocusPressed = false; FocusTabPressed = false;
DimBgRatio = 0.0f; DimBgRatio = 0.0f;
MouseCursor = ImGuiMouseCursor_Arrow; MouseCursor = ImGuiMouseCursor_Arrow;
@ -1697,7 +1633,6 @@ struct ImGuiContext
memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal)); memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal));
CurrentTable = NULL; CurrentTable = NULL;
CurrentTableStackIdx = -1;
CurrentTabBar = NULL; CurrentTabBar = NULL;
LastValidMousePos = ImVec2(0.0f, 0.0f); LastValidMousePos = ImVec2(0.0f, 0.0f);
@ -1734,7 +1669,7 @@ struct ImGuiContext
DebugItemPickerBreakId = 0; DebugItemPickerBreakId = 0;
memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame));
FramerateSecPerFrameIdx = FramerateSecPerFrameCount = 0; FramerateSecPerFrameIdx = 0;
FramerateSecPerFrameAccum = 0.0f; FramerateSecPerFrameAccum = 0.0f;
WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1; WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1;
memset(TempBuffer, 0, sizeof(TempBuffer)); memset(TempBuffer, 0, sizeof(TempBuffer));
@ -1772,8 +1707,8 @@ struct IMGUI_API ImGuiWindowTempData
// Keyboard/Gamepad navigation // Keyboard/Gamepad navigation
ImGuiNavLayer NavLayerCurrent; // Current layer, 0..31 (we currently only use 0..1) ImGuiNavLayer NavLayerCurrent; // Current layer, 0..31 (we currently only use 0..1)
short NavLayersActiveMask; // Which layers have been written to (result from previous frame) int NavLayerActiveMask; // Which layers have been written to (result from previous frame)
short NavLayersActiveMaskNext;// Which layers have been written to (accumulator for current frame) int NavLayerActiveMaskNext; // Which layers have been written to (accumulator for current frame)
ImGuiID NavFocusScopeIdCurrent; // Current focus scope ID while appending ImGuiID NavFocusScopeIdCurrent; // Current focus scope ID while appending
bool NavHideHighlightOneFrame; bool NavHideHighlightOneFrame;
bool NavHasScroll; // Set when scrolling can be used (ScrollMax > 0.0f) bool NavHasScroll; // Set when scrolling can be used (ScrollMax > 0.0f)
@ -1795,6 +1730,7 @@ struct IMGUI_API ImGuiWindowTempData
// Local parameters stacks // Local parameters stacks
// We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings. // We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings.
ImGuiItemFlags ItemFlags; // == g.ItemFlagsStack.back()
float ItemWidth; // Current item width (>0.0: width in pixels, <0.0: align xx pixels to the right of window). float ItemWidth; // Current item width (>0.0: width in pixels, <0.0: align xx pixels to the right of window).
float TextWrapPos; // Current text wrap pos. float TextWrapPos; // Current text wrap pos.
ImVector<float> ItemWidthStack; // Store item widths to restore (attention: .back() is not == ItemWidth) ImVector<float> ItemWidthStack; // Store item widths to restore (attention: .back() is not == ItemWidth)
@ -1839,9 +1775,8 @@ struct IMGUI_API ImGuiWindow
bool HasCloseButton; // Set when the window has a close button (p_open != NULL) bool HasCloseButton; // Set when the window has a close button (p_open != NULL)
signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3) signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3)
short BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) short BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
short BeginOrderWithinParent; // Begin() order within immediate parent window, if we are a child window. Otherwise 0. short BeginOrderWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0.
short BeginOrderWithinContext; // Begin() order within entire imgui context. This is mostly used for debugging submission order related issues. short BeginOrderWithinContext; // Order within entire imgui context. This is mostly used for debugging submission order related issues.
short FocusOrder; // Order within WindowsFocusOrder[], altered when windows are focused.
ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
ImS8 AutoFitFramesX, AutoFitFramesY; ImS8 AutoFitFramesX, AutoFitFramesY;
ImS8 AutoFitChildAxises; ImS8 AutoFitChildAxises;
@ -1850,7 +1785,6 @@ struct IMGUI_API ImGuiWindow
ImS8 HiddenFramesCanSkipItems; // Hide the window for N frames ImS8 HiddenFramesCanSkipItems; // Hide the window for N frames
ImS8 HiddenFramesCannotSkipItems; // Hide the window for N frames while allowing items to be submitted so we can measure their size ImS8 HiddenFramesCannotSkipItems; // Hide the window for N frames while allowing items to be submitted so we can measure their size
ImS8 HiddenFramesForRenderOnly; // Hide the window until frame N at Render() time only ImS8 HiddenFramesForRenderOnly; // Hide the window until frame N at Render() time only
ImS8 DisableInputsFrames; // Disable window interactions for N frames
ImGuiCond SetWindowPosAllowFlags : 8; // store acceptable condition flags for SetNextWindowPos() use. ImGuiCond SetWindowPosAllowFlags : 8; // store acceptable condition flags for SetNextWindowPos() use.
ImGuiCond SetWindowSizeAllowFlags : 8; // store acceptable condition flags for SetNextWindowSize() use. ImGuiCond SetWindowSizeAllowFlags : 8; // store acceptable condition flags for SetNextWindowSize() use.
ImGuiCond SetWindowCollapsedAllowFlags : 8; // store acceptable condition flags for SetNextWindowCollapsed() use. ImGuiCond SetWindowCollapsedAllowFlags : 8; // store acceptable condition flags for SetNextWindowCollapsed() use.
@ -1944,7 +1878,6 @@ enum ImGuiTabBarFlagsPrivate_
// Extend ImGuiTabItemFlags_ // Extend ImGuiTabItemFlags_
enum ImGuiTabItemFlagsPrivate_ enum ImGuiTabItemFlagsPrivate_
{ {
ImGuiTabItemFlags_SectionMask_ = ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_Trailing,
ImGuiTabItemFlags_NoCloseButton = 1 << 20, // Track whether p_open was set or not (we'll need this info on the next frame to recompute ContentWidth during layout) ImGuiTabItemFlags_NoCloseButton = 1 << 20, // Track whether p_open was set or not (we'll need this info on the next frame to recompute ContentWidth during layout)
ImGuiTabItemFlags_Button = 1 << 21 // Used by TabItemButton, change the tab item behavior to mimic a button ImGuiTabItemFlags_Button = 1 << 21 // Used by TabItemButton, change the tab item behavior to mimic a button
}; };
@ -1990,7 +1923,7 @@ struct ImGuiTabBar
float ScrollingRectMinX; float ScrollingRectMinX;
float ScrollingRectMaxX; float ScrollingRectMaxX;
ImGuiID ReorderRequestTabId; ImGuiID ReorderRequestTabId;
ImS16 ReorderRequestOffset; ImS8 ReorderRequestDir;
ImS8 BeginCount; ImS8 BeginCount;
bool WantLayout; bool WantLayout;
bool VisibleTabWasSubmitted; bool VisibleTabWasSubmitted;
@ -2015,6 +1948,8 @@ struct ImGuiTabBar
// [SECTION] Table support // [SECTION] Table support
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifdef IMGUI_HAS_TABLE
#define IM_COL32_DISABLE IM_COL32(0,0,0,1) // Special sentinel code which cannot be used as a regular color. #define IM_COL32_DISABLE IM_COL32(0,0,0,1) // Special sentinel code which cannot be used as a regular color.
#define IMGUI_TABLE_MAX_COLUMNS 64 // sizeof(ImU64) * 8. This is solely because we frequently encode columns set in a ImU64. #define IMGUI_TABLE_MAX_COLUMNS 64 // sizeof(ImU64) * 8. This is solely because we frequently encode columns set in a ImU64.
#define IMGUI_TABLE_MAX_DRAW_CHANNELS (4 + 64 * 2) // See TableSetupDrawChannels() #define IMGUI_TABLE_MAX_DRAW_CHANNELS (4 + 64 * 2) // See TableSetupDrawChannels()
@ -2091,13 +2026,12 @@ struct ImGuiTableCellData
ImGuiTableColumnIdx Column; // Column number ImGuiTableColumnIdx Column; // Column number
}; };
// FIXME-TABLE: more transient data could be stored in a per-stacked table structure: DrawSplitter, SortSpecs, incoming RowData // FIXME-TABLE: transient data could be stored in a per-stacked table structure: DrawSplitter, SortSpecs, incoming RowData
struct ImGuiTable struct ImGuiTable
{ {
ImGuiID ID; ImGuiID ID;
ImGuiTableFlags Flags; ImGuiTableFlags Flags;
void* RawData; // Single allocation to hold Columns[], DisplayOrderToIndex[] and RowCellData[] void* RawData; // Single allocation to hold Columns[], DisplayOrderToIndex[] and RowCellData[]
ImGuiTableTempData* TempData; // Transient data while table is active. Point within g.CurrentTableStack[]
ImSpan<ImGuiTableColumn> Columns; // Point within RawData[] ImSpan<ImGuiTableColumn> Columns; // Point within RawData[]
ImSpan<ImGuiTableColumnIdx> DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1) ImSpan<ImGuiTableColumnIdx> DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1)
ImSpan<ImGuiTableCellData> RowCellData; // Point within RawData[]. Store cells background requests for current row. ImSpan<ImGuiTableCellData> RowCellData; // Point within RawData[]. Store cells background requests for current row.
@ -2149,11 +2083,22 @@ struct ImGuiTable
ImRect Bg0ClipRectForDrawCmd; // Actual ImDrawCmd clip rect for BG0/1 channel. This tends to be == OuterWindow->ClipRect at BeginTable() because output in BG0/BG1 is cpu-clipped ImRect Bg0ClipRectForDrawCmd; // Actual ImDrawCmd clip rect for BG0/1 channel. This tends to be == OuterWindow->ClipRect at BeginTable() because output in BG0/BG1 is cpu-clipped
ImRect Bg2ClipRectForDrawCmd; // Actual ImDrawCmd clip rect for BG2 channel. This tends to be a correct, tight-fit, because output to BG2 are done by widgets relying on regular ClipRect. ImRect Bg2ClipRectForDrawCmd; // Actual ImDrawCmd clip rect for BG2 channel. This tends to be a correct, tight-fit, because output to BG2 are done by widgets relying on regular ClipRect.
ImRect HostClipRect; // This is used to check if we can eventually merge our columns draw calls into the current draw call of the current window. ImRect HostClipRect; // This is used to check if we can eventually merge our columns draw calls into the current draw call of the current window.
ImRect HostBackupWorkRect; // Backup of InnerWindow->WorkRect at the end of BeginTable()
ImRect HostBackupParentWorkRect; // Backup of InnerWindow->ParentWorkRect at the end of BeginTable()
ImRect HostBackupInnerClipRect; // Backup of InnerWindow->ClipRect during PushTableBackground()/PopTableBackground() ImRect HostBackupInnerClipRect; // Backup of InnerWindow->ClipRect during PushTableBackground()/PopTableBackground()
ImVec2 HostBackupPrevLineSize; // Backup of InnerWindow->DC.PrevLineSize at the end of BeginTable()
ImVec2 HostBackupCurrLineSize; // Backup of InnerWindow->DC.CurrLineSize at the end of BeginTable()
ImVec2 HostBackupCursorMaxPos; // Backup of InnerWindow->DC.CursorMaxPos at the end of BeginTable()
ImVec2 UserOuterSize; // outer_size.x passed to BeginTable()
ImVec1 HostBackupColumnsOffset; // Backup of OuterWindow->DC.ColumnsOffset at the end of BeginTable()
float HostBackupItemWidth; // Backup of OuterWindow->DC.ItemWidth at the end of BeginTable()
int HostBackupItemWidthStackSize;// Backup of OuterWindow->DC.ItemWidthStack.Size at the end of BeginTable()
ImGuiWindow* OuterWindow; // Parent window for the table ImGuiWindow* OuterWindow; // Parent window for the table
ImGuiWindow* InnerWindow; // Window holding the table data (== OuterWindow or a child window) ImGuiWindow* InnerWindow; // Window holding the table data (== OuterWindow or a child window)
ImGuiTextBuffer ColumnsNames; // Contiguous buffer holding columns names ImGuiTextBuffer ColumnsNames; // Contiguous buffer holding columns names
ImDrawListSplitter* DrawSplitter; // Shortcut to TempData->DrawSplitter while in table. Isolate draw commands per columns to avoid switching clip rect constantly ImDrawListSplitter DrawSplitter; // We carry our own ImDrawList splitter to allow recursion (FIXME: could be stored outside, worst case we need 1 splitter per recursing table)
ImGuiTableColumnSortSpecs SortSpecsSingle;
ImVector<ImGuiTableColumnSortSpecs> SortSpecsMulti; // FIXME-OPT: Using a small-vector pattern would work be good.
ImGuiTableSortSpecs SortSpecs; // Public facing sorts specs, this is what we return in TableGetSortSpecs() ImGuiTableSortSpecs SortSpecs; // Public facing sorts specs, this is what we return in TableGetSortSpecs()
ImGuiTableColumnIdx SortSpecsCount; ImGuiTableColumnIdx SortSpecsCount;
ImGuiTableColumnIdx ColumnsEnabledCount; // Number of enabled columns (<= ColumnsCount) ImGuiTableColumnIdx ColumnsEnabledCount; // Number of enabled columns (<= ColumnsCount)
@ -2200,32 +2145,6 @@ struct ImGuiTable
IMGUI_API ~ImGuiTable() { IM_FREE(RawData); } IMGUI_API ~ImGuiTable() { IM_FREE(RawData); }
}; };
// Transient data that are only needed between BeginTable() and EndTable(), those buffers are shared (1 per level of stacked table).
// - Accessing those requires chasing an extra pointer so for very frequently used data we leave them in the main table structure.
// - We also leave out of this structure data that tend to be particularly useful for debugging/metrics.
// FIXME-TABLE: more transient data could be stored here: DrawSplitter, incoming RowData?
struct ImGuiTableTempData
{
int TableIndex; // Index in g.Tables.Buf[] pool
float LastTimeActive; // Last timestamp this structure was used
ImVec2 UserOuterSize; // outer_size.x passed to BeginTable()
ImDrawListSplitter DrawSplitter;
ImGuiTableColumnSortSpecs SortSpecsSingle;
ImVector<ImGuiTableColumnSortSpecs> SortSpecsMulti; // FIXME-OPT: Using a small-vector pattern would be good.
ImRect HostBackupWorkRect; // Backup of InnerWindow->WorkRect at the end of BeginTable()
ImRect HostBackupParentWorkRect; // Backup of InnerWindow->ParentWorkRect at the end of BeginTable()
ImVec2 HostBackupPrevLineSize; // Backup of InnerWindow->DC.PrevLineSize at the end of BeginTable()
ImVec2 HostBackupCurrLineSize; // Backup of InnerWindow->DC.CurrLineSize at the end of BeginTable()
ImVec2 HostBackupCursorMaxPos; // Backup of InnerWindow->DC.CursorMaxPos at the end of BeginTable()
ImVec1 HostBackupColumnsOffset; // Backup of OuterWindow->DC.ColumnsOffset at the end of BeginTable()
float HostBackupItemWidth; // Backup of OuterWindow->DC.ItemWidth at the end of BeginTable()
int HostBackupItemWidthStackSize;//Backup of OuterWindow->DC.ItemWidthStack.Size at the end of BeginTable()
IMGUI_API ImGuiTableTempData() { memset(this, 0, sizeof(*this)); LastTimeActive = -1.0f; }
};
// sizeof() ~ 12 // sizeof() ~ 12
struct ImGuiTableColumnSettings struct ImGuiTableColumnSettings
{ {
@ -2264,6 +2183,8 @@ struct ImGuiTableSettings
ImGuiTableColumnSettings* GetColumnSettings() { return (ImGuiTableColumnSettings*)(this + 1); } ImGuiTableColumnSettings* GetColumnSettings() { return (ImGuiTableColumnSettings*)(this + 1); }
}; };
#endif // #ifdef IMGUI_HAS_TABLE
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] ImGui internal API // [SECTION] ImGui internal API
// No guarantee of forward compatibility here! // No guarantee of forward compatibility here!
@ -2342,7 +2263,7 @@ namespace ImGui
inline ImGuiItemStatusFlags GetItemStatusFlags() { ImGuiContext& g = *GImGui; return g.CurrentWindow->DC.LastItemStatusFlags; } inline ImGuiItemStatusFlags GetItemStatusFlags() { ImGuiContext& g = *GImGui; return g.CurrentWindow->DC.LastItemStatusFlags; }
inline ImGuiID GetActiveID() { ImGuiContext& g = *GImGui; return g.ActiveId; } inline ImGuiID GetActiveID() { ImGuiContext& g = *GImGui; return g.ActiveId; }
inline ImGuiID GetFocusID() { ImGuiContext& g = *GImGui; return g.NavId; } inline ImGuiID GetFocusID() { ImGuiContext& g = *GImGui; return g.NavId; }
inline ImGuiItemFlags GetItemFlags() { ImGuiContext& g = *GImGui; return g.CurrentItemFlags; } inline ImGuiItemFlags GetItemsFlags() { ImGuiContext& g = *GImGui; return g.CurrentWindow->DC.ItemFlags; }
IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window);
IMGUI_API void SetFocusID(ImGuiID id, ImGuiWindow* window); IMGUI_API void SetFocusID(ImGuiID id, ImGuiWindow* window);
IMGUI_API void ClearActiveID(); IMGUI_API void ClearActiveID();
@ -2356,11 +2277,12 @@ namespace ImGui
// Basic Helpers for widget code // Basic Helpers for widget code
IMGUI_API void ItemSize(const ImVec2& size, float text_baseline_y = -1.0f); IMGUI_API void ItemSize(const ImVec2& size, float text_baseline_y = -1.0f);
IMGUI_API void ItemSize(const ImRect& bb, float text_baseline_y = -1.0f); IMGUI_API void ItemSize(const ImRect& bb, float text_baseline_y = -1.0f);
IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL, ImGuiItemAddFlags flags = 0); IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL);
IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id); IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id);
IMGUI_API void ItemFocusable(ImGuiWindow* window, ImGuiID id);
IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged); IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged);
IMGUI_API void SetLastItemData(ImGuiWindow* window, ImGuiID item_id, ImGuiItemStatusFlags status_flags, const ImRect& item_rect); IMGUI_API void SetLastItemData(ImGuiWindow* window, ImGuiID item_id, ImGuiItemStatusFlags status_flags, const ImRect& item_rect);
IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id); // Return true if focus is requested
IMGUI_API void FocusableItemUnregister(ImGuiWindow* window);
IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h); IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h);
IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x);
IMGUI_API void PushMultiItemsWidths(int components, float width_full); IMGUI_API void PushMultiItemsWidths(int components, float width_full);
@ -2370,15 +2292,6 @@ namespace ImGui
IMGUI_API ImVec2 GetContentRegionMaxAbs(); IMGUI_API ImVec2 GetContentRegionMaxAbs();
IMGUI_API void ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess); IMGUI_API void ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess);
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// If you have old/custom copy-and-pasted widgets that used FocusableItemRegister():
// (Old) IMGUI_VERSION_NUM < 18209: using 'ItemAdd(....)' and 'bool focused = FocusableItemRegister(...)'
// (New) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and 'bool focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0'
// Widget code are simplified as there's no need to call FocusableItemUnregister() while managing the transition from regular widget to TempInputText()
inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id) { IM_ASSERT(0); IM_UNUSED(window); IM_UNUSED(id); return false; } // -> pass ImGuiItemAddFlags_Focusable flag to ItemAdd()
inline void FocusableItemUnregister(ImGuiWindow* window) { IM_ASSERT(0); IM_UNUSED(window); } // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem
#endif
// Logging/Capture // Logging/Capture
IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name. IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name.
IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging/capturing to internal buffer IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging/capturing to internal buffer
@ -2396,7 +2309,6 @@ namespace ImGui
IMGUI_API ImGuiWindow* GetTopMostPopupModal(); IMGUI_API ImGuiWindow* GetTopMostPopupModal();
IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window); IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window);
IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy); IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy);
IMGUI_API bool BeginViewportSideBar(const char* name, ImGuiViewport* viewport, ImGuiDir dir, float size, ImGuiWindowFlags window_flags);
// Gamepad/Keyboard Navigation // Gamepad/Keyboard Navigation
IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit); IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit);
@ -2408,7 +2320,7 @@ namespace ImGui
IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f); IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f);
IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate); IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate);
IMGUI_API void ActivateItem(ImGuiID id); // Remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again. IMGUI_API void ActivateItem(ImGuiID id); // Remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again.
IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel); IMGUI_API void SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);
// Focus Scope (WIP) // Focus Scope (WIP)
// This is generally used to identify a selection set (multiple of which may be in the same window), as selection // This is generally used to identify a selection set (multiple of which may be in the same window), as selection
@ -2449,6 +2361,7 @@ namespace ImGui
// Tables: Candidates for public API // Tables: Candidates for public API
IMGUI_API void TableOpenContextMenu(int column_n = -1); IMGUI_API void TableOpenContextMenu(int column_n = -1);
IMGUI_API void TableSetColumnEnabled(int column_n, bool enabled);
IMGUI_API void TableSetColumnWidth(int column_n, float width); IMGUI_API void TableSetColumnWidth(int column_n, float width);
IMGUI_API void TableSetColumnSortDirection(int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs); IMGUI_API void TableSetColumnSortDirection(int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs);
IMGUI_API int TableGetHoveredColumn(); // May use (TableGetColumnFlags() & ImGuiTableColumnFlags_IsHovered) instead. Return hovered column. return -1 when table is not hovered. return columns_count if the unused space at the right of visible columns is hovered. IMGUI_API int TableGetHoveredColumn(); // May use (TableGetColumnFlags() & ImGuiTableColumnFlags_IsHovered) instead. Return hovered column. return -1 when table is not hovered. return columns_count if the unused space at the right of visible columns is hovered.
@ -2486,7 +2399,6 @@ namespace ImGui
IMGUI_API void TableSetColumnWidthAutoAll(ImGuiTable* table); IMGUI_API void TableSetColumnWidthAutoAll(ImGuiTable* table);
IMGUI_API void TableRemove(ImGuiTable* table); IMGUI_API void TableRemove(ImGuiTable* table);
IMGUI_API void TableGcCompactTransientBuffers(ImGuiTable* table); IMGUI_API void TableGcCompactTransientBuffers(ImGuiTable* table);
IMGUI_API void TableGcCompactTransientBuffers(ImGuiTableTempData* table);
IMGUI_API void TableGcCompactSettings(); IMGUI_API void TableGcCompactSettings();
// Tables: Settings // Tables: Settings
@ -2503,8 +2415,7 @@ namespace ImGui
IMGUI_API ImGuiTabItem* TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id); IMGUI_API ImGuiTabItem* TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id);
IMGUI_API void TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id); IMGUI_API void TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id);
IMGUI_API void TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab); IMGUI_API void TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab);
IMGUI_API void TabBarQueueReorder(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, int offset); IMGUI_API void TabBarQueueReorder(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, int dir);
IMGUI_API void TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, ImVec2 mouse_pos);
IMGUI_API bool TabBarProcessReorder(ImGuiTabBar* tab_bar); IMGUI_API bool TabBarProcessReorder(ImGuiTabBar* tab_bar);
IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags); IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags);
IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button); IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button);
@ -2551,8 +2462,7 @@ namespace ImGui
IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col); IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col);
IMGUI_API ImRect GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis); IMGUI_API ImRect GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis);
IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis); IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis);
IMGUI_API ImGuiID GetWindowResizeCornerID(ImGuiWindow* window, int n); // 0..3: corners IMGUI_API ImGuiID GetWindowResizeID(ImGuiWindow* window, int n); // 0..3: corners, 4..7: borders
IMGUI_API ImGuiID GetWindowResizeBorderID(ImGuiWindow* window, ImGuiDir dir);
IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags); IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags);
IMGUI_API bool CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value); IMGUI_API bool CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value);
IMGUI_API bool CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value); IMGUI_API bool CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value);

View File

@ -1,4 +1,4 @@
// dear imgui, v1.83 // dear imgui, v1.82 WIP
// (tables and columns code) // (tables and columns code)
/* /*
@ -8,7 +8,6 @@ Index of this file:
// [SECTION] Commentary // [SECTION] Commentary
// [SECTION] Header mess // [SECTION] Header mess
// [SECTION] Tables: Main code // [SECTION] Tables: Main code
// [SECTION] Tables: Simple accessors
// [SECTION] Tables: Row changes // [SECTION] Tables: Row changes
// [SECTION] Tables: Columns changes // [SECTION] Tables: Columns changes
// [SECTION] Tables: Columns width management // [SECTION] Tables: Columns width management
@ -74,7 +73,7 @@ Index of this file:
// (Read carefully because this is subtle but it does make sense!) // (Read carefully because this is subtle but it does make sense!)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// About 'outer_size': // About 'outer_size':
// Its meaning needs to differ slightly depending on if we are using ScrollX/ScrollY flags. // Its meaning needs to differ slightly depending of if we are using ScrollX/ScrollY flags.
// Default value is ImVec2(0.0f, 0.0f). // Default value is ImVec2(0.0f, 0.0f).
// X // X
// - outer_size.x <= 0.0f -> Right-align from window/work-rect right-most edge. With -FLT_MIN or 0.0f will align exactly on right-most edge. // - outer_size.x <= 0.0f -> Right-align from window/work-rect right-most edge. With -FLT_MIN or 0.0f will align exactly on right-most edge.
@ -91,7 +90,7 @@ Index of this file:
// Outer size is also affected by the NoHostExtendX/NoHostExtendY flags. // Outer size is also affected by the NoHostExtendX/NoHostExtendY flags.
// Important to that note how the two flags have slightly different behaviors! // Important to that note how the two flags have slightly different behaviors!
// - ImGuiTableFlags_NoHostExtendX -> Make outer width auto-fit to columns (overriding outer_size.x value). Only available when ScrollX/ScrollY are disabled and Stretch columns are not used. // - ImGuiTableFlags_NoHostExtendX -> Make outer width auto-fit to columns (overriding outer_size.x value). Only available when ScrollX/ScrollY are disabled and Stretch columns are not used.
// - ImGuiTableFlags_NoHostExtendY -> Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY is disabled. Data below the limit will be clipped and not visible. // - ImGuiTableFlags_NoHostExtendY -> Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.
// In theory ImGuiTableFlags_NoHostExtendY could be the default and any non-scrolling tables with outer_size.y != 0.0f would use exact height. // In theory ImGuiTableFlags_NoHostExtendY could be the default and any non-scrolling tables with outer_size.y != 0.0f would use exact height.
// This would be consistent but perhaps less useful and more confusing (as vertically clipped items are not easily noticeable) // This would be consistent but perhaps less useful and more confusing (as vertically clipped items are not easily noticeable)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -133,7 +132,7 @@ Index of this file:
// - the typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns. // - the typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns.
// - using mixed policies with ScrollX does not make much sense, as using Stretch columns with ScrollX does not make much sense in the first place! // - using mixed policies with ScrollX does not make much sense, as using Stretch columns with ScrollX does not make much sense in the first place!
// that is, unless 'inner_width' is passed to BeginTable() to explicitly provide a total width to layout columns in. // that is, unless 'inner_width' is passed to BeginTable() to explicitly provide a total width to layout columns in.
// - when using ImGuiTableFlags_SizingFixedSame with mixed columns, only the Fixed/Auto columns will match their widths to the width of the maximum contents. // - when using ImGuiTableFlags_SizingFixedSame with mixed columns, only the Fixed/Auto columns will match their widths to the maximum contents width.
// - when using ImGuiTableFlags_SizingStretchSame with mixed columns, only the Stretch columns will match their weight/widths. // - when using ImGuiTableFlags_SizingStretchSame with mixed columns, only the Stretch columns will match their weight/widths.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// About using column width: // About using column width:
@ -141,9 +140,9 @@ Index of this file:
// - you may use GetContentRegionAvail().x to query the width available in a given column. // - you may use GetContentRegionAvail().x to query the width available in a given column.
// - right-side alignment features such as SetNextItemWidth(-x) or PushItemWidth(-x) will rely on this width. // - right-side alignment features such as SetNextItemWidth(-x) or PushItemWidth(-x) will rely on this width.
// If the column is not resizable and has no width specified with TableSetupColumn(): // If the column is not resizable and has no width specified with TableSetupColumn():
// - its width will be automatic and be set to the max of items submitted. // - its width will be automatic and be the set to the max of items submitted.
// - therefore you generally cannot have ALL items of the columns use e.g. SetNextItemWidth(-FLT_MIN). // - therefore you generally cannot have ALL items of the columns use e.g. SetNextItemWidth(-FLT_MIN).
// - but if the column has one or more items of known/fixed size, this will become the reference width used by SetNextItemWidth(-FLT_MIN). // - but if the column has one or more item of known/fixed size, this will become the reference width used by SetNextItemWidth(-FLT_MIN).
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -162,18 +161,18 @@ Index of this file:
// - Both TableSetColumnIndex() and TableNextColumn() return true when the column is visible or performing // - Both TableSetColumnIndex() and TableNextColumn() return true when the column is visible or performing
// width measurements. Otherwise, you may skip submitting the contents of a cell/column, BUT ONLY if you know // width measurements. Otherwise, you may skip submitting the contents of a cell/column, BUT ONLY if you know
// it is not going to contribute to row height. // it is not going to contribute to row height.
// In many situations, you may skip submitting contents for every column but one (e.g. the first one). // In many situations, you may skip submitting contents for every columns but one (e.g. the first one).
// - Case A: column is not hidden by user, and at least partially in sight (most common case). // - Case A: column is not hidden by user, and at least partially in sight (most common case).
// - Case B: column is clipped / out of sight (because of scrolling or parent ClipRect): TableNextColumn() return false as a hint but we still allow layout output. // - Case B: column is clipped / out of sight (because of scrolling or parent ClipRect): TableNextColumn() return false as a hint but we still allow layout output.
// - Case C: column is hidden explicitly by the user (e.g. via the context menu, or _DefaultHide column flag, etc.). // - Case C: column is hidden explicitly by the user (e.g. via the context menu, or _DefaultHide column flag, etc.).
// //
// [A] [B] [C] // [A] [B] [C]
// TableNextColumn(): true false false -> [userland] when TableNextColumn() / TableSetColumnIndex() return false, user can skip submitting items but only if the column doesn't contribute to row height. // TableNextColumn(): true false false -> [userland] when TableNextColumn() / TableSetColumnIndex() return false, user can skip submitting items but only if the column doesn't contribute to row height.
// SkipItems: false false true -> [internal] when SkipItems is true, most widgets will early out if submitted, resulting is no layout output. // SkipItems: false false true -> [internal] when SkipItems is true, most widgets will early out if submitted, resulting is no layout output.
// ClipRect: normal zero-width zero-width -> [internal] when ClipRect is zero, ItemAdd() will return false and most widgets will early out mid-way. // ClipRect: normal zero-width zero-width -> [internal] when ClipRect is zero, ItemAdd() will return false and most widgets will early out mid-way.
// ImDrawList output: normal dummy dummy -> [internal] when using the dummy channel, ImDrawList submissions (if any) will be wasted (because cliprect is zero-width anyway). // ImDrawList output: normal dummy dummy -> [internal] when using the dummy channel, ImDrawList submissions (if any) will be wasted (because cliprect is zero-width anyway).
// //
// - We need to distinguish those cases because non-hidden columns that are clipped outside of scrolling bounds should still contribute their height to the row. // - We need distinguish those cases because non-hidden columns that are clipped outside of scrolling bounds should still contribute their height to the row.
// However, in the majority of cases, the contribution to row height is the same for all columns, or the tallest cells are known by the programmer. // However, in the majority of cases, the contribution to row height is the same for all columns, or the tallest cells are known by the programmer.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// About clipping/culling of whole Tables: // About clipping/culling of whole Tables:
@ -210,8 +209,6 @@ Index of this file:
#if defined(_MSC_VER) && _MSC_VER >= 1922 // MSVC 2019 16.2 or later #if defined(_MSC_VER) && _MSC_VER >= 1922 // MSVC 2019 16.2 or later
#pragma warning (disable: 5054) // operator '|': deprecated between enumerations of different types #pragma warning (disable: 5054) // operator '|': deprecated between enumerations of different types
#endif #endif
#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2).
#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
#endif #endif
// Clang/GCC warnings with -Weverything // Clang/GCC warnings with -Weverything
@ -238,19 +235,6 @@ Index of this file:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] Tables: Main code // [SECTION] Tables: Main code
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// - TableFixFlags() [Internal]
// - TableFindByID() [Internal]
// - BeginTable()
// - BeginTableEx() [Internal]
// - TableBeginInitMemory() [Internal]
// - TableBeginApplyRequests() [Internal]
// - TableSetupColumnFlags() [Internal]
// - TableUpdateLayout() [Internal]
// - TableUpdateBorders() [Internal]
// - EndTable()
// - TableSetupColumn()
// - TableSetupScrollFreeze()
//-----------------------------------------------------------------------------
// Configuration // Configuration
static const int TABLE_DRAW_CHANNEL_BG0 = 0; static const int TABLE_DRAW_CHANNEL_BG0 = 0;
@ -343,16 +327,6 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
if (instance_no > 0) if (instance_no > 0)
IM_ASSERT(table->ColumnsCount == columns_count && "BeginTable(): Cannot change columns count mid-frame while preserving same ID"); IM_ASSERT(table->ColumnsCount == columns_count && "BeginTable(): Cannot change columns count mid-frame while preserving same ID");
// Acquire temporary buffers
const int table_idx = g.Tables.GetIndex(table);
g.CurrentTableStackIdx++;
if (g.CurrentTableStackIdx + 1 > g.TablesTempDataStack.Size)
g.TablesTempDataStack.resize(g.CurrentTableStackIdx + 1, ImGuiTableTempData());
ImGuiTableTempData* temp_data = table->TempData = &g.TablesTempDataStack[g.CurrentTableStackIdx];
temp_data->TableIndex = table_idx;
table->DrawSplitter = &table->TempData->DrawSplitter;
table->DrawSplitter->Clear();
// Fix flags // Fix flags
table->IsDefaultSizingPolicy = (flags & ImGuiTableFlags_SizingMask_) == 0; table->IsDefaultSizingPolicy = (flags & ImGuiTableFlags_SizingMask_) == 0;
flags = TableFixFlags(flags, outer_window); flags = TableFixFlags(flags, outer_window);
@ -366,7 +340,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->ColumnsCount = columns_count; table->ColumnsCount = columns_count;
table->IsLayoutLocked = false; table->IsLayoutLocked = false;
table->InnerWidth = inner_width; table->InnerWidth = inner_width;
temp_data->UserOuterSize = outer_size; table->UserOuterSize = outer_size;
// When not using a child window, WorkRect.Max will grow as we append contents. // When not using a child window, WorkRect.Max will grow as we append contents.
if (use_child_window) if (use_child_window)
@ -415,14 +389,14 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->HostIndentX = inner_window->DC.Indent.x; table->HostIndentX = inner_window->DC.Indent.x;
table->HostClipRect = inner_window->ClipRect; table->HostClipRect = inner_window->ClipRect;
table->HostSkipItems = inner_window->SkipItems; table->HostSkipItems = inner_window->SkipItems;
temp_data->HostBackupWorkRect = inner_window->WorkRect; table->HostBackupWorkRect = inner_window->WorkRect;
temp_data->HostBackupParentWorkRect = inner_window->ParentWorkRect; table->HostBackupParentWorkRect = inner_window->ParentWorkRect;
temp_data->HostBackupColumnsOffset = outer_window->DC.ColumnsOffset; table->HostBackupColumnsOffset = outer_window->DC.ColumnsOffset;
temp_data->HostBackupPrevLineSize = inner_window->DC.PrevLineSize; table->HostBackupPrevLineSize = inner_window->DC.PrevLineSize;
temp_data->HostBackupCurrLineSize = inner_window->DC.CurrLineSize; table->HostBackupCurrLineSize = inner_window->DC.CurrLineSize;
temp_data->HostBackupCursorMaxPos = inner_window->DC.CursorMaxPos; table->HostBackupCursorMaxPos = inner_window->DC.CursorMaxPos;
temp_data->HostBackupItemWidth = outer_window->DC.ItemWidth; table->HostBackupItemWidth = outer_window->DC.ItemWidth;
temp_data->HostBackupItemWidthStackSize = outer_window->DC.ItemWidthStack.Size; table->HostBackupItemWidthStackSize = outer_window->DC.ItemWidthStack.Size;
inner_window->DC.PrevLineSize = inner_window->DC.CurrLineSize = ImVec2(0.0f, 0.0f); inner_window->DC.PrevLineSize = inner_window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
// Padding and Spacing // Padding and Spacing
@ -465,6 +439,8 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->BorderColorLight = GetColorU32(ImGuiCol_TableBorderLight); table->BorderColorLight = GetColorU32(ImGuiCol_TableBorderLight);
// Make table current // Make table current
const int table_idx = g.Tables.GetIndex(table);
g.CurrentTableStack.push_back(ImGuiPtrOrIndex(table_idx));
g.CurrentTable = table; g.CurrentTable = table;
outer_window->DC.CurrentTableIdx = table_idx; outer_window->DC.CurrentTableIdx = table_idx;
if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly. if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly.
@ -477,18 +453,13 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
if (table_idx >= g.TablesLastTimeActive.Size) if (table_idx >= g.TablesLastTimeActive.Size)
g.TablesLastTimeActive.resize(table_idx + 1, -1.0f); g.TablesLastTimeActive.resize(table_idx + 1, -1.0f);
g.TablesLastTimeActive[table_idx] = (float)g.Time; g.TablesLastTimeActive[table_idx] = (float)g.Time;
temp_data->LastTimeActive = (float)g.Time;
table->MemoryCompacted = false; table->MemoryCompacted = false;
// Setup memory buffer (clear data if columns count changed) // Setup memory buffer (clear data if columns count changed)
ImGuiTableColumn* old_columns_to_preserve = NULL; const int stored_size = table->Columns.size();
void* old_columns_raw_data = NULL; if (stored_size != 0 && stored_size != columns_count)
const int old_columns_count = table->Columns.size();
if (old_columns_count != 0 && old_columns_count != columns_count)
{ {
// Attempt to preserve width on column count change (#4046) IM_FREE(table->RawData);
old_columns_to_preserve = table->Columns.Data;
old_columns_raw_data = table->RawData;
table->RawData = NULL; table->RawData = NULL;
} }
if (table->RawData == NULL) if (table->RawData == NULL)
@ -511,24 +482,14 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
for (int n = 0; n < columns_count; n++) for (int n = 0; n < columns_count; n++)
{ {
ImGuiTableColumn* column = &table->Columns[n]; ImGuiTableColumn* column = &table->Columns[n];
if (old_columns_to_preserve && n < old_columns_count) float width_auto = column->WidthAuto;
{ *column = ImGuiTableColumn();
// FIXME: We don't attempt to preserve column order in this path. column->WidthAuto = width_auto;
*column = old_columns_to_preserve[n]; column->IsPreserveWidthAuto = true; // Preserve WidthAuto when reinitializing a live table: not technically necessary but remove a visible flicker
}
else
{
float width_auto = column->WidthAuto;
*column = ImGuiTableColumn();
column->WidthAuto = width_auto;
column->IsPreserveWidthAuto = true; // Preserve WidthAuto when reinitializing a live table: not technically necessary but remove a visible flicker
column->IsEnabled = column->IsEnabledNextFrame = true;
}
column->DisplayOrder = table->DisplayOrderToIndex[n] = (ImGuiTableColumnIdx)n; column->DisplayOrder = table->DisplayOrderToIndex[n] = (ImGuiTableColumnIdx)n;
column->IsEnabled = column->IsEnabledNextFrame = true;
} }
} }
if (old_columns_raw_data)
IM_FREE(old_columns_raw_data);
// Load settings // Load settings
if (table->IsSettingsRequestLoad) if (table->IsSettingsRequestLoad)
@ -674,7 +635,7 @@ static void TableSetupColumnFlags(ImGuiTable* table, ImGuiTableColumn* column, I
{ {
IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiTableColumnFlags_WidthMask_)); // Check that only 1 of each set is used. IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiTableColumnFlags_WidthMask_)); // Check that only 1 of each set is used.
} }
// Resize // Resize
if ((table->Flags & ImGuiTableFlags_Resizable) == 0) if ((table->Flags & ImGuiTableFlags_Resizable) == 0)
flags |= ImGuiTableColumnFlags_NoResize; flags |= ImGuiTableColumnFlags_NoResize;
@ -847,7 +808,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// Apply same widths policy // Apply same widths policy
float width_auto = column->WidthAuto; float width_auto = column->WidthAuto;
if (table_sizing_policy == ImGuiTableFlags_SizingFixedSame && (column->AutoFitQueue != 0x00 || !column_is_resizable)) if (table_sizing_policy == ImGuiTableFlags_SizingFixedSame && (column->AutoFitQueue != 0x00 || !column_is_resizable))
width_auto = fixed_max_width_auto; width_auto = fixed_max_width_auto;
// Apply automatic width // Apply automatic width
// Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!) // Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!)
@ -1126,7 +1087,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// Initial state // Initial state
ImGuiWindow* inner_window = table->InnerWindow; ImGuiWindow* inner_window = table->InnerWindow;
if (table->Flags & ImGuiTableFlags_NoClip) if (table->Flags & ImGuiTableFlags_NoClip)
table->DrawSplitter->SetCurrentChannel(inner_window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP); table->DrawSplitter.SetCurrentChannel(inner_window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP);
else else
inner_window->DrawList->PushClipRect(inner_window->ClipRect.Min, inner_window->ClipRect.Max, false); inner_window->DrawList->PushClipRect(inner_window->ClipRect.Min, inner_window->ClipRect.Max, false);
} }
@ -1214,7 +1175,6 @@ void ImGui::EndTable()
const ImGuiTableFlags flags = table->Flags; const ImGuiTableFlags flags = table->Flags;
ImGuiWindow* inner_window = table->InnerWindow; ImGuiWindow* inner_window = table->InnerWindow;
ImGuiWindow* outer_window = table->OuterWindow; ImGuiWindow* outer_window = table->OuterWindow;
ImGuiTableTempData* temp_data = table->TempData;
IM_ASSERT(inner_window == g.CurrentWindow); IM_ASSERT(inner_window == g.CurrentWindow);
IM_ASSERT(outer_window == inner_window || outer_window == inner_window->ParentWindow); IM_ASSERT(outer_window == inner_window || outer_window == inner_window->ParentWindow);
@ -1227,9 +1187,9 @@ void ImGui::EndTable()
TableOpenContextMenu((int)table->HoveredColumnBody); TableOpenContextMenu((int)table->HoveredColumnBody);
// Finalize table height // Finalize table height
inner_window->DC.PrevLineSize = temp_data->HostBackupPrevLineSize; inner_window->DC.PrevLineSize = table->HostBackupPrevLineSize;
inner_window->DC.CurrLineSize = temp_data->HostBackupCurrLineSize; inner_window->DC.CurrLineSize = table->HostBackupCurrLineSize;
inner_window->DC.CursorMaxPos = temp_data->HostBackupCursorMaxPos; inner_window->DC.CursorMaxPos = table->HostBackupCursorMaxPos;
const float inner_content_max_y = table->RowPosY2; const float inner_content_max_y = table->RowPosY2;
IM_ASSERT(table->RowPosY2 == inner_window->DC.CursorPos.y); IM_ASSERT(table->RowPosY2 == inner_window->DC.CursorPos.y);
if (inner_window != outer_window) if (inner_window != outer_window)
@ -1276,11 +1236,10 @@ void ImGui::EndTable()
#endif #endif
// Flatten channels and merge draw calls // Flatten channels and merge draw calls
ImDrawListSplitter* splitter = table->DrawSplitter; table->DrawSplitter.SetCurrentChannel(inner_window->DrawList, 0);
splitter->SetCurrentChannel(inner_window->DrawList, 0);
if ((table->Flags & ImGuiTableFlags_NoClip) == 0) if ((table->Flags & ImGuiTableFlags_NoClip) == 0)
TableMergeDrawChannels(table); TableMergeDrawChannels(table);
splitter->Merge(inner_window->DrawList); table->DrawSplitter.Merge(inner_window->DrawList);
// Update ColumnsAutoFitWidth to get us ahead for host using our size to auto-resize without waiting for next BeginTable() // Update ColumnsAutoFitWidth to get us ahead for host using our size to auto-resize without waiting for next BeginTable()
const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1); const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1);
@ -1322,18 +1281,18 @@ void ImGui::EndTable()
// Pop from id stack // Pop from id stack
IM_ASSERT_USER_ERROR(inner_window->IDStack.back() == table->ID + table->InstanceCurrent, "Mismatching PushID/PopID!"); IM_ASSERT_USER_ERROR(inner_window->IDStack.back() == table->ID + table->InstanceCurrent, "Mismatching PushID/PopID!");
IM_ASSERT_USER_ERROR(outer_window->DC.ItemWidthStack.Size >= temp_data->HostBackupItemWidthStackSize, "Too many PopItemWidth!"); IM_ASSERT_USER_ERROR(outer_window->DC.ItemWidthStack.Size >= table->HostBackupItemWidthStackSize, "Too many PopItemWidth!");
PopID(); PopID();
// Restore window data that we modified // Restore window data that we modified
const ImVec2 backup_outer_max_pos = outer_window->DC.CursorMaxPos; const ImVec2 backup_outer_max_pos = outer_window->DC.CursorMaxPos;
inner_window->WorkRect = temp_data->HostBackupWorkRect; inner_window->WorkRect = table->HostBackupWorkRect;
inner_window->ParentWorkRect = temp_data->HostBackupParentWorkRect; inner_window->ParentWorkRect = table->HostBackupParentWorkRect;
inner_window->SkipItems = table->HostSkipItems; inner_window->SkipItems = table->HostSkipItems;
outer_window->DC.CursorPos = table->OuterRect.Min; outer_window->DC.CursorPos = table->OuterRect.Min;
outer_window->DC.ItemWidth = temp_data->HostBackupItemWidth; outer_window->DC.ItemWidth = table->HostBackupItemWidth;
outer_window->DC.ItemWidthStack.Size = temp_data->HostBackupItemWidthStackSize; outer_window->DC.ItemWidthStack.Size = table->HostBackupItemWidthStackSize;
outer_window->DC.ColumnsOffset = temp_data->HostBackupColumnsOffset; outer_window->DC.ColumnsOffset = table->HostBackupColumnsOffset;
// Layout in outer window // Layout in outer window
// (FIXME: To allow auto-fit and allow desirable effect of SameLine() we dissociate 'used' vs 'ideal' size by overriding // (FIXME: To allow auto-fit and allow desirable effect of SameLine() we dissociate 'used' vs 'ideal' size by overriding
@ -1356,20 +1315,20 @@ void ImGui::EndTable()
IM_ASSERT((table->Flags & ImGuiTableFlags_ScrollX) == 0); IM_ASSERT((table->Flags & ImGuiTableFlags_ScrollX) == 0);
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth); outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth);
} }
else if (temp_data->UserOuterSize.x <= 0.0f) else if (table->UserOuterSize.x <= 0.0f)
{ {
const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.x : 0.0f; const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.x : 0.0f;
outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth + decoration_size - temp_data->UserOuterSize.x); outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth + decoration_size - table->UserOuterSize.x);
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth)); outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth));
} }
else else
{ {
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, table->OuterRect.Max.x); outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, table->OuterRect.Max.x);
} }
if (temp_data->UserOuterSize.y <= 0.0f) if (table->UserOuterSize.y <= 0.0f)
{ {
const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollY) ? inner_window->ScrollbarSizes.y : 0.0f; const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollY) ? inner_window->ScrollbarSizes.y : 0.0f;
outer_window->DC.IdealMaxPos.y = ImMax(outer_window->DC.IdealMaxPos.y, inner_content_max_y + decoration_size - temp_data->UserOuterSize.y); outer_window->DC.IdealMaxPos.y = ImMax(outer_window->DC.IdealMaxPos.y, inner_content_max_y + decoration_size - table->UserOuterSize.y);
outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(table->OuterRect.Max.y, inner_content_max_y)); outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(table->OuterRect.Max.y, inner_content_max_y));
} }
else else
@ -1385,15 +1344,8 @@ void ImGui::EndTable()
// Clear or restore current table, if any // Clear or restore current table, if any
IM_ASSERT(g.CurrentWindow == outer_window && g.CurrentTable == table); IM_ASSERT(g.CurrentWindow == outer_window && g.CurrentTable == table);
IM_ASSERT(g.CurrentTableStackIdx >= 0); g.CurrentTableStack.pop_back();
g.CurrentTableStackIdx--; g.CurrentTable = g.CurrentTableStack.Size ? g.Tables.GetByIndex(g.CurrentTableStack.back().Index) : NULL;
temp_data = g.CurrentTableStackIdx >= 0 ? &g.TablesTempDataStack[g.CurrentTableStackIdx] : NULL;
g.CurrentTable = temp_data ? g.Tables.GetByIndex(temp_data->TableIndex) : NULL;
if (g.CurrentTable)
{
g.CurrentTable->TempData = temp_data;
g.CurrentTable->DrawSplitter = &temp_data->DrawSplitter;
}
outer_window->DC.CurrentTableIdx = g.CurrentTable ? g.Tables.GetIndex(g.CurrentTable) : -1; outer_window->DC.CurrentTableIdx = g.CurrentTable ? g.Tables.GetIndex(g.CurrentTable) : -1;
} }
@ -1483,20 +1435,6 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
table->IsUnfrozenRows = (table->FreezeRowsCount == 0); // Make sure this is set before TableUpdateLayout() so ImGuiListClipper can benefit from it.b table->IsUnfrozenRows = (table->FreezeRowsCount == 0); // Make sure this is set before TableUpdateLayout() so ImGuiListClipper can benefit from it.b
} }
//-----------------------------------------------------------------------------
// [SECTION] Tables: Simple accessors
//-----------------------------------------------------------------------------
// - TableGetColumnCount()
// - TableGetColumnName()
// - TableGetColumnName() [Internal]
// - TableSetColumnEnabled() [Internal]
// - TableGetColumnFlags()
// - TableGetCellBgRect() [Internal]
// - TableGetColumnResizeID() [Internal]
// - TableGetHoveredColumn() [Internal]
// - TableSetBgColor()
//-----------------------------------------------------------------------------
int ImGui::TableGetColumnCount() int ImGui::TableGetColumnCount()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -1525,9 +1463,6 @@ const char* ImGui::TableGetColumnName(const ImGuiTable* table, int column_n)
return &table->ColumnsNames.Buf[column->NameOffset]; return &table->ColumnsNames.Buf[column->NameOffset];
} }
// Request enabling/disabling a column (often perceived as "showing/hiding" from users point of view)
// Note that end-user can use the context menu to change this themselves (right-click in headers, or right-click in columns body with ImGuiTableFlags_ContextMenuInBody)
// Request will be applied during next layout, which happens on the first call to TableNextRow() after BeginTable()
// For the getter you can use (TableGetColumnFlags() & ImGuiTableColumnFlags_IsEnabled) // For the getter you can use (TableGetColumnFlags() & ImGuiTableColumnFlags_IsEnabled)
void ImGui::TableSetColumnEnabled(int column_n, bool enabled) void ImGui::TableSetColumnEnabled(int column_n, bool enabled)
{ {
@ -1766,7 +1701,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
// always followed by a change of clipping rectangle we perform the smallest overwrite possible here. // always followed by a change of clipping rectangle we perform the smallest overwrite possible here.
if ((table->Flags & ImGuiTableFlags_NoClip) == 0) if ((table->Flags & ImGuiTableFlags_NoClip) == 0)
window->DrawList->_CmdHeader.ClipRect = table->Bg0ClipRectForDrawCmd.ToVec4(); window->DrawList->_CmdHeader.ClipRect = table->Bg0ClipRectForDrawCmd.ToVec4();
table->DrawSplitter->SetCurrentChannel(window->DrawList, TABLE_DRAW_CHANNEL_BG0); table->DrawSplitter.SetCurrentChannel(window->DrawList, TABLE_DRAW_CHANNEL_BG0);
} }
// Draw row background // Draw row background
@ -1838,7 +1773,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
// Update cliprect ahead of TableBeginCell() so clipper can access to new ClipRect->Min.y // Update cliprect ahead of TableBeginCell() so clipper can access to new ClipRect->Min.y
SetWindowClipRectBeforeSetChannel(window, table->Columns[0].ClipRect); SetWindowClipRectBeforeSetChannel(window, table->Columns[0].ClipRect);
table->DrawSplitter->SetCurrentChannel(window->DrawList, table->Columns[0].DrawChannelCurrent); table->DrawSplitter.SetCurrentChannel(window->DrawList, table->Columns[0].DrawChannelCurrent);
} }
if (!(table->RowFlags & ImGuiTableRowFlags_Headers)) if (!(table->RowFlags & ImGuiTableRowFlags_Headers))
@ -1953,14 +1888,14 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
if (table->Flags & ImGuiTableFlags_NoClip) if (table->Flags & ImGuiTableFlags_NoClip)
{ {
// FIXME: if we end up drawing all borders/bg in EndTable, could remove this and just assert that channel hasn't changed. // FIXME: if we end up drawing all borders/bg in EndTable, could remove this and just assert that channel hasn't changed.
table->DrawSplitter->SetCurrentChannel(window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP); table->DrawSplitter.SetCurrentChannel(window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP);
//IM_ASSERT(table->DrawSplitter._Current == TABLE_DRAW_CHANNEL_NOCLIP); //IM_ASSERT(table->DrawSplitter._Current == TABLE_DRAW_CHANNEL_NOCLIP);
} }
else else
{ {
// FIXME-TABLE: Could avoid this if draw channel is dummy channel? // FIXME-TABLE: Could avoid this if draw channel is dummy channel?
SetWindowClipRectBeforeSetChannel(window, column->ClipRect); SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent); table->DrawSplitter.SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
} }
// Logging // Logging
@ -2208,7 +2143,7 @@ void ImGui::TablePushBackgroundChannel()
// Optimization: avoid SetCurrentChannel() + PushClipRect() // Optimization: avoid SetCurrentChannel() + PushClipRect()
table->HostBackupInnerClipRect = window->ClipRect; table->HostBackupInnerClipRect = window->ClipRect;
SetWindowClipRectBeforeSetChannel(window, table->Bg2ClipRectForDrawCmd); SetWindowClipRectBeforeSetChannel(window, table->Bg2ClipRectForDrawCmd);
table->DrawSplitter->SetCurrentChannel(window->DrawList, table->Bg2DrawChannelCurrent); table->DrawSplitter.SetCurrentChannel(window->DrawList, table->Bg2DrawChannelCurrent);
} }
void ImGui::TablePopBackgroundChannel() void ImGui::TablePopBackgroundChannel()
@ -2220,7 +2155,7 @@ void ImGui::TablePopBackgroundChannel()
// Optimization: avoid PopClipRect() + SetCurrentChannel() // Optimization: avoid PopClipRect() + SetCurrentChannel()
SetWindowClipRectBeforeSetChannel(window, table->HostBackupInnerClipRect); SetWindowClipRectBeforeSetChannel(window, table->HostBackupInnerClipRect);
table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent); table->DrawSplitter.SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
} }
// Allocate draw channels. Called by TableUpdateLayout() // Allocate draw channels. Called by TableUpdateLayout()
@ -2246,7 +2181,7 @@ void ImGui::TableSetupDrawChannels(ImGuiTable* table)
const int channels_for_bg = 1 + 1 * freeze_row_multiplier; const int channels_for_bg = 1 + 1 * freeze_row_multiplier;
const int channels_for_dummy = (table->ColumnsEnabledCount < table->ColumnsCount || table->VisibleMaskByIndex != table->EnabledMaskByIndex) ? +1 : 0; const int channels_for_dummy = (table->ColumnsEnabledCount < table->ColumnsCount || table->VisibleMaskByIndex != table->EnabledMaskByIndex) ? +1 : 0;
const int channels_total = channels_for_bg + (channels_for_row * freeze_row_multiplier) + channels_for_dummy; const int channels_total = channels_for_bg + (channels_for_row * freeze_row_multiplier) + channels_for_dummy;
table->DrawSplitter->Split(table->InnerWindow->DrawList, channels_total); table->DrawSplitter.Split(table->InnerWindow->DrawList, channels_total);
table->DummyDrawChannel = (ImGuiTableDrawChannelIdx)((channels_for_dummy > 0) ? channels_total - 1 : -1); table->DummyDrawChannel = (ImGuiTableDrawChannelIdx)((channels_for_dummy > 0) ? channels_total - 1 : -1);
table->Bg2DrawChannelCurrent = TABLE_DRAW_CHANNEL_BG2_FROZEN; table->Bg2DrawChannelCurrent = TABLE_DRAW_CHANNEL_BG2_FROZEN;
table->Bg2DrawChannelUnfrozen = (ImGuiTableDrawChannelIdx)((table->FreezeRowsCount > 0) ? 2 + channels_for_row : TABLE_DRAW_CHANNEL_BG2_FROZEN); table->Bg2DrawChannelUnfrozen = (ImGuiTableDrawChannelIdx)((table->FreezeRowsCount > 0) ? 2 + channels_for_row : TABLE_DRAW_CHANNEL_BG2_FROZEN);
@ -2310,7 +2245,7 @@ void ImGui::TableSetupDrawChannels(ImGuiTable* table)
void ImGui::TableMergeDrawChannels(ImGuiTable* table) void ImGui::TableMergeDrawChannels(ImGuiTable* table)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImDrawListSplitter* splitter = table->DrawSplitter; ImDrawListSplitter* splitter = &table->DrawSplitter;
const bool has_freeze_v = (table->FreezeRowsCount > 0); const bool has_freeze_v = (table->FreezeRowsCount > 0);
const bool has_freeze_h = (table->FreezeColumnsCount > 0); const bool has_freeze_h = (table->FreezeColumnsCount > 0);
IM_ASSERT(splitter->_Current == 0); IM_ASSERT(splitter->_Current == 0);
@ -2321,11 +2256,10 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
ImRect ClipRect; ImRect ClipRect;
int ChannelsCount; int ChannelsCount;
ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> ChannelsMask; ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> ChannelsMask;
MergeGroup() { ChannelsCount = 0; }
}; };
int merge_group_mask = 0x00; int merge_group_mask = 0x00;
MergeGroup merge_groups[4]; MergeGroup merge_groups[4];
memset(merge_groups, 0, sizeof(merge_groups));
// 1. Scan channels and take note of those which can be merged // 1. Scan channels and take note of those which can be merged
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
@ -2403,6 +2337,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
g.DrawChannelsTempMergeBuffer.resize(splitter->_Count - LEADING_DRAW_CHANNELS); // Use shared temporary storage so the allocation gets amortized g.DrawChannelsTempMergeBuffer.resize(splitter->_Count - LEADING_DRAW_CHANNELS); // Use shared temporary storage so the allocation gets amortized
ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer.Data; ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer.Data;
ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> remaining_mask; // We need 132-bit of storage ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> remaining_mask; // We need 132-bit of storage
remaining_mask.ClearAllBits();
remaining_mask.SetBitRange(LEADING_DRAW_CHANNELS, splitter->_Count); remaining_mask.SetBitRange(LEADING_DRAW_CHANNELS, splitter->_Count);
remaining_mask.ClearBit(table->Bg2DrawChannelUnfrozen); remaining_mask.ClearBit(table->Bg2DrawChannelUnfrozen);
IM_ASSERT(has_freeze_v == false || table->Bg2DrawChannelUnfrozen != TABLE_DRAW_CHANNEL_BG2_FROZEN); IM_ASSERT(has_freeze_v == false || table->Bg2DrawChannelUnfrozen != TABLE_DRAW_CHANNEL_BG2_FROZEN);
@ -2481,7 +2416,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
return; return;
ImDrawList* inner_drawlist = inner_window->DrawList; ImDrawList* inner_drawlist = inner_window->DrawList;
table->DrawSplitter->SetCurrentChannel(inner_drawlist, TABLE_DRAW_CHANNEL_BG0); table->DrawSplitter.SetCurrentChannel(inner_drawlist, TABLE_DRAW_CHANNEL_BG0);
inner_drawlist->PushClipRect(table->Bg0ClipRectForDrawCmd.Min, table->Bg0ClipRectForDrawCmd.Max, false); inner_drawlist->PushClipRect(table->Bg0ClipRectForDrawCmd.Min, table->Bg0ClipRectForDrawCmd.Max, false);
// Draw inner border and resizing feedback // Draw inner border and resizing feedback
@ -2741,22 +2676,20 @@ void ImGui::TableSortSpecsBuild(ImGuiTable* table)
TableSortSpecsSanitize(table); TableSortSpecsSanitize(table);
// Write output // Write output
ImGuiTableTempData* temp_data = table->TempData; table->SortSpecsMulti.resize(table->SortSpecsCount <= 1 ? 0 : table->SortSpecsCount);
temp_data->SortSpecsMulti.resize(table->SortSpecsCount <= 1 ? 0 : table->SortSpecsCount); ImGuiTableColumnSortSpecs* sort_specs = (table->SortSpecsCount == 0) ? NULL : (table->SortSpecsCount == 1) ? &table->SortSpecsSingle : table->SortSpecsMulti.Data;
ImGuiTableColumnSortSpecs* sort_specs = (table->SortSpecsCount == 0) ? NULL : (table->SortSpecsCount == 1) ? &temp_data->SortSpecsSingle : temp_data->SortSpecsMulti.Data; for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
if (sort_specs != NULL) {
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) ImGuiTableColumn* column = &table->Columns[column_n];
{ if (column->SortOrder == -1)
ImGuiTableColumn* column = &table->Columns[column_n]; continue;
if (column->SortOrder == -1) IM_ASSERT(column->SortOrder < table->SortSpecsCount);
continue; ImGuiTableColumnSortSpecs* sort_spec = &sort_specs[column->SortOrder];
IM_ASSERT(column->SortOrder < table->SortSpecsCount); sort_spec->ColumnUserID = column->UserID;
ImGuiTableColumnSortSpecs* sort_spec = &sort_specs[column->SortOrder]; sort_spec->ColumnIndex = (ImGuiTableColumnIdx)column_n;
sort_spec->ColumnUserID = column->UserID; sort_spec->SortOrder = (ImGuiTableColumnIdx)column->SortOrder;
sort_spec->ColumnIndex = (ImGuiTableColumnIdx)column_n; sort_spec->SortDirection = column->SortDirection;
sort_spec->SortOrder = (ImGuiTableColumnIdx)column->SortOrder; }
sort_spec->SortDirection = column->SortDirection;
}
table->SortSpecs.Specs = sort_specs; table->SortSpecs.Specs = sort_specs;
table->SortSpecs.SpecsCount = table->SortSpecsCount; table->SortSpecs.SpecsCount = table->SortSpecsCount;
table->SortSpecs.SpecsDirty = true; // Mark as dirty for user table->SortSpecs.SpecsDirty = true; // Mark as dirty for user
@ -3385,9 +3318,6 @@ static void TableSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandle
for (int column_n = 0; column_n < settings->ColumnsCount; column_n++, column++) for (int column_n = 0; column_n < settings->ColumnsCount; column_n++, column++)
{ {
// "Column 0 UserID=0x42AD2D21 Width=100 Visible=1 Order=0 Sort=0v" // "Column 0 UserID=0x42AD2D21 Width=100 Visible=1 Order=0 Sort=0v"
bool save_column = column->UserID != 0 || save_size || save_visible || save_order || (save_sort && column->SortOrder != -1);
if (!save_column)
continue;
buf->appendf("Column %-2d", column_n); buf->appendf("Column %-2d", column_n);
if (column->UserID != 0) buf->appendf(" UserID=%08X", column->UserID); if (column->UserID != 0) buf->appendf(" UserID=%08X", column->UserID);
if (save_size && column->IsStretch) buf->appendf(" Weight=%.4f", column->WidthOrWeight); if (save_size && column->IsStretch) buf->appendf(" Weight=%.4f", column->WidthOrWeight);
@ -3441,6 +3371,8 @@ void ImGui::TableGcCompactTransientBuffers(ImGuiTable* table)
//IMGUI_DEBUG_LOG("TableGcCompactTransientBuffers() id=0x%08X\n", table->ID); //IMGUI_DEBUG_LOG("TableGcCompactTransientBuffers() id=0x%08X\n", table->ID);
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_ASSERT(table->MemoryCompacted == false); IM_ASSERT(table->MemoryCompacted == false);
table->DrawSplitter.ClearFreeMemory();
table->SortSpecsMulti.clear();
table->SortSpecs.Specs = NULL; table->SortSpecs.Specs = NULL;
table->IsSortSpecsDirty = true; table->IsSortSpecsDirty = true;
table->ColumnsNames.clear(); table->ColumnsNames.clear();
@ -3450,13 +3382,6 @@ void ImGui::TableGcCompactTransientBuffers(ImGuiTable* table)
g.TablesLastTimeActive[g.Tables.GetIndex(table)] = -1.0f; g.TablesLastTimeActive[g.Tables.GetIndex(table)] = -1.0f;
} }
void ImGui::TableGcCompactTransientBuffers(ImGuiTableTempData* temp_data)
{
temp_data->DrawSplitter.ClearFreeMemory();
temp_data->SortSpecsMulti.clear();
temp_data->LastTimeActive = -1.0f;
}
// Compact and remove unused settings data (currently only used by TestEngine) // Compact and remove unused settings data (currently only used by TestEngine)
void ImGui::TableGcCompactSettings() void ImGui::TableGcCompactSettings()
{ {

File diff suppressed because it is too large Load Diff

View File

@ -740,7 +740,9 @@ retry:
if (c == '\n' && state->single_line) if (c == '\n' && state->single_line)
break; break;
if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) { if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)
&& (STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE) // [DEAR IMGUI]
) {
stb_text_makeundo_replace(str, state, state->cursor, 1, 1); stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1); STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {

View File

@ -28,10 +28,3 @@ See https://gist.github.com/ocornut/b3a9ecf13502fd818799a452969649ad
Small, thin anti-aliased fonts are typically benefiting a lots from Freetype's hinting: Small, thin anti-aliased fonts are typically benefiting a lots from Freetype's hinting:
![comparing_font_rasterizers](https://user-images.githubusercontent.com/8225057/107550178-fef87f00-6bd0-11eb-8d09-e2edb2f0ccfc.gif) ![comparing_font_rasterizers](https://user-images.githubusercontent.com/8225057/107550178-fef87f00-6bd0-11eb-8d09-e2edb2f0ccfc.gif)
### Colorful glyphs/emojis
You can use the `ImGuiFreeTypeBuilderFlags_LoadColor` flag to load certain colorful glyphs. See
["Using Colorful Glyphs/Emojis"](https://github.com/ocornut/imgui/edit/master/docs/FONTS.md#using-colorful-glyphsemojis) section of FONTS.md.
![colored glyphs](https://user-images.githubusercontent.com/8225057/106171241-9dc4ba80-6191-11eb-8a69-ca1467b206d1.png)

View File

@ -1,7 +1,7 @@
// dear imgui: FreeType font builder (used as a replacement for the stb_truetype builder) // dear imgui: FreeType font builder (used as a replacement for the stb_truetype builder)
// (code) // (code)
// Get the latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype // Get latest version at https://github.com/ocornut/imgui/tree/master/misc/freetype
// Original code by @vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained since 2019 by @ocornut. // Original code by @vuhdo (Aleksei Skriabin). Improvements by @mikesart. Maintained since 2019 by @ocornut.
// CHANGELOG // CHANGELOG