Added ViewCreateListener interface

This commit is contained in:
Alexei Anoshenko 2025-06-25 13:53:08 +03:00
parent 2dd8d8d256
commit b0185726db
4 changed files with 69 additions and 38 deletions

View File

@ -161,8 +161,8 @@ SizeUnit объявлена как
| "sub(<arg1>, <arg2>)" | SubSize(arg0, arg1 any) | находит разность значений аргументов |
| "mul(<arg1>, <arg2>)" | MulSize(arg0, arg1 any) | находит результат умножения значений аргументов |
| "div(<arg1>, <arg2>)" | DivSize(arg0, arg1 any) | находит результат деления значений аргументов |
| "rem(<arg1>, <arg2>)" | ModSize(arg0, arg1 any) | находит остаток деления значений аргументов, результат имеет тотже знак что и делимое |
| "mod(<arg1>, <arg2>)" | ModSize(arg0, arg1 any) | находит остаток деления значений аргументов, результат имеет тотже знак что и делитель |
| "rem(<arg1>, <arg2>)" | ModSize(arg0, arg1 any) | находит остаток деления значений аргументов, результат имеет тот же знак что и делимое |
| "mod(<arg1>, <arg2>)" | ModSize(arg0, arg1 any) | находит остаток деления значений аргументов, результат имеет тот же знак что и делитель |
| "round(<arg1>, <arg2>)" | RoundSize(arg0, arg1 any) | округляет первый аргумент до ближайшего целого числа кратного второму аргументу |
| "round-up(<arg1>, <arg2>)" | RoundUpSize(arg0, arg1 any) | округляет первый аргумент до ближайшего большего целого числа, кратного второму аргументу |
| "round-down(<arg1>, <arg2>)" | RoundDownSize(arg0, arg1 any) | округляет первый аргумент до ближайшего меньшего целого числа кратного второму аргументу |
@ -1086,7 +1086,7 @@ RadiusProperty, а не структура BoxRadius. Получить стру
Получить значение данного свойства можно с помощью функции
func GetShadowPropertys(view View, subviewID ...string) []ShadowProperty
func GetShadowProperties(view View, subviewID ...string) []ShadowProperty
Если тень не задана, то данная функция вернет пустой массив
@ -2291,14 +2291,14 @@ radius необходимо передать nil
#### Свойство "drag-data"
Для того чтобы сделать View перетаскиваемым ему неоходимо задать свойство "drag-data" (константа DragData).
Для того чтобы сделать View перетаскиваемым ему необходимо задать свойство "drag-data" (константа DragData).
Данное свойство задает множество перетаскиваемых данных в виде ключ:значение и имеет тип:
map[string]string
В качестве ключей рекомендуется использовать mime-тип значения.
Например, если в перетаскиваемыми данными асляется текст, то ключем должен быть "text/plain", если jpeg-изображение, то "image/jpg" и т.п.
Но это только рекомендация, ключем может быть любой текст.
Например, если в перетаскиваемыми данными является текст, то ключом должен быть "text/plain", если jpeg-изображение, то "image/jpg" и т.п.
Но это только рекомендация, ключом может быть любой текст.
Пример
@ -2318,7 +2318,7 @@ radius необходимо передать nil
По умолчанию при перетаскивании перемещается весь View. Часто это бывает не удобно, например если View очень большой.
Свойство "drag-image" (константа DragImage) типа string позволяет задать картинку, которая будет отображаться вместо View при перетаскивании.
В качестве значения "drag-image" задаеться:
В качестве значения "drag-image" задается:
* Имя изображения в ресурсах приложения
* Константа изображения
* URL изображения
@ -2442,15 +2442,15 @@ radius необходимо передать nil
#### События "drag-enter-event", "drag-leave-event" и "drag-over-event"
События "drag-enter-event", "drag-leave-event" и "drag-over-event" генерируются только для View приемника перетескиваемого объекта.
События "drag-enter-event", "drag-leave-event" и "drag-over-event" генерируются только для View приемника перетаскиваемого объекта.
Событие "drag-enter-event" генерируется когда перетаскиваемый оъект входит в область View приемника.
Событие "drag-enter-event" генерируется когда перетаскиваемый объект входит в область View приемника.
Событие "drag-leave-event" генерируется когда перетаскиваемый оъект покидает область View приемника.
Событие "drag-leave-event" генерируется когда перетаскиваемый объект покидает область View приемника.
Событие "drag-over-event" генерируется c определенным интервалом (несколько раз в секунду) пока перетаскиваемый оъект находится область View приемника.
Событие "drag-over-event" генерируется c определенным интервалом (несколько раз в секунду) пока перетаскиваемый объект находится область View приемника.
Пример, меняем цвет рамки с серой на красную когда перетаскиваемый оъект находится над областью приемника
Пример, меняем цвет рамки с серой на красную когда перетаскиваемый объект находится над областью приемника
view.SetParams(rui.Params{
rui.DragEnterEvent: func(view rui.View, event rui.DragAndDropEvent)) {
@ -3834,7 +3834,7 @@ float32, float64, int, int8…int64, uint, uint8…uint64.
Между пунктами списка можно добавлять разделителями. Для этого используется свойство "item-separators" (константа ItemSeparators).
Данному свойству присваивается массив индексов пунктов после которых необходимо добавить разделители.
Свойству "item-separators" могут присваиваться теже типы данных что и свойству "disabled-items".
Свойству "item-separators" могут присваиваться те же типы данных что и свойству "disabled-items".
Прочитать значение свойства "item-separators" можно с помощью функции
func GetDropDownItemSeparators(view View, subviewID ...string) []int
@ -4085,7 +4085,7 @@ int свойство "current" (константа Current). Значение "c
с помощью int свойств "checkbox-horizontal-align" и "checkbox-vertical-align" (константы
CheckboxHorizontalAlign и CheckboxVerticalAlign)
Свойство "checkbox-horizontal-align" (константа СheckboxHorizontalAlign) может принимать следующие значения:
Свойство "checkbox-horizontal-align" (константа CheckboxHorizontalAlign) может принимать следующие значения:
| Значение | Константа | Имя | Расположение чекбокса |
|:--------:|--------------|----------|-------------------------------------------------|
@ -4647,7 +4647,7 @@ rotation - угол поворота эллипса относительно ц
Метод NewPath() создает пустую фигуру. Далее вы должны описать фигуру используя методы интерфейса Path
Метод NewPathFromSvg(data string) Path создает фигуру описанную в параметре data.
Параметр data является описанием фигуры в формате елемента <path> svg изображения. Например
Параметр data является описанием фигуры в формате элемента <path> svg изображения. Например
path := canvas.NewPathFromSvg("M 30,0 C 30,0 27,8.6486 17,21.622 7,34.595 0,40 0,40 0,40 6,44.3243 17,58.378 28,72.432 30,80 30,80 30,80 37.8387,65.074 43,58.378 53,45.405 60,40 60,40 60,40 53,34.5946 43,21.622 33,8.649 30,0 30,0 Z")
@ -4827,7 +4827,7 @@ AudioPlayer и VideoPlayer это элементы которые предназ
### Свойство "src"
Свойство "src" (константа Source) задает один или несколько источников медиафайлов. Свойство "src" может принимать
Свойство "src" (константа Source) задает один или несколько источников медиа файлов. Свойство "src" может принимать
значение следующих типов:
* string,
@ -4872,7 +4872,7 @@ AudioPlayer и VideoPlayer это элементы которые предназ
|:--------:|-----------------|------------|----------------------------------------------------------------------------------------|
| 0 | PreloadNone | "none" | Медиа файл не должен быть предварительно загружен |
| 1 | PreloadMetadata | "metadata" | Предварительно загружаются только метаданные |
| 2 | PreloadAuto | "auto" | Весь медиафайл может быть загружен, даже если пользователь не должен его использовать. |
| 2 | PreloadAuto | "auto" | Весь медиа файл может быть загружен, даже если пользователь не должен его использовать.|
Значение по умолчанию PreloadAuto (2)
@ -5723,9 +5723,11 @@ Safari и Firefox.
}
func createButton(session rui.Session) rui.View {
b := new(button)
b.view = rui.CreateViewFromResources(session, "button.rui", b)
return b.view
return rui.CreateViewFromResources(session, "button.rui", new(button))
}
func (button *button) OnCreate(view rui.View) {
button.view = view
}
func (button *button) ButtonClick() {
@ -5733,7 +5735,7 @@ Safari и Firefox.
}
В данном примере в файле ресурсов указано, что в качестве обработчика клика надо использовать функцию с именем "ButtonClick".
При создании View из ресeрсов с помощью функции CreateViewFromResources в качестве третьего параметра задается объект связывания.
При создании View из ресурсов с помощью функции CreateViewFromResources в качестве третьего параметра задается объект связывания.
При возникновении события "click-event" система будет искать в связанном объекте один из следующих методов
ButtonClick()
@ -5743,7 +5745,14 @@ Safari и Firefox.
Система найдет метод ButtonClick() и вызовет его.
Теперь рассотрим как добавить отслеживание изменения свойств.
Также для связанного объекта может задаваться опциональный метод
OnCreate(view rui.View)
Данный метод вызывается функциями CreateViewFromText, CreateViewFromResources и CreateViewFromObject после создания View.
В данном примере этот метод используется для сохранения указателя на созданный View.
Теперь рассмотрим как добавить отслеживание изменения свойств.
Для этого добавим в пример слушателя изменения свойства "background-color" в свойство "change-listeners"
Button {

View File

@ -2135,7 +2135,7 @@ You can get lists of pointer event listeners using the functions:
### Touch events
These events are used to track multipoint touches. Single touches emulate mouse events.
These events are used to track multi point touches. Single touches emulate mouse events.
If you do not need to track multi-point touches, then it is easier to use mouse events
| Event | Constant | Description |
@ -5726,22 +5726,24 @@ The binding mechanism is designed to set event handlers and listeners for change
Let's look at an example:
Resource file ("button.rui") describing the button
The resource file ("button.rui") describing the button:
Button {
click-event = ButtonClick,
}
Code to create this button from resources
The code to create this button from resources
type button struct {
view rui.View
}
func createButton(session rui.Session) rui.View {
b := new(button)
b.view = rui.CreateViewFromResources(session, "button.rui", b)
return b.view
return rui.CreateViewFromResources(session, "button.rui", new(button))
}
func (button *button) OnCreate(view rui.View) {
button.view = view
}
func (button *button) ButtonClick() {
@ -5759,6 +5761,13 @@ When a "click-event" occurs, the system will look for one of the following metho
The system will find the ButtonClick() method and call it.
The optional method OnCreate can also be specified for the associated object
OnCreate(view rui.View)
This method is called by the CreateViewFromText, CreateViewFromResources, and CreateViewFromObject functions after the View has been created.
In this example, this method is used to save a pointer to the created View.
Now let's look at how to add property change tracking.
To do this, let's add a property change listener "background-color" to the property "change-listeners" in the example.

View File

@ -151,7 +151,7 @@ const (
//
// Used by Popup.
// Specify start translation, scale and rotation over x, y and z axes as well as a distortion
// for an animated Popup showing/hidding.
// for an animated Popup showing/hiding.
//
// Supported types: TransformProperty, string.
//
@ -279,7 +279,7 @@ type Popup interface {
viewByHTMLID(id string) View
keyEvent(event KeyEvent) bool
showAnimation()
dissmissAnimation(listener func(PropertyName)) bool
dismissAnimation(listener func(PropertyName)) bool
}
type popupListener interface {
@ -849,7 +849,7 @@ func (popup *popupData) showAnimation() {
}
}
func (popup *popupData) dissmissAnimation(listener func(PropertyName)) bool {
func (popup *popupData) dismissAnimation(listener func(PropertyName)) bool {
if popup.showOpacity != 1 || popup.showTransform != nil {
session := popup.Session()
popup.popupView.Set(TransitionEndEvent, listener)
@ -1012,23 +1012,26 @@ func (manager *popupManager) dismissPopup(popup Popup) {
session := popup.Session()
listener := func(PropertyName) {
if index == count-1 {
switch index {
case 0:
if count == 1 {
manager.popups = []Popup{}
session.updateCSSProperty("ruiRoot", "pointer-events", "auto")
session.updateCSSProperty("ruiPopupLayer", "visibility", "hidden")
} else {
manager.popups = manager.popups[:count-1]
manager.popups = manager.popups[1:]
}
} else if index == 0 {
manager.popups = manager.popups[1:]
} else {
case count - 1:
manager.popups = manager.popups[:count-1]
default:
manager.popups = append(manager.popups[:index], manager.popups[index+1:]...)
}
popup.onDismiss()
}
if !popup.dissmissAnimation(listener) {
if !popup.dismissAnimation(listener) {
listener("")
}
}

View File

@ -36,6 +36,13 @@ var systemViewCreators = map[string]func(Session) View{
"VideoPlayer": newVideoPlayer,
}
// ViewCreateListener is the listener interface of a view create event
type ViewCreateListener interface {
// OnCreate is a function of binding object that is called by the CreateViewFromText, CreateViewFromResources,
// and CreateViewFromObject functions after the creation of a view
OnCreate(view View)
}
var viewCreate map[string]func(Session) View = nil
func viewCreators() map[string]func(Session) View {
@ -64,7 +71,7 @@ func RegisterViewCreator(tag string, creator func(Session) View) bool {
// CreateViewFromObject create new View and initialize it by DataObject data. Parameters:
// - session - the session to which the view will be attached (should not be nil);
// - object - datas describing View;
// - object - data describing View;
// - binding - object assigned to the Binding property (may be nil).
//
// If the function fails, it returns nil and an error message is written to the log.
@ -96,6 +103,9 @@ func CreateViewFromObject(session Session, object DataObject, binding any) View
parseProperties(view, object)
if binding != nil {
view.setRaw(Binding, binding)
if listener, ok := binding.(ViewCreateListener); ok {
listener.OnCreate(view)
}
}
return view
}