widget: [API] make text.Alignment direction-sensitive

This commit ensures that text.Alignment is intuitive for
the direction of the text being aligned. RTL text with
Alignment Start will be aligned to the right edge of the area,
whereas LTR text with Alignment Start will continue to be
aligned to the left edge. Vice versa for the End alignment.

References: https://todo.sr.ht/~eliasnaur/gio/146
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
This commit is contained in:
Chris Waldon
2022-03-16 16:01:41 -04:00
committed by Elias Naur
parent e14bbee252
commit 7daab97fab
2 changed files with 16 additions and 5 deletions
+3 -3
View File
@@ -851,7 +851,7 @@ func (e *Editor) scrollBounds() image.Rectangle {
var b image.Rectangle
if e.SingleLine {
if len(e.lines) > 0 {
b.Min.X = align(e.Alignment, e.lines[0].Width, e.viewSize.X).Floor()
b.Min.X = align(e.Alignment, e.locale.Direction, e.lines[0].Width, e.viewSize.X).Floor()
if b.Min.X > 0 {
b.Min.X = 0
}
@@ -1060,7 +1060,7 @@ func seekPosition(lines []text.Line, alignment text.Alignment, width int, start,
start.lineCol.X = 0
start.clusterIndex = 0
l = lines[start.lineCol.Y]
start.x = align(alignment, l.Width, width)
start.x = align(alignment, l.Layout.Direction, l.Width, width)
if l.Layout.Direction.Progression() == system.TowardOrigin {
start.x += l.Width
}
@@ -1213,7 +1213,7 @@ func (e *Editor) moveEnd(selAct selectionAction) {
caret = e.closestPosition(combinedPos{lineCol: screenPos{X: maxInt, Y: caret.lineCol.Y}})
e.caret.start = caret.runes
l := e.lines[caret.lineCol.Y]
a := align(e.Alignment, l.Width, e.viewSize.X)
a := align(e.Alignment, e.locale.Direction, l.Width, e.viewSize.X)
e.caret.xoff = l.Width + a - caret.x
e.updateSelection(selAct)
}
+13 -2
View File
@@ -82,7 +82,7 @@ func subLayout(line text.Line, start, end combinedPos) text.Layout {
func firstPos(line text.Line, alignment text.Alignment, width int) combinedPos {
p := combinedPos{
x: align(alignment, line.Width, width),
x: align(alignment, line.Layout.Direction, line.Width, width),
y: line.Ascent.Ceil(),
}
@@ -180,8 +180,19 @@ func linesDimens(lines []text.Line) layout.Dimensions {
}
}
func align(align text.Alignment, width fixed.Int26_6, maxWidth int) fixed.Int26_6 {
// align returns the x offset that should be applied to text with width so that it
// appears correctly aligned within a space of size maxWidth and with the primary
// text direction dir.
func align(align text.Alignment, dir system.TextDirection, width fixed.Int26_6, maxWidth int) fixed.Int26_6 {
mw := fixed.I(maxWidth)
if dir.Progression() == system.TowardOrigin {
switch align {
case text.Start:
align = text.End
case text.End:
align = text.Start
}
}
switch align {
case text.Middle:
return fixed.I(((mw - width) / 2).Floor())