mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-14 00:39:55 +02:00
Merge branch 'master' into docking
# Conflicts: # examples/imgui_impl_dx10.cpp # examples/imgui_impl_dx10.h # examples/imgui_impl_dx11.cpp # examples/imgui_impl_dx11.h # examples/imgui_impl_dx9.cpp # examples/imgui_impl_dx9.h # examples/imgui_impl_glfw.cpp # examples/imgui_impl_opengl2.cpp # examples/imgui_impl_opengl2.h # examples/imgui_impl_opengl3.cpp # examples/imgui_impl_opengl3.h # imgui.cpp
This commit is contained in:
@ -487,7 +487,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
{
|
||||
hovered = true;
|
||||
SetHoveredID(id);
|
||||
if (CalcTypematicPressedRepeatAmount(g.HoveredIdTimer + 0.0001f, g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, 0.01f, 0.70f)) // FIXME: Our formula for CalcTypematicPressedRepeatAmount() is fishy
|
||||
if (CalcTypematicRepeatAmount(g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, g.HoveredIdTimer + 0.0001f, 0.70f, 0.00f))
|
||||
{
|
||||
pressed = true;
|
||||
FocusWindow(window);
|
||||
@ -761,7 +761,7 @@ bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos, ImGuiDockNode* dock_no
|
||||
|
||||
// Render
|
||||
//bool is_dock_menu = (window->DockNodeAsHost && !window->Collapsed);
|
||||
ImVec2 off = dock_node ? ImVec2((float)(int)(-g.Style.ItemInnerSpacing.x * 0.5f) + 0.5f, 0.0f) : ImVec2(0.0f, 0.0f);
|
||||
ImVec2 off = dock_node ? ImVec2(IM_FLOOR(-g.Style.ItemInnerSpacing.x * 0.5f) + 0.5f, 0.0f) : ImVec2(0.0f, 0.0f);
|
||||
ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
||||
ImU32 text_col = GetColorU32(ImGuiCol_Text);
|
||||
ImVec2 center = bb.GetCenter();
|
||||
@ -815,7 +815,7 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa
|
||||
const bool horizontal = (axis == ImGuiAxis_X);
|
||||
|
||||
ImRect bb = bb_frame;
|
||||
bb.Expand(ImVec2(-ImClamp((float)(int)((bb_frame_width - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp((float)(int)((bb_frame_height - 2.0f) * 0.5f), 0.0f, 3.0f)));
|
||||
bb.Expand(ImVec2(-ImClamp(IM_FLOOR((bb_frame_width - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp(IM_FLOOR((bb_frame_height - 2.0f) * 0.5f), 0.0f, 3.0f)));
|
||||
|
||||
// V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar)
|
||||
const float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight();
|
||||
@ -858,7 +858,7 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa
|
||||
// Apply scroll
|
||||
// It is ok to modify Scroll here because we are being called in Begin() after the calculation of ContentSize and before setting up our starting position
|
||||
const float scroll_v_norm = ImSaturate((clicked_v_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm * 0.5f) / (1.0f - grab_h_norm));
|
||||
*p_scroll_v = (float)(int)(0.5f + scroll_v_norm * scroll_max);//(win_size_contents_v - win_size_v));
|
||||
*p_scroll_v = IM_FLOOR(0.5f + scroll_v_norm * scroll_max);//(win_size_contents_v - win_size_v));
|
||||
|
||||
// Update values for rendering
|
||||
scroll_ratio = ImSaturate(*p_scroll_v / scroll_max);
|
||||
@ -1011,12 +1011,12 @@ bool ImGui::Checkbox(const char* label, bool* v)
|
||||
if (window->DC.ItemFlags & ImGuiItemFlags_MixedValue)
|
||||
{
|
||||
// Undocumented tristate/mixed/indeterminate checkbox (#2644)
|
||||
ImVec2 pad(ImMax(1.0f, (float)(int)(square_sz / 3.6f)), ImMax(1.0f, (float)(int)(square_sz / 3.6f)));
|
||||
ImVec2 pad(ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)), ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)));
|
||||
window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding);
|
||||
}
|
||||
else if (*v)
|
||||
{
|
||||
const float pad = ImMax(1.0f, (float)(int)(square_sz / 6.0f));
|
||||
const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f));
|
||||
RenderCheckMark(check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad*2.0f);
|
||||
}
|
||||
|
||||
@ -1064,8 +1064,8 @@ bool ImGui::RadioButton(const char* label, bool active)
|
||||
return false;
|
||||
|
||||
ImVec2 center = check_bb.GetCenter();
|
||||
center.x = (float)(int)center.x + 0.5f;
|
||||
center.y = (float)(int)center.y + 0.5f;
|
||||
center.x = IM_FLOOR(center.x + 0.5f);
|
||||
center.y = IM_FLOOR(center.y + 0.5f);
|
||||
const float radius = (square_sz - 1.0f) * 0.5f;
|
||||
|
||||
bool hovered, held;
|
||||
@ -1077,7 +1077,7 @@ bool ImGui::RadioButton(const char* label, bool active)
|
||||
window->DrawList->AddCircleFilled(center, radius, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), 16);
|
||||
if (active)
|
||||
{
|
||||
const float pad = ImMax(1.0f, (float)(int)(square_sz / 6.0f));
|
||||
const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f));
|
||||
window->DrawList->AddCircleFilled(center, radius - pad, GetColorU32(ImGuiCol_CheckMark), 16);
|
||||
}
|
||||
|
||||
@ -1687,25 +1687,25 @@ const ImGuiDataTypeInfo* ImGui::DataTypeGetInfo(ImGuiDataType data_type)
|
||||
return &GDataTypeInfo[data_type];
|
||||
}
|
||||
|
||||
int ImGui::DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format)
|
||||
int ImGui::DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* p_data, const char* format)
|
||||
{
|
||||
// Signedness doesn't matter when pushing integer arguments
|
||||
if (data_type == ImGuiDataType_S32 || data_type == ImGuiDataType_U32)
|
||||
return ImFormatString(buf, buf_size, format, *(const ImU32*)data_ptr);
|
||||
return ImFormatString(buf, buf_size, format, *(const ImU32*)p_data);
|
||||
if (data_type == ImGuiDataType_S64 || data_type == ImGuiDataType_U64)
|
||||
return ImFormatString(buf, buf_size, format, *(const ImU64*)data_ptr);
|
||||
return ImFormatString(buf, buf_size, format, *(const ImU64*)p_data);
|
||||
if (data_type == ImGuiDataType_Float)
|
||||
return ImFormatString(buf, buf_size, format, *(const float*)data_ptr);
|
||||
return ImFormatString(buf, buf_size, format, *(const float*)p_data);
|
||||
if (data_type == ImGuiDataType_Double)
|
||||
return ImFormatString(buf, buf_size, format, *(const double*)data_ptr);
|
||||
return ImFormatString(buf, buf_size, format, *(const double*)p_data);
|
||||
if (data_type == ImGuiDataType_S8)
|
||||
return ImFormatString(buf, buf_size, format, *(const ImS8*)data_ptr);
|
||||
return ImFormatString(buf, buf_size, format, *(const ImS8*)p_data);
|
||||
if (data_type == ImGuiDataType_U8)
|
||||
return ImFormatString(buf, buf_size, format, *(const ImU8*)data_ptr);
|
||||
return ImFormatString(buf, buf_size, format, *(const ImU8*)p_data);
|
||||
if (data_type == ImGuiDataType_S16)
|
||||
return ImFormatString(buf, buf_size, format, *(const ImS16*)data_ptr);
|
||||
return ImFormatString(buf, buf_size, format, *(const ImS16*)p_data);
|
||||
if (data_type == ImGuiDataType_U16)
|
||||
return ImFormatString(buf, buf_size, format, *(const ImU16*)data_ptr);
|
||||
return ImFormatString(buf, buf_size, format, *(const ImU16*)p_data);
|
||||
IM_ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
@ -1762,7 +1762,7 @@ void ImGui::DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void*
|
||||
|
||||
// User can input math operators (e.g. +100) to edit a numerical values.
|
||||
// NB: This is _not_ a full expression evaluator. We should probably add one and replace this dumb mess..
|
||||
bool ImGui::DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* format)
|
||||
bool ImGui::DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* p_data, const char* format)
|
||||
{
|
||||
while (ImCharIsBlankA(*buf))
|
||||
buf++;
|
||||
@ -1788,7 +1788,7 @@ bool ImGui::DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
|
||||
int data_backup[2];
|
||||
const ImGuiDataTypeInfo* type_info = ImGui::DataTypeGetInfo(data_type);
|
||||
IM_ASSERT(type_info->Size <= sizeof(data_backup));
|
||||
memcpy(data_backup, data_ptr, type_info->Size);
|
||||
memcpy(data_backup, p_data, type_info->Size);
|
||||
|
||||
if (format == NULL)
|
||||
format = type_info->ScanFmt;
|
||||
@ -1797,7 +1797,7 @@ bool ImGui::DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
|
||||
int arg1i = 0;
|
||||
if (data_type == ImGuiDataType_S32)
|
||||
{
|
||||
int* v = (int*)data_ptr;
|
||||
int* v = (int*)p_data;
|
||||
int arg0i = *v;
|
||||
float arg1f = 0.0f;
|
||||
if (op && sscanf(initial_value_buf, format, &arg0i) < 1)
|
||||
@ -1812,7 +1812,7 @@ bool ImGui::DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
|
||||
{
|
||||
// For floats we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in
|
||||
format = "%f";
|
||||
float* v = (float*)data_ptr;
|
||||
float* v = (float*)p_data;
|
||||
float arg0f = *v, arg1f = 0.0f;
|
||||
if (op && sscanf(initial_value_buf, format, &arg0f) < 1)
|
||||
return false;
|
||||
@ -1826,7 +1826,7 @@ bool ImGui::DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
|
||||
else if (data_type == ImGuiDataType_Double)
|
||||
{
|
||||
format = "%lf"; // scanf differentiate float/double unlike printf which forces everything to double because of ellipsis
|
||||
double* v = (double*)data_ptr;
|
||||
double* v = (double*)p_data;
|
||||
double arg0f = *v, arg1f = 0.0;
|
||||
if (op && sscanf(initial_value_buf, format, &arg0f) < 1)
|
||||
return false;
|
||||
@ -1841,7 +1841,7 @@ bool ImGui::DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
|
||||
{
|
||||
// All other types assign constant
|
||||
// We don't bother handling support for legacy operators since they are a little too crappy. Instead we will later implement a proper expression evaluator in the future.
|
||||
sscanf(buf, format, data_ptr);
|
||||
sscanf(buf, format, p_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1849,18 +1849,18 @@ bool ImGui::DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
|
||||
int v32;
|
||||
sscanf(buf, format, &v32);
|
||||
if (data_type == ImGuiDataType_S8)
|
||||
*(ImS8*)data_ptr = (ImS8)ImClamp(v32, (int)IM_S8_MIN, (int)IM_S8_MAX);
|
||||
*(ImS8*)p_data = (ImS8)ImClamp(v32, (int)IM_S8_MIN, (int)IM_S8_MAX);
|
||||
else if (data_type == ImGuiDataType_U8)
|
||||
*(ImU8*)data_ptr = (ImU8)ImClamp(v32, (int)IM_U8_MIN, (int)IM_U8_MAX);
|
||||
*(ImU8*)p_data = (ImU8)ImClamp(v32, (int)IM_U8_MIN, (int)IM_U8_MAX);
|
||||
else if (data_type == ImGuiDataType_S16)
|
||||
*(ImS16*)data_ptr = (ImS16)ImClamp(v32, (int)IM_S16_MIN, (int)IM_S16_MAX);
|
||||
*(ImS16*)p_data = (ImS16)ImClamp(v32, (int)IM_S16_MIN, (int)IM_S16_MAX);
|
||||
else if (data_type == ImGuiDataType_U16)
|
||||
*(ImU16*)data_ptr = (ImU16)ImClamp(v32, (int)IM_U16_MIN, (int)IM_U16_MAX);
|
||||
*(ImU16*)p_data = (ImU16)ImClamp(v32, (int)IM_U16_MIN, (int)IM_U16_MAX);
|
||||
else
|
||||
IM_ASSERT(0);
|
||||
}
|
||||
|
||||
return memcmp(data_backup, data_ptr, type_info->Size) != 0;
|
||||
return memcmp(data_backup, p_data, type_info->Size) != 0;
|
||||
}
|
||||
|
||||
static float GetMinimumStepAtDecimalPrecision(int decimal_precision)
|
||||
@ -2030,7 +2030,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* v, float v_speed, const void* v_min, const void* v_max, const char* format, float power, ImGuiDragFlags flags)
|
||||
bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v_speed, const void* p_min, const void* p_max, const char* format, float power, ImGuiDragFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.ActiveId == id)
|
||||
@ -2045,30 +2045,32 @@ bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* v, float v_s
|
||||
|
||||
switch (data_type)
|
||||
{
|
||||
case ImGuiDataType_S8: { ImS32 v32 = (ImS32)*(ImS8*)v; bool r = DragBehaviorT<ImS32, ImS32, float >(ImGuiDataType_S32, &v32, v_speed, v_min ? *(const ImS8*) v_min : IM_S8_MIN, v_max ? *(const ImS8*)v_max : IM_S8_MAX, format, power, flags); if (r) *(ImS8*)v = (ImS8)v32; return r; }
|
||||
case ImGuiDataType_U8: { ImU32 v32 = (ImU32)*(ImU8*)v; bool r = DragBehaviorT<ImU32, ImS32, float >(ImGuiDataType_U32, &v32, v_speed, v_min ? *(const ImU8*) v_min : IM_U8_MIN, v_max ? *(const ImU8*)v_max : IM_U8_MAX, format, power, flags); if (r) *(ImU8*)v = (ImU8)v32; return r; }
|
||||
case ImGuiDataType_S16: { ImS32 v32 = (ImS32)*(ImS16*)v; bool r = DragBehaviorT<ImS32, ImS32, float >(ImGuiDataType_S32, &v32, v_speed, v_min ? *(const ImS16*)v_min : IM_S16_MIN, v_max ? *(const ImS16*)v_max : IM_S16_MAX, format, power, flags); if (r) *(ImS16*)v = (ImS16)v32; return r; }
|
||||
case ImGuiDataType_U16: { ImU32 v32 = (ImU32)*(ImU16*)v; bool r = DragBehaviorT<ImU32, ImS32, float >(ImGuiDataType_U32, &v32, v_speed, v_min ? *(const ImU16*)v_min : IM_U16_MIN, v_max ? *(const ImU16*)v_max : IM_U16_MAX, format, power, flags); if (r) *(ImU16*)v = (ImU16)v32; return r; }
|
||||
case ImGuiDataType_S32: return DragBehaviorT<ImS32, ImS32, float >(data_type, (ImS32*)v, v_speed, v_min ? *(const ImS32* )v_min : IM_S32_MIN, v_max ? *(const ImS32* )v_max : IM_S32_MAX, format, power, flags);
|
||||
case ImGuiDataType_U32: return DragBehaviorT<ImU32, ImS32, float >(data_type, (ImU32*)v, v_speed, v_min ? *(const ImU32* )v_min : IM_U32_MIN, v_max ? *(const ImU32* )v_max : IM_U32_MAX, format, power, flags);
|
||||
case ImGuiDataType_S64: return DragBehaviorT<ImS64, ImS64, double>(data_type, (ImS64*)v, v_speed, v_min ? *(const ImS64* )v_min : IM_S64_MIN, v_max ? *(const ImS64* )v_max : IM_S64_MAX, format, power, flags);
|
||||
case ImGuiDataType_U64: return DragBehaviorT<ImU64, ImS64, double>(data_type, (ImU64*)v, v_speed, v_min ? *(const ImU64* )v_min : IM_U64_MIN, v_max ? *(const ImU64* )v_max : IM_U64_MAX, format, power, flags);
|
||||
case ImGuiDataType_Float: return DragBehaviorT<float, float, float >(data_type, (float*)v, v_speed, v_min ? *(const float* )v_min : -FLT_MAX, v_max ? *(const float* )v_max : FLT_MAX, format, power, flags);
|
||||
case ImGuiDataType_Double: return DragBehaviorT<double,double,double>(data_type, (double*)v, v_speed, v_min ? *(const double*)v_min : -DBL_MAX, v_max ? *(const double*)v_max : DBL_MAX, format, power, flags);
|
||||
case ImGuiDataType_S8: { ImS32 v32 = (ImS32)*(ImS8*)p_v; bool r = DragBehaviorT<ImS32, ImS32, float>(ImGuiDataType_S32, &v32, v_speed, p_min ? *(const ImS8*) p_min : IM_S8_MIN, p_max ? *(const ImS8*)p_max : IM_S8_MAX, format, power, flags); if (r) *(ImS8*)p_v = (ImS8)v32; return r; }
|
||||
case ImGuiDataType_U8: { ImU32 v32 = (ImU32)*(ImU8*)p_v; bool r = DragBehaviorT<ImU32, ImS32, float>(ImGuiDataType_U32, &v32, v_speed, p_min ? *(const ImU8*) p_min : IM_U8_MIN, p_max ? *(const ImU8*)p_max : IM_U8_MAX, format, power, flags); if (r) *(ImU8*)p_v = (ImU8)v32; return r; }
|
||||
case ImGuiDataType_S16: { ImS32 v32 = (ImS32)*(ImS16*)p_v; bool r = DragBehaviorT<ImS32, ImS32, float>(ImGuiDataType_S32, &v32, v_speed, p_min ? *(const ImS16*)p_min : IM_S16_MIN, p_max ? *(const ImS16*)p_max : IM_S16_MAX, format, power, flags); if (r) *(ImS16*)p_v = (ImS16)v32; return r; }
|
||||
case ImGuiDataType_U16: { ImU32 v32 = (ImU32)*(ImU16*)p_v; bool r = DragBehaviorT<ImU32, ImS32, float>(ImGuiDataType_U32, &v32, v_speed, p_min ? *(const ImU16*)p_min : IM_U16_MIN, p_max ? *(const ImU16*)p_max : IM_U16_MAX, format, power, flags); if (r) *(ImU16*)p_v = (ImU16)v32; return r; }
|
||||
case ImGuiDataType_S32: return DragBehaviorT<ImS32, ImS32, float >(data_type, (ImS32*)p_v, v_speed, p_min ? *(const ImS32* )p_min : IM_S32_MIN, p_max ? *(const ImS32* )p_max : IM_S32_MAX, format, power, flags);
|
||||
case ImGuiDataType_U32: return DragBehaviorT<ImU32, ImS32, float >(data_type, (ImU32*)p_v, v_speed, p_min ? *(const ImU32* )p_min : IM_U32_MIN, p_max ? *(const ImU32* )p_max : IM_U32_MAX, format, power, flags);
|
||||
case ImGuiDataType_S64: return DragBehaviorT<ImS64, ImS64, double>(data_type, (ImS64*)p_v, v_speed, p_min ? *(const ImS64* )p_min : IM_S64_MIN, p_max ? *(const ImS64* )p_max : IM_S64_MAX, format, power, flags);
|
||||
case ImGuiDataType_U64: return DragBehaviorT<ImU64, ImS64, double>(data_type, (ImU64*)p_v, v_speed, p_min ? *(const ImU64* )p_min : IM_U64_MIN, p_max ? *(const ImU64* )p_max : IM_U64_MAX, format, power, flags);
|
||||
case ImGuiDataType_Float: return DragBehaviorT<float, float, float >(data_type, (float*)p_v, v_speed, p_min ? *(const float* )p_min : -FLT_MAX, p_max ? *(const float* )p_max : FLT_MAX, format, power, flags);
|
||||
case ImGuiDataType_Double: return DragBehaviorT<double,double,double>(data_type, (double*)p_v, v_speed, p_min ? *(const double*)p_min : -DBL_MAX, p_max ? *(const double*)p_max : DBL_MAX, format, power, flags);
|
||||
case ImGuiDataType_COUNT: break;
|
||||
}
|
||||
IM_ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* v, float v_speed, const void* v_min, const void* v_max, const char* format, float power)
|
||||
// Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a Drag widget, p_min and p_max are optional.
|
||||
// Read code of e.g. SliderFloat(), SliderInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
|
||||
bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, const char* format, float power)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
if (power != 1.0f)
|
||||
IM_ASSERT(v_min != NULL && v_max != NULL); // When using a power curve the drag needs to have known bounds
|
||||
IM_ASSERT(p_min != NULL && p_max != NULL); // When using a power curve the drag needs to have known bounds
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
@ -2111,7 +2113,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* v, floa
|
||||
}
|
||||
}
|
||||
if (temp_input_is_active || temp_input_start)
|
||||
return TempInputTextScalar(frame_bb, id, label, data_type, v, format);
|
||||
return TempInputTextScalar(frame_bb, id, label, data_type, p_data, format);
|
||||
|
||||
// Draw frame
|
||||
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
||||
@ -2119,13 +2121,13 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* v, floa
|
||||
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding);
|
||||
|
||||
// Drag behavior
|
||||
const bool value_changed = DragBehavior(id, data_type, v, v_speed, v_min, v_max, format, power, ImGuiDragFlags_None);
|
||||
const bool value_changed = DragBehavior(id, data_type, p_data, v_speed, p_min, p_max, format, power, ImGuiDragFlags_None);
|
||||
if (value_changed)
|
||||
MarkItemEdited(id);
|
||||
|
||||
// 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, v, format);
|
||||
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));
|
||||
|
||||
if (label_size.x > 0.0f)
|
||||
@ -2135,7 +2137,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* v, floa
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
bool ImGui::DragScalarN(const char* label, ImGuiDataType data_type, void* v, int components, float v_speed, const void* v_min, const void* v_max, const char* format, float power)
|
||||
bool ImGui::DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min, const void* p_max, const char* format, float power)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
@ -2152,10 +2154,10 @@ bool ImGui::DragScalarN(const char* label, ImGuiDataType data_type, void* v, int
|
||||
PushID(i);
|
||||
if (i > 0)
|
||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
value_changed |= DragScalar("", data_type, v, v_speed, v_min, v_max, format, power);
|
||||
value_changed |= DragScalar("", data_type, p_data, v_speed, p_min, p_max, format, power);
|
||||
PopID();
|
||||
PopItemWidth();
|
||||
v = (void*)((char*)v + type_size);
|
||||
p_data = (void*)((char*)p_data + type_size);
|
||||
}
|
||||
PopID();
|
||||
|
||||
@ -2481,39 +2483,41 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
||||
// For 32-bits and larger types, slider bounds are limited to half the natural type range.
|
||||
// So e.g. an integer Slider between INT_MAX-10 and INT_MAX will fail, but an integer Slider between INT_MAX/2-10 and INT_MAX/2 will be ok.
|
||||
// It would be possible to lift that limitation with some work but it doesn't seem to be worth it for sliders.
|
||||
bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format, float power, ImGuiSliderFlags flags, ImRect* out_grab_bb)
|
||||
bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* p_v, const void* p_min, const void* p_max, const char* format, float power, ImGuiSliderFlags flags, ImRect* out_grab_bb)
|
||||
{
|
||||
switch (data_type)
|
||||
{
|
||||
case ImGuiDataType_S8: { ImS32 v32 = (ImS32)*(ImS8*)v; bool r = SliderBehaviorT<ImS32, ImS32, float >(bb, id, ImGuiDataType_S32, &v32, *(const ImS8*)v_min, *(const ImS8*)v_max, format, power, flags, out_grab_bb); if (r) *(ImS8*)v = (ImS8)v32; return r; }
|
||||
case ImGuiDataType_U8: { ImU32 v32 = (ImU32)*(ImU8*)v; bool r = SliderBehaviorT<ImU32, ImS32, float >(bb, id, ImGuiDataType_U32, &v32, *(const ImU8*)v_min, *(const ImU8*)v_max, format, power, flags, out_grab_bb); if (r) *(ImU8*)v = (ImU8)v32; return r; }
|
||||
case ImGuiDataType_S16: { ImS32 v32 = (ImS32)*(ImS16*)v; bool r = SliderBehaviorT<ImS32, ImS32, float >(bb, id, ImGuiDataType_S32, &v32, *(const ImS16*)v_min, *(const ImS16*)v_max, format, power, flags, out_grab_bb); if (r) *(ImS16*)v = (ImS16)v32; return r; }
|
||||
case ImGuiDataType_U16: { ImU32 v32 = (ImU32)*(ImU16*)v; bool r = SliderBehaviorT<ImU32, ImS32, float >(bb, id, ImGuiDataType_U32, &v32, *(const ImU16*)v_min, *(const ImU16*)v_max, format, power, flags, out_grab_bb); if (r) *(ImU16*)v = (ImU16)v32; return r; }
|
||||
case ImGuiDataType_S8: { ImS32 v32 = (ImS32)*(ImS8*)p_v; bool r = SliderBehaviorT<ImS32, ImS32, float>(bb, id, ImGuiDataType_S32, &v32, *(const ImS8*)p_min, *(const ImS8*)p_max, format, power, flags, out_grab_bb); if (r) *(ImS8*)p_v = (ImS8)v32; return r; }
|
||||
case ImGuiDataType_U8: { ImU32 v32 = (ImU32)*(ImU8*)p_v; bool r = SliderBehaviorT<ImU32, ImS32, float>(bb, id, ImGuiDataType_U32, &v32, *(const ImU8*)p_min, *(const ImU8*)p_max, format, power, flags, out_grab_bb); if (r) *(ImU8*)p_v = (ImU8)v32; return r; }
|
||||
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*)v_min >= IM_S32_MIN/2 && *(const ImS32*)v_max <= IM_S32_MAX/2);
|
||||
return SliderBehaviorT<ImS32, ImS32, float >(bb, id, data_type, (ImS32*)v, *(const ImS32*)v_min, *(const ImS32*)v_max, format, power, flags, out_grab_bb);
|
||||
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*)v_max <= IM_U32_MAX/2);
|
||||
return SliderBehaviorT<ImU32, ImS32, float >(bb, id, data_type, (ImU32*)v, *(const ImU32*)v_min, *(const ImU32*)v_max, format, power, flags, out_grab_bb);
|
||||
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*)v_min >= IM_S64_MIN/2 && *(const ImS64*)v_max <= IM_S64_MAX/2);
|
||||
return SliderBehaviorT<ImS64, ImS64, double>(bb, id, data_type, (ImS64*)v, *(const ImS64*)v_min, *(const ImS64*)v_max, format, power, flags, out_grab_bb);
|
||||
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*)v_max <= IM_U64_MAX/2);
|
||||
return SliderBehaviorT<ImU64, ImS64, double>(bb, id, data_type, (ImU64*)v, *(const ImU64*)v_min, *(const ImU64*)v_max, format, power, flags, out_grab_bb);
|
||||
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*)v_min >= -FLT_MAX/2.0f && *(const float*)v_max <= FLT_MAX/2.0f);
|
||||
return SliderBehaviorT<float, float, float >(bb, id, data_type, (float*)v, *(const float*)v_min, *(const float*)v_max, format, power, flags, out_grab_bb);
|
||||
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*)v_min >= -DBL_MAX/2.0f && *(const double*)v_max <= DBL_MAX/2.0f);
|
||||
return SliderBehaviorT<double,double,double>(bb, id, data_type, (double*)v, *(const double*)v_min, *(const double*)v_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);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format, float power)
|
||||
// Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a slider, they are all required.
|
||||
// Read code of e.g. SliderFloat(), SliderInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
|
||||
bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, float power)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
@ -2560,7 +2564,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* v, co
|
||||
}
|
||||
}
|
||||
if (temp_input_is_active || temp_input_start)
|
||||
return TempInputTextScalar(frame_bb, id, label, data_type, v, format);
|
||||
return TempInputTextScalar(frame_bb, id, label, data_type, p_data, format);
|
||||
|
||||
// Draw frame
|
||||
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
||||
@ -2569,7 +2573,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* v, co
|
||||
|
||||
// Slider behavior
|
||||
ImRect grab_bb;
|
||||
const bool value_changed = SliderBehavior(frame_bb, id, data_type, v, v_min, v_max, format, power, ImGuiSliderFlags_None, &grab_bb);
|
||||
const bool value_changed = SliderBehavior(frame_bb, id, data_type, p_data, p_min, p_max, format, power, ImGuiSliderFlags_None, &grab_bb);
|
||||
if (value_changed)
|
||||
MarkItemEdited(id);
|
||||
|
||||
@ -2579,7 +2583,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* v, co
|
||||
|
||||
// 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, v, format);
|
||||
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));
|
||||
|
||||
if (label_size.x > 0.0f)
|
||||
@ -2675,7 +2679,7 @@ bool ImGui::SliderInt4(const char* label, int v[4], int v_min, int v_max, const
|
||||
return SliderScalarN(label, ImGuiDataType_S32, v, 4, &v_min, &v_max, format);
|
||||
}
|
||||
|
||||
bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format, float power)
|
||||
bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, float power)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
@ -2715,7 +2719,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
|
||||
|
||||
// Slider behavior
|
||||
ImRect grab_bb;
|
||||
const bool value_changed = SliderBehavior(frame_bb, id, data_type, v, v_min, v_max, format, power, ImGuiSliderFlags_Vertical, &grab_bb);
|
||||
const bool value_changed = SliderBehavior(frame_bb, id, data_type, p_data, p_min, p_max, format, power, ImGuiSliderFlags_Vertical, &grab_bb);
|
||||
if (value_changed)
|
||||
MarkItemEdited(id);
|
||||
|
||||
@ -2726,7 +2730,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
|
||||
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
||||
// 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, v, format);
|
||||
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));
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||
@ -2839,7 +2843,7 @@ int ImParseFormatPrecision(const char* fmt, int default_precision)
|
||||
|
||||
// Create text input in place of another active widget (e.g. used when doing a CTRL+Click on drag/slider widgets)
|
||||
// FIXME: Facilitate using this in variety of other situations.
|
||||
bool ImGui::TempInputTextScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format)
|
||||
bool ImGui::TempInputTextScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
@ -2852,7 +2856,7 @@ bool ImGui::TempInputTextScalar(const ImRect& bb, ImGuiID id, const char* label,
|
||||
char fmt_buf[32];
|
||||
char data_buf[32];
|
||||
format = ImParseFormatTrimDecorations(format, fmt_buf, IM_ARRAYSIZE(fmt_buf));
|
||||
DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, data_ptr, format);
|
||||
DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, p_data, format);
|
||||
ImStrTrimBlanks(data_buf);
|
||||
|
||||
g.CurrentWindow->DC.CursorPos = bb.Min;
|
||||
@ -2867,14 +2871,16 @@ bool ImGui::TempInputTextScalar(const ImRect& bb, ImGuiID id, const char* label,
|
||||
}
|
||||
if (value_changed)
|
||||
{
|
||||
value_changed = DataTypeApplyOpFromText(data_buf, g.InputTextState.InitialTextA.Data, data_type, data_ptr, NULL);
|
||||
value_changed = DataTypeApplyOpFromText(data_buf, g.InputTextState.InitialTextA.Data, data_type, p_data, NULL);
|
||||
if (value_changed)
|
||||
MarkItemEdited(id);
|
||||
}
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* data_ptr, const void* step, const void* step_fast, const char* format, ImGuiInputTextFlags flags)
|
||||
// Note: p_data, p_step, p_step_fast are _pointers_ to a memory address holding the data. For an Input widget, p_step and p_step_fast are optional.
|
||||
// Read code of e.g. InputFloat(), InputInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
|
||||
bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
@ -2887,7 +2893,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* data_p
|
||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||
|
||||
char buf[64];
|
||||
DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, data_ptr, format);
|
||||
DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format);
|
||||
|
||||
bool value_changed = false;
|
||||
if ((flags & (ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsScientific)) == 0)
|
||||
@ -2895,7 +2901,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* data_p
|
||||
flags |= ImGuiInputTextFlags_AutoSelectAll;
|
||||
flags |= ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ourselve by comparing the actual data rather than the string.
|
||||
|
||||
if (step != NULL)
|
||||
if (p_step != NULL)
|
||||
{
|
||||
const float button_size = GetFrameHeight();
|
||||
|
||||
@ -2903,7 +2909,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* data_p
|
||||
PushID(label);
|
||||
SetNextItemWidth(ImMax(1.0f, CalcItemWidth() - (button_size + style.ItemInnerSpacing.x) * 2));
|
||||
if (InputText("", buf, IM_ARRAYSIZE(buf), flags)) // PushId(label) + "" gives us the expected ID from outside point of view
|
||||
value_changed = DataTypeApplyOpFromText(buf, g.InputTextState.InitialTextA.Data, data_type, data_ptr, format);
|
||||
value_changed = DataTypeApplyOpFromText(buf, g.InputTextState.InitialTextA.Data, data_type, p_data, format);
|
||||
|
||||
// Step buttons
|
||||
const ImVec2 backup_frame_padding = style.FramePadding;
|
||||
@ -2914,13 +2920,13 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* data_p
|
||||
SameLine(0, style.ItemInnerSpacing.x);
|
||||
if (ButtonEx("-", ImVec2(button_size, button_size), button_flags))
|
||||
{
|
||||
DataTypeApplyOp(data_type, '-', data_ptr, data_ptr, g.IO.KeyCtrl && step_fast ? step_fast : step);
|
||||
DataTypeApplyOp(data_type, '-', p_data, p_data, g.IO.KeyCtrl && p_step_fast ? p_step_fast : p_step);
|
||||
value_changed = true;
|
||||
}
|
||||
SameLine(0, style.ItemInnerSpacing.x);
|
||||
if (ButtonEx("+", ImVec2(button_size, button_size), button_flags))
|
||||
{
|
||||
DataTypeApplyOp(data_type, '+', data_ptr, data_ptr, g.IO.KeyCtrl && step_fast ? step_fast : step);
|
||||
DataTypeApplyOp(data_type, '+', p_data, p_data, g.IO.KeyCtrl && p_step_fast ? p_step_fast : p_step);
|
||||
value_changed = true;
|
||||
}
|
||||
|
||||
@ -2938,7 +2944,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* data_p
|
||||
else
|
||||
{
|
||||
if (InputText(label, buf, IM_ARRAYSIZE(buf), flags))
|
||||
value_changed = DataTypeApplyOpFromText(buf, g.InputTextState.InitialTextA.Data, data_type, data_ptr, format);
|
||||
value_changed = DataTypeApplyOpFromText(buf, g.InputTextState.InitialTextA.Data, data_type, p_data, format);
|
||||
}
|
||||
if (value_changed)
|
||||
MarkItemEdited(window->DC.LastItemId);
|
||||
@ -2946,7 +2952,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* data_p
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
bool ImGui::InputScalarN(const char* label, ImGuiDataType data_type, void* v, int components, const void* step, const void* step_fast, const char* format, ImGuiInputTextFlags flags)
|
||||
bool ImGui::InputScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
@ -2963,10 +2969,10 @@ bool ImGui::InputScalarN(const char* label, ImGuiDataType data_type, void* v, in
|
||||
PushID(i);
|
||||
if (i > 0)
|
||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
value_changed |= InputScalar("", data_type, v, step, step_fast, format, flags);
|
||||
value_changed |= InputScalar("", data_type, p_data, p_step, p_step_fast, format, flags);
|
||||
PopID();
|
||||
PopItemWidth();
|
||||
v = (void*)((char*)v + type_size);
|
||||
p_data = (void*)((char*)p_data + type_size);
|
||||
}
|
||||
PopID();
|
||||
|
||||
@ -3332,6 +3338,10 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
|
||||
return false;
|
||||
}
|
||||
|
||||
// We ignore Ascii representation of delete (emitted from Backspace on OSX, see #2578, #2817)
|
||||
if (c == 127)
|
||||
return false;
|
||||
|
||||
// Filter private Unicode range. GLFW on OSX seems to send private characters for special keys like arrow keys (FIXME)
|
||||
if (c >= 0xE000 && c <= 0xF8FF)
|
||||
return false;
|
||||
@ -3520,6 +3530,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
// Declare our inputs
|
||||
IM_ASSERT(ImGuiNavInput_COUNT < 32);
|
||||
g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
|
||||
if (is_multiline || (flags & ImGuiInputTextFlags_CallbackHistory))
|
||||
g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down);
|
||||
g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);
|
||||
@ -4018,9 +4029,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
const float scroll_increment_x = inner_size.x * 0.25f;
|
||||
if (cursor_offset.x < state->ScrollX)
|
||||
state->ScrollX = (float)(int)ImMax(0.0f, cursor_offset.x - scroll_increment_x);
|
||||
state->ScrollX = IM_FLOOR(ImMax(0.0f, cursor_offset.x - scroll_increment_x));
|
||||
else if (cursor_offset.x - inner_size.x >= state->ScrollX)
|
||||
state->ScrollX = (float)(int)(cursor_offset.x - inner_size.x + scroll_increment_x);
|
||||
state->ScrollX = IM_FLOOR(cursor_offset.x - inner_size.x + scroll_increment_x);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4068,7 +4079,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
else
|
||||
{
|
||||
ImVec2 rect_size = InputTextCalcTextSizeW(p, text_selected_end, &p, NULL, true);
|
||||
if (rect_size.x <= 0.0f) rect_size.x = (float)(int)(g.Font->GetCharAdvance((ImWchar)' ') * 0.50f); // So we can see selected empty lines
|
||||
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));
|
||||
rect.ClipWith(clip_rect);
|
||||
if (rect.Overlaps(clip_rect))
|
||||
@ -4238,8 +4249,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, (float)(int)((w_inputs - (style.ItemInnerSpacing.x) * (components-1)) / (float)components));
|
||||
const float w_item_last = ImMax(1.0f, (float)(int)(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" };
|
||||
@ -4514,7 +4525,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
float sv_picker_size = ImMax(bars_width * 1, width - (alpha_bar ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box
|
||||
float bar0_pos_x = picker_pos.x + sv_picker_size + style.ItemInnerSpacing.x;
|
||||
float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x;
|
||||
float bars_triangles_half_sz = (float)(int)(bars_width * 0.20f);
|
||||
float bars_triangles_half_sz = IM_FLOOR(bars_width * 0.20f);
|
||||
|
||||
float backup_initial_col[4];
|
||||
memcpy(backup_initial_col, col, components * sizeof(float));
|
||||
@ -4794,13 +4805,13 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size, sv_picker_size), col_white, hue_color32, hue_color32, col_white);
|
||||
draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size, sv_picker_size), 0, 0, col_black, col_black);
|
||||
RenderFrameBorder(picker_pos, picker_pos + ImVec2(sv_picker_size, sv_picker_size), 0.0f);
|
||||
sv_cursor_pos.x = ImClamp((float)(int)(picker_pos.x + ImSaturate(S) * sv_picker_size + 0.5f), picker_pos.x + 2, picker_pos.x + sv_picker_size - 2); // Sneakily prevent the circle to stick out too much
|
||||
sv_cursor_pos.y = ImClamp((float)(int)(picker_pos.y + ImSaturate(1 - V) * sv_picker_size + 0.5f), picker_pos.y + 2, picker_pos.y + sv_picker_size - 2);
|
||||
sv_cursor_pos.x = ImClamp(IM_FLOOR(picker_pos.x + ImSaturate(S) * sv_picker_size + 0.5f), picker_pos.x + 2, picker_pos.x + sv_picker_size - 2); // Sneakily prevent the circle to stick out too much
|
||||
sv_cursor_pos.y = ImClamp(IM_FLOOR(picker_pos.y + ImSaturate(1 - V) * sv_picker_size + 0.5f), picker_pos.y + 2, picker_pos.y + sv_picker_size - 2);
|
||||
|
||||
// Render Hue Bar
|
||||
for (int i = 0; i < 6; ++i)
|
||||
draw_list->AddRectFilledMultiColor(ImVec2(bar0_pos_x, picker_pos.y + i * (sv_picker_size / 6)), ImVec2(bar0_pos_x + bars_width, picker_pos.y + (i + 1) * (sv_picker_size / 6)), col_hues[i], col_hues[i], col_hues[i + 1], col_hues[i + 1]);
|
||||
float bar0_line_y = (float)(int)(picker_pos.y + H * sv_picker_size + 0.5f);
|
||||
float bar0_line_y = IM_FLOOR(picker_pos.y + H * sv_picker_size + 0.5f);
|
||||
RenderFrameBorder(ImVec2(bar0_pos_x, picker_pos.y), ImVec2(bar0_pos_x + bars_width, picker_pos.y + sv_picker_size), 0.0f);
|
||||
RenderArrowsForVerticalBar(draw_list, ImVec2(bar0_pos_x - 1, bar0_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f, style.Alpha);
|
||||
}
|
||||
@ -4818,7 +4829,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
ImRect bar1_bb(bar1_pos_x, picker_pos.y, bar1_pos_x + bars_width, picker_pos.y + sv_picker_size);
|
||||
RenderColorRectWithAlphaCheckerboard(bar1_bb.Min, bar1_bb.Max, 0, bar1_bb.GetWidth() / 2.0f, ImVec2(0.0f, 0.0f));
|
||||
draw_list->AddRectFilledMultiColor(bar1_bb.Min, bar1_bb.Max, user_col32_striped_of_alpha, user_col32_striped_of_alpha, user_col32_striped_of_alpha & ~IM_COL32_A_MASK, user_col32_striped_of_alpha & ~IM_COL32_A_MASK);
|
||||
float bar1_line_y = (float)(int)(picker_pos.y + (1.0f - alpha) * sv_picker_size + 0.5f);
|
||||
float bar1_line_y = IM_FLOOR(picker_pos.y + (1.0f - alpha) * sv_picker_size + 0.5f);
|
||||
RenderFrameBorder(bar1_bb.Min, bar1_bb.Max, 0.0f);
|
||||
RenderArrowsForVerticalBar(draw_list, ImVec2(bar1_pos_x - 1, bar1_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f, style.Alpha);
|
||||
}
|
||||
@ -4875,7 +4886,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
||||
bb_inner.Expand(off);
|
||||
if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f)
|
||||
{
|
||||
float mid_x = (float)(int)((bb_inner.Min.x + bb_inner.Max.x) * 0.5f + 0.5f);
|
||||
float mid_x = IM_FLOOR((bb_inner.Min.x + bb_inner.Max.x) * 0.5f + 0.5f);
|
||||
RenderColorRectWithAlphaCheckerboard(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);
|
||||
}
|
||||
@ -5227,8 +5238,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
{
|
||||
// Framed header expand a little outside the default padding, to the edge of InnerClipRect
|
||||
// (FIXME: May remove this at some point and make InnerClipRect align with WindowPadding.x instead of WindowPadding.x*0.5f)
|
||||
frame_bb.Min.x -= (float)(int)(window->WindowPadding.x * 0.5f - 1.0f);
|
||||
frame_bb.Max.x += (float)(int)(window->WindowPadding.x * 0.5f);
|
||||
frame_bb.Min.x -= IM_FLOOR(window->WindowPadding.x * 0.5f - 1.0f);
|
||||
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
|
||||
@ -5241,7 +5252,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
ImRect interact_bb = frame_bb;
|
||||
if (!display_frame && (flags & (ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_SpanFullWidth)) == 0)
|
||||
interact_bb.Max.x = frame_bb.Min.x + text_width + style.ItemSpacing.x * 2.0f;
|
||||
|
||||
|
||||
// Store a flag for the current depth to tell if we will allow closing this node when navigating one of its child.
|
||||
// For this purpose we essentially compare if g.NavIdIsAlive went from 0 to 1 between TreeNode() and TreePop().
|
||||
// This is currently only support 32 level deep and we are fine with (1 << Depth) overflowing into a zero.
|
||||
@ -5520,8 +5531,8 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
// Selectables are tightly packed together so we extend the box to cover spacing between selectable.
|
||||
const float spacing_x = style.ItemSpacing.x;
|
||||
const float spacing_y = style.ItemSpacing.y;
|
||||
const float spacing_L = (float)(int)(spacing_x * 0.50f);
|
||||
const float spacing_U = (float)(int)(spacing_y * 0.50f);
|
||||
const float spacing_L = IM_FLOOR(spacing_x * 0.50f);
|
||||
const float spacing_U = IM_FLOOR(spacing_y * 0.50f);
|
||||
bb.Min.x -= spacing_L;
|
||||
bb.Min.y -= spacing_U;
|
||||
bb.Max.x += (spacing_x - spacing_L);
|
||||
@ -5971,7 +5982,7 @@ void ImGuiMenuColumns::Update(int count, float spacing, bool clear)
|
||||
{
|
||||
if (i > 0 && NextWidths[i] > 0.0f)
|
||||
Width += Spacing;
|
||||
Pos[i] = (float)(int)Width;
|
||||
Pos[i] = IM_FLOOR(Width);
|
||||
Width += NextWidths[i];
|
||||
NextWidths[i] = 0.0f;
|
||||
}
|
||||
@ -6130,19 +6141,19 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
||||
// Menu inside an horizontal menu bar
|
||||
// Selectable extend their highlight by half ItemSpacing in each direction.
|
||||
// For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin()
|
||||
popup_pos = ImVec2(pos.x - 1.0f - (float)(int)(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight());
|
||||
window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f);
|
||||
popup_pos = ImVec2(pos.x - 1.0f - IM_FLOOR(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight());
|
||||
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f);
|
||||
PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y));
|
||||
float w = label_size.x;
|
||||
pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_PressedOnClick | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
|
||||
PopStyleVar();
|
||||
window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
|
||||
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
|
||||
}
|
||||
else
|
||||
{
|
||||
// Menu inside a menu
|
||||
popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y);
|
||||
float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, (float)(int)(g.FontSize * 1.20f)); // Feedback to next frame
|
||||
float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, IM_FLOOR(g.FontSize * 1.20f)); // Feedback to next frame
|
||||
float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w);
|
||||
pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_PressedOnClick | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
|
||||
ImU32 text_col = GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled);
|
||||
@ -6281,16 +6292,16 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo
|
||||
// Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful
|
||||
// Note that in this situation we render neither the shortcut neither the selected tick mark
|
||||
float w = label_size.x;
|
||||
window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f);
|
||||
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f);
|
||||
PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y));
|
||||
pressed = Selectable(label, false, flags, ImVec2(w, 0.0f));
|
||||
PopStyleVar();
|
||||
window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
|
||||
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
|
||||
}
|
||||
else
|
||||
{
|
||||
ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f);
|
||||
float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame
|
||||
float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, IM_FLOOR(g.FontSize * 1.20f)); // Feedback for next frame
|
||||
float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w);
|
||||
pressed = Selectable(label, false, flags | ImGuiSelectableFlags_DrawFillAvailWidth, ImVec2(w, 0.0f));
|
||||
if (shortcut_size.x > 0.0f)
|
||||
@ -6591,7 +6602,7 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
// If we don't have enough room, resize down the largest tabs first
|
||||
ShrinkWidths(g.ShrinkWidthBuffer.Data, g.ShrinkWidthBuffer.Size, width_excess);
|
||||
for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++)
|
||||
tab_bar->Tabs[g.ShrinkWidthBuffer[tab_n].Index].Width = (float)(int)g.ShrinkWidthBuffer[tab_n].Width;
|
||||
tab_bar->Tabs[g.ShrinkWidthBuffer[tab_n].Index].Width = IM_FLOOR(g.ShrinkWidthBuffer[tab_n].Width);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -7037,7 +7048,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
|
||||
// Layout
|
||||
size.x = tab->Width;
|
||||
window->DC.CursorPos = tab_bar->BarRect.Min + ImVec2((float)(int)tab->Offset - tab_bar->ScrollingAnim, 0.0f);
|
||||
window->DC.CursorPos = tab_bar->BarRect.Min + ImVec2(IM_FLOOR(tab->Offset - tab_bar->ScrollingAnim), 0.0f);
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
ImRect bb(pos, pos + size);
|
||||
|
||||
@ -7138,7 +7149,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
if (hovered && g.HoveredIdNotActiveTimer > 0.50f && bb.GetWidth() < tab->WidthContents)
|
||||
{
|
||||
// Enlarge tab display when hovering
|
||||
bb.Max.x = bb.Min.x + (float)(int)ImLerp(bb.GetWidth(), tab->WidthContents, ImSaturate((g.HoveredIdNotActiveTimer - 0.40f) * 6.0f));
|
||||
bb.Max.x = bb.Min.x + IM_FLOOR(ImLerp(bb.GetWidth(), tab->WidthContents, ImSaturate((g.HoveredIdNotActiveTimer - 0.40f) * 6.0f)));
|
||||
display_draw_list = GetForegroundDrawList(window);
|
||||
TabItemBackground(display_draw_list, bb, flags, GetColorU32(ImGuiCol_TitleBgActive));
|
||||
}
|
||||
@ -7258,7 +7269,7 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
|
||||
if (flags & ImGuiTabItemFlags_UnsavedDocument)
|
||||
{
|
||||
text_pixel_clip_bb.Max.x -= CalcTextSize(TAB_UNSAVED_MARKER, NULL, false).x;
|
||||
ImVec2 unsaved_marker_pos(ImMin(bb.Min.x + frame_padding.x + label_size.x + 2, text_pixel_clip_bb.Max.x), bb.Min.y + frame_padding.y + (float)(int)(-g.FontSize * 0.25f));
|
||||
ImVec2 unsaved_marker_pos(ImMin(bb.Min.x + frame_padding.x + label_size.x + 2, text_pixel_clip_bb.Max.x), bb.Min.y + frame_padding.y + IM_FLOOR(-g.FontSize * 0.25f));
|
||||
RenderTextClippedEx(draw_list, unsaved_marker_pos, bb.Max - frame_padding, TAB_UNSAVED_MARKER, NULL, NULL);
|
||||
}
|
||||
ImRect text_ellipsis_clip_bb = text_pixel_clip_bb;
|
||||
@ -7567,7 +7578,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
|
||||
float width = offset_1 - offset_0;
|
||||
PushItemWidth(width * 0.65f);
|
||||
window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f);
|
||||
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
window->WorkRect.Max.x = window->Pos.x + offset_1 - column_padding;
|
||||
}
|
||||
|
||||
@ -7582,7 +7593,7 @@ void ImGui::NextColumn()
|
||||
|
||||
if (columns->Count == 1)
|
||||
{
|
||||
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
IM_ASSERT(columns->Current == 0);
|
||||
return;
|
||||
}
|
||||
@ -7607,7 +7618,7 @@ void ImGui::NextColumn()
|
||||
columns->Current = 0;
|
||||
columns->LineMinY = columns->LineMaxY;
|
||||
}
|
||||
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
window->DC.CursorPos.y = columns->LineMinY;
|
||||
window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
|
||||
window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||
@ -7674,7 +7685,7 @@ void ImGui::EndColumns()
|
||||
|
||||
// Draw column
|
||||
const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator);
|
||||
const float xi = (float)(int)x;
|
||||
const float xi = IM_FLOOR(x);
|
||||
window->DrawList->AddLine(ImVec2(xi, y1 + 1.0f), ImVec2(xi, y2), col);
|
||||
}
|
||||
|
||||
@ -7694,7 +7705,7 @@ void ImGui::EndColumns()
|
||||
window->WorkRect = columns->HostWorkRect;
|
||||
window->DC.CurrentColumns = NULL;
|
||||
window->DC.ColumnsOffset.x = 0.0f;
|
||||
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
}
|
||||
|
||||
// [2018-03: This is currently the only public API, while we are working on making BeginColumns/EndColumns user-facing]
|
||||
|
Reference in New Issue
Block a user