-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdrawing-area.go
More file actions
133 lines (113 loc) · 2.76 KB
/
Copy pathdrawing-area.go
File metadata and controls
133 lines (113 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package main
import (
"encoding/gob"
term "github.com/nsf/termbox-go"
"github.com/nvlled/wind"
"github.com/nvlled/wind/size"
"os"
)
type invalidFileError string
func (err invalidFileError) Error() string {
return string(err) + ": invalid file format"
}
type drawingArea struct {
Buffer [][]term.Cell
cursor *pos
flush bool
baseX int
baseY int
actualW int
actualH int
Shit int
//redrawList []pos
}
func init() {
var buf [][]term.Cell
gob.Register(buf)
gob.Register(&drawingArea{})
}
func (dArea *drawingArea) Width() size.T {
return size.Const(len(dArea.Buffer[0]))
}
func (dArea *drawingArea) Height() size.T {
return size.Const(len(dArea.Buffer))
}
func (dArea *drawingArea) Render(canvas wind.Canvas) {
// possibly need synchronization from other threads
dArea.baseX, dArea.baseY = canvas.Base()
dArea.actualW, dArea.actualH = canvas.Dimension()
// I could avoid the need to refer to canvas' properties by
// * avoiding the use of termbox.SetCursor
// * defer drawing operations
// redraw.add(x, y)
curs := dArea.cursor
if curs.x >= 0 && curs.y >= 0 {
bx, by := canvas.Base()
term.SetCursor(curs.x+bx, curs.y+by)
}
if dArea.flush {
for y, row := range dArea.Buffer {
for x, cell := range row {
canvas.Draw(x, y,
cell.Ch, uint16(cell.Fg), uint16(cell.Bg))
}
}
dArea.flush = false
} /*TODO: else {
for _, pos := range dArea.redraw {
//draw as done above
}
}*/
}
func (dArea *drawingArea) Draw(x, y int, ch rune, fg, bg term.Attribute) {
dArea.Buffer[y][x] = term.Cell{ch, fg, bg}
// redraw(x, y)
term.SetCell(dArea.baseX+x, dArea.baseY+y, ch, fg, bg)
}
func (dArea *drawingArea) DrawCell(x, y int, cell term.Cell) {
dArea.Draw(x, y, cell.Ch, cell.Fg, cell.Bg)
}
func (dArea *drawingArea) Flush() {
dArea.flush = true
}
func (dArea *drawingArea) ActualSize() (int, int) {
return dArea.actualW, dArea.actualH
}
func saveDrawingArea(filename string, dArea *drawingArea) error {
file, err := os.Create(filename)
if err != nil {
return err
}
enc := gob.NewEncoder(file)
return enc.Encode(dArea)
}
func loadDrawingArea(filename string) (*drawingArea, error) {
var dArea drawingArea
file, err := os.Open(filename)
if err != nil {
return nil, err
}
dec := gob.NewDecoder(file)
err = dec.Decode(&dArea)
if err != nil {
return nil, invalidFileError(filename)
}
dArea.cursor = newpos(0, 0)
return &dArea, nil
}
func NewDrawingArea(width, height int) *drawingArea {
// width and height must be greater than zero
buffer := createBuffer(width, height)
return &drawingArea{
Buffer: buffer,
cursor: newpos(0, 0),
flush: false,
}
}
func createBuffer(width, height int) [][]term.Cell {
buffer := make([][]term.Cell, height)
for y := range buffer {
buffer[y] = make([]term.Cell, width)
}
return buffer
}