mirror of https://github.com/anoshenko/rui.git
Added: "focusable" and "user-data" properties, ConstantTags and ColorTags function to Session, ReloadTableViewData function. Bug fixing
This commit is contained in:
parent
1e3c820c61
commit
8a625dcc78
|
@ -9,8 +9,8 @@
|
|||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${workspaceRoot}/demo",
|
||||
//"program": "${workspaceRoot}/editor",
|
||||
//"program": "${workspaceRoot}/demo",
|
||||
"program": "${workspaceRoot}/ruiEditor",
|
||||
"env": {},
|
||||
"args": []
|
||||
}
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
# v0.6.0
|
||||
|
||||
* Added "user-data" property
|
||||
* Added "focusable" property
|
||||
* Added ReloadTableViewData function
|
||||
|
||||
# v0.5.0
|
||||
|
||||
* NewApplication function and Start function of the Application interface were replaced by StartApp function
|
||||
|
|
28
README-ru.md
28
README-ru.md
|
@ -1679,6 +1679,10 @@ radius необходимо передать nil
|
|||
|
||||
func GetSkew(view View, subviewID string) (AngleUnit, AngleUnit)
|
||||
|
||||
### Пользовательские данные
|
||||
|
||||
Вы можете сохранить любые ваши данные в виде свойства "user-data" (константа UserData)
|
||||
|
||||
### События клавиатуры
|
||||
|
||||
Для View получившего фокус ввода могут генерироваться два вида событий клавиатуры
|
||||
|
@ -2682,16 +2686,16 @@ EditTextChangedEvent). Основной слушатель события име
|
|||
func NewNumberPicker(session Session, params Params) NumberPicker
|
||||
|
||||
NumberPicker может работать в двух режимах: редактор текста и слайдер.
|
||||
Режим устанавливает int свойство "date-picker-type" (константа NumberPickerType).
|
||||
Свойство "date-picker-type" может принимать следующие значения:
|
||||
Режим устанавливает int свойство "number-picker-type" (константа NumberPickerType).
|
||||
Свойство "number-picker-type" может принимать следующие значения:
|
||||
|
||||
| Значение | Константа | Имя | Тип редактора |
|
||||
|:--------:|--------------|----------|----------------------------------------|
|
||||
| 0 | NumberEditor | "editor" | Редактор текста. Значение по умолчанию |
|
||||
| 1 | NumberSlider | "slider" | Слайдер |
|
||||
|
||||
Установить/прочитать текущее значение можно с помощью свойства "date-picker-value"
|
||||
(константа NumberPickerValue). В качестве значения свойству "date-picker-value" могут быть переданы:
|
||||
Установить/прочитать текущее значение можно с помощью свойства "number-picker-value"
|
||||
(константа NumberPickerValue). В качестве значения свойству "number-picker-value" могут быть переданы:
|
||||
|
||||
* float64
|
||||
* float32
|
||||
|
@ -2702,7 +2706,7 @@ NumberPicker может работать в двух режимах: редак
|
|||
* текстовое представление любых из выше перечисленых типов
|
||||
|
||||
Все эти типы приводятся к float64. Соответственно функция Get всегда возвращает float64 значение.
|
||||
Прочитано значение свойства "date-picker-value" может быть также с помощью функции:
|
||||
Прочитано значение свойства "number-picker-value" может быть также с помощью функции:
|
||||
|
||||
func GetNumberPickerValue(view View, subviewID string) float64
|
||||
|
||||
|
@ -2710,14 +2714,14 @@ NumberPicker может работать в двух режимах: редак
|
|||
|
||||
| Свойство | Константа | Ограничение |
|
||||
|----------------------|------------------|------------------------|
|
||||
| "date-picker-min" | NumberPickerMin | Минимальное значение |
|
||||
| "date-picker-max" | NumberPickerMax | Максимальное значение |
|
||||
| "date-picker-step" | NumberPickerStep | Шаг изменения значения |
|
||||
| "number-picker-min" | NumberPickerMin | Минимальное значение |
|
||||
| "number-picker-max" | NumberPickerMax | Максимальное значение |
|
||||
| "number-picker-step" | NumberPickerStep | Шаг изменения значения |
|
||||
|
||||
Присвоины данным свойствам могут те же типы значений, что и "date-picker-value".
|
||||
Присвоины данным свойствам могут те же типы значений, что и "number-picker-value".
|
||||
|
||||
По умолчанию, в случае если "date-picker-type" равно NumberSlider, минимальное значение равно 0,
|
||||
максимальное - 1. Если же "date-picker-type" равно NumberEditor то вводимые числа, по умолчанию,
|
||||
По умолчанию, в случае если "number-picker-type" равно NumberSlider, минимальное значение равно 0,
|
||||
максимальное - 1. Если же "number-picker-type" равно NumberEditor то вводимые числа, по умолчанию,
|
||||
ограничены лишь диапазоном значений float64.
|
||||
|
||||
Прочитать значения данных свойств можно с помощью функций:
|
||||
|
@ -2725,7 +2729,7 @@ NumberPicker может работать в двух режимах: редак
|
|||
func GetNumberPickerMinMax(view View, subviewID string) (float64, float64)
|
||||
func GetNumberPickerStep(view View, subviewID string) float64
|
||||
|
||||
Для отслеживания изменения вводимого значения используется событие "date-changed" (константа
|
||||
Для отслеживания изменения вводимого значения используется событие "number-changed" (константа
|
||||
NumberChangedEvent). Основной слушатель события имеет следующий формат:
|
||||
|
||||
func(picker NumberPicker, newValue float64)
|
||||
|
|
32
README.md
32
README.md
|
@ -1654,6 +1654,10 @@ You can get the value of these properties using the function
|
|||
|
||||
func GetSkew(view View, subviewID string) (AngleUnit, AngleUnit)
|
||||
|
||||
### User data
|
||||
|
||||
You can save any of your data as "user-data" property (UserData constant)
|
||||
|
||||
### Keyboard events
|
||||
|
||||
Two kinds of keyboard events can be generated for a View that has received input focus.
|
||||
|
@ -2648,16 +2652,16 @@ To create a NumberPicker, the function is used:
|
|||
func NewNumberPicker(session Session, params Params) NumberPicker
|
||||
|
||||
NumberPicker can work in two modes: text editor and slider.
|
||||
The mode sets the int property "date-picker-type" (NumberPickerType constant).
|
||||
The "date-picker-type" property can take the following values:
|
||||
The mode sets the int property "number-picker-type" (NumberPickerType constant).
|
||||
The "number-picker-type" property can take the following values:
|
||||
|
||||
| Value | Constant | Name | Editor type |
|
||||
|:-----:|--------------|----------|----------------------------|
|
||||
| 0 | NumberEditor | "editor" | Text editor. Default value |
|
||||
| 1 | NumberSlider | "slider" | Slider |
|
||||
|
||||
You can set/get the current value using the "date-picker-value" property (NumberPickerValue constant).
|
||||
The following can be passed as a value to the "date-picker-value" property:
|
||||
You can set/get the current value using the "number-picker-value" property (NumberPickerValue constant).
|
||||
The following can be passed as a value to the "number-picker-value" property:
|
||||
|
||||
* float64
|
||||
* float32
|
||||
|
@ -2668,29 +2672,29 @@ The following can be passed as a value to the "date-picker-value" property:
|
|||
* textual representation of any of the above types
|
||||
|
||||
All of these types are cast to float64. Accordingly, the Get function always returns a float64 value.
|
||||
The value of the "date-picker-value" property can also be read using the function:
|
||||
The value of the "number-picker-value" property can also be read using the function:
|
||||
|
||||
func GetNumberPickerValue(view View, subviewID string) float64
|
||||
|
||||
The entered values may be subject to restrictions. For this, the following properties are used:
|
||||
|
||||
| Property | Constant | Restriction |
|
||||
|--------------------|------------------|-------------------|
|
||||
| "date-picker-min" | NumberPickerMin | Minimum value |
|
||||
| "date-picker-max" | NumberPickerMax | Maximum value |
|
||||
| "date-picker-step" | NumberPickerStep | Value change step |
|
||||
| Property | Constant | Restriction |
|
||||
|----------------------|------------------|-------------------|
|
||||
| "number-picker-min" | NumberPickerMin | Minimum value |
|
||||
| "number-picker-max" | NumberPickerMax | Maximum value |
|
||||
| "number-picker-step" | NumberPickerStep | Value change step |
|
||||
|
||||
Assignments to these properties can be the same value types as "date-picker-value".
|
||||
Assignments to these properties can be the same value types as "number-picker-value".
|
||||
|
||||
By default, if "date-picker-type" is equal to NumberSlider, the minimum value is 0, maximum is 1.
|
||||
If "date-picker-type" is equal to NumberEditor, then the entered numbers, by default, are limited only by the range of float64 values.
|
||||
By default, if "number-picker-type" is equal to NumberSlider, the minimum value is 0, maximum is 1.
|
||||
If "number-picker-type" is equal to NumberEditor, then the entered numbers, by default, are limited only by the range of float64 values.
|
||||
|
||||
You can read the values of these properties using the functions:
|
||||
|
||||
func GetNumberPickerMinMax(view View, subviewID string) (float64, float64)
|
||||
func GetNumberPickerStep(view View, subviewID string) float64
|
||||
|
||||
The "date-changed" event (NumberChangedEvent constant) is used to track the change in the entered value.
|
||||
The "number-changed" event (NumberChangedEvent constant) is used to track the change in the entered value.
|
||||
The main event listener has the following format:
|
||||
|
||||
func(picker NumberPicker, newValue float64)
|
||||
|
|
|
@ -1759,7 +1759,7 @@ function tableRowClickEvent(element, event) {
|
|||
const table = document.getElementById(tableID);
|
||||
if (table) {
|
||||
const selection = table.getAttribute("data-selection");
|
||||
if (selection == "cell") {
|
||||
if (selection == "row") {
|
||||
const currentID = table.getAttribute("data-current");
|
||||
if (!currentID || currentID != element.ID) {
|
||||
setTableRowCursor(table, row)
|
||||
|
|
|
@ -21,13 +21,25 @@ div:focus {
|
|||
}
|
||||
|
||||
input {
|
||||
padding: 4px;
|
||||
overflow: auto;
|
||||
margin: 2px;
|
||||
padding: 1px;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
select {
|
||||
margin: 2px;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
textarea {
|
||||
padding: 4px;
|
||||
margin: 2px;
|
||||
padding: 1px;
|
||||
overflow: auto;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
ul:focus {
|
||||
|
|
|
@ -65,7 +65,7 @@ theme {
|
|||
styles = [
|
||||
ruiApp {
|
||||
font-name = "Arial, Helvetica, sans-serif",
|
||||
text-size = 12pt,
|
||||
text-size = 10pt,
|
||||
text-color = @ruiTextColor,
|
||||
background-color = @ruiBackgroundColor,
|
||||
},
|
||||
|
|
|
@ -9,6 +9,9 @@ const (
|
|||
StyleDisabled = "style-disabled"
|
||||
// Disabled is the constant for the "disabled" property tag.
|
||||
Disabled = "disabled"
|
||||
// Focusable is the constant for the "disabled" property tag.
|
||||
// The bool "focusable" determines whether the view will receive focus.
|
||||
Focusable = "focusable"
|
||||
// Semantics is the constant for the "semantics" property tag.
|
||||
Semantics = "semantics"
|
||||
// Visibility is the constant for the "visibility" property tag.
|
||||
|
@ -440,4 +443,7 @@ const (
|
|||
// The "float" property places a View on the left or right side of its container,
|
||||
// allowing text and inline Views to wrap around it.
|
||||
Float = "float"
|
||||
// UsetData is the constant for the "user-data" property tag.
|
||||
// This property can contain any user data
|
||||
UserData = "user-data"
|
||||
)
|
||||
|
|
|
@ -37,6 +37,7 @@ var angleProperties = []string{
|
|||
|
||||
var boolProperties = []string{
|
||||
Disabled,
|
||||
Focusable,
|
||||
Inset,
|
||||
BackfaceVisible,
|
||||
ReadOnly,
|
||||
|
|
52
session.go
52
session.go
|
@ -29,8 +29,12 @@ type Session interface {
|
|||
TextDirection() int
|
||||
// Constant returns the constant with "tag" name or "" if it is not exists
|
||||
Constant(tag string) (string, bool)
|
||||
// ConstantTags returns the list of all available constants
|
||||
ConstantTags() []string
|
||||
// Color returns the color with "tag" name or 0 if it is not exists
|
||||
Color(tag string) (Color, bool)
|
||||
// ColorTags returns the list of all available color constants
|
||||
ColorTags() []string
|
||||
// SetCustomTheme set the custom theme
|
||||
SetCustomTheme(name string) bool
|
||||
// UserAgent returns the "user-agent" text of the client browser
|
||||
|
@ -106,6 +110,7 @@ type Session interface {
|
|||
|
||||
type sessionData struct {
|
||||
customTheme *theme
|
||||
currentTheme *theme
|
||||
darkTheme bool
|
||||
touchScreen bool
|
||||
textDirection int
|
||||
|
@ -146,6 +151,7 @@ func newSession(app Application, id int, customTheme string, params DataObject)
|
|||
if customTheme != "" {
|
||||
if theme, ok := newTheme(customTheme); ok {
|
||||
session.customTheme = theme
|
||||
session.currentTheme = nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,18 +212,11 @@ func (session *sessionData) close() {
|
|||
}
|
||||
|
||||
func (session *sessionData) styleProperty(styleTag, propertyTag string) (string, bool) {
|
||||
var style DataObject
|
||||
ok := false
|
||||
if session.customTheme != nil {
|
||||
style, ok = session.customTheme.styles[styleTag]
|
||||
}
|
||||
if !ok {
|
||||
style, ok = defaultTheme.styles[styleTag]
|
||||
}
|
||||
|
||||
if ok {
|
||||
if node := style.PropertyWithTag(propertyTag); node != nil && node.Type() == TextNode {
|
||||
return session.resolveConstants(node.Text())
|
||||
if style, ok := session.getCurrentTheme().styles[styleTag]; ok {
|
||||
if value, ok := style[propertyTag]; ok {
|
||||
if text, ok := value.(string); ok {
|
||||
return session.resolveConstants(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,17 +225,12 @@ func (session *sessionData) styleProperty(styleTag, propertyTag string) (string,
|
|||
}
|
||||
|
||||
func (session *sessionData) stylePropertyNode(styleTag, propertyTag string) DataNode {
|
||||
var style DataObject
|
||||
ok := false
|
||||
if session.customTheme != nil {
|
||||
style, ok = session.customTheme.styles[styleTag]
|
||||
}
|
||||
if !ok {
|
||||
style, ok = defaultTheme.styles[styleTag]
|
||||
}
|
||||
|
||||
if ok {
|
||||
return style.PropertyWithTag(propertyTag)
|
||||
if style, ok := session.getCurrentTheme().styles[styleTag]; ok {
|
||||
if value, ok := style[propertyTag]; ok {
|
||||
if node, ok := value.(DataNode); ok {
|
||||
return node
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -280,17 +274,7 @@ func (session *sessionData) RootView() View {
|
|||
}
|
||||
|
||||
func (session *sessionData) writeInitScript(writer *strings.Builder) {
|
||||
var workTheme *theme
|
||||
if session.customTheme == nil {
|
||||
workTheme = defaultTheme
|
||||
} else {
|
||||
workTheme = new(theme)
|
||||
workTheme.init()
|
||||
workTheme.concat(defaultTheme)
|
||||
workTheme.concat(session.customTheme)
|
||||
}
|
||||
|
||||
if css := workTheme.cssText(session); css != "" {
|
||||
if css := session.getCurrentTheme().cssText(session); css != "" {
|
||||
writer.WriteString(`document.querySelector('style').textContent += "`)
|
||||
writer.WriteString(css)
|
||||
writer.WriteString("\";\n")
|
||||
|
|
105
sessionTheme.go
105
sessionTheme.go
|
@ -2,24 +2,10 @@ package rui
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
type Session struct {
|
||||
customTheme *theme
|
||||
darkTheme bool
|
||||
touchScreen bool
|
||||
textDirection int
|
||||
pixelRatio float64
|
||||
language string
|
||||
languages []string
|
||||
checkboxOff string
|
||||
checkboxOn string
|
||||
radiobuttonOff string
|
||||
radiobuttonOn string
|
||||
}
|
||||
*/
|
||||
func (session *sessionData) DarkTheme() bool {
|
||||
return session.darkTheme
|
||||
}
|
||||
|
@ -39,27 +25,17 @@ func (session *sessionData) TextDirection() int {
|
|||
func (session *sessionData) constant(tag string, prevTags []string) (string, bool) {
|
||||
tags := append(prevTags, tag)
|
||||
result := ""
|
||||
themes := session.themes()
|
||||
theme := session.getCurrentTheme()
|
||||
for {
|
||||
ok := false
|
||||
if session.touchScreen {
|
||||
for _, theme := range themes {
|
||||
if theme.touchConstants != nil {
|
||||
if result, ok = theme.touchConstants[tag]; ok {
|
||||
break
|
||||
}
|
||||
}
|
||||
if theme.touchConstants != nil {
|
||||
result, ok = theme.touchConstants[tag]
|
||||
}
|
||||
}
|
||||
|
||||
if !ok {
|
||||
for _, theme := range themes {
|
||||
if theme.constants != nil {
|
||||
if result, ok = theme.constants[tag]; ok {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
result, ok = theme.constants[tag]
|
||||
}
|
||||
|
||||
if !ok {
|
||||
|
@ -149,38 +125,38 @@ func (session *sessionData) Constant(tag string) (string, bool) {
|
|||
return session.constant(tag, []string{})
|
||||
}
|
||||
|
||||
func (session *sessionData) themes() []*theme {
|
||||
if session.customTheme != nil {
|
||||
return []*theme{session.customTheme, defaultTheme}
|
||||
func (session *sessionData) getCurrentTheme() *theme {
|
||||
if session.currentTheme != nil {
|
||||
return session.currentTheme
|
||||
}
|
||||
|
||||
return []*theme{defaultTheme}
|
||||
if session.customTheme != nil {
|
||||
session.currentTheme = new(theme)
|
||||
session.currentTheme.init()
|
||||
session.currentTheme.concat(defaultTheme)
|
||||
session.currentTheme.concat(session.customTheme)
|
||||
return session.currentTheme
|
||||
}
|
||||
|
||||
return defaultTheme
|
||||
}
|
||||
|
||||
// Color return the color with "tag" name or 0 if it is not exists
|
||||
func (session *sessionData) Color(tag string) (Color, bool) {
|
||||
tags := []string{tag}
|
||||
result := ""
|
||||
themes := session.themes()
|
||||
theme := session.getCurrentTheme()
|
||||
for {
|
||||
ok := false
|
||||
if session.darkTheme {
|
||||
for _, theme := range themes {
|
||||
if theme.darkColors != nil {
|
||||
if result, ok = theme.darkColors[tag]; ok {
|
||||
break
|
||||
}
|
||||
}
|
||||
if theme.darkColors != nil {
|
||||
result, ok = theme.darkColors[tag]
|
||||
}
|
||||
}
|
||||
|
||||
if !ok {
|
||||
for _, theme := range themes {
|
||||
if theme.colors != nil {
|
||||
if result, ok = theme.colors[tag]; ok {
|
||||
break
|
||||
}
|
||||
}
|
||||
if theme.colors != nil {
|
||||
result, ok = theme.colors[tag]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,6 +193,7 @@ func (session *sessionData) SetCustomTheme(name string) bool {
|
|||
}
|
||||
} else if theme, ok := resources.themes[name]; ok {
|
||||
session.customTheme = theme
|
||||
session.currentTheme = nil
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
|
@ -361,3 +338,39 @@ func (session *sessionData) SetLanguage(lang string) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (session *sessionData) ConstantTags() []string {
|
||||
theme := session.getCurrentTheme()
|
||||
|
||||
keys := make([]string, 0, len(theme.constants))
|
||||
for k := range theme.constants {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
for tag := range theme.touchConstants {
|
||||
if _, ok := theme.constants[tag]; !ok {
|
||||
keys = append(keys, tag)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
func (session *sessionData) ColorTags() []string {
|
||||
theme := session.getCurrentTheme()
|
||||
|
||||
keys := make([]string, 0, len(theme.colors))
|
||||
for k := range theme.colors {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
for tag := range theme.darkColors {
|
||||
if _, ok := theme.colors[tag]; !ok {
|
||||
keys = append(keys, tag)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
|
|
@ -230,3 +230,21 @@ func GetTableRowSelectedListeners(view View, subviewID string) []func(TableView,
|
|||
}
|
||||
return []func(TableView, int){}
|
||||
}
|
||||
|
||||
// ReloadTableViewData updates TableView
|
||||
func ReloadTableViewData(view View, subviewID string) bool {
|
||||
var tableView TableView
|
||||
if subviewID != "" {
|
||||
if tableView = TableViewByID(view, subviewID); tableView == nil {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
var ok bool
|
||||
if tableView, ok = view.(TableView); !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
tableView.ReloadTableData()
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ func (tabsLayout *tabsLayoutData) remove(tag string) {
|
|||
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 {
|
||||
listener(tabsLayout, 0, oldCurrent)
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ func (tabsLayout *tabsLayoutData) set(tag string, value interface{}) bool {
|
|||
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 {
|
||||
listener(tabsLayout, current, oldCurrent)
|
||||
}
|
||||
|
|
39
theme.go
39
theme.go
|
@ -16,7 +16,7 @@ type mediaStyle struct {
|
|||
orientation int
|
||||
width int
|
||||
height int
|
||||
styles map[string]DataObject
|
||||
styles map[string]Params
|
||||
}
|
||||
|
||||
func (rule mediaStyle) cssText() string {
|
||||
|
@ -47,7 +47,7 @@ func (rule mediaStyle) cssText() string {
|
|||
}
|
||||
|
||||
func parseMediaRule(text string) (mediaStyle, bool) {
|
||||
rule := mediaStyle{orientation: defaultMedia, width: 0, height: 0, styles: map[string]DataObject{}}
|
||||
rule := mediaStyle{orientation: defaultMedia, width: 0, height: 0, styles: map[string]Params{}}
|
||||
elements := strings.Split(text, ":")
|
||||
for i := 1; i < len(elements); i++ {
|
||||
switch element := elements[i]; element {
|
||||
|
@ -111,7 +111,7 @@ type theme struct {
|
|||
touchConstants map[string]string
|
||||
colors map[string]string
|
||||
darkColors map[string]string
|
||||
styles map[string]DataObject
|
||||
styles map[string]Params
|
||||
mediaStyles []mediaStyle
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ func (theme *theme) init() {
|
|||
theme.touchConstants = map[string]string{}
|
||||
theme.colors = map[string]string{}
|
||||
theme.darkColors = map[string]string{}
|
||||
theme.styles = map[string]DataObject{}
|
||||
theme.styles = map[string]Params{}
|
||||
theme.mediaStyles = []mediaStyle{}
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,9 @@ func (theme *theme) cssText(session Session) string {
|
|||
for tag, obj := range theme.styles {
|
||||
var style viewStyle
|
||||
style.init()
|
||||
parseProperties(&style, obj)
|
||||
for tag, value := range obj {
|
||||
style.Set(tag, value)
|
||||
}
|
||||
builder.startStyle(tag)
|
||||
style.cssViewStyle(&builder, session)
|
||||
builder.endStyle()
|
||||
|
@ -200,7 +202,9 @@ func (theme *theme) cssText(session Session) string {
|
|||
for tag, obj := range media.styles {
|
||||
var style viewStyle
|
||||
style.init()
|
||||
parseProperties(&style, obj)
|
||||
for tag, value := range obj {
|
||||
style.Set(tag, value)
|
||||
}
|
||||
builder.startStyle(tag)
|
||||
style.cssViewStyle(&builder, session)
|
||||
builder.endStyle()
|
||||
|
@ -234,6 +238,25 @@ func (theme *theme) addData(data DataObject) {
|
|||
func (theme *theme) parseThemeData(data DataObject) {
|
||||
count := data.PropertyCount()
|
||||
|
||||
objToParams := func(obj DataObject) Params {
|
||||
params := Params{}
|
||||
for i := 0; i < obj.PropertyCount(); i++ {
|
||||
if node := obj.Property(i); node != nil {
|
||||
switch node.Type() {
|
||||
case ArrayNode:
|
||||
params[node.Tag()] = node.ArrayElements()
|
||||
|
||||
case ObjectNode:
|
||||
params[node.Tag()] = node.Object()
|
||||
|
||||
default:
|
||||
params[node.Tag()] = node.Text()
|
||||
}
|
||||
}
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
for i := 0; i < count; i++ {
|
||||
if d := data.Property(i); d != nil {
|
||||
switch tag := d.Tag(); tag {
|
||||
|
@ -291,7 +314,7 @@ func (theme *theme) parseThemeData(data DataObject) {
|
|||
for k := 0; k < arraySize; k++ {
|
||||
if element := d.ArrayElement(k); element != nil && element.IsObject() {
|
||||
if obj := element.Object(); obj != nil {
|
||||
theme.styles[obj.Tag()] = obj
|
||||
theme.styles[obj.Tag()] = objToParams(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -304,7 +327,7 @@ func (theme *theme) parseThemeData(data DataObject) {
|
|||
for k := 0; k < arraySize; k++ {
|
||||
if element := d.ArrayElement(k); element != nil && element.IsObject() {
|
||||
if obj := element.Object(); obj != nil {
|
||||
rule.styles[obj.Tag()] = obj
|
||||
rule.styles[obj.Tag()] = objToParams(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
9
view.go
9
view.go
|
@ -177,6 +177,9 @@ func (view *viewData) ViewByID(id string) View {
|
|||
}
|
||||
|
||||
func (view *viewData) Focusable() bool {
|
||||
if focus, ok := boolProperty(view, Focusable, view.session); ok {
|
||||
return focus
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -189,6 +192,9 @@ func (view *viewData) remove(tag string) {
|
|||
case ID:
|
||||
view.viewID = ""
|
||||
|
||||
case UserData:
|
||||
delete(view.properties, tag)
|
||||
|
||||
case Style, StyleDisabled:
|
||||
if _, ok := view.properties[tag]; ok {
|
||||
delete(view.properties, tag)
|
||||
|
@ -311,6 +317,9 @@ func (view *viewData) set(tag string, value interface{}) bool {
|
|||
}
|
||||
view.viewID = text
|
||||
|
||||
case UserData:
|
||||
view.properties[tag] = value
|
||||
|
||||
case Style, StyleDisabled:
|
||||
text, ok := value.(string)
|
||||
if !ok {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package rui
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
@ -135,5 +136,13 @@ func CreateViewFromResources(session Session, name string) View {
|
|||
}
|
||||
}
|
||||
|
||||
if resources.path != "" {
|
||||
if data, err := os.ReadFile(resources.path + viewDir + "/" + name); err == nil {
|
||||
if data := ParseDataText(string(data)); data != nil {
|
||||
return CreateViewFromObject(session, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
14
viewUtils.go
14
viewUtils.go
|
@ -1053,19 +1053,13 @@ func GetCurrent(view View, subviewID string) int {
|
|||
view = ViewByID(view, subviewID)
|
||||
}
|
||||
|
||||
var defaultValue int
|
||||
switch view.Tag() {
|
||||
case "ListView":
|
||||
defaultValue = -1
|
||||
|
||||
default:
|
||||
defaultValue = 0
|
||||
}
|
||||
|
||||
defaultValue := -1
|
||||
if view != nil {
|
||||
if result, ok := intProperty(view, Current, view.Session(), defaultValue); ok {
|
||||
return result
|
||||
} else if view.Tag() != "ListView" {
|
||||
defaultValue = 0
|
||||
}
|
||||
}
|
||||
return -1
|
||||
return defaultValue
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue