mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 18:05:35 +00:00
widget,text: move Label and Editor from text to widget package
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -3,10 +3,6 @@
|
|||||||
package text
|
package text
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"image"
|
|
||||||
|
|
||||||
"gioui.org/layout"
|
|
||||||
"gioui.org/op/paint"
|
"gioui.org/op/paint"
|
||||||
"gioui.org/unit"
|
"gioui.org/unit"
|
||||||
"golang.org/x/image/math/fixed"
|
"golang.org/x/image/math/fixed"
|
||||||
@@ -87,46 +83,6 @@ const (
|
|||||||
Bold Weight = 700
|
Bold Weight = 700
|
||||||
)
|
)
|
||||||
|
|
||||||
func linesDimens(lines []Line) layout.Dimensions {
|
|
||||||
var width fixed.Int26_6
|
|
||||||
var h int
|
|
||||||
var baseline int
|
|
||||||
if len(lines) > 0 {
|
|
||||||
baseline = lines[0].Ascent.Ceil()
|
|
||||||
var prevDesc fixed.Int26_6
|
|
||||||
for _, l := range lines {
|
|
||||||
h += (prevDesc + l.Ascent).Ceil()
|
|
||||||
prevDesc = l.Descent
|
|
||||||
if l.Width > width {
|
|
||||||
width = l.Width
|
|
||||||
}
|
|
||||||
}
|
|
||||||
h += lines[len(lines)-1].Descent.Ceil()
|
|
||||||
}
|
|
||||||
w := width.Ceil()
|
|
||||||
return layout.Dimensions{
|
|
||||||
Size: image.Point{
|
|
||||||
X: w,
|
|
||||||
Y: h,
|
|
||||||
},
|
|
||||||
Baseline: baseline,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func align(align Alignment, width fixed.Int26_6, maxWidth int) fixed.Int26_6 {
|
|
||||||
mw := fixed.I(maxWidth)
|
|
||||||
switch align {
|
|
||||||
case Middle:
|
|
||||||
return fixed.I(((mw - width) / 2).Floor())
|
|
||||||
case End:
|
|
||||||
return fixed.I((mw - width).Floor())
|
|
||||||
case Start:
|
|
||||||
return 0
|
|
||||||
default:
|
|
||||||
panic(fmt.Errorf("unknown alignment %v", align))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a Alignment) String() string {
|
func (a Alignment) String() string {
|
||||||
switch a {
|
switch a {
|
||||||
case Start:
|
case Start:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: Unlicense OR MIT
|
// SPDX-License-Identifier: Unlicense OR MIT
|
||||||
|
|
||||||
package text
|
package widget
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: Unlicense OR MIT
|
// SPDX-License-Identifier: Unlicense OR MIT
|
||||||
|
|
||||||
package text
|
package widget
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
@@ -15,6 +15,7 @@ import (
|
|||||||
"gioui.org/layout"
|
"gioui.org/layout"
|
||||||
"gioui.org/op"
|
"gioui.org/op"
|
||||||
"gioui.org/op/paint"
|
"gioui.org/op/paint"
|
||||||
|
"gioui.org/text"
|
||||||
"gioui.org/unit"
|
"gioui.org/unit"
|
||||||
|
|
||||||
"golang.org/x/image/math/fixed"
|
"golang.org/x/image/math/fixed"
|
||||||
@@ -22,7 +23,7 @@ import (
|
|||||||
|
|
||||||
// Editor implements an editable and scrollable text area.
|
// Editor implements an editable and scrollable text area.
|
||||||
type Editor struct {
|
type Editor struct {
|
||||||
Alignment Alignment
|
Alignment text.Alignment
|
||||||
// SingleLine force the text to stay on a single line.
|
// SingleLine force the text to stay on a single line.
|
||||||
// SingleLine also sets the scrolling direction to
|
// SingleLine also sets the scrolling direction to
|
||||||
// horizontal.
|
// horizontal.
|
||||||
@@ -33,14 +34,14 @@ type Editor struct {
|
|||||||
|
|
||||||
eventKey int
|
eventKey int
|
||||||
scale int
|
scale int
|
||||||
font Font
|
font text.Font
|
||||||
blinkStart time.Time
|
blinkStart time.Time
|
||||||
focused bool
|
focused bool
|
||||||
rr editBuffer
|
rr editBuffer
|
||||||
maxWidth int
|
maxWidth int
|
||||||
viewSize image.Point
|
viewSize image.Point
|
||||||
valid bool
|
valid bool
|
||||||
lines []Line
|
lines []text.Line
|
||||||
shapes []line
|
shapes []line
|
||||||
dims layout.Dimensions
|
dims layout.Dimensions
|
||||||
carWidth fixed.Int26_6
|
carWidth fixed.Int26_6
|
||||||
@@ -175,7 +176,7 @@ func (e *Editor) Focus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Layout lays out the editor.
|
// Layout lays out the editor.
|
||||||
func (e *Editor) Layout(gtx *layout.Context, sh *Shaper, font Font) {
|
func (e *Editor) Layout(gtx *layout.Context, sh *text.Shaper, font text.Font) {
|
||||||
if e.font != font {
|
if e.font != font {
|
||||||
e.invalidate()
|
e.invalidate()
|
||||||
e.font = font
|
e.font = font
|
||||||
@@ -187,7 +188,7 @@ func (e *Editor) Layout(gtx *layout.Context, sh *Shaper, font Font) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Editor) layout(gtx *layout.Context, sh *Shaper) {
|
func (e *Editor) layout(gtx *layout.Context, sh *text.Shaper) {
|
||||||
// Crude configuration change detection.
|
// Crude configuration change detection.
|
||||||
if scale := gtx.Px(unit.Sp(100)); scale != e.scale {
|
if scale := gtx.Px(unit.Sp(100)); scale != e.scale {
|
||||||
e.invalidate()
|
e.invalidate()
|
||||||
@@ -391,9 +392,9 @@ func (e *Editor) moveCoord(c unit.Converter, pos image.Point) {
|
|||||||
e.moveToLine(x, carLine)
|
e.moveToLine(x, carLine)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Editor) layoutText(c unit.Converter, s *Shaper, font Font) ([]Line, layout.Dimensions) {
|
func (e *Editor) layoutText(c unit.Converter, s *text.Shaper, font text.Font) ([]text.Line, layout.Dimensions) {
|
||||||
txt := e.rr.String()
|
txt := e.rr.String()
|
||||||
opts := LayoutOptions{SingleLine: e.SingleLine, MaxWidth: e.maxWidth}
|
opts := text.LayoutOptions{SingleLine: e.SingleLine, MaxWidth: e.maxWidth}
|
||||||
textLayout := s.Layout(c, font, txt, opts)
|
textLayout := s.Layout(c, font, txt, opts)
|
||||||
lines := textLayout.Lines
|
lines := textLayout.Lines
|
||||||
dims := linesDimens(lines)
|
dims := linesDimens(lines)
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
// SPDX-License-Identifier: Unlicense OR MIT
|
// SPDX-License-Identifier: Unlicense OR MIT
|
||||||
|
|
||||||
// Package text implements text widgets.
|
package widget
|
||||||
package text
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"gioui.org/layout"
|
"gioui.org/layout"
|
||||||
"gioui.org/op"
|
"gioui.org/op"
|
||||||
"gioui.org/op/paint"
|
"gioui.org/op/paint"
|
||||||
|
"gioui.org/text"
|
||||||
|
|
||||||
"golang.org/x/image/math/fixed"
|
"golang.org/x/image/math/fixed"
|
||||||
)
|
)
|
||||||
@@ -18,15 +19,15 @@ import (
|
|||||||
// Label is a widget for laying out and drawing text.
|
// Label is a widget for laying out and drawing text.
|
||||||
type Label struct {
|
type Label struct {
|
||||||
// Alignment specify the text alignment.
|
// Alignment specify the text alignment.
|
||||||
Alignment Alignment
|
Alignment text.Alignment
|
||||||
// MaxLines limits the number of lines. Zero means no limit.
|
// MaxLines limits the number of lines. Zero means no limit.
|
||||||
MaxLines int
|
MaxLines int
|
||||||
}
|
}
|
||||||
|
|
||||||
type lineIterator struct {
|
type lineIterator struct {
|
||||||
Lines []Line
|
Lines []text.Line
|
||||||
Clip image.Rectangle
|
Clip image.Rectangle
|
||||||
Alignment Alignment
|
Alignment text.Alignment
|
||||||
Width int
|
Width int
|
||||||
Offset image.Point
|
Offset image.Point
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ type lineIterator struct {
|
|||||||
|
|
||||||
const inf = 1e6
|
const inf = 1e6
|
||||||
|
|
||||||
func (l *lineIterator) Next() (String, f32.Point, bool) {
|
func (l *lineIterator) Next() (text.String, f32.Point, bool) {
|
||||||
for len(l.Lines) > 0 {
|
for len(l.Lines) > 0 {
|
||||||
line := l.Lines[0]
|
line := l.Lines[0]
|
||||||
l.Lines = l.Lines[1:]
|
l.Lines = l.Lines[1:]
|
||||||
@@ -78,12 +79,12 @@ func (l *lineIterator) Next() (String, f32.Point, bool) {
|
|||||||
offf := f32.Point{X: float32(off.X) / 64, Y: float32(off.Y) / 64}
|
offf := f32.Point{X: float32(off.X) / 64, Y: float32(off.Y) / 64}
|
||||||
return str, offf, true
|
return str, offf, true
|
||||||
}
|
}
|
||||||
return String{}, f32.Point{}, false
|
return text.String{}, f32.Point{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l Label) Layout(gtx *layout.Context, s *Shaper, font Font, txt string) {
|
func (l Label) Layout(gtx *layout.Context, s *text.Shaper, font text.Font, txt string) {
|
||||||
cs := gtx.Constraints
|
cs := gtx.Constraints
|
||||||
textLayout := s.Layout(gtx, font, txt, LayoutOptions{MaxWidth: cs.Width.Max})
|
textLayout := s.Layout(gtx, font, txt, text.LayoutOptions{MaxWidth: cs.Width.Max})
|
||||||
lines := textLayout.Lines
|
lines := textLayout.Lines
|
||||||
if max := l.MaxLines; max > 0 && len(lines) > max {
|
if max := l.MaxLines; max > 0 && len(lines) > max {
|
||||||
lines = lines[:max]
|
lines = lines[:max]
|
||||||
@@ -121,7 +122,7 @@ func toRectF(r image.Rectangle) f32.Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func textPadding(lines []Line) (padding image.Rectangle) {
|
func textPadding(lines []text.Line) (padding image.Rectangle) {
|
||||||
if len(lines) == 0 {
|
if len(lines) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -141,3 +142,43 @@ func textPadding(lines []Line) (padding image.Rectangle) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func linesDimens(lines []text.Line) layout.Dimensions {
|
||||||
|
var width fixed.Int26_6
|
||||||
|
var h int
|
||||||
|
var baseline int
|
||||||
|
if len(lines) > 0 {
|
||||||
|
baseline = lines[0].Ascent.Ceil()
|
||||||
|
var prevDesc fixed.Int26_6
|
||||||
|
for _, l := range lines {
|
||||||
|
h += (prevDesc + l.Ascent).Ceil()
|
||||||
|
prevDesc = l.Descent
|
||||||
|
if l.Width > width {
|
||||||
|
width = l.Width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h += lines[len(lines)-1].Descent.Ceil()
|
||||||
|
}
|
||||||
|
w := width.Ceil()
|
||||||
|
return layout.Dimensions{
|
||||||
|
Size: image.Point{
|
||||||
|
X: w,
|
||||||
|
Y: h,
|
||||||
|
},
|
||||||
|
Baseline: baseline,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func align(align text.Alignment, width fixed.Int26_6, maxWidth int) fixed.Int26_6 {
|
||||||
|
mw := fixed.I(maxWidth)
|
||||||
|
switch align {
|
||||||
|
case text.Middle:
|
||||||
|
return fixed.I(((mw - width) / 2).Floor())
|
||||||
|
case text.End:
|
||||||
|
return fixed.I((mw - width).Floor())
|
||||||
|
case text.Start:
|
||||||
|
return 0
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("unknown alignment %v", align))
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user