Unify config into shell.json and add Noctalia plugin support

This commit is contained in:
Ryan Hughes
2026-05-14 02:21:48 -04:00
parent 5c0f5669c9
commit bcbe12b075
49 changed files with 2178 additions and 350 deletions
@@ -0,0 +1,9 @@
import QtQuick
import qs.Commons
Rectangle {
color: Color.mSurfaceVariant
border.color: Color.mOutline
border.width: Style.borderS
radius: Style.radiusM
}
@@ -0,0 +1,26 @@
import QtQuick
import QtQuick.Controls
import qs.Commons
Button {
id: root
property string label: ""
property color colorBg: Color.mSurfaceVariant
property color colorFg: Color.mOnSurface
text: label || ""
background: Rectangle {
color: root.hovered ? Color.mHover : root.colorBg
radius: Style.radiusM
border.color: Color.mOutline
border.width: Style.borderS
}
contentItem: Text {
text: root.text
color: root.colorFg
font.family: "JetBrainsMono Nerd Font"
font.pixelSize: Style.fontSizeM
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
@@ -0,0 +1,11 @@
import QtQuick
import QtQuick.Controls
import qs.Commons
CheckBox {
id: root
property string label: ""
text: label || ""
font.family: "JetBrainsMono Nerd Font"
font.pixelSize: Style.fontSizeS
}
@@ -0,0 +1,17 @@
import QtQuick
import QtQuick.Controls
import qs.Commons
ComboBox {
id: root
property string label: ""
font.family: "JetBrainsMono Nerd Font"
font.pixelSize: Style.fontSizeS
background: Rectangle {
color: Color.mSurfaceVariant
border.color: Color.mOutline
border.width: Style.borderS
radius: Style.radiusS
}
}
@@ -0,0 +1,8 @@
import QtQuick
import qs.Commons
Rectangle {
implicitHeight: 1
color: Color.mOutline
opacity: 0.4
}
@@ -0,0 +1,18 @@
import QtQuick
import qs.Commons
// Noctalia compat shim. Renders an icon by name through the Icons map.
Text {
id: root
property string icon: ""
property real pointSize: 14
property bool applyUiScale: true
text: Icons.get(icon)
color: Color.mOnSurface
font.family: "JetBrainsMono Nerd Font"
font.pixelSize: Math.round(pointSize * (applyUiScale ? Style.uiScaleRatio : 1))
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
renderType: Text.NativeRendering
}
@@ -0,0 +1,67 @@
import QtQuick
import qs.Commons
import qs.Services.UI
// Noctalia compat shim. The widget plugins lean on this heavily; it's the
// primary clickable bar element. We mimic Noctalia's surface area
// (icon/text/tooltip/colors/border) but skip the long tail of properties
// no observed plugin actually sets.
Rectangle {
id: root
property string icon: ""
property string text: ""
property string tooltipText: ""
property string tooltipDirection: ""
property real baseSize: Style.baseWidgetSize
property bool applyUiScale: false
property real customRadius: -1
property color colorBg: Style.capsuleColor
property color colorFg: Color.mOnSurface
property color colorBgHover: Color.mHover
property color colorFgHover: Color.mOnHover
property color colorBorder: Style.capsuleBorderColor
property color colorBorderHover: Style.capsuleBorderColor
property bool flat: false
signal clicked()
signal rightClicked()
signal middleClicked()
signal wheel(int delta)
readonly property real effectiveSize: Math.round(baseSize * (applyUiScale ? Style.uiScaleRatio : 1))
implicitWidth: effectiveSize
implicitHeight: effectiveSize
radius: customRadius >= 0 ? customRadius : Style.radiusM
color: mouse.containsMouse ? colorBgHover : colorBg
border.color: mouse.containsMouse ? colorBorderHover : colorBorder
border.width: Style.capsuleBorderWidth
Behavior on color { ColorAnimation { duration: Style.animationFast } }
Text {
anchors.centerIn: parent
text: root.icon ? Icons.get(root.icon) : root.text
color: mouse.containsMouse ? root.colorFgHover : root.colorFg
font.family: "JetBrainsMono Nerd Font"
font.pixelSize: Math.round(Style.fontSizeM * (root.applyUiScale ? Style.uiScaleRatio : 1))
Behavior on color { ColorAnimation { duration: Style.animationFast } }
}
MouseArea {
id: mouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
onEntered: if (root.tooltipText) TooltipService.show(root, root.tooltipText, root.tooltipDirection)
onExited: TooltipService.hide(root)
onClicked: function(m) {
if (m.button === Qt.RightButton) root.rightClicked()
else if (m.button === Qt.MiddleButton) root.middleClicked()
else root.clicked()
}
onWheel: function(w) { root.wheel(w.angleDelta.y) }
}
}
@@ -0,0 +1,23 @@
import QtQuick
import QtQuick.Controls
import qs.Commons
// Noctalia compat shim. Plugins instantiate this with a model of action
// objects and expect `triggered(action)` when a row is picked.
Menu {
id: root
property var model: []
signal triggered(string action)
Instantiator {
model: root.model
delegate: MenuItem {
required property var modelData
text: modelData ? String(modelData.label || modelData.action || "") : ""
onTriggered: root.triggered(modelData ? String(modelData.action || "") : "")
}
onObjectAdded: function(index, object) { root.insertItem(index, object) }
onObjectRemoved: function(index, object) { root.removeItem(object) }
}
}
@@ -0,0 +1,55 @@
import QtQuick
import qs.Commons
// Noctalia compat shim. Auto-scrolling label.
Item {
id: root
property string text: ""
property real maxWidth: 200
property real pointSize: Style.fontSizeM
property int scrollMode: NScrollText.ScrollMode.Hover
property bool forcedHover: false
property real fadeExtent: 0.1
property real fadeCornerRadius: 0
property bool fadeRoundLeftCorners: false
property bool fadeRoundRightCorners: false
property color textColor: Color.mOnSurface
enum ScrollMode { Always, Hover, Never }
implicitHeight: label.implicitHeight
implicitWidth: Math.min(maxWidth, label.implicitWidth)
clip: true
readonly property bool overflowing: label.implicitWidth > width
readonly property bool shouldScroll: {
if (!overflowing) return false
if (scrollMode === NScrollText.ScrollMode.Always) return true
if (scrollMode === NScrollText.ScrollMode.Hover) return forcedHover
return false
}
Text {
id: label
text: root.text
color: root.textColor
font.family: "JetBrainsMono Nerd Font"
font.pixelSize: root.pointSize
verticalAlignment: Text.AlignVCenter
height: parent.height
anchors.verticalCenter: parent.verticalCenter
NumberAnimation on x {
id: scrollAnim
running: root.shouldScroll
loops: Animation.Infinite
duration: Math.max(5000, label.implicitWidth * 22)
from: root.width
to: -label.implicitWidth
easing.type: Easing.Linear
}
onShouldScrollChanged: if (!root.shouldScroll) x = 0
}
}
@@ -0,0 +1,8 @@
import QtQuick
import QtQuick.Controls
import qs.Commons
Slider {
id: root
property string label: ""
}
@@ -0,0 +1,10 @@
import QtQuick
import QtQuick.Controls
import qs.Commons
SpinBox {
id: root
property string label: ""
font.family: "JetBrainsMono Nerd Font"
font.pixelSize: Style.fontSizeS
}
@@ -0,0 +1,19 @@
import QtQuick
import qs.Commons
// Noctalia compat shim. The original supports pointSize (interpreted as
// pixel size in Noctalia) plus an applyUiScale flag. We translate to
// font.pixelSize directly; uiScaleRatio comes from Style.
Text {
id: root
property real pointSize: 12
property bool applyUiScale: true
property var customFont: null
color: Color.mOnSurface
font.family: customFont || "JetBrainsMono Nerd Font"
font.pixelSize: Math.round(pointSize * (applyUiScale ? Style.uiScaleRatio : 1))
font.weight: Style.fontWeightRegular
verticalAlignment: Text.AlignVCenter
renderType: Text.NativeRendering
}
@@ -0,0 +1,20 @@
import QtQuick
import QtQuick.Controls
import qs.Commons
TextField {
id: root
property string label: ""
property string description: ""
property string defaultValue: ""
font.family: "JetBrainsMono Nerd Font"
font.pixelSize: Style.fontSizeS
color: Color.mOnSurface
background: Rectangle {
color: Color.mSurfaceVariant
border.color: root.focus ? Color.mPrimary : Color.mOutline
border.width: Style.borderS
radius: Style.radiusS
}
}
@@ -0,0 +1,38 @@
import QtQuick
import QtQuick.Controls
import qs.Commons
Switch {
id: root
property string label: ""
indicator: Rectangle {
implicitWidth: 32
implicitHeight: 18
x: root.leftPadding
y: root.height / 2 - height / 2
radius: height / 2
color: root.checked ? Color.mPrimary : Color.mSurfaceVariant
border.color: Color.mOutline
border.width: Style.borderS
Rectangle {
x: root.checked ? parent.width - width - 2 : 2
y: 2
width: parent.height - 4
height: parent.height - 4
radius: height / 2
color: Color.mOnSurface
Behavior on x { NumberAnimation { duration: Style.animationFast } }
}
}
contentItem: Text {
leftPadding: 38
text: root.label || root.text
color: Color.mOnSurface
font.family: "JetBrainsMono Nerd Font"
font.pixelSize: Style.fontSizeS
verticalAlignment: Text.AlignVCenter
}
}
@@ -0,0 +1,15 @@
module qs.Widgets
NText 1.0 NText.qml
NIcon 1.0 NIcon.qml
NIconButton 1.0 NIconButton.qml
NBox 1.0 NBox.qml
NButton 1.0 NButton.qml
NPopupContextMenu 1.0 NPopupContextMenu.qml
NScrollText 1.0 NScrollText.qml
NToggle 1.0 NToggle.qml
NSpinBox 1.0 NSpinBox.qml
NSlider 1.0 NSlider.qml
NTextInput 1.0 NTextInput.qml
NComboBox 1.0 NComboBox.qml
NCheckbox 1.0 NCheckbox.qml
NDivider 1.0 NDivider.qml