Compare commits
2
Commits
95fdf94912
..
v0.1.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce82582e37 | ||
|
|
090525076f |
+1
-1
@@ -116,7 +116,7 @@ The Style Editor (`ImGui.ShowStyleEditor()`) and the Metrics/Debugger (`ImGui.Sh
|
||||
|
||||
### Getting Started & Integration (Roblox)
|
||||
|
||||
With [Wally](https://wally.run) ([4dbug/imgui-luau](https://wally.run/package/4dbug/imgui-luau)): add `ImGui = "4dbug/[email protected].3"` under `[dependencies]` in your `wally.toml`, run `wally install`, then `require(ReplicatedStorage.Packages.ImGui)`. Or from source:
|
||||
With [Wally](https://wally.run) ([4dbug/imgui-luau](https://wally.run/package/4dbug/imgui-luau)): add `ImGui = "4dbug/[email protected].4"` under `[dependencies]` in your `wally.toml`, run `wally install`, then `require(ReplicatedStorage.Packages.ImGui)`. Or from source:
|
||||
|
||||
1. Build the module: `python3 tools/bundle.py` writes `build/ImGui.luau` (`--no-demo` leaves the demo out) and `build/ImGuiTyped.luau`, a small typed entry module (Luau types for the public `ImGui.*` API, `ImVec2`/`ImVec4` and the flag enums) that requires `build/ImGui.luau` as its child `Impl`. The Wally package and the Rojo projects use that layout, so you get autocomplete and type errors in `--!strict` scripts. The single-file `ImGui.luau` also works on its own, just untyped.
|
||||
2. Sync with [Rojo](https://rojo.space): [`default.project.json`](/default.project.json) puts the module in `ReplicatedStorage.ImGui` and the example LocalScript in `StarterPlayerScripts`.
|
||||
|
||||
@@ -61,6 +61,8 @@ jobs:
|
||||
grep -q "CACHED OK" /tmp/c.txt
|
||||
MINIFY=1 python3 tools/test/run.py --main tools/test/scripts/t_readme.luau --frames 30 --quiet --roblox --timeout 300 | tee /tmp/rm.txt
|
||||
grep -q "README OK" /tmp/rm.txt
|
||||
python3 tools/test/run.py --main tools/test/scripts/t_fixes.luau --frames 25 --quiet --roblox --timeout 300 | tee /tmp/f.txt
|
||||
grep -q "FIXES OK" /tmp/f.txt
|
||||
python3 tools/bundle.py --target love >/dev/null
|
||||
luajit tools/test/love/t_drawhash.lua 60 Widgets,Basic | tee /tmp/h.txt
|
||||
cp build/imgui_love.lua /tmp/imgui_love.lua && cp dist/imgui_love.min.lua build/imgui_love.lua
|
||||
|
||||
@@ -113,7 +113,7 @@ The Style Editor (`ImGui.ShowStyleEditor()`) and the Metrics/Debugger (`ImGui.Sh
|
||||
|
||||
### Getting Started & Integration (Roblox)
|
||||
|
||||
With [Wally](https://wally.run) ([4dbug/imgui-luau](https://wally.run/package/4dbug/imgui-luau)): add `ImGui = "4dbug/[email protected].3"` under `[dependencies]` in your `wally.toml`, run `wally install`, then `require(ReplicatedStorage.Packages.ImGui)`. Or from source:
|
||||
With [Wally](https://wally.run) ([4dbug/imgui-luau](https://wally.run/package/4dbug/imgui-luau)): add `ImGui = "4dbug/[email protected].4"` under `[dependencies]` in your `wally.toml`, run `wally install`, then `require(ReplicatedStorage.Packages.ImGui)`. Or from source:
|
||||
|
||||
1. Build the module: `python3 tools/bundle.py` writes `build/ImGui.luau` (`--no-demo` leaves the demo out) and `build/ImGuiTyped.luau`, a small typed entry module (Luau types for the public `ImGui.*` API, `ImVec2`/`ImVec4` and the flag enums) that requires `build/ImGui.luau` as its child `Impl`. The Wally package and the Rojo projects use that layout, so you get autocomplete and type errors in `--!strict` scripts. The single-file `ImGui.luau` also works on its own, just untyped.
|
||||
2. Sync with [Rojo](https://rojo.space): [`default.project.json`](default.project.json) puts the module in `ReplicatedStorage.ImGui` and the example LocalScript in `StarterPlayerScripts`.
|
||||
|
||||
@@ -1 +1 @@
|
||||
[[12, "imgui.lua"], [21288, "imgui_demo.lua"], [29706, "imgui_draw.lua"], [35476, "imgui_h.lua"], [38142, "imgui_impl_roblox.lua"], [39494, "imgui_impl_roblox_fonts.lua"], [45897, "imgui_internal.lua"], [49343, "imgui_tables.lua"], [54338, "imgui_widgets.lua"], [64949, "imstb_rectpack.lua"], [65613, "imstb_textedit.lua"], [67155, "imstb_truetype.lua"], [69943, "imstd_minstdio.lua"]]
|
||||
[[12, "imgui.lua"], [21288, "imgui_demo.lua"], [29706, "imgui_draw.lua"], [35476, "imgui_h.lua"], [38142, "imgui_impl_roblox.lua"], [39494, "imgui_impl_roblox_fonts.lua"], [45897, "imgui_internal.lua"], [49343, "imgui_tables.lua"], [54338, "imgui_widgets.lua"], [64948, "imstb_rectpack.lua"], [65612, "imstb_textedit.lua"], [67154, "imstb_truetype.lua"], [69942, "imstd_minstdio.lua"]]
|
||||
+8
-9
@@ -57019,19 +57019,18 @@ end
|
||||
-- fmt = "blah blah" -> return ""
|
||||
-- fmt = "%.3f" -> return "%.3f"
|
||||
-- fmt = "hello %.3f" -> return "%.3f"
|
||||
-- TODO: temporary patch. does not look good
|
||||
-- fmt = "%.3f hello" -> return "%.3f"
|
||||
--- @param fmt string
|
||||
local function ImParseFormatTrimDecorations(fmt)
|
||||
local fmt_start = ImParseFormatFindStart(fmt)
|
||||
if string.byte(fmt, fmt_start) ~= 37 then -- '%'
|
||||
if fmt_start == nil or string.byte(fmt, fmt_start) ~= 37 then -- '%'
|
||||
return ""
|
||||
end
|
||||
--- @cast fmt_start int
|
||||
local fmt_end = ImParseFormatFindEnd(fmt, fmt_start)
|
||||
if string.byte(fmt, fmt_end) ~= 37 then
|
||||
if fmt_end > #fmt then -- If we only have leading decoration, we don't need to copy the data.
|
||||
return string.sub(fmt, fmt_start)
|
||||
end
|
||||
return string.sub(fmt, fmt_start, fmt_end)
|
||||
return string.sub(fmt, fmt_start, fmt_end - 1)
|
||||
end
|
||||
|
||||
-- - For scanning we need to remove all width and precision fields and flags "%+3.7f" -> "%f". BUT don't strip types like "%I64d" which includes digits. ! "%07I64d" -> "%I64d"
|
||||
@@ -60144,15 +60143,15 @@ function ImGui.InputTextEx(label, hint, buf, buf_size, size_arg, flags, callback
|
||||
in_len, c = ImStd.ImTextCharFromUtf8(clipboard, i, clipboard_end)
|
||||
i = i + in_len
|
||||
c, ret2 = InputTextFilterCharacter(g, state, c, callback, callback_user_data, true)
|
||||
if ret2 then
|
||||
break
|
||||
if not ret2 then
|
||||
break -- continue
|
||||
end
|
||||
|
||||
local c_utf8 = {0, 0, 0, 0, 0}
|
||||
ImStd.ImTextCharToUtf8(c_utf8, c)
|
||||
local out_len = ImStd.ImStrlen(c_utf8)
|
||||
clipboard_filtered:resize(clipboard_filtered.Size + out_len)
|
||||
ImStd.memmove(clipboard_filtered.Data, clipboard_filtered.Size - out_len, c_utf8, 1, out_len)
|
||||
ImStd.memmove(clipboard_filtered.Data, clipboard_filtered.Size - out_len + 1, c_utf8, 1, out_len)
|
||||
|
||||
until true
|
||||
end
|
||||
@@ -63664,7 +63663,7 @@ function ImGui.ShrinkWidths(items, first, count, width_excess, width_min)
|
||||
for n = 1, count do slice[n] = items[first + n - 1] end
|
||||
table.sort(slice, function(a, b)
|
||||
if a.Width ~= b.Width then return a.Width > b.Width end
|
||||
return a.Index < b.Index
|
||||
return a.Index > b.Index -- ShrinkWidthItemComparer: b->Index - a->Index (Width compared exactly: upstream's (int) truncation isn't a strict weak order, which table.sort rejects)
|
||||
end)
|
||||
for n = 1, count do items[first + n - 1] = slice[n] end
|
||||
local it = slice
|
||||
|
||||
@@ -1 +1 @@
|
||||
[[149, "imgui.lua"], [21425, "imgui_demo.lua"], [29843, "imgui_draw.lua"], [35613, "imgui_h.lua"], [38279, "imgui_impl_love.lua"], [38819, "imgui_internal.lua"], [42265, "imgui_tables.lua"], [47260, "imgui_widgets.lua"], [57871, "imstb_rectpack.lua"], [58535, "imstb_textedit.lua"], [60077, "imstb_truetype.lua"], [62865, "imstd_minstdio.lua"]]
|
||||
[[149, "imgui.lua"], [21425, "imgui_demo.lua"], [29843, "imgui_draw.lua"], [35613, "imgui_h.lua"], [38279, "imgui_impl_love.lua"], [38819, "imgui_internal.lua"], [42265, "imgui_tables.lua"], [47260, "imgui_widgets.lua"], [57870, "imstb_rectpack.lua"], [58534, "imstb_textedit.lua"], [60076, "imstb_truetype.lua"], [62864, "imstd_minstdio.lua"]]
|
||||
@@ -49941,19 +49941,18 @@ end
|
||||
-- fmt = "blah blah" -> return ""
|
||||
-- fmt = "%.3f" -> return "%.3f"
|
||||
-- fmt = "hello %.3f" -> return "%.3f"
|
||||
-- TODO: temporary patch. does not look good
|
||||
-- fmt = "%.3f hello" -> return "%.3f"
|
||||
--- @param fmt string
|
||||
local function ImParseFormatTrimDecorations(fmt)
|
||||
local fmt_start = ImParseFormatFindStart(fmt)
|
||||
if string.byte(fmt, fmt_start) ~= 37 then -- '%'
|
||||
if fmt_start == nil or string.byte(fmt, fmt_start) ~= 37 then -- '%'
|
||||
return ""
|
||||
end
|
||||
--- @cast fmt_start int
|
||||
local fmt_end = ImParseFormatFindEnd(fmt, fmt_start)
|
||||
if string.byte(fmt, fmt_end) ~= 37 then
|
||||
if fmt_end > #fmt then -- If we only have leading decoration, we don't need to copy the data.
|
||||
return string.sub(fmt, fmt_start)
|
||||
end
|
||||
return string.sub(fmt, fmt_start, fmt_end)
|
||||
return string.sub(fmt, fmt_start, fmt_end - 1)
|
||||
end
|
||||
|
||||
-- - For scanning we need to remove all width and precision fields and flags "%+3.7f" -> "%f". BUT don't strip types like "%I64d" which includes digits. ! "%07I64d" -> "%I64d"
|
||||
@@ -53066,15 +53065,15 @@ function ImGui.InputTextEx(label, hint, buf, buf_size, size_arg, flags, callback
|
||||
in_len, c = ImStd.ImTextCharFromUtf8(clipboard, i, clipboard_end)
|
||||
i = i + in_len
|
||||
c, ret2 = InputTextFilterCharacter(g, state, c, callback, callback_user_data, true)
|
||||
if ret2 then
|
||||
break
|
||||
if not ret2 then
|
||||
break -- continue
|
||||
end
|
||||
|
||||
local c_utf8 = {0, 0, 0, 0, 0}
|
||||
ImStd.ImTextCharToUtf8(c_utf8, c)
|
||||
local out_len = ImStd.ImStrlen(c_utf8)
|
||||
clipboard_filtered:resize(clipboard_filtered.Size + out_len)
|
||||
ImStd.memmove(clipboard_filtered.Data, clipboard_filtered.Size - out_len, c_utf8, 1, out_len)
|
||||
ImStd.memmove(clipboard_filtered.Data, clipboard_filtered.Size - out_len + 1, c_utf8, 1, out_len)
|
||||
|
||||
until true
|
||||
end
|
||||
@@ -56586,7 +56585,7 @@ function ImGui.ShrinkWidths(items, first, count, width_excess, width_min)
|
||||
for n = 1, count do slice[n] = items[first + n - 1] end
|
||||
table.sort(slice, function(a, b)
|
||||
if a.Width ~= b.Width then return a.Width > b.Width end
|
||||
return a.Index < b.Index
|
||||
return a.Index > b.Index -- ShrinkWidthItemComparer: b->Index - a->Index (Width compared exactly: upstream's (int) truncation isn't a strict weak order, which table.sort rejects)
|
||||
end)
|
||||
for n = 1, count do items[first + n - 1] = slice[n] end
|
||||
local it = slice
|
||||
|
||||
+8
-9
@@ -2682,19 +2682,18 @@ end
|
||||
-- fmt = "blah blah" -> return ""
|
||||
-- fmt = "%.3f" -> return "%.3f"
|
||||
-- fmt = "hello %.3f" -> return "%.3f"
|
||||
-- TODO: temporary patch. does not look good
|
||||
-- fmt = "%.3f hello" -> return "%.3f"
|
||||
--- @param fmt string
|
||||
local function ImParseFormatTrimDecorations(fmt)
|
||||
local fmt_start = ImParseFormatFindStart(fmt)
|
||||
if string.byte(fmt, fmt_start) ~= 37 then -- '%'
|
||||
if fmt_start == nil or string.byte(fmt, fmt_start) ~= 37 then -- '%'
|
||||
return ""
|
||||
end
|
||||
--- @cast fmt_start int
|
||||
local fmt_end = ImParseFormatFindEnd(fmt, fmt_start)
|
||||
if string.byte(fmt, fmt_end) ~= 37 then
|
||||
if fmt_end > #fmt then -- If we only have leading decoration, we don't need to copy the data.
|
||||
return string.sub(fmt, fmt_start)
|
||||
end
|
||||
return string.sub(fmt, fmt_start, fmt_end)
|
||||
return string.sub(fmt, fmt_start, fmt_end - 1)
|
||||
end
|
||||
|
||||
-- - For scanning we need to remove all width and precision fields and flags "%+3.7f" -> "%f". BUT don't strip types like "%I64d" which includes digits. ! "%07I64d" -> "%I64d"
|
||||
@@ -5807,15 +5806,15 @@ function ImGui.InputTextEx(label, hint, buf, buf_size, size_arg, flags, callback
|
||||
in_len, c = ImStd.ImTextCharFromUtf8(clipboard, i, clipboard_end)
|
||||
i = i + in_len
|
||||
c, ret2 = InputTextFilterCharacter(g, state, c, callback, callback_user_data, true)
|
||||
if ret2 then
|
||||
break
|
||||
if not ret2 then
|
||||
break -- continue
|
||||
end
|
||||
|
||||
local c_utf8 = {0, 0, 0, 0, 0}
|
||||
ImStd.ImTextCharToUtf8(c_utf8, c)
|
||||
local out_len = ImStd.ImStrlen(c_utf8)
|
||||
clipboard_filtered:resize(clipboard_filtered.Size + out_len)
|
||||
ImStd.memmove(clipboard_filtered.Data, clipboard_filtered.Size - out_len, c_utf8, 1, out_len)
|
||||
ImStd.memmove(clipboard_filtered.Data, clipboard_filtered.Size - out_len + 1, c_utf8, 1, out_len)
|
||||
|
||||
until true
|
||||
end
|
||||
@@ -9327,7 +9326,7 @@ function ImGui.ShrinkWidths(items, first, count, width_excess, width_min)
|
||||
for n = 1, count do slice[n] = items[first + n - 1] end
|
||||
table.sort(slice, function(a, b)
|
||||
if a.Width ~= b.Width then return a.Width > b.Width end
|
||||
return a.Index < b.Index
|
||||
return a.Index > b.Index -- ShrinkWidthItemComparer: b->Index - a->Index (Width compared exactly: upstream's (int) truncation isn't a strict weak order, which table.sort rejects)
|
||||
end)
|
||||
for n = 1, count do items[first + n - 1] = slice[n] end
|
||||
local it = slice
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
-- Regressions vs upstream: clipboard paste filter (InputTextEx), ImParseFormatTrimDecorations (Ctrl+click temp input), ShrinkWidths tie order
|
||||
local G = require(game:GetService("ReplicatedStorage"):WaitForChild("ImGui"))
|
||||
local ImGui, ImVec2 = G.ImGui, G.ImVec2
|
||||
ImGui.CreateContext(); G.ImGui_ImplRoblox.Init()
|
||||
local io = ImGui.GetIO()
|
||||
local failed = {}
|
||||
local function check(ok, msg) if not ok then table.insert(failed, msg); print("FAIL " .. msg) end end
|
||||
|
||||
-- ShrinkWidths: equal widths sort by Index descending (upstream ShrinkWidthItemComparer), so the rounding remainder goes to the highest Index first
|
||||
local items = {}
|
||||
for i = 1, 4 do local it = G.ImGuiShrinkWidthItem(); it.Index = i - 1; it.Width = 100; it.InitialWidth = 100; items[i] = it end
|
||||
ImGui.ShrinkWidths(items, 1, 4, 2.0, 10.0)
|
||||
local w = {}
|
||||
for _, it in items do w[it.Index] = it.Width end
|
||||
check(w[3] == 100 and w[2] == 100 and w[1] == 99 and w[0] == 99, ("ShrinkWidths widths %s %s %s %s"):format(w[0], w[1], w[2], w[3]))
|
||||
|
||||
local function edit_text()
|
||||
local st = ImGui.GetCurrentContext().InputTextState
|
||||
return G.ImGui._ByteArrayToString(st.TextA.Data, 1, st.TextLen + 1)
|
||||
end
|
||||
local buf = ImGui.NewTextBuffer("", 64)
|
||||
local f, sf, di = 0, 45.0, 50
|
||||
local rects = {}
|
||||
local function rect() local a, b = ImGui.GetItemRectMin(), ImGui.GetItemRectMax(); return { ImVec2(a.x, a.y), ImVec2(b.x, b.y) } end -- copies: GetItemRectMin() returns the live LastItemData.Rect.Min
|
||||
local function click(name, ctrl)
|
||||
local r = rects[name]
|
||||
io:AddMousePosEvent((r[1].x + r[2].x) / 2, (r[1].y + r[2].y) / 2)
|
||||
if ctrl then io:AddKeyEvent(G.ImGuiMod_Ctrl, true) end
|
||||
io:AddMouseButtonEvent(0, true)
|
||||
end
|
||||
local function release() io:AddMouseButtonEvent(0, false); io:AddKeyEvent(G.ImGuiMod_Ctrl, false) end
|
||||
local function key(k) io:AddKeyEvent(k, true); io:AddKeyEvent(k, false) end
|
||||
|
||||
game:GetService("RunService").Stepped:Connect(function()
|
||||
f += 1
|
||||
G.ImGui_ImplRoblox.NewFrame()
|
||||
if f == 3 then click("t") elseif f == 4 then release() end
|
||||
-- clipboard: tab is filtered out (single line, no AllowTabInput), é is 2 bytes
|
||||
if f == 6 then ImGui.SetClipboardText("ab\tc\u{e9}"); io:AddKeyEvent(G.ImGuiMod_Ctrl, true); io:AddKeyEvent(G.ImGuiKey.V, true) end
|
||||
if f == 7 then io:AddKeyEvent(G.ImGuiKey.V, false); io:AddKeyEvent(G.ImGuiMod_Ctrl, false) end
|
||||
if f == 9 then key(G.ImGuiKey.Escape) end
|
||||
if f == 11 then click("s", true) elseif f == 12 then release() end
|
||||
if f == 14 then key(G.ImGuiKey.Escape) end
|
||||
if f == 16 then click("d", true) elseif f == 17 then release() end
|
||||
ImGui.NewFrame()
|
||||
ImGui.SetNextWindowPos(ImVec2(10, 10)); ImGui.SetNextWindowSize(ImVec2(300, 200))
|
||||
ImGui.Begin("T")
|
||||
ImGui.InputText("##t", buf, 64); rects.t = rect()
|
||||
sf = ImGui.SliderFloat("##s", sf, 0.0, 100.0, "%.0f deg"); rects.s = rect()
|
||||
di = ImGui.DragInt("##d", di, 1, 0, 100, "%d%%"); rects.d = rect()
|
||||
ImGui.End()
|
||||
ImGui.Render(); G.ImGui_ImplRoblox.RenderDrawData(ImGui.GetDrawData())
|
||||
if f == 8 then check(edit_text() == "abc\u{e9}", "paste: '" .. edit_text() .. "'") end
|
||||
if f == 13 then check(edit_text() == "45", "SliderFloat temp input: '" .. edit_text() .. "'") end
|
||||
if f == 18 then check(edit_text() == "50", "DragInt temp input: '" .. edit_text() .. "'") end
|
||||
if f == 20 and #failed == 0 then print("FIXES OK") end
|
||||
end)
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "4dbug/imgui-luau"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
registry = "https://github.com/UpliftGames/wally-index"
|
||||
realm = "shared"
|
||||
license = "MIT"
|
||||
|
||||
Reference in New Issue
Block a user