Compare commits

..

3 Commits

10 changed files with 95 additions and 118 deletions

View File

@ -32,9 +32,11 @@ HOW TO UPDATE?
-----------------------------------------------------------------------
VERSION 1.82 WIP (In Progresss)
VERSION 1.82 (Released 2021-02-15)
-----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.82
Breaking Changes:
- Removed redirecting functions/enums names that were marked obsolete in 1.66 (September 2018):
@ -75,9 +77,9 @@ Breaking Changes:
Other Changes:
- Window, Nav: Fixed crash when calling SetWindowFocus(NULL) at the time a new window appears. (#3865) [@nem0]
- Window: Shrink close button hit-testing region when it covers an abnormally high portion of the window visible
area (e.g. when window is collapsed + moved in a corner) to facilitate moving the window away. (#3825)
- Window, Nav: Fixed crash when calling SetWindowFocus(NULL) as the time a new window appears. (#3865) [@nem0]
- Nav: Various fixes for losing gamepad/keyboard navigation reference point when a window reappears or
when it appears while gamepad/keyboard are not being used. (#787)
- Drags: Fixed crash when using DragScalar() directly (not via common wrapper like DragFloat() etc.)
@ -86,26 +88,27 @@ Other Changes:
format specifier (e.g. using "%f123" as a format string). [@rokups]
- Drags, Sliders: Fixed a bug where using custom formatting flags (',$,_) supported by stb_sprintf.h
would cause incorrect value to be displayed. (#3604) [@rokups]
- Drags, Sliders: Support ImGuiSliderFlags_Logarithmic flag with integers. Because why not? (#3786)
- Tables: Fixed unaligned accesses when using TableSetBgColor(ImGuiTableBgTarget_CellBg). (#3872)
- IsItemHovered(): fixed return value false positive when used after EndChild(), EndGroup() or widgets using
either of them, when the hovered location is located within a child window, e.g. InputTextMultiline().
This is intended to have no side effects, but brace yourself for the possible comeback.. (#3851, #1370)
- Drag and Drop: can use BeginDragDropSource() for other than the left mouse button as long as the item
has an ID (for ID-less items will add new functionalities later). (#1637, #3885)
- Added GetAllocatorFunctions() to facilitate sharing allocators accross DLL boundaries. (#3836)
- ImFontAtlas: Added 'bool TexPixelsUseColors' output to help backend decide of underlying texture format. (#3369)
This can currently only ever be set by the Freetype renderer.
- imgui_freetype: Added ImGuiFreeTypeBuilderFlags_Bitmap flag to request Freetype loading bitmap data.
This may have an effect on size and must be called with correct size values. (#3879) [@metarutaiga]
- ImDrawList: PathArcTo() now supports "int num_segments = 0" (new default) and adaptively tesselate.
The adapative tesselation uses look up tables, tends to be faster than old PathArcTo() while maintaining
quality for large arcs (tesselation quality derived from "style.CircleTessellationMaxError") (#3491) [@thedmd]
- ImDrawList: PathArcToFast() also adaptively tesselate efficiently. This means that large rounded corners
- ImDrawList: PathArcTo() now supports "int num_segments = 0" (new default) and adaptively tessellate.
The adaptive tessellation uses look up tables, tends to be faster than old PathArcTo() while maintaining
quality for large arcs (tessellation quality derived from "style.CircleTessellationMaxError") (#3491) [@thedmd]
- ImDrawList: PathArcToFast() also adaptively tessellate efficiently. This means that large rounded corners
in e.g. hi-dpi settings will generally look better. (#3491) [@thedmd]
- ImDrawList: AddCircle, AddCircleFilled(): Tweaked default segment count calculation to honor MaxError
with more accuracy. Made default segment count always even for better looking result. (#3808) [@thedmd]
- Misc: Added GetAllocatorFunctions() to facilitate sharing allocators across DLL boundaries. (#3836)
- Misc: Added 'debuggers/imgui.gdb' and 'debuggers/imgui.natstepfilter' (along with existing 'imgui.natvis')
scriptss to configure popular debuggers into skipping trivial functions when using StepInto. [@rokups]
scripts to configure popular debuggers into skipping trivial functions when using StepInto. [@rokups]
- Backends: Android: Added native Android backend. (#3446) [@duddel]
- Backends: Win32: Added ImGui_ImplWin32_EnableAlphaCompositing() to facilitate experimenting with
alpha compositing and transparent windows. (#2766, #3447 etc.).
@ -115,7 +118,7 @@ Other Changes:
(#2693, #2764, #2766, #2873, #3447, #3813, #3816) [@ocornut, @thedmd, @ShawnM427, @Ubpa, @aiekick]
- Backends: DX9: Fix to support IMGUI_USE_BGRA_PACKED_COLOR. (#3844) [@Xiliusha]
- Backends: DX9: Fix to support colored glyphs, using newly introduced 'TexPixelsUseColors' info. (#3844)
- Examples: Android: Added Android + GL ES2 example. (#3446) [@duddel]
- Examples: Android: Added Android + GL ES3 example. (#3446) [@duddel]
- Examples: Reworked setup of clear color to be compatible with transparent values.
- CI: Use a dedicated "scheduled" workflow to trigger scheduled builds. Forks may disable this workflow if
scheduled builds builds are not required. [@rokups]
@ -126,6 +129,8 @@ Other Changes:
VERSION 1.81 (Released 2021-02-10)
-----------------------------------------------------------------------
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.81
Breaking Changes:
- ListBox helpers:

View File

@ -81,9 +81,6 @@ You may use the [docking](https://github.com/ocornut/imgui/tree/docking) branch
Many projects are using this branch and it is kept in sync with master regularly.
You may merge in the [tables](https://github.com/ocornut/imgui/tree/tables) branch which includes:
- [Table features](https://github.com/ocornut/imgui/issues/2957)
##### [Return to Index](#index)
----

View File

@ -1,4 +1,4 @@
// dear imgui, v1.82 WIP
// dear imgui, v1.82
// (main code and documentation)
// Help:
@ -3251,18 +3251,18 @@ bool ImGui::FocusableItemRegister(ImGuiWindow* window, ImGuiID id)
// Process TAB/Shift-TAB to tab *OUT* of the currently focused item.
// (Note that we can always TAB out of a widget that doesn't allow tabbing in)
if (g.ActiveId == id && g.FocusTabPressed && !IsActiveIdUsingKey(ImGuiKey_Tab) && g.FocusRequestNextWindow == NULL)
if (g.ActiveId == id && g.TabFocusPressed && !IsActiveIdUsingKey(ImGuiKey_Tab) && g.TabFocusRequestNextWindow == NULL)
{
g.FocusRequestNextWindow = window;
g.FocusRequestNextCounterTabStop = window->DC.FocusCounterTabStop + (g.IO.KeyShift ? (is_tab_stop ? -1 : 0) : +1); // Modulo on index will be applied at the end of frame once we've got the total counter of items.
g.TabFocusRequestNextWindow = window;
g.TabFocusRequestNextCounterTabStop = window->DC.FocusCounterTabStop + (g.IO.KeyShift ? (is_tab_stop ? -1 : 0) : +1); // Modulo on index will be applied at the end of frame once we've got the total counter of items.
}
// Handle focus requests
if (g.FocusRequestCurrWindow == window)
if (g.TabFocusRequestCurrWindow == window)
{
if (window->DC.FocusCounterRegular == g.FocusRequestCurrCounterRegular)
if (window->DC.FocusCounterRegular == g.TabFocusRequestCurrCounterRegular)
return true;
if (is_tab_stop && window->DC.FocusCounterTabStop == g.FocusRequestCurrCounterTabStop)
if (is_tab_stop && window->DC.FocusCounterTabStop == g.TabFocusRequestCurrCounterTabStop)
{
g.NavJustTabbedId = id;
return true;
@ -3768,32 +3768,32 @@ void ImGui::UpdateTabFocus()
ImGuiContext& g = *GImGui;
// Pressing TAB activate widget focus
g.FocusTabPressed = (g.NavWindow && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab));
if (g.ActiveId == 0 && g.FocusTabPressed)
g.TabFocusPressed = (g.NavWindow && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab));
if (g.ActiveId == 0 && g.TabFocusPressed)
{
// Note that SetKeyboardFocusHere() sets the Next fields mid-frame. To be consistent we also
// manipulate the Next fields even, even though they will be turned into Curr fields by the code below.
g.FocusRequestNextWindow = g.NavWindow;
g.FocusRequestNextCounterRegular = INT_MAX;
g.TabFocusRequestNextWindow = g.NavWindow;
g.TabFocusRequestNextCounterRegular = INT_MAX;
if (g.NavId != 0 && g.NavIdTabCounter != INT_MAX)
g.FocusRequestNextCounterTabStop = g.NavIdTabCounter + 1 + (g.IO.KeyShift ? -1 : 1);
g.TabFocusRequestNextCounterTabStop = g.NavIdTabCounter + 1 + (g.IO.KeyShift ? -1 : 1);
else
g.FocusRequestNextCounterTabStop = g.IO.KeyShift ? -1 : 0;
g.TabFocusRequestNextCounterTabStop = g.IO.KeyShift ? -1 : 0;
}
// Turn queued focus request into current one
g.FocusRequestCurrWindow = NULL;
g.FocusRequestCurrCounterRegular = g.FocusRequestCurrCounterTabStop = INT_MAX;
if (g.FocusRequestNextWindow != NULL)
g.TabFocusRequestCurrWindow = NULL;
g.TabFocusRequestCurrCounterRegular = g.TabFocusRequestCurrCounterTabStop = INT_MAX;
if (g.TabFocusRequestNextWindow != NULL)
{
ImGuiWindow* window = g.FocusRequestNextWindow;
g.FocusRequestCurrWindow = window;
if (g.FocusRequestNextCounterRegular != INT_MAX && window->DC.FocusCounterRegular != -1)
g.FocusRequestCurrCounterRegular = ImModPositive(g.FocusRequestNextCounterRegular, window->DC.FocusCounterRegular + 1);
if (g.FocusRequestNextCounterTabStop != INT_MAX && window->DC.FocusCounterTabStop != -1)
g.FocusRequestCurrCounterTabStop = ImModPositive(g.FocusRequestNextCounterTabStop, window->DC.FocusCounterTabStop + 1);
g.FocusRequestNextWindow = NULL;
g.FocusRequestNextCounterRegular = g.FocusRequestNextCounterTabStop = INT_MAX;
ImGuiWindow* window = g.TabFocusRequestNextWindow;
g.TabFocusRequestCurrWindow = window;
if (g.TabFocusRequestNextCounterRegular != INT_MAX && window->DC.FocusCounterRegular != -1)
g.TabFocusRequestCurrCounterRegular = ImModPositive(g.TabFocusRequestNextCounterRegular, window->DC.FocusCounterRegular + 1);
if (g.TabFocusRequestNextCounterTabStop != INT_MAX && window->DC.FocusCounterTabStop != -1)
g.TabFocusRequestCurrCounterTabStop = ImModPositive(g.TabFocusRequestNextCounterTabStop, window->DC.FocusCounterTabStop + 1);
g.TabFocusRequestNextWindow = NULL;
g.TabFocusRequestNextCounterRegular = g.TabFocusRequestNextCounterTabStop = INT_MAX;
}
g.NavIdTabCounter = INT_MAX;
@ -5886,7 +5886,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
{
window->Collapsed = !window->Collapsed;
MarkIniSettingsDirty(window);
FocusWindow(window);
}
}
else
@ -6222,7 +6221,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
if (want_focus)
{
FocusWindow(window);
NavInitWindow(window, false);
NavInitWindow(window, false); // <-- this is in the way for us to be able to defer and sort reappearing FocusWindow() calls
}
// Title bar
@ -6924,9 +6923,9 @@ void ImGui::SetKeyboardFocusHere(int offset)
IM_ASSERT(offset >= -1); // -1 is allowed but not below
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
g.FocusRequestNextWindow = window;
g.FocusRequestNextCounterRegular = window->DC.FocusCounterRegular + 1 + offset;
g.FocusRequestNextCounterTabStop = INT_MAX;
g.TabFocusRequestNextWindow = window;
g.TabFocusRequestNextCounterRegular = window->DC.FocusCounterRegular + 1 + offset;
g.TabFocusRequestNextCounterTabStop = INT_MAX;
}
void ImGui::SetItemDefaultFocus()

View File

@ -1,4 +1,4 @@
// dear imgui, v1.82 WIP
// dear imgui, v1.82
// (headers)
// Help:
@ -60,8 +60,8 @@ Index of this file:
// 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)
#define IMGUI_VERSION "1.82 WIP"
#define IMGUI_VERSION_NUM 18104
#define IMGUI_VERSION "1.82"
#define IMGUI_VERSION_NUM 18200
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE

View File

@ -1,4 +1,4 @@
// dear imgui, v1.82 WIP
// dear imgui, v1.82
// (demo code)
// Help:
@ -1272,7 +1272,6 @@ static void ShowDemoWindowWidgets()
static ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput;
HelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp because we don't want to include <string> in here)");
ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly);
ImGui::CheckboxFlags("ImGuiInputTextFlags_AlwaysOverwrite", &flags, ImGuiInputTextFlags_AlwaysOverwrite);
ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", &flags, ImGuiInputTextFlags_AllowTabInput);
ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", &flags, ImGuiInputTextFlags_CtrlEnterForNewLine);
ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16), flags);

View File

@ -1,4 +1,4 @@
// dear imgui, v1.82 WIP
// dear imgui, v1.82
// (drawing and font code)
/*

View File

@ -1,4 +1,4 @@
// dear imgui, v1.82 WIP
// dear imgui, v1.82
// (internal structures/api)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@ -976,7 +976,6 @@ struct IMGUI_API ImGuiInputTextState
bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!)
bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection
bool Edited; // edited this frame
bool OverwriteMode; // toggle with INSERT key
ImGuiInputTextFlags UserFlags; // Temporarily set while we call user's callback
ImGuiInputTextCallback UserCallback; // "
void* UserCallbackData; // "
@ -1423,13 +1422,13 @@ struct ImGuiContext
bool NavWindowingToggleLayer;
// Legacy Focus/Tabbing system (older than Nav, active even if Nav is disabled, misnamed. FIXME-NAV: This needs a redesign!)
ImGuiWindow* FocusRequestCurrWindow; //
ImGuiWindow* FocusRequestNextWindow; //
int FocusRequestCurrCounterRegular; // Any item being requested for focus, stored as an index (we on layout to be stable between the frame pressing TAB and the next frame, semi-ouch)
int FocusRequestCurrCounterTabStop; // Tab item being requested for focus, stored as an index
int FocusRequestNextCounterRegular; // Stored for next frame
int FocusRequestNextCounterTabStop; // "
bool FocusTabPressed; //
ImGuiWindow* TabFocusRequestCurrWindow; //
ImGuiWindow* TabFocusRequestNextWindow; //
int TabFocusRequestCurrCounterRegular; // Any item being requested for focus, stored as an index (we on layout to be stable between the frame pressing TAB and the next frame, semi-ouch)
int TabFocusRequestCurrCounterTabStop; // Tab item being requested for focus, stored as an index
int TabFocusRequestNextCounterRegular; // Stored for next frame
int TabFocusRequestNextCounterTabStop; // "
bool TabFocusPressed; //
// Render
float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list)
@ -1612,10 +1611,10 @@ struct ImGuiContext
NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f;
NavWindowingToggleLayer = false;
FocusRequestCurrWindow = FocusRequestNextWindow = NULL;
FocusRequestCurrCounterRegular = FocusRequestCurrCounterTabStop = INT_MAX;
FocusRequestNextCounterRegular = FocusRequestNextCounterTabStop = INT_MAX;
FocusTabPressed = false;
TabFocusRequestCurrWindow = TabFocusRequestNextWindow = NULL;
TabFocusRequestCurrCounterRegular = TabFocusRequestCurrCounterTabStop = INT_MAX;
TabFocusRequestNextCounterRegular = TabFocusRequestNextCounterTabStop = INT_MAX;
TabFocusPressed = false;
DimBgRatio = 0.0f;
MouseCursor = ImGuiMouseCursor_Arrow;

View File

@ -1,4 +1,4 @@
// dear imgui, v1.82 WIP
// dear imgui, v1.82
// (tables and columns code)
/*

View File

@ -1,4 +1,4 @@
// dear imgui, v1.82 WIP
// dear imgui, v1.82
// (widgets code)
/*
@ -2143,9 +2143,9 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
{
ImGuiContext& g = *GImGui;
const ImGuiAxis axis = (flags & ImGuiSliderFlags_Vertical) ? ImGuiAxis_Y : ImGuiAxis_X;
const bool is_decimal = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double);
const bool is_clamped = (v_min < v_max);
const bool is_logarithmic = (flags & ImGuiSliderFlags_Logarithmic) && is_decimal;
const bool is_logarithmic = (flags & ImGuiSliderFlags_Logarithmic) != 0;
const bool is_floating_point = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double);
// Default tweak speed
if (v_speed == 0.0f && is_clamped && (v_max - v_min < FLT_MAX))
@ -2163,7 +2163,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
}
else if (g.ActiveIdSource == ImGuiInputSource_Nav)
{
int decimal_precision = is_decimal ? ImParseFormatPrecision(format, 3) : 0;
const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0;
adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f / 10.0f, 10.0f)[axis];
v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision));
}
@ -2203,7 +2203,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
if (is_logarithmic)
{
// When using logarithmic sliders, we need to clamp to avoid hitting zero, but our choice of clamp value greatly affects slider precision. We attempt to use the specified precision to estimate a good lower bound.
const int decimal_precision = is_decimal ? ImParseFormatPrecision(format, 3) : 1;
const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 1;
logarithmic_zero_epsilon = ImPow(0.1f, (float)decimal_precision);
// Convert to parametric space, apply delta, convert back
@ -2241,9 +2241,9 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
// Clamp values (+ handle overflow/wrap-around for integer types)
if (*v != v_cur && is_clamped)
{
if (v_cur < v_min || (v_cur > *v && adjust_delta < 0.0f && !is_decimal))
if (v_cur < v_min || (v_cur > *v && adjust_delta < 0.0f && !is_floating_point))
v_cur = v_min;
if (v_cur > v_max || (v_cur < *v && adjust_delta > 0.0f && !is_decimal))
if (v_cur > v_max || (v_cur < *v && adjust_delta > 0.0f && !is_floating_point))
v_cur = v_max;
}
@ -2634,7 +2634,7 @@ TYPE ImGui::ScaleValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_min, T
{
if (v_min == v_max)
return v_min;
const bool is_decimal = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double);
const bool is_floating_point = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double);
TYPE result;
if (is_logarithmic)
@ -2682,7 +2682,7 @@ TYPE ImGui::ScaleValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_min, T
else
{
// Linear slider
if (is_decimal)
if (is_floating_point)
{
result = ImLerp(v_min, v_max, t);
}
@ -2715,14 +2715,14 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
const ImGuiStyle& style = g.Style;
const ImGuiAxis axis = (flags & ImGuiSliderFlags_Vertical) ? ImGuiAxis_Y : ImGuiAxis_X;
const bool is_decimal = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double);
const bool is_logarithmic = (flags & ImGuiSliderFlags_Logarithmic) && is_decimal;
const bool is_logarithmic = (flags & ImGuiSliderFlags_Logarithmic) != 0;
const bool is_floating_point = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double);
const float grab_padding = 2.0f;
const float slider_sz = (bb.Max[axis] - bb.Min[axis]) - grab_padding * 2.0f;
float grab_sz = style.GrabMinSize;
SIGNEDTYPE v_range = (v_min < v_max ? v_max - v_min : v_min - v_max);
if (!is_decimal && v_range >= 0) // v_range < 0 may happen on integer overflows
if (!is_floating_point && v_range >= 0) // v_range < 0 may happen on integer overflows
grab_sz = ImMax((float)(slider_sz / (v_range + 1)), style.GrabMinSize); // For integer sliders: if possible have the grab size represent 1 unit
grab_sz = ImMin(grab_sz, slider_sz);
const float slider_usable_sz = slider_sz - grab_sz;
@ -2734,7 +2734,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
if (is_logarithmic)
{
// When using logarithmic sliders, we need to clamp to avoid hitting zero, but our choice of clamp value greatly affects slider precision. We attempt to use the specified precision to estimate a good lower bound.
const int decimal_precision = is_decimal ? ImParseFormatPrecision(format, 3) : 1;
const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 1;
logarithmic_zero_epsilon = ImPow(0.1f, (float)decimal_precision);
zero_deadzone_halfsize = (style.LogSliderDeadzone * 0.5f) / ImMax(slider_usable_sz, 1.0f);
}
@ -2772,7 +2772,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
float input_delta = (axis == ImGuiAxis_X) ? input_delta2.x : -input_delta2.y;
if (input_delta != 0.0f)
{
const int decimal_precision = is_decimal ? ImParseFormatPrecision(format, 3) : 0;
const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0;
if (decimal_precision > 0)
{
input_delta /= 100.0f; // Gamepad/keyboard tweak speeds in % of slider bounds
@ -3672,7 +3672,6 @@ static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const Im
#define STB_TEXTEDIT_K_WORDRIGHT 0x20000D // keyboard input to move cursor right one word
#define STB_TEXTEDIT_K_PGUP 0x20000E // keyboard input to move cursor up a page
#define STB_TEXTEDIT_K_PGDOWN 0x20000F // keyboard input to move cursor down a page
#define STB_TEXTEDIT_K_INSERT 0x200010 // keyboard input to toggle insert mode
#define STB_TEXTEDIT_K_SHIFT 0x400000
#define STB_TEXTEDIT_IMPLEMENTATION
@ -3928,7 +3927,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
ImGuiInputTextState* state = GetInputTextState(id);
const bool focus_requested = FocusableItemRegister(window, id);
const bool focus_requested_by_code = focus_requested && (g.FocusRequestCurrWindow == window && g.FocusRequestCurrCounterRegular == window->DC.FocusCounterRegular);
const bool focus_requested_by_code = focus_requested && (g.TabFocusRequestCurrWindow == window && g.TabFocusRequestCurrCounterRegular == window->DC.FocusCounterRegular);
const bool focus_requested_by_tab = focus_requested && !focus_requested_by_code;
const bool user_clicked = hovered && io.MouseClicked[0];
@ -3981,6 +3980,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (!is_multiline && focus_requested_by_code)
select_all = true;
}
if (flags & ImGuiInputTextFlags_AlwaysOverwrite)
state->Stb.insert_mode = 1; // stb field name is indeed incorrect (see #2863)
if (!is_multiline && (focus_requested_by_tab || (user_clicked && io.KeyCtrl)))
select_all = true;
}
@ -4063,9 +4064,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
state->UserCallback = callback;
state->UserCallbackData = callback_user_data;
// Update overwrite / insert mode
state->Stb.insert_mode = (flags & ImGuiInputTextFlags_AlwaysOverwrite) ? 1 : state->OverwriteMode; // stb field name is confusing (see #2863)
// 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 library-wide concept of Selected vs Active.
g.ActiveIdAllowOverlap = !io.MouseDown[0];
@ -4166,7 +4164,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_PageUp) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGUP | k_mask); scroll_y -= row_count_per_page * g.FontSize; }
else if (IsKeyPressedMap(ImGuiKey_PageDown) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGDOWN | k_mask); scroll_y += row_count_per_page * g.FontSize; }
else if (IsKeyPressedMap(ImGuiKey_Insert) && !is_readonly) { if ((flags & ImGuiInputTextFlags_AlwaysOverwrite) == 0) { state->OnKeyPressed(STB_TEXTEDIT_K_INSERT | k_mask); state->OverwriteMode = state->Stb.insert_mode != 0; } }
else if (IsKeyPressedMap(ImGuiKey_Home)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_End)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Delete) && !is_readonly) { state->OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
@ -4588,45 +4585,28 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
}
}
const ImVec2 cursor_screen_pos = draw_pos + cursor_offset - draw_scroll;
bool cursor_is_visible = false;
bool cursor_is_overwrite_mode = false;
if (render_cursor)
{
state->CursorAnim += io.DeltaTime;
cursor_is_visible = (!g.IO.ConfigInputTextCursorBlink) || (state->CursorAnim <= 0.0f) || ImFmod(state->CursorAnim, 1.20f) <= 0.80f;
const bool cursor_at_eol = state->TextW[state->Stb.cursor] == 0 || state->TextW[state->Stb.cursor] == '\n';
cursor_is_overwrite_mode = state->Stb.insert_mode && !state->HasSelection() && !cursor_at_eol;
}
// Draw blinking cursor (overwrite cursor)
if (cursor_is_visible && cursor_is_overwrite_mode)
{
ImVec2 rect_size = InputTextCalcTextSizeW(&state->TextW[state->Stb.cursor], &state->TextW[state->Stb.cursor] + 1, NULL, NULL, false);
ImRect cursor_rect(cursor_screen_pos.x, cursor_screen_pos.y - rect_size.y, cursor_screen_pos.x + rect_size.x, cursor_screen_pos.y);
if (cursor_rect.Overlaps(clip_rect))
draw_window->DrawList->AddRectFilled(cursor_rect.Min, cursor_rect.Max, GetColorU32(ImGuiCol_Text, 0.20f));
}
// Draw text we test for 'buf_display_max_length' as a way to avoid some pathological cases (e.g. single-line 1 MB string) which would make ImDrawList crash.
// We test for 'buf_display_max_length' as a way to avoid some pathological cases (e.g. single-line 1 MB string) which would make ImDrawList crash.
if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
{
ImU32 col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text);
draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, col, buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect);
}
// Draw blinking cursor (append cursor)
if (cursor_is_visible && !cursor_is_overwrite_mode)
// Draw blinking cursor
if (render_cursor)
{
ImRect cursor_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x, cursor_screen_pos.y - 0.5f);
if (cursor_rect.Overlaps(clip_rect))
draw_window->DrawList->AddLine(cursor_rect.Min, cursor_rect.Max, GetColorU32(ImGuiCol_Text));
}
state->CursorAnim += io.DeltaTime;
bool cursor_is_visible = (!g.IO.ConfigInputTextCursorBlink) || (state->CursorAnim <= 0.0f) || ImFmod(state->CursorAnim, 1.20f) <= 0.80f;
ImVec2 cursor_screen_pos = draw_pos + cursor_offset - draw_scroll;
ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.5f);
if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect))
draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.GetBL(), GetColorU32(ImGuiCol_Text));
// Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.)
if (cursor_is_visible && !is_readonly)
if (!is_readonly)
g.PlatformImePos = ImVec2(cursor_screen_pos.x - 1.0f, cursor_screen_pos.y - g.FontSize);
}
}
else
{
// Render text only (no selection, no cursor)

View File

@ -740,9 +740,7 @@ retry:
if (c == '\n' && state->single_line)
break;
if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)
&& (STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE) // [DEAR IMGUI]
) {
if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {