Organize project files

Put QML components into folders, remove unused ones, split __init__.py
with engine.py.
This commit is contained in:
miruka
2019-03-26 05:52:43 -04:00
parent cccc43a9ae
commit 76b699ad64
28 changed files with 117 additions and 174 deletions

View File

@@ -0,0 +1,39 @@
import QtQuick.Controls 1.4 as Controls1
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
import "side_pane" as SidePane
import "chat" as Chat
//https://doc.qt.io/qt-5/qml-qtquick-controls-splitview.html
Controls1.SplitView {
anchors.fill: parent
SidePane.Root {
Layout.minimumWidth: 36
width: 200
}
StackView {
function show_page(componentName) {
pageStack.replace(componentName + ".qml")
}
function show_room(user_obj, room_obj) {
pageStack.replace(
"chat/Root.qml", { user: user_obj, room: room_obj }
)
}
id: "pageStack"
initialItem: Chat.Root {
user: Backend.accountsModel.get(0)
room: Backend.roomsModel[Backend.accountsModel.get(0).user_id].get(0)
}
onCurrentItemChanged: currentItem.forceActiveFocus()
// Buggy
replaceExit: null
popExit: null
pushExit: null
}
}

View File

@@ -0,0 +1,15 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
ApplicationWindow {
visible: true
width: 640
height: 700
title: "Harmony QML"
Loader {
anchors.fill: parent
source: "UI.qml"
objectName: "UILoader"
}
}

View File

@@ -0,0 +1,40 @@
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.4
Item {
property bool invisible: false
property string username: "?"
property var imageSource: null
property int dimmension: 48
id: root
width: dimmension
height: invisible ? 1 : dimmension
Rectangle {
id: letterRectangle
anchors.fill: parent
visible: ! invisible && imageSource === null
color: Qt.hsla(Backend.hueFromString(username), 0.22, 0.5, 1)
HLabel {
anchors.centerIn: parent
text: username.charAt(0)
color: "white"
font.pixelSize: letterRectangle.height / 1.4
}
}
Image {
id: avatarImage
anchors.fill: parent
visible: ! invisible && imageSource !== null
Component.onCompleted: if (imageSource) {source = imageSource}
asynchronous: true
mipmap: true
fillMode: Image.PreserveAspectCrop
sourceSize.width: root.dimmension
}
}

View File

@@ -0,0 +1,12 @@
import QtQuick 2.7
import QtQuick.Controls 2.0
Label {
property int bigSize: 24
property int normalSize: 16
property int smallSize: 12
font.family: "Roboto"
font.pixelSize: normalSize
textFormat: Text.PlainText
}

View File

@@ -0,0 +1,31 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
ToolButton {
property string tooltip: ""
property string iconName: ""
id: "button"
display: ToolButton.IconOnly
icon.source: "../../icons/" + iconName + ".svg"
background: Rectangle { color: "transparent" }
onClicked: toolTip.hide()
ToolTip {
id: "toolTip"
text: tooltip
delay: Qt.styleHints.mousePressAndHoldInterval
visible: text ? toolTipZone.containsMouse : false
}
MouseArea {
id: "toolTipZone"
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.NoButton // Make button receive clicks normally
onEntered: button.background.color = "#656565"
onExited: button.background.color = "transparent"
}
}

View File

@@ -0,0 +1,16 @@
import QtQuick 2.7
import QtQuick.Controls 2.0
HLabel {
id: text
ToolTip {
delay: Qt.styleHints.mousePressAndHoldInterval
visible: text ? toolTipZone.containsMouse : false
text: user_id
}
MouseArea {
id: toolTipZone
anchors.fill: parent
hoverEnabled: true
}
}

View File

@@ -0,0 +1,12 @@
import QtQuick 2.7
import "../base" as Base
Base.HLabel {
text: date_time.toLocaleDateString()
width: rootCol.width
horizontalAlignment: Text.AlignHCenter
topPadding: rootCol.isFirstMessage ? 0 : rootCol.verticalPadding * 4
bottomPadding: rootCol.verticalPadding * 2
font.pixelSize: normalSize * 1.1
color: "darkolivegreen"
}

View File

@@ -0,0 +1,107 @@
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.4
import "../base" as Base
Column {
id: rootCol
function mins_between(date1, date2) {
return Math.round((((date2 - date1) % 86400000) % 3600000) / 60000)
}
readonly property string displayName:
Backend.getUser(sender_id).display_name
readonly property bool isOwn:
chatPage.user.user_id === sender_id
readonly property var previousData:
index > 0 ? messageListView.model.get(index - 1) : null
readonly property bool isFirstMessage: ! previousData
readonly property bool combine:
! isFirstMessage &&
previousData.sender_id == sender_id &&
mins_between(previousData.date_time, date_time) <= 5
readonly property bool dayBreak:
isFirstMessage ||
previousData.date_time.getDay() != date_time.getDay()
readonly property bool talkBreak:
! isFirstMessage &&
! dayBreak &&
mins_between(previousData.date_time, date_time) >= 20
property int standardSpacing: 8
property int horizontalPadding: 7
property int verticalPadding: 5
width: parent.width
topPadding:
previousData === null ? 0 :
talkBreak ? standardSpacing * 6 :
combine ? standardSpacing / 2 :
standardSpacing * 1.2
Daybreak { visible: dayBreak }
Row {
id: row
spacing: standardSpacing
layoutDirection: isOwn ? Qt.RightToLeft : Qt.LeftToRight
anchors.right: isOwn ? parent.right : undefined
Base.Avatar { id: avatar; invisible: combine; username: displayName }
ColumnLayout {
spacing: 0
Base.HLabel {
visible: ! combine
id: nameLabel
text: displayName
background: Rectangle {color: "#DDD"}
color: isOwn ? "teal" : "purple"
elide: Text.ElideRight
maximumLineCount: 1
Layout.preferredWidth: contentLabel.width
horizontalAlignment: isOwn ? Text.AlignRight : Text.AlignLeft
leftPadding: horizontalPadding
rightPadding: horizontalPadding
topPadding: verticalPadding
}
Base.HLabel {
id: contentLabel
//text: (isOwn ? "" : content + "&nbsp;&nbsp;") +
//"<font size=" + smallSize + "px color=gray>" +
//Qt.formatDateTime(date_time, "hh:mm:ss") +
//"</font>" +
// (isOwn ? "&nbsp;&nbsp;" + content : "")
text: content +
"&nbsp;&nbsp;<font size=" + smallSize + "px color=gray>" +
Qt.formatDateTime(date_time, "hh:mm:ss") +
"</font>"
textFormat: Text.RichText
background: Rectangle {color: "#DDD"}
wrapMode: Text.Wrap
leftPadding: horizontalPadding
rightPadding: horizontalPadding
bottomPadding: verticalPadding
Layout.minimumWidth: nameLabel.implicitWidth
Layout.maximumWidth: Math.min(
600, messageListView.width - avatar.width - row.spacing
)
}
}
}
}

View File

@@ -0,0 +1,24 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
Rectangle {
property int space: 8
Layout.fillWidth: true
Layout.fillHeight: true
Layout.leftMargin: space
Layout.rightMargin: space
ListView {
id: messageListView
anchors.fill: parent
model: Backend.messagesModel[chatPage.room.room_id]
delegate: MessageDelegate {}
//highlight: Rectangle {color: "lightsteelblue"; radius: 5}
clip: true
topMargin: space
bottomMargin: space
}
}

View File

@@ -0,0 +1,49 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
import "../base" as Base
Rectangle {
id: root
Layout.fillWidth: true
Layout.minimumHeight: 36
Layout.maximumHeight: Layout.minimumHeight
color: "#BBB"
RowLayout {
id: "row"
spacing: 12
anchors.fill: parent
Base.Avatar {
id: "avatar"
Layout.alignment: Qt.AlignTop
dimmension: root.Layout.minimumHeight
username: chatPage.room.display_name
}
Base.HLabel {
id: "roomName"
text: chatPage.room.display_name
font.pixelSize: bigSize
elide: Text.ElideRight
maximumLineCount: 1
Layout.maximumWidth: row.width - row.spacing * (row.children.length - 1) - avatar.width
}
Base.HLabel {
id: "roomSubtitle"
text: chatPage.room.subtitle
font.pixelSize: smallSize
elide: Text.ElideRight
maximumLineCount: 1
Layout.maximumWidth:
row.width -
row.spacing * (row.children.length - 1) -
avatar.width -
roomName.width
}
Item { Layout.fillWidth: true }
}
}

