forked from mbk-lab/rui_orig
2
0
Fork 0

Added the "current" property to StackLayout

This commit is contained in:
anoshenko 2021-11-20 14:22:00 +03:00
parent 7e2804f002
commit 36e6d0a389
5 changed files with 115 additions and 35 deletions

View File

@ -1,3 +1,11 @@
# v0.4.0
* Added SetTitle and SetTitleColor function to the Session interface
* Added a listener for changing a view property value
* Added the "current" property to StackLayout
* Updated TabsLayout
* Bug fixing
# v0.3.0 # v0.3.0
* Added FilePicker * Added FilePicker

View File

@ -224,7 +224,7 @@ func (customView *CustomViewData) Append(view View) {
} }
// Insert inserts a view to the "index" position in the list of a view children // Insert inserts a view to the "index" position in the list of a view children
func (customView *CustomViewData) Insert(view View, index uint) { func (customView *CustomViewData) Insert(view View, index int) {
if customView.superView != nil { if customView.superView != nil {
if container, ok := customView.superView.(ViewsContainer); ok { if container, ok := customView.superView.(ViewsContainer); ok {
container.Insert(view, index) container.Insert(view, index)
@ -233,7 +233,7 @@ func (customView *CustomViewData) Insert(view View, index uint) {
} }
// Remove removes a view from the list of a view children and return it // Remove removes a view from the list of a view children and return it
func (customView *CustomViewData) RemoveView(index uint) View { func (customView *CustomViewData) RemoveView(index int) View {
if customView.superView != nil { if customView.superView != nil {
if container, ok := customView.superView.(ViewsContainer); ok { if container, ok := customView.superView.(ViewsContainer); ok {
return container.RemoveView(index) return container.RemoveView(index)

View File

@ -6,8 +6,6 @@ import (
"strings" "strings"
) )
// TODO PeekChangedEvent
const ( const (
// DefaultAnimation - default animation of StackLayout push // DefaultAnimation - default animation of StackLayout push
DefaultAnimation = 0 DefaultAnimation = 0
@ -33,7 +31,7 @@ type StackLayout interface {
type stackLayoutData struct { type stackLayoutData struct {
viewsContainerData viewsContainerData
peek uint peek int
pushView, popView View pushView, popView View
animationType int animationType int
onPushFinished func() onPushFinished func()
@ -66,11 +64,12 @@ func (layout *stackLayoutData) pushFinished(view View, tag string) {
layout.pushView = nil layout.pushView = nil
count := len(layout.views) count := len(layout.views)
if count > 0 { if count > 0 {
layout.peek = uint(count - 1) layout.peek = count - 1
} else { } else {
layout.peek = 0 layout.peek = 0
} }
updateInnerHTML(layout.htmlID(), layout.session) updateInnerHTML(layout.htmlID(), layout.session)
layout.propertyChangedEvent(Current)
} }
if layout.onPushFinished != nil { if layout.onPushFinished != nil {
@ -99,7 +98,13 @@ func (layout *stackLayoutData) Set(tag string, value interface{}) bool {
} }
func (layout *stackLayoutData) set(tag string, value interface{}) bool { func (layout *stackLayoutData) set(tag string, value interface{}) bool {
if tag == TransitionEndEvent { if value == nil {
layout.remove(tag)
return true
}
switch tag {
case TransitionEndEvent:
listeners, ok := valueToAnimationListeners(value) listeners, ok := valueToAnimationListeners(value)
if ok { if ok {
listeners = append(listeners, layout.pushFinished) listeners = append(listeners, layout.pushFinished)
@ -108,6 +113,46 @@ func (layout *stackLayoutData) set(tag string, value interface{}) bool {
layout.propertyChangedEvent(TransitionEndEvent) layout.propertyChangedEvent(TransitionEndEvent)
} }
return ok return ok
case Current:
setCurrent := func(index int) {
if index != layout.peek {
if layout.peek < len(layout.views) {
updateCSSProperty(layout.htmlID()+"page"+strconv.Itoa(layout.peek), "visibility", "hidden", layout.Session())
}
layout.peek = index
updateCSSProperty(layout.htmlID()+"page"+strconv.Itoa(index), "visibility", "visible", layout.Session())
layout.propertyChangedEvent(Current)
}
}
switch value := value.(type) {
case string:
text, ok := layout.session.resolveConstants(value)
if !ok {
invalidPropertyValue(tag, value)
return false
}
n, err := strconv.Atoi(strings.Trim(text, " \t"))
if err != nil {
invalidPropertyValue(tag, value)
ErrorLog(err.Error())
return false
}
setCurrent(n)
default:
n, ok := isInt(value)
if !ok {
notCompatibleType(tag, value)
return false
} else if n < 0 || n >= len(layout.views) {
ErrorLogF(`The view index "%d" of "%s" property is out of range`, n, tag)
return false
}
setCurrent(n)
}
return true
} }
return layout.viewsContainerData.set(tag, value) return layout.viewsContainerData.set(tag, value)
} }
@ -117,14 +162,30 @@ func (layout *stackLayoutData) Remove(tag string) {
} }
func (layout *stackLayoutData) remove(tag string) { func (layout *stackLayoutData) remove(tag string) {
if tag == TransitionEndEvent { switch tag {
case TransitionEndEvent:
layout.properties[TransitionEndEvent] = []func(View, string){layout.pushFinished, layout.popFinished} layout.properties[TransitionEndEvent] = []func(View, string){layout.pushFinished, layout.popFinished}
layout.propertyChangedEvent(TransitionEndEvent) layout.propertyChangedEvent(TransitionEndEvent)
} else {
case Current:
layout.set(Current, 0)
default:
layout.viewsContainerData.remove(tag) layout.viewsContainerData.remove(tag)
} }
} }
func (layout *stackLayoutData) Get(tag string) interface{} {
return layout.get(strings.ToLower(tag))
}
func (layout *stackLayoutData) get(tag string) interface{} {
if tag == Current {
return layout.peek
}
return layout.viewsContainerData.get(tag)
}
func (layout *stackLayoutData) Peek() View { func (layout *stackLayoutData) Peek() View {
if int(layout.peek) < len(layout.views) { if int(layout.peek) < len(layout.views) {
return layout.views[layout.peek] return layout.views[layout.peek]
@ -142,8 +203,9 @@ func (layout *stackLayoutData) MoveToFront(view View) bool {
updateCSSProperty(layout.htmlID()+"page"+strconv.Itoa(peek), "visibility", "hidden", layout.Session()) updateCSSProperty(layout.htmlID()+"page"+strconv.Itoa(peek), "visibility", "hidden", layout.Session())
} }
layout.peek = uint(i) layout.peek = i
updateCSSProperty(layout.htmlID()+"page"+strconv.Itoa(i), "visibility", "visible", layout.Session()) updateCSSProperty(layout.htmlID()+"page"+strconv.Itoa(i), "visibility", "visible", layout.Session())
layout.propertyChangedEvent(Current)
} }
return true return true
} }
@ -162,8 +224,9 @@ func (layout *stackLayoutData) MoveToFrontByID(viewID string) bool {
updateCSSProperty(layout.htmlID()+"page"+strconv.Itoa(peek), "visibility", "hidden", layout.Session()) updateCSSProperty(layout.htmlID()+"page"+strconv.Itoa(peek), "visibility", "hidden", layout.Session())
} }
layout.peek = uint(i) layout.peek = i
updateCSSProperty(layout.htmlID()+"page"+strconv.Itoa(i), "visibility", "visible", layout.Session()) updateCSSProperty(layout.htmlID()+"page"+strconv.Itoa(i), "visibility", "visible", layout.Session())
layout.propertyChangedEvent(Current)
} }
return true return true
} }
@ -175,31 +238,38 @@ func (layout *stackLayoutData) MoveToFrontByID(viewID string) bool {
func (layout *stackLayoutData) Append(view View) { func (layout *stackLayoutData) Append(view View) {
if view != nil { if view != nil {
layout.peek = uint(len(layout.views)) layout.peek = len(layout.views)
layout.viewsContainerData.Append(view) layout.viewsContainerData.Append(view)
layout.propertyChangedEvent(Current)
} else { } else {
ErrorLog("StackLayout.Append(nil, ....) is forbidden") ErrorLog("StackLayout.Append(nil, ....) is forbidden")
} }
} }
func (layout *stackLayoutData) Insert(view View, index uint) { func (layout *stackLayoutData) Insert(view View, index int) {
if view != nil { if view != nil {
count := uint(len(layout.views)) count := len(layout.views)
if index < count { if index < count {
layout.peek = index layout.peek = int(index)
} else { } else {
layout.peek = count layout.peek = count
} }
layout.viewsContainerData.Insert(view, index) layout.viewsContainerData.Insert(view, index)
layout.propertyChangedEvent(Current)
} else { } else {
ErrorLog("StackLayout.Insert(nil, ....) is forbidden") ErrorLog("StackLayout.Insert(nil, ....) is forbidden")
} }
} }
func (layout *stackLayoutData) RemoveView(index uint) View { func (layout *stackLayoutData) RemoveView(index int) View {
if index < 0 || index >= len(layout.views) {
return nil
}
if layout.peek > 0 { if layout.peek > 0 {
layout.peek-- layout.peek--
} }
defer layout.propertyChangedEvent(Current)
return layout.viewsContainerData.RemoveView(index) return layout.viewsContainerData.RemoveView(index)
} }
@ -254,7 +324,7 @@ func (layout *stackLayoutData) Push(view View, animation int, onPushFinished fun
} }
func (layout *stackLayoutData) Pop(animation int, onPopFinished func(View)) bool { func (layout *stackLayoutData) Pop(animation int, onPopFinished func(View)) bool {
count := uint(len(layout.views)) count := len(layout.views)
if count == 0 || layout.peek >= count { if count == 0 || layout.peek >= count {
ErrorLog("StackLayout is empty") ErrorLog("StackLayout is empty")
return false return false
@ -299,7 +369,6 @@ func (layout *stackLayoutData) Pop(animation int, onPopFinished func(View)) bool
} }
updateCSSProperty(htmlID+"pop", "transform", value, layout.session) updateCSSProperty(htmlID+"pop", "transform", value, layout.session)
layout.propertyChangedEvent(Content)
return true return true
} }

View File

@ -588,31 +588,32 @@ func (tabsLayout *tabsLayoutData) Append(view View) {
if view != nil { if view != nil {
tabsLayout.viewsContainerData.Append(view) tabsLayout.viewsContainerData.Append(view)
if len(tabsLayout.views) == 1 { if len(tabsLayout.views) == 1 {
tabsLayout.setIntProperty(Current, 0) tabsLayout.properties[Current] = 0
for _, listener := range tabsLayout.tabListener { for _, listener := range tabsLayout.tabListener {
listener(tabsLayout, 0, -1) listener(tabsLayout, 0, -1)
} }
defer tabsLayout.propertyChangedEvent(Current)
} }
updateInnerHTML(tabsLayout.htmlID(), tabsLayout.session) updateInnerHTML(tabsLayout.htmlID(), tabsLayout.session)
} }
} }
// Insert inserts view to the "index" position in view list // Insert inserts view to the "index" position in view list
func (tabsLayout *tabsLayoutData) Insert(view View, index uint) { func (tabsLayout *tabsLayoutData) Insert(view View, index int) {
if tabsLayout.views == nil { if tabsLayout.views == nil {
tabsLayout.views = []View{} tabsLayout.views = []View{}
} }
if view != nil { if view != nil {
tabsLayout.viewsContainerData.Insert(view, index) if current := tabsLayout.currentItem(); current >= int(index) {
current := tabsLayout.currentItem() tabsLayout.properties[Current] = current + 1
if current >= int(index) { defer tabsLayout.propertyChangedEvent(Current)
tabsLayout.Set(Current, current+1)
} }
tabsLayout.viewsContainerData.Insert(view, index)
} }
} }
// Remove removes view from list and return it // Remove removes view from list and return it
func (tabsLayout *tabsLayoutData) RemoveView(index uint) View { func (tabsLayout *tabsLayoutData) RemoveView(index int) View {
if tabsLayout.views == nil { if tabsLayout.views == nil {
tabsLayout.views = []View{} tabsLayout.views = []View{}
return nil return nil
@ -629,6 +630,7 @@ func (tabsLayout *tabsLayoutData) RemoveView(index uint) View {
for _, listener := range tabsLayout.tabListener { for _, listener := range tabsLayout.tabListener {
listener(tabsLayout, 0, 0) listener(tabsLayout, 0, 0)
} }
tabsLayout.propertyChangedEvent(Current)
return view return view
} }
@ -639,6 +641,7 @@ func (tabsLayout *tabsLayoutData) RemoveView(index uint) View {
for _, listener := range tabsLayout.tabListener { for _, listener := range tabsLayout.tabListener {
listener(tabsLayout, current-1, current) listener(tabsLayout, current-1, current)
} }
defer tabsLayout.propertyChangedEvent(Current)
} }
return tabsLayout.viewsContainerData.RemoveView(index) return tabsLayout.viewsContainerData.RemoveView(index)

View File

@ -14,9 +14,9 @@ type ViewsContainer interface {
// Append appends a view to the end of the list of a view children // Append appends a view to the end of the list of a view children
Append(view View) Append(view View)
// Insert inserts a view to the "index" position in the list of a view children // Insert inserts a view to the "index" position in the list of a view children
Insert(view View, index uint) Insert(view View, index int)
// Remove removes a view from the list of a view children and return it // Remove removes a view from the list of a view children and return it
RemoveView(index uint) View RemoveView(index int) View
} }
type viewsContainerData struct { type viewsContainerData struct {
@ -63,10 +63,10 @@ func (container *viewsContainerData) Append(view View) {
} }
// Insert inserts a view to the "index" position in the list of a view children // Insert inserts a view to the "index" position in the list of a view children
func (container *viewsContainerData) Insert(view View, index uint) { func (container *viewsContainerData) Insert(view View, index int) {
if view != nil { if view != nil {
htmlID := container.htmlID() htmlID := container.htmlID()
if container.views == nil || index >= uint(len(container.views)) { if container.views == nil || index < 0 || index >= len(container.views) {
container.Append(view) container.Append(view)
} else if index > 0 { } else if index > 0 {
view.setParentID(htmlID) view.setParentID(htmlID)
@ -83,21 +83,21 @@ func (container *viewsContainerData) Insert(view View, index uint) {
} }
// Remove removes view from list and return it // Remove removes view from list and return it
func (container *viewsContainerData) RemoveView(index uint) View { func (container *viewsContainerData) RemoveView(index int) View {
if container.views == nil { if container.views == nil {
container.views = []View{} container.views = []View{}
return nil return nil
} }
viewsLen := uint(len(container.views)) count := len(container.views)
if index >= viewsLen { if index < 0 || index >= count {
return nil return nil
} }
view := container.views[index] view := container.views[index]
if index == 0 { if index == 0 {
container.views = container.views[1:] container.views = container.views[1:]
} else if index == viewsLen-1 { } else if index == count-1 {
container.views = container.views[:index] container.views = container.views[:index]
} else { } else {
container.views = append(container.views[:index], container.views[index+1:]...) container.views = append(container.views[:index], container.views[index+1:]...)
@ -306,7 +306,7 @@ func AppendView(rootView View, containerID string, view View) bool {
} }
// Insert inserts a view to the "index" position in the list of a view children // Insert inserts a view to the "index" position in the list of a view children
func InsertView(rootView View, containerID string, view View, index uint) bool { func InsertView(rootView View, containerID string, view View, index int) bool {
var container ViewsContainer = nil var container ViewsContainer = nil
if containerID != "" { if containerID != "" {
container = ViewsContainerByID(rootView, containerID) container = ViewsContainerByID(rootView, containerID)
@ -327,7 +327,7 @@ func InsertView(rootView View, containerID string, view View, index uint) bool {
} }
// Remove removes a view from the list of a view children and return it // Remove removes a view from the list of a view children and return it
func RemoveView(rootView View, containerID string, index uint) View { func RemoveView(rootView View, containerID string, index int) View {
var container ViewsContainer = nil var container ViewsContainer = nil
if containerID != "" { if containerID != "" {
container = ViewsContainerByID(rootView, containerID) container = ViewsContainerByID(rootView, containerID)