From 59acf03260877348c8cfbca911a6a7f96f64e02a Mon Sep 17 00:00:00 2001 From: anoshenko Date: Sat, 20 Nov 2021 19:51:51 +0300 Subject: [PATCH] GetDropDownCurrent and GetListViewCurrent functions replaced by the GetCurrent function. Updated readme --- CHANGELOG.md | 1 + README-ru.md | 147 +++++++++++++++++++++++++++++++++++++--- README.md | 131 ++++++++++++++++++++++++++++++++++- demo/animationDemo.go | 10 +-- demo/backgroundDemo.go | 14 ++-- demo/stackLayoutDemo.go | 6 +- demo/textStyle.go | 2 +- dropDownList.go | 22 ++---- listView.go | 28 ++------ tabsLayout.go | 17 ----- viewUtils.go | 24 +++++++ 11 files changed, 320 insertions(+), 82 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abc2459..ecdf41b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ * Added SetTitle and SetTitleColor function to the Session interface * Added a listener for changing a view property value * Added the "current" property to StackLayout +* GetDropDownCurrent and GetListViewCurrent functions replaced by the GetCurrent function * Updated TabsLayout * Bug fixing diff --git a/README-ru.md b/README-ru.md index 693e8d6..17cfc1c 100644 --- a/README-ru.md +++ b/README-ru.md @@ -316,12 +316,12 @@ Value - угловая величина Для более наглядного и простого задания переменных типа AngleUnit могут использоваться функции приведенные ниже -| Функция | Эквивалентное определение | -|---------------|-------------------------------------------------| -| rui.Rad(n) | rui.AngleUnit{ Type: rui.Radian, Value: n } | -| rui.PiRad(n) | rui.AngleUnit{ Type: rui.PiRadian, Value: n } | -| rui.Deg(n) | rui.AngleUnit{ Type: rui.Degree, Value: n } | -| rui.Grad(n) | rui.AngleUnit{ Type: rui.Gradian, Value: n } | +| Функция | Эквивалентное определение | +|---------------|-----------------------------------------------| +| rui.Rad(n) | rui.AngleUnit{ Type: rui.Radian, Value: n } | +| rui.PiRad(n) | rui.AngleUnit{ Type: rui.PiRadian, Value: n } | +| rui.Deg(n) | rui.AngleUnit{ Type: rui.Degree, Value: n } | +| rui.Grad(n) | rui.AngleUnit{ Type: rui.Gradian, Value: n } | Переменные типа AngleUnit имеют текстовое представление состоящее из числа (равному значению поля Value) и следующим за ним суффиксом определяющим тип. Суффиксы перечислены в следующей таблице: @@ -374,6 +374,22 @@ View имеет ряд свойств, таких как высота, шири Данные функции возвращают/устанавливают значение дочернего View +### Отслеживание изменения свойств + +Вы можете установить функцию для отслеживания изменения абсолютно любого свойства View (исключений нет). +Для установки слушателя изменений интерфейс View содержит функцию: + + SetChangeListener(tag string, listener func(View, string)) + +где первый параметр это имя отслеживаемого свойства, а второй - функция которая будет вызываться +какждый раз когда значение свойства изменится. + +Например + + view.SetChangeListener(rui.BackgroundColor, listener func(view View, tag string) { + // The background color changed + }) + ### События При взаимодействии с приложением возникаю различные события: клики, изменение размеров, @@ -2368,10 +2384,28 @@ StackLayout является контейнером, реализующим ин Второй аргумент onPopFinished - функция вызываемая по окончании анимации. Может быть nil. Функция вернёт false если StackLayout пуст и true если текущий элемени был удален. - Получить текущий (видимый) View можно с помощью функции интерфейса +Получить текущий (видимый) View можно с помощью функции интерфейса Peek() View +Так же получить текущий View можно используя его индекс. Для получения индекса используется +свойство "current" (константа Current). Пример + + func peek(layout rui.StackLayout) { + views := layout.Views() + if index := rui.GetCurrent(layout, ""); index >= 0 && index < len(views) { + return views[index] + } + return nil + } + +Конечно это менее удобно по сравнению с функцией Peek. Однако свойство "current" может быть использовано +для отслеживания изменения текущего View: + + layout.SetChangeListener(rui.Current, func(view rui.View, tag string) { + // current view changed + }) + Для того чтобы сделать любой дочерний View текущим (видимым) используются функции интерфейса: MoveToFront(view View) bool @@ -2380,6 +2414,101 @@ StackLayout является контейнером, реализующим ин Данная функция вернет true в случае успеха и false если дочерний View или View с таким id не существует и в лог будет записано сообщение об ошибке. +Также чтобы сделать любой дочерний View текущим (видимым) можно использовать свойство "current". + +## TabsLayout + +TabsLayout является контейнером, реализующим интерфейс ViewsContainer. Все дочерние View +располагаются друг над другом и каждый занимает все пространство контейнера. В каждый момент времени +доступен только один дочерний View (текущий). Для выбора текущего View используются вкладки которые располагаются +вдоль одной из сторон контейнера + +Для создания TabsLayout используется функция + + func NewTabsLayout(session Session, params Params) TabsLayout + +Для каждого View создается закладка. На закладке может отображаться заголовок, иконка и кнопка закрытия. + +Заголовок задается с помощью текстового свойства "title" (константа Title) дочернего View. +Свойство "title" опционально. Если оно не задано, то на вкладке не будет текста. + +Иконка задается с помощью текстового свойства "icon" (константа Icon) дочернего View. +В качестве значения ему присваивается имя файла иконки (если иконка располагается +в ресурсах приложения) или url. Свойство "icon" опционально. Если оно не задано, то на вкладке не будет иконки. + +Отображение кнопки закрытия вкладки управляется с помощью булевского свойства "tab-close-button" (константа TabCloseButton). +Значение "true" включает отображение кнопки закрытия вкладки. Значение по умолчанию "false". + +Cвойства "tab-close-button" может быть задано как для дочернего View так и для самого TabsLayout. +Установка значения свойства "tab-close-button" для TabsLayout включает/выключает отображение +кнопки закрытия сразу для всех вкладок. Значение "tab-close-button" установленое для дочернего +элемента имеет более высокий приоритет по сравнению со значением установленным для TabsLayout. + +Кнопка закрытия вкладки не закрывает вкладку, а только генерирует событие "tab-close-event" (константа TabCloseEvent). +Основной обработчик данного события имеет формат + + func(layout TabsLayout, index int) + +где второй элемент это индекс дочернего View. + +Как уже было сказано, нажатие на кнопку закрытия вкладки не закрывает вкладку. +Вы сами должны закрывать вкладку. Это делается следующим образом + + tabsView.Set(rui.TabCloseEvent, func(layout rui.TabsLayout, index int) { + layout.RemoveView(index) + }) + +Управлять текущим View можно с помощью целочисленного свойства "current" (константа Current). +Для программного переключания вкладок присвойте данному свойству значение индекса новой текущего View. +Прочитать значение свойства "current" можно с помощью функции + + func GetCurrent(view View, subviewID string) int + +Также свойство "current" может быть использовано для отслеживания изменения текущего View: + + tabsView.SetChangeListener(rui.Current, func(view rui.View, tag string) { + // current view changed + }) + +Вкладки располагаются вдоль одной из сторон контейнера TabsLayout. Расположение вкладок +задается с помощью целочисленного свойства "tabs" (константа Tabs). Данное свойство может +принимать следующие значения + +| Значение | Константа | Имя | Расположение вкладок | +|:--------:|---------------|--------------|----------------------------------------------------------------| +| 0 | TopTabs | "top" | Сверху. Значение по умолчанию. | +| 1 | BottomTabs | "bottom" | Снизу. | +| 2 | LeftTabs | "left" | Слева. Каждая вкладка повернута на 90° против часовой стрелки. | +| 3 | RightTabs | "right" | Справа. Каждая вкладка повернута на 90° по часовой стрелки. | +| 4 | LeftListTabs | "left-list" | Слева. Вкладки отображаются в виде списка. | +| 5 | RightListTabs | "right-list" | Справа. Вкладки отображаются в виде списка. | +| 6 | HiddenTabs | "hidden" | Вкладки скрыты. | + +Зачем нужно значение HiddenTabs. Дело в том, что TabsLayout реализует интерфейс ListAdapter. +Что позволяет легко реализовать вкладки с помощью ListView. Именно в этом случаи и применяется значение HiddenTabs. + +При отображении текущей (выбранной) вкладки типа TopTabs, BottomTabs, LeftListTabs и RightListTabs используется +стиль "ruiActiveTab", а для вкладки типа LeftTabs и RightTabs используется стиль "ruiActiveVerticalTab". +Если вы хотите кастомизировать отображение вкладок, то вы можите либо переопределить данные стили, либо +назначить свой стиль с помощью свойства "current-tab-style" (константа CurrentTabStyle). + +Соответственно, для неактивной вкладки используются стили "ruiInactiveTab" и "ruiInactiveVerticalTab", а +назначить свой стиль можно с помощью свойства "tab-style" (константа TabStyle). + +Также при отображении вкладок используется следующие константы и стили: + +* "ruiTabHeight" - SizeUnit константа задает высоту панели вкладок; + +* "ruiTabSpace" - SizeUnit константа задает расстояние между вкладками; + +* "ruiTabsPadding" - SizeUnit или BoundsProperty константа задает отступ от внутри панели вкладок; + +* "ruiTabsBackgroundColor" - цвет фона панели закладок; + +* "ruiTabCloseButton" - стиль кнопки закрытия вкладки. + +Вы можете переопределять данные константы и стили для кастимизации панели вкладок + ## AbsoluteLayout AbsoluteLayout является контейнером, реализующим интерфейс ViewsContainer. Дочерние View @@ -2840,7 +2969,7 @@ float32, float64, int, int8…int64, uint, uint8…uint64. Выбранное значение определяется int свойством "current" (константа Current). Значение по умолчанию 0. Прочитать значение данного свойства можно с помощью функции - func GetDropDownCurrent(view View, subviewID string) int + func GetCurrent(view View, subviewID string) int Для отслеживания изменения свойства "current" используется событие "drop-down-event" (константа DropDownEvent). Основной слушатель события имеет следующий формат: @@ -3023,7 +3152,7 @@ int свойство "current" (константа Current). Значение "c Получить значение данного свойства можно с помощью функции - func GetListViewCurrent(view View, subviewID string) int + func GetCurrent(view View, subviewID string) int ### Свойства "list-item-style", "current-style" и "current-inactive-style" diff --git a/README.md b/README.md index f98ff20..3da9303 100644 --- a/README.md +++ b/README.md @@ -377,6 +377,22 @@ To simplify setting / reading properties, there are also two global functions Ge These functions get/set the value of the child View +### Tracking property changes + +You can set a function to track the change of absolutely any View property (there are no exceptions). +To set up a change listener, the View interface contains a function: + + SetChangeListener(tag string, listener func(View, string)) + +where the first parameter is the name of the tracked property, and the second is the function +that will be called every time the property value changes. + +For example + + view.SetChangeListener(rui.BackgroundColor, listener func(view View, tag string) { + // The background color changed + }) + ### Events When interacting with the application, various events arise: clicks, resizing, changing input data, etc. @@ -2342,6 +2358,23 @@ The function will return false if the StackLayout is empty and true if the curre Peek() View +You can also get the current View using its index. The "current" property (constant Current) is used to get the index. +Example + + func peek(layout rui.StackLayout) { + views := layout.Views() + if index := rui.GetCurrent(layout, ""); index >= 0 && index < len(views) { + return views[index] + } + return nil + } + +Of course, this is less convenient than the Peek function. However, the "current" property can be used to track changes to the current View: + + layout.SetChangeListener(rui.Current, func(view rui.View, tag string) { + // current view changed + }) + In order to make any child View current (visible), the interface functions are used: MoveToFront(view View) bool @@ -2350,6 +2383,100 @@ In order to make any child View current (visible), the interface functions are u This function will return true if successful and false if the child View or View with id does not exist and an error message will be written to the log. +You can also use the "current" property to make any child View current (visible). + +## TabsLayout + +TabsLayout is a container that implements the ViewsContainer interface. All child Views are stacked +on top of each other and each takes up the entire container space. +Only one child View (current) is available at a time. Tabs, that are located along one of the sides of the container, +are used to select the current View. + +To create a TabsLayout, use the function + + func NewTabsLayout(session Session, params Params) TabsLayout + +A bookmark is created for each View. A bookmark can display a title, an icon, and a close button. + +The title is set using the "title" text property (constant Title) of the child View. +The "title" property is optional. If it is not specified, then there will be no text on the tab. + +The icon is set using the "icon" text property (constant Icon) of the child View. +As a value, it is assigned the name of the icon file (if the icon is located in the application resources) or url. +The "icon" property is optional. If it is not specified, then there will be no icon on the tab. + +The display of the tab close button is controlled by the "tab-close-button" boolean property (constant TabCloseButton). +"true" enables the display of the close button for the tab. The default is "false". + +The "tab-close-button" properties can be set for both the child View and the TabsLayout itself. +Setting the value of the "tab-close-button" property for the TabsLayout enables/disables the display +of the close button for all tabs at once. The "tab-close-button" value set on the child View +takes precedence over the value set on the TabsLayout. + +The tab close button does not close the tab, but only generates the "tab-close-event" event (constant TabCloseEvent). +The main handler for this event has the format + + func(layout TabsLayout, index int) + +where the second element is the index of the child View. + +As already mentioned, clicking on the close tab button does not close the tab. +You must close the tab yourself. This is done as follows + + tabsView.Set(rui.TabCloseEvent, func(layout rui.TabsLayout, index int) { + layout.RemoveView(index) + }) + +You can control the current View using the "current" integer property (constant Current). +To programmatically switch tabs, set this property to the index of the new current View. +You can read the value of the "current" property using the function + + func GetCurrent(view View, subviewID string) int + +Also, the "current" property can be used to track changes to the current View: + + tabsView.SetChangeListener(rui.Current, func(view rui.View, tag string) { + // current view changed + }) + +Tabs are positioned along one side of the TabsLayout container. The tabs are positioned using +the "tabs" integer property (the Tabs constant). This property can take on the following values: + +| Value | Constant | Name | Placement of tabs | +|:--------:|---------------|--------------|--------------------------------------------------| +| 0 | TopTabs | "top" | Top. Default value. | +| 1 | BottomTabs | "bottom" | Bottom. | +| 2 | LeftTabs | "left" | Left. Each tab is rotated 90 ° counterclockwise. | +| 3 | RightTabs | "right" | On right. Each tab is rotated 90 ° clockwise. | +| 4 | LeftListTabs | "left-list" | Left. The tabs are displayed as a list. | +| 5 | RightListTabs | "right-list" | On right. The tabs are displayed as a list. | +| 6 | HiddenTabs | "hidden" | The tabs are hidden. | + +Why do I need the value HiddenTabs. The point is that TabsLayout implements the ListAdapter interface. +Which makes it easy to implement tabs with a ListView. This is where the HiddenTabs value comes in. + +When displaying the current (selected) tabs of type TopTabs, BottomTabs, LeftListTabs and RightListTabs, +the style is "ruiActiveTab", and for tabs of type LeftTabs and RightTabs, the style is "ruiActiveVerticalTab". +If you want to customize the display of tabs, you can either override these styles, or assign your own style using +the "current-tab-style" property (constant CurrentTabStyle). + +Accordingly, for an inactive tab, the "ruiInactiveTab" and "ruiInactiveVerticalTab" styles are used, +and you can assign your own style using the "tab-style" property (constant TabStyle). + +Also, when displaying tabs, the following constants and styles are used: + +* "ruiTabHeight" - the SizeUnit constant sets the height of the tab bar; + +* "ruiTabSpace" - the SizeUnit constant sets the distance between tabs; + +* "ruiTabsPadding" - the SizeUnit or BoundsProperty constant sets the indentation from the inside of the tab bar; + +* "ruiTabsBackgroundColor" - background color of the tabs bar; + +* "ruiTabCloseButton" - style of the button for closing the tab. + +You can override these constants and styles to customize the tab bar + ## AbsoluteLayout AbsoluteLayout is a container that implements the ViewsContainer interface. @@ -2809,7 +2936,7 @@ You can read the value of the "items" property using the function The selected value is determined by the int property "current" (Current constant). The default is 0. You can read the value of this property using the function - func GetDropDownCurrent(view View, subviewID string) int + func GetCurrent(view View, subviewID string) int To track the change of the "current" property, the "drop-down-event" event (DropDownEvent constant) is used. The main event listener has the following format: @@ -2990,7 +3117,7 @@ The value "current" is less than 0 means that no item is selected You can get the value of this property using the function - func GetListViewCurrent(view View, subviewID string) int + func GetCurrent(view View, subviewID string) int ### "list-item-style", "current-style", and "current-inactive-style" properties diff --git a/demo/animationDemo.go b/demo/animationDemo.go index 9e5d4ea..86348f0 100644 --- a/demo/animationDemo.go +++ b/demo/animationDemo.go @@ -80,12 +80,12 @@ func createAnimationDemo(session rui.Session) rui.View { params := rui.Params{ rui.PropertyTag: []rui.AnimatedProperty{prop1, prop2, prop3}, - rui.Duration: rui.GetDropDownCurrent(view, "animationDuration") * 4, - rui.Delay: rui.GetDropDownCurrent(view, "animationDelay"), - rui.AnimationDirection: rui.GetDropDownCurrent(view, "animationDirection"), + rui.Duration: rui.GetCurrent(view, "animationDuration") * 4, + rui.Delay: rui.GetCurrent(view, "animationDelay"), + rui.AnimationDirection: rui.GetCurrent(view, "animationDirection"), } - switch rui.GetDropDownCurrent(view, "animationTimingFunction") { + switch rui.GetCurrent(view, "animationTimingFunction") { case 0: params[rui.TimingFunction] = rui.EaseTiming @@ -96,7 +96,7 @@ func createAnimationDemo(session rui.Session) rui.View { params[rui.TimingFunction] = rui.StepsTiming(40) } - switch rui.GetDropDownCurrent(view, "animationIterationCount") { + switch rui.GetCurrent(view, "animationIterationCount") { case 0: params[rui.IterationCount] = 1 diff --git a/demo/backgroundDemo.go b/demo/backgroundDemo.go index 6010b07..476e92c 100644 --- a/demo/backgroundDemo.go +++ b/demo/backgroundDemo.go @@ -54,13 +54,13 @@ func createBackgroundDemo(session rui.Session) rui.View { updateBackground1 := func(list rui.DropDownList, number int) { images := []string{"cat.jpg", "winds.png", "gifsInEmail.gif", "mountain.svg"} image := rui.NewBackgroundImage(rui.Params{ - rui.Source: images[rui.GetDropDownCurrent(view, "backgroundImage1")], - rui.Fit: rui.GetDropDownCurrent(view, "backgroundFit1"), - rui.HorizontalAlign: rui.GetDropDownCurrent(view, "backgroundHAlign1"), - rui.VerticalAlign: rui.GetDropDownCurrent(view, "backgroundVAlign1"), - rui.Repeat: rui.GetDropDownCurrent(view, "backgroundRepeat1"), - rui.BackgroundClip: rui.GetDropDownCurrent(view, "backgroundClip1"), - rui.Attachment: rui.GetDropDownCurrent(view, "backgroundAttachment1"), + rui.Source: images[rui.GetCurrent(view, "backgroundImage1")], + rui.Fit: rui.GetCurrent(view, "backgroundFit1"), + rui.HorizontalAlign: rui.GetCurrent(view, "backgroundHAlign1"), + rui.VerticalAlign: rui.GetCurrent(view, "backgroundVAlign1"), + rui.Repeat: rui.GetCurrent(view, "backgroundRepeat1"), + rui.BackgroundClip: rui.GetCurrent(view, "backgroundClip1"), + rui.Attachment: rui.GetCurrent(view, "backgroundAttachment1"), }) rui.Set(view, "backgroundView", rui.Background, image) } diff --git a/demo/stackLayoutDemo.go b/demo/stackLayoutDemo.go index e05d7e1..4a51597 100644 --- a/demo/stackLayoutDemo.go +++ b/demo/stackLayoutDemo.go @@ -40,20 +40,20 @@ func createStackLayoutDemo(session rui.Session) rui.View { } animation := func() int { - return rui.GetDropDownCurrent(view, "pushAnimation") + return rui.GetCurrent(view, "pushAnimation") } /* transition := func() rui.ViewTransition { timing := rui.EaseTiming timings := []string{rui.EaseTiming, rui.LinearTiming} - if n := rui.GetDropDownCurrent(view, "pushTiming"); n >= 0 && n < len(timings) { + if n := rui.GetCurrent(view, "pushTiming"); n >= 0 && n < len(timings) { timing = timings[n] } duration := float64(0.5) durations := []float64{0.5, 1, 2} - if n := rui.GetDropDownCurrent(view, "pushDuration"); n >= 0 && n < len(durations) { + if n := rui.GetCurrent(view, "pushDuration"); n >= 0 && n < len(durations) { duration = durations[n] } diff --git a/demo/textStyle.go b/demo/textStyle.go index a6b2479..bdd25d5 100644 --- a/demo/textStyle.go +++ b/demo/textStyle.go @@ -59,7 +59,7 @@ func createTextStyleDemo(session rui.Session) rui.View { 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) { + if number := rui.GetCurrent(v, ""); number > 0 && number < len(fonts) { rui.Set(view, "textStyleText", rui.FontName, fonts[number]) } else { rui.Set(view, "textStyleText", rui.FontName, nil) diff --git a/dropDownList.go b/dropDownList.go index b3d84dc..8008226 100644 --- a/dropDownList.go +++ b/dropDownList.go @@ -61,7 +61,7 @@ func (list *dropDownListData) remove(tag string) { } case Current: - oldCurrent := GetDropDownCurrent(list, "") + oldCurrent := GetCurrent(list, "") delete(list.properties, Current) if oldCurrent != 0 { if list.created { @@ -89,12 +89,12 @@ func (list *dropDownListData) set(tag string, value interface{}) bool { return list.setDropDownListener(value) case Current: - oldCurrent := GetDropDownCurrent(list, "") + oldCurrent := GetCurrent(list, "") if !list.setIntProperty(Current, value) { return false } - if current := GetDropDownCurrent(list, ""); oldCurrent != current { + if current := GetCurrent(list, ""); oldCurrent != current { if list.created { list.session.runScript(fmt.Sprintf(`selectDropDownListItem('%s', %d)`, list.htmlID(), current)) } @@ -267,7 +267,7 @@ func (list *dropDownListData) htmlTag() string { func (list *dropDownListData) htmlSubviews(self View, buffer *strings.Builder) { if list.items != nil { - current := GetDropDownCurrent(list, "") + current := GetCurrent(list, "") notTranslate := GetNotTranslate(list, "") for i, item := range list.items { if i == current { @@ -309,7 +309,7 @@ func (list *dropDownListData) handleCommand(self View, command string, data Data case "itemSelected": if text, ok := data.PropertyValue("number"); ok { if number, err := strconv.Atoi(text); err == nil { - if GetDropDownCurrent(list, "") != number && number >= 0 && number < len(list.items) { + if GetCurrent(list, "") != number && number >= 0 && number < len(list.items) { list.properties[Current] = number list.onSelectedItemChanged(number) } @@ -345,15 +345,3 @@ func GetDropDownItems(view View, subviewID string) []string { } return []string{} } - -// func GetDropDownCurrentItem return the number of the selected item -func GetDropDownCurrent(view View, subviewID string) int { - if subviewID != "" { - view = ViewByID(view, subviewID) - } - if view != nil { - result, _ := intProperty(view, Current, view.Session(), 0) - return result - } - return 0 -} diff --git a/listView.go b/listView.go index 44b2f6c..4353526 100644 --- a/listView.go +++ b/listView.go @@ -141,7 +141,7 @@ func (listView *listViewData) remove(tag string) { } case Current: - current := GetListViewCurrent(listView, "") + current := GetCurrent(listView, "") delete(listView.properties, tag) if listView.created { updateInnerHTML(listView.htmlID(), listView.session) @@ -235,11 +235,11 @@ func (listView *listViewData) set(tag string, value interface{}) bool { } case Current: - oldCurrent := GetListViewCurrent(listView, "") + oldCurrent := GetCurrent(listView, "") if !listView.setIntProperty(Current, value) { return false } - current := GetListViewCurrent(listView, "") + current := GetCurrent(listView, "") if oldCurrent == current { return true } @@ -791,7 +791,7 @@ func (listView *listViewData) checkboxSubviews(self View, buffer *strings.Builde itemDiv := listView.checkboxItemDiv(self, checkbox, hCheckboxAlign, vCheckboxAlign) onDiv, offDiv, contentDiv := listView.getDivs(self, checkbox, hCheckboxAlign, vCheckboxAlign) - current := GetListViewCurrent(listView, "") + current := GetCurrent(listView, "") checkedItems := GetListViewCheckedItems(listView, "") for i := 0; i < count; i++ { buffer.WriteString(`
= 0 && current < listView.adapter.ListSize() { buffer.WriteString(` data-current="`) buffer.WriteString(listView.htmlID()) @@ -1113,7 +1113,7 @@ func (listView *listViewData) handleCommand(self View, command string, data Data } func (listView *listViewData) onItemClick() { - current := GetListViewCurrent(listView, "") + current := GetCurrent(listView, "") if current >= 0 && !IsDisabled(listView, "") { checkbox := GetListViewCheckbox(listView, "") m: @@ -1235,20 +1235,6 @@ func GetListItemCheckedListeners(view View, subviewID string) []func(ListView, [ return []func(ListView, []int){} } -// GetListViewCurrent returns the index of the ListView selected item or <0 if there is no a selected item. -// If the second argument (subviewID) is "" then a value from the first argument (view) is returned. -func GetListViewCurrent(view View, subviewID string) int { - if subviewID != "" { - view = ViewByID(view, subviewID) - } - if view != nil { - if result, ok := intProperty(view, Current, view.Session(), -1); ok { - return result - } - } - return -1 -} - // GetListItemWidth returns the width of a ListView item. // If the second argument (subviewID) is "" then a value from the first argument (view) is returned. func GetListItemWidth(view View, subviewID string) SizeUnit { diff --git a/tabsLayout.go b/tabsLayout.go index 68e9f1f..af8ab94 100644 --- a/tabsLayout.go +++ b/tabsLayout.go @@ -50,27 +50,10 @@ const ( type TabsLayout interface { ViewsContainer ListAdapter - /* - // Current return the index of active tab - currentItem() int - // SetCurrent set the index of active tab - SetCurrent(current int) - // TabsLocation return the location of tabs. It returns one of the following values: HiddenTabs (0), - // TopTabs (1), BottomTabs (2), LeftTabs (3), RightTabs (4), LeftListTabs (5), RightListTabs (6) - tabsLocation() int - // TabsLocation set the location of tabs. Valid values: HiddenTabs (0), TopTabs (1), - // BottomTabs (2), LeftTabs (3), RightTabs (4), LeftListTabs (5), RightListTabs (6) - SetTabsLocation(location int) - // TabStyle() return styles of tab in the passive and the active state - TabStyle() (string, string) - SetTabStyle(tabStyle string, activeTabStyle string) - */ } type tabsLayoutData struct { viewsContainerData - //currentTab, tabsLocation int - //tabStyle, activeTabStyle string tabListener []func(TabsLayout, int, int) tabCloseListener []func(TabsLayout, int) } diff --git a/viewUtils.go b/viewUtils.go index e877b18..b7e9e17 100644 --- a/viewUtils.go +++ b/viewUtils.go @@ -1045,3 +1045,27 @@ func FocusViewByID(viewID string, session Session) { session.runScript("focus('" + viewID + "')") } } + +// GetCurrent returns the index of the selected item (<0 if there is no a selected item) or the current view index (StackLayout, TabsLayout). +// If the second argument (subviewID) is "" then a value from the first argument (view) is returned. +func GetCurrent(view View, subviewID string) int { + if subviewID != "" { + view = ViewByID(view, subviewID) + } + + var defaultValue int + switch view.Tag() { + case "ListView": + defaultValue = -1 + + default: + defaultValue = 0 + } + + if view != nil { + if result, ok := intProperty(view, Current, view.Session(), defaultValue); ok { + return result + } + } + return -1 +}