Merge remote-tracking branch 'origin/main' into addon-i18n

This commit is contained in:
月月
2025-06-21 09:10:40 +08:00
71 changed files with 2040 additions and 671 deletions
@@ -16,8 +16,8 @@ Singleton {
property string syntaxHighlightingTheme
// Extremely conservative transparency values for consistency and readability
property real transparency: ConfigOptions?.appearance.transparency ? (m3colors.darkmode ? 0.1 : 0) : 0
property real contentTransparency: ConfigOptions?.appearance.transparency ? (m3colors.darkmode ? 0.55 : 0) : 0
property real transparency: ConfigOptions?.appearance.transparency ? (m3colors.darkmode ? 0.1 : 0.07) : 0
property real contentTransparency: ConfigOptions?.appearance.transparency ? (m3colors.darkmode ? 0.55 : 0.55) : 0
m3colors: QtObject {
property bool darkmode: false
@@ -126,10 +126,11 @@ Singleton {
property color colPrimaryContainer: m3colors.m3primaryContainer
property color colPrimaryContainerHover: ColorUtils.mix(colors.colPrimaryContainer, colLayer1Hover, 0.7)
property color colPrimaryContainerActive: ColorUtils.mix(colors.colPrimaryContainer, colLayer1Active, 0.6)
property color colOnPrimaryContainer: m3colors.m3onPrimaryContainer
property color colSecondary: m3colors.m3secondary
property color colSecondaryHover: ColorUtils.mix(m3colors.m3secondary, colLayer1Hover, 0.85)
property color colSecondaryActive: ColorUtils.mix(m3colors.m3secondary, colLayer1Active, 0.4)
property color colSecondaryContainer: ColorUtils.transparentize(m3colors.m3secondaryContainer, root.contentTransparency)
property color colSecondaryContainer: m3colors.m3secondaryContainer
property color colSecondaryContainerHover: ColorUtils.mix(m3colors.m3secondaryContainer, colLayer1Hover, 0.6)
property color colSecondaryContainerActive: ColorUtils.mix(m3colors.m3secondaryContainer, colLayer1Active, 0.54)
property color colOnSecondaryContainer: m3colors.m3onSecondaryContainer
@@ -177,7 +178,7 @@ Singleton {
property int larger: 19
property int huge: 22
property int hugeass: 23
property int title: 28
property int title: huge
}
}
@@ -187,11 +188,17 @@ Singleton {
readonly property list<real> expressiveSlowSpatial: [0.39, 1.29, 0.35, 0.98, 1, 1] // Default, 650ms
readonly property list<real> expressiveEffects: [0.34, 0.80, 0.34, 1.00, 1, 1] // Default, 200ms
readonly property list<real> emphasized: [0.05, 0, 2 / 15, 0.06, 1 / 6, 0.4, 5 / 24, 0.82, 0.25, 1, 1, 1]
readonly property list<real> emphasizedFirstHalf: [0.05, 0, 2 / 15, 0.06, 1 / 6, 0.4, 5 / 24, 0.82]
readonly property list<real> emphasizedLastHalf: [5 / 24, 0.82, 0.25, 1, 1, 1]
readonly property list<real> emphasizedAccel: [0.3, 0, 0.8, 0.15, 1, 1]
readonly property list<real> emphasizedDecel: [0.05, 0.7, 0.1, 1, 1, 1]
readonly property list<real> standard: [0.2, 0, 0, 1, 1, 1]
readonly property list<real> standardAccel: [0.3, 0, 1, 1, 1, 1]
readonly property list<real> standardDecel: [0, 0, 0, 1, 1, 1]
readonly property real expressiveFastSpatialDuration: 350
readonly property real expressiveDefaultSpatialDuration: 500
readonly property real expressiveSlowSpatialDuration: 650
readonly property real expressiveEffectsDuration: 200
}
animation: QtObject {
@@ -31,10 +31,8 @@ Singleton {
property QtObject apps: QtObject {
property string bluetooth: "kcmshell6 kcm_bluetooth"
property string imageViewer: "loupe"
property string network: "plasmawindowed org.kde.plasma.networkmanagement"
property string networkEthernet: "kcmshell6 kcm_networkmanagement"
property string settings: "systemsettings"
property string taskManager: "plasma-systemmonitor --page-name Processes"
property string terminal: "kitty -1" // This is only for shell actions
}
@@ -157,6 +155,7 @@ Singleton {
property QtObject windows: QtObject {
property bool showTitlebar: true // Client-side decoration for shell apps
property bool centerTitle: true
}
property QtObject hacks: QtObject {
@@ -32,12 +32,12 @@ Singleton {
property string wallpaperSwitchScriptPath: FileUtils.trimFileProtocol(`${Directories.config}/quickshell/scripts/colors/switchwall.sh`)
// Cleanup on init
Component.onCompleted: {
Hyprland.dispatch(`exec mkdir -p '${shellConfig}'`)
Hyprland.dispatch(`exec mkdir -p '${favicons}'`)
Hyprland.dispatch(`exec rm -rf '${coverArt}'; mkdir -p '${coverArt}'`)
Hyprland.dispatch(`exec rm -rf '${booruPreviews}'; mkdir -p '${booruPreviews}'`)
Hyprland.dispatch(`exec mkdir -p '${booruDownloads}' && mkdir -p '${booruDownloadsNsfw}'`)
Hyprland.dispatch(`exec rm -rf '${latexOutput}'; mkdir -p '${latexOutput}'`)
Hyprland.dispatch(`exec rm -rf '${cliphistDecode}'; mkdir -p '${cliphistDecode}'`)
Quickshell.execDetached(["bash", "-c", `mkdir -p '${shellConfig}'`])
Quickshell.execDetached(["bash", "-c", `mkdir -p '${favicons}'`])
Quickshell.execDetached(["bash", "-c", `rm -rf '${coverArt}'; mkdir -p '${coverArt}'`])
Quickshell.execDetached(["bash", "-c", `rm -rf '${booruPreviews}'; mkdir -p '${booruPreviews}'`])
Quickshell.execDetached(["bash", "-c", `mkdir -p '${booruDownloads}' && mkdir -p '${booruDownloadsNsfw}'`])
Quickshell.execDetached(["bash", "-c", `rm -rf '${latexOutput}'; mkdir -p '${latexOutput}'`])
Quickshell.execDetached(["bash", "-c", `rm -rf '${cliphistDecode}'; mkdir -p '${cliphistDecode}'`])
}
}
@@ -8,6 +8,7 @@ import Qt.labs.platform
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Io
import Quickshell.Widgets
import Quickshell.Hyprland
@@ -71,7 +72,7 @@ Rectangle {
}
Component.onDestruction: {
Hyprland.dispatch(`exec bash -c "[ -f '${imageDecodeFilePath}' ] && rm -f '${imageDecodeFilePath}'"`)
Quickshell.execDetached(["bash", "-c", `[ -f '${imageDecodeFilePath}' ] && rm -f '${imageDecodeFilePath}'`])
}
Image {
@@ -0,0 +1,8 @@
import QtQuick
import QtQuick.Layouts
RowLayout {
property bool uniform: false
spacing: 10
uniformCellSizes: uniform
}
@@ -0,0 +1,48 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
import "root:/services/"
import "root:/modules/common/"
import "root:/modules/common/widgets/"
import "root:/modules/common/functions/color_utils.js" as ColorUtils
import "root:/modules/common/functions/file_utils.js" as FileUtils
Flow {
id: root
Layout.fillWidth: true
spacing: 2
property list<var> options: []
property string configOptionName: ""
property var currentValue: null
signal selected(var newValue)
Repeater {
model: root.options
delegate: SelectionGroupButton {
id: paletteButton
required property var modelData
required property int index
onYChanged: {
if (index === 0) {
paletteButton.leftmost = true
} else {
var prev = root.children[index - 1]
var thisIsOnNewLine = prev && prev.y !== paletteButton.y
paletteButton.leftmost = thisIsOnNewLine
prev.rightmost = thisIsOnNewLine
}
}
leftmost: index === 0
rightmost: index === root.options.length - 1
buttonText: modelData.displayName;
toggled: root.currentValue === modelData.value
onClicked: {
root.selected(modelData.value);
}
}
}
}
@@ -0,0 +1,31 @@
import "root:/modules/common/widgets/"
import "root:/modules/common/"
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
RippleButton {
id: root
Layout.fillWidth: true
implicitHeight: contentItem.implicitHeight + 8 * 2
contentItem: RowLayout {
spacing: 10
StyledText {
id: labelWidget
Layout.fillWidth: true
text: root.text
font.pixelSize: Appearance.font.pixelSize.small
color: Appearance.colors.colOnSecondaryContainer
}
StyledSwitch {
id: switchWidget
down: root.down
scale: 0.6
Layout.fillWidth: false
checked: root.checked
onClicked: root.clicked()
}
}
}
@@ -0,0 +1,29 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import "root:/modules/common/"
import "root:/modules/common/widgets/"
Flickable {
id: root
property real baseWidth: 500
property bool forceWidth: false
property real bottomContentPadding: 100
default property alias data: contentColumn.data
clip: true
contentHeight: contentColumn.implicitHeight + root.bottomContentPadding // Add some padding at the bottom
implicitWidth: contentColumn.implicitWidth
ColumnLayout {
id: contentColumn
width: root.forceWidth ? root.baseWidth : Math.max(root.baseWidth, implicitWidth)
anchors {
top: parent.top
horizontalCenter: parent.horizontalCenter
margins: 10
}
spacing: 20
}
}
@@ -0,0 +1,22 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import "root:/modules/common/"
import "root:/modules/common/widgets/"
ColumnLayout {
id: root
property string title
default property alias data: sectionContent.data
Layout.fillWidth: true
spacing: 8
StyledText {
text: root.title
font.pixelSize: Appearance.font.pixelSize.larger
}
ColumnLayout {
id: sectionContent
spacing: 4
}
}
@@ -0,0 +1,60 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import "root:/modules/common/"
import "root:/modules/common/widgets/"
/**
* Material 3 FAB.
*/
RippleButton {
id: root
property string iconText: "add"
property bool expanded: false
property real baseSize: 56
property real elementSpacing: 5
implicitWidth: Math.max(contentRowLayout.implicitWidth + 10 * 2, baseSize)
implicitHeight: baseSize
buttonRadius: Appearance.rounding.small
colBackground: Appearance.colors.colPrimaryContainer
colBackgroundHover: Appearance.colors.colPrimaryContainerHover
colRipple: Appearance.colors.colPrimaryContainerActive
contentItem: RowLayout {
id: contentRowLayout
property real horizontalMargins: (root.baseSize - icon.width) / 2
anchors {
verticalCenter: parent?.verticalCenter
left: parent?.left
leftMargin: contentRowLayout.horizontalMargins
}
spacing: 0
MaterialSymbol {
id: icon
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
iconSize: 24
color: Appearance.colors.colOnPrimaryContainer
text: root.iconText
}
Loader {
active: true
sourceComponent: Revealer {
visible: root.expanded || implicitWidth > 0
reveal: root.expanded
implicitWidth: reveal ? (buttonText.implicitWidth + root.elementSpacing + contentRowLayout.horizontalMargins) : 0
StyledText {
id: buttonText
anchors {
left: parent.left
leftMargin: root.elementSpacing
}
text: root.buttonText
color: Appearance.colors.colOnPrimaryContainer
font.pixelSize: 14
font.weight: 450
}
}
}
}
}
@@ -15,7 +15,7 @@ Rectangle {
property real extraBottomBorderWidth: 2
property color borderColor: Appearance.colors.colOnLayer0
property real borderRadius: 5
property color keyColor: Appearance.colors.colSurfaceContainerLow
property color keyColor: Appearance.m3colors.m3surfaceContainerLow
implicitWidth: keyFace.implicitWidth + borderWidth * 2
implicitHeight: keyFace.implicitHeight + borderWidth * 2 + extraBottomBorderWidth
radius: borderRadius
@@ -0,0 +1,124 @@
import "root:/modules/common"
import "root:/modules/common/widgets"
import "root:/modules/common/functions/color_utils.js" as ColorUtils
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
GroupButton {
id: lightDarkButtonRoot
required property bool dark
property color previewBg: dark ? ColorUtils.colorWithHueOf("#3f3838", Appearance.m3colors.m3primary) :
ColorUtils.colorWithHueOf("#F7F9FF", Appearance.m3colors.m3primary)
property color previewFg: dark ? Qt.lighter(previewBg, 2.2) : ColorUtils.mix(previewBg, "#292929", 0.85)
padding: 5
Layout.fillWidth: true
colBackground: Appearance.colors.colLayer2
toggled: Appearance.m3colors.darkmode === dark
onClicked: {
Quickshell.execDetached(["bash", "-c", `${Directories.wallpaperSwitchScriptPath} --mode ${dark ? "dark" : "light"} --noswitch`])
}
contentItem: Item {
anchors.centerIn: parent
implicitWidth: buttonContentLayout.implicitWidth
implicitHeight: buttonContentLayout.implicitHeight
ColumnLayout {
id: buttonContentLayout
anchors.centerIn: parent
Rectangle {
Layout.alignment: Qt.AlignHCenter
implicitWidth: 250
implicitHeight: skeletonColumnLayout.implicitHeight + 10 * 2
radius: lightDarkButtonRoot.buttonRadius - lightDarkButtonRoot.padding
color: lightDarkButtonRoot.previewBg
border {
width: 1
color: Appearance.m3colors.m3outlineVariant
}
// Some skeleton items
ColumnLayout {
id: skeletonColumnLayout
anchors.fill: parent
anchors.margins: 10
spacing: 10
RowLayout {
Rectangle {
radius: Appearance.rounding.full
color: lightDarkButtonRoot.previewFg
implicitWidth: 50
implicitHeight: 50
}
ColumnLayout {
spacing: 4
Rectangle {
radius: Appearance.rounding.unsharpenmore
color: lightDarkButtonRoot.previewFg
Layout.fillWidth: true
implicitHeight: 22
}
Rectangle {
radius: Appearance.rounding.unsharpenmore
color: lightDarkButtonRoot.previewFg
Layout.fillWidth: true
Layout.rightMargin: 45
implicitHeight: 18
}
}
}
StyledProgressBar {
Layout.topMargin: 5
Layout.bottomMargin: 5
Layout.fillWidth: true
value: 0.7
sperm: true
animateSperm: lightDarkButtonRoot.toggled
highlightColor: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3primary : lightDarkButtonRoot.previewFg
trackColor: ColorUtils.mix(lightDarkButtonRoot.previewBg, lightDarkButtonRoot.previewFg, 0.5)
}
RowLayout {
spacing: 2
Rectangle {
radius: Appearance.rounding.full
color: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3primary : lightDarkButtonRoot.previewFg
Layout.fillWidth: true
implicitHeight: 30
MaterialSymbol {
visible: lightDarkButtonRoot.toggled
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
text: "check"
iconSize: 20
color: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3onPrimary : lightDarkButtonRoot.previewBg
}
}
Rectangle {
radius: Appearance.rounding.unsharpenmore
color: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3secondaryContainer : lightDarkButtonRoot.previewFg
Layout.fillWidth: true
implicitHeight: 30
}
Rectangle {
topLeftRadius: Appearance.rounding.unsharpenmore
bottomLeftRadius: Appearance.rounding.unsharpenmore
topRightRadius: Appearance.rounding.full
bottomRightRadius: Appearance.rounding.full
color: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3secondaryContainer : lightDarkButtonRoot.previewFg
Layout.fillWidth: true
implicitHeight: 30
}
}
}
}
StyledText {
Layout.fillWidth: true
text: dark ? "Dark" : "Light"
color: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3onPrimary : Appearance.colors.colOnLayer2
horizontalAlignment: Text.AlignHCenter
}
}
}
}
@@ -12,6 +12,7 @@ Text {
hintingPreference: Font.PreferFullHinting
family: Appearance?.font.family.iconMaterial ?? "Material Symbols Rounded"
pixelSize: iconSize
weight: Font.Normal + (Font.DemiBold - Font.Normal) * fill
}
verticalAlignment: Text.AlignVCenter
color: Appearance.m3colors.m3onBackground
@@ -1,60 +0,0 @@
import "root:/modules/common"
import "root:/modules/common/widgets"
import "root:/modules/common/functions/color_utils.js" as ColorUtils
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell.Io
Button {
id: button
property bool toggled
property string buttonIcon
property string buttonText
Layout.alignment: Qt.AlignHCenter
implicitHeight: columnLayout.implicitHeight
implicitWidth: columnLayout.implicitWidth
background: null
PointingHandInteraction {}
// Real stuff
ColumnLayout {
id: columnLayout
spacing: 5
Rectangle {
width: 62
implicitHeight: navRailButtonIcon.height + 2 * 2
Layout.alignment: Qt.AlignHCenter
radius: Appearance.rounding.full
color: toggled ?
(button.down ? Appearance.colors.colSecondaryContainerActive : button.hovered ? Appearance.colors.colSecondaryContainerHover : Appearance.colors.colSecondaryContainer) :
(button.down ? Appearance.colors.colLayer1Active : button.hovered ? Appearance.colors.colLayer1Hover : ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1))
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
MaterialSymbol {
id: navRailButtonIcon
anchors.centerIn: parent
iconSize: Appearance.font.pixelSize.hugeass
fill: toggled ? 1 : 0
text: buttonIcon
color: toggled ? Appearance.m3colors.m3onSecondaryContainer : Appearance.colors.colOnLayer1
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
}
StyledText {
Layout.alignment: Qt.AlignHCenter
text: buttonText
color: Appearance.colors.colOnLayer1
}
}
}
@@ -0,0 +1,12 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import "root:/modules/common/"
import "root:/modules/common/widgets/"
ColumnLayout { // Window content with navigation rail and content pane
id: root
property bool expanded: true
property int currentIndex: 0
spacing: 5
}
@@ -0,0 +1,149 @@
import "root:/modules/common"
import "root:/modules/common/widgets"
import "root:/modules/common/functions/color_utils.js" as ColorUtils
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell.Io
TabButton {
id: root
property bool toggled: TabBar.tabBar.currentIndex === TabBar.index
property string buttonIcon
property string buttonText
property bool expanded: false
property bool showToggledHighlight: true
readonly property real visualWidth: root.expanded ? root.baseSize + 20 + itemText.implicitWidth : root.baseSize
property real baseSize: 56
property real baseHighlightHeight: 32
property real highlightCollapsedTopMargin: 8
padding: 0
// The navigation items target area always spans the full width of the
// nav rail, even if the item container hugs its contents.
Layout.fillWidth: true
// implicitWidth: contentItem.implicitWidth
implicitHeight: baseSize
background: null
PointingHandInteraction {}
// Real stuff
contentItem: Item {
id: buttonContent
anchors {
top: parent.top
bottom: parent.bottom
left: parent.left
right: undefined
}
implicitWidth: root.visualWidth
implicitHeight: root.expanded ? itemIconBackground.implicitHeight : itemIconBackground.implicitHeight + itemText.implicitHeight
Rectangle {
id: itemBackground
anchors.top: itemIconBackground.top
anchors.left: itemIconBackground.left
anchors.bottom: itemIconBackground.bottom
implicitWidth: root.visualWidth
radius: Appearance.rounding.full
color: toggled ?
root.showToggledHighlight ?
(root.down ? Appearance.colors.colSecondaryContainerActive : root.hovered ? Appearance.colors.colSecondaryContainerHover : Appearance.colors.colSecondaryContainer)
: ColorUtils.transparentize(Appearance.colors.colSecondaryContainer) :
(root.down ? Appearance.colors.colLayer1Active : root.hovered ? Appearance.colors.colLayer1Hover : ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1))
states: State {
name: "expanded"
when: root.expanded
AnchorChanges {
target: itemBackground
anchors.top: buttonContent.top
anchors.left: buttonContent.left
anchors.bottom: buttonContent.bottom
}
PropertyChanges {
target: itemBackground
implicitWidth: root.visualWidth
}
}
transitions: Transition {
AnchorAnimation {
duration: Appearance.animation.elementMoveFast.duration
easing.type: Appearance.animation.elementMoveFast.type
easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve
}
PropertyAnimation {
target: itemBackground
property: "implicitWidth"
duration: Appearance.animation.elementMove.duration
easing.type: Appearance.animation.elementMove.type
easing.bezierCurve: Appearance.animation.elementMove.bezierCurve
}
}
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
Item {
id: itemIconBackground
implicitWidth: root.baseSize
implicitHeight: root.baseHighlightHeight
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
}
MaterialSymbol {
id: navRailButtonIcon
anchors.centerIn: parent
iconSize: 24
fill: toggled ? 1 : 0
font.weight: (toggled || root.hovered) ? Font.DemiBold : Font.Normal
text: buttonIcon
color: toggled ? Appearance.m3colors.m3onSecondaryContainer : Appearance.colors.colOnLayer1
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
}
StyledText {
id: itemText
anchors {
top: itemIconBackground.bottom
topMargin: 2
horizontalCenter: itemIconBackground.horizontalCenter
}
states: State {
name: "expanded"
when: root.expanded
AnchorChanges {
target: itemText
anchors {
top: undefined
horizontalCenter: undefined
left: itemIconBackground.right
verticalCenter: itemIconBackground.verticalCenter
}
}
}
transitions: Transition {
AnchorAnimation {
duration: Appearance.animation.elementMoveFast.duration
easing.type: Appearance.animation.elementMoveFast.type
easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve
}
}
text: buttonText
font.pixelSize: 14
color: Appearance.colors.colOnLayer1
}
}
}
@@ -0,0 +1,25 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import "root:/modules/common/"
import "root:/modules/common/widgets/"
RippleButton {
id: root
Layout.alignment: Qt.AlignLeft
implicitWidth: 40
implicitHeight: 40
Layout.leftMargin: 8
onClicked: {
parent.expanded = !parent.expanded;
}
buttonRadius: Appearance.rounding.full
contentItem: MaterialSymbol {
id: icon
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
iconSize: 24
color: Appearance.colors.colOnLayer1
text: root.parent.expanded ? "menu_open" : "menu"
}
}
@@ -0,0 +1,44 @@
import "root:/modules/common"
import "root:/modules/common/widgets"
import "root:/modules/common/functions/color_utils.js" as ColorUtils
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell.Io
Item {
id: root
property int currentIndex: 0
property bool expanded: false
default property alias data: tabBarColumn.data
implicitHeight: tabBarColumn.implicitHeight
implicitWidth: tabBarColumn.implicitWidth
Layout.topMargin: 25
Rectangle {
property real itemHeight: tabBarColumn.children[0].baseSize
property real baseHighlightHeight: tabBarColumn.children[0].baseHighlightHeight
anchors {
top: tabBarColumn.top
left: tabBarColumn.left
topMargin: itemHeight * root.currentIndex + (root.expanded ? 0 : ((itemHeight - baseHighlightHeight) / 2))
}
radius: Appearance.rounding.full
color: Appearance.colors.colSecondaryContainer
implicitHeight: root.expanded ? itemHeight : baseHighlightHeight
implicitWidth: tabBarColumn.children[root.currentIndex].visualWidth
Behavior on anchors.topMargin {
NumberAnimation {
duration: Appearance.animationCurves.expressiveFastSpatialDuration
easing.type: Appearance.animation.elementMove.type
easing.bezierCurve: Appearance.animationCurves.expressiveFastSpatial
}
}
}
ColumnLayout {
id: tabBarColumn
anchors.fill: parent
spacing: 0
}
}
@@ -94,12 +94,6 @@ Item { // Notification item area
}
}
onPressAndHold: (mouse) => {
if (mouse.button === Qt.LeftButton) {
Hyprland.dispatch(`exec wl-copy '${StringUtils.shellSingleQuoteEscape(notificationObject.body)}'`)
notificationSummaryText.text = String.format(Translation.tr("{0} (copied)"), notificationObject.summary)
}
}
onDraggingChanged: () => {
if (dragging) {
root.qmlParent.dragIndex = root.index ?? root.parent.children.indexOf(root);
@@ -226,12 +220,8 @@ Item { // Notification item area
Qt.openUrlExternally(link)
Hyprland.dispatch("global quickshell:sidebarRightClose")
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton // Only for hover
hoverEnabled: true
cursorShape: parent.hoveredLink !== "" ? Qt.PointingHandCursor : Qt.ArrowCursor
}
PointingHandLinkHover {}
}
Flickable { // Notification actions
@@ -295,7 +285,7 @@ Item { // Notification item area
(contentItem.implicitWidth + leftPadding + rightPadding)
onClicked: {
Hyprland.dispatch(`exec wl-copy '${StringUtils.shellSingleQuoteEscape(notificationObject.body)}'`)
Quickshell.clipboardText = notificationObject.body
copyIcon.text = "inventory"
copyIconTimer.restart()
}
@@ -0,0 +1,8 @@
import QtQuick
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton // Only for hover
hoverEnabled: true
cursorShape: parent.hoveredLink !== "" ? Qt.PointingHandCursor : Qt.ArrowCursor
}
@@ -13,7 +13,7 @@ Item {
implicitWidth: (reveal || vertical) ? childrenRect.width : 0
implicitHeight: (reveal || !vertical) ? childrenRect.height : 0
visible: reveal && width > 0 && height > 0
visible: reveal || (width > 0 && height > 0)
Behavior on implicitWidth {
enabled: !vertical
@@ -0,0 +1,56 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import "root:/modules/common/"
import "root:/modules/common/widgets/"
RippleButton {
id: buttonWithIconRoot
property string nerdIcon
property string materialIcon
property bool materialIconFill: true
property string mainText: "Button text"
property Component mainContentComponent: Component {
StyledText {
text: buttonWithIconRoot.mainText
font.pixelSize: Appearance.font.pixelSize.small
color: Appearance.colors.colOnSecondaryContainer
}
}
implicitHeight: 35
horizontalPadding: 15
buttonRadius: Appearance.rounding.small
colBackground: Appearance.colors.colLayer2
contentItem: RowLayout {
Item {
implicitWidth: Math.max(materialIconLoader.implicitWidth, nerdIconLoader.implicitWidth)
Loader {
id: materialIconLoader
anchors.centerIn: parent
active: !nerdIcon
sourceComponent: MaterialSymbol {
text: buttonWithIconRoot.materialIcon
iconSize: Appearance.font.pixelSize.larger
color: Appearance.colors.colOnSecondaryContainer
fill: buttonWithIconRoot.materialIconFill ? 1 : 0
}
}
Loader {
id: nerdIconLoader
anchors.centerIn: parent
active: nerdIcon
sourceComponent: StyledText {
text: buttonWithIconRoot.nerdIcon
font.pixelSize: Appearance.font.pixelSize.larger
font.family: Appearance.font.family.iconNerd
color: Appearance.colors.colOnSecondaryContainer
}
}
}
Loader {
sourceComponent: buttonWithIconRoot.mainContentComponent
Layout.alignment: Qt.AlignVCenter
}
}
}
@@ -0,0 +1,24 @@
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
import "root:/services/"
import "root:/modules/common/"
import "root:/modules/common/widgets/"
GroupButton {
id: root
horizontalPadding: 12
verticalPadding: 8
bounce: false
property bool leftmost: false
property bool rightmost: false
leftRadius: (toggled || leftmost) ? (height / 2) : Appearance.rounding.unsharpenmore
rightRadius: (toggled || rightmost) ? (height / 2) : Appearance.rounding.unsharpenmore
colBackground: Appearance.colors.colSecondaryContainer
contentItem: StyledText {
color: parent.toggled ? Appearance.colors.colOnPrimary : Appearance.colors.colOnSecondaryContainer
text: root.buttonText
}
}
@@ -41,8 +41,7 @@ ProgressBar {
}
contentItem: Item {
implicitWidth: parent.width
implicitHeight: parent.height
anchors.fill: parent
Canvas {
id: wavyFill
@@ -6,7 +6,8 @@ RectangularShadow {
required property var target
anchors.fill: target
radius: target.radius
blur: 1.2 * Appearance.sizes.elevationMargin
blur: 0.9 * Appearance.sizes.elevationMargin
offset: Qt.vector2d(0.0, 1.0)
spread: 1
color: Appearance.colors.colShadow
cached: true
@@ -36,13 +36,13 @@ Switch {
// Custom thumb styling
indicator: Rectangle {
width: root.pressed ? (28 * root.scale) : root.checked ? (24 * root.scale) : (16 * root.scale)
height: root.pressed ? (28 * root.scale) : root.checked ? (24 * root.scale) : (16 * root.scale)
width: (root.pressed || root.down) ? (28 * root.scale) : root.checked ? (24 * root.scale) : (16 * root.scale)
height: (root.pressed || root.down) ? (28 * root.scale) : root.checked ? (24 * root.scale) : (16 * root.scale)
radius: Appearance.rounding.full
color: root.checked ? Appearance.m3colors.m3onPrimary : Appearance.m3colors.m3outline
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: root.checked ? (root.pressed ? (22 * root.scale) : 24 * root.scale) : (root.pressed ? (2 * root.scale) : 8 * root.scale)
anchors.leftMargin: root.checked ? ((root.pressed || root.down) ? (22 * root.scale) : 24 * root.scale) : ((root.pressed || root.down) ? (2 * root.scale) : 8 * root.scale)
Behavior on anchors.leftMargin {
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
@@ -2,6 +2,9 @@ import "root:/modules/common"
import QtQuick
import QtQuick.Controls
/**
* Does not include visual layout, but includes the easily neglected colors.
*/
TextArea {
renderType: Text.NativeRendering
selectedTextColor: Appearance.m3colors.m3onSecondaryContainer