func (l *List) LayoutChildren() { if l.adapter == nil { l.outer.RemoveAll() return } if !l.RelayoutSuspended() { // Disable relayout on AddChild / RemoveChild as we're performing layout here. l.SetRelayoutSuspended(true) defer l.SetRelayoutSuspended(false) } s := l.outer.Size().Contract(l.Padding()) o := l.Padding().LT() var itemSize math.Size if l.orientation.Horizontal() { itemSize = math.Size{W: l.itemSize.W, H: s.H} } else { itemSize = math.Size{W: s.W, H: l.itemSize.H} } startIndex, endIndex := l.VisibleItemRange(true) majorAxisItemSize := l.MajorAxisItemSize() d := startIndex*majorAxisItemSize - l.scrollOffset mark := l.layoutMark l.layoutMark++ for idx := startIndex; idx < endIndex; idx++ { item := l.adapter.ItemAt(idx) details, found := l.details[item] if found { if details.mark == mark { panic(fmt.Errorf("Adapter for control '%s' returned duplicate item (%v) for indices %v and %v", gxui.Path(l.outer), item, details.index, idx)) } } else { control := l.adapter.Create(l.theme, idx) details.onClickSubscription = control.OnClick(func(ev gxui.MouseEvent) { l.ItemClicked(ev, item) }) details.child = l.AddChildAt(0, control) } details.mark = mark details.index = idx l.details[item] = details c := details.child cm := c.Control.Margin() cs := itemSize.Contract(cm).Max(math.ZeroSize) if l.orientation.Horizontal() { c.Layout(math.CreateRect(d, cm.T, d+cs.W, cm.T+cs.H).Offset(o)) } else { c.Layout(math.CreateRect(cm.L, d, cm.L+cs.W, d+cs.H).Offset(o)) } d += majorAxisItemSize } // Reap unused items for item, details := range l.details { if details.mark != mark { details.onClickSubscription.Unlisten() l.RemoveChild(details.child.Control) delete(l.details, item) } } if l.scrollBarEnabled { ss := l.scrollBar.DesiredSize(math.ZeroSize, s) if l.Orientation().Horizontal() { l.scrollBarChild.Layout(math.CreateRect(0, s.H-ss.H, s.W, s.H).Canon().Offset(o)) } else { l.scrollBarChild.Layout(math.CreateRect(s.W-ss.W, 0, s.W, s.H).Canon().Offset(o)) } // Only show the scroll bar if needed entireContentVisible := startIndex == 0 && endIndex == l.itemCount l.scrollBar.SetVisible(!entireContentVisible) } l.UpdateItemMouseOver() }