1
0
mirror of https://github.com/ocornut/imgui.git synced 2025-02-07 14:51:22 +01:00

Merge branch 'master' into docking

# Conflicts:
#	imgui.cpp
This commit is contained in:
ocornut 2023-05-22 10:10:29 +02:00
commit 54c1ac3e38
9 changed files with 124 additions and 107 deletions

View File

@ -479,8 +479,8 @@ jobs:
wget -q https://github.com/emscripten-core/emsdk/archive/master.tar.gz wget -q https://github.com/emscripten-core/emsdk/archive/master.tar.gz
tar -xvf master.tar.gz tar -xvf master.tar.gz
emsdk-master/emsdk update emsdk-master/emsdk update
emsdk-master/emsdk install latest emsdk-master/emsdk install 3.1.37
emsdk-master/emsdk activate latest emsdk-master/emsdk activate 3.1.37
- name: Build example_sdl2_opengl3 with Emscripten - name: Build example_sdl2_opengl3 with Emscripten
run: | run: |

View File

@ -104,6 +104,14 @@ Other changes:
Breaking changes: Breaking changes:
- Clipper: Commented out obsolete redirection constructor which was marked obsolete in 1.79:
'ImGuiListClipper(int items_count, float items_height)' --> Use 'ImGuiListClipper() + clipper.Begin()'.
- Clipper: Renamed ForceDisplayRangeByIndices() to IncludeRangeByIndices(), kept
inline redirection function (introduced in 1.86 and rarely used). (#6424, #3841)
- Commented out obsolete/redirecting functions that were marked obsolete more than two years ago:
- ListBoxHeader() -> use BeginListBox()
- ListBoxFooter() -> use EndListBox()
- Note how two variants of ListBoxHeader() existed. Check commented versions in imgui.h for refeence.
- Backends: GLUT: Removed call to ImGui::NewFrame() from ImGui_ImplGLUT_NewFrame(). - Backends: GLUT: Removed call to ImGui::NewFrame() from ImGui_ImplGLUT_NewFrame().
It needs to be called from the main app loop, like with every other backends. (#6337) [@GereonV] It needs to be called from the main app loop, like with every other backends. (#6337) [@GereonV]
@ -167,6 +175,8 @@ Docking+Viewports Branch:
VERSION 1.89.5 (Released 2023-04-13) VERSION 1.89.5 (Released 2023-04-13)
----------------------------------------------------------------------- -----------------------------------------------------------------------
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.89.5
Other changes: Other changes:
- InputText: Reworked prev/next-word behavior to more closely match Visual Studio - InputText: Reworked prev/next-word behavior to more closely match Visual Studio
@ -247,6 +257,8 @@ Docking+Viewports Branch:
VERSION 1.89.4 (Released 2023-03-14) VERSION 1.89.4 (Released 2023-03-14)
----------------------------------------------------------------------- -----------------------------------------------------------------------
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.89.4
Breaking Changes: Breaking Changes:
- Renamed PushAllowKeyboardFocus()/PopAllowKeyboardFocus() to PushTabStop()/PopTabStop(). - Renamed PushAllowKeyboardFocus()/PopAllowKeyboardFocus() to PushTabStop()/PopTabStop().
@ -1098,7 +1110,7 @@ Other Changes:
Fixes issue where e.g. drag and dropping an item and scrolling ensure the item source location is Fixes issue where e.g. drag and dropping an item and scrolling ensure the item source location is
still submitted. (#3841, #1725) [@GamingMinds-DanielC, @ocornut] still submitted. (#3841, #1725) [@GamingMinds-DanielC, @ocornut]
- Clipper: added ForceDisplayRangeByIndices() to force a given item (or several) to be stepped out - Clipper: added ForceDisplayRangeByIndices() to force a given item (or several) to be stepped out
during a clipping operation. (#3841) [@@GamingMinds-DanielC] during a clipping operation. (#3841) [@GamingMinds-DanielC]
- Clipper: rework so gamepad/keyboard navigation doesn't create spikes in number of items requested - Clipper: rework so gamepad/keyboard navigation doesn't create spikes in number of items requested
by the clipper to display. (#3841) by the clipper to display. (#3841)
- Clipper: fixed content height declaration slightly mismatching the value of when not using a clipper. - Clipper: fixed content height declaration slightly mismatching the value of when not using a clipper.

View File

@ -111,6 +111,7 @@ int main(int, char**)
{ {
g_d3dpp.BackBufferWidth = g_ResizeWidth; g_d3dpp.BackBufferWidth = g_ResizeWidth;
g_d3dpp.BackBufferHeight = g_ResizeHeight; g_d3dpp.BackBufferHeight = g_ResizeHeight;
g_ResizeWidth = g_ResizeHeight = 0;
ResetDevice(); ResetDevice();
} }

View File

@ -405,6 +405,11 @@ CODE
- likewise io.MousePos and GetMousePos() will use OS coordinates. - likewise io.MousePos and GetMousePos() will use OS coordinates.
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos. If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
- 2023/05/22 (1.86.6) - listbox: commented out obsolete/redirecting functions that were marked obsolete more than two years ago:
- ListBoxHeader() -> use BeginListBox() (note how two variants of ListBoxHeader() existed. Check commented versions in imgui.h for reference)
- ListBoxFooter() -> use EndListBox()
- 2023/05/15 (1.86.6) - clipper: commented out obsolete redirection constructor 'ImGuiListClipper(int items_count, float items_height = -1.0f)' that was marked obsolete in 1.79. Use default constructor + clipper.Begin().
- 2023/05/15 (1.89.6) - clipper: renamed ImGuiListClipper::ForceDisplayRangeByIndices() to ImGuiListClipper::IncludeRangeByIndices().
- 2023/03/14 (1.89.4) - commented out redirecting enums/functions names that were marked obsolete two years ago: - 2023/03/14 (1.89.4) - commented out redirecting enums/functions names that were marked obsolete two years ago:
- ImGuiSliderFlags_ClampOnInput -> use ImGuiSliderFlags_AlwaysClamp - ImGuiSliderFlags_ClampOnInput -> use ImGuiSliderFlags_AlwaysClamp
- ImGuiInputTextFlags_AlwaysInsertMode -> use ImGuiInputTextFlags_AlwaysOverwrite - ImGuiInputTextFlags_AlwaysInsertMode -> use ImGuiInputTextFlags_AlwaysOverwrite
@ -2860,13 +2865,13 @@ void ImGuiListClipper::End()
ItemsCount = -1; ItemsCount = -1;
} }
void ImGuiListClipper::ForceDisplayRangeByIndices(int item_min, int item_max) void ImGuiListClipper::IncludeRangeByIndices(int item_begin, int item_end)
{ {
ImGuiListClipperData* data = (ImGuiListClipperData*)TempData; ImGuiListClipperData* data = (ImGuiListClipperData*)TempData;
IM_ASSERT(DisplayStart < 0); // Only allowed after Begin() and if there has not been a specified range yet. IM_ASSERT(DisplayStart < 0); // Only allowed after Begin() and if there has not been a specified range yet.
IM_ASSERT(item_min <= item_max); IM_ASSERT(item_begin <= item_end);
if (item_min < item_max) if (item_begin < item_end)
data->Ranges.push_back(ImGuiListClipperRange::FromIndices(item_min, item_max)); data->Ranges.push_back(ImGuiListClipperRange::FromIndices(item_begin, item_end));
} }
static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper) static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper)
@ -9849,6 +9854,11 @@ void ImGui::ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, vo
if (log_callback) log_callback(user_data, "Recovered from missing PopStyleVar() in '%s'", window->Name); if (log_callback) log_callback(user_data, "Recovered from missing PopStyleVar() in '%s'", window->Name);
PopStyleVar(); PopStyleVar();
} }
while (g.FontStack.Size > stack_sizes->SizeOfFontStack) //-V1044
{
if (log_callback) log_callback(user_data, "Recovered from missing PopFont() in '%s'", window->Name);
PopFont();
}
while (g.FocusScopeStack.Size > stack_sizes->SizeOfFocusScopeStack + 1) //-V1044 while (g.FocusScopeStack.Size > stack_sizes->SizeOfFocusScopeStack + 1) //-V1044
{ {
if (log_callback) log_callback(user_data, "Recovered from missing PopFocusScope() in '%s'", window->Name); if (log_callback) log_callback(user_data, "Recovered from missing PopFocusScope() in '%s'", window->Name);
@ -11333,7 +11343,7 @@ void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window)
NavClearPreferredPosForAxis(ImGuiAxis_Y); NavClearPreferredPosForAxis(ImGuiAxis_Y);
} }
ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy) static ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy)
{ {
if (ImFabs(dx) > ImFabs(dy)) if (ImFabs(dx) > ImFabs(dy))
return (dx > 0.0f) ? ImGuiDir_Right : ImGuiDir_Left; return (dx > 0.0f) ? ImGuiDir_Right : ImGuiDir_Left;
@ -11706,7 +11716,8 @@ void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags wra
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_ASSERT((wrap_flags & ImGuiNavMoveFlags_WrapMask_ ) != 0 && (wrap_flags & ~ImGuiNavMoveFlags_WrapMask_) == 0); // Call with _WrapX, _WrapY, _LoopX, _LoopY IM_ASSERT((wrap_flags & ImGuiNavMoveFlags_WrapMask_ ) != 0 && (wrap_flags & ~ImGuiNavMoveFlags_WrapMask_) == 0); // Call with _WrapX, _WrapY, _LoopX, _LoopY
// In theory we should test for NavMoveRequestButNoResultYet() but there's no point doing it, NavEndFrame() will do the same test // In theory we should test for NavMoveRequestButNoResultYet() but there's no point doing it:
// as NavEndFrame() will do the same test. It will end up calling NavUpdateCreateWrappingRequest().
if (g.NavWindow == window && g.NavMoveScoringItems && g.NavLayer == ImGuiNavLayer_Main) if (g.NavWindow == window && g.NavMoveScoringItems && g.NavLayer == ImGuiNavLayer_Main)
g.NavMoveFlags = (g.NavMoveFlags & ~ImGuiNavMoveFlags_WrapMask_) | wrap_flags; g.NavMoveFlags = (g.NavMoveFlags & ~ImGuiNavMoveFlags_WrapMask_) | wrap_flags;
} }
@ -12035,7 +12046,7 @@ void ImGui::NavInitRequestApplyResult()
} }
// Bias scoring rect ahead of scoring + update preferred pos (if missing) using source position // Bias scoring rect ahead of scoring + update preferred pos (if missing) using source position
static void NavBiasScoringRect(ImRect& r, ImVec2& preferred_pos_rel, ImGuiDir move_dir) static void NavBiasScoringRect(ImRect& r, ImVec2& preferred_pos_rel, ImGuiDir move_dir, ImGuiNavMoveFlags move_flags)
{ {
// Bias initial rect // Bias initial rect
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -12044,15 +12055,18 @@ static void NavBiasScoringRect(ImRect& r, ImVec2& preferred_pos_rel, ImGuiDir mo
// Initialize bias on departure if we don't have any. So mouse-click + arrow will record bias. // Initialize bias on departure if we don't have any. So mouse-click + arrow will record bias.
// - We default to L/U bias, so moving down from a large source item into several columns will land on left-most column. // - We default to L/U bias, so moving down from a large source item into several columns will land on left-most column.
// - But each successful move sets new bias on one axis, only cleared when using mouse. // - But each successful move sets new bias on one axis, only cleared when using mouse.
if (preferred_pos_rel.x == FLT_MAX) if ((move_flags & ImGuiNavMoveFlags_Forwarded) == 0)
preferred_pos_rel.x = ImMin(r.Min.x + 1.0f, r.Max.x) - rel_to_abs_offset.x; {
if (preferred_pos_rel.y == FLT_MAX) if (preferred_pos_rel.x == FLT_MAX)
preferred_pos_rel.y = r.GetCenter().y - rel_to_abs_offset.y; preferred_pos_rel.x = ImMin(r.Min.x + 1.0f, r.Max.x) - rel_to_abs_offset.x;
if (preferred_pos_rel.y == FLT_MAX)
preferred_pos_rel.y = r.GetCenter().y - rel_to_abs_offset.y;
}
// Apply general bias on the other axis // Apply general bias on the other axis
if (move_dir == ImGuiDir_Up || move_dir == ImGuiDir_Down) if ((move_dir == ImGuiDir_Up || move_dir == ImGuiDir_Down) && preferred_pos_rel.x != FLT_MAX)
r.Min.x = r.Max.x = preferred_pos_rel.x + rel_to_abs_offset.x; r.Min.x = r.Max.x = preferred_pos_rel.x + rel_to_abs_offset.x;
else else if ((move_dir == ImGuiDir_Left || move_dir == ImGuiDir_Right) && preferred_pos_rel.y != FLT_MAX)
r.Min.y = r.Max.y = preferred_pos_rel.y + rel_to_abs_offset.y; r.Min.y = r.Max.y = preferred_pos_rel.y + rel_to_abs_offset.y;
} }
@ -12163,7 +12177,7 @@ void ImGui::NavUpdateCreateMoveRequest()
scoring_rect = WindowRectRelToAbs(window, nav_rect_rel); scoring_rect = WindowRectRelToAbs(window, nav_rect_rel);
scoring_rect.TranslateY(scoring_rect_offset_y); scoring_rect.TranslateY(scoring_rect_offset_y);
if (g.NavMoveSubmitted) if (g.NavMoveSubmitted)
NavBiasScoringRect(scoring_rect, window->RootWindowForNav->NavPreferredScoringPosRel[g.NavLayer], g.NavMoveDir); NavBiasScoringRect(scoring_rect, window->RootWindowForNav->NavPreferredScoringPosRel[g.NavLayer], g.NavMoveDir, g.NavMoveFlags);
IM_ASSERT(!scoring_rect.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allow us to remove extraneous ImFabs() calls in NavScoreItem(). IM_ASSERT(!scoring_rect.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allow us to remove extraneous ImFabs() calls in NavScoreItem().
//GetForegroundDrawList()->AddRect(scoring_rect.Min, scoring_rect.Max, IM_COL32(255,200,0,255)); // [DEBUG] //GetForegroundDrawList()->AddRect(scoring_rect.Min, scoring_rect.Max, IM_COL32(255,200,0,255)); // [DEBUG]
//if (!g.NavScoringNoClipRect.IsInverted()) { GetForegroundDrawList()->AddRect(g.NavScoringNoClipRect.Min, g.NavScoringNoClipRect.Max, IM_COL32(255, 200, 0, 255)); } // [DEBUG] //if (!g.NavScoringNoClipRect.IsInverted()) { GetForegroundDrawList()->AddRect(g.NavScoringNoClipRect.Min, g.NavScoringNoClipRect.Max, IM_COL32(255, 200, 0, 255)); } // [DEBUG]
@ -12451,7 +12465,9 @@ static void ImGui::NavUpdateCreateWrappingRequest()
bool do_forward = false; bool do_forward = false;
ImRect bb_rel = window->NavRectRel[g.NavLayer]; ImRect bb_rel = window->NavRectRel[g.NavLayer];
ImGuiDir clip_dir = g.NavMoveDir; ImGuiDir clip_dir = g.NavMoveDir;
const ImGuiNavMoveFlags move_flags = g.NavMoveFlags; const ImGuiNavMoveFlags move_flags = g.NavMoveFlags;
//const ImGuiAxis move_axis = (g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) ? ImGuiAxis_Y : ImGuiAxis_X;
if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX))) if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX)))
{ {
bb_rel.Min.x = bb_rel.Max.x = window->ContentSize.x + window->WindowPadding.x; bb_rel.Min.x = bb_rel.Max.x = window->ContentSize.x + window->WindowPadding.x;

22
imgui.h
View File

@ -21,9 +21,9 @@
// please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above. // please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above.
// Library Version // Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345') // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.89.6 WIP" #define IMGUI_VERSION "1.89.6 WIP"
#define IMGUI_VERSION_NUM 18956 #define IMGUI_VERSION_NUM 18958
#define IMGUI_HAS_TABLE #define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch #define IMGUI_HAS_VIEWPORT // Viewport WIP branch
#define IMGUI_HAS_DOCK // Docking WIP branch #define IMGUI_HAS_DOCK // Docking WIP branch
@ -2455,11 +2455,13 @@ struct ImGuiListClipper
IMGUI_API void End(); // Automatically called on the last call of Step() that returns false. IMGUI_API void End(); // Automatically called on the last call of Step() that returns false.
IMGUI_API bool Step(); // Call until it returns false. The DisplayStart/DisplayEnd fields will be set and you can process/draw those items. IMGUI_API bool Step(); // Call until it returns false. The DisplayStart/DisplayEnd fields will be set and you can process/draw those items.
// Call ForceDisplayRangeByIndices() before first call to Step() if you need a range of items to be displayed regardless of visibility. // Call IncludeRangeByIndices() *BEFORE* first call to Step() if you need a range of items to not be clipped, regardless of their visibility.
IMGUI_API void ForceDisplayRangeByIndices(int item_min, int item_max); // item_max is exclusive e.g. use (42, 42+1) to make item 42 always visible BUT due to alignment/padding of certain items it is likely that an extra item may be included on either end of the display range. // (Due to alignment / padding of certain items it is possible that an extra item may be included on either end of the display range).
IMGUI_API void IncludeRangeByIndices(int item_begin, int item_end); // item_end is exclusive e.g. use (42, 42+1) to make item 42 never clipped.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
inline ImGuiListClipper(int items_count, float items_height = -1.0f) { memset(this, 0, sizeof(*this)); ItemsCount = -1; Begin(items_count, items_height); } // [removed in 1.79] inline void ForceDisplayRangeByIndices(int item_begin, int item_end) { IncludeRangeByIndices(item_begin, item_end); } // [renamed in 1.89.6]
//inline ImGuiListClipper(int items_count, float items_height = -1.0f) { memset(this, 0, sizeof(*this)); ItemsCount = -1; Begin(items_count, items_height); } // [removed in 1.79]
#endif #endif
}; };
@ -3299,12 +3301,12 @@ namespace ImGui
IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // Calculate coarse clipping for large list of evenly sized items. Prefer using ImGuiListClipper. IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // Calculate coarse clipping for large list of evenly sized items. Prefer using ImGuiListClipper.
// OBSOLETED in 1.85 (from August 2021) // OBSOLETED in 1.85 (from August 2021)
static inline float GetWindowContentRegionWidth() { return GetWindowContentRegionMax().x - GetWindowContentRegionMin().x; } static inline float GetWindowContentRegionWidth() { return GetWindowContentRegionMax().x - GetWindowContentRegionMin().x; }
// OBSOLETED in 1.81 (from February 2021)
IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // Helper to calculate size from items_count and height_in_items
static inline bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)) { return BeginListBox(label, size); }
static inline void ListBoxFooter() { EndListBox(); }
// Some of the older obsolete names along with their replacement (commented out so they are not reported in IDE) // Some of the older obsolete names along with their replacement (commented out so they are not reported in IDE)
//-- OBSOLETED in 1.81 (from February 2021)
//static inline bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)) { return BeginListBox(label, size); }
//static inline bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1) { float height = GetTextLineHeightWithSpacing() * ((height_in_items < 0 ? ImMin(items_count, 7) : height_in_items) + 0.25f) + GetStyle().FramePadding.y * 2.0f; return BeginListBox(label, ImVec2(0.0f, height)); } // Helper to calculate size from items_count and height_in_items
//static inline void ListBoxFooter() { EndListBox(); }
//-- OBSOLETED in 1.79 (from August 2020) //-- OBSOLETED in 1.79 (from August 2020)
//static inline void OpenPopupContextItem(const char* str_id = NULL, ImGuiMouseButton mb = 1) { OpenPopupOnItemClick(str_id, mb); } // Bool return value removed. Use IsWindowAppearing() in BeginPopup() instead. Renamed in 1.77, renamed back in 1.79. Sorry! //static inline void OpenPopupContextItem(const char* str_id = NULL, ImGuiMouseButton mb = 1) { OpenPopupOnItemClick(str_id, mb); } // Bool return value removed. Use IsWindowAppearing() in BeginPopup() instead. Renamed in 1.77, renamed back in 1.79. Sorry!
//-- OBSOLETED in 1.78 (from June 2020): Old drag/sliders functions that took a 'float power > 1.0f' argument instead of ImGuiSliderFlags_Logarithmic. See github.com/ocornut/imgui/issues/3361 for details. //-- OBSOLETED in 1.78 (from June 2020): Old drag/sliders functions that took a 'float power > 1.0f' argument instead of ImGuiSliderFlags_Logarithmic. See github.com/ocornut/imgui/issues/3361 for details.

