1922 lines
107 KiB
Lua
1922 lines
107 KiB
Lua
-- Demo: DemoWindowWidgets*() sections (port of imgui_demo.cpp). Globals picked up by DemoWindowWidgets() in imgui_demo.lua.
|
|
local _
|
|
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 Buf, BufStr = DemoBuf, DemoBufStr
|
|
local S = {} -- statics, one subtable per section
|
|
|
|
local ExampleNames = {
|
|
"Artichoke", "Arugula", "Asparagus", "Avocado", "Bamboo Shoots", "Bean Sprouts", "Beans", "Beet", "Belgian Endive", "Bell Pepper",
|
|
"Bitter Gourd", "Bok Choy", "Broccoli", "Brussels Sprouts", "Burdock Root", "Cabbage", "Calabash", "Capers", "Carrot", "Cassava",
|
|
"Cauliflower", "Celery", "Celery Root", "Celcuce", "Chayote", "Chinese Broccoli", "Corn", "Cucumber" }
|
|
|
|
S.basic = { clicked = 0, check = true, e = 0, counter = 0, str0 = Buf("Hello, world!", 128), str1 = Buf("", 128),
|
|
i0 = 123, f0 = 0.001, d0 = 999999.00000001, f1 = 1.e10, vec4a = { 0.10, 0.20, 0.30, 0.44 },
|
|
di1 = 50, di2 = 42, di3 = 128, df1 = 1.0, df2 = 0.0067, si1 = 0, sf1 = 0.123, sf2 = 0.0, angle = 0.0, elem = 0,
|
|
col1 = { 1.0, 0.0, 0.2 }, col2 = { 0.4, 0.7, 0.0, 0.5 }, combo = 0, listbox = 1 }
|
|
|
|
function DemoWindowWidgetsBasic()
|
|
if not ImGui.TreeNode("Basic") then return end
|
|
local s = S.basic
|
|
ImGui.SeparatorText("General")
|
|
if ImGui.Button("Button") then s.clicked = s.clicked + 1 end
|
|
if s.clicked % 2 == 1 then ImGui.SameLine(); ImGui.Text("Thanks for clicking me!") end
|
|
_, s.check = ImGui.Checkbox("checkbox", s.check)
|
|
_, s.e = ImGui.RadioButton("radio a", s.e, 0); ImGui.SameLine()
|
|
_, s.e = ImGui.RadioButton("radio b", s.e, 1); ImGui.SameLine()
|
|
_, s.e = ImGui.RadioButton("radio c", s.e, 2)
|
|
ImGui.AlignTextToFramePadding()
|
|
ImGui.TextLinkOpenURL("Hyperlink", "https://github.com/ocornut/imgui/wiki/Error-Handling")
|
|
for i = 0, 6 do
|
|
if i > 0 then ImGui.SameLine() end
|
|
ImGui.PushID(i)
|
|
ImGui.PushStyleColor(ImGuiCol.Button, HSV(i / 7.0, 0.6, 0.6))
|
|
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, HSV(i / 7.0, 0.7, 0.7))
|
|
ImGui.PushStyleColor(ImGuiCol.ButtonActive, HSV(i / 7.0, 0.8, 0.8))
|
|
ImGui.Button("Click")
|
|
ImGui.PopStyleColor(3)
|
|
ImGui.PopID()
|
|
end
|
|
ImGui.AlignTextToFramePadding()
|
|
ImGui.Text("Hold to repeat:")
|
|
ImGui.SameLine()
|
|
local spacing = ImGui.GetStyle().ItemInnerSpacing.x
|
|
ImGui.PushItemFlag(ImGuiItemFlags.ButtonRepeat, true)
|
|
if ImGui.ArrowButton("##left", ImGuiDir.Left) then s.counter = s.counter - 1 end
|
|
ImGui.SameLine(0.0, spacing)
|
|
if ImGui.ArrowButton("##right", ImGuiDir.Right) then s.counter = s.counter + 1 end
|
|
ImGui.PopItemFlag()
|
|
ImGui.SameLine()
|
|
ImGui.Text("%d", s.counter)
|
|
ImGui.Button("Tooltip")
|
|
ImGui.SetItemTooltip("I am a tooltip")
|
|
ImGui.LabelText("label", "Value")
|
|
|
|
ImGui.SeparatorText("Inputs")
|
|
ImGui.InputText("input text", s.str0, 128)
|
|
ImGui.SameLine(); HelpMarker("USER:\nHold Shift or use mouse to select text.\nCtrl+Left/Right to word jump.\nCtrl+A or Double-Click to select all.\nCtrl+X,Ctrl+C,Ctrl+V for clipboard.\nCtrl+Z to undo, Ctrl+Y/Ctrl+Shift+Z to redo.\nEscape to revert.")
|
|
ImGui.InputTextWithHint("input text (w/ hint)", "enter text here", s.str1, 128)
|
|
s.i0 = ImGui.InputInt("input int", s.i0)
|
|
s.f0 = ImGui.InputFloat("input float", s.f0, 0.01, 1.0, "%.3f")
|
|
s.d0 = ImGui.InputDouble("input double", s.d0, 0.01, 1.0, "%.8f")
|
|
s.f1 = ImGui.InputFloat("input scientific", s.f1, 0.0, 0.0, "%e")
|
|
ImGui.SameLine(); HelpMarker("You can input value using the scientific notation,\n e.g. \"1e+8\" becomes \"100000000\".")
|
|
ImGui.InputFloat3("input float3", s.vec4a)
|
|
|
|
ImGui.SeparatorText("Drags")
|
|
s.di1 = ImGui.DragInt("drag int", s.di1, 1)
|
|
ImGui.SameLine(); HelpMarker("Click and drag to edit value.\nHold Shift/Alt for faster/slower edit.\nDouble-Click or Ctrl+Click to input value.")
|
|
s.di2 = ImGui.DragInt("drag int 0..100", s.di2, 1, 0, 100, "%d%%", ImGuiSliderFlags.AlwaysClamp)
|
|
s.di3 = ImGui.DragInt("drag int wrap 100..200", s.di3, 1, 100, 200, "%d", ImGuiSliderFlags.WrapAround)
|
|
s.df1 = ImGui.DragFloat("drag float", s.df1, 0.005)
|
|
s.df2 = ImGui.DragFloat("drag small float", s.df2, 0.0001, 0.0, 0.0, "%.06f ns")
|
|
|
|
ImGui.SeparatorText("Sliders")
|
|
s.si1 = ImGui.SliderInt("slider int", s.si1, -1, 3)
|
|
ImGui.SameLine(); HelpMarker("Ctrl+Click to input value.")
|
|
s.sf1 = ImGui.SliderFloat("slider float", s.sf1, 0.0, 1.0, "ratio = %.3f")
|
|
s.sf2 = ImGui.SliderFloat("slider float (log)", s.sf2, -10.0, 10.0, "%.4f", ImGuiSliderFlags.Logarithmic)
|
|
s.angle = ImGui.SliderAngle("slider angle", s.angle)
|
|
local elems_names = { "Fire", "Earth", "Air", "Water" }
|
|
local elem_name = elems_names[s.elem + 1] or "Unknown"
|
|
s.elem = ImGui.SliderInt("slider enum", s.elem, 0, 3, elem_name)
|
|
ImGui.SameLine(); HelpMarker("Using the format string parameter to display a name instead of the underlying integer.")
|
|
|
|
ImGui.SeparatorText("Selectors/Pickers")
|
|
ImGui.ColorEdit3("color 1", s.col1)
|
|
ImGui.SameLine(); HelpMarker("Click on the color square to open a color picker.\nClick and hold to use drag and drop.\nRight-Click on the color square to show options.\nCtrl+Click on individual component to input value.\n")
|
|
ImGui.ColorEdit4("color 2", s.col2)
|
|
s.combo = ImGui.Combo("combo", s.combo, { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIIIIII", "JJJJ", "KKKKKKK" })
|
|
ImGui.SameLine(); HelpMarker("Using the simplified one-liner Combo API here.")
|
|
s.listbox = ImGui.ListBox("listbox", s.listbox, { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon" }, 9, 4)
|
|
ImGui.SameLine(); HelpMarker("Using the simplified one-liner ListBox API here.")
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.chdr = { closable_group = true }
|
|
function DemoWindowWidgetsBullets()
|
|
if not ImGui.TreeNode("Bullets") then return end
|
|
ImGui.BulletText("Bullet point 1")
|
|
ImGui.BulletText("Bullet point 2\nOn multiple lines")
|
|
if ImGui.TreeNode("Tree node") then ImGui.BulletText("Another bullet point"); ImGui.TreePop() end
|
|
ImGui.Bullet(); ImGui.Text("Bullet point 3 (two calls)")
|
|
ImGui.Bullet(); ImGui.SmallButton("Button")
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
function DemoWindowWidgetsCollapsingHeaders()
|
|
if not ImGui.TreeNode("Collapsing Headers") then return end
|
|
local s = S.chdr
|
|
_, s.closable_group = ImGui.Checkbox("Show 2nd header", s.closable_group)
|
|
if ImGui.CollapsingHeader("Header", ImGuiTreeNodeFlags.None) then
|
|
ImGui.Text("IsItemHovered: %d", ImGui.IsItemHovered() and 1 or 0)
|
|
for i = 0, 4 do ImGui.Text("Some content %d", i) end
|
|
end
|
|
local open
|
|
open, s.closable_group = ImGui.CollapsingHeader("Header with a close button", s.closable_group)
|
|
if open then
|
|
ImGui.Text("IsItemHovered: %d", ImGui.IsItemHovered() and 1 or 0)
|
|
for i = 0, 4 do ImGui.Text("More content %d", i) end
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
IMGUI_PAYLOAD_TYPE_COLOR_3F = IMGUI_PAYLOAD_TYPE_COLOR_3F or "_COL3F"
|
|
IMGUI_PAYLOAD_TYPE_COLOR_4F = IMGUI_PAYLOAD_TYPE_COLOR_4F or "_COL4F"
|
|
|
|
S.color = { color = ImVec4(114.0 / 255.0, 144.0 / 255.0, 154.0 / 255.0, 200.0 / 255.0), base_flags = 0, palette = nil,
|
|
backup = ImVec4(), no_border = false, ref_color = false, ref_color_v = ImVec4(1.0, 0.0, 1.0, 0.5), picker_mode = 0,
|
|
display_mode = 0, picker_flags = ImGuiColorEditFlags.AlphaBar, hsv = ImVec4(0.23, 1.0, 1.0, 1.0) }
|
|
|
|
function DemoWindowWidgetsColorAndPickers()
|
|
if not ImGui.TreeNode("Color/Picker Widgets") then return end
|
|
local s = S.color
|
|
local CE = ImGuiColorEditFlags
|
|
local color = s.color
|
|
|
|
ImGui.SeparatorText("Options")
|
|
_, s.base_flags = ImGui.CheckboxFlags("ImGuiColorEditFlags_NoAlpha", s.base_flags, CE.NoAlpha)
|
|
_, s.base_flags = ImGui.CheckboxFlags("ImGuiColorEditFlags_AlphaOpaque", s.base_flags, CE.AlphaOpaque)
|
|
_, s.base_flags = ImGui.CheckboxFlags("ImGuiColorEditFlags_AlphaNoBg", s.base_flags, CE.AlphaNoBg)
|
|
_, s.base_flags = ImGui.CheckboxFlags("ImGuiColorEditFlags_AlphaPreviewHalf", s.base_flags, CE.AlphaPreviewHalf)
|
|
_, s.base_flags = ImGui.CheckboxFlags("ImGuiColorEditFlags_NoOptions", s.base_flags, CE.NoOptions); ImGui.SameLine(); HelpMarker("Right-click on the individual color widget to show options.")
|
|
_, s.base_flags = ImGui.CheckboxFlags("ImGuiColorEditFlags_NoDragDrop", s.base_flags, CE.NoDragDrop)
|
|
if CE.NoColorMarkers then _, s.base_flags = ImGui.CheckboxFlags("ImGuiColorEditFlags_NoColorMarkers", s.base_flags, CE.NoColorMarkers) end
|
|
_, s.base_flags = ImGui.CheckboxFlags("ImGuiColorEditFlags_HDR", s.base_flags, CE.HDR); ImGui.SameLine(); HelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets.")
|
|
local base_flags = s.base_flags
|
|
|
|
ImGui.SeparatorText("Inline color editor")
|
|
ImGui.Text("Color widget:")
|
|
ImGui.SameLine(); HelpMarker("Click on the color square to open a color picker.\nCtrl+Click on individual component to input value.\n")
|
|
ImGui.ColorEdit3("MyColor##1", color, base_flags)
|
|
ImGui.Text("Color widget HSV with Alpha:")
|
|
ImGui.ColorEdit4("MyColor##2", color, bit32.bor(CE.DisplayHSV, base_flags))
|
|
ImGui.Text("Color widget with Float Display:")
|
|
ImGui.ColorEdit4("MyColor##2f", color, bit32.bor(CE.Float, base_flags))
|
|
ImGui.Text("Color button with Picker:")
|
|
ImGui.SameLine(); HelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup.")
|
|
ImGui.ColorEdit4("MyColor##3", color, bit32.bor(CE.NoInputs, CE.NoLabel, base_flags))
|
|
|
|
ImGui.Text("Color button with Custom Picker Popup:")
|
|
if s.palette == nil then
|
|
s.palette = {}
|
|
for n = 0, 31 do s.palette[n] = HSV(n / 31.0, 0.8, 0.8, 1.0) end
|
|
end
|
|
local open_popup = ImGui.ColorButton("MyColor##3b", color, base_flags)
|
|
ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.x)
|
|
open_popup = ImGui.Button("Palette") or open_popup
|
|
if open_popup then
|
|
ImGui.OpenPopup("mypicker")
|
|
ImVec4_Copy(s.backup, color)
|
|
end
|
|
if ImGui.BeginPopup("mypicker") then
|
|
ImGui.Text("MY CUSTOM COLOR PICKER WITH AN AMAZING PALETTE!")
|
|
ImGui.Separator()
|
|
ImGui.ColorPicker4("##picker", color, bit32.bor(base_flags, CE.NoSidePreview, CE.NoSmallPreview))
|
|
ImGui.SameLine()
|
|
ImGui.BeginGroup()
|
|
ImGui.Text("Current")
|
|
ImGui.ColorButton("##current", color, bit32.bor(CE.NoPicker, CE.AlphaPreviewHalf), ImVec2(60, 40))
|
|
ImGui.Text("Previous")
|
|
if ImGui.ColorButton("##previous", s.backup, bit32.bor(CE.NoPicker, CE.AlphaPreviewHalf), ImVec2(60, 40)) then
|
|
ImVec4_Copy(color, s.backup)
|
|
end
|
|
ImGui.Separator()
|
|
ImGui.Text("Palette")
|
|
for n = 0, 31 do
|
|
ImGui.PushID(n)
|
|
if n % 8 ~= 0 then ImGui.SameLine(0.0, ImGui.GetStyle().ItemSpacing.y) end
|
|
local pal = s.palette[n]
|
|
if ImGui.ColorButton("##palette", pal, bit32.bor(CE.NoAlpha, CE.NoPicker, CE.NoTooltip), ImVec2(20, 20)) then
|
|
color.x = pal.x; color.y = pal.y; color.z = pal.z -- Preserve alpha!
|
|
end
|
|
if ImGui.BeginDragDropTarget() then
|
|
local payload = ImGui.AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F)
|
|
if payload and payload.Data then pal.x, pal.y, pal.z = payload.Data[1], payload.Data[2], payload.Data[3] end
|
|
payload = ImGui.AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)
|
|
if payload and payload.Data then pal.x, pal.y, pal.z, pal.w = payload.Data[1], payload.Data[2], payload.Data[3], payload.Data[4] end
|
|
ImGui.EndDragDropTarget()
|
|
end
|
|
ImGui.PopID()
|
|
end
|
|
ImGui.EndGroup()
|
|
ImGui.EndPopup()
|
|
end
|
|
|
|
ImGui.Text("Color button only:")
|
|
_, s.no_border = ImGui.Checkbox("ImGuiColorEditFlags_NoBorder", s.no_border)
|
|
ImGui.ColorButton("MyColor##3c", color, bit32.bor(base_flags, s.no_border and CE.NoBorder or 0), ImVec2(80, 80))
|
|
|
|
ImGui.SeparatorText("Color picker")
|
|
ImGui.PushID("Color picker")
|
|
_, s.picker_flags = ImGui.CheckboxFlags("ImGuiColorEditFlags_NoAlpha", s.picker_flags, CE.NoAlpha)
|
|
_, s.picker_flags = ImGui.CheckboxFlags("ImGuiColorEditFlags_AlphaBar", s.picker_flags, CE.AlphaBar)
|
|
_, s.picker_flags = ImGui.CheckboxFlags("ImGuiColorEditFlags_NoSidePreview", s.picker_flags, CE.NoSidePreview)
|
|
if bit32.band(s.picker_flags, CE.NoSidePreview) ~= 0 then
|
|
ImGui.SameLine()
|
|
_, s.ref_color = ImGui.Checkbox("With Ref Color", s.ref_color)
|
|
if s.ref_color then
|
|
ImGui.SameLine()
|
|
ImGui.ColorEdit4("##RefColor", s.ref_color_v, bit32.bor(CE.NoInputs, base_flags))
|
|
end
|
|
end
|
|
_, s.picker_flags = ImGui.CheckboxFlags("ImGuiColorEditFlags_PickerNoRotate", s.picker_flags, CE.PickerNoRotate)
|
|
s.picker_mode = ImGui.Combo("Picker Mode", s.picker_mode, "Auto/Current\0ImGuiColorEditFlags_PickerHueBar\0ImGuiColorEditFlags_PickerHueWheel\0")
|
|
ImGui.SameLine(); HelpMarker("When not specified explicitly, user can right-click the picker to change mode.")
|
|
s.display_mode = ImGui.Combo("Display Mode", s.display_mode, "Auto/Current\0ImGuiColorEditFlags_NoInputs\0ImGuiColorEditFlags_DisplayRGB\0ImGuiColorEditFlags_DisplayHSV\0ImGuiColorEditFlags_DisplayHex\0")
|
|
ImGui.SameLine(); HelpMarker("ColorEdit defaults to displaying RGB inputs if you don't specify a display mode, but the user can change it with a right-click on those inputs.\n\nColorPicker defaults to displaying RGB+HSV+Hex if you don't specify a display mode.\n\nYou can change the defaults using io.ConfigColorEditFlags.")
|
|
local flags = bit32.bor(base_flags, s.picker_flags)
|
|
if s.picker_mode == 1 then flags = bit32.bor(flags, CE.PickerHueBar) end
|
|
if s.picker_mode == 2 then flags = bit32.bor(flags, CE.PickerHueWheel) end
|
|
if s.display_mode == 1 then flags = bit32.bor(flags, CE.NoInputs) end
|
|
if s.display_mode == 2 then flags = bit32.bor(flags, CE.DisplayRGB) end
|
|
if s.display_mode == 3 then flags = bit32.bor(flags, CE.DisplayHSV) end
|
|
if s.display_mode == 4 then flags = bit32.bor(flags, CE.DisplayHex) end
|
|
ImGui.ColorPicker4("MyColor##4", color, flags, s.ref_color and s.ref_color_v or nil)
|
|
|
|
ImGui.Text("Set defaults in code:")
|
|
ImGui.SameLine(); HelpMarker("io.ConfigColorEditFlags is designed to allow you to set boot-time default.")
|
|
if ImGui.Button("Overwrite default: Uint8 + HSV + Hue Bar") then
|
|
ImGui.GetIO().ConfigColorEditFlags = bit32.bor(CE.Uint8, CE.DisplayHSV, CE.PickerHueBar, CE.InputRGB) -- [port] + InputRGB: upstream omits it and then trips its own InputMask_ assert
|
|
end
|
|
if ImGui.Button("Overwrite default: Float + HDR + Hue Wheel") then
|
|
ImGui.GetIO().ConfigColorEditFlags = bit32.bor(CE.Float, CE.HDR, CE.PickerHueWheel, CE.DisplayRGB, CE.InputRGB)
|
|
end
|
|
|
|
ImGui.Text("Both types:")
|
|
local w = (ImGui.GetContentRegionAvail().x - ImGui.GetStyle().ItemSpacing.y) * 0.40
|
|
ImGui.SetNextItemWidth(w)
|
|
ImGui.ColorPicker3("##MyColor##5", color, bit32.bor(CE.PickerHueBar, CE.NoSidePreview, CE.NoInputs, CE.NoAlpha))
|
|
ImGui.SameLine()
|
|
ImGui.SetNextItemWidth(w)
|
|
ImGui.ColorPicker3("##MyColor##6", color, bit32.bor(CE.PickerHueWheel, CE.NoSidePreview, CE.NoInputs, CE.NoAlpha))
|
|
ImGui.PopID()
|
|
|
|
ImGui.Spacing()
|
|
ImGui.Text("HSV encoded colors")
|
|
ImGui.SameLine(); HelpMarker("By default, colors are given to ColorEdit and ColorPicker in RGB, but ImGuiColorEditFlags_InputHSV allows you to store colors as HSV and pass them to ColorEdit and ColorPicker as HSV.")
|
|
ImGui.Text("Color widget with InputHSV:")
|
|
ImGui.ColorEdit4("HSV shown as RGB##1", s.hsv, bit32.bor(CE.DisplayRGB, CE.InputHSV, CE.Float))
|
|
ImGui.ColorEdit4("HSV shown as HSV##1", s.hsv, bit32.bor(CE.DisplayHSV, CE.InputHSV, CE.Float))
|
|
ImGui.DragFloat4("Raw HSV values", s.hsv, 0.01, 0.0, 1.0)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.combo = { flags = 0, sel = 0, filter = nil, c2 = 0, c3 = -1, c4 = 0 }
|
|
function DemoWindowWidgetsComboBoxes()
|
|
if not ImGui.TreeNode("Combo") then return end
|
|
local s = S.combo
|
|
local CF = ImGuiComboFlags
|
|
local p
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", s.flags, CF.PopupAlignLeft)
|
|
ImGui.SameLine(); HelpMarker("Only makes a difference if the popup is larger than the combo")
|
|
p, s.flags = ImGui.CheckboxFlags("ImGuiComboFlags_NoArrowButton", s.flags, CF.NoArrowButton)
|
|
if p then s.flags = bit32.band(s.flags, bit32.bnot(CF.NoPreview)) end
|
|
p, s.flags = ImGui.CheckboxFlags("ImGuiComboFlags_NoPreview", s.flags, CF.NoPreview)
|
|
if p then s.flags = bit32.band(s.flags, bit32.bnot(bit32.bor(CF.NoArrowButton, CF.WidthFitPreview))) end
|
|
p, s.flags = ImGui.CheckboxFlags("ImGuiComboFlags_WidthFitPreview", s.flags, CF.WidthFitPreview)
|
|
if p then s.flags = bit32.band(s.flags, bit32.bnot(CF.NoPreview)) end
|
|
for _, h in ipairs({ "HeightSmall", "HeightRegular", "HeightLargest" }) do
|
|
p, s.flags = ImGui.CheckboxFlags("ImGuiComboFlags_" .. h, s.flags, CF[h])
|
|
if p then s.flags = bit32.band(s.flags, bit32.bnot(bit32.band(CF.HeightMask_, bit32.bnot(CF[h])))) end
|
|
end
|
|
|
|
local items = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" }
|
|
local combo_preview_value = items[s.sel + 1]
|
|
if ImGui.BeginCombo("combo 1", combo_preview_value, s.flags) then
|
|
for n = 0, #items - 1 do
|
|
local is_selected = (s.sel == n)
|
|
if ImGui.Selectable(items[n + 1], is_selected) then s.sel = n end
|
|
if is_selected then ImGui.SetItemDefaultFocus() end
|
|
end
|
|
ImGui.EndCombo()
|
|
end
|
|
|
|
if ImGui.BeginCombo("combo 2 (w/ filter)", combo_preview_value, s.flags) then
|
|
s.filter = s.filter or ImGuiTextFilter()
|
|
if ImGui.IsWindowAppearing() then
|
|
ImGui.SetKeyboardFocusHere()
|
|
s.filter:Clear()
|
|
end
|
|
ImGui.SetNextItemShortcut(bit32.bor(ImGuiMod_Ctrl, ImGuiKey.F))
|
|
ImGui.SetNextItemWidth(-FLT_MIN)
|
|
s.filter:DrawWithHint("##Filter", "Filter (incl -excl)")
|
|
for n = 0, #items - 1 do
|
|
local is_selected = (s.sel == n)
|
|
if s.filter:PassFilter(items[n + 1]) then
|
|
if ImGui.Selectable(items[n + 1], is_selected) then s.sel = n end
|
|
end
|
|
end
|
|
ImGui.EndCombo()
|
|
end
|
|
|
|
ImGui.Spacing()
|
|
ImGui.SeparatorText("One-liner variants")
|
|
HelpMarker("The Combo() function is not greatly useful apart from cases were you want to embed all options in a single strings.\nFlags above don't apply to this section.")
|
|
s.c2 = ImGui.Combo("combo 3 (one-liner)", s.c2, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0")
|
|
s.c3 = ImGui.Combo("combo 4 (array)", s.c3, items, #items)
|
|
s.c4 = ImGui.Combo("combo 5 (function)", s.c4, function(data, n) return data[n + 1] end, items, #items)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.dt = { s8 = 127, u8 = 255, s16 = 32767, u16 = 65535, s32 = -1, u32 = 0xFFFFFFFF, s64 = -1, u64 = 0, f32 = 0.123, f64 = 90000.01234567890123456789,
|
|
drag_clamp = false, inputs_step = true, flags = 0 }
|
|
function DemoWindowWidgetsDataTypes()
|
|
if not ImGui.TreeNode("Data Types") then return end
|
|
local s = S.dt
|
|
local DT = ImGuiDataType
|
|
-- ponytail: Luau numbers are doubles, so S64/U64 are shown with S32/Double here (no 64-bit integer type)
|
|
local s32_min, s32_max = math.floor(-2147483648 / 2), math.floor(2147483647 / 2)
|
|
local u32_max = math.floor(4294967295 / 2)
|
|
local drag_speed = 0.2
|
|
ImGui.SeparatorText("Drags")
|
|
_, s.drag_clamp = ImGui.Checkbox("Clamp integers to 0..50", s.drag_clamp)
|
|
ImGui.SameLine(); HelpMarker("As with every widget in dear imgui, we never modify values unless there is a user interaction.\nYou can override the clamping limits by using Ctrl+Click to input a value.")
|
|
local lo, hi = s.drag_clamp and 0 or nil, s.drag_clamp and 50 or nil
|
|
s.s8 = ImGui.DragScalar("drag s8", DT.S8, s.s8, drag_speed, lo, hi)
|
|
s.u8 = ImGui.DragScalar("drag u8", DT.U8, s.u8, drag_speed, lo, hi, "%u ms")
|
|
s.s16 = ImGui.DragScalar("drag s16", DT.S16, s.s16, drag_speed, lo, hi)
|
|
s.u16 = ImGui.DragScalar("drag u16", DT.U16, s.u16, drag_speed, lo, hi, "%u ms")
|
|
s.s32 = ImGui.DragScalar("drag s32", DT.S32, s.s32, drag_speed, lo, hi)
|
|
s.s32 = ImGui.DragScalar("drag s32 hex", DT.S32, s.s32, drag_speed, lo, hi, "0x%08X")
|
|
s.u32 = ImGui.DragScalar("drag u32", DT.U32, s.u32, drag_speed, lo, hi, "%u ms")
|
|
s.f32 = ImGui.DragScalar("drag float", DT.Float, s.f32, 0.005, 0.0, 1.0, "%f")
|
|
s.f32 = ImGui.DragScalar("drag float log", DT.Float, s.f32, 0.005, 0.0, 1.0, "%f", ImGuiSliderFlags.Logarithmic)
|
|
s.f64 = ImGui.DragScalar("drag double", DT.Double, s.f64, 0.0005, 0.0, nil, "%.10f grams")
|
|
s.f64 = ImGui.DragScalar("drag double log",DT.Double, s.f64, 0.0005, 0.0, 1.0, "0 < %.10f < 1", ImGuiSliderFlags.Logarithmic)
|
|
|
|
ImGui.SeparatorText("Sliders")
|
|
s.s8 = ImGui.SliderScalar("slider s8 full", DT.S8, s.s8, -128, 127, "%d")
|
|
s.u8 = ImGui.SliderScalar("slider u8 full", DT.U8, s.u8, 0, 255, "%u")
|
|
s.s16 = ImGui.SliderScalar("slider s16 full", DT.S16, s.s16, -32768, 32767, "%d")
|
|
s.u16 = ImGui.SliderScalar("slider u16 full", DT.U16, s.u16, 0, 65535, "%u")
|
|
s.s32 = ImGui.SliderScalar("slider s32 low", DT.S32, s.s32, 0, 50, "%d")
|
|
s.s32 = ImGui.SliderScalar("slider s32 high", DT.S32, s.s32, s32_max - 100, s32_max, "%d")
|
|
s.s32 = ImGui.SliderScalar("slider s32 full", DT.S32, s.s32, s32_min, s32_max, "%d")
|
|
s.s32 = ImGui.SliderScalar("slider s32 hex", DT.S32, s.s32, 0, 50, "0x%04X")
|
|
s.u32 = ImGui.SliderScalar("slider u32 low", DT.U32, s.u32, 0, 50, "%u")
|
|
s.u32 = ImGui.SliderScalar("slider u32 high", DT.U32, s.u32, u32_max - 100, u32_max, "%u")
|
|
s.u32 = ImGui.SliderScalar("slider u32 full", DT.U32, s.u32, 0, u32_max, "%u")
|
|
s.f32 = ImGui.SliderScalar("slider float low", DT.Float, s.f32, 0.0, 1.0)
|
|
s.f32 = ImGui.SliderScalar("slider float low log", DT.Float, s.f32, 0.0, 1.0, "%.10f", ImGuiSliderFlags.Logarithmic)
|
|
s.f32 = ImGui.SliderScalar("slider float high", DT.Float, s.f32, -10000000000.0, 10000000000.0, "%e")
|
|
s.f64 = ImGui.SliderScalar("slider double low", DT.Double, s.f64, 0.0, 1.0, "%.10f grams")
|
|
s.f64 = ImGui.SliderScalar("slider double low log", DT.Double, s.f64, 0.0, 1.0, "%.10f", ImGuiSliderFlags.Logarithmic)
|
|
s.f64 = ImGui.SliderScalar("slider double high", DT.Double, s.f64, -1000000000000000.0, 1000000000000000.0, "%e grams")
|
|
|
|
ImGui.SeparatorText("Sliders (reverse)")
|
|
s.s8 = ImGui.SliderScalar("slider s8 reverse", DT.S8, s.s8, 127, -128, "%d")
|
|
s.u8 = ImGui.SliderScalar("slider u8 reverse", DT.U8, s.u8, 255, 0, "%u")
|
|
s.s32 = ImGui.SliderScalar("slider s32 reverse", DT.S32, s.s32, 50, 0, "%d")
|
|
s.u32 = ImGui.SliderScalar("slider u32 reverse", DT.U32, s.u32, 50, 0, "%u")
|
|
|
|
ImGui.SeparatorText("Inputs")
|
|
_, s.inputs_step = ImGui.Checkbox("Show step buttons", s.inputs_step)
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiInputTextFlags_ReadOnly", s.flags, ImGuiInputTextFlags.ReadOnly)
|
|
if ImGuiInputTextFlags.ParseEmptyRefVal then _, s.flags = ImGui.CheckboxFlags("ImGuiInputTextFlags_ParseEmptyRefVal", s.flags, ImGuiInputTextFlags.ParseEmptyRefVal) end
|
|
if ImGuiInputTextFlags.DisplayEmptyRefVal then _, s.flags = ImGui.CheckboxFlags("ImGuiInputTextFlags_DisplayEmptyRefVal", s.flags, ImGuiInputTextFlags.DisplayEmptyRefVal) end
|
|
local one = s.inputs_step and 1 or nil
|
|
s.s8 = ImGui.InputScalar("input s8", DT.S8, s.s8, one, nil, "%d", s.flags)
|
|
s.u8 = ImGui.InputScalar("input u8", DT.U8, s.u8, one, nil, "%u", s.flags)
|
|
s.s16 = ImGui.InputScalar("input s16", DT.S16, s.s16, one, nil, "%d", s.flags)
|
|
s.u16 = ImGui.InputScalar("input u16", DT.U16, s.u16, one, nil, "%u", s.flags)
|
|
s.s32 = ImGui.InputScalar("input s32", DT.S32, s.s32, one, nil, "%d", s.flags)
|
|
s.s32 = ImGui.InputScalar("input s32 hex", DT.S32, s.s32, one, nil, "%04X", s.flags)
|
|
s.u32 = ImGui.InputScalar("input u32", DT.U32, s.u32, one, nil, "%u", s.flags)
|
|
s.u32 = ImGui.InputScalar("input u32 hex", DT.U32, s.u32, one, nil, "%08X", s.flags)
|
|
s.f32 = ImGui.InputScalar("input float", DT.Float, s.f32, s.inputs_step and 1.0 or nil, nil, nil, s.flags)
|
|
s.f64 = ImGui.InputScalar("input double", DT.Double, s.f64, s.inputs_step and 1.0 or nil, nil, nil, s.flags)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
function DemoWindowWidgetsDisableBlocks(demo_data)
|
|
if not ImGui.TreeNode("Disable Blocks") then return end
|
|
_, demo_data.DisableSections = ImGui.Checkbox("Disable entire section above", demo_data.DisableSections)
|
|
ImGui.SameLine(); HelpMarker("Demonstrate using BeginDisabled()/EndDisabled() across other sections.")
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.dnd = { col1 = { 1.0, 0.0, 0.2 }, col2 = { 0.4, 0.7, 0.0, 0.5 }, mode = 0,
|
|
names = { "Bobby", "Beatrice", "Betty", "Brianna", "Barry", "Bernard", "Bibi", "Blaine", "Bryn" },
|
|
item_names = { "Item One", "Item Two", "Item Three", "Item Four", "Item Five" }, col4 = ImVec4(1.0, 0.0, 0.2, 1.0) }
|
|
function DemoWindowWidgetsDragAndDrop()
|
|
if not ImGui.TreeNode("Drag and Drop") then return end
|
|
local s = S.dnd
|
|
if ImGui.TreeNode("Drag and drop in standard widgets") then
|
|
HelpMarker("You can drag from the color squares.")
|
|
ImGui.ColorEdit3("color 1", s.col1)
|
|
ImGui.ColorEdit4("color 2", s.col2)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Drag and drop to copy/swap items") then
|
|
local Mode_Copy, Mode_Move, Mode_Swap = 0, 1, 2
|
|
if ImGui.RadioButtonEx("Copy", s.mode == Mode_Copy) then s.mode = Mode_Copy end ImGui.SameLine()
|
|
if ImGui.RadioButtonEx("Move", s.mode == Mode_Move) then s.mode = Mode_Move end ImGui.SameLine()
|
|
if ImGui.RadioButtonEx("Swap", s.mode == Mode_Swap) then s.mode = Mode_Swap end
|
|
local names = s.names
|
|
for n = 0, #names - 1 do
|
|
ImGui.PushID(n)
|
|
if n % 3 ~= 0 then ImGui.SameLine() end
|
|
ImGui.Button(names[n + 1], ImVec2(60, 60))
|
|
if ImGui.BeginDragDropSource(ImGuiDragDropFlags.None) then
|
|
ImGui.SetDragDropPayload("DND_DEMO_CELL", n, 4)
|
|
if s.mode == Mode_Copy then ImGui.Text("Copy %s", names[n + 1]) end
|
|
if s.mode == Mode_Move then ImGui.Text("Move %s", names[n + 1]) end
|
|
if s.mode == Mode_Swap then ImGui.Text("Swap %s", names[n + 1]) end
|
|
ImGui.EndDragDropSource()
|
|
end
|
|
if ImGui.BeginDragDropTarget() then
|
|
local payload = ImGui.AcceptDragDropPayload("DND_DEMO_CELL")
|
|
if payload then
|
|
local payload_n = payload.Data
|
|
if s.mode == Mode_Copy then names[n + 1] = names[payload_n + 1] end
|
|
if s.mode == Mode_Move then names[n + 1] = names[payload_n + 1]; names[payload_n + 1] = "" end
|
|
if s.mode == Mode_Swap then names[n + 1], names[payload_n + 1] = names[payload_n + 1], names[n + 1] end
|
|
end
|
|
ImGui.EndDragDropTarget()
|
|
end
|
|
ImGui.PopID()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Drag to reorder items (simple)") then
|
|
ImGui.PushItemFlag(ImGuiItemFlags.AllowDuplicateId, true)
|
|
HelpMarker("We don't use the drag and drop api at all here! Instead we query when the item is held but not hovered, and order items accordingly.")
|
|
local item_names = s.item_names
|
|
for n = 1, #item_names do
|
|
local item = item_names[n]
|
|
ImGui.Selectable(item)
|
|
if ImGui.IsItemActive() and not ImGui.IsItemHovered() then
|
|
local n_next = n + ((ImGui.GetMouseDragDelta(0).y < 0.0) and -1 or 1)
|
|
if n_next >= 1 and n_next <= #item_names then
|
|
item_names[n] = item_names[n_next]
|
|
item_names[n_next] = item
|
|
ImGui.ResetMouseDragDelta()
|
|
end
|
|
end
|
|
end
|
|
ImGui.PopItemFlag()
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Tooltip at target location") then
|
|
for n = 0, 1 do
|
|
ImGui.Button((n == 1) and "drop here##1" or "drop here##0")
|
|
if ImGui.BeginDragDropTarget() then
|
|
local drop_target_flags = bit32.bor(ImGuiDragDropFlags.AcceptBeforeDelivery, ImGuiDragDropFlags.AcceptNoPreviewTooltip)
|
|
if ImGui.AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F, drop_target_flags) then
|
|
ImGui.SetMouseCursor(ImGuiMouseCursor.NotAllowed)
|
|
ImGui.SetTooltip("Cannot drop here!")
|
|
end
|
|
ImGui.EndDragDropTarget()
|
|
end
|
|
if n == 0 then ImGui.ColorButton("drag me", s.col4) end
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.ds = { flags = 0, drag_f = 0.5, drag_f4 = { 0, 0, 0, 0 }, drag_i = 50, slider_f = 0.5, slider_f4 = { 0, 0, 0, 0 }, slider_i = 50 }
|
|
function DemoWindowWidgetsDragsAndSliders()
|
|
if not ImGui.TreeNode("Drag/Slider Flags") then return end
|
|
local s = S.ds
|
|
local SF = ImGuiSliderFlags
|
|
local function F(name, help)
|
|
if SF[name] == nil then return end
|
|
_, s.flags = ImGui.CheckboxFlags("ImGuiSliderFlags_" .. name, s.flags, SF[name])
|
|
if help then ImGui.SameLine(); HelpMarker(help) end
|
|
end
|
|
F("AlwaysClamp")
|
|
F("ClampOnInput", "Clamp value to min/max bounds when input manually with Ctrl+Click. By default Ctrl+Click allows going out of bounds.")
|
|
F("ClampZeroRange", "Clamp even if min==max==0.0f. Otherwise DragXXX functions don't clamp.")
|
|
F("Logarithmic", "Enable logarithmic editing (more precision for small values).")
|
|
F("NoRoundToFormat", "Disable rounding underlying value to match precision of the format string (e.g. %.3f values are rounded to those 3 digits).")
|
|
F("NoInput", "Disable Ctrl+Click or Enter key allowing to input text directly into the widget.")
|
|
F("NoSpeedTweaks", "Disable keyboard modifiers altering tweak speed. Useful if you want to alter tweak speed yourself based on your own logic.")
|
|
F("WrapAround", "Enable wrapping around from max to min and from min to max (only supported by DragXXX() functions)")
|
|
F("ColorMarkers")
|
|
local flags = s.flags
|
|
|
|
ImGui.Text("Underlying float value: %f", s.drag_f)
|
|
s.drag_f = ImGui.DragFloat("DragFloat (0 -> 1)", s.drag_f, 0.005, 0.0, 1.0, "%.3f", flags)
|
|
s.drag_f = ImGui.DragFloat("DragFloat (0 -> +inf)", s.drag_f, 0.005, 0.0, FLT_MAX, "%.3f", flags)
|
|
s.drag_f = ImGui.DragFloat("DragFloat (-inf -> 1)", s.drag_f, 0.005, -FLT_MAX, 1.0, "%.3f", flags)
|
|
s.drag_f = ImGui.DragFloat("DragFloat (-inf -> +inf)", s.drag_f, 0.005, -FLT_MAX, FLT_MAX, "%.3f", flags)
|
|
s.drag_i = ImGui.DragInt("DragInt (0 -> 100)", s.drag_i, 0.5, 0, 100, "%d", flags)
|
|
ImGui.DragFloat4("DragFloat4 (0 -> 1)", s.drag_f4, 0.005, 0.0, 1.0, "%.3f", flags)
|
|
|
|
local flags_for_sliders = bit32.band(flags, bit32.bnot(SF.WrapAround))
|
|
ImGui.Text("Underlying float value: %f", s.slider_f)
|
|
s.slider_f = ImGui.SliderFloat("SliderFloat (0 -> 1)", s.slider_f, 0.0, 1.0, "%.3f", flags_for_sliders)
|
|
s.slider_i = ImGui.SliderInt("SliderInt (0 -> 100)", s.slider_i, 0, 100, "%d", flags_for_sliders)
|
|
ImGui.SliderFloat4("SliderFloat4 (0 -> 1)", s.slider_f4, 0.0, 1.0, "%.3f", flags_for_sliders)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
function DemoWindowWidgetsFonts()
|
|
if not ImGui.TreeNode("Fonts") then return end
|
|
if ImGui.ShowFontAtlas then ImGui.ShowFontAtlas(ImGui.GetIO().Fonts) else DemoNotPorted("ShowFontAtlas") end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.img = { viewer = nil, pressed_count = 0 }
|
|
function DemoWindowWidgetsImages()
|
|
if not ImGui.TreeNode("Images") then return end
|
|
local s = S.img
|
|
local io = ImGui.GetIO()
|
|
ImGui.TextWrapped("Below we are displaying the font texture (which is the only texture we have access to in this demo). Use the 'ImTextureID' type as storage to pass pointers or identifier to your own texture data. Hover the texture for a zoomed view!")
|
|
local atlas = io.Fonts
|
|
local my_tex_id = atlas.TexRef
|
|
local my_tex_w = atlas.TexData and atlas.TexData.Width or 0
|
|
local my_tex_h = atlas.TexData and atlas.TexData.Height or 0
|
|
ImGui.Text("%.0fx%.0f", my_tex_w, my_tex_h)
|
|
|
|
ImGui.SeparatorText("Image()/ImageWithBg() function")
|
|
ImGui.PushStyleVar(ImGuiStyleVar.ImageBorderSize, math.max(1.0, ImGui.GetStyle().ImageBorderSize))
|
|
ImGui.ImageWithBg(my_tex_id, ImVec2(my_tex_w, my_tex_h), ImVec2(0.0, 0.0), ImVec2(1.0, 1.0), ImVec4(0.0, 0.0, 0.0, 1.0))
|
|
ImGui.PopStyleVar()
|
|
|
|
ImGui.SeparatorText("Interactive Image Viewer")
|
|
s.viewer = s.viewer or ExampleImageViewerData()
|
|
local canvas_size = ImVec2(ImGui.GetContentRegionAvail().x, my_tex_h * 2.0)
|
|
ExampleImageViewer_DrawOptions(s.viewer)
|
|
ExampleImageViewer_DrawCanvas(s.viewer, canvas_size, my_tex_id, my_tex_w, my_tex_h)
|
|
|
|
ImGui.SeparatorText("Textured Buttons")
|
|
ImGui.TextWrapped("And now some textured buttons..")
|
|
for i = 0, 7 do
|
|
ImGui.PushID(i)
|
|
if i > 0 then ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, ImVec2(i - 1.0, i - 1.0)) end
|
|
local size = ImVec2(32.0, 32.0)
|
|
local uv0 = ImVec2(0.0, 0.0)
|
|
local uv1 = ImVec2(32.0 / my_tex_w, 32.0 / my_tex_h)
|
|
if ImGui.ImageButton("", my_tex_id, size, uv0, uv1, ImVec4(0.0, 0.0, 0.0, 1.0), ImVec4(1.0, 1.0, 1.0, 1.0)) then
|
|
s.pressed_count = s.pressed_count + 1
|
|
end
|
|
if i > 0 then ImGui.PopStyleVar() end
|
|
ImGui.PopID()
|
|
ImGui.SameLine()
|
|
end
|
|
ImGui.NewLine()
|
|
ImGui.Text("Pressed %d times.", s.pressed_count)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.lb = { sel = 0, highlight = false }
|
|
function DemoWindowWidgetsListBoxes()
|
|
if not ImGui.TreeNode("List Boxes") then return end
|
|
local s = S.lb
|
|
local items = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" }
|
|
local item_highlighted_idx = -1
|
|
_, s.highlight = ImGui.Checkbox("Highlight hovered item in second listbox", s.highlight)
|
|
if ImGui.BeginListBox("listbox 1") then
|
|
for n = 0, #items - 1 do
|
|
local is_selected = (s.sel == n)
|
|
if ImGui.Selectable(items[n + 1], is_selected) then s.sel = n end
|
|
if s.highlight and ImGui.IsItemHovered() then item_highlighted_idx = n end
|
|
if is_selected then ImGui.SetItemDefaultFocus() end
|
|
end
|
|
ImGui.EndListBox()
|
|
end
|
|
ImGui.SameLine(); HelpMarker("Here we are sharing selection state between both boxes.")
|
|
ImGui.Text("Full-width:")
|
|
if ImGui.BeginListBox("##listbox 2", ImVec2(-FLT_MIN, 5 * ImGui.GetTextLineHeightWithSpacing())) then
|
|
for n = 0, #items - 1 do
|
|
local is_selected = (s.sel == n)
|
|
local flags = (item_highlighted_idx == n) and ImGuiSelectableFlags.Highlight or 0
|
|
if ImGui.Selectable(items[n + 1], is_selected, flags) then s.sel = n end
|
|
if is_selected then ImGui.SetItemDefaultFocus() end
|
|
end
|
|
ImGui.EndListBox()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.le = { str = Buf("", 32), i = 0, f = 0.0 }
|
|
function DemoWindowWidgetsLiveEdit(demo_data)
|
|
if not ImGui.TreeNode("Live Edit Flags") then return end
|
|
local s = S.le
|
|
ImGui.TextWrapped("Select whether to apply keyboard edits to backing variables _while_ typing.")
|
|
_, demo_data.LiveEditOverride = ImGui.Checkbox("Override Live Edit Flags in Demo Window", demo_data.LiveEditOverride)
|
|
if not demo_data.LiveEditOverride then demo_data.LiveEditFlags = ImGui.GetItemFlags() end
|
|
ImGui.BeginDisabled(demo_data.LiveEditOverride == false)
|
|
ImGui.Indent()
|
|
_, demo_data.LiveEditFlags = ImGui.CheckboxFlags("ImGuiItemFlags_LiveEditOnInputText", demo_data.LiveEditFlags, ImGuiItemFlags.LiveEditOnInputText)
|
|
_, demo_data.LiveEditFlags = ImGui.CheckboxFlags("ImGuiItemFlags_LiveEditOnInputScalar", demo_data.LiveEditFlags, ImGuiItemFlags.LiveEditOnInputScalar)
|
|
ImGui.Unindent()
|
|
ImGui.EndDisabled()
|
|
ImGui.Text("Try typing '123' and seeing effect on backing value:")
|
|
ImGui.InputText("str", s.str, 32)
|
|
ImGui.Text("Backing value: \"%s\"", BufStr(s.str))
|
|
s.i = ImGui.InputInt("int", s.i, 0, 0)
|
|
ImGui.Text("Backing value: %d", s.i)
|
|
s.f = ImGui.SliderFloat("float", s.f, 0.0, 100.0)
|
|
ImGui.Text("Backing value: %f", s.f)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.mv = { use_liveedit = false, items = { 12.0, 0.0, 0.0 } }
|
|
function DemoWindowWidgetsMixedValues()
|
|
if not ImGui.TreeNode("Mixed Values") then return end
|
|
local s = S.mv
|
|
local items = s.items
|
|
HelpMarker("Using ImGuiItemFlags_MixedValue.")
|
|
_, s.use_liveedit = ImGui.Checkbox("ImGuiItemFlags_LiveEditOnInput", s.use_liveedit)
|
|
ImGui.SeparatorText("Scalar/Text Widgets")
|
|
local is_mixed = items[1] ~= items[2] or items[1] ~= items[3]
|
|
ImGui.PushItemFlag(ImGuiItemFlags.LiveEditOnInput, s.use_liveedit)
|
|
ImGui.PushItemFlag(ImGuiItemFlags.MixedValue, is_mixed)
|
|
local edited, e = false, false
|
|
items[1], e = ImGui.DragFloat("DragFloat", items[1]); edited = edited or e
|
|
items[1], e = ImGui.SliderFloat("SliderFloat", items[1], 0.0, 100.0); edited = edited or e
|
|
items[1], e = ImGui.InputFloat("InputFloat", items[1], 1.0); edited = edited or e
|
|
if edited then items[2] = items[1]; items[3] = items[1] end
|
|
ImGui.PopItemFlag()
|
|
ImGui.Text("Underlying data:")
|
|
items[1] = ImGui.InputFloat("item 0 (ref)", items[1])
|
|
items[2] = ImGui.InputFloat("item 1", items[2])
|
|
items[3] = ImGui.InputFloat("item 2", items[3])
|
|
ImGui.PopItemFlag()
|
|
|
|
ImGui.SeparatorText("Others Widgets")
|
|
ImGui.Text("(note: edits are not applied in this demo)")
|
|
ImGui.Checkbox("Checkbox On", true)
|
|
ImGui.Checkbox("Checkbox Off", false)
|
|
ImGui.PushItemFlag(ImGuiItemFlags.MixedValue, true)
|
|
ImGui.Checkbox("Checkbox Mixed", false)
|
|
ImGui.RadioButtonEx("RadioButton Mixed", true)
|
|
ImGui.SameLine()
|
|
ImGui.RadioButtonEx("RadioButton Mixed##2", true)
|
|
ImGui.Combo("Combo", 0, "One\0Two\0Three\0")
|
|
ImGui.ColorEdit4("ColorEdit4", ImVec4(0.5, 0.5, 0.5, 0.5))
|
|
ImGui.PopItemFlag()
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.mc = { vec4f = { 0.10, 0.20, 0.30, 0.44 }, vec4i = { 1, 5, 100, 255 }, flags = 0, b = 10, e = 90, bi = 100, ei = 1000 }
|
|
function DemoWindowWidgetsMultiComponents()
|
|
if not ImGui.TreeNode("Multi-component Widgets") then return end
|
|
local s = S.mc
|
|
local f, i = s.vec4f, s.vec4i
|
|
if ImGuiSliderFlags.ColorMarkers then _, s.flags = ImGui.CheckboxFlags("ImGuiSliderFlags_ColorMarkers", s.flags, ImGuiSliderFlags.ColorMarkers) end
|
|
local flags = s.flags
|
|
for _, n in ipairs({ 2, 3, 4 }) do
|
|
ImGui.SeparatorText(n .. "-wide")
|
|
ImGui["InputFloat" .. n]("input float" .. n, f)
|
|
ImGui["InputInt" .. n]("input int" .. n, i)
|
|
ImGui["DragFloat" .. n]("drag float" .. n, f, 0.01, 0.0, 1.0, nil, flags)
|
|
ImGui["DragInt" .. n]("drag int" .. n, i, 1, 0, 255, nil, flags)
|
|
ImGui["SliderFloat" .. n]("slider float" .. n, f, 0.0, 1.0, nil, flags)
|
|
ImGui["SliderInt" .. n]("slider int" .. n, i, 0, 255, nil, flags)
|
|
end
|
|
ImGui.SeparatorText("Ranges")
|
|
s.b, s.e = ImGui.DragFloatRange2("range float", s.b, s.e, 0.25, 0.0, 100.0, "Min: %.1f %%", "Max: %.1f %%", ImGuiSliderFlags.AlwaysClamp)
|
|
s.bi, s.ei = ImGui.DragIntRange2("range int", s.bi, s.ei, 5, 0, 1000, "Min: %d units", "Max: %d units")
|
|
s.bi, s.ei = ImGui.DragIntRange2("range int (no bounds)", s.bi, s.ei, 5, 0, 0, "Min: %d units", "Max: %d units")
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.plot = { animate = true, arr = { 0.6, 0.1, 1.0, 0.5, 0.92, 0.1, 0.2 }, values = {}, values_offset = 0, refresh_time = 0.0, phase = 0.0,
|
|
func_type = 0, display_count = 70 }
|
|
for n = 1, 90 do S.plot.values[n] = 0.0 end
|
|
function DemoWindowWidgetsPlotting()
|
|
if not ImGui.TreeNode("Plotting") then return end
|
|
local s = S.plot
|
|
ImGui.Text("Need better plotting and graphing? Consider using ImPlot:")
|
|
ImGui.TextLinkOpenURL("https://github.com/epezent/implot")
|
|
ImGui.Separator()
|
|
_, s.animate = ImGui.Checkbox("Animate", s.animate)
|
|
ImGui.PlotLines("Frame Times", s.arr, nil, #s.arr)
|
|
ImGui.PlotHistogram("Histogram", s.arr, nil, #s.arr, 0, nil, 0.0, 1.0, ImVec2(0, 80.0))
|
|
|
|
local values = s.values
|
|
if not s.animate or s.refresh_time == 0.0 then s.refresh_time = ImGui.GetTime() end
|
|
while s.refresh_time < ImGui.GetTime() do
|
|
values[s.values_offset + 1] = math.cos(s.phase)
|
|
s.values_offset = (s.values_offset + 1) % #values
|
|
s.phase = s.phase + 0.10 * s.values_offset
|
|
s.refresh_time = s.refresh_time + 1.0 / 60.0
|
|
end
|
|
local average = 0.0
|
|
for n = 1, #values do average = average + values[n] end
|
|
average = average / #values
|
|
ImGui.PlotLines("Lines", values, nil, #values, s.values_offset, string.format("avg %f", average), -1.0, 1.0, ImVec2(0, 80.0))
|
|
|
|
-- Getters receive a 1-based index in this port
|
|
local function Sin(_, i) return math.sin((i - 1) * 0.1) end
|
|
local function Saw(_, i) return ((i - 1) % 2 == 1) and 1.0 or -1.0 end
|
|
ImGui.SeparatorText("Functions")
|
|
ImGui.SetNextItemWidth(ImGui.GetFontSize() * 8)
|
|
s.func_type = ImGui.Combo("func", s.func_type, "Sin\0Saw\0")
|
|
ImGui.SameLine()
|
|
s.display_count = ImGui.SliderInt("Sample count", s.display_count, 1, 400)
|
|
local func = (s.func_type == 0) and Sin or Saw
|
|
ImGui.PlotLines("Lines##2", func, nil, s.display_count, 0, nil, -1.0, 1.0, ImVec2(0, 80))
|
|
ImGui.PlotHistogram("Histogram##2", func, nil, s.display_count, 0, nil, -1.0, 1.0, ImVec2(0, 80))
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.pb = { accum = 0.0, dir = 1.0 }
|
|
function DemoWindowWidgetsProgressBars()
|
|
if not ImGui.TreeNode("Progress Bars") then return end
|
|
local s = S.pb
|
|
s.accum = s.accum + s.dir * 0.4 * ImGui.GetIO().DeltaTime
|
|
if s.accum >= 1.1 then s.accum = 1.1; s.dir = -s.dir end
|
|
if s.accum <= -0.1 then s.accum = -0.1; s.dir = -s.dir end
|
|
local progress = DemoClamp(s.accum, 0.0, 1.0)
|
|
ImGui.ProgressBar(progress, ImVec2(0.0, 0.0))
|
|
ImGui.SameLine(0.0, ImGui.GetStyle().ItemInnerSpacing.x)
|
|
ImGui.Text("Progress Bar")
|
|
ImGui.ProgressBar(progress, ImVec2(0.0, 0.0), string.format("%d/%d", math.floor(progress * 1753), 1753))
|
|
ImGui.ProgressBar(-1.0 * ImGui.GetTime(), ImVec2(0.0, 0.0), "Searching..")
|
|
ImGui.SameLine(0.0, ImGui.GetStyle().ItemInnerSpacing.x)
|
|
ImGui.Text("Indeterminate")
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
-- Selectable(label, bool* p_selected) overload: toggles on press
|
|
local function SelectableP(label, sel, flags, size)
|
|
local pressed = ImGui.Selectable(label, sel, flags, size)
|
|
if pressed then sel = not sel end
|
|
return pressed, sel
|
|
end
|
|
|
|
local function B(v) return v and 1 or 0 end
|
|
|
|
S.qs = { item_type = 4, item_disabled = false, item_mixedvalue = false, liveedit_override = false, liveedit_flags = 0,
|
|
b = false, col4f = { 1.0, 0.5, 0.0, 1.0 }, str = Buf("", 16), combo = 1, listbox = 1, unused = Buf("", 1),
|
|
embed = false, test_window = false }
|
|
function DemoWindowWidgetsQueryingStatuses()
|
|
local s = S.qs
|
|
if ImGui.TreeNode("Querying Item Status (Edited/Active/Hovered etc.)") then
|
|
local item_names = { "Text", "Button", "Button (w/ repeat)", "Checkbox", "SliderFloat", "InputText", "InputTextMultiline", "InputFloat",
|
|
"InputFloat3", "ColorEdit4", "Selectable", "MenuItem", "TreeNode", "TreeNode (w/ double-click)", "Combo", "ListBox" }
|
|
s.item_type = ImGui.Combo("Item Type", s.item_type, item_names, #item_names, #item_names)
|
|
ImGui.SameLine()
|
|
HelpMarker("Testing how various types of items are interacting with the IsItemXXX functions. Note that the bool return value of most ImGui function is generally equivalent to calling ImGui::IsItemHovered().")
|
|
_, s.item_disabled = ImGui.Checkbox("Item Disabled", s.item_disabled)
|
|
_, s.item_mixedvalue = ImGui.Checkbox("Item MixedValue", s.item_mixedvalue)
|
|
_, s.liveedit_override = ImGui.Checkbox("Override LiveEdit:", s.liveedit_override)
|
|
ImGui.SameLine()
|
|
if not s.liveedit_override then s.liveedit_flags = ImGui.GetItemFlags() end
|
|
ImGui.BeginDisabled(s.liveedit_override == false)
|
|
_, s.liveedit_flags = ImGui.CheckboxFlags("_LiveEditOnInput", s.liveedit_flags, ImGuiItemFlags.LiveEditOnInput)
|
|
ImGui.SameLine()
|
|
_, s.liveedit_flags = ImGui.CheckboxFlags("_LiveEditOnInputText", s.liveedit_flags, ImGuiItemFlags.LiveEditOnInputText)
|
|
ImGui.SameLine()
|
|
_, s.liveedit_flags = ImGui.CheckboxFlags("_LiveEditOnInputScalar", s.liveedit_flags, ImGuiItemFlags.LiveEditOnInputScalar)
|
|
ImGui.EndDisabled()
|
|
if s.liveedit_override then
|
|
ImGui.PushItemFlag(ImGuiItemFlags.LiveEditOnInputText, bit32.band(s.liveedit_flags, ImGuiItemFlags.LiveEditOnInputText) ~= 0)
|
|
ImGui.PushItemFlag(ImGuiItemFlags.LiveEditOnInputScalar, bit32.band(s.liveedit_flags, ImGuiItemFlags.LiveEditOnInputScalar) ~= 0)
|
|
end
|
|
|
|
local ret = false
|
|
local t = s.item_type
|
|
if s.item_disabled then ImGui.BeginDisabled(true) end
|
|
if s.item_mixedvalue then ImGui.PushItemFlag(ImGuiItemFlags.MixedValue, true) end
|
|
if t == 0 then ImGui.Text("ITEM: Text") end
|
|
if t == 1 then ret = ImGui.Button("ITEM: Button") end
|
|
if t == 2 then ImGui.PushItemFlag(ImGuiItemFlags.ButtonRepeat, true); ret = ImGui.Button("ITEM: Button"); ImGui.PopItemFlag() end
|
|
if t == 3 then ret, s.b = ImGui.Checkbox("ITEM: Checkbox", s.b) end
|
|
if t == 4 then s.col4f[1], ret = ImGui.SliderFloat("ITEM: SliderFloat", s.col4f[1], 0.0, 1.0) end
|
|
if t == 5 then ret = ImGui.InputText("ITEM: InputText", s.str, 16) end
|
|
if t == 6 then ret = ImGui.InputTextMultiline("ITEM: InputTextMultiline", s.str, 16) end
|
|
if t == 7 then s.col4f[1], ret = ImGui.InputFloat("ITEM: InputFloat", s.col4f[1], 1.0) end
|
|
if t == 8 then ret = ImGui.InputFloat3("ITEM: InputFloat3", s.col4f) end
|
|
if t == 9 then ret = ImGui.ColorEdit4("ITEM: ColorEdit4", s.col4f) end
|
|
if t == 10 then ret = ImGui.Selectable("ITEM: Selectable") end
|
|
if t == 11 then ret = ImGui.MenuItem("ITEM: MenuItem") end
|
|
if t == 12 then ret = ImGui.TreeNode("ITEM: TreeNode"); if ret then ImGui.TreePop() end end
|
|
if t == 13 then ret = ImGui.TreeNodeEx("ITEM: TreeNode w/ ImGuiTreeNodeFlags_OpenOnDoubleClick", bit32.bor(ImGuiTreeNodeFlags.OpenOnDoubleClick, ImGuiTreeNodeFlags.NoTreePushOnOpen)) end
|
|
if t == 14 then s.combo, ret = ImGui.Combo("ITEM: Combo", s.combo, { "Apple", "Banana", "Cherry", "Kiwi" }) end
|
|
if t == 15 then s.listbox, ret = ImGui.ListBox("ITEM: ListBox", s.listbox, { "Apple", "Banana", "Cherry", "Kiwi" }, 4, 4) end
|
|
|
|
local HF = ImGuiHoveredFlags
|
|
local hovered_delay_none = ImGui.IsItemHovered()
|
|
local hovered_delay_stationary = ImGui.IsItemHovered(HF.Stationary)
|
|
local hovered_delay_short = ImGui.IsItemHovered(HF.DelayShort)
|
|
local hovered_delay_normal = ImGui.IsItemHovered(HF.DelayNormal)
|
|
local hovered_delay_tooltip = ImGui.IsItemHovered(HF.ForTooltip)
|
|
local rmin, rmax, rsize = ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), ImGui.GetItemRectSize()
|
|
ImGui.BulletText(
|
|
"Return value = %d\nIsItemFocused() = %d\nIsItemHovered() = %d\nIsItemHovered(_AllowWhenBlockedByPopup) = %d\n" ..
|
|
"IsItemHovered(_AllowWhenBlockedByActiveItem) = %d\nIsItemHovered(_AllowWhenOverlappedByItem) = %d\n" ..
|
|
"IsItemHovered(_AllowWhenOverlappedByWindow) = %d\nIsItemHovered(_AllowWhenDisabled) = %d\nIsItemHovered(_RectOnly) = %d\n" ..
|
|
"IsItemActive() = %d\nIsItemEdited() = %d\nIsItemActivated() = %d\nIsItemDeactivated() = %d\nIsItemDeactivatedAfterEdit() = %d\n" ..
|
|
"IsItemVisible() = %d\nIsItemClicked() = %d\nIsItemToggledOpen() = %d\n" ..
|
|
"GetItemRectMin() = (%.1f, %.1f)\nGetItemRectMax() = (%.1f, %.1f)\nGetItemRectSize() = (%.1f, %.1f)",
|
|
B(ret), B(ImGui.IsItemFocused()), B(ImGui.IsItemHovered()), B(ImGui.IsItemHovered(HF.AllowWhenBlockedByPopup)),
|
|
B(ImGui.IsItemHovered(HF.AllowWhenBlockedByActiveItem)), B(ImGui.IsItemHovered(HF.AllowWhenOverlappedByItem)),
|
|
B(ImGui.IsItemHovered(HF.AllowWhenOverlappedByWindow)), B(ImGui.IsItemHovered(HF.AllowWhenDisabled)), B(ImGui.IsItemHovered(HF.RectOnly)),
|
|
B(ImGui.IsItemActive()), B(ImGui.IsItemEdited()), B(ImGui.IsItemActivated()), B(ImGui.IsItemDeactivated()), B(ImGui.IsItemDeactivatedAfterEdit()),
|
|
B(ImGui.IsItemVisible()), B(ImGui.IsItemClicked()), B(ImGui.IsItemToggledOpen()),
|
|
rmin.x, rmin.y, rmax.x, rmax.y, rsize.x, rsize.y)
|
|
ImGui.BulletText(
|
|
"with Hovering Delay or Stationary test:\nIsItemHovered() = %d\nIsItemHovered(_Stationary) = %d\nIsItemHovered(_DelayShort) = %d\nIsItemHovered(_DelayNormal) = %d\nIsItemHovered(_Tooltip) = %d",
|
|
B(hovered_delay_none), B(hovered_delay_stationary), B(hovered_delay_short), B(hovered_delay_normal), B(hovered_delay_tooltip))
|
|
|
|
if s.liveedit_override then ImGui.PopItemFlag(); ImGui.PopItemFlag() end
|
|
if s.item_mixedvalue then ImGui.PopItemFlag() end
|
|
if s.item_disabled then ImGui.EndDisabled() end
|
|
|
|
ImGui.InputText("unused", s.unused, 1, ImGuiInputTextFlags.ReadOnly)
|
|
ImGui.SameLine()
|
|
HelpMarker("This widget is only here to be able to tab-out of the widgets above and see e.g. Deactivated() status.")
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Querying Window Status (Focused/Hovered etc.)") then
|
|
_, s.embed = ImGui.Checkbox("Embed everything inside a child window for testing _RootWindow flag.", s.embed)
|
|
if s.embed then ImGui.BeginChild("outer_child", ImVec2(0, ImGui.GetFontSize() * 20.0), ImGuiChildFlags.Borders) end
|
|
local FF, HF = ImGuiFocusedFlags, ImGuiHoveredFlags
|
|
local bor = bit32.bor
|
|
ImGui.BulletText(
|
|
"IsWindowFocused() = %d\nIsWindowFocused(_ChildWindows) = %d\nIsWindowFocused(_ChildWindows|_NoPopupHierarchy) = %d\n" ..
|
|
"IsWindowFocused(_ChildWindows|_DockHierarchy) = %d\nIsWindowFocused(_ChildWindows|_RootWindow) = %d\n" ..
|
|
"IsWindowFocused(_ChildWindows|_RootWindow|_NoPopupHierarchy) = %d\nIsWindowFocused(_ChildWindows|_RootWindow|_DockHierarchy) = %d\n" ..
|
|
"IsWindowFocused(_RootWindow) = %d\nIsWindowFocused(_RootWindow|_NoPopupHierarchy) = %d\nIsWindowFocused(_RootWindow|_DockHierarchy) = %d\n" ..
|
|
"IsWindowFocused(_AnyWindow) = %d\n",
|
|
B(ImGui.IsWindowFocused()), B(ImGui.IsWindowFocused(FF.ChildWindows)), B(ImGui.IsWindowFocused(bor(FF.ChildWindows, FF.NoPopupHierarchy))),
|
|
B(ImGui.IsWindowFocused(bor(FF.ChildWindows, FF.DockHierarchy))), B(ImGui.IsWindowFocused(bor(FF.ChildWindows, FF.RootWindow))),
|
|
B(ImGui.IsWindowFocused(bor(FF.ChildWindows, FF.RootWindow, FF.NoPopupHierarchy))), B(ImGui.IsWindowFocused(bor(FF.ChildWindows, FF.RootWindow, FF.DockHierarchy))),
|
|
B(ImGui.IsWindowFocused(FF.RootWindow)), B(ImGui.IsWindowFocused(bor(FF.RootWindow, FF.NoPopupHierarchy))), B(ImGui.IsWindowFocused(bor(FF.RootWindow, FF.DockHierarchy))),
|
|
B(ImGui.IsWindowFocused(FF.AnyWindow)))
|
|
ImGui.BulletText(
|
|
"IsWindowHovered() = %d\nIsWindowHovered(_AllowWhenBlockedByPopup) = %d\nIsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n" ..
|
|
"IsWindowHovered(_ChildWindows) = %d\nIsWindowHovered(_ChildWindows|_NoPopupHierarchy) = %d\nIsWindowHovered(_ChildWindows|_DockHierarchy) = %d\n" ..
|
|
"IsWindowHovered(_ChildWindows|_RootWindow) = %d\nIsWindowHovered(_ChildWindows|_RootWindow|_NoPopupHierarchy) = %d\n" ..
|
|
"IsWindowHovered(_ChildWindows|_RootWindow|_DockHierarchy) = %d\nIsWindowHovered(_RootWindow) = %d\nIsWindowHovered(_RootWindow|_NoPopupHierarchy) = %d\n" ..
|
|
"IsWindowHovered(_RootWindow|_DockHierarchy) = %d\nIsWindowHovered(_ChildWindows|_AllowWhenBlockedByPopup) = %d\nIsWindowHovered(_AnyWindow) = %d\n" ..
|
|
"IsWindowHovered(_Stationary) = %d\n",
|
|
B(ImGui.IsWindowHovered()), B(ImGui.IsWindowHovered(HF.AllowWhenBlockedByPopup)), B(ImGui.IsWindowHovered(HF.AllowWhenBlockedByActiveItem)),
|
|
B(ImGui.IsWindowHovered(HF.ChildWindows)), B(ImGui.IsWindowHovered(bor(HF.ChildWindows, HF.NoPopupHierarchy))), B(ImGui.IsWindowHovered(bor(HF.ChildWindows, HF.DockHierarchy))),
|
|
B(ImGui.IsWindowHovered(bor(HF.ChildWindows, HF.RootWindow))), B(ImGui.IsWindowHovered(bor(HF.ChildWindows, HF.RootWindow, HF.NoPopupHierarchy))),
|
|
B(ImGui.IsWindowHovered(bor(HF.ChildWindows, HF.RootWindow, HF.DockHierarchy))), B(ImGui.IsWindowHovered(HF.RootWindow)), B(ImGui.IsWindowHovered(bor(HF.RootWindow, HF.NoPopupHierarchy))),
|
|
B(ImGui.IsWindowHovered(bor(HF.RootWindow, HF.DockHierarchy))), B(ImGui.IsWindowHovered(bor(HF.ChildWindows, HF.AllowWhenBlockedByPopup))), B(ImGui.IsWindowHovered(HF.AnyWindow)),
|
|
B(ImGui.IsWindowHovered(HF.Stationary)))
|
|
ImGui.BeginChild("child", ImVec2(0, 50), ImGuiChildFlags.Borders)
|
|
ImGui.Text("This is another child window for testing the _ChildWindows flag.")
|
|
ImGui.EndChild()
|
|
if s.embed then ImGui.EndChild() end
|
|
|
|
_, s.test_window = ImGui.Checkbox("Hovered/Active tests after Begin() for title bar testing", s.test_window)
|
|
if s.test_window then
|
|
s.test_window = ImGui.Begin("Title bar Hovered/Active tests", s.test_window)
|
|
if ImGui.BeginPopupContextItem() then
|
|
if ImGui.MenuItem("Close") then s.test_window = false end
|
|
ImGui.EndPopup()
|
|
end
|
|
ImGui.Text("IsItemHovered() after begin = %d (== is title bar hovered)\nIsItemActive() after begin = %d (== is window being clicked/moved)\n",
|
|
B(ImGui.IsItemHovered()), B(ImGui.IsItemActive()))
|
|
ImGui.End()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
end
|
|
|
|
S.sel = { basic = { false, true, false, false }, multi = { false, false, false }, checked = { false, false, false, false, false }, selected_n = 0,
|
|
tables = {}, grid = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } },
|
|
align = { true, false, true, false, true, false, true, false, true } }
|
|
for i = 1, 10 do S.sel.tables[i] = false end
|
|
function DemoWindowWidgetsSelectables()
|
|
if not ImGui.TreeNode("Selectables") then return end
|
|
local s = S.sel
|
|
if ImGui.TreeNode("Basic") then
|
|
local b = s.basic
|
|
_, b[1] = SelectableP("1. I am selectable", b[1])
|
|
_, b[2] = SelectableP("2. I am selectable", b[2])
|
|
_, b[3] = SelectableP("3. I am selectable", b[3])
|
|
if ImGui.Selectable("4. I am double clickable", b[4], ImGuiSelectableFlags.AllowDoubleClick) then
|
|
if ImGui.IsMouseDoubleClicked(0) then b[4] = not b[4] end
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Multiple items on the same line") then
|
|
local m = s.multi
|
|
ImGui.SetNextItemAllowOverlap(); _, m[1] = SelectableP("main.c", m[1]); ImGui.SameLine(); ImGui.SmallButton("Link 1")
|
|
ImGui.SetNextItemAllowOverlap(); _, m[2] = SelectableP("hello.cpp", m[2]); ImGui.SameLine(); ImGui.SmallButton("Link 2")
|
|
ImGui.SetNextItemAllowOverlap(); _, m[3] = SelectableP("hello.h", m[3]); ImGui.SameLine(); ImGui.SmallButton("Link 3")
|
|
ImGui.Spacing()
|
|
local color_marker_w = ImGui.CalcTextSize("x").x
|
|
for n = 0, 4 do
|
|
ImGui.PushID(n)
|
|
ImGui.AlignTextToFramePadding()
|
|
if ImGui.Selectable("##selectable", s.selected_n == n, ImGuiSelectableFlags.AllowOverlap) then s.selected_n = n end
|
|
ImGui.SameLine(0, 0)
|
|
_, s.checked[n + 1] = ImGui.Checkbox("##check", s.checked[n + 1])
|
|
ImGui.SameLine()
|
|
local color = ImVec4((n % 2 == 1) and 1.0 or 0.2, (math.floor(n / 2) % 2 == 1) and 1.0 or 0.2, 0.2, 1.0)
|
|
ImGui.ColorButton("##color", color, ImGuiColorEditFlags.NoTooltip, ImVec2(color_marker_w, 0))
|
|
ImGui.SameLine()
|
|
ImGui.Text("Some label")
|
|
ImGui.PopID()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("In Tables") then
|
|
local sel = s.tables
|
|
local TF = ImGuiTableFlags
|
|
if ImGui.BeginTable("split1", 3, bit32.bor(TF.Resizable, TF.NoSavedSettings, TF.Borders)) then
|
|
for i = 0, 9 do
|
|
ImGui.TableNextColumn()
|
|
_, sel[i + 1] = SelectableP(string.format("Item %d", i), sel[i + 1])
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
ImGui.Spacing()
|
|
if ImGui.BeginTable("split2", 3, bit32.bor(TF.Resizable, TF.NoSavedSettings, TF.Borders)) then
|
|
for i = 0, 9 do
|
|
ImGui.TableNextRow()
|
|
ImGui.TableNextColumn()
|
|
_, sel[i + 1] = SelectableP(string.format("Item %d", i), sel[i + 1], ImGuiSelectableFlags.SpanAllColumns)
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("Some other contents")
|
|
ImGui.TableNextColumn()
|
|
ImGui.Text("123456")
|
|
end
|
|
ImGui.EndTable()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Grid") then
|
|
local g = s.grid
|
|
local time = ImGui.GetTime()
|
|
local winning_state = true
|
|
for y = 1, 4 do for x = 1, 4 do if g[y][x] == 0 then winning_state = false end end end
|
|
if winning_state then
|
|
ImGui.PushStyleVar(ImGuiStyleVar.SelectableTextAlign, ImVec2(0.5 + 0.5 * math.cos(time * 2.0), 0.5 + 0.5 * math.sin(time * 3.0)))
|
|
end
|
|
local size = ImGui.CalcTextSize("Sailor").x
|
|
for y = 1, 4 do
|
|
for x = 1, 4 do
|
|
if x > 1 then ImGui.SameLine() end
|
|
ImGui.PushID((y - 1) * 4 + (x - 1))
|
|
if ImGui.Selectable("Sailor", g[y][x] ~= 0, 0, ImVec2(size, size)) then
|
|
g[y][x] = 1 - g[y][x]
|
|
if x > 1 then g[y][x - 1] = 1 - g[y][x - 1] end
|
|
if x < 4 then g[y][x + 1] = 1 - g[y][x + 1] end
|
|
if y > 1 then g[y - 1][x] = 1 - g[y - 1][x] end
|
|
if y < 4 then g[y + 1][x] = 1 - g[y + 1][x] end
|
|
end
|
|
ImGui.PopID()
|
|
end
|
|
end
|
|
if winning_state then ImGui.PopStyleVar() end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Alignment") then
|
|
HelpMarker("By default, Selectables uses style.SelectableTextAlign but it can be overridden on a per-item basis using PushStyleVar(). You'll probably want to always keep your default situation to left-align otherwise it becomes difficult to layout multiple items on a same line")
|
|
local size = ImGui.CalcTextSize("(1.0,1.0)").x
|
|
for y = 0, 2 do
|
|
for x = 0, 2 do
|
|
local alignment = ImVec2(x / 2.0, y / 2.0)
|
|
local name = string.format("(%.1f,%.1f)", alignment.x, alignment.y)
|
|
if x > 0 then ImGui.SameLine() end
|
|
ImGui.PushStyleVar(ImGuiStyleVar.SelectableTextAlign, alignment)
|
|
_, s.align[3 * y + x + 1] = SelectableP(name, s.align[3 * y + x + 1], ImGuiSelectableFlags.None, ImVec2(size, size))
|
|
ImGui.PopStyleVar()
|
|
end
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
local function EditTabBarFittingPolicyFlags(flags)
|
|
local TB = ImGuiTabBarFlags
|
|
if bit32.band(flags, TB.FittingPolicyMask_) == 0 then flags = bit32.bor(flags, TB.FittingPolicyDefault_) end
|
|
for _, n in ipairs({ "FittingPolicyMixed", "FittingPolicyShrink", "FittingPolicyScroll" }) do
|
|
local p
|
|
p, flags = ImGui.CheckboxFlags("ImGuiTabBarFlags_" .. n, flags, TB[n])
|
|
if p then flags = bit32.band(flags, bit32.bnot(bit32.bxor(TB.FittingPolicyMask_, TB[n]))) end
|
|
end
|
|
return flags
|
|
end
|
|
|
|
S.tabs = { adv_flags = ImGuiTabBarFlags.Reorderable, opened = { true, true, true, true }, active_tabs = {}, next_tab_id = 0,
|
|
show_leading = true, show_trailing = true, show_lt_tabs = false,
|
|
tib_flags = bit32.bor(ImGuiTabBarFlags.AutoSelectNewTabs, ImGuiTabBarFlags.Reorderable, ImGuiTabBarFlags.FittingPolicyMixed) }
|
|
function DemoWindowWidgetsTabs()
|
|
if not ImGui.TreeNode("Tabs") then return end
|
|
local s = S.tabs
|
|
local TB, TI = ImGuiTabBarFlags, ImGuiTabItemFlags
|
|
if ImGui.TreeNode("Basic") then
|
|
if ImGui.BeginTabBar("MyTabBar", TB.None) then
|
|
if ImGui.BeginTabItem("Avocado") then ImGui.Text("This is the Avocado tab!\nblah blah blah blah blah"); ImGui.EndTabItem() end
|
|
if ImGui.BeginTabItem("Broccoli") then ImGui.Text("This is the Broccoli tab!\nblah blah blah blah blah"); ImGui.EndTabItem() end
|
|
if ImGui.BeginTabItem("Cucumber") then ImGui.Text("This is the Cucumber tab!\nblah blah blah blah blah"); ImGui.EndTabItem() end
|
|
ImGui.EndTabBar()
|
|
end
|
|
ImGui.Separator()
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Advanced & Close Button") then
|
|
for _, n in ipairs({ "Reorderable", "AutoSelectNewTabs", "TabListPopupButton", "NoCloseWithMiddleMouseButton", "DrawSelectedOverline" }) do
|
|
_, s.adv_flags = ImGui.CheckboxFlags("ImGuiTabBarFlags_" .. n, s.adv_flags, TB[n])
|
|
end
|
|
s.adv_flags = EditTabBarFittingPolicyFlags(s.adv_flags)
|
|
ImGui.AlignTextToFramePadding()
|
|
ImGui.Text("Opened:")
|
|
local names = { "Artichoke", "Beetroot", "Celery", "Daikon" }
|
|
for n = 1, 4 do
|
|
ImGui.SameLine()
|
|
_, s.opened[n] = ImGui.Checkbox(names[n], s.opened[n])
|
|
end
|
|
if ImGui.BeginTabBar("MyTabBar", s.adv_flags) then
|
|
for n = 1, 4 do
|
|
if s.opened[n] then
|
|
local visible
|
|
visible, s.opened[n] = ImGui.BeginTabItem(names[n], s.opened[n], TI.None)
|
|
if visible then
|
|
ImGui.Text("This is the %s tab!", names[n])
|
|
if (n - 1) % 2 == 1 then ImGui.Text("I am an odd tab.") end
|
|
ImGui.EndTabItem()
|
|
end
|
|
end
|
|
end
|
|
ImGui.EndTabBar()
|
|
end
|
|
ImGui.Separator()
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("TabItemButton & Leading/Trailing flags") then
|
|
if s.next_tab_id == 0 then
|
|
for _ = 1, 3 do s.active_tabs[#s.active_tabs + 1] = s.next_tab_id; s.next_tab_id = s.next_tab_id + 1 end
|
|
end
|
|
_, s.show_leading = ImGui.Checkbox("Show Leading TabItemButton()", s.show_leading)
|
|
_, s.show_trailing = ImGui.Checkbox("Show Trailing TabItemButton()", s.show_trailing)
|
|
_, s.show_lt_tabs = ImGui.Checkbox("Show Leading+Trailing TabItem()", s.show_lt_tabs)
|
|
s.tib_flags = EditTabBarFittingPolicyFlags(s.tib_flags)
|
|
if ImGui.BeginTabBar("MyTabBar", s.tib_flags) then
|
|
if s.show_leading then
|
|
if ImGui.TabItemButton("?", bit32.bor(TI.Leading, TI.NoTooltip)) then ImGui.OpenPopup("MyHelpMenu") end
|
|
end
|
|
if ImGui.BeginPopup("MyHelpMenu") then
|
|
ImGui.Selectable("Hello!")
|
|
ImGui.EndPopup()
|
|
end
|
|
if s.show_lt_tabs then
|
|
if ImGui.BeginTabItem("Leading", nil, TI.Leading) then ImGui.EndTabItem() end
|
|
if ImGui.BeginTabItem("Trailing", nil, TI.Trailing) then ImGui.EndTabItem() end
|
|
end
|
|
if s.show_trailing then
|
|
if ImGui.TabItemButton("+", bit32.bor(TI.Trailing, TI.NoTooltip)) then
|
|
s.active_tabs[#s.active_tabs + 1] = s.next_tab_id; s.next_tab_id = s.next_tab_id + 1
|
|
end
|
|
end
|
|
local n = 1
|
|
while n <= #s.active_tabs do
|
|
local name = string.format("%04d", s.active_tabs[n])
|
|
local visible, open = ImGui.BeginTabItem(name, true, TI.None)
|
|
if visible then
|
|
ImGui.Text("This is the %s tab!", name)
|
|
ImGui.EndTabItem()
|
|
end
|
|
if open == false then table.remove(s.active_tabs, n) else n = n + 1 end
|
|
end
|
|
ImGui.EndTabBar()
|
|
end
|
|
ImGui.Separator()
|
|
ImGui.TreePop()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.text = { custom_size = 16.0, custom_scale = 1.0, wrap_width = 200.0, utf8 = Buf("\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e", 32) }
|
|
function DemoWindowWidgetsText()
|
|
if not ImGui.TreeNode("Text") then return end
|
|
local s = S.text
|
|
if ImGui.TreeNode("Colorful Text") then
|
|
ImGui.TextColored(ImVec4(1.0, 0.0, 1.0, 1.0), "Pink")
|
|
ImGui.TextColored(ImVec4(1.0, 1.0, 0.0, 1.0), "Yellow")
|
|
ImGui.TextDisabled("Disabled")
|
|
ImGui.SameLine(); HelpMarker("The TextDisabled color is stored in ImGuiStyle.")
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Font Size") then
|
|
local style = ImGui.GetStyle()
|
|
local global_scale = style.FontScaleMain * style.FontScaleDpi
|
|
ImGui.Text("style.FontScaleMain = %0.2f", style.FontScaleMain)
|
|
ImGui.Text("style.FontScaleDpi = %0.2f", style.FontScaleDpi)
|
|
ImGui.Text("global_scale = ~%0.2f", global_scale)
|
|
ImGui.Text("FontSize = %0.2f", ImGui.GetFontSize())
|
|
ImGui.SeparatorText("")
|
|
s.custom_size = ImGui.SliderFloat("custom_size", s.custom_size, 10.0, 100.0, "%.0f")
|
|
ImGui.Text("ImGui::PushFont(nullptr, custom_size);")
|
|
ImGui.PushFont(nil, s.custom_size)
|
|
ImGui.Text("FontSize = %.2f (== %.2f * global_scale)", ImGui.GetFontSize(), s.custom_size)
|
|
ImGui.PopFont()
|
|
ImGui.SeparatorText("")
|
|
s.custom_scale = ImGui.SliderFloat("custom_scale", s.custom_scale, 0.5, 4.0, "%.2f")
|
|
ImGui.Text("ImGui::PushFont(nullptr, style.FontSizeBase * custom_scale);")
|
|
ImGui.PushFont(nil, style.FontSizeBase * s.custom_scale)
|
|
ImGui.Text("FontSize = %.2f (== style.FontSizeBase * %.2f * global_scale)", ImGui.GetFontSize(), s.custom_scale)
|
|
ImGui.PopFont()
|
|
ImGui.SeparatorText("")
|
|
local scaling = 0.5
|
|
while scaling <= 4.0 do
|
|
ImGui.PushFont(nil, style.FontSizeBase * scaling)
|
|
ImGui.Text("FontSize = %.2f (== style.FontSizeBase * %.2f * global_scale)", ImGui.GetFontSize(), scaling)
|
|
ImGui.PopFont()
|
|
scaling = scaling + 0.5
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Word Wrapping") then
|
|
ImGui.TextWrapped("This text should automatically wrap on the edge of the window. The current implementation for text wrapping follows simple rules suitable for English and possibly other languages.")
|
|
ImGui.Spacing()
|
|
s.wrap_width = ImGui.SliderFloat("Wrap width", s.wrap_width, -20, 600, "%.0f")
|
|
local draw_list = ImGui.GetWindowDrawList()
|
|
for n = 0, 1 do
|
|
ImGui.Text("Test paragraph %d:", n)
|
|
local pos = ImGui.GetCursorScreenPos()
|
|
local marker_min = ImVec2(pos.x + s.wrap_width, pos.y)
|
|
local marker_max = ImVec2(pos.x + s.wrap_width + 10, pos.y + ImGui.GetTextLineHeight())
|
|
ImGui.PushTextWrapPos(ImGui.GetCursorPos().x + s.wrap_width)
|
|
if n == 0 then
|
|
ImGui.Text("The lazy dog is a good dog. This paragraph should fit within %.0f pixels. Testing a 1 character word. The quick brown fox jumps over the lazy dog.", s.wrap_width)
|
|
else
|
|
ImGui.Text("aaaaaaaa bbbbbbbb, c cccccccc,dddddddd. d eeeeeeee ffffffff. gggggggg!hhhhhhhh")
|
|
end
|
|
draw_list:AddRect(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), IM_COL32(255, 255, 0, 255))
|
|
draw_list:AddRectFilled(marker_min, marker_max, IM_COL32(255, 0, 255, 255))
|
|
ImGui.PopTextWrapPos()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("UTF-8 Text") then
|
|
ImGui.TextWrapped("CJK text will only appear if the font was loaded with the appropriate CJK character ranges. Call io.Fonts->AddFontFromFileTTF() manually to load extra character ranges. Read docs/FONTS.md for details.")
|
|
ImGui.Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)")
|
|
ImGui.Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)")
|
|
ImGui.InputText("UTF-8 input", s.utf8, 32)
|
|
ImGui.TreePop()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.tf = { filter = nil }
|
|
function DemoWindowWidgetsTextFilter()
|
|
if not ImGui.TreeNode("Text Filter") then return end
|
|
S.tf.filter = S.tf.filter or ImGuiTextFilter()
|
|
local filter = S.tf.filter
|
|
HelpMarker("Not a widget per-se, but ImGuiTextFilter is a helper to perform simple filtering on text strings.")
|
|
ImGui.Text("Filter usage:\n \"\" display all lines\n xxx display lines containing \"xxx\"\n xxx yyy display lines containing \"xxx\" and \"yyy\"\n \"xxx yyy\" display lines containing \"xxx yyy\"\n xxx,yyy display lines containing \"xxx\" or \"yyy\"\n -xxx hide lines containing \"xxx\"")
|
|
ImGui.SetNextItemWidth(-FLT_MIN)
|
|
filter:DrawWithHint("##Filter", "Filter (incl -excl)")
|
|
if ImGui.BeginChild("##items", ImVec2(-FLT_MIN, ImGui.GetTextLineHeightWithSpacing() * 15), ImGuiChildFlags.FrameStyle) then
|
|
for _, item in ipairs({ "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" }) do
|
|
if filter:PassFilter(item) then ImGui.TextUnformatted(item) end
|
|
end
|
|
for _, item in ipairs(ExampleNames) do
|
|
if filter:PassFilter(item) then ImGui.TextUnformatted(item) end
|
|
end
|
|
end
|
|
ImGui.EndChild()
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.ti = {
|
|
text = Buf("/*\n The Pentium F00F bug, shorthand for F0 0F C7 C8,\n the hexadecimal encoding of one offending instruction,\n more formally, the invalid operand with locked CMPXCHG8B\n instruction bug, is a design flaw in the majority of\n Intel Pentium, Pentium MMX, and Pentium OverDrive\n processors (all in the P5 microarchitecture).\n*/\n\nlabel:\n\tlock cmpxchg8b eax\n", 1024 * 16),
|
|
ml_flags = ImGuiInputTextFlags.AllowTabInput,
|
|
f = { Buf("", 32), Buf("", 32), Buf("", 32), Buf("", 32), Buf("", 32), Buf("", 32), Buf("", 32) },
|
|
password = Buf("password123", 64), cb1 = Buf("", 64), cb2 = Buf("", 64), cb3 = Buf("", 64), edit_count = { 0 },
|
|
rs_flags = 0, rs = Buf("", 1024),
|
|
elide = Buf("/path/to/some/folder/with/long/filename.cpp", 128), elide_flags = ImGuiInputTextFlags.ElideLeft,
|
|
misc = Buf("", 16), misc_flags = ImGuiInputTextFlags.EscapeClearsAll }
|
|
function DemoWindowWidgetsTextInput()
|
|
if not ImGui.TreeNode("Text Input") then return end
|
|
local s = S.ti
|
|
local IT = ImGuiInputTextFlags
|
|
local function FlagBox(key, name)
|
|
if IT[name] then _, s[key] = ImGui.CheckboxFlags("ImGuiInputTextFlags_" .. name, s[key], IT[name]) end
|
|
end
|
|
if ImGui.TreeNode("Multi-line Text Input") then
|
|
HelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type.")
|
|
FlagBox("ml_flags", "ReadOnly")
|
|
FlagBox("ml_flags", "WordWrap")
|
|
ImGui.SameLine(); HelpMarker("Feature is currently in Beta. Please read comments in imgui.h")
|
|
FlagBox("ml_flags", "AllowTabInput")
|
|
ImGui.SameLine(); HelpMarker("When _AllowTabInput is set, passing through the widget with Tabbing doesn't automatically activate it, in order to also cycling through subsequent widgets.")
|
|
FlagBox("ml_flags", "CtrlEnterForNewLine")
|
|
ImGui.InputTextMultiline("##source", s.text, 1024 * 16, ImVec2(-FLT_MIN, ImGui.GetTextLineHeight() * 16), s.ml_flags)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Filtered Text Input") then
|
|
local a, z, A, Z = string.byte("a"), string.byte("z"), string.byte("A"), string.byte("Z")
|
|
local function FilterCasingSwap(data)
|
|
local c = data.EventChar
|
|
if c >= a and c <= z then data.EventChar = c - (a - A)
|
|
elseif c >= A and c <= Z then data.EventChar = c + (a - A) end
|
|
return 0
|
|
end
|
|
local function FilterImGuiLetters(data)
|
|
local c = data.EventChar
|
|
if c < 256 and string.find("imgui", string.char(c), 1, true) then return 0 end
|
|
return 1
|
|
end
|
|
local f = s.f
|
|
ImGui.InputText("default", f[1], 32)
|
|
ImGui.InputText("decimal", f[2], 32, IT.CharsDecimal)
|
|
ImGui.InputText("hexadecimal", f[3], 32, bit32.bor(IT.CharsHexadecimal, IT.CharsUppercase))
|
|
ImGui.InputText("uppercase", f[4], 32, IT.CharsUppercase)
|
|
ImGui.InputText("no blank", f[5], 32, IT.CharsNoBlank)
|
|
ImGui.InputText("casing swap", f[6], 32, IT.CallbackCharFilter, FilterCasingSwap)
|
|
ImGui.InputText("\"imgui\"", f[7], 32, IT.CallbackCharFilter, FilterImGuiLetters)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Password Input") then
|
|
ImGui.InputText("password", s.password, 64, IT.Password)
|
|
ImGui.SameLine(); HelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n")
|
|
ImGui.InputTextWithHint("password (w/ hint)", "<password>", s.password, 64, IT.Password)
|
|
ImGui.InputText("password (clear)", s.password, 64)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Completion, History, Edit Callbacks") then
|
|
local function MyCallback(data)
|
|
if data.EventFlag == IT.CallbackCompletion then
|
|
data:InsertChars(data.CursorPos, "..")
|
|
elseif data.EventFlag == IT.CallbackHistory then
|
|
if data.EventKey == ImGuiKey.UpArrow then
|
|
data:DeleteChars(0, data.BufTextLen)
|
|
data:InsertChars(0, "Pressed Up!")
|
|
data:SelectAll()
|
|
elseif data.EventKey == ImGuiKey.DownArrow then
|
|
data:DeleteChars(0, data.BufTextLen)
|
|
data:InsertChars(0, "Pressed Down!")
|
|
data:SelectAll()
|
|
end
|
|
elseif data.EventFlag == IT.CallbackEdit then
|
|
local c = data.Buf[1]
|
|
if (c >= 97 and c <= 122) or (c >= 65 and c <= 90) then data.Buf[1] = bit32.bxor(c, 32) end
|
|
data.BufDirty = true
|
|
local p_int = data.UserData
|
|
p_int[1] = p_int[1] + 1
|
|
end
|
|
return 0
|
|
end
|
|
ImGui.InputText("Completion", s.cb1, 64, IT.CallbackCompletion, MyCallback)
|
|
ImGui.SameLine(); HelpMarker("Here we append \"..\" each time Tab is pressed. See 'Examples>Console' for a more meaningful demonstration of using this callback.")
|
|
ImGui.InputText("History", s.cb2, 64, IT.CallbackHistory, MyCallback)
|
|
ImGui.SameLine(); HelpMarker("Here we replace and select text each time Up/Down are pressed. See 'Examples>Console' for a more meaningful demonstration of using this callback.")
|
|
ImGui.InputText("Edit", s.cb3, 64, IT.CallbackEdit, MyCallback, s.edit_count)
|
|
ImGui.SameLine(); HelpMarker("Here we toggle the casing of the first character on every edit + count edits.")
|
|
ImGui.SameLine(); ImGui.Text("(%d)", s.edit_count[1])
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Resize Callback") then
|
|
HelpMarker("Using ImGuiInputTextFlags_CallbackResize to wire your custom string type to InputText().\n\n(Lua port: fixed 1024 byte buffer, CallbackResize growth not supported)")
|
|
FlagBox("rs_flags", "WordWrap")
|
|
ImGui.InputTextMultiline("##MyStr", s.rs, 1024, ImVec2(-FLT_MIN, ImGui.GetTextLineHeight() * 16), s.rs_flags)
|
|
ImGui.Text("Size: %d\nCapacity: %d", #BufStr(s.rs) + 1, 1024)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Eliding, Alignment") then
|
|
FlagBox("elide_flags", "ElideLeft")
|
|
ImGui.InputText("Path", s.elide, 128, s.elide_flags)
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Miscellaneous") then
|
|
FlagBox("misc_flags", "EscapeClearsAll")
|
|
FlagBox("misc_flags", "ReadOnly")
|
|
FlagBox("misc_flags", "NoUndoRedo")
|
|
ImGui.InputText("Hello", s.misc, 16, s.misc_flags)
|
|
ImGui.TreePop()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.tt = { arr = { 0.6, 0.1, 1.0, 0.5, 0.92, 0.1, 0.2 }, always_on = 0 }
|
|
function DemoWindowWidgetsTooltips()
|
|
if not ImGui.TreeNode("Tooltips") then return end
|
|
local s = S.tt
|
|
local HF = ImGuiHoveredFlags
|
|
ImGui.SeparatorText("General")
|
|
HelpMarker("Tooltip are typically created by using a IsItemHovered() + SetTooltip() sequence.\n\nWe provide a helper SetItemTooltip() function to perform the two with standards flags.")
|
|
local sz = ImVec2(-FLT_MIN, 0.0)
|
|
ImGui.Button("Basic", sz)
|
|
ImGui.SetItemTooltip("I am a tooltip")
|
|
ImGui.Button("Fancy", sz)
|
|
if ImGui.BeginItemTooltip() then
|
|
ImGui.Text("I am a fancy tooltip")
|
|
ImGui.PlotLines("Curve", s.arr, nil, #s.arr)
|
|
ImGui.Text("Sin(time) = %f", math.sin(ImGui.GetTime()))
|
|
ImGui.EndTooltip()
|
|
end
|
|
|
|
ImGui.SeparatorText("Always On")
|
|
_, s.always_on = ImGui.RadioButton("Off", s.always_on, 0)
|
|
ImGui.SameLine()
|
|
_, s.always_on = ImGui.RadioButton("Always On (Simple)", s.always_on, 1)
|
|
ImGui.SameLine()
|
|
_, s.always_on = ImGui.RadioButton("Always On (Advanced)", s.always_on, 2)
|
|
if s.always_on == 1 then
|
|
ImGui.SetTooltip("I am following you around.")
|
|
elseif s.always_on == 2 and ImGui.BeginTooltip() then
|
|
ImGui.ProgressBar(math.sin(ImGui.GetTime()) * 0.5 + 0.5, ImVec2(ImGui.GetFontSize() * 25, 0.0))
|
|
ImGui.EndTooltip()
|
|
end
|
|
|
|
ImGui.SeparatorText("Custom")
|
|
HelpMarker("Passing ImGuiHoveredFlags_ForTooltip to IsItemHovered() is the preferred way to standardize tooltip activation details across your application. You may however decide to use custom flags for a specific tooltip instance.")
|
|
ImGui.Button("Manual", sz)
|
|
if ImGui.IsItemHovered(HF.ForTooltip) then ImGui.SetTooltip("I am a manually emitted tooltip.") end
|
|
ImGui.Button("DelayNone", sz)
|
|
if ImGui.IsItemHovered(HF.DelayNone) then ImGui.SetTooltip("I am a tooltip with no delay.") end
|
|
ImGui.Button("DelayShort", sz)
|
|
if ImGui.IsItemHovered(bit32.bor(HF.DelayShort, HF.NoSharedDelay)) then ImGui.SetTooltip("I am a tooltip with a short delay (%0.2f sec).", ImGui.GetStyle().HoverDelayShort) end
|
|
ImGui.Button("DelayLong", sz)
|
|
if ImGui.IsItemHovered(bit32.bor(HF.DelayNormal, HF.NoSharedDelay)) then ImGui.SetTooltip("I am a tooltip with a long delay (%0.2f sec).", ImGui.GetStyle().HoverDelayNormal) end
|
|
ImGui.Button("Stationary", sz)
|
|
if ImGui.IsItemHovered(HF.Stationary) then ImGui.SetTooltip("I am a tooltip requiring mouse to be stationary before activating.") end
|
|
ImGui.BeginDisabled()
|
|
ImGui.Button("Disabled item", sz)
|
|
if ImGui.IsItemHovered(HF.ForTooltip) then ImGui.SetTooltip("I am a tooltip for a disabled item.") end
|
|
ImGui.EndDisabled()
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.tn = { lines_flags = bit32.bor(ImGuiTreeNodeFlags.DrawLinesFull, ImGuiTreeNodeFlags.DefaultOpen), selection_mask = 0,
|
|
adv_flags = bit32.bor(ImGuiTreeNodeFlags.OpenOnArrow, ImGuiTreeNodeFlags.OpenOnDoubleClick, ImGuiTreeNodeFlags.SpanAvailWidth),
|
|
align_label = false, use_dnd = false }
|
|
function DemoWindowWidgetsTreeNodes()
|
|
if not ImGui.TreeNode("Tree Nodes") then return end
|
|
local s = S.tn
|
|
local TN = ImGuiTreeNodeFlags
|
|
if ImGui.TreeNode("Basic Trees") then
|
|
for i = 0, 4 do
|
|
if i == 0 then ImGui.SetNextItemOpen(true, ImGuiCond.Once) end
|
|
ImGui.PushID(i)
|
|
if ImGui.TreeNode("", "Child %d", i) then
|
|
ImGui.Text("blah blah")
|
|
ImGui.SameLine()
|
|
if ImGui.SmallButton("button") then end
|
|
ImGui.TreePop()
|
|
end
|
|
ImGui.PopID()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Hierarchy Lines") then
|
|
HelpMarker("Default option for DrawLinesXXX is stored in style.TreeLinesFlags")
|
|
_, s.lines_flags = ImGui.CheckboxFlags("ImGuiTreeNodeFlags_DrawLinesNone", s.lines_flags, TN.DrawLinesNone)
|
|
_, s.lines_flags = ImGui.CheckboxFlags("ImGuiTreeNodeFlags_DrawLinesFull", s.lines_flags, TN.DrawLinesFull)
|
|
_, s.lines_flags = ImGui.CheckboxFlags("ImGuiTreeNodeFlags_DrawLinesToNodes", s.lines_flags, TN.DrawLinesToNodes)
|
|
local f = s.lines_flags
|
|
if ImGui.TreeNodeEx("Parent", f) then
|
|
if ImGui.TreeNodeEx("Child 1", f) then ImGui.Button("Button for Child 1"); ImGui.TreePop() end
|
|
if ImGui.TreeNodeEx("Child 2", f) then ImGui.Button("Button for Child 2"); ImGui.TreePop() end
|
|
ImGui.Text("Remaining contents")
|
|
ImGui.Text("Remaining contents")
|
|
ImGui.TreePop()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Clipping Large Trees") then
|
|
ImGui.TextWrapped("- Using ImGuiListClipper with trees is a less easy than on arrays or grids.\n- Refer to 'Demo->Examples->Property Editor' for an example of how to do that.\n- Discuss in #3823")
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Selectable Nodes") then
|
|
HelpMarker("Manually implemented selectable nodes.\nClick to select, Ctrl+Click to toggle, click on arrows or double-click to open.")
|
|
local node_clicked_idx = -1
|
|
for node_n = 0, 5 do
|
|
local flags = bit32.bor(TN.OpenOnArrow, TN.OpenOnDoubleClick, TN.SpanAvailWidth)
|
|
if bit32.band(s.selection_mask, bit32.lshift(1, node_n)) ~= 0 then flags = bit32.bor(flags, TN.Selected) end
|
|
local is_open = ImGui.TreeNodeEx(node_n, flags, "Selectable Node %d", node_n)
|
|
if ImGui.IsItemClicked() and not ImGui.IsItemToggledOpen() then node_clicked_idx = node_n end
|
|
if is_open then
|
|
ImGui.BulletText("<Node contents here>")
|
|
ImGui.TreePop()
|
|
end
|
|
end
|
|
if node_clicked_idx ~= -1 then
|
|
if ImGui.GetIO().KeyCtrl then
|
|
s.selection_mask = bit32.bxor(s.selection_mask, bit32.lshift(1, node_clicked_idx))
|
|
else
|
|
s.selection_mask = bit32.lshift(1, node_clicked_idx)
|
|
end
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
if ImGui.TreeNode("Advanced") then
|
|
local function FB(name, help)
|
|
_, s.adv_flags = ImGui.CheckboxFlags("ImGuiTreeNodeFlags_" .. name, s.adv_flags, TN[name])
|
|
if help then ImGui.SameLine(); HelpMarker(help) end
|
|
end
|
|
FB("OpenOnArrow"); FB("OpenOnDoubleClick")
|
|
FB("SpanAvailWidth", "Extend hit area to all available width instead of allowing more items to be laid out after the node.")
|
|
FB("SpanFullWidth")
|
|
FB("SpanLabelWidth", "Reduce hit area to the text label and a bit of margin.")
|
|
FB("SpanAllColumns", "For use in Tables only.")
|
|
FB("AllowOverlap")
|
|
FB("Framed", "Draw frame with background (e.g. for CollapsingHeader)")
|
|
FB("FramePadding"); FB("NavLeftJumpsToParent")
|
|
HelpMarker("Default option for DrawLinesXXX is stored in style.TreeLinesFlags")
|
|
FB("DrawLinesNone"); FB("DrawLinesFull"); FB("DrawLinesToNodes")
|
|
_, s.align_label = ImGui.Checkbox("Align label with current X position", s.align_label)
|
|
_, s.use_dnd = ImGui.Checkbox("Make Tree Nodes as drag & drop sources", s.use_dnd)
|
|
if s.align_label then ImGui.Unindent(ImGui.GetTreeNodeToLabelSpacing()) end
|
|
for node_n = 0, 5 do
|
|
local node_flags = s.adv_flags
|
|
if node_n < 3 then
|
|
local is_open = ImGui.TreeNodeEx(node_n, node_flags, "Selectable Node %d", node_n)
|
|
if s.use_dnd and ImGui.BeginDragDropSource() then
|
|
ImGui.SetDragDropPayload("MY_TREENODE_PAYLOAD_TYPE", nil, 0)
|
|
ImGui.Text("This is a drag and drop source")
|
|
ImGui.EndDragDropSource()
|
|
end
|
|
if node_n == 2 and bit32.band(s.adv_flags, TN.SpanLabelWidth) ~= 0 then
|
|
ImGui.SameLine()
|
|
if ImGui.SmallButton("button") then end
|
|
end
|
|
if is_open then
|
|
ImGui.BulletText("Blah blah\nBlah Blah")
|
|
ImGui.SameLine()
|
|
ImGui.SmallButton("Button")
|
|
ImGui.TreePop()
|
|
end
|
|
else
|
|
node_flags = bit32.bor(node_flags, TN.Leaf, TN.NoTreePushOnOpen)
|
|
ImGui.TreeNodeEx(node_n, node_flags, "Selectable Leaf %d", node_n)
|
|
if s.use_dnd and ImGui.BeginDragDropSource() then
|
|
ImGui.SetDragDropPayload("MY_TREENODE_PAYLOAD_TYPE", nil, 0)
|
|
ImGui.Text("This is a drag and drop source")
|
|
ImGui.EndDragDropSource()
|
|
end
|
|
end
|
|
end
|
|
if s.align_label then ImGui.Indent(ImGui.GetTreeNodeToLabelSpacing()) end
|
|
ImGui.TreePop()
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
S.vs = { int_value = 0, values = { 0.0, 0.60, 0.35, 0.9, 0.70, 0.20, 0.0 }, values2 = { 0.20, 0.80, 0.40, 0.25 } }
|
|
function DemoWindowWidgetsVerticalSliders()
|
|
if not ImGui.TreeNode("Vertical Sliders") then return end
|
|
local s = S.vs
|
|
local spacing = 4
|
|
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, ImVec2(spacing, spacing))
|
|
s.int_value = ImGui.VSliderInt("##int", ImVec2(18, 160), s.int_value, 0, 5)
|
|
ImGui.SameLine()
|
|
local values = s.values
|
|
ImGui.PushID("set1")
|
|
for i = 0, 6 do
|
|
if i > 0 then ImGui.SameLine() end
|
|
ImGui.PushID(i)
|
|
ImGui.PushStyleColor(ImGuiCol.FrameBg, HSV(i / 7.0, 0.5, 0.5))
|
|
ImGui.PushStyleColor(ImGuiCol.FrameBgHovered, HSV(i / 7.0, 0.6, 0.5))
|
|
ImGui.PushStyleColor(ImGuiCol.FrameBgActive, HSV(i / 7.0, 0.7, 0.5))
|
|
ImGui.PushStyleColor(ImGuiCol.SliderGrab, HSV(i / 7.0, 0.9, 0.9))
|
|
values[i + 1] = ImGui.VSliderFloat("##v", ImVec2(18, 160), values[i + 1], 0.0, 1.0, "")
|
|
if ImGui.IsItemActive() or ImGui.IsItemHovered() then ImGui.SetTooltip("%.3f", values[i + 1]) end
|
|
ImGui.PopStyleColor(4)
|
|
ImGui.PopID()
|
|
end
|
|
ImGui.PopID()
|
|
|
|
ImGui.SameLine()
|
|
ImGui.PushID("set2")
|
|
local rows = 3
|
|
local small_slider_size = ImVec2(18, math.floor((160.0 - (rows - 1) * spacing) / rows))
|
|
for nx = 0, 3 do
|
|
if nx > 0 then ImGui.SameLine() end
|
|
ImGui.BeginGroup()
|
|
for ny = 0, rows - 1 do
|
|
ImGui.PushID(nx * rows + ny)
|
|
s.values2[nx + 1] = ImGui.VSliderFloat("##v", small_slider_size, s.values2[nx + 1], 0.0, 1.0, "")
|
|
if ImGui.IsItemActive() or ImGui.IsItemHovered() then ImGui.SetTooltip("%.3f", s.values2[nx + 1]) end
|
|
ImGui.PopID()
|
|
end
|
|
ImGui.EndGroup()
|
|
end
|
|
ImGui.PopID()
|
|
|
|
ImGui.SameLine()
|
|
ImGui.PushID("set3")
|
|
for i = 0, 3 do
|
|
if i > 0 then ImGui.SameLine() end
|
|
ImGui.PushID(i)
|
|
ImGui.PushStyleVar(ImGuiStyleVar.GrabMinSize, 40)
|
|
values[i + 1] = ImGui.VSliderFloat("##v", ImVec2(40, 160), values[i + 1], 0.0, 1.0, "%.2f\nsec")
|
|
ImGui.PopStyleVar()
|
|
ImGui.PopID()
|
|
end
|
|
ImGui.PopID()
|
|
ImGui.PopStyleVar()
|
|
ImGui.TreePop()
|
|
end
|
|
|
|
----------------------------------------------------------------
|
|
-- [SECTION] Example App: Main Menu Bar / ShowExampleAppMainMenuBar()
|
|
----------------------------------------------------------------
|
|
|
|
S.menu = { enabled = true, f = 0.5, n = 0, b = true }
|
|
function ShowExampleMenuFile()
|
|
local s = S.menu
|
|
ImGui.MenuItem("(demo menu)", nil, false, false)
|
|
if ImGui.MenuItem("New") then end
|
|
if ImGui.MenuItem("Open", "Ctrl+O") then end
|
|
if ImGui.BeginMenu("Open Recent") then
|
|
ImGui.MenuItem("fish_hat.c")
|
|
ImGui.MenuItem("fish_hat.inl")
|
|
ImGui.MenuItem("fish_hat.h")
|
|
if ImGui.BeginMenu("More..") then
|
|
ImGui.MenuItem("Hello")
|
|
ImGui.MenuItem("Sailor")
|
|
if ImGui.BeginMenu("Recurse..") then
|
|
ShowExampleMenuFile()
|
|
ImGui.EndMenu()
|
|
end
|
|
ImGui.EndMenu()
|
|
end
|
|
ImGui.EndMenu()
|
|
end
|
|
if ImGui.MenuItem("Save", "Ctrl+S") then end
|
|
if ImGui.MenuItem("Save As..") then end
|
|
|
|
ImGui.Separator()
|
|
if ImGui.BeginMenu("Options") then
|
|
_, s.enabled = ImGui.MenuItem("Enabled", "", s.enabled)
|
|
ImGui.BeginChild("child", ImVec2(0, ImGui.GetTextLineHeightWithSpacing() * 5.0), ImGuiChildFlags.Borders)
|
|
for i = 0, 9 do ImGui.Text("Scrolling Text %d", i) end
|
|
ImGui.EndChild()
|
|
s.f = ImGui.SliderFloat("Value", s.f, 0.0, 1.0)
|
|
s.f = ImGui.InputFloat("Input", s.f, 0.1)
|
|
s.n = ImGui.Combo("Combo", s.n, "Yes\0No\0Maybe\0\0")
|
|
ImGui.EndMenu()
|
|
end
|
|
|
|
if ImGui.BeginMenu("Colors") then
|
|
local sz = ImGui.GetTextLineHeight()
|
|
for i = 0, ImGuiCol.COUNT - 1 do
|
|
local name = ImGui.GetStyleColorName(i)
|
|
local p = ImGui.GetCursorScreenPos()
|
|
ImGui.GetWindowDrawList():AddRectFilled(p, ImVec2(p.x + sz, p.y + sz), ImGui.GetColorU32(i))
|
|
ImGui.Dummy(ImVec2(sz, sz))
|
|
ImGui.SameLine()
|
|
ImGui.MenuItem(name)
|
|
end
|
|
ImGui.EndMenu()
|
|
end
|
|
|
|
-- Here we demonstrate appending again to the "Options" menu (which we already created above)
|
|
if ImGui.BeginMenu("Options") then
|
|
_, s.b = ImGui.Checkbox("SomeOption", s.b)
|
|
ImGui.EndMenu()
|
|
end
|
|
|
|
if ImGui.BeginMenu("Disabled", false) then
|
|
IM_ASSERT(false)
|
|
end
|
|
if ImGui.MenuItem("Checked", nil, true) then end
|
|
ImGui.Separator()
|
|
if ImGui.MenuItem("Quit", "Alt+F4") then end
|
|
end
|
|
|
|
function ShowExampleAppMainMenuBar()
|
|
if ImGui.BeginMainMenuBar() then
|
|
if ImGui.BeginMenu("File") then
|
|
ShowExampleMenuFile()
|
|
ImGui.EndMenu()
|
|
end
|
|
if ImGui.BeginMenu("Edit") then
|
|
if ImGui.MenuItem("Undo", "Ctrl+Z") then end
|
|
if ImGui.MenuItem("Redo", "Ctrl+Y", false, false) then end
|
|
ImGui.Separator()
|
|
if ImGui.MenuItem("Cut", "Ctrl+X") then end
|
|
if ImGui.MenuItem("Copy", "Ctrl+C") then end
|
|
if ImGui.MenuItem("Paste", "Ctrl+V") then end
|
|
ImGui.EndMenu()
|
|
end
|
|
ImGui.EndMainMenuBar()
|
|
end
|
|
end
|
|
|
|
----------------------------------------------------------------
|
|
-- [SECTION] Style Editor / ShowStyleEditor()
|
|
----------------------------------------------------------------
|
|
|
|
-- Deep copy of an ImGuiStyle (ImVec2/ImVec4 fields and Colors[] are copied by value)
|
|
local function StyleCopy(dst, src)
|
|
for k, v in pairs(src) do
|
|
if k == "Colors" then
|
|
dst.Colors = dst.Colors or {}
|
|
for i, c in pairs(v) do
|
|
if type(c) == "table" then dst.Colors[i] = dst.Colors[i] or ImVec4(); ImVec4_Copy(dst.Colors[i], c) else dst.Colors[i] = c end
|
|
end
|
|
elseif type(v) == "table" and getmetatable(v) ~= nil and type(v[1]) == "number" then
|
|
local c = dst[k]
|
|
if type(c) ~= "table" then c = setmetatable({}, getmetatable(v)); dst[k] = c end
|
|
for i = 1, #v do rawset(c, i, v[i]) end
|
|
else
|
|
dst[k] = v
|
|
end
|
|
end
|
|
if getmetatable(dst) == nil then setmetatable(dst, getmetatable(src)) end
|
|
return dst
|
|
end
|
|
|
|
local function ColorsEqual(a, b) return a[1] == b[1] and a[2] == b[2] and a[3] == b[3] and a[4] == b[4] end
|
|
|
|
S.ss = { style_idx = -1 }
|
|
function ImGui.ShowStyleSelector(label)
|
|
local s = S.ss
|
|
local style_names = { "Dark", "Light", "Classic" }
|
|
local ret = false
|
|
if ImGui.BeginCombo(label, style_names[s.style_idx + 1] or "") then
|
|
for n = 0, 2 do
|
|
if ImGui.Selectable(style_names[n + 1], s.style_idx == n, ImGuiSelectableFlags.SelectOnNav) then
|
|
s.style_idx = n
|
|
ret = true
|
|
if n == 0 then ImGui.StyleColorsDark() elseif n == 1 then ImGui.StyleColorsLight() else ImGui.StyleColorsClassic() end
|
|
elseif s.style_idx == n then
|
|
ImGui.SetItemDefaultFocus()
|
|
end
|
|
end
|
|
ImGui.EndCombo()
|
|
end
|
|
return ret
|
|
end
|
|
|
|
local function GetTreeLinesFlagsName(flags)
|
|
local TN = ImGuiTreeNodeFlags
|
|
if flags == TN.DrawLinesNone then return "DrawLinesNone" end
|
|
if flags == TN.DrawLinesFull then return "DrawLinesFull" end
|
|
if flags == TN.DrawLinesToNodes then return "DrawLinesToNodes" end
|
|
return ""
|
|
end
|
|
|
|
S.se = { ref_saved_style = nil, init = true, output_dest = 0, output_only_modified = true, alpha_flags = 0, filter = nil }
|
|
function ImGui.ShowStyleEditor(ref)
|
|
local se = S.se
|
|
local style = ImGui.GetStyle()
|
|
if se.ref_saved_style == nil then se.ref_saved_style = {} end
|
|
if se.init and ref == nil then StyleCopy(se.ref_saved_style, style) end
|
|
se.init = false
|
|
if ref == nil then ref = se.ref_saved_style end
|
|
|
|
local default_border_size = math.floor(style._MainScale or 1.0)
|
|
local max_border_size = math.max(default_border_size, 2.0)
|
|
local function SF(name, mn, mx, fmt) if style[name] ~= nil then style[name] = ImGui.SliderFloat(name, style[name], mn, mx, fmt or "%.0f") end end
|
|
local function SF2(name, mn, mx, fmt) if style[name] ~= nil then ImGui.SliderFloat2(name, style[name], mn, mx, fmt or "%.0f") end end
|
|
local function DF(name, speed, mn, mx, fmt, flags) if style[name] ~= nil then style[name] = ImGui.DragFloat(name, style[name], speed, mn, mx, fmt or "%.0f", flags) end end
|
|
|
|
ImGui.PushItemWidth(ImGui.GetWindowWidth() * 0.50)
|
|
|
|
ImGui.SeparatorText("General")
|
|
if bit32.band(ImGui.GetIO().BackendFlags, ImGuiBackendFlags.RendererHasTextures) == 0 then
|
|
ImGui.BulletText("Warning: Font scaling will NOT be smooth, because\nImGuiBackendFlags_RendererHasTextures is not set!")
|
|
ImGui.BulletText("For instructions, see:")
|
|
ImGui.SameLine()
|
|
ImGui.TextLinkOpenURL("docs/BACKENDS.md", "https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md")
|
|
end
|
|
if ImGui.ShowStyleSelector("Colors##Selector") then StyleCopy(se.ref_saved_style, style) end
|
|
if ImGui.ShowFontSelector then ImGui.ShowFontSelector("Fonts##Selector") end
|
|
local changed
|
|
style.FontSizeBase, changed = ImGui.DragFloat("FontSizeBase", style.FontSizeBase, 0.20, 5.0, 100.0, "%.0f")
|
|
if changed then style._NextFrameFontSizeBase = style.FontSizeBase end
|
|
ImGui.SameLine(0.0, 0.0); ImGui.Text(" (out %.2f)", ImGui.GetFontSize())
|
|
style.FontScaleMain = ImGui.DragFloat("FontScaleMain", style.FontScaleMain, 0.02, 0.5, 4.0)
|
|
ImGui.BeginDisabled(ImGui.GetIO().ConfigDpiScaleFonts == true)
|
|
style.FontScaleDpi = ImGui.DragFloat("FontScaleDpi", style.FontScaleDpi, 0.02, 0.5, 4.0)
|
|
ImGui.SetItemTooltip("When io.ConfigDpiScaleFonts is set, this value is automatically overwritten.")
|
|
ImGui.EndDisabled()
|
|
|
|
style.FrameRounding, changed = ImGui.SliderFloat("FrameRounding", style.FrameRounding, 0.0, 12.0, "%.0f")
|
|
if changed then style.GrabRounding = style.FrameRounding end
|
|
local p, border
|
|
p, border = ImGui.Checkbox("WindowBorder", style.WindowBorderSize > 0.0); if p then style.WindowBorderSize = border and default_border_size or 0.0 end
|
|
ImGui.SameLine()
|
|
p, border = ImGui.Checkbox("FrameBorder", style.FrameBorderSize > 0.0); if p then style.FrameBorderSize = border and default_border_size or 0.0 end
|
|
ImGui.SameLine()
|
|
p, border = ImGui.Checkbox("PopupBorder", style.PopupBorderSize > 0.0); if p then style.PopupBorderSize = border and default_border_size or 0.0 end
|
|
|
|
if ImGui.Button("Save Ref") then StyleCopy(se.ref_saved_style, style); if ref ~= se.ref_saved_style then StyleCopy(ref, style) end end
|
|
ImGui.SameLine()
|
|
if ImGui.Button("Revert Ref") then StyleCopy(style, ref) end
|
|
ImGui.SameLine()
|
|
HelpMarker("Save/Revert in local non-persistent storage. Default Colors definition are not affected. Use \"Export\" below to save them somewhere.")
|
|
|
|
ImGui.SeparatorText("Details")
|
|
if ImGui.BeginTabBar("##tabs", ImGuiTabBarFlags.None) then
|
|
if ImGui.BeginTabItem("Sizes") then
|
|
ImGui.SeparatorText("Main")
|
|
SF2("WindowPadding", 0.0, 20.0); SF2("FramePadding", 0.0, 20.0); SF2("ItemSpacing", 0.0, 20.0)
|
|
SF2("ItemInnerSpacing", 0.0, 20.0); SF2("TouchExtraPadding", 0.0, 10.0)
|
|
SF("IndentSpacing", 0.0, 30.0); SF("GrabMinSize", 1.0, 20.0)
|
|
|
|
ImGui.SeparatorText("Borders")
|
|
SF("WindowBorderSize", 0.0, max_border_size); SF("ChildBorderSize", 0.0, max_border_size)
|
|
SF("PopupBorderSize", 0.0, max_border_size); SF("FrameBorderSize", 0.0, max_border_size)
|
|
|
|
ImGui.SeparatorText("Rounding")
|
|
SF("WindowRounding", 0.0, 12.0); SF("ChildRounding", 0.0, 12.0); SF("FrameRounding", 0.0, 12.0)
|
|
SF("PopupRounding", 0.0, 12.0); SF("GrabRounding", 0.0, 12.0); SF("MenuItemRounding", 0.0, 12.0)
|
|
|
|
ImGui.SeparatorText("Scrollbar")
|
|
SF("ScrollbarSize", 1.0, 20.0); SF("ScrollbarRounding", 0.0, 12.0); SF("ScrollbarPadding", 0.0, 10.0)
|
|
|
|
ImGui.SeparatorText("Tabs")
|
|
SF("TabBorderSize", 0.0, max_border_size); SF("TabBarBorderSize", 0.0, max_border_size)
|
|
SF("TabBarOverlineSize", 0.0, math.max(3.0, max_border_size))
|
|
ImGui.SameLine(); HelpMarker("Overline is only drawn over the selected tab when ImGuiTabBarFlags_DrawSelectedOverline is set.")
|
|
DF("TabMinWidthBase", 0.5, 1.0, 500.0); DF("TabMinWidthShrink", 0.5, 1.0, 500.0, "%0.f")
|
|
if style.TabCloseButtonMinWidthSelected ~= nil then
|
|
DF("TabCloseButtonMinWidthSelected", 0.5, -1.0, 100.0, (style.TabCloseButtonMinWidthSelected < 0.0) and "%.0f (Always)" or "%.0f")
|
|
DF("TabCloseButtonMinWidthUnselected", 0.5, -1.0, 100.0, (style.TabCloseButtonMinWidthUnselected < 0.0) and "%.0f (Always)" or "%.0f")
|
|
end
|
|
SF("TabRounding", 0.0, 12.0)
|
|
|
|
ImGui.SeparatorText("Tables")
|
|
SF2("CellPadding", 0.0, 20.0)
|
|
style.TableAngledHeadersAngle = ImGui.SliderAngle("TableAngledHeadersAngle", style.TableAngledHeadersAngle, -50.0, 50.0)
|
|
SF2("TableAngledHeadersTextAlign", 0.0, 1.0, "%.2f")
|
|
|
|
ImGui.SeparatorText("Trees")
|
|
local combo_open = ImGui.BeginCombo("TreeLinesFlags", GetTreeLinesFlagsName(style.TreeLinesFlags))
|
|
ImGui.SameLine()
|
|
HelpMarker("[Experimental] Tree lines may not work in all situations (e.g. using a clipper) and may incurs slight traversal overhead.\n\nImGuiTreeNodeFlags_DrawLinesFull is faster than ImGuiTreeNodeFlags_DrawLinesToNode.")
|
|
if combo_open then
|
|
local TN = ImGuiTreeNodeFlags
|
|
for _, option in ipairs({ TN.DrawLinesNone, TN.DrawLinesFull, TN.DrawLinesToNodes }) do
|
|
if ImGui.Selectable(GetTreeLinesFlagsName(option), style.TreeLinesFlags == option) then style.TreeLinesFlags = option end
|
|
end
|
|
ImGui.EndCombo()
|
|
end
|
|
SF("TreeLinesSize", 0.0, max_border_size); SF("TreeLinesRounding", 0.0, 12.0)
|
|
|
|
ImGui.SeparatorText("Windows")
|
|
SF2("WindowTitleAlign", 0.0, 1.0, "%.2f"); SF("WindowBorderHoverPadding", 1.0, 20.0)
|
|
local window_menu_button_position = style.WindowMenuButtonPosition + 1
|
|
window_menu_button_position, changed = ImGui.Combo("WindowMenuButtonPosition", window_menu_button_position, "None\0Left\0Right\0")
|
|
if changed then style.WindowMenuButtonPosition = window_menu_button_position - 1 end
|
|
|
|
ImGui.SeparatorText("Widgets")
|
|
SF("ColorMarkerSize", 0.0, 8.0)
|
|
style.ColorButtonPosition = ImGui.Combo("ColorButtonPosition", style.ColorButtonPosition, "Left\0Right\0")
|
|
SF2("ButtonTextAlign", 0.0, 1.0, "%.2f")
|
|
ImGui.SameLine(); HelpMarker("Alignment applies when a button is larger than its text content.")
|
|
SF2("SelectableTextAlign", 0.0, 1.0, "%.2f")
|
|
ImGui.SameLine(); HelpMarker("Alignment applies when a selectable is larger than its text content.")
|
|
SF("SeparatorSize", 0.0, 10.0); SF("SeparatorTextBorderSize", 0.0, 10.0)
|
|
SF2("SeparatorTextAlign", 0.0, 1.0, "%.2f"); SF2("SeparatorTextPadding", 0.0, 40.0)
|
|
SF("LogSliderDeadzone", 0.0, 12.0); SF("ImageRounding", 0.0, 12.0); SF("ImageBorderSize", 0.0, max_border_size)
|
|
|
|
ImGui.SeparatorText("Docking")
|
|
_, style.DockingNodeHasCloseButton = ImGui.Checkbox("DockingNodeHasCloseButton", style.DockingNodeHasCloseButton)
|
|
SF("DockingSeparatorSize", 0.0, 12.0)
|
|
|
|
ImGui.SeparatorText("Tooltips")
|
|
for n = 0, 1 do
|
|
local key = (n == 0) and "HoverFlagsForTooltipMouse" or "HoverFlagsForTooltipNav"
|
|
if ImGui.TreeNodeEx(key) then
|
|
for _, f in ipairs({ "DelayNone", "DelayShort", "DelayNormal", "Stationary", "NoSharedDelay" }) do
|
|
_, style[key] = ImGui.CheckboxFlags("ImGuiHoveredFlags_" .. f, style[key], ImGuiHoveredFlags[f])
|
|
end
|
|
ImGui.TreePop()
|
|
end
|
|
end
|
|
|
|
ImGui.SeparatorText("Misc")
|
|
SF2("DisplayWindowPadding", 0.0, 30.0); ImGui.SameLine(); HelpMarker("Apply to regular windows: amount which we enforce to keep visible when moving near edges of your screen.")
|
|
SF2("DisplaySafeAreaPadding", 0.0, 30.0); ImGui.SameLine(); HelpMarker("Apply to every windows, menus, popups, tooltips: amount where we avoid displaying contents. Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured).")
|
|
ImGui.EndTabItem()
|
|
end
|
|
|
|
if ImGui.BeginTabItem("Colors") then
|
|
if ImGui.Button("Export") then
|
|
if se.output_dest == 0 then ImGui.LogToClipboard() else ImGui.LogToTTY() end
|
|
ImGui.LogText("ImVec4* colors = GetStyle().Colors;\n")
|
|
for i = 0, ImGuiCol.COUNT - 1 do
|
|
local col = style.Colors[i]
|
|
local name = ImGui.GetStyleColorName(i)
|
|
if not se.output_only_modified or not ColorsEqual(col, ref.Colors[i]) then
|
|
ImGui.LogText("colors[ImGuiCol_%s]%s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);\n", name, string.rep(" ", math.max(0, 23 - #name)), col.x, col.y, col.z, col.w)
|
|
end
|
|
end
|
|
ImGui.LogFinish()
|
|
end
|
|
ImGui.SameLine(); ImGui.SetNextItemWidth(ImGui.GetFontSize() * 10)
|
|
se.output_dest = ImGui.Combo("##output_type", se.output_dest, "To Clipboard\0To TTY\0")
|
|
ImGui.SameLine(); _, se.output_only_modified = ImGui.Checkbox("Only Modified Colors", se.output_only_modified)
|
|
|
|
local CE = ImGuiColorEditFlags
|
|
if ImGui.RadioButtonEx("Opaque", se.alpha_flags == CE.AlphaOpaque) then se.alpha_flags = CE.AlphaOpaque end ImGui.SameLine()
|
|
if ImGui.RadioButtonEx("Alpha", se.alpha_flags == CE.None) then se.alpha_flags = CE.None end ImGui.SameLine()
|
|
if ImGui.RadioButtonEx("Both", se.alpha_flags == CE.AlphaPreviewHalf) then se.alpha_flags = CE.AlphaPreviewHalf end ImGui.SameLine()
|
|
HelpMarker("In the color list:\nLeft-click on color square to open color picker,\nRight-click to open edit options menu.")
|
|
|
|
se.filter = se.filter or ImGuiTextFilter()
|
|
ImGui.SetNextItemWidth(-FLT_MIN)
|
|
se.filter:DrawWithHint("##FilterColors", "Filter Colors (incl -excl)")
|
|
|
|
ImGui.SetNextWindowSizeConstraints(ImVec2(0.0, ImGui.GetTextLineHeightWithSpacing() * 10), ImVec2(FLT_MAX, FLT_MAX))
|
|
ImGui.BeginChild("##colors", ImVec2(0, 0), bit32.bor(ImGuiChildFlags.Borders, ImGuiChildFlags.NavFlattened), bit32.bor(ImGuiWindowFlags.AlwaysVerticalScrollbar, ImGuiWindowFlags.AlwaysHorizontalScrollbar))
|
|
ImGui.PushItemWidth(ImGui.GetFontSize() * -12)
|
|
for i = 0, ImGuiCol.COUNT - 1 do
|
|
local name = ImGui.GetStyleColorName(i)
|
|
if se.filter:PassFilter(name) then
|
|
ImGui.PushID(i)
|
|
if ImGui.DebugFlashStyleColor then
|
|
if ImGui.Button("?") then ImGui.DebugFlashStyleColor(i) end
|
|
ImGui.SetItemTooltip("Flash given color to identify places where it is used.")
|
|
ImGui.SameLine()
|
|
end
|
|
ImGui.ColorEdit4("##color", style.Colors[i], bit32.bor(CE.AlphaBar, se.alpha_flags))
|
|
if not ColorsEqual(style.Colors[i], ref.Colors[i]) then
|
|
ImGui.SameLine(0.0, style.ItemInnerSpacing.x); if ImGui.Button("Save") then ImVec4_Copy(ref.Colors[i], style.Colors[i]) end
|
|
ImGui.SameLine(0.0, style.ItemInnerSpacing.x); if ImGui.Button("Revert") then ImVec4_Copy(style.Colors[i], ref.Colors[i]) end
|
|
end
|
|
ImGui.SameLine(0.0, style.ItemInnerSpacing.x)
|
|
ImGui.TextUnformatted(name)
|
|
ImGui.PopID()
|
|
end
|
|
end
|
|
ImGui.PopItemWidth()
|
|
ImGui.EndChild()
|
|
ImGui.EndTabItem()
|
|
end
|
|
|
|
if ImGui.BeginTabItem("Fonts") then
|
|
if ImGui.ShowFontAtlas then ImGui.ShowFontAtlas(ImGui.GetIO().Fonts) else DemoNotPorted("ShowFontAtlas") end
|
|
ImGui.EndTabItem()
|
|
end
|
|
|
|
if ImGui.BeginTabItem("Rendering") then
|
|
_, style.AntiAliasedLines = ImGui.Checkbox("Anti-aliased lines", style.AntiAliasedLines)
|
|
ImGui.SameLine()
|
|
HelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well.")
|
|
ImGui.BeginDisabled(style.AntiAliasedLines == false)
|
|
_, style.AntiAliasedLineEnds = ImGui.Checkbox("Anti-aliased line ends", style.AntiAliasedLineEnds)
|
|
ImGui.EndDisabled()
|
|
_, style.AntiAliasedFill = ImGui.Checkbox("Anti-aliased fill", style.AntiAliasedFill)
|
|
local io = ImGui.GetIO()
|
|
_, io.ConfigDebugDrawListDefaultsToStrokeLegacy = ImGui.Checkbox("Debug: DrawList Defaults to _StrokeLegacy", io.ConfigDebugDrawListDefaultsToStrokeLegacy == true)
|
|
|
|
ImGui.PushItemWidth(ImGui.GetFontSize() * 8)
|
|
-- [port] library still stores the pre-1.93 CurveTessellationTol (== MaxError * MaxError)
|
|
local curve_err = ImGui.DragFloat("Curve Tessellation Max Error", math.sqrt(style.CurveTessellationTol), 0.02, 0.10, 10.0, "%.2f")
|
|
if curve_err < 0.10 then curve_err = 0.10 end
|
|
style.CurveTessellationTol = curve_err * curve_err
|
|
|
|
style.CircleTessellationMaxError = ImGui.DragFloat("Circle Tessellation Max Error", style.CircleTessellationMaxError, 0.005, 0.10, 5.0, "%.2f", ImGuiSliderFlags.AlwaysClamp)
|
|
local show_samples = ImGui.IsItemActive()
|
|
if show_samples then ImGui.SetNextWindowPos(ImGui.GetCursorScreenPos()) end
|
|
if show_samples and ImGui.BeginTooltip() then
|
|
ImGui.TextUnformatted("(R = radius, N = approx number of segments)")
|
|
ImGui.Spacing()
|
|
local draw_list = ImGui.GetWindowDrawList()
|
|
local min_widget_width = ImGui.CalcTextSize("R: MMM\nN: MMM").x
|
|
for n = 0, 7 do
|
|
local RAD_MIN, RAD_MAX = 5.0, 70.0
|
|
local rad = RAD_MIN + (RAD_MAX - RAD_MIN) * n / (8.0 - 1.0)
|
|
ImGui.BeginGroup()
|
|
ImGui.Text("R: %.f\nN: %d", rad, draw_list:_CalcCircleAutoSegmentCount(rad))
|
|
local canvas_width = math.max(min_widget_width, rad * 2.0)
|
|
local offset_x = math.floor(canvas_width * 0.5)
|
|
local offset_y = math.floor(RAD_MAX)
|
|
local p1 = ImGui.GetCursorScreenPos()
|
|
draw_list:AddCircle(ImVec2(p1.x + offset_x, p1.y + offset_y), rad, ImGui.GetColorU32(ImGuiCol.Text))
|
|
ImGui.Dummy(ImVec2(canvas_width, RAD_MAX * 2))
|
|
ImGui.EndGroup()
|
|
ImGui.SameLine()
|
|
end
|
|
ImGui.EndTooltip()
|
|
end
|
|
ImGui.SameLine()
|
|
HelpMarker("When drawing circle primitives with \"num_segments == 0\" tessellation will be calculated automatically.")
|
|
style.Alpha = ImGui.DragFloat("Global Alpha", style.Alpha, 0.005, 0.20, 1.0, "%.2f")
|
|
style.DisabledAlpha = ImGui.DragFloat("Disabled Alpha", style.DisabledAlpha, 0.005, 0.0, 1.0, "%.2f")
|
|
ImGui.SameLine(); HelpMarker("Additional alpha multiplier for disabled items (multiply over current value of Alpha).")
|
|
ImGui.PopItemWidth()
|
|
ImGui.EndTabItem()
|
|
end
|
|
ImGui.EndTabBar()
|
|
end
|
|
ImGui.PopItemWidth()
|
|
end
|
|
|
|
return true
|