From fe48368cb2f198b5ea4c3e1629144b0682b86944 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Mar 2019 15:44:21 +0100 Subject: [PATCH 1/6] InputText: Moving some code in anticipation of supporting hint display with password. This commit is aimed at having no visible side effect. (#2400) --- imgui_widgets.cpp | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index a3683613..543bcf8b 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -3252,23 +3252,6 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (hovered) g.MouseCursor = ImGuiMouseCursor_TextInput; - // Password pushes a temporary font with only a fallback glyph - if (is_password) - { - const ImFontGlyph* glyph = g.Font->FindGlyph('*'); - ImFont* password_font = &g.InputTextPasswordFont; - password_font->FontSize = g.Font->FontSize; - password_font->Scale = g.Font->Scale; - password_font->DisplayOffset = g.Font->DisplayOffset; - password_font->Ascent = g.Font->Ascent; - password_font->Descent = g.Font->Descent; - password_font->ContainerAtlas = g.Font->ContainerAtlas; - password_font->FallbackGlyph = glyph; - password_font->FallbackAdvanceX = glyph->AdvanceX; - IM_ASSERT(password_font->Glyphs.empty() && password_font->IndexAdvanceX.empty() && password_font->IndexLookup.empty()); - PushFont(password_font); - } - // NB: we are only allowed to access 'edit_state' if we are the active widget. ImGuiInputTextState* state = NULL; if (g.InputTextState.ID == id) @@ -3353,10 +3336,6 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (g.ActiveId == id && io.MouseClicked[0] && !init_state && !init_make_active) //-V560 clear_active_id = true; - bool value_changed = false; - bool enter_pressed = false; - int backup_current_text_length = 0; - // When read-only we always use the live data passed to the function // FIXME-OPT: Because our selection/cursor code currently needs the wide text we need to convert it when active, which is not ideal :( if (is_readonly && state != NULL) @@ -3373,7 +3352,31 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 } } + // Lock the decision of whether we are going to take the path displaying the cursor or selection + const bool render_cursor = (g.ActiveId == id) || (state && user_scroll_active); + const bool render_selection = state && state->HasSelection() && (RENDER_SELECTION_WHEN_INACTIVE || render_cursor); + bool value_changed = false; + bool enter_pressed = false; + + // Password pushes a temporary font with only a fallback glyph + if (is_password) + { + const ImFontGlyph* glyph = g.Font->FindGlyph('*'); + ImFont* password_font = &g.InputTextPasswordFont; + password_font->FontSize = g.Font->FontSize; + password_font->Scale = g.Font->Scale; + password_font->DisplayOffset = g.Font->DisplayOffset; + password_font->Ascent = g.Font->Ascent; + password_font->Descent = g.Font->Descent; + password_font->ContainerAtlas = g.Font->ContainerAtlas; + password_font->FallbackGlyph = glyph; + password_font->FallbackAdvanceX = glyph->AdvanceX; + IM_ASSERT(password_font->Glyphs.empty() && password_font->IndexAdvanceX.empty() && password_font->IndexLookup.empty()); + PushFont(password_font); + } + // Process mouse inputs and character inputs + int backup_current_text_length = 0; if (g.ActiveId == id) { IM_ASSERT(state != NULL); @@ -3725,8 +3728,6 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Render text. We currently only render selection when the widget is active or while scrolling. // FIXME: We could remove the '&& render_cursor' to keep rendering selection when inactive. - const bool render_cursor = (g.ActiveId == id) || (state && user_scroll_active); - const bool render_selection = state && state->HasSelection() && (RENDER_SELECTION_WHEN_INACTIVE || render_cursor); if (render_cursor || render_selection) { // Render text (with cursor and selection) From ab80ee645316f36c172fcef9fe9a7d225516dbb2 Mon Sep 17 00:00:00 2001 From: Lucas Lazare Date: Wed, 6 Mar 2019 14:31:19 +0100 Subject: [PATCH 2/6] Added InputTextWithHint() (#2400) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Squashed commit of the following: commit 1970d84051d3878f8c1354d9c33c795d9c66143f Author: Lucas Lazare Date: Tue Mar 5 12:20:39 2019 -0500 Removing sneaky tabulations #2 (why, editor T-T) I should update my settings, I guess commit 219bdfcb7fbd17edf3048cb0edfde2532e4d6ac3 Author: Lucas Lazare Date: Tue Mar 5 12:17:27 2019 -0500 Removing useless check introduced in b0d172 commit 8afd7a2b459df0eb14eca88d832d2bebd1e684e6 Author: Lucas Lazare Date: Tue Mar 5 11:49:24 2019 -0500 Removing sneaky tabulations commit 8e0490863126d63cafc782a6aac8707e44f95653 Author: Lucas Lazare Date: Tue Mar 5 11:45:13 2019 -0500 Moving InputTextHinted code to InputTextEx commit b0d1723a2fb02d17ba15b9c1e679dedbbe3c17fd Author: Lucas Lazare Date: Tue Mar 5 00:23:02 2019 -0500 C++11 to C++98 commit 9afeae399826015357962607b4aeb0109fde698e Author: Lucas Lazare Date: Mon Mar 4 23:43:28 2019 -0500 Added InputTextHinted --- imgui.h | 1 + imgui_demo.cpp | 5 +++- imgui_internal.h | 2 +- imgui_widgets.cpp | 52 ++++++++++++++++++++++++++++++++------- misc/cpp/imgui_stdlib.cpp | 12 +++++++++ misc/cpp/imgui_stdlib.h | 1 + 6 files changed, 62 insertions(+), 11 deletions(-) diff --git a/imgui.h b/imgui.h index 2ffe14dd..748313ec 100644 --- a/imgui.h +++ b/imgui.h @@ -450,6 +450,7 @@ namespace ImGui // - Most of the ImGuiInputTextFlags flags are only useful for InputText() and not for InputFloatX, InputIntX, InputDouble etc. IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0,0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); + IMGUI_API bool InputTextWithHint(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, const char* format = "%.3f", ImGuiInputTextFlags flags = 0); IMGUI_API bool InputFloat2(const char* label, float v[2], const char* format = "%.3f", ImGuiInputTextFlags flags = 0); IMGUI_API bool InputFloat3(const char* label, float v[3], const char* format = "%.3f", ImGuiInputTextFlags flags = 0); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 45a21e48..1ecf49b8 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -481,10 +481,13 @@ static void ShowDemoWindowWidgets() { static char str0[128] = "Hello, world!"; - static int i0 = 123; ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0)); ImGui::SameLine(); ShowHelpMarker("USER:\nHold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n\nPROGRAMMER:\nYou can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputText() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example (this is not demonstrated in imgui_demo.cpp)."); + static char str1[128] = ""; + ImGui::InputTextWithHint("input text (w/ hint)", "enter text here", str1, IM_ARRAYSIZE(str1)); + + static int i0 = 123; ImGui::InputInt("input int", &i0); ImGui::SameLine(); ShowHelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n"); diff --git a/imgui_internal.h b/imgui_internal.h index 4f5ac884..576e3366 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1545,7 +1545,7 @@ namespace ImGui template IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v); // InputText - IMGUI_API bool InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); + 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); // Color diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 543bcf8b..388d5547 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -2692,7 +2692,7 @@ bool ImGui::InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const c DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, data_ptr, format); ImStrTrimBlanks(data_buf); ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ((data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImGuiInputTextFlags_CharsScientific : ImGuiInputTextFlags_CharsDecimal); - bool value_changed = InputTextEx(label, data_buf, IM_ARRAYSIZE(data_buf), bb.GetSize(), flags); + bool value_changed = InputTextEx(label, NULL, data_buf, IM_ARRAYSIZE(data_buf), bb.GetSize(), flags); if (g.ScalarAsInputTextId == 0) { // First frame we started displaying the InputText widget, we expect it to take the active id. @@ -2883,9 +2883,10 @@ bool ImGui::InputDouble(const char* label, double* v, double step, double step_f } //------------------------------------------------------------------------- -// [SECTION] Widgets: InputText, InputTextMultiline +// [SECTION] Widgets: InputText, InputTextMultiline, InputTextWithHint //------------------------------------------------------------------------- // - InputText() +// - InputTextWithHint() // - InputTextMultiline() // - InputTextEx() [Internal] //------------------------------------------------------------------------- @@ -2893,12 +2894,17 @@ bool ImGui::InputDouble(const char* label, double* v, double step, double step_f bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) { IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline() - return InputTextEx(label, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data); + return InputTextEx(label, NULL, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data); } bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) { - return InputTextEx(label, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data); + return InputTextEx(label, NULL, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data); +} + +bool ImGui::InputTextWithHint(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) +{ + return InputTextEx(label, hint, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data); } static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end) @@ -3193,7 +3199,7 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f // - If you want to use ImGui::InputText() with std::string, see misc/cpp/imgui_stdlib.h // (FIXME: Rather confusing and messy function, among the worse part of our codebase, expecting to rewrite a V2 at some point.. Partly because we are // doing UTF8 > U16 > UTF8 conversions on the go to easily interface with stb_textedit. Ideally should stay in UTF-8 all the time. See https://github.com/nothings/stb/issues/188) -bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* callback_user_data) +bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* callback_user_data) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -3725,6 +3731,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const int buf_display_max_length = 2 * 1024 * 1024; const char* buf_display = NULL; const char* buf_display_end = NULL; + ImGuiCol text_color = ImGuiCol_COUNT; // Render text. We currently only render selection when the widget is active or while scrolling. // FIXME: We could remove the '&& render_cursor' to keep rendering selection when inactive. @@ -3861,11 +3868,26 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 } } + if (state->CurLenA != 0 || hint == NULL) + { + buf_display = (!is_readonly && state->TextAIsValid) ? state->TextA.Data : buf; + buf_display_end = buf_display + state->CurLenA; + text_color = ImGuiCol_Text; + } + else + { + buf_display = hint; + buf_display_end = hint + strlen(hint); + text_color = ImGuiCol_TextDisabled; + } + + // We test for 'buf_display_max_length' as a way to avoid some pathological cases (e.g. single-line 1 MB string) which would make ImDrawList crash. - buf_display = (!is_readonly && state->TextAIsValid) ? state->TextA.Data : buf; - buf_display_end = buf_display + state->CurLenA; if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length) - draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, GetColorU32(ImGuiCol_Text), buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect); + { + IM_ASSERT(text_color != ImGuiCol_COUNT); + draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, GetColorU32(text_color), buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect); + } // Draw blinking cursor if (render_cursor) @@ -3885,6 +3907,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 else { // Render text only (no selection, no cursor) + text_color = ImGuiCol_Text; buf_display = (g.ActiveId == id && !is_readonly && state->TextAIsValid) ? state->TextA.Data : buf; if (is_multiline) text_size = ImVec2(size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_display_end) * g.FontSize); // We don't need width @@ -3892,8 +3915,19 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 buf_display_end = buf_display + state->CurLenA; else buf_display_end = buf_display + strlen(buf_display); + + if (buf_display_end == buf_display && hint != NULL) + { + buf_display = hint; + buf_display_end = buf_display + strlen(buf_display); + text_color = ImGuiCol_TextDisabled; + } + if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length) - draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos, GetColorU32(ImGuiCol_Text), buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect); + { + IM_ASSERT(text_color != ImGuiCol_COUNT); + draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos, GetColorU32(text_color), buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect); + } } if (is_multiline) diff --git a/misc/cpp/imgui_stdlib.cpp b/misc/cpp/imgui_stdlib.cpp index 694813a4..fda60f4d 100644 --- a/misc/cpp/imgui_stdlib.cpp +++ b/misc/cpp/imgui_stdlib.cpp @@ -63,3 +63,15 @@ bool ImGui::InputTextMultiline(const char* label, std::string* str, const ImVec2 cb_user_data.ChainCallbackUserData = user_data; return InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, &cb_user_data); } + +bool ImGui::InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) +{ + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + flags |= ImGuiInputTextFlags_CallbackResize; + + InputTextCallback_UserData cb_user_data; + cb_user_data.Str = str; + cb_user_data.ChainCallback = callback; + cb_user_data.ChainCallbackUserData = user_data; + return InputTextWithHint(label, hint, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data); +} diff --git a/misc/cpp/imgui_stdlib.h b/misc/cpp/imgui_stdlib.h index 06b06b9a..5bccb032 100644 --- a/misc/cpp/imgui_stdlib.h +++ b/misc/cpp/imgui_stdlib.h @@ -19,4 +19,5 @@ namespace ImGui // Because text input needs dynamic resizing, we need to setup a callback to grow the capacity IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); + IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); } From c779fbb651a5979e0701949b90898e6b7cae3390 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Mar 2019 17:33:24 +0100 Subject: [PATCH 3/6] InputTextWithHint: Fix for Password fields. Update changelog, demo. (#2400) --- docs/CHANGELOG.txt | 4 +++- imgui_demo.cpp | 4 +++- imgui_widgets.cpp | 60 +++++++++++++++++++--------------------------- 3 files changed, 30 insertions(+), 38 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 7f002f30..1f928008 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -45,7 +45,9 @@ Other Changes: - Added GetBackgroundDrawList() helper to quickly get access to a ImDrawList that will be rendered behind every other windows. (#2391) - DragScalar, InputScalar, SliderScalar: Added support for u8/s8/u16/s16 data types. - We are reusing function instances for larger types to reduce code size. (#643, #320, #708, #1011) + We are reusing function instances of larger types to reduce code size. (#643, #320, #708, #1011) +- Added InputTextWithHint() to display a description/hint in the text box when no text + has been entered. (#2400) [@Organic-Code, @ocornut] - Nav: Fixed a tap on AltGR (e.g. German keyboard) from navigating to the menu layer. - Nav: Fixed Ctrl+Tab keeping active InputText() of a previous window active after the switch. (#2380) - Fixed IsItemDeactivated()/IsItemDeactivatedAfterEdit() from not correctly returning true diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 1ecf49b8..f8f23c2f 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -770,6 +770,7 @@ static void ShowDemoWindowWidgets() // Expose flags as checkbox for the demo static ImGuiComboFlags flags = 0; ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", (unsigned int*)&flags, ImGuiComboFlags_PopupAlignLeft); + ImGui::SameLine(); ShowHelpMarker("Only makes a difference if the popup is larger than the combo"); if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", (unsigned int*)&flags, ImGuiComboFlags_NoArrowButton)) flags &= ~ImGuiComboFlags_NoPreview; // Clear the other flag, as we cannot combine both if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", (unsigned int*)&flags, ImGuiComboFlags_NoPreview)) @@ -934,6 +935,7 @@ static void ShowDemoWindowWidgets() static char bufpass[64] = "password123"; ImGui::InputText("password", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); ImGui::SameLine(); ShowHelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); + ImGui::InputTextWithHint("password (w/ hint)", "", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); ImGui::InputText("password (clear)", bufpass, 64, ImGuiInputTextFlags_CharsNoBlank); ImGui::TreePop(); @@ -2177,7 +2179,7 @@ static void ShowDemoWindowPopups() // We can also use OpenPopupOnItemClick() which is the same as BeginPopupContextItem() but without the Begin call. // So here we will make it that clicking on the text field with the right mouse button (1) will toggle the visibility of the popup above. - ImGui::Text("(You can also right-click me to the same popup as above.)"); + ImGui::Text("(You can also right-click me to open the same popup as above.)"); ImGui::OpenPopupOnItemClick("item context menu", 1); // When used after an item that has an ID (here the Button), we can skip providing an ID to BeginPopupContextItem(). diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 388d5547..bb514efc 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -2904,7 +2904,8 @@ bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, co bool ImGui::InputTextWithHint(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) { - return InputTextEx(label, hint, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data); + IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline() + return InputTextEx(label, hint, buf, (int)buf_size, ImVec2(0, 0), flags, callback, user_data); } static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end) @@ -3364,8 +3365,18 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ bool value_changed = false; bool enter_pressed = false; + // Select the buffer to render. + const char* buf_display = ((render_cursor || render_selection || g.ActiveId == id) && !is_readonly && state->TextAIsValid) ? state->TextA.Data : buf; + const char* buf_display_end = NULL; // We have specialized paths below for setting the length + const bool is_displaying_hint = (hint != NULL && buf_display[0] == 0); + if (is_displaying_hint) + { + buf_display = hint; + buf_display_end = hint + strlen(hint); + } + // Password pushes a temporary font with only a fallback glyph - if (is_password) + if (is_password && !is_displaying_hint) { const ImFontGlyph* glyph = g.Font->FindGlyph('*'); ImFont* password_font = &g.InputTextPasswordFont; @@ -3729,14 +3740,14 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // without any carriage return, which would makes ImFont::RenderText() reserve too many vertices and probably crash. Avoid it altogether. // Note that we only use this limit on single-line InputText(), so a pathologically large line on a InputTextMultiline() would still crash. const int buf_display_max_length = 2 * 1024 * 1024; - const char* buf_display = NULL; - const char* buf_display_end = NULL; - ImGuiCol text_color = ImGuiCol_COUNT; // Render text. We currently only render selection when the widget is active or while scrolling. // FIXME: We could remove the '&& render_cursor' to keep rendering selection when inactive. if (render_cursor || render_selection) { + if (!is_displaying_hint) + buf_display_end = buf_display + state->CurLenA; + // Render text (with cursor and selection) // This is going to be messy. We need to: // - Display the text (this alone can be more easily clipped) @@ -3868,25 +3879,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ } } - if (state->CurLenA != 0 || hint == NULL) - { - buf_display = (!is_readonly && state->TextAIsValid) ? state->TextA.Data : buf; - buf_display_end = buf_display + state->CurLenA; - text_color = ImGuiCol_Text; - } - else - { - buf_display = hint; - buf_display_end = hint + strlen(hint); - text_color = ImGuiCol_TextDisabled; - } - - // We test for 'buf_display_max_length' as a way to avoid some pathological cases (e.g. single-line 1 MB string) which would make ImDrawList crash. if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length) { - IM_ASSERT(text_color != ImGuiCol_COUNT); - draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, GetColorU32(text_color), buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect); + ImU32 col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text); + draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, col, buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect); } // Draw blinking cursor @@ -3907,26 +3904,17 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ else { // Render text only (no selection, no cursor) - text_color = ImGuiCol_Text; - buf_display = (g.ActiveId == id && !is_readonly && state->TextAIsValid) ? state->TextA.Data : buf; if (is_multiline) text_size = ImVec2(size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_display_end) * g.FontSize); // We don't need width - else if (g.ActiveId == id) + else if (!is_displaying_hint && g.ActiveId == id) buf_display_end = buf_display + state->CurLenA; - else + else if (!is_displaying_hint) buf_display_end = buf_display + strlen(buf_display); - if (buf_display_end == buf_display && hint != NULL) - { - buf_display = hint; - buf_display_end = buf_display + strlen(buf_display); - text_color = ImGuiCol_TextDisabled; - } - if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length) { - IM_ASSERT(text_color != ImGuiCol_COUNT); - draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos, GetColorU32(text_color), buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect); + ImU32 col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text); + draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos, col, buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect); } } @@ -3937,11 +3925,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ EndGroup(); } - if (is_password) + if (is_password && !is_displaying_hint) PopFont(); // Log as text - if (g.LogEnabled && !is_password) + if (g.LogEnabled && !(is_password && !is_displaying_hint)) LogRenderedText(&draw_pos, buf_display, buf_display_end); if (label_size.x > 0) From 510342f02483f930c2f07e24e05ced024bbd6bef Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Mar 2019 18:00:04 +0100 Subject: [PATCH 4/6] Examples: DirectX9: Minor changes to match the other DirectX examples more closely. (#2394) --- docs/CHANGELOG.txt | 1 + examples/example_win32_directx10/main.cpp | 2 +- examples/example_win32_directx11/main.cpp | 2 +- examples/example_win32_directx9/main.cpp | 82 +++++++++++++---------- 4 files changed, 51 insertions(+), 36 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 1f928008..722ca610 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -84,6 +84,7 @@ Other Changes: - Examples: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN even if the OpenGL headers/loader happens to define the value. (#2366, #2186) - Examples: Allegro: Added support for touch events (emulating mouse). (#2219) [@dos1] +- Examples: DirectX9: Minor changes to match the other DirectX examples more closely. (#2394) ----------------------------------------------------------------------- diff --git a/examples/example_win32_directx10/main.cpp b/examples/example_win32_directx10/main.cpp index 344af239..7e3dd922 100644 --- a/examples/example_win32_directx10/main.cpp +++ b/examples/example_win32_directx10/main.cpp @@ -18,7 +18,7 @@ static ID3D10RenderTargetView* g_mainRenderTargetView = NULL; void CreateRenderTarget() { ID3D10Texture2D* pBackBuffer; - g_pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer); + g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_mainRenderTargetView); pBackBuffer->Release(); } diff --git a/examples/example_win32_directx11/main.cpp b/examples/example_win32_directx11/main.cpp index 7cfa0abc..a08c8cb4 100644 --- a/examples/example_win32_directx11/main.cpp +++ b/examples/example_win32_directx11/main.cpp @@ -18,7 +18,7 @@ static ID3D11RenderTargetView* g_mainRenderTargetView = NULL; void CreateRenderTarget() { ID3D11Texture2D* pBackBuffer; - g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); + g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_mainRenderTargetView); pBackBuffer->Release(); } diff --git a/examples/example_win32_directx9/main.cpp b/examples/example_win32_directx9/main.cpp index 11ef1bac..eee800e0 100644 --- a/examples/example_win32_directx9/main.cpp +++ b/examples/example_win32_directx9/main.cpp @@ -10,8 +10,44 @@ #include // Data +static LPDIRECT3D9 g_pD3D = NULL; static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; -static D3DPRESENT_PARAMETERS g_d3dpp; +static D3DPRESENT_PARAMETERS g_d3dpp = {}; + +HRESULT CreateDeviceD3D(HWND hWnd) +{ + if ((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) + return E_FAIL; + + // Create the D3DDevice + ZeroMemory(&g_d3dpp, sizeof(g_d3dpp)); + g_d3dpp.Windowed = TRUE; + g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; + g_d3dpp.EnableAutoDepthStencil = TRUE; + g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16; + g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // Present with vsync + //g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Present without vsync, maximum unthrottled framerate + if (g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice) < 0) + return E_FAIL; + + return S_OK; +} + +void CleanupDeviceD3D() +{ + if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } + if (g_pD3D) { g_pD3D->Release(); g_pD3D = NULL; } +} + +void ResetDevice() +{ + ImGui_ImplDX9_InvalidateDeviceObjects(); + HRESULT hr = g_pd3dDevice->Reset(&g_d3dpp); + if (hr == D3DERR_INVALIDCALL) + IM_ASSERT(0); + ImGui_ImplDX9_CreateDeviceObjects(); +} extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) @@ -24,13 +60,9 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_SIZE: if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED) { - ImGui_ImplDX9_InvalidateDeviceObjects(); - g_d3dpp.BackBufferWidth = LOWORD(lParam); + g_d3dpp.BackBufferWidth = LOWORD(lParam); g_d3dpp.BackBufferHeight = HIWORD(lParam); - HRESULT hr = g_pd3dDevice->Reset(&g_d3dpp); - if (hr == D3DERR_INVALIDCALL) - IM_ASSERT(0); - ImGui_ImplDX9_CreateDeviceObjects(); + ResetDevice(); } return 0; case WM_SYSCOMMAND: @@ -52,28 +84,16 @@ int main(int, char**) HWND hwnd = CreateWindow(wc.lpszClassName, _T("Dear ImGui DirectX9 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); // Initialize Direct3D - LPDIRECT3D9 pD3D; - if ((pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) + if (CreateDeviceD3D(hwnd) < 0) { + CleanupDeviceD3D(); UnregisterClass(wc.lpszClassName, wc.hInstance); - return 0; + return 1; } - ZeroMemory(&g_d3dpp, sizeof(g_d3dpp)); - g_d3dpp.Windowed = TRUE; - g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; - g_d3dpp.EnableAutoDepthStencil = TRUE; - g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16; - g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // Present with vsync - //g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Present without vsync, maximum unthrottled framerate - // Create the D3DDevice - if (pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice) < 0) - { - pD3D->Release(); - UnregisterClass(wc.lpszClassName, wc.hInstance); - return 0; - } + // Show the window + ShowWindow(hwnd, SW_SHOWDEFAULT); + UpdateWindow(hwnd); // Setup Dear ImGui context IMGUI_CHECKVERSION(); @@ -104,6 +124,7 @@ int main(int, char**) //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != NULL); + // Our state bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); @@ -111,8 +132,6 @@ int main(int, char**) // Main loop MSG msg; ZeroMemory(&msg, sizeof(msg)); - ShowWindow(hwnd, SW_SHOWDEFAULT); - UpdateWindow(hwnd); while (msg.message != WM_QUIT) { // Poll and handle messages (inputs, window resize, etc.) @@ -186,19 +205,14 @@ int main(int, char**) // Handle loss of D3D9 device if (result == D3DERR_DEVICELOST && g_pd3dDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET) - { - ImGui_ImplDX9_InvalidateDeviceObjects(); - g_pd3dDevice->Reset(&g_d3dpp); - ImGui_ImplDX9_CreateDeviceObjects(); - } + ResetDevice(); } ImGui_ImplDX9_Shutdown(); ImGui_ImplWin32_Shutdown(); ImGui::DestroyContext(); - if (g_pd3dDevice) g_pd3dDevice->Release(); - if (pD3D) pD3D->Release(); + CleanupDeviceD3D(); DestroyWindow(hwnd); UnregisterClass(wc.lpszClassName, wc.hInstance); From ea8158acdf943ed90f0d3f7c72bddae5ee30f005 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Mar 2019 18:19:28 +0100 Subject: [PATCH 5/6] Demo: Renamed ShowHelpMarker() -> HelpMarker(). Fixed minor PVS warning. Removed unnecessary casts. --- imgui_demo.cpp | 110 +++++++++++++++++++++++----------------------- imgui_widgets.cpp | 14 +++--- 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index f8f23c2f..13757b29 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -126,7 +126,7 @@ static void ShowExampleAppCustomRendering(bool* p_open); static void ShowExampleMenuFile(); // Helper to display a little (?) mark which shows a tooltip when hovered. -static void ShowHelpMarker(const char* desc) +static void HelpMarker(const char* desc) { ImGui::TextDisabled("(?)"); if (ImGui::IsItemHovered()) @@ -311,9 +311,9 @@ void ImGui::ShowDemoWindow(bool* p_open) { ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard); ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad); - ImGui::SameLine(); ShowHelpMarker("Required back-end to feed in gamepad inputs in io.NavInputs[] and set io.BackendFlags |= ImGuiBackendFlags_HasGamepad.\n\nRead instructions in imgui.cpp for details."); + ImGui::SameLine(); HelpMarker("Required back-end to feed in gamepad inputs in io.NavInputs[] and set io.BackendFlags |= ImGuiBackendFlags_HasGamepad.\n\nRead instructions in imgui.cpp for details."); ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos); - ImGui::SameLine(); ShowHelpMarker("Instruct navigation to move the mouse cursor. See comment for ImGuiConfigFlags_NavEnableSetMousePos."); + ImGui::SameLine(); HelpMarker("Instruct navigation to move the mouse cursor. See comment for ImGuiConfigFlags_NavEnableSetMousePos."); ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NoMouse); if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) // Create a way to restore this flag otherwise we could be stuck completely! { @@ -326,21 +326,21 @@ void ImGui::ShowDemoWindow(bool* p_open) io.ConfigFlags &= ~ImGuiConfigFlags_NoMouse; } ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange); - ImGui::SameLine(); ShowHelpMarker("Instruct back-end to not alter mouse cursor shape and visibility."); + ImGui::SameLine(); HelpMarker("Instruct back-end to not alter mouse cursor shape and visibility."); ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink); - ImGui::SameLine(); ShowHelpMarker("Set to false to disable blinking cursor, for users who consider it distracting"); + ImGui::SameLine(); HelpMarker("Set to false to disable blinking cursor, for users who consider it distracting"); ImGui::Checkbox("io.ConfigWindowsResizeFromEdges", &io.ConfigWindowsResizeFromEdges); - ImGui::SameLine(); ShowHelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback."); + ImGui::SameLine(); HelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback."); ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly); ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor); - ImGui::SameLine(); ShowHelpMarker("Instruct Dear ImGui to render a mouse cursor for you. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something)."); + ImGui::SameLine(); HelpMarker("Instruct Dear ImGui to render a mouse cursor for you. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something)."); ImGui::TreePop(); ImGui::Separator(); } if (ImGui::TreeNode("Backend Flags")) { - ShowHelpMarker("Those flags are set by the back-ends (imgui_impl_xxx files) to specify their capabilities."); + HelpMarker("Those flags are set by the back-ends (imgui_impl_xxx files) to specify their capabilities."); ImGuiBackendFlags backend_flags = io.BackendFlags; // Make a local copy to avoid modifying the back-end flags. ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", (unsigned int *)&backend_flags, ImGuiBackendFlags_HasGamepad); ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", (unsigned int *)&backend_flags, ImGuiBackendFlags_HasMouseCursors); @@ -359,7 +359,7 @@ void ImGui::ShowDemoWindow(bool* p_open) if (ImGui::TreeNode("Capture/Logging")) { ImGui::TextWrapped("The logging API redirects all text output so you can easily capture the content of a window or a block. Tree nodes can be automatically expanded."); - ShowHelpMarker("Try opening any of the contents below in this window and then click one of the \"Log To\" button."); + HelpMarker("Try opening any of the contents below in this window and then click one of the \"Log To\" button."); ImGui::LogButtons(); ImGui::TextWrapped("You can also call ImGui::LogText() to output directly to the log without a visual output."); if (ImGui::Button("Copy \"Hello, world!\" to clipboard")) @@ -476,20 +476,20 @@ static void ShowDemoWindowWidgets() const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" }; static int item_current = 0; ImGui::Combo("combo", &item_current, items, IM_ARRAYSIZE(items)); - ImGui::SameLine(); ShowHelpMarker("Refer to the \"Combo\" section below for an explanation of the full BeginCombo/EndCombo API, and demonstration of various flags.\n"); + ImGui::SameLine(); HelpMarker("Refer to the \"Combo\" section below for an explanation of the full BeginCombo/EndCombo API, and demonstration of various flags.\n"); } { static char str0[128] = "Hello, world!"; ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0)); - ImGui::SameLine(); ShowHelpMarker("USER:\nHold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n\nPROGRAMMER:\nYou can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputText() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example (this is not demonstrated in imgui_demo.cpp)."); + ImGui::SameLine(); HelpMarker("USER:\nHold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n\nPROGRAMMER:\nYou can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputText() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example (this is not demonstrated in imgui_demo.cpp)."); static char str1[128] = ""; ImGui::InputTextWithHint("input text (w/ hint)", "enter text here", str1, IM_ARRAYSIZE(str1)); static int i0 = 123; ImGui::InputInt("input int", &i0); - ImGui::SameLine(); ShowHelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n"); + ImGui::SameLine(); HelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n"); static float f0 = 0.001f; ImGui::InputFloat("input float", &f0, 0.01f, 1.0f, "%.3f"); @@ -499,7 +499,7 @@ static void ShowDemoWindowWidgets() static float f1 = 1.e10f; ImGui::InputFloat("input scientific", &f1, 0.0f, 0.0f, "%e"); - ImGui::SameLine(); ShowHelpMarker("You can input value using the scientific notation,\n e.g. \"1e+8\" becomes \"100000000\".\n"); + ImGui::SameLine(); HelpMarker("You can input value using the scientific notation,\n e.g. \"1e+8\" becomes \"100000000\".\n"); static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; ImGui::InputFloat3("input float3", vec4a); @@ -508,7 +508,7 @@ static void ShowDemoWindowWidgets() { static int i1 = 50, i2 = 42; ImGui::DragInt("drag int", &i1, 1); - ImGui::SameLine(); ShowHelpMarker("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input value."); + ImGui::SameLine(); HelpMarker("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input value."); ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%d%%"); @@ -520,7 +520,7 @@ static void ShowDemoWindowWidgets() { static int i1=0; ImGui::SliderInt("slider int", &i1, -1, 3); - ImGui::SameLine(); ShowHelpMarker("CTRL+click to input value."); + ImGui::SameLine(); HelpMarker("CTRL+click to input value."); static float f1=0.123f, f2=0.0f; ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f"); @@ -533,7 +533,7 @@ static void ShowDemoWindowWidgets() static float col1[3] = { 1.0f,0.0f,0.2f }; static float col2[4] = { 0.4f,0.7f,0.0f,0.5f }; ImGui::ColorEdit3("color 1", col1); - ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nClick and hold to use drag and drop.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); + ImGui::SameLine(); HelpMarker("Click on the colored square to open a color picker.\nClick and hold to use drag and drop.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); ImGui::ColorEdit4("color 2", col2); } @@ -576,7 +576,7 @@ static void ShowDemoWindowWidgets() if (ImGui::TreeNode("Advanced, with Selectable nodes")) { - ShowHelpMarker("This is a more standard looking tree with selectable nodes.\nClick to select, CTRL+Click to toggle, click on arrows or double-click to open."); + HelpMarker("This is a more standard looking tree with selectable nodes.\nClick to select, CTRL+Click to toggle, click on arrows or double-click to open."); static bool align_label_with_current_x_position = false; ImGui::Checkbox("Align label with current X position)", &align_label_with_current_x_position); ImGui::Text("Hello!"); @@ -663,7 +663,7 @@ static void ShowDemoWindowWidgets() ImGui::TextColored(ImVec4(1.0f,0.0f,1.0f,1.0f), "Pink"); ImGui::TextColored(ImVec4(1.0f,1.0f,0.0f,1.0f), "Yellow"); ImGui::TextDisabled("Disabled"); - ImGui::SameLine(); ShowHelpMarker("The TextDisabled color is stored in ImGuiStyle."); + ImGui::SameLine(); HelpMarker("The TextDisabled color is stored in ImGuiStyle."); ImGui::TreePop(); } @@ -770,7 +770,7 @@ static void ShowDemoWindowWidgets() // Expose flags as checkbox for the demo static ImGuiComboFlags flags = 0; ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", (unsigned int*)&flags, ImGuiComboFlags_PopupAlignLeft); - ImGui::SameLine(); ShowHelpMarker("Only makes a difference if the popup is larger than the combo"); + ImGui::SameLine(); HelpMarker("Only makes a difference if the popup is larger than the combo"); if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", (unsigned int*)&flags, ImGuiComboFlags_NoArrowButton)) flags &= ~ImGuiComboFlags_NoPreview; // Clear the other flag, as we cannot combine both if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", (unsigned int*)&flags, ImGuiComboFlags_NoPreview)) @@ -841,7 +841,7 @@ static void ShowDemoWindowWidgets() } if (ImGui::TreeNode("Selection State: Multiple Selection")) { - ShowHelpMarker("Hold CTRL and click to select multiple items."); + HelpMarker("Hold CTRL and click to select multiple items."); static bool selection[5] = { false, false, false, false, false }; for (int n = 0; n < 5; n++) { @@ -901,7 +901,7 @@ static void ShowDemoWindowWidgets() } if (ImGui::TreeNode("Alignment")) { - ShowHelpMarker("Alignment applies when a selectable is larger than its text content.\nBy default, Selectables uses style.SelectableTextAlign but it can be overriden on a per-item basis using PushStyleVar()."); + HelpMarker("Alignment applies when a selectable is larger than its text content.\nBy default, Selectables uses style.SelectableTextAlign but it can be overriden on a per-item basis using PushStyleVar()."); static bool selected[3*3] = { true, false, true, false, true, false, true, false, true }; for (int y = 0; y < 3; y++) { @@ -934,7 +934,7 @@ static void ShowDemoWindowWidgets() ImGui::Text("Password input"); static char bufpass[64] = "password123"; ImGui::InputText("password", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); - ImGui::SameLine(); ShowHelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); + ImGui::SameLine(); HelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); ImGui::InputTextWithHint("password (w/ hint)", "", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); ImGui::InputText("password (clear)", bufpass, 64, ImGuiInputTextFlags_CharsNoBlank); @@ -958,7 +958,7 @@ static void ShowDemoWindowWidgets() "\tlock cmpxchg8b eax\n"; static ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput; - ShowHelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp)"); + HelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp)"); ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", (unsigned int*)&flags, ImGuiInputTextFlags_ReadOnly); ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", (unsigned int*)&flags, ImGuiInputTextFlags_AllowTabInput); ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", (unsigned int*)&flags, ImGuiInputTextFlags_CtrlEnterForNewLine); @@ -1042,12 +1042,12 @@ static void ShowDemoWindowWidgets() ImGui::Checkbox("With Alpha Preview", &alpha_preview); ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview); ImGui::Checkbox("With Drag and Drop", &drag_and_drop); - ImGui::Checkbox("With Options Menu", &options_menu); ImGui::SameLine(); ShowHelpMarker("Right-click on the individual color widget to show options."); - ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); ShowHelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets."); + ImGui::Checkbox("With Options Menu", &options_menu); ImGui::SameLine(); HelpMarker("Right-click on the individual color widget to show options."); + ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); HelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets."); int misc_flags = (hdr ? ImGuiColorEditFlags_HDR : 0) | (drag_and_drop ? 0 : ImGuiColorEditFlags_NoDragDrop) | (alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0)) | (options_menu ? 0 : ImGuiColorEditFlags_NoOptions); ImGui::Text("Color widget:"); - ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nCTRL+click on individual component to input value.\n"); + ImGui::SameLine(); HelpMarker("Click on the colored square to open a color picker.\nCTRL+click on individual component to input value.\n"); ImGui::ColorEdit3("MyColor##1", (float*)&color, misc_flags); ImGui::Text("Color widget HSV with Alpha:"); @@ -1057,7 +1057,7 @@ static void ShowDemoWindowWidgets() ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | misc_flags); ImGui::Text("Color button with Picker:"); - ImGui::SameLine(); ShowHelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup."); + ImGui::SameLine(); HelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup."); ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | misc_flags); ImGui::Text("Color button with Custom Picker Popup:"); @@ -1149,9 +1149,9 @@ static void ShowDemoWindowWidgets() } } ImGui::Combo("Display Mode", &display_mode, "Auto/Current\0None\0RGB Only\0HSV Only\0Hex Only\0"); - ImGui::SameLine(); ShowHelpMarker("ColorEdit defaults to displaying RGB inputs if you don't specify a display mode, but the user can change it with a right-click.\n\nColorPicker defaults to displaying RGB+HSV+Hex if you don't specify a display mode.\n\nYou can change the defaults using SetColorEditOptions()."); + ImGui::SameLine(); HelpMarker("ColorEdit defaults to displaying RGB inputs if you don't specify a display mode, but the user can change it with a right-click.\n\nColorPicker defaults to displaying RGB+HSV+Hex if you don't specify a display mode.\n\nYou can change the defaults using SetColorEditOptions()."); ImGui::Combo("Picker Mode", &picker_mode, "Auto/Current\0Hue bar + SV rect\0Hue wheel + SV triangle\0"); - ImGui::SameLine(); ShowHelpMarker("User can right-click the picker to change mode."); + ImGui::SameLine(); HelpMarker("User can right-click the picker to change mode."); ImGuiColorEditFlags flags = misc_flags; if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4() if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar; @@ -1165,7 +1165,7 @@ static void ShowDemoWindowWidgets() ImGui::ColorPicker4("MyColor##4", (float*)&color, flags, ref_color ? &ref_color_v.x : NULL); ImGui::Text("Programmatically set defaults:"); - ImGui::SameLine(); ShowHelpMarker("SetColorEditOptions() is designed to allow you to set boot-time default.\nWe don't have Push/Pop functions because you can force options on a per-widget basis if needed, and the user can change non-forced ones with the options menu.\nWe don't have a getter to avoid encouraging you to persistently save values that aren't forward-compatible."); + ImGui::SameLine(); HelpMarker("SetColorEditOptions() is designed to allow you to set boot-time default.\nWe don't have Push/Pop functions because you can force options on a per-widget basis if needed, and the user can change non-forced ones with the options menu.\nWe don't have a getter to avoid encouraging you to persistently save values that aren't forward-compatible."); if (ImGui::Button("Default: Uint8 + HSV + Hue Bar")) ImGui::SetColorEditOptions(ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_PickerHueBar); if (ImGui::Button("Default: Float + HDR + Hue Wheel")) @@ -1230,7 +1230,7 @@ static void ShowDemoWindowWidgets() const float drag_speed = 0.2f; static bool drag_clamp = false; ImGui::Text("Drags:"); - ImGui::Checkbox("Clamp integers to 0..50", &drag_clamp); ImGui::SameLine(); ShowHelpMarker("As with every widgets in dear imgui, we never modify values unless there is a user interaction.\nYou can override the clamping limits by using CTRL+Click to input a value."); + ImGui::Checkbox("Clamp integers to 0..50", &drag_clamp); ImGui::SameLine(); HelpMarker("As with every widgets in dear imgui, we never modify values unless there is a user interaction.\nYou can override the clamping limits by using CTRL+Click to input a value."); ImGui::DragScalar("drag s8", ImGuiDataType_S8, &s8_v, drag_speed, drag_clamp ? &s8_zero : NULL, drag_clamp ? &s8_fifty : NULL); ImGui::DragScalar("drag u8", ImGuiDataType_U8, &u8_v, drag_speed, drag_clamp ? &u8_zero : NULL, drag_clamp ? &u8_fifty : NULL, "%u ms"); ImGui::DragScalar("drag s16", ImGuiDataType_S16, &s16_v, drag_speed, drag_clamp ? &s16_zero : NULL, drag_clamp ? &s16_fifty : NULL); @@ -1240,7 +1240,7 @@ static void ShowDemoWindowWidgets() ImGui::DragScalar("drag s64", ImGuiDataType_S64, &s64_v, drag_speed, drag_clamp ? &s64_zero : NULL, drag_clamp ? &s64_fifty : NULL); ImGui::DragScalar("drag u64", ImGuiDataType_U64, &u64_v, drag_speed, drag_clamp ? &u64_zero : NULL, drag_clamp ? &u64_fifty : NULL); ImGui::DragScalar("drag float", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f", 1.0f); - ImGui::DragScalar("drag float ^2", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f", 2.0f); ImGui::SameLine(); ShowHelpMarker("You can use the 'power' parameter to increase tweaking precision on one side of the range."); + ImGui::DragScalar("drag float ^2", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f", 2.0f); ImGui::SameLine(); HelpMarker("You can use the 'power' parameter to increase tweaking precision on one side of the range."); ImGui::DragScalar("drag double", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, NULL, "%.10f grams", 1.0f); ImGui::DragScalar("drag double ^2", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, &f64_one, "0 < %.10f < 1", 2.0f); @@ -1589,7 +1589,7 @@ static void ShowDemoWindowLayout() if (ImGui::TreeNode("Child windows")) { - ShowHelpMarker("Use child windows to begin into a self-contained independent scrolling/clipping regions within a host window."); + HelpMarker("Use child windows to begin into a self-contained independent scrolling/clipping regions within a host window."); static bool disable_mouse_wheel = false; static bool disable_menu = false; ImGui::Checkbox("Disable Mouse Wheel", &disable_mouse_wheel); @@ -1673,31 +1673,31 @@ static void ShowDemoWindowLayout() { static float f = 0.0f; ImGui::Text("PushItemWidth(100)"); - ImGui::SameLine(); ShowHelpMarker("Fixed width."); + ImGui::SameLine(); HelpMarker("Fixed width."); ImGui::PushItemWidth(100); ImGui::DragFloat("float##1", &f); ImGui::PopItemWidth(); ImGui::Text("PushItemWidth(GetWindowWidth() * 0.5f)"); - ImGui::SameLine(); ShowHelpMarker("Half of window width."); + ImGui::SameLine(); HelpMarker("Half of window width."); ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f); ImGui::DragFloat("float##2", &f); ImGui::PopItemWidth(); ImGui::Text("PushItemWidth(GetContentRegionAvailWidth() * 0.5f)"); - ImGui::SameLine(); ShowHelpMarker("Half of available width.\n(~ right-cursor_pos)\n(works within a column set)"); + ImGui::SameLine(); HelpMarker("Half of available width.\n(~ right-cursor_pos)\n(works within a column set)"); ImGui::PushItemWidth(ImGui::GetContentRegionAvailWidth() * 0.5f); ImGui::DragFloat("float##3", &f); ImGui::PopItemWidth(); ImGui::Text("PushItemWidth(-100)"); - ImGui::SameLine(); ShowHelpMarker("Align to right edge minus 100"); + ImGui::SameLine(); HelpMarker("Align to right edge minus 100"); ImGui::PushItemWidth(-100); ImGui::DragFloat("float##4", &f); ImGui::PopItemWidth(); ImGui::Text("PushItemWidth(-1)"); - ImGui::SameLine(); ShowHelpMarker("Align to right edge"); + ImGui::SameLine(); HelpMarker("Align to right edge"); ImGui::PushItemWidth(-1); ImGui::DragFloat("float##5", &f); ImGui::PopItemWidth(); @@ -1866,7 +1866,7 @@ static void ShowDemoWindowLayout() if (ImGui::TreeNode("Groups")) { - ShowHelpMarker("Using ImGui::BeginGroup()/EndGroup() to layout items. BeginGroup() basically locks the horizontal position. EndGroup() bundles the whole group so that you can use functions such as IsItemHovered() on it."); + HelpMarker("Using ImGui::BeginGroup()/EndGroup() to layout items. BeginGroup() basically locks the horizontal position. EndGroup() bundles the whole group so that you can use functions such as IsItemHovered() on it."); ImGui::BeginGroup(); { ImGui::BeginGroup(); @@ -1910,7 +1910,7 @@ static void ShowDemoWindowLayout() if (ImGui::TreeNode("Text Baseline Alignment")) { - ShowHelpMarker("This is testing the vertical alignment that gets applied on text to keep it aligned with widgets. Lines only composed of text or \"small\" widgets fit in less vertical spaces than lines with normal widgets."); + HelpMarker("This is testing the vertical alignment that gets applied on text to keep it aligned with widgets. Lines only composed of text or \"small\" widgets fit in less vertical spaces than lines with normal widgets."); ImGui::Text("One\nTwo\nThree"); ImGui::SameLine(); ImGui::Text("Hello\nWorld"); ImGui::SameLine(); @@ -1965,7 +1965,7 @@ static void ShowDemoWindowLayout() if (ImGui::TreeNode("Scrolling")) { - ShowHelpMarker("Use SetScrollHereY() or SetScrollFromPosY() to scroll to a given position."); + HelpMarker("Use SetScrollHereY() or SetScrollFromPosY() to scroll to a given position."); static bool track = true; static int track_line = 50, scroll_to_px = 200; @@ -2007,7 +2007,7 @@ static void ShowDemoWindowLayout() if (ImGui::TreeNode("Horizontal Scrolling")) { - ShowHelpMarker("Horizontal scrolling for a window has to be enabled explicitly via the ImGuiWindowFlags_HorizontalScrollbar flag.\n\nYou may want to explicitly specify content width by calling SetNextWindowContentWidth() before Begin()."); + HelpMarker("Horizontal scrolling for a window has to be enabled explicitly via the ImGuiWindowFlags_HorizontalScrollbar flag.\n\nYou may want to explicitly specify content width by calling SetNextWindowContentWidth() before Begin()."); static int lines = 7; ImGui::SliderInt("Lines", &lines, 1, 15); ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); @@ -2460,7 +2460,7 @@ static void ShowDemoWindowColumns() } bool node_open = ImGui::TreeNode("Tree within single cell"); - ImGui::SameLine(); ShowHelpMarker("NB: Tree node must be poped before ending the cell. There's no storage of state per-cell."); + ImGui::SameLine(); HelpMarker("NB: Tree node must be poped before ending the cell. There's no storage of state per-cell."); if (node_open) { ImGui::Columns(2, "tree items"); @@ -2543,7 +2543,7 @@ static void ShowDemoWindowMisc() ImGui::InputText("3", buf, IM_ARRAYSIZE(buf)); ImGui::PushAllowKeyboardFocus(false); ImGui::InputText("4 (tab skip)", buf, IM_ARRAYSIZE(buf)); - //ImGui::SameLine(); ShowHelperMarker("Use ImGui::PushAllowKeyboardFocus(bool)\nto disable tabbing through certain widgets."); + //ImGui::SameLine(); HelpMarker("Use ImGui::PushAllowKeyboardFocus(bool)\nto disable tabbing through certain widgets."); ImGui::PopAllowKeyboardFocus(); ImGui::InputText("5", buf, IM_ARRAYSIZE(buf)); ImGui::TreePop(); @@ -2621,7 +2621,7 @@ static void ShowDemoWindowMisc() ImGui::Text("Current mouse cursor = %d: %s", ImGui::GetMouseCursor(), mouse_cursors_names[ImGui::GetMouseCursor()]); ImGui::Text("Hover to see mouse cursors:"); - ImGui::SameLine(); ShowHelpMarker("Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, otherwise your backend needs to handle it."); + ImGui::SameLine(); HelpMarker("Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, otherwise your backend needs to handle it."); for (int i = 0; i < ImGuiMouseCursor_COUNT; i++) { char label[32]; @@ -2799,7 +2799,7 @@ void ImGui::ShowFontSelector(const char* label) ImGui::EndCombo(); } ImGui::SameLine(); - ShowHelpMarker( + HelpMarker( "- Load additional fonts with io.Fonts->AddFontFromFileTTF().\n" "- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\n" "- Read FAQ and documentation in misc/fonts/ for more details.\n" @@ -2842,7 +2842,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) if (ImGui::Button("Revert Ref")) style = *ref; ImGui::SameLine(); - ShowHelpMarker("Save/Revert in local non-persistent storage. Default Colors definition are not affected. Use \"Export Colors\" below to save them somewhere."); + HelpMarker("Save/Revert in local non-persistent storage. Default Colors definition are not affected. Use \"Export Colors\" below to save them somewhere."); ImGui::Separator(); @@ -2875,9 +2875,9 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f, "%.0f"); ImGui::Text("Alignment"); ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f"); - ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); ShowHelpMarker("Alignment applies when a button is larger than its text content."); - ImGui::SliderFloat2("SelectableTextAlign", (float*)&style.SelectableTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); ShowHelpMarker("Alignment applies when a selectable is larger than its text content."); - ImGui::Text("Safe Area Padding"); ImGui::SameLine(); ShowHelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured)."); + ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); HelpMarker("Alignment applies when a button is larger than its text content."); + ImGui::SliderFloat2("SelectableTextAlign", (float*)&style.SelectableTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); HelpMarker("Alignment applies when a selectable is larger than its text content."); + ImGui::Text("Safe Area Padding"); ImGui::SameLine(); HelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured)."); ImGui::SliderFloat2("DisplaySafeAreaPadding", (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f"); ImGui::EndTabItem(); } @@ -2912,7 +2912,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::RadioButton("Opaque", &alpha_flags, 0); ImGui::SameLine(); ImGui::RadioButton("Alpha", &alpha_flags, ImGuiColorEditFlags_AlphaPreview); ImGui::SameLine(); ImGui::RadioButton("Both", &alpha_flags, ImGuiColorEditFlags_AlphaPreviewHalf); ImGui::SameLine(); - ShowHelpMarker("In the color list:\nLeft-click on colored square to open color picker,\nRight-click to open edit options menu."); + HelpMarker("In the color list:\nLeft-click on colored square to open color picker,\nRight-click to open edit options menu."); ImGui::BeginChild("##colors", ImVec2(0, 0), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NavFlattened); ImGui::PushItemWidth(-160); @@ -2944,7 +2944,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) { ImGuiIO& io = ImGui::GetIO(); ImFontAtlas* atlas = io.Fonts; - ShowHelpMarker("Read FAQ and misc/fonts/README.txt for details on font loading."); + HelpMarker("Read FAQ and misc/fonts/README.txt for details on font loading."); ImGui::PushItemWidth(120); for (int i = 0; i < atlas->Fonts.Size; i++) { @@ -2958,7 +2958,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::Text("The quick brown fox jumps over the lazy dog"); ImGui::PopFont(); ImGui::DragFloat("Font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f"); // Scale only this font - ImGui::SameLine(); ShowHelpMarker("Note than the default embedded font is NOT meant to be scaled.\n\nFont are currently rendered into bitmaps at a given size at the time of building the atlas. You may oversample them to get some flexibility with scaling. You can also render at multiple sizes and select which one to use at runtime.\n\n(Glimmer of hope: the atlas system should hopefully be rewritten in the future to make scaling more natural and automatic.)"); + ImGui::SameLine(); HelpMarker("Note than the default embedded font is NOT meant to be scaled.\n\nFont are currently rendered into bitmaps at a given size at the time of building the atlas. You may oversample them to get some flexibility with scaling. You can also render at multiple sizes and select which one to use at runtime.\n\n(Glimmer of hope: the atlas system should hopefully be rewritten in the future to make scaling more natural and automatic.)"); ImGui::InputFloat("Font offset", &font->DisplayOffset.y, 1, 1, "%.0f"); ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent); ImGui::Text("Fallback character: '%c' (%d)", font->FallbackChar, font->FallbackChar); @@ -3027,7 +3027,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) if (ImGui::BeginTabItem("Rendering")) { - ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); ImGui::SameLine(); ShowHelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well."); + ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); ImGui::SameLine(); HelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well."); ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill); ImGui::PushItemWidth(100); ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, FLT_MAX, "%.2f", 2.0f); @@ -3701,7 +3701,7 @@ static void ShowExampleAppPropertyEditor(bool* p_open) return; } - ShowHelpMarker("This example shows how you may implement a property editor using two columns.\nAll objects/fields data are dummies here.\nRemember that in many simple cases, you can use ImGui::SameLine(xxx) to position\nyour cursor horizontally instead of using the Columns() API."); + HelpMarker("This example shows how you may implement a property editor using two columns.\nAll objects/fields data are dummies here.\nRemember that in many simple cases, you can use ImGui::SameLine(xxx) to position\nyour cursor horizontally instead of using the Columns() API."); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2,2)); ImGui::Columns(2); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index bb514efc..0e63a14d 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1155,7 +1155,7 @@ void ImGui::Separator() // Those flags should eventually be overridable by the user ImGuiSeparatorFlags flags = (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal; - IM_ASSERT(ImIsPowerOfTwo((int)(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical)))); // Check that only 1 option is selected + IM_ASSERT(ImIsPowerOfTwo(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical))); // Check that only 1 option is selected if (flags & ImGuiSeparatorFlags_Vertical) { VerticalSeparator(); @@ -3366,7 +3366,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ bool enter_pressed = false; // Select the buffer to render. - const char* buf_display = ((render_cursor || render_selection || g.ActiveId == id) && !is_readonly && state->TextAIsValid) ? state->TextA.Data : buf; + const char* buf_display = ((render_cursor || render_selection || g.ActiveId == id) && !is_readonly && state && state->TextAIsValid) ? state->TextA.Data : buf; const char* buf_display_end = NULL; // We have specialized paths below for setting the length const bool is_displaying_hint = (hint != NULL && buf_display[0] == 0); if (is_displaying_hint) @@ -3745,6 +3745,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // FIXME: We could remove the '&& render_cursor' to keep rendering selection when inactive. if (render_cursor || render_selection) { + IM_ASSERT(state != NULL); if (!is_displaying_hint) buf_display_end = buf_display + state->CurLenA; @@ -3755,7 +3756,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // - Measure text height (for scrollbar) // We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort) // FIXME: This should occur on buf_display but we'd need to maintain cursor/select_start/select_end for UTF-8. - IM_ASSERT(state != NULL); const ImWchar* text_begin = state->TextW.Data; ImVec2 cursor_offset, select_start_offset; @@ -4266,7 +4266,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl // Read stored options if (!(flags & ImGuiColorEditFlags__PickerMask)) flags |= ((g.ColorEditOptions & ImGuiColorEditFlags__PickerMask) ? g.ColorEditOptions : ImGuiColorEditFlags__OptionsDefault) & ImGuiColorEditFlags__PickerMask; - IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__PickerMask))); // Check that only 1 is selected + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags__PickerMask)); // Check that only 1 is selected if (!(flags & ImGuiColorEditFlags_NoOptions)) flags |= (g.ColorEditOptions & ImGuiColorEditFlags_AlphaBar); @@ -4637,9 +4637,9 @@ void ImGui::SetColorEditOptions(ImGuiColorEditFlags flags) flags |= ImGuiColorEditFlags__OptionsDefault & ImGuiColorEditFlags__DataTypeMask; if ((flags & ImGuiColorEditFlags__PickerMask) == 0) flags |= ImGuiColorEditFlags__OptionsDefault & ImGuiColorEditFlags__PickerMask; - IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__DisplayMask))); // Check only 1 option is selected - IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__DataTypeMask))); // Check only 1 option is selected - IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__PickerMask))); // Check only 1 option is selected + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags__DisplayMask)); // Check only 1 option is selected + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags__DataTypeMask)); // Check only 1 option is selected + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiColorEditFlags__PickerMask)); // Check only 1 option is selected g.ColorEditOptions = flags; } From 8464df1f6e0e7349e2fc4db797bbc552358b9078 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 6 Mar 2019 19:12:53 +0100 Subject: [PATCH 6/6] Internals: ColorEdit: Minor optimizations. Initialize internal arrays as static const, avoid unnecessary HSV->RGB conversion. --- imgui_widgets.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 0e63a14d..965cef97 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -4022,14 +4022,14 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag const float w_item_last = ImMax(1.0f, (float)(int)(w_items_all - (w_item_one + style.ItemInnerSpacing.x) * (components-1))); const bool hide_prefix = (w_item_one <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x); - const char* ids[4] = { "##X", "##Y", "##Z", "##W" }; - const char* fmt_table_int[3][4] = + static const char* ids[4] = { "##X", "##Y", "##Z", "##W" }; + static const char* fmt_table_int[3][4] = { { "%3d", "%3d", "%3d", "%3d" }, // Short display { "R:%3d", "G:%3d", "B:%3d", "A:%3d" }, // Long display for RGBA { "H:%3d", "S:%3d", "V:%3d", "A:%3d" } // Long display for HSVA }; - const char* fmt_table_float[3][4] = + static const char* fmt_table_float[3][4] = { { "%0.3f", "%0.3f", "%0.3f", "%0.3f" }, // Short display { "R:%0.3f", "G:%0.3f", "B:%0.3f", "A:%0.3f" }, // Long display for RGBA @@ -4129,21 +4129,19 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag } // Convert back - if (picker_active_window == NULL) + if (value_changed && picker_active_window == NULL) { if (!value_changed_as_float) for (int n = 0; n < 4; n++) f[n] = i[n] / 255.0f; if (flags & ImGuiColorEditFlags_DisplayHSV) ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]); - if (value_changed) - { - col[0] = f[0]; - col[1] = f[1]; - col[2] = f[2]; - if (alpha) - col[3] = f[3]; - } + + col[0] = f[0]; + col[1] = f[1]; + col[2] = f[2]; + if (alpha) + col[3] = f[3]; } PopID(); @@ -4395,12 +4393,14 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl ImVec4 col_v4(col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); if ((flags & ImGuiColorEditFlags_NoLabel)) Text("Current"); - ColorButton("##current", col_v4, (flags & (ImGuiColorEditFlags_HDR|ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf|ImGuiColorEditFlags_NoTooltip)), ImVec2(square_sz * 3, square_sz * 2)); + + ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_HDR|ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf|ImGuiColorEditFlags_NoTooltip; + ColorButton("##current", col_v4, (flags & sub_flags_to_forward), ImVec2(square_sz * 3, square_sz * 2)); if (ref_col != NULL) { Text("Original"); ImVec4 ref_col_v4(ref_col[0], ref_col[1], ref_col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : ref_col[3]); - if (ColorButton("##original", ref_col_v4, (flags & (ImGuiColorEditFlags_HDR|ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf|ImGuiColorEditFlags_NoTooltip)), ImVec2(square_sz * 3, square_sz * 2))) + if (ColorButton("##original", ref_col_v4, (flags & sub_flags_to_forward), ImVec2(square_sz * 3, square_sz * 2))) { memcpy(col, ref_col, components * sizeof(float)); value_changed = true;