View File

@ -415,23 +415,21 @@ void ImGui::ShowDemoWindow(bool* p_open)
IMGUI_DEMO_MARKER("Help"); IMGUI_DEMO_MARKER("Help");
if (ImGui::CollapsingHeader("Help")) if (ImGui::CollapsingHeader("Help"))
{ {
ImGui::Text("ABOUT THIS DEMO:"); ImGui::SeparatorText("ABOUT THIS DEMO:");
ImGui::BulletText("Sections below are demonstrating many aspects of the library."); ImGui::BulletText("Sections below are demonstrating many aspects of the library.");
ImGui::BulletText("The \"Examples\" menu above leads to more demo contents."); ImGui::BulletText("The \"Examples\" menu above leads to more demo contents.");
ImGui::BulletText("The \"Tools\" menu above gives access to: About Box, Style Editor,\n" ImGui::BulletText("The \"Tools\" menu above gives access to: About Box, Style Editor,\n"
"and Metrics/Debugger (general purpose Dear ImGui debugging tool)."); "and Metrics/Debugger (general purpose Dear ImGui debugging tool).");
ImGui::Separator();
ImGui::Text("PROGRAMMER GUIDE:"); ImGui::SeparatorText("PROGRAMMER GUIDE:");
ImGui::BulletText("See the ShowDemoWindow() code in imgui_demo.cpp. <- you are here!"); ImGui::BulletText("See the ShowDemoWindow() code in imgui_demo.cpp. <- you are here!");
ImGui::BulletText("See comments in imgui.cpp."); ImGui::BulletText("See comments in imgui.cpp.");
ImGui::BulletText("See example applications in the examples/ folder."); ImGui::BulletText("See example applications in the examples/ folder.");
ImGui::BulletText("Read the FAQ at http://www.dearimgui.com/faq/"); ImGui::BulletText("Read the FAQ at http://www.dearimgui.com/faq/");
ImGui::BulletText("Set 'io.ConfigFlags |= NavEnableKeyboard' for keyboard controls."); ImGui::BulletText("Set 'io.ConfigFlags |= NavEnableKeyboard' for keyboard controls.");
ImGui::BulletText("Set 'io.ConfigFlags |= NavEnableGamepad' for gamepad controls."); ImGui::BulletText("Set 'io.ConfigFlags |= NavEnableGamepad' for gamepad controls.");
ImGui::Separator();
ImGui::Text("USER GUIDE:"); ImGui::SeparatorText("USER GUIDE:");
ImGui::ShowUserGuide(); ImGui::ShowUserGuide();
} }

