Updated "disabled" property, removed "style-disabled" property and GetDisabledStyle function

This commit is contained in:
Alexei Anoshenko 2026-04-09 15:54:35 +03:00
parent 18d6251589
commit 79dd20a889
18 changed files with 85 additions and 160 deletions

View File

@ -1,3 +1,7 @@
# v0.21.0
* Removed "style-disabled" property and GetDisabledStyle function
# v0.20.0
* Added support of binding

View File

@ -230,18 +230,6 @@ function removeView(elementId) {
}
}
function setDisabled(elementId, disabled) {
const element = document.getElementById(elementId);
if (element) {
if ('disabled' in element) {
element.disabled = disabled
} else {
element.setAttribute("data-disabled", disabled ? "1" : "0");
}
scanElementsSize();
}
}
function focusEvent(element, event) {
event.stopPropagation();
sendMessage("focus-event{session=" + sessionID + ",id=" + element.id + "}");
@ -626,7 +614,7 @@ function selectDropDownListItem(elementId, number) {
function listItemClickEvent(element, event) {
event.stopPropagation();
if (element.getAttribute("data-disabled") == "1") {
if (element.getAttribute("inert") != null) {
return
}
@ -707,11 +695,19 @@ function selectListItem(element, item) {
scanElementsSize();
}
function isListItemDisabled(item) {
let inert = item.getAttribute("inert");
if (inert != null) {
return true;
}
return false;
}
function findRightListItem(list, x, y) {
list = list.childNodes[0];
let result;
for (const item of list.childNodes) {
if (item.getAttribute("data-disabled") == "1") {
if (isListItemDisabled(item)) {
continue;
}
if (item.offsetLeft >= x) {
@ -733,7 +729,7 @@ function findLeftListItem(list, x, y) {
list = list.childNodes[0];
let result;
for (const item of list.childNodes) {
if (item.getAttribute("data-disabled") == "1") {
if (isListItemDisabled(item)) {
continue;
}
if (item.offsetLeft < x) {
@ -755,7 +751,7 @@ function findTopListItem(list, x, y) {
list = list.childNodes[0];
let result;
for (const item of list.childNodes) {
if (item.getAttribute("data-disabled") == "1") {
if (isListItemDisabled(item)) {
continue;
}
if (item.offsetTop < y) {
@ -777,7 +773,7 @@ function findBottomListItem(list, x, y) {
list = list.childNodes[0];
let result;
for (const item of list.childNodes) {
if (item.getAttribute("data-disabled") == "1") {
if (isListItemDisabled(item)) {
continue;
}
if (item.offsetTop >= y) {
@ -851,11 +847,22 @@ function listViewKeyDownEvent(element, event) {
break;
case "Home":
item = element.childNodes[0];
for (const i of list.childNodes) {
if (!isListItemDisabled(i)) {
item = i;
break;
}
}
break;
case "End":
item = element.childNodes[element.childNodes.length - 1];
for (var i = element.childNodes.length-1; i >= 0; i--) {
const itm = element.childNodes[i]
if (!isListItemDisabled(itm)) {
item = itm;
break;
}
}
break;
case "PageUp":
@ -886,11 +893,10 @@ function listViewKeyDownEvent(element, event) {
case "PageDown":
const list = element.childNodes[0];
for (const item of list.childNodes) {
if (item.getAttribute("data-disabled") == "1") {
continue;
if (!isListItemDisabled(item)) {
selectListItem(element, item);
return;
}
selectListItem(element, item);
return;
}
break;
@ -1484,7 +1490,7 @@ function setTableCellCursorByID(tableID, row, column) {
function setTableCellCursor(element, row, column) {
const cellID = element.id + "-" + row + "-" + column;
const cell = document.getElementById(cellID);
if (!cell || cell.getAttribute("data-disabled")) {
if (!cell || cell.getAttribute("inert") != null) {
return false;
}
@ -1675,7 +1681,7 @@ function setTableRowCursorByID(tableID, row) {
function setTableRowCursor(element, row) {
const tableRowID = element.id + "-" + row;
const tableRow = document.getElementById(tableRowID);
if (!tableRow || tableRow.getAttribute("data-disabled")) {
if (!tableRow || tableRow.getAttribute("inert") != null) {
return false;
}

View File

@ -41,6 +41,11 @@ div:focus {
}
*/
[inert] > * {
opacity: 0.6;
filter: grayscale(100%);
}
input {
box-sizing: border-box;
margin: 2px;

View File

@ -28,7 +28,7 @@ func (button *buttonData) init(session Session) {
button.tag = "Button"
button.systemClass = "ruiButton"
button.setRaw(Style, "ruiEnabledButton")
button.setRaw(StyleDisabled, "ruiDisabledButton")
//button.setRaw(StyleDisabled, "ruiDisabledButton")
button.setRaw(Semantics, ButtonSemantics)
button.setRaw(TabIndex, 0)
}

View File

@ -63,7 +63,6 @@ func newColorPicker(session Session) View {
func (picker *colorPickerData) init(session Session) {
picker.viewData.init(session)
picker.tag = "ColorPicker"
picker.hasHtmlDisabled = true
picker.properties[Padding] = Px(0)
picker.normalize = normalizeColorPickerTag
picker.get = picker.getFunc

View File

@ -203,8 +203,8 @@ func (customView *CustomViewData) handleCommand(self View, command PropertyName,
return customView.superView.handleCommand(customView.superView, command, data)
}
func (customView *CustomViewData) htmlClass(disabled bool) string {
return customView.superView.htmlClass(disabled)
func (customView *CustomViewData) htmlClass() string {
return customView.superView.htmlClass()
}
func (customView *CustomViewData) htmlTag() string {
@ -227,10 +227,6 @@ func (customView *CustomViewData) htmlProperties(self View, buffer *strings.Buil
customView.superView.htmlProperties(customView.superView, buffer)
}
func (customView *CustomViewData) htmlDisabledProperty() bool {
return customView.superView.htmlDisabledProperty()
}
func (customView *CustomViewData) cssStyle(self View, builder cssBuilder) {
customView.superView.cssStyle(customView.superView, builder)
}

View File

@ -136,7 +136,6 @@ func newDatePicker(session Session) View {
func (picker *datePickerData) init(session Session) {
picker.viewData.init(session)
picker.tag = "DatePicker"
picker.hasHtmlDisabled = true
picker.normalize = normalizeDatePickerTag
picker.set = picker.setFunc
picker.get = picker.getFunc

View File

@ -6,8 +6,6 @@ theme {
ruiButtonColor = #FFE0E0E0,
ruiButtonActiveColor = #FFC0C0C0,
ruiButtonTextColor = #FF000000,
ruiButtonDisabledColor = #FFE0E0E0,
ruiButtonDisabledTextColor = #FF808080,
ruiHighlightColor = #FF1A74E8,
ruiHighlightTextColor = #FFFFFFFF,
ruiSelectedColor = #FFE0E0E0,
@ -33,8 +31,6 @@ theme {
ruiBackgroundColor = #FF080808,
ruiButtonColor = #FF404040,
ruiButtonTextColor = #FFE0E0E0,
ruiButtonDisabledColor = #FF404040,
ruiButtonDisabledTextColor = #FFA0A0A0,
ruiHighlightColor = #FF1A74E8,
ruiHighlightTextColor = #FFFFFFFF,
ruiPopupBackgroundColor = #FF424242,
@ -90,14 +86,6 @@ theme {
text-color = @ruiButtonTextColor,
border = _{width = 1px, style = solid, color = @ruiButtonTextColor}
},
ruiDisabledButton {
padding = "@ruiButtonVerticalPadding, @ruiButtonHorizontalPadding, @ruiButtonVerticalPadding, @ruiButtonHorizontalPadding",
margin = @ruiButtonMargin,
radius = @ruiButtonRadius,
background-color = @ruiButtonDisabledColor,
text-color = @ruiButtonDisabledTextColor,
border = _{width = 1px, style = solid, color = @ruiButtonDisabledTextColor}
},
ruiEnabledButton:hover {
text-color = @ruiTextColor,
background-color = @ruiBackgroundColor,

View File

@ -49,7 +49,6 @@ func newDropDownList(session Session) View {
func (list *dropDownListData) init(session Session) {
list.viewData.init(session)
list.tag = "DropDownList"
list.hasHtmlDisabled = true
list.normalize = normalizeDropDownListTag
list.get = list.getFunc
list.set = list.setFunc

View File

@ -118,7 +118,6 @@ func newEditView(session Session) View {
func (edit *editViewData) init(session Session) {
edit.viewData.init(session)
edit.hasHtmlDisabled = true
edit.tag = "EditView"
edit.normalize = normalizeEditViewTag
edit.get = edit.getFunc

View File

@ -128,7 +128,6 @@ func newFilePicker(session Session) View {
func (picker *filePickerData) init(session Session) {
picker.viewData.init(session)
picker.tag = "FilePicker"
picker.hasHtmlDisabled = true
picker.files = []FileInfo{}
//picker.loader = map[int]func(FileInfo, []byte){}
picker.get = picker.getFunc

View File

@ -286,7 +286,7 @@ func (listView *listViewData) propertyChanged(tag PropertyName) {
}
}
case Items, Orientation, ListWrap, ListRowGap, ListColumnGap, VerticalAlign, HorizontalAlign, Style, StyleDisabled, ItemWidth, ItemHeight,
case Items, Orientation, ListWrap, ListRowGap, ListColumnGap, VerticalAlign, HorizontalAlign, Style, ItemWidth, ItemHeight,
ItemHorizontalAlign, ItemVerticalAlign, ItemCheckbox, CheckboxHorizontalAlign, CheckboxVerticalAlign, ListItemStyle, AccentColor:
updateInnerHTML(listView.htmlID(), listView.Session())
@ -631,6 +631,13 @@ func listViewCurrentInactiveStyle(view View) string {
return listViewItemStyle(view, CurrentInactiveStyle, "ruiListItemSelected")
}
func (listView *listViewData) itemEnabledAdapter(adapter ListAdapter) ListItemEnabled {
if ext, ok := adapter.(ListItemEnabled); ok {
return ext
}
return nil
}
func (listView *listViewData) checkboxSubviews(adapter ListAdapter, buffer *strings.Builder, checkbox int) {
count := adapter.ListSize()
listViewID := listView.htmlID()
@ -643,6 +650,8 @@ func (listView *listViewData) checkboxSubviews(adapter ListAdapter, buffer *stri
current := GetCurrent(listView)
checkedItems := GetListViewCheckedItems(listView)
enabledItems := listView.itemEnabledAdapter(adapter)
for i := range count {
buffer.WriteString(`<div id="`)
buffer.WriteString(listViewID)
@ -654,14 +663,14 @@ func (listView *listViewData) checkboxSubviews(adapter ListAdapter, buffer *stri
buffer.WriteRune(' ')
buffer.WriteString(listViewCurrentInactiveStyle(listView))
}
buffer.WriteString(`" onclick="listItemClickEvent(this, event)" data-left="0" data-top="0" data-width="0" data-height="0" style="display: grid; justify-items: stretch; align-items: stretch;`)
listView.itemSize(buffer)
if ext, ok := adapter.(ListItemEnabled); ok {
if !ext.IsListItemEnabled(i) {
buffer.WriteString(`" data-disabled="1`)
}
if enabledItems != nil && !enabledItems.IsListItemEnabled(i) {
buffer.WriteString(`" inert>`)
} else {
buffer.WriteString(`">`)
}
buffer.WriteString(`">`)
buffer.WriteString(itemDiv)
checked := false
@ -704,6 +713,8 @@ func (listView *listViewData) noneCheckboxSubviews(adapter ListAdapter, buffer *
itemStyle := itemStyleBuilder.String()
current := GetCurrent(listView)
enabledItems := listView.itemEnabledAdapter(adapter)
for i := range count {
buffer.WriteString(`<div id="`)
buffer.WriteString(listViewID)
@ -717,10 +728,8 @@ func (listView *listViewData) noneCheckboxSubviews(adapter ListAdapter, buffer *
}
buffer.WriteString(`" `)
buffer.WriteString(itemStyle)
if ext, ok := adapter.(ListItemEnabled); ok {
if !ext.IsListItemEnabled(i) {
buffer.WriteString(` data-disabled="1"`)
}
if enabledItems != nil && !enabledItems.IsListItemEnabled(i) {
buffer.WriteString(` inert`)
}
buffer.WriteString(`>`)

View File

@ -127,7 +127,6 @@ func newNumberPicker(session Session) View {
func (picker *numberPickerData) init(session Session) {
picker.viewData.init(session)
picker.tag = "NumberPicker"
picker.hasHtmlDisabled = true
picker.normalize = normalizeNumberPickerTag
picker.get = picker.getFunc
picker.set = picker.setFunc

View File

@ -71,14 +71,6 @@ const (
// - 4 (DoubleLine) or "double" - Double line as an outline.
Style PropertyName = "style"
// StyleDisabled is the constant for "style-disabled" property tag.
//
// Used by View.
// Sets the name of the style that is applied to the view when the "disabled" property is set to true.
//
// Supported types: string.
StyleDisabled PropertyName = "style-disabled"
// Disabled is the constant for "disabled" property tag.
//
// Used by ViewsContainer.

View File

@ -1124,7 +1124,7 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) {
buffer.WriteString(` onclick="tableRowClickEvent(this, event)"`)
if allowRowSelection != nil && !allowRowSelection.AllowRowSelection(row) {
buffer.WriteString(` data-disabled="1"`)
buffer.WriteString(` inert`)
}
}
@ -1214,7 +1214,7 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) {
if selectionMode == CellSelection {
buffer.WriteString(` onclick="tableCellClickEvent(this, event)"`)
if allowCellSelection != nil && !allowCellSelection.AllowCellSelection(row, column) {
buffer.WriteString(` data-disabled="1"`)
buffer.WriteString(` inert`)
}
}

View File

@ -118,7 +118,6 @@ func newTimePicker(session Session) View {
func (picker *timePickerData) init(session Session) {
picker.viewData.init(session)
picker.tag = "TimePicker"
picker.hasHtmlDisabled = true
picker.normalize = normalizeTimePickerTag
picker.get = picker.getFunc
picker.set = picker.setFunc

83
view.go
View File

@ -92,7 +92,7 @@ type View interface {
init(session Session)
handleCommand(self View, command PropertyName, data DataObject) bool
htmlClass(disabled bool) string
htmlClass() string
htmlTag() string
closeHTMLTag() bool
htmlID() string
@ -103,7 +103,6 @@ type View interface {
cssStyle(self View, builder cssBuilder)
addToCSSStyle(addCSS map[string]string)
excludeTags() []PropertyName
htmlDisabledProperty() bool
binding() any
onResize(self View, x, y, width, height float64)
@ -130,7 +129,6 @@ type viewData struct {
noResizeEvent bool
created bool
hasFocus bool
hasHtmlDisabled bool
get func(tag PropertyName) any
set func(tag PropertyName, value any) []PropertyName
remove func(tag PropertyName) []PropertyName
@ -178,7 +176,6 @@ func (view *viewData) init(session Session) {
view.singleTransition = map[PropertyName]AnimationProperty{}
view.noResizeEvent = false
view.created = false
view.hasHtmlDisabled = false
view.fileLoader = map[string]func(FileInfo, []byte){}
}
@ -472,7 +469,7 @@ func (view *viewData) setFunc(tag PropertyName, value any) []PropertyName {
view.setRaw(tag, value)
return []PropertyName{UserData}
case Style, StyleDisabled:
case Style:
if text, ok := value.(string); ok {
view.setRaw(tag, text)
return []PropertyName{tag}
@ -634,39 +631,15 @@ func (view *viewData) propertyChanged(tag PropertyName) {
session.updateProperty(htmlID, "tabindex", "-1")
}
case Style, StyleDisabled:
session.updateProperty(htmlID, "class", view.htmlClass(IsDisabled(view)))
case Style:
session.updateProperty(htmlID, "class", view.htmlClass())
case Disabled:
tabIndex := GetTabIndex(view, htmlID)
enabledClass := view.htmlClass(false)
disabledClass := view.htmlClass(true)
session.startUpdateScript(htmlID)
if IsDisabled(view) {
session.updateProperty(htmlID, "data-disabled", "1")
if view.htmlDisabledProperty() {
session.updateProperty(htmlID, "disabled", true)
}
if tabIndex >= 0 {
session.updateProperty(htmlID, "tabindex", -1)
}
if enabledClass != disabledClass {
session.updateProperty(htmlID, "class", disabledClass)
}
if disabled, ok := boolProperty(view, Disabled, session); ok && disabled {
session.updateProperty(htmlID, "inert", true)
} else {
session.updateProperty(htmlID, "data-disabled", "0")
if view.htmlDisabledProperty() {
session.removeProperty(htmlID, "disabled")
}
if tabIndex >= 0 {
session.updateProperty(htmlID, "tabindex", tabIndex)
}
if enabledClass != disabledClass {
session.updateProperty(htmlID, "class", enabledClass)
}
session.removeProperty(htmlID, "inert")
}
session.finishUpdateScript(htmlID)
updateInnerHTML(htmlID, session)
case Visibility:
switch GetVisibility(view) {
@ -1102,20 +1075,11 @@ func (view *viewData) cssStyle(self View, builder cssBuilder) {
}
}
func (view *viewData) htmlDisabledProperty() bool {
return view.hasHtmlDisabled
}
func (view *viewData) htmlProperties(self View, buffer *strings.Builder) {
view.created = true
if IsDisabled(self) {
buffer.WriteString(` data-disabled="1"`)
if view.hasHtmlDisabled {
buffer.WriteString(` disabled`)
}
} else {
buffer.WriteString(` data-disabled="0"`)
if disabled, ok := boolProperty(view, Disabled, view.Session()); ok && disabled {
buffer.WriteString(` inert`)
}
if view.frame.Left != 0 || view.frame.Top != 0 || view.frame.Width != 0 || view.frame.Height != 0 {
@ -1135,9 +1099,7 @@ func viewHTML(view View, buffer *strings.Builder, htmlTag string) {
buffer.WriteString(view.htmlID())
buffer.WriteRune('"')
disabled := IsDisabled(view)
if cls := view.htmlClass(disabled); cls != "" {
if cls := view.htmlClass(); cls != "" {
buffer.WriteString(` class="`)
buffer.WriteString(cls)
buffer.WriteRune('"')
@ -1161,12 +1123,10 @@ func viewHTML(view View, buffer *strings.Builder, htmlTag string) {
buffer.WriteRune(' ')
}
if !disabled {
if tabIndex := GetTabIndex(view); tabIndex >= 0 {
buffer.WriteString(`tabindex="`)
buffer.WriteString(strconv.Itoa(tabIndex))
buffer.WriteString(`" `)
}
if tabIndex := GetTabIndex(view); tabIndex >= 0 {
buffer.WriteString(`tabindex="`)
buffer.WriteString(strconv.Itoa(tabIndex))
buffer.WriteString(`" `)
}
if tooltip := GetTooltip(view); tooltip != "" {
@ -1197,19 +1157,10 @@ func viewHTML(view View, buffer *strings.Builder, htmlTag string) {
}
}
func (view *viewData) htmlClass(disabled bool) string {
func (view *viewData) htmlClass() string {
cls := "ruiView"
disabledStyle := false
if disabled {
if value, ok := stringProperty(view, StyleDisabled, view.Session()); ok && value != "" {
cls += " " + value
disabledStyle = true
}
}
if !disabledStyle {
if value, ok := stringProperty(view, Style, view.Session()); ok {
cls += " " + value
}
if value, ok := stringProperty(view, Style, view.Session()); ok {
cls += " " + value
}
if view.systemClass != "" {

View File

@ -128,17 +128,6 @@ func GetStyle(view View, subviewID ...string) string {
return ""
}
// GetDisabledStyle returns the disabled subview style id.
// If the second argument (subviewID) is not specified or it is "" then a style of the first argument (view) is returned
func GetDisabledStyle(view View, subviewID ...string) string {
if view = getSubview(view, subviewID); view != nil {
if style, ok := stringProperty(view, StyleDisabled, view.Session()); ok {
return style
}
}
return ""
}
// GetVisibility returns the subview visibility. One of the following values is returned:
// Visible (0), Invisible (1), or Gone (2)
// If the second argument (subviewID) is not specified or it is "" then a visibility of the first argument (view) is returned
@ -615,21 +604,13 @@ func GetNotTranslate(view View, subviewID ...string) bool {
func valueFromStyle(view View, tag PropertyName) any {
session := view.Session()
getValue := func(styleTag PropertyName) any {
if style, ok := stringProperty(view, styleTag, session); ok {
if style, ok := session.resolveConstants(style); ok {
return session.styleProperty(style, tag)
}
}
return nil
}
if IsDisabled(view) {
if value := getValue(StyleDisabled); value != nil {
return value
if style, ok := stringProperty(view, Style, session); ok {
if style, ok := session.resolveConstants(style); ok {
return session.styleProperty(style, tag)
}
}
return getValue(Style)
return nil
}
func stringStyledProperty(view View, subviewID []string, tag PropertyName, inherit bool) string {