mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 03:00:46 +03:00
Switch to manual polishing of event delegates
This commit is contained in:
parent
205a42dade
commit
6c6370c83f
7 changed files with 169 additions and 60 deletions
|
@ -52,8 +52,8 @@ Item {
|
||||||
//onModelChanged: if (room) room.sendReset()
|
//onModelChanged: if (room) room.sendReset()
|
||||||
//reuseItems: true
|
//reuseItems: true
|
||||||
boundsBehavior: Flickable.StopAtBounds
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
displayMarginBeginning: height / 2
|
displayMarginBeginning: height / 4
|
||||||
displayMarginEnd: height / 2
|
displayMarginEnd: height / 4
|
||||||
model: (filteredTimeline.filterByThread || filteredTimeline.filterByContent) ? filteredTimeline : room
|
model: (filteredTimeline.filterByThread || filteredTimeline.filterByContent) ? filteredTimeline : room
|
||||||
//pixelAligned: true
|
//pixelAligned: true
|
||||||
spacing: 2
|
spacing: 2
|
||||||
|
|
|
@ -18,7 +18,7 @@ TimelineEvent {
|
||||||
id: wrapper
|
id: wrapper
|
||||||
ListView.delayRemove: true
|
ListView.delayRemove: true
|
||||||
width: chat.delegateMaxWidth
|
width: chat.delegateMaxWidth
|
||||||
height: Math.max((section.item?.height ?? 0) + gridContainer.implicitHeight + reactionRow.implicitHeight + unreadRow.height, 10)
|
height: Math.max((section.item?.height ?? 0) + gridContainer.implicitHeight + reactionRow.implicitHeight + unreadRow.height, 20)
|
||||||
anchors.horizontalCenter: ListView.view.contentItem.horizontalCenter
|
anchors.horizontalCenter: ListView.view.contentItem.horizontalCenter
|
||||||
//room: chatRoot.roommodel
|
//room: chatRoot.roommodel
|
||||||
|
|
||||||
|
@ -51,6 +51,8 @@ TimelineEvent {
|
||||||
property alias hovered: messageHover.hovered
|
property alias hovered: messageHover.hovered
|
||||||
property bool scrolledToThis: false
|
property bool scrolledToThis: false
|
||||||
|
|
||||||
|
maxWidth: chat.delegateMaxWidth - avatarMargin - metadata.width
|
||||||
|
|
||||||
data: [
|
data: [
|
||||||
Loader {
|
Loader {
|
||||||
id: section
|
id: section
|
||||||
|
@ -131,7 +133,7 @@ TimelineEvent {
|
||||||
anchors.top: gridContainer.top
|
anchors.top: gridContainer.top
|
||||||
anchors.left: gridContainer.left
|
anchors.left: gridContainer.left
|
||||||
anchors.topMargin: -2
|
anchors.topMargin: -2
|
||||||
anchors.leftMargin: wrapper.avatarMargin + 2
|
anchors.leftMargin: -2
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
border.color: Nheko.theme.red
|
border.color: Nheko.theme.red
|
||||||
border.width: wrapper.notificationlevel == MtxEvent.Highlight ? 1 : 0
|
border.width: wrapper.notificationlevel == MtxEvent.Highlight ? 1 : 0
|
||||||
|
@ -139,11 +141,13 @@ TimelineEvent {
|
||||||
height: contentColumn.implicitHeight + 4
|
height: contentColumn.implicitHeight + 4
|
||||||
width: contentColumn.implicitWidth + 4
|
width: contentColumn.implicitWidth + 4
|
||||||
},
|
},
|
||||||
RowLayout {
|
Row {
|
||||||
id: gridContainer
|
id: gridContainer
|
||||||
|
|
||||||
width: wrapper.width
|
width: wrapper.width - wrapper.avatarMargin
|
||||||
|
x: wrapper.avatarMargin
|
||||||
y: section.visible && section.active ? section.y + section.height : 0
|
y: section.visible && section.active ? section.y + section.height : 0
|
||||||
|
spacing: Nheko.paddingSmall
|
||||||
|
|
||||||
HoverHandler {
|
HoverHandler {
|
||||||
id: messageHover
|
id: messageHover
|
||||||
|
@ -154,23 +158,20 @@ TimelineEvent {
|
||||||
messageActions.model = wrapper;
|
messageActions.model = wrapper;
|
||||||
messageActions.attached = wrapper;
|
messageActions.attached = wrapper;
|
||||||
messageActions.anchors.bottomMargin = -gridContainer.y
|
messageActions.anchors.bottomMargin = -gridContainer.y
|
||||||
|
messageActions.anchors.rightMargin = metadata.width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.preferredWidth: wrapper.avatarMargin
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractButton {
|
AbstractButton {
|
||||||
ToolTip.delay: Nheko.tooltipDelay
|
ToolTip.delay: Nheko.tooltipDelay
|
||||||
ToolTip.text: qsTr("Part of a thread")
|
ToolTip.text: qsTr("Part of a thread")
|
||||||
ToolTip.visible: hovered
|
ToolTip.visible: hovered
|
||||||
Layout.fillHeight: true
|
height: contentColumn.height
|
||||||
visible: wrapper.threadId
|
visible: wrapper.threadId
|
||||||
Layout.preferredWidth: 4
|
width: 4
|
||||||
|
|
||||||
onClicked: wrapper.room.thread = wrapper.threadId
|
onClicked: wrapper.room.thread = wrapper.threadId
|
||||||
|
|
||||||
|
@ -181,17 +182,16 @@ TimelineEvent {
|
||||||
color: TimelineManager.userColor(wrapper.threadId, palette.base)
|
color: TimelineManager.userColor(wrapper.threadId, palette.base)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
Column {
|
||||||
id: contentColumn
|
id: contentColumn
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
AbstractButton {
|
AbstractButton {
|
||||||
id: replyRow
|
id: replyRow
|
||||||
visible: wrapper.reply
|
visible: wrapper.reply
|
||||||
Layout.fillWidth: true
|
//Layout.fillWidth: true
|
||||||
Layout.maximumHeight: timelineView.height / 8
|
//Layout.maximumHeight: timelineView.height / 8
|
||||||
Layout.preferredWidth: replyRowLay.implicitWidth
|
//Layout.preferredWidth: replyRowLay.implicitWidth
|
||||||
Layout.preferredHeight: replyRowLay.implicitHeight
|
//Layout.preferredHeight: replyRowLay.implicitHeight
|
||||||
|
|
||||||
property color userColor: TimelineManager.userColor(wrapper.reply?.userId ?? '', palette.base)
|
property color userColor: TimelineManager.userColor(wrapper.reply?.userId ?? '', palette.base)
|
||||||
|
|
||||||
|
@ -202,32 +202,33 @@ TimelineEvent {
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: RowLayout {
|
contentItem: Row {
|
||||||
id: replyRowLay
|
id: replyRowLay
|
||||||
|
|
||||||
anchors.fill: parent
|
spacing: Nheko.paddingSmall
|
||||||
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: replyLine
|
id: replyLine
|
||||||
Layout.fillHeight: true
|
height: replyCol.height
|
||||||
color: replyRow.userColor
|
color: replyRow.userColor
|
||||||
Layout.preferredWidth: 4
|
width: 4
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
Column {
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
|
id: replyCol
|
||||||
|
|
||||||
AbstractButton {
|
AbstractButton {
|
||||||
id: replyUserButton
|
id: replyUserButton
|
||||||
Layout.fillWidth: true
|
|
||||||
contentItem: ElidedLabel {
|
contentItem: Label {
|
||||||
id: userName_
|
id: userName_
|
||||||
fullText: wrapper.reply?.userName ?? ''
|
text: wrapper.reply?.userName ?? ''
|
||||||
color: replyRow.userColor
|
color: replyRow.userColor
|
||||||
textFormat: Text.RichText
|
textFormat: Text.RichText
|
||||||
width: parent.width
|
width: wrapper.maxWidth
|
||||||
elideWidth: width
|
//elideWidth: wrapper.maxWidth
|
||||||
}
|
}
|
||||||
onClicked: wrapper.room.openUserProfile(wrapper.reply?.userId)
|
onClicked: wrapper.room.openUserProfile(wrapper.reply?.userId)
|
||||||
}
|
}
|
||||||
|
@ -239,7 +240,7 @@ TimelineEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
width: replyRow.implicitContentWidth
|
//width: replyRow.implicitContentWidth
|
||||||
color: Qt.tint(palette.base, Qt.hsla(replyRow.userColor.hslHue, 0.5, replyRow.userColor.hslLightness, 0.1))
|
color: Qt.tint(palette.base, Qt.hsla(replyRow.userColor.hslHue, 0.5, replyRow.userColor.hslLightness, 0.1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,19 +260,16 @@ TimelineEvent {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
},
|
||||||
// spacer to fill width if needed
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: metadata
|
id: metadata
|
||||||
|
|
||||||
property int iconSize: Math.floor(fontMetrics.ascent * scaling)
|
property int iconSize: Math.floor(fontMetrics.ascent * scaling)
|
||||||
property double scaling: Settings.bubbles ? 0.75 : 1
|
property double scaling: Settings.bubbles ? 0.75 : 1
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignTop | Qt.AlignRight
|
anchors.right: parent.right
|
||||||
Layout.preferredWidth: implicitWidth
|
y: section.visible && section.active ? section.y + section.height : 0
|
||||||
|
|
||||||
spacing: 2
|
spacing: 2
|
||||||
visible: !isStateEvent
|
visible: !isStateEvent
|
||||||
|
|
||||||
|
@ -339,8 +337,7 @@ TimelineEvent {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
|
||||||
Reactions {
|
Reactions {
|
||||||
id: reactionRow
|
id: reactionRow
|
||||||
|
|
||||||
|
|
|
@ -620,7 +620,6 @@ Item {
|
||||||
roleValue: MtxEvent.Member
|
roleValue: MtxEvent.Member
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
width: parent?.width ?? 100
|
|
||||||
|
|
||||||
NoticeMessage {
|
NoticeMessage {
|
||||||
body: formatted
|
body: formatted
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
import ".."
|
import ".."
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
//import QtQuick.Layouts
|
||||||
import im.nheko
|
import im.nheko
|
||||||
|
|
||||||
MatrixText {
|
MatrixText {
|
||||||
|
@ -41,7 +41,10 @@ MatrixText {
|
||||||
}" : "") + // TODO(Nico): Figure out how to support mobile
|
}" : "") + // TODO(Nico): Figure out how to support mobile
|
||||||
"</style>
|
"</style>
|
||||||
" + formatted.replace(/<del>/g, "<s>").replace(/<\/del>/g, "</s>").replace(/<strike>/g, "<s>").replace(/<\/strike>/g, "</s>")
|
" + formatted.replace(/<del>/g, "<s>").replace(/<\/del>/g, "</s>").replace(/<strike>/g, "<s>").replace(/<\/strike>/g, "</s>")
|
||||||
Layout.maximumHeight: !keepFullText ? Math.round(Math.min(timelineView.height / 8, implicitHeight)) : implicitHeight
|
//Layout.maximumHeight: !keepFullText ? Math.round(Math.min(timelineView.height / 8, implicitHeight)) : implicitHeight
|
||||||
|
|
||||||
|
//EventDelegateChooser.fillWidth: true
|
||||||
|
|
||||||
clip: !keepFullText
|
clip: !keepFullText
|
||||||
selectByMouse: !Settings.mobileMode && !isReply
|
selectByMouse: !Settings.mobileMode && !isReply
|
||||||
enabled: !Settings.mobileMode && !isReply
|
enabled: !Settings.mobileMode && !isReply
|
||||||
|
|
|
@ -131,7 +131,7 @@ EventDelegateChooser::DelegateIncubator::setInitialState(QObject *obj)
|
||||||
roleToPropIdx.insert(*role, i);
|
roleToPropIdx.insert(*role, i);
|
||||||
roles.emplace_back(*role);
|
roles.emplace_back(*role);
|
||||||
|
|
||||||
nhlog::ui()->critical("Found prop {}, idx {}, role {}", prop.name(), i, *role);
|
// nhlog::ui()->critical("Found prop {}, idx {}, role {}", prop.name(), i, *role);
|
||||||
} else {
|
} else {
|
||||||
nhlog::ui()->critical("Required property {} not found in model!", prop.name());
|
nhlog::ui()->critical("Required property {} not found in model!", prop.name());
|
||||||
}
|
}
|
||||||
|
@ -140,14 +140,15 @@ EventDelegateChooser::DelegateIncubator::setInitialState(QObject *obj)
|
||||||
nhlog::ui()->debug("Querying data for id {}", currentId.toStdString());
|
nhlog::ui()->debug("Querying data for id {}", currentId.toStdString());
|
||||||
chooser.room_->multiData(currentId, forReply ? chooser.eventId_ : QString(), roles);
|
chooser.room_->multiData(currentId, forReply ? chooser.eventId_ : QString(), roles);
|
||||||
|
|
||||||
|
Qt::beginPropertyUpdateGroup();
|
||||||
for (const auto &role : roles) {
|
for (const auto &role : roles) {
|
||||||
const auto &roleName = roleNames[role.role()];
|
const auto &roleName = roleNames[role.role()];
|
||||||
nhlog::ui()->critical("Setting role {}, {} to {}",
|
// nhlog::ui()->critical("Setting role {}, {} to {}",
|
||||||
role.role(),
|
// role.role(),
|
||||||
roleName.toStdString(),
|
// roleName.toStdString(),
|
||||||
role.data().toString().toStdString());
|
// role.data().toString().toStdString());
|
||||||
|
|
||||||
nhlog::ui()->critical("Setting {}", mo->property(roleToPropIdx[role.role()]).name());
|
// nhlog::ui()->critical("Setting {}", mo->property(roleToPropIdx[role.role()]).name());
|
||||||
mo->property(roleToPropIdx[role.role()]).write(obj, role.data());
|
mo->property(roleToPropIdx[role.role()]).write(obj, role.data());
|
||||||
|
|
||||||
if (const auto &req = requiredProperties.find(roleName); req != requiredProperties.end())
|
if (const auto &req = requiredProperties.find(roleName); req != requiredProperties.end())
|
||||||
|
@ -156,14 +157,15 @@ EventDelegateChooser::DelegateIncubator::setInitialState(QObject *obj)
|
||||||
|
|
||||||
if (isReplyNeeded) {
|
if (isReplyNeeded) {
|
||||||
const auto roleName = QByteArray("isReply");
|
const auto roleName = QByteArray("isReply");
|
||||||
nhlog::ui()->critical("Setting role {} to {}", roleName.toStdString(), forReply);
|
// nhlog::ui()->critical("Setting role {} to {}", roleName.toStdString(), forReply);
|
||||||
|
|
||||||
nhlog::ui()->critical("Setting {}", mo->property(roleToPropIdx[-1]).name());
|
// nhlog::ui()->critical("Setting {}", mo->property(roleToPropIdx[-1]).name());
|
||||||
mo->property(roleToPropIdx[-1]).write(obj, forReply);
|
mo->property(roleToPropIdx[-1]).write(obj, forReply);
|
||||||
|
|
||||||
if (const auto &req = requiredProperties.find(roleName); req != requiredProperties.end())
|
if (const auto &req = requiredProperties.find(roleName); req != requiredProperties.end())
|
||||||
QQmlIncubatorPrivate::get(this)->requiredProperties()->remove(*req);
|
QQmlIncubatorPrivate::get(this)->requiredProperties()->remove(*req);
|
||||||
}
|
}
|
||||||
|
Qt::endPropertyUpdateGroup();
|
||||||
|
|
||||||
// setInitialProperties(rolesToSet);
|
// setInitialProperties(rolesToSet);
|
||||||
|
|
||||||
|
@ -188,9 +190,12 @@ EventDelegateChooser::DelegateIncubator::setInitialState(QObject *obj)
|
||||||
auto mo = obj->metaObject();
|
auto mo = obj->metaObject();
|
||||||
chooser.room_->multiData(
|
chooser.room_->multiData(
|
||||||
currentId, forReply ? chooser.eventId_ : QString(), rolesToRequest);
|
currentId, forReply ? chooser.eventId_ : QString(), rolesToRequest);
|
||||||
|
|
||||||
|
Qt::beginPropertyUpdateGroup();
|
||||||
for (const auto &role : rolesToRequest) {
|
for (const auto &role : rolesToRequest) {
|
||||||
mo->property(roleToPropIdx[role.role()]).write(obj, role.data());
|
mo->property(roleToPropIdx[role.role()]).write(obj, role.data());
|
||||||
}
|
}
|
||||||
|
Qt::endPropertyUpdateGroup();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!forReply) {
|
if (!forReply) {
|
||||||
|
@ -257,11 +262,22 @@ EventDelegateChooser::DelegateIncubator::statusChanged(QQmlIncubator::Status sta
|
||||||
|
|
||||||
child->setParentItem(&chooser);
|
child->setParentItem(&chooser);
|
||||||
QQmlEngine::setObjectOwnership(child, QQmlEngine::ObjectOwnership::JavaScriptOwnership);
|
QQmlEngine::setObjectOwnership(child, QQmlEngine::ObjectOwnership::JavaScriptOwnership);
|
||||||
|
|
||||||
|
// connect(child, &QQuickItem::parentChanged, child, [child](QQuickItem *) {
|
||||||
|
// // QTBUG-115687
|
||||||
|
// if (child->flags().testFlag(QQuickItem::ItemObservesViewport)) {
|
||||||
|
// nhlog::ui()->critical("SETTING OBSERVES VIEWPORT");
|
||||||
|
// // Re-trigger the parent traversal to get subtreeTransformChangedEnabled turned
|
||||||
|
// on child->setFlag(QQuickItem::ItemObservesViewport);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
if (forReply)
|
if (forReply)
|
||||||
emit chooser.replyChanged();
|
emit chooser.replyChanged();
|
||||||
else
|
else
|
||||||
emit chooser.mainChanged();
|
emit chooser.mainChanged();
|
||||||
|
|
||||||
|
chooser.polish();
|
||||||
} else if (status == QQmlIncubator::Error) {
|
} else if (status == QQmlIncubator::Error) {
|
||||||
auto errors_ = errors();
|
auto errors_ = errors();
|
||||||
for (const auto &e : qAsConst(errors_))
|
for (const auto &e : qAsConst(errors_))
|
||||||
|
@ -269,3 +285,49 @@ EventDelegateChooser::DelegateIncubator::statusChanged(QQmlIncubator::Status sta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
EventDelegateChooser::updatePolish()
|
||||||
|
{
|
||||||
|
auto mainChild = qobject_cast<QQuickItem *>(eventIncubator.object());
|
||||||
|
auto replyChild = qobject_cast<QQuickItem *>(replyIncubator.object());
|
||||||
|
|
||||||
|
nhlog::ui()->critical("POLISHING {}", (void *)this);
|
||||||
|
|
||||||
|
if (mainChild) {
|
||||||
|
auto attached = qobject_cast<EventDelegateChooserAttachedType *>(
|
||||||
|
qmlAttachedPropertiesObject<EventDelegateChooser>(mainChild));
|
||||||
|
Q_ASSERT(attached != nullptr);
|
||||||
|
|
||||||
|
// in theory we could also reset the width, but that doesn't seem to work nicely for text
|
||||||
|
// areas because of how they cache it.
|
||||||
|
mainChild->setWidth(maxWidth_);
|
||||||
|
mainChild->ensurePolished();
|
||||||
|
auto width = mainChild->implicitWidth();
|
||||||
|
|
||||||
|
if (width > maxWidth_ || attached->fillWidth())
|
||||||
|
width = maxWidth_;
|
||||||
|
|
||||||
|
nhlog::ui()->debug(
|
||||||
|
"Made event delegate width: {}, {}", width, mainChild->metaObject()->className());
|
||||||
|
mainChild->setWidth(width);
|
||||||
|
mainChild->ensurePolished();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replyChild) {
|
||||||
|
auto attached = qobject_cast<EventDelegateChooserAttachedType *>(
|
||||||
|
qmlAttachedPropertiesObject<EventDelegateChooser>(replyChild));
|
||||||
|
Q_ASSERT(attached != nullptr);
|
||||||
|
|
||||||
|
// in theory we could also reset the width, but that doesn't seem to work nicely for text
|
||||||
|
// areas because of how they cache it.
|
||||||
|
replyChild->setWidth(maxWidth_);
|
||||||
|
replyChild->ensurePolished();
|
||||||
|
auto width = replyChild->implicitWidth();
|
||||||
|
|
||||||
|
if (width > maxWidth_ || attached->fillWidth())
|
||||||
|
width = maxWidth_;
|
||||||
|
|
||||||
|
replyChild->setWidth(width);
|
||||||
|
replyChild->ensurePolished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// A DelegateChooser like the one, that was added to Qt5.12 (in labs), but compatible with older Qt
|
|
||||||
// versions see KDE/kquickitemviews see qtdeclarative/qqmldelagatecomponent
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
@ -17,6 +14,32 @@
|
||||||
|
|
||||||
#include "TimelineModel.h"
|
#include "TimelineModel.h"
|
||||||
|
|
||||||
|
class EventDelegateChooserAttachedType : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool fillWidth READ fillWidth WRITE setFillWidth NOTIFY fillWidthChanged)
|
||||||
|
QML_ANONYMOUS
|
||||||
|
public:
|
||||||
|
EventDelegateChooserAttachedType(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
bool fillWidth() const { return fillWidth_; }
|
||||||
|
void setFillWidth(bool fill)
|
||||||
|
{
|
||||||
|
fillWidth_ = fill;
|
||||||
|
emit fillWidthChanged();
|
||||||
|
}
|
||||||
|
signals:
|
||||||
|
void fillWidthChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool fillWidth_ = false, keepAspectRatio = false;
|
||||||
|
double aspectRatio = 1.;
|
||||||
|
int maxWidth = -1;
|
||||||
|
int maxHeight = -1;
|
||||||
|
};
|
||||||
|
|
||||||
class EventDelegateChoice : public QObject
|
class EventDelegateChoice : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -51,14 +74,18 @@ class EventDelegateChooser : public QQuickItem
|
||||||
QML_ELEMENT
|
QML_ELEMENT
|
||||||
Q_CLASSINFO("DefaultProperty", "choices")
|
Q_CLASSINFO("DefaultProperty", "choices")
|
||||||
|
|
||||||
public:
|
QML_ATTACHED(EventDelegateChooserAttachedType)
|
||||||
|
|
||||||
Q_PROPERTY(QQmlListProperty<EventDelegateChoice> choices READ choices CONSTANT FINAL)
|
Q_PROPERTY(QQmlListProperty<EventDelegateChoice> choices READ choices CONSTANT FINAL)
|
||||||
Q_PROPERTY(QQuickItem *main READ main NOTIFY mainChanged FINAL)
|
Q_PROPERTY(QQuickItem *main READ main NOTIFY mainChanged FINAL)
|
||||||
Q_PROPERTY(QQuickItem *reply READ reply NOTIFY replyChanged FINAL)
|
Q_PROPERTY(QQuickItem *reply READ reply NOTIFY replyChanged FINAL)
|
||||||
Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged REQUIRED FINAL)
|
Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged REQUIRED FINAL)
|
||||||
Q_PROPERTY(QString replyTo READ replyTo WRITE setReplyTo NOTIFY replyToChanged REQUIRED FINAL)
|
Q_PROPERTY(QString replyTo READ replyTo WRITE setReplyTo NOTIFY replyToChanged REQUIRED FINAL)
|
||||||
Q_PROPERTY(TimelineModel *room READ room WRITE setRoom NOTIFY roomChanged REQUIRED FINAL)
|
Q_PROPERTY(TimelineModel *room READ room WRITE setRoom NOTIFY roomChanged REQUIRED FINAL)
|
||||||
|
Q_PROPERTY(bool sameWidth READ sameWidth WRITE setSameWidth NOTIFY sameWidthChanged)
|
||||||
|
Q_PROPERTY(int maxWidth READ maxWidth WRITE setMaxWidth NOTIFY maxWidthChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
QQmlListProperty<EventDelegateChoice> choices();
|
QQmlListProperty<EventDelegateChoice> choices();
|
||||||
|
|
||||||
[[nodiscard]] QQuickItem *main() const
|
[[nodiscard]] QQuickItem *main() const
|
||||||
|
@ -70,6 +97,20 @@ public:
|
||||||
return qobject_cast<QQuickItem *>(replyIncubator.object());
|
return qobject_cast<QQuickItem *>(replyIncubator.object());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sameWidth() const { return sameWidth_; }
|
||||||
|
void setSameWidth(bool width)
|
||||||
|
{
|
||||||
|
sameWidth_ = width;
|
||||||
|
emit sameWidthChanged();
|
||||||
|
}
|
||||||
|
bool maxWidth() const { return maxWidth_; }
|
||||||
|
void setMaxWidth(int width)
|
||||||
|
{
|
||||||
|
maxWidth_ = width;
|
||||||
|
emit maxWidthChanged();
|
||||||
|
polish();
|
||||||
|
}
|
||||||
|
|
||||||
void setRoom(TimelineModel *m)
|
void setRoom(TimelineModel *m)
|
||||||
{
|
{
|
||||||
if (m != room_) {
|
if (m != room_) {
|
||||||
|
@ -105,12 +146,21 @@ public:
|
||||||
|
|
||||||
void componentComplete() override;
|
void componentComplete() override;
|
||||||
|
|
||||||
|
static EventDelegateChooserAttachedType *qmlAttachedProperties(QObject *object)
|
||||||
|
{
|
||||||
|
return new EventDelegateChooserAttachedType(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updatePolish() override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void mainChanged();
|
void mainChanged();
|
||||||
void replyChanged();
|
void replyChanged();
|
||||||
void roomChanged();
|
void roomChanged();
|
||||||
void eventIdChanged();
|
void eventIdChanged();
|
||||||
void replyToChanged();
|
void replyToChanged();
|
||||||
|
void sameWidthChanged();
|
||||||
|
void maxWidthChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct DelegateIncubator final : public QQmlIncubator
|
struct DelegateIncubator final : public QQmlIncubator
|
||||||
|
@ -142,6 +192,8 @@ private:
|
||||||
TimelineModel *room_{nullptr};
|
TimelineModel *room_{nullptr};
|
||||||
QString eventId_;
|
QString eventId_;
|
||||||
QString replyId;
|
QString replyId;
|
||||||
|
bool sameWidth_ = false;
|
||||||
|
int maxWidth_ = 400;
|
||||||
|
|
||||||
static void appendChoice(QQmlListProperty<EventDelegateChoice> *, EventDelegateChoice *);
|
static void appendChoice(QQmlListProperty<EventDelegateChoice> *, EventDelegateChoice *);
|
||||||
static qsizetype choiceCount(QQmlListProperty<EventDelegateChoice> *);
|
static qsizetype choiceCount(QQmlListProperty<EventDelegateChoice> *);
|
||||||
|
|
|
@ -601,12 +601,8 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
|
||||||
case UserName:
|
case UserName:
|
||||||
return QVariant(displayName(QString::fromStdString(acc::sender(event))));
|
return QVariant(displayName(QString::fromStdString(acc::sender(event))));
|
||||||
case UserPowerlevel: {
|
case UserPowerlevel: {
|
||||||
return static_cast<qlonglong>(mtx::events::state::PowerLevels{
|
return static_cast<qlonglong>(
|
||||||
cache::client()
|
permissions_.powerlevelEvent().user_level(acc::sender(event)));
|
||||||
->getStateEvent<mtx::events::state::PowerLevels>(room_id_.toStdString())
|
|
||||||
.value_or(mtx::events::StateEvent<mtx::events::state::PowerLevels>{})
|
|
||||||
.content}
|
|
||||||
.user_level(acc::sender(event)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case Day: {
|
case Day: {
|
||||||
|
|
Loading…
Reference in a new issue