View File

@ -489,7 +489,6 @@ IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, c
IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);
IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w); IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w);
inline float ImTriangleArea(const ImVec2& a, const ImVec2& b, const ImVec2& c) { return ImFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5f; } inline float ImTriangleArea(const ImVec2& a, const ImVec2& b, const ImVec2& c) { return ImFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5f; }
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)
@ -914,7 +913,7 @@ enum ImGuiSeparatorFlags_
ImGuiSeparatorFlags_None = 0, ImGuiSeparatorFlags_None = 0,
ImGuiSeparatorFlags_Horizontal = 1 << 0, // Axis default to current layout type, so generally Horizontal unless e.g. in a menu bar ImGuiSeparatorFlags_Horizontal = 1 << 0, // Axis default to current layout type, so generally Horizontal unless e.g. in a menu bar
ImGuiSeparatorFlags_Vertical = 1 << 1, ImGuiSeparatorFlags_Vertical = 1 << 1,
ImGuiSeparatorFlags_SpanAllColumns = 1 << 2, ImGuiSeparatorFlags_SpanAllColumns = 1 << 2, // Make separator cover all columns of a legacy Columns() set.
}; };
// Flags for FocusWindow(). This is not called ImGuiFocusFlags to avoid confusion with public-facing ImGuiFocusedFlags. // Flags for FocusWindow(). This is not called ImGuiFocusFlags to avoid confusion with public-facing ImGuiFocusedFlags.
@ -1426,6 +1425,7 @@ enum ImGuiInputFlags_
// [SECTION] Clipper support // [SECTION] Clipper support
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Note that Max is exclusive, so perhaps should be using a Begin/End convention.
struct ImGuiListClipperRange struct ImGuiListClipperRange
{ {
int Min; int Min;
@ -2713,7 +2713,7 @@ struct IMGUI_API ImGuiTabBar
typedef ImS16 ImGuiTableColumnIdx; typedef ImS16 ImGuiTableColumnIdx;
typedef ImU16 ImGuiTableDrawChannelIdx; typedef ImU16 ImGuiTableDrawChannelIdx;
// [Internal] sizeof() ~ 104 // [Internal] sizeof() ~ 112
// We use the terminology "Enabled" to refer to a column that is not Hidden by user/api. // We use the terminology "Enabled" to refer to a column that is not Hidden by user/api.
// We use the terminology "Clipped" to refer to a column that is out of sight because of scrolling/clipping. // We use the terminology "Clipped" to refer to a column that is out of sight because of scrolling/clipping.
// This is in contrast with some user-facing api such as IsItemVisible() / IsRectVisible() which use "Visible" to mean "not clipped". // This is in contrast with some user-facing api such as IsItemVisible() / IsRectVisible() which use "Visible" to mean "not clipped".
@ -2759,7 +2759,7 @@ struct ImGuiTableColumn
ImU8 SortDirection : 2; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending ImU8 SortDirection : 2; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending
ImU8 SortDirectionsAvailCount : 2; // Number of available sort directions (0 to 3) ImU8 SortDirectionsAvailCount : 2; // Number of available sort directions (0 to 3)
ImU8 SortDirectionsAvailMask : 4; // Mask of available sort directions (1-bit each) ImU8 SortDirectionsAvailMask : 4; // Mask of available sort directions (1-bit each)
ImU8 SortDirectionsAvailList; // Ordered of available sort directions (2-bits each) ImU8 SortDirectionsAvailList; // Ordered list of available sort directions (2-bits each, total 8-bits)
ImGuiTableColumn() ImGuiTableColumn()
{ {
@ -2794,6 +2794,7 @@ struct ImGuiTableInstanceData
}; };
// FIXME-TABLE: more transient data could be stored in a stacked ImGuiTableTempData: e.g. SortSpecs, incoming RowData // FIXME-TABLE: more transient data could be stored in a stacked ImGuiTableTempData: e.g. SortSpecs, incoming RowData
// sizeof() ~ 580 bytes + heap allocs described in TableBeginInitMemory()
struct IMGUI_API ImGuiTable struct IMGUI_API ImGuiTable
{ {
ImGuiID ID; ImGuiID ID;
@ -2909,6 +2910,7 @@ struct IMGUI_API ImGuiTable
// Transient data that are only needed between BeginTable() and EndTable(), those buffers are shared (1 per level of stacked table). // 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. // - 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. // - We also leave out of this structure data that tend to be particularly useful for debugging/metrics.
// sizeof() ~ 112 bytes.
struct IMGUI_API ImGuiTableTempData struct IMGUI_API ImGuiTableTempData
{ {
int TableIndex; // Index in g.Tables.Buf[] pool int TableIndex; // Index in g.Tables.Buf[] pool
@ -3426,7 +3428,7 @@ namespace ImGui
IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0); IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0); IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0);
IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col, ImGuiButtonFlags flags = 0); IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col, ImGuiButtonFlags flags = 0);
IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags); IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags, float thickness = 1.0f);
IMGUI_API void SeparatorTextEx(ImGuiID id, const char* label, const char* label_end, float extra_width); IMGUI_API void SeparatorTextEx(ImGuiID id, const char* label, const char* label_end, float extra_width);
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

@ -80,20 +80,20 @@ Index of this file:
// - 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.
// - outer_size.x > 0.0f -> Set Fixed width. // - outer_size.x > 0.0f -> Set Fixed width.
// Y with ScrollX/ScrollY disabled: we output table directly in current window // Y with ScrollX/ScrollY disabled: we output table directly in current window
// - outer_size.y < 0.0f -> Bottom-align (but will auto extend, unless _NoHostExtendY is set). Not meaningful is parent window can vertically scroll. // - outer_size.y < 0.0f -> Bottom-align (but will auto extend, unless _NoHostExtendY is set). Not meaningful if parent window can vertically scroll.
// - outer_size.y = 0.0f -> No minimum height (but will auto extend, unless _NoHostExtendY is set) // - outer_size.y = 0.0f -> No minimum height (but will auto extend, unless _NoHostExtendY is set)
// - outer_size.y > 0.0f -> Set Minimum height (but will auto extend, unless _NoHostExtenY is set) // - outer_size.y > 0.0f -> Set Minimum height (but will auto extend, unless _NoHostExtenY is set)
// Y with ScrollX/ScrollY enabled: using a child window for scrolling // Y with ScrollX/ScrollY enabled: using a child window for scrolling
// - outer_size.y < 0.0f -> Bottom-align. Not meaningful is parent window can vertically scroll. // - outer_size.y < 0.0f -> Bottom-align. Not meaningful if parent window can vertically scroll.
// - outer_size.y = 0.0f -> Bottom-align, consistent with BeginChild(). Not recommended unless table is last item in parent window. // - outer_size.y = 0.0f -> Bottom-align, consistent with BeginChild(). Not recommended unless table is last item in parent window.
// - outer_size.y > 0.0f -> Set Exact height. Recommended when using Scrolling on any axis. // - outer_size.y > 0.0f -> Set Exact height. Recommended when using Scrolling on any axis.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// 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 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 is 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 useful and not easily noticeable).
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// About 'inner_width': // About 'inner_width':
// With ScrollX disabled: // With ScrollX disabled:
@ -112,15 +112,16 @@ Index of this file:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// COLUMNS SIZING POLICIES // COLUMNS SIZING POLICIES
// (Reference: ImGuiTableFlags_SizingXXX flags and ImGuiTableColumnFlags_WidthXXX flags)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// About overriding column sizing policy and width/weight with TableSetupColumn(): // About overriding column sizing policy and width/weight with TableSetupColumn():
// We use a default parameter of 'init_width_or_weight == -1'. // We use a default parameter of -1 for 'init_width'/'init_weight'.
// - with ImGuiTableColumnFlags_WidthFixed, init_width <= 0 (default) --> width is automatic // - with ImGuiTableColumnFlags_WidthFixed, init_width <= 0 (default) --> width is automatic
// - with ImGuiTableColumnFlags_WidthFixed, init_width > 0 (explicit) --> width is custom // - with ImGuiTableColumnFlags_WidthFixed, init_width > 0 (explicit) --> width is custom
// - with ImGuiTableColumnFlags_WidthStretch, init_weight <= 0 (default) --> weight is 1.0f // - with ImGuiTableColumnFlags_WidthStretch, init_weight <= 0 (default) --> weight is 1.0f
// - with ImGuiTableColumnFlags_WidthStretch, init_weight > 0 (explicit) --> weight is custom // - with ImGuiTableColumnFlags_WidthStretch, init_weight > 0 (explicit) --> weight is custom
// Widths are specified _without_ CellPadding. If you specify a width of 100.0f, the column will be cover (100.0f + Padding * 2.0f) // Widths are specified _without_ CellPadding. If you specify a width of 100.0f, the column will be cover (100.0f + Padding * 2.0f)
// and you can fit a 100.0f wide item in it without clipping and with full padding. // and you can fit a 100.0f wide item in it without clipping and with padding honored.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// About default sizing policy (if you don't specify a ImGuiTableColumnFlags_WidthXXXX flag) // About default sizing policy (if you don't specify a ImGuiTableColumnFlags_WidthXXXX flag)
// - with Table policy ImGuiTableFlags_SizingFixedFit --> default Column policy is ImGuiTableColumnFlags_WidthFixed, default Width is equal to contents width // - with Table policy ImGuiTableFlags_SizingFixedFit --> default Column policy is ImGuiTableColumnFlags_WidthFixed, default Width is equal to contents width
@ -134,10 +135,10 @@ Index of this file:
// - 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 width of the maximum contents.
// - 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 weights/widths.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// About using column width: // About using column width:
// If a column is manual resizable or has a width specified with TableSetupColumn(): // If a column is manually resizable or has a width specified with TableSetupColumn():
// - 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():
@ -151,7 +152,7 @@ Index of this file:
// TABLES CLIPPING/CULLING // TABLES CLIPPING/CULLING
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// About clipping/culling of Rows in Tables: // About clipping/culling of Rows in Tables:
// - For large numbers of rows, it is recommended you use ImGuiListClipper to only submit visible rows. // - For large numbers of rows, it is recommended you use ImGuiListClipper to submit only visible rows.
// ImGuiListClipper is reliant on the fact that rows are of equal height. // ImGuiListClipper is reliant on the fact that rows are of equal height.
// See 'Demo->Tables->Vertical Scrolling' or 'Demo->Tables->Advanced' for a demo of using the clipper. // See 'Demo->Tables->Vertical Scrolling' or 'Demo->Tables->Advanced' for a demo of using the clipper.
// - Note that auto-resizing columns don't play well with using the clipper. // - Note that auto-resizing columns don't play well with using the clipper.
@ -168,7 +169,7 @@ Index of this file:
// - 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() returns 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).
@ -319,7 +320,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
if (flags & ImGuiTableFlags_ScrollX) if (flags & ImGuiTableFlags_ScrollX)
IM_ASSERT(inner_width >= 0.0f); IM_ASSERT(inner_width >= 0.0f);
// If an outer size is specified ahead we will be able to early out when not visible. Exact clipping rules may evolve. // If an outer size is specified ahead we will be able to early out when not visible. Exact clipping criteria may evolve.
const bool use_child_window = (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0; const bool use_child_window = (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0;
const ImVec2 avail_size = GetContentRegionAvail(); const ImVec2 avail_size = GetContentRegionAvail();
ImVec2 actual_outer_size = CalcItemSize(outer_size, ImMax(avail_size.x, 1.0f), use_child_window ? ImMax(avail_size.y, 1.0f) : 0.0f); ImVec2 actual_outer_size = CalcItemSize(outer_size, ImMax(avail_size.x, 1.0f), use_child_window ? ImMax(avail_size.y, 1.0f) : 0.0f);
@ -366,7 +367,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
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");
if (table->InstanceDataExtra.Size < instance_no) if (table->InstanceDataExtra.Size < instance_no)
table->InstanceDataExtra.push_back(ImGuiTableInstanceData()); table->InstanceDataExtra.push_back(ImGuiTableInstanceData());
instance_id = GetIDWithSeed(instance_no, GetIDWithSeed("##Instances", NULL, id)); // Push "##Instance" followed by (int)instance_no in ID stack. instance_id = GetIDWithSeed(instance_no, GetIDWithSeed("##Instances", NULL, id)); // Push "##Instances" followed by (int)instance_no in ID stack.
} }
else else
{ {
@ -477,7 +478,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->IsUnfrozenRows = true; table->IsUnfrozenRows = true;
table->DeclColumnsCount = 0; table->DeclColumnsCount = 0;
// Using opaque colors facilitate overlapping elements of the grid // Using opaque colors facilitate overlapping lines of the grid, otherwise we'd need to improve TableDrawBorders()
table->BorderColorStrong = GetColorU32(ImGuiCol_TableBorderStrong); table->BorderColorStrong = GetColorU32(ImGuiCol_TableBorderStrong);
table->BorderColorLight = GetColorU32(ImGuiCol_TableBorderLight); table->BorderColorLight = GetColorU32(ImGuiCol_TableBorderLight);
@ -491,7 +492,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
if ((table_last_flags & ImGuiTableFlags_Reorderable) && (flags & ImGuiTableFlags_Reorderable) == 0) if ((table_last_flags & ImGuiTableFlags_Reorderable) && (flags & ImGuiTableFlags_Reorderable) == 0)
table->IsResetDisplayOrderRequest = true; table->IsResetDisplayOrderRequest = true;
// Mark as used // Mark as used to avoid GC
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;
@ -584,13 +585,13 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
} }
// For reference, the average total _allocation count_ for a table is: // For reference, the average total _allocation count_ for a table is:
// + 0 (for ImGuiTable instance, we are pooling allocations in g.Tables) // + 0 (for ImGuiTable instance, we are pooling allocations in g.Tables[])
// + 1 (for table->RawData allocated below) // + 1 (for table->RawData allocated below)
// + 1 (for table->ColumnsNames, if names are used) // + 1 (for table->ColumnsNames, if names are used)
// Shared allocations per number of nested tables // Shared allocations for the maximum number of simultaneously nested tables (generally a very small number)
// + 1 (for table->Splitter._Channels) // + 1 (for table->Splitter._Channels)
// + 2 * active_channels_count (for ImDrawCmd and ImDrawIdx buffers inside channels) // + 2 * active_channels_count (for ImDrawCmd and ImDrawIdx buffers inside channels)
// Where active_channels_count is variable but often == columns_count or columns_count + 1, see TableSetupDrawChannels() for details. // Where active_channels_count is variable but often == columns_count or == columns_count + 1, see TableSetupDrawChannels() for details.
// Unused channels don't perform their +2 allocations. // Unused channels don't perform their +2 allocations.
void ImGui::TableBeginInitMemory(ImGuiTable* table, int columns_count) void ImGui::TableBeginInitMemory(ImGuiTable* table, int columns_count)
{ {
@ -617,7 +618,7 @@ void ImGui::TableBeginInitMemory(ImGuiTable* table, int columns_count)
void ImGui::TableBeginApplyRequests(ImGuiTable* table) void ImGui::TableBeginApplyRequests(ImGuiTable* table)
{ {
// Handle resizing request // Handle resizing request
// (We process this at the first TableBegin of the frame) // (We process this in the TableBegin() of the first instance of each table)
// FIXME-TABLE: Contains columns if our work area doesn't allow for scrolling? // FIXME-TABLE: Contains columns if our work area doesn't allow for scrolling?
if (table->InstanceCurrent == 0) if (table->InstanceCurrent == 0)
{ {
@ -662,8 +663,7 @@ void ImGui::TableBeginApplyRequests(ImGuiTable* table)
table->Columns[table->DisplayOrderToIndex[order_n]].DisplayOrder -= (ImGuiTableColumnIdx)reorder_dir; table->Columns[table->DisplayOrderToIndex[order_n]].DisplayOrder -= (ImGuiTableColumnIdx)reorder_dir;
IM_ASSERT(dst_column->DisplayOrder == dst_order - reorder_dir); IM_ASSERT(dst_column->DisplayOrder == dst_order - reorder_dir);
// Display order is stored in both columns->IndexDisplayOrder and table->DisplayOrder[], // Display order is stored in both columns->IndexDisplayOrder and table->DisplayOrder[]. Rebuild later from the former.
// rebuild the later from the former.
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
table->DisplayOrderToIndex[table->Columns[column_n].DisplayOrder] = (ImGuiTableColumnIdx)column_n; table->DisplayOrderToIndex[table->Columns[column_n].DisplayOrder] = (ImGuiTableColumnIdx)column_n;
table->ReorderColumnDir = 0; table->ReorderColumnDir = 0;
@ -737,8 +737,8 @@ static void TableSetupColumnFlags(ImGuiTable* table, ImGuiTableColumn* column, I
} }
} }
// Layout columns for the frame. This is in essence the followup to BeginTable(). // Layout columns for the frame. This is in essence the followup to BeginTable() and this is our largest function.
// Runs on the first call to TableNextRow(), to give a chance for TableSetupColumn() to be called first. // Runs on the first call to TableNextRow(), to give a chance for TableSetupColumn() and other TableSetupXXXXX() functions to be called first.
// FIXME-TABLE: Our width (and therefore our WorkRect) will be minimal in the first frame for _WidthAuto columns. // FIXME-TABLE: Our width (and therefore our WorkRect) will be minimal in the first frame for _WidthAuto columns.
// Increase feedback side-effect with widgets relying on WorkRect.Max.x... Maybe provide a default distribution for _WidthAuto columns? // Increase feedback side-effect with widgets relying on WorkRect.Max.x... Maybe provide a default distribution for _WidthAuto columns?
void ImGui::TableUpdateLayout(ImGuiTable* table) void ImGui::TableUpdateLayout(ImGuiTable* table)
@ -859,8 +859,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
table->IsSettingsDirty = true; table->IsSettingsDirty = true;
// [Part 3] Fix column flags and record a few extra information. // [Part 3] Fix column flags and record a few extra information.
float sum_width_requests = 0.0f; // Sum of all width for fixed and auto-resize columns, excluding width contributed by Stretch columns but including spacing/padding. float sum_width_requests = 0.0f; // Sum of all width for fixed and auto-resize columns, excluding width contributed by Stretch columns but including spacing/padding.
float stretch_sum_weights = 0.0f; // Sum of all weights for stretch columns. float stretch_sum_weights = 0.0f; // Sum of all weights for stretch columns.
table->LeftMostStretchedColumn = table->RightMostStretchedColumn = -1; table->LeftMostStretchedColumn = table->RightMostStretchedColumn = -1;
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
{ {
@ -1145,7 +1145,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
EndPopup(); EndPopup();
} }
// [Part 12] Sanitize and build sort specs before we have a change to use them for display. // [Part 12] Sanitize and build sort specs before we have a chance to use them for display.
// This path will only be exercised when sort specs are modified before header rows (e.g. init or visibility change) // This path will only be exercised when sort specs are modified before header rows (e.g. init or visibility change)
if (table->IsSortSpecsDirty && (table->Flags & ImGuiTableFlags_Sortable)) if (table->IsSortSpecsDirty && (table->Flags & ImGuiTableFlags_Sortable))
TableSortSpecsBuild(table); TableSortSpecsBuild(table);
@ -1166,9 +1166,9 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
} }
// Process hit-testing on resizing borders. Actual size change will be applied in EndTable() // Process hit-testing on resizing borders. Actual size change will be applied in EndTable()
// - Set table->HoveredColumnBorder with a short delay/timer to reduce feedback noise // - Set table->HoveredColumnBorder with a short delay/timer to reduce visual feedback noise.
// - Submit ahead of table contents and header, use ImGuiButtonFlags_AllowItemOverlap to prioritize widgets // - Submit ahead of table contents and header, use ImGuiButtonFlags_AllowItemOverlap to prioritize
// overlapping the same area. // widgets overlapping the same area.
void ImGui::TableUpdateBorders(ImGuiTable* table) void ImGui::TableUpdateBorders(ImGuiTable* table)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -1643,7 +1643,7 @@ ImGuiID ImGui::TableGetColumnResizeID(ImGuiTable* table, int column_n, int insta
return instance_id + 1 + column_n; // FIXME: #6140: still not ideal return instance_id + 1 + column_n; // FIXME: #6140: still not ideal
} }
// Return -1 when table is not hovered. return columns_count if the unused space at the right of visible columns is hovered. // Return -1 when table is not hovered. return columns_count if hovering the unused space at the right of the right-most visible column.
int ImGui::TableGetHoveredColumn() int ImGui::TableGetHoveredColumn()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -1980,6 +1980,7 @@ bool ImGui::TableNextColumn()
// FIXME-TABLE FIXME-OPT: Could probably shortcut some things for non-active or clipped columns. // FIXME-TABLE FIXME-OPT: Could probably shortcut some things for non-active or clipped columns.
void ImGui::TableBeginCell(ImGuiTable* table, int column_n) void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
{ {
ImGuiContext& g = *GImGui;
ImGuiTableColumn* column = &table->Columns[column_n]; ImGuiTableColumn* column = &table->Columns[column_n];
ImGuiWindow* window = table->InnerWindow; ImGuiWindow* window = table->InnerWindow;
table->CurrentColumn = column_n; table->CurrentColumn = column_n;
@ -2004,7 +2005,6 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
window->SkipItems = column->IsSkipItems; window->SkipItems = column->IsSkipItems;
if (column->IsSkipItems) if (column->IsSkipItems)
{ {
ImGuiContext& g = *GImGui;
g.LastItemData.ID = 0; g.LastItemData.ID = 0;
g.LastItemData.StatusFlags = 0; g.LastItemData.StatusFlags = 0;
} }
@ -2023,7 +2023,6 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
} }
// Logging // Logging
ImGuiContext& g = *GImGui;
if (g.LogEnabled && !column->IsSkipItems) if (g.LogEnabled && !column->IsSkipItems)
{ {
LogRenderedText(&window->DC.CursorPos, "|"); LogRenderedText(&window->DC.CursorPos, "|");
@ -2143,7 +2142,7 @@ void ImGui::TableSetColumnWidth(int column_n, float width)
// - All stretch: easy. // - All stretch: easy.
// - One or more fixed + one stretch: easy. // - One or more fixed + one stretch: easy.
// - One or more fixed + more than one stretch: tricky. // - One or more fixed + more than one stretch: tricky.
// Qt when manual resize is enabled only support a single _trailing_ stretch column. // Qt when manual resize is enabled only supports a single _trailing_ stretch column, we support more cases here.
// When forwarding resize from Wn| to Fn+1| we need to be considerate of the _NoResize flag on Fn+1. // When forwarding resize from Wn| to Fn+1| we need to be considerate of the _NoResize flag on Fn+1.
// FIXME-TABLE: Find a way to rewrite all of this so interactions feel more consistent for the user. // FIXME-TABLE: Find a way to rewrite all of this so interactions feel more consistent for the user.
@ -2226,7 +2225,7 @@ void ImGui::TableUpdateColumnsWeightFromWidth(ImGuiTable* table)
{ {
IM_ASSERT(table->LeftMostStretchedColumn != -1 && table->RightMostStretchedColumn != -1); IM_ASSERT(table->LeftMostStretchedColumn != -1 && table->RightMostStretchedColumn != -1);
// Measure existing quantity // Measure existing quantities
float visible_weight = 0.0f; float visible_weight = 0.0f;
float visible_width = 0.0f; float visible_width = 0.0f;
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
@ -2501,11 +2500,9 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
merge_clip_rect.Max.x = ImMax(merge_clip_rect.Max.x, host_rect.Max.x); merge_clip_rect.Max.x = ImMax(merge_clip_rect.Max.x, host_rect.Max.x);
if ((merge_group_n & 2) != 0 && (table->Flags & ImGuiTableFlags_NoHostExtendY) == 0) if ((merge_group_n & 2) != 0 && (table->Flags & ImGuiTableFlags_NoHostExtendY) == 0)
merge_clip_rect.Max.y = ImMax(merge_clip_rect.Max.y, host_rect.Max.y); merge_clip_rect.Max.y = ImMax(merge_clip_rect.Max.y, host_rect.Max.y);
#if 0 //GetForegroundDrawList()->AddRect(merge_group->ClipRect.Min, merge_group->ClipRect.Max, IM_COL32(255, 0, 0, 200), 0.0f, 0, 1.0f); // [DEBUG]
GetOverlayDrawList()->AddRect(merge_group->ClipRect.Min, merge_group->ClipRect.Max, IM_COL32(255, 0, 0, 200), 0.0f, 0, 1.0f); //GetForegroundDrawList()->AddLine(merge_group->ClipRect.Min, merge_clip_rect.Min, IM_COL32(255, 100, 0, 200));
GetOverlayDrawList()->AddLine(merge_group->ClipRect.Min, merge_clip_rect.Min, IM_COL32(255, 100, 0, 200)); //GetForegroundDrawList()->AddLine(merge_group->ClipRect.Max, merge_clip_rect.Max, IM_COL32(255, 100, 0, 200));
GetOverlayDrawList()->AddLine(merge_group->ClipRect.Max, merge_clip_rect.Max, IM_COL32(255, 100, 0, 200));
#endif
remaining_count -= merge_group->ChannelsCount; remaining_count -= merge_group->ChannelsCount;
for (int n = 0; n < (size_for_masks_bitarrays_one >> 2); n++) for (int n = 0; n < (size_for_masks_bitarrays_one >> 2); n++)
remaining_mask[n] &= ~merge_group->ChannelsMask[n]; remaining_mask[n] &= ~merge_group->ChannelsMask[n];
@ -2669,7 +2666,6 @@ ImGuiTableSortSpecs* ImGui::TableGetSortSpecs()
TableUpdateLayout(table); TableUpdateLayout(table);
TableSortSpecsBuild(table); TableSortSpecsBuild(table);
return &table->SortSpecs; return &table->SortSpecs;
} }
@ -2788,7 +2784,7 @@ void ImGui::TableSortSpecsSanitize(ImGuiTable* table)
} }
} }
// Fallback default sort order (if no column had the ImGuiTableColumnFlags_DefaultSort flag) // Fallback default sort order (if no column with the ImGuiTableColumnFlags_DefaultSort flag)
if (sort_order_count == 0 && !(table->Flags & ImGuiTableFlags_SortTristate)) if (sort_order_count == 0 && !(table->Flags & ImGuiTableFlags_SortTristate))
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
{ {
@ -3479,12 +3475,12 @@ static void TableSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandle
if (!save_column) if (!save_column)
continue; 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); }
if (save_size && !column->IsStretch) buf->appendf(" Width=%d", (int)column->WidthOrWeight); if (save_size && !column->IsStretch) { buf->appendf(" Width=%d", (int)column->WidthOrWeight); }
if (save_visible) buf->appendf(" Visible=%d", column->IsEnabled); if (save_visible) { buf->appendf(" Visible=%d", column->IsEnabled); }
if (save_order) buf->appendf(" Order=%d", column->DisplayOrder); if (save_order) { buf->appendf(" Order=%d", column->DisplayOrder); }
if (save_sort && column->SortOrder != -1) buf->appendf(" Sort=%d%c", column->SortOrder, (column->SortDirection == ImGuiSortDirection_Ascending) ? 'v' : '^'); if (save_sort && column->SortOrder != -1) { buf->appendf(" Sort=%d%c", column->SortOrder, (column->SortDirection == ImGuiSortDirection_Ascending) ? 'v' : '^'); }
buf->append("\n"); buf->append("\n");
} }
buf->append("\n"); buf->append("\n");
@ -3532,7 +3528,7 @@ void ImGui::TableGcCompactTransientBuffers(ImGuiTable* table)
IM_ASSERT(table->MemoryCompacted == false); IM_ASSERT(table->MemoryCompacted == false);
table->SortSpecs.Specs = NULL; table->SortSpecs.Specs = NULL;
table->SortSpecsMulti.clear(); table->SortSpecsMulti.clear();
table->IsSortSpecsDirty = true; // FIXME: shouldn't have to leak into user performing a sort table->IsSortSpecsDirty = true; // FIXME: In theory shouldn't have to leak into user performing a sort on resume.
table->ColumnsNames.clear(); table->ColumnsNames.clear();
table->MemoryCompacted = true; table->MemoryCompacted = true;
for (int n = 0; n < table->ColumnsCount; n++) for (int n = 0; n < table->ColumnsCount; n++)

