From 7daab97fab6ff5de7804ed70cf9d27281a4339c5 Mon Sep 17 00:00:00 2001 From: Chris Waldon Date: Wed, 16 Mar 2022 16:01:41 -0400 Subject: [PATCH] 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 --- widget/editor.go | 6 +++--- widget/label.go | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/widget/editor.go b/widget/editor.go index cc77fc7a..e373319b 100644 --- a/widget/editor.go +++ b/widget/editor.go @@ -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) } diff --git a/widget/label.go b/widget/label.go index 71e192e8..14d11c25 100644 --- a/widget/label.go +++ b/widget/label.go @@ -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())