From 15a11dc558cc661e90c9efad00ec09d11a810034 Mon Sep 17 00:00:00 2001 From: anoshenko Date: Wed, 5 Jan 2022 18:33:18 +0300 Subject: [PATCH] Added TableView properties --- propertySet.go | 5 + tableView.go | 274 +++++++++++++++++++++++++++++++++++++++++++++- tableViewUtils.go | 84 ++++++++++++++ 3 files changed, 362 insertions(+), 1 deletion(-) create mode 100644 tableViewUtils.go diff --git a/propertySet.go b/propertySet.go index 5948b8a..414a0b2 100644 --- a/propertySet.go +++ b/propertySet.go @@ -412,6 +412,11 @@ var enumProperties = map[string]struct { "", []string{"none", "metadata", "auto"}, }, + SelectionMode: { + []string{"none", "cell", "row"}, + "", + []string{"none", "cell", "row"}, + }, } func notCompatibleType(tag string, value interface{}) { diff --git a/tableView.go b/tableView.go index b5d82ba..0c7a90f 100644 --- a/tableView.go +++ b/tableView.go @@ -11,139 +11,217 @@ const ( // The "table-vertical-align" int property sets the vertical alignment of the content inside a table cell. // Valid values are LeftAlign (0), RightAlign (1), CenterAlign (2), and BaselineAlign (3, 4) TableVerticalAlign = "table-vertical-align" + // HeadHeight is the constant for the "head-height" property tag. // The "head-height" int property sets the number of rows in the table header. // The default value is 0 (no header) HeadHeight = "head-height" + // HeadStyle is the constant for the "head-style" property tag. // The "head-style" string property sets the header style name HeadStyle = "head-style" + // FootHeight is the constant for the "foot-height" property tag. // The "foot-height" int property sets the number of rows in the table footer. // The default value is 0 (no footer) FootHeight = "foot-height" + // FootStyle is the constant for the "foot-style" property tag. // The "foot-style" string property sets the footer style name FootStyle = "foot-style" + // RowSpan is the constant for the "row-span" property tag. // The "row-span" int property sets the number of table row to span. // Used only when specifying cell parameters in the implementation of TableCellStyle RowSpan = "row-span" + // ColumnSpan is the constant for the "column-span" property tag. // The "column-span" int property sets the number of table column to span. // Used only when specifying cell parameters in the implementation of TableCellStyle ColumnSpan = "column-span" + // RowStyle is the constant for the "row-style" property tag. // The "row-style" property sets the adapter which specifies styles of each table row. // This property can be assigned or by an implementation of TableRowStyle interface, or by an array of Params. RowStyle = "row-style" + // ColumnStyle is the constant for the "column-style" property tag. // The "column-style" property sets the adapter which specifies styles of each table column. // This property can be assigned or by an implementation of TableColumnStyle interface, or by an array of Params. ColumnStyle = "column-style" + // CellStyle is the constant for the "cell-style" property tag. // The "cell-style" property sets the adapter which specifies styles of each table cell. // This property can be assigned only by an implementation of TableCellStyle interface. CellStyle = "cell-style" + // CellPadding is the constant for the "cell-padding" property tag. // The "cell-padding" Bounds property sets the padding area on all four sides of a table call at once. // An element's padding area is the space between its content and its border. CellPadding = "cell-padding" + // CellPaddingLeft is the constant for the "cell-padding-left" property tag. // The "cell-padding-left" SizeUnit property sets the width of the padding area to the left of a cell content. // An element's padding area is the space between its content and its border. CellPaddingLeft = "cell-padding-left" + // CellPaddingRight is the constant for the "cell-padding-right" property tag. // The "cell-padding-right" SizeUnit property sets the width of the padding area to the left of a cell content. // An element's padding area is the space between its content and its border. CellPaddingRight = "cell-padding-right" + // CellPaddingTop is the constant for the "cell-padding-top" property tag. // The "cell-padding-top" SizeUnit property sets the height of the padding area to the top of a cell content. // An element's padding area is the space between its content and its border. CellPaddingTop = "cell-padding-top" + // CellPaddingBottom is the constant for the "cell-padding-bottom" property tag. // The "cell-padding-bottom" SizeUnit property sets the height of the padding area to the bottom of a cell content. CellPaddingBottom = "cell-padding-bottom" + // CellBorder is the constant for the "cell-border" property tag. // The "cell-border" property sets a table cell's border. It sets the values of a border width, style, and color. // This property can be assigned a value of BorderProperty type, or ViewBorder type, or BorderProperty text representation. CellBorder = "cell-border" + // CellBorderLeft is the constant for the "cell-border-left" property tag. // The "cell-border-left" property sets a view's left border. It sets the values of a border width, style, and color. // This property can be assigned a value of BorderProperty type, or ViewBorder type, or BorderProperty text representation. CellBorderLeft = "cell-border-left" + // CellBorderRight is the constant for the "cell-border-right" property tag. // The "cell-border-right" property sets a view's right border. It sets the values of a border width, style, and color. // This property can be assigned a value of BorderProperty type, or ViewBorder type, or BorderProperty text representation. CellBorderRight = "cell-border-right" + // CellBorderTop is the constant for the "cell-border-top" property tag. // The "cell-border-top" property sets a view's top border. It sets the values of a border width, style, and color. // This property can be assigned a value of BorderProperty type, or ViewBorder type, or BorderProperty text representation. CellBorderTop = "cell-border-top" + // CellBorderBottom is the constant for the "cell-border-bottom" property tag. // The "cell-border-bottom" property sets a view's bottom border. It sets the values of a border width, style, and color. // This property can be assigned a value of BorderProperty type, or ViewBorder type, or BorderProperty text representation. CellBorderBottom = "cell-border-bottom" + // CellBorderStyle is the constant for the "cell-border-style" property tag. // The "cell-border-style" int property sets the line style for all four sides of a table cell's border. // Valid values are NoneLine (0), SolidLine (1), DashedLine (2), DottedLine (3), and DoubleLine (4). CellBorderStyle = "cell-border-style" + // CellBorderLeftStyle is the constant for the "cell-border-left-style" property tag. // The "cell-border-left-style" int property sets the line style of a table cell's left border. // Valid values are NoneLine (0), SolidLine (1), DashedLine (2), DottedLine (3), and DoubleLine (4). CellBorderLeftStyle = "cell-border-left-style" + // CellBorderRightStyle is the constant for the "cell-border-right-style" property tag. // The "cell-border-right-style" int property sets the line style of a table cell's right border. // Valid values are NoneLine (0), SolidLine (1), DashedLine (2), DottedLine (3), and DoubleLine (4). CellBorderRightStyle = "cell-border-right-style" + // CellBorderTopStyle is the constant for the "cell-border-top-style" property tag. // The "cell-border-top-style" int property sets the line style of a table cell's top border. // Valid values are NoneLine (0), SolidLine (1), DashedLine (2), DottedLine (3), and DoubleLine (4). CellBorderTopStyle = "cell-border-top-style" + // CellBorderBottomStyle is the constant for the "cell-border-bottom-style" property tag. // The "cell-border-bottom-style" int property sets the line style of a table cell's bottom border. // Valid values are NoneLine (0), SolidLine (1), DashedLine (2), DottedLine (3), and DoubleLine (4). CellBorderBottomStyle = "cell-border-bottom-style" + // CellBorderWidth is the constant for the "cell-border-width" property tag. // The "cell-border-width" property sets the line width for all four sides of a table cell's border. CellBorderWidth = "cell-border-width" + // CellBorderLeftWidth is the constant for the "cell-border-left-width" property tag. // The "cell-border-left-width" SizeUnit property sets the line width of a table cell's left border. CellBorderLeftWidth = "cell-border-left-width" + // CellBorderRightWidth is the constant for the "cell-border-right-width" property tag. // The "cell-border-right-width" SizeUnit property sets the line width of a table cell's right border. CellBorderRightWidth = "cell-border-right-width" + // CellBorderTopWidth is the constant for the "cell-border-top-width" property tag. // The "cell-border-top-width" SizeUnit property sets the line width of a table cell's top border. CellBorderTopWidth = "cell-border-top-width" + // CellBorderBottomWidth is the constant for the "cell-border-bottom-width" property tag. // The "cell-border-bottom-width" SizeUnit property sets the line width of a table cell's bottom border. CellBorderBottomWidth = "cell-border-bottom-width" + // CellBorderColor is the constant for the "cell-border-color" property tag. // The "cell-border-color" property sets the line color for all four sides of a table cell's border. CellBorderColor = "cell-border-color" + // CellBorderLeftColor is the constant for the "cell-border-left-color" property tag. // The "cell-border-left-color" property sets the line color of a table cell's left border. CellBorderLeftColor = "cell-border-left-color" + // CellBorderRightColor is the constant for the "cell-border-right-color" property tag. // The "cell-border-right-color" property sets the line color of a table cell's right border. CellBorderRightColor = "cell-border-right-color" + // CellBorderTopColor is the constant for the "cell-border-top-color" property tag. // The "cell-border-top-color" property sets the line color of a table cell's top border. CellBorderTopColor = "cell-border-top-color" + // CellBorderBottomColor is the constant for the "cell-border-bottom-color" property tag. // The "cell-border-bottom-color" property sets the line color of a table cell's bottom border. CellBorderBottomColor = "cell-border-bottom-color" + + // SelectionMode is the constant for the "selection-mode" property tag. + // The "selection-mode" int property sets the mode of the table elements selection. + // Valid values are NoneSelection (0), CellSelection (1), and RowSelection (2) + SelectionMode = "selection-mode" + + // TableCellClickedEvent is the constant for "table-cell-clicked" property tag. + // The "table-cell-clicked" event occurs when the user clicks on a table cell. + // The main listener format: func(TableView, int, int), where the second argument is the row number, + // and third argument is the column number. + TableCellClickedEvent = "table-cell-clicked" + + // TableCellSelectedEvent is the constant for "table-cell-selected" property tag. + // The "table-cell-selected" event occurs when a table cell becomes selected. + // The main listener format: func(TableView, int, int), where the second argument is the row number, + // and third argument is the column number. + TableCellSelectedEvent = "table-cell-selected" + + // TableRowClickedEvent is the constant for "table-row-clicked" property tag. + // The "table-row-clicked" event occurs when the user clicks on a table row. + // The main listener format: func(TableView, int), where the second argument is the row number. + TableRowClickedEvent = "table-row-clicked" + + // TableRowSelectedEvent is the constant for "table-row-selected" property tag. + // The "table-row-selected" event occurs when a table row becomes selected. + // The main listener format: func(TableView, int), where the second argument is the row number. + TableRowSelectedEvent = "table-row-selected" + + // NoneSelection is the value of "selection-mode" property: the selection is forbidden. + NoneSelection = 0 + // CellSelection is the value of "selection-mode" property: the selection of a single cell only is enabled. + CellSelection = 1 + // RowSelection is the value of "selection-mode" property: the selection of a table row only is enabled. + RowSelection = 2 ) +// CellIndex defines coordinates of the TableView cell +type CellIndex struct { + Row, Column int +} + // TableView - text View type TableView interface { View + ParanetView ReloadTableData() } type tableViewData struct { viewData + cellViews []View + cellSelectedListener, cellClickedListener []func(TableView, int, int) + rowSelectedListener, rowClickedListener []func(TableView, int) + current CellIndex } type tableCellView struct { @@ -166,6 +244,13 @@ func newTableView(session Session) View { func (table *tableViewData) Init(session Session) { table.viewData.Init(session) table.tag = "TableView" + table.cellViews = []View{} + table.cellSelectedListener = []func(TableView, int, int){} + table.cellClickedListener = []func(TableView, int, int){} + table.rowSelectedListener = []func(TableView, int){} + table.rowClickedListener = []func(TableView, int){} + table.current.Row = -1 + table.current.Column = -1 } func (table *tableViewData) normalizeTag(tag string) string { @@ -206,6 +291,27 @@ func (table *tableViewData) remove(tag string) { table.propertyChanged(tag) } + case TableCellClickedEvent: + table.cellClickedListener = []func(TableView, int, int){} + table.propertyChanged(tag) + + case TableCellSelectedEvent: + table.cellSelectedListener = []func(TableView, int, int){} + table.propertyChanged(tag) + + case TableRowClickedEvent: + table.rowClickedListener = []func(TableView, int){} + table.propertyChanged(tag) + + case TableRowSelectedEvent: + table.rowSelectedListener = []func(TableView, int){} + table.propertyChanged(tag) + + case Current: + table.current.Row = -1 + table.current.Column = -1 + table.propertyChanged(tag) + default: table.viewData.remove(tag) } @@ -238,6 +344,38 @@ func (table *tableViewData) set(tag string, value interface{}) bool { return false } + case TableCellClickedEvent: + listeners := table.valueToCellListeners(value) + if listeners == nil { + notCompatibleType(tag, value) + return false + } + table.cellClickedListener = listeners + + case TableCellSelectedEvent: + listeners := table.valueToCellListeners(value) + if listeners == nil { + notCompatibleType(tag, value) + return false + } + table.cellSelectedListener = listeners + + case TableRowClickedEvent: + listeners := table.valueToRowListeners(value) + if listeners == nil { + notCompatibleType(tag, value) + return false + } + table.rowClickedListener = listeners + + case TableRowSelectedEvent: + listeners := table.valueToRowListeners(value) + if listeners == nil { + notCompatibleType(tag, value) + return false + } + table.rowSelectedListener = []func(TableView, int){} + case CellStyle: if style, ok := value.(TableCellStyle); ok { table.properties[tag] = style @@ -342,6 +480,22 @@ func (table *tableViewData) set(tag string, value interface{}) bool { return false } + case SelectionMode: + if !table.setEnumProperty(SelectionMode, value, enumProperties[SelectionMode].values) { + return false + } + + case Current: + switch GetSelectionMode(table, "") { + case NoneSelection: + + case CellSelection: + // TODO + + case RowSelection: + // TODO + } + default: return table.viewData.set(tag, value) } @@ -355,7 +509,8 @@ func (table *tableViewData) propertyChanged(tag string) { switch tag { case Content, RowStyle, ColumnStyle, CellStyle, CellPadding, CellBorder, HeadHeight, HeadStyle, FootHeight, FootStyle, - CellPaddingTop, CellPaddingRight, CellPaddingBottom, CellPaddingLeft: + CellPaddingTop, CellPaddingRight, CellPaddingBottom, CellPaddingLeft, + TableCellClickedEvent, TableCellSelectedEvent, TableRowClickedEvent, TableRowSelectedEvent: table.ReloadTableData() case Gap: @@ -374,11 +529,123 @@ func (table *tableViewData) propertyChanged(tag string) { table.propertyChangedEvent(tag) } +func (table *tableViewData) valueToCellListeners(value interface{}) []func(TableView, int, int) { + if value == nil { + return []func(TableView, int, int){} + } + + switch value := value.(type) { + case func(TableView, int, int): + return []func(TableView, int, int){value} + + case func(int, int): + fn := func(view TableView, row, column int) { + value(row, column) + } + return []func(TableView, int, int){fn} + + case []func(TableView, int, int): + return value + + case []func(int, int): + listeners := make([]func(TableView, int, int), len(value)) + for i, val := range value { + if val == nil { + return nil + } + listeners[i] = func(view TableView, row, column int) { + val(row, column) + } + } + return listeners + + case []interface{}: + listeners := make([]func(TableView, int, int), len(value)) + for i, val := range value { + if val == nil { + return nil + } + switch val := val.(type) { + case func(TableView, int, int): + listeners[i] = val + + case func(int, int): + listeners[i] = func(view TableView, row, column int) { + val(row, column) + } + + default: + return nil + } + } + return listeners + } + + return nil +} + +func (table *tableViewData) valueToRowListeners(value interface{}) []func(TableView, int) { + if value == nil { + return []func(TableView, int){} + } + + switch value := value.(type) { + case func(TableView, int): + return []func(TableView, int){value} + + case func(int): + fn := func(view TableView, index int) { + value(index) + } + return []func(TableView, int){fn} + + case []func(TableView, int): + return value + + case []func(int): + listeners := make([]func(TableView, int), len(value)) + for i, val := range value { + if val == nil { + return nil + } + listeners[i] = func(view TableView, index int) { + val(index) + } + } + return listeners + + case []interface{}: + listeners := make([]func(TableView, int), len(value)) + for i, val := range value { + if val == nil { + return nil + } + switch val := val.(type) { + case func(TableView, int): + listeners[i] = val + + case func(int): + listeners[i] = func(view TableView, index int) { + val(index) + } + + default: + return nil + } + } + return listeners + } + + return nil +} + func (table *tableViewData) htmlTag() string { return "table" } func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) { + table.cellViews = []View{} + content := table.getRaw(Content) if content == nil { return @@ -556,6 +823,7 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) { case View: viewHTML(value, buffer) + table.cellViews = append(table.cellViews, value) case Color: buffer.WriteString(`