From 7ccbb765e2c0acc84b3e5d7335050e0af8bb555f Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 17 Jan 2018 12:15:00 +0100 Subject: [PATCH 01/17] InputText: Cursor X position not lost when clicking outside on an item that's submitted after the InputText(). It was only noticeable when restoring focus programmatically. (#1418, #1554) --- imgui.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index f1f54e6b..904fe861 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8607,8 +8607,11 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 } else if (io.MouseClicked[0] && !edit_state.SelectedAllMouseLock) { - stb_textedit_click(&edit_state, &edit_state.StbState, mouse_x, mouse_y); - edit_state.CursorAnimReset(); + if (hovered) + { + stb_textedit_click(&edit_state, &edit_state.StbState, mouse_x, mouse_y); + edit_state.CursorAnimReset(); + } } else if (io.MouseDown[0] && !edit_state.SelectedAllMouseLock && (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f)) { From cc15512bfc2a3abb88d7c8969ecf6d67611e1b96 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 17 Jan 2018 12:15:24 +0100 Subject: [PATCH 02/17] InputText: Minor tweak. --- imgui_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_internal.h b/imgui_internal.h index 0f90942c..6873a293 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -357,7 +357,7 @@ struct IMGUI_API ImGuiTextEditState void CursorClamp() { StbState.cursor = ImMin(StbState.cursor, CurLenW); StbState.select_start = ImMin(StbState.select_start, CurLenW); StbState.select_end = ImMin(StbState.select_end, CurLenW); } bool HasSelection() const { return StbState.select_start != StbState.select_end; } void ClearSelection() { StbState.select_start = StbState.select_end = StbState.cursor; } - void SelectAll() { StbState.select_start = 0; StbState.select_end = CurLenW; StbState.cursor = StbState.select_end; StbState.has_preferred_x = false; } + void SelectAll() { StbState.select_start = 0; StbState.cursor = StbState.select_end = CurLenW; StbState.has_preferred_x = false; } void OnKeyPressed(int key); }; From d1f726cd9db6445e18090e488c8ee8ca4fe6e09c Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 17 Jan 2018 12:46:07 +0100 Subject: [PATCH 03/17] Comments about Begin/End pair and handling of return value. --- imgui.h | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/imgui.h b/imgui.h index ee6f0135..91671ead 100644 --- a/imgui.h +++ b/imgui.h @@ -145,11 +145,11 @@ namespace ImGui IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as a end-user (mouse/keyboard controls). // Window - IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed, so you can early out in your code. 'bool* p_open' creates a widget on the upper-right to close the window (which sets your bool to false). - IMGUI_API void End(); // finish appending to current window, pop it off the window stack. - IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // begin a scrolling region. size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). size>0.0f: fixed size. each axis can use a different mode, e.g. ImVec2(0,400). - IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // " - IMGUI_API void EndChild(); + IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed (so you can early out in your code) but you always need to call End() regardless. 'bool* p_open' creates a widget on the upper-right to close the window (which sets your bool to false). + IMGUI_API void End(); // always call even if Begin() return false (which indicates a collapsed window)! finish appending to current window, pop it off the window stack. + IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0); // begin a scrolling region. size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). size>0.0f: fixed size. each axis can use a different mode, e.g. ImVec2(0,400). + IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0); // " + IMGUI_API void EndChild(); // always call even if BeginChild() return false (which indicates a collapsed or clipping child window) IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos() IMGUI_API float GetContentRegionAvailWidth(); // @@ -303,7 +303,7 @@ namespace ImGui // The new BeginCombo()/EndCombo() api allows you to manage your contents and selection state however you want it. // The old Combo() api are helpers over BeginCombo()/EndCombo() which are kept available for convenience purpose. IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0); - IMGUI_API void EndCombo(); + IMGUI_API void EndCombo(); // only call EndCombo() if BeginCombo() returns true! IMGUI_API bool Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items = -1); IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items = -1); // Separate items with \0 within a string, end item-list with \0\0. e.g. "One\0Two\0Three\0" IMGUI_API bool Combo(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_max_height_in_items = -1); @@ -397,23 +397,23 @@ namespace ImGui IMGUI_API void EndTooltip(); // Menus - IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar. only call EndMainMenuBar() if this returns true! - IMGUI_API void EndMainMenuBar(); - IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set on parent window). only call EndMenuBar() if this returns true! - IMGUI_API void EndMenuBar(); + IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar. + IMGUI_API void EndMainMenuBar(); // only call EndMainMenuBar() if BeginMainMenuBar() returns true! + IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set on parent window). + IMGUI_API void EndMenuBar(); // only call EndMenuBar() if BeginMenuBar() returns true! IMGUI_API bool BeginMenu(const char* label, bool enabled = true); // create a sub-menu entry. only call EndMenu() if this returns true! - IMGUI_API void EndMenu(); + IMGUI_API void EndMenu(); // only call EndBegin() if BeginMenu() returns true! IMGUI_API bool MenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true); // return true when activated. shortcuts are displayed for convenience but not processed by ImGui at the moment IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL // Popups IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!). popups are closed when user click outside, or if CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. By default, Selectable()/MenuItem() are calling CloseCurrentPopup(). Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). - IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returned true! + IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returns true! IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp! IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, int mouse_button = 1, bool also_over_items = true); // helper to open and begin popup when clicked on current window. IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (where there are no imgui windows). IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // modal dialog (regular window with title bar, block interactions behind the modal window, can't close the modal window by clicking outside) - IMGUI_API void EndPopup(); + IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true! IMGUI_API bool OpenPopupOnItemClick(const char* str_id = NULL, int mouse_button = 1); // helper to open popup when clicked on last item. return true when just opened. IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. @@ -430,10 +430,10 @@ namespace ImGui // [BETA API] Missing Demo code. API may evolve. IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0, int mouse_button = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t size, ImGuiCond cond = 0);// type is a user defined string of maximum 8 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. - IMGUI_API void EndDragDropSource(); + IMGUI_API void EndDragDropSource(); // only call EndDragDropSource() if BeginDragDropSource() returns true! IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. - IMGUI_API void EndDragDropTarget(); + IMGUI_API void EndDragDropTarget(); // only call EndDragDropTarget() if BeginDragDropTarget() returns true! // Clipping IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); @@ -473,8 +473,8 @@ namespace ImGui IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // calculate coarse clipping for large list of evenly sized items. Prefer using the ImGuiListClipper higher-level helper if you can. - IMGUI_API bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags extra_flags = 0); // helper to create a child window / scrolling region that looks like a normal widget frame - IMGUI_API void EndChildFrame(); + IMGUI_API bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags = 0); // helper to create a child window / scrolling region that looks like a normal widget frame + IMGUI_API void EndChildFrame(); // always call EndChildFrame() regardless of BeginChildFrame() return values (which indicates a collapsed/clipped window) IMGUI_API ImVec4 ColorConvertU32ToFloat4(ImU32 in); IMGUI_API ImU32 ColorConvertFloat4ToU32(const ImVec4& in); From 60d5dc79029e4d9c778c9635987c1f11260ce87e Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 18 Jan 2018 10:01:36 +0100 Subject: [PATCH 04/17] Examples: SDL: Fixed mapping of Insert key (#1555, fix bug introduced in #1541) --- examples/sdl_opengl2_example/imgui_impl_sdl.cpp | 2 +- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index ac920083..689c7ad3 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -214,7 +214,7 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; - io.KeyMap[ImGuiKey_Insert] = SDLK_INSERT; + io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT; io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index f9e970f3..b16a0300 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -325,7 +325,7 @@ bool ImGui_ImplSdlGL3_Init(SDL_Window* window) io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; - io.KeyMap[ImGuiKey_Insert] = SDLK_INSERT; + io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT; io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; From 932d3f01988276e5a9ee969b3faaf443c21c118d Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 18 Jan 2018 10:06:58 +0100 Subject: [PATCH 05/17] NewFrame(): Added an assert to detect incorrect filling of the io.KeyMap[] array earlier. (#1555) + comments. --- imgui.cpp | 2 ++ imgui.h | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 904fe861..bd218caf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2282,6 +2282,8 @@ void ImGui::NewFrame() IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting"); IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations)"); IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?"); + for (int n = 0; n < ImGuiKey_COUNT; n++) + IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..512, or -1 for unmapped key)"); // Initialize on first frame if (!g.Initialized) diff --git a/imgui.h b/imgui.h index 91671ead..c6bf05de 100644 --- a/imgui.h +++ b/imgui.h @@ -881,8 +881,8 @@ struct ImGuiIO const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified). float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds. float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels. - float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging - int KeyMap[ImGuiKey_COUNT]; // // Map of indices into the KeysDown[512] entries array + float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging. + int KeyMap[ImGuiKey_COUNT]; // // Map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. float KeyRepeatDelay; // = 0.250f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.). float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds. void* UserData; // = NULL // Store your own data for retrieval by callbacks. @@ -936,7 +936,7 @@ struct ImGuiIO bool KeyShift; // Keyboard modifier pressed: Shift bool KeyAlt; // Keyboard modifier pressed: Alt bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows - bool KeysDown[512]; // Keyboard keys that are pressed (in whatever storage order you naturally have access to keyboard data) + bool KeysDown[512]; // Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). ImWchar InputCharacters[16+1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper. // Functions From 63d47e8328db78784c99685ee3b9f1e57e6a1aff Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 18 Jan 2018 17:32:34 +0100 Subject: [PATCH 06/17] Drag and Drop: Increased payload type string to 12 characters instead of 8.(#143) --- imgui.cpp | 2 +- imgui.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index bd218caf..7b65d37a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11397,7 +11397,7 @@ bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_s cond = ImGuiCond_Always; IM_ASSERT(type != NULL); - IM_ASSERT(strlen(type) < IM_ARRAYSIZE(payload.DataType)); // Payload type can be at most 8 characters longs + IM_ASSERT(strlen(type) < IM_ARRAYSIZE(payload.DataType) && "Payload type can be at most 12 characters long"); IM_ASSERT((data != NULL && data_size > 0) || (data == NULL && data_size == 0)); IM_ASSERT(cond == ImGuiCond_Always || cond == ImGuiCond_Once); IM_ASSERT(payload.SourceId != 0); // Not called between BeginDragDropSource() and EndDragDropSource() diff --git a/imgui.h b/imgui.h index c6bf05de..33c66b45 100644 --- a/imgui.h +++ b/imgui.h @@ -429,7 +429,7 @@ namespace ImGui // Drag and Drop // [BETA API] Missing Demo code. API may evolve. IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0, int mouse_button = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() - IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t size, ImGuiCond cond = 0);// type is a user defined string of maximum 8 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. + IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t size, ImGuiCond cond = 0);// type is a user defined string of maximum 12 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. IMGUI_API void EndDragDropSource(); // only call EndDragDropSource() if BeginDragDropSource() returns true! IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. @@ -1239,7 +1239,7 @@ struct ImGuiPayload ImGuiID SourceId; // Source item id ImGuiID SourceParentId; // Source parent id (if available) int DataFrameCount; // Data timestamp - char DataType[8 + 1]; // Data type tag (short user-supplied string) + char DataType[12 + 1]; // Data type tag (short user-supplied string, 12 characters max) bool Preview; // Set when AcceptDragDropPayload() was called and mouse has been hovering the target item (nb: handle overlapping drag targets) bool Delivery; // Set when AcceptDragDropPayload() was called and mouse button is released over the target item. From c2ffce3e5aef30d17fdc89c3afa3ee55ed9376b6 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 18 Jan 2018 17:39:40 +0100 Subject: [PATCH 07/17] Drag and Drop: Fix comment. Removed IMGUI_PAYLOAD_TYPE_DOCKABLE from master branch. (#143) --- imgui.h | 2 +- imgui_internal.h | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/imgui.h b/imgui.h index 33c66b45..f5d8eb02 100644 --- a/imgui.h +++ b/imgui.h @@ -655,7 +655,7 @@ enum ImGuiDragDropFlags_ ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery. }; -// Standard Drag and Drop payload types. You can define you own payload types using 8-characters long strings. Types starting with '_' are defined by Dear ImGui. +// Standard Drag and Drop payload types. You can define you own payload types using 12-characters long strings. Types starting with '_' are defined by Dear ImGui. #define IMGUI_PAYLOAD_TYPE_COLOR_3F "_COL3F" // float[3] // Standard type for colors, without alpha. User code may use this type. #define IMGUI_PAYLOAD_TYPE_COLOR_4F "_COL4F" // float[4] // Standard type for colors. User code may use this type. diff --git a/imgui_internal.h b/imgui_internal.h index 6873a293..4a5edfc1 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -170,9 +170,6 @@ template void IM_DELETE(T*& p) { if (p) { p->~T(); ImGui::MemFree(p // Types //----------------------------------------------------------------------------- -// Internal Drag and Drop payload types. String starting with '_' are reserved for Dear ImGui. -#define IMGUI_PAYLOAD_TYPE_DOCKABLE "_IMDOCK" // ImGuiWindow* // [Internal] Docking/tabs - enum ImGuiButtonFlags_ { ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat From 74dc70c543107c14ddd9e635908958c90524abef Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 09:16:26 +0100 Subject: [PATCH 08/17] DragFloat: Fix/workaround for backends which do not preserve a valid mouse position when dragged out of bounds. (#1559) --- imgui.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7b65d37a..7dbc92c1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3580,6 +3580,7 @@ bool ImGui::IsMousePosValid(const ImVec2* mouse_pos) return mouse_pos->x >= MOUSE_INVALID && mouse_pos->y >= MOUSE_INVALID; } +// NB: This is only valid if IsMousePosValid(). Backends in theory should always keep mouse position valid when dragging even outside the client window. ImVec2 ImGui::GetMouseDragDelta(int button, float lock_threshold) { ImGuiContext& g = *GImGui; @@ -7622,16 +7623,19 @@ bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_s float v_cur = g.DragCurrentValue; const ImVec2 mouse_drag_delta = GetMouseDragDelta(0, 1.0f); float adjust_delta = 0.0f; - //if (g.ActiveIdSource == ImGuiInputSource_Mouse) + if (IsMousePosValid()) { - adjust_delta = mouse_drag_delta.x - g.DragLastMouseDelta.x; - if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f) - adjust_delta *= g.DragSpeedScaleFast; - if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f) - adjust_delta *= g.DragSpeedScaleSlow; + //if (g.ActiveIdSource == ImGuiInputSource_Mouse) + { + adjust_delta = mouse_drag_delta.x - g.DragLastMouseDelta.x; + if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f) + adjust_delta *= g.DragSpeedScaleFast; + if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f) + adjust_delta *= g.DragSpeedScaleSlow; + } + g.DragLastMouseDelta.x = mouse_drag_delta.x; } adjust_delta *= v_speed; - g.DragLastMouseDelta.x = mouse_drag_delta.x; if (fabsf(adjust_delta) > 0.0f) { From ce17e0f27496ad09dcfc2ca8f605ed2494ed909d Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 09:25:31 +0100 Subject: [PATCH 09/17] Examples: SDL: Using SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS (which is ~~hovered). We should use SDL_CaptureMouse + SDL_WINDOW_MOUSE_CAPTURE_FLAG which requires SDL 2.0.4 will give it a try shortly. (#1559) --- examples/sdl_opengl2_example/imgui_impl_sdl.cpp | 2 +- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index 689c7ad3..205840b6 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -274,7 +274,7 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) int mx, my; Uint32 mouseMask = SDL_GetMouseState(&mx, &my); - if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) + if (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) io.MousePos = ImVec2((float)mx, (float)my); else io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index b16a0300..037f0723 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -385,7 +385,7 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) int mx, my; Uint32 mouseMask = SDL_GetMouseState(&mx, &my); - if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) + if (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) io.MousePos = ImVec2((float)mx, (float)my); else io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); From 15fd5b6c4c77e8f168d854118dd80d7a49808410 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 09:43:28 +0100 Subject: [PATCH 10/17] Examples: SDL: Minor renaming. --- examples/sdl_opengl2_example/imgui_impl_sdl.cpp | 8 ++++---- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index 205840b6..263017dc 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -273,15 +273,15 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) // Setup inputs // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) int mx, my; - Uint32 mouseMask = SDL_GetMouseState(&mx, &my); + Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); if (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) io.MousePos = ImVec2((float)mx, (float)my); else io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX); - io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - io.MouseDown[1] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; - io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; + io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; + io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; io.MouseWheel = g_MouseWheel; diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 037f0723..e9a1393c 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -384,15 +384,15 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) // Setup inputs // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) int mx, my; - Uint32 mouseMask = SDL_GetMouseState(&mx, &my); + Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); if (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) io.MousePos = ImVec2((float)mx, (float)my); else io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. - io.MouseDown[1] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; - io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; + io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; + io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; io.MouseWheel = g_MouseWheel; From 79dca9d5e6f127f6dd236ca7146f28b55550489f Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 09:45:27 +0100 Subject: [PATCH 11/17] Examples: SDL+GL2: Renamed imgui_impl_sdl.* to imgui_impl_sdl_gl2.* for consistency and to emphasis on GL2-ness. --- examples/sdl_opengl2_example/build_win32.bat | 2 +- .../{imgui_impl_sdl.cpp => imgui_impl_sdl_gl2.cpp} | 6 +++--- .../{imgui_impl_sdl.h => imgui_impl_sdl_gl2.h} | 0 examples/sdl_opengl2_example/main.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) rename examples/sdl_opengl2_example/{imgui_impl_sdl.cpp => imgui_impl_sdl_gl2.cpp} (97%) rename examples/sdl_opengl2_example/{imgui_impl_sdl.h => imgui_impl_sdl_gl2.h} (100%) diff --git a/examples/sdl_opengl2_example/build_win32.bat b/examples/sdl_opengl2_example/build_win32.bat index 3cf81e60..799561de 100644 --- a/examples/sdl_opengl2_example/build_win32.bat +++ b/examples/sdl_opengl2_example/build_win32.bat @@ -1,3 +1,3 @@ @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL_DIR%\include main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/sdl_opengl2_example.exe /FoDebug/ /link /libpath:%SDL_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +cl /nologo /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL_DIR%\include main.cpp imgui_impl_sdl_gl2.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/sdl_opengl2_example.exe /FoDebug/ /link /libpath:%SDL_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp similarity index 97% rename from examples/sdl_opengl2_example/imgui_impl_sdl.cpp rename to examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index 263017dc..154a6d23 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -19,7 +19,7 @@ #include #include #include -#include "imgui_impl_sdl.h" +#include "imgui_impl_sdl_gl2.h" // Data static double g_Time = 0.0f; @@ -30,7 +30,7 @@ static GLuint g_FontTexture = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. // If text or lines are blurry when integrating ImGui in your engine: in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) -void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) +void ImGui_ImplSdlGL2_RenderDrawLists(ImDrawData* draw_data) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) ImGuiIO& io = ImGui::GetIO(); @@ -226,7 +226,7 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) io.KeyMap[ImGuiKey_Y] = SDLK_y; io.KeyMap[ImGuiKey_Z] = SDLK_z; - io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.RenderDrawListsFn = ImGui_ImplSdlGL2_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; io.ClipboardUserData = NULL; diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.h b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.h similarity index 100% rename from examples/sdl_opengl2_example/imgui_impl_sdl.h rename to examples/sdl_opengl2_example/imgui_impl_sdl_gl2.h diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index 1396fcca..21b567a8 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -7,7 +7,7 @@ // See imgui_impl_sdl.cpp for details. #include -#include "imgui_impl_sdl.h" +#include "imgui_impl_sdl_gl2.h" #include #include #include From ba99900023000e6c7bb6001100744549f869f53b Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 09:48:23 +0100 Subject: [PATCH 12/17] Examples: GLFW+GL2: Renamed imgui_impl_glfw.* to imgui_impl_glfw_gl2.* for consistency and to emphasis on GL2-ness. --- examples/opengl2_example/Makefile | 2 +- .../{imgui_impl_glfw.cpp => imgui_impl_glfw_gl2.cpp} | 2 +- .../{imgui_impl_glfw.h => imgui_impl_glfw_gl2.h} | 0 examples/opengl2_example/main.cpp | 2 +- examples/opengl2_example/opengl2_example.vcxproj | 4 ++-- examples/opengl2_example/opengl2_example.vcxproj.filters | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) rename examples/opengl2_example/{imgui_impl_glfw.cpp => imgui_impl_glfw_gl2.cpp} (99%) rename examples/opengl2_example/{imgui_impl_glfw.h => imgui_impl_glfw_gl2.h} (100%) diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile index 932aebed..f10c59a8 100644 --- a/examples/opengl2_example/Makefile +++ b/examples/opengl2_example/Makefile @@ -11,7 +11,7 @@ #CXX = g++ EXE = opengl2_example -OBJS = main.o imgui_impl_glfw.o +OBJS = main.o imgui_impl_glfw_gl2.o OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o UNAME_S := $(shell uname -s) diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp similarity index 99% rename from examples/opengl2_example/imgui_impl_glfw.cpp rename to examples/opengl2_example/imgui_impl_glfw_gl2.cpp index d2eb657f..4ce831d9 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp @@ -16,7 +16,7 @@ // https://github.com/ocornut/imgui #include -#include "imgui_impl_glfw.h" +#include "imgui_impl_glfw_gl2.h" // GLFW #include diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw_gl2.h similarity index 100% rename from examples/opengl2_example/imgui_impl_glfw.h rename to examples/opengl2_example/imgui_impl_glfw_gl2.h diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index ef098e54..6359f5b6 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -7,7 +7,7 @@ // See imgui_impl_glfw.cpp for details. #include -#include "imgui_impl_glfw.h" +#include "imgui_impl_glfw_gl2.h" #include #include diff --git a/examples/opengl2_example/opengl2_example.vcxproj b/examples/opengl2_example/opengl2_example.vcxproj index a6cbebd6..237eba7d 100644 --- a/examples/opengl2_example/opengl2_example.vcxproj +++ b/examples/opengl2_example/opengl2_example.vcxproj @@ -153,14 +153,14 @@ - + - + diff --git a/examples/opengl2_example/opengl2_example.vcxproj.filters b/examples/opengl2_example/opengl2_example.vcxproj.filters index f2282bf6..3cc7ee9e 100644 --- a/examples/opengl2_example/opengl2_example.vcxproj.filters +++ b/examples/opengl2_example/opengl2_example.vcxproj.filters @@ -16,7 +16,7 @@ imgui - + sources @@ -33,7 +33,7 @@ imgui - + sources From 00351ee2ab7562e07aaec70c3923a58385b6f760 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 09:53:55 +0100 Subject: [PATCH 13/17] Examples: SDL: Minor renaming. --- examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index 154a6d23..802a31be 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -111,12 +111,12 @@ void ImGui_ImplSdlGL2_RenderDrawLists(ImDrawData* draw_data) glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); } -static const char* ImGui_ImplSdl_GetClipboardText(void*) +static const char* ImGui_ImplSdlGL2_GetClipboardText(void*) { return SDL_GetClipboardText(); } -static void ImGui_ImplSdl_SetClipboardText(void*, const char* text) +static void ImGui_ImplSdlGL2_SetClipboardText(void*, const char* text) { SDL_SetClipboardText(text); } @@ -227,8 +227,8 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) io.KeyMap[ImGuiKey_Z] = SDLK_z; io.RenderDrawListsFn = ImGui_ImplSdlGL2_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; + io.SetClipboardTextFn = ImGui_ImplSdlGL2_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplSdlGL2_GetClipboardText; io.ClipboardUserData = NULL; #ifdef _WIN32 @@ -267,7 +267,7 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) // Setup time step Uint32 time = SDL_GetTicks(); double current_time = time / 1000.0; - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f); g_Time = current_time; // Setup inputs From f3e510a9bf508337244433f8c1dcc6c120dcc990 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 10:46:54 +0100 Subject: [PATCH 14/17] Examples: SDL: Using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. (#1559) Digging into sdl window/mouse stuff will also be useful for multi-viewport work. --- .../imgui_impl_sdl_gl2.cpp | 28 +++++++++++------ .../imgui_impl_sdl_gl3.cpp | 30 ++++++++++++------- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index 802a31be..6bcd4c38 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -270,23 +270,33 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f); g_Time = current_time; - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) + // Setup mouse inputs (we already got mouse wheel, keyboard keys & characters from our event handler) int mx, my; Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); - if (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) - io.MousePos = ImVec2((float)mx, (float)my); - else - io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX); - + io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + io.MouseWheel = g_MouseWheel; io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; - - io.MouseWheel = g_MouseWheel; g_MouseWheel = 0.0f; + // We need to use SDL_CaptureMouse() to easily retrieve mouse coordinates outside of the client area. This is only supported from SDL 2.0.4 (released Jan 2016) +#if (SDL_MAJOR_VERSION >= 2) && (SDL_MINOR_VERSION >= 0) && (SDL_PATCHLEVEL >= 4) + if ((SDL_GetWindowFlags(window) & (SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_MOUSE_CAPTURE)) != 0) + io.MousePos = ImVec2((float)mx, (float)my); + bool any_mouse_button_down = false; + for (int n = 0; n < IM_ARRAYSIZE(io.MouseDown); n++) + any_mouse_button_down |= io.MouseDown[n]; + if (any_mouse_button_down && (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_CAPTURE) == 0) + SDL_CaptureMouse(SDL_TRUE); + if (!any_mouse_button_down && (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_CAPTURE) != 0) + SDL_CaptureMouse(SDL_FALSE); +#else + if ((SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) != 0) + io.MousePos = ImVec2((float)mx, (float)my); +#endif + // Hide OS mouse cursor if ImGui is drawing it SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index e9a1393c..ef1957a5 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -381,23 +381,33 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f); g_Time = current_time; - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) + // Setup mouse inputs (we already got mouse wheel, keyboard keys & characters from our event handler) int mx, my; Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); - if (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) - io.MousePos = ImVec2((float)mx, (float)my); - else - io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - - io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + io.MouseWheel = g_MouseWheel; + io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. io.MouseDown[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; - - io.MouseWheel = g_MouseWheel; g_MouseWheel = 0.0f; + // We need to use SDL_CaptureMouse() to easily retrieve mouse coordinates outside of the client area. This is only supported from SDL 2.0.4 (released Jan 2016) +#if (SDL_MAJOR_VERSION >= 2) && (SDL_MINOR_VERSION >= 0) && (SDL_PATCHLEVEL >= 4) + if ((SDL_GetWindowFlags(window) & (SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_MOUSE_CAPTURE)) != 0) + io.MousePos = ImVec2((float)mx, (float)my); + bool any_mouse_button_down = false; + for (int n = 0; n < IM_ARRAYSIZE(io.MouseDown); n++) + any_mouse_button_down |= io.MouseDown[n]; + if (any_mouse_button_down && (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_CAPTURE) == 0) + SDL_CaptureMouse(SDL_TRUE); + if (!any_mouse_button_down && (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_CAPTURE) != 0) + SDL_CaptureMouse(SDL_FALSE); +#else + if ((SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) != 0) + io.MousePos = ImVec2((float)mx, (float)my); +#endif + // Hide OS mouse cursor if ImGui is drawing it SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); From 0978f00911df253196b0a013b77adc4c8202fdcb Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 15:06:39 +0100 Subject: [PATCH 15/17] MovingWindow: Track click offset based on root window (undo 514d30d8cdd659b6af3c93512583a00ee18ecbaf). This should not affect the patch used for #1345 as the RootWindow for Child+Tooltip window points to itself now. --- imgui.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7dbc92c1..41ce93da 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2393,11 +2393,8 @@ void ImGui::NewFrame() if (g.IO.MouseDown[0]) { // MovingWindow = window we clicked on, could be a child window. We track it to preserve Focus and so that ActiveIdWindow == MovingWindow and ActiveId == MovingWindow->MoveId for consistency. - // actually_moving_window = MovingWindow->RootWindow. ImGuiWindow* actually_moving_window = g.MovingWindow->RootWindow; ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset; - if (actually_moving_window != g.MovingWindow) - pos += actually_moving_window->PosFloat - g.MovingWindow->PosFloat; if (actually_moving_window->PosFloat.x != pos.x || actually_moving_window->PosFloat.y != pos.y) { MarkIniSettingsDirty(actually_moving_window); @@ -2979,7 +2976,7 @@ void ImGui::EndFrame() // Set ActiveId even if the _NoMove flag is set, without it dragging away from a window with _NoMove would activate hover on other windows. FocusWindow(g.HoveredWindow); SetActiveID(g.HoveredWindow->MoveId, g.HoveredWindow); - g.ActiveIdClickOffset = g.IO.MousePos - g.HoveredWindow->Pos; + g.ActiveIdClickOffset = g.IO.MousePos - g.HoveredRootWindow->Pos; if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoMove)) { g.MovingWindow = g.HoveredWindow; From 42a612d7c9fa69fc87e0fd37eef800e7b875add1 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 15:33:35 +0100 Subject: [PATCH 16/17] Begin: Removed asserts that got in the way of some flags combination. (#1345) --- imgui.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 41ce93da..b38120bd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4649,12 +4649,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Apply minimum/maximum window size constraints and final size window->SizeFull = CalcSizeAfterConstraint(window, window->SizeFull); - window->Size = window->Collapsed ? window->TitleBarRect().GetSize() : window->SizeFull; - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) - { - IM_ASSERT(window_size_x_set_by_api && window_size_y_set_by_api); // Submitted by BeginChild() - window->Size = window->SizeFull; - } + window->Size = window->Collapsed && !(flags & ImGuiWindowFlags_ChildWindow) ? window->TitleBarRect().GetSize() : window->SizeFull; // SCROLLBAR STATUS From e5a6e85f6d24da8506f8141f258c9f4f0c9d3281 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 15:37:25 +0100 Subject: [PATCH 17/17] Basic undocumented/unsupported combination of Child+Tooltip. The full feature needs substancially more work but this is enough for simplest cases. (#1345) --- imgui.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b38120bd..ca142754 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4560,10 +4560,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // When reusing window again multiple times a frame, just append content (don't need to setup again) if (first_begin_of_the_frame) { + const bool is_pinned_child_tooltip = (flags & ImGuiWindowFlags_ChildWindow) && (flags & ImGuiWindowFlags_Tooltip); // FIXME-WIP: Undocumented behavior of Child+Tooltip for pinned tooltip (#1345) + // Initialize window->ParentWindow = parent_window; window->RootWindow = window->RootNonPopupWindow = window; - if (parent_window && (flags & ImGuiWindowFlags_ChildWindow)) + if (parent_window && (flags & ImGuiWindowFlags_ChildWindow) && !is_pinned_child_tooltip) window->RootWindow = parent_window->RootWindow; if (parent_window && !(flags & ImGuiWindowFlags_Modal) && (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup))) window->RootNonPopupWindow = parent_window->RootNonPopupWindow; @@ -4681,8 +4683,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { window->BeginOrderWithinParent = parent_window->DC.ChildWindows.Size; parent_window->DC.ChildWindows.push_back(window); - - if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api) + if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api && !is_pinned_child_tooltip) window->Pos = window->PosFloat = parent_window->DC.CursorPos; } @@ -4713,7 +4714,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } // Position tooltip (always follows mouse) - if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api) + if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api && !is_pinned_child_tooltip) { ImVec2 ref_pos = g.IO.MousePos; ImRect rect_to_avoid(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24, ref_pos.y + 24); // FIXME: Completely hard-coded. Store boxes in mouse cursor data? Scale? Center on cursor hit-point? @@ -4771,7 +4772,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DrawList->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); ImRect fullscreen_rect(GetVisibleRect()); - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !is_pinned_child_tooltip) PushClipRect(parent_window->ClipRect.Min, parent_window->ClipRect.Max, true); else PushClipRect(fullscreen_rect.Min, fullscreen_rect.Max, true);