func (l *List) SetScrollOffset(scrollOffset int) { if l.adapter == nil { return } s := l.outer.Size().Contract(l.outer.Padding()) if l.orientation.Horizontal() { maxScroll := math.Max(l.itemSize.W*l.itemCount-s.W, 0) scrollOffset = math.Clamp(scrollOffset, 0, maxScroll) l.scrollBar.SetScrollPosition(scrollOffset, scrollOffset+s.W) } else { maxScroll := math.Max(l.itemSize.H*l.itemCount-s.H, 0) scrollOffset = math.Clamp(scrollOffset, 0, maxScroll) l.scrollBar.SetScrollPosition(scrollOffset, scrollOffset+s.H) } if l.scrollOffset != scrollOffset { l.scrollOffset = scrollOffset l.LayoutChildren() } }
func (l *CodeSyntaxLayer) UpdateSpans(runeCount int, edits []TextBoxEdit) { min := 0 max := runeCount for _, e := range edits { if l == nil { continue } for j, s := range l.spans { at := e.At start, end := s.Range() if start >= at { start = math.Clamp(start+e.Delta, min, max) } if end > at { end = math.Clamp(end+e.Delta, min, max) } if end < start { end = start } l.spans[j] = interval.CreateIntData(start, end, s.Data()) } } }
func (t *TextBoxController) updateSelectionsForEdits(edits []TextBoxEdit) { min := 0 max := len(t.text) selections := TextSelectionList{} for _, selection := range t.selections { for _, e := range edits { at := e.At delta := e.Delta if selection.start > at { selection.start += delta } if selection.end >= at { selection.end += delta } } if selection.end < selection.start { selection.end = selection.start } selection.start = math.Clamp(selection.start, min, max) selection.end = math.Clamp(selection.end, min, max) interval.Merge(&selections, selection) } t.selections = selections }
func (s *ScrollBar) updateBarRect() { sf, st := s.ScrollFraction() size := s.Size() b := size.Rect() halfMinLen := s.minBarLength / 2 if s.orientation.Horizontal() { b.Min.X = math.Lerp(0, size.W, sf) b.Max.X = math.Lerp(0, size.W, st) if b.W() < s.minBarLength { c := (b.Min.X + b.Max.X) / 2 c = math.Clamp(c, b.Min.X+halfMinLen, b.Max.X-halfMinLen) b.Min.X, b.Max.X = c-halfMinLen, c+halfMinLen } } else { b.Min.Y = math.Lerp(0, size.H, sf) b.Max.Y = math.Lerp(0, size.H, st) if b.H() < s.minBarLength { c := (b.Min.Y + b.Max.Y) / 2 c = math.Clamp(c, b.Min.Y+halfMinLen, b.Max.Y-halfMinLen) b.Min.Y, b.Max.Y = c-halfMinLen, c+halfMinLen } } s.barRect = b }
func (s *ScrollBar) rangeAt(p math.Point) (from, to int) { width := s.scrollPositionTo - s.scrollPositionFrom from = math.Clamp(s.positionAt(p), 0, s.scrollLimit-width) to = from + width return }
func (o *BubbleOverlay) Paint(c gxui.Canvas) { if !o.IsVisible() { return } for _, child := range o.outer.Children() { b := child.Bounds().Expand(o.outer.Padding()) t := o.targetPoint a := o.arrowWidth / 2 var p gxui.Polygon switch { case t.X < b.Min.X: /* A-----------------B G | F | E | D-----------------C */ p = gxui.Polygon{ /*A*/ {Position: b.TL(), RoundedRadius: 5}, /*B*/ {Position: b.TR(), RoundedRadius: 5}, /*C*/ {Position: b.BR(), RoundedRadius: 5}, /*D*/ {Position: b.BL(), RoundedRadius: 5}, /*E*/ {Position: math.Point{X: b.Min.X, Y: math.Clamp(t.Y+a, b.Min.Y+a, b.Max.Y)}, RoundedRadius: 0}, /*F*/ {Position: t, RoundedRadius: 0}, /*G*/ {Position: math.Point{X: b.Min.X, Y: math.Clamp(t.Y-a, b.Min.Y, b.Max.Y-a)}, RoundedRadius: 0}, } // fmt.Printf("A: %+v\n", p) case t.X > b.Max.X: /* A-----------------B | C | D | E G-----------------F */ p = gxui.Polygon{ /*A*/ {Position: b.TL(), RoundedRadius: 5}, /*B*/ {Position: b.TR(), RoundedRadius: 5}, /*C*/ {Position: math.Point{X: b.Max.X, Y: math.Clamp(t.Y-a, b.Min.Y, b.Max.Y-a)}, RoundedRadius: 0}, /*D*/ {Position: t, RoundedRadius: 0}, /*E*/ {Position: math.Point{X: b.Max.X, Y: math.Clamp(t.Y+a, b.Min.Y+a, b.Max.Y)}, RoundedRadius: 0}, /*F*/ {Position: b.BR(), RoundedRadius: 5}, /*G*/ {Position: b.BL(), RoundedRadius: 5}, } // fmt.Printf("B: %+v\n", p) case t.Y < b.Min.Y: /* C / \ A-----------B D-E | | | | G-----------------F */ p = gxui.Polygon{ /*A*/ {Position: b.TL(), RoundedRadius: 5}, /*B*/ {Position: math.Point{X: math.Clamp(t.X-a, b.Min.X, b.Max.X-a), Y: b.Min.Y}, RoundedRadius: 0}, /*C*/ {Position: t, RoundedRadius: 0}, /*D*/ {Position: math.Point{X: math.Clamp(t.X+a, b.Min.X+a, b.Max.X), Y: b.Min.Y}, RoundedRadius: 0}, /*E*/ {Position: b.TR(), RoundedRadius: 5}, /*F*/ {Position: b.BR(), RoundedRadius: 5}, /*G*/ {Position: b.BL(), RoundedRadius: 5}, } // fmt.Printf("C: %+v\n", p) default: /* A-----------------B | | | | G-----------F D-C \ / E */ p = gxui.Polygon{ /*A*/ {Position: b.TL(), RoundedRadius: 5}, /*B*/ {Position: b.TR(), RoundedRadius: 5}, /*C*/ {Position: b.BR(), RoundedRadius: 5}, /*D*/ {Position: math.Point{X: math.Clamp(t.X+a, b.Min.X+a, b.Max.X), Y: b.Max.Y}, RoundedRadius: 0}, /*E*/ {Position: t, RoundedRadius: 0}, /*F*/ {Position: math.Point{X: math.Clamp(t.X-a, b.Min.X, b.Max.X-a), Y: b.Max.Y}, RoundedRadius: 0}, /*G*/ {Position: b.BL(), RoundedRadius: 5}, } // fmt.Printf("D: %+v\n", p) } c.DrawPolygon(p, o.pen, o.brush) } o.PaintChildren.Paint(c) }