diff --git a/CMakeLists.txt b/CMakeLists.txt index 41dc895..c86334a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,8 @@ set(SRCS src/appmenu/dbusmenu_interface.cpp src/appmenu/dbusmenu_interface.h + src/poweractions.cpp + qml.qrc ) diff --git a/images/dark/system-lock-screen.svg b/images/dark/system-lock-screen.svg new file mode 100755 index 0000000..0abfd96 --- /dev/null +++ b/images/dark/system-lock-screen.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/images/dark/system-log-out.svg b/images/dark/system-log-out.svg new file mode 100644 index 0000000..c0b5106 --- /dev/null +++ b/images/dark/system-log-out.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/images/dark/system-reboot.svg b/images/dark/system-reboot.svg new file mode 100644 index 0000000..61b7222 --- /dev/null +++ b/images/dark/system-reboot.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/images/dark/system-shutdown.svg b/images/dark/system-shutdown.svg new file mode 100644 index 0000000..99e419c --- /dev/null +++ b/images/dark/system-shutdown.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/images/dark/system-suspend.svg b/images/dark/system-suspend.svg new file mode 100644 index 0000000..a2d20fb --- /dev/null +++ b/images/dark/system-suspend.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/images/light/system-lock-screen.svg b/images/light/system-lock-screen.svg new file mode 100755 index 0000000..6618df1 --- /dev/null +++ b/images/light/system-lock-screen.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/images/light/system-log-out.svg b/images/light/system-log-out.svg new file mode 100644 index 0000000..07a6400 --- /dev/null +++ b/images/light/system-log-out.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/images/light/system-reboot.svg b/images/light/system-reboot.svg new file mode 100644 index 0000000..b703ec1 --- /dev/null +++ b/images/light/system-reboot.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/images/light/system-shutdown.svg b/images/light/system-shutdown.svg new file mode 100644 index 0000000..c5f6a6d --- /dev/null +++ b/images/light/system-shutdown.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/images/light/system-suspend.svg b/images/light/system-suspend.svg new file mode 100644 index 0000000..35d5397 --- /dev/null +++ b/images/light/system-suspend.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/qml.qrc b/qml.qrc index 3767ad6..9061b67 100644 --- a/qml.qrc +++ b/qml.qrc @@ -111,5 +111,17 @@ images/dark/notification-new-symbolic.svg images/dark/notification-symbolic.svg images/logo.svg + qml/ShutdownDialog.qml + images/light/system-lock-screen.svg + images/light/system-log-out.svg + images/light/system-reboot.svg + images/light/system-shutdown.svg + images/light/system-suspend.svg + images/dark/system-lock-screen.svg + images/dark/system-log-out.svg + images/dark/system-reboot.svg + images/dark/system-shutdown.svg + images/dark/system-suspend.svg + qml/StandardCard.qml diff --git a/qml/CardItem.qml b/qml/CardItem.qml index 9ac87ab..0e3f30a 100644 --- a/qml/CardItem.qml +++ b/qml/CardItem.qml @@ -97,12 +97,17 @@ Item { anchors.fill: parent anchors.leftMargin: FishUI.Theme.smallRadius anchors.rightMargin: FishUI.Theme.smallRadius + spacing: FishUI.Units.smallSpacing + + Item { + Layout.fillHeight: true + } Image { id: _image - Layout.preferredWidth: control.height * 0.3 - Layout.preferredHeight: control.height * 0.3 - sourceSize: Qt.size(width, height) + Layout.preferredWidth: 28 + Layout.preferredHeight: 28 + sourceSize: Qt.size(28, 28) asynchronous: true Layout.alignment: Qt.AlignHCenter Layout.topMargin: FishUI.Units.largeSpacing @@ -116,19 +121,12 @@ Item { // } } - Item { - Layout.fillHeight: true - } - Label { id: _titleLabel color: control.checked ? FishUI.Theme.highlightedTextColor : FishUI.Theme.textColor Layout.preferredHeight: control.height * 0.15 Layout.alignment: Qt.AlignHCenter - } - - Item { - Layout.fillHeight: true + visible: text } Label { @@ -139,6 +137,7 @@ Item { Layout.alignment: Qt.AlignHCenter Layout.maximumWidth: control.width - FishUI.Units.largeSpacing Layout.bottomMargin: FishUI.Units.largeSpacing + visible: text } Item { diff --git a/qml/ControlCenter.qml b/qml/ControlCenter.qml index ce2d54e..5966f5f 100644 --- a/qml/ControlCenter.qml +++ b/qml/ControlCenter.qml @@ -212,17 +212,17 @@ ControlCenterDialog { } } - IconButton { - id: shutdownButton - implicitWidth: topItem.height - implicitHeight: topItem.height - Layout.alignment: Qt.AlignTop - source: "qrc:/images/" + (FishUI.Theme.darkMode ? "dark/" : "light/") + "system-shutdown-symbolic.svg" - onLeftButtonClicked: { - control.visible = false - process.startDetached("cutefish-shutdown") - } - } +// IconButton { +// id: shutdownButton +// implicitWidth: topItem.height +// implicitHeight: topItem.height +// Layout.alignment: Qt.AlignTop +// source: "qrc:/images/" + (FishUI.Theme.darkMode ? "dark/" : "light/") + "system-shutdown-symbolic.svg" +// onLeftButtonClicked: { +// control.visible = false +// process.startDetached("cutefish-shutdown") +// } +// } } } diff --git a/qml/ShutdownDialog.qml b/qml/ShutdownDialog.qml new file mode 100644 index 0000000..fedb341 --- /dev/null +++ b/qml/ShutdownDialog.qml @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2021 - 2022 CutefishOS Team. + * + * Author: Kate Leet + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Window 2.12 +import QtQuick.Layouts 1.12 +import QtGraphicalEffects 1.0 + +import Cutefish.Accounts 1.0 as Accounts +import Cutefish.Bluez 1.0 as Bluez +import Cutefish.StatusBar 1.0 +import Cutefish.Audio 1.0 +import FishUI 1.0 as FishUI + +ControlCenterDialog { + id: control + + width: _mainLayout.implicitWidth + FishUI.Units.largeSpacing * 3 + height: _mainLayout.implicitHeight + FishUI.Units.largeSpacing * 3 + + onWidthChanged: adjustCorrectLocation() + onHeightChanged: adjustCorrectLocation() + onPositionChanged: adjustCorrectLocation() + + property point position: Qt.point(0, 0) + property var margin: 4 * Screen.devicePixelRatio + property var borderColor: windowHelper.compositing ? FishUI.Theme.darkMode ? Qt.rgba(255, 255, 255, 0.3) + : Qt.rgba(0, 0, 0, 0.2) : FishUI.Theme.darkMode ? Qt.rgba(255, 255, 255, 0.15) + : Qt.rgba(0, 0, 0, 0.15) + + FishUI.WindowBlur { + view: control + geometry: Qt.rect(control.x, control.y, control.width, control.height) + windowRadius: _background.radius + enabled: true + } + + FishUI.WindowShadow { + view: control + geometry: Qt.rect(control.x, control.y, control.width, control.height) + radius: _background.radius + } + + Rectangle { + id: _background + anchors.fill: parent + radius: windowHelper.compositing ? FishUI.Theme.bigRadius * 1.5 : 0 + color: FishUI.Theme.darkMode ? "#4D4D4D" : "#FFFFFF" + opacity: windowHelper.compositing ? FishUI.Theme.darkMode ? 0.5 : 0.7 : 1.0 + antialiasing: true + border.width: 1 / Screen.devicePixelRatio + border.pixelAligned: Screen.devicePixelRatio > 1 ? false : true + border.color: control.borderColor + + Behavior on color { + ColorAnimation { + duration: 200 + easing.type: Easing.Linear + } + } + } + + GridLayout { + id: _mainLayout + anchors.fill: parent + anchors.margins: FishUI.Units.largeSpacing * 1.5 + rowSpacing: FishUI.Units.largeSpacing + columnSpacing: FishUI.Units.largeSpacing + columns: 3 + + StandardCard { + Layout.preferredWidth: 96 + Layout.preferredHeight: 96 + icon: FishUI.Theme.darkMode ? "qrc:/images/dark/system-shutdown.svg" + : "qrc:/images/light/system-shutdown.svg" + visible: true + checked: false + text: qsTr("Shutdown") + + onClicked: { + control.visible = false + actions.shutdown() + } + } + + StandardCard { + Layout.preferredWidth: 96 + Layout.preferredHeight: 96 + icon: FishUI.Theme.darkMode ? "qrc:/images/dark/system-reboot.svg" + : "qrc:/images/light/system-reboot.svg" + visible: true + checked: false + text: qsTr("Reboot") + + onClicked: { + control.visible = false + actions.reboot() + } + } + + StandardCard { + Layout.preferredWidth: 96 + Layout.preferredHeight: 96 + icon: FishUI.Theme.darkMode ? "qrc:/images/dark/system-log-out.svg" + : "qrc:/images/light/system-log-out.svg" + visible: true + checked: false + text: qsTr("Log out") + + onClicked: { + control.visible = false + actions.logout() + } + } + + StandardCard { + Layout.preferredWidth: 96 + Layout.preferredHeight: 96 + icon: FishUI.Theme.darkMode ? "qrc:/images/dark/system-lock-screen.svg" + : "qrc:/images/light/system-lock-screen.svg" + visible: true + checked: false + text: qsTr("Lock Screen") + + onClicked: { + control.visible = false + actions.lockScreen() + } + } + + StandardCard { + Layout.preferredWidth: 96 + Layout.preferredHeight: 96 + icon: FishUI.Theme.darkMode ? "qrc:/images/dark/system-suspend.svg" + : "qrc:/images/light/system-suspend.svg" + visible: true + checked: false + text: qsTr("Suspend") + + onClicked: { + control.visible = false + actions.suspend() + } + } + } + + PowerActions { + id: actions + } + + function adjustCorrectLocation() { + var posX = control.position.x + var posY = control.position.y + + if (posX + control.width >= StatusBar.screenRect.x + StatusBar.screenRect.width) + posX = StatusBar.screenRect.x + StatusBar.screenRect.width - control.width - control.margin + + posY = rootItem.y + rootItem.height + control.margin + + control.x = posX + control.y = posY + } +} diff --git a/qml/StandardCard.qml b/qml/StandardCard.qml new file mode 100644 index 0000000..3350257 --- /dev/null +++ b/qml/StandardCard.qml @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2021 CutefishOS Team. + * + * Author: Reion Wong + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import QtGraphicalEffects 1.0 +import FishUI 1.0 as FishUI + +Item { + id: control + + property bool checked: false + property alias icon: _image.source + property alias text: _label.text + + signal clicked + signal pressAndHold + + property var backgroundColor: FishUI.Theme.darkMode ? Qt.rgba(255, 255, 255, 0.1) + : Qt.rgba(0, 0, 0, 0.05) + property var hoverColor: FishUI.Theme.darkMode ? Qt.rgba(255, 255, 255, 0.15) + : Qt.rgba(0, 0, 0, 0.1) + property var pressedColor: FishUI.Theme.darkMode ? Qt.rgba(255, 255, 255, 0.2) + : Qt.rgba(0, 0, 0, 0.15) + + property var highlightHoverColor: FishUI.Theme.darkMode ? Qt.lighter(FishUI.Theme.highlightColor, 1.1) + : Qt.darker(FishUI.Theme.highlightColor, 1.1) + property var highlightPressedColor: FishUI.Theme.darkMode ? Qt.lighter(FishUI.Theme.highlightColor, 1.1) + : Qt.darker(FishUI.Theme.highlightColor, 1.2) + + MouseArea { + id: _mouseArea + anchors.fill: parent + hoverEnabled: true + acceptedButtons: Qt.LeftButton + onClicked: control.clicked() + + onPressedChanged: { + control.scale = pressed ? 0.95 : 1.0 + } + + onPressAndHold: { + control.pressAndHold() + } + } + + Behavior on scale { + NumberAnimation { + duration: 200 + easing.type: Easing.OutSine + } + } + + Rectangle { + anchors.fill: parent + radius: FishUI.Theme.bigRadius + opacity: 1 + + color: { + if (control.checked) { + if (_mouseArea.pressed) + return highlightPressedColor + else if (_mouseArea.containsMouse) + return highlightHoverColor + else + return FishUI.Theme.highlightColor + } else { + if (_mouseArea.pressed) + return pressedColor + else if (_mouseArea.containsMouse) + return hoverColor + else + return backgroundColor + } + } + } + + ColumnLayout { + anchors.fill: parent + anchors.leftMargin: FishUI.Theme.smallRadius + anchors.rightMargin: FishUI.Theme.smallRadius + spacing: FishUI.Units.smallSpacing + + Item { + Layout.fillHeight: true + } + + Image { + id: _image + Layout.preferredWidth: 32 + Layout.preferredHeight: 32 + sourceSize: Qt.size(32, 32) + asynchronous: true + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: FishUI.Units.largeSpacing + antialiasing: true + smooth: true + +// ColorOverlay { +// anchors.fill: _image +// source: _image +// color: control.checked ? FishUI.Theme.highlightedTextColor : FishUI.Theme.disabledTextColor +// } + } + + Item { + Layout.fillHeight: true + } + + Label { + id: _label + color: control.checked ? FishUI.Theme.highlightedTextColor : FishUI.Theme.textColor + Layout.preferredHeight: control.height * 0.15 + Layout.alignment: Qt.AlignHCenter + visible: text + } + + Item { + Layout.fillHeight: true + } + } +} diff --git a/qml/main.qml b/qml/main.qml index 6a9f2e4..2db3062 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -257,7 +257,7 @@ Item { width: trayView.itemWidth height: ListView.view.height - animationEnabled: false + animationEnabled: true onDarkModeChanged: updateTimer.restart() @@ -416,19 +416,32 @@ Item { visible: battery.showPercentage } } + } + } - Image { - id: shutdownIcon - width: rootItem.iconSize - height: width - sourceSize: Qt.size(width, height) - source: "qrc:/images/" + (rootItem.darkMode ? "dark/" : "light/") + "system-shutdown-symbolic.svg" - asynchronous: true - Layout.alignment: Qt.AlignCenter - visible: !batteryIcon.visible - antialiasing: true - smooth: false - } + StandardItem { + id: shutdownItem + + animationEnabled: true + Layout.fillHeight: true + Layout.preferredWidth: shutdownIcon.implicitWidth + FishUI.Units.smallSpacing + + onClicked: { + shutdownDialog.position = Qt.point(0, 0) + shutdownDialog.position = mapToGlobal(0, 0) + shutdownDialog.open() + } + + Image { + id: shutdownIcon + anchors.centerIn: parent + width: rootItem.iconSize + height: width + sourceSize: Qt.size(width, height) + source: "qrc:/images/" + (rootItem.darkMode ? "dark/" : "light/") + "system-shutdown-symbolic.svg" + asynchronous: true + antialiasing: true + smooth: false } } @@ -532,6 +545,10 @@ Item { id: controlCenter } + ShutdownDialog { + id: shutdownDialog + } + NM.ActiveConnection { id: activeConnection } diff --git a/src/main.cpp b/src/main.cpp index 9fefde0..f2f3e9d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,6 +26,7 @@ #include "systemtray/systemtraymodel.h" #include "appmenu/appmenumodel.h" #include "appmenu/appmenuapplet.h" +#include "poweractions.h" #include "appearance.h" #include "brightness.h" @@ -44,6 +45,7 @@ int main(int argc, char *argv[]) qmlRegisterType(uri, 1, 0, "Battery"); qmlRegisterType(uri, 1, 0, "AppMenuModel"); qmlRegisterType(uri, 1, 0, "AppMenuApplet"); + qmlRegisterType(uri, 1, 0, "PowerActions"); QString qmFilePath = QString("%1/%2.qm").arg("/usr/share/cutefish-statusbar/translations/").arg(QLocale::system().name()); if (QFile::exists(qmFilePath)) { diff --git a/src/poweractions.cpp b/src/poweractions.cpp new file mode 100644 index 0000000..85288c4 --- /dev/null +++ b/src/poweractions.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2021 CutefishOS Team. + * + * Author: revenmartin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "poweractions.h" +#include +#include +#include +#include + +const static QString s_dbusName = "com.cutefish.Session"; +const static QString s_pathName = "/Session"; +const static QString s_interfaceName = "com.cutefish.Session"; + +PowerActions::PowerActions(QObject *parent) + : QObject(parent) +{ + +} + +void PowerActions::shutdown() +{ + QDBusInterface iface(s_dbusName, s_pathName, s_interfaceName, QDBusConnection::sessionBus()); + if (iface.isValid()) { + iface.call("powerOff"); + } +} + +void PowerActions::logout() +{ + QDBusInterface iface(s_dbusName, s_pathName, s_interfaceName, QDBusConnection::sessionBus()); + if (iface.isValid()) { + iface.call("logout"); + } +} + +void PowerActions::reboot() +{ + QDBusInterface iface(s_dbusName, s_pathName, s_interfaceName, QDBusConnection::sessionBus()); + if (iface.isValid()) { + iface.call("reboot"); + } +} + +void PowerActions::lockScreen() +{ + QProcess::startDetached("cutefish-screenlocker", QStringList()); +} + +void PowerActions::suspend() +{ + QDBusInterface iface(s_dbusName, s_pathName, s_interfaceName, QDBusConnection::sessionBus()); + + if (iface.isValid()) { + iface.call("suspend"); + } +} diff --git a/src/poweractions.h b/src/poweractions.h new file mode 100644 index 0000000..2aad392 --- /dev/null +++ b/src/poweractions.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 CutefishOS Team. + * + * Author: revenmartin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef ACTIONS_H +#define ACTIONS_H + +#include + +class PowerActions : public QObject +{ + Q_OBJECT + +public: + explicit PowerActions(QObject *parent = nullptr); + + Q_INVOKABLE void shutdown(); + Q_INVOKABLE void logout(); + Q_INVOKABLE void reboot(); + Q_INVOKABLE void lockScreen(); + Q_INVOKABLE void suspend(); +}; + +#endif // ACTIONS_H diff --git a/translations/en_US.ts b/translations/en_US.ts index a8d632e..3fd519f 100644 --- a/translations/en_US.ts +++ b/translations/en_US.ts @@ -12,39 +12,67 @@ ControlCenter - + Wi-Fi - - - + + + On - - - + + + Off - + Bluetooth - + Dark Mode + + ShutdownDialog + + + Shutdown + + + + + Reboot + + + + + Log out + + + + + Lock Screen + + + + + Suspend + + + main - + Close diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts index 4475ced..4884777 100644 --- a/translations/zh_CN.ts +++ b/translations/zh_CN.ts @@ -12,39 +12,67 @@ ControlCenter - + Wi-Fi 无线网络 - - - + + + On 打开 - - - + + + Off 关闭 - + Bluetooth 蓝牙 - + Dark Mode 深色模式 + + ShutdownDialog + + + Shutdown + 关机 + + + + Reboot + 重启 + + + + Log out + 注销 + + + + Lock Screen + 锁屏 + + + + Suspend + 休眠 + + main - + Close 关闭