mirror of https://github.com/anoshenko/rui.git
				
				
				
			Add a listener for changing a property value
This commit is contained in:
		
							parent
							
								
									584983b818
								
							
						
					
					
						commit
						7e2804f002
					
				|  | @ -53,6 +53,7 @@ func (canvasView *canvasViewData) remove(tag string) { | ||||||
| 	if tag == DrawFunction { | 	if tag == DrawFunction { | ||||||
| 		canvasView.drawer = nil | 		canvasView.drawer = nil | ||||||
| 		canvasView.Redraw() | 		canvasView.Redraw() | ||||||
|  | 		canvasView.propertyChangedEvent(tag) | ||||||
| 	} else { | 	} else { | ||||||
| 		canvasView.viewData.remove(tag) | 		canvasView.viewData.remove(tag) | ||||||
| 	} | 	} | ||||||
|  | @ -73,6 +74,7 @@ func (canvasView *canvasViewData) set(tag string, value interface{}) bool { | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
| 		canvasView.Redraw() | 		canvasView.Redraw() | ||||||
|  | 		canvasView.propertyChangedEvent(tag) | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										67
									
								
								checkbox.go
								
								
								
								
							
							
						
						
									
										67
									
								
								checkbox.go
								
								
								
								
							|  | @ -57,13 +57,16 @@ func (button *checkboxData) Get(tag string) interface{} { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (button *checkboxData) Set(tag string, value interface{}) bool { | func (button *checkboxData) Set(tag string, value interface{}) bool { | ||||||
| 	switch strings.ToLower(tag) { | 	return button.set(tag, value) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (button *checkboxData) set(tag string, value interface{}) bool { | ||||||
|  | 	switch tag { | ||||||
| 	case CheckboxChangedEvent: | 	case CheckboxChangedEvent: | ||||||
| 		ok := button.setChangedListener(value) | 		if !button.setChangedListener(value) { | ||||||
| 		if !ok { |  | ||||||
| 			notCompatibleType(tag, value) | 			notCompatibleType(tag, value) | ||||||
|  | 			return false | ||||||
| 		} | 		} | ||||||
| 		return ok |  | ||||||
| 
 | 
 | ||||||
| 	case Checked: | 	case Checked: | ||||||
| 		oldChecked := button.checked() | 		oldChecked := button.checked() | ||||||
|  | @ -76,46 +79,60 @@ func (button *checkboxData) Set(tag string, value interface{}) bool { | ||||||
| 				button.changedCheckboxState(checked) | 				button.changedCheckboxState(checked) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		return true |  | ||||||
| 
 | 
 | ||||||
| 	case CheckboxHorizontalAlign, CheckboxVerticalAlign: | 	case CheckboxHorizontalAlign, CheckboxVerticalAlign: | ||||||
| 		if button.setEnumProperty(tag, value, enumProperties[tag].values) { | 		if !button.setEnumProperty(tag, value, enumProperties[tag].values) { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
| 		if button.created { | 		if button.created { | ||||||
| 			htmlID := button.htmlID() | 			htmlID := button.htmlID() | ||||||
| 			updateCSSStyle(htmlID, button.session) | 			updateCSSStyle(htmlID, button.session) | ||||||
| 			updateInnerHTML(htmlID, button.session) | 			updateInnerHTML(htmlID, button.session) | ||||||
| 		} | 		} | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 		return false |  | ||||||
| 
 | 
 | ||||||
| 	case VerticalAlign: | 	case VerticalAlign: | ||||||
| 		if button.setEnumProperty(tag, value, enumProperties[tag].values) { | 		if !button.setEnumProperty(tag, value, enumProperties[tag].values) { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
| 		if button.created { | 		if button.created { | ||||||
| 			updateCSSProperty(button.htmlID()+"content", "align-items", button.cssVerticalAlign(), button.session) | 			updateCSSProperty(button.htmlID()+"content", "align-items", button.cssVerticalAlign(), button.session) | ||||||
| 		} | 		} | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 		return false |  | ||||||
| 
 | 
 | ||||||
| 	case HorizontalAlign: | 	case HorizontalAlign: | ||||||
| 		if button.setEnumProperty(tag, value, enumProperties[tag].values) { | 		if !button.setEnumProperty(tag, value, enumProperties[tag].values) { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
| 		if button.created { | 		if button.created { | ||||||
| 			updateCSSProperty(button.htmlID()+"content", "justify-items", button.cssHorizontalAlign(), button.session) | 			updateCSSProperty(button.htmlID()+"content", "justify-items", button.cssHorizontalAlign(), button.session) | ||||||
| 		} | 		} | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 		return false |  | ||||||
| 
 | 
 | ||||||
| 	case CellVerticalAlign, CellHorizontalAlign, CellWidth, CellHeight: | 	case CellVerticalAlign, CellHorizontalAlign, CellWidth, CellHeight: | ||||||
| 		return false | 		return false | ||||||
|  | 
 | ||||||
|  | 	default: | ||||||
|  | 		return button.viewsContainerData.set(tag, value) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return button.viewsContainerData.Set(tag, value) | 	button.propertyChangedEvent(tag) | ||||||
|  | 	return true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (button *checkboxData) Remove(tag string) { | func (button *checkboxData) Remove(tag string) { | ||||||
| 	switch strings.ToLower(tag) { | 	button.remove(strings.ToLower(tag)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (button *checkboxData) remove(tag string) { | ||||||
|  | 	switch tag { | ||||||
|  | 	case ClickEvent: | ||||||
|  | 		if !button.viewsContainerData.set(ClickEvent, checkboxClickListener) { | ||||||
|  | 			delete(button.properties, tag) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	case KeyDownEvent: | ||||||
|  | 		if !button.viewsContainerData.set(KeyDownEvent, checkboxKeyListener) { | ||||||
|  | 			delete(button.properties, tag) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 	case CheckboxChangedEvent: | 	case CheckboxChangedEvent: | ||||||
| 		if len(button.checkedListeners) > 0 { | 		if len(button.checkedListeners) > 0 { | ||||||
| 			button.checkedListeners = []func(Checkbox, bool){} | 			button.checkedListeners = []func(Checkbox, bool){} | ||||||
|  | @ -124,27 +141,35 @@ func (button *checkboxData) Remove(tag string) { | ||||||
| 	case Checked: | 	case Checked: | ||||||
| 		oldChecked := button.checked() | 		oldChecked := button.checked() | ||||||
| 		delete(button.properties, tag) | 		delete(button.properties, tag) | ||||||
| 		if oldChecked { | 		if button.created && oldChecked { | ||||||
| 			button.changedCheckboxState(false) | 			button.changedCheckboxState(false) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	case CheckboxHorizontalAlign, CheckboxVerticalAlign: | 	case CheckboxHorizontalAlign, CheckboxVerticalAlign: | ||||||
| 		delete(button.properties, tag) | 		delete(button.properties, tag) | ||||||
|  | 		if button.created { | ||||||
| 			htmlID := button.htmlID() | 			htmlID := button.htmlID() | ||||||
| 			updateCSSStyle(htmlID, button.session) | 			updateCSSStyle(htmlID, button.session) | ||||||
| 			updateInnerHTML(htmlID, button.session) | 			updateInnerHTML(htmlID, button.session) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case VerticalAlign: | 	case VerticalAlign: | ||||||
| 		delete(button.properties, tag) | 		delete(button.properties, tag) | ||||||
|  | 		if button.created { | ||||||
| 			updateCSSProperty(button.htmlID()+"content", "align-items", button.cssVerticalAlign(), button.session) | 			updateCSSProperty(button.htmlID()+"content", "align-items", button.cssVerticalAlign(), button.session) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case HorizontalAlign: | 	case HorizontalAlign: | ||||||
| 		delete(button.properties, tag) | 		delete(button.properties, tag) | ||||||
|  | 		if button.created { | ||||||
| 			updateCSSProperty(button.htmlID()+"content", "justify-items", button.cssHorizontalAlign(), button.session) | 			updateCSSProperty(button.htmlID()+"content", "justify-items", button.cssHorizontalAlign(), button.session) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		button.viewsContainerData.Remove(tag) | 		button.viewsContainerData.remove(tag) | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
|  | 	button.propertyChangedEvent(tag) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (button *checkboxData) checked() bool { | func (button *checkboxData) checked() bool { | ||||||
|  |  | ||||||
|  | @ -56,7 +56,10 @@ func (picker *colorPickerData) Remove(tag string) { | ||||||
| func (picker *colorPickerData) remove(tag string) { | func (picker *colorPickerData) remove(tag string) { | ||||||
| 	switch tag { | 	switch tag { | ||||||
| 	case ColorChangedEvent: | 	case ColorChangedEvent: | ||||||
|  | 		if len(picker.colorChangedListeners) > 0 { | ||||||
| 			picker.colorChangedListeners = []func(ColorPicker, Color){} | 			picker.colorChangedListeners = []func(ColorPicker, Color){} | ||||||
|  | 			picker.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case ColorPickerValue: | 	case ColorPickerValue: | ||||||
| 		oldColor := GetColorPickerValue(picker, "") | 		oldColor := GetColorPickerValue(picker, "") | ||||||
|  | @ -131,15 +134,13 @@ func (picker *colorPickerData) set(tag string, value interface{}) bool { | ||||||
| 			} | 			} | ||||||
| 			picker.colorChangedListeners = listeners | 			picker.colorChangedListeners = listeners | ||||||
| 		} | 		} | ||||||
|  | 		picker.propertyChangedEvent(tag) | ||||||
| 		return true | 		return true | ||||||
| 
 | 
 | ||||||
| 	case ColorPickerValue: | 	case ColorPickerValue: | ||||||
| 		oldColor := GetColorPickerValue(picker, "") | 		oldColor := GetColorPickerValue(picker, "") | ||||||
| 		if picker.setColorProperty(ColorPickerValue, value) { | 		if picker.setColorProperty(ColorPickerValue, value) { | ||||||
| 			newValue := GetColorPickerValue(picker, "") |  | ||||||
| 			if oldColor != newValue { |  | ||||||
| 			picker.colorChanged(oldColor) | 			picker.colorChanged(oldColor) | ||||||
| 			} |  | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -150,12 +151,14 @@ func (picker *colorPickerData) set(tag string, value interface{}) bool { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (picker *colorPickerData) colorChanged(oldColor Color) { | func (picker *colorPickerData) colorChanged(oldColor Color) { | ||||||
| 	newColor := GetColorPickerValue(picker, "") | 	if newColor := GetColorPickerValue(picker, ""); oldColor != newColor { | ||||||
| 	if oldColor != newColor { | 		if picker.created { | ||||||
| 			picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, picker.htmlID(), newColor.rgbString())) | 			picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, picker.htmlID(), newColor.rgbString())) | ||||||
|  | 		} | ||||||
| 		for _, listener := range picker.colorChangedListeners { | 		for _, listener := range picker.colorChangedListeners { | ||||||
| 			listener(picker, newColor) | 			listener(picker, newColor) | ||||||
| 		} | 		} | ||||||
|  | 		picker.propertyChangedEvent(ColorTag) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -188,7 +191,7 @@ func (picker *colorPickerData) htmlProperties(self View, buffer *strings.Builder | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (picker *colorPickerData) htmlDisabledProperties(self View, buffer *strings.Builder) { | func (picker *colorPickerData) htmlDisabledProperties(self View, buffer *strings.Builder) { | ||||||
| 	if IsDisabled(self) { | 	if IsDisabled(self, "") { | ||||||
| 		buffer.WriteString(` disabled`) | 		buffer.WriteString(` disabled`) | ||||||
| 	} | 	} | ||||||
| 	picker.viewData.htmlDisabledProperties(self, buffer) | 	picker.viewData.htmlDisabledProperties(self, buffer) | ||||||
|  |  | ||||||
|  | @ -82,6 +82,7 @@ func (columnLayout *columnLayoutData) Remove(tag string) { | ||||||
| 
 | 
 | ||||||
| func (columnLayout *columnLayoutData) remove(tag string) { | func (columnLayout *columnLayoutData) remove(tag string) { | ||||||
| 	columnLayout.viewsContainerData.remove(tag) | 	columnLayout.viewsContainerData.remove(tag) | ||||||
|  | 	if columnLayout.created { | ||||||
| 		switch tag { | 		switch tag { | ||||||
| 		case ColumnCount, ColumnWidth, ColumnGap: | 		case ColumnCount, ColumnWidth, ColumnGap: | ||||||
| 			updateCSSProperty(columnLayout.htmlID(), tag, "", columnLayout.Session()) | 			updateCSSProperty(columnLayout.htmlID(), tag, "", columnLayout.Session()) | ||||||
|  | @ -89,6 +90,7 @@ func (columnLayout *columnLayoutData) remove(tag string) { | ||||||
| 		case ColumnSeparator: | 		case ColumnSeparator: | ||||||
| 			updateCSSProperty(columnLayout.htmlID(), "column-rule", "", columnLayout.Session()) | 			updateCSSProperty(columnLayout.htmlID(), "column-rule", "", columnLayout.Session()) | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (columnLayout *columnLayoutData) Set(tag string, value interface{}) bool { | func (columnLayout *columnLayoutData) Set(tag string, value interface{}) bool { | ||||||
|  | @ -101,22 +103,11 @@ func (columnLayout *columnLayoutData) set(tag string, value interface{}) bool { | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	switch tag { | 	if !columnLayout.viewsContainerData.set(tag, value) { | ||||||
| 	case ColumnCount: |  | ||||||
| 		if columnLayout.setIntProperty(tag, value) { |  | ||||||
| 			session := columnLayout.Session() |  | ||||||
| 			if count, ok := intProperty(columnLayout, tag, session, 0); ok && count > 0 { |  | ||||||
| 				updateCSSProperty(columnLayout.htmlID(), tag, strconv.Itoa(count), session) |  | ||||||
| 			} else { |  | ||||||
| 				updateCSSProperty(columnLayout.htmlID(), tag, "auto", session) |  | ||||||
| 			} |  | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 		return false | 		return false | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ok := columnLayout.viewsContainerData.set(tag, value) | 	if columnLayout.created { | ||||||
| 	if ok { |  | ||||||
| 		switch tag { | 		switch tag { | ||||||
| 		case ColumnSeparator: | 		case ColumnSeparator: | ||||||
| 			css := "" | 			css := "" | ||||||
|  | @ -126,9 +117,17 @@ func (columnLayout *columnLayoutData) set(tag string, value interface{}) bool { | ||||||
| 				css = separator.cssValue(columnLayout.Session()) | 				css = separator.cssValue(columnLayout.Session()) | ||||||
| 			} | 			} | ||||||
| 			updateCSSProperty(columnLayout.htmlID(), "column-rule", css, session) | 			updateCSSProperty(columnLayout.htmlID(), "column-rule", css, session) | ||||||
|  | 
 | ||||||
|  | 		case ColumnCount: | ||||||
|  | 			session := columnLayout.Session() | ||||||
|  | 			if count, ok := intProperty(columnLayout, tag, session, 0); ok && count > 0 { | ||||||
|  | 				updateCSSProperty(columnLayout.htmlID(), tag, strconv.Itoa(count), session) | ||||||
|  | 			} else { | ||||||
|  | 				updateCSSProperty(columnLayout.htmlID(), tag, "auto", session) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	return ok | 	} | ||||||
|  | 	return true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetColumnCount returns int value which specifies number of columns into which the content of
 | // GetColumnCount returns int value which specifies number of columns into which the content of
 | ||||||
|  |  | ||||||
|  | @ -68,6 +68,10 @@ func (customView *CustomViewData) SetAnimated(tag string, value interface{}, ani | ||||||
| 	return customView.superView.SetAnimated(tag, value, animation) | 	return customView.superView.SetAnimated(tag, value, animation) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (customView *CustomViewData) SetChangeListener(tag string, listener func(View, string)) { | ||||||
|  | 	customView.superView.SetChangeListener(tag, listener) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Remove removes the property with name defined by the argument
 | // Remove removes the property with name defined by the argument
 | ||||||
| func (customView *CustomViewData) Remove(tag string) { | func (customView *CustomViewData) Remove(tag string) { | ||||||
| 	customView.superView.Remove(tag) | 	customView.superView.Remove(tag) | ||||||
|  |  | ||||||
|  | @ -63,28 +63,47 @@ func (picker *datePickerData) remove(tag string) { | ||||||
| 	case DateChangedEvent: | 	case DateChangedEvent: | ||||||
| 		if len(picker.dateChangedListeners) > 0 { | 		if len(picker.dateChangedListeners) > 0 { | ||||||
| 			picker.dateChangedListeners = []func(DatePicker, time.Time){} | 			picker.dateChangedListeners = []func(DatePicker, time.Time){} | ||||||
|  | 			picker.propertyChangedEvent(tag) | ||||||
| 		} | 		} | ||||||
|  | 		return | ||||||
| 
 | 
 | ||||||
| 	case DatePickerMin: | 	case DatePickerMin: | ||||||
| 		delete(picker.properties, DatePickerMin) | 		delete(picker.properties, DatePickerMin) | ||||||
|  | 		if picker.created { | ||||||
| 			removeProperty(picker.htmlID(), Min, picker.session) | 			removeProperty(picker.htmlID(), Min, picker.session) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case DatePickerMax: | 	case DatePickerMax: | ||||||
| 		delete(picker.properties, DatePickerMax) | 		delete(picker.properties, DatePickerMax) | ||||||
|  | 		if picker.created { | ||||||
| 			removeProperty(picker.htmlID(), Max, picker.session) | 			removeProperty(picker.htmlID(), Max, picker.session) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case DatePickerStep: | 	case DatePickerStep: | ||||||
| 		delete(picker.properties, DatePickerMax) | 		delete(picker.properties, DatePickerMax) | ||||||
|  | 		if picker.created { | ||||||
| 			removeProperty(picker.htmlID(), Step, picker.session) | 			removeProperty(picker.htmlID(), Step, picker.session) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case DatePickerValue: | 	case DatePickerValue: | ||||||
|  | 		if _, ok := picker.properties[DatePickerValue]; ok { | ||||||
| 			delete(picker.properties, DatePickerValue) | 			delete(picker.properties, DatePickerValue) | ||||||
| 		updateProperty(picker.htmlID(), Value, time.Now().Format(dateFormat), picker.session) | 			date := GetDatePickerValue(picker, "") | ||||||
|  | 			if picker.created { | ||||||
|  | 				picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, picker.htmlID(), date.Format(dateFormat))) | ||||||
|  | 			} | ||||||
|  | 			for _, listener := range picker.dateChangedListeners { | ||||||
|  | 				listener(picker, date) | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		picker.viewData.remove(tag) | 		picker.viewData.remove(tag) | ||||||
| 		picker.propertyChanged(tag) | 		return | ||||||
| 	} | 	} | ||||||
|  | 	picker.propertyChangedEvent(tag) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (picker *datePickerData) Set(tag string, value interface{}) bool { | func (picker *datePickerData) Set(tag string, value interface{}) bool { | ||||||
|  | @ -98,7 +117,6 @@ func (picker *datePickerData) set(tag string, value interface{}) bool { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	setTimeValue := func(tag string) (time.Time, bool) { | 	setTimeValue := func(tag string) (time.Time, bool) { | ||||||
| 		//old, oldOK := getDateProperty(picker, tag, shortTag)
 |  | ||||||
| 		switch value := value.(type) { | 		switch value := value.(type) { | ||||||
| 		case time.Time: | 		case time.Time: | ||||||
| 			picker.properties[tag] = value | 			picker.properties[tag] = value | ||||||
|  | @ -122,8 +140,11 @@ func (picker *datePickerData) set(tag string, value interface{}) bool { | ||||||
| 		old, oldOK := getDateProperty(picker, DatePickerMin, Min) | 		old, oldOK := getDateProperty(picker, DatePickerMin, Min) | ||||||
| 		if date, ok := setTimeValue(DatePickerMin); ok { | 		if date, ok := setTimeValue(DatePickerMin); ok { | ||||||
| 			if !oldOK || date != old { | 			if !oldOK || date != old { | ||||||
|  | 				if picker.created { | ||||||
| 					updateProperty(picker.htmlID(), Min, date.Format(dateFormat), picker.session) | 					updateProperty(picker.htmlID(), Min, date.Format(dateFormat), picker.session) | ||||||
| 				} | 				} | ||||||
|  | 				picker.propertyChangedEvent(tag) | ||||||
|  | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -131,33 +152,41 @@ func (picker *datePickerData) set(tag string, value interface{}) bool { | ||||||
| 		old, oldOK := getDateProperty(picker, DatePickerMax, Max) | 		old, oldOK := getDateProperty(picker, DatePickerMax, Max) | ||||||
| 		if date, ok := setTimeValue(DatePickerMax); ok { | 		if date, ok := setTimeValue(DatePickerMax); ok { | ||||||
| 			if !oldOK || date != old { | 			if !oldOK || date != old { | ||||||
|  | 				if picker.created { | ||||||
| 					updateProperty(picker.htmlID(), Max, date.Format(dateFormat), picker.session) | 					updateProperty(picker.htmlID(), Max, date.Format(dateFormat), picker.session) | ||||||
| 				} | 				} | ||||||
|  | 				picker.propertyChangedEvent(tag) | ||||||
|  | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	case DatePickerStep: | 	case DatePickerStep: | ||||||
| 		oldStep := GetDatePickerStep(picker, "") | 		oldStep := GetDatePickerStep(picker, "") | ||||||
| 		if picker.setIntProperty(DatePickerStep, value) { | 		if picker.setIntProperty(DatePickerStep, value) { | ||||||
| 			step := GetDatePickerStep(picker, "") | 			if step := GetDatePickerStep(picker, ""); oldStep != step { | ||||||
| 			if oldStep != step { | 				if picker.created { | ||||||
| 					if step > 0 { | 					if step > 0 { | ||||||
| 						updateProperty(picker.htmlID(), Step, strconv.Itoa(step), picker.session) | 						updateProperty(picker.htmlID(), Step, strconv.Itoa(step), picker.session) | ||||||
| 					} else { | 					} else { | ||||||
| 						removeProperty(picker.htmlID(), Step, picker.session) | 						removeProperty(picker.htmlID(), Step, picker.session) | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | 				picker.propertyChangedEvent(tag) | ||||||
|  | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	case DatePickerValue: | 	case DatePickerValue: | ||||||
| 		oldDate := GetDatePickerValue(picker, "") | 		oldDate := GetDatePickerValue(picker, "") | ||||||
| 		if date, ok := setTimeValue(DatePickerMax); ok { | 		if date, ok := setTimeValue(DatePickerMax); ok { | ||||||
| 			picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, picker.htmlID(), date.Format(dateFormat))) |  | ||||||
| 			if date != oldDate { | 			if date != oldDate { | ||||||
|  | 				if picker.created { | ||||||
|  | 					picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, picker.htmlID(), date.Format(dateFormat))) | ||||||
|  | 				} | ||||||
| 				for _, listener := range picker.dateChangedListeners { | 				for _, listener := range picker.dateChangedListeners { | ||||||
| 					listener(picker, date) | 					listener(picker, date) | ||||||
| 				} | 				} | ||||||
|  | 				picker.propertyChangedEvent(tag) | ||||||
| 			} | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
|  | @ -214,13 +243,11 @@ func (picker *datePickerData) set(tag string, value interface{}) bool { | ||||||
| 			} | 			} | ||||||
| 			picker.dateChangedListeners = listeners | 			picker.dateChangedListeners = listeners | ||||||
| 		} | 		} | ||||||
|  | 		picker.propertyChangedEvent(tag) | ||||||
| 		return true | 		return true | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		if picker.viewData.set(tag, value) { | 		return picker.viewData.set(tag, value) | ||||||
| 			picker.propertyChanged(tag) |  | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 	return false | 	return false | ||||||
| } | } | ||||||
|  | @ -274,7 +301,7 @@ func (picker *datePickerData) htmlProperties(self View, buffer *strings.Builder) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (picker *datePickerData) htmlDisabledProperties(self View, buffer *strings.Builder) { | func (picker *datePickerData) htmlDisabledProperties(self View, buffer *strings.Builder) { | ||||||
| 	if IsDisabled(self) { | 	if IsDisabled(self, "") { | ||||||
| 		buffer.WriteString(` disabled`) | 		buffer.WriteString(` disabled`) | ||||||
| 	} | 	} | ||||||
| 	picker.viewData.htmlDisabledProperties(self, buffer) | 	picker.viewData.htmlDisabledProperties(self, buffer) | ||||||
|  |  | ||||||
|  | @ -57,6 +57,15 @@ func createTextStyleDemo(session rui.Session) rui.View { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	rui.SetChangeListener(view, "textStyleFont", rui.Current, func(v rui.View, tag string) { | ||||||
|  | 		fonts := []string{"", "serif", "sans-serif", "\"Courier new\", monospace", "cursive", "fantasy"} | ||||||
|  | 		if number := rui.GetDropDownCurrent(v, ""); number > 0 && number < len(fonts) { | ||||||
|  | 			rui.Set(view, "textStyleText", rui.FontName, fonts[number]) | ||||||
|  | 		} else { | ||||||
|  | 			rui.Set(view, "textStyleText", rui.FontName, nil) | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  | 	/* | ||||||
| 		rui.Set(view, "textStyleFont", rui.DropDownEvent, func(number int) { | 		rui.Set(view, "textStyleFont", rui.DropDownEvent, func(number int) { | ||||||
| 			fonts := []string{"", "serif", "sans-serif", "\"Courier new\", monospace", "cursive", "fantasy"} | 			fonts := []string{"", "serif", "sans-serif", "\"Courier new\", monospace", "cursive", "fantasy"} | ||||||
| 			if number > 0 && number < len(fonts) { | 			if number > 0 && number < len(fonts) { | ||||||
|  | @ -65,6 +74,7 @@ func createTextStyleDemo(session rui.Session) rui.View { | ||||||
| 				rui.Set(view, "textStyleText", rui.FontName, nil) | 				rui.Set(view, "textStyleText", rui.FontName, nil) | ||||||
| 			} | 			} | ||||||
| 		}) | 		}) | ||||||
|  | 	*/ | ||||||
| 
 | 
 | ||||||
| 	rui.Set(view, "textStyleSize", rui.DropDownEvent, func(number int) { | 	rui.Set(view, "textStyleSize", rui.DropDownEvent, func(number int) { | ||||||
| 		sizes := []string{"1em", "14pt", "12px", "1.5em"} | 		sizes := []string{"1em", "14pt", "12px", "1.5em"} | ||||||
|  |  | ||||||
|  | @ -2,6 +2,8 @@ package rui | ||||||
| 
 | 
 | ||||||
| import "strings" | import "strings" | ||||||
| 
 | 
 | ||||||
|  | // TODO Expanded event
 | ||||||
|  | 
 | ||||||
| const ( | const ( | ||||||
| 	// Summary is the constant for the "summary" property tag.
 | 	// Summary is the constant for the "summary" property tag.
 | ||||||
| 	// The contents of the "summary" property are used as the label for the disclosure widget.
 | 	// The contents of the "summary" property are used as the label for the disclosure widget.
 | ||||||
|  | @ -45,18 +47,14 @@ func (detailsView *detailsViewData) Remove(tag string) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (detailsView *detailsViewData) remove(tag string) { | func (detailsView *detailsViewData) remove(tag string) { | ||||||
| 	if _, ok := detailsView.properties[tag]; ok { | 	detailsView.viewsContainerData.remove(tag) | ||||||
|  | 	if detailsView.created { | ||||||
| 		switch tag { | 		switch tag { | ||||||
| 		case Summary: | 		case Summary: | ||||||
| 			delete(detailsView.properties, tag) |  | ||||||
| 			updateInnerHTML(detailsView.htmlID(), detailsView.Session()) | 			updateInnerHTML(detailsView.htmlID(), detailsView.Session()) | ||||||
| 
 | 
 | ||||||
| 		case Expanded: | 		case Expanded: | ||||||
| 			delete(detailsView.properties, tag) |  | ||||||
| 			removeProperty(detailsView.htmlID(), "open", detailsView.Session()) | 			removeProperty(detailsView.htmlID(), "open", detailsView.Session()) | ||||||
| 
 |  | ||||||
| 		default: |  | ||||||
| 			detailsView.viewsContainerData.remove(tag) |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | @ -66,6 +64,11 @@ func (detailsView *detailsViewData) Set(tag string, value interface{}) bool { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (detailsView *detailsViewData) set(tag string, value interface{}) bool { | func (detailsView *detailsViewData) set(tag string, value interface{}) bool { | ||||||
|  | 	if value == nil { | ||||||
|  | 		detailsView.remove(tag) | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	switch tag { | 	switch tag { | ||||||
| 	case Summary: | 	case Summary: | ||||||
| 		switch value := value.(type) { | 		switch value := value.(type) { | ||||||
|  | @ -86,23 +89,29 @@ func (detailsView *detailsViewData) set(tag string, value interface{}) bool { | ||||||
| 			notCompatibleType(tag, value) | 			notCompatibleType(tag, value) | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
|  | 		if detailsView.created { | ||||||
| 			updateInnerHTML(detailsView.htmlID(), detailsView.Session()) | 			updateInnerHTML(detailsView.htmlID(), detailsView.Session()) | ||||||
| 		return true | 		} | ||||||
| 
 | 
 | ||||||
| 	case Expanded: | 	case Expanded: | ||||||
| 		if detailsView.setBoolProperty(tag, value) { | 		if !detailsView.setBoolProperty(tag, value) { | ||||||
|  | 			notCompatibleType(tag, value) | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
|  | 		if detailsView.created { | ||||||
| 			if IsDetailsExpanded(detailsView, "") { | 			if IsDetailsExpanded(detailsView, "") { | ||||||
| 				updateProperty(detailsView.htmlID(), "open", "", detailsView.Session()) | 				updateProperty(detailsView.htmlID(), "open", "", detailsView.Session()) | ||||||
| 			} else { | 			} else { | ||||||
| 				removeProperty(detailsView.htmlID(), "open", detailsView.Session()) | 				removeProperty(detailsView.htmlID(), "open", detailsView.Session()) | ||||||
| 			} | 			} | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 		notCompatibleType(tag, value) |  | ||||||
| 		return false |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 	default: | ||||||
| 		return detailsView.viewsContainerData.Set(tag, value) | 		return detailsView.viewsContainerData.Set(tag, value) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	detailsView.propertyChangedEvent(tag) | ||||||
|  | 	return true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (detailsView *detailsViewData) Get(tag string) interface{} { | func (detailsView *detailsViewData) Get(tag string) interface{} { | ||||||
|  |  | ||||||
|  | @ -48,19 +48,31 @@ func (list *dropDownListData) remove(tag string) { | ||||||
| 	case Items: | 	case Items: | ||||||
| 		if len(list.items) > 0 { | 		if len(list.items) > 0 { | ||||||
| 			list.items = []string{} | 			list.items = []string{} | ||||||
|  | 			if list.created { | ||||||
| 				updateInnerHTML(list.htmlID(), list.session) | 				updateInnerHTML(list.htmlID(), list.session) | ||||||
| 			} | 			} | ||||||
| 
 | 			list.propertyChangedEvent(tag) | ||||||
| 	case Current: | 		} | ||||||
| 		list.set(Current, 0) |  | ||||||
| 
 | 
 | ||||||
| 	case DropDownEvent: | 	case DropDownEvent: | ||||||
| 		if len(list.dropDownListener) > 0 { | 		if len(list.dropDownListener) > 0 { | ||||||
| 			list.dropDownListener = []func(DropDownList, int){} | 			list.dropDownListener = []func(DropDownList, int){} | ||||||
|  | 			list.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	case Current: | ||||||
|  | 		oldCurrent := GetDropDownCurrent(list, "") | ||||||
|  | 		delete(list.properties, Current) | ||||||
|  | 		if oldCurrent != 0 { | ||||||
|  | 			if list.created { | ||||||
|  | 				list.session.runScript(fmt.Sprintf(`selectDropDownListItem('%s', %d)`, list.htmlID(), 0)) | ||||||
|  | 			} | ||||||
|  | 			list.onSelectedItemChanged(0) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		list.viewData.remove(tag) | 		list.viewData.remove(tag) | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -73,23 +85,22 @@ func (list *dropDownListData) set(tag string, value interface{}) bool { | ||||||
| 	case Items: | 	case Items: | ||||||
| 		return list.setItems(value) | 		return list.setItems(value) | ||||||
| 
 | 
 | ||||||
|  | 	case DropDownEvent: | ||||||
|  | 		return list.setDropDownListener(value) | ||||||
|  | 
 | ||||||
| 	case Current: | 	case Current: | ||||||
| 		oldCurrent := GetDropDownCurrent(list, "") | 		oldCurrent := GetDropDownCurrent(list, "") | ||||||
| 		if !list.setIntProperty(Current, value) { | 		if !list.setIntProperty(Current, value) { | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if !list.session.ignoreViewUpdates() { | 		if current := GetDropDownCurrent(list, ""); oldCurrent != current { | ||||||
| 			current := GetDropDownCurrent(list, "") | 			if list.created { | ||||||
| 			if oldCurrent != current { |  | ||||||
| 				list.session.runScript(fmt.Sprintf(`selectDropDownListItem('%s', %d)`, list.htmlID(), current)) | 				list.session.runScript(fmt.Sprintf(`selectDropDownListItem('%s', %d)`, list.htmlID(), current)) | ||||||
|  | 			} | ||||||
| 			list.onSelectedItemChanged(current) | 			list.onSelectedItemChanged(current) | ||||||
| 		} | 		} | ||||||
| 		} |  | ||||||
| 		return true | 		return true | ||||||
| 
 |  | ||||||
| 	case DropDownEvent: |  | ||||||
| 		return list.setDropDownListener(value) |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return list.viewData.set(tag, value) | 	return list.viewData.set(tag, value) | ||||||
|  | @ -160,9 +171,11 @@ func (list *dropDownListData) setItems(value interface{}) bool { | ||||||
| 		return false | 		return false | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if !list.session.ignoreViewUpdates() { | 	if list.created { | ||||||
| 		updateInnerHTML(list.htmlID(), list.session) | 		updateInnerHTML(list.htmlID(), list.session) | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	list.propertyChangedEvent(Items) | ||||||
| 	return true | 	return true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -170,17 +183,14 @@ func (list *dropDownListData) setDropDownListener(value interface{}) bool { | ||||||
| 	switch value := value.(type) { | 	switch value := value.(type) { | ||||||
| 	case func(DropDownList, int): | 	case func(DropDownList, int): | ||||||
| 		list.dropDownListener = []func(DropDownList, int){value} | 		list.dropDownListener = []func(DropDownList, int){value} | ||||||
| 		return true |  | ||||||
| 
 | 
 | ||||||
| 	case func(int): | 	case func(int): | ||||||
| 		list.dropDownListener = []func(DropDownList, int){func(list DropDownList, index int) { | 		list.dropDownListener = []func(DropDownList, int){func(list DropDownList, index int) { | ||||||
| 			value(index) | 			value(index) | ||||||
| 		}} | 		}} | ||||||
| 		return true |  | ||||||
| 
 | 
 | ||||||
| 	case []func(DropDownList, int): | 	case []func(DropDownList, int): | ||||||
| 		list.dropDownListener = value | 		list.dropDownListener = value | ||||||
| 		return true |  | ||||||
| 
 | 
 | ||||||
| 	case []func(int): | 	case []func(int): | ||||||
| 		listeners := make([]func(DropDownList, int), len(value)) | 		listeners := make([]func(DropDownList, int), len(value)) | ||||||
|  | @ -194,7 +204,6 @@ func (list *dropDownListData) setDropDownListener(value interface{}) bool { | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		list.dropDownListener = listeners | 		list.dropDownListener = listeners | ||||||
| 		return true |  | ||||||
| 
 | 
 | ||||||
| 	case []interface{}: | 	case []interface{}: | ||||||
| 		listeners := make([]func(DropDownList, int), len(value)) | 		listeners := make([]func(DropDownList, int), len(value)) | ||||||
|  | @ -216,13 +225,16 @@ func (list *dropDownListData) setDropDownListener(value interface{}) bool { | ||||||
| 				notCompatibleType(DropDownEvent, value) | 				notCompatibleType(DropDownEvent, value) | ||||||
| 				return false | 				return false | ||||||
| 			} | 			} | ||||||
|  | 		} | ||||||
| 		list.dropDownListener = listeners | 		list.dropDownListener = listeners | ||||||
| 		} |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
|  | 	default: | ||||||
| 		notCompatibleType(DropDownEvent, value) | 		notCompatibleType(DropDownEvent, value) | ||||||
| 		return false | 		return false | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	list.propertyChangedEvent(DropDownEvent) | ||||||
|  | 	return true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (list *dropDownListData) Get(tag string) interface{} { | func (list *dropDownListData) Get(tag string) interface{} { | ||||||
|  | @ -280,7 +292,7 @@ func (list *dropDownListData) htmlProperties(self View, buffer *strings.Builder) | ||||||
| 
 | 
 | ||||||
| func (list *dropDownListData) htmlDisabledProperties(self View, buffer *strings.Builder) { | func (list *dropDownListData) htmlDisabledProperties(self View, buffer *strings.Builder) { | ||||||
| 	list.viewData.htmlDisabledProperties(self, buffer) | 	list.viewData.htmlDisabledProperties(self, buffer) | ||||||
| 	if IsDisabled(list) { | 	if IsDisabled(list, "") { | ||||||
| 		buffer.WriteString(`disabled`) | 		buffer.WriteString(`disabled`) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | @ -289,6 +301,7 @@ func (list *dropDownListData) onSelectedItemChanged(number int) { | ||||||
| 	for _, listener := range list.dropDownListener { | 	for _, listener := range list.dropDownListener { | ||||||
| 		listener(list, number) | 		listener(list, number) | ||||||
| 	} | 	} | ||||||
|  | 	list.propertyChangedEvent(Current) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (list *dropDownListData) handleCommand(self View, command string, data DataObject) bool { | func (list *dropDownListData) handleCommand(self View, command string, data DataObject) bool { | ||||||
|  |  | ||||||
							
								
								
									
										66
									
								
								editView.go
								
								
								
								
							
							
						
						
									
										66
									
								
								editView.go
								
								
								
								
							|  | @ -84,63 +84,98 @@ func (edit *editViewData) Remove(tag string) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (edit *editViewData) remove(tag string) { | func (edit *editViewData) remove(tag string) { | ||||||
| 	if _, ok := edit.properties[tag]; ok { | 	_, exists := edit.properties[tag] | ||||||
| 	switch tag { | 	switch tag { | ||||||
| 	case Hint: | 	case Hint: | ||||||
|  | 		if exists { | ||||||
| 			delete(edit.properties, Hint) | 			delete(edit.properties, Hint) | ||||||
|  | 			if edit.created { | ||||||
| 				removeProperty(edit.htmlID(), "placeholder", edit.session) | 				removeProperty(edit.htmlID(), "placeholder", edit.session) | ||||||
|  | 			} | ||||||
|  | 			edit.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case MaxLength: | 	case MaxLength: | ||||||
|  | 		if exists { | ||||||
| 			delete(edit.properties, MaxLength) | 			delete(edit.properties, MaxLength) | ||||||
|  | 			if edit.created { | ||||||
| 				removeProperty(edit.htmlID(), "maxlength", edit.session) | 				removeProperty(edit.htmlID(), "maxlength", edit.session) | ||||||
|  | 			} | ||||||
|  | 			edit.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case ReadOnly, Spellcheck: | 	case ReadOnly, Spellcheck: | ||||||
|  | 		if exists { | ||||||
| 			delete(edit.properties, tag) | 			delete(edit.properties, tag) | ||||||
|  | 			if edit.created { | ||||||
| 				updateBoolProperty(edit.htmlID(), tag, false, edit.session) | 				updateBoolProperty(edit.htmlID(), tag, false, edit.session) | ||||||
|  | 			} | ||||||
|  | 			edit.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case EditTextChangedEvent: | 	case EditTextChangedEvent: | ||||||
| 		if len(edit.textChangeListeners) > 0 { | 		if len(edit.textChangeListeners) > 0 { | ||||||
| 			edit.textChangeListeners = []func(EditView, string){} | 			edit.textChangeListeners = []func(EditView, string){} | ||||||
|  | 			edit.propertyChangedEvent(tag) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	case Text: | 	case Text: | ||||||
|  | 		if exists { | ||||||
| 			oldText := GetText(edit, "") | 			oldText := GetText(edit, "") | ||||||
| 			delete(edit.properties, tag) | 			delete(edit.properties, tag) | ||||||
| 			if oldText != "" { | 			if oldText != "" { | ||||||
| 				edit.textChanged("") | 				edit.textChanged("") | ||||||
|  | 				if edit.created { | ||||||
| 					edit.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, edit.htmlID(), "")) | 					edit.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, edit.htmlID(), "")) | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case EditViewPattern: | 	case EditViewPattern: | ||||||
|  | 		if exists { | ||||||
| 			oldText := GetEditViewPattern(edit, "") | 			oldText := GetEditViewPattern(edit, "") | ||||||
| 			delete(edit.properties, tag) | 			delete(edit.properties, tag) | ||||||
| 			if oldText != "" { | 			if oldText != "" { | ||||||
|  | 				if edit.created { | ||||||
| 					removeProperty(edit.htmlID(), Pattern, edit.session) | 					removeProperty(edit.htmlID(), Pattern, edit.session) | ||||||
| 				} | 				} | ||||||
|  | 				edit.propertyChangedEvent(tag) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case EditViewType: | 	case EditViewType: | ||||||
|  | 		if exists { | ||||||
| 			oldType := GetEditViewType(edit, "") | 			oldType := GetEditViewType(edit, "") | ||||||
| 			delete(edit.properties, tag) | 			delete(edit.properties, tag) | ||||||
| 			if oldType != 0 { | 			if oldType != 0 { | ||||||
|  | 				if edit.created { | ||||||
| 					updateInnerHTML(edit.parentHTMLID(), edit.session) | 					updateInnerHTML(edit.parentHTMLID(), edit.session) | ||||||
| 				} | 				} | ||||||
|  | 				edit.propertyChangedEvent(tag) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case Wrap: | 	case Wrap: | ||||||
|  | 		if exists { | ||||||
| 			oldWrap := IsEditViewWrap(edit, "") | 			oldWrap := IsEditViewWrap(edit, "") | ||||||
| 			delete(edit.properties, tag) | 			delete(edit.properties, tag) | ||||||
| 			if GetEditViewType(edit, "") == MultiLineText { | 			if GetEditViewType(edit, "") == MultiLineText { | ||||||
| 				if wrap := IsEditViewWrap(edit, ""); wrap != oldWrap { | 				if wrap := IsEditViewWrap(edit, ""); wrap != oldWrap { | ||||||
|  | 					if edit.created { | ||||||
| 						if wrap { | 						if wrap { | ||||||
| 							updateProperty(edit.htmlID(), "wrap", "soft", edit.session) | 							updateProperty(edit.htmlID(), "wrap", "soft", edit.session) | ||||||
| 						} else { | 						} else { | ||||||
| 							updateProperty(edit.htmlID(), "wrap", "off", edit.session) | 							updateProperty(edit.htmlID(), "wrap", "off", edit.session) | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
|  | 					edit.propertyChangedEvent(tag) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		edit.viewData.remove(tag) | 		edit.viewData.remove(tag) | ||||||
| 		} | 		return | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -161,6 +196,7 @@ func (edit *editViewData) set(tag string, value interface{}) bool { | ||||||
| 			edit.properties[Text] = text | 			edit.properties[Text] = text | ||||||
| 			if text = GetText(edit, ""); oldText != text { | 			if text = GetText(edit, ""); oldText != text { | ||||||
| 				edit.textChanged(text) | 				edit.textChanged(text) | ||||||
|  | 				if edit.created { | ||||||
| 					if GetEditViewType(edit, "") == MultiLineText { | 					if GetEditViewType(edit, "") == MultiLineText { | ||||||
| 						updateInnerHTML(edit.htmlID(), edit.Session()) | 						updateInnerHTML(edit.htmlID(), edit.Session()) | ||||||
| 					} else { | 					} else { | ||||||
|  | @ -171,6 +207,7 @@ func (edit *editViewData) set(tag string, value interface{}) bool { | ||||||
| 						edit.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, edit.htmlID(), text)) | 						edit.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, edit.htmlID(), text)) | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 		return false | 		return false | ||||||
|  | @ -180,12 +217,15 @@ func (edit *editViewData) set(tag string, value interface{}) bool { | ||||||
| 		if text, ok := value.(string); ok { | 		if text, ok := value.(string); ok { | ||||||
| 			edit.properties[Hint] = text | 			edit.properties[Hint] = text | ||||||
| 			if text = GetHint(edit, ""); oldText != text { | 			if text = GetHint(edit, ""); oldText != text { | ||||||
|  | 				if edit.created { | ||||||
| 					if text != "" { | 					if text != "" { | ||||||
| 						updateProperty(edit.htmlID(), "placeholder", text, edit.session) | 						updateProperty(edit.htmlID(), "placeholder", text, edit.session) | ||||||
| 					} else { | 					} else { | ||||||
| 						removeProperty(edit.htmlID(), "placeholder", edit.session) | 						removeProperty(edit.htmlID(), "placeholder", edit.session) | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | 				edit.propertyChangedEvent(tag) | ||||||
|  | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 		return false | 		return false | ||||||
|  | @ -194,30 +234,39 @@ func (edit *editViewData) set(tag string, value interface{}) bool { | ||||||
| 		oldMaxLength := GetMaxLength(edit, "") | 		oldMaxLength := GetMaxLength(edit, "") | ||||||
| 		if edit.setIntProperty(MaxLength, value) { | 		if edit.setIntProperty(MaxLength, value) { | ||||||
| 			if maxLength := GetMaxLength(edit, ""); maxLength != oldMaxLength { | 			if maxLength := GetMaxLength(edit, ""); maxLength != oldMaxLength { | ||||||
|  | 				if edit.created { | ||||||
| 					if maxLength > 0 { | 					if maxLength > 0 { | ||||||
| 						updateProperty(edit.htmlID(), "maxlength", strconv.Itoa(maxLength), edit.session) | 						updateProperty(edit.htmlID(), "maxlength", strconv.Itoa(maxLength), edit.session) | ||||||
| 					} else { | 					} else { | ||||||
| 						removeProperty(edit.htmlID(), "maxlength", edit.session) | 						removeProperty(edit.htmlID(), "maxlength", edit.session) | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | 				edit.propertyChangedEvent(tag) | ||||||
|  | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 		return false | 		return false | ||||||
| 
 | 
 | ||||||
| 	case ReadOnly: | 	case ReadOnly: | ||||||
| 		if edit.setBoolProperty(ReadOnly, value) { | 		if edit.setBoolProperty(ReadOnly, value) { | ||||||
|  | 			if edit.created { | ||||||
| 				if IsReadOnly(edit, "") { | 				if IsReadOnly(edit, "") { | ||||||
| 					updateProperty(edit.htmlID(), ReadOnly, "", edit.session) | 					updateProperty(edit.htmlID(), ReadOnly, "", edit.session) | ||||||
| 				} else { | 				} else { | ||||||
| 					removeProperty(edit.htmlID(), ReadOnly, edit.session) | 					removeProperty(edit.htmlID(), ReadOnly, edit.session) | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
|  | 			edit.propertyChangedEvent(tag) | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 		return false | 		return false | ||||||
| 
 | 
 | ||||||
| 	case Spellcheck: | 	case Spellcheck: | ||||||
| 		if edit.setBoolProperty(Spellcheck, value) { | 		if edit.setBoolProperty(Spellcheck, value) { | ||||||
|  | 			if edit.created { | ||||||
| 				updateBoolProperty(edit.htmlID(), Spellcheck, IsSpellcheck(edit, ""), edit.session) | 				updateBoolProperty(edit.htmlID(), Spellcheck, IsSpellcheck(edit, ""), edit.session) | ||||||
|  | 			} | ||||||
|  | 			edit.propertyChangedEvent(tag) | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 		return false | 		return false | ||||||
|  | @ -227,12 +276,15 @@ func (edit *editViewData) set(tag string, value interface{}) bool { | ||||||
| 		if text, ok := value.(string); ok { | 		if text, ok := value.(string); ok { | ||||||
| 			edit.properties[Pattern] = text | 			edit.properties[Pattern] = text | ||||||
| 			if text = GetEditViewPattern(edit, ""); oldText != text { | 			if text = GetEditViewPattern(edit, ""); oldText != text { | ||||||
|  | 				if edit.created { | ||||||
| 					if text != "" { | 					if text != "" { | ||||||
| 						updateProperty(edit.htmlID(), Pattern, text, edit.session) | 						updateProperty(edit.htmlID(), Pattern, text, edit.session) | ||||||
| 					} else { | 					} else { | ||||||
| 						removeProperty(edit.htmlID(), Pattern, edit.session) | 						removeProperty(edit.htmlID(), Pattern, edit.session) | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | 				edit.propertyChangedEvent(tag) | ||||||
|  | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 		return false | 		return false | ||||||
|  | @ -241,8 +293,11 @@ func (edit *editViewData) set(tag string, value interface{}) bool { | ||||||
| 		oldType := GetEditViewType(edit, "") | 		oldType := GetEditViewType(edit, "") | ||||||
| 		if edit.setEnumProperty(EditViewType, value, enumProperties[EditViewType].values) { | 		if edit.setEnumProperty(EditViewType, value, enumProperties[EditViewType].values) { | ||||||
| 			if GetEditViewType(edit, "") != oldType { | 			if GetEditViewType(edit, "") != oldType { | ||||||
|  | 				if edit.created { | ||||||
| 					updateInnerHTML(edit.parentHTMLID(), edit.session) | 					updateInnerHTML(edit.parentHTMLID(), edit.session) | ||||||
| 				} | 				} | ||||||
|  | 				edit.propertyChangedEvent(tag) | ||||||
|  | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 		return false | 		return false | ||||||
|  | @ -252,12 +307,15 @@ func (edit *editViewData) set(tag string, value interface{}) bool { | ||||||
| 		if edit.setBoolProperty(Wrap, value) { | 		if edit.setBoolProperty(Wrap, value) { | ||||||
| 			if GetEditViewType(edit, "") == MultiLineText { | 			if GetEditViewType(edit, "") == MultiLineText { | ||||||
| 				if wrap := IsEditViewWrap(edit, ""); wrap != oldWrap { | 				if wrap := IsEditViewWrap(edit, ""); wrap != oldWrap { | ||||||
|  | 					if edit.created { | ||||||
| 						if wrap { | 						if wrap { | ||||||
| 							updateProperty(edit.htmlID(), "wrap", "soft", edit.session) | 							updateProperty(edit.htmlID(), "wrap", "soft", edit.session) | ||||||
| 						} else { | 						} else { | ||||||
| 							updateProperty(edit.htmlID(), "wrap", "off", edit.session) | 							updateProperty(edit.htmlID(), "wrap", "off", edit.session) | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
|  | 					edit.propertyChangedEvent(tag) | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
|  | @ -268,6 +326,7 @@ func (edit *editViewData) set(tag string, value interface{}) bool { | ||||||
| 		if !ok { | 		if !ok { | ||||||
| 			notCompatibleType(tag, value) | 			notCompatibleType(tag, value) | ||||||
| 		} | 		} | ||||||
|  | 		edit.propertyChangedEvent(tag) | ||||||
| 		return ok | 		return ok | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -363,6 +422,7 @@ func (edit *editViewData) textChanged(newText string) { | ||||||
| 	for _, listener := range edit.textChangeListeners { | 	for _, listener := range edit.textChangeListeners { | ||||||
| 		listener(edit, newText) | 		listener(edit, newText) | ||||||
| 	} | 	} | ||||||
|  | 	edit.propertyChangedEvent(Text) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (edit *editViewData) htmlTag() string { | func (edit *editViewData) htmlTag() string { | ||||||
|  | @ -446,7 +506,7 @@ func (edit *editViewData) htmlProperties(self View, buffer *strings.Builder) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (edit *editViewData) htmlDisabledProperties(self View, buffer *strings.Builder) { | func (edit *editViewData) htmlDisabledProperties(self View, buffer *strings.Builder) { | ||||||
| 	if IsDisabled(self) { | 	if IsDisabled(self, "") { | ||||||
| 		buffer.WriteString(` disabled`) | 		buffer.WriteString(` disabled`) | ||||||
| 	} | 	} | ||||||
| 	edit.viewData.htmlDisabledProperties(self, buffer) | 	edit.viewData.htmlDisabledProperties(self, buffer) | ||||||
|  |  | ||||||
|  | @ -114,7 +114,17 @@ func (picker *filePickerData) Remove(tag string) { | ||||||
| func (picker *filePickerData) remove(tag string) { | func (picker *filePickerData) remove(tag string) { | ||||||
| 	switch tag { | 	switch tag { | ||||||
| 	case FileSelectedEvent: | 	case FileSelectedEvent: | ||||||
|  | 		if len(picker.fileSelectedListeners) > 0 { | ||||||
| 			picker.fileSelectedListeners = []func(FilePicker, []FileInfo){} | 			picker.fileSelectedListeners = []func(FilePicker, []FileInfo){} | ||||||
|  | 			picker.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 	case Accept: | ||||||
|  | 		delete(picker.properties, tag) | ||||||
|  | 		if picker.created { | ||||||
|  | 			removeProperty(picker.htmlID(), "accept", picker.Session()) | ||||||
|  | 		} | ||||||
|  | 		picker.propertyChangedEvent(tag) | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		picker.viewData.remove(tag) | 		picker.viewData.remove(tag) | ||||||
|  | @ -184,6 +194,7 @@ func (picker *filePickerData) set(tag string, value interface{}) bool { | ||||||
| 			} | 			} | ||||||
| 			picker.fileSelectedListeners = listeners | 			picker.fileSelectedListeners = listeners | ||||||
| 		} | 		} | ||||||
|  | 		picker.propertyChangedEvent(tag) | ||||||
| 		return true | 		return true | ||||||
| 
 | 
 | ||||||
| 	case Accept: | 	case Accept: | ||||||
|  | @ -218,6 +229,15 @@ func (picker *filePickerData) set(tag string, value interface{}) bool { | ||||||
| 			notCompatibleType(tag, value) | 			notCompatibleType(tag, value) | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		if picker.created { | ||||||
|  | 			if css := picker.acceptCSS(); css != "" { | ||||||
|  | 				updateProperty(picker.htmlID(), "accept", css, picker.Session()) | ||||||
|  | 			} else { | ||||||
|  | 				removeProperty(picker.htmlID(), "accept", picker.Session()) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		picker.propertyChangedEvent(tag) | ||||||
| 		return true | 		return true | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
|  | @ -271,7 +291,7 @@ func (picker *filePickerData) htmlProperties(self View, buffer *strings.Builder) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (picker *filePickerData) htmlDisabledProperties(self View, buffer *strings.Builder) { | func (picker *filePickerData) htmlDisabledProperties(self View, buffer *strings.Builder) { | ||||||
| 	if IsDisabled(self) { | 	if IsDisabled(self, "") { | ||||||
| 		buffer.WriteString(` disabled`) | 		buffer.WriteString(` disabled`) | ||||||
| 	} | 	} | ||||||
| 	picker.viewData.htmlDisabledProperties(self, buffer) | 	picker.viewData.htmlDisabledProperties(self, buffer) | ||||||
|  |  | ||||||
|  | @ -216,10 +216,12 @@ func (gridLayout *gridLayoutData) remove(tag string) { | ||||||
| 	if tag == Gap { | 	if tag == Gap { | ||||||
| 		gridLayout.remove(GridRowGap) | 		gridLayout.remove(GridRowGap) | ||||||
| 		gridLayout.remove(GridColumnGap) | 		gridLayout.remove(GridColumnGap) | ||||||
|  | 		gridLayout.propertyChangedEvent(Gap) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	gridLayout.viewsContainerData.remove(tag) | 	gridLayout.viewsContainerData.remove(tag) | ||||||
|  | 	if gridLayout.created { | ||||||
| 		switch tag { | 		switch tag { | ||||||
| 		case CellWidth: | 		case CellWidth: | ||||||
| 			updateCSSProperty(gridLayout.htmlID(), `grid-template-columns`, | 			updateCSSProperty(gridLayout.htmlID(), `grid-template-columns`, | ||||||
|  | @ -230,6 +232,7 @@ func (gridLayout *gridLayoutData) remove(tag string) { | ||||||
| 				gridLayout.gridCellSizesCSS(CellHeight, gridLayout.session), gridLayout.session) | 				gridLayout.gridCellSizesCSS(CellHeight, gridLayout.session), gridLayout.session) | ||||||
| 
 | 
 | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (gridLayout *gridLayoutData) Set(tag string, value interface{}) bool { | func (gridLayout *gridLayoutData) Set(tag string, value interface{}) bool { | ||||||
|  | @ -243,10 +246,15 @@ func (gridLayout *gridLayoutData) set(tag string, value interface{}) bool { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if tag == Gap { | 	if tag == Gap { | ||||||
| 		return gridLayout.set(GridRowGap, value) && gridLayout.set(GridColumnGap, value) | 		if gridLayout.set(GridRowGap, value) && gridLayout.set(GridColumnGap, value) { | ||||||
|  | 			gridLayout.propertyChangedEvent(Gap) | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 		return false | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if gridLayout.viewsContainerData.set(tag, value) { | 	if gridLayout.viewsContainerData.set(tag, value) { | ||||||
|  | 		if gridLayout.created { | ||||||
| 			switch tag { | 			switch tag { | ||||||
| 			case CellWidth: | 			case CellWidth: | ||||||
| 				updateCSSProperty(gridLayout.htmlID(), `grid-template-columns`, | 				updateCSSProperty(gridLayout.htmlID(), `grid-template-columns`, | ||||||
|  | @ -257,6 +265,7 @@ func (gridLayout *gridLayoutData) set(tag string, value interface{}) bool { | ||||||
| 					gridLayout.gridCellSizesCSS(CellHeight, gridLayout.session), gridLayout.session) | 					gridLayout.gridCellSizesCSS(CellHeight, gridLayout.session), gridLayout.session) | ||||||
| 
 | 
 | ||||||
| 			} | 			} | ||||||
|  | 		} | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								imageView.go
								
								
								
								
							
							
						
						
									
										14
									
								
								imageView.go
								
								
								
								
							|  | @ -67,7 +67,7 @@ func (imageView *imageViewData) normalizeTag(tag string) string { | ||||||
| 	case HorizontalAlign: | 	case HorizontalAlign: | ||||||
| 		tag = ImageHorizontalAlign | 		tag = ImageHorizontalAlign | ||||||
| 
 | 
 | ||||||
| 	case altProperty: | 	case altTag: | ||||||
| 		tag = AltText | 		tag = AltText | ||||||
| 	} | 	} | ||||||
| 	return tag | 	return tag | ||||||
|  | @ -79,6 +79,7 @@ func (imageView *imageViewData) Remove(tag string) { | ||||||
| 
 | 
 | ||||||
| func (imageView *imageViewData) remove(tag string) { | func (imageView *imageViewData) remove(tag string) { | ||||||
| 	imageView.viewData.remove(tag) | 	imageView.viewData.remove(tag) | ||||||
|  | 	if imageView.created { | ||||||
| 		switch tag { | 		switch tag { | ||||||
| 		case Source: | 		case Source: | ||||||
| 			updateProperty(imageView.htmlID(), "src", "", imageView.session) | 			updateProperty(imageView.htmlID(), "src", "", imageView.session) | ||||||
|  | @ -90,6 +91,7 @@ func (imageView *imageViewData) remove(tag string) { | ||||||
| 		case ImageVerticalAlign, ImageHorizontalAlign: | 		case ImageVerticalAlign, ImageHorizontalAlign: | ||||||
| 			updateCSSStyle(imageView.htmlID(), imageView.session) | 			updateCSSStyle(imageView.htmlID(), imageView.session) | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (imageView *imageViewData) Set(tag string, value interface{}) bool { | func (imageView *imageViewData) Set(tag string, value interface{}) bool { | ||||||
|  | @ -106,30 +108,38 @@ func (imageView *imageViewData) set(tag string, value interface{}) bool { | ||||||
| 	case Source: | 	case Source: | ||||||
| 		if text, ok := value.(string); ok { | 		if text, ok := value.(string); ok { | ||||||
| 			imageView.properties[Source] = text | 			imageView.properties[Source] = text | ||||||
|  | 			if imageView.created { | ||||||
| 				updateProperty(imageView.htmlID(), "src", text, imageView.session) | 				updateProperty(imageView.htmlID(), "src", text, imageView.session) | ||||||
| 				if srcset := imageView.srcSet(text); srcset != "" { | 				if srcset := imageView.srcSet(text); srcset != "" { | ||||||
| 					updateProperty(imageView.htmlID(), "srcset", srcset, imageView.session) | 					updateProperty(imageView.htmlID(), "srcset", srcset, imageView.session) | ||||||
| 				} else { | 				} else { | ||||||
| 					removeProperty(imageView.htmlID(), "srcset", imageView.session) | 					removeProperty(imageView.htmlID(), "srcset", imageView.session) | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
|  | 			imageView.propertyChangedEvent(Source) | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 		notCompatibleType(tag, value) | 		notCompatibleType(Source, value) | ||||||
| 
 | 
 | ||||||
| 	case AltText: | 	case AltText: | ||||||
| 		if text, ok := value.(string); ok { | 		if text, ok := value.(string); ok { | ||||||
| 			imageView.properties[AltText] = text | 			imageView.properties[AltText] = text | ||||||
|  | 			if imageView.created { | ||||||
| 				updateInnerHTML(imageView.htmlID(), imageView.session) | 				updateInnerHTML(imageView.htmlID(), imageView.session) | ||||||
|  | 			} | ||||||
|  | 			imageView.propertyChangedEvent(Source) | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 		notCompatibleType(tag, value) | 		notCompatibleType(tag, value) | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		if imageView.viewData.set(tag, value) { | 		if imageView.viewData.set(tag, value) { | ||||||
|  | 			if imageView.created { | ||||||
| 				switch tag { | 				switch tag { | ||||||
| 				case ImageVerticalAlign, ImageHorizontalAlign: | 				case ImageVerticalAlign, ImageHorizontalAlign: | ||||||
| 					updateCSSStyle(imageView.htmlID(), imageView.session) | 					updateCSSStyle(imageView.htmlID(), imageView.session) | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -77,7 +77,7 @@ func (adapter *viewListAdapter) ListItem(index int, session Session) View { | ||||||
| 
 | 
 | ||||||
| func (adapter *viewListAdapter) IsListItemEnabled(index int) bool { | func (adapter *viewListAdapter) IsListItemEnabled(index int) bool { | ||||||
| 	if index >= 0 && index < len(adapter.items) { | 	if index >= 0 && index < len(adapter.items) { | ||||||
| 		return !IsDisabled(adapter.items[index]) | 		return !IsDisabled(adapter.items[index], "") | ||||||
| 	} | 	} | ||||||
| 	return true | 	return true | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -55,10 +55,12 @@ func (listLayout *listLayoutData) Remove(tag string) { | ||||||
| 
 | 
 | ||||||
| func (listLayout *listLayoutData) remove(tag string) { | func (listLayout *listLayoutData) remove(tag string) { | ||||||
| 	listLayout.viewsContainerData.remove(tag) | 	listLayout.viewsContainerData.remove(tag) | ||||||
|  | 	if listLayout.created { | ||||||
| 		switch tag { | 		switch tag { | ||||||
| 		case Orientation, Wrap, HorizontalAlign, VerticalAlign: | 		case Orientation, Wrap, HorizontalAlign, VerticalAlign: | ||||||
| 			updateCSSStyle(listLayout.htmlID(), listLayout.session) | 			updateCSSStyle(listLayout.htmlID(), listLayout.session) | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (listLayout *listLayoutData) Set(tag string, value interface{}) bool { | func (listLayout *listLayoutData) Set(tag string, value interface{}) bool { | ||||||
|  | @ -72,10 +74,12 @@ func (listLayout *listLayoutData) set(tag string, value interface{}) bool { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if listLayout.viewsContainerData.set(tag, value) { | 	if listLayout.viewsContainerData.set(tag, value) { | ||||||
|  | 		if listLayout.created { | ||||||
| 			switch tag { | 			switch tag { | ||||||
| 			case Orientation, Wrap, HorizontalAlign, VerticalAlign: | 			case Orientation, Wrap, HorizontalAlign, VerticalAlign: | ||||||
| 				updateCSSStyle(listLayout.htmlID(), listLayout.session) | 				updateCSSStyle(listLayout.htmlID(), listLayout.session) | ||||||
| 			} | 			} | ||||||
|  | 		} | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
| 	return false | 	return false | ||||||
|  |  | ||||||
							
								
								
									
										88
									
								
								listView.go
								
								
								
								
							
							
						
						
									
										88
									
								
								listView.go
								
								
								
								
							|  | @ -114,46 +114,71 @@ func (listView *listViewData) Remove(tag string) { | ||||||
| func (listView *listViewData) remove(tag string) { | func (listView *listViewData) remove(tag string) { | ||||||
| 	switch tag { | 	switch tag { | ||||||
| 	case Checked: | 	case Checked: | ||||||
|  | 		if len(listView.checkedItem) > 0 { | ||||||
| 			listView.checkedItem = []int{} | 			listView.checkedItem = []int{} | ||||||
|  | 			if listView.created { | ||||||
| 				updateInnerHTML(listView.htmlID(), listView.session) | 				updateInnerHTML(listView.htmlID(), listView.session) | ||||||
|  | 			} | ||||||
|  | 			listView.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case Items: | 	case Items: | ||||||
|  | 		if listView.adapter != nil { | ||||||
| 			listView.adapter = nil | 			listView.adapter = nil | ||||||
|  | 			if listView.created { | ||||||
| 				updateInnerHTML(listView.htmlID(), listView.session) | 				updateInnerHTML(listView.htmlID(), listView.session) | ||||||
|  | 			} | ||||||
|  | 			listView.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case Orientation, Wrap: | 	case Orientation, Wrap: | ||||||
|  | 		if _, ok := listView.properties[tag]; ok { | ||||||
| 			delete(listView.properties, tag) | 			delete(listView.properties, tag) | ||||||
|  | 			if listView.created { | ||||||
| 				updateCSSStyle(listView.htmlID(), listView.session) | 				updateCSSStyle(listView.htmlID(), listView.session) | ||||||
|  | 			} | ||||||
|  | 			listView.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case Current: | 	case Current: | ||||||
| 		current := GetListViewCurrent(listView, "") | 		current := GetListViewCurrent(listView, "") | ||||||
| 		delete(listView.properties, tag) | 		delete(listView.properties, tag) | ||||||
|  | 		if listView.created { | ||||||
| 			updateInnerHTML(listView.htmlID(), listView.session) | 			updateInnerHTML(listView.htmlID(), listView.session) | ||||||
|  | 		} | ||||||
| 		if current != -1 { | 		if current != -1 { | ||||||
| 			for _, listener := range listView.selectedListeners { | 			for _, listener := range listView.selectedListeners { | ||||||
| 				listener(listView, -1) | 				listener(listView, -1) | ||||||
| 			} | 			} | ||||||
|  | 			listView.propertyChangedEvent(tag) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	case ItemWidth, ItemHeight, ItemHorizontalAlign, ItemVerticalAlign, ItemCheckbox, | 	case ItemWidth, ItemHeight, ItemHorizontalAlign, ItemVerticalAlign, ItemCheckbox, | ||||||
| 		CheckboxHorizontalAlign, CheckboxVerticalAlign, ListItemStyle, CurrentStyle, CurrentInactiveStyle: | 		CheckboxHorizontalAlign, CheckboxVerticalAlign, ListItemStyle, CurrentStyle, CurrentInactiveStyle: | ||||||
| 
 | 		if _, ok := listView.properties[tag]; ok { | ||||||
| 			delete(listView.properties, tag) | 			delete(listView.properties, tag) | ||||||
|  | 			if listView.created { | ||||||
| 				updateInnerHTML(listView.htmlID(), listView.session) | 				updateInnerHTML(listView.htmlID(), listView.session) | ||||||
|  | 			} | ||||||
|  | 			listView.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case ListItemClickedEvent: | 	case ListItemClickedEvent: | ||||||
| 		if len(listView.clickedListeners) > 0 { | 		if len(listView.clickedListeners) > 0 { | ||||||
| 			listView.clickedListeners = []func(ListView, int){} | 			listView.clickedListeners = []func(ListView, int){} | ||||||
|  | 			listView.propertyChangedEvent(tag) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	case ListItemSelectedEvent: | 	case ListItemSelectedEvent: | ||||||
| 		if len(listView.selectedListeners) > 0 { | 		if len(listView.selectedListeners) > 0 { | ||||||
| 			listView.selectedListeners = []func(ListView, int){} | 			listView.selectedListeners = []func(ListView, int){} | ||||||
|  | 			listView.propertyChangedEvent(tag) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	case ListItemCheckedEvent: | 	case ListItemCheckedEvent: | ||||||
| 		if len(listView.checkedListeners) > 0 { | 		if len(listView.checkedListeners) > 0 { | ||||||
| 			listView.checkedListeners = []func(ListView, []int){} | 			listView.checkedListeners = []func(ListView, []int){} | ||||||
|  | 			listView.propertyChangedEvent(tag) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
|  | @ -171,10 +196,7 @@ func (listView *listViewData) set(tag string, value interface{}) bool { | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	result := false |  | ||||||
| 
 |  | ||||||
| 	switch tag { | 	switch tag { | ||||||
| 
 |  | ||||||
| 	case ListItemClickedEvent: | 	case ListItemClickedEvent: | ||||||
| 		listeners := listView.valueToItemListeners(value) | 		listeners := listView.valueToItemListeners(value) | ||||||
| 		if listeners == nil { | 		if listeners == nil { | ||||||
|  | @ -182,6 +204,7 @@ func (listView *listViewData) set(tag string, value interface{}) bool { | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
| 		listView.clickedListeners = listeners | 		listView.clickedListeners = listeners | ||||||
|  | 		listView.propertyChangedEvent(tag) | ||||||
| 		return true | 		return true | ||||||
| 
 | 
 | ||||||
| 	case ListItemSelectedEvent: | 	case ListItemSelectedEvent: | ||||||
|  | @ -191,44 +214,56 @@ func (listView *listViewData) set(tag string, value interface{}) bool { | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
| 		listView.selectedListeners = listeners | 		listView.selectedListeners = listeners | ||||||
|  | 		listView.propertyChangedEvent(tag) | ||||||
| 		return true | 		return true | ||||||
| 
 | 
 | ||||||
| 	case ListItemCheckedEvent: | 	case ListItemCheckedEvent: | ||||||
| 		return listView.setItemCheckedEvent(value) | 		if !listView.setItemCheckedEvent(value) { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
|  | 		listView.propertyChangedEvent(tag) | ||||||
|  | 		return true | ||||||
| 
 | 
 | ||||||
| 	case Checked: | 	case Checked: | ||||||
| 		return listView.setChecked(value) | 		if !listView.setChecked(value) { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case Items: | 	case Items: | ||||||
| 		result = listView.setItems(value) | 		if !listView.setItems(value) { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case Current: | 	case Current: | ||||||
| 		oldCurrent := GetListViewCurrent(listView, "") | 		oldCurrent := GetListViewCurrent(listView, "") | ||||||
| 		if listView.setIntProperty(Current, value) { | 		if !listView.setIntProperty(Current, value) { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
| 		current := GetListViewCurrent(listView, "") | 		current := GetListViewCurrent(listView, "") | ||||||
| 			if oldCurrent != current { | 		if oldCurrent == current { | ||||||
| 				updateInnerHTML(listView.htmlID(), listView.session) |  | ||||||
| 				for _, listener := range listView.selectedListeners { |  | ||||||
| 					listener(listView, current) |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	case Orientation, Wrap, VerticalAlign, HorizontalAlign, Style, StyleDisabled: | 		for _, listener := range listView.selectedListeners { | ||||||
| 		result = listView.viewData.set(tag, value) | 			listener(listView, current) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case ItemWidth, ItemHeight: | 	case Orientation, Wrap, VerticalAlign, HorizontalAlign, Style, StyleDisabled, ItemWidth, ItemHeight: | ||||||
| 		result = listView.setSizeProperty(tag, value) | 		result := listView.viewData.set(tag, value) | ||||||
|  | 		if result && listView.created { | ||||||
|  | 			updateInnerHTML(listView.htmlID(), listView.session) | ||||||
|  | 		} | ||||||
|  | 		return result | ||||||
| 
 | 
 | ||||||
| 	case ItemHorizontalAlign, ItemVerticalAlign, ItemCheckbox, CheckboxHorizontalAlign, CheckboxVerticalAlign: | 	case ItemHorizontalAlign, ItemVerticalAlign, ItemCheckbox, CheckboxHorizontalAlign, CheckboxVerticalAlign: | ||||||
| 		result = listView.setEnumProperty(tag, value, enumProperties[tag].values) | 		if !listView.setEnumProperty(tag, value, enumProperties[tag].values) { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case ListItemStyle, CurrentStyle, CurrentInactiveStyle: | 	case ListItemStyle, CurrentStyle, CurrentInactiveStyle: | ||||||
| 		switch value := value.(type) { | 		switch value := value.(type) { | ||||||
| 		case string: | 		case string: | ||||||
| 			listView.properties[tag] = value | 			listView.properties[tag] = value | ||||||
| 			result = true |  | ||||||
| 
 | 
 | ||||||
| 		default: | 		default: | ||||||
| 			notCompatibleType(tag, value) | 			notCompatibleType(tag, value) | ||||||
|  | @ -239,11 +274,11 @@ func (listView *listViewData) set(tag string, value interface{}) bool { | ||||||
| 		return listView.viewData.set(tag, value) | 		return listView.viewData.set(tag, value) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if result { | 	if listView.created { | ||||||
| 		updateInnerHTML(listView.htmlID(), listView.session) | 		updateInnerHTML(listView.htmlID(), listView.session) | ||||||
| 	} | 	} | ||||||
| 
 | 	listView.propertyChangedEvent(tag) | ||||||
| 	return result | 	return true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (listView *listViewData) setItemCheckedEvent(value interface{}) bool { | func (listView *listViewData) setItemCheckedEvent(value interface{}) bool { | ||||||
|  | @ -1054,14 +1089,18 @@ func (listView *listViewData) handleCommand(self View, command string, data Data | ||||||
| 				for _, listener := range listView.selectedListeners { | 				for _, listener := range listView.selectedListeners { | ||||||
| 					listener(listView, number) | 					listener(listView, number) | ||||||
| 				} | 				} | ||||||
|  | 				listView.propertyChangedEvent(Current) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	case "itemUnselected": | 	case "itemUnselected": | ||||||
|  | 		if _, ok := listView.properties[Current]; ok { | ||||||
| 			delete(listView.properties, Current) | 			delete(listView.properties, Current) | ||||||
| 			for _, listener := range listView.selectedListeners { | 			for _, listener := range listView.selectedListeners { | ||||||
| 				listener(listView, -1) | 				listener(listView, -1) | ||||||
| 			} | 			} | ||||||
|  | 			listView.propertyChangedEvent(Current) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case "itemClick": | 	case "itemClick": | ||||||
| 		listView.onItemClick() | 		listView.onItemClick() | ||||||
|  | @ -1075,7 +1114,7 @@ func (listView *listViewData) handleCommand(self View, command string, data Data | ||||||
| 
 | 
 | ||||||
| func (listView *listViewData) onItemClick() { | func (listView *listViewData) onItemClick() { | ||||||
| 	current := GetListViewCurrent(listView, "") | 	current := GetListViewCurrent(listView, "") | ||||||
| 	if current >= 0 && !IsDisabled(listView) { | 	if current >= 0 && !IsDisabled(listView, "") { | ||||||
| 		checkbox := GetListViewCheckbox(listView, "") | 		checkbox := GetListViewCheckbox(listView, "") | ||||||
| 	m: | 	m: | ||||||
| 		switch checkbox { | 		switch checkbox { | ||||||
|  | @ -1115,6 +1154,7 @@ func (listView *listViewData) onItemClick() { | ||||||
| 			for _, listener := range listView.checkedListeners { | 			for _, listener := range listView.checkedListeners { | ||||||
| 				listener(listView, listView.checkedItem) | 				listener(listView, listView.checkedItem) | ||||||
| 			} | 			} | ||||||
|  | 			listView.propertyChangedEvent(Checked) | ||||||
| 		} | 		} | ||||||
| 		for _, listener := range listView.clickedListeners { | 		for _, listener := range listView.clickedListeners { | ||||||
| 			listener(listView, current) | 			listener(listView, current) | ||||||
|  |  | ||||||
|  | @ -173,20 +173,8 @@ func (player *mediaPlayerData) Remove(tag string) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (player *mediaPlayerData) remove(tag string) { | func (player *mediaPlayerData) remove(tag string) { | ||||||
| 	switch tag { |  | ||||||
| 
 |  | ||||||
| 	case Controls, Loop, Muted, Preload, AbortEvent, LoadStartEvent, PlayerErrorEvent, |  | ||||||
| 		CanPlayEvent, CanPlayThroughEvent, CompleteEvent, DurationChangedEvent, |  | ||||||
| 		EmptiedEvent, EndedEvent, LoadedDataEvent, LoadedMetadataEvent, PauseEvent, PlayEvent, |  | ||||||
| 		PlayingEvent, RateChangedEvent, SeekedEvent, SeekingEvent, StalledEvent, SuspendEvent, |  | ||||||
| 		ProgressEvent, TimeUpdateEvent, VolumeChangedEvent, WaitingEvent: |  | ||||||
| 
 |  | ||||||
| 	player.viewData.remove(tag) | 	player.viewData.remove(tag) | ||||||
| 	player.propertyChanged(tag) | 	player.propertyChanged(tag) | ||||||
| 
 |  | ||||||
| 	default: |  | ||||||
| 		player.viewData.remove(tag) |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (player *mediaPlayerData) Set(tag string, value interface{}) bool { | func (player *mediaPlayerData) Set(tag string, value interface{}) bool { | ||||||
|  | @ -216,6 +204,7 @@ func (player *mediaPlayerData) set(tag string, value interface{}) bool { | ||||||
| 				player.properties[tag] = listeners | 				player.properties[tag] = listeners | ||||||
| 			} | 			} | ||||||
| 			player.propertyChanged(tag) | 			player.propertyChanged(tag) | ||||||
|  | 			player.propertyChangedEvent(tag) | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 		notCompatibleType(tag, value) | 		notCompatibleType(tag, value) | ||||||
|  | @ -228,6 +217,7 @@ func (player *mediaPlayerData) set(tag string, value interface{}) bool { | ||||||
| 				player.properties[tag] = listeners | 				player.properties[tag] = listeners | ||||||
| 			} | 			} | ||||||
| 			player.propertyChanged(tag) | 			player.propertyChanged(tag) | ||||||
|  | 			player.propertyChangedEvent(tag) | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 		notCompatibleType(tag, value) | 		notCompatibleType(tag, value) | ||||||
|  | @ -240,6 +230,7 @@ func (player *mediaPlayerData) set(tag string, value interface{}) bool { | ||||||
| 				player.properties[tag] = listeners | 				player.properties[tag] = listeners | ||||||
| 			} | 			} | ||||||
| 			player.propertyChanged(tag) | 			player.propertyChanged(tag) | ||||||
|  | 			player.propertyChangedEvent(tag) | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 		notCompatibleType(tag, value) | 		notCompatibleType(tag, value) | ||||||
|  | @ -247,14 +238,14 @@ func (player *mediaPlayerData) set(tag string, value interface{}) bool { | ||||||
| 	case Source: | 	case Source: | ||||||
| 		if player.setSource(value) { | 		if player.setSource(value) { | ||||||
| 			player.propertyChanged(tag) | 			player.propertyChanged(tag) | ||||||
|  | 			player.propertyChangedEvent(tag) | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		if player.viewData.set(tag, value) { | 		return player.viewData.set(tag, value) | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	return false | 	return false | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -657,6 +648,7 @@ func playerEvents() []struct{ tag, cssTag string } { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (player *mediaPlayerData) propertyChanged(tag string) { | func (player *mediaPlayerData) propertyChanged(tag string) { | ||||||
|  | 	if player.created { | ||||||
| 		switch tag { | 		switch tag { | ||||||
| 		case Controls, Loop: | 		case Controls, Loop: | ||||||
| 			value, _ := boolProperty(player, tag, player.Session()) | 			value, _ := boolProperty(player, tag, player.Session()) | ||||||
|  | @ -737,9 +729,7 @@ func (player *mediaPlayerData) propertyChanged(tag string) { | ||||||
| 
 | 
 | ||||||
| 		case Source: | 		case Source: | ||||||
| 			updateInnerHTML(player.htmlID(), player.Session()) | 			updateInnerHTML(player.htmlID(), player.Session()) | ||||||
| 
 | 		} | ||||||
| 	default: |  | ||||||
| 		player.viewData.propertyChanged(tag) |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -69,6 +69,7 @@ func (picker *numberPickerData) remove(tag string) { | ||||||
| 	case NumberChangedEvent: | 	case NumberChangedEvent: | ||||||
| 		if len(picker.numberChangedListeners) > 0 { | 		if len(picker.numberChangedListeners) > 0 { | ||||||
| 			picker.numberChangedListeners = []func(NumberPicker, float64){} | 			picker.numberChangedListeners = []func(NumberPicker, float64){} | ||||||
|  | 			picker.propertyChangedEvent(tag) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
|  | @ -135,18 +136,21 @@ func (picker *numberPickerData) set(tag string, value interface{}) bool { | ||||||
| 			} | 			} | ||||||
| 			picker.numberChangedListeners = listeners | 			picker.numberChangedListeners = listeners | ||||||
| 		} | 		} | ||||||
|  | 		picker.propertyChangedEvent(tag) | ||||||
| 		return true | 		return true | ||||||
| 
 | 
 | ||||||
| 	case NumberPickerValue: | 	case NumberPickerValue: | ||||||
| 		oldValue := GetNumberPickerValue(picker, "") | 		oldValue := GetNumberPickerValue(picker, "") | ||||||
| 		min, max := GetNumberPickerMinMax(picker, "") | 		min, max := GetNumberPickerMinMax(picker, "") | ||||||
| 		if picker.setFloatProperty(NumberPickerValue, value, min, max) { | 		if picker.setFloatProperty(NumberPickerValue, value, min, max) { | ||||||
| 			newValue := GetNumberPickerValue(picker, "") | 			if newValue := GetNumberPickerValue(picker, ""); oldValue != newValue { | ||||||
| 			if oldValue != newValue { | 				if picker.created { | ||||||
| 					picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%f')`, picker.htmlID(), newValue)) | 					picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%f')`, picker.htmlID(), newValue)) | ||||||
|  | 				} | ||||||
| 				for _, listener := range picker.numberChangedListeners { | 				for _, listener := range picker.numberChangedListeners { | ||||||
| 					listener(picker, newValue) | 					listener(picker, newValue) | ||||||
| 				} | 				} | ||||||
|  | 				picker.propertyChangedEvent(tag) | ||||||
| 			} | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
|  | @ -161,6 +165,7 @@ func (picker *numberPickerData) set(tag string, value interface{}) bool { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (picker *numberPickerData) propertyChanged(tag string) { | func (picker *numberPickerData) propertyChanged(tag string) { | ||||||
|  | 	if picker.created { | ||||||
| 		switch tag { | 		switch tag { | ||||||
| 		case NumberPickerType: | 		case NumberPickerType: | ||||||
| 			if GetNumberPickerType(picker, "") == NumberSlider { | 			if GetNumberPickerType(picker, "") == NumberSlider { | ||||||
|  | @ -191,6 +196,7 @@ func (picker *numberPickerData) propertyChanged(tag string) { | ||||||
| 				listener(picker, value) | 				listener(picker, value) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (picker *numberPickerData) Get(tag string) interface{} { | func (picker *numberPickerData) Get(tag string) interface{} { | ||||||
|  | @ -246,7 +252,7 @@ func (picker *numberPickerData) htmlProperties(self View, buffer *strings.Builde | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (picker *numberPickerData) htmlDisabledProperties(self View, buffer *strings.Builder) { | func (picker *numberPickerData) htmlDisabledProperties(self View, buffer *strings.Builder) { | ||||||
| 	if IsDisabled(self) { | 	if IsDisabled(self, "") { | ||||||
| 		buffer.WriteString(` disabled`) | 		buffer.WriteString(` disabled`) | ||||||
| 	} | 	} | ||||||
| 	picker.viewData.htmlDisabledProperties(self, buffer) | 	picker.viewData.htmlDisabledProperties(self, buffer) | ||||||
|  |  | ||||||
|  | @ -58,6 +58,7 @@ func (progress *progressBarData) remove(tag string) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (progress *progressBarData) propertyChanged(tag string) { | func (progress *progressBarData) propertyChanged(tag string) { | ||||||
|  | 	if progress.created { | ||||||
| 		switch tag { | 		switch tag { | ||||||
| 		case ProgressBarMax: | 		case ProgressBarMax: | ||||||
| 			updateProperty(progress.htmlID(), Max, strconv.FormatFloat(GetProgressBarMax(progress, ""), 'f', -1, 32), progress.session) | 			updateProperty(progress.htmlID(), Max, strconv.FormatFloat(GetProgressBarMax(progress, ""), 'f', -1, 32), progress.session) | ||||||
|  | @ -65,6 +66,7 @@ func (progress *progressBarData) propertyChanged(tag string) { | ||||||
| 		case ProgressBarValue: | 		case ProgressBarValue: | ||||||
| 			updateProperty(progress.htmlID(), Value, strconv.FormatFloat(GetProgressBarValue(progress, ""), 'f', -1, 32), progress.session) | 			updateProperty(progress.htmlID(), Value, strconv.FormatFloat(GetProgressBarValue(progress, ""), 'f', -1, 32), progress.session) | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (progress *progressBarData) Set(tag string, value interface{}) bool { | func (progress *progressBarData) Set(tag string, value interface{}) bool { | ||||||
|  |  | ||||||
|  | @ -368,7 +368,7 @@ const ( | ||||||
| 	CenterY = "center-y" | 	CenterY = "center-y" | ||||||
| 	// AltText is the constant for the "alt-text" property tag.
 | 	// AltText is the constant for the "alt-text" property tag.
 | ||||||
| 	AltText = "alt-text" | 	AltText = "alt-text" | ||||||
| 	altProperty = "alt" | 	altTag  = "alt" | ||||||
| 	// AvoidBreak is the constant for the "avoid-break" property tag.
 | 	// AvoidBreak is the constant for the "avoid-break" property tag.
 | ||||||
| 	// The "avoid-break" bool property sets how region breaks should behave inside a generated box.
 | 	// The "avoid-break" bool property sets how region breaks should behave inside a generated box.
 | ||||||
| 	// If the property value is "true" then fvoids any break from being inserted within the principal box.
 | 	// If the property value is "true" then fvoids any break from being inserted within the principal box.
 | ||||||
|  |  | ||||||
|  | @ -65,6 +65,7 @@ var intProperties = []string{ | ||||||
| 	FootHeight, | 	FootHeight, | ||||||
| 	RowSpan, | 	RowSpan, | ||||||
| 	ColumnSpan, | 	ColumnSpan, | ||||||
|  | 	ColumnCount, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var floatProperties = map[string]struct{ min, max float64 }{ | var floatProperties = map[string]struct{ min, max float64 }{ | ||||||
|  |  | ||||||
							
								
								
									
										37
									
								
								resizable.go
								
								
								
								
							
							
						
						
									
										37
									
								
								resizable.go
								
								
								
								
							|  | @ -75,22 +75,29 @@ func (resizable *resizableData) remove(tag string) { | ||||||
| 		oldSide := resizable.getSide() | 		oldSide := resizable.getSide() | ||||||
| 		delete(resizable.properties, Side) | 		delete(resizable.properties, Side) | ||||||
| 		if oldSide != resizable.getSide() { | 		if oldSide != resizable.getSide() { | ||||||
|  | 			if resizable.created { | ||||||
| 				updateInnerHTML(resizable.htmlID(), resizable.Session()) | 				updateInnerHTML(resizable.htmlID(), resizable.Session()) | ||||||
| 				resizable.updateResizeBorderWidth() | 				resizable.updateResizeBorderWidth() | ||||||
| 			} | 			} | ||||||
|  | 			resizable.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case ResizeBorderWidth: | 	case ResizeBorderWidth: | ||||||
| 		w := resizable.resizeBorderWidth() | 		w := resizable.resizeBorderWidth() | ||||||
| 		delete(resizable.properties, ResizeBorderWidth) | 		delete(resizable.properties, ResizeBorderWidth) | ||||||
| 		if !w.Equal(resizable.resizeBorderWidth()) { | 		if !w.Equal(resizable.resizeBorderWidth()) { | ||||||
| 			resizable.updateResizeBorderWidth() | 			resizable.updateResizeBorderWidth() | ||||||
|  | 			resizable.propertyChangedEvent(tag) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	case Content: | 	case Content: | ||||||
| 		if len(resizable.content) > 0 { | 		if len(resizable.content) > 0 { | ||||||
| 			resizable.content = []View{} | 			resizable.content = []View{} | ||||||
|  | 			if resizable.created { | ||||||
| 				updateInnerHTML(resizable.htmlID(), resizable.Session()) | 				updateInnerHTML(resizable.htmlID(), resizable.Session()) | ||||||
| 			} | 			} | ||||||
|  | 			resizable.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		resizable.viewData.remove(tag) | 		resizable.viewData.remove(tag) | ||||||
|  | @ -110,20 +117,25 @@ func (resizable *resizableData) set(tag string, value interface{}) bool { | ||||||
| 	switch tag { | 	switch tag { | ||||||
| 	case Side: | 	case Side: | ||||||
| 		oldSide := resizable.getSide() | 		oldSide := resizable.getSide() | ||||||
| 		ok := resizable.setSide(value) | 		if !resizable.setSide(value) { | ||||||
| 		if ok && oldSide != resizable.getSide() { | 			notCompatibleType(tag, value) | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
|  | 		if oldSide != resizable.getSide() { | ||||||
|  | 			if resizable.created { | ||||||
| 				updateInnerHTML(resizable.htmlID(), resizable.Session()) | 				updateInnerHTML(resizable.htmlID(), resizable.Session()) | ||||||
| 				resizable.updateResizeBorderWidth() | 				resizable.updateResizeBorderWidth() | ||||||
| 		} else { |  | ||||||
| 			notCompatibleType(tag, value) |  | ||||||
| 			} | 			} | ||||||
| 		return ok | 			resizable.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
|  | 		return true | ||||||
| 
 | 
 | ||||||
| 	case ResizeBorderWidth: | 	case ResizeBorderWidth: | ||||||
| 		w := resizable.resizeBorderWidth() | 		w := resizable.resizeBorderWidth() | ||||||
| 		ok := resizable.setSizeProperty(tag, value) | 		ok := resizable.setSizeProperty(tag, value) | ||||||
| 		if ok && !w.Equal(resizable.resizeBorderWidth()) { | 		if ok && !w.Equal(resizable.resizeBorderWidth()) { | ||||||
| 			resizable.updateResizeBorderWidth() | 			resizable.updateResizeBorderWidth() | ||||||
|  | 			resizable.propertyChangedEvent(tag) | ||||||
| 		} | 		} | ||||||
| 		return ok | 		return ok | ||||||
| 
 | 
 | ||||||
|  | @ -139,18 +151,25 @@ func (resizable *resizableData) set(tag string, value interface{}) bool { | ||||||
| 		case DataObject: | 		case DataObject: | ||||||
| 			if view := CreateViewFromObject(resizable.Session(), value); view != nil { | 			if view := CreateViewFromObject(resizable.Session(), value); view != nil { | ||||||
| 				newContent = view | 				newContent = view | ||||||
| 			} | 			} else { | ||||||
|  | 				return false | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 		default: | ||||||
|  | 			notCompatibleType(tag, value) | ||||||
|  | 			return false | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if newContent != nil { |  | ||||||
| 		if len(resizable.content) == 0 { | 		if len(resizable.content) == 0 { | ||||||
| 			resizable.content = []View{newContent} | 			resizable.content = []View{newContent} | ||||||
| 		} else { | 		} else { | ||||||
| 			resizable.content[0] = newContent | 			resizable.content[0] = newContent | ||||||
| 		} | 		} | ||||||
|  | 		if resizable.created { | ||||||
| 			updateInnerHTML(resizable.htmlID(), resizable.Session()) | 			updateInnerHTML(resizable.htmlID(), resizable.Session()) | ||||||
| 			return true |  | ||||||
| 		} | 		} | ||||||
|  | 		resizable.propertyChangedEvent(tag) | ||||||
|  | 		return true | ||||||
| 
 | 
 | ||||||
| 	case CellWidth, CellHeight, GridRowGap, GridColumnGap, CellVerticalAlign, CellHorizontalAlign: | 	case CellWidth, CellHeight, GridRowGap, GridColumnGap, CellVerticalAlign, CellHorizontalAlign: | ||||||
| 		ErrorLogF(`Not supported "%s" property`, tag) | 		ErrorLogF(`Not supported "%s" property`, tag) | ||||||
|  | @ -306,12 +325,14 @@ func (resizable *resizableData) resizeBorderWidth() SizeUnit { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (resizable *resizableData) updateResizeBorderWidth() { | func (resizable *resizableData) updateResizeBorderWidth() { | ||||||
|  | 	if resizable.created { | ||||||
| 		htmlID := resizable.htmlID() | 		htmlID := resizable.htmlID() | ||||||
| 		session := resizable.Session() | 		session := resizable.Session() | ||||||
| 		column, row := resizable.cellSizeCSS() | 		column, row := resizable.cellSizeCSS() | ||||||
| 
 | 
 | ||||||
| 		updateCSSProperty(htmlID, "grid-template-columns", column, session) | 		updateCSSProperty(htmlID, "grid-template-columns", column, session) | ||||||
| 		updateCSSProperty(htmlID, "grid-template-rows", row, session) | 		updateCSSProperty(htmlID, "grid-template-rows", row, session) | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (resizable *resizableData) cellSizeCSS() (string, string) { | func (resizable *resizableData) cellSizeCSS() (string, string) { | ||||||
|  |  | ||||||
|  | @ -6,6 +6,8 @@ import ( | ||||||
| 	"strings" | 	"strings" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // TODO PeekChangedEvent
 | ||||||
|  | 
 | ||||||
| const ( | const ( | ||||||
| 	// DefaultAnimation - default animation of StackLayout push
 | 	// DefaultAnimation - default animation of StackLayout push
 | ||||||
| 	DefaultAnimation = 0 | 	DefaultAnimation = 0 | ||||||
|  | @ -93,23 +95,33 @@ func (layout *stackLayoutData) popFinished(view View, tag string) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (layout *stackLayoutData) Set(tag string, value interface{}) bool { | func (layout *stackLayoutData) Set(tag string, value interface{}) bool { | ||||||
| 	if strings.ToLower(tag) == TransitionEndEvent { | 	return layout.set(strings.ToLower(tag), value) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (layout *stackLayoutData) set(tag string, value interface{}) bool { | ||||||
|  | 	if tag == TransitionEndEvent { | ||||||
| 		listeners, ok := valueToAnimationListeners(value) | 		listeners, ok := valueToAnimationListeners(value) | ||||||
| 		if ok { | 		if ok { | ||||||
| 			listeners = append(listeners, layout.pushFinished) | 			listeners = append(listeners, layout.pushFinished) | ||||||
| 			listeners = append(listeners, layout.popFinished) | 			listeners = append(listeners, layout.popFinished) | ||||||
| 			layout.properties[TransitionEndEvent] = listeners | 			layout.properties[TransitionEndEvent] = listeners | ||||||
|  | 			layout.propertyChangedEvent(TransitionEndEvent) | ||||||
| 		} | 		} | ||||||
| 		return ok | 		return ok | ||||||
| 	} | 	} | ||||||
| 	return layout.viewsContainerData.Set(tag, value) | 	return layout.viewsContainerData.set(tag, value) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (layout *stackLayoutData) Remove(tag string) { | func (layout *stackLayoutData) Remove(tag string) { | ||||||
| 	if strings.ToLower(tag) == TransitionEndEvent { | 	layout.remove(strings.ToLower(tag)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (layout *stackLayoutData) remove(tag string) { | ||||||
|  | 	if tag == TransitionEndEvent { | ||||||
| 		layout.properties[TransitionEndEvent] = []func(View, string){layout.pushFinished, layout.popFinished} | 		layout.properties[TransitionEndEvent] = []func(View, string){layout.pushFinished, layout.popFinished} | ||||||
|  | 		layout.propertyChangedEvent(TransitionEndEvent) | ||||||
| 	} else { | 	} else { | ||||||
| 		layout.viewsContainerData.Remove(tag) | 		layout.viewsContainerData.remove(tag) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -238,6 +250,7 @@ func (layout *stackLayoutData) Push(view View, animation int, onPushFinished fun | ||||||
| 
 | 
 | ||||||
| 	layout.views = append(layout.views, view) | 	layout.views = append(layout.views, view) | ||||||
| 	view.setParentID(htmlID) | 	view.setParentID(htmlID) | ||||||
|  | 	layout.propertyChangedEvent(Content) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (layout *stackLayoutData) Pop(animation int, onPopFinished func(View)) bool { | func (layout *stackLayoutData) Pop(animation int, onPopFinished func(View)) bool { | ||||||
|  | @ -286,6 +299,7 @@ func (layout *stackLayoutData) Pop(animation int, onPopFinished func(View)) bool | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	updateCSSProperty(htmlID+"pop", "transform", value, layout.session) | 	updateCSSProperty(htmlID+"pop", "transform", value, layout.session) | ||||||
|  | 	layout.propertyChangedEvent(Content) | ||||||
| 	return true | 	return true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										44
									
								
								tableView.go
								
								
								
								
							
							
						
						
									
										44
									
								
								tableView.go
								
								
								
								
							|  | @ -168,35 +168,51 @@ func (table *tableViewData) Init(session Session) { | ||||||
| 	table.tag = "TableView" | 	table.tag = "TableView" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (table *tableViewData) normalizeTag(tag string) string { | ||||||
|  | 	switch tag = strings.ToLower(tag); tag { | ||||||
|  | 	case "top-cell-padding": | ||||||
|  | 		tag = CellPaddingTop | ||||||
|  | 
 | ||||||
|  | 	case "right-cell-padding": | ||||||
|  | 		tag = CellPaddingRight | ||||||
|  | 
 | ||||||
|  | 	case "bottom-cell-padding": | ||||||
|  | 		tag = CellPaddingBottom | ||||||
|  | 
 | ||||||
|  | 	case "left-cell-padding": | ||||||
|  | 		tag = CellPaddingLeft | ||||||
|  | 	} | ||||||
|  | 	return tag | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (table *tableViewData) Get(tag string) interface{} { | func (table *tableViewData) Get(tag string) interface{} { | ||||||
| 	return table.get(strings.ToLower(tag)) | 	return table.get(table.normalizeTag(tag)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (table *tableViewData) Remove(tag string) { | func (table *tableViewData) Remove(tag string) { | ||||||
| 	table.remove(strings.ToLower(tag)) | 	table.remove(table.normalizeTag(tag)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (table *tableViewData) remove(tag string) { | func (table *tableViewData) remove(tag string) { | ||||||
| 	switch tag { | 	switch tag { | ||||||
| 
 | 	case CellPaddingTop, CellPaddingRight, CellPaddingBottom, CellPaddingLeft: | ||||||
| 	case CellPaddingTop, CellPaddingRight, CellPaddingBottom, CellPaddingLeft, |  | ||||||
| 		"top-cell-padding", "right-cell-padding", "bottom-cell-padding", "left-cell-padding": |  | ||||||
| 		table.removeBoundsSide(CellPadding, tag) | 		table.removeBoundsSide(CellPadding, tag) | ||||||
|  | 		table.propertyChanged(tag) | ||||||
| 
 | 
 | ||||||
| 	case Gap, CellBorder, CellPadding, RowStyle, ColumnStyle, CellStyle, | 	case Gap, CellBorder, CellPadding, RowStyle, ColumnStyle, CellStyle, | ||||||
| 		HeadHeight, HeadStyle, FootHeight, FootStyle: | 		HeadHeight, HeadStyle, FootHeight, FootStyle: | ||||||
|  | 		if _, ok := table.properties[tag]; ok { | ||||||
| 			delete(table.properties, tag) | 			delete(table.properties, tag) | ||||||
|  | 			table.propertyChanged(tag) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		table.viewData.remove(tag) | 		table.viewData.remove(tag) | ||||||
| 		return |  | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	table.propertyChanged(tag) |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (table *tableViewData) Set(tag string, value interface{}) bool { | func (table *tableViewData) Set(tag string, value interface{}) bool { | ||||||
| 	return table.set(strings.ToLower(tag), value) | 	return table.set(table.normalizeTag(tag), value) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (table *tableViewData) set(tag string, value interface{}) bool { | func (table *tableViewData) set(tag string, value interface{}) bool { | ||||||
|  | @ -307,8 +323,7 @@ func (table *tableViewData) set(tag string, value interface{}) bool { | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	case CellPaddingTop, CellPaddingRight, CellPaddingBottom, CellPaddingLeft, | 	case CellPaddingTop, CellPaddingRight, CellPaddingBottom, CellPaddingLeft: | ||||||
| 		"top-cell-padding", "right-cell-padding", "bottom-cell-padding", "left-cell-padding": |  | ||||||
| 		if !table.setBoundsSide(CellPadding, tag, value) { | 		if !table.setBoundsSide(CellPadding, tag, value) { | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
|  | @ -336,11 +351,11 @@ func (table *tableViewData) set(tag string, value interface{}) bool { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (table *tableViewData) propertyChanged(tag string) { | func (table *tableViewData) propertyChanged(tag string) { | ||||||
|  | 	if table.created { | ||||||
| 		switch tag { | 		switch tag { | ||||||
| 		case Content, RowStyle, ColumnStyle, CellStyle, CellPadding, CellBorder, | 		case Content, RowStyle, ColumnStyle, CellStyle, CellPadding, CellBorder, | ||||||
| 			HeadHeight, HeadStyle, FootHeight, FootStyle, | 			HeadHeight, HeadStyle, FootHeight, FootStyle, | ||||||
| 		CellPaddingTop, CellPaddingRight, CellPaddingBottom, CellPaddingLeft, | 			CellPaddingTop, CellPaddingRight, CellPaddingBottom, CellPaddingLeft: | ||||||
| 		"top-cell-padding", "right-cell-padding", "bottom-cell-padding", "left-cell-padding": |  | ||||||
| 			table.ReloadTableData() | 			table.ReloadTableData() | ||||||
| 
 | 
 | ||||||
| 		case Gap: | 		case Gap: | ||||||
|  | @ -354,8 +369,9 @@ func (table *tableViewData) propertyChanged(tag string) { | ||||||
| 				updateCSSProperty(htmlID, "border-spacing", gap.cssString("0"), session) | 				updateCSSProperty(htmlID, "border-spacing", gap.cssString("0"), session) | ||||||
| 				updateCSSProperty(htmlID, "border-collapse", "separate", session) | 				updateCSSProperty(htmlID, "border-collapse", "separate", session) | ||||||
| 			} | 			} | ||||||
| 
 |  | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
|  | 	table.propertyChangedEvent(tag) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (table *tableViewData) htmlTag() string { | func (table *tableViewData) htmlTag() string { | ||||||
|  |  | ||||||
|  | @ -123,15 +123,26 @@ func (tabsLayout *tabsLayoutData) Remove(tag string) { | ||||||
| func (tabsLayout *tabsLayoutData) remove(tag string) { | func (tabsLayout *tabsLayoutData) remove(tag string) { | ||||||
| 	switch tag { | 	switch tag { | ||||||
| 	case CurrentTabChangedEvent: | 	case CurrentTabChangedEvent: | ||||||
|  | 		if len(tabsLayout.tabListener) > 0 { | ||||||
| 			tabsLayout.tabListener = []func(TabsLayout, int, int){} | 			tabsLayout.tabListener = []func(TabsLayout, int, int){} | ||||||
|  | 			tabsLayout.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
|  | 		return | ||||||
| 
 | 
 | ||||||
| 	case TabCloseEvent: | 	case TabCloseEvent: | ||||||
|  | 		if len(tabsLayout.tabCloseListener) > 0 { | ||||||
| 			tabsLayout.tabCloseListener = []func(TabsLayout, int){} | 			tabsLayout.tabCloseListener = []func(TabsLayout, int){} | ||||||
|  | 			tabsLayout.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
|  | 		return | ||||||
| 
 | 
 | ||||||
| 	case Current: | 	case Current: | ||||||
| 		oldCurrent := tabsLayout.currentItem() | 		oldCurrent := tabsLayout.currentItem() | ||||||
| 		delete(tabsLayout.properties, Current) | 		delete(tabsLayout.properties, Current) | ||||||
| 		if !tabsLayout.session.ignoreViewUpdates() && oldCurrent != 0 { | 		if oldCurrent == 0 { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		if tabsLayout.created { | ||||||
| 			tabsLayout.session.runScript(fmt.Sprintf("activateTab(%v, %d);", tabsLayout.htmlID(), 0)) | 			tabsLayout.session.runScript(fmt.Sprintf("activateTab(%v, %d);", tabsLayout.htmlID(), 0)) | ||||||
| 			for _, listener := range tabsLayout.tabListener { | 			for _, listener := range tabsLayout.tabListener { | ||||||
| 				listener(tabsLayout, 0, oldCurrent) | 				listener(tabsLayout, 0, oldCurrent) | ||||||
|  | @ -140,7 +151,7 @@ func (tabsLayout *tabsLayoutData) remove(tag string) { | ||||||
| 
 | 
 | ||||||
| 	case Tabs: | 	case Tabs: | ||||||
| 		delete(tabsLayout.properties, Tabs) | 		delete(tabsLayout.properties, Tabs) | ||||||
| 		if !tabsLayout.session.ignoreViewUpdates() { | 		if tabsLayout.created { | ||||||
| 			htmlID := tabsLayout.htmlID() | 			htmlID := tabsLayout.htmlID() | ||||||
| 			updateProperty(htmlID, inactiveTabStyle, tabsLayout.inactiveTabStyle(), tabsLayout.session) | 			updateProperty(htmlID, inactiveTabStyle, tabsLayout.inactiveTabStyle(), tabsLayout.session) | ||||||
| 			updateProperty(htmlID, activeTabStyle, tabsLayout.activeTabStyle(), tabsLayout.session) | 			updateProperty(htmlID, activeTabStyle, tabsLayout.activeTabStyle(), tabsLayout.session) | ||||||
|  | @ -150,7 +161,7 @@ func (tabsLayout *tabsLayoutData) remove(tag string) { | ||||||
| 
 | 
 | ||||||
| 	case TabStyle, CurrentTabStyle: | 	case TabStyle, CurrentTabStyle: | ||||||
| 		delete(tabsLayout.properties, tag) | 		delete(tabsLayout.properties, tag) | ||||||
| 		if !tabsLayout.session.ignoreViewUpdates() { | 		if tabsLayout.created { | ||||||
| 			htmlID := tabsLayout.htmlID() | 			htmlID := tabsLayout.htmlID() | ||||||
| 			updateProperty(htmlID, inactiveTabStyle, tabsLayout.inactiveTabStyle(), tabsLayout.session) | 			updateProperty(htmlID, inactiveTabStyle, tabsLayout.inactiveTabStyle(), tabsLayout.session) | ||||||
| 			updateProperty(htmlID, activeTabStyle, tabsLayout.activeTabStyle(), tabsLayout.session) | 			updateProperty(htmlID, activeTabStyle, tabsLayout.activeTabStyle(), tabsLayout.session) | ||||||
|  | @ -159,13 +170,16 @@ func (tabsLayout *tabsLayoutData) remove(tag string) { | ||||||
| 
 | 
 | ||||||
| 	case TabCloseButton: | 	case TabCloseButton: | ||||||
| 		delete(tabsLayout.properties, tag) | 		delete(tabsLayout.properties, tag) | ||||||
| 		if !tabsLayout.session.ignoreViewUpdates() { | 		if tabsLayout.created { | ||||||
| 			updateInnerHTML(tabsLayout.htmlID(), tabsLayout.session) | 			updateInnerHTML(tabsLayout.htmlID(), tabsLayout.session) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		tabsLayout.viewsContainerData.remove(tag) | 		tabsLayout.viewsContainerData.remove(tag) | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	tabsLayout.propertyChangedEvent(tag) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (tabsLayout *tabsLayoutData) Set(tag string, value interface{}) bool { | func (tabsLayout *tabsLayoutData) Set(tag string, value interface{}) bool { | ||||||
|  | @ -201,21 +215,22 @@ func (tabsLayout *tabsLayoutData) set(tag string, value interface{}) bool { | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if !tabsLayout.session.ignoreViewUpdates() { |  | ||||||
| 		current := tabsLayout.currentItem() | 		current := tabsLayout.currentItem() | ||||||
| 			if oldCurrent != current { | 		if oldCurrent == current { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 		if tabsLayout.created { | ||||||
| 			tabsLayout.session.runScript(fmt.Sprintf("activateTab(%v, %d);", tabsLayout.htmlID(), current)) | 			tabsLayout.session.runScript(fmt.Sprintf("activateTab(%v, %d);", tabsLayout.htmlID(), current)) | ||||||
| 			for _, listener := range tabsLayout.tabListener { | 			for _, listener := range tabsLayout.tabListener { | ||||||
| 				listener(tabsLayout, current, oldCurrent) | 				listener(tabsLayout, current, oldCurrent) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 	case Tabs: | 	case Tabs: | ||||||
| 		if !tabsLayout.setEnumProperty(Tabs, value, enumProperties[Tabs].values) { | 		if !tabsLayout.setEnumProperty(Tabs, value, enumProperties[Tabs].values) { | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
| 		if !tabsLayout.session.ignoreViewUpdates() { | 		if tabsLayout.created { | ||||||
| 			htmlID := tabsLayout.htmlID() | 			htmlID := tabsLayout.htmlID() | ||||||
| 			updateProperty(htmlID, inactiveTabStyle, tabsLayout.inactiveTabStyle(), tabsLayout.session) | 			updateProperty(htmlID, inactiveTabStyle, tabsLayout.inactiveTabStyle(), tabsLayout.session) | ||||||
| 			updateProperty(htmlID, activeTabStyle, tabsLayout.activeTabStyle(), tabsLayout.session) | 			updateProperty(htmlID, activeTabStyle, tabsLayout.activeTabStyle(), tabsLayout.session) | ||||||
|  | @ -235,7 +250,7 @@ func (tabsLayout *tabsLayoutData) set(tag string, value interface{}) bool { | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if !tabsLayout.session.ignoreViewUpdates() { | 		if tabsLayout.created { | ||||||
| 			htmlID := tabsLayout.htmlID() | 			htmlID := tabsLayout.htmlID() | ||||||
| 			updateProperty(htmlID, inactiveTabStyle, tabsLayout.inactiveTabStyle(), tabsLayout.session) | 			updateProperty(htmlID, inactiveTabStyle, tabsLayout.inactiveTabStyle(), tabsLayout.session) | ||||||
| 			updateProperty(htmlID, activeTabStyle, tabsLayout.activeTabStyle(), tabsLayout.session) | 			updateProperty(htmlID, activeTabStyle, tabsLayout.activeTabStyle(), tabsLayout.session) | ||||||
|  | @ -246,7 +261,7 @@ func (tabsLayout *tabsLayoutData) set(tag string, value interface{}) bool { | ||||||
| 		if !tabsLayout.setBoolProperty(tag, value) { | 		if !tabsLayout.setBoolProperty(tag, value) { | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
| 		if !tabsLayout.session.ignoreViewUpdates() { | 		if tabsLayout.created { | ||||||
| 			updateInnerHTML(tabsLayout.htmlID(), tabsLayout.session) | 			updateInnerHTML(tabsLayout.htmlID(), tabsLayout.session) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -254,6 +269,7 @@ func (tabsLayout *tabsLayoutData) set(tag string, value interface{}) bool { | ||||||
| 		return tabsLayout.viewsContainerData.set(tag, value) | 		return tabsLayout.viewsContainerData.set(tag, value) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	tabsLayout.propertyChangedEvent(tag) | ||||||
| 	return true | 	return true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -905,6 +921,7 @@ func (tabsLayout *tabsLayoutData) handleCommand(self View, command string, data | ||||||
| 					for _, listener := range tabsLayout.tabListener { | 					for _, listener := range tabsLayout.tabListener { | ||||||
| 						listener(tabsLayout, number, current) | 						listener(tabsLayout, number, current) | ||||||
| 					} | 					} | ||||||
|  | 					tabsLayout.propertyChangedEvent(Current) | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
							
								
								
									
										16
									
								
								textView.go
								
								
								
								
							
							
						
						
									
										16
									
								
								textView.go
								
								
								
								
							|  | @ -43,6 +43,7 @@ func (textView *textViewData) Remove(tag string) { | ||||||
| 
 | 
 | ||||||
| func (textView *textViewData) remove(tag string) { | func (textView *textViewData) remove(tag string) { | ||||||
| 	textView.viewData.remove(tag) | 	textView.viewData.remove(tag) | ||||||
|  | 	if textView.created { | ||||||
| 		switch tag { | 		switch tag { | ||||||
| 		case Text: | 		case Text: | ||||||
| 			updateInnerHTML(textView.htmlID(), textView.session) | 			updateInnerHTML(textView.htmlID(), textView.session) | ||||||
|  | @ -50,6 +51,7 @@ func (textView *textViewData) remove(tag string) { | ||||||
| 		case TextOverflow: | 		case TextOverflow: | ||||||
| 			textView.textOverflowUpdated() | 			textView.textOverflowUpdated() | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (textView *textViewData) Set(tag string, value interface{}) bool { | func (textView *textViewData) Set(tag string, value interface{}) bool { | ||||||
|  | @ -90,16 +92,24 @@ func (textView *textViewData) set(tag string, value interface{}) bool { | ||||||
| 				return false | 				return false | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		if textView.created { | ||||||
| 			updateInnerHTML(textView.htmlID(), textView.session) | 			updateInnerHTML(textView.htmlID(), textView.session) | ||||||
| 		return true | 		} | ||||||
| 
 | 
 | ||||||
| 	case TextOverflow: | 	case TextOverflow: | ||||||
| 		if textView.viewData.set(tag, value) { | 		if !textView.viewData.set(tag, value) { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
|  | 		if textView.created { | ||||||
| 			textView.textOverflowUpdated() | 			textView.textOverflowUpdated() | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 	default: | ||||||
|  | 		return textView.viewData.set(tag, value) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return textView.viewData.set(tag, value) | 	textView.propertyChangedEvent(tag) | ||||||
|  | 	return true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (textView *textViewData) textOverflowUpdated() { | func (textView *textViewData) textOverflowUpdated() { | ||||||
|  |  | ||||||
|  | @ -63,28 +63,47 @@ func (picker *timePickerData) remove(tag string) { | ||||||
| 	case TimeChangedEvent: | 	case TimeChangedEvent: | ||||||
| 		if len(picker.timeChangedListeners) > 0 { | 		if len(picker.timeChangedListeners) > 0 { | ||||||
| 			picker.timeChangedListeners = []func(TimePicker, time.Time){} | 			picker.timeChangedListeners = []func(TimePicker, time.Time){} | ||||||
|  | 			picker.propertyChangedEvent(tag) | ||||||
| 		} | 		} | ||||||
|  | 		return | ||||||
| 
 | 
 | ||||||
| 	case TimePickerMin: | 	case TimePickerMin: | ||||||
| 		delete(picker.properties, TimePickerMin) | 		delete(picker.properties, TimePickerMin) | ||||||
|  | 		if picker.created { | ||||||
| 			removeProperty(picker.htmlID(), Min, picker.session) | 			removeProperty(picker.htmlID(), Min, picker.session) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case TimePickerMax: | 	case TimePickerMax: | ||||||
| 		delete(picker.properties, TimePickerMax) | 		delete(picker.properties, TimePickerMax) | ||||||
|  | 		if picker.created { | ||||||
| 			removeProperty(picker.htmlID(), Max, picker.session) | 			removeProperty(picker.htmlID(), Max, picker.session) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case TimePickerStep: | 	case TimePickerStep: | ||||||
| 		delete(picker.properties, TimePickerMax) | 		delete(picker.properties, TimePickerMax) | ||||||
|  | 		if picker.created { | ||||||
| 			removeProperty(picker.htmlID(), Step, picker.session) | 			removeProperty(picker.htmlID(), Step, picker.session) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case TimePickerValue: | 	case TimePickerValue: | ||||||
|  | 		if _, ok := picker.properties[TimePickerValue]; ok { | ||||||
| 			delete(picker.properties, TimePickerValue) | 			delete(picker.properties, TimePickerValue) | ||||||
| 		updateProperty(picker.htmlID(), Value, time.Now().Format(timeFormat), picker.session) | 			time := GetTimePickerValue(picker, "") | ||||||
|  | 			if picker.created { | ||||||
|  | 				picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, picker.htmlID(), time.Format(timeFormat))) | ||||||
|  | 			} | ||||||
|  | 			for _, listener := range picker.timeChangedListeners { | ||||||
|  | 				listener(picker, time) | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		picker.viewData.remove(tag) | 		picker.viewData.remove(tag) | ||||||
| 		picker.propertyChanged(tag) | 		return | ||||||
| 	} | 	} | ||||||
|  | 	picker.propertyChangedEvent(tag) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (picker *timePickerData) Set(tag string, value interface{}) bool { | func (picker *timePickerData) Set(tag string, value interface{}) bool { | ||||||
|  | @ -121,8 +140,11 @@ func (picker *timePickerData) set(tag string, value interface{}) bool { | ||||||
| 		old, oldOK := getTimeProperty(picker, TimePickerMin, Min) | 		old, oldOK := getTimeProperty(picker, TimePickerMin, Min) | ||||||
| 		if time, ok := setTimeValue(TimePickerMin); ok { | 		if time, ok := setTimeValue(TimePickerMin); ok { | ||||||
| 			if !oldOK || time != old { | 			if !oldOK || time != old { | ||||||
|  | 				if picker.created { | ||||||
| 					updateProperty(picker.htmlID(), Min, time.Format(timeFormat), picker.session) | 					updateProperty(picker.htmlID(), Min, time.Format(timeFormat), picker.session) | ||||||
| 				} | 				} | ||||||
|  | 				picker.propertyChangedEvent(tag) | ||||||
|  | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -130,33 +152,41 @@ func (picker *timePickerData) set(tag string, value interface{}) bool { | ||||||
| 		old, oldOK := getTimeProperty(picker, TimePickerMax, Max) | 		old, oldOK := getTimeProperty(picker, TimePickerMax, Max) | ||||||
| 		if time, ok := setTimeValue(TimePickerMax); ok { | 		if time, ok := setTimeValue(TimePickerMax); ok { | ||||||
| 			if !oldOK || time != old { | 			if !oldOK || time != old { | ||||||
|  | 				if picker.created { | ||||||
| 					updateProperty(picker.htmlID(), Max, time.Format(timeFormat), picker.session) | 					updateProperty(picker.htmlID(), Max, time.Format(timeFormat), picker.session) | ||||||
| 				} | 				} | ||||||
|  | 				picker.propertyChangedEvent(tag) | ||||||
|  | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	case TimePickerStep: | 	case TimePickerStep: | ||||||
| 		oldStep := GetTimePickerStep(picker, "") | 		oldStep := GetTimePickerStep(picker, "") | ||||||
| 		if picker.setIntProperty(TimePickerStep, value) { | 		if picker.setIntProperty(TimePickerStep, value) { | ||||||
| 			step := GetTimePickerStep(picker, "") | 			if step := GetTimePickerStep(picker, ""); oldStep != step { | ||||||
| 			if oldStep != step { | 				if picker.created { | ||||||
| 					if step > 0 { | 					if step > 0 { | ||||||
| 						updateProperty(picker.htmlID(), Step, strconv.Itoa(step), picker.session) | 						updateProperty(picker.htmlID(), Step, strconv.Itoa(step), picker.session) | ||||||
| 					} else { | 					} else { | ||||||
| 						removeProperty(picker.htmlID(), Step, picker.session) | 						removeProperty(picker.htmlID(), Step, picker.session) | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | 				picker.propertyChangedEvent(tag) | ||||||
|  | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	case TimePickerValue: | 	case TimePickerValue: | ||||||
| 		oldTime := GetTimePickerValue(picker, "") | 		oldTime := GetTimePickerValue(picker, "") | ||||||
| 		if time, ok := setTimeValue(TimePickerMax); ok { | 		if time, ok := setTimeValue(TimePickerMax); ok { | ||||||
| 			picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, picker.htmlID(), time.Format(timeFormat))) |  | ||||||
| 			if time != oldTime { | 			if time != oldTime { | ||||||
|  | 				if picker.created { | ||||||
|  | 					picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, picker.htmlID(), time.Format(timeFormat))) | ||||||
|  | 				} | ||||||
| 				for _, listener := range picker.timeChangedListeners { | 				for _, listener := range picker.timeChangedListeners { | ||||||
| 					listener(picker, time) | 					listener(picker, time) | ||||||
| 				} | 				} | ||||||
|  | 				picker.propertyChangedEvent(tag) | ||||||
| 			} | 			} | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
|  | @ -167,8 +197,8 @@ func (picker *timePickerData) set(tag string, value interface{}) bool { | ||||||
| 			picker.timeChangedListeners = []func(TimePicker, time.Time){value} | 			picker.timeChangedListeners = []func(TimePicker, time.Time){value} | ||||||
| 
 | 
 | ||||||
| 		case func(time.Time): | 		case func(time.Time): | ||||||
| 			fn := func(view TimePicker, date time.Time) { | 			fn := func(view TimePicker, time time.Time) { | ||||||
| 				value(date) | 				value(time) | ||||||
| 			} | 			} | ||||||
| 			picker.timeChangedListeners = []func(TimePicker, time.Time){fn} | 			picker.timeChangedListeners = []func(TimePicker, time.Time){fn} | ||||||
| 
 | 
 | ||||||
|  | @ -183,8 +213,8 @@ func (picker *timePickerData) set(tag string, value interface{}) bool { | ||||||
| 					return false | 					return false | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				listeners[i] = func(view TimePicker, date time.Time) { | 				listeners[i] = func(view TimePicker, time time.Time) { | ||||||
| 					val(date) | 					val(time) | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			picker.timeChangedListeners = listeners | 			picker.timeChangedListeners = listeners | ||||||
|  | @ -202,8 +232,8 @@ func (picker *timePickerData) set(tag string, value interface{}) bool { | ||||||
| 					listeners[i] = val | 					listeners[i] = val | ||||||
| 
 | 
 | ||||||
| 				case func(time.Time): | 				case func(time.Time): | ||||||
| 					listeners[i] = func(view TimePicker, date time.Time) { | 					listeners[i] = func(view TimePicker, time time.Time) { | ||||||
| 						val(date) | 						val(time) | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 				default: | 				default: | ||||||
|  | @ -213,13 +243,11 @@ func (picker *timePickerData) set(tag string, value interface{}) bool { | ||||||
| 			} | 			} | ||||||
| 			picker.timeChangedListeners = listeners | 			picker.timeChangedListeners = listeners | ||||||
| 		} | 		} | ||||||
|  | 		picker.propertyChangedEvent(tag) | ||||||
| 		return true | 		return true | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		if picker.viewData.set(tag, value) { | 		return picker.viewData.set(tag, value) | ||||||
| 			picker.propertyChanged(tag) |  | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 	return false | 	return false | ||||||
| } | } | ||||||
|  | @ -273,7 +301,7 @@ func (picker *timePickerData) htmlProperties(self View, buffer *strings.Builder) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (picker *timePickerData) htmlDisabledProperties(self View, buffer *strings.Builder) { | func (picker *timePickerData) htmlDisabledProperties(self View, buffer *strings.Builder) { | ||||||
| 	if IsDisabled(self) { | 	if IsDisabled(self, "") { | ||||||
| 		buffer.WriteString(` disabled`) | 		buffer.WriteString(` disabled`) | ||||||
| 	} | 	} | ||||||
| 	picker.viewData.htmlDisabledProperties(self, buffer) | 	picker.viewData.htmlDisabledProperties(self, buffer) | ||||||
|  |  | ||||||
							
								
								
									
										150
									
								
								view.go
								
								
								
								
							
							
						
						
									
										150
									
								
								view.go
								
								
								
								
							|  | @ -57,6 +57,8 @@ type View interface { | ||||||
| 	// a description of the error is written to the log
 | 	// a description of the error is written to the log
 | ||||||
| 	SetAnimated(tag string, value interface{}, animation Animation) bool | 	SetAnimated(tag string, value interface{}, animation Animation) bool | ||||||
| 
 | 
 | ||||||
|  | 	SetChangeListener(tag string, listener func(View, string)) | ||||||
|  | 
 | ||||||
| 	handleCommand(self View, command string, data DataObject) bool | 	handleCommand(self View, command string, data DataObject) bool | ||||||
| 	//updateEventHandlers()
 | 	//updateEventHandlers()
 | ||||||
| 	htmlClass(disabled bool) string | 	htmlClass(disabled bool) string | ||||||
|  | @ -87,6 +89,7 @@ type viewData struct { | ||||||
| 	_htmlID          string | 	_htmlID          string | ||||||
| 	parentID         string | 	parentID         string | ||||||
| 	systemClass      string | 	systemClass      string | ||||||
|  | 	changeListener   map[string]func(View, string) | ||||||
| 	singleTransition map[string]Animation | 	singleTransition map[string]Animation | ||||||
| 	addCSS           map[string]string | 	addCSS           map[string]string | ||||||
| 	frame            Frame | 	frame            Frame | ||||||
|  | @ -129,6 +132,7 @@ func (view *viewData) Init(session Session) { | ||||||
| 	view.viewStyle.init() | 	view.viewStyle.init() | ||||||
| 	view.tag = "View" | 	view.tag = "View" | ||||||
| 	view.session = session | 	view.session = session | ||||||
|  | 	view.changeListener = map[string]func(View, string){} | ||||||
| 	view.addCSS = map[string]string{} | 	view.addCSS = map[string]string{} | ||||||
| 	//view.animation = map[string]AnimationEndListener{}
 | 	//view.animation = map[string]AnimationEndListener{}
 | ||||||
| 	view.singleTransition = map[string]Animation{} | 	view.singleTransition = map[string]Animation{} | ||||||
|  | @ -186,7 +190,7 @@ func (view *viewData) remove(tag string) { | ||||||
| 	case Style, StyleDisabled: | 	case Style, StyleDisabled: | ||||||
| 		if _, ok := view.properties[tag]; ok { | 		if _, ok := view.properties[tag]; ok { | ||||||
| 			delete(view.properties, tag) | 			delete(view.properties, tag) | ||||||
| 			updateProperty(view.htmlID(), "class", view.htmlClass(IsDisabled(view)), view.session) | 			updateProperty(view.htmlID(), "class", view.htmlClass(IsDisabled(view, "")), view.session) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	case FocusEvent, LostFocusEvent: | 	case FocusEvent, LostFocusEvent: | ||||||
|  | @ -221,8 +225,62 @@ func (view *viewData) remove(tag string) { | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		view.viewStyle.remove(tag) | 		view.viewStyle.remove(tag) | ||||||
| 		view.propertyChanged(tag) | 		viewPropertyChanged(view, tag) | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	view.propertyChangedEvent(tag) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (view *viewData) propertyChangedEvent(tag string) { | ||||||
|  | 	if listener, ok := view.changeListener[tag]; ok { | ||||||
|  | 		listener(view, tag) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	switch tag { | ||||||
|  | 	case BorderLeft, BorderRight, BorderTop, BorderBottom, | ||||||
|  | 		BorderStyle, BorderLeftStyle, BorderRightStyle, BorderTopStyle, BorderBottomStyle, | ||||||
|  | 		BorderColor, BorderLeftColor, BorderRightColor, BorderTopColor, BorderBottomColor, | ||||||
|  | 		BorderWidth, BorderLeftWidth, BorderRightWidth, BorderTopWidth, BorderBottomWidth: | ||||||
|  | 		tag = Border | ||||||
|  | 
 | ||||||
|  | 	case CellBorderStyle, CellBorderColor, CellBorderWidth, | ||||||
|  | 		CellBorderLeft, CellBorderLeftStyle, CellBorderLeftColor, CellBorderLeftWidth, | ||||||
|  | 		CellBorderRight, CellBorderRightStyle, CellBorderRightColor, CellBorderRightWidth, | ||||||
|  | 		CellBorderTop, CellBorderTopStyle, CellBorderTopColor, CellBorderTopWidth, | ||||||
|  | 		CellBorderBottom, CellBorderBottomStyle, CellBorderBottomColor, CellBorderBottomWidth: | ||||||
|  | 		tag = CellBorder | ||||||
|  | 
 | ||||||
|  | 	case OutlineColor, OutlineStyle, OutlineWidth: | ||||||
|  | 		tag = Outline | ||||||
|  | 
 | ||||||
|  | 	case RadiusX, RadiusY, RadiusTopLeft, RadiusTopLeftX, RadiusTopLeftY, | ||||||
|  | 		RadiusTopRight, RadiusTopRightX, RadiusTopRightY, | ||||||
|  | 		RadiusBottomLeft, RadiusBottomLeftX, RadiusBottomLeftY, | ||||||
|  | 		RadiusBottomRight, RadiusBottomRightX, RadiusBottomRightY: | ||||||
|  | 		tag = Radius | ||||||
|  | 
 | ||||||
|  | 	case MarginTop, MarginRight, MarginBottom, MarginLeft, | ||||||
|  | 		"top-margin", "right-margin", "bottom-margin", "left-margin": | ||||||
|  | 		tag = Margin | ||||||
|  | 
 | ||||||
|  | 	case PaddingTop, PaddingRight, PaddingBottom, PaddingLeft, | ||||||
|  | 		"top-padding", "right-padding", "bottom-padding", "left-padding": | ||||||
|  | 		tag = Padding | ||||||
|  | 
 | ||||||
|  | 	case CellPaddingTop, CellPaddingRight, CellPaddingBottom, CellPaddingLeft: | ||||||
|  | 		tag = CellPadding | ||||||
|  | 
 | ||||||
|  | 	case ColumnSeparatorStyle, ColumnSeparatorWidth, ColumnSeparatorColor: | ||||||
|  | 		tag = ColumnSeparator | ||||||
|  | 
 | ||||||
|  | 	default: | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if listener, ok := view.changeListener[tag]; ok { | ||||||
|  | 		listener(view, tag) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (view *viewData) Set(tag string, value interface{}) bool { | func (view *viewData) Set(tag string, value interface{}) bool { | ||||||
|  | @ -235,64 +293,71 @@ func (view *viewData) set(tag string, value interface{}) bool { | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	result := func(res bool) bool { | ||||||
|  | 		if res { | ||||||
|  | 			view.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
|  | 		return res | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	switch tag { | 	switch tag { | ||||||
| 	case ID: | 	case ID: | ||||||
| 		if text, ok := value.(string); ok { | 		text, ok := value.(string) | ||||||
| 			view.viewID = text | 		if !ok { | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 			notCompatibleType(ID, value) | 			notCompatibleType(ID, value) | ||||||
| 			return false | 			return false | ||||||
|  | 		} | ||||||
|  | 		view.viewID = text | ||||||
| 
 | 
 | ||||||
| 	case Style, StyleDisabled: | 	case Style, StyleDisabled: | ||||||
| 		if text, ok := value.(string); ok { | 		text, ok := value.(string) | ||||||
| 			view.properties[tag] = text | 		if !ok { | ||||||
| 			//updateInnerHTML(view.parentID, view.session)
 |  | ||||||
| 			if view.created { |  | ||||||
| 				updateProperty(view.htmlID(), "class", view.htmlClass(IsDisabled(view)), view.session) |  | ||||||
| 			} |  | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 			notCompatibleType(ID, value) | 			notCompatibleType(ID, value) | ||||||
| 			return false | 			return false | ||||||
|  | 		} | ||||||
|  | 		view.properties[tag] = text | ||||||
|  | 		if view.created { | ||||||
|  | 			updateProperty(view.htmlID(), "class", view.htmlClass(IsDisabled(view, "")), view.session) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	case FocusEvent, LostFocusEvent: | 	case FocusEvent, LostFocusEvent: | ||||||
| 		return view.setFocusListener(tag, value) | 		return result(view.setFocusListener(tag, value)) | ||||||
| 
 | 
 | ||||||
| 	case KeyDownEvent, KeyUpEvent: | 	case KeyDownEvent, KeyUpEvent: | ||||||
| 		return view.setKeyListener(tag, value) | 		return result(view.setKeyListener(tag, value)) | ||||||
| 
 | 
 | ||||||
| 	case ClickEvent, DoubleClickEvent, MouseDown, MouseUp, MouseMove, MouseOut, MouseOver, ContextMenuEvent: | 	case ClickEvent, DoubleClickEvent, MouseDown, MouseUp, MouseMove, MouseOut, MouseOver, ContextMenuEvent: | ||||||
| 		return view.setMouseListener(tag, value) | 		return result(view.setMouseListener(tag, value)) | ||||||
| 
 | 
 | ||||||
| 	case PointerDown, PointerUp, PointerMove, PointerOut, PointerOver, PointerCancel: | 	case PointerDown, PointerUp, PointerMove, PointerOut, PointerOver, PointerCancel: | ||||||
| 		return view.setPointerListener(tag, value) | 		return result(view.setPointerListener(tag, value)) | ||||||
| 
 | 
 | ||||||
| 	case TouchStart, TouchEnd, TouchMove, TouchCancel: | 	case TouchStart, TouchEnd, TouchMove, TouchCancel: | ||||||
| 		return view.setTouchListener(tag, value) | 		return result(view.setTouchListener(tag, value)) | ||||||
| 
 | 
 | ||||||
| 	case TransitionRunEvent, TransitionStartEvent, TransitionEndEvent, TransitionCancelEvent: | 	case TransitionRunEvent, TransitionStartEvent, TransitionEndEvent, TransitionCancelEvent: | ||||||
| 		return view.setTransitionListener(tag, value) | 		return result(view.setTransitionListener(tag, value)) | ||||||
| 
 | 
 | ||||||
| 	case AnimationStartEvent, AnimationEndEvent, AnimationIterationEvent, AnimationCancelEvent: | 	case AnimationStartEvent, AnimationEndEvent, AnimationIterationEvent, AnimationCancelEvent: | ||||||
| 		return view.setAnimationListener(tag, value) | 		return result(view.setAnimationListener(tag, value)) | ||||||
| 
 | 
 | ||||||
| 	case ResizeEvent, ScrollEvent: | 	case ResizeEvent, ScrollEvent: | ||||||
| 		return view.setFrameListener(tag, value) | 		return result(view.setFrameListener(tag, value)) | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if view.viewStyle.set(tag, value) { |  | ||||||
| 		if view.created { |  | ||||||
| 			view.propertyChanged(tag) |  | ||||||
| 		} |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
|  | 	default: | ||||||
|  | 		if !view.viewStyle.set(tag, value) { | ||||||
| 			return false | 			return false | ||||||
|  | 		} | ||||||
|  | 		if view.created { | ||||||
|  | 			viewPropertyChanged(view, tag) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	view.propertyChangedEvent(tag) | ||||||
|  | 	return true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (view *viewData) propertyChanged(tag string) { | func viewPropertyChanged(view *viewData, tag string) { | ||||||
| 
 |  | ||||||
| 	if view.updateTransformProperty(tag) { | 	if view.updateTransformProperty(tag) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  | @ -446,7 +511,7 @@ func (view *viewData) propertyChanged(tag string) { | ||||||
| 	case Strikethrough, Overline, Underline: | 	case Strikethrough, Overline, Underline: | ||||||
| 		updateCSSProperty(htmlID, "text-decoration", view.cssTextDecoration(session), session) | 		updateCSSProperty(htmlID, "text-decoration", view.cssTextDecoration(session), session) | ||||||
| 		for _, tag2 := range []string{TextLineColor, TextLineStyle, TextLineThickness} { | 		for _, tag2 := range []string{TextLineColor, TextLineStyle, TextLineThickness} { | ||||||
| 			view.propertyChanged(tag2) | 			viewPropertyChanged(view, tag2) | ||||||
| 		} | 		} | ||||||
| 		return | 		return | ||||||
| 
 | 
 | ||||||
|  | @ -568,7 +633,7 @@ func (view *viewData) htmlProperties(self View, buffer *strings.Builder) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (view *viewData) htmlDisabledProperties(self View, buffer *strings.Builder) { | func (view *viewData) htmlDisabledProperties(self View, buffer *strings.Builder) { | ||||||
| 	if IsDisabled(self) { | 	if IsDisabled(self, "") { | ||||||
| 		buffer.WriteString(` data-disabled="1"`) | 		buffer.WriteString(` data-disabled="1"`) | ||||||
| 	} else { | 	} else { | ||||||
| 		buffer.WriteString(` data-disabled="0"`) | 		buffer.WriteString(` data-disabled="0"`) | ||||||
|  | @ -583,7 +648,7 @@ func viewHTML(view View, buffer *strings.Builder) { | ||||||
| 	buffer.WriteString(view.htmlID()) | 	buffer.WriteString(view.htmlID()) | ||||||
| 	buffer.WriteRune('"') | 	buffer.WriteRune('"') | ||||||
| 
 | 
 | ||||||
| 	disabled := IsDisabled(view) | 	disabled := IsDisabled(view, "") | ||||||
| 
 | 
 | ||||||
| 	if cls := view.htmlClass(disabled); cls != "" { | 	if cls := view.htmlClass(disabled); cls != "" { | ||||||
| 		buffer.WriteString(` class="`) | 		buffer.WriteString(` class="`) | ||||||
|  | @ -660,7 +725,7 @@ func (view *viewData) handleCommand(self View, command string, data DataObject) | ||||||
| 	switch command { | 	switch command { | ||||||
| 
 | 
 | ||||||
| 	case KeyDownEvent, KeyUpEvent: | 	case KeyDownEvent, KeyUpEvent: | ||||||
| 		if !IsDisabled(self) { | 		if !IsDisabled(self, "") { | ||||||
| 			handleKeyEvents(self, command, data) | 			handleKeyEvents(self, command, data) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -767,13 +832,10 @@ func (view *viewData) String() string { | ||||||
| 	return writer.finish() | 	return writer.finish() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // IsDisabled returns "true" if the view is disabled
 | func (view *viewData) SetChangeListener(tag string, listener func(View, string)) { | ||||||
| func IsDisabled(view View) bool { | 	if listener == nil { | ||||||
| 	if disabled, _ := boolProperty(view, Disabled, view.Session()); disabled { | 		delete(view.changeListener, tag) | ||||||
| 		return true | 	} else { | ||||||
|  | 		view.changeListener[tag] = listener | ||||||
| 	} | 	} | ||||||
| 	if parent := view.Parent(); parent != nil { |  | ||||||
| 		return IsDisabled(parent) |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										45
									
								
								viewUtils.go
								
								
								
								
							
							
						
						
									
										45
									
								
								viewUtils.go
								
								
								
								
							|  | @ -4,7 +4,13 @@ package rui | ||||||
| // The type of return value depends on the property.
 | // The type of return value depends on the property.
 | ||||||
| // If the subview don't exists or the property is not set then nil is returned.
 | // If the subview don't exists or the property is not set then nil is returned.
 | ||||||
| func Get(rootView View, viewID, tag string) interface{} { | func Get(rootView View, viewID, tag string) interface{} { | ||||||
| 	if view := ViewByID(rootView, viewID); view != nil { | 	var view View | ||||||
|  | 	if viewID != "" { | ||||||
|  | 		view = ViewByID(rootView, viewID) | ||||||
|  | 	} else { | ||||||
|  | 		view = rootView | ||||||
|  | 	} | ||||||
|  | 	if view != nil { | ||||||
| 		return view.Get(tag) | 		return view.Get(tag) | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
|  | @ -14,12 +20,29 @@ func Get(rootView View, viewID, tag string) interface{} { | ||||||
| // true - success,
 | // true - success,
 | ||||||
| // false - error (incompatible type or invalid format of a string value, see AppLog).
 | // false - error (incompatible type or invalid format of a string value, see AppLog).
 | ||||||
| func Set(rootView View, viewID, tag string, value interface{}) bool { | func Set(rootView View, viewID, tag string, value interface{}) bool { | ||||||
| 	if view := ViewByID(rootView, viewID); view != nil { | 	var view View | ||||||
|  | 	if viewID != "" { | ||||||
|  | 		view = ViewByID(rootView, viewID) | ||||||
|  | 	} else { | ||||||
|  | 		view = rootView | ||||||
|  | 	} | ||||||
|  | 	if view != nil { | ||||||
| 		return view.Set(tag, value) | 		return view.Set(tag, value) | ||||||
| 	} | 	} | ||||||
| 	return false | 	return false | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // SetChangeListener sets a listener for changing a subview property value.
 | ||||||
|  | // If the second argument (subviewID) is "" then a listener for the first argument (view) is set
 | ||||||
|  | func SetChangeListener(view View, viewID, tag string, listener func(View, string)) { | ||||||
|  | 	if viewID != "" { | ||||||
|  | 		view = ViewByID(view, viewID) | ||||||
|  | 	} | ||||||
|  | 	if view != nil { | ||||||
|  | 		view.SetChangeListener(tag, listener) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // SetParams sets properties with name "tag" of the "rootView" subview. Result:
 | // SetParams sets properties with name "tag" of the "rootView" subview. Result:
 | ||||||
| // true - all properties were set successful,
 | // true - all properties were set successful,
 | ||||||
| // false - error (incompatible type or invalid format of a string value, see AppLog).
 | // false - error (incompatible type or invalid format of a string value, see AppLog).
 | ||||||
|  | @ -36,6 +59,22 @@ func SetParams(rootView View, viewID string, params Params) bool { | ||||||
| 	return result | 	return result | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // IsDisabled returns "true" if the subview is disabled
 | ||||||
|  | // If the second argument (subviewID) is "" then a state of the first argument (view) is returned
 | ||||||
|  | func IsDisabled(view View, subviewID string) bool { | ||||||
|  | 	if subviewID != "" { | ||||||
|  | 		view = ViewByID(view, subviewID) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if disabled, _ := boolProperty(view, Disabled, view.Session()); disabled { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 	if parent := view.Parent(); parent != nil { | ||||||
|  | 		return IsDisabled(parent, "") | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // GetSemantics returns the subview semantics.  Valid semantics values are
 | // GetSemantics returns the subview semantics.  Valid semantics values are
 | ||||||
| // DefaultSemantics (0), ArticleSemantics (1), SectionSemantics (2), AsideSemantics (3),
 | // DefaultSemantics (0), ArticleSemantics (1), SectionSemantics (2), AsideSemantics (3),
 | ||||||
| // HeaderSemantics (4), MainSemantics (5), FooterSemantics (6), NavigationSemantics (7),
 | // HeaderSemantics (4), MainSemantics (5), FooterSemantics (6), NavigationSemantics (7),
 | ||||||
|  | @ -926,7 +965,7 @@ func valueFromStyle(view View, tag string) (string, bool) { | ||||||
| 		return "", false | 		return "", false | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if IsDisabled(view) { | 	if IsDisabled(view, "") { | ||||||
| 		if value, ok := getValue(StyleDisabled); ok { | 		if value, ok := getValue(StyleDisabled); ok { | ||||||
| 			return value, true | 			return value, true | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -39,16 +39,6 @@ func (container *viewsContainerData) setParentID(parentID string) { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SetDisabled set the View disabled state
 |  | ||||||
| func (container *viewsContainerData) SetDisabled(disabled bool) { |  | ||||||
| 	container.viewData.Set(Disabled, disabled) |  | ||||||
| 	if container.views != nil { |  | ||||||
| 		for _, view := range container.views { |  | ||||||
| 			view.Set(Disabled, disabled) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Views return a list of child views
 | // Views return a list of child views
 | ||||||
| func (container *viewsContainerData) Views() []View { | func (container *viewsContainerData) Views() []View { | ||||||
| 	if container.views == nil { | 	if container.views == nil { | ||||||
|  | @ -68,6 +58,7 @@ func (container *viewsContainerData) Append(view View) { | ||||||
| 			container.views = append(container.views, view) | 			container.views = append(container.views, view) | ||||||
| 		} | 		} | ||||||
| 		updateInnerHTML(container.htmlID(), container.session) | 		updateInnerHTML(container.htmlID(), container.session) | ||||||
|  | 		container.propertyChangedEvent(Content) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -81,10 +72,12 @@ func (container *viewsContainerData) Insert(view View, index uint) { | ||||||
| 			view.setParentID(htmlID) | 			view.setParentID(htmlID) | ||||||
| 			container.views = append(container.views[:index], append([]View{view}, container.views[index:]...)...) | 			container.views = append(container.views[:index], append([]View{view}, container.views[index:]...)...) | ||||||
| 			updateInnerHTML(container.htmlID(), container.session) | 			updateInnerHTML(container.htmlID(), container.session) | ||||||
|  | 			container.propertyChangedEvent(Content) | ||||||
| 		} else { | 		} else { | ||||||
| 			view.setParentID(htmlID) | 			view.setParentID(htmlID) | ||||||
| 			container.views = append([]View{view}, container.views...) | 			container.views = append([]View{view}, container.views...) | ||||||
| 			updateInnerHTML(container.htmlID(), container.session) | 			updateInnerHTML(container.htmlID(), container.session) | ||||||
|  | 			container.propertyChangedEvent(Content) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | @ -112,6 +105,7 @@ func (container *viewsContainerData) RemoveView(index uint) View { | ||||||
| 
 | 
 | ||||||
| 	view.setParentID("") | 	view.setParentID("") | ||||||
| 	updateInnerHTML(container.htmlID(), container.session) | 	updateInnerHTML(container.htmlID(), container.session) | ||||||
|  | 	container.propertyChangedEvent(Content) | ||||||
| 	return view | 	return view | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -151,6 +145,18 @@ func (container *viewsContainerData) remove(tag string) { | ||||||
| 			container.views = []View{} | 			container.views = []View{} | ||||||
| 			updateInnerHTML(container.htmlID(), container.Session()) | 			updateInnerHTML(container.htmlID(), container.Session()) | ||||||
| 		} | 		} | ||||||
|  | 		container.propertyChangedEvent(Content) | ||||||
|  | 
 | ||||||
|  | 	case Disabled: | ||||||
|  | 		if _, ok := container.properties[Disabled]; ok { | ||||||
|  | 			delete(container.properties, Disabled) | ||||||
|  | 			if container.views != nil { | ||||||
|  | 				for _, view := range container.views { | ||||||
|  | 					view.Remove(Disabled) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			container.propertyChangedEvent(tag) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		container.viewData.remove(tag) | 		container.viewData.remove(tag) | ||||||
|  | @ -167,7 +173,27 @@ func (container *viewsContainerData) set(tag string, value interface{}) bool { | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if tag != Content { | 	switch tag { | ||||||
|  | 	case Content: | ||||||
|  | 		// do nothing
 | ||||||
|  | 
 | ||||||
|  | 	case Disabled: | ||||||
|  | 		oldDisabled := IsDisabled(container, "") | ||||||
|  | 		if container.viewData.Set(Disabled, value) { | ||||||
|  | 			disabled := IsDisabled(container, "") | ||||||
|  | 			if oldDisabled != disabled { | ||||||
|  | 				if container.views != nil { | ||||||
|  | 					for _, view := range container.views { | ||||||
|  | 						view.Set(Disabled, disabled) | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			container.propertyChangedEvent(tag) | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 		return false | ||||||
|  | 
 | ||||||
|  | 	default: | ||||||
| 		return container.viewData.set(tag, value) | 		return container.viewData.set(tag, value) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -239,6 +265,8 @@ func (container *viewsContainerData) set(tag string, value interface{}) bool { | ||||||
| 	if container.created { | 	if container.created { | ||||||
| 		updateInnerHTML(htmlID, container.session) | 		updateInnerHTML(htmlID, container.session) | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	container.propertyChangedEvent(Content) | ||||||
| 	return true | 	return true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue