Пример #1
0
func ChildToParent(coord math.Point, from Control, to Parent) math.Point {
	c := from
	for {
		p := c.Parent()
		if p == nil {
			panic(fmt.Errorf("Control detached: %s", Path(c)))
		}
		child := p.Children().Find(c)
		if child == nil {
			Dump(p)
			panic(fmt.Errorf("Control's parent (%p %T) did not contain control (%p %T).", &p, p, &c, c))
		}
		coord = coord.Add(child.Offset)
		if p == to {
			return coord
		}

		if control, ok := p.(Control); ok {
			c = control
		} else {
			Dump(p)
			panic(fmt.Errorf("ChildToParent (%p %T) -> (%p %T) reached non-control parent (%p %T).",
				&from, from, &to, to, &p, p))
		}
	}
}
Пример #2
0
func (l *CodeEditorLine) PaintEditorSelections(c gxui.Canvas, info CodeEditorLinePaintInfo) {
	controller := l.textbox.controller

	ls, le := uint64(controller.LineStart(l.lineIndex)), uint64(controller.LineEnd(l.lineIndex))

	selections := controller.Selections()
	if l.textbox.selectionDragging {
		interval.Replace(&selections, l.textbox.selectionDrag)
	}
	interval.Visit(&selections, gxui.CreateTextSelection(int(ls), int(le), false), func(s, e uint64, _ int) {
		if s < e {
			var startOffset math.Point
			if s > ls {
				startOffset = l.endOfChar(info.GlyphOffsets[s-ls-1])
			}
			var endOffset math.Point
			if e > ls {
				endOffset = l.endOfChar(info.GlyphOffsets[e-ls-1])
			}

			width := endOffset.X - startOffset.X
			m := l.outer.MeasureRunes(int(s), int(e))
			m.W = width
			top := math.Point{X: l.caretWidth + startOffset.X, Y: 0}
			bottom := top.Add(m.Point())
			l.outer.PaintSelection(c, top, bottom)
		}
	})
}
Пример #3
0
func (i *Image) PixelAt(p math.Point) (math.Point, bool) {
	ir := i.calculateDrawRect()
	if tex := i.Texture(); tex != nil {
		s := tex.SizePixels()
		p = p.Sub(ir.Min).
			ScaleX(float32(s.W) / float32(ir.W())).
			ScaleY(float32(s.H) / float32(ir.H()))
		if s.Rect().Contains(p) {
			return p, true
		}
	}
	return math.Point{X: -1, Y: -1}, false
}
Пример #4
0
func (f *font) Measure(fl *gxui.TextBlock) math.Size {
	size := math.Size{W: 0, H: f.glyphMaxSizeDips.H}
	var offset math.Point
	for _, r := range fl.Runes {
		if r == '\n' {
			offset.X = 0
			offset.Y += f.glyphMaxSizeDips.H
			continue
		}
		offset.X += f.advanceDips(r)
		size = size.Max(math.Size{W: offset.X, H: offset.Y + f.glyphMaxSizeDips.H})
	}
	return size
}
Пример #5
0
func (c *Container) ContainsPoint(p math.Point) bool {
	if !c.outer.IsVisible() || !c.outer.Size().Rect().Contains(p) {
		return false
	}
	for _, v := range c.children {
		if v.Control.ContainsPoint(p.Sub(v.Offset)) {
			return true
		}
	}
	if c.IsMouseEventTarget() {
		return true
	}
	return false
}
Пример #6
0
func (t *DefaultTextBoxLine) PaintCarets(c gxui.Canvas) {
	controller := t.textbox.controller
	for i, cnt := 0, controller.SelectionCount(); i < cnt; i++ {
		e := controller.Caret(i)
		l := controller.LineIndex(e)
		if l == t.lineIndex {
			s := controller.LineStart(l)
			m := t.outer.MeasureRunes(s, e)
			top := math.Point{X: t.caretWidth + m.W, Y: 0}
			bottom := top.Add(math.Point{X: 0, Y: t.Size().H})
			t.outer.PaintCaret(c, top, bottom)
		}
	}
}
Пример #7
0
func TopControlsUnder(p math.Point, c Parent) ControlPointList {
	children := c.Children()
	for i := len(children) - 1; i >= 0; i-- {
		child := children[i]
		cp := p.Sub(child.Offset)
		if child.Control.ContainsPoint(cp) {
			l := ControlPointList{ControlPoint{child.Control, cp}}
			if cc, ok := child.Control.(Parent); ok {
				l = append(l, TopControlsUnder(cp, cc)...)
			}
			return l
		}
	}
	return ControlPointList{}
}
Пример #8
0
func BreadcrumbsAt(p Container, pnt math.Point) string {
	s := reflect.TypeOf(p).String()
	for _, c := range p.Children() {
		b := c.Control.Size().Rect().Offset(c.Offset)
		if b.Contains(pnt) {
			switch t := c.Control.(type) {
			case Container:
				return s + " > " + BreadcrumbsAt(t, pnt.Sub(c.Offset))
			default:
				return s + " > " + reflect.TypeOf(c.Control).String()
			}
		}
	}
	return s
}
Пример #9
0
func (l *CodeEditorLine) PaintEditorCarets(c gxui.Canvas, info CodeEditorLinePaintInfo) {
	controller := l.textbox.controller
	for i, count := 0, controller.SelectionCount(); i < count; i++ {
		caret := controller.Caret(i)
		line := controller.LineIndex(caret)
		if line == l.lineIndex {
			var offset math.Point
			start := controller.LineStart(line)
			if len(info.GlyphOffsets) > 0 && caret > start {
				caretOffsetIndex := caret - start - 1
				offset = l.endOfChar(info.GlyphOffsets[caretOffsetIndex])
			}
			top := math.Point{X: l.caretWidth + offset.X, Y: 0}
			bottom := top.Add(math.Point{X: 0, Y: l.Size().H})
			l.outer.PaintCaret(c, top, bottom)
		}
	}
}
Пример #10
0
func ControlsUnder(p math.Point, c Parent) ControlPointList {
	toVisit := []ParentPoint{ParentPoint{c, p}}
	l := ControlPointList{}
	for len(toVisit) > 0 {
		c = toVisit[0].C
		p = toVisit[0].P
		toVisit = toVisit[1:]
		for _, child := range c.Children() {
			cp := p.Sub(child.Offset)
			if child.Control.ContainsPoint(cp) {
				l = append(l, ControlPoint{child.Control, cp})
				if cc, ok := child.Control.(Parent); ok {
					toVisit = append(toVisit, ParentPoint{cc, cp})
				}
			}
		}
	}
	return l
}
Пример #11
0
func WindowToChild(coord math.Point, to Control) math.Point {
	c := to
	for {
		p := c.Parent()
		if p == nil {
			panic("Control's parent was nil")
		}
		child := p.Children().Find(c)
		if child == nil {
			Dump(p)
			panic(fmt.Errorf("Control's parent (%p %T) did not contain control (%p %T).", &p, p, &c, c))
		}
		coord = coord.Sub(child.Offset)
		if _, ok := p.(Window); ok {
			return coord
		}
		c = p.(Control)
	}
}
Пример #12
0
func (t *DefaultTextBoxLine) PaintSelections(c gxui.Canvas) {
	controller := t.textbox.controller

	ls, le := controller.LineStart(t.lineIndex), controller.LineEnd(t.lineIndex)

	selections := controller.Selections()
	if t.textbox.selectionDragging {
		interval.Replace(&selections, t.textbox.selectionDrag)
	}
	interval.Visit(&selections, gxui.CreateTextSelection(ls, le, false), func(s, e uint64, _ int) {
		if s < e {
			x := t.outer.MeasureRunes(ls, int(s)).W
			m := t.outer.MeasureRunes(int(s), int(e))
			top := math.Point{X: t.caretWidth + x, Y: 0}
			bottom := top.Add(m.Point())
			t.outer.PaintSelection(c, top, bottom)
		}
	})
}
Пример #13
0
func (l *ScrollLayout) SetScrollOffset(scrollOffset math.Point) bool {
	var cs math.Size
	if l.child != nil {
		cs = l.child.Control.Size()
	}

	s := l.innerSize
	scrollOffset = scrollOffset.Min(cs.Sub(s).Point()).Max(math.Point{})

	l.scrollBarX.Control.SetVisible(l.canScrollX && cs.W > s.W)
	l.scrollBarY.Control.SetVisible(l.canScrollY && cs.H > s.H)
	l.scrollBarX.Control.(gxui.ScrollBar).SetScrollPosition(l.scrollOffset.X, l.scrollOffset.X+s.W)
	l.scrollBarY.Control.(gxui.ScrollBar).SetScrollPosition(l.scrollOffset.Y, l.scrollOffset.Y+s.H)

	if l.scrollOffset != scrollOffset {
		l.scrollOffset = scrollOffset
		l.Relayout()
		return true
	}

	return false
}
Пример #14
0
func (f *font) Layout(fl *gxui.TextBlock) (offsets []math.Point) {
	sizeDips := math.Size{}
	offsets = make([]math.Point, len(fl.Runes))
	var offset math.Point
	for i, r := range fl.Runes {
		if r == '\n' {
			offset.X = 0
			offset.Y += f.glyphMaxSizeDips.H
			continue
		}

		offsets[i] = offset
		offset.X += f.advanceDips(r)
		sizeDips = sizeDips.Max(math.Size{W: offset.X, H: offset.Y + f.glyphMaxSizeDips.H})
	}

	origin := f.align(fl.AlignRect, sizeDips, f.ascentDips, fl.H, fl.V)
	for i, p := range offsets {
		offsets[i] = p.Add(origin)
	}
	return offsets
}
Пример #15
0
func (l *LinearLayout) DesiredSize(min, max math.Size) math.Size {
	if l.sizeMode.Fill() {
		return max
	}

	bounds := min.Rect()
	children := l.outer.Children()

	horizontal := l.direction.Orientation().Horizontal()
	offset := math.Point{X: 0, Y: 0}
	for _, c := range children {
		cs := c.Control.DesiredSize(math.ZeroSize, max)
		cm := c.Control.Margin()
		cb := cs.Expand(cm).Rect().Offset(offset)
		if horizontal {
			offset.X += cb.W()
		} else {
			offset.Y += cb.H()
		}
		bounds = bounds.Union(cb)
	}

	return bounds.Size().Expand(l.outer.Padding()).Clamp(min, max)
}
Пример #16
0
func (f *font) align(rect math.Rect, size math.Size, ascent int, h gxui.HorizontalAlignment, v gxui.VerticalAlignment) math.Point {
	var origin math.Point
	switch h {
	case gxui.AlignLeft:
		origin.X = rect.Min.X
	case gxui.AlignCenter:
		origin.X = rect.Mid().X - (size.W / 2)
	case gxui.AlignRight:
		origin.X = rect.Max.X - size.W
	}
	switch v {
	case gxui.AlignTop:
		origin.Y = rect.Min.Y + ascent
	case gxui.AlignMiddle:
		origin.Y = rect.Mid().Y - (size.H / 2) + ascent
	case gxui.AlignBottom:
		origin.Y = rect.Max.Y - size.H + ascent
	}
	return origin
}
Пример #17
0
func ParentToChild(coord math.Point, from Parent, to Control) math.Point {
	return coord.Sub(ChildToParent(math.ZeroPoint, to, from))
}
Пример #18
0
// endOfChar takes a position of a character and returns the position
// of its end.
func (l *CodeEditorLine) endOfChar(position math.Point) math.Point {
	return position.AddX(l.ce.Font().GlyphMaxSize().W / 2)
}
Пример #19
0
func (s *ScrollBar) positionAt(p math.Point) int {
	o := s.orientation
	frac := float32(o.Major(p.XY())) / float32(o.Major(s.Size().WH()))
	max := s.ScrollLimit()
	return int(float32(max) * frac)
}