8f35e60801
- Standardized capitalization for variables and file names everywhere in QML and JS, get rid of mixed camelCase/snakeCase, use camelCase like everywhere in Qt - ListModel items are now stored and returned as real QObjects with PyQt properties and signals. This makes dynamic property binding a lot easier and eliminates the need for many hacks. - New update(), updateOrAppendWhere() methods and roles property for ListModel - RoomHeader now properly updates when the room title or topic changes - Add Backend.pdb(), to make it easier to start the debugger from QML
84 lines
2.5 KiB
Python
84 lines
2.5 KiB
Python
from typing import Any, Callable, Optional, Tuple, Union
|
|
|
|
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal
|
|
|
|
|
|
class ListItem(QObject):
|
|
roles: Tuple[str, ...] = ()
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__()
|
|
|
|
for role, value in zip(self.roles, args):
|
|
setattr(self, role, value)
|
|
|
|
for role, value in kwargs.items():
|
|
setattr(self, role, value)
|
|
|
|
|
|
def __repr__(self) -> str:
|
|
return "%s(%s)" % (
|
|
type(self).__name__,
|
|
", ".join((f"{r}={getattr(self, r)!r}" for r in self.roles)),
|
|
)
|
|
|
|
|
|
@pyqtProperty(str, constant=True)
|
|
def repr(self) -> str:
|
|
return repr(self)
|
|
|
|
|
|
def prop(qt_type: Union[str, Callable],
|
|
name: str,
|
|
signal: Optional[pyqtSignal] = None,
|
|
default_value: Any = None) -> pyqtProperty:
|
|
|
|
def fget(self, name=name, default_value=default_value):
|
|
if not hasattr(self, f"_{name}"):
|
|
setattr(self, f"_{name}", default_value)
|
|
return getattr(self, f"_{name}")
|
|
|
|
def fset(self, value, name=name, signal=signal):
|
|
setattr(self, f"_{name}", value)
|
|
if signal:
|
|
getattr(self, f"{name}Changed").emit(value)
|
|
|
|
kws = {"notify": signal} if signal else {"constant": True}
|
|
|
|
return pyqtProperty(qt_type, fget=fget, fset=fset, **kws)
|
|
|
|
|
|
class User(ListItem):
|
|
roles = ("userId", "displayName", "avatarUrl", "statusMessage")
|
|
|
|
displayNameChanged = pyqtSignal("QVariant")
|
|
avatarUrlChanged = pyqtSignal("QVariant")
|
|
statusMessageChanged = pyqtSignal(str)
|
|
|
|
userId = prop(str, "userId")
|
|
displayName = prop("QVariant", "displayName", displayNameChanged)
|
|
avatarUrl = prop(str, "avatarUrl", avatarUrlChanged)
|
|
statusMessage = prop(str, "statusMessage", statusMessageChanged, "")
|
|
|
|
|
|
class Room(ListItem):
|
|
roles = ("roomId", "displayName", "topic", "typingUsers")
|
|
|
|
displayNameChanged = pyqtSignal("QVariant")
|
|
topicChanged = pyqtSignal(str)
|
|
typingUsersChanged = pyqtSignal("QVariantList")
|
|
|
|
roomId = prop(str, "roomId")
|
|
displayName = prop(str, "displayName", displayNameChanged)
|
|
topic = prop(str, "topic", topicChanged, "")
|
|
typingUsers = prop(list, "typingUsers", typingUsersChanged, [])
|
|
|
|
|
|
class RoomEvent(ListItem):
|
|
roles = ("type", "dateTime", "dict", "isLocalEcho")
|
|
|
|
type = prop(str, "type")
|
|
dateTime = prop("QVariant", "dateTime")
|
|
dict = prop("QVariantMap", "dict")
|
|
isLocalEcho = prop(bool, "isLocalEcho", None, False)
|