212 lines
6.0 KiB
QML
212 lines
6.0 KiB
QML
import QtQuick 2.4
|
|
import QtQuick.Controls 1.3
|
|
import QtQuick.Window 2.2
|
|
import Qt.labs.platform 1.0
|
|
|
|
import ApiPoller 1.0
|
|
import LokinetApiClient 1.0
|
|
import PlatformDetails 1.0
|
|
import "."
|
|
|
|
ApplicationWindow {
|
|
id: window
|
|
title: qsTr("Lokinet Control Panel")
|
|
visible: true
|
|
flags: nohide ? Qt.Window : Qt.FramelessWindowHint
|
|
maximumHeight: minimumHeight
|
|
maximumWidth: minimumWidth
|
|
|
|
color: Style.panelSeparatorColor
|
|
|
|
// crude way to dismiss main window when it loses focus.
|
|
// this isn't going to work well on a "sloppy focus" window managers, but
|
|
// probably works well on the most common OSes
|
|
onActiveChanged: {
|
|
if (!active && !nohide) {
|
|
window.visible = false;
|
|
}
|
|
}
|
|
|
|
|
|
onClosing: {
|
|
window.exitApp();
|
|
}
|
|
|
|
|
|
ControlPanel {
|
|
id: controlPanel
|
|
}
|
|
|
|
BootstrapDownloadDialog {
|
|
id: bootstrapDialog
|
|
visible: false
|
|
}
|
|
|
|
function exitApp() {
|
|
if (! platformDetails.isDebug()) {
|
|
platformDetails.stopLokinetIfWeStartedIt();
|
|
}
|
|
Qt.quit();
|
|
}
|
|
|
|
function openSysTray() {
|
|
var rect = platformDetails.getAbsoluteCursorPosition();
|
|
console.log("mouse cursor at: "+ rect.x +", "+ rect.y);
|
|
|
|
// attempt to determine what quadrant the systray is positioned in
|
|
// and anchor the window to the opposite corner of the systray icon
|
|
// TODO: this technique is flawed -- it often leaves the window partially obscured
|
|
// by the taskbar (esp. when the taskbar is oriented horizontally)
|
|
var right = false;
|
|
if ((rect.x / Screen.width) >= 0.5) {
|
|
right = true;
|
|
}
|
|
|
|
var bottom = false;
|
|
if ((rect.y / Screen.height) >= 0.5) {
|
|
bottom = true;
|
|
}
|
|
|
|
console.log("right: "+ right);
|
|
console.log("bottom: "+ bottom);
|
|
|
|
console.log("window size: "+ window.width +"x"+ window.height);
|
|
|
|
// on the right side, shift left by (window width)
|
|
// on the left side, shift right by (systray icon width)
|
|
// on the bottom side, shift up by (window height)
|
|
// on the top side, shift down by systray icon height)
|
|
var winX = (right ? (rect.x - window.width) : rect.x);
|
|
var winY = (bottom ? (rect.y - window.height) : rect.y);
|
|
|
|
// systrayMenu.x = winX;
|
|
// systrayMenu.y = winY;
|
|
systrayMenu.visible = true;
|
|
}
|
|
|
|
function display() {
|
|
window.show();
|
|
window.raise();
|
|
window.requestActivate();
|
|
|
|
}
|
|
|
|
SystemTrayIcon {
|
|
id: systray
|
|
tooltip: qsTr("Loki Network")
|
|
visible: platformDetails.hasSysTray();
|
|
iconSource: "qrc:/res/images/icon.svg"
|
|
|
|
menu: Menu {
|
|
id: systrayMenu
|
|
enabled: true
|
|
|
|
MenuItem {
|
|
text: qsTr("Show")
|
|
onTriggered: {
|
|
window.display();
|
|
}
|
|
}
|
|
MenuItem {
|
|
text: qsTr("Hide")
|
|
// visible: (platformDetails.isDebug() || platformDetails.isLinux())
|
|
onTriggered: {
|
|
window.visible = false;
|
|
}
|
|
}
|
|
MenuItem {
|
|
text: qsTr("Exit")
|
|
onTriggered: {
|
|
window.exitApp();
|
|
}
|
|
}
|
|
|
|
MenuSeparator { }
|
|
|
|
MenuItem {
|
|
text: qsTr("Start lokinet")
|
|
onTriggered: {
|
|
platformDetails.startLokinetProcess();
|
|
}
|
|
}
|
|
MenuItem {
|
|
text: qsTr("Stop lokinet")
|
|
onTriggered: {
|
|
platformDetails.managedStopLokinetProcess();
|
|
}
|
|
}
|
|
|
|
MenuSeparator { }
|
|
|
|
MenuItem {
|
|
visible: !isSystemd
|
|
text: qsTr("Bootstrap Client from Web")
|
|
onTriggered: {
|
|
bootstrapDialog.visible = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// under some Linux window managers, intercepting left click (or even any click in some
|
|
// cases) is not possible. in these cases, the context menu seems to be reliably shown,
|
|
// so interaction with the system tray icon will have to be through the context menu in
|
|
// these cases.
|
|
//
|
|
// this leaves our behavior as:
|
|
// - left/double click: show main window (if we get these events)
|
|
// - right click: show context menu (if we get these events)
|
|
// - fallback: hope the OS/WM at least gives us the context menu automatically
|
|
onActivated: {
|
|
switch(reason) {
|
|
|
|
// right click
|
|
case SystemTrayIcon.Context:
|
|
window.openSysTray();
|
|
break;
|
|
// left click
|
|
case SystemTrayIcon.Trigger:
|
|
window.display();
|
|
break;
|
|
case SystemTrayIcon.DoubleClick:
|
|
|
|
// Qt on MacOS only gives us one event to work with, namely
|
|
// onActivated() where action == Trigger. It will also try to
|
|
// show the context menu at the same time.
|
|
// We don't want both, and we only get one, so we let Qt show
|
|
// the context menu.
|
|
if (! platformDetails.isMacOS()) {
|
|
window.display();
|
|
}
|
|
break;
|
|
|
|
default:
|
|
console.log("systray icon 'activated', but ignoring. reason: "+ reason);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
ApiPoller {
|
|
id: stateApiPoller
|
|
Component.onCompleted: {
|
|
stateApiPoller.setApiEndpoint("llarp.status");
|
|
}
|
|
}
|
|
|
|
ApiPoller {
|
|
id: statusApiPoller
|
|
Component.onCompleted: {
|
|
statusApiPoller.setApiEndpoint("llarp.version");
|
|
}
|
|
}
|
|
|
|
LokinetApiClient {
|
|
id: apiClient
|
|
}
|
|
PlatformDetails {
|
|
id: platformDetails
|
|
}
|
|
|
|
}
|
|
|