Merge branch 'master' into docking

# Conflicts:
#	imgui.cpp
#	imgui_demo.cpp
This commit is contained in:
omar 2019-04-16 13:12:01 +02:00
commit 655ebe4eaf
13 changed files with 104 additions and 63 deletions

View File

@ -114,6 +114,7 @@ Other Changes:
- GetMouseDragDelta(): verify that mouse positions are valid otherwise returns zero. - GetMouseDragDelta(): verify that mouse positions are valid otherwise returns zero.
- Inputs: Also add support for horizontal scroll with Shift+Mouse Wheel. (#2424, #1463) [@LucaRood] - Inputs: Also add support for horizontal scroll with Shift+Mouse Wheel. (#2424, #1463) [@LucaRood]
- PlotLines, PlotHistogram: Ignore NaN values when calculating min/max bounds. (#2485) - PlotLines, PlotHistogram: Ignore NaN values when calculating min/max bounds. (#2485)
- Window: Window close button is horizontally aligned with style.FramePadding.x.
- Misc: Added IM_MALLOC/IM_FREE macros mimicking IM_NEW/IM_DELETE so user doesn't need to revert - Misc: Added IM_MALLOC/IM_FREE macros mimicking IM_NEW/IM_DELETE so user doesn't need to revert
to using the ImGui::MemAlloc()/MemFree() calls directly. to using the ImGui::MemAlloc()/MemFree() calls directly.
- Examples: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized - Examples: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized
@ -125,6 +126,7 @@ Other Changes:
- Examples: Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like. - Examples: Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like.
- Examples: Vulkan: Added ImGui_ImplVulkan_SetMinImageCount() to change min image count at runtime. (#2071) [@nathanvoglsam] - Examples: Vulkan: Added ImGui_ImplVulkan_SetMinImageCount() to change min image count at runtime. (#2071) [@nathanvoglsam]
- Examples: DirectX9: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). (#2454) - Examples: DirectX9: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). (#2454)
- Examples: DirectX10/11/12, Allegro, Marmalade: Render functions early out when display size is zero (minimized). (#2496)
- Examples: GLUT: Fixed existing FreeGLUT example to work with regular GLUT. (#2465) [@andrewwillmott] - Examples: GLUT: Fixed existing FreeGLUT example to work with regular GLUT. (#2465) [@andrewwillmott]
- Examples: GLUT: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h. (#2465) [@andrewwillmott] - Examples: GLUT: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h. (#2465) [@andrewwillmott]
- Examples: GLUT: Made io.DeltaTime always > 0. (#2430) - Examples: GLUT: Made io.DeltaTime always > 0. (#2430)

1
examples/.gitignore vendored
View File

@ -25,6 +25,7 @@ project.xcworkspace
xcuserdata xcuserdata
## Emscripten output ## Emscripten output
*.o.tmp
*.out.js *.out.js
*.out.wasm *.out.wasm
example_emscripten/example_emscripten.* example_emscripten/example_emscripten.*

View File

@ -24,10 +24,12 @@ UNAME_S := $(shell uname -s)
EMS = -s USE_SDL=2 -s WASM=1 EMS = -s USE_SDL=2 -s WASM=1
EMS += -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN_TRAP_MODE=clamp EMS += -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN_TRAP_MODE=clamp
EMS += -s DISABLE_EXCEPTION_CATCHING=1 -s NO_EXIT_RUNTIME=0 EMS += -s DISABLE_EXCEPTION_CATCHING=1 -s NO_EXIT_RUNTIME=0
EMS += -s ASSERTIONS=1 -s SAFE_HEAP=1 EMS += -s ASSERTIONS=1 -s NO_FILESYSTEM=1
#EMS += -s SAFE_HEAP=1 ## Adds overhead
CPPFLAGS = -I../ -I../../ CPPFLAGS = -I../ -I../../
CPPFLAGS += -g -Wall -Wformat -O3 #CPPFLAGS += -g
CPPFLAGS += -Wall -Wformat -Os
CPPFLAGS += $(EMS) CPPFLAGS += $(EMS)
LIBS = $(EMS) LIBS = $(EMS)
LDFLAGS = --shell-file shell_minimal.html LDFLAGS = --shell-file shell_minimal.html

View File

@ -14,7 +14,7 @@
#include <SDL.h> #include <SDL.h>
#include <SDL_opengles2.h> #include <SDL_opengles2.h>
// Emscripten requires to have full control over the main loop. We're going to store our SDL book-keeping variables globally. // Emscripten requires to have full control over the main loop. We're going to store our SDL book-keeping variables globally.
// Having a single function that acts as a loop prevents us to store state in the stack of said function. So we need some location for this. // Having a single function that acts as a loop prevents us to store state in the stack of said function. So we need some location for this.
SDL_Window* g_Window = NULL; SDL_Window* g_Window = NULL;
SDL_GLContext g_GLContext = NULL; SDL_GLContext g_GLContext = NULL;
@ -63,6 +63,10 @@ int main(int, char**)
ImGuiIO& io = ImGui::GetIO(); (void)io; ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
// For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.
// You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
io.IniFilename = NULL;
// Setup Dear ImGui style // Setup Dear ImGui style
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic(); //ImGui::StyleColorsClassic();
@ -90,7 +94,7 @@ int main(int, char**)
emscripten_set_main_loop_arg(main_loop, NULL, 0, true); emscripten_set_main_loop_arg(main_loop, NULL, 0, true);
} }
void main_loop(void* arg) void main_loop(void* arg)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IM_UNUSED(arg); // We can pass this argument as the second parameter of emscripten_set_main_loop_arg(), but we don't use that. IM_UNUSED(arg); // We can pass this argument as the second parameter of emscripten_set_main_loop_arg(), but we don't use that.

View File

@ -64,6 +64,10 @@ struct ImDrawVertAllegro
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data) void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
{ {
// Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
// Backup Allegro state that will be modified // Backup Allegro state that will be modified
ALLEGRO_TRANSFORM last_transform = *al_get_current_transform(); ALLEGRO_TRANSFORM last_transform = *al_get_current_transform();
ALLEGRO_TRANSFORM last_projection_transform = *al_get_current_projection_transform(); ALLEGRO_TRANSFORM last_projection_transform = *al_get_current_projection_transform();

View File

@ -65,6 +65,10 @@ static void ImGui_ImplDX10_ShutdownPlatformInterface();
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
{ {
// Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
ID3D10Device* ctx = g_pd3dDevice; ID3D10Device* ctx = g_pd3dDevice;
// Create and grow vertex/index buffers if needed // Create and grow vertex/index buffers if needed

View File

@ -65,6 +65,10 @@ static void ImGui_ImplDX11_ShutdownPlatformInterface();
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
{ {
// Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
ID3D11DeviceContext* ctx = g_pd3dDeviceContext; ID3D11DeviceContext* ctx = g_pd3dDeviceContext;
// Create and grow vertex/index buffers if needed // Create and grow vertex/index buffers if needed

View File

@ -66,6 +66,10 @@ static void ImGui_ImplDX12_ShutdownPlatformInterface();
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx) void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx)
{ {
// Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
// FIXME: I'm assuming that this only gets called once per frame! // FIXME: I'm assuming that this only gets called once per frame!
// If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator. // If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator.
g_frameIndex = g_frameIndex + 1; g_frameIndex = g_frameIndex + 1;

View File

@ -40,6 +40,10 @@ static ImVec2 g_RenderScale = ImVec2(1.0f,1.0f);
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_Marmalade_RenderDrawData(ImDrawData* draw_data) void ImGui_Marmalade_RenderDrawData(ImDrawData* draw_data)
{ {
// Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
// Render command lists // Render command lists
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {

View File

@ -925,7 +925,7 @@ CODE
(The ImGuiWindowFlags_NoDecoration flag itself is a shortcut for NoTitleBar | NoResize | NoScrollbar | NoCollapse) (The ImGuiWindowFlags_NoDecoration flag itself is a shortcut for NoTitleBar | NoResize | NoScrollbar | NoCollapse)
Then you can retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like. Then you can retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like.
- You can call ImGui::GetBackgroundDrawList() or ImGui::GetForegroundDrawList() and use those draw list to display - You can call ImGui::GetBackgroundDrawList() or ImGui::GetForegroundDrawList() and use those draw list to display
contents behind or over every other imgui windows. (1 bg/fg drawlist per viewport) contents behind or over every other imgui windows (one bg/fg drawlist per viewport).
- You can create your own ImDrawList instance. You'll need to initialize them ImGui::GetDrawListSharedData(), or create - You can create your own ImDrawList instance. You'll need to initialize them ImGui::GetDrawListSharedData(), or create
your own ImDrawListSharedData, and then call your rendered code with your own ImDrawList or ImDrawData data. your own ImDrawListSharedData, and then call your rendered code with your own ImDrawList or ImDrawData data.
@ -2277,8 +2277,8 @@ static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
ImGuiWindow* window = ImGui::GetCurrentWindow(); ImGuiWindow* window = ImGui::GetCurrentWindow();
window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHereY() can properly function after the end of our clipper usage. window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHereY() can properly function after the end of our clipper usage.
window->DC.PrevLineSize.y = (line_height - GImGui->Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list. window->DC.PrevLineSize.y = (line_height - GImGui->Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list.
if (window->DC.ColumnsSet) if (window->DC.CurrentColumns)
window->DC.ColumnsSet->LineMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly window->DC.CurrentColumns->LineMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly
} }
// Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1 // Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1
@ -2654,7 +2654,7 @@ ImGuiWindow::~ImGuiWindow()
IM_ASSERT(DrawList == &DrawListInst); IM_ASSERT(DrawList == &DrawListInst);
IM_DELETE(Name); IM_DELETE(Name);
for (int i = 0; i != ColumnsStorage.Size; i++) for (int i = 0; i != ColumnsStorage.Size; i++)
ColumnsStorage[i].~ImGuiColumnsSet(); ColumnsStorage[i].~ImGuiColumns();
} }
ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end) ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end)
@ -5957,7 +5957,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->DC.ItemFlagsStack.resize(0); window->DC.ItemFlagsStack.resize(0);
window->DC.ItemWidthStack.resize(0); window->DC.ItemWidthStack.resize(0);
window->DC.TextWrapPosStack.resize(0); window->DC.TextWrapPosStack.resize(0);
window->DC.ColumnsSet = NULL; window->DC.CurrentColumns = NULL;
window->DC.TreeDepth = 0; window->DC.TreeDepth = 0;
window->DC.TreeDepthMayJumpToParentOnPop = 0x00; window->DC.TreeDepthMayJumpToParentOnPop = 0x00;
window->DC.StateStorage = &window->StateStorage; window->DC.StateStorage = &window->StateStorage;
@ -6093,7 +6093,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
BeginAsDockableDragDropTarget(window); BeginAsDockableDragDropTarget(window);
} }
// We fill last item data based on Title Bar or Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin(). // We fill last item data based on Title Bar/Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin().
// This is useful to allow creating context menus on title bar only, etc. // This is useful to allow creating context menus on title bar only, etc.
if (window->DockIsActive) if (window->DockIsActive)
{ {
@ -6202,7 +6202,7 @@ void ImGui::End()
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
if (window->DC.ColumnsSet != NULL) if (window->DC.CurrentColumns != NULL)
EndColumns(); EndColumns();
if (!(window->Flags & ImGuiWindowFlags_DockNodeHost)) // Pop inner window clip rectangle if (!(window->Flags & ImGuiWindowFlags_DockNodeHost)) // Pop inner window clip rectangle
PopClipRect(); PopClipRect();
@ -6991,8 +6991,8 @@ ImVec2 ImGui::GetContentRegionMax()
{ {
ImGuiWindow* window = GetCurrentWindowRead(); ImGuiWindow* window = GetCurrentWindowRead();
ImVec2 mx = window->ContentsRegionRect.Max - window->Pos; ImVec2 mx = window->ContentsRegionRect.Max - window->Pos;
if (window->DC.ColumnsSet) if (window->DC.CurrentColumns)
mx.x = GetColumnOffset(window->DC.ColumnsSet->Current + 1) - window->WindowPadding.x; mx.x = GetColumnOffset(window->DC.CurrentColumns->Current + 1) - window->WindowPadding.x;
return mx; return mx;
} }
@ -8630,8 +8630,8 @@ static void ImGui::NavUpdate()
if (g.NavWindow) if (g.NavWindow)
{ {
ImDrawList* draw_list = GetForegroundDrawList(g.NavWindow); ImDrawList* draw_list = GetForegroundDrawList(g.NavWindow);
if (1) { for (int layer = 0; layer < 2; layer++) draw_list->AddRect(g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Max, IM_COL32(255, 200, 0, 255)); } // [DEBUG] if (1) { for (int layer = 0; layer < 2; layer++) draw_list->AddRect(g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Max, IM_COL32(255,200,0,255)); } // [DEBUG]
if (1) { ImU32 col = (!g.NavWindow->Hidden) ? IM_COL32(255, 0, 255, 255) : IM_COL32(255, 0, 0, 255); ImVec2 p = NavCalcPreferredRefPos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); draw_list->AddCircleFilled(p, 3.0f, col); draw_list->AddText(NULL, 13.0f, p + ImVec2(8, -4), col, buf); } if (1) { ImU32 col = (!g.NavWindow->Hidden) ? IM_COL32(255,0,255,255) : IM_COL32(255,0,0,255); ImVec2 p = NavCalcPreferredRefPos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); draw_list->AddCircleFilled(p, 3.0f, col); draw_list->AddText(NULL, 13.0f, p + ImVec2(8,-4), col, buf); }
} }
#endif #endif
} }
@ -8973,11 +8973,11 @@ void ImGui::NavUpdateWindowingList()
void ImGui::NextColumn() void ImGui::NextColumn()
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems || window->DC.ColumnsSet == NULL) if (window->SkipItems || window->DC.CurrentColumns == NULL)
return; return;
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiColumnsSet* columns = window->DC.ColumnsSet; ImGuiColumns* columns = window->DC.CurrentColumns;
if (columns->Count == 1) if (columns->Count == 1)
{ {
@ -9016,28 +9016,28 @@ void ImGui::NextColumn()
int ImGui::GetColumnIndex() int ImGui::GetColumnIndex()
{ {
ImGuiWindow* window = GetCurrentWindowRead(); ImGuiWindow* window = GetCurrentWindowRead();
return window->DC.ColumnsSet ? window->DC.ColumnsSet->Current : 0; return window->DC.CurrentColumns ? window->DC.CurrentColumns->Current : 0;
} }
int ImGui::GetColumnsCount() int ImGui::GetColumnsCount()
{ {
ImGuiWindow* window = GetCurrentWindowRead(); ImGuiWindow* window = GetCurrentWindowRead();
return window->DC.ColumnsSet ? window->DC.ColumnsSet->Count : 1; return window->DC.CurrentColumns ? window->DC.CurrentColumns->Count : 1;
} }
static float OffsetNormToPixels(const ImGuiColumnsSet* columns, float offset_norm) static float OffsetNormToPixels(const ImGuiColumns* columns, float offset_norm)
{ {
return offset_norm * (columns->MaxX - columns->MinX); return offset_norm * (columns->MaxX - columns->MinX);
} }
static float PixelsToOffsetNorm(const ImGuiColumnsSet* columns, float offset) static float PixelsToOffsetNorm(const ImGuiColumns* columns, float offset)
{ {
return offset / (columns->MaxX - columns->MinX); return offset / (columns->MaxX - columns->MinX);
} }
static inline float GetColumnsRectHalfWidth() { return 4.0f; } static inline float GetColumnsRectHalfWidth() { return 4.0f; }
static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index) static float GetDraggedColumnOffset(ImGuiColumns* columns, int column_index)
{ {
// Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing // Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing
// window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning. // window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning.
@ -9057,7 +9057,7 @@ static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index)
float ImGui::GetColumnOffset(int column_index) float ImGui::GetColumnOffset(int column_index)
{ {
ImGuiWindow* window = GetCurrentWindowRead(); ImGuiWindow* window = GetCurrentWindowRead();
ImGuiColumnsSet* columns = window->DC.ColumnsSet; ImGuiColumns* columns = window->DC.CurrentColumns;
IM_ASSERT(columns != NULL); IM_ASSERT(columns != NULL);
if (column_index < 0) if (column_index < 0)
@ -9069,7 +9069,7 @@ float ImGui::GetColumnOffset(int column_index)
return x_offset; return x_offset;
} }
static float GetColumnWidthEx(ImGuiColumnsSet* columns, int column_index, bool before_resize = false) static float GetColumnWidthEx(ImGuiColumns* columns, int column_index, bool before_resize = false)
{ {
if (column_index < 0) if (column_index < 0)
column_index = columns->Current; column_index = columns->Current;
@ -9085,7 +9085,7 @@ static float GetColumnWidthEx(ImGuiColumnsSet* columns, int column_index, bool b
float ImGui::GetColumnWidth(int column_index) float ImGui::GetColumnWidth(int column_index)
{ {
ImGuiWindow* window = GetCurrentWindowRead(); ImGuiWindow* window = GetCurrentWindowRead();
ImGuiColumnsSet* columns = window->DC.ColumnsSet; ImGuiColumns* columns = window->DC.CurrentColumns;
IM_ASSERT(columns != NULL); IM_ASSERT(columns != NULL);
if (column_index < 0) if (column_index < 0)
@ -9097,7 +9097,7 @@ void ImGui::SetColumnOffset(int column_index, float offset)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
ImGuiColumnsSet* columns = window->DC.ColumnsSet; ImGuiColumns* columns = window->DC.CurrentColumns;
IM_ASSERT(columns != NULL); IM_ASSERT(columns != NULL);
if (column_index < 0) if (column_index < 0)
@ -9118,7 +9118,7 @@ void ImGui::SetColumnOffset(int column_index, float offset)
void ImGui::SetColumnWidth(int column_index, float width) void ImGui::SetColumnWidth(int column_index, float width)
{ {
ImGuiWindow* window = GetCurrentWindowRead(); ImGuiWindow* window = GetCurrentWindowRead();
ImGuiColumnsSet* columns = window->DC.ColumnsSet; ImGuiColumns* columns = window->DC.CurrentColumns;
IM_ASSERT(columns != NULL); IM_ASSERT(columns != NULL);
if (column_index < 0) if (column_index < 0)
@ -9129,46 +9129,57 @@ void ImGui::SetColumnWidth(int column_index, float width)
void ImGui::PushColumnClipRect(int column_index) void ImGui::PushColumnClipRect(int column_index)
{ {
ImGuiWindow* window = GetCurrentWindowRead(); ImGuiWindow* window = GetCurrentWindowRead();
ImGuiColumnsSet* columns = window->DC.ColumnsSet; ImGuiColumns* columns = window->DC.CurrentColumns;
if (column_index < 0) if (column_index < 0)
column_index = columns->Current; column_index = columns->Current;
PushClipRect(columns->Columns[column_index].ClipRect.Min, columns->Columns[column_index].ClipRect.Max, false); ImGuiColumnData* column = &columns->Columns[column_index];
PushClipRect(column->ClipRect.Min, column->ClipRect.Max, false);
} }
static ImGuiColumnsSet* FindOrAddColumnsSet(ImGuiWindow* window, ImGuiID id) ImGuiColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id)
{ {
// We have few columns per window so for now we don't need bother much with turning this into a faster lookup.
for (int n = 0; n < window->ColumnsStorage.Size; n++) for (int n = 0; n < window->ColumnsStorage.Size; n++)
if (window->ColumnsStorage[n].ID == id) if (window->ColumnsStorage[n].ID == id)
return &window->ColumnsStorage[n]; return &window->ColumnsStorage[n];
window->ColumnsStorage.push_back(ImGuiColumnsSet()); window->ColumnsStorage.push_back(ImGuiColumns());
ImGuiColumnsSet* columns = &window->ColumnsStorage.back(); ImGuiColumns* columns = &window->ColumnsStorage.back();
columns->ID = id; columns->ID = id;
return columns; return columns;
} }
ImGuiID ImGui::GetColumnsID(const char* str_id, int columns_count)
{
ImGuiWindow* window = GetCurrentWindow();
// Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget.
// In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer.
PushID(0x11223347 + (str_id ? 0 : columns_count));
ImGuiID id = window->GetID(str_id ? str_id : "columns");
PopID();
return id;
}
void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlags flags) void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlags flags)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
IM_ASSERT(columns_count >= 1); IM_ASSERT(columns_count >= 1);
IM_ASSERT(window->DC.ColumnsSet == NULL); // Nested columns are currently not supported IM_ASSERT(window->DC.CurrentColumns == NULL); // Nested columns are currently not supported
// Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget. ImGuiID id = GetColumnsID(str_id, columns_count);
// In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer.
PushID(0x11223347 + (str_id ? 0 : columns_count));
ImGuiID id = window->GetID(str_id ? str_id : "columns");
PopID();
// Acquire storage for the columns set // Acquire storage for the columns set
ImGuiColumnsSet* columns = FindOrAddColumnsSet(window, id); ImGuiColumns* columns = FindOrCreateColumns(window, id);
IM_ASSERT(columns->ID == id); IM_ASSERT(columns->ID == id);
columns->Current = 0; columns->Current = 0;
columns->Count = columns_count; columns->Count = columns_count;
columns->Flags = flags; columns->Flags = flags;
window->DC.ColumnsSet = columns; window->DC.CurrentColumns = columns;
// Set state for first column // Set state for first column
const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->InnerClipRect.Max.x - window->Pos.x); const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->InnerClipRect.Max.x - window->Pos.x);
@ -9219,7 +9230,7 @@ void ImGui::EndColumns()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
ImGuiColumnsSet* columns = window->DC.ColumnsSet; ImGuiColumns* columns = window->DC.CurrentColumns;
IM_ASSERT(columns != NULL); IM_ASSERT(columns != NULL);
PopItemWidth(); PopItemWidth();
@ -9280,7 +9291,7 @@ void ImGui::EndColumns()
} }
columns->IsBeingResized = is_being_resized; columns->IsBeingResized = is_being_resized;
window->DC.ColumnsSet = NULL; window->DC.CurrentColumns = NULL;
window->DC.ColumnsOffset.x = 0.0f; window->DC.ColumnsOffset.x = 0.0f;
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
} }
@ -9293,10 +9304,10 @@ void ImGui::Columns(int columns_count, const char* id, bool border)
ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder); ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder);
//flags |= ImGuiColumnsFlags_NoPreserveWidths; // NB: Legacy behavior //flags |= ImGuiColumnsFlags_NoPreserveWidths; // NB: Legacy behavior
if (window->DC.ColumnsSet != NULL && window->DC.ColumnsSet->Count == columns_count && window->DC.ColumnsSet->Flags == flags) if (window->DC.CurrentColumns != NULL && window->DC.CurrentColumns->Count == columns_count && window->DC.CurrentColumns->Flags == flags)
return; return;
if (window->DC.ColumnsSet != NULL) if (window->DC.CurrentColumns != NULL)
EndColumns(); EndColumns();
if (columns_count != 1) if (columns_count != 1)
@ -14189,7 +14200,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
{ {
for (int n = 0; n < window->ColumnsStorage.Size; n++) for (int n = 0; n < window->ColumnsStorage.Size; n++)
{ {
const ImGuiColumnsSet* columns = &window->ColumnsStorage[n]; const ImGuiColumns* columns = &window->ColumnsStorage[n];
if (ImGui::TreeNode((void*)(uintptr_t)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags)) if (ImGui::TreeNode((void*)(uintptr_t)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags))
{ {
ImGui::BulletText("Width: %.1f (MinX: %.1f, MaxX: %.1f)", columns->MaxX - columns->MinX, columns->MinX, columns->MaxX); ImGui::BulletText("Width: %.1f (MinX: %.1f, MaxX: %.1f)", columns->MaxX - columns->MinX, columns->MinX, columns->MaxX);
@ -14295,9 +14306,9 @@ void ImGui::ShowMetricsWindow(bool* p_open)
char buf[64] = ""; char buf[64] = "";
char* p = buf; char* p = buf;
p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "Order: %d\n", window->BeginOrderWithinContext); p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "Order: %d\n", window->BeginOrderWithinContext);
ImDrawList* overlay_draw_list = GetForegroundDrawList(window->Viewport); ImDrawList* fg_draw_list = GetForegroundDrawList(window->Viewport);
overlay_draw_list->AddRectFilled(window->Pos - ImVec2(1, 1), window->Pos + CalcTextSize(buf) + ImVec2(1, 1), IM_COL32(200, 100, 100, 255)); fg_draw_list->AddRectFilled(window->Pos - ImVec2(1, 1), window->Pos + CalcTextSize(buf) + ImVec2(1, 1), IM_COL32(200, 100, 100, 255));
overlay_draw_list->AddText(NULL, 0.0f, window->Pos, IM_COL32(255, 255, 255, 255), buf); fg_draw_list->AddText(NULL, 0.0f, window->Pos, IM_COL32(255, 255, 255, 255), buf);
} }
} }
ImGui::End(); ImGui::End();

View File

@ -1697,7 +1697,6 @@ static void ShowDemoWindowWidgets()
if (ImGui::MenuItem("Close")) { test_window = false; } if (ImGui::MenuItem("Close")) { test_window = false; }
ImGui::EndPopup(); ImGui::EndPopup();
} }
//if (IsItemHovered() || IsItemActive()) { printf("[%05d] Hovered %d Active %d\n", GetFrameCount(), IsItemHovered(), IsItemActive()); } // [DEBUG]
ImGui::Text( ImGui::Text(
"IsItemHovered() after begin = %d (== is title bar hovered)\n" "IsItemHovered() after begin = %d (== is title bar hovered)\n"
"IsItemActive() after begin = %d (== is window being clicked/moved)\n", "IsItemActive() after begin = %d (== is window being clicked/moved)\n",
@ -4051,7 +4050,7 @@ static void ShowExampleAppConstrainedResize(bool* p_open)
// Demonstrate creating a simple static window with no decoration + a context-menu to choose which corner of the screen to use. // Demonstrate creating a simple static window with no decoration + a context-menu to choose which corner of the screen to use.
static void ShowExampleAppSimpleOverlay(bool* p_open) static void ShowExampleAppSimpleOverlay(bool* p_open)
{ {
// FIXME-VIEWPORT-ABS: Select a default viewport // FIXME-VIEWPORT: Select a default viewport
const float DISTANCE = 10.0f; const float DISTANCE = 10.0f;
static int corner = 0; static int corner = 0;
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();

View File

@ -63,7 +63,7 @@ struct ImDrawDataBuilder; // Helper to build a ImDrawData instance
struct ImDrawListSharedData; // Data shared between all ImDrawList instances struct ImDrawListSharedData; // Data shared between all ImDrawList instances
struct ImGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it struct ImGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it
struct ImGuiColumnData; // Storage data for a single column struct ImGuiColumnData; // Storage data for a single column
struct ImGuiColumnsSet; // Storage data for a columns set struct ImGuiColumns; // Storage data for a columns set
struct ImGuiContext; // Main imgui context struct ImGuiContext; // Main imgui context
struct ImGuiDockContext; // Docking system context struct ImGuiDockContext; // Docking system context
struct ImGuiDockNode; // Docking system node (hold a list of Windows OR two child dock nodes) struct ImGuiDockNode; // Docking system node (hold a list of Windows OR two child dock nodes)
@ -681,7 +681,7 @@ struct ImGuiColumnData
ImGuiColumnData() { OffsetNorm = OffsetNormBeforeResize = 0.0f; Flags = 0; } ImGuiColumnData() { OffsetNorm = OffsetNormBeforeResize = 0.0f; Flags = 0; }
}; };
struct ImGuiColumnsSet struct ImGuiColumns
{ {
ImGuiID ID; ImGuiID ID;
ImGuiColumnsFlags Flags; ImGuiColumnsFlags Flags;
@ -695,7 +695,7 @@ struct ImGuiColumnsSet
float StartMaxPosX; // Copy of CursorMaxPos float StartMaxPosX; // Copy of CursorMaxPos
ImVector<ImGuiColumnData> Columns; ImVector<ImGuiColumnData> Columns;
ImGuiColumnsSet() { Clear(); } ImGuiColumns() { Clear(); }
void Clear() void Clear()
{ {
ID = 0; ID = 0;
@ -1311,7 +1311,7 @@ struct IMGUI_API ImGuiWindowTempData
ImVec1 Indent; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) ImVec1 Indent; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
ImVec1 GroupOffset; ImVec1 GroupOffset;
ImVec1 ColumnsOffset; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API. ImVec1 ColumnsOffset; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API.
ImGuiColumnsSet* ColumnsSet; // Current columns set ImGuiColumns* CurrentColumns; // Current columns set
ImGuiWindowTempData() ImGuiWindowTempData()
{ {
@ -1342,7 +1342,7 @@ struct IMGUI_API ImGuiWindowTempData
Indent = ImVec1(0.0f); Indent = ImVec1(0.0f);
GroupOffset = ImVec1(0.0f); GroupOffset = ImVec1(0.0f);
ColumnsOffset = ImVec1(0.0f); ColumnsOffset = ImVec1(0.0f);
ColumnsSet = NULL; CurrentColumns = NULL;
} }
}; };
@ -1414,7 +1414,7 @@ struct IMGUI_API ImGuiWindow
float ItemWidthDefault; float ItemWidthDefault;
ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items
ImGuiStorage StateStorage; ImGuiStorage StateStorage;
ImVector<ImGuiColumnsSet> ColumnsStorage; ImVector<ImGuiColumns> ColumnsStorage;
float FontWindowScale; // User scale multiplier per-window float FontWindowScale; // User scale multiplier per-window
float FontDpiScale; float FontDpiScale;
int SettingsIdx; // Index into SettingsWindow[] (indices are always valid as we only grow the array from the back) int SettingsIdx; // Index into SettingsWindow[] (indices are always valid as we only grow the array from the back)
@ -1711,6 +1711,8 @@ namespace ImGui
IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().
IMGUI_API void EndColumns(); // close columns IMGUI_API void EndColumns(); // close columns
IMGUI_API void PushColumnClipRect(int column_index = -1); IMGUI_API void PushColumnClipRect(int column_index = -1);
IMGUI_API ImGuiID GetColumnsID(const char* str_id, int count);
IMGUI_API ImGuiColumns* FindOrCreateColumns(ImGuiWindow* window, ImGuiID id);
// Tab Bars // Tab Bars
IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags, ImGuiDockNode* dock_node); IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags, ImGuiDockNode* dock_node);

View File

@ -1240,7 +1240,7 @@ void ImGui::Separator()
} }
// Horizontal Separator // Horizontal Separator
if (window->DC.ColumnsSet) if (window->DC.CurrentColumns)
PopClipRect(); PopClipRect();
float x1 = window->Pos.x; float x1 = window->Pos.x;
@ -1252,7 +1252,7 @@ void ImGui::Separator()
ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout. ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout.
if (!ItemAdd(bb, 0)) if (!ItemAdd(bb, 0))
{ {
if (window->DC.ColumnsSet) if (window->DC.CurrentColumns)
PushColumnClipRect(); PushColumnClipRect();
return; return;
} }
@ -1262,10 +1262,10 @@ void ImGui::Separator()
if (g.LogEnabled) if (g.LogEnabled)
LogRenderedText(&bb.Min, "--------------------------------"); LogRenderedText(&bb.Min, "--------------------------------");
if (window->DC.ColumnsSet) if (window->DC.CurrentColumns)
{ {
PushColumnClipRect(); PushColumnClipRect();
window->DC.ColumnsSet->LineMinY = window->DC.CursorPos.y; window->DC.CurrentColumns->LineMinY = window->DC.CursorPos.y;
} }
} }
@ -5337,7 +5337,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style; const ImGuiStyle& style = g.Style;
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) // FIXME-OPT: Avoid if vertically clipped. if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.CurrentColumns) // FIXME-OPT: Avoid if vertically clipped.
PopClipRect(); PopClipRect();
ImGuiID id = window->GetID(label); ImGuiID id = window->GetID(label);
@ -5381,7 +5381,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
} }
if (!item_add) if (!item_add)
{ {
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.CurrentColumns)
PushColumnClipRect(); PushColumnClipRect();
return false; return false;
} }
@ -5426,7 +5426,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding); RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding);
} }
if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.CurrentColumns)
{ {
PushColumnClipRect(); PushColumnClipRect();
bb.Max.x -= (GetContentRegionMax().x - max_x); bb.Max.x -= (GetContentRegionMax().x - max_x);