Single message text selection for mouses

This commit is contained in:
miruka 2020-03-26 20:31:19 -04:00
parent 3852357614
commit 2d471b70f5
5 changed files with 69 additions and 22 deletions

View File

@ -1,6 +1,6 @@
# TODO
- precise text selection for one message
- make it not select messages when closing context menu
- long-press-drag to select multiple messages on touch
- drag to select on non-touch
- shift+click to select everything in between

View File

@ -32,16 +32,6 @@ TextEdit {
}
// XXX
// TapHandler {
// acceptedButtons: Qt.LeftButton
// onTapped: {
// tapCount === 2 ? selectWordAt(eventPoint.position) :
// tapCount === 3 ? selectAllText() :
// null
// }
// }
MouseArea {
anchors.fill: label
acceptedButtons: Qt.NoButton

View File

@ -67,6 +67,8 @@ HRowLayout {
readonly property alias debugConsoleLoader: debugConsoleLoader
readonly property alias selectedText: contentLabel.selectedText
DebugConsoleLoader {
id: debugConsoleLoader
@ -112,7 +114,10 @@ HRowLayout {
visible: ! pureMedia
enableLinkActivation: ! eventList.selectedCount
// selectByMouse: eventDelegate.checked XXX
selectByMouse:
eventList.selectedCount <= 1 &&
eventDelegate.checked &&
textSelectionBlocker.point.scenePosition === Qt.point(0, 0)
topPadding: theme.chat.message.verticalSpacing
bottomPadding: topPadding
@ -157,25 +162,61 @@ HRowLayout {
Layout.maximumWidth: eventContent.maxMessageWidth
Layout.fillWidth: true
function selectAllText() {
// Select the message body without the date or name
contentLabel.select(
0,
contentLabel.length -
timeText.length - 1 // - 1: separating space
)
onSelectedTextChanged:
if (selectedText) eventList.delegateWithSelectedText = model.id
Connections {
target: eventList
onCheckedDelegatesChanged: contentLabel.deselect()
onDelegateWithSelectedTextChanged:
if (eventList.delegateWithSelectedText !== model.id)
contentLabel.deselect()
}
HoverHandler { id: contentHover }
TapHandler {
PointHandler {
id: mousePointHandler
acceptedButtons: Qt.LeftButton
acceptedPointerTypes:
PointerDevice.GenericPointer | PointerDevice.Eraser
onActiveChanged: {
if (active &&
! eventDelegate.checked &&
(! parent.hoveredLink ||
! parent.enableLinkActivation)) {
eventList.delegatesChecked(model.index)
checkedNow = true
}
if (! active && eventDelegate.checked) {
checkedNow ?
checkedNow = false :
eventList.delegatesUnchecked(model.index)
}
}
property bool checkedNow: false
}
TapHandler {
id: touchTapHandler
acceptedButtons: Qt.LeftButton
acceptedPointerTypes: PointerDevice.Finger | PointerDevice.Pen
onTapped:
if (! parent.hoveredLink || ! parent.enableLinkActivation)
eventDelegate.toggleChecked()
}
TapHandler {
id: textSelectionBlocker
acceptedPointerTypes: PointerDevice.Finger | PointerDevice.Pen
}
Rectangle {
id: contentBackground
width: Math.max(
parent.paintedWidth +
parent.leftPadding + parent.rightPadding,
@ -186,12 +227,18 @@ HRowLayout {
height: contentColumn.height
radius: theme.chat.message.radius
z: -100
color: eventDelegate.checked ?
"blue" : // XXX
color: eventDelegate.checked &&
! contentLabel.selectedText &&
! mousePointHandler.active?
"lightseagreen" : // XXX
isOwn?
theme.chat.message.ownBackground :
theme.chat.message.background
Behavior on color { HColorAnimation {} }
Rectangle {
visible: model.event_type === "RoomMessageNotice"
// y: parent.height / 2 - height / 2

View File

@ -57,6 +57,8 @@ HColumnLayout {
combine ? theme.spacing / (compact ? 4 : 2) :
theme.spacing * (compact ? 1 : 2)
readonly property alias leftTapHandler: leftTapHandler
// Needed because of eventList's MouseArea which steals the
// HSelectableLabel's MouseArea hover events
onCursorShapeChanged: eventList.cursorShape = cursorShape
@ -112,6 +114,7 @@ HColumnLayout {
}
TapHandler {
id: leftTapHandler
acceptedButtons: Qt.LeftButton
onTapped: toggleChecked()
}
@ -193,6 +196,11 @@ HColumnLayout {
return
}
if (eventContent.selectedText) {
Clipboard.text = eventContent.selectedText
return
}
const contents = []
for (const model of eventList.getSortedCheckedDelegates()) {

View File

@ -76,6 +76,8 @@ Rectangle {
property bool ownEventsOnRight:
width < theme.chat.eventList.ownEventsOnRightUnderWidth
property string delegateWithSelectedText: ""
function canCombine(item, itemAfter) {
if (! item || ! itemAfter) return false