diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7fe4f7a..5d3c98b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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",
diff --git a/README-ru.md b/README-ru.md
index ea6ac7b..8b8fe05 100644
--- a/README-ru.md
+++ b/README-ru.md
@@ -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) предназначено для настройки оформления ячейки таблицы. Данному свойству
diff --git a/README.md b/README.md
index 0e91275..9b26347 100644
--- a/README.md
+++ b/README.md
@@ -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.
diff --git a/tableView.go b/tableView.go
index 750f9d9..01fcdc1 100644
--- a/tableView.go
+++ b/tableView.go
@@ -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(`
`)
- 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(`
`)
+ 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("")
}
}
-
- 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("")
- }
- }
+ */
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(`
`)
+ 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("")
+ }
+ }
+}
+
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
}
diff --git a/tableViewUtils.go b/tableViewUtils.go
index d8e46f3..9385d12 100644
--- a/tableViewUtils.go
+++ b/tableViewUtils.go
@@ -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
+}
diff --git a/tabsLayout.go b/tabsLayout.go
index e880aa7..881f485 100644
--- a/tabsLayout.go
+++ b/tabsLayout.go
@@ -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 = ``
+ 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 = `
`
+ titleStyle = ` style="writing-mode: vertical-lr; grid-row-start: 2; grid-row-end: 3; grid-column-start: 1; grid-column-end: 2;">`
default:
- titleDiv = `
`
+ 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(`
`)
}
- buffer.WriteString(titleDiv)
+ buffer.WriteString(`
`)
@@ -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: