From ae2c4a8044f254b540b391b4837f1a23e3a17c0b Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Sat, 18 Mar 2023 19:58:58 -0500 Subject: [PATCH] screen: extend interface with LockRegion method Extend the Screen interface with a new LockRegion method. This method sets or unsets a lock on a region of cells. This will be used in subsequent commits to enable direct drawing to the underlying TTY. The locks are necessary in order to prevent cells from being drawn on top of a directly drawn cell. Implement this interface for the three screen implementations included in the library. --- screen.go | 4 ++++ simulation.go | 15 +++++++++++++++ tscreen.go | 16 ++++++++++++++++ wscreen.go | 15 +++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/screen.go b/screen.go index bd35a89..75a71e0 100644 --- a/screen.go +++ b/screen.go @@ -255,6 +255,10 @@ type Screen interface { // does not support application-initiated resizing, whereas the legacy terminal does. // Also, some emulators can support this but may have it disabled by default. SetSize(int, int) + + // LockRegion sets or unsets a lock on a region of cells. A lock on a + // cell prevents the cell from being redrawn. + LockRegion(x, y, width, height int, lock bool) } // NewScreen returns a default Screen suitable for the user's terminal diff --git a/simulation.go b/simulation.go index b18b664..98ae6f8 100644 --- a/simulation.go +++ b/simulation.go @@ -553,3 +553,18 @@ func (s *simscreen) Suspend() error { func (s *simscreen) Resume() error { return nil } + +func (s *simscreen) LockRegion(x, y, width, height int, lock bool) { + s.Lock() + defer s.Unlock() + for j := y; j < (y + height); j += 1 { + for i := x; i < (x + width); i += 1 { + switch lock { + case true: + s.back.LockCell(i, j) + case false: + s.back.UnlockCell(i, j) + } + } + } +} diff --git a/tscreen.go b/tscreen.go index 5248290..127c47b 100644 --- a/tscreen.go +++ b/tscreen.go @@ -1852,6 +1852,22 @@ func (t *tScreen) Resume() error { return t.engage() } + +func (t *tScreen) LockRegion(x, y, width, height int, lock bool) { + t.Lock() + defer t.Unlock() + for j := y; j < (y + height); j += 1 { + for i := x; i < (x + width); i += 1 { + switch lock { + case true: + t.cells.LockCell(i, j) + case false: + t.cells.UnlockCell(i, j) + } + } + } +} + // engage is used to place the terminal in raw mode and establish screen size, etc. // Think of this is as tcell "engaging" the clutch, as it's going to be driving the // terminal interface. diff --git a/wscreen.go b/wscreen.go index 90965b0..4c398aa 100644 --- a/wscreen.go +++ b/wscreen.go @@ -562,6 +562,21 @@ func (t *wScreen) Beep() error { return nil } +func (t *wScreen) LockRegion(x, y, width, height int, lock bool) { + t.Lock() + defer t.Unlock() + for j := y; j < (y + height); j += 1 { + for i := x; i < (x + width); i += 1 { + switch lock { + case true: + t.cells.LockCell(i, j) + case false: + t.cells.UnlockCell(i, j) + } + } + } +} + // WebKeyNames maps string names reported from HTML // (KeyboardEvent.key) to tcell accepted keys. var WebKeyNames = map[string]Key{