diff --git a/imgui.cpp b/imgui.cpp index f4d2227f..2051f382 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10,8 +10,8 @@ - MISSION STATEMENT - END-USER GUIDE - PROGRAMMER GUIDE - - TROUBLESHOOTING & FREQUENTLY ASKED QUESTIONS - API BREAKING CHANGES + - TROUBLESHOOTING & FREQUENTLY ASKED QUESTIONS - ISSUES & TODO-LIST - CODE - SAMPLE CODE @@ -105,6 +105,22 @@ // swap video buffer, etc. } + API BREAKING CHANGES + ==================== + + 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. + + - 2014/11/26 (1.17) retired IMGUI_ONCE_UPON_A_FRAME helper macro in favor of ImGuiOnceUponAFrame type that works on all compilers. + - 2014/11/07 (1.15) renamed IsHovered() to IsItemHovered() + - 2014/10/02 (1.14) renamed IMGUI_INCLUDE_IMGUI_USER_CPP to IMGUI_INCLUDE_IMGUI_USER_INL and imgui_user.cpp to imgui_user.inl (more IDE friendly) + - 2014/09/25 (1.13) removed 'text_end' parameter from IO.SetClipboardTextFn (the string is now always zero-terminated for simplicity) + - 2014/09/24 (1.12) renamed SetFontScale() to SetWindowFontScale() + - 2014/09/24 (1.12) moved IM_MALLOC/IM_REALLOC/IM_FREE preprocessor defines to IO.MemAllocFn/IO.MemReallocFn/IO.MemFreeFn + - 2014/08/30 (1.09) removed IO.FontHeight (now computed automatically) + - 2014/08/30 (1.09) moved IMGUI_FONT_TEX_UV_FOR_WHITE preprocessor define to IO.FontTexUvForWhite + - 2014/08/28 (1.09) changed the behavior of IO.PixelCenterOffset following various rendering fixes + TROUBLESHOOTING & FREQUENTLY ASKED QUESTIONS ============================================ @@ -142,23 +158,11 @@ e.g. "##Foobar" display an empty label and uses "##Foobar" as ID - read articles about the imgui principles (see web links) to understand the requirement and use of ID. - - tip: the construct 'if (IMGUI_ONCE_UPON_A_FRAME)' will evaluate to true only once a frame, you can use it to add custom UI in the middle of a deep nested inner loop in your code. + - tip: the construct 'static ImGuiOnceUponAFrame once; if (once)' will evaluate to 'true' only once a frame, you can use it to quickly add custom UI in the middle of a deep nested inner loop in your code. - tip: you can call Render() multiple times (e.g for VR renders), up to you to communicate the extra state to your RenderDrawListFn function. - tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug" - tip: read the ShowTestWindow() code for more example of how to use ImGui! - API BREAKING CHANGES - ==================== - - - 2014/11/07 (1.15) renamed IsHovered() to IsItemHovered() - - 2014/10/02 (1.14) renamed IMGUI_INCLUDE_IMGUI_USER_CPP to IMGUI_INCLUDE_IMGUI_USER_INL and imgui_user.cpp to imgui_user.inl (more IDE friendly) - - 2014/09/25 (1.13) removed 'text_end' parameter from IO.SetClipboardTextFn (the string is now always zero-terminated for simplicity) - - 2014/09/24 (1.12) renamed SetFontScale() to SetWindowFontScale() - - 2014/09/24 (1.12) moved IM_MALLOC/IM_REALLOC/IM_FREE preprocessor defines to IO.MemAllocFn/IO.MemReallocFn/IO.MemFreeFn - - 2014/08/30 (1.09) removed IO.FontHeight (now computed automatically) - - 2014/08/30 (1.09) moved IMGUI_FONT_TEX_UV_FOR_WHITE preprocessor define to IO.FontTexUvForWhite - - 2014/08/28 (1.09) changed the behavior of IO.PixelCenterOffset following various rendering fixes - ISSUES & TODO-LIST ================== @@ -3678,7 +3682,7 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c ItemSize(bb); RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg)); - // Process clicking on the slider + // Process clicking on the slider if (g.ActiveId == id) { if (g.IO.MouseDown[0]) @@ -4121,7 +4125,7 @@ static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* ob static bool is_white(unsigned int c) { return c==0 || c==' ' || c=='\t' || c=='\r' || c=='\n'; } static bool is_separator(unsigned int c) { return c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; } -static bool STB_TEXTEDIT_IS_SPACE(ImWchar c) { return is_white((unsigned int)c) || is_separator((unsigned int)c); } +#define STB_TEXTEDIT_IS_SPACE(CH) ( is_white((unsigned int)CH) || is_separator((unsigned int)CH) ) static void STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int pos, int n) { ImWchar* dst = obj->Text+pos; const ImWchar* src = obj->Text+pos+n; while (ImWchar c = *src++) *dst++ = c; *dst = '\0'; } static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const ImWchar* new_text, int new_text_len) { @@ -4437,17 +4441,17 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT edit_state.SelectedAllMouseLock = false; const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0); - if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Backspace)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); } + if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_Delete)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } + else if (IsKeyPressedMap(ImGuiKey_Backspace)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Enter)) { g.ActiveId = 0; enter_pressed = true; } else if (IsKeyPressedMap(ImGuiKey_Escape)) { g.ActiveId = 0; cancel_edit = true; } - else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); } - else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); } - else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); } + else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); } + else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y)) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); } + else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); } else if (is_ctrl_down && (IsKeyPressedMap(ImGuiKey_X) || IsKeyPressedMap(ImGuiKey_C))) { // Cut, Copy @@ -4559,15 +4563,15 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT callback_data.BufSize = edit_state.BufSize; callback_data.BufDirty = false; callback_data.Flags = flags; - callback_data.UserData = user_data; + callback_data.UserData = user_data; // We have to convert from position from wchar to UTF-8 positions const int utf8_cursor_pos = callback_data.CursorPos = ImTextCountUtf8BytesFromWchar(edit_state.Text, edit_state.Text + edit_state.StbState.cursor); const int utf8_selection_start = callback_data.SelectionStart = ImTextCountUtf8BytesFromWchar(edit_state.Text, edit_state.Text + edit_state.StbState.select_start); const int utf8_selection_end = callback_data.SelectionEnd = ImTextCountUtf8BytesFromWchar(edit_state.Text, edit_state.Text + edit_state.StbState.select_end); - // Call user code - callback(&callback_data); + // Call user code + callback(&callback_data); // Read back what user may have modified IM_ASSERT(callback_data.Buf == text_tmp_utf8); // Invalid to modify those fields @@ -6683,6 +6687,10 @@ void ImGui::ShowTestWindow(bool* open) ImGui::EndTooltip(); } + //static ImGuiOnceUponAFrame oaf; + //if (oaf) ImGui::Text("This will be displayed."); + //if (oaf) ImGui::Text("This won't be displayed!"); + ImGui::Separator(); ImGui::Text("^ Horizontal separator"); @@ -7092,7 +7100,7 @@ struct ExampleAppConsole void 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) { case ImGuiKey_Tab: @@ -7149,11 +7157,11 @@ struct ExampleAppConsole match_len++; } - if (match_len > 0) - { - data->DeleteChars(word_start - data->Buf, word_end-word_start); - data->InsertChars(data->CursorPos, candidates[0], candidates[0] + match_len); - } + if (match_len > 0) + { + data->DeleteChars(word_start - data->Buf, word_end-word_start); + data->InsertChars(data->CursorPos, candidates[0], candidates[0] + match_len); + } // List matches AddLog("Possible matches:\n"); @@ -7182,7 +7190,7 @@ static void ShowExampleAppConsole(bool* open) } ImGui::TextWrapped("This example implement a simple console. A more elaborate implementation may want to store individual entries along with extra data such as timestamp, emitter, etc."); - ImGui::TextWrapped("Press TAB to use text completion."); + ImGui::TextWrapped("Press TAB to use text completion."); // TODO: display from bottom // TODO: clip manually diff --git a/imgui.h b/imgui.h index d0572a70..ae6e603d 100644 --- a/imgui.h +++ b/imgui.h @@ -123,7 +123,7 @@ public: #endif // #ifndef ImVector // Helpers at bottom of the file: -// - if (IMGUI_ONCE_UPON_A_FRAME) // Execute a block of code once per frame only +// - struct ImGuiOnceUponAFrame // Execute a block of code once per frame only (convenient for creating UI within deep-nested code that runs multiple times) // - struct ImGuiTextFilter // Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" // - struct ImGuiTextBuffer // Text buffer for logging/accumulating text // - struct ImGuiStorage // Custom key value storage (if you need to alter open/close states manually) @@ -239,7 +239,7 @@ namespace ImGui 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, 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, void (*callback)(ImGuiTextEditCallbackData*) = 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 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); @@ -326,8 +326,8 @@ enum ImGuiInputTextFlags_ ImGuiInputTextFlags_AutoSelectAll = 1 << 2, // Select entire text when first taking focus 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_CallbackHistory = 1 << 5, // Call user function on pressing Up/Down arrows (for history handling) - ImGuiInputTextFlags_CallbackAlways = 1 << 6 // Call user function every frame + ImGuiInputTextFlags_CallbackHistory = 1 << 5, // Call user function on pressing Up/Down arrows (for history handling) + ImGuiInputTextFlags_CallbackAlways = 1 << 6 // Call user function every frame //ImGuiInputTextFlags_AlignCenter = 1 << 6, }; @@ -529,15 +529,15 @@ struct ImGuiIO //----------------------------------------------------------------------------- // Helper: execute a block of code once a frame only -// Usage: if (IMGUI_ONCE_UPON_A_FRAME) {/*do something once a frame*/) -#define IMGUI_ONCE_UPON_A_FRAME static ImGuiOncePerFrame im = ImGuiOncePerFrame() -struct ImGuiOncePerFrame +// Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. +// Usage: +// static ImGuiOnceUponAFrame once; +// if (once) { ... } +struct ImGuiOnceUponAFrame { - ImGuiOncePerFrame() : LastFrame(-1) {} - operator bool() const { return TryIsNewFrame(); } -private: - mutable int LastFrame; - bool TryIsNewFrame() const { const int current_frame = ImGui::GetFrameCount(); if (LastFrame == current_frame) return false; LastFrame = current_frame; return true; } + ImGuiOnceUponAFrame() { RefFrame = -1; } + mutable int RefFrame; + operator bool() const { const int current_frame = ImGui::GetFrameCount(); if (RefFrame == current_frame) return false; RefFrame = current_frame; return true; } }; // Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" @@ -608,19 +608,19 @@ struct ImGuiStorage // Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used. struct ImGuiTextEditCallbackData { - 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 - ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only - int CursorPos; // // Read-write - int SelectionStart; // // Read-write (== to SelectionEnd when no selection) - int SelectionEnd; // // Read-write - 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 + ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only + int CursorPos; // // Read-write + int SelectionStart; // // Read-write (== to SelectionEnd when no selection) + int SelectionEnd; // // Read-write + void* UserData; // What user passed to InputText() - // NB: calling those function loses selection. - void DeleteChars(size_t pos, size_t bytes_count); - void InsertChars(size_t pos, const char* text, const char* text_end = NULL); + // NB: calling those function loses selection. + void DeleteChars(size_t pos, size_t bytes_count); + void InsertChars(size_t pos, const char* text, const char* text_end = NULL); }; //-----------------------------------------------------------------------------