Merge branch 'master' into docking

# Conflicts:
#	examples/imgui_impl_sdl.cpp
#	imgui.cpp
This commit is contained in:
omar 2019-12-18 20:49:41 +01:00
commit c706ff6f3a
7 changed files with 175 additions and 82 deletions

View File

@ -124,6 +124,8 @@ Breaking Changes:
documented (can only unreserve from the last reserve call). If you suspect you ever documented (can only unreserve from the last reserve call). If you suspect you ever
used that feature before, #define IMGUI_DEBUG_PARANOID in imconfig.h to catch existing used that feature before, #define IMGUI_DEBUG_PARANOID in imconfig.h to catch existing
calls. [@ShironekoBen] calls. [@ShironekoBen]
- Limiting Columns()/BeginColumns() api to 64 columns with an assert. While the current code
technically supports it, future code may not so we're putting the restriction ahead.
- imgui_internal.h: changed ImRect() default constructor initializes all fields to 0.0f instead - imgui_internal.h: changed ImRect() default constructor initializes all fields to 0.0f instead
of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by
adding multiple points into it, you may need to fix your initial value. adding multiple points into it, you may need to fix your initial value.
@ -138,6 +140,8 @@ Other Changes:
selection, those new api can fill a gap. [@ShironekoBen] selection, those new api can fill a gap. [@ShironekoBen]
- Backends: GLFW, SDL, Win32, OSX, Allegro: Added support for ImGuiMouseCursor_NotAllowed. [@rokups] - Backends: GLFW, SDL, Win32, OSX, Allegro: Added support for ImGuiMouseCursor_NotAllowed. [@rokups]
- Backends: GLFW: Added support for the missing mouse cursors newly added in GLFW 3.4+. [@rokups] - Backends: GLFW: Added support for the missing mouse cursors newly added in GLFW 3.4+. [@rokups]
- Backends: SDL: Wayland: use SDL_GetMouseState (because there is no global mouse state available
on Wayland). (#2800, #2802) [@NeroBurner]
- Examples: Explicitly adding -DIMGUI_IMPL_OPENGL_LOADER_GL3W to Makefile to match linking - Examples: Explicitly adding -DIMGUI_IMPL_OPENGL_LOADER_GL3W to Makefile to match linking
settings (otherwise if another loader such as Glew is accessible, the opengl3 backend might settings (otherwise if another loader such as Glew is accessible, the opengl3 backend might
automatically use it). [#2919, #2798] automatically use it). [#2919, #2798]

View File

@ -20,6 +20,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2019-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state).
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter. // 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
// 2019-04-23: Inputs: Added support for SDL_GameController (if ImGuiConfigFlags_NavEnableGamepad is set by user application). // 2019-04-23: Inputs: Added support for SDL_GameController (if ImGuiConfigFlags_NavEnableGamepad is set by user application).
@ -72,6 +73,7 @@ static Uint64 g_Time = 0;
static bool g_MousePressed[3] = { false, false, false }; static bool g_MousePressed[3] = { false, false, false };
static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {};
static char* g_ClipboardTextData = NULL; static char* g_ClipboardTextData = NULL;
static bool g_MouseCanUseGlobalState = true;
// Forward Declarations // Forward Declarations
static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context); static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context);
@ -191,6 +193,7 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, void* sdl_gl_context)
io.GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText; io.GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText;
io.ClipboardUserData = NULL; io.ClipboardUserData = NULL;
// Load mouse cursors
g_MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); g_MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
g_MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); g_MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
g_MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); g_MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL);
@ -201,6 +204,9 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, void* sdl_gl_context)
g_MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); g_MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
g_MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO); g_MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
// Check and store if we are on Wayland
g_MouseCanUseGlobalState = strncmp(SDL_GetCurrentVideoDriver(), "wayland", 7) != 0;
// Our mouse update function expect PlatformHandle to be filled for the main viewport // Our mouse update function expect PlatformHandle to be filled for the main viewport
ImGuiViewport* main_viewport = ImGui::GetMainViewport(); ImGuiViewport* main_viewport = ImGui::GetMainViewport();
main_viewport->PlatformHandle = (void*)window; main_viewport->PlatformHandle = (void*)window;
@ -291,26 +297,34 @@ static void ImGui_ImplSDL2_UpdateMousePosAndButtons()
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) #if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS)
// SDL 2.0.4 and later has SDL_GetGlobalMouseState() and SDL_CaptureMouse() if (g_MouseCanUseGlobalState)
int mouse_x_global, mouse_y_global;
SDL_GetGlobalMouseState(&mouse_x_global, &mouse_y_global);
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{ {
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor) // SDL 2.0.4 and later has SDL_GetGlobalMouseState() and SDL_CaptureMouse()
if (SDL_Window* focused_window = SDL_GetKeyboardFocus()) int mouse_x_global, mouse_y_global;
if (ImGui::FindViewportByPlatformHandle((void*)focused_window) != NULL) SDL_GetGlobalMouseState(&mouse_x_global, &mouse_y_global);
io.MousePos = ImVec2((float)mouse_x_global, (float)mouse_y_global);
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
if (SDL_Window* focused_window = SDL_GetKeyboardFocus())
if (ImGui::FindViewportByPlatformHandle((void*)focused_window) != NULL)
io.MousePos = ImVec2((float)mouse_x_global, (float)mouse_y_global);
}
else
{
// Single-viewport mode: mouse position in client window coordinatesio.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS)
{
int window_x, window_y;
SDL_GetWindowPosition(g_Window, &window_x, &window_y);
io.MousePos = ImVec2((float)(mouse_x_global - window_x), (float)(mouse_y_global - window_y));
}
}
} }
else else
{ {
// Single-viewport mode: mouse position in client window coordinatesio.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS) if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS)
{ io.MousePos = ImVec2((float)mouse_x_local, (float)mouse_y_local);
int window_x, window_y;
SDL_GetWindowPosition(g_Window, &window_x, &window_y);
io.MousePos = ImVec2((float)(mouse_x_global - window_x), (float)(mouse_y_global - window_y));
}
} }
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger the OS window resize cursor. // SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger the OS window resize cursor.

