uic: support for spacers

This commit is contained in:
mappu 2024-10-03 17:11:30 +13:00
parent 0ba1f0f6fa
commit 2c05d876f9
2 changed files with 67 additions and 45 deletions

View File

@ -5,9 +5,12 @@ import (
) )
type UiLayoutItem struct { type UiLayoutItem struct {
Row *int `xml:"row,attr"` Row *int `xml:"row,attr"`
Column *int `xml:"column,attr"` Column *int `xml:"column,attr"`
Widget UiWidget `xml:"widget"`
// A layout item either has a widget, or a spacer
Widget *UiWidget `xml:"widget"`
Spacer *UiSpacer `xml:"spacer"`
} }
type UiLayout struct { type UiLayout struct {
@ -20,6 +23,11 @@ type UiPropertyContainer struct {
Properties []UiProperty `xml:"property"` Properties []UiProperty `xml:"property"`
} }
type UiSpacer struct {
Name string `xml:"name,attr"`
Properties []UiProperty `xml:"property"`
}
type UiWidget struct { type UiWidget struct {
Class string `xml:"class,attr"` Class string `xml:"class,attr"`
Name string `xml:"name,attr"` Name string `xml:"name,attr"`

View File

@ -7,18 +7,23 @@ import (
"strings" "strings"
) )
func collectClassNames_Widget(u UiWidget) []string { func collectClassNames_Widget(u *UiWidget) []string {
var ret []string var ret []string
if u.Name != "" { if u.Name != "" {
ret = append(ret, u.Name+" *qt."+u.Class) ret = append(ret, u.Name+" *qt."+u.Class)
} }
for _, w := range u.Widgets { for _, w := range u.Widgets {
ret = append(ret, collectClassNames_Widget(w)...) ret = append(ret, collectClassNames_Widget(&w)...)
} }
if u.Layout != nil { if u.Layout != nil {
ret = append(ret, u.Layout.Name+" *qt."+u.Layout.Class) ret = append(ret, u.Layout.Name+" *qt."+u.Layout.Class)
for _, li := range u.Layout.Items { for _, li := range u.Layout.Items {
ret = append(ret, collectClassNames_Widget(li.Widget)...) if li.Widget != nil {
ret = append(ret, collectClassNames_Widget(li.Widget)...)
}
if li.Spacer != nil {
ret = append(ret, li.Spacer.Name+" *qt.QSpacerItem")
}
} }
} }
for _, a := range u.Actions { for _, a := range u.Actions {
@ -127,56 +132,65 @@ func generateWidget(w UiWidget, parentName string, parentClass string) (string,
ui.` + w.Layout.Name + `.SetObjectName(` + strconv.Quote(w.Layout.Name) + `) ui.` + w.Layout.Name + `.SetObjectName(` + strconv.Quote(w.Layout.Name) + `)
`) `)
for _, child := range w.Layout.Items { for i, child := range w.Layout.Items {
// Layout items have the parent as the real QWidget parent and are // A layout item is either a widget, or a spacer
// separately assigned to the layout afterwards
nest, err := generateWidget(child.Widget, `ui.`+w.Name, w.Class) if child.Spacer != nil {
if err != nil { ret.WriteString("/* miqt-uic: no handler for spacer */\n")
return "", fmt.Errorf(w.Name+": %w", err)
} }
ret.WriteString(nest) if child.Widget != nil {
// Assign to layout // Layout items have the parent as the real QWidget parent and are
// separately assigned to the layout afterwards
switch w.Layout.Class { nest, err := generateWidget(*child.Widget, `ui.`+w.Name, w.Class)
case `QFormLayout`: if err != nil {
// Row and Column are always populated. return "", fmt.Errorf(w.Name+"/Layout/Item[%d]: %w", i, err)
rowPos := fmt.Sprintf("%d", *child.Row)
var colPos string
if *child.Column == 0 {
colPos = `qt.QFormLayout__LabelRole`
} else if *child.Column == 1 {
colPos = `qt.QFormLayout__FieldRole`
} else {
ret.WriteString("/* miqt-uic: QFormLayout does not understand column index */\n")
continue
} }
// For QFormLayout it's SetWidget ret.WriteString(nest)
ret.WriteString(`
ui.` + w.Layout.Name + `.SetWidget(` + rowPos + `, ` + colPos + `, ` + qwidgetName(`ui.`+child.Widget.Name, child.Widget.Class) + `)
`)
case `QGridLayout`: // Assign to layout
// For QGridLayout it's AddWidget2
// FIXME in Miqt this function has optionals, needs to be called with the correct arity
// TODO support rowSpan, columnSpan
ret.WriteString(`
ui.` + w.Layout.Name + `.AddWidget2(` + qwidgetName(`ui.`+child.Widget.Name, child.Widget.Class) + `, ` + fmt.Sprintf("%d, %d", *child.Row, *child.Column) + `)
`)
case "QVBoxLayout", "QHBoxLayout": switch w.Layout.Class {
// For box layout it's AddWidget case `QFormLayout`:
ret.WriteString(` // Row and Column are always populated.
ui.` + w.Layout.Name + `.AddWidget(` + qwidgetName(`ui.`+child.Widget.Name, child.Widget.Class) + `) rowPos := fmt.Sprintf("%d", *child.Row)
`) var colPos string
if *child.Column == 0 {
colPos = `qt.QFormLayout__LabelRole`
} else if *child.Column == 1 {
colPos = `qt.QFormLayout__FieldRole`
} else {
ret.WriteString("/* miqt-uic: QFormLayout does not understand column index */\n")
continue
}
default: // For QFormLayout it's SetWidget
ret.WriteString("/* miqt-uic: no handler for layout '" + w.Layout.Class + "' */\n") ret.WriteString(`
ui.` + w.Layout.Name + `.SetWidget(` + rowPos + `, ` + colPos + `, ` + qwidgetName(`ui.`+child.Widget.Name, child.Widget.Class) + `)
`)
case `QGridLayout`:
// For QGridLayout it's AddWidget2
// FIXME in Miqt this function has optionals, needs to be called with the correct arity
// TODO support rowSpan, columnSpan
ret.WriteString(`
ui.` + w.Layout.Name + `.AddWidget2(` + qwidgetName(`ui.`+child.Widget.Name, child.Widget.Class) + `, ` + fmt.Sprintf("%d, %d", *child.Row, *child.Column) + `)
`)
case "QVBoxLayout", "QHBoxLayout":
// For box layout it's AddWidget
ret.WriteString(`
ui.` + w.Layout.Name + `.AddWidget(` + qwidgetName(`ui.`+child.Widget.Name, child.Widget.Class) + `)
`)
default:
ret.WriteString("/* miqt-uic: no handler for layout '" + w.Layout.Class + "' */\n")
}
} }
} }
} }
@ -301,7 +315,7 @@ import (
) )
type ` + u.Class + `Ui struct { type ` + u.Class + `Ui struct {
` + strings.Join(collectClassNames_Widget(u.Widget), "\n") + ` ` + strings.Join(collectClassNames_Widget(&u.Widget), "\n") + `
} }
// New` + u.Class + `Ui creates all Qt widget classes for ` + u.Class + `. // New` + u.Class + `Ui creates all Qt widget classes for ` + u.Class + `.