mirror of
https://github.com/ocornut/imgui.git
synced 2026-03-30 13:05:23 -05:00
Merge branch 'master' into docking
This commit is contained in:
103
imgui.cpp
103
imgui.cpp
@@ -1385,9 +1385,9 @@ void ImGuiIO::ClearInputKeys()
|
||||
MouseWheel = MouseWheelH = 0.0f;
|
||||
}
|
||||
|
||||
static ImGuiInputEvent* FindLatestInputEvent(ImGuiInputEventType type, int arg = -1)
|
||||
static ImGuiInputEvent* FindLatestInputEvent(ImGuiContext* ctx, ImGuiInputEventType type, int arg = -1)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiContext& g = *ctx;
|
||||
for (int n = g.InputEventsQueue.Size - 1; n >= 0; n--)
|
||||
{
|
||||
ImGuiInputEvent* e = &g.InputEventsQueue[n];
|
||||
@@ -1406,6 +1406,8 @@ static ImGuiInputEvent* FindLatestInputEvent(ImGuiInputEventType type, int arg =
|
||||
// - ImGuiKey key: Translated key (as in, generally ImGuiKey_A matches the key end-user would use to emit an 'A' character)
|
||||
// - bool down: Is the key down? use false to signify a key release.
|
||||
// - float analog_value: 0.0f..1.0f
|
||||
// IMPORTANT: THIS FUNCTION AND OTHER "ADD" GRABS THE CONTEXT FROM OUR INSTANCE.
|
||||
// WE NEED TO ENSURE THAT ALL FUNCTION CALLS ARE FULLFILLING THIS, WHICH IS WHY GetKeyData() HAS AN EXPLICIT CONTEXT.
|
||||
void ImGuiIO::AddKeyAnalogEvent(ImGuiKey key, bool down, float analog_value)
|
||||
{
|
||||
//if (e->Down) { IMGUI_DEBUG_LOG_IO("AddKeyEvent() Key='%s' %d, NativeKeycode = %d, NativeScancode = %d\n", ImGui::GetKeyName(e->Key), e->Down, e->NativeKeycode, e->NativeScancode); }
|
||||
@@ -1414,7 +1416,7 @@ void ImGuiIO::AddKeyAnalogEvent(ImGuiKey key, bool down, float analog_value)
|
||||
return;
|
||||
ImGuiContext& g = *Ctx;
|
||||
IM_ASSERT(ImGui::IsNamedKeyOrModKey(key)); // Backend needs to pass a valid ImGuiKey_ constant. 0..511 values are legacy native key codes which are not accepted by this API.
|
||||
IM_ASSERT(!ImGui::IsAliasKey(key)); // Backend cannot submit ImGuiKey_MouseXXX values they are automatically inferred from AddMouseXXX() events.
|
||||
IM_ASSERT(ImGui::IsAliasKey(key) == false); // Backend cannot submit ImGuiKey_MouseXXX values they are automatically inferred from AddMouseXXX() events.
|
||||
IM_ASSERT(key != ImGuiMod_Shortcut); // We could easily support the translation here but it seems saner to not accept it (TestEngine perform a translation itself)
|
||||
|
||||
// Verify that backend isn't mixing up using new io.AddKeyEvent() api and old io.KeysDown[] + io.KeyMap[] data.
|
||||
@@ -1429,8 +1431,8 @@ void ImGuiIO::AddKeyAnalogEvent(ImGuiKey key, bool down, float analog_value)
|
||||
BackendUsingLegacyNavInputArray = false;
|
||||
|
||||
// Filter duplicate (in particular: key mods and gamepad analog values are commonly spammed)
|
||||
const ImGuiInputEvent* latest_event = FindLatestInputEvent(ImGuiInputEventType_Key, (int)key);
|
||||
const ImGuiKeyData* key_data = ImGui::GetKeyData(key);
|
||||
const ImGuiInputEvent* latest_event = FindLatestInputEvent(&g, ImGuiInputEventType_Key, (int)key);
|
||||
const ImGuiKeyData* key_data = ImGui::GetKeyData(&g, key);
|
||||
const bool latest_key_down = latest_event ? latest_event->Key.Down : key_data->Down;
|
||||
const float latest_key_analog = latest_event ? latest_event->Key.AnalogValue : key_data->AnalogValue;
|
||||
if (latest_key_down == down && latest_key_analog == analog_value)
|
||||
@@ -1496,7 +1498,7 @@ void ImGuiIO::AddMousePosEvent(float x, float y)
|
||||
ImVec2 pos((x > -FLT_MAX) ? ImFloorSigned(x) : x, (y > -FLT_MAX) ? ImFloorSigned(y) : y);
|
||||
|
||||
// Filter duplicate
|
||||
const ImGuiInputEvent* latest_event = FindLatestInputEvent(ImGuiInputEventType_MousePos);
|
||||
const ImGuiInputEvent* latest_event = FindLatestInputEvent(&g, ImGuiInputEventType_MousePos);
|
||||
const ImVec2 latest_pos = latest_event ? ImVec2(latest_event->MousePos.PosX, latest_event->MousePos.PosY) : g.IO.MousePos;
|
||||
if (latest_pos.x == pos.x && latest_pos.y == pos.y)
|
||||
return;
|
||||
@@ -1518,7 +1520,7 @@ void ImGuiIO::AddMouseButtonEvent(int mouse_button, bool down)
|
||||
return;
|
||||
|
||||
// Filter duplicate
|
||||
const ImGuiInputEvent* latest_event = FindLatestInputEvent(ImGuiInputEventType_MouseButton, (int)mouse_button);
|
||||
const ImGuiInputEvent* latest_event = FindLatestInputEvent(&g, ImGuiInputEventType_MouseButton, (int)mouse_button);
|
||||
const bool latest_button_down = latest_event ? latest_event->MouseButton.Down : g.IO.MouseDown[mouse_button];
|
||||
if (latest_button_down == down)
|
||||
return;
|
||||
@@ -1551,14 +1553,14 @@ void ImGuiIO::AddMouseWheelEvent(float wheel_x, float wheel_y)
|
||||
|
||||
void ImGuiIO::AddMouseViewportEvent(ImGuiID viewport_id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
|
||||
IM_ASSERT(Ctx != NULL);
|
||||
ImGuiContext& g = *Ctx;
|
||||
IM_ASSERT(g.IO.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport);
|
||||
if (!AppAcceptingEvents)
|
||||
return;
|
||||
|
||||
// Filter duplicate
|
||||
const ImGuiInputEvent* latest_event = FindLatestInputEvent(ImGuiInputEventType_MouseViewport);
|
||||
const ImGuiInputEvent* latest_event = FindLatestInputEvent(&g, ImGuiInputEventType_MouseViewport);
|
||||
const ImGuiID latest_viewport_id = latest_event ? latest_event->MouseViewport.HoveredViewportID : g.IO.MouseHoveredViewport;
|
||||
if (latest_viewport_id == viewport_id)
|
||||
return;
|
||||
@@ -1576,7 +1578,7 @@ void ImGuiIO::AddFocusEvent(bool focused)
|
||||
ImGuiContext& g = *Ctx;
|
||||
|
||||
// Filter duplicate
|
||||
const ImGuiInputEvent* latest_event = FindLatestInputEvent(ImGuiInputEventType_Focus);
|
||||
const ImGuiInputEvent* latest_event = FindLatestInputEvent(&g, ImGuiInputEventType_Focus);
|
||||
const bool latest_focused = latest_event ? latest_event->AppFocused.Focused : !g.IO.AppFocusLost;
|
||||
if (latest_focused == focused)
|
||||
return;
|
||||
@@ -3666,6 +3668,7 @@ void ImGui::Shutdown()
|
||||
g.ClipboardHandlerData.clear();
|
||||
g.MenusIdSubmittedThisFrame.clear();
|
||||
g.InputTextState.ClearFreeMemory();
|
||||
g.InputTextDeactivatedState.ClearFreeMemory();
|
||||
|
||||
g.SettingsWindows.clear();
|
||||
g.SettingsHandlers.clear();
|
||||
@@ -3844,13 +3847,23 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
// While most behaved code would make an effort to not steal active id during window move/drag operations,
|
||||
// we at least need to be resilient to it. Cancelling the move is rather aggressive and users of 'master' branch
|
||||
// may prefer the weird ill-defined half working situation ('docking' did assert), so may need to rework that.
|
||||
if (g.MovingWindow != NULL && g.ActiveId == g.MovingWindow->MoveId)
|
||||
// Clear previous active id
|
||||
if (g.ActiveId != 0)
|
||||
{
|
||||
IMGUI_DEBUG_LOG_ACTIVEID("SetActiveID() cancel MovingWindow\n");
|
||||
g.MovingWindow = NULL;
|
||||
// While most behaved code would make an effort to not steal active id during window move/drag operations,
|
||||
// we at least need to be resilient to it. Canceling the move is rather aggressive and users of 'master' branch
|
||||
// may prefer the weird ill-defined half working situation ('docking' did assert), so may need to rework that.
|
||||
if (g.MovingWindow != NULL && g.ActiveId == g.MovingWindow->MoveId)
|
||||
{
|
||||
IMGUI_DEBUG_LOG_ACTIVEID("SetActiveID() cancel MovingWindow\n");
|
||||
g.MovingWindow = NULL;
|
||||
}
|
||||
|
||||
// This could be written in a more general way (e.g associate a hook to ActiveId),
|
||||
// but since this is currently quite an exception we'll leave it as is.
|
||||
// One common scenario leading to this is: pressing Key ->NavMoveRequestApplyResult() -> ClearActiveId()
|
||||
if (g.InputTextState.ID == g.ActiveId)
|
||||
InputTextDeactivateHook(g.ActiveId);
|
||||
}
|
||||
|
||||
// Set active id
|
||||
@@ -3876,7 +3889,8 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
|
||||
if (id)
|
||||
{
|
||||
g.ActiveIdIsAlive = id;
|
||||
g.ActiveIdSource = (g.NavActivateId == id || g.NavJustMovedToId == id) ? (ImGuiInputSource)ImGuiInputSource_Nav : ImGuiInputSource_Mouse;
|
||||
g.ActiveIdSource = (g.NavActivateId == id || g.NavJustMovedToId == id) ? g.NavInputSource : ImGuiInputSource_Mouse;
|
||||
IM_ASSERT(g.ActiveIdSource != ImGuiInputSource_None);
|
||||
}
|
||||
|
||||
// Clear declaration of inputs claimed by the widget
|
||||
@@ -3924,11 +3938,17 @@ void ImGui::MarkItemEdited(ImGuiID id)
|
||||
// This marking is solely to be able to provide info for IsItemDeactivatedAfterEdit().
|
||||
// ActiveId might have been released by the time we call this (as in the typical press/release button behavior) but still need to fill the data.
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(g.ActiveId == id || g.ActiveId == 0 || g.DragDropActive);
|
||||
IM_UNUSED(id); // Avoid unused variable warnings when asserts are compiled out.
|
||||
if (g.ActiveId == id || g.ActiveId == 0)
|
||||
{
|
||||
g.ActiveIdHasBeenEditedThisFrame = true;
|
||||
g.ActiveIdHasBeenEditedBefore = true;
|
||||
}
|
||||
|
||||
// We accept a MarkItemEdited() on drag and drop targets (see https://github.com/ocornut/imgui/issues/1875#issuecomment-978243343)
|
||||
// We accept 'ActiveIdPreviousFrame == id' for InputText() returning an edit after it has been taken ActiveId away (#4714)
|
||||
IM_ASSERT(g.DragDropActive || g.ActiveId == id || g.ActiveId == 0 || g.ActiveIdPreviousFrame == id);
|
||||
|
||||
//IM_ASSERT(g.CurrentWindow->DC.LastItemId == id);
|
||||
g.ActiveIdHasBeenEditedThisFrame = true;
|
||||
g.ActiveIdHasBeenEditedBefore = true;
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited;
|
||||
}
|
||||
|
||||
@@ -5542,7 +5562,7 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
|
||||
FocusWindow(child_window);
|
||||
NavInitWindow(child_window, false);
|
||||
SetActiveID(id + 1, child_window); // Steal ActiveId with another arbitrary id so that key-press won't activate child item
|
||||
g.ActiveIdSource = ImGuiInputSource_Nav;
|
||||
g.ActiveIdSource = g.NavInputSource;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -8307,13 +8327,13 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max)
|
||||
// - Shortcut() [Internal]
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ImGuiKeyData* ImGui::GetKeyData(ImGuiKey key)
|
||||
ImGuiKeyData* ImGui::GetKeyData(ImGuiContext* ctx, ImGuiKey key)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiContext& g = *ctx;
|
||||
|
||||
// Special storage location for mods
|
||||
if (key & ImGuiMod_Mask_)
|
||||
key = ConvertSingleModFlagToKey(key);
|
||||
key = ConvertSingleModFlagToKey(ctx, key);
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
IM_ASSERT(key >= ImGuiKey_LegacyNativeKey_BEGIN && key < ImGuiKey_NamedKey_END);
|
||||
@@ -8362,22 +8382,22 @@ IM_STATIC_ASSERT(ImGuiKey_NamedKey_COUNT == IM_ARRAYSIZE(GKeyNames));
|
||||
|
||||
const char* ImGui::GetKeyName(ImGuiKey key)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
IM_ASSERT((IsNamedKey(key) || key == ImGuiKey_None) && "Support for user key indices was dropped in favor of ImGuiKey. Please update backend and user code.");
|
||||
#else
|
||||
if (IsLegacyKey(key))
|
||||
{
|
||||
ImGuiIO& io = GetIO();
|
||||
if (io.KeyMap[key] == -1)
|
||||
if (g.IO.KeyMap[key] == -1)
|
||||
return "N/A";
|
||||
IM_ASSERT(IsNamedKey((ImGuiKey)io.KeyMap[key]));
|
||||
key = (ImGuiKey)io.KeyMap[key];
|
||||
IM_ASSERT(IsNamedKey((ImGuiKey)g.IO.KeyMap[key]));
|
||||
key = (ImGuiKey)g.IO.KeyMap[key];
|
||||
}
|
||||
#endif
|
||||
if (key == ImGuiKey_None)
|
||||
return "None";
|
||||
if (key & ImGuiMod_Mask_)
|
||||
key = ConvertSingleModFlagToKey(key);
|
||||
key = ConvertSingleModFlagToKey(&g, key);
|
||||
if (!IsNamedKey(key))
|
||||
return "Unknown";
|
||||
|
||||
@@ -8472,7 +8492,7 @@ static void ImGui::UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt)
|
||||
// Apply routing to owner if there's no owner already (RoutingCurr == None at this point)
|
||||
if (routing_entry->Mods == g.IO.KeyMods)
|
||||
{
|
||||
ImGuiKeyOwnerData* owner_data = ImGui::GetKeyOwnerData(key);
|
||||
ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(&g, key);
|
||||
if (owner_data->OwnerCurr == ImGuiKeyOwner_None)
|
||||
owner_data->OwnerCurr = routing_entry->RoutingCurr;
|
||||
}
|
||||
@@ -8509,7 +8529,7 @@ ImGuiKeyRoutingData* ImGui::GetShortcutRoutingData(ImGuiKeyChord key_chord)
|
||||
ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_);
|
||||
ImGuiKey mods = (ImGuiKey)(key_chord & ImGuiMod_Mask_);
|
||||
if (key == ImGuiKey_None)
|
||||
key = ConvertSingleModFlagToKey(mods);
|
||||
key = ConvertSingleModFlagToKey(&g, mods);
|
||||
IM_ASSERT(IsNamedKey(key));
|
||||
|
||||
// Get (in the majority of case, the linked list will have one element so this should be 2 reads.
|
||||
@@ -9242,7 +9262,7 @@ void ImGui::SetNextFrameWantCaptureMouse(bool want_capture_mouse)
|
||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
static const char* GetInputSourceName(ImGuiInputSource source)
|
||||
{
|
||||
const char* input_source_names[] = { "None", "Mouse", "Keyboard", "Gamepad", "Nav", "Clipboard" };
|
||||
const char* input_source_names[] = { "None", "Mouse", "Keyboard", "Gamepad", "Clipboard" };
|
||||
IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT && source >= 0 && source < ImGuiInputSource_COUNT);
|
||||
return input_source_names[source];
|
||||
}
|
||||
@@ -9389,7 +9409,7 @@ ImGuiID ImGui::GetKeyOwner(ImGuiKey key)
|
||||
return ImGuiKeyOwner_None;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(key);
|
||||
ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(&g, key);
|
||||
ImGuiID owner_id = owner_data->OwnerCurr;
|
||||
|
||||
if (g.ActiveIdUsingAllKeyboardKeys && owner_id != g.ActiveId && owner_id != ImGuiKeyOwner_Any)
|
||||
@@ -9413,7 +9433,7 @@ bool ImGui::TestKeyOwner(ImGuiKey key, ImGuiID owner_id)
|
||||
if (key >= ImGuiKey_Keyboard_BEGIN && key < ImGuiKey_Keyboard_END)
|
||||
return false;
|
||||
|
||||
ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(key);
|
||||
ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(&g, key);
|
||||
if (owner_id == ImGuiKeyOwner_Any)
|
||||
return (owner_data->LockThisFrame == false);
|
||||
|
||||
@@ -9441,7 +9461,8 @@ void ImGui::SetKeyOwner(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags)
|
||||
IM_ASSERT(IsNamedKeyOrModKey(key) && (owner_id != ImGuiKeyOwner_Any || (flags & (ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease)))); // Can only use _Any with _LockXXX flags (to eat a key away without an ID to retrieve it)
|
||||
IM_ASSERT((flags & ~ImGuiInputFlags_SupportedBySetKeyOwner) == 0); // Passing flags not supported by this function!
|
||||
|
||||
ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(key);
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(&g, key);
|
||||
owner_data->OwnerCurr = owner_data->OwnerNext = owner_id;
|
||||
|
||||
// We cannot lock by default as it would likely break lots of legacy code.
|
||||
@@ -9490,7 +9511,7 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags
|
||||
// Special storage location for mods
|
||||
ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_);
|
||||
if (key == ImGuiKey_None)
|
||||
key = ConvertSingleModFlagToKey(mods);
|
||||
key = ConvertSingleModFlagToKey(&g, mods);
|
||||
|
||||
if (!IsKeyPressed(key, owner_id, (flags & (ImGuiInputFlags_Repeat | (ImGuiInputFlags)ImGuiInputFlags_RepeatRateMask_))))
|
||||
return false;
|
||||
@@ -9941,7 +9962,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
||||
// return false;
|
||||
const bool is_rect_visible = bb.Overlaps(window->ClipRect);
|
||||
if (!is_rect_visible)
|
||||
if (id == 0 || (id != g.ActiveId && id != g.NavId))
|
||||
if (id == 0 || (id != g.ActiveId && id != g.ActiveIdPreviousFrame && id != g.NavId))
|
||||
if (!g.LogEnabled)
|
||||
return false;
|
||||
|
||||
@@ -11232,7 +11253,7 @@ void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window)
|
||||
if (g.LastItemData.ID == id)
|
||||
window->NavRectRel[nav_layer] = WindowRectAbsToRel(window, g.LastItemData.NavRect);
|
||||
|
||||
if (g.ActiveIdSource == ImGuiInputSource_Nav)
|
||||
if (g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad)
|
||||
g.NavDisableMouseHover = true;
|
||||
else
|
||||
g.NavDisableHighlight = true;
|
||||
@@ -19290,7 +19311,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
{
|
||||
for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1))
|
||||
{
|
||||
ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(key);
|
||||
ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(&g, key);
|
||||
if (owner_data->OwnerCurr == ImGuiKeyOwner_None)
|
||||
continue;
|
||||
Text("%s: 0x%08X%s", GetKeyName(key), owner_data->OwnerCurr,
|
||||
|
||||
Reference in New Issue
Block a user