Internals: Added TempInputText() to facilitate creation of custom widgets, renamed TempInputTextScalar() to TempInputScalar() etc. (#2718)

+ Minor imgui.h/todo comments
This commit is contained in:
ocornut 2020-02-25 16:26:30 +01:00
parent e547f898a9
commit 898e91f20d
5 changed files with 55 additions and 39 deletions

View File

@ -163,6 +163,9 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- tabs: make EndTabBar fail if users doesn't respect BeginTabBar return value, for consistency/future-proofing.
- tabs: persistent order/focus in BeginTabBar() api (#261, #351)
- tabs: TabItem could honor SetNextItemWidth()?
- tabs: explicit api (even if internal) to cleanly manipulate tab order.
- tabs: Mouse wheel over tab bar could scroll? (#2702)
- 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?

View File

@ -3678,8 +3678,8 @@ void ImGui::NewFrame()
g.ActiveIdHasBeenEditedThisFrame = false;
g.ActiveIdPreviousFrameIsAlive = false;
g.ActiveIdIsJustActivated = false;
if (g.TempInputTextId != 0 && g.ActiveId != g.TempInputTextId)
g.TempInputTextId = 0;
if (g.TempInputId != 0 && g.ActiveId != g.TempInputId)
g.TempInputId = 0;
if (g.ActiveId == 0)
{
g.ActiveIdUsingNavDirMask = g.ActiveIdUsingNavInputMask = 0;

23
imgui.h
View File

@ -217,7 +217,7 @@ struct ImVec4
//-----------------------------------------------------------------------------
// ImGui: Dear ImGui end-user API
// (Inside a namespace so you can add extra functions in your own separate file. Please don't modify imgui source files!)
// (This is a namespace. You can add extra ImGui:: functions in your own separate file. Please don't modify imgui source files!)
//-----------------------------------------------------------------------------
namespace ImGui
@ -233,16 +233,16 @@ namespace ImGui
// Main
IMGUI_API ImGuiIO& GetIO(); // access the IO structure (mouse/keyboard/gamepad inputs, time, various configuration options/flags)
IMGUI_API ImGuiStyle& GetStyle(); // access the Style structure (colors, sizes). Always use PushStyleCol(), PushStyleVar() to modify style mid-frame.
IMGUI_API ImGuiStyle& GetStyle(); // access the Style structure (colors, sizes). Always use PushStyleCol(), PushStyleVar() to modify style mid-frame!
IMGUI_API void NewFrame(); // start a new Dear ImGui frame, you can submit any command from this point until Render()/EndFrame().
IMGUI_API void EndFrame(); // ends the Dear ImGui frame. automatically called by Render(), you likely don't need to call that yourself directly. If you don't need to render data (skipping rendering) you may call EndFrame() but you'll have wasted CPU already! If you don't need to render, better to not create any imgui windows and not call NewFrame() at all!
IMGUI_API void Render(); // ends the Dear ImGui frame, finalize the draw data. You can get call GetDrawData() to obtain it and run your rendering function. (Obsolete: this used to call io.RenderDrawListsFn(). Nowadays, we allow and prefer calling your render function yourself.)
IMGUI_API void EndFrame(); // ends the Dear ImGui frame. automatically called by Render(). If you don't need to render data (skipping rendering) you may call EndFrame() without Render()... but you'll have wasted CPU already! If you don't need to render, better to not create any windows and not call NewFrame() at all!
IMGUI_API void Render(); // ends the Dear ImGui frame, finalize the draw data. You can get call GetDrawData() to obtain it and run your rendering function (up to v1.60, this used to call io.RenderDrawListsFn(). Nowadays, we allow and prefer calling your render function yourself.)
IMGUI_API ImDrawData* GetDrawData(); // valid after Render() and until the next call to NewFrame(). this is what you have to render.
// Demo, Debug, Information
IMGUI_API void ShowDemoWindow(bool* p_open = NULL); // create Demo window (previously called ShowTestWindow). demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application!
IMGUI_API void ShowAboutWindow(bool* p_open = NULL); // create About window. display Dear ImGui version, credits and build/system information.
IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create Metrics/Debug window. display Dear ImGui internals: draw commands (with individual draw calls and vertices), window list, basic internal state, etc.
IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create Debug/Metrics window. display Dear ImGui internals: draw commands (with individual draw calls and vertices), window list, basic internal state, etc.
IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // add style editor block (not a window). you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style)
IMGUI_API bool ShowStyleSelector(const char* label); // add style selector block (not a window), essentially a combo listing the default styles.
IMGUI_API void ShowFontSelector(const char* label); // add font selector block (not a window), essentially a combo listing the loaded fonts.
@ -345,11 +345,11 @@ namespace ImGui
IMGUI_API ImU32 GetColorU32(ImU32 col); // retrieve given color with style alpha applied
// Parameters stacks (current window)
IMGUI_API void PushItemWidth(float item_width); // set width of items for common large "item+label" widgets. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side). 0.0f = default to ~2/3 of windows width,
IMGUI_API void PushItemWidth(float item_width); // push width of items for common large "item+label" widgets. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side). 0.0f = default to ~2/3 of windows width,
IMGUI_API void PopItemWidth();
IMGUI_API void SetNextItemWidth(float item_width); // set width of the _next_ common large "item+label" widget. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side)
IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position. NOT necessarily the width of last item unlike most 'Item' functions.
IMGUI_API void PushTextWrapPos(float wrap_local_pos_x = 0.0f); // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space
IMGUI_API void PushTextWrapPos(float wrap_local_pos_x = 0.0f); // push word-wrapping position for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space
IMGUI_API void PopTextWrapPos();
IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets
IMGUI_API void PopAllowKeyboardFocus();
@ -360,6 +360,9 @@ namespace ImGui
// - By "cursor" we mean the current output position.
// - The typical widget behavior is to output themselves at the current cursor position, then move the cursor one line down.
// - You can call SameLine() between widgets to undo the last carriage return and output at the right of the preceeding widget.
// - Attention! We currently have inconsistencies between window-local and absolute positions we will aim to fix with future API:
// Window-local coordinates: SameLine(), GetCursorPos(), SetCursorPos(), GetCursorStartPos(), GetContentRegionMax(), GetWindowContentRegion*(), PushTextWrapPos()
// Absolute coordinate: GetCursorScreenPos(), SetCursorScreenPos(), all ImDrawList:: functions.
IMGUI_API void Separator(); // separator, generally horizontal. inside a menu bar or in horizontal layout mode, this becomes a vertical separator.
IMGUI_API void SameLine(float offset_from_start_x=0.0f, float spacing=-1.0f); // call between widgets or groups to layout them horizontally. X position given in window coordinates.
IMGUI_API void NewLine(); // undo a SameLine() or force a new line when in an horizontal-layout context.
@ -597,7 +600,7 @@ namespace ImGui
// - You can also use SameLine(pos_x) to mimic simplified columns.
// - The columns API is work-in-progress and rather lacking (columns are arguably the worst part of dear imgui at the moment!)
// - There is a maximum of 64 columns.
// - Currently working on new 'Tables' api which will replace columns (see GitHub #2957)
// - Currently working on new 'Tables' api which will replace columns around Q2 2020 (see GitHub #2957).
IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true);
IMGUI_API void NextColumn(); // next column, defaults to current row or next row if the current row is finished
IMGUI_API int GetColumnIndex(); // get current column index
@ -674,11 +677,13 @@ namespace ImGui
IMGUI_API const char* GetStyleColorName(ImGuiCol idx); // get a string corresponding to the enum value (for display, saving, etc.).
IMGUI_API void SetStateStorage(ImGuiStorage* storage); // replace current window storage with our own (if you want to manipulate it yourself, typically clear subsection of it)
IMGUI_API ImGuiStorage* GetStateStorage();
IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // calculate coarse clipping for large list of evenly sized items. Prefer using the ImGuiListClipper higher-level helper if you can.
IMGUI_API bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags = 0); // helper to create a child window / scrolling region that looks like a normal widget frame
IMGUI_API void EndChildFrame(); // always call EndChildFrame() regardless of BeginChildFrame() return values (which indicates a collapsed/clipped window)
// Text Utilities
IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
// Color Utilities
IMGUI_API ImVec4 ColorConvertU32ToFloat4(ImU32 in);
IMGUI_API ImU32 ColorConvertFloat4ToU32(const ImVec4& in);

View File

@ -1147,7 +1147,7 @@ struct ImGuiContext
ImVec2 LastValidMousePos;
ImGuiInputTextState InputTextState;
ImFont InputTextPasswordFont;
ImGuiID TempInputTextId; // Temporary text input when CTRL+clicking on a slider, etc.
ImGuiID TempInputId; // Temporary text input when CTRL+clicking on a slider, etc.
ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets
float ColorEditLastHue; // Backup of last Hue associated to LastColor[3], so we can restore Hue in lossy RGB<>HSV round trips
float ColorEditLastSat; // Backup of last Saturation associated to LastColor[3], so we can restore Saturation in lossy RGB<>HSV round trips
@ -1291,7 +1291,7 @@ struct ImGuiContext
CurrentTabBar = NULL;
LastValidMousePos = ImVec2(0.0f, 0.0f);
TempInputTextId = 0;
TempInputId = 0;
ColorEditOptions = ImGuiColorEditFlags__OptionsDefault;
ColorEditLastHue = ColorEditLastSat = 0.0f;
ColorEditLastColor[0] = ColorEditLastColor[1] = ColorEditLastColor[2] = FLT_MAX;
@ -1841,8 +1841,9 @@ 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 TempInputTextScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format);
inline bool TempInputTextIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputTextId == id); }
IMGUI_API bool TempInputText(const ImRect& bb, ImGuiID id, const char* label, char* buf, int buf_size, ImGuiInputTextFlags flags);
IMGUI_API bool TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format);
inline bool TempInputIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputId == id); }
// Color
IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags);

View File

@ -2109,7 +2109,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
// Tabbing or CTRL-clicking on Drag turns it into an input box
const bool hovered = ItemHoverable(frame_bb, id);
bool temp_input_is_active = TempInputTextIsActive(id);
bool temp_input_is_active = TempInputIsActive(id);
bool temp_input_start = false;
if (!temp_input_is_active)
{
@ -2130,7 +2130,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
}
}
if (temp_input_is_active || temp_input_start)
return TempInputTextScalar(frame_bb, id, label, data_type, p_data, format);
return TempInputScalar(frame_bb, id, label, data_type, p_data, format);
// Draw frame
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
@ -2561,7 +2561,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
// Tabbing or CTRL-clicking on Slider turns it into an input box
const bool hovered = ItemHoverable(frame_bb, id);
bool temp_input_is_active = TempInputTextIsActive(id);
bool temp_input_is_active = TempInputIsActive(id);
bool temp_input_start = false;
if (!temp_input_is_active)
{
@ -2581,7 +2581,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
}
}
if (temp_input_is_active || temp_input_start)
return TempInputTextScalar(frame_bb, id, label, data_type, p_data, format);
return TempInputScalar(frame_bb, id, label, data_type, p_data, format);
// Draw frame
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
@ -2860,32 +2860,39 @@ int ImParseFormatPrecision(const char* fmt, int default_precision)
// 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::TempInputTextScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format)
bool ImGui::TempInputText(const ImRect& bb, ImGuiID id, const char* label, char* buf, int buf_size, ImGuiInputTextFlags flags)
{
ImGuiContext& g = *GImGui;
// 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.
const bool init = (g.TempInputTextId != id);
ImGuiContext& g = *GImGui;
const bool init = (g.TempInputId != id);
if (init)
ClearActiveID();
g.CurrentWindow->DC.CursorPos = bb.Min;
bool value_changed = InputTextEx(label, NULL, buf, buf_size, bb.GetSize(), flags);
if (init)
{
// First frame we started displaying the InputText widget, we expect it to take the active id.
IM_ASSERT(g.ActiveId == id);
g.TempInputId = g.ActiveId;
}
return value_changed;
}
bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format)
{
ImGuiContext& g = *GImGui;
char fmt_buf[32];
char data_buf[32];
format = ImParseFormatTrimDecorations(format, fmt_buf, IM_ARRAYSIZE(fmt_buf));
DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, p_data, format);
ImStrTrimBlanks(data_buf);
g.CurrentWindow->DC.CursorPos = bb.Min;
ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_NoMarkEdited;
flags |= ((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 (init)
{
// First frame we started displaying the InputText widget, we expect it to take the active id.
IM_ASSERT(g.ActiveId == id);
g.TempInputTextId = g.ActiveId;
}
bool value_changed = TempInputText(bb, id, label, data_buf, IM_ARRAYSIZE(data_buf), flags);
if (value_changed)
{
value_changed = DataTypeApplyOpFromText(data_buf, g.InputTextState.InitialTextA.Data, data_type, p_data, NULL);