Added ReloadCell and ReloadTableViewCell functions

This commit is contained in:
anoshenko 2023-05-14 17:53:26 +03:00
parent 3bf3b9c2ba
commit 904859ff6e
6 changed files with 200 additions and 64 deletions

View File

@ -1,6 +1,8 @@
# v0.13.0
* Added ViewIndex function to ViewsContainer interface
* Added ReloadCell function to TableView interface
* Added ReloadTableViewCell function
* Added "tooltip" property and GetTooltip function
* Added "outline-offset" property and GetOutlineOffset function
* Changed the main event listener format for "drop-down-event", "edit-text-changed",

View File

@ -3800,6 +3800,18 @@ Cell(row, column int) возвращает содержимое ячейки т
[][]any и [][]string при присвоении преобразуются к TableAdapter.
Если элементы таблицы меняются в ходе работы, то для обновления содержимого таблицы необходимо вызвать один
из двух методов интерфейса TableView
* ReloadTableData()
* ReloadCell(row, column int)
Метод ReloadTableData обновляет таблицу целиком, а ReloadCell обновляет содержимое только конкретной ячейки таблицы.
Для вызова методов ReloadTableData и ReloadCell могут использоваться глобальные функции
func ReloadTableViewData(view View, subviewID ...string) bool
func ReloadTableViewCell(row, column int, view View, subviewID ...string) bool
### Свойство "cell-style"
Свойство "cell-style" (константа CellStyle) предназначено для настройки оформления ячейки таблицы. Данному свойству

View File

@ -3763,6 +3763,18 @@ The "content" property can also be assigned the following data types
[][]any and [][]string are converted to a TableAdapter when assigned.
If the elements of the table change during operation, then to update the contents of the table,
you must call one of the two methods of the TableView interface
* ReloadTableData()
* ReloadCell(row, column int)
The ReloadTableData method updates the entire table, while ReloadCell updates the contents of only a specific table cell.
Global functions can be used to call the ReloadTableData and ReloadCell methods
func ReloadTableViewData(view View, subviewID ...string) bool
func ReloadTableViewCell(row, column int, view View, subviewID ...string) bool
### "cell-style" property
The "cell-style" property (CellStyle constant) is used to customize the appearance of a table cell.

View File

