From c31b2f9d8cf0aeeacf978861faf40a8f71c9d62e Mon Sep 17 00:00:00 2001 From: anoshenko Date: Sun, 18 Dec 2022 18:22:58 +0300 Subject: [PATCH 1/9] PropertyWithTag method of DataObject renamed to PropertyByTag --- app_scripts.js | 42 ++++++++++++++++++++++++++++++++++++++---- border.go | 2 +- data.go | 8 ++++---- filePicker.go | 2 +- session.go | 38 +++++++++++++++++++++++++++++++++++++- touchEvents.go | 2 +- 6 files changed, 82 insertions(+), 12 deletions(-) diff --git a/app_scripts.js b/app_scripts.js index 1162fae..a9ff7a7 100644 --- a/app_scripts.js +++ b/app_scripts.js @@ -52,6 +52,24 @@ function sessionInfo() { message += ",pixel-ratio=" + pixelRatio; } + if (localStorage.length > 0) { + message += ",storage=" + lead = "_{" + for (var i = 0; i < localStorage.length; i++) { + var key = localStorage.key(i) + var value = localStorage.getItem(key) + key = key.replaceAll(/\\/g, "\\\\") + key = key.replaceAll(/\"/g, "\\\"") + key = key.replaceAll(/\'/g, "\\\'") + value = value.replaceAll(/\\/g, "\\\\") + value = value.replaceAll(/\"/g, "\\\"") + value = value.replaceAll(/\'/g, "\\\'") + message += lead + "\"" + key + "\"=\"" + value + "\"" + lead = "," + } + message += "}" + } + return message + "}"; } @@ -940,8 +958,8 @@ function radioButtonKeyClickEvent(element, event) { function editViewInputEvent(element) { var text = element.value - text = text.replace(/\\/g, "\\\\") - text = text.replace(/\"/g, "\\\"") + text = text.replaceAll(/\\/g, "\\\\") + text = text.replaceAll(/\"/g, "\\\"") var message = "textChanged{session=" + sessionID + ",id=" + element.id + ",text=\"" + text + "\"}" sendMessage(message); } @@ -1147,7 +1165,7 @@ function loadImage(url) { img.addEventListener("error", function(event) { var message = "imageError{session=" + sessionID + ",url=\"" + url + "\""; if (event && event.message) { - var text = event.message.replace(new RegExp("\"", 'g'), "\\\"") + var text = event.message.replaceAll(new RegExp("\"", 'g'), "\\\"") message += ",message=\"" + text + "\""; } sendMessage(message + "}") @@ -1178,7 +1196,7 @@ function loadInlineImage(url, content) { img.addEventListener("error", function(event) { var message = "imageError{session=" + sessionID + ",url=\"" + url + "\""; if (event && event.message) { - var text = event.message.replace(new RegExp("\"", 'g'), "\\\"") + var text = event.message.replaceAll(new RegExp("\"", 'g'), "\\\"") message += ",message=\"" + text + "\""; } sendMessage(message + "}") @@ -1842,3 +1860,19 @@ function getCanvasContext(elementId) { } return null; } + +function localStorageSet(key, value) { + try { + localStorage.setItem(key, value) + } catch (err) { + sendMessage("storageError{session=" + sessionID + ", error=`" + err + "`}") + } +} + +function localStorageClear() { + try { + localStorage.setItem(key, value) + } catch (err) { + sendMessage("storageError{session=" + sessionID + ", error=`" + err + "`}") + } +} diff --git a/border.go b/border.go index 97a62f9..209ec9e 100644 --- a/border.go +++ b/border.go @@ -286,7 +286,7 @@ func (border *borderProperty) setBorderObject(obj DataObject) bool { result := true for _, side := range []string{Top, Right, Bottom, Left} { - if node := obj.PropertyWithTag(side); node != nil { + if node := obj.PropertyByTag(side); node != nil { if node.Type() == ObjectNode { if !border.setSingleBorderObject(side, node.Object()) { result = false diff --git a/data.go b/data.go index 0f26698..4e51271 100644 --- a/data.go +++ b/data.go @@ -18,7 +18,7 @@ type DataObject interface { Tag() string PropertyCount() int Property(index int) DataNode - PropertyWithTag(tag string) DataNode + PropertyByTag(tag string) DataNode PropertyValue(tag string) (string, bool) PropertyObject(tag string) DataObject SetPropertyValue(tag, value string) @@ -106,7 +106,7 @@ func (object *dataObject) Property(index int) DataNode { return object.property[index] } -func (object *dataObject) PropertyWithTag(tag string) DataNode { +func (object *dataObject) PropertyByTag(tag string) DataNode { if object.property != nil { for _, node := range object.property { if node.Tag() == tag { @@ -118,14 +118,14 @@ func (object *dataObject) PropertyWithTag(tag string) DataNode { } func (object *dataObject) PropertyValue(tag string) (string, bool) { - if node := object.PropertyWithTag(tag); node != nil && node.Type() == TextNode { + if node := object.PropertyByTag(tag); node != nil && node.Type() == TextNode { return node.Text(), true } return "", false } func (object *dataObject) PropertyObject(tag string) DataObject { - if node := object.PropertyWithTag(tag); node != nil && node.Type() == ObjectNode { + if node := object.PropertyByTag(tag); node != nil && node.Type() == ObjectNode { return node.Object() } return nil diff --git a/filePicker.go b/filePicker.go index 3e236f7..8081aab 100644 --- a/filePicker.go +++ b/filePicker.go @@ -270,7 +270,7 @@ func (picker *filePickerData) htmlDisabledProperties(self View, buffer *strings. func (picker *filePickerData) handleCommand(self View, command string, data DataObject) bool { switch command { case "fileSelected": - if node := data.PropertyWithTag("files"); node != nil && node.Type() == ArrayNode { + if node := data.PropertyByTag("files"); node != nil && node.Type() == ArrayNode { count := node.ArraySize() files := make([]FileInfo, count) for i := 0; i < count; i++ { diff --git a/session.go b/session.go index 41ea863..33cfd37 100644 --- a/session.go +++ b/session.go @@ -100,6 +100,10 @@ type Session interface { // OpenURL opens the url in the new browser tab OpenURL(url string) + ClientItem(key string) (string, bool) + SetClientItem(key, value string) + RemoveAllClientItems() + getCurrentTheme() Theme registerAnimation(props []AnimatedProperty) string @@ -183,6 +187,7 @@ type sessionData struct { animationCounter int animationCSS string updateScripts map[string]*strings.Builder + clientStorage map[string]string } func newSession(app Application, id int, customTheme string, params DataObject) Session { @@ -199,6 +204,7 @@ func newSession(app Application, id int, customTheme string, params DataObject) session.animationCounter = 0 session.animationCSS = "" session.updateScripts = map[string]*strings.Builder{} + session.clientStorage = map[string]string{} if customTheme != "" { if theme, ok := CreateThemeFromText(customTheme); ok { @@ -516,7 +522,7 @@ func (session *sessionData) handleRootSize(data DataObject) { } func (session *sessionData) handleResize(data DataObject) { - if node := data.PropertyWithTag("views"); node != nil && node.Type() == ArrayNode { + if node := data.PropertyByTag("views"); node != nil && node.Type() == ArrayNode { for _, el := range node.ArrayElements() { if el.IsObject() { obj := el.Object() @@ -591,6 +597,16 @@ func (session *sessionData) handleSessionInfo(params DataObject) { session.pixelRatio = f } } + + if node := params.PropertyByTag("storage"); node != nil && node.Type() == ObjectNode { + if obj := node.Object(); obj != nil { + for i := 0; i < obj.PropertyCount(); i++ { + if element := obj.Property(i); element.Type() == TextNode { + session.clientStorage[element.Tag()] = element.Text() + } + } + } + } } func (session *sessionData) handleEvent(command string, data DataObject) { @@ -610,6 +626,11 @@ func (session *sessionData) handleEvent(command string, data DataObject) { case "sessionInfo": session.handleSessionInfo(data) + case "storageError": + if text, ok := data.PropertyValue("error"); ok { + ErrorLog(text) + } + default: if viewID, ok := data.PropertyValue("id"); ok { if view := session.viewByHTMLID(viewID); view != nil { @@ -641,3 +662,18 @@ func (session *sessionData) OpenURL(urlStr string) { } session.callFunc("openURL", urlStr) } + +func (session *sessionData) ClientItem(key string) (string, bool) { + value, ok := session.clientStorage[key] + return value, ok +} + +func (session *sessionData) SetClientItem(key, value string) { + session.clientStorage[key] = value + session.bridge.callFunc("localStorageSet", key, value) +} + +func (session *sessionData) RemoveAllClientItems() { + session.clientStorage = map[string]string{} + session.bridge.callFunc("localStorageClear") +} diff --git a/touchEvents.go b/touchEvents.go index 7c2be24..8a4e92f 100644 --- a/touchEvents.go +++ b/touchEvents.go @@ -140,7 +140,7 @@ func (event *TouchEvent) init(data DataObject) { event.Touches = []Touch{} event.TimeStamp = getTimeStamp(data) - if node := data.PropertyWithTag("touches"); node != nil && node.Type() == ArrayNode { + if node := data.PropertyByTag("touches"); node != nil && node.Type() == ArrayNode { for i := 0; i < node.ArraySize(); i++ { if element := node.ArrayElement(i); element != nil && element.IsObject() { if obj := element.Object(); obj != nil { From 9fe570ec22fa48143ddfdea001c831ffe63be817 Mon Sep 17 00:00:00 2001 From: anoshenko Date: Sun, 18 Dec 2022 18:37:36 +0300 Subject: [PATCH 2/9] Added "order" property --- propertyNames.go | 5 +++++ propertySet.go | 1 + view.go | 2 +- viewStyle.go | 16 ++++++++-------- viewUtils.go | 6 ++++++ 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/propertyNames.go b/propertyNames.go index 2601fb7..df26607 100644 --- a/propertyNames.go +++ b/propertyNames.go @@ -669,4 +669,9 @@ const ( // The "user-select" bool property controls whether the user can select text. // This is an inherited property, i.e. if it is not defined, then the value of the parent view is used. UserSelect = "user-select" + + // Order is the constant for the "Order" property tag. + // The "Order" int property sets the order to layout an item in a ListLayout or GridLayout container. + // Items in a container are sorted by ascending order value and then by their source code order. + Order = "Order" ) diff --git a/propertySet.go b/propertySet.go index 34ead12..ab62187 100644 --- a/propertySet.go +++ b/propertySet.go @@ -73,6 +73,7 @@ var intProperties = []string{ RowSpan, ColumnSpan, ColumnCount, + Order, } var floatProperties = map[string]struct{ min, max float64 }{ diff --git a/view.go b/view.go index b81dae3..f7a62eb 100644 --- a/view.go +++ b/view.go @@ -577,7 +577,7 @@ func viewPropertyChanged(view *viewData, tag string) { } return - case ZIndex, TabSize: + case ZIndex, Order, TabSize: if i, ok := intProperty(view, tag, session, 0); ok { session.updateCSSProperty(htmlID, tag, strconv.Itoa(i)) } diff --git a/viewStyle.go b/viewStyle.go index 1abd273..1c505b6 100644 --- a/viewStyle.go +++ b/viewStyle.go @@ -193,16 +193,20 @@ func (style *viewStyle) cssViewStyle(builder cssBuilder, session Session) { outline.ViewOutline(session).cssValue(builder, session) } - if z, ok := intProperty(style, ZIndex, session, 0); ok { - builder.add(ZIndex, strconv.Itoa(z)) + for _, tag := range []string{ZIndex, Order} { + if value, ok := intProperty(style, tag, session, 0); ok { + builder.add(tag, strconv.Itoa(value)) + } } if opacity, ok := floatProperty(style, Opacity, session, 1.0); ok && opacity >= 0 && opacity <= 1 { builder.add(Opacity, strconv.FormatFloat(opacity, 'f', 3, 32)) } - if n, ok := intProperty(style, ColumnCount, session, 0); ok && n > 0 { - builder.add(ColumnCount, strconv.Itoa(n)) + for _, tag := range []string{ColumnCount, TabSize} { + if value, ok := intProperty(style, tag, session, 0); ok && value > 0 { + builder.add(tag, strconv.Itoa(value)) + } } for _, tag := range []string{ @@ -279,10 +283,6 @@ func (style *viewStyle) cssViewStyle(builder cssBuilder, session Session) { } } - if tabSize, ok := intProperty(style, TabSize, session, 8); ok && tabSize > 0 { - builder.add(TabSize, strconv.Itoa(tabSize)) - } - if text := style.cssTextDecoration(session); text != "" { builder.add("text-decoration", text) } diff --git a/viewUtils.go b/viewUtils.go index fd4765d..5e89dbe 100644 --- a/viewUtils.go +++ b/viewUtils.go @@ -159,6 +159,12 @@ func GetZIndex(view View, subviewID ...string) int { return intStyledProperty(view, subviewID, ZIndex, 0) } +// GetOrder returns the subview order to layout an item in a ListLayout or GridLayout container. +// If the second argument (subviewID) is not specified or it is "" then an order of the first argument (view) is returned +func GetOrder(view View, subviewID ...string) int { + return intStyledProperty(view, subviewID, Order, 0) +} + // GetWidth returns the subview width. // If the second argument (subviewID) is not specified or it is "" then a width of the first argument (view) is returned func GetWidth(view View, subviewID ...string) SizeUnit { From e5842180efe1cb4fa6075748c1cc6c895e8c3eae Mon Sep 17 00:00:00 2001 From: anoshenko Date: Mon, 19 Dec 2022 18:31:35 +0300 Subject: [PATCH 3/9] Added mix-blend-mode and background-blend-mode --- CHANGELOG.md | 7 ++++ propertyNames.go | 16 ++++++++++ propertySet.go | 10 ++++++ propertyValues.go | 81 +++++++++++++++++++++++++++++++++++++++++++++++ viewStyle.go | 2 +- viewUtils.go | 24 ++++++++++++++ 6 files changed, 139 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ad372a..c55347e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v.11.0 + +* Added "order", "background-blend-mode", and "mix-blend-mode" properties +* Added GetOrder, GetBackgroundBlendMode, and GetMixBlendMode functions +* ClientItem, SetClientItem, and RemoveAllClientItems method added to Session interface +* PropertyWithTag method of DataObject interface renamed to PropertyByTag + # v.10.0 * The Canvas.TextWidth method replaced by Canvas.TextMetrics diff --git a/propertyNames.go b/propertyNames.go index df26607..318eeaf 100644 --- a/propertyNames.go +++ b/propertyNames.go @@ -674,4 +674,20 @@ const ( // The "Order" int property sets the order to layout an item in a ListLayout or GridLayout container. // Items in a container are sorted by ascending order value and then by their source code order. Order = "Order" + + // BackgroundBlendMode is the constant for the "background-blend-mode" property tag. + // The "background-blend-mode" int property sets how an element's background images should blend + // with each other and with the element's background color. + // Valid values are "normal" (0), "multiply" (1), "screen" (2), "overlay" (3), "darken" (4), "lighten" (5), + // "color-dodge" (6), "color-burn" (7), "hard-light" (8), "soft-light" (9), "difference" (10), + // "exclusion" (11), "hue" (12), "saturation" (13), "color" (14), "luminosity" (15). + BackgroundBlendMode = "background-blend-mode" + + // MixBlendMode is the constant for the "mix-blend-mode" property tag. + // The "mix-blend-mode" int property sets how a view's content should blend + // with the content of the view's parent and the view's background. + // Valid values are "normal" (0), "multiply" (1), "screen" (2), "overlay" (3), "darken" (4), "lighten" (5), + // "color-dodge" (6), "color-burn" (7), "hard-light" (8), "soft-light" (9), "difference" (10), + // "exclusion" (11), "hue" (12), "saturation" (13), "color" (14), "luminosity" (15). + MixBlendMode = "mix-blend-mode" ) diff --git a/propertySet.go b/propertySet.go index ab62187..8d8a775 100644 --- a/propertySet.go +++ b/propertySet.go @@ -448,6 +448,16 @@ var enumProperties = map[string]struct { "", []string{"none", "top", "right", "bottom", "left"}, }, + MixBlendMode: { + []string{"normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity"}, + MixBlendMode, + []string{"normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity"}, + }, + BackgroundBlendMode: { + []string{"normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity"}, + BackgroundBlendMode, + []string{"normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity"}, + }, } func notCompatibleType(tag string, value any) { diff --git a/propertyValues.go b/propertyValues.go index 27e630b..d262463 100644 --- a/propertyValues.go +++ b/propertyValues.go @@ -307,4 +307,85 @@ const ( // "dense" packing algorithm attempts to fill in holes earlier in the grid, if smaller items come up later. // This may cause views to appear out-of-order, when doing so would fill in holes left by larger views. ColumnDenseAutoFlow = 3 + + // BlendNormal - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color is the top color, regardless of what the bottom color is. + // The effect is like two opaque pieces of paper overlapping. + BlendNormal = 0 + + // BlendMultiply - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color is the result of multiplying the top and bottom colors. + // A black layer leads to a black final layer, and a white layer leads to no change. + // The effect is like two images printed on transparent film overlapping. + BlendMultiply = 1 + + // BlendScreen - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color is the result of inverting the colors, multiplying them, and inverting that value. + // A black layer leads to no change, and a white layer leads to a white final layer. + // The effect is like two images shone onto a projection screen. + BlendScreen = 2 + + // BlendOverlay - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color is the result of multiply if the bottom color is darker, or screen if the bottom color is lighter. + // This blend mode is equivalent to hard-light but with the layers swapped. + BlendOverlay = 3 + + // BlendDarken - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color is composed of the darkest values of each color channel. + BlendDarken = 4 + + // BlendLighten - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color is composed of the lightest values of each color channel. + BlendLighten = 5 + + // BlendColorDodge - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color is the result of dividing the bottom color by the inverse of the top color. + // A black foreground leads to no change. A foreground with the inverse color of the backdrop leads to a fully lit color. + // This blend mode is similar to screen, but the foreground need only be as light as the inverse of the backdrop to create a fully lit color. + BlendColorDodge = 6 + + // BlendColorBurn - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color is the result of inverting the bottom color, dividing the value by the top color, and inverting that value. + // A white foreground leads to no change. A foreground with the inverse color of the backdrop leads to a black final image. + // This blend mode is similar to multiply, but the foreground need only be as dark as the inverse of the backdrop to make the final image black. + BlendColorBurn = 7 + + // BlendHardLight - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color is the result of multiply if the top color is darker, or screen if the top color is lighter. + // This blend mode is equivalent to overlay but with the layers swapped. The effect is similar to shining a harsh spotlight on the backdrop. + BlendHardLight = 8 + + // BlendSoftLight - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color is similar to hard-light, but softer. This blend mode behaves similar to hard-light. + // The effect is similar to shining a diffused spotlight on the backdrop*.* + BlendSoftLight = 9 + + // BlendDifference - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color is the result of subtracting the darker of the two colors from the lighter one. + // A black layer has no effect, while a white layer inverts the other layer's color. + BlendDifference = 10 + + // BlendExclusion - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color is similar to difference, but with less contrast. + // As with difference, a black layer has no effect, while a white layer inverts the other layer's color. + BlendExclusion = 11 + + // BlendHue - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color has the hue of the top color, while using the saturation and luminosity of the bottom color. + BlendHue = 12 + + // BlendSaturation - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color has the saturation of the top color, while using the hue and luminosity of the bottom color. + // A pure gray backdrop, having no saturation, will have no effect. + BlendSaturation = 13 + + // BlendColor - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color has the hue and saturation of the top color, while using the luminosity of the bottom color. + // The effect preserves gray levels and can be used to colorize the foreground. + BlendColor = 14 + + // BlendLuminosity - value of the "mix-blend-mode" and "background-blend-mode" property: + // The final color has the luminosity of the top color, while using the hue and saturation of the bottom color. + // This blend mode is equivalent to BlendColor, but with the layers swapped. + BlendLuminosity = 15 ) diff --git a/viewStyle.go b/viewStyle.go index 1c505b6..789537b 100644 --- a/viewStyle.go +++ b/viewStyle.go @@ -252,7 +252,7 @@ func (style *viewStyle) cssViewStyle(builder cssBuilder, session Session) { for _, tag := range []string{ Overflow, TextAlign, TextTransform, TextWeight, TextLineStyle, WritingMode, TextDirection, VerticalTextOrientation, CellVerticalAlign, CellHorizontalAlign, GridAutoFlow, Cursor, - WhiteSpace, WordBreak, TextOverflow, Float, TableVerticalAlign, Resize} { + WhiteSpace, WordBreak, TextOverflow, Float, TableVerticalAlign, Resize, MixBlendMode, BackgroundBlendMode} { if data, ok := enumProperties[tag]; ok { if tag != VerticalTextOrientation || (writingMode != VerticalLeftToRight && writingMode != VerticalRightToLeft) { diff --git a/viewUtils.go b/viewUtils.go index 5e89dbe..335274e 100644 --- a/viewUtils.go +++ b/viewUtils.go @@ -896,3 +896,27 @@ func isUserSelect(view View) (bool, bool) { return false, false } + +// GetMixBlendMode returns a "mix-blend-mode" of the subview. Returns one of next values: +// +// BlendNormal (0), BlendMultiply (1), BlendScreen (2), BlendOverlay (3), BlendDarken (4), +// BlendLighten (5), BlendColorDodge (6), BlendColorBurn (7), BlendHardLight (8), +// BlendSoftLight (9), BlendDifference (10), BlendExclusion (11), BlendHue (12), +// BlendSaturation (13), BlendColor (14), BlendLuminosity (15) +// +// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. +func GetMixBlendMode(view View, subviewID ...string) int { + return enumStyledProperty(view, subviewID, MixBlendMode, BlendNormal, true) +} + +// GetBackgroundBlendMode returns a "background-blend-mode" of the subview. Returns one of next values: +// +// BlendNormal (0), BlendMultiply (1), BlendScreen (2), BlendOverlay (3), BlendDarken (4), +// BlendLighten (5), BlendColorDodge (6), BlendColorBurn (7), BlendHardLight (8), +// BlendSoftLight (9), BlendDifference (10), BlendExclusion (11), BlendHue (12), +// BlendSaturation (13), BlendColor (14), BlendLuminosity (15) +// +// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. +func GetBackgroundBlendMode(view View, subviewID ...string) int { + return enumStyledProperty(view, subviewID, BackgroundBlendMode, BlendNormal, true) +} From 60783f2f222b8a6c696cf4dc49662a84b10b8a1c Mon Sep 17 00:00:00 2001 From: anoshenko Date: Mon, 19 Dec 2022 19:18:35 +0300 Subject: [PATCH 4/9] Updated readme --- README-ru.md | 137 ++++++++++++++++++++++++++++++----------------- README.md | 41 ++++++++++++++ propertyNames.go | 4 +- 3 files changed, 132 insertions(+), 50 deletions(-) diff --git a/README-ru.md b/README-ru.md index e214ab5..9525dd1 100644 --- a/README-ru.md +++ b/README-ru.md @@ -615,7 +615,7 @@ SizeUnit или имя константы (о константах ниже): Значение по умолчанию для всех типов View кроме многострочного редактора текста это NoneResize (0). Значение по умолчанию для многострочного редактора текста это BothResize (1). -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetResize(view View, subviewID ...string) int @@ -1021,7 +1021,7 @@ RadiusProperty, а не структура BoxRadius. Получить стру [, spread-radius = <увеличение>] [, inset = <тип>] } -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetViewShadows(view View, subviewID ...string) []ViewShadow @@ -1202,7 +1202,7 @@ AngleUnit или string (угловая константа или текстов * Attachment - ??? * Repeat (repeat) - необязательный параметр задающий повтор изображения. -Может принимать одно из следующих значений типа Int: +Может принимать одно из следующих значений типа int: | Константа | Значение | Имя | Описание | |-------------|:--------:|-------------|---------------------------------------------------------------| @@ -1216,6 +1216,47 @@ AngleUnit или string (угловая константа или текстов * ImageHorizontalAlign, * ImageVerticalAlign, +### Свойство "background-blend-mode" + +Свойство "background-blend-mode" (константа BackgroundBlendMode) типа int устанавливает, +как фоновые изображения / градиенты элемента должны смешиваться друг с другом и с цветом фона. + +Может принимать одно из следующих значений: + +| Константа | Значение | Имя | Описание | +|-----------------|:--------:|--------------|---------------------------------------------------------------| +| BlendNormal | 0 | "normal" | Конечный цвет это верхний цвет, независимо от того, какой нижний цвет. Эффект подобен двум непрозрачным листам бумаги, перекрывающимся друг с другом. | +| BlendMultiply | 1 | "multiply" | Конечный цвет является результатом умножения верхнего и нижнего цветов. Черный слой приводит к черному конечному слою, а белый слой не приводит к изменению. Эффект подобен наложению двух изображений, напечатанных на прозрачной пленке. | +| BlendScreen | 2 | "screen" | Конечный цвет является результатом инвертирования цветов, их умножения и инвертирования этого значения. Черный слой не приводит к изменению, а белый слой приводит к белому конечному слою. Эффект подобен двум изображениям на проекционном экране. | +| BlendOverlay | 3 | "overlay" | Конечный цвет является результатом умножения, если нижний цвет темнее, или "screen", если нижний цвет светлее. Этот режим наложения эквивалентен жесткому свету, но с перестановкой слоев. | +| BlendDarken | 4 | "darken" | Конечный цвет состоит из самых темных значений каждого цветового канала. | +| BlendLighten | 5 | "lighten" | Конечный цвет состоит из самых светлых значений каждого цветового канала. | +| BlendColorDodge | 6 | "color-dodge"| Окончательный цвет является результатом деления нижнего цвета на инверсию верхнего цвета. Черный передний план не приводит к изменениям. Передний план с обратным цветом фона приводит к полностью освещенному цвету. Этот режим наложения похож на "screen", но передний план должен быть таким же светлым, как и обратная сторона фона, чтобы создать полностью освещенный цвет. | +| BlendColorBurn | 7 | "color-burn" | Конечный цвет является результатом инвертирования нижнего цвета, деления значения на верхний цвет и инвертирования этого значения. Белый передний план не приводит к изменениям. Передний план с обратным цветом фона приводит к черному конечному изображению. Этот режим наложения похож на режим умножения, но передний план должен быть таким же темным, как и обратная сторона фона, чтобы окончательное изображение стало черным. | +| BlendHardLight | 8 | "hard-light" | Окончательный цвет является результатом умножения, если верхний цвет темнее, или "screen", если верхний цвет светлее. Этот режим наложения эквивалентен наложению, но слои меняются местами. Эффект подобен яркому прожектору на фоне. | +| BlendSoftLight | 9 | "soft-light" | Конечный цвет похож на "hard-light", но мягче. Этот режим наложения ведет себя аналогично "hard-light". Эффект подобен рассеянному свету прожектора на фоне | +| BlendDifference | 10 | "difference" | Окончательный цвет получается в результате вычитания более темного из двух цветов из более светлого. Черный слой не имеет никакого эффекта, а белый слой инвертирует цвет другого слоя. | +| BlendExclusion | 11 | "exclusion" | Конечный цвет подобен "difference", но с меньшим контрастом. Как и в случае с "difference", черный слой не имеет эффекта, а белый слой инвертирует цвет другого слоя. | +| BlendHue | 12 | "hue" | Конечный цвет имеет оттенок верхнего цвета, используя при этом насыщенность и яркость нижнего цвета. | +| BlendSaturation | 13 | "saturation" | Конечный цвет имеет насыщенность верхнего цвета при использовании оттенка и яркости нижнего цвета. Чисто серый фон, не имеющий насыщенности, не будет иметь никакого эффекта. | +| BlendColor | 14 | "color" | Конечный цвет имеет оттенок и насыщенность верхнего цвета, используя при этом яркость нижнего цвета. Эффект сохраняет уровни серого и может использоваться для раскрашивания переднего плана. | +| BlendLuminosity | 15 | "luminosity" | Окончательный цвет имеет яркость верхнего цвета, используя при этом оттенок и насыщенность нижнего цвета. Этот режим наложения эквивалентен "color", но с перестановкой слоев. | + +Получить значение данного свойства можно с помощью функции + + func GetBackgroundBlendMode(view View, subviewID ...string) int + +### Свойство "mix-blend-mode" + +Свойство "mix-blend-mode" (константа MixBlendMode) типа int устанавливает, +как содержимое View должно сочетаться с содержимым родительского View и фоном. + +Возможные значения данного свойства аналогичны значениям свойства "background-blend-mode" (см. выше) + +Получить значение данного свойства можно с помощью функции + + func GetMixBlendMode(view View, subviewID ...string) int + ### Свойство "clip" Свойство "clip" (константа Clip) типа ClipShape задает задает область образки. @@ -1282,7 +1323,7 @@ radius необходимо передать nil Свойство "opacity" (константа Opacity) типа float64 задает прозрачность View. Допустимые значения от 0 до 1. Где 1 - View полностью непрозрачен, 0 - полностью прозрачен. -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetOpacity(view View, subviewID ...string) float64 @@ -1292,7 +1333,7 @@ radius необходимо передать nil В случае перекрытия элементов, это значение определяет порядок наложения. В общем случае, элементы с большим z-index перекрывают элементы с меньшим. -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetZIndex(view View, subviewID ...string) int @@ -1306,7 +1347,7 @@ radius необходимо передать nil | 1 | Invisible | "invisible" | View невидим, но занимает место. | | 2 | Gone | "gone" | View невидим и не занимает место. | -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetVisibility(view View, subviewID ...string) int @@ -1383,7 +1424,7 @@ radius необходимо передать nil Шрифты применяются в том порядке в котором они перечислены. Т.е. сначала применяется первый, если он недоступен, то второй, третий и т.д. -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetFontName(view View, subviewID ...string) string @@ -1391,7 +1432,7 @@ radius необходимо передать nil Свойство "text-color" (константа TextColor) - Свойство типа Color определяет цвет текста. -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetTextColor(view View, subviewID ...string) Color @@ -1399,7 +1440,7 @@ radius необходимо передать nil Свойство "text-size" (константа TextSize) - Свойство типа SizeUnit определяет размер шрифта. -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetTextSize(view View, subviewID ...string) SizeUnit @@ -1407,7 +1448,7 @@ radius необходимо передать nil Свойство "italic" (константа Italic) - Свойство типа bool. Если значение равно true, то к тексту применяется курсивное начертание -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func IsItalic(view View, subviewID ...string) bool @@ -1415,7 +1456,7 @@ radius необходимо передать nil Свойство "small-caps" (константа SmallCaps) - Свойство типа bool. Если значение равно true, то к тексту применяется начертание капителью -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func IsSmallCaps(view View, subviewID ...string) bool @@ -1501,7 +1542,7 @@ radius необходимо передать nil Свойство "text-line-thickness" (константа TextLineThickness) - Свойство типа SizeUnit. Свойство устанавливает толщину декоративных линий на тексте заданных с помощью Свойств "strikethrough", "overline" и "underline". -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции GetTextLineThickness(view View, subviewID ...string) SizeUnit @@ -1521,7 +1562,7 @@ radius необходимо передать nil Если Свойство не определено то используется сплошная линия (SolidLine (1)). -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetTextLineStyle(view View, subviewID ...string) int @@ -1531,7 +1572,7 @@ radius необходимо передать nil Свойство устанавливает цвет декоративных линий на тексте заданных с помощью Свойств "strikethrough", "overline" и "underline". Если Свойство не определено то для линий используется цвет текста заданный с помощью Свойства "text-color". -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetTextLineColor(view View, subviewID ...string) Color @@ -1551,9 +1592,9 @@ radius необходимо передать nil | 8 | ExtraBoldFont | Дополнительный жирный (Сверх жирный) Extra Bold (Ultra Bold) | | 9 | BlackFont | Чёрный (Густой) Black (Heavy) | -Некоторые шрифты доступны только в нормальном или полужирном начертании. В этом случае значение данного Свойства игнорируется +Некоторые шрифты доступны только в нормальном или полужирном начертании. В этом случае значение данного свойства игнорируется -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetTextWeight(view View, subviewID ...string) int @@ -1580,7 +1621,7 @@ radius необходимо передать nil В качестве значения Свойству "text-shadow" может быть присвоено ViewShadow, массив ViewShadow, текстовое представление ViewShadow (см. выше, раздел "Свойство 'shadow'"). -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetTextShadows(view View, subviewID ...string) []ViewShadow @@ -1597,7 +1638,7 @@ radius необходимо передать nil | 2 | CenterAlign | "center" | Выравнивание по центру | | 3 | JustifyAlign | "justify" | Выравнивание по ширине | -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetTextAlign(view View, subviewID ...string) int @@ -1605,7 +1646,7 @@ radius необходимо передать nil Свойство "text-indent" (TextIndent) - Свойство типа SizeUnit определяет размер отступа (пустого места) перед первой строкой текста. -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetTextIndent(view View, subviewID ...string) SizeUnit @@ -1615,7 +1656,7 @@ radius необходимо передать nil Значение может быть отрицательным, но при этом могут быть ограничения, зависящие от конкретной реализации. Агент пользователя может не увеличивать или уменьшать межбуквенное расстояние для выравнивания текста. -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetLetterSpacing(view View, subviewID ...string) SizeUnit @@ -1625,7 +1666,7 @@ radius необходимо передать nil Если величина задана в процентах, то она определяет дополнительный интервал как процент от предварительной ширины символа. В остальных случаях она определяет дополнительный интервал в дополнение к внутреннему интервалу между словами, определяемому шрифтом. -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetWordSpacing(view View, subviewID ...string) SizeUnit @@ -1633,7 +1674,7 @@ radius необходимо передать nil Свойство "line-height" (константа LineHeight) - Свойство типа SizeUnit устанавливает величину пространства между строками. -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetLineHeight(view View, subviewID ...string) SizeUnit @@ -1648,7 +1689,7 @@ radius необходимо передать nil | 2 | LowerCaseTextTransform | Все символы строчные | | 3 | UpperCaseTextTransform | Все символы заглавные | -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetTextTransform(view View, subviewID ...string) int @@ -1662,7 +1703,7 @@ radius необходимо передать nil | 1 | LeftToRightDirection | Слева направо. Используется для английского и большинства других языков. | | 2 | RightToLeftDirection | Справа налево. Используется для иврит, арабский и некоторых других. | -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetTextDirection(view View, subviewID ...string) int @@ -1679,7 +1720,7 @@ radius необходимо передать nil | 2 | VerticalRightToLeft | Вертикальные строки выводятся справа налево. | | 3 | VerticalLeftToRight | Вертикальные строки выводятся слева направо. | -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetWritingMode(view View, subviewID ...string) int @@ -1694,7 +1735,7 @@ radius необходимо передать nil | 0 | MixedTextOrientation | Символы повернуты на 90 по часовой стрелке. Значение по умолчанию. | | 1 | UprightTextOrientation | Символы расположены нормально (вертикально). | -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetVerticalTextOrientation(view View, subviewID ...string) int @@ -1710,7 +1751,7 @@ radius необходимо передать nil Как и все Свойства текста Свойство "user-select" наследуемое, т.е. если вы установите его для контейнера, то оно также примениться ко всем дочерним элементам -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func IsUserSelect(view View, subviewID ...string) bool @@ -1729,7 +1770,7 @@ radius необходимо передать nil Точка схождения по умолчанию расположена в центре элемента, но её можно переместить используя Свойства "perspective-origin-x" и "perspective-origin-y". -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetPerspective(view View, subviewID ...string) SizeUnit @@ -1753,7 +1794,7 @@ radius необходимо передать nil задняя грань может быть видимой, когда преобразование вызывает вращение элемента в 3D пространстве. (Это Свойство не влияет на 2D-преобразования, которые не имеют перспективы.) -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetBackfaceVisible(view View, subviewID ...string) bool @@ -2154,7 +2195,7 @@ radius необходимо передать nil ### "content" Свойство "content" (константа Content) определяет массив дочерних View. Функция Get интерфейса -для данного Свойства всегда возвращает []View. +для данного свойства всегда возвращает []View. В качестве значения Свойства "content" могут быть переданы следующие 5 типов данных: @@ -2406,12 +2447,12 @@ ColumnLayout является контейнером, реализующим и Если данное Свойство равно 0 и не задано Свойство "column-width", то разбитие на колонки не выполняется, а контейнер прокручивается вниз. -Если значение данного Свойства больше 0, то список разбивается на колонки. Высота колонки +Если значение данного свойства больше 0, то список разбивается на колонки. Высота колонки равна высоте ColumnLayout, а ширина вычисляется как ширина ColumnLayout делённая на "column-count". Каждая следующая колонка располагается в зависимости от Свойства "text-direction" справа или слева от предыдущей, а контейнер прокручивается по горизонтали. -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetColumnCount(view View, subviewID ...string) int @@ -2423,7 +2464,7 @@ ColumnLayout является контейнером, реализующим и ВАЖНО! В качестве значения "column-width" нельзя использовать проценты (т.е. если вы зададите значение в процентах, то это проигнорируется системой) -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetColumnWidth(view View, subviewID ...string) SizeUnit @@ -2431,7 +2472,7 @@ ColumnLayout является контейнером, реализующим и Свойство "column-gap" (константа ColumnGap) типа SizeUnit устанавливает ширину разрыва между колонками. -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetColumnGap(view View, subviewID ...string) SizeUnit @@ -2514,10 +2555,10 @@ ViewBorder описана как Свойство "avoid-break" (константа AvoidBreak) типа bool позволяет избежать этого эффекта. Необходимо установить для View, который нельзя разрывать, данное Свойство со значением "true". -Соответственно значение "false" данного Свойства позволяет разрывать View. +Соответственно значение "false" данного свойства позволяет разрывать View. Значение по умолчанию "false". -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetAvoidBreak(view View, subviewID ...string) bool @@ -3225,7 +3266,7 @@ float32, float64, int, int8…int64, uint, uint8…uint64. func GetDropDownDisabledItems(view View, subviewID ...string) []int Выбранное значение определяется int Свойством "current" (константа Current). Значение по умолчанию 0. -Прочитать значение данного Свойства можно с помощью функции +Прочитать значение данного свойства можно с помощью функции func GetCurrent(view View, subviewID ...string) int @@ -3339,7 +3380,7 @@ ReloadListViewData() интерфейса ListView или глобальную Свойства "text-direction". Для языков с письмом справа налево (арабский, иврит) начало находится справа, для остальных языков - слева. -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetListOrientation(view View, subviewID ...string) int @@ -3356,7 +3397,7 @@ ReloadListViewData() интерфейса ListView или глобальную * WrapReverse (2) - начинается новая колонка/строка элементов. Новая колонка располагается по направлению к началу (о положении начала и конца см. выше), новая строка - сверху. -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetListWrap(view View, subviewID ...string) int @@ -3386,7 +3427,7 @@ ReloadListViewData() интерфейса ListView или глобальную | 2 | CenterAlign | "center" | Выравнивание по центру | | 3 | StretchAlign | "stretch" | Выравнивание по высоте | -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetListItemVerticalAlign(view View, subviewID ...string) int @@ -3402,7 +3443,7 @@ ReloadListViewData() интерфейса ListView или глобальную | 2 | CenterAlign | "center" | Выравнивание по центру | | 3 | StretchAlign | "stretch" | Выравнивание по ширине | -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции GetListItemHorizontalAlign(view View, subviewID ...string) int @@ -3413,7 +3454,7 @@ ListView позволяет выбирать пункты списка имею int Свойство "current" (константа Current). Значение "current" меньше 0 означает что не выбран ни один пункт -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetCurrent(view View, subviewID ...string) int @@ -3441,13 +3482,13 @@ int Свойство "current" (константа Current). Значение "c | 2 | MultipleCheckbox | "multiple" | ☑ Чекбокс позволяющий пометить несколько пунктов | -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetListViewCheckbox(view View, subviewID ...string) int Получить/установить список помеченных пунктов можно с помощью Свойства "checked" (константа Checked). Данное Свойство имеет тип []int и хранит индексы помеченных элементов. -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetListViewCheckedItems(view View, subviewID ...string) []int @@ -3698,7 +3739,7 @@ TableColumnStyle объявлена как Для горизонтального выравнивания используется Свойство "text-align". -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetTableVerticalAlign(view View, subviewID ...string) int @@ -3720,7 +3761,7 @@ TableColumnStyle объявлена как (с использованием клавиш управления курсором). В данном режиме таблица может получить фокус ввода. В данном режиме таблица генерирует два вида событий: "table-row-selected" и "table-row-clicked" (о них ниже). -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetSelectionMode(view View, subviewID ...string) int @@ -3738,7 +3779,7 @@ TableColumnStyle объявлена как В режиме RowSelection значение поля Column игнорируется. Также в данном режиме Свойству "current" можно присваивать значение типа int (индекс строки). -Получить значение данного Свойства можно с помощью функции +Получить значение данного свойства можно с помощью функции func GetTableCurrent(view View, subviewID ...string) CellIndex @@ -3869,7 +3910,7 @@ CanvasView это область в которой вы можете рисов func NewCanvasView(session Session, params Params) CanvasView CanvasView имеет всего одно дополнительное Свойство: "draw-function" (константа DrawFunction). -С помощью данного Свойства задается функция рисования имеющая следующее описание +С помощью данного свойства задается функция рисования имеющая следующее описание func(Canvas) diff --git a/README.md b/README.md index 67d1de1..d804aca 100644 --- a/README.md +++ b/README.md @@ -1195,6 +1195,47 @@ Can be one of the following int values: * ImageVerticalAlign, +### "background-blend-mode" property + +The "background-blend-mode" int property (BackgroundBlendMode constant)sets how an view's background images should blend +with each other and with the view's background color. + +Can take one of the following values: + +| Constant | Value | Name | Description | +|-----------------|:-----:|--------------|------------------------------------------------------------------| +| BlendNormal | 0 | "normal" | The final color is the top color, regardless of what the bottom color is. The effect is like two opaque pieces of paper overlapping. | +| BlendMultiply | 1 | "multiply" | The final color is the result of multiplying the top and bottom colors. A black layer leads to a black final layer, and a white layer leads to no change. The effect is like two images printed on transparent film overlapping. | +| BlendScreen | 2 | "screen" | The final color is the result of inverting the colors, multiplying them, and inverting that value. A black layer leads to no change, and a white layer leads to a white final layer. The effect is like two images shone onto a projection screen. | +| BlendOverlay | 3 | "overlay" | The final color is the result of multiply if the bottom color is darker, or screen if the bottom color is lighter. This blend mode is equivalent to hard-light but with the layers swapped. | +| BlendDarken | 4 | "darken" | The final color is composed of the darkest values of each color channel. | +| BlendLighten | 5 | "lighten" | The final color is composed of the lightest values of each color channel. | +| BlendColorDodge | 6 | "color-dodge"| The final color is the result of dividing the bottom color by the inverse of the top color. A black foreground leads to no change. A foreground with the inverse color of the backdrop leads to a fully lit color. This blend mode is similar to screen, but the foreground need only be as light as the inverse of the backdrop to create a fully lit color. | +| BlendColorBurn | 7 | "color-burn" | The final color is the result of inverting the bottom color, dividing the value by the top color, and inverting that value. A white foreground leads to no change. A foreground with the inverse color of the backdrop leads to a black final image. This blend mode is similar to multiply, but the foreground need only be as dark as the inverse of the backdrop to make the final image black. | +| BlendHardLight | 8 | "hard-light" | The final color is the result of multiply if the top color is darker, or screen if the top color is lighter. This blend mode is equivalent to overlay but with the layers swapped. The effect is similar to shining a harsh spotlight on the backdrop. | +| BlendSoftLight | 9 | "soft-light" | The final color is similar to hard-light, but softer. This blend mode behaves similar to hard-light. The effect is similar to shining a diffused spotlight on the backdrop*.* | +| BlendDifference | 10 | "difference" | The final color is the result of subtracting the darker of the two colors from the lighter one. A black layer has no effect, while a white layer inverts the other layer's color. | +| BlendExclusion | 11 | "exclusion" | The final color is similar to difference, but with less contrast. As with difference, a black layer has no effect, while a white layer inverts the other layer's color. | +| BlendHue | 12 | "hue" | The final color has the hue of the top color, while using the saturation and luminosity of the bottom color. | +| BlendSaturation | 13 | "saturation" | The final color has the saturation of the top color, while using the hue and luminosity of the bottom color. A pure gray backdrop, having no saturation, will have no effect. | +| BlendColor | 14 | "color" | The final color has the hue and saturation of the top color, while using the luminosity of the bottom color. The effect preserves gray levels and can be used to colorize the foreground. | +| BlendLuminosity | 15 | "luminosity" | The final color has the luminosity of the top color, while using the hue and saturation of the bottom color. This blend mode is equivalent to BlendColor, but with the layers swapped. | + +You can get the value of this property using the function + + func GetBackgroundBlendMode(view View, subviewID ...string) int + +### "mix-blend-mode" property + +The "mix-blend-mode" int property (MixBlendMode constant) sets how a view's content should blend +with the content of the view's parent and the view's background. + +Possible values of this property are similar to the values of the "background-blend-mode" property (see above) + +You can get the value of this property using the function + + func GetMixBlendMode(view View, subviewID ...string) int + ### "clip" property The "clip" property (Clip constant) of the ClipShape type specifies the crop area. diff --git a/propertyNames.go b/propertyNames.go index 318eeaf..78b492a 100644 --- a/propertyNames.go +++ b/propertyNames.go @@ -676,8 +676,8 @@ const ( Order = "Order" // BackgroundBlendMode is the constant for the "background-blend-mode" property tag. - // The "background-blend-mode" int property sets how an element's background images should blend - // with each other and with the element's background color. + // The "background-blend-mode" int property sets how an view's background images should blend + // with each other and with the view's background color. // Valid values are "normal" (0), "multiply" (1), "screen" (2), "overlay" (3), "darken" (4), "lighten" (5), // "color-dodge" (6), "color-burn" (7), "hard-light" (8), "soft-light" (9), "difference" (10), // "exclusion" (11), "hue" (12), "saturation" (13), "color" (14), "luminosity" (15). From c5485c27c2044545e97546c9354186a2b400f2d9 Mon Sep 17 00:00:00 2001 From: anoshenko Date: Tue, 20 Dec 2022 17:48:00 +0300 Subject: [PATCH 5/9] Updated readme --- README-ru.md | 11 +++++++++++ README.md | 11 +++++++++++ tableView.go | 8 ++++---- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/README-ru.md b/README-ru.md index 9525dd1..6a26eb8 100644 --- a/README-ru.md +++ b/README-ru.md @@ -2301,6 +2301,17 @@ ListLayout является контейнером, реализующим ин Свойства "list-row-gap" и "list-column-gap" (константы ListRowGap и ListColumnGap) типа SizeUnit позволяют установить соответственно расстояния между строками и столбцами контейнера. Значение по умолчанию 0. +### "order" + +Свойство "order" (константа Order) типа int используется View, помещенными в контейнер ListLayout или GridLayout (см. ниже), +для изменения своего положения в контейнере. +Свойство "order" определяет порядок, используемый для размещения View в контейнере. Элементы располагаются в восходящем порядке по значению order. +Элементы с одинаковым значением order располагаются в том порядке, в каком они добавлялись в контейнер. + +Значение по умолчанию равно 0. Поэтому для помещения View в начало надо использовать отрицательные значения свойства "order". + +Внимание: свойство "order" воздействует только на визуальный порядок элементов, но не логический порядок или табуляцию. + ## GridLayout GridLayout является контейнером, реализующим интерфейс ViewsContainer. Для его создания используется функция diff --git a/README.md b/README.md index d804aca..147fb66 100644 --- a/README.md +++ b/README.md @@ -2279,6 +2279,17 @@ alignment of items in the list. Valid values: The "list-row-gap" and "list-column-gap" SizeUnit properties (ListRowGap and ListColumnGap constants) allow you to set the distance between the rows and columns of the container, respectively. The default is 0px. +### "order" + +The "order" property (Order constant) of type int is used by Views placed in a ListLayout or GridLayout container (see below), +to change its position in the container. +The "order" property defines the order used to place the View in the container. The elements are arranged in ascending order by their order value. +Elements with the same order value are placed in the order in which they were added to the container. + +The default value is 0. Therefore, negative values of the "order" property must be used to place the View at the beginning. + +Note: The "order" property only affects the visual order of the elements, not the logical order or tabs. + ## GridLayout GridLayout is a container that implements the ViewsContainer interface. To create it, use the function diff --git a/tableView.go b/tableView.go index 897bb4d..db618d4 100644 --- a/tableView.go +++ b/tableView.go @@ -831,7 +831,7 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) { var view tableCellView view.init(session) - ignorCells := []struct{ row, column int }{} + ignoreCells := []struct{ row, column int }{} selectionMode := GetTableSelectionMode(table) var allowCellSelection TableAllowCellSelection = nil @@ -908,7 +908,7 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) { for column := 0; column < columnCount; column++ { ignore := false - for _, cell := range ignorCells { + for _, cell := range ignoreCells { if cell.row == row && cell.column == column { ignore = true break @@ -994,7 +994,7 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) { buffer.WriteString(strconv.Itoa(columnSpan)) buffer.WriteRune('"') for c := column + 1; c < column+columnSpan; c++ { - ignorCells = append(ignorCells, struct { + ignoreCells = append(ignoreCells, struct { row int column int }{row: row, column: c}) @@ -1010,7 +1010,7 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) { } for r := row + 1; r < row+rowSpan; r++ { for c := column; c < column+columnSpan; c++ { - ignorCells = append(ignorCells, struct { + ignoreCells = append(ignoreCells, struct { row int column int }{row: r, column: c}) From 3c3271663dfc79475fdc5cebb41632b664f066a7 Mon Sep 17 00:00:00 2001 From: anoshenko Date: Tue, 20 Dec 2022 18:38:39 +0300 Subject: [PATCH 6/9] Added "tabindex" property --- propertyNames.go | 8 ++++++++ propertySet.go | 1 + tableView.go | 12 +++++++++--- view.go | 30 ++++++++++++++++++++++++++++-- viewUtils.go | 19 +++++++++++++++++++ 5 files changed, 65 insertions(+), 5 deletions(-) diff --git a/propertyNames.go b/propertyNames.go index 78b492a..553b865 100644 --- a/propertyNames.go +++ b/propertyNames.go @@ -690,4 +690,12 @@ const ( // "color-dodge" (6), "color-burn" (7), "hard-light" (8), "soft-light" (9), "difference" (10), // "exclusion" (11), "hue" (12), "saturation" (13), "color" (14), "luminosity" (15). MixBlendMode = "mix-blend-mode" + + // TabIndex is the constant for the "tabindex" property tag. + // The "tabindex" int property indicates that View can be focused, and where it participates in sequential keyboard navigation + // (usually with the Tab key, hence the name). + // * A negative value means that View is not reachable via sequential keyboard navigation, but could be focused by clicking with the mouse or touching. + // * tabindex="0" means that View should be focusable in sequential keyboard navigation, after any positive tabindex values and its order is defined in order of its addition. + // * A positive value means View should be focusable in sequential keyboard navigation, with its order defined by the value of the number. + TabIndex = "tabindex" ) diff --git a/propertySet.go b/propertySet.go index 8d8a775..810a368 100644 --- a/propertySet.go +++ b/propertySet.go @@ -74,6 +74,7 @@ var intProperties = []string{ ColumnSpan, ColumnCount, Order, + TabIndex, } var floatProperties = map[string]struct{ min, max float64 }{ diff --git a/tableView.go b/tableView.go index db618d4..94a3871 100644 --- a/tableView.go +++ b/tableView.go @@ -606,7 +606,8 @@ func (table *tableViewData) propertyChanged(tag string) { switch GetTableSelectionMode(table) { case CellSelection: - session.updateProperty(htmlID, "tabindex", "0") + tabIndex, _ := intProperty(table, TabIndex, session, 0) + session.updateProperty(htmlID, "tabindex", tabIndex) session.updateProperty(htmlID, "onfocus", "tableViewFocusEvent(this, event)") session.updateProperty(htmlID, "onblur", "tableViewBlurEvent(this, event)") session.updateProperty(htmlID, "data-selection", "cell") @@ -621,7 +622,8 @@ func (table *tableViewData) propertyChanged(tag string) { session.updateProperty(htmlID, "onkeydown", "tableViewCellKeyDownEvent(this, event)") case RowSelection: - session.updateProperty(htmlID, "tabindex", "0") + tabIndex, _ := intProperty(table, TabIndex, session, 0) + session.updateProperty(htmlID, "tabindex", tabIndex) session.updateProperty(htmlID, "onfocus", "tableViewFocusEvent(this, event)") session.updateProperty(htmlID, "onblur", "tableViewBlurEvent(this, event)") session.updateProperty(htmlID, "data-selection", "row") @@ -636,7 +638,11 @@ func (table *tableViewData) propertyChanged(tag string) { session.updateProperty(htmlID, "onkeydown", "tableViewRowKeyDownEvent(this, event)") default: // NoneSelection - for _, prop := range []string{"tabindex", "data-current", "onfocus", "onblur", "onkeydown", "data-selection"} { + if tabIndex, ok := intProperty(table, TabIndex, session, -1); !ok || tabIndex < 0 { + session.removeProperty(htmlID, "tabindex") + } + + for _, prop := range []string{"data-current", "onfocus", "onblur", "onkeydown", "data-selection"} { session.removeProperty(htmlID, prop) } } diff --git a/view.go b/view.go index f7a62eb..8a251fe 100644 --- a/view.go +++ b/view.go @@ -187,6 +187,14 @@ func (view *viewData) remove(tag string) { case ID: view.viewID = "" + case TabIndex, "tab-index": + delete(view.properties, tag) + if view.Focusable() { + view.session.updateProperty(view.htmlID(), "tabindex", "0") + } else { + view.session.updateProperty(view.htmlID(), "tabindex", "-1") + } + case UserData: delete(view.properties, tag) @@ -312,6 +320,18 @@ func (view *viewData) set(tag string, value any) bool { } view.viewID = text + case TabIndex, "tab-index": + if !view.setIntProperty(tag, value) { + return false + } + if value, ok := intProperty(view, TabIndex, view.Session(), 0); ok { + view.session.updateProperty(view.htmlID(), "tabindex", strconv.Itoa(value)) + } else if view.Focusable() { + view.session.updateProperty(view.htmlID(), "tabindex", "0") + } else { + view.session.updateProperty(view.htmlID(), "tabindex", "-1") + } + case UserData: view.properties[tag] = value @@ -758,8 +778,14 @@ func viewHTML(view View, buffer *strings.Builder) { buffer.WriteRune(' ') } - if view.Focusable() && !disabled { - buffer.WriteString(`tabindex="0" `) + if !disabled { + if value, ok := intProperty(view, TabIndex, view.Session(), -1); ok { + buffer.WriteString(`tabindex="`) + buffer.WriteString(strconv.Itoa(value)) + buffer.WriteString(`" `) + } else if view.Focusable() { + buffer.WriteString(`tabindex="0" `) + } } buffer.WriteString(`onscroll="scrollEvent(this, event)" `) diff --git a/viewUtils.go b/viewUtils.go index 335274e..fd8bb48 100644 --- a/viewUtils.go +++ b/viewUtils.go @@ -153,6 +153,25 @@ func GetOverflow(view View, subviewID ...string) int { return enumStyledProperty(view, subviewID, Overflow, defaultOverflow, false) } +// GetTabIndex returns the subview tab-index. +// If the second argument (subviewID) is not specified or it is "" then a tab-index of the first argument (view) is returned +func GetTabIndex(view View, subviewID ...string) int { + if len(subviewID) > 0 && subviewID[0] != "" { + view = ViewByID(view, subviewID[0]) + } + + defaultValue := -1 + if view != nil { + if view.Focusable() { + defaultValue = 0 + } + if value, ok := intProperty(view, TabIndex, view.Session(), defaultValue); ok { + return value + } + } + return defaultValue +} + // GetZIndex returns the subview z-order. // If the second argument (subviewID) is not specified or it is "" then a z-order of the first argument (view) is returned func GetZIndex(view View, subviewID ...string) int { From 3993dbad20897ae038c3db6494de4b3248ccd317 Mon Sep 17 00:00:00 2001 From: anoshenko Date: Tue, 20 Dec 2022 18:55:54 +0300 Subject: [PATCH 7/9] Updated readme --- CHANGELOG.md | 4 ++-- README-ru.md | 16 ++++++++++++++++ README.md | 18 +++++++++++++++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c55347e..0814c6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # v.11.0 -* Added "order", "background-blend-mode", and "mix-blend-mode" properties -* Added GetOrder, GetBackgroundBlendMode, and GetMixBlendMode functions +* Added "tabindex", "order", "background-blend-mode", and "mix-blend-mode" properties +* Added GetTabIndex, GetOrder, GetBackgroundBlendMode, and GetMixBlendMode functions * ClientItem, SetClientItem, and RemoveAllClientItems method added to Session interface * PropertyWithTag method of DataObject interface renamed to PropertyByTag diff --git a/README-ru.md b/README-ru.md index 6a26eb8..7de1413 100644 --- a/README-ru.md +++ b/README-ru.md @@ -1327,6 +1327,22 @@ radius необходимо передать nil func GetOpacity(view View, subviewID ...string) float64 +### Свойство "tabindex" + +Свойство "tabindex" (константа TabIndex) типа int определяет должен ли данный View участвовать в последовательной +навигации по всей странице с помощью клавиатуры и в каком порядке. Может принимать одно из следующих видов значений: + +* отрицательное значение – View может быть выделен с помощью мыши или прикосновения, однако не участвует в последовательной навигации; + +* 0 – View может быть выделен и достигнут с помощью последовательной навигации, порядок навигации определён браузером (обычно в порядке добавления); + +* положительное значение – элемент будет достигнут (и выделен) с помощью последовательной навигации, а навигация осуществляется по возрастанию значения "tabindex". +В случае, если несколько элементов содержат одно и то же значение "tabindex", то навигации осуществляется в порядке их добавления. + +Получить значение данного свойства можно с помощью функции + + func GetTabIndex(view View, subviewID ...string) int + ### Свойство "z-index" Свойство "z-index" (константа ZIndex) типа int определяет положение элемента и нижестоящих элементов по оси z. diff --git a/README.md b/README.md index 147fb66..0a75cd2 100644 --- a/README.md +++ b/README.md @@ -1298,13 +1298,29 @@ The textual description of the polygonal cropping area is in the following forma ### "opacity" property -The "opacity" property (constant Opacity) of the float64 type sets the transparency of the View. Valid values are from 0 to 1. +The "opacity" property (Opacity constant) of the float64 type sets the transparency of the View. Valid values are from 0 to 1. Where 1 - View is fully opaque, 0 - fully transparent. You can get the value of this property using the function func GetOpacity(view View, subviewID ...string) float64 +### "tabindex" property + +The "tabindex" int property (TabIndex constant) determines whether this View should participate in sequential navigation +throughout the page using the keyboard and in what order. It can take one of the following types of values: + +* negative value - View can be selected with the mouse or touch, but does not participate in sequential navigation; + +* 0 - View can be selected and reached using sequential navigation, the order of navigation is determined by the browser (usually in order of addition); + +* positive value - the element will be reached (and selected) using sequential navigation, and navigation is performed by ascending "tabindex" value. +If multiple elements contain the same "tabindex" value, navigation is done in the order in which they were added. + +You can get the value of this property using the function + + func GetTabIndex(viewView, subviewID ...string) int + ### "z-index" property The "z-index" property (constant ZIndex) of type int defines the position of the element and its children along the z-axis. From c7a7b3ed1e34203ee76b1c0a0494155f64b22e6c Mon Sep 17 00:00:00 2001 From: anoshenko Date: Fri, 23 Dec 2022 17:27:14 +0300 Subject: [PATCH 8/9] Added "column-fill" property --- CHANGELOG.md | 5 +++-- README-ru.md | 14 ++++++++++++++ README.md | 18 ++++++++++++++++-- columnLayout.go | 20 ++++++++++++++++++++ propertySet.go | 5 +++++ propertyValues.go | 7 +++++++ 6 files changed, 65 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0814c6a..509f8e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,14 @@ # v.11.0 -* Added "tabindex", "order", "background-blend-mode", and "mix-blend-mode" properties -* Added GetTabIndex, GetOrder, GetBackgroundBlendMode, and GetMixBlendMode functions +* Added "tabindex", "order", "column-fill", "background-blend-mode", and "mix-blend-mode" properties +* Added GetTabIndex, GetOrder, GetColumnFill, GetBackgroundBlendMode, and GetMixBlendMode functions * ClientItem, SetClientItem, and RemoveAllClientItems method added to Session interface * PropertyWithTag method of DataObject interface renamed to PropertyByTag # v.10.0 * The Canvas.TextWidth method replaced by Canvas.TextMetrics +* Added support of WebAssembly # v0.9.0 diff --git a/README-ru.md b/README-ru.md index 7de1413..8aa6399 100644 --- a/README-ru.md +++ b/README-ru.md @@ -2574,6 +2574,20 @@ ViewBorder описана как rui.ColorProperty: rui.Black, })) +### Свойство "column-fill" + +Свойство "column-fill" (константа ColumnFill) типа int управляет тем, как содержимое элемента сбалансировано при разбиении на столбцы. +Может принимать одно из двух значений + +| Значение | Константа | Имя | Описание | +|:--------:|-------------------|-----------|------------------------------------------------------------------| +| 0 | ColumnFillBalance | "balance" | Контент поровну разделен между столбцами (значение по умолчанию) | +| 1 | ColumnFillAuto | "auto" | Столбцы заполняются последовательно. Контент занимает ровно столько места, сколько ему нужно, что может привести к тому, что некоторые столбцы останутся пустыми. | + +Получить значение данного свойства можно с помощью функции + + func GetColumnFill(view View, subviewID ...string) int + ### Свойство "avoid-break" При формировании колонок ColumnLayout может разрывать некоторые типы View, так что начало diff --git a/README.md b/README.md index 0a75cd2..3d0bcc6 100644 --- a/README.md +++ b/README.md @@ -2496,7 +2496,7 @@ which implements the Properties interface (see above). ColumnSeparatorProperty c Line style can take the following values: | Value | Constant | Name | Description | -|:-----:|------------|----------| ------------------| +|:-----:|------------|----------|-------------------| | 0 | NoneLine | "none" | No frame | | 1 | SolidLine | "solid" | Solid line | | 2 | DashedLine | "dashed" | Dashed line | @@ -2550,6 +2550,20 @@ equivalent to rui.ColorProperty: rui.Black, })) +### "column-fill" property + +The "column-fill" int property (ColumnFill constant) controls how an ColumnLayout's contents are balanced when broken into columns. +Valid values: + +| Value | Constant | Name | Description | +|:-----:|-------------------|-----------|------------------------------------------------------------| +| 0 | ColumnFillBalance | "balance" | Content is equally divided between columns (default value) | +| 1 | ColumnFillAuto | "auto" | Columns are filled sequentially. Content takes up only the room it needs, possibly resulting in some columns remaining empty | + +You can get the value of this property using the function + + func GetColumnFill(view View, subviewID ...string) int + ### "avoid-break" property When forming columns, ColumnLayout can break some types of View, so that the beginning @@ -2807,7 +2821,7 @@ It determines how the text is cut if it goes out of bounds. This property of type int can take the following values | Value | Constant | Name | Cropping Text | -|:-----:|----------------------| -----------|-------------------------------------------------------------| +|:-----:|----------------------|------------|-------------------------------------------------------------| | 0 | TextOverflowClip | "clip" | Text is clipped at the border (default) | | 1 | TextOverflowEllipsis | "ellipsis" | At the end of the visible part of the text '…' is displayed | diff --git a/columnLayout.go b/columnLayout.go index d4a5bdf..7dd4b6a 100644 --- a/columnLayout.go +++ b/columnLayout.go @@ -11,28 +11,41 @@ const ( // Values less than zero are not valid. if the "column-count" property value is 0 then // the number of columns is calculated based on the "column-width" property ColumnCount = "column-count" + // ColumnWidth is the constant for the "column-width" property tag. // The "column-width" SizeUnit property specifies the width of each column. ColumnWidth = "column-width" + // ColumnGap is the constant for the "column-gap" property tag. // The "column-width" SizeUnit property sets the size of the gap (gutter) between columns. ColumnGap = "column-gap" + // ColumnSeparator is the constant for the "column-separator" property tag. // The "column-separator" property specifies the line drawn between columns in a multi-column layout. ColumnSeparator = "column-separator" + // ColumnSeparatorStyle is the constant for the "column-separator-style" property tag. // The "column-separator-style" int property sets the style of the line drawn between // columns in a multi-column layout. // Valid values are NoneLine (0), SolidLine (1), DashedLine (2), DottedLine (3), and DoubleLine (4). ColumnSeparatorStyle = "column-separator-style" + // ColumnSeparatorWidth is the constant for the "column-separator-width" property tag. // The "column-separator-width" SizeUnit property sets the width of the line drawn between // columns in a multi-column layout. ColumnSeparatorWidth = "column-separator-width" + // ColumnSeparatorColor is the constant for the "column-separator-color" property tag. // The "column-separator-color" Color property sets the color of the line drawn between // columns in a multi-column layout. ColumnSeparatorColor = "column-separator-color" + + // ColumnFill is the constant for the "column-fill" property tag. + // The "column-fill" int property controls how an ColumnLayout's contents are balanced when broken into columns. + // Valid values are + // * ColumnFillBalance (0) - Content is equally divided between columns (default value); + // * ColumnFillAuto (1) - Columns are filled sequentially. Content takes up only the room it needs, possibly resulting in some columns remaining empty. + ColumnFill = "column-fill" ) // ColumnLayout - grid-container of View @@ -206,3 +219,10 @@ func GetColumnSeparatorColor(view View, subviewID ...string) Color { border := getColumnSeparator(view, subviewID) return border.Color } + +// GetColumnFill returns a "column-fill" property value of the subview. +// Returns one of next values: ColumnFillBalance (0) or ColumnFillAuto (1) +// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. +func GetColumnFill(view View, subviewID ...string) int { + return enumStyledProperty(view, subviewID, ColumnFill, ColumnFillBalance, true) +} diff --git a/propertySet.go b/propertySet.go index 810a368..607a98c 100644 --- a/propertySet.go +++ b/propertySet.go @@ -459,6 +459,11 @@ var enumProperties = map[string]struct { BackgroundBlendMode, []string{"normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity"}, }, + ColumnFill: { + []string{"balance", "auto"}, + ColumnFill, + []string{"balance", "auto"}, + }, } func notCompatibleType(tag string, value any) { diff --git a/propertyValues.go b/propertyValues.go index d262463..85b7e41 100644 --- a/propertyValues.go +++ b/propertyValues.go @@ -388,4 +388,11 @@ const ( // The final color has the luminosity of the top color, while using the hue and saturation of the bottom color. // This blend mode is equivalent to BlendColor, but with the layers swapped. BlendLuminosity = 15 + + // ColumnFillBalance - value of the "column-fill" property: content is equally divided between columns. + ColumnFillBalance = 0 + + // ColumnFillAuto - value of the "column-fill" property: + // Columns are filled sequentially. Content takes up only the room it needs, possibly resulting in some columns remaining empty. + ColumnFillAuto = 1 ) From 01e2e2e00b01f1688e46378adc6f1d780613d6e3 Mon Sep 17 00:00:00 2001 From: anoshenko Date: Tue, 3 Jan 2023 14:56:57 +0300 Subject: [PATCH 9/9] Added "column-span-all" property --- CHANGELOG.md | 4 ++-- README-ru.md | 14 ++++++++++++++ README.md | 14 ++++++++++++++ app_scripts.js | 1 + columnLayout.go | 10 ++++++++++ propertySet.go | 1 + view.go | 8 ++++++++ viewStyle.go | 8 ++++++++ 8 files changed, 58 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 509f8e4..f80f85e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # v.11.0 -* Added "tabindex", "order", "column-fill", "background-blend-mode", and "mix-blend-mode" properties -* Added GetTabIndex, GetOrder, GetColumnFill, GetBackgroundBlendMode, and GetMixBlendMode functions +* Added "tabindex", "order", "column-fill", "column-span-all", "background-blend-mode", and "mix-blend-mode" properties +* Added GetTabIndex, GetOrder, GetColumnFill, IsColumnSpanAll, GetBackgroundBlendMode, and GetMixBlendMode functions * ClientItem, SetClientItem, and RemoveAllClientItems method added to Session interface * PropertyWithTag method of DataObject interface renamed to PropertyByTag diff --git a/README-ru.md b/README-ru.md index 8aa6399..c427cad 100644 --- a/README-ru.md +++ b/README-ru.md @@ -2603,6 +2603,20 @@ ViewBorder описана как func GetAvoidBreak(view View, subviewID ...string) bool +### Свойство "column-span-all" + +Свойство "column-span-all" (константа ColumnSpanAll) типа bool устанавливается для View помещенных в ColumnLayout. +Если данное свойство установлено в true, то View расширяется на всю ширину ColumnLayout, занимая все колонки. +Такое View будет как бы разрывать контейнер. + +Обычно данное свойство используется для заголовков. + +Значение по умолчанию "false". + +Получить значение данного свойства можно с помощью функции + + func IsColumnSpanAll(view View, subviewID ...string) bool + ## StackLayout StackLayout является контейнером, реализующим интерфейс ViewsContainer. Все дочерние View diff --git a/README.md b/README.md index 3d0bcc6..8f8fae6 100644 --- a/README.md +++ b/README.md @@ -2579,6 +2579,20 @@ You can get the value of this property using the function func GetAvoidBreak(view View, subviewID ...string) bool +### "column-span-all" property + +The "column-span-all" bool property (ColumnSpanAll constant) is set for Views placed in the ColumnLayout. +If this property is set to true, then the View expands to the full width of the ColumnLayout, covering all columns. +Such a View will, as it were, break the container. + +Typically, this property is used for headers. + +The default value is "false". + +You can get the value of this property using the function + + func IsColumnSpanAll(view View, subviewID ...string) bool + ## StackLayout StackLayout is a container that implements the ViewsContainer interface. diff --git a/app_scripts.js b/app_scripts.js index a9ff7a7..2b39533 100644 --- a/app_scripts.js +++ b/app_scripts.js @@ -426,6 +426,7 @@ function mouseOutEvent(element, event) { function clickEvent(element, event) { mouseEvent(element, event, "click-event") event.preventDefault(); + event.stopPropagation(); } function doubleClickEvent(element, event) { diff --git a/columnLayout.go b/columnLayout.go index 7dd4b6a..1a883f7 100644 --- a/columnLayout.go +++ b/columnLayout.go @@ -46,6 +46,10 @@ const ( // * ColumnFillBalance (0) - Content is equally divided between columns (default value); // * ColumnFillAuto (1) - Columns are filled sequentially. Content takes up only the room it needs, possibly resulting in some columns remaining empty. ColumnFill = "column-fill" + + // ColumnSpanAll is the constant for the "column-span-all" property tag. + // The "column-span-all" bool property makes it possible for a view to span across all columns when its value is set to true. + ColumnSpanAll = "column-span-all" ) // ColumnLayout - grid-container of View @@ -226,3 +230,9 @@ func GetColumnSeparatorColor(view View, subviewID ...string) Color { func GetColumnFill(view View, subviewID ...string) int { return enumStyledProperty(view, subviewID, ColumnFill, ColumnFillBalance, true) } + +// IsColumnSpanAll returns a "column-span-all" property value of the subview. +// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. +func IsColumnSpanAll(view View, subviewID ...string) bool { + return boolStyledProperty(view, subviewID, ColumnSpanAll, false) +} diff --git a/propertySet.go b/propertySet.go index 607a98c..0df23ce 100644 --- a/propertySet.go +++ b/propertySet.go @@ -63,6 +63,7 @@ var boolProperties = []string{ TabCloseButton, Repeating, UserSelect, + ColumnSpanAll, } var intProperties = []string{ diff --git a/view.go b/view.go index 8a251fe..ebd7dd7 100644 --- a/view.go +++ b/view.go @@ -626,6 +626,14 @@ func viewPropertyChanged(view *viewData, tag string) { session.updateCSSProperty(htmlID, "user-select", "") } return + + case ColumnSpanAll: + if spanAll, ok := boolProperty(view, ColumnSpanAll, session); ok && spanAll { + session.updateCSSProperty(htmlID, `column-span`, `all`) + } else { + session.updateCSSProperty(htmlID, `column-span`, `none`) + } + return } if cssTag, ok := sizeProperties[tag]; ok { diff --git a/viewStyle.go b/viewStyle.go index 789537b..98895e2 100644 --- a/viewStyle.go +++ b/viewStyle.go @@ -453,6 +453,14 @@ func (style *viewStyle) cssViewStyle(builder cssBuilder, session Session) { builder.add(`animation-play-state`, `running`) } } + + if spanAll, ok := boolProperty(style, ColumnSpanAll, session); ok { + if spanAll { + builder.add(`column-span`, `all`) + } else { + builder.add(`column-span`, `none`) + } + } } func valueToOrientation(value any, session Session) (int, bool) {