grids: navigation and scroll with keys

This commit is contained in:
Vadim Lopatin 2014-06-05 10:58:55 +04:00
parent a9b921350e
commit 16839c4f36
1 changed files with 128 additions and 21 deletions

View File

@ -112,6 +112,38 @@ enum GridActions : int {
Left, Left,
/// move selection right /// move selection right
Right, Right,
/// move cursor one page up
PageUp,
/// move cursor one page up with selection
SelectPageUp,
/// move cursor one page down
PageDown,
/// move cursor one page down with selection
SelectPageDown,
/// move cursor to the beginning of page
PageBegin,
/// move cursor to the beginning of page with selection
SelectPageBegin,
/// move cursor to the end of page
PageEnd,
/// move cursor to the end of page with selection
SelectPageEnd,
/// move cursor to the beginning of line
LineBegin,
/// move cursor to the beginning of line with selection
SelectLineBegin,
/// move cursor to the end of line
LineEnd,
/// move cursor to the end of line with selection
SelectLineEnd,
/// move cursor to the beginning of document
DocumentBegin,
/// move cursor to the beginning of document with selection
SelectDocumentBegin,
/// move cursor to the end of document
DocumentEnd,
/// move cursor to the end of document with selection
SelectDocumentEnd,
} }
/** /**
@ -146,13 +178,16 @@ class StringGridWidget : GridWidgetBase {
this(string ID = null) { this(string ID = null) {
super(ID); super(ID);
_headerCols = 1;
_headerRows = 1;
_vscrollbar = new ScrollBar("vscrollbar", Orientation.Vertical); _vscrollbar = new ScrollBar("vscrollbar", Orientation.Vertical);
_hscrollbar = new ScrollBar("hscrollbar", Orientation.Horizontal); _hscrollbar = new ScrollBar("hscrollbar", Orientation.Horizontal);
addChild(_vscrollbar); addChild(_vscrollbar);
addChild(_hscrollbar); addChild(_hscrollbar);
styleId = "EDIT_BOX"; styleId = "EDIT_BOX";
// create sample grid content
_headerCols = 1;
_headerRows = 1;
_fixedCols = 2;
_fixedRows = 2;
resize(20, 30); resize(20, 30);
_col = 3; _col = 3;
_row = 4; _row = 4;
@ -166,6 +201,14 @@ class StringGridWidget : GridWidgetBase {
new Action(GridActions.Down, KeyCode.DOWN, 0), new Action(GridActions.Down, KeyCode.DOWN, 0),
new Action(GridActions.Left, KeyCode.LEFT, 0), new Action(GridActions.Left, KeyCode.LEFT, 0),
new Action(GridActions.Right, KeyCode.RIGHT, 0), new Action(GridActions.Right, KeyCode.RIGHT, 0),
new Action(GridActions.LineBegin, KeyCode.HOME, 0),
new Action(GridActions.LineEnd, KeyCode.END, 0),
new Action(GridActions.PageUp, KeyCode.PAGEUP, 0),
new Action(GridActions.PageDown, KeyCode.PAGEDOWN, 0),
new Action(GridActions.PageBegin, KeyCode.PAGEUP, KeyFlag.Control),
new Action(GridActions.PageEnd, KeyCode.PAGEDOWN, KeyFlag.Control),
new Action(GridActions.DocumentBegin, KeyCode.HOME, KeyFlag.Control),
new Action(GridActions.DocumentEnd, KeyCode.END, KeyFlag.Control),
]); ]);
focusable = true; focusable = true;
} }
@ -280,7 +323,7 @@ class StringGridWidget : GridWidgetBase {
if (i == y) if (i == y)
rc.top = yy; rc.top = yy;
yy += rowHeight(i); yy += rowHeight(i);
if (i == x) { if (i == y) {
rc.bottom = yy; rc.bottom = yy;
break; break;
} }
@ -325,6 +368,56 @@ class StringGridWidget : GridWidgetBase {
return false; return false;
} }
/// update scrollbar positions
void updateScrollBars() {
// TODO
}
/// ensure that cell is visible (scroll if necessary)
void makeCellVisible(int col, int row) {
bool scrolled = false;
Rect rc = cellRect(col, row);
if (col >= _headerCols + _fixedCols && col < _headerCols + _fixedCols + _scrollCol) {
// scroll to the left
_scrollCol = col - _headerCols - _fixedCols;
scrolled = true;
} else {
while (rc.right > _clientRect.width && _scrollCol < _cols - _fixedCols - _headerCols - 1) {
_scrollCol++;
rc = cellRect(col, row);
scrolled = true;
}
}
if (row >= _headerRows + _fixedRows && row < _headerRows + _fixedRows + _scrollRow) {
// scroll to the left
_scrollRow = row - _headerRows - _fixedRows;
scrolled = true;
} else {
while (rc.bottom > _clientRect.height && _scrollRow < _rows - _fixedRows - _headerRows - 1) {
_scrollRow++;
rc = cellRect(col, row);
scrolled = true;
}
}
if (scrolled) {
updateScrollBars();
invalidate();
}
}
bool selectCell(int col, int row, bool makeVisible = true) {
if (_col == col && _row == row)
return false; // same position
if (col < _headerCols || row < _headerRows || col >= _cols || row >= _rows)
return false; // out of range
_col = col;
_row = row;
invalidate();
if (makeVisible)
makeCellVisible(_col, _row);
return true;
}
/// handle mouse wheel events /// handle mouse wheel events
override bool onMouseEvent(MouseEvent event) { override bool onMouseEvent(MouseEvent event) {
if (visibility != Visibility.Visible) if (visibility != Visibility.Visible)
@ -344,18 +437,14 @@ class StringGridWidget : GridWidgetBase {
} }
if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) { if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) {
if (cellFound && normalCell) { if (cellFound && normalCell) {
_col = c; selectCell(c, r);
_row = r;
invalidate();
} }
return true; return true;
} }
if (event.action == MouseAction.Move && (event.flags & MouseFlag.LButton)) { if (event.action == MouseAction.Move && (event.flags & MouseFlag.LButton)) {
// TODO: selection // TODO: selection
if (cellFound && normalCell) { if (cellFound && normalCell) {
_col = c; selectCell(c, r);
_row = r;
invalidate();
} }
return true; return true;
} }
@ -365,24 +454,38 @@ class StringGridWidget : GridWidgetBase {
override protected bool handleAction(const Action a) { override protected bool handleAction(const Action a) {
switch (a.id) { switch (a.id) {
case GridActions.Left: case GridActions.Left:
if (_col > _headerCols) selectCell(_col - 1, _row);
_col--;
invalidate();
return true; return true;
case GridActions.Right: case GridActions.Right:
if (_col < _cols - 1) selectCell(_col + 1, _row);
_col++;
invalidate();
return true; return true;
case GridActions.Up: case GridActions.Up:
if (_row > _headerRows) selectCell(_col, _row - 1);
_row--;
invalidate();
return true; return true;
case GridActions.Down: case GridActions.Down:
if (_row < _rows - 1) selectCell(_col, _row + 1);
_row++; return true;
invalidate(); case GridActions.LineBegin:
if (_scrollCol > 0) {
_scrollCol = 0;
updateScrollBars();
invalidate();
}
selectCell(_headerCols, _row);
return true;
case GridActions.LineEnd:
selectCell(_cols - 1, _row);
return true;
case GridActions.DocumentBegin:
if (_scrollRow > 0) {
_scrollRow = 0;
updateScrollBars();
invalidate();
}
selectCell(_col, _headerRows);
return true;
case GridActions.DocumentEnd:
selectCell(_col, _rows - 1);
return true; return true;
default: default:
return super.handleAction(a); return super.handleAction(a);
@ -499,6 +602,10 @@ class StringGridWidget : GridWidgetBase {
buf.fillRect(hborder, 0x80202020); buf.fillRect(hborder, 0x80202020);
} else { } else {
// normal cell background // normal cell background
if (col < _headerCols + _fixedCols || row < _headerRows + _fixedRows) {
// fixed cell background
buf.fillRect(rc, 0x80E0E0E0);
}
buf.fillRect(vborder, 0x80C0C0C0); buf.fillRect(vborder, 0x80C0C0C0);
buf.fillRect(hborder, 0x80C0C0C0); buf.fillRect(hborder, 0x80C0C0C0);
if (selectedCell) if (selectedCell)