mirror of https://github.com/buggins/dlangui.git
grids: navigation and scroll with keys
This commit is contained in:
parent
a9b921350e
commit
16839c4f36
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue