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

@ -1,54 +0,0 @@
import QtQuick 2.7
ListModel {
ListElement {
user_id: "@runi:matrix.org"
name: "Runi"
content: "Lorem ipsum"
date: "2019-03-10"
time: "19:41:10"
}
ListElement {
user_id: "@runi:matrix.org"
name: "Runi"
content: "Combine test?"
date: "2019-03-10"
time: "19:41:12"
}
ListElement {
user_id: "@mary:matrix.org"
name: "Mary"
content: "sit dolor amet"
date: "2019-03-10"
time: "19:42:10"
}
ListElement {
user_id: "@runi:matrix.org"
name: "Runi but a very long name test lorem ipsum foo bar flour orange water test"
content: "blah blah"
date: "2019-03-10"
time: "19:43:57"
}
ListElement {
user_id: "@runi:matrix.org"
name: "Runi"
content: "Long message text <b>wxall of text</b> jsqdjlfjlsdjf 1234 zaekfpozekf lorem ipsum foo bar 123 zfjhozj aazaazazaz fdefzef"
date: "2019-03-10"
time: "19:44:10"
}
ListElement {
user_id: "@renko:matrix.org"
name: "Renko"
content: "Baaaar."
date: "2019-03-10"
time: "19:44:22"
}
ListElement {
user_id: "@runi:matrix.org"
name: "Runi"
content: "Test new day"
date: "2019-03-11"
time: "10:10:47"
}
}

View File

@ -1,35 +0,0 @@
import QtQuick 2.7
ListModel {
ListElement {
account: "Runi"
room_name: "Maribel"
description: "This is a test ellide"
}
ListElement {
account: "Runi"
room_name: "Renko"
description: "Away"
}
ListElement {
account: "Runi"
room_name: "Moonlight"
description: "lorem ispum"
}
ListElement {
account: "Runi"
room_name: "test long abc def"
description: "WWWWWW WWWWWW WWWW WWWWWW WWWW"
}
ListElement {
account: "Maribel"
room_name: "Maribel"
description: "This is a test ellide"
}
ListElement {
account: "Maribel"
room_name: "Moonlight"
description: "lorem ispum"
}
}

View File

@ -1,63 +1,16 @@
# Copyright 2019 miruka # Copyright 2019 miruka
# This file is part of harmonyqml, licensed under GPLv3. # This file is part of harmonyqml, licensed under GPLv3.
import logging
import os
import sys import sys
from typing import Optional
from PyQt5.QtCore import (
QFileSystemWatcher, QMetaObject, QObject, QTimer, pyqtSlot
)
from PyQt5.QtGui import QGuiApplication from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine, qmlRegisterType
from .__about__ import __doc__ from .engine import Engine
from .backend import DummyBackend
# logging.basicConfig(level=logging.INFO) # logging.basicConfig(level=logging.INFO)
class Engine(QQmlApplicationEngine):
def __init__(self, app: QGuiApplication, parent: Optional[QObject] = None
) -> None:
super().__init__(parent)
self.app = app
self.backend = DummyBackend()
self.program_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
# Set QML properties
self.rootContext().setContextProperty("Engine", self)
self.rootContext().setContextProperty("Backend", self.backend)
# Connect Qt signals
self.quit.connect(self.app.quit)
# Make SIGINT (ctrl-c) work
self._sigint_timer = QTimer()
self._sigint_timer.timeout.connect(lambda: None)
self._sigint_timer.start(100)
# Setup UI live-reloading when a file is edited
self.file_watcher = QFileSystemWatcher()
self.file_watcher.directoryChanged.connect(lambda _: self.reload_qml())
self.file_watcher.addPath(self.program_dir)
# Load QML page and show window
self.load(os.path.join(self.program_dir, "Window.qml"))
self.rootObjects()[0].show()
sys.exit(self.app.exec())
def reload_qml(self) -> None:
self.clearComponentCache()
loader = self.rootObjects()[0].findChild(QObject, "UILoader")
source = loader.property("source")
loader.setProperty("source", None)
loader.setProperty("source", source)
logging.info("Reloaded: %s", source)
def run() -> None: def run() -> None:
app = QGuiApplication(sys.argv) app = QGuiApplication(sys.argv)
_ = Engine(app) # need to keep a reference engine = Engine(app)
engine.show_window()

