mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-07 21:39:54 +02:00
Merge branch 'master' into viewport
# Conflicts: # examples/allegro5_example/imgui_impl_a5.cpp # examples/allegro5_example/imgui_impl_a5.h # examples/allegro5_example/imgui_impl_allegro5.cpp # examples/allegro5_example/imgui_impl_allegro5.h # examples/allegro5_example/main.cpp # examples/imgui_impl_allegro5.cpp # examples/imgui_impl_allegro5.h # imgui.cpp # imgui_internal.h
This commit is contained in:
134
imgui.cpp
134
imgui.cpp
@ -124,7 +124,7 @@
|
||||
- Call ImGui::NewFrame() to begin the frame
|
||||
- You can use any ImGui function you want between NewFrame() and Render()
|
||||
- Call ImGui::Render() as late as you can to end the frame and finalize render data. it will call your io.RenderDrawListFn handler.
|
||||
(Even if you don't render, call Render() and ignore the callback, or call EndFrame() instead. Otherwhise some features will break)
|
||||
(Even if you don't render, call Render() and ignore the callback, or call EndFrame() instead. Otherwise some features will break)
|
||||
- All rendering information are stored into command-lists until ImGui::Render() is called.
|
||||
- Dear ImGui never touches or knows about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you provide.
|
||||
- Effectively it means you can create widgets at any time in your code, regardless of considerations of being in "update" vs "render" phases
|
||||
@ -275,7 +275,7 @@
|
||||
- 2018/02/07 (1.60) - reorganized context handling to be more explicit,
|
||||
- YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END.
|
||||
- removed Shutdown() function, as DestroyContext() serve this purpose.
|
||||
- you may pass a ImFontAtlas* pointer to CreateContext() to share a font atlas between contexts. Otherwhise CreateContext() will create its own font atlas instance.
|
||||
- you may pass a ImFontAtlas* pointer to CreateContext() to share a font atlas between contexts. Otherwise CreateContext() will create its own font atlas instance.
|
||||
- removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions(), and shared by all contexts.
|
||||
- removed the default global context and font atlas instance, which were confusing for users of DLL reloading and users of multiple contexts.
|
||||
- 2018/01/31 (1.60) - moved sample TTF files from extra_fonts/ to misc/fonts/. If you loaded files directly from the imgui repo you may need to update your paths.
|
||||
@ -777,7 +777,7 @@ static void SetClipboardTextFn_DefaultImpl(void* user_data, const ch
|
||||
// Context
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Current context pointer. Implicitely used by all ImGui functions. Always assumed to be != NULL.
|
||||
// Current context pointer. Implicitly used by all ImGui functions. Always assumed to be != NULL.
|
||||
// CreateContext() will automatically set this pointer if it is NULL. Change to a different context by calling ImGui::SetCurrentContext().
|
||||
// If you use DLL hotreloading you might need to call SetCurrentContext() after reloading code from this file.
|
||||
// ImGui functions are not thread-safe because of this pointer. If you want thread-safety to allow N threads to access N different contexts, you can:
|
||||
@ -1927,7 +1927,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
|
||||
ViewportId = 0;
|
||||
ViewportAllowPlatformMonitorExtend = -1;
|
||||
ViewportPos = ImVec2(FLT_MAX, FLT_MAX);
|
||||
PosFloat = Pos = ImVec2(0.0f, 0.0f);
|
||||
Pos = ImVec2(0.0f, 0.0f);
|
||||
Size = SizeFull = ImVec2(0.0f, 0.0f);
|
||||
SizeContents = SizeContentsExplicit = ImVec2(0.0f, 0.0f);
|
||||
WindowPadding = ImVec2(0.0f, 0.0f);
|
||||
@ -2944,8 +2944,8 @@ static void ImGui::NavUpdateWindowing()
|
||||
if (move_delta.x != 0.0f || move_delta.y != 0.0f)
|
||||
{
|
||||
const float NAV_MOVE_SPEED = 800.0f;
|
||||
const float move_speed = ImFloor(NAV_MOVE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y));
|
||||
g.NavWindowingTarget->PosFloat += move_delta * move_speed;
|
||||
const float move_speed = ImFloor(NAV_MOVE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y)); // FIXME: Doesn't code variable framerate very well
|
||||
g.NavWindowingTarget->Pos += move_delta * move_speed;
|
||||
g.NavDisableMouseHover = true;
|
||||
MarkIniSettingsDirty(g.NavWindowingTarget);
|
||||
}
|
||||
@ -3351,7 +3351,7 @@ static void ImGui::UpdateMovingWindow()
|
||||
if (g.IO.MouseDown[0] && IsMousePosValid(&g.IO.MousePos))
|
||||
{
|
||||
ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset;
|
||||
if (moving_window->PosFloat.x != pos.x || moving_window->PosFloat.y != pos.y)
|
||||
if (moving_window->Pos.x != pos.x || moving_window->Pos.y != pos.y)
|
||||
{
|
||||
MarkIniSettingsDirty(moving_window);
|
||||
SetWindowPos(moving_window, pos, ImGuiCond_Always);
|
||||
@ -3405,7 +3405,6 @@ static ImGuiViewportP* FindViewportHoveredFromPlatformWindowStack(const ImVec2 m
|
||||
static void TranslateWindow(ImGuiWindow* window, const ImVec2& delta)
|
||||
{
|
||||
window->Pos += delta;
|
||||
window->PosFloat += delta;
|
||||
window->ClipRect.Translate(delta);
|
||||
window->WindowRectClipped.Translate(delta);
|
||||
window->InnerRect.Translate(delta);
|
||||
@ -3954,7 +3953,6 @@ void ImGui::NewFrame()
|
||||
|
||||
const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size;
|
||||
window->Pos += offset;
|
||||
window->PosFloat += offset;
|
||||
window->Size *= scale;
|
||||
window->SizeFull *= scale;
|
||||
}
|
||||
@ -5804,9 +5802,10 @@ static void CheckStacksSize(ImGuiWindow* window, bool write)
|
||||
{ int current = window->IDStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushID/PopID or TreeNode/TreePop Mismatch!"); p_backup++; } // Too few or too many PopID()/TreePop()
|
||||
{ int current = window->DC.GroupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "BeginGroup/EndGroup Mismatch!"); p_backup++; } // Too few or too many EndGroup()
|
||||
{ int current = g.CurrentPopupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "BeginMenu/EndMenu or BeginPopup/EndPopup Mismatch"); p_backup++;}// Too few or too many EndMenu()/EndPopup()
|
||||
{ int current = g.ColorModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushStyleColor/PopStyleColor Mismatch!"); p_backup++; } // Too few or too many PopStyleColor()
|
||||
{ int current = g.StyleModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushStyleVar/PopStyleVar Mismatch!"); p_backup++; } // Too few or too many PopStyleVar()
|
||||
{ int current = g.FontStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushFont/PopFont Mismatch!"); p_backup++; } // Too few or too many PopFont()
|
||||
// For color, style and font stacks there is an incentive to use Push/Begin/Pop/.../End patterns, so we relax our checks a little to allow them.
|
||||
{ int current = g.ColorModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup >= current && "PushStyleColor/PopStyleColor Mismatch!"); p_backup++; } // Too few or too many PopStyleColor()
|
||||
{ int current = g.StyleModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup >= current && "PushStyleVar/PopStyleVar Mismatch!"); p_backup++; } // Too few or too many PopStyleVar()
|
||||
{ int current = g.FontStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup >= current && "PushFont/PopFont Mismatch!"); p_backup++; } // Too few or too many PopFont()
|
||||
IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup));
|
||||
}
|
||||
|
||||
@ -5910,13 +5909,13 @@ static ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window)
|
||||
r_avoid = ImRect(-FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight(), FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight() + parent_window->MenuBarHeight());
|
||||
else
|
||||
r_avoid = ImRect(parent_window->Pos.x + horizontal_overlap, -FLT_MAX, parent_window->Pos.x + parent_window->Size.x - horizontal_overlap - parent_window->ScrollbarSizes.x, FLT_MAX);
|
||||
return FindBestWindowPosForPopupEx(window->PosFloat, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid);
|
||||
return FindBestWindowPosForPopupEx(window->Pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid);
|
||||
}
|
||||
if (window->Flags & ImGuiWindowFlags_Popup)
|
||||
{
|
||||
ImRect r_outer = FindAllowedExtentRectForWindow(window);
|
||||
ImRect r_avoid = ImRect(window->PosFloat.x - 1, window->PosFloat.y - 1, window->PosFloat.x + 1, window->PosFloat.y + 1);
|
||||
return FindBestWindowPosForPopupEx(window->PosFloat, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid);
|
||||
ImRect r_avoid = ImRect(window->Pos.x - 1, window->Pos.y - 1, window->Pos.x + 1, window->Pos.y + 1);
|
||||
return FindBestWindowPosForPopupEx(window->Pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid);
|
||||
}
|
||||
if (window->Flags & ImGuiWindowFlags_Tooltip)
|
||||
{
|
||||
@ -5935,7 +5934,7 @@ static ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window)
|
||||
return pos;
|
||||
}
|
||||
IM_ASSERT(0);
|
||||
return window->PosFloat;
|
||||
return window->Pos;
|
||||
}
|
||||
|
||||
static void SetWindowConditionAllowFlags(ImGuiWindow* window, ImGuiCond flags, bool enabled)
|
||||
@ -5961,13 +5960,16 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
|
||||
window->Flags = flags;
|
||||
g.WindowsById.SetVoidPtr(window->ID, window);
|
||||
|
||||
// Default/arbitrary window position. Use SetNextWindowPos() with the appropriate condition flag to change the initial position of a window.
|
||||
window->Pos = ImVec2(60, 60);
|
||||
|
||||
// User can disable loading and saving of settings. Tooltip and child windows also don't store settings.
|
||||
if (!(flags & ImGuiWindowFlags_NoSavedSettings))
|
||||
{
|
||||
// Retrieve settings from .ini file
|
||||
// Use SetWindowPos() or SetNextWindowPos() with the appropriate condition flag to change the initial position of a window.
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
window->Pos = window->PosFloat = main_viewport->Pos + ImVec2(60, 60);
|
||||
window->Pos = main_viewport->Pos + ImVec2(60, 60);
|
||||
|
||||
if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID))
|
||||
{
|
||||
@ -5981,10 +5983,10 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
|
||||
{
|
||||
window->ViewportPos = main_viewport->Pos;
|
||||
}
|
||||
window->Pos = window->PosFloat = ImFloor(settings->Pos + window->ViewportPos);
|
||||
window->Pos = ImFloor(settings->Pos + window->ViewportPos);
|
||||
window->Collapsed = settings->Collapsed;
|
||||
if (ImLengthSqr(settings->Size) > 0.00001f)
|
||||
size = settings->Size;
|
||||
size = ImFloor(settings->Size);
|
||||
}
|
||||
}
|
||||
window->Size = window->SizeFull = window->SizeFullAtLastBegin = size;
|
||||
@ -6316,7 +6318,8 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au
|
||||
|
||||
// Using the FlattenChilds button flag we make the resize button accessible even if we are hovering over a child window
|
||||
ImRect resize_rect(corner, corner + grip.InnerDir * grip_hover_size);
|
||||
resize_rect.FixInverted();
|
||||
if (resize_rect.Min.x > resize_rect.Max.x) ImSwap(resize_rect.Min.x, resize_rect.Max.x);
|
||||
if (resize_rect.Min.y > resize_rect.Max.y) ImSwap(resize_rect.Min.y, resize_rect.Max.y);
|
||||
bool hovered, held;
|
||||
ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus);
|
||||
if (hovered || held)
|
||||
@ -6395,7 +6398,7 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au
|
||||
}
|
||||
if (pos_target.x != FLT_MAX)
|
||||
{
|
||||
window->Pos = window->PosFloat = ImFloor(pos_target);
|
||||
window->Pos = ImFloor(pos_target);
|
||||
MarkIniSettingsDirty(window);
|
||||
}
|
||||
|
||||
@ -6404,7 +6407,7 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au
|
||||
|
||||
static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& rect, const ImVec2& padding)
|
||||
{
|
||||
window->PosFloat = ImMin(rect.Max - padding, ImMax(window->PosFloat + window->Size, rect.Min + padding) - window->Size);
|
||||
window->Pos = ImMin(rect.Max - padding, ImMax(window->Pos + window->Size, rect.Min + padding) - window->Size);
|
||||
}
|
||||
|
||||
// Push a new ImGui window to add widgets to.
|
||||
@ -6669,7 +6672,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
{
|
||||
window->AutoPosLastDirection = ImGuiDir_None;
|
||||
if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api)
|
||||
window->Pos = window->PosFloat = g.CurrentPopupStack.back().OpenPopupPos;
|
||||
window->Pos = g.CurrentPopupStack.back().OpenPopupPos;
|
||||
}
|
||||
|
||||
// Position child window
|
||||
@ -6678,27 +6681,27 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->BeginOrderWithinParent = parent_window->DC.ChildWindows.Size;
|
||||
parent_window->DC.ChildWindows.push_back(window);
|
||||
if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api && !window_is_child_tooltip)
|
||||
window->Pos = window->PosFloat = parent_window->DC.CursorPos;
|
||||
window->Pos = parent_window->DC.CursorPos;
|
||||
}
|
||||
|
||||
const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFrames == 0);
|
||||
if (window_pos_with_pivot)
|
||||
SetWindowPos(window, ImMax(style.DisplaySafeAreaPadding, window->SetWindowPosVal - window->SizeFull * window->SetWindowPosPivot), 0); // Position given a pivot (e.g. for centering)
|
||||
else if ((flags & ImGuiWindowFlags_ChildMenu) != 0)
|
||||
window->PosFloat = FindBestWindowPosForPopup(window);
|
||||
window->Pos = FindBestWindowPosForPopup(window);
|
||||
else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize)
|
||||
window->PosFloat = FindBestWindowPosForPopup(window);
|
||||
window->Pos = FindBestWindowPosForPopup(window);
|
||||
else if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api && !window_is_child_tooltip)
|
||||
window->PosFloat = FindBestWindowPosForPopup(window);
|
||||
window->Pos = FindBestWindowPosForPopup(window);
|
||||
|
||||
if (window->ViewportAllowPlatformMonitorExtend >= 0 && !window->ViewportOwned)
|
||||
{
|
||||
if (!window->Viewport->GetRect().Contains(ImRect(window->PosFloat, window->PosFloat + window->Size)))
|
||||
if (!window->Viewport->GetRect().Contains(window->Rect()))
|
||||
{
|
||||
// Late create viewport, based on the assumption that with our calculations, the DPI will be known ahead (same as the DPI of the selection done in UpdateSelectWindowViewport)
|
||||
//ImGuiViewport* old_viewport = window->Viewport;
|
||||
ImGuiViewportFlags viewport_flags = ImGuiViewportFlags_NoDecoration | ImGuiViewportFlags_NoFocusOnAppearing | ((window->Flags & ImGuiWindowFlags_NoInputs) ? ImGuiViewportFlags_NoInputs : 0);
|
||||
window->Viewport = AddUpdateViewport(window, window->ID, window->PosFloat, window->Size, viewport_flags);
|
||||
window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, viewport_flags);
|
||||
|
||||
// FIXME-DPI
|
||||
//IM_ASSERT(old_viewport->DpiScale == window->Viewport->DpiScale); // FIXME-DPI: Something went wrong
|
||||
@ -6712,7 +6715,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
{
|
||||
// Synchronize viewport --> window
|
||||
if (window->Viewport->PlatformRequestMove)
|
||||
window->PosFloat = window->Viewport->Pos;
|
||||
window->Pos = window->Viewport->Pos;
|
||||
if (window->Viewport->PlatformRequestResize)
|
||||
window->Size = window->SizeFull = window->Viewport->Size;
|
||||
|
||||
@ -6734,7 +6737,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
if (window->Viewport->PlatformMonitor == -1)
|
||||
{
|
||||
// Fallback for "lost" window (e.g. a monitor disconnected): we move the window back over the main viewport
|
||||
window->PosFloat = g.Viewports[0]->Pos + style.DisplayWindowPadding;
|
||||
SetWindowPos(window, g.Viewports[0]->Pos + style.DisplayWindowPadding, ImGuiCond_Always);
|
||||
window->ViewportTryMerge = true;
|
||||
}
|
||||
else
|
||||
@ -6744,7 +6747,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
window->Pos = ImFloor(window->PosFloat);
|
||||
window->Pos = ImFloor(window->Pos);
|
||||
|
||||
// Lock window rounding for the frame (so that altering them doesn't cause inconsistencies)
|
||||
window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding;
|
||||
@ -6782,7 +6785,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
if (window->ViewportOwned)
|
||||
{
|
||||
if (!window->Viewport->PlatformRequestMove)
|
||||
window->Viewport->Pos = window->PosFloat;
|
||||
window->Viewport->Pos = window->Pos;
|
||||
if (!window->Viewport->PlatformRequestResize)
|
||||
window->Viewport->Size = window->Size;
|
||||
viewport_rect = window->Viewport->GetRect();
|
||||
@ -7752,7 +7755,6 @@ static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond)
|
||||
|
||||
// Set
|
||||
const ImVec2 old_pos = window->Pos;
|
||||
window->PosFloat = pos;
|
||||
window->Pos = ImFloor(pos);
|
||||
window->DC.CursorPos += (window->Pos - old_pos); // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor
|
||||
window->DC.CursorMaxPos += (window->Pos - old_pos); // And more importantly we need to adjust this so size calculation doesn't get affected.
|
||||
@ -8856,7 +8858,7 @@ bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags)
|
||||
if (flags & ImGuiTreeNodeFlags_Leaf)
|
||||
return true;
|
||||
|
||||
// We only write to the tree storage if the user clicks (or explicitely use SetNextTreeNode*** functions)
|
||||
// We only write to the tree storage if the user clicks (or explicitly use SetNextTreeNode*** functions)
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiStorage* storage = window->DC.StateStorage;
|
||||
@ -10921,15 +10923,15 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX;
|
||||
const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize*0.5f));
|
||||
|
||||
const bool osx_double_click_selects_words = io.OptMacOSXBehaviors; // OS X style: Double click selects by word instead of selecting whole text
|
||||
if (select_all || (hovered && !osx_double_click_selects_words && io.MouseDoubleClicked[0]))
|
||||
const bool is_osx = io.OptMacOSXBehaviors;
|
||||
if (select_all || (hovered && !is_osx && io.MouseDoubleClicked[0]))
|
||||
{
|
||||
edit_state.SelectAll();
|
||||
edit_state.SelectedAllMouseLock = true;
|
||||
}
|
||||
else if (hovered && osx_double_click_selects_words && io.MouseDoubleClicked[0])
|
||||
else if (hovered && is_osx && io.MouseDoubleClicked[0])
|
||||
{
|
||||
// Select a word only, OS X style (by simulating keystrokes)
|
||||
// Double-click select a word only, OS X style (by simulating keystrokes)
|
||||
edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT);
|
||||
edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT);
|
||||
}
|
||||
@ -10954,7 +10956,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
{
|
||||
// Process text input (before we check for Return because using some IME will effectively send a Return?)
|
||||
// We ignore CTRL inputs, but need to allow ALT+CTRL as some keyboards (e.g. German) use AltGR (which _is_ Alt+Ctrl) to input certain characters.
|
||||
if (!(io.KeyCtrl && !io.KeyAlt) && is_editable && !user_nav_input_start)
|
||||
bool ignore_inputs = (io.KeyCtrl && !io.KeyAlt) || (is_osx && io.KeySuper);
|
||||
if (!ignore_inputs && is_editable && !user_nav_input_start)
|
||||
for (int n = 0; n < IM_ARRAYSIZE(io.InputCharacters) && io.InputCharacters[n]; n++)
|
||||
{
|
||||
// Insert character if they pass filtering
|
||||
@ -10973,15 +10976,19 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
{
|
||||
// Handle key-presses
|
||||
const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0);
|
||||
const bool is_shortcut_key_only = (io.OptMacOSXBehaviors ? (io.KeySuper && !io.KeyCtrl) : (io.KeyCtrl && !io.KeySuper)) && !io.KeyAlt && !io.KeyShift; // OS X style: Shortcuts using Cmd/Super instead of Ctrl
|
||||
const bool is_wordmove_key_down = io.OptMacOSXBehaviors ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl
|
||||
const bool is_startend_key_down = io.OptMacOSXBehaviors && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End
|
||||
const bool is_osx = io.OptMacOSXBehaviors;
|
||||
const bool is_shortcut_key = (is_osx ? (io.KeySuper && !io.KeyCtrl) : (io.KeyCtrl && !io.KeySuper)) && !io.KeyAlt && !io.KeyShift; // OS X style: Shortcuts using Cmd/Super instead of Ctrl
|
||||
const bool is_osx_shift_shortcut = is_osx && io.KeySuper && io.KeyShift && !io.KeyCtrl && !io.KeyAlt;
|
||||
const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl
|
||||
const bool is_startend_key_down = is_osx && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End
|
||||
const bool is_ctrl_key_only = io.KeyCtrl && !io.KeyShift && !io.KeyAlt && !io.KeySuper;
|
||||
const bool is_shift_key_only = io.KeyShift && !io.KeyCtrl && !io.KeyAlt && !io.KeySuper;
|
||||
|
||||
const bool is_cut = ((is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_X)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Delete))) && is_editable && !is_password && (!is_multiline || edit_state.HasSelection());
|
||||
const bool is_copy = ((is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_C)) || (is_ctrl_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && !is_password && (!is_multiline || edit_state.HasSelection());
|
||||
const bool is_paste = ((is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_V)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && is_editable;
|
||||
const bool is_cut = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_X)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Delete))) && is_editable && !is_password && (!is_multiline || edit_state.HasSelection());
|
||||
const bool is_copy = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_C)) || (is_ctrl_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && !is_password && (!is_multiline || edit_state.HasSelection());
|
||||
const bool is_paste = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_V)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && is_editable;
|
||||
const bool is_undo = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_Z)) && is_editable && is_undoable);
|
||||
const bool is_redo = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_Y)) || (is_osx_shift_shortcut && IsKeyPressedMap(ImGuiKey_Z))) && is_editable && is_undoable;
|
||||
|
||||
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); }
|
||||
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); }
|
||||
@ -10995,7 +11002,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
if (!edit_state.HasSelection())
|
||||
{
|
||||
if (is_wordmove_key_down) edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT|STB_TEXTEDIT_K_SHIFT);
|
||||
else if (io.OptMacOSXBehaviors && io.KeySuper && !io.KeyAlt && !io.KeyCtrl) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT);
|
||||
else if (is_osx && io.KeySuper && !io.KeyAlt && !io.KeyCtrl) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT);
|
||||
}
|
||||
edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask);
|
||||
}
|
||||
@ -11019,10 +11026,20 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
if (InputTextFilterCharacter(&c, flags, callback, user_data))
|
||||
edit_state.OnKeyPressed((int)c);
|
||||
}
|
||||
else if (IsKeyPressedMap(ImGuiKey_Escape)) { clear_active_id = cancel_edit = true; }
|
||||
else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable && is_undoable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); }
|
||||
else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable && is_undoable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); }
|
||||
else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; }
|
||||
else if (IsKeyPressedMap(ImGuiKey_Escape))
|
||||
{
|
||||
clear_active_id = cancel_edit = true;
|
||||
}
|
||||
else if (is_undo || is_redo)
|
||||
{
|
||||
edit_state.OnKeyPressed(is_undo ? STB_TEXTEDIT_K_UNDO : STB_TEXTEDIT_K_REDO);
|
||||
edit_state.ClearSelection();
|
||||
}
|
||||
else if (is_shortcut_key && IsKeyPressedMap(ImGuiKey_A))
|
||||
{
|
||||
edit_state.SelectAll();
|
||||
edit_state.CursorFollow = true;
|
||||
}
|
||||
else if (is_cut || is_copy)
|
||||
{
|
||||
// Cut, Copy
|
||||
@ -11034,7 +11051,6 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
ImTextStrToUtf8(edit_state.TempTextBuffer.Data, edit_state.TempTextBuffer.Size, edit_state.Text.Data+ib, edit_state.Text.Data+ie);
|
||||
SetClipboardText(edit_state.TempTextBuffer.Data);
|
||||
}
|
||||
|
||||
if (is_cut)
|
||||
{
|
||||
if (!edit_state.HasSelection())
|
||||
@ -11045,7 +11061,6 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
}
|
||||
else if (is_paste)
|
||||
{
|
||||
// Paste
|
||||
if (const char* clipboard = GetClipboardText())
|
||||
{
|
||||
// Filter pasted buffer
|
||||
@ -13530,7 +13545,7 @@ void ImGui::EndColumns()
|
||||
columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y);
|
||||
window->DC.CursorPos.y = columns->LineMaxY;
|
||||
if (!(columns->Flags & ImGuiColumnsFlags_GrowParentContentsSize))
|
||||
window->DC.CursorMaxPos.x = ImMax(columns->StartMaxPosX, columns->MaxX); // Restore cursor max pos, as columns don't grow parent
|
||||
window->DC.CursorMaxPos.x = columns->StartMaxPosX; // Restore cursor max pos, as columns don't grow parent
|
||||
|
||||
// Draw columns borders and handle resize
|
||||
bool is_being_resized = false;
|
||||
@ -14047,7 +14062,7 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text)
|
||||
static void ScaleWindow(ImGuiWindow* window, float scale)
|
||||
{
|
||||
ImVec2 origin = window->Viewport->Pos;
|
||||
window->Pos = window->PosFloat = ImFloor((window->PosFloat - origin) * scale + origin);
|
||||
window->Pos = ImFloor((window->Pos - origin) * scale + origin);
|
||||
window->Size = ImFloor(window->Size * scale);
|
||||
window->SizeFull = ImFloor(window->SizeFull * scale);
|
||||
window->SizeContents = ImFloor(window->SizeContents * scale);
|
||||
@ -14231,13 +14246,14 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
ImGui::BulletText("Active: %d, WriteAccessed: %d, BeginOrderWithinContext: %d", window->Active, window->WriteAccessed, (window->Active || window->WasActive) ? window->BeginOrderWithinContext : -1);
|
||||
ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask);
|
||||
ImGui::BulletText("NavLastChildNavWindow: %s", window->NavLastChildNavWindow ? window->NavLastChildNavWindow->Name : "NULL");
|
||||
if (window->NavRectRel[0].IsInverted())
|
||||
if (!window->NavRectRel[0].IsInverted())
|
||||
ImGui::BulletText("NavRectRel[0]: (%.1f,%.1f)(%.1f,%.1f)", window->NavRectRel[0].Min.x, window->NavRectRel[0].Min.y, window->NavRectRel[0].Max.x, window->NavRectRel[0].Max.y);
|
||||
else
|
||||
ImGui::BulletText("NavRectRel[0]: <None>");
|
||||
ImGui::BulletText("Viewport: %d, ViewportId: 0x%08X, ViewportPos: (%.1f,%.1f)", window->Viewport ? window->Viewport->Idx : -1, window->ViewportId, window->ViewportPos.x, window->ViewportPos.y);
|
||||
ImGui::BulletText("ViewportMonitor: %d", window->Viewport->PlatformMonitor);
|
||||
if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow");
|
||||
if (window->ParentWindow != NULL) NodeWindow(window->ParentWindow, "ParentWindow");
|
||||
if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows");
|
||||
if (window->ColumnsStorage.Size > 0 && ImGui::TreeNode("Columns", "Columns sets (%d)", window->ColumnsStorage.Size))
|
||||
{
|
||||
@ -14265,7 +14281,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
{
|
||||
ImGuiWindowFlags flags = viewport->Flags;
|
||||
ImGui::BulletText("Pos: (%.0f,%.0f), Monitor: %d", viewport->Pos.x, viewport->Pos.y, viewport->PlatformMonitor);
|
||||
if (viewport->Idx > 0) { ImGui::SameLine(); if (ImGui::SmallButton("Reset")) { viewport->Pos = ImVec2(200,200); if (viewport->Window) viewport->Window->Pos = viewport->Window->PosFloat = ImVec2(200,200); } }
|
||||
if (viewport->Idx > 0) { ImGui::SameLine(); if (ImGui::SmallButton("Reset")) { viewport->Pos = ImVec2(200,200); if (viewport->Window) viewport->Window->Pos = ImVec2(200,200); } }
|
||||
ImGui::BulletText("Size: (%0.f,%.0f), DpiScale: %.0f%%", viewport->Size.x, viewport->Size.y, viewport->DpiScale * 100.0f);
|
||||
ImGui::BulletText("Flags: 0x%04X =%s%s%s%s%s", viewport->Flags,
|
||||
(flags & ImGuiViewportFlags_CanHostOtherWindows) ? " CanHostOtherWindows" : "", (flags & ImGuiViewportFlags_NoDecoration) ? " NoDecoration" : "",
|
||||
@ -14343,8 +14359,8 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "%d", window->BeginOrderWithinContext);
|
||||
float font_size = ImGui::GetFontSize() * 2;
|
||||
ImDrawList* overlay_draw_list = GetOverlayDrawList(window->Viewport);
|
||||
overlay_draw_list->AddRectFilled(window->PosFloat, window->PosFloat + ImVec2(font_size, font_size), IM_COL32(200, 100, 100, 255));
|
||||
overlay_draw_list->AddText(NULL, font_size, window->PosFloat, IM_COL32(255, 255, 255, 255), buf);
|
||||
overlay_draw_list->AddRectFilled(window->Pos, window->Pos + ImVec2(font_size, font_size), IM_COL32(200, 100, 100, 255));
|
||||
overlay_draw_list->AddText(NULL, font_size, window->Pos, IM_COL32(255, 255, 255, 255), buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user