ref: a8bb4e36f51179ad6b544d2236600b88aab371d2
parent: 00d144fb31327e3e7181f669c58d6fdbe0c9485e
author: Philip Silva <philip.silva@protonmail.com>
date: Thu Jun 26 12:56:25 EDT 2025
field click
--- a/button/button.go
+++ b/button/button.go
@@ -44,7 +44,7 @@
b.x = x
var err error
- b.textImg, err = font.String(text)
+ b.textImg, err = font.String(text, nil)
if err != nil {
panic(err.Error())
}
--- a/field/field.go
+++ b/field/field.go
@@ -6,6 +6,7 @@
//"fmt"
"image"
"log"
+ "slices"
"sync"
"github.com/psilva261/xui"
"github.com/psilva261/xui/events"
@@ -38,6 +39,9 @@
// Position of the cursor
Pos int
+ // Offsets of the characters
+ Offsets []int
+
textImg *memdraw.Image
borderImg *memdraw.Image
hoverImg *memdraw.Image
@@ -69,10 +73,14 @@
switch tev := ev.(type) {
case mouse.Event:
- if tev.Type == mouse.Enter {
+ switch tev.Type {
+ case mouse.Enter:
f.hover = true
- } else if tev.Type == mouse.Leave {
+ case mouse.Leave:
f.hover = false
+ case mouse.Click:
+ f.Pos, _ = slices.BinarySearch(f.Offsets, tev.Point.X)
+ f.updateTextImgs()
}
if f.cb != nil {
@@ -79,11 +87,11 @@
f.cb(tev, f.cbUserData)
}
case keyboard.Event:
- log.Printf("key pressed: %+v %d % x", tev, tev, tev)
+ //log.Printf("key pressed: %+v %d % x", tev, tev, tev)
switch tev.Key {
case Backspace:
- if f.Pos > 0 && len(f.Text) > 0 {
+ if f.Pos > 0 && f.Pos <= len(f.Text) && len(f.Text) > 0 {
f.Text = f.Text[:f.Pos-1] + f.Text[f.Pos:]
}
f.Pos -= 1
@@ -96,8 +104,8 @@
case draw.KeyRight:
f.Pos += 1
default:
- f.Text += string([]byte{byte(tev.Key)})
- f.Pos = len(f.Text)
+ f.Text = f.Text[:f.Pos]+string([]byte{byte(tev.Key)})+f.Text[f.Pos:]
+ f.Pos += 1
}
if f.Pos < 0 {
f.Pos = 0
@@ -127,10 +135,9 @@
}
func (f *Field) updateTextImgs() {
-
var err error
- //log.Printf("updateTextImgs: call font.String")
- f.textImg, err = font.String(f.Text)
+
+ f.textImg, err = font.String(f.Text, &f.Offsets)
if err != nil {
panic(err.Error())
}
@@ -157,9 +164,13 @@
f.hoverImg.Draw(rr, f.textImg, image.ZP, color.EmptyMask, image.ZP, draw.SoverD)
geom.DrawRoundedBorder(f.hoverImg, f.Rectangle, f.Colorset.Hover.Border)
- textPart, err := font.String(f.Text[:f.Pos])
+ pos := f.Pos
+ if pos+1 >= len(f.Offsets) {
+ pos = len(f.Offsets)-1
+ }
+ textPartR := draw.Rect(0, 0, f.Offsets[pos], f.textImg.R.Dy())
if err == nil {
- geom.DrawCursor(f.hoverImg, r, textPart.R, f.Colorset.Hover.Border)
+ geom.DrawCursor(f.hoverImg, r, textPartR, f.Colorset.Hover.Border)
} else {
log.Printf("font string sub text: %v", err)
}
--- a/field/field_test.go
+++ b/field/field_test.go
@@ -4,6 +4,7 @@
"9fans.net/go/draw"
"9fans.net/go/draw/memdraw"
"github.com/psilva261/xui/events/keyboard"
+ "github.com/psilva261/xui/events/mouse"
"github.com/psilva261/xui/xuitest"
"image"
"testing"
@@ -32,6 +33,20 @@
}
if f.Pos != 1 {
t.Fatalf("Pos=%d", f.Pos)
+ }
+}
+
+func TestEventClick(t *testing.T) {
+ f := newField(t)
+ f.Text = "abcdefghijklmn"
+ f.Pos = 13
+ f.Offsets = []int{0, 19, 40, 57, 78, 96, 108, 129, 150, 159, 169, 189, 198, 229, 250}
+ f.Event(mouse.Event{
+ Type: mouse.Click,
+ Point: image.Pt(82,423),
+ })
+ if f.Pos != 5 {
+ t.Fatalf("%v", f.Pos)
}
}
--- a/font/font.go
+++ b/font/font.go
@@ -34,7 +34,7 @@
return
}
-func String(text string) (textImg *memdraw.Image, err error) {
+func String(text string, offsets *[]int) (textImg *memdraw.Image, err error) {
face, err := Open("")
if err != nil {
return nil, fmt.Errorf("open font: %w", err)
@@ -42,10 +42,16 @@
ascent := face.Metrics().Ascent.Ceil()
w := 0
- for _, r := range text {
+ if offsets != nil && len(*offsets) <= len(text) {
+ *offsets = append(*offsets, make([]int, len(text)-len(*offsets)+1)...)
+ }
+ for i, r := range text {
bounds, adv, _ := face.GlyphBounds(r)
_ = bounds
w += adv.Ceil()
+ if offsets != nil {
+ (*offsets)[i+1] = w
+ }
}
r := image.Rect(0, 0, w, 2*ascent)
if r.Dx() == 0 {
@@ -64,7 +70,7 @@
}
d.DrawString(text)
- log.Printf("String: dst.Bounds()=%+v", dst.Bounds())
+ //log.Printf("String: dst.Bounds()=%+v", dst.Bounds())
textImg, err = memdraw.AllocImage(dst.Bounds(), draw.ABGR32)
if err != nil {
--- a/font/font_test.go
+++ b/font/font_test.go
@@ -35,7 +35,7 @@
}
func testString(t *testing.T, text string) (map[color.Color]int, image.Rectangle) {
- img, err := String(text)
+ img, err := String(text, nil)
if err != nil {
t.Fail()
}
--- a/label/label.go
+++ b/label/label.go
@@ -27,7 +27,7 @@
l.Text = text
var err error
- l.textImg, err = font.String(text)
+ l.textImg, err = font.String(text, nil)
if err != nil {
panic(err.Error())
}
--
⑨