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:
omar
2018-04-25 15:32:04 +02:00
12 changed files with 166 additions and 91 deletions

134
imgui.cpp
View File

@ -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);
}
}
}