feat(qt): Library Explorer columns select a run with Shift
A facet column already took Ctrl as "add or remove one" and a plain click as "only this". Shift now picks the run from the last clicked value and Ctrl+Shift adds that run, the file-list rule (SelectionModel.nextExclusive), each column over its values as listed. A column whose values are rebuilt by a change upstream starts without an anchor. cc
This commit is contained in:
3 files changed
+84
-14
No files matched your search
@@ -118,4 +118,39 @@ QtObject {
|
|||||||
root.anchorId = key
|
root.anchorId = key
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The spreadsheet / file-manager rule, for lists where a plain click
|
||||||
|
/// REPLACES the selection (the Library Explorer facets):
|
||||||
|
///
|
||||||
|
/// plain click only this row; it becomes the anchor
|
||||||
|
/// Ctrl / Cmd toggle this row, keep the rest; it becomes the anchor
|
||||||
|
/// Shift only the range anchor..row; the anchor stays
|
||||||
|
/// Ctrl+Shift add the range anchor..row to the selection
|
||||||
|
///
|
||||||
|
/// Without a visible anchor Shift behaves like the same click without it.
|
||||||
|
function nextExclusive(current, id, rows, modifiers) {
|
||||||
|
var mods = modifiers || 0
|
||||||
|
var shift = (mods & Qt.ShiftModifier) !== 0
|
||||||
|
var additive = (mods & (Qt.ControlModifier | Qt.MetaModifier)) !== 0
|
||||||
|
var key = String(id)
|
||||||
|
var anchorAt = root.anchorId !== "" ? root._indexOf(rows, root.anchorId) : -1
|
||||||
|
|
||||||
|
if (shift && anchorAt >= 0) {
|
||||||
|
var here = root._indexOf(rows, id)
|
||||||
|
if (here >= 0)
|
||||||
|
return root._fillRange(additive ? Object.assign({}, current) : {},
|
||||||
|
rows, anchorAt, here)
|
||||||
|
}
|
||||||
|
|
||||||
|
root.anchorId = key
|
||||||
|
if (!additive) {
|
||||||
|
var only = {}
|
||||||
|
only[key] = true
|
||||||
|
return only
|
||||||
|
}
|
||||||
|
var out = Object.assign({}, current)
|
||||||
|
if (out[key] === true) delete out[key]
|
||||||
|
else out[key] = true
|
||||||
|
return out
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1187,23 +1187,42 @@ Rectangle {
|
|||||||
return sortRows(rows, genresSort)
|
return sortRows(rows, genresSort)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The Explorer facets follow the spreadsheet rule — a plain click picks
|
||||||
|
// one value, Ctrl adds or removes one, Shift picks the run from the last
|
||||||
|
// click, Ctrl+Shift adds that run (SelectionModel.nextExclusive) — each
|
||||||
|
// column over its values AS LISTED (sorted, and filtered by its own
|
||||||
|
// search box). One anchor per column; a column whose values are rebuilt
|
||||||
|
// by a change upstream starts without one.
|
||||||
|
SelectionModel { id: genreFacetSel; idKey: "key" }
|
||||||
|
SelectionModel { id: yearFacetSel; idKey: "key" }
|
||||||
|
SelectionModel { id: artistFacetSel; idKey: "key" }
|
||||||
|
SelectionModel { id: albumFacetSel; idKey: "key" }
|
||||||
function toggleGenre(key, modifiers) {
|
function toggleGenre(key, modifiers) {
|
||||||
selectedGenres = nextFacetSelection(selectedGenres, key, modifiers)
|
selectedGenres = nextFacetSelection(genreFacetSel, selectedGenres, key, modifiers, genreNames)
|
||||||
selectedGenreYears = ({})
|
selectedGenreYears = ({})
|
||||||
selectedGenreArtists = ({})
|
selectedGenreArtists = ({})
|
||||||
selectedGenreAlbums = ({})
|
selectedGenreAlbums = ({})
|
||||||
|
yearFacetSel.anchorId = ""
|
||||||
|
artistFacetSel.anchorId = ""
|
||||||
|
albumFacetSel.anchorId = ""
|
||||||
}
|
}
|
||||||
function toggleGenreYear(key, modifiers) {
|
function toggleGenreYear(key, modifiers) {
|
||||||
selectedGenreYears = nextFacetSelection(selectedGenreYears, key, modifiers)
|
selectedGenreYears = nextFacetSelection(yearFacetSel, selectedGenreYears, key, modifiers,
|
||||||
|
genreYearOptions)
|
||||||
selectedGenreArtists = ({})
|
selectedGenreArtists = ({})
|
||||||
selectedGenreAlbums = ({})
|
selectedGenreAlbums = ({})
|
||||||
|
artistFacetSel.anchorId = ""
|
||||||
|
albumFacetSel.anchorId = ""
|
||||||
}
|
}
|
||||||
function toggleGenreArtist(key, modifiers) {
|
function toggleGenreArtist(key, modifiers) {
|
||||||
selectedGenreArtists = nextFacetSelection(selectedGenreArtists, key, modifiers)
|
selectedGenreArtists = nextFacetSelection(artistFacetSel, selectedGenreArtists, key,
|
||||||
|
modifiers, genreArtistOptions)
|
||||||
selectedGenreAlbums = ({})
|
selectedGenreAlbums = ({})
|
||||||
|
albumFacetSel.anchorId = ""
|
||||||
}
|
}
|
||||||
function toggleGenreAlbum(key, modifiers) {
|
function toggleGenreAlbum(key, modifiers) {
|
||||||
selectedGenreAlbums = nextFacetSelection(selectedGenreAlbums, key, modifiers)
|
selectedGenreAlbums = nextFacetSelection(albumFacetSel, selectedGenreAlbums, key, modifiers,
|
||||||
|
genreAlbumOptions)
|
||||||
}
|
}
|
||||||
function setExplorerColumns(mode) {
|
function setExplorerColumns(mode) {
|
||||||
if (["genre", "year", "both"].indexOf(mode) < 0 || mode === explorerColumns)
|
if (["genre", "year", "both"].indexOf(mode) < 0 || mode === explorerColumns)
|
||||||
@@ -1219,17 +1238,14 @@ Rectangle {
|
|||||||
readonly property int explorerFacetCount: explorerColumns === "both" ? 4 : 3
|
readonly property int explorerFacetCount: explorerColumns === "both" ? 4 : 3
|
||||||
readonly property int explorerLeadingCount: explorerColumns === "year"
|
readonly property int explorerLeadingCount: explorerColumns === "year"
|
||||||
? genreYearOptions.length : genreNames.length
|
? genreYearOptions.length : genreNames.length
|
||||||
function nextFacetSelection(current, key, modifiers) {
|
/// `key` "" is the column's "All" row: it clears the column.
|
||||||
if (key === "") return ({})
|
function nextFacetSelection(rule, current, key, modifiers, options) {
|
||||||
var additive = (modifiers & Qt.ControlModifier) !== 0
|
if (key === "") {
|
||||||
|| (modifiers & Qt.MetaModifier) !== 0
|
rule.anchorId = ""
|
||||||
if (!additive) {
|
return ({})
|
||||||
var only = {}; only[key] = true; return only
|
|
||||||
}
|
}
|
||||||
var out = Object.assign({}, current)
|
return rule.nextExclusive(current, key, options || [],
|
||||||
if (out[key]) delete out[key]
|
modifiers === undefined ? Qt.NoModifier : modifiers)
|
||||||
else out[key] = true
|
|
||||||
return out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The selected artist's albums.
|
// The selected artist's albums.
|
||||||
|
|||||||
@@ -432,5 +432,24 @@ Item {
|
|||||||
m = keyedRule.next(m, 7, rows, Qt.ShiftModifier)
|
m = keyedRule.next(m, 7, rows, Qt.ShiftModifier)
|
||||||
compare(Object.keys(m).sort().join(","), "7,8,9")
|
compare(Object.keys(m).sort().join(","), "7,8,9")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function test_exclusive_rule() {
|
||||||
|
var rows = [{ "id": "g1" }, { "id": "g2" }, { "id": "g3" }, { "id": "g4" }, { "id": "g5" }]
|
||||||
|
var m = rule.nextExclusive({}, "g2", rows, Qt.NoModifier)
|
||||||
|
compare(Object.keys(m).sort().join(","), "g2", "a plain click selects only that row")
|
||||||
|
m = rule.nextExclusive(m, "g4", rows, Qt.ShiftModifier)
|
||||||
|
compare(Object.keys(m).sort().join(","), "g2,g3,g4", "Shift selects the range")
|
||||||
|
m = rule.nextExclusive(m, "g1", rows, Qt.ShiftModifier)
|
||||||
|
compare(Object.keys(m).sort().join(","), "g1,g2", "the anchor stays, Shift replaces the range")
|
||||||
|
m = rule.nextExclusive(m, "g5", rows, Qt.ControlModifier)
|
||||||
|
compare(Object.keys(m).sort().join(","), "g1,g2,g5", "Ctrl adds one")
|
||||||
|
m = rule.nextExclusive(m, "g5", rows, Qt.ControlModifier)
|
||||||
|
compare(Object.keys(m).sort().join(","), "g1,g2", "Ctrl on a selected row removes it")
|
||||||
|
m = rule.nextExclusive(m, "g3", rows, Qt.ControlModifier)
|
||||||
|
m = rule.nextExclusive(m, "g5", rows, Qt.ControlModifier | Qt.ShiftModifier)
|
||||||
|
compare(Object.keys(m).sort().join(","), "g1,g2,g3,g4,g5", "Ctrl+Shift adds a range")
|
||||||
|
m = rule.nextExclusive(m, "g4", rows, Qt.NoModifier)
|
||||||
|
compare(Object.keys(m).sort().join(","), "g4", "a plain click starts over")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user