diff --git a/docs/TODO.txt b/docs/TODO.txt index 57845d364..9e64b1630 100644 --- a/docs/TODO.txt +++ b/docs/TODO.txt @@ -143,7 +143,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - image/image button: misalignment on padded/bordered button? - image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that? - image button: not taking an explicit id can be problematic. (#2464, #1390) - - slider/drag: ctrl+click when format doesn't include a % character.. disable? display underlying value in default format? (see InputScalarAsWidgetReplacement) + - slider/drag: ctrl+click when format doesn't include a % character.. disable? display underlying value in default format? (see TempInputTextScalar) - slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt() - slider: initial absolute click is imprecise. change to relative movement slider (same as scrollbar). (#1946) - slider: add dragging-based widgets to edit values with mouse (on 2 axises), saving screen real-estate. diff --git a/imgui.cpp b/imgui.cpp index 6eeed76b8..2dbc42070 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3515,8 +3515,8 @@ void ImGui::NewFrame() g.ActiveIdIsAlive = 0; g.ActiveIdPreviousFrameIsAlive = false; g.ActiveIdIsJustActivated = false; - if (g.ScalarAsInputTextId && g.ActiveId != g.ScalarAsInputTextId) - g.ScalarAsInputTextId = 0; + if (g.TempInputTextId != 0 && g.ActiveId != g.TempInputTextId) + g.TempInputTextId = 0; // Drag and drop g.DragDropAcceptIdPrev = g.DragDropAcceptIdCurr; diff --git a/imgui_internal.h b/imgui_internal.h index 7aeaf6797..0cf8f03b3 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -938,7 +938,7 @@ struct ImGuiContext // Widget state ImGuiInputTextState InputTextState; ImFont InputTextPasswordFont; - ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc. + ImGuiID TempInputTextId; // Temporary text input when CTRL+clicking on a slider, etc. ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets ImVec4 ColorPickerRef; bool DragCurrentAccumDirty; @@ -1075,7 +1075,7 @@ struct ImGuiContext CurrentTabBar = NULL; - ScalarAsInputTextId = 0; + TempInputTextId = 0; ColorEditOptions = ImGuiColorEditFlags__OptionsDefault; DragCurrentAccumDirty = false; DragCurrentAccum = 0.0f; @@ -1559,7 +1559,8 @@ namespace ImGui // InputText IMGUI_API bool InputTextEx(const char* label, const char* hint, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); - IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format); + IMGUI_API bool TempInputTextScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format); + inline bool TempInputTextIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputTextId == id); } // Color IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 950c8cf92..46eaf7f34 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -2000,9 +2000,10 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* v, floa format = PatchFormatStringFloatToInt(format); // Tabbing or CTRL-clicking on Drag turns it into an input box - bool start_text_input = false; + bool temp_input_is_active = TempInputTextIsActive(id); + bool temp_input_start = false; const bool focus_requested = FocusableItemRegister(window, id); - if (focus_requested || (hovered && (g.IO.MouseClicked[0] || g.IO.MouseDoubleClicked[0])) || g.NavActivateId == id || (g.NavInputId == id && g.ScalarAsInputTextId != id)) + if (focus_requested || (hovered && (g.IO.MouseClicked[0] || g.IO.MouseDoubleClicked[0])) || g.NavActivateId == id || (g.NavInputId == id && !temp_input_is_active)) { SetActiveID(id, window); SetFocusID(id, window); @@ -2010,15 +2011,15 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* v, floa g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); if (focus_requested || g.IO.KeyCtrl || g.IO.MouseDoubleClicked[0] || g.NavInputId == id) { - start_text_input = true; - g.ScalarAsInputTextId = 0; + temp_input_start = true; + g.TempInputTextId = 0; } } - if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) + if (temp_input_is_active || temp_input_start) { window->DC.CursorPos = frame_bb.Min; FocusableItemUnregister(window); - return InputScalarAsWidgetReplacement(frame_bb, id, label, data_type, v, format); + return TempInputTextScalar(frame_bb, id, label, data_type, v, format); } // Actual drag behavior @@ -2442,10 +2443,11 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* v, co format = PatchFormatStringFloatToInt(format); // Tabbing or CTRL-clicking on Slider turns it into an input box - bool start_text_input = false; + bool temp_input_is_active = TempInputTextIsActive(id); + bool temp_input_start = false; const bool focus_requested = FocusableItemRegister(window, id); const bool hovered = ItemHoverable(frame_bb, id); - if (focus_requested || (hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || (g.NavInputId == id && g.ScalarAsInputTextId != id)) + if (focus_requested || (hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || (g.NavInputId == id && !temp_input_is_active)) { SetActiveID(id, window); SetFocusID(id, window); @@ -2453,15 +2455,15 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* v, co g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); if (focus_requested || g.IO.KeyCtrl || g.NavInputId == id) { - start_text_input = true; - g.ScalarAsInputTextId = 0; + temp_input_start = true; + g.TempInputTextId = 0; } } - if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) + if (temp_input_is_active || temp_input_start) { window->DC.CursorPos = frame_bb.Min; FocusableItemUnregister(window); - return InputScalarAsWidgetReplacement(frame_bb, id, label, data_type, v, format); + return TempInputTextScalar(frame_bb, id, label, data_type, v, format); } // Draw frame @@ -2648,7 +2650,7 @@ bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, // - ImParseFormatFindEnd() [Internal] // - ImParseFormatTrimDecorations() [Internal] // - ImParseFormatPrecision() [Internal] -// - InputScalarAsWidgetReplacement() [Internal] +// - TempInputTextScalar() [Internal] // - InputScalar() // - InputScalarN() // - InputFloat() @@ -2734,16 +2736,16 @@ int ImParseFormatPrecision(const char* fmt, int default_precision) return (precision == INT_MAX) ? default_precision : precision; } -// Create text input in place of an active drag/slider (used when doing a CTRL+Click on drag/slider widgets) +// Create text input in place of another active widget (e.g. used when doing a CTRL+Click on drag/slider widgets) // FIXME: Facilitate using this in variety of other situations. -bool ImGui::InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format) +bool ImGui::TempInputTextScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format) { IM_UNUSED(id); ImGuiContext& g = *GImGui; - // On the first frame, g.ScalarAsInputTextId == 0, then on subsequent frames it becomes == id. + // On the first frame, g.TempInputTextId == 0, then on subsequent frames it becomes == id. // We clear ActiveID on the first frame to allow the InputText() taking it back. - if (g.ScalarAsInputTextId == 0) + if (g.TempInputTextId == 0) ClearActiveID(); char fmt_buf[32]; @@ -2753,11 +2755,11 @@ bool ImGui::InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const c ImStrTrimBlanks(data_buf); ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ((data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImGuiInputTextFlags_CharsScientific : ImGuiInputTextFlags_CharsDecimal); bool value_changed = InputTextEx(label, NULL, data_buf, IM_ARRAYSIZE(data_buf), bb.GetSize(), flags); - if (g.ScalarAsInputTextId == 0) + if (g.TempInputTextId == 0) { // First frame we started displaying the InputText widget, we expect it to take the active id. IM_ASSERT(g.ActiveId == id); - g.ScalarAsInputTextId = g.ActiveId; + g.TempInputTextId = g.ActiveId; } if (value_changed) return DataTypeApplyOpFromText(data_buf, g.InputTextState.InitialTextA.Data, data_type, data_ptr, NULL);