celina/widgets/table

Search:
Group by:

Table widget

This module provides table widgets for displaying structured data in rows and columns, with support for headers, selection, scrolling, and styling.

Types

Column = object
  title*: string
  width*: Option[int]
  alignment*: ColumnAlignment
  style*: Option[Style]
Table column definition
ColumnAlignment = enum
  AlignLeft, AlignCenter, AlignRight
Column text alignment options
SelectionMode = enum
  None, Single, Multiple
Table selection behavior
Table = ref object of Widget
  columns*: seq[Column]
  rows*: seq[TableRow]
  keyboardFocused*: bool ## Keyboard focus. `setFocus`/`isFocused` are the authoritative focus API;
                         ## key navigation is gated on this so the table only consumes keys when
                         ## it actually holds focus.
  selectionMode*: SelectionMode
  selectedIndices*: seq[int]
  highlightedIndex*: int
  scrollOffset*: int
  visibleRowCount*: int
  showHeader*: bool
  borderStyle*: BorderKind
  columnSpacing*: int
  showScrollbar*: bool
  headerStyle*: Style
  normalRowStyle*: Style
  selectedRowStyle*: Style
  highlightedRowStyle*: Style
  borderColor*: Style
  onSelect*: proc (index: int)
  onMultiSelect*: proc (indices: seq[int])
  onHighlight*: proc (index: int)
  onFocus*: proc ()
  onBlur*: proc ()
Table widget for structured data
TableCallbacks = object
  onSelect*: proc (index: int)
  onMultiSelect*: proc (indices: seq[int])
  onHighlight*: proc (index: int)
  onFocus*: proc ()          ## Called when the table gains keyboard focus
  onBlur*: proc ()           ## Called when the table loses keyboard focus
Callback aggregate for table events
TableRow = object
  cells*: seq[string]
  style*: Option[Style]
  selectable*: bool
Table row data
TableStyle = object
  header*: Style             ## Header row style
  normalRow*: Style          ## Normal data row style
  selectedRow*: Style        ## Selected row style
  highlightedRow*: Style     ## Highlighted (focused navigation) row style
  border*: Style             ## Border glyph style
Style aggregate for table colors

Procs

proc addColumn(widget: Table; col: Column) {....raises: [], tags: [], forbids: [].}
Add a column to the table
proc addColumn(widget: Table; title: string; width: Option[int] = none(int)) {.
    ...raises: [], tags: [], forbids: [].}
Add a simple column to the table
proc addRow(widget: Table; cells: seq[string]) {....raises: [], tags: [],
    forbids: [].}
Add a simple row to the table
proc addRow(widget: Table; row: TableRow) {....raises: [], tags: [], forbids: [].}
Add a row to the table
proc borderStyleOptions(widget: Table): Style {....deprecated: "Use `borderColor`",
    raises: [], tags: [], forbids: [].}
Deprecated: Use `borderColor`
Deprecated accessor – use borderColor instead.
proc borderStyleOptions=(widget: Table; val: Style) {.
    ...deprecated: "Use `borderColor=`", raises: [], tags: [], forbids: [].}
Deprecated: Use `borderColor=`
Deprecated setter – use borderColor= instead.
proc calculateColumnWidths(widget: Table; availableWidth: int): seq[int] {.
    ...raises: [], tags: [], forbids: [].}
Calculate actual column widths based on content and constraints
proc calculateTotalLineWidth(columnWidths: seq[int]; columnSpacing: int;
                             hasBorders: bool): int {....raises: [], tags: [],
    forbids: [].}
Calculate the total width needed for a table line including borders and spacing
proc clearRows(widget: Table) {....raises: [Exception], tags: [RootEffect],
                                forbids: [].}
Clear all rows from the table
proc clearSelection(widget: Table) {....raises: [Exception], tags: [RootEffect],
                                     forbids: [].}
Clear all selections
proc column(title: string): Column {....raises: [], tags: [], forbids: [].}
Convenience constructor for simple column
proc column(title: string; alignment: ColumnAlignment): Column {....raises: [],
    tags: [], forbids: [].}
Create column with specific alignment
proc column(title: string; width: int): Column {....raises: [], tags: [],
    forbids: [].}
Create column with fixed width
proc defaultTableStyle(): TableStyle {....raises: [], tags: [], forbids: [].}
Default style aggregate matching the historical per-field defaults.
proc deselectRow(widget: Table; index: int) {....raises: [Exception],
    tags: [RootEffect], forbids: [].}
Deselect a row (for multiple selection mode)
proc formatCell(content: string; width: int; alignment: ColumnAlignment): string {.
    ...raises: [], tags: [], forbids: [].}
Format a cell's content within the given width
proc fullPageDown(widget: Table) {....raises: [Exception], tags: [RootEffect],
                                   forbids: [].}
Scroll down by full page (vim: Ctrl-F)
proc fullPageUp(widget: Table) {....raises: [Exception], tags: [RootEffect],
                                 forbids: [].}
Scroll up by full page (vim: Ctrl-B)
proc handleKeyEvent(widget: Table; event: KeyEvent): EventResult {.
    ...raises: [Exception], tags: [RootEffect], forbids: [].}
Handle keyboard input for the table with vim-like navigation. Returns erConsume when the table reacted to the event, erContinue otherwise.
proc highlightFirst(widget: Table) {....raises: [Exception], tags: [RootEffect],
                                     forbids: [].}
