diff --git a/components/DaemonConsole.qml b/components/DaemonConsole.qml
index 2643a339..225b2dba 100644
--- a/components/DaemonConsole.qml
+++ b/components/DaemonConsole.qml
@@ -27,22 +27,23 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import QtQuick 2.0
-import QtQuick.Controls 1.4
+import QtQuick.Controls 2.0
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.4
-import QtQuick.Window 2.0
+import QtQuick.Window 2.2
import "../components" as MoneroComponents
+import "../js/Windows.js" as Windows
+import "../js/Utils.js" as Utils
Window {
id: root
modality: Qt.ApplicationModal
- flags: Qt.Window | Qt.FramelessWindowHint
- property alias title: dialogTitle.text
+ color: "black"
+ flags: Windows.flags
property alias text: dialogContent.text
property alias content: root.text
- property alias okVisible: okButton.visible
property alias textArea: dialogContent
property var icon
@@ -50,15 +51,25 @@ Window {
signal accepted()
signal rejected()
+ onClosing: {
+ inactiveOverlay.visible = false;
+ }
function open() {
- show()
+ inactiveOverlay.visible = true;
+ show();
}
// TODO: implement without hardcoding sizes
width: 480
height: 280
+ // background gradient
+ Image {
+ anchors.fill: parent
+ source: "../images/middlePanelBg.jpg"
+ }
+
// Make window draggable
MouseArea {
anchors.fill: parent
@@ -70,79 +81,136 @@ Window {
ColumnLayout {
id: mainLayout
- spacing: 10
- anchors { fill: parent; margins: 35 }
+
+ anchors.fill: parent
+ anchors.topMargin: 20 * scaleRatio
+ anchors.margins: 35 * scaleRatio
+ spacing: 20 * scaleRatio
RowLayout {
- id: column
- //anchors {fill: parent; margins: 16 }
- Layout.alignment: Qt.AlignHCenter
+ id: content
+ Layout.fillWidth: true
+ Layout.fillHeight: true
- Label {
- id: dialogTitle
- horizontalAlignment: Text.AlignHCenter
- font.pixelSize: 32
- font.family: "Arial"
- color: "#555555"
- }
+ Flickable {
+ id: flickable
+ anchors.fill: parent
- }
+ TextArea.flickable: TextArea {
+ id : dialogContent
+ textFormat: TextEdit.RichText
+ selectByMouse: true
+ selectByKeyboard: true
+ anchors.fill: parent
+ font.family: "Ariel"
+ font.pixelSize: 14 * scaleRatio
+ color: MoneroComponents.Style.defaultFontColor
+ selectionColor: MoneroComponents.Style.dimmedFontColor
+ wrapMode: TextEdit.Wrap
+ readOnly: true
+ background: Rectangle {
+ color: "transparent"
+ anchors.fill: parent
+ border.color: Qt.rgba(255, 255, 255, 0.25);
+ border.width: 1
+ radius: 4
+ }
+ function logCommand(msg){
+ msg = log_color(msg, "lime");
+ textArea.append(msg);
+ }
+ function logMessage(msg){
+ msg = msg.trim();
+ var color = "white";
+ if(msg.toLowerCase().indexOf('error') >= 0){
+ color = "red";
+ } else if (msg.toLowerCase().indexOf('warning') >= 0){
+ color = "yellow";
+ }
- RowLayout {
- TextArea {
- id : dialogContent
- Layout.fillWidth: true
- Layout.fillHeight: true
- font.family: "Arial"
- textFormat: TextEdit.AutoText
- readOnly: true
- font.pixelSize: 12
- }
- }
+ // format multi-lines
+ if(msg.split("\n").length >= 2){
+ msg = msg.split("\n").join('
');
+ }
- // Ok/Cancel buttons
- RowLayout {
- id: buttons
- spacing: 60
- Layout.alignment: Qt.AlignHCenter
+ log(msg, color);
+ }
+ function log_color(msg, color){
+ return "" + msg + "";
+ }
+ function log(msg, color){
+ var timestamp = Utils.formatDate(new Date(), {
+ weekday: undefined,
+ month: "numeric",
+ timeZoneName: undefined
+ });
- MoneroComponents.StandardButton {
- id: okButton
- width: 120
- fontSize: 14
- text: qsTr("Close") + translationManager.emptyString
- onClicked: {
- root.close()
- root.accepted()
+ var _timestamp = log_color("[" + timestamp + "]", "#FFFFFF");
+ var _msg = log_color(msg, color);
+ textArea.append(_timestamp + " " + _msg);
+ // scroll to bottom
+ if(flickable.contentHeight > content.height){
+ flickable.contentY = flickable.contentHeight + 20;
+ }
+ }
+ }
+
+ ScrollBar.vertical: ScrollBar {
+ // TODO: scrollbar always visible is buggy.
+ // QT 5.9 introduces `policy: ScrollBar.AlwaysOn`
+ contentItem.opacity: 1
+ anchors.top: flickable.top
+ anchors.left: flickable.right
+ anchors.leftMargin: 10 * scaleRatio
+ anchors.bottom: flickable.bottom
}
}
+ }
+
+ RowLayout {
+ Layout.fillWidth: true
MoneroComponents.LineEdit {
id: sendCommandText
- width: 300
+ Layout.fillWidth: true
placeholderText: qsTr("command + enter (e.g help)") + translationManager.emptyString
onAccepted: {
- if(text.length > 0)
- daemonManager.sendCommand(text,currentWallet.nettype);
+ if(text.length > 0) {
+ textArea.logCommand(">>> " + text)
+ daemonManager.sendCommand(text, currentWallet.nettype);
+ }
text = ""
}
}
-
- // Status button
-// MoneroComponents.StandardButton {
-// id: sendCommandButton
-// enabled: sendCommandText.text.length > 0
-// fontSize: 14
-// text: qsTr("Send command")
-// onClicked: {
-// daemonManager.sendCommand(sendCommandText.text,currentWallet.testnet);
-// }
-// }
}
}
-}
-
+ // window borders
+ Rectangle {
+ anchors.bottom: parent.bottom
+ anchors.top: parent.top
+ anchors.left: parent.left
+ width:1
+ color: "#2F2F2F"
+ z: 2
+ }
+ Rectangle {
+ anchors.bottom: parent.bottom
+ anchors.top: parent.top
+ anchors.right: parent.right
+ width:1
+ color: "#2F2F2F"
+ z: 2
+ }
+ Rectangle {
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ anchors.left: parent.left
+ height:1
+ color: "#2F2F2F"
+ z: 2
+ }
+}
\ No newline at end of file
diff --git a/components/NewPasswordDialog.qml b/components/NewPasswordDialog.qml
index d83364de..d94b5407 100644
--- a/components/NewPasswordDialog.qml
+++ b/components/NewPasswordDialog.qml
@@ -38,13 +38,7 @@ import "../components" as MoneroComponents
Item {
id: root
visible: false
- Rectangle {
- id: bg
- z: parent.z + 1
- anchors.fill: parent
- color: "black"
- opacity: 0.8
- }
+ z: parent.z + 2
property alias password: passwordInput1.text
diff --git a/components/PasswordDialog.qml b/components/PasswordDialog.qml
index 1f75f461..1534e1f3 100644
--- a/components/PasswordDialog.qml
+++ b/components/PasswordDialog.qml
@@ -38,6 +38,7 @@ import "../components" as MoneroComponents
Item {
id: root
visible: false
+ z: parent.z + 2
property alias password: passwordInput.text
property string walletName
@@ -48,6 +49,7 @@ Item {
signal closeCallback()
function open(walletName) {
+ inactiveOverlay.visible = true // draw appwindow inactive
root.walletName = walletName ? walletName : ""
leftPanel.enabled = false
middlePanel.enabled = false
@@ -59,6 +61,7 @@ Item {
}
function close() {
+ inactiveOverlay.visible = false
leftPanel.enabled = true
middlePanel.enabled = true
titleBar.enabled = true
@@ -166,11 +169,4 @@ Item {
}
}
- Rectangle {
- id: bg
-
- anchors.fill: parent
- color: "black"
- opacity: 0.8
- }
}
diff --git a/components/TitleBar.qml b/components/TitleBar.qml
index 3fd9a8a0..166e2be9 100644
--- a/components/TitleBar.qml
+++ b/components/TitleBar.qml
@@ -33,39 +33,55 @@ import QtQuick.Layouts 1.1
Rectangle {
id: titleBar
+ height: {
+ if(!customDecorations || isMobile){
+ return 0;
+ }
+
+ if(small) return 38 * scaleRatio;
+ else return 50 * scaleRatio;
+ }
+ y: -height
+ z: 1
+
+ property string title
property int mouseX: 0
property bool containsMouse: false
property alias basicButtonVisible: goToBasicVersionButton.visible
- property bool customDecorations: true
+ property bool customDecorations: persistentSettings.customDecorations
+ property bool showWhatIsButton: true
+ property bool showMinimizeButton: false
+ property bool showMaximizeButton: false
+ property bool showCloseButton: true
+ property bool showMoneroLogo: false
+ property bool small: false
+
+ signal closeClicked
+ signal maximizeClicked
+ signal minimizeClicked
signal goToBasicVersion(bool yes)
- height: customDecorations && !isMobile ? 50 : 0
- y: -height
- property string title
- property alias maximizeButtonVisible: maximizeButton.visible
- z: 1
Item {
- id: test
+ // Background gradient
width: parent.width
- height: 50
- z: 1
+ height: s
+ z: parent.z + 1
- // use jpg for gradiency
Image {
- anchors.fill: parent
- height: parent.height
- width: parent.width
+ anchors.fill: titleBar
+ height: titleBar.height
+ width: titleBar.width
source: "../images/titlebarGradient.jpg"
}
}
- Item{
+ Item {
id: titlebarlogo
width: 125
- height: 50
+ height: parent.height
anchors.centerIn: parent
- visible: customDecorations
- z: 1
+ visible: customDecorations && showMoneroLogo
+ z: parent.z + 1
Image {
anchors.left: parent.left
@@ -77,6 +93,15 @@ Rectangle {
}
}
+ Label {
+ id: titleLabel
+ visible: !showMoneroLogo && customDecorations && titleBar.title !== ''
+ anchors.centerIn: parent
+ fontSize: 18
+ text: titleBar.title
+ z: parent.z + 1
+ }
+
// collapse left panel
Rectangle {
id: goToBasicVersionButton
@@ -85,10 +110,10 @@ Rectangle {
anchors.top: parent.top
anchors.left: parent.left
color: "transparent"
- height: 50 * scaleRatio
+ height: titleBar.height
width: height
visible: isMobile
- z: 2
+ z: parent.z + 2
Image {
width: 14
@@ -118,10 +143,11 @@ Rectangle {
anchors.top: parent.top
anchors.bottom: parent.bottom
visible: parent.customDecorations
- z: 2
+ z: parent.z + 2
Rectangle {
id: minimizeButton
+ visible: showMinimizeButton
anchors.top: parent.top
anchors.bottom: parent.bottom
width: 42
@@ -139,14 +165,13 @@ Rectangle {
cursorShape: Qt.PointingHandCursor
onEntered: minimizeButton.color = "#262626";
onExited: minimizeButton.color = "transparent";
- onClicked: {
- appWindow.visibility = Window.Minimized
- }
+ onClicked: minimizeClicked();
}
}
Rectangle {
id: maximizeButton
+ visible: showMaximizeButton
anchors.top: parent.top
anchors.bottom: parent.bottom
width: 42
@@ -167,15 +192,13 @@ Rectangle {
cursorShape: Qt.PointingHandCursor
onEntered: maximizeButton.color = "#262626";
onExited: maximizeButton.color = "transparent";
- onClicked: {
- appWindow.visibility = appWindow.visibility !== Window.FullScreen ? Window.FullScreen :
- Window.Windowed
- }
+ onClicked: maximizeClicked();
}
}
Rectangle {
id: closeButton
+ visible: showCloseButton
anchors.top: parent.top
anchors.bottom: parent.bottom
width: 42
@@ -190,7 +213,7 @@ Rectangle {
MouseArea {
anchors.fill: parent
- onClicked: appWindow.close();
+ onClicked: closeClicked();
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onEntered: closeButton.color = "#262626";
@@ -199,4 +222,23 @@ Rectangle {
}
}
+ // window borders
+ Rectangle {
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ anchors.left: parent.left
+ height: 1
+ color: "#2F2F2F"
+ z: parent.z + 1
+ }
+
+ Rectangle {
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.left: parent.left
+ visible: titleBar.small
+ height: 1
+ color: "#2F2F2F"
+ z: parent.z + 1
+ }
}
diff --git a/js/Utils.js b/js/Utils.js
new file mode 100644
index 00000000..7cf582b2
--- /dev/null
+++ b/js/Utils.js
@@ -0,0 +1,25 @@
+/**
+ * Formats a date.
+ * @param {date} date - toggle decorations
+ * @param {params} params -
+ */
+function formatDate( date, params ) {
+ var options = {
+ weekday: "short",
+ year: "numeric",
+ month: "long",
+ day: "numeric",
+ hour: "2-digit",
+ minute: "2-digit",
+ timeZone: "UTC",
+ timeZoneName: "short",
+ };
+
+ options = [options, params].reduce(function (r, o) {
+ Object.keys(o).forEach(function (k) { r[k] = o[k]; });
+ return r;
+ }, {});
+
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString
+ return new Date( date ).toLocaleString( 'en-US', options );
+}
diff --git a/js/Windows.js b/js/Windows.js
new file mode 100644
index 00000000..be2f503e
--- /dev/null
+++ b/js/Windows.js
@@ -0,0 +1,34 @@
+var flagsCustomDecorations = (Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint);
+var flags = (Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint | Qt.WindowTitleHint | Qt.WindowMaximizeButtonHint);
+
+/**
+ * Toggles window decorations
+ * @param {bool} custom - toggle decorations
+ */
+function setCustomWindowDecorations(custom) {
+ // save x,y positions, because we need to hide/show the window
+ var x = appWindow.x
+ var y = appWindow.y
+ if (x < 0) x = 0
+ if (y < 0) y = 0
+
+ // Update persistentSettings
+ persistentSettings.customDecorations = custom;
+
+ titleBar.visible = custom;
+ daemonConsolePopup.titleBar.visible = custom;
+
+ if (custom) {
+ appWindow.flags = flagsCustomDecorations;
+ daemonConsolePopup.flags = flagsCustomDecorations;
+ } else {
+ appWindow.flags = flags;
+ daemonConsolePopup.flags = flags;
+ }
+
+ // Reset window
+ appWindow.hide()
+ appWindow.x = x
+ appWindow.y = y
+ appWindow.show()
+}
diff --git a/main.qml b/main.qml
index d3a56796..50621493 100644
--- a/main.qml
+++ b/main.qml
@@ -40,6 +40,7 @@ import moneroComponents.NetworkType 1.0
import "components"
import "wizard"
+import "js/Windows.js" as Windows
ApplicationWindow {
id: appWindow
@@ -933,30 +934,9 @@ ApplicationWindow {
// width: screenWidth //rightPanelExpanded ? 1269 : 1269 - 300
// height: 900 //300//maxWindowHeight;
color: "#FFFFFF"
- flags: persistentSettings.customDecorations ? (Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint) : (Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint | Qt.WindowTitleHint | Qt.WindowMaximizeButtonHint)
+ flags: persistentSettings.customDecorations ? Windows.flagsCustomDecorations : Windows.flags
onWidthChanged: x -= 0
- function setCustomWindowDecorations(custom) {
- var x = appWindow.x
- var y = appWindow.y
- if (x < 0)
- x = 0
- if (y < 0)
- y = 0
- persistentSettings.customDecorations = custom;
- titleBar.visible = custom; // hides custom titlebar based on customDecorations
-
- if (custom)
- appWindow.flags = Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint;
- else
- appWindow.flags = Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint | Qt.WindowTitleHint | Qt.WindowMaximizeButtonHint;
-
- appWindow.hide()
- appWindow.x = x
- appWindow.y = y
- appWindow.show()
- }
-
Component.onCompleted: {
x = (Screen.width - width) / 2
y = (Screen.height - maxWindowHeight) / 2
@@ -1281,7 +1261,7 @@ ApplicationWindow {
PropertyChanges { target: appWindow; width: (screenWidth < 930 || isAndroid || isIOS)? screenWidth : 930; }
PropertyChanges { target: appWindow; height: maxWindowHeight; }
PropertyChanges { target: resizeArea; visible: true }
- PropertyChanges { target: titleBar; maximizeButtonVisible: false }
+ PropertyChanges { target: titleBar; showMaximizeButton: false }
// PropertyChanges { target: frameArea; blocked: true }
PropertyChanges { target: titleBar; visible: false }
PropertyChanges { target: titleBar; y: 0 }
@@ -1297,7 +1277,7 @@ ApplicationWindow {
PropertyChanges { target: appWindow; width: (screenWidth < 969 || isAndroid || isIOS)? screenWidth : 969 } //rightPanelExpanded ? 1269 : 1269 - 300;
PropertyChanges { target: appWindow; height: maxWindowHeight; }
PropertyChanges { target: resizeArea; visible: true }
- PropertyChanges { target: titleBar; maximizeButtonVisible: true }
+ PropertyChanges { target: titleBar; showMaximizeButton: true }
// PropertyChanges { target: frameArea; blocked: true }
PropertyChanges { target: titleBar; visible: true }
// PropertyChanges { target: titleBar; y: 0 }
@@ -1616,11 +1596,20 @@ ApplicationWindow {
TitleBar {
id: titleBar
- anchors.left: parent.left
- anchors.right: parent.right
x: 0
y: 0
- customDecorations: persistentSettings.customDecorations
+ anchors.left: parent.left
+ anchors.right: parent.right
+ showMinimizeButton: true
+ showMaximizeButton: true
+ showWhatIsButton: false
+ showMoneroLogo: true
+ onCloseClicked: appWindow.close();
+ onMaximizeClicked: {
+ appWindow.visibility = appWindow.visibility !== Window.FullScreen ? Window.FullScreen :
+ Window.Windowed
+ }
+ onMinimizeClicked: appWindow.visibility = Window.Minimized
onGoToBasicVersion: {
if (yes) {
// basicPanel.currentView = middlePanel.currentView
@@ -1649,15 +1638,6 @@ ApplicationWindow {
}
}
}
-
- Rectangle {
- anchors.bottom: parent.bottom
- anchors.right: parent.right
- anchors.left: parent.left
- height:1
- color: "#2F2F2F"
- z: 2
- }
}
// new ToolTip
@@ -1824,7 +1804,25 @@ ApplicationWindow {
middlePanel.focus = true
middlePanel.focus = false
}
+ }
+ // Daemon console
+ DaemonConsole {
+ id: daemonConsolePopup
+ height:500
+ width:800
+ title: qsTr("Daemon log") + translationManager.emptyString
+ onAccepted: {
+ close();
+ }
+ }
+ // background gradient
+ Rectangle {
+ id: inactiveOverlay
+ visible: false
+ anchors.fill: parent
+ color: "black"
+ opacity: 0.8
}
}
diff --git a/pages/Settings.qml b/pages/Settings.qml
index bc9c689c..0b27c898 100644
--- a/pages/Settings.qml
+++ b/pages/Settings.qml
@@ -32,6 +32,8 @@ import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2
import "../version.js" as Version
+import "../js/Windows.js" as Windows
+import "../js/Utils.js" as Utils
import "../components"
@@ -501,7 +503,7 @@ Rectangle {
visible: !isMobile
id: customDecorationsCheckBox
checked: persistentSettings.customDecorations
- onClicked: appWindow.setCustomWindowDecorations(checked)
+ onClicked: Windows.setCustomWindowDecorations(checked)
text: qsTr("Custom decorations") + translationManager.emptyString
}
}
@@ -719,17 +721,6 @@ Rectangle {
}
}
- // Daemon console
- DaemonConsole {
- id: daemonConsolePopup
- height:500
- width:800
- title: qsTr("Daemon log") + translationManager.emptyString
- onAccepted: {
- close();
- }
- }
-
// Choose blockchain folder
FileDialog {
id: blockchainFileDialog
@@ -794,7 +785,7 @@ Rectangle {
function onDaemonConsoleUpdated(message){
// Update daemon console
- daemonConsolePopup.textArea.append(message)
+ daemonConsolePopup.textArea.logMessage(message)
}
diff --git a/qml.qrc b/qml.qrc
index 42b868e6..4e605d89 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -206,5 +206,7 @@
images/warning.png
images/checkedBlackIcon.png
images/rightArrowInactive.png
+ js/Windows.js
+ js/Utils.js