3074 lines
137 KiB
Lua
3074 lines
137 KiB
Lua
--- ImGui Sincerely WIP
|
|
-- (Demo Code, part 2): DemoWindowLayout(), DemoWindowPopups(), DemoWindowTables(), DemoWindowColumns(),
|
|
-- DemoWindowInputs() and all ShowExampleAppXXX() example apps.
|
|
-- Port of imgui_demo.cpp (docking branch). Globals are shared with imgui_demo.lua (HelpMarker, ShowExampleMenuFile, ...)
|
|
|
|
local IM_MIN = math.min
|
|
local IM_MAX = math.max
|
|
local function IM_CLAMP(V, MN, MX) return (V < MN) and MN or (V > MX) and MX or V end
|
|
local _
|
|
local function IMGUI_DEMO_MARKER(_) end -- upstream hook, no-op here
|
|
|
|
--- `char buf[size] = "str"` -> zero-terminated byte table
|
|
local function Buf(str, size)
|
|
local t = {}
|
|
for i = 1, #str do t[i] = string.byte(str, i) end
|
|
t[#str + 1] = 0
|
|
if size then for i = #str + 2, size do t[i] = 0 end end
|
|
return t
|
|
end
|
|
--- byte table -> Lua string (up to the zero terminator)
|
|
local function BufStr(buf)
|
|
local n = 0
|
|
while buf[n + 1] ~= nil and buf[n + 1] ~= 0 do n = n + 1 end
|
|
return ImGui._ByteArrayToString(buf, 1, n + 1)
|
|
end
|
|
local function BufSet(buf, str)
|
|
for i = 1, #str do buf[i] = string.byte(str, i) end
|
|
buf[#str + 1] = 0
|
|
end
|
|
|
|
--- ImColor::HSV() as ImVec4
|
|
local function HSV(h, s, v, a)
|
|
local r, g, b = ImGui.ColorConvertHSVtoRGB(h, s, v)
|
|
return ImVec4(r, g, b, a or 1.0)
|
|
end
|
|
local function B2I(b) return b and 1 or 0 end
|
|
|
|
local function Has(flags, f) return bit32.band(flags, f) ~= 0 end
|
|
local function NotSupported() ImGui.TextDisabled("(not supported on Roblox)") end
|
|
local function NotPorted(what) ImGui.TextDisabled("(not ported yet%s)", what and (": " .. what) or "") end
|
|
|
|
local function DemoHelpMarker(desc)
|
|
if HelpMarker then HelpMarker(desc) return end
|
|
ImGui.TextDisabled("(?)")
|
|
if ImGui.BeginItemTooltip() then
|
|
ImGui.PushTextWrapPos(ImGui.GetFontSize() * 35.0)
|
|
ImGui.TextUnformatted(desc)
|
|
ImGui.PopTextWrapPos()
|
|
ImGui.EndTooltip()
|
|
end
|
|
end
|
|
local function DemoMenuFile() if ShowExampleMenuFile then ShowExampleMenuFile() end end
|
|
|
|
--- Minimal ImGuiTextFilter stand-in when the library one isn't available
|
|
local function MakeTextFilter()
|
|
if ImGuiTextFilter then return ImGuiTextFilter() end
|
|
local f = { InputBuf = Buf("", 256) }
|
|
function f:Draw(label, width)
|
|
if width and width ~= 0 then ImGui.SetNextItemWidth(width) end
|
|
return ImGui.InputText(label or "Filter (inc,-exc)", self.InputBuf, 256)
|
|
end
|
|
function f:IsActive() return self.InputBuf[1] ~= 0 end
|
|
function f:Clear() self.InputBuf[1] = 0 end
|
|
function f:Build() end
|
|
function f:PassFilter(text, text_end)
|
|
if text_end then text = string.sub(text, 1, text_end - 1) end
|
|
local s = BufStr(self.InputBuf)
|
|
if s == "" then return true end
|
|
local any_inc, pass_inc = false, false
|
|
for tok in string.gmatch(s, "[^,]+") do
|
|
tok = string.match(tok, "^%s*(.-)%s*$")
|
|
if tok ~= "" then
|
|
if string.sub(tok, 1, 1) == "-" then
|
|
if #tok > 1 and string.find(string.lower(text), string.lower(string.sub(tok, 2)), 1, true) then return false end
|
|
else
|
|
any_inc = true
|
|
if string.find(string.lower(text), string.lower(tok), 1, true) then pass_inc = true end
|
|
end
|
|
end
|
|
end
|
|
return (not any_inc) or pass_inc
|
|
end
|
|
return f
|
|
end
|
|
|
|
-- ImGuiInputTextCallbackData helpers (the port's callback data has no methods). Buf is a 1-based zero-terminated
|
|
-- byte table, positions are 0-based like C++.
|
|
local function CB_DeleteChars(data, pos, bytes_count)
|
|
local buf = data.Buf
|
|
local len = data.BufTextLen
|
|
for i = pos + 1, len - bytes_count + 1 do buf[i] = buf[i + bytes_count] end
|
|
for i = len - bytes_count + 2, len + 1 do buf[i] = 0 end
|
|
if data.CursorPos >= pos + bytes_count then data.CursorPos = data.CursorPos - bytes_count
|
|
elseif data.CursorPos >= pos then data.CursorPos = pos end
|
|
data.SelectionStart = data.CursorPos; data.SelectionEnd = data.CursorPos
|
|
data.BufDirty = true
|
|
data.BufTextLen = len - bytes_count
|
|
end
|
|
local function CB_InsertChars(data, pos, text)
|
|
local n = #text
|
|
if n == 0 then return end
|
|
if data.BufTextLen + n >= data.BufSize then return end
|
|
local buf = data.Buf
|
|
for i = data.BufTextLen + 1, pos + 1, -1 do buf[i + n] = buf[i] end
|
|
for i = 1, n do buf[pos + i] = string.byte(text, i) end
|
|
if data.CursorPos >= pos then data.CursorPos = data.CursorPos + n end
|
|
data.SelectionStart = data.CursorPos; data.SelectionEnd = data.CursorPos
|
|
data.BufDirty = true
|
|
data.BufTextLen = data.BufTextLen + n
|
|
end
|
|
local function CB_SelectAll(data) data.SelectionStart = 0; data.SelectionEnd = data.BufTextLen end
|
|
|
|
--- ImGui::BeginChild() wrapper accepting upstream args
|
|
local function BeginChild(id, size, child_flags, window_flags)
|
|
return ImGui.BeginChild(id, size or ImVec2(0, 0), child_flags or 0, window_flags or 0)
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- [SECTION] DemoWindowLayout()
|
|
-------------------------------------------------------------------------------
|
|
|
|
local SL = {
|
|
disable_mouse_wheel = false, disable_menu = false,
|
|
draw_lines = 3, max_height_in_lines = 10,
|
|
offset_x = 0, override_bg_color = true, child_flags = nil,
|
|
f = 0.0, show_indented_items = true,
|
|
c1 = false, c2 = false, c3 = false, c4 = false,
|
|
f0 = 1.0, f1 = 2.0, f2 = 3.0, item = -1, selection = { 0, 1, 2, 3 },
|
|
track_item = 50, enable_track = true, enable_extra_decorations = false, scroll_to_off_px = 0.0, scroll_to_pos_px = 200.0,
|
|
lines = 7, show_horizontal_contents_size_demo_window = false,
|
|
show_h_scrollbar = true, show_button = true, show_tree_nodes = true, show_text_wrapped = false, show_columns = true,
|
|
show_tab_bar = true, show_child = false, explicit_content_size = false, contents_size_x = 300.0,
|
|
clip_size = nil, clip_offset = nil,
|
|
enable_allow_overlap = true,
|
|
}
|
|
|
|
local function DemoWindowLayout_ChildWindows()
|
|
IMGUI_DEMO_MARKER("Layout/Child windows")
|
|
ImGui.SeparatorText("Child windows")
|
|
|
|
DemoHelpMarker("Use child windows to begin into a self-contained independent scrolling/clipping regions within a host window.")
|
|
_, SL.disable_mouse_wheel = ImGui.Checkbox("Disable Mouse Wheel", SL.disable_mouse_wheel)
|
|
_, SL.disable_menu = ImGui.Checkbox("Disable Menu", SL.disable_menu)
|
|
|
|
-- Child 1: no border, enable horizontal scrollbar
|
|
do
|
|
local window_flags = ImGuiWindowFlags.HorizontalScrollbar
|
|
if SL.disable_mouse_wheel then
|
|
window_flags = bit32.bor(window_flags, ImGuiWindowFlags.NoScrollWithMouse)
|
|
end
|
|
BeginChild("ChildL", ImVec2(ImGui.GetContentRegionAvail().x * 0.5, 260), ImGuiChildFlags.None, window_flags)
|
|
for i = 0, 99 do
|
|
ImGui.Text("%04d: scrollable region", i)
|
|
end
|
|
ImGui.EndChild()
|
|
end
|
|
|
|
ImGui.SameLine()
|
|
|
|
-- Child 2: rounded border
|
|
do
|
|
local window_flags = ImGuiWindowFlags.None
|
|
if SL.disable_mouse_wheel then
|
|
window_flags = bit32.bor(window_flags, ImGuiWindowFlags.NoScrollWithMouse)
|
|
end
|
|
if not SL.disable_menu then
|
|
window_flags = bit32.bor(window_flags, ImGuiWindowFlags.MenuBar)
|
|
end
|
|
ImGui.PushStyleVar(ImGuiStyleVar.ChildRounding, 5.0)
|
|
BeginChild("ChildR", ImVec2(0, 260), ImGuiChildFlags.Borders, window_flags)
|
|
if not SL.disable_menu and ImGui.BeginMenuBar() then
|
|
if ImGui.BeginMenu("Menu") then
|
|
DemoMenuFile()
|
|
ImGui.EndMenu()
|
|
end
|
|
ImGui.EndMenuBar()
|
|
end
|
|
if ImGui.BeginTable("split", 2, bit32.bor(ImGuiTableFlags.Resizable, ImGuiTableFlags.NoSavedSettings)) then
|
|
for i = 0, 99 do
|
|
local buf = string.format("%03d", i)
|
|
ImGui.TableNextColumn()
|
|
ImGui.Button(buf, ImVec2(-FLT_MIN, 0.0))
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
ImGui.EndChild()
|
|
ImGui.PopStyleVar()
|
|
end
|
|
|
|
-- Child 3: manual-resize
|
|
ImGui.SeparatorText("Manual-resize")
|
|
do
|
|
DemoHelpMarker("Drag bottom border to resize. Double-click bottom border to auto-fit to vertical contents.")
|
|
ImGui.PushStyleColor(ImGuiCol.ChildBg, ImGui.GetStyleColorVec4(ImGuiCol.FrameBg))
|
|
if BeginChild("ResizableChild", ImVec2(-FLT_MIN, ImGui.GetTextLineHeightWithSpacing() * 8), bit32.bor(ImGuiChildFlags.Borders, ImGuiChildFlags.ResizeY)) then
|
|
for n = 0, 9 do
|
|
ImGui.Text("Line %04d", n)
|
|
end
|
|
end
|
|
ImGui.PopStyleColor()
|
|
ImGui.EndChild()
|
|
end
|
|
|
|
-- Child 4: auto-resizing height with a limit
|
|
ImGui.SeparatorText("Auto-resize with constraints")
|
|
do
|
|
ImGui.SetNextItemWidth(ImGui.GetFontSize() * 8)
|
|
SL.draw_lines = ImGui.DragInt("Lines Count", SL.draw_lines, 0.2)
|
|
ImGui.SetNextItemWidth(ImGui.GetFontSize() * 8)
|
|
SL.max_height_in_lines = ImGui.DragInt("Max Height (in Lines)", SL.max_height_in_lines, 0.2)
|
|
|
|
ImGui.SetNextWindowSizeConstraints(ImVec2(0.0, ImGui.GetTextLineHeightWithSpacing() * 1), ImVec2(FLT_MAX, ImGui.GetTextLineHeightWithSpacing() * SL.max_height_in_lines))
|
|
if BeginChild("ConstrainedChild", ImVec2(-FLT_MIN, 0.0), bit32.bor(ImGuiChildFlags.Borders, ImGuiChildFlags.AutoResizeY)) then
|
|
for n = 0, SL.draw_lines - 1 do
|
|
ImGui.Text("Line %04d", n)
|
|
end
|
|
end
|
|
ImGui.EndChild()
|
|
end
|
|
|
|
ImGui.SeparatorText("Misc/Advanced")
|
|
|
|
do
|
|
if SL.child_flags == nil then SL.child_flags = bit32.bor(ImGuiChildFlags.Borders, ImGuiChildFlags.ResizeX, ImGuiChildFlags.ResizeY) end
|
|
ImGui.SetNextItemWidth(ImGui.GetFontSize() * 8)
|
|
SL.offset_x = ImGui.DragInt("Offset X", SL.offset_x, 1.0, -1000, 1000)
|
|
_, SL.override_bg_color = ImGui.Checkbox("Override ChildBg color", SL.override_bg_color)
|
|
_, SL.child_flags = ImGui.CheckboxFlags("ImGuiChildFlags_Borders", SL.child_flags, ImGuiChildFlags.Borders)
|
|
_, SL.child_flags = ImGui.CheckboxFlags("ImGuiChildFlags_AlwaysUseWindowPadding", SL.child_flags, ImGuiChildFlags.AlwaysUseWindowPadding)
|
|
_, SL.child_flags = ImGui.CheckboxFlags("ImGuiChildFlags_ResizeX", SL.child_flags, ImGuiChildFlags.ResizeX)
|
|
_, SL.child_flags = ImGui.CheckboxFlags("ImGuiChildFlags_ResizeY", SL.child_flags, ImGuiChildFlags.ResizeY)
|
|
_, SL.child_flags = ImGui.CheckboxFlags("ImGuiChildFlags_FrameStyle", SL.child_flags, ImGuiChildFlags.FrameStyle)
|
|
ImGui.SameLine(); DemoHelpMarker("Style the child window like a framed item: use FrameBg, FrameRounding, FrameBorderSize, FramePadding instead of ChildBg, ChildRounding, ChildBorderSize, WindowPadding.")
|
|
if Has(SL.child_flags, ImGuiChildFlags.FrameStyle) then
|
|
SL.override_bg_color = false
|
|
end
|
|
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + SL.offset_x)
|
|
if SL.override_bg_color then
|
|
ImGui.PushStyleColor(ImGuiCol.ChildBg, IM_COL32(255, 0, 0, 100))
|
|
end
|
|
BeginChild("Red", ImVec2(200, 100), SL.child_flags, ImGuiWindowFlags.None)
|
|
if SL.override_bg_color then
|
|
ImGui.PopStyleColor()
|
|
end
|
|
|
|
for n = 0, 49 do
|
|
ImGui.Text("Some test %d", n)
|
|
end
|
|
ImGui.EndChild()
|
|
local child_is_hovered = ImGui.IsItemHovered()
|
|
local child_rect_min = ImGui.GetItemRectMin()
|
|
local child_rect_max = ImGui.GetItemRectMax()
|
|
ImGui.Text("Hovered: %d", B2I(child_is_hovered))
|
|
ImGui.Text("Rect of child window is: (%.0f,%.0f) (%.0f,%.0f)", child_rect_min.x, child_rect_min.y, child_rect_max.x, child_rect_max.y)
|
|
end
|
|
end
|
|
|
|
local function DemoWindowLayout_WidgetsWidth()
|
|
IMGUI_DEMO_MARKER("Layout/Widgets Width")
|
|
_, SL.show_indented_items = ImGui.Checkbox("Show indented items", SL.show_indented_items)
|
|
|
|
local function block(text, help, width, l1, l2)
|
|
ImGui.Text(text)
|
|
if help then ImGui.SameLine(); DemoHelpMarker(help) end
|
|
ImGui.PushItemWidth(width)
|
|
SL.f = ImGui.DragFloat(l1, SL.f)
|
|
if SL.show_indented_items then
|
|
ImGui.Indent()
|
|
SL.f = ImGui.DragFloat(l2, SL.f)
|
|
ImGui.Unindent()
|
|
end
|
|
ImGui.PopItemWidth()
|
|
end
|
|
block("SetNextItemWidth/PushItemWidth(100)", "Fixed width.", 100, "float##1b", "float (indented)##1b")
|
|
block("SetNextItemWidth/PushItemWidth(-100)", "Align to right edge minus 100", -100, "float##2a", "float (indented)##2b")
|
|
block("SetNextItemWidth/PushItemWidth(GetContentRegionAvail().x * 0.5f)", "Half of available width.\n(~ right-cursor_pos)\n(works within a column set)", ImGui.GetContentRegionAvail().x * 0.5, "float##3a", "float (indented)##3b")
|
|
block("SetNextItemWidth/PushItemWidth(-GetContentRegionAvail().x * 0.5f)", "Align to right edge minus half", -ImGui.GetContentRegionAvail().x * 0.5, "float##4a", "float (indented)##4b")
|
|
block("SetNextItemWidth/PushItemWidth(-Min(GetContentRegionAvail().x * 0.40f, GetFontSize() * 12))", nil, -IM_MIN(ImGui.GetFontSize() * 12, ImGui.GetContentRegionAvail().x * 0.40), "float##5a", "float (indented)##5b")
|
|
-- Demonstrate using PushItemWidth to surround three items.
|
|
block("SetNextItemWidth/PushItemWidth(-FLT_MIN)", "Align to right edge", -FLT_MIN, "##float6a", "float (indented)##6b")
|
|
end
|
|
|
|
local function DemoWindowLayout_BasicHorizontal()
|
|
IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout")
|
|
ImGui.TextWrapped("(Use ImGui::SameLine() to keep adding items to the right of the preceding item)")
|
|
|
|
-- Text
|
|
IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout/SameLine")
|
|
ImGui.Text("Two items: Hello"); ImGui.SameLine()
|
|
ImGui.TextColored(ImVec4(1, 1, 0, 1), "Sailor")
|
|
|
|
-- Adjust spacing
|
|
ImGui.Text("More spacing: Hello"); ImGui.SameLine(0, 20)
|
|
ImGui.TextColored(ImVec4(1, 1, 0, 1), "Sailor")
|
|
|
|
-- Button
|
|
ImGui.AlignTextToFramePadding()
|
|
ImGui.Text("Normal buttons"); ImGui.SameLine()
|
|
ImGui.Button("Banana"); ImGui.SameLine()
|
|
ImGui.Button("Apple"); ImGui.SameLine()
|
|
ImGui.Button("Corniflower")
|
|
|
|
-- Button
|
|
ImGui.Text("Small buttons"); ImGui.SameLine()
|
|
ImGui.SmallButton("Like this one"); ImGui.SameLine()
|
|
ImGui.Text("can fit within a text block.")
|
|
|
|
-- Aligned to arbitrary position. Easy/cheap column.
|
|
IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout/SameLine (with offset)")
|
|
ImGui.Text("Aligned")
|
|
ImGui.SameLine(150); ImGui.Text("x=150")
|
|
ImGui.SameLine(300); ImGui.Text("x=300")
|
|
ImGui.Text("Aligned")
|
|
ImGui.SameLine(150); ImGui.SmallButton("x=150")
|
|
ImGui.SameLine(300); ImGui.SmallButton("x=300")
|
|
|
|
-- Checkbox
|
|
IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout/SameLine (more)")
|
|
_, SL.c1 = ImGui.Checkbox("My", SL.c1); ImGui.SameLine()
|
|
_, SL.c2 = ImGui.Checkbox("Tailor", SL.c2); ImGui.SameLine()
|
|
_, SL.c3 = ImGui.Checkbox("Is", SL.c3); ImGui.SameLine()
|
|
_, SL.c4 = ImGui.Checkbox("Rich", SL.c4)
|
|
|
|
-- Various
|
|
ImGui.PushItemWidth(ImGui.CalcTextSize("AAAAAAA").x)
|
|
local items = { "AAAA", "BBBB", "CCCC", "DDDD" }
|
|
if ImGui.Combo then
|
|
SL.item = ImGui.Combo("Combo", SL.item, items, #items)
|
|
else
|
|
NotPorted("Combo")
|
|
end
|
|
ImGui.SameLine()
|
|
SL.f0 = ImGui.SliderFloat("X", SL.f0, 0.0, 5.0); ImGui.SameLine()
|
|
SL.f1 = ImGui.SliderFloat("Y", SL.f1, 0.0, 5.0); ImGui.SameLine()
|
|
SL.f2 = ImGui.SliderFloat("Z", SL.f2, 0.0, 5.0)
|
|
|
|
ImGui.Text("Lists:")
|
|
for i = 1, 4 do
|
|
if i > 1 then ImGui.SameLine() end
|
|
ImGui.PushID(i - 1)
|
|
if ImGui.ListBox then
|
|
SL.selection[i] = ImGui.ListBox("", SL.selection[i], items, #items)
|
|
else
|
|
NotPorted("ListBox")
|
|
end
|
|
ImGui.PopID()
|
|
end
|
|
ImGui.PopItemWidth()
|
|
|
|
-- Dummy
|
|
IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout/Dummy")
|
|
local button_sz = ImVec2(40, 40)
|
|
ImGui.Button("A", button_sz); ImGui.SameLine()
|
|
ImGui.Dummy(button_sz); ImGui.SameLine()
|
|
ImGui.Button("B", button_sz)
|
|
|
|
-- Manually wrapping
|
|
IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout/Manual wrapping")
|
|
ImGui.Text("Manual wrapping:")
|
|
local style = ImGui.GetStyle()
|
|
local buttons_count = 20
|
|
local window_visible_x2 = ImGui.GetCursorScreenPos().x + ImGui.GetContentRegionAvail().x
|
|
for n = 0, buttons_count - 1 do
|
|
ImGui.PushID(n)
|
|
ImGui.Button("Box", button_sz)
|
|
local last_button_x2 = ImGui.GetItemRectMax().x
|
|
local next_button_x2 = last_button_x2 + style.ItemSpacing.x + button_sz.x -- Expected position if next button was on same line
|
|
if n + 1 < buttons_count and next_button_x2 < window_visible_x2 then
|
|
ImGui.SameLine()
|
|
end
|
|
ImGui.PopID()
|
|
end
|
|
end
|
|
|
|
local function DemoWindowLayout_Groups()
|
|
IMGUI_DEMO_MARKER("Layout/Groups")
|
|
DemoHelpMarker(
|
|
"BeginGroup() basically locks the horizontal position for new line. " ..
|
|
"EndGroup() bundles the whole group so that you can use \"item\" functions such as " ..
|
|
"IsItemHovered()/IsItemActive() or SameLine() etc. on the whole group.")
|
|
ImGui.BeginGroup()
|
|
do
|
|
ImGui.BeginGroup()
|
|
ImGui.Button("AAA")
|
|
ImGui.SameLine()
|
|
ImGui.Button("BBB")
|
|
ImGui.SameLine()
|
|
ImGui.BeginGroup()
|
|
ImGui.Button("CCC")
|
|
ImGui.Button("DDD")
|
|
ImGui.EndGroup()
|
|
ImGui.SameLine()
|
|
ImGui.Button("EEE")
|
|
ImGui.EndGroup()
|
|
ImGui.SetItemTooltip("First group hovered")
|
|
end
|
|
-- Capture the group size and create widgets using the same size
|
|
local size = ImGui.GetItemRectSize()
|
|
local values = { 0.5, 0.20, 0.80, 0.60, 0.25 }
|
|
ImGui.PlotHistogram("##values", values, nil, #values, 0, nil, 0.0, 1.0, size)
|
|
|
|
ImGui.Button("ACTION", ImVec2((size.x - ImGui.GetStyle().ItemSpacing.x) * 0.5, size.y))
|
|
ImGui.SameLine()
|
|
ImGui.Button("REACTION", ImVec2((size.x - ImGui.GetStyle().ItemSpacing.x) * 0.5, size.y))
|
|
ImGui.EndGroup()
|
|
ImGui.SameLine()
|
|
|
|
ImGui.Button("LEVERAGE\nBUZZWORD", size)
|
|
ImGui.SameLine()
|
|
|
|
if ImGui.BeginListBox and ImGui.BeginListBox("List", size) then
|
|
ImGui.Selectable("Selected", true)
|
|
ImGui.Selectable("Not Selected", false)
|
|
ImGui.EndListBox()
|
|
end
|
|
end
|
|
|
|
local function DemoWindowLayout_TextBaseline()
|
|
IMGUI_DEMO_MARKER("Layout/Text Baseline Alignment")
|
|
do
|
|
ImGui.BulletText("Text baseline:")
|
|
ImGui.SameLine(); DemoHelpMarker(
|
|
"This is testing the vertical alignment that gets applied on text to keep it aligned with widgets. " ..
|
|
"Lines only composed of text or \"small\" widgets use less vertical space than lines with framed widgets.")
|
|
ImGui.Indent()
|
|
|
|
ImGui.Text("KO Blahblah"); ImGui.SameLine()
|
|
ImGui.Button("Some framed item"); ImGui.SameLine()
|
|
DemoHelpMarker("Baseline of button will look misaligned with text..")
|
|
|
|
ImGui.AlignTextToFramePadding()
|
|
ImGui.Text("OK Blahblah"); ImGui.SameLine()
|
|
ImGui.Button("Some framed item##2"); ImGui.SameLine()
|
|
DemoHelpMarker("We call AlignTextToFramePadding() to vertically align the text baseline by +FramePadding.y")
|
|
|
|
-- SmallButton() uses the same vertical padding as Text
|
|
ImGui.Button("TEST##1"); ImGui.SameLine()
|
|
ImGui.Text("TEST"); ImGui.SameLine()
|
|
ImGui.SmallButton("TEST##2")
|
|
|
|
ImGui.AlignTextToFramePadding()
|
|
ImGui.Text("Text aligned to framed item"); ImGui.SameLine()
|
|
ImGui.Button("Item##1"); ImGui.SameLine()
|
|
ImGui.Text("Item"); ImGui.SameLine()
|
|
ImGui.SmallButton("Item##2"); ImGui.SameLine()
|
|
ImGui.Button("Item##3")
|
|
|
|
ImGui.Unindent()
|
|
end
|
|
|
|
ImGui.Spacing()
|
|
|
|
do
|
|
ImGui.BulletText("Multi-line text:")
|
|
ImGui.Indent()
|
|
ImGui.Text("One\nTwo\nThree"); ImGui.SameLine()
|
|
ImGui.Text("Hello\nWorld"); ImGui.SameLine()
|
|
ImGui.Text("Banana")
|
|
|
|
ImGui.Text("Banana"); ImGui.SameLine()
|
|
ImGui.Text("Hello\nWorld"); ImGui.SameLine()
|
|
ImGui.Text("One\nTwo\nThree")
|
|
|
|
ImGui.Button("HOP##1"); ImGui.SameLine()
|
|
ImGui.Text("Banana"); ImGui.SameLine()
|
|
ImGui.Text("Hello\nWorld"); ImGui.SameLine()
|
|
ImGui.Text("Banana")
|
|
|
|
ImGui.Button("HOP##2"); ImGui.SameLine()
|
|
ImGui.Text("Hello\nWorld"); ImGui.SameLine()
|
|
ImGui.Text("Banana")
|
|
ImGui.Unindent()
|
|
end
|
|
|
|
ImGui.Spacing()
|
|
|
|
do
|
|
ImGui.BulletText("Misc items:")
|
|
ImGui.Indent()
|
|
|
|
ImGui.Button("80x80", ImVec2(80, 80))
|
|
ImGui.SameLine()
|
|
ImGui.Button("50x50", ImVec2(50, 50))
|
|
ImGui.SameLine()
|
|
ImGui.Button("Button()")
|
|
ImGui.SameLine()
|
|
ImGui.SmallButton("SmallButton()")
|
|
|
|
-- Tree
|
|
local spacing = ImGui.GetStyle().ItemInnerSpacing.x
|
|
ImGui.Button("Button##1") -- Will make line higher
|
|
ImGui.SameLine(0.0, spacing)
|
|
if ImGui.TreeNodeEx("Node##1", ImGuiTreeNodeFlags.DrawLinesNone) then
|
|
for i = 0, 5 do
|
|
ImGui.BulletText("Item %d..", i)
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
local padding = math.floor(ImGui.GetFontSize() * 1.20) -- Large padding
|
|
ImGui.PushStyleVarY(ImGuiStyleVar.FramePadding, padding)
|
|
ImGui.Button("Button##2")
|
|
ImGui.PopStyleVar()
|
|
ImGui.SameLine(0.0, spacing)
|
|
if ImGui.TreeNodeEx("Node##2", ImGuiTreeNodeFlags.DrawLinesNone) then
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
ImGui.AlignTextToFramePadding()
|
|
|
|
local node_open = ImGui.TreeNode("Node##3")
|
|
ImGui.SameLine(0.0, spacing); ImGui.Button("Button##3")
|
|
if node_open then
|
|
for i = 0, 5 do
|
|
ImGui.BulletText("Item %d..", i)
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
-- Bullet
|
|
ImGui.Button("Button##4")
|
|
ImGui.SameLine(0.0, spacing)
|
|
ImGui.BulletText("Bullet text")
|
|
|
|
ImGui.AlignTextToFramePadding()
|
|
ImGui.BulletText("Node")
|
|
ImGui.SameLine(0.0, spacing); ImGui.Button("Button##5")
|
|
ImGui.Unindent()
|
|
end
|
|
end
|
|
|
|
local function DemoWindowLayout_HorizontalContentsSizeWindow()
|
|
if SL.explicit_content_size then
|
|
ImGui.SetNextWindowContentSize(ImVec2(SL.contents_size_x, 0.0))
|
|
end
|
|
SL.show_horizontal_contents_size_demo_window = ImGui.Begin("Horizontal contents size demo window", SL.show_horizontal_contents_size_demo_window, SL.show_h_scrollbar and ImGuiWindowFlags.HorizontalScrollbar or 0)
|
|
IMGUI_DEMO_MARKER("Layout/Scrolling/Horizontal contents size demo window")
|
|
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, ImVec2(2, 0))
|
|
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, ImVec2(2, 0))
|
|
DemoHelpMarker(
|
|
"Test how different widgets react and impact the work rectangle growing when horizontal scrolling is enabled.\n\n" ..
|
|
"Use 'Metrics->Tools->Show windows rectangles' to visualize rectangles.")
|
|
_, SL.show_h_scrollbar = ImGui.Checkbox("H-scrollbar", SL.show_h_scrollbar)
|
|
_, SL.show_button = ImGui.Checkbox("Button", SL.show_button)
|
|
_, SL.show_tree_nodes = ImGui.Checkbox("Tree nodes", SL.show_tree_nodes)
|
|
_, SL.show_text_wrapped = ImGui.Checkbox("Text wrapped", SL.show_text_wrapped)
|
|
_, SL.show_columns = ImGui.Checkbox("Columns", SL.show_columns)
|
|
_, SL.show_tab_bar = ImGui.Checkbox("Tab bar", SL.show_tab_bar)
|
|
_, SL.show_child = ImGui.Checkbox("Child", SL.show_child)
|
|
_, SL.explicit_content_size = ImGui.Checkbox("Explicit content size", SL.explicit_content_size)
|
|
ImGui.Text("Scroll %.1f/%.1f %.1f/%.1f", ImGui.GetScrollX(), ImGui.GetScrollMaxX(), ImGui.GetScrollY(), ImGui.GetScrollMaxY())
|
|
if SL.explicit_content_size then
|
|
ImGui.SameLine()
|
|
ImGui.SetNextItemWidth(ImGui.CalcTextSize("123456").x)
|
|
SL.contents_size_x = ImGui.DragFloat("##csx", SL.contents_size_x)
|
|
local p = ImGui.GetCursorScreenPos()
|
|
ImGui.GetWindowDrawList():AddRectFilled(p, ImVec2(p.x + 10, p.y + 10), IM_COL32_WHITE)
|
|
ImGui.GetWindowDrawList():AddRectFilled(ImVec2(p.x + SL.contents_size_x - 10, p.y), ImVec2(p.x + SL.contents_size_x, p.y + 10), IM_COL32_WHITE)
|
|
ImGui.Dummy(ImVec2(0, 10))
|
|
end
|
|
ImGui.PopStyleVar(2)
|
|
ImGui.Separator()
|
|
if SL.show_button then
|
|
ImGui.Button("this is a 300-wide button", ImVec2(300, 0))
|
|
end
|
|
if SL.show_tree_nodes then
|
|
local open = true
|
|
if ImGui.TreeNode("this is a tree node") then
|
|
if ImGui.TreeNode("another one of those tree node...") then
|
|
ImGui.Text("Some tree contents")
|
|
ImGui.TreePop()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
ImGui.CollapsingHeader("CollapsingHeader", open)
|
|
end
|
|
if SL.show_text_wrapped then
|
|
ImGui.TextWrapped("This text should automatically wrap on the edge of the work rectangle.")
|
|
end
|
|
if SL.show_columns then
|
|
ImGui.Text("Tables:")
|
|
if ImGui.BeginTable("table", 4, ImGuiTableFlags.Borders) then
|
|
for n = 0, 3 do
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("Width %.2f", ImGui.GetContentRegionAvail().x)
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
ImGui.Text("Columns:")
|
|
if ImGui.Columns then
|
|
ImGui.Columns(4)
|
|
for n = 0, 3 do
|
|
ImGui.Text("Width %.2f", ImGui.GetColumnWidth())
|
|
ImGui.NextColumn()
|
|
end
|
|
ImGui.Columns(1)
|
|
else
|
|
NotPorted("Columns")
|
|
end
|
|
end
|
|
if SL.show_tab_bar and ImGui.BeginTabBar and ImGui.BeginTabBar("Hello") then
|
|
if ImGui.BeginTabItem("OneOneOne") then ImGui.EndTabItem() end
|
|
if ImGui.BeginTabItem("TwoTwoTwo") then ImGui.EndTabItem() end
|
|
if ImGui.BeginTabItem("ThreeThreeThree") then ImGui.EndTabItem() end
|
|
if ImGui.BeginTabItem("FourFourFour") then ImGui.EndTabItem() end
|
|
ImGui.EndTabBar()
|
|
end
|
|
if SL.show_child then
|
|
BeginChild("child", ImVec2(0, 0), ImGuiChildFlags.Borders)
|
|
ImGui.EndChild()
|
|
end
|
|
ImGui.End()
|
|
end
|
|
|
|
local function DemoWindowLayout_Scrolling()
|
|
IMGUI_DEMO_MARKER("Layout/Scrolling/Vertical")
|
|
DemoHelpMarker("Use SetScrollHereY() or SetScrollFromPosY() to scroll to a given vertical position.")
|
|
|
|
_, SL.enable_extra_decorations = ImGui.Checkbox("Decoration", SL.enable_extra_decorations)
|
|
|
|
ImGui.PushItemWidth(ImGui.GetFontSize() * 10)
|
|
local changed
|
|
SL.track_item, changed = ImGui.DragInt("##item", SL.track_item, 0.25, 0, 99, "Item = %d")
|
|
SL.enable_track = SL.enable_track or changed
|
|
ImGui.SameLine()
|
|
_, SL.enable_track = ImGui.Checkbox("Track", SL.enable_track)
|
|
|
|
local scroll_to_off
|
|
SL.scroll_to_off_px, scroll_to_off = ImGui.DragFloat("##off", SL.scroll_to_off_px, 1.00, 0, FLT_MAX, "+%.0f px")
|
|
ImGui.SameLine()
|
|
scroll_to_off = ImGui.Button("Scroll Offset") or scroll_to_off
|
|
|
|
local scroll_to_pos
|
|
SL.scroll_to_pos_px, scroll_to_pos = ImGui.DragFloat("##pos", SL.scroll_to_pos_px, 1.00, -10, FLT_MAX, "X/Y = %.0f px")
|
|
ImGui.SameLine()
|
|
scroll_to_pos = ImGui.Button("Scroll To Pos") or scroll_to_pos
|
|
ImGui.PopItemWidth()
|
|
|
|
if scroll_to_off or scroll_to_pos then
|
|
SL.enable_track = false
|
|
end
|
|
|
|
local style = ImGui.GetStyle()
|
|
local child_w = (ImGui.GetContentRegionAvail().x - 4 * style.ItemSpacing.x) / 5
|
|
if child_w < 1.0 then
|
|
child_w = 1.0
|
|
end
|
|
ImGui.PushID("##VerticalScrolling")
|
|
local vnames = { "Top", "25%", "Center", "75%", "Bottom" }
|
|
for i = 0, 4 do
|
|
if i > 0 then ImGui.SameLine() end
|
|
ImGui.BeginGroup()
|
|
ImGui.TextUnformatted(vnames[i + 1])
|
|
|
|
local child_flags = SL.enable_extra_decorations and ImGuiWindowFlags.MenuBar or 0
|
|
local child_id = ImGui.GetID(i)
|
|
local child_is_visible = BeginChild(child_id, ImVec2(child_w, 200.0), ImGuiChildFlags.Borders, child_flags)
|
|
if ImGui.BeginMenuBar() then
|
|
ImGui.TextUnformatted("abc")
|
|
ImGui.EndMenuBar()
|
|
end
|
|
if scroll_to_off then
|
|
ImGui.SetScrollY(SL.scroll_to_off_px)
|
|
end
|
|
if scroll_to_pos then
|
|
ImGui.SetScrollFromPosY(ImGui.GetCursorStartPos().y + SL.scroll_to_pos_px, i * 0.25)
|
|
end
|
|
if child_is_visible then -- Avoid calling SetScrollHereY when running with culled items
|
|
for item = 0, 99 do
|
|
if SL.enable_track and item == SL.track_item then
|
|
ImGui.TextColored(ImVec4(1, 1, 0, 1), "Item %d", item)
|
|
ImGui.SetScrollHereY(i * 0.25) -- 0.0f:top, 0.5f:center, 1.0f:bottom
|
|
else
|
|
ImGui.Text("Item %d", item)
|
|
end
|
|
end
|
|
end
|
|
local scroll_y = ImGui.GetScrollY()
|
|
local scroll_max_y = ImGui.GetScrollMaxY()
|
|
ImGui.EndChild()
|
|
ImGui.Text("%.0f/%.0f", scroll_y, scroll_max_y)
|
|
ImGui.EndGroup()
|
|
end
|
|
ImGui.PopID()
|
|
|
|
-- Horizontal scroll functions
|
|
IMGUI_DEMO_MARKER("Layout/Scrolling/Horizontal")
|
|
ImGui.Spacing()
|
|
DemoHelpMarker(
|
|
"Use SetScrollHereX() or SetScrollFromPosX() to scroll to a given horizontal position.\n\n" ..
|
|
"Because the clipping rectangle of most window hides half worth of WindowPadding on the " ..
|
|
"left/right, using SetScrollFromPosX(+1) will usually result in clipped text whereas the " ..
|
|
"equivalent SetScrollFromPosY(+1) wouldn't.")
|
|
ImGui.PushID("##HorizontalScrolling")
|
|
local hnames = { "Left", "25%", "Center", "75%", "Right" }
|
|
for i = 0, 4 do
|
|
local child_height = ImGui.GetTextLineHeight() + style.ScrollbarSize + style.WindowPadding.y * 2.0
|
|
local child_flags = bit32.bor(ImGuiWindowFlags.HorizontalScrollbar, SL.enable_extra_decorations and ImGuiWindowFlags.AlwaysVerticalScrollbar or 0)
|
|
local child_id = ImGui.GetID(i)
|
|
local child_is_visible = BeginChild(child_id, ImVec2(-100, child_height), ImGuiChildFlags.Borders, child_flags)
|
|
if scroll_to_off then
|
|
ImGui.SetScrollX(SL.scroll_to_off_px)
|
|
end
|
|
if scroll_to_pos then
|
|
ImGui.SetScrollFromPosX(ImGui.GetCursorStartPos().x + SL.scroll_to_pos_px, i * 0.25)
|
|
end
|
|
if child_is_visible then
|
|
for item = 0, 99 do
|
|
if item > 0 then
|
|
ImGui.SameLine()
|
|
end
|
|
if SL.enable_track and item == SL.track_item then
|
|
ImGui.TextColored(ImVec4(1, 1, 0, 1), "Item %d", item)
|
|
ImGui.SetScrollHereX(i * 0.25) -- 0.0f:left, 0.5f:center, 1.0f:right
|
|
else
|
|
ImGui.Text("Item %d", item)
|
|
end
|
|
end
|
|
end
|
|
local scroll_x = ImGui.GetScrollX()
|
|
local scroll_max_x = ImGui.GetScrollMaxX()
|
|
ImGui.EndChild()
|
|
ImGui.SameLine()
|
|
ImGui.Text("%s\n%.0f/%.0f", hnames[i + 1], scroll_x, scroll_max_x)
|
|
ImGui.Spacing()
|
|
end
|
|
ImGui.PopID()
|
|
|
|
-- Miscellaneous Horizontal Scrolling Demo
|
|
IMGUI_DEMO_MARKER("Layout/Scrolling/Horizontal (more)")
|
|
DemoHelpMarker(
|
|
"Horizontal scrolling for a window is enabled via the ImGuiWindowFlags_HorizontalScrollbar flag.\n\n" ..
|
|
"You may want to also explicitly specify content width by using SetNextWindowContentWidth() before Begin().")
|
|
SL.lines = ImGui.SliderInt("Lines", SL.lines, 1, 15)
|
|
ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 3.0)
|
|
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, ImVec2(2.0, 1.0))
|
|
local scrolling_child_size = ImVec2(0, ImGui.GetFrameHeightWithSpacing() * 7 + 30)
|
|
BeginChild("scrolling", scrolling_child_size, ImGuiChildFlags.Borders, ImGuiWindowFlags.HorizontalScrollbar)
|
|
for line = 0, SL.lines - 1 do
|
|
local num_buttons = 10 + ((line % 2 == 1) and line * 9 or line * 3)
|
|
local base_w = ImGui.GetFontSize() * 3
|
|
for n = 0, num_buttons - 1 do
|
|
if n > 0 then ImGui.SameLine() end
|
|
ImGui.PushID(n + line * 1000)
|
|
local label = (n % 15 == 0) and "FizzBuzz" or (n % 3 == 0) and "Fizz" or (n % 5 == 0) and "Buzz" or tostring(n)
|
|
local hue = n * 0.05
|
|
ImGui.PushStyleColor(ImGuiCol.Button, HSV(hue, 0.6, 0.6))
|
|
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, HSV(hue, 0.7, 0.7))
|
|
ImGui.PushStyleColor(ImGuiCol.ButtonActive, HSV(hue, 0.8, 0.8))
|
|
ImGui.Button(label, ImVec2(base_w + math.sin(line + n) * base_w * 0.5, 0.0))
|
|
ImGui.PopStyleColor(3)
|
|
ImGui.PopID()
|
|
end
|
|
end
|
|
local scroll_x = ImGui.GetScrollX()
|
|
local scroll_max_x = ImGui.GetScrollMaxX()
|
|
ImGui.EndChild()
|
|
ImGui.PopStyleVar(2)
|
|
local scroll_x_delta = 0.0
|
|
ImGui.SmallButton("<<")
|
|
if ImGui.IsItemActive() then
|
|
scroll_x_delta = -ImGui.GetIO().DeltaTime * 1000.0
|
|
end
|
|
ImGui.SameLine()
|
|
ImGui.Text("Scroll from code"); ImGui.SameLine()
|
|
ImGui.SmallButton(">>")
|
|
if ImGui.IsItemActive() then
|
|
scroll_x_delta = ImGui.GetIO().DeltaTime * 1000.0
|
|
end
|
|
ImGui.SameLine()
|
|
ImGui.Text("%.0f/%.0f", scroll_x, scroll_max_x)
|
|
if scroll_x_delta ~= 0.0 then
|
|
-- Demonstrate a trick: you can use Begin to set yourself in the context of another window
|
|
BeginChild("scrolling")
|
|
ImGui.SetScrollX(ImGui.GetScrollX() + scroll_x_delta)
|
|
ImGui.EndChild()
|
|
end
|
|
ImGui.Spacing()
|
|
|
|
_, SL.show_horizontal_contents_size_demo_window = ImGui.Checkbox("Show Horizontal contents size demo window", SL.show_horizontal_contents_size_demo_window)
|
|
|
|
if SL.show_horizontal_contents_size_demo_window then
|
|
DemoWindowLayout_HorizontalContentsSizeWindow()
|
|
end
|
|
end
|
|
|
|
local function DemoWindowLayout_TextClipping()
|
|
IMGUI_DEMO_MARKER("Layout/Text Clipping")
|
|
if SL.clip_size == nil then SL.clip_size = { 100.0, 100.0 }; SL.clip_offset = ImVec2(30.0, 30.0) end
|
|
ImGui.DragFloat2("size", SL.clip_size, 0.5, 1.0, 200.0, "%.0f")
|
|
ImGui.TextWrapped("(Click and drag to scroll)")
|
|
|
|
DemoHelpMarker(
|
|
"(Left) Using ImGui::PushClipRect():\n" ..
|
|
"Will alter ImGui hit-testing logic + ImDrawList rendering.\n" ..
|
|
"(use this if you want your clipping rectangle to affect interactions)\n\n" ..
|
|
"(Center) Using ImDrawList::PushClipRect():\n" ..
|
|
"Will alter ImDrawList rendering only.\n" ..
|
|
"(use this as a shortcut if you are only using ImDrawList calls)\n\n" ..
|
|
"(Right) Using ImDrawList::AddText() with a fine ClipRect:\n" ..
|
|
"Will alter only this specific ImDrawList::AddText() rendering.\n" ..
|
|
"This is often used internally to avoid altering the clipping rectangle and minimize draw calls.")
|
|
|
|
local size = ImVec2(SL.clip_size[1], SL.clip_size[2])
|
|
local offset = SL.clip_offset
|
|
for n = 0, 2 do repeat
|
|
if n > 0 then
|
|
ImGui.SameLine()
|
|
end
|
|
|
|
ImGui.PushID(n)
|
|
ImGui.InvisibleButton("##canvas", size)
|
|
if ImGui.IsItemActive() and ImGui.IsMouseDragging(ImGuiMouseButton.Left) then
|
|
offset.x = offset.x + ImGui.GetIO().MouseDelta.x
|
|
offset.y = offset.y + ImGui.GetIO().MouseDelta.y
|
|
end
|
|
ImGui.PopID()
|
|
if not ImGui.IsItemVisible() then -- Skip rendering as ImDrawList elements are not clipped.
|
|
break
|
|
end
|
|
|
|
local p0 = ImGui.GetItemRectMin()
|
|
local p1 = ImGui.GetItemRectMax()
|
|
local text_str = "Line 1 hello\nLine 2 clip me!"
|
|
local text_pos = ImVec2(p0.x + offset.x, p0.y + offset.y)
|
|
local draw_list = ImGui.GetWindowDrawList()
|
|
if n == 0 then
|
|
ImGui.PushClipRect(p0, p1, true)
|
|
draw_list:AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255))
|
|
draw_list:AddText(text_pos, IM_COL32_WHITE, text_str)
|
|
ImGui.PopClipRect()
|
|
elseif n == 1 then
|
|
draw_list:PushClipRect(p0, p1, true)
|
|
draw_list:AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255))
|
|
draw_list:AddText(text_pos, IM_COL32_WHITE, text_str)
|
|
draw_list:PopClipRect()
|
|
else
|
|
local clip_rect = ImVec4(p0.x, p0.y, p1.x, p1.y)
|
|
draw_list:AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255))
|
|
draw_list:AddText(ImGui.GetFont(), ImGui.GetFontSize(), text_pos, IM_COL32_WHITE, text_str, nil, 0.0, clip_rect)
|
|
end
|
|
until true end
|
|
end
|
|
|
|
local function DemoWindowLayout_OverlapMode()
|
|
IMGUI_DEMO_MARKER("Layout/Overlap Mode")
|
|
DemoHelpMarker(
|
|
"Hit-testing is by default performed in item submission order, which generally is perceived as 'back-to-front'.\n\n" ..
|
|
"By using SetNextItemAllowOverlap() you can notify that an item may be overlapped by another. " ..
|
|
"Doing so alters the hovering logic: items using AllowOverlap mode requires an extra frame to accept hovered state.")
|
|
_, SL.enable_allow_overlap = ImGui.Checkbox("Enable AllowOverlap", SL.enable_allow_overlap)
|
|
|
|
local button1_pos = ImGui.GetCursorScreenPos()
|
|
local button2_pos = ImVec2(button1_pos.x + 50.0, button1_pos.y + 50.0)
|
|
if SL.enable_allow_overlap then
|
|
ImGui.SetNextItemAllowOverlap()
|
|
end
|
|
ImGui.Button("Button 1", ImVec2(80, 80))
|
|
ImGui.SetCursorScreenPos(button2_pos)
|
|
ImGui.Button("Button 2", ImVec2(80, 80))
|
|
|
|
if SL.enable_allow_overlap then
|
|
ImGui.SetNextItemAllowOverlap()
|
|
end
|
|
ImGui.Selectable("Some Selectable", false)
|
|
ImGui.SameLine()
|
|
ImGui.SmallButton("++")
|
|
end
|
|
|
|
function DemoWindowLayout()
|
|
if not ImGui.CollapsingHeader("Layout & Scrolling") then
|
|
return
|
|
end
|
|
if ImGui.TreeNode("Child windows") then DemoWindowLayout_ChildWindows(); ImGui.TreePop() end
|
|
if ImGui.TreeNode("Widgets Width") then DemoWindowLayout_WidgetsWidth(); ImGui.TreePop() end
|
|
if ImGui.TreeNode("Basic Horizontal Layout") then DemoWindowLayout_BasicHorizontal(); ImGui.TreePop() end
|
|
if ImGui.TreeNode("Groups") then DemoWindowLayout_Groups(); ImGui.TreePop() end
|
|
if ImGui.TreeNode("Text Baseline Alignment") then DemoWindowLayout_TextBaseline(); ImGui.TreePop() end
|
|
if ImGui.TreeNode("Scrolling") then DemoWindowLayout_Scrolling(); ImGui.TreePop() end
|
|
if ImGui.TreeNode("Text Clipping") then DemoWindowLayout_TextClipping(); ImGui.TreePop() end
|
|
if ImGui.TreeNode("Overlap Mode") then DemoWindowLayout_OverlapMode(); ImGui.TreePop() end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- [SECTION] DemoWindowPopups()
|
|
-------------------------------------------------------------------------------
|
|
|
|
local SP = {
|
|
selected_fish = -1, toggles = { true, false, false, false, false },
|
|
ctx_selected = -1, value = 0.5, name = nil,
|
|
dont_ask_me_next_time = false, item = 1, color = { 0.4, 0.7, 0.0, 0.5 },
|
|
}
|
|
|
|
local function DemoWindowPopups_Popups()
|
|
IMGUI_DEMO_MARKER("Popups/Popups")
|
|
ImGui.TextWrapped(
|
|
"When a popup is active, it inhibits interacting with windows that are behind the popup. " ..
|
|
"Clicking outside the popup closes it.")
|
|
|
|
local names = { "Bream", "Haddock", "Mackerel", "Pollock", "Tilefish" }
|
|
local toggles = SP.toggles
|
|
|
|
if ImGui.Button("Select..") then
|
|
ImGui.OpenPopup("my_select_popup")
|
|
end
|
|
ImGui.SameLine()
|
|
ImGui.TextUnformatted(SP.selected_fish == -1 and "<None>" or names[SP.selected_fish + 1])
|
|
if ImGui.BeginPopup("my_select_popup") then
|
|
ImGui.SeparatorText("Aquarium")
|
|
for i = 1, #names do
|
|
if ImGui.Selectable(names[i]) then
|
|
SP.selected_fish = i - 1
|
|
end
|
|
end
|
|
ImGui.EndPopup()
|
|
end
|
|
|
|
-- Showing a menu with toggles
|
|
if ImGui.Button("Toggle..") then
|
|
ImGui.OpenPopup("my_toggle_popup")
|
|
end
|
|
if ImGui.BeginPopup("my_toggle_popup") then
|
|
for i = 1, #names do
|
|
_, toggles[i] = ImGui.MenuItem(names[i], "", toggles[i])
|
|
end
|
|
if ImGui.BeginMenu("Sub-menu") then
|
|
ImGui.MenuItem("Click me")
|
|
ImGui.EndMenu()
|
|
end
|
|
|
|
ImGui.Separator()
|
|
ImGui.Text("Tooltip here")
|
|
ImGui.SetItemTooltip("I am a tooltip over a popup")
|
|
|
|
if ImGui.Button("Stacked Popup") then
|
|
ImGui.OpenPopup("another popup")
|
|
end
|
|
if ImGui.BeginPopup("another popup") then
|
|
for i = 1, #names do
|
|
_, toggles[i] = ImGui.MenuItem(names[i], "", toggles[i])
|
|
end
|
|
if ImGui.BeginMenu("Sub-menu") then
|
|
ImGui.MenuItem("Click me")
|
|
if ImGui.Button("Stacked Popup") then
|
|
ImGui.OpenPopup("another popup")
|
|
end
|
|
if ImGui.BeginPopup("another popup") then
|
|
ImGui.Text("I am the last one here.")
|
|
ImGui.EndPopup()
|
|
end
|
|
ImGui.EndMenu()
|
|
end
|
|
ImGui.EndPopup()
|
|
end
|
|
ImGui.EndPopup()
|
|
end
|
|
|
|
-- Call the more complete ShowExampleMenuFile which we use in various places of this demo
|
|
if ImGui.Button("With a menu..") then
|
|
ImGui.OpenPopup("my_file_popup")
|
|
end
|
|
if ImGui.BeginPopup("my_file_popup", ImGuiWindowFlags.MenuBar) then
|
|
if ImGui.BeginMenuBar() then
|
|
if ImGui.BeginMenu("File") then
|
|
DemoMenuFile()
|
|
ImGui.EndMenu()
|
|
end
|
|
if ImGui.BeginMenu("Edit") then
|
|
ImGui.MenuItem("Dummy")
|
|
ImGui.EndMenu()
|
|
end
|
|
ImGui.EndMenuBar()
|
|
end
|
|
ImGui.Text("Hello from popup!")
|
|
ImGui.Button("This is a dummy button..")
|
|
ImGui.EndPopup()
|
|
end
|
|
end
|
|
|
|
local function DemoWindowPopups_ContextMenus()
|
|
IMGUI_DEMO_MARKER("Popups/Context menus")
|
|
DemoHelpMarker("\"Context\" functions are simple helpers to associate a Popup to a given Item or Window identifier.")
|
|
|
|
-- Example 1
|
|
do
|
|
local names = { "Label1", "Label2", "Label3", "Label4", "Label5" }
|
|
for n = 0, 4 do
|
|
if ImGui.Selectable(names[n + 1], SP.ctx_selected == n) then
|
|
SP.ctx_selected = n
|
|
end
|
|
if ImGui.BeginPopupContextItem() then -- <-- use last item id as popup id
|
|
SP.ctx_selected = n
|
|
ImGui.Text("This is a popup for \"%s\"!", names[n + 1])
|
|
if ImGui.Button("Close") then
|
|
ImGui.CloseCurrentPopup()
|
|
end
|
|
ImGui.EndPopup()
|
|
end
|
|
ImGui.SetItemTooltip("Right-click to open popup")
|
|
end
|
|
end
|
|
|
|
-- Example 2
|
|
do
|
|
DemoHelpMarker("Text() elements don't have stable identifiers so we need to provide one.")
|
|
ImGui.Text("Value = %.3f <-- (1) right-click this text", SP.value)
|
|
if ImGui.BeginPopupContextItem("my popup") then
|
|
if ImGui.Selectable("Set to zero") then SP.value = 0.0 end
|
|
if ImGui.Selectable("Set to PI") then SP.value = 3.1415 end
|
|
ImGui.SetNextItemWidth(-FLT_MIN)
|
|
SP.value = ImGui.DragFloat("##Value", SP.value, 0.1, 0.0, 0.0)
|
|
ImGui.EndPopup()
|
|
end
|
|
|
|
ImGui.Text("(2) Or right-click this text")
|
|
ImGui.OpenPopupOnItemClick("my popup", ImGuiPopupFlags.MouseButtonRight)
|
|
|
|
if ImGui.Button("(3) Or click this button") then
|
|
ImGui.OpenPopup("my popup")
|
|
end
|
|
end
|
|
|
|
-- Example 3
|
|
do
|
|
DemoHelpMarker("Showcase using a popup ID linked to item ID, with the item having a changing label + stable ID using the ### operator.")
|
|
if SP.name == nil then SP.name = Buf("Label1", 32) end
|
|
local buf = string.format("Button: %s###Button", BufStr(SP.name)) -- ### operator override ID ignoring the preceding label
|
|
ImGui.Button(buf)
|
|
if ImGui.BeginPopupContextItem() then
|
|
ImGui.Text("Edit name:")
|
|
ImGui.InputText("##edit", SP.name, 32)
|
|
if ImGui.Button("Close") then
|
|
ImGui.CloseCurrentPopup()
|
|
end
|
|
ImGui.EndPopup()
|
|
end
|
|
ImGui.SameLine(); ImGui.Text("(<-- right-click here)")
|
|
end
|
|
end
|
|
|
|
local function DemoWindowPopups_Modals()
|
|
IMGUI_DEMO_MARKER("Popups/Modals")
|
|
ImGui.TextWrapped("Modal windows are like popups but the user cannot close them by clicking outside.")
|
|
|
|
if ImGui.Button("Delete..") then
|
|
ImGui.OpenPopup("Delete?")
|
|
end
|
|
|
|
-- Always center this window when appearing
|
|
local center = ImGui.GetMainViewport():GetCenter()
|
|
ImGui.SetNextWindowPos(center, ImGuiCond.Appearing, ImVec2(0.5, 0.5))
|
|
|
|
if ImGui.BeginPopupModal("Delete?", nil, ImGuiWindowFlags.AlwaysAutoResize) then
|
|
ImGui.Text("All those beautiful files will be deleted.\nThis operation cannot be undone!")
|
|
ImGui.Separator()
|
|
|
|
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, ImVec2(0, 0))
|
|
_, SP.dont_ask_me_next_time = ImGui.Checkbox("Don't ask me next time", SP.dont_ask_me_next_time)
|
|
ImGui.PopStyleVar()
|
|
|
|
if ImGui.Button("OK", ImVec2(120, 0)) then ImGui.CloseCurrentPopup() end
|
|
ImGui.SetItemDefaultFocus()
|
|
ImGui.SameLine()
|
|
if ImGui.Button("Cancel", ImVec2(120, 0)) then ImGui.CloseCurrentPopup() end
|
|
ImGui.EndPopup()
|
|
end
|
|
|
|
if ImGui.Button("Stacked modals..") then
|
|
ImGui.OpenPopup("Stacked 1")
|
|
end
|
|
if ImGui.BeginPopupModal("Stacked 1", nil, ImGuiWindowFlags.MenuBar) then
|
|
if ImGui.BeginMenuBar() then
|
|
if ImGui.BeginMenu("File") then
|
|
if ImGui.MenuItem("Some menu item") then end
|
|
ImGui.EndMenu()
|
|
end
|
|
ImGui.EndMenuBar()
|
|
end
|
|
ImGui.Text("Hello from Stacked The First\nUsing style.Colors[ImGuiCol_ModalWindowDimBg] behind it.")
|
|
|
|
-- Testing behavior of widgets stacking their own regular popups over the modal.
|
|
if ImGui.Combo then
|
|
SP.item = ImGui.Combo("Combo", SP.item, { "aaaa", "bbbb", "cccc", "dddd", "eeee" }, 5)
|
|
else
|
|
NotPorted("Combo")
|
|
end
|
|
ImGui.ColorEdit4("Color", SP.color)
|
|
|
|
if ImGui.Button("Add another modal..") then
|
|
ImGui.OpenPopup("Stacked 2")
|
|
end
|
|
|
|
local unused_open = true
|
|
if ImGui.BeginPopupModal("Stacked 2", unused_open) then
|
|
ImGui.Text("Hello from Stacked The Second!")
|
|
ImGui.ColorEdit4("Color", SP.color) -- Allow opening another nested popup
|
|
if ImGui.Button("Close") then
|
|
ImGui.CloseCurrentPopup()
|
|
end
|
|
ImGui.EndPopup()
|
|
end
|
|
|
|
if ImGui.Button("Close") then
|
|
ImGui.CloseCurrentPopup()
|
|
end
|
|
ImGui.EndPopup()
|
|
end
|
|
end
|
|
|
|
function DemoWindowPopups()
|
|
if not ImGui.CollapsingHeader("Popups & Modal windows") then
|
|
return
|
|
end
|
|
|
|
if ImGui.TreeNode("Popups") then DemoWindowPopups_Popups(); ImGui.TreePop() end
|
|
if ImGui.TreeNode("Context menus") then DemoWindowPopups_ContextMenus(); ImGui.TreePop() end
|
|
if ImGui.TreeNode("Modals") then
|
|
if ImGui.BeginPopupModal then DemoWindowPopups_Modals() else NotPorted("BeginPopupModal") end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Menus inside a regular window") then
|
|
IMGUI_DEMO_MARKER("Popups/Menus inside a regular window")
|
|
ImGui.TextWrapped("Below we are testing adding menu items to a regular window. It's rather unusual but should work!")
|
|
ImGui.Separator()
|
|
|
|
ImGui.MenuItem("Menu item", "Ctrl+M")
|
|
if ImGui.BeginMenu("Menu inside a regular window") then
|
|
DemoMenuFile()
|
|
ImGui.EndMenu()
|
|
end
|
|
ImGui.Separator()
|
|
ImGui.TreePop()
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- [SECTION] DemoWindowTables()
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- MyItemColumnID
|
|
local MyItemColumnID_ID, MyItemColumnID_Name, MyItemColumnID_Action, MyItemColumnID_Quantity, MyItemColumnID_Description = 0, 1, 2, 3, 4
|
|
|
|
local function MyItem(id, name, quantity) return { ID = id, Name = name, Quantity = quantity } end
|
|
|
|
--- Sort a Lua array (1-based) of MyItem with ImGuiTableSortSpecs (Specs is 1-based array or ImVector)
|
|
local function MyItem_SortWithSortSpecs(sort_specs, items, items_count)
|
|
if items_count <= 1 then return end
|
|
local specs = sort_specs.Specs
|
|
local function get_spec(n) -- n: 0-based
|
|
if specs.Data then return specs.Data[n + 1] end
|
|
return specs[n + 1]
|
|
end
|
|
local function cmp(a, b) -- returns <0, 0, >0
|
|
for n = 0, sort_specs.SpecsCount - 1 do
|
|
local sort_spec = get_spec(n)
|
|
local delta = 0
|
|
local uid = sort_spec.ColumnUserID
|
|
if uid == MyItemColumnID_ID then delta = a.ID - b.ID
|
|
elseif uid == MyItemColumnID_Name then delta = (a.Name < b.Name) and -1 or (a.Name > b.Name) and 1 or 0
|
|
elseif uid == MyItemColumnID_Quantity then delta = a.Quantity - b.Quantity
|
|
elseif uid == MyItemColumnID_Description then delta = (a.Name < b.Name) and -1 or (a.Name > b.Name) and 1 or 0
|
|
else IM_ASSERT(false) end
|
|
if delta > 0 then
|
|
return (sort_spec.SortDirection == ImGuiSortDirection.Ascending) and 1 or -1
|
|
end
|
|
if delta < 0 then
|
|
return (sort_spec.SortDirection == ImGuiSortDirection.Ascending) and -1 or 1
|
|
end
|
|
end
|
|
return a.ID - b.ID
|
|
end
|
|
local arr = items.Data or items
|
|
if items.Data then
|
|
-- ImVector: sort only the used range
|
|
local tmp = {}
|
|
for i = 1, items_count do tmp[i] = arr[i] end
|
|
table.sort(tmp, function(a, b) return cmp(a, b) < 0 end)
|
|
for i = 1, items_count do arr[i] = tmp[i] end
|
|
else
|
|
table.sort(arr, function(a, b) return cmp(a, b) < 0 end)
|
|
end
|
|
end
|
|
|
|
-- Make the UI compact because there are so many fields
|
|
local function PushStyleCompact()
|
|
local style = ImGui.GetStyle()
|
|
ImGui.PushStyleVarY(ImGuiStyleVar.FramePadding, math.floor(style.FramePadding.y * 0.60))
|
|
ImGui.PushStyleVarY(ImGuiStyleVar.ItemSpacing, math.floor(style.ItemSpacing.y * 0.60))
|
|
end
|
|
|
|
local function PopStyleCompact()
|
|
ImGui.PopStyleVar(2)
|
|
end
|
|
|
|
local table_sizing_policies = nil
|
|
-- Show a combo box with a choice of sizing policies
|
|
local function EditTableSizingFlags(flags)
|
|
if table_sizing_policies == nil then
|
|
table_sizing_policies = {
|
|
{ Value = ImGuiTableFlags.None, Name = "Default", Tooltip = "Use default sizing policy:\n- ImGuiTableFlags_SizingFixedFit if ScrollX is on or if host window has ImGuiWindowFlags_AlwaysAutoResize.\n- ImGuiTableFlags_SizingStretchSame otherwise." },
|
|
{ Value = ImGuiTableFlags.SizingFixedFit, Name = "ImGuiTableFlags_SizingFixedFit", Tooltip = "Columns default to _WidthFixed (if resizable) or _WidthAuto (if not resizable), matching contents width." },
|
|
{ Value = ImGuiTableFlags.SizingFixedSame, Name = "ImGuiTableFlags_SizingFixedSame", Tooltip = "Columns are all the same width, matching the maximum contents width.\nImplicitly disable ImGuiTableFlags_Resizable and enable ImGuiTableFlags_NoKeepColumnsVisible." },
|
|
{ Value = ImGuiTableFlags.SizingStretchProp, Name = "ImGuiTableFlags_SizingStretchProp", Tooltip = "Columns default to _WidthStretch with weights proportional to their widths." },
|
|
{ Value = ImGuiTableFlags.SizingStretchSame, Name = "ImGuiTableFlags_SizingStretchSame", Tooltip = "Columns default to _WidthStretch with same weights." },
|
|
}
|
|
end
|
|
local policies = table_sizing_policies
|
|
local idx = 1
|
|
while idx <= #policies do
|
|
if policies[idx].Value == bit32.band(flags, ImGuiTableFlags.SizingMask_) then break end
|
|
idx = idx + 1
|
|
end
|
|
local preview_text = (idx <= #policies) and (idx > 1 and string.sub(policies[idx].Name, #"ImGuiTableFlags" + 1) or policies[idx].Name) or ""
|
|
if ImGui.BeginCombo("Sizing Policy", preview_text) then
|
|
for n = 1, #policies do
|
|
if ImGui.Selectable(policies[n].Name, idx == n) then
|
|
flags = bit32.bor(bit32.band(flags, bit32.bnot(ImGuiTableFlags.SizingMask_)), policies[n].Value)
|
|
end
|
|
end
|
|
ImGui.EndCombo()
|
|
end
|
|
ImGui.SameLine()
|
|
ImGui.TextDisabled("(?)")
|
|
if ImGui.BeginItemTooltip() then
|
|
ImGui.PushTextWrapPos(ImGui.GetFontSize() * 50.0)
|
|
for m = 1, #policies do
|
|
ImGui.Separator()
|
|
ImGui.Text("%s:", policies[m].Name)
|
|
ImGui.Separator()
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().IndentSpacing * 0.5)
|
|
ImGui.TextUnformatted(policies[m].Tooltip)
|
|
end
|
|
ImGui.PopTextWrapPos()
|
|
ImGui.EndTooltip()
|
|
end
|
|
return flags
|
|
end
|
|
|
|
local function EditTableColumnsFlags(f)
|
|
local p
|
|
local F = ImGuiTableColumnFlags
|
|
_, f = ImGui.CheckboxFlags("_Disabled", f, F.Disabled); ImGui.SameLine(); DemoHelpMarker("Master disable flag (also hide from context menu)")
|
|
_, f = ImGui.CheckboxFlags("_DefaultHide", f, F.DefaultHide)
|
|
_, f = ImGui.CheckboxFlags("_DefaultSort", f, F.DefaultSort)
|
|
p, f = ImGui.CheckboxFlags("_WidthStretch", f, F.WidthStretch)
|
|
if p then f = bit32.band(f, bit32.bnot(bit32.bxor(F.WidthMask_, F.WidthStretch))) end
|
|
p, f = ImGui.CheckboxFlags("_WidthFixed", f, F.WidthFixed)
|
|
if p then f = bit32.band(f, bit32.bnot(bit32.bxor(F.WidthMask_, F.WidthFixed))) end
|
|
_, f = ImGui.CheckboxFlags("_NoResize", f, F.NoResize)
|
|
_, f = ImGui.CheckboxFlags("_NoReorder", f, F.NoReorder)
|
|
_, f = ImGui.CheckboxFlags("_NoHide", f, F.NoHide)
|
|
_, f = ImGui.CheckboxFlags("_NoClip", f, F.NoClip)
|
|
_, f = ImGui.CheckboxFlags("_NoSort", f, F.NoSort)
|
|
_, f = ImGui.CheckboxFlags("_NoSortAscending", f, F.NoSortAscending)
|
|
_, f = ImGui.CheckboxFlags("_NoSortDescending", f, F.NoSortDescending)
|
|
_, f = ImGui.CheckboxFlags("_NoHeaderLabel", f, F.NoHeaderLabel)
|
|
_, f = ImGui.CheckboxFlags("_NoHeaderWidth", f, F.NoHeaderWidth)
|
|
_, f = ImGui.CheckboxFlags("_PreferSortAscending", f, F.PreferSortAscending)
|
|
_, f = ImGui.CheckboxFlags("_PreferSortDescending", f, F.PreferSortDescending)
|
|
_, f = ImGui.CheckboxFlags("_IndentEnable", f, F.IndentEnable); ImGui.SameLine(); DemoHelpMarker("Default for column 0")
|
|
_, f = ImGui.CheckboxFlags("_IndentDisable", f, F.IndentDisable); ImGui.SameLine(); DemoHelpMarker("Default for column >0")
|
|
_, f = ImGui.CheckboxFlags("_AngledHeader", f, F.AngledHeader)
|
|
return f
|
|
end
|
|
|
|
local function ShowTableColumnsStatusFlags(flags)
|
|
ImGui.CheckboxFlags("_IsEnabled", flags, ImGuiTableColumnFlags.IsEnabled)
|
|
ImGui.CheckboxFlags("_IsVisible", flags, ImGuiTableColumnFlags.IsVisible)
|
|
ImGui.CheckboxFlags("_IsSorted", flags, ImGuiTableColumnFlags.IsSorted)
|
|
ImGui.CheckboxFlags("_IsHovered", flags, ImGuiTableColumnFlags.IsHovered)
|
|
end
|
|
|
|
local function bor(...) return bit32.bor(...) end
|
|
local TF = setmetatable({}, { __index = function(_, k) return ImGuiTableFlags[k] end })
|
|
|
|
local ST = {} -- statics for DemoWindowTables (one sub-table per section)
|
|
local TEXT_BASE_WIDTH, TEXT_BASE_HEIGHT = 0, 0
|
|
|
|
local function Tables_Basic()
|
|
IMGUI_DEMO_MARKER("Tables/Basic")
|
|
-- [Method 1] Using TableNextRow() to create a new row, and TableSetColumnIndex() to select the column.
|
|
DemoHelpMarker("Using TableNextRow() + calling TableSetColumnIndex() _before_ each cell, in a loop.")
|
|
if ImGui.BeginTable("table1", 3) then
|
|
for row = 0, 3 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, 2 do
|
|
ImGui.TableSetColumnIndex(column)
|
|
ImGui.Text("Row %d Column %d", row, column)
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
|
|
-- [Method 2] Using TableNextColumn() called multiple times, instead of using a for loop + TableSetColumnIndex().
|
|
DemoHelpMarker("Using TableNextRow() + calling TableNextColumn() _before_ each cell, manually.")
|
|
if ImGui.BeginTable("table2", 3) then
|
|
for row = 0, 3 do
|
|
ImGui.TableNextRow()
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("Row %d", row)
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("Some contents")
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("123.456")
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
|
|
-- [Method 3] We call TableNextColumn() _before_ each cell. We never call TableNextRow(),
|
|
DemoHelpMarker(
|
|
"Only using TableNextColumn(), which tends to be convenient for tables where every cell contains " ..
|
|
"the same type of contents.\n This is also more similar to the old NextColumn() function of the " ..
|
|
"Columns API, and provided to facilitate the Columns->Tables API transition.")
|
|
if ImGui.BeginTable("table3", 3) then
|
|
for item = 0, 13 do
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("Item %d", item)
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_BordersBackground()
|
|
IMGUI_DEMO_MARKER("Tables/Borders, background")
|
|
local CT_Text, CT_FillButton = 0, 1
|
|
local s = ST.borders
|
|
if s == nil then s = { flags = bor(TF.Borders, TF.RowBg), display_headers = false, contents_type = CT_Text }; ST.borders = s end
|
|
|
|
PushStyleCompact()
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_RowBg", s.flags, TF.RowBg)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_Borders", s.flags, TF.Borders)
|
|
ImGui.SameLine(); DemoHelpMarker("ImGuiTableFlags_Borders\n = ImGuiTableFlags_BordersInnerV\n | ImGuiTableFlags_BordersOuterV\n | ImGuiTableFlags_BordersInnerH\n | ImGuiTableFlags_BordersOuterH")
|
|
ImGui.Indent()
|
|
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_BordersH", s.flags, TF.BordersH)
|
|
ImGui.Indent()
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_BordersOuterH", s.flags, TF.BordersOuterH)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_BordersInnerH", s.flags, TF.BordersInnerH)
|
|
ImGui.Unindent()
|
|
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_BordersV", s.flags, TF.BordersV)
|
|
ImGui.Indent()
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_BordersOuterV", s.flags, TF.BordersOuterV)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_BordersInnerV", s.flags, TF.BordersInnerV)
|
|
ImGui.Unindent()
|
|
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_BordersOuter", s.flags, TF.BordersOuter)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_BordersInner", s.flags, TF.BordersInner)
|
|
ImGui.Unindent()
|
|
|
|
ImGui.AlignTextToFramePadding(); ImGui.Text("Cell contents:")
|
|
ImGui.SameLine(); _, s.contents_type = ImGui.RadioButton("Text", s.contents_type, CT_Text)
|
|
ImGui.SameLine(); _, s.contents_type = ImGui.RadioButton("FillButton", s.contents_type, CT_FillButton)
|
|
_, s.display_headers = ImGui.Checkbox("Display headers", s.display_headers)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoBordersInBody", s.flags, TF.NoBordersInBody); ImGui.SameLine(); DemoHelpMarker("Disable vertical borders in columns Body (borders will always appear in Headers)")
|
|
PopStyleCompact()
|
|
|
|
if ImGui.BeginTable("table1", 3, s.flags) then
|
|
if s.display_headers then
|
|
ImGui.TableSetupColumn("One")
|
|
ImGui.TableSetupColumn("Two")
|
|
ImGui.TableSetupColumn("Three")
|
|
ImGui.TableHeadersRow()
|
|
end
|
|
|
|
for row = 0, 4 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, 2 do
|
|
ImGui.TableSetColumnIndex(column)
|
|
local buf = string.format("Hello %d,%d", column, row)
|
|
if s.contents_type == CT_Text then
|
|
ImGui.TextUnformatted(buf)
|
|
elseif s.contents_type == CT_FillButton then
|
|
ImGui.Button(buf, ImVec2(-FLT_MIN, 0.0))
|
|
end
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_HelloGrid(id, flags, rows, cols, fmt)
|
|
if ImGui.BeginTable(id, cols, flags) then
|
|
for row = 0, rows - 1 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, cols - 1 do
|
|
ImGui.TableSetColumnIndex(column)
|
|
ImGui.Text(fmt or "Hello %d,%d", column, row)
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_ResizableStretch()
|
|
IMGUI_DEMO_MARKER("Tables/Resizable, stretch")
|
|
local s = ST.rstretch
|
|
if s == nil then s = { flags = bor(TF.SizingStretchSame, TF.Resizable, TF.BordersOuter, TF.BordersV, TF.ContextMenuInBody) }; ST.rstretch = s end
|
|
PushStyleCompact()
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_Resizable", s.flags, TF.Resizable)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_BordersV", s.flags, TF.BordersV)
|
|
ImGui.SameLine(); DemoHelpMarker(
|
|
"Using the _Resizable flag automatically enables the _BordersInnerV flag as well, " ..
|
|
"this is why the resize borders are still showing when unchecking this.")
|
|
PopStyleCompact()
|
|
|
|
Tables_HelloGrid("table1", s.flags, 5, 3)
|
|
end
|
|
|
|
local function Tables_ResizableFixed()
|
|
IMGUI_DEMO_MARKER("Tables/Resizable, fixed")
|
|
DemoHelpMarker(
|
|
"Using _Resizable + _SizingFixedFit flags.\n" ..
|
|
"Fixed-width columns generally makes more sense if you want to use horizontal scrolling.\n\n" ..
|
|
"Double-click a column border to auto-fit the column to its contents.")
|
|
PushStyleCompact()
|
|
local s = ST.rfixed
|
|
if s == nil then s = { flags = bor(TF.SizingFixedFit, TF.Resizable, TF.BordersOuter, TF.BordersV, TF.ContextMenuInBody) }; ST.rfixed = s end
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoHostExtendX", s.flags, TF.NoHostExtendX)
|
|
PopStyleCompact()
|
|
|
|
Tables_HelloGrid("table1", s.flags, 5, 3)
|
|
end
|
|
|
|
local function Tables_ResizableMixed()
|
|
IMGUI_DEMO_MARKER("Tables/Resizable, mixed")
|
|
DemoHelpMarker(
|
|
"Using TableSetupColumn() to alter resizing policy on a per-column basis.\n\n" ..
|
|
"When combining Fixed and Stretch columns, generally you only want one, maybe two trailing columns to use _WidthStretch.")
|
|
local flags = bor(TF.SizingFixedFit, TF.RowBg, TF.Borders, TF.Resizable, TF.Reorderable, TF.Hideable)
|
|
local CF = ImGuiTableColumnFlags
|
|
|
|
if ImGui.BeginTable("table1", 3, flags) then
|
|
ImGui.TableSetupColumn("AAA", CF.WidthFixed)
|
|
ImGui.TableSetupColumn("BBB", CF.WidthFixed)
|
|
ImGui.TableSetupColumn("CCC", CF.WidthStretch)
|
|
ImGui.TableHeadersRow()
|
|
for row = 0, 4 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, 2 do
|
|
ImGui.TableSetColumnIndex(column)
|
|
ImGui.Text("%s %d,%d", (column == 2) and "Stretch" or "Fixed", column, row)
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
if ImGui.BeginTable("table2", 6, flags) then
|
|
ImGui.TableSetupColumn("AAA", CF.WidthFixed)
|
|
ImGui.TableSetupColumn("BBB", CF.WidthFixed)
|
|
ImGui.TableSetupColumn("CCC", bor(CF.WidthFixed, CF.DefaultHide))
|
|
ImGui.TableSetupColumn("DDD", CF.WidthStretch)
|
|
ImGui.TableSetupColumn("EEE", CF.WidthStretch)
|
|
ImGui.TableSetupColumn("FFF", bor(CF.WidthStretch, CF.DefaultHide))
|
|
ImGui.TableHeadersRow()
|
|
for row = 0, 4 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, 5 do
|
|
ImGui.TableSetColumnIndex(column)
|
|
ImGui.Text("%s %d,%d", (column >= 3) and "Stretch" or "Fixed", column, row)
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_Reorderable()
|
|
IMGUI_DEMO_MARKER("Tables/Reorderable, hideable, with headers")
|
|
DemoHelpMarker(
|
|
"Click and drag column headers to reorder columns.\n\n" ..
|
|
"Right-click on a header to open a context menu.")
|
|
local s = ST.reorder
|
|
if s == nil then s = { flags = bor(TF.Resizable, TF.Reorderable, TF.Hideable, TF.BordersOuter, TF.BordersV) }; ST.reorder = s end
|
|
PushStyleCompact()
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_Resizable", s.flags, TF.Resizable)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_Reorderable", s.flags, TF.Reorderable)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_Hideable", s.flags, TF.Hideable)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoBordersInBody", s.flags, TF.NoBordersInBody)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoBordersInBodyUntilResize", s.flags, TF.NoBordersInBodyUntilResize); ImGui.SameLine(); DemoHelpMarker("Disable vertical borders in columns Body until hovered for resize (borders will always appear in Headers)")
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_HighlightHoveredColumn", s.flags, TF.HighlightHoveredColumn)
|
|
PopStyleCompact()
|
|
|
|
if ImGui.BeginTable("table1", 3, s.flags) then
|
|
ImGui.TableSetupColumn("One")
|
|
ImGui.TableSetupColumn("Two")
|
|
ImGui.TableSetupColumn("Three")
|
|
ImGui.TableHeadersRow()
|
|
for row = 0, 5 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, 2 do
|
|
ImGui.TableSetColumnIndex(column)
|
|
ImGui.Text("Hello %d,%d", column, row)
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
|
|
-- Use outer_size.x == 0.0f instead of default to make the table as tight as possible
|
|
if ImGui.BeginTable("table2", 3, bor(s.flags, TF.SizingFixedFit), ImVec2(0.0, 0.0)) then
|
|
ImGui.TableSetupColumn("One")
|
|
ImGui.TableSetupColumn("Two")
|
|
ImGui.TableSetupColumn("Three")
|
|
ImGui.TableHeadersRow()
|
|
for row = 0, 5 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, 2 do
|
|
ImGui.TableSetColumnIndex(column)
|
|
ImGui.Text("Fixed %d,%d", column, row)
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_Padding()
|
|
IMGUI_DEMO_MARKER("Tables/Padding")
|
|
DemoHelpMarker(
|
|
"We often want outer padding activated when any using features which makes the edges of a column visible:\n" ..
|
|
"e.g.:\n" ..
|
|
"- BorderOuterV\n" ..
|
|
"- any form of row selection\n" ..
|
|
"Because of this, activating BorderOuterV sets the default to PadOuterX. " ..
|
|
"Using PadOuterX or NoPadOuterX you can override the default.\n\n" ..
|
|
"Actual padding values are using style.CellPadding.\n\n" ..
|
|
"In this demo we don't show horizontal borders to emphasize how they don't affect default horizontal padding.")
|
|
|
|
local s = ST.padding
|
|
if s == nil then
|
|
s = { flags1 = TF.BordersV, show_headers = false, flags2 = bor(TF.Borders, TF.RowBg), cell_padding = ImVec2(0.0, 0.0),
|
|
show_widget_frame_bg = true, text_bufs = {}, init = true }
|
|
ST.padding = s
|
|
end
|
|
PushStyleCompact()
|
|
_, s.flags1 = ImGui.CheckboxFlags("ImGuiTableFlags_PadOuterX", s.flags1, TF.PadOuterX)
|
|
ImGui.SameLine(); DemoHelpMarker("Enable outer-most padding (default if ImGuiTableFlags_BordersOuterV is set)")
|
|
_, s.flags1 = ImGui.CheckboxFlags("ImGuiTableFlags_NoPadOuterX", s.flags1, TF.NoPadOuterX)
|
|
ImGui.SameLine(); DemoHelpMarker("Disable outer-most padding (default if ImGuiTableFlags_BordersOuterV is not set)")
|
|
_, s.flags1 = ImGui.CheckboxFlags("ImGuiTableFlags_NoPadInnerX", s.flags1, TF.NoPadInnerX)
|
|
ImGui.SameLine(); DemoHelpMarker("Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off)")
|
|
_, s.flags1 = ImGui.CheckboxFlags("ImGuiTableFlags_BordersOuterV", s.flags1, TF.BordersOuterV)
|
|
_, s.flags1 = ImGui.CheckboxFlags("ImGuiTableFlags_BordersInnerV", s.flags1, TF.BordersInnerV)
|
|
_, s.show_headers = ImGui.Checkbox("show_headers", s.show_headers)
|
|
PopStyleCompact()
|
|
|
|
if ImGui.BeginTable("table_padding", 3, s.flags1) then
|
|
if s.show_headers then
|
|
ImGui.TableSetupColumn("One")
|
|
ImGui.TableSetupColumn("Two")
|
|
ImGui.TableSetupColumn("Three")
|
|
ImGui.TableHeadersRow()
|
|
end
|
|
|
|
for row = 0, 4 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, 2 do
|
|
ImGui.TableSetColumnIndex(column)
|
|
if row == 0 then
|
|
ImGui.Text("Avail %.2f", ImGui.GetContentRegionAvail().x)
|
|
else
|
|
local buf = string.format("Hello %d,%d", column, row)
|
|
ImGui.Button(buf, ImVec2(-FLT_MIN, 0.0))
|
|
end
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
|
|
-- Second example: set style.CellPadding to (0.0) or a custom value.
|
|
DemoHelpMarker("Setting style.CellPadding to (0,0) or a custom value.")
|
|
|
|
PushStyleCompact()
|
|
_, s.flags2 = ImGui.CheckboxFlags("ImGuiTableFlags_Borders", s.flags2, TF.Borders)
|
|
_, s.flags2 = ImGui.CheckboxFlags("ImGuiTableFlags_BordersH", s.flags2, TF.BordersH)
|
|
_, s.flags2 = ImGui.CheckboxFlags("ImGuiTableFlags_BordersV", s.flags2, TF.BordersV)
|
|
_, s.flags2 = ImGui.CheckboxFlags("ImGuiTableFlags_BordersInner", s.flags2, TF.BordersInner)
|
|
_, s.flags2 = ImGui.CheckboxFlags("ImGuiTableFlags_BordersOuter", s.flags2, TF.BordersOuter)
|
|
_, s.flags2 = ImGui.CheckboxFlags("ImGuiTableFlags_RowBg", s.flags2, TF.RowBg)
|
|
_, s.flags2 = ImGui.CheckboxFlags("ImGuiTableFlags_Resizable", s.flags2, TF.Resizable)
|
|
_, s.show_widget_frame_bg = ImGui.Checkbox("show_widget_frame_bg", s.show_widget_frame_bg)
|
|
ImGui.SliderFloat2("CellPadding", s.cell_padding, 0.0, 10.0, "%.0f")
|
|
PopStyleCompact()
|
|
|
|
ImGui.PushStyleVar(ImGuiStyleVar.CellPadding, s.cell_padding)
|
|
if ImGui.BeginTable("table_padding_2", 3, s.flags2) then
|
|
if not s.show_widget_frame_bg then
|
|
ImGui.PushStyleColor(ImGuiCol.FrameBg, 0)
|
|
end
|
|
for cell = 0, 3 * 5 - 1 do
|
|
ImGui.TableNextColumn()
|
|
if s.init then
|
|
s.text_bufs[cell + 1] = Buf("edit me", 16)
|
|
end
|
|
ImGui.SetNextItemWidth(-FLT_MIN)
|
|
ImGui.PushID(cell)
|
|
ImGui.InputText("##cell", s.text_bufs[cell + 1], 16)
|
|
ImGui.PopID()
|
|
end
|
|
if not s.show_widget_frame_bg then
|
|
ImGui.PopStyleColor()
|
|
end
|
|
s.init = false
|
|
ImGui.EndTable()
|
|
end
|
|
ImGui.PopStyleVar()
|
|
end
|
|
|
|
local function Tables_SizingPolicies()
|
|
IMGUI_DEMO_MARKER("Tables/Explicit widths")
|
|
local s = ST.sizing
|
|
if s == nil then
|
|
s = { flags1 = bor(TF.BordersV, TF.BordersOuterH, TF.RowBg, TF.ContextMenuInBody),
|
|
sizing_policy_flags = { TF.SizingFixedFit, TF.SizingFixedSame, TF.SizingStretchProp, TF.SizingStretchSame },
|
|
flags = bor(TF.ScrollY, TF.Borders, TF.RowBg, TF.Resizable), contents_type = 0, column_count = 3, text_buf = Buf("", 32) }
|
|
ST.sizing = s
|
|
end
|
|
PushStyleCompact()
|
|
_, s.flags1 = ImGui.CheckboxFlags("ImGuiTableFlags_Resizable", s.flags1, TF.Resizable)
|
|
_, s.flags1 = ImGui.CheckboxFlags("ImGuiTableFlags_NoHostExtendX", s.flags1, TF.NoHostExtendX)
|
|
PopStyleCompact()
|
|
|
|
for table_n = 0, 3 do
|
|
ImGui.PushID(table_n)
|
|
ImGui.SetNextItemWidth(TEXT_BASE_WIDTH * 30)
|
|
s.sizing_policy_flags[table_n + 1] = EditTableSizingFlags(s.sizing_policy_flags[table_n + 1])
|
|
|
|
if ImGui.BeginTable("table1", 3, bor(s.sizing_policy_flags[table_n + 1], s.flags1)) then
|
|
for row = 0, 2 do
|
|
ImGui.TableNextRow()
|
|
ImGui.TableNextColumn(); ImGui.Text("Oh dear")
|
|
ImGui.TableNextColumn(); ImGui.Text("Oh dear")
|
|
ImGui.TableNextColumn(); ImGui.Text("Oh dear")
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
if ImGui.BeginTable("table2", 3, bor(s.sizing_policy_flags[table_n + 1], s.flags1)) then
|
|
for row = 0, 2 do
|
|
ImGui.TableNextRow()
|
|
ImGui.TableNextColumn(); ImGui.Text("AAAA")
|
|
ImGui.TableNextColumn(); ImGui.Text("BBBBBBBB")
|
|
ImGui.TableNextColumn(); ImGui.Text("CCCCCCCCCCCC")
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
ImGui.PopID()
|
|
end
|
|
|
|
ImGui.Spacing()
|
|
ImGui.TextUnformatted("Advanced")
|
|
ImGui.SameLine()
|
|
DemoHelpMarker(
|
|
"This section allows you to interact and see the effect of various sizing policies " ..
|
|
"depending on whether Scroll is enabled and the contents of your columns.")
|
|
|
|
local CT_ShowWidth, CT_ShortText, CT_LongText, CT_Button, CT_FillButton, CT_InputText = 0, 1, 2, 3, 4, 5
|
|
|
|
PushStyleCompact()
|
|
ImGui.PushID("Advanced")
|
|
ImGui.PushItemWidth(TEXT_BASE_WIDTH * 30)
|
|
s.flags = EditTableSizingFlags(s.flags)
|
|
if ImGui.Combo then
|
|
s.contents_type = ImGui.Combo("Contents", s.contents_type, { "Show width", "Short Text", "Long Text", "Button", "Fill Button", "InputText" }, 6)
|
|
else
|
|
NotPorted("Combo")
|
|
end
|
|
if s.contents_type == CT_FillButton then
|
|
ImGui.SameLine()
|
|
DemoHelpMarker(
|
|
"Be mindful that using right-alignment (e.g. size.x = -FLT_MIN) creates a feedback loop " ..
|
|
"where contents width can feed into auto-column width can feed into contents width.")
|
|
end
|
|
s.column_count = ImGui.DragInt("Columns", s.column_count, 0.1, 1, 64, "%d", ImGuiSliderFlags.AlwaysClamp)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_Resizable", s.flags, TF.Resizable)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_PreciseWidths", s.flags, TF.PreciseWidths)
|
|
ImGui.SameLine(); DemoHelpMarker("Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth.")
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_ScrollX", s.flags, TF.ScrollX)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_ScrollY", s.flags, TF.ScrollY)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoClip", s.flags, TF.NoClip)
|
|
ImGui.PopItemWidth()
|
|
ImGui.PopID()
|
|
PopStyleCompact()
|
|
|
|
if ImGui.BeginTable("table2", s.column_count, s.flags, ImVec2(0.0, TEXT_BASE_HEIGHT * 7)) then
|
|
for cell = 0, 10 * s.column_count - 1 do
|
|
ImGui.TableNextColumn()
|
|
local column = ImGui.TableGetColumnIndex()
|
|
local row = ImGui.TableGetRowIndex()
|
|
|
|
ImGui.PushID(cell)
|
|
local label = string.format("Hello %d,%d", column, row)
|
|
local ct = s.contents_type
|
|
if ct == CT_ShortText then ImGui.TextUnformatted(label)
|
|
elseif ct == CT_LongText then ImGui.Text("Some %s text %d,%d\nOver two lines..", column == 0 and "long" or "longeeer", column, row)
|
|
elseif ct == CT_ShowWidth then ImGui.Text("W: %.1f", ImGui.GetContentRegionAvail().x)
|
|
elseif ct == CT_Button then ImGui.Button(label)
|
|
elseif ct == CT_FillButton then ImGui.Button(label, ImVec2(-FLT_MIN, 0.0))
|
|
elseif ct == CT_InputText then ImGui.SetNextItemWidth(-FLT_MIN); ImGui.InputText("##", s.text_buf, 32)
|
|
end
|
|
ImGui.PopID()
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_VerticalScrolling()
|
|
IMGUI_DEMO_MARKER("Tables/Vertical scrolling, with clipping")
|
|
DemoHelpMarker(
|
|
"Here we activate ScrollY, which will create a child window container to allow hosting scrollable contents.\n\n" ..
|
|
"We also demonstrate using ImGuiListClipper to virtualize the submission of many items.")
|
|
local s = ST.vscroll
|
|
if s == nil then s = { flags = bor(TF.ScrollY, TF.RowBg, TF.BordersOuter, TF.BordersV, TF.Resizable, TF.Reorderable, TF.Hideable) }; ST.vscroll = s end
|
|
|
|
PushStyleCompact()
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_ScrollY", s.flags, TF.ScrollY)
|
|
PopStyleCompact()
|
|
|
|
local outer_size = ImVec2(0.0, TEXT_BASE_HEIGHT * 8)
|
|
if ImGui.BeginTable("table_scrolly", 3, s.flags, outer_size) then
|
|
ImGui.TableSetupScrollFreeze(0, 1) -- Make top row always visible
|
|
ImGui.TableSetupColumn("One", ImGuiTableColumnFlags.None)
|
|
ImGui.TableSetupColumn("Two", ImGuiTableColumnFlags.None)
|
|
ImGui.TableSetupColumn("Three", ImGuiTableColumnFlags.None)
|
|
ImGui.TableHeadersRow()
|
|
|
|
-- Demonstrate using clipper for large vertical lists
|
|
local clipper = ImGuiListClipper()
|
|
clipper:Begin(1000)
|
|
while clipper:Step() do
|
|
for row = clipper.DisplayStart, clipper.DisplayEnd - 1 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, 2 do
|
|
ImGui.TableSetColumnIndex(column)
|
|
ImGui.Text("Hello %d,%d", column, row)
|
|
end
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_HorizontalScrolling()
|
|
IMGUI_DEMO_MARKER("Tables/Horizontal scrolling")
|
|
DemoHelpMarker(
|
|
"When ScrollX is enabled, the default sizing policy becomes ImGuiTableFlags_SizingFixedFit, " ..
|
|
"as automatically stretching columns doesn't make much sense with horizontal scrolling.\n\n" ..
|
|
"Also note that as of the current version, you will almost always want to enable ScrollY along with ScrollX, " ..
|
|
"because the container window won't automatically extend vertically to fix contents " ..
|
|
"(this may be improved in future versions).")
|
|
local s = ST.hscroll
|
|
if s == nil then
|
|
s = { flags = bor(TF.ScrollX, TF.ScrollY, TF.RowBg, TF.BordersOuter, TF.BordersV, TF.Resizable, TF.Reorderable, TF.Hideable),
|
|
freeze_cols = 1, freeze_rows = 1,
|
|
flags2 = bor(TF.SizingStretchSame, TF.ScrollX, TF.ScrollY, TF.BordersOuter, TF.RowBg, TF.ContextMenuInBody), inner_width = 1000.0 }
|
|
ST.hscroll = s
|
|
end
|
|
|
|
PushStyleCompact()
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_Resizable", s.flags, TF.Resizable)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_ScrollX", s.flags, TF.ScrollX)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_ScrollY", s.flags, TF.ScrollY)
|
|
ImGui.SetNextItemWidth(ImGui.GetFrameHeight())
|
|
s.freeze_cols = ImGui.DragInt("freeze_cols", s.freeze_cols, 0.2, 0, 9, nil, ImGuiSliderFlags.NoInput)
|
|
ImGui.SetNextItemWidth(ImGui.GetFrameHeight())
|
|
s.freeze_rows = ImGui.DragInt("freeze_rows", s.freeze_rows, 0.2, 0, 9, nil, ImGuiSliderFlags.NoInput)
|
|
PopStyleCompact()
|
|
|
|
local outer_size = ImVec2(0.0, TEXT_BASE_HEIGHT * 8)
|
|
if ImGui.BeginTable("table_scrollx", 7, s.flags, outer_size) then
|
|
ImGui.TableSetupScrollFreeze(s.freeze_cols, s.freeze_rows)
|
|
ImGui.TableSetupColumn("Line #", ImGuiTableColumnFlags.NoHide) -- Make the first column not hideable to match our use of TableSetupScrollFreeze()
|
|
ImGui.TableSetupColumn("One")
|
|
ImGui.TableSetupColumn("Two")
|
|
ImGui.TableSetupColumn("Three")
|
|
ImGui.TableSetupColumn("Four")
|
|
ImGui.TableSetupColumn("Five")
|
|
ImGui.TableSetupColumn("Six")
|
|
ImGui.TableHeadersRow()
|
|
for row = 0, 19 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, 6 do repeat
|
|
if not ImGui.TableSetColumnIndex(column) and column > 0 then
|
|
break -- continue
|
|
end
|
|
if column == 0 then
|
|
ImGui.Text("Line %d", row)
|
|
else
|
|
ImGui.Text("Hello world %d,%d", column, row)
|
|
end
|
|
until true end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
|
|
ImGui.Spacing()
|
|
ImGui.TextUnformatted("Stretch + ScrollX")
|
|
ImGui.SameLine()
|
|
DemoHelpMarker(
|
|
"Showcase using Stretch columns + ScrollX together: " ..
|
|
"this is rather unusual and only makes sense when specifying an 'inner_width' for the table!\n" ..
|
|
"Without an explicit value, inner_width is == outer_size.x and therefore using Stretch columns " ..
|
|
"along with ScrollX doesn't make sense.")
|
|
PushStyleCompact()
|
|
ImGui.PushID("flags3")
|
|
ImGui.PushItemWidth(TEXT_BASE_WIDTH * 30)
|
|
_, s.flags2 = ImGui.CheckboxFlags("ImGuiTableFlags_ScrollX", s.flags2, TF.ScrollX)
|
|
s.inner_width = ImGui.DragFloat("inner_width", s.inner_width, 1.0, 0.0, FLT_MAX, "%.1f")
|
|
ImGui.PopItemWidth()
|
|
ImGui.PopID()
|
|
PopStyleCompact()
|
|
if ImGui.BeginTable("table2", 7, s.flags2, outer_size, s.inner_width) then
|
|
for cell = 0, 20 * 7 - 1 do
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("Hello world %d,%d", ImGui.TableGetColumnIndex(), ImGui.TableGetRowIndex())
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_ColumnsFlags()
|
|
IMGUI_DEMO_MARKER("Tables/Columns flags")
|
|
local column_count = 3
|
|
local column_names = { "One", "Two", "Three" }
|
|
local s = ST.colflags
|
|
if s == nil then
|
|
s = { column_flags = { ImGuiTableColumnFlags.DefaultSort, ImGuiTableColumnFlags.None, ImGuiTableColumnFlags.DefaultHide }, column_flags_out = { 0, 0, 0 } }
|
|
ST.colflags = s
|
|
end
|
|
|
|
if ImGui.BeginTable("table_columns_flags_checkboxes", column_count, ImGuiTableFlags.None) then
|
|
PushStyleCompact()
|
|
for column = 1, column_count do
|
|
ImGui.TableNextColumn()
|
|
ImGui.PushID(column - 1)
|
|
ImGui.AlignTextToFramePadding() -- FIXME-TABLE: Workaround for wrong text baseline propagation across columns
|
|
ImGui.Text("'%s'", column_names[column])
|
|
ImGui.Spacing()
|
|
ImGui.Text("Input flags:")
|
|
s.column_flags[column] = EditTableColumnsFlags(s.column_flags[column])
|
|
ImGui.Spacing()
|
|
ImGui.Text("Output flags:")
|
|
ImGui.BeginDisabled()
|
|
ShowTableColumnsStatusFlags(s.column_flags_out[column])
|
|
ImGui.EndDisabled()
|
|
ImGui.PopID()
|
|
end
|
|
PopStyleCompact()
|
|
ImGui.EndTable()
|
|
end
|
|
|
|
local flags = bor(TF.SizingFixedFit, TF.ScrollX, TF.ScrollY, TF.RowBg, TF.BordersOuter, TF.BordersV, TF.Resizable, TF.Reorderable, TF.Hideable, TF.Sortable)
|
|
local outer_size = ImVec2(0.0, TEXT_BASE_HEIGHT * 9)
|
|
if ImGui.BeginTable("table_columns_flags", column_count, flags, outer_size) then
|
|
local has_angled_header = false
|
|
for column = 1, column_count do
|
|
has_angled_header = has_angled_header or Has(s.column_flags[column], ImGuiTableColumnFlags.AngledHeader)
|
|
ImGui.TableSetupColumn(column_names[column], s.column_flags[column])
|
|
end
|
|
if has_angled_header then
|
|
ImGui.TableAngledHeadersRow()
|
|
end
|
|
ImGui.TableHeadersRow()
|
|
for column = 1, column_count do
|
|
s.column_flags_out[column] = ImGui.TableGetColumnFlags(column - 1)
|
|
end
|
|
local indent_step = math.floor(math.floor(TEXT_BASE_WIDTH) / 2)
|
|
for row = 0, 7 do
|
|
-- Add some indentation to demonstrate usage of per-column IndentEnable/IndentDisable flags.
|
|
ImGui.Indent(indent_step)
|
|
ImGui.TableNextRow()
|
|
for column = 0, column_count - 1 do
|
|
ImGui.TableSetColumnIndex(column)
|
|
ImGui.Text("%s %s", (column == 0) and "Indented" or "Hello", ImGui.TableGetColumnName(column))
|
|
end
|
|
end
|
|
ImGui.Unindent(indent_step * 8.0)
|
|
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_ColumnsWidths()
|
|
IMGUI_DEMO_MARKER("Tables/Columns widths")
|
|
DemoHelpMarker("Using TableSetupColumn() to setup default width.")
|
|
local s = ST.colwidths
|
|
if s == nil then s = { flags1 = bor(TF.Borders, TF.NoBordersInBodyUntilResize), flags2 = TF.None }; ST.colwidths = s end
|
|
local CF = ImGuiTableColumnFlags
|
|
|
|
PushStyleCompact()
|
|
_, s.flags1 = ImGui.CheckboxFlags("ImGuiTableFlags_Resizable", s.flags1, TF.Resizable)
|
|
_, s.flags1 = ImGui.CheckboxFlags("ImGuiTableFlags_NoBordersInBodyUntilResize", s.flags1, TF.NoBordersInBodyUntilResize)
|
|
PopStyleCompact()
|
|
if ImGui.BeginTable("table1", 3, s.flags1) then
|
|
ImGui.TableSetupColumn("one", CF.WidthFixed, 100.0) -- Default to 100.0f
|
|
ImGui.TableSetupColumn("two", CF.WidthFixed, 200.0) -- Default to 200.0f
|
|
ImGui.TableSetupColumn("three", CF.WidthFixed) -- Default to auto
|
|
ImGui.TableHeadersRow()
|
|
for row = 0, 3 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, 2 do
|
|
ImGui.TableSetColumnIndex(column)
|
|
if row == 0 then
|
|
ImGui.Text("(w: %5.1f)", ImGui.GetContentRegionAvail().x)
|
|
else
|
|
ImGui.Text("Hello %d,%d", column, row)
|
|
end
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
|
|
DemoHelpMarker(
|
|
"Using TableSetupColumn() to setup explicit width.\n\nUnless _NoKeepColumnsVisible is set, " ..
|
|
"fixed columns with set width may still be shrunk down if there's not enough space in the host.")
|
|
|
|
PushStyleCompact()
|
|
_, s.flags2 = ImGui.CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", s.flags2, TF.NoKeepColumnsVisible)
|
|
_, s.flags2 = ImGui.CheckboxFlags("ImGuiTableFlags_BordersInnerV", s.flags2, TF.BordersInnerV)
|
|
_, s.flags2 = ImGui.CheckboxFlags("ImGuiTableFlags_BordersOuterV", s.flags2, TF.BordersOuterV)
|
|
PopStyleCompact()
|
|
if ImGui.BeginTable("table2", 4, s.flags2) then
|
|
ImGui.TableSetupColumn("", CF.WidthFixed, 100.0)
|
|
ImGui.TableSetupColumn("", CF.WidthFixed, TEXT_BASE_WIDTH * 15.0)
|
|
ImGui.TableSetupColumn("", CF.WidthFixed, TEXT_BASE_WIDTH * 30.0)
|
|
ImGui.TableSetupColumn("", CF.WidthFixed, TEXT_BASE_WIDTH * 15.0)
|
|
for row = 0, 4 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, 3 do
|
|
ImGui.TableSetColumnIndex(column)
|
|
if row == 0 then
|
|
ImGui.Text("(w: %5.1f)", ImGui.GetContentRegionAvail().x)
|
|
else
|
|
ImGui.Text("Hello %d,%d", column, row)
|
|
end
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_Nested()
|
|
IMGUI_DEMO_MARKER("Tables/Nested tables")
|
|
DemoHelpMarker("This demonstrates embedding a table into another table cell.")
|
|
|
|
if ImGui.BeginTable("table_nested1", 2, bor(TF.Borders, TF.Resizable, TF.Reorderable, TF.Hideable)) then
|
|
ImGui.TableSetupColumn("A0")
|
|
ImGui.TableSetupColumn("A1")
|
|
ImGui.TableHeadersRow()
|
|
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("A0 Row 0")
|
|
do
|
|
local rows_height = (TEXT_BASE_HEIGHT * 2.0) + (ImGui.GetStyle().CellPadding.y * 2.0)
|
|
if ImGui.BeginTable("table_nested2", 2, bor(TF.Borders, TF.Resizable, TF.Reorderable, TF.Hideable)) then
|
|
ImGui.TableSetupColumn("B0")
|
|
ImGui.TableSetupColumn("B1")
|
|
ImGui.TableHeadersRow()
|
|
|
|
ImGui.TableNextRow(ImGuiTableRowFlags.None, rows_height)
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("B0 Row 0")
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("B1 Row 0")
|
|
ImGui.TableNextRow(ImGuiTableRowFlags.None, rows_height)
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("B0 Row 1")
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("B1 Row 1")
|
|
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
ImGui.TableNextColumn(); ImGui.Text("A1 Row 0")
|
|
ImGui.TableNextColumn(); ImGui.Text("A0 Row 1")
|
|
ImGui.TableNextColumn(); ImGui.Text("A1 Row 1")
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_RowHeight()
|
|
IMGUI_DEMO_MARKER("Tables/Row height")
|
|
DemoHelpMarker(
|
|
"You can pass a 'min_row_height' to TableNextRow().\n\nRows are padded with 'style.CellPadding.y' on top and bottom, " ..
|
|
"so effectively the minimum row height will always be >= 'style.CellPadding.y * 2.0f'.\n\n" ..
|
|
"We cannot honor a _maximum_ row height as that would require a unique clipping rectangle per row.")
|
|
if ImGui.BeginTable("table_row_height", 1, TF.Borders) then
|
|
for row = 0, 7 do
|
|
local min_row_height = math.floor(TEXT_BASE_HEIGHT * 0.30 * row + ImGui.GetStyle().CellPadding.y * 2.0)
|
|
ImGui.TableNextRow(ImGuiTableRowFlags.None, min_row_height)
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("min_row_height = %.2f", min_row_height)
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
|
|
DemoHelpMarker(
|
|
"Showcase using SameLine(0,0) to share Current Line Height between cells.\n\n" ..
|
|
"Please note that Tables Row Height is not the same thing as Current Line Height, " ..
|
|
"as a table cell may contains multiple lines.")
|
|
if ImGui.BeginTable("table_share_lineheight", 2, TF.Borders) then
|
|
ImGui.TableNextRow()
|
|
ImGui.TableNextColumn()
|
|
ImGui.ColorButton("##1", ImVec4(0.13, 0.26, 0.40, 1.0), ImGuiColorEditFlags.None, ImVec2(40, 40))
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("Line 1")
|
|
ImGui.Text("Line 2")
|
|
|
|
ImGui.TableNextRow()
|
|
ImGui.TableNextColumn()
|
|
ImGui.ColorButton("##2", ImVec4(0.13, 0.26, 0.40, 1.0), ImGuiColorEditFlags.None, ImVec2(40, 40))
|
|
ImGui.TableNextColumn()
|
|
ImGui.SameLine(0.0, 0.0) -- Reuse line height from previous column
|
|
ImGui.Text("Line 1, with SameLine(0,0)")
|
|
ImGui.Text("Line 2")
|
|
|
|
ImGui.EndTable()
|
|
end
|
|
|
|
DemoHelpMarker("Showcase altering CellPadding.y between rows. Note that CellPadding.x is locked for the entire table.")
|
|
if ImGui.BeginTable("table_changing_cellpadding_y", 1, TF.Borders) then
|
|
local style = ImGui.GetStyle()
|
|
for row = 0, 7 do
|
|
if (row % 3) == 2 then
|
|
ImGui.PushStyleVarY(ImGuiStyleVar.CellPadding, 20.0)
|
|
end
|
|
ImGui.TableNextRow(ImGuiTableRowFlags.None)
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("CellPadding.y = %.2f", style.CellPadding.y)
|
|
if (row % 3) == 2 then
|
|
ImGui.PopStyleVar()
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_OuterSize()
|
|
IMGUI_DEMO_MARKER("Tables/Outer size")
|
|
ImGui.Text("Using NoHostExtendX and NoHostExtendY:")
|
|
PushStyleCompact()
|
|
local s = ST.outer
|
|
if s == nil then s = { flags = bor(TF.Borders, TF.Resizable, TF.ContextMenuInBody, TF.RowBg, TF.SizingFixedFit, TF.NoHostExtendX) }; ST.outer = s end
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoHostExtendX", s.flags, TF.NoHostExtendX)
|
|
ImGui.SameLine(); DemoHelpMarker("Make outer width auto-fit to columns, overriding outer_size.x value.\n\nOnly available when ScrollX/ScrollY are disabled and Stretch columns are not used.")
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoHostExtendY", s.flags, TF.NoHostExtendY)
|
|
ImGui.SameLine(); DemoHelpMarker("Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit).\n\nOnly available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.")
|
|
PopStyleCompact()
|
|
|
|
local outer_size = ImVec2(0.0, TEXT_BASE_HEIGHT * 5.5)
|
|
if ImGui.BeginTable("table1", 3, s.flags, outer_size) then
|
|
for row = 0, 9 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, 2 do
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("Cell %d,%d", column, row)
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
ImGui.SameLine()
|
|
ImGui.Text("Hello!")
|
|
|
|
ImGui.Spacing()
|
|
|
|
ImGui.Text("Using explicit size:")
|
|
if ImGui.BeginTable("table2", 3, bor(TF.Borders, TF.RowBg), ImVec2(TEXT_BASE_WIDTH * 30, 0.0)) then
|
|
for row = 0, 4 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, 2 do
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("Cell %d,%d", column, row)
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
ImGui.SameLine()
|
|
if ImGui.BeginTable("table3", 3, bor(TF.Borders, TF.RowBg), ImVec2(TEXT_BASE_WIDTH * 30, 0.0)) then
|
|
local rows_height = TEXT_BASE_HEIGHT * 1.5 + ImGui.GetStyle().CellPadding.y * 2.0
|
|
for row = 0, 2 do
|
|
ImGui.TableNextRow(0, rows_height)
|
|
for column = 0, 2 do
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("Cell %d,%d", column, row)
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_BackgroundColor()
|
|
IMGUI_DEMO_MARKER("Tables/Background color")
|
|
local s = ST.bgcolor
|
|
if s == nil then s = { flags = TF.RowBg, row_bg_type = 1, row_bg_target = 1, cell_bg_type = 1 }; ST.bgcolor = s end
|
|
|
|
PushStyleCompact()
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_Borders", s.flags, TF.Borders)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_RowBg", s.flags, TF.RowBg)
|
|
ImGui.SameLine(); DemoHelpMarker("ImGuiTableFlags_RowBg automatically sets RowBg0 to alternative colors pulled from the Style.")
|
|
if ImGui.Combo then
|
|
s.row_bg_type = ImGui.Combo("row bg type", s.row_bg_type, { "None", "Red", "Gradient" }, 3)
|
|
s.row_bg_target = ImGui.Combo("row bg target", s.row_bg_target, { "RowBg0", "RowBg1" }, 2); ImGui.SameLine(); DemoHelpMarker("Target RowBg0 to override the alternating odd/even colors,\nTarget RowBg1 to blend with them.")
|
|
s.cell_bg_type = ImGui.Combo("cell bg type", s.cell_bg_type, { "None", "Blue" }, 2); ImGui.SameLine(); DemoHelpMarker("We are colorizing cells to B1->C2 here.")
|
|
else
|
|
NotPorted("Combo")
|
|
end
|
|
IM_ASSERT(s.row_bg_type >= 0 and s.row_bg_type <= 2)
|
|
IM_ASSERT(s.row_bg_target >= 0 and s.row_bg_target <= 1)
|
|
IM_ASSERT(s.cell_bg_type >= 0 and s.cell_bg_type <= 1)
|
|
PopStyleCompact()
|
|
|
|
if ImGui.BeginTable("table1", 5, s.flags) then
|
|
for row = 0, 5 do
|
|
ImGui.TableNextRow()
|
|
|
|
if s.row_bg_type ~= 0 then
|
|
local row_bg_color = ImGui.GetColorU32(s.row_bg_type == 1 and ImVec4(0.7, 0.3, 0.3, 0.65) or ImVec4(0.2 + row * 0.1, 0.2, 0.2, 0.65)) -- Flat or Gradient?
|
|
ImGui.TableSetBgColor(ImGuiTableBgTarget.RowBg0 + s.row_bg_target, row_bg_color)
|
|
end
|
|
|
|
-- Fill cells
|
|
for column = 0, 4 do
|
|
ImGui.TableSetColumnIndex(column)
|
|
ImGui.Text("%s%s", string.char(65 + row), string.char(48 + column))
|
|
|
|
if row >= 1 and row <= 2 and column >= 1 and column <= 2 and s.cell_bg_type == 1 then
|
|
local cell_bg_color = ImGui.GetColorU32(ImVec4(0.3, 0.3, 0.7, 0.65))
|
|
ImGui.TableSetBgColor(ImGuiTableBgTarget.CellBg, cell_bg_color)
|
|
end
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local tree_view_nodes = {
|
|
{ Name = "Root with Long Name", Type = "Folder", Size = -1, ChildIdx = 1, ChildCount = 3 }, -- 0
|
|
{ Name = "Music", Type = "Folder", Size = -1, ChildIdx = 4, ChildCount = 2 }, -- 1
|
|
{ Name = "Textures", Type = "Folder", Size = -1, ChildIdx = 6, ChildCount = 3 }, -- 2
|
|
{ Name = "desktop.ini", Type = "System file", Size = 1024, ChildIdx = -1, ChildCount = -1 }, -- 3
|
|
{ Name = "File1_a.wav", Type = "Audio file", Size = 123000, ChildIdx = -1, ChildCount = -1 }, -- 4
|
|
{ Name = "File1_b.wav", Type = "Audio file", Size = 456000, ChildIdx = -1, ChildCount = -1 }, -- 5
|
|
{ Name = "Image001.png", Type = "Image file", Size = 203128, ChildIdx = -1, ChildCount = -1 }, -- 6
|
|
{ Name = "Copy of Image001.png", Type = "Image file", Size = 203256, ChildIdx = -1, ChildCount = -1 }, -- 7
|
|
{ Name = "Copy of Image001 (Final2).png", Type = "Image file", Size = 203512, ChildIdx = -1, ChildCount = -1 }, -- 8
|
|
}
|
|
|
|
local function MyTreeNode_DisplayNode(node, all_nodes, tree_node_flags_base)
|
|
ImGui.TableNextRow()
|
|
ImGui.TableNextColumn()
|
|
local is_folder = (node.ChildCount > 0)
|
|
|
|
local node_flags = tree_node_flags_base
|
|
if node ~= all_nodes[1] then
|
|
node_flags = bit32.band(node_flags, bit32.bnot(ImGuiTreeNodeFlags.LabelSpanAllColumns)) -- Only demonstrate this on the root node.
|
|
end
|
|
|
|
if is_folder then
|
|
local open = ImGui.TreeNodeEx(node.Name, node_flags)
|
|
if bit32.band(node_flags, ImGuiTreeNodeFlags.LabelSpanAllColumns) == 0 then
|
|
ImGui.TableNextColumn()
|
|
ImGui.TextDisabled("--")
|
|
ImGui.TableNextColumn()
|
|
ImGui.TextUnformatted(node.Type)
|
|
end
|
|
if open then
|
|
for child_n = 0, node.ChildCount - 1 do
|
|
MyTreeNode_DisplayNode(all_nodes[node.ChildIdx + child_n + 1], all_nodes, tree_node_flags_base)
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
else
|
|
ImGui.TreeNodeEx(node.Name, bor(node_flags, ImGuiTreeNodeFlags.Leaf, ImGuiTreeNodeFlags.Bullet, ImGuiTreeNodeFlags.NoTreePushOnOpen))
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("%d", node.Size)
|
|
ImGui.TableNextColumn()
|
|
ImGui.TextUnformatted(node.Type)
|
|
end
|
|
end
|
|
|
|
local function Tables_TreeView()
|
|
IMGUI_DEMO_MARKER("Tables/Tree view")
|
|
local s = ST.treeview
|
|
if s == nil then
|
|
s = { table_flags = bor(TF.BordersV, TF.BordersOuterH, TF.Resizable, TF.RowBg, TF.NoBordersInBody),
|
|
tree_node_flags_base = bor(ImGuiTreeNodeFlags.SpanAllColumns, ImGuiTreeNodeFlags.DefaultOpen, ImGuiTreeNodeFlags.DrawLinesFull) }
|
|
ST.treeview = s
|
|
end
|
|
_, s.tree_node_flags_base = ImGui.CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", s.tree_node_flags_base, ImGuiTreeNodeFlags.SpanFullWidth)
|
|
_, s.tree_node_flags_base = ImGui.CheckboxFlags("ImGuiTreeNodeFlags_SpanLabelWidth", s.tree_node_flags_base, ImGuiTreeNodeFlags.SpanLabelWidth)
|
|
_, s.tree_node_flags_base = ImGui.CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", s.tree_node_flags_base, ImGuiTreeNodeFlags.SpanAllColumns)
|
|
_, s.tree_node_flags_base = ImGui.CheckboxFlags("ImGuiTreeNodeFlags_LabelSpanAllColumns", s.tree_node_flags_base, ImGuiTreeNodeFlags.LabelSpanAllColumns)
|
|
ImGui.SameLine(); DemoHelpMarker("Useful if you know that you aren't displaying contents in other columns")
|
|
|
|
DemoHelpMarker("See \"Columns flags\" section to configure how indentation is applied to individual columns.")
|
|
if ImGui.BeginTable("3ways", 3, s.table_flags) then
|
|
ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.NoHide)
|
|
ImGui.TableSetupColumn("Size", ImGuiTableColumnFlags.WidthFixed, TEXT_BASE_WIDTH * 12.0)
|
|
ImGui.TableSetupColumn("Type", ImGuiTableColumnFlags.WidthFixed, TEXT_BASE_WIDTH * 18.0)
|
|
ImGui.TableHeadersRow()
|
|
|
|
MyTreeNode_DisplayNode(tree_view_nodes[1], tree_view_nodes, s.tree_node_flags_base)
|
|
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_ItemWidth()
|
|
IMGUI_DEMO_MARKER("Tables/Item width")
|
|
DemoHelpMarker(
|
|
"Showcase using PushItemWidth() and how it is preserved on a per-column basis.\n\n" ..
|
|
"Note that on auto-resizing non-resizable fixed columns, querying the content width for " ..
|
|
"e.g. right-alignment doesn't make sense.")
|
|
if ImGui.BeginTable("table_item_width", 3, TF.Borders) then
|
|
ImGui.TableSetupColumn("small")
|
|
ImGui.TableSetupColumn("half")
|
|
ImGui.TableSetupColumn("right-align")
|
|
ImGui.TableHeadersRow()
|
|
|
|
for row = 0, 2 do
|
|
ImGui.TableNextRow()
|
|
if row == 0 then
|
|
-- Setup ItemWidth once (instead of setting up every time, which is also possible but less efficient)
|
|
ImGui.TableSetColumnIndex(0)
|
|
ImGui.PushItemWidth(TEXT_BASE_WIDTH * 3.0) -- Small
|
|
ImGui.TableSetColumnIndex(1)
|
|
ImGui.PushItemWidth(-ImGui.GetContentRegionAvail().x * 0.5)
|
|
ImGui.TableSetColumnIndex(2)
|
|
ImGui.PushItemWidth(-FLT_MIN) -- Right-aligned
|
|
end
|
|
|
|
-- Draw our contents
|
|
ImGui.PushID(row)
|
|
ImGui.TableSetColumnIndex(0)
|
|
ST.dummy_f = ImGui.SliderFloat("float0", ST.dummy_f or 0.0, 0.0, 1.0)
|
|
ImGui.TableSetColumnIndex(1)
|
|
ST.dummy_f = ImGui.SliderFloat("float1", ST.dummy_f, 0.0, 1.0)
|
|
ImGui.TableSetColumnIndex(2)
|
|
ST.dummy_f = ImGui.SliderFloat("##float2", ST.dummy_f, 0.0, 1.0) -- No visible label since right-aligned
|
|
ImGui.PopID()
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_CustomHeaders()
|
|
IMGUI_DEMO_MARKER("Tables/Custom headers")
|
|
local COLUMNS_COUNT = 3
|
|
if ImGui.BeginTable("table_custom_headers", COLUMNS_COUNT, bor(TF.Borders, TF.Reorderable, TF.Hideable)) then
|
|
ImGui.TableSetupColumn("Apricot")
|
|
ImGui.TableSetupColumn("Banana")
|
|
ImGui.TableSetupColumn("Cherry")
|
|
|
|
-- Dummy entire-column selection storage
|
|
if ST.column_selected == nil then ST.column_selected = { false, false, false } end
|
|
local column_selected = ST.column_selected
|
|
|
|
ImGui.TableNextRow(ImGuiTableRowFlags.Headers)
|
|
for column = 0, COLUMNS_COUNT - 1 do
|
|
ImGui.TableSetColumnIndex(column)
|
|
local column_name = ImGui.TableGetColumnName(column) -- Retrieve name passed to TableSetupColumn()
|
|
ImGui.PushID(column)
|
|
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, ImVec2(0, 0))
|
|
_, column_selected[column + 1] = ImGui.Checkbox("##checkall", column_selected[column + 1])
|
|
ImGui.PopStyleVar()
|
|
ImGui.SameLine(0.0, ImGui.GetStyle().ItemInnerSpacing.x)
|
|
ImGui.TableHeader(column_name)
|
|
ImGui.PopID()
|
|
end
|
|
|
|
-- Submit table contents
|
|
for row = 0, 4 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, 2 do
|
|
local buf = string.format("Cell %d,%d", column, row)
|
|
ImGui.TableSetColumnIndex(column)
|
|
ImGui.Selectable(buf, column_selected[column + 1])
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_AngledHeaders()
|
|
IMGUI_DEMO_MARKER("Tables/Angled headers")
|
|
local column_names = { "Track", "cabasa", "ride", "smash", "tom-hi", "tom-mid", "tom-low", "hihat-o", "hihat-c", "snare-s", "snare-c", "clap", "rim", "kick" }
|
|
local columns_count = #column_names
|
|
local rows_count = 12
|
|
|
|
local s = ST.angled
|
|
if s == nil then
|
|
s = { table_flags = bor(TF.SizingFixedFit, TF.ScrollX, TF.ScrollY, TF.BordersOuter, TF.BordersInnerH, TF.Hideable, TF.Resizable, TF.Reorderable, TF.HighlightHoveredColumn),
|
|
column_flags = bor(ImGuiTableColumnFlags.AngledHeader, ImGuiTableColumnFlags.WidthFixed),
|
|
bools = {}, frozen_cols = 1, frozen_rows = 2 }
|
|
for i = 1, columns_count * rows_count do s.bools[i] = false end
|
|
ST.angled = s
|
|
end
|
|
_, s.table_flags = ImGui.CheckboxFlags("_ScrollX", s.table_flags, TF.ScrollX)
|
|
_, s.table_flags = ImGui.CheckboxFlags("_ScrollY", s.table_flags, TF.ScrollY)
|
|
_, s.table_flags = ImGui.CheckboxFlags("_Resizable", s.table_flags, TF.Resizable)
|
|
_, s.table_flags = ImGui.CheckboxFlags("_Sortable", s.table_flags, TF.Sortable)
|
|
_, s.table_flags = ImGui.CheckboxFlags("_NoBordersInBody", s.table_flags, TF.NoBordersInBody)
|
|
_, s.table_flags = ImGui.CheckboxFlags("_HighlightHoveredColumn", s.table_flags, TF.HighlightHoveredColumn)
|
|
ImGui.SetNextItemWidth(ImGui.GetFontSize() * 8)
|
|
s.frozen_cols = ImGui.SliderInt("Frozen columns", s.frozen_cols, 0, 2)
|
|
ImGui.SetNextItemWidth(ImGui.GetFontSize() * 8)
|
|
s.frozen_rows = ImGui.SliderInt("Frozen rows", s.frozen_rows, 0, 2)
|
|
_, s.column_flags = ImGui.CheckboxFlags("Disable header contributing to column width", s.column_flags, ImGuiTableColumnFlags.NoHeaderWidth)
|
|
|
|
if ImGui.TreeNode("Style settings") then
|
|
ImGui.SameLine()
|
|
DemoHelpMarker("Giving access to some ImGuiStyle value in this demo for convenience.")
|
|
ImGui.SetNextItemWidth(ImGui.GetFontSize() * 8)
|
|
local style = ImGui.GetStyle()
|
|
style.TableAngledHeadersAngle = ImGui.SliderAngle("style.TableAngledHeadersAngle", style.TableAngledHeadersAngle, -50.0, 50.0)
|
|
ImGui.SetNextItemWidth(ImGui.GetFontSize() * 8)
|
|
ImGui.SliderFloat2("style.TableAngledHeadersTextAlign", style.TableAngledHeadersTextAlign, 0.0, 1.0, "%.2f")
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.BeginTable("table_angled_headers", columns_count, s.table_flags, ImVec2(0.0, TEXT_BASE_HEIGHT * 12)) then
|
|
ImGui.TableSetupColumn(column_names[1], bor(ImGuiTableColumnFlags.NoHide, ImGuiTableColumnFlags.NoReorder))
|
|
for n = 2, columns_count do
|
|
ImGui.TableSetupColumn(column_names[n], s.column_flags)
|
|
end
|
|
ImGui.TableSetupScrollFreeze(s.frozen_cols, s.frozen_rows)
|
|
|
|
ImGui.TableAngledHeadersRow() -- Draw angled headers for all columns with the ImGuiTableColumnFlags_AngledHeader flag.
|
|
ImGui.TableHeadersRow() -- Draw remaining headers and allow access to context-menu and other functions.
|
|
for row = 0, rows_count - 1 do
|
|
ImGui.PushID(row)
|
|
ImGui.TableNextRow()
|
|
ImGui.TableSetColumnIndex(0)
|
|
ImGui.AlignTextToFramePadding()
|
|
ImGui.Text("Track %d", row)
|
|
for column = 1, columns_count - 1 do
|
|
if ImGui.TableSetColumnIndex(column) then
|
|
ImGui.PushID(column)
|
|
local idx = row * columns_count + column + 1
|
|
_, s.bools[idx] = ImGui.Checkbox("", s.bools[idx])
|
|
ImGui.PopID()
|
|
end
|
|
end
|
|
ImGui.PopID()
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_ContextMenus()
|
|
IMGUI_DEMO_MARKER("Tables/Context menus")
|
|
DemoHelpMarker(
|
|
"By default, right-clicking over a TableHeadersRow()/TableHeader() line will open the default context-menu.\n" ..
|
|
"Using ImGuiTableFlags_ContextMenuInBody we also allow right-clicking over columns body.")
|
|
local s = ST.ctxmenu
|
|
if s == nil then s = { flags1 = bor(TF.Resizable, TF.Reorderable, TF.Hideable, TF.Borders, TF.ContextMenuInBody) }; ST.ctxmenu = s end
|
|
|
|
PushStyleCompact()
|
|
_, s.flags1 = ImGui.CheckboxFlags("ImGuiTableFlags_ContextMenuInBody", s.flags1, TF.ContextMenuInBody)
|
|
PopStyleCompact()
|
|
|
|
local COLUMNS_COUNT = 3
|
|
if ImGui.BeginTable("table_context_menu", COLUMNS_COUNT, s.flags1) then
|
|
ImGui.TableSetupColumn("One")
|
|
ImGui.TableSetupColumn("Two")
|
|
ImGui.TableSetupColumn("Three")
|
|
|
|
-- [1.1]] Right-click on the TableHeadersRow() line to open the default table context menu.
|
|
ImGui.TableHeadersRow()
|
|
|
|
-- Submit dummy contents
|
|
for row = 0, 3 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, COLUMNS_COUNT - 1 do
|
|
ImGui.TableSetColumnIndex(column)
|
|
ImGui.Text("Cell %d,%d", column, row)
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
|
|
DemoHelpMarker(
|
|
"Demonstrate mixing table context menu (over header), item context button (over button) " ..
|
|
"and custom per-column context menu (over column body).")
|
|
local flags2 = bor(TF.Resizable, TF.SizingFixedFit, TF.Reorderable, TF.Hideable, TF.Borders)
|
|
if ImGui.BeginTable("table_context_menu_2", COLUMNS_COUNT, flags2) then
|
|
ImGui.TableSetupColumn("One")
|
|
ImGui.TableSetupColumn("Two")
|
|
ImGui.TableSetupColumn("Three")
|
|
|
|
-- [2.1] Right-click on the TableHeadersRow() line to open the default table context menu.
|
|
ImGui.TableHeadersRow()
|
|
for row = 0, 3 do
|
|
ImGui.TableNextRow()
|
|
for column = 0, COLUMNS_COUNT - 1 do
|
|
-- Submit dummy contents
|
|
ImGui.TableSetColumnIndex(column)
|
|
ImGui.Text("Cell %d,%d", column, row)
|
|
ImGui.SameLine()
|
|
|
|
-- [2.2] Right-click on the ".." to open a custom popup
|
|
ImGui.PushID(row * COLUMNS_COUNT + column)
|
|
ImGui.SmallButton("..")
|
|
if ImGui.BeginPopupContextItem() then
|
|
ImGui.Text("This is the popup for Button(\"..\") in Cell %d,%d", column, row)
|
|
if ImGui.Button("Close") then
|
|
ImGui.CloseCurrentPopup()
|
|
end
|
|
ImGui.EndPopup()
|
|
end
|
|
ImGui.PopID()
|
|
end
|
|
end
|
|
|
|
-- [2.3] Right-click anywhere in columns to open another custom popup
|
|
local hovered_column = -1
|
|
for column = 0, COLUMNS_COUNT do
|
|
ImGui.PushID(column)
|
|
if Has(ImGui.TableGetColumnFlags(column), ImGuiTableColumnFlags.IsHovered) then
|
|
hovered_column = column
|
|
end
|
|
if hovered_column == column and not ImGui.IsAnyItemHovered() and ImGui.IsMouseReleased(1) then
|
|
ImGui.OpenPopup("MyPopup")
|
|
end
|
|
if ImGui.BeginPopup("MyPopup") then
|
|
if column == COLUMNS_COUNT then
|
|
ImGui.Text("This is a custom popup for unused space after the last column.")
|
|
else
|
|
ImGui.Text("This is a custom popup for Column %d", column)
|
|
end
|
|
if ImGui.Button("Close") then
|
|
ImGui.CloseCurrentPopup()
|
|
end
|
|
ImGui.EndPopup()
|
|
end
|
|
ImGui.PopID()
|
|
end
|
|
|
|
ImGui.EndTable()
|
|
ImGui.Text("Hovered column: %d", hovered_column)
|
|
end
|
|
end
|
|
|
|
local function Tables_SyncedInstances()
|
|
IMGUI_DEMO_MARKER("Tables/Synced instances")
|
|
DemoHelpMarker("Multiple tables with the same identifier will share their settings, width, visibility, order etc.")
|
|
|
|
local s = ST.synced
|
|
if s == nil then s = { flags = bor(TF.Resizable, TF.Reorderable, TF.Hideable, TF.Borders, TF.SizingFixedFit, TF.NoSavedSettings) }; ST.synced = s end
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_Resizable", s.flags, TF.Resizable)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_ScrollY", s.flags, TF.ScrollY)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_SizingFixedFit", s.flags, TF.SizingFixedFit)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_HighlightHoveredColumn", s.flags, TF.HighlightHoveredColumn)
|
|
for n = 0, 2 do
|
|
local buf = string.format("Synced Table %d", n)
|
|
local open = ImGui.CollapsingHeader(buf, ImGuiTreeNodeFlags.DefaultOpen)
|
|
if open and ImGui.BeginTable("Table", 3, s.flags, ImVec2(0.0, ImGui.GetTextLineHeightWithSpacing() * 5)) then
|
|
ImGui.TableSetupColumn("One")
|
|
ImGui.TableSetupColumn("Two")
|
|
ImGui.TableSetupColumn("Three")
|
|
ImGui.TableHeadersRow()
|
|
local cell_count = (n == 1) and 27 or 9 -- Make second table have a scrollbar to verify that additional decoration is not affecting column positions.
|
|
for cell = 0, cell_count - 1 do
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("this cell %d", cell)
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
end
|
|
|
|
local template_items_names = {
|
|
"Banana", "Apple", "Cherry", "Watermelon", "Grapefruit", "Strawberry", "Mango",
|
|
"Kiwi", "Orange", "Pineapple", "Blueberry", "Plum", "Coconut", "Pear", "Apricot"
|
|
}
|
|
|
|
local function Tables_Sorting()
|
|
IMGUI_DEMO_MARKER("Tables/Sorting")
|
|
local s = ST.sorting
|
|
if s == nil then
|
|
s = { items = {},
|
|
flags = bor(TF.Resizable, TF.Reorderable, TF.Hideable, TF.Sortable, TF.SortMulti, TF.RowBg, TF.BordersOuter, TF.BordersV, TF.NoBordersInBody, TF.ScrollY) }
|
|
for n = 0, 49 do
|
|
local template_n = n % #template_items_names
|
|
s.items[n + 1] = MyItem(n, template_items_names[template_n + 1], (n * n - n) % 20) -- Assign default quantities
|
|
end
|
|
ST.sorting = s
|
|
end
|
|
local items = s.items
|
|
|
|
PushStyleCompact()
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_SortMulti", s.flags, TF.SortMulti)
|
|
ImGui.SameLine(); DemoHelpMarker("When sorting is enabled: hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1).")
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_SortTristate", s.flags, TF.SortTristate)
|
|
ImGui.SameLine(); DemoHelpMarker("When sorting is enabled: allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0).")
|
|
PopStyleCompact()
|
|
|
|
if ImGui.BeginTable("table_sorting", 4, s.flags, ImVec2(0.0, TEXT_BASE_HEIGHT * 15), 0.0) then
|
|
local CF = ImGuiTableColumnFlags
|
|
ImGui.TableSetupColumn("ID", bor(CF.DefaultSort, CF.WidthFixed), 0.0, MyItemColumnID_ID)
|
|
ImGui.TableSetupColumn("Name", CF.WidthFixed, 0.0, MyItemColumnID_Name)
|
|
ImGui.TableSetupColumn("Action", bor(CF.NoSort, CF.WidthFixed), 0.0, MyItemColumnID_Action)
|
|
ImGui.TableSetupColumn("Quantity", bor(CF.PreferSortDescending, CF.WidthStretch), 0.0, MyItemColumnID_Quantity)
|
|
ImGui.TableSetupScrollFreeze(0, 1) -- Make row always visible
|
|
ImGui.TableHeadersRow()
|
|
|
|
-- Sort our data if sort specs have been changed!
|
|
local sort_specs = ImGui.TableGetSortSpecs()
|
|
if sort_specs and sort_specs.SpecsDirty then
|
|
MyItem_SortWithSortSpecs(sort_specs, items, #items)
|
|
sort_specs.SpecsDirty = false
|
|
end
|
|
|
|
-- Demonstrate using clipper for large vertical lists
|
|
local clipper = ImGuiListClipper()
|
|
clipper:Begin(#items)
|
|
while clipper:Step() do
|
|
for row_n = clipper.DisplayStart, clipper.DisplayEnd - 1 do
|
|
-- Display a data item
|
|
local item = items[row_n + 1]
|
|
ImGui.PushID(item.ID)
|
|
ImGui.TableNextRow()
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("%04d", item.ID)
|
|
ImGui.TableNextColumn()
|
|
ImGui.TextUnformatted(item.Name)
|
|
ImGui.TableNextColumn()
|
|
ImGui.SmallButton("None")
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("%d", item.Quantity)
|
|
ImGui.PopID()
|
|
end
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
end
|
|
|
|
local function Tables_AdvancedOptions(s)
|
|
-- Make the UI compact because there are so many fields
|
|
PushStyleCompact()
|
|
ImGui.PushItemWidth(TEXT_BASE_WIDTH * 28.0)
|
|
|
|
if ImGui.TreeNodeEx("Features:", ImGuiTreeNodeFlags.DefaultOpen) then
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_Resizable", s.flags, TF.Resizable)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_Reorderable", s.flags, TF.Reorderable)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_Hideable", s.flags, TF.Hideable)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_Sortable", s.flags, TF.Sortable)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoSavedSettings", s.flags, TF.NoSavedSettings)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_ContextMenuInBody", s.flags, TF.ContextMenuInBody)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNodeEx("Decorations:", ImGuiTreeNodeFlags.DefaultOpen) then
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_RowBg", s.flags, TF.RowBg)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_BordersV", s.flags, TF.BordersV)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_BordersOuterV", s.flags, TF.BordersOuterV)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_BordersInnerV", s.flags, TF.BordersInnerV)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_BordersH", s.flags, TF.BordersH)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_BordersOuterH", s.flags, TF.BordersOuterH)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_BordersInnerH", s.flags, TF.BordersInnerH)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoBordersInBody", s.flags, TF.NoBordersInBody); ImGui.SameLine(); DemoHelpMarker("Disable vertical borders in columns Body (borders will always appear in Headers)")
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoBordersInBodyUntilResize", s.flags, TF.NoBordersInBodyUntilResize); ImGui.SameLine(); DemoHelpMarker("Disable vertical borders in columns Body until hovered for resize (borders will always appear in Headers)")
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNodeEx("Sizing:", ImGuiTreeNodeFlags.DefaultOpen) then
|
|
s.flags = EditTableSizingFlags(s.flags)
|
|
ImGui.SameLine(); DemoHelpMarker("In the Advanced demo we override the policy of each column so those table-wide settings have less effect that typical.")
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoHostExtendX", s.flags, TF.NoHostExtendX)
|
|
ImGui.SameLine(); DemoHelpMarker("Make outer width auto-fit to columns, overriding outer_size.x value.\n\nOnly available when ScrollX/ScrollY are disabled and Stretch columns are not used.")
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoHostExtendY", s.flags, TF.NoHostExtendY)
|
|
ImGui.SameLine(); DemoHelpMarker("Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit).\n\nOnly available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.")
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", s.flags, TF.NoKeepColumnsVisible)
|
|
ImGui.SameLine(); DemoHelpMarker("Only available if ScrollX is disabled.")
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_PreciseWidths", s.flags, TF.PreciseWidths)
|
|
ImGui.SameLine(); DemoHelpMarker("Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth.")
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoClip", s.flags, TF.NoClip)
|
|
ImGui.SameLine(); DemoHelpMarker("Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with ScrollFreeze options.")
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNodeEx("Padding:", ImGuiTreeNodeFlags.DefaultOpen) then
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_PadOuterX", s.flags, TF.PadOuterX)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoPadOuterX", s.flags, TF.NoPadOuterX)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_NoPadInnerX", s.flags, TF.NoPadInnerX)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNodeEx("Scrolling:", ImGuiTreeNodeFlags.DefaultOpen) then
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_ScrollX", s.flags, TF.ScrollX)
|
|
ImGui.SameLine()
|
|
ImGui.SetNextItemWidth(ImGui.GetFrameHeight())
|
|
s.freeze_cols = ImGui.DragInt("freeze_cols", s.freeze_cols, 0.2, 0, 9, nil, ImGuiSliderFlags.NoInput)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_ScrollY", s.flags, TF.ScrollY)
|
|
ImGui.SameLine()
|
|
ImGui.SetNextItemWidth(ImGui.GetFrameHeight())
|
|
s.freeze_rows = ImGui.DragInt("freeze_rows", s.freeze_rows, 0.2, 0, 9, nil, ImGuiSliderFlags.NoInput)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNodeEx("Sorting:", ImGuiTreeNodeFlags.DefaultOpen) then
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_SortMulti", s.flags, TF.SortMulti)
|
|
ImGui.SameLine(); DemoHelpMarker("When sorting is enabled: hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1).")
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_SortTristate", s.flags, TF.SortTristate)
|
|
ImGui.SameLine(); DemoHelpMarker("When sorting is enabled: allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0).")
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNodeEx("Headers:", ImGuiTreeNodeFlags.DefaultOpen) then
|
|
_, s.show_headers = ImGui.Checkbox("show_headers", s.show_headers)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiTableFlags_HighlightHoveredColumn", s.flags, TF.HighlightHoveredColumn)
|
|
_, s.columns_base_flags = ImGui.CheckboxFlags("ImGuiTableColumnFlags_AngledHeader", s.columns_base_flags, ImGuiTableColumnFlags.AngledHeader)
|
|
ImGui.SameLine(); DemoHelpMarker("Enable AngledHeader on all columns. Best enabled on selected narrow columns (see \"Angled headers\" section of the demo).")
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNodeEx("Other:", ImGuiTreeNodeFlags.DefaultOpen) then
|
|
_, s.show_wrapped_text = ImGui.Checkbox("show_wrapped_text", s.show_wrapped_text)
|
|
|
|
ImGui.DragFloat2("##OuterSize", s.outer_size_value)
|
|
ImGui.SameLine(0.0, ImGui.GetStyle().ItemInnerSpacing.x)
|
|
_, s.outer_size_enabled = ImGui.Checkbox("outer_size", s.outer_size_enabled)
|
|
ImGui.SameLine()
|
|
DemoHelpMarker("If scrolling is disabled (ScrollX and ScrollY not set):\n" ..
|
|
"- The table is output directly in the parent window.\n" ..
|
|
"- OuterSize.x < 0.0f will right-align the table.\n" ..
|
|
"- OuterSize.x = 0.0f will narrow fit the table unless there are any Stretch columns.\n" ..
|
|
"- OuterSize.y then becomes the minimum size for the table, which will extend vertically if there are more rows (unless NoHostExtendY is set).")
|
|
|
|
s.inner_width_with_scroll = ImGui.DragFloat("inner_width (when ScrollX active)", s.inner_width_with_scroll, 1.0, 0.0, FLT_MAX)
|
|
|
|
s.row_min_height = ImGui.DragFloat("row_min_height", s.row_min_height, 1.0, 0.0, FLT_MAX)
|
|
ImGui.SameLine(); DemoHelpMarker("Specify height of the Selectable item.")
|
|
|
|
s.items_count = ImGui.DragInt("items_count", s.items_count, 0.1, 0, 9999)
|
|
local contents_type_names = { "Text", "Button", "SmallButton", "FillButton", "Selectable", "Selectable (span row)" }
|
|
if ImGui.Combo then
|
|
s.contents_type = ImGui.Combo("items_type (first column)", s.contents_type, contents_type_names, #contents_type_names)
|
|
else
|
|
NotPorted("Combo")
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
ImGui.PopItemWidth()
|
|
PopStyleCompact()
|
|
ImGui.Spacing()
|
|
end
|
|
|
|
local function Tables_Advanced()
|
|
IMGUI_DEMO_MARKER("Tables/Advanced")
|
|
local CT_Text, CT_Button, CT_SmallButton, CT_FillButton, CT_Selectable, CT_SelectableSpanRow = 0, 1, 2, 3, 4, 5
|
|
local s = ST.advanced
|
|
if s == nil then
|
|
s = { flags = bor(TF.Resizable, TF.Reorderable, TF.Hideable, TF.Sortable, TF.SortMulti, TF.RowBg, TF.Borders, TF.NoBordersInBody, TF.ScrollX, TF.ScrollY, TF.SizingFixedFit),
|
|
columns_base_flags = ImGuiTableColumnFlags.None, contents_type = CT_SelectableSpanRow,
|
|
freeze_cols = 1, freeze_rows = 1, items_count = #template_items_names * 2,
|
|
outer_size_value = ImVec2(0.0, TEXT_BASE_HEIGHT * 12), row_min_height = 0.0, inner_width_with_scroll = 0.0,
|
|
outer_size_enabled = true, show_headers = true, show_wrapped_text = false,
|
|
items = {}, selection = {}, items_need_sort = false, show_debug_details = false }
|
|
ST.advanced = s
|
|
end
|
|
if ImGui.TreeNode("Options") then
|
|
Tables_AdvancedOptions(s)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
-- Update item list if we changed the number of items
|
|
local items = s.items
|
|
local selection = s.selection
|
|
if #items ~= s.items_count then
|
|
for n = #items, s.items_count + 1, -1 do items[n] = nil end
|
|
for n = 0, s.items_count - 1 do
|
|
local template_n = n % #template_items_names
|
|
items[n + 1] = MyItem(n, template_items_names[template_n + 1], (template_n == 3) and 10 or (template_n == 4) and 20 or 0) -- Assign default quantities
|
|
end
|
|
end
|
|
|
|
local parent_draw_list = ImGui.GetWindowDrawList()
|
|
local parent_draw_list_draw_cmd_count = parent_draw_list.CmdBuffer.Size
|
|
local table_scroll_cur, table_scroll_max -- For debug display
|
|
local table_draw_list = nil
|
|
|
|
-- Submit table
|
|
local flags = s.flags
|
|
local columns_base_flags = s.columns_base_flags
|
|
local inner_width_to_use = Has(flags, TF.ScrollX) and s.inner_width_with_scroll or 0.0
|
|
local CF = ImGuiTableColumnFlags
|
|
if ImGui.BeginTable("table_advanced", 6, flags, s.outer_size_enabled and s.outer_size_value or ImVec2(0, 0), inner_width_to_use) then
|
|
ImGui.TableSetupColumn("ID", bor(columns_base_flags, CF.DefaultSort, CF.WidthFixed, CF.NoHide), 0.0, MyItemColumnID_ID)
|
|
ImGui.TableSetupColumn("Name", bor(columns_base_flags, CF.WidthFixed), 0.0, MyItemColumnID_Name)
|
|
ImGui.TableSetupColumn("Action", bor(columns_base_flags, CF.NoSort, CF.WidthFixed), 0.0, MyItemColumnID_Action)
|
|
ImGui.TableSetupColumn("Quantity", bor(columns_base_flags, CF.PreferSortDescending), 0.0, MyItemColumnID_Quantity)
|
|
ImGui.TableSetupColumn("Description", bor(columns_base_flags, Has(flags, TF.NoHostExtendX) and 0 or CF.WidthStretch), 0.0, MyItemColumnID_Description)
|
|
ImGui.TableSetupColumn("Hidden", bor(columns_base_flags, CF.DefaultHide, CF.NoSort))
|
|
ImGui.TableSetupScrollFreeze(s.freeze_cols, s.freeze_rows)
|
|
|
|
-- Sort our data if sort specs have been changed!
|
|
local sort_specs = ImGui.TableGetSortSpecs()
|
|
if sort_specs and sort_specs.SpecsDirty then
|
|
s.items_need_sort = true
|
|
end
|
|
if sort_specs and s.items_need_sort and #items > 1 then
|
|
MyItem_SortWithSortSpecs(sort_specs, items, #items)
|
|
sort_specs.SpecsDirty = false
|
|
end
|
|
s.items_need_sort = false
|
|
|
|
local sorts_specs_using_quantity = Has(ImGui.TableGetColumnFlags(3), CF.IsSorted)
|
|
|
|
-- Show headers
|
|
if s.show_headers and Has(columns_base_flags, CF.AngledHeader) then
|
|
ImGui.TableAngledHeadersRow()
|
|
end
|
|
if s.show_headers then
|
|
ImGui.TableHeadersRow()
|
|
end
|
|
|
|
-- Demonstrate using clipper for large vertical lists
|
|
local clipper = ImGuiListClipper()
|
|
clipper:Begin(#items)
|
|
while clipper:Step() do
|
|
for row_n = clipper.DisplayStart, clipper.DisplayEnd - 1 do
|
|
local item = items[row_n + 1]
|
|
|
|
local item_is_selected = table.find(selection, item.ID) ~= nil
|
|
ImGui.PushID(item.ID)
|
|
ImGui.TableNextRow(ImGuiTableRowFlags.None, s.row_min_height)
|
|
|
|
-- For the demo purpose we can select among different type of items submitted in the first column
|
|
ImGui.TableSetColumnIndex(0)
|
|
local label = string.format("%04d", item.ID)
|
|
local ct = s.contents_type
|
|
if ct == CT_Text then
|
|
ImGui.TextUnformatted(label)
|
|
elseif ct == CT_Button then
|
|
ImGui.Button(label)
|
|
elseif ct == CT_SmallButton then
|
|
ImGui.SmallButton(label)
|
|
elseif ct == CT_FillButton then
|
|
ImGui.Button(label, ImVec2(-FLT_MIN, 0.0))
|
|
elseif ct == CT_Selectable or ct == CT_SelectableSpanRow then
|
|
local selectable_flags = (ct == CT_SelectableSpanRow) and bor(ImGuiSelectableFlags.SpanAllColumns, ImGuiSelectableFlags.AllowOverlap) or ImGuiSelectableFlags.None
|
|
if ImGui.Selectable(label, item_is_selected, selectable_flags, ImVec2(0, s.row_min_height)) then
|
|
if ImGui.GetIO().KeyCtrl then
|
|
if item_is_selected then
|
|
table.remove(selection, table.find(selection, item.ID))
|
|
else
|
|
table.insert(selection, item.ID)
|
|
end
|
|
else
|
|
table.clear(selection)
|
|
table.insert(selection, item.ID)
|
|
end
|
|
end
|
|
end
|
|
|
|
if ImGui.TableSetColumnIndex(1) then
|
|
ImGui.TextUnformatted(item.Name)
|
|
end
|
|
|
|
if ImGui.TableSetColumnIndex(2) then
|
|
if ImGui.SmallButton("Chop") then item.Quantity = item.Quantity + 1 end
|
|
if sorts_specs_using_quantity and ImGui.IsItemDeactivated() then s.items_need_sort = true end
|
|
ImGui.SameLine()
|
|
if ImGui.SmallButton("Eat") then item.Quantity = item.Quantity - 1 end
|
|
if sorts_specs_using_quantity and ImGui.IsItemDeactivated() then s.items_need_sort = true end
|
|
end
|
|
|
|
if ImGui.TableSetColumnIndex(3) then
|
|
ImGui.Text("%d", item.Quantity)
|
|
end
|
|
|
|
ImGui.TableSetColumnIndex(4)
|
|
if s.show_wrapped_text then
|
|
ImGui.TextWrapped("Lorem ipsum dolor sit amet")
|
|
else
|
|
ImGui.Text("Lorem ipsum dolor sit amet")
|
|
end
|
|
|
|
if ImGui.TableSetColumnIndex(5) then
|
|
ImGui.Text("1234")
|
|
end
|
|
|
|
ImGui.PopID()
|
|
end
|
|
end
|
|
|
|
-- Store some info to display debug details below
|
|
table_scroll_cur = ImVec2(ImGui.GetScrollX(), ImGui.GetScrollY())
|
|
table_scroll_max = ImVec2(ImGui.GetScrollMaxX(), ImGui.GetScrollMaxY())
|
|
table_draw_list = ImGui.GetWindowDrawList()
|
|
ImGui.EndTable()
|
|
end
|
|
_, s.show_debug_details = ImGui.Checkbox("Debug details", s.show_debug_details)
|
|
if s.show_debug_details and table_draw_list then
|
|
ImGui.SameLine(0.0, 0.0)
|
|
local table_draw_list_draw_cmd_count = table_draw_list.CmdBuffer.Size
|
|
if table_draw_list == parent_draw_list then
|
|
ImGui.Text(": DrawCmd: +%d (in same window)",
|
|
table_draw_list_draw_cmd_count - parent_draw_list_draw_cmd_count)
|
|
else
|
|
ImGui.Text(": DrawCmd: +%d (in child window), Scroll: (%.f/%.f) (%.f/%.f)",
|
|
table_draw_list_draw_cmd_count - 1, table_scroll_cur.x, table_scroll_max.x, table_scroll_cur.y, table_scroll_max.y)
|
|
end
|
|
end
|
|
end
|
|
|
|
local DCS = { selected = -1, h_borders = true, v_borders = true, columns_count = 4, foo = 1.0, bar = 1.0 }
|
|
|
|
local function DemoWindowColumns()
|
|
local open = ImGui.TreeNode("Legacy Columns API")
|
|
ImGui.SameLine()
|
|
DemoHelpMarker("Columns() is an old API! Prefer using the more flexible and powerful BeginTable() API!")
|
|
if not open then
|
|
return
|
|
end
|
|
|
|
-- Basic columns
|
|
if ImGui.TreeNode("Basic") then
|
|
IMGUI_DEMO_MARKER("Columns (legacy API)/Basic")
|
|
ImGui.Text("Without border:")
|
|
ImGui.Columns(3, "mycolumns3", false) -- 3-ways, no border
|
|
ImGui.Separator()
|
|
for n = 0, 13 do
|
|
local label = string.format("Item %d", n)
|
|
if ImGui.Selectable(label) then end
|
|
ImGui.NextColumn()
|
|
end
|
|
ImGui.Columns(1)
|
|
ImGui.Separator()
|
|
|
|
ImGui.Text("With border:")
|
|
ImGui.Columns(4, "mycolumns") -- 4-ways, with border
|
|
ImGui.Separator()
|
|
ImGui.Text("ID"); ImGui.NextColumn()
|
|
ImGui.Text("Name"); ImGui.NextColumn()
|
|
ImGui.Text("Path"); ImGui.NextColumn()
|
|
ImGui.Text("Hovered"); ImGui.NextColumn()
|
|
ImGui.Separator()
|
|
local names = { "One", "Two", "Three" }
|
|
local paths = { "/path/one", "/path/two", "/path/three" }
|
|
for i = 0, 2 do
|
|
local label = string.format("%04d", i)
|
|
if ImGui.Selectable(label, DCS.selected == i, ImGuiSelectableFlags.SpanAllColumns) then
|
|
DCS.selected = i
|
|
end
|
|
local hovered = ImGui.IsItemHovered()
|
|
ImGui.NextColumn()
|
|
ImGui.Text(names[i + 1]); ImGui.NextColumn()
|
|
ImGui.Text(paths[i + 1]); ImGui.NextColumn()
|
|
ImGui.Text("%d", hovered and 1 or 0); ImGui.NextColumn()
|
|
end
|
|
ImGui.Columns(1)
|
|
ImGui.Separator()
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Borders") then
|
|
IMGUI_DEMO_MARKER("Columns (legacy API)/Borders")
|
|
-- NB: Future columns API should allow automatic horizontal borders.
|
|
local lines_count = 3
|
|
ImGui.SetNextItemWidth(ImGui.GetFontSize() * 8)
|
|
DCS.columns_count = ImGui.DragInt("##columns_count", DCS.columns_count, 0.1, 2, 10, "%d columns")
|
|
if DCS.columns_count < 2 then
|
|
DCS.columns_count = 2
|
|
end
|
|
ImGui.SameLine()
|
|
_, DCS.h_borders = ImGui.Checkbox("horizontal", DCS.h_borders)
|
|
ImGui.SameLine()
|
|
_, DCS.v_borders = ImGui.Checkbox("vertical", DCS.v_borders)
|
|
ImGui.Columns(DCS.columns_count, nil, DCS.v_borders)
|
|
for i = 0, DCS.columns_count * lines_count - 1 do
|
|
if DCS.h_borders and ImGui.GetColumnIndex() == 0 then
|
|
ImGui.Separator()
|
|
end
|
|
ImGui.PushID(i)
|
|
local c = string.char(string.byte("a") + i)
|
|
ImGui.Text("%s%s%s", c, c, c)
|
|
ImGui.Text("Width %.2f", ImGui.GetColumnWidth())
|
|
ImGui.Text("Avail %.2f", ImGui.GetContentRegionAvail().x)
|
|
ImGui.Text("Offset %.2f", ImGui.GetColumnOffset())
|
|
ImGui.Text("Long text that is likely to clip")
|
|
ImGui.Button("Button", ImVec2(-FLT_MIN, 0.0))
|
|
ImGui.PopID()
|
|
ImGui.NextColumn()
|
|
end
|
|
ImGui.Columns(1)
|
|
if DCS.h_borders then
|
|
ImGui.Separator()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
-- Create multiple items in a same cell before switching to next column
|
|
if ImGui.TreeNode("Mixed items") then
|
|
IMGUI_DEMO_MARKER("Columns (legacy API)/Mixed items")
|
|
ImGui.Columns(3, "mixed")
|
|
ImGui.Separator()
|
|
|
|
ImGui.Text("Hello")
|
|
ImGui.Button("Banana")
|
|
ImGui.NextColumn()
|
|
|
|
ImGui.Text("ImGui")
|
|
ImGui.Button("Apple")
|
|
DCS.foo = ImGui.InputFloat("red", DCS.foo, 0.05, 0, "%.3f")
|
|
ImGui.Text("An extra line here.")
|
|
ImGui.NextColumn()
|
|
|
|
ImGui.Text("Sailor")
|
|
ImGui.Button("Corniflower")
|
|
DCS.bar = ImGui.InputFloat("blue", DCS.bar, 0.05, 0, "%.3f")
|
|
ImGui.NextColumn()
|
|
|
|
if ImGui.CollapsingHeader("Category A") then ImGui.Text("Blah blah blah") end ImGui.NextColumn()
|
|
if ImGui.CollapsingHeader("Category B") then ImGui.Text("Blah blah blah") end ImGui.NextColumn()
|
|
if ImGui.CollapsingHeader("Category C") then ImGui.Text("Blah blah blah") end ImGui.NextColumn()
|
|
ImGui.Columns(1)
|
|
ImGui.Separator()
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
-- Word wrapping
|
|
if ImGui.TreeNode("Word-wrapping") then
|
|
IMGUI_DEMO_MARKER("Columns (legacy API)/Word-wrapping")
|
|
ImGui.Columns(2, "word-wrapping")
|
|
ImGui.Separator()
|
|
ImGui.TextWrapped("The quick brown fox jumps over the lazy dog.")
|
|
ImGui.TextWrapped("Hello Left")
|
|
ImGui.NextColumn()
|
|
ImGui.TextWrapped("The quick brown fox jumps over the lazy dog.")
|
|
ImGui.TextWrapped("Hello Right")
|
|
ImGui.Columns(1)
|
|
ImGui.Separator()
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Horizontal Scrolling") then
|
|
IMGUI_DEMO_MARKER("Columns (legacy API)/Horizontal Scrolling")
|
|
ImGui.SetNextWindowContentSize(ImVec2(1500.0, 0.0))
|
|
local child_size = ImVec2(0, ImGui.GetFontSize() * 20.0)
|
|
ImGui.BeginChild("##ScrollingRegion", child_size, ImGuiChildFlags.None, ImGuiWindowFlags.HorizontalScrollbar)
|
|
ImGui.Columns(10)
|
|
|
|
-- Also demonstrate using clipper for large vertical lists
|
|
local ITEMS_COUNT = 2000
|
|
local clipper = ImGuiListClipper()
|
|
clipper:Begin(ITEMS_COUNT)
|
|
while clipper:Step() do
|
|
for i = clipper.DisplayStart, clipper.DisplayEnd - 1 do
|
|
for j = 0, 9 do
|
|
ImGui.Text("Line %d Column %d...", i, j)
|
|
ImGui.NextColumn()
|
|
end
|
|
end
|
|
end
|
|
ImGui.Columns(1)
|
|
ImGui.EndChild()
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Tree") then
|
|
IMGUI_DEMO_MARKER("Columns (legacy API)/Tree")
|
|
ImGui.Columns(2, "tree", true)
|
|
for x = 0, 2 do
|
|
local open1 = ImGui.TreeNode(x, "Node%d", x)
|
|
ImGui.NextColumn()
|
|
ImGui.Text("Node contents")
|
|
ImGui.NextColumn()
|
|
if open1 then
|
|
for y = 0, 2 do
|
|
local open2 = ImGui.TreeNode(y, "Node%d.%d", x, y)
|
|
ImGui.NextColumn()
|
|
ImGui.Text("Node contents")
|
|
if open2 then
|
|
ImGui.Text("Even more contents")
|
|
if ImGui.TreeNode("Tree in column") then
|
|
ImGui.Text("The quick brown fox jumps over the lazy dog")
|
|
ImGui.TreePop()
|
|
end
|
|
end
|
|
ImGui.NextColumn()
|
|
if open2 then
|
|
ImGui.TreePop()
|
|
end
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
end
|
|
ImGui.Columns(1)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
local tables_sections = {
|
|
{ "Basic", Tables_Basic },
|
|
{ "Borders, background", Tables_BordersBackground },
|
|
{ "Resizable, stretch", Tables_ResizableStretch },
|
|
{ "Resizable, fixed", Tables_ResizableFixed },
|
|
{ "Resizable, mixed", Tables_ResizableMixed },
|
|
{ "Reorderable, hideable, with headers", Tables_Reorderable },
|
|
{ "Padding", Tables_Padding },
|
|
{ "Sizing policies", Tables_SizingPolicies },
|
|
{ "Vertical scrolling, with clipping", Tables_VerticalScrolling },
|
|
{ "Horizontal scrolling", Tables_HorizontalScrolling },
|
|
{ "Columns flags", Tables_ColumnsFlags },
|
|
{ "Columns widths", Tables_ColumnsWidths },
|
|
{ "Nested tables", Tables_Nested },
|
|
{ "Row height", Tables_RowHeight },
|
|
{ "Outer size", Tables_OuterSize },
|
|
{ "Background color", Tables_BackgroundColor },
|
|
{ "Tree view", Tables_TreeView },
|
|
{ "Item width", Tables_ItemWidth },
|
|
{ "Custom headers", Tables_CustomHeaders },
|
|
{ "Angled headers", Tables_AngledHeaders },
|
|
{ "Context menus", Tables_ContextMenus },
|
|
{ "Synced instances", Tables_SyncedInstances },
|
|
{ "Sorting", Tables_Sorting },
|
|
{ "Advanced", Tables_Advanced },
|
|
}
|
|
|
|
function DemoWindowTables()
|
|
if not ImGui.CollapsingHeader("Tables & Columns") then
|
|
return
|
|
end
|
|
|
|
-- Using those as a base value to create width/height that are factor of the size of our font
|
|
TEXT_BASE_WIDTH = ImGui.CalcTextSize("A").x
|
|
TEXT_BASE_HEIGHT = ImGui.GetTextLineHeightWithSpacing()
|
|
|
|
ImGui.PushID("Tables")
|
|
|
|
local open_action = -1
|
|
if ImGui.Button("Expand all") then
|
|
open_action = 1
|
|
end
|
|
ImGui.SameLine()
|
|
if ImGui.Button("Collapse all") then
|
|
open_action = 0
|
|
end
|
|
ImGui.SameLine()
|
|
|
|
-- Options
|
|
_, ST.disable_indent = ImGui.Checkbox("Disable tree indentation", ST.disable_indent or false)
|
|
ImGui.SameLine()
|
|
DemoHelpMarker("Disable the indenting of tree nodes so demo tables can use the full window width.")
|
|
ImGui.Separator()
|
|
local disable_indent = ST.disable_indent
|
|
if disable_indent then
|
|
ImGui.PushStyleVar(ImGuiStyleVar.IndentSpacing, 0.0)
|
|
end
|
|
|
|
-- Demos
|
|
for _, sec in ipairs(tables_sections) do
|
|
if open_action ~= -1 then
|
|
ImGui.SetNextItemOpen(open_action ~= 0)
|
|
end
|
|
if ImGui.TreeNode(sec[1]) then
|
|
sec[2]()
|
|
ImGui.TreePop()
|
|
end
|
|
end
|
|
|
|
ImGui.PopID()
|
|
|
|
DemoWindowColumns()
|
|
|
|
if disable_indent then
|
|
ImGui.PopStyleVar()
|
|
end
|
|
end
|
|
|