commit 62df25ce8e090f53aef822c2b22c754fd4fca3e1 Author: marcin Date: Mon Jul 7 19:08:30 2014 +0200 first push diff --git a/LeftPanel.qml b/LeftPanel.qml new file mode 100644 index 00000000..a33b0dda --- /dev/null +++ b/LeftPanel.qml @@ -0,0 +1,245 @@ +import QtQuick 2.2 +import "components" + +Rectangle { + id: panel + signal dashboardClicked() + signal historyClicked() + signal transferClicked() + signal settingsClicked() + signal addressBookClicked() + signal miningClicked() + + width: 260 + color: "#FFFFFF" + + Image { + id: logo + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + anchors.topMargin: 31 + source: "images/moneroLogo.png" + } + + Column { + id: column1 + anchors.left: parent.left + anchors.right: parent.right + anchors.top: logo.bottom + anchors.topMargin: 40 + spacing: 6 + + Label { + text: qsTr("Locked balance") + anchors.left: parent.left + anchors.leftMargin: 50 + } + + Row { + Item { + anchors.verticalCenter: parent.verticalCenter + height: 26 + width: 50 + + Image { + anchors.centerIn: parent + source: "images/lockIcon.png" + } + } + + Text { + anchors.verticalCenter: parent.verticalCenter + font.family: "Arial" + font.pixelSize: 26 + color: "#000000" + text: "78.9239845" + } + } + + Item { //separator + anchors.left: parent.left + anchors.right: parent.right + height: 1 + } + + Label { + text: qsTr("Unlocked") + anchors.left: parent.left + anchors.leftMargin: 50 + } + + Text { + anchors.left: parent.left + anchors.leftMargin: 50 + font.family: "Arial" + font.pixelSize: 18 + color: "#000000" + text: "2324.9239845" + } + } + + Rectangle { + anchors.top: parent.top + anchors.left: parent.left + anchors.bottom: menuRect.top + width: 1 + color: "#DBDBDB" + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + height: 1 + color: "#DBDBDB" + } + + Rectangle { + id: menuRect + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.top: column1.bottom + anchors.topMargin: 50 + color: "#1C1C1C" + + Column { + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + + property var previousButton: dashboardButton + MenuButton { + id: dashboardButton + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Dashboard") + symbol: qsTr("D") + dotColor: "#FFE00A" + checked: true + onClicked: { + parent.previousButton.checked = false + parent.previousButton = dashboardButton + panel.dashboardClicked() + } + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 16 + color: dashboardButton.checked || transferButton.checked ? "#1C1C1C" : "#505050" + height: 1 + } + + MenuButton { + id: transferButton + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Transfer") + symbol: qsTr("T") + dotColor: "#FF6C3C" + onClicked: { + parent.previousButton.checked = false + parent.previousButton = transferButton + panel.transferClicked() + } + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 16 + color: transferButton.checked || historyButton.checked ? "#1C1C1C" : "#505050" + height: 1 + } + + MenuButton { + id: historyButton + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("History") + symbol: qsTr("H") + dotColor: "#6B0072" + onClicked: { + parent.previousButton.checked = false + parent.previousButton = historyButton + panel.historyClicked() + } + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 16 + color: historyButton.checked || addressBookButton.checked ? "#1C1C1C" : "#505050" + height: 1 + } + + MenuButton { + id: addressBookButton + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Address book") + symbol: qsTr("B") + dotColor: "#FF4F41" + onClicked: { + parent.previousButton.checked = false + parent.previousButton = addressBookButton + panel.addressBookClicked() + } + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 16 + color: addressBookButton.checked || miningButton.checked ? "#1C1C1C" : "#505050" + height: 1 + } + + MenuButton { + id: miningButton + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Mining") + symbol: qsTr("M") + dotColor: "#FFD781" + onClicked: { + parent.previousButton.checked = false + parent.previousButton = miningButton + panel.miningClicked() + } + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 16 + color: miningButton.checked || settingsButton.checked ? "#1C1C1C" : "#505050" + height: 1 + } + + MenuButton { + id: settingsButton + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Settings") + symbol: qsTr("S") + dotColor: "#36B25C" + onClicked: { + parent.previousButton.checked = false + parent.previousButton = settingsButton + panel.settingsClicked() + } + } + } + + NetworkStatusItem { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + connected: true + } + } +} diff --git a/MiddlePanel.qml b/MiddlePanel.qml new file mode 100644 index 00000000..e3043a46 --- /dev/null +++ b/MiddlePanel.qml @@ -0,0 +1,72 @@ +import QtQuick 2.2 + +Rectangle { + color: "#F0EEEE" + + states: [ + State { + name: "Dashboard" + PropertyChanges { target: loader; source: "pages/Dashboard.qml" } + }, State { + name: "History" + PropertyChanges { target: loader; source: "pages/History.qml" } + }, State { + name: "Transfer" + PropertyChanges { target: loader; source: "pages/Transfer.qml" } + }, State { + name: "AddressBook" + PropertyChanges { target: loader; source: "pages/AddressBook.qml" } + }, State { + name: "Settings" + PropertyChanges { target: loader; source: "pages/Settings.qml" } + }, State { + name: "Mining" + PropertyChanges { target: loader; source: "pages/Mining.qml" } + } + ] + + Row { + id: styledRow + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + + Rectangle { height: 4; width: parent.width / 5; color: "#FFE00A" } + Rectangle { height: 4; width: parent.width / 5; color: "#6B0072" } + Rectangle { height: 4; width: parent.width / 5; color: "#FF6C3C" } + Rectangle { height: 4; width: parent.width / 5; color: "#FFD781" } + Rectangle { height: 4; width: parent.width / 5; color: "#FF4F41" } + } + + Loader { + id: loader + anchors.left: parent.left + anchors.right: parent.right + anchors.top: styledRow.bottom + anchors.bottom: parent.bottom + } + + Rectangle { + anchors.top: styledRow.bottom + anchors.bottom: parent.bottom + anchors.right: parent.right + width: 1 + color: "#DBDBDB" + } + + Rectangle { + anchors.top: styledRow.bottom + anchors.bottom: parent.bottom + anchors.left: parent.left + width: 1 + color: "#DBDBDB" + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + height: 1 + color: "#DBDBDB" + } +} diff --git a/RightPanel.qml b/RightPanel.qml new file mode 100644 index 00000000..f59ac3bc --- /dev/null +++ b/RightPanel.qml @@ -0,0 +1,248 @@ +import QtQuick 2.2 +import QtQuick.Window 2.0 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 +import "tabs" + +Rectangle { + width: 330 + + Row { + anchors.top: parent.top + anchors.right: parent.right + anchors.topMargin: 5 + anchors.rightMargin: 5 + + Rectangle { + width: 25 + height: 25 + radius: 5 + clip: true + color: helpArea.containsMouse ? "#DBDBDB" : "#FFFFFF" + + Rectangle { + width: 25 + height: 25 + radius: 5 + color: "#FFFFFF" + visible: helpArea.containsMouse + x: 1; y: 2 + } + + Image { + anchors.centerIn: parent + source: { + if(appWindow.whatIsEnable) + return "images/whatIsIcon.png" + return helpArea.containsMouse ? "images/helpIconHovered.png" : + "images/helpIcon.png" + } + } + + MouseArea { + id: helpArea + anchors.fill: parent + hoverEnabled: true + onClicked: { + appWindow.whatIsEnable = !appWindow.whatIsEnable + } + } + } + + Rectangle { + width: 25 + height: 25 + radius: 5 + clip: true + color: minimizeArea.containsMouse ? "#DBDBDB" : "#FFFFFF" + + Rectangle { + width: 25 + height: 25 + radius: 5 + color: "#FFFFFF" + visible: minimizeArea.containsMouse + x: 1; y: 2 + } + + Image { + anchors.centerIn: parent + source: minimizeArea.containsMouse ? "images/minimizeIconHovered.png" : + "images/minimizeIcon.png" + } + + MouseArea { + id: minimizeArea + anchors.fill: parent + hoverEnabled: true + onClicked: appWindow.visibility = Window.Minimized + } + } + + Rectangle { + property bool checked: false + width: 25 + height: 25 + radius: 5 + clip: true + color: maximizeArea.containsMouse ? "#DBDBDB" : "#FFFFFF" + + Rectangle { + width: 25 + height: 25 + radius: 5 + color: "#FFFFFF" + visible: maximizeArea.containsMouse + x: 1; y: 2 + } + + Image { + anchors.centerIn: parent + source: { + if(parent.checked) + return maximizeArea.containsMouse ? "images/backToWindowIconHovered.png" : + "images/backToWindowIcon.png" + return maximizeArea.containsMouse ? "images/maximizeIconHovered.png" : + "images/maximizeIcon.png" + } + } + + MouseArea { + id: maximizeArea + anchors.fill: parent + hoverEnabled: true + onClicked: { + parent.checked = !parent.checked + appWindow.visibility = parent.checked ? Window.FullScreen : + Window.Windowed + } + } + } + + Rectangle { + width: 25 + height: 25 + radius: 5 + clip: true + color: closeArea.containsMouse ? "#DBDBDB" : "#FFFFFF" + + Rectangle { + width: 25 + height: 25 + radius: 5 + color: "#FFFFFF" + visible: closeArea.containsMouse + x: 1; y: 2 + } + + Image { + anchors.centerIn: parent + source: "images/closeIcon.png" + } + + MouseArea { + id: closeArea + anchors.fill: parent + hoverEnabled: true + onClicked: Qt.quit() + } + } + } + + TabView { + id: tabView + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: styledRow.top + anchors.leftMargin: 14 + anchors.rightMargin: 14 + anchors.topMargin: 40 + + Tab { title: qsTr("Twitter"); source: "tabs/Twitter.qml" } + Tab { title: "News" } + Tab { title: "Help" } + Tab { title: "About" } + + style: TabViewStyle { + frameOverlap: 2 + tabOverlap: 0 + tab: Rectangle { + implicitHeight: 31 + implicitWidth: 68 + + Text { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 12 + anchors.rightMargin: 12 + elide: Text.ElideRight + font.family: "Arial" + font.pixelSize: 14 + color: styleData.selected ? "#FF4E40" : "#4A4646" + text: styleData.title + } + + Rectangle { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: parent.right + width: 1 + color: "#DBDBDB" + visible: styleData.index !== tabView.count - 1 + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + height: 1 + color: styleData.selected ? "#FFFFFF" : "#DBDBDB" + } + } + + frame: Rectangle { + color: "#FFFFFF" + anchors.fill: parent + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: 1 + height: 1 + color: "#DBDBDB" + } + } + } + } + + Row { + id: styledRow + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + + Rectangle { height: 8; width: parent.width / 5; color: "#FFE00A" } + Rectangle { height: 8; width: parent.width / 5; color: "#6B0072" } + Rectangle { height: 8; width: parent.width / 5; color: "#FF6C3C" } + Rectangle { height: 8; width: parent.width / 5; color: "#FFD781" } + Rectangle { height: 8; width: parent.width / 5; color: "#FF4F41" } + } + + Rectangle { + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: 1 + color: "#DBDBDB" + } + + Rectangle { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: parent.right + width: 1 + color: "#DBDBDB" + } +} diff --git a/bitmonero.pro b/bitmonero.pro new file mode 100644 index 00000000..3904b44c --- /dev/null +++ b/bitmonero.pro @@ -0,0 +1,17 @@ +TEMPLATE = app + +QT += qml quick widgets + +SOURCES += main.cpp \ + filter.cpp + +RESOURCES += qml.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Default rules for deployment. +include(deployment.pri) + +HEADERS += \ + filter.h diff --git a/bitmonero.pro.user b/bitmonero.pro.user new file mode 100644 index 00000000..d1aa9be3 --- /dev/null +++ b/bitmonero.pro.user @@ -0,0 +1,251 @@ + + + + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.3.0 MinGW 32bit + Desktop Qt 5.3.0 MinGW 32bit + qt.53.win32_mingw482_kit + 0 + 0 + 0 + + G:/RPA/build-bitmonero-Desktop_Qt_5_3_0_MinGW_32bit-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + budowania + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + czyszczenia + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + G:/RPA/build-bitmonero-Desktop_Qt_5_3_0_MinGW_32bit-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + budowania + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + czyszczenia + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 2 + + + 0 + instalacji + + ProjectExplorer.BuildSteps.Deploy + + 1 + Zainstaluj lokalnie + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + bitmonero + + Qt4ProjectManager.Qt4RunConfiguration:G:/RPA/bitmonero/bitmonero.pro + + bitmonero.pro + false + false + + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.EnvironmentId + {20382c58-78e1-43a4-9d27-354b0656be87} + + + ProjectExplorer.Project.Updater.FileVersion + 15 + + diff --git a/components/DashboardTable.qml b/components/DashboardTable.qml new file mode 100644 index 00000000..dda95cd5 --- /dev/null +++ b/components/DashboardTable.qml @@ -0,0 +1,177 @@ +import QtQuick 2.0 +import "../components" + +ListView { + id: listView + clip: true + boundsBehavior: ListView.StopAtBounds + + property var previousItem + delegate: Rectangle { + id: delegate + height: 90 + width: listView.width + z: 0 + color: index % 2 ? "#F8F8F8" : "#FFFFFF" + function collapseDropdown() { dropdown.expanded = false } + + Row { + id: row1 + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: 14 + + Rectangle { + id: dot + width: 14 + height: width + radius: width / 2 + color: out ? "#FF4F41" : "#36B05B" + } + + Item { //separator + width: 12 + height: 14 + } + + Text { + id: paymentIdText + width: text.length ? 122 : 0 + anchors.verticalCenter: dot.verticalCenter + font.family: "Arial" + font.bold: true + font.pixelSize: 19 + color: "#444444" + elide: Text.ElideRight + text: paymentId + } + + Item { //separator + width: paymentIdText.width ? 12 : 0 + height: 14 + } + + Text { + anchors.verticalCenter: dot.verticalCenter + width: parent.width - x - 12 + elide: Text.ElideRight + font.family: "Arial" + font.pixelSize: 14 + color: "#545454" + text: address + } + } + + Row { + anchors.left: parent.left + anchors.top: row1.bottom + anchors.topMargin: 8 + spacing: 12 + + Item { //separator + width: 14 + height: 14 + } + + Column { + anchors.top: parent.top + width: 202 + + Text { + anchors.left: parent.left + font.family: "Arial" + font.pixelSize: 12 + color: "#545454" + text: qsTr("Date") + } + + Text { + font.family: "Arial" + font.pixelSize: 18 + color: "#000000" + text: date + } + } + + Column { + anchors.top: parent.top + width: 148 + + Text { + anchors.left: parent.left + font.family: "Arial" + font.pixelSize: 12 + color: "#545454" + text: qsTr("Amount") + } + + Text { + font.family: "Arial" + font.pixelSize: 18 + color: "#000000" + text: amount + } + } + + Column { + anchors.top: parent.top + width: 148 + + Text { + anchors.left: parent.left + font.family: "Arial" + font.pixelSize: 12 + color: "#545454" + text: qsTr("Balance") + } + + Row { + spacing: 2 + Text { + anchors.bottom: parent.bottom + anchors.bottomMargin: 3 + font.family: "Arial" + font.pixelSize: 16 + color: out ? "#FF4F41" : "#36B05B" + text: out ? "↓" : "↑" + } + + Text { + anchors.bottom: parent.bottom + font.family: "Arial" + font.pixelSize: 18 + color: out ? "#FF4F41" : "#36B05B" + text: balance + } + } + } + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + height: 1 + color: "#DBDBDB" + } + + TableDropdown { + id: dropdown + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.bottomMargin: 11 + anchors.rightMargin: 5 + onExpandedChanged: { + if(listView.previousItem !== undefined && listView.previousItem !== delegate) + listView.previousItem.collapseDropdown() + if(expanded) { + listView.previousItem = delegate + listView.currentIndex = index + listView.currentItem.z = 2 + } + } + onCollapsed: delegate.z = 0 + } + } +} diff --git a/components/Input.qml b/components/Input.qml new file mode 100644 index 00000000..98acf532 --- /dev/null +++ b/components/Input.qml @@ -0,0 +1,18 @@ +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 +import QtQuick 2.2 + +TextField { + font.family: "Arial" + font.pixelSize: 18 + + style: TextFieldStyle { + textColor: "#3F3F3F" + placeholderTextColor: "#BABABA" + + background: Rectangle { + border.width: 0 + color: "transparent" + } + } +} diff --git a/components/Label.qml b/components/Label.qml new file mode 100644 index 00000000..35101ff1 --- /dev/null +++ b/components/Label.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 + +Item { + property alias text: label.text + property alias color: label.color + property int fontSize: 12 + width: icon.x + icon.width + height: icon.height + + Text { + id: label + anchors.bottom: parent.bottom + anchors.bottomMargin: 2 + anchors.left: parent.left + font.family: "Arial" + font.pixelSize: parent.fontSize + color: "#555555" + } + + Image { + id: icon + anchors.verticalCenter: parent.verticalCenter + anchors.left: label.right + anchors.leftMargin: 5 + source: "../images/whatIsIcon.png" + visible: appWindow.whatIsEnable + } +} diff --git a/components/LineEdit.qml b/components/LineEdit.qml new file mode 100644 index 00000000..aad227ae --- /dev/null +++ b/components/LineEdit.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 + +Item { + property alias placeholderText: input.placeholderText + property alias text: input.text + height: 37 + + Rectangle { + anchors.fill: parent + anchors.bottomMargin: 1 + color: "#DBDBDB" + radius: 4 + } + + Rectangle { + anchors.fill: parent + anchors.topMargin: 1 + color: "#FFFFFF" + radius: 4 + } + + Input { + id: input + anchors.fill: parent + anchors.leftMargin: 11 + anchors.rightMargin: 11 + } +} diff --git a/components/MenuButton.qml b/components/MenuButton.qml new file mode 100644 index 00000000..59bd20c9 --- /dev/null +++ b/components/MenuButton.qml @@ -0,0 +1,75 @@ +import QtQuick 2.0 + +Rectangle { + id: button + property alias text: label.text + property bool checked: false + property alias dotColor: dot.color + property alias symbol: symbolText.text + signal clicked() + + height: 64 + color: checked ? "#FFFFFF" : "#1C1C1C" + + Item { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + width: 50 + + Rectangle { + id: dot + anchors.centerIn: parent + width: 16 + height: width + radius: height / 2 + + Rectangle { + anchors.centerIn: parent + width: 12 + height: width + radius: height / 2 + color: "#1C1C1C" + visible: !button.checked && !buttonArea.containsMouse + } + } + + Text { + id: symbolText + anchors.centerIn: parent + font.pixelSize: 11 + font.bold: true + color: button.checked || buttonArea.containsMouse ? "#FFFFFF" : dot.color + visible: appWindow.ctrlPressed + } + } + + Image { + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 20 + source: "../images/menuIndicator.png" + } + + Text { + id: label + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 50 + font.family: "Arial" + font.pixelSize: 18 + color: parent.checked ? "#000000" : "#FFFFFF" + } + + MouseArea { + id: buttonArea + anchors.fill: parent + hoverEnabled: true + onClicked: { + if(parent.checked) + return + button.clicked() + parent.checked = true + } + } +} diff --git a/components/NetworkStatusItem.qml b/components/NetworkStatusItem.qml new file mode 100644 index 00000000..bf6cf303 --- /dev/null +++ b/components/NetworkStatusItem.qml @@ -0,0 +1,41 @@ +import QtQuick 2.0 + +Row { + id: item + property bool connected: false + + Item { + id: iconItem + anchors.bottom: parent.bottom + width: 50 + height: 50 + + Image { + anchors.centerIn: parent + source: item.connected ? "../images/statusConnected.png" : + "../images/statusDisconnected.png" + } + } + + Column { + anchors.bottom: parent.bottom + height: 53 + spacing: 3 + + Text { + anchors.left: parent.left + font.family: "Arial" + font.pixelSize: 12 + color: "#545454" + text: qsTr("Network status") + } + + Text { + anchors.left: parent.left + font.family: "Arial" + font.pixelSize: 18 + color: item.connected ? "#FF6C3B" : "#AAAAAA" + text: item.connected ? qsTr("Connected") : qsTr("Disconnected") + } + } +} diff --git a/components/SearchInput.qml b/components/SearchInput.qml new file mode 100644 index 00000000..7505c5cd --- /dev/null +++ b/components/SearchInput.qml @@ -0,0 +1,167 @@ +import QtQuick 2.0 + +Item { + id: item + signal searchClicked(string text, int option) + height: 50 + + Rectangle { + anchors.fill: parent + color: "#DBDBDB" + radius: 10 + } + + Rectangle { + anchors.fill: parent + anchors.topMargin: 1 + color: "#FFFFFF" + radius: 10 + + Item { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + width: 45 + + Image { + anchors.centerIn: parent + source: "../images/magnifier.png" + } + } + + Input { + id: input + anchors.left: parent.left + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: dropdown.left + anchors.leftMargin: 45 + verticalAlignment: TextInput.AlignVCenter + placeholderText: qsTr("Search by...") + } + + Item { + id: dropdown + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: button.left + width: 154 + + Row { + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + + Text { + id: dropText + width: 114 - 12 + anchors.verticalCenter: parent.verticalCenter + font.family: "Arial" + font.pixelSize: 12 + color: "#4A4747" + text: "NAME" + } + + Image { + anchors.verticalCenter: parent.verticalCenter + source: "../images/hseparator.png" + } + + Item { + height: dropdown.height + width: 38 + + Image { + id: dropIndicator + anchors.centerIn: parent + source: "../images/dropIndicator.png" + rotation: droplist.height === 0 ? 0 : 180 + } + } + } + + MouseArea { + anchors.fill: parent + onClicked: droplist.height = droplist.height === 0 ? dropcolumn.height : 0 + } + } + + Rectangle { + id: droplist + property int currentOption: 0 + + width: 154 + height: 0 + clip: true + x: dropdown.x + y: dropdown.height + color: "#FFFFFF" + + Behavior on height { + NumberAnimation { duration: 100; easing.type: Easing.InQuad } + } + + ListModel { + id: dropdownModel + ListElement { name: "NAME" } + ListElement { name: "DESCRIPTION" } + ListElement { name: "ADDRESS" } + } + + Column { + id: dropcolumn + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + + Repeater { + model: dropdownModel + delegate: Rectangle { + property bool isCurrent: name === dropText.text + anchors.left: parent.left + anchors.right: parent.right + height: 30 + color: delegateArea.pressed || isCurrent ? "#4A4646" : "#FFFFFF" + + Text { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.right: parent.right + elide: Text.ElideRight + anchors.leftMargin: 12 + anchors.rightMargin: 12 + font.family: "Arial" + font.pixelSize: 12 + color: delegateArea.pressed || parent.isCurrent ? "#FFFFFF" : "#4A4646" + text: name + } + + MouseArea { + id: delegateArea + anchors.fill: parent + onClicked: { + droplist.currentOption = index + droplist.height = 0 + dropText.text = name + } + } + } + } + } + } + + StandardButton { + id: button + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.margins: 6 + width: 80 + + shadowColor: "#8C0B00" + pressedColor: "#C60F00" + releasedColor: "#FF4F41" + text: qsTr("SEARCH") + onClicked: item.searchClicked(input.text, droplist.currentOption) + } + } +} diff --git a/components/StandardButton.qml b/components/StandardButton.qml new file mode 100644 index 00000000..027356e8 --- /dev/null +++ b/components/StandardButton.qml @@ -0,0 +1,46 @@ +import QtQuick 2.0 + +Item { + height: 37 + property string shadowColor + property string pressedColor + property string releasedColor + property string textColor: "#FFFFFF" + property alias text: label.text + signal clicked() + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + height: parent.height - 1 + y: buttonArea.pressed ? 1 : 0 + radius: 4 + color: parent.shadowColor + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + height: parent.height - 1 + y: buttonArea.pressed ? 0 : 1 + color: buttonArea.pressed ? parent.pressedColor : parent.releasedColor + radius: 4 + } + + Text { + id: label + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.right: parent.right + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight + font.pixelSize: 12 + color: parent.textColor + } + + MouseArea { + id: buttonArea + anchors.fill: parent + onClicked: parent.clicked() + } +} diff --git a/components/TableDropdown.qml b/components/TableDropdown.qml new file mode 100644 index 00000000..19186253 --- /dev/null +++ b/components/TableDropdown.qml @@ -0,0 +1,135 @@ +import QtQuick 2.0 + +Item { + id: dropdown + property bool expanded: false + signal collapsed() + width: 72 + height: 37 + + Item { + id: head + anchors.fill: parent + + Rectangle { + anchors.fill: parent + anchors.topMargin: dropdown.expanded ? 0 : 1 + radius: 3 + color: dropdown.expanded ? "#888888" : "#DBDBDB" + } + + Rectangle { + anchors.fill: parent + anchors.bottomMargin: dropdown.expanded ? 0 : 1 + radius: 3 + color: dropdown.expanded ? "#DBDBDB" : "#F0EEEE" + } + + Image { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 10 + source: "../images/tableOptions.png" + } + + Rectangle { + anchors.centerIn: parent + anchors.horizontalCenterOffset: 1 + height: 23 + width: 1 + color: dropdown.expanded ? "#FFFFFF" : "#DBDBDB" + } + + Image { + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 10 + source: "../images/dropIndicator.png" + } + + MouseArea { + anchors.fill: parent + onPressed: dropdown.expanded = !dropdown.expanded + } + } + + Item { + anchors.left: parent.left + anchors.right: parent.right + anchors.top: head.bottom + height: dropdown.expanded ? column.height : 0 + onHeightChanged: if(height === 0) dropdown.collapsed() + clip: true + + Behavior on height { + NumberAnimation { duration: 100; easing.type: Easing.InQuad } + } + + Column { + id: column + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + + ListModel { + id: dataModel + ListElement { name: "text 1"; icon: "../images/dropdownOption1.png" } + ListElement { name: "longer text 2"; icon: "../images/dropdownSend.png" } + ListElement { name: "text3

lorem ipsum asdasd asdasd"; icon: "../images/dropdownSearch.png" } + } + + Repeater { + id: repeater + model: dataModel + + delegate: Rectangle { + id: delegate + anchors.left: parent.left + anchors.right: parent.right + height: 30 + color: delegateArea.containsMouse ? "#F0EEEE" : "#DBDBDB" + radius: index === repeater.count - 1 ? 5 : 0 + + Rectangle { + anchors.left: parent.left + anchors.top: parent.top + width: 5 + height: 5 + color: delegate.color + } + + Rectangle { + anchors.right: parent.right + anchors.top: parent.top + width: 5 + height: 5 + color: delegate.color + } + + Image { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 10 + source: icon + } + + MouseArea { + id: delegateArea + hoverEnabled: true + anchors.fill: parent + onEntered: { + var pos = rootItem.mapFromItem(delegate, 30, -20) + tipItem.text = name + tipItem.x = pos.x + if(tipItem.height > 30) + pos.y -= tipItem.height - 30 + tipItem.y = pos.y + tipItem.visible = true + } + onExited: tipItem.visible = false + } + } + } + } + } +} diff --git a/components/TableHeader.qml b/components/TableHeader.qml new file mode 100644 index 00000000..a2b3e544 --- /dev/null +++ b/components/TableHeader.qml @@ -0,0 +1,154 @@ +import QtQuick 2.0 + +Rectangle { + id: header + signal sortRequest(bool desc, int column) + property int activeSortColumn: -1 + + height: 31 + color: "#FFFFFF" + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + height: 1 + color: "#DBDBDB" + } + + ListModel { + id: columnsModel + ListElement { columnName: "Date"; columnWidth: 92 } + ListElement { columnName: "Amount"; columnWidth: 158 } + ListElement { columnName: "Balance"; columnWidth: 168 } + } + + Row { + anchors.horizontalCenter: parent.horizontalCenter + + Rectangle { + height: 31 + width: 1 + color: "#DBDBDB" + } + + Repeater { + id: columnsRepeater + model: columnsModel + delegate: Rectangle { + id: delegate + property bool desc: false + height: 31 + width: columnWidth + + Text { + anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenterOffset: -2 + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 13 + anchors.rightMargin: 13 + elide: Text.ElideRight + font.family: "Arial" + font.pixelSize: 14 + color: { + if(delegateArea.pressed) + return "#FF4304" + return index === header.activeSortColumn || delegateArea.containsMouse ? "#FF6C3C" : "#4A4949" + } + text: columnName + } + + MouseArea { + id: delegateArea + hoverEnabled: true + anchors.fill: parent + onClicked: { + delegate.desc = !delegate.desc + header.activeSortColumn = index + header.sortRequest(delegate.desc, index) + } + } + + Row { + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.rightMargin: 9 + + Item { + width: 14 + anchors.top: parent.top + anchors.bottom: parent.bottom + + Image { + anchors.centerIn: parent + anchors.verticalCenterOffset: -2 + source: { + if(descArea.pressed) + return "../images/descSortIndicatorPressed.png" + return index === header.activeSortColumn || descArea.containsMouse ? "../images/descSortIndicatorActived.png" : + "../images/descSortIndicator.png" + } + } + + MouseArea { + id: descArea + hoverEnabled: true + anchors.fill: parent + onClicked: { + delegate.desc = true + header.activeSortColumn = index + header.sortRequest(delegate.desc, index) + } + } + } + + Item { + width: 14 + anchors.top: parent.top + anchors.bottom: parent.bottom + + Image { + anchors.centerIn: parent + anchors.verticalCenterOffset: -3 + source: { + if(ascArea.pressed) + return "../images/ascSortIndicatorPressed.png" + return index === header.activeSortColumn || ascArea.containsMouse ? "../images/ascSortIndicatorActived.png" : + "../images/ascSortIndicator.png" + } + } + + MouseArea { + id: ascArea + hoverEnabled: true + anchors.fill: parent + onClicked: { + delegate.desc = false + header.activeSortColumn = index + header.sortRequest(delegate.desc, index) + } + } + } + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + height: 1 + color: index === header.activeSortColumn ? "#FFFFFF" : "#DBDBDB" + } + + Rectangle { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: parent.right + width: 1 + color: "#DBDBDB" + } + } + } + } +} diff --git a/components/TipItem.qml b/components/TipItem.qml new file mode 100644 index 00000000..1b2c0a38 --- /dev/null +++ b/components/TipItem.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 + +Rectangle { + property alias text: content.text + width: content.width + 12 + height: content.height + 17 + color: "#FF6C3C" + radius: 3 + + Image { + anchors.top: parent.bottom + anchors.left: parent.left + anchors.leftMargin: 8 + source: "../images/tip.png" + } + + Text { + id: content + anchors.horizontalCenter: parent.horizontalCenter + y: 6 + lineHeight: 0.7 + font.family: "Arial" + font.pixelSize: 12 + color: "#FFFFFF" + } +} diff --git a/deployment.pri b/deployment.pri new file mode 100644 index 00000000..5441b63d --- /dev/null +++ b/deployment.pri @@ -0,0 +1,27 @@ +android-no-sdk { + target.path = /data/user/qt + export(target.path) + INSTALLS += target +} else:android { + x86 { + target.path = /libs/x86 + } else: armeabi-v7a { + target.path = /libs/armeabi-v7a + } else { + target.path = /libs/armeabi + } + export(target.path) + INSTALLS += target +} else:unix { + isEmpty(target.path) { + qnx { + target.path = /tmp/$${TARGET}/bin + } else { + target.path = /opt/$${TARGET}/bin + } + export(target.path) + } + INSTALLS += target +} + +export(INSTALLS) diff --git a/filter.cpp b/filter.cpp new file mode 100644 index 00000000..cf41f648 --- /dev/null +++ b/filter.cpp @@ -0,0 +1,30 @@ +#include "filter.h" +#include + +filter::filter(QObject *parent) : + QObject(parent) +{ + m_ctrlPressed = true; +} + +bool filter::eventFilter(QObject *obj, QEvent *ev) { + switch(ev->type()) { + case QEvent::KeyPress: { + QKeyEvent *ke = static_cast(ev); + if(ke->key() == Qt::Key_Control) { + emit ctrlPressed(); + m_ctrlPressed = true; + } + } break; + case QEvent::KeyRelease: { + QKeyEvent *ke = static_cast(ev); + if(ke->key() == Qt::Key_Control) { + emit ctrlReleased(); + m_ctrlPressed = false; + } + } break; + default: break; + } + + return QObject::eventFilter(obj, ev); +} diff --git a/filter.h b/filter.h new file mode 100644 index 00000000..e9bea569 --- /dev/null +++ b/filter.h @@ -0,0 +1,24 @@ +#ifndef FILTER_H +#define FILTER_H + +#include + +class filter : public QObject +{ + Q_OBJECT + +private: + bool m_ctrlPressed; + +public: + explicit filter(QObject *parent = 0); + +protected: + bool eventFilter(QObject *obj, QEvent *ev); + +signals: + void ctrlPressed(); + void ctrlReleased(); +}; + +#endif // FILTER_H diff --git a/images/ascSortIndicator.png b/images/ascSortIndicator.png new file mode 100644 index 00000000..cc27dd61 Binary files /dev/null and b/images/ascSortIndicator.png differ diff --git a/images/ascSortIndicatorActived.png b/images/ascSortIndicatorActived.png new file mode 100644 index 00000000..fe61f83f Binary files /dev/null and b/images/ascSortIndicatorActived.png differ diff --git a/images/ascSortIndicatorPressed.png b/images/ascSortIndicatorPressed.png new file mode 100644 index 00000000..b7d29fe9 Binary files /dev/null and b/images/ascSortIndicatorPressed.png differ diff --git a/images/backToWindowIcon.png b/images/backToWindowIcon.png new file mode 100644 index 00000000..7d1c3a6e Binary files /dev/null and b/images/backToWindowIcon.png differ diff --git a/images/backToWindowIconHovered.png b/images/backToWindowIconHovered.png new file mode 100644 index 00000000..4a27a0c6 Binary files /dev/null and b/images/backToWindowIconHovered.png differ diff --git a/images/closeIcon.png b/images/closeIcon.png new file mode 100644 index 00000000..c0e65fa0 Binary files /dev/null and b/images/closeIcon.png differ diff --git a/images/connectedImage.png b/images/connectedImage.png new file mode 100644 index 00000000..e21e73c4 Binary files /dev/null and b/images/connectedImage.png differ diff --git a/images/descSortIndicator.png b/images/descSortIndicator.png new file mode 100644 index 00000000..8a3f1627 Binary files /dev/null and b/images/descSortIndicator.png differ diff --git a/images/descSortIndicatorActived.png b/images/descSortIndicatorActived.png new file mode 100644 index 00000000..71c361b2 Binary files /dev/null and b/images/descSortIndicatorActived.png differ diff --git a/images/descSortIndicatorPressed.png b/images/descSortIndicatorPressed.png new file mode 100644 index 00000000..ae2397f7 Binary files /dev/null and b/images/descSortIndicatorPressed.png differ diff --git a/images/disconnectedImage.png b/images/disconnectedImage.png new file mode 100644 index 00000000..b577904f Binary files /dev/null and b/images/disconnectedImage.png differ diff --git a/images/dropIndicator.png b/images/dropIndicator.png new file mode 100644 index 00000000..1aa931fe Binary files /dev/null and b/images/dropIndicator.png differ diff --git a/images/dropdownOption1.png b/images/dropdownOption1.png new file mode 100644 index 00000000..b4f9c637 Binary files /dev/null and b/images/dropdownOption1.png differ diff --git a/images/dropdownSearch.png b/images/dropdownSearch.png new file mode 100644 index 00000000..c7102e38 Binary files /dev/null and b/images/dropdownSearch.png differ diff --git a/images/dropdownSend.png b/images/dropdownSend.png new file mode 100644 index 00000000..9ca1cf51 Binary files /dev/null and b/images/dropdownSend.png differ diff --git a/images/helpIcon.png b/images/helpIcon.png new file mode 100644 index 00000000..373e6cca Binary files /dev/null and b/images/helpIcon.png differ diff --git a/images/helpIconHovered.png b/images/helpIconHovered.png new file mode 100644 index 00000000..16476263 Binary files /dev/null and b/images/helpIconHovered.png differ diff --git a/images/hseparator.png b/images/hseparator.png new file mode 100644 index 00000000..2429f44d Binary files /dev/null and b/images/hseparator.png differ diff --git a/images/lockIcon.png b/images/lockIcon.png new file mode 100644 index 00000000..d2f0982d Binary files /dev/null and b/images/lockIcon.png differ diff --git a/images/magnifier.png b/images/magnifier.png new file mode 100644 index 00000000..809f83b2 Binary files /dev/null and b/images/magnifier.png differ diff --git a/images/maximizeIcon.png b/images/maximizeIcon.png new file mode 100644 index 00000000..177c20c5 Binary files /dev/null and b/images/maximizeIcon.png differ diff --git a/images/maximizeIconHovered.png b/images/maximizeIconHovered.png new file mode 100644 index 00000000..92a3a2ab Binary files /dev/null and b/images/maximizeIconHovered.png differ diff --git a/images/menuIndicator.png b/images/menuIndicator.png new file mode 100644 index 00000000..a8d76940 Binary files /dev/null and b/images/menuIndicator.png differ diff --git a/images/minimizeIcon.png b/images/minimizeIcon.png new file mode 100644 index 00000000..af10ae7a Binary files /dev/null and b/images/minimizeIcon.png differ diff --git a/images/minimizeIconHovered.png b/images/minimizeIconHovered.png new file mode 100644 index 00000000..8d7ac355 Binary files /dev/null and b/images/minimizeIconHovered.png differ diff --git a/images/moneroLogo.png b/images/moneroLogo.png new file mode 100644 index 00000000..8155c5fa Binary files /dev/null and b/images/moneroLogo.png differ diff --git a/images/statusConnected.png b/images/statusConnected.png new file mode 100644 index 00000000..db18925e Binary files /dev/null and b/images/statusConnected.png differ diff --git a/images/statusDisconnected.png b/images/statusDisconnected.png new file mode 100644 index 00000000..f9258246 Binary files /dev/null and b/images/statusDisconnected.png differ diff --git a/images/tableOptions.png b/images/tableOptions.png new file mode 100644 index 00000000..3e07d274 Binary files /dev/null and b/images/tableOptions.png differ diff --git a/images/tip.png b/images/tip.png new file mode 100644 index 00000000..ddb0d13d Binary files /dev/null and b/images/tip.png differ diff --git a/images/whatIsIcon.png b/images/whatIsIcon.png new file mode 100644 index 00000000..373de443 Binary files /dev/null and b/images/whatIsIcon.png differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 00000000..10743122 --- /dev/null +++ b/main.cpp @@ -0,0 +1,20 @@ +#include +#include + +#include "filter.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + filter *eventFilter = new filter; + app.installEventFilter(eventFilter); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); + QObject *rootObject = engine.rootObjects().first(); + + QObject::connect(eventFilter, SIGNAL(ctrlPressed()), rootObject, SLOT(ctrlKeyPressed())); + QObject::connect(eventFilter, SIGNAL(ctrlReleased()), rootObject, SLOT(ctrlKeyReleased())); + + return app.exec(); +} diff --git a/main.qml b/main.qml new file mode 100644 index 00000000..a3e827ea --- /dev/null +++ b/main.qml @@ -0,0 +1,77 @@ +import QtQuick 2.2 +import QtQuick.Window 2.0 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import "components" + +ApplicationWindow { + id: appWindow + property bool whatIsEnable: false + property bool ctrlPressed: false + function ctrlKeyPressed() { ctrlPressed = true; } + function ctrlKeyReleased() { ctrlPressed = false; } + + visible: true + width: 1269 + height: 932 + color: "#FFFFFF" + x: (Screen.width - width) / 2 + y: (Screen.height - height) / 2 + flags: Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint + + Item { + id: rootItem + anchors.fill: parent + + MouseArea { + property var previousPosition + anchors.fill: parent + + onPressed: previousPosition = Qt.point(mouseX, mouseY) + onPositionChanged: { + if (pressedButtons == Qt.LeftButton) { + var dx = mouseX - previousPosition.x + var dy = mouseY - previousPosition.y + appWindow.x += dx + appWindow.y += dy + } + } + } + + LeftPanel { + id: leftPanel + anchors.left: parent.left + anchors.top: parent.top + anchors.bottom: parent.bottom + onDashboardClicked: middlePanel.state = "Dashboard" + onHistoryClicked: middlePanel.state = "History" + onTransferClicked: middlePanel.state = "Transfer" + onAddressBookClicked: middlePanel.state = "AddressBook" + onMiningClicked: middlePanel.state = "Minning" + onSettingsClicked: middlePanel.state = "Settings" + } + + RightPanel { + id: rightPanel + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + } + + MiddlePanel { + id: middlePanel + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: leftPanel.right + anchors.right: rightPanel.left + state: "Dashboard" + } + + TipItem { + id: tipItem + text: "send to the same destination" + visible: false + z: 100 + } + } +} diff --git a/pages/AddressBook.qml b/pages/AddressBook.qml new file mode 100644 index 00000000..26d3c7c9 --- /dev/null +++ b/pages/AddressBook.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Rectangle { + color: "#000000" +} diff --git a/pages/Dashboard.qml b/pages/Dashboard.qml new file mode 100644 index 00000000..f8df1b18 --- /dev/null +++ b/pages/Dashboard.qml @@ -0,0 +1,125 @@ +import QtQuick 2.0 +import "../components" + +Rectangle { + color: "#F0EEEE" + + SearchInput { + id: searchInput + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.margins: 17 + z: 1 + } + + Text { + id: quickTransferText + anchors.left: parent.left + anchors.right: parent.right + anchors.top: searchInput.bottom + anchors.topMargin: 20 + elide: Text.ElideRight + anchors.margins: 17 + font.family: "Arial" + font.pixelSize: 18 + color: "#4A4949" + text: qsTr("Quick transfer") + } + + LineEdit { + id: quickTransferLine + anchors.left: parent.left + anchors.right: parent.right + anchors.top: quickTransferText.bottom + anchors.topMargin: 18 + anchors.leftMargin: 17 + anchors.rightMargin: 17 + } + + Row { + id: row + anchors.left: parent.left + anchors.right: parent.right + anchors.top: quickTransferLine.bottom + anchors.topMargin: 18 + anchors.leftMargin: 17 + anchors.rightMargin: 17 + spacing: 17 + + LineEdit { + id: amountLine + width: 148 + placeholderText: "amount..." + } + + StandardButton { + id: sendButton + width: 60 + text: qsTr("SEND") + shadowColor: "#FF4304" + releasedColor: "#FF6C3C" + pressedColor: "#FF4304" + } + + Text { + anchors.verticalCenter: parent.verticalCenter + font.family: "Arial" + font.pixelSize: 12 + color: "#545454" + text: qsTr("lookng for security level and address book? go to Transfer tab") + } + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.top: row.bottom + anchors.topMargin: 17 + color: "#FFFFFF" + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + height: 1 + color: "#DBDBDB" + } + + TableHeader { + id: header + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: 17 + anchors.leftMargin: 14 + anchors.rightMargin: 14 + onSortRequest: console.log("column: " + column + " desc: " + desc) + } + + ListModel { + id: testModel + ListElement { paymentId: "Malkolm T."; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014 12:23 AM"; amount: "19301.870709159241"; balance: "0.000709159241"; out: false } + ListElement { paymentId: "Martin"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014 12:23 AM"; amount: "19301.870709159241"; balance: "0.000709159241"; out: true } + ListElement { paymentId: "Martin"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014 12:23 AM"; amount: "19301.870709159241"; balance: "0.000709159241"; out: true } + ListElement { paymentId: ""; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014 12:23 AM"; amount: "19301.870709159241"; balance: "0.000709159241"; out: false } + ListElement { paymentId: ""; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014 12:23 AM"; amount: "19301.870709159241"; balance: "0.000709159241"; out: false } + ListElement { paymentId: "Malkolm T."; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014 12:23 AM"; amount: "19301.870709159241"; balance: "0.000709159241"; out: false } + ListElement { paymentId: ""; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014 12:23 AM"; amount: "19301.870709159241"; balance: "0.000709159241"; out: false } + ListElement { paymentId: "Malkolm T."; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014 12:23 AM"; amount: "19301.870709159241"; balance: "0.000709159241"; out: false } + ListElement { paymentId: "Malkolm T."; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014 12:23 AM"; amount: "19301.870709159241"; balance: "0.000709159241"; out: false } + ListElement { paymentId: "Malkolm T."; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014 12:23 AM"; amount: "19301.870709159241"; balance: "0.000709159241"; out: false } + } + + DashboardTable { + anchors.left: parent.left + anchors.right: parent.right + anchors.top: header.bottom + anchors.bottom: parent.bottom + anchors.leftMargin: 14 + anchors.rightMargin: 14 + model: testModel + } + } +} diff --git a/pages/History.qml b/pages/History.qml new file mode 100644 index 00000000..c972e631 --- /dev/null +++ b/pages/History.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Rectangle { + color: "#00FF00" +} diff --git a/pages/Mining.qml b/pages/Mining.qml new file mode 100644 index 00000000..af5804e7 --- /dev/null +++ b/pages/Mining.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Rectangle { + width: 100 + height: 62 +} diff --git a/pages/Settings.qml b/pages/Settings.qml new file mode 100644 index 00000000..af5804e7 --- /dev/null +++ b/pages/Settings.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Rectangle { + width: 100 + height: 62 +} diff --git a/pages/Transfer.qml b/pages/Transfer.qml new file mode 100644 index 00000000..eaf59bad --- /dev/null +++ b/pages/Transfer.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Rectangle { + color: "#0000FF" +} diff --git a/qml.qrc b/qml.qrc new file mode 100644 index 00000000..69d2c9f6 --- /dev/null +++ b/qml.qrc @@ -0,0 +1,57 @@ + + + main.qml + LeftPanel.qml + RightPanel.qml + MiddlePanel.qml + images/closeIcon.png + images/helpIcon.png + images/maximizeIcon.png + images/minimizeIcon.png + images/helpIconHovered.png + images/maximizeIconHovered.png + images/minimizeIconHovered.png + images/moneroLogo.png + components/Label.qml + images/whatIsIcon.png + images/lockIcon.png + components/MenuButton.qml + images/menuIndicator.png + pages/Dashboard.qml + pages/Transfer.qml + pages/History.qml + pages/AddressBook.qml + pages/Mining.qml + pages/Settings.qml + components/NetworkStatusItem.qml + images/statusConnected.png + images/statusDisconnected.png + components/Input.qml + components/SearchInput.qml + images/magnifier.png + components/StandardButton.qml + images/dropIndicator.png + images/hseparator.png + components/LineEdit.qml + components/TableHeader.qml + images/ascSortIndicator.png + images/ascSortIndicatorActived.png + images/ascSortIndicatorPressed.png + images/descSortIndicator.png + images/descSortIndicatorActived.png + images/descSortIndicatorPressed.png + images/backToWindowIcon.png + images/backToWindowIconHovered.png + components/DashboardTable.qml + components/TableDropdown.qml + images/tableOptions.png + images/dropdownOption1.png + images/dropdownSearch.png + images/dropdownSend.png + components/TipItem.qml + images/tip.png + tabs/Twitter.qml + tabs/tweetSearch.js + tabs/TweetsModel.qml + + diff --git a/tabs/TweetsModel.qml b/tabs/TweetsModel.qml new file mode 100644 index 00000000..19b77ab1 --- /dev/null +++ b/tabs/TweetsModel.qml @@ -0,0 +1,88 @@ +import QtQuick 2.2 +import "tweetSearch.js" as Helper + +Item { + id: wrapper + + // Insert valid consumer key and secret tokens below + // See https://dev.twitter.com/apps +//! [auth tokens] + property string tweetsMaxCount: "20" + property string consumerKey : "" + property string consumerSecret : "" +//! [auth tokens] + property string bearerToken : "" + + property variant model: tweets + property string from : "" + property string phrase : "" + + property int status: XMLHttpRequest.UNSENT + property bool isLoading: status === XMLHttpRequest.LOADING + property bool wasLoading: false + signal isLoaded + + ListModel { id: tweets } + + function encodePhrase(x) { return encodeURIComponent(x); } + + function reload() { + tweets.clear() + + if (from == "" && phrase == "") + return; + +//! [requesting] + var req = new XMLHttpRequest; + req.open("GET", "https://api.twitter.com/1.1/search/tweets.json?from=" + from + + "&count=" + tweetsMaxCount + "&q=" + encodePhrase(phrase)); + req.setRequestHeader("Authorization", "Bearer " + bearerToken); + req.onreadystatechange = function() { + status = req.readyState; + if (status === XMLHttpRequest.DONE) { + var objectArray = JSON.parse(req.responseText); + if (objectArray.errors !== undefined) + console.log("Error fetching tweets: " + objectArray.errors[0].message) + else { + for (var key in objectArray.statuses) { + var jsonObject = objectArray.statuses[key]; + tweets.append(jsonObject); + } + } + if (wasLoading == true) + wrapper.isLoaded() + } + wasLoading = (status === XMLHttpRequest.LOADING); + } + req.send(); +//! [requesting] + } + + + Component.onCompleted: { + if (consumerKey === "" || consumerSecret == "") { + console.log("setting demo token") + bearerToken = encodeURIComponent(Helper.demoToken()) + tweetsModel.phrase = "" + tweetsModel.from = "@monerocurrency" + reload() + return; + } + + var authReq = new XMLHttpRequest; + authReq.open("POST", "https://api.twitter.com/oauth2/token"); + authReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); + authReq.setRequestHeader("Authorization", "Basic " + Qt.btoa(consumerKey + ":" + consumerSecret)); + authReq.onreadystatechange = function() { + if (authReq.readyState === XMLHttpRequest.DONE) { + var jsonResponse = JSON.parse(authReq.responseText); + if (jsonResponse.errors !== undefined) + console.log("Authentication error: " + jsonResponse.errors[0].message) + else + bearerToken = jsonResponse.access_token; + } + } + authReq.send("grant_type=client_credentials"); + } + +} diff --git a/tabs/Twitter.qml b/tabs/Twitter.qml new file mode 100644 index 00000000..03c9be81 --- /dev/null +++ b/tabs/Twitter.qml @@ -0,0 +1,124 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import "tweetSearch.js" as Helper + +Item { + id: tab + ListModel { + id: testModel + ListElement { head: "Monero || #xmr"; foot: "@btcplanet Duis turpis arcu, varius nec rutrum in, adipiscing at enim. Donec quis consequat ipsum," } + ListElement { head: "Monero || #xmr"; foot: "@btcplanet Duis turpis arcu, varius nec rutrum in, adipiscing at enim. Donec quis consequat ipsum," } + ListElement { head: "Monero || #xmr"; foot: "@btcplanet Duis turpis arcu, varius nec rutrum in, adipiscing at enim. Donec quis consequat ipsum," } + ListElement { head: "Monero || #xmr"; foot: "@btcplanet Duis turpis arcu, varius nec rutrum in, adipiscing at enim. Donec quis consequat ipsum," } + ListElement { head: "Monero || #xmr"; foot: "@btcplanet Duis turpis arcu, varius nec rutrum in, adipiscing at enim. Donec quis consequat ipsum," } + ListElement { head: "Monero || #xmr"; foot: "@btcplanet Duis turpis arcu, varius nec rutrum in, adipiscing at enim. Donec quis consequat ipsum," } + ListElement { head: "Monero || #xmr"; foot: "@btcplanet Duis turpis arcu, varius nec rutrum in, adipiscing at enim. Donec quis consequat ipsum," } + ListElement { head: "Monero || #xmr"; foot: "@btcplanet Duis turpis arcu, varius nec rutrum in, adipiscing at enim. Donec quis consequat ipsum," } + ListElement { head: "Monero || #xmr"; foot: "@btcplanet Duis turpis arcu, varius nec rutrum in, adipiscing at enim. Donec quis consequat ipsum," } + ListElement { head: "Monero || #xmr"; foot: "@btcplanet Duis turpis arcu, varius nec rutrum in, adipiscing at enim. Donec quis consequat ipsum," } + ListElement { head: "Monero || #xmr"; foot: "@btcplanet Duis turpis arcu, varius nec rutrum in, adipiscing at enim. Donec quis consequat ipsum," } + ListElement { head: "Monero || #xmr"; foot: "@btcplanet Duis turpis arcu, varius nec rutrum in, adipiscing at enim. Donec quis consequat ipsum," } + } + + property int inAnimDur: 250 + property int counter: 0 + property alias isLoading: tweetsModel.isLoading + property var idx + property var ids + + Component.onCompleted: { + ids = new Array() + } + + function idInModel(id) { + for (var j = 0; j < ids.length; j++) + if (ids[j] === id) + return 1 + return 0 + } + + TweetsModel { + id: tweetsModel + onIsLoaded: { + console.debug("Reload") + idx = new Array() + for (var i = 0; i < tweetsModel.model.count; i++) { + var id = tweetsModel.model.get(i).id + if (!idInModel(id)) + idx.push(i) + } + console.debug(idx.length + " new tweets") + tab.counter = idx.length + } + } + + Timer { + id: timer + interval: 1; running: tab.counter; repeat: true + onTriggered: { + tab.counter--; + var id = tweetsModel.model.get(idx[tab.counter]).id + var item = tweetsModel.model.get(tab.counter) + listView.add({ "statusText": item.text, + "twitterName": item.user.screen_name, + "name" : item.user.name, + "userImage": item.user.profile_image_url, + "source": item.source, + "id": id, + "uri": Helper.insertLinks(item.user.url, item.user.entities), + "published": item.created_at }); + console.log(item.created_at) + ids.push(id) + } + } + + ListView { + id: listView + model: ListModel { id: finalModel } + anchors.fill: parent + clip: true + boundsBehavior: ListView.StopAtBounds + + function add(obj) { model.insert(0, obj) } + delegate: Rectangle { + height: 98 + width: listView.width + + Text { + id: headerText + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: 16 + elide: Text.ElideRight + font.family: "Arial" + font.pixelSize: 18 + color: "#000000" + text: model.name + } + + Text { + anchors.left: parent.left + anchors.right: parent.right + anchors.top: headerText.bottom + anchors.bottom: parent.bottom + anchors.topMargin: 10 + anchors.bottomMargin: 10 + wrapMode: Text.Wrap + elide: Text.ElideRight + font.family: "Arial" + font.pixelSize: 12 + color: "#535353" + text: model.statusText + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + height: 1 + color: "#DBDBDB" + } + } + } +} diff --git a/tabs/tweetSearch.js b/tabs/tweetSearch.js new file mode 100644 index 00000000..2d1c083f --- /dev/null +++ b/tabs/tweetSearch.js @@ -0,0 +1,83 @@ +.pragma library + +function formatDate(date) { + var da = new Date(date) + return da.toDateString() +} + +function demoToken() { + var a = new Array(22).join('A') + return a + String.fromCharCode(0x44, 0x69, 0x4a, 0x52, 0x51, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x74, 0x2b, 0x72, 0x6a, 0x6c, 0x2b, 0x71, + 0x6d, 0x7a, 0x30, 0x72, 0x63, 0x79, 0x2b, 0x42, 0x62, + 0x75, 0x58, 0x42, 0x42, 0x73, 0x72, 0x55, 0x48, 0x47, + 0x45, 0x67, 0x3d, 0x71, 0x30, 0x45, 0x4b, 0x32, 0x61, + 0x57, 0x71, 0x51, 0x4d, 0x62, 0x31, 0x35, 0x67, 0x43, + 0x5a, 0x4e, 0x77, 0x5a, 0x6f, 0x39, 0x79, 0x71, 0x61, + 0x65, 0x30, 0x68, 0x70, 0x65, 0x32, 0x46, 0x44, 0x73, + 0x53, 0x39, 0x32, 0x57, 0x41, 0x75, 0x30, 0x67) +} + +function linkForEntity(entity) { + return (entity.url ? entity.url : + (entity.screen_name ? 'https://twitter.com/' + entity.screen_name : + 'https://twitter.com/search?q=%23' + entity.text)) +} + +function textForEntity(entity) { + return (entity.display_url ? entity.display_url : + (entity.screen_name ? entity.screen_name : entity.text)) +} + +function insertLinks(text, entities) { + if (typeof text !== 'string') + return ""; + + if (!entities) + return text; + + // Add all links (urls, usernames and hashtags) to an array and sort them in + // descending order of appearance in text + var links = [] + if (entities.urls) + links = entities.urls.concat(entities.hashtags, entities.user_mentions) + else if (entities.url) + links = entities.url.urls + + links.sort(function(a, b) { return b.indices[0] - a.indices[0] }) + + for (var i = 0; i < links.length; i++) { + var offset = links[i].url ? 0 : 1 + text = text.substring(0, links[i].indices[0] + offset) + + '' + + textForEntity(links[i]) + '' + + text.substring(links[i].indices[1]) + } + return text.replace(/\n/g, '
'); +} + +function boldLinks(text, entities) { + if (typeof text !== 'string') + return ""; + + if (!entities) + return text; + + // Add all links (urls, usernames and hashtags) to an array and sort them in + // descending order of appearance in text + var links = [] + if (entities.urls) + links = entities.urls.concat(entities.hashtags, entities.user_mentions) + else if (entities.url) + links = entities.url.urls + + links.sort(function(a, b) { return b.indices[0] - a.indices[0] }) + + for (var i = 0; i < links.length; i++) { + var offset = links[i].url ? 0 : 1 + text = text.substring(0, links[i].indices[0] + offset) + + '' + textForEntity(links[i]) + '' + + text.substring(links[i].indices[1]) + } + return text.replace(/\n/g, '
'); +}