mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
InputText(): added ImGuiInputTextFlags_CallbackCharFilter system for filtering/replacement. Callback now passed an "EventFlag" parameter.
This commit is contained in:
parent
183a27fd70
commit
9473cd491e
92
imgui.cpp
92
imgui.cpp
@ -129,6 +129,7 @@
|
|||||||
Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix.
|
Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix.
|
||||||
Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
|
Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
|
||||||
|
|
||||||
|
- 2015/02/11 (1.32) - changed text input callback ImGuiTextEditCallback return type from void-->int. reserved for future use, return 0 for now.
|
||||||
- 2015/02/10 (1.32) - renamed GetItemWidth() to CalcItemWidth() to clarify its evolving behavior
|
- 2015/02/10 (1.32) - renamed GetItemWidth() to CalcItemWidth() to clarify its evolving behavior
|
||||||
- 2015/02/08 (1.31) - renamed GetTextLineSpacing() to GetTextLineHeightWithSpacing()
|
- 2015/02/08 (1.31) - renamed GetTextLineSpacing() to GetTextLineHeightWithSpacing()
|
||||||
- 2015/02/01 (1.31) - removed IO.MemReallocFn (unused)
|
- 2015/02/01 (1.31) - removed IO.MemReallocFn (unused)
|
||||||
@ -5223,27 +5224,44 @@ void ImGuiTextEditCallbackData::InsertChars(int pos, const char* new_text, const
|
|||||||
SelectionStart = SelectionEnd = CursorPos;
|
SelectionStart = SelectionEnd = CursorPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool InputTextFilterCharacter(ImWchar c, ImGuiInputTextFlags flags)
|
// Return false to discard a character.
|
||||||
|
static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data)
|
||||||
{
|
{
|
||||||
|
unsigned int c = *p_char;
|
||||||
|
|
||||||
if (c < 128 && c != ' ' && !isprint((int)(c & 0xFF)))
|
if (c < 128 && c != ' ' && !isprint((int)(c & 0xFF)))
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
if (c >= 0xE000 && c <= 0xF8FF) // Filter private Unicode range. I don't imagine anybody would want to input them. GLFW on OSX seems to send private characters for special keys like arrow keys.
|
if (c >= 0xE000 && c <= 0xF8FF) // Filter private Unicode range. I don't imagine anybody would want to input them. GLFW on OSX seems to send private characters for special keys like arrow keys.
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
if (flags & ImGuiInputTextFlags_CharsDecimal)
|
if (flags & ImGuiInputTextFlags_CharsDecimal)
|
||||||
if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/'))
|
if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/'))
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
if (flags & ImGuiInputTextFlags_CharsHexadecimal)
|
if (flags & ImGuiInputTextFlags_CharsHexadecimal)
|
||||||
if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F'))
|
if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F'))
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
return false;
|
if (flags & ImGuiInputTextFlags_CallbackCharFilter)
|
||||||
|
{
|
||||||
|
ImGuiTextEditCallbackData callback_data;
|
||||||
|
memset(&callback_data, 0, sizeof(ImGuiTextEditCallbackData));
|
||||||
|
callback_data.EventFlag = ImGuiInputTextFlags_CallbackCharFilter;
|
||||||
|
callback_data.EventChar = c;
|
||||||
|
callback_data.Flags = flags;
|
||||||
|
callback_data.UserData = user_data;
|
||||||
|
callback(&callback_data);
|
||||||
|
*p_char = callback_data.EventChar;
|
||||||
|
if (!callback_data.EventChar)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Edit a string of text
|
// Edit a string of text
|
||||||
bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, void (*callback)(ImGuiTextEditCallbackData*), void* user_data)
|
bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data)
|
||||||
{
|
{
|
||||||
ImGuiState& g = *GImGui;
|
ImGuiState& g = *GImGui;
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
@ -5344,13 +5362,13 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT
|
|||||||
// Process text input (before we check for Return because using some IME will effectively send a Return?)
|
// Process text input (before we check for Return because using some IME will effectively send a Return?)
|
||||||
for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
|
for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
|
||||||
{
|
{
|
||||||
const ImWchar c = g.IO.InputCharacters[n];
|
unsigned int c = (unsigned int)g.IO.InputCharacters[n];
|
||||||
if (c)
|
if (c)
|
||||||
{
|
{
|
||||||
// Insert character if they pass filtering
|
// Insert character if they pass filtering
|
||||||
if (InputTextFilterCharacter(c, flags))
|
if (!InputTextFilterCharacter(&c, flags, callback, user_data))
|
||||||
continue;
|
continue;
|
||||||
edit_state.OnKeyPressed(c);
|
edit_state.OnKeyPressed((int)c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5407,7 +5425,7 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT
|
|||||||
break;
|
break;
|
||||||
if (c >= 0x10000)
|
if (c >= 0x10000)
|
||||||
continue;
|
continue;
|
||||||
if (InputTextFilterCharacter((ImWchar)c, flags))
|
if (!InputTextFilterCharacter(&c, flags, callback, user_data))
|
||||||
continue;
|
continue;
|
||||||
clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c;
|
clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c;
|
||||||
}
|
}
|
||||||
@ -5442,17 +5460,28 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT
|
|||||||
IM_ASSERT(callback != NULL);
|
IM_ASSERT(callback != NULL);
|
||||||
|
|
||||||
// The reason we specify the usage semantic (Completion/History) is that Completion needs to disable keyboard TABBING at the moment.
|
// The reason we specify the usage semantic (Completion/History) is that Completion needs to disable keyboard TABBING at the moment.
|
||||||
|
ImGuiInputTextFlags event_flag = 0;
|
||||||
ImGuiKey event_key = ImGuiKey_COUNT;
|
ImGuiKey event_key = ImGuiKey_COUNT;
|
||||||
if ((flags & ImGuiInputTextFlags_CallbackCompletion) != 0 && IsKeyPressedMap(ImGuiKey_Tab))
|
if ((flags & ImGuiInputTextFlags_CallbackCompletion) != 0 && IsKeyPressedMap(ImGuiKey_Tab))
|
||||||
|
{
|
||||||
|
event_flag = ImGuiInputTextFlags_CallbackCompletion;
|
||||||
event_key = ImGuiKey_Tab;
|
event_key = ImGuiKey_Tab;
|
||||||
|
}
|
||||||
else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_UpArrow))
|
else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_UpArrow))
|
||||||
|
{
|
||||||
|
event_flag = ImGuiInputTextFlags_CallbackHistory;
|
||||||
event_key = ImGuiKey_UpArrow;
|
event_key = ImGuiKey_UpArrow;
|
||||||
|
}
|
||||||
else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_DownArrow))
|
else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_DownArrow))
|
||||||
|
{
|
||||||
|
event_flag = ImGuiInputTextFlags_CallbackHistory;
|
||||||
event_key = ImGuiKey_DownArrow;
|
event_key = ImGuiKey_DownArrow;
|
||||||
|
}
|
||||||
|
|
||||||
if (event_key != ImGuiKey_COUNT || (flags & ImGuiInputTextFlags_CallbackAlways) != 0)
|
if (event_key != ImGuiKey_COUNT || (flags & ImGuiInputTextFlags_CallbackAlways) != 0)
|
||||||
{
|
{
|
||||||
ImGuiTextEditCallbackData callback_data;
|
ImGuiTextEditCallbackData callback_data;
|
||||||
|
callback_data.EventFlag = event_flag;
|
||||||
callback_data.EventKey = event_key;
|
callback_data.EventKey = event_key;
|
||||||
callback_data.Buf = text_tmp_utf8;
|
callback_data.Buf = text_tmp_utf8;
|
||||||
callback_data.BufSize = edit_state.BufSize;
|
callback_data.BufSize = edit_state.BufSize;
|
||||||
@ -8313,6 +8342,33 @@ void ImGui::ShowTestWindow(bool* opened)
|
|||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::TreeNode("Filtered Text Input"))
|
||||||
|
{
|
||||||
|
static char buf1[64] = ""; ImGui::InputText("default", buf1, 64);
|
||||||
|
static char buf2[64] = ""; ImGui::InputText("decimal", buf2, 64, ImGuiInputTextFlags_CharsDecimal);
|
||||||
|
static char buf3[64] = ""; ImGui::InputText("hexadecimal", buf3, 64, ImGuiInputTextFlags_CharsHexadecimal);
|
||||||
|
struct TextFilters
|
||||||
|
{
|
||||||
|
static int FilterAZ(ImGuiTextEditCallbackData* data)
|
||||||
|
{
|
||||||
|
const ImWchar c = data->EventChar;
|
||||||
|
if (!((c >= 'a' && c <= 'z') || c >= 'A' && c <= 'Z'))
|
||||||
|
data->EventChar = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int FilterUppercase(ImGuiTextEditCallbackData* data)
|
||||||
|
{
|
||||||
|
const ImWchar c = data->EventChar;
|
||||||
|
if (c >= 'a' && c <= 'z')
|
||||||
|
data->EventChar += 'A'-'a';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static char buf4[64] = ""; ImGui::InputText("a-z only", buf4, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterAZ);
|
||||||
|
static char buf5[64] = ""; ImGui::InputText("uppercase", buf5, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterUppercase);
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
|
||||||
static bool check = true;
|
static bool check = true;
|
||||||
ImGui::Checkbox("checkbox", &check);
|
ImGui::Checkbox("checkbox", &check);
|
||||||
|
|
||||||
@ -8967,18 +9023,18 @@ struct ExampleAppConsole
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TextEditCallbackStub(ImGuiTextEditCallbackData* data)
|
static int TextEditCallbackStub(ImGuiTextEditCallbackData* data)
|
||||||
{
|
{
|
||||||
ExampleAppConsole* console = (ExampleAppConsole*)data->UserData;
|
ExampleAppConsole* console = (ExampleAppConsole*)data->UserData;
|
||||||
console->TextEditCallback(data);
|
return console->TextEditCallback(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEditCallback(ImGuiTextEditCallbackData* data)
|
int TextEditCallback(ImGuiTextEditCallbackData* data)
|
||||||
{
|
{
|
||||||
//AddLog("cursor: %d, selection: %d-%d", data->CursorPos, data->SelectionStart, data->SelectionEnd);
|
//AddLog("cursor: %d, selection: %d-%d", data->CursorPos, data->SelectionStart, data->SelectionEnd);
|
||||||
switch (data->EventKey)
|
switch (data->EventFlag)
|
||||||
{
|
{
|
||||||
case ImGuiKey_Tab:
|
case ImGuiInputTextFlags_CallbackCompletion:
|
||||||
{
|
{
|
||||||
// Example of TEXT COMPLETION
|
// Example of TEXT COMPLETION
|
||||||
|
|
||||||
@ -9043,8 +9099,7 @@ struct ExampleAppConsole
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ImGuiKey_UpArrow:
|
case ImGuiInputTextFlags_CallbackHistory:
|
||||||
case ImGuiKey_DownArrow:
|
|
||||||
{
|
{
|
||||||
// Example of HISTORY
|
// Example of HISTORY
|
||||||
const int prev_history_pos = HistoryPos;
|
const int prev_history_pos = HistoryPos;
|
||||||
@ -9071,6 +9126,7 @@ struct ExampleAppConsole
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
30
imgui.h
30
imgui.h
@ -44,6 +44,7 @@ typedef int ImGuiWindowFlags; // enum ImGuiWindowFlags_
|
|||||||
typedef int ImGuiSetCondition; // enum ImGuiSetCondition_
|
typedef int ImGuiSetCondition; // enum ImGuiSetCondition_
|
||||||
typedef int ImGuiInputTextFlags; // enum ImGuiInputTextFlags_
|
typedef int ImGuiInputTextFlags; // enum ImGuiInputTextFlags_
|
||||||
struct ImGuiTextEditCallbackData; // for advanced uses of InputText()
|
struct ImGuiTextEditCallbackData; // for advanced uses of InputText()
|
||||||
|
typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data);
|
||||||
|
|
||||||
struct ImVec2
|
struct ImVec2
|
||||||
{
|
{
|
||||||
@ -275,7 +276,7 @@ namespace ImGui
|
|||||||
IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
|
IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
|
||||||
IMGUI_API bool RadioButton(const char* label, bool active);
|
IMGUI_API bool RadioButton(const char* label, bool active);
|
||||||
IMGUI_API bool RadioButton(const char* label, int* v, int v_button);
|
IMGUI_API bool RadioButton(const char* label, int* v, int v_button);
|
||||||
IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, void (*callback)(ImGuiTextEditCallbackData*) = NULL, void* user_data = NULL);
|
IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL);
|
||||||
IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0);
|
IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0);
|
||||||
IMGUI_API bool InputFloat2(const char* label, float v[2], int decimal_precision = -1);
|
IMGUI_API bool InputFloat2(const char* label, float v[2], int decimal_precision = -1);
|
||||||
IMGUI_API bool InputFloat3(const char* label, float v[3], int decimal_precision = -1);
|
IMGUI_API bool InputFloat3(const char* label, float v[3], int decimal_precision = -1);
|
||||||
@ -391,7 +392,8 @@ enum ImGuiInputTextFlags_
|
|||||||
ImGuiInputTextFlags_EnterReturnsTrue = 1 << 3, // Return 'true' when Enter is pressed (as opposed to when the value was modified)
|
ImGuiInputTextFlags_EnterReturnsTrue = 1 << 3, // Return 'true' when Enter is pressed (as opposed to when the value was modified)
|
||||||
ImGuiInputTextFlags_CallbackCompletion = 1 << 4, // Call user function on pressing TAB (for completion handling)
|
ImGuiInputTextFlags_CallbackCompletion = 1 << 4, // Call user function on pressing TAB (for completion handling)
|
||||||
ImGuiInputTextFlags_CallbackHistory = 1 << 5, // Call user function on pressing Up/Down arrows (for history handling)
|
ImGuiInputTextFlags_CallbackHistory = 1 << 5, // Call user function on pressing Up/Down arrows (for history handling)
|
||||||
ImGuiInputTextFlags_CallbackAlways = 1 << 6 // Call user function every time
|
ImGuiInputTextFlags_CallbackAlways = 1 << 6, // Call user function every time
|
||||||
|
ImGuiInputTextFlags_CallbackCharFilter = 1 << 7 // Call user function to filter character. Modify data->EventChar to replace/filter input.
|
||||||
//ImGuiInputTextFlags_AlignCenter = 1 << 6,
|
//ImGuiInputTextFlags_AlignCenter = 1 << 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -716,15 +718,21 @@ struct ImGuiStorage
|
|||||||
// Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used.
|
// Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used.
|
||||||
struct ImGuiTextEditCallbackData
|
struct ImGuiTextEditCallbackData
|
||||||
{
|
{
|
||||||
ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only
|
ImGuiInputTextFlags EventFlag; // One of ImGuiInputTextFlags_Callback* // Read-only
|
||||||
char* Buf; // Current text // Read-write (pointed data only)
|
ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only
|
||||||
size_t BufSize; // // Read-only
|
void* UserData; // What user passed to InputText() // Read-only
|
||||||
bool BufDirty; // Set if you modify Buf directly // Write
|
|
||||||
ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only
|
// CharFilter event:
|
||||||
int CursorPos; // // Read-write
|
ImWchar EventChar; // Character input // Read-write (replace character or set to zero)
|
||||||
int SelectionStart; // // Read-write (== to SelectionEnd when no selection)
|
|
||||||
int SelectionEnd; // // Read-write
|
// Completion,History,Always events:
|
||||||
void* UserData; // What user passed to InputText()
|
ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only
|
||||||
|
char* Buf; // Current text // Read-write (pointed data only)
|
||||||
|
size_t BufSize; // // Read-only
|
||||||
|
bool BufDirty; // Set if you modify Buf directly // Write
|
||||||
|
int CursorPos; // // Read-write
|
||||||
|
int SelectionStart; // // Read-write (== to SelectionEnd when no selection)
|
||||||
|
int SelectionEnd; // // Read-write
|
||||||
|
|
||||||
// NB: calling those function loses selection.
|
// NB: calling those function loses selection.
|
||||||
void DeleteChars(int pos, int bytes_count);
|
void DeleteChars(int pos, int bytes_count);
|
||||||
|
Loading…
Reference in New Issue
Block a user