From 7fc9c134b0e1750cd65e4f9e7a30c58fee8d0525 Mon Sep 17 00:00:00 2001 From: milarin Date: Mon, 24 Apr 2023 16:41:36 +0200 Subject: [PATCH] fixed unicode characters on last column --- draw_buffer.go | 24 +++++++++++++++--------- go.mod | 1 + go.sum | 2 ++ layouts/layout_separator.go | 1 + screen.go | 33 ++++++++++++++++++++++++++------- tests/screen_test.go | 4 ++-- 6 files changed, 47 insertions(+), 18 deletions(-) diff --git a/draw_buffer.go b/draw_buffer.go index 999ea43..6586920 100644 --- a/draw_buffer.go +++ b/draw_buffer.go @@ -1,30 +1,36 @@ package tui import ( + "git.milar.in/milarin/slices" "github.com/gdamore/tcell" + "github.com/mattn/go-runewidth" ) func drawBuffer(scr tcell.Screen, buf *ViewBuffer) { - // buf.ForEach(func(x, y int, rn Rune) { - // scr.SetContent(x, y, rn.Rn, nil, rn.Style) - // }) - - // TODO use runewidth.RuneWidth(rn)? buf.ForEachLine(func(y int, content []Rune) { for x := 0; x < buf.Width(); x++ { rn := content[x] - if rn.Rn >= '─' && rn.Rn <= '╿' { - scr.SetContent(x, y, rn.Rn, []rune{content[x+1].Rn}, rn.Style) - x++ + + extraRuneCount := runewidth.RuneWidth(rn.Rn) - 1 + var extraRunes []Rune + if x+1+extraRuneCount < len(content) { + extraRunes = content[x+1 : x+1+extraRuneCount] } else { - scr.SetContent(x, y, rn.Rn, nil, rn.Style) + extraRunes = content[x+1 : x+1] } + + scr.SetContent(x, y, rn.Rn, slices.Map(extraRunes, getRune), rn.Style) + x += extraRuneCount } }) scr.Show() } +func getRune(rn Rune) rune { + return rn.Rn +} + func truncateBuffer(buf *ViewBuffer, w, h int) *ViewBuffer { if w < 0 { w = buf.Width() diff --git a/go.mod b/go.mod index 0b91197..a936826 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( git.milar.in/milarin/buf2d v1.1.7 git.milar.in/milarin/ds v0.0.2 git.milar.in/milarin/gmath v0.0.3 + git.milar.in/milarin/slices v0.0.8 github.com/gdamore/tcell v1.4.0 github.com/mattn/go-runewidth v0.0.7 ) diff --git a/go.sum b/go.sum index 71a932d..91a64dd 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ git.milar.in/milarin/ds v0.0.2 h1:vCA3mDxZUNfvHpzrdz7SeBUKiPn74NTopo915IUG7I0= git.milar.in/milarin/ds v0.0.2/go.mod h1:HJK7QERcRvV9j7xzEocrKUtW+1q4JB1Ly4Bj54chfwI= git.milar.in/milarin/gmath v0.0.3 h1:ii6rKNItS55O/wtIFhD1cTN2BMwDZjTBmiOocKURvxM= git.milar.in/milarin/gmath v0.0.3/go.mod h1:HDLftG5RLpiNGKiIWh+O2G1PYkNzyLDADO8Cd/1abiE= +git.milar.in/milarin/slices v0.0.8 h1:qN9TE3tkArdTixMKSnwvNPcApwAjxpLVwA5a9k1rm2s= +git.milar.in/milarin/slices v0.0.8/go.mod h1:qMhdtMnfWswc1rHpwgNw33lB84aNEkdBn5BDiYA+G3k= github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/tcell v1.4.0 h1:vUnHwJRvcPQa3tzi+0QI4U9JINXYJlOz9yiaiPQ2wMU= diff --git a/layouts/layout_separator.go b/layouts/layout_separator.go index 0991647..c824b70 100644 --- a/layouts/layout_separator.go +++ b/layouts/layout_separator.go @@ -111,6 +111,7 @@ func (g *SeperatorLayout) OnKeyPressed(event *tui.KeyEvent) (consumed bool) { return true } } + return false } diff --git a/screen.go b/screen.go index be2e617..7e94389 100644 --- a/screen.go +++ b/screen.go @@ -23,6 +23,13 @@ type Screen struct { // Root is the root view which is currently shown on screen Root View + + // Some unicode characters need more bytes than one. For these characters, + // an additional last column will be provided in the internal view buffer. + // That way, these characters can also be shown on the right most column. + // + // You should enable this flag if you have missing unicode characters in the last column. + UnicodeSupport bool } func NewScreen(root View) (*Screen, error) { @@ -142,13 +149,7 @@ func (s *Screen) drawloop() { defer s.handlePanic("panicked while redrawing") for range s.redrawCh { - w, h := s.scr.Size() - - if s.buf == nil || s.buf.Width() != w || s.buf.Height() != h { - s.buf = buf2d.NewBuffer(w, h, DefaultRune) - } else { - s.buf.Fill(DefaultRune) - } + s.prepareViewBuffer() // draw root view rw, rh := s.Root.Layout() @@ -166,6 +167,24 @@ func (s *Screen) drawloop() { } } +func (s *Screen) prepareViewBuffer() { + w, h := s.scr.Size() + + if s.UnicodeSupport { + if s.buf == nil || s.buf.Width() != w-1 || s.buf.Height() != h { + s.buf = buf2d.NewBuffer(w, h, DefaultRune).Sub(0, 0, w-1, h) + } else { + s.buf.Fill(DefaultRune) + } + } else { + if s.buf == nil || s.buf.Width() != w || s.buf.Height() != h { + s.buf = buf2d.NewBuffer(w, h, DefaultRune) + } else { + s.buf.Fill(DefaultRune) + } + } +} + func (s *Screen) handlePanic(msg string) { if err := recover(); err != nil { if e, ok := err.(error); ok { diff --git a/tests/screen_test.go b/tests/screen_test.go index 2011253..1683a6a 100644 --- a/tests/screen_test.go +++ b/tests/screen_test.go @@ -86,11 +86,11 @@ func TestScrollView(t *testing.T) { } func TestBorderView(t *testing.T) { - textView := views.NewTextView("hello world!") + textView := views.NewTextView("hello world! こんにちは!") borderView := views.NewBorderView(textView) //borderView2 := views.NewBorderView(borderView) - screen, err := tui.NewScreen(borderView) + screen, err := tui.NewScreen(views.NewGrowView(borderView)) if err != nil { t.Error(err) return