diff --git a/imgui.cpp b/imgui.cpp index 65a1491a..743616eb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -414,6 +414,7 @@ - window: get size/pos helpers given names (see discussion in #249) - window: a collapsed window can be stuck behind the main menu bar? - window: detect extra End() call that pop the "Debug" window out and assert at call site instead of later. + - window: consider renaming "GetWindowFont" which conflict with old Windows #define (#340) - window/tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic. - draw-list: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). !- scrolling: allow immediately effective change of scroll if we haven't appended items yet @@ -5545,6 +5546,7 @@ bool ImGui::TreeNodeBehaviorIsOpened(ImGuiID id, ImGuiTreeNodeFlags flags) return opened; } +// FIXME: Split into CollapsingHeader(label, default_open?) and TreeNodeBehavior(label), obsolete the 4 parameters function. bool ImGui::CollapsingHeader(const char* label, const char* str_id, bool display_frame, bool default_open) { ImGuiWindow* window = GetCurrentWindow(); @@ -7122,7 +7124,7 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f } // Edit a string of text -// FIXME: This is rather complex partly because we are doing UTF8 > u16 > UTF8 conversions on the go to more easily handle stb_textedit calls. Ideally we should stay in UTF-8 all the time. +// FIXME: Rather messy function partly because we are doing UTF8 > u16 > UTF8 conversions on the go to more easily handle stb_textedit calls. Ideally we should stay in UTF-8 all the time. See https://github.com/nothings/stb/issues/188 bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) { ImGuiWindow* window = GetCurrentWindow(); @@ -7141,7 +7143,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const bool is_editable = (flags & ImGuiInputTextFlags_ReadOnly) == 0; const bool is_password = (flags & ImGuiInputTextFlags_Password) != 0; - ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true); + const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true); ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), is_multiline ? ImGui::GetTextLineHeight() * 8.0f : label_size.y); // Arbitrary default of 8 lines high for multi-line const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size + style.FramePadding*2.0f); const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f)); @@ -7210,7 +7212,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 { // Start edition // Take a copy of the initial buffer value (both in original UTF-8 format and converted to wchar) - // From the moment we focused we are ignoring the content of 'buf' + // From the moment we focused we are ignoring the content of 'buf' (unless we are in read-only mode) const int prev_len_w = edit_state.CurLenW; edit_state.Text.resize(buf_size+1); // wchar count <= utf-8 count. we use +1 to make sure that .Data isn't NULL so it doesn't crash. edit_state.InitialText.resize(buf_size+1); // utf-8. we use +1 to make sure that .Data isn't NULL so it doesn't crash. @@ -7271,7 +7273,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 edit_state.BufSizeA = buf_size; // Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget. - // Down the line we should have a cleaner concept of focused vs active in the library. + // Down the line we should have a cleaner library-wide concept of Selected vs Active. g.ActiveIdAllowHoveringOthers = !io.MouseDown[0]; // Edit in progress @@ -7419,9 +7421,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 else { // Apply new value immediately - copy modified buffer back - // Note that as soon as we can focus into the input box, the in-widget value gets priority over any underlying modification of the input buffer - // FIXME: We actually always render 'buf' when calling DrawList->AddText - // FIXME-OPT: CPU waste to do this every time the widget is active, should mark dirty state from the stb_textedit callbacks + // Note that as soon as the input box is active, the in-widget value gets priority over any underlying modification of the input buffer + // FIXME: We actually always render 'buf' when calling DrawList->AddText, making the comment above incorrect. + // FIXME-OPT: CPU waste to do this every time the widget is active, should mark dirty state from the stb_textedit callbacks. if (is_editable) { edit_state.TempTextBuffer.resize(edit_state.Text.Size * 4); diff --git a/imgui_internal.h b/imgui_internal.h index 22acb810..c58d903e 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -196,33 +196,33 @@ enum ImGuiDataType // NB: we can't rely on ImVec2 math operators being available here struct IMGUI_API ImRect { - ImVec2 Min; // Upper-left - ImVec2 Max; // Lower-right + ImVec2 Min; // Upper-left + ImVec2 Max; // Lower-right ImRect() : Min(FLT_MAX,FLT_MAX), Max(-FLT_MAX,-FLT_MAX) {} ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {} ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {} ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {} - ImVec2 GetCenter() const { return ImVec2((Min.x+Max.x)*0.5f, (Min.y+Max.y)*0.5f); } - ImVec2 GetSize() const { return ImVec2(Max.x-Min.x, Max.y-Min.y); } - float GetWidth() const { return Max.x-Min.x; } - float GetHeight() const { return Max.y-Min.y; } - ImVec2 GetTL() const { return Min; } - ImVec2 GetTR() const { return ImVec2(Max.x, Min.y); } - ImVec2 GetBL() const { return ImVec2(Min.x, Max.y); } - ImVec2 GetBR() const { return Max; } - bool Contains(const ImVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x < Max.x && p.y < Max.y; } - bool Contains(const ImRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x < Max.x && r.Max.y < Max.y; } - bool Overlaps(const ImRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; } - void Add(const ImVec2& rhs) { if (Min.x > rhs.x) Min.x = rhs.x; if (Min.y > rhs.y) Min.y = rhs.y; if (Max.x < rhs.x) Max.x = rhs.x; if (Max.y < rhs.y) Max.y = rhs.y; } - void Add(const ImRect& rhs) { if (Min.x > rhs.Min.x) Min.x = rhs.Min.x; if (Min.y > rhs.Min.y) Min.y = rhs.Min.y; if (Max.x < rhs.Max.x) Max.x = rhs.Max.x; if (Max.y < rhs.Max.y) Max.y = rhs.Max.y; } - void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } - void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } - void Reduce(const ImVec2& amount) { Min.x += amount.x; Min.y += amount.y; Max.x -= amount.x; Max.y -= amount.y; } - void Clip(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; } - void Round() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } - ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const + ImVec2 GetCenter() const { return ImVec2((Min.x+Max.x)*0.5f, (Min.y+Max.y)*0.5f); } + ImVec2 GetSize() const { return ImVec2(Max.x-Min.x, Max.y-Min.y); } + float GetWidth() const { return Max.x-Min.x; } + float GetHeight() const { return Max.y-Min.y; } + ImVec2 GetTL() const { return Min; } // Top-left + ImVec2 GetTR() const { return ImVec2(Max.x, Min.y); } // Top-right + ImVec2 GetBL() const { return ImVec2(Min.x, Max.y); } // Bottom-left + ImVec2 GetBR() const { return Max; } // Bottom-right + bool Contains(const ImVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x < Max.x && p.y < Max.y; } + bool Contains(const ImRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x < Max.x && r.Max.y < Max.y; } + bool Overlaps(const ImRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; } + void Add(const ImVec2& rhs) { if (Min.x > rhs.x) Min.x = rhs.x; if (Min.y > rhs.y) Min.y = rhs.y; if (Max.x < rhs.x) Max.x = rhs.x; if (Max.y < rhs.y) Max.y = rhs.y; } + void Add(const ImRect& rhs) { if (Min.x > rhs.Min.x) Min.x = rhs.Min.x; if (Min.y > rhs.Min.y) Min.y = rhs.Min.y; if (Max.x < rhs.Max.x) Max.x = rhs.Max.x; if (Max.y < rhs.Max.y) Max.y = rhs.Max.y; } + void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } + void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } + void Reduce(const ImVec2& amount) { Min.x += amount.x; Min.y += amount.y; Max.x -= amount.x; Max.y -= amount.y; } + void Clip(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; } + void Round() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } + ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const { if (!on_edge && Contains(p)) return p; @@ -237,8 +237,8 @@ struct IMGUI_API ImRect // Stacked color modifier, backup of modified data so we can restore it struct ImGuiColMod { - ImGuiCol Col; - ImVec4 PreviousValue; + ImGuiCol Col; + ImVec4 PreviousValue; }; // Stacked style modifier, backup of modified data so we can restore it @@ -251,34 +251,34 @@ struct ImGuiStyleMod // Stacked data for BeginGroup()/EndGroup() struct ImGuiGroupData { - ImVec2 BackupCursorPos; - ImVec2 BackupCursorMaxPos; - float BackupIndentX; - float BackupCurrentLineHeight; - float BackupCurrentLineTextBaseOffset; - float BackupLogLinePosY; - bool AdvanceCursor; + ImVec2 BackupCursorPos; + ImVec2 BackupCursorMaxPos; + float BackupIndentX; + float BackupCurrentLineHeight; + float BackupCurrentLineTextBaseOffset; + float BackupLogLinePosY; + bool AdvanceCursor; }; // Per column data for Columns() struct ImGuiColumnData { - float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) - //float IndentX; + float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) + //float IndentX; }; // Simple column measurement currently used for MenuItem() only. This is very short-sighted for now and NOT a generic helper. struct IMGUI_API ImGuiSimpleColumns { - int Count; - float Spacing; - float Width, NextWidth; - float Pos[8], NextWidths[8]; + int Count; + float Spacing; + float Width, NextWidth; + float Pos[8], NextWidths[8]; ImGuiSimpleColumns(); - void Update(int count, float spacing, bool clear); - float DeclColumns(float w0, float w1, float w2); - float CalcExtraSpace(float avail_w); + void Update(int count, float spacing, bool clear); + float DeclColumns(float w0, float w1, float w2); + float CalcExtraSpace(float avail_w); }; // Internal state of the currently focused/edited text input box @@ -308,11 +308,11 @@ struct IMGUI_API ImGuiTextEditState // Data saved in imgui.ini file struct ImGuiIniData { - char* Name; - ImGuiID ID; - ImVec2 Pos; - ImVec2 Size; - bool Collapsed; + char* Name; + ImGuiID ID; + ImVec2 Pos; + ImVec2 Size; + bool Collapsed; }; // Mouse cursor data (used when io.MouseDrawCursor is set) @@ -328,11 +328,11 @@ struct ImGuiMouseCursorData // Storage for current popup stack struct ImGuiPopupRef { - ImGuiID PopupID; // Set on OpenPopup() - ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() - ImGuiWindow* ParentWindow; // Set on OpenPopup() - ImGuiID ParentMenuSet; // Set on OpenPopup() - ImVec2 MousePosOnOpen; // Copy of mouse position at the time of opening popup + ImGuiID PopupID; // Set on OpenPopup() + ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() + ImGuiWindow* ParentWindow; // Set on OpenPopup() + ImGuiID ParentMenuSet; // Set on OpenPopup() + ImVec2 MousePosOnOpen; // Copy of mouse position at the time of opening popup ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupID = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; } };