forked from mbk-lab/rui_orig
2
0
Fork 0

Fixed Popup

This commit is contained in:
Alexei Anoshenko 2022-08-07 18:59:56 +03:00
parent e0aa021384
commit 082c30b062
9 changed files with 411 additions and 279 deletions

View File

@ -1,8 +1,9 @@
# v0.8.0 # v0.9.0
* Requared go 1.18 * Requared go 1.18
* The "interface{}" type replaced by "any" * The "interface{}" type replaced by "any"
* Added "overflow", "arrow", "arrow-align", "arrow-size", and "arrow-offset" properties * Added "overflow", "arrow", "arrow-align", "arrow-size", "arrow-width", and "arrow-offset" properties
* Added "@ruiArrowSize" and "@ruiArrowWidth" constants to the default theme
* Added the GetOverflow function * Added the GetOverflow function
# v0.8.0 # v0.8.0

View File

@ -4349,6 +4349,42 @@ params - параметры всплавающего окна (может быт
Заголовок также может иметь кнопку закрытия окна. Для ее добавления к заголовку используется свойство "close-button" типа bool. Заголовок также может иметь кнопку закрытия окна. Для ее добавления к заголовку используется свойство "close-button" типа bool.
Установка этого свойства в "true" добавляет к заголовку кнопку закрытия окна (значение по умолчанию равно "false"). Установка этого свойства в "true" добавляет к заголовку кнопку закрытия окна (значение по умолчанию равно "false").
### Стрелка Popup
Всплывающее окно может иметь у одной из сторон стрелку. Стрелка задается с помощью свойства "arrow" (константа Arrow).
ойства "arrow" может принимать следующие значения
| Значение | Константа | Расположение стрелки |
|:--------:|-------------|---------------------------------------------|
| 0 | NoneArrow | Нет стрелки (значение по умолчанию) |
| 1 | TopArrow | Стрелка у верхней стороны всплывающего окна |
| 2 | RightArrow | Стрелка у правой стороны всплывающего окна |
| 3 | BottomArrow | Стрелка у нижней стороны всплывающего окна |
| 4 | LeftArrow | Стрелка у левой стороны всплывающего окна |
Размеры стрелки задаются с помощью свойств "arrow-size" (константа ArrowSize) и "arrow-width" (константа ArrowWidth) типа SizeUnit.
Они задают длину ("arrow-size") и ширину ("arrow-width") стрелки. Если данные свойтсва не заданы то используются константы
"@ruiArrowSize" (значение по умолчанию 16px) и "@ruiArrowWidth" (значение по умолчанию 16px).
Выравнивание стрелки относительно всплывающего окна задается с помощью свойства "arrow-align" (константа ArrowAlign).
ойства "arrow-align" может принимать следующие значения
| Значение | Константы | Выравнивание |
|:--------:|--------------------------|------------------------------------------------|
| 0 | TopAlign / LeftAlign | Выравнивание по верхнему / левому краю строны |
| 1 | BottomAlign / RightAlign | Выравнивание по нижнему / правому краю строны |
| 2 | CenterAlign | Выравнивание по центру (значение по умолчанию) |
Также для стрелки можно задать дополнительное смещение. Для этого используется свойств "arrow-offset" (константа ArrowOffset) типа SizeUnit.
Если значение свойства "arrow-align" равно TopAlign/LeftAlign, то смещение задается относительно верхней / левой стороны.
Если значение свойства "arrow-align" равно BottomAlign/RightAlign, то смещение задается относительно нижней / правой стороны.
Если значение свойства "arrow-align" равно CenterAlign, то смещение (может быть как положительным так и отрицательным) добавляется в виде отступа стрелки.
Т.е по центру выравнивается стрелка со смещением
Если "arrow-offset" не задано, то значением по умолчанию для "arrow-align" равного CenterAlign является 0.
Для других значений "arrow-align" значением по умолчанию является соответствующий радиус скругления угла всплывающего окна.
### Закрытие Popup ### Закрытие Popup
Как было сказано выше, для закрытия всплавающего окна используется метод Dismiss() интерфейса Popup. Как было сказано выше, для закрытия всплавающего окна используется метод Dismiss() интерфейса Popup.

View File

@ -4312,6 +4312,43 @@ not to use the "title-style" property, but to override the "ruiPopupTitle" style
The header can also have a window close button. To add it to the header, use the "close-button" bool property. The header can also have a window close button. To add it to the header, use the "close-button" bool property.
Setting this property to "true" adds a window close button to the title bar (the default value is "false"). Setting this property to "true" adds a window close button to the title bar (the default value is "false").
### Arrow Popup
A pop-up window can have an arrow on one side. An arrow is specified using the "arrow" int property (Arrow constant).
The "arrow" property can take the following values
| Value | Constant | Arrow location |
|:-----:|-------------|----------------------------------------------|
| 0 | NoneArrow | No arrow (default value) |
| 1 | Top Arrow | Arrow at the top side of the pop-up window |
| 2 | RightArrow | Arrow on the right side of the pop-up window |
| 3 | bottomarrow | Arrow at the bottom of the pop-up window |
| 4 | LeftArrow | Arrow on the left side of the pop-up window |
The size of the arrow is specified using the "arrow-size" (ArrowSize constant) and "arrow-width" (ArrowWidth constant) SizeUnit properties.
They specify the length ("arrow-size") and width ("arrow-width") of the arrow.
If these properties are not set, then the constants "@ruiArrowSize" (the default value is 16px)
and "@ruiArrowWidth" (the default value is 16px) are used.
The alignment of the arrow relative to the popup is set using the "arrow-align" int property (ArrowAlign constant).
The "arrow-align" property can take the following values
| Value | Constants | Alignment |
|:-----:|--------------------------|----------------------------------|
| 0 | TopAlign / LeftAlign | Top/left alignment |
| 1 | BottomAlign / RightAlign | Bottom/Right Alignment |
| 2 | CenterAlign | Center alignment (default value) |
You can also set an additional offset for the arrow. For this, the "arrow-offset" SizeUnit property (ArrowOffset constant) is used.
If the value of the "arrow-align" property is TopAlign/LeftAlign, then the offset is relative to the top/left side.
If the value of the "arrow-align" property is BottomAlign/RightAlign, then the offset is relative to the bottom/right side.
If the value of the "arrow-align" property is CenterAlign, then an offset (can be either positive or negative) is added as an arrow padding.
That is, the arrow is aligned in the center with an offset
If "arrow-offset" is not set, then the default value for "arrow-align" equal to CenterAlign is 0.
For other "arrow-align" values, the default value is the appropriate corner radius of the popup.
### Close Popup ### Close Popup
As it was said above, the Dismiss() method of the Popup interface is used to close the popup window. As it was said above, the Dismiss() method of the Popup interface is used to close the popup window.

View File

@ -62,6 +62,7 @@ theme {
ruiTabBarPadding = 2px, ruiTabBarPadding = 2px,
ruiTabRadius = 2px, ruiTabRadius = 2px,
ruiArrowSize = 16px, ruiArrowSize = 16px,
ruiArrowWidth = 16px,
}, },
constants:touch = _{ constants:touch = _{
ruiButtonHorizontalPadding = 20px, ruiButtonHorizontalPadding = 20px,

590
popup.go
View File

@ -44,23 +44,40 @@ const (
Arrow = "arrow" Arrow = "arrow"
// ArrowAlign is the constant for the "arrow-align" property tag. // ArrowAlign is the constant for the "arrow-align" property tag.
// The "arrow-align" int property is used for set the horizontal alignment of Popup arrow. // The "arrow-align" int property is used for set the horizontal alignment of the Popup arrow.
// Valid values: LeftAlign (0), RightAlign (1), TopAlign (0), BottomAlign (1), CenterAlign (2) // Valid values: LeftAlign (0), RightAlign (1), TopAlign (0), BottomAlign (1), CenterAlign (2)
ArrowAlign = "arrow-align" ArrowAlign = "arrow-align"
// ArrowSize is the constant for the "arrow-size" property tag. // ArrowSize is the constant for the "arrow-size" property tag.
// The "arrow-size" SizeUnit property is used for set the size of Popup arrow. // The "arrow-size" SizeUnit property is used for set the size (length) of the Popup arrow.
ArrowSize = "arrow-size" ArrowSize = "arrow-size"
// ArrowWidth is the constant for the "arrow-width" property tag.
// The "arrow-width" SizeUnit property is used for set the width of the Popup arrow.
ArrowWidth = "arrow-width"
// ArrowOffset is the constant for the "arrow-offset" property tag. // ArrowOffset is the constant for the "arrow-offset" property tag.
// The "arrow-offset" SizeUnit property is used for set the offset of Popup arrow. // The "arrow-offset" SizeUnit property is used for set the offset of the Popup arrow.
ArrowOffset = "arrow-offset" ArrowOffset = "arrow-offset"
NoneArrow = 0 // NoneArrow is value of the popup "arrow" property: no arrow
TopArrow = 1 NoneArrow = 0
RightArrow = 2
// TopArrow is value of the popup "arrow" property:
// Arrow at the top side of the pop-up window
TopArrow = 1
// RightArrow is value of the popup "arrow" property:
// Arrow on the right side of the pop-up window
RightArrow = 2
// BottomArrow is value of the popup "arrow" property:
// Arrow at the bottom of the pop-up window
BottomArrow = 3 BottomArrow = 3
LeftArrow = 4
// LeftArrow is value of the popup "arrow" property:
// Arrow on the left side of the pop-up window
LeftArrow = 4
) )
// PopupButton describes a button that will be placed at the bottom of the window. // PopupButton describes a button that will be placed at the bottom of the window.
@ -90,27 +107,259 @@ type popupManager struct {
popups []Popup popups []Popup
} }
type popupArrow struct {
column, row int
location, align int
size, width, off SizeUnit
}
func (arrow *popupArrow) fixOff(popupView View) {
if arrow.align == CenterAlign && arrow.off.Type == Auto {
r := GetRadius(popupView, "")
switch arrow.location {
case TopArrow:
switch arrow.align {
case LeftAlign:
arrow.off = r.TopLeftX
case RightAlign:
arrow.off = r.TopRightX
}
case BottomArrow:
switch arrow.align {
case LeftAlign:
arrow.off = r.BottomLeftX
case RightAlign:
arrow.off = r.BottomRightX
}
case RightArrow:
switch arrow.align {
case TopAlign:
arrow.off = r.TopRightY
case BottomAlign:
arrow.off = r.BottomRightY
}
case LeftArrow:
switch arrow.align {
case TopAlign:
arrow.off = r.TopLeftY
case BottomAlign:
arrow.off = r.BottomLeftY
}
}
}
}
func (arrow *popupArrow) createView(popupView View) View {
session := popupView.Session()
defaultSize := func(constTag string, defValue SizeUnit) SizeUnit {
if value, ok := session.Constant(constTag); ok {
if size, ok := StringToSizeUnit(value); ok && size.Type != Auto && size.Value != 0 {
return size
}
}
return defValue
}
if arrow.size.Type == Auto || arrow.size.Value == 0 {
arrow.size = defaultSize("ruiArrowSize", Px(16))
}
if arrow.width.Type == Auto || arrow.width.Value == 0 {
arrow.width = defaultSize("ruiArrowWidth", Px(16))
}
color := GetBackgroundColor(popupView, "")
border := NewBorder(Params{
Style: SolidLine,
ColorTag: color,
Width: arrow.size,
})
border2 := NewBorder(Params{
Style: SolidLine,
Width: SizeUnit{Type: arrow.width.Type, Value: arrow.width.Value / 2},
})
params := Params{}
switch arrow.location {
case TopArrow:
params[Row] = 0
params[Column] = 1
params[BorderBottom] = border
params[BorderLeft] = border2
params[BorderRight] = border2
case RightArrow:
params[Row] = 1
params[Column] = 0
params[BorderLeft] = border
params[BorderTop] = border2
params[BorderBottom] = border2
case BottomArrow:
params[Row] = 0
params[Column] = 1
params[BorderTop] = border
params[BorderLeft] = border2
params[BorderRight] = border2
case LeftArrow:
params[Row] = 1
params[Column] = 0
params[BorderRight] = border
params[BorderTop] = border2
params[BorderBottom] = border2
}
arrowView := NewView(session, params)
params = Params{
Row: arrow.row,
Column: arrow.column,
Content: arrowView,
}
arrow.fixOff(popupView)
switch arrow.location {
case TopArrow, BottomArrow:
cellWidth := make([]SizeUnit, 3)
switch arrow.align {
case LeftAlign:
cellWidth[0] = arrow.off
cellWidth[2] = Fr(1)
case RightAlign:
cellWidth[0] = Fr(1)
cellWidth[2] = arrow.off
default:
cellWidth[0] = Fr(1)
cellWidth[2] = Fr(1)
if arrow.off.Type != Auto && arrow.off.Value != 0 {
arrowView.Set(MarginLeft, arrow.off)
}
}
params[CellWidth] = cellWidth
case RightArrow, LeftArrow:
cellHeight := make([]SizeUnit, 3)
switch arrow.align {
case TopAlign:
cellHeight[0] = arrow.off
cellHeight[2] = Fr(1)
case BottomAlign:
cellHeight[0] = Fr(1)
cellHeight[2] = arrow.off
default:
cellHeight[0] = Fr(1)
cellHeight[2] = Fr(1)
if arrow.off.Type != Auto && arrow.off.Value != 0 {
arrowView.Set(MarginTop, arrow.off)
}
}
params[CellHeight] = cellHeight
}
return NewGridLayout(session, params)
}
func (popup *popupData) init(view View, popupParams Params) { func (popup *popupData) init(view View, popupParams Params) {
popup.view = view popup.view = view
session := view.Session() session := view.Session()
columnCount := 3
rowCount := 3
popupRow := 1
popupColumn := 1
arrow := popupArrow{
row: 1,
column: 1,
align: CenterAlign,
}
switch arrow.location, _ = enumProperty(popupParams, Arrow, session, NoneArrow); arrow.location {
case TopArrow:
rowCount = 4
popupRow = 2
case BottomArrow:
rowCount = 4
arrow.row = 2
case LeftArrow:
columnCount = 4
popupColumn = 2
case RightArrow:
columnCount = 4
arrow.column = 2
default:
}
cellWidth := make([]SizeUnit, columnCount)
switch hAlign, _ := enumProperty(popupParams, HorizontalAlign, session, CenterAlign); hAlign {
case LeftAlign:
cellWidth[columnCount-1] = Fr(1)
case RightAlign:
cellWidth[0] = Fr(1)
default:
cellWidth[0] = Fr(1)
cellWidth[columnCount-1] = Fr(1)
}
cellHeight := make([]SizeUnit, rowCount)
switch vAlign, _ := enumProperty(popupParams, VerticalAlign, session, CenterAlign); vAlign {
case LeftAlign:
cellHeight[rowCount-1] = Fr(1)
case RightAlign:
cellHeight[0] = Fr(1)
default:
cellHeight[0] = Fr(1)
cellHeight[rowCount-1] = Fr(1)
}
layerParams := Params{
Style: "ruiPopupLayer",
MaxWidth: Percent(100),
MaxHeight: Percent(100),
CellWidth: cellWidth,
CellHeight: cellHeight,
}
params := Params{ params := Params{
Style: "ruiPopup", Style: "ruiPopup",
Row: popupRow,
Column: popupColumn,
MaxWidth: Percent(100), MaxWidth: Percent(100),
MaxHeight: Percent(100), MaxHeight: Percent(100),
CellVerticalAlign: StretchAlign, CellVerticalAlign: StretchAlign,
CellHorizontalAlign: StretchAlign, CellHorizontalAlign: StretchAlign,
ClickEvent: func(View) {}, ClickEvent: func(View) {},
Shadow: NewShadowWithParams(Params{
SpreadRadius: Px(4),
Blur: Px(16),
ColorTag: "@ruiPopupShadow",
}),
} }
closeButton := false var closeButton View = nil
outsideClose := false outsideClose := false
vAlign := CenterAlign
hAlign := CenterAlign
arrow := 0
arrowAlign := CenterAlign
arrowSize := AutoSize()
arrowOff := AutoSize()
buttons := []PopupButton{} buttons := []PopupButton{}
titleStyle := "ruiPopupTitle" titleStyle := "ruiPopupTitle"
var title View = nil var title View = nil
@ -118,18 +367,42 @@ func (popup *popupData) init(view View, popupParams Params) {
for tag, value := range popupParams { for tag, value := range popupParams {
if value != nil { if value != nil {
switch tag { switch tag {
case VerticalAlign, HorizontalAlign, Arrow, Row, Column:
// Do nothing
case Margin:
layerParams[Padding] = value
case MarginLeft:
layerParams[PaddingLeft] = value
case MarginRight:
layerParams[PaddingRight] = value
case MarginTop:
layerParams[PaddingTop] = value
case MarginBottom:
layerParams[PaddingBottom] = value
case CloseButton: case CloseButton:
closeButton, _ = boolProperty(popupParams, CloseButton, session) closeButton = NewGridLayout(session, Params{
Column: 1,
Height: "@ruiPopupTitleHeight",
Width: "@ruiPopupTitleHeight",
CellHorizontalAlign: CenterAlign,
CellVerticalAlign: CenterAlign,
TextSize: Px(20),
Content: "✕",
NotTranslate: true,
ClickEvent: func(View) {
popup.Dismiss()
},
})
case OutsideClose: case OutsideClose:
outsideClose, _ = boolProperty(popupParams, OutsideClose, session) outsideClose, _ = boolProperty(popupParams, OutsideClose, session)
case VerticalAlign:
vAlign, _ = enumProperty(popupParams, VerticalAlign, session, CenterAlign)
case HorizontalAlign:
hAlign, _ = enumProperty(popupParams, HorizontalAlign, session, CenterAlign)
case Buttons: case Buttons:
switch value := value.(type) { switch value := value.(type) {
case PopupButton: case PopupButton:
@ -169,9 +442,6 @@ func (popup *popupData) init(view View, popupParams Params) {
notCompatibleType(tag, value) notCompatibleType(tag, value)
} }
case Arrow:
arrow, _ = enumProperty(popupParams, Arrow, session, NoneArrow)
case ArrowAlign: case ArrowAlign:
switch text := value.(type) { switch text := value.(type) {
case string: case string:
@ -183,13 +453,13 @@ func (popup *popupData) init(view View, popupParams Params) {
value = "right" value = "right"
} }
} }
arrowAlign, _ = enumProperty(popupParams, ArrowAlign, session, CenterAlign) arrow.align, _ = enumProperty(popupParams, ArrowAlign, session, CenterAlign)
case ArrowSize: case ArrowSize:
arrowSize, _ = sizeProperty(popupParams, ArrowSize, session) arrow.size, _ = sizeProperty(popupParams, ArrowSize, session)
case ArrowOffset: case ArrowOffset:
arrowOff, _ = sizeProperty(popupParams, ArrowOffset, session) arrow.off, _ = sizeProperty(popupParams, ArrowOffset, session)
default: default:
params[tag] = value params[tag] = value
@ -199,40 +469,29 @@ func (popup *popupData) init(view View, popupParams Params) {
popupView := NewGridLayout(view.Session(), params) popupView := NewGridLayout(view.Session(), params)
var cellHeight []SizeUnit var popupCellHeight []SizeUnit
viewRow := 0 viewRow := 0
if title != nil || closeButton { if title != nil || closeButton != nil {
viewRow = 1 titleContent := []View{}
titleView := NewGridLayout(session, Params{ if title != nil {
titleContent = append(titleContent, title)
}
if closeButton != nil {
titleContent = append(titleContent, closeButton)
}
popupView.Append(NewGridLayout(session, Params{
Row: 0, Row: 0,
Style: titleStyle, Style: titleStyle,
CellWidth: []any{Fr(1), "@ruiPopupTitleHeight"}, CellWidth: []any{Fr(1), AutoSize()},
CellVerticalAlign: CenterAlign, CellVerticalAlign: CenterAlign,
PaddingLeft: Px(12), PaddingLeft: Px(12),
}) Content: titleContent,
if title != nil { }))
titleView.Append(title)
}
if closeButton {
titleView.Append(NewGridLayout(session, Params{
Column: 1,
Height: "@ruiPopupTitleHeight",
Width: "@ruiPopupTitleHeight",
CellHorizontalAlign: CenterAlign,
CellVerticalAlign: CenterAlign,
TextSize: Px(20),
Content: "✕",
NotTranslate: true,
ClickEvent: func(View) {
popup.Dismiss()
},
}))
}
popupView.Append(titleView) viewRow = 1
cellHeight = []SizeUnit{AutoSize(), Fr(1)} popupCellHeight = []SizeUnit{AutoSize(), Fr(1)}
} else { } else {
cellHeight = []SizeUnit{Fr(1)} popupCellHeight = []SizeUnit{Fr(1)}
} }
view.Set(Row, viewRow) view.Set(Row, viewRow)
@ -240,7 +499,7 @@ func (popup *popupData) init(view View, popupParams Params) {
if buttonCount := len(buttons); buttonCount > 0 { if buttonCount := len(buttons); buttonCount > 0 {
buttonsAlign, _ := enumProperty(params, ButtonsAlign, session, RightAlign) buttonsAlign, _ := enumProperty(params, ButtonsAlign, session, RightAlign)
cellHeight = append(cellHeight, AutoSize()) popupCellHeight = append(popupCellHeight, AutoSize())
gap, _ := sizeConstant(session, "ruiPopupButtonGap") gap, _ := sizeConstant(session, "ruiPopupButtonGap")
cellWidth := []SizeUnit{} cellWidth := []SizeUnit{}
for i := 0; i < buttonCount; i++ { for i := 0; i < buttonCount; i++ {
@ -278,25 +537,16 @@ func (popup *popupData) init(view View, popupParams Params) {
Content: buttonsPanel, Content: buttonsPanel,
})) }))
} }
popupView.Set(CellHeight, cellHeight)
popup.layerView = NewGridLayout(session, Params{ popupView.Set(CellHeight, popupCellHeight)
Style: "ruiPopupLayer",
CellVerticalAlign: vAlign, if arrow.location != NoneArrow {
CellHorizontalAlign: hAlign, layerParams[Content] = []View{popupView, arrow.createView(popupView)}
MaxWidth: Percent(100), } else {
MaxHeight: Percent(100), layerParams[Content] = []View{popupView}
Filter: NewViewFilter(Params{ }
DropShadow: NewShadowWithParams(Params{
SpreadRadius: Px(4), popup.layerView = NewGridLayout(session, layerParams)
Blur: Px(16),
ColorTag: "@ruiPopupShadow",
}),
}),
Content: NewColumnLayout(session, Params{
Content: popup.createArrow(arrow, arrowAlign, arrowSize, arrowOff, popupView),
}),
})
if outsideClose { if outsideClose {
popup.layerView.Set(ClickEvent, func(View) { popup.layerView.Set(ClickEvent, func(View) {
@ -305,200 +555,6 @@ func (popup *popupData) init(view View, popupParams Params) {
} }
} }
func (popup popupData) createArrow(arrow int, align int, size SizeUnit, off SizeUnit, popupView View) View {
if arrow == NoneArrow {
return popupView
}
session := popupView.Session()
if size.Type == Auto {
size = Px(16)
if value, ok := session.Constant("ruiArrowSize"); ok {
size, _ = StringToSizeUnit(value)
}
}
color := GetBackgroundColor(popupView, "")
border := NewBorder(Params{
Style: SolidLine,
ColorTag: color,
Width: size,
})
border2 := NewBorder(Params{
Style: SolidLine,
ColorTag: 1,
Width: SizeUnit{Type: size.Type, Value: size.Value / 2},
})
popupParams := Params{
MaxWidth: Percent(100),
MaxHeight: Percent(100),
Row: 1,
Column: 1,
Content: popupView,
}
arrowParams := Params{
Width: size,
Height: size,
}
containerParams := Params{
MaxWidth: Percent(100),
MaxHeight: Percent(100),
CellWidth: []SizeUnit{AutoSize(), Fr(1), AutoSize()},
CellHeight: []SizeUnit{AutoSize(), Fr(1), AutoSize()},
}
switch arrow {
case TopArrow:
arrowParams[Column] = 1
arrowParams[BorderBottom] = border
arrowParams[BorderLeft] = border2
arrowParams[BorderRight] = border2
case RightArrow:
arrowParams[Column] = 2
arrowParams[Row] = 1
arrowParams[BorderLeft] = border
arrowParams[BorderTop] = border2
arrowParams[BorderBottom] = border2
case BottomArrow:
arrowParams[Column] = 1
arrowParams[Row] = 2
arrowParams[BorderTop] = border
arrowParams[BorderLeft] = border2
arrowParams[BorderRight] = border2
case LeftArrow:
arrowParams[Row] = 1
arrowParams[BorderRight] = border
arrowParams[BorderTop] = border2
arrowParams[BorderBottom] = border2
default:
return popupView
}
switch align {
case LeftAlign:
switch arrow {
case TopArrow:
if off.Type == Auto {
off = GetRadius(popupView, "").TopLeftX
}
if off.Type != Auto {
arrowParams[MarginLeft] = off
}
case RightArrow:
if off.Type == Auto {
off = GetRadius(popupView, "").TopRightY
}
if off.Type != Auto {
arrowParams[MarginTop] = off
}
case BottomArrow:
if off.Type == Auto {
off = GetRadius(popupView, "").BottomLeftX
}
if off.Type != Auto {
arrowParams[MarginLeft] = off
}
case LeftArrow:
if off.Type == Auto {
off = GetRadius(popupView, "").TopLeftY
}
if off.Type != Auto {
arrowParams[MarginTop] = off
}
}
case RightAlign:
switch arrow {
case TopArrow:
if off.Type == Auto {
off = GetRadius(popupView, "").TopRightX
}
if off.Type != Auto {
arrowParams[MarginRight] = off
}
case RightArrow:
if off.Type == Auto {
off = GetRadius(popupView, "").BottomRightY
}
if off.Type != Auto {
arrowParams[MarginBottom] = off
}
case BottomArrow:
if off.Type == Auto {
off = GetRadius(popupView, "").BottomRightX
}
if off.Type != Auto {
arrowParams[MarginRight] = off
}
case LeftArrow:
if off.Type == Auto {
off = GetRadius(popupView, "").BottomLeftY
}
if off.Type != Auto {
arrowParams[MarginBottom] = off
}
}
default:
align = CenterAlign
if off.Type != Auto {
switch arrow {
case TopArrow, BottomArrow:
if off.Value < 0 {
off.Value = -off.Value
arrowParams[MarginRight] = off
} else {
arrowParams[MarginLeft] = off
}
case RightArrow, LeftArrow:
if off.Value < 0 {
off.Value = -off.Value
arrowParams[MarginBottom] = off
} else {
arrowParams[MarginTop] = off
}
}
}
}
if margin := popupView.Get(Margin); margin != nil {
popupView.Remove(Margin)
containerParams[Padding] = margin
}
/*
for key, value := range popupParams {
if key != Content {
popupView.Set(key, value)
}
}
*/
containerParams[CellVerticalAlign] = align
containerParams[CellHorizontalAlign] = align
containerParams[Content] = []View{
NewView(session, arrowParams),
//popupView,
NewColumnLayout(session, popupParams),
}
return NewGridLayout(session, containerParams)
}
func (popup popupData) View() View { func (popup popupData) View() View {
return popup.view return popup.view
} }

View File

@ -22,7 +22,7 @@ func (view *viewData) onItemResize(self View, index string, x, y, width, height
} }
func (view *viewData) setFrameListener(tag string, value any) bool { func (view *viewData) setFrameListener(tag string, value any) bool {
listeners, ok := valueToEventListeners[FilePicker, []FileInfo](value) listeners, ok := valueToEventListeners[View, Frame](value)
if !ok { if !ok {
notCompatibleType(tag, value) notCompatibleType(tag, value)
return false return false

View File

@ -3,7 +3,6 @@ package rui
import ( import (
"embed" "embed"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
@ -171,7 +170,7 @@ func registerImage(fs *embed.FS, path, filename string) {
} }
func scanImagesDirectory(path, filePrefix string) { func scanImagesDirectory(path, filePrefix string) {
if files, err := ioutil.ReadDir(path); err == nil { if files, err := os.ReadDir(path); err == nil {
for _, file := range files { for _, file := range files {
filename := file.Name() filename := file.Name()
if filename[0] != '.' { if filename[0] != '.' {
@ -189,7 +188,7 @@ func scanImagesDirectory(path, filePrefix string) {
} }
func scanThemesDir(path string) { func scanThemesDir(path string) {
if files, err := ioutil.ReadDir(path); err == nil { if files, err := os.ReadDir(path); err == nil {
for _, file := range files { for _, file := range files {
filename := file.Name() filename := file.Name()
if filename[0] != '.' { if filename[0] != '.' {
@ -197,7 +196,7 @@ func scanThemesDir(path string) {
if file.IsDir() { if file.IsDir() {
scanThemesDir(newPath) scanThemesDir(newPath)
} else if strings.ToLower(filepath.Ext(newPath)) == ".rui" { } else if strings.ToLower(filepath.Ext(newPath)) == ".rui" {
if data, err := ioutil.ReadFile(newPath); err == nil { if data, err := os.ReadFile(newPath); err == nil {
registerThemeText(string(data)) registerThemeText(string(data))
} else { } else {
ErrorLog(err.Error()) ErrorLog(err.Error())
@ -380,7 +379,7 @@ func AllRawResources() []string {
} }
if resources.path != "" { if resources.path != "" {
if files, err := ioutil.ReadDir(resources.path + rawDir); err == nil { if files, err := os.ReadDir(resources.path + rawDir); err == nil {
for _, file := range files { for _, file := range files {
result = append(result, file.Name()) result = append(result, file.Name())
} }
@ -388,7 +387,7 @@ func AllRawResources() []string {
} }
if exe, err := os.Executable(); err == nil { if exe, err := os.Executable(); err == nil {
if files, err := ioutil.ReadDir(filepath.Dir(exe) + "/resources/" + rawDir); err == nil { if files, err := os.ReadDir(filepath.Dir(exe) + "/resources/" + rawDir); err == nil {
for _, file := range files { for _, file := range files {
result = append(result, file.Name()) result = append(result, file.Name())
} }

View File

@ -351,6 +351,8 @@ func (layout *stackLayoutData) Pop(animation int, onPopFinished func(View)) bool
buffer.WriteString(htmlID) buffer.WriteString(htmlID)
buffer.WriteString(`pop" class="ruiStackPageLayout" ontransitionend="stackTransitionEndEvent(\'`) buffer.WriteString(`pop" class="ruiStackPageLayout" ontransitionend="stackTransitionEndEvent(\'`)
buffer.WriteString(htmlID) buffer.WriteString(htmlID)
buffer.WriteString(`\', \'ruiPop\', event)" ontransitioncancel="stackTransitionEndEvent(\'`)
buffer.WriteString(htmlID)
buffer.WriteString(`\', \'ruiPop\', event)" style="transition: transform 1s ease;">`) buffer.WriteString(`\', \'ruiPop\', event)" style="transition: transform 1s ease;">`)
viewHTML(layout.popView, buffer) viewHTML(layout.popView, buffer)
buffer.WriteString(`</div>`) buffer.WriteString(`</div>`)

View File

@ -2,7 +2,7 @@ package rui
import ( import (
"embed" "embed"
"io/ioutil" "os"
"path/filepath" "path/filepath"
"strings" "strings"
) )
@ -28,7 +28,7 @@ func scanEmbedStringsDir(fs *embed.FS, dir string) {
} }
func scanStringsDir(path string) { func scanStringsDir(path string) {
if files, err := ioutil.ReadDir(path); err == nil { if files, err := os.ReadDir(path); err == nil {
for _, file := range files { for _, file := range files {
filename := file.Name() filename := file.Name()
if filename[0] != '.' { if filename[0] != '.' {
@ -36,7 +36,7 @@ func scanStringsDir(path string) {
if file.IsDir() { if file.IsDir() {
scanStringsDir(newPath) scanStringsDir(newPath)
} else if strings.ToLower(filepath.Ext(newPath)) == ".rui" { } else if strings.ToLower(filepath.Ext(newPath)) == ".rui" {
if data, err := ioutil.ReadFile(newPath); err == nil { if data, err := os.ReadFile(newPath); err == nil {
loadStringResources(string(data)) loadStringResources(string(data))
} else { } else {
ErrorLog(err.Error()) ErrorLog(err.Error())