mirror of
https://github.com/wolfpld/tracy.git
synced 2025-03-20 07:40:02 +08:00
Bump ImGui to ~1.77.
This commit is contained in:
+179
-144
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.77 WIP
|
||||
// dear imgui, v1.77
|
||||
// (widgets code)
|
||||
|
||||
/*
|
||||
@@ -58,19 +58,19 @@ Index of this file:
|
||||
|
||||
// Clang/GCC warnings with -Weverything
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse.
|
||||
#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
|
||||
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning : format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
|
||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness //
|
||||
#if __has_warning("-Wzero-as-null-pointer-constant")
|
||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning : zero as null pointer constant // some standard header variations use #define NULL 0
|
||||
#endif
|
||||
#if __has_warning("-Wdouble-promotion")
|
||||
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
|
||||
#endif
|
||||
#if __has_warning("-Wdeprecated-enum-enum-conversion")
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||
#if __has_warning("-Wunknown-warning-option")
|
||||
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great!
|
||||
#endif
|
||||
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||||
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
|
||||
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning: format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
|
||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
|
||||
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
|
||||
#pragma clang diagnostic ignored "-Wenum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_')
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
|
||||
@@ -160,7 +160,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
||||
// - We use memchr(), pay attention that well optimized versions of those str/mem functions are much faster than a casually written loop.
|
||||
const char* line = text;
|
||||
const float line_height = GetTextLineHeight();
|
||||
ImVec2 text_size(0,0);
|
||||
ImVec2 text_size(0, 0);
|
||||
|
||||
// Lines to skip (can't skip when logging text)
|
||||
ImVec2 pos = text_pos;
|
||||
@@ -332,8 +332,8 @@ void ImGui::LabelTextV(const char* label, const char* fmt, va_list args)
|
||||
const float w = CalcItemWidth();
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImRect value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2));
|
||||
const ImRect total_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y*2) + label_size);
|
||||
const ImRect value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2));
|
||||
const ImRect total_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y * 2) + label_size);
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
if (!ItemAdd(total_bb, 0))
|
||||
return;
|
||||
@@ -341,7 +341,7 @@ void ImGui::LabelTextV(const char* label, const char* fmt, va_list args)
|
||||
// Render
|
||||
const char* value_text_begin = &g.TempBuffer[0];
|
||||
const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
||||
RenderTextClipped(value_bb.Min, value_bb.Max, value_text_begin, value_text_end, NULL, ImVec2(0.0f,0.5f));
|
||||
RenderTextClipped(value_bb.Min, value_bb.Max, value_text_begin, value_text_end, NULL, ImVec2(0.0f, 0.5f));
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label);
|
||||
}
|
||||
@@ -377,7 +377,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
|
||||
|
||||
// Render
|
||||
ImU32 text_col = GetColorU32(ImGuiCol_Text);
|
||||
RenderBullet(window->DrawList, bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, g.FontSize*0.5f), text_col);
|
||||
RenderBullet(window->DrawList, bb.Min + ImVec2(style.FramePadding.x + g.FontSize * 0.5f, g.FontSize * 0.5f), text_col);
|
||||
RenderText(bb.Min + ImVec2(g.FontSize + style.FramePadding.x * 2, 0.0f), text_begin, text_end, false);
|
||||
}
|
||||
|
||||
@@ -557,7 +557,8 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
if ((flags & ImGuiButtonFlags_PressedOnRelease) && mouse_button_released != -1)
|
||||
{
|
||||
// Repeat mode trumps on release behavior
|
||||
if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay))
|
||||
const bool has_repeated_at_least_once = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay;
|
||||
if (!has_repeated_at_least_once)
|
||||
pressed = true;
|
||||
ClearActiveID();
|
||||
}
|
||||
@@ -780,8 +781,8 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos)//, float size)
|
||||
float cross_extent = g.FontSize * 0.5f * 0.7071f - 1.0f;
|
||||
ImU32 cross_col = GetColorU32(ImGuiCol_Text);
|
||||
center -= ImVec2(0.5f, 0.5f);
|
||||
window->DrawList->AddLine(center + ImVec2(+cross_extent,+cross_extent), center + ImVec2(-cross_extent,-cross_extent), cross_col, 1.0f);
|
||||
window->DrawList->AddLine(center + ImVec2(+cross_extent,-cross_extent), center + ImVec2(-cross_extent,+cross_extent), cross_col, 1.0f);
|
||||
window->DrawList->AddLine(center + ImVec2(+cross_extent, +cross_extent), center + ImVec2(-cross_extent, -cross_extent), cross_col, 1.0f);
|
||||
window->DrawList->AddLine(center + ImVec2(+cross_extent, -cross_extent), center + ImVec2(-cross_extent, +cross_extent), cross_col, 1.0f);
|
||||
|
||||
return pressed;
|
||||
}
|
||||
@@ -987,28 +988,16 @@ void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2&
|
||||
}
|
||||
}
|
||||
|
||||
// frame_padding < 0: uses FramePadding from style (default)
|
||||
// frame_padding = 0: no framing
|
||||
// frame_padding > 0: set framing size
|
||||
// The color used are the button colors.
|
||||
bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col)
|
||||
// ImageButton() is flawed as 'id' is always derived from 'texture_id' (see #2464 #1390)
|
||||
// We provide this internal helper to write your own variant while we figure out how to redesign the public ImageButton() API.
|
||||
bool ImGui::ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
|
||||
// Default to using texture ID as ID. User can still push string/integer prefixes.
|
||||
// We could hash the size/uv to create a unique ID but that would prevent the user from animating UV.
|
||||
PushID((void*)(intptr_t)user_texture_id);
|
||||
const ImGuiID id = window->GetID("#image");
|
||||
PopID();
|
||||
|
||||
const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : style.FramePadding;
|
||||
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding * 2);
|
||||
const ImRect image_bb(window->DC.CursorPos + padding, window->DC.CursorPos + padding + size);
|
||||
ItemSize(bb);
|
||||
if (!ItemAdd(bb, id))
|
||||
return false;
|
||||
@@ -1019,14 +1008,33 @@ bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const I
|
||||
// Render
|
||||
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
||||
RenderNavHighlight(bb, id);
|
||||
RenderFrame(bb.Min, bb.Max, col, true, ImClamp((float)ImMin(padding.x, padding.y), 0.0f, style.FrameRounding));
|
||||
RenderFrame(bb.Min, bb.Max, col, true, ImClamp((float)ImMin(padding.x, padding.y), 0.0f, g.Style.FrameRounding));
|
||||
if (bg_col.w > 0.0f)
|
||||
window->DrawList->AddRectFilled(image_bb.Min, image_bb.Max, GetColorU32(bg_col));
|
||||
window->DrawList->AddImage(user_texture_id, image_bb.Min, image_bb.Max, uv0, uv1, GetColorU32(tint_col));
|
||||
window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, GetColorU32(bg_col));
|
||||
window->DrawList->AddImage(texture_id, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
// frame_padding < 0: uses FramePadding from style (default)
|
||||
// frame_padding = 0: no framing
|
||||
// frame_padding > 0: set framing size
|
||||
bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
// Default to using texture ID as ID. User can still push string/integer prefixes.
|
||||
PushID((void*)(intptr_t)user_texture_id);
|
||||
const ImGuiID id = window->GetID("#image");
|
||||
PopID();
|
||||
|
||||
const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : g.Style.FramePadding;
|
||||
return ImageButtonEx(id, user_texture_id, size, uv0, uv1, padding, bg_col, tint_col);
|
||||
}
|
||||
|
||||
bool ImGui::Checkbox(const char* label, bool* v)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
@@ -1066,7 +1074,7 @@ bool ImGui::Checkbox(const char* label, bool* v)
|
||||
else if (*v)
|
||||
{
|
||||
const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f));
|
||||
RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad*2.0f);
|
||||
RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f);
|
||||
}
|
||||
|
||||
if (g.LogEnabled)
|
||||
@@ -1132,7 +1140,7 @@ bool ImGui::RadioButton(const char* label, bool active)
|
||||
|
||||
if (style.FrameBorderSize > 0.0f)
|
||||
{
|
||||
window->DrawList->AddCircle(center + ImVec2(1,1), radius, GetColorU32(ImGuiCol_BorderShadow), 16, style.FrameBorderSize);
|
||||
window->DrawList->AddCircle(center + ImVec2(1, 1), radius, GetColorU32(ImGuiCol_BorderShadow), 16, style.FrameBorderSize);
|
||||
window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16, style.FrameBorderSize);
|
||||
}
|
||||
|
||||
@@ -1165,7 +1173,7 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over
|
||||
const ImGuiStyle& style = g.Style;
|
||||
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), g.FontSize + style.FramePadding.y*2.0f);
|
||||
ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), g.FontSize + style.FramePadding.y * 2.0f);
|
||||
ImRect bb(pos, pos + size);
|
||||
ItemSize(size, style.FramePadding.y);
|
||||
if (!ItemAdd(bb, 0))
|
||||
@@ -1182,13 +1190,13 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over
|
||||
char overlay_buf[32];
|
||||
if (!overlay)
|
||||
{
|
||||
ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", fraction*100+0.01f);
|
||||
ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", fraction * 100 + 0.01f);
|
||||
overlay = overlay_buf;
|
||||
}
|
||||
|
||||
ImVec2 overlay_size = CalcTextSize(overlay, NULL);
|
||||
if (overlay_size.x > 0.0f)
|
||||
RenderTextClipped(ImVec2(ImClamp(fill_br.x + style.ItemSpacing.x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImVec2(0.0f,0.5f), &bb);
|
||||
RenderTextClipped(ImVec2(ImClamp(fill_br.x + style.ItemSpacing.x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImVec2(0.0f, 0.5f), &bb);
|
||||
}
|
||||
|
||||
void ImGui::Bullet()
|
||||
@@ -1199,18 +1207,18 @@ void ImGui::Bullet()
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const float line_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + g.Style.FramePadding.y*2), g.FontSize);
|
||||
const float line_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + g.Style.FramePadding.y * 2), g.FontSize);
|
||||
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize, line_height));
|
||||
ItemSize(bb);
|
||||
if (!ItemAdd(bb, 0))
|
||||
{
|
||||
SameLine(0, style.FramePadding.x*2);
|
||||
SameLine(0, style.FramePadding.x * 2);
|
||||
return;
|
||||
}
|
||||
|
||||
// Render and stay on same line
|
||||
ImU32 text_col = GetColorU32(ImGuiCol_Text);
|
||||
RenderBullet(window->DrawList, bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f), text_col);
|
||||
RenderBullet(window->DrawList, bb.Min + ImVec2(style.FramePadding.x + g.FontSize * 0.5f, line_height * 0.5f), text_col);
|
||||
SameLine(0, style.FramePadding.x * 2.0f);
|
||||
}
|
||||
|
||||
@@ -1232,7 +1240,7 @@ void ImGui::Spacing()
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return;
|
||||
ItemSize(ImVec2(0,0));
|
||||
ItemSize(ImVec2(0, 0));
|
||||
}
|
||||
|
||||
void ImGui::Dummy(const ImVec2& size)
|
||||
@@ -1256,7 +1264,7 @@ void ImGui::NewLine()
|
||||
const ImGuiLayoutType backup_layout_type = window->DC.LayoutType;
|
||||
window->DC.LayoutType = ImGuiLayoutType_Vertical;
|
||||
if (window->DC.CurrLineSize.y > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height.
|
||||
ItemSize(ImVec2(0,0));
|
||||
ItemSize(ImVec2(0, 0));
|
||||
else
|
||||
ItemSize(ImVec2(0.0f, g.FontSize));
|
||||
window->DC.LayoutType = backup_layout_type;
|
||||
@@ -1483,7 +1491,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const float expected_w = CalcItemWidth();
|
||||
const float w = (flags & ImGuiComboFlags_NoPreview) ? arrow_size : expected_w;
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f));
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
||||
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
if (!ItemAdd(total_bb, id, &frame_bb))
|
||||
@@ -1491,7 +1499,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
||||
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(frame_bb, id, &hovered, &held);
|
||||
bool popup_open = IsPopupOpen(id);
|
||||
bool popup_open = IsPopupOpen(id, ImGuiPopupFlags_None);
|
||||
|
||||
const ImU32 frame_col = GetColorU32(hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
||||
const float value_x2 = ImMax(frame_bb.Min.x, frame_bb.Max.x - arrow_size);
|
||||
@@ -1508,7 +1516,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
||||
}
|
||||
RenderFrameBorder(frame_bb.Min, frame_bb.Max, style.FrameRounding);
|
||||
if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview))
|
||||
RenderTextClipped(frame_bb.Min + style.FramePadding, ImVec2(value_x2, frame_bb.Max.y), preview_value, NULL, NULL, ImVec2(0.0f,0.0f));
|
||||
RenderTextClipped(frame_bb.Min + style.FramePadding, ImVec2(value_x2, frame_bb.Max.y), preview_value, NULL, NULL, ImVec2(0.0f, 0.0f));
|
||||
if (label_size.x > 0)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||
|
||||
@@ -1516,7 +1524,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
||||
{
|
||||
if (window->DC.NavLayerCurrent == 0)
|
||||
window->NavLastIds[0] = id;
|
||||
OpenPopupEx(id);
|
||||
OpenPopupEx(id, ImGuiPopupFlags_None);
|
||||
popup_open = true;
|
||||
}
|
||||
|
||||
@@ -1618,7 +1626,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
|
||||
|
||||
// The old Combo() API exposed "popup_max_height_in_items". The new more general BeginCombo() API doesn't have/need it, but we emulate it here.
|
||||
if (popup_max_height_in_items != -1 && !(g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint))
|
||||
SetNextWindowSizeConstraints(ImVec2(0,0), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items)));
|
||||
SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items)));
|
||||
|
||||
if (!BeginCombo(label, preview_value, ImGuiComboFlags_None))
|
||||
return false;
|
||||
@@ -2010,7 +2018,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
|
||||
|
||||
// Inputs accumulates into g.DragCurrentAccum, which is flushed into the current value as soon as it makes a difference with our precision settings
|
||||
float adjust_delta = 0.0f;
|
||||
if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid() && g.IO.MouseDragMaxDistanceSqr[0] > 1.0f*1.0f)
|
||||
if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid() && g.IO.MouseDragMaxDistanceSqr[0] > 1.0f * 1.0f)
|
||||
{
|
||||
adjust_delta = g.IO.MouseDelta[axis];
|
||||
if (g.IO.KeyAlt)
|
||||
@@ -2147,7 +2155,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const float w = CalcItemWidth();
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f));
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
||||
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
@@ -2368,12 +2376,12 @@ float ImGui::SliderCalcRatioFromValueT(ImGuiDataType data_type, TYPE v, TYPE v_m
|
||||
if (v_clamped < 0.0f)
|
||||
{
|
||||
const float f = 1.0f - (float)((v_clamped - v_min) / (ImMin((TYPE)0, v_max) - v_min));
|
||||
return (1.0f - ImPow(f, 1.0f/power)) * linear_zero_pos;
|
||||
return (1.0f - ImPow(f, 1.0f / power)) * linear_zero_pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
const float f = (float)((v_clamped - ImMax((TYPE)0, v_min)) / (v_max - ImMax((TYPE)0, v_min)));
|
||||
return linear_zero_pos + ImPow(f, 1.0f/power) * (1.0f - linear_zero_pos);
|
||||
return linear_zero_pos + ImPow(f, 1.0f / power) * (1.0f - linear_zero_pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2449,7 +2457,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
||||
}
|
||||
else if (delta != 0.0f)
|
||||
{
|
||||
clicked_t = SliderCalcRatioFromValueT<TYPE,FLOATTYPE>(data_type, *v, v_min, v_max, power, linear_zero_pos);
|
||||
clicked_t = SliderCalcRatioFromValueT<TYPE, FLOATTYPE>(data_type, *v, v_min, v_max, power, linear_zero_pos);
|
||||
const int decimal_precision = is_decimal ? ImParseFormatPrecision(format, 3) : 0;
|
||||
if ((decimal_precision > 0) || is_power)
|
||||
{
|
||||
@@ -2521,7 +2529,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
||||
}
|
||||
|
||||
// Round to user desired precision based on format string
|
||||
v_new = RoundScalarWithFormatT<TYPE,SIGNEDTYPE>(format, data_type, v_new);
|
||||
v_new = RoundScalarWithFormatT<TYPE, SIGNEDTYPE>(format, data_type, v_new);
|
||||
|
||||
// Apply result
|
||||
if (*v != v_new)
|
||||
@@ -2564,23 +2572,23 @@ bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type
|
||||
case ImGuiDataType_S16: { ImS32 v32 = (ImS32)*(ImS16*)p_v; bool r = SliderBehaviorT<ImS32, ImS32, float>(bb, id, ImGuiDataType_S32, &v32, *(const ImS16*)p_min, *(const ImS16*)p_max, format, power, flags, out_grab_bb); if (r) *(ImS16*)p_v = (ImS16)v32; return r; }
|
||||
case ImGuiDataType_U16: { ImU32 v32 = (ImU32)*(ImU16*)p_v; bool r = SliderBehaviorT<ImU32, ImS32, float>(bb, id, ImGuiDataType_U32, &v32, *(const ImU16*)p_min, *(const ImU16*)p_max, format, power, flags, out_grab_bb); if (r) *(ImU16*)p_v = (ImU16)v32; return r; }
|
||||
case ImGuiDataType_S32:
|
||||
IM_ASSERT(*(const ImS32*)p_min >= IM_S32_MIN/2 && *(const ImS32*)p_max <= IM_S32_MAX/2);
|
||||
IM_ASSERT(*(const ImS32*)p_min >= IM_S32_MIN / 2 && *(const ImS32*)p_max <= IM_S32_MAX / 2);
|
||||
return SliderBehaviorT<ImS32, ImS32, float >(bb, id, data_type, (ImS32*)p_v, *(const ImS32*)p_min, *(const ImS32*)p_max, format, power, flags, out_grab_bb);
|
||||
case ImGuiDataType_U32:
|
||||
IM_ASSERT(*(const ImU32*)p_max <= IM_U32_MAX/2);
|
||||
IM_ASSERT(*(const ImU32*)p_max <= IM_U32_MAX / 2);
|
||||
return SliderBehaviorT<ImU32, ImS32, float >(bb, id, data_type, (ImU32*)p_v, *(const ImU32*)p_min, *(const ImU32*)p_max, format, power, flags, out_grab_bb);
|
||||
case ImGuiDataType_S64:
|
||||
IM_ASSERT(*(const ImS64*)p_min >= IM_S64_MIN/2 && *(const ImS64*)p_max <= IM_S64_MAX/2);
|
||||
IM_ASSERT(*(const ImS64*)p_min >= IM_S64_MIN / 2 && *(const ImS64*)p_max <= IM_S64_MAX / 2);
|
||||
return SliderBehaviorT<ImS64, ImS64, double>(bb, id, data_type, (ImS64*)p_v, *(const ImS64*)p_min, *(const ImS64*)p_max, format, power, flags, out_grab_bb);
|
||||
case ImGuiDataType_U64:
|
||||
IM_ASSERT(*(const ImU64*)p_max <= IM_U64_MAX/2);
|
||||
IM_ASSERT(*(const ImU64*)p_max <= IM_U64_MAX / 2);
|
||||
return SliderBehaviorT<ImU64, ImS64, double>(bb, id, data_type, (ImU64*)p_v, *(const ImU64*)p_min, *(const ImU64*)p_max, format, power, flags, out_grab_bb);
|
||||
case ImGuiDataType_Float:
|
||||
IM_ASSERT(*(const float*)p_min >= -FLT_MAX/2.0f && *(const float*)p_max <= FLT_MAX/2.0f);
|
||||
IM_ASSERT(*(const float*)p_min >= -FLT_MAX / 2.0f && *(const float*)p_max <= FLT_MAX / 2.0f);
|
||||
return SliderBehaviorT<float, float, float >(bb, id, data_type, (float*)p_v, *(const float*)p_min, *(const float*)p_max, format, power, flags, out_grab_bb);
|
||||
case ImGuiDataType_Double:
|
||||
IM_ASSERT(*(const double*)p_min >= -DBL_MAX/2.0f && *(const double*)p_max <= DBL_MAX/2.0f);
|
||||
return SliderBehaviorT<double,double,double>(bb, id, data_type, (double*)p_v, *(const double*)p_min, *(const double*)p_max, format, power, flags, out_grab_bb);
|
||||
IM_ASSERT(*(const double*)p_min >= -DBL_MAX / 2.0f && *(const double*)p_max <= DBL_MAX / 2.0f);
|
||||
return SliderBehaviorT<double, double, double>(bb, id, data_type, (double*)p_v, *(const double*)p_min, *(const double*)p_max, format, power, flags, out_grab_bb);
|
||||
case ImGuiDataType_COUNT: break;
|
||||
}
|
||||
IM_ASSERT(0);
|
||||
@@ -2601,7 +2609,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
const float w = CalcItemWidth();
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f));
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
||||
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
@@ -2658,7 +2666,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
||||
char value_buf[64];
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f,0.5f));
|
||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
||||
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||
@@ -2727,9 +2735,9 @@ bool ImGui::SliderAngle(const char* label, float* v_rad, float v_degrees_min, fl
|
||||
{
|
||||
if (format == NULL)
|
||||
format = "%.0f deg";
|
||||
float v_deg = (*v_rad) * 360.0f / (2*IM_PI);
|
||||
float v_deg = (*v_rad) * 360.0f / (2 * IM_PI);
|
||||
bool value_changed = SliderFloat(label, &v_deg, v_degrees_min, v_degrees_max, format, 1.0f);
|
||||
*v_rad = v_deg * (2*IM_PI) / 360.0f;
|
||||
*v_rad = v_deg * (2 * IM_PI) / 360.0f;
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
@@ -2805,7 +2813,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
|
||||
// For the vertical slider we allow centered text to overlap the frame padding
|
||||
char value_buf[64];
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
||||
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f,0.0f));
|
||||
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.0f));
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||
|
||||
@@ -3096,7 +3104,7 @@ bool ImGui::InputScalarN(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
bool ImGui::InputFloat(const char* label, float* v, float step, float step_fast, const char* format, ImGuiInputTextFlags flags)
|
||||
{
|
||||
flags |= ImGuiInputTextFlags_CharsScientific;
|
||||
return InputScalar(label, ImGuiDataType_Float, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), format, flags);
|
||||
return InputScalar(label, ImGuiDataType_Float, (void*)v, (void*)(step > 0.0f ? &step : NULL), (void*)(step_fast > 0.0f ? &step_fast : NULL), format, flags);
|
||||
}
|
||||
|
||||
bool ImGui::InputFloat2(const char* label, float v[2], const char* format, ImGuiInputTextFlags flags)
|
||||
@@ -3153,7 +3161,7 @@ bool ImGui::InputInt(const char* label, int* v, int step, int step_fast, ImGuiIn
|
||||
{
|
||||
// Hexadecimal input provided as a convenience but the flag name is awkward. Typically you'd use InputText() to parse your own data, if you want to handle prefixes.
|
||||
const char* format = (flags & ImGuiInputTextFlags_CharsHexadecimal) ? "%08X" : "%d";
|
||||
return InputScalar(label, ImGuiDataType_S32, (void*)v, (void*)(step>0 ? &step : NULL), (void*)(step_fast>0 ? &step_fast : NULL), format, flags);
|
||||
return InputScalar(label, ImGuiDataType_S32, (void*)v, (void*)(step > 0 ? &step : NULL), (void*)(step_fast > 0 ? &step_fast : NULL), format, flags);
|
||||
}
|
||||
|
||||
bool ImGui::InputInt2(const char* label, int v[2], ImGuiInputTextFlags flags)
|
||||
@@ -3174,7 +3182,7 @@ bool ImGui::InputInt4(const char* label, int v[4], ImGuiInputTextFlags flags)
|
||||
bool ImGui::InputDouble(const char* label, double* v, double step, double step_fast, const char* format, ImGuiInputTextFlags flags)
|
||||
{
|
||||
flags |= ImGuiInputTextFlags_CharsScientific;
|
||||
return InputScalar(label, ImGuiDataType_Double, (void*)v, (void*)(step>0.0 ? &step : NULL), (void*)(step_fast>0.0 ? &step_fast : NULL), format, flags);
|
||||
return InputScalar(label, ImGuiDataType_Double, (void*)v, (void*)(step > 0.0 ? &step : NULL), (void*)(step_fast > 0.0 ? &step_fast : NULL), format, flags);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -3189,7 +3197,7 @@ bool ImGui::InputDouble(const char* label, double* v, double step, double step_f
|
||||
bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
|
||||
{
|
||||
IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline()
|
||||
return InputTextEx(label, NULL, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data);
|
||||
return InputTextEx(label, NULL, buf, (int)buf_size, ImVec2(0, 0), flags, callback, user_data);
|
||||
}
|
||||
|
||||
bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
|
||||
@@ -3224,7 +3232,7 @@ static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* t
|
||||
const float line_height = g.FontSize;
|
||||
const float scale = line_height / font->FontSize;
|
||||
|
||||
ImVec2 text_size = ImVec2(0,0);
|
||||
ImVec2 text_size = ImVec2(0, 0);
|
||||
float line_width = 0.0f;
|
||||
|
||||
const ImWchar* s = text_begin;
|
||||
@@ -3285,10 +3293,10 @@ static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* ob
|
||||
}
|
||||
|
||||
static bool is_separator(unsigned int c) { return ImCharIsBlankW(c) || c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; }
|
||||
static int is_word_boundary_from_right(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (is_separator( obj->TextW[idx-1] ) && !is_separator( obj->TextW[idx] ) ) : 1; }
|
||||
static int is_word_boundary_from_right(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (is_separator(obj->TextW[idx - 1]) && !is_separator(obj->TextW[idx]) ) : 1; }
|
||||
static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { idx--; while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; }
|
||||
#ifdef __APPLE__ // FIXME: Move setting to IO structure
|
||||
static int is_word_boundary_from_left(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (!is_separator( obj->TextW[idx-1] ) && is_separator( obj->TextW[idx] ) ) : 1; }
|
||||
static int is_word_boundary_from_left(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (!is_separator(obj->TextW[idx - 1]) && is_separator(obj->TextW[idx]) ) : 1; }
|
||||
static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; }
|
||||
#else
|
||||
static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; }
|
||||
@@ -3476,21 +3484,25 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
|
||||
// Generic named filters
|
||||
if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific))
|
||||
{
|
||||
// Allow 0-9 . - + * /
|
||||
if (flags & ImGuiInputTextFlags_CharsDecimal)
|
||||
if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/'))
|
||||
return false;
|
||||
|
||||
// Allow 0-9 . - + * / e E
|
||||
if (flags & ImGuiInputTextFlags_CharsScientific)
|
||||
if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/') && (c != 'e') && (c != 'E'))
|
||||
return false;
|
||||
|
||||
// Allow 0-9 a-F A-F
|
||||
if (flags & ImGuiInputTextFlags_CharsHexadecimal)
|
||||
if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F'))
|
||||
return false;
|
||||
|
||||
// Turn a-z into A-Z
|
||||
if (flags & ImGuiInputTextFlags_CharsUppercase)
|
||||
if (c >= 'a' && c <= 'z')
|
||||
*p_char = (c += (unsigned int)('A'-'a'));
|
||||
*p_char = (c += (unsigned int)('A' - 'a'));
|
||||
|
||||
if (flags & ImGuiInputTextFlags_CharsNoBlank)
|
||||
if (ImCharIsBlankW(c))
|
||||
@@ -3551,7 +3563,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
BeginGroup();
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImVec2 frame_size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? g.FontSize * 8.0f : label_size.y) + style.FramePadding.y*2.0f); // Arbitrary default of 8 lines high for multi-line
|
||||
const ImVec2 frame_size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? g.FontSize * 8.0f : label_size.y) + style.FramePadding.y * 2.0f); // Arbitrary default of 8 lines high for multi-line
|
||||
const ImVec2 total_size = ImVec2(frame_size.x + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), frame_size.y);
|
||||
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size);
|
||||
@@ -3741,7 +3753,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
// Edit in progress
|
||||
const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + state->ScrollX;
|
||||
const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize*0.5f));
|
||||
const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize * 0.5f));
|
||||
|
||||
const bool is_osx = io.ConfigMacOSXBehaviors;
|
||||
if (select_all || (hovered && !is_osx && io.MouseDoubleClicked[0]))
|
||||
@@ -3837,9 +3849,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (!state->HasSelection())
|
||||
{
|
||||
if (is_wordmove_key_down)
|
||||
state->OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT|STB_TEXTEDIT_K_SHIFT);
|
||||
state->OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT);
|
||||
else if (is_osx && io.KeySuper && !io.KeyAlt && !io.KeyCtrl)
|
||||
state->OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT);
|
||||
state->OnKeyPressed(STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT);
|
||||
}
|
||||
state->OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask);
|
||||
}
|
||||
@@ -3898,7 +3910,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
// Filter pasted buffer
|
||||
const int clipboard_len = (int)strlen(clipboard);
|
||||
ImWchar* clipboard_filtered = (ImWchar*)IM_ALLOC((clipboard_len+1) * sizeof(ImWchar));
|
||||
ImWchar* clipboard_filtered = (ImWchar*)IM_ALLOC((clipboard_len + 1) * sizeof(ImWchar));
|
||||
int clipboard_filtered_len = 0;
|
||||
for (const char* s = clipboard; *s; )
|
||||
{
|
||||
@@ -4230,7 +4242,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
ImVec2 rect_size = InputTextCalcTextSizeW(p, text_selected_end, &p, NULL, true);
|
||||
if (rect_size.x <= 0.0f) rect_size.x = IM_FLOOR(g.Font->GetCharAdvance((ImWchar)' ') * 0.50f); // So we can see selected empty lines
|
||||
ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos +ImVec2(rect_size.x, bg_offy_dn));
|
||||
ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos + ImVec2(rect_size.x, bg_offy_dn));
|
||||
rect.ClipWith(clip_rect);
|
||||
if (rect.Overlaps(clip_rect))
|
||||
draw_window->DrawList->AddRectFilled(rect.Min, rect.Max, bg_color);
|
||||
@@ -4293,7 +4305,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
PopFont();
|
||||
|
||||
// Log as text
|
||||
if (g.LogEnabled && !(is_password && !is_displaying_hint))
|
||||
if (g.LogEnabled && (!is_password || is_displaying_hint))
|
||||
LogRenderedText(&draw_pos, buf_display, buf_display_end);
|
||||
|
||||
if (label_size.x > 0)
|
||||
@@ -4404,8 +4416,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
if ((flags & (ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV)) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0)
|
||||
{
|
||||
// RGB/HSV 0..255 Sliders
|
||||
const float w_item_one = ImMax(1.0f, IM_FLOOR((w_inputs - (style.ItemInnerSpacing.x) * (components-1)) / (float)components));
|
||||
const float w_item_last = ImMax(1.0f, IM_FLOOR(w_inputs - (w_item_one + style.ItemInnerSpacing.x) * (components-1)));
|
||||
const float w_item_one = ImMax(1.0f, IM_FLOOR((w_inputs - (style.ItemInnerSpacing.x) * (components - 1)) / (float)components));
|
||||
const float w_item_last = ImMax(1.0f, IM_FLOOR(w_inputs - (w_item_one + style.ItemInnerSpacing.x) * (components - 1)));
|
||||
|
||||
const bool hide_prefix = (w_item_one <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x);
|
||||
static const char* ids[4] = { "##X", "##Y", "##Z", "##W" };
|
||||
@@ -4432,7 +4444,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
// FIXME: When ImGuiColorEditFlags_HDR flag is passed HS values snap in weird ways when SV values go below 0.
|
||||
if (flags & ImGuiColorEditFlags_Float)
|
||||
{
|
||||
value_changed |= DragFloat(ids[n], &f[n], 1.0f/255.0f, 0.0f, hdr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n]);
|
||||
value_changed |= DragFloat(ids[n], &f[n], 1.0f / 255.0f, 0.0f, hdr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n]);
|
||||
value_changed_as_float |= value_changed;
|
||||
}
|
||||
else
|
||||
@@ -4440,7 +4452,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]);
|
||||
}
|
||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||
OpenPopupOnItemClick("context");
|
||||
OpenPopupContextItem("context");
|
||||
}
|
||||
}
|
||||
else if ((flags & ImGuiColorEditFlags_DisplayHex) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0)
|
||||
@@ -4448,9 +4460,9 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
// RGB Hexadecimal Input
|
||||
char buf[64];
|
||||
if (alpha)
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", ImClamp(i[0],0,255), ImClamp(i[1],0,255), ImClamp(i[2],0,255), ImClamp(i[3],0,255));
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255), ImClamp(i[3], 0, 255));
|
||||
else
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", ImClamp(i[0],0,255), ImClamp(i[1],0,255), ImClamp(i[2],0,255));
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255));
|
||||
SetNextItemWidth(w_inputs);
|
||||
if (InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase))
|
||||
{
|
||||
@@ -4465,7 +4477,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]);
|
||||
}
|
||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||
OpenPopupOnItemClick("context");
|
||||
OpenPopupContextItem("context");
|
||||
}
|
||||
|
||||
ImGuiWindow* picker_active_window = NULL;
|
||||
@@ -4482,11 +4494,11 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
// Store current color and open a picker
|
||||
g.ColorPickerRef = col_v4;
|
||||
OpenPopup("picker");
|
||||
SetNextWindowPos(window->DC.LastItemRect.GetBL() + ImVec2(-1,style.ItemSpacing.y));
|
||||
SetNextWindowPos(window->DC.LastItemRect.GetBL() + ImVec2(-1, style.ItemSpacing.y));
|
||||
}
|
||||
}
|
||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||
OpenPopupOnItemClick("context");
|
||||
OpenPopupContextItem("context");
|
||||
|
||||
if (BeginPopup("picker"))
|
||||
{
|
||||
@@ -4643,7 +4655,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
float wheel_thickness = sv_picker_size * 0.08f;
|
||||
float wheel_r_outer = sv_picker_size * 0.50f;
|
||||
float wheel_r_inner = wheel_r_outer - wheel_thickness;
|
||||
ImVec2 wheel_center(picker_pos.x + (sv_picker_size + bars_width)*0.5f, picker_pos.y + sv_picker_size*0.5f);
|
||||
ImVec2 wheel_center(picker_pos.x + (sv_picker_size + bars_width)*0.5f, picker_pos.y + sv_picker_size * 0.5f);
|
||||
|
||||
// Note: the triangle is displayed rotated with triangle_pa pointing to Hue, but most coordinates stays unrotated for logic.
|
||||
float triangle_r = wheel_r_inner - (int)(sv_picker_size * 0.027f);
|
||||
@@ -4682,10 +4694,10 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
ImVec2 initial_off = g.IO.MouseClickedPos[0] - wheel_center;
|
||||
ImVec2 current_off = g.IO.MousePos - wheel_center;
|
||||
float initial_dist2 = ImLengthSqr(initial_off);
|
||||
if (initial_dist2 >= (wheel_r_inner-1)*(wheel_r_inner-1) && initial_dist2 <= (wheel_r_outer+1)*(wheel_r_outer+1))
|
||||
if (initial_dist2 >= (wheel_r_inner - 1) * (wheel_r_inner - 1) && initial_dist2 <= (wheel_r_outer + 1) * (wheel_r_outer + 1))
|
||||
{
|
||||
// Interactive with Hue wheel
|
||||
H = ImAtan2(current_off.y, current_off.x) / IM_PI*0.5f;
|
||||
H = ImAtan2(current_off.y, current_off.x) / IM_PI * 0.5f;
|
||||
if (H < 0.0f)
|
||||
H += 1.0f;
|
||||
value_changed = value_changed_h = true;
|
||||
@@ -4706,7 +4718,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
}
|
||||
}
|
||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||
OpenPopupOnItemClick("context");
|
||||
OpenPopupContextItem("context");
|
||||
}
|
||||
else if (flags & ImGuiColorEditFlags_PickerHueBar)
|
||||
{
|
||||
@@ -4714,19 +4726,19 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
InvisibleButton("sv", ImVec2(sv_picker_size, sv_picker_size));
|
||||
if (IsItemActive())
|
||||
{
|
||||
S = ImSaturate((io.MousePos.x - picker_pos.x) / (sv_picker_size-1));
|
||||
V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1));
|
||||
S = ImSaturate((io.MousePos.x - picker_pos.x) / (sv_picker_size - 1));
|
||||
V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size - 1));
|
||||
value_changed = value_changed_sv = true;
|
||||
}
|
||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||
OpenPopupOnItemClick("context");
|
||||
OpenPopupContextItem("context");
|
||||
|
||||
// Hue bar logic
|
||||
SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y));
|
||||
InvisibleButton("hue", ImVec2(bars_width, sv_picker_size));
|
||||
if (IsItemActive())
|
||||
{
|
||||
H = ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1));
|
||||
H = ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size - 1));
|
||||
value_changed = value_changed_h = true;
|
||||
}
|
||||
}
|
||||
@@ -4738,7 +4750,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
InvisibleButton("alpha", ImVec2(bars_width, sv_picker_size));
|
||||
if (IsItemActive())
|
||||
{
|
||||
col[3] = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1));
|
||||
col[3] = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size - 1));
|
||||
value_changed = true;
|
||||
}
|
||||
}
|
||||
@@ -4789,7 +4801,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
{
|
||||
if (flags & ImGuiColorEditFlags_InputRGB)
|
||||
{
|
||||
ColorConvertHSVtoRGB(H >= 1.0f ? H - 10 * 1e-6f : H, S > 0.0f ? S : 10*1e-6f, V > 0.0f ? V : 1e-6f, col[0], col[1], col[2]);
|
||||
ColorConvertHSVtoRGB(H >= 1.0f ? H - 10 * 1e-6f : H, S > 0.0f ? S : 10 * 1e-6f, V > 0.0f ? V : 1e-6f, col[0], col[1], col[2]);
|
||||
g.ColorEditLastHue = H;
|
||||
g.ColorEditLastSat = S;
|
||||
memcpy(g.ColorEditLastColor, col, sizeof(float) * 3);
|
||||
@@ -4892,17 +4904,17 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
// Paint colors over existing vertices
|
||||
ImVec2 gradient_p0(wheel_center.x + ImCos(a0) * wheel_r_inner, wheel_center.y + ImSin(a0) * wheel_r_inner);
|
||||
ImVec2 gradient_p1(wheel_center.x + ImCos(a1) * wheel_r_inner, wheel_center.y + ImSin(a1) * wheel_r_inner);
|
||||
ShadeVertsLinearColorGradientKeepAlpha(draw_list, vert_start_idx, vert_end_idx, gradient_p0, gradient_p1, col_hues[n], col_hues[n+1]);
|
||||
ShadeVertsLinearColorGradientKeepAlpha(draw_list, vert_start_idx, vert_end_idx, gradient_p0, gradient_p1, col_hues[n], col_hues[n + 1]);
|
||||
}
|
||||
|
||||
// Render Cursor + preview on Hue Wheel
|
||||
float cos_hue_angle = ImCos(H * 2.0f * IM_PI);
|
||||
float sin_hue_angle = ImSin(H * 2.0f * IM_PI);
|
||||
ImVec2 hue_cursor_pos(wheel_center.x + cos_hue_angle * (wheel_r_inner+wheel_r_outer)*0.5f, wheel_center.y + sin_hue_angle * (wheel_r_inner+wheel_r_outer)*0.5f);
|
||||
ImVec2 hue_cursor_pos(wheel_center.x + cos_hue_angle * (wheel_r_inner + wheel_r_outer) * 0.5f, wheel_center.y + sin_hue_angle * (wheel_r_inner + wheel_r_outer) * 0.5f);
|
||||
float hue_cursor_rad = value_changed_h ? wheel_thickness * 0.65f : wheel_thickness * 0.55f;
|
||||
int hue_cursor_segments = ImClamp((int)(hue_cursor_rad / 1.4f), 9, 32);
|
||||
draw_list->AddCircleFilled(hue_cursor_pos, hue_cursor_rad, hue_color32, hue_cursor_segments);
|
||||
draw_list->AddCircle(hue_cursor_pos, hue_cursor_rad+1, col_midgrey, hue_cursor_segments);
|
||||
draw_list->AddCircle(hue_cursor_pos, hue_cursor_rad + 1, col_midgrey, hue_cursor_segments);
|
||||
draw_list->AddCircle(hue_cursor_pos, hue_cursor_rad, col_white, hue_cursor_segments);
|
||||
|
||||
// Render SV triangle (rotated according to hue)
|
||||
@@ -4940,7 +4952,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
// Render cursor/preview circle (clamp S/V within 0..1 range because floating points colors may lead HSV values to be out of range)
|
||||
float sv_cursor_rad = value_changed_sv ? 10.0f : 6.0f;
|
||||
draw_list->AddCircleFilled(sv_cursor_pos, sv_cursor_rad, user_col32_striped_of_alpha, 12);
|
||||
draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad+1, col_midgrey, 12);
|
||||
draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad + 1, col_midgrey, 12);
|
||||
draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad, col_white, 12);
|
||||
|
||||
// Render alpha bar
|
||||
@@ -5012,8 +5024,8 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
||||
if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f)
|
||||
{
|
||||
float mid_x = IM_ROUND((bb_inner.Min.x + bb_inner.Max.x) * 0.5f);
|
||||
RenderColorRectWithAlphaCheckerboard(window->DrawList, ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), grid_step, ImVec2(-grid_step + off, off), rounding, ImDrawCornerFlags_TopRight| ImDrawCornerFlags_BotRight);
|
||||
window->DrawList->AddRectFilled(bb_inner.Min, ImVec2(mid_x, bb_inner.Max.y), GetColorU32(col_rgb_without_alpha), rounding, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotLeft);
|
||||
RenderColorRectWithAlphaCheckerboard(window->DrawList, ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), grid_step, ImVec2(-grid_step + off, off), rounding, ImDrawCornerFlags_TopRight | ImDrawCornerFlags_BotRight);
|
||||
window->DrawList->AddRectFilled(bb_inner.Min, ImVec2(mid_x, bb_inner.Max.y), GetColorU32(col_rgb_without_alpha), rounding, ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotLeft);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5131,7 +5143,7 @@ void ImGui::ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags)
|
||||
|
||||
if (allow_opt_inputs || allow_opt_datatype)
|
||||
Separator();
|
||||
if (Button("Copy as..", ImVec2(-1,0)))
|
||||
if (Button("Copy as..", ImVec2(-1, 0)))
|
||||
OpenPopup("Copy");
|
||||
if (BeginPopup("Copy"))
|
||||
{
|
||||
@@ -5175,7 +5187,7 @@ void ImGui::ColorPickerOptionsPopup(const float* ref_col, ImGuiColorEditFlags fl
|
||||
// Draw small/thumbnail version of each picker type (over an invisible button for selection)
|
||||
if (picker_type > 0) Separator();
|
||||
PushID(picker_type);
|
||||
ImGuiColorEditFlags picker_flags = ImGuiColorEditFlags_NoInputs|ImGuiColorEditFlags_NoOptions|ImGuiColorEditFlags_NoLabel|ImGuiColorEditFlags_NoSidePreview|(flags & ImGuiColorEditFlags_NoAlpha);
|
||||
ImGuiColorEditFlags picker_flags = ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoSidePreview | (flags & ImGuiColorEditFlags_NoAlpha);
|
||||
if (picker_type == 0) picker_flags |= ImGuiColorEditFlags_PickerHueBar;
|
||||
if (picker_type == 1) picker_flags |= ImGuiColorEditFlags_PickerHueWheel;
|
||||
ImVec2 backup_pos = GetCursorScreenPos();
|
||||
@@ -5359,7 +5371,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
const ImVec2 label_size = CalcTextSize(label, label_end, false);
|
||||
|
||||
// We vertically grow up to current line height up the typical widget height.
|
||||
const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y*2), label_size.y + padding.y*2);
|
||||
const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2);
|
||||
ImRect frame_bb;
|
||||
frame_bb.Min.x = (flags & ImGuiTreeNodeFlags_SpanFullWidth) ? window->WorkRect.Min.x : window->DC.CursorPos.x;
|
||||
frame_bb.Min.y = window->DC.CursorPos.y;
|
||||
@@ -5373,9 +5385,9 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
frame_bb.Max.x += IM_FLOOR(window->WindowPadding.x * 0.5f);
|
||||
}
|
||||
|
||||
const float text_offset_x = g.FontSize + (display_frame ? padding.x*3 : padding.x*2); // Collapser arrow width + Spacing
|
||||
const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapser arrow width + Spacing
|
||||
const float text_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it
|
||||
const float text_width = g.FontSize + (label_size.x > 0.0f ? label_size.x + padding.x*2 : 0.0f); // Include collapser
|
||||
const float text_width = g.FontSize + (label_size.x > 0.0f ? label_size.x + padding.x * 2 : 0.0f); // Include collapser
|
||||
ImVec2 text_pos(window->DC.CursorPos.x + text_offset_x, window->DC.CursorPos.y + text_offset_y);
|
||||
ItemSize(ImVec2(text_width, frame_height), padding.y);
|
||||
|
||||
@@ -5509,9 +5521,9 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
// NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here.
|
||||
const char log_prefix[] = "\n##";
|
||||
const char log_suffix[] = "##";
|
||||
LogRenderedText(&text_pos, log_prefix, log_prefix+3);
|
||||
LogRenderedText(&text_pos, log_prefix, log_prefix + 3);
|
||||
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
|
||||
LogRenderedText(&text_pos, log_suffix, log_suffix+2);
|
||||
LogRenderedText(&text_pos, log_suffix, log_suffix + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5632,7 +5644,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags
|
||||
if (p_open)
|
||||
flags |= ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton;
|
||||
bool is_open = TreeNodeBehavior(id, flags, label);
|
||||
if (p_open)
|
||||
if (p_open != NULL)
|
||||
{
|
||||
// Create a small overlapping close button
|
||||
// FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc.
|
||||
@@ -5986,7 +5998,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_get
|
||||
const float v0 = values_getter(data, (v_idx + values_offset) % values_count);
|
||||
const float v1 = values_getter(data, (v_idx + 1 + values_offset) % values_count);
|
||||
if (plot_type == ImGuiPlotType_Lines)
|
||||
SetTooltip("%d: %8.4g\n%d: %8.4g", v_idx, v0, v_idx+1, v1);
|
||||
SetTooltip("%d: %8.4g\n%d: %8.4g", v_idx, v0, v_idx + 1, v1);
|
||||
else if (plot_type == ImGuiPlotType_Histogram)
|
||||
SetTooltip("%d: %8.4g", v_idx, v0);
|
||||
idx_hovered = v_idx;
|
||||
@@ -6032,7 +6044,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_get
|
||||
|
||||
// Text overlay
|
||||
if (overlay_text)
|
||||
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, overlay_text, NULL, NULL, ImVec2(0.5f,0.0f));
|
||||
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, overlay_text, NULL, NULL, ImVec2(0.5f, 0.0f));
|
||||
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label);
|
||||
@@ -6307,7 +6319,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
bool menu_is_open = IsPopupOpen(id);
|
||||
bool menu_is_open = IsPopupOpen(id, ImGuiPopupFlags_None);
|
||||
|
||||
// Sub-menus are ChildWindow so that mouse can be hovering across them (otherwise top-most popup menu would steal focus and not allow hovering on parent menu)
|
||||
ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus;
|
||||
@@ -6433,7 +6445,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
||||
|
||||
if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }'
|
||||
want_close = true;
|
||||
if (want_close && IsPopupOpen(id))
|
||||
if (want_close && IsPopupOpen(id, ImGuiPopupFlags_None))
|
||||
ClosePopupToLevel(g.BeginPopupStack.Size, true);
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0));
|
||||
@@ -7242,7 +7254,9 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
if (tab_bar->Tabs.Size == 1 && !(tab_bar->Flags & ImGuiTabBarFlags_AutoSelectNewTabs))
|
||||
tab_contents_visible = true;
|
||||
|
||||
if (tab_appearing && !(tab_bar_appearing && !tab_is_new))
|
||||
// Note that tab_is_new is not necessarily the same as tab_appearing! When a tab bar stops being submitted
|
||||
// and then gets submitted again, the tabs will have 'tab_appearing=true' but 'tab_is_new=false'.
|
||||
if (tab_appearing && (!tab_bar_appearing || tab_is_new))
|
||||
{
|
||||
PushItemFlag(ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus, true);
|
||||
ItemAdd(ImRect(), id);
|
||||
@@ -7401,14 +7415,16 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
// Tooltip (FIXME: Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer)
|
||||
// We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar (which g.HoveredId ignores)
|
||||
if (g.HoveredId == id && !held && g.HoveredIdNotActiveTimer > 0.50f && IsItemHovered())
|
||||
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip))
|
||||
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
|
||||
SetTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
|
||||
|
||||
return tab_contents_visible;
|
||||
}
|
||||
|
||||
// [Public] This is call is 100% optional but it allows to remove some one-frame glitches when a tab has been unexpectedly removed.
|
||||
// To use it to need to call the function SetTabItemClosed() after BeginTabBar() and before any call to BeginTabItem()
|
||||
// To use it to need to call the function SetTabItemClosed() after BeginTabBar() and before any call to BeginTabItem().
|
||||
// Tabs closed by the close button will automatically be flagged to avoid this issue.
|
||||
// FIXME: We should aim to support calling SetTabItemClosed() after the tab submission (for next frame)
|
||||
void ImGui::SetTabItemClosed(const char* label)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@@ -7541,6 +7557,7 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
|
||||
// [SECTION] Widgets: Columns, BeginColumns, EndColumns, etc.
|
||||
// In the current version, Columns are very weak. Needs to be replaced with a more full-featured system.
|
||||
//-------------------------------------------------------------------------
|
||||
// - SetWindowClipRectBeforeSetChannel() [Internal]
|
||||
// - GetColumnIndex()
|
||||
// - GetColumnCount()
|
||||
// - GetColumnOffset()
|
||||
@@ -7558,6 +7575,18 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
|
||||
// - Columns()
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// [Internal] Small optimization to avoid calls to PopClipRect/SetCurrentChannel/PushClipRect in sequences,
|
||||
// they would meddle many times with the underlying ImDrawCmd.
|
||||
// Instead, we do a preemptive overwrite of clipping rectangle _without_ altering the command-buffer and let
|
||||
// the subsequent single call to SetCurrentChannel() does it things once.
|
||||
void ImGui::SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect)
|
||||
{
|
||||
ImVec4 clip_rect_vec4 = clip_rect.ToVec4();
|
||||
window->ClipRect = clip_rect;
|
||||
window->DrawList->_CmdHeader.ClipRect = clip_rect_vec4;
|
||||
window->DrawList->_ClipRectStack.Data[window->DrawList->_ClipRectStack.Size - 1] = clip_rect_vec4;
|
||||
}
|
||||
|
||||
int ImGui::GetColumnIndex()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
@@ -7652,7 +7681,7 @@ void ImGui::SetColumnOffset(int column_index, float offset)
|
||||
column_index = columns->Current;
|
||||
IM_ASSERT(column_index < columns->Columns.Size);
|
||||
|
||||
const bool preserve_width = !(columns->Flags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < columns->Count-1);
|
||||
const bool preserve_width = !(columns->Flags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < columns->Count - 1);
|
||||
const float width = preserve_width ? GetColumnWidthEx(columns, column_index, columns->IsBeingResized) : 0.0f;
|
||||
|
||||
if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow))
|
||||
@@ -7692,11 +7721,11 @@ void ImGui::PushColumnsBackground()
|
||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||
if (columns->Count == 1)
|
||||
return;
|
||||
|
||||
// Optimization: avoid SetCurrentChannel() + PushClipRect()
|
||||
columns->HostBackupClipRect = window->ClipRect;
|
||||
SetWindowClipRectBeforeSetChannel(window, columns->HostInitialClipRect);
|
||||
columns->Splitter.SetCurrentChannel(window->DrawList, 0);
|
||||
int cmd_size = window->DrawList->CmdBuffer.Size;
|
||||
PushClipRect(columns->HostClipRect.Min, columns->HostClipRect.Max, false);
|
||||
IM_UNUSED(cmd_size);
|
||||
IM_ASSERT(cmd_size == window->DrawList->CmdBuffer.Size); // Being in channel 0 this should not have created an ImDrawCmd
|
||||
}
|
||||
|
||||
void ImGui::PopColumnsBackground()
|
||||
@@ -7705,8 +7734,10 @@ void ImGui::PopColumnsBackground()
|
||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||
if (columns->Count == 1)
|
||||
return;
|
||||
|
||||
// Optimization: avoid PopClipRect() + SetCurrentChannel()
|
||||
SetWindowClipRectBeforeSetChannel(window, columns->HostBackupClipRect);
|
||||
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
|
||||
PopClipRect();
|
||||
}
|
||||
|
||||
ImGuiColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id)
|
||||
@@ -7754,7 +7785,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
|
||||
|
||||
columns->HostCursorPosY = window->DC.CursorPos.y;
|
||||
columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x;
|
||||
columns->HostClipRect = window->ClipRect;
|
||||
columns->HostInitialClipRect = window->ClipRect;
|
||||
columns->HostWorkRect = window->WorkRect;
|
||||
|
||||
// Set state for first column
|
||||
@@ -7826,25 +7857,31 @@ void ImGui::NextColumn()
|
||||
IM_ASSERT(columns->Current == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Next column
|
||||
if (++columns->Current == columns->Count)
|
||||
columns->Current = 0;
|
||||
|
||||
PopItemWidth();
|
||||
PopClipRect();
|
||||
|
||||
// Optimization: avoid PopClipRect() + SetCurrentChannel() + PushClipRect()
|
||||
// (which would needlessly attempt to update commands in the wrong channel, then pop or overwrite them),
|
||||
ImGuiColumnData* column = &columns->Columns[columns->Current];
|
||||
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
|
||||
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
|
||||
|
||||
const float column_padding = g.Style.ItemSpacing.x;
|
||||
columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y);
|
||||
if (++columns->Current < columns->Count)
|
||||
if (columns->Current > 0)
|
||||
{
|
||||
// Columns 1+ ignore IndentX (by canceling it out)
|
||||
// FIXME-COLUMNS: Unnecessary, could be locked?
|
||||
window->DC.ColumnsOffset.x = GetColumnOffset(columns->Current) - window->DC.Indent.x + column_padding;
|
||||
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// New row/line
|
||||
// Column 0 honor IndentX
|
||||
// New row/line: column 0 honor IndentX.
|
||||
window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f);
|
||||
columns->Splitter.SetCurrentChannel(window->DrawList, 1);
|
||||
columns->Current = 0;
|
||||
columns->LineMinY = columns->LineMaxY;
|
||||
}
|
||||
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
@@ -7852,8 +7889,6 @@ void ImGui::NextColumn()
|
||||
window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
|
||||
window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||
|
||||
PushColumnClipRect(columns->Current); // FIXME-COLUMNS: Could it be an overwrite?
|
||||
|
||||
// FIXME-COLUMNS: Share code with BeginColumns() - move code on columns setup.
|
||||
float offset_0 = GetColumnOffset(columns->Current);
|
||||
float offset_1 = GetColumnOffset(columns->Current + 1);
|
||||
|
||||
Reference in New Issue
Block a user