Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 24 additions & 23 deletions core/form.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"slices"
"strings"

"cogentcore.org/core/base/keylist"
"cogentcore.org/core/base/reflectx"
"cogentcore.org/core/base/strcase"
"cogentcore.org/core/colors"
Expand All @@ -35,8 +36,8 @@ type Form struct {
// and resetting logic. Ignored if nil.
Modified map[string]bool

// structFields are the fields of the current struct.
structFields []*structField
// structFields are the fields of the current struct, keys are field paths.
structFields keylist.List[string, *structField]

// isShouldDisplayer is whether the struct implements [ShouldDisplayer], which results
// in additional updating being done at certain points.
Expand Down Expand Up @@ -79,7 +80,7 @@ type ShouldDisplayer interface {
func (fm *Form) WidgetValue() any { return &fm.Struct }

func (fm *Form) getStructFields() {
var fields []*structField
var fields keylist.List[string, *structField]

shouldShow := func(parent reflect.Value, field reflect.StructField) bool {
if field.Tag.Get("display") == "-" {
Expand Down Expand Up @@ -109,10 +110,11 @@ func (fm *Form) getStructFields() {
if field.Tag.Get("edit") == "-" && sfield.Tag.Get("edit") == "" {
sfield.Tag += ` edit:"-"`
}
fields = append(fields, &structField{path: field.Name + " • " + sfield.Name, field: sfield, value: value, parent: parent})
path := field.Name + " • " + sfield.Name
fields.Add(path, &structField{path: path, field: sfield, value: value, parent: parent})
})
} else {
fields = append(fields, &structField{path: field.Name, field: field, value: value, parent: parent})
fields.Add(field.Name, &structField{path: field.Name, field: field, value: value, parent: parent})
}
})
fm.structFields = fields
Expand Down Expand Up @@ -145,15 +147,17 @@ func (fm *Form) Init() {
sc = !noSentenceCaseForType(types.TypeNameValue(fm.Struct))
}

for i, f := range fm.structFields {
for i := range fm.structFields.Len() {
f := fm.structFields.Values[i]
fieldPath := fm.structFields.Keys[i]
label := f.path
if sc {
label = strcase.ToSentence(label)
}
if lt, ok := f.field.Tag.Lookup("label"); ok {
label = lt
}
labnm := fmt.Sprintf("label-%s", f.path)
labnm := fmt.Sprintf("label-%s", fieldPath)
// we must have a different name for different types
// so that the widget can be re-made for a new type
typnm := reflectx.ShortTypeName(f.field.Type)
Expand All @@ -162,12 +166,11 @@ func (fm *Form) Init() {
if !reflectx.Underlying(f.value).IsValid() {
typnm = "invalid"
}
// We must have a different name for different indexes so that the index
// is always guaranteed to be accurate, which is required since we use it
// as the ground truth everywhere. The index could otherwise become invalid,
// such as when a ShouldDisplayer condition is newly satisfied
// (see https://github.com/cogentcore/core/issues/1096).
valnm := fmt.Sprintf("value-%s-%s-%d", f.path, typnm, i)
// Using the type name ensures that widgets are specific to the type,
// even if they happen to have the same name. Using the path to index
// the structFields ensures safety against any [ShouldDisplayer]
// updates (see #1390).
valnm := fmt.Sprintf("value-%s-%s", fieldPath, typnm)
readOnlyTag := f.field.Tag.Get("edit") == "-"
def, hasDef := f.field.Tag.Lookup("default")

Expand All @@ -190,7 +193,7 @@ func (fm *Form) Init() {
}
var isDef bool
w.Styler(func(s *styles.Style) {
f := fm.structFields[i]
f := fm.structFields.At(fieldPath)
dcr := "(Double click to reset to default) "
if fm.Modified != nil {
isDef = !fm.Modified[f.path]
Expand All @@ -209,7 +212,7 @@ func (fm *Form) Init() {
}
})
w.OnDoubleClick(func(e events.Event) {
f := fm.structFields[i]
f := fm.structFields.At(fieldPath)
if isDef {
return
}
Expand Down Expand Up @@ -254,7 +257,7 @@ func (fm *Form) Init() {
wb.SetTooltip("(Default: " + def + ") " + wb.Tooltip)
}
wb.OnInput(func(e events.Event) {
f := fm.structFields[i]
f := fm.structFields.At(fieldPath)
fm.Send(events.Input, e)
if f.field.Tag.Get("immediate") == "+" {
wb.SendChange(e)
Expand All @@ -276,13 +279,11 @@ func (fm *Form) Init() {
}
wb.Updater(func() {
wb.SetReadOnly(fm.IsReadOnly() || readOnlyTag)
if i < len(fm.structFields) {
f := fm.structFields[i]
Bind(reflectx.UnderlyingPointer(f.value).Interface(), w)
vc := joinValueTitle(fm.ValueTitle, label)
if vc != wb.ValueTitle {
wb.ValueTitle = vc + " (" + wb.ValueTitle + ")"
}
f := fm.structFields.At(fieldPath)
Bind(reflectx.UnderlyingPointer(f.value).Interface(), w)
vc := joinValueTitle(fm.ValueTitle, label)
if vc != wb.ValueTitle {
wb.ValueTitle = vc + " (" + wb.ValueTitle + ")"
}
})
})
Expand Down
4 changes: 2 additions & 2 deletions core/layout.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,13 +294,13 @@ func (ls *geomState) contentRangeDim(d math32.Dims) (cmin, cmax float32) {
// totalRect returns Pos.Total -- Size.Actual.Total
// as an image.Rectangle, e.g., for bounding box
func (ls *geomState) totalRect() image.Rectangle {
return math32.RectFromPosSizeMax(ls.Pos.Total, ls.Size.Actual.Total)
return math32.RectFromPosSizeMax(ls.Pos.Total, ls.Size.Alloc.Total)
}

// contentRect returns Pos.Content, Size.Actual.Content
// as an image.Rectangle, e.g., for bounding box.
func (ls *geomState) contentRect() image.Rectangle {
return math32.RectFromPosSizeMax(ls.Pos.Content, ls.Size.Actual.Content)
return math32.RectFromPosSizeMax(ls.Pos.Content, ls.Size.Alloc.Content)
}

// ScrollOffset computes the net scrolling offset as a function of
Expand Down
7 changes: 6 additions & 1 deletion core/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,11 @@ func (tr *Tree) Position() {
sz.Actual.Total.X = rn.Geom.Size.Actual.Total.X - (tr.Geom.Pos.Total.X - rn.Geom.Pos.Total.X)
sz.Actual.Content.X = sz.Actual.Total.X - sz.Space.X
tr.widgetSize.X = sz.Actual.Total.X
sz.Alloc = sz.Actual
psz := &tr.Parts.Geom.Size
psz.Alloc.Total = tr.widgetSize
psz.setContentFromTotal(&psz.Alloc)

tr.WidgetBase.Position() // just does our parts

if !tr.Closed {
Expand All @@ -619,7 +624,7 @@ func (tr *Tree) ApplyScenePos() {
}
tr.WidgetBase.ApplyScenePos()
tr.applyScenePosChildren()
tr.Geom.Size.Actual.Total = tr.widgetSize // key: we revert to just ourselves
sz.Actual.Total = tr.widgetSize // key: we revert to just ourselves
}

func (tr *Tree) Render() {
Expand Down
10 changes: 5 additions & 5 deletions examples/demo/demo.go
Original file line number Diff line number Diff line change
Expand Up @@ -442,14 +442,14 @@ type tableStruct struct { //types:add

type inlineStruct struct { //types:add

// click to show next
On bool

// this is now showing
ShowMe string

// click to show next
On bool

// a condition
Condition int
Condition int `default:"0"`

// if On && Condition == 0
Condition1 string
Expand All @@ -458,7 +458,7 @@ type inlineStruct struct { //types:add
Condition2 tableStruct

// a value
Value float32
Value float32 `default:"1"`
}

func (il *inlineStruct) ShouldDisplay(field string) bool {
Expand Down
Loading