View File

@ -1398,8 +1398,9 @@ void ImGui::AlignTextToFramePadding()
} }
// Horizontal/vertical separating line // Horizontal/vertical separating line
// FIXME: Surprisingly, this seemingly simple widget is adjacent to MANY different legacy/tricky layout issues. // FIXME: Surprisingly, this seemingly trivial widget is a victim of many different legacy/tricky layout issues.
void ImGui::SeparatorEx(ImGuiSeparatorFlags flags) // Note how thickness == 1.0f is handled specifically as not moving CursorPos by 'thickness', but other values are.
void ImGui::SeparatorEx(ImGuiSeparatorFlags flags, float thickness)
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems) if (window->SkipItems)
@ -1407,8 +1408,8 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags)
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_ASSERT(ImIsPowerOfTwo(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical))); // Check that only 1 option is selected IM_ASSERT(ImIsPowerOfTwo(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical))); // Check that only 1 option is selected
IM_ASSERT(thickness > 0.0f);
const float thickness = 1.0f; // Cannot use g.Style.SeparatorTextSize yet for various reasons.
if (flags & ImGuiSeparatorFlags_Vertical) if (flags & ImGuiSeparatorFlags_Vertical)
{ {
// Vertical separator, for menu bars (use current line height). // Vertical separator, for menu bars (use current line height).
@ -1442,6 +1443,8 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags)
x2 = table->Columns[table->CurrentColumn].MaxX; x2 = table->Columns[table->CurrentColumn].MaxX;
} }
// Before Tables API happened, we relied on Separator() to span all columns of a Columns() set.
// We currently don't need to provide the same feature for tables because tables naturally have border features.
ImGuiOldColumns* columns = (flags & ImGuiSeparatorFlags_SpanAllColumns) ? window->DC.CurrentColumns : NULL; ImGuiOldColumns* columns = (flags & ImGuiSeparatorFlags_SpanAllColumns) ? window->DC.CurrentColumns : NULL;
if (columns) if (columns)
PushColumnsBackground(); PushColumnsBackground();
@ -1451,8 +1454,8 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags)
const float thickness_for_layout = (thickness == 1.0f) ? 0.0f : thickness; // FIXME: See 1.70/1.71 Separator() change: makes legacy 1-px separator not affect layout yet. Should change. const float thickness_for_layout = (thickness == 1.0f) ? 0.0f : thickness; // FIXME: See 1.70/1.71 Separator() change: makes legacy 1-px separator not affect layout yet. Should change.
const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y + thickness)); const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y + thickness));
ItemSize(ImVec2(0.0f, thickness_for_layout)); ItemSize(ImVec2(0.0f, thickness_for_layout));
const bool item_visible = ItemAdd(bb, 0);
if (item_visible) if (ItemAdd(bb, 0))
{ {
// Draw // Draw
window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_Separator)); window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_Separator));
@ -1475,10 +1478,11 @@ void ImGui::Separator()
if (window->SkipItems) if (window->SkipItems)
return; return;
// Those flags should eventually be overridable by the user // Those flags should eventually be configurable by the user
// FIXME: We cannot g.Style.SeparatorTextBorderSize for thickness as it relates to SeparatorText() which is a decorated separator, not defaulting to 1.0f.
ImGuiSeparatorFlags flags = (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal; ImGuiSeparatorFlags flags = (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal;
flags |= ImGuiSeparatorFlags_SpanAllColumns; // NB: this only applies to legacy Columns() api as they relied on Separator() a lot. flags |= ImGuiSeparatorFlags_SpanAllColumns; // NB: this only applies to legacy Columns() api as they relied on Separator() a lot.
SeparatorEx(flags); SeparatorEx(flags, 1.0f);
} }
void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end, float extra_w) void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end, float extra_w)
@ -1538,8 +1542,8 @@ void ImGui::SeparatorText(const char* label)
return; return;
// The SeparatorText() vs SeparatorTextEx() distinction is designed to be considerate that we may want: // The SeparatorText() vs SeparatorTextEx() distinction is designed to be considerate that we may want:
// - allow headers to be draggable items (would require a stable ID + a noticeable highlight) // - allow separator-text to be draggable items (would require a stable ID + a noticeable highlight)
// - this high-level entry point to allow formatting? (may require ID separate from formatted string) // - this high-level entry point to allow formatting? (which in turns may require ID separate from formatted string)
// - because of this we probably can't turn 'const char* label' into 'const char* fmt, ...' // - because of this we probably can't turn 'const char* label' into 'const char* fmt, ...'
// Otherwise, we can decide that users wanting to drag this would layout a dedicated drag-item, // Otherwise, we can decide that users wanting to drag this would layout a dedicated drag-item,
// and then we can turn this into a format function. // and then we can turn this into a format function.
@ -6622,20 +6626,6 @@ bool ImGui::BeginListBox(const char* label, const ImVec2& size_arg)
return true; return true;
} }
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// OBSOLETED in 1.81 (from February 2021)
bool ImGui::ListBoxHeader(const char* label, int items_count, int height_in_items)
{
// If height_in_items == -1, default height is maximum 7.
ImGuiContext& g = *GImGui;
float height_in_items_f = (height_in_items < 0 ? ImMin(items_count, 7) : height_in_items) + 0.25f;
ImVec2 size;
size.x = 0.0f;
size.y = GetTextLineHeightWithSpacing() * height_in_items_f + g.Style.FramePadding.y * 2.0f;
return BeginListBox(label, size);
}
#endif
void ImGui::EndListBox() void ImGui::EndListBox()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;