diff --git a/CellFrameDashboardGUI/qml.qrc b/CellFrameDashboardGUI/qml.qrc index 940d52a2f9a49fc166362b1dce5931890608d88a..0a6881da10880d56957f945dd80fb9e4b88e3767 100755 --- a/CellFrameDashboardGUI/qml.qrc +++ b/CellFrameDashboardGUI/qml.qrc @@ -173,5 +173,14 @@ <file>screen/desktop/Certificates/CertificatesLogic.qml</file> <file>screen/desktop/Certificates/parts/TitleTextView.qml</file> <file>screen/desktop/Certificates/parts/Utils.qml</file> + <file>screen/desktop/NetworksPanel/DapNetworksPanel.qml</file> + <file>resources/icons/networks_next_icon.png</file> + <file>resources/icons/networks_next_icon_hover.png</file> + <file>resources/icons/networks_previous_icon.png</file> + <file>resources/icons/networks_previous_icon_hover.png</file> + <file>screen/desktop/NetworksPanel/DapNetworkPanelButton.qml</file> + <file>screen/desktop/NetworksPanel/DapNetworksListView.qml</file> + <file>screen/desktop/NetworksPanel/DapNetworkPopup.qml</file> + <file>screen/desktop/NetworksPanel/DapNetworkName.qml</file> </qresource> </RCC> diff --git a/CellFrameDashboardGUI/resources/icons/networks_next_icon.png b/CellFrameDashboardGUI/resources/icons/networks_next_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4c062690c145ae4ff694861f755f49df5ba5247c Binary files /dev/null and b/CellFrameDashboardGUI/resources/icons/networks_next_icon.png differ diff --git a/CellFrameDashboardGUI/resources/icons/networks_next_icon_hover.png b/CellFrameDashboardGUI/resources/icons/networks_next_icon_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..3af36cffe9f631f06229d04093f1b16a9272fa21 Binary files /dev/null and b/CellFrameDashboardGUI/resources/icons/networks_next_icon_hover.png differ diff --git a/CellFrameDashboardGUI/resources/icons/networks_previous_icon.png b/CellFrameDashboardGUI/resources/icons/networks_previous_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d7dd180573e65ca308a69f268df39c55ffa44d33 Binary files /dev/null and b/CellFrameDashboardGUI/resources/icons/networks_previous_icon.png differ diff --git a/CellFrameDashboardGUI/resources/icons/networks_previous_icon_hover.png b/CellFrameDashboardGUI/resources/icons/networks_previous_icon_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..d2a245cfcf580446cb43627615c762bd055109d5 Binary files /dev/null and b/CellFrameDashboardGUI/resources/icons/networks_previous_icon_hover.png differ diff --git a/CellFrameDashboardGUI/screen/DapMainApplicationWindow.qml b/CellFrameDashboardGUI/screen/DapMainApplicationWindow.qml index 850bf02c6f2db14587ffea0f0825d141de80b701..a0030da5e79c4d03f8fc8191228b6f7caaf27a37 100644 --- a/CellFrameDashboardGUI/screen/DapMainApplicationWindow.qml +++ b/CellFrameDashboardGUI/screen/DapMainApplicationWindow.qml @@ -1,7 +1,7 @@ import QtQuick 2.4 import "qrc:/resources/QML" import "qrc:/screen/desktop/Certificates" - +import "qrc:/screen/desktop/NetworksPanel" @@ -51,7 +51,13 @@ Item { { id: rowMainWindow - anchors.fill: parent + anchors { + left: parent.left; + top: parent.top; + right: parent.right; + bottom: networksPanel.top + bottomMargin: 4 * pt + } // Virtual logo column frame and menu bar Column @@ -126,6 +132,13 @@ Item { } } + DapNetworksPanel + { + id: networksPanel + y: parent.height - height + width: parent.width + } + property var dapWallets: [] diff --git a/CellFrameDashboardGUI/screen/desktop/NetworksPanel/DapNetworkName.qml b/CellFrameDashboardGUI/screen/desktop/NetworksPanel/DapNetworkName.qml new file mode 100644 index 0000000000000000000000000000000000000000..1a8f2804eb20978ace6e99f8cdb99fa708a09831 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/NetworksPanel/DapNetworkName.qml @@ -0,0 +1,55 @@ +import QtQuick 2.9 + +Item { + id: control + + property string name + property string state + property color textColor + + Row { + id: row1 + + x: Math.floor((parent.width - width) / 2) + y: Math.floor((parent.height - height) / 2) + spacing: 8 * pt + leftPadding: spacing + rightPadding: spacing + + Text { + id: textName + + width: Math.min(implicitWidth, control.width - indicator.width - row1.spacing - row1.rightPadding - row1.leftPadding) + height: Math.min(implicitHeight, control.height) + + font: quicksandFonts.medium12 + elide: Text.ElideRight + color: control.textColor + text: control.name + } + + Rectangle { + id: indicator + + y: Math.floor((parent.height - height) / 2) + width: Math.floor(textName.height * 0.5) + height: width + radius: width * 0.5 + + color: { + switch (control.state) { + case "Online": + return "#9DD51F"; + case "Offline": + return "#FFC527"; + //TODO: добавить ÑоÑтоÑÐ½Ð¸Ñ Ð¸Ð· DapNetwork::stateToString + default: + if (control.state.length > 0) + console.warn("Unknown network state: " + control.state); + return "#000000"; + } + } + } + } + +} diff --git a/CellFrameDashboardGUI/screen/desktop/NetworksPanel/DapNetworkPanelButton.qml b/CellFrameDashboardGUI/screen/desktop/NetworksPanel/DapNetworkPanelButton.qml new file mode 100644 index 0000000000000000000000000000000000000000..493057295fb2d2ef7678c929808be081484250b9 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/NetworksPanel/DapNetworkPanelButton.qml @@ -0,0 +1,27 @@ +import QtQuick 2.9 + +Item { + id: control + + property string normalIcon + property string hoverIcon + + signal clicked + + implicitWidth: 40 * pt + implicitHeight: 40 * pt + + Image { + anchors.fill: parent + source: mouseArea.containsMouse ? control.hoverIcon : control.normalIcon + } + + MouseArea { + id: mouseArea + + anchors.fill: parent + hoverEnabled: true + + onClicked: control.clicked() + } +} diff --git a/CellFrameDashboardGUI/screen/desktop/NetworksPanel/DapNetworkPopup.qml b/CellFrameDashboardGUI/screen/desktop/NetworksPanel/DapNetworkPopup.qml new file mode 100644 index 0000000000000000000000000000000000000000..c0591cd7c920318664dd6e57446d093ed0399561 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/NetworksPanel/DapNetworkPopup.qml @@ -0,0 +1,192 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.9 +import QtQuick.Layouts 1.9 +import QtGraphicalEffects 1.9 + +Popup { + id: control + + property QtObject networkDelegateItem + + property point networkDelegateItemCoords: networkDelegateItem ? parent.mapFromItem(networkDelegateItem.parent, networkDelegateItem.x, networkDelegateItem.y) : Qt.point(0, 0) + property int networkDelegateItemWidth: networkDelegateItem ? networkDelegateItem.width : 0 + property int networkDelegateItemHeight: networkDelegateItem ? networkDelegateItem.height : 0 + + property string name: networkDelegateItem ? networkDelegateItem.name : "" + property string state: networkDelegateItem ? networkDelegateItem.state : "" + property string targetState: networkDelegateItem ? networkDelegateItem.targetState : "" + property int activeLinksCount: networkDelegateItem ? networkDelegateItem.activeLinksCount : 0 + property int linksCount: networkDelegateItem ? networkDelegateItem.linksCount : 0 + property string nodeAddress: networkDelegateItem ? networkDelegateItem.nodeAddress : "" + + x: networkDelegateItemCoords.x + y: networkDelegateItemCoords.y + networkDelegateItemHeight - height + width: networkDelegateItemWidth + height: contentHeight + + parent: Overlay.overlay + margins: 0 + padding: 0 + + enter: Transition { + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 100 } + } + + exit: Transition { + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 100 } + } + + contentItem: Item { + id: contentItem + + implicitWidth: columnItem.width + implicitHeight: columnItem.height + + MouseArea { + id: contentItemMouseArea + + width: parent.width + height: parent.height + hoverEnabled: true + } + + Column { + id: columnItem + + topPadding: 20 * pt + spacing: Math.floor(control.networkDelegateItemHeight / 2) + + ColumnLayout { + width: contentItem.width + + RowLayout { + Text { + font: quicksandFonts.medium12 + color: "#070023" + text: qsTr("State: ") + } + Text { + font: quicksandFonts.medium12 + color: "#070023" + elide: Text.ElideRight + text: control.state + Layout.fillWidth: true + Layout.maximumWidth: Math.ceil(implicitWidth) + } + + Layout.alignment: Qt.AlignHCenter + } + + RowLayout { + Text { + font: quicksandFonts.medium12 + color: "#070023" + text: qsTr("Target state: ") + } + Text { + font: quicksandFonts.medium12 + color: "#070023" + elide: Text.ElideRight + text: control.targetState + Layout.fillWidth: true + Layout.maximumWidth: Math.ceil(implicitWidth) + } + + Layout.alignment: Qt.AlignHCenter + } + + RowLayout { + Text { + font: quicksandFonts.medium12 + color: "#070023" + text: qsTr("Active links: ") + } + Text { + font: quicksandFonts.medium12 + color: "#070023" + elide: Text.ElideRight + text: control.activeLinksCount + qsTr(" from ") + control.linksCount + Layout.fillWidth: true + Layout.maximumWidth: Math.ceil(implicitWidth) + } + + Layout.alignment: Qt.AlignHCenter + } + + RowLayout { + Text { + id: textAddress + font: quicksandFonts.medium12 + color: "#070023" + text: qsTr("Address: ") + } + Text { + font: quicksandFonts.medium12 + color: "#070023" + elide: Text.ElideRight + text: control.nodeAddress + Layout.fillWidth: true + Layout.maximumWidth: Math.ceil(implicitWidth) + } + Image { + source: btnCopyAddressMouseArea.containsMouse ? "qrc:/resources/icons/ic_copy_hover.png" : "qrc:/resources/icons/ic_copy.png" + + Layout.maximumWidth: Math.floor(textAddress.height * 1.1) + Layout.maximumHeight: Layout.maximumWidth + + MouseArea { + id: btnCopyAddressMouseArea + + anchors.fill: parent + hoverEnabled: true + + onClicked: { + // TODO: copy control.nodeAddress to clipboard + console.log("Clicked copy nodeAddres. nodeAddres: " + control.nodeAddress); + } + } + } + + Layout.alignment: Qt.AlignHCenter + } + } + + DapNetworkName { + id: networkName + + y: parent.height - height + width: control.networkDelegateItemWidth + height: control.networkDelegateItemHeight + textColor: "#070023" + name: control.name + state: control.state + } + } + } + + background: Item { + Rectangle { + id: r1 + width: parent.width + height: parent.height + visible: true + color: "#FFFFFF" + } + + DropShadow { + anchors.fill: r1 + opacity: control.opacity === 1.0 ? 1.0 : control.opacity / 4 + source: r1 + radius: 5 + samples: 11 + color: "#80000000" + } + } + + Timer { + running: !contentItemMouseArea.containsMouse && !btnCopyAddressMouseArea.containsMouse && control.visible + interval: 100 + repeat: false + onTriggered: control.close() + } +} diff --git a/CellFrameDashboardGUI/screen/desktop/NetworksPanel/DapNetworksListView.qml b/CellFrameDashboardGUI/screen/desktop/NetworksPanel/DapNetworksListView.qml new file mode 100644 index 0000000000000000000000000000000000000000..b2d5d4acf462b7dfdcbb6dd23734c98974925412 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/NetworksPanel/DapNetworksListView.qml @@ -0,0 +1,128 @@ +import QtQuick 2.9 + +ListView { + id: control + + property bool hasLeft: d.leftIndex - 1 >= 0 + property bool hasRight: d.leftIndex + d.visibleItems < control.count + + function scrollToLeft() + { + if (hasLeft) { + d.positionViewAtIndexAnimation(d.leftIndex - 1, ListView.Beginning); + d.leftIndex--; + } + } + + function scrollToRight() + { + if (hasRight) { + d.positionViewAtIndexAnimation(d.leftIndex + d.visibleItems, ListView.End); + d.leftIndex++; + } + } + + orientation: Qt.Horizontal + clip: true + interactive: false + + // TODO код только Ð´Ð»Ñ Ñ‚ÐµÑта, удалить потом + model: ListModel { } + Component.onCompleted: { + for (var i = 0; i < 5; ++i) { + model.append({ + name: "Network #" + i, + state: i % 2 === 0 ? "Online" : "Offline", + targetState: "targetState", + activeLinksCount: i, + linksCount: i * 2, + nodeAddress: "nodeAddress_" + (i + 1) + }); + } + } + + delegate: Rectangle { + id: delegateItem + + // properties duplicated for DapNetworkPopup + property string name: model.name + property string state: model.state + property string targetState: model.targetState + property int activeLinksCount: model.activeLinksCount + property int linksCount: model.linksCount + property string nodeAddress: model.nodeAddress + + width: d.delegateWidth + height: control.height + color: "#070023" + + DapNetworkName { + width: parent.width + height: parent.height + textColor: "#FFFFFF" + name: delegateItem.name + state: delegateItem.state + } + + MouseArea { + id: delegateMouseArea + + width: parent.width + height: parent.height + hoverEnabled: true + + onEntered: { + if (index >= d.leftIndex && index < d.leftIndex + d.visibleItems) { + networkPopup.networkDelegateItem = delegateItem; + networkPopup.open(); + } + } + } + } + + DapNetworkPopup { + id: networkPopup + } + + Item { + id: d + + property int delegateWidth: { + var w = Math.max(control.width / control.count, 295 * pt); + var visibleItems = Math.max(Math.floor(control.width / w), 1); + d.visibleItems = visibleItems; + return Math.floor((control.width - w * visibleItems) / visibleItems + w); + } + + property int visibleItems: 0 + property int leftIndex: 0 + + function positionViewAtIndexAnimation(index, mode) + { + scrollAnimation.running = false; + var pos = control.contentX; + control.positionViewAtIndex(index, mode); + var dest = control.contentX; + + scrollAnimation.from = pos; + scrollAnimation.to = dest; + scrollAnimation.running = true; + } + + onDelegateWidthChanged: { + if (d.leftIndex > control.count - d.visibleItems) + d.leftIndex = control.count - d.visibleItems; + if (d.leftIndex < 0) + d.leftIndex = 0; + if (d.leftIndex < control.count) + control.positionViewAtIndex(d.leftIndex, ListView.Beginning); + } + } + + NumberAnimation { + id: scrollAnimation + target: control + property: "contentX" + duration: 100 + } +} diff --git a/CellFrameDashboardGUI/screen/desktop/NetworksPanel/DapNetworksPanel.qml b/CellFrameDashboardGUI/screen/desktop/NetworksPanel/DapNetworksPanel.qml new file mode 100644 index 0000000000000000000000000000000000000000..a7c6490667cb92bcfb077dea5fac37f50d7d2add --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/NetworksPanel/DapNetworksPanel.qml @@ -0,0 +1,39 @@ +import QtQuick 2.9 + +Rectangle { + id: control + + implicitHeight: Math.max(btnPrevious.implicitHeight, networksListView.implicitHeight, btnNext.implicitHeight) + implicitWidth: btnPrevious.implicitWidth + btnNext.implicitWidth + 180 * pt + + color: "#070023" + + DapNetworkPanelButton { + id: btnPrevious + + visible: networksListView.hasLeft + height: parent.height + normalIcon: "qrc:/resources/icons/networks_previous_icon.png" + hoverIcon: "qrc:/resources/icons/networks_previous_icon_hover.png" + onClicked: networksListView.scrollToLeft() + } + + DapNetworksListView { + id: networksListView + + anchors.left: btnPrevious.right + anchors.right: btnNext.left + height: parent.height + } + + DapNetworkPanelButton { + id: btnNext + + visible: networksListView.hasRight + anchors.right: parent.right + height: parent.height + normalIcon: "qrc:/resources/icons/networks_next_icon.png" + hoverIcon: "qrc:/resources/icons/networks_next_icon_hover.png" + onClicked: networksListView.scrollToRight() + } +}