Move highlight to first selectable row (vim: gg)
proc highlightLast(widget: Table) {....raises: [Exception], tags: [RootEffect],
                                    forbids: [].}
Move highlight to last selectable row (vim: G)
proc highlightNext(widget: Table) {....raises: [Exception], tags: [RootEffect],
                                    forbids: [].}
Move highlight to next selectable row
proc highlightPrevious(widget: Table) {....raises: [Exception], tags: [RootEffect],
                                        forbids: [].}
Move highlight to previous selectable row
proc isSelected(widget: Table; index: int): bool {....raises: [], tags: [],
    forbids: [].}
Check if a row is selected
proc newColumn(title: string; width: Option[int] = none(int);
               alignment: ColumnAlignment = AlignLeft;
               style: Option[Style] = none(Style)): Column {....raises: [],
    tags: [], forbids: [].}
Create a new table column
proc newTable(columns: seq[Column] = @[]; rows: seq[TableRow] = @[];
              selectionMode: SelectionMode = Single; showHeader: bool = true;
              border: BorderKind = bkSimple; columnSpacing: int = 1;
              showScrollbar: bool = true;
              style: TableStyle = defaultTableStyle();
              callbacks: TableCallbacks = TableCallbacks()): Table {....raises: [],
    tags: [], forbids: [].}
Create a new Table widget using TableStyle and TableCallbacks aggregates.
proc newTable(columns: seq[Column]; rows: seq[TableRow];
              selectionMode: SelectionMode; showHeader: bool;
              borderStyle: BorderKind; columnSpacing: int; showScrollbar: bool;
              headerStyle: Style; normalRowStyle: Style = defaultStyle();
              selectedRowStyle: Style = style(Black, White);
              highlightedRowStyle: Style = style(White, BrightBlack);
              borderStyleOptions: Style = style(BrightBlack);
              onSelect: proc (index: int) = nil;
              onMultiSelect: proc (indices: seq[int]) = nil;
              onHighlight: proc (index: int) = nil): Table {.
    ...deprecated: "Use newTable with TableStyle/TableCallbacks aggregate",
    raises: [], tags: [], forbids: [].}
Deprecated: Use newTable with TableStyle/TableCallbacks aggregate

Deprecated: legacy form taking individual style and callback parameters.

The required positional headerStyle disambiguates this overload from the aggregate-based one.

proc newTableRow(cells: seq[string]; style: Option[Style] = none(Style);
                 selectable: bool = true): TableRow {....raises: [], tags: [],
    forbids: [].}
Create a new table row
proc pageDown(widget: Table) {....raises: [Exception], tags: [RootEffect],
                               forbids: [].}
Scroll down by one page (vim: Ctrl-D)
proc pageUp(widget: Table) {....raises: [Exception], tags: [RootEffect],
                             forbids: [].}
Scroll up by one page (vim: Ctrl-U)
proc removeColumn(widget: Table; index: int) {....raises: [], tags: [], forbids: [].}
Remove a column from the table
proc removeRow(widget: Table; index: int) {....raises: [Exception],
    tags: [RootEffect], forbids: [].}
Remove a row from the table
proc scrollDown(widget: Table; lines: int = 1) {....raises: [], tags: [],
    forbids: [].}
Scroll the table down
proc scrollUp(widget: Table; lines: int = 1) {....raises: [], tags: [], forbids: [].}
Scroll the table up
proc selectRow(widget: Table; index: int) {....raises: [Exception],
    tags: [RootEffect], forbids: [].}
Select a row (respecting selection mode)
proc setData(widget: Table; rows: seq[seq[string]]) {....raises: [Exception],
    tags: [RootEffect], forbids: [].}
Replace all row data
proc table(columns: seq[string]): Table {....raises: [], tags: [], forbids: [].}
Convenience constructor from column titles
proc table(columns: seq[string]; rows: seq[seq[string]]): Table {....raises: [],
    tags: [], forbids: [].}
Convenience constructor from column titles and row data
proc tableRow(cells: seq[string]): TableRow {....raises: [], tags: [], forbids: [].}
Convenience constructor for simple row
proc tableRow(cells: seq[string]; style: Style): TableRow {....raises: [],
    tags: [], forbids: [].}
Create styled row
proc toggleSelection(widget: Table; index: int) {....raises: [Exception],
    tags: [RootEffect], forbids: [].}
Toggle selection of a row

Methods

method canFocus(widget: Table): bool {....raises: [], tags: [], forbids: [].}
Tables can receive focus when they have selectable rows
method getMinSize(widget: Table): Size {....raises: [], tags: [], forbids: [].}
Get minimum size for table widget
method getPreferredSize(widget: Table; available: Size): Size {....raises: [],
    tags: [], forbids: [].}
Get preferred size for table widget
method handleEvent(widget`gensym88: Table; event`gensym88: Event;
                   area`gensym88: Rect): EventResult {....raises: [Exception],
    tags: [RootEffect], forbids: [].}
method isFocused(widget: Table): bool {....raises: [], tags: [], forbids: [].}
method render(widget: Table; area: Rect; buf: var Buffer) {....raises: [],
    tags: [], forbids: [].}
Render the table widget
method setFocus(widget: Table; focused: bool) {....raises: [Exception],
    tags: [RootEffect], forbids: [].}
Set keyboard focus. Tracked via keyboardFocused, which gates key handling. Acquiring focus is refused when the table is not focusable (canFocus), so a table with no selectable rows never silently swallows navigation keys. Fires onFocus/onBlur on a real focus transition.