#pragma once #include "Layout.h" #include #include struct KeyboardMetrics { qreal padding = 6; // around the whole keyboard qreal gap = 8; // between keys, horizontally and vertically qreal blockGap = 24; // between side-by-side blocks (main, navigation, numpad) }; // The keys on screen: blocks of rows, side by side. // A block can reserve room (minUnits, minRows) so that swapping its rows, e.g. // switching layers, moves nothing else; its keys stretch into the room. struct Block { QList rows; bool fillHeight = false; // spans the full height instead of max(rows, minRows) shared rows qreal minUnits = 0; // reserved width qsizetype minRows = 0; // reserved height, in shared rows qsizetype fixedRows = 0; // leading rows that keep the shared height when the block stretches }; // Lays out blocks to fill `size`. Returns one rect per key, block by block in // row order (spacers included). One key unit has the same width everywhere; // rows share one height, set by the tallest block that doesn't fill, and // shorter blocks sit at the bottom. A block given more height than its rows // need (fillHeight, minRows) grows its rows after fixedRows to take it up. // In each block, stretch keys grow to make their row as wide as the widest // one (or minUnits), and remaining shorter rows are centered. QList computeKeyRects(const QList &blocks, QSizeF size, KeyboardMetrics metrics = {}); inline QList computeKeyRects(const Layer &layer, QSizeF size, KeyboardMetrics metrics = {}) { return computeKeyRects({{layer.rows}}, size, metrics); } // Total width of a row in key units, before stretching. qreal rowUnits(const Row &row); // Width of all blocks in key units, ignoring gaps. qreal totalUnits(const QList &blocks); // Shared rows of the tallest block that sets the row height (see computeKeyRects). qsizetype totalRows(const QList &blocks);