Update stackLayout.go

This commit is contained in:
Alexei Anoshenko 2024-11-24 21:14:35 +02:00
parent 488368de8c
commit 91093637c7
1 changed files with 58 additions and 25 deletions

View File

@ -70,11 +70,15 @@ type StackLayout interface {
// RemovePeek removes the current View and returns it. If StackLayout is empty then it doesn't do anything and returns nil. // RemovePeek removes the current View and returns it. If StackLayout is empty then it doesn't do anything and returns nil.
RemovePeek() View RemovePeek() View
// MoveToFront makes the given View current. Returns true if successful, false otherwise. // MoveToFront makes the given View current.
MoveToFront(view View) bool // The second argument is a function called after the move to front animation ends.
// Returns true if successful, false otherwise.
MoveToFront(view View, onShown ...func(View)) bool
// MoveToFrontByID makes the View current by viewID. Returns true if successful, false otherwise. // MoveToFrontByID makes the View current by viewID.
MoveToFrontByID(viewID string) bool // The second argument is a function called after the move to front animation ends.
// Returns true if successful, false otherwise.
MoveToFrontByID(viewID string, onShown ...func(View)) bool
// Push adds a new View to the container and makes it current. // Push adds a new View to the container and makes it current.
// It is similar to Append, but the addition is done using an animation effect. // It is similar to Append, but the addition is done using an animation effect.
@ -84,29 +88,30 @@ type StackLayout interface {
// * EndToStartAnimation (2) - End-to-Beginning animation; // * EndToStartAnimation (2) - End-to-Beginning animation;
// * TopDownAnimation (3) - Top-down animation; // * TopDownAnimation (3) - Top-down animation;
// * BottomUpAnimation (4) - Bottom up animation. // * BottomUpAnimation (4) - Bottom up animation.
// The third argument `onPushFinished` is the function to be called when the animation ends. It may be nil. // The second argument `onPushFinished` is the function to be called when the animation ends.
Push(view View, onPushFinished func()) Push(view View, onPushFinished ...func())
// Pop removes the current View from the container using animation. // Pop removes the current View from the container using animation.
// The second argument `onPopFinished`` is the function to be called when the animation ends. It may be nil. // The argument `onPopFinished` is the function to be called when the animation ends.
// The function will return false if the StackLayout is empty and true if the current item has been removed. // The function will return false if the StackLayout is empty and true if the current item has been removed.
Pop(onPopFinished func(View)) bool Pop(onPopFinished ...func(View)) bool
} }
type pushFinished struct { type pushFinished struct {
peekID string peekID string
listener func() listener []func()
} }
type popFinished struct { type popFinished struct {
view View view View
listener func(View) listener []func(View)
} }
type stackLayoutData struct { type stackLayoutData struct {
viewsContainerData viewsContainerData
onPushFinished map[string]pushFinished onPushFinished map[string]pushFinished
onPopFinished map[string]popFinished onPopFinished map[string]popFinished
onMoveFinished map[string]popFinished
} }
// NewStackLayout create new StackLayout object and return it // NewStackLayout create new StackLayout object and return it
@ -129,6 +134,7 @@ func (layout *stackLayoutData) init(session Session) {
layout.systemClass = "ruiStackLayout" layout.systemClass = "ruiStackLayout"
layout.onPushFinished = map[string]pushFinished{} layout.onPushFinished = map[string]pushFinished{}
layout.onPopFinished = map[string]popFinished{} layout.onPopFinished = map[string]popFinished{}
layout.onMoveFinished = map[string]popFinished{}
layout.set = layout.setFunc layout.set = layout.setFunc
layout.remove = layout.removeFunc layout.remove = layout.removeFunc
@ -167,8 +173,10 @@ func (layout *stackLayoutData) transitionFinished(view View, tag PropertyName) {
session.removeProperty(pageID, "ontransitioncancel") session.removeProperty(pageID, "ontransitioncancel")
session.finishUpdateScript(pageID) session.finishUpdateScript(pageID)
if finished.listener != nil { for _, listener := range finished.listener {
finished.listener() if listener != nil {
listener()
}
} }
delete(layout.onPushFinished, viewID) delete(layout.onPushFinished, viewID)
layout.contentChanged() layout.contentChanged()
@ -177,8 +185,10 @@ func (layout *stackLayoutData) transitionFinished(view View, tag PropertyName) {
case "pop": case "pop":
if finished, ok := layout.onPopFinished[viewID]; ok { if finished, ok := layout.onPopFinished[viewID]; ok {
session.callFunc("removeView", viewID+"page") session.callFunc("removeView", viewID+"page")
if finished.listener != nil { for _, listener := range finished.listener {
finished.listener(finished.view) if listener != nil {
listener(finished.view)
}
} }
delete(layout.onPopFinished, viewID) delete(layout.onPopFinished, viewID)
@ -209,6 +219,15 @@ func (layout *stackLayoutData) transitionFinished(view View, tag PropertyName) {
session.removeProperty(pageID, "ontransitioncancel") session.removeProperty(pageID, "ontransitioncancel")
session.finishUpdateScript(pageID) session.finishUpdateScript(pageID)
layout.contentChanged() layout.contentChanged()
if finished, ok := layout.onMoveFinished[viewID]; ok {
for _, listener := range finished.listener {
if listener != nil {
listener(finished.view)
}
}
delete(layout.onMoveFinished, viewID)
}
} }
} }
} }
@ -250,7 +269,7 @@ func (layout *stackLayoutData) Peek() View {
return nil return nil
} }
func (layout *stackLayoutData) MoveToFront(view View) bool { func (layout *stackLayoutData) MoveToFront(view View, onShown ...func(View)) bool {
if view == nil { if view == nil {
ErrorLog(`MoveToFront(nil) forbidden`) ErrorLog(`MoveToFront(nil) forbidden`)
return false return false
@ -269,7 +288,7 @@ func (layout *stackLayoutData) MoveToFront(view View) bool {
default: default:
for i, view := range layout.views { for i, view := range layout.views {
if view.htmlID() == htmlID { if view.htmlID() == htmlID {
layout.moveToFrontByIndex(i) layout.moveToFrontByIndex(i, onShown)
return true return true
} }
} }
@ -279,7 +298,7 @@ func (layout *stackLayoutData) MoveToFront(view View) bool {
return false return false
} }
func (layout *stackLayoutData) MoveToFrontByID(viewID string) bool { func (layout *stackLayoutData) MoveToFrontByID(viewID string, onShown ...func(View)) bool {
switch count := len(layout.views); count { switch count := len(layout.views); count {
case 0: case 0:
// do nothing // do nothing
@ -292,7 +311,7 @@ func (layout *stackLayoutData) MoveToFrontByID(viewID string) bool {
default: default:
for i, view := range layout.views { for i, view := range layout.views {
if view.ID() == viewID { if view.ID() == viewID {
layout.moveToFrontByIndex(i) layout.moveToFrontByIndex(i, onShown)
return true return true
} }
} }
@ -302,7 +321,7 @@ func (layout *stackLayoutData) MoveToFrontByID(viewID string) bool {
return false return false
} }
func (layout *stackLayoutData) moveToFrontByIndex(index int) { func (layout *stackLayoutData) moveToFrontByIndex(index int, onShow []func(View)) {
count := len(layout.views) count := len(layout.views)
if index == count-1 { if index == count-1 {
@ -332,9 +351,19 @@ func (layout *stackLayoutData) moveToFrontByIndex(index int) {
session.updateCSSProperty(peekPageID, "visibility", "hidden") session.updateCSSProperty(peekPageID, "visibility", "hidden")
session.updateCSSProperty(pageID, "visibility", "visible") session.updateCSSProperty(pageID, "visibility", "visible")
layout.contentChanged() layout.contentChanged()
for _, listener := range onShow {
if listener != nil {
listener(view)
}
}
return return
} }
layout.onMoveFinished[view.htmlID()] = popFinished{
view: view,
listener: onShow,
}
buffer := allocStringBuilder() buffer := allocStringBuilder()
defer freeStringBuilder(buffer) defer freeStringBuilder(buffer)
@ -514,7 +543,7 @@ func (layout *stackLayoutData) RemoveView(index int) View {
return view return view
} }
func (layout *stackLayoutData) Push(view View, onPushFinished func()) { func (layout *stackLayoutData) Push(view View, onPushFinished ...func()) {
if view == nil { if view == nil {
ErrorLog("StackLayout.Push(nil, ....) is forbidden") ErrorLog("StackLayout.Push(nil, ....) is forbidden")
return return
@ -523,8 +552,10 @@ func (layout *stackLayoutData) Push(view View, onPushFinished func()) {
transform := GetPushTransform(layout) transform := GetPushTransform(layout)
if transform == nil { if transform == nil {
layout.Append(view) layout.Append(view)
if onPushFinished != nil { for _, listener := range onPushFinished {
onPushFinished() if listener != nil {
listener()
}
} }
return return
} }
@ -578,7 +609,7 @@ func (layout *stackLayoutData) Push(view View, onPushFinished func()) {
layout.session.updateCSSProperty(htmlID+"page", "transform", "") layout.session.updateCSSProperty(htmlID+"page", "transform", "")
} }
func (layout *stackLayoutData) Pop(onPopFinished func(View)) bool { func (layout *stackLayoutData) Pop(onPopFinished ...func(View)) bool {
count := len(layout.views) count := len(layout.views)
if count == 0 { if count == 0 {
ErrorLog("StackLayout is empty") ErrorLog("StackLayout is empty")
@ -588,8 +619,10 @@ func (layout *stackLayoutData) Pop(onPopFinished func(View)) bool {
transform := GetPushTransform(layout) transform := GetPushTransform(layout)
if transform == nil { if transform == nil {
if view := layout.RemovePeek(); view != nil { if view := layout.RemovePeek(); view != nil {
if onPopFinished != nil { for _, listener := range onPopFinished {
onPopFinished(view) if listener != nil {
listener(view)
}
} }
return true return true
} }