about summary refs log tree commit diff stats
path: root/src/types/cell.nim
blob: 8820f3512a7626396d0e6dd2cd391d2525541eeb (plain) (blame)
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
import types/color
import utils/strwidth

type
  FormatFlags* = enum
    ffBold
    ffItalic
    ffUnderline
    ffReverse
    ffStrike
    ffOverline
    ffBlink

  Format* = object
    fgcolor*: CellColor
    bgcolor*: CellColor
    flags*: set[FormatFlags]

  SimpleFormatCell* = object
    format*: Format
    pos*: int

  SimpleFlexibleLine* = object
    str*: string
    formats*: seq[SimpleFormatCell]

  SimpleFlexibleGrid* = seq[SimpleFlexibleLine]

  FixedCell* = object
    str*: string
    format*: Format

  FixedGrid* = object
    width*, height*: int
    cells*: seq[FixedCell]

proc `[]=`*(grid: var FixedGrid; i: int; cell: FixedCell) = grid.cells[i] = cell
proc `[]=`*(grid: var FixedGrid; i: BackwardsIndex; cell: FixedCell) =
  grid.cells[i] = cell
proc `[]`*(grid: var FixedGrid; i: int): var FixedCell = grid.cells[i]
proc `[]`*(grid: var FixedGrid; i: BackwardsIndex): var FixedCell =
  grid.cells[i]
proc `[]`*(grid: FixedGrid; i: int): FixedCell = grid.cells[i]
proc `[]`*(grid: FixedGrid; i: BackwardsIndex): FixedCell = grid.cells[i]

proc len*(grid: FixedGrid): int = grid.cells.len
proc high*(grid: FixedGrid): int = grid.cells.high

iterator items*(grid: FixedGrid): FixedCell {.inline.} =
  for cell in grid.cells:
    yield cell

const FormatCodes*: array[FormatFlags, tuple[s, e: uint8]] = [
  ffBold: (1u8, 22u8),
  ffItalic: (3u8, 23u8),
  ffUnderline: (4u8, 24u8),
  ffReverse: (7u8, 27u8),
  ffStrike: (9u8, 29u8),
  ffOverline: (53u8, 55u8),
  ffBlink: (5u8, 25u8),
]

func newFixedGrid*(w: int; h: int = 1): FixedGrid =
  return FixedGrid(width: w, height: h, cells: newSeq[FixedCell](w * h))

func width*(cell: FixedCell): int =
  return cell.str.width()

# Get the first format cell after pos, if any.
func findFormatN*(line: SimpleFlexibleLine; pos: int): int =
  var i = 0
  while i < line.formats.len:
    if line.formats[i].pos > pos:
      break
    inc i
  return i

func findFormat*(line: SimpleFlexibleLine; pos: int): SimpleFormatCell =
  let i = line.findFormatN(pos) - 1
  if i != -1:
    result = line.formats[i]
  else:
    result.pos = -1

func findNextFormat*(line: SimpleFlexibleLine; pos: int): SimpleFormatCell =
  let i = line.findFormatN(pos)
  if i < line.formats.len:
    result = line.formats[i]
  else:
    result.pos = -1