diff --git a/3rdparty/ocornut-imgui/imgui.cpp b/3rdparty/ocornut-imgui/imgui.cpp index 2cfcdfd3..5993e3db 100644 --- a/3rdparty/ocornut-imgui/imgui.cpp +++ b/3rdparty/ocornut-imgui/imgui.cpp @@ -19,7 +19,7 @@ - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS - How can I help? - How do I update to a newer version of ImGui? - - Can I have multiple widgets with the same label? Can I have widget without a label? (Yes) + - Can I have multiple widgets with the same label? Can I have widget without a label? (Yes) / A primer on the use of labels/IDs in ImGui. - I integrated ImGui in my engine and the text or lines are blurry.. - I integrated ImGui in my engine and some elements are disappearing when I move windows around.. - How can I load a different font than the default? @@ -149,6 +149,7 @@ 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. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2016/03/02 (1.48) - InputText() completion/history/always callbacks: if you modify the text buffer manually (without using DeleteChars()/InsertChars() helper) you need to maintain the BufTextLen field. added an assert. - 2016/01/23 (1.48) - fixed not honoring exact width passed to PushItemWidth(), previously it would add extra FramePadding.x*2 over that width. if you had manual pixel-perfect alignment in place it might affect you. - 2015/12/27 (1.48) - fixed ImDrawList::AddRect() which used to render a rectangle 1 px too large on each axis. - 2015/12/04 (1.47) - renamed Color() helpers to ValueColor() - dangerously named, rarely used and probably to be made obsolete. @@ -425,6 +426,7 @@ - window: detect extra End() call that pop the "Debug" window out and assert at call site instead of later. - window: consider renaming "GetWindowFont" which conflict with old Windows #define (#340) - window/tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic. + - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. - draw-list: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). !- scrolling: allow immediately effective change of scroll if we haven't appended items yet - splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) @@ -436,6 +438,7 @@ - main: IsItemHovered() make it more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes - main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode? - input text: add ImGuiInputTextFlags_EnterToApply? (off #218) + - input text: reorganize event handling, allow CharFilter to modify buffers, allow multiple events? (#541) - input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc). - input text multi-line: way to dynamically grow the buffer without forcing the user to initially allocate for worse case (follow up on #200) - input text multi-line: line numbers? status bar? (follow up on #200) @@ -443,6 +446,7 @@ - input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled) - input number: use mouse wheel to step up/down - input number: applying arithmetics ops (+,-,*,/) messes up with text edit undo stack. + - button: provide a button that looks framed. - text: proper alignment options - image/image button: misalignment on padded/bordered button? - image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that? @@ -450,6 +454,7 @@ - layout: horizontal flow until no space left (#404) - layout: more generic alignment state (left/right/centered) for single items? - layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding. + - layout: BeginGroup() needs a border option. - columns: declare column set (each column: fixed size, %, fill, distribute default size among fills) (#513, #125) - columns: add a conditional parameter to SetColumnOffset() (#513, #125) - columns: separator function or parameter that works within the column (currently Separator() bypass all columns) (#125) @@ -467,9 +472,11 @@ !- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402) - popups: add variant using global identifier similar to Begin/End (#402) - popups: border options. richer api like BeginChild() perhaps? (#197) + - tooltip: tooltip that doesn't fit in entire screen seems to lose their "last prefered button" and may teleport when moving mouse - menus: local shortcuts, global shortcuts (#456, #126) - menus: icons - menus: menubars: some sort of priority / effect of main menu-bar on desktop size? + - menus: calling BeginMenu() twice with a same name doesn't seem to append nicely - statusbar: add a per-window status bar helper similar to what menubar does. - tabs (#261, #351) - separator: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y) @@ -493,6 +500,7 @@ - text edit: flag to disable live update of the user buffer. - text edit: field resize behavior - field could stretch when being edited? hover tooltip shows more text? - tree node / optimization: avoid formatting when clipped. + - tree node: clarify spacing, perhaps provide API to query exact spacing. provide API to draw the primitive. same with Bullet(). - tree node: tree-node/header right-most side doesn't take account of horizontal scrolling. - tree node: add treenode/treepush int variants? because (void*) cast from int warns on some platforms/settings - tree node / selectable render mismatch which is visible if you use them both next to each other (e.g. cf. property viewer) @@ -523,6 +531,7 @@ - input: support track pad style scrolling & slider edit. - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL) - misc: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? + - misc: provide HoveredTime and ActivatedTime to ease the creation of animations. - style editor: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438) - style editor: color child window height expressed in multiple of line height. - remote: make a system like RemoteImGui first-class citizen/project (#75) @@ -1990,7 +1999,7 @@ void ImGui::NewFrame() } // Are we using inputs? Tell user so they can capture/discard the inputs away from the rest of their application. - // When clicking outside of a window we assume the click is owned by the application and won't request capture. + // When clicking outside of a window we assume the click is owned by the application and won't request capture. We need to track click ownership. int mouse_earliest_button_down = -1; bool mouse_any_down = false; for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) @@ -2002,16 +2011,19 @@ void ImGui::NewFrame() if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[mouse_earliest_button_down] > g.IO.MouseClickedTime[i]) mouse_earliest_button_down = i; } - bool mouse_owned_by_application = mouse_earliest_button_down != -1 && !g.IO.MouseDownOwned[mouse_earliest_button_down]; - g.IO.WantCaptureMouse = (!mouse_owned_by_application && g.HoveredWindow != NULL) || (!mouse_owned_by_application && mouse_any_down) || (g.ActiveId != 0) || (!g.OpenedPopupStack.empty()) || (g.CaptureMouseNextFrame); - g.IO.WantCaptureKeyboard = (g.ActiveId != 0) || (g.CaptureKeyboardNextFrame); + bool mouse_avail_to_imgui = (mouse_earliest_button_down == -1) || g.IO.MouseDownOwned[mouse_earliest_button_down]; + if (g.CaptureMouseNextFrame != -1) + g.IO.WantCaptureMouse = (g.CaptureMouseNextFrame != 0); + else + g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (g.ActiveId != 0) || (!g.OpenedPopupStack.empty()); + g.IO.WantCaptureKeyboard = (g.CaptureKeyboardNextFrame != -1) ? (g.CaptureKeyboardNextFrame != 0) : (g.ActiveId != 0); g.IO.WantTextInput = (g.ActiveId != 0 && g.InputTextState.Id == g.ActiveId); g.MouseCursor = ImGuiMouseCursor_Arrow; - g.CaptureMouseNextFrame = g.CaptureKeyboardNextFrame = false; + g.CaptureMouseNextFrame = g.CaptureKeyboardNextFrame = -1; g.OsImePosRequest = ImVec2(1.0f, 1.0f); // OS Input Method Editor showing on top-left of our window by default // If mouse was first clicked outside of ImGui bounds we also cancel out hovering. - if (mouse_owned_by_application) + if (!mouse_avail_to_imgui) g.HoveredWindow = g.HoveredRootWindow = NULL; // Scale & Scrolling @@ -2990,14 +3002,14 @@ void ImGui::SetMouseCursor(ImGuiMouseCursor cursor_type) GImGui->MouseCursor = cursor_type; } -void ImGui::CaptureKeyboardFromApp() +void ImGui::CaptureKeyboardFromApp(bool capture) { - GImGui->CaptureKeyboardNextFrame = true; + GImGui->CaptureKeyboardNextFrame = capture ? 1 : 0; } -void ImGui::CaptureMouseFromApp() +void ImGui::CaptureMouseFromApp(bool capture) { - GImGui->CaptureMouseNextFrame = true; + GImGui->CaptureMouseNextFrame = capture ? 1 : 0; } bool ImGui::IsItemHovered() @@ -3383,12 +3395,11 @@ void ImGui::EndChild() else { // When using auto-filling child window, we don't provide full width/height to ItemSize so that it doesn't feed back into automatic size-fitting. - ImGuiState& g = *GImGui; ImVec2 sz = ImGui::GetWindowSize(); - if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitX) // Arbitrary minimum zeroish child size of 4.0f - sz.x = ImMax(4.0f, sz.x - g.Style.WindowPadding.x); + if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitX) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f + sz.x = ImMax(4.0f, sz.x); if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitY) - sz.y = ImMax(4.0f, sz.y - g.Style.WindowPadding.y); + sz.y = ImMax(4.0f, sz.y); ImGui::End(); @@ -5078,6 +5089,8 @@ void ImGui::TextUnformatted(const char* text, const char* text_end) while (line < text_end && lines_skipped < lines_skippable) { const char* line_end = strchr(line, '\n'); + if (!line_end) + line_end = text_end; line = line_end + 1; lines_skipped++; } @@ -5223,7 +5236,11 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool SetHoveredID(id); if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) { - if (g.IO.MouseClicked[0]) + if (g.IO.MouseDoubleClicked[0] && (flags & ImGuiButtonFlags_PressedOnDoubleClick)) + { + pressed = true; + } + else if (g.IO.MouseClicked[0]) { if (flags & ImGuiButtonFlags_PressedOnClick) { @@ -6405,6 +6422,7 @@ bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_s g.DragLastMouseDelta = ImVec2(0.f, 0.f); } + float v_cur = g.DragCurrentValue; const ImVec2 mouse_drag_delta = ImGui::GetMouseDragDelta(0, 1.0f); if (fabsf(mouse_drag_delta.x - g.DragLastMouseDelta.x) > 0.0f) { @@ -6416,7 +6434,6 @@ bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_s if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f) speed = speed * g.DragSpeedScaleSlow; - float v_cur = g.DragCurrentValue; float delta = (mouse_drag_delta.x - g.DragLastMouseDelta.x) * speed; if (fabsf(power - 1.0f) > 0.001f) { @@ -6438,14 +6455,14 @@ bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_s if (v_min < v_max) v_cur = ImClamp(v_cur, v_min, v_max); g.DragCurrentValue = v_cur; + } - // Round to user desired precision, then apply - v_cur = RoundScalar(v_cur, decimal_precision); - if (*v != v_cur) - { - *v = v_cur; - value_changed = true; - } + // Round to user desired precision, then apply + v_cur = RoundScalar(v_cur, decimal_precision); + if (*v != v_cur) + { + *v = v_cur; + value_changed = true; } } else @@ -7118,41 +7135,41 @@ void ImGuiTextEditState::OnKeyPressed(int key) // Public API to manipulate UTF-8 text // We expose UTF-8 to the user (unlike the STB_TEXTEDIT_* functions which are manipulating wchar) +// FIXME: The existence of this rarely exercised code path is a bit of a nuisance. void ImGuiTextEditCallbackData::DeleteChars(int pos, int bytes_count) { + IM_ASSERT(pos + bytes_count <= BufTextLen); char* dst = Buf + pos; const char* src = Buf + pos + bytes_count; while (char c = *src++) *dst++ = c; *dst = '\0'; - BufDirty = true; if (CursorPos + bytes_count >= pos) CursorPos -= bytes_count; else if (CursorPos >= pos) CursorPos = pos; SelectionStart = SelectionEnd = CursorPos; + BufDirty = true; + BufTextLen -= bytes_count; } void ImGuiTextEditCallbackData::InsertChars(int pos, const char* new_text, const char* new_text_end) { - const int text_len = (int)strlen(Buf); - if (!new_text_end) - new_text_end = new_text + strlen(new_text); - const int new_text_len = (int)(new_text_end - new_text); - - if (new_text_len + text_len + 1 >= BufSize) + const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)strlen(new_text); + if (new_text_len + BufTextLen + 1 >= BufSize) return; - if (text_len != pos) - memmove(Buf + pos + new_text_len, Buf + pos, (size_t)(text_len - pos)); + if (BufTextLen != pos) + memmove(Buf + pos + new_text_len, Buf + pos, (size_t)(BufTextLen - pos)); memcpy(Buf + pos, new_text, (size_t)new_text_len * sizeof(char)); - Buf[text_len + new_text_len] = '\0'; + Buf[BufTextLen + new_text_len] = '\0'; - BufDirty = true; if (CursorPos >= pos) CursorPos += new_text_len; SelectionStart = SelectionEnd = CursorPos; + BufDirty = true; + BufTextLen += new_text_len; } // Return false to discard a character. @@ -7540,10 +7557,13 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 event_flag = ImGuiInputTextFlags_CallbackHistory; event_key = ImGuiKey_DownArrow; } + else if (flags & ImGuiInputTextFlags_CallbackAlways) + event_flag = ImGuiInputTextFlags_CallbackAlways; - if (event_key != ImGuiKey_COUNT || (flags & ImGuiInputTextFlags_CallbackAlways) != 0) + if (event_flag) { ImGuiTextEditCallbackData callback_data; + memset(&callback_data, 0, sizeof(ImGuiTextEditCallbackData)); callback_data.EventFlag = event_flag; callback_data.Flags = flags; callback_data.UserData = user_data; @@ -7551,10 +7571,11 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 callback_data.EventKey = event_key; callback_data.Buf = edit_state.TempTextBuffer.Data; + callback_data.BufTextLen = edit_state.CurLenA; callback_data.BufSize = edit_state.BufSizeA; callback_data.BufDirty = false; - // We have to convert from position from wchar to UTF-8 positions + // We have to convert from wchar-positions to UTF-8-positions, which can be pretty slow (an incentive to ditch the ImWchar buffer, see https://github.com/nothings/stb/issues/188) ImWchar* text = edit_state.Text.Data; const int utf8_cursor_pos = callback_data.CursorPos = ImTextCountUtf8BytesFromStr(text, text + edit_state.StbState.cursor); const int utf8_selection_start = callback_data.SelectionStart = ImTextCountUtf8BytesFromStr(text, text + edit_state.StbState.select_start); @@ -7572,8 +7593,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (callback_data.SelectionEnd != utf8_selection_end) edit_state.StbState.select_end = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionEnd); if (callback_data.BufDirty) { - edit_state.CurLenW = ImTextStrFromUtf8(text, edit_state.Text.Size, edit_state.TempTextBuffer.Data, NULL); - edit_state.CurLenA = (int)strlen(edit_state.TempTextBuffer.Data); + IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text! + edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, edit_state.Text.Size, callback_data.Buf, NULL); + edit_state.CurLenA = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen() edit_state.CursorAnimReset(); } } @@ -8137,6 +8159,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl if (flags & ImGuiSelectableFlags_Menu) button_flags |= ImGuiButtonFlags_PressedOnClick; if (flags & ImGuiSelectableFlags_MenuItem) button_flags |= ImGuiButtonFlags_PressedOnClick|ImGuiButtonFlags_PressedOnRelease; if (flags & ImGuiSelectableFlags_Disabled) button_flags |= ImGuiButtonFlags_Disabled; + if (flags & ImGuiSelectableFlags_AllowDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnDoubleClick; bool hovered, held; bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, button_flags); if (flags & ImGuiSelectableFlags_Disabled) diff --git a/3rdparty/ocornut-imgui/imgui.h b/3rdparty/ocornut-imgui/imgui.h index d00a936d..7bb57318 100644 --- a/3rdparty/ocornut-imgui/imgui.h +++ b/3rdparty/ocornut-imgui/imgui.h @@ -239,7 +239,7 @@ namespace ImGui IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // doesn't require null terminated string if 'text_end' is specified. no copy done to any bounded stack buffer, recommended for long chunks of text IMGUI_API void LabelText(const char* label, const char* fmt, ...) IM_PRINTFARGS(2); // display text+label aligned the same way as value+label widgets IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args); - IMGUI_API void Bullet(); + IMGUI_API void Bullet(); // draw a small circle and keep the cursor on the same line. advance you by the same distance as an empty TreeNode() call. IMGUI_API void BulletText(const char* fmt, ...) IM_PRINTFARGS(1); IMGUI_API void BulletTextV(const char* fmt, va_list args); IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0)); @@ -303,8 +303,8 @@ namespace ImGui IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f"); // Widgets: Trees - IMGUI_API bool TreeNode(const char* str_label_id); // if returning 'true' the node is open and the user is responsible for calling TreePop() - IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_PRINTFARGS(2); // " + IMGUI_API bool TreeNode(const char* str_label_id); // if returning 'true' the node is open and the user is responsible for calling TreePop(). + IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_PRINTFARGS(2); // read the FAQ about why and how to use ID. to align arbitrary text at the same level as a TreeNode() you can use Bullet(). IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...) IM_PRINTFARGS(2); // " IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args); // " IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args); // " @@ -415,8 +415,8 @@ namespace ImGui IMGUI_API void ResetMouseDragDelta(int button = 0); // IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired cursor type, reset in ImGui::NewFrame(), this updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you IMGUI_API void SetMouseCursor(ImGuiMouseCursor type); // set desired cursor type - IMGUI_API void CaptureKeyboardFromApp(); // manually enforce imgui setting the io.WantCaptureKeyboard flag next frame (your application needs to handle it). e.g. capture keyboard when your widget is being hovered. - IMGUI_API void CaptureMouseFromApp(); // manually enforce imgui setting the io.WantCaptureMouse flag next frame (your application needs to handle it). + IMGUI_API void CaptureKeyboardFromApp(bool capture = true); // manually override io.WantCaptureKeyboard flag next frame (said flag is entirely left for your application handle). e.g. force capture keyboard when your widget is being hovered. + IMGUI_API void CaptureMouseFromApp(bool capture = true); // manually override io.WantCaptureMouse flag next frame (said flag is entirely left for your application handle). // Helpers functions to access functions pointers in ImGui::GetIO() IMGUI_API void* MemAlloc(size_t sz); @@ -488,7 +488,7 @@ enum ImGuiInputTextFlags_ ImGuiInputTextFlags_EnterReturnsTrue = 1 << 5, // Return 'true' when Enter is pressed (as opposed to when the value was modified) ImGuiInputTextFlags_CallbackCompletion = 1 << 6, // Call user function on pressing TAB (for completion handling) ImGuiInputTextFlags_CallbackHistory = 1 << 7, // Call user function on pressing Up/Down arrows (for history handling) - ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Call user function every time + ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Call user function every time. User code may query cursor position, modify text buffer. ImGuiInputTextFlags_CallbackCharFilter = 1 << 9, // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character. ImGuiInputTextFlags_AllowTabInput = 1 << 10, // Pressing TAB input a '\t' character into the text field ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, allow exiting edition by pressing Enter. Ctrl+Enter to add new line (by default adds new lines with Enter). @@ -505,7 +505,8 @@ enum ImGuiSelectableFlags_ { // Default: 0 ImGuiSelectableFlags_DontClosePopups = 1 << 0, // Clicking this don't close parent popup window - ImGuiSelectableFlags_SpanAllColumns = 1 << 1 // Selectable frame can span all columns (text will still fit in current column) + ImGuiSelectableFlags_SpanAllColumns = 1 << 1, // Selectable frame can span all columns (text will still fit in current column) + ImGuiSelectableFlags_AllowDoubleClick = 1 << 2 // Generate press events on double clicks too }; // User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array @@ -946,7 +947,7 @@ struct ImGuiStorage IMGUI_API void SetAllInt(int val); }; -// 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 and the corresponding callback is triggered. struct ImGuiTextEditCallbackData { ImGuiInputTextFlags EventFlag; // One of ImGuiInputTextFlags_Callback* // Read-only @@ -958,15 +959,17 @@ struct ImGuiTextEditCallbackData ImWchar EventChar; // Character input // Read-write (replace character or set to zero) // Completion,History,Always events: + // If you modify the buffer contents make sure you update 'BufTextLen' and set 'BufDirty' to true. ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only - char* Buf; // Current text // Read-write (pointed data only) - int BufSize; // // Read-only - bool BufDirty; // Must set if you modify Buf directly // Write + char* Buf; // Current text buffer // Read-write (pointed data only, can't replace the actual pointer) + int BufTextLen; // Current text length in bytes // Read-write + int BufSize; // Maximum text length in bytes // Read-only + bool BufDirty; // Set if you modify Buf/BufTextLen!! // Write int CursorPos; // // Read-write int SelectionStart; // // Read-write (== to SelectionEnd when no selection) int SelectionEnd; // // Read-write - // NB: calling those function loses selection. + // NB: Helper functions for text manipulation. Calling those function loses selection. void DeleteChars(int pos, int bytes_count); void InsertChars(int pos, const char* text, const char* text_end = NULL); bool HasSelection() const { return SelectionStart != SelectionEnd; } @@ -1256,7 +1259,7 @@ struct ImFontAtlas int TexHeight; // Texture height calculated during Build(). int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel (part of the TexExtraData block) - ImVector Fonts; + ImVector Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. // Private ImVector ConfigData; // Internal data diff --git a/3rdparty/ocornut-imgui/imgui_demo.cpp b/3rdparty/ocornut-imgui/imgui_demo.cpp index 7c965377..5169cbac 100644 --- a/3rdparty/ocornut-imgui/imgui_demo.cpp +++ b/3rdparty/ocornut-imgui/imgui_demo.cpp @@ -392,11 +392,14 @@ void ImGui::ShowTestWindow(bool* p_opened) { if (ImGui::TreeNode("Basic")) { - static bool selected[3] = { false, true, false }; + static bool selected[4] = { false, true, false, false }; ImGui::Selectable("1. I am selectable", &selected[0]); ImGui::Selectable("2. I am selectable", &selected[1]); ImGui::Text("3. I am not selectable"); ImGui::Selectable("4. I am selectable", &selected[2]); + if (ImGui::Selectable("5. I am double clickable", selected[3], ImGuiSelectableFlags_AllowDoubleClick)) + if (ImGui::IsMouseDoubleClicked(0)) + selected[3] = !selected[3]; ImGui::TreePop(); } if (ImGui::TreeNode("Rendering more text into the same block")) @@ -713,7 +716,9 @@ void ImGui::ShowTestWindow(bool* p_opened) static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr)); - static ImVector values; if (values.empty()) { values.resize(90); memset(values.Data, 0, values.Size*sizeof(float)); } + // Create a dummy array of contiguous float values to plot + // Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float and the sizeof() of your structure in the Stride parameter. + static float values[90] = { 0 }; static int values_offset = 0; if (animate) { @@ -722,11 +727,11 @@ void ImGui::ShowTestWindow(bool* p_opened) { static float phase = 0.0f; values[values_offset] = cosf(phase); - values_offset = (values_offset+1)%values.Size; + values_offset = (values_offset+1) % IM_ARRAYSIZE(values); phase += 0.10f*values_offset; } } - ImGui::PlotLines("Lines", values.Data, values.Size, values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80)); + ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80)); ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,80)); // Use functions to generate output @@ -1501,10 +1506,14 @@ void ImGui::ShowTestWindow(bool* p_opened) ImGui::Text("WantCaptureKeyboard: %s", io.WantCaptureKeyboard ? "true" : "false"); ImGui::Text("WantTextInput: %s", io.WantTextInput ? "true" : "false"); - ImGui::Button("Hover me\nto enforce\ninputs capture"); + ImGui::Button("Hovering me sets the\nkeyboard capture flag"); if (ImGui::IsItemHovered()) - ImGui::CaptureKeyboardFromApp(); - + ImGui::CaptureKeyboardFromApp(true); + ImGui::SameLine(); + ImGui::Button("Holding me clears the\nthe keyboard capture flag"); + if (ImGui::IsItemActive()) + ImGui::CaptureKeyboardFromApp(false); + ImGui::TreePop(); } @@ -1886,18 +1895,19 @@ struct ExampleAppConsole Commands.push_back("HISTORY"); Commands.push_back("CLEAR"); Commands.push_back("CLASSIFY"); // "classify" is here to provide an example of "C"+[tab] completing to "CL" and displaying matches. + AddLog("Welcome to ImGui!"); } ~ExampleAppConsole() { ClearLog(); - for (int i = 0; i < Items.Size; i++) + for (int i = 0; i < History.Size; i++) free(History[i]); } // Portable helpers static int Stricmp(const char* str1, const char* str2) { int d; while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } return d; } static int Strnicmp(const char* str1, const char* str2, int n) { int d = 0; while (n > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; n--; } return d; } - static char* Strdup(const char *str) { size_t len = strlen(str) + 1; void* buff = ImGui::MemAlloc(len); return (char*)memcpy(buff, (const void*)str, len); } + static char* Strdup(const char *str) { size_t len = strlen(str) + 1; void* buff = malloc(len); return (char*)memcpy(buff, (const void*)str, len); } void ClearLog() { @@ -2126,9 +2136,8 @@ struct ExampleAppConsole // A better implementation would preserve the data on the current input line along with cursor position. if (prev_history_pos != HistoryPos) { - snprintf(data->Buf, data->BufSize, "%s", (HistoryPos >= 0) ? History[HistoryPos] : ""); + data->CursorPos = data->SelectionStart = data->SelectionEnd = data->BufTextLen = (int)snprintf(data->Buf, data->BufSize, "%s", (HistoryPos >= 0) ? History[HistoryPos] : ""); data->BufDirty = true; - data->CursorPos = data->SelectionStart = data->SelectionEnd = (int)strlen(data->Buf); } } } diff --git a/3rdparty/ocornut-imgui/imgui_internal.h b/3rdparty/ocornut-imgui/imgui_internal.h index a4caacff..f6300e74 100644 --- a/3rdparty/ocornut-imgui/imgui_internal.h +++ b/3rdparty/ocornut-imgui/imgui_internal.h @@ -152,14 +152,15 @@ inline void operator delete(void*, ImPlacementNewDummy, void*) {} enum ImGuiButtonFlags_ { - ImGuiButtonFlags_Repeat = 1 << 0, - ImGuiButtonFlags_PressedOnClick = 1 << 1, // return pressed on click only (default requires click+release) - ImGuiButtonFlags_PressedOnRelease = 1 << 2, // return pressed on release only (default requires click+release) - ImGuiButtonFlags_FlattenChilds = 1 << 3, - ImGuiButtonFlags_DontClosePopups = 1 << 4, - ImGuiButtonFlags_Disabled = 1 << 5, - ImGuiButtonFlags_AlignTextBaseLine = 1 << 6, - ImGuiButtonFlags_NoKeyModifiers = 1 << 7 + ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat + ImGuiButtonFlags_PressedOnClick = 1 << 1, // return pressed on click (default requires click+release) + ImGuiButtonFlags_PressedOnRelease = 1 << 2, // return pressed on release (default requires click+release) + ImGuiButtonFlags_PressedOnDoubleClick = 1 << 3, // return pressed on double-click (default requires click+release) + ImGuiButtonFlags_FlattenChilds = 1 << 4, // allow interaction even if a child window is overlapping + ImGuiButtonFlags_DontClosePopups = 1 << 5, // disable automatically closing parent popup on press + ImGuiButtonFlags_Disabled = 1 << 6, // disable interaction + ImGuiButtonFlags_AlignTextBaseLine = 1 << 7, // vertically align button to match text baseline - ButtonEx() only + ImGuiButtonFlags_NoKeyModifiers = 1 << 8 // disable interaction if a key modifier is held }; enum ImGuiTreeNodeFlags_ @@ -176,10 +177,10 @@ enum ImGuiSliderFlags_ enum ImGuiSelectableFlagsPrivate_ { // NB: need to be in sync with last value of ImGuiSelectableFlags_ - ImGuiSelectableFlags_Menu = 1 << 2, - ImGuiSelectableFlags_MenuItem = 1 << 3, - ImGuiSelectableFlags_Disabled = 1 << 4, - ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 5 + ImGuiSelectableFlags_Menu = 1 << 3, + ImGuiSelectableFlags_MenuItem = 1 << 4, + ImGuiSelectableFlags_Disabled = 1 << 5, + ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 6 }; // FIXME: this is in development, not exposed/functional as a generic feature yet. @@ -434,8 +435,8 @@ struct ImGuiState float FramerateSecPerFrame[120]; // calculate estimate of framerate for user int FramerateSecPerFrameIdx; float FramerateSecPerFrameAccum; - bool CaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags - bool CaptureKeyboardNextFrame; + int CaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags + int CaptureKeyboardNextFrame; char TempBuffer[1024*3+1]; // temporary text buffer ImGuiState() @@ -501,7 +502,7 @@ struct ImGuiState memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); FramerateSecPerFrameIdx = 0; FramerateSecPerFrameAccum = 0.0f; - CaptureMouseNextFrame = CaptureKeyboardNextFrame = false; + CaptureMouseNextFrame = CaptureKeyboardNextFrame = -1; memset(TempBuffer, 0, sizeof(TempBuffer)); } };