mirror of
https://github.com/ocornut/imgui.git
synced 2024-12-03 21:59:15 +08:00
Merge branch 'master' into docking
This commit is contained in:
commit
fee0210592
@ -56,39 +56,52 @@ Breaking changes:
|
||||
|
||||
Other changes:
|
||||
|
||||
- Inputs: added Shortcut() function (w/ routing policies) in public API. (#456, #2637)
|
||||
- using ImGui::Shortcut(ImGuiMod_Ctrl | ImGuiKey_C); with default policy:
|
||||
- checks that CTRL+C is pressed,
|
||||
- and that current window is in focus stack,
|
||||
- and that no other requests for CTRL+C have been made from deeper locations of the window/item stack.
|
||||
- Added ImGuiInputFlags_RouteFocused, ImGuiInputFlags_RouteGlobal and other flags
|
||||
related to routing policies. (#456, #2637)
|
||||
- Added ImGuiInputFlags_Repeat for use by Shortcut() and by upcoming (still internal)
|
||||
extended rework of various input functions.
|
||||
- About routing system and routing policies:
|
||||
The general idea is that several callers may register interest in a shortcut, and only one owner gets it.
|
||||
- Windows: BeginChild(): fixed visibility of fully clipped child windows and tables to Test Engine.
|
||||
- Windows: BeginChild(): fixed auto-fit calculation when using either (not both) ResizeX/ResizeY
|
||||
and double-clicking on a border. Calculation incorrectly didn't always account for scrollbar as
|
||||
it assumed the other axis would also be auto-fit. (#1710)
|
||||
- Inputs: added shortcut and routing system in public API. (#456, #2637)
|
||||
- The general idea is that several callers may register interest in a shortcut, and only one owner gets it.
|
||||
Parent -> call Shortcut(Ctrl+S) // When Parent is focused, Parent gets the shortcut.
|
||||
Child1 -> call Shortcut(Ctrl+S) // When Child1 is focused, Child1 gets the shortcut (Child1 overrides Parent shortcuts)
|
||||
Child2 -> no call // When Child2 is focused, Parent gets the shortcut.
|
||||
The whole system is order independent, so if Child1 makes its calls before Parent, results will be identical.
|
||||
This is an important property as it facilitate working with foreign code or larger codebase.
|
||||
- Inputs: added SetNextItemShortcut() to set a shortcut to locally or remotely press or activate
|
||||
an item (depending on specified routing policy). Items like buttons are not fully activated, in
|
||||
the sense that they get pressed but an active e.g. InputText() won't be deactivated. (#456)
|
||||
- Added ImGuiInputFlags_Tooltip to automatically show a tooltip when hovering item.
|
||||
- Using e.g. ImGuiInputFlags_RouteGlobal the item shortcut may be executed even if its
|
||||
window is not in focus stack.
|
||||
- Added Shortcut() function:
|
||||
e.g. Using ImGui::Shortcut(ImGuiMod_Ctrl | ImGuiKey_C); with default policy:
|
||||
- checks that CTRL+C is pressed,
|
||||
- and that current window is in focus stack,
|
||||
- and that no other requests for CTRL+C have been made from higher priority locations
|
||||
(e.g. deeper in the window/item stack).
|
||||
- Added SetNextItemShortcut() to set a shortcut to locally or remotely press or activate
|
||||
an item (depending on specified routing policy: using ImGuiInputFlags_RouteGlobal the item
|
||||
shortcut may be executed even if its window is not in focus stack).
|
||||
Items like buttons are not fully activated, in the sense that they get pressed but another
|
||||
active item, e.g. InputText() won't be deactivated.
|
||||
- Added routing policies for Shortcut(), SetNextItemShortcut(): (#456, #2637)
|
||||
- ImGuiInputFlags_RouteFocused: focus stack route (default)
|
||||
- ImGuiInputFlags_RouteActive: only route to active item
|
||||
- ImGuiInputFlags_RouteGlobal: route globally, unless a focus route claim shame shortcut.
|
||||
- ImGuiInputFlags_RouteAlways: no routing submission, no routing check.
|
||||
- Added other shortcut/routing options: (#456, #2637)
|
||||
- ImGuiInputFlags_Repeat: for use by Shortcut() and by upcoming rework of various
|
||||
input functions (which are still internal for now).
|
||||
- ImGuiInputFlags_Tooltip: for SetNextItemShortcut() to show a tooltip when hovering item.
|
||||
- ImGuiInputFlags_RouteGlobalOverFocused
|
||||
- ImGuiInputFlags_RouteGlobalOverActive
|
||||
- ImGuiInputFlags_RouteUnlessBgFocused
|
||||
- ImGuiInputFlags_RouteFromRootWindow
|
||||
- Inputs: (OSX) Fixes variety of code which inconsistently required using Ctrl instead of Cmd.
|
||||
- e.g. Drags/Sliders now use Cmd+Click to input a value. (#4084)
|
||||
- Some shortcuts still uses Ctrl on Mac: e.g. Ctrl+Tab to switch windows. (#4828)
|
||||
- Inputs: (OSX) Ctrl+Left Click alias as a Right click. (#2343) [@haldean, @ocornut]
|
||||
- Inputs: Fixed ImGui::GetKeyName(ImGuiKey_None) from returning "N/A" or "None" depending
|
||||
on value of IMGUI_DISABLE_OBSOLETE_KEYIO. It always returns "None".
|
||||
- Windows: BeginChild(): fixed visibility of fully clipped child windows and tables to Test Engine.
|
||||
- Nav: fixed holding Ctrl or gamepad L1 from not slowing down keyboard/gamepad tweak speed.
|
||||
Broken during a refactor refactor for 1.89. Holding Shift/R1 to speed up wasn't broken.
|
||||
- Tables: fixed cell background of fully clipped row overlapping with header. (#7575, #7041) [@prabuinet]
|
||||
- Demo: Added "Inputs & Focus -> Shortcuts" section. (#456, #2637)
|
||||
- Demo: Documents: Added shortcuts and renaming tabs/documents. (#7233)
|
||||
- Examples: Win32+DX9,DX10,DX11,DX12: rework main loop to handle minimization and screen
|
||||
locking without burning resources by running unthrottled code. (#2496, #3907, #6308, #7615)
|
||||
- Backends: all backends + demo now call IMGUI_CHECKVERSION() to verify ABI compatibility between caller
|
||||
@ -103,9 +116,12 @@ Breaking changes IF you were using imgui_internal.h versions of Shortcut() or ow
|
||||
versions of IsKeyPressed(), IsKeyChordPressed(), IsMouseClicked() prior to this version:
|
||||
|
||||
- Inputs (Internals) Renamed ImGuiKeyOwner_None to ImGuiKeyOwner_NoOwner, to make use more
|
||||
explicit and reduce confusion with the fact it is a non-zero value and cannot be the
|
||||
default value.
|
||||
- Inputs (Internals) Shortcut(), SetShortcutRouting(): swapped last two parameters order
|
||||
explicit and reduce confusion with the fact it is a non-zero value and cannot be a default.
|
||||
- Inputs (Internals): Renamed symbols global routes:
|
||||
Renamed ImGuiInputFlags_RouteGlobalLow -> ImGuiInputFlags_RouteGlobal (this is the suggest global route)
|
||||
Renamed ImGuiInputFlags_RouteGlobal -> ImGuiInputFlags_RouteGlobalOverFocused (override focused route)
|
||||
Renamed ImGuiInputFlags_RouteGlobalHigh -> ImGuiInputFlags_RouteGlobalHighest
|
||||
- Inputs (Internals): Shortcut(), SetShortcutRouting(): swapped last two parameters order
|
||||
in function signatures:
|
||||
Before: Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0);
|
||||
After: Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags = 0, ImGuiID owner_id = 0);
|
||||
@ -115,6 +131,7 @@ versions of IsKeyPressed(), IsKeyChordPressed(), IsMouseClicked() prior to this
|
||||
After: IsKeyPressed(ImGuiKey key, ImGuiInputFlags flags, ImGuiID owner_id = 0);
|
||||
Before: IsMouseClicked(ImGuiMouseButton button, ImGuiID owner_id, ImGuiInputFlags flags = 0);
|
||||
After: IsMouseClicked(ImGuiMouseButton button, ImGuiInputFlags flags, ImGuiID owner_id = 0);
|
||||
|
||||
- For several reasons those changes makes sense. They are being made because making some of
|
||||
those API public. Only past users of imgui_internal.h with the extra parameters will be affected.
|
||||
Added asserts for valid flags in various functions to detect _some_ misuses, BUT NOT ALL.
|
||||
|
@ -203,6 +203,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- tooltip: drag tooltip hovering over source widget with IsItemHovered/SetTooltip flickers (WIP branch)
|
||||
|
||||
- status-bar: add a per-window status bar helper similar to what menu-bar does. generalize concept of layer0 rect in window (can make _MenuBar window flag obsolete too).
|
||||
- shortcuts: store multiple keychords in ImGuiKeyChord
|
||||
- shortcuts: Hovered route (lower than Focused, higher than Global)
|
||||
- shortcuts: local-style shortcut api, e.g. parse "&Save"
|
||||
- shortcuts,menus: global-style shortcut api e.g. "Save (CTRL+S)" -> explicit flag for recursing into closed menu
|
||||
- shortcuts: programmatically access shortcuts "Focus("&Save"))
|
||||
|
65
imgui.cpp
65
imgui.cpp
@ -439,6 +439,7 @@ CODE
|
||||
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
|
||||
|
||||
- 2024/05/22 (1.90.7) - inputs (internals): renamed ImGuiKeyOwner_None to ImGuiKeyOwner_NoOwner, to make use more explicit and reduce confusion with the default it is a non-zero value and cannot be the default value (never made public, but disclosing as I expect a few users caught on owner-aware inputs).
|
||||
- inputs (internals): renamed ImGuiInputFlags_RouteGlobalLow -> ImGuiInputFlags_RouteGlobal, ImGuiInputFlags_RouteGlobal -> ImGuiInputFlags_RouteGlobalOverFocused, ImGuiInputFlags_RouteGlobalHigh -> ImGuiInputFlags_RouteGlobalHighest.
|
||||
- inputs (internals): Shortcut(), SetShortcutRouting(): swapped last two parameters order in function signatures:
|
||||
- old: Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0);
|
||||
- new: Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags = 0, ImGuiID owner_id = 0);
|
||||
@ -6143,10 +6144,18 @@ static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_cont
|
||||
size_max = g.PlatformIO.Monitors[monitor_idx].WorkSize - style.DisplaySafeAreaPadding * 2.0f;
|
||||
ImVec2 size_auto_fit = ImClamp(size_desired, size_min, ImMax(size_min, size_max));
|
||||
|
||||
// FIXME: CalcWindowAutoFitSize() doesn't take into account that only one axis may be auto-fit when calculating scrollbars,
|
||||
// we may need to compute/store three variants of size_auto_fit, for x/y/xy.
|
||||
// Here we implement a workaround for child windows only, but a full solution would apply to normal windows as well:
|
||||
if ((window->ChildFlags & ImGuiChildFlags_ResizeX) && !(window->ChildFlags & ImGuiChildFlags_ResizeY))
|
||||
size_auto_fit.y = window->SizeFull.y;
|
||||
else if (!(window->ChildFlags & ImGuiChildFlags_ResizeX) && (window->ChildFlags & ImGuiChildFlags_ResizeY))
|
||||
size_auto_fit.x = window->SizeFull.x;
|
||||
|
||||
// When the window cannot fit all contents (either because of constraints, either because screen is too small),
|
||||
// we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than ViewportSize-WindowPadding.
|
||||
ImVec2 size_auto_fit_after_constraint = CalcWindowSizeAfterConstraint(window, size_auto_fit);
|
||||
bool will_have_scrollbar_x = (size_auto_fit_after_constraint.x - size_pad.x - decoration_w_without_scrollbars < size_contents.x && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && (window->Flags & ImGuiWindowFlags_HorizontalScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar);
|
||||
bool will_have_scrollbar_x = (size_auto_fit_after_constraint.x - size_pad.x - decoration_w_without_scrollbars < size_contents.x && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && (window->Flags & ImGuiWindowFlags_HorizontalScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar);
|
||||
bool will_have_scrollbar_y = (size_auto_fit_after_constraint.y - size_pad.y - decoration_h_without_scrollbars < size_contents.y && !(window->Flags & ImGuiWindowFlags_NoScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysVerticalScrollbar);
|
||||
if (will_have_scrollbar_x)
|
||||
size_auto_fit.y += style.ScrollbarSize;
|
||||
@ -6358,6 +6367,7 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si
|
||||
if (held && g.IO.MouseDoubleClicked[0])
|
||||
{
|
||||
// Double-clicking bottom or right border auto-fit on this axis
|
||||
// FIXME: CalcWindowAutoFitSize() doesn't take into account that only one side may be auto-fit when calculating scrollbars.
|
||||
// FIXME: Support top and right borders: rework CalcResizePosSizeFromAnyCorner() to be reusable in both cases.
|
||||
if (border_n == 1 || border_n == 3) // Right and bottom border
|
||||
{
|
||||
@ -9219,8 +9229,8 @@ ImGuiKeyRoutingData* ImGui::GetShortcutRoutingData(ImGuiKeyChord key_chord)
|
||||
}
|
||||
|
||||
// Current score encoding (lower is highest priority):
|
||||
// - 0: ImGuiInputFlags_RouteGlobalHighest
|
||||
// - 1: ImGuiInputFlags_RouteFocused (if item active)
|
||||
// - 0: ImGuiInputFlags_RouteGlobalOverActive
|
||||
// - 1: ImGuiInputFlags_ActiveItem or ImGuiInputFlags_RouteFocused (if item active)
|
||||
// - 2: ImGuiInputFlags_RouteGlobalOverFocused
|
||||
// - 3+: ImGuiInputFlags_RouteFocused (if window in focus-stack)
|
||||
// - 254: ImGuiInputFlags_RouteGlobal
|
||||
@ -9228,10 +9238,9 @@ ImGuiKeyRoutingData* ImGui::GetShortcutRoutingData(ImGuiKeyChord key_chord)
|
||||
// 'flags' should include an explicit routing policy
|
||||
static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInputFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (flags & ImGuiInputFlags_RouteFocused)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
// ActiveID gets top priority
|
||||
// (we don't check g.ActiveIdUsingAllKeys here. Routing is applied but if input ownership is tested later it may discard it)
|
||||
if (owner_id != 0 && g.ActiveId == owner_id)
|
||||
@ -9252,12 +9261,19 @@ static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInput
|
||||
|
||||
return 255;
|
||||
}
|
||||
|
||||
// ImGuiInputFlags_RouteGlobalHighest is default, so calls without flags are not conditional
|
||||
if (flags & ImGuiInputFlags_RouteGlobalOverFocused)
|
||||
if (flags & ImGuiInputFlags_RouteActive)
|
||||
{
|
||||
if (owner_id != 0 && g.ActiveId == owner_id)
|
||||
return 1;
|
||||
return 255;
|
||||
}
|
||||
if (flags & ImGuiInputFlags_RouteOverFocused)
|
||||
return 2;
|
||||
if (flags & ImGuiInputFlags_RouteGlobal)
|
||||
return 254;
|
||||
if (flags & ImGuiInputFlags_RouteOverActive)
|
||||
return 0;
|
||||
IM_ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -9284,11 +9300,13 @@ static bool IsKeyChordPotentiallyCharInput(ImGuiKeyChord key_chord)
|
||||
// - Routes and key ownership are attributed at the beginning of next frame based on best score and mod state.
|
||||
// (Conceptually this does a "Submit for next frame" + "Test for current frame".
|
||||
// As such, it could be called TrySetXXX or SubmitXXX, or the Submit and Test operations should be separate.)
|
||||
bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id, ImGuiID focus_scope_id)
|
||||
bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiInputFlags_RouteTypeMask_)); // Check that only 1 routing flag is used
|
||||
IM_ASSERT(owner_id != ImGuiKeyOwner_Any && owner_id != ImGuiKeyOwner_NoOwner);
|
||||
if (flags & (ImGuiInputFlags_RouteOverFocused | ImGuiInputFlags_RouteOverActive | ImGuiInputFlags_RouteUnlessBgFocused))
|
||||
IM_ASSERT(flags & ImGuiInputFlags_RouteGlobal);
|
||||
|
||||
// Add ImGuiMod_XXXX when a corresponding ImGuiKey_LeftXXX/ImGuiKey_RightXXX is specified.
|
||||
key_chord = FixupKeyChord(key_chord);
|
||||
@ -9308,7 +9326,7 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, I
|
||||
return true;
|
||||
}
|
||||
|
||||
// Specific culling when there's an active.
|
||||
// Specific culling when there's an active item.
|
||||
if (g.ActiveId != 0 && g.ActiveId != owner_id)
|
||||
{
|
||||
// Cull shortcuts with no modifiers when it could generate a character.
|
||||
@ -9322,8 +9340,11 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, I
|
||||
return false;
|
||||
}
|
||||
|
||||
if (flags & ImGuiInputFlags_RouteActive)
|
||||
return false;
|
||||
|
||||
// ActiveIdUsingAllKeyboardKeys trumps all for ActiveId
|
||||
if ((flags & ImGuiInputFlags_RouteGlobalHighest) == 0 && g.ActiveIdUsingAllKeyboardKeys)
|
||||
if ((flags & ImGuiInputFlags_RouteOverActive) == 0 && g.ActiveIdUsingAllKeyboardKeys)
|
||||
{
|
||||
ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_);
|
||||
if (key == ImGuiKey_None)
|
||||
@ -9333,6 +9354,11 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, I
|
||||
}
|
||||
}
|
||||
|
||||
// Where do we evaluate route for?
|
||||
ImGuiID focus_scope_id = g.CurrentFocusScopeId;
|
||||
if (flags & ImGuiInputFlags_RouteFromRootWindow)
|
||||
focus_scope_id = g.CurrentWindow->RootWindow->ID; // See PushFocusScope() call in Begin()
|
||||
|
||||
const int score = CalcRoutingScore(focus_scope_id, owner_id, flags);
|
||||
IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, flags=%04X, owner_id=0x%08X) -> score %d\n", GetKeyChordName(key_chord), flags, owner_id, score);
|
||||
if (score == 255)
|
||||
@ -10350,7 +10376,7 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags)
|
||||
|
||||
bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
//ImGuiContext& g = *GImGui;
|
||||
//IMGUI_DEBUG_LOG("Shortcut(%s, flags=%X, owner_id=0x%08X)\n", GetKeyChordName(key_chord, g.TempBuffer.Data, g.TempBuffer.Size), flags, owner_id);
|
||||
|
||||
// When using (owner_id == 0/Any): SetShortcutRouting() will use CurrentFocusScopeId and filter with this, so IsKeyPressed() is fine with he 0/Any.
|
||||
@ -10362,13 +10388,8 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID own
|
||||
if (owner_id == ImGuiKeyOwner_Any || owner_id == ImGuiKeyOwner_NoOwner)
|
||||
owner_id = GetRoutingIdFromOwnerId(owner_id);
|
||||
|
||||
// Where do we evaluate route for?
|
||||
ImGuiID focus_scope_id = g.CurrentFocusScopeId;
|
||||
if (flags & ImGuiInputFlags_RouteFromRootWindow)
|
||||
focus_scope_id = g.CurrentWindow->RootWindow->ID; // See PushFocusScope() call in Begin()
|
||||
|
||||
// Submit route
|
||||
if (!SetShortcutRouting(key_chord, flags, owner_id, focus_scope_id))
|
||||
if (!SetShortcutRouting(key_chord, flags, owner_id))
|
||||
return false;
|
||||
|
||||
// Default repeat behavior for Shortcut()
|
||||
@ -10378,6 +10399,10 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID own
|
||||
|
||||
if (!IsKeyChordPressed(key_chord, flags, owner_id))
|
||||
return false;
|
||||
|
||||
// Claim mods during the press
|
||||
SetKeyOwnersForKeyChord(key_chord & ImGuiMod_Mask_, owner_id);
|
||||
|
||||
IM_ASSERT((flags & ~ImGuiInputFlags_SupportedByShortcut) == 0); // Passing flags not supported by this function!
|
||||
return true;
|
||||
}
|
||||
@ -13537,7 +13562,7 @@ static void ImGui::NavUpdateWindowing()
|
||||
g.NavWindowingToggleLayer = start_windowing_with_gamepad ? true : false; // Gamepad starts toggling layer
|
||||
g.NavInputSource = start_windowing_with_keyboard ? ImGuiInputSource_Keyboard : ImGuiInputSource_Gamepad;
|
||||
|
||||
// Manually register ownership of our mods. Using ImGuiInputFlags_RouteGlobalHighest in the Shortcut() calls instead would probably be correct but may have more side-effects.
|
||||
// Manually register ownership of our mods. Using a global route in the Shortcut() calls instead would probably be correct but may have more side-effects.
|
||||
if (keyboard_next_window || keyboard_prev_window)
|
||||
SetKeyOwnersForKeyChord((g.ConfigNavWindowingKeyNext | g.ConfigNavWindowingKeyPrev) & ImGuiMod_Mask_, owner_id);
|
||||
}
|
||||
@ -21730,7 +21755,7 @@ void ImGui::ShowIDStackToolWindow(bool* p_open)
|
||||
Checkbox("Ctrl+C: copy path to clipboard", &tool->CopyToClipboardOnCtrlC);
|
||||
SameLine();
|
||||
TextColored((time_since_copy >= 0.0f && time_since_copy < 0.75f && ImFmod(time_since_copy, 0.25f) < 0.25f * 0.5f) ? ImVec4(1.f, 1.f, 0.3f, 1.f) : ImVec4(), "*COPIED*");
|
||||
if (tool->CopyToClipboardOnCtrlC && Shortcut(ImGuiMod_Ctrl | ImGuiKey_C, ImGuiInputFlags_RouteGlobalOverFocused))
|
||||
if (tool->CopyToClipboardOnCtrlC && Shortcut(ImGuiMod_Ctrl | ImGuiKey_C, ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverFocused))
|
||||
{
|
||||
tool->CopyToClipboardLastTime = (float)g.Time;
|
||||
char* p = g.TempBuffer.Data;
|
||||
|
22
imgui.h
22
imgui.h
@ -28,7 +28,7 @@
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.90.7 WIP"
|
||||
#define IMGUI_VERSION_NUM 19066
|
||||
#define IMGUI_VERSION_NUM 19067
|
||||
#define IMGUI_HAS_TABLE
|
||||
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
|
||||
#define IMGUI_HAS_DOCK // Docking WIP branch
|
||||
@ -1546,18 +1546,20 @@ enum ImGuiInputFlags_
|
||||
ImGuiInputFlags_Repeat = 1 << 0, // Enable repeat. Return true on successive repeats. Default for legacy IsKeyPressed(). NOT Default for legacy IsMouseClicked(). MUST BE == 1.
|
||||
|
||||
// Flags for Shortcut(), SetNextItemShortcut()
|
||||
// - Routing policies: RouteGlobalOverActive >> RouteActive or RouteFocused (if owner is active item) >> RouteGlobalOverFocused >> RouteFocused (if in focused window stack) >> RouteGlobal.
|
||||
// - Default policy is RouteFocused. Can select only 1 policy among all available.
|
||||
// - Priorities: GlobalHighest > Focused (if owner is active item) > GlobalOverFocused > Focused (if in focused window) > Global.
|
||||
ImGuiInputFlags_RouteFocused = 1 << 12, // Focus stack route (default): Accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window.
|
||||
ImGuiInputFlags_RouteGlobal = 1 << 13, // Global route (normal priority): unless a focused window or active item registered the route) -> recommended Global priority.
|
||||
ImGuiInputFlags_RouteGlobalOverFocused = 1 << 14, // Global route (higher priority): unless an active item registered the route, e.g. CTRL+A registered by InputText will take priority over this).
|
||||
ImGuiInputFlags_RouteGlobalHighest = 1 << 15, // Global route (highest priority): unlikely you need to use that: will interfere with every active items, e.g. CTRL+A registered by InputText will be overridden by this)
|
||||
ImGuiInputFlags_RouteAlways = 1 << 16, // Do not register route, poll keys directly.
|
||||
ImGuiInputFlags_RouteUnlessBgFocused = 1 << 17, // Option: global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications.
|
||||
ImGuiInputFlags_RouteFromRootWindow = 1 << 18, // Option: route evaluated from the point of view of root window rather than current window.
|
||||
ImGuiInputFlags_RouteActive = 1 << 10, // Route to active item only.
|
||||
ImGuiInputFlags_RouteFocused = 1 << 11, // Route to windows in the focus stack (DEFAULT). Deep-most focused window takes inputs. Active item takes inputs over deep-most focused window.
|
||||
ImGuiInputFlags_RouteGlobal = 1 << 12, // Global route (unless a focused window or active item registered the route).
|
||||
ImGuiInputFlags_RouteAlways = 1 << 13, // Do not register route, poll keys directly.
|
||||
// - Routing options
|
||||
ImGuiInputFlags_RouteOverFocused = 1 << 14, // Option: global route: higher priority than focused route (unless active item in focused route).
|
||||
ImGuiInputFlags_RouteOverActive = 1 << 15, // Option: global route: higher priority than active item. Unlikely you need to use that: will interfere with every active items, e.g. CTRL+A registered by InputText will be overridden by this. May not be fully honored as user/internal code is likely to always assume they can access keys when active.
|
||||
ImGuiInputFlags_RouteUnlessBgFocused = 1 << 16, // Option: global route: will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications.
|
||||
ImGuiInputFlags_RouteFromRootWindow = 1 << 17, // Option: route evaluated from the point of view of root window rather than current window.
|
||||
|
||||
// Flags for SetNextItemShortcut()
|
||||
ImGuiInputFlags_Tooltip = 1 << 19, // Automatically display a tooltip when hovering item.
|
||||
ImGuiInputFlags_Tooltip = 1 << 18, // Automatically display a tooltip when hovering item.
|
||||
};
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
|
259
imgui_demo.cpp
259
imgui_demo.cpp
@ -6260,12 +6260,14 @@ static void ShowDemoWindowInputs()
|
||||
// Display inputs submitted to ImGuiIO
|
||||
IMGUI_DEMO_MARKER("Inputs & Focus/Inputs");
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
if (ImGui::TreeNode("Inputs"))
|
||||
bool inputs_opened = ImGui::TreeNode("Inputs");
|
||||
ImGui::SameLine();
|
||||
HelpMarker(
|
||||
"This is a simplified view. See more detailed input state:\n"
|
||||
"- in 'Tools->Metrics/Debugger->Inputs'.\n"
|
||||
"- in 'Tools->Debug Log->IO'.");
|
||||
if (inputs_opened)
|
||||
{
|
||||
HelpMarker(
|
||||
"This is a simplified view. See more detailed input state:\n"
|
||||
"- in 'Tools->Metrics/Debugger->Inputs'.\n"
|
||||
"- in 'Tools->Debug Log->IO'.");
|
||||
if (ImGui::IsMousePosValid())
|
||||
ImGui::Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y);
|
||||
else
|
||||
@ -6296,15 +6298,17 @@ static void ShowDemoWindowInputs()
|
||||
// Display ImGuiIO output flags
|
||||
IMGUI_DEMO_MARKER("Inputs & Focus/Outputs");
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
if (ImGui::TreeNode("Outputs"))
|
||||
bool outputs_opened = ImGui::TreeNode("Outputs");
|
||||
ImGui::SameLine();
|
||||
HelpMarker(
|
||||
"The value of io.WantCaptureMouse and io.WantCaptureKeyboard are normally set by Dear ImGui "
|
||||
"to instruct your application of how to route inputs. Typically, when a value is true, it means "
|
||||
"Dear ImGui wants the corresponding inputs and we expect the underlying application to ignore them.\n\n"
|
||||
"The most typical case is: when hovering a window, Dear ImGui set io.WantCaptureMouse to true, "
|
||||
"and underlying application should ignore mouse inputs (in practice there are many and more subtle "
|
||||
"rules leading to how those flags are set).");
|
||||
if (outputs_opened)
|
||||
{
|
||||
HelpMarker(
|
||||
"The value of io.WantCaptureMouse and io.WantCaptureKeyboard are normally set by Dear ImGui "
|
||||
"to instruct your application of how to route inputs. Typically, when a value is true, it means "
|
||||
"Dear ImGui wants the corresponding inputs and we expect the underlying application to ignore them.\n\n"
|
||||
"The most typical case is: when hovering a window, Dear ImGui set io.WantCaptureMouse to true, "
|
||||
"and underlying application should ignore mouse inputs (in practice there are many and more subtle "
|
||||
"rules leading to how those flags are set).");
|
||||
ImGui::Text("io.WantCaptureMouse: %d", io.WantCaptureMouse);
|
||||
ImGui::Text("io.WantCaptureMouseUnlessPopupClose: %d", io.WantCaptureMouseUnlessPopupClose);
|
||||
ImGui::Text("io.WantCaptureKeyboard: %d", io.WantCaptureKeyboard);
|
||||
@ -6351,27 +6355,42 @@ static void ShowDemoWindowInputs()
|
||||
IMGUI_DEMO_MARKER("Inputs & Focus/Shortcuts");
|
||||
if (ImGui::TreeNode("Shortcuts"))
|
||||
{
|
||||
static ImGuiInputFlags route_options = ImGuiInputFlags_Repeat;
|
||||
static ImGuiInputFlags route_type = ImGuiInputFlags_RouteFocused;
|
||||
ImGui::CheckboxFlags("ImGuiInputFlags_Repeat", &route_options, ImGuiInputFlags_Repeat);
|
||||
ImGui::RadioButton("ImGuiInputFlags_RouteActive", &route_type, ImGuiInputFlags_RouteActive);
|
||||
ImGui::RadioButton("ImGuiInputFlags_RouteFocused (default)", &route_type, ImGuiInputFlags_RouteFocused);
|
||||
ImGui::RadioButton("ImGuiInputFlags_RouteGlobal", &route_type, ImGuiInputFlags_RouteGlobal);
|
||||
ImGui::Indent();
|
||||
ImGui::BeginDisabled(route_type != ImGuiInputFlags_RouteGlobal);
|
||||
ImGui::CheckboxFlags("ImGuiInputFlags_RouteOverFocused", &route_options, ImGuiInputFlags_RouteOverFocused);
|
||||
ImGui::CheckboxFlags("ImGuiInputFlags_RouteOverActive", &route_options, ImGuiInputFlags_RouteOverActive);
|
||||
ImGui::CheckboxFlags("ImGuiInputFlags_RouteUnlessBgFocused", &route_options, ImGuiInputFlags_RouteUnlessBgFocused);
|
||||
ImGui::EndDisabled();
|
||||
ImGui::Unindent();
|
||||
ImGui::RadioButton("ImGuiInputFlags_RouteAlways", &route_type, ImGuiInputFlags_RouteAlways);
|
||||
ImGuiInputFlags flags = route_type | route_options; // Merged flags
|
||||
if (route_type != ImGuiInputFlags_RouteGlobal)
|
||||
route_options &= ~(ImGuiInputFlags_RouteOverFocused | ImGuiInputFlags_RouteOverActive | ImGuiInputFlags_RouteUnlessBgFocused);
|
||||
|
||||
ImGui::SeparatorText("Using SetNextItemShortcut()");
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_S);
|
||||
ImGui::Text("Ctrl+S");
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_S, flags | ImGuiInputFlags_Tooltip);
|
||||
ImGui::Button("Save");
|
||||
ImGui::SetItemTooltip("Ctrl+S"); // FIXME: Tooltip could be automatically submitted by SetNextItemShortcut
|
||||
ImGui::Text("Alt+F");
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Alt | ImGuiKey_F, flags | ImGuiInputFlags_Tooltip);
|
||||
static float f = 0.5f;
|
||||
ImGui::SliderFloat("Factor", &f, 0.0f, 1.0f);
|
||||
|
||||
ImGui::SeparatorText("Using Shortcut()");
|
||||
const float line_height = ImGui::GetTextLineHeightWithSpacing();
|
||||
const ImGuiKeyChord key_chord = ImGuiMod_Ctrl | ImGuiKey_A;
|
||||
static ImGuiInputFlags other_flags = ImGuiInputFlags_Repeat;
|
||||
static ImGuiInputFlags routing_flags = ImGuiInputFlags_RouteFocused;
|
||||
ImGui::CheckboxFlags("ImGuiInputFlags_Repeat", &other_flags, ImGuiInputFlags_Repeat);
|
||||
ImGui::RadioButton("ImGuiInputFlags_RouteFocused (default)", &routing_flags, ImGuiInputFlags_RouteFocused);
|
||||
ImGui::RadioButton("ImGuiInputFlags_RouteAlways", &routing_flags, ImGuiInputFlags_RouteAlways);
|
||||
ImGui::RadioButton("ImGuiInputFlags_RouteGlobal", &routing_flags, ImGuiInputFlags_RouteGlobal);
|
||||
ImGui::RadioButton("ImGuiInputFlags_RouteGlobalOverFocused", &routing_flags, ImGuiInputFlags_RouteGlobalOverFocused);
|
||||
ImGui::RadioButton("ImGuiInputFlags_RouteGlobalHighest", &routing_flags, ImGuiInputFlags_RouteGlobalHighest);
|
||||
ImGui::CheckboxFlags("ImGuiInputFlags_RouteUnlessBgFocused", &other_flags, ImGuiInputFlags_RouteUnlessBgFocused);
|
||||
const ImGuiInputFlags flags = other_flags | routing_flags; // Merged flags
|
||||
|
||||
ImGui::Text("Ctrl+A");
|
||||
ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags) ? "PRESSED" : "...");
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 0.0f, 1.0f, 0.1f));
|
||||
|
||||
ImGui::BeginChild("WindowA", ImVec2(-FLT_MIN, line_height * 14), true);
|
||||
ImGui::Text("Press CTRL+A and see who receives it!");
|
||||
ImGui::Separator();
|
||||
@ -6414,6 +6433,7 @@ static void ShowDemoWindowInputs()
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
@ -8640,51 +8660,85 @@ void ShowExampleAppDockSpace(bool* p_open)
|
||||
// Simplified structure to mimic a Document model
|
||||
struct MyDocument
|
||||
{
|
||||
const char* Name; // Document title
|
||||
char Name[32]; // Document title
|
||||
int UID; // Unique ID (necessary as we can change title)
|
||||
bool Open; // Set when open (we keep an array of all available documents to simplify demo code!)
|
||||
bool OpenPrev; // Copy of Open from last update.
|
||||
bool Dirty; // Set when the document has been modified
|
||||
bool WantClose; // Set when the document
|
||||
ImVec4 Color; // An arbitrary variable associated to the document
|
||||
|
||||
MyDocument(const char* name, bool open = true, const ImVec4& color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f))
|
||||
MyDocument(int uid, const char* name, bool open = true, const ImVec4& color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f))
|
||||
{
|
||||
Name = name;
|
||||
UID = uid;
|
||||
snprintf(Name, sizeof(Name), "%s", name);
|
||||
Open = OpenPrev = open;
|
||||
Dirty = false;
|
||||
WantClose = false;
|
||||
Color = color;
|
||||
}
|
||||
void DoOpen() { Open = true; }
|
||||
void DoQueueClose() { WantClose = true; }
|
||||
void DoForceClose() { Open = false; Dirty = false; }
|
||||
void DoSave() { Dirty = false; }
|
||||
};
|
||||
|
||||
struct ExampleAppDocuments
|
||||
{
|
||||
ImVector<MyDocument> Documents;
|
||||
ImVector<MyDocument*> CloseQueue;
|
||||
MyDocument* RenamingDoc = NULL;
|
||||
bool RenamingStarted = false;
|
||||
|
||||
ExampleAppDocuments()
|
||||
{
|
||||
Documents.push_back(MyDocument(0, "Lettuce", true, ImVec4(0.4f, 0.8f, 0.4f, 1.0f)));
|
||||
Documents.push_back(MyDocument(1, "Eggplant", true, ImVec4(0.8f, 0.5f, 1.0f, 1.0f)));
|
||||
Documents.push_back(MyDocument(2, "Carrot", true, ImVec4(1.0f, 0.8f, 0.5f, 1.0f)));
|
||||
Documents.push_back(MyDocument(3, "Tomato", false, ImVec4(1.0f, 0.3f, 0.4f, 1.0f)));
|
||||
Documents.push_back(MyDocument(4, "A Rather Long Title", false, ImVec4(0.4f, 0.8f, 0.8f, 1.0f)));
|
||||
Documents.push_back(MyDocument(5, "Some Document", false, ImVec4(0.8f, 0.8f, 1.0f, 1.0f)));
|
||||
}
|
||||
|
||||
// As we allow to change document name, we append a never-changing document ID so tabs are stable
|
||||
void GetTabName(MyDocument* doc, char* out_buf, size_t out_buf_size)
|
||||
{
|
||||
snprintf(out_buf, out_buf_size, "%s###doc%d", doc->Name, doc->UID);
|
||||
}
|
||||
|
||||
// Display placeholder contents for the Document
|
||||
static void DisplayContents(MyDocument* doc)
|
||||
void DisplayDocContents(MyDocument* doc)
|
||||
{
|
||||
ImGui::PushID(doc);
|
||||
ImGui::Text("Document \"%s\"", doc->Name);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, doc->Color);
|
||||
ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_R, ImGuiInputFlags_Tooltip);
|
||||
if (ImGui::Button("Rename.."))
|
||||
{
|
||||
RenamingDoc = doc;
|
||||
RenamingStarted = true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_M, ImGuiInputFlags_Tooltip);
|
||||
if (ImGui::Button("Modify"))
|
||||
doc->Dirty = true;
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_S, ImGuiInputFlags_Tooltip);
|
||||
if (ImGui::Button("Save"))
|
||||
doc->DoSave();
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_W, ImGuiInputFlags_Tooltip);
|
||||
if (ImGui::Button("Close"))
|
||||
doc->DoQueueClose();
|
||||
CloseQueue.push_back(doc);
|
||||
ImGui::ColorEdit3("color", &doc->Color.x); // Useful to test drag and drop and hold-dragged-to-open-tab behavior.
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
// Display context menu for the Document
|
||||
static void DisplayContextMenu(MyDocument* doc)
|
||||
void DisplayDocContextMenu(MyDocument* doc)
|
||||
{
|
||||
if (!ImGui::BeginPopupContextItem())
|
||||
return;
|
||||
@ -8693,45 +8747,32 @@ struct MyDocument
|
||||
sprintf(buf, "Save %s", doc->Name);
|
||||
if (ImGui::MenuItem(buf, "Ctrl+S", false, doc->Open))
|
||||
doc->DoSave();
|
||||
if (ImGui::MenuItem("Rename...", "Ctrl+R", false, doc->Open))
|
||||
RenamingDoc = doc;
|
||||
if (ImGui::MenuItem("Close", "Ctrl+W", false, doc->Open))
|
||||
doc->DoQueueClose();
|
||||
CloseQueue.push_back(doc);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
};
|
||||
|
||||
struct ExampleAppDocuments
|
||||
{
|
||||
ImVector<MyDocument> Documents;
|
||||
|
||||
ExampleAppDocuments()
|
||||
// [Optional] Notify the system of Tabs/Windows closure that happened outside the regular tab interface.
|
||||
// If a tab has been closed programmatically (aka closed from another source such as the Checkbox() in the demo,
|
||||
// as opposed to clicking on the regular tab closing button) and stops being submitted, it will take a frame for
|
||||
// the tab bar to notice its absence. During this frame there will be a gap in the tab bar, and if the tab that has
|
||||
// disappeared was the selected one, the tab bar will report no selected tab during the frame. This will effectively
|
||||
// give the impression of a flicker for one frame.
|
||||
// We call SetTabItemClosed() to manually notify the Tab Bar or Docking system of removed tabs to avoid this glitch.
|
||||
// Note that this completely optional, and only affect tab bars with the ImGuiTabBarFlags_Reorderable flag.
|
||||
void NotifyOfDocumentsClosedElsewhere()
|
||||
{
|
||||
Documents.push_back(MyDocument("Lettuce", true, ImVec4(0.4f, 0.8f, 0.4f, 1.0f)));
|
||||
Documents.push_back(MyDocument("Eggplant", true, ImVec4(0.8f, 0.5f, 1.0f, 1.0f)));
|
||||
Documents.push_back(MyDocument("Carrot", true, ImVec4(1.0f, 0.8f, 0.5f, 1.0f)));
|
||||
Documents.push_back(MyDocument("Tomato", false, ImVec4(1.0f, 0.3f, 0.4f, 1.0f)));
|
||||
Documents.push_back(MyDocument("A Rather Long Title", false));
|
||||
Documents.push_back(MyDocument("Some Document", false));
|
||||
for (MyDocument& doc : Documents)
|
||||
{
|
||||
if (!doc.Open && doc.OpenPrev)
|
||||
ImGui::SetTabItemClosed(doc.Name);
|
||||
doc.OpenPrev = doc.Open;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// [Optional] Notify the system of Tabs/Windows closure that happened outside the regular tab interface.
|
||||
// If a tab has been closed programmatically (aka closed from another source such as the Checkbox() in the demo,
|
||||
// as opposed to clicking on the regular tab closing button) and stops being submitted, it will take a frame for
|
||||
// the tab bar to notice its absence. During this frame there will be a gap in the tab bar, and if the tab that has
|
||||
// disappeared was the selected one, the tab bar will report no selected tab during the frame. This will effectively
|
||||
// give the impression of a flicker for one frame.
|
||||
// We call SetTabItemClosed() to manually notify the Tab Bar or Docking system of removed tabs to avoid this glitch.
|
||||
// Note that this completely optional, and only affect tab bars with the ImGuiTabBarFlags_Reorderable flag.
|
||||
static void NotifyOfDocumentsClosedElsewhere(ExampleAppDocuments& app)
|
||||
{
|
||||
for (MyDocument& doc : app.Documents)
|
||||
{
|
||||
if (!doc.Open && doc.OpenPrev)
|
||||
ImGui::SetTabItemClosed(doc.Name);
|
||||
doc.OpenPrev = doc.Open;
|
||||
}
|
||||
}
|
||||
|
||||
void ShowExampleAppDocuments(bool* p_open)
|
||||
{
|
||||
static ExampleAppDocuments app;
|
||||
@ -8779,7 +8820,7 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
}
|
||||
if (ImGui::MenuItem("Close All Documents", NULL, false, open_count > 0))
|
||||
for (MyDocument& doc : app.Documents)
|
||||
doc.DoQueueClose();
|
||||
app.CloseQueue.push_back(&doc);
|
||||
if (ImGui::MenuItem("Exit") && p_open)
|
||||
*p_open = false;
|
||||
ImGui::EndMenu();
|
||||
@ -8825,7 +8866,7 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
if (ImGui::BeginTabBar("##tabs", tab_bar_flags))
|
||||
{
|
||||
if (opt_reorderable)
|
||||
NotifyOfDocumentsClosedElsewhere(app);
|
||||
app.NotifyOfDocumentsClosedElsewhere();
|
||||
|
||||
// [DEBUG] Stress tests
|
||||
//if ((ImGui::GetFrameCount() % 30) == 0) docs[1].Open ^= 1; // [DEBUG] Automatically show/hide a tab. Test various interactions e.g. dragging with this on.
|
||||
@ -8837,20 +8878,23 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
if (!doc.Open)
|
||||
continue;
|
||||
|
||||
// As we allow to change document name, we append a never-changing document id so tabs are stable
|
||||
char doc_name_buf[64];
|
||||
app.GetTabName(&doc, doc_name_buf, sizeof(doc_name_buf));
|
||||
ImGuiTabItemFlags tab_flags = (doc.Dirty ? ImGuiTabItemFlags_UnsavedDocument : 0);
|
||||
bool visible = ImGui::BeginTabItem(doc.Name, &doc.Open, tab_flags);
|
||||
bool visible = ImGui::BeginTabItem(doc_name_buf, &doc.Open, tab_flags);
|
||||
|
||||
// Cancel attempt to close when unsaved add to save queue so we can display a popup.
|
||||
if (!doc.Open && doc.Dirty)
|
||||
{
|
||||
doc.Open = true;
|
||||
doc.DoQueueClose();
|
||||
app.CloseQueue.push_back(&doc);
|
||||
}
|
||||
|
||||
MyDocument::DisplayContextMenu(&doc);
|
||||
app.DisplayDocContextMenu(&doc);
|
||||
if (visible)
|
||||
{
|
||||
MyDocument::DisplayContents(&doc);
|
||||
app.DisplayDocContents(&doc);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
@ -8862,7 +8906,7 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
{
|
||||
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_DockingEnable)
|
||||
{
|
||||
NotifyOfDocumentsClosedElsewhere(app);
|
||||
app.NotifyOfDocumentsClosedElsewhere();
|
||||
|
||||
// Create a DockSpace node where any window can be docked
|
||||
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
|
||||
@ -8883,12 +8927,12 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
if (!doc->Open && doc->Dirty)
|
||||
{
|
||||
doc->Open = true;
|
||||
doc->DoQueueClose();
|
||||
app.CloseQueue.push_back(doc);
|
||||
}
|
||||
|
||||
MyDocument::DisplayContextMenu(doc);
|
||||
app.DisplayDocContextMenu(doc);
|
||||
if (visible)
|
||||
MyDocument::DisplayContents(doc);
|
||||
app.DisplayDocContents(doc);
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
@ -8906,33 +8950,44 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
return;
|
||||
}
|
||||
|
||||
// Update closing queue
|
||||
static ImVector<MyDocument*> close_queue;
|
||||
if (close_queue.empty())
|
||||
// Display renaming UI
|
||||
if (app.RenamingDoc != NULL)
|
||||
{
|
||||
// Close queue is locked once we started a popup
|
||||
for (MyDocument& doc : app.Documents)
|
||||
if (doc.WantClose)
|
||||
if (app.RenamingStarted)
|
||||
ImGui::OpenPopup("Rename");
|
||||
if (ImGui::BeginPopup("Rename"))
|
||||
{
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 30);
|
||||
if (ImGui::InputText("###Name", app.RenamingDoc->Name, IM_ARRAYSIZE(app.RenamingDoc->Name), ImGuiInputTextFlags_EnterReturnsTrue))
|
||||
{
|
||||
doc.WantClose = false;
|
||||
close_queue.push_back(&doc);
|
||||
ImGui::CloseCurrentPopup();
|
||||
app.RenamingDoc = NULL;
|
||||
}
|
||||
if (app.RenamingStarted)
|
||||
ImGui::SetKeyboardFocusHere(-1);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.RenamingDoc = NULL;
|
||||
}
|
||||
app.RenamingStarted = false;
|
||||
}
|
||||
|
||||
// Display closing confirmation UI
|
||||
if (!close_queue.empty())
|
||||
if (!app.CloseQueue.empty())
|
||||
{
|
||||
int close_queue_unsaved_documents = 0;
|
||||
for (int n = 0; n < close_queue.Size; n++)
|
||||
if (close_queue[n]->Dirty)
|
||||
for (int n = 0; n < app.CloseQueue.Size; n++)
|
||||
if (app.CloseQueue[n]->Dirty)
|
||||
close_queue_unsaved_documents++;
|
||||
|
||||
if (close_queue_unsaved_documents == 0)
|
||||
{
|
||||
// Close documents when all are unsaved
|
||||
for (int n = 0; n < close_queue.Size; n++)
|
||||
close_queue[n]->DoForceClose();
|
||||
close_queue.clear();
|
||||
for (int n = 0; n < app.CloseQueue.Size; n++)
|
||||
app.CloseQueue[n]->DoForceClose();
|
||||
app.CloseQueue.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -8943,37 +8998,35 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
ImGui::Text("Save change to the following items?");
|
||||
float item_height = ImGui::GetTextLineHeightWithSpacing();
|
||||
if (ImGui::BeginChild(ImGui::GetID("frame"), ImVec2(-FLT_MIN, 6.25f * item_height), ImGuiChildFlags_FrameStyle))
|
||||
{
|
||||
for (int n = 0; n < close_queue.Size; n++)
|
||||
if (close_queue[n]->Dirty)
|
||||
ImGui::Text("%s", close_queue[n]->Name);
|
||||
}
|
||||
for (MyDocument* doc : app.CloseQueue)
|
||||
if (doc->Dirty)
|
||||
ImGui::Text("%s", doc->Name);
|
||||
ImGui::EndChild();
|
||||
|
||||
ImVec2 button_size(ImGui::GetFontSize() * 7.0f, 0.0f);
|
||||
if (ImGui::Button("Yes", button_size))
|
||||
{
|
||||
for (int n = 0; n < close_queue.Size; n++)
|
||||
for (MyDocument* doc : app.CloseQueue)
|
||||
{
|
||||
if (close_queue[n]->Dirty)
|
||||
close_queue[n]->DoSave();
|
||||
close_queue[n]->DoForceClose();
|
||||
if (doc->Dirty)
|
||||
doc->DoSave();
|
||||
doc->DoForceClose();
|
||||
}
|
||||
close_queue.clear();
|
||||
app.CloseQueue.clear();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("No", button_size))
|
||||
{
|
||||
for (int n = 0; n < close_queue.Size; n++)
|
||||
close_queue[n]->DoForceClose();
|
||||
close_queue.clear();
|
||||
for (MyDocument* doc : app.CloseQueue)
|
||||
doc->DoForceClose();
|
||||
app.CloseQueue.clear();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Cancel", button_size))
|
||||
{
|
||||
close_queue.clear();
|
||||
app.CloseQueue.clear();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
|
@ -1484,24 +1484,23 @@ enum ImGuiInputFlagsPrivate_
|
||||
ImGuiInputFlags_RepeatUntilKeyModsChangeFromNone = 1 << 6, // Stop repeating when released OR if keyboard mods are leaving the None state. Allows going from Mod+Key to Key by releasing Mod.
|
||||
ImGuiInputFlags_RepeatUntilOtherKeyPress = 1 << 7, // Stop repeating when released OR if any other keyboard key is pressed during the repeat
|
||||
|
||||
// Flags for SetItemKeyOwner()
|
||||
// - Condition
|
||||
ImGuiInputFlags_CondHovered = 1 << 8, // Only set if item is hovered (default to both)
|
||||
ImGuiInputFlags_CondActive = 1 << 9, // Only set if item is active (default to both)
|
||||
ImGuiInputFlags_CondDefault_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive,
|
||||
|
||||
// Flags for SetKeyOwner(), SetItemKeyOwner()
|
||||
// - Locking key away from non-input aware code. Locking is useful to make input-owner-aware code steal keys from non-input-owner-aware code. If all code is input-owner-aware locking would never be necessary.
|
||||
ImGuiInputFlags_LockThisFrame = 1 << 10, // Further accesses to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame.
|
||||
ImGuiInputFlags_LockUntilRelease = 1 << 11, // Further accesses to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when the key is released or at end of each frame if key is released.
|
||||
ImGuiInputFlags_LockThisFrame = 1 << 20, // Further accesses to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame.
|
||||
ImGuiInputFlags_LockUntilRelease = 1 << 21, // Further accesses to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when the key is released or at end of each frame if key is released.
|
||||
|
||||
// - Condition for SetItemKeyOwner()
|
||||
ImGuiInputFlags_CondHovered = 1 << 22, // Only set if item is hovered (default to both)
|
||||
ImGuiInputFlags_CondActive = 1 << 23, // Only set if item is active (default to both)
|
||||
ImGuiInputFlags_CondDefault_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive,
|
||||
|
||||
// [Internal] Mask of which function support which flags
|
||||
ImGuiInputFlags_RepeatRateMask_ = ImGuiInputFlags_RepeatRateDefault | ImGuiInputFlags_RepeatRateNavMove | ImGuiInputFlags_RepeatRateNavTweak,
|
||||
ImGuiInputFlags_RepeatUntilMask_ = ImGuiInputFlags_RepeatUntilRelease | ImGuiInputFlags_RepeatUntilKeyModsChange | ImGuiInputFlags_RepeatUntilKeyModsChangeFromNone | ImGuiInputFlags_RepeatUntilOtherKeyPress,
|
||||
ImGuiInputFlags_RepeatMask_ = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RepeatUntilMask_,
|
||||
ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive,
|
||||
ImGuiInputFlags_RouteTypeMask_ = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobalOverFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteGlobalHighest | ImGuiInputFlags_RouteAlways,
|
||||
ImGuiInputFlags_RouteOptionsMask_ = ImGuiInputFlags_RouteUnlessBgFocused | ImGuiInputFlags_RouteFromRootWindow,
|
||||
ImGuiInputFlags_RouteTypeMask_ = ImGuiInputFlags_RouteActive | ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteAlways,
|
||||
ImGuiInputFlags_RouteOptionsMask_ = ImGuiInputFlags_RouteOverFocused | ImGuiInputFlags_RouteOverActive | ImGuiInputFlags_RouteUnlessBgFocused | ImGuiInputFlags_RouteFromRootWindow,
|
||||
ImGuiInputFlags_SupportedByIsKeyPressed = ImGuiInputFlags_RepeatMask_,
|
||||
ImGuiInputFlags_SupportedByIsMouseClicked = ImGuiInputFlags_Repeat,
|
||||
ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteTypeMask_ | ImGuiInputFlags_RouteOptionsMask_,
|
||||
@ -3516,7 +3515,7 @@ namespace ImGui
|
||||
// - You can chain two unrelated windows in the focus stack using SetWindowParentWindowForFocusRoute()
|
||||
// e.g. if you have a tool window associated to a document, and you want document shortcuts to run when the tool is focused.
|
||||
IMGUI_API bool Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id);
|
||||
IMGUI_API bool SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id, ImGuiID focus_scope_id); // routing policy and owner_id needs to be explicit and cannot be 0
|
||||
IMGUI_API bool SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id); // routing policy and owner_id needs to be explicit and cannot be 0
|
||||
IMGUI_API bool TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id);
|
||||
IMGUI_API ImGuiKeyRoutingData* GetShortcutRoutingData(ImGuiKeyChord key_chord);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user