View File

@@ -0,0 +1,16 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
ColumnLayout {
property var user: null
property var room: null
id: chatPage
spacing: 0
onFocusChanged: sendBox.setFocus()
RoomHeader {}
MessageList {}
SendBox { id: sendBox }
}

View File

@@ -0,0 +1,63 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
import "../base" as Base
Rectangle {
function setFocus() { textArea.forceActiveFocus() }
id: "root"
Layout.fillWidth: true
Layout.minimumHeight: 32
Layout.preferredHeight: textArea.implicitHeight
// parent.height / 2 causes binding loop?
Layout.maximumHeight: pageStack.height / 2
color: "#BBB"
RowLayout {
anchors.fill: parent
spacing: 0
Base.Avatar {
id: "avatar"
username: chatPage.user.display_name
dimmension: root.Layout.minimumHeight
//visible: textArea.text === ""
visible: textArea.height <= root.Layout.minimumHeight
}
ScrollView {
Layout.fillHeight: true
Layout.fillWidth: true
id: sendBoxScrollView
clip: true
TextArea {
id: textArea
placeholderText: qsTr("Type a message...")
wrapMode: TextEdit.Wrap
selectByMouse: true
font.family: "Roboto"
font.pixelSize: 16
focus: true
Keys.onReturnPressed: {
event.accepted = true
if (event.modifiers & Qt.ShiftModifier ||
event.modifiers & Qt.ControlModifier ||
event.modifiers & Qt.AltModifier) {
textArea.insert(textArea.cursorPosition, "\n")
return
}
Backend.sendMessage(chatPage.user.user_id,
chatPage.room.room_id,
textArea.text)
textArea.clear()
}
Keys.onEnterPressed: Keys.onReturnPressed(event) // numpad enter
}
}
}
}

View File

@@ -0,0 +1,9 @@
import QtQuick 2.7
import "../base" as Base
Rectangle {
Base.HLabel {
anchors.centerIn: parent
text: "Add account page"
}
}

View File

@@ -0,0 +1,9 @@
import QtQuick 2.7
import "../base" as Base
Rectangle {
Base.HLabel {
anchors.centerIn: parent
text: "Add room page"
}
}

View File

@@ -0,0 +1,9 @@
import QtQuick 2.7
import "../base" as Base
Rectangle {
Base.HLabel {
anchors.centerIn: parent
text: "Home page"
}
}

View File

@@ -0,0 +1,9 @@
import QtQuick 2.7
import "../base" as Base
Rectangle {
Base.HLabel {
anchors.centerIn: parent
text: "Settings page"
}
}

View File

@@ -0,0 +1,85 @@
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.4
import "../base" as Base
ColumnLayout {
id: "accountDelegate"
spacing: 0
width: parent.width
RowLayout {
id: "row"
spacing: 0
Base.Avatar { id: "avatar"; username: display_name; dimmension: 36 }
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 0
Base.HLabel {
id: "accountLabel"
text: display_name
elide: Text.ElideRight
maximumLineCount: 1
Layout.fillWidth: true
leftPadding: 6
rightPadding: leftPadding
}
TextField {
id: "statusEdit"
text: status_message || ""
placeholderText: qsTr("Set status message")
background: null
color: "black"
selectByMouse: true
font.family: "Roboto"
font.pixelSize: 12
Layout.fillWidth: true
padding: 0
leftPadding: accountLabel.leftPadding
rightPadding: leftPadding
onEditingFinished: {
Backend.setStatusMessage(user_id, text)
pageStack.forceActiveFocus()
}
}
}
Base.HToolButton {
id: "toggleExpand"
iconName: roomList.visible ? "up" : "down"
Layout.maximumWidth: 28
Layout.maximumHeight: Layout.maximumWidth
onClicked: {
toggleExpand.ToolTip.hide()
roomList.visible = ! roomList.visible
}
}
}
RoomList {
id: "roomList"
visible: true
user: Backend.getUser(user_id)
Layout.minimumHeight:
roomList.visible ?
roomList.contentHeight + roomList.anchors.margins * 2 :
0
Layout.maximumHeight: Layout.minimumHeight
Layout.minimumWidth: parent.width - Layout.leftMargin * 2
Layout.maximumWidth: Layout.minimumWidth
Layout.margins: accountList.spacing
Layout.leftMargin:
sidePane.width < 36 + Layout.margins ? 0 : Layout.margins
Layout.rightMargin: Layout.leftMargin
}
}