View File

@ -1,12 +1,14 @@
import QtQuick.Controls 1.4 as Controls1 import QtQuick.Controls 1.4 as Controls1
import QtQuick.Controls 2.2 import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4 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 //https://doc.qt.io/qt-5/qml-qtquick-controls-splitview.html
Controls1.SplitView { Controls1.SplitView {
anchors.fill: parent anchors.fill: parent
SidePane { SidePane.Root {
Layout.minimumWidth: 36 Layout.minimumWidth: 36
width: 200 width: 200
} }
@ -17,12 +19,12 @@ Controls1.SplitView {
} }
function show_room(user_obj, room_obj) { function show_room(user_obj, room_obj) {
pageStack.replace( pageStack.replace(
"ChatPage.qml", { user: user_obj, room: room_obj } "chat/Root.qml", { user: user_obj, room: room_obj }
) )
} }
id: "pageStack" id: "pageStack"
initialItem: ChatPage { initialItem: Chat.Root {
user: Backend.accountsModel.get(0) user: Backend.accountsModel.get(0)
room: Backend.roomsModel[Backend.accountsModel.get(0).user_id].get(0) room: Backend.roomsModel[Backend.accountsModel.get(0).user_id].get(0)
} }

View File

@ -18,7 +18,7 @@ Item {
visible: ! invisible && imageSource === null visible: ! invisible && imageSource === null
color: Qt.hsla(Backend.hueFromString(username), 0.22, 0.5, 1) color: Qt.hsla(Backend.hueFromString(username), 0.22, 0.5, 1)
PlainLabel { HLabel {
anchors.centerIn: parent anchors.centerIn: parent
text: username.charAt(0) text: username.charAt(0)
color: "white" color: "white"

View File

@ -8,7 +8,7 @@ ToolButton {
id: "button" id: "button"
display: ToolButton.IconOnly display: ToolButton.IconOnly
icon.source: "icons/" + iconName + ".svg" icon.source: "../../icons/" + iconName + ".svg"
background: Rectangle { color: "transparent" } background: Rectangle { color: "transparent" }
onClicked: toolTip.hide() onClicked: toolTip.hide()

View File

@ -1,7 +1,7 @@
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
PlainLabel { HLabel {
id: text id: text
ToolTip { ToolTip {
delay: Qt.styleHints.mousePressAndHoldInterval delay: Qt.styleHints.mousePressAndHoldInterval

View File

@ -1,6 +1,7 @@
import QtQuick 2.7 import QtQuick 2.7
import "../base" as Base
PlainLabel { Base.HLabel {
text: date_time.toLocaleDateString() text: date_time.toLocaleDateString()
width: rootCol.width width: rootCol.width
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter

View File

@ -1,6 +1,7 @@
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQuick.Layouts 1.4 import QtQuick.Layouts 1.4
import "../base" as Base
Column { Column {
id: rootCol id: rootCol
@ -46,7 +47,7 @@ Column {
combine ? standardSpacing / 2 : combine ? standardSpacing / 2 :
standardSpacing * 1.2 standardSpacing * 1.2
DaybreakDelegate { visible: dayBreak } Daybreak { visible: dayBreak }
Row { Row {
@ -55,12 +56,12 @@ Column {
layoutDirection: isOwn ? Qt.RightToLeft : Qt.LeftToRight layoutDirection: isOwn ? Qt.RightToLeft : Qt.LeftToRight
anchors.right: isOwn ? parent.right : undefined anchors.right: isOwn ? parent.right : undefined
Avatar { id: avatar; invisible: combine; username: displayName } Base.Avatar { id: avatar; invisible: combine; username: displayName }
ColumnLayout { ColumnLayout {
spacing: 0 spacing: 0
PlainLabel { Base.HLabel {
visible: ! combine visible: ! combine
id: nameLabel id: nameLabel
text: displayName text: displayName
@ -76,7 +77,7 @@ Column {
topPadding: verticalPadding topPadding: verticalPadding
} }
PlainLabel { Base.HLabel {
id: contentLabel id: contentLabel
//text: (isOwn ? "" : content + "&nbsp;&nbsp;") + //text: (isOwn ? "" : content + "&nbsp;&nbsp;") +
//"<font size=" + smallSize + "px color=gray>" + //"<font size=" + smallSize + "px color=gray>" +

View File

@ -1,6 +1,7 @@
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 2.2 import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4 import QtQuick.Layouts 1.4
import "../base" as Base
Rectangle { Rectangle {
id: root id: root
@ -14,14 +15,14 @@ Rectangle {
spacing: 12 spacing: 12
anchors.fill: parent anchors.fill: parent
Avatar { Base.Avatar {
id: "avatar" id: "avatar"
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
dimmension: root.Layout.minimumHeight dimmension: root.Layout.minimumHeight
username: chatPage.room.display_name username: chatPage.room.display_name
} }
PlainLabel { Base.HLabel {
id: "roomName" id: "roomName"
text: chatPage.room.display_name text: chatPage.room.display_name
font.pixelSize: bigSize font.pixelSize: bigSize
@ -30,13 +31,17 @@ Rectangle {
Layout.maximumWidth: row.width - row.spacing * (row.children.length - 1) - avatar.width Layout.maximumWidth: row.width - row.spacing * (row.children.length - 1) - avatar.width
} }
PlainLabel { Base.HLabel {
id: "roomSubtitle" id: "roomSubtitle"
text: chatPage.room.subtitle text: chatPage.room.subtitle
font.pixelSize: smallSize font.pixelSize: smallSize
elide: Text.ElideRight elide: Text.ElideRight
maximumLineCount: 1 maximumLineCount: 1
Layout.maximumWidth: row.width - row.spacing * (row.children.length - 1) - avatar.width - roomName.width Layout.maximumWidth:
row.width -
row.spacing * (row.children.length - 1) -
avatar.width -
roomName.width
} }
Item { Layout.fillWidth: true } Item { Layout.fillWidth: true }

View File

@ -11,6 +11,6 @@ ColumnLayout {
onFocusChanged: sendBox.setFocus() onFocusChanged: sendBox.setFocus()
RoomHeader {} RoomHeader {}
MessageDisplay {} MessageList {}
SendBox { id: sendBox } SendBox { id: sendBox }
} }

View File

@ -1,6 +1,7 @@
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 2.2 import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4 import QtQuick.Layouts 1.4
import "../base" as Base
Rectangle { Rectangle {
function setFocus() { textArea.forceActiveFocus() } function setFocus() { textArea.forceActiveFocus() }
@ -17,7 +18,7 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
spacing: 0 spacing: 0
Avatar { Base.Avatar {
id: "avatar" id: "avatar"
username: chatPage.user.display_name username: chatPage.user.display_name
dimmension: root.Layout.minimumHeight dimmension: root.Layout.minimumHeight

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQuick.Layouts 1.4 import QtQuick.Layouts 1.4
import "../base" as Base
ColumnLayout { ColumnLayout {
id: "accountDelegate" id: "accountDelegate"
@ -11,14 +12,14 @@ ColumnLayout {
id: "row" id: "row"
spacing: 0 spacing: 0
Avatar { id: "avatar"; username: display_name; dimmension: 36 } Base.Avatar { id: "avatar"; username: display_name; dimmension: 36 }
ColumnLayout { ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
spacing: 0 spacing: 0
PlainLabel { Base.HLabel {
id: "accountLabel" id: "accountLabel"
text: display_name text: display_name
elide: Text.ElideRight elide: Text.ElideRight
@ -49,7 +50,7 @@ ColumnLayout {
} }
} }
HButton { Base.HToolButton {
id: "toggleExpand" id: "toggleExpand"
iconName: roomList.visible ? "up" : "down" iconName: roomList.visible ? "up" : "down"
Layout.maximumWidth: 28 Layout.maximumWidth: 28

View File

@ -1,6 +1,7 @@
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 2.2 import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4 import QtQuick.Layouts 1.4
import "../base" as Base
RowLayout { RowLayout {
id: "toolBar" id: "toolBar"
@ -8,28 +9,28 @@ RowLayout {
Layout.maximumHeight: 32 Layout.maximumHeight: 32
spacing: 0 spacing: 0
ActionButton { HToolButton {
visible: ! toolBarIsBig() visible: ! toolBarIsBig()
iconName: "reduced_menu" iconName: "reduced_menu"
tooltip: "Menu" tooltip: "Menu"
} }
ActionButton { HToolButton {
iconName: "settings" iconName: "settings"
tooltip: "Settings" tooltip: "Settings"
} }
ActionButton { HToolButton {
iconName: "add_account" iconName: "add_account"
tooltip: "Add new account" tooltip: "Add new account"
} }
ActionButton { HToolButton {
iconName: "set_status" iconName: "set_status"
tooltip: "Set status for all accounts" tooltip: "Set status for all accounts"
} }
ActionButton { HToolButton {
iconName: "search" iconName: "search"
tooltip: "Filter rooms" tooltip: "Filter rooms"
} }

View File

@ -1,8 +1,9 @@
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 2.2 import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4 import QtQuick.Layouts 1.4
import "../base" as Base
HButton { Base.HToolButton {
function toolBarIsBig() { function toolBarIsBig() {
return sidePane.width > return sidePane.width >
Layout.minimumWidth * (toolBar.children.length - 2) Layout.minimumWidth * (toolBar.children.length - 2)

View File

@ -1,6 +1,7 @@
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQuick.Layouts 1.4 import QtQuick.Layouts 1.4
import "../base" as Base
MouseArea { MouseArea {
id: "root" id: "root"
@ -17,12 +18,12 @@ MouseArea {
id: row id: row
spacing: 1 spacing: 1
Avatar { id: avatar; username: display_name; dimmension: 36 } Base.Avatar { id: avatar; username: display_name; dimmension: 36 }
ColumnLayout { ColumnLayout {
spacing: 0 spacing: 0
PlainLabel { Base.HLabel {
id: roomLabel id: roomLabel
text: display_name text: display_name
elide: Text.ElideRight elide: Text.ElideRight
@ -35,7 +36,7 @@ MouseArea {
leftPadding: 5 leftPadding: 5
rightPadding: leftPadding rightPadding: leftPadding
} }
PlainLabel { Base.HLabel {
id: subtitleLabel id: subtitleLabel
visible: text !== "" visible: text !== ""
text: subtitle text: subtitle

View File

@ -1,6 +1,7 @@
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 2.2 import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4 import QtQuick.Layouts 1.4
import "../base" as Base
ListView { ListView {
property var user: null property var user: null

View File

@ -1,6 +1,7 @@
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 2.2 import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4 import QtQuick.Layouts 1.4
import "../base" as Base
Rectangle { Rectangle {
id: sidePane id: sidePane
@ -16,6 +17,6 @@ Rectangle {
Layout.fillHeight: true Layout.fillHeight: true
} }
ButtonsBar {} HToolBar {}
} }
} }

59
harmonyqml/engine.py Normal file
View File

@ -0,0 +1,59 @@
# Copyright 2019 miruka
# This file is part of harmonyqml, licensed under GPLv3.
import logging
import sys
from pathlib import Path
from typing import Optional
from PyQt5.QtCore import QFileSystemWatcher, QObject, QTimer
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine
from .__about__ import __doc__
from .backend import DummyBackend
# logging.basicConfig(level=logging.INFO)
class Engine(QQmlApplicationEngine):
def __init__(self, app: QGuiApplication, parent: Optional[QObject] = None
) -> None:
super().__init__(parent)
self.app = app
self.backend = DummyBackend()
self.app_dir = Path(sys.argv[0]).resolve().parent
# Set QML properties
self.rootContext().setContextProperty("Engine", self)
self.rootContext().setContextProperty("Backend", self.backend)
# Connect Qt signals
self.quit.connect(self.app.quit)
# Make SIGINT (ctrl-c) work
self._sigint_timer = QTimer()
self._sigint_timer.timeout.connect(lambda: None)
self._sigint_timer.start(100)
# Setup UI live-reloading when a file is edited
self.file_watcher = QFileSystemWatcher()
self.file_watcher.directoryChanged.connect(lambda _: self.reload_qml())
self.file_watcher.addPath(str(self.app_dir / "components"))
# Load QML page and show window
self.load(str(self.app_dir / "components" / "Window.qml"))
def show_window(self) -> None:
self.rootObjects()[0].show()
sys.exit(self.app.exec())
def reload_qml(self) -> None:
self.clearComponentCache()
loader = self.rootObjects()[0].findChild(QObject, "UILoader")
source = loader.property("source")
loader.setProperty("source", None)
loader.setProperty("source", source)
logging.info("Reloaded: %s", source)

Binary file not shown.