Documentation
¶
Overview ¶
Package grid provides StringGrid — a terminal-mode data grid with rows, named columns, in-place cell editing, mouse navigation, per- column alignment and validation, multi-cell selection, click-to-sort headers, an optional filter row, copy-to-clipboard, column resize and reorder via mouse drag, frozen leading columns, CSV import / export, and a virtual-data-source mode for huge datasets.
Ported from Grid.pas (TStringGrid). The Pascal version's per-cell undo log isn't here yet (that's editor scope); everything else from the FVTest grid-test page is.
Index ¶
- type Alignment
- type CSVOptions
- type Cell
- type Column
- type SelectionMode
- type SortDirection
- type SortKey
- type StringGrid
- func (g *StringGrid) AddRow(values []string)
- func (g *StringGrid) AddSortKey(col int)
- func (g *StringGrid) AutoFitAll()
- func (g *StringGrid) AutoFitColumn(col int)
- func (g *StringGrid) Cell(row, col int) string
- func (g *StringGrid) ClearFilters()
- func (g *StringGrid) ClearModified()
- func (g *StringGrid) ClearSort()
- func (g *StringGrid) ColCount() int
- func (g *StringGrid) CopySelection()
- func (g *StringGrid) CycleSort(col int)
- func (g *StringGrid) Draw()
- func (g *StringGrid) ExtendTo(col, row int)
- func (g *StringGrid) FindNext(dir int) bool
- func (g *StringGrid) GetTypeID() string
- func (g *StringGrid) HandleEvent(ev *drivers.Event)
- func (g *StringGrid) HasActiveFilters() bool
- func (g *StringGrid) LoadCSV(r io.Reader, opts CSVOptions) error
- func (g *StringGrid) MoveTo(col, row int)
- func (g *StringGrid) PasteClipboard()
- func (g *StringGrid) RawRowAt(visRow int) int
- func (g *StringGrid) RawRowCount() int
- func (g *StringGrid) RemoveRow(raw int)
- func (g *StringGrid) ResetColumnWidth(col int)
- func (g *StringGrid) RowCount() int
- func (g *StringGrid) SaveCSV(w io.Writer, opts CSVOptions) error
- func (g *StringGrid) SetCell(row, col int, value string)
- func (g *StringGrid) SetFilter(col int, text string)
- func (g *StringGrid) SetFind(needle string)
- func (g *StringGrid) SetRows(rows [][]string)
- func (g *StringGrid) Sort(col int, dir SortDirection)
- func (g *StringGrid) ToggleColumnVisible(col int)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CSVOptions ¶
type CSVOptions struct {
Delimiter rune // zero → ','
LineEnd string // zero → "\n"
AutoDetectDelimiter bool
IncludeHeader bool // export header row; import treats first row as data
}
CSVOptions controls CSV import / export. Zero value is minimal and boring (`CSVOptions{}` → comma, LF, no header). Use DefaultCSVOptions for spreadsheet-style output (CRLF + header). AutoDetectDelimiter, on import only, sniffs the first non-empty line for the most frequent of {',', ';', '\t'} and overrides Delimiter.
func DefaultCSVOptions ¶
func DefaultCSVOptions() CSVOptions
DefaultCSVOptions returns the spreadsheet-style configuration: comma delimiter, CRLF line endings, header on export / import.
type Cell ¶
type Cell struct{ Col, Row int }
Cell coords. (0, 0) is the top-left data cell — the header row / column don't have addresses in this scheme.
type Column ¶
type Column struct {
Title string
Width int
MinWidth int // 0 = no lower clamp on resize / auto-fit
MaxWidth int // 0 = no upper clamp
Align Alignment
Color uint16 // per-column override; 0 = use the grid default
ReadOnly bool
Sortable bool
// Hidden, when true, suppresses rendering / hit-testing for this
// column while keeping it in the data + filters. Zero value
// (Column{}) is visible — flipping the sense from a previous
// Visible bool removes the New()-time "force every column on"
// kludge that prevented constructing initially-hidden columns.
Hidden bool
DefaultValue string // used by AddRow() / SetRowCount() to fill new cells
Validator validators.Validator
Compare func(a, b string) int // typed comparison; nil = string compare
}
Column describes one column. Validator (optional) runs on commit of an edit; rejection bounces the user back into edit mode. Sortable can be cleared to lock a column out of header-click sorting. The optional Compare hook is used for typed sorts (e.g. numeric); when nil, the grid falls back to lexicographic string compare.
type SelectionMode ¶
type SelectionMode int
SelectionMode controls how selections expand. Cell = a single cell (anchor == focus). Range = a rectangular block. Row = full row(s).
const ( SelectCell SelectionMode = iota SelectRange SelectRow )
type SortDirection ¶
type SortDirection int
SortDirection — Asc, Desc, or None (unsorted).
const ( SortNone SortDirection = iota SortAsc SortDesc )
type SortKey ¶
type SortKey struct {
Col int
Dir SortDirection
}
SortKey is one entry in a multi-column sort. Multiple keys form a lexicographic comparison: when the primary key ties, the secondary breaks the tie, and so on.
type StringGrid ¶
type StringGrid struct {
views.Base
Columns []Column
// Selection. Focus is the "active" corner the cursor moves; Anchor
// is the opposite end of the range. Cell vs Range vs Row is the
// Mode toggle.
Anchor, Focus Cell
Mode SelectionMode
Top int // first visible row (in visible/filtered index space)
LeftCol int // first visible column (in column-order space)
HasHeader bool
// FixedCols pins the first N columns so they don't scroll
// horizontally. The pin is visual only — Anchor/Focus still
// address pinned columns the same as any others.
FixedCols int
// FixedRows pins the first N rows (in visible / post-sort order) so
// they stay on screen even when the body scrolls.
FixedRows int
// ShowFilter toggles the per-column filter row below the header.
// Filters[i] is the case-insensitive substring required in column i
// (empty = no filter).
ShowFilter bool
Filters []string
// ShowRowMarker paints a "►" glyph over the leading padding cell of
// the focused row, so the active row stays visible even when focus
// moves elsewhere on the screen. Purely cosmetic — doesn't change
// column geometry or hit-testing.
ShowRowMarker bool
// Visual toggles. All default to true via New(); callers can flip
// any of them off to get a stripped-down look.
ShowGridLines bool // "│" column dividers between cells
ShowZebra bool // alternating row backgrounds
ShowHeaderUnderline bool // the "─" row under the header titles
// Behavior toggles. All default to true.
ReadOnly bool // disables every mutation path from input
AllowResize bool // mouse-drag on column separator
AllowReorder bool // mouse-drag on column header
AllowDragSelect bool // mouse-drag on cells extends selection
AllowWheelScroll bool // wheel scrolls the body
// Sort state. SortKeys[0] is the primary sort column; subsequent
// entries break ties. Empty = unsorted. SortCol / SortDir mirror
// the primary key for back-compat with existing display code.
SortKeys []SortKey
SortCol int
SortDir SortDirection
// FindText is the active incremental-search substring (set by
// FindFirst / FindNext); used purely for cell highlighting.
FindText string
// Per-cell color hook. Called for every data cell during Draw with
// the base attr the grid would use; returning a non-zero override
// is painted instead. Useful for conditional formatting / heatmaps.
OnCellAttr func(row, col int, base uint16) uint16
// Edit callbacks. OnBeforeEdit can deny an edit by returning false.
// OnAfterEdit fires after a successful commit. OnCellFocused fires
// when MoveTo / arrow keys / mouse change Focus.
OnBeforeEdit func(row, col int, current string) bool
OnAfterEdit func(row, col int, oldVal, newVal string)
OnCellFocused func(row, col int)
// Modified is set true after any data-mutating edit and cleared by
// SetRows / LoadCSV / SaveCSV / ClearModified.
Modified bool
// Virtual mode. When OnGetCell is non-nil, rows is ignored and the
// callback supplies cell data on demand. VirtualRowCount is the
// reported total row count in this mode.
OnGetCell func(row, col int) string
OnSetCell func(row, col int, value string)
VirtualRowCount int
HScroll *views.ScrollBar
VScroll *views.ScrollBar
// contains filtered or unexported fields
}
StringGrid is a 2D grid of text cells.
func New ¶
New constructs an empty grid with the given columns. All visual / behavior toggles default to "on" — turn the ones you don't want off individually rather than passing a flags blob.
func (*StringGrid) AddRow ¶
func (g *StringGrid) AddRow(values []string)
AddRow appends a row. Missing cells are filled from each column's DefaultValue (or "" when unset). Sets the Modified flag.
func (*StringGrid) AddSortKey ¶
func (g *StringGrid) AddSortKey(col int)
AddSortKey appends col as a secondary sort key, or — if col is already in the chain — cycles its direction (Asc → Desc → remove). Used by Shift-click on header to build multi-column sorts.
func (*StringGrid) AutoFitAll ¶
func (g *StringGrid) AutoFitAll()
AutoFitAll auto-fits every visible column. Convenience wrapper.
func (*StringGrid) AutoFitColumn ¶
func (g *StringGrid) AutoFitColumn(col int)
AutoFitColumn scans every currently-visible row, plus the column title, and resizes the column so the widest entry fits without truncation. Clamped by MinWidth / MaxWidth and the 3-cell global minimum. Triggered by double-clicking the column separator.
func (*StringGrid) Cell ¶
func (g *StringGrid) Cell(row, col int) string
Cell returns the displayed cell at (visible-row, col). Use this for reading what the user sees, not for editing internal state.
func (*StringGrid) ClearFilters ¶
func (g *StringGrid) ClearFilters()
ClearFilters wipes all filter strings.
func (*StringGrid) ClearModified ¶
func (g *StringGrid) ClearModified()
ClearModified resets the dirty-data flag. Use it after persisting the grid through a non-CSV path that the grid can't detect itself.
func (*StringGrid) ColCount ¶
func (g *StringGrid) ColCount() int
ColCount returns the column count.
func (*StringGrid) CopySelection ¶
func (g *StringGrid) CopySelection()
CopySelection copies the selected cells to the clipboard as TSV. Rows are separated by '\n', cells by '\t'. Multi-line cell contents have their tabs/newlines stripped so the output stays one cell per field — TV cells are single-line anyway.
func (*StringGrid) CycleSort ¶
func (g *StringGrid) CycleSort(col int)
CycleSort advances col through asc → desc → unsorted. Used by a plain header click. Only fires when the column is Sortable.
func (*StringGrid) Draw ¶
func (g *StringGrid) Draw()
Draw paints header (if any), optional filter row, then visible rows.
func (*StringGrid) ExtendTo ¶
func (g *StringGrid) ExtendTo(col, row int)
ExtendTo moves the focus end of the selection, keeping the anchor fixed. Shift+arrow / Shift+click are the entry points.
func (*StringGrid) FindNext ¶
func (g *StringGrid) FindNext(dir int) bool
FindNext jumps Focus to the next cell whose text contains FindText. dir = +1 for forward, -1 for backward. Wraps. No-op when FindText is empty or no match exists. Returns true on a successful jump.
func (*StringGrid) GetTypeID ¶
func (g *StringGrid) GetTypeID() string
GetTypeID for serial registry.
func (*StringGrid) HandleEvent ¶
func (g *StringGrid) HandleEvent(ev *drivers.Event)
HandleEvent dispatches keyboard / mouse events.
func (*StringGrid) HasActiveFilters ¶
func (g *StringGrid) HasActiveFilters() bool
HasActiveFilters returns true if any column has a non-empty filter.
func (*StringGrid) LoadCSV ¶
func (g *StringGrid) LoadCSV(r io.Reader, opts CSVOptions) error
LoadCSV parses CSV from r and replaces the grid's rows. Uses encoding/csv so malformed input (notably EOF inside a quoted field) surfaces as an error — the previous hand-rolled parser silently accepted truncated quotes.
func (*StringGrid) MoveTo ¶
func (g *StringGrid) MoveTo(col, row int)
MoveTo sets the active cell + collapses selection to it.
func (*StringGrid) PasteClipboard ¶
func (g *StringGrid) PasteClipboard()
PasteClipboard pastes the clipboard's TSV (or single line) into the grid starting at the focused cell. Empty / no clipboard is a no-op. Honors grid ReadOnly. Auto-expands the row count if the paste overflows past the end (non-virtual mode only).
func (*StringGrid) RawRowAt ¶
func (g *StringGrid) RawRowAt(visRow int) int
RawRowAt maps a visible row index to its underlying raw row. Returns -1 if visRow is out of range. Use this when you need to edit the underlying storage (e.g. RemoveRow) and only have a visible-row index from Focus / a mouse hit.
func (*StringGrid) RawRowCount ¶
func (g *StringGrid) RawRowCount() int
RawRowCount returns the unfiltered row count (virtual or in-memory).
func (*StringGrid) RemoveRow ¶
func (g *StringGrid) RemoveRow(raw int)
RemoveRow drops the raw row at the given index from the underlying store. No-op in virtual mode (the caller's data source owns the rows there). Selection is clamped after the deletion.
func (*StringGrid) ResetColumnWidth ¶
func (g *StringGrid) ResetColumnWidth(col int)
ResetColumnWidth restores the column to MinWidth (when set) or 12. Useful after a long auto-fit or manual drag the user wants to undo.
func (*StringGrid) RowCount ¶
func (g *StringGrid) RowCount() int
RowCount returns the number of VISIBLE rows (after filtering / sorting). For the underlying raw count, use RawRowCount.
func (*StringGrid) SaveCSV ¶
func (g *StringGrid) SaveCSV(w io.Writer, opts CSVOptions) error
SaveCSV writes the grid's data to w using encoding/csv. The export reflects the current filter/sort (visible rows in their displayed order) and includes all columns — Column.Hidden is visual state, not a data filter.
LineEnd only respects "\n" vs "\r\n"; encoding/csv.Writer doesn't expose finer line-ending control. Other values are interpreted as CRLF if they contain '\r', else LF.
func (*StringGrid) SetCell ¶
func (g *StringGrid) SetCell(row, col int, value string)
SetCell updates the (row, col) value. In non-virtual mode it mutates the backing slice (and expands it if needed). In virtual mode it calls OnSetCell. Sets Modified and fires OnAfterEdit when the value actually changes.
func (*StringGrid) SetFilter ¶
func (g *StringGrid) SetFilter(col int, text string)
SetFilter sets the filter substring for column col. Empty value clears it.
func (*StringGrid) SetFind ¶
func (g *StringGrid) SetFind(needle string)
SetFind installs a case-insensitive incremental-search needle. Matching cells light up; FindNext jumps the cursor between them. Empty needle clears the highlight.
func (*StringGrid) SetRows ¶
func (g *StringGrid) SetRows(rows [][]string)
SetRows replaces all cell data. Clears the Modified flag because the new data is the baseline by definition.
func (*StringGrid) Sort ¶
func (g *StringGrid) Sort(col int, dir SortDirection)
Sort sets the active sort column and direction. Call with (col, SortNone) to clear sorting. Replaces any existing multi-key sort; use AddSortKey to extend instead.
func (*StringGrid) ToggleColumnVisible ¶
func (g *StringGrid) ToggleColumnVisible(col int)
ToggleColumnVisible flips Visible for col. The grid keeps the column's underlying data; it just stops rendering / hit-testing it.