From 59fb302e1879b51a4320a8ce45cd29ff47b3c2d3 Mon Sep 17 00:00:00 2001 From: DanyLE Date: Sun, 28 Jul 2024 19:05:34 +0200 Subject: [PATCH] feat(GridView): allows navigation by arrow keys --- Makefile | 2 +- d.ts/antos.d.ts | 53 ++++++++++- src/core/BaseDialog.ts | 2 +- src/core/tags/GridViewTag.ts | 137 +++++++++++++++++++++++++++ src/core/tags/ListViewTag.ts | 8 +- src/core/tags/SystemPanelTag.ts | 4 +- src/packages/Setting/package.json | 2 +- src/packages/Setting/scheme.html | 2 +- src/themes/default/afx-grid-view.css | 4 + 9 files changed, 202 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 2c3a90f..eb54e23 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ TSC=./node_modules/typescript/bin/tsc UGLIFYJS=./node_modules/terser/bin/terser UGLIFYCSS=./node_modules/uglifycss/uglifycss -VERSION?=2.0.2-b +VERSION?=2.0.3-b BUILDID?=master GSED=sed diff --git a/d.ts/antos.d.ts b/d.ts/antos.d.ts index d76c293..5648473 100644 --- a/d.ts/antos.d.ts +++ b/d.ts/antos.d.ts @@ -4780,14 +4780,14 @@ declare namespace OS { * @returns {void} * @memberof ListViewTag */ - nav_next(): void; + nav_prev(): void; /** * Navigate the list down * * @returns {void} * @memberof ListViewTag */ - nav_prev(): void; + nav_next(): void; /** * Commit the navigated item * @@ -6300,6 +6300,13 @@ declare namespace OS { * @memberof GridViewTag */ private _dnd; + /** + * Grid navigation index + * + * @private + * @type {number} + */ + private _nav_index; /** * placeholder of list drag and drop event handle * @@ -6480,6 +6487,12 @@ declare namespace OS { * @memberof GridViewTag */ delete(row: GridRowTag): void; + /** + * Scroll the grid view to item + * + * @memberof GridViewTag + */ + scroll_to_item(item: GridRowTag): void; /** * Scroll the grid view to bottom * @@ -6559,6 +6572,42 @@ declare namespace OS { * @memberof GridViewTag */ private calibrate_header; + /** + * Reset the navigation indicator + * + * @private + */ + private nav_reset; + /** + * Navigate the list up + * + * @public + * @returns {void} + * @memberof ListViewTag + */ + nav_prev(): void; + /** + * Navigate the list down + * + * @returns {void} + * @memberof ListViewTag + */ + nav_next(): void; + /** + * Commit the navigated item + * + * @returns {void} + * @memberof ListViewTag + */ + nav_commit(): void; + /** + * Handle special key event such as key up and down + * + * @private + * @param {JQuery.KeyboardEventBase} event + * @returns {void} + */ + private handle_special_key; /** * Mount the grid view tag * diff --git a/src/core/BaseDialog.ts b/src/core/BaseDialog.ts index dc7f4ae..514967b 100644 --- a/src/core/BaseDialog.ts +++ b/src/core/BaseDialog.ts @@ -685,7 +685,7 @@ namespace OS { InfoDialog.scheme = `\ - +
diff --git a/src/core/tags/GridViewTag.ts b/src/core/tags/GridViewTag.ts index 8379265..7c01133 100644 --- a/src/core/tags/GridViewTag.ts +++ b/src/core/tags/GridViewTag.ts @@ -497,6 +497,14 @@ namespace OS { */ private _dnd: { from: GridRowTag[]; to: GridRowTag }; + /** + * Grid navigation index + * + * @private + * @type {number} + */ + private _nav_index: number; + /** * placeholder of list drag and drop event handle * @@ -514,6 +522,7 @@ namespace OS { */ constructor() { super(); + this._nav_index = -1; } /** @@ -883,6 +892,35 @@ namespace OS { } $(row).remove(); } + + /** + * Scroll the grid view to item + * + * @memberof GridViewTag + */ + scroll_to_item(item: GridRowTag) + { + const cell = $(item).children()[0]; + const offset = $(this.refs.container).offset(); + const cell_offset = $(cell).offset(); + + const top = $(this.refs.container).scrollTop(); + const cell_height = $(cell).outerHeight(); + const container_height = $(this.refs.container).outerHeight(); + if (cell_offset.top + cell_height > container_height + offset.top) + { + $(this.refs.container).scrollTop( + top + + (cell_offset.top + cell_height - offset.top - container_height) + ); + } else if (cell_offset.top < offset.top) { + $(this.refs.container).scrollTop( + top - + (offset.top - cell_offset.top) + ); + } + } + /** * Scroll the grid view to bottom * @@ -1042,6 +1080,7 @@ namespace OS { } evt.data.item = row; this._selectedRow = row; + this._nav_index = $(row).index(); this._onrowselect(evt); return this.observable.trigger("rowselect", evt); } @@ -1152,6 +1191,101 @@ namespace OS { } } + /** + * Reset the navigation indicator + * + * @private + */ + private nav_reset() { + const el = $(this.refs.grid).children().eq(this._nav_index); + if(el) + { + $(el).removeClass("gridview-nav-focus"); + } + } + + /** + * Navigate the list up + * + * @public + * @returns {void} + * @memberof ListViewTag + */ + public nav_prev() { + console.log("nav_prev"); + if(this._nav_index <= 0) { + return; + } + this.nav_reset(); + this._nav_index--; + const el = $(this.refs.grid).children().eq(this._nav_index); + if(el) { + $(el).addClass("gridview-nav-focus"); + this.scroll_to_item(el[0] as GridRowTag); + } + } + + /** + * Navigate the list down + * + * @returns {void} + * @memberof ListViewTag + */ + public nav_next() { + console.log("nav_next"); + if(this._nav_index >= this.rows.length - 1) { + return; + } + this.nav_reset(); + this._nav_index++; + const el = $(this.refs.grid).children().eq(this._nav_index); + if(el) { + $(el).addClass("gridview-nav-focus"); + this.scroll_to_item(el[0] as GridRowTag); + } + } + + /** + * Commit the navigated item + * + * @returns {void} + * @memberof ListViewTag + */ + public nav_commit() { + if(this._nav_index > this.rows.length - 1 || this._nav_index < 0) { + return; + } + const el = $(this.refs.grid).children().eq(this._nav_index); + if(el) { + (el[0] as GridRowTag).selected = true; + } + } + + /** + * Handle special key event such as key up and down + * + * @private + * @param {JQuery.KeyboardEventBase} event + * @returns {void} + */ + private handle_special_key(event: JQuery.KeyboardEventBase) { + switch (event.which) { + case 37: + case 38: + this.nav_prev(); + return event.preventDefault(); + case 39: + case 40: + this.nav_next(); + return event.preventDefault(); + case 13: + event.preventDefault(); + return this.nav_commit(); + default: + break; + } + } + /** * Mount the grid view tag * @@ -1160,6 +1294,9 @@ namespace OS { * @memberof GridViewTag */ protected mount(): void { + $(this).on("keyup", (e) => { + this.handle_special_key(e); + }); $(this).css("overflow", "hidden"); $(this.refs.grid).css("display", "grid"); $(this.refs.header).css("display", "grid"); diff --git a/src/core/tags/ListViewTag.ts b/src/core/tags/ListViewTag.ts index 23ec541..0a0f8a0 100644 --- a/src/core/tags/ListViewTag.ts +++ b/src/core/tags/ListViewTag.ts @@ -1122,7 +1122,7 @@ namespace OS { * @returns {void} * @memberof ListViewTag */ - public nav_next() { + public nav_prev() { if(this._nav_index <= 0) { return; } @@ -1141,7 +1141,7 @@ namespace OS { * @returns {void} * @memberof ListViewTag */ - public nav_prev() { + public nav_next() { if(this._nav_index >= this.data.length - 1) { return; } @@ -1179,11 +1179,11 @@ namespace OS { switch (event.which) { case 37: case 38: - this.nav_next(); + this.nav_prev(); return event.preventDefault(); case 39: case 40: - this.nav_prev(); + this.nav_next(); return event.preventDefault(); case 13: event.preventDefault(); diff --git a/src/core/tags/SystemPanelTag.ts b/src/core/tags/SystemPanelTag.ts index c3721a4..a6394ed 100644 --- a/src/core/tags/SystemPanelTag.ts +++ b/src/core/tags/SystemPanelTag.ts @@ -156,12 +156,12 @@ namespace OS { return this.toggle(false); case 37: - applist.nav_next(); + applist.nav_prev(); return e.preventDefault(); case 38: return e.preventDefault(); case 39: - applist.nav_prev(); + applist.nav_next(); return e.preventDefault(); case 40: return e.preventDefault(); diff --git a/src/packages/Setting/package.json b/src/packages/Setting/package.json index 28f9bd8..8e7c446 100644 --- a/src/packages/Setting/package.json +++ b/src/packages/Setting/package.json @@ -6,7 +6,7 @@ "author": "Xuan Sang LE", "email": "xsang.le@gmail.com" }, - "version":"0.2.1-b", + "version":"0.2.2-b", "category":"System", "iconclass":"fa fa-wrench", "mimes":["none"] diff --git a/src/packages/Setting/scheme.html b/src/packages/Setting/scheme.html index a77292c..37e3c8c 100644 --- a/src/packages/Setting/scheme.html +++ b/src/packages/Setting/scheme.html @@ -75,7 +75,7 @@ - + diff --git a/src/themes/default/afx-grid-view.css b/src/themes/default/afx-grid-view.css index afbda1f..48bb9e3 100644 --- a/src/themes/default/afx-grid-view.css +++ b/src/themes/default/afx-grid-view.css @@ -17,6 +17,10 @@ afx-grid-view afx-grid-row.afx-grid-row-selected afx-grid-cell background-color: var(--item-bg-active); color:var(--text-tertiary); } +afx-grid-view afx-grid-row.gridview-nav-focus afx-grid-cell +{ + background-color: var(--item-bg-hover); +} afx-grid-view afx-grid-row.afx-grid-row-selected afx-grid-cell.afx-grid-cell-selected { font-weight: normal;