Skip to content

Commit

Permalink
add: scroll in ScrollArea using scrollbar
Browse files Browse the repository at this point in the history
  • Loading branch information
levovix0 committed Sep 14, 2024
1 parent 7be5c36 commit 6d794f1
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 62 deletions.
12 changes: 9 additions & 3 deletions src/sigui/animations.nim
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,19 @@ template transition*[T](prop: var AnyProperty[T], dur: Duration): Animation[T] =
),
duration: dur.property
)
a.a{} = prop.unsafeVal
a.b{} = prop.unsafeVal
a.a{} = prop[]
a.b{} = prop[]

var prevPropVal = prop[]

prop.changed.connect(a.eventHandler, proc() =
a.a{} = a.currentValue
a.a{} = prevPropVal
a.b{} = prop[]
start a
, flags = {EventConnectionFlag.transition})

prop.changed.connect(a.eventHandler, proc() = prevPropVal = prop[])

a


Expand Down
65 changes: 61 additions & 4 deletions src/sigui/scrollArea.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import std/[sequtils]
import pkg/fusion/[matching]
import ./[uibase, animations, mouseArea]
import ./[uibase, events {.all.}, animations, mouseArea, dolars]

type
ScrollAreaSetting* = enum
Expand All @@ -12,8 +12,8 @@ type
shrinkScrollBarWhenNotHovered
hideScrollBarWhenNotHoveredOrScrolled

# disableAnimationsWhenScrollingUsingBar
# immediateScrollWhenClickedOnScrollBarArea
disableAnimationsWhenScrollingUsingBar
instantScrollWhenClickedOnScrollBarArea


ScrollArea* = ref object of Uiobj
Expand Down Expand Up @@ -156,6 +156,59 @@ method init*(this: ScrollArea) =
not(scrollArea.horizontalScrollBarArea.hovered[] or scrollArea.horizontalScrollBarArea.pressed[])
):
scrollArea.horizontalScrollBarShouldBeVisible[] = false


template makeScrollBar3(
this, mouseY, scrollY, targetY, scrollH, y, h, verticalScrollbarObj, verticalScrollOverFit, verticalScrollSpeed
) =
var isDraggingScrollbar: bool
var prevMouseY: float

proc moveVerticalScrollbarToMouse(mouseY: float) =
proc setScrollY(scrollArea: ScrollArea, newScrollY: float) =
if disableAnimationsWhenScrollingUsingBar in scrollArea.settings[]:
scrollArea.scrollY{} = newScrollY
scrollArea.scrollY.changed.emit({EventConnectionFlag.transition})
scrollArea.targetY[] = newScrollY
else:
scrollArea.targetY[] = newScrollY

if isDraggingScrollbar:
let d = mouseY - prevMouseY
prevMouseY = mouseY
scrollArea.setScrollY (
scrollArea.targetY[] + (d / this.h[] * (scrollArea.scrollH[] + scrollArea.verticalScrollOverFit[]))
).min(scrollArea.scrollH[] + scrollArea.verticalScrollOverFit[] - scrollArea.h[]).max(0)

else:
if instantScrollWhenClickedOnScrollBarArea in scrollArea.settings[]:
scrollArea.setScrollY (
(this.mouseY[] - scrollArea.verticalScrollbarObj[].h[] / 2) / (this.h[] - scrollArea.verticalScrollbarObj[].h[]) *
(scrollArea.scrollH[] + scrollArea.verticalScrollOverFit[] - scrollArea.h[])
).min(scrollArea.scrollH[] + scrollArea.verticalScrollOverFit[] - scrollArea.h[]).max(0)

else:
if this.mouseY[] notin (
scrollArea.verticalScrollbarObj[].y[] ..
(scrollArea.verticalScrollbarObj[].y[] + scrollArea.verticalScrollbarObj[].h[])
):
scrollArea.setScrollY (
scrollArea.targetY[] +
scrollArea.verticalScrollSpeed[] * (if this.mouseY[] < scrollArea.verticalScrollbarObj[].y[]: -1 else: 1)
).min(scrollArea.scrollH[] + scrollArea.verticalScrollOverFit[] - scrollArea.h[]).max(0)


this.pressed.changed.connectTo scrollArea:
isDraggingScrollbar = this.mouseY[] in (
scrollArea.verticalScrollbarObj[].y[] ..
(scrollArea.verticalScrollbarObj[].y[] + scrollArea.verticalScrollbarObj[].h[])
)
prevMouseY = this.mouseY[]
if (hasScrollBar in scrollArea.settings[]) and this.pressed[]: moveVerticalScrollbarToMouse(this.mouseY[])

this.mouseY.changed.connectTo scrollArea:
if (hasScrollBar in scrollArea.settings[]) and this.pressed[]: moveVerticalScrollbarToMouse(this.mouseY[])



# actual scroll area
Expand Down Expand Up @@ -205,7 +258,7 @@ method init*(this: ScrollArea) =
w = binding:
if (
shrinkScrollBarWhenNotHovered in scrollArea.settings[] and
(not scrollArea.verticalScrollBarArea.hovered[] or scrollArea.verticalScrollBarArea.pressed[])
not (scrollArea.verticalScrollBarArea.hovered[] or scrollArea.verticalScrollBarArea.pressed[])
):
scrollArea.verticalScrollBarShrinkedWidth[]
else:
Expand All @@ -219,6 +272,8 @@ method init*(this: ScrollArea) =

- this.w.transition(0.2's):
easing = outSquareEasing

makeScrollBar3(this, mouseY, scrollY, targetY, scrollH, y, h, verticalScrollBarObj, verticalScrollOverFit, verticalScrollSpeed)


- scrollArea.horizontalScrollBarArea:
Expand Down Expand Up @@ -246,6 +301,8 @@ method init*(this: ScrollArea) =

- this.h.transition(0.2's):
easing = outSquareEasing

makeScrollBar3(this, mouseX, scrollX, targetX, scrollW, x, w, horizontalScrollbarObj, horizontalScrollOverFit, horizontalScrollSpeed)


this.newChildsObject = container
Expand Down
6 changes: 3 additions & 3 deletions src/sigui/uibase.nim
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ method addChangableChildUntyped*(parent: Uiobj, child: Uiobj): CustomProperty[Ui
parent.childs[i] = v
v.parent = parent
v.recieve(ParentChanged(newParentInTree: parent))
parent.recieve(ChildAdded(child: child))
parent.recieve(ChildAdded(child: v))
),
)

Expand Down Expand Up @@ -1594,8 +1594,8 @@ macro makeLayout*(obj: Uiobj, body: untyped) =
genSym(nskLabel, "changableChildInitializationBlock")
stmtList:
discard checkCtor ctor
let
updateProc = genSym(nskProc)

let updateProc = genSym(nskProc)

asgn:
prop
Expand Down
89 changes: 37 additions & 52 deletions tests/t_todoapp.nim
Original file line number Diff line number Diff line change
Expand Up @@ -78,62 +78,47 @@ test "todo app":
taskName.pushState()
taskName.text[] = ""

- ClipRect():
- ScrollArea():
this.fillHorizontal(parent, 20)
bottom = parent.bottom - 20
top = taskAdder.bottom + 20

- MouseArea():
this.fill parent

- Uiobj():
w := parent.w[]

- this.y.transition(0.2's):
easing = outSquareEasing

var targetY = 0'f32.property
this.binding y: targetY[]

parent.scrolled.connectTo this, delta:
targetY[] = (targetY[] - delta.y * 56).min(0).max(-(app.layout[].h[] - 56).max(0))

app.layout --- Layout():
this.binding w: parent.w[]

orientation = vertical
gap = 5

for i in 0..app.tasks.high:
template task: auto = app.tasks[i]

- Layout():
spacing = 10
align = center

- Switch(isOn: task.complete[].property):
color = color(0.43, 0.15, 0.76)

isOn := task.complete[]
this.bindingValue task.complete[]: this.isOn[]

- UiText():
text = task.name

this.binding font:
let it = typeface.withSize(24)
it.strikethrough = task.complete[]
it

this.binding color:
if mouse.pressed[]: color(0.2, 0.2, 0.2)
elif mouse.hovered[]: color(0.4, 0.4, 0.4)
else: color(0, 0, 0)

- MouseArea() as mouse:
this.fill parent
this.mouseDownAndUpInside.connectTo this:
task.complete[] = not task.complete[]
app.layout --- Layout():
this.binding w: parent.w[]

orientation = vertical
gap = 5

for i in 0..app.tasks.high:
template task: auto = app.tasks[i]

- Layout():
spacing = 10
align = center

- Switch(isOn: task.complete[].property):
color = color(0.43, 0.15, 0.76)

isOn := task.complete[]
this.bindingValue task.complete[]: this.isOn[]

- UiText():
text = task.name

this.binding font:
let it = typeface.withSize(24)
it.strikethrough = task.complete[]
it

this.binding color:
if mouse.pressed[]: color(0.2, 0.2, 0.2)
elif mouse.hovered[]: color(0.4, 0.4, 0.4)
else: color(0, 0, 0)

- MouseArea() as mouse:
this.fill parent
this.mouseDownAndUpInside.connectTo this:
task.complete[] = not task.complete[]

app.tasksChanged.connectTo app:
app.layout[] = Layout()
Expand Down

0 comments on commit 6d794f1

Please sign in to comment.