Merge branch 'master' into navigation

This commit is contained in:
omar 2017-11-08 23:17:14 +01:00
commit a297cbafdb
3 changed files with 54 additions and 42 deletions

View File

@ -1428,10 +1428,10 @@ static ImVector<ImGuiStorage::Pair>::iterator LowerBound(ImVector<ImGuiStorage::
{
ImVector<ImGuiStorage::Pair>::iterator first = data.begin();
ImVector<ImGuiStorage::Pair>::iterator last = data.end();
int count = (int)(last - first);
size_t count = (size_t)(last - first);
while (count > 0)
{
int count2 = count / 2;
size_t count2 = count >> 1;
ImVector<ImGuiStorage::Pair>::iterator mid = first + count2;
if (mid->key < key)
{
@ -4828,13 +4828,9 @@ static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size,
ImGuiWindow* ImGui::FindWindowByName(const char* name)
{
// FIXME-OPT: Store sorted hashes -> pointers so we can do a bissection in a contiguous block
ImGuiContext& g = *GImGui;
ImGuiID id = ImHash(name, 0);
for (int i = 0; i < g.Windows.Size; i++)
if (g.Windows[i]->ID == id)
return g.Windows[i];
return NULL;
return (ImGuiWindow*)g.WindowsById.GetVoidPtr(id);
}
static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags)
@ -4845,6 +4841,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
ImGuiWindow* window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow));
IM_PLACEMENT_NEW(window) ImGuiWindow(name);
window->Flags = flags;
g.WindowsById.SetVoidPtr(window->ID, window);
if (flags & ImGuiWindowFlags_NoSavedSettings)
{
@ -4947,7 +4944,7 @@ static ImVec2 CalcSizeAutoFit(ImGuiWindow* window)
if (size_auto_fit_after_constraint.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar))
size_auto_fit.y += style.ScrollbarSize;
if (size_auto_fit_after_constraint.y < window->SizeContents.y && !(flags & ImGuiWindowFlags_NoScrollbar))
size_auto_fit.x += style.ScrollbarSize * 2.0f;
size_auto_fit.x += style.ScrollbarSize;
size_auto_fit.y = ImMax(size_auto_fit.y - style.ItemSpacing.y, 0.0f);
}
return size_auto_fit;
@ -5149,10 +5146,21 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// SIZE
// Save contents size from last frame for auto-fitting (unless explicitly specified)
// Update contents size from last frame for auto-fitting (unless explicitly specified)
window->SizeContents.x = (float)(int)((window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.x - window->Pos.x) + window->Scroll.x));
window->SizeContents.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.y - window->Pos.y) + window->Scroll.y));
// Update scrollbar status based on the Size that was effective during last frame (and not the upcoming Size which we are updating below), so that user code consuming exactly the available size won't trigger scrollbars when e.g. manually resizing.
if (!window->Collapsed)
{
window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar));
window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->Size.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar));
if (window->ScrollbarX && !window->ScrollbarY)
window->ScrollbarY = (window->SizeContents.y > window->Size.y + style.ItemSpacing.y - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar);
window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f);
window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f;
}
// Hide popup/tooltip window when first appearing while we measure size (because we recycle them)
if (window->HiddenFrames > 0)
window->HiddenFrames--;
@ -5168,7 +5176,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
}
// Lock window padding so that altering the ShowBorders flag for children doesn't have side-effects.
window->WindowPadding = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) ? ImVec2(0,0) : style.WindowPadding;
window->WindowPadding = style.WindowPadding;
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup)))
window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f);
// Calculate auto-fit size, handle automatic resize
const ImVec2 size_auto_fit = CalcSizeAutoFit(window);
@ -5311,7 +5321,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Manual resize
// Using the FlattenChilds button flag, we make the resize button accessible even if we are hovering over a child window
const ImVec2 br = window->Rect().GetBR();
const ImRect resize_rect(br - ImVec2(resize_corner_size * 0.75f, resize_corner_size * 0.75f), br);
const ImRect resize_rect(br - ImFloor(ImVec2(resize_corner_size * 0.75f, resize_corner_size * 0.75f)), br);
const ImGuiID resize_id = window->GetID("#RESIZE");
bool hovered, held;
ButtonBehavior(resize_rect, resize_id, &hovered, &held, ImGuiButtonFlags_FlattenChilds | ImGuiButtonFlags_NoNavFocus);
@ -5346,7 +5356,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
else if (held)
{
// We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
size_target = (g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize()) - window->Pos;
size_target = (g.IO.MousePos - g.ActiveIdClickOffset - window->Pos) + resize_rect.GetSize();
}
if (size_target.x != FLT_MAX && size_target.y != FLT_MAX)
@ -5360,14 +5370,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
title_bar_rect = window->TitleBarRect();
}
// Scrollbars
window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar));
window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->Size.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar));
if (window->ScrollbarX && !window->ScrollbarY)
window->ScrollbarY = (window->SizeContents.y > window->Size.y + style.ItemSpacing.y - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar);
window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f);
window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f;
// Window background, Default Alpha
ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags));
window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImGuiCorner_All : ImGuiCorner_BotLeft|ImGuiCorner_BotRight);
@ -6263,8 +6265,7 @@ bool ImGui::IsWindowAppearing()
void ImGui::SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond)
{
ImGuiWindow* window = FindWindowByName(name);
if (window)
if (ImGuiWindow* window = FindWindowByName(name))
SetWindowCollapsed(window, collapsed, cond);
}
@ -6852,11 +6853,15 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
{
pressed = true;
if (flags & ImGuiButtonFlags_NoHoldingActiveID)
{
ClearActiveID();
}
else
{
SetActiveID(id, window); // Hold on ID
g.ActiveIdClickOffset = g.IO.MousePos - bb.Min;
}
FocusWindow(window);
g.ActiveIdClickOffset = g.IO.MousePos - bb.Min;
}
if ((flags & ImGuiButtonFlags_PressedOnRelease) && g.IO.MouseReleased[0])
{
@ -11641,8 +11646,8 @@ void ImGui::EndColumns()
{
float x = window->Pos.x + GetColumnOffset(i);
const ImGuiID column_id = window->DC.ColumnsSetId + ImGuiID(i);
const float column_w = 4.0f; // Width for interaction
const ImRect column_rect(ImVec2(x - column_w, y1), ImVec2(x + column_w, y2));
const float column_hw = 4.0f; // Half-width for interaction
const ImRect column_rect(ImVec2(x - column_hw, y1), ImVec2(x + column_hw, y2));
if (IsClippedEx(column_rect, column_id, false))
continue;
@ -11653,7 +11658,7 @@ void ImGui::EndColumns()
if (hovered || held)
g.MouseCursor = ImGuiMouseCursor_ResizeEW;
if (held && g.ActiveIdIsJustActivated)
g.ActiveIdClickOffset.x -= column_w; // Store from center of column line (we used a 8 wide rect for columns clicking). This is used by GetDraggedColumnOffset().
g.ActiveIdClickOffset.x -= column_hw; // Store from center of column line (we used a 8 wide rect for columns clicking). This is used by GetDraggedColumnOffset().
if (held)
dragging_column = i;
}

View File

@ -2183,31 +2183,40 @@ static void ShowExampleAppConstrainedResize(bool* p_open)
static void Step(ImGuiSizeConstraintCallbackData* data) { float step = (float)(int)(intptr_t)data->UserData; data->DesiredSize = ImVec2((int)(data->DesiredSize.x / step + 0.5f) * step, (int)(data->DesiredSize.y / step + 0.5f) * step); }
};
static bool auto_resize = false;
static int type = 0;
static int display_lines = 10;
if (type == 0) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 0), ImVec2(-1, FLT_MAX)); // Vertical only
if (type == 1) ImGui::SetNextWindowSizeConstraints(ImVec2(0, -1), ImVec2(FLT_MAX, -1)); // Horizontal only
if (type == 2) ImGui::SetNextWindowSizeConstraints(ImVec2(100, 100), ImVec2(FLT_MAX, FLT_MAX)); // Width > 100, Height > 100
if (type == 3) ImGui::SetNextWindowSizeConstraints(ImVec2(300, 0), ImVec2(400, FLT_MAX)); // Width 300-400
if (type == 4) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Square); // Always Square
if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)100);// Fixed Step
if (type == 3) ImGui::SetNextWindowSizeConstraints(ImVec2(400, -1), ImVec2(500, -1)); // Width 400-500
if (type == 4) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 400), ImVec2(-1, 500)); // Height 400-500
if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Square); // Always Square
if (type == 6) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)100);// Fixed Step
if (ImGui::Begin("Example: Constrained Resize", p_open))
ImGuiWindowFlags flags = auto_resize ? ImGuiWindowFlags_AlwaysAutoResize : 0;
if (ImGui::Begin("Example: Constrained Resize", p_open, flags))
{
const char* desc[] =
{
"Resize vertical only",
"Resize horizontal only",
"Width > 100, Height > 100",
"Width 300-400",
"Width 400-500",
"Height 400-500",
"Custom: Always Square",
"Custom: Fixed Steps (100)",
};
ImGui::Combo("Constraint", &type, desc, IM_ARRAYSIZE(desc));
if (ImGui::Button("200x200")) { ImGui::SetWindowSize(ImVec2(200,200)); } ImGui::SameLine();
if (ImGui::Button("500x500")) { ImGui::SetWindowSize(ImVec2(500,500)); } ImGui::SameLine();
if (ImGui::Button("800x200")) { ImGui::SetWindowSize(ImVec2(800,200)); }
for (int i = 0; i < 10; i++)
ImGui::Text("Hello, sailor! Making this line long enough for the example.");
if (ImGui::Button("200x200")) { ImGui::SetWindowSize(ImVec2(200, 200)); } ImGui::SameLine();
if (ImGui::Button("500x500")) { ImGui::SetWindowSize(ImVec2(500, 500)); } ImGui::SameLine();
if (ImGui::Button("800x200")) { ImGui::SetWindowSize(ImVec2(800, 200)); }
ImGui::PushItemWidth(200);
ImGui::Combo("Constraint", &type, desc, IM_ARRAYSIZE(desc));
ImGui::DragInt("Lines", &display_lines, 0.2f, 1, 100);
ImGui::PopItemWidth();
ImGui::Checkbox("Auto-resize", &auto_resize);
for (int i = 0; i < display_lines; i++)
ImGui::Text("%*sHello, sailor! Making this line long enough for the example.", i * 4, "");
}
ImGui::End();
}