@ -220,6 +220,7 @@ type TableView interface {
View
ParentView
ReloadTableData()
ReloadCell(row, column int)
CellFrame(row, column int) Frame
content() TableAdapter
@ -880,7 +881,7 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) {
vAlign := vAlignCss[vAlignValue]
tableCSS := func(startRow, endRow int, cellTag string, cellBorder BorderProperty, cellPadding BoundsProperty) {
var namedColors []NamedColor = nil
//var namedColors []NamedColor = nil
for row := startRow; row < endRow; row++ {
cssBuilder.buffer.Reset()
@ -1042,57 +1043,60 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) {
}
buffer.WriteRune('>')
switch value := adapter.Cell(row, column).(type) {
case string:
buffer.WriteString(value)
table.writeCellHtml(adapter, row, column, buffer)
/*
switch value := adapter.Cell(row, column).(type) {
case string:
buffer.WriteString(value)
case View:
viewHTML(value, buffer)
table.cellViews = append(table.cellViews, value)
case View:
viewHTML(value, buffer)
table.cellViews = append(table.cellViews, value)
case Color:
buffer.WriteString(`<div style="display: inline; height: 1em; background-color: `)
buffer.WriteString(value.cssString())
buffer.WriteString(`">&nbsp;&nbsp;&nbsp;&nbsp;</div> `)
buffer.WriteString(value.String())
if namedColors == nil {
namedColors = NamedColors()
}
for _, namedColor := range namedColors {
if namedColor.Color == value {
buffer.WriteString(" (")
buffer.WriteString(namedColor.Name)
buffer.WriteRune(')')
break
case Color:
buffer.WriteString(`<div style="display: inline; height: 1em; background-color: `)
buffer.WriteString(value.cssString())
buffer.WriteString(`">&nbsp;&nbsp;&nbsp;&nbsp;</div> `)
buffer.WriteString(value.String())
if namedColors == nil {
namedColors = NamedColors()
}
for _, namedColor := range namedColors {
if namedColor.Color == value {
buffer.WriteString(" (")
buffer.WriteString(namedColor.Name)
buffer.WriteRune(')')
break
}
}
case fmt.Stringer:
buffer.WriteString(value.String())
case rune:
buffer.WriteString(string(value))
case float32:
buffer.WriteString(fmt.Sprintf("%g", float64(value)))
case float64:
buffer.WriteString(fmt.Sprintf("%g", value))
case bool:
if value {
buffer.WriteString(session.checkboxOnImage())
} else {
buffer.WriteString(session.checkboxOffImage())
}
default:
if n, ok := isInt(value); ok {
buffer.WriteString(fmt.Sprintf("%d", n))
} else {
buffer.WriteString("<Unsupported value>")
}
}
case fmt.Stringer:
buffer.WriteString(value.String())
case rune:
buffer.WriteString(string(value))
case float32:
buffer.WriteString(fmt.Sprintf("%g", float64(value)))
case float64:
buffer.WriteString(fmt.Sprintf("%g", value))
case bool:
if value {
buffer.WriteString(session.checkboxOnImage())
} else {
buffer.WriteString(session.checkboxOffImage())
}
default:
if n, ok := isInt(value); ok {
buffer.WriteString(fmt.Sprintf("%d", n))
} else {
buffer.WriteString("<Unsupported value>")
}
}
*/
buffer.WriteString(`</`)
buffer.WriteString(cellTag)
@ -1308,6 +1312,59 @@ func (table *tableViewData) cellPaddingFromStyle(style string) BoundsProperty {
return nil
}
func (table *tableViewData) writeCellHtml(adapter TableAdapter, row, column int, buffer *strings.Builder) {
switch value := adapter.Cell(row, column).(type) {
case string:
buffer.WriteString(value)
case View:
viewHTML(value, buffer)
table.cellViews = append(table.cellViews, value)
case Color:
buffer.WriteString(`<div style="display: inline; height: 1em; background-color: `)
buffer.WriteString(value.cssString())
buffer.WriteString(`">&nbsp;&nbsp;&nbsp;&nbsp;</div> `)
buffer.WriteString(value.String())
namedColors := NamedColors()
for _, namedColor := range namedColors {
if namedColor.Color == value {
buffer.WriteString(" (")
buffer.WriteString(namedColor.Name)
buffer.WriteRune(')')
break
}
}
case fmt.Stringer:
buffer.WriteString(value.String())
case rune:
buffer.WriteString(string(value))
case float32:
buffer.WriteString(fmt.Sprintf("%g", float64(value)))
case float64:
buffer.WriteString(fmt.Sprintf("%g", value))
case bool:
if value {
buffer.WriteString(table.Session().checkboxOnImage())
} else {
buffer.WriteString(table.Session().checkboxOffImage())
}
default:
if n, ok := isInt(value); ok {
buffer.WriteString(fmt.Sprintf("%d", n))
} else {
buffer.WriteString("<Unsupported value>")
}
}
}
func (table *tableViewData) cellBorderFromStyle(style string) BorderProperty {
if value := table.Session().styleProperty(style, CellBorder); value != nil {
if border, ok := value.(BorderProperty); ok {
@ -1395,6 +1452,19 @@ func (table *tableViewData) CellFrame(row, column int) Frame {
return Frame{}
}
func (table *tableViewData) ReloadCell(row, column int) {
adapter := table.content()
if adapter == nil {
return
}
buffer := allocStringBuilder()
defer freeStringBuilder(buffer)
table.writeCellHtml(adapter, row, column, buffer)
table.session.updateInnerHTML(table.cellID(row, column), buffer.String())
}
func (table *tableViewData) Views() []View {
return table.cellViews
}

View File

@ -182,6 +182,7 @@ func GetTableRowSelectedListeners(view View, subviewID ...string) []func(TableVi
}
// ReloadTableViewData updates TableView
// If the second argument (subviewID) is not specified or it is "" then updates the first argument (TableView).
func ReloadTableViewData(view View, subviewID ...string) bool {
var tableView TableView
if len(subviewID) > 0 && subviewID[0] != "" {
@ -198,3 +199,22 @@ func ReloadTableViewData(view View, subviewID ...string) bool {
tableView.ReloadTableData()
return true
}
// ReloadTableViewCell updates the given table cell.
// If the last argument (subviewID) is not specified or it is "" then updates the cell of the first argument (TableView).
func ReloadTableViewCell(row, column int, view View, subviewID ...string) bool {
var tableView TableView
if len(subviewID) > 0 && subviewID[0] != "" {
if tableView = TableViewByID(view, subviewID[0]); tableView == nil {
return false
}
} else {
var ok bool
if tableView, ok = view.(TableView); !ok {
return false
}
}
tableView.ReloadCell(row, column)
return true
}

View File

@ -566,7 +566,22 @@ func (tabsLayout *tabsLayoutData) IsListItemEnabled(index int) bool {
return true
}
func (tabsLayout *tabsLayoutData) updateContent(view View, tag string) {
func (tabsLayout *tabsLayoutData) updateTitle(view View, tag string) {
session := tabsLayout.session
title, _ := stringProperty(view, Title, session)
if !GetNotTranslate(tabsLayout) {
title, _ = session.GetString(title)
}
session.updateInnerHTML(view.htmlID()+"-title", title)
}
func (tabsLayout *tabsLayoutData) updateIcon(view View, tag string) {
session := tabsLayout.session
icon, _ := stringProperty(view, Icon, session)
session.updateProperty(view.htmlID()+"-icon", "src", icon)
}
func (tabsLayout *tabsLayoutData) updateTabCloseButton(view View, tag string) {
updateInnerHTML(tabsLayout.htmlID(), tabsLayout.session)
}
@ -577,9 +592,9 @@ func (tabsLayout *tabsLayoutData) Append(view View) {
}
if view != nil {
tabsLayout.viewsContainerData.Append(view)
view.SetChangeListener(Title, tabsLayout.updateContent)
view.SetChangeListener(Icon, tabsLayout.updateContent)
view.SetChangeListener(TabCloseButton, tabsLayout.updateContent)
view.SetChangeListener(Title, tabsLayout.updateTitle)
view.SetChangeListener(Icon, tabsLayout.updateIcon)
view.SetChangeListener(TabCloseButton, tabsLayout.updateTabCloseButton)
if len(tabsLayout.views) == 1 {
tabsLayout.properties[Current] = 0
for _, listener := range tabsLayout.tabListener {
@ -601,9 +616,9 @@ func (tabsLayout *tabsLayoutData) Insert(view View, index int) {
defer tabsLayout.propertyChangedEvent(Current)
}
tabsLayout.viewsContainerData.Insert(view, index)
view.SetChangeListener(Title, tabsLayout.updateContent)
view.SetChangeListener(Icon, tabsLayout.updateContent)
view.SetChangeListener(TabCloseButton, tabsLayout.updateContent)
view.SetChangeListener(Title, tabsLayout.updateTitle)
view.SetChangeListener(Icon, tabsLayout.updateIcon)
view.SetChangeListener(TabCloseButton, tabsLayout.updateTabCloseButton)
}
}
@ -721,7 +736,7 @@ func (tabsLayout *tabsLayoutData) htmlSubviews(self View, buffer *strings.Builde
notTranslate := GetNotTranslate(tabsLayout)
closeButton, _ := boolProperty(tabsLayout, TabCloseButton, tabsLayout.session)
var tabStyle, titleDiv string
var tabStyle, titleStyle string
switch location {
case LeftTabs, RightTabs:
tabStyle = `display: grid; grid-template-rows: auto 1fr auto; align-items: center; justify-items: center; grid-row-gap: 8px;`
@ -735,13 +750,13 @@ func (tabsLayout *tabsLayoutData) htmlSubviews(self View, buffer *strings.Builde
switch location {
case LeftTabs:
titleDiv = `<div style="writing-mode: vertical-lr; transform: rotate(180deg); grid-row-start: 2; grid-row-end: 3; grid-column-start: 1; grid-column-end: 2;">`
titleStyle = ` style="writing-mode: vertical-lr; transform: rotate(180deg); grid-row-start: 2; grid-row-end: 3; grid-column-start: 1; grid-column-end: 2;">`
case RightTabs:
titleDiv = `<div style="writing-mode: vertical-lr; grid-row-start: 2; grid-row-end: 3; grid-column-start: 1; grid-column-end: 2;">`
titleStyle = ` style="writing-mode: vertical-lr; grid-row-start: 2; grid-row-end: 3; grid-column-start: 1; grid-column-end: 2;">`
default:
titleDiv = `<div style="grid-row-start: 1; grid-row-end: 2; grid-column-start: 2; grid-column-end: 3;">`
titleStyle = ` style="grid-row-start: 1; grid-row-end: 2; grid-column-start: 2; grid-column-end: 3;">`
}
for n, view := range tabsLayout.views {
@ -780,21 +795,26 @@ func (tabsLayout *tabsLayoutData) htmlSubviews(self View, buffer *strings.Builde
buffer.WriteString(`">`)
if icon != "" {
buffer.WriteString(`<img id="`)
buffer.WriteString(view.htmlID())
switch location {
case LeftTabs:
buffer.WriteString(`<img style="grid-row-start: 3; grid-row-end: 4; grid-column-start: 1; grid-column-end: 2;" src="`)
buffer.WriteString(`-icon" style="grid-row-start: 3; grid-row-end: 4; grid-column-start: 1; grid-column-end: 2;" src="`)
case RightTabs:
buffer.WriteString(`<img style="grid-row-start: 1; grid-row-end: 2; grid-column-start: 1; grid-column-end: 2;" src="`)
buffer.WriteString(`-icon" style="grid-row-start: 1; grid-row-end: 2; grid-column-start: 1; grid-column-end: 2;" src="`)
default:
buffer.WriteString(`<img style="grid-row-start: 1; grid-row-end: 2; grid-column-start: 1; grid-column-end: 2;" src="`)
buffer.WriteString(`-icon" style="grid-row-start: 1; grid-row-end: 2; grid-column-start: 1; grid-column-end: 2;" src="`)
}
buffer.WriteString(icon)
buffer.WriteString(`">`)
}
buffer.WriteString(titleDiv)
buffer.WriteString(`<div id="`)
buffer.WriteString(view.htmlID())
buffer.WriteString(`-title"`)
buffer.WriteString(titleStyle)
buffer.WriteString(title)
buffer.WriteString(`</div>`)
@ -811,7 +831,7 @@ func (tabsLayout *tabsLayoutData) htmlSubviews(self View, buffer *strings.Builde
buffer.WriteString(tabsLayoutID)
buffer.WriteString(`', `)
buffer.WriteString(strconv.Itoa(n))
buffer.WriteString(`, event)" style="display: grid; `)
buffer.WriteString(`, event)" style="display: grid; `)
switch location {
case LeftTabs: