Browse Source

Layout: Fixed mixing up SameLine() and SetCursorPos() together. SameLine() is a stateful.

+ minor unrelatedcomments.
pull/5234/head
ocornut 3 years ago
parent
commit
5b29d14783
  1. 4
      docs/CHANGELOG.txt
  2. 12
      imgui.cpp
  3. 2
      imgui.h
  4. 7
      imgui_demo.cpp
  5. 1
      imgui_internal.h
  6. 5
      imgui_widgets.cpp

4
docs/CHANGELOG.txt

@ -56,6 +56,9 @@ Other Changes:
or interacting with a game/3D view). or interacting with a game/3D view).
- Clipper: Fixed a regression in 1.86 when not calling clipper.End() and late destructing the - Clipper: Fixed a regression in 1.86 when not calling clipper.End() and late destructing the
clipper instance. High-level languages (Lua,Rust etc.) would typically be affected. (#4822) clipper instance. High-level languages (Lua,Rust etc.) would typically be affected. (#4822)
- Layout: Fixed mixing up SameLine() and SetCursorPos() together from creating situations where line
height would be emitted from the wrong location (e.g. 'ItemA+SameLine()+SetCursorPos()+ItemB' would
emit ItemA worth of height from the position of ItemB, which is not necessarily aligned with ItemA).
- Sliders, Drags: Fixed dragging when using hexadecimal display format string. (#5165, #3133) - Sliders, Drags: Fixed dragging when using hexadecimal display format string. (#5165, #3133)
- Sliders, Drags: Fixed manual input when using hexadecimal display format string. (#5165, #3133) - Sliders, Drags: Fixed manual input when using hexadecimal display format string. (#5165, #3133)
- InputScalar: Fixed manual input when using %03d style width in display format string. (#5165, #3133) - InputScalar: Fixed manual input when using %03d style width in display format string. (#5165, #3133)
@ -109,6 +112,7 @@ Breaking Changes:
- Added io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() functions, - Added io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() functions,
obsoleting writing directly to io.MousePos, io.MouseDown[], io.MouseWheel, etc. obsoleting writing directly to io.MousePos, io.MouseDown[], io.MouseWheel, etc.
- This enable input queue trickling to support low framerates. (#2787, #1992, #3383, #2525, #1320) - This enable input queue trickling to support low framerates. (#2787, #1992, #3383, #2525, #1320)
- For all calls to IO new functions, the Dear ImGui context should be bound/current.
- Reworked IO keyboard input API: (#4921, #2625, #3724) [@thedmd, @ocornut] - Reworked IO keyboard input API: (#4921, #2625, #3724) [@thedmd, @ocornut]
- Added io.AddKeyEvent() function, obsoleting writing directly to io.KeyMap[], io.KeysDown[] arrays. - Added io.AddKeyEvent() function, obsoleting writing directly to io.KeyMap[], io.KeysDown[] arrays.
- For keyboard modifiers, you can call io.AddKeyEvent() with ImGuiKey_ModXXX values, - For keyboard modifiers, you can call io.AddKeyEvent() with ImGuiKey_ModXXX values,

12
imgui.cpp

@ -395,6 +395,7 @@ CODE
- Backend writing to io.MouseDown[] -> backend should call io.AddMouseButtonEvent() - Backend writing to io.MouseDown[] -> backend should call io.AddMouseButtonEvent()
- Backend writing to io.MouseWheel -> backend should call io.AddMouseWheelEvent() - Backend writing to io.MouseWheel -> backend should call io.AddMouseWheelEvent()
- Backend writing to io.MouseHoveredViewport -> backend should call io.AddMouseViewportEvent() [Docking branch w/ multi-viewports only] - Backend writing to io.MouseHoveredViewport -> backend should call io.AddMouseViewportEvent() [Docking branch w/ multi-viewports only]
note: for all calls to IO new functions, the Dear ImGui context should be bound/current.
- 2022/01/10 (1.87) - inputs: reworked keyboard IO. Removed io.KeyMap[], io.KeysDown[] in favor of calling io.AddKeyEvent(). Removed GetKeyIndex(), now unecessary. All IsKeyXXX() functions now take ImGuiKey values. All features are still functional until IMGUI_DISABLE_OBSOLETE_KEYIO is defined. Read Changelog and Release Notes for details. - 2022/01/10 (1.87) - inputs: reworked keyboard IO. Removed io.KeyMap[], io.KeysDown[] in favor of calling io.AddKeyEvent(). Removed GetKeyIndex(), now unecessary. All IsKeyXXX() functions now take ImGuiKey values. All features are still functional until IMGUI_DISABLE_OBSOLETE_KEYIO is defined. Read Changelog and Release Notes for details.
- IsKeyPressed(MY_NATIVE_KEY_XXX) -> use IsKeyPressed(ImGuiKey_XXX) - IsKeyPressed(MY_NATIVE_KEY_XXX) -> use IsKeyPressed(ImGuiKey_XXX)
- IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) -> use IsKeyPressed(ImGuiKey_XXX) - IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) -> use IsKeyPressed(ImGuiKey_XXX)
@ -6490,6 +6491,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->DC.IdealMaxPos = window->DC.CursorStartPos; window->DC.IdealMaxPos = window->DC.CursorStartPos;
window->DC.CurrLineSize = window->DC.PrevLineSize = ImVec2(0.0f, 0.0f); window->DC.CurrLineSize = window->DC.PrevLineSize = ImVec2(0.0f, 0.0f);
window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f; window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f;
window->DC.IsSameLine = false;
window->DC.NavLayerCurrent = ImGuiNavLayer_Main; window->DC.NavLayerCurrent = ImGuiNavLayer_Main;
window->DC.NavLayersActiveMask = window->DC.NavLayersActiveMaskNext; window->DC.NavLayersActiveMask = window->DC.NavLayersActiveMaskNext;
@ -8203,14 +8205,16 @@ void ImGui::ItemSize(const ImVec2& size, float text_baseline_y)
// In theory we should be offsetting the starting position (window->DC.CursorPos), that will be the topic of a larger refactor, // In theory we should be offsetting the starting position (window->DC.CursorPos), that will be the topic of a larger refactor,
// but since ItemSize() is not yet an API that moves the cursor (to handle e.g. wrapping) enlarging the height has the same effect. // but since ItemSize() is not yet an API that moves the cursor (to handle e.g. wrapping) enlarging the height has the same effect.
const float offset_to_match_baseline_y = (text_baseline_y >= 0) ? ImMax(0.0f, window->DC.CurrLineTextBaseOffset - text_baseline_y) : 0.0f; const float offset_to_match_baseline_y = (text_baseline_y >= 0) ? ImMax(0.0f, window->DC.CurrLineTextBaseOffset - text_baseline_y) : 0.0f;
const float line_height = ImMax(window->DC.CurrLineSize.y, size.y + offset_to_match_baseline_y);
const float line_y1 = window->DC.IsSameLine ? window->DC.CursorPosPrevLine.y : window->DC.CursorPos.y;
const float line_height = ImMax(window->DC.CurrLineSize.y, /*ImMax(*/window->DC.CursorPos.y - line_y1/*, 0.0f)*/ + size.y + offset_to_match_baseline_y);
// Always align ourselves on pixel boundaries // Always align ourselves on pixel boundaries
//if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG] //if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG]
window->DC.CursorPosPrevLine.x = window->DC.CursorPos.x + size.x; window->DC.CursorPosPrevLine.x = window->DC.CursorPos.x + size.x;
window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y; window->DC.CursorPosPrevLine.y = line_y1;
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); // Next line window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); // Next line
window->DC.CursorPos.y = IM_FLOOR(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y); // Next line window->DC.CursorPos.y = IM_FLOOR(line_y1 + line_height + g.Style.ItemSpacing.y); // Next line
window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x); window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x);
window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y - g.Style.ItemSpacing.y); window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y - g.Style.ItemSpacing.y);
//if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG] //if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG]
@ -8219,6 +8223,7 @@ void ImGui::ItemSize(const ImVec2& size, float text_baseline_y)
window->DC.CurrLineSize.y = 0.0f; window->DC.CurrLineSize.y = 0.0f;
window->DC.PrevLineTextBaseOffset = ImMax(window->DC.CurrLineTextBaseOffset, text_baseline_y); window->DC.PrevLineTextBaseOffset = ImMax(window->DC.CurrLineTextBaseOffset, text_baseline_y);
window->DC.CurrLineTextBaseOffset = 0.0f; window->DC.CurrLineTextBaseOffset = 0.0f;
window->DC.IsSameLine = false;
// Horizontal layout mode // Horizontal layout mode
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
@ -8322,6 +8327,7 @@ void ImGui::SameLine(float offset_from_start_x, float spacing_w)
} }
window->DC.CurrLineSize = window->DC.PrevLineSize; window->DC.CurrLineSize = window->DC.PrevLineSize;
window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset; window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset;
window->DC.IsSameLine = true;
} }
ImVec2 ImGui::GetCursorScreenPos() ImVec2 ImGui::GetCursorScreenPos()