View File

@ -2,10 +2,9 @@
// (internals)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
// Implement maths operators for ImVec2 (disabled by default to not collide with using IM_VEC2_CLASS_EXTRA along with your own math types+operators)
// Set:
// #define IMGUI_DEFINE_MATH_OPERATORS
// Define IM_PLACEMENT_NEW() macro helper.
// #define IMGUI_DEFINE_PLACEMENT_NEW
// To implement maths operators for ImVec2 (disabled by default to not collide with using IM_VEC2_CLASS_EXTRA along with your own math types+operators)
#pragma once
@ -161,12 +160,10 @@ static inline float ImLinearSweep(float current, float target, float speed)
// We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax.
// Defining a custom placement new() with a dummy parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions.
#ifdef IMGUI_DEFINE_PLACEMENT_NEW
struct ImPlacementNewDummy {};
inline void* operator new(size_t, ImPlacementNewDummy, void* ptr) { return ptr; }
inline void operator delete(void*, ImPlacementNewDummy, void*) {}
#define IM_PLACEMENT_NEW(_PTR) new(ImPlacementNewDummy(), _PTR)
#endif
//-----------------------------------------------------------------------------
// Types
@ -442,6 +439,7 @@ struct ImGuiContext
ImVector<ImGuiWindow*> Windows;
ImVector<ImGuiWindow*> WindowsSortBuffer;
ImVector<ImGuiWindow*> CurrentWindowStack;
ImGuiStorage WindowsById;
ImGuiWindow* CurrentWindow; // Being drawn into
ImGuiWindow* HoveredWindow; // Will catch mouse inputs
ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only)