Beispiel #1
0
func (t *TextBoxController) updateSelectionsForEdits(edits []TextBoxEdit) {
	min := 0
	max := len(t.text)
	selections := TextSelectionList{}
	for _, selection := range t.selections {
		for _, e := range edits {
			start := e.At
			if e.Delta < 0 {
				start -= e.Delta
			}
			delta := e.Delta
			if selection.start >= start {
				selection.start += delta
			}
			if selection.end >= start {
				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)
		selection = selection.Store()
		interval.Merge(&selections, selection)
	}
	t.selections = selections
}
Beispiel #2
0
func (t *TextBox) updateHorizScrollLimit() {
	maxWidth := t.MaxLineWidth()
	size := t.Size().Contract(t.outer.Padding())
	maxScroll := math.Max(maxWidth-size.W, 0)
	math.Clamp(t.horizOffset, 0, maxScroll)
	t.horizScroll.SetScrollLimit(maxWidth)
}
Beispiel #3
0
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()
	}
}
Beispiel #4
0
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())
		}
	}
}
Beispiel #5
0
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
}
Beispiel #6
0
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)
}
Beispiel #7
0
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
}