grid - selecting, scrolling

This commit is contained in:
Jan Prochazka
2020-03-22 10:25:19 +01:00
parent 043d21c43a
commit 6a7b7abcb7
4 changed files with 71 additions and 18 deletions

View File

@@ -15,7 +15,7 @@ export default function ColumnLabel(column) {
if (column.foreignKey) Icon = ForeignKeyIcon; if (column.foreignKey) Icon = ForeignKeyIcon;
return ( return (
<Label {...column}> <Label {...column}>
{Icon ? <Icon /> : null} {column.headerText || column.columnName} {Icon ? <Icon size={12} /> : null} {column.headerText || column.columnName}
</Label> </Label>
); );
} }

View File

@@ -102,6 +102,8 @@ const NullSpan = styled.span`
font-style: italic; font-style: italic;
`; `;
const wheelRowCount = 5;
function CellFormattedValue({ value }) { function CellFormattedValue({ value }) {
if (value == null) return <NullSpan>(NULL)</NullSpan>; if (value == null) return <NullSpan>(NULL)</NullSpan>;
if (_.isDate(value)) return moment(value).format('YYYY-MM-DD HH:mm:ss'); if (_.isDate(value)) return moment(value).format('YYYY-MM-DD HH:mm:ss');
@@ -133,6 +135,7 @@ export default function DataGridCore(props) {
const [currentCell, setCurrentCell] = React.useState(topLeftCell); const [currentCell, setCurrentCell] = React.useState(topLeftCell);
const [selectedCells, setSelectedCells] = React.useState(emptyCellArray); const [selectedCells, setSelectedCells] = React.useState(emptyCellArray);
const [dragStartCell, setDragStartCell] = React.useState(nullCell); const [dragStartCell, setDragStartCell] = React.useState(nullCell);
const [shiftDragStartCell, setShiftDragStartCell] = React.useState(nullCell);
const loadNextData = async () => { const loadNextData = async () => {
if (isLoading) return; if (isLoading) return;
@@ -200,7 +203,7 @@ export default function DataGridCore(props) {
// console.log('containerWidth', containerWidth); // console.log('containerWidth', containerWidth);
const gridScrollAreaHeight = containerHeight - 2 * rowHeight; const gridScrollAreaHeight = containerHeight - 2 * rowHeight;
const gridScrollAreaWidth = containerWidth - columnSizes.frozenSize - headerColWidth; const gridScrollAreaWidth = containerWidth - columnSizes.frozenSize - headerColWidth - 32;
const visibleRowCountUpperBound = Math.ceil(gridScrollAreaHeight / Math.floor(rowHeight)); const visibleRowCountUpperBound = Math.ceil(gridScrollAreaHeight / Math.floor(rowHeight));
const visibleRowCountLowerBound = Math.floor(gridScrollAreaHeight / Math.ceil(rowHeight)); const visibleRowCountLowerBound = Math.floor(gridScrollAreaHeight / Math.ceil(rowHeight));
@@ -340,12 +343,50 @@ export default function DataGridCore(props) {
} }
} }
function handleGridWheel(event) {
console.log('WHEEL', event, event.deltaY);
// let delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
let newFirstVisibleRowScrollIndex = firstVisibleRowScrollIndex;
if (event.deltaY > 0) {
newFirstVisibleRowScrollIndex += wheelRowCount;
}
if (event.deltaY < 0) {
newFirstVisibleRowScrollIndex -= wheelRowCount;
}
let rowCount = rowCountNewIncluded;
if (newFirstVisibleRowScrollIndex + visibleRowCountLowerBound > rowCount) {
newFirstVisibleRowScrollIndex = rowCount - visibleRowCountLowerBound + 1;
}
if (newFirstVisibleRowScrollIndex < 0) {
newFirstVisibleRowScrollIndex = 0;
}
setFirstVisibleRowScrollIndex(newFirstVisibleRowScrollIndex);
// @ts-ignore
setvScrollValueToSet(newFirstVisibleRowScrollIndex);
setvScrollValueToSetDate(new Date());
}
function handleGridKeyDown(event) { function handleGridKeyDown(event) {
handleCursorMove(event); handleCursorMove(event);
if (event.shiftKey) {
if (!isRegularCell(shiftDragStartCell)) {
setShiftDragStartCell(currentCell);
}
} else {
setShiftDragStartCell(nullCell);
}
const newCell = handleCursorMove(event);
if (event.shiftKey && newCell) {
// @ts-ignore
setSelectedCells(getCellRange(shiftDragStartCell, newCell));
}
} }
function handleCursorMove(event) { function handleCursorMove(event) {
if (!isRegularCell(currentCell)) return false; if (!isRegularCell(currentCell)) return null;
let rowCount = rowCountNewIncluded; let rowCount = rowCountNewIncluded;
if (event.ctrlKey) { if (event.ctrlKey) {
switch (event.keyCode) { switch (event.keyCode) {
@@ -366,7 +407,7 @@ export default function DataGridCore(props) {
case keycodes.a: case keycodes.a:
setSelectedCells([['header', 'header']]); setSelectedCells([['header', 'header']]);
event.preventDefault(); event.preventDefault();
return true; return ['header', 'header'];
} }
} else { } else {
switch (event.keyCode) { switch (event.keyCode) {
@@ -390,30 +431,31 @@ export default function DataGridCore(props) {
return moveCurrentCell(currentCell[0] + visibleRowCountLowerBound, currentCell[1], event); return moveCurrentCell(currentCell[0] + visibleRowCountLowerBound, currentCell[1], event);
} }
} }
return false; return null;
} }
function focusFilterEditor(columnRealIndex) { function focusFilterEditor(columnRealIndex) {
// let modelIndex = this.columnSizes.realToModel(columnRealIndex); // let modelIndex = this.columnSizes.realToModel(columnRealIndex);
// this.headerFilters[this.columns[modelIndex].uniquePath].focus(); // this.headerFilters[this.columns[modelIndex].uniquePath].focus();
return true; return ['filter', columnRealIndex];
} }
function moveCurrentCell(row, col, event) { function moveCurrentCell(row, col, event) {
let rowCount = rowCountNewIncluded; const rowCount = rowCountNewIncluded;
if (row < 0) row = 0; if (row < 0) row = 0;
if (row >= rowCount) row = rowCount - 1; if (row >= rowCount) row = rowCount - 1;
if (col < 0) col = 0; if (col < 0) col = 0;
if (col >= columnSizes.realCount) col = columnSizes.realCount - 1; if (col >= columnSizes.realCount) col = columnSizes.realCount - 1;
setCurrentCell([row, col]); setCurrentCell([row, col]);
setSelectedCells([...(event.ctrlKey ? selectedCells : []), [row, col]]); // setSelectedCells([...(event.ctrlKey ? selectedCells : []), [row, col]]);
setSelectedCells([[row, col]]);
scrollIntoView([row, col]); scrollIntoView([row, col]);
// this.selectedCells.push(this.currentCell); // this.selectedCells.push(this.currentCell);
// this.scrollIntoView(this.currentCell); // this.scrollIntoView(this.currentCell);
if (event) event.preventDefault(); if (event) event.preventDefault();
return true; return [row, col];
} }
function scrollIntoView(cell) { function scrollIntoView(cell) {
@@ -534,6 +576,7 @@ export default function DataGridCore(props) {
onMouseMove={handleGridMouseMove} onMouseMove={handleGridMouseMove}
onMouseUp={handleGridMouseUp} onMouseUp={handleGridMouseUp}
onKeyDown={handleGridKeyDown} onKeyDown={handleGridKeyDown}
onWheel={handleGridWheel}
// table can be focused // table can be focused
tabIndex={-1} tabIndex={-1}
ref={tableRef} ref={tableRef}

View File

@@ -259,16 +259,25 @@ export class SeriesSizes {
if (scrollIndex < firstVisibleIndex) { if (scrollIndex < firstVisibleIndex) {
return scrollIndex; return scrollIndex;
} }
let res: number = 0; let testedIndex = firstVisibleIndex + 1;
let testedIndex: number = scrollIndex; while (testedIndex < this.scrollCount) {
while (res < viewportSize && testedIndex >= 0) { if (this.isWholeInView(testedIndex, scrollIndex, viewportSize)) {
let size: number = this.getSizeByScrollIndex(testedIndex); return testedIndex;
if (res + size > viewportSize) return testedIndex + 1; }
testedIndex--; testedIndex++;
res += size;
} }
if (res >= viewportSize && testedIndex < scrollIndex) return testedIndex + 1; return this.scrollCount - 1;
return firstVisibleIndex;
// let res: number = 0;
// let testedIndex: number = scrollIndex;
// while (res < viewportSize && testedIndex >= 0) {
// let size: number = this.getSizeByScrollIndex(testedIndex);
// if (res + size > viewportSize) return testedIndex + 1;
// testedIndex--;
// res += size;
// }
// if (res >= viewportSize && testedIndex < scrollIndex) return testedIndex + 1;
// return firstVisibleIndex;
} }
public resize(realIndex: number, newSize: number): void { public resize(realIndex: number, newSize: number): void {
if (realIndex < 0) return; if (realIndex < 0) return;

View File

@@ -8,6 +8,7 @@ export const nullCell: CellAddress = null;
export const emptyCellArray: CellAddress[] = []; export const emptyCellArray: CellAddress[] = [];
export function isRegularCell(cell: CellAddress): cell is RegularCellAddress { export function isRegularCell(cell: CellAddress): cell is RegularCellAddress {
if (!cell) return false;
const [row, col] = cell; const [row, col] = cell;
return _.isNumber(row) && _.isNumber(col); return _.isNumber(row) && _.isNumber(col);
} }