Minor miscellaneous merges from Navigation branch to reduce divergence a little bit

This commit is contained in:
omar 2017-08-22 18:13:10 +08:00
parent 6ee317d26d
commit d5b0d51274
2 changed files with 60 additions and 57 deletions

View File

@ -615,7 +615,7 @@ static ImGuiIniData* FindWindowSettings(const char* name);
static ImGuiIniData* AddWindowSettings(const char* name); static ImGuiIniData* AddWindowSettings(const char* name);
static void LoadIniSettingsFromDisk(const char* ini_filename); static void LoadIniSettingsFromDisk(const char* ini_filename);
static void SaveIniSettingsToDisk(const char* ini_filename); static void SaveIniSettingsToDisk(const char* ini_filename);
static void MarkIniSettingsDirty(); static void MarkIniSettingsDirty(ImGuiWindow* window);
static ImRect GetVisibleRect(); static ImRect GetVisibleRect();
@ -742,6 +742,7 @@ ImGuiIO::ImGuiIO()
// Most fields are initialized with zero // Most fields are initialized with zero
memset(this, 0, sizeof(*this)); memset(this, 0, sizeof(*this));
// Settings
DisplaySize = ImVec2(-1.0f, -1.0f); DisplaySize = ImVec2(-1.0f, -1.0f);
DeltaTime = 1.0f/60.0f; DeltaTime = 1.0f/60.0f;
IniSavingRate = 5.0f; IniSavingRate = 5.0f;
@ -774,6 +775,7 @@ ImGuiIO::ImGuiIO()
SetClipboardTextFn = SetClipboardTextFn_DefaultImpl; SetClipboardTextFn = SetClipboardTextFn_DefaultImpl;
ClipboardUserData = NULL; ClipboardUserData = NULL;
ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl; ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl;
ImeWindowHandle = NULL;
// Set OS X style defaults based on __APPLE__ compile time flag // Set OS X style defaults based on __APPLE__ compile time flag
#ifdef __APPLE__ #ifdef __APPLE__
@ -1934,7 +1936,6 @@ bool ImGui::IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindowRead(); ImGuiWindow* window = GetCurrentWindowRead();
if (!bb.Overlaps(window->ClipRect)) if (!bb.Overlaps(window->ClipRect))
if (!id || *id != GImGui->ActiveId) if (!id || *id != GImGui->ActiveId)
if (clip_even_when_logged || !g.LogEnabled) if (clip_even_when_logged || !g.LogEnabled)
@ -2146,7 +2147,8 @@ void ImGui::NewFrame()
g.RenderDrawData.CmdLists = NULL; g.RenderDrawData.CmdLists = NULL;
g.RenderDrawData.CmdListsCount = g.RenderDrawData.TotalVtxCount = g.RenderDrawData.TotalIdxCount = 0; g.RenderDrawData.CmdListsCount = g.RenderDrawData.TotalVtxCount = g.RenderDrawData.TotalIdxCount = 0;
// Update inputs state
// Update mouse input state
if (g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) if (g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0)
g.IO.MousePos = ImVec2(-9999.0f, -9999.0f); g.IO.MousePos = ImVec2(-9999.0f, -9999.0f);
if ((g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) || (g.IO.MousePosPrev.x < 0 && g.IO.MousePosPrev.y < 0)) // if mouse just appeared or disappeared (negative coordinate) we cancel out movement in MouseDelta if ((g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) || (g.IO.MousePosPrev.x < 0 && g.IO.MousePosPrev.y < 0)) // if mouse just appeared or disappeared (negative coordinate) we cancel out movement in MouseDelta
@ -2213,7 +2215,7 @@ void ImGui::NewFrame()
{ {
g.MovedWindow->PosFloat += g.IO.MouseDelta; g.MovedWindow->PosFloat += g.IO.MouseDelta;
if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoSavedSettings) && (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f)) if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoSavedSettings) && (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f))
MarkIniSettingsDirty(); MarkIniSettingsDirty(g.MovedWindow);
} }
FocusWindow(g.MovedWindow); FocusWindow(g.MovedWindow);
} }
@ -2291,13 +2293,11 @@ void ImGui::NewFrame()
if (g.HoveredWindow && g.IO.MouseWheel != 0.0f && !g.HoveredWindow->Collapsed) if (g.HoveredWindow && g.IO.MouseWheel != 0.0f && !g.HoveredWindow->Collapsed)
{ {
ImGuiWindow* window = g.HoveredWindow; ImGuiWindow* window = g.HoveredWindow;
if (g.IO.KeyCtrl) if (g.IO.KeyCtrl && g.IO.FontAllowUserScaling)
{
if (g.IO.FontAllowUserScaling)
{ {
// Zoom / Scale window // Zoom / Scale window
float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f); const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f);
float scale = new_font_scale / window->FontWindowScale; const float scale = new_font_scale / window->FontWindowScale;
window->FontWindowScale = new_font_scale; window->FontWindowScale = new_font_scale;
const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size;
@ -2306,8 +2306,7 @@ void ImGui::NewFrame()
window->Size *= scale; window->Size *= scale;
window->SizeFull *= scale; window->SizeFull *= scale;
} }
} else if (!g.IO.KeyCtrl && !(window->Flags & ImGuiWindowFlags_NoScrollWithMouse))
else if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse))
{ {
// Scroll // Scroll
const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5; const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5;
@ -2530,9 +2529,10 @@ static void SaveIniSettingsToDisk(const char* ini_filename)
fclose(f); fclose(f);
} }
static void MarkIniSettingsDirty() static void MarkIniSettingsDirty(ImGuiWindow* window)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings))
if (g.SettingsDirtyTimer <= 0.0f) if (g.SettingsDirtyTimer <= 0.0f)
g.SettingsDirtyTimer = g.IO.IniSavingRate; g.SettingsDirtyTimer = g.IO.IniSavingRate;
} }
@ -2684,6 +2684,7 @@ void ImGui::EndFrame()
continue; continue;
AddWindowToSortedBuffer(g.WindowsSortBuffer, window); AddWindowToSortedBuffer(g.WindowsSortBuffer, window);
} }
IM_ASSERT(g.Windows.Size == g.WindowsSortBuffer.Size); // we done something wrong IM_ASSERT(g.Windows.Size == g.WindowsSortBuffer.Size); // we done something wrong
g.Windows.swap(g.WindowsSortBuffer); g.Windows.swap(g.WindowsSortBuffer);
@ -3315,8 +3316,7 @@ bool ImGui::IsAnyItemActive()
bool ImGui::IsItemVisible() bool ImGui::IsItemVisible()
{ {
ImGuiWindow* window = GetCurrentWindowRead(); ImGuiWindow* window = GetCurrentWindowRead();
ImRect r(window->ClipRect); return window->ClipRect.Overlaps(window->DC.LastItemRect);
return r.Overlaps(window->DC.LastItemRect);
} }
// Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority. // Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority.
@ -3631,7 +3631,7 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button)
static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
{ {
ImGuiWindow* window = ImGui::GetCurrentWindow(); ImGuiWindow* parent_window = ImGui::GetCurrentWindow();
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow; ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow;
const ImVec2 content_avail = ImGui::GetContentRegionAvail(); const ImVec2 content_avail = ImGui::GetContentRegionAvail();
@ -3654,14 +3654,14 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
char title[256]; char title[256];
if (name) if (name)
ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s.%08X", window->Name, name, id); ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s.%08X", parent_window->Name, name, id);
else else
ImFormatString(title, IM_ARRAYSIZE(title), "%s.%08X", window->Name, id); ImFormatString(title, IM_ARRAYSIZE(title), "%s.%08X", parent_window->Name, id);
bool ret = ImGui::Begin(title, NULL, size, -1.0f, flags); bool ret = ImGui::Begin(title, NULL, size, -1.0f, flags);
ImGuiWindow* child_window = ImGui::GetCurrentWindow();
if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) if (!(parent_window->Flags & ImGuiWindowFlags_ShowBorders))
ImGui::GetCurrentWindow()->Flags &= ~ImGuiWindowFlags_ShowBorders; child_window->Flags &= ~ImGuiWindowFlags_ShowBorders;
return ret; return ret;
} }
@ -3697,8 +3697,8 @@ void ImGui::EndChild()
ImGui::End(); ImGui::End();
window = GetCurrentWindow(); ImGuiWindow* parent_window = GetCurrentWindow();
ImRect bb(window->DC.CursorPos, window->DC.CursorPos + sz); ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + sz);
ItemSize(sz); ItemSize(sz);
ItemAdd(bb, NULL); ItemAdd(bb, NULL);
} }
@ -3744,7 +3744,7 @@ static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size,
// Clamp into visible area while not overlapping the cursor. Safety padding is optional if our popup size won't fit without it. // Clamp into visible area while not overlapping the cursor. Safety padding is optional if our popup size won't fit without it.
ImVec2 safe_padding = style.DisplaySafeAreaPadding; ImVec2 safe_padding = style.DisplaySafeAreaPadding;
ImRect r_outer(GetVisibleRect()); ImRect r_outer(GetVisibleRect());
r_outer.Reduce(ImVec2((size.x - r_outer.GetWidth() > safe_padding.x*2) ? safe_padding.x : 0.0f, (size.y - r_outer.GetHeight() > safe_padding.y*2) ? safe_padding.y : 0.0f)); r_outer.Expand(ImVec2((size.x - r_outer.GetWidth() > safe_padding.x*2) ? -safe_padding.x : 0.0f, (size.y - r_outer.GetHeight() > safe_padding.y*2) ? -safe_padding.y : 0.0f));
ImVec2 base_pos_clamped = ImClamp(base_pos, r_outer.Min, r_outer.Max - size); ImVec2 base_pos_clamped = ImClamp(base_pos, r_outer.Min, r_outer.Max - size);
for (int n = (*last_dir != -1) ? -1 : 0; n < 4; n++) // Last, Right, down, up, left. (Favor last used direction). for (int n = (*last_dir != -1) ? -1 : 0; n < 4; n++) // Last, Right, down, up, left. (Favor last used direction).
@ -4022,8 +4022,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
if (g.HoveredWindow == window && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseDoubleClicked[0]) if (g.HoveredWindow == window && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseDoubleClicked[0])
{ {
window->Collapsed = !window->Collapsed; window->Collapsed = !window->Collapsed;
if (!(flags & ImGuiWindowFlags_NoSavedSettings)) MarkIniSettingsDirty(window);
MarkIniSettingsDirty();
FocusWindow(window); FocusWindow(window);
} }
} }
@ -4097,8 +4096,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
window->SizeFull.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; window->SizeFull.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x;
if (window->AutoFitFramesY > 0) if (window->AutoFitFramesY > 0)
window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y;
if (!(flags & ImGuiWindowFlags_NoSavedSettings)) MarkIniSettingsDirty(window);
MarkIniSettingsDirty();
} }
} }
@ -4232,16 +4230,14 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
{ {
// Manual auto-fit when double-clicking // Manual auto-fit when double-clicking
ApplySizeFullWithConstraint(window, size_auto_fit); ApplySizeFullWithConstraint(window, size_auto_fit);
if (!(flags & ImGuiWindowFlags_NoSavedSettings)) MarkIniSettingsDirty(window);
MarkIniSettingsDirty();
ClearActiveID(); ClearActiveID();
} }
else if (held) else if (held)
{ {
// We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
ApplySizeFullWithConstraint(window, (g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize()) - window->Pos); ApplySizeFullWithConstraint(window, (g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize()) - window->Pos);
if (!(flags & ImGuiWindowFlags_NoSavedSettings)) MarkIniSettingsDirty(window);
MarkIniSettingsDirty();
} }
window->Size = window->SizeFull; window->Size = window->SizeFull;
@ -4407,7 +4403,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
// Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior. // Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior.
const ImRect title_bar_rect = window->TitleBarRect(); const ImRect title_bar_rect = window->TitleBarRect();
const float border_size = window->BorderSize; const float border_size = window->BorderSize;
ImRect clip_rect; // Force round to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. // Force round to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result.
ImRect clip_rect;
clip_rect.Min.x = ImFloor(0.5f + title_bar_rect.Min.x + ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f))); clip_rect.Min.x = ImFloor(0.5f + title_bar_rect.Min.x + ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f)));
clip_rect.Min.y = ImFloor(0.5f + title_bar_rect.Max.y + window->MenuBarHeight() + border_size); clip_rect.Min.y = ImFloor(0.5f + title_bar_rect.Max.y + window->MenuBarHeight() + border_size);
clip_rect.Max.x = ImFloor(0.5f + window->Pos.x + window->Size.x - window->ScrollbarSizes.x - ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f))); clip_rect.Max.x = ImFloor(0.5f + window->Pos.x + window->Size.x - window->ScrollbarSizes.x - ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f)));
@ -4496,7 +4493,7 @@ static void Scrollbar(ImGuiWindow* window, bool horizontal)
else else
window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImGuiCorner_TopRight : 0) | (other_scrollbar ? 0 : ImGuiCorner_BottomRight); window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImGuiCorner_TopRight : 0) | (other_scrollbar ? 0 : ImGuiCorner_BottomRight);
window->DrawList->AddRectFilled(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_ScrollbarBg), window_rounding, window_rounding_corners); window->DrawList->AddRectFilled(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_ScrollbarBg), window_rounding, window_rounding_corners);
bb.Reduce(ImVec2(ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f))); bb.Expand(ImVec2(-ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f)));
// V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar) // V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar)
float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight(); float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight();
@ -5580,6 +5577,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
return false; return false;
} }
// Default behavior requires click+release on same spot
if ((flags & (ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick)) == 0) if ((flags & (ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick)) == 0)
flags |= ImGuiButtonFlags_PressedOnClickRelease; flags |= ImGuiButtonFlags_PressedOnClickRelease;
@ -6468,13 +6466,18 @@ int ImGui::ParseFormatPrecision(const char* fmt, int default_precision)
return precision; return precision;
} }
static float GetMinimumStepAtDecimalPrecision(int decimal_precision)
{
static const float min_steps[10] = { 1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f };
return (decimal_precision >= 0 && decimal_precision < 10) ? min_steps[decimal_precision] : powf(10.0f, (float)-decimal_precision);
}
float ImGui::RoundScalar(float value, int decimal_precision) float ImGui::RoundScalar(float value, int decimal_precision)
{ {
// Round past decimal precision // Round past decimal precision
// So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0 // So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0
// FIXME: Investigate better rounding methods // FIXME: Investigate better rounding methods
static const float min_steps[10] = { 1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f }; const float min_step = GetMinimumStepAtDecimalPrecision(decimal_precision);
float min_step = (decimal_precision >= 0 && decimal_precision < 10) ? min_steps[decimal_precision] : powf(10.0f, (float)-decimal_precision);
bool negative = value < 0.0f; bool negative = value < 0.0f;
value = fabsf(value); value = fabsf(value);
float remainder = fmodf(value, min_step); float remainder = fmodf(value, min_step);
@ -6602,10 +6605,8 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v
} }
} }
// Calculate slider grab positioning
float grab_t = SliderBehaviorCalcRatioFromValue(*v, v_min, v_max, power, linear_zero_pos);
// Draw // Draw
float grab_t = SliderBehaviorCalcRatioFromValue(*v, v_min, v_max, power, linear_zero_pos);
if (!is_horizontal) if (!is_horizontal)
grab_t = 1.0f - grab_t; grab_t = 1.0f - grab_t;
const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t); const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t);
@ -7293,7 +7294,7 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over
// Render // Render
fraction = ImSaturate(fraction); fraction = ImSaturate(fraction);
RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
bb.Reduce(ImVec2(window->BorderSize, window->BorderSize)); bb.Expand(ImVec2(-window->BorderSize, -window->BorderSize));
const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y); const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y);
RenderFrame(bb.Min, fill_br, GetColorU32(ImGuiCol_PlotHistogram), false, style.FrameRounding); RenderFrame(bb.Min, fill_br, GetColorU32(ImGuiCol_PlotHistogram), false, style.FrameRounding);
@ -8570,6 +8571,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
if (BeginPopupEx(id, flags)) if (BeginPopupEx(id, flags))
{ {
// Display items // Display items
// FIXME-OPT: Use clipper
Spacing(); Spacing();
for (int i = 0; i < items_count; i++) for (int i = 0; i < items_count; i++)
{ {
@ -8757,7 +8759,7 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v
// Assume all items have even height (= 1 line of text). If you need items of different or variable sizes you can create a custom version of ListBox() in your code without using the clipper. // Assume all items have even height (= 1 line of text). If you need items of different or variable sizes you can create a custom version of ListBox() in your code without using the clipper.
bool value_changed = false; bool value_changed = false;
ImGuiListClipper clipper(items_count, GetTextLineHeightWithSpacing()); ImGuiListClipper clipper(items_count, GetTextLineHeightWithSpacing()); // We know exactly our line height here so we pass it as a minor optimization, but generally you don't need to.
while (clipper.Step()) while (clipper.Step())
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
{ {
@ -10471,8 +10473,8 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImGui::Text("FocusedWindow: '%s'", g.FocusedWindow ? g.FocusedWindow->Name : "NULL"); ImGui::Text("FocusedWindow: '%s'", g.FocusedWindow ? g.FocusedWindow->Name : "NULL");
ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL"); ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL");
ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL"); ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL");
ImGui::Text("HoveredID: 0x%08X/0x%08X", g.HoveredId, g.HoveredIdPreviousFrame); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not ImGui::Text("HoveredId: 0x%08X/0x%08X", g.HoveredId, g.HoveredIdPreviousFrame); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not
ImGui::Text("ActiveID: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame); ImGui::Text("ActiveId: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame);
ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
ImGui::TreePop(); ImGui::TreePop();
} }

View File

@ -266,7 +266,7 @@ struct IMGUI_API ImRect
void Add(const ImRect& rhs) { if (Min.x > rhs.Min.x) Min.x = rhs.Min.x; if (Min.y > rhs.Min.y) Min.y = rhs.Min.y; if (Max.x < rhs.Max.x) Max.x = rhs.Max.x; if (Max.y < rhs.Max.y) Max.y = rhs.Max.y; } void Add(const ImRect& rhs) { if (Min.x > rhs.Min.x) Min.x = rhs.Min.x; if (Min.y > rhs.Min.y) Min.y = rhs.Min.y; if (Max.x < rhs.Max.x) Max.x = rhs.Max.x; if (Max.y < rhs.Max.y) Max.y = rhs.Max.y; }
void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; }
void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; }
void Reduce(const ImVec2& amount) { Min.x += amount.x; Min.y += amount.y; Max.x -= amount.x; Max.y -= amount.y; } void Translate(const ImVec2& v) { Min.x += v.x; Min.y += v.y; Max.x += v.x; Max.y += v.y; }
void ClipWith(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; } void ClipWith(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; }
void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; }
ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const
@ -397,8 +397,8 @@ struct ImGuiContext
ImGuiIO IO; ImGuiIO IO;
ImGuiStyle Style; ImGuiStyle Style;
ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back()
float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize() float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window.
float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Size of characters. float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height.
ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvWhitePixel ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvWhitePixel
float Time; float Time;
@ -407,8 +407,8 @@ struct ImGuiContext
int FrameCountRendered; int FrameCountRendered;
ImVector<ImGuiWindow*> Windows; ImVector<ImGuiWindow*> Windows;
ImVector<ImGuiWindow*> WindowsSortBuffer; ImVector<ImGuiWindow*> WindowsSortBuffer;
ImGuiWindow* CurrentWindow; // Being drawn into
ImVector<ImGuiWindow*> CurrentWindowStack; ImVector<ImGuiWindow*> CurrentWindowStack;
ImGuiWindow* CurrentWindow; // Being drawn into
ImGuiWindow* FocusedWindow; // Will catch keyboard inputs ImGuiWindow* FocusedWindow; // Will catch keyboard inputs
ImGuiWindow* HoveredWindow; // Will catch mouse inputs ImGuiWindow* HoveredWindow; // Will catch mouse inputs
ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only) ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only)
@ -417,9 +417,10 @@ struct ImGuiContext
ImGuiID HoveredIdPreviousFrame; ImGuiID HoveredIdPreviousFrame;
ImGuiID ActiveId; // Active widget ImGuiID ActiveId; // Active widget
ImGuiID ActiveIdPreviousFrame; ImGuiID ActiveIdPreviousFrame;
bool ActiveIdIsAlive; bool ActiveIdIsAlive; // Active widget has been seen this frame
bool ActiveIdIsJustActivated; // Set at the time of activation for one frame bool ActiveIdIsJustActivated; // Set at the time of activation for one frame
bool ActiveIdAllowOverlap; // Set only by active widget bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always)
ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior) ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior)
ImGuiWindow* ActiveIdWindow; ImGuiWindow* ActiveIdWindow;
ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window. ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window.