rui_orig/listLayout.go

284 lines
8.3 KiB
Go
Raw Normal View History

2021-09-07 17:36:50 +03:00
package rui
import (
"strings"
)
// Constants which represent values of the "orientation" property of the [ListLayout]
2021-09-07 17:36:50 +03:00
const (
// TopDownOrientation - subviews are arranged from top to bottom. Synonym of VerticalOrientation
TopDownOrientation = 0
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// StartToEndOrientation - subviews are arranged from left to right. Synonym of HorizontalOrientation
StartToEndOrientation = 1
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// BottomUpOrientation - subviews are arranged from bottom to top
BottomUpOrientation = 2
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// EndToStartOrientation - subviews are arranged from right to left
EndToStartOrientation = 3
)
2024-04-23 19:34:36 +03:00
// Constants which represent values of the "list-wrap" property of the [ListLayout]
const (
// ListWrapOff - subviews are scrolled and "true" if a new row/column starts
ListWrapOff = 0
2024-04-23 19:34:36 +03:00
// ListWrapOn - the new row/column starts at bottom/right
ListWrapOn = 1
2024-04-23 19:34:36 +03:00
// ListWrapReverse - the new row/column starts at top/left
ListWrapReverse = 2
2021-09-07 17:36:50 +03:00
)
// ListLayout represents a ListLayout view
2021-09-07 17:36:50 +03:00
type ListLayout interface {
ViewsContainer
// UpdateContent updates child Views if the "content" property value is set to ListAdapter,
// otherwise does nothing
UpdateContent()
2021-09-07 17:36:50 +03:00
}
type listLayoutData struct {
viewsContainerData
adapter ListAdapter
2021-09-07 17:36:50 +03:00
}
// NewListLayout create new ListLayout object and return it
func NewListLayout(session Session, params Params) ListLayout {
view := new(listLayoutData)
view.init(session)
2021-09-07 17:36:50 +03:00
setInitParams(view, params)
return view
}
func newListLayout(session Session) View {
2024-11-13 12:56:39 +03:00
//return NewListLayout(session, nil)
return new(listLayoutData)
2021-09-07 17:36:50 +03:00
}
// Init initialize fields of ViewsAlignContainer by default values
func (listLayout *listLayoutData) init(session Session) {
listLayout.viewsContainerData.init(session)
2021-09-07 17:36:50 +03:00
listLayout.tag = "ListLayout"
listLayout.systemClass = "ruiListLayout"
2024-11-13 12:56:39 +03:00
listLayout.normalize = normalizeListLayoutTag
listLayout.get = listLayout.getFunc
2024-11-13 12:56:39 +03:00
listLayout.set = listLayout.setFunc
listLayout.remove = listLayout.removeFunc
listLayout.changed = listLayout.propertyChanged
2021-09-07 17:36:50 +03:00
2022-05-22 12:54:02 +03:00
}
2024-11-13 12:56:39 +03:00
func normalizeListLayoutTag(tag PropertyName) PropertyName {
tag = defaultNormalize(tag)
switch tag {
case "wrap":
tag = ListWrap
case "row-gap":
return ListRowGap
case ColumnGap:
return ListColumnGap
}
return tag
}
func (listLayout *listLayoutData) getFunc(tag PropertyName) any {
2024-11-13 12:56:39 +03:00
switch tag {
case Gap:
if rowGap := GetListRowGap(listLayout); rowGap.Equal(GetListColumnGap(listLayout)) {
return rowGap
}
return AutoSize()
2024-11-13 12:56:39 +03:00
case Content:
if listLayout.adapter != nil {
return listLayout.adapter
}
}
return listLayout.viewsContainerData.getFunc(tag)
2021-09-07 17:36:50 +03:00
}
func (listLayout *listLayoutData) removeFunc(tag PropertyName) []PropertyName {
switch tag {
case Gap:
2024-11-13 12:56:39 +03:00
result := []PropertyName{}
for _, tag := range []PropertyName{ListRowGap, ListColumnGap} {
if listLayout.getRaw(tag) != nil {
listLayout.setRaw(tag, nil)
result = append(result, tag)
}
}
return result
case Content:
listLayout.viewsContainerData.removeFunc(Content)
listLayout.adapter = nil
2024-11-13 12:56:39 +03:00
return []PropertyName{Content}
}
return listLayout.viewsContainerData.removeFunc(tag)
2021-09-07 17:36:50 +03:00
}
func (listLayout *listLayoutData) setFunc(tag PropertyName, value any) []PropertyName {
switch tag {
case Gap:
result := listLayout.setFunc(ListRowGap, value)
2024-11-13 12:56:39 +03:00
if result != nil {
if gap := listLayout.getRaw(ListRowGap); gap != nil {
listLayout.setRaw(ListColumnGap, gap)
result = append(result, ListColumnGap)
}
}
return result
case Content:
if adapter, ok := value.(ListAdapter); ok {
listLayout.adapter = adapter
2024-11-13 12:56:39 +03:00
listLayout.createContent()
} else if listLayout.setContent(value) {
listLayout.adapter = nil
} else {
return nil
}
2024-11-13 12:56:39 +03:00
return []PropertyName{Content}
}
return listLayout.viewsContainerData.setFunc(tag, value)
2024-11-13 12:56:39 +03:00
}
func (listLayout *listLayoutData) propertyChanged(tag PropertyName) {
2024-11-13 12:56:39 +03:00
switch tag {
case Orientation, ListWrap, HorizontalAlign, VerticalAlign:
updateCSSStyle(listLayout.htmlID(), listLayout.Session())
2024-11-13 12:56:39 +03:00
default:
listLayout.viewsContainerData.propertyChanged(tag)
2021-09-07 17:36:50 +03:00
}
}
func (listLayout *listLayoutData) htmlSubviews(self View, buffer *strings.Builder) {
if listLayout.views != nil {
for _, view := range listLayout.views {
view.addToCSSStyle(map[string]string{`flex`: `0 0 auto`})
2024-11-21 09:25:46 +03:00
viewHTML(view, buffer, "")
2021-09-07 17:36:50 +03:00
}
}
}
2024-11-13 12:56:39 +03:00
func (listLayout *listLayoutData) createContent() bool {
if adapter := listLayout.adapter; adapter != nil {
listLayout.views = []View{}
session := listLayout.session
htmlID := listLayout.htmlID()
isDisabled := IsDisabled(listLayout)
count := adapter.ListSize()
for i := 0; i < count; i++ {
if view := adapter.ListItem(i, session); view != nil {
view.setParentID(htmlID)
if isDisabled {
view.Set(Disabled, true)
}
listLayout.views = append(listLayout.views, view)
}
}
2024-11-13 12:56:39 +03:00
return true
}
return false
}
func (listLayout *listLayoutData) UpdateContent() {
if listLayout.createContent() {
if listLayout.created {
2024-11-13 12:56:39 +03:00
updateInnerHTML(listLayout.htmlID(), listLayout.session)
}
2024-11-13 12:56:39 +03:00
if listener, ok := listLayout.changeListener[Content]; ok {
listener(listLayout, Content)
}
}
}
2021-09-07 17:36:50 +03:00
// GetListVerticalAlign returns the vertical align of a ListLayout or ListView sibview:
// TopAlign (0), BottomAlign (1), CenterAlign (2), or StretchAlign (3)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
func GetListVerticalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, VerticalAlign, TopAlign, false)
2021-09-07 17:36:50 +03:00
}
// GetListHorizontalAlign returns the vertical align of a ListLayout or ListView subview:
// LeftAlign (0), RightAlign (1), CenterAlign (2), or StretchAlign (3)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
func GetListHorizontalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, HorizontalAlign, LeftAlign, false)
2021-09-07 17:36:50 +03:00
}
// GetListOrientation returns the orientation of a ListLayout or ListView subview:
// TopDownOrientation (0), StartToEndOrientation (1), BottomUpOrientation (2), or EndToStartOrientation (3)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
func GetListOrientation(view View, subviewID ...string) int {
if len(subviewID) > 0 && subviewID[0] != "" {
view = ViewByID(view, subviewID[0])
2021-09-07 17:36:50 +03:00
}
2021-11-11 13:23:41 +03:00
if view != nil {
if orientation, ok := valueToOrientation(view.Get(Orientation), view.Session()); ok {
return orientation
}
2022-05-23 15:22:14 +03:00
if value := valueFromStyle(view, Orientation); value != nil {
2021-11-11 13:23:41 +03:00
if orientation, ok := valueToOrientation(value, view.Session()); ok {
return orientation
}
}
2021-09-07 17:36:50 +03:00
}
2021-11-11 13:23:41 +03:00
return 0
2021-09-07 17:36:50 +03:00
}
// GetListWrap returns the wrap type of a ListLayout or ListView subview:
2022-07-28 12:41:50 +03:00
// ListWrapOff (0), ListWrapOn (1), or ListWrapReverse (2)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
func GetListWrap(view View, subviewID ...string) int {
2022-07-28 12:41:50 +03:00
return enumStyledProperty(view, subviewID, ListWrap, ListWrapOff, false)
2021-09-07 17:36:50 +03:00
}
// GetListRowGap returns the gap between ListLayout or ListView rows.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
func GetListRowGap(view View, subviewID ...string) SizeUnit {
return sizeStyledProperty(view, subviewID, ListRowGap, false)
}
// GetListColumnGap returns the gap between ListLayout or ListView columns.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
func GetListColumnGap(view View, subviewID ...string) SizeUnit {
return sizeStyledProperty(view, subviewID, ListColumnGap, false)
}
2024-06-06 16:20:15 +03:00
// UpdateContent updates child Views of ListLayout/GridLayout subview if the "content" property value is set to ListAdapter/GridAdapter,
// otherwise does nothing.
// If the second argument (subviewID) is not specified or it is "" then the first argument (view) updates.
func UpdateContent(view View, subviewID ...string) {
if len(subviewID) > 0 && subviewID[0] != "" {
view = ViewByID(view, subviewID[0])
}
if view != nil {
switch view := view.(type) {
2024-06-06 16:20:15 +03:00
case GridLayout:
view.UpdateGridContent()
case ListLayout:
view.UpdateContent()
case ListView:
view.ReloadListViewData()
}
}
}