|
@@ -1252,7 +1252,7 @@ void ImGuiIO::ClearInputKeys()
|
|
|
KeysData[n].DownDurationPrev = -1.0f;
|
|
KeysData[n].DownDurationPrev = -1.0f;
|
|
|
}
|
|
}
|
|
|
KeyCtrl = KeyShift = KeyAlt = KeySuper = false;
|
|
KeyCtrl = KeyShift = KeyAlt = KeySuper = false;
|
|
|
- KeyMods = KeyModsPrev = ImGuiKeyModFlags_None;
|
|
|
|
|
|
|
+ KeyMods = ImGuiKeyModFlags_None;
|
|
|
for (int n = 0; n < IM_ARRAYSIZE(NavInputsDownDuration); n++)
|
|
for (int n = 0; n < IM_ARRAYSIZE(NavInputsDownDuration); n++)
|
|
|
NavInputsDownDuration[n] = NavInputsDownDurationPrev[n] = -1.0f;
|
|
NavInputsDownDuration[n] = NavInputsDownDurationPrev[n] = -1.0f;
|
|
|
}
|
|
}
|
|
@@ -1323,8 +1323,10 @@ void ImGuiIO::SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native
|
|
|
// Build native->imgui map so old user code can still call key functions with native 0..511 values.
|
|
// Build native->imgui map so old user code can still call key functions with native 0..511 values.
|
|
|
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
|
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
|
|
const int legacy_key = (native_legacy_index != -1) ? native_legacy_index : native_keycode;
|
|
const int legacy_key = (native_legacy_index != -1) ? native_legacy_index : native_keycode;
|
|
|
- if (ImGui::IsLegacyKey(legacy_key))
|
|
|
|
|
- KeyMap[legacy_key] = key;
|
|
|
|
|
|
|
+ if (!ImGui::IsLegacyKey(legacy_key))
|
|
|
|
|
+ return;
|
|
|
|
|
+ KeyMap[legacy_key] = key;
|
|
|
|
|
+ KeyMap[key] = legacy_key;
|
|
|
#else
|
|
#else
|
|
|
IM_UNUSED(key);
|
|
IM_UNUSED(key);
|
|
|
IM_UNUSED(native_legacy_index);
|
|
IM_UNUSED(native_legacy_index);
|
|
@@ -2567,15 +2569,14 @@ void ImGuiListClipper::Begin(int items_count, float items_height)
|
|
|
|
|
|
|
|
void ImGuiListClipper::End()
|
|
void ImGuiListClipper::End()
|
|
|
{
|
|
{
|
|
|
- // In theory here we should assert that we are already at the right position, but it seems saner to just seek at the end and not assert/crash the user.
|
|
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
- if (ItemsCount >= 0 && ItemsCount < INT_MAX && DisplayStart >= 0)
|
|
|
|
|
- ImGuiListClipper_SeekCursorForItem(this, ItemsCount);
|
|
|
|
|
- ItemsCount = -1;
|
|
|
|
|
-
|
|
|
|
|
- // Restore temporary buffer and fix back pointers which may be invalidated when nesting
|
|
|
|
|
if (ImGuiListClipperData* data = (ImGuiListClipperData*)TempData)
|
|
if (ImGuiListClipperData* data = (ImGuiListClipperData*)TempData)
|
|
|
{
|
|
{
|
|
|
|
|
+ // In theory here we should assert that we are already at the right position, but it seems saner to just seek at the end and not assert/crash the user.
|
|
|
|
|
+ if (ItemsCount >= 0 && ItemsCount < INT_MAX && DisplayStart >= 0)
|
|
|
|
|
+ ImGuiListClipper_SeekCursorForItem(this, ItemsCount);
|
|
|
|
|
+
|
|
|
|
|
+ // Restore temporary buffer and fix back pointers which may be invalidated when nesting
|
|
|
IM_ASSERT(data->ListClipper == this);
|
|
IM_ASSERT(data->ListClipper == this);
|
|
|
data->StepNo = data->Ranges.Size;
|
|
data->StepNo = data->Ranges.Size;
|
|
|
if (--g.ClipperTempDataStacked > 0)
|
|
if (--g.ClipperTempDataStacked > 0)
|
|
@@ -2585,6 +2586,7 @@ void ImGuiListClipper::End()
|
|
|
}
|
|
}
|
|
|
TempData = NULL;
|
|
TempData = NULL;
|
|
|
}
|
|
}
|
|
|
|
|
+ ItemsCount = -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void ImGuiListClipper::ForceDisplayRangeByIndices(int item_min, int item_max)
|
|
void ImGuiListClipper::ForceDisplayRangeByIndices(int item_min, int item_max)
|
|
@@ -2601,6 +2603,7 @@ bool ImGuiListClipper::Step()
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
ImGuiWindow* window = g.CurrentWindow;
|
|
ImGuiWindow* window = g.CurrentWindow;
|
|
|
ImGuiListClipperData* data = (ImGuiListClipperData*)TempData;
|
|
ImGuiListClipperData* data = (ImGuiListClipperData*)TempData;
|
|
|
|
|
+ IM_ASSERT(data != NULL && "Called ImGuiListClipper::Step() too many times, or before ImGuiListClipper::Begin() ?");
|
|
|
|
|
|
|
|
ImGuiTable* table = g.CurrentTable;
|
|
ImGuiTable* table = g.CurrentTable;
|
|
|
if (table && table->IsInsideRow)
|
|
if (table && table->IsInsideRow)
|
|
@@ -2717,8 +2720,8 @@ bool ImGuiListClipper::Step()
|
|
|
// Advance the cursor to the end of the list and then returns 'false' to end the loop.
|
|
// Advance the cursor to the end of the list and then returns 'false' to end the loop.
|
|
|
if (ItemsCount < INT_MAX)
|
|
if (ItemsCount < INT_MAX)
|
|
|
ImGuiListClipper_SeekCursorForItem(this, ItemsCount);
|
|
ImGuiListClipper_SeekCursorForItem(this, ItemsCount);
|
|
|
- ItemsCount = -1;
|
|
|
|
|
|
|
|
|
|
|
|
+ End();
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -3476,7 +3479,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
|
|
|
{
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
ImGuiWindow* window = g.CurrentWindow;
|
|
ImGuiWindow* window = g.CurrentWindow;
|
|
|
- if (g.NavDisableMouseHover && !g.NavDisableHighlight)
|
|
|
|
|
|
|
+ if (g.NavDisableMouseHover && !g.NavDisableHighlight && !(flags & ImGuiHoveredFlags_NoNavOverride))
|
|
|
{
|
|
{
|
|
|
if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
|
|
if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
|
|
|
return false;
|
|
return false;
|
|
@@ -3537,8 +3540,6 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
|
|
|
return false;
|
|
return false;
|
|
|
if (!IsMouseHoveringRect(bb.Min, bb.Max))
|
|
if (!IsMouseHoveringRect(bb.Min, bb.Max))
|
|
|
return false;
|
|
return false;
|
|
|
- if (g.NavDisableMouseHover)
|
|
|
|
|
- return false;
|
|
|
|
|
if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
|
|
if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
|
|
|
{
|
|
{
|
|
|
g.HoveredIdDisabled = true;
|
|
g.HoveredIdDisabled = true;
|
|
@@ -3574,6 +3575,9 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
|
|
|
IM_DEBUG_BREAK();
|
|
IM_DEBUG_BREAK();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if (g.NavDisableMouseHover)
|
|
|
|
|
+ return false;
|
|
|
|
|
+
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -3940,16 +3944,13 @@ static void ImGui::UpdateKeyboardInputs()
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
ImGuiIO& io = g.IO;
|
|
ImGuiIO& io = g.IO;
|
|
|
|
|
|
|
|
- // Synchronize io.KeyMods with individual modifiers io.KeyXXX bools
|
|
|
|
|
- io.KeyMods = GetMergedKeyModFlags();
|
|
|
|
|
-
|
|
|
|
|
// Import legacy keys or verify they are not used
|
|
// Import legacy keys or verify they are not used
|
|
|
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
|
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
|
|
if (io.BackendUsingLegacyKeyArrays == 0)
|
|
if (io.BackendUsingLegacyKeyArrays == 0)
|
|
|
{
|
|
{
|
|
|
- // Backend used new io.AddKeyEvent() API: Good! Verify that old arrays are never written too.
|
|
|
|
|
- for (int n = 0; n < IM_ARRAYSIZE(io.KeysDown); n++)
|
|
|
|
|
- IM_ASSERT(io.KeysDown[n] == false && "Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!");
|
|
|
|
|
|
|
+ // Backend used new io.AddKeyEvent() API: Good! Verify that old arrays are never written to externally.
|
|
|
|
|
+ for (int n = 0; n < ImGuiKey_LegacyNativeKey_END; n++)
|
|
|
|
|
+ IM_ASSERT((io.KeysDown[n] == false || IsKeyDown(n)) && "Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!");
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
@@ -3972,6 +3973,8 @@ static void ImGui::UpdateKeyboardInputs()
|
|
|
const ImGuiKey key = (ImGuiKey)(io.KeyMap[n] != -1 ? io.KeyMap[n] : n);
|
|
const ImGuiKey key = (ImGuiKey)(io.KeyMap[n] != -1 ? io.KeyMap[n] : n);
|
|
|
IM_ASSERT(io.KeyMap[n] == -1 || IsNamedKey(key));
|
|
IM_ASSERT(io.KeyMap[n] == -1 || IsNamedKey(key));
|
|
|
io.KeysData[key].Down = io.KeysDown[n];
|
|
io.KeysData[key].Down = io.KeysDown[n];
|
|
|
|
|
+ if (key != n)
|
|
|
|
|
+ io.KeysDown[key] = io.KeysDown[n]; // Allow legacy code using io.KeysDown[GetKeyIndex()] with old backends
|
|
|
io.BackendUsingLegacyKeyArrays = 1;
|
|
io.BackendUsingLegacyKeyArrays = 1;
|
|
|
}
|
|
}
|
|
|
if (io.BackendUsingLegacyKeyArrays == 1)
|
|
if (io.BackendUsingLegacyKeyArrays == 1)
|
|
@@ -3984,6 +3987,9 @@ static void ImGui::UpdateKeyboardInputs()
|
|
|
}
|
|
}
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|
|
+ // Synchronize io.KeyMods with individual modifiers io.KeyXXX bools
|
|
|
|
|
+ io.KeyMods = GetMergedKeyModFlags();
|
|
|
|
|
+
|
|
|
// Clear gamepad data if disabled
|
|
// Clear gamepad data if disabled
|
|
|
if ((io.BackendFlags & ImGuiBackendFlags_HasGamepad) == 0)
|
|
if ((io.BackendFlags & ImGuiBackendFlags_HasGamepad) == 0)
|
|
|
for (int i = ImGuiKey_Gamepad_BEGIN; i < ImGuiKey_Gamepad_END; i++)
|
|
for (int i = ImGuiKey_Gamepad_BEGIN; i < ImGuiKey_Gamepad_END; i++)
|
|
@@ -4866,7 +4872,6 @@ void ImGui::EndFrame()
|
|
|
// Clear Input data for next frame
|
|
// Clear Input data for next frame
|
|
|
g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f;
|
|
g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f;
|
|
|
g.IO.InputQueueCharacters.resize(0);
|
|
g.IO.InputQueueCharacters.resize(0);
|
|
|
- g.IO.KeyModsPrev = g.IO.KeyMods; // doing it here is better than in NewFrame() as we'll tolerate backend writing to KeyMods. If we want to firmly disallow it we should detect it.
|
|
|
|
|
memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs));
|
|
memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs));
|
|
|
|
|
|
|
|
CallContextHooks(&g, ImGuiContextHookType_EndFramePost);
|
|
CallContextHooks(&g, ImGuiContextHookType_EndFramePost);
|
|
@@ -7659,14 +7664,8 @@ bool ImGui::IsMouseClicked(ImGuiMouseButton button, bool repeat)
|
|
|
const float t = g.IO.MouseDownDuration[button];
|
|
const float t = g.IO.MouseDownDuration[button];
|
|
|
if (t == 0.0f)
|
|
if (t == 0.0f)
|
|
|
return true;
|
|
return true;
|
|
|
-
|
|
|
|
|
if (repeat && t > g.IO.KeyRepeatDelay)
|
|
if (repeat && t > g.IO.KeyRepeatDelay)
|
|
|
- {
|
|
|
|
|
- // FIXME: 2019/05/03: Our old repeat code was wrong here and led to doubling the repeat rate, which made it an ok rate for repeat on mouse hold.
|
|
|
|
|
- int amount = CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate * 0.50f);
|
|
|
|
|
- if (amount > 0)
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0;
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -7802,8 +7801,18 @@ static const char* GetInputSourceName(ImGuiInputSource source)
|
|
|
return input_source_names[source];
|
|
return input_source_names[source];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/*static void DebugLogInputEvent(const char* prefix, const ImGuiInputEvent* e)
|
|
|
|
|
+{
|
|
|
|
|
+ if (e->Type == ImGuiInputEventType_MousePos) { IMGUI_DEBUG_LOG("%s: MousePos (%.1f %.1f)\n", prefix, e->MousePos.PosX, e->MousePos.PosY); return; }
|
|
|
|
|
+ if (e->Type == ImGuiInputEventType_MouseButton) { IMGUI_DEBUG_LOG("%s: MouseButton %d %s\n", prefix, e->MouseButton.Button, e->MouseButton.Down ? "Down" : "Up"); return; }
|
|
|
|
|
+ if (e->Type == ImGuiInputEventType_MouseWheel) { IMGUI_DEBUG_LOG("%s: MouseWheel (%.1f %.1f)\n", prefix, e->MouseWheel.WheelX, e->MouseWheel.WheelY); return; }
|
|
|
|
|
+ if (e->Type == ImGuiInputEventType_Key) { IMGUI_DEBUG_LOG("%s: Key \"%s\" %s\n", prefix, ImGui::GetKeyName(e->Key.Key), e->Key.Down ? "Down" : "Up"); return; }
|
|
|
|
|
+ if (e->Type == ImGuiInputEventType_Text) { IMGUI_DEBUG_LOG("%s: Text: %c (U+%08X)\n", prefix, e->Text.Char, e->Text.Char); return; }
|
|
|
|
|
+ if (e->Type == ImGuiInputEventType_Focus) { IMGUI_DEBUG_LOG("%s: AppFocused %d\n", prefix, e->AppFocused.Focused); return; }
|
|
|
|
|
+}*/
|
|
|
|
|
|
|
|
// Process input queue
|
|
// Process input queue
|
|
|
|
|
+// We always call this with the value of 'bool g.IO.ConfigInputTrickleEventQueue'.
|
|
|
// - trickle_fast_inputs = false : process all events, turn into flattened input state (e.g. successive down/up/down/up will be lost)
|
|
// - trickle_fast_inputs = false : process all events, turn into flattened input state (e.g. successive down/up/down/up will be lost)
|
|
|
// - trickle_fast_inputs = true : process as many events as possible (successive down/up/down/up will be trickled over several frames so nothing is lost) (new feature in 1.87)
|
|
// - trickle_fast_inputs = true : process as many events as possible (successive down/up/down/up will be trickled over several frames so nothing is lost) (new feature in 1.87)
|
|
|
void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
|
void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
|
@@ -7811,7 +7820,12 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
ImGuiIO& io = g.IO;
|
|
ImGuiIO& io = g.IO;
|
|
|
|
|
|
|
|
- bool mouse_moved = false, mouse_wheeled = false, key_changed = false, text_inputed = false;
|
|
|
|
|
|
|
+ // Only trickle chars<>key when working with InputText()
|
|
|
|
|
+ // FIXME: InputText() could parse event trail?
|
|
|
|
|
+ // FIXME: Could specialize chars<>keys trickling rules for control keys (those not typically associated to characters)
|
|
|
|
|
+ const bool trickle_interleaved_keys_and_text = (trickle_fast_inputs && g.WantTextInputNextFrame == 1);
|
|
|
|
|
+
|
|
|
|
|
+ bool mouse_moved = false, mouse_wheeled = false, key_changed = false, text_inputted = false;
|
|
|
int mouse_button_changed = 0x00;
|
|
int mouse_button_changed = 0x00;
|
|
|
ImBitArray<ImGuiKey_KeysData_SIZE> key_changed_mask;
|
|
ImBitArray<ImGuiKey_KeysData_SIZE> key_changed_mask;
|
|
|
|
|
|
|
@@ -7827,7 +7841,7 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
|
|
if (io.MousePos.x != event_pos.x || io.MousePos.y != event_pos.y)
|
|
if (io.MousePos.x != event_pos.x || io.MousePos.y != event_pos.y)
|
|
|
{
|
|
{
|
|
|
// Trickling Rule: Stop processing queued events if we already handled a mouse button change
|
|
// Trickling Rule: Stop processing queued events if we already handled a mouse button change
|
|
|
- if (trickle_fast_inputs && (mouse_button_changed != 0 || mouse_wheeled || key_changed || text_inputed))
|
|
|
|
|
|
|
+ if (trickle_fast_inputs && (mouse_button_changed != 0 || mouse_wheeled || key_changed || text_inputted))
|
|
|
break;
|
|
break;
|
|
|
io.MousePos = event_pos;
|
|
io.MousePos = event_pos;
|
|
|
mouse_moved = true;
|
|
mouse_moved = true;
|
|
@@ -7867,7 +7881,7 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
|
|
if (keydata->Down != e->Key.Down || keydata->AnalogValue != e->Key.AnalogValue)
|
|
if (keydata->Down != e->Key.Down || keydata->AnalogValue != e->Key.AnalogValue)
|
|
|
{
|
|
{
|
|
|
// Trickling Rule: Stop processing queued events if we got multiple action on the same button
|
|
// Trickling Rule: Stop processing queued events if we got multiple action on the same button
|
|
|
- if (trickle_fast_inputs && keydata->Down != e->Key.Down && (key_changed_mask.TestBit(keydata_index) || text_inputed || mouse_button_changed != 0))
|
|
|
|
|
|
|
+ if (trickle_fast_inputs && keydata->Down != e->Key.Down && (key_changed_mask.TestBit(keydata_index) || text_inputted || mouse_button_changed != 0))
|
|
|
break;
|
|
break;
|
|
|
keydata->Down = e->Key.Down;
|
|
keydata->Down = e->Key.Down;
|
|
|
keydata->AnalogValue = e->Key.AnalogValue;
|
|
keydata->AnalogValue = e->Key.AnalogValue;
|
|
@@ -7882,16 +7896,24 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
|
|
if (key == ImGuiKey_ModSuper) { io.KeySuper = keydata->Down; }
|
|
if (key == ImGuiKey_ModSuper) { io.KeySuper = keydata->Down; }
|
|
|
io.KeyMods = GetMergedKeyModFlags();
|
|
io.KeyMods = GetMergedKeyModFlags();
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // Allow legacy code using io.KeysDown[GetKeyIndex()] with new backends
|
|
|
|
|
+#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
|
|
|
|
+ io.KeysDown[key] = keydata->Down;
|
|
|
|
|
+ if (io.KeyMap[key] != -1)
|
|
|
|
|
+ io.KeysDown[io.KeyMap[key]] = keydata->Down;
|
|
|
|
|
+#endif
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
else if (e->Type == ImGuiInputEventType_Text)
|
|
else if (e->Type == ImGuiInputEventType_Text)
|
|
|
{
|
|
{
|
|
|
// Trickling Rule: Stop processing queued events if keys/mouse have been interacted with
|
|
// Trickling Rule: Stop processing queued events if keys/mouse have been interacted with
|
|
|
- if (trickle_fast_inputs && (key_changed || mouse_button_changed != 0 || mouse_moved || mouse_wheeled))
|
|
|
|
|
|
|
+ if (trickle_fast_inputs && ((key_changed && trickle_interleaved_keys_and_text) || mouse_button_changed != 0 || mouse_moved || mouse_wheeled))
|
|
|
break;
|
|
break;
|
|
|
unsigned int c = e->Text.Char;
|
|
unsigned int c = e->Text.Char;
|
|
|
io.InputQueueCharacters.push_back(c <= IM_UNICODE_CODEPOINT_MAX ? (ImWchar)c : IM_UNICODE_CODEPOINT_INVALID);
|
|
io.InputQueueCharacters.push_back(c <= IM_UNICODE_CODEPOINT_MAX ? (ImWchar)c : IM_UNICODE_CODEPOINT_INVALID);
|
|
|
- text_inputed = true;
|
|
|
|
|
|
|
+ if (trickle_interleaved_keys_and_text)
|
|
|
|
|
+ text_inputted = true;
|
|
|
}
|
|
}
|
|
|
else if (e->Type == ImGuiInputEventType_Focus)
|
|
else if (e->Type == ImGuiInputEventType_Focus)
|
|
|
{
|
|
{
|
|
@@ -7910,6 +7932,11 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
|
|
for (int n = 0; n < event_n; n++)
|
|
for (int n = 0; n < event_n; n++)
|
|
|
g.InputEventsTrail.push_back(g.InputEventsQueue[n]);
|
|
g.InputEventsTrail.push_back(g.InputEventsQueue[n]);
|
|
|
|
|
|
|
|
|
|
+ // [DEBUG]
|
|
|
|
|
+ /*if (event_n != 0)
|
|
|
|
|
+ for (int n = 0; n < g.InputEventsQueue.Size; n++)
|
|
|
|
|
+ DebugLogInputEvent(n < event_n ? "Processed" : "Remaining", &g.InputEventsQueue[n]);*/
|
|
|
|
|
+
|
|
|
// Remaining events will be processed on the next frame
|
|
// Remaining events will be processed on the next frame
|
|
|
if (event_n == g.InputEventsQueue.Size)
|
|
if (event_n == g.InputEventsQueue.Size)
|
|
|
g.InputEventsQueue.resize(0);
|
|
g.InputEventsQueue.resize(0);
|
|
@@ -7974,7 +8001,7 @@ static void ImGui::ErrorCheckNewFrameSanityChecks()
|
|
|
IM_ASSERT(g.Style.WindowMenuButtonPosition == ImGuiDir_None || g.Style.WindowMenuButtonPosition == ImGuiDir_Left || g.Style.WindowMenuButtonPosition == ImGuiDir_Right);
|
|
IM_ASSERT(g.Style.WindowMenuButtonPosition == ImGuiDir_None || g.Style.WindowMenuButtonPosition == ImGuiDir_Left || g.Style.WindowMenuButtonPosition == ImGuiDir_Right);
|
|
|
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
|
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
|
|
for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_COUNT; n++)
|
|
for (int n = ImGuiKey_NamedKey_BEGIN; 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..511, or -1 for unmapped key)");
|
|
|
|
|
|
|
+ IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < ImGuiKey_LegacyNativeKey_END && "io.KeyMap[] contains an out of bound value (need to be 0..511, or -1 for unmapped key)");
|
|
|
|
|
|
|
|
// Check: required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was only added in 1.60 WIP)
|
|
// Check: required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was only added in 1.60 WIP)
|
|
|
if ((g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && g.IO.BackendUsingLegacyKeyArrays == 1)
|
|
if ((g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && g.IO.BackendUsingLegacyKeyArrays == 1)
|
|
@@ -10798,7 +10825,7 @@ static void ImGui::NavUpdateWindowing()
|
|
|
// - Testing that only Alt is tested prevents Alt+Shift or AltGR from toggling menu layer.
|
|
// - Testing that only Alt is tested prevents Alt+Shift or AltGR from toggling menu layer.
|
|
|
// - AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl). But even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway.
|
|
// - AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl). But even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway.
|
|
|
const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
|
|
const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
|
|
|
- if (nav_keyboard_active && io.KeyMods == ImGuiKeyModFlags_Alt && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) == 0)
|
|
|
|
|
|
|
+ if (nav_keyboard_active && IsKeyPressed(ImGuiKey_ModAlt))
|
|
|
{
|
|
{
|
|
|
g.NavWindowingToggleLayer = true;
|
|
g.NavWindowingToggleLayer = true;
|
|
|
g.NavInputSource = ImGuiInputSource_Keyboard;
|
|
g.NavInputSource = ImGuiInputSource_Keyboard;
|
|
@@ -10811,13 +10838,12 @@ static void ImGui::NavUpdateWindowing()
|
|
|
g.NavWindowingToggleLayer = false;
|
|
g.NavWindowingToggleLayer = false;
|
|
|
|
|
|
|
|
// Apply layer toggle on release
|
|
// Apply layer toggle on release
|
|
|
- // Important: we don't assume that Alt was previously held in order to handle loss of focus when backend calls io.AddFocusEvent(false)
|
|
|
|
|
// Important: as before version <18314 we lacked an explicit IO event for focus gain/loss, we also compare mouse validity to detect old backends clearing mouse pos on focus loss.
|
|
// Important: as before version <18314 we lacked an explicit IO event for focus gain/loss, we also compare mouse validity to detect old backends clearing mouse pos on focus loss.
|
|
|
- if (!(io.KeyMods & ImGuiKeyModFlags_Alt) && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) && g.NavWindowingToggleLayer)
|
|
|
|
|
|
|
+ if (IsKeyReleased(ImGuiKey_ModAlt) && g.NavWindowingToggleLayer)
|
|
|
if (g.ActiveId == 0 || g.ActiveIdAllowOverlap)
|
|
if (g.ActiveId == 0 || g.ActiveIdAllowOverlap)
|
|
|
if (IsMousePosValid(&io.MousePos) == IsMousePosValid(&io.MousePosPrev))
|
|
if (IsMousePosValid(&io.MousePos) == IsMousePosValid(&io.MousePosPrev))
|
|
|
apply_toggle_layer = true;
|
|
apply_toggle_layer = true;
|
|
|
- if (!io.KeyAlt)
|
|
|
|
|
|
|
+ if (!IsKeyDown(ImGuiKey_ModAlt))
|
|
|
g.NavWindowingToggleLayer = false;
|
|
g.NavWindowingToggleLayer = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -12149,19 +12175,20 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
{
|
|
{
|
|
|
static ImRect GetTableRect(ImGuiTable* table, int rect_type, int n)
|
|
static ImRect GetTableRect(ImGuiTable* table, int rect_type, int n)
|
|
|
{
|
|
{
|
|
|
|
|
+ ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent); // Always using last submitted instance
|
|
|
if (rect_type == TRT_OuterRect) { return table->OuterRect; }
|
|
if (rect_type == TRT_OuterRect) { return table->OuterRect; }
|
|
|
else if (rect_type == TRT_InnerRect) { return table->InnerRect; }
|
|
else if (rect_type == TRT_InnerRect) { return table->InnerRect; }
|
|
|
else if (rect_type == TRT_WorkRect) { return table->WorkRect; }
|
|
else if (rect_type == TRT_WorkRect) { return table->WorkRect; }
|
|
|
else if (rect_type == TRT_HostClipRect) { return table->HostClipRect; }
|
|
else if (rect_type == TRT_HostClipRect) { return table->HostClipRect; }
|
|
|
else if (rect_type == TRT_InnerClipRect) { return table->InnerClipRect; }
|
|
else if (rect_type == TRT_InnerClipRect) { return table->InnerClipRect; }
|
|
|
else if (rect_type == TRT_BackgroundClipRect) { return table->BgClipRect; }
|
|
else if (rect_type == TRT_BackgroundClipRect) { return table->BgClipRect; }
|
|
|
- else if (rect_type == TRT_ColumnsRect) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->MinX, table->InnerClipRect.Min.y, c->MaxX, table->InnerClipRect.Min.y + table->LastOuterHeight); }
|
|
|
|
|
|
|
+ else if (rect_type == TRT_ColumnsRect) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->MinX, table->InnerClipRect.Min.y, c->MaxX, table->InnerClipRect.Min.y + table_instance->LastOuterHeight); }
|
|
|
else if (rect_type == TRT_ColumnsWorkRect) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->WorkRect.Min.y, c->WorkMaxX, table->WorkRect.Max.y); }
|
|
else if (rect_type == TRT_ColumnsWorkRect) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->WorkRect.Min.y, c->WorkMaxX, table->WorkRect.Max.y); }
|
|
|
else if (rect_type == TRT_ColumnsClipRect) { ImGuiTableColumn* c = &table->Columns[n]; return c->ClipRect; }
|
|
else if (rect_type == TRT_ColumnsClipRect) { ImGuiTableColumn* c = &table->Columns[n]; return c->ClipRect; }
|
|
|
- else if (rect_type == TRT_ColumnsContentHeadersUsed){ ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersUsed, table->InnerClipRect.Min.y + table->LastFirstRowHeight); } // Note: y1/y2 not always accurate
|
|
|
|
|
- else if (rect_type == TRT_ColumnsContentHeadersIdeal){ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersIdeal, table->InnerClipRect.Min.y + table->LastFirstRowHeight); }
|
|
|
|
|
- else if (rect_type == TRT_ColumnsContentFrozen) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXFrozen, table->InnerClipRect.Min.y + table->LastFirstRowHeight); }
|
|
|
|
|
- else if (rect_type == TRT_ColumnsContentUnfrozen) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y + table->LastFirstRowHeight, c->ContentMaxXUnfrozen, table->InnerClipRect.Max.y); }
|
|
|
|
|
|
|
+ else if (rect_type == TRT_ColumnsContentHeadersUsed){ ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersUsed, table->InnerClipRect.Min.y + table_instance->LastFirstRowHeight); } // Note: y1/y2 not always accurate
|
|
|
|
|
+ else if (rect_type == TRT_ColumnsContentHeadersIdeal){ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersIdeal, table->InnerClipRect.Min.y + table_instance->LastFirstRowHeight); }
|
|
|
|
|
+ else if (rect_type == TRT_ColumnsContentFrozen) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXFrozen, table->InnerClipRect.Min.y + table_instance->LastFirstRowHeight); }
|
|
|
|
|
+ else if (rect_type == TRT_ColumnsContentUnfrozen) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y + table_instance->LastFirstRowHeight, c->ContentMaxXUnfrozen, table->InnerClipRect.Max.y); }
|
|
|
IM_ASSERT(0);
|
|
IM_ASSERT(0);
|
|
|
return ImRect();
|
|
return ImRect();
|
|
|
}
|
|
}
|
|
@@ -12428,7 +12455,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
|
|
Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
|
|
|
|
|
|
|
|
int active_id_using_key_input_count = 0;
|
|
int active_id_using_key_input_count = 0;
|
|
|
- for (int n = 0; n < ImGuiKey_NamedKey_COUNT; n++)
|
|
|
|
|
|
|
+ for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_NamedKey_END; n++)
|
|
|
active_id_using_key_input_count += g.ActiveIdUsingKeyInputMask[n] ? 1 : 0;
|
|
active_id_using_key_input_count += g.ActiveIdUsingKeyInputMask[n] ? 1 : 0;
|
|
|
Text("ActiveIdUsing: Wheel: %d, NavDirMask: %X, NavInputMask: %X, KeyInputMask: %d key(s)", g.ActiveIdUsingMouseWheel, g.ActiveIdUsingNavDirMask, g.ActiveIdUsingNavInputMask, active_id_using_key_input_count);
|
|
Text("ActiveIdUsing: Wheel: %d, NavDirMask: %X, NavInputMask: %X, KeyInputMask: %d key(s)", g.ActiveIdUsingMouseWheel, g.ActiveIdUsingNavDirMask, g.ActiveIdUsingNavInputMask, active_id_using_key_input_count);
|
|
|
Text("HoveredId: 0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Not displaying g.HoveredId as it is update mid-frame
|
|
Text("HoveredId: 0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Not displaying g.HoveredId as it is update mid-frame
|