View File

@@ -0,0 +1,11 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
ListView {
id: "accountList"
spacing: 8
model: Backend.accountsModel
delegate: AccountDelegate {}
clip: true
}

View File

@@ -0,0 +1,49 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
import "../base" as Base
RowLayout {
id: "toolBar"
Layout.fillWidth: true
Layout.maximumHeight: 32
spacing: 0
HToolButton {
visible: ! toolBarIsBig()
iconName: "reduced_menu"
tooltip: "Menu"
}
HToolButton {
iconName: "settings"
tooltip: "Settings"
}
HToolButton {
iconName: "add_account"
tooltip: "Add new account"
}
HToolButton {
iconName: "set_status"
tooltip: "Set status for all accounts"
}
HToolButton {
iconName: "search"
tooltip: "Filter rooms"
}
TextField {
id: filterField
visible: false
placeholderText: qsTr("Filter rooms")
selectByMouse: true
font.family: "Roboto"
Layout.fillWidth: true
Layout.fillHeight: true
background: Rectangle { color: "lightgray" }
}
}

View File

@@ -0,0 +1,17 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
import "../base" as Base
Base.HToolButton {
function toolBarIsBig() {
return sidePane.width >
Layout.minimumWidth * (toolBar.children.length - 2)
}
id: "button"
visible: toolBarIsBig()
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumWidth: height
}

View File

@@ -0,0 +1,57 @@
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.4
import "../base" as Base
MouseArea {
id: "root"
width: roomList.width
height: Math.max(roomLabel.height + subtitleLabel.height, avatar.height)
onClicked: pageStack.show_room(
roomList.user,
roomList.model.get(index)
)
RowLayout {
anchors.fill: parent
id: row
spacing: 1
Base.Avatar { id: avatar; username: display_name; dimmension: 36 }
ColumnLayout {
spacing: 0
Base.HLabel {
id: roomLabel
text: display_name
elide: Text.ElideRight
maximumLineCount: 1
Layout.maximumWidth: row.width - row.spacing - avatar.width
verticalAlignment: Qt.AlignVCenter
topPadding: -2
bottomPadding: subtitleLabel.visible ? 0 : topPadding
leftPadding: 5
rightPadding: leftPadding
}
Base.HLabel {
id: subtitleLabel
visible: text !== ""
text: subtitle
font.pixelSize: smallSize
elide: Text.ElideRight
maximumLineCount: 1
Layout.maximumWidth: roomLabel.Layout.maximumWidth
topPadding: -2
bottomPadding: topPadding
leftPadding: 5
rightPadding: leftPadding
}
}
Item { Layout.fillWidth: true }
}
}

View File

@@ -0,0 +1,26 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
import "../base" as Base
ListView {
property var user: null
property int contentHeight: 0
onCountChanged: {
var children = roomList.children
var childrenHeight = 0
for (var i = 0; i < children.length; i++) {
childrenHeight += children[i].height
}
contentHeight = childrenHeight + spacing * (children.length - 1)
}
id: "roomList"
spacing: 8
model: Backend.roomsModel[user.user_id]
delegate: RoomDelegate {}
}

View File

@@ -0,0 +1,22 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
import "../base" as Base
Rectangle {
id: sidePane
color: "gray"
clip: true // Avoid artifacts when resizing pane width to minimum
ColumnLayout {
anchors.fill: parent
spacing: 0
AccountList {
Layout.fillWidth: true
Layout.fillHeight: true
}
HToolBar {}
}
}