2
imgui.h

@ -65,7 +65,7 @@ Index of this file:
// Version // Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.88 WIP" #define IMGUI_VERSION "1.88 WIP"
#define IMGUI_VERSION_NUM 18717 #define IMGUI_VERSION_NUM 18718
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE #define IMGUI_HAS_TABLE

7
imgui_demo.cpp

@ -1855,10 +1855,9 @@ static void ShowDemoWindowWidgets()
ImGui::Combo("Display Mode", &display_mode, "Auto/Current\0None\0RGB Only\0HSV Only\0Hex Only\0"); ImGui::Combo("Display Mode", &display_mode, "Auto/Current\0None\0RGB Only\0HSV Only\0Hex Only\0");
ImGui::SameLine(); HelpMarker( ImGui::SameLine(); HelpMarker(
"ColorEdit defaults to displaying RGB inputs if you don't specify a display mode, " "ColorEdit defaults to displaying RGB inputs if you don't specify a display mode, "
"but the user can change it with a right-click.\n\nColorPicker defaults to displaying RGB+HSV+Hex " "but the user can change it with a right-click on those inputs.\n\nColorPicker defaults to displaying RGB+HSV+Hex "
"if you don't specify a display mode.\n\nYou can change the defaults using SetColorEditOptions()."); "if you don't specify a display mode.\n\nYou can change the defaults using SetColorEditOptions().");
ImGui::Combo("Picker Mode", &picker_mode, "Auto/Current\0Hue bar + SV rect\0Hue wheel + SV triangle\0"); ImGui::SameLine(); HelpMarker("When not specified explicitly (Auto/Current mode), user can right-click the picker to change mode.");
ImGui::SameLine(); HelpMarker("User can right-click the picker to change mode.");
ImGuiColorEditFlags flags = misc_flags; ImGuiColorEditFlags flags = misc_flags;
if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4() if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4()
if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar; if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar;
@ -3421,7 +3420,7 @@ static void ShowDemoWindowPopups()
{ {
HelpMarker("Text() elements don't have stable identifiers so we need to provide one."); HelpMarker("Text() elements don't have stable identifiers so we need to provide one.");
static float value = 0.5f; static float value = 0.5f;
ImGui::Text("Value = %.3f <-- (1) right-click this value", value); ImGui::Text("Value = %.3f <-- (1) right-click this text", value);
if (ImGui::BeginPopupContextItem("my popup")) if (ImGui::BeginPopupContextItem("my popup"))
{ {
if (ImGui::Selectable("Set to zero")) value = 0.0f; if (ImGui::Selectable("Set to zero")) value = 0.0f;

1
imgui_internal.h

@ -1979,6 +1979,7 @@ struct IMGUI_API ImGuiWindowTempData
ImVec2 PrevLineSize; ImVec2 PrevLineSize;
float CurrLineTextBaseOffset; // Baseline offset (0.0f by default on a new line, generally == style.FramePadding.y when a framed item has been added). float CurrLineTextBaseOffset; // Baseline offset (0.0f by default on a new line, generally == style.FramePadding.y when a framed item has been added).
float PrevLineTextBaseOffset; float PrevLineTextBaseOffset;
bool IsSameLine;
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 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.
ImVec1 GroupOffset; ImVec1 GroupOffset;

5
imgui_widgets.cpp

@ -1342,6 +1342,7 @@ void ImGui::NewLine()
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
const ImGuiLayoutType backup_layout_type = window->DC.LayoutType; const ImGuiLayoutType backup_layout_type = window->DC.LayoutType;
window->DC.LayoutType = ImGuiLayoutType_Vertical; window->DC.LayoutType = ImGuiLayoutType_Vertical;
window->DC.IsSameLine = false;
if (window->DC.CurrLineSize.y > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height. if (window->DC.CurrLineSize.y > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height.
ItemSize(ImVec2(0, 0)); ItemSize(ImVec2(0, 0));
else else
@ -1734,6 +1735,7 @@ bool ImGui::BeginComboPreview()
window->DC.CursorPos = preview_data->PreviewRect.Min + g.Style.FramePadding; window->DC.CursorPos = preview_data->PreviewRect.Min + g.Style.FramePadding;
window->DC.CursorMaxPos = window->DC.CursorPos; window->DC.CursorMaxPos = window->DC.CursorPos;
window->DC.LayoutType = ImGuiLayoutType_Horizontal; window->DC.LayoutType = ImGuiLayoutType_Horizontal;
window->DC.IsSameLine = false;
PushClipRect(preview_data->PreviewRect.Min, preview_data->PreviewRect.Max, true); PushClipRect(preview_data->PreviewRect.Min, preview_data->PreviewRect.Max, true);
return true; return true;
@ -1759,6 +1761,7 @@ void ImGui::EndComboPreview()
window->DC.CursorPosPrevLine = preview_data->BackupCursorPosPrevLine; window->DC.CursorPosPrevLine = preview_data->BackupCursorPosPrevLine;
window->DC.PrevLineTextBaseOffset = preview_data->BackupPrevLineTextBaseOffset; window->DC.PrevLineTextBaseOffset = preview_data->BackupPrevLineTextBaseOffset;
window->DC.LayoutType = preview_data->BackupLayout; window->DC.LayoutType = preview_data->BackupLayout;
window->DC.IsSameLine = false;
preview_data->PreviewRect = ImRect(); preview_data->PreviewRect = ImRect();
} }
@ -6730,6 +6733,7 @@ bool ImGui::BeginMenuBar()
// We overwrite CursorMaxPos because BeginGroup sets it to CursorPos (essentially the .EmitItem hack in EndMenuBar() would need something analogous here, maybe a BeginGroupEx() with flags). // We overwrite CursorMaxPos because BeginGroup sets it to CursorPos (essentially the .EmitItem hack in EndMenuBar() would need something analogous here, maybe a BeginGroupEx() with flags).
window->DC.CursorPos = window->DC.CursorMaxPos = ImVec2(bar_rect.Min.x + window->DC.MenuBarOffset.x, bar_rect.Min.y + window->DC.MenuBarOffset.y); window->DC.CursorPos = window->DC.CursorMaxPos = ImVec2(bar_rect.Min.x + window->DC.MenuBarOffset.x, bar_rect.Min.y + window->DC.MenuBarOffset.y);
window->DC.LayoutType = ImGuiLayoutType_Horizontal; window->DC.LayoutType = ImGuiLayoutType_Horizontal;
window->DC.IsSameLine = false;
window->DC.NavLayerCurrent = ImGuiNavLayer_Menu; window->DC.NavLayerCurrent = ImGuiNavLayer_Menu;
window->DC.MenuBarAppending = true; window->DC.MenuBarAppending = true;
AlignTextToFramePadding(); AlignTextToFramePadding();
@ -6773,6 +6777,7 @@ void ImGui::EndMenuBar()
g.GroupStack.back().EmitItem = false; g.GroupStack.back().EmitItem = false;
EndGroup(); // Restore position on layer 0 EndGroup(); // Restore position on layer 0
window->DC.LayoutType = ImGuiLayoutType_Vertical; window->DC.LayoutType = ImGuiLayoutType_Vertical;
window->DC.IsSameLine = false;
window->DC.NavLayerCurrent = ImGuiNavLayer_Main; window->DC.NavLayerCurrent = ImGuiNavLayer_Main;
window->DC.MenuBarAppending = false; window->DC.MenuBarAppending = false;
} }

Loading…
Cancel
Save