mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
Internals: Refactor: Moved code out of NewFrame() into UpdateTabFocus() and UpdateSettings()
This commit is contained in:
parent
095dc996b0
commit
2679bee28d
@ -87,6 +87,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
|||||||
- input text: option to Tab after an Enter validation.
|
- input text: option to Tab after an Enter validation.
|
||||||
- input text: add ImGuiInputTextFlags_EnterToApply? (off #218)
|
- input text: add ImGuiInputTextFlags_EnterToApply? (off #218)
|
||||||
- input text: easier ways to update buffer (from source char*) while owned. preserve some sort of cursor position for multi-line text.
|
- input text: easier ways to update buffer (from source char*) while owned. preserve some sort of cursor position for multi-line text.
|
||||||
|
- input text: add flag (e.g. ImGuiInputTextFlags_EscapeClearsBuffer) to clear instead of revert. what to do with focus? (also see #2890)
|
||||||
- input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725)
|
- input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725)
|
||||||
- input text: display bug when clicking a drag/slider after an input text in a different window has all-selected text (order dependent). actually a very old bug but no one appears to have noticed it.
|
- input text: display bug when clicking a drag/slider after an input text in a different window has all-selected text (order dependent). actually a very old bug but no one appears to have noticed it.
|
||||||
- input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position.
|
- input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position.
|
||||||
|
149
imgui.cpp
149
imgui.cpp
@ -904,10 +904,12 @@ static void ErrorCheckEndFrame();
|
|||||||
static void ErrorCheckBeginEndCompareStacksSize(ImGuiWindow* window, bool write);
|
static void ErrorCheckBeginEndCompareStacksSize(ImGuiWindow* window, bool write);
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
|
static void UpdateSettings();
|
||||||
static void UpdateMouseInputs();
|
static void UpdateMouseInputs();
|
||||||
static void UpdateMouseWheel();
|
static void UpdateMouseWheel();
|
||||||
static bool UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]);
|
static void UpdateTabFocus();
|
||||||
static void UpdateDebugToolItemPicker();
|
static void UpdateDebugToolItemPicker();
|
||||||
|
static bool UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]);
|
||||||
static void RenderWindowOuterBorders(ImGuiWindow* window);
|
static void RenderWindowOuterBorders(ImGuiWindow* window);
|
||||||
static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size);
|
static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size);
|
||||||
static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open);
|
static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open);
|
||||||
@ -3495,6 +3497,42 @@ void ImGui::UpdateMouseWheel()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGui::UpdateTabFocus()
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
|
||||||
|
// Pressing TAB activate widget focus
|
||||||
|
g.FocusTabPressed = (g.NavWindow && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab));
|
||||||
|
if (g.ActiveId == 0 && g.FocusTabPressed)
|
||||||
|
{
|
||||||
|
// Note that SetKeyboardFocusHere() sets the Next fields mid-frame. To be consistent we also
|
||||||
|
// manipulate the Next fields even, even though they will be turned into Curr fields by the code below.
|
||||||
|
g.FocusRequestNextWindow = g.NavWindow;
|
||||||
|
g.FocusRequestNextCounterRegular = INT_MAX;
|
||||||
|
if (g.NavId != 0 && g.NavIdTabCounter != INT_MAX)
|
||||||
|
g.FocusRequestNextCounterTabStop = g.NavIdTabCounter + 1 + (g.IO.KeyShift ? -1 : 1);
|
||||||
|
else
|
||||||
|
g.FocusRequestNextCounterTabStop = g.IO.KeyShift ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn queued focus request into current one
|
||||||
|
g.FocusRequestCurrWindow = NULL;
|
||||||
|
g.FocusRequestCurrCounterRegular = g.FocusRequestCurrCounterTabStop = INT_MAX;
|
||||||
|
if (g.FocusRequestNextWindow != NULL)
|
||||||
|
{
|
||||||
|
ImGuiWindow* window = g.FocusRequestNextWindow;
|
||||||
|
g.FocusRequestCurrWindow = window;
|
||||||
|
if (g.FocusRequestNextCounterRegular != INT_MAX && window->DC.FocusCounterRegular != -1)
|
||||||
|
g.FocusRequestCurrCounterRegular = ImModPositive(g.FocusRequestNextCounterRegular, window->DC.FocusCounterRegular + 1);
|
||||||
|
if (g.FocusRequestNextCounterTabStop != INT_MAX && window->DC.FocusCounterTabStop != -1)
|
||||||
|
g.FocusRequestCurrCounterTabStop = ImModPositive(g.FocusRequestNextCounterTabStop, window->DC.FocusCounterTabStop + 1);
|
||||||
|
g.FocusRequestNextWindow = NULL;
|
||||||
|
g.FocusRequestNextCounterRegular = g.FocusRequestNextCounterTabStop = INT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
g.NavIdTabCounter = INT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
// The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app)
|
// The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app)
|
||||||
void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
||||||
{
|
{
|
||||||
@ -3595,28 +3633,8 @@ void ImGui::NewFrame()
|
|||||||
// Check and assert for various common IO and Configuration mistakes
|
// Check and assert for various common IO and Configuration mistakes
|
||||||
NewFrameSanityChecks();
|
NewFrameSanityChecks();
|
||||||
|
|
||||||
// Load settings on first frame (if not explicitly loaded manually before)
|
// Load settings on first frame, save settings when modified (after a delay)
|
||||||
if (!g.SettingsLoaded)
|
UpdateSettings();
|
||||||
{
|
|
||||||
IM_ASSERT(g.SettingsWindows.empty());
|
|
||||||
if (g.IO.IniFilename)
|
|
||||||
LoadIniSettingsFromDisk(g.IO.IniFilename);
|
|
||||||
g.SettingsLoaded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save settings (with a delay after the last modification, so we don't spam disk too much)
|
|
||||||
if (g.SettingsDirtyTimer > 0.0f)
|
|
||||||
{
|
|
||||||
g.SettingsDirtyTimer -= g.IO.DeltaTime;
|
|
||||||
if (g.SettingsDirtyTimer <= 0.0f)
|
|
||||||
{
|
|
||||||
if (g.IO.IniFilename != NULL)
|
|
||||||
SaveIniSettingsToDisk(g.IO.IniFilename);
|
|
||||||
else
|
|
||||||
g.IO.WantSaveIniSettings = true; // Let user know they can call SaveIniSettingsToMemory(). user will need to clear io.WantSaveIniSettings themselves.
|
|
||||||
g.SettingsDirtyTimer = 0.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g.Time += g.IO.DeltaTime;
|
g.Time += g.IO.DeltaTime;
|
||||||
g.WithinFrameScope = true;
|
g.WithinFrameScope = true;
|
||||||
@ -3625,6 +3643,12 @@ void ImGui::NewFrame()
|
|||||||
g.WindowsActiveCount = 0;
|
g.WindowsActiveCount = 0;
|
||||||
g.MenusIdSubmittedThisFrame.resize(0);
|
g.MenusIdSubmittedThisFrame.resize(0);
|
||||||
|
|
||||||
|
// Calculate frame-rate for the user, as a purely luxurious feature
|
||||||
|
g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx];
|
||||||
|
g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx] = g.IO.DeltaTime;
|
||||||
|
g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame);
|
||||||
|
g.IO.Framerate = (g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame))) : FLT_MAX;
|
||||||
|
|
||||||
// Setup current font and draw list shared data
|
// Setup current font and draw list shared data
|
||||||
g.IO.Fonts->Locked = true;
|
g.IO.Fonts->Locked = true;
|
||||||
SetCurrentFont(GetDefaultFont());
|
SetCurrentFont(GetDefaultFont());
|
||||||
@ -3655,7 +3679,7 @@ void ImGui::NewFrame()
|
|||||||
if (g.DragDropActive && g.DragDropPayload.SourceId == g.ActiveId)
|
if (g.DragDropActive && g.DragDropPayload.SourceId == g.ActiveId)
|
||||||
KeepAliveID(g.DragDropPayload.SourceId);
|
KeepAliveID(g.DragDropPayload.SourceId);
|
||||||
|
|
||||||
// Clear reference to active widget if the widget isn't alive anymore
|
// Update HoveredId data
|
||||||
if (!g.HoveredIdPreviousFrame)
|
if (!g.HoveredIdPreviousFrame)
|
||||||
g.HoveredIdTimer = 0.0f;
|
g.HoveredIdTimer = 0.0f;
|
||||||
if (!g.HoveredIdPreviousFrame || (g.HoveredId && g.ActiveId == g.HoveredId))
|
if (!g.HoveredIdPreviousFrame || (g.HoveredId && g.ActiveId == g.HoveredId))
|
||||||
@ -3667,6 +3691,8 @@ void ImGui::NewFrame()
|
|||||||
g.HoveredIdPreviousFrame = g.HoveredId;
|
g.HoveredIdPreviousFrame = g.HoveredId;
|
||||||
g.HoveredId = 0;
|
g.HoveredId = 0;
|
||||||
g.HoveredIdAllowOverlap = false;
|
g.HoveredIdAllowOverlap = false;
|
||||||
|
|
||||||
|
// Update ActiveId data (clear reference to active widget if the widget isn't alive anymore)
|
||||||
if (g.ActiveIdIsAlive != g.ActiveId && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
|
if (g.ActiveIdIsAlive != g.ActiveId && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
|
||||||
ClearActiveID();
|
ClearActiveID();
|
||||||
if (g.ActiveId)
|
if (g.ActiveId)
|
||||||
@ -3683,8 +3709,9 @@ void ImGui::NewFrame()
|
|||||||
g.TempInputId = 0;
|
g.TempInputId = 0;
|
||||||
if (g.ActiveId == 0)
|
if (g.ActiveId == 0)
|
||||||
{
|
{
|
||||||
g.ActiveIdUsingNavDirMask = g.ActiveIdUsingNavInputMask = 0;
|
g.ActiveIdUsingNavDirMask = 0x00;
|
||||||
g.ActiveIdUsingKeyInputMask = 0;
|
g.ActiveIdUsingNavInputMask = 0x00;
|
||||||
|
g.ActiveIdUsingKeyInputMask = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drag and drop
|
// Drag and drop
|
||||||
@ -3704,12 +3731,6 @@ void ImGui::NewFrame()
|
|||||||
// Update mouse input state
|
// Update mouse input state
|
||||||
UpdateMouseInputs();
|
UpdateMouseInputs();
|
||||||
|
|
||||||
// Calculate frame-rate for the user, as a purely luxurious feature
|
|
||||||
g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx];
|
|
||||||
g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx] = g.IO.DeltaTime;
|
|
||||||
g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame);
|
|
||||||
g.IO.Framerate = (g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame))) : FLT_MAX;
|
|
||||||
|
|
||||||
// Find hovered window
|
// Find hovered window
|
||||||
// (needs to be before UpdateMouseMovingWindowNewFrame so we fill g.HoveredWindowUnderMovingWindow on the mouse release frame)
|
// (needs to be before UpdateMouseMovingWindowNewFrame so we fill g.HoveredWindowUnderMovingWindow on the mouse release frame)
|
||||||
UpdateHoveredWindowAndCaptureFlags();
|
UpdateHoveredWindowAndCaptureFlags();
|
||||||
@ -3730,36 +3751,8 @@ void ImGui::NewFrame()
|
|||||||
// Mouse wheel scrolling, scale
|
// Mouse wheel scrolling, scale
|
||||||
UpdateMouseWheel();
|
UpdateMouseWheel();
|
||||||
|
|
||||||
// Pressing TAB activate widget focus
|
// Update legacy TAB focus
|
||||||
g.FocusTabPressed = (g.NavWindow && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab));
|
UpdateTabFocus();
|
||||||
if (g.ActiveId == 0 && g.FocusTabPressed)
|
|
||||||
{
|
|
||||||
// Note that SetKeyboardFocusHere() sets the Next fields mid-frame. To be consistent we also
|
|
||||||
// manipulate the Next fields even, even though they will be turned into Curr fields by the code below.
|
|
||||||
g.FocusRequestNextWindow = g.NavWindow;
|
|
||||||
g.FocusRequestNextCounterRegular = INT_MAX;
|
|
||||||
if (g.NavId != 0 && g.NavIdTabCounter != INT_MAX)
|
|
||||||
g.FocusRequestNextCounterTabStop = g.NavIdTabCounter + 1 + (g.IO.KeyShift ? -1 : 1);
|
|
||||||
else
|
|
||||||
g.FocusRequestNextCounterTabStop = g.IO.KeyShift ? -1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Turn queued focus request into current one
|
|
||||||
g.FocusRequestCurrWindow = NULL;
|
|
||||||
g.FocusRequestCurrCounterRegular = g.FocusRequestCurrCounterTabStop = INT_MAX;
|
|
||||||
if (g.FocusRequestNextWindow != NULL)
|
|
||||||
{
|
|
||||||
ImGuiWindow* window = g.FocusRequestNextWindow;
|
|
||||||
g.FocusRequestCurrWindow = window;
|
|
||||||
if (g.FocusRequestNextCounterRegular != INT_MAX && window->DC.FocusCounterRegular != -1)
|
|
||||||
g.FocusRequestCurrCounterRegular = ImModPositive(g.FocusRequestNextCounterRegular, window->DC.FocusCounterRegular + 1);
|
|
||||||
if (g.FocusRequestNextCounterTabStop != INT_MAX && window->DC.FocusCounterTabStop != -1)
|
|
||||||
g.FocusRequestCurrCounterTabStop = ImModPositive(g.FocusRequestNextCounterTabStop, window->DC.FocusCounterTabStop + 1);
|
|
||||||
g.FocusRequestNextWindow = NULL;
|
|
||||||
g.FocusRequestNextCounterRegular = g.FocusRequestNextCounterTabStop = INT_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
g.NavIdTabCounter = INT_MAX;
|
|
||||||
|
|
||||||
// Mark all windows as not visible and compact unused memory.
|
// Mark all windows as not visible and compact unused memory.
|
||||||
IM_ASSERT(g.WindowsFocusOrder.Size == g.Windows.Size);
|
IM_ASSERT(g.WindowsFocusOrder.Size == g.Windows.Size);
|
||||||
@ -4972,7 +4965,7 @@ ImGuiID ImGui::GetWindowResizeID(ImGuiWindow* window, int n)
|
|||||||
|
|
||||||
// Handle resize for: Resize Grips, Borders, Gamepad
|
// Handle resize for: Resize Grips, Borders, Gamepad
|
||||||
// Return true when using auto-fit (double click on resize grip)
|
// Return true when using auto-fit (double click on resize grip)
|
||||||
static bool ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4])
|
static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4])
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindowFlags flags = window->Flags;
|
ImGuiWindowFlags flags = window->Flags;
|
||||||
@ -5645,7 +5638,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
|
const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
|
||||||
const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
||||||
if (!window->Collapsed)
|
if (!window->Collapsed)
|
||||||
if (UpdateManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]))
|
if (UpdateWindowManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]))
|
||||||
use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true;
|
use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true;
|
||||||
window->ResizeBorderHeld = (signed char)border_held;
|
window->ResizeBorderHeld = (signed char)border_held;
|
||||||
|
|
||||||
@ -9444,6 +9437,34 @@ void ImGui::LogButtons()
|
|||||||
// [SECTION] SETTINGS
|
// [SECTION] SETTINGS
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Called by NewFrame()
|
||||||
|
void ImGui::UpdateSettings()
|
||||||
|
{
|
||||||
|
// Load settings on first frame (if not explicitly loaded manually before)
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
if (!g.SettingsLoaded)
|
||||||
|
{
|
||||||
|
IM_ASSERT(g.SettingsWindows.empty());
|
||||||
|
if (g.IO.IniFilename)
|
||||||
|
LoadIniSettingsFromDisk(g.IO.IniFilename);
|
||||||
|
g.SettingsLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save settings (with a delay after the last modification, so we don't spam disk too much)
|
||||||
|
if (g.SettingsDirtyTimer > 0.0f)
|
||||||
|
{
|
||||||
|
g.SettingsDirtyTimer -= g.IO.DeltaTime;
|
||||||
|
if (g.SettingsDirtyTimer <= 0.0f)
|
||||||
|
{
|
||||||
|
if (g.IO.IniFilename != NULL)
|
||||||
|
SaveIniSettingsToDisk(g.IO.IniFilename);
|
||||||
|
else
|
||||||
|
g.IO.WantSaveIniSettings = true; // Let user know they can call SaveIniSettingsToMemory(). user will need to clear io.WantSaveIniSettings themselves.
|
||||||
|
g.SettingsDirtyTimer = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ImGui::MarkIniSettingsDirty()
|
void ImGui::MarkIniSettingsDirty()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
Loading…
Reference in New Issue
Block a user