Single message text selection for mouses
This commit is contained in:
parent
3852357614
commit
2d471b70f5
2
TODO.md
2
TODO.md
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user