mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 11:00:48 +03:00
Fix hover handling in the timeline
This commit is contained in:
parent
0d61f4bff1
commit
d43607d01c
16 changed files with 127 additions and 67 deletions
|
@ -281,6 +281,7 @@ set(SRC_FILES
|
|||
src/ui/InfoMessage.cpp
|
||||
src/ui/Label.cpp
|
||||
src/ui/LoadingIndicator.cpp
|
||||
src/ui/NhekoCursorShape.cpp
|
||||
src/ui/NhekoDropArea.cpp
|
||||
src/ui/OverlayModal.cpp
|
||||
src/ui/OverlayWidget.cpp
|
||||
|
@ -495,6 +496,7 @@ qt5_wrap_cpp(MOC_HEADERS
|
|||
src/ui/Label.h
|
||||
src/ui/FloatingButton.h
|
||||
src/ui/Menu.h
|
||||
src/ui/NhekoCursorShape.h
|
||||
src/ui/NhekoDropArea.h
|
||||
src/ui/OverlayWidget.h
|
||||
src/ui/SnackBar.h
|
||||
|
|
|
@ -116,9 +116,7 @@ brew install --cask nheko
|
|||
|
||||
### Build Requirements
|
||||
|
||||
- Qt5 (5.10 or greater). Qt 5.7 adds support for color font rendering with
|
||||
Freetype, which is essential to properly support emoji, 5.8 adds some features
|
||||
to make interopability with Qml easier, 5.10 makes sliders actually visible with different palettes.
|
||||
- Qt5 (5.12 or greater). Required for overlapping hover handlers in Qml.
|
||||
- CMake 3.15 or greater. (Lower version may work, but may break boost linking)
|
||||
- [mtxclient](https://github.com/Nheko-Reborn/mtxclient)
|
||||
- [LMDB](https://symas.com/lightning-memory-mapped-database/)
|
||||
|
|
|
@ -90,4 +90,9 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
CursorShape {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import QtQuick 2.5
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.1
|
||||
import im.nheko 1.0
|
||||
|
||||
|
@ -24,14 +24,11 @@ Rectangle {
|
|||
color: "transparent"
|
||||
width: 16
|
||||
height: 16
|
||||
ToolTip.visible: ma.containsMouse && indicator.visible
|
||||
ToolTip.visible: ma.hovered && indicator.visible
|
||||
ToolTip.text: getEncryptionTooltip()
|
||||
|
||||
MouseArea {
|
||||
HoverHandler {
|
||||
id: ma
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
}
|
||||
|
||||
Image {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import "./ui"
|
||||
import QtQuick 2.3
|
||||
import QtQuick.Controls 2.3
|
||||
import im.nheko 1.0 // for cursor shape
|
||||
|
||||
AbstractButton {
|
||||
id: button
|
||||
|
@ -23,11 +24,10 @@ AbstractButton {
|
|||
source: image != "" ? ("image://colorimage/" + image + "?" + ((button.hovered && changeColorOnHover) ? highlightColor : buttonTextColor)) : ""
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
CursorShape {
|
||||
id: mouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
onPressed: mouse.accepted = false
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ TextEdit {
|
|||
focus: false
|
||||
wrapMode: Text.Wrap
|
||||
selectByMouse: !Settings.mobileMode
|
||||
enabled: selectByMouse
|
||||
color: colors.text
|
||||
onLinkActivated: {
|
||||
if (/^https:\/\/matrix.to\/#\/(@.*)$/.test(link)) {
|
||||
|
@ -25,12 +26,9 @@ TextEdit {
|
|||
ToolTip.visible: hoveredLink
|
||||
ToolTip.text: hoveredLink
|
||||
|
||||
MouseArea {
|
||||
id: ma
|
||||
|
||||
CursorShape {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
cursorShape: hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import "./delegates"
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick 2.9
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.2
|
||||
import QtQuick.Window 2.2
|
||||
|
@ -153,12 +153,15 @@ ScrollView {
|
|||
color: TimelineManager.userColor(modelData ? modelData.userId : "", colors.window)
|
||||
textFormat: Text.RichText
|
||||
|
||||
MouseArea {
|
||||
TapHandler {
|
||||
//cursorShape: Qt.PointingHandCursor
|
||||
|
||||
onSingleTapped: chat.model.openUserProfile(modelData.userId)
|
||||
}
|
||||
|
||||
CursorShape {
|
||||
anchors.fill: parent
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
onClicked: chat.model.openUserProfile(modelData.userId)
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
propagateComposedEvents: true
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import "./delegates"
|
||||
import "./emoji"
|
||||
import QtQuick 2.6
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.2
|
||||
import QtQuick.Window 2.2
|
||||
|
@ -12,27 +12,23 @@ Item {
|
|||
height: row.height
|
||||
|
||||
Rectangle {
|
||||
color: (Settings.messageHoverHighlight && hoverHandler.containsMouse) ? colors.alternateBase : "transparent"
|
||||
color: (Settings.messageHoverHighlight && hoverHandler.hovered) ? colors.alternateBase : "transparent"
|
||||
anchors.fill: row
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
|
||||
anchors.fill: parent
|
||||
propagateComposedEvents: true
|
||||
preventStealing: false
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.AllButtons
|
||||
onClicked: {
|
||||
if (mouse.button === Qt.RightButton)
|
||||
messageContextMenu.show(model.id, model.type, model.isEncrypted, model.isEditable, row);
|
||||
else
|
||||
mouse.accepted = false;
|
||||
}
|
||||
onPressAndHold: {
|
||||
messageContextMenu.show(model.id, model.type, model.isEncrypted, model.isEditable, row, mapToItem(timelineRoot, mouse.x, mouse.y));
|
||||
}
|
||||
acceptedDevices: PointerDevice.GenericPointer
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
onSingleTapped: messageContextMenu.show(model.id, model.type, model.isEncrypted, model.isEditable, row, mapToItem(timelineRoot, eventPoint.position.x, eventPoint.position.y))
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
onLongPressed: messageContextMenu.show(model.id, model.type, model.isEncrypted, model.isEditable, row, mapToItem(timelineRoot, point.position.x, point.position.y))
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
|
@ -151,15 +147,11 @@ Item {
|
|||
text: model.timestamp.toLocaleTimeString("HH:mm")
|
||||
width: Math.max(implicitWidth, text.length * fontMetrics.maximumCharacterWidth)
|
||||
color: inactiveColors.text
|
||||
ToolTip.visible: ma.containsMouse
|
||||
ToolTip.visible: ma.hovered
|
||||
ToolTip.text: Qt.formatDateTime(model.timestamp, Qt.DefaultLocaleLongDate)
|
||||
|
||||
MouseArea {
|
||||
HoverHandler {
|
||||
id: ma
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
propagateComposedEvents: true
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import QtQuick 2.6
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.2
|
||||
import im.nheko 1.0
|
||||
|
||||
|
@ -31,7 +31,15 @@ Item {
|
|||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: TimelineManager.timeline.saveMedia(model.data.id)
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
onSingleTapped: TimelineManager.timeline.saveMedia(model.data.id)
|
||||
}
|
||||
|
||||
CursorShape {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import QtQuick 2.6
|
||||
import QtQuick 2.12
|
||||
import im.nheko 1.0
|
||||
|
||||
Item {
|
||||
|
@ -32,20 +32,20 @@ Item {
|
|||
smooth: true
|
||||
mipmap: true
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
|
||||
TapHandler {
|
||||
enabled: model.data.type == MtxEvent.ImageMessage && img.status == Image.Ready
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: TimelineManager.openImageOverlay(model.data.url, model.data.id)
|
||||
onSingleTapped: TimelineManager.openImageOverlay(model.data.url, model.data.id)
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: mouseArea
|
||||
}
|
||||
|
||||
Item {
|
||||
id: overlay
|
||||
|
||||
anchors.fill: parent
|
||||
visible: mouseArea.containsMouse
|
||||
visible: mouseArea.hovered
|
||||
|
||||
Rectangle {
|
||||
id: container
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import QtMultimedia 5.6
|
||||
import QtQuick 2.6
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.2
|
||||
import im.nheko 1.0
|
||||
|
@ -140,9 +140,8 @@ Rectangle {
|
|||
fillMode: Image.Pad
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
TapHandler {
|
||||
onSingleTapped: {
|
||||
switch (button.state) {
|
||||
case "":
|
||||
TimelineManager.timeline.cacheMedia(model.data.id);
|
||||
|
@ -159,6 +158,10 @@ Rectangle {
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CursorShape {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import QtQuick 2.6
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.2
|
||||
import QtQuick.Window 2.2
|
||||
|
@ -13,10 +13,12 @@ Item {
|
|||
width: parent.width
|
||||
height: replyContainer.height
|
||||
|
||||
MouseArea {
|
||||
TapHandler {
|
||||
onSingleTapped: chat.positionViewAtIndex(chat.model.idToIndex(modelData.id), ListView.Contain)
|
||||
}
|
||||
|
||||
CursorShape {
|
||||
anchors.fill: parent
|
||||
preventStealing: false
|
||||
onClicked: chat.positionViewAtIndex(chat.model.idToIndex(modelData.id), ListView.Contain)
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
|
||||
|
@ -43,10 +45,8 @@ Item {
|
|||
color: replyComponent.userColor
|
||||
textFormat: Text.RichText
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: chat.model.openUserProfile(reply.modelData.userId)
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
TapHandler {
|
||||
onSingleTapped: chat.model.openUserProfile(reply.modelData.userId)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,5 +8,6 @@ MatrixText {
|
|||
width: parent ? parent.width : undefined
|
||||
height: isReply ? Math.round(Math.min(timelineRoot.height / 8, implicitHeight)) : undefined
|
||||
clip: isReply
|
||||
selectByMouse: !Settings.mobileMode && !isReply
|
||||
font.pointSize: (Settings.enlargeEmojiOnlyMessages && model.data.isOnlyEmoji > 0 && model.data.isOnlyEmoji < 4) ? Settings.fontSize * 3 : Settings.fontSize
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "dialogs/ImageOverlay.h"
|
||||
#include "emoji/EmojiModel.h"
|
||||
#include "emoji/Provider.h"
|
||||
#include "ui/NhekoCursorShape.h"
|
||||
#include "ui/NhekoDropArea.h"
|
||||
|
||||
#include <iostream> //only for debugging
|
||||
|
@ -118,6 +119,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
|
|||
qmlRegisterType<DelegateChoice>("im.nheko", 1, 0, "DelegateChoice");
|
||||
qmlRegisterType<DelegateChooser>("im.nheko", 1, 0, "DelegateChooser");
|
||||
qmlRegisterType<NhekoDropArea>("im.nheko", 1, 0, "NhekoDropArea");
|
||||
qmlRegisterType<NhekoCursorShape>("im.nheko", 1, 0, "CursorShape");
|
||||
qmlRegisterUncreatableType<DeviceVerificationFlow>(
|
||||
"im.nheko", 1, 0, "DeviceVerificationFlow", "Can't create verification flow from QML!");
|
||||
qmlRegisterUncreatableType<UserProfile>(
|
||||
|
@ -548,4 +550,4 @@ void
|
|||
TimelineViewManager::focusMessageInput()
|
||||
{
|
||||
emit focusInput();
|
||||
}
|
||||
}
|
||||
|
|
25
src/ui/NhekoCursorShape.cpp
Normal file
25
src/ui/NhekoCursorShape.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include "NhekoCursorShape.h"
|
||||
|
||||
#include <QCursor>
|
||||
|
||||
NhekoCursorShape::NhekoCursorShape(QQuickItem *parent)
|
||||
: QQuickItem(parent)
|
||||
, currentShape_(Qt::CursorShape::ArrowCursor)
|
||||
{}
|
||||
|
||||
Qt::CursorShape
|
||||
NhekoCursorShape::cursorShape() const
|
||||
{
|
||||
return cursor().shape();
|
||||
}
|
||||
|
||||
void
|
||||
NhekoCursorShape::setCursorShape(Qt::CursorShape cursorShape)
|
||||
{
|
||||
if (currentShape_ == cursorShape)
|
||||
return;
|
||||
|
||||
currentShape_ = cursorShape;
|
||||
setCursor(cursorShape);
|
||||
emit cursorShapeChanged();
|
||||
}
|
26
src/ui/NhekoCursorShape.h
Normal file
26
src/ui/NhekoCursorShape.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
// see
|
||||
// https://stackoverflow.com/questions/27821054/how-to-change-cursor-shape-in-qml-when-mousearea-is-covered-with-another-mousear/29382092#29382092
|
||||
|
||||
#include <QQuickItem>
|
||||
|
||||
class NhekoCursorShape : public QQuickItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape NOTIFY
|
||||
cursorShapeChanged)
|
||||
|
||||
public:
|
||||
explicit NhekoCursorShape(QQuickItem *parent = 0);
|
||||
|
||||
private:
|
||||
Qt::CursorShape cursorShape() const;
|
||||
void setCursorShape(Qt::CursorShape cursorShape);
|
||||
|
||||
Qt::CursorShape currentShape_;
|
||||
|
||||
signals:
|
||||
void cursorShapeChanged();
|
||||
};
|
Loading…
Reference in a new issue