ASDlkjas;ldkj
This commit is contained in:
		
							parent
							
								
									5661608233
								
							
						
					
					
						commit
						4259e8f021
					
				
							
								
								
									
										31
									
								
								box.go
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								box.go
									
									
									
									
									
								
							@ -251,7 +251,10 @@ func (this *box) doDraw () {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *box) doLayout () {
 | 
			
		||||
	this.canvas = this.parent.canvas().Clip(this.bounds)
 | 
			
		||||
	if this.parent == nil { this.canvas = nil; return  }
 | 
			
		||||
	parentCanvas := this.parent.canvas()
 | 
			
		||||
	if parentCanvas == nil { this.canvas = nil; return }
 | 
			
		||||
	this.canvas = parentCanvas.Clip(this.bounds)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *box) setParent (parent parent) {
 | 
			
		||||
@ -274,7 +277,31 @@ func (this *box) invalidateDraw () {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *box) recalculateMinimumSize () {
 | 
			
		||||
	if this.outer != this {
 | 
			
		||||
	if this.outer != anyBox(this) {
 | 
			
		||||
		this.outer.recalculateMinimumSize()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *box) canBeFocused () bool {
 | 
			
		||||
	return this.focusable
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *box) boxUnder (point image.Point) anyBox {
 | 
			
		||||
	if point.In(this.bounds) {
 | 
			
		||||
		return this.outer
 | 
			
		||||
	} else {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *box) handleMouseDown (button input.Button) {
 | 
			
		||||
	for _, listener := range this.on.mouseDown.Listeners() {
 | 
			
		||||
		listener(button)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *box) handleMouseUp (button input.Button) {
 | 
			
		||||
	for _, listener := range this.on.mouseUp.Listeners() {
 | 
			
		||||
		listener(button)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -13,9 +13,10 @@ type containerBox struct {
 | 
			
		||||
	contentBounds image.Rectangle
 | 
			
		||||
	scroll        image.Point
 | 
			
		||||
	
 | 
			
		||||
	gap      image.Point
 | 
			
		||||
	children []tomo.Box
 | 
			
		||||
	layout   tomo.Layout
 | 
			
		||||
	gap             image.Point
 | 
			
		||||
	children        []tomo.Box
 | 
			
		||||
	layout          tomo.Layout
 | 
			
		||||
	propagateEvents bool
 | 
			
		||||
 | 
			
		||||
	on struct {
 | 
			
		||||
		contentBoundsChange event.FuncBroadcaster
 | 
			
		||||
@ -24,7 +25,8 @@ type containerBox struct {
 | 
			
		||||
 | 
			
		||||
func (backend *Backend) NewContainerBox() tomo.ContainerBox {
 | 
			
		||||
	box := &containerBox {
 | 
			
		||||
		box: backend.NewBox().(*box),
 | 
			
		||||
		box:             backend.NewBox().(*box),
 | 
			
		||||
		propagateEvents: true,
 | 
			
		||||
	}
 | 
			
		||||
	box.drawer = box
 | 
			
		||||
	box.outer  = box
 | 
			
		||||
@ -63,6 +65,10 @@ func (this *containerBox) OnContentBoundsChange (callback func()) event.Cookie {
 | 
			
		||||
	return this.on.contentBoundsChange.Connect(callback)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *containerBox) PropagateEvents (propagate bool) {
 | 
			
		||||
	this.propagateEvents = propagate
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *containerBox) SetGap (gap image.Point) {
 | 
			
		||||
	if this.gap == gap { return }
 | 
			
		||||
	this.gap = gap
 | 
			
		||||
@ -210,3 +216,14 @@ func (this *containerBox) recursiveRedo () {
 | 
			
		||||
		child.(anyBox).recursiveRedo()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *containerBox) boxUnder (point image.Point) anyBox {
 | 
			
		||||
	if this.propagateEvents {
 | 
			
		||||
		for _, box := range this.children {
 | 
			
		||||
			candidate := box.(anyBox).boxUnder(point)
 | 
			
		||||
			if candidate != nil { return candidate }
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return this.box.boxUnder(point)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										71
									
								
								event.go
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								event.go
									
									
									
									
									
								
							@ -4,7 +4,9 @@ import "image"
 | 
			
		||||
 | 
			
		||||
import "github.com/jezek/xgbutil"
 | 
			
		||||
import "github.com/jezek/xgb/xproto"
 | 
			
		||||
import "git.tebibyte.media/tomo/xgbkb"
 | 
			
		||||
import "github.com/jezek/xgbutil/xevent"
 | 
			
		||||
import "git.tebibyte.media/tomo/tomo/input"
 | 
			
		||||
 | 
			
		||||
func (window *window) handleExpose (
 | 
			
		||||
	connection *xgbutil.XUtil,
 | 
			
		||||
@ -72,6 +74,61 @@ func (window *window) exposeEventFollows (event xproto.ConfigureNotifyEvent) (fo
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func (window *window) handleButtonPress (
 | 
			
		||||
	connection *xgbutil.XUtil,
 | 
			
		||||
	event xevent.ButtonPressEvent,
 | 
			
		||||
) {
 | 
			
		||||
	if window.hasModal { return }
 | 
			
		||||
	
 | 
			
		||||
	buttonEvent  := *event.ButtonPressEvent
 | 
			
		||||
	point        := image.Pt(int(buttonEvent.EventX), int(buttonEvent.EventY))
 | 
			
		||||
	insideWindow := point.In(window.xCanvas.Bounds())
 | 
			
		||||
	scrolling    := buttonEvent.Detail >= 4 && buttonEvent.Detail <= 7
 | 
			
		||||
	window.updateModifiers(buttonEvent.State)
 | 
			
		||||
	window.updateMousePosition(buttonEvent.EventX, buttonEvent.EventY)
 | 
			
		||||
 | 
			
		||||
	if !insideWindow && window.shy && !scrolling {
 | 
			
		||||
		window.Close()
 | 
			
		||||
	} else if scrolling {
 | 
			
		||||
		// underneath := window.scrollTargetChildAt(point)
 | 
			
		||||
		// if underneath != nil {
 | 
			
		||||
			// if child, ok := underneath.element.(ability.ScrollTarget); ok {
 | 
			
		||||
				// sum := scrollSum { }
 | 
			
		||||
				// sum.add(buttonEvent.Detail, window, buttonEvent.State)
 | 
			
		||||
				// window.compressScrollSum(buttonEvent, &sum)
 | 
			
		||||
				// child.HandleScroll (
 | 
			
		||||
					// point, float64(sum.x), float64(sum.y),
 | 
			
		||||
					// modifiers)
 | 
			
		||||
			// }
 | 
			
		||||
		// }
 | 
			
		||||
	} else {
 | 
			
		||||
		underneath := window.boxUnder(point)
 | 
			
		||||
		window.drags[buttonEvent.Detail] = underneath
 | 
			
		||||
		if underneath != nil {
 | 
			
		||||
			underneath.handleMouseDown(input.Button(buttonEvent.Detail))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (window *window) handleButtonRelease (
 | 
			
		||||
	connection *xgbutil.XUtil,
 | 
			
		||||
	event xevent.ButtonReleaseEvent,
 | 
			
		||||
) {
 | 
			
		||||
	if window.hasModal { return }
 | 
			
		||||
	
 | 
			
		||||
	buttonEvent := *event.ButtonReleaseEvent
 | 
			
		||||
	if buttonEvent.Detail >= 4 && buttonEvent.Detail <= 7 { return }
 | 
			
		||||
	window.updateModifiers(buttonEvent.State)
 | 
			
		||||
	window.updateMousePosition(buttonEvent.EventX, buttonEvent.EventY)
 | 
			
		||||
	dragging := window.drags[buttonEvent.Detail]
 | 
			
		||||
	
 | 
			
		||||
	if dragging != nil {
 | 
			
		||||
		dragging.handleMouseUp(input.Button(buttonEvent.Detail))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func (window *window) compressExpose (
 | 
			
		||||
	firstEvent xproto.ExposeEvent,
 | 
			
		||||
) (
 | 
			
		||||
@ -136,3 +193,17 @@ func (window *window) compressConfigureNotify (
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (window *window) updateModifiers (state uint16) {
 | 
			
		||||
	modifiers := xgbkb.StateToModifiers(state)
 | 
			
		||||
	window.modifiers.Shift   = modifiers.Shift || modifiers.ShiftLock
 | 
			
		||||
	window.modifiers.Control = modifiers.Control
 | 
			
		||||
	window.modifiers.Alt     = modifiers.Alt
 | 
			
		||||
	window.modifiers.Meta    = modifiers.Meta
 | 
			
		||||
	window.modifiers.Super   = modifiers.Super
 | 
			
		||||
	window.modifiers.Hyper   = modifiers.Hyper
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (window *window) updateMousePosition (x, y int16) {
 | 
			
		||||
	window.mousePosition = image.Pt(int(x), int(y))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.mod
									
									
									
									
									
								
							@ -4,8 +4,8 @@ go 1.20
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	git.tebibyte.media/tomo/ggfx v0.4.0
 | 
			
		||||
	git.tebibyte.media/tomo/tomo v0.14.0
 | 
			
		||||
	git.tebibyte.media/tomo/typeset v0.3.0
 | 
			
		||||
	git.tebibyte.media/tomo/tomo v0.16.0
 | 
			
		||||
	git.tebibyte.media/tomo/typeset v0.4.0
 | 
			
		||||
	git.tebibyte.media/tomo/xgbkb v1.0.1
 | 
			
		||||
	github.com/jezek/xgb v1.1.0
 | 
			
		||||
	github.com/jezek/xgbutil v0.0.0-20230603163917-04188eb39cf0
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								go.sum
									
									
									
									
									
								
							@ -9,12 +9,18 @@ git.tebibyte.media/tomo/tomo v0.13.0 h1:xQvEia1vDUfq3QkpU3De72z53ON+y8I6HMP8TDtc
 | 
			
		||||
git.tebibyte.media/tomo/tomo v0.13.0/go.mod h1:lTwjpiHbP4UN/kFw+6FwhG600B+PMKVtMOr7wpd5IUY=
 | 
			
		||||
git.tebibyte.media/tomo/tomo v0.14.0 h1:cMCOLjBEH9OtF+CODn0XFWa9liE0keMnLWs3t66I+Zw=
 | 
			
		||||
git.tebibyte.media/tomo/tomo v0.14.0/go.mod h1:lTwjpiHbP4UN/kFw+6FwhG600B+PMKVtMOr7wpd5IUY=
 | 
			
		||||
git.tebibyte.media/tomo/tomo v0.15.0 h1:xjHPB+nq1M2myjFeRU79p3DvuIIG/94hKwFr/OB8cGY=
 | 
			
		||||
git.tebibyte.media/tomo/tomo v0.15.0/go.mod h1:lTwjpiHbP4UN/kFw+6FwhG600B+PMKVtMOr7wpd5IUY=
 | 
			
		||||
git.tebibyte.media/tomo/tomo v0.16.0 h1:5tgN0Uj+3LSMzvXRLNE8AxgRUOTc/GEw8+TEJKmVGtQ=
 | 
			
		||||
git.tebibyte.media/tomo/tomo v0.16.0/go.mod h1:lTwjpiHbP4UN/kFw+6FwhG600B+PMKVtMOr7wpd5IUY=
 | 
			
		||||
git.tebibyte.media/tomo/typeset v0.1.0 h1:ZLwQzy51vUskjg1nB4Emjag8VXn3ki2jEkE19kwVQ4c=
 | 
			
		||||
git.tebibyte.media/tomo/typeset v0.1.0/go.mod h1:PwDpSdBF3l/EzoIsa2ME7QffVVajnTHZN6l3MHEGe1g=
 | 
			
		||||
git.tebibyte.media/tomo/typeset v0.2.0 h1:7DcnB0sW12eL+MxkEMv99eVG2IQxsZHDDK6pz6VE1O8=
 | 
			
		||||
git.tebibyte.media/tomo/typeset v0.2.0/go.mod h1:PwDpSdBF3l/EzoIsa2ME7QffVVajnTHZN6l3MHEGe1g=
 | 
			
		||||
git.tebibyte.media/tomo/typeset v0.3.0 h1:9koJzy0bguBHjlesrHpXK8odIVEMmQRBIFIRXDhv7Bk=
 | 
			
		||||
git.tebibyte.media/tomo/typeset v0.3.0/go.mod h1:PwDpSdBF3l/EzoIsa2ME7QffVVajnTHZN6l3MHEGe1g=
 | 
			
		||||
git.tebibyte.media/tomo/typeset v0.4.0 h1:JdTmbqSJlMtdvqlwXC5AseM1GgG4tyfWcqPFGkHFRpU=
 | 
			
		||||
git.tebibyte.media/tomo/typeset v0.4.0/go.mod h1:PwDpSdBF3l/EzoIsa2ME7QffVVajnTHZN6l3MHEGe1g=
 | 
			
		||||
git.tebibyte.media/tomo/xgbkb v1.0.1 h1:b3HDUopjdQp1MZrb5Vpil4bOtk3NnNXtfQW27Blw2kE=
 | 
			
		||||
git.tebibyte.media/tomo/xgbkb v1.0.1/go.mod h1:P5Du0yo5hUsojchW08t+Mds0XPIJXwMi733ZfklzjRw=
 | 
			
		||||
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298 h1:1qlsVAQJXZHsaM8b6OLVo6muQUQd4CwkH/D3fnnbHXA=
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								system.go
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								system.go
									
									
									
									
									
								
							@ -2,6 +2,7 @@ package x
 | 
			
		||||
 | 
			
		||||
import "image"
 | 
			
		||||
import "git.tebibyte.media/tomo/tomo"
 | 
			
		||||
import "git.tebibyte.media/tomo/tomo/input"
 | 
			
		||||
import "git.tebibyte.media/tomo/tomo/canvas"
 | 
			
		||||
 | 
			
		||||
type boxSet map[anyBox] struct { }
 | 
			
		||||
@ -43,7 +44,12 @@ type anyBox interface {
 | 
			
		||||
	doLayout      ()
 | 
			
		||||
	setParent     (parent)
 | 
			
		||||
	recursiveRedo ()
 | 
			
		||||
	canBeFocused  () bool
 | 
			
		||||
	boxUnder      (image.Point) anyBox
 | 
			
		||||
	recalculateMinimumSize ()
 | 
			
		||||
 | 
			
		||||
	handleMouseDown (input.Button)
 | 
			
		||||
	handleMouseUp   (input.Button)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func assertAnyBox (unknown tomo.Box) anyBox {
 | 
			
		||||
@ -86,6 +92,8 @@ func (window *window) invalidateDraw (box anyBox) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (window *window) invalidateLayout (box anyBox) {
 | 
			
		||||
	// TODO: use a priority queue for this and have the value be the amount
 | 
			
		||||
	// of parents a box has
 | 
			
		||||
	window.needLayout.Add(box)
 | 
			
		||||
	window.invalidateDraw(box)
 | 
			
		||||
}
 | 
			
		||||
@ -97,6 +105,11 @@ func (window *window) focus (box anyBox) {
 | 
			
		||||
	window.invalidateDraw(box)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *window) boxUnder (point image.Point) anyBox {
 | 
			
		||||
	if this.root == nil { return nil }
 | 
			
		||||
	return this.root.boxUnder(point)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (window *window) afterEvent () {
 | 
			
		||||
	if window.xCanvas == nil { return }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										28
									
								
								textbox.go
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								textbox.go
									
									
									
									
									
								
							@ -83,7 +83,7 @@ func (this *textBox) SetFace (face font.Face) {
 | 
			
		||||
 | 
			
		||||
func (this *textBox) SetWrap (wrap bool) {
 | 
			
		||||
	if this.wrap == wrap { return }
 | 
			
		||||
	this.wrap = wrap
 | 
			
		||||
	this.drawer.SetWrap(wrap)
 | 
			
		||||
	this.recalculateMinimumSize()
 | 
			
		||||
	this.invalidateLayout()
 | 
			
		||||
}
 | 
			
		||||
@ -126,12 +126,12 @@ func (this *textBox) recalculateMinimumSize () {
 | 
			
		||||
		this.drawer.Em().Round(),
 | 
			
		||||
		this.drawer.LineHeight().Round())
 | 
			
		||||
 | 
			
		||||
	textSize := this.normalizedLayoutBoundsSpace()
 | 
			
		||||
	textSize := this.drawer.MinimumSize()
 | 
			
		||||
	if !this.hOverflow && !this.wrap {
 | 
			
		||||
		minimum.X = textSize.Dx()
 | 
			
		||||
		minimum.X = textSize.X
 | 
			
		||||
	}
 | 
			
		||||
	if !this.vOverflow {
 | 
			
		||||
		 minimum.Y = textSize.Dy()
 | 
			
		||||
		 minimum.Y = textSize.Y
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	minimum.X += this.padding.Horizontal()
 | 
			
		||||
@ -147,16 +147,16 @@ func (this *textBox) doLayout () {
 | 
			
		||||
	previousContentBounds := this.contentBounds
 | 
			
		||||
 | 
			
		||||
	innerBounds := this.InnerBounds()
 | 
			
		||||
	if this.hOverflow && !this.wrap {
 | 
			
		||||
		this.drawer.SetMaxWidth(0)
 | 
			
		||||
	} else {
 | 
			
		||||
		this.drawer.SetMaxWidth(innerBounds.Dx())
 | 
			
		||||
	}
 | 
			
		||||
	if this.vOverflow {
 | 
			
		||||
		this.drawer.SetMaxHeight(0)
 | 
			
		||||
	} else {
 | 
			
		||||
		this.drawer.SetMaxHeight(innerBounds.Dy())
 | 
			
		||||
	}
 | 
			
		||||
	this.drawer.SetMaxWidth(innerBounds.Dx())
 | 
			
		||||
	this.drawer.SetMaxHeight(innerBounds.Dy())
 | 
			
		||||
	// if this.hOverflow && !this.wrap {
 | 
			
		||||
		// this.drawer.SetMaxWidth(0)
 | 
			
		||||
	// } else {
 | 
			
		||||
	// }
 | 
			
		||||
	// if this.vOverflow {
 | 
			
		||||
		// this.drawer.SetMaxHeight(0)
 | 
			
		||||
	// } else {
 | 
			
		||||
	// }
 | 
			
		||||
	
 | 
			
		||||
	this.contentBounds = this.normalizedLayoutBoundsSpace().Sub(this.scroll)
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
@ -38,6 +38,7 @@ type window struct {
 | 
			
		||||
 | 
			
		||||
	modifiers     input.Modifiers
 | 
			
		||||
	mousePosition image.Point
 | 
			
		||||
	drags         [10]anyBox
 | 
			
		||||
 | 
			
		||||
	onClose event.FuncBroadcaster
 | 
			
		||||
 | 
			
		||||
@ -112,10 +113,10 @@ func (backend *Backend) newWindow (
 | 
			
		||||
		// Connect(backend.x, window.xWindow.Id)
 | 
			
		||||
	// xevent.KeyReleaseFun(window.handleKeyRelease).
 | 
			
		||||
		// Connect(backend.x, window.xWindow.Id)
 | 
			
		||||
	// xevent.ButtonPressFun(window.handleButtonPress).
 | 
			
		||||
		// Connect(backend.x, window.xWindow.Id)
 | 
			
		||||
	// xevent.ButtonReleaseFun(window.handleButtonRelease).
 | 
			
		||||
		// Connect(backend.x, window.xWindow.Id)
 | 
			
		||||
	xevent.ButtonPressFun(window.handleButtonPress).
 | 
			
		||||
		Connect(backend.x, window.xWindow.Id)
 | 
			
		||||
	xevent.ButtonReleaseFun(window.handleButtonRelease).
 | 
			
		||||
		Connect(backend.x, window.xWindow.Id)
 | 
			
		||||
	// xevent.MotionNotifyFun(window.handleMotionNotify).
 | 
			
		||||
		// Connect(backend.x, window.xWindow.Id)
 | 
			
		||||
	// xevent.SelectionNotifyFun(window.handleSelectionNotify).
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user