diff --git a/src/gui/Base/AutoDirectionLayout.qml b/src/gui/Base/AutoDirectionLayout.qml
index fd286cda..bc3eb140 100644
--- a/src/gui/Base/AutoDirectionLayout.qml
+++ b/src/gui/Base/AutoDirectionLayout.qml
@@ -15,6 +15,7 @@ HGridLayout {
return sum
}
+
flow:
width >= summedImplicitWidth ?
HGridLayout.LeftToRight :
diff --git a/src/gui/Base/HAvatar.qml b/src/gui/Base/HAvatar.qml
index 105930ac..bd6aded4 100644
--- a/src/gui/Base/HAvatar.qml
+++ b/src/gui/Base/HAvatar.qml
@@ -5,21 +5,6 @@ import QtQuick.Controls 2.12
Rectangle {
id: avatar
- implicitWidth: implicitHeight
- implicitHeight:
- compact ?
- theme.controls.avatar.compactSize :
- theme.controls.avatar.size
-
- radius: theme.controls.avatar.radius
-
- color: avatarImage.visible ? "transparent" : utils.hsluv(
- name ? utils.hueFrom(name) : 0,
- name ? theme.controls.avatar.background.saturation : 0,
- theme.controls.avatar.background.lightness,
- theme.controls.avatar.background.opacity
- )
-
property bool compact: false
@@ -37,6 +22,21 @@ Rectangle {
readonly property alias circleRadius: avatarImage.circleRadius
+ implicitWidth: implicitHeight
+ implicitHeight:
+ compact ?
+ theme.controls.avatar.compactSize :
+ theme.controls.avatar.size
+
+ radius: theme.controls.avatar.radius
+
+ color: avatarImage.visible ? "transparent" : utils.hsluv(
+ name ? utils.hueFrom(name) : 0,
+ name ? theme.controls.avatar.background.saturation : 0,
+ theme.controls.avatar.background.lightness,
+ theme.controls.avatar.background.opacity
+ )
+
Behavior on color { HColorAnimation {} }
HLabel {
@@ -73,13 +73,6 @@ Rectangle {
HToolTip {
id: avatarToolTip
- visible: ! avatarImage.broken &&
- avatarImage.status !== Image.Error &&
- avatarImage.width < dimension * 0.75 &&
- (toolTipSourceOverride || toolTipMxc) &&
- hoverHandler.hovered
- delay: 1000
- backgroundColor: theme.controls.avatar.hoveredImage.background
readonly property int dimension: Math.min(
mainUI.width / 1.25,
@@ -88,6 +81,14 @@ Rectangle {
background.border.width * 2,
)
+ visible: ! avatarImage.broken &&
+ avatarImage.status !== Image.Error &&
+ avatarImage.width < dimension * 0.75 &&
+ (toolTipSourceOverride || toolTipMxc) &&
+ hoverHandler.hovered
+ delay: 1000
+ backgroundColor: theme.controls.avatar.hoveredImage.background
+
contentItem: HMxcImage {
id: avatarToolTipImage
fillMode: Image.PreserveAspectCrop
diff --git a/src/gui/Base/HBottomFocusLine.qml b/src/gui/Base/HBottomFocusLine.qml
index 1184d544..e35621ee 100644
--- a/src/gui/Base/HBottomFocusLine.qml
+++ b/src/gui/Base/HBottomFocusLine.qml
@@ -6,7 +6,6 @@ import QtQuick 2.12
HRectangleBottomBorder {
id: line
-
property bool show: false
diff --git a/src/gui/Base/HBox.qml b/src/gui/Base/HBox.qml
index 9e690709..2b76d869 100644
--- a/src/gui/Base/HBox.qml
+++ b/src/gui/Base/HBox.qml
@@ -12,7 +12,6 @@ HFlickableColumnPage {
radius: theme.controls.box.radius
}
-
HNumberAnimation on scale {
running: true
from: 0
diff --git a/src/gui/Base/HBusyIndicator.qml b/src/gui/Base/HBusyIndicator.qml
index 3fe4f063..5a982ee6 100644
--- a/src/gui/Base/HBusyIndicator.qml
+++ b/src/gui/Base/HBusyIndicator.qml
@@ -9,7 +9,6 @@ HCircleProgressBar {
baseCircle.strokeWidth: 2
progressCircle.strokeWidth: 2
-
HNumberAnimation on rotation {
from: 0
to: 360
diff --git a/src/gui/Base/HButton.qml b/src/gui/Base/HButton.qml
index 11d89fc0..0462f3ad 100644
--- a/src/gui/Base/HButton.qml
+++ b/src/gui/Base/HButton.qml
@@ -6,6 +6,28 @@ import QtQuick.Layouts 1.12
Button {
id: button
+
+ readonly property alias iconItem: contentItem.icon
+ readonly property alias label: contentItem.label
+
+ property color backgroundColor: theme.controls.button.background
+ property color focusLineColor:
+ Qt.colorEqual(icon.color, theme.icons.colorize) ?
+ theme.controls.button.focusedBorder :
+ icon.color
+
+ property bool disableWhileLoading: true
+ property bool loading: false
+ property bool circle: false
+ property bool padded: true
+ property bool enableRadius: false
+
+ property HToolTip toolTip: HToolTip {
+ id: toolTip
+ visible: text && hovered
+ }
+
+
enabled: ! button.loading
spacing: theme.spacing
topPadding: padded ? spacing * (circle ? 1 : 0.5) : 0
@@ -45,28 +67,6 @@ Button {
Keys.onEnterPressed: Keys.onReturnPressed(event)
activeFocusOnTab: true
-
- readonly property alias iconItem: contentItem.icon
- readonly property alias label: contentItem.label
-
- property color backgroundColor: theme.controls.button.background
- property color focusLineColor:
- Qt.colorEqual(icon.color, theme.icons.colorize) ?
- theme.controls.button.focusedBorder :
- icon.color
-
- property bool disableWhileLoading: true
- property bool loading: false
- property bool circle: false
- property bool padded: true
- property bool enableRadius: false
-
- property HToolTip toolTip: HToolTip {
- id: toolTip
- visible: text && hovered
- }
-
-
Binding on enabled {
when: disableWhileLoading && button.loading
value: false
diff --git a/src/gui/Base/HButtonBackground.qml b/src/gui/Base/HButtonBackground.qml
index 2103647f..42cc5d0f 100644
--- a/src/gui/Base/HButtonBackground.qml
+++ b/src/gui/Base/HButtonBackground.qml
@@ -15,7 +15,6 @@ Rectangle {
enabled ? 1 :
theme.disabledElementsOpacity
-
Behavior on opacity { HNumberAnimation {} }
Rectangle {
diff --git a/src/gui/Base/HButtonContent.qml b/src/gui/Base/HButtonContent.qml
index 363f71f5..7509c231 100644
--- a/src/gui/Base/HButtonContent.qml
+++ b/src/gui/Base/HButtonContent.qml
@@ -6,10 +6,6 @@ import QtQuick.Layouts 1.12
HRowLayout {
id: buttonContent
- spacing: button.spacing
- opacity: button.loading ? theme.loadingElementsOpacity :
- enabled ? 1 : theme.disabledElementsOpacity
-
property var button
property QtObject buttonTheme
@@ -18,8 +14,11 @@ HRowLayout {
readonly property alias label: label
- Behavior on opacity { HNumberAnimation {} }
+ spacing: button.spacing
+ opacity: button.loading ? theme.loadingElementsOpacity :
+ enabled ? 1 : theme.disabledElementsOpacity
+ Behavior on opacity { HNumberAnimation {} }
Item {
visible: button.icon.name || button.loading
diff --git a/src/gui/Base/HCheckBox.qml b/src/gui/Base/HCheckBox.qml
index 1b307c45..a13fb8b4 100644
--- a/src/gui/Base/HCheckBox.qml
+++ b/src/gui/Base/HCheckBox.qml
@@ -6,6 +6,15 @@ import QtQuick.Layouts 1.12
CheckBox {
id: box
+
+ property alias mainText: mainText
+ property alias subtitle: subtitleText
+ property bool defaultChecked: false
+ readonly property bool changed: checked !== defaultChecked
+
+ function reset() { checked = defaultChecked }
+
+
checked: defaultChecked
spacing: contentItem.visible ? theme.spacing : 0
padding: 0
@@ -83,15 +92,5 @@ CheckBox {
}
}
-
- property alias mainText: mainText
- property alias subtitle: subtitleText
- property bool defaultChecked: false
- readonly property bool changed: checked !== defaultChecked
-
-
- function reset() { checked = defaultChecked }
-
-
Behavior on opacity { HNumberAnimation { factor: 2 } }
}
diff --git a/src/gui/Base/HCircleProgressBar.qml b/src/gui/Base/HCircleProgressBar.qml
index 290be8e3..771c5f18 100644
--- a/src/gui/Base/HCircleProgressBar.qml
+++ b/src/gui/Base/HCircleProgressBar.qml
@@ -5,14 +5,6 @@ import QtQuick.Shapes 1.12
Item {
- implicitWidth: 96 * (theme ? theme.uiScale : 1)
- implicitHeight: implicitWidth
-
- layer.enabled: true
- layer.samples: 4
- layer.smooth: true
-
-
property real progress: 0 // 0-1
readonly property alias baseCircle: baseCircle
@@ -20,14 +12,22 @@ Item {
readonly property alias label: label
+ implicitWidth: 96 * (theme ? theme.uiScale : 1)
+ implicitHeight: implicitWidth
+
+ layer.enabled: true
+ layer.samples: 4
+ layer.smooth: true
+
HLabel {
id: label
+
+ property int progressNumber: Math.floor(progress * 100)
+
anchors.centerIn: parent
text: progressNumber + "%"
font.pixelSize: theme ? theme.fontSize.big : 22
- property int progressNumber: Math.floor(progress * 100)
-
Behavior on progressNumber { HNumberAnimation { factor: 2 } }
}
diff --git a/src/gui/Base/HColorAnimation.qml b/src/gui/Base/HColorAnimation.qml
index c5cc8790..7db135d6 100644
--- a/src/gui/Base/HColorAnimation.qml
+++ b/src/gui/Base/HColorAnimation.qml
@@ -4,5 +4,7 @@ import QtQuick 2.12
ColorAnimation {
property real factor: 1.0
+
+
duration: theme.animationDuration * factor
}
diff --git a/src/gui/Base/HColumnPage.qml b/src/gui/Base/HColumnPage.qml
index 9903acb8..73ceca19 100644
--- a/src/gui/Base/HColumnPage.qml
+++ b/src/gui/Base/HColumnPage.qml
@@ -5,15 +5,14 @@ import QtQuick 2.12
HPage {
id: page
-
default property alias columnData: column.data
+
property alias column: column
implicitWidth: theme.controls.box.defaultWidth
contentHeight: column.childrenRect.height
-
HColumnLayout {
id: column
anchors.fill: parent
diff --git a/src/gui/Base/HDrawer.qml b/src/gui/Base/HDrawer.qml
index b9ee0a8e..8a562bf8 100644
--- a/src/gui/Base/HDrawer.qml
+++ b/src/gui/Base/HDrawer.qml
@@ -5,29 +5,6 @@ import QtQuick.Controls 2.12
Drawer {
id: drawer
- implicitWidth: horizontal ? calculatedSize : parent.width
- implicitHeight: vertical ? calculatedSize : parent.height
-
- // Prevents this: open a popup, make the window small enough for the
- // drawer to collapse, then make it big again → popup is now behind drawer
- z: -1
-
- topPadding: 0
- bottomPadding: 0
- leftPadding: 0
- rightPadding: 0
-
- // FIXME: https://bugreports.qt.io/browse/QTBUG-59141
- // dragMargin: parent.width / 2
-
- interactive: collapse
- position: 1
- visible: ! collapse
- modal: false
- closePolicy: Popup.NoAutoClose
-
- background: Rectangle { id: bg; color: theme.colors.strongBackground }
-
property string saveName: ""
property var saveId: "ALL"
@@ -77,6 +54,29 @@ Drawer {
readonly property bool vertical: ! horizontal
+ implicitWidth: horizontal ? calculatedSize : parent.width
+ implicitHeight: vertical ? calculatedSize : parent.height
+
+ // Prevents this: open a popup, make the window small enough for the
+ // drawer to collapse, then make it big again → popup is now behind drawer
+ z: -1
+
+ topPadding: 0
+ bottomPadding: 0
+ leftPadding: 0
+ rightPadding: 0
+
+ // FIXME: https://bugreports.qt.io/browse/QTBUG-59141
+ // dragMargin: parent.width / 2
+
+ interactive: collapse
+ position: 1
+ visible: ! collapse
+ modal: false
+ closePolicy: Popup.NoAutoClose
+
+ background: Rectangle { id: bg; color: theme.colors.strongBackground }
+
Behavior on width {
enabled: horizontal && ! resizeMouseHandler.drag.active
NumberAnimation { duration: 100 }
@@ -97,6 +97,12 @@ Drawer {
MouseArea {
id: resizeMouseHandler
+
+ function snapSize(num) {
+ return num < snapAt + snapZone && num > snapAt - snapZone ?
+ snapAt : num
+ }
+
anchors.fill: parent
enabled: ! drawer.collapse
acceptedButtons: Qt.LeftButton
@@ -124,11 +130,6 @@ Drawer {
}
onReleased: window.saveState(drawer)
-
- function snapSize(num) {
- return num < snapAt + snapZone && num > snapAt - snapZone ?
- snapAt : num
- }
}
}
}
diff --git a/src/gui/Base/HFlickableColumnPage.qml b/src/gui/Base/HFlickableColumnPage.qml
index 45234bc9..3730c02f 100644
--- a/src/gui/Base/HFlickableColumnPage.qml
+++ b/src/gui/Base/HFlickableColumnPage.qml
@@ -6,12 +6,9 @@ import "../ShortcutBundles"
HPage {
id: page
- implicitWidth: theme.controls.box.defaultWidth
- contentHeight:
- flickable.contentHeight + flickable.topMargin + flickable.bottomMargin
-
default property alias columnData: column.data
+
property alias column: column
property alias flickable: flickable
property alias flickShortcuts: flickShortcuts
@@ -20,8 +17,11 @@ HPage {
SwipeView ? SwipeView.isCurrentItem : true
- padding: 0
+ implicitWidth: theme.controls.box.defaultWidth
+ contentHeight:
+ flickable.contentHeight + flickable.topMargin + flickable.bottomMargin
+ padding: 0
HFlickable {
id: flickable
diff --git a/src/gui/Base/HGridView.qml b/src/gui/Base/HGridView.qml
index a7adf366..a915734a 100644
--- a/src/gui/Base/HGridView.qml
+++ b/src/gui/Base/HGridView.qml
@@ -5,58 +5,6 @@ import QtQuick.Controls 2.12
GridView {
id: gridView
- currentIndex: -1
- keyNavigationWraps: true
- highlightMoveDuration: theme.animationDuration
-
- // Keep highlighted delegate at the center
- highlightRangeMode: GridView.ApplyRange
- preferredHighlightBegin: height / 2 - currentItemHeight / 2
- preferredHighlightEnd: height / 2 + currentItemHeight / 2
-
- maximumFlickVelocity: window.settings.kineticScrollingMaxSpeed
-
-
- highlight: Rectangle {
- color: theme.controls.gridView.highlight
- }
-
- ScrollBar.vertical: HScrollBar {
- visible: gridView.interactive
- }
-
- // property bool debug: false
-
- // https://doc.qt.io/qt-5/qml-qtquick-viewtransition.html
- // #handling-interrupted-animations
- add: Transition {
- // ScriptAction { script: if (gridView.debug) print("add") }
- HNumberAnimation { property: "opacity"; from: 0; to: 1 }
- HNumberAnimation { property: "scale"; from: 0; to: 1 }
- }
-
- move: Transition {
- // ScriptAction { script: if (gridView.debug) print("move") }
- HNumberAnimation { property: "opacity"; to: 1 }
- HNumberAnimation { property: "scale"; to: 1 }
- HNumberAnimation { properties: "x,y" }
- }
-
- remove: Transition {
- // ScriptAction { script: if (gridView.debug) print("remove") }
- HNumberAnimation { property: "opacity"; to: 0 }
- HNumberAnimation { property: "scale"; to: 0 }
- }
-
- displaced: Transition {
- // ScriptAction { script: if (gridView.debug) print("displaced") }
- HNumberAnimation { property: "opacity"; to: 1 }
- HNumberAnimation { property: "scale"; to: 1 }
- HNumberAnimation { properties: "x,y" }
- }
-
- onSelectedCountChanged: if (! selectedCount) lastCheckedDelegateIndex = 0
-
property alias cursorShape: mouseArea.cursorShape
property int currentItemHeight: currentItem ? currentItem.height : 0
@@ -117,6 +65,58 @@ GridView {
}
+ currentIndex: -1
+ keyNavigationWraps: true
+ highlightMoveDuration: theme.animationDuration
+
+ // Keep highlighted delegate at the center
+ highlightRangeMode: GridView.ApplyRange
+ preferredHighlightBegin: height / 2 - currentItemHeight / 2
+ preferredHighlightEnd: height / 2 + currentItemHeight / 2
+
+ maximumFlickVelocity: window.settings.kineticScrollingMaxSpeed
+
+
+ highlight: Rectangle {
+ color: theme.controls.gridView.highlight
+ }
+
+ ScrollBar.vertical: HScrollBar {
+ visible: gridView.interactive
+ }
+
+ // property bool debug: false
+
+ // https://doc.qt.io/qt-5/qml-qtquick-viewtransition.html
+ // #handling-interrupted-animations
+ add: Transition {
+ // ScriptAction { script: if (gridView.debug) print("add") }
+ HNumberAnimation { property: "opacity"; from: 0; to: 1 }
+ HNumberAnimation { property: "scale"; from: 0; to: 1 }
+ }
+
+ move: Transition {
+ // ScriptAction { script: if (gridView.debug) print("move") }
+ HNumberAnimation { property: "opacity"; to: 1 }
+ HNumberAnimation { property: "scale"; to: 1 }
+ HNumberAnimation { properties: "x,y" }
+ }
+
+ remove: Transition {
+ // ScriptAction { script: if (gridView.debug) print("remove") }
+ HNumberAnimation { property: "opacity"; to: 0 }
+ HNumberAnimation { property: "scale"; to: 0 }
+ }
+
+ displaced: Transition {
+ // ScriptAction { script: if (gridView.debug) print("displaced") }
+ HNumberAnimation { property: "opacity"; to: 1 }
+ HNumberAnimation { property: "scale"; to: 1 }
+ HNumberAnimation { properties: "x,y" }
+ }
+
+ onSelectedCountChanged: if (! selectedCount) lastCheckedDelegateIndex = 0
+
HKineticScrollingDisabler {
id: mouseArea
width: enabled ? parent.width : 0
diff --git a/src/gui/Base/HIcon.qml b/src/gui/Base/HIcon.qml
index 9796bbc5..a73bde9c 100644
--- a/src/gui/Base/HIcon.qml
+++ b/src/gui/Base/HIcon.qml
@@ -5,15 +5,6 @@ import QtGraphicalEffects 1.12
Image {
id: icon
- cache: true
- asynchronous: true
- fillMode: Image.PreserveAspectFit
- visible: Boolean(svgName)
-
- source: svgName ? `../../icons/${iconPack}/${svgName}.svg` : ""
- sourceSize.width: svgName ? dimension : 0
- sourceSize.height: svgName ? dimension : 0
-
property string svgName: ""
@@ -27,6 +18,15 @@ Image {
property string iconPack: theme ? theme.icons.preferredPack : "thin"
+ cache: true
+ asynchronous: true
+ fillMode: Image.PreserveAspectFit
+ visible: Boolean(svgName)
+ source: svgName ? `../../icons/${iconPack}/${svgName}.svg` : ""
+
+ sourceSize.width: svgName ? dimension : 0
+ sourceSize.height: svgName ? dimension : 0
+
layer.enabled: ! Qt.colorEqual(colorize, "transparent")
layer.effect: ColorOverlay {
color: icon.colorize
diff --git a/src/gui/Base/HImage.qml b/src/gui/Base/HImage.qml
index 8f262baa..48b43e4b 100644
--- a/src/gui/Base/HImage.qml
+++ b/src/gui/Base/HImage.qml
@@ -5,16 +5,6 @@ import QtGraphicalEffects 1.12
Image {
id: image
- autoTransform: true
- asynchronous: true
- fillMode: Image.PreserveAspectFit
-
- cache: ! (animate && animated) &&
- (sourceSize.width + sourceSize.height) <= 512
-
- layer.enabled: radius !== 0
- layer.effect: OpacityMask { maskSource: roundMask }
-
property bool circle: radius === circleRadius
property bool broken: false
@@ -31,11 +21,24 @@ Image {
Math.ceil(Math.max(image.width, image.height))
+ autoTransform: true
+ asynchronous: true
+ fillMode: Image.PreserveAspectFit
+
+ cache: ! (animate && animated) &&
+ (sourceSize.width + sourceSize.height) <= 512
+
+ layer.enabled: radius !== 0
+ layer.effect: OpacityMask { maskSource: roundMask }
+
Component {
id: animatedImageComponent
AnimatedImage {
id: animatedImage
+
+ property bool userPaused: ! window.settings.media.autoPlayGIF
+
source: image.source
autoTransform: image.autoTransform
asynchronous: image.asynchronous
@@ -46,6 +49,14 @@ Image {
horizontalAlignment: image.horizontalAlignment
verticalAlignment: image.verticalAlignment
+ // Online GIFs won't be able to loop if cache is set to false,
+ // but caching GIFs is expansive.
+ cache: ! Qt.resolvedUrl(source).startsWith("file://")
+ paused: ! visible || window.hidden || userPaused
+
+ layer.enabled: image.radius !== 0
+ layer.effect: OpacityMask { maskSource: roundMask }
+
// Hack to make the non-animated image behind this one
// basically invisible
Binding {
@@ -64,16 +75,6 @@ Image {
value: 1
}
- // Online GIFs won't be able to loop if cache is set to false,
- // but caching GIFs is expansive.
- cache: ! Qt.resolvedUrl(source).startsWith("file://")
- paused: ! visible || window.hidden || userPaused
-
- layer.enabled: image.radius !== 0
- layer.effect: OpacityMask { maskSource: roundMask }
-
- property bool userPaused: ! window.settings.media.autoPlayGIF
-
TapHandler {
enabled: image.enabledAnimatedPausing
onTapped: parent.userPaused = ! parent.userPaused
diff --git a/src/gui/Base/HKineticScrollingDisabler.qml b/src/gui/Base/HKineticScrollingDisabler.qml
index 84b23acc..7352104f 100644
--- a/src/gui/Base/HKineticScrollingDisabler.qml
+++ b/src/gui/Base/HKineticScrollingDisabler.qml
@@ -4,27 +4,12 @@ import QtQuick 2.12
MouseArea {
id: mouseArea
- enabled: ! window.settings.enableKineticScrolling
- propagateComposedEvents: true
- acceptedButtons: Qt.NoButton
-
-
- onWheel: {
- // Make components below the stack notice the wheel event
- wheel.accepted = false
-
- const pos = getNewPosition(flickable, wheel)
- flickable.flick(0, 0)
- flickable.contentY = pos
- }
-
property Flickable flickable: parent
// Used to get default flickDeceleration value
readonly property Flickable dummy: Flickable {}
-
function getNewPosition(flickable, wheel) {
// wheel.pixelDelta will be available on high resolution trackpads.
// Otherwise use wheel.angleDelta, which is available from mouses and
@@ -53,6 +38,19 @@ MouseArea {
}
+ enabled: ! window.settings.enableKineticScrolling
+ propagateComposedEvents: true
+ acceptedButtons: Qt.NoButton
+
+ onWheel: {
+ // Make components below the stack notice the wheel event
+ wheel.accepted = false
+
+ const pos = getNewPosition(flickable, wheel)
+ flickable.flick(0, 0)
+ flickable.contentY = pos
+ }
+
Binding {
target: flickable
property: "maximumFlickVelocity"
diff --git a/src/gui/Base/HLabeledItem.qml b/src/gui/Base/HLabeledItem.qml
index b36968d5..17565614 100644
--- a/src/gui/Base/HLabeledItem.qml
+++ b/src/gui/Base/HLabeledItem.qml
@@ -4,9 +4,6 @@ import QtQuick 2.12
import QtQuick.Layouts 1.12
HColumnLayout {
- spacing: theme.spacing / 2
-
-
default property alias insideData: itemHolder.data
property bool loading: false
@@ -17,6 +14,8 @@ HColumnLayout {
readonly property alias toolTip: toolTip
+ spacing: theme.spacing / 2
+
HRowLayout {
spacing: theme.spacing
diff --git a/src/gui/Base/HListView.qml b/src/gui/Base/HListView.qml
index c838d490..dcac8449 100644
--- a/src/gui/Base/HListView.qml
+++ b/src/gui/Base/HListView.qml
@@ -5,59 +5,6 @@ import QtQuick.Controls 2.12
ListView {
id: listView
- currentIndex: -1
- keyNavigationWraps: true
- highlightMoveDuration: theme.animationDuration
- highlightResizeDuration: theme.animationDuration
-
- // Keep highlighted delegate at the center
- highlightRangeMode: ListView.ApplyRange
- preferredHighlightBegin: height / 2 - currentItemHeight / 2
- preferredHighlightEnd: height / 2 + currentItemHeight / 2
-
- maximumFlickVelocity: window.settings.kineticScrollingMaxSpeed
-
-
- highlight: Rectangle {
- color: theme.controls.listView.highlight
- }
-
- ScrollBar.vertical: HScrollBar {
- visible: listView.interactive
- }
-
- // property bool debug: false
-
- // https://doc.qt.io/qt-5/qml-qtquick-viewtransition.html
- // #handling-interrupted-animations
- add: Transition {
- // ScriptAction { script: if (listView.debug) print("add") }
- HNumberAnimation { property: "opacity"; from: 0; to: 1 }
- HNumberAnimation { property: "scale"; from: 0; to: 1 }
- }
-
- move: Transition {
- // ScriptAction { script: if (listView.debug) print("move") }
- HNumberAnimation { property: "opacity"; to: 1 }
- HNumberAnimation { property: "scale"; to: 1 }
- HNumberAnimation { properties: "x,y" }
- }
-
- remove: Transition {
- // ScriptAction { script: if (listView.debug) print("remove") }
- HNumberAnimation { property: "opacity"; to: 0 }
- HNumberAnimation { property: "scale"; to: 0 }
- }
-
- displaced: Transition {
- // ScriptAction { script: if (listView.debug) print("displaced") }
- HNumberAnimation { property: "opacity"; to: 1 }
- HNumberAnimation { property: "scale"; to: 1 }
- HNumberAnimation { properties: "x,y" }
- }
-
- onSelectedCountChanged: if (! selectedCount) lastCheckedDelegateIndex = 0
-
property alias cursorShape: cursorShapeArea.cursorShape
property int currentItemHeight: currentItem ? currentItem.height : 0
@@ -67,7 +14,6 @@ ListView {
property int lastCheckedDelegateIndex: 0
property int selectedCount: Object.keys(checked).length
-
function check(...indices) {
for (const i of indices) {
const model = listView.model.get(i)
@@ -131,6 +77,59 @@ ListView {
}
+ currentIndex: -1
+ keyNavigationWraps: true
+ highlightMoveDuration: theme.animationDuration
+ highlightResizeDuration: theme.animationDuration
+
+ // Keep highlighted delegate at the center
+ highlightRangeMode: ListView.ApplyRange
+ preferredHighlightBegin: height / 2 - currentItemHeight / 2
+ preferredHighlightEnd: height / 2 + currentItemHeight / 2
+
+ maximumFlickVelocity: window.settings.kineticScrollingMaxSpeed
+
+
+ highlight: Rectangle {
+ color: theme.controls.listView.highlight
+ }
+
+ ScrollBar.vertical: HScrollBar {
+ visible: listView.interactive
+ }
+
+ // property bool debug: false
+
+ // https://doc.qt.io/qt-5/qml-qtquick-viewtransition.html
+ // #handling-interrupted-animations
+ add: Transition {
+ // ScriptAction { script: if (listView.debug) print("add") }
+ HNumberAnimation { property: "opacity"; from: 0; to: 1 }
+ HNumberAnimation { property: "scale"; from: 0; to: 1 }
+ }
+
+ move: Transition {
+ // ScriptAction { script: if (listView.debug) print("move") }
+ HNumberAnimation { property: "opacity"; to: 1 }
+ HNumberAnimation { property: "scale"; to: 1 }
+ HNumberAnimation { properties: "x,y" }
+ }
+
+ remove: Transition {
+ // ScriptAction { script: if (listView.debug) print("remove") }
+ HNumberAnimation { property: "opacity"; to: 0 }
+ HNumberAnimation { property: "scale"; to: 0 }
+ }
+
+ displaced: Transition {
+ // ScriptAction { script: if (listView.debug) print("displaced") }
+ HNumberAnimation { property: "opacity"; to: 1 }
+ HNumberAnimation { property: "scale"; to: 1 }
+ HNumberAnimation { properties: "x,y" }
+ }
+
+ onSelectedCountChanged: if (! selectedCount) lastCheckedDelegateIndex = 0
+
MouseArea {
id: cursorShapeArea
anchors.fill: parent
diff --git a/src/gui/Base/HMenu.qml b/src/gui/Base/HMenu.qml
index 55b5532b..d85c7770 100644
--- a/src/gui/Base/HMenu.qml
+++ b/src/gui/Base/HMenu.qml
@@ -6,6 +6,17 @@ import CppUtils 0.1
Menu {
id: menu
+
+ property var previouslyFocused: null
+
+ // MenuItems that open popups (or other elements taking focus when opened)
+ // should set this to null. It will be reset to previouslyFocus when
+ // the Menu is closed and opened again.
+ property Item focusOnClosed: previouslyFocused
+
+ readonly property string uuid: CppUtils.uuid()
+
+
modal: true
dim: false
padding: theme.controls.menu.borderWidth
@@ -48,24 +59,17 @@ Menu {
previouslyFocused = window.activeFocusItem
focusOnClosed = Qt.binding(() => previouslyFocused)
}
+
onOpened: {
window.visibleMenus[uuid] = this
window.visibleMenusChanged()
}
+
onClosed: {
if (focusOnClosed) focusOnClosed.forceActiveFocus()
delete window.visibleMenus[uuid]
window.visibleMenusChanged()
}
+
Component.onDestruction: closed()
-
-
- property var previouslyFocused: null
-
- // MenuItems that open popups (or other elements taking focus when opened)
- // should set this to null. It will be reset to previouslyFocus when
- // the Menu is closed and opened again.
- property Item focusOnClosed: previouslyFocused
-
- readonly property string uuid: CppUtils.uuid()
}
diff --git a/src/gui/Base/HMenuItem.qml b/src/gui/Base/HMenuItem.qml
index 7dfc3822..3181df09 100644
--- a/src/gui/Base/HMenuItem.qml
+++ b/src/gui/Base/HMenuItem.qml
@@ -5,6 +5,11 @@ import QtQuick.Controls 2.12
MenuItem {
id: menuItem
+
+ readonly property alias iconItem: contentItem.icon
+ readonly property alias label: contentItem.label
+
+
spacing: theme.spacing
leftPadding: spacing
rightPadding: leftPadding
@@ -27,8 +32,4 @@ MenuItem {
buttonTheme: theme.controls.menuItem
label.horizontalAlignment: Label.AlignLeft
}
-
-
- readonly property alias iconItem: contentItem.icon
- readonly property alias label: contentItem.label
}
diff --git a/src/gui/Base/HMenuItemPopupSpawner.qml b/src/gui/Base/HMenuItemPopupSpawner.qml
index bc052540..d6f466f2 100644
--- a/src/gui/Base/HMenuItemPopupSpawner.qml
+++ b/src/gui/Base/HMenuItemPopupSpawner.qml
@@ -4,6 +4,11 @@ import QtQuick 2.12
import QtQuick.Controls 2.12
HMenuItem {
+ property var popup // url or HPopup Component
+ property bool autoDestruct: true
+ property var properties: ({})
+
+
onTriggered: {
menu.focusOnClosed = null
@@ -16,9 +21,4 @@ HMenuItem {
autoDestruct,
)
}
-
-
- property var popup // url or HPopup Component
- property bool autoDestruct: true
- property var properties: ({})
}
diff --git a/src/gui/Base/HMxcImage.qml b/src/gui/Base/HMxcImage.qml
index f246e184..b28e516d 100644
--- a/src/gui/Base/HMxcImage.qml
+++ b/src/gui/Base/HMxcImage.qml
@@ -5,15 +5,6 @@ import "../PythonBridge"
HImage {
id: image
- inderterminateProgressBar: isMxc
- source: sourceOverride || (show ? cachedPath : "")
-
- onWidthChanged: Qt.callLater(update)
- onHeightChanged: Qt.callLater(update)
- onVisibleChanged: Qt.callLater(update)
- onMxcChanged: Qt.callLater(update)
- Component.onDestruction: if (getFuture) getFuture.cancel()
-
property string mxc
property string title
@@ -28,7 +19,6 @@ HImage {
readonly property bool isMxc: mxc.startsWith("mxc://")
-
function update() {
if (! py) return // component was destroyed
@@ -64,4 +54,14 @@ HImage {
},
)
}
+
+
+ inderterminateProgressBar: isMxc
+ source: sourceOverride || (show ? cachedPath : "")
+
+ onWidthChanged: Qt.callLater(update)
+ onHeightChanged: Qt.callLater(update)
+ onVisibleChanged: Qt.callLater(update)
+ onMxcChanged: Qt.callLater(update)
+ Component.onDestruction: if (getFuture) getFuture.cancel()
}
diff --git a/src/gui/Base/HNoticePage.qml b/src/gui/Base/HNoticePage.qml
index b407eda7..6b62a0b1 100644
--- a/src/gui/Base/HNoticePage.qml
+++ b/src/gui/Base/HNoticePage.qml
@@ -11,6 +11,7 @@ HRowLayout {
property alias backgroundColor: noticeLabelBackground.color
property alias radius: noticeLabelBackground.radius
+
HLabel {
id: noticeLabel
horizontalAlignment: Text.AlignHCenter
diff --git a/src/gui/Base/HNumberAnimation.qml b/src/gui/Base/HNumberAnimation.qml
index e5750df0..b444f19c 100644
--- a/src/gui/Base/HNumberAnimation.qml
+++ b/src/gui/Base/HNumberAnimation.qml
@@ -6,6 +6,7 @@ NumberAnimation {
property real factor: 1.0
property real overshoot: 1.0
+
duration: theme.animationDuration * Math.max(overshoot / 1.7, 1.0) * factor
easing.type: overshoot > 1 ? Easing.OutBack : Easing.Linear
easing.overshoot: overshoot
diff --git a/src/gui/Base/HPage.qml b/src/gui/Base/HPage.qml
index 9026957d..b8ae94af 100644
--- a/src/gui/Base/HPage.qml
+++ b/src/gui/Base/HPage.qml
@@ -4,14 +4,6 @@ import QtQuick 2.12
import QtQuick.Controls 2.12
Page {
- padding: currentSpacing < theme.spacing ? 0 : currentSpacing
- background: null
-
- Keys.onReturnPressed: keyboardAccept()
- Keys.onEnterPressed: keyboardAccept()
- Keys.onEscapePressed: keyboardCancel()
-
-
property bool useVariableSpacing: true
property int currentSpacing:
@@ -27,5 +19,12 @@ Page {
signal keyboardCancel()
+ padding: currentSpacing < theme.spacing ? 0 : currentSpacing
+ background: null
+
+ Keys.onReturnPressed: keyboardAccept()
+ Keys.onEnterPressed: keyboardAccept()
+ Keys.onEscapePressed: keyboardCancel()
+
Behavior on padding { HNumberAnimation {} }
}
diff --git a/src/gui/Base/HPopup.qml b/src/gui/Base/HPopup.qml
index 855a1a48..306f9d3e 100644
--- a/src/gui/Base/HPopup.qml
+++ b/src/gui/Base/HPopup.qml
@@ -6,6 +6,19 @@ import CppUtils 0.1
Popup {
id: popup
+
+ property var previouslyFocused: null
+ property Item focusOnClosed: previouslyFocused
+
+ readonly property int maximumPreferredWidth:
+ window.width - leftMargin - rightMargin - leftInset - rightInset
+
+ readonly property int maximumPreferredHeight:
+ window.height - topMargin - bottomMargin - topInset - bottomInset
+
+ readonly property string uuid: CppUtils.uuid()
+
+
modal: true
focus: true
padding: 0
@@ -43,17 +56,6 @@ Popup {
delete window.visiblePopups[uuid]
window.visibleMenusChanged()
}
+
Component.onDestruction: closed()
-
-
- property var previouslyFocused: null
- property Item focusOnClosed: previouslyFocused
-
- readonly property int maximumPreferredWidth:
- window.width - leftMargin - rightMargin - leftInset - rightInset
-
- readonly property int maximumPreferredHeight:
- window.height - topMargin - bottomMargin - topInset - bottomInset
-
- readonly property string uuid: CppUtils.uuid()
}
diff --git a/src/gui/Base/HProgressBar.qml b/src/gui/Base/HProgressBar.qml
index 3e41eb1f..ff98d378 100644
--- a/src/gui/Base/HProgressBar.qml
+++ b/src/gui/Base/HProgressBar.qml
@@ -9,6 +9,7 @@ ProgressBar {
property color backgroundColor: theme.controls.progressBar.background
property color foregroundColor: theme.controls.progressBar.foreground
+
background: Rectangle {
implicitWidth: 200
implicitHeight: theme.controls.progressBar.height
diff --git a/src/gui/Base/HRectangleBottomBorder.qml b/src/gui/Base/HRectangleBottomBorder.qml
index 9fcb9d06..0f45ee76 100644
--- a/src/gui/Base/HRectangleBottomBorder.qml
+++ b/src/gui/Base/HRectangleBottomBorder.qml
@@ -7,6 +7,7 @@ Item {
property alias borderHeight: clipArea.height
property alias color: borderRectangle.color
+
implicitWidth: rectangle.width
implicitHeight: rectangle.height
diff --git a/src/gui/Base/HRepeater.qml b/src/gui/Base/HRepeater.qml
index 49d63390..e59f222b 100644
--- a/src/gui/Base/HRepeater.qml
+++ b/src/gui/Base/HRepeater.qml
@@ -7,7 +7,6 @@ import QtQuick 2.12
Repeater {
id: repeater
-
readonly property var childrenImplicitWidth: {
const widths = []
diff --git a/src/gui/Base/HRoomAvatar.qml b/src/gui/Base/HRoomAvatar.qml
index d0821fe9..9efa33bf 100644
--- a/src/gui/Base/HRoomAvatar.qml
+++ b/src/gui/Base/HRoomAvatar.qml
@@ -3,13 +3,13 @@
import QtQuick 2.12
HAvatar {
+ property string roomId
+ property string displayName
+
+
name: displayName[0] === "#" && displayName.length > 1 ?
displayName.substring(1) :
displayName
title: "room_" + roomId + ".avatar"
-
-
- property string roomId
- property string displayName
}
diff --git a/src/gui/Base/HScrollBar.qml b/src/gui/Base/HScrollBar.qml
index 85d643bc..51815fd4 100644
--- a/src/gui/Base/HScrollBar.qml
+++ b/src/gui/Base/HScrollBar.qml
@@ -5,6 +5,7 @@ import QtQuick.Controls 2.12
ScrollBar {
id: scrollBar
+
minimumSize: (Math.min(height / 1.5, 48) * theme.uiScale) / height
opacity: size < 1 && (active || hovered) ? 1 : 0
padding: 0
diff --git a/src/gui/Base/HSelectableLabel.qml b/src/gui/Base/HSelectableLabel.qml
index 40c23cc8..602b18c1 100644
--- a/src/gui/Base/HSelectableLabel.qml
+++ b/src/gui/Base/HSelectableLabel.qml
@@ -5,6 +5,19 @@ import QtQuick.Controls 2.12
TextEdit {
id: label
+
+ property bool enableLinkActivation: true
+
+ function selectWordAt(position) {
+ label.cursorPosition = positionAt(position.x, position.y)
+ label.selectWord()
+ }
+
+ function selectAllText() {
+ label.selectAll()
+ }
+
+
font.family: theme.fontFamily.sans
font.pixelSize: theme.fontSize.normal
color: theme.colors.text
@@ -18,20 +31,6 @@ TextEdit {
selectByMouse: true
onLinkActivated: if (enableLinkActivation) Qt.openUrlExternally(link)
-
- property bool enableLinkActivation: true
-
-
- function selectWordAt(position) {
- label.cursorPosition = positionAt(position.x, position.y)
- label.selectWord()
- }
-
- function selectAllText() {
- label.selectAll()
- }
-
-
MouseArea {
anchors.fill: label
acceptedButtons: Qt.NoButton
diff --git a/src/gui/Base/HShortcut.qml b/src/gui/Base/HShortcut.qml
index 040db6f7..6da39fd7 100644
--- a/src/gui/Base/HShortcut.qml
+++ b/src/gui/Base/HShortcut.qml
@@ -3,10 +3,10 @@
import QtQuick 2.12
Shortcut {
- enabled: ! window.anyPopupOrMenu && active
- context: Qt.ApplicationShortcut
-
-
// TODO: use enabled + a Binding with restoreValue when switch to Qt 5.15
property bool active: true
+
+
+ enabled: ! window.anyPopupOrMenu && active
+ context: Qt.ApplicationShortcut
}
diff --git a/src/gui/Base/HSlider.qml b/src/gui/Base/HSlider.qml
index ea9d9f74..edf73717 100644
--- a/src/gui/Base/HSlider.qml
+++ b/src/gui/Base/HSlider.qml
@@ -5,10 +5,6 @@ import QtQuick.Controls 2.12
Slider {
id: slider
- leftPadding: 0
- rightPadding: leftPadding
- topPadding: 0
- bottomPadding: topPadding
property bool enableRadius: true
property bool fullHeight: false
@@ -18,6 +14,12 @@ Slider {
property alias toolTip: toolTip
property alias mouseArea: mouseArea
+
+ leftPadding: 0
+ rightPadding: leftPadding
+ topPadding: 0
+ bottomPadding: topPadding
+
background: Rectangle {
color: backgroundColor
x: slider.leftPadding
diff --git a/src/gui/Base/HSwipeView.qml b/src/gui/Base/HSwipeView.qml
index 1b80084e..f02511f6 100644
--- a/src/gui/Base/HSwipeView.qml
+++ b/src/gui/Base/HSwipeView.qml
@@ -7,21 +7,6 @@ import "../ShortcutBundles"
SwipeView {
id: swipeView
- Component.onCompleted: if (! changed) {
- setCurrentIndex(window.getState(this, "currentIndex", defaultIndex))
- saveEnabled = true
- }
-
- onCurrentIndexChanged: {
- if (saveEnabled) window.saveState(this)
-
- if (currentIndex < previousIndex) lastMove = HSwipeView.Move.ToPrevious
- if (currentIndex > previousIndex) lastMove = HSwipeView.Move.ToNext
-
- previousIndex = currentIndex
- }
-
-
enum Move { ToPrevious, ToNext }
property string saveName: ""
@@ -52,6 +37,20 @@ SwipeView {
}
+ Component.onCompleted: if (! changed) {
+ setCurrentIndex(window.getState(this, "currentIndex", defaultIndex))
+ saveEnabled = true
+ }
+
+ onCurrentIndexChanged: {
+ if (saveEnabled) window.saveState(this)
+
+ if (currentIndex < previousIndex) lastMove = HSwipeView.Move.ToPrevious
+ if (currentIndex > previousIndex) lastMove = HSwipeView.Move.ToNext
+
+ previousIndex = currentIndex
+ }
+
TabShortcuts {
container: swipeView
}
diff --git a/src/gui/Base/HTabBar.qml b/src/gui/Base/HTabBar.qml
index cb851b30..a1a75fba 100644
--- a/src/gui/Base/HTabBar.qml
+++ b/src/gui/Base/HTabBar.qml
@@ -6,6 +6,7 @@ import "../ShortcutBundles"
TabBar {
id: tabBar
+
spacing: 0
position: TabBar.Header
@@ -18,7 +19,6 @@ TabBar {
}
}
-
TabShortcuts {
container: tabBar
}
diff --git a/src/gui/Base/HTabButton.qml b/src/gui/Base/HTabButton.qml
index ab545082..63cb02c4 100644
--- a/src/gui/Base/HTabButton.qml
+++ b/src/gui/Base/HTabButton.qml
@@ -6,27 +6,6 @@ import QtQuick.Layouts 1.12
TabButton {
id: button
- spacing: theme.spacing
- topPadding: spacing / 1.5
- bottomPadding: topPadding
- leftPadding: spacing
- rightPadding: leftPadding
-
- icon.color: theme.icons.colorize
-
- implicitWidth: Math.max(
- implicitBackgroundWidth + leftInset + rightInset,
- // FIXME: why is *2 needed to not get ellided text in AddAccount page?
- implicitContentWidth + leftPadding * 2 + rightPadding * 2,
- )
- implicitHeight: Math.max(
- implicitBackgroundHeight + topInset + bottomInset,
- implicitContentHeight + topPadding + bottomPadding,
- )
-
- // Prevent button from gaining focus and being highlighted on click
- focusPolicy: Qt.TabFocus
-
readonly property alias iconItem: contentItem.icon
readonly property alias label: contentItem.label
@@ -48,6 +27,27 @@ TabButton {
}
+ spacing: theme.spacing
+ topPadding: spacing / 1.5
+ bottomPadding: topPadding
+ leftPadding: spacing
+ rightPadding: leftPadding
+
+ icon.color: theme.icons.colorize
+
+ implicitWidth: Math.max(
+ implicitBackgroundWidth + leftInset + rightInset,
+ // FIXME: why is *2 needed to not get ellided text in AddAccount page?
+ implicitContentWidth + leftPadding * 2 + rightPadding * 2,
+ )
+ implicitHeight: Math.max(
+ implicitBackgroundHeight + topInset + bottomInset,
+ implicitContentHeight + topPadding + bottomPadding,
+ )
+
+ // Prevent button from gaining focus and being highlighted on click
+ focusPolicy: Qt.TabFocus
+
background: HButtonBackground {
button: button
buttonTheme: theme.controls.tab
diff --git a/src/gui/Base/HTextArea.qml b/src/gui/Base/HTextArea.qml
index 6a172e95..daac70e1 100644
--- a/src/gui/Base/HTextArea.qml
+++ b/src/gui/Base/HTextArea.qml
@@ -6,7 +6,6 @@ import QtQuick.Controls 2.12
TextArea {
id: textArea
-
property string saveName: ""
property var saveId: "ALL"
property var saveProperties: ["text"]
@@ -27,7 +26,6 @@ TextArea {
property string previousDefaultText: "" // private
-
function reset() { clear(); text = Qt.binding(() => defaultText || "") }
function insertAtCursor(text) { insert(cursorPosition, text) }
diff --git a/src/gui/Base/HTextContextMenu.qml b/src/gui/Base/HTextContextMenu.qml
index 8d7595c3..3e378bb7 100644
--- a/src/gui/Base/HTextContextMenu.qml
+++ b/src/gui/Base/HTextContextMenu.qml
@@ -7,7 +7,6 @@ HMenu {
property bool hadPersistentSelection: false // TODO: use a Qt 5.15 Binding
-
function spawn(atMousePosition=true) {
hadPersistentSelection = control.persistentSelection
control.persistentSelection = true
@@ -25,7 +24,6 @@ HMenu {
Component.onDestruction:
control.persistentSelection = hadPersistentSelection
-
HMenuItem {
icon.name: "undo"
text: qsTr("Undo")
diff --git a/src/gui/Base/HTextField.qml b/src/gui/Base/HTextField.qml
index 8c99c1e0..5020e91b 100644
--- a/src/gui/Base/HTextField.qml
+++ b/src/gui/Base/HTextField.qml
@@ -5,6 +5,33 @@ import QtQuick.Controls 2.12
TextField {
id: field
+
+ property string saveName: ""
+ property var saveId: "ALL"
+ property var saveProperties: ["text"]
+
+ property bool error: false
+
+ property alias radius: textFieldBackground.radius
+ property bool bordered: true
+
+ property color backgroundColor: theme.controls.textField.background
+ property color borderColor: theme.controls.textField.border
+ property color errorBorder: theme.controls.textField.errorBorder
+
+ property color focusedBackgroundColor:
+ theme.controls.textField.focusedBackground
+ property color focusedBorderColor: theme.controls.textField.focusedBorder
+
+ property var disabledText: null
+ property var defaultText: null
+ readonly property bool changed: text !== (defaultText || "")
+
+ property string previousDefaultText: "" // private
+
+ function reset() { clear(); text = Qt.binding(() => defaultText || "")}
+
+
text: defaultText || ""
opacity: enabled ? 1 : theme.disabledElementsOpacity
selectByMouse: true
@@ -75,33 +102,6 @@ TextField {
event.accepted = cursorPosition === length && ! selectedText
- property string saveName: ""
- property var saveId: "ALL"
- property var saveProperties: ["text"]
-
- property bool error: false
-
- property alias radius: textFieldBackground.radius
- property bool bordered: true
-
- property color backgroundColor: theme.controls.textField.background
- property color borderColor: theme.controls.textField.border
- property color errorBorder: theme.controls.textField.errorBorder
-
- property color focusedBackgroundColor:
- theme.controls.textField.focusedBackground
- property color focusedBorderColor: theme.controls.textField.focusedBorder
-
- property var disabledText: null
- property var defaultText: null
- readonly property bool changed: text !== (defaultText || "")
-
- property string previousDefaultText: "" // private
-
-
- function reset() { clear(); text = Qt.binding(() => defaultText || "")}
-
-
Binding on color {
value: "transparent"
when: disabledText !== null && ! field.enabled
diff --git a/src/gui/Base/HTile/ContentRow.qml b/src/gui/Base/HTile/ContentRow.qml
index 08c63248..e0dea128 100644
--- a/src/gui/Base/HTile/ContentRow.qml
+++ b/src/gui/Base/HTile/ContentRow.qml
@@ -4,9 +4,9 @@ import QtQuick 2.12
import ".."
HRowLayout {
+ property HTile tile
+
+
spacing: tile.spacing
opacity: tile.contentOpacity
-
-
- property HTile tile
}
diff --git a/src/gui/Base/HTile/HTile.qml b/src/gui/Base/HTile/HTile.qml
index 04eabc4f..86c3ce4c 100644
--- a/src/gui/Base/HTile/HTile.qml
+++ b/src/gui/Base/HTile/HTile.qml
@@ -5,26 +5,15 @@ import ".."
HButton {
id: tile
- topPadding: padded ? spacing / (compact ? 4 : 2) : 0
- bottomPadding: topPadding
-
- Keys.onEnterPressed: leftClicked()
- Keys.onReturnPressed: leftClicked()
- Keys.onSpacePressed: leftClicked()
- Keys.onMenuPressed: doRightClick(false)
+ property bool compact: window.settings.compactMode
+ property real contentOpacity: 1
+ property Component contextMenu: null
signal leftClicked()
signal rightClicked()
signal longPressed()
-
- property bool compact: window.settings.compactMode
- property real contentOpacity: 1
-
- property Component contextMenu: null
-
-
function openMenu(atCursor=true) {
if (! contextMenu) return
const menu = contextMenu.createObject(tile)
@@ -38,6 +27,15 @@ HButton {
}
+ topPadding: padded ? spacing / (compact ? 4 : 2) : 0
+ bottomPadding: topPadding
+
+ Keys.onEnterPressed: leftClicked()
+ Keys.onReturnPressed: leftClicked()
+ Keys.onSpacePressed: leftClicked()
+ Keys.onMenuPressed: doRightClick(false)
+
+
Behavior on topPadding { HNumberAnimation {} }
Behavior on bottomPadding { HNumberAnimation {} }
diff --git a/src/gui/Base/HTile/SubtitleLabel.qml b/src/gui/Base/HTile/SubtitleLabel.qml
index 5cca552c..0d5af75c 100644
--- a/src/gui/Base/HTile/SubtitleLabel.qml
+++ b/src/gui/Base/HTile/SubtitleLabel.qml
@@ -7,6 +7,7 @@ import ".."
HLabel {
property HTile tile
+
textFormat: Text.StyledText
font.pixelSize: theme.fontSize.small
verticalAlignment: Qt.AlignVCenter
diff --git a/src/gui/Base/HTile/TitleRightInfoLabel.qml b/src/gui/Base/HTile/TitleRightInfoLabel.qml
index bdd1a6ca..2fb623a4 100644
--- a/src/gui/Base/HTile/TitleRightInfoLabel.qml
+++ b/src/gui/Base/HTile/TitleRightInfoLabel.qml
@@ -5,6 +5,9 @@ import QtQuick.Layouts 1.12
import ".."
HLabel {
+ property HTile tile
+
+
font.pixelSize: theme.fontSize.small
verticalAlignment: Qt.AlignVCenter
color: theme.colors.halfDimText
@@ -15,9 +18,5 @@ HLabel {
text && tile.width >= 200 * theme.uiScale ?
implicitWidth : 0
-
- property HTile tile
-
-
Behavior on Layout.maximumWidth { HNumberAnimation {} }
}
diff --git a/src/gui/Base/HToolTip.qml b/src/gui/Base/HToolTip.qml
index edc4947c..8056de3c 100644
--- a/src/gui/Base/HToolTip.qml
+++ b/src/gui/Base/HToolTip.qml
@@ -6,6 +6,23 @@ import QtQuick.Layouts 1.12
ToolTip {
id: toolTip
+
+ property bool instant: false
+
+ property alias label: label
+ property alias backgroundColor: background.color
+
+ readonly property bool hideNow: ! window.hovered
+
+
+ function instantShow() {
+ if (visible) return
+ instant = true
+ open()
+ instant = false
+ }
+
+
delay: instant ? 0 : theme.controls.toolTip.delay
padding: background.border.width
@@ -43,23 +60,6 @@ ToolTip {
onHideNowChanged: if (visible && hideNow) toolTip.hide()
-
- property bool instant: false
-
- property alias label: label
- property alias backgroundColor: background.color
-
- readonly property bool hideNow: ! window.hovered
-
-
- function instantShow() {
- if (visible) return
- instant = true
- open()
- instant = false
- }
-
-
TapHandler {
onTapped: toolTip.hide()
}
diff --git a/src/gui/Base/HUserAvatar.qml b/src/gui/Base/HUserAvatar.qml
index 8fb91f31..7f9c0ebe 100644
--- a/src/gui/Base/HUserAvatar.qml
+++ b/src/gui/Base/HUserAvatar.qml
@@ -3,10 +3,6 @@
import QtQuick 2.12
HAvatar {
- name: displayName || userId.substring(1) // no leading @
- title: "user_" + userId + ".avatar"
-
-
property string userId
property string displayName
property string presence: ""
@@ -18,6 +14,9 @@ HAvatar {
readonly property bool moderator: powerLevel >= 50 && ! admin
+ name: displayName || userId.substring(1) // no leading @
+ title: "user_" + userId + ".avatar"
+
HLoader {
active: admin || moderator || invited
anchors.top: parent.top
@@ -53,6 +52,11 @@ HAvatar {
}
HLoader {
+ property int diameter:
+ window.settings.compactMode ?
+ theme.controls.presence.radius * 2 :
+ theme.controls.presence.radius * 2.5
+
active: presence && presence !== "offline"
anchors.bottom: parent.bottom
anchors.right: parent.right
@@ -61,11 +65,6 @@ HAvatar {
opacity: theme.controls.presence.opacity
z: 300
- property int diameter:
- window.settings.compactMode ?
- theme.controls.presence.radius * 2 :
- theme.controls.presence.radius * 2.5
-
sourceComponent: Rectangle {
width: diameter
height: diameter
diff --git a/src/gui/Base/MediaPlayer/AudioPlayer.qml b/src/gui/Base/MediaPlayer/AudioPlayer.qml
index d81f18e2..2c7692ab 100644
--- a/src/gui/Base/MediaPlayer/AudioPlayer.qml
+++ b/src/gui/Base/MediaPlayer/AudioPlayer.qml
@@ -5,16 +5,16 @@ import QtAV 1.7
OSD {
id: osd
+
+ property alias source: audioPlayer.source
+
+
audioOnly: true
media: audioPlayer
implicitWidth: osd.width
implicitHeight: osd.height
-
- property alias source: audioPlayer.source
-
-
MediaPlayer {
id: audioPlayer
autoLoad: window.settings.media.autoLoad
diff --git a/src/gui/Base/MediaPlayer/OSD.qml b/src/gui/Base/MediaPlayer/OSD.qml
index baef2f90..cf015a4f 100644
--- a/src/gui/Base/MediaPlayer/OSD.qml
+++ b/src/gui/Base/MediaPlayer/OSD.qml
@@ -7,20 +7,6 @@ import "../../Base"
HColumnLayout {
id: osd
- visible: osdScaleTransform.yScale > 0
-
- transform: Scale {
- id: osdScaleTransform
- yScale: audioOnly ||
- osdHover.hovered ||
- media.playbackState !== MediaPlayer.PlayingState ||
- osd.showup ?
- 1 : 0
- origin.y: osd.height
-
- Behavior on yScale { HNumberAnimation {} }
- }
-
property QtObject media: parent // QtAV.Video or QtAV.MediaPlayer
property bool audioOnly: false
@@ -35,12 +21,6 @@ HColumnLayout {
savedDuration ?
Math.min(media.position, savedDuration) : media.position
-
- onShowupChanged: if (showup) osdHideTimer.restart()
- onDurationChanged: if (duration) savedDuration = duration
- onAspectRatioChanged: if (aspectRatio) savedAspectRatio = aspectRatio
-
-
function togglePlay() {
media.playbackState === MediaPlayer.PlayingState ?
media.pause() : media.play()
@@ -52,6 +32,24 @@ HColumnLayout {
}
+ visible: osdScaleTransform.yScale > 0
+
+ transform: Scale {
+ id: osdScaleTransform
+ yScale: audioOnly ||
+ osdHover.hovered ||
+ media.playbackState !== MediaPlayer.PlayingState ||
+ osd.showup ?
+ 1 : 0
+ origin.y: osd.height
+
+ Behavior on yScale { HNumberAnimation {} }
+ }
+
+ onShowupChanged: if (showup) osdHideTimer.restart()
+ onDurationChanged: if (duration) savedDuration = duration
+ onAspectRatioChanged: if (aspectRatio) savedAspectRatio = aspectRatio
+
HoverHandler { id: osdHover }
Timer {
@@ -77,6 +75,13 @@ HColumnLayout {
HToolTip {
id: previewToolTip
+
+ readonly property int wantTimestamp:
+ visible ?
+ savedDuration *
+ (timeSlider.mouseArea.mouseX / timeSlider.mouseArea.width) :
+ -1
+
x: timeSlider.mouseArea.mouseX - width / 2
visible: ! audioOnly &&
@@ -88,20 +93,6 @@ HColumnLayout {
! timeSlider.pressed && timeSlider.mouseArea.containsMouse
- readonly property int wantTimestamp:
- visible ?
- savedDuration *
- (timeSlider.mouseArea.mouseX / timeSlider.mouseArea.width) :
- -1
-
- Timer {
- interval: 300
- running: previewToolTip.visible
- repeat: true
- triggeredOnStart: true
- onTriggered: preview.timestamp = previewToolTip.wantTimestamp
- }
-
contentItem: VideoPreview {
id: preview
implicitHeight: Math.min(
@@ -129,11 +120,19 @@ HColumnLayout {
}
}
}
- }
- Binding on value {
- value: boundPosition
- when: ! timeSlider.pressed
+ Binding on value {
+ value: boundPosition
+ when: ! timeSlider.pressed
+ }
+
+ Timer {
+ interval: 300
+ running: previewToolTip.visible
+ repeat: true
+ triggeredOnStart: true
+ onTriggered: preview.timestamp = previewToolTip.wantTimestamp
+ }
}
}
diff --git a/src/gui/Base/MediaPlayer/OSDButton.qml b/src/gui/Base/MediaPlayer/OSDButton.qml
index 3fed282a..a3eb7f2c 100644
--- a/src/gui/Base/MediaPlayer/OSDButton.qml
+++ b/src/gui/Base/MediaPlayer/OSDButton.qml
@@ -3,7 +3,6 @@
import QtQuick 2.12
import "../../Base"
-
HButton {
backgroundColor: "transparent"
iconItem.dimension: theme.mediaPlayer.controls.iconSize
diff --git a/src/gui/Base/MediaPlayer/OSDLabel.qml b/src/gui/Base/MediaPlayer/OSDLabel.qml
index 1c847b63..2eef077f 100644
--- a/src/gui/Base/MediaPlayer/OSDLabel.qml
+++ b/src/gui/Base/MediaPlayer/OSDLabel.qml
@@ -4,7 +4,6 @@ import QtQuick 2.12
import QtQuick.Layouts 1.12
import "../../Base"
-
HLabel {
Layout.leftMargin: theme.spacing / 2
Layout.rightMargin: Layout.leftMargin
diff --git a/src/gui/Base/MultiviewPane.qml b/src/gui/Base/MultiviewPane.qml
index 3bc75ec1..f3905e87 100644
--- a/src/gui/Base/MultiviewPane.qml
+++ b/src/gui/Base/MultiviewPane.qml
@@ -6,9 +6,8 @@ import QtQuick.Layouts 1.12
HDrawer {
id: pane
- defaultSize: buttonRepeater.count * buttonWidth
- minimumSize: buttonWidth
+ default property alias swipeViewData: swipeView.contentData
property color buttonsBackgroundColor
@@ -18,8 +17,9 @@ HDrawer {
readonly property alias buttonRepeater: buttonRepeater
readonly property alias swipeView: swipeView
- default property alias swipeViewData: swipeView.contentData
+ defaultSize: buttonRepeater.count * buttonWidth
+ minimumSize: buttonWidth
HColumnLayout {
anchors.fill: parent
diff --git a/src/gui/DebugConsole.qml b/src/gui/DebugConsole.qml
index d2400a6d..3f89a316 100644
--- a/src/gui/DebugConsole.qml
+++ b/src/gui/DebugConsole.qml
@@ -8,37 +8,6 @@ import "ShortcutBundles"
HDrawer {
id: debugConsole
- objectName: "debugConsole"
- edge: Qt.TopEdge
- x: horizontal ? 0 : referenceSizeParent.width / 2 - width / 2
- y: vertical ? 0 : referenceSizeParent.height / 2 - height / 2
- width: horizontal ? calculatedSize : Math.min(window.width, 720)
- height: vertical ? calculatedSize : Math.min(window.height, 720)
- defaultSize: 400
- z: 9999
- position: 0
-
- onTargetChanged: {
- commandsView.model.insert(0, {
- input: "t = " + String(target),
- output: "",
- error: false,
- })
- }
-
- onVisibleChanged: {
- if (visible) {
- previouslyFocused = window.activeFocusItem
- forceActiveFocus()
- } else if (previouslyFocused) {
- previouslyFocused.forceActiveFocus()
- }
- }
-
- onHistoryEntryChanged:
- inputField.text =
- historyEntry === -1 ? "" : history.slice(-historyEntry - 1)[0]
-
property Item previouslyFocused: null
@@ -74,7 +43,6 @@ HDrawer {
readonly property alias commandsView: commandsView
-
function toggle(targetItem=null, js="", addToHistory=false) {
if (debugConsole.visible) {
debugConsole.visible = false
@@ -90,7 +58,6 @@ HDrawer {
if (js) debugConsole.runJS(js, addToHistory)
}
-
function runJS(input, addToHistory=true) {
if (addToHistory && history.slice(-1)[0] !== input) {
history.push(input)
@@ -135,6 +102,37 @@ HDrawer {
}
+ objectName: "debugConsole"
+ edge: Qt.TopEdge
+ x: horizontal ? 0 : referenceSizeParent.width / 2 - width / 2
+ y: vertical ? 0 : referenceSizeParent.height / 2 - height / 2
+ width: horizontal ? calculatedSize : Math.min(window.width, 720)
+ height: vertical ? calculatedSize : Math.min(window.height, 720)
+ defaultSize: 400
+ z: 9999
+ position: 0
+
+ onTargetChanged: {
+ commandsView.model.insert(0, {
+ input: "t = " + String(target),
+ output: "",
+ error: false,
+ })
+ }
+
+ onVisibleChanged: {
+ if (visible) {
+ previouslyFocused = window.activeFocusItem
+ forceActiveFocus()
+ } else if (previouslyFocused) {
+ previouslyFocused.forceActiveFocus()
+ }
+ }
+
+ onHistoryEntryChanged:
+ inputField.text =
+ historyEntry === -1 ? "" : history.slice(-historyEntry - 1)[0]
+
HShortcut {
sequences: settings.keys.toggleDebugConsole
onActivated: debugConsole.toggle()
diff --git a/src/gui/Dialogs/ExportKeys.qml b/src/gui/Dialogs/ExportKeys.qml
index a8fbeb99..a66ed74f 100644
--- a/src/gui/Dialogs/ExportKeys.qml
+++ b/src/gui/Dialogs/ExportKeys.qml
@@ -5,24 +5,13 @@ import Qt.labs.platform 1.1
import "../Popups"
HFileDialogOpener {
- fill: false
- dialog.title: qsTr("Save decryption keys file as...")
- dialog.fileMode: FileDialog.SaveFile
- onFilePicked: {
- exportPasswordPopup.file = file
- exportPasswordPopup.open()
- }
-
-
// This is used for the SignOutPopup to know when the export is done
// so it can close
signal done()
-
property string userId: ""
property bool exporting: false
-
function exportKeys(file, passphrase) {
exporting = true
@@ -35,14 +24,23 @@ HFileDialogOpener {
}
+ fill: false
+ dialog.title: qsTr("Save decryption keys file as...")
+ dialog.fileMode: FileDialog.SaveFile
+ onFilePicked: {
+ exportPasswordPopup.file = file
+ exportPasswordPopup.open()
+ }
+
PasswordPopup {
id: exportPasswordPopup
+
+ property url file: ""
+
summary.text: qsTr("Passphrase to protect this file:")
validateButton.text: qsTr("Export")
validateButton.icon.name: "export-keys"
onAcceptedPasswordChanged: exportKeys(file, acceptedPassword)
-
- property url file: ""
}
}
diff --git a/src/gui/Dialogs/HFileDialogOpener.qml b/src/gui/Dialogs/HFileDialogOpener.qml
index c978b53f..89d95e05 100644
--- a/src/gui/Dialogs/HFileDialogOpener.qml
+++ b/src/gui/Dialogs/HFileDialogOpener.qml
@@ -5,13 +5,8 @@ import Qt.labs.platform 1.1
Item {
id: opener
- anchors.fill: fill ? parent : undefined
-
-
- signal filePicked(string file)
- signal filesPicked(var files)
- signal cancelled()
+ enum FileType { All, Images }
property bool fill: true
@@ -24,9 +19,14 @@ Item {
property string selectSubject:
dialog.fileMode === FileDialog.SaveFile ? qsTr("file") : qsTr("open")
- enum FileType { All, Images }
property int fileType: HFileDialogOpener.FileType.All
+ signal filePicked(string file)
+ signal filesPicked(var files)
+ signal cancelled()
+
+
+ anchors.fill: fill ? parent : undefined
TapHandler { enabled: opener.enabled && fill; onTapped: fileDialog.open() }
diff --git a/src/gui/Dialogs/ImportKeys.qml b/src/gui/Dialogs/ImportKeys.qml
index 0d008866..f84fa0ee 100644
--- a/src/gui/Dialogs/ImportKeys.qml
+++ b/src/gui/Dialogs/ImportKeys.qml
@@ -7,6 +7,10 @@ import "../Popups"
import "../PythonBridge"
HFileDialogOpener {
+ property string userId: ""
+ property Future importFuture: null
+
+
fill: false
dialog.title: qsTr("Select a decryption keys file to import")
onFilePicked: {
@@ -14,26 +18,11 @@ HFileDialogOpener {
importPasswordPopup.open()
}
-
- property string userId: ""
- property Future importFuture: null
-
-
PasswordPopup {
id: importPasswordPopup
- summary.text:
- importFuture ?
- qsTr("This might take a while...") :
- qsTr("Passphrase used to protect this file:")
- validateButton.text: qsTr("Import")
- validateButton.icon.name: "import-keys"
-
- onClosed: if (importFuture) importFuture.cancel()
-
property url file: ""
-
function verifyPassword(pass, callback) {
const call = py.callClientCoro
const path = file.toString().replace(/^file:\/\//, "")
@@ -72,6 +61,14 @@ HFileDialogOpener {
})
}
+ summary.text:
+ importFuture ?
+ qsTr("This might take a while...") :
+ qsTr("Passphrase used to protect this file:")
+ validateButton.text: qsTr("Import")
+ validateButton.icon.name: "import-keys"
+
+ onClosed: if (importFuture) importFuture.cancel()
Binding on closePolicy {
value: Popup.CloseOnEscape
diff --git a/src/gui/Dialogs/SendFilePicker.qml b/src/gui/Dialogs/SendFilePicker.qml
index 56a3987c..6a0b1a77 100644
--- a/src/gui/Dialogs/SendFilePicker.qml
+++ b/src/gui/Dialogs/SendFilePicker.qml
@@ -4,6 +4,11 @@ import QtQuick 2.12
import Qt.labs.platform 1.1
HFileDialogOpener {
+ property string userId
+ property string roomId
+ property bool destroyWhenDone: false
+
+
fill: false
dialog.title: qsTr("Select a file to send")
dialog.fileMode: FileDialog.OpenFiles
@@ -23,9 +28,4 @@ HFileDialogOpener {
}
onCancelled: if (destroyWhenDone) destroy()
-
-
- property string userId
- property string roomId
- property bool destroyWhenDone: false
}
diff --git a/src/gui/IdleManager.qml b/src/gui/IdleManager.qml
index 4fd2c002..046df980 100644
--- a/src/gui/IdleManager.qml
+++ b/src/gui/IdleManager.qml
@@ -8,7 +8,6 @@ Timer {
readonly property ListModel accounts: ModelStore.get("accounts")
readonly property var accountsSet: new Set()
-
function setPresence(userId, presence) {
py.callClientCoro(userId, "set_presence", [presence, undefined, false])
}
diff --git a/src/gui/MainPane/AccountBar.qml b/src/gui/MainPane/AccountBar.qml
index d1a4c391..0815ba92 100644
--- a/src/gui/MainPane/AccountBar.qml
+++ b/src/gui/MainPane/AccountBar.qml
@@ -7,14 +7,13 @@ import "../Base"
import "../Base/HTile"
Rectangle {
- implicitHeight: accountList.count >= 2 ? accountList.contentHeight : 0
- color: theme.mainPane.accountBar.background
-
-
property RoomList roomList
readonly property alias accountList: accountList
+ implicitHeight: accountList.count >= 2 ? accountList.contentHeight : 0
+ color: theme.mainPane.accountBar.background
+
Behavior on implicitHeight { HNumberAnimation {} }
HGridView {
diff --git a/src/gui/MainPane/AccountContextMenu.qml b/src/gui/MainPane/AccountContextMenu.qml
index bb6755ec..f910fdbb 100644
--- a/src/gui/MainPane/AccountContextMenu.qml
+++ b/src/gui/MainPane/AccountContextMenu.qml
@@ -13,10 +13,8 @@ HMenu {
property string presence
property string statusMsg
-
signal wentToAccountPage()
-
function setPresence(presence, statusMsg=undefined) {
py.callClientCoro(userId, "set_presence", [presence, statusMsg])
}
@@ -24,7 +22,6 @@ HMenu {
onOpened: statusText.forceActiveFocus()
-
HLabeledItem {
id: statusMsgLabel
enabled: presence && presence !== "offline"
diff --git a/src/gui/MainPane/AccountDelegate.qml b/src/gui/MainPane/AccountDelegate.qml
index 6f55fb39..c88a51ef 100644
--- a/src/gui/MainPane/AccountDelegate.qml
+++ b/src/gui/MainPane/AccountDelegate.qml
@@ -7,6 +7,39 @@ import "../Base/HTile"
HTile {
id: account
+
+ property bool enableKeybinds: false
+ property bool filterActive: false
+
+ readonly property bool collapsed:
+ (window.uiState.collapseAccounts[model.id] || false) &&
+ ! filterActive
+
+ readonly property alias avatar: title
+ readonly property alias totalMessageIndicator: totalMessageIndicator
+ readonly property alias title: title
+ readonly property alias addChat: addChat
+ readonly property alias expand: expand
+
+ signal wentToAccountPage()
+
+ function setCollapse(collapse) {
+ window.uiState.collapseAccounts[model.id] = collapse
+ window.uiStateChanged()
+
+ py.callCoro("set_account_collapse", [model.id, collapse])
+ }
+
+ function toggleCollapse() {
+ setCollapse(! collapsed)
+ }
+
+ function togglePresence(presence) {
+ if (model.presence === presence) presence = "online"
+ py.callClientCoro(model.id, "set_presence", [presence])
+ }
+
+
backgroundColor: theme.mainPane.listView.account.background
contentItem: ContentRow {
@@ -171,40 +204,6 @@ HTile {
onWentToAccountPage: account.wentToAccountPage()
}
-
- property bool enableKeybinds: false
- property bool filterActive: false
-
- readonly property bool collapsed:
- (window.uiState.collapseAccounts[model.id] || false) &&
- ! filterActive
-
- readonly property alias avatar: title
- readonly property alias totalMessageIndicator: totalMessageIndicator
- readonly property alias title: title
- readonly property alias addChat: addChat
- readonly property alias expand: expand
-
- signal wentToAccountPage()
-
-
- function setCollapse(collapse) {
- window.uiState.collapseAccounts[model.id] = collapse
- window.uiStateChanged()
-
- py.callCoro("set_account_collapse", [model.id, collapse])
- }
-
- function toggleCollapse() {
- setCollapse(! collapsed)
- }
-
- function togglePresence(presence) {
- if (model.presence === presence) presence = "online"
- py.callClientCoro(model.id, "set_presence", [presence])
- }
-
-
HShortcut {
enabled: enableKeybinds
sequences: window.settings.keys.accountSettings
diff --git a/src/gui/MainPane/BottomBar.qml b/src/gui/MainPane/BottomBar.qml
index 9de82fee..af5cdc97 100644
--- a/src/gui/MainPane/BottomBar.qml
+++ b/src/gui/MainPane/BottomBar.qml
@@ -5,17 +5,16 @@ import QtQuick.Layouts 1.12
import "../Base"
Rectangle {
- // Hide filter field overflowing for a sec on size changes
- clip: true
- implicitHeight: theme.baseElementsHeight
- color: theme.mainPane.bottomBar.background
-
-
property RoomList roomList
readonly property alias addAccountButton: addAccountButton
readonly property alias filterField: filterField
+ // Hide filter field overflowing for a sec on size changes
+ clip: true
+ implicitHeight: theme.baseElementsHeight
+ color: theme.mainPane.bottomBar.background
+
HRowLayout {
anchors.fill: parent
diff --git a/src/gui/MainPane/MainPane.qml b/src/gui/MainPane/MainPane.qml
index cda68341..fbd3c586 100644
--- a/src/gui/MainPane/MainPane.qml
+++ b/src/gui/MainPane/MainPane.qml
@@ -6,15 +6,11 @@ import "../Base"
HDrawer {
id: mainPane
- saveName: "mainPane"
- background: Rectangle { color: theme.mainPane.background }
- minimumSize: theme.mainPane.minimumSize
readonly property alias accountBar: accountBar
readonly property alias roomList: roomList
readonly property alias bottomBar: bottomBar
-
function toggleFocus() {
if (bottomBar.filterField.activeFocus) {
pageLoader.takeFocus()
@@ -26,6 +22,10 @@ HDrawer {
}
+ saveName: "mainPane"
+ background: Rectangle { color: theme.mainPane.background }
+ minimumSize: theme.mainPane.minimumSize
+
Behavior on opacity { HNumberAnimation {} }
Binding on visible {
diff --git a/src/gui/MainPane/MessageIndicator.qml b/src/gui/MainPane/MessageIndicator.qml
index 63b1dc27..dc137f3c 100644
--- a/src/gui/MainPane/MessageIndicator.qml
+++ b/src/gui/MainPane/MessageIndicator.qml
@@ -4,6 +4,13 @@ import QtQuick 2.12
import "../Base"
HLabel {
+ property QtObject indicatorTheme
+ property int unreads: 0
+ property int highlights: 0
+ property bool localUnreads: false
+ property bool localHighlights: false
+
+
text:
unreads >= 1000000 ? Math.floor(unreads / 1000000) + "M" :
unreads >= 1000 ? Math.floor(unreads / 1000) + "K" :
@@ -31,13 +38,5 @@ HLabel {
Behavior on color { HColorAnimation {} }
}
-
- property QtObject indicatorTheme
- property int unreads: 0
- property int highlights: 0
- property bool localUnreads: false
- property bool localHighlights: false
-
-
Behavior on scale { HNumberAnimation {} }
}
diff --git a/src/gui/MainPane/RoomDelegate.qml b/src/gui/MainPane/RoomDelegate.qml
index 705b1cc2..a0b5237d 100644
--- a/src/gui/MainPane/RoomDelegate.qml
+++ b/src/gui/MainPane/RoomDelegate.qml
@@ -9,6 +9,22 @@ import "../Base/HTile"
HTile {
id: room
+
+ readonly property bool joined: ! invited && ! parted
+ readonly property bool invited: model.inviter_id && ! parted
+ readonly property bool parted: model.left
+
+ readonly property ListModel eventModel:
+ ModelStore.get(model.for_account, model.id, "events")
+
+ // FIXME: binding loop
+ readonly property QtObject accountModel:
+ ModelStore.get("accounts").find(model.for_account)
+
+ readonly property QtObject lastEvent:
+ eventModel.count > 0 ? eventModel.get(0) : null
+
+
backgroundColor: theme.mainPane.listView.room.background
leftPadding: theme.spacing * 2
rightPadding: theme.spacing
@@ -179,19 +195,4 @@ HTile {
})
}
}
-
-
- readonly property bool joined: ! invited && ! parted
- readonly property bool invited: model.inviter_id && ! parted
- readonly property bool parted: model.left
-
- readonly property ListModel eventModel:
- ModelStore.get(model.for_account, model.id, "events")
-
- // FIXME: binding loop
- readonly property QtObject accountModel:
- ModelStore.get("accounts").find(model.for_account)
-
- readonly property QtObject lastEvent:
- eventModel.count > 0 ? eventModel.get(0) : null
}
diff --git a/src/gui/MainPane/RoomList.qml b/src/gui/MainPane/RoomList.qml
index 1113660c..5f97dc69 100644
--- a/src/gui/MainPane/RoomList.qml
+++ b/src/gui/MainPane/RoomList.qml
@@ -8,83 +8,19 @@ import "../Base"
HListView {
id: roomList
- model: ModelStore.get("all_rooms")
-
- delegate: DelegateChooser {
- role: "type"
-
- DelegateChoice {
- roleValue: "Account"
- AccountDelegate {
- width: roomList.width
- leftPadding: theme.spacing
- rightPadding: 0 // the right buttons have padding
-
- filterActive: Boolean(filter)
- enableKeybinds: Boolean(
- roomList.model.get(currentIndex) && (
- roomList.model.get(currentIndex).for_account ||
- roomList.model.get(currentIndex).id
- ) === model.id
- )
-
- totalMessageIndicator.visible: false
-
- onLeftClicked: showItemAtIndex(model.index)
- onCollapsedChanged:
- if (wantedUserId === model.id) startCorrectItemSearch()
-
- onWentToAccountPage: roomList.currentIndex = model.index
- }
- }
-
- DelegateChoice {
- roleValue: "Room"
- RoomDelegate {
- width: roomList.width
- onLeftClicked: showItemAtIndex(model.index)
- }
- }
- }
-
- onFilterChanged: {
- py.callCoro("set_substring_filter", ["all_rooms", filter], () => {
- if (filter) {
- currentIndex = 1 // highlight the first matching room
- return
- }
-
- const item = model.get(currentIndex)
-
- if (
- ! filter &&
- item && (
- currentIndex === 1 || // required, related to the if above
- (
- currentShouldBeAccount &&
- wantedUserId !== item.id
- ) || (
- currentShouldBeRoom && (
- wantedUserId !== item.for_account ||
- wantedRoomId !== item.id
- )
- )
- )
- )
- startCorrectItemSearch()
- })
- }
-
property string filter: ""
readonly property bool currentShouldBeAccount:
window.uiState.page === "Pages/AccountSettings/AccountSettings.qml" ||
window.uiState.page === "Pages/AddChat/AddChat.qml"
+
readonly property bool currentShouldBeRoom:
window.uiState.page === "Pages/Chat/Chat.qml"
+
readonly property string wantedUserId:
window.uiState.pageProperties.userId || ""
+
readonly property string wantedRoomId:
window.uiState.pageProperties.roomId || ""
@@ -99,7 +35,6 @@ HListView {
return accounts
}
-
function goToAccount(userId) {
accountIndice[userId] + 1 <= model.count -1 &&
model.get(accountIndice[userId] + 1).type === "Room" ?
@@ -200,6 +135,73 @@ HListView {
}
+ model: ModelStore.get("all_rooms")
+
+ delegate: DelegateChooser {
+ role: "type"
+
+ DelegateChoice {
+ roleValue: "Account"
+ AccountDelegate {
+ width: roomList.width
+ leftPadding: theme.spacing
+ rightPadding: 0 // the right buttons have padding
+
+ filterActive: Boolean(filter)
+ enableKeybinds: Boolean(
+ roomList.model.get(currentIndex) && (
+ roomList.model.get(currentIndex).for_account ||
+ roomList.model.get(currentIndex).id
+ ) === model.id
+ )
+
+ totalMessageIndicator.visible: false
+
+ onLeftClicked: showItemAtIndex(model.index)
+ onCollapsedChanged:
+ if (wantedUserId === model.id) startCorrectItemSearch()
+
+ onWentToAccountPage: roomList.currentIndex = model.index
+ }
+ }
+
+ DelegateChoice {
+ roleValue: "Room"
+ RoomDelegate {
+ width: roomList.width
+ onLeftClicked: showItemAtIndex(model.index)
+ }
+ }
+ }
+
+ onFilterChanged: {
+ py.callCoro("set_substring_filter", ["all_rooms", filter], () => {
+ if (filter) {
+ currentIndex = 1 // highlight the first matching room
+ return
+ }
+
+ const item = model.get(currentIndex)
+
+ if (
+ ! filter &&
+ item && (
+ currentIndex === 1 || // required, related to the if above
+ (
+ currentShouldBeAccount &&
+ wantedUserId !== item.id
+ ) || (
+ currentShouldBeRoom && (
+ wantedUserId !== item.for_account ||
+ wantedRoomId !== item.id
+ )
+ )
+ )
+ )
+ startCorrectItemSearch()
+ })
+ }
+
Connections {
target: pageLoader
diff --git a/src/gui/ModelStore.qml b/src/gui/ModelStore.qml
index 14884197..773ead26 100644
--- a/src/gui/ModelStore.qml
+++ b/src/gui/ModelStore.qml
@@ -6,22 +6,17 @@ import "PythonBridge"
QtObject {
property QtObject privates: QtObject {
- onEnsureModelExists:
- py.callCoro("models.ensure_exists_from_qml", [modelId])
-
- signal ensureModelExists(var modelId)
-
readonly property var store: ({})
readonly property PythonBridge py: PythonBridge {}
readonly property Component model: Component {
ListModel {
+ property var modelId
+
// Used by HFilterModel
signal fieldsChanged(int index, var changes)
- property var modelId
-
function findIndex(id, default_=null) {
for (let i = 0; i < count; i++)
if (get(i).id === id) return i
@@ -37,6 +32,11 @@ QtObject {
}
}
}
+
+ signal ensureModelExists(var modelId)
+
+ onEnsureModelExists:
+ py.callCoro("models.ensure_exists_from_qml", [modelId])
}
diff --git a/src/gui/PageLoader.qml b/src/gui/PageLoader.qml
index cf175c70..2c72fdfa 100644
--- a/src/gui/PageLoader.qml
+++ b/src/gui/PageLoader.qml
@@ -10,31 +10,6 @@ import "MainPane"
HLoader {
id: pageLoader
- clip: appearAnimation.running
-
- onLoaded: { takeFocus(); appearAnimation.start() }
-
- Component.onCompleted: {
- if (! py.startupAnyAccountsSaved) {
- pageLoader.showPage(
- "AddAccount/AddAccount", {"header.show": false},
- )
- return
- }
-
- const page = window.uiState.page
- const props = window.uiState.pageProperties
-
- if (page === "Pages/Chat/Chat.qml") {
- pageLoader.showRoom(props.userId, props.roomId)
- } else {
- pageLoader._show(page, props)
- }
- }
-
-
- signal previousShown(string componentUrl, var properties)
-
property bool isWide: width > theme.contentIsWideAbove
@@ -44,6 +19,7 @@ HLoader {
readonly property alias appearAnimation: appearAnimation
+ signal previousShown(string componentUrl, var properties)
function _show(componentUrl, properties={}) {
history.unshift([componentUrl, properties])
@@ -90,6 +66,28 @@ HLoader {
}
+ clip: appearAnimation.running
+
+ onLoaded: { takeFocus(); appearAnimation.start() }
+
+ Component.onCompleted: {
+ if (! py.startupAnyAccountsSaved) {
+ pageLoader.showPage(
+ "AddAccount/AddAccount", {"header.show": false},
+ )
+ return
+ }
+
+ const page = window.uiState.page
+ const props = window.uiState.pageProperties
+
+ if (page === "Pages/Chat/Chat.qml") {
+ pageLoader.showRoom(props.userId, props.roomId)
+ } else {
+ pageLoader._show(page, props)
+ }
+ }
+
HNumberAnimation {
id: appearAnimation
target: pageLoader.item
diff --git a/src/gui/Pages/AccountSettings/Account.qml b/src/gui/Pages/AccountSettings/Account.qml
index ae51de37..7fdc02f5 100644
--- a/src/gui/Pages/AccountSettings/Account.qml
+++ b/src/gui/Pages/AccountSettings/Account.qml
@@ -11,12 +11,10 @@ import "../../Dialogs"
HFlickableColumnPage {
id: page
-
property string userId
readonly property QtObject account: ModelStore.get("accounts").find(userId)
readonly property bool ready: account && account.profile_updated >= new Date(1)
-
function takeFocus() {
nameField.item.forceActiveFocus()
}
@@ -90,11 +88,11 @@ HFlickableColumnPage {
onKeyboardCancel: cancel()
onKeyboardAccept: applyChanges()
-
HUserAvatar {
+ id: avatar
+
property bool changed: Boolean(sourceOverride)
- id: avatar
userId: page.userId
displayName: nameField.item.text
mxc: account ? account.avatar_url : ""
@@ -231,6 +229,8 @@ HFlickableColumnPage {
}
HLabeledItem {
+ id: aliasField
+
readonly property var aliases: window.settings.writeAliases
readonly property string currentAlias: aliases[userId] || ""
@@ -243,9 +243,6 @@ HFlickableColumnPage {
return ""
}
-
- id: aliasField
-
label.text: qsTr("Composer alias:")
errorLabel.text:
diff --git a/src/gui/Pages/AccountSettings/AccountSettings.qml b/src/gui/Pages/AccountSettings/AccountSettings.qml
index ce7a0cea..eb05844f 100644
--- a/src/gui/Pages/AccountSettings/AccountSettings.qml
+++ b/src/gui/Pages/AccountSettings/AccountSettings.qml
@@ -9,7 +9,6 @@ import "../../Base"
HPage {
id: page
-
property string userId
diff --git a/src/gui/Pages/AccountSettings/DeviceDelegate.qml b/src/gui/Pages/AccountSettings/DeviceDelegate.qml
index 00b96d17..cefc141c 100644
--- a/src/gui/Pages/AccountSettings/DeviceDelegate.qml
+++ b/src/gui/Pages/AccountSettings/DeviceDelegate.qml
@@ -9,7 +9,6 @@ import "../../Base/HTile"
HTile {
id: deviceTile
-
property HListView view
property string userId
diff --git a/src/gui/Pages/AccountSettings/DeviceSection.qml b/src/gui/Pages/AccountSettings/DeviceSection.qml
index 4ba77009..9ff79c3a 100644
--- a/src/gui/Pages/AccountSettings/DeviceSection.qml
+++ b/src/gui/Pages/AccountSettings/DeviceSection.qml
@@ -15,6 +15,7 @@ HRowLayout {
readonly property int sectionTotalCount:
deviceList.sectionItemCounts[section] || 0
+
HCheckBox {
id: checkBox
padding: theme.spacing
diff --git a/src/gui/Pages/AccountSettings/Encryption.qml b/src/gui/Pages/AccountSettings/Encryption.qml
index 032aa81c..01e35f6b 100644
--- a/src/gui/Pages/AccountSettings/Encryption.qml
+++ b/src/gui/Pages/AccountSettings/Encryption.qml
@@ -8,10 +8,8 @@ import "../../Base/Buttons"
HFlickableColumnPage {
id: page
-
property string userId
-
function takeFocus() { exportButton.forceActiveFocus() }
diff --git a/src/gui/Pages/AccountSettings/Sessions.qml b/src/gui/Pages/AccountSettings/Sessions.qml
index a06702c6..980e1d67 100644
--- a/src/gui/Pages/AccountSettings/Sessions.qml
+++ b/src/gui/Pages/AccountSettings/Sessions.qml
@@ -11,15 +11,6 @@ import "../../ShortcutBundles"
HColumnPage {
id: page
- enabled: ModelStore.get("accounts").find(userId).presence !== "offline"
- contentHeight: Math.min(
- window.height,
- Math.max(
- deviceList.contentHeight + deviceList.bottomMargin,
- busyIndicatorLoader.height + theme.spacing * 2,
- )
- )
-
property string userId
@@ -28,7 +19,6 @@ HColumnPage {
property Future loadFuture: null
-
function takeFocus() {} // TODO
function loadDevices() {
@@ -100,6 +90,15 @@ HColumnPage {
}
+ enabled: ModelStore.get("accounts").find(userId).presence !== "offline"
+ contentHeight: Math.min(
+ window.height,
+ Math.max(
+ deviceList.contentHeight + deviceList.bottomMargin,
+ busyIndicatorLoader.height + theme.spacing * 2,
+ )
+ )
+
footer: AutoDirectionLayout {
GroupButton {
id: refreshButton
@@ -126,7 +125,6 @@ HColumnPage {
Keys.forwardTo: [deviceList]
-
HListView {
id: deviceList
diff --git a/src/gui/Pages/AddAccount/Register.qml b/src/gui/Pages/AddAccount/Register.qml
index c5c799ab..ac8c993e 100644
--- a/src/gui/Pages/AddAccount/Register.qml
+++ b/src/gui/Pages/AddAccount/Register.qml
@@ -20,7 +20,6 @@ HFlickableColumnPage {
}
}
-
HLabel {
wrapMode: Text.Wrap
horizontalAlignment: Qt.AlignHCenter
diff --git a/src/gui/Pages/AddAccount/Reset.qml b/src/gui/Pages/AddAccount/Reset.qml
index 9e4cb56d..42675c68 100644
--- a/src/gui/Pages/AddAccount/Reset.qml
+++ b/src/gui/Pages/AddAccount/Reset.qml
@@ -21,7 +21,6 @@ HFlickableColumnPage {
}
}
-
HLabel {
wrapMode: Text.Wrap
horizontalAlignment: Qt.AlignHCenter
diff --git a/src/gui/Pages/AddAccount/SignIn.qml b/src/gui/Pages/AddAccount/SignIn.qml
index f8d32a26..88cdce98 100644
--- a/src/gui/Pages/AddAccount/SignIn.qml
+++ b/src/gui/Pages/AddAccount/SignIn.qml
@@ -8,7 +8,6 @@ import "../../Base/Buttons"
HFlickableColumnPage {
id: page
-
property var loginFuture: null
property string signInWith: "username"
@@ -17,7 +16,6 @@ HFlickableColumnPage {
serverField.item.text.trim() && idField.item.text.trim() &&
passwordField.item.text && ! serverField.item.error
-
function takeFocus() { idField.item.forceActiveFocus() }
function signIn() {
@@ -95,7 +93,6 @@ HFlickableColumnPage {
onKeyboardAccept: page.signIn()
onKeyboardCancel: page.cancel()
-
Timer {
id: signInTimeout
interval: 30 * 1000
@@ -190,11 +187,11 @@ HFlickableColumnPage {
Layout.fillWidth: true
HTextField {
+ readonly property string cleanText: text.toLowerCase().trim()
+
width: parent.width
text: "https://matrix.org"
error: ! /.+:\/\/.+/.test(cleanText)
-
- readonly property string cleanText: text.toLowerCase().trim()
}
}
diff --git a/src/gui/Pages/AddChat/AddChat.qml b/src/gui/Pages/AddChat/AddChat.qml
index 4ad4a259..955dcbf8 100644
--- a/src/gui/Pages/AddChat/AddChat.qml
+++ b/src/gui/Pages/AddChat/AddChat.qml
@@ -7,7 +7,6 @@ import "../../Base"
HPage {
id: page
-
property string userId
diff --git a/src/gui/Pages/AddChat/CreateRoom.qml b/src/gui/Pages/AddChat/CreateRoom.qml
index ef7d5112..15254699 100644
--- a/src/gui/Pages/AddChat/CreateRoom.qml
+++ b/src/gui/Pages/AddChat/CreateRoom.qml
@@ -8,13 +8,10 @@ import "../../Base/Buttons"
HFlickableColumnPage {
id: page
- enabled: account && account.presence !== "offline"
-
property string userId
readonly property QtObject account: ModelStore.get("accounts").find(userId)
-
function takeFocus() { nameField.item.forceActiveFocus() }
function create() {
@@ -52,6 +49,8 @@ HFlickableColumnPage {
}
+ enabled: account && account.presence !== "offline"
+
footer: AutoDirectionLayout {
ApplyButton {
id: applyButton
@@ -68,7 +67,6 @@ HFlickableColumnPage {
onKeyboardAccept: create()
onKeyboardCancel: cancel()
-
HRoomAvatar {
id: avatar
roomId: ""
diff --git a/src/gui/Pages/AddChat/CurrentUserAvatar.qml b/src/gui/Pages/AddChat/CurrentUserAvatar.qml
index 2593ff90..39d7a74a 100644
--- a/src/gui/Pages/AddChat/CurrentUserAvatar.qml
+++ b/src/gui/Pages/AddChat/CurrentUserAvatar.qml
@@ -7,6 +7,7 @@ import "../../Base"
HUserAvatar {
property QtObject account
+
// userId: (set me)
displayName: account ? account.display_name : ""
mxc: account ? account.avatar_url : ""
diff --git a/src/gui/Pages/AddChat/DirectChat.qml b/src/gui/Pages/AddChat/DirectChat.qml
index 8662d105..6bce4d20 100644
--- a/src/gui/Pages/AddChat/DirectChat.qml
+++ b/src/gui/Pages/AddChat/DirectChat.qml
@@ -8,13 +8,10 @@ import "../../Base/Buttons"
HFlickableColumnPage {
id: page
- enabled: account && account.presence !== "offline"
-
property string userId
readonly property QtObject account: ModelStore.get("accounts").find(userId)
-
function takeFocus() {
userField.item.forceActiveFocus()
}
@@ -64,6 +61,8 @@ HFlickableColumnPage {
}
+ enabled: account && account.presence !== "offline"
+
footer: AutoDirectionLayout {
ApplyButton {
id: applyButton
@@ -85,7 +84,6 @@ HFlickableColumnPage {
onKeyboardAccept: startChat()
onKeyboardCancel: cancel()
-
CurrentUserAvatar {
userId: page.userId
account: page.account
diff --git a/src/gui/Pages/AddChat/EncryptCheckBox.qml b/src/gui/Pages/AddChat/EncryptCheckBox.qml
index 986ff4f4..91b6fcaa 100644
--- a/src/gui/Pages/AddChat/EncryptCheckBox.qml
+++ b/src/gui/Pages/AddChat/EncryptCheckBox.qml
@@ -5,11 +5,11 @@ import "../../Base"
HCheckBox {
text: qsTr("Encrypt messages")
+ subtitle.textFormat: Text.StyledText
subtitle.text:
qsTr("Only you and those you trust will be able to read the " +
"conversation") +
`
` +
qsTr("Cannot be disabled later!") +
""
- subtitle.textFormat: Text.StyledText
}
diff --git a/src/gui/Pages/AddChat/JoinRoom.qml b/src/gui/Pages/AddChat/JoinRoom.qml
index 28e723da..08e563a5 100644
--- a/src/gui/Pages/AddChat/JoinRoom.qml
+++ b/src/gui/Pages/AddChat/JoinRoom.qml
@@ -8,13 +8,10 @@ import "../../Base/Buttons"
HFlickableColumnPage {
id: page
- enabled: account && account.presence !== "offline"
-
property string userId
readonly property QtObject account: ModelStore.get("accounts").find(userId)
-
function takeFocus() {
roomField.item.forceActiveFocus()
}
@@ -57,6 +54,8 @@ HFlickableColumnPage {
}
+ enabled: account && account.presence !== "offline"
+
footer: AutoDirectionLayout {
ApplyButton {
id: joinButton
@@ -74,7 +73,6 @@ HFlickableColumnPage {
onKeyboardAccept: join()
onKeyboardCancel: cancel()
-
CurrentUserAvatar {
userId: page.userId
account: page.account
diff --git a/src/gui/Pages/Chat/Banners/Banner.qml b/src/gui/Pages/Chat/Banners/Banner.qml
index 477e8360..bb51d0db 100644
--- a/src/gui/Pages/Chat/Banners/Banner.qml
+++ b/src/gui/Pages/Chat/Banners/Banner.qml
@@ -6,8 +6,6 @@ import "../../../Base"
Rectangle {
id: banner
- implicitHeight: childrenRect.height
- color: theme.controls.box.background
property alias avatar: bannerAvatar
property alias icon: bannerIcon
@@ -15,6 +13,10 @@ Rectangle {
property alias buttonModel: bannerRepeater.model
property var buttonCallbacks: []
+
+ implicitHeight: childrenRect.height
+ color: theme.controls.box.background
+
HGridLayout {
id: bannerGrid
width: parent.width
diff --git a/src/gui/Pages/Chat/Banners/InviteBanner.qml b/src/gui/Pages/Chat/Banners/InviteBanner.qml
index 8313f1eb..1ee9606b 100644
--- a/src/gui/Pages/Chat/Banners/InviteBanner.qml
+++ b/src/gui/Pages/Chat/Banners/InviteBanner.qml
@@ -8,6 +8,7 @@ Banner {
property string inviterName: chat.roomInfo.inviter_name
property string inviterAvatar: chat.roomInfo.inviter_avatar
+
color: theme.chat.inviteBanner.background
avatar.userId: inviterId
diff --git a/src/gui/Pages/Chat/Chat.qml b/src/gui/Pages/Chat/Chat.qml
index 6b935216..3dc4c490 100644
--- a/src/gui/Pages/Chat/Chat.qml
+++ b/src/gui/Pages/Chat/Chat.qml
@@ -9,10 +9,6 @@ import "RoomPane"
Item {
id: chat
- onFocusChanged: if (focus && loader.item) loader.item.composer.takeFocus()
- onReadyChanged: longLoading = false
-
-
property string userId
property string roomId
@@ -33,6 +29,9 @@ Item {
Boolean(loader.item && loader.item.composer.hasFocus)
+ onFocusChanged: if (focus && loader.item) loader.item.composer.takeFocus()
+ onReadyChanged: longLoading = false
+
HShortcut {
sequences: window.settings.keys.leaveRoom
active: userInfo && userInfo.presence !== "offline"
diff --git a/src/gui/Pages/Chat/ChatPage.qml b/src/gui/Pages/Chat/ChatPage.qml
index e2fea337..3a4347bd 100644
--- a/src/gui/Pages/Chat/ChatPage.qml
+++ b/src/gui/Pages/Chat/ChatPage.qml
@@ -10,12 +10,6 @@ import "Timeline"
HColumnPage {
id: chatPage
- padding: 0
- column.spacing: 0
-
- onLoadEventListChanged: if (loadEventList) loadedOnce = true
- Component.onDestruction: if (loadMembersFuture) loadMembersFuture.cancel()
-
property bool loadedOnce: false
property var loadMembersFuture: null
@@ -26,6 +20,12 @@ HColumnPage {
! mainUI.mainPane.visible : ! pageLoader.appearAnimation.running
+ padding: 0
+ column.spacing: 0
+
+ onLoadEventListChanged: if (loadEventList) loadedOnce = true
+ Component.onDestruction: if (loadMembersFuture) loadMembersFuture.cancel()
+
Timer {
interval: 200
running: true
diff --git a/src/gui/Pages/Chat/Composer/Composer.qml b/src/gui/Pages/Chat/Composer/Composer.qml
index 44f8d8e1..4fb5b52a 100644
--- a/src/gui/Pages/Chat/Composer/Composer.qml
+++ b/src/gui/Pages/Chat/Composer/Composer.qml
@@ -8,7 +8,6 @@ Rectangle {
property alias eventList: messageArea.eventList
readonly property bool hasFocus: messageArea.activeFocus
-
function takeFocus() { messageArea.forceActiveFocus() }
@@ -17,7 +16,6 @@ Rectangle {
color: theme.chat.composer.background
-
HRowLayout {
anchors.fill: parent
diff --git a/src/gui/Pages/Chat/Composer/MessageArea.qml b/src/gui/Pages/Chat/Composer/MessageArea.qml
index 13587d2b..6975ee8e 100644
--- a/src/gui/Pages/Chat/Composer/MessageArea.qml
+++ b/src/gui/Pages/Chat/Composer/MessageArea.qml
@@ -7,7 +7,6 @@ import "../../../Base"
HTextArea {
id: textArea
-
property HListView eventList
property string indent: " "
@@ -50,7 +49,6 @@ HTextArea {
return obj
}
-
function setTyping(typing) {
py.callClientCoro(
writingUserId, "room_typing", [chat.roomId, typing, 5000],
diff --git a/src/gui/Pages/Chat/Composer/UploadButton.qml b/src/gui/Pages/Chat/Composer/UploadButton.qml
index 263de22c..00390b66 100644
--- a/src/gui/Pages/Chat/Composer/UploadButton.qml
+++ b/src/gui/Pages/Chat/Composer/UploadButton.qml
@@ -19,7 +19,6 @@ HButton {
onClicked: sendFilePicker.dialog.open()
-
HShortcut {
sequences: window.settings.keys.sendFileFromPathInClipboard
onActivated: utils.sendFile(
diff --git a/src/gui/Pages/Chat/FileTransfer/Transfer.qml b/src/gui/Pages/Chat/FileTransfer/Transfer.qml
index 929a2ab6..d9dbd262 100644
--- a/src/gui/Pages/Chat/FileTransfer/Transfer.qml
+++ b/src/gui/Pages/Chat/FileTransfer/Transfer.qml
@@ -8,7 +8,6 @@ import "../../../Base"
HColumnLayout {
id: transfer
-
property bool cancelPending: false
property int msLeft: model.time_left
@@ -18,7 +17,6 @@ HColumnLayout {
readonly property string status: model.status
readonly property bool paused: model.paused
-
function cancel() {
cancelPending = true
// Python will delete this model item on cancel
@@ -51,6 +49,15 @@ HColumnLayout {
HLabel {
id: statusLabel
+
+ property bool expand: status === "Error"
+
+ readonly property string fileName:
+ model.filepath.split("/").slice(-1)[0]
+
+ readonly property string filePath:
+ model.filepath.replace(/^file:\/\//, "")
+
elide: expand ? Text.ElideNone : Text.ElideRight
wrapMode: expand ? Text.Wrap : Text.NoWrap
@@ -92,16 +99,6 @@ HColumnLayout {
Layout.fillWidth: true
-
- property bool expand: status === "Error"
-
- readonly property string fileName:
- model.filepath.split("/").slice(-1)[0]
-
- readonly property string filePath:
- model.filepath.replace(/^file:\/\//, "")
-
-
HoverHandler { id: statusLabelHover }
HToolTip {
diff --git a/src/gui/Pages/Chat/FileTransfer/TransferList.qml b/src/gui/Pages/Chat/FileTransfer/TransferList.qml
index ec3116ad..0a6fe431 100644
--- a/src/gui/Pages/Chat/FileTransfer/TransferList.qml
+++ b/src/gui/Pages/Chat/FileTransfer/TransferList.qml
@@ -5,13 +5,6 @@ import "../../.."
import "../../../Base"
Rectangle {
- implicitWidth: 800
- implicitHeight: firstDelegate ? firstDelegate.height : 0
- color: theme.chat.fileTransfer.background
- opacity: implicitHeight ? 1 : 0
- clip: true
-
-
property int delegateHeight: 0
readonly property var firstDelegate:
@@ -20,6 +13,12 @@ Rectangle {
readonly property alias transferCount: transferList.count
+ implicitWidth: 800
+ implicitHeight: firstDelegate ? firstDelegate.height : 0
+ color: theme.chat.fileTransfer.background
+ opacity: implicitHeight ? 1 : 0
+ clip: true
+
Behavior on implicitHeight { HNumberAnimation {} }
HListView {
diff --git a/src/gui/Pages/Chat/InfoBar.qml b/src/gui/Pages/Chat/InfoBar.qml
index 7e117c04..a8681363 100644
--- a/src/gui/Pages/Chat/InfoBar.qml
+++ b/src/gui/Pages/Chat/InfoBar.qml
@@ -5,15 +5,15 @@ import QtQuick.Layouts 1.12
import "../../Base"
Rectangle {
- implicitHeight: label.text ? rowLayout.height : 0
- opacity: implicitHeight ? 1 : 0
-
+ default property alias rowLayoutData: rowLayout.data
readonly property alias icon: icon
readonly property alias label: label
- default property alias rowLayoutData: rowLayout.data
+ implicitHeight: label.text ? rowLayout.height : 0
+ opacity: implicitHeight ? 1 : 0
+
Behavior on implicitHeight { HNumberAnimation {} }
HRowLayout {
diff --git a/src/gui/Pages/Chat/ReplyBar.qml b/src/gui/Pages/Chat/ReplyBar.qml
index 30cedfde..74aa280b 100644
--- a/src/gui/Pages/Chat/ReplyBar.qml
+++ b/src/gui/Pages/Chat/ReplyBar.qml
@@ -5,6 +5,13 @@ import QtQuick.Layouts 1.12
import "../../Base"
InfoBar {
+ property string replyToEventId: ""
+ property string replyToUserId: ""
+ property string replyToDisplayName: ""
+
+ signal cancel()
+
+
color: theme.chat.replyBar.background
icon.svgName: "reply-to"
label.textFormat: Text.StyledText
@@ -13,15 +20,6 @@ InfoBar {
utils.coloredNameHtml(replyToDisplayName, replyToUserId) :
""
-
- signal cancel()
-
-
- property string replyToEventId: ""
- property string replyToUserId: ""
- property string replyToDisplayName: ""
-
-
HButton {
backgroundColor: "transparent"
icon.name: "reply-cancel"
diff --git a/src/gui/Pages/Chat/RoomHeader.qml b/src/gui/Pages/Chat/RoomHeader.qml
index 678d3564..e6f76c34 100644
--- a/src/gui/Pages/Chat/RoomHeader.qml
+++ b/src/gui/Pages/Chat/RoomHeader.qml
@@ -5,16 +5,15 @@ import QtQuick.Layouts 1.12
import "../../Base"
Rectangle {
- implicitHeight: theme.baseElementsHeight
- color: theme.chat.roomHeader.background
-
-
readonly property bool showPaneButtons: mainUI.mainPane.collapse
readonly property bool center:
showPaneButtons || window.settings.alwaysCenterRoomHeader
+ implicitHeight: theme.baseElementsHeight
+ color: theme.chat.roomHeader.background
+
HRowLayout {
id: row
anchors.fill: parent
@@ -113,16 +112,16 @@ Rectangle {
}
HToolTip {
- visible: text && (nameHover.hovered || topicHover.hovered)
- label.textFormat: Text.StyledText
- text: name && topic ? (`${name}
${topic}`) : (name || topic)
-
readonly property string name:
nameLabel.truncated ?
(`${chat.roomInfo.display_name}`) : ""
readonly property string topic:
topicLabel.truncated ? chat.roomInfo.topic : ""
+
+ visible: text && (nameHover.hovered || topicHover.hovered)
+ label.textFormat: Text.StyledText
+ text: name && topic ? (`${name}
${topic}`) : (name || topic)
}
HSpacer {
diff --git a/src/gui/Pages/Chat/RoomPane/MemberView/DeviceVerification.qml b/src/gui/Pages/Chat/RoomPane/MemberView/DeviceVerification.qml
index 1de8d4b5..7375c89e 100644
--- a/src/gui/Pages/Chat/RoomPane/MemberView/DeviceVerification.qml
+++ b/src/gui/Pages/Chat/RoomPane/MemberView/DeviceVerification.qml
@@ -8,7 +8,6 @@ import "../../../../Base/Buttons"
HFlickableColumnPage {
id: page
-
property string deviceOwner
property string deviceOwnerDisplayName
property string deviceId
@@ -20,7 +19,6 @@ HFlickableColumnPage {
signal trustSet(bool trust)
-
function close() {
if (previouslyFocused) previouslyFocused.forceActiveFocus()
stackView.pop()
@@ -72,7 +70,6 @@ HFlickableColumnPage {
onKeyboardCancel: page.close()
-
HRowLayout {
HButton {
id: closeButton
diff --git a/src/gui/Pages/Chat/RoomPane/MemberView/MemberDelegate.qml b/src/gui/Pages/Chat/RoomPane/MemberView/MemberDelegate.qml
index f2cdfec4..6430332d 100644
--- a/src/gui/Pages/Chat/RoomPane/MemberView/MemberDelegate.qml
+++ b/src/gui/Pages/Chat/RoomPane/MemberView/MemberDelegate.qml
@@ -9,6 +9,7 @@ import "../../../../Popups"
HTile {
id: member
+
backgroundColor: theme.chat.roomPane.listView.member.background
contentOpacity:
model.invited ? theme.chat.roomPane.listView.member.invitedOpacity : 1
@@ -142,7 +143,6 @@ HTile {
}
}
-
Behavior on contentOpacity { HNumberAnimation {} }
Behavior on spacing { HNumberAnimation {} }
diff --git a/src/gui/Pages/Chat/RoomPane/MemberView/MemberProfile.qml b/src/gui/Pages/Chat/RoomPane/MemberView/MemberProfile.qml
index 93614ee7..b4dbb2e3 100644
--- a/src/gui/Pages/Chat/RoomPane/MemberView/MemberProfile.qml
+++ b/src/gui/Pages/Chat/RoomPane/MemberView/MemberProfile.qml
@@ -8,13 +8,11 @@ import "../../../../Base"
HListView {
id: profile
-
property string userId
property string roomId
property QtObject member // RoomMember model item
property HStackView stackView
-
function loadDevices() {
py.callClientCoro(userId, "member_devices", [member.id], devices => {
profile.model.clear()
@@ -211,7 +209,6 @@ HListView {
}
Keys.onEscapePressed: stackView.pop()
-
Connections {
target: py.eventHandlers
diff --git a/src/gui/Pages/Chat/RoomPane/MemberView/MemberView.qml b/src/gui/Pages/Chat/RoomPane/MemberView/MemberView.qml
index 2cb88bc2..1f4311b4 100644
--- a/src/gui/Pages/Chat/RoomPane/MemberView/MemberView.qml
+++ b/src/gui/Pages/Chat/RoomPane/MemberView/MemberView.qml
@@ -10,6 +10,7 @@ HColumnLayout {
readonly property var modelSyncId:
[chat.userId, chat.roomId, "filtered_members"]
+
HStackView {
id: stackView
diff --git a/src/gui/Pages/Chat/RoomPane/RoomPane.qml b/src/gui/Pages/Chat/RoomPane/RoomPane.qml
index 1c95a15a..a24908f2 100644
--- a/src/gui/Pages/Chat/RoomPane/RoomPane.qml
+++ b/src/gui/Pages/Chat/RoomPane/RoomPane.qml
@@ -7,6 +7,22 @@ import "MemberView"
MultiviewPane {
id: roomPane
+
+ readonly property QtObject accountModel:
+ ModelStore.get("accounts").find(chat.roomInfo.for_account)
+
+ function toggleFocus() {
+ if (roomPane.activeFocus) {
+ if (roomPane.collapse) roomPane.close()
+ pageLoader.takeFocus()
+ return
+ }
+
+ roomPane.open()
+ swipeView.currentItem.keybindFocusItem.forceActiveFocus()
+ }
+
+
saveName: "roomPane"
edge: Qt.RightEdge
@@ -56,23 +72,6 @@ MultiviewPane {
}
}
-
- readonly property QtObject accountModel:
- ModelStore.get("accounts").find(chat.roomInfo.for_account)
-
-
- function toggleFocus() {
- if (roomPane.activeFocus) {
- if (roomPane.collapse) roomPane.close()
- pageLoader.takeFocus()
- return
- }
-
- roomPane.open()
- swipeView.currentItem.keybindFocusItem.forceActiveFocus()
- }
-
-
Connections {
target: swipeView
diff --git a/src/gui/Pages/Chat/RoomPane/SettingsView.qml b/src/gui/Pages/Chat/RoomPane/SettingsView.qml
index f551f82e..1eda1b2a 100644
--- a/src/gui/Pages/Chat/RoomPane/SettingsView.qml
+++ b/src/gui/Pages/Chat/RoomPane/SettingsView.qml
@@ -9,7 +9,6 @@ import "../../../Base/Buttons"
HFlickableColumnPage {
id: settingsView
-
property var saveFuture: null
readonly property bool anyChange:
@@ -19,7 +18,6 @@ HFlickableColumnPage {
readonly property Item keybindFocusItem: nameField.item
-
function save() {
if (saveFuture) saveFuture.cancel()
@@ -81,7 +79,6 @@ HFlickableColumnPage {
onKeyboardAccept: save()
onKeyboardCancel: cancel()
-
HRoomAvatar {
id: avatar
roomId: chat.roomId
@@ -117,13 +114,13 @@ HFlickableColumnPage {
Layout.fillWidth: true
HScrollView {
+ readonly property alias area: topicAreaIn
+
clip: true
width: parent.width
height:
Math.min(topicAreaIn.implicitHeight, settingsView.height / 2)
- readonly property alias area: topicAreaIn
-
HTextArea {
id: topicAreaIn
placeholderText: qsTr("This room is about...")
diff --git a/src/gui/Pages/Chat/Timeline/EventContent.qml b/src/gui/Pages/Chat/Timeline/EventContent.qml
index b11edac1..ff8ad099 100644
--- a/src/gui/Pages/Chat/Timeline/EventContent.qml
+++ b/src/gui/Pages/Chat/Timeline/EventContent.qml
@@ -7,9 +7,6 @@ import "../../.."
HRowLayout {
id: eventContent
- spacing: theme.chat.message.horizontalSpacing
- layoutDirection: onRight ? Qt.RightToLeft: Qt.LeftToRight
-
readonly property var mentions: JSON.parse(model.mentions)
@@ -76,6 +73,9 @@ HRowLayout {
readonly property alias selectedText: contentLabel.selectedText
+ spacing: theme.chat.message.horizontalSpacing
+ layoutDirection: onRight ? Qt.RightToLeft: Qt.LeftToRight
+
Item {
id: avatarWrapper
opacity: collapseAvatar ? 0 : 1
@@ -187,6 +187,9 @@ HRowLayout {
PointHandler {
id: mousePointHandler
+
+ property bool checkedNow: false
+
acceptedButtons: Qt.LeftButton
acceptedModifiers: Qt.NoModifier
acceptedPointerTypes:
@@ -208,8 +211,6 @@ HRowLayout {
eventList.uncheck(model.index)
}
}
-
- property bool checkedNow: false
}
PointHandler {
diff --git a/src/gui/Pages/Chat/Timeline/EventDelegate.qml b/src/gui/Pages/Chat/Timeline/EventDelegate.qml
index 20ba1ead..dafaf02c 100644
--- a/src/gui/Pages/Chat/Timeline/EventDelegate.qml
+++ b/src/gui/Pages/Chat/Timeline/EventDelegate.qml
@@ -8,10 +8,6 @@ import "../../../Base"
HColumnLayout {
id: eventDelegate
- width: eventList.width - eventList.leftMargin - eventList.rightMargin
-
- ListView.onRemove: eventList.uncheck(model.id)
-
enum Media { Page, File, Image, Video, Audio }
@@ -62,18 +58,6 @@ HColumnLayout {
readonly property alias eventContent: eventContent
- // Needed because of eventList's MouseArea which steals the
- // HSelectableLabel's MouseArea hover events
- onCursorShapeChanged: eventList.cursorShape = cursorShape
-
- Component.onCompleted: if (model.fetch_profile) py.callClientCoro(
- chat.userId, "get_event_profiles", [chat.roomId, model.id],
- )
-
- Component.onDestruction:
- if (fetchProfilesFuture) fetchProfilesFuture.cancel()
-
-
function json() {
let event = ModelStore.get(chat.userId, chat.roomId, "events")
.get(model.index)
@@ -93,6 +77,21 @@ HColumnLayout {
}
+ width: eventList.width - eventList.leftMargin - eventList.rightMargin
+
+ // Needed because of eventList's MouseArea which steals the
+ // HSelectableLabel's MouseArea hover events
+ onCursorShapeChanged: eventList.cursorShape = cursorShape
+
+ Component.onCompleted: if (model.fetch_profile) py.callClientCoro(
+ chat.userId, "get_event_profiles", [chat.roomId, model.id],
+ )
+
+ Component.onDestruction:
+ if (fetchProfilesFuture) fetchProfilesFuture.cancel()
+
+ ListView.onRemove: eventList.uncheck(model.id)
+
Item {
Layout.fillWidth: true
Layout.preferredHeight:
@@ -240,6 +239,16 @@ HColumnLayout {
}
HMenuItemPopupSpawner {
+ readonly property var events: {
+ eventList.selectedCount ?
+ eventList.redactableCheckedEvents :
+
+ eventList.canRedact(currentModel) ?
+ [model] :
+
+ []
+ }
+
icon.name: "remove-message"
text: qsTr("Remove")
enabled: properties.eventSenderAndIds.length
@@ -254,16 +263,6 @@ HColumnLayout {
! chat.roomInfo.can_redact_all &&
events.length < eventList.selectedCount
})
-
- readonly property var events: {
- eventList.selectedCount ?
- eventList.redactableCheckedEvents :
-
- eventList.canRedact(currentModel) ?
- [model] :
-
- []
- }
}
HMenuItem {
diff --git a/src/gui/Pages/Chat/Timeline/EventFile.qml b/src/gui/Pages/Chat/Timeline/EventFile.qml
index 950b15f2..6cb7b8cd 100644
--- a/src/gui/Pages/Chat/Timeline/EventFile.qml
+++ b/src/gui/Pages/Chat/Timeline/EventFile.qml
@@ -8,6 +8,15 @@ import "../../../Base/HTile"
HTile {
id: file
+
+ property EventMediaLoader loader
+
+ readonly property bool cryptDict:
+ JSON.parse(loader.singleMediaInfo.media_crypt_dict)
+
+ readonly property bool isEncrypted: ! utils.isEmptyObject(cryptDict)
+
+
width: Math.min(
eventDelegate.width,
eventContent.maxMessageWidth,
@@ -55,15 +64,6 @@ HTile {
]
}
-
- property EventMediaLoader loader
-
- readonly property bool cryptDict:
- JSON.parse(loader.singleMediaInfo.media_crypt_dict)
-
- readonly property bool isEncrypted: ! utils.isEmptyObject(cryptDict)
-
-
Binding on backgroundColor {
value: theme.chat.message.checkedBackground
when: eventDelegate.checked
diff --git a/src/gui/Pages/Chat/Timeline/EventImage.qml b/src/gui/Pages/Chat/Timeline/EventImage.qml
index 248fedfd..2269f249 100644
--- a/src/gui/Pages/Chat/Timeline/EventImage.qml
+++ b/src/gui/Pages/Chat/Timeline/EventImage.qml
@@ -5,24 +5,6 @@ import "../../../Base"
HMxcImage {
id: image
- width: fitSize.width
- height: fitSize.height
- horizontalAlignment: Image.AlignLeft
- enabledAnimatedPausing: ! eventList.selectedCount
-
- title: thumbnail ? loader.thumbnailTitle : loader.title
- animated: loader.singleMediaInfo.media_mime === "image/gif" ||
- utils.urlExtension(loader.mediaUrl).toLowerCase() === "gif"
- thumbnail: ! animated && loader.thumbnailMxc
- mxc: thumbnail ?
- (loader.thumbnailMxc || loader.mediaUrl) :
- (loader.mediaUrl || loader.thumbnailMxc)
- cryptDict: JSON.parse(
- thumbnail && loader.thumbnailMxc ?
- loader.singleMediaInfo.thumbnail_crypt_dict :
- loader.singleMediaInfo.media_crypt_dict
- )
-
property EventMediaLoader loader
@@ -61,7 +43,6 @@ HMxcImage {
Math.max(maxHeight, theme.chat.message.thumbnailMinSize.height),
)
-
function getOpenUrl(callback) {
if (image.isEncrypted && loader.mediaUrl) {
loader.download(callback)
@@ -82,6 +63,24 @@ HMxcImage {
}
+ width: fitSize.width
+ height: fitSize.height
+ horizontalAlignment: Image.AlignLeft
+ enabledAnimatedPausing: ! eventList.selectedCount
+
+ title: thumbnail ? loader.thumbnailTitle : loader.title
+ animated: loader.singleMediaInfo.media_mime === "image/gif" ||
+ utils.urlExtension(loader.mediaUrl).toLowerCase() === "gif"
+ thumbnail: ! animated && loader.thumbnailMxc
+ mxc: thumbnail ?
+ (loader.thumbnailMxc || loader.mediaUrl) :
+ (loader.mediaUrl || loader.thumbnailMxc)
+ cryptDict: JSON.parse(
+ thumbnail && loader.thumbnailMxc ?
+ loader.singleMediaInfo.thumbnail_crypt_dict :
+ loader.singleMediaInfo.media_crypt_dict
+ )
+
TapHandler {
acceptedModifiers: Qt.NoModifier
onTapped:
diff --git a/src/gui/Pages/Chat/Timeline/EventImageTextBubble.qml b/src/gui/Pages/Chat/Timeline/EventImageTextBubble.qml
index 196506b2..98d685e7 100644
--- a/src/gui/Pages/Chat/Timeline/EventImageTextBubble.qml
+++ b/src/gui/Pages/Chat/Timeline/EventImageTextBubble.qml
@@ -5,6 +5,7 @@ import "../../../Base"
HLabel {
id: bubble
+
anchors.margins: theme.spacing / 4
topPadding: theme.spacing / 2
diff --git a/src/gui/Pages/Chat/Timeline/EventList.qml b/src/gui/Pages/Chat/Timeline/EventList.qml
index 92c00c09..75c1c902 100644
--- a/src/gui/Pages/Chat/Timeline/EventList.qml
+++ b/src/gui/Pages/Chat/Timeline/EventList.qml
@@ -10,12 +10,11 @@ import "../../../PythonBridge"
import "../../../ShortcutBundles"
Rectangle {
- color: theme.chat.eventList.background
-
-
property alias eventList: eventList
+ color: theme.chat.eventList.background
+
HShortcut {
sequences: window.settings.keys.unfocusOrDeselectAllMessages
onActivated: {
@@ -52,6 +51,27 @@ Rectangle {
}
HShortcut {
+ readonly property var events:
+ eventList.selectedCount ?
+ eventList.redactableCheckedEvents :
+
+ eventList.currentItem &&
+ eventList.canRedact(eventList.currentItem.currentModel) ?
+ [eventList.currentItem.currentModel] :
+
+ eventList.currentItem ?
+ [] :
+ null
+
+ function findLastRemovableDelegate() {
+ for (let i = 0; i < eventList.model.count && i <= 1000; i++) {
+ const event = eventList.model.get(i)
+ if (eventList.canRedact(event) &&
+ mainUI.accountIds.includes(event.sender_id)) return [event]
+ }
+ return []
+ }
+
enabled: (events && events.length > 0) || events === null
sequences: window.settings.keys.removeFocusedOrSelectedMessages
onActivated: utils.makePopup(
@@ -73,27 +93,6 @@ Rectangle {
events.length < eventList.selectedCount
}
)
-
- readonly property var events:
- eventList.selectedCount ?
- eventList.redactableCheckedEvents :
-
- eventList.currentItem &&
- eventList.canRedact(eventList.currentItem.currentModel) ?
- [eventList.currentItem.currentModel] :
-
- eventList.currentItem ?
- [] :
- null
-
- function findLastRemovableDelegate() {
- for (let i = 0; i < eventList.model.count && i <= 1000; i++) {
- const event = eventList.model.get(i)
- if (eventList.canRedact(event) &&
- mainUI.accountIds.includes(event.sender_id)) return [event]
- }
- return []
- }
}
HShortcut {
@@ -181,67 +180,6 @@ Rectangle {
HListView {
id: eventList
- anchors.fill: parent
- clip: true
- keyNavigationWraps: false
- leftMargin: theme.spacing
- rightMargin: theme.spacing
- topMargin: theme.spacing
- bottomMargin: theme.spacing
- verticalLayoutDirection: ListView.BottomToTop
-
- // Keep x scroll pages cached, to limit images having to be
- // reloaded from network.
- cacheBuffer: Screen.desktopAvailableHeight * 2
-
- model: ModelStore.get(chat.userId, chat.roomId, "events")
- delegate: EventDelegate {}
-
- highlight: Rectangle {
- color: theme.chat.message.focusedHighlight
- opacity: theme.chat.message.focusedHighlightOpacity
- }
-
- // Since the list is BottomToTop, this is actually a header
- footer: Item {
- width: eventList.width
- height: (button.height + theme.spacing * 2) * opacity
- opacity: eventList.loading ? 1 : 0
- visible: opacity > 0
-
- Behavior on opacity { HNumberAnimation {} }
-
- HButton {
- readonly property bool offline:
- chat.userInfo.presence === "offline"
-
- id: button
- width: Math.min(parent.width, implicitWidth)
- anchors.centerIn: parent
-
- loading: parent.visible && ! offline
- icon.name: offline ? "feature-unavailable-offline" : ""
- icon.color:
- offline ?
- theme.colors.negativeBackground :
- theme.icons.colorize
- text:
- offline ?
- qsTr("Cannot load history offline") :
- qsTr("Loading previous messages...")
-
- enableRadius: true
- iconItem.small: true
- }
- }
-
- onYPosChanged:
- if (canLoad && yPos < 0.1) Qt.callLater(loadPastEvents)
-
- // When an invited room becomes joined, we should now be able to
- // fetch past events.
- onInviterChanged: canLoad = true
-
property string inviter: chat.roomInfo.inviter || ""
property real yPos: visibleArea.yPosition
@@ -261,7 +199,6 @@ Rectangle {
readonly property var redactableCheckedEvents:
getSortedChecked().filter(ev => eventList.canRedact(ev))
-
function copySelectedDelegates() {
if (eventList.selectedText) {
Clipboard.text = eventList.selectedText
@@ -362,6 +299,67 @@ Rectangle {
return
}
}
+
+ anchors.fill: parent
+ clip: true
+ keyNavigationWraps: false
+ leftMargin: theme.spacing
+ rightMargin: theme.spacing
+ topMargin: theme.spacing
+ bottomMargin: theme.spacing
+ verticalLayoutDirection: ListView.BottomToTop
+
+ // Keep x scroll pages cached, to limit images having to be
+ // reloaded from network.
+ cacheBuffer: Screen.desktopAvailableHeight * 2
+
+ model: ModelStore.get(chat.userId, chat.roomId, "events")
+ delegate: EventDelegate {}
+
+ highlight: Rectangle {
+ color: theme.chat.message.focusedHighlight
+ opacity: theme.chat.message.focusedHighlightOpacity
+ }
+
+ // Since the list is BottomToTop, this is actually a header
+ footer: Item {
+ width: eventList.width
+ height: (button.height + theme.spacing * 2) * opacity
+ opacity: eventList.loading ? 1 : 0
+ visible: opacity > 0
+
+ Behavior on opacity { HNumberAnimation {} }
+
+ HButton {
+ readonly property bool offline:
+ chat.userInfo.presence === "offline"
+
+ id: button
+ width: Math.min(parent.width, implicitWidth)
+ anchors.centerIn: parent
+
+ loading: parent.visible && ! offline
+ icon.name: offline ? "feature-unavailable-offline" : ""
+ icon.color:
+ offline ?
+ theme.colors.negativeBackground :
+ theme.icons.colorize
+ text:
+ offline ?
+ qsTr("Cannot load history offline") :
+ qsTr("Loading previous messages...")
+
+ enableRadius: true
+ iconItem.small: true
+ }
+ }
+
+ onYPosChanged:
+ if (canLoad && yPos < 0.1) Qt.callLater(loadPastEvents)
+
+ // When an invited room becomes joined, we should now be able to
+ // fetch past events.
+ onInviterChanged: canLoad = true
}
Timer {
diff --git a/src/gui/Pages/Chat/Timeline/EventMediaLoader.qml b/src/gui/Pages/Chat/Timeline/EventMediaLoader.qml
index 472e86e0..bbbf5ca4 100644
--- a/src/gui/Pages/Chat/Timeline/EventMediaLoader.qml
+++ b/src/gui/Pages/Chat/Timeline/EventMediaLoader.qml
@@ -5,21 +5,6 @@ import "../../../Base"
HLoader {
id: loader
- visible: Boolean(item)
- x: eventContent.spacing
-
- onTypeChanged: {
- if (type === EventDelegate.Media.Image) {
- var file = "EventImage.qml"
-
- } else if (type !== EventDelegate.Media.Page) {
- var file = "EventFile.qml"
-
- } else { return }
-
- loader.setSource(file, {loader})
- }
-
property QtObject singleMediaInfo
property string mediaUrl
@@ -87,7 +72,6 @@ HLoader {
readonly property string thumbnailMxc: singleMediaInfo.thumbnail_url
-
function download(callback) {
if (! loader.mediaUrl.startsWith("mxc://")) {
downloadedPath = loader.mediaUrl
@@ -109,4 +93,20 @@ HLoader {
callback(path)
})
}
+
+
+ visible: Boolean(item)
+ x: eventContent.spacing
+
+ onTypeChanged: {
+ if (type === EventDelegate.Media.Image) {
+ var file = "EventImage.qml"
+
+ } else if (type !== EventDelegate.Media.Page) {
+ var file = "EventFile.qml"
+
+ } else { return }
+
+ loader.setSource(file, {loader})
+ }
}
diff --git a/src/gui/Pages/Chat/TypingMembersBar.qml b/src/gui/Pages/Chat/TypingMembersBar.qml
index 2173bde6..47436b3d 100644
--- a/src/gui/Pages/Chat/TypingMembersBar.qml
+++ b/src/gui/Pages/Chat/TypingMembersBar.qml
@@ -5,6 +5,9 @@ import QtQuick.Layouts 1.12
import "../../Base"
InfoBar {
+ property var typingMembers: []
+
+
color: theme.chat.typingMembers.background
icon.svgName: "typing" // TODO: animate
label.textFormat: Text.StyledText
@@ -17,7 +20,4 @@ InfoBar {
return qsTr("%1 and %2 are typing...")
.arg(tm.slice(0, -1).join(", ")).arg(tm.slice(-1)[0])
}
-
-
- property var typingMembers: []
}
diff --git a/src/gui/Popups/ClearMessagesPopup.qml b/src/gui/Popups/ClearMessagesPopup.qml
index e982c1d8..14b890ce 100644
--- a/src/gui/Popups/ClearMessagesPopup.qml
+++ b/src/gui/Popups/ClearMessagesPopup.qml
@@ -7,7 +7,6 @@ import "../Base/Buttons"
HFlickableColumnPopup {
id: popup
-
property string userId: ""
property string roomId: ""
property var preClearCallback: null
diff --git a/src/gui/Popups/DeleteDevicesPopup.qml b/src/gui/Popups/DeleteDevicesPopup.qml
index 0983afd0..b226c619 100644
--- a/src/gui/Popups/DeleteDevicesPopup.qml
+++ b/src/gui/Popups/DeleteDevicesPopup.qml
@@ -8,14 +8,12 @@ import "../PythonBridge"
PasswordPopup {
id: popup
-
property string userId
property var deviceIds // array
property var deletedCallback: null
property Future deleteFuture: null
-
function verifyPassword(pass, callback) {
deleteFuture = py.callClientCoro(
userId,
@@ -35,6 +33,7 @@ PasswordPopup {
)
}
+
summary.text:
qsTr("Enter your account's password to continue:")
diff --git a/src/gui/Popups/ForgetRoomPopup.qml b/src/gui/Popups/ForgetRoomPopup.qml
index 503bc3b0..a6656308 100644
--- a/src/gui/Popups/ForgetRoomPopup.qml
+++ b/src/gui/Popups/ForgetRoomPopup.qml
@@ -7,14 +7,12 @@ import "../Base/Buttons"
HFlickableColumnPopup {
id: popup
-
property string userId: ""
property string roomId: ""
property string roomName: ""
property bool canDestroy: false
-
function forget() {
py.callClientCoro(userId, "room_forget", [roomId], () => {
if (window.uiState.page === "Pages/Chat/Chat.qml" &&
@@ -49,7 +47,6 @@ HFlickableColumnPopup {
onOpened: forgetButton.forceActiveFocus()
onClosed: if (canDestroy) Qt.callLater(popup.destroy)
-
SummaryLabel {
text: qsTr("Leave %1 and lose the history?").arg(roomName)
textFormat: Text.StyledText
diff --git a/src/gui/Popups/HColumnPopup.qml b/src/gui/Popups/HColumnPopup.qml
index a800a781..ddfd4f45 100644
--- a/src/gui/Popups/HColumnPopup.qml
+++ b/src/gui/Popups/HColumnPopup.qml
@@ -6,8 +6,8 @@ import "../Base"
HPopup {
id: popup
-
default property alias pageData: page.columnData
+
readonly property alias page: page
signal keyboardAccept()
diff --git a/src/gui/Popups/HFlickableColumnPopup.qml b/src/gui/Popups/HFlickableColumnPopup.qml
index 970289f9..0cfef004 100644
--- a/src/gui/Popups/HFlickableColumnPopup.qml
+++ b/src/gui/Popups/HFlickableColumnPopup.qml
@@ -6,8 +6,8 @@ import "../Base"
HPopup {
id: popup
-
default property alias pageData: page.columnData
+
readonly property alias page: page
signal keyboardAccept()
diff --git a/src/gui/Popups/InviteToRoomPopup.qml b/src/gui/Popups/InviteToRoomPopup.qml
index a9ae7f36..56e9adbe 100644
--- a/src/gui/Popups/InviteToRoomPopup.qml
+++ b/src/gui/Popups/InviteToRoomPopup.qml
@@ -9,7 +9,6 @@ import "../Base/Buttons"
HColumnPopup {
id: popup
-
property string userId
property string roomId
property string roomName
@@ -19,7 +18,6 @@ HColumnPopup {
property var successfulInvites: []
property var failedInvites: []
-
function invite() {
inviteButton.loading = true
@@ -67,7 +65,6 @@ HColumnPopup {
onInvitingAllowedChanged:
if (! invitingAllowed && inviteFuture) inviteFuture.cancel()
-
SummaryLabel {
text: qsTr("Invite members to %1").arg(roomName)
textFormat: Text.StyledText
@@ -89,16 +86,6 @@ HColumnPopup {
HLabel {
id: errorMessage
- visible: Layout.maximumHeight > 0
- wrapMode: Text.Wrap
- color: theme.colors.errorText
- text:
- invitingAllowed ?
- allErrors :
- qsTr("You do not have permission to invite members to this room")
-
- Layout.maximumHeight: text ? implicitHeight : 0
- Layout.fillWidth: true
readonly property string allErrors: {
// TODO: handle these: real user not found
@@ -142,6 +129,17 @@ HColumnPopup {
return lines.join("\n\n")
}
+ visible: Layout.maximumHeight > 0
+ wrapMode: Text.Wrap
+ color: theme.colors.errorText
+ text:
+ invitingAllowed ?
+ allErrors :
+ qsTr("You do not have permission to invite members to this room")
+
+ Layout.maximumHeight: text ? implicitHeight : 0
+ Layout.fillWidth: true
+
Behavior on Layout.maximumHeight { HNumberAnimation {} }
}
}
diff --git a/src/gui/Popups/KeyVerificationPopup.qml b/src/gui/Popups/KeyVerificationPopup.qml
index c3c59fed..6cab3e6c 100644
--- a/src/gui/Popups/KeyVerificationPopup.qml
+++ b/src/gui/Popups/KeyVerificationPopup.qml
@@ -8,7 +8,6 @@ import "../Base/Buttons"
HFlickableColumnPopup {
id: popup
-
property string deviceOwner
property string deviceId
property string deviceName
@@ -76,6 +75,8 @@ HFlickableColumnPopup {
}
HTextArea {
+ id: infoArea
+
function formatInfo(info, value) {
return (
`
` + @@ -86,7 +87,6 @@ HFlickableColumnPopup { ) } - id: infoArea readOnly: true wrapMode: HSelectableLabel.Wrap textFormat: Qt.RichText diff --git a/src/gui/Popups/LeaveRoomPopup.qml b/src/gui/Popups/LeaveRoomPopup.qml index 2891813c..5d4fa442 100644 --- a/src/gui/Popups/LeaveRoomPopup.qml +++ b/src/gui/Popups/LeaveRoomPopup.qml @@ -7,7 +7,6 @@ import "../Base/Buttons" HFlickableColumnPopup { id: popup - property string userId: "" property string roomId: "" property string roomName: "" @@ -33,7 +32,6 @@ HFlickableColumnPopup { onOpened: leaveButton.forceActiveFocus() - SummaryLabel { text: qsTr("Leave %1?").arg(roomName) textFormat: Text.StyledText diff --git a/src/gui/Popups/PasswordPopup.qml b/src/gui/Popups/PasswordPopup.qml index b064fecd..35e1e419 100644 --- a/src/gui/Popups/PasswordPopup.qml +++ b/src/gui/Popups/PasswordPopup.qml @@ -8,7 +8,6 @@ import "../Base/Buttons" HFlickableColumnPopup { id: popup - property bool validateWhileTyping: false property string acceptedPassword: "" @@ -21,7 +20,6 @@ HFlickableColumnPopup { signal cancelled() - function verifyPassword(pass, callback) { // Can be reimplemented when using this component. // Pass to the callback true on success, false on invalid password, @@ -77,7 +75,6 @@ HFlickableColumnPopup { onOpened: passwordField.forceActiveFocus() onKeyboardAccept: popup.validate() - SummaryLabel { id: summary } DetailsLabel { id: details } diff --git a/src/gui/Popups/RedactPopup.qml b/src/gui/Popups/RedactPopup.qml index 0bc8d8c1..87be185b 100644 --- a/src/gui/Popups/RedactPopup.qml +++ b/src/gui/Popups/RedactPopup.qml @@ -8,7 +8,6 @@ import "../Base/Buttons" HFlickableColumnPopup { id: popup - property string preferUserId: "" property string roomId: "" @@ -16,7 +15,6 @@ HFlickableColumnPopup { property bool onlyOwnMessageWarning: false property bool isLast: false - function remove() { const idsForSender = {} // {senderId: [event.id, ...]} @@ -53,7 +51,6 @@ HFlickableColumnPopup { onOpened: reasonField.item.forceActiveFocus() onKeyboardAccept: popup.remove() - SummaryLabel { text: isLast ? diff --git a/src/gui/Popups/RemoveMemberPopup.qml b/src/gui/Popups/RemoveMemberPopup.qml index a4f94936..deb2cba4 100644 --- a/src/gui/Popups/RemoveMemberPopup.qml +++ b/src/gui/Popups/RemoveMemberPopup.qml @@ -8,7 +8,6 @@ import "../Base/Buttons" HFlickableColumnPopup { id: popup - property string userId property string roomId property string targetUserId @@ -50,7 +49,6 @@ HFlickableColumnPopup { onOpened: reasonField.item.forceActiveFocus() onKeyboardAccept: popup.remove() - SummaryLabel { textFormat: Text.StyledText text: diff --git a/src/gui/Popups/SignOutPopup.qml b/src/gui/Popups/SignOutPopup.qml index b3f7e08a..0f31faab 100644 --- a/src/gui/Popups/SignOutPopup.qml +++ b/src/gui/Popups/SignOutPopup.qml @@ -8,7 +8,6 @@ import "../Base/Buttons" HFlickableColumnPopup { id: popup - property string userId: "" @@ -54,7 +53,6 @@ HFlickableColumnPopup { onOpened: exportButton.forceActiveFocus() - SummaryLabel { text: qsTr("Backup your decryption keys before signing out?") } diff --git a/src/gui/Popups/UnexpectedErrorPopup.qml b/src/gui/Popups/UnexpectedErrorPopup.qml index da49a087..71c9d043 100644 --- a/src/gui/Popups/UnexpectedErrorPopup.qml +++ b/src/gui/Popups/UnexpectedErrorPopup.qml @@ -9,7 +9,6 @@ import "../Base/Buttons" HColumnPopup { id: popup - property string errorType property string message: "" property string traceback: "" @@ -31,7 +30,6 @@ HColumnPopup { onOpened: cancelButton.forceActiveFocus() - SummaryLabel { text: qsTr("Unexpected error occured: %1").arg(errorType) textFormat: Text.StyledText diff --git a/src/gui/PythonBridge/EventHandlers.qml b/src/gui/PythonBridge/EventHandlers.qml index 162d9e18..4a118c4b 100644 --- a/src/gui/PythonBridge/EventHandlers.qml +++ b/src/gui/PythonBridge/EventHandlers.qml @@ -7,12 +7,10 @@ import "../.." QtObject { signal deviceUpdateSignal(string forAccount) - function onExitRequested(exitCode) { Qt.exit(exitCode) } - function onAlertRequested(highImportance) { const msec = highImportance ? @@ -24,7 +22,6 @@ QtObject { } } - function onCoroutineDone(uuid, result, error, traceback) { const onSuccess = Globals.pendingCoroutines[uuid].onSuccess const onError = Globals.pendingCoroutines[uuid].onError @@ -48,14 +45,12 @@ QtObject { if (onSuccess) onSuccess(result) } - function onLoopException(message, error, traceback) { // No need to log these here, the asyncio exception handler does it const type = py.getattr(py.getattr(error, "__class__"), "__name__") utils.showError(type, traceback, message) } - function onModelItemSet(syncId, indexThen, indexNow, changedFields){ if (indexThen === undefined) { // print("insert", syncId, indexThen, indexNow, @@ -74,19 +69,16 @@ QtObject { } } - function onModelItemDeleted(syncId, index, count=1) { // print("delete", syncId, index, count) ModelStore.get(syncId).remove(index, count) } - function onModelCleared(syncId) { // print("clear", syncId) ModelStore.get(syncId).clear() } - function onDevicesUpdated(forAccount) { deviceUpdateSignal(forAccount) } diff --git a/src/gui/PythonBridge/Future.qml b/src/gui/PythonBridge/Future.qml index d9a6a102..c6029a53 100644 --- a/src/gui/PythonBridge/Future.qml +++ b/src/gui/PythonBridge/Future.qml @@ -5,16 +5,14 @@ import QtQuick 2.12 QtObject { id: future - property PythonBridge bridge readonly property QtObject privates: QtObject { - onPythonFutureChanged: if (cancelPending) future.cancel() - property var pythonFuture: null property bool cancelPending: false - } + onPythonFutureChanged: if (cancelPending) future.cancel() + } function cancel() { if (! privates.pythonFuture) { diff --git a/src/gui/PythonBridge/PythonBridge.qml b/src/gui/PythonBridge/PythonBridge.qml index 9a09fd4a..71aa974d 100644 --- a/src/gui/PythonBridge/PythonBridge.qml +++ b/src/gui/PythonBridge/PythonBridge.qml @@ -8,10 +8,8 @@ import "." Python { id: py - readonly property var pendingCoroutines: Globals.pendingCoroutines - function makeFuture(callback) { return Qt.createComponent("Future.qml").createObject(py, {bridge: py}) } diff --git a/src/gui/PythonBridge/PythonRootBridge.qml b/src/gui/PythonBridge/PythonRootBridge.qml index 1b233e34..5c17eecb 100644 --- a/src/gui/PythonBridge/PythonRootBridge.qml +++ b/src/gui/PythonBridge/PythonRootBridge.qml @@ -4,6 +4,12 @@ import QtQuick 2.12 import "." PythonBridge { + property bool ready: false + property bool startupAnyAccountsSaved: false + + readonly property EventHandlers eventHandlers: EventHandlers {} + + Component.onCompleted: { for (var func in eventHandlers) { if (! eventHandlers.hasOwnProperty(func)) continue @@ -25,10 +31,4 @@ PythonBridge { }) }) } - - - property bool ready: false - property bool startupAnyAccountsSaved: false - - readonly property EventHandlers eventHandlers: EventHandlers {} } diff --git a/src/gui/ShortcutBundles/FlickShortcuts.qml b/src/gui/ShortcutBundles/FlickShortcuts.qml index e64ecdab..239007bf 100644 --- a/src/gui/ShortcutBundles/FlickShortcuts.qml +++ b/src/gui/ShortcutBundles/FlickShortcuts.qml @@ -6,7 +6,6 @@ import "../Base" HQtObject { id: root - property Item flickable: parent property bool active: true diff --git a/src/gui/ShortcutBundles/TabShortcuts.qml b/src/gui/ShortcutBundles/TabShortcuts.qml index 52759de8..791cd9a9 100644 --- a/src/gui/ShortcutBundles/TabShortcuts.qml +++ b/src/gui/ShortcutBundles/TabShortcuts.qml @@ -6,7 +6,6 @@ import "../Base" HQtObject { id: root - property Item container: parent property bool active: container.count > 1 diff --git a/src/gui/UI.qml b/src/gui/UI.qml index fe4c9ec7..73e670ea 100644 --- a/src/gui/UI.qml +++ b/src/gui/UI.qml @@ -10,10 +10,6 @@ import "MainPane" Item { id: mainUI - focus: true - - Component.onCompleted: window.mainUI = mainUI - property bool accountsPresent: ModelStore.get("accounts").count > 0 || py.startupAnyAccountsSaved @@ -35,12 +31,14 @@ Item { readonly property alias fontMetrics: fontMetrics readonly property alias idleManager: idleManager - function reloadSettings() { py.loadSettings(() => { mainUI.pressAnimation.start() }) } + focus: true + Component.onCompleted: window.mainUI = mainUI + SequentialAnimation { id: pressAnimation HNumberAnimation { diff --git a/src/gui/Window.qml b/src/gui/Window.qml index f05cd85d..f3022f25 100644 --- a/src/gui/Window.qml +++ b/src/gui/Window.qml @@ -7,14 +7,6 @@ import "PythonBridge" ApplicationWindow { id: window - flags: Qt.WA_TranslucentBackground - minimumWidth: theme ? theme.minimumSupportedWidth : 240 - minimumHeight: theme ? theme.minimumSupportedHeight : 120 - width: Math.min(screen.width, 1152) - height: Math.min(screen.height, 768) - visible: true - color: "transparent" - // FIXME: Qt 5.13.1 bug, this randomly stops updating after the cursor // leaves the window until it's clicked again. @@ -26,20 +18,10 @@ ApplicationWindow { window.visibility === window.Minimized || window.visibility === window.Hidden - // NOTE: For JS object variables, the corresponding method to notify - // key/value changes must be called manually, e.g. settingsChanged(). - property var mainUI: null - property var settings: ({}) - onSettingsChanged: py.saveConfig("ui_settings", settings) - property var uiState: ({}) - onUiStateChanged: py.saveConfig("ui_state", uiState) - property var history: ({}) - onHistoryChanged: py.saveConfig("history", history) - property var theme: null property var hideErrorTypes: new Set(["gaierror", "SSLError"]) @@ -77,6 +59,20 @@ ApplicationWindow { } + flags: Qt.WA_TranslucentBackground + minimumWidth: theme ? theme.minimumSupportedWidth : 240 + minimumHeight: theme ? theme.minimumSupportedHeight : 120 + width: Math.min(screen.width, 1152) + height: Math.min(screen.height, 768) + visible: true + color: "transparent" + + // NOTE: For JS object variables, the corresponding method to notify + // key/value changes must be called manually, e.g. settingsChanged(). + onSettingsChanged: py.saveConfig("ui_settings", settings) + onUiStateChanged: py.saveConfig("ui_state", uiState) + onHistoryChanged: py.saveConfig("history", history) + PythonRootBridge { id: py } Utils { id: utils }