mirror of https://github.com/anoshenko/rui.git
332 lines
6.7 KiB
Go
332 lines
6.7 KiB
Go
package rui
|
|
|
|
type TableAdapter interface {
|
|
RowCount() int
|
|
ColumnCount() int
|
|
Cell(row, column int) interface{}
|
|
}
|
|
|
|
type TableColumnStyle interface {
|
|
ColumnStyle(column int) Params
|
|
}
|
|
|
|
type TableRowStyle interface {
|
|
RowStyle(row int) Params
|
|
}
|
|
|
|
type TableCellStyle interface {
|
|
CellStyle(row, column int) Params
|
|
}
|
|
|
|
type SimpleTableAdapter interface {
|
|
TableAdapter
|
|
TableCellStyle
|
|
}
|
|
|
|
type simpleTableAdapter struct {
|
|
content [][]interface{}
|
|
columnCount int
|
|
}
|
|
|
|
type TextTableAdapter interface {
|
|
TableAdapter
|
|
}
|
|
|
|
type textTableAdapter struct {
|
|
content [][]string
|
|
columnCount int
|
|
}
|
|
|
|
type VerticalTableJoin struct {
|
|
}
|
|
|
|
type HorizontalTableJoin struct {
|
|
}
|
|
|
|
func NewSimpleTableAdapter(content [][]interface{}) SimpleTableAdapter {
|
|
if content == nil {
|
|
return nil
|
|
}
|
|
|
|
adapter := new(simpleTableAdapter)
|
|
adapter.content = content
|
|
adapter.columnCount = 0
|
|
for _, row := range content {
|
|
if row != nil {
|
|
columnCount := len(row)
|
|
if adapter.columnCount < columnCount {
|
|
adapter.columnCount = columnCount
|
|
}
|
|
}
|
|
}
|
|
|
|
return adapter
|
|
}
|
|
|
|
func (adapter *simpleTableAdapter) RowCount() int {
|
|
if adapter.content != nil {
|
|
return len(adapter.content)
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (adapter *simpleTableAdapter) ColumnCount() int {
|
|
return adapter.columnCount
|
|
}
|
|
|
|
func (adapter *simpleTableAdapter) Cell(row, column int) interface{} {
|
|
if adapter.content != nil && row >= 0 && row < len(adapter.content) &&
|
|
adapter.content[row] != nil && column >= 0 && column < len(adapter.content[row]) {
|
|
return adapter.content[row][column]
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (adapter *simpleTableAdapter) CellStyle(row, column int) Params {
|
|
if adapter.content == nil {
|
|
return nil
|
|
}
|
|
|
|
getColumnSpan := func() int {
|
|
count := 0
|
|
for i := column + 1; i < adapter.columnCount; i++ {
|
|
next := adapter.Cell(row, i)
|
|
switch next.(type) {
|
|
case HorizontalTableJoin:
|
|
count++
|
|
|
|
default:
|
|
return count
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
getRowSpan := func() int {
|
|
rowCount := len(adapter.content)
|
|
count := 0
|
|
for i := row + 1; i < rowCount; i++ {
|
|
next := adapter.Cell(i, column)
|
|
switch next.(type) {
|
|
case VerticalTableJoin:
|
|
count++
|
|
|
|
default:
|
|
return count
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
columnSpan := getColumnSpan()
|
|
rowSpan := getRowSpan()
|
|
|
|
var params Params = nil
|
|
if rowSpan > 0 {
|
|
params = Params{RowSpan: rowSpan + 1}
|
|
}
|
|
|
|
if columnSpan > 0 {
|
|
if params == nil {
|
|
params = Params{ColumnSpan: columnSpan + 1}
|
|
} else {
|
|
params[ColumnSpan] = columnSpan
|
|
}
|
|
}
|
|
|
|
return params
|
|
}
|
|
|
|
func NewTextTableAdapter(content [][]string) TextTableAdapter {
|
|
if content == nil {
|
|
return nil
|
|
}
|
|
|
|
adapter := new(textTableAdapter)
|
|
adapter.content = content
|
|
adapter.columnCount = 0
|
|
for _, row := range content {
|
|
if row != nil {
|
|
columnCount := len(row)
|
|
if adapter.columnCount < columnCount {
|
|
adapter.columnCount = columnCount
|
|
}
|
|
}
|
|
}
|
|
|
|
return adapter
|
|
}
|
|
|
|
func (adapter *textTableAdapter) RowCount() int {
|
|
if adapter.content != nil {
|
|
return len(adapter.content)
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (adapter *textTableAdapter) ColumnCount() int {
|
|
return adapter.columnCount
|
|
}
|
|
|
|
func (adapter *textTableAdapter) Cell(row, column int) interface{} {
|
|
if adapter.content != nil && row >= 0 && row < len(adapter.content) &&
|
|
adapter.content[row] != nil && column >= 0 && column < len(adapter.content[row]) {
|
|
return adapter.content[row][column]
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type simpleTableRowStyle struct {
|
|
params []Params
|
|
}
|
|
|
|
func (style *simpleTableRowStyle) RowStyle(row int) Params {
|
|
if row < len(style.params) {
|
|
params := style.params[row]
|
|
if len(params) > 0 {
|
|
return params
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (table *tableViewData) setRowStyle(value interface{}) bool {
|
|
newSimpleTableRowStyle := func(params []Params) TableRowStyle {
|
|
if len(params) == 0 {
|
|
return nil
|
|
}
|
|
result := new(simpleTableRowStyle)
|
|
result.params = params
|
|
return result
|
|
}
|
|
|
|
switch value := value.(type) {
|
|
case TableRowStyle:
|
|
table.properties[RowStyle] = value
|
|
|
|
case []Params:
|
|
if style := newSimpleTableRowStyle(value); style != nil {
|
|
table.properties[RowStyle] = style
|
|
} else {
|
|
delete(table.properties, RowStyle)
|
|
}
|
|
|
|
case DataNode:
|
|
if value.Type() == ArrayNode {
|
|
params := make([]Params, value.ArraySize())
|
|
for i, element := range value.ArrayElements() {
|
|
params[i] = Params{}
|
|
if element.IsObject() {
|
|
obj := element.Object()
|
|
for k := 0; k < obj.PropertyCount(); k++ {
|
|
if prop := obj.Property(k); prop != nil && prop.Type() == TextNode {
|
|
params[i][prop.Tag()] = prop.Text()
|
|
}
|
|
}
|
|
} else {
|
|
params[i][Style] = element.Value()
|
|
}
|
|
}
|
|
if style := newSimpleTableRowStyle(params); style != nil {
|
|
table.properties[RowStyle] = style
|
|
} else {
|
|
delete(table.properties, RowStyle)
|
|
}
|
|
} else {
|
|
return false
|
|
}
|
|
|
|
default:
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (table *tableViewData) getRowStyle() TableRowStyle {
|
|
for _, tag := range []string{RowStyle, Content} {
|
|
if value := table.getRaw(tag); value != nil {
|
|
if style, ok := value.(TableRowStyle); ok {
|
|
return style
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type simpleTableColumnStyle struct {
|
|
params []Params
|
|
}
|
|
|
|
func (style *simpleTableColumnStyle) ColumnStyle(row int) Params {
|
|
if row < len(style.params) {
|
|
params := style.params[row]
|
|
if len(params) > 0 {
|
|
return params
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (table *tableViewData) setColumnStyle(value interface{}) bool {
|
|
newSimpleTableColumnStyle := func(params []Params) TableColumnStyle {
|
|
if len(params) == 0 {
|
|
return nil
|
|
}
|
|
result := new(simpleTableColumnStyle)
|
|
result.params = params
|
|
return result
|
|
}
|
|
|
|
switch value := value.(type) {
|
|
case TableColumnStyle:
|
|
table.properties[ColumnStyle] = value
|
|
|
|
case []Params:
|
|
if style := newSimpleTableColumnStyle(value); style != nil {
|
|
table.properties[ColumnStyle] = style
|
|
} else {
|
|
delete(table.properties, ColumnStyle)
|
|
}
|
|
|
|
case DataNode:
|
|
if value.Type() == ArrayNode {
|
|
params := make([]Params, value.ArraySize())
|
|
for i, element := range value.ArrayElements() {
|
|
params[i] = Params{}
|
|
if element.IsObject() {
|
|
obj := element.Object()
|
|
for k := 0; k < obj.PropertyCount(); k++ {
|
|
if prop := obj.Property(k); prop != nil && prop.Type() == TextNode {
|
|
params[i][prop.Tag()] = prop.Text()
|
|
}
|
|
}
|
|
} else {
|
|
params[i][Style] = element.Value()
|
|
}
|
|
}
|
|
if style := newSimpleTableColumnStyle(params); style != nil {
|
|
table.properties[ColumnStyle] = style
|
|
} else {
|
|
delete(table.properties, ColumnStyle)
|
|
}
|
|
} else {
|
|
return false
|
|
}
|
|
|
|
default:
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (table *tableViewData) getColumnStyle() TableColumnStyle {
|
|
for _, tag := range []string{ColumnStyle, Content} {
|
|
if value := table.getRaw(tag); value != nil {
|
|
if style, ok := value.(TableColumnStyle); ok {
|
|
return style
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|