Upgrade tomo version

This commit is contained in:
Sasha Koshka 2023-09-09 15:05:08 -04:00
parent c91d4577e7
commit 2ecfafa469
8 changed files with 149 additions and 34 deletions

11
box.go
View File

@ -259,6 +259,11 @@ func (this *box) handleMouseUp (button input.Button) {
listener(button)
}
}
func (this *box) handleScroll (x, y float64) {
for _, listener := range this.on.scroll.Listeners() {
listener(x, y)
}
}
func (this *box) handleKeyDown (key input.Key, numberPad bool) {
for _, listener := range this.on.keyDown.Listeners() {
listener(key, numberPad)
@ -374,6 +379,10 @@ func (this *box) setParent (parent parent) {
this.parent = parent
}
func (this *box) getParent () parent {
return this.parent
}
func (this *box) flushActionQueue () {
if this.parent == nil || this.parent.window() == nil { return }
@ -412,7 +421,7 @@ func (this *box) canBeFocused () bool {
return this.focusable
}
func (this *box) boxUnder (point image.Point) anyBox {
func (this *box) boxUnder (point image.Point, category eventCategory) anyBox {
if point.In(this.bounds) {
return this.outer
} else {

View File

@ -13,11 +13,11 @@ type containerBox struct {
hAlign, vAlign tomo.Align
contentBounds image.Rectangle
scroll image.Point
capture [4]bool
gap image.Point
children []tomo.Box
layout tomo.Layout
propagateEvents bool
on struct {
contentBoundsChange event.FuncBroadcaster
@ -25,7 +25,7 @@ type containerBox struct {
}
func (backend *Backend) NewContainerBox() tomo.ContainerBox {
this := &containerBox { propagateEvents: true }
this := &containerBox { }
this.box = backend.newBox(this)
return this
}
@ -68,8 +68,20 @@ func (this *containerBox) OnContentBoundsChange (callback func()) event.Cookie {
return this.on.contentBoundsChange.Connect(callback)
}
func (this *containerBox) SetPropagateEvents (propagate bool) {
this.propagateEvents = propagate
func (this *containerBox) CaptureDND (capture bool) {
this.capture[eventCategoryDND] = capture
}
func (this *containerBox) CaptureMouse (capture bool) {
this.capture[eventCategoryMouse] = capture
}
func (this *containerBox) CaptureScroll (capture bool) {
this.capture[eventCategoryScroll] = capture
}
func (this *containerBox) CaptureKeyboard (capture bool) {
this.capture[eventCategoryKeyboard] = capture
}
func (this *containerBox) SetGap (gap image.Point) {
@ -175,7 +187,7 @@ func (this *containerBox) drawBackgroundPart (can canvas.Canvas) {
func (this *containerBox) invalidateTransparentChildren () {
window := this.window()
if this.window == nil { return }
if window == nil { return }
for _, box := range this.children {
box := assertAnyBox(box)
if box.transparent() {
@ -251,15 +263,15 @@ func (this *containerBox) recursiveRedo () {
}
}
func (this *containerBox) boxUnder (point image.Point) anyBox {
if this.propagateEvents {
func (this *containerBox) boxUnder (point image.Point, category eventCategory) anyBox {
if !this.capture[category] {
for _, box := range this.children {
candidate := box.(anyBox).boxUnder(point)
candidate := box.(anyBox).boxUnder(point, category)
if candidate != nil { return candidate }
}
}
return this.box.boxUnder(point)
return this.box.boxUnder(point, category)
}
func (this *containerBox) propagate (callback func (anyBox) bool) bool {
@ -281,3 +293,7 @@ func (this *containerBox) propagateAlt (callback func (anyBox) bool) bool {
return true
}
func (this *containerBox) captures (category eventCategory) bool {
return this.capture[category]
}

View File

@ -8,6 +8,31 @@ import "git.tebibyte.media/tomo/xgbkb"
import "github.com/jezek/xgbutil/xevent"
import "git.tebibyte.media/tomo/tomo/input"
type scrollSum struct {
x, y int
}
// TODO: this needs to be configurable, we need a config api
const scrollDistance = 16
func (sum *scrollSum) add (button xproto.Button, window *window, state uint16) {
if xgbkb.StateToModifiers(state).Shift {
switch button {
case 4: sum.x -= scrollDistance
case 5: sum.x += scrollDistance
case 6: sum.y -= scrollDistance
case 7: sum.y += scrollDistance
}
} else {
switch button {
case 4: sum.y -= scrollDistance
case 5: sum.y += scrollDistance
case 6: sum.x -= scrollDistance
case 7: sum.x += scrollDistance
}
}
}
var buttonCodeTable = map[xproto.Keysym] input.Key {
0xFFFFFF: input.KeyNone,
@ -208,7 +233,7 @@ func (window *window) handleKeyPress (
} else if key == input.KeyEscape && window.shy {
window.Close()
} else if window.focused != nil {
window.focused.handleKeyDown(key, numberPad)
window.keyboardTarget().handleKeyDown(key, numberPad)
}
}
@ -241,7 +266,7 @@ func (window *window) handleKeyRelease (
window.updateModifiers(keyEvent.State)
if window.focused != nil {
window.focused.handleKeyUp(key, numberPad)
window.keyboardTarget().handleKeyUp(key, numberPad)
}
}
@ -261,20 +286,15 @@ func (window *window) handleButtonPress (
if !insideWindow && window.shy && !scrolling {
window.Close()
} else if scrolling {
// TODO
// 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)
// }
// }
underneath := window.boxUnder(point, eventCategoryScroll)
if underneath != nil {
sum := scrollSum { }
sum.add(buttonEvent.Detail, window, buttonEvent.State)
window.compressScrollSum(buttonEvent, &sum)
underneath.handleScroll(float64(sum.x), float64(sum.y))
}
} else {
underneath := window.boxUnder(point)
underneath := window.boxUnder(point, eventCategoryMouse)
window.drags[buttonEvent.Detail] = underneath
if underneath != nil {
underneath.handleMouseDown(input.Button(buttonEvent.Detail))
@ -318,7 +338,7 @@ func (window *window) handleMotionNotify (
handled = true
}
underneath := window.boxUnder(image.Pt(x, y))
underneath := window.boxUnder(image.Pt(x, y), eventCategoryMouse)
window.hover(underneath)
if !handled {
@ -391,6 +411,33 @@ func (window *window) compressConfigureNotify (
return
}
func (window *window) compressScrollSum (
firstEvent xproto.ButtonPressEvent,
sum *scrollSum,
) {
window.backend.x.Sync()
xevent.Read(window.backend.x, false)
for index, untypedEvent := range xevent.Peek(window.backend.x) {
if untypedEvent.Err != nil { continue }
typedEvent, ok := untypedEvent.Event.(xproto.ButtonPressEvent)
if !ok { continue }
if firstEvent.Event == typedEvent.Event &&
typedEvent.Detail >= 4 &&
typedEvent.Detail <= 7 {
sum.add(typedEvent.Detail, window, typedEvent.State)
defer func (index int) {
xevent.DequeueAt(window.backend.x, index)
} (index)
}
}
return
}
func (window *window) compressMotionNotify (
firstEvent xproto.MotionNotifyEvent,
) (

2
go.mod
View File

@ -3,7 +3,7 @@ module git.tebibyte.media/tomo/x
go 1.20
require (
git.tebibyte.media/tomo/tomo v0.28.0
git.tebibyte.media/tomo/tomo v0.29.0
git.tebibyte.media/tomo/typeset v0.5.2
git.tebibyte.media/tomo/xgbkb v1.0.1
github.com/jezek/xgb v1.1.0

4
go.sum
View File

@ -1,6 +1,6 @@
git.tebibyte.media/sashakoshka/xgbkb v1.0.0/go.mod h1:pNcE6TRO93vHd6q42SdwLSTTj25L0Yzggz7yLe0JV6Q=
git.tebibyte.media/tomo/tomo v0.28.0 h1:wB+RpYw48Jn2DUQhXwdUe54BnYJf/79On3jxnBYvQ1Q=
git.tebibyte.media/tomo/tomo v0.28.0/go.mod h1:C9EzepS9wjkTJjnZaPBh22YvVPyA4hbBAJVU20Rdmps=
git.tebibyte.media/tomo/tomo v0.29.0 h1:uvdPaEQYcWH965y85SjIKwhLklnTbs+x6MRwLfdRvfo=
git.tebibyte.media/tomo/tomo v0.29.0/go.mod h1:C9EzepS9wjkTJjnZaPBh22YvVPyA4hbBAJVU20Rdmps=
git.tebibyte.media/tomo/typeset v0.5.2 h1:qHxN62/VDnrAouOuzxLmLleQNwAebshrfVYvtoOnAG4=
git.tebibyte.media/tomo/typeset v0.5.2/go.mod h1:PwDpSdBF3l/EzoIsa2ME7QffVVajnTHZN6l3MHEGe1g=
git.tebibyte.media/tomo/xgbkb v1.0.1 h1:b3HDUopjdQp1MZrb5Vpil4bOtk3NnNXtfQW27Blw2kE=

View File

@ -37,6 +37,7 @@ type parent interface {
canvas () canvas.Canvas
notifyMinimumSizeChange (anyBox)
drawBackgroundPart (canvas.Canvas)
captures (eventCategory) bool
}
type anyBox interface {
@ -48,10 +49,11 @@ type anyBox interface {
doMinimumSize ()
contentMinimum () image.Point
setParent (parent)
getParent () parent
flushActionQueue ()
recursiveRedo ()
canBeFocused () bool
boxUnder (image.Point) anyBox
boxUnder (image.Point, eventCategory) anyBox
transparent () bool
propagate (func (anyBox) bool) bool
@ -67,7 +69,7 @@ type anyBox interface {
handleMouseMove ()
handleMouseDown (input.Button)
handleMouseUp (input.Button)
// handleScroll (float64, float64)
handleScroll (float64, float64)
handleKeyDown (input.Key, bool)
handleKeyUp (input.Key, bool)
}
@ -153,9 +155,36 @@ func (window *window) anyFocused () bool {
return window.focused != nil
}
func (this *window) boxUnder (point image.Point) anyBox {
type eventCategory int; const (
eventCategoryDND eventCategory = iota
eventCategoryMouse
eventCategoryScroll
eventCategoryKeyboard
)
func (this *window) boxUnder (point image.Point, category eventCategory) anyBox {
if this.root == nil { return nil }
return this.root.boxUnder(point)
return this.root.boxUnder(point, category)
}
func (this *window) captures (eventCategory) bool {
return false
}
func (this *window) keyboardTarget () anyBox {
focused := this.window().focused
if focused == nil { return nil }
parent := focused.getParent()
for {
parentBox, ok := parent.(anyBox)
if !ok { break }
if parent.captures(eventCategoryKeyboard) {
return parentBox
}
parent = parentBox.getParent()
}
return focused
}
func (this *window) focusNext () {

View File

@ -298,7 +298,7 @@ func (this *textBox) doLayout () {
this.drawer.SetMaxWidth(innerBounds.Dx())
this.drawer.SetMaxHeight(innerBounds.Dy())
this.contentBounds = this.normalizedLayoutBoundsSpace().Sub(this.scroll)
this.contentBounds = this.normalizedLayoutBoundsSpace().Add(this.scroll)
if previousContentBounds != this.contentBounds {
this.on.contentBoundsChange.Broadcast()

View File

@ -73,6 +73,20 @@ func (backend *Backend) NewWindow (
return output, err
}
func (backend *Backend) NewPlainWindow (
bounds image.Rectangle,
) (
output tomo.MainWindow,
err error,
) {
backend.assert()
window, err := backend.newWindow(bounds, false)
window.setType("dock")
output = mainWindow { window: window }
return output, err
}
func (backend *Backend) newWindow (
bounds image.Rectangle,
override bool,