# Painting in other UI frameworks

`SharpCell.Grid` holds everything about the grid that is not Avalonia or WPF: sizes and positions,
hit testing, selection, copying, scrolling and painting. The two `SpreadsheetView` controls are
thin hosts over it, and a host for another UI framework is the same few calls.

```csharp snippet=painter
var painter = new GridPainter
{
    // Text width in your UI framework's font engine, for fitting numbers and running text.
    MeasureText = (text, font) => text.Length * font.Size * 0.5,
};
painter.Layout = SheetLayout.FromWorksheet(sheet, painter.MaxDigitWidth(sheet));
painter.FrozenRows = sheet.FrozenRows;
painter.FrozenColumns = sheet.FrozenColumns;

var viewport = new GridViewport(OffsetX: 0, OffsetY: 0, Width: 800, Height: 600);
var selection = GridSelection.Cell(new CellPosition(1, 1), sheet);
painter.Paint(canvas, sheet, viewport, selection);   // canvas: your IGridCanvas

// A click, then a drag to (300, 90): what Excel selects, and what is copied.
if (painter.Hit(viewport, x: 120, y: 30, sheet) is { } hit)
    selection = GridSelection.At(hit, sheet).ExtendTo(painter.CellNearest(viewport, 300, 90), sheet);
string copied = GridClipboard.Text(sheet, selection.Area);
```

## The parts

- `SheetLayout` holds the column widths and row heights in pixels, their offsets, the cell under
  an offset and the cells in a rectangle. `SheetLayout.FromWorksheet` converts a sheet's sizes as
  Excel does, from the width of the widest digit of the default font.
- `GridViewport` is what is shown: the scroll offset into the sheet and the size of the grid on
  screen, headers included.
- `GridPainter` paints the part of the sheet in a viewport and the selection onto an `IGridCanvas`,
  and answers where a cell is (`CellBounds`), what is under a point (`HitTest` for cells, `Hit`
  for headers and the corner too), which cell a drag has reached (`CellNearest`, past the edges the
  next one out of view), and where to scroll (`ScrollIntoView`, `Clamp`).
- `GridSelection` is Excel's selection: what a click selects (`At`), and each step of the mouse
  and keyboard (`ExtendTo`, `Extend`, `Move`, `MoveWithin`, `EntireColumns`, `EntireRows`). A host
  maps its input events to these calls; `SpreadsheetView` shows how.
- `GridEditor` changes cells as Excel does when people edit them, typing (`Enter`, through
  SharpCell's `Cell.Input`), Delete (`Clear`) and pasting text (`Paste`), each change one step to
  `Undo` and `Redo`, the workbook recalculated after it.
- `GridClipboard` gives the selected cells as text and as HTML, the forms Excel pastes, and
  `WindowsHtml` wraps the HTML in the clipboard format Windows applications read.
- `IGridCanvas` is what a host implements over its drawing API: fill and stroke rectangles, draw
  lines with a dash pattern, draw text inside bounds, cut off at them, on one line or wrapped.

## Measuring text

`GridPainter.MeasureText` gives the width of text in a font, from the host's font engine. With it,
numbers are fitted to their column, text runs on over empty cells, and row headers widen for long
row numbers. Without it, nothing is fitted and Calibri 11's digit width (7 pixels) is assumed.

`GridFont` sizes are in device-independent pixels: 11 points are 14.67 pixels at 96 DPI.
`GridPainter.FontOf` converts a SharpCell font.
