Updated ImGui.
This commit is contained in:
parent
7621b1d4d8
commit
bfc1d0285a
63
3rdparty/dear-imgui/imgui.cpp
vendored
63
3rdparty/dear-imgui/imgui.cpp
vendored
@ -372,6 +372,7 @@ CODE
|
||||
When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
|
||||
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
|
||||
|
||||
- 2020/09/17 (1.79) - removed ImFont::DisplayOffset in favor of ImFontConfig::GlyphOffset. DisplayOffset was applied after scaling and not very meaningful/useful outside of being needed by the default ProggyClean font. It was also getting in the way of better font scaling, so let's get rid of it now!
|
||||
- 2020/08/17 (1.78) - obsoleted use of the trailing 'float power=1.0f' parameter for DragFloat(), DragFloat2(), DragFloat3(), DragFloat4(), DragFloatRange2(), DragScalar(), DragScalarN(), SliderFloat(), SliderFloat2(), SliderFloat3(), SliderFloat4(), SliderScalar(), SliderScalarN(), VSliderFloat() and VSliderScalar().
|
||||
replaced the 'float power=1.0f' argument with integer-based flags defaulting to 0 (as with all our flags).
|
||||
worked out a backward-compatibility scheme so hopefully most C++ codebase should not be affected. in short, when calling those functions:
|
||||
@ -8009,26 +8010,47 @@ ImVec2 ImGui::FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& s
|
||||
}
|
||||
}
|
||||
|
||||
// Default popup policy
|
||||
const ImGuiDir dir_prefered_order[ImGuiDir_COUNT] = { ImGuiDir_Right, ImGuiDir_Down, ImGuiDir_Up, ImGuiDir_Left };
|
||||
for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_COUNT; n++)
|
||||
// Tooltip and Default popup policy
|
||||
// (Always first try the direction we used on the last frame, if any)
|
||||
if (policy == ImGuiPopupPositionPolicy_Tooltip || policy == ImGuiPopupPositionPolicy_Default)
|
||||
{
|
||||
const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n];
|
||||
if (n != -1 && dir == *last_dir) // Already tried this direction?
|
||||
continue;
|
||||
float avail_w = (dir == ImGuiDir_Left ? r_avoid.Min.x : r_outer.Max.x) - (dir == ImGuiDir_Right ? r_avoid.Max.x : r_outer.Min.x);
|
||||
float avail_h = (dir == ImGuiDir_Up ? r_avoid.Min.y : r_outer.Max.y) - (dir == ImGuiDir_Down ? r_avoid.Max.y : r_outer.Min.y);
|
||||
if (avail_w < size.x || avail_h < size.y)
|
||||
continue;
|
||||
ImVec2 pos;
|
||||
pos.x = (dir == ImGuiDir_Left) ? r_avoid.Min.x - size.x : (dir == ImGuiDir_Right) ? r_avoid.Max.x : base_pos_clamped.x;
|
||||
pos.y = (dir == ImGuiDir_Up) ? r_avoid.Min.y - size.y : (dir == ImGuiDir_Down) ? r_avoid.Max.y : base_pos_clamped.y;
|
||||
*last_dir = dir;
|
||||
return pos;
|
||||
const ImGuiDir dir_prefered_order[ImGuiDir_COUNT] = { ImGuiDir_Right, ImGuiDir_Down, ImGuiDir_Up, ImGuiDir_Left };
|
||||
for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_COUNT; n++)
|
||||
{
|
||||
const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n];
|
||||
if (n != -1 && dir == *last_dir) // Already tried this direction?
|
||||
continue;
|
||||
|
||||
const float avail_w = (dir == ImGuiDir_Left ? r_avoid.Min.x : r_outer.Max.x) - (dir == ImGuiDir_Right ? r_avoid.Max.x : r_outer.Min.x);
|
||||
const float avail_h = (dir == ImGuiDir_Up ? r_avoid.Min.y : r_outer.Max.y) - (dir == ImGuiDir_Down ? r_avoid.Max.y : r_outer.Min.y);
|
||||
|
||||
// If there not enough room on one axis, there's no point in positioning on a side on this axis (e.g. when not enough width, use a top/bottom position to maximize available width)
|
||||
if (avail_w < size.x && (dir == ImGuiDir_Left || dir == ImGuiDir_Right))
|
||||
continue;
|
||||
if (avail_h < size.y && (dir == ImGuiDir_Up || dir == ImGuiDir_Down))
|
||||
continue;
|
||||
|
||||
ImVec2 pos;
|
||||
pos.x = (dir == ImGuiDir_Left) ? r_avoid.Min.x - size.x : (dir == ImGuiDir_Right) ? r_avoid.Max.x : base_pos_clamped.x;
|
||||
pos.y = (dir == ImGuiDir_Up) ? r_avoid.Min.y - size.y : (dir == ImGuiDir_Down) ? r_avoid.Max.y : base_pos_clamped.y;
|
||||
|
||||
// Clamp top-left corner of popup
|
||||
pos.x = ImMax(pos.x, r_outer.Min.x);
|
||||
pos.y = ImMax(pos.y, r_outer.Min.y);
|
||||
|
||||
*last_dir = dir;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback, try to keep within display
|
||||
// Fallback when not enough room:
|
||||
*last_dir = ImGuiDir_None;
|
||||
|
||||
// For tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible.
|
||||
if (policy == ImGuiPopupPositionPolicy_Tooltip)
|
||||
return ref_pos + ImVec2(2, 2);
|
||||
|
||||
// Otherwise try to keep within display
|
||||
ImVec2 pos = ref_pos;
|
||||
pos.x = ImMax(ImMin(pos.x + size.x, r_outer.Max.x) - size.x, r_outer.Min.x);
|
||||
pos.y = ImMax(ImMin(pos.y + size.y, r_outer.Max.y) - size.y, r_outer.Min.y);
|
||||
@ -8061,12 +8083,12 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
|
||||
r_avoid = ImRect(-FLT_MAX, parent_window->ClipRect.Min.y, FLT_MAX, parent_window->ClipRect.Max.y); // Avoid parent menu-bar. If we wanted multi-line menu-bar, we may instead want to have the calling window setup e.g. a NextWindowData.PosConstraintAvoidRect field
|
||||
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->Pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid);
|
||||
return FindBestWindowPosForPopupEx(window->Pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid, ImGuiPopupPositionPolicy_Default);
|
||||
}
|
||||
if (window->Flags & ImGuiWindowFlags_Popup)
|
||||
{
|
||||
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);
|
||||
return FindBestWindowPosForPopupEx(window->Pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid, ImGuiPopupPositionPolicy_Default);
|
||||
}
|
||||
if (window->Flags & ImGuiWindowFlags_Tooltip)
|
||||
{
|
||||
@ -8078,10 +8100,7 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
|
||||
r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8);
|
||||
else
|
||||
r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * sc, ref_pos.y + 24 * sc); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important.
|
||||
ImVec2 pos = FindBestWindowPosForPopupEx(ref_pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid);
|
||||
if (window->AutoPosLastDirection == ImGuiDir_None)
|
||||
pos = ref_pos + ImVec2(2, 2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible.
|
||||
return pos;
|
||||
return FindBestWindowPosForPopupEx(ref_pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid, ImGuiPopupPositionPolicy_Tooltip);
|
||||
}
|
||||
IM_ASSERT(0);
|
||||
return window->Pos;
|
||||
|
11
3rdparty/dear-imgui/imgui.h
vendored
11
3rdparty/dear-imgui/imgui.h
vendored
@ -887,13 +887,15 @@ enum ImGuiTreeNodeFlags_
|
||||
// small flags values as a mouse button index, so we encode the mouse button in the first few bits of the flags.
|
||||
// It is therefore guaranteed to be legal to pass a mouse button index in ImGuiPopupFlags.
|
||||
// - For the same reason, we exceptionally default the ImGuiPopupFlags argument of BeginPopupContextXXX functions to 1 instead of 0.
|
||||
// IMPORTANT: because the default parameter is 1 (==ImGuiPopupFlags_MouseButtonRight), if you rely on the default parameter
|
||||
// and want to another another flag, you need to pass in the ImGuiPopupFlags_MouseButtonRight flag.
|
||||
// - Multiple buttons currently cannot be combined/or-ed in those functions (we could allow it later).
|
||||
enum ImGuiPopupFlags_
|
||||
{
|
||||
ImGuiPopupFlags_None = 0,
|
||||
ImGuiPopupFlags_MouseButtonLeft = 0, // For BeginPopupContext*(): open on Left Mouse release. Guaranted to always be == 0 (same as ImGuiMouseButton_Left)
|
||||
ImGuiPopupFlags_MouseButtonRight = 1, // For BeginPopupContext*(): open on Right Mouse release. Guaranted to always be == 1 (same as ImGuiMouseButton_Right)
|
||||
ImGuiPopupFlags_MouseButtonMiddle = 2, // For BeginPopupContext*(): open on Middle Mouse release. Guaranted to always be == 2 (same as ImGuiMouseButton_Middle)
|
||||
ImGuiPopupFlags_MouseButtonLeft = 0, // For BeginPopupContext*(): open on Left Mouse release. Guaranteed to always be == 0 (same as ImGuiMouseButton_Left)
|
||||
ImGuiPopupFlags_MouseButtonRight = 1, // For BeginPopupContext*(): open on Right Mouse release. Guaranteed to always be == 1 (same as ImGuiMouseButton_Right)
|
||||
ImGuiPopupFlags_MouseButtonMiddle = 2, // For BeginPopupContext*(): open on Middle Mouse release. Guaranteed to always be == 2 (same as ImGuiMouseButton_Middle)
|
||||
ImGuiPopupFlags_MouseButtonMask_ = 0x1F,
|
||||
ImGuiPopupFlags_MouseButtonDefault_ = 1,
|
||||
ImGuiPopupFlags_NoOpenOverExistingPopup = 1 << 5, // For OpenPopup*(), BeginPopupContext*(): don't open if there's already a popup at the same level of the popup stack
|
||||
@ -2404,11 +2406,10 @@ struct ImFont
|
||||
float FallbackAdvanceX; // 4 // out // = FallbackGlyph->AdvanceX
|
||||
float FontSize; // 4 // in // // Height of characters/line, set during loading (don't change after loading)
|
||||
|
||||
// Members: Hot ~36/48 bytes (for CalcTextSize + render loop)
|
||||
// Members: Hot ~28/40 bytes (for CalcTextSize + render loop)
|
||||
ImVector<ImWchar> IndexLookup; // 12-16 // out // // Sparse. Index glyphs by Unicode code-point.
|
||||
ImVector<ImFontGlyph> Glyphs; // 12-16 // out // // All glyphs.
|
||||
const ImFontGlyph* FallbackGlyph; // 4-8 // out // = FindGlyph(FontFallbackChar)
|
||||
ImVec2 DisplayOffset; // 8 // in // = (0,0) // Offset font rendering by xx pixels
|
||||
|
||||
// Members: Cold ~32/40 bytes
|
||||
ImFontAtlas* ContainerAtlas; // 4-8 // out // // What we has been loaded into
|
||||
|
16
3rdparty/dear-imgui/imgui_demo.cpp
vendored
16
3rdparty/dear-imgui/imgui_demo.cpp
vendored
@ -854,7 +854,7 @@ static void ShowDemoWindowWidgets()
|
||||
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width);
|
||||
if (n == 0)
|
||||
ImGui::Text("The lazy dog is a good dog. This paragraph should fit within %.0f pixels. Testing a 1 character word. The quick brown fox jumps over the lazy dog.", wrap_width);
|
||||
if (n == 1)
|
||||
else
|
||||
ImGui::Text("aaaaaaaa bbbbbbbb, c cccccccc,dddddddd. d eeeeeeee ffffffff. gggggggg!hhhhhhhh");
|
||||
|
||||
// Draw actual text bounding box, following by marker of our expected limit (should not overlap!)
|
||||
@ -953,7 +953,7 @@ static void ShowDemoWindowWidgets()
|
||||
int frame_padding = -1 + i; // -1 == uses default padding (style.FramePadding)
|
||||
ImVec2 size = ImVec2(32.0f, 32.0f); // Size of the image we want to make visible
|
||||
ImVec2 uv0 = ImVec2(0.0f, 0.0f); // UV coordinates for lower-left
|
||||
ImVec2 uv1 = ImVec2(32.0f / my_tex_w, 32 / my_tex_h); // UV coordinates for (32,32) in our texture
|
||||
ImVec2 uv1 = ImVec2(32.0f / my_tex_w, 32.0f / my_tex_h);// UV coordinates for (32,32) in our texture
|
||||
ImVec4 bg_col = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); // Black background
|
||||
ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint
|
||||
if (ImGui::ImageButton(my_tex_id, size, uv0, uv1, frame_padding, bg_col, tint_col))
|
||||
@ -982,7 +982,7 @@ static void ShowDemoWindowWidgets()
|
||||
// stored in the object itself, etc.)
|
||||
const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" };
|
||||
static int item_current_idx = 0; // Here our selection data is an index.
|
||||
const char* combo_label = items[item_current_idx]; // Label to preview before opening the combo (technically could be anything)(
|
||||
const char* combo_label = items[item_current_idx]; // Label to preview before opening the combo (technically it could be anything)
|
||||
if (ImGui::BeginCombo("combo 1", combo_label, flags))
|
||||
{
|
||||
for (int n = 0; n < IM_ARRAYSIZE(items); n++)
|
||||
@ -3715,7 +3715,6 @@ static void NodeFont(ImFont* font)
|
||||
"You may oversample them to get some flexibility with scaling. "
|
||||
"You can also render at multiple sizes and select which one to use at runtime.\n\n"
|
||||
"(Glimmer of hope: the atlas system will be rewritten in the future to make scaling more flexible.)");
|
||||
ImGui::InputFloat("Font offset", &font->DisplayOffset.y, 1, 1, "%.0f");
|
||||
ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent);
|
||||
ImGui::Text("Fallback character: '%c' (U+%04X)", font->FallbackChar, font->FallbackChar);
|
||||
ImGui::Text("Ellipsis character: '%c' (U+%04X)", font->EllipsisChar, font->EllipsisChar);
|
||||
@ -3724,8 +3723,8 @@ static void NodeFont(ImFont* font)
|
||||
for (int config_i = 0; config_i < font->ConfigDataCount; config_i++)
|
||||
if (font->ConfigData)
|
||||
if (const ImFontConfig* cfg = &font->ConfigData[config_i])
|
||||
ImGui::BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d",
|
||||
config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH);
|
||||
ImGui::BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d, Offset: (%.1f,%.1f)",
|
||||
config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH, cfg->GlyphOffset.x, cfg->GlyphOffset.y);
|
||||
if (ImGui::TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size))
|
||||
{
|
||||
// Display all glyphs of the fonts in separate pages of 256 characters
|
||||
@ -4939,16 +4938,15 @@ static void ShowExampleAppSimpleOverlay(bool* p_open)
|
||||
const float DISTANCE = 10.0f;
|
||||
static int corner = 0;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav;
|
||||
if (corner != -1)
|
||||
{
|
||||
window_flags |= ImGuiWindowFlags_NoMove;
|
||||
ImVec2 window_pos = ImVec2((corner & 1) ? io.DisplaySize.x - DISTANCE : DISTANCE, (corner & 2) ? io.DisplaySize.y - DISTANCE : DISTANCE);
|
||||
ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f);
|
||||
ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot);
|
||||
}
|
||||
ImGui::SetNextWindowBgAlpha(0.35f); // Transparent background
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav;
|
||||
if (corner != -1)
|
||||
window_flags |= ImGuiWindowFlags_NoMove;
|
||||
if (ImGui::Begin("Example: Simple overlay", p_open, window_flags))
|
||||
{
|
||||
ImGui::Text("Simple overlay\n" "in the corner of the screen.\n" "(right-click to change position)");
|
||||
|
15
3rdparty/dear-imgui/imgui_draw.cpp
vendored
15
3rdparty/dear-imgui/imgui_draw.cpp
vendored
@ -339,7 +339,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ImDrawList
|
||||
// [SECTION] ImDrawList
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ImDrawListSharedData::ImDrawListSharedData()
|
||||
@ -1405,7 +1405,7 @@ void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& p_mi
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ImDrawListSplitter
|
||||
// [SECTION] ImDrawListSplitter
|
||||
//-----------------------------------------------------------------------------
|
||||
// FIXME: This may be a little confusing, trying to be a little too low-level/optimal instead of just doing vector swap..
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1891,11 +1891,11 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template)
|
||||
if (font_cfg.Name[0] == '\0')
|
||||
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "ProggyClean.ttf, %dpx", (int)font_cfg.SizePixels);
|
||||
font_cfg.EllipsisChar = (ImWchar)0x0085;
|
||||
font_cfg.GlyphOffset.y = 1.0f * IM_FLOOR(font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units
|
||||
|
||||
const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85();
|
||||
const ImWchar* glyph_ranges = font_cfg.GlyphRanges != NULL ? font_cfg.GlyphRanges : GetGlyphRangesDefault();
|
||||
ImFont* font = AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_cfg.SizePixels, &font_cfg, glyph_ranges);
|
||||
font->DisplayOffset.y = 1.0f;
|
||||
return font;
|
||||
}
|
||||
|
||||
@ -2768,7 +2768,6 @@ ImFont::ImFont()
|
||||
FallbackAdvanceX = 0.0f;
|
||||
FallbackChar = (ImWchar)'?';
|
||||
EllipsisChar = (ImWchar)-1;
|
||||
DisplayOffset = ImVec2(0.0f, 0.0f);
|
||||
FallbackGlyph = NULL;
|
||||
ContainerAtlas = NULL;
|
||||
ConfigData = NULL;
|
||||
@ -3163,8 +3162,8 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
|
||||
if (!glyph || !glyph->Visible)
|
||||
return;
|
||||
float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f;
|
||||
pos.x = IM_FLOOR(pos.x + DisplayOffset.x);
|
||||
pos.y = IM_FLOOR(pos.y + DisplayOffset.y);
|
||||
pos.x = IM_FLOOR(pos.x);
|
||||
pos.y = IM_FLOOR(pos.y);
|
||||
draw_list->PrimReserve(6, 4);
|
||||
draw_list->PrimRectUV(ImVec2(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale), ImVec2(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col);
|
||||
}
|
||||
@ -3175,8 +3174,8 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
|
||||
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
|
||||
|
||||
// Align to be pixel perfect
|
||||
pos.x = IM_FLOOR(pos.x + DisplayOffset.x);
|
||||
pos.y = IM_FLOOR(pos.y + DisplayOffset.y);
|
||||
pos.x = IM_FLOOR(pos.x);
|
||||
pos.y = IM_FLOOR(pos.y);
|
||||
float x = pos.x;
|
||||
float y = pos.y;
|
||||
if (y > clip_rect.w)
|
||||
|
5
3rdparty/dear-imgui/imgui_internal.h
vendored
5
3rdparty/dear-imgui/imgui_internal.h
vendored
@ -777,7 +777,8 @@ enum ImGuiNavLayer
|
||||
enum ImGuiPopupPositionPolicy
|
||||
{
|
||||
ImGuiPopupPositionPolicy_Default,
|
||||
ImGuiPopupPositionPolicy_ComboBox
|
||||
ImGuiPopupPositionPolicy_ComboBox,
|
||||
ImGuiPopupPositionPolicy_Tooltip
|
||||
};
|
||||
|
||||
struct ImGuiDataTypeTempStorage
|
||||
@ -1879,7 +1880,7 @@ namespace ImGui
|
||||
IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, ImGuiTooltipFlags tooltip_flags);
|
||||
IMGUI_API ImGuiWindow* GetTopMostPopupModal();
|
||||
IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window);
|
||||
IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy = ImGuiPopupPositionPolicy_Default);
|
||||
IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy);
|
||||
|
||||
// Gamepad/Keyboard Navigation
|
||||
IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit);
|
||||
|
39
3rdparty/dear-imgui/imgui_widgets.cpp
vendored
39
3rdparty/dear-imgui/imgui_widgets.cpp
vendored
@ -274,7 +274,10 @@ void ImGui::TextColored(const ImVec4& col, const char* fmt, ...)
|
||||
void ImGui::TextColoredV(const ImVec4& col, const char* fmt, va_list args)
|
||||
{
|
||||
PushStyleColor(ImGuiCol_Text, col);
|
||||
TextV(fmt, args);
|
||||
if (fmt[0] == '%' && fmt[1] == 's' && fmt[2] == 0)
|
||||
TextEx(va_arg(args, const char*), NULL, ImGuiTextFlags_NoWidthForLargeClippedText); // Skip formatting
|
||||
else
|
||||
TextV(fmt, args);
|
||||
PopStyleColor();
|
||||
}
|
||||
|
||||
@ -288,8 +291,12 @@ void ImGui::TextDisabled(const char* fmt, ...)
|
||||
|
||||
void ImGui::TextDisabledV(const char* fmt, va_list args)
|
||||
{
|
||||
PushStyleColor(ImGuiCol_Text, GImGui->Style.Colors[ImGuiCol_TextDisabled]);
|
||||
TextV(fmt, args);
|
||||
ImGuiContext& g = *GImGui;
|
||||
PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
|
||||
if (fmt[0] == '%' && fmt[1] == 's' && fmt[2] == 0)
|
||||
TextEx(va_arg(args, const char*), NULL, ImGuiTextFlags_NoWidthForLargeClippedText); // Skip formatting
|
||||
else
|
||||
TextV(fmt, args);
|
||||
PopStyleColor();
|
||||
}
|
||||
|
||||
@ -303,11 +310,14 @@ void ImGui::TextWrapped(const char* fmt, ...)
|
||||
|
||||
void ImGui::TextWrappedV(const char* fmt, va_list args)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
bool need_backup = (window->DC.TextWrapPos < 0.0f); // Keep existing wrap position if one is already set
|
||||
ImGuiContext& g = *GImGui;
|
||||
bool need_backup = (g.CurrentWindow->DC.TextWrapPos < 0.0f); // Keep existing wrap position if one is already set
|
||||
if (need_backup)
|
||||
PushTextWrapPos(0.0f);
|
||||
TextV(fmt, args);
|
||||
if (fmt[0] == '%' && fmt[1] == 's' && fmt[2] == 0)
|
||||
TextEx(va_arg(args, const char*), NULL, ImGuiTextFlags_NoWidthForLargeClippedText); // Skip formatting
|
||||
else
|
||||
TextV(fmt, args);
|
||||
if (need_backup)
|
||||
PopTextWrapPos();
|
||||
}
|
||||
@ -3595,6 +3605,8 @@ static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const Im
|
||||
#define STB_TEXTEDIT_K_REDO 0x20000B // keyboard input to perform redo
|
||||
#define STB_TEXTEDIT_K_WORDLEFT 0x20000C // keyboard input to move cursor left one word
|
||||
#define STB_TEXTEDIT_K_WORDRIGHT 0x20000D // keyboard input to move cursor right one word
|
||||
#define STB_TEXTEDIT_K_PGUP 0x20000E // keyboard input to move cursor up a page
|
||||
#define STB_TEXTEDIT_K_PGDOWN 0x20000F // keyboard input to move cursor down a page
|
||||
#define STB_TEXTEDIT_K_SHIFT 0x400000
|
||||
|
||||
#define STB_TEXTEDIT_IMPLEMENTATION
|
||||
@ -3861,6 +3873,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
bool clear_active_id = false;
|
||||
bool select_all = (g.ActiveId != id) && ((flags & ImGuiInputTextFlags_AutoSelectAll) != 0 || user_nav_input_start) && (!is_multiline);
|
||||
|
||||
float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX;
|
||||
|
||||
const bool init_make_active = (focus_requested || user_clicked || user_scroll_finish || user_nav_input_start);
|
||||
const bool init_state = (init_make_active || user_scroll_active);
|
||||
if (init_state && g.ActiveId != id)
|
||||
@ -3921,7 +3935,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);
|
||||
g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_Home) | ((ImU64)1 << ImGuiKey_End);
|
||||
if (is_multiline)
|
||||
g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_PageUp) | ((ImU64)1 << ImGuiKey_PageDown); // FIXME-NAV: Page up/down actually not supported yet by widget, but claim them ahead.
|
||||
g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_PageUp) | ((ImU64)1 << ImGuiKey_PageDown);
|
||||
if (flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_AllowTabInput)) // Disable keyboard tabbing out as we will use the \t character.
|
||||
g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_Tab);
|
||||
}
|
||||
@ -3963,7 +3977,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
ImFont* password_font = &g.InputTextPasswordFont;
|
||||
password_font->FontSize = g.Font->FontSize;
|
||||
password_font->Scale = g.Font->Scale;
|
||||
password_font->DisplayOffset = g.Font->DisplayOffset;
|
||||
password_font->Ascent = g.Font->Ascent;
|
||||
password_font->Descent = g.Font->Descent;
|
||||
password_font->ContainerAtlas = g.Font->ContainerAtlas;
|
||||
@ -4061,6 +4074,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
IM_ASSERT(state != NULL);
|
||||
IM_ASSERT(io.KeyMods == GetMergedKeyModFlags() && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods"); // We rarely do this check, but if anything let's do it here.
|
||||
|
||||
const int row_count_per_page = ImMax((int)((inner_size.y - style.FramePadding.y) / g.FontSize), 1);
|
||||
state->Stb.row_count_per_page = row_count_per_page;
|
||||
|
||||
const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0);
|
||||
const bool is_osx = io.ConfigMacOSXBehaviors;
|
||||
const bool is_osx_shift_shortcut = is_osx && (io.KeyMods == (ImGuiKeyModFlags_Super | ImGuiKeyModFlags_Shift));
|
||||
@ -4080,6 +4096,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); }
|
||||
else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); }
|
||||
else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); }
|
||||
else if (IsKeyPressedMap(ImGuiKey_PageUp) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGUP | k_mask); scroll_y -= row_count_per_page * g.FontSize; }
|
||||
else if (IsKeyPressedMap(ImGuiKey_PageDown) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGDOWN | k_mask); scroll_y += row_count_per_page * g.FontSize; }
|
||||
else if (IsKeyPressedMap(ImGuiKey_Home)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); }
|
||||
else if (IsKeyPressedMap(ImGuiKey_End)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
|
||||
else if (IsKeyPressedMap(ImGuiKey_Delete) && !is_readonly) { state->OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
|
||||
@ -4449,12 +4467,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (is_multiline)
|
||||
{
|
||||
// Test if cursor is vertically visible
|
||||
float scroll_y = draw_window->Scroll.y;
|
||||
const float scroll_max_y = ImMax((text_size.y + style.FramePadding.y * 2.0f) - inner_size.y, 0.0f);
|
||||
if (cursor_offset.y - g.FontSize < scroll_y)
|
||||
scroll_y = ImMax(0.0f, cursor_offset.y - g.FontSize);
|
||||
else if (cursor_offset.y - inner_size.y >= scroll_y)
|
||||
scroll_y = cursor_offset.y - inner_size.y + style.FramePadding.y * 2.0f;
|
||||
const float scroll_max_y = ImMax((text_size.y + style.FramePadding.y * 2.0f) - inner_size.y, 0.0f);
|
||||
scroll_y = ImClamp(scroll_y, 0.0f, scroll_max_y);
|
||||
draw_pos.y += (draw_window->Scroll.y - scroll_y); // Manipulate cursor pos immediately avoid a frame of lag
|
||||
draw_window->Scroll.y = scroll_y;
|
||||
@ -7953,7 +7970,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
|
||||
float clip_x1 = IM_ROUND(window->Pos.x + GetColumnOffset(n));
|
||||
float clip_x2 = IM_ROUND(window->Pos.x + GetColumnOffset(n + 1) - 1.0f);
|
||||
column->ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX);
|
||||
column->ClipRect.ClipWith(window->ClipRect);
|
||||
column->ClipRect.ClipWithFull(window->ClipRect);
|
||||
}
|
||||
|
||||
if (columns->Count > 1)
|
||||
|
163
3rdparty/stb/stb_textedit.h
vendored
163
3rdparty/stb/stb_textedit.h
vendored
@ -1,3 +1,9 @@
|
||||
// [DEAR IMGUI]
|
||||
// This is a slightly modified version of stb_textedit.h 1.13.
|
||||
// Those changes would need to be pushed into nothings/stb:
|
||||
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
|
||||
// Grep for [DEAR IMGUI] to find the changes.
|
||||
|
||||
// stb_textedit.h - v1.13 - public domain - Sean Barrett
|
||||
// Development of this library was sponsored by RAD Game Tools
|
||||
//
|
||||
@ -13,7 +19,7 @@
|
||||
// texts, as its performance does not scale and it has limited undo).
|
||||
//
|
||||
// Non-trivial behaviors are modelled after Windows text controls.
|
||||
//
|
||||
//
|
||||
//
|
||||
// LICENSE
|
||||
//
|
||||
@ -142,6 +148,8 @@
|
||||
// STB_TEXTEDIT_K_RIGHT keyboard input to move cursor right
|
||||
// STB_TEXTEDIT_K_UP keyboard input to move cursor up
|
||||
// STB_TEXTEDIT_K_DOWN keyboard input to move cursor down
|
||||
// STB_TEXTEDIT_K_PGUP keyboard input to move cursor up a page
|
||||
// STB_TEXTEDIT_K_PGDOWN keyboard input to move cursor down a page
|
||||
// STB_TEXTEDIT_K_LINESTART keyboard input to move cursor to start of line // e.g. HOME
|
||||
// STB_TEXTEDIT_K_LINEEND keyboard input to move cursor to end of line // e.g. END
|
||||
// STB_TEXTEDIT_K_TEXTSTART keyboard input to move cursor to start of text // e.g. ctrl-HOME
|
||||
@ -164,10 +172,6 @@
|
||||
// STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text
|
||||
// STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text
|
||||
//
|
||||
// Todo:
|
||||
// STB_TEXTEDIT_K_PGUP keyboard input to move cursor up a page
|
||||
// STB_TEXTEDIT_K_PGDOWN keyboard input to move cursor down a page
|
||||
//
|
||||
// Keyboard input must be encoded as a single integer value; e.g. a character code
|
||||
// and some bitflags that represent shift states. to simplify the interface, SHIFT must
|
||||
// be a bitflag, so we can test the shifted state of cursor movements to allow selection,
|
||||
@ -213,20 +217,20 @@
|
||||
// call this with the mouse x,y on a mouse down; it will update the cursor
|
||||
// and reset the selection start/end to the cursor point. the x,y must
|
||||
// be relative to the text widget, with (0,0) being the top left.
|
||||
//
|
||||
//
|
||||
// drag:
|
||||
// call this with the mouse x,y on a mouse drag/up; it will update the
|
||||
// cursor and the selection end point
|
||||
//
|
||||
//
|
||||
// cut:
|
||||
// call this to delete the current selection; returns true if there was
|
||||
// one. you should FIRST copy the current selection to the system paste buffer.
|
||||
// (To copy, just copy the current selection out of the string yourself.)
|
||||
//
|
||||
//
|
||||
// paste:
|
||||
// call this to paste text at the current cursor point or over the current
|
||||
// selection if there is one.
|
||||
//
|
||||
//
|
||||
// key:
|
||||
// call this for keyboard inputs sent to the textfield. you can use it
|
||||
// for "key down" events or for "translated" key events. if you need to
|
||||
@ -237,7 +241,7 @@
|
||||
// clear. STB_TEXTEDIT_KEYTYPE defaults to int, but you can #define it to
|
||||
// anything other type you wante before including.
|
||||
//
|
||||
//
|
||||
//
|
||||
// When rendering, you can read the cursor position and selection state from
|
||||
// the STB_TexteditState.
|
||||
//
|
||||
@ -331,6 +335,10 @@ typedef struct
|
||||
// each textfield keeps its own insert mode state. to keep an app-wide
|
||||
// insert mode, copy this value in/out of the app state
|
||||
|
||||
int row_count_per_page;
|
||||
// page size in number of row.
|
||||
// this value MUST be set to >0 for pageup or pagedown in multilines documents.
|
||||
|
||||
/////////////////////
|
||||
//
|
||||
// private data
|
||||
@ -756,7 +764,7 @@ retry:
|
||||
state->insert_mode = !state->insert_mode;
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
case STB_TEXTEDIT_K_UNDO:
|
||||
stb_text_undo(str, state);
|
||||
state->has_preferred_x = 0;
|
||||
@ -771,7 +779,7 @@ retry:
|
||||
// if currently there's a selection, move cursor to start of selection
|
||||
if (STB_TEXT_HAS_SELECTION(state))
|
||||
stb_textedit_move_to_first(state);
|
||||
else
|
||||
else
|
||||
if (state->cursor > 0)
|
||||
--state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
@ -820,7 +828,7 @@ retry:
|
||||
|
||||
#ifdef STB_TEXTEDIT_MOVEWORDRIGHT
|
||||
case STB_TEXTEDIT_K_WORDRIGHT:
|
||||
if (STB_TEXT_HAS_SELECTION(state))
|
||||
if (STB_TEXT_HAS_SELECTION(state))
|
||||
stb_textedit_move_to_last(str, state);
|
||||
else {
|
||||
state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor);
|
||||
@ -849,12 +857,16 @@ retry:
|
||||
break;
|
||||
|
||||
case STB_TEXTEDIT_K_DOWN:
|
||||
case STB_TEXTEDIT_K_DOWN | STB_TEXTEDIT_K_SHIFT: {
|
||||
case STB_TEXTEDIT_K_DOWN | STB_TEXTEDIT_K_SHIFT:
|
||||
case STB_TEXTEDIT_K_PGDOWN:
|
||||
case STB_TEXTEDIT_K_PGDOWN | STB_TEXTEDIT_K_SHIFT: {
|
||||
StbFindState find;
|
||||
StbTexteditRow row;
|
||||
int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0;
|
||||
int i, j, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0;
|
||||
int is_page = (key & ~STB_TEXTEDIT_K_SHIFT) == STB_TEXTEDIT_K_PGDOWN;
|
||||
int row_count = is_page ? state->row_count_per_page : 1;
|
||||
|
||||
if (state->single_line) {
|
||||
if (!is_page && state->single_line) {
|
||||
// on windows, up&down in single-line behave like left&right
|
||||
key = STB_TEXTEDIT_K_RIGHT | (key & STB_TEXTEDIT_K_SHIFT);
|
||||
goto retry;
|
||||
@ -863,17 +875,25 @@ retry:
|
||||
if (sel)
|
||||
stb_textedit_prep_selection_at_cursor(state);
|
||||
else if (STB_TEXT_HAS_SELECTION(state))
|
||||
stb_textedit_move_to_last(str,state);
|
||||
stb_textedit_move_to_last(str, state);
|
||||
|
||||
// compute current position of cursor point
|
||||
stb_textedit_clamp(str, state);
|
||||
stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
|
||||
|
||||
// now find character position down a row
|
||||
if (find.length) {
|
||||
float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
|
||||
float x;
|
||||
for (j = 0; j < row_count; ++j) {
|
||||
float x, goal_x = state->has_preferred_x ? state->preferred_x : find.x;
|
||||
int start = find.first_char + find.length;
|
||||
|
||||
if (find.length == 0)
|
||||
break;
|
||||
|
||||
// [DEAR IMGUI]
|
||||
// going down while being on the last line shouldn't bring us to that line end
|
||||
if (STB_TEXTEDIT_GETCHAR(str, find.first_char + find.length - 1) != STB_TEXTEDIT_NEWLINE)
|
||||
break;
|
||||
|
||||
// now find character position down a row
|
||||
state->cursor = start;
|
||||
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
|
||||
x = row.x0;
|
||||
@ -895,17 +915,25 @@ retry:
|
||||
|
||||
if (sel)
|
||||
state->select_end = state->cursor;
|
||||
|
||||
// go to next line
|
||||
find.first_char = find.first_char + find.length;
|
||||
find.length = row.num_chars;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case STB_TEXTEDIT_K_UP:
|
||||
case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT: {
|
||||
case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT:
|
||||
case STB_TEXTEDIT_K_PGUP:
|
||||
case STB_TEXTEDIT_K_PGUP | STB_TEXTEDIT_K_SHIFT: {
|
||||
StbFindState find;
|
||||
StbTexteditRow row;
|
||||
int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0;
|
||||
int i, j, prev_scan, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0;
|
||||
int is_page = (key & ~STB_TEXTEDIT_K_SHIFT) == STB_TEXTEDIT_K_PGUP;
|
||||
int row_count = is_page ? state->row_count_per_page : 1;
|
||||
|
||||
if (state->single_line) {
|
||||
if (!is_page && state->single_line) {
|
||||
// on windows, up&down become left&right
|
||||
key = STB_TEXTEDIT_K_LEFT | (key & STB_TEXTEDIT_K_SHIFT);
|
||||
goto retry;
|
||||
@ -920,11 +948,14 @@ retry:
|
||||
stb_textedit_clamp(str, state);
|
||||
stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
|
||||
|
||||
// can only go up if there's a previous row
|
||||
if (find.prev_first != find.first_char) {
|
||||
for (j = 0; j < row_count; ++j) {
|
||||
float x, goal_x = state->has_preferred_x ? state->preferred_x : find.x;
|
||||
|
||||
// can only go up if there's a previous row
|
||||
if (find.prev_first == find.first_char)
|
||||
break;
|
||||
|
||||
// now find character position up a row
|
||||
float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
|
||||
float x;
|
||||
state->cursor = find.prev_first;
|
||||
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
|
||||
x = row.x0;
|
||||
@ -946,6 +977,14 @@ retry:
|
||||
|
||||
if (sel)
|
||||
state->select_end = state->cursor;
|
||||
|
||||
// go to previous line
|
||||
// (we need to scan previous line the hard way. maybe we could expose this as a new API function?)
|
||||
prev_scan = find.prev_first > 0 ? find.prev_first - 1 : 0;
|
||||
while (prev_scan > 0 && STB_TEXTEDIT_GETCHAR(str, prev_scan - 1) != STB_TEXTEDIT_NEWLINE)
|
||||
--prev_scan;
|
||||
find.first_char = find.prev_first;
|
||||
find.prev_first = prev_scan;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -975,7 +1014,7 @@ retry:
|
||||
}
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
|
||||
#ifdef STB_TEXTEDIT_K_TEXTSTART2
|
||||
case STB_TEXTEDIT_K_TEXTSTART2:
|
||||
#endif
|
||||
@ -992,7 +1031,7 @@ retry:
|
||||
state->select_start = state->select_end = 0;
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
|
||||
#ifdef STB_TEXTEDIT_K_TEXTSTART2
|
||||
case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT:
|
||||
#endif
|
||||
@ -1069,10 +1108,6 @@ retry:
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// @TODO:
|
||||
// STB_TEXTEDIT_K_PGUP - move cursor up a page
|
||||
// STB_TEXTEDIT_K_PGDOWN - move cursor down a page
|
||||
}
|
||||
}
|
||||
|
||||
@ -1128,7 +1163,14 @@ static void stb_textedit_discard_redo(StbUndoState *state)
|
||||
state->undo_rec[i].char_storage += n;
|
||||
}
|
||||
// now move all the redo records towards the end of the buffer; the first one is at 'redo_point'
|
||||
STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
|
||||
// [DEAR IMGUI]
|
||||
size_t move_size = (size_t)((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
|
||||
const char* buf_begin = (char*)state->undo_rec; (void)buf_begin;
|
||||
const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end;
|
||||
IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin);
|
||||
IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end);
|
||||
STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
|
||||
|
||||
// now move redo_point to point to the new one
|
||||
++state->redo_point;
|
||||
}
|
||||
@ -1337,6 +1379,7 @@ static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_lin
|
||||
state->initialized = 1;
|
||||
state->single_line = (unsigned char) is_single_line;
|
||||
state->insert_mode = 0;
|
||||
state->row_count_per_page = 0;
|
||||
}
|
||||
|
||||
// API initialize
|
||||
@ -1367,38 +1410,38 @@ This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user