Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ jobs:
run: |
nim r tests/test_textboxes.nim
nim r -d:silkyTesting -d:nimTypeNames tests/test_inputs.nim
nim r -d:silkyTesting tests/test_subwindow.nim
nim r tests/test_atlas_png.nim
nim r -d:silkyTesting tests/test_layout.nim
nim r -d:silkyTesting tests/test_layout_regressions.nim
Expand Down
5 changes: 4 additions & 1 deletion src/silky/widgets.nim
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,10 @@ proc subWindowStart*(
titleBarInteraction = sk.interact(titleBarRect, true)

case titleBarInteraction
of Disabled, None, Error, ReleasedOutside:
of Disabled, None, Error:
sk.draw9Patch("header.9patch", sk.theme.headerPatch, sk.pos, sk.size)
of ReleasedOutside:
subWindowState.dragging = false
sk.draw9Patch("header.9patch", sk.theme.headerPatch, sk.pos, sk.size)
of Pressed:
subWindowState.dragOffset = sk.mousePos - subWindowState.pos
Expand Down
67 changes: 67 additions & 0 deletions tests/test_subwindow.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import
std/options,
vmath,
silky

when not defined(silkyTesting):
{.error: "Compile with -d:silkyTesting".}

let builder = newAtlasBuilder(1024, 4)
builder.addDir("tests/data/", "tests/data/")
builder.addFont("tests/data/IBMPlexSans-Regular.ttf", "Default", 18.0)

var show = true

proc drawSubwindow(sk: Silky, window: Window) =
## Exercise the real title-bar interaction and balanced window layout.
let state = sk.subWindowStart(
window, "Drag regression", show, some(vec2(100, 100)), some(vec2(300, 200))
)
sk.subWindowEnd(window, state)

block:
subWindowStates.clear()
var harness = newTestHarness(builder.atlas)
let window = harness.window
window.moveMouse(150, 110)
discard harness.pumpFrame(drawSubwindow, 2)
let state = subWindowStates["Drag regression"]
window.pressButton(MouseLeft)
discard harness.pumpFrame(drawSubwindow)
doAssert state.dragging, "Pressing the header must start dragging"
doAssert state.pos == vec2(100, 100)

# A held drag must keep working even when the pointer leaves the old header.
window.moveMouse(210, 160)
discard harness.pumpFrame(drawSubwindow)
doAssert state.dragging
doAssert state.pos == vec2(160, 150)
let heldPosition = state.pos

# Release well outside the current header before another frame is drawn.
window.moveMouse(450, 350)
window.releaseButton(MouseLeft)
discard harness.pumpFrame(drawSubwindow)
doAssert not state.dragging, "Releasing outside the header must end dragging"
doAssert state.pos == heldPosition, "A released drag must not move the window"

window.moveMouse(600, 450)
discard harness.pumpFrame(drawSubwindow, 2)
doAssert state.pos == heldPosition,
"Pointer movement after an outside release must not drag the window"

# A new drag starts from the last held position, not a stale drag offset.
window.moveMouse(230, 160)
discard harness.pumpFrame(drawSubwindow, 2)
window.pressButton(MouseLeft)
discard harness.pumpFrame(drawSubwindow)
doAssert state.dragging and state.pos == heldPosition
window.moveMouse(260, 180)
discard harness.pumpFrame(drawSubwindow)
doAssert state.pos == heldPosition + vec2(30, 20)
discard harness.pumpFrame(drawSubwindow, 2)
window.releaseButton(MouseLeft)
discard harness.pumpFrame(drawSubwindow)
doAssert not state.dragging, "Releasing over the header must still end dragging"

echo "Subwindow outside release stops dragging and the next drag starts cleanly"
Loading