forked from mbk-lab/rui_orig
2
0
Fork 0

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 # v0.13.0
* Added ViewIndex function to ViewsContainer interface * Added ViewIndex function to ViewsContainer interface
* Added ReloadCell function to TableView interface
* Added ReloadTableViewCell function
* Added "tooltip" property and GetTooltip function * Added "tooltip" property and GetTooltip function
* Added "outline-offset" property and GetOutlineOffset function * Added "outline-offset" property and GetOutlineOffset function
* Changed the main event listener format for "drop-down-event", "edit-text-changed", * 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. [][]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"
Свойство "cell-style" (константа CellStyle) предназначено для настройки оформления ячейки таблицы. Данному свойству Свойство "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. [][]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 ### "cell-style" property
The "cell-style" property (CellStyle constant) is used to customize the appearance of a table cell. 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 View
ParentView ParentView
ReloadTableData() ReloadTableData()
ReloadCell(row, column int)
CellFrame(row, column int) Frame CellFrame(row, column int) Frame
content() TableAdapter content() TableAdapter
@ -880,7 +881,7 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) {
vAlign := vAlignCss[vAlignValue] vAlign := vAlignCss[vAlignValue]
tableCSS := func(startRow, endRow int, cellTag string, cellBorder BorderProperty, cellPadding BoundsProperty) { 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++ { for row := startRow; row < endRow; row++ {
cssBuilder.buffer.Reset() cssBuilder.buffer.Reset()
@ -1042,57 +1043,60 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) {
} }
buffer.WriteRune('>') buffer.WriteRune('>')
switch value := adapter.Cell(row, column).(type) { table.writeCellHtml(adapter, row, column, buffer)
case string: /*
buffer.WriteString(value) switch value := adapter.Cell(row, column).(type) {
case string:
buffer.WriteString(value)
case View: case View:
viewHTML(value, buffer) viewHTML(value, buffer)
table.cellViews = append(table.cellViews, value) table.cellViews = append(table.cellViews, value)
case Color: case Color:
buffer.WriteString(`<div style="display: inline; height: 1em; background-color: `) buffer.WriteString(`<div style="display: inline; height: 1em; background-color: `)
buffer.WriteString(value.cssString()) buffer.WriteString(value.cssString())
buffer.WriteString(`">&nbsp;&nbsp;&nbsp;&nbsp;</div> `) buffer.WriteString(`">&nbsp;&nbsp;&nbsp;&nbsp;</div> `)
buffer.WriteString(value.String()) buffer.WriteString(value.String())
if namedColors == nil { if namedColors == nil {
namedColors = NamedColors() namedColors = NamedColors()
} }
for _, namedColor := range namedColors { for _, namedColor := range namedColors {
if namedColor.Color == value { if namedColor.Color == value {
buffer.WriteString(" (") buffer.WriteString(" (")
buffer.WriteString(namedColor.Name) buffer.WriteString(namedColor.Name)
buffer.WriteRune(')') buffer.WriteRune(')')
break 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(`</`)
buffer.WriteString(cellTag) buffer.WriteString(cellTag)
@ -1308,6 +1312,59 @@ func (table *tableViewData) cellPaddingFromStyle(style string) BoundsProperty {
return nil 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 { func (table *tableViewData) cellBorderFromStyle(style string) BorderProperty {
if value := table.Session().styleProperty(style, CellBorder); value != nil { if value := table.Session().styleProperty(style, CellBorder); value != nil {
if border, ok := value.(BorderProperty); ok { if border, ok := value.(BorderProperty); ok {
@ -1395,6 +1452,19 @@ func (table *tableViewData) CellFrame(row, column int) Frame {
return 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 { func (table *tableViewData) Views() []View {
return table.cellViews return table.cellViews
} }

View File

@ -182,6 +182,7 @@ func GetTableRowSelectedListeners(view View, subviewID ...string) []func(TableVi
} }
// ReloadTableViewData updates TableView // 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 { func ReloadTableViewData(view View, subviewID ...string) bool {
var tableView TableView var tableView TableView
if len(subviewID) > 0 && subviewID[0] != "" { if len(subviewID) > 0 && subviewID[0] != "" {
@ -198,3 +199,22 @@ func ReloadTableViewData(view View, subviewID ...string) bool {
tableView.ReloadTableData() tableView.ReloadTableData()
return true 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 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) updateInnerHTML(tabsLayout.htmlID(), tabsLayout.session)
} }
@ -577,9 +592,9 @@ func (tabsLayout *tabsLayoutData) Append(view View) {
} }
if view != nil { if view != nil {
tabsLayout.viewsContainerData.Append(view) tabsLayout.viewsContainerData.Append(view)
view.SetChangeListener(Title, tabsLayout.updateContent) view.SetChangeListener(Title, tabsLayout.updateTitle)
view.SetChangeListener(Icon, tabsLayout.updateContent) view.SetChangeListener(Icon, tabsLayout.updateIcon)
view.SetChangeListener(TabCloseButton, tabsLayout.updateContent) view.SetChangeListener(TabCloseButton, tabsLayout.updateTabCloseButton)
if len(tabsLayout.views) == 1 { if len(tabsLayout.views) == 1 {
tabsLayout.properties[Current] = 0 tabsLayout.properties[Current] = 0
for _, listener := range tabsLayout.tabListener { for _, listener := range tabsLayout.tabListener {
@ -601,9 +616,9 @@ func (tabsLayout *tabsLayoutData) Insert(view View, index int) {
defer tabsLayout.propertyChangedEvent(Current) defer tabsLayout.propertyChangedEvent(Current)
} }
tabsLayout.viewsContainerData.Insert(view, index) tabsLayout.viewsContainerData.Insert(view, index)
view.SetChangeListener(Title, tabsLayout.updateContent) view.SetChangeListener(Title, tabsLayout.updateTitle)
view.SetChangeListener(Icon, tabsLayout.updateContent) view.SetChangeListener(Icon, tabsLayout.updateIcon)
view.SetChangeListener(TabCloseButton, tabsLayout.updateContent) view.SetChangeListener(TabCloseButton, tabsLayout.updateTabCloseButton)
} }
} }
@ -721,7 +736,7 @@ func (tabsLayout *tabsLayoutData) htmlSubviews(self View, buffer *strings.Builde
notTranslate := GetNotTranslate(tabsLayout) notTranslate := GetNotTranslate(tabsLayout)
closeButton, _ := boolProperty(tabsLayout, TabCloseButton, tabsLayout.session) closeButton, _ := boolProperty(tabsLayout, TabCloseButton, tabsLayout.session)
var tabStyle, titleDiv string var tabStyle, titleStyle string
switch location { switch location {
case LeftTabs, RightTabs: case LeftTabs, RightTabs:
tabStyle = `display: grid; grid-template-rows: auto 1fr auto; align-items: center; justify-items: center; grid-row-gap: 8px;` 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 { switch location {
case LeftTabs: 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: 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: 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 { for n, view := range tabsLayout.views {
@ -780,21 +795,26 @@ func (tabsLayout *tabsLayoutData) htmlSubviews(self View, buffer *strings.Builde
buffer.WriteString(`">`) buffer.WriteString(`">`)
if icon != "" { if icon != "" {
buffer.WriteString(`<img id="`)
buffer.WriteString(view.htmlID())
switch location { switch location {
case LeftTabs: 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: 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: 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(icon)
buffer.WriteString(`">`) buffer.WriteString(`">`)
} }
buffer.WriteString(titleDiv) buffer.WriteString(`<div id="`)
buffer.WriteString(view.htmlID())
buffer.WriteString(`-title"`)
buffer.WriteString(titleStyle)
buffer.WriteString(title) buffer.WriteString(title)
buffer.WriteString(`</div>`) buffer.WriteString(`</div>`)
@ -811,7 +831,7 @@ func (tabsLayout *tabsLayoutData) htmlSubviews(self View, buffer *strings.Builde
buffer.WriteString(tabsLayoutID) buffer.WriteString(tabsLayoutID)
buffer.WriteString(`', `) buffer.WriteString(`', `)
buffer.WriteString(strconv.Itoa(n)) buffer.WriteString(strconv.Itoa(n))
buffer.WriteString(`, event)" style="display: grid; `) buffer.WriteString(`, event)" style="display: grid; `)
switch location { switch location {
case LeftTabs: case LeftTabs: