mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-10-26 12:27:30 +00:00 
			
		
		
		
	InputText: Added support for buffer size/capacity changes via the ImGuiInputTextFlags_CallbackResize flag. (#2006, #1443, #1008).
This commit is contained in:
		| @@ -52,6 +52,8 @@ Other Changes: | ||||
|  - Window: Allow menu and popups windows from ignoring the style.WindowMinSize values so short menus/popups are not padded. (#1909) | ||||
|  - Window: Added global io.OptResizeWindowsFromEdges option to enable resizing windows from their edges and from the lower-left corner. (#1495) | ||||
|  - Window: Collapse button shows hovering highlight + clicking and dragging on it allows to drag the window as well.  | ||||
|  - InputText: Added support for buffer size/capacity changes via the ImGuiInputTextFlags_CallbackResize flag. (#2006, #1443, #1008). | ||||
|  - InputText: Fixed minor off-by-one issue when submitting a buffer size smaller than the initial zero-terminated buffer contents. | ||||
|  - Drag and Drop: Fixed an incorrect assert when dropping a source that is submitted after the target (bug introduced with 1.62 changes  | ||||
|    related to the addition of IsItemDeactivated()). (#1875, #143) | ||||
|  - Drag and Drop: Fixed ImGuiDragDropFlags_SourceNoDisableHover to affect hovering state prior to calling IsItemHovered() + fixed description. (#143) | ||||
| @@ -60,7 +62,6 @@ Other Changes: | ||||
|  - Drag and Drop: Payload stays available and under the mouse if the source stops being submitted, however the tooltip is replaced by "...". (#1725) | ||||
|  - Drag and Drop: Added ImGuiDragDropFlags_SourceAutoExpirePayload flag to force payload to expire if the source stops being submitted. (#1725, #143). | ||||
|  - IsItemHovered(): Added ImGuiHoveredFlags_AllowWhenDisabled flag to query hovered status on disabled items. (#1940, #211) | ||||
|  - InputText: Fixed minor off-by-one issue when submitting a buffer size smaller than the initial zero-terminated buffer contents. | ||||
|  - Selectable: Added ImGuiSelectableFlags_Disabled flag in the public API. (#211) | ||||
|  - Misc: Added IMGUI_VERSION_NUM for easy compile-time testing. (#2025) | ||||
|  - Misc: Added ImGuiMouseCursor_Hand cursor enum + corresponding software cursor. (#1913, 1914) [@aiekick, @ocornut]  | ||||
|   | ||||
							
								
								
									
										1
									
								
								TODO.txt
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								TODO.txt
									
									
									
									
									
								
							| @@ -66,7 +66,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i | ||||
|  - input text: expose CursorPos in char filter event (#816) | ||||
|  - input text: access public fields via a non-callback API e.g. InputTextGetState("xxx") that may return NULL if not active. | ||||
|  - input text: flag to disable live update of the user buffer (also applies to float/int text input) (#701) | ||||
|  - input text: way to dynamically grow the buffer without forcing the user to initially allocate for worse case, e.g. more natural std::string (follow up on #200) | ||||
|  - input text: hover tooltip could show unclamped text | ||||
|  - input text: option to Tab after an Enter validation. | ||||
|  - input text: add ImGuiInputTextFlags_EnterToApply? (off #218) | ||||
|   | ||||
							
								
								
									
										65
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										65
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -10535,15 +10535,23 @@ static void STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int pos, int n) | ||||
|  | ||||
| static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const ImWchar* new_text, int new_text_len) | ||||
| { | ||||
|     const bool is_resizable = (obj->UserFlags & ImGuiInputTextFlags_CallbackResize) != 0; | ||||
|     const int text_len = obj->CurLenW; | ||||
|     IM_ASSERT(pos <= text_len); | ||||
|     if (new_text_len + text_len + 1 > obj->Text.Size) | ||||
|         return false; | ||||
|  | ||||
|     const int new_text_len_utf8 = ImTextCountUtf8BytesFromStr(new_text, new_text + new_text_len); | ||||
|     if (new_text_len_utf8 + obj->CurLenA + 1 > obj->BufCapacityA) | ||||
|     if (!is_resizable && (new_text_len_utf8 + obj->CurLenA + 1 > obj->BufCapacityA)) | ||||
|         return false; | ||||
|  | ||||
|     // Grow internal buffer if needed | ||||
|     if (new_text_len + text_len + 1 > obj->Text.Size) | ||||
|     { | ||||
|         if (!is_resizable) | ||||
|             return false; | ||||
|         IM_ASSERT(text_len < obj->Text.Size); | ||||
|         obj->Text.resize(text_len + ImClamp(new_text_len * 4, 32, ImMax(256, new_text_len)) + 1); | ||||
|     } | ||||
|  | ||||
|     ImWchar* text = obj->Text.Data; | ||||
|     if (pos != text_len) | ||||
|         memmove(text + pos + new_text_len, text + pos, (size_t)(text_len - pos) * sizeof(ImWchar)); | ||||
| @@ -10585,6 +10593,11 @@ void ImGuiTextEditState::OnKeyPressed(int key) | ||||
|     CursorAnimReset(); | ||||
| } | ||||
|  | ||||
| ImGuiTextEditCallbackData::ImGuiTextEditCallbackData() | ||||
| { | ||||
|     memset(this, 0, sizeof(*this)); | ||||
| } | ||||
|  | ||||
| // Public API to manipulate UTF-8 text | ||||
| // We expose UTF-8 to the user (unlike the STB_TEXTEDIT_* functions which are manipulating wchar) | ||||
| // FIXME: The existence of this rarely exercised code path is a bit of a nuisance. | ||||
| @@ -10693,6 +10706,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 | ||||
|  | ||||
|     IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackHistory) && (flags & ImGuiInputTextFlags_Multiline))); // Can't use both together (they both use up/down keys) | ||||
|     IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackCompletion) && (flags & ImGuiInputTextFlags_AllowTabInput))); // Can't use both together (they both use tab key) | ||||
|     if (flags & ImGuiInputTextFlags_CallbackResize) | ||||
|         IM_ASSERT(callback != NULL); | ||||
|  | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     const ImGuiIO& io = g.IO; | ||||
| @@ -10818,6 +10833,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 | ||||
|  | ||||
|     bool value_changed = false; | ||||
|     bool enter_pressed = false; | ||||
|     int backup_current_text_length = 0; | ||||
|  | ||||
|     if (g.ActiveId == id) | ||||
|     { | ||||
| @@ -10831,7 +10847,11 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 | ||||
|             edit_state.CursorClamp(); | ||||
|         } | ||||
|  | ||||
|         backup_current_text_length = edit_state.CurLenA; | ||||
|         edit_state.BufCapacityA = buf_size; | ||||
|         edit_state.UserFlags = flags; | ||||
|         edit_state.UserCallback = callback; | ||||
|         edit_state.UserCallbackData = callback_user_data; | ||||
|  | ||||
|         // 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. | ||||
| @@ -11009,13 +11029,15 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 | ||||
|  | ||||
|     if (g.ActiveId == id) | ||||
|     { | ||||
|         const char* apply_new_text = NULL; | ||||
|         int apply_new_text_length = 0; | ||||
|         if (cancel_edit) | ||||
|         { | ||||
|             // Restore initial value. Only return true if restoring to the initial value changes the current buffer contents. | ||||
|             if (is_editable && strncmp(buf, edit_state.InitialText.Data, buf_size) != 0) | ||||
|             { | ||||
|                 ImStrncpy(buf, edit_state.InitialText.Data, buf_size); | ||||
|                 value_changed = true; | ||||
|                 apply_new_text = edit_state.InitialText.Data; | ||||
|                 apply_new_text_length = buf_size - 1; | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -11100,13 +11122,40 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Copy back to user buffer | ||||
|             // Will copy result string if modified | ||||
|             if (is_editable && strcmp(edit_state.TempTextBuffer.Data, buf) != 0) | ||||
|             { | ||||
|                 ImStrncpy(buf, edit_state.TempTextBuffer.Data, edit_state.CurLenA + 1); | ||||
|                 apply_new_text = edit_state.TempTextBuffer.Data; | ||||
|                 apply_new_text_length = edit_state.CurLenA; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Copy result to user buffer | ||||
|         if (apply_new_text) | ||||
|         { | ||||
|             IM_ASSERT(apply_new_text_length >= 0); | ||||
|             if (backup_current_text_length != apply_new_text_length && (flags & ImGuiInputTextFlags_CallbackResize)) | ||||
|             { | ||||
|                 ImGuiTextEditCallbackData callback_data; | ||||
|                 callback_data.EventFlag = ImGuiInputTextFlags_CallbackResize; | ||||
|                 callback_data.Flags = flags; | ||||
|                 callback_data.Buf = buf; | ||||
|                 callback_data.BufTextLen = edit_state.CurLenA; | ||||
|                 callback_data.BufSize = ImMax(buf_size, apply_new_text_length + 1); | ||||
|                 callback_data.UserData = callback_user_data; | ||||
|                 callback(&callback_data); | ||||
|                 buf = callback_data.Buf; | ||||
|                 buf_size = callback_data.BufSize; | ||||
|             } | ||||
|             IM_ASSERT(apply_new_text_length <= buf_size); | ||||
|             ImStrncpy(buf, edit_state.TempTextBuffer.Data, apply_new_text_length + 1); | ||||
|             value_changed = true; | ||||
|         } | ||||
|         } | ||||
|  | ||||
|         // Clear temporary user storage | ||||
|         edit_state.UserFlags = 0; | ||||
|         edit_state.UserCallback = NULL; | ||||
|         edit_state.UserCallbackData = NULL; | ||||
|     } | ||||
|  | ||||
|     // Release active ID at the end of the function (so e.g. pressing Return still does a final application of the value) | ||||
|   | ||||
							
								
								
									
										34
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -643,7 +643,7 @@ enum ImGuiInputTextFlags_ | ||||
|     ImGuiInputTextFlags_CallbackCompletion  = 1 << 6,   // Call user function on pressing TAB (for completion handling) | ||||
|     ImGuiInputTextFlags_CallbackHistory     = 1 << 7,   // Call user function on pressing Up/Down arrows (for history handling) | ||||
|     ImGuiInputTextFlags_CallbackAlways      = 1 << 8,   // Call user function every time. User code may query cursor position, modify text buffer. | ||||
|     ImGuiInputTextFlags_CallbackCharFilter  = 1 << 9,   // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character. | ||||
|     ImGuiInputTextFlags_CallbackCharFilter  = 1 << 9,   // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 in callback to discard character. | ||||
|     ImGuiInputTextFlags_AllowTabInput       = 1 << 10,  // Pressing TAB input a '\t' character into the text field | ||||
|     ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11,  // In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter (default is opposite: unfocus with Ctrl+Enter, add line with Enter). | ||||
|     ImGuiInputTextFlags_NoHorizontalScroll  = 1 << 12,  // Disable following the cursor horizontally | ||||
| @@ -652,6 +652,7 @@ enum ImGuiInputTextFlags_ | ||||
|     ImGuiInputTextFlags_Password            = 1 << 15,  // Password mode, display all characters as '*' | ||||
|     ImGuiInputTextFlags_NoUndoRedo          = 1 << 16,  // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID(). | ||||
|     ImGuiInputTextFlags_CharsScientific     = 1 << 17,  // Allow 0123456789.+-*/eE (Scientific notation input) | ||||
|     ImGuiInputTextFlags_CallbackResize      = 1 << 18,  // Allow buffer capacity resize + notify when the string wants to be resized (for string types which hold a cache of their Size) | ||||
|     // [Internal] | ||||
|     ImGuiInputTextFlags_Multiline           = 1 << 20   // For internal use by InputTextMultiline() | ||||
| }; | ||||
| @@ -1415,27 +1416,30 @@ struct ImGuiStorage | ||||
| }; | ||||
|  | ||||
| // Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used and the corresponding callback is triggered. | ||||
| // The callback function should return 0 by default. | ||||
| // Special processing: | ||||
| // - ImGuiInputTextFlags_CallbackCharFilter:  return 1 if the character is not allowed. You may also set 'EventChar=0' as any character replacement are allowed. | ||||
| // - ImGuiInputTextFlags_CallbackResize:      BufTextLen is set to the new desired string length so you can allocate or update known size. No need to initialize new characters or zero-terminator as InputText will do it. | ||||
| struct ImGuiTextEditCallbackData | ||||
| { | ||||
|     ImGuiInputTextFlags EventFlag;      // One of ImGuiInputTextFlags_Callback* // Read-only | ||||
|     ImGuiInputTextFlags EventFlag;      // One ImGuiInputTextFlags_Callback*    // Read-only | ||||
|     ImGuiInputTextFlags Flags;          // What user passed to InputText()      // Read-only | ||||
|     void*               UserData;       // What user passed to InputText()      // Read-only | ||||
|  | ||||
|     // CharFilter event: | ||||
|     ImWchar             EventChar;      // Character input                      // Read-write (replace character or set to zero) | ||||
|  | ||||
|     // Completion,History,Always events: | ||||
|     // If you modify the buffer contents make sure you update 'BufTextLen' and set 'BufDirty' to true. | ||||
|     ImGuiKey            EventKey;       // Key pressed (Up/Down/TAB)            // Read-only | ||||
|     char*               Buf;            // Current text buffer                  // Read-write (pointed data only, can't replace the actual pointer) | ||||
|     int                 BufTextLen;     // Current text length in bytes         // Read-write | ||||
|     int                 BufSize;        // Capacity (maximum text length + 1)   // Read-only | ||||
|     bool                BufDirty;       // Set if you modify Buf/BufTextLen!!   // Write | ||||
|     int                 CursorPos;      //                                      // Read-write | ||||
|     int                 SelectionStart; //                                      // Read-write (== to SelectionEnd when no selection) | ||||
|     int                 SelectionEnd;   //                                      // Read-write | ||||
|     // Arguments for the different callback events | ||||
|     // (If you modify the 'buf' contents make sure you update 'BufTextLen' and set 'BufDirty' to true!) | ||||
|     ImWchar             EventChar;      // Character input                      // Read-write   // [CharFilter] Replace character or set to zero. return 1 is equivalent to setting EventChar=0; | ||||
|     ImGuiKey            EventKey;       // Key pressed (Up/Down/TAB)            // Read-only    // [Completion,History] | ||||
|     char*               Buf;            // Current text buffer                  // Read-write   // [Resize] Can replace pointer / [Completion,History,Always] Only write to pointed data, don't replace the actual pointer! | ||||
|     int                 BufTextLen;     // Current text length in bytes         // Read-write   // [Resize,Completion,History,Always] | ||||
|     int                 BufSize;        // Capacity + 1 (max text length + 1)   // Read-only    // [Resize,Completion,History,Always] | ||||
|     bool                BufDirty;       // Set if you modify Buf/BufTextLen!!   // Write        // [Completion,History,Always] | ||||
|     int                 CursorPos;      //                                      // Read-write   // [Completion,History,Always] | ||||
|     int                 SelectionStart; //                                      // Read-write   // [Completion,History,Always] == to SelectionEnd when no selection) | ||||
|     int                 SelectionEnd;   //                                      // Read-write   // [Completion,History,Always] | ||||
|  | ||||
|     // NB: Helper functions for text manipulation. Calling those function loses selection. | ||||
|     ImGuiTextEditCallbackData(); | ||||
|     IMGUI_API void      DeleteChars(int pos, int bytes_count); | ||||
|     IMGUI_API void      InsertChars(int pos, const char* text, const char* text_end = NULL); | ||||
|     bool                HasSelection() const { return SelectionStart != SelectionEnd; } | ||||
|   | ||||
| @@ -443,6 +443,11 @@ struct IMGUI_API ImGuiTextEditState | ||||
|     bool                    CursorFollow; | ||||
|     bool                    SelectedAllMouseLock; | ||||
|  | ||||
|     // Temporarily set when active | ||||
|     ImGuiInputTextFlags     UserFlags; | ||||
|     ImGuiTextEditCallback   UserCallback; | ||||
|     void*                   UserCallbackData; | ||||
|  | ||||
|     ImGuiTextEditState()                            { memset(this, 0, sizeof(*this)); } | ||||
|     void                CursorAnimReset()           { CursorAnim = -0.30f; }                                   // After a user-input the cursor stays on for a while without blinking | ||||
|     void                CursorClamp()               { StbState.cursor = ImMin(StbState.cursor, CurLenW); StbState.select_start = ImMin(StbState.select_start, CurLenW); StbState.select_end = ImMin(StbState.select_end, CurLenW); } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 omar
					omar