From a0580893c4b314e7dea5bfdbcd8b64e83ff2c3cf Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 8 May 2020 16:18:01 -0400 Subject: [PATCH 1/4] basic application state; basic subscriber and dispatcher --- src/applicationLogic.nim | 16 +++++++++++++++- src/state.nim | 25 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/state.nim diff --git a/src/applicationLogic.nim b/src/applicationLogic.nim index 5e81f5ef1c..7b075e6242 100644 --- a/src/applicationLogic.nim +++ b/src/applicationLogic.nim @@ -2,7 +2,7 @@ import NimQml import status import libstatus import json - +import state var signalHandler: SignalCallback = proc(p0: cstring): void = setupForeignThreadGc() @@ -37,7 +37,21 @@ QtObject: result.accountResult = status.queryAccounts() status.subscribeToTest() + var appState = state.newAppState() + echo appState.title + appState.subscribe(proc () = + echo "1nd subscriber got a new update!" + ) + appState.addChannel("test") + + appState.subscribe(proc () = + echo "2nd subscriber got a new update!" + ) + + appState.addChannel("test2") + for channel in appState.channels: + echo channel.name # ¯\_(ツ)_/¯ dunno what is this proc setup(self: ApplicationLogic) = diff --git a/src/state.nim b/src/state.nim new file mode 100644 index 0000000000..0d28eb88e7 --- /dev/null +++ b/src/state.nim @@ -0,0 +1,25 @@ + + +type Channel = object + name*: string +type + Subscriber* = proc () + +type AppState* = ref object + title*: string + channels*: seq[Channel] + subscribers*: seq[Subscriber] + +proc newAppState*(): AppState = + result = AppState(title: "hello") + +proc subscribe*(self: AppState, subscriber: Subscriber) = + self.subscribers.add(subscriber) + +proc dispatch*(self: AppState) = + for subscriber in self.subscribers: + subscriber() + +proc addChannel*(self: AppState, name: string) = + self.channels.add(Channel(name: name)) + self.dispatch() From 41dd96e9c94dd0ebe98527dc26f5becc3f2530dd Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 8 May 2020 18:04:53 -0400 Subject: [PATCH 2/4] display values from a list, and support changing that list from nim --- main.qml | 15 +++++++++++++-- src/applicationLogic.nim | 13 +++++-------- src/chats.nim | 38 ++++++++++++++++++++++++++++++++++++++ src/nim_status_client.nim | 10 +++++++++- src/state.nim | 1 - 5 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 src/chats.nim diff --git a/main.qml b/main.qml index bae8731011..2e7bccec8e 100644 --- a/main.qml +++ b/main.qml @@ -7,7 +7,7 @@ ApplicationWindow { id: applicationWindow width: 1024 height: 768 - title: "JSON RPC Caller" + title: "Nim Status Client" visible: true RowLayout { @@ -237,6 +237,17 @@ ApplicationWindow { font.pixelSize: 28 } } + Component { + id: chatViewDelegate + Label { text: "Name:" + name } + } + + ListView { + id: listView + anchors.fill: parent + model: chatsModel + delegate: chatViewDelegate + } } Item { @@ -292,6 +303,6 @@ ApplicationWindow { /*##^## Designer { - D{i:9;anchors_height:40;anchors_width:40}D{i:19;anchors_y:0}D{i:23;anchors_height:100;anchors_width:100} + D{i:9;anchors_height:40;anchors_width:40} } ##^##*/ diff --git a/src/applicationLogic.nim b/src/applicationLogic.nim index 7b075e6242..e6cb0fcde0 100644 --- a/src/applicationLogic.nim +++ b/src/applicationLogic.nim @@ -20,6 +20,7 @@ QtObject: app: QApplication callResult: string accountResult: string + # chats: seq[ChatView] # Constructor proc newApplicationLogic*(app: QApplication): ApplicationLogic = @@ -41,17 +42,13 @@ QtObject: echo appState.title appState.subscribe(proc () = echo "1nd subscriber got a new update!" + for channel in appState.channels: + echo channel.name ) appState.addChannel("test") - - appState.subscribe(proc () = - echo "2nd subscriber got a new update!" - ) - appState.addChannel("test2") - for channel in appState.channels: - echo channel.name + # result.chats.add(ChatView(name: "test")) # ¯\_(ツ)_/¯ dunno what is this proc setup(self: ApplicationLogic) = @@ -112,4 +109,4 @@ QtObject: notify = callResultChanged # This class has the metaObject property available which lets - # access all the QProperties which are stored as QVariants \ No newline at end of file + # access all the QProperties which are stored as QVariants diff --git a/src/chats.nim b/src/chats.nim new file mode 100644 index 0000000000..e039735e86 --- /dev/null +++ b/src/chats.nim @@ -0,0 +1,38 @@ +import NimQml +import Tables + +type + RoleNames {.pure.} = enum + Name = UserRole + 1, + +QtObject: + type + ChatsModel* = ref object of QAbstractListModel + names*: seq[string] + + proc delete(self: ChatsModel) = + self.QAbstractListModel.delete + + proc setup(self: ChatsModel) = + self.QAbstractListModel.setup + + proc newChatsModel*(): ChatsModel = + new(result, delete) + result.names = @["test", "test2"] + result.setup + + proc addNameTolist*(self: ChatsModel, name: string) = + self.names.add(name) + + method rowCount(self: ChatsModel, index: QModelIndex = nil): int = + return self.names.len + + method data(self: ChatsModel, index: QModelIndex, role: int): QVariant = + if not index.isValid: + return + if index.row < 0 or index.row >= self.names.len: + return + return newQVariant(self.names[index.row]) + + method roleNames(self: ChatsModel): Table[int, string] = + { RoleNames.Name.int:"name"}.toTable diff --git a/src/nim_status_client.nim b/src/nim_status_client.nim index bbc5214c65..59c2d3b735 100644 --- a/src/nim_status_client.nim +++ b/src/nim_status_client.nim @@ -1,5 +1,6 @@ import NimQml import applicationLogic +import chats proc mainProc() = @@ -11,7 +12,9 @@ proc mainProc() = var app = newQApplication() defer: app.delete() # Defer will run this just before mainProc() function ends - + var chatsModel = newChatsModel(); + defer: chatsModel.delete + var engine = newQQmlApplicationEngine() defer: engine.delete() @@ -22,7 +25,12 @@ proc mainProc() = let logicVariant = newQVariant(logic) defer: logicVariant.delete + let chatsVariant = newQVariant(chatsModel) + defer: chatsVariant.delete + chatsModel.addNameTolist("hello") + engine.setRootContextProperty("logic", logicVariant) + engine.setRootContextProperty("chatsModel", chatsVariant) engine.load("main.qml") # Qt main event loop is entered here diff --git a/src/state.nim b/src/state.nim index 0d28eb88e7..5ecbc5550b 100644 --- a/src/state.nim +++ b/src/state.nim @@ -1,5 +1,4 @@ - type Channel = object name*: string type From 3b9be01cc5c91adfad3c6b35631157cb4fec3977 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 8 May 2020 18:12:32 -0400 Subject: [PATCH 3/4] move subscriber logic to level above the view --- src/applicationLogic.nim | 13 ------------- src/nim_status_client.nim | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/applicationLogic.nim b/src/applicationLogic.nim index e6cb0fcde0..a59e010b36 100644 --- a/src/applicationLogic.nim +++ b/src/applicationLogic.nim @@ -2,7 +2,6 @@ import NimQml import status import libstatus import json -import state var signalHandler: SignalCallback = proc(p0: cstring): void = setupForeignThreadGc() @@ -38,18 +37,6 @@ QtObject: result.accountResult = status.queryAccounts() status.subscribeToTest() - var appState = state.newAppState() - echo appState.title - appState.subscribe(proc () = - echo "1nd subscriber got a new update!" - for channel in appState.channels: - echo channel.name - ) - - appState.addChannel("test") - appState.addChannel("test2") - # result.chats.add(ChatView(name: "test")) - # ¯\_(ツ)_/¯ dunno what is this proc setup(self: ApplicationLogic) = # discard status.onMessage(self.onMessage) diff --git a/src/nim_status_client.nim b/src/nim_status_client.nim index 59c2d3b735..22e067ac35 100644 --- a/src/nim_status_client.nim +++ b/src/nim_status_client.nim @@ -1,6 +1,7 @@ import NimQml import applicationLogic import chats +import state proc mainProc() = @@ -27,7 +28,19 @@ proc mainProc() = let chatsVariant = newQVariant(chatsModel) defer: chatsVariant.delete - chatsModel.addNameTolist("hello") + + var appState = state.newAppState() + echo appState.title + + appState.subscribe(proc () = + chatsModel.names = @[] + for channel in appState.channels: + echo channel.name + chatsModel.addNameTolist(channel.name) + ) + + appState.addChannel("test") + appState.addChannel("test2") engine.setRootContextProperty("logic", logicVariant) engine.setRootContextProperty("chatsModel", chatsVariant) From 6e20f47ec8fc3ed6fada137300b7dfc701565495 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 8 May 2020 19:04:04 -0400 Subject: [PATCH 4/4] fix qml issue after rebasing --- main.qml | 187 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 102 insertions(+), 85 deletions(-) diff --git a/main.qml b/main.qml index 2e7bccec8e..0763fc9821 100644 --- a/main.qml +++ b/main.qml @@ -160,94 +160,111 @@ ApplicationWindow { height: parent.height Layout.minimumWidth: 200 - Text { - id: element - x: 772 - text: qsTr("Chat") - anchors.top: parent.top - anchors.topMargin: 17 - font.bold: true - anchors.horizontalCenter: parent.horizontalCenter - font.pixelSize: 17 - } + ColumnLayout { + anchors.rightMargin: 0 + anchors.fill: parent - Rectangle { - id: searchBox - height: 36 - color: "#EEF2F5" - anchors.top: parent.top - anchors.topMargin: 59 - radius: 8 - anchors.right: parent.right - anchors.rightMargin: 55 - anchors.left: parent.left - anchors.leftMargin: 16 + Item { + Layout.preferredHeight: 100 + Layout.fillHeight: false + Layout.fillWidth: true - TextField { - id: searchText - placeholderText: qsTr("Search") - anchors.left: parent.left - anchors.leftMargin: 32 - anchors.verticalCenter: parent.verticalCenter - font.pixelSize: 12 - background: { + Text { + id: element + x: 772 + text: qsTr("Chat") + anchors.top: parent.top + anchors.topMargin: 17 + font.bold: true + anchors.horizontalCenter: parent.horizontalCenter + font.pixelSize: 17 + } + + Rectangle { + id: searchBox + height: 36 + color: "#EEF2F5" + anchors.top: parent.top + anchors.topMargin: 59 + radius: 8 + anchors.right: parent.right + anchors.rightMargin: 55 + anchors.left: parent.left + anchors.leftMargin: 16 + + TextField { + id: searchText + placeholderText: qsTr("Search") + anchors.left: parent.left + anchors.leftMargin: 32 + anchors.verticalCenter: parent.verticalCenter + font.pixelSize: 12 + background: { + } + } + + Image { + id: image4 + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.verticalCenter: parent.verticalCenter + fillMode: Image.PreserveAspectFit + source: "img/search.svg" + } + + MouseArea { + id: mouseArea + anchors.fill: parent + onClicked : { + searchText.forceActiveFocus(Qt.MouseFocusReason) + } + } + } + + Rectangle { + id: addChat + width: 36 + height: 36 + color: "#4360DF" + radius: 50 + anchors.right: parent.right + anchors.rightMargin: 9 + anchors.top: parent.top + anchors.topMargin: 59 + + Text { + id: element3 + color: "#ffffff" + text: qsTr("+") + anchors.verticalCenterOffset: -1 + anchors.horizontalCenterOffset: 1 + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + lineHeight: 1 + fontSizeMode: Text.FixedSize + font.bold: true + font.pixelSize: 28 + } } } - Image { - id: image4 - anchors.left: parent.left - anchors.leftMargin: 10 - anchors.verticalCenter: parent.verticalCenter - fillMode: Image.PreserveAspectFit - source: "img/search.svg" - } + Item { + Layout.fillHeight: true + Layout.fillWidth: true - MouseArea { - id: mouseArea - anchors.fill: parent - onClicked : { - searchText.forceActiveFocus(Qt.MouseFocusReason) + Component { + id: chatViewDelegate + Label { text: "Name:" + name } + } + + ListView { + id: listView + anchors.fill: parent + model: chatsModel + delegate: chatViewDelegate } } } - - Rectangle { - id: addChat - width: 36 - height: 36 - color: "#4360DF" - radius: 50 - anchors.right: parent.right - anchors.rightMargin: 9 - anchors.top: parent.top - anchors.topMargin: 59 - - Text { - id: element3 - color: "#ffffff" - text: qsTr("+") - anchors.verticalCenterOffset: -1 - anchors.horizontalCenterOffset: 1 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - lineHeight: 1 - fontSizeMode: Text.FixedSize - font.bold: true - font.pixelSize: 28 - } - } - Component { - id: chatViewDelegate - Label { text: "Name:" + name } - } - - ListView { - id: listView - anchors.fill: parent - model: chatsModel - delegate: chatViewDelegate - } } Item { @@ -282,14 +299,14 @@ ApplicationWindow { } - ColumnLayout { - anchors.fill: parent + ColumnLayout { + anchors.fill: parent - RowLayout { - Layout.fillHeight: true - TextArea { id: accountResult; Layout.fillWidth: true; text: logic.accountResult; readOnly: true } - } + RowLayout { + Layout.fillHeight: true + TextArea { id: accountResult; Layout.fillWidth: true; text: logic.accountResult; readOnly: true } } + } Item {