Skip to content

Commit

Permalink
Start of base screen refactoring.
Browse files Browse the repository at this point in the history
A lot of functionality is duplicated across screen implementations,
and adding convenience methods is onerous because one needs to touch
each implementation with what is mostly copy-paste coding.

This represents the start of refactoring to eliminate redundant code
from each implemenation and provide for it in a common layer.
  • Loading branch information
gdamore committed Dec 4, 2023
1 parent fe52739 commit ef4f9cc
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 41 deletions.
16 changes: 2 additions & 14 deletions console_win.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//go:build windows
// +build windows

// Copyright 2022 The TCell Authors
// Copyright 2023 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
Expand Down Expand Up @@ -175,7 +175,7 @@ var vtCursorStyles = map[CursorStyle]string{
// with the current process. The Screen makes use of the Windows Console
// API to display content and read events.
func NewConsoleScreen() (Screen, error) {
return &cScreen{}, nil
return &baseScreen{screenImpl: &cScreen{}}, nil
}

func (s *cScreen) Init() error {
Expand Down Expand Up @@ -894,14 +894,6 @@ func (s *cScreen) mapStyle(style Style) uint16 {
return attr
}

func (s *cScreen) SetCell(x, y int, style Style, ch ...rune) {
if len(ch) > 0 {
s.SetContent(x, y, ch[0], ch[1:], style)
} else {
s.SetContent(x, y, ' ', nil, style)
}
}

func (s *cScreen) SetContent(x, y int, primary rune, combining []rune, style Style) {
s.Lock()
if !s.fini {
Expand Down Expand Up @@ -1154,10 +1146,6 @@ func (s *cScreen) resize() {
_ = s.PostEvent(NewEventResize(w, h))
}

func (s *cScreen) Clear() {
s.Fill(' ', s.style)
}

func (s *cScreen) Fill(r rune, style Style) {
s.cells.Fill(r, style)
}
Expand Down
59 changes: 58 additions & 1 deletion screen.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ type Screen interface {
// Tty returns the underlying Tty. If the screen is not a terminal, the
// returned bool will be false
Tty() (Tty, bool)

}

// NewScreen returns a default Screen suitable for the user's terminal
Expand Down Expand Up @@ -302,3 +301,61 @@ const (
CursorStyleBlinkingBar
CursorStyleSteadyBar
)

// screenImpl is a subset of Screen that can be used with baseScreen to formulate
// a complete implementation of Screen. See Screen for doc comments about methods.
type screenImpl interface {
Init() error
Fini()
Fill(rune, Style)
GetContent(x, y int) (primary rune, combining []rune, style Style, width int)
SetContent(x int, y int, primary rune, combining []rune, style Style)
SetStyle(style Style)
ShowCursor(x int, y int)
HideCursor()
SetCursorStyle(CursorStyle)
Size() (width, height int)
ChannelEvents(ch chan<- Event, quit <-chan struct{})
PollEvent() Event
HasPendingEvent() bool
PostEvent(ev Event) error
PostEventWait(ev Event)
EnableMouse(...MouseFlags)
DisableMouse()
EnablePaste()
DisablePaste()
EnableFocus()
DisableFocus()
HasMouse() bool
Colors() int
Show()
Sync()
CharacterSet() string
RegisterRuneFallback(r rune, subst string)
UnregisterRuneFallback(r rune)
CanDisplay(r rune, checkFallbacks bool) bool
Resize(int, int, int, int)
HasKey(Key) bool
Suspend() error
Resume() error
Beep() error
SetSize(int, int)
LockRegion(x, y, width, height int, lock bool)
Tty() (Tty, bool)
}

type baseScreen struct {
screenImpl
}

func (b *baseScreen) SetCell(x int, y int, style Style, ch ...rune) {
if len(ch) > 0 {
b.SetContent(x, y, ch[0], ch[1:], style)
} else {
b.SetContent(x, y, ' ', nil, style)
}
}

func (b *baseScreen) Clear() {
b.Fill(' ', StyleDefault)
}
14 changes: 1 addition & 13 deletions tscreen.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func NewTerminfoScreenFromTtyTerminfo(tty Tty, ti *terminfo.Terminfo) (s Screen,
t.fallback[k] = v
}

return t, nil
return &baseScreen{screenImpl: t}, nil
}

// NewTerminfoScreenFromTty returns a Screen using a custom Tty implementation.
Expand Down Expand Up @@ -595,10 +595,6 @@ func (t *tScreen) SetStyle(style Style) {
t.Unlock()
}

func (t *tScreen) Clear() {
t.Fill(' ', t.style)
}

func (t *tScreen) Fill(r rune, style Style) {
t.Lock()
if !t.fini {
Expand All @@ -622,14 +618,6 @@ func (t *tScreen) GetContent(x, y int) (rune, []rune, Style, int) {
return mainc, combc, style, width
}

func (t *tScreen) SetCell(x, y int, style Style, ch ...rune) {
if len(ch) > 0 {
t.SetContent(x, y, ch[0], ch[1:], style)
} else {
t.SetContent(x, y, ' ', nil, style)
}
}

func (t *tScreen) encodeRune(r rune, buf []byte) []byte {

nb := make([]byte, 6)
Expand Down
14 changes: 1 addition & 13 deletions wscreen.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func NewTerminfoScreen() (Screen, error) {
t := &wScreen{}
t.fallback = make(map[rune]string)

return t, nil
return &baseScreen{screenImpl: t}, nil
}

type wScreen struct {
Expand Down Expand Up @@ -79,10 +79,6 @@ func (t *wScreen) SetStyle(style Style) {
t.Unlock()
}

func (t *wScreen) Clear() {
t.Fill(' ', t.style)
}

func (t *wScreen) Fill(r rune, style Style) {
t.Lock()
t.cells.Fill(r, style)
Expand All @@ -102,14 +98,6 @@ func (t *wScreen) GetContent(x, y int) (rune, []rune, Style, int) {
return mainc, combc, style, width
}

func (t *wScreen) SetCell(x, y int, style Style, ch ...rune) {
if len(ch) > 0 {
t.SetContent(x, y, ch[0], ch[1:], style)
} else {
t.SetContent(x, y, ' ', nil, style)
}
}

// paletteColor gives a more natural palette color actually matching
// typical XTerm. We might in the future want to permit styling these
// via CSS.
Expand Down

0 comments on commit ef4f9cc

Please sign in to comment.