mirror of https://github.com/anoshenko/rui.git
Added "list-row-gap" and "list-column-gap" properties
This commit is contained in:
parent
379d98fe4a
commit
6dad96c2a7
|
@ -2,10 +2,11 @@
|
|||
|
||||
* Requires go 1.18 or higher
|
||||
* The "interface{}" type replaced by "any"
|
||||
* Added "accent-color", "tab-size", "overflow", "arrow", "arrow-align", "arrow-size", "arrow-width", and "arrow-offset" properties
|
||||
* Added "list-row-gap", "list-column-gap", "accent-color", "tab-size", "overflow",
|
||||
"arrow", "arrow-align", "arrow-size", "arrow-width", and "arrow-offset" properties
|
||||
* Added "@ruiArrowSize" and "@ruiArrowWidth" constants to the default theme
|
||||
* Added Transition, Transitions, and SetTransition functions to the ViewStyle interface
|
||||
* Added GetAccentColor, GetTabSize, GetOverflow, IsTimingFunctionValid, and GetTransitions functions
|
||||
* Added GetListRowGap, GetListColumnGap, GetAccentColor, GetTabSize, GetOverflow, IsTimingFunctionValid, and GetTransitions functions
|
||||
* Changed GetTransition functions
|
||||
* Added the OpenURL function to the Session interface
|
||||
|
||||
|
|
12
README-ru.md
12
README-ru.md
|
@ -30,7 +30,7 @@
|
|||
В функции main вызывается функция StartApp. Она создает rui приложение и запускает его основной цикл.
|
||||
Функция StartApp имеет 3 параметра:
|
||||
1) IP адрес по которому будет доступно приложение (в нашем примере это "localhost:8000")
|
||||
2) Фуекция создает структуру реализующую интерфейс SessionContent
|
||||
2) Функция создает структуру реализующую интерфейс SessionContent
|
||||
3) Дополнительные опциональные параметры (в нашем примере это заголовок и имя файла иконки)
|
||||
|
||||
Интерфейс SessionContent объявлен как:
|
||||
|
@ -2205,6 +2205,11 @@ ListLayout является контейнером, реализующим ин
|
|||
| 2 | CenterAlign | "center" | Выравнивание по центру |
|
||||
| 3 | StretchAlign | "stretch" | Выравнивание по ширине |
|
||||
|
||||
### "list-row-gap" и "list-column-gap"
|
||||
|
||||
Свойства "list-row-gap" и "list-column-gap" (константы ListRowGap и ListColumnGap) типа SizeUnit позволяют
|
||||
установить соответственно расстояния между строками и столбцами контейнера. Значение по умолчанию 0.
|
||||
|
||||
## GridLayout
|
||||
|
||||
GridLayout является контейнером, реализующим интерфейс ViewsContainer. Для его создания используется функция
|
||||
|
@ -3226,6 +3231,11 @@ int8…int64, uint, uint8…uint64
|
|||
|
||||
func NewListView(session Session, params Params) ListView
|
||||
|
||||
ListView реализован на основе ListLayout и поэтому он поддерживает все свойства ListLayout:
|
||||
"orientation", "list-wrap", "vertical-align", "horizontal-align", "list-row-gap" и "list-column-gap".
|
||||
|
||||
Помимо эти свойств ListView имеет ещё следующие:
|
||||
|
||||
### Свойство "items"
|
||||
|
||||
Элементы списка задаются с помощью свойства "items" (константа Items). Основным значением
|
||||
|
|
12
README.md
12
README.md
|
@ -1,3 +1,5 @@
|
|||
[Russian](https://github.com/anoshenko/rui/blob/main/README-ru.md)
|
||||
|
||||
# RUI library
|
||||
|
||||
The RUI (Remote User Interface) library is designed to create web applications in the go language.
|
||||
|
@ -2183,6 +2185,11 @@ alignment of items in the list. Valid values:
|
|||
| 2 | CenterAlign | "center" | Center alignment |
|
||||
| 3 | StretchAlign | "stretch" | Width alignment |
|
||||
|
||||
### "list-row-gap" and "list-column-gap" properties
|
||||
|
||||
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.
|
||||
|
||||
## GridLayout
|
||||
|
||||
GridLayout is a container that implements the ViewsContainer interface. To create it, use the function
|
||||
|
@ -3193,6 +3200,11 @@ The ListView is created using the function:
|
|||
|
||||
func NewListView(session Session, params Params) ListView
|
||||
|
||||
ListView is implemented on top of ListLayout and therefore supports all ListLayout properties:
|
||||
"orientation", "list-wrap", "vertical-align", "horizontal-align", "list-row-gap", and "list-column-gap".
|
||||
|
||||
In addition to these properties ListView has the following:
|
||||
|
||||
### The "items" property
|
||||
|
||||
List items are set using the "items" property (Items constant).
|
||||
|
|
|
@ -250,11 +250,7 @@ func (gridLayout *gridLayoutData) set(tag string, value any) bool {
|
|||
}
|
||||
|
||||
if tag == Gap {
|
||||
if gridLayout.set(GridRowGap, value) && gridLayout.set(GridColumnGap, value) {
|
||||
gridLayout.propertyChangedEvent(Gap)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return gridLayout.set(GridRowGap, value) && gridLayout.set(GridColumnGap, value)
|
||||
}
|
||||
|
||||
if gridLayout.viewsContainerData.set(tag, value) {
|
||||
|
|
|
@ -58,6 +58,12 @@ func (listLayout *listLayoutData) normalizeTag(tag string) string {
|
|||
switch tag {
|
||||
case "wrap":
|
||||
tag = ListWrap
|
||||
|
||||
case "row-gap":
|
||||
return ListRowGap
|
||||
|
||||
case ColumnGap:
|
||||
return ListColumnGap
|
||||
}
|
||||
return tag
|
||||
}
|
||||
|
@ -66,11 +72,27 @@ func (listLayout *listLayoutData) Get(tag string) any {
|
|||
return listLayout.get(listLayout.normalizeTag(tag))
|
||||
}
|
||||
|
||||
func (listLayout *listLayoutData) get(tag string) any {
|
||||
if tag == Gap {
|
||||
if rowGap := GetListRowGap(listLayout, ""); rowGap.Equal(GetListColumnGap(listLayout, "")) {
|
||||
return rowGap
|
||||
}
|
||||
return AutoSize()
|
||||
}
|
||||
|
||||
return listLayout.viewsContainerData.get(tag)
|
||||
}
|
||||
|
||||
func (listLayout *listLayoutData) Remove(tag string) {
|
||||
listLayout.remove(listLayout.normalizeTag(tag))
|
||||
}
|
||||
|
||||
func (listLayout *listLayoutData) remove(tag string) {
|
||||
if tag == Gap {
|
||||
listLayout.remove(ListRowGap)
|
||||
listLayout.remove(ListColumnGap)
|
||||
return
|
||||
}
|
||||
listLayout.viewsContainerData.remove(tag)
|
||||
if listLayout.created {
|
||||
switch tag {
|
||||
|
@ -90,6 +112,10 @@ func (listLayout *listLayoutData) set(tag string, value any) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
if tag == Gap {
|
||||
return listLayout.set(ListRowGap, value) && listLayout.set(ListColumnGap, value)
|
||||
}
|
||||
|
||||
if listLayout.viewsContainerData.set(tag, value) {
|
||||
if listLayout.created {
|
||||
switch tag {
|
||||
|
@ -168,3 +194,15 @@ func GetListOrientation(view View, subviewID string) int {
|
|||
func GetListWrap(view View, subviewID string) int {
|
||||
return enumStyledProperty(view, subviewID, ListWrap, ListWrapOff, false)
|
||||
}
|
||||
|
||||
// GetListRowGap returns the gap between ListLayout or ListView rows.
|
||||
// If the second argument (subviewID) is "" then a value from the first argument (view) is returned.
|
||||
func GetListRowGap(view View, subviewID string) SizeUnit {
|
||||
return sizeStyledProperty(view, subviewID, ListRowGap, false)
|
||||
}
|
||||
|
||||
// GetListColumnGap returns the gap between ListLayout or ListView columns.
|
||||
// If the second argument (subviewID) is "" then a value from the first argument (view) is returned.
|
||||
func GetListColumnGap(view View, subviewID string) SizeUnit {
|
||||
return sizeStyledProperty(view, subviewID, ListColumnGap, false)
|
||||
}
|
||||
|
|
33
listView.go
33
listView.go
|
@ -110,6 +110,12 @@ func (listView *listViewData) normalizeTag(tag string) string {
|
|||
|
||||
case "wrap":
|
||||
tag = ListWrap
|
||||
|
||||
case "row-gap":
|
||||
return ListRowGap
|
||||
|
||||
case ColumnGap:
|
||||
return ListColumnGap
|
||||
}
|
||||
return tag
|
||||
}
|
||||
|
@ -120,6 +126,10 @@ func (listView *listViewData) Remove(tag string) {
|
|||
|
||||
func (listView *listViewData) remove(tag string) {
|
||||
switch tag {
|
||||
case Gap:
|
||||
listView.remove(ListRowGap)
|
||||
listView.remove(ListColumnGap)
|
||||
|
||||
case Checked:
|
||||
if len(listView.checkedItem) > 0 {
|
||||
listView.checkedItem = []int{}
|
||||
|
@ -204,6 +214,9 @@ func (listView *listViewData) set(tag string, value any) bool {
|
|||
}
|
||||
|
||||
switch tag {
|
||||
case Gap:
|
||||
return listView.set(ListRowGap, value) && listView.set(ListColumnGap, value)
|
||||
|
||||
case ListItemClickedEvent:
|
||||
listeners, ok := valueToEventListeners[ListView, int](value)
|
||||
if !ok {
|
||||
|
@ -264,7 +277,7 @@ func (listView *listViewData) set(tag string, value any) bool {
|
|||
listener(listView, current)
|
||||
}
|
||||
|
||||
case Orientation, ListWrap, VerticalAlign, HorizontalAlign, Style, StyleDisabled, ItemWidth, ItemHeight:
|
||||
case Orientation, ListWrap, ListRowGap, ListColumnGap, VerticalAlign, HorizontalAlign, Style, StyleDisabled, ItemWidth, ItemHeight:
|
||||
result := listView.viewData.set(tag, value)
|
||||
if result && listView.created {
|
||||
updateInnerHTML(listView.htmlID(), listView.session)
|
||||
|
@ -303,6 +316,12 @@ func (listView *listViewData) Get(tag string) any {
|
|||
|
||||
func (listView *listViewData) get(tag string) any {
|
||||
switch tag {
|
||||
case Gap:
|
||||
if rowGap := GetListRowGap(listView, ""); rowGap.Equal(GetListColumnGap(listView, "")) {
|
||||
return rowGap
|
||||
}
|
||||
return AutoSize()
|
||||
|
||||
case ListItemClickedEvent:
|
||||
return listView.clickedListeners
|
||||
|
||||
|
@ -875,6 +894,18 @@ func (listView *listViewData) htmlSubviews(self View, buffer *strings.Builder) {
|
|||
|
||||
buffer.WriteString(`<div style="display: flex; align-content: stretch;`)
|
||||
|
||||
if gap := GetListRowGap(listView, ""); gap.Type != Auto {
|
||||
buffer.WriteString(` row-gap: `)
|
||||
buffer.WriteString(gap.cssString("0"))
|
||||
buffer.WriteRune(';')
|
||||
}
|
||||
|
||||
if gap := GetListColumnGap(listView, ""); gap.Type != Auto {
|
||||
buffer.WriteString(` column-gap: `)
|
||||
buffer.WriteString(gap.cssString("0"))
|
||||
buffer.WriteRune(';')
|
||||
}
|
||||
|
||||
wrap := GetListWrap(listView, "")
|
||||
orientation := GetListOrientation(listView, "")
|
||||
rows := (orientation == StartToEndOrientation || orientation == EndToStartOrientation)
|
||||
|
|
|
@ -104,12 +104,14 @@ func ShowCancellableQuestion(title, text string, session Session, onYes func(),
|
|||
|
||||
type popupMenuData struct {
|
||||
items []string
|
||||
disabled []int
|
||||
session Session
|
||||
popup Popup
|
||||
result func(int)
|
||||
}
|
||||
|
||||
func (popup *popupMenuData) itemClick(list ListView, n int) {
|
||||
if popup.IsListItemEnabled(n) {
|
||||
if popup.popup != nil {
|
||||
popup.popup.Dismiss()
|
||||
popup.popup = nil
|
||||
|
@ -117,6 +119,7 @@ func (popup *popupMenuData) itemClick(list ListView, n int) {
|
|||
if popup.result != nil {
|
||||
popup.result(n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (popup *popupMenuData) ListSize() int {
|
||||
|
@ -131,6 +134,13 @@ func (popup *popupMenuData) ListItem(index int, session Session) View {
|
|||
}
|
||||
|
||||
func (popup *popupMenuData) IsListItemEnabled(index int) bool {
|
||||
if popup.disabled != nil {
|
||||
for _, n := range popup.disabled {
|
||||
if index == n {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -165,13 +175,18 @@ func ShowMenu(session Session, params Params) Popup {
|
|||
return nil
|
||||
}
|
||||
|
||||
value, ok = params[PopupMenuResult]
|
||||
if ok && value != nil {
|
||||
if value, ok := params[PopupMenuResult]; ok && value != nil {
|
||||
if result, ok := value.(func(int)); ok {
|
||||
data.result = result
|
||||
}
|
||||
}
|
||||
|
||||
if value, ok := params[DisabledItems]; ok && value != nil {
|
||||
if value, ok := value.([]int); ok {
|
||||
data.disabled = value
|
||||
}
|
||||
}
|
||||
|
||||
listView := NewListView(session, Params{
|
||||
Items: adapter,
|
||||
Orientation: TopDownOrientation,
|
||||
|
@ -181,7 +196,7 @@ func ShowMenu(session Session, params Params) Popup {
|
|||
popupParams := Params{}
|
||||
for tag, value := range params {
|
||||
switch tag {
|
||||
case Items, PopupMenuResult:
|
||||
case Items, PopupMenuResult, DisabledItems:
|
||||
// do nothing
|
||||
|
||||
default:
|
||||
|
|
|
@ -568,9 +568,19 @@ const (
|
|||
// Orientation is the constant for the "orientation" property tag.
|
||||
Orientation = "orientation"
|
||||
|
||||
// Gap is the constant for the "gap" property tag.
|
||||
// Gap is t he constant for the "gap" property tag.
|
||||
Gap = "gap"
|
||||
|
||||
// ListRowGap is the constant for the "list-row-gap" property tag.
|
||||
// The "list-row-gap" SizeUnit properties allow to set the distance between the rows of the ListLayout or ListView.
|
||||
// The default is 0px.
|
||||
ListRowGap = "list-row-gap"
|
||||
|
||||
// ListColumnGap is the constant for the "list-column-gap" property tag.
|
||||
// The "list-column-gap" SizeUnit properties allow to set the distance between the columns of the GridLayout or ListView.
|
||||
// The default is 0px.
|
||||
ListColumnGap = "list-column-gap"
|
||||
|
||||
// Text is the constant for the "text" property tag.
|
||||
Text = "text"
|
||||
|
||||
|
|
|
@ -110,6 +110,8 @@ var sizeProperties = map[string]string{
|
|||
WordSpacing: WordSpacing,
|
||||
LineHeight: LineHeight,
|
||||
TextLineThickness: "text-decoration-thickness",
|
||||
ListRowGap: "row-gap",
|
||||
ListColumnGap: "column-gap",
|
||||
GridRowGap: GridRowGap,
|
||||
GridColumnGap: GridColumnGap,
|
||||
ColumnWidth: ColumnWidth,
|
||||
|
|
|
@ -208,7 +208,7 @@ func (style *viewStyle) cssViewStyle(builder cssBuilder, session Session) {
|
|||
for _, tag := range []string{
|
||||
Width, Height, MinWidth, MinHeight, MaxWidth, MaxHeight, Left, Right, Top, Bottom,
|
||||
TextSize, TextIndent, LetterSpacing, WordSpacing, LineHeight, TextLineThickness,
|
||||
GridRowGap, GridColumnGap, ColumnGap, ColumnWidth} {
|
||||
ListRowGap, ListColumnGap, GridRowGap, GridColumnGap, ColumnGap, ColumnWidth} {
|
||||
|
||||
if size, ok := sizeProperty(style, tag, session); ok && size.Type != Auto {
|
||||
cssTag, ok := sizeProperties[tag]
|
||||
|
@ -799,7 +799,7 @@ func writeViewStyle(name string, view ViewStyle, buffer *strings.Builder, indent
|
|||
Opacity, ZIndex, Width, Height, MinWidth, MinHeight, MaxWidth, MaxHeight,
|
||||
Margin, Padding, BackgroundClip, BackgroundColor, Background, Border, Radius, Outline, Shadow,
|
||||
Orientation, ListWrap, VerticalAlign, HorizontalAlign, CellWidth, CellHeight,
|
||||
CellVerticalAlign, CellHorizontalAlign, GridRowGap, GridColumnGap,
|
||||
CellVerticalAlign, CellHorizontalAlign, ListRowGap, ListColumnGap, GridRowGap, GridColumnGap,
|
||||
ColumnCount, ColumnWidth, ColumnSeparator, ColumnGap, AvoidBreak,
|
||||
Current, Expanded, Side, ResizeBorderWidth, EditViewType, MaxLength, Hint, Text, EditWrap,
|
||||
TextOverflow, FontName, TextSize, TextColor, TextWeight, Italic, SmallCaps,
|
||||
|
|
Loading…
Reference in New Issue