Merge branch 'master' into viewport

# Conflicts:
#	examples/imgui_impl_sdl.cpp
#	imgui.cpp
This commit is contained in:
omar
2018-07-24 16:50:49 +02:00
24 changed files with 187 additions and 142 deletions

201
imgui.cpp
View File

@ -190,7 +190,7 @@
io.MouseDown[1] = my_mouse_buttons[1];
// Call NewFrame(), after this point you can use ImGui::* functions anytime
// (So you want to try calling Newframe() as early as you can in your mainloop to be able to use imgui everywhere)
// (So you want to try calling NewFrame() as early as you can in your mainloop to be able to use imgui everywhere)
ImGui::NewFrame();
// Most of your application code here
@ -316,6 +316,7 @@
- 2018/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
- 2018/XX/XX (1.XX) - removed io.DisplayVisibleMin, io.DisplayVisibleMax settings (it was used to clip within the DisplayMin..DisplayMax range, I don't know of anyone using it)
- 2018/07/22 (1.63) - changed ImGui::GetTime() return value from float to double to avoid accumulating floating point imprecisions over time.
- 2018/07/08 (1.63) - style: renamed ImGuiCol_ModalWindowDarkening to ImGuiCol_ModalWindowDimBg for consistency with other features. Kept redirection enum (will obsolete).
- 2018/07/06 (1.63) - removed per-window ImGuiWindowFlags_ResizeFromAnySide beta flag in favor of a global io.OptResizeWindowsFromEdges to enable the feature.
- 2018/06/06 (1.62) - renamed GetGlyphRangesChinese() to GetGlyphRangesChineseFull() to distinguish other variants and discourage using the full set.
@ -900,6 +901,7 @@ static void NavUpdateWindowingList();
static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, const ImGuiID id);
static void UpdateMouseInputs();
static void UpdateMouseWheel();
static void UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]);
static void FocusFrontMostActiveWindow(ImGuiWindow* ignore_window);
@ -1847,37 +1849,41 @@ bool ImGuiTextFilter::Draw(const char* label, float width)
return value_changed;
}
void ImGuiTextFilter::TextRange::split(char separator, ImVector<TextRange>& out)
void ImGuiTextFilter::TextRange::split(char separator, ImVector<TextRange>* out) const
{
out.resize(0);
out->resize(0);
const char* wb = b;
const char* we = wb;
while (we < e)
{
if (*we == separator)
{
out.push_back(TextRange(wb, we));
out->push_back(TextRange(wb, we));
wb = we + 1;
}
we++;
}
if (wb != we)
out.push_back(TextRange(wb, we));
out->push_back(TextRange(wb, we));
}
void ImGuiTextFilter::Build()
{
Filters.resize(0);
TextRange input_range(InputBuf, InputBuf+strlen(InputBuf));
input_range.split(',', Filters);
input_range.split(',', &Filters);
CountGrep = 0;
for (int i = 0; i != Filters.Size; i++)
{
Filters[i].trim_blanks();
if (Filters[i].empty())
TextRange& f = Filters[i];
while (f.b < f.e && ImCharIsBlankA(f.b[0]))
f.b++;
while (f.e > f.b && ImCharIsBlankA(f.e[-1]))
f.e--;
if (f.empty())
continue;
if (Filters[i].front() != '-')
if (Filters[i].b[0] != '-')
CountGrep += 1;
}
}
@ -1895,7 +1901,7 @@ bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const
const TextRange& f = Filters[i];
if (f.empty())
continue;
if (f.front() == '-')
if (f.b[0] == '-')
{
// Subtract
if (ImStristr(text, text_end, f.begin()+1, f.end()) != NULL)
@ -2934,7 +2940,7 @@ ImDrawData* ImGui::GetDrawData()
return g.Viewports[0]->DrawDataP.Valid ? &g.Viewports[0]->DrawDataP : NULL;
}
float ImGui::GetTime()
double ImGui::GetTime()
{
return GImGui->Time;
}
@ -4114,7 +4120,7 @@ static void ImGui::UpdateMouseInputs()
g.IO.MouseDoubleClicked[i] = false;
if (g.IO.MouseClicked[i])
{
if (g.Time - g.IO.MouseClickedTime[i] < g.IO.MouseDoubleClickTime)
if ((float)(g.Time - g.IO.MouseClickedTime[i]) < g.IO.MouseDoubleClickTime)
{
ImVec2 delta_from_click_pos = IsMousePosValid(&g.IO.MousePos) ? (g.IO.MousePos - g.IO.MouseClickedPos[i]) : ImVec2(0.0f, 0.0f);
if (ImLengthSqr(delta_from_click_pos) < g.IO.MouseDoubleClickMaxDist * g.IO.MouseDoubleClickMaxDist)
@ -4142,6 +4148,51 @@ static void ImGui::UpdateMouseInputs()
}
}
void ImGui::UpdateMouseWheel()
{
ImGuiContext& g = *GImGui;
if (!g.HoveredWindow || g.HoveredWindow->Collapsed)
return;
if (g.IO.MouseWheel == 0.0f && g.IO.MouseWheelH == 0.0f)
return;
// If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent (unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set).
ImGuiWindow* window = g.HoveredWindow;
ImGuiWindow* scroll_window = window;
while ((scroll_window->Flags & ImGuiWindowFlags_ChildWindow) && (scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoScrollbar) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs) && scroll_window->ParentWindow)
scroll_window = scroll_window->ParentWindow;
const bool scroll_allowed = !(scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs);
if (g.IO.MouseWheel != 0.0f)
{
if (g.IO.KeyCtrl && g.IO.FontAllowUserScaling)
{
// Zoom / Scale window
const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f);
const float scale = new_font_scale / window->FontWindowScale;
window->FontWindowScale = new_font_scale;
const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size;
window->Pos += offset;
window->Size *= scale;
window->SizeFull *= scale;
}
else if (!g.IO.KeyCtrl && scroll_allowed)
{
// Mouse wheel vertical scrolling
float scroll_amount = 5 * scroll_window->CalcFontSize();
scroll_amount = (float)(int)ImMin(scroll_amount, (scroll_window->ContentsRegionRect.GetHeight() + scroll_window->WindowPadding.y * 2.0f) * 0.67f);
SetWindowScrollY(scroll_window, scroll_window->Scroll.y - g.IO.MouseWheel * scroll_amount);
}
}
if (g.IO.MouseWheelH != 0.0f && scroll_allowed && !g.IO.KeyCtrl)
{
// Mouse wheel horizontal scrolling (for hardware that supports it)
float scroll_amount = scroll_window->CalcFontSize();
SetWindowScrollX(scroll_window, scroll_window->Scroll.x - g.IO.MouseWheelH * scroll_amount);
}
}
// The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app)
void ImGui::UpdateHoveredWindowAndCaptureFlags()
{
@ -4288,8 +4339,9 @@ void ImGui::NewFrame()
UpdateViewports();
// Setup font, draw list shared data
// Setup current font, and draw list shared data
// FIXME-VIEWPORT: the concept of a single ClipRectFullscreen is not ideal!
g.IO.Fonts->Locked = true;
SetCurrentFont(GetDefaultFont());
IM_ASSERT(g.Font->IsLoaded());
ImVec2 virtual_space_max(0,0);
@ -4373,45 +4425,7 @@ void ImGui::NewFrame()
g.PlatformImePosViewport = NULL;
// Mouse wheel scrolling, scale
if (g.HoveredWindow && !g.HoveredWindow->Collapsed && (g.IO.MouseWheel != 0.0f || g.IO.MouseWheelH != 0.0f))
{
// If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent (unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set).
ImGuiWindow* window = g.HoveredWindow;
ImGuiWindow* scroll_window = window;
while ((scroll_window->Flags & ImGuiWindowFlags_ChildWindow) && (scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoScrollbar) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs) && scroll_window->ParentWindow)
scroll_window = scroll_window->ParentWindow;
const bool scroll_allowed = !(scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs);
if (g.IO.MouseWheel != 0.0f)
{
if (g.IO.KeyCtrl && g.IO.FontAllowUserScaling)
{
// Zoom / Scale window
const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f);
const float scale = new_font_scale / window->FontWindowScale;
window->FontWindowScale = new_font_scale;
const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size;
window->Pos += offset;
window->Size *= scale;
window->SizeFull *= scale;
}
else if (!g.IO.KeyCtrl && scroll_allowed)
{
// Mouse wheel vertical scrolling
float scroll_amount = 5 * scroll_window->CalcFontSize();
scroll_amount = (float)(int)ImMin(scroll_amount, (scroll_window->ContentsRegionRect.GetHeight() + scroll_window->WindowPadding.y * 2.0f) * 0.67f);
SetWindowScrollY(scroll_window, scroll_window->Scroll.y - g.IO.MouseWheel * scroll_amount);
}
}
if (g.IO.MouseWheelH != 0.0f && scroll_allowed)
{
// Mouse wheel horizontal scrolling (for hardware that supports it)
float scroll_amount = scroll_window->CalcFontSize();
if (!g.IO.KeyCtrl && !(window->Flags & ImGuiWindowFlags_NoScrollWithMouse))
SetWindowScrollX(window, window->Scroll.x - g.IO.MouseWheelH * scroll_amount);
}
}
UpdateMouseWheel();
// Pressing TAB activate widget focus
if (g.ActiveId == 0 && g.NavWindow != NULL && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab, false))
@ -5015,6 +5029,9 @@ void ImGui::EndFrame()
IM_ASSERT(g.Windows.Size == g.WindowsSortBuffer.Size); // we done something wrong
g.Windows.swap(g.WindowsSortBuffer);
// Unlock font atlas
g.IO.Fonts->Locked = false;
// Clear Input data for next frame
g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f;
memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
@ -5378,11 +5395,23 @@ void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding)
}
}
// Render a triangle to denote expanded/collapsed state
// Render an arrow. 'pos' is position of the arrow tip. half_sz.x is length from base to tip. half_sz.y is length on each side.
void ImGui::RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col)
{
switch (direction)
{
case ImGuiDir_Left: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), pos, col); return;
case ImGuiDir_Right: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), pos, col); return;
case ImGuiDir_Up: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), pos, col); return;
case ImGuiDir_Down: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), pos, col); return;
case ImGuiDir_None: case ImGuiDir_COUNT: break; // Fix warnings
}
}
// Render an arrow aimed to be aligned with text (p_min is a position in the same space text would be positioned). To e.g. denote expanded/collapsed state
void ImGui::RenderArrow(ImVec2 p_min, ImGuiDir dir, float scale)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
const float h = g.FontSize * 1.00f;
float r = h * 0.40f * scale;
@ -5394,18 +5423,16 @@ void ImGui::RenderArrow(ImVec2 p_min, ImGuiDir dir, float scale)
case ImGuiDir_Up:
case ImGuiDir_Down:
if (dir == ImGuiDir_Up) r = -r;
center.y -= r * 0.25f;
a = ImVec2(0,1) * r;
b = ImVec2(-0.866f,-0.5f) * r;
c = ImVec2(+0.866f,-0.5f) * r;
a = ImVec2(+0.000f,+0.750f) * r;
b = ImVec2(-0.866f,-0.750f) * r;
c = ImVec2(+0.866f,-0.750f) * r;
break;
case ImGuiDir_Left:
case ImGuiDir_Right:
if (dir == ImGuiDir_Left) r = -r;
center.x -= r * 0.25f;
a = ImVec2(1,0) * r;
b = ImVec2(-0.500f,+0.866f) * r;
c = ImVec2(-0.500f,-0.866f) * r;
a = ImVec2(+0.750f,+0.000f) * r;
b = ImVec2(-0.750f,+0.866f) * r;
c = ImVec2(-0.750f,-0.866f) * r;
break;
case ImGuiDir_None:
case ImGuiDir_COUNT:
@ -5413,7 +5440,7 @@ void ImGui::RenderArrow(ImVec2 p_min, ImGuiDir dir, float scale)
break;
}
window->DrawList->AddTriangleFilled(center + a, center + b, center + c, GetColorU32(ImGuiCol_Text));
g.CurrentWindow->DrawList->AddTriangleFilled(center + a, center + b, center + c, GetColorU32(ImGuiCol_Text));
}
void ImGui::RenderBullet(ImVec2 pos)
@ -7601,15 +7628,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Collapse button
if (!(flags & ImGuiWindowFlags_NoCollapse))
{
ImGuiID id = window->GetID("#COLLAPSE");
ImRect bb(window->Pos + style.FramePadding + ImVec2(1,1), window->Pos + style.FramePadding + ImVec2(g.FontSize,g.FontSize) - ImVec2(1,1));
ItemAdd(bb, id);
if (ButtonBehavior(bb, id, NULL, NULL))
if (CollapseButton(window->GetID("#COLLAPSE"), window->Pos + style.FramePadding))
window->CollapseToggleWanted = true; // Defer collapsing to next frame as we are too far in the Begin() function
RenderNavHighlight(bb, id);
RenderArrow(window->Pos + style.FramePadding, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f);
}
// Close button
if (p_open != NULL)
@ -9320,6 +9340,24 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos, float radius)
return pressed;
}
bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
ImRect bb(pos, pos + ImVec2(g.FontSize, g.FontSize));
ItemAdd(bb, id);
bool ret = ButtonBehavior(bb, id, NULL, NULL, ImGuiButtonFlags_None);
RenderNavHighlight(bb, id);
RenderArrow(bb.Min, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f);
// Switch to moving the window after mouse is moved beyond the initial drag threshold
if (IsItemActive() && IsMouseDragging())
StartMouseMovingWindow(window);
return ret;
}
void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col)
{
ImGuiWindow* window = GetCurrentWindow();
@ -13548,25 +13586,12 @@ bool ImGui::ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags fl
return true;
}
// 'pos' is position of the arrow tip. half_sz.x is length from base to tip. half_sz.y is length on each side.
static void RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col)
{
switch (direction)
{
case ImGuiDir_Left: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), pos, col); return;
case ImGuiDir_Right: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), pos, col); return;
case ImGuiDir_Up: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), pos, col); return;
case ImGuiDir_Down: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), pos, col); return;
case ImGuiDir_None: case ImGuiDir_COUNT: break; // Fix warnings
}
}
static void RenderArrowsForVerticalBar(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, float bar_w)
{
RenderArrow(draw_list, ImVec2(pos.x + half_sz.x + 1, pos.y), ImVec2(half_sz.x + 2, half_sz.y + 1), ImGuiDir_Right, IM_COL32_BLACK);
RenderArrow(draw_list, ImVec2(pos.x + half_sz.x, pos.y), half_sz, ImGuiDir_Right, IM_COL32_WHITE);
RenderArrow(draw_list, ImVec2(pos.x + bar_w - half_sz.x - 1, pos.y), ImVec2(half_sz.x + 2, half_sz.y + 1), ImGuiDir_Left, IM_COL32_BLACK);
RenderArrow(draw_list, ImVec2(pos.x + bar_w - half_sz.x, pos.y), half_sz, ImGuiDir_Left, IM_COL32_WHITE);
ImGui::RenderArrowPointingAt(draw_list, ImVec2(pos.x + half_sz.x + 1, pos.y), ImVec2(half_sz.x + 2, half_sz.y + 1), ImGuiDir_Right, IM_COL32_BLACK);
ImGui::RenderArrowPointingAt(draw_list, ImVec2(pos.x + half_sz.x, pos.y), half_sz, ImGuiDir_Right, IM_COL32_WHITE);
ImGui::RenderArrowPointingAt(draw_list, ImVec2(pos.x + bar_w - half_sz.x - 1, pos.y), ImVec2(half_sz.x + 2, half_sz.y + 1), ImGuiDir_Left, IM_COL32_BLACK);
ImGui::RenderArrowPointingAt(draw_list, ImVec2(pos.x + bar_w - half_sz.x, pos.y), half_sz, ImGuiDir_Left, IM_COL32_WHITE);
}
// ColorPicker