mirror of https://github.com/buggins/dlangui.git
grids: continue development; simple grid content is shown
This commit is contained in:
parent
1dc6ac7697
commit
1a849c1970
|
@ -63,6 +63,18 @@ struct Rect {
|
||||||
top += dy;
|
top += dy;
|
||||||
bottom += dy;
|
bottom += dy;
|
||||||
}
|
}
|
||||||
|
void expand(int dx, int dy) {
|
||||||
|
left -= dx;
|
||||||
|
right += dx;
|
||||||
|
top -= dy;
|
||||||
|
bottom += dy;
|
||||||
|
}
|
||||||
|
void shrink(int dx, int dy) {
|
||||||
|
left += dx;
|
||||||
|
right -= dx;
|
||||||
|
top += dy;
|
||||||
|
bottom -= dy;
|
||||||
|
}
|
||||||
/// for all fields, sets this.field to rc.field if rc.field > this.field
|
/// for all fields, sets this.field to rc.field if rc.field > this.field
|
||||||
void setMax(Rect rc) {
|
void setMax(Rect rc) {
|
||||||
if (left < rc.left)
|
if (left < rc.left)
|
||||||
|
|
|
@ -407,6 +407,7 @@ struct ClipRectSaver {
|
||||||
private DrawBuf _buf;
|
private DrawBuf _buf;
|
||||||
private Rect _oldClipRect;
|
private Rect _oldClipRect;
|
||||||
private uint _oldAlpha;
|
private uint _oldAlpha;
|
||||||
|
/// apply (intersect) new clip rectangle and alpha to draw buf; restore
|
||||||
this(DrawBuf buf, ref Rect newClipRect, uint newAlpha = 0) {
|
this(DrawBuf buf, ref Rect newClipRect, uint newAlpha = 0) {
|
||||||
_buf = buf;
|
_buf = buf;
|
||||||
_oldClipRect = buf.clipRect;
|
_oldClipRect = buf.clipRect;
|
||||||
|
|
|
@ -134,6 +134,7 @@ class StringGridWidget : GridWidgetBase {
|
||||||
addChild(_vscrollbar);
|
addChild(_vscrollbar);
|
||||||
addChild(_hscrollbar);
|
addChild(_hscrollbar);
|
||||||
styleId = "EDIT_BOX";
|
styleId = "EDIT_BOX";
|
||||||
|
resize(20, 30);
|
||||||
}
|
}
|
||||||
@property override int cols() {
|
@property override int cols() {
|
||||||
return _cols;
|
return _cols;
|
||||||
|
@ -174,6 +175,18 @@ class StringGridWidget : GridWidgetBase {
|
||||||
_data[row][col] = text;
|
_data[row][col] = text;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// zero based index generation of column header - like in Excel - for testing
|
||||||
|
dstring genColHeader(int col) {
|
||||||
|
dstring res;
|
||||||
|
int n1 = col / 26;
|
||||||
|
int n2 = col % 26;
|
||||||
|
if (n1)
|
||||||
|
res ~= n1 + 'A';
|
||||||
|
res ~= n2 + 'A';
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/// set new size
|
/// set new size
|
||||||
void resize(int cols, int rows) {
|
void resize(int cols, int rows) {
|
||||||
if (cols == _cols && rows == _rows)
|
if (cols == _cols && rows == _rows)
|
||||||
|
@ -186,23 +199,36 @@ class StringGridWidget : GridWidgetBase {
|
||||||
_colTitles[i] = i > 0 ? ("col "d ~ to!dstring(i)) : ""d;
|
_colTitles[i] = i > 0 ? ("col "d ~ to!dstring(i)) : ""d;
|
||||||
_rowTitles.length = rows;
|
_rowTitles.length = rows;
|
||||||
_colWidths.length = cols;
|
_colWidths.length = cols;
|
||||||
for (int i = _cols; i < cols; i++)
|
for (int i = _cols; i < cols; i++) {
|
||||||
_colWidths[i] = i == 0 ? 10 : 80;
|
if (i >= _headerCols)
|
||||||
|
_data[0][i] = genColHeader(i - _headerCols);
|
||||||
|
_colWidths[i] = i == 0 ? 20 : 80;
|
||||||
|
}
|
||||||
_rowHeights.length = rows;
|
_rowHeights.length = rows;
|
||||||
int fontHeight = font.height;
|
int fontHeight = font.height;
|
||||||
for (int i = _rows; i < rows; i++)
|
for (int i = _rows; i < rows; i++) {
|
||||||
_rowHeights[i] = fontHeight;
|
if (i >= _headerRows)
|
||||||
|
_data[i][0] = to!dstring(i - _headerRows + 1);
|
||||||
|
_rowHeights[i] = fontHeight + 2;
|
||||||
|
}
|
||||||
_cols = cols;
|
_cols = cols;
|
||||||
_rows = rows;
|
_rows = rows;
|
||||||
}
|
}
|
||||||
/// returns column width (col 0 is row header)
|
|
||||||
|
/// returns column width (index includes col/row headers, if any); returns 0 for columns hidden by scroll at the left
|
||||||
int colWidth(int x) {
|
int colWidth(int x) {
|
||||||
|
if (x >= _headerCols + _fixedCols && x < _headerCols + _fixedCols + _scrollCol)
|
||||||
|
return 0;
|
||||||
return _colWidths[x];
|
return _colWidths[x];
|
||||||
}
|
}
|
||||||
/// returns row height (row 0 is column header)
|
|
||||||
|
/// returns row height (index includes col/row headers, if any); returns 0 for riws hidden by scroll at the top
|
||||||
int rowHeight(int y) {
|
int rowHeight(int y) {
|
||||||
|
if (y >= _headerRows + _fixedRows && y < _headerRows + _fixedRows + _scrollRow)
|
||||||
|
return 0;
|
||||||
return _rowHeights[y];
|
return _rowHeights[y];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// returns cell rectangle relative to client area; row 0 is col headers row; col 0 is row headers column
|
/// returns cell rectangle relative to client area; row 0 is col headers row; col 0 is row headers column
|
||||||
Rect cellRect(int x, int y) {
|
Rect cellRect(int x, int y) {
|
||||||
Rect rc;
|
Rect rc;
|
||||||
|
@ -248,23 +274,19 @@ class StringGridWidget : GridWidgetBase {
|
||||||
}
|
}
|
||||||
/// draw column header
|
/// draw column header
|
||||||
void drawColHeader(DrawBuf buf, Rect rc, int index) {
|
void drawColHeader(DrawBuf buf, Rect rc, int index) {
|
||||||
FontRef fnt = font;
|
//FontRef fnt = font;
|
||||||
buf.fillRect(rc, 0xE0E0E0);
|
//buf.fillRect(rc, 0xE0E0E0);
|
||||||
buf.drawFrame(rc, 0x808080, Rect(1,1,1,1));
|
//buf.drawFrame(rc, 0x808080, Rect(1,1,1,1));
|
||||||
fnt.drawText(buf, rc.left, rc.top, "col"d, 0x000000);
|
//fnt.drawText(buf, rc.left, rc.top, "col"d, 0x000000);
|
||||||
}
|
}
|
||||||
/// draw row header
|
/// draw row header
|
||||||
void drawRowHeader(DrawBuf buf, Rect rc, int index) {
|
void drawRowHeader(DrawBuf buf, Rect rc, int index) {
|
||||||
FontRef fnt = font;
|
//FontRef fnt = font;
|
||||||
buf.fillRect(rc, 0xE0E0E0);
|
//buf.fillRect(rc, 0xE0E0E0);
|
||||||
buf.drawFrame(rc, 0x808080, Rect(1,1,1,1));
|
//buf.drawFrame(rc, 0x808080, Rect(1,1,1,1));
|
||||||
fnt.drawText(buf, rc.left, rc.top, "row"d, 0x000000);
|
//fnt.drawText(buf, rc.left, rc.top, "row"d, 0x000000);
|
||||||
}
|
|
||||||
/// draw cell header
|
|
||||||
void drawCell(DrawBuf buf, Rect rc, int col, int row) {
|
|
||||||
FontRef fnt = font;
|
|
||||||
fnt.drawText(buf, rc.left, rc.top, "sample"d, 0x000000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Measure widget according to desired width and height constraints. (Step 1 of two phase layout).
|
/// Measure widget according to desired width and height constraints. (Step 1 of two phase layout).
|
||||||
override void measure(int parentWidth, int parentHeight) {
|
override void measure(int parentWidth, int parentHeight) {
|
||||||
Rect m = margins;
|
Rect m = margins;
|
||||||
|
@ -306,8 +328,77 @@ class StringGridWidget : GridWidgetBase {
|
||||||
_clientRect.right = vsbrc.left;
|
_clientRect.right = vsbrc.left;
|
||||||
_clientRect.bottom = hsbrc.top;
|
_clientRect.bottom = hsbrc.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// draw cell content
|
||||||
|
void drawCell(DrawBuf buf, Rect rc, int col, int row) {
|
||||||
|
rc.shrink(1, 1);
|
||||||
|
FontRef fnt = font;
|
||||||
|
dstring txt = cellText(col, row);
|
||||||
|
Point sz = fnt.textSize(txt);
|
||||||
|
Align ha = Align.Left;
|
||||||
|
if (col < _headerCols)
|
||||||
|
ha = Align.Right;
|
||||||
|
if (row < _headerRows)
|
||||||
|
ha = Align.HCenter;
|
||||||
|
applyAlign(rc, sz, ha, Align.VCenter);
|
||||||
|
fnt.drawText(buf, rc.left + 1, rc.top + 1, txt, 0x000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// draw cell background
|
||||||
|
void drawCellBackground(DrawBuf buf, Rect rc, int col, int row) {
|
||||||
|
Rect vborder = rc;
|
||||||
|
Rect hborder = rc;
|
||||||
|
vborder.left = vborder.right - 1;
|
||||||
|
hborder.top = hborder.bottom - 1;
|
||||||
|
hborder.right--;
|
||||||
|
if (col < _headerCols || row < _headerRows) {
|
||||||
|
// draw header cell background
|
||||||
|
buf.fillRect(rc, 0x80808080);
|
||||||
|
buf.fillRect(vborder, 0x80FFFFFF);
|
||||||
|
buf.fillRect(hborder, 0x80FFFFFF);
|
||||||
|
} else {
|
||||||
|
// normal cell background
|
||||||
|
buf.fillRect(vborder, 0x80C0C0C0);
|
||||||
|
buf.fillRect(hborder, 0x80C0C0C0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void drawClient(DrawBuf buf) {
|
void drawClient(DrawBuf buf) {
|
||||||
buf.fillRect(_clientRect, 0x80A08080);
|
auto saver = ClipRectSaver(buf, _clientRect, 0);
|
||||||
|
//buf.fillRect(_clientRect, 0x80A08080);
|
||||||
|
Rect rc;
|
||||||
|
for (int phase = 0; phase < 2; phase++) {
|
||||||
|
int yy = 0;
|
||||||
|
for (int y = 0; y < _rows; y++) {
|
||||||
|
int rh = rowHeight(y);
|
||||||
|
rc.top = yy;
|
||||||
|
rc.bottom = yy + rh;
|
||||||
|
if (rh == 0)
|
||||||
|
continue;
|
||||||
|
if (yy > _clientRect.height)
|
||||||
|
break;
|
||||||
|
yy += rh;
|
||||||
|
int xx = 0;
|
||||||
|
for (int x = 0; x < _cols; x++) {
|
||||||
|
int cw = colWidth(x);
|
||||||
|
rc.left = xx;
|
||||||
|
rc.right = xx + cw;
|
||||||
|
if (cw == 0)
|
||||||
|
continue;
|
||||||
|
if (xx > _clientRect.width)
|
||||||
|
break;
|
||||||
|
xx += cw;
|
||||||
|
// draw cell
|
||||||
|
Rect cellRect = rc;
|
||||||
|
cellRect.moveBy(_clientRect.left, _clientRect.top);
|
||||||
|
auto cellSaver = ClipRectSaver(buf, cellRect, 0);
|
||||||
|
if (phase == 0)
|
||||||
|
drawCellBackground(buf, cellRect, x, y);
|
||||||
|
else
|
||||||
|
drawCell(buf, cellRect, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/// Draw widget at its position to buffer
|
/// Draw widget at its position to buffer
|
||||||
override void onDraw(DrawBuf buf) {
|
override void onDraw(DrawBuf buf) {
|
||||||
|
|
|
@ -1086,9 +1086,7 @@ class Widget {
|
||||||
rc.right -= m.right;
|
rc.right -= m.right;
|
||||||
}
|
}
|
||||||
/// Applies alignment for content of size sz - set rectangle rc to aligned value of content inside of initial value of rc.
|
/// Applies alignment for content of size sz - set rectangle rc to aligned value of content inside of initial value of rc.
|
||||||
void applyAlign(ref Rect rc, Point sz) {
|
static void applyAlign(ref Rect rc, Point sz, Align ha, Align va) {
|
||||||
Align va = valign;
|
|
||||||
Align ha = halign;
|
|
||||||
if (va == Align.Bottom) {
|
if (va == Align.Bottom) {
|
||||||
rc.top = rc.bottom - sz.y;
|
rc.top = rc.bottom - sz.y;
|
||||||
} else if (va == Align.VCenter) {
|
} else if (va == Align.VCenter) {
|
||||||
|
@ -1108,6 +1106,12 @@ class Widget {
|
||||||
rc.right = rc.left + sz.x;
|
rc.right = rc.left + sz.x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// Applies alignment for content of size sz - set rectangle rc to aligned value of content inside of initial value of rc.
|
||||||
|
void applyAlign(ref Rect rc, Point sz) {
|
||||||
|
Align va = valign;
|
||||||
|
Align ha = halign;
|
||||||
|
applyAlign(rc, sz, ha, va);
|
||||||
|
}
|
||||||
|
|
||||||
// ===========================================================
|
// ===========================================================
|
||||||
// popup menu support
|
// popup menu support
|
||||||
|
|
Loading…
Reference in New Issue