diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index d7f4ca26a..641e11c1b 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -34,6 +34,7 @@ HOW TO UPDATE? Breaking Changes: - IO: changed AddInputCharacter(unsigned short c) signature to AddInputCharacter(unsigned int c). +- Renamed SetNextTreeNodeOpen() to SetNextItemOpen(). Kept inline redirection function (will obsolete). Other Changes: - Columns: Fixed Separator from creating an extraneous draw command. (#125) diff --git a/imgui.cpp b/imgui.cpp index 781614d2f..3baeed9d6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -369,6 +369,7 @@ CODE When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2019/05/13 (1.71) - renamed SetNextTreeNodeOpen() to SetNextItemOpen(). Kept inline redirection function (will obsolete). - 2019/05/11 (1.71) - changed io.AddInputCharacter(unsigned short c) signature to io.AddInputCharacter(unsigned int c). - 2019/04/29 (1.70) - improved ImDrawList thick strokes (>1.0f) preserving correct thickness up to 90 degrees angles (e.g. rectangles). If you have custom rendering using thick lines, they will appear thicker now. - 2019/04/29 (1.70) - removed GetContentRegionAvailWidth(), use GetContentRegionAvail().x instead. Kept inline redirection function (will obsolete). @@ -2840,6 +2841,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg) window->DC.LastItemId = id; window->DC.LastItemRect = bb; window->DC.LastItemStatusFlags = ImGuiItemStatusFlags_None; + g.NextItemData.Flags = ImGuiNextItemDataFlags_None; #ifdef IMGUI_ENABLE_TEST_ENGINE if (id != 0) @@ -5794,8 +5796,9 @@ void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWind void ImGui::SetNextItemWidth(float item_width) { - ImGuiWindow* window = GetCurrentWindow(); - window->DC.NextItemWidth = item_width; + ImGuiContext& g = *GImGui; + g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasWidth; + g.NextItemData.Width = item_width; } void ImGui::PushItemWidth(float item_width) @@ -5825,15 +5828,16 @@ void ImGui::PopItemWidth() } // Calculate default item width given value passed to PushItemWidth() or SetNextItemWidth(), -// Then consume the +// Then _consume_ the SetNextItemWidth() data. float ImGui::GetNextItemWidth() { - ImGuiWindow* window = GImGui->CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; float w; - if (window->DC.NextItemWidth != FLT_MAX) + if (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasWidth) { - w = window->DC.NextItemWidth; - window->DC.NextItemWidth = FLT_MAX; + w = g.NextItemData.Width; + g.NextItemData.Flags &= ~ImGuiNextItemDataFlags_HasWidth; } else { @@ -5852,10 +5856,10 @@ float ImGui::GetNextItemWidth() // (rarely used, which is why we avoid calling this from GetNextItemWidth() and instead do a backup/restore here) float ImGui::CalcItemWidth() { - ImGuiWindow* window = GImGui->CurrentWindow; - float backup_next_item_width = window->DC.NextItemWidth; + ImGuiContext& g = *GImGui; + ImGuiNextItemDataFlags backup_flags = g.NextItemData.Flags; float w = GetNextItemWidth(); - window->DC.NextItemWidth = backup_next_item_width; + g.NextItemData.Flags = backup_flags; return w; } diff --git a/imgui.h b/imgui.h index 7c05d7c4b..0bcea46bd 100644 --- a/imgui.h +++ b/imgui.h @@ -494,9 +494,9 @@ namespace ImGui IMGUI_API void TreePop(); // ~ Unindent()+PopId() IMGUI_API void TreeAdvanceToLabelPos(); // advance cursor x position by GetTreeNodeToLabelSpacing() IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode - IMGUI_API void SetNextTreeNodeOpen(bool is_open, ImGuiCond cond = 0); // set next TreeNode/CollapsingHeader open state. IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop(). IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header + IMGUI_API void SetNextItemOpen(bool is_open, ImGuiCond cond = 0); // set next TreeNode/CollapsingHeader open state. // Widgets: Selectables // - A selectable highlights when hovered, and can display another color when selected. @@ -1173,7 +1173,7 @@ enum ImGuiMouseCursor_ #endif }; -// Enumateration for ImGui::SetWindow***(), SetNextWindow***(), SetNextTreeNode***() functions +// Enumateration for ImGui::SetWindow***(), SetNextWindow***(), SetNextItem***() functions // Represent a condition. // Important: Treat as a regular enum! Do NOT combine multiple values using binary operators! All the functions above treat 0 as a shortcut to ImGuiCond_Always. enum ImGuiCond_ @@ -1529,6 +1529,9 @@ struct ImGuiPayload #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS namespace ImGui { + // OBSOLETED in 1.71 (from May 2019) + static inline void SetNextTreeNodeOpen(bool open, ImGuiCond cond = 0) { SetNextItemOpen(open, cond); } + // OBSOLETED in 1.70 (from May 2019) static inline float GetContentRegionAvailWidth() { return GetContentRegionAvail().x; } // OBSOLETED in 1.69 (from Mar 2019) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index f9cb7c6b4..7ce699d17 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -568,13 +568,20 @@ static void ShowDemoWindowWidgets() if (ImGui::TreeNode("Basic trees")) { for (int i = 0; i < 5; i++) + { + // Use SetNextItemOpen() so set the default state of a node to be open. + // We could also use TreeNodeEx() with the ImGuiTreeNodeFlags_DefaultOpen flag to achieve the same thing! + if (i == 0) + ImGui::SetNextItemOpen(true, ImGuiCond_Once); + if (ImGui::TreeNode((void*)(intptr_t)i, "Child %d", i)) { ImGui::Text("blah blah"); ImGui::SameLine(); - if (ImGui::SmallButton("button")) { }; + if (ImGui::SmallButton("button")) {}; ImGui::TreePop(); } + } ImGui::TreePop(); } diff --git a/imgui_internal.h b/imgui_internal.h index 494d54812..d45086578 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -72,6 +72,7 @@ struct ImGuiItemHoveredDataBackup; // Backup and restore IsItemHovered() intern struct ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only struct ImGuiNavMoveResult; // Result of a directional navigation move query result struct ImGuiNextWindowData; // Storage for SetNextWindow** functions +struct ImGuiNextItemData; // Storage for SetNextItem** functions struct ImGuiPopupData; // Storage for current popup stack struct ImGuiSettingsHandler; // Storage for one type registered in the .ini file struct ImGuiStyleMod; // Stacked style modifier, backup of modified data so we can restore it @@ -90,6 +91,7 @@ typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // F typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight() typedef int ImGuiNavDirSourceFlags; // -> enum ImGuiNavDirSourceFlags_ // Flags: for GetNavInputAmount2d() typedef int ImGuiNavMoveFlags; // -> enum ImGuiNavMoveFlags_ // Flags: for navigation requests +typedef int ImGuiNextItemDataFlags; // -> enum ImGuiNextItemDataFlags_ // Flags: for SetNextItemXXX() functions typedef int ImGuiNextWindowDataFlags; // -> enum ImGuiNextWindowDataFlags_// Flags: for SetNextWindowXXX() functions typedef int ImGuiSeparatorFlags; // -> enum ImGuiSeparatorFlags_ // Flags: for SeparatorEx() typedef int ImGuiSliderFlags; // -> enum ImGuiSliderFlags_ // Flags: for SliderBehavior() @@ -778,6 +780,24 @@ struct ImGuiNextWindowData inline void ClearFlags() { Flags = ImGuiNextWindowDataFlags_None; } }; +enum ImGuiNextItemDataFlags_ +{ + ImGuiNextItemDataFlags_None = 0, + ImGuiNextItemDataFlags_HasWidth = 1 << 0, + ImGuiNextItemDataFlags_HasOpen = 1 << 1 +}; + +struct ImGuiNextItemData +{ + ImGuiNextItemDataFlags Flags; + float Width; // Set by SetNextItemWidth(). + bool OpenVal; // Set by SetNextItemOpen() function. + ImGuiCond OpenCond; + + ImGuiNextItemData() { memset(this, 0, sizeof(*this)); } + inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; } +}; + //----------------------------------------------------------------------------- // Tabs //----------------------------------------------------------------------------- @@ -858,8 +878,7 @@ struct ImGuiContext // Next window/item data ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions - bool NextTreeNodeOpenVal; // Storage for SetNextTreeNode** functions - ImGuiCond NextTreeNodeOpenCond; + ImGuiNextItemData NextItemData; // Storage for SetNextItem** functions // Shared stacks ImVector ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() @@ -1041,9 +1060,6 @@ struct ImGuiContext LastActiveId = 0; LastActiveIdTimer = 0.0f; - NextTreeNodeOpenVal = false; - NextTreeNodeOpenCond = 0; - NavWindow = NULL; NavId = NavActivateId = NavActivateDownId = NavActivatePressedId = NavInputId = 0; NavJustTabbedId = NavJustMovedToId = NavJustMovedToMultiSelectScopeId = NavNextActivateId = 0; @@ -1166,7 +1182,6 @@ struct IMGUI_API ImGuiWindowTempData // We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings. ImGuiItemFlags ItemFlags; // == ItemFlagsStack.back() [empty == ImGuiItemFlags_Default] float ItemWidth; // == ItemWidthStack.back(). 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window - float NextItemWidth; float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f] ImVectorItemFlagsStack; ImVector ItemWidthStack; @@ -1202,7 +1217,6 @@ struct IMGUI_API ImGuiWindowTempData ItemFlags = ImGuiItemFlags_Default_; ItemWidth = 0.0f; - NextItemWidth = +FLT_MAX; TextWrapPos = -1.0f; memset(StackSizesBackup, 0, sizeof(StackSizesBackup)); @@ -1569,7 +1583,7 @@ namespace ImGui IMGUI_API bool SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format, float power, ImGuiSliderFlags flags, ImRect* out_grab_bb); IMGUI_API bool SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f, float hover_visibility_delay = 0.0f); IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL); - IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextTreeNodeOpened() data, if any. May return true when logging + IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextItemOpen() data, if any. May return true when logging IMGUI_API void TreePushOverrideID(ImGuiID id); // Template functions are instantiated in imgui_widgets.cpp for a finite number of types. diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 490b672d7..301634c90 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -4906,7 +4906,7 @@ void ImGui::ColorPickerOptionsPopup(const float* ref_col, ImGuiColorEditFlags fl // - TreePop() // - TreeAdvanceToLabelPos() // - GetTreeNodeToLabelSpacing() -// - SetNextTreeNodeOpen() +// - SetNextItemOpen() // - CollapsingHeader() //------------------------------------------------------------------------- @@ -5000,17 +5000,17 @@ bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) if (flags & ImGuiTreeNodeFlags_Leaf) return true; - // We only write to the tree storage if the user clicks (or explicitly use SetNextTreeNode*** functions) + // We only write to the tree storage if the user clicks (or explicitly use the SetNextItemOpen function) ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; ImGuiStorage* storage = window->DC.StateStorage; bool is_open; - if (g.NextTreeNodeOpenCond != 0) + if (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasOpen) { - if (g.NextTreeNodeOpenCond & ImGuiCond_Always) + if (g.NextItemData.OpenCond & ImGuiCond_Always) { - is_open = g.NextTreeNodeOpenVal; + is_open = g.NextItemData.OpenVal; storage->SetInt(id, is_open); } else @@ -5019,7 +5019,7 @@ bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) const int stored_value = storage->GetInt(id, -1); if (stored_value == -1) { - is_open = g.NextTreeNodeOpenVal; + is_open = g.NextItemData.OpenVal; storage->SetInt(id, is_open); } else @@ -5027,7 +5027,6 @@ bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) is_open = stored_value != 0; } } - g.NextTreeNodeOpenCond = 0; } else { @@ -5256,13 +5255,14 @@ float ImGui::GetTreeNodeToLabelSpacing() return g.FontSize + (g.Style.FramePadding.x * 2.0f); } -void ImGui::SetNextTreeNodeOpen(bool is_open, ImGuiCond cond) +void ImGui::SetNextItemOpen(bool is_open, ImGuiCond cond) { ImGuiContext& g = *GImGui; if (g.CurrentWindow->SkipItems) return; - g.NextTreeNodeOpenVal = is_open; - g.NextTreeNodeOpenCond = cond ? cond : ImGuiCond_Always; + g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasOpen; + g.NextItemData.OpenVal = is_open; + g.NextItemData.OpenCond = cond ? cond : ImGuiCond_Always; } // CollapsingHeader returns true when opened but do not indent nor push into the ID stack (because of the ImGuiTreeNodeFlags_NoTreePushOnOpen flag).