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)
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ type containerBox struct {
|
||||
gap image.Point
|
||||
children []tomo.Box
|
||||
layout tomo.Layout
|
||||
propagateEvents bool
|
||||
|
||||
on struct {
|
||||
contentBoundsChange event.FuncBroadcaster
|
||||
@ -25,6 +26,7 @@ type containerBox struct {
|
||||
func (backend *Backend) NewContainerBox() tomo.ContainerBox {
|
||||
box := &containerBox {
|
||||
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 }
|
||||
|
||||
|
24
textbox.go
24
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())
|
||||
}
|
||||
// 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