summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx
diff options
context:
space:
mode:
author Branimir Karadžić <branimirkaradzic@gmail.com>2016-05-03 12:20:29 +0200
committer Miodrag Milanovic <mmicko@gmail.com>2016-05-03 12:20:29 +0200
commitf97b68d3ed8312f0800fc0e501ad0174a968d3e9 (patch)
treebf876c8732bd657d05908876ae88e1736f306610 /3rdparty/bgfx
parentf2aca844f6bbfcc0d1284d6dd546cd552cbe0a92 (diff)
Update GENie, BGFX and BX (nw)
Diffstat (limited to '3rdparty/bgfx')
-rw-r--r--3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_print_metal_visitor.cpp12
-rw-r--r--3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp362
-rw-r--r--3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h57
-rw-r--r--3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp65
-rw-r--r--3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp63
-rw-r--r--3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h36
-rw-r--r--3rdparty/bgfx/README.md3
-rw-r--r--3rdparty/bgfx/examples/00-helloworld/helloworld.cpp191
-rw-r--r--3rdparty/bgfx/makefile12
-rw-r--r--3rdparty/bgfx/scripts/geometryc.lua5
-rw-r--r--3rdparty/bgfx/scripts/shaderc.lua3
-rw-r--r--3rdparty/bgfx/scripts/texturec.lua7
-rw-r--r--3rdparty/bgfx/scripts/texturev.lua2
-rw-r--r--3rdparty/bgfx/src/bgfx.cpp5
-rw-r--r--3rdparty/bgfx/tools/shaderc/shaderc_glsl.cpp7
-rw-r--r--3rdparty/bgfx/tools/texturev/texturev.cpp2
16 files changed, 456 insertions, 376 deletions
diff --git a/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_print_metal_visitor.cpp b/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_print_metal_visitor.cpp
index f9988a31f61..9f7071d9564 100644
--- a/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_print_metal_visitor.cpp
+++ b/3rdparty/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_print_metal_visitor.cpp
@@ -1020,7 +1020,17 @@ void ir_print_metal_visitor::visit(ir_expression *ir)
const bool halfCast = (arg_prec == glsl_precision_medium || arg_prec == glsl_precision_low);
buffer.asprintf_append (halfCast ? "((half)1.0/(" : "(1.0/(");
} else {
- buffer.asprintf_append ("%s(", operator_glsl_strs[ir->operation]);
+ switch(ir->operation) {
+ case ir_unop_dFdy:
+ case ir_unop_dFdy_coarse:
+ case ir_unop_dFdy_fine:
+ buffer.asprintf_append ("%s(-", operator_glsl_strs[ir->operation]);
+ break;
+
+ default:
+ buffer.asprintf_append ("%s(", operator_glsl_strs[ir->operation]);
+ break;
+ }
}
if (ir->operands[0])
ir->operands[0]->accept(this);
diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp
index 91a03843a52..51d5acb4d3b 100644
--- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp
+++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp
@@ -152,6 +152,8 @@
Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
Also read releases logs https://github.com/ocornut/imgui/releases for more details.
+ - 2016/05/01 (1.49) - obsoleted old signature of CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false) as extra parameters were badly designed and rarely used. You can replace the "default_open = true" flag in new API with CollapsingHeader(label, ImGuiTreeNodeFlags_DefaultOpen).
+ - 2016/04/26 (1.49) - changed ImDrawList::PushClipRect(ImVec4 rect) to ImDraw::PushClipRect(Imvec2 min,ImVec2 max,bool intersect_with_current_clip_rect=false). Note that higher-level ImGui::PushClipRect() is preferable because it will clip at logic/widget level, whereas ImDrawList::PushClipRect() only affect your renderer.
- 2016/04/03 (1.48) - removed style.WindowFillAlphaDefault setting which was redundant. Bake default BG alpha inside style.Colors[ImGuiCol_WindowBg] and all other Bg color values. (ref github issue #337).
- 2016/04/03 (1.48) - renamed ImGuiCol_TooltipBg to ImGuiCol_PopupBg, used by popups/menus and tooltips. popups/menus were previously using ImGuiCol_WindowBg. (ref github issue #337)
- 2016/03/21 (1.48) - renamed GetWindowFont() to GetFont(), GetWindowFontSize() to GetFontSize(). Kept inline redirection function (will obsolete).
@@ -410,13 +412,17 @@
io.Fonts->LoadFromFileTTF("myfontfile.ttf", size_pixels, NULL, &config, io.Fonts->GetGlyphRangesJapanese());
Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
- A: When loading a font, pass custom Unicode ranges to specify the glyphs to load. ImGui will support UTF-8 encoding across the board.
- Character input depends on you passing the right character code to io.AddInputCharacter(). The example applications do that.
+ A: When loading a font, pass custom Unicode ranges to specify the glyphs to load.
+ All strings passed need to use UTF-8 encoding. Specifying literal in your source code using a local code page (such as CP-923 for Japanese CP-1251 for Cyrillic) will not work.
+ In C++11 you can encode a string literal in UTF-8 by using the u8"hello" syntax. Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8.
+ You can also try to remap your local codepage characters to their Unicode codepoint using font->AddRemapChar(), but international users may have problems reading/editing your source code.
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, io.Fonts->GetGlyphRangesJapanese()); // Load Japanese characters
io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8()
io.ImeWindowHandle = MY_HWND; // To input using Microsoft IME, give ImGui the hwnd of your application
+ As for text input, depends on you passing the right character code to io.AddInputCharacter(). The example applications do that.
+
- tip: the construct 'IMGUI_ONCE_UPON_A_FRAME { ... }' will run the block of code only once a frame. You can use it to quickly add custom UI in the middle of a deep nested inner loop in your code.
- tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug"
- tip: you can call Begin() multiple times with the same name during the same frame, it will keep appending to the same window. this is also useful to set yourself in the context of another window (to get/set other settings)
@@ -537,7 +543,7 @@
- style: WindowPadding needs to be EVEN needs the 0.5 multiplier probably have a subtle effect on clip rectangle
- text: simple markup language for color change?
- font: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier.
- - font: helper to add glyph redirect/replacements (e.g. redirect alternate apostrophe unicode code points to ascii one, etc.)
+ - font: fix AddRemapChar() to work before font has been built.
- log: LogButtons() options for specifying depth and/or hiding depth slider
- log: have more control over the log scope (e.g. stop logging when leaving current tree node scope)
- log: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard)
@@ -547,6 +553,7 @@
- shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus)
!- keyboard: tooltip & combo boxes are messing up / not honoring keyboard tabbing
- keyboard: full keyboard navigation and focus. (#323)
+ - focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622)
- focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame)
- input: rework IO system to be able to pass actual ordered/timestamped events.
- input: allow to decide and pass explicit double-clicks (e.g. for windows by the CS_DBLCLKS style).
@@ -557,7 +564,6 @@
- style editor: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438)
- style editor: color child window height expressed in multiple of line height.
- remote: make a system like RemoteImGui first-class citizen/project (#75)
-!- demo: custom render demo pushes a clipping rectangle past parent window bounds. expose ImGui::PushClipRect() from imgui_internal.h?
- drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack.
- examples: directx9: save/restore device state more thoroughly.
- examples: window minimize, maximize (#583)
@@ -704,7 +710,7 @@ ImGuiStyle::ImGuiStyle()
ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines
ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label)
TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much!
- IndentSpacing = 22.0f; // Horizontal spacing when e.g. entering a tree node
+ IndentSpacing = 21.0f; // Horizontal spacing when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2).
ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns
ScrollbarSize = 16.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar
ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar
@@ -1718,29 +1724,22 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id)
ImGuiWindow* window = GetCurrentWindow();
window->DC.LastItemID = id ? *id : 0;
window->DC.LastItemRect = bb;
+ window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false;
if (IsClippedEx(bb, id, false))
- {
- window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false;
return false;
- }
// This is a sensible default, but widgets are free to override it after calling ItemAdd()
ImGuiState& g = *GImGui;
if (IsMouseHoveringRect(bb.Min, bb.Max))
{
- // Matching the behavior of IsHovered() but ignore if ActiveId==window->MoveID (we clicked on the window background)
+ // Matching the behavior of IsHovered() but allow if ActiveId==window->MoveID (we clicked on the window background)
// So that clicking on items with no active id such as Text() still returns true with IsItemHovered()
window->DC.LastItemHoveredRect = true;
- window->DC.LastItemHoveredAndUsable = false;
if (g.HoveredRootWindow == window->RootWindow)
if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdAllowOverlap || (g.ActiveId == window->MoveID))
if (IsWindowContentHoverable(window))
window->DC.LastItemHoveredAndUsable = true;
}
- else
- {
- window->DC.LastItemHoveredAndUsable = window->DC.LastItemHoveredRect = false;
- }
return true;
}
@@ -1751,14 +1750,13 @@ bool ImGui::IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when
ImGuiWindow* window = GetCurrentWindowRead();
if (!bb.Overlaps(window->ClipRect))
- {
if (!id || *id != GImGui->ActiveId)
if (clip_even_when_logged || !g.LogEnabled)
return true;
- }
return false;
}
+// NB: This is an internal helper. The user-facing IsItemHovered() is using data emitted from ItemAdd(), with a slightly different logic.
bool ImGui::IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs)
{
ImGuiState& g = *GImGui;
@@ -1766,7 +1764,7 @@ bool ImGui::IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs)
{
ImGuiWindow* window = GetCurrentWindowRead();
if (g.HoveredWindow == window || (flatten_childs && g.HoveredRootWindow == window->RootWindow))
- if ((g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdAllowOverlap) && ImGui::IsMouseHoveringRect(bb.Min, bb.Max))
+ if ((g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdAllowOverlap) && IsMouseHoveringRect(bb.Min, bb.Max))
if (IsWindowContentHoverable(g.HoveredRootWindow))
return true;
}
@@ -2369,23 +2367,12 @@ static void AddWindowToRenderList(ImVector<ImDrawList*>& out_render_list, ImGuiW
}
}
-void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_existing_clip_rect)
+// When using this function it is sane to ensure that float are perfectly rounded to integer values, to that e.g. (int)(max.x-min.x) in user's render produce correct result.
+void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect)
{
ImGuiWindow* window = GetCurrentWindow();
-
- ImRect cr(clip_rect_min, clip_rect_max);
- if (intersect_with_existing_clip_rect) // Clip our argument with the current clip rect
- cr.Clip(window->ClipRect);
- cr.Max.x = ImMax(cr.Min.x, cr.Max.x);
- cr.Max.y = ImMax(cr.Min.y, cr.Max.y);
- cr.Min.x = (float)(int)(cr.Min.x + 0.5f); // Round (expecting to round down). Ensure that e.g. (int)(max.x-min.x) in user code produce correct result.
- cr.Min.y = (float)(int)(cr.Min.y + 0.5f);
- cr.Max.x = (float)(int)(cr.Max.x + 0.5f);
- cr.Max.y = (float)(int)(cr.Max.y + 0.5f);
-
- IM_ASSERT(cr.Min.x <= cr.Max.x && cr.Min.y <= cr.Max.y);
- window->ClipRect = cr;
- window->DrawList->PushClipRect(ImVec4(cr.Min.x, cr.Min.y, cr.Max.x, cr.Max.y));
+ window->DrawList->PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect);
+ window->ClipRect = window->DrawList->_ClipRectStack.back();
}
void ImGui::PopClipRect()
@@ -2756,6 +2743,12 @@ void ImGui::RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale, bool
window->DrawList->AddTriangleFilled(a, b, c, GetColorU32(ImGuiCol_Text));
}
+void ImGui::RenderBullet(ImVec2 pos)
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ window->DrawList->AddCircleFilled(pos, GImGui->FontSize*0.20f, GetColorU32(ImGuiCol_Text), 8);
+}
+
void ImGui::RenderCheckMark(ImVec2 pos, ImU32 col)
{
ImGuiState& g = *GImGui;
@@ -3070,6 +3063,11 @@ bool ImGui::IsItemActive()
return false;
}
+bool ImGui::IsItemClicked(int mouse_button)
+{
+ return IsMouseClicked(mouse_button) && IsItemHovered();
+}
+
bool ImGui::IsAnyItemHovered()
{
return GImGui->HoveredId != 0 || GImGui->HoveredIdPreviousFrame != 0;
@@ -3224,8 +3222,8 @@ static void CloseInactivePopups()
static ImGuiWindow* GetFrontMostModalRootWindow()
{
ImGuiState& g = *GImGui;
- if (!g.OpenedPopupStack.empty())
- if (ImGuiWindow* front_most_popup = g.OpenedPopupStack.back().Window)
+ for (int n = g.OpenedPopupStack.Size-1; n >= 0; n--)
+ if (ImGuiWindow* front_most_popup = g.OpenedPopupStack.Data[n].Window)
if (front_most_popup->Flags & ImGuiWindowFlags_Modal)
return front_most_popup;
return NULL;
@@ -4131,11 +4129,11 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
// 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 float border_size = window->BorderSize;
- ImRect clip_rect;
- clip_rect.Min.x = title_bar_rect.Min.x + ImMax(border_size, (float)(int)(window->WindowPadding.x*0.5f));
- clip_rect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight() + border_size;
- clip_rect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x - ImMax(border_size, (float)(int)(window->WindowPadding.x*0.5f));
- clip_rect.Max.y = window->Pos.y + window->Size.y - border_size - window->ScrollbarSizes.y;
+ ImRect clip_rect; // Force round to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result.
+ 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.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.y = ImFloor(0.5f + window->Pos.y + window->Size.y - window->ScrollbarSizes.y - border_size);
PushClipRect(clip_rect.Min, clip_rect.Max, true);
// Clear 'accessed' flag last thing
@@ -4595,15 +4593,19 @@ bool ImGui::IsWindowFocused()
bool ImGui::IsRootWindowFocused()
{
ImGuiState& g = *GImGui;
- ImGuiWindow* root_window = g.CurrentWindow->RootWindow;
- return g.FocusedWindow == root_window;
+ return g.FocusedWindow == g.CurrentWindow->RootWindow;
}
bool ImGui::IsRootWindowOrAnyChildFocused()
{
ImGuiState& g = *GImGui;
- ImGuiWindow* root_window = g.CurrentWindow->RootWindow;
- return g.FocusedWindow && g.FocusedWindow->RootWindow == root_window;
+ return g.FocusedWindow && g.FocusedWindow->RootWindow == g.CurrentWindow->RootWindow;
+}
+
+bool ImGui::IsRootWindowOrAnyChildHovered()
+{
+ ImGuiState& g = *GImGui;
+ return g.HoveredRootWindow && (g.HoveredRootWindow == g.CurrentWindow->RootWindow) && IsWindowContentHoverable(g.HoveredRootWindow);
}
float ImGui::GetWindowWidth()
@@ -5271,39 +5273,34 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
return false;
}
+ if ((flags & (ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick)) == 0)
+ flags |= ImGuiButtonFlags_PressedOnClickRelease;
+
bool pressed = false;
- const bool hovered = IsHovered(bb, id, (flags & ImGuiButtonFlags_FlattenChilds) != 0);
+ bool hovered = IsHovered(bb, id, (flags & ImGuiButtonFlags_FlattenChilds) != 0);
if (hovered)
{
SetHoveredID(id);
if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt))
{
- if (g.IO.MouseDoubleClicked[0] && (flags & ImGuiButtonFlags_PressedOnDoubleClick))
+ if ((flags & ImGuiButtonFlags_PressedOnClickRelease) && g.IO.MouseClicked[0]) // Most common type
{
- pressed = true;
- }
- else if (g.IO.MouseClicked[0])
- {
- if (flags & ImGuiButtonFlags_PressedOnClick)
- {
- pressed = true;
- SetActiveID(0);
- }
- else
- {
- SetActiveID(id, window);
- }
+ SetActiveID(id, window); // Hold on ID
FocusWindow(window);
}
- else if (g.IO.MouseReleased[0] && (flags & ImGuiButtonFlags_PressedOnRelease))
+ if (((flags & ImGuiButtonFlags_PressedOnClick) && g.IO.MouseClicked[0]) || ((flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDoubleClicked[0]))
{
pressed = true;
SetActiveID(0);
+ FocusWindow(window);
}
- else if ((flags & ImGuiButtonFlags_Repeat) && g.ActiveId == id && ImGui::IsMouseClicked(0, true))
+ if ((flags & ImGuiButtonFlags_PressedOnRelease) && g.IO.MouseReleased[0])
{
pressed = true;
+ SetActiveID(0);
}
+ if ((flags & ImGuiButtonFlags_Repeat) && g.ActiveId == id && ImGui::IsMouseClicked(0, true))
+ pressed = true;
}
}
@@ -5316,12 +5313,16 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
}
else
{
- if (hovered)
+ if (hovered && (flags & ImGuiButtonFlags_PressedOnClickRelease))
pressed = true;
SetActiveID(0);
}
}
+ // AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. This allows using patterns where a later submitted widget overlaps a previous one.
+ if (hovered && (flags & ImGuiButtonFlags_AllowOverlapMode) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0))
+ hovered = pressed = held = false;
+
if (out_hovered) *out_hovered = hovered;
if (out_held) *out_held = held;
@@ -5602,6 +5603,9 @@ void ImGui::LogButtons()
bool ImGui::TreeNodeBehaviorIsOpened(ImGuiID id, ImGuiTreeNodeFlags flags)
{
+ if (flags & ImGuiTreeNodeFlags_AlwaysOpen)
+ return true;
+
// We only write to the tree storage if the user clicks (or explicitely use SetNextTreeNode*** functions)
ImGuiState& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
@@ -5638,14 +5642,13 @@ bool ImGui::TreeNodeBehaviorIsOpened(ImGuiID id, ImGuiTreeNodeFlags flags)
// When logging is enabled, we automatically expand tree nodes (but *NOT* collapsing headers.. seems like sensible behavior).
// NB- If we are above max depth we still allow manually opened nodes to be logged.
- if (g.LogEnabled && !(flags & ImGuiTreeNodeFlags_NoAutoExpandOnLog) && window->DC.TreeDepth < g.LogAutoExpandMaxDepth)
+ if (g.LogEnabled && !(flags & ImGuiTreeNodeFlags_NoAutoOpenOnLog) && window->DC.TreeDepth < g.LogAutoExpandMaxDepth)
opened = true;
return opened;
}
-// FIXME: Split into CollapsingHeader(label, default_open?) and TreeNodeBehavior(label), obsolete the 4 parameters function.
-bool ImGui::CollapsingHeader(const char* label, const char* str_id, bool display_frame, bool default_open)
+bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
@@ -5653,20 +5656,16 @@ bool ImGui::CollapsingHeader(const char* label, const char* str_id, bool display
ImGuiState& g = *GImGui;
const ImGuiStyle& style = g.Style;
+ const bool display_frame = (flags & ImGuiTreeNodeFlags_Framed) != 0;
const ImVec2 padding = display_frame ? style.FramePadding : ImVec2(style.FramePadding.x, 0.0f);
- IM_ASSERT(str_id != NULL || label != NULL);
- if (str_id == NULL)
- str_id = label;
- if (label == NULL)
- label = str_id;
- const bool label_hide_text_after_double_hash = (label == str_id); // Only search and hide text after ## if we have passed label and ID separately, otherwise allow "##" within format string.
- const ImGuiID id = window->GetID(str_id);
- const ImVec2 label_size = CalcTextSize(label, NULL, label_hide_text_after_double_hash);
+ if (!label_end)
+ label_end = FindRenderedTextEnd(label);
+ const ImVec2 label_size = CalcTextSize(label, label_end, false);
// We vertically grow up to current line height up the typical widget height.
const float text_base_offset_y = ImMax(0.0f, window->DC.CurrentLineTextBaseOffset - padding.y); // Latch before ItemSize changes it
- const float frame_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y*2), label_size.y + padding.y*2);
+ const float frame_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + style.FramePadding.y*2), label_size.y + padding.y*2);
ImRect bb = ImRect(window->DC.CursorPos, ImVec2(window->Pos.x + GetContentRegionMax().x, window->DC.CursorPos.y + frame_height));
if (display_frame)
{
@@ -5675,28 +5674,49 @@ bool ImGui::CollapsingHeader(const char* label, const char* str_id, bool display
bb.Max.x += (float)(int)(window->WindowPadding.x*0.5f) - 1;
}
- const float collapser_width = g.FontSize + (display_frame ? padding.x*2 : padding.x);
+ const float text_offset_x = g.FontSize + (display_frame ? padding.x*3 : padding.x*2); // Collapser arrow width + Spacing
const float text_width = g.FontSize + (label_size.x > 0.0f ? label_size.x + padding.x*2 : 0.0f); // Include collapser
ItemSize(ImVec2(text_width, frame_height), text_base_offset_y);
// For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing
// (Ideally we'd want to add a flag for the user to specify we want want the hit test to be done up to the right side of the content or not)
const ImRect interact_bb = display_frame ? bb : ImRect(bb.Min.x, bb.Min.y, bb.Min.x + text_width + style.ItemSpacing.x*2, bb.Max.y);
- bool opened = TreeNodeBehaviorIsOpened(id, (default_open ? ImGuiTreeNodeFlags_DefaultOpen : 0) | (display_frame ? ImGuiTreeNodeFlags_NoAutoExpandOnLog : 0));
+ bool opened = TreeNodeBehaviorIsOpened(id, flags);
if (!ItemAdd(interact_bb, &id))
+ {
+ if (opened && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
+ TreePushRawID(id);
return opened;
+ }
- bool hovered, held;
- bool pressed = ButtonBehavior(interact_bb, id, &hovered, &held, ImGuiButtonFlags_NoKeyModifiers);
- if (pressed)
- {
- opened = !opened;
- window->DC.StateStorage->SetInt(id, opened);
+ // Flags that affects opening behavior:
+ // - 0(default) ..................... single-click anywhere to open
+ // - OpenOnDoubleClick .............. double-click anywhere to open
+ // - OpenOnArrow .................... single-click on arrow to open
+ // - OpenOnDoubleClick|OpenOnArrow .. single-click on arrow or double-click anywhere to open
+ ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowOverlapMode) ? ImGuiButtonFlags_AllowOverlapMode : 0);
+ if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick)
+ button_flags |= ImGuiButtonFlags_PressedOnDoubleClick | ((flags & ImGuiTreeNodeFlags_OpenOnArrow) ? ImGuiButtonFlags_PressedOnClickRelease : 0);
+ bool hovered, held, pressed = ButtonBehavior(interact_bb, id, &hovered, &held, button_flags);
+ if (pressed && !(flags & ImGuiTreeNodeFlags_AlwaysOpen))
+ {
+ bool toggled = !(flags & (ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick));
+ if (flags & ImGuiTreeNodeFlags_OpenOnArrow)
+ toggled |= IsMouseHoveringRect(interact_bb.Min, ImVec2(interact_bb.Min.x + text_offset_x, interact_bb.Max.y));
+ if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick)
+ toggled |= g.IO.MouseDoubleClicked[0];
+ if (toggled)
+ {
+ opened = !opened;
+ window->DC.StateStorage->SetInt(id, opened);
+ }
}
+ if (flags & ImGuiTreeNodeFlags_AllowOverlapMode)
+ SetItemAllowOverlap();
// Render
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
- const ImVec2 text_pos = bb.Min + padding + ImVec2(collapser_width, text_base_offset_y);
+ const ImVec2 text_pos = bb.Min + ImVec2(text_offset_x, padding.y + text_base_offset_y);
if (display_frame)
{
// Framed type
@@ -5708,80 +5728,131 @@ bool ImGui::CollapsingHeader(const char* label, const char* str_id, bool display
const char log_prefix[] = "\n##";
const char log_suffix[] = "##";
LogRenderedText(text_pos, log_prefix, log_prefix+3);
- RenderTextClipped(text_pos, bb.Max, label, NULL, &label_size);
+ RenderTextClipped(text_pos, bb.Max, label, label_end, &label_size);
LogRenderedText(text_pos, log_suffix+1, log_suffix+3);
}
else
{
- RenderTextClipped(text_pos, bb.Max, label, NULL, &label_size);
+ RenderTextClipped(text_pos, bb.Max, label, label_end, &label_size);
}
}
else
{
// Unframed typed for tree nodes
- if (hovered)
+ if (hovered || (flags & ImGuiTreeNodeFlags_Selected))
RenderFrame(bb.Min, bb.Max, col, false);
- RenderCollapseTriangle(bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), opened, 0.70f, false);
+ if (flags & ImGuiTreeNodeFlags_AlwaysOpen)
+ RenderBullet(bb.Min + ImVec2(text_offset_x * 0.5f, g.FontSize*0.50f + text_base_offset_y));
+ else
+ RenderCollapseTriangle(bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), opened, 0.70f, false);
if (g.LogEnabled)
LogRenderedText(text_pos, ">");
- RenderText(text_pos, label, NULL, label_hide_text_after_double_hash);
+ RenderText(text_pos, label, label_end, false);
}
+ if (opened && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
+ TreePushRawID(id);
return opened;
}
-// If returning 'true' the node is open and the user is responsible for calling TreePop
-bool ImGui::TreeNodeV(const char* str_id, const char* fmt, va_list args)
+bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return false;
- ImGuiState& g = *GImGui;
- ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
- if (!str_id || !str_id[0])
- str_id = fmt;
+ return TreeNodeBehavior(window->GetID(label), flags | ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen, label);
+}
- ImGui::PushID(str_id);
- const bool opened = ImGui::CollapsingHeader(g.TempBuffer, "", false);
- ImGui::PopID();
+bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags)
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return false;
- if (opened)
- ImGui::TreePush(str_id);
+ if (p_open && !*p_open)
+ return false;
+
+ ImGuiID id = window->GetID(label);
+ bool opened = TreeNodeBehavior(id, flags | ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen | (p_open ? ImGuiTreeNodeFlags_AllowOverlapMode : 0), label);
+ if (p_open)
+ {
+ // Create a small overlapping close button // FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc.
+ ImGuiState& g = *GImGui;
+ float button_sz = g.FontSize * 0.5f;
+ if (CloseButton(window->GetID((void*)(intptr_t)(id+1)), ImVec2(window->DC.LastItemRect.Max.x - g.Style.FramePadding.x - button_sz, window->DC.LastItemRect.Min.y + g.Style.FramePadding.y + button_sz), button_sz))
+ *p_open = false;
+ }
return opened;
}
-bool ImGui::TreeNode(const char* str_id, const char* fmt, ...)
+bool ImGui::TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags)
{
- va_list args;
- va_start(args, fmt);
- bool s = TreeNodeV(str_id, fmt, args);
- va_end(args);
- return s;
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return false;
+
+ return TreeNodeBehavior(window->GetID(label), flags, label, NULL);
}
-// If returning 'true' the node is open and the user is responsible for calling TreePop
-bool ImGui::TreeNodeV(const void* ptr_id, const char* fmt, va_list args)
+bool ImGui::TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return false;
ImGuiState& g = *GImGui;
- ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
+ const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
+ return TreeNodeBehavior(window->GetID(str_id), flags, g.TempBuffer, label_end);
+}
- if (!ptr_id)
- ptr_id = fmt;
+bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args)
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return false;
- ImGui::PushID(ptr_id);
- const bool opened = ImGui::CollapsingHeader(g.TempBuffer, "", false);
- ImGui::PopID();
+ ImGuiState& g = *GImGui;
+ const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
+ return TreeNodeBehavior(window->GetID(ptr_id), flags, g.TempBuffer, label_end);
+}
- if (opened)
- ImGui::TreePush(ptr_id);
+bool ImGui::TreeNodeV(const char* str_id, const char* fmt, va_list args)
+{
+ return TreeNodeExV(str_id, 0, fmt, args);
+}
+
+bool ImGui::TreeNodeV(const void* ptr_id, const char* fmt, va_list args)
+{
+ return TreeNodeExV(ptr_id, 0, fmt, args);
+}
+bool ImGui::TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ bool opened = TreeNodeExV(str_id, flags, fmt, args);
+ va_end(args);
+ return opened;
+}
+
+bool ImGui::TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ bool opened = TreeNodeExV(ptr_id, flags, fmt, args);
+ va_end(args);
+ return opened;
+}
+
+bool ImGui::TreeNode(const char* str_id, const char* fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ bool opened = TreeNodeExV(str_id, 0, fmt, args);
+ va_end(args);
return opened;
}
@@ -5789,14 +5860,29 @@ bool ImGui::TreeNode(const void* ptr_id, const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
- bool s = TreeNodeV(ptr_id, fmt, args);
+ bool opened = TreeNodeExV(ptr_id, 0, fmt, args);
va_end(args);
- return s;
+ return opened;
+}
+
+bool ImGui::TreeNode(const char* label)
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return false;
+
+ return TreeNodeBehavior(window->GetID(label), 0, label, NULL);
}
-bool ImGui::TreeNode(const char* str_label_id)
+float ImGui::GetTreeNodeToLabelSpacing(ImGuiTreeNodeFlags flags)
{
- return TreeNode(str_label_id, "%s", str_label_id);
+ ImGuiState& g = *GImGui;
+ float off_from_start;
+ if (flags & ImGuiTreeNodeFlags_Framed)
+ off_from_start = g.FontSize + (g.Style.FramePadding.x * 3.0f) - ((float)(int)(g.CurrentWindow->WindowPadding.x*0.5f) - 1);
+ else
+ off_from_start = g.FontSize + (g.Style.FramePadding.x * 2.0f);
+ return off_from_start;
}
void ImGui::SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond)
@@ -5869,12 +5955,9 @@ void ImGui::Bullet()
return;
}
- // Render
- const float bullet_size = g.FontSize*0.15f;
- window->DrawList->AddCircleFilled(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f), bullet_size, GetColorU32(ImGuiCol_Text));
-
- // Stay on same line
- ImGui::SameLine(0, style.FramePadding.x*2);
+ // Render and stay on same line
+ RenderBullet(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f));
+ SameLine(0, style.FramePadding.x*2);
}
// Text with a little bullet aligned to the typical tree node.
@@ -5898,8 +5981,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
return;
// Render
- const float bullet_size = g.FontSize*0.15f;
- window->DrawList->AddCircleFilled(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f), bullet_size, GetColorU32(ImGuiCol_Text));
+ RenderBullet(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f));
RenderText(bb.Min+ImVec2(g.FontSize + style.FramePadding.x*2, text_base_offset_y), text_begin, text_end);
}
@@ -8230,7 +8312,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
if (flags & ImGuiSelectableFlags_Menu) button_flags |= ImGuiButtonFlags_PressedOnClick;
if (flags & ImGuiSelectableFlags_MenuItem) button_flags |= ImGuiButtonFlags_PressedOnClick|ImGuiButtonFlags_PressedOnRelease;
if (flags & ImGuiSelectableFlags_Disabled) button_flags |= ImGuiButtonFlags_Disabled;
- if (flags & ImGuiSelectableFlags_AllowDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnDoubleClick;
+ if (flags & ImGuiSelectableFlags_AllowDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick;
bool hovered, held;
bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, button_flags);
if (flags & ImGuiSelectableFlags_Disabled)
@@ -8375,7 +8457,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo
float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame
float extra_w = ImMax(0.0f, ImGui::GetContentRegionAvail().x - w);
- bool pressed = ImGui::Selectable(label, false, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
+ bool pressed = ImGui::Selectable(label, false, ImGuiSelectableFlags_MenuItem | ImGuiSelectableFlags_DrawFillAvailWidth | (enabled ? 0 : ImGuiSelectableFlags_Disabled), ImVec2(w, 0.0f));
if (shortcut_size.x > 0.0f)
{
ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
@@ -8384,7 +8466,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo
}
if (selected)
- RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), GetColorU32(ImGuiCol_Text));
+ RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled));
return pressed;
}
@@ -8437,7 +8519,7 @@ bool ImGui::BeginMenuBar()
ImGui::BeginGroup(); // Save position
ImGui::PushID("##menubar");
ImRect rect = window->MenuBarRect();
- PushClipRect(ImVec2(rect.Min.x, rect.Min.y + window->BorderSize), ImVec2(rect.Max.x, rect.Max.y), false);
+ PushClipRect(ImVec2(ImFloor(rect.Min.x+0.5f), ImFloor(rect.Min.y + window->BorderSize + 0.5f)), ImVec2(ImFloor(rect.Max.x+0.5f), ImFloor(rect.Max.y+0.5f)), false);
window->DC.CursorPos = ImVec2(rect.Min.x + window->DC.MenuBarOffsetX, rect.Min.y);// + g.Style.FramePadding.y);
window->DC.LayoutType = ImGuiLayoutType_Horizontal;
window->DC.MenuBarAppending = true;
@@ -9000,7 +9082,7 @@ float ImGui::GetColumnWidth(int column_index)
if (column_index < 0)
column_index = window->DC.ColumnsCurrent;
- const float w = GetColumnOffset(column_index+1) - GetColumnOffset(column_index);
+ float w = GetColumnOffset(column_index+1) - GetColumnOffset(column_index);
return w;
}
@@ -9010,8 +9092,8 @@ static void PushColumnClipRect(int column_index)
if (column_index < 0)
column_index = window->DC.ColumnsCurrent;
- const float x1 = window->Pos.x + ImGui::GetColumnOffset(column_index) - 1;
- const float x2 = window->Pos.x + ImGui::GetColumnOffset(column_index+1) - 1;
+ float x1 = ImFloor(0.5f + window->Pos.x + ImGui::GetColumnOffset(column_index) - 1.0f);
+ float x2 = ImFloor(0.5f + window->Pos.x + ImGui::GetColumnOffset(column_index+1) - 1.0f);
ImGui::PushClipRect(ImVec2(x1,-FLT_MAX), ImVec2(x2,+FLT_MAX), true);
}
@@ -9139,6 +9221,14 @@ void ImGui::TreePush(const void* ptr_id)
PushID(ptr_id ? ptr_id : (const void*)"#TreePush");
}
+void ImGui::TreePushRawID(ImGuiID id)
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ ImGui::Indent();
+ window->DC.TreeDepth++;
+ window->IDStack.push_back(id);
+}
+
void ImGui::TreePop()
{
ImGuiWindow* window = GetCurrentWindow();
@@ -9357,8 +9447,8 @@ void ImGui::ShowMetricsWindow(bool* opened)
ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL;
for (int i = elem_offset; i < elem_offset + (int)pcmd->ElemCount; i++)
vtxs_rect.Add(draw_list->VtxBuffer[idx_buffer ? idx_buffer[i] : i].pos);
- clip_rect.Floor(); overlay_draw_list->AddRect(clip_rect.Min, clip_rect.Max, ImColor(255,255,0));
- vtxs_rect.Floor(); overlay_draw_list->AddRect(vtxs_rect.Min, vtxs_rect.Max, ImColor(255,0,255));
+ clip_rect.Floor(); overlay_draw_list->AddRect(clip_rect.Min, clip_rect.Max, IM_COL32(255,255,0,255));
+ vtxs_rect.Floor(); overlay_draw_list->AddRect(vtxs_rect.Min, vtxs_rect.Max, IM_COL32(255,0,255,255));
}
if (!draw_opened)
continue;
@@ -9374,7 +9464,7 @@ void ImGui::ShowMetricsWindow(bool* opened)
}
ImGui::Selectable(buf, false);
if (ImGui::IsItemHovered())
- overlay_draw_list->AddPolyline(triangles_pos, 3, ImColor(255,255,0), true, 1.0f, false); // Add triangle without AA, more readable for large-thin triangle
+ overlay_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f, false); // Add triangle without AA, more readable for large-thin triangle
}
ImGui::TreePop();
}
diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h
index 0ad337d169e..887cc068876 100644
--- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h
+++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h
@@ -70,6 +70,7 @@ typedef int ImGuiWindowFlags; // window flags for Begin*() // e
typedef int ImGuiSetCond; // condition flags for Set*() // enum ImGuiSetCond_
typedef int ImGuiInputTextFlags; // flags for InputText*() // enum ImGuiInputTextFlags_
typedef int ImGuiSelectableFlags; // flags for Selectable() // enum ImGuiSelectableFlags_
+typedef int ImGuiTreeNodeFlags; // flags for TreeNode*(), Collapsing*() // enum ImGuiTreeNodeFlags_
typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data);
// Others helpers at bottom of the file:
@@ -251,7 +252,6 @@ namespace ImGui
IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size);
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0));
IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding
- IMGUI_API bool CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false);
IMGUI_API bool Checkbox(const char* label, bool* v);
IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
IMGUI_API bool RadioButton(const char* label, bool active);
@@ -307,15 +307,23 @@ namespace ImGui
IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f");
// Widgets: Trees
- IMGUI_API bool TreeNode(const char* str_label_id); // if returning 'true' the node is open and the user is responsible for calling TreePop().
+ IMGUI_API bool TreeNode(const char* label); // if returning 'true' the node is open and the tree id is pushed into the id stack. user is responsible for calling TreePop().
IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_PRINTFARGS(2); // read the FAQ about why and how to use ID. to align arbitrary text at the same level as a TreeNode() you can use Bullet().
IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...) IM_PRINTFARGS(2); // "
IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args); // "
IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args); // "
- IMGUI_API void TreePush(const char* str_id = NULL); // already called by TreeNode(), but you can call Push/Pop yourself for layouting purpose
+ IMGUI_API bool TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags = 0);
+ IMGUI_API bool TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_PRINTFARGS(3);
+ IMGUI_API bool TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_PRINTFARGS(3);
+ IMGUI_API bool TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args);
+ IMGUI_API bool TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args);
+ IMGUI_API void TreePush(const char* str_id = NULL); // already called by TreeNode(), but you can call Push/Pop yourself for layout purpose
IMGUI_API void TreePush(const void* ptr_id = NULL); // "
IMGUI_API void TreePop();
IMGUI_API void SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0); // set next tree node/collapsing header to be opened.
+ IMGUI_API float GetTreeNodeToLabelSpacing(ImGuiTreeNodeFlags flags = 0); // return horizontal distance between cursor and text label due to collapsing node. == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode
+ IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. user doesn't have to call TreePop().
+ IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header
// Widgets: Selectable / Lists
IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height
@@ -368,10 +376,15 @@ namespace ImGui
IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard
IMGUI_API void LogText(const char* fmt, ...) IM_PRINTFARGS(1); // pass text data straight to log (without being displayed)
+ // Clipping
+ IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect);
+ IMGUI_API void PopClipRect();
+
// Utilities
IMGUI_API bool IsItemHovered(); // was the last item hovered by mouse?
IMGUI_API bool IsItemHoveredRect(); // was the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this
IMGUI_API bool IsItemActive(); // was the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false)
+ IMGUI_API bool IsItemClicked(int mouse_button = 0); // was the last item clicked? (e.g. button/node just clicked on)
IMGUI_API bool IsItemVisible(); // was the last item visible? (aka not out of sight due to clipping/scrolling.)
IMGUI_API bool IsAnyItemHovered();
IMGUI_API bool IsAnyItemActive();
@@ -381,8 +394,9 @@ namespace ImGui
IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area.
IMGUI_API bool IsWindowHovered(); // is current window hovered and hoverable (not blocked by a popup) (differentiate child windows from each others)
IMGUI_API bool IsWindowFocused(); // is current window focused
- IMGUI_API bool IsRootWindowFocused(); // is current root window focused (top parent window in case of child windows)
+ IMGUI_API bool IsRootWindowFocused(); // is current root window focused (root = top-most parent of a child, otherwise self)
IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused
+ IMGUI_API bool IsRootWindowOrAnyChildHovered(); // is current root window or any of its child (including current window) hovered and hoverable (not blocked by a popup)
IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle of given size starting from cursor pos is visible (not clipped). to perform coarse clipping on user's side (as an optimization)
IMGUI_API bool IsPosHoveringAnyWindow(const ImVec2& pos); // is given position hovering any active imgui window
IMGUI_API float GetTime();
@@ -436,6 +450,7 @@ namespace ImGui
// Obsolete (will be removed)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
+ static inline bool CollapsingHeader(const char* label, const char* str_id, bool display_frame = true, bool default_open = false) { (void)str_id; (void)display_frame; ImGuiTreeNodeFlags default_open_flags = 1<<5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+
static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+
static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+
static inline void OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpened(open, 0); } // OBSOLETE 1.34+
@@ -507,6 +522,24 @@ enum ImGuiInputTextFlags_
ImGuiInputTextFlags_Multiline = 1 << 20 // For internal use by InputTextMultiline()
};
+// Flags for ImGui::TreeNode*(), ImGui::CollapsingHeader*()
+enum ImGuiTreeNodeFlags_
+{
+ ImGuiTreeNodeFlags_Selected = 1 << 0, // Draw as selected
+ ImGuiTreeNodeFlags_Framed = 1 << 1, // Full colored frame (e.g. for CollapsingHeader)
+ ImGuiTreeNodeFlags_AllowOverlapMode = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one
+ ImGuiTreeNodeFlags_NoTreePushOnOpen = 1 << 3, // Don't do a TreePush() when opened (e.g. for CollapsingHeader) = no extra indent nor pushing on ID stack
+ ImGuiTreeNodeFlags_NoAutoOpenOnLog = 1 << 4, // Don't automatically and temporarily open node when Logging is active (by default logging will automatically open tree nodes)
+ ImGuiTreeNodeFlags_DefaultOpen = 1 << 5, // Default node to be opened
+ ImGuiTreeNodeFlags_OpenOnDoubleClick = 1 << 6, // Need double-click to open node
+ ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If ImGuiTreeNodeFlags_OpenOnDoubleClick is also set, single-click arrow or double-click all box to open.
+ ImGuiTreeNodeFlags_AlwaysOpen = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes).
+ //ImGuiTreeNodeFlags_UnindentArrow = 1 << 9, // FIXME: TODO: Unindent tree so that Label is aligned to current X position
+ //ImGuITreeNodeFlags_SpanAllAvailWidth = 1 << 10, // FIXME: TODO: Extend hit box horizontally even if not framed
+ //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 11, // FIXME: TODO: Automatically scroll on TreePop() if node got just opened and contents is not visible
+ ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoAutoOpenOnLog
+};
+
// Flags for ImGui::Selectable()
enum ImGuiSelectableFlags_
{
@@ -664,7 +697,7 @@ struct ImGuiStyle
ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines
ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label)
ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much!
- float IndentSpacing; // Horizontal indentation when e.g. entering a tree node
+ float IndentSpacing; // Horizontal indentation when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2).
float ColumnsMinSpacing; // Minimum horizontal spacing between two columns
float ScrollbarSize; // Width of the vertical scrollbar, Height of the horizontal scrollbar
float ScrollbarRounding; // Radius of grab corners for scrollbar
@@ -1131,7 +1164,7 @@ struct ImDrawList
ImDrawList() { _OwnerName = NULL; Clear(); }
~ImDrawList() { ClearFreeMemory(); }
- IMGUI_API void PushClipRect(const ImVec4& clip_rect); // Scissoring. Note that the values are (x1,y1,x2,y2) and NOT (x1,y1,w,h). This is passed down to your render function but not used for CPU-side clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
+ IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
IMGUI_API void PushClipRectFullScreen();
IMGUI_API void PopClipRect();
IMGUI_API void PushTextureID(const ImTextureID& texture_id);
@@ -1261,7 +1294,7 @@ struct ImFontAtlas
void SetTexID(void* id) { TexID = id; }
// Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list)
- // (Those functions could be static but aren't so most users don't have to refer to the ImFontAtlas:: name ever if in their code; just using io.Fonts->)
+ // NB: Make sure that your string are UTF-8 and NOT in your local code page. See FAQ for details.
IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin
IMGUI_API const ImWchar* GetGlyphRangesKorean(); // Default + Korean characters
IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs
@@ -1319,10 +1352,10 @@ struct ImFont
IMGUI_API ~ImFont();
IMGUI_API void Clear();
IMGUI_API void BuildLookupTable();
- IMGUI_API const Glyph* FindGlyph(unsigned short c) const;
+ IMGUI_API const Glyph* FindGlyph(ImWchar c) const;
IMGUI_API void SetFallbackChar(ImWchar c);
- float GetCharAdvance(unsigned short c) const { return ((int)c < IndexXAdvance.Size) ? IndexXAdvance[(int)c] : FallbackXAdvance; }
- bool IsLoaded() const { return ContainerAtlas != NULL; }
+ float GetCharAdvance(ImWchar c) const { return ((int)c < IndexXAdvance.Size) ? IndexXAdvance[(int)c] : FallbackXAdvance; }
+ bool IsLoaded() const { return ContainerAtlas != NULL; }
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
@@ -1330,6 +1363,10 @@ struct ImFont
IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const;
IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const;
IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const;
+
+ // Private
+ IMGUI_API void GrowIndex(int new_size);
+ IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built.
};
//---- Include imgui_user.h at the end of imgui.h
diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp
index 41dd1564d1a..794eb4e2c9b 100644
--- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp
+++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp
@@ -270,16 +270,65 @@ void ImGui::ShowTestWindow(bool* p_opened)
{
if (ImGui::TreeNode("Trees"))
{
- for (int i = 0; i < 5; i++)
+ if (ImGui::TreeNode("Basic trees"))
+ {
+ for (int i = 0; i < 5; i++)
+ if (ImGui::TreeNode((void*)(intptr_t)i, "Child %d", i))
+ {
+ ImGui::Text("blah blah");
+ ImGui::SameLine();
+ if (ImGui::SmallButton("print")) printf("Child %d pressed", i);
+ ImGui::TreePop();
+ }
+ ImGui::TreePop();
+ }
+
+ if (ImGui::TreeNode("With selectable nodes"))
{
- if (ImGui::TreeNode((void*)(intptr_t)i, "Child %d", i))
+ ShowHelpMarker("Click to select, CTRL+Click to toggle, click on arrows to open");
+ static int selection_mask = 0x02; // Dumb representation of what may be user-side selection state. You may carry selection state inside or outside your objects in whatever format you see fit.
+ int node_clicked = -1;
+ for (int i = 0; i < 6; i++)
{
- ImGui::Text("blah blah");
- ImGui::SameLine();
- if (ImGui::SmallButton("print"))
- printf("Child %d pressed", i);
- ImGui::TreePop();
+ ImGuiTreeNodeFlags node_flags = ((selection_mask & (1 << i)) ? ImGuiTreeNodeFlags_Selected : 0) | ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
+ if (i >= 3)
+ node_flags |= ImGuiTreeNodeFlags_AlwaysOpen;
+ bool opened = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable %s %d", (i >= 3) ? "Leaf" : "Node", i);
+ if (ImGui::IsItemClicked())
+ node_clicked = i;
+ if (opened)
+ {
+ ImGui::Text("Blah blah");
+ ImGui::Text("Blah blah");
+ ImGui::TreePop();
+ }
}
+ if (node_clicked != -1)
+ {
+ // Update selection state. Process outside of tree loop to avoid visual inconsistencies during the clicking-frame.
+ if (ImGui::GetIO().KeyCtrl)
+ selection_mask ^= (1 << node_clicked); // CTRL+click to toggle
+ else
+ selection_mask = (1 << node_clicked); // Click to single-select
+ }
+ ImGui::TreePop();
+ }
+ ImGui::TreePop();
+ }
+
+ if (ImGui::TreeNode("Collapsing Headers"))
+ {
+ static bool closable_group = true;
+ if (ImGui::CollapsingHeader("Header"))
+ {
+ ImGui::Checkbox("Enable extra group", &closable_group);
+ for (int i = 0; i < 5; i++)
+ ImGui::Text("Some content %d", i);
+ }
+ if (ImGui::CollapsingHeader("Header with a close button", &closable_group))
+ {
+ for (int i = 0; i < 5; i++)
+ ImGui::Text("More content %d", i);
}
ImGui::TreePop();
}
@@ -1863,7 +1912,7 @@ static void ShowExampleAppCustomRendering(bool* opened)
points.pop_back();
}
}
- draw_list->PushClipRect(ImVec4(canvas_pos.x, canvas_pos.y, canvas_pos.x+canvas_size.x, canvas_pos.y+canvas_size.y)); // clip lines within the canvas (if we resize it, etc.)
+ draw_list->PushClipRect(canvas_pos, ImVec2(canvas_pos.x+canvas_size.x, canvas_pos.y+canvas_size.y)); // clip lines within the canvas (if we resize it, etc.)
for (int i = 0; i < points.Size - 1; i += 2)
draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i+1].x, canvas_pos.y + points[i+1].y), 0xFF00FFFF, 2.0f);
draw_list->PopClipRect();
diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp
index 0a94dbfbaba..4f3fe3a228a 100644
--- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp
+++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp
@@ -215,20 +215,29 @@ void ImDrawList::UpdateTextureID()
#undef GetCurrentClipRect
#undef GetCurrentTextureId
-// Scissoring. The values in clip_rect are x1, y1, x2, y2. Only apply to rendering! Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
-void ImDrawList::PushClipRect(const ImVec4& clip_rect)
+// Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
+void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_current_clip_rect)
{
- _ClipRectStack.push_back(clip_rect);
+ ImVec4 cr(cr_min.x, cr_min.y, cr_max.x, cr_max.y);
+ if (intersect_with_current_clip_rect && _ClipRectStack.Size)
+ {
+ ImVec4 current = _ClipRectStack.Data[_ClipRectStack.Size-1];
+ if (cr.x < current.x) cr.x = current.x;
+ if (cr.y < current.y) cr.y = current.y;
+ if (cr.z > current.z) cr.z = current.z;
+ if (cr.w > current.w) cr.w = current.w;
+ }
+ cr.z = ImMax(cr.x, cr.z);
+ cr.w = ImMax(cr.y, cr.w);
+
+ _ClipRectStack.push_back(cr);
UpdateClipRect();
}
void ImDrawList::PushClipRectFullScreen()
{
- PushClipRect(GNullClipRect);
-
- // FIXME-OPT: This would be more correct but we're not supposed to access ImGuiState from here?
- //ImGuiState& g = *GImGui;
- //PushClipRect(GetVisibleRect());
+ PushClipRect(ImVec2(GNullClipRect.x, GNullClipRect.y), ImVec2(GNullClipRect.z, GNullClipRect.w));
+ //PushClipRect(GetVisibleRect()); // FIXME-OPT: This would be more correct but we're not supposed to access ImGuiState from here?
}
void ImDrawList::PopClipRect()
@@ -1679,14 +1688,8 @@ void ImFont::BuildLookupTable()
IM_ASSERT(Glyphs.Size < 32*1024);
IndexXAdvance.clear();
- IndexXAdvance.resize(max_codepoint + 1);
IndexLookup.clear();
- IndexLookup.resize(max_codepoint + 1);
- for (int i = 0; i < max_codepoint + 1; i++)
- {
- IndexXAdvance[i] = -1.0f;
- IndexLookup[i] = (short)-1;
- }
+ GrowIndex(max_codepoint + 1);
for (int i = 0; i < Glyphs.Size; i++)
{
int codepoint = (int)Glyphs[i].Codepoint;
@@ -1722,6 +1725,36 @@ void ImFont::SetFallbackChar(ImWchar c)
BuildLookupTable();
}
+void ImFont::GrowIndex(int new_size)
+{
+ IM_ASSERT(IndexXAdvance.Size == IndexLookup.Size);
+ int old_size = IndexLookup.Size;
+ if (new_size <= old_size)
+ return;
+ IndexXAdvance.resize(new_size);
+ IndexLookup.resize(new_size);
+ for (int i = old_size; i < new_size; i++)
+ {
+ IndexXAdvance[i] = -1.0f;
+ IndexLookup[i] = (short)-1;
+ }
+}
+
+void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst)
+{
+ IM_ASSERT(IndexLookup.Size > 0); // Currently this can only be called AFTER the font has been built, aka after calling ImFontAtlas::GetTexDataAs*() function.
+ int index_size = IndexLookup.Size;
+
+ if (dst < index_size && IndexLookup.Data[dst] == -1 && !overwrite_dst) // 'dst' already exists
+ return;
+ if (src >= index_size && dst >= index_size) // both 'dst' and 'src' don't exist -> no-op
+ return;
+
+ GrowIndex(dst + 1);
+ IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : -1;
+ IndexXAdvance[dst] = (src < index_size) ? IndexXAdvance.Data[src] : 1.0f;
+}
+
const ImFont::Glyph* ImFont::FindGlyph(unsigned short c) const
{
if (c < IndexLookup.Size)
diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h
index 8d18d1b5c89..0ef0b8478e7 100644
--- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h
+++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h
@@ -135,6 +135,7 @@ static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t)
static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; }
static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y + lhs.z*lhs.z + lhs.w*lhs.w; }
static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / sqrtf(d); return fail_value; }
+static inline float ImFloor(float f) { return (float)(int)f; }
static inline ImVec2 ImFloor(ImVec2 v) { return ImVec2((float)(int)v.x, (float)(int)v.y); }
// We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax.
@@ -153,20 +154,16 @@ inline void operator delete(void*, ImPlacementNewDummy, void*) {}
enum ImGuiButtonFlags_
{
ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat
- ImGuiButtonFlags_PressedOnClick = 1 << 1, // return pressed on click (default requires click+release)
- ImGuiButtonFlags_PressedOnRelease = 1 << 2, // return pressed on release (default requires click+release)
- ImGuiButtonFlags_PressedOnDoubleClick = 1 << 3, // return pressed on double-click (default requires click+release)
- ImGuiButtonFlags_FlattenChilds = 1 << 4, // allow interaction even if a child window is overlapping
- ImGuiButtonFlags_DontClosePopups = 1 << 5, // disable automatically closing parent popup on press
- ImGuiButtonFlags_Disabled = 1 << 6, // disable interaction
- ImGuiButtonFlags_AlignTextBaseLine = 1 << 7, // vertically align button to match text baseline - ButtonEx() only
- ImGuiButtonFlags_NoKeyModifiers = 1 << 8 // disable interaction if a key modifier is held
-};
-
-enum ImGuiTreeNodeFlags_
-{
- ImGuiTreeNodeFlags_DefaultOpen = 1 << 0,
- ImGuiTreeNodeFlags_NoAutoExpandOnLog = 1 << 1
+ ImGuiButtonFlags_PressedOnClickRelease = 1 << 1, // (default) return pressed on click+release on same item (default if no PressedOn** flag is set)
+ ImGuiButtonFlags_PressedOnClick = 1 << 2, // return pressed on click (default requires click+release)
+ ImGuiButtonFlags_PressedOnRelease = 1 << 3, // return pressed on release (default requires click+release)
+ ImGuiButtonFlags_PressedOnDoubleClick = 1 << 4, // return pressed on double-click (default requires click+release)
+ ImGuiButtonFlags_FlattenChilds = 1 << 5, // allow interaction even if a child window is overlapping
+ ImGuiButtonFlags_DontClosePopups = 1 << 6, // disable automatically closing parent popup on press
+ ImGuiButtonFlags_Disabled = 1 << 7, // disable interaction
+ ImGuiButtonFlags_AlignTextBaseLine = 1 << 8, // vertically align button to match text baseline - ButtonEx() only
+ ImGuiButtonFlags_NoKeyModifiers = 1 << 9, // disable interaction if a key modifier is held
+ ImGuiButtonFlags_AllowOverlapMode = 1 << 10 // require previous frame HoveredId to either match id or be null before being usable
};
enum ImGuiSliderFlags_
@@ -702,18 +699,17 @@ namespace ImGui
inline IMGUI_API ImU32 GetColorU32(const ImVec4& col) { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); }
// NB: All position are in absolute pixels coordinates (not window coordinates)
- // FIXME: Refactor all RenderText* functions into one.
+ // FIXME: All those functions are a mess and needs to be refactored into something decent. Avoid use outside of imgui.cpp!
+ // We need: a sort of symbol library, preferably baked into font atlas when possible + decent text rendering helpers.
IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true);
IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width);
IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, ImGuiAlign align = ImGuiAlign_Default, const ImVec2* clip_min = NULL, const ImVec2* clip_max = NULL);
IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f);
- IMGUI_API void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale = 1.0f, bool shadow = false);
+ IMGUI_API void RenderCollapseTriangle(ImVec2 pos, bool opened, float scale = 1.0f, bool shadow = false);
+ IMGUI_API void RenderBullet(ImVec2 pos);
IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col);
IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text.
- IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_existing_clip_rect = true);
- IMGUI_API void PopClipRect();
-
IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0);
IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0);
IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius);
@@ -732,7 +728,9 @@ namespace ImGui
IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags);
IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision);
+ IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL);
IMGUI_API bool TreeNodeBehaviorIsOpened(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextTreeNodeOpened() data, if any. May return true when logging
+ IMGUI_API void TreePushRawID(ImGuiID id);
IMGUI_API void PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size);
diff --git a/3rdparty/bgfx/README.md b/3rdparty/bgfx/README.md
index c074bcc2b68..fbd958eaac4 100644
--- a/3rdparty/bgfx/README.md
+++ b/3rdparty/bgfx/README.md
@@ -56,8 +56,9 @@ Languages:
* [C#/VB/F# language API bindings](https://github.com/MikePopoloski/SharpBgfx)
* [D language API bindings](https://github.com/DerelictOrg/DerelictBgfx)
* [Go language API bindings](https://github.com/james4k/go-bgfx)
- * [Java language API bindings](https://github.com/enleeten/twilight-bgfx)
* [Haskell language API bindings](https://github.com/haskell-game/bgfx)
+ * [Java language API bindings](https://github.com/enleeten/twilight-bgfx)
+ * [Lua language API bindings](https://github.com/excessive/lua-bgfx)
* [Python language API bindings](https://github.com/jnadro/pybgfx#pybgf)
* [Rust language API bindings](https://github.com/rhoot/bgfx-rs)
diff --git a/3rdparty/bgfx/examples/00-helloworld/helloworld.cpp b/3rdparty/bgfx/examples/00-helloworld/helloworld.cpp
index e2e8a599a15..92996ae0314 100644
--- a/3rdparty/bgfx/examples/00-helloworld/helloworld.cpp
+++ b/3rdparty/bgfx/examples/00-helloworld/helloworld.cpp
@@ -7,7 +7,6 @@
#include "common.h"
#include "bgfx_utils.h"
#include "logo.h"
-#include "imgui/imgui.h"
class ExampleHelloWorld : public entry::AppI
{
@@ -29,111 +28,23 @@ class ExampleHelloWorld : public entry::AppI
// Set view 0 clear state.
bgfx::setViewClear(0
, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
- , 0x000000ff
+ , 0x303030ff
, 1.0f
, 0
);
- imguiCreate();
- ImGui::GetIO().FontGlobalScale = 1.5;
}
virtual int shutdown() BX_OVERRIDE
{
- // Cleanup.
- imguiDestroy();
-
// Shutdown bgfx.
bgfx::shutdown();
return 0;
}
- void displayMainMenu()
- {
- if (ImGui::BeginMainMenuBar())
- {
- if (ImGui::BeginMenu("Left"))
- {
- if (ImGui::MenuItem("Brief", "CTRL+1")) {}
- if (ImGui::MenuItem("Medium", "CTRL+2")) {}
- if (ImGui::MenuItem("Two columns", "CTRL+3")) {}
- if (ImGui::MenuItem("Full (name)", "CTRL+4")) {}
- if (ImGui::MenuItem("Full (size, time)", "CTRL+5")) {}
- if (ImGui::MenuItem("Full (access)", "CTRL+6")) {}
- ImGui::Separator();
- if (ImGui::BeginMenu("Sort mode"))
- {
- ImGui::MenuItem("Name");
- ImGui::MenuItem("Extension");
- ImGui::MenuItem("Modif. Time");
- ImGui::MenuItem("Size");
- ImGui::MenuItem("Unsorted");
- ImGui::EndMenu();
- }
- if (ImGui::MenuItem("Change source")) {}
- ImGui::EndMenu();
- }
- if (ImGui::BeginMenu("Files"))
- {
- if (ImGui::MenuItem("User menu", "F2")) {}
- if (ImGui::MenuItem("View", "F3")) {}
- if (ImGui::MenuItem("Edit", "F4")) {}
- if (ImGui::MenuItem("Copy", "F5")) {}
- if (ImGui::MenuItem("Rename or move", "F6")) {}
- if (ImGui::MenuItem("Make directory", "F7")) {}
- if (ImGui::MenuItem("Delete", "F8")) {}
- ImGui::Separator();
- if (ImGui::MenuItem("File attributes", "CTRL+A")) {}
- if (ImGui::MenuItem("Apply command", "CTRL+G")) {}
- ImGui::Separator();
- if (ImGui::MenuItem("Select group")) {}
- if (ImGui::MenuItem("Unselect group")) {}
- if (ImGui::MenuItem("Invert selection")) {}
- ImGui::EndMenu();
- }
- if (ImGui::BeginMenu("Commands"))
- {
- if (ImGui::MenuItem("Find file", "ALT+F7")) {}
- if (ImGui::MenuItem("History", "ALT+F8")) {}
- if (ImGui::MenuItem("Maximize window", "ALT+F9")) {}
- ImGui::Separator();
- if (ImGui::MenuItem("Panel on/off", "CTRL+O")) {}
- if (ImGui::MenuItem("Equal panels", "CTRL+=")) {}
- ImGui::EndMenu();
- }
- if (ImGui::BeginMenu("Options"))
- {
- if (ImGui::MenuItem("Settings")) {}
- ImGui::EndMenu();
- }
- if (ImGui::BeginMenu("Right"))
- {
- if (ImGui::MenuItem("Brief", "CTRL+1")) {}
- if (ImGui::MenuItem("Medium", "CTRL+2")) {}
- if (ImGui::MenuItem("Two columns", "CTRL+3")) {}
- if (ImGui::MenuItem("Full (name)", "CTRL+4")) {}
- if (ImGui::MenuItem("Full (size, time)", "CTRL+5")) {}
- if (ImGui::MenuItem("Full (access)", "CTRL+6")) {}
- ImGui::Separator();
- if (ImGui::BeginMenu("Sort mode"))
- {
- ImGui::MenuItem("Name");
- ImGui::MenuItem("Extension");
- ImGui::MenuItem("Modif. Time");
- ImGui::MenuItem("Size");
- ImGui::MenuItem("Unsorted");
- ImGui::EndMenu();
- }
- if (ImGui::MenuItem("Change source")) {}
- ImGui::EndMenu();
- }
- ImGui::EndMainMenuBar();
- }
- }
-
bool update() BX_OVERRIDE
{
- if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
+ if (!entry::processEvents(m_width, m_height, m_debug, m_reset) )
{
// Set view 0 default viewport.
bgfx::setViewRect(0, 0, 0, m_width, m_height);
@@ -142,91 +53,18 @@ class ExampleHelloWorld : public entry::AppI
// if no other draw calls are submitted to view 0.
bgfx::touch(0);
- imguiBeginFrame(m_mouseState.m_mx
- , m_mouseState.m_my
- , (m_mouseState.m_buttons[entry::MouseButton::Left] ? IMGUI_MBUT_LEFT : 0)
- | (m_mouseState.m_buttons[entry::MouseButton::Right] ? IMGUI_MBUT_RIGHT : 0)
- , m_mouseState.m_mz
- , m_width
- , m_height
- );
- displayMainMenu();
- ImGui::SetNextWindowPos(ImVec2(0, 32));
- ImGui::SetNextWindowSize(ImVec2(m_width/2, m_height - 32));
- if (ImGui::Begin("Window1", nullptr, ImVec2(m_width/2, m_height-32), 1.0f, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar))
- {
- ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, 5.0f);
- ImGui::BeginChild("Sub1", ImVec2(0, m_height - 48), true);
-
-
- ImGui::Columns(4, "mycolumns");
- ImGui::Separator();
- ImGui::Text("ID"); ImGui::NextColumn();
- ImGui::Text("Name"); ImGui::NextColumn();
- ImGui::Text("Path"); ImGui::NextColumn();
- ImGui::Text("Flags"); ImGui::NextColumn();
- ImGui::Separator();
- const char* names[3] = { "One", "Two", "Three" };
- const char* paths[3] = { "/path/one", "/path/two", "/path/three" };
- static int selected = -1;
- for (int i = 0; i < 50; i++)
- {
- char label[32];
- sprintf(label, "%04d", i);
- if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns))
- selected = i;
- ImGui::NextColumn();
- ImGui::Text(names[i%3]); ImGui::NextColumn();
- ImGui::Text(paths[i % 3]); ImGui::NextColumn();
- ImGui::Text("...."); ImGui::NextColumn();
- }
- ImGui::Columns(1);
- ImGui::Separator();
-
-
-
- ImGui::EndChild();
- ImGui::PopStyleVar();
- }
- ImGui::End();
- ImGui::SameLine();
- ImGui::SetNextWindowPos(ImVec2(m_width / 2, 32));
- ImGui::SetNextWindowSize(ImVec2(m_width / 2, m_height - 32));
- if (ImGui::Begin("Window2", nullptr, ImVec2(m_width/2, m_height - 32), 1.0f, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar))
- {
- ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, 5.0f);
- ImGui::BeginChild("Sub2", ImVec2(0, m_height - 48), true);
-
- ImGui::Columns(4, "mycolumns");
- ImGui::Separator();
- ImGui::Text("ID"); ImGui::NextColumn();
- ImGui::Text("Name"); ImGui::NextColumn();
- ImGui::Text("Path"); ImGui::NextColumn();
- ImGui::Text("Flags"); ImGui::NextColumn();
- ImGui::Separator();
- const char* names[3] = { "One", "Two", "Three" };
- const char* paths[3] = { "/path/one", "/path/two", "/path/three" };
- static int selected = -1;
- for (int i = 0; i < 3; i++)
- {
- char label[32];
- sprintf(label, "%04d", i);
- if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns))
- selected = i;
- ImGui::NextColumn();
- ImGui::Text(names[i]); ImGui::NextColumn();
- ImGui::Text(paths[i]); ImGui::NextColumn();
- ImGui::Text("...."); ImGui::NextColumn();
- }
- ImGui::Columns(1);
- ImGui::Separator();
-
-
- ImGui::EndChild();
- ImGui::PopStyleVar();
- }
- ImGui::End();
- imguiEndFrame();
+ // Use debug font to print information about this example.
+ bgfx::dbgTextClear();
+ bgfx::dbgTextImage(bx::uint16_max(m_width /2/8, 20)-20
+ , bx::uint16_max(m_height/2/16, 6)-6
+ , 40
+ , 12
+ , s_logo
+ , 160
+ );
+ bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/00-helloworld");
+ bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Initialization and debug text.");
+
// Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives.
bgfx::frame();
@@ -241,7 +79,6 @@ class ExampleHelloWorld : public entry::AppI
uint32_t m_height;
uint32_t m_debug;
uint32_t m_reset;
- entry::MouseState m_mouseState;
};
ENTRY_IMPLEMENT_MAIN(ExampleHelloWorld);
diff --git a/3rdparty/bgfx/makefile b/3rdparty/bgfx/makefile
index e69671486f0..965de58a245 100644
--- a/3rdparty/bgfx/makefile
+++ b/3rdparty/bgfx/makefile
@@ -343,11 +343,13 @@ tools: geometryc shaderc texturec texturev ## Build tools.
dist-windows: .build/projects/gmake-mingw-gcc
$(SILENT) $(MAKE) -C .build/projects/gmake-mingw-gcc config=release64 -j 6 geometryc
- $(SILENT) cp .build/win64_mingw-gcc/bin/geometrycRelease tools/bin/windows/geometryc.exe
+ $(SILENT) cp .build/win64_mingw-gcc/bin/geometrycRelease.exe tools/bin/windows/geometryc.exe
$(SILENT) $(MAKE) -C .build/projects/gmake-mingw-gcc config=release64 -j 6 shaderc
- $(SILENT) cp .build/win64_mingw-gcc/bin/shadercRelease tools/bin/windows/shaderc.exe
+ $(SILENT) cp .build/win64_mingw-gcc/bin/shadercRelease.exe tools/bin/windows/shaderc.exe
$(SILENT) $(MAKE) -C .build/projects/gmake-mingw-gcc config=release64 -j 6 texturec
- $(SILENT) cp .build/win64_mingw-gcc/bin/texturecRelease tools/bin/windows/texturec.exe
+ $(SILENT) cp .build/win64_mingw-gcc/bin/texturecRelease.exe tools/bin/windows/texturec.exe
+ $(SILENT) $(MAKE) -C .build/projects/gmake-mingw-gcc config=release64 -j 6 texturev
+ $(SILENT) cp .build/win64_mingw-gcc/bin/texturevRelease.exe tools/bin/windows/texturev.exe
dist-linux: .build/projects/gmake-linux
$(SILENT) $(MAKE) -C .build/projects/gmake-linux config=release64 -j 6 geometryc
@@ -356,6 +358,8 @@ dist-linux: .build/projects/gmake-linux
$(SILENT) cp .build/linux64_gcc/bin/shadercRelease tools/bin/linux/shaderc
$(SILENT) $(MAKE) -C .build/projects/gmake-linux config=release64 -j 6 texturec
$(SILENT) cp .build/linux64_gcc/bin/texturecRelease tools/bin/linux/texturec
+ $(SILENT) $(MAKE) -C .build/projects/gmake-linux config=release64 -j 6 texturev
+ $(SILENT) cp .build/linux64_gcc/bin/texturevRelease tools/bin/linux/texturev
dist-darwin: .build/projects/gmake-osx
$(SILENT) $(MAKE) -C .build/projects/gmake-osx config=release64 -j 6 geometryc
@@ -364,5 +368,7 @@ dist-darwin: .build/projects/gmake-osx
$(SILENT) cp .build/osx64_clang/bin/shadercRelease tools/bin/darwin/shaderc
$(SILENT) $(MAKE) -C .build/projects/gmake-osx config=release64 -j 6 texturec
$(SILENT) cp .build/osx64_clang/bin/texturecRelease tools/bin/darwin/texturec
+ $(SILENT) $(MAKE) -C .build/projects/gmake-osx config=release64 -j 6 texturev
+ $(SILENT) cp .build/osx64_clang/bin/texturevRelease tools/bin/darwin/texturev
dist: clean dist-windows dist-linux dist-darwin
diff --git a/3rdparty/bgfx/scripts/geometryc.lua b/3rdparty/bgfx/scripts/geometryc.lua
index 9caecd29da1..47b2ee016b1 100644
--- a/3rdparty/bgfx/scripts/geometryc.lua
+++ b/3rdparty/bgfx/scripts/geometryc.lua
@@ -25,9 +25,14 @@ project "geometryc"
path.join(BGFX_DIR, "examples/common/bounds.**"),
}
+ configuration { "mingw-*" }
+ targetextension ".exe"
+
configuration { "osx" }
links {
"Cocoa.framework",
}
+ configuration {}
+
strip()
diff --git a/3rdparty/bgfx/scripts/shaderc.lua b/3rdparty/bgfx/scripts/shaderc.lua
index 4c09f847745..f45310417e4 100644
--- a/3rdparty/bgfx/scripts/shaderc.lua
+++ b/3rdparty/bgfx/scripts/shaderc.lua
@@ -36,6 +36,9 @@ project "shaderc"
"/wd4996" -- warning C4996: 'strdup': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _strdup.
}
+ configuration { "mingw-*" }
+ targetextension ".exe"
+
configuration { "mingw* or linux or osx" }
buildoptions {
"-fno-strict-aliasing", -- glsl-optimizer has bugs if strict aliasing is used.
diff --git a/3rdparty/bgfx/scripts/texturec.lua b/3rdparty/bgfx/scripts/texturec.lua
index 28e9bcc8bd4..36a01b15fde 100644
--- a/3rdparty/bgfx/scripts/texturec.lua
+++ b/3rdparty/bgfx/scripts/texturec.lua
@@ -38,11 +38,12 @@ project "texturec"
path.join(BGFX_DIR, "tools/texturec/**.h"),
}
- links {
--- "bgfx",
- }
+ configuration { "mingw-*" }
+ targetextension ".exe"
configuration { "osx" }
links {
"Cocoa.framework",
}
+
+ configuration {}
diff --git a/3rdparty/bgfx/scripts/texturev.lua b/3rdparty/bgfx/scripts/texturev.lua
index 4a04cff4cbd..2cfd106a8a7 100644
--- a/3rdparty/bgfx/scripts/texturev.lua
+++ b/3rdparty/bgfx/scripts/texturev.lua
@@ -120,7 +120,7 @@ project ("texturev")
"/DELAYLOAD:\"libGLESv2.dll\"",
}
- configuration { "mingw*" }
+ configuration { "mingw-*" }
targetextension ".exe"
configuration { "vs20* or mingw*" }
diff --git a/3rdparty/bgfx/src/bgfx.cpp b/3rdparty/bgfx/src/bgfx.cpp
index bf5f020f4f3..5da3c5609b7 100644
--- a/3rdparty/bgfx/src/bgfx.cpp
+++ b/3rdparty/bgfx/src/bgfx.cpp
@@ -65,8 +65,11 @@ namespace bgfx
{
char temp[2048];
char* out = temp;
+ va_list argListCopy;
+ va_copy(argListCopy, _argList);
int32_t len = bx::snprintf(out, sizeof(temp), "%s (%d): ", _filePath, _line);
- int32_t total = len + bx::vsnprintf(out + len, sizeof(temp)-len, _format, _argList);
+ int32_t total = len + bx::vsnprintf(out + len, sizeof(temp)-len, _format, argListCopy);
+ va_end(argListCopy);
if ( (int32_t)sizeof(temp) < total)
{
out = (char*)alloca(total+1);
diff --git a/3rdparty/bgfx/tools/shaderc/shaderc_glsl.cpp b/3rdparty/bgfx/tools/shaderc/shaderc_glsl.cpp
index 0a4ce15d937..78328cffbbd 100644
--- a/3rdparty/bgfx/tools/shaderc/shaderc_glsl.cpp
+++ b/3rdparty/bgfx/tools/shaderc/shaderc_glsl.cpp
@@ -208,6 +208,13 @@ namespace bgfx
uint8_t nul = 0;
bx::write(_writer, nul);
+ if (_cmdLine.hasArg('\0', "disasm") )
+ {
+ std::string disasmfp = _cmdLine.findOption('o');
+ disasmfp += ".disasm";
+ writeFile(disasmfp.c_str(), optimizedShader, shaderSize);
+ }
+
glslopt_cleanup(ctx);
return true;
diff --git a/3rdparty/bgfx/tools/texturev/texturev.cpp b/3rdparty/bgfx/tools/texturev/texturev.cpp
index ef976d626f4..28e298acbf7 100644
--- a/3rdparty/bgfx/tools/texturev/texturev.cpp
+++ b/3rdparty/bgfx/tools/texturev/texturev.cpp
@@ -224,7 +224,7 @@ struct View
}
std::string name = path;
- char ch = name.back();
+ char ch = name[name.size()-1];
name += '/' == ch || '\\' == ch ? "" : "/";
name += item->d_name;
m_fileList.push_back(name);