mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 19:08:58 +03:00
Fix crash with ScrollView
This commit is contained in:
parent
551515860e
commit
07e71e6eae
6 changed files with 78 additions and 45 deletions
|
@ -8,7 +8,7 @@ import im.nheko 1.0
|
||||||
Rectangle {
|
Rectangle {
|
||||||
color: colors.window
|
color: colors.window
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: textInput.height
|
Layout.preferredHeight: textInput.height + 16
|
||||||
Layout.minimumHeight: 40
|
Layout.minimumHeight: 40
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
@ -23,6 +23,7 @@ Rectangle {
|
||||||
id: inputBar
|
id: inputBar
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
anchors.margins: 8
|
||||||
spacing: 16
|
spacing: 16
|
||||||
|
|
||||||
ImageButton {
|
ImageButton {
|
||||||
|
@ -35,9 +36,7 @@ Rectangle {
|
||||||
image: CallManager.isOnCall ? ":/icons/icons/ui/end-call.png" : ":/icons/icons/ui/place-call.png"
|
image: CallManager.isOnCall ? ":/icons/icons/ui/end-call.png" : ":/icons/icons/ui/place-call.png"
|
||||||
ToolTip.visible: hovered
|
ToolTip.visible: hovered
|
||||||
ToolTip.text: CallManager.isOnCall ? qsTr("Hang up") : qsTr("Place a call")
|
ToolTip.text: CallManager.isOnCall ? qsTr("Hang up") : qsTr("Place a call")
|
||||||
Layout.topMargin: 8
|
Layout.leftMargin: 8
|
||||||
Layout.bottomMargin: 8
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (TimelineManager.timeline) {
|
if (TimelineManager.timeline) {
|
||||||
if (CallManager.haveCallInvite) {
|
if (CallManager.haveCallInvite) {
|
||||||
|
@ -59,9 +58,7 @@ Rectangle {
|
||||||
width: 22
|
width: 22
|
||||||
height: 22
|
height: 22
|
||||||
image: ":/icons/icons/ui/paper-clip-outline.png"
|
image: ":/icons/icons/ui/paper-clip-outline.png"
|
||||||
Layout.topMargin: 8
|
Layout.leftMargin: CallManager.callsSupported ? 0 : 8
|
||||||
Layout.bottomMargin: 8
|
|
||||||
Layout.leftMargin: CallManager.callsSupported ? 0 : 16
|
|
||||||
onClicked: TimelineManager.timeline.input.openFileSelection()
|
onClicked: TimelineManager.timeline.input.openFileSelection()
|
||||||
ToolTip.visible: hovered
|
ToolTip.visible: hovered
|
||||||
ToolTip.text: qsTr("Send a file")
|
ToolTip.text: qsTr("Send a file")
|
||||||
|
@ -80,12 +77,30 @@ Rectangle {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollView {
|
Flickable {
|
||||||
id: textInput
|
id: textInput
|
||||||
|
|
||||||
|
function ensureVisible(r) {
|
||||||
|
if (contentX >= r.x)
|
||||||
|
contentX = r.x;
|
||||||
|
else if (contentX + width <= r.x + r.width)
|
||||||
|
contentX = r.x + r.width - width;
|
||||||
|
if (contentY >= r.y)
|
||||||
|
contentY = r.y;
|
||||||
|
else if (contentY + height <= r.y + r.height)
|
||||||
|
contentY = r.y + r.height - height;
|
||||||
|
}
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignBottom
|
Layout.alignment: Qt.AlignBottom
|
||||||
Layout.maximumHeight: Window.height / 4
|
Layout.maximumHeight: Window.height / 4
|
||||||
|
Layout.minimumHeight: Settings.fontSize
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
clip: true
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
implicitWidth: textArea.width
|
||||||
|
implicitHeight: textArea.height
|
||||||
|
contentWidth: textArea.width
|
||||||
|
contentHeight: textArea.height
|
||||||
|
|
||||||
TextArea {
|
TextArea {
|
||||||
id: textArea
|
id: textArea
|
||||||
|
@ -104,13 +119,17 @@ Rectangle {
|
||||||
popup.completer.setSearchString(textArea.getText(completerTriggeredAt, cursorPosition));
|
popup.completer.setSearchString(textArea.getText(completerTriggeredAt, cursorPosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
text: "asfkajsdf"
|
||||||
selectByMouse: true
|
selectByMouse: true
|
||||||
placeholderText: qsTr("Write a message...")
|
placeholderText: qsTr("Write a message...")
|
||||||
placeholderTextColor: colors.buttonText
|
placeholderTextColor: colors.buttonText
|
||||||
color: colors.text
|
color: colors.text
|
||||||
|
width: textInput.width
|
||||||
wrapMode: TextEdit.Wrap
|
wrapMode: TextEdit.Wrap
|
||||||
|
padding: 0
|
||||||
focus: true
|
focus: true
|
||||||
onTextChanged: TimelineManager.timeline.input.updateState(selectionStart, selectionEnd, cursorPosition, text)
|
onTextChanged: TimelineManager.timeline.input.updateState(selectionStart, selectionEnd, cursorPosition, text)
|
||||||
|
onCursorRectangleChanged: textInput.ensureVisible(cursorRectangle)
|
||||||
onCursorPositionChanged: {
|
onCursorPositionChanged: {
|
||||||
TimelineManager.timeline.input.updateState(selectionStart, selectionEnd, cursorPosition, text);
|
TimelineManager.timeline.input.updateState(selectionStart, selectionEnd, cursorPosition, text);
|
||||||
if (cursorPosition <= completerTriggeredAt) {
|
if (cursorPosition <= completerTriggeredAt) {
|
||||||
|
@ -189,6 +208,7 @@ Rectangle {
|
||||||
popup.down();
|
popup.down();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
background: null
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
onTimelineChanged: {
|
onTimelineChanged: {
|
||||||
|
@ -230,10 +250,9 @@ Rectangle {
|
||||||
roomid: TimelineManager.timeline.roomId()
|
roomid: TimelineManager.timeline.roomId()
|
||||||
}
|
}
|
||||||
|
|
||||||
background: Rectangle {
|
}
|
||||||
color: colors.window
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ScrollBar.vertical: ScrollBar {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -246,8 +265,6 @@ Rectangle {
|
||||||
width: 22
|
width: 22
|
||||||
height: 22
|
height: 22
|
||||||
image: ":/icons/icons/ui/smile.png"
|
image: ":/icons/icons/ui/smile.png"
|
||||||
Layout.topMargin: 8
|
|
||||||
Layout.bottomMargin: 8
|
|
||||||
ToolTip.visible: hovered
|
ToolTip.visible: hovered
|
||||||
ToolTip.text: qsTr("Emoji")
|
ToolTip.text: qsTr("Emoji")
|
||||||
onClicked: emojiPopup.visible ? emojiPopup.close() : emojiPopup.show(emojiButton, function(emoji) {
|
onClicked: emojiPopup.visible ? emojiPopup.close() : emojiPopup.show(emojiButton, function(emoji) {
|
||||||
|
@ -261,9 +278,7 @@ Rectangle {
|
||||||
width: 22
|
width: 22
|
||||||
height: 22
|
height: 22
|
||||||
image: ":/icons/icons/ui/cursor.png"
|
image: ":/icons/icons/ui/cursor.png"
|
||||||
Layout.topMargin: 8
|
Layout.rightMargin: 8
|
||||||
Layout.bottomMargin: 8
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
ToolTip.visible: hovered
|
ToolTip.visible: hovered
|
||||||
ToolTip.text: qsTr("Send")
|
ToolTip.text: qsTr("Send")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
|
|
@ -20,9 +20,10 @@ ListView {
|
||||||
spacing: 4
|
spacing: 4
|
||||||
verticalLayoutDirection: ListView.BottomToTop
|
verticalLayoutDirection: ListView.BottomToTop
|
||||||
onCountChanged: {
|
onCountChanged: {
|
||||||
// Mark timeline as read
|
// Mark timeline as read
|
||||||
if (atYEnd)
|
if (atYEnd)
|
||||||
model.currentIndex = 0;
|
model.currentIndex = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollHelper {
|
ScrollHelper {
|
||||||
|
|
|
@ -57,6 +57,7 @@ Page {
|
||||||
|
|
||||||
CallInvite {
|
CallInvite {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu {
|
Menu {
|
||||||
|
@ -202,6 +203,7 @@ Page {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: msgView
|
id: msgView
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
color: colors.base
|
color: colors.base
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
import QtQuick 2.10
|
import QtQuick 2.10
|
||||||
import QtQuick.Controls 2.3
|
import QtQuick.Controls 2.3
|
||||||
import QtGraphicalEffects 1.0
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: ripple
|
id: ripple
|
||||||
|
|
|
@ -6,12 +6,12 @@ import im.nheko 1.0
|
||||||
Popup {
|
Popup {
|
||||||
modal: true
|
modal: true
|
||||||
palette: colors
|
palette: colors
|
||||||
|
|
||||||
// only set the anchors on Qt 5.12 or higher
|
// only set the anchors on Qt 5.12 or higher
|
||||||
// see https://doc.qt.io/qt-5/qml-qtquick-controls2-popup.html#anchors.centerIn-prop
|
// see https://doc.qt.io/qt-5/qml-qtquick-controls2-popup.html#anchors.centerIn-prop
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (anchors)
|
if (anchors)
|
||||||
anchors.centerIn = parent;
|
anchors.centerIn = parent;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
|
|
@ -9,23 +9,21 @@ Popup {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height
|
height: parent.height
|
||||||
palette: colors
|
palette: colors
|
||||||
background: Rectangle {
|
|
||||||
color: colors.window
|
|
||||||
border.color: colors.windowText
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: deviceError
|
id: deviceError
|
||||||
|
|
||||||
DeviceError {
|
DeviceError {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: CallManager
|
target: CallManager
|
||||||
onNewInviteState: {
|
onNewInviteState: {
|
||||||
if (!CallManager.haveCallInvite) {
|
if (!CallManager.haveCallInvite)
|
||||||
close();
|
close();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,9 +54,10 @@ Popup {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
property string image: CallManager.isVideo ? ":/icons/icons/ui/video-call.png" : ":/icons/icons/ui/place-call.png"
|
property string image: CallManager.isVideo ? ":/icons/icons/ui/video-call.png" : ":/icons/icons/ui/place-call.png"
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
Layout.preferredWidth: msgView.height / 10
|
Layout.preferredWidth: msgView.height / 10
|
||||||
Layout.preferredHeight: msgView.height / 10
|
Layout.preferredHeight: msgView.height / 10
|
||||||
source: "image://colorimage/" + image + "?" + colors.windowText
|
source: "image://colorimage/" + image + "?" + colors.windowText
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,17 +67,18 @@ Popup {
|
||||||
font.pointSize: fontMetrics.font.pointSize * 2
|
font.pointSize: fontMetrics.font.pointSize * 2
|
||||||
color: colors.windowText
|
color: colors.windowText
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: deviceCombos
|
id: deviceCombos
|
||||||
|
|
||||||
property int imageSize: msgView.height / 20
|
property int imageSize: msgView.height / 20
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
Layout.bottomMargin: msgView.height / 25
|
Layout.bottomMargin: msgView.height / 25
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
@ -89,13 +89,14 @@ Popup {
|
||||||
|
|
||||||
ComboBox {
|
ComboBox {
|
||||||
id: micCombo
|
id: micCombo
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
model: CallManager.mics
|
model: CallManager.mics
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
||||||
visible: CallManager.isVideo && CallManager.cameras.length > 0
|
visible: CallManager.isVideo && CallManager.cameras.length > 0
|
||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
|
||||||
|
@ -107,18 +108,19 @@ Popup {
|
||||||
|
|
||||||
ComboBox {
|
ComboBox {
|
||||||
id: cameraCombo
|
id: cameraCombo
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
model: CallManager.cameras
|
model: CallManager.cameras
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: buttonLayout
|
id: buttonLayout
|
||||||
|
|
||||||
property int buttonSize: msgView.height / 8
|
property int buttonSize: msgView.height / 8
|
||||||
Layout.alignment: Qt.AlignCenter
|
|
||||||
spacing: msgView.height / 6
|
|
||||||
|
|
||||||
function validateMic() {
|
function validateMic() {
|
||||||
if (CallManager.mics.length == 0) {
|
if (CallManager.mics.length == 0) {
|
||||||
|
@ -132,51 +134,64 @@ Popup {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
spacing: msgView.height / 6
|
||||||
|
|
||||||
RoundButton {
|
RoundButton {
|
||||||
implicitWidth: buttonLayout.buttonSize
|
implicitWidth: buttonLayout.buttonSize
|
||||||
implicitHeight: buttonLayout.buttonSize
|
implicitHeight: buttonLayout.buttonSize
|
||||||
|
onClicked: {
|
||||||
|
CallManager.hangUp();
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
radius: buttonLayout.buttonSize / 2
|
radius: buttonLayout.buttonSize / 2
|
||||||
color: "#ff0000"
|
color: "#ff0000"
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem : Image {
|
contentItem: Image {
|
||||||
source: "image://colorimage/:/icons/icons/ui/end-call.png?#ffffff"
|
source: "image://colorimage/:/icons/icons/ui/end-call.png?#ffffff"
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
CallManager.hangUp();
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RoundButton {
|
RoundButton {
|
||||||
id: acceptButton
|
id: acceptButton
|
||||||
|
|
||||||
property string image: CallManager.isVideo ? ":/icons/icons/ui/video-call.png" : ":/icons/icons/ui/place-call.png"
|
property string image: CallManager.isVideo ? ":/icons/icons/ui/video-call.png" : ":/icons/icons/ui/place-call.png"
|
||||||
|
|
||||||
implicitWidth: buttonLayout.buttonSize
|
implicitWidth: buttonLayout.buttonSize
|
||||||
implicitHeight: buttonLayout.buttonSize
|
implicitHeight: buttonLayout.buttonSize
|
||||||
|
onClicked: {
|
||||||
|
if (buttonLayout.validateMic()) {
|
||||||
|
Settings.microphone = micCombo.currentText;
|
||||||
|
if (cameraCombo.visible)
|
||||||
|
Settings.camera = cameraCombo.currentText;
|
||||||
|
|
||||||
|
CallManager.acceptInvite();
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
radius: buttonLayout.buttonSize / 2
|
radius: buttonLayout.buttonSize / 2
|
||||||
color: "#00ff00"
|
color: "#00ff00"
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem : Image {
|
contentItem: Image {
|
||||||
source: "image://colorimage/" + acceptButton.image + "?#ffffff"
|
source: "image://colorimage/" + acceptButton.image + "?#ffffff"
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
if (buttonLayout.validateMic()) {
|
|
||||||
Settings.microphone = micCombo.currentText;
|
|
||||||
if (cameraCombo.visible)
|
|
||||||
Settings.camera = cameraCombo.currentText;
|
|
||||||
CallManager.acceptInvite();
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: colors.window
|
||||||
|
border.color: colors.windowText
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue