Skip to content

Commit a9db1ff

Browse files
committed
🚧 up Feb 18
1 parent cb56c39 commit a9db1ff

File tree

16 files changed

+137
-111
lines changed

16 files changed

+137
-111
lines changed

imgui.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
[Window][Another Window]
2+
Pos=60,60
3+
Size=197,71
4+
Collapsed=0
5+
16
[Window][Debug##Default]
27
Pos=60,60
38
Size=400,400

src/main/kotlin/imgui/Context.kt

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,6 @@ class Context(sharedFontAtlas: FontAtlas? = null) {
8484
/** Track the window we clicked on (in order to preserve focus).
8585
* The actually window that is moved is generally MovingWindow.rootWindow. */
8686
var movingWindow: Window? = null
87-
/** .ini Settings */
88-
val settings = ArrayList<WindowSettings>()
89-
/** Save .ini Settings on disk when time reaches zero */
90-
var settingsDirtyTimer = 0f
9187
/** Stack for PushStyleColor()/PopStyleColor() */
9288
var colorModifiers = Stack<ColMod>()
9389
/** Stack for PushStyleVar()/PopStyleVar() */
@@ -265,6 +261,15 @@ class Context(sharedFontAtlas: FontAtlas? = null) {
265261
var imeInProgress = false
266262
var imeLastKey = 0
267263

264+
//------------------------------------------------------------------
265+
// Settings
266+
//------------------------------------------------------------------
267+
268+
var settingsLoaded = false
269+
/** Save .ini Settings on disk when time reaches zero */
270+
var settingsDirtyTimer = 0f
271+
/** .ini Settings for Window */
272+
val settingsWindows = ArrayList<WindowSettings>()
268273

269274
//------------------------------------------------------------------
270275
// Logging
@@ -306,6 +311,12 @@ class Context(sharedFontAtlas: FontAtlas? = null) {
306311
All those functions are not reliant on the current context. */
307312
init {
308313
if (gImGui == null) setCurrent()
314+
315+
// ~initialize(ctx)
316+
assert(!g.initialized && !g.settingsLoaded)
317+
g.logClipboard = StringBuilder()
318+
319+
g.initialized = true
309320
}
310321

311322
/** This function is merely here to free heap allocations. */
@@ -321,7 +332,8 @@ class Context(sharedFontAtlas: FontAtlas? = null) {
321332

322333
saveIniSettingsToDisk(io.iniFilename)
323334

324-
for (window in g.windows) window.clear()
335+
// Clear everything else
336+
g.windows.forEach { it.clear() }
325337
g.windows.clear()
326338
g.windowsSortBuffer.clear()
327339
g.currentWindow = null
@@ -332,7 +344,7 @@ class Context(sharedFontAtlas: FontAtlas? = null) {
332344
g.hoveredRootWindow = null
333345
g.activeIdWindow = null
334346
g.movingWindow = null
335-
g.settings.clear()
347+
g.settingsWindows.clear()
336348
g.colorModifiers.clear()
337349
g.styleModifiers.clear()
338350
g.fontStack.clear()
@@ -433,11 +445,6 @@ class IO(sharedFontAtlas: FontAtlas?) {
433445
// User Functions
434446
//------------------------------------------------------------------
435447

436-
/** Rendering function, will be called in Render().
437-
* Alternatively you can keep this to NULL and call GetDrawData() after Render() to get the same pointer.
438-
* See example applications if you are unsure of how to implement this. */
439-
var renderDrawListsFn: ((DrawData) -> Unit)? = null
440-
441448
// Optional: access OS clipboard
442449
// (default to use native Win32 clipboard on Windows, otherwise uses a private clipboard. Override to access OS clipboard on other architectures)
443450
var getClipboardTextFn: ((userData: Any) -> Unit)? = null
@@ -467,7 +474,7 @@ class IO(sharedFontAtlas: FontAtlas?) {
467474
val mouseDown = BooleanArray(5)
468475
/** Mouse wheel: 1 unit scrolls about 5 lines text. */
469476
var mouseWheel = 0f
470-
/** Mouse wheel (Horizontal). Most users don't have a mouse with an horizontal wheel, may not be filled by all back ends. */
477+
/** Mouse wheel (Horizontal). Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. */
471478
var mouseWheelH = 0f
472479
/** Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). */
473480
var mouseDrawCursor = false

src/main/kotlin/imgui/draw.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,7 +1023,7 @@ class DrawList(sharedData: DrawListSharedData?) {
10231023
val currentClipRect get() = if (_clipRectStack.isNotEmpty()) _clipRectStack.last()!! else _data.clipRectFullscreen
10241024
val currentTextureId get() = if (_textureIdStack.isNotEmpty()) _textureIdStack.last()!! else null
10251025

1026-
infix fun addTo(renderList: ArrayList<DrawList>) {
1026+
infix fun addTo(outList: ArrayList<DrawList>) {
10271027

10281028
if (cmdBuffer.empty()) return
10291029

@@ -1057,7 +1057,7 @@ class DrawList(sharedData: DrawListSharedData?) {
10571057
beginChild()/endChild() before reaching the 64K limit to split your draw commands in multiple draw lists.*/
10581058
// assert(_vtxCurrentIdx <= (1L shl (Int.BYTES * 8))) // Too many vertices in same Im See comment above.
10591059

1060-
renderList += this
1060+
outList += this
10611061
io.metricsRenderVertices += vtxBuffer.size
10621062
io.metricsRenderIndices += idxBuffer.size
10631063
}

src/main/kotlin/imgui/enums.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ enum class NavInput {
396396
fun isPressed(mode: InputReadMode) = getNavInputAmount(this, mode) > 0f
397397
}
398398

399-
/** [BETA] Gamepad/Keyboard directional navigation options */
399+
/** [BETA] Gamepad/Keyboard directional navigation flags, stored in io.NavFlags */
400400
enum class NavFlags {
401401
/** Master keyboard navigation enable flag. ::newFrame() will automatically fill io.navInputs[] based on io.keyDown[]. */
402402
EnableKeyboard,
@@ -609,7 +609,7 @@ enum class MouseCursor(val i: Int) {
609609
/** When hovering over InputText, etc. */
610610
TextInput(1),
611611
/** Unused */
612-
Move(2),
612+
ResizeAll(2),
613613
/** When hovering over an horizontal border */
614614
ResizeNS(3),
615615
/** When hovering over a vertical border or a column */

src/main/kotlin/imgui/font.kt

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,8 @@ class FontAtlas {
506506

507507
if (cursor <= MouseCursor.None || cursor >= MouseCursor.Count) return false
508508

509+
if (flags has Flags.NoMouseCursors) return false
510+
509511
val r = customRects[customRectIds[0]]
510512
assert(r.id == DefaultTexData.id)
511513
val pos = DefaultTexData.cursorDatas[cursor.i][0] + Vec2(r.x, r.y)
@@ -526,6 +528,20 @@ class FontAtlas {
526528
// Members
527529
//-------------------------------------------
528530

531+
enum class Flags {
532+
/** Don't round the height to next power of two */
533+
NoPowerOfTwoHeight,
534+
/** Don't build software mouse cursors into the atlas */
535+
NoMouseCursors;
536+
537+
val i = 1 shl ordinal
538+
}
539+
540+
infix fun Int.has(flag: Flags) = and(flag.i) != 0
541+
infix fun Int.hasnt(flag: Flags) = and(flag.i) == 0
542+
543+
/** Build flags (see ImFontAtlasFlags_) */
544+
var flags = 0
529545
/** User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you
530546
during rendering via the DrawCmd structure. */
531547
var texId = -1
@@ -608,7 +624,7 @@ class FontAtlas {
608624
// Start packing
609625
val maxTexHeight = 1024 * 32
610626
val spc = STBTTPackContext.create()
611-
if(!stbtt_PackBegin(spc, null, texSize.x, maxTexHeight, 0, texGlyphPadding, MemoryUtil.NULL))
627+
if (!stbtt_PackBegin(spc, null, texSize.x, maxTexHeight, 0, texGlyphPadding, MemoryUtil.NULL))
612628
return false
613629

614630
/* Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have
@@ -698,7 +714,7 @@ class FontAtlas {
698714
assert(bufRangesN == totalRangesCount)
699715

700716
// Create texture
701-
texSize.y = texSize.y.upperPowerOfTwo
717+
texSize.y = if (flags has Flags.NoPowerOfTwoHeight) texSize.y + 1 else texSize.y.upperPowerOfTwo
702718
texUvScale = 1f / Vec2(texSize)
703719
texPixelsAlpha8 = bufferBig(texSize.x * texSize.y)
704720
spc.pixels = texPixelsAlpha8!!
@@ -768,8 +784,11 @@ class FontAtlas {
768784
}
769785

770786
fun buildRegisterDefaultCustomRects() {
771-
if (customRectIds[0] < 0)
772-
customRectIds[0] = addCustomRectRegular(DefaultTexData.id, DefaultTexData.wHalf * 2 + 1, DefaultTexData.h)
787+
if (customRectIds[0] >= 0) return
788+
customRectIds[0] = when {
789+
flags hasnt Flags.NoMouseCursors -> addCustomRectRegular(DefaultTexData.id, DefaultTexData.wHalf * 2 + 1, DefaultTexData.h)
790+
else -> addCustomRectRegular(DefaultTexData.id, 2, 2)
791+
}
773792
}
774793

775794
fun buildSetupFont(font: Font, fontConfig: FontConfig, ascent: Float, descent: Float) {
@@ -828,21 +847,34 @@ class FontAtlas {
828847

829848
fun buildRenderDefaultTexData() {
830849

850+
assert(customRectIds[0] >= 0 && texPixelsAlpha8 != null)
831851
val r = customRects[customRectIds[0]]
832-
assert(r.width == DefaultTexData.wHalf * 2 + 1 && r.height == DefaultTexData.h)
833-
assert(r.isPacked && texPixelsAlpha8 != null)
834-
835-
// Render/copy pixels
836-
var n = 0
837-
for (y in 0 until DefaultTexData.h)
838-
for (x in 0 until DefaultTexData.wHalf) {
839-
val offset0 = r.x + x + (r.y + y) * texSize.x
840-
val offset1 = offset0 + DefaultTexData.wHalf + 1
841-
texPixelsAlpha8!![offset0] = if (DefaultTexData.pixels[n] == '.') 0xFF.b else 0x00.b
842-
texPixelsAlpha8!![offset1] = if (DefaultTexData.pixels[n] == 'X') 0xFF.b else 0x00.b
843-
n++
852+
assert(r.id == DefaultTexData.id && r.isPacked)
853+
854+
val w = texSize.x
855+
if (flags hasnt Flags.NoMouseCursors) {
856+
// Render/copy pixels
857+
assert(r.width == DefaultTexData.wHalf * 2 + 1 && r.height == DefaultTexData.h)
858+
var n = 0
859+
for (y in 0 until DefaultTexData.h)
860+
for (x in 0 until DefaultTexData.wHalf) {
861+
val offset0 = r.x + x + (r.y + y) * w
862+
val offset1 = offset0 + DefaultTexData.wHalf + 1
863+
texPixelsAlpha8!![offset0] = if (DefaultTexData.pixels[n] == '.') 0xFF.b else 0x00.b
864+
texPixelsAlpha8!![offset1] = if (DefaultTexData.pixels[n] == 'X') 0xFF.b else 0x00.b
865+
n++
866+
}
867+
} else {
868+
assert(r.width == 2 && r.height == 2)
869+
val offset = r.x.i + r.y.i * w
870+
with(texPixelsAlpha8!!) {
871+
put(offset + w + 1, 0xFF.b)
872+
put(offset + w, 0xFF.b)
873+
put(offset + 1, 0xFF.b)
874+
put(offset, 0xFF.b)
844875
}
845-
texUvWhitePixel = (r.x + 0.5f) * texUvScale
876+
}
877+
texUvWhitePixel = (Vec2(r.x, r.y) + 0.5f) * texUvScale
846878
}
847879

848880
fun buildMultiplyCalcLookupTable(inBrightenFactor: Float) = CharArray(256, {

src/main/kotlin/imgui/imgui/internal.kt

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,6 @@ interface imgui_internal {
104104

105105
fun findWindowByName(name: String) = g.windowsById[hash(name, 0)]
106106

107-
fun initialize() {
108-
109-
g.logClipboard = StringBuilder()
110-
111-
assert(g.settings.isEmpty())
112-
loadIniSettingsFromDisk(io.iniFilename)
113-
g.initialized = true
114-
}
115-
116107
fun markIniSettingsDirty() {
117108
if (g.settingsDirtyTimer <= 0f) g.settingsDirtyTimer = io.iniSavingRate
118109
}
@@ -2772,13 +2763,14 @@ interface imgui_internal {
27722763
}
27732764

27742765
val tStep = 1f / resW
2766+
val invScale = if(scaleMin == scaleMax) 0f else 1f / (scaleMax - scaleMin)
27752767

27762768
val v0 = data[(0 + valuesOffset) % valuesCount]
27772769
var t0 = 0f
27782770
// Point in the normalized space of our target rectangle
2779-
val tp0 = Vec2(t0, 1f - saturate((v0 - scaleMin) / (scaleMax - scaleMin)))
2771+
val tp0 = Vec2(t0, 1f - saturate((v0 - scaleMin) * invScale))
27802772
// Where does the zero line stands
2781-
val histogramZeroLineT = if (scaleMin * scaleMax < 0f) -scaleMin / (scaleMax - scaleMin) else if (scaleMin < 0f) 0f else 1f
2773+
val histogramZeroLineT = if (scaleMin * scaleMax < 0f) -scaleMin * invScale else if (scaleMin < 0f) 0f else 1f
27822774

27832775
val colBase = (if (plotType == PlotType.Lines) Col.PlotLines else Col.PlotHistogram).u32
27842776
val colHovered = (if (plotType == PlotType.Lines) Col.PlotLinesHovered else Col.PlotHistogramHovered).u32
@@ -2788,7 +2780,7 @@ interface imgui_internal {
27882780
val v1Idx = (t0 * itemCount + 0.5f).i
27892781
assert(v1Idx in 0 until valuesCount)
27902782
val v1 = data[(v1Idx + valuesOffset + 1) % valuesCount]
2791-
val tp1 = Vec2(t1, 1f - saturate((v1 - scaleMin) / (scaleMax - scaleMin)))
2783+
val tp1 = Vec2(t1, 1f - saturate((v1 - scaleMin) * invScale))
27922784

27932785
// NB: Draw calls are merged together by the DrawList system. Still, we should render our batch are lower level to save a bit of CPU.
27942786
val pos0 = innerBb.min.lerp(innerBb.max, tp0)

src/main/kotlin/imgui/imgui/main.kt

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import imgui.ImGui.clearDragDrop
1313
import imgui.ImGui.closePopupsOverWindow
1414
import imgui.ImGui.end
1515
import imgui.ImGui.getNavInputAmount2d
16-
import imgui.ImGui.initialize
1716
import imgui.ImGui.io
1817
import imgui.ImGui.isMousePosValid
1918
import imgui.ImGui.keepAliveId
@@ -37,23 +36,14 @@ interface imgui_main {
3736
get() = gImGui?.style
3837
?: throw Error("No current context. Did you call ImGui::Context() or ImGui::setCurrentContext()?")
3938

40-
// val style
41-
// get() = g.style
42-
// set(value) {
43-
// g.style = value
44-
// }
45-
46-
/** Same value as passed to your ::renderDrawListsFn() function. Valid after ::render() and
47-
* until the next call to ::newFrame() */
48-
val drawData get() = g.drawData.takeIf { it.valid }
49-
5039
/** start a new ImGui frame, you can submit any command from this point until NewFrame()/Render(). */
5140
fun newFrame() {
5241

5342
ptrIndices = 0
5443

5544
/* (We pass an error message in the assert expression as a trick to get it visible to programmers who are not
5645
using a debugger, as most assert handlers display their argument) */
46+
assert(g.initialized)
5747
assert(io.deltaTime >= 0f) { "Need a positive deltaTime (zero is tolerated but will cause some timing issues)" }
5848
assert(io.displaySize greaterThanEqual 0) { "Invalid displaySize value" }
5949
assert(io.fonts.fonts.size > 0) { "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?" }
@@ -69,8 +59,12 @@ interface imgui_main {
6959
if (io.navFlags has NavFlags.EnableKeyboard)
7060
assert(io.keyMap[Key.Space] != -1) { "ImGuiKey_Space is not mapped, required for keyboard navigation." }
7161

72-
// Initialize on first frame
73-
if (!g.initialized) initialize()
62+
// Load settings on first frame
63+
if (!g.settingsLoaded) {
64+
assert(g.settingsWindows.isEmpty())
65+
loadIniSettingsFromDisk(io.iniFilename)
66+
g.settingsLoaded = true
67+
}
7468

7569
g.time += io.deltaTime
7670
g.frameCount += 1
@@ -186,7 +180,7 @@ interface imgui_main {
186180
is lagging as this point.
187181
- We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect
188182
windows below it, which is useful for e.g. docking mechanisms. */
189-
g.hoveredWindow = if (g.movingWindow?.flags?.hasnt(Wf.NoInputs) == true) g.movingWindow else findHoveredWindow(io.mousePos)
183+
g.hoveredWindow = if (g.movingWindow?.flags?.hasnt(Wf.NoInputs) == true) g.movingWindow else findHoveredWindow()
190184
g.hoveredRootWindow = g.hoveredWindow?.rootWindow
191185

192186
val modalWindow = frontMostModalRootWindow
@@ -315,7 +309,8 @@ interface imgui_main {
315309
}
316310

317311

318-
/** ends the ImGui frame, finalize rendering data, then call your io.RenderDrawListsFn() function if set. */
312+
/** Ends the ImGui frame, finalize the draw data. (Obsolete: optionally call io.renderDrawListsFn if set.
313+
* Nowadays, prefer calling your render function yourself.) */
319314
fun render() {
320315

321316
assert(g.initialized) // Forgot to call ImGui::NewFrame()
@@ -365,13 +360,13 @@ interface imgui_main {
365360
setupDrawData(g.drawDataBuilder.layers[0], g.drawData)
366361
io.metricsRenderVertices = g.drawData.totalVtxCount
367362
io.metricsRenderIndices = g.drawData.totalIdxCount
368-
369-
// Render. If user hasn't set a callback then they may retrieve the draw data via GetDrawData()
370-
if (g.drawData.cmdListsCount > 0 && io.renderDrawListsFn != null)
371-
io.renderDrawListsFn!!(g.drawData)
372363
}
373364
}
374365

366+
/** Same value as passed to the old io.renderDrawListsFn function. Valid after ::render() and until the next call to
367+
* ::newFrame() */
368+
val drawData get() = g.drawData.takeIf { it.valid }
369+
375370
/** Ends the ImGui frame. Automatically called by Render()! you most likely don't need to ever call that yourself
376371
* directly. If you don't need to render you can call EndFrame() but you'll have wasted CPU already. If you don't
377372
* need to render, don't create any windows instead!

0 commit comments

Comments
 (0)