144
imgui.cpp
View File

@ -45,7 +45,8 @@ CODE
// [SECTION] FORWARD DECLARATIONS // [SECTION] FORWARD DECLARATIONS
// [SECTION] CONTEXT AND MEMORY ALLOCATORS // [SECTION] CONTEXT AND MEMORY ALLOCATORS
// [SECTION] MAIN USER FACING STRUCTURES (ImGuiStyle, ImGuiIO) // [SECTION] MAIN USER FACING STRUCTURES (ImGuiStyle, ImGuiIO)
// [SECTION] MISC HELPERS/UTILITIES (Geometry, String, Format, Hash, File functions) // [SECTION] MISC HELPERS/UTILITIES (Geometry functions)
// [SECTION] MISC HELPERS/UTILITIES (String, Format, Hash functions)
// [SECTION] MISC HELPERS/UTILITIES (File functions) // [SECTION] MISC HELPERS/UTILITIES (File functions)
// [SECTION] MISC HELPERS/UTILITIES (ImText* functions) // [SECTION] MISC HELPERS/UTILITIES (ImText* functions)
// [SECTION] MISC HELPERS/UTILITIES (Color functions) // [SECTION] MISC HELPERS/UTILITIES (Color functions)
@ -364,6 +365,7 @@ CODE
- 2019/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api. - 2019/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
- 2019/12/17 (1.75) - made Columns() limited to 64 columns by asserting above that limit. While the current code technically supports it, future code may not so we're putting the restriction ahead.
- 2019/12/13 (1.75) - [imgui_internal.h] changed ImRect() default constructor initializes all fields to 0.0f instead of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by adding multiple points into it, you may need to fix your initial value. - 2019/12/13 (1.75) - [imgui_internal.h] changed ImRect() default constructor initializes all fields to 0.0f instead of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by adding multiple points into it, you may need to fix your initial value.
- 2019/12/08 (1.75) - removed redirecting functions/enums that were marked obsolete in 1.53 (December 2017): - 2019/12/08 (1.75) - removed redirecting functions/enums that were marked obsolete in 1.53 (December 2017):
- ShowTestWindow() -> use ShowDemoWindow() - ShowTestWindow() -> use ShowDemoWindow()
@ -1143,9 +1145,77 @@ void ImGuiIO::ClearInputCharacters()
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] MISC HELPERS/UTILITIES (Geometry, String, Format, Hash, File functions) // [SECTION] MISC HELPERS/UTILITIES (Geometry functions)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ImVec2 ImBezierClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments)
{
IM_ASSERT(num_segments > 0); // Use ImBezierClosestPointCasteljau()
ImVec2 p_last = p1;
ImVec2 p_closest;
float p_closest_dist2 = FLT_MAX;
float t_step = 1.0f / (float)num_segments;
for (int i_step = 1; i_step <= num_segments; i_step++)
{
ImVec2 p_current = ImBezierCalc(p1, p2, p3, p4, t_step * i_step);
ImVec2 p_line = ImLineClosestPoint(p_last, p_current, p);
float dist2 = ImLengthSqr(p - p_line);
if (dist2 < p_closest_dist2)
{
p_closest = p_line;
p_closest_dist2 = dist2;
}
p_last = p_current;
}
return p_closest;
}
// Closely mimics PathBezierToCasteljau() in imgui_draw.cpp
static void BezierClosestPointCasteljauStep(const ImVec2& p, ImVec2& p_closest, ImVec2& p_last, float& p_closest_dist2, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level)
{
float dx = x4 - x1;
float dy = y4 - y1;
float d2 = ((x2 - x4) * dy - (y2 - y4) * dx);
float d3 = ((x3 - x4) * dy - (y3 - y4) * dx);
d2 = (d2 >= 0) ? d2 : -d2;
d3 = (d3 >= 0) ? d3 : -d3;
if ((d2+d3) * (d2+d3) < tess_tol * (dx*dx + dy*dy))
{
ImVec2 p_current(x4, y4);
ImVec2 p_line = ImLineClosestPoint(p_last, p_current, p);
float dist2 = ImLengthSqr(p - p_line);
if (dist2 < p_closest_dist2)
{
p_closest = p_line;
p_closest_dist2 = dist2;
}
p_last = p_current;
}
else if (level < 10)
{
float x12 = (x1+x2)*0.5f, y12 = (y1+y2)*0.5f;
float x23 = (x2+x3)*0.5f, y23 = (y2+y3)*0.5f;
float x34 = (x3+x4)*0.5f, y34 = (y3+y4)*0.5f;
float x123 = (x12+x23)*0.5f, y123 = (y12+y23)*0.5f;
float x234 = (x23+x34)*0.5f, y234 = (y23+y34)*0.5f;
float x1234 = (x123+x234)*0.5f, y1234 = (y123+y234)*0.5f;
BezierClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1);
BezierClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1);
}
}
// tess_tol is generally the same value you would find in ImGui::GetStyle().CurveTessellationTol
// Because those ImXXX functions are lower-level than ImGui:: we cannot access this value automatically.
ImVec2 ImBezierClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol)
{
IM_ASSERT(tess_tol > 0.0f);
ImVec2 p_last = p1;
ImVec2 p_closest;
float p_closest_dist2 = FLT_MAX;
BezierClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, tess_tol, 0);
return p_closest;
}
ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p) ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p)
{ {
ImVec2 ap = p - a; ImVec2 ap = p - a;
@ -1194,6 +1264,10 @@ ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c,
return proj_ca; return proj_ca;
} }
//-----------------------------------------------------------------------------
// [SECTION] MISC HELPERS/UTILITIES (String, Format, Hash functions)
//-----------------------------------------------------------------------------
// Consider using _stricmp/_strnicmp under Windows or strcasecmp/strncasecmp. We don't actually use either ImStricmp/ImStrnicmp in the codebase any more. // Consider using _stricmp/_strnicmp under Windows or strcasecmp/strncasecmp. We don't actually use either ImStricmp/ImStrnicmp in the codebase any more.
int ImStricmp(const char* str1, const char* str2) int ImStricmp(const char* str1, const char* str2)
{ {
@ -1764,38 +1838,6 @@ void ImGui::ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float&
} }
} }
ImU32 ImGui::GetColorU32(ImGuiCol idx, float alpha_mul)
{
ImGuiStyle& style = GImGui->Style;
ImVec4 c = style.Colors[idx];
c.w *= style.Alpha * alpha_mul;
return ColorConvertFloat4ToU32(c);
}
ImU32 ImGui::GetColorU32(const ImVec4& col)
{
ImGuiStyle& style = GImGui->Style;
ImVec4 c = col;
c.w *= style.Alpha;
return ColorConvertFloat4ToU32(c);
}
const ImVec4& ImGui::GetStyleColorVec4(ImGuiCol idx)
{
ImGuiStyle& style = GImGui->Style;
return style.Colors[idx];
}
ImU32 ImGui::GetColorU32(ImU32 col)
{
float style_alpha = GImGui->Style.Alpha;
if (style_alpha >= 1.0f)
return col;
ImU32 a = (col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT;
a = (ImU32)(a * style_alpha); // We don't need to clamp 0..255 because Style.Alpha is in 0..1 range.
return (col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] ImGuiStorage // [SECTION] ImGuiStorage
// Helper: Key->value storage // Helper: Key->value storage
@ -2253,10 +2295,42 @@ bool ImGuiListClipper::Step()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] RENDER HELPERS // [SECTION] RENDER HELPERS
// Those (internal) functions are currently quite a legacy mess - their signature and behavior will change. // Some of those (internal) functions are currently quite a legacy mess - their signature and behavior will change.
// Also see imgui_draw.cpp for some more which have been reworked to not rely on ImGui:: state. // Also see imgui_draw.cpp for some more which have been reworked to not rely on ImGui:: state.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ImU32 ImGui::GetColorU32(ImGuiCol idx, float alpha_mul)
{
ImGuiStyle& style = GImGui->Style;
ImVec4 c = style.Colors[idx];
c.w *= style.Alpha * alpha_mul;
return ColorConvertFloat4ToU32(c);
}
ImU32 ImGui::GetColorU32(const ImVec4& col)
{
ImGuiStyle& style = GImGui->Style;
ImVec4 c = col;
c.w *= style.Alpha;
return ColorConvertFloat4ToU32(c);
}
const ImVec4& ImGui::GetStyleColorVec4(ImGuiCol idx)
{
ImGuiStyle& style = GImGui->Style;
return style.Colors[idx];
}
ImU32 ImGui::GetColorU32(ImU32 col)
{
ImGuiStyle& style = GImGui->Style;
if (style.Alpha >= 1.0f)
return col;
ImU32 a = (col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT;
a = (ImU32)(a * style.Alpha); // We don't need to clamp 0..255 because Style.Alpha is in 0..1 range.
return (col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT);
}
const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end) const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end)
{ {
const char* text_display_end = text; const char* text_display_end = text;

View File

@ -596,6 +596,7 @@ namespace ImGui
// Columns // Columns
// - You can also use SameLine(pos_x) to mimic simplified columns. // - You can also use SameLine(pos_x) to mimic simplified columns.
// - The columns API is work-in-progress and rather lacking (columns are arguably the worst part of dear imgui at the moment!) // - The columns API is work-in-progress and rather lacking (columns are arguably the worst part of dear imgui at the moment!)
// - There is a maximum of 64 columns.
// - By end of the 2019 we will expose a new 'Table' api which will replace columns. // - By end of the 2019 we will expose a new 'Table' api which will replace columns.
IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true);
IMGUI_API void NextColumn(); // next column, defaults to current row or next row if the current row is finished IMGUI_API void NextColumn(); // next column, defaults to current row or next row if the current row is finished
@ -2042,7 +2043,7 @@ struct ImDrawList
IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, bool closed, float thickness); IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, bool closed, float thickness);
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); // Note: Anti-aliased filling requires points to be in clockwise order. IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); // Note: Anti-aliased filling requires points to be in clockwise order.
IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0); IMGUI_API void AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0);
// Image primitives // Image primitives
// - Read FAQ to understand what ImTextureID is. // - Read FAQ to understand what ImTextureID is.
@ -2060,7 +2061,7 @@ struct ImDrawList
inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); _Path.Size = 0; } inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); _Path.Size = 0; }
IMGUI_API void PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 10); IMGUI_API void PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 10);
IMGUI_API void PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle IMGUI_API void PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle
IMGUI_API void PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0); IMGUI_API void PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0);
IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawCornerFlags rounding_corners = ImDrawCornerFlags_All); IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawCornerFlags rounding_corners = ImDrawCornerFlags_All);
// Advanced // Advanced

