2017-12-26 22:19:42 -07:00
|
|
|
package exhibit
|
|
|
|
|
|
|
|
import (
|
2017-12-30 03:23:20 -07:00
|
|
|
"image"
|
2017-12-26 22:19:42 -07:00
|
|
|
"sync"
|
|
|
|
)
|
|
|
|
|
2017-12-27 01:20:41 -07:00
|
|
|
type ListEntry interface {
|
2017-12-27 16:49:20 -07:00
|
|
|
String() string
|
2017-12-27 01:20:41 -07:00
|
|
|
Attributes() Attributes
|
|
|
|
}
|
|
|
|
|
2017-12-26 22:19:42 -07:00
|
|
|
type ListWidget struct {
|
2017-12-30 12:25:56 -07:00
|
|
|
blockLock sync.Mutex
|
|
|
|
block Block
|
2017-12-30 12:24:00 -07:00
|
|
|
|
2017-12-30 14:42:13 -07:00
|
|
|
rightAlignLock sync.Mutex
|
|
|
|
rightAlign bool
|
|
|
|
|
|
|
|
borderLock sync.Mutex
|
|
|
|
border Border
|
2017-12-26 22:19:42 -07:00
|
|
|
|
|
|
|
listLock sync.Mutex
|
2017-12-27 01:20:41 -07:00
|
|
|
list [][]Cell
|
|
|
|
|
|
|
|
listBuf [][]Cell
|
2017-12-26 22:19:42 -07:00
|
|
|
}
|
|
|
|
|
2017-12-30 12:24:00 -07:00
|
|
|
func (l *ListWidget) Size() image.Point {
|
|
|
|
l.blockLock.Lock()
|
|
|
|
defer l.blockLock.Unlock()
|
|
|
|
|
2017-12-30 03:23:20 -07:00
|
|
|
return l.block.Rect.Size()
|
2017-12-27 17:03:14 -07:00
|
|
|
}
|
|
|
|
|
2017-12-30 03:23:20 -07:00
|
|
|
func (l *ListWidget) SetSize(p image.Point) {
|
2017-12-30 12:24:00 -07:00
|
|
|
l.blockLock.Lock()
|
|
|
|
defer l.blockLock.Unlock()
|
|
|
|
|
2017-12-30 03:23:20 -07:00
|
|
|
l.block.SetSize(p)
|
2017-12-27 15:25:38 -07:00
|
|
|
}
|
|
|
|
|
2017-12-30 13:08:07 -07:00
|
|
|
func (l *ListWidget) Origin() image.Point {
|
|
|
|
l.blockLock.Lock()
|
|
|
|
defer l.blockLock.Unlock()
|
|
|
|
|
|
|
|
return l.block.Rect.Min
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *ListWidget) SetOrigin(p image.Point) {
|
|
|
|
l.blockLock.Lock()
|
|
|
|
defer l.blockLock.Unlock()
|
|
|
|
|
|
|
|
l.block.SetOrigin(p)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *ListWidget) Render(origin image.Point) Block {
|
2017-12-30 03:23:20 -07:00
|
|
|
l.blockLock.Lock()
|
|
|
|
defer l.blockLock.Unlock()
|
2017-12-26 22:19:42 -07:00
|
|
|
|
2017-12-30 03:23:20 -07:00
|
|
|
b := NewBlock(0, 0, 0, 0)
|
2017-12-30 13:08:07 -07:00
|
|
|
b.Rect = l.block.Rect.Add(origin)
|
2017-12-26 22:19:42 -07:00
|
|
|
|
2017-12-30 03:23:20 -07:00
|
|
|
for k, v := range l.block.Cells {
|
2017-12-30 13:08:07 -07:00
|
|
|
k = k.Add(origin)
|
2017-12-30 03:23:20 -07:00
|
|
|
b.Cells[k] = v
|
2017-12-26 22:19:42 -07:00
|
|
|
}
|
|
|
|
|
2017-12-30 03:23:20 -07:00
|
|
|
return b
|
2017-12-26 22:19:42 -07:00
|
|
|
}
|
|
|
|
|
2017-12-27 01:20:41 -07:00
|
|
|
func (l *ListWidget) AddEntry(entry ListEntry) {
|
2017-12-30 03:23:20 -07:00
|
|
|
l.listLock.Lock()
|
|
|
|
defer l.listLock.Unlock()
|
|
|
|
|
2017-12-27 01:20:41 -07:00
|
|
|
if l.listBuf == nil {
|
|
|
|
l.listBuf = make([][]Cell, 1)
|
|
|
|
} else {
|
|
|
|
l.listBuf = append(l.listBuf, []Cell{})
|
|
|
|
}
|
2017-12-26 22:19:42 -07:00
|
|
|
|
2017-12-27 01:20:41 -07:00
|
|
|
index := len(l.listBuf) - 1
|
2017-12-26 22:19:42 -07:00
|
|
|
|
2017-12-27 01:20:41 -07:00
|
|
|
for _, r := range entry.String() {
|
|
|
|
cell := Cell{}
|
|
|
|
cell.Value = r
|
|
|
|
cell.Attrs = entry.Attributes()
|
|
|
|
|
|
|
|
l.listBuf[index] = append(l.listBuf[index], cell)
|
2017-12-26 22:19:42 -07:00
|
|
|
}
|
2017-12-27 01:20:41 -07:00
|
|
|
}
|
2017-12-26 22:19:42 -07:00
|
|
|
|
2017-12-27 01:20:41 -07:00
|
|
|
func (l *ListWidget) Commit() {
|
2017-12-26 22:19:42 -07:00
|
|
|
l.listLock.Lock()
|
2017-12-27 01:20:41 -07:00
|
|
|
l.list = append([][]Cell{}, l.listBuf...)
|
2017-12-26 22:19:42 -07:00
|
|
|
l.listLock.Unlock()
|
2017-12-27 01:20:41 -07:00
|
|
|
l.listBuf = nil
|
2017-12-26 22:19:42 -07:00
|
|
|
l.recalculateCells()
|
|
|
|
}
|
|
|
|
|
2017-12-30 14:42:13 -07:00
|
|
|
func (l *ListWidget) Border() Border {
|
|
|
|
l.borderLock.Lock()
|
|
|
|
defer l.borderLock.Unlock()
|
|
|
|
|
|
|
|
return l.border
|
|
|
|
}
|
|
|
|
func (l *ListWidget) SetBorder(b Border) {
|
|
|
|
l.borderLock.Lock()
|
2017-12-26 22:19:42 -07:00
|
|
|
if l.border == b {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
l.border = b
|
2017-12-30 14:42:13 -07:00
|
|
|
l.borderLock.Unlock()
|
2017-12-26 22:19:42 -07:00
|
|
|
|
|
|
|
l.recalculateCells()
|
|
|
|
}
|
|
|
|
|
2017-12-30 14:42:13 -07:00
|
|
|
func (l *ListWidget) RightAlign() bool {
|
|
|
|
l.rightAlignLock.Lock()
|
|
|
|
defer l.rightAlignLock.Unlock()
|
|
|
|
|
|
|
|
return l.rightAlign
|
|
|
|
}
|
|
|
|
|
2017-12-26 22:19:42 -07:00
|
|
|
func (l *ListWidget) SetRightAlign(b bool) {
|
2017-12-30 14:42:13 -07:00
|
|
|
l.rightAlignLock.Lock()
|
2017-12-26 22:19:42 -07:00
|
|
|
if l.rightAlign == b {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
l.rightAlign = b
|
2017-12-30 14:42:13 -07:00
|
|
|
l.rightAlignLock.Unlock()
|
2017-12-26 22:19:42 -07:00
|
|
|
|
|
|
|
l.recalculateCells()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *ListWidget) recalculateCells() {
|
|
|
|
l.listLock.Lock()
|
|
|
|
defer l.listLock.Unlock()
|
|
|
|
|
2017-12-30 03:23:20 -07:00
|
|
|
l.blockLock.Lock()
|
2017-12-30 14:42:13 -07:00
|
|
|
rect := l.block.Rect
|
2017-12-30 03:23:20 -07:00
|
|
|
l.blockLock.Unlock()
|
2017-12-26 22:19:42 -07:00
|
|
|
|
2017-12-30 14:42:13 -07:00
|
|
|
origin := rect.Min
|
|
|
|
size := rect.Size()
|
|
|
|
|
|
|
|
rightAlign := l.RightAlign()
|
|
|
|
|
|
|
|
border := l.Border()
|
|
|
|
|
2017-12-30 03:23:20 -07:00
|
|
|
cells := make(map[image.Point]Cell)
|
2017-12-26 22:19:42 -07:00
|
|
|
|
2017-12-30 03:23:20 -07:00
|
|
|
var i, bx, by int
|
2017-12-30 14:42:13 -07:00
|
|
|
if border.Visible {
|
2017-12-30 03:23:20 -07:00
|
|
|
size = size.Add(image.Point{2, 2})
|
|
|
|
bx = 1
|
|
|
|
by = 1
|
|
|
|
}
|
2017-12-26 22:19:42 -07:00
|
|
|
|
2017-12-30 03:23:20 -07:00
|
|
|
for x := 0; x < size.X; x++ {
|
|
|
|
for y := 0; y < size.Y; y++ {
|
|
|
|
c := Cell{Value: ' '}
|
2017-12-30 13:08:07 -07:00
|
|
|
point := image.Pt(x, y).Add(origin)
|
2017-12-26 22:19:42 -07:00
|
|
|
|
2017-12-30 14:42:13 -07:00
|
|
|
cell, ok := border.Cell(point, rect)
|
|
|
|
if ok {
|
|
|
|
cells[point] = cell
|
|
|
|
continue
|
2017-12-30 03:23:20 -07:00
|
|
|
}
|
2017-12-26 22:19:42 -07:00
|
|
|
|
2017-12-30 03:23:20 -07:00
|
|
|
if y < len(l.list)+by {
|
|
|
|
length := len(l.list[y-by])
|
2017-12-26 22:19:42 -07:00
|
|
|
|
2017-12-30 14:42:13 -07:00
|
|
|
if rightAlign {
|
2017-12-30 03:23:20 -07:00
|
|
|
i = (size.X - x - length - bx) * -1
|
|
|
|
} else {
|
|
|
|
i = x - bx
|
|
|
|
}
|
2017-12-26 22:19:42 -07:00
|
|
|
|
2017-12-30 03:23:20 -07:00
|
|
|
if i < length && i >= 0 {
|
|
|
|
c = l.list[y-by][i]
|
|
|
|
}
|
2017-12-26 22:19:42 -07:00
|
|
|
|
2017-12-30 13:08:07 -07:00
|
|
|
cells[point] = c
|
2017-12-30 03:23:20 -07:00
|
|
|
}
|
2017-12-26 22:19:42 -07:00
|
|
|
}
|
2017-12-30 03:23:20 -07:00
|
|
|
}
|
2017-12-26 22:19:42 -07:00
|
|
|
|
2017-12-30 03:23:20 -07:00
|
|
|
l.blockLock.Lock()
|
|
|
|
l.block.Cells = cells
|
|
|
|
l.blockLock.Unlock()
|
|
|
|
}
|