Initial implementation of message selection

This commit is contained in:
miruka
2019-08-30 11:17:13 -04:00
parent aaaff814a1
commit 016f76167f
7 changed files with 348 additions and 101 deletions

View File

@@ -3,6 +3,7 @@ import QtQuick.Controls 2.12
ListView {
id: listView
interactive: enableFlicking
currentIndex: -1
keyNavigationWraps: true
highlightMoveDuration: theme.animationDuration
@@ -13,6 +14,8 @@ ListView {
preferredHighlightEnd: height / 2 + currentItemHeight
property bool enableFlicking: true
readonly property int currentItemHeight:
currentItem ? currentItem.height : 0
@@ -21,7 +24,9 @@ ListView {
color: theme.controls.listView.highlight
}
ScrollBar.vertical: ScrollBar { visible: listView.interactive }
ScrollBar.vertical: ScrollBar {
visible: listView.interactive || ! listView.enableFlicking
}
add: Transition {
ParallelAnimation {
@@ -45,6 +50,5 @@ ListView {
}
}
populate: add
displaced: move
}

View File

@@ -0,0 +1,119 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
TextEdit {
id: label
font.family: theme.fontFamily.sans
font.pixelSize: theme.fontSize.normal
color: theme.colors.text
textFormat: Label.PlainText
tabStopDistance: 4 * 4 // 4 spaces
readOnly: true
persistentSelection: true
onLinkActivated: Qt.openUrlExternally(link)
property HSelectableLabelContainer container
property int index
function updateSelection() {
if (! container.reversed &&
container.selectionStart <= container.selectionEnd ||
container.reversed &&
container.selectionStart > container.selectionEnd)
{
var first = container.selectionStart
var firstPos = container.selectionStartPosition
var last = container.selectionEnd
var lastPos = container.selectionEndPosition
} else {
var first = container.selectionEnd
var firstPos = container.selectionEndPosition
var last = container.selectionStart
var lastPos = container.selectionStartPosition
}
if (first == index && last == index) {
select(
label.positionAt(firstPos.x, firstPos.y),
label.positionAt(lastPos.x, lastPos.y),
)
} else if ((! container.reversed && first < index && index < last) ||
(container.reversed && first > index && index > last))
{
label.selectAll()
} else if (first == index) {
label.select(positionAt(firstPos.x, firstPos.y), length)
} else if (last == index) {
label.select(0, positionAt(lastPos.x, lastPos.y))
} else {
label.deselect()
}
updateContainerSelectedTexts()
}
function updateContainerSelectedTexts() {
container.selectedTexts[index] = selectedText
container.selectedTextsChanged()
}
function selectWordAt(position) {
container.clearSelection()
label.cursorPosition = positionAt(position.x, position.y)
label.selectWord()
updateContainerSelectedTexts()
}
function selectAllText() {
container.clearSelection()
label.selectAll()
updateContainerSelectedTexts()
}
Connections {
target: container
onSelectionInfoChanged: updateSelection()
onDeselectAll: deselect()
}
DropArea {
anchors.fill: parent
onPositionChanged: {
if (! container.selecting) {
container.clearSelection()
container.selectionStart = index
container.selectionStartPosition = Qt.point(drag.x, drag.y)
container.selecting = true
} else {
container.selectionEnd = index
container.selectionEndPosition = Qt.point(drag.x, drag.y)
}
}
}
TapHandler {
acceptedButtons: Qt.LeftButton
onTapped: {
tapCount == 2 ? selectWordAt(eventPoint.position) :
tapCount == 3 ? selectAllText() :
container.clearSelection()
}
}
MouseArea {
anchors.fill: label
acceptedButtons: Qt.NoButton
cursorShape: label.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor
}
}

View File

@@ -0,0 +1,72 @@
import QtQuick 2.12
Item {
signal deselectAll()
property bool reversed: false
readonly property bool dragging: pointHandler.active || dragHandler.active
// onDraggingChanged: print(dragging)
property bool selecting: false
property int selectionStart: -1
property int selectionEnd: -1
property point selectionStartPosition: Qt.point(-1, -1)
property point selectionEndPosition: Qt.point(-1, -1)
property var selectedTexts: ({})
readonly property var selectionInfo: [
selectionStart, selectionStartPosition,
selectionEnd, selectionEndPosition,
]
readonly property alias dragPoint: dragHandler.centroid
readonly property alias dragPosition: dragHandler.centroid.position
function clearSelection() {
selecting = false
selectionStart = -1
selectionEnd = -1
selectionStartPosition = Qt.point(-1, -1)
selectionEndPosition = Qt.point(-1, -1)
deselectAll()
}
function copySelection() {
let toCopy = []
for (let key of Object.keys(selectedTexts).sort()) {
if (selectedTexts[key]) toCopy.push(selectedTexts[key])
}
// Call some function to copy to clipboard here instead
print("Copy: <" + toCopy.join("\n\n") + ">")
}
Item { id: dragPoint }
DragHandler {
id: dragHandler
target: dragPoint
onActiveChanged: {
if (active) {
target.Drag.active = true
} else {
target.Drag.drop()
target.Drag.active = false
selecting = false
}
}
}
TapHandler {
acceptedButtons: Qt.LeftButton
onTapped: clearSelection()
}
PointHandler {
id: pointHandler
}
}