mirror of https://github.com/anoshenko/rui.git
				
				
				
			Fixed Popup
This commit is contained in:
		
							parent
							
								
									e0aa021384
								
							
						
					
					
						commit
						082c30b062
					
				|  | @ -1,8 +1,9 @@ | |||
| # v0.8.0 | ||||
| # v0.9.0 | ||||
| 
 | ||||
| * Requared go 1.18 | ||||
| * 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 | ||||
| 
 | ||||
| # v0.8.0 | ||||
|  |  | |||
							
								
								
									
										36
									
								
								README-ru.md
								
								
								
								
							
							
						
						
									
										36
									
								
								README-ru.md
								
								
								
								
							|  | @ -4349,6 +4349,42 @@ params - параметры всплавающего окна (может быт | |||
| Заголовок также может иметь кнопку закрытия окна. Для ее добавления к заголовку используется свойство "close-button" типа bool. | ||||
| Установка этого свойства в "true" добавляет к заголовку кнопку закрытия окна (значение по умолчанию равно "false"). | ||||
| 
 | ||||
| ### Стрелка Popup | ||||
| 
 | ||||
| Всплывающее окно может иметь у одной из сторон стрелку. Стрелка задается с помощью свойства "arrow" (константа Arrow).  | ||||
| Cвойства "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).  | ||||
| Cвойства "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 | ||||
| 
 | ||||
| Как было сказано выше, для закрытия всплавающего окна используется метод Dismiss() интерфейса Popup. | ||||
|  |  | |||
							
								
								
									
										37
									
								
								README.md
								
								
								
								
							
							
						
						
									
										37
									
								
								README.md
								
								
								
								
							|  | @ -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. | ||||
| 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 | ||||
| 
 | ||||
| As it was said above, the Dismiss() method of the Popup interface is used to close the popup window. | ||||
|  |  | |||
|  | @ -62,6 +62,7 @@ theme { | |||
| 		ruiTabBarPadding = 2px, | ||||
| 		ruiTabRadius = 2px, | ||||
| 		ruiArrowSize = 16px, | ||||
| 		ruiArrowWidth = 16px, | ||||
| 	}, | ||||
| 	constants:touch = _{ | ||||
| 		ruiButtonHorizontalPadding = 20px, | ||||
|  |  | |||
							
								
								
									
										590
									
								
								popup.go
								
								
								
								
							
							
						
						
									
										590
									
								
								popup.go
								
								
								
								
							|  | @ -44,23 +44,40 @@ const ( | |||
| 	Arrow = "arrow" | ||||
| 
 | ||||
| 	// 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)
 | ||||
| 	ArrowAlign = "arrow-align" | ||||
| 
 | ||||
| 	// 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" | ||||
| 
 | ||||
| 	// 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.
 | ||||
| 	// 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" | ||||
| 
 | ||||
| 	NoneArrow   = 0 | ||||
| 	TopArrow    = 1 | ||||
| 	RightArrow  = 2 | ||||
| 	// NoneArrow is value of the popup "arrow" property: no arrow
 | ||||
| 	NoneArrow = 0 | ||||
| 
 | ||||
| 	// 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 | ||||
| 	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.
 | ||||
|  | @ -90,27 +107,259 @@ type popupManager struct { | |||
| 	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) { | ||||
| 	popup.view = view | ||||
| 	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{ | ||||
| 		Style:               "ruiPopup", | ||||
| 		Row:                 popupRow, | ||||
| 		Column:              popupColumn, | ||||
| 		MaxWidth:            Percent(100), | ||||
| 		MaxHeight:           Percent(100), | ||||
| 		CellVerticalAlign:   StretchAlign, | ||||
| 		CellHorizontalAlign: StretchAlign, | ||||
| 		ClickEvent:          func(View) {}, | ||||
| 		Shadow: NewShadowWithParams(Params{ | ||||
| 			SpreadRadius: Px(4), | ||||
| 			Blur:         Px(16), | ||||
| 			ColorTag:     "@ruiPopupShadow", | ||||
| 		}), | ||||
| 	} | ||||
| 
 | ||||
| 	closeButton := false | ||||
| 	var closeButton View = nil | ||||
| 	outsideClose := false | ||||
| 	vAlign := CenterAlign | ||||
| 	hAlign := CenterAlign | ||||
| 	arrow := 0 | ||||
| 	arrowAlign := CenterAlign | ||||
| 	arrowSize := AutoSize() | ||||
| 	arrowOff := AutoSize() | ||||
| 	buttons := []PopupButton{} | ||||
| 	titleStyle := "ruiPopupTitle" | ||||
| 	var title View = nil | ||||
|  | @ -118,18 +367,42 @@ func (popup *popupData) init(view View, popupParams Params) { | |||
| 	for tag, value := range popupParams { | ||||
| 		if value != nil { | ||||
| 			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: | ||||
| 				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: | ||||
| 				outsideClose, _ = boolProperty(popupParams, OutsideClose, session) | ||||
| 
 | ||||
| 			case VerticalAlign: | ||||
| 				vAlign, _ = enumProperty(popupParams, VerticalAlign, session, CenterAlign) | ||||
| 
 | ||||
| 			case HorizontalAlign: | ||||
| 				hAlign, _ = enumProperty(popupParams, HorizontalAlign, session, CenterAlign) | ||||
| 
 | ||||
| 			case Buttons: | ||||
| 				switch value := value.(type) { | ||||
| 				case PopupButton: | ||||
|  | @ -169,9 +442,6 @@ func (popup *popupData) init(view View, popupParams Params) { | |||
| 					notCompatibleType(tag, value) | ||||
| 				} | ||||
| 
 | ||||
| 			case Arrow: | ||||
| 				arrow, _ = enumProperty(popupParams, Arrow, session, NoneArrow) | ||||
| 
 | ||||
| 			case ArrowAlign: | ||||
| 				switch text := value.(type) { | ||||
| 				case string: | ||||
|  | @ -183,13 +453,13 @@ func (popup *popupData) init(view View, popupParams Params) { | |||
| 						value = "right" | ||||
| 					} | ||||
| 				} | ||||
| 				arrowAlign, _ = enumProperty(popupParams, ArrowAlign, session, CenterAlign) | ||||
| 				arrow.align, _ = enumProperty(popupParams, ArrowAlign, session, CenterAlign) | ||||
| 
 | ||||
| 			case ArrowSize: | ||||
| 				arrowSize, _ = sizeProperty(popupParams, ArrowSize, session) | ||||
| 				arrow.size, _ = sizeProperty(popupParams, ArrowSize, session) | ||||
| 
 | ||||
| 			case ArrowOffset: | ||||
| 				arrowOff, _ = sizeProperty(popupParams, ArrowOffset, session) | ||||
| 				arrow.off, _ = sizeProperty(popupParams, ArrowOffset, session) | ||||
| 
 | ||||
| 			default: | ||||
| 				params[tag] = value | ||||
|  | @ -199,40 +469,29 @@ func (popup *popupData) init(view View, popupParams Params) { | |||
| 
 | ||||
| 	popupView := NewGridLayout(view.Session(), params) | ||||
| 
 | ||||
| 	var cellHeight []SizeUnit | ||||
| 	var popupCellHeight []SizeUnit | ||||
| 	viewRow := 0 | ||||
| 	if title != nil || closeButton { | ||||
| 		viewRow = 1 | ||||
| 		titleView := NewGridLayout(session, Params{ | ||||
| 	if title != nil || closeButton != nil { | ||||
| 		titleContent := []View{} | ||||
| 		if title != nil { | ||||
| 			titleContent = append(titleContent, title) | ||||
| 		} | ||||
| 		if closeButton != nil { | ||||
| 			titleContent = append(titleContent, closeButton) | ||||
| 		} | ||||
| 		popupView.Append(NewGridLayout(session, Params{ | ||||
| 			Row:               0, | ||||
| 			Style:             titleStyle, | ||||
| 			CellWidth:         []any{Fr(1), "@ruiPopupTitleHeight"}, | ||||
| 			CellWidth:         []any{Fr(1), AutoSize()}, | ||||
| 			CellVerticalAlign: CenterAlign, | ||||
| 			PaddingLeft:       Px(12), | ||||
| 		}) | ||||
| 		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() | ||||
| 				}, | ||||
| 			})) | ||||
| 		} | ||||
| 			Content:           titleContent, | ||||
| 		})) | ||||
| 
 | ||||
| 		popupView.Append(titleView) | ||||
| 		cellHeight = []SizeUnit{AutoSize(), Fr(1)} | ||||
| 		viewRow = 1 | ||||
| 		popupCellHeight = []SizeUnit{AutoSize(), Fr(1)} | ||||
| 	} else { | ||||
| 		cellHeight = []SizeUnit{Fr(1)} | ||||
| 		popupCellHeight = []SizeUnit{Fr(1)} | ||||
| 	} | ||||
| 
 | ||||
| 	view.Set(Row, viewRow) | ||||
|  | @ -240,7 +499,7 @@ func (popup *popupData) init(view View, popupParams Params) { | |||
| 
 | ||||
| 	if buttonCount := len(buttons); buttonCount > 0 { | ||||
| 		buttonsAlign, _ := enumProperty(params, ButtonsAlign, session, RightAlign) | ||||
| 		cellHeight = append(cellHeight, AutoSize()) | ||||
| 		popupCellHeight = append(popupCellHeight, AutoSize()) | ||||
| 		gap, _ := sizeConstant(session, "ruiPopupButtonGap") | ||||
| 		cellWidth := []SizeUnit{} | ||||
| 		for i := 0; i < buttonCount; i++ { | ||||
|  | @ -278,25 +537,16 @@ func (popup *popupData) init(view View, popupParams Params) { | |||
| 			Content:             buttonsPanel, | ||||
| 		})) | ||||
| 	} | ||||
| 	popupView.Set(CellHeight, cellHeight) | ||||
| 
 | ||||
| 	popup.layerView = NewGridLayout(session, Params{ | ||||
| 		Style:               "ruiPopupLayer", | ||||
| 		CellVerticalAlign:   vAlign, | ||||
| 		CellHorizontalAlign: hAlign, | ||||
| 		MaxWidth:            Percent(100), | ||||
| 		MaxHeight:           Percent(100), | ||||
| 		Filter: NewViewFilter(Params{ | ||||
| 			DropShadow: NewShadowWithParams(Params{ | ||||
| 				SpreadRadius: Px(4), | ||||
| 				Blur:         Px(16), | ||||
| 				ColorTag:     "@ruiPopupShadow", | ||||
| 			}), | ||||
| 		}), | ||||
| 		Content: NewColumnLayout(session, Params{ | ||||
| 			Content: popup.createArrow(arrow, arrowAlign, arrowSize, arrowOff, popupView), | ||||
| 		}), | ||||
| 	}) | ||||
| 	popupView.Set(CellHeight, popupCellHeight) | ||||
| 
 | ||||
| 	if arrow.location != NoneArrow { | ||||
| 		layerParams[Content] = []View{popupView, arrow.createView(popupView)} | ||||
| 	} else { | ||||
| 		layerParams[Content] = []View{popupView} | ||||
| 	} | ||||
| 
 | ||||
| 	popup.layerView = NewGridLayout(session, layerParams) | ||||
| 
 | ||||
| 	if outsideClose { | ||||
| 		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 { | ||||
| 	return popup.view | ||||
| } | ||||
|  |  | |||
|  | @ -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 { | ||||
| 	listeners, ok := valueToEventListeners[FilePicker, []FileInfo](value) | ||||
| 	listeners, ok := valueToEventListeners[View, Frame](value) | ||||
| 	if !ok { | ||||
| 		notCompatibleType(tag, value) | ||||
| 		return false | ||||
|  |  | |||
							
								
								
									
										11
									
								
								resources.go
								
								
								
								
							
							
						
						
									
										11
									
								
								resources.go
								
								
								
								
							|  | @ -3,7 +3,6 @@ package rui | |||
| import ( | ||||
| 	"embed" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
|  | @ -171,7 +170,7 @@ func registerImage(fs *embed.FS, path, filename 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 { | ||||
| 			filename := file.Name() | ||||
| 			if filename[0] != '.' { | ||||
|  | @ -189,7 +188,7 @@ func scanImagesDirectory(path, filePrefix 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 { | ||||
| 			filename := file.Name() | ||||
| 			if filename[0] != '.' { | ||||
|  | @ -197,7 +196,7 @@ func scanThemesDir(path string) { | |||
| 				if file.IsDir() { | ||||
| 					scanThemesDir(newPath) | ||||
| 				} 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)) | ||||
| 					} else { | ||||
| 						ErrorLog(err.Error()) | ||||
|  | @ -380,7 +379,7 @@ func AllRawResources() []string { | |||
| 	} | ||||
| 
 | ||||
| 	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 { | ||||
| 				result = append(result, file.Name()) | ||||
| 			} | ||||
|  | @ -388,7 +387,7 @@ func AllRawResources() []string { | |||
| 	} | ||||
| 
 | ||||
| 	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 { | ||||
| 				result = append(result, file.Name()) | ||||
| 			} | ||||
|  |  | |||
|  | @ -351,6 +351,8 @@ func (layout *stackLayoutData) Pop(animation int, onPopFinished func(View)) bool | |||
| 	buffer.WriteString(htmlID) | ||||
| 	buffer.WriteString(`pop" class="ruiStackPageLayout" ontransitionend="stackTransitionEndEvent(\'`) | ||||
| 	buffer.WriteString(htmlID) | ||||
| 	buffer.WriteString(`\', \'ruiPop\', event)" ontransitioncancel="stackTransitionEndEvent(\'`) | ||||
| 	buffer.WriteString(htmlID) | ||||
| 	buffer.WriteString(`\', \'ruiPop\', event)" style="transition: transform 1s ease;">`) | ||||
| 	viewHTML(layout.popView, buffer) | ||||
| 	buffer.WriteString(`</div>`) | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ package rui | |||
| 
 | ||||
| import ( | ||||
| 	"embed" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| ) | ||||
|  | @ -28,7 +28,7 @@ func scanEmbedStringsDir(fs *embed.FS, dir 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 { | ||||
| 			filename := file.Name() | ||||
| 			if filename[0] != '.' { | ||||
|  | @ -36,7 +36,7 @@ func scanStringsDir(path string) { | |||
| 				if file.IsDir() { | ||||
| 					scanStringsDir(newPath) | ||||
| 				} 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)) | ||||
| 					} else { | ||||
| 						ErrorLog(err.Error()) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue