mirror of https://github.com/anoshenko/rui.git
Added GridAdapter
This commit is contained in:
parent
f9d7c77500
commit
d0d81907eb
|
@ -1,6 +1,7 @@
|
|||
# v0.16.0
|
||||
* Can use ListAdapter as "content" property value of ListLayout
|
||||
* The IsListItemEnabled method of the ListAdapter interface has been made optional
|
||||
* Can use GridAdapter as "content" property value of GridLayout
|
||||
* Bug fixing
|
||||
|
||||
# v0.15.0
|
||||
|
|
48
README-ru.md
48
README-ru.md
|
@ -2344,13 +2344,13 @@ ListAdapter используется для создания дочерних Vi
|
|||
Соответственно функции этого интерфейса должны возвращать количество элементов и View i-го элемента.
|
||||
|
||||
ListAdapter создает дочерние View в момент установки свойства "content".
|
||||
Для пересоздания дочерних элементов ListLayout имеет свойство UpdateContent().
|
||||
Для пересоздания дочерних элементов ListLayout имеет метод UpdateContent().
|
||||
Данный метод удаляет все дочерние View и создает их заново используя ListAdapter.
|
||||
|
||||
Внимание! При вызове метода UpdateContent() данные из старых View не переносятся в заново создаваемые.
|
||||
Вы должны сделать это в ручную.
|
||||
|
||||
Если свойство "content" присвоен не ListAdapter, то метод UpdateContent() ничего не делает.
|
||||
Если свойству "content" присвоен не ListAdapter, то метод UpdateContent() ничего не делает.
|
||||
|
||||
Вызвать метод UpdateContent можно также с помощью глобальной функции
|
||||
|
||||
|
@ -2435,6 +2435,50 @@ GridLayout является контейнером, реализующим ин
|
|||
Все дочерние элементы располагаются в ячейках таблицы. Ячейка адресуется по номеру строки и
|
||||
столбца. Номера строк и столбцов начинаются с 0.
|
||||
|
||||
### "content"
|
||||
|
||||
Свойство "content" (константа Content) определяет массив дочерних View.
|
||||
Данное свойство унаследовано от ViewsContainer.
|
||||
Также как и для ViewsContainer данному свойству можно присваивать следующие типы данных:
|
||||
|
||||
* View (преобразуется во []View содержащий один View);
|
||||
* []View;
|
||||
* string (преобразуется во []View содержащий один TextView);
|
||||
* []string (преобразуется во []View содержащий TextView);
|
||||
* []any - данный массив должен содержать только View и string (преобразуется в TextView).
|
||||
|
||||
Однако кроме этих типов данных свойству "content" GridLayout может быть назначена реализация интерфейса GridAdapter.
|
||||
|
||||
GridAdapter используется для создания дочерних View и объявлен как
|
||||
|
||||
type GridAdapter interface {
|
||||
GridColumnCount() int
|
||||
GridRowCount() int
|
||||
GridCellContent(row, column int, session Session) View
|
||||
}
|
||||
|
||||
Соответственно функции этого интерфейса должны возвращать количество столбцов и строк и View элемента в позиции (row, column).
|
||||
|
||||
Кроме этих трех обязательных методов, при реализации GridAdapter, могут быть заданы еще два опциональных:
|
||||
|
||||
GridCellColumnSpan(row, column int) int
|
||||
GridCellRowSpan(row, column int) int
|
||||
|
||||
Первый метод задает сколько столбцов занимает View в позиции (row, column) а вторая - сколько строк.
|
||||
|
||||
GridAdapter создает дочерние View в момент установки свойства "content".
|
||||
Для пересоздания дочерних элементов GridLayout имеет метод UpdateGridContent().
|
||||
Данный метод удаляет все дочерние View и создает их заново используя GridAdapter.
|
||||
|
||||
Внимание! При вызове метода UpdateGridContent() данные из старых View не переносятся в заново создаваемые.
|
||||
Вы должны сделать это в ручную.
|
||||
|
||||
Если свойству "content" присвоен не GridAdapter, то метод UpdateGridContent() ничего не делает.
|
||||
|
||||
Вызвать метод UpdateGridContent можно также с помощью глобальной функции
|
||||
|
||||
func UpdateContent(view View, subviewID ...string)
|
||||
|
||||
### "column" и "row"
|
||||
|
||||
Расположение View внутри GridLayout определяется с помощью свойств "column" и "row".
|
||||
|
|
45
README.md
45
README.md
|
@ -2410,6 +2410,51 @@ The container space of this container is split into cells in the form of a table
|
|||
All children are located in the cells of the table. A cell is addressed by row and column number.
|
||||
Row and column numbers start at 0.
|
||||
|
||||
### "content"
|
||||
|
||||
The "content" property (Content constant) defines an array of child Views.
|
||||
This property is inherited from ViewsContainer.
|
||||
Just like for ViewsContainer, this property can be assigned the following data types:
|
||||
|
||||
* View (converts to []View containing one View);
|
||||
* []View;
|
||||
* string (converts to []View containing one TextView);
|
||||
* []string (converts to []View containing TextView);
|
||||
* []any - this array must contain only View and string.
|
||||
|
||||
However, in addition to these data types, the "content" property of a GridLayout
|
||||
can be assigned an implementation of the GridAdapter interface.
|
||||
|
||||
GridAdapter is used to create child Views and is declared as
|
||||
|
||||
type GridAdapter interface {
|
||||
GridColumnCount() int
|
||||
GridRowCount() int
|
||||
GridCellContent(row, column int, session Session) View
|
||||
}
|
||||
|
||||
Accordingly, the functions of this interface must return the number of columns and rows and the View of the element at position (row, column).
|
||||
|
||||
In addition to these three required methods, when implementing a GridAdapter, two more optional ones can be specified:
|
||||
|
||||
GridCellColumnSpan(row, column int) int
|
||||
GridCellRowSpan(row, column int) int
|
||||
|
||||
The first method sets how many columns the View occupies in (row, column) position and the second sets how many rows.
|
||||
|
||||
GridAdapter creates child Views when the "content" property is set.
|
||||
To recreate child elements, GridLayout has the UpdateGridContent() method.
|
||||
This method deletes all child Views and creates them again using the GridAdapter.
|
||||
|
||||
Attention! When calling the UpdateGridContent() method, data from old Views is not transferred to newly created ones.
|
||||
You must do this manually.
|
||||
|
||||
If the "content" property is not set to a GridAdapter then the UpdateGridContent() method does nothing.
|
||||
|
||||
You can also call the UpdateGridContent method using the global function
|
||||
|
||||
func UpdateContent(view View, subviewID ...string)
|
||||
|
||||
### "column" and "row" properties
|
||||
|
||||
The location of the View inside the GridLayout is determined using the "column" and "row" properties.
|
||||
|
|
113
gridLayout.go
113
gridLayout.go
|
@ -43,13 +43,43 @@ const (
|
|||
CellHorizontalSelfAlign = "cell-horizontal-self-align"
|
||||
)
|
||||
|
||||
type GridAdapter interface {
|
||||
// GridColumnCount returns the number of columns in the grid
|
||||
GridColumnCount() int
|
||||
|
||||
// GridRowCount returns the number of rows in the grid
|
||||
GridRowCount() int
|
||||
|
||||
// GridCellContent creates a View at the given cell
|
||||
GridCellContent(row, column int, session Session) View
|
||||
}
|
||||
|
||||
// GridCellColumnSpanAdapter implements the optional method of GridAdapter interface
|
||||
type GridCellColumnSpanAdapter interface {
|
||||
// GridCellColumnSpan returns the number of columns that a cell spans.
|
||||
// Values less than 1 are ignored.
|
||||
GridCellColumnSpan(row, column int) int
|
||||
}
|
||||
|
||||
// GridCellColumnSpanAdapter implements the optional method of GridAdapter interface
|
||||
type GridCellRowSpanAdapter interface {
|
||||
// GridCellRowSpan returns the number of rows that a cell spans
|
||||
// Values less than 1 are ignored.
|
||||
GridCellRowSpan(row, column int) int
|
||||
}
|
||||
|
||||
// GridLayout - grid-container of View
|
||||
type GridLayout interface {
|
||||
ViewsContainer
|
||||
|
||||
// UpdateContent updates child Views if the "content" property value is set to GridAdapter,
|
||||
// otherwise does nothing
|
||||
UpdateGridContent()
|
||||
}
|
||||
|
||||
type gridLayoutData struct {
|
||||
viewsContainerData
|
||||
adapter GridAdapter
|
||||
}
|
||||
|
||||
// NewGridLayout create new GridLayout object and return it
|
||||
|
@ -69,6 +99,7 @@ func (gridLayout *gridLayoutData) init(session Session) {
|
|||
gridLayout.viewsContainerData.init(session)
|
||||
gridLayout.tag = "GridLayout"
|
||||
gridLayout.systemClass = "ruiGridLayout"
|
||||
gridLayout.adapter = nil
|
||||
}
|
||||
|
||||
func (gridLayout *gridLayoutData) String() string {
|
||||
|
@ -257,14 +288,19 @@ func (gridLayout *gridLayoutData) Remove(tag string) {
|
|||
}
|
||||
|
||||
func (gridLayout *gridLayoutData) remove(tag string) {
|
||||
if tag == Gap {
|
||||
switch tag {
|
||||
case Gap:
|
||||
gridLayout.remove(GridRowGap)
|
||||
gridLayout.remove(GridColumnGap)
|
||||
gridLayout.propertyChangedEvent(Gap)
|
||||
return
|
||||
|
||||
case Content:
|
||||
gridLayout.adapter = nil
|
||||
}
|
||||
|
||||
gridLayout.viewsContainerData.remove(tag)
|
||||
|
||||
if gridLayout.created {
|
||||
switch tag {
|
||||
case CellWidth:
|
||||
|
@ -289,8 +325,17 @@ func (gridLayout *gridLayoutData) set(tag string, value any) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
if tag == Gap {
|
||||
switch tag {
|
||||
case Gap:
|
||||
return gridLayout.set(GridRowGap, value) && gridLayout.set(GridColumnGap, value)
|
||||
|
||||
case Content:
|
||||
if adapter, ok := value.(GridAdapter); ok {
|
||||
gridLayout.adapter = adapter
|
||||
gridLayout.UpdateGridContent()
|
||||
return true
|
||||
}
|
||||
gridLayout.adapter = nil
|
||||
}
|
||||
|
||||
if gridLayout.viewsContainerData.set(tag, value) {
|
||||
|
@ -312,6 +357,70 @@ func (gridLayout *gridLayoutData) set(tag string, value any) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (gridLayout *gridLayoutData) UpdateGridContent() {
|
||||
if adapter := gridLayout.adapter; adapter != nil {
|
||||
gridLayout.views = []View{}
|
||||
|
||||
session := gridLayout.session
|
||||
htmlID := gridLayout.htmlID()
|
||||
isDisabled := IsDisabled(gridLayout)
|
||||
|
||||
var columnSpan GridCellColumnSpanAdapter = nil
|
||||
if span, ok := adapter.(GridCellColumnSpanAdapter); ok {
|
||||
columnSpan = span
|
||||
}
|
||||
|
||||
var rowSpan GridCellRowSpanAdapter = nil
|
||||
if span, ok := adapter.(GridCellRowSpanAdapter); ok {
|
||||
rowSpan = span
|
||||
}
|
||||
|
||||
width := adapter.GridColumnCount()
|
||||
height := adapter.GridRowCount()
|
||||
for column := 0; column < width; column++ {
|
||||
for row := 0; row < height; row++ {
|
||||
if view := adapter.GridCellContent(row, column, session); view != nil {
|
||||
view.setParentID(htmlID)
|
||||
|
||||
columnCount := 1
|
||||
if columnSpan != nil {
|
||||
columnCount = columnSpan.GridCellColumnSpan(row, column)
|
||||
}
|
||||
|
||||
if columnCount > 1 {
|
||||
view.Set(Column, Range{First: column, Last: column + columnCount - 1})
|
||||
} else {
|
||||
view.Set(Column, column)
|
||||
}
|
||||
|
||||
rowCount := 1
|
||||
if rowSpan != nil {
|
||||
rowCount = rowSpan.GridCellRowSpan(row, column)
|
||||
}
|
||||
|
||||
if rowCount > 1 {
|
||||
view.Set(Row, Range{First: row, Last: row + rowCount - 1})
|
||||
} else {
|
||||
view.Set(Row, row)
|
||||
}
|
||||
|
||||
if isDisabled {
|
||||
view.Set(Disabled, true)
|
||||
}
|
||||
|
||||
gridLayout.views = append(gridLayout.views, view)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if gridLayout.created {
|
||||
updateInnerHTML(htmlID, session)
|
||||
}
|
||||
|
||||
gridLayout.propertyChangedEvent(Content)
|
||||
}
|
||||
}
|
||||
|
||||
func gridCellSizes(properties Properties, tag string, session Session) []SizeUnit {
|
||||
if value := properties.Get(tag); value != nil {
|
||||
switch value := value.(type) {
|
||||
|
|
|
@ -245,7 +245,7 @@ func GetListColumnGap(view View, subviewID ...string) SizeUnit {
|
|||
return sizeStyledProperty(view, subviewID, ListColumnGap, false)
|
||||
}
|
||||
|
||||
// UpdateContent updates child Views of ListLayout subview if the "content" property value is set to ListAdapter,
|
||||
// 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) {
|
||||
|
@ -255,6 +255,9 @@ func UpdateContent(view View, subviewID ...string) {
|
|||
|
||||
if view != nil {
|
||||
switch view := view.(type) {
|
||||
case GridLayout:
|
||||
view.UpdateGridContent()
|
||||
|
||||
case ListLayout:
|
||||
view.UpdateContent()
|
||||
|
||||
|
|
Loading…
Reference in New Issue