Add base dot manipulation implementation

This commit is contained in:
Sasha Koshka 2023-08-03 12:45:21 -04:00
parent a0fd8a694b
commit 991f72cd8f
6 changed files with 83 additions and 25 deletions

13
box.go
View File

@ -132,6 +132,11 @@ func (this *box) SetDNDAccept (types ...data.Mime) {
}
func (this *box) SetFocused (focused bool) {
if this.parent == nil { return }
window := this.parent.window()
if window == nil { return }
if !this.focusable { return }
if this.Focused () && !focused {
this.parent.window().focus(nil)
} else if !this.Focused() && focused {
@ -309,6 +314,14 @@ func (this *box) handleFocusLeave () {
}
func (this *box) handleMouseDown (button input.Button) {
if this.focusable {
this.SetFocused(true)
} else {
if this.parent == nil { return }
window := this.parent.window()
if window == nil { return }
window.focus(nil)
}
for _, listener := range this.on.mouseDown.Listeners() {
listener(button)
}

View File

@ -65,7 +65,7 @@ func (this *containerBox) OnContentBoundsChange (callback func()) event.Cookie {
return this.on.contentBoundsChange.Connect(callback)
}
func (this *containerBox) PropagateEvents (propagate bool) {
func (this *containerBox) SetPropagateEvents (propagate bool) {
this.propagateEvents = propagate
}
@ -143,7 +143,6 @@ func (this *containerBox) Draw (can canvas.Canvas) {
pen := can.Pen()
pen.Fill(this.color)
// TODO: do this in doLayout and save the result
rocks := make([]image.Rectangle, len(this.children))
for index, box := range this.children {
rocks[index] = box.Bounds()

4
go.mod
View File

@ -4,15 +4,15 @@ go 1.20
require (
git.tebibyte.media/tomo/ggfx v0.4.0
git.tebibyte.media/tomo/tomo v0.16.0
git.tebibyte.media/tomo/tomo v0.17.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
golang.org/x/image v0.9.0
)
require (
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298 // indirect
github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966 // indirect
golang.org/x/image v0.9.0 // indirect
)

20
go.sum
View File

@ -1,24 +1,8 @@
git.tebibyte.media/sashakoshka/xgbkb v1.0.0/go.mod h1:pNcE6TRO93vHd6q42SdwLSTTj25L0Yzggz7yLe0JV6Q=
git.tebibyte.media/tomo/ggfx v0.4.0 h1:3aUHeGS/yYWRV/zCDubBsXnik5ygkMnj/VgrM5Z75A4=
git.tebibyte.media/tomo/ggfx v0.4.0/go.mod h1:zPoz8BdVQyG2KhEmeGFQBK66V71i6Kj8oVFbrZaCwRA=
git.tebibyte.media/tomo/tomo v0.11.0 h1:Gh9c/6rDqvhxt/DaNQHYNUfdRmSQTuz9T3F+pb5W6BI=
git.tebibyte.media/tomo/tomo v0.11.0/go.mod h1:lTwjpiHbP4UN/kFw+6FwhG600B+PMKVtMOr7wpd5IUY=
git.tebibyte.media/tomo/tomo v0.12.0 h1:MwcudNzo7hSeiEWGSLt6lxJGK3itxTSgdggaZoHZLJo=
git.tebibyte.media/tomo/tomo v0.12.0/go.mod h1:lTwjpiHbP4UN/kFw+6FwhG600B+PMKVtMOr7wpd5IUY=
git.tebibyte.media/tomo/tomo v0.13.0 h1:xQvEia1vDUfq3QkpU3De72z53ON+y8I6HMP8TDtcS2k=
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/tomo v0.17.0 h1:J+Sxh24o7YDls/18b86VHriilhrGYmObaMbzrYNyVaY=
git.tebibyte.media/tomo/tomo v0.17.0/go.mod h1:lTwjpiHbP4UN/kFw+6FwhG600B+PMKVtMOr7wpd5IUY=
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=

View File

@ -5,6 +5,7 @@ import "image/color"
import "golang.org/x/image/font"
import "git.tebibyte.media/tomo/tomo"
import "git.tebibyte.media/tomo/typeset"
import "git.tebibyte.media/tomo/tomo/text"
import "git.tebibyte.media/tomo/tomo/event"
import "git.tebibyte.media/tomo/tomo/canvas"
@ -20,11 +21,15 @@ type textBox struct {
face font.Face
wrap bool
hAlign tomo.Align
selectable bool
dot text.Dot
drawer typeset.Drawer
on struct {
contentBoundsChange event.FuncBroadcaster
dotChange event.FuncBroadcaster
}
}
@ -88,6 +93,28 @@ func (this *textBox) SetWrap (wrap bool) {
this.invalidateLayout()
}
func (this *textBox) SetSelectable (selectable bool) {
if this.selectable == selectable { return }
this.selectable = selectable
}
func (this *textBox) Select (dot text.Dot) {
if !this.selectable { return }
if this.dot == dot { return }
this.SetFocused(true)
this.dot = dot
this.on.dotChange.Broadcast()
this.invalidateDraw()
}
func (this *textBox) Dot () text.Dot {
return this.dot
}
func (this *textBox) OnDotChange (callback func ()) event.Cookie {
return this.on.dotChange.Connect(callback)
}
func (this *textBox) SetAlign (x, y tomo.Align) {
if this.hAlign == x { return }
this.hAlign = x
@ -109,11 +136,46 @@ func (this *textBox) Draw (can canvas.Canvas) {
pen.Fill(this.color)
pen.Rectangle(can.Bounds())
if this.selectable && this.Focused() {
this.drawDot(can)
}
if this.face == nil { return }
offset := this.InnerBounds().Min.
this.drawer.Draw(can, this.textColor, this.textOffset())
}
func (this *textBox) drawDot (can canvas.Canvas) {
pen := can.Pen()
pen.Fill(color.Transparent)
pen.Stroke(this.textColor)
pen.StrokeWeight(1)
// TODO draw dot
if this.dot.Empty() {
metrics := this.face.Metrics()
position := this.drawer.PositionAt(this.dot.Start)
roundPos :=
image.Pt(position.X.Round(), position.Y.Round()).
Add(this.textOffset())
pen.Path (
roundPos.Add(image.Pt(0, metrics.Descent.Round())),
roundPos.Sub(image.Pt(0, metrics.Ascent.Round())))
} else {
}
}
func (this *textBox) textOffset () image.Point {
return this.InnerBounds().Min.
Sub(this.scroll).
Sub(this.drawer.LayoutBoundsSpace().Min)
this.drawer.Draw(can, this.textColor, offset)
}
func (this *textBox) handleFocusLeave () {
this.dot = text.EmptyDot(0)
this.on.dotChange.Broadcast()
this.invalidateDraw()
this.box.handleFocusLeave()
}
func (this *textBox) normalizedLayoutBoundsSpace () image.Rectangle {

View File

@ -144,7 +144,7 @@ func (window *window) SetTitle (title string) {
icccm.WmIconNameSet (window.backend.x, window.xWindow.Id, title)
}
func (window *window) SetIcon (sizes []image.Image) {
func (window *window) SetIcon (sizes ...image.Image) {
wmIcons := []ewmh.WmIcon { }
for _, icon := range sizes {