grid navigation: support PageUp/PageDown and Ctrl+PageUp/Ctrl+PageDown

This commit is contained in:
Vadim Lopatin 2014-06-05 12:05:37 +04:00
parent 16839c4f36
commit f7f5e9e9e9
1 changed files with 97 additions and 6 deletions

View File

@ -451,7 +451,38 @@ class StringGridWidget : GridWidgetBase {
return super.onMouseEvent(event); return super.onMouseEvent(event);
} }
protected void calcScrollableAreaPos(ref Rect fullyVisibleCells, ref Rect fullyVisibleCellsRect) {
fullyVisibleCells.left = _headerCols + _fixedCols + _scrollCol;
fullyVisibleCells.top = _headerRows + _fixedRows + _scrollRow;
Rect rc;
int xx = 0;
for (int i = 0; i < _cols && xx < _clientRect.width; i++) {
if (i == fullyVisibleCells.left)
fullyVisibleCellsRect.left = fullyVisibleCellsRect.right = xx;
int w = colWidth(i);
if (i >= fullyVisibleCells.left && xx + w <= _clientRect.width) {
fullyVisibleCellsRect.right = xx + w;
fullyVisibleCells.right = i;
}
xx += w;
}
int yy = 0;
for (int i = 0; i < _rows && yy < _clientRect.height; i++) {
if (i == fullyVisibleCells.top)
fullyVisibleCellsRect.top = fullyVisibleCellsRect.bottom = yy;
int w = rowHeight(i);
if (i >= fullyVisibleCells.top && yy + w <= _clientRect.height) {
fullyVisibleCellsRect.bottom = yy + w;
fullyVisibleCells.bottom = i;
}
yy += w;
}
}
override protected bool handleAction(const Action a) { override protected bool handleAction(const Action a) {
Rect fullyVisibleCells;
Rect fullyVisibleCellsRect;
calcScrollableAreaPos(fullyVisibleCells, fullyVisibleCellsRect);
switch (a.id) { switch (a.id) {
case GridActions.Left: case GridActions.Left:
selectCell(_col - 1, _row); selectCell(_col - 1, _row);
@ -466,12 +497,16 @@ class StringGridWidget : GridWidgetBase {
selectCell(_col, _row + 1); selectCell(_col, _row + 1);
return true; return true;
case GridActions.LineBegin: case GridActions.LineBegin:
if (_scrollCol > 0 && _col > _headerCols + _fixedCols + _scrollCol)
selectCell(_headerCols + _fixedCols + _scrollCol, _row);
else {
if (_scrollCol > 0) { if (_scrollCol > 0) {
_scrollCol = 0; _scrollCol = 0;
updateScrollBars(); updateScrollBars();
invalidate(); invalidate();
} }
selectCell(_headerCols, _row); selectCell(_headerCols, _row);
}
return true; return true;
case GridActions.LineEnd: case GridActions.LineEnd:
selectCell(_cols - 1, _row); selectCell(_cols - 1, _row);
@ -487,6 +522,62 @@ class StringGridWidget : GridWidgetBase {
case GridActions.DocumentEnd: case GridActions.DocumentEnd:
selectCell(_col, _rows - 1); selectCell(_col, _rows - 1);
return true; return true;
case GridActions.PageBegin:
if (_scrollRow > 0)
selectCell(_col, _headerRows + _fixedRows + _scrollRow);
else
selectCell(_col, _headerRows);
return true;
case GridActions.PageEnd:
int found = -1;
for (int i = _fixedRows; i < _rows; i++) {
Rect rc = cellRect(_col, i);
if (rc.bottom <= _clientRect.height)
found = i;
else
break;
}
if (found >= 0)
selectCell(_col, found);
return true;
case GridActions.PageUp:
if (_row > fullyVisibleCells.top) {
// not at top scrollable cell
selectCell(_col, fullyVisibleCells.top);
} else {
// at top of scrollable area
if (_scrollRow > 0) {
// scroll up line by line
int prevRow = _row;
for (int i = prevRow - 1; i >= _headerRows; i--) {
selectCell(_col, i);
calcScrollableAreaPos(fullyVisibleCells, fullyVisibleCellsRect);
if (fullyVisibleCells.bottom <= prevRow)
break;
}
} else {
// scrolled to top - move upper cell
selectCell(_col, _headerRows);
}
}
return true;
case GridActions.PageDown:
if (_row < _rows) {
if (_row < fullyVisibleCells.bottom) {
// not at top scrollable cell
selectCell(_col, fullyVisibleCells.bottom);
} else {
// scroll down
int prevRow = _row;
for (int i = prevRow + 1; i < _rows; i++) {
selectCell(_col, i);
calcScrollableAreaPos(fullyVisibleCells, fullyVisibleCellsRect);
if (fullyVisibleCells.top >= prevRow)
break;
}
}
}
return true;
default: default:
return super.handleAction(a); return super.handleAction(a);
} }