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 # 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 - long-press-drag to select multiple messages on touch
- drag to select on non-touch - drag to select on non-touch
- shift+click to select everything in between - 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 { MouseArea {
anchors.fill: label anchors.fill: label
acceptedButtons: Qt.NoButton acceptedButtons: Qt.NoButton

View File

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

View File

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

View File

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