View File

@ -913,6 +913,17 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
} }
} }
ImVec2 ImBezierCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t)
{
float u = 1.0f - t;
float w1 = u*u*u;
float w2 = 3*u*u*t;
float w3 = 3*u*t*t;
float w4 = t*t*t;
return ImVec2(w1*p1.x + w2*p2.x + w3*p3.x + w4*p4.x, w1*p1.y + w2*p2.y + w3*p3.y + w4*p4.y);
}
// Closely mimics BezierClosestPointCasteljauStep() in imgui.cpp
static void PathBezierToCasteljau(ImVector<ImVec2>* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level) static void PathBezierToCasteljau(ImVector<ImVec2>* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level)
{ {
float dx = x4 - x1; float dx = x4 - x1;
@ -933,7 +944,6 @@ static void PathBezierToCasteljau(ImVector<ImVec2>* path, float x1, float y1, fl
float x123 = (x12+x23)*0.5f, y123 = (y12+y23)*0.5f; float x123 = (x12+x23)*0.5f, y123 = (y12+y23)*0.5f;
float x234 = (x23+x34)*0.5f, y234 = (y23+y34)*0.5f; float x234 = (x23+x34)*0.5f, y234 = (y23+y34)*0.5f;
float x1234 = (x123+x234)*0.5f, y1234 = (y123+y234)*0.5f; float x1234 = (x123+x234)*0.5f, y1234 = (y123+y234)*0.5f;
PathBezierToCasteljau(path, x1,y1, x12,y12, x123,y123, x1234,y1234, tess_tol, level+1); PathBezierToCasteljau(path, x1,y1, x12,y12, x123,y123, x1234,y1234, tess_tol, level+1);
PathBezierToCasteljau(path, x1234,y1234, x234,y234, x34,y34, x4,y4, tess_tol, level+1); PathBezierToCasteljau(path, x1234,y1234, x234,y234, x34,y34, x4,y4, tess_tol, level+1);
} }
@ -944,22 +954,13 @@ void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImV
ImVec2 p1 = _Path.back(); ImVec2 p1 = _Path.back();
if (num_segments == 0) if (num_segments == 0)
{ {
// Auto-tessellated PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); // Auto-tessellated
PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0);
} }
else else
{ {
float t_step = 1.0f / (float)num_segments; float t_step = 1.0f / (float)num_segments;
for (int i_step = 1; i_step <= num_segments; i_step++) for (int i_step = 1; i_step <= num_segments; i_step++)
{ _Path.push_back(ImBezierCalc(p1, p2, p3, p4, t_step * i_step));
float t = t_step * i_step;
float u = 1.0f - t;
float w1 = u*u*u;
float w2 = 3*u*u*t;
float w3 = 3*u*t*t;
float w4 = t*t*t;
_Path.push_back(ImVec2(w1*p1.x + w2*p2.x + w3*p3.x + w4*p4.x, w1*p1.y + w2*p2.y + w3*p3.y + w4*p4.y));
}
} }
} }
@ -1134,13 +1135,14 @@ void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, in
PathFillConvex(col); PathFillConvex(col);
} }
void ImDrawList::AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments) // Cubic Bezier takes 4 controls points
void ImDrawList::AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments)
{ {
if ((col & IM_COL32_A_MASK) == 0) if ((col & IM_COL32_A_MASK) == 0)
return; return;
PathLineTo(pos0); PathLineTo(p1);
PathBezierCurveTo(cp0, cp1, pos1, num_segments); PathBezierCurveTo(p2, p3, p4, num_segments);
PathStroke(col, false, thickness); PathStroke(col, false, thickness);
} }

View File

@ -203,6 +203,8 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Generic helpers // Generic helpers
// Note that the ImXXX helpers functions are lower-level than ImGui functions.
// ImGui functions or the ImGui context are never called/used from other ImXXX functions.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// - Helpers: Misc // - Helpers: Misc
// - Helpers: Bit manipulation // - Helpers: Bit manipulation
@ -349,6 +351,9 @@ static inline float ImLinearSweep(float current, float target, float speed)
static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
// Helpers: Geometry // Helpers: Geometry
IMGUI_API ImVec2 ImBezierCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t); // Cubic Bezier
IMGUI_API ImVec2 ImBezierClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments); // For curves with explicit number of segments
IMGUI_API ImVec2 ImBezierClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol);// For auto-tessellated curves you can use tess_tol = style.CurveTessellationTol
IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p); IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p);
IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);
IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);

View File

@ -1266,21 +1266,14 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags)
// We don't provide our width to the layout so that it doesn't get feed back into AutoFit // We don't provide our width to the layout so that it doesn't get feed back into AutoFit
const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y + thickness_draw)); const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y + thickness_draw));
ItemSize(ImVec2(0.0f, thickness_layout)); ItemSize(ImVec2(0.0f, thickness_layout));
if (!ItemAdd(bb, 0)) const bool item_visible = ItemAdd(bb, 0);
if (item_visible)
{ {
if (columns) // Draw
{ window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x, bb.Min.y), GetColorU32(ImGuiCol_Separator));
PopColumnsBackground(); if (g.LogEnabled)
columns->LineMinY = window->DC.CursorPos.y; LogRenderedText(&bb.Min, "--------------------------------");
}
return;
} }
// Draw
window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x, bb.Min.y), GetColorU32(ImGuiCol_Separator));
if (g.LogEnabled)
LogRenderedText(&bb.Min, "--------------------------------");
if (columns) if (columns)
{ {
PopColumnsBackground(); PopColumnsBackground();
@ -7528,8 +7521,8 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
IM_ASSERT(columns_count >= 1); IM_ASSERT(columns_count >= 1 && columns_count <= 64); // Maximum 64 columns
IM_ASSERT(window->DC.CurrentColumns == NULL); // Nested columns are currently not supported IM_ASSERT(window->DC.CurrentColumns == NULL); // Nested columns are currently not supported
// Acquire storage for the columns set // Acquire storage for the columns set
ImGuiID id = GetColumnsID(str_id, columns_count); ImGuiID id = GetColumnsID(str_id, columns_count);