You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
statusbar/qml/main.qml

535 lines
17 KiB
QML

/*
* Copyright (C) 2021 CutefishOS Team.
*
* Author: Reion Wong <aj@cutefishos.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
5 years ago
import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.12
import QtQuick.Window 2.12
5 years ago
import Cutefish.StatusBar 1.0
5 years ago
import Cutefish.NetworkManagement 1.0 as NM
5 years ago
import FishUI 1.0 as FishUI
5 years ago
Item {
id: rootItem
5 years ago
property int iconSize: 16
5 years ago
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
LayoutMirroring.childrenInherit: true
property bool darkMode: FishUI.Theme.darkMode
property color textColor: rootItem.darkMode ? "#FFFFFF" : "#000000";
property var fontSize: rootItem.height ? rootItem.height / 3 : 1
property var timeFormat: StatusBar.twentyFourTime ? "HH:mm" : "h:mm ap"
onTimeFormatChanged: {
timeTimer.restart()
}
5 years ago
Rectangle {
id: background
anchors.fill: parent
color: FishUI.Theme.darkMode ? "#4D4D4D" : "#FFFFFF"
opacity: windowHelper.compositing ? FishUI.Theme.darkMode ? 0.5 : 0.7 : 1.0
5 years ago
Behavior on color {
ColorAnimation {
duration: 200
easing.type: Easing.Linear
}
}
5 years ago
}
FishUI.WindowHelper {
id: windowHelper
}
5 years ago
FishUI.PopupTips {
5 years ago
id: popupTips
backgroundColor: background.color
backgroundOpacity: background.opacity
5 years ago
}
5 years ago
FishUI.DesktopMenu {
id: acticityMenu
MenuItem {
text: qsTr("Close")
onTriggered: acticity.close()
}
}
// Main layout
5 years ago
RowLayout {
anchors.fill: parent
5 years ago
anchors.leftMargin: FishUI.Units.smallSpacing
anchors.rightMargin: FishUI.Units.smallSpacing
spacing: FishUI.Units.smallSpacing / 2
5 years ago
// App name
StandardItem {
id: acticityItem
animationEnabled: true
Layout.fillHeight: true
Layout.preferredWidth: acticityLayout.implicitWidth ? Math.min(acticityLayout.implicitWidth + FishUI.Units.largeSpacing,
rootItem.width / 2)
: 0
onRightClicked: acticityMenu.open()
RowLayout {
id: acticityLayout
anchors.fill: parent
5 years ago
anchors.leftMargin: FishUI.Units.smallSpacing
anchors.rightMargin: FishUI.Units.smallSpacing
spacing: FishUI.Units.smallSpacing
Image {
id: acticityIcon
5 years ago
width: rootItem.iconSize
height: rootItem.iconSize
5 years ago
sourceSize: Qt.size(rootItem.iconSize,
rootItem.iconSize)
source: acticity.icon ? "image://icontheme/" + acticity.icon : ""
visible: status === Image.Ready
5 years ago
antialiasing: true
smooth: false
}
Label {
id: acticityLabel
text: acticity.title
Layout.fillWidth: true
elide: Qt.ElideRight
color: rootItem.textColor
visible: text
5 years ago
Layout.alignment: Qt.AlignVCenter
font.pointSize: rootItem.fontSize
}
}
}
// App menu
5 years ago
Item {
id: appMenuItem
Layout.fillHeight: true
5 years ago
Layout.fillWidth: true
ListView {
id: appMenuView
anchors.fill: parent
orientation: Qt.Horizontal
spacing: FishUI.Units.smallSpacing
visible: appMenuModel.visible
interactive: false
clip: true
model: appMenuModel
// Initialize the current index
onVisibleChanged: {
if (!visible)
appMenuView.currentIndex = -1
}
delegate: StandardItem {
id: _menuItem
width: _actionText.width + FishUI.Units.largeSpacing
height: ListView.view.height
checked: appMenuApplet.currentIndex === index
onClicked: {
appMenuApplet.trigger(_menuItem, index)
checked = Qt.binding(function() {
return appMenuApplet.currentIndex === index
})
}
Text {
id: _actionText
anchors.centerIn: parent
color: rootItem.textColor
font.pointSize: rootItem.fontSize
text: {
var text = activeMenu
text = text.replace(/([^&]*)&(.)([^&]*)/g, function (match, p1, p2, p3) {
return p1.concat(p2, p3)
})
return text
}
}
// QMenu opens on press, so we'll replicate that here
MouseArea {
anchors.fill: parent
hoverEnabled: appMenuApplet.currentIndex !== -1
onPressed: parent.clicked()
onEntered: parent.clicked()
}
}
AppMenuModel {
id: appMenuModel
onRequestActivateIndex: appMenuApplet.requestActivateIndex(appMenuView.currentIndex)
Component.onCompleted: {
appMenuView.model = appMenuModel
}
}
AppMenuApplet {
id: appMenuApplet
model: appMenuModel
}
Component.onCompleted: {
appMenuApplet.buttonGrid = appMenuView
// Handle left and right shortcut keys.
appMenuApplet.requestActivateIndex.connect(function (index) {
var idx = Math.max(0, Math.min(appMenuView.count - 1, index))
var button = appMenuView.itemAtIndex(index)
if (button) {
button.clicked()
}
});
// Handle mouse movement.
appMenuApplet.mousePosChanged.connect(function (x, y) {
var item = itemAt(x, y)
if (item)
item.clicked();
});
}
}
5 years ago
}
// System tray(Right)
5 years ago
ListView {
id: trayView
orientation: Qt.Horizontal
layoutDirection: Qt.RightToLeft
interactive: false
clip: true
spacing: FishUI.Units.smallSpacing / 2
5 years ago
property real itemWidth: rootItem.iconSize + FishUI.Units.largeSpacing
5 years ago
Layout.fillHeight: true
Layout.preferredWidth: (itemWidth + (count - 1) * FishUI.Units.smallSpacing) * count
5 years ago
model: SystemTrayModel {
id: trayModel
}
moveDisplaced: Transition {
NumberAnimation {
properties: "x, y"
duration: 200
easing.type: Easing.InOutQuad
}
}
5 years ago
delegate: StandardItem {
id: _trayItem
property bool darkMode: rootItem.darkMode
property int dragItemIndex: index
property bool dragStarted: false
5 years ago
width: trayView.itemWidth
height: ListView.view.height
animationEnabled: true
5 years ago
5 years ago
onDarkModeChanged: updateTimer.restart()
Drag.active: _trayItem.mouseArea.drag.active
Drag.dragType: Drag.Automatic
Drag.supportedActions: Qt.MoveAction
Drag.hotSpot.x: iconItem.width / 2
Drag.hotSpot.y: iconItem.height / 2
Drag.onDragStarted: {
dragStarted = true
}
Drag.onDragFinished: {
dragStarted = false
}
onPositionChanged: {
if (_trayItem.mouseArea.pressed) {
_trayItem.mouseArea.drag.target = iconItem
iconItem.grabToImage(function(result) {
_trayItem.Drag.imageSource = result.url
})
} else {
_trayItem.mouseArea.drag.target = null
}
}
onReleased: {
_trayItem.mouseArea.drag.target = null
}
DropArea {
anchors.fill: parent
enabled: true
onEntered: {
if (drag.source)
trayModel.move(drag.source.dragItemIndex,
_trayItem.dragItemIndex)
}
}
5 years ago
Timer {
id: updateTimer
interval: 10
onTriggered: iconItem.updateIcon()
}
5 years ago
FishUI.IconItem {
5 years ago
id: iconItem
5 years ago
anchors.centerIn: parent
5 years ago
width: rootItem.iconSize
5 years ago
height: width
source: model.iconName ? model.iconName : model.icon
5 years ago
antialiasing: true
smooth: false
visible: !dragStarted
5 years ago
}
onClicked: trayModel.leftButtonClick(model.id)
onRightClicked: trayModel.rightButtonClick(model.id)
popupText: model.toolTip ? model.toolTip : model.title
}
}
StandardItem {
id: controler
checked: controlCenter.visible
animationEnabled: true
5 years ago
Layout.fillHeight: true
5 years ago
Layout.preferredWidth: _controlerLayout.implicitWidth + FishUI.Units.largeSpacing
5 years ago
onClicked: toggleDialog()
onRightClicked: toggleDialog()
function toggleDialog() {
if (controlCenter.visible)
controlCenter.close()
5 years ago
else {
// 先初始化用户可能会通过Alt鼠标左键移动位置
controlCenter.position = Qt.point(0, 0)
controlCenter.position = mapToGlobal(0, 0)
controlCenter.open()
5 years ago
}
}
RowLayout {
id: _controlerLayout
anchors.fill: parent
5 years ago
anchors.leftMargin: FishUI.Units.smallSpacing
anchors.rightMargin: FishUI.Units.smallSpacing
5 years ago
5 years ago
spacing: FishUI.Units.largeSpacing
5 years ago
Image {
id: volumeIcon
visible: controlCenter.defaultSink
source: "qrc:/images/" + (rootItem.darkMode ? "dark/" : "light/") + controlCenter.volumeIconName + ".svg"
5 years ago
width: rootItem.iconSize
5 years ago
height: width
sourceSize: Qt.size(width, height)
asynchronous: true
Layout.alignment: Qt.AlignCenter
5 years ago
antialiasing: true
smooth: false
5 years ago
}
Image {
id: wirelessIcon
5 years ago
width: rootItem.iconSize
5 years ago
height: width
sourceSize: Qt.size(width, height)
source: activeConnection.wirelessIcon ? "qrc:/images/" + (rootItem.darkMode ? "dark/" : "light/") + activeConnection.wirelessIcon + ".svg" : ""
5 years ago
asynchronous: true
Layout.alignment: Qt.AlignCenter
visible: enabledConnections.wirelessHwEnabled &&
enabledConnections.wirelessEnabled &&
activeConnection.wirelessName &&
5 years ago
wirelessIcon.status === Image.Ready
5 years ago
antialiasing: true
smooth: false
5 years ago
}
// Battery Item
RowLayout {
5 years ago
visible: battery.available
Image {
id: batteryIcon
height: rootItem.iconSize
5 years ago
width: height + 6
sourceSize: Qt.size(width, height)
source: "qrc:/images/" + (rootItem.darkMode ? "dark/" : "light/") + battery.iconSource
Layout.alignment: Qt.AlignCenter
5 years ago
antialiasing: true
smooth: false
}
5 years ago
Label {
text: battery.chargePercent + "%"
font.pointSize: rootItem.fontSize
color: rootItem.textColor
visible: battery.showPercentage
}
}
Image {
5 years ago
id: shutdownIcon
width: rootItem.iconSize
height: width
sourceSize: Qt.size(width, height)
5 years ago
source: "qrc:/images/" + (rootItem.darkMode ? "dark/" : "light/") + "system-shutdown-symbolic.svg"
asynchronous: true
Layout.alignment: Qt.AlignCenter
5 years ago
visible: !batteryIcon.visible
antialiasing: true
smooth: false
}
}
}
// Pop-up notification center and calendar
StandardItem {
id: datetimeItem
animationEnabled: true
Layout.fillHeight: true
Layout.preferredWidth: _dateTimeLayout.implicitWidth + FishUI.Units.smallSpacing
onClicked: {
process.startDetached("cutefish-notificationd", ["-s"])
}
RowLayout {
id: _dateTimeLayout
anchors.fill: parent
// Image {
// width: rootItem.iconSize
// height: width
// sourceSize: Qt.size(width, height)
// source: "qrc:/images/" + (rootItem.darkMode ? "dark/" : "light/") + "notification-symbolic.svg"
// asynchronous: true
// Layout.alignment: Qt.AlignCenter
// antialiasing: true
// smooth: false
// }
5 years ago
Label {
id: timeLabel
Layout.alignment: Qt.AlignCenter
font.pointSize: rootItem.fontSize
color: rootItem.textColor
5 years ago
Timer {
id: timeTimer
5 years ago
interval: 1000
repeat: true
running: true
triggeredOnStart: true
onTriggered: {
timeLabel.text = new Date().toLocaleTimeString(Qt.locale(), rootItem.timeFormat)
5 years ago
}
}
}
}
}
5 years ago
}
MouseArea {
id: _sliding
anchors.fill: parent
z: -1
property int startY: -1
property bool activated: false
onActivatedChanged: {
// TODO
// if (activated)
// acticity.move()
}
onPressed: {
startY = mouse.y
}
onReleased: {
startY = -1
}
onDoubleClicked: {
acticity.toggleMaximize()
}
onMouseYChanged: {
if (startY === parseInt(mouse.y)) {
activated = false
return
}
// Up
if (startY > parseInt(mouse.y)) {
activated = false
return
}
if (mouse.y > rootItem.height)
activated = true
else
activated = false
}
}
5 years ago
// Components
ControlCenter {
id: controlCenter
5 years ago
}
NM.ActiveConnection {
id: activeConnection
5 years ago
}
NM.EnabledConnections {
id: enabledConnections
}
NM.Handler {
id: nmHandler
5 years ago
}
}