diff --git a/src/EasyApp/Gui/Components/NewTableView.qml b/src/EasyApp/Gui/Components/NewTableView.qml new file mode 100644 index 00000000..86dd0cb7 --- /dev/null +++ b/src/EasyApp/Gui/Components/NewTableView.qml @@ -0,0 +1,159 @@ +import QtQuick +import QtQuick.Controls + +import EasyApp.Gui.Globals as EaGlobals +import EasyApp.Gui.Style as EaStyle +import EasyApp.Gui.Animations as EaAnimations +import EasyApp.Gui.Elements as EaElements +import EasyApp.Gui.Components as EaComponents + +Item { + id: newTableView + height: count === 0 ? + 2 * EaStyle.Sizes.tableRowHeight : + showHeader ? + nestedTableView.tableRowHeight * (Math.min(count, maxRowCountShow) + 1 ) : + nestedTableView.tableRowHeight * (Math.min(count, maxRowCountShow)) + width: EaStyle.Sizes.sideBarContentWidth + + // exposing underlying tableview API + property alias count: nestedTableView.count + property alias showHeader: nestedTableView.showHeader + property alias tallRows: nestedTableView.tallRows + property alias maxRowCountShow: nestedTableView.maxRowCountShow + property alias defaultInfoText: nestedTableView.defaultInfoText + property alias header: nestedTableView.header + property alias model: nestedTableView.model + property alias delegate: nestedTableView.delegate + + // trigger for bindings + property int selectionRevision: 0 + // idx for shift-selection + property int anchorRow: -1 + + ItemSelectionModel { + id: selectionModel + model: nestedTableView.model + } + + Connections { + target: selectionModel + + function onSelectionChanged() { + newTableView.selectionRevision++ + } + } + + // --- helper: convert row -> QModelIndex --- + function _index(row) { + if (!selectionModel.model) + return null + return selectionModel.model.index(row, 0) + } + + // --- public API --- + function isSelected(row) { + let idx = _index(row) + return idx ? selectionModel.isSelected(idx) : false + } + + function selectWithModifiers(row, modifiers) { + let idx = _index(row) + if (!idx) return + + // --- SHIFT: range selection --- + if (modifiers & Qt.ShiftModifier) { + if (anchorRow < 0) { + anchorRow = row + } + + let from = Math.min(anchorRow, row) + let to = Math.max(anchorRow, row) + + // If Ctrl is NOT pressed → replace selection + if (!(modifiers & Qt.ControlModifier)) { + selectionModel.clearSelection() + } + + for (let i = from; i <= to; i++) { + let rIdx = _index(i) + if (rIdx) { + selectionModel.select( + rIdx, + ItemSelectionModel.Select | ItemSelectionModel.Rows + ) + } + } + + return + } + + // --- CTRL: toggle --- + if (modifiers & Qt.ControlModifier) { + selectionModel.select( + idx, + ItemSelectionModel.Toggle | ItemSelectionModel.Rows + ) + anchorRow = row + return + } + + // --- DEFAULT: single selection --- + selectionModel.select( + idx, + ItemSelectionModel.ClearAndSelect | ItemSelectionModel.Rows + ) + anchorRow = row + } + + function clearSelection() { + selectionModel.clearSelection() + } + + // ScrollView{ + // width: nestedTableView.width + // height: nestedTableView.height + + // ScrollBar.vertical: EaElements.ScrollBar { + // id: scrollBar + // anchors.right: parent.right + // // anchors.top: parent.header.bottom + // topPadding: parent.showHeader ? parent.tableRowHeight : 0 + // background.anchors.top: parent.parent.header.bottom + // //anchors.bottom: parent.bottom + // policy: ScrollBar.AlwaysOn // ScrollBar.AsNeeded + // width: 6 + // } + + EaComponents.TableView { + id: nestedTableView + clip: true + antialiasing: true + anchors { + fill: parent + // margins: 1 + // rightMargin: 1 // scrollBar.width + } + + ScrollBar.vertical: EaElements.ScrollBar { + id: scrollBar + // anchors.right: parent.right + // anchors.top: parent.header.bottom + anchors.topMargin: 1 + topInset: parent.showHeader ? parent.tableRowHeight : 0 + topPadding: parent.showHeader ? parent.tableRowHeight + 1 : 0 + //background.anchors.top: parent.parent.header.bottom + anchors.bottom: parent.bottom + policy: ScrollBar.AlwaysOn // ScrollBar.AsNeeded // AlwaysOn + width: 6 + } + + // fixes an issue of clicks not registering right after scroll + // does not give too much delay due to selection animation playing anyway + // somehow value doesn't affect anything, just fixes the missing clicks issue + // even 10000 delay doesn't create a long delay, just fixes the issue + pressDelay: 10 + + } + +} diff --git a/src/EasyApp/Gui/Components/NewTableViewDelegate.qml b/src/EasyApp/Gui/Components/NewTableViewDelegate.qml new file mode 100644 index 00000000..97acc8be --- /dev/null +++ b/src/EasyApp/Gui/Components/NewTableViewDelegate.qml @@ -0,0 +1,67 @@ +import QtQuick + +import EasyApp.Gui.Style as EaStyle +import EasyApp.Gui.Animations as EaAnimations + +Rectangle { + id: control + + default property alias contentRowData: contentRow.data + //property alias mouseArea: mouseArea + property Item tableView: parent === null ? null : parent.parent + + implicitWidth: ListView.view.parent.width + implicitHeight: tableView === null ? EaStyle.Sizes.tableRowHeight : tableView.tableRowHeight + + color: { + ListView.view.parent.selectionRevision + + let selected = ListView.view.parent.isSelected(index) + let c1 = EaStyle.Colors.themeAccentMinor + let c2 = EaStyle.Colors.themeBackgroundHovered2 + let c3 = EaStyle.Colors.themeBackgroundHovered1 + + return selected ? c1 : (index % 2 ? c2 : c3) + } + Behavior on color { EaAnimations.ThemeChange {} } + + Row { + id: contentRow + + height: parent.height + spacing: EaStyle.Sizes.tableColumnSpacing + } + + //Mouse area to react on click events + MouseArea { + id: mouseArea + anchors.fill: parent + propagateComposedEvents: true + cursorShape: undefined //Qt.PointingHandCursor + hoverEnabled: false + onReleased: (mouse) => { + control.ListView.view.parent.selectWithModifiers(index, mouse.modifiers) + } + } + + // TapHandler { + // acceptedButtons: Qt.LeftButton // | Qt.RightButton // match whatever you need + // onTapped: (eventPoint, button) => { + // control.ListView.view.parent.selectWithModifiers(index, eventPoint.modifiers) + // } + // } + + // HoverHandler to react on hover events + HoverHandler { + id: mouseHoverHandler + acceptedDevices: PointerDevice.AllDevices + cursorShape: Qt.PointingHandCursor + blocking: false + onHoveredChanged: { + if (hovered) { + //console.error(`${control} [TableViewDelegate.qml] hovered`) + parent.ListView.view.currentIndex = index + } + } + } +} diff --git a/src/EasyApp/Gui/Components/qmldir b/src/EasyApp/Gui/Components/qmldir index 55a7dd24..7437af08 100644 --- a/src/EasyApp/Gui/Components/qmldir +++ b/src/EasyApp/Gui/Components/qmldir @@ -21,6 +21,8 @@ SideBarColumn 1.0 SideBarColumn.qml PreferencesDialog 1.0 PreferencesDialog.qml ProjectDescriptionDialog 1.0 ProjectDescriptionDialog.qml +NewTableView 1.0 NewTableView.qml +NewTableViewDelegate 1.0 NewTableViewDelegate.qml TableView 1.0 TableView.qml TableViewHeader 1.0 TableViewHeader.qml TableViewDelegate 1.0 TableViewDelegate.qml