mirror of https://github.com/buggins/dlangui.git
Merge pull request #339 from igor84/multiSelect
Added multi selection to string grid and filedlg, issue #23
This commit is contained in:
commit
e4d156cfae
|
@ -384,6 +384,7 @@ extern (C) int UIAppMain(string[] args) {
|
||||||
UIString caption;
|
UIString caption;
|
||||||
caption = "Open Text File"d;
|
caption = "Open Text File"d;
|
||||||
FileDialog dlg = new FileDialog(caption, window, null);
|
FileDialog dlg = new FileDialog(caption, window, null);
|
||||||
|
dlg.allowMultipleFiles = true;
|
||||||
dlg.addFilter(FileFilterEntry(UIString("FILTER_ALL_FILES", "All files (*)"d), "*"));
|
dlg.addFilter(FileFilterEntry(UIString("FILTER_ALL_FILES", "All files (*)"d), "*"));
|
||||||
dlg.addFilter(FileFilterEntry(UIString("FILTER_TEXT_FILES", "Text files (*.txt)"d), "*.txt"));
|
dlg.addFilter(FileFilterEntry(UIString("FILTER_TEXT_FILES", "Text files (*.txt)"d), "*.txt"));
|
||||||
dlg.addFilter(FileFilterEntry(UIString("FILTER_SOURCE_FILES", "Source files"d), "*.d;*.dd;*.c;*.cc;*.cpp;*.h;*.hpp"));
|
dlg.addFilter(FileFilterEntry(UIString("FILTER_SOURCE_FILES", "Source files"d), "*.d;*.dd;*.c;*.cc;*.cpp;*.h;*.hpp"));
|
||||||
|
@ -391,7 +392,8 @@ extern (C) int UIAppMain(string[] args) {
|
||||||
//dlg.filterIndex = 2;
|
//dlg.filterIndex = 2;
|
||||||
dlg.dialogResult = delegate(Dialog dlg, const Action result) {
|
dlg.dialogResult = delegate(Dialog dlg, const Action result) {
|
||||||
if (result.id == ACTION_OPEN.id) {
|
if (result.id == ACTION_OPEN.id) {
|
||||||
string filename = result.stringParam;
|
string[] filenames = (cast(FileDialog)dlg).filenames;
|
||||||
|
foreach (filename; filenames) {
|
||||||
if (filename.endsWith(".d") || filename.endsWith(".txt") || filename.endsWith(".cpp") || filename.endsWith(".h") || filename.endsWith(".c")
|
if (filename.endsWith(".d") || filename.endsWith(".txt") || filename.endsWith(".cpp") || filename.endsWith(".h") || filename.endsWith(".c")
|
||||||
|| filename.endsWith(".json") || filename.endsWith(".dd") || filename.endsWith(".ddoc") || filename.endsWith(".xml") || filename.endsWith(".html")
|
|| filename.endsWith(".json") || filename.endsWith(".dd") || filename.endsWith(".ddoc") || filename.endsWith(".xml") || filename.endsWith(".html")
|
||||||
|| filename.endsWith(".html") || filename.endsWith(".css") || filename.endsWith(".log") || filename.endsWith(".hpp")) {
|
|| filename.endsWith(".html") || filename.endsWith(".css") || filename.endsWith(".log") || filename.endsWith(".hpp")) {
|
||||||
|
@ -415,6 +417,7 @@ extern (C) int UIAppMain(string[] args) {
|
||||||
window.showMessageBox(UIString("FileOpen result"d), UIString("Filename: "d ~ toUTF32(filename)));
|
window.showMessageBox(UIString("FileOpen result"d), UIString("Filename: "d ~ toUTF32(filename)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
dlg.show();
|
dlg.show();
|
||||||
|
@ -950,6 +953,7 @@ void main()
|
||||||
grid.fixedCols = 3;
|
grid.fixedCols = 3;
|
||||||
grid.fixedRows = 2;
|
grid.fixedRows = 2;
|
||||||
//grid.rowSelect = true; // testing full row selection
|
//grid.rowSelect = true; // testing full row selection
|
||||||
|
grid.multiSelect = true;
|
||||||
grid.selectCell(4, 6, false);
|
grid.selectCell(4, 6, false);
|
||||||
// create sample grid content
|
// create sample grid content
|
||||||
for (int y = 0; y < grid.rows; y++) {
|
for (int y = 0; y < grid.rows; y++) {
|
||||||
|
|
|
@ -56,6 +56,10 @@ struct Point {
|
||||||
Point opBinary(string op)(Point v) if (op == "-") {
|
Point opBinary(string op)(Point v) if (op == "-") {
|
||||||
return Point(x - v.x, y - v.y);
|
return Point(x - v.x, y - v.y);
|
||||||
}
|
}
|
||||||
|
int opCmp(ref const Point b) const {
|
||||||
|
if (x == b.x) return y - b.y;
|
||||||
|
return x - b.x;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 2D rectangle
|
/// 2D rectangle
|
||||||
|
|
|
@ -120,6 +120,7 @@ class FileDialog : Dialog, CustomGridCellAdapter {
|
||||||
protected bool _isOpenDialog;
|
protected bool _isOpenDialog;
|
||||||
|
|
||||||
protected bool _showHiddenFiles;
|
protected bool _showHiddenFiles;
|
||||||
|
protected bool _allowMultipleFiles;
|
||||||
|
|
||||||
protected string[string] _filetypeIcons;
|
protected string[string] _filetypeIcons;
|
||||||
|
|
||||||
|
@ -183,6 +184,18 @@ class FileDialog : Dialog, CustomGridCellAdapter {
|
||||||
_filename = s;
|
_filename = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// all the selected filenames
|
||||||
|
@property string[] filenames() {
|
||||||
|
string[] res;
|
||||||
|
res.reserve(_fileList.selection.length);
|
||||||
|
int i = 0;
|
||||||
|
foreach (val; _fileList.selection) {
|
||||||
|
res ~= _entries[val.y];
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
@property bool showHiddenFiles() {
|
@property bool showHiddenFiles() {
|
||||||
return _showHiddenFiles;
|
return _showHiddenFiles;
|
||||||
}
|
}
|
||||||
|
@ -191,6 +204,14 @@ class FileDialog : Dialog, CustomGridCellAdapter {
|
||||||
_showHiddenFiles = b;
|
_showHiddenFiles = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property bool allowMultipleFiles() {
|
||||||
|
return _allowMultipleFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@property void allowMultipleFiles(bool b) {
|
||||||
|
_allowMultipleFiles = b;
|
||||||
|
}
|
||||||
|
|
||||||
/// return currently selected filter value - array of patterns like ["*.txt", "*.rtf"]
|
/// return currently selected filter value - array of patterns like ["*.txt", "*.rtf"]
|
||||||
@property string[] selectedFilter() {
|
@property string[] selectedFilter() {
|
||||||
if (_filterIndex >= 0 && _filterIndex < _filters.length)
|
if (_filterIndex >= 0 && _filterIndex < _filters.length)
|
||||||
|
@ -575,6 +596,7 @@ class FileDialog : Dialog, CustomGridCellAdapter {
|
||||||
_fileList.setColTitle(3, "Modified"d);
|
_fileList.setColTitle(3, "Modified"d);
|
||||||
_fileList.showRowHeaders = false;
|
_fileList.showRowHeaders = false;
|
||||||
_fileList.rowSelect = true;
|
_fileList.rowSelect = true;
|
||||||
|
_fileList.multiSelect = _allowMultipleFiles;
|
||||||
_fileList.cellPopupMenu = &getCellPopupMenu;
|
_fileList.cellPopupMenu = &getCellPopupMenu;
|
||||||
_fileList.menuItemAction = &handleAction;
|
_fileList.menuItemAction = &handleAction;
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ import dlangui.widgets.controls;
|
||||||
import dlangui.widgets.scroll;
|
import dlangui.widgets.scroll;
|
||||||
import dlangui.widgets.menu;
|
import dlangui.widgets.menu;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
|
import std.container.rbtree;
|
||||||
import std.algorithm : equal;
|
import std.algorithm : equal;
|
||||||
|
|
||||||
/// cellPopupMenu signal handler interface
|
/// cellPopupMenu signal handler interface
|
||||||
|
@ -151,12 +152,20 @@ enum GridActions : int {
|
||||||
None = 0,
|
None = 0,
|
||||||
/// move selection up
|
/// move selection up
|
||||||
Up = 2000,
|
Up = 2000,
|
||||||
|
/// expend selection up
|
||||||
|
SelectUp,
|
||||||
/// move selection down
|
/// move selection down
|
||||||
Down,
|
Down,
|
||||||
|
/// expend selection down
|
||||||
|
SelectDown,
|
||||||
/// move selection left
|
/// move selection left
|
||||||
Left,
|
Left,
|
||||||
|
/// expend selection left
|
||||||
|
SelectLeft,
|
||||||
/// move selection right
|
/// move selection right
|
||||||
Right,
|
Right,
|
||||||
|
/// expend selection right
|
||||||
|
SelectRight,
|
||||||
|
|
||||||
/// scroll up, w/o changing selection
|
/// scroll up, w/o changing selection
|
||||||
ScrollUp,
|
ScrollUp,
|
||||||
|
@ -208,6 +217,8 @@ enum GridActions : int {
|
||||||
DocumentEnd,
|
DocumentEnd,
|
||||||
/// move cursor to the end of document with selection
|
/// move cursor to the end of document with selection
|
||||||
SelectDocumentEnd,
|
SelectDocumentEnd,
|
||||||
|
/// select all entries without moving the cursor
|
||||||
|
SelectAll,
|
||||||
/// Enter key pressed on cell
|
/// Enter key pressed on cell
|
||||||
ActivateCell,
|
ActivateCell,
|
||||||
}
|
}
|
||||||
|
@ -324,10 +335,15 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
||||||
/// scroll Y offset in pixels
|
/// scroll Y offset in pixels
|
||||||
protected int _scrollY;
|
protected int _scrollY;
|
||||||
|
|
||||||
|
/// selected cells when multiselect is enabled
|
||||||
|
protected RedBlackTree!Point _selection;
|
||||||
/// selected cell column
|
/// selected cell column
|
||||||
protected int _col;
|
protected int _col;
|
||||||
/// selected cell row
|
/// selected cell row
|
||||||
protected int _row;
|
protected int _row;
|
||||||
|
/// when true, allows multi cell selection
|
||||||
|
protected bool _multiSelect;
|
||||||
|
private Point _lastSelectedCell;
|
||||||
/// when true, allows to select only whole row
|
/// when true, allows to select only whole row
|
||||||
protected bool _rowSelect;
|
protected bool _rowSelect;
|
||||||
/// default column width - for newly added columns
|
/// default column width - for newly added columns
|
||||||
|
@ -337,6 +353,8 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
||||||
|
|
||||||
// properties
|
// properties
|
||||||
|
|
||||||
|
/// selected cells when multiselect is enabled
|
||||||
|
@property RedBlackTree!Point selection() { return _selection; }
|
||||||
/// selected column
|
/// selected column
|
||||||
@property int col() { return _col - _headerCols; }
|
@property int col() { return _col - _headerCols; }
|
||||||
/// selected row
|
/// selected row
|
||||||
|
@ -422,12 +440,29 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// when true, allows multi cell selection
|
||||||
|
@property bool multiSelect() {
|
||||||
|
return _multiSelect;
|
||||||
|
}
|
||||||
|
@property GridWidgetBase multiSelect(bool flg) {
|
||||||
|
_multiSelect = flg;
|
||||||
|
if (!_multiSelect) {
|
||||||
|
_selection.clear();
|
||||||
|
_selection.insert(Point(_col - _headerCols, _row - _headerRows));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/// when true, allows only select the whole row
|
/// when true, allows only select the whole row
|
||||||
@property bool rowSelect() {
|
@property bool rowSelect() {
|
||||||
return _rowSelect;
|
return _rowSelect;
|
||||||
}
|
}
|
||||||
@property GridWidgetBase rowSelect(bool flg) {
|
@property GridWidgetBase rowSelect(bool flg) {
|
||||||
_rowSelect = flg;
|
_rowSelect = flg;
|
||||||
|
if (_rowSelect) {
|
||||||
|
_selection.clear();
|
||||||
|
_selection.insert(Point(_col - _headerCols, _row - _headerRows));
|
||||||
|
}
|
||||||
invalidate();
|
invalidate();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -872,10 +907,51 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool multiSelectCell(int col, int row, bool expandExisting = false) {
|
||||||
|
if (_col == col && _row == row && !expandExisting)
|
||||||
|
return false; // same position
|
||||||
|
if (col < _headerCols || row < _headerRows || col >= _cols || row >= _rows)
|
||||||
|
return false; // out of range
|
||||||
|
if (_changedSize) updateCumulativeSizes();
|
||||||
|
_lastSelectedCell.x = col;
|
||||||
|
_lastSelectedCell.y = row;
|
||||||
|
if (_rowSelect) col = _headerCols;
|
||||||
|
if (expandExisting) {
|
||||||
|
_selection.clear();
|
||||||
|
int startX = _col - _headerCols;
|
||||||
|
int startY = _row - headerRows;
|
||||||
|
int endX = col - _headerCols;
|
||||||
|
int endY = row - headerRows;
|
||||||
|
if (_rowSelect) startX = 0;
|
||||||
|
if (startX > endX) {
|
||||||
|
startX = endX;
|
||||||
|
endX = _col - _headerCols;
|
||||||
|
}
|
||||||
|
if (startY > endY) {
|
||||||
|
startY = endY;
|
||||||
|
endY = _row - _headerRows;
|
||||||
|
}
|
||||||
|
for (int x = startX; x <= endX; ++x) {
|
||||||
|
for (int y = startY; y <= endY; ++y) {
|
||||||
|
_selection.insert(Point(x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_selection.insert(Point(col - _headerCols, row - _headerRows));
|
||||||
|
_col = col;
|
||||||
|
_row = row;
|
||||||
|
}
|
||||||
|
invalidate();
|
||||||
|
calcScrollableAreaPos();
|
||||||
|
makeCellVisible(_lastSelectedCell.x, _lastSelectedCell.y);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// move selection to specified cell
|
/// move selection to specified cell
|
||||||
bool selectCell(int col, int row, bool makeVisible = true, GridWidgetBase source = null, bool needNotification = true) {
|
bool selectCell(int col, int row, bool makeVisible = true, GridWidgetBase source = null, bool needNotification = true) {
|
||||||
if (source is null)
|
if (source is null)
|
||||||
source = this;
|
source = this;
|
||||||
|
_selection.clear();
|
||||||
if (_col == col && _row == row)
|
if (_col == col && _row == row)
|
||||||
return false; // same position
|
return false; // same position
|
||||||
if (col < _headerCols || row < _headerRows || col >= _cols || row >= _rows)
|
if (col < _headerCols || row < _headerRows || col >= _cols || row >= _rows)
|
||||||
|
@ -883,6 +959,12 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
||||||
if (_changedSize) updateCumulativeSizes();
|
if (_changedSize) updateCumulativeSizes();
|
||||||
_col = col;
|
_col = col;
|
||||||
_row = row;
|
_row = row;
|
||||||
|
_lastSelectedCell = Point(col, row);
|
||||||
|
if (_rowSelect) {
|
||||||
|
_selection.insert(Point(0, row - _headerRows));
|
||||||
|
} else {
|
||||||
|
_selection.insert(Point(col - _headerCols, row - _headerRows));
|
||||||
|
}
|
||||||
invalidate();
|
invalidate();
|
||||||
calcScrollableAreaPos();
|
calcScrollableAreaPos();
|
||||||
if (makeVisible)
|
if (makeVisible)
|
||||||
|
@ -1063,6 +1145,8 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
||||||
if (cellFound && normalCell) {
|
if (cellFound && normalCell) {
|
||||||
if (c == _col && r == _row && event.doubleClick) {
|
if (c == _col && r == _row && event.doubleClick) {
|
||||||
activateCell(c, r);
|
activateCell(c, r);
|
||||||
|
} else if (_multiSelect && (event.flags & (MouseFlag.Shift | MouseFlag.Control)) != 0) {
|
||||||
|
multiSelectCell(c, r, (event.flags & MouseFlag.Shift) != 0);
|
||||||
} else {
|
} else {
|
||||||
selectCell(c, r);
|
selectCell(c, r);
|
||||||
}
|
}
|
||||||
|
@ -1072,8 +1156,12 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
||||||
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) {
|
||||||
|
if (_multiSelect) {
|
||||||
|
multiSelectCell(c, r, true);
|
||||||
|
} else {
|
||||||
selectCell(c, r);
|
selectCell(c, r);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (event.action == MouseAction.Wheel) {
|
if (event.action == MouseAction.Wheel) {
|
||||||
|
@ -1175,18 +1263,39 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
||||||
case Left:
|
case Left:
|
||||||
selectCell(_col - 1, _row);
|
selectCell(_col - 1, _row);
|
||||||
return true;
|
return true;
|
||||||
|
case SelectLeft:
|
||||||
|
if (_multiSelect) {
|
||||||
|
multiSelectCell(_lastSelectedCell.x - 1, _lastSelectedCell.y, true);
|
||||||
|
} else {
|
||||||
|
selectCell(_col - 1, _row);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
case ScrollRight:
|
case ScrollRight:
|
||||||
scrollBy(1, 0);
|
scrollBy(1, 0);
|
||||||
return true;
|
return true;
|
||||||
case Right:
|
case Right:
|
||||||
selectCell(_col + 1, _row);
|
selectCell(_col + 1, _row);
|
||||||
return true;
|
return true;
|
||||||
|
case SelectRight:
|
||||||
|
if (_multiSelect) {
|
||||||
|
multiSelectCell(_lastSelectedCell.x + 1, _lastSelectedCell.y, true);
|
||||||
|
} else {
|
||||||
|
selectCell(_col + 1, _row);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
case ScrollUp:
|
case ScrollUp:
|
||||||
scrollBy(0, -1);
|
scrollBy(0, -1);
|
||||||
return true;
|
return true;
|
||||||
case Up:
|
case Up:
|
||||||
selectCell(_col, _row - 1);
|
selectCell(_col, _row - 1);
|
||||||
return true;
|
return true;
|
||||||
|
case SelectUp:
|
||||||
|
if (_multiSelect) {
|
||||||
|
multiSelectCell(_lastSelectedCell.x, _lastSelectedCell.y - 1, true);
|
||||||
|
} else {
|
||||||
|
selectCell(_col, _row - 1);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
case ScrollDown:
|
case ScrollDown:
|
||||||
if (lastScrollRow < _rows - 1)
|
if (lastScrollRow < _rows - 1)
|
||||||
scrollBy(0, 1);
|
scrollBy(0, 1);
|
||||||
|
@ -1194,6 +1303,13 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
||||||
case Down:
|
case Down:
|
||||||
selectCell(_col, _row + 1);
|
selectCell(_col, _row + 1);
|
||||||
return true;
|
return true;
|
||||||
|
case SelectDown:
|
||||||
|
if (_multiSelect) {
|
||||||
|
multiSelectCell(_lastSelectedCell.x, _lastSelectedCell.y + 1, true);
|
||||||
|
} else {
|
||||||
|
selectCell(_col, _row + 1);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
case ScrollPageLeft:
|
case ScrollPageLeft:
|
||||||
// scroll left cell by cell
|
// scroll left cell by cell
|
||||||
while (scrollCol > nonScrollCols) {
|
while (scrollCol > nonScrollCols) {
|
||||||
|
@ -1224,8 +1340,23 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
case SelectLineBegin:
|
||||||
|
if (!_multiSelect) goto case LineBegin;
|
||||||
|
if (_rowSelect) goto case SelectDocumentBegin;
|
||||||
|
if (sc > nonScrollCols && _col > sc) {
|
||||||
|
multiSelectCell(sc, _lastSelectedCell.y, true);
|
||||||
|
} else {
|
||||||
|
if (sc > nonScrollCols) {
|
||||||
|
_scrollX = 0;
|
||||||
|
updateScrollBars();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
multiSelectCell(_headerCols, _lastSelectedCell.y, true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
case LineBegin:
|
case LineBegin:
|
||||||
if (sc > nonScrollCols && _col > sc && !_rowSelect) {
|
if (_rowSelect) goto case DocumentBegin;
|
||||||
|
if (sc > nonScrollCols && _col > sc) {
|
||||||
// move selection and don's scroll
|
// move selection and don's scroll
|
||||||
selectCell(sc, _row);
|
selectCell(sc, _row);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1238,14 +1369,34 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
||||||
selectCell(_headerCols, _row);
|
selectCell(_headerCols, _row);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
case SelectLineEnd:
|
||||||
|
if (!_multiSelect) goto case LineEnd;
|
||||||
|
if (_rowSelect) goto case SelectDocumentEnd;
|
||||||
|
if (_col < lastScrollCol) {
|
||||||
|
// move selection and don's scroll
|
||||||
|
multiSelectCell(lastScrollCol, _lastSelectedCell.y, true);
|
||||||
|
} else {
|
||||||
|
multiSelectCell(_cols - 1, _lastSelectedCell.y, true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
case LineEnd:
|
case LineEnd:
|
||||||
if (_col < lastScrollCol && !_rowSelect) {
|
if (_rowSelect) goto case DocumentEnd;
|
||||||
|
if (_col < lastScrollCol) {
|
||||||
// move selection and don's scroll
|
// move selection and don's scroll
|
||||||
selectCell(lastScrollCol, _row);
|
selectCell(lastScrollCol, _row);
|
||||||
} else {
|
} else {
|
||||||
selectCell(_cols - 1, _row);
|
selectCell(_cols - 1, _row);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
case SelectDocumentBegin:
|
||||||
|
if (!_multiSelect) goto case DocumentBegin;
|
||||||
|
if (_scrollY > 0) {
|
||||||
|
_scrollY = 0;
|
||||||
|
updateScrollBars();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
multiSelectCell(_lastSelectedCell.x, _headerRows, true);
|
||||||
|
return true;
|
||||||
case DocumentBegin:
|
case DocumentBegin:
|
||||||
if (_scrollY > 0) {
|
if (_scrollY > 0) {
|
||||||
_scrollY = 0;
|
_scrollY = 0;
|
||||||
|
@ -1254,18 +1405,64 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
||||||
}
|
}
|
||||||
selectCell(_col, _headerRows);
|
selectCell(_col, _headerRows);
|
||||||
return true;
|
return true;
|
||||||
|
case SelectDocumentEnd:
|
||||||
|
if (!_multiSelect) goto case DocumentEnd;
|
||||||
|
multiSelectCell(_lastSelectedCell.x, _rows - 1, true);
|
||||||
|
return true;
|
||||||
case DocumentEnd:
|
case DocumentEnd:
|
||||||
selectCell(_col, _rows - 1);
|
selectCell(_col, _rows - 1);
|
||||||
return true;
|
return true;
|
||||||
|
case SelectAll:
|
||||||
|
if (!_multiSelect) return true;
|
||||||
|
int endX = row;
|
||||||
|
if (_rowSelect) endX = 0;
|
||||||
|
for (int x = 0; x <= endX; ++x) {
|
||||||
|
for (int y = 0; y < rows; ++y) {
|
||||||
|
_selection.insert(Point(x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
invalidate();
|
||||||
|
return true;
|
||||||
|
case SelectPageBegin:
|
||||||
|
if (!_multiSelect) goto case PageBegin;
|
||||||
|
if (scrollRow > nonScrollRows)
|
||||||
|
multiSelectCell(_lastSelectedCell.x, scrollRow, true);
|
||||||
|
else
|
||||||
|
multiSelectCell(_lastSelectedCell.x, _headerRows, true);
|
||||||
|
return true;
|
||||||
case PageBegin:
|
case PageBegin:
|
||||||
if (scrollRow > nonScrollRows)
|
if (scrollRow > nonScrollRows)
|
||||||
selectCell(_col, scrollRow);
|
selectCell(_col, scrollRow);
|
||||||
else
|
else
|
||||||
selectCell(_col, _headerRows);
|
selectCell(_col, _headerRows);
|
||||||
return true;
|
return true;
|
||||||
|
case SelectPageEnd:
|
||||||
|
if (!_multiSelect) goto case PageEnd;
|
||||||
|
multiSelectCell(_lastSelectedCell.x, lastScrollRow, true);
|
||||||
|
return true;
|
||||||
case PageEnd:
|
case PageEnd:
|
||||||
selectCell(_col, lastScrollRow);
|
selectCell(_col, lastScrollRow);
|
||||||
return true;
|
return true;
|
||||||
|
case SelectPageUp:
|
||||||
|
if (_row > sr) {
|
||||||
|
// not at top scrollable cell
|
||||||
|
multiSelectCell(_lastSelectedCell.x, sr, true);
|
||||||
|
} else {
|
||||||
|
// at top of scrollable area
|
||||||
|
if (scrollRow > nonScrollRows) {
|
||||||
|
// scroll up line by line
|
||||||
|
int prevRow = _row;
|
||||||
|
for (int i = prevRow - 1; i >= _headerRows; i--) {
|
||||||
|
multiSelectCell(_lastSelectedCell.x, i, true);
|
||||||
|
if (lastScrollRow <= prevRow)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// scrolled to top - move upper cell
|
||||||
|
multiSelectCell(_lastSelectedCell.x, _headerRows, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
case PageUp:
|
case PageUp:
|
||||||
if (_row > sr) {
|
if (_row > sr) {
|
||||||
// not at top scrollable cell
|
// not at top scrollable cell
|
||||||
|
@ -1286,6 +1483,24 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
case SelectPageDown:
|
||||||
|
if (_row < _rows - 1) {
|
||||||
|
int lr = lastScrollRow;
|
||||||
|
if (_row < lr) {
|
||||||
|
// not at bottom scrollable cell
|
||||||
|
multiSelectCell(_lastSelectedCell.x, lr, true);
|
||||||
|
} else {
|
||||||
|
// scroll down
|
||||||
|
int prevRow = _row;
|
||||||
|
for (int i = prevRow + 1; i < _rows; i++) {
|
||||||
|
multiSelectCell(_lastSelectedCell.x, i, true);
|
||||||
|
calcScrollableAreaPos();
|
||||||
|
if (scrollRow >= prevRow)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
case PageDown:
|
case PageDown:
|
||||||
if (_row < _rows - 1) {
|
if (_row < _rows - 1) {
|
||||||
int lr = lastScrollRow;
|
int lr = lastScrollRow;
|
||||||
|
@ -1470,6 +1685,7 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
||||||
super(ID, hscrollbarMode, vscrollbarMode);
|
super(ID, hscrollbarMode, vscrollbarMode);
|
||||||
_headerCols = 1;
|
_headerCols = 1;
|
||||||
_headerRows = 1;
|
_headerRows = 1;
|
||||||
|
_selection = new RedBlackTree!Point();
|
||||||
_defRowHeight = BACKEND_CONSOLE ? 1 : pointsToPixels(16);
|
_defRowHeight = BACKEND_CONSOLE ? 1 : pointsToPixels(16);
|
||||||
_defColumnWidth = BACKEND_CONSOLE ? 7 : 100;
|
_defColumnWidth = BACKEND_CONSOLE ? 7 : 100;
|
||||||
|
|
||||||
|
@ -1488,6 +1704,19 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
||||||
new Action(GridActions.PageEnd, KeyCode.PAGEDOWN, KeyFlag.Control),
|
new Action(GridActions.PageEnd, KeyCode.PAGEDOWN, KeyFlag.Control),
|
||||||
new Action(GridActions.DocumentBegin, KeyCode.HOME, KeyFlag.Control),
|
new Action(GridActions.DocumentBegin, KeyCode.HOME, KeyFlag.Control),
|
||||||
new Action(GridActions.DocumentEnd, KeyCode.END, KeyFlag.Control),
|
new Action(GridActions.DocumentEnd, KeyCode.END, KeyFlag.Control),
|
||||||
|
new Action(GridActions.SelectUp, KeyCode.UP, KeyFlag.Shift),
|
||||||
|
new Action(GridActions.SelectDown, KeyCode.DOWN, KeyFlag.Shift),
|
||||||
|
new Action(GridActions.SelectLeft, KeyCode.LEFT, KeyFlag.Shift),
|
||||||
|
new Action(GridActions.SelectRight, KeyCode.RIGHT, KeyFlag.Shift),
|
||||||
|
new Action(GridActions.SelectLineBegin, KeyCode.HOME, KeyFlag.Shift),
|
||||||
|
new Action(GridActions.SelectLineEnd, KeyCode.END, KeyFlag.Shift),
|
||||||
|
new Action(GridActions.SelectPageUp, KeyCode.PAGEUP, KeyFlag.Shift),
|
||||||
|
new Action(GridActions.SelectPageDown, KeyCode.PAGEDOWN, KeyFlag.Shift),
|
||||||
|
new Action(GridActions.SelectPageBegin, KeyCode.PAGEUP, KeyFlag.Control | KeyFlag.Shift),
|
||||||
|
new Action(GridActions.SelectPageEnd, KeyCode.PAGEDOWN, KeyFlag.Control | KeyFlag.Shift),
|
||||||
|
new Action(GridActions.SelectDocumentBegin, KeyCode.HOME, KeyFlag.Control | KeyFlag.Shift),
|
||||||
|
new Action(GridActions.SelectDocumentEnd, KeyCode.END, KeyFlag.Control | KeyFlag.Shift),
|
||||||
|
new Action(GridActions.SelectAll, KeyCode.KEY_A, KeyFlag.Control),
|
||||||
new Action(GridActions.ActivateCell, KeyCode.RETURN, 0),
|
new Action(GridActions.ActivateCell, KeyCode.RETURN, 0),
|
||||||
]);
|
]);
|
||||||
focusable = true;
|
focusable = true;
|
||||||
|
@ -1673,6 +1902,9 @@ class StringGridWidget : StringGridWidgetBase {
|
||||||
bool selectedCell = selectedCol && selectedRow;
|
bool selectedCell = selectedCol && selectedRow;
|
||||||
if (_rowSelect && selectedRow)
|
if (_rowSelect && selectedRow)
|
||||||
selectedCell = true;
|
selectedCell = true;
|
||||||
|
if (!selectedCell && _multiSelect) {
|
||||||
|
selectedCell = Point(c, r) in _selection || (_rowSelect && Point(0, r) in _selection);
|
||||||
|
}
|
||||||
// draw header cell background
|
// draw header cell background
|
||||||
DrawableRef dw = c < 0 ? _cellRowHeaderBackgroundDrawable : _cellHeaderBackgroundDrawable;
|
DrawableRef dw = c < 0 ? _cellRowHeaderBackgroundDrawable : _cellHeaderBackgroundDrawable;
|
||||||
uint cl = _cellHeaderBackgroundColor;
|
uint cl = _cellHeaderBackgroundColor;
|
||||||
|
@ -1703,6 +1935,9 @@ class StringGridWidget : StringGridWidgetBase {
|
||||||
bool selectedCell = selectedCol && selectedRow;
|
bool selectedCell = selectedCol && selectedRow;
|
||||||
if (_rowSelect && selectedRow)
|
if (_rowSelect && selectedRow)
|
||||||
selectedCell = true;
|
selectedCell = true;
|
||||||
|
if (!selectedCell && _multiSelect) {
|
||||||
|
selectedCell = Point(c, r) in _selection || (_rowSelect && Point(0, r) in _selection);
|
||||||
|
}
|
||||||
uint borderColor = _cellBorderColor;
|
uint borderColor = _cellBorderColor;
|
||||||
if (c < fixedCols || r < fixedRows) {
|
if (c < fixedCols || r < fixedRows) {
|
||||||
// fixed cell background
|
// fixed cell background
|
||||||
|
|
Loading…
Reference in New Issue