rebrand!: Antergos NeXT -> Euri Linux
This commit is contained in:
+20
@@ -0,0 +1,20 @@
|
||||
import QtQuick
|
||||
import org.kde.plasma.configuration
|
||||
|
||||
ConfigModel {
|
||||
ConfigCategory {
|
||||
name: i18n("Visualizer")
|
||||
icon: "waveform-symbolic"
|
||||
source: "configVisualizer.qml"
|
||||
}
|
||||
ConfigCategory {
|
||||
name: "CAVA"
|
||||
icon: "view-process-system-symbolic"
|
||||
source: "configCava.qml"
|
||||
}
|
||||
ConfigCategory {
|
||||
name: i18n("General")
|
||||
icon: "configure-symbolic"
|
||||
source: "configGeneral.qml"
|
||||
}
|
||||
}
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
|
||||
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
|
||||
<kcfgfile name=""/>
|
||||
|
||||
<group name="General">
|
||||
<!-- Cava config -->
|
||||
<entry name="framerate" type="Int">
|
||||
<default>60</default>
|
||||
</entry>
|
||||
<entry name="barCount" type="Int">
|
||||
<default>25</default>
|
||||
</entry>
|
||||
<entry name="noiseReduction" type="Int">
|
||||
<default>77</default>
|
||||
</entry>
|
||||
<entry name="monstercat" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="waves" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="autoSensitivity" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="sensitivityEnabled" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="sensitivity" type="Int">
|
||||
<default>100</default>
|
||||
</entry>
|
||||
<entry name="lowerCutoffFreq" type="Int">
|
||||
<default>50</default>
|
||||
</entry>
|
||||
<entry name="higherCutoffFreq" type="Int">
|
||||
<default>10000</default>
|
||||
</entry>
|
||||
<entry name="inputMethod" type="String">
|
||||
<default></default>
|
||||
</entry>
|
||||
<entry name="inputSource" type="String">
|
||||
<default></default>
|
||||
</entry>
|
||||
<entry name="sampleRate" type="Int">
|
||||
<default>44100</default>
|
||||
</entry>
|
||||
<entry name="sampleBits" type="Int">
|
||||
<default>16</default>
|
||||
</entry>
|
||||
<entry name="inputChannels" type="Int">
|
||||
<default>2</default>
|
||||
</entry>
|
||||
<entry name="autoconnect" type="Int">
|
||||
<default>2</default>
|
||||
</entry>
|
||||
<entry name="active" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="remix" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="virtual" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="outputChannels" type="String">
|
||||
<default>mono</default>
|
||||
</entry>
|
||||
<entry name="monoOption" type="String">
|
||||
<default>average</default>
|
||||
</entry>
|
||||
<entry name="reverse" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="eqEnabled" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="eq" type="StringList">
|
||||
<default>1.0,1.0,1.0,1.0,1.0</default>
|
||||
</entry>
|
||||
<!-- Widget config -->
|
||||
<entry name="debugMode" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="hideWhenIdle" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="idleTimer" type="Int">
|
||||
<default>5</default>
|
||||
</entry>
|
||||
<entry name="cavaSleepTimer" type="Int">
|
||||
<default>5</default>
|
||||
</entry>
|
||||
<entry name="visualizerStyle" type="Int">
|
||||
<default>1</default>
|
||||
</entry>
|
||||
<entry name="circleMode" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="circleModeSize" type="Double">
|
||||
<default>0.5</default>
|
||||
</entry>
|
||||
<entry name="fillWave" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="barWidth" type="Int">
|
||||
<default>2</default>
|
||||
</entry>
|
||||
<entry name="blockHeight" type="Int">
|
||||
<default>2</default>
|
||||
</entry>
|
||||
<entry name="blockSpacing" type="Int">
|
||||
<default>2</default>
|
||||
</entry>
|
||||
<entry name="barGap" type="Int">
|
||||
<default>5</default>
|
||||
</entry>
|
||||
<!-- ./package/contents/ui/code/globals.js[baseBarColors] -->
|
||||
<entry name="barColors" type="String">
|
||||
<default>{}</default>
|
||||
</entry>
|
||||
<!-- ./package/contents/ui/code/globals.js[baseWaveFillColors] -->
|
||||
<entry name="waveFillColors" type="String">
|
||||
<default>{}</default>
|
||||
</entry>
|
||||
<!-- ./package/contents/ui/code/globals.js[inactiveBlockColor] -->
|
||||
<entry name="inactiveBlockColors" type="String">
|
||||
<default>{}</default>
|
||||
</entry>
|
||||
<entry name="drawInactiveBlocks" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="desktopWidgetBg" type="Int">
|
||||
<default>1</default>
|
||||
</entry>
|
||||
<entry name="centeredBars" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="roundedBars" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<!-- fill panel thickness -->
|
||||
<entry name="fillPanel" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<!-- take all the available space in the panel -->
|
||||
<entry name="expanding" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="length" type="Int">
|
||||
<default>200</default>
|
||||
</entry>
|
||||
<entry name="orientation" type="Int">
|
||||
<!-- ./package/contents/ui/code/enum.js[Orientation] -->
|
||||
<default>1</default>
|
||||
</entry>
|
||||
<entry name="_stopCava" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="hideToolTip" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="disableLeftClick" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="pauseOnFullScreenWindow" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="pauseOnMaximizedWindow" type="Bool">
|
||||
<default>false</default>
|
||||
</entry>
|
||||
</group>
|
||||
</kcfg>
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+139
@@ -0,0 +1,139 @@
|
||||
import QtQuick
|
||||
import "./components"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property int framerate
|
||||
property int barCount
|
||||
property int noiseReduction
|
||||
property int monstercat // boolean
|
||||
property int waves // boolean
|
||||
property int autoSensitivity // boolean
|
||||
property bool sensitivityEnabled
|
||||
property int sensitivity
|
||||
property int lowerCutoffFreq
|
||||
property int higherCutoffFreq
|
||||
property string inputMethod
|
||||
property string inputSource
|
||||
property int sampleRate
|
||||
property int sampleBits
|
||||
property int inputChannels
|
||||
property int autoconnect
|
||||
property int active // boolean
|
||||
property int remix // boolean
|
||||
property int virtual // boolean
|
||||
property string outputChannels
|
||||
property string monoOption
|
||||
property int reverse // boolean
|
||||
property bool eqEnabled
|
||||
property list<real> eq
|
||||
property list<int> values
|
||||
property bool idle
|
||||
property bool idleCheck
|
||||
property int idleTimer
|
||||
property int cavaSleepTimer
|
||||
property int asciiMaxRange: 100
|
||||
readonly property bool hasError: error !== "" || loadingFailed
|
||||
readonly property string error: process.stderr
|
||||
readonly property list<string> loadingErrors: process.loadingErrors
|
||||
readonly property bool loadingFailed: process.loadingFailed
|
||||
readonly property bool usingFallback: process.usingFallback
|
||||
readonly property bool running: process.running
|
||||
readonly property string cavaCommand: process.command
|
||||
readonly property string cavaConfig: {
|
||||
let config = `[general]
|
||||
framerate=${root.framerate}
|
||||
bars=${root.barCount}
|
||||
autosens=${root.autoSensitivity}
|
||||
lower_cutoff_freq=${root.lowerCutoffFreq}
|
||||
higher_cutoff_freq=${root.higherCutoffFreq}
|
||||
sleep_timer=${root.cavaSleepTimer}
|
||||
`;
|
||||
|
||||
if (root.sensitivityEnabled) {
|
||||
config += `sensitivity=${root.sensitivity}\n`;
|
||||
}
|
||||
config += "[input]\n";
|
||||
if (root.inputMethod !== "") {
|
||||
config += `method=${root.inputMethod}\n`;
|
||||
}
|
||||
if (root.inputSource !== "") {
|
||||
config += `source=${root.inputSource}\n`;
|
||||
}
|
||||
|
||||
config += `sample_rate=${root.sampleRate}
|
||||
sample_bits=${root.sampleBits}
|
||||
channels=${root.inputChannels}
|
||||
autoconnect=${root.autoconnect}
|
||||
active=${root.active}
|
||||
remix=${root.remix}
|
||||
virtual=${root.virtual}
|
||||
[output]
|
||||
channels=${root.outputChannels}
|
||||
mono_option=${root.monoOption}
|
||||
reverse=${root.reverse}
|
||||
method=raw
|
||||
raw_target=/dev/stdout
|
||||
data_format=ascii
|
||||
ascii_max_range=${asciiMaxRange}
|
||||
[smoothing]
|
||||
noise_reduction=${root.noiseReduction}
|
||||
monstercat=${root.monstercat}
|
||||
waves=${root.waves}
|
||||
`;
|
||||
if (root.eqEnabled) {
|
||||
config += "[eq]\n";
|
||||
for (let i = 0; i < eq.length; i++) {
|
||||
config += `${i + 1}=${eq[i]}`;
|
||||
if (i < eq.length - 1) {
|
||||
config += '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}
|
||||
function restart() {
|
||||
process.restart();
|
||||
}
|
||||
function start() {
|
||||
process.start();
|
||||
}
|
||||
function stop() {
|
||||
process.stop();
|
||||
}
|
||||
onCavaConfigChanged: {
|
||||
if (barCount > 0 && cavaConfig != "") {
|
||||
process.command = `exec cava -p /dev/stdin <<-EOF
|
||||
${cavaConfig}
|
||||
EOF
|
||||
`;
|
||||
}
|
||||
}
|
||||
ProcessMonitor {
|
||||
id: process
|
||||
onStdoutChanged: {
|
||||
let output = process.stdout.trim();
|
||||
if (output.endsWith(';')) {
|
||||
output = output.slice(0, -1);
|
||||
}
|
||||
root.values = output.split(";").map(v => parseInt(v, 10));
|
||||
if (!root.idleCheck) {
|
||||
return;
|
||||
}
|
||||
if (root.values.find(v => v > 0)) {
|
||||
if (idleTimer.running) {
|
||||
idleTimer.stop();
|
||||
}
|
||||
root.idle = false;
|
||||
} else {
|
||||
idleTimer.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: idleTimer
|
||||
interval: root.idleTimer * 1000
|
||||
onTriggered: root.idle = true
|
||||
}
|
||||
}
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.plasmoid
|
||||
import "./components"
|
||||
import "code/enum.js" as Enum
|
||||
import "code/globals.js" as Globals
|
||||
import "code/utils.js" as Utils
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
Layout.preferredWidth: Plasmoid.configuration.expanding || main.onDesktop ? -1 : content.implicitWidth
|
||||
Layout.preferredHeight: Plasmoid.configuration.expanding || main.onDesktop ? -1 : content.implicitHeight
|
||||
Layout.minimumWidth: Layout.preferredWidth
|
||||
Layout.minimumHeight: Layout.preferredHeight
|
||||
Layout.fillHeight: main.horizontal || Plasmoid.configuration.expanding || main.onDesktop
|
||||
Layout.fillWidth: !main.horizontal || Plasmoid.configuration.expanding || main.onDesktop
|
||||
|
||||
property int framerate: Plasmoid.configuration.framerate
|
||||
property int barGap: Plasmoid.configuration.barGap
|
||||
property int barWidth: Plasmoid.configuration.barWidth
|
||||
property int blockHeight: Plasmoid.configuration.blockHeight
|
||||
property int blockSpacing: Plasmoid.configuration.blockSpacing
|
||||
property int noiseReduction: Plasmoid.configuration.noiseReduction
|
||||
property int monstercat: Plasmoid.configuration.monstercat
|
||||
property int waves: Plasmoid.configuration.waves
|
||||
property bool centeredBars: Plasmoid.configuration.centeredBars
|
||||
property bool roundedBars: Plasmoid.configuration.roundedBars
|
||||
property int visualizerStyle: Plasmoid.configuration.visualizerStyle
|
||||
property bool circleMode: Plasmoid.configuration.circleMode
|
||||
property real circleModeSize: Plasmoid.configuration.circleModeSize
|
||||
property bool fillWave: Plasmoid.configuration.fillWave
|
||||
property int orientation: Plasmoid.configuration.orientation
|
||||
property bool disableLeftClick: Plasmoid.configuration.disableLeftClick
|
||||
clip: !Plasmoid.configuration.debugMode
|
||||
|
||||
property var logger: Logger.create(Plasmoid.configuration.debugMode ? LoggingCategory.Debug : LoggingCategory.Info)
|
||||
|
||||
property var barColorsCfg: {
|
||||
let barColors;
|
||||
try {
|
||||
barColors = JSON.parse(Plasmoid.configuration.barColors);
|
||||
} catch (e) {
|
||||
logger.error(e, e.stack);
|
||||
globalSettings = Globals.baseBarColors;
|
||||
}
|
||||
const config = Utils.mergeConfigs(Globals.baseBarColors, barColors);
|
||||
const configStr = JSON.stringify(config);
|
||||
if (Plasmoid.configuration.barColors !== configStr) {
|
||||
Plasmoid.configuration.barColors = configStr;
|
||||
Plasmoid.configuration.writeConfig();
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
property var waveFillColorsCfg: {
|
||||
let waveFillColors;
|
||||
try {
|
||||
waveFillColors = JSON.parse(Plasmoid.configuration.waveFillColors);
|
||||
} catch (e) {
|
||||
logger.error(e, e.stack);
|
||||
globalSettings = Globals.baseWaveFillColors;
|
||||
}
|
||||
const config = Utils.mergeConfigs(Globals.baseWaveFillColors, waveFillColors);
|
||||
const configStr = JSON.stringify(config);
|
||||
if (Plasmoid.configuration.waveFillColors !== configStr) {
|
||||
Plasmoid.configuration.waveFillColors = configStr;
|
||||
Plasmoid.configuration.writeConfig();
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
property var inactiveBlockColorsCfg: {
|
||||
let inactiveBlockColors;
|
||||
try {
|
||||
inactiveBlockColors = JSON.parse(Plasmoid.configuration.inactiveBlockColors);
|
||||
} catch (e) {
|
||||
logger.error(e, e.stack);
|
||||
globalSettings = Globals.baseInactiveBlockColors;
|
||||
}
|
||||
const config = Utils.mergeConfigs(Globals.baseInactiveBlockColors, inactiveBlockColors);
|
||||
const configStr = JSON.stringify(config);
|
||||
if (Plasmoid.configuration.inactiveBlockColors !== configStr) {
|
||||
Plasmoid.configuration.inactiveBlockColors = configStr;
|
||||
Plasmoid.configuration.writeConfig();
|
||||
}
|
||||
return config;
|
||||
}
|
||||
property bool drawInactiveBlocks: Plasmoid.configuration.drawInactiveBlocks
|
||||
|
||||
RowLayout {
|
||||
id: content
|
||||
height: [Enum.Orientation.Left, Enum.Orientation.Right].includes(root.orientation) ? parent.width : parent.height
|
||||
width: [Enum.Orientation.Left, Enum.Orientation.Right].includes(root.orientation) ? parent.height : parent.width
|
||||
anchors.centerIn: parent
|
||||
spacing: 0
|
||||
Visualizer {
|
||||
id: visualizer
|
||||
visualizerStyle: root.visualizerStyle
|
||||
circleMode: root.circleMode
|
||||
circleModeSize: root.circleModeSize
|
||||
barWidth: root.barWidth
|
||||
blockHeight: root.blockHeight
|
||||
blockSpacing: root.blockSpacing
|
||||
barGap: root.barGap
|
||||
centeredBars: root.centeredBars
|
||||
roundedBars: root.roundedBars
|
||||
fillWave: root.fillWave
|
||||
barColorsCfg: root.barColorsCfg
|
||||
waveFillColorsCfg: root.waveFillColorsCfg
|
||||
inactiveBlockColorsCfg: root.inactiveBlockColorsCfg
|
||||
drawInactiveBlocks: root.drawInactiveBlocks
|
||||
values: cava.values
|
||||
debugMode: Plasmoid.configuration.debugMode
|
||||
visible: !cava.hasError && !cava.idle
|
||||
fixVertical: !main.horizontal
|
||||
Layout.preferredWidth: (main.horizontal && !Plasmoid.configuration.expanding) ? Plasmoid.configuration.length : -1
|
||||
Layout.preferredHeight: !(main.horizontal && !Plasmoid.configuration.expanding) ? Plasmoid.configuration.length : -1
|
||||
Layout.fillHeight: main.horizontal || Plasmoid.configuration.expanding || [Enum.Orientation.Left, Enum.Orientation.Right].includes(root.orientation) || main.onDesktop
|
||||
Layout.fillWidth: !main.horizontal || Plasmoid.configuration.expanding || [Enum.Orientation.Left, Enum.Orientation.Right].includes(root.orientation) || main.onDesktop
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
|
||||
property var orientationBottom: Rotation {
|
||||
origin.x: Math.floor(visualizer.width / 2)
|
||||
origin.y: Math.floor(visualizer.height / 2)
|
||||
axis {
|
||||
x: 1
|
||||
y: 0
|
||||
z: 0
|
||||
}
|
||||
angle: 0
|
||||
}
|
||||
property var orientationTop: Rotation {
|
||||
origin.x: Math.floor(visualizer.width / 2)
|
||||
origin.y: Math.floor(visualizer.height / 2)
|
||||
axis {
|
||||
x: 1
|
||||
y: 0
|
||||
z: 0
|
||||
}
|
||||
angle: 180
|
||||
}
|
||||
property var orientationLeft: Rotation {
|
||||
origin.x: Math.floor(visualizer.width / 2)
|
||||
origin.y: Math.floor(visualizer.height / 2)
|
||||
angle: 90
|
||||
}
|
||||
property var orientationRight: Rotation {
|
||||
origin.x: Math.floor(visualizer.width / 2)
|
||||
origin.y: Math.floor(visualizer.height / 2)
|
||||
angle: -90
|
||||
}
|
||||
transform: {
|
||||
let t = [];
|
||||
if (main.orientation === Enum.Orientation.Top) {
|
||||
t.push(orientationTop);
|
||||
}
|
||||
if (main.orientation === Enum.Orientation.Left) {
|
||||
t.push(orientationLeft);
|
||||
}
|
||||
if (main.orientation === Enum.Orientation.Right) {
|
||||
t.push(orientationRight);
|
||||
t.push(orientationTop);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
Kirigami.Icon {
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
Layout.preferredWidth: Kirigami.Units.iconSizes.roundedIconSize(Math.min(main.height, main.width))
|
||||
Layout.fillHeight: Layout.preferredWidth
|
||||
source: Qt.resolvedUrl("./icons/error.svg").toString().replace("file://", "")
|
||||
active: mouseArea.containsMouse
|
||||
isMask: true
|
||||
color: Kirigami.Theme.negativeTextColor
|
||||
visible: cava.hasError
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: enabled
|
||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
onClicked: {
|
||||
main.expanded = !main.expanded;
|
||||
}
|
||||
enabled: !root.disableLeftClick || cava.hasError || main.expanded
|
||||
}
|
||||
|
||||
PlasmaCore.ToolTipArea {
|
||||
anchors.fill: parent
|
||||
mainItem: Tooltip {}
|
||||
active: !Plasmoid.configuration.hideToolTip
|
||||
}
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.plasma.components as PlasmaComponents
|
||||
import org.kde.plasma.extras as PlasmaExtras
|
||||
import org.kde.plasma.plasmoid
|
||||
import "./components"
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
Layout.minimumWidth: Kirigami.Units.gridUnit * 25
|
||||
Layout.maximumWidth: Kirigami.Units.gridUnit * 25
|
||||
Layout.minimumHeight: Kirigami.Units.gridUnit * 25
|
||||
Layout.maximumHeight: Kirigami.Units.gridUnit * 25
|
||||
property string cavaVersion: ""
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
PlasmaExtras.Heading {
|
||||
Layout.fillWidth: true
|
||||
text: Plasmoid.metaData.name
|
||||
wrapMode: Text.Wrap
|
||||
horizontalAlignment: TextEdit.AlignHCenter
|
||||
}
|
||||
PlasmaComponents.Label {
|
||||
Layout.leftMargin: Kirigami.Units.gridUnit
|
||||
Layout.rightMargin: Kirigami.Units.gridUnit
|
||||
Layout.fillWidth: true
|
||||
text: i18n("Oh no! Something went wrong")
|
||||
wrapMode: Text.Wrap
|
||||
horizontalAlignment: TextEdit.AlignHCenter
|
||||
visible: cava.hasError
|
||||
font.bold: true
|
||||
color: Kirigami.Theme.negativeTextColor
|
||||
}
|
||||
PlasmaComponents.Button {
|
||||
text: cava.running ? i18n("Stop CAVA") : i18n("Start CAVA")
|
||||
onClicked: {
|
||||
if (cava.running) {
|
||||
cava.stop();
|
||||
} else {
|
||||
cava.start();
|
||||
}
|
||||
}
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
PlasmaComponents.ToolButton {
|
||||
id: copyButton
|
||||
display: PlasmaComponents.AbstractButton.TextBesideIcon
|
||||
text: i18n("Copy to clipboard")
|
||||
icon.name: "edit-copy"
|
||||
onClicked: {
|
||||
textArea.selectAll();
|
||||
textArea.copy();
|
||||
textArea.deselect();
|
||||
}
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
PlasmaComponents.ScrollView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
TextArea {
|
||||
id: textArea
|
||||
text: {
|
||||
let msg = "";
|
||||
if (cava.error) {
|
||||
msg += `Error: ${cava.error}\n`;
|
||||
}
|
||||
if (!cava.running && cava.loadingFailed) {
|
||||
msg += `Error: ${cava.loadingErrors.join('\n')}\n`;
|
||||
}
|
||||
if (cava.running) {
|
||||
msg += `CAVA is running\n`;
|
||||
} else {
|
||||
msg += `❌ CAVA is not running\n`;
|
||||
}
|
||||
msg += `Widget version: ${Plasmoid.metaData.version}\n`;
|
||||
if (root.cavaVersion) {
|
||||
msg += `CAVA version: ${root.cavaVersion}\n`;
|
||||
} else {
|
||||
msg += `❌ CAVA not found\n`;
|
||||
}
|
||||
msg += `Using ProcessMonitorFallback: ${cava.usingFallback}\n`;
|
||||
msg += `Widget install location: ${Qt.resolvedUrl("../../").toString().substring(7)}\n`;
|
||||
msg += `\nCava command:\n${cava.cavaCommand}\n`;
|
||||
return msg;
|
||||
}
|
||||
// HACK: silence binding loop warnings.
|
||||
// contentWidth seems to be causing the binding loop,
|
||||
// but contentWidth is read-only and we have no control
|
||||
// over how it is calculated.
|
||||
implicitWidth: 0
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
wrapMode: Text.Wrap
|
||||
readOnly: true
|
||||
selectByMouse: true
|
||||
}
|
||||
}
|
||||
}
|
||||
RunCommand {
|
||||
id: cavaVersion
|
||||
onExited: (cmd, exitCode, exitStatus, stdout, stderr) => {
|
||||
if (exitCode !== 0) {
|
||||
root.cavaVersion = "";
|
||||
return;
|
||||
}
|
||||
root.cavaVersion = stdout.trim().split(" ").pop();
|
||||
}
|
||||
}
|
||||
Component.onCompleted: cavaVersion.run("cava -v")
|
||||
Timer {
|
||||
interval: 1000
|
||||
onTriggered: {
|
||||
if (root.visible) {
|
||||
cavaVersion.run("cava -v");
|
||||
}
|
||||
}
|
||||
running: root.visible
|
||||
repeat: true
|
||||
triggeredOnStart: true
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
pragma Singleton
|
||||
import QtQuick
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
property int logLevel: LoggingCategory.Info
|
||||
readonly property string name: "luisbocanegra.audio.visualizer"
|
||||
readonly property LoggingCategory loggingCategory: {
|
||||
let cat;
|
||||
switch (logLevel) {
|
||||
case LoggingCategory.Info:
|
||||
cat = infoCategory;
|
||||
break;
|
||||
case LoggingCategory.Warning:
|
||||
cat = warningCategory;
|
||||
break;
|
||||
case LoggingCategory.Critical:
|
||||
cat = errorCategory;
|
||||
break;
|
||||
default:
|
||||
cat = debugCategory;
|
||||
}
|
||||
return cat;
|
||||
}
|
||||
|
||||
readonly property LoggingCategory debugCategory: LoggingCategory {
|
||||
name: root.name
|
||||
defaultLogLevel: LoggingCategory.Debug
|
||||
}
|
||||
readonly property LoggingCategory infoCategory: LoggingCategory {
|
||||
name: root.name
|
||||
defaultLogLevel: LoggingCategory.Info
|
||||
}
|
||||
readonly property LoggingCategory warningCategory: LoggingCategory {
|
||||
name: root.name
|
||||
defaultLogLevel: LoggingCategory.Warning
|
||||
}
|
||||
readonly property LoggingCategory errorCategory: LoggingCategory {
|
||||
name: root.name
|
||||
defaultLogLevel: LoggingCategory.Critical
|
||||
}
|
||||
|
||||
function _fmt(arg) {
|
||||
if (arg === null)
|
||||
return "null";
|
||||
if (arg === undefined)
|
||||
return "undefined";
|
||||
if (typeof arg === "object") {
|
||||
try {
|
||||
return JSON.stringify(arg);
|
||||
} catch (e) {
|
||||
return String(arg);
|
||||
}
|
||||
}
|
||||
return String(arg);
|
||||
}
|
||||
|
||||
function _joinMessage(arr) {
|
||||
return Array.prototype.map.call(arr, _fmt).join(" ");
|
||||
}
|
||||
|
||||
function debug(...message) {
|
||||
console.debug(loggingCategory, `[DEBUG]: ${_joinMessage(message)}`);
|
||||
}
|
||||
|
||||
function info(...message) {
|
||||
console.info(loggingCategory, `[INFO]: ${_joinMessage(message)}`);
|
||||
}
|
||||
|
||||
function warn(...message) {
|
||||
console.warn(loggingCategory, `[WARNING]: ${_joinMessage(message)}`);
|
||||
}
|
||||
|
||||
function error(...message) {
|
||||
console.error(loggingCategory, `[ERROR]: ${_joinMessage(message)}`);
|
||||
}
|
||||
|
||||
function create(logLevel) {
|
||||
if (logLevel != undefined && logLevel !== null) {
|
||||
root.logLevel = logLevel;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
import QtQuick
|
||||
import org.kde.taskmanager as TaskManager
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property var screenGeometry
|
||||
property bool activeExists: false
|
||||
property bool maximizedExists: false
|
||||
property bool fullScreenExists: false
|
||||
property bool visibleExists: false
|
||||
property var abstractTasksModel: TaskManager.AbstractTasksModel
|
||||
property var isMaximized: abstractTasksModel.IsMaximized
|
||||
property var isActive: abstractTasksModel.IsActive
|
||||
property var isWindow: abstractTasksModel.IsWindow
|
||||
property var isFullScreen: abstractTasksModel.IsFullScreen
|
||||
property var isMinimized: abstractTasksModel.IsMinimized
|
||||
property bool filterByActive: false
|
||||
property bool filterByScreen: true
|
||||
property bool trackLastActive: false
|
||||
|
||||
function getTopTask() {
|
||||
let highestTask = null;
|
||||
let maxStackingOrder = 0;
|
||||
for (var i = 0; i < tasksModel.count; i++) {
|
||||
const currentTask = tasksModel.index(i, 0);
|
||||
if (currentTask === undefined || !tasksModel.data(currentTask, isWindow))
|
||||
continue;
|
||||
|
||||
const stakingOder = tasksModel.data(currentTask, abstractTasksModel.StackingOrder);
|
||||
if (stakingOder > maxStackingOrder) {
|
||||
maxStackingOrder = stakingOder;
|
||||
highestTask = currentTask;
|
||||
}
|
||||
}
|
||||
return highestTask;
|
||||
}
|
||||
|
||||
function updateWindowsInfo() {
|
||||
let activeCount = 0;
|
||||
let visibleCount = 0;
|
||||
let maximizedCount = 0;
|
||||
let fullScreenCount = 0;
|
||||
for (var i = 0; i < tasksModel.count; i++) {
|
||||
const currentTask = tasksModel.index(i, 0);
|
||||
if (currentTask === undefined || !tasksModel.data(currentTask, isWindow))
|
||||
continue;
|
||||
|
||||
if (filterByActive && !tasksModel.data(currentTask, isActive))
|
||||
continue;
|
||||
|
||||
visibleCount += 1;
|
||||
if (tasksModel.data(currentTask, isMaximized))
|
||||
maximizedCount += 1;
|
||||
|
||||
if (tasksModel.data(currentTask, isFullScreen))
|
||||
fullScreenCount += 1;
|
||||
}
|
||||
|
||||
let _activeExists = tasksModel.data(tasksModel.activeTask, isActive) || false;
|
||||
let _activeTask = null;
|
||||
let _maximizedExists = maximizedCount > 0;
|
||||
let _fullScreenExists = fullScreenCount > 0;
|
||||
let _visibleExists = visibleCount > 0;
|
||||
if (filterByActive && _activeExists) {
|
||||
_activeTask = tasksModel.activeTask;
|
||||
}
|
||||
|
||||
if (filterByActive && !_activeTask && trackLastActive) {
|
||||
_activeTask = getTopTask();
|
||||
_activeExists = Boolean(_activeTask);
|
||||
}
|
||||
|
||||
if (_activeTask) {
|
||||
_maximizedExists = tasksModel.data(_activeTask, isMaximized) || false;
|
||||
_fullScreenExists = tasksModel.data(_activeTask, isFullScreen) || false;
|
||||
_visibleExists = _activeExists;
|
||||
}
|
||||
|
||||
activeExists = _activeExists;
|
||||
fullScreenExists = _fullScreenExists;
|
||||
maximizedExists = _maximizedExists;
|
||||
visibleExists = _visibleExists;
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onValueChanged() {
|
||||
if (!updateTimer.running)
|
||||
updateTimer.start();
|
||||
}
|
||||
|
||||
target: plasmoid.configuration
|
||||
}
|
||||
|
||||
TaskManager.VirtualDesktopInfo {
|
||||
id: virtualDesktopInfo
|
||||
}
|
||||
|
||||
TaskManager.ActivityInfo {
|
||||
id: activityInfo
|
||||
|
||||
readonly property string nullUuid: "00000000-0000-0000-0000-000000000000"
|
||||
}
|
||||
|
||||
TaskManager.TasksModel {
|
||||
id: tasksModel
|
||||
|
||||
sortMode: TaskManager.TasksModel.SortVirtualDesktop
|
||||
groupMode: TaskManager.TasksModel.GroupDisabled
|
||||
virtualDesktop: virtualDesktopInfo.currentDesktop
|
||||
activity: activityInfo.currentActivity
|
||||
screenGeometry: root.screenGeometry
|
||||
filterByVirtualDesktop: true
|
||||
filterByScreen: root.filterByScreen
|
||||
filterByActivity: true
|
||||
filterMinimized: true
|
||||
onDataChanged: {
|
||||
Qt.callLater(() => {
|
||||
if (!updateTimer.running)
|
||||
updateTimer.start();
|
||||
});
|
||||
}
|
||||
onCountChanged: {
|
||||
Qt.callLater(() => {
|
||||
if (!updateTimer.running)
|
||||
updateTimer.start();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: updateTimer
|
||||
|
||||
interval: 5
|
||||
onTriggered: {
|
||||
root.updateWindowsInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
+356
@@ -0,0 +1,356 @@
|
||||
|
||||
function bars(ctx, canvas, circleMode = false) {
|
||||
if (circleMode) {
|
||||
barsCircle(ctx, canvas);
|
||||
} else {
|
||||
barsRect(ctx, canvas);
|
||||
}
|
||||
}
|
||||
|
||||
function wave(ctx, canvas, circleMode = false) {
|
||||
if (circleMode) {
|
||||
waveCircle(ctx, canvas);
|
||||
} else {
|
||||
waveRect(ctx, canvas);
|
||||
}
|
||||
}
|
||||
|
||||
function blocks(ctx, canvas, circleMode = false) {
|
||||
if (circleMode) {
|
||||
blocksCircle(ctx, canvas);
|
||||
} else {
|
||||
blocksRect(ctx, canvas);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bars
|
||||
* @param {Context2D} ctx QML Type (canvas.getContext('2d'))
|
||||
* @param {Canvas} canvas QML Type
|
||||
*/
|
||||
function barsRect(ctx, canvas) {
|
||||
const canvasHeight = canvas.height;
|
||||
const maxValue = canvasHeight;
|
||||
const barCount = canvas.barCount;
|
||||
const roundedBars = canvas.roundedBars;
|
||||
const barWidth = canvas.barWidth;
|
||||
const centeredBars = canvas.centeredBars;
|
||||
const values = canvas.values;
|
||||
const radiusOffset = canvas.radiusOffset;
|
||||
const spacing = canvas.spacing;
|
||||
ctx.lineCap = roundedBars ? "round" : "butt";
|
||||
ctx.lineWidth = barWidth;
|
||||
|
||||
let x = barWidth / 2;
|
||||
|
||||
const centerY = canvasHeight / 2;
|
||||
for (let i = 0; i < barCount; i++) {
|
||||
const value = Math.max(1, Math.min(maxValue, values[i]));
|
||||
|
||||
let barHeight;
|
||||
let yBottom;
|
||||
let yTop;
|
||||
if (centeredBars) {
|
||||
if (roundedBars) {
|
||||
barHeight = (value / maxValue) * ((canvasHeight - barWidth) / 2);
|
||||
} else {
|
||||
barHeight = (value / maxValue) * (canvasHeight / 2);
|
||||
}
|
||||
yBottom = centerY - barHeight;
|
||||
yTop = yBottom + (barHeight * 2);
|
||||
} else {
|
||||
if (roundedBars) {
|
||||
barHeight = (value / maxValue) * (canvasHeight - barWidth);
|
||||
yBottom = canvasHeight - radiusOffset;
|
||||
} else {
|
||||
barHeight = (value / maxValue) * canvasHeight;
|
||||
yBottom = canvasHeight;
|
||||
}
|
||||
yTop = yBottom - barHeight;
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, yBottom);
|
||||
ctx.lineTo(x, yTop);
|
||||
ctx.stroke();
|
||||
x += barWidth + spacing;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wave
|
||||
* @param {Context2D} ctx QML Type (canvas.getContext('2d'))
|
||||
* @param {Canvas} canvas QML Type
|
||||
*/
|
||||
function waveRect(ctx, canvas) {
|
||||
const canvasWidth = canvas.width;
|
||||
const canvasHeight = canvas.height;
|
||||
const maxValue = canvasHeight;
|
||||
const barCount = canvas.barCount;
|
||||
const roundedBars = canvas.roundedBars;
|
||||
const barWidth = canvas.barWidth;
|
||||
const centeredBars = canvas.centeredBars;
|
||||
const fillWave = canvas.fillWave;
|
||||
const waveFillGradient = canvas.waveFillGradient;
|
||||
const values = canvas.values;
|
||||
|
||||
if (barCount < 2)
|
||||
return;
|
||||
|
||||
ctx.lineCap = roundedBars ? "round" : "butt";
|
||||
ctx.lineWidth = barWidth;
|
||||
|
||||
const step = canvasWidth / (barCount - 1);
|
||||
const yBottom = centeredBars ? (canvasHeight / 2) : (canvasHeight - barWidth / 2);
|
||||
|
||||
canvas.gradientHeight = yBottom;
|
||||
|
||||
ctx.beginPath();
|
||||
let prevX = 0;
|
||||
let prevY = yBottom - Math.max(0, Math.min(maxValue, values[0])) / maxValue * yBottom;
|
||||
ctx.lineTo(prevX - 0.5, prevY);
|
||||
|
||||
for (let i = 1; i < barCount; i++) {
|
||||
const norm = Math.max(0, Math.min(maxValue, values[i])) / maxValue;
|
||||
const x = i * step;
|
||||
const y = yBottom - norm * yBottom;
|
||||
const midX = (prevX + x) / 2;
|
||||
const midY = (prevY + y) / 2;
|
||||
ctx.quadraticCurveTo(prevX, prevY, midX, midY);
|
||||
prevX = x;
|
||||
prevY = y;
|
||||
}
|
||||
|
||||
ctx.lineTo(canvasWidth + 0.5, prevY);
|
||||
ctx.stroke();
|
||||
|
||||
if (fillWave && waveFillGradient) {
|
||||
const yBottom = centeredBars ? (canvasHeight / 2 + barWidth / 2) : canvasHeight;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0, yBottom);
|
||||
|
||||
prevX = 0;
|
||||
prevY = yBottom - Math.max(0, Math.min(maxValue, values[0])) / maxValue * yBottom;
|
||||
ctx.lineTo(prevX, prevY);
|
||||
|
||||
for (let i = 1; i < barCount; i++) {
|
||||
const norm = Math.max(0, Math.min(maxValue, values[i])) / maxValue;
|
||||
const x = i * step;
|
||||
const y = yBottom - norm * yBottom;
|
||||
const midX = (prevX + x) / 2;
|
||||
const midY = (prevY + y) / 2;
|
||||
ctx.quadraticCurveTo(prevX, prevY, midX, midY);
|
||||
prevX = x;
|
||||
prevY = y;
|
||||
}
|
||||
|
||||
ctx.lineTo(canvasWidth, prevY);
|
||||
ctx.lineTo(canvasWidth, yBottom);
|
||||
ctx.closePath();
|
||||
ctx.fillStyle = waveFillGradient;
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bars in circle mode
|
||||
* @param {Context2D} ctx QML Type (canvas.getContext('2d'))
|
||||
* @param {Canvas} canvas QML Type
|
||||
*/
|
||||
function barsCircle(ctx, canvas) {
|
||||
const canvasWidth = canvas.width;
|
||||
const canvasHeight = canvas.height;
|
||||
const maxValue = Math.min(canvasWidth, canvasHeight) / 2;
|
||||
const barCount = canvas.barCount;
|
||||
const roundedBars = canvas.roundedBars;
|
||||
const barWidth = canvas.barWidth;
|
||||
const values = canvas.values;
|
||||
const barRadiusOffset = canvas.radiusOffset * 2;
|
||||
const circleSize = canvas.circleModeSize;
|
||||
ctx.lineCap = roundedBars ? "round" : "butt";
|
||||
ctx.lineWidth = barWidth;
|
||||
|
||||
const centerX = canvasWidth / 2;
|
||||
const centerY = canvasHeight / 2;
|
||||
const angleStep = (2 * Math.PI) / barCount;
|
||||
const innerRadius = (Math.min(canvasWidth, canvasHeight) / 2) * circleSize - barRadiusOffset;
|
||||
|
||||
for (let i = 0; i < barCount; i++) {
|
||||
const value = Math.max(1, Math.min(maxValue, values[i]));
|
||||
const norm = value / maxValue;
|
||||
const barLength = norm * (maxValue - barWidth / 2) * (1 - circleSize);
|
||||
const angle = i * angleStep - Math.PI / 2;
|
||||
|
||||
const xStart = centerX + Math.cos(angle) * innerRadius;
|
||||
const yStart = centerY + Math.sin(angle) * innerRadius;
|
||||
const xEnd = centerX + Math.cos(angle) * (innerRadius + barLength);
|
||||
const yEnd = centerY + Math.sin(angle) * (innerRadius + barLength);
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(xStart, yStart);
|
||||
ctx.lineTo(xEnd, yEnd);
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wave in circle mode
|
||||
* @param {Context2D} ctx QML Type (canvas.getContext('2d'))
|
||||
* @param {Canvas} canvas QML Type
|
||||
*/
|
||||
function waveCircle(ctx, canvas) {
|
||||
const canvasWidth = canvas.width;
|
||||
const canvasHeight = canvas.height;
|
||||
const maxValue = Math.min(canvasWidth, canvasHeight) / 2;
|
||||
const barCount = canvas.barCount;
|
||||
const circleSize = canvas.circleModeSize;
|
||||
const innerRadius = (Math.min(canvasWidth, canvasHeight) / 2) * circleSize;
|
||||
const barWidth = canvas.barWidth;
|
||||
const fillWave = canvas.fillWave;
|
||||
const waveFillGradient = canvas.waveFillGradient;
|
||||
const values = canvas.values;
|
||||
|
||||
if (barCount < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.lineWidth = barWidth;
|
||||
|
||||
const centerX = canvasWidth / 2;
|
||||
const centerY = canvasHeight / 2;
|
||||
const angleStep = (2 * Math.PI) / barCount;
|
||||
|
||||
canvas.gradientHeight = maxValue - innerRadius;
|
||||
|
||||
const outerPoints = new Array(barCount + 1);
|
||||
for (let i = 0; i <= barCount; i++) {
|
||||
const idx = i % barCount;
|
||||
const val = Math.max(0, Math.min(maxValue, values[idx]));
|
||||
const radial = val * (1 - circleSize);
|
||||
const angle = idx * angleStep - Math.PI / 2;
|
||||
outerPoints[i] = {
|
||||
x: centerX + Math.cos(angle) * (innerRadius + radial),
|
||||
y: centerY + Math.sin(angle) * (innerRadius + radial)
|
||||
};
|
||||
}
|
||||
|
||||
// wave line
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(outerPoints[0].x, outerPoints[0].y);
|
||||
let prev = outerPoints[0];
|
||||
for (let i = 1; i < outerPoints.length; i++) {
|
||||
const cur = outerPoints[i];
|
||||
const midX = (prev.x + cur.x) / 2;
|
||||
const midY = (prev.y + cur.y) / 2;
|
||||
ctx.quadraticCurveTo(prev.x, prev.y, midX, midY);
|
||||
prev = cur;
|
||||
}
|
||||
// back to start
|
||||
ctx.quadraticCurveTo(prev.x, prev.y, (prev.x + outerPoints[0].x) / 2, (prev.y + outerPoints[0].y) / 2);
|
||||
ctx.stroke();
|
||||
|
||||
if (fillWave && waveFillGradient) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(outerPoints[0].x, outerPoints[0].y);
|
||||
prev = outerPoints[0];
|
||||
for (let i = 1; i < outerPoints.length; i++) {
|
||||
const cur = outerPoints[i];
|
||||
const midX = (prev.x + cur.x) / 2;
|
||||
const midY = (prev.y + cur.y) / 2;
|
||||
ctx.quadraticCurveTo(prev.x, prev.y, midX, midY);
|
||||
prev = cur;
|
||||
}
|
||||
ctx.quadraticCurveTo(prev.x, prev.y, (prev.x + outerPoints[0].x) / 2, (prev.y + outerPoints[0].y) / 2);
|
||||
|
||||
const startAngle = -Math.PI / 2;
|
||||
const innerStartX = centerX + Math.cos(startAngle) * innerRadius;
|
||||
const innerStartY = centerY + Math.sin(startAngle) * innerRadius;
|
||||
ctx.lineTo(innerStartX, innerStartY);
|
||||
ctx.arc(centerX, centerY, innerRadius, startAngle, startAngle + 2 * Math.PI, false);
|
||||
|
||||
ctx.closePath();
|
||||
ctx.fillStyle = waveFillGradient;
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks
|
||||
* @param {Context2D} ctx QML Type (canvas.getContext('2d'))
|
||||
* @param {Canvas} canvas QML Type
|
||||
*/
|
||||
function blocksRect(ctx, canvas) {
|
||||
const canvasHeight = canvas.height;
|
||||
const barCount = canvas.barCount;
|
||||
const blockWidth = canvas.barWidth;
|
||||
const blockHeight = canvas.blockHeight;
|
||||
const blockSpacing = canvas.blockSpacing;
|
||||
const totalRows = Math.floor((canvasHeight + blockSpacing) / (blockHeight + blockSpacing));
|
||||
const columnSpacing = canvas.spacing;
|
||||
const values = canvas.values || [];
|
||||
|
||||
for (let col = 0; col < barCount; col++) {
|
||||
let value = values[col];
|
||||
const activeRows = Math.floor((value / canvasHeight) * totalRows);
|
||||
|
||||
for (let row = 0; row < totalRows; row++) {
|
||||
const x = col * (blockWidth + columnSpacing);
|
||||
const y = canvasHeight - (row + 1) * blockHeight - row * blockSpacing;
|
||||
|
||||
if (row < activeRows) {
|
||||
ctx.fillStyle = canvas.gradient;
|
||||
ctx.fillRect(x, y, blockWidth, blockHeight);
|
||||
}
|
||||
else if (canvas.drawInactiveBlocks) {
|
||||
ctx.fillStyle = canvas.inactiveBlockGradient;
|
||||
ctx.fillRect(x, y, blockWidth, blockHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function blocksCircle(ctx, canvas) {
|
||||
const canvasWidth = canvas.width;
|
||||
const canvasHeight = canvas.height;
|
||||
const barCount = canvas.barCount;
|
||||
const blockWidth = canvas.barWidth;
|
||||
const circleSize = canvas.circleModeSize;
|
||||
const innerRadius = (Math.min(canvasWidth, canvasHeight) / 2) * circleSize;
|
||||
const blockHeight = canvas.blockHeight;
|
||||
const blockSpacing = canvas.blockSpacing;
|
||||
const totalRows = Math.floor(((Math.min(canvasWidth, canvasHeight) / 2) - innerRadius + blockSpacing) / (blockHeight + blockSpacing));
|
||||
const angleStep = (2 * Math.PI) / barCount;
|
||||
const values = canvas.values || [];
|
||||
|
||||
const centerX = canvasWidth / 2;
|
||||
const centerY = canvasHeight / 2;
|
||||
|
||||
for (let col = 0; col < barCount; col++) {
|
||||
let value = values[col];
|
||||
const activeRows = Math.floor((value / (Math.min(canvasWidth, canvasHeight) / 2)) * totalRows);
|
||||
|
||||
for (let row = 0; row < totalRows; row++) {
|
||||
const radius = innerRadius + row * (blockHeight + blockSpacing) + blockHeight / 2;
|
||||
const angle = col * angleStep - Math.PI / 2;
|
||||
|
||||
const x = centerX + Math.cos(angle) * radius - (blockHeight / 2);
|
||||
const y = centerY + Math.sin(angle) * radius - (blockHeight / 2);
|
||||
|
||||
ctx.save();
|
||||
ctx.translate(x + blockHeight / 2, y + blockHeight / 2);
|
||||
ctx.rotate(angle + Math.PI / 2);
|
||||
ctx.translate(-(x + blockHeight / 2), -(y + blockHeight / 2));
|
||||
|
||||
if (row < activeRows) {
|
||||
ctx.fillStyle = canvas.gradient;
|
||||
ctx.fillRect(x, y, blockWidth, blockHeight);
|
||||
}
|
||||
else if (canvas.drawInactiveBlocks) {
|
||||
ctx.fillStyle = canvas.inactiveBlockGradient;
|
||||
ctx.fillRect(x, y, blockWidth, blockHeight);
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
const VisualizerStyles = {
|
||||
Bars: 0,
|
||||
Wave: 1,
|
||||
Blocks: 2,
|
||||
};
|
||||
|
||||
const Orientation = {
|
||||
Top: 0,
|
||||
Bottom: 1,
|
||||
Left: 2,
|
||||
Right: 3,
|
||||
};
|
||||
|
||||
const ColorSourceType = {
|
||||
Custom: 0,
|
||||
SystemTheme: 1,
|
||||
List: 2,
|
||||
Random: 3,
|
||||
// 4-6 unused
|
||||
Hue: 7,
|
||||
};
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
const baseColorList = [
|
||||
"#ED8796",
|
||||
"#A6DA95",
|
||||
"#EED49F",
|
||||
"#8AADF4",
|
||||
"#F5BDE6",
|
||||
"#8BD5CA",
|
||||
"#f5a97f",
|
||||
];
|
||||
|
||||
const baseBarColors = {
|
||||
enabled: false,
|
||||
lightness: 0.5,
|
||||
saturation: 0.5,
|
||||
alpha: 1,
|
||||
systemColor: "highlightColor",
|
||||
systemColorSet: "Window",
|
||||
custom: "#013eff",
|
||||
list: baseColorList,
|
||||
reverseList: false,
|
||||
followColor: 0,
|
||||
saturationEnabled: false,
|
||||
lightnessEnabled: false,
|
||||
sourceType: 7,
|
||||
smoothGradient: true,
|
||||
colorsOrientation: 0,
|
||||
image: {
|
||||
source: "",
|
||||
fillMode: 2
|
||||
},
|
||||
hueStart: 0,
|
||||
hueEnd: 360,
|
||||
};
|
||||
|
||||
const baseWaveFillColors = {
|
||||
enabled: false,
|
||||
lightness: 0.5,
|
||||
saturation: 0.5,
|
||||
alpha: 0.3,
|
||||
systemColor: "highlightColor",
|
||||
systemColorSet: "Window",
|
||||
custom: "#013eff",
|
||||
list: baseColorList,
|
||||
reverseList: false,
|
||||
followColor: 0,
|
||||
saturationEnabled: false,
|
||||
lightnessEnabled: false,
|
||||
sourceType: 7,
|
||||
smoothGradient: true,
|
||||
colorsOrientation: 0,
|
||||
image: {
|
||||
source: "",
|
||||
fillMode: 2
|
||||
},
|
||||
hueStart: 0,
|
||||
hueEnd: 360,
|
||||
};
|
||||
|
||||
const baseInactiveBlockColors = {
|
||||
enabled: false,
|
||||
lightness: 0.5,
|
||||
saturation: 0.5,
|
||||
alpha: 0.3,
|
||||
systemColor: "textColor",
|
||||
systemColorSet: "Window",
|
||||
custom: "#013eff",
|
||||
list: baseColorList,
|
||||
reverseList: false,
|
||||
followColor: 0,
|
||||
saturationEnabled: false,
|
||||
lightnessEnabled: false,
|
||||
sourceType: 1,
|
||||
smoothGradient: true,
|
||||
colorsOrientation: 0,
|
||||
image: {
|
||||
source: "",
|
||||
fillMode: 2
|
||||
},
|
||||
hueStart: 0,
|
||||
hueEnd: 360,
|
||||
};
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
|
||||
function mergeConfigs(sourceConfig, newConfig) {
|
||||
for (var key in sourceConfig) {
|
||||
if (Array.isArray(sourceConfig[key])) {
|
||||
if (!newConfig.hasOwnProperty(key)) {
|
||||
newConfig[key] = sourceConfig[key].slice();
|
||||
}
|
||||
} else if (typeof sourceConfig[key] === "object" && sourceConfig[key] !== null) {
|
||||
if (!newConfig.hasOwnProperty(key)) {
|
||||
newConfig[key] = {};
|
||||
}
|
||||
mergeConfigs(sourceConfig[key], newConfig[key]);
|
||||
} else {
|
||||
if (!newConfig.hasOwnProperty(key)) {
|
||||
newConfig[key] = sourceConfig[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return newConfig;
|
||||
}
|
||||
|
||||
function getRandomColor(h, s, l, a) {
|
||||
h = h ?? Math.random();
|
||||
s = s ?? Math.random();
|
||||
l = l ?? Math.random();
|
||||
a = a ?? 1.0;
|
||||
return Qt.hsla(h, s, l, a);
|
||||
}
|
||||
|
||||
function scaleSaturation(color, saturation) {
|
||||
return Qt.hsla(color.hslHue, saturation, color.hslLightness, color.a);
|
||||
}
|
||||
|
||||
function scaleLightness(color, lightness) {
|
||||
return Qt.hsla(color.hslHue, color.hslSaturation, lightness, color.a);
|
||||
}
|
||||
|
||||
function adjustColor(color, saturationEnabled, saturation, lightnessEnabled, lightness, alpha) {
|
||||
if (saturationEnabled) {
|
||||
color = scaleSaturation(color, saturation);
|
||||
}
|
||||
if (lightnessEnabled) {
|
||||
color = scaleLightness(color, lightness);
|
||||
}
|
||||
if (alpha !== 1.0) {
|
||||
color = Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
function hexToRgb(hex) {
|
||||
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result
|
||||
? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16),
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
function rgbToQtColor(rgb) {
|
||||
return Qt.rgba(rgb.r / 255, rgb.g / 255, rgb.b / 255, 1);
|
||||
}
|
||||
|
||||
function hexToQtColor(hex) {
|
||||
let rgb = hexToRgb(hex);
|
||||
return rgbToQtColor(rgb);
|
||||
}
|
||||
|
||||
function buildCanvasGradient(ctx, smooth, gradientStops, orientation, height, width, circleMode = false) {
|
||||
let gradient;
|
||||
if (circleMode) {
|
||||
const centerX = width / 2;
|
||||
const centerY = height / 2;
|
||||
const radius = Math.min(width, height) / 2;
|
||||
gradient = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, radius);
|
||||
} else if (orientation === 0) {
|
||||
gradient = ctx.createLinearGradient(0, 0, width, 0);
|
||||
} else {
|
||||
gradient = ctx.createLinearGradient(0, height, 0, 0);
|
||||
}
|
||||
for (let i = 0; i < gradientStops.length; i++) {
|
||||
const stop = gradientStops[i];
|
||||
let color = stop.color ?? stop;
|
||||
let position = stop.position ?? (1 / gradientStops.length) * i;
|
||||
gradient.addColorStop(position, color);
|
||||
if (!smooth && i > 0 && i < gradientStops.length) {
|
||||
let prevStop = gradientStops[i - 1];
|
||||
let prevColor = prevStop.color ?? prevStop;
|
||||
gradient.addColorStop(Math.max(position - 0.0001, 0), prevColor);
|
||||
}
|
||||
}
|
||||
return gradient;
|
||||
}
|
||||
|
||||
function getColors(barColorsCfg, barCount, themeColor) {
|
||||
const saturationEnabled = barColorsCfg.saturationEnabled;
|
||||
const saturation = barColorsCfg.saturation;
|
||||
const lightnessEnabled = barColorsCfg.lightnessEnabled;
|
||||
const lightness = barColorsCfg.lightness;
|
||||
const alpha = barColorsCfg.alpha;
|
||||
const colorSourceType = barColorsCfg.sourceType;
|
||||
const reverseList = barColorsCfg.reverseList;
|
||||
const hueStart = barColorsCfg.hueStart;
|
||||
const hueEnd = barColorsCfg.hueEnd;
|
||||
|
||||
let colors = [];
|
||||
let color = null;
|
||||
if (colorSourceType === Enum.ColorSourceType.Custom) {
|
||||
color = hexToQtColor(barColorsCfg.custom);
|
||||
} else if (colorSourceType === Enum.ColorSourceType.SystemTheme) {
|
||||
color = themeColor;
|
||||
}
|
||||
if (color) {
|
||||
colors.push(adjustColor(color, saturationEnabled, saturation, lightnessEnabled, lightness, alpha));
|
||||
}
|
||||
if (colorSourceType === Enum.ColorSourceType.List) {
|
||||
colors = barColorsCfg.list.map(c => adjustColor(hexToQtColor(c), saturationEnabled, saturation, lightnessEnabled, lightness, alpha));
|
||||
}
|
||||
if (colorSourceType === Enum.ColorSourceType.Random) {
|
||||
for (let i = 0; i < barCount; i++) {
|
||||
colors.push(adjustColor(getRandomColor(null, 0.8, 0.7, null), saturationEnabled, saturation, lightnessEnabled, lightness, alpha));
|
||||
}
|
||||
}
|
||||
if (colorSourceType === Enum.ColorSourceType.Hue) {
|
||||
const start = hueStart / 360;
|
||||
const end = hueEnd / 360;
|
||||
for (let i = 0; i < barCount; i++) {
|
||||
let c = Qt.hsla(start + ((i / barCount) * (end - start)), 0.8, 0.7, 1.0);
|
||||
colors.push(adjustColor(c, saturationEnabled, saturation, lightnessEnabled, lightness, alpha));
|
||||
}
|
||||
}
|
||||
if (reverseList) {
|
||||
let reversed = [];
|
||||
for (let i = colors.length - 1; i >= 0; i--) {
|
||||
reversed.push(colors[i]);
|
||||
}
|
||||
colors = reversed;
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/28507619/how-to-create-delay-function-in-qml
|
||||
function delay(interval, callback, parentItem) {
|
||||
let timer = Qt.createQmlObject("import QtQuick; Timer {}", parentItem);
|
||||
timer.interval = interval;
|
||||
timer.repeat = false;
|
||||
timer.triggered.connect(callback);
|
||||
timer.triggered.connect(function release() {
|
||||
timer.triggered.disconnect(callback);
|
||||
timer.triggered.disconnect(release);
|
||||
timer.destroy();
|
||||
});
|
||||
timer.start();
|
||||
}
|
||||
|
||||
function makeEven(n) {
|
||||
return n - (n % 2);
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
// This is a modified version of https://invent.kde.org/frameworks/kdeclarative/-/blob/master/src/qmlcontrols/kquickcontrols/ColorButton.qml to make it look more like a button
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Dialogs
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
Button {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* The user selected color
|
||||
*/
|
||||
property alias color: colorDialog.selectedColor
|
||||
/**
|
||||
* Title to show in the dialog
|
||||
*/
|
||||
property alias dialogTitle: colorDialog.title
|
||||
/**
|
||||
* Allow the user to configure an alpha value
|
||||
*/
|
||||
property bool showAlphaChannel: false
|
||||
property bool showCurentColor: true
|
||||
|
||||
/**
|
||||
* This signal is emitted when the color dialog has been accepted
|
||||
*
|
||||
* @since 5.61
|
||||
*/
|
||||
signal accepted(string color)
|
||||
|
||||
onClicked: {
|
||||
colorDialog.open();
|
||||
}
|
||||
|
||||
ColorDialog {
|
||||
id: colorDialog
|
||||
onAccepted: root.accepted(color)
|
||||
parentWindow: root.Window.window
|
||||
options: root.showAlphaChannel ? ColorDialog.ShowAlphaChannel : undefined
|
||||
}
|
||||
|
||||
contentItem: Item {
|
||||
implicitWidth: btnL.implicitWidth + 8
|
||||
implicitHeight: btnL.implicitHeight
|
||||
|
||||
RowLayout {
|
||||
id: btnL
|
||||
|
||||
anchors.centerIn: parent
|
||||
|
||||
Rectangle {
|
||||
color: root.color
|
||||
height: currentColorText.implicitHeight
|
||||
width: height
|
||||
radius: 2
|
||||
|
||||
border {
|
||||
width: 1
|
||||
color: Kirigami.Theme.textColor
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
id: currentColorText
|
||||
text: root.color.toString().toUpperCase()
|
||||
visible: root.showCurentColor
|
||||
textFormat: Text.PlainText
|
||||
font.family: "Monospace"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+266
@@ -0,0 +1,266 @@
|
||||
// pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.plasma.plasmoid
|
||||
import "../"
|
||||
|
||||
// A component to create a list of color pickers
|
||||
// color (hex) | ColorButton | randomize | position | delete | add new
|
||||
// ...
|
||||
// text field with colors | update list above
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
property var stopsList: []
|
||||
signal colorsChanged(stopsList: var)
|
||||
property bool ready: false
|
||||
signal removeColor(index: int)
|
||||
|
||||
onRemoveColor: index => {
|
||||
stopsListModel.remove(index);
|
||||
updateColorsList();
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: stopsListModel
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: stopsListModelTmp
|
||||
ListElement {
|
||||
color: "#ff0000"
|
||||
position: 0.0
|
||||
}
|
||||
}
|
||||
|
||||
property var logger: Logger.create(Plasmoid.configuration.debugMode ? LoggingCategory.Debug : LoggingCategory.Info)
|
||||
|
||||
Connections {
|
||||
target: stopsListModel
|
||||
function onCountChanged(count, ready) {
|
||||
if (!ready)
|
||||
return;
|
||||
logger.debug("model count changed:", count);
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
|
||||
onStopsListChanged: {
|
||||
initColorsListModel();
|
||||
}
|
||||
|
||||
function initColorsListModel() {
|
||||
if (stopsListModel.count !== 0) {
|
||||
return;
|
||||
}
|
||||
ready = false;
|
||||
const stops = stopsList;
|
||||
for (let stop of stops) {
|
||||
stopsListModel.append({
|
||||
"color": stop.color,
|
||||
"position": stop.position
|
||||
});
|
||||
}
|
||||
ready = true;
|
||||
}
|
||||
|
||||
function getRandomColor() {
|
||||
const h = Math.random();
|
||||
const s = Math.random();
|
||||
const l = Math.random();
|
||||
const a = 1.0;
|
||||
logger.debug(h, s, l);
|
||||
return Qt.hsla(h, s, l, a);
|
||||
}
|
||||
|
||||
function updateColorsList() {
|
||||
logger.debug("updateColorsList()");
|
||||
let colors_list = [];
|
||||
for (let i = 0; i < stopsListModel.count; i++) {
|
||||
colors_list.push({
|
||||
"color": stopsListModel.get(i).color,
|
||||
"position": stopsListModel.get(i).position
|
||||
});
|
||||
}
|
||||
stopsList = colors_list;
|
||||
colorsChanged(stopsList);
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
initColorsListModel();
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Repeater {
|
||||
id: customColorsRepeater
|
||||
model: stopsListModel
|
||||
delegate: RowLayout {
|
||||
|
||||
TextMetrics {
|
||||
id: metrics
|
||||
text: (model.length + 1).toString()
|
||||
}
|
||||
|
||||
Label {
|
||||
text: (index + 1).toString() + "."
|
||||
Layout.preferredWidth: metrics.width
|
||||
}
|
||||
|
||||
TextMetrics {
|
||||
id: colorMetrics
|
||||
text: "#FFFFFF"
|
||||
}
|
||||
|
||||
TextArea {
|
||||
text: model.color
|
||||
font.capitalization: Font.AllUppercase
|
||||
Kirigami.SpellCheck.enabled: false
|
||||
Layout.preferredWidth: colorMetrics.width * 1.4
|
||||
onTextChanged: {
|
||||
if (text !== model.color) {
|
||||
stopsListModel.set(index, {
|
||||
"color": text
|
||||
});
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColorButton {
|
||||
showAlphaChannel: true
|
||||
dialogTitle: i18n("Widget background") + "(" + index + ")"
|
||||
color: model.color
|
||||
showCurentColor: false
|
||||
onAccepted: color => {
|
||||
stopsListModel.set(index, {
|
||||
"color": color.toString()
|
||||
});
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.name: "randomize-symbolic"
|
||||
onClicked: {
|
||||
stopsListModel.set(index, {
|
||||
"color": getRandomColor().toString()
|
||||
});
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.name: "arrow-up"
|
||||
enabled: index > 0
|
||||
onClicked: {
|
||||
let prevIndex = index - 1;
|
||||
let prev = stopsListModel.get(prevIndex).color;
|
||||
stopsListModel.set(prevIndex, stopsListModel.get(index));
|
||||
stopsListModel.set(index, {
|
||||
"color": prev
|
||||
});
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.name: "arrow-down"
|
||||
enabled: index < stopsListModel.count - 1
|
||||
onClicked: {
|
||||
let nextIndex = index + 1;
|
||||
let next = stopsListModel.get(nextIndex).color;
|
||||
stopsListModel.set(nextIndex, stopsListModel.get(index));
|
||||
stopsListModel.set(index, {
|
||||
"color": next
|
||||
});
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
id: stepPositionSpinbox
|
||||
value: model.position * multiplier
|
||||
// Component.onCompleted: value = parseFloat(model.position)
|
||||
from: 0 * multiplier
|
||||
to: 1 * multiplier
|
||||
onValueModified: {
|
||||
if (value !== model.position / stepPositionSpinbox.multiplier) {
|
||||
stopsListModel.set(index, {
|
||||
"position": value / stepPositionSpinbox.multiplier
|
||||
});
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.name: "edit-delete-remove"
|
||||
onClicked: {
|
||||
root.removeColor(index);
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.name: "list-add-symbolic"
|
||||
onClicked: {
|
||||
stopsListModel.insert(index + 1, {
|
||||
"color": getRandomColor().toString(),
|
||||
"position": 0.0
|
||||
});
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: stopsListModel.count === 0
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
icon.name: "list-add-symbolic"
|
||||
onClicked: {
|
||||
stopsListModel.insert(0, {
|
||||
"color": getRandomColor().toString(),
|
||||
"position": 0.0
|
||||
});
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
TextArea {
|
||||
id: customColors
|
||||
text: stopsList?.map(s => s.color + ":" + s.position).join(" ") || []
|
||||
Layout.preferredWidth: 300
|
||||
Layout.fillWidth: true
|
||||
wrapMode: TextEdit.WordWrap
|
||||
font.capitalization: Font.AllUppercase
|
||||
Kirigami.SpellCheck.enabled: false
|
||||
}
|
||||
Button {
|
||||
id: btn
|
||||
icon.name: "view-refresh-symbolic"
|
||||
onClicked: {
|
||||
stopsList = customColors.text.split(" ").map(s => {
|
||||
logger.debug(s.split(":"));
|
||||
return {
|
||||
"color": s.split(":")[0],
|
||||
"position": parseFloat(s.split(":")[1])
|
||||
};
|
||||
});
|
||||
stopsListModel.clear();
|
||||
initColorsListModel();
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.plasma.plasmoid
|
||||
import "../"
|
||||
|
||||
// A component to create a list of color pickers
|
||||
// color (hex) | ColorButton | randomize | move up | move down | delete | add new
|
||||
// ...
|
||||
// text field with colors | update list above
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
property var colorsList: []
|
||||
signal colorsChanged(newColors: var)
|
||||
property bool ready: false
|
||||
signal removeColor(index: int)
|
||||
|
||||
onRemoveColor: index => {
|
||||
colorsListModel.remove(index);
|
||||
updateColorsList();
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: colorsListModel
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: colorsListModelTmp
|
||||
ListElement {
|
||||
color: "#ff0000"
|
||||
}
|
||||
}
|
||||
|
||||
property var logger: Logger.create(Plasmoid.configuration.debugMode ? LoggingCategory.Debug : LoggingCategory.Info)
|
||||
|
||||
Connections {
|
||||
target: colorsListModel
|
||||
function onCountChanged(count, ready) {
|
||||
if (!ready)
|
||||
return;
|
||||
logger.debug("model count changed:", count);
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
|
||||
onColorsListChanged: {
|
||||
initColorsListModel();
|
||||
}
|
||||
|
||||
function initColorsListModel() {
|
||||
if (colorsListModel.count !== 0) {
|
||||
return;
|
||||
}
|
||||
ready = false;
|
||||
const colors = colorsList;
|
||||
for (let i in colors) {
|
||||
colorsListModel.append({
|
||||
"color": colors[i]
|
||||
});
|
||||
}
|
||||
ready = true;
|
||||
}
|
||||
|
||||
function getRandomColor() {
|
||||
const h = Math.random();
|
||||
const s = Math.random();
|
||||
const l = Math.random();
|
||||
const a = 1.0;
|
||||
logger.debug(h, s, l);
|
||||
return Qt.hsla(h, s, l, a);
|
||||
}
|
||||
|
||||
function updateColorsList() {
|
||||
logger.debug("updateColorsList()");
|
||||
let colors_list = [];
|
||||
for (let i = 0; i < colorsListModel.count; i++) {
|
||||
let c = colorsListModel.get(i).color;
|
||||
colors_list.push(c);
|
||||
}
|
||||
colorsList = colors_list;
|
||||
colorsChanged(colorsList);
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
initColorsListModel();
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Repeater {
|
||||
id: customColorsRepeater
|
||||
model: colorsListModel
|
||||
delegate: RowLayout {
|
||||
|
||||
TextMetrics {
|
||||
id: metrics
|
||||
text: (model.length + 1).toString()
|
||||
}
|
||||
|
||||
Label {
|
||||
text: (index + 1).toString() + "."
|
||||
Layout.preferredWidth: metrics.width
|
||||
}
|
||||
|
||||
TextMetrics {
|
||||
id: colorMetrics
|
||||
text: "#FFFFFF"
|
||||
}
|
||||
|
||||
TextArea {
|
||||
text: modelData
|
||||
font.capitalization: Font.AllUppercase
|
||||
Kirigami.SpellCheck.enabled: false
|
||||
Layout.preferredWidth: colorMetrics.width * 1.4
|
||||
onTextChanged: {
|
||||
if (text !== modelData) {
|
||||
colorsListModel.set(index, {
|
||||
"color": text
|
||||
});
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColorButton {
|
||||
showAlphaChannel: false
|
||||
dialogTitle: i18n("Widget background") + "(" + index + ")"
|
||||
color: modelData
|
||||
showCurentColor: false
|
||||
onAccepted: color => {
|
||||
colorsListModel.set(index, {
|
||||
"color": color.toString()
|
||||
});
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.name: "randomize-symbolic"
|
||||
onClicked: {
|
||||
colorsListModel.set(index, {
|
||||
"color": getRandomColor().toString()
|
||||
});
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.name: "arrow-up"
|
||||
enabled: index > 0
|
||||
onClicked: {
|
||||
let prevIndex = index - 1;
|
||||
let prev = colorsListModel.get(prevIndex).color;
|
||||
colorsListModel.set(prevIndex, colorsListModel.get(index));
|
||||
colorsListModel.set(index, {
|
||||
"color": prev
|
||||
});
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.name: "arrow-down"
|
||||
enabled: index < colorsListModel.count - 1
|
||||
onClicked: {
|
||||
let nextIndex = index + 1;
|
||||
let next = colorsListModel.get(nextIndex).color;
|
||||
colorsListModel.set(nextIndex, colorsListModel.get(index));
|
||||
colorsListModel.set(index, {
|
||||
"color": next
|
||||
});
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.name: "edit-delete-remove"
|
||||
onClicked: {
|
||||
root.removeColor(index);
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.name: "list-add-symbolic"
|
||||
onClicked: {
|
||||
colorsListModel.insert(index + 1, {
|
||||
"color": getRandomColor().toString()
|
||||
});
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: colorsListModel.count === 0
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
icon.name: "list-add-symbolic"
|
||||
onClicked: {
|
||||
colorsListModel.insert(0, {
|
||||
"color": getRandomColor().toString()
|
||||
});
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
TextArea {
|
||||
id: customColors
|
||||
text: colorsList?.join(" ") || []
|
||||
Layout.preferredWidth: 300
|
||||
Layout.fillWidth: true
|
||||
wrapMode: TextEdit.WordWrap
|
||||
font.capitalization: Font.AllUppercase
|
||||
Kirigami.SpellCheck.enabled: false
|
||||
}
|
||||
Button {
|
||||
id: btn
|
||||
icon.name: "view-refresh-symbolic"
|
||||
onClicked: {
|
||||
colorsList = customColors.text.split(" ");
|
||||
colorsListModel.clear();
|
||||
initColorsListModel();
|
||||
updateColorsList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
// Simple double spinbox based on Qt example implementation
|
||||
SpinBox {
|
||||
editable: true
|
||||
wheelEnabled: true
|
||||
|
||||
property int decimals: 2
|
||||
property int multiplier: Math.pow(10, decimals)
|
||||
|
||||
validator: DoubleValidator {
|
||||
bottom: Math.min(from, to)
|
||||
top: Math.max(from, to)
|
||||
}
|
||||
|
||||
textFromValue: function (value, locale) {
|
||||
return Number(value / multiplier).toLocaleString(locale, 'f', decimals);
|
||||
}
|
||||
|
||||
valueFromText: function (text, locale) {
|
||||
return Number.fromLocaleString(locale, text) * multiplier;
|
||||
}
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
property list<real> values
|
||||
property int fromFreq
|
||||
property int toFreq
|
||||
readonly property real freqStep: Math.abs(toFreq - fromFreq) / values.length
|
||||
signal valueChanged(index: int, newValue: real)
|
||||
signal bandAdded
|
||||
signal bandRemoved
|
||||
signal flat
|
||||
|
||||
function formatFreq(freq) {
|
||||
let formatted = "";
|
||||
if (freq > 1000) {
|
||||
freq = freq / 1000;
|
||||
formatted = `${Math.round((freq * 10)) / 10} kHz`;
|
||||
} else {
|
||||
formatted = `${freq} Hz`;
|
||||
}
|
||||
return formatted;
|
||||
}
|
||||
|
||||
TextMetrics {
|
||||
id: labelWidth
|
||||
text: "99.9 kHz"
|
||||
font.features: {
|
||||
"tnum": 1
|
||||
}
|
||||
font.pointSize: Kirigami.Theme.smallFont.pointSize
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
id: sv
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.maximumWidth: parent.width
|
||||
RowLayout {
|
||||
// HACK: silence binding loop warnings.
|
||||
// contentWidth seems to be causing the binding loop,
|
||||
// but contentWidth is read-only and we have no control
|
||||
// over how it is calculated.
|
||||
implicitWidth: 0
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
spacing: Kirigami.Units.mediumSpacing
|
||||
Repeater {
|
||||
model: root.values
|
||||
ColumnLayout {
|
||||
id: col
|
||||
required property int index
|
||||
required property var modelData
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
Layout.preferredWidth: labelWidth.width
|
||||
Label {
|
||||
text: col.index + 1
|
||||
font.features: {
|
||||
"tnum": 1
|
||||
}
|
||||
font.pointSize: Kirigami.Theme.smallFont.pointSize
|
||||
opacity: 0.75
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
Label {
|
||||
text: root.formatFreq(Math.round((col.index + 1) * root.freqStep))
|
||||
font.features: {
|
||||
"tnum": 1
|
||||
}
|
||||
font.pointSize: Kirigami.Theme.smallFont.pointSize
|
||||
opacity: 0.75
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
Slider {
|
||||
id: slider
|
||||
orientation: Qt.Vertical
|
||||
from: 0
|
||||
to: 5
|
||||
stepSize: 0.1
|
||||
onValueChanged: {
|
||||
root.valueChanged(col.index, value);
|
||||
}
|
||||
value: col.modelData
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredHeight: 250
|
||||
}
|
||||
Label {
|
||||
text: parseFloat(slider.value).toFixed(1)
|
||||
font.features: {
|
||||
"tnum": 1
|
||||
}
|
||||
font.pointSize: Kirigami.Theme.smallFont.pointSize
|
||||
opacity: 0.75
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Button {
|
||||
enabled: root.values.length >= 3
|
||||
icon.name: "edit-clear"
|
||||
autoRepeat: true
|
||||
onClicked: {
|
||||
root.bandRemoved();
|
||||
}
|
||||
text: i18n("Remove band")
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.name: "list-add-symbolic"
|
||||
text: i18n("Add band")
|
||||
autoRepeat: true
|
||||
onClicked: {
|
||||
root.bandAdded();
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.name: "gnumeric-object-line-symbolic"
|
||||
onClicked: {
|
||||
root.flat();
|
||||
}
|
||||
text: i18n("Flat response")
|
||||
}
|
||||
}
|
||||
}
|
||||
+765
@@ -0,0 +1,765 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Dialogs
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.plasma.plasmoid
|
||||
import "../"
|
||||
import "../code/enum.js" as Enum
|
||||
import "../code/utils.js" as Utils
|
||||
|
||||
Kirigami.FormLayout {
|
||||
id: root
|
||||
|
||||
// required to align with parent form
|
||||
property alias formLayout: root
|
||||
property bool isSection: true
|
||||
property string sectionName
|
||||
// wether read from the string or existing config object
|
||||
property bool handleString
|
||||
// internal config objects to be sent, both string and json
|
||||
property string configString: "{}"
|
||||
property var config: handleString ? JSON.parse(configString) : undefined
|
||||
// to hide options that make no sense
|
||||
property var followOptions: {
|
||||
"panel": false,
|
||||
"widget": false,
|
||||
"tray": false
|
||||
}
|
||||
property bool showFollowPanel: followOptions.panel
|
||||
property bool showFollowWidget: followOptions.widget
|
||||
property bool showFollowTray: followOptions.tray
|
||||
property bool showFollowRadio: showFollowPanel || showFollowWidget || showFollowTray
|
||||
// wether or not show these options
|
||||
property bool multiColor: true
|
||||
property bool supportsGradient: false
|
||||
property bool supportsImage: false
|
||||
|
||||
signal updateConfigString(string configString, var config)
|
||||
|
||||
function updateConfig() {
|
||||
updateConfigString(configString, config);
|
||||
}
|
||||
|
||||
twinFormLayouts: parentLayout
|
||||
Layout.fillWidth: true
|
||||
|
||||
property var logger: Logger.create(Plasmoid.configuration.debugMode ? LoggingCategory.Debug : LoggingCategory.Info)
|
||||
|
||||
ListModel {
|
||||
id: themeColorSetModel
|
||||
|
||||
ListElement {
|
||||
value: "View"
|
||||
displayName: "View"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "Window"
|
||||
displayName: "Window"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "Button"
|
||||
displayName: "Button"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "Selection"
|
||||
displayName: "Selection"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "Tooltip"
|
||||
displayName: "Tooltip"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "Complementary"
|
||||
displayName: "Complementary"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "Header"
|
||||
displayName: "Header"
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: themeColorModel
|
||||
|
||||
ListElement {
|
||||
value: "textColor"
|
||||
displayName: "Text Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "disabledTextColor"
|
||||
displayName: "Disabled Text Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "highlightedTextColor"
|
||||
displayName: "Highlighted Text Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "activeTextColor"
|
||||
displayName: "Active Text Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "linkColor"
|
||||
displayName: "Link Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "visitedLinkColor"
|
||||
displayName: "Visited LinkColor"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "negativeTextColor"
|
||||
displayName: "Negative Text Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "neutralTextColor"
|
||||
displayName: "Neutral Text Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "positiveTextColor"
|
||||
displayName: "Positive Text Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "backgroundColor"
|
||||
displayName: "Background Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "highlightColor"
|
||||
displayName: "Highlight Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "activeBackgroundColor"
|
||||
displayName: "Active Background Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "linkBackgroundColor"
|
||||
displayName: "Link Background Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "visitedLinkBackgroundColor"
|
||||
displayName: "Visited Link Background Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "negativeBackgroundColor"
|
||||
displayName: "Negative Background Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "neutralBackgroundColor"
|
||||
displayName: "Neutral Background Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "positiveBackgroundColor"
|
||||
displayName: "Positive Background Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "alternateBackgroundColor"
|
||||
displayName: "Alternate Background Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "focusColor"
|
||||
displayName: "Focus Color"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
value: "hoverColor"
|
||||
displayName: "Hover Color"
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Kirigami.FormData.isSection: root.isSection
|
||||
Kirigami.FormData.label: root.sectionName || i18n("Color")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: animationCheckbox
|
||||
|
||||
Kirigami.FormData.label: i18n("Animation:")
|
||||
checked: root.config.animation.enabled
|
||||
onCheckedChanged: {
|
||||
root.config.animation.enabled = checked;
|
||||
root.updateConfig();
|
||||
// ensure valid option is checked as single and accent are
|
||||
// disabled in animated mode
|
||||
if (checked && (root.config.sourceType <= 1 || root.config.sourceType >= 4))
|
||||
listColorRadio.checked = true;
|
||||
}
|
||||
visible: false
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
id: animationInterval
|
||||
|
||||
Kirigami.FormData.label: i18n("Interval (ms):")
|
||||
from: 0
|
||||
to: 30000
|
||||
stepSize: 100
|
||||
value: root.config.animation.interval
|
||||
onValueModified: {
|
||||
root.config.animation.interval = value;
|
||||
root.updateConfig();
|
||||
}
|
||||
enabled: animationCheckbox.checked
|
||||
visible: false
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
id: animationTransition
|
||||
|
||||
Kirigami.FormData.label: i18n("Smoothing (ms):")
|
||||
from: 0
|
||||
to: animationInterval.value
|
||||
stepSize: 100
|
||||
value: root.config.animation.smoothing
|
||||
onValueModified: {
|
||||
root.config.animation.smoothing = value;
|
||||
root.updateConfig();
|
||||
}
|
||||
enabled: animationCheckbox.checked
|
||||
visible: false
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Color source:")
|
||||
RadioButton {
|
||||
id: singleColorRadio
|
||||
|
||||
property int index: 0
|
||||
|
||||
text: i18n("Custom")
|
||||
ButtonGroup.group: colorModeGroup
|
||||
checked: root.config.sourceType === index
|
||||
enabled: !animationCheckbox.checked
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("A fixed custom color")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
RadioButton {
|
||||
id: accentColorRadio
|
||||
|
||||
property int index: 1
|
||||
|
||||
text: i18n("System")
|
||||
ButtonGroup.group: colorModeGroup
|
||||
checked: root.config.sourceType === index
|
||||
enabled: !animationCheckbox.checked
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Color that updates with your System theme")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: root.multiColor
|
||||
RadioButton {
|
||||
id: listColorRadio
|
||||
|
||||
property int index: 2
|
||||
|
||||
text: i18n("Custom list")
|
||||
ButtonGroup.group: colorModeGroup
|
||||
checked: root.config.sourceType === index
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Define a list of colors that will be applied to all the elements, wraps around if there are more elements than colors")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
RadioButton {
|
||||
id: randomColorRadio
|
||||
|
||||
property int index: 3
|
||||
|
||||
text: i18n("Random")
|
||||
ButtonGroup.group: colorModeGroup
|
||||
checked: root.config.sourceType === index
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Random color for each element")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: root.showFollowRadio
|
||||
RadioButton {
|
||||
id: followColorRadio
|
||||
|
||||
property int index: 4
|
||||
|
||||
text: i18n("Follow")
|
||||
ButtonGroup.group: colorModeGroup
|
||||
checked: root.config.sourceType === index
|
||||
enabled: !animationCheckbox.checked
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Follow the color of a parent element")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: root.supportsGradient
|
||||
RadioButton {
|
||||
id: gradientRadio
|
||||
property int index: 5
|
||||
text: i18n("Gradient")
|
||||
ButtonGroup.group: colorModeGroup
|
||||
checked: root.config.sourceType === index
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Horizontal or vertical customizable color gradient")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: root.supportsImage
|
||||
RadioButton {
|
||||
id: imageRadio
|
||||
property int index: 6
|
||||
text: i18n("Image")
|
||||
ButtonGroup.group: colorModeGroup
|
||||
checked: root.config.sourceType === index
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("High resolution images can slow down the desktop when the panel or widget size changes!")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
RadioButton {
|
||||
id: hueRadio
|
||||
property int index: 7
|
||||
text: i18n("Hue")
|
||||
ButtonGroup.group: colorModeGroup
|
||||
checked: root.config.sourceType === index
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Automatically shifted color for each bar")
|
||||
}
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
id: colorModeGroup
|
||||
|
||||
onCheckedButtonChanged: {
|
||||
if (checkedButton) {
|
||||
root.config.sourceType = checkedButton.index;
|
||||
root.updateConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
// >
|
||||
|
||||
RadioButton {
|
||||
id: followPanelBgRadio
|
||||
|
||||
property int index: 0
|
||||
|
||||
Kirigami.FormData.label: i18n("Element:")
|
||||
text: i18n("Panel background")
|
||||
ButtonGroup.group: followColorGroup
|
||||
checked: root.config.followColor === index
|
||||
visible: followColorRadio.checked && root.showFollowPanel
|
||||
}
|
||||
|
||||
RadioButton {
|
||||
id: followWidgetBgRadio
|
||||
|
||||
property int index: 1
|
||||
|
||||
text: i18n("Widget background")
|
||||
ButtonGroup.group: followColorGroup
|
||||
checked: root.config.followColor === index
|
||||
visible: followColorRadio.checked && root.showFollowWidget
|
||||
}
|
||||
|
||||
RadioButton {
|
||||
id: followTrayWidgetBgRadio
|
||||
|
||||
property int index: 2
|
||||
|
||||
text: i18n("Tray widget background")
|
||||
ButtonGroup.group: followColorGroup
|
||||
checked: root.config.followColor === index
|
||||
visible: followColorRadio.checked && root.showFollowTray
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
id: followColorGroup
|
||||
|
||||
onCheckedButtonChanged: {
|
||||
if (checkedButton) {
|
||||
root.config.followColor = checkedButton.index;
|
||||
root.updateConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: imageFillMode
|
||||
Kirigami.FormData.label: i18n("Positioning:")
|
||||
visible: root.supportsImage && imageRadio.checked
|
||||
model: [
|
||||
{
|
||||
'label': i18n("Stretch"),
|
||||
'fillMode': AnimatedImage.Stretch
|
||||
},
|
||||
{
|
||||
'label': i18n("Tile"),
|
||||
'fillMode': AnimatedImage.Tile
|
||||
},
|
||||
{
|
||||
'label': i18n("Scaled and Cropped"),
|
||||
'fillMode': AnimatedImage.PreserveAspectCrop
|
||||
}
|
||||
]
|
||||
textRole: "label"
|
||||
valueRole: "fillMode"
|
||||
onActivated: {
|
||||
root.config.image.fillMode = currentValue;
|
||||
root.updateConfig();
|
||||
}
|
||||
currentIndex: indexOfValue(root.config.image.fillMode)
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: root.supportsImage && imageRadio.checked
|
||||
Kirigami.FormData.label: i18n("Image:")
|
||||
TextField {
|
||||
id: imgTextArea
|
||||
Layout.preferredWidth: 300
|
||||
text: root.config.image.source
|
||||
onTextChanged: {
|
||||
if (root.config.image.source !== text) {
|
||||
root.config.image.source = text;
|
||||
root.updateConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
Button {
|
||||
icon.name: "insert-image-symbolic"
|
||||
onClicked: fileDialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
FileDialog {
|
||||
id: fileDialog
|
||||
fileMode: FileDialog.OpenFile
|
||||
title: i18n("Pick a image file")
|
||||
nameFilters: [i18n("Image files") + " (*.png *.jpg *.jpeg *.gif *.webp *.bmp *.svg)", i18n("All files") + " (*)"]
|
||||
onAccepted: {
|
||||
if (fileDialog.selectedFile) {
|
||||
logger.debug(fileDialog.selectedFile);
|
||||
imgTextArea.text = fileDialog.selectedFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColorButton {
|
||||
id: customColorBtn
|
||||
Kirigami.FormData.label: i18n("Color:")
|
||||
color: root.config.custom
|
||||
visible: singleColorRadio.checked
|
||||
onAccepted: color => {
|
||||
root.config.custom = color.toString();
|
||||
root.updateConfig();
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: colorSetCombobx
|
||||
|
||||
Kirigami.FormData.label: i18n("Color set:")
|
||||
model: themeColorSetModel
|
||||
textRole: "displayName"
|
||||
visible: accentColorRadio.checked
|
||||
onCurrentIndexChanged: {
|
||||
root.config.systemColorSet = themeColorSetModel.get(currentIndex).value;
|
||||
root.updateConfig();
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: colorSetCombobx
|
||||
property: "currentIndex"
|
||||
value: {
|
||||
for (var i = 0; i < themeColorSetModel.count; i++) {
|
||||
if (themeColorSetModel.get(i).value === root.config.systemColorSet)
|
||||
return i;
|
||||
}
|
||||
return 0; // Default to the first item if no match is found
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: colorThemeCombobx
|
||||
|
||||
Kirigami.FormData.label: i18n("Color:")
|
||||
model: themeColorModel
|
||||
textRole: "displayName"
|
||||
visible: accentColorRadio.checked
|
||||
onCurrentIndexChanged: {
|
||||
root.config.systemColor = themeColorModel.get(currentIndex).value;
|
||||
root.updateConfig();
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: colorThemeCombobx
|
||||
property: "currentIndex"
|
||||
value: {
|
||||
for (var i = 0; i < themeColorModel.count; i++) {
|
||||
if (themeColorModel.get(i).value === root.config.systemColor)
|
||||
return i;
|
||||
}
|
||||
return 0; // Default to the first item if no match is found
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
visible: root.multiColor && listColorRadio.checked
|
||||
Kirigami.FormData.label: i18n("Colors:")
|
||||
|
||||
Loader {
|
||||
asynchronous: true
|
||||
sourceComponent: listColorRadio.checked ? pickerList : null
|
||||
onLoaded: {
|
||||
item.colorsList = root.config.list;
|
||||
item.onColorsChanged.connect(colorsList => {
|
||||
root.config.list = colorsList;
|
||||
root.updateConfig();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: pickerList
|
||||
|
||||
ColorPickerList {}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
visible: root.config.sourceType === Enum.ColorSourceType.Hue
|
||||
Kirigami.FormData.label: i18n("Range:")
|
||||
Kirigami.FormData.buddyFor: hue
|
||||
RowLayout {
|
||||
id: hue
|
||||
SpinBox {
|
||||
id: hueStart
|
||||
from: 0
|
||||
to: 360
|
||||
stepSize: 1
|
||||
onValueModified: {
|
||||
if (value >= hueEnd.value - 1) {
|
||||
value = hueEnd.value - 1;
|
||||
}
|
||||
root.config.hueStart = value;
|
||||
root.updateConfig();
|
||||
}
|
||||
Component.onCompleted: value = root.config.hueStart
|
||||
}
|
||||
Label {
|
||||
text: "-"
|
||||
}
|
||||
SpinBox {
|
||||
id: hueEnd
|
||||
from: 0
|
||||
to: 360
|
||||
stepSize: 1
|
||||
onValueModified: {
|
||||
if (value <= hueStart.value + 1) {
|
||||
value = hueStart.value + 1;
|
||||
}
|
||||
root.config.hueEnd = value;
|
||||
root.updateConfig();
|
||||
}
|
||||
Component.onCompleted: value = root.config.hueEnd
|
||||
}
|
||||
}
|
||||
Canvas {
|
||||
id: canvas
|
||||
property list<color> colors: {
|
||||
let colors = [];
|
||||
const start = hueStart.value / 360;
|
||||
const end = hueEnd.value / 360;
|
||||
for (let i = 0; i < canvas.width; i++) {
|
||||
let c = Qt.hsla(start + ((i / canvas.width) * (end - start)), 0.8, 0.7, 1.0);
|
||||
colors.push(c);
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
property var gradient: {
|
||||
if (canvas.available) {
|
||||
return Utils.buildCanvasGradient(getContext("2d"), true, colors, 0, height, width);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 8
|
||||
onColorsChanged: canvas.requestPaint()
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RadioButton {
|
||||
id: gradientHorizontalRadio
|
||||
Kirigami.FormData.label: i18n("Orientation:")
|
||||
property int index: 0
|
||||
text: i18n("Horizontal")
|
||||
ButtonGroup.group: gradientOrientationBtnGroup
|
||||
checked: root.config.colorsOrientation === index
|
||||
visible: root.config.sourceType > 1
|
||||
}
|
||||
|
||||
RadioButton {
|
||||
id: gradientVerticalRadio
|
||||
property int index: 1
|
||||
text: i18n("Vertical")
|
||||
ButtonGroup.group: gradientOrientationBtnGroup
|
||||
checked: root.config.colorsOrientation === index
|
||||
visible: root.config.sourceType > 1
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
id: gradientOrientationBtnGroup
|
||||
|
||||
onCheckedButtonChanged: {
|
||||
if (checkedButton) {
|
||||
root.config.colorsOrientation = checkedButton.index;
|
||||
root.updateConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
Kirigami.FormData.label: i18n("Gradient:")
|
||||
checked: root.config.smoothGradient
|
||||
onCheckedChanged: {
|
||||
root.config.smoothGradient = checked;
|
||||
root.updateConfig();
|
||||
}
|
||||
visible: root.config.sourceType > 1
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Reverse:")
|
||||
CheckBox {
|
||||
checked: root.config.reverseList
|
||||
onCheckedChanged: {
|
||||
root.config.reverseList = checked;
|
||||
root.updateConfig();
|
||||
}
|
||||
visible: root.config.sourceType > 1
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Display colors the other way around")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Alpha:")
|
||||
visible: colorModeGroup.checkedButton.index !== 6
|
||||
|
||||
DoubleSpinBox {
|
||||
id: alphaSpinbox
|
||||
from: 0 * multiplier
|
||||
to: 1 * multiplier
|
||||
value: (root.config.alpha ?? 0) * multiplier
|
||||
onValueModified: {
|
||||
root.config.alpha = value / alphaSpinbox.multiplier;
|
||||
root.updateConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
Kirigami.FormData.isSection: false
|
||||
Kirigami.FormData.label: i18n("Contrast Correction")
|
||||
Layout.fillWidth: true
|
||||
visible: colorModeGroup.checkedButton.index !== 6
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Saturation:")
|
||||
visible: colorModeGroup.checkedButton.index !== 6
|
||||
|
||||
CheckBox {
|
||||
id: saturationEnabled
|
||||
|
||||
checked: root.config.saturationEnabled
|
||||
onCheckedChanged: {
|
||||
root.config.saturationEnabled = checked;
|
||||
root.updateConfig();
|
||||
}
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
id: saturationSpinbox
|
||||
from: 0 * multiplier
|
||||
to: 1 * multiplier
|
||||
value: (root.config.saturation ?? 0) * multiplier
|
||||
onValueModified: {
|
||||
root.config.saturation = value / saturationSpinbox.multiplier;
|
||||
root.updateConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Lightness:")
|
||||
visible: colorModeGroup.checkedButton.index !== 6
|
||||
|
||||
CheckBox {
|
||||
id: lightnessEnabled
|
||||
|
||||
checked: root.config.lightnessEnabled
|
||||
onCheckedChanged: {
|
||||
root.config.lightnessEnabled = checked;
|
||||
root.updateConfig();
|
||||
}
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
id: lightnessSpinbox
|
||||
from: 0 * multiplier
|
||||
to: 1 * multiplier
|
||||
value: (root.config.lightness ?? 0) * multiplier
|
||||
onValueModified: {
|
||||
root.config.lightness = value / lightnessSpinbox.multiplier;
|
||||
root.updateConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property list<string> names
|
||||
RunCommand {
|
||||
id: process
|
||||
onExited: (cmd, exitCode, exitStatus, stdout, stderr) => {
|
||||
if (exitCode !== 0) {
|
||||
return;
|
||||
}
|
||||
if (stdout) {
|
||||
let output = stdout.trim().split('\n');
|
||||
output = output.map(l => l.split(/\t+/)[1]);
|
||||
output.unshift("auto");
|
||||
root.names = output;
|
||||
}
|
||||
}
|
||||
}
|
||||
Component.onCompleted: process.run("pactl list sources short && pactl list sinks short")
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
import QtQuick
|
||||
import org.kde.plasma.plasmoid
|
||||
import "../"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string command: ""
|
||||
readonly property string stdout: process.stdout ?? ""
|
||||
readonly property string stderr: process.stderr ?? ""
|
||||
readonly property bool forceFallback: false
|
||||
readonly property bool running: process.running ?? false
|
||||
property bool usingFallback: false
|
||||
property var process: null
|
||||
property bool loadingFailed: false
|
||||
property list<string> loadingErrors
|
||||
|
||||
function restart() {
|
||||
if (process !== null) {
|
||||
process.restart();
|
||||
}
|
||||
}
|
||||
|
||||
function start() {
|
||||
if (process !== null) {
|
||||
process.start();
|
||||
}
|
||||
}
|
||||
|
||||
function stop() {
|
||||
if (process !== null) {
|
||||
process.stop();
|
||||
}
|
||||
}
|
||||
|
||||
onCommandChanged: {
|
||||
if (process !== null) {
|
||||
process.command = root.command;
|
||||
}
|
||||
}
|
||||
|
||||
property var logger: Logger.create(Plasmoid.configuration.debugMode ? LoggingCategory.Debug : LoggingCategory.Info)
|
||||
|
||||
Component.onCompleted: {
|
||||
let component = null;
|
||||
const sources = ["ProcessMonitorFallback.qml"];
|
||||
if (!root.forceFallback) {
|
||||
sources.unshift("ProcessMonitorPrimary.qml");
|
||||
}
|
||||
for (let source of sources) {
|
||||
logger.debug("Trying to load", source);
|
||||
component = Qt.createComponent(source);
|
||||
if (component.status === Component.Ready) {
|
||||
process = component.createObject(root);
|
||||
process.command = root.command;
|
||||
break;
|
||||
} else {
|
||||
logger.warn(component.errorString());
|
||||
root.loadingErrors.push(component.errorString());
|
||||
}
|
||||
}
|
||||
|
||||
if (process === null) {
|
||||
root.loadingFailed = true;
|
||||
}
|
||||
root.usingFallback = component.url.toString().includes("ProcessMonitorFallback.qml");
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
import QtQuick
|
||||
import QtWebSockets
|
||||
import "../code/utils.js" as Utils
|
||||
import org.kde.plasma.plasmoid
|
||||
import "../"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property string command: ""
|
||||
property string stdout: ""
|
||||
property string stderr: ""
|
||||
property bool running: stdout !== ""
|
||||
property string pid: ""
|
||||
property bool isReady: false
|
||||
property bool pendingRestart: false
|
||||
|
||||
readonly property string toolsDir: Qt.resolvedUrl("../tools").toString().substring(7) + "/"
|
||||
readonly property string commandMonitorTool: "'" + toolsDir + "commandMonitor'"
|
||||
readonly property string monitorCommand: `${commandMonitorTool} ${server.url} "${command}"`
|
||||
|
||||
property var logger: Logger.create(Plasmoid.configuration.debugMode ? LoggingCategory.Debug : LoggingCategory.Info)
|
||||
|
||||
// run command
|
||||
RunCommand {
|
||||
id: runCommand
|
||||
onExited: (cmd, exitCode, exitStatus, stdout, stderr) => {
|
||||
if (exitCode !== 0) {
|
||||
root.logger.error(`ProcessMonitorFallback cmd: ${cmd}, exitCode: ${exitCode}, exitStatus: ${exitStatus}, stdout: ${stdout}, stderr: ${stderr}`);
|
||||
root.stderr = stderr;
|
||||
} else {
|
||||
root.logger.debug(`cmd: ${cmd}, exitCode: ${exitCode}, exitStatus: ${exitStatus}, stdout: ${stdout}, stderr: ${stderr}`);
|
||||
}
|
||||
root.stdout = "";
|
||||
root.pid = "";
|
||||
}
|
||||
}
|
||||
|
||||
// get live output lines
|
||||
WebSocketServer {
|
||||
id: server
|
||||
listen: true
|
||||
onUrlChanged: url => {
|
||||
root.logger.debug("started websocket server:", url);
|
||||
}
|
||||
onClientConnected: webSocket => {
|
||||
webSocket.onTextMessageReceived.connect(function (message) {
|
||||
if (message) {
|
||||
if (message.includes("ERROR:")) {
|
||||
logger.error(message);
|
||||
root.stderr = message;
|
||||
root.stdout = "";
|
||||
root.pid = "";
|
||||
return;
|
||||
}
|
||||
if (message.includes("PID:")) {
|
||||
root.pid = message.trim().split(" ")[1];
|
||||
logger.debug(`started ${root.monitorCommand} with pid:`, root.pid);
|
||||
root.stderr = "";
|
||||
root.pendingRestart = false;
|
||||
return;
|
||||
}
|
||||
root.stdout = message.trim().replace(/"/g, "");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function start() {
|
||||
logger.debug("ProcessMonitorFallback.start()");
|
||||
pendingRestart = true;
|
||||
Utils.delay(100, () => {
|
||||
isReady = true;
|
||||
runCommand.run(root.monitorCommand);
|
||||
}, root);
|
||||
}
|
||||
|
||||
function stop() {
|
||||
logger.debug("ProcessMonitorFallback.stop()");
|
||||
if (pid) {
|
||||
runCommand.run(`kill -TERM ${pid}`);
|
||||
}
|
||||
}
|
||||
|
||||
function restart() {
|
||||
if (pendingRestart)
|
||||
return;
|
||||
logger.debug("ProcessMonitorFallback.restart()");
|
||||
stop();
|
||||
start();
|
||||
}
|
||||
|
||||
onCommandChanged: {
|
||||
if (command == "")
|
||||
return;
|
||||
logger.debug("ProcessMonitorFallback.onCommandChanged:", command);
|
||||
restart();
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import QtQuick
|
||||
import com.github.luisbocanegra.audiovisualizer.process
|
||||
import org.kde.plasma.plasmoid
|
||||
import "../"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property string command: ""
|
||||
readonly property string stdout: process.stdout
|
||||
readonly property string stderr: process.stderr
|
||||
readonly property bool running: process.running
|
||||
property var logger: Logger.create(Plasmoid.configuration.debugMode ? LoggingCategory.Debug : LoggingCategory.Info)
|
||||
|
||||
function restart() {
|
||||
logger.debug("ProcessMonitorPrimary.restart()");
|
||||
process.restart();
|
||||
}
|
||||
// the plugin keeps a single process so no special handling is needed here
|
||||
// this function is here just to match the signature of the fallback
|
||||
function start() {
|
||||
logger.debug("ProcessMonitorPrimary.start()");
|
||||
restart();
|
||||
}
|
||||
function stop() {
|
||||
logger.debug("ProcessMonitorPrimary.stop()");
|
||||
process.stop();
|
||||
}
|
||||
Process {
|
||||
id: process
|
||||
}
|
||||
|
||||
onCommandChanged: {
|
||||
if (command == "")
|
||||
return;
|
||||
process.command = ["sh", "-c", `${command}`];
|
||||
logger.debug("ProcessMonitorPrimary.onCommandChanged:", command);
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
import QtQuick
|
||||
import org.kde.plasma.plasma5support as P5Support
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string output: ""
|
||||
|
||||
signal exited(string cmd, int exitCode, int exitStatus, string stdout, string stderr)
|
||||
|
||||
function onExited(cmd, exitCode, exitStatus, stdout, stderr) {
|
||||
if (exitCode !== 0)
|
||||
return;
|
||||
|
||||
if (stdout.length > 0) {
|
||||
output = stdout.trim()
|
||||
}
|
||||
}
|
||||
|
||||
function run(cmd) {
|
||||
runCommand.exec(cmd);
|
||||
}
|
||||
|
||||
function terminate(cmd) {
|
||||
runCommand.exit(cmd);
|
||||
}
|
||||
|
||||
P5Support.DataSource {
|
||||
id: runCommand
|
||||
|
||||
function exec(cmd) {
|
||||
runCommand.connectSource(cmd);
|
||||
}
|
||||
|
||||
function exit(cmd) {
|
||||
runCommand.disconnectSource(cmd);
|
||||
}
|
||||
|
||||
engine: "executable"
|
||||
connectedSources: []
|
||||
onNewData: function (source, data) {
|
||||
var exitCode = data["exit code"];
|
||||
var exitStatus = data["exit status"];
|
||||
var stdout = data["stdout"];
|
||||
var stderr = data["stderr"];
|
||||
root.exited(source, exitCode, exitStatus, stdout, stderr);
|
||||
disconnectSource(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.components as PlasmaComponents
|
||||
import org.kde.plasma.extras as PlasmaExtras
|
||||
import org.kde.plasma.plasmoid
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
Item {
|
||||
|
||||
property int preferredTextWidth: Kirigami.Units.gridUnit * 20
|
||||
|
||||
implicitWidth: mainLayout.implicitWidth + Kirigami.Units.gridUnit
|
||||
implicitHeight: mainLayout.implicitHeight + Kirigami.Units.gridUnit
|
||||
|
||||
ColumnLayout {
|
||||
id: mainLayout
|
||||
|
||||
anchors {
|
||||
centerIn: parent
|
||||
}
|
||||
spacing: 0
|
||||
|
||||
PlasmaExtras.Heading {
|
||||
id: label
|
||||
Layout.fillWidth: true
|
||||
level: 3
|
||||
text: Plasmoid.metaData.name
|
||||
}
|
||||
|
||||
Label {
|
||||
text: Plasmoid.metaData.description
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Label.Wrap
|
||||
}
|
||||
}
|
||||
}
|
||||
+226
@@ -0,0 +1,226 @@
|
||||
import QtQuick
|
||||
import QtQuick.Shapes
|
||||
import QtQuick.Controls
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.plasmoid
|
||||
import "../code/utils.js" as Utils
|
||||
import "../code/enum.js" as Enum
|
||||
import "../code/drawCanvas.js" as DrawCanvas
|
||||
|
||||
Item {
|
||||
id: root
|
||||
required property int visualizerStyle
|
||||
required property bool circleMode
|
||||
required property real circleModeSize
|
||||
required property int barWidth
|
||||
required property int blockHeight
|
||||
required property int blockSpacing
|
||||
required property int barGap
|
||||
required property bool centeredBars
|
||||
required property bool roundedBars
|
||||
required property bool fillWave
|
||||
required property var barColorsCfg
|
||||
required property var waveFillColorsCfg
|
||||
required property var inactiveBlockColorsCfg
|
||||
required property bool drawInactiveBlocks
|
||||
required property bool fixVertical
|
||||
property list<int> values
|
||||
property bool debugMode: false
|
||||
|
||||
Rectangle {
|
||||
id: kirigamiColorItem
|
||||
opacity: 0
|
||||
height: 1
|
||||
width: height
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme[root.barColorsCfg.systemColorSet]
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: kirigamiColorItem2
|
||||
opacity: 0
|
||||
height: 1
|
||||
width: height
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme[root.waveFillColorsCfg.systemColorSet]
|
||||
}
|
||||
Rectangle {
|
||||
color: Kirigami.Theme.highlightColor
|
||||
opacity: 0.2
|
||||
visible: root.debugMode
|
||||
width: canvas.width
|
||||
height: canvas.height
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Canvas {
|
||||
id: canvas
|
||||
anchors.centerIn: parent
|
||||
// renderStrategy: Canvas.Threaded
|
||||
property int visualizerStyle: root.visualizerStyle
|
||||
property bool circleMode: root.circleMode
|
||||
property real circleModeSize: root.circleModeSize
|
||||
property int barWidth: root.barWidth
|
||||
property int blockHeight: root.blockHeight
|
||||
property int blockSpacing: root.blockSpacing
|
||||
property int spacing: {
|
||||
if (visualizerStyle === Enum.VisualizerStyles.Wave) {
|
||||
return Math.max(1, root.barGap);
|
||||
}
|
||||
return root.barGap;
|
||||
}
|
||||
property int barCount: root.values.length
|
||||
property bool centeredBars: root.centeredBars
|
||||
property bool roundedBars: root.roundedBars
|
||||
property var values: {
|
||||
if (root.debugMode) {
|
||||
let copy = root.values.slice();
|
||||
copy[0] = height;
|
||||
return copy;
|
||||
}
|
||||
return root.values;
|
||||
}
|
||||
property bool fillWave: root.fillWave
|
||||
|
||||
property real radiusOffset: barWidth / 2
|
||||
property int gradientHeight: canvas.height
|
||||
property int gradientWidth: canvas.width
|
||||
|
||||
function updateGradients() {
|
||||
if (!canvas.available) {
|
||||
return;
|
||||
}
|
||||
canvas.requestPaint();
|
||||
}
|
||||
onHeightChanged: updateGradients()
|
||||
onWidthChanged: updateGradients()
|
||||
|
||||
property var barColorsCfg: root.barColorsCfg
|
||||
property list<color> colors: Utils.getColors(barColorsCfg, barCount, kirigamiColorItem.Kirigami.Theme[barColorsCfg.systemColor])
|
||||
property var gradient: {
|
||||
if (canvas.available) {
|
||||
return Utils.buildCanvasGradient(getContext("2d"), barColorsCfg.smoothGradient, colors, barColorsCfg.colorsOrientation, canvas.height, canvas.width, circleMode);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
property var waveFillColorsCfg: root.waveFillColorsCfg
|
||||
property list<color> waveFillColors: Utils.getColors(waveFillColorsCfg, barCount, kirigamiColorItem2.Kirigami.Theme[waveFillColorsCfg.systemColor])
|
||||
property var waveFillGradient: {
|
||||
if (canvas.available) {
|
||||
return Utils.buildCanvasGradient(getContext("2d"), waveFillColorsCfg.smoothGradient, waveFillColors, waveFillColorsCfg.colorsOrientation, canvas.height, canvas.width, circleMode);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
property var inactiveBlockColorsCfg: root.inactiveBlockColorsCfg
|
||||
property list<color> inactiveBlockColors: Utils.getColors(inactiveBlockColorsCfg, barCount, kirigamiColorItem.Kirigami.Theme[inactiveBlockColorsCfg.systemColor])
|
||||
property var inactiveBlockGradient: {
|
||||
if (canvas.available) {
|
||||
return Utils.buildCanvasGradient(getContext("2d"), inactiveBlockColorsCfg.smoothGradient, inactiveBlockColors, inactiveBlockColorsCfg.colorsOrientation, canvas.height, canvas.width, circleMode);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
property bool drawInactiveBlocks: root.drawInactiveBlocks
|
||||
|
||||
width: {
|
||||
if (visualizerStyle === Enum.VisualizerStyles.Wave) {
|
||||
return barWidth + ((barCount - 1) * spacing);
|
||||
}
|
||||
return barCount * barWidth + ((barCount - 1) * spacing);
|
||||
}
|
||||
height: parent.height
|
||||
property bool fixAlign: barWidth % 2 === 0 && centeredBars && visualizerStyle === Enum.VisualizerStyles.Wave && !root.fixVertical
|
||||
|
||||
onValuesChanged: canvas.requestPaint()
|
||||
|
||||
onPaint: {
|
||||
const ctx = getContext("2d");
|
||||
ctx.reset();
|
||||
if (fixAlign) {
|
||||
ctx.translate(0.0, 0.5);
|
||||
}
|
||||
if (root.fixVertical) {
|
||||
ctx.translate(0.0, -0.5);
|
||||
}
|
||||
if (gradient) {
|
||||
ctx.strokeStyle = gradient;
|
||||
ctx.fillStyle = gradient;
|
||||
}
|
||||
switch (visualizerStyle) {
|
||||
case Enum.VisualizerStyles.Bars:
|
||||
DrawCanvas.bars(ctx, canvas, circleMode);
|
||||
break;
|
||||
case Enum.VisualizerStyles.Wave:
|
||||
DrawCanvas.wave(ctx, canvas, circleMode);
|
||||
break;
|
||||
case Enum.VisualizerStyles.Blocks:
|
||||
DrawCanvas.blocks(ctx, canvas, circleMode);
|
||||
break;
|
||||
default:
|
||||
DrawCanvas.bars(ctx, canvas, circleMode);
|
||||
break;
|
||||
}
|
||||
if (fixAlign) {
|
||||
ctx.translate(0.0, -0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Shape {
|
||||
id: shape
|
||||
visible: root.debugMode
|
||||
width: canvas.width
|
||||
height: canvas.height
|
||||
anchors.centerIn: parent
|
||||
ShapePath {
|
||||
fillColor: "transparent"
|
||||
strokeWidth: 1
|
||||
strokeColor: "red"
|
||||
strokeStyle: ShapePath.DashLine
|
||||
dashPattern: [1, 8]
|
||||
startX: 0
|
||||
startY: shape.height
|
||||
PathLine {
|
||||
x: shape.width
|
||||
y: shape.height
|
||||
}
|
||||
PathLine {
|
||||
x: shape.width
|
||||
y: 0
|
||||
}
|
||||
PathLine {
|
||||
x: 0
|
||||
y: 0
|
||||
}
|
||||
PathLine {
|
||||
x: 0
|
||||
y: shape.height
|
||||
}
|
||||
}
|
||||
ShapePath {
|
||||
fillColor: "transparent"
|
||||
strokeWidth: 1
|
||||
strokeColor: "red"
|
||||
strokeStyle: ShapePath.DashLine
|
||||
dashPattern: [1, 8]
|
||||
startX: 0
|
||||
startY: shape.height / 2
|
||||
PathLine {
|
||||
x: shape.width
|
||||
y: shape.height / 2
|
||||
}
|
||||
}
|
||||
ShapePath {
|
||||
fillColor: "transparent"
|
||||
strokeWidth: 1
|
||||
strokeColor: "red"
|
||||
strokeStyle: ShapePath.DashLine
|
||||
dashPattern: [1, 8]
|
||||
startX: shape.width / 2
|
||||
startY: 0
|
||||
PathLine {
|
||||
x: shape.width / 2
|
||||
y: shape.height
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+540
@@ -0,0 +1,540 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.kcmutils as KCM
|
||||
import org.kde.plasma.plasmoid
|
||||
import "./components"
|
||||
|
||||
KCM.SimpleKCM {
|
||||
id: root
|
||||
// general
|
||||
property alias cfg_barCount: barCountSpinbox.value
|
||||
property alias cfg_framerate: framerateSpinbox.value
|
||||
property alias cfg_autoSensitivity: autoSensitivityCheckbox.checked
|
||||
property alias cfg_sensitivityEnabled: sensitivityEnabled.checked
|
||||
property alias cfg_sensitivity: sensitivitySpinbox.value
|
||||
property alias cfg_lowerCutoffFreq: lowerCutoffFreqSpinbox.value
|
||||
property alias cfg_higherCutoffFreq: higherCutoffFreqSpinbox.value
|
||||
property alias cfg_cavaSleepTimer: cavaSleepTimerSpinbox.value
|
||||
// smoothing
|
||||
property alias cfg_noiseReduction: noiseReductionSpinbox.value
|
||||
property alias cfg_monstercat: monstercatCheckbox.checked
|
||||
property alias cfg_waves: wavesCheckbox.checked
|
||||
// input
|
||||
property string cfg_inputMethod
|
||||
property alias cfg_inputSource: inputSourceField.text
|
||||
property alias cfg_sampleRate: sampleRateSpinbox.value
|
||||
property alias cfg_sampleBits: sampleBitsSpinbox.value
|
||||
property alias cfg_inputChannels: inputChannelsSpinbox.value
|
||||
property alias cfg_autoconnect: autoconnectSpinbox.value
|
||||
property alias cfg_active: activeCheckbox.checked
|
||||
property alias cfg_remix: remixCheckbox.checked
|
||||
property alias cfg_virtual: virtualCheckbox.checked
|
||||
// output
|
||||
property string cfg_outputChannels
|
||||
property string cfg_monoOption
|
||||
property alias cfg_reverse: reverseCheckbox.checked
|
||||
// eq
|
||||
property alias cfg_eqEnabled: eqEnabled.checked
|
||||
property var cfg_eq
|
||||
|
||||
property alias cfg_pauseOnFullScreenWindow: pauseOnFullScreenWindow.checked
|
||||
property alias cfg_pauseOnMaximizedWindow: pauseOnMaximizedWindow.checked
|
||||
|
||||
PactlList {
|
||||
id: pactl
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Kirigami.FormLayout {
|
||||
id: parentLayout
|
||||
Layout.fillWidth: true
|
||||
|
||||
Kirigami.Separator {
|
||||
Kirigami.FormData.isSection: true
|
||||
Kirigami.FormData.label: i18n("General")
|
||||
}
|
||||
|
||||
Button {
|
||||
id: stopCavaButton
|
||||
text: Plasmoid.configuration._stopCava ? i18n("Start CAVA") : i18n("Stop CAVA")
|
||||
onClicked: {
|
||||
Plasmoid.configuration._stopCava = !Plasmoid.configuration._stopCava;
|
||||
Plasmoid.configuration.writeConfig();
|
||||
}
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
id: framerateSpinbox
|
||||
Kirigami.FormData.label: i18n("Framerate:")
|
||||
from: 1
|
||||
to: 144
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: barsRow
|
||||
Kirigami.FormData.buddyFor: barCountSpinbox
|
||||
Kirigami.FormData.label: i18n("Number of bars:")
|
||||
SpinBox {
|
||||
id: barCountSpinbox
|
||||
enabled: false //TODO enable when we have a visualization style that can use it
|
||||
from: 1
|
||||
to: 512
|
||||
Layout.alignment: Qt.AlignTop
|
||||
}
|
||||
Label {
|
||||
visible: !barCountSpinbox.enabled
|
||||
text: i18n("Automatically calculated for the current visualizer style.")
|
||||
font: Kirigami.Theme.smallFont
|
||||
Layout.maximumWidth: 200
|
||||
wrapMode: Label.Wrap
|
||||
enabled: false
|
||||
Layout.alignment: Qt.AlignTop
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Automatic sensitivity:")
|
||||
CheckBox {
|
||||
id: autoSensitivityCheckbox
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Attempt to decrease sensitivity if the bars peak.")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Sensitivity:")
|
||||
CheckBox {
|
||||
id: sensitivityEnabled
|
||||
}
|
||||
SpinBox {
|
||||
id: sensitivitySpinbox
|
||||
from: 1
|
||||
to: 999
|
||||
enabled: sensitivityEnabled.checked
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Manual sensitivity in %.\nIf autosens is enabled, this will only be the initial value")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Frequency range (Hz):")
|
||||
|
||||
Label {
|
||||
text: i18n("Min")
|
||||
}
|
||||
SpinBox {
|
||||
id: lowerCutoffFreqSpinbox
|
||||
from: 20
|
||||
to: 22000
|
||||
stepSize: 100
|
||||
}
|
||||
|
||||
Label {
|
||||
text: i18n("Max")
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
id: higherCutoffFreqSpinbox
|
||||
from: 1
|
||||
to: 22000
|
||||
stepSize: 100
|
||||
}
|
||||
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Lower and higher cutoff frequencies for lowest and highest bars, the bandwidth of the visualizer.\nNote: Cava will automatically increase the higher cutoff if a too low band is specified.")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Sleep timer (seconds):")
|
||||
SpinBox {
|
||||
id: cavaSleepTimerSpinbox
|
||||
from: 1
|
||||
to: 60
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Seconds with no input before cava goes to sleep mode.\nCava will not perform FFT and only check for input once per second.")
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: pauseOnFullScreenWindow
|
||||
Kirigami.FormData.label: i18n("Pause on:")
|
||||
text: i18n("Full screen window")
|
||||
}
|
||||
CheckBox {
|
||||
id: pauseOnMaximizedWindow
|
||||
text: i18n("Maximized window")
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
Kirigami.FormData.isSection: true
|
||||
Kirigami.FormData.label: i18n("Input")
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Method:")
|
||||
Layout.preferredWidth: 300
|
||||
ComboBox {
|
||||
id: inputMethodCombobox
|
||||
textRole: "label"
|
||||
valueRole: "value"
|
||||
Layout.fillWidth: true
|
||||
model: [
|
||||
{
|
||||
label: i18n("Default"),
|
||||
value: ""
|
||||
},
|
||||
{
|
||||
label: "OSS",
|
||||
value: "oss"
|
||||
},
|
||||
{
|
||||
label: "PipeWire",
|
||||
value: "pipewire"
|
||||
},
|
||||
{
|
||||
label: "Sndio",
|
||||
value: "sndio"
|
||||
},
|
||||
{
|
||||
label: "JACK",
|
||||
value: "jack"
|
||||
},
|
||||
{
|
||||
label: "PulseAudio",
|
||||
value: "pulse"
|
||||
},
|
||||
{
|
||||
label: "ALSA",
|
||||
value: "alsa"
|
||||
},
|
||||
{
|
||||
label: "PortAudio",
|
||||
value: "portaudio"
|
||||
},
|
||||
{
|
||||
label: "FIFO",
|
||||
value: "fifo"
|
||||
},
|
||||
{
|
||||
label: "shmem",
|
||||
value: "shmem"
|
||||
},
|
||||
]
|
||||
onActivated: {
|
||||
root.cfg_inputMethod = currentValue;
|
||||
if (!["pipewire", "pulse"].includes(root.cfg_inputMethod)) {
|
||||
sourcesCard.visible = false;
|
||||
root.cfg_inputSource = "";
|
||||
}
|
||||
}
|
||||
Component.onCompleted: currentIndex = indexOfValue(root.cfg_inputMethod)
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Audio capturing method.\nDefaults to 'oss', 'pipewire', 'sndio', 'jack', 'pulse', 'alsa', 'portaudio' or 'fifo', in that order, dependent on what support cava was built with.\n")
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Source:")
|
||||
Layout.preferredWidth: 300
|
||||
TextField {
|
||||
id: inputSourceField
|
||||
Layout.fillWidth: true
|
||||
placeholderText: "auto"
|
||||
}
|
||||
Button {
|
||||
visible: ["pipewire", "pulse"].includes(root.cfg_inputMethod)
|
||||
icon.name: sourcesCard.visible ? "arrow-up" : "arrow-down"
|
||||
onClicked: {
|
||||
sourcesCard.visible = !sourcesCard.visible;
|
||||
}
|
||||
checkable: true
|
||||
checked: sourcesCard.visible
|
||||
}
|
||||
ToolButton {
|
||||
onCheckedChanged: inputSourceHelpCard.visible = !inputSourceHelpCard.visible
|
||||
checkable: true
|
||||
icon.name: "help"
|
||||
}
|
||||
}
|
||||
Kirigami.AbstractCard {
|
||||
id: sourcesCard
|
||||
implicitHeight: 200
|
||||
visible: false
|
||||
Layout.fillWidth: true
|
||||
contentItem: ScrollView {
|
||||
clip: true
|
||||
ListView {
|
||||
model: pactl.names
|
||||
delegate: ItemDelegate {
|
||||
id: delegate
|
||||
required property string modelData
|
||||
// required property Item root
|
||||
width: ListView.view.width
|
||||
text: modelData
|
||||
contentItem: Label {
|
||||
text: delegate.text
|
||||
wrapMode: Label.WrapAnywhere
|
||||
Layout.fillWidth: true
|
||||
font: Kirigami.Theme.smallFont
|
||||
}
|
||||
ToolTip.visible: false
|
||||
onClicked: root.cfg_inputSource = modelData
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Kirigami.AbstractCard {
|
||||
id: inputSourceHelpCard
|
||||
spacing: 0
|
||||
visible: false
|
||||
Layout.fillWidth: true
|
||||
contentItem: ColumnLayout {
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
Kirigami.SelectableLabel {
|
||||
text: i18n("For pulseaudio and pipewire 'source' will be the source. Default: 'auto', which uses the monitor source of the default sink (all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them).")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Kirigami.SelectableLabel {
|
||||
text: i18n("For pipewire 'source' will be the object name or object.serial of the device to capture from. Both input and output devices are supported.")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Kirigami.SelectableLabel {
|
||||
text: i18n("For alsa 'source' will be the capture device.")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Kirigami.SelectableLabel {
|
||||
text: i18n("For fifo 'source' will be the path to fifo-file.")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Kirigami.SelectableLabel {
|
||||
text: i18n("For shmem 'source' will be /squeezelite-AA:BB:CC:DD:EE:FF where 'AA:BB:CC:DD:EE:FF' will be squeezelite's MAC address.")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Kirigami.SelectableLabel {
|
||||
text: i18n("For sndio 'source' will be a raw recording audio descriptor or a monitoring sub-device, e.g. 'rsnd/2' or 'snd/1'. Default: 'default'.")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Kirigami.SelectableLabel {
|
||||
text: i18n("For oss 'source' will be the path to a audio device, e.g. '/dev/dsp2'. Default: '/dev/dsp', i.e. the default audio device.")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Kirigami.SelectableLabel {
|
||||
text: i18n("For jack 'source' will be the name of the JACK server to connect to, e.g. 'foobar'. Default: 'default'.")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.FormLayout {
|
||||
twinFormLayouts: [parentLayout]
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Sample rate:")
|
||||
SpinBox {
|
||||
id: sampleRateSpinbox
|
||||
from: 1
|
||||
to: 192000
|
||||
stepSize: 100
|
||||
enabled: ["", "fifo", "pipewire", "sndio", "oss"].includes(root.cfg_inputMethod)
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Only for fifo, pipewire, sndio, oss")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Sample bits:")
|
||||
SpinBox {
|
||||
id: sampleBitsSpinbox
|
||||
from: 8
|
||||
to: 32
|
||||
stepSize: 8
|
||||
enabled: ["", "fifo", "pipewire", "sndio", "oss"].includes(root.cfg_inputMethod)
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Only for fifo, pipewire, sndio, oss")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Channels:")
|
||||
SpinBox {
|
||||
id: inputChannelsSpinbox
|
||||
from: 2
|
||||
to: 4
|
||||
enabled: ["", "pipewire", "sndio", "oss", "jack"].includes(root.cfg_inputMethod)
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Only for pipewire & cava>=0.10.6, sndio, oss, jack")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Auto connect:")
|
||||
SpinBox {
|
||||
id: autoconnectSpinbox
|
||||
from: 2
|
||||
to: 4
|
||||
enabled: ["", "jack"].includes(root.cfg_inputMethod)
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Only for jack")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Active:")
|
||||
CheckBox {
|
||||
id: activeCheckbox
|
||||
enabled: ["", "pipewire"].includes(root.cfg_inputMethod)
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Only for pipewire & cava>=0.10.6. Force the node to always process. Useful for monitoring sources when no other application is active.")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Remix:")
|
||||
CheckBox {
|
||||
id: remixCheckbox
|
||||
enabled: ["", "pipewire"].includes(root.cfg_inputMethod)
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Only for pipewire & cava>=0.10.6. Allow to remix audio channels to match cava's channel count. Useful for surround sound.")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Virtual:")
|
||||
CheckBox {
|
||||
id: virtualCheckbox
|
||||
enabled: ["", "pipewire"].includes(root.cfg_inputMethod)
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Only for pipewire & cava>=0.10.6. Set the node to virtual, to avoid recording notifications from the DE.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.FormLayout {
|
||||
twinFormLayouts: [parentLayout]
|
||||
|
||||
Kirigami.Separator {
|
||||
Kirigami.FormData.isSection: true
|
||||
Kirigami.FormData.label: i18n("Output")
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Visual channels:")
|
||||
ComboBox {
|
||||
id: outputChannelsCombobox
|
||||
model: ["mono", "stereo"]
|
||||
onActivated: root.cfg_outputChannels = currentValue
|
||||
Component.onCompleted: currentIndex = indexOfValue(root.cfg_outputChannels)
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("'mono' outputs left to right lowest to highest frequencies.\n'stereo' mirrors both channels with low frequencies in center.")
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: monoOptionCombobox
|
||||
Kirigami.FormData.label: i18n("Mono channel:")
|
||||
model: ['left', 'right', 'average']
|
||||
onActivated: root.cfg_monoOption = currentValue
|
||||
Component.onCompleted: currentIndex = indexOfValue(root.cfg_monoOption)
|
||||
enabled: root.cfg_outputChannels === "mono"
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Reverse:")
|
||||
CheckBox {
|
||||
id: reverseCheckbox
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Display frequencies the other way around")
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
Kirigami.FormData.isSection: true
|
||||
Kirigami.FormData.label: i18n("Smoothing")
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Noise reduction:")
|
||||
SpinBox {
|
||||
id: noiseReductionSpinbox
|
||||
from: 0
|
||||
to: 100
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("The raw visualization is very noisy, this factor adjusts the integral and gravity filters to keep the signal smooth.\n100 will be very slow and smooth, 0 will be fast but noisy.")
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Monstercat:")
|
||||
CheckBox {
|
||||
id: monstercatCheckbox
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Enable the so-called \"Monstercat smoothing\" with or without \"waves\".")
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: wavesCheckbox
|
||||
text: i18n("Waves")
|
||||
enabled: monstercatCheckbox.checked
|
||||
}
|
||||
Kirigami.Separator {
|
||||
Kirigami.FormData.isSection: true
|
||||
Kirigami.FormData.label: i18n("Equalizer")
|
||||
}
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Enabled:")
|
||||
CheckBox {
|
||||
id: eqEnabled
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Adjust frequencies by a multiplication factor, more bands equals more precision.")
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
Eq {
|
||||
enabled: eqEnabled.checked
|
||||
Layout.preferredWidth: parent.width - Kirigami.Units.gridUnit * 2
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
fromFreq: root.cfg_lowerCutoffFreq
|
||||
toFreq: root.cfg_higherCutoffFreq
|
||||
onValueChanged: (index, value) => {
|
||||
root.cfg_eq[index] = parseFloat(value.toString()).toFixed(1);
|
||||
const tmp = root.cfg_eq;
|
||||
root.cfg_eq = null;
|
||||
root.cfg_eq = tmp;
|
||||
}
|
||||
Component.onCompleted: values = root.cfg_eq.map(v => parseFloat(v).toFixed(1))
|
||||
onBandRemoved: {
|
||||
root.cfg_eq.pop();
|
||||
values = root.cfg_eq.map(v => parseFloat(v).toFixed(1));
|
||||
}
|
||||
onBandAdded: {
|
||||
root.cfg_eq.push("1.0");
|
||||
values = root.cfg_eq.map(v => parseFloat(v).toFixed(1));
|
||||
}
|
||||
onFlat: {
|
||||
root.cfg_eq = root.cfg_eq.map(v => "1.0");
|
||||
// HACK: setting values alone doesn't update the values in the controls
|
||||
bandAdded();
|
||||
bandRemoved();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.kcmutils as KCM
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
|
||||
KCM.SimpleKCM {
|
||||
id: root
|
||||
property alias cfg_desktopWidgetBg: desktopWidgetBackgroundRadio.value
|
||||
property alias cfg_hideWhenIdle: hideWhenIdleCheckbox.checked
|
||||
property int cfg_visualizerStyle
|
||||
property string cfg_barColors
|
||||
property string cfg_waveFillColors
|
||||
property alias cfg_debugMode: debugModeCheckbox.checked
|
||||
property alias cfg_idleTimer: idleTimerSpinbox.value
|
||||
property alias cfg_hideToolTip: hideToolTipCheckbox.checked
|
||||
property alias cfg_disableLeftClick: disableLeftClickCheckbox.checked
|
||||
|
||||
Kirigami.FormLayout {
|
||||
id: parentLayout
|
||||
Layout.fillWidth: true
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Auto-hide when idle:")
|
||||
CheckBox {
|
||||
id: hideWhenIdleCheckbox
|
||||
}
|
||||
Label {
|
||||
text: i18n("After")
|
||||
}
|
||||
SpinBox {
|
||||
id: idleTimerSpinbox
|
||||
enabled: hideWhenIdleCheckbox.checked
|
||||
from: 1
|
||||
to: 60
|
||||
}
|
||||
Label {
|
||||
text: i18n("seconds")
|
||||
}
|
||||
}
|
||||
|
||||
RadioButton {
|
||||
Kirigami.FormData.label: i18n("Desktop background:")
|
||||
text: i18n("Default")
|
||||
checked: desktopWidgetBackgroundRadio.value == PlasmaCore.Types.StandardBackground
|
||||
onCheckedChanged: () => {
|
||||
if (checked) {
|
||||
desktopWidgetBackgroundRadio.value = PlasmaCore.Types.StandardBackground;
|
||||
}
|
||||
}
|
||||
ButtonGroup.group: desktopWidgetBackgroundRadio
|
||||
}
|
||||
RadioButton {
|
||||
text: i18n("Transparent")
|
||||
checked: desktopWidgetBackgroundRadio.value == PlasmaCore.Types.NoBackground
|
||||
onCheckedChanged: () => {
|
||||
if (checked) {
|
||||
desktopWidgetBackgroundRadio.value = PlasmaCore.Types.NoBackground;
|
||||
}
|
||||
}
|
||||
ButtonGroup.group: desktopWidgetBackgroundRadio
|
||||
}
|
||||
RowLayout {
|
||||
RadioButton {
|
||||
text: i18n("Transparent with shadow")
|
||||
checked: desktopWidgetBackgroundRadio.value == PlasmaCore.Types.ShadowBackground
|
||||
onCheckedChanged: () => {
|
||||
if (checked) {
|
||||
desktopWidgetBackgroundRadio.value = PlasmaCore.Types.ShadowBackground;
|
||||
}
|
||||
}
|
||||
ButtonGroup.group: desktopWidgetBackgroundRadio
|
||||
}
|
||||
}
|
||||
ButtonGroup {
|
||||
id: desktopWidgetBackgroundRadio
|
||||
property int value: PlasmaCore.Types.StandardBackground
|
||||
}
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Disable tooltip:")
|
||||
CheckBox {
|
||||
id: hideToolTipCheckbox
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Disable ToolTip that shows the widget name and description.")
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Disable left click:")
|
||||
CheckBox {
|
||||
id: disableLeftClickCheckbox
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Applet popup will still be accessible from the right click menu.")
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
Kirigami.FormData.isSection: true
|
||||
Kirigami.FormData.label: i18n("Troubleshooting")
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Kirigami.FormData.label: i18n("Debug mode:")
|
||||
CheckBox {
|
||||
id: debugModeCheckbox
|
||||
}
|
||||
Kirigami.ContextualHelpButton {
|
||||
toolTipText: i18n("Print additional messages to the system log. To make it easier to spot sizing issues, this will also force full height to the first visualizer bar and displays a grid over it.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.kcmutils as KCM
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.plasmoid
|
||||
import "components" as Components
|
||||
import "code/enum.js" as Enum
|
||||
import "code/utils.js" as Utils
|
||||
|
||||
KCM.SimpleKCM {
|
||||
id: root
|
||||
property alias cfg_barGap: barGapSpinbox.value
|
||||
property alias cfg_barWidth: barWidthSpinbox.value
|
||||
property alias cfg_blockHeight: blockHeightSpinbox.value
|
||||
property alias cfg_blockSpacing: blockSpacing.value
|
||||
property alias cfg_centeredBars: centeredBarsCheckbox.checked
|
||||
property alias cfg_roundedBars: roundedBarsCheckbox.checked
|
||||
// fill panel thickness
|
||||
property alias cfg_fillPanel: fillPanelCheckbox.checked
|
||||
property int cfg_visualizerStyle
|
||||
property alias cfg_circleMode: circleMode.checked
|
||||
property real cfg_circleModeSize
|
||||
property string cfg_barColors
|
||||
property string cfg_waveFillColors
|
||||
property string cfg_inactiveBlockColors
|
||||
property alias cfg_drawInactiveBlocks: drawInactiveBlocks.checked
|
||||
property alias cfg_fillWave: fillWaveCheckbox.checked
|
||||
// take all the available space in the panel
|
||||
property alias cfg_expanding: expandingCheckbox.checked
|
||||
property alias cfg_length: lengthSpinbox.value
|
||||
property int cfg_orientation
|
||||
|
||||
readonly property bool vertical: {
|
||||
if (Plasmoid.formFactor == PlasmaCore.Types.Vertical) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
readonly property string dimensionStr: vertical ? i18n("height") : i18n("width")
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
Kirigami.FormLayout {
|
||||
id: parentLayout
|
||||
Layout.fillWidth: true
|
||||
|
||||
ComboBox {
|
||||
id: visualizerStyleCombobox
|
||||
Kirigami.FormData.label: i18n("Style:")
|
||||
textRole: "label"
|
||||
valueRole: "value"
|
||||
model: [
|
||||
{
|
||||
"label": i18n("Bars"),
|
||||
"value": Enum.VisualizerStyles.Bars
|
||||
},
|
||||
{
|
||||
"label": i18n("Wave"),
|
||||
"value": Enum.VisualizerStyles.Wave
|
||||
},
|
||||
{
|
||||
"label": i18n("Blocks"),
|
||||
"value": Enum.VisualizerStyles.Blocks
|
||||
},
|
||||
]
|
||||
onActivated: {
|
||||
root.cfg_visualizerStyle = currentValue;
|
||||
}
|
||||
Component.onCompleted: {
|
||||
currentIndex = indexOfValue(root.cfg_visualizerStyle);
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: fillWaveCheckbox
|
||||
text: i18n("Fill wave")
|
||||
enabled: root.cfg_visualizerStyle === Enum.VisualizerStyles.Wave
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: drawInactiveBlocks
|
||||
text: i18n("Draw inactive blocks")
|
||||
enabled: root.cfg_visualizerStyle === Enum.VisualizerStyles.Blocks
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: circleMode
|
||||
Kirigami.FormData.label: i18n("Circle mode:")
|
||||
}
|
||||
|
||||
Components.DoubleSpinBox {
|
||||
id: circleModeSize
|
||||
Kirigami.FormData.label: i18n("Circle size:")
|
||||
from: 0 * multiplier
|
||||
to: 0.99 * multiplier
|
||||
value: cfg_circleModeSize * multiplier
|
||||
onValueModified: {
|
||||
cfg_circleModeSize = value / circleModeSize.multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: orientationCombobox
|
||||
Kirigami.FormData.label: i18n("Orientation:")
|
||||
valueRole: "value"
|
||||
textRole: "label"
|
||||
|
||||
model: [
|
||||
{
|
||||
label: i18n("Top"),
|
||||
value: Enum.Orientation.Top
|
||||
},
|
||||
{
|
||||
label: i18n("Bottom"),
|
||||
value: Enum.Orientation.Bottom
|
||||
},
|
||||
{
|
||||
label: i18n("Left"),
|
||||
value: Enum.Orientation.Left
|
||||
},
|
||||
{
|
||||
label: i18n("Right"),
|
||||
value: Enum.Orientation.Right
|
||||
}
|
||||
]
|
||||
onActivated: root.cfg_orientation = currentValue
|
||||
Component.onCompleted: currentIndex = indexOfValue(root.cfg_orientation)
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: expandingCheckbox
|
||||
visible: !(Plasmoid.location === PlasmaCore.Types.Floating)
|
||||
Kirigami.FormData.label: i18n("Fill panel %1:", root.dimensionStr)
|
||||
}
|
||||
SpinBox {
|
||||
id: lengthSpinbox
|
||||
visible: !(Plasmoid.location === PlasmaCore.Types.Floating)
|
||||
enabled: !expandingCheckbox.checked
|
||||
Kirigami.FormData.label: i18n("Fixed %1:", root.dimensionStr)
|
||||
from: 1
|
||||
to: 9999
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: fillPanelCheckbox
|
||||
visible: !(Plasmoid.location === PlasmaCore.Types.Floating)
|
||||
Kirigami.FormData.label: i18n("Fill panel thickness:")
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: centeredBarsCheckbox
|
||||
Kirigami.FormData.label: i18n("Centered bars:")
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: roundedBarsCheckbox
|
||||
Kirigami.FormData.label: i18n("Rounded bars:")
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
id: barWidthSpinbox
|
||||
Kirigami.FormData.label: root.cfg_visualizerStyle === Enum.VisualizerStyles.Wave ? i18n("Line width:") : i18n("Bar width:")
|
||||
from: 1
|
||||
to: 999
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
id: barGapSpinbox
|
||||
Kirigami.FormData.label: i18n("Bar gap:")
|
||||
from: root.cfg_visualizerStyle === Enum.VisualizerStyles.Wave ? 1 : 0
|
||||
to: 999
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
id: blockHeightSpinbox
|
||||
Kirigami.FormData.label: i18n("Block height:")
|
||||
from: 1
|
||||
to: 999
|
||||
enabled: root.cfg_visualizerStyle === Enum.VisualizerStyles.Blocks
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
id: blockSpacing
|
||||
Kirigami.FormData.label: i18n("Block gap:")
|
||||
from: 0
|
||||
to: 999
|
||||
enabled: root.cfg_visualizerStyle === Enum.VisualizerStyles.Blocks
|
||||
}
|
||||
}
|
||||
|
||||
Components.FormColors {
|
||||
configString: root.cfg_barColors
|
||||
handleString: true
|
||||
onUpdateConfigString: (newString, newConfig) => {
|
||||
root.cfg_barColors = JSON.stringify(newConfig);
|
||||
}
|
||||
sectionName: root.cfg_visualizerStyle === Enum.VisualizerStyles.Wave ? i18n("Wave Color") : i18n("Bar Color")
|
||||
multiColor: true
|
||||
}
|
||||
|
||||
Components.FormColors {
|
||||
configString: root.cfg_inactiveBlockColors
|
||||
handleString: true
|
||||
onUpdateConfigString: (newString, newConfig) => {
|
||||
root.cfg_inactiveBlockColors = JSON.stringify(newConfig);
|
||||
}
|
||||
sectionName: i18n("Inactive block color")
|
||||
multiColor: true
|
||||
visible: root.cfg_visualizerStyle === Enum.VisualizerStyles.Blocks && drawInactiveBlocks.checked
|
||||
}
|
||||
|
||||
Components.FormColors {
|
||||
configString: root.cfg_waveFillColors
|
||||
handleString: true
|
||||
onUpdateConfigString: (newString, newConfig) => {
|
||||
root.cfg_waveFillColors = JSON.stringify(newConfig);
|
||||
}
|
||||
sectionName: i18n("Wave Fill Color")
|
||||
multiColor: true
|
||||
visible: root.cfg_visualizerStyle === Enum.VisualizerStyles.Wave && fillWaveCheckbox.checked
|
||||
}
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
sodipodi:docname="error.svg"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview2"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="9.5459416"
|
||||
inkscape:cx="20.322773"
|
||||
inkscape:cy="22.365525"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1048"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="22-22-material-you" />
|
||||
<defs
|
||||
id="materia">
|
||||
<style
|
||||
id="current-color-scheme"
|
||||
type="text/css">
|
||||
.ColorScheme-Background {color:#181818; } .ColorScheme-ButtonBackground { color:#343434; } .ColorScheme-Highlight { color:#4285f4; } .ColorScheme-Text { color:#dfdfdf; } .ColorScheme-ViewBackground { color:#242424; } .ColorScheme-NegativeText { color:#f44336; } .ColorScheme-PositiveText { color:#4caf50; } .ColorScheme-NeutralText { color:#ff9800; }
|
||||
</style>
|
||||
</defs>
|
||||
<g
|
||||
id="22-22-material-you"
|
||||
transform="translate(27,5.0000005)"
|
||||
style="opacity:1;fill:currentColor"
|
||||
class="ColorScheme-Text">
|
||||
<rect
|
||||
style="opacity:0.00100002"
|
||||
width="22"
|
||||
height="22"
|
||||
x="4.7904868"
|
||||
y="5"
|
||||
id="rect1" />
|
||||
<path
|
||||
d="m 12.474932,8 -4.6844452,4.684445 v 6.63111 L 12.474932,24 h 6.63111 l 4.684445,-4.684445 v -6.63111 L 19.106042,8 m -6.506666,3.555555 3.191111,3.191112 3.191111,-3.191112 1.253334,1.253334 L 17.04382,16 20.234932,19.191111 18.981598,20.444445 15.790487,17.253333 12.599376,20.444445 11.346042,19.191111 14.537154,16 11.346042,12.808889"
|
||||
id="path1-3-6"
|
||||
style="fill:currentColor;stroke-width:0.888887" />
|
||||
</g>
|
||||
<g
|
||||
id="material-you"
|
||||
class="ColorScheme-Text"
|
||||
style="opacity:1;fill:currentColor"
|
||||
transform="translate(35.302961,-8.4852813)">
|
||||
<rect
|
||||
style="opacity:0.00100002"
|
||||
width="32"
|
||||
height="32"
|
||||
x="-35.302959"
|
||||
y="8.485281"
|
||||
id="rect2" />
|
||||
<path
|
||||
d="m -24.276292,12.485281 -7.026668,7.026667 v 9.946666 l 7.026668,7.026667 h 9.946666 l 7.0266667,-7.026667 v -9.946666 l -7.0266667,-7.026667 m -9.76,5.333333 4.786667,4.786667 4.786667,-4.786667 1.88,1.88 -4.786667,4.786667 4.786667,4.786667 -1.88,1.88 -4.786667,-4.786667 -4.786667,4.786667 -1.880001,-1.88 4.786668,-4.786667 -4.786668,-4.786667"
|
||||
id="path1-3"
|
||||
style="stroke-width:1.33333" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
+208
@@ -0,0 +1,208 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
import org.kde.plasma.core as PlasmaCore
|
||||
import org.kde.plasma.plasmoid
|
||||
import "code/enum.js" as Enum
|
||||
import "code/utils.js" as Utils
|
||||
|
||||
PlasmoidItem {
|
||||
id: main
|
||||
Plasmoid.backgroundHints: editMode ? PlasmaCore.Types.StandardBackground : plasmoid.configuration.desktopWidgetBg
|
||||
Plasmoid.constraintHints: Plasmoid.configuration.fillPanel ? Plasmoid.CanFillArea : Plasmoid.NoHint
|
||||
|
||||
property bool editMode: Plasmoid.containment.corona?.editMode ?? false
|
||||
property bool onDesktop: Plasmoid.location === PlasmaCore.Types.Floating
|
||||
property bool horizontal: Plasmoid.formFactor !== PlasmaCore.Types.Vertical
|
||||
property int orientation: Plasmoid.configuration.orientation
|
||||
property bool stopCava: Plasmoid.configuration._stopCava
|
||||
property bool disableLeftClick: Plasmoid.configuration.disableLeftClick
|
||||
|
||||
property int barGap: {
|
||||
if (Plasmoid.configuration.visualizerStyle === Enum.VisualizerStyles.Wave) {
|
||||
return Math.max(1, Plasmoid.configuration.barGap);
|
||||
}
|
||||
return Plasmoid.configuration.barGap;
|
||||
}
|
||||
|
||||
property int barCount: {
|
||||
let bars = 1;
|
||||
let width;
|
||||
if (Plasmoid.configuration.circleMode) {
|
||||
width = Math.min(main.width, main.height);
|
||||
} else {
|
||||
width = [Enum.Orientation.Left, Enum.Orientation.Right].includes(Plasmoid.configuration.orientation) ? main.height : main.width;
|
||||
}
|
||||
if (Plasmoid.configuration.visualizerStyle === Enum.VisualizerStyles.Wave) {
|
||||
bars = Math.floor((width + barGap) / barGap);
|
||||
} else {
|
||||
bars = Math.floor((width + barGap) / (Plasmoid.configuration.barWidth + barGap));
|
||||
}
|
||||
if (Plasmoid.configuration.outputChannels === "stereo") {
|
||||
bars = Utils.makeEven(bars);
|
||||
}
|
||||
if (Plasmoid.configuration.visualizerStyle === Enum.VisualizerStyles.Wave) {
|
||||
bars = Math.max(2, bars);
|
||||
}
|
||||
return bars;
|
||||
}
|
||||
|
||||
property int asciiMaxRange: [Enum.Orientation.Left, Enum.Orientation.Right].includes(Plasmoid.configuration.orientation) ? main.width : main.height
|
||||
property var logger: Logger.create(Plasmoid.configuration.debugMode ? LoggingCategory.Debug : LoggingCategory.Info)
|
||||
property bool hideWhenIdle: Plasmoid.configuration.hideWhenIdle
|
||||
|
||||
property bool pauseFullScreen: Plasmoid.configuration.pauseOnFullScreenWindow
|
||||
property bool pauseMaximized: Plasmoid.configuration.pauseOnMaximizedWindow
|
||||
property bool pauseByWindow: (pauseMaximized && tasksModel.maximizedExists) || (pauseFullScreen && tasksModel.fullScreenExists)
|
||||
|
||||
Plasmoid.status: PlasmaCore.Types.ActiveStatus
|
||||
|
||||
function updateStatus() {
|
||||
logger.debug("Plasmoid.status:", Plasmoid.status);
|
||||
// HACK: without this delay there is a visible margin on the right side when expanding == true
|
||||
Utils.delay(10, () => {
|
||||
if (Plasmoid.status === PlasmaCore.Types.RequiresAttentionStatus) {
|
||||
return;
|
||||
}
|
||||
Plasmoid.status = (hideWhenIdle && cava.idle || !cava.running) && !Plasmoid.expanded && !editMode && !cava.hasError ? PlasmaCore.Types.HiddenStatus : PlasmaCore.Types.ActiveStatus;
|
||||
logger.debug("Plasmoid.status:", Plasmoid.status);
|
||||
}, main);
|
||||
}
|
||||
onExpandedChanged: expanded => {
|
||||
logger.debug("expanded:", expanded);
|
||||
Utils.delay(1000, updateStatus, main);
|
||||
}
|
||||
|
||||
onBarCountChanged: {
|
||||
if (editMode && stopCava) {
|
||||
return;
|
||||
}
|
||||
Qt.callLater(() => {
|
||||
resizeDebounce.restart();
|
||||
});
|
||||
}
|
||||
|
||||
onAsciiMaxRangeChanged: {
|
||||
if (editMode && stopCava) {
|
||||
return;
|
||||
}
|
||||
Qt.callLater(() => {
|
||||
resizeDebounce.restart();
|
||||
});
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: resizeDebounce
|
||||
interval: 50
|
||||
onTriggered: {
|
||||
cava.barCount = main.barCount;
|
||||
cava.asciiMaxRange = main.asciiMaxRange;
|
||||
logger.debug("barCount:", barCount, "asciiMaxRange:", asciiMaxRange);
|
||||
}
|
||||
}
|
||||
|
||||
onEditModeChanged: {
|
||||
logger.debug("editMode:", editMode);
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
Cava {
|
||||
id: cava
|
||||
framerate: Plasmoid.configuration.framerate
|
||||
noiseReduction: Plasmoid.configuration.noiseReduction
|
||||
monstercat: Plasmoid.configuration.monstercat
|
||||
waves: Plasmoid.configuration.waves
|
||||
autoSensitivity: Plasmoid.configuration.autoSensitivity
|
||||
sensitivityEnabled: Plasmoid.configuration.sensitivityEnabled
|
||||
sensitivity: Plasmoid.configuration.sensitivity
|
||||
lowerCutoffFreq: Plasmoid.configuration.lowerCutoffFreq
|
||||
higherCutoffFreq: Plasmoid.configuration.higherCutoffFreq
|
||||
inputMethod: Plasmoid.configuration.inputMethod
|
||||
inputSource: Plasmoid.configuration.inputSource
|
||||
sampleRate: Plasmoid.configuration.sampleRate
|
||||
sampleBits: Plasmoid.configuration.sampleBits
|
||||
inputChannels: Plasmoid.configuration.inputChannels
|
||||
autoconnect: Plasmoid.configuration.autoconnect
|
||||
active: Plasmoid.configuration.active
|
||||
remix: Plasmoid.configuration.remix
|
||||
virtual: Plasmoid.configuration.virtual
|
||||
outputChannels: Plasmoid.configuration.outputChannels
|
||||
monoOption: Plasmoid.configuration.monoOption
|
||||
reverse: Plasmoid.configuration.reverse
|
||||
eqEnabled: Plasmoid.configuration.eqEnabled
|
||||
eq: Plasmoid.configuration.eq
|
||||
idleCheck: main.hideWhenIdle
|
||||
idleTimer: Plasmoid.configuration.idleTimer
|
||||
cavaSleepTimer: Plasmoid.configuration.cavaSleepTimer
|
||||
onIdleChanged: {
|
||||
main.logger.info("cava.idle:", idle);
|
||||
main.updateStatus();
|
||||
}
|
||||
onHasErrorChanged: {
|
||||
main.logger.error("cava.hasError:", hasError, error);
|
||||
main.updateStatus();
|
||||
}
|
||||
onRunningChanged: {
|
||||
main.logger.info("cava.running:", running);
|
||||
main.updateStatus();
|
||||
}
|
||||
}
|
||||
|
||||
preferredRepresentation: compactRepresentation
|
||||
compactRepresentation: CompactRepresentation {}
|
||||
fullRepresentation: FullRepresentation {}
|
||||
|
||||
onStopCavaChanged: {
|
||||
logger.debug("stopCava:", stopCava);
|
||||
if (stopCava) {
|
||||
cava.stop();
|
||||
} else {
|
||||
cava.start();
|
||||
}
|
||||
}
|
||||
|
||||
Plasmoid.contextualActions: [
|
||||
PlasmaCore.Action {
|
||||
text: cava.running ? i18n("Stop CAVA") : i18n("Start CAVA")
|
||||
icon.name: "waveform-symbolic"
|
||||
onTriggered: {
|
||||
Plasmoid.configuration._stopCava = !Plasmoid.configuration._stopCava;
|
||||
Plasmoid.configuration.writeConfig();
|
||||
}
|
||||
},
|
||||
PlasmaCore.Action {
|
||||
text: i18n("Show support information")
|
||||
icon.name: "info-symbolic"
|
||||
onTriggered: {
|
||||
main.expanded = !main.expanded;
|
||||
}
|
||||
visible: main.disableLeftClick
|
||||
}
|
||||
]
|
||||
// hide default tooltip
|
||||
toolTipMainText: ""
|
||||
toolTipSubText: ""
|
||||
Connections {
|
||||
target: Qt.application
|
||||
function onAboutToQuit() {
|
||||
cava.stop();
|
||||
}
|
||||
}
|
||||
|
||||
TasksModel {
|
||||
id: tasksModel
|
||||
screenGeometry: Plasmoid.containment.screenGeometry
|
||||
}
|
||||
|
||||
onPauseByWindowChanged: {
|
||||
if (Plasmoid.configuration._stopCava) {
|
||||
return;
|
||||
}
|
||||
if (pauseByWindow) {
|
||||
cava.stop();
|
||||
} else {
|
||||
cava.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
singleton Logger 1.0 Logger.qml
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import asyncio
|
||||
import sys
|
||||
from signal import SIGTERM
|
||||
import websockets
|
||||
|
||||
|
||||
async def monitor_command_output(cmd: str, ws_url: str) -> None:
|
||||
"""Run a command and send the PID and live output to a websocket
|
||||
|
||||
Args:
|
||||
cmd (str): command
|
||||
ws_url (str): websocket url
|
||||
"""
|
||||
proc = None
|
||||
try:
|
||||
async with websockets.connect(ws_url) as ws:
|
||||
await ws.send(f"PID: {os.getpid()}")
|
||||
|
||||
print(f"Starting process {cmd} ...")
|
||||
proc = await asyncio.create_subprocess_shell(
|
||||
cmd,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
|
||||
async with websockets.connect(ws_url) as ws:
|
||||
assert proc.stdout is not None
|
||||
async for line in proc.stdout:
|
||||
await ws.send(line.decode().rstrip())
|
||||
|
||||
assert proc.stderr is not None
|
||||
async for line in proc.stderr:
|
||||
await ws.send(f"ERROR: {line.decode().rstrip()}")
|
||||
|
||||
await proc.wait()
|
||||
except asyncio.CancelledError:
|
||||
if proc is not None and proc.returncode is None:
|
||||
print(f"Stopping process pid: {proc.pid} {cmd} ...")
|
||||
proc.kill()
|
||||
await proc.wait()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 3:
|
||||
print(f"Usage: {os.path.basename(__file__)} <ws-url> <command>")
|
||||
sys.exit(1)
|
||||
|
||||
WS_URL = sys.argv[1]
|
||||
COMMAND = " ".join(sys.argv[2:])
|
||||
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
main_task = asyncio.ensure_future(
|
||||
monitor_command_output(COMMAND, WS_URL), loop=loop
|
||||
)
|
||||
loop.add_signal_handler(SIGTERM, main_task.cancel)
|
||||
|
||||
try:
|
||||
loop.run_until_complete(main_task)
|
||||
finally:
|
||||
loop.close()
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"KPackageStructure": "Plasma/Applet",
|
||||
"KPlugin": {
|
||||
"Authors": [
|
||||
{
|
||||
"Email": "luisbocanegra17b@gmail.com",
|
||||
"Name": "Luis Bocanegra"
|
||||
}
|
||||
],
|
||||
"BugReportUrl": "https://github.com/luisbocanegra/kurve/issues",
|
||||
"Category": "System Information",
|
||||
"Description": "Audio visualizer powered by CAVA",
|
||||
"Description[nl]": "Audiovisualisatie, gebaseerd op CAVA",
|
||||
"Description[ru]": "Аудио-визуализатор на базе CAVA",
|
||||
"Description[sv]": "Ljudvisualisering som använder CAVA",
|
||||
"Description[zh_CN]": "基于CAVA的音频可视化器",
|
||||
"EnabledByDefault": false,
|
||||
"Icon": "waveform-symbolic",
|
||||
"Id": "luisbocanegra.audio.visualizer",
|
||||
"License": "GPL-3.0",
|
||||
"Name": "Kurve",
|
||||
"Name[nl]": "Kurve",
|
||||
"Name[ru]": "Kurve",
|
||||
"Name[sv]": "Kurve",
|
||||
"Name[zh_CN]": "Kurve",
|
||||
"Version": "3.3.0",
|
||||
"Website": "https://github.com/luisbocanegra/kurve"
|
||||
},
|
||||
"X-Plasma-API-Minimum-Version": "6.0"
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
# Translate
|
||||
|
||||
## Status
|
||||
|
||||
| Locale | Lines | % Done|
|
||||
|----------|---------|-------|
|
||||
| Template | 156 | |
|
||||
| nl | 148/156 | 94% |
|
||||
| ru | 153/156 | 98% |
|
||||
| sv | 148/156 | 94% |
|
||||
| zh_CN | 156/156 | 100% |
|
||||
|
||||
|
||||
## New Translations
|
||||
|
||||
* Fill out [`template.pot`](template.pot) with your translations then open a [new issue](https://github.com/luisbocanegra/kurve/issues/new), name the file `spanish.txt`, attach the txt file to the issue (drag and drop).
|
||||
|
||||
Or if you know how to make a pull request
|
||||
|
||||
* Copy the `template.pot` file and name it your locale's code (Eg: `en`/`de`/`fr`) with the extension `.po`. Then fill out all the `msgstr ""`.
|
||||
* Your region's locale code can be found at: https://stackoverflow.com/questions/3191664/list-of-all-locales-and-their-short-codes/28357857#28357857
|
||||
|
||||
## Scripts
|
||||
|
||||
Zren's `kpac` script can easily run the `gettext` commands for you, parsing the `metadata.json` and filling out any placeholders for you. `kpac` can be [downloaded here](https://github.com/Zren/plasma-applet-lib/blob/master/kpac) and should be placed at `~/Code/plasmoid-widgetname/kpac` to edit translations at `~/Code/plasmoid-widgetname/package/translate/`.
|
||||
|
||||
|
||||
* `python3 ./kpac i18n` will parse the `i18n()` calls in the `*.qml` files and write it to the `template.pot` file. Then it will merge any changes into the `*.po` language files. Then it converts the `*.po` files to it's binary `*.mo` version and move it to `contents/locale/...` which will bundle the translations in the `*.plasmoid` without needing the user to manually install them.
|
||||
* `python3 ./kpac localetest` will convert the `.po` to the `*.mo` files then run `plasmoidviewer` (part of `plasma-sdk`).
|
||||
|
||||
## How it works
|
||||
|
||||
Since KDE Frameworks v5.37, translations can be bundled with the zipped `*.plasmoid` file downloaded from the store.
|
||||
|
||||
* `xgettext` extracts the messages from the source code into a `template.pot`.
|
||||
* Translators copy the `template.pot` to `fr.po` to translate the French language.
|
||||
* When the source code is updated, we use `msgmerge` to update the `fr.po` based on the updated `template.pot`.
|
||||
* When testing or releasing the widget, we convert the `.po` files to their binary `.mo` form with `msgfmt`.
|
||||
|
||||
The binary `.mo` translation files are placed in `package/contents/locale/` so you may want to add `*.mo` to your `.gitignore`.
|
||||
|
||||
```
|
||||
package/contents/locale/fr/LC_MESSAGES/plasma_applet_luisbocanegra.audio.visualizer.mo
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
* https://develop.kde.org/docs/plasma/widget/translations-i18n/
|
||||
* https://l10n.kde.org/stats/gui/trunk-kf5/team/fr/plasma-desktop/
|
||||
* https://techbase.kde.org/Development/Tutorials/Localization/i18n_Build_Systems
|
||||
* https://api.kde.org/frameworks/ki18n/html/prg_guide.html
|
||||
|
||||
> Version 8 of [Zren's i18n scripts](https://github.com/Zren/plasma-applet-lib).
|
||||
+776
@@ -0,0 +1,776 @@
|
||||
# Translation of visualizer in nl
|
||||
# Copyright (C) 2025
|
||||
# This file is distributed under the same license as the visualizer package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: visualizer\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/luisbocanegra/kurve\n"
|
||||
"POT-Creation-Date: 2025-12-13 18:30+0000\n"
|
||||
"PO-Revision-Date: 2025-11-12 10:33+0100\n"
|
||||
"Last-Translator: Heimen Stoffels <vistausss@fastmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: nl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 3.8\n"
|
||||
|
||||
#: ../metadata.json
|
||||
msgid "Kurve"
|
||||
msgstr "Kurve"
|
||||
|
||||
#: ../metadata.json
|
||||
msgid "Audio visualizer powered by CAVA"
|
||||
msgstr "Audiovisualisatie, gebaseerd op CAVA"
|
||||
|
||||
#: ../contents/config/config.qml
|
||||
msgid "Visualizer"
|
||||
msgstr "Visualisatie"
|
||||
|
||||
#: ../contents/config/config.qml ../contents/ui/configCava.qml
|
||||
msgid "General"
|
||||
msgstr "Algemeen"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml
|
||||
msgid "Oh no! Something went wrong"
|
||||
msgstr "Oeps, er is iets misgegaan…"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml ../contents/ui/configCava.qml
|
||||
#: ../contents/ui/main.qml
|
||||
msgid "Stop CAVA"
|
||||
msgstr "CAVA stoppen"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml ../contents/ui/configCava.qml
|
||||
#: ../contents/ui/main.qml
|
||||
msgid "Start CAVA"
|
||||
msgstr "CAVA starten"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml
|
||||
msgid "Copy to clipboard"
|
||||
msgstr "Kopiëren naar klembord"
|
||||
|
||||
#: ../contents/ui/components/ColorPickerGradientList.qml
|
||||
#: ../contents/ui/components/ColorPickerList.qml
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Widget background"
|
||||
msgstr "Widgetachtergrond"
|
||||
|
||||
#: ../contents/ui/components/Eq.qml
|
||||
msgid "Remove band"
|
||||
msgstr "Bandbreedte verwijderen"
|
||||
|
||||
#: ../contents/ui/components/Eq.qml
|
||||
msgid "Add band"
|
||||
msgstr "Bandbreedte toevoegen"
|
||||
|
||||
#: ../contents/ui/components/Eq.qml
|
||||
msgid "Flat response"
|
||||
msgstr "Plat antwoord"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color"
|
||||
msgstr "Kleur"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Animation:"
|
||||
msgstr "Animatie:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Interval (ms):"
|
||||
msgstr "Tussenpoos (in ms):"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Smoothing (ms):"
|
||||
msgstr "Vloeiende overgangen (in ms):"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color source:"
|
||||
msgstr "Kleurbron:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Custom"
|
||||
msgstr "Zelfgekozen"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "A fixed custom color"
|
||||
msgstr "Een zelfgekozen kleur"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "System"
|
||||
msgstr "Systeemthema"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color that updates with your System theme"
|
||||
msgstr "De kleur van het systeemthema"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Custom list"
|
||||
msgstr "Zelfgemaakte lijst"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid ""
|
||||
"Define a list of colors that will be applied to all the elements, wraps "
|
||||
"around if there are more elements than colors"
|
||||
msgstr ""
|
||||
"Stel een lijst samen met kleuren die worden toegepast op alle elementen - in "
|
||||
"herhaalde volgorde indien er meer elementen dat kleuren zijn"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Random"
|
||||
msgstr "Willekeurig"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Random color for each element"
|
||||
msgstr "Gebruik een willekeurige kleur per element"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Follow"
|
||||
msgstr "Volgen"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Follow the color of a parent element"
|
||||
msgstr "Gebruik de kleur van het hoofdelement"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Gradient"
|
||||
msgstr "Verloop"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Horizontal or vertical customizable color gradient"
|
||||
msgstr "Een horizontaal of verticaal kleurverloop, naar eigen inzicht"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Image"
|
||||
msgstr "Afbeelding"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid ""
|
||||
"High resolution images can slow down the desktop when the panel or widget "
|
||||
"size changes!"
|
||||
msgstr ""
|
||||
"Let op: afbeeldingen met een hoge resolutie kunnen voor vertraging zorgen!"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Hue"
|
||||
msgstr "Tint"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Automatically shifted color for each bar"
|
||||
msgstr "Voorzie elke balk van een eigen tint"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Element:"
|
||||
msgstr "Element:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Panel background"
|
||||
msgstr "Paneelachtergrond"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Tray widget background"
|
||||
msgstr "Systeemvakachtergrond"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Positioning:"
|
||||
msgstr "Uitlijning:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Stretch"
|
||||
msgstr "Uitgerekt"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Tile"
|
||||
msgstr "Tegelen"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Scaled and Cropped"
|
||||
msgstr "Bijsnijden en inpassen"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Image:"
|
||||
msgstr "Afbeelding:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Pick a image file"
|
||||
msgstr "Kies een afbeelding"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Image files"
|
||||
msgstr "Afbeeldingsbestanden"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "All files"
|
||||
msgstr "Alle bestanden"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color:"
|
||||
msgstr "Kleur:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color set:"
|
||||
msgstr "Kleurenschema:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Colors:"
|
||||
msgstr "Kleuren:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Range:"
|
||||
msgstr "Bereik:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml ../contents/ui/configVisualizer.qml
|
||||
msgid "Orientation:"
|
||||
msgstr "Oriëntatie:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Horizontal"
|
||||
msgstr "Horizontaal"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Vertical"
|
||||
msgstr "Verticaal"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Gradient:"
|
||||
msgstr "Verloop:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml ../contents/ui/configCava.qml
|
||||
msgid "Reverse:"
|
||||
msgstr "Verwisselen:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Display colors the other way around"
|
||||
msgstr "Kleuren omkeren"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Alpha:"
|
||||
msgstr "Alfa:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Contrast Correction"
|
||||
msgstr "Contrastaanpassing"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Saturation:"
|
||||
msgstr "Verzadiging:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Lightness:"
|
||||
msgstr "Helderheid:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Framerate:"
|
||||
msgstr "Framesnelheid:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Number of bars:"
|
||||
msgstr "Aantal balken:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Automatically calculated for the current visualizer style."
|
||||
msgstr ""
|
||||
"Dit wordt automatisch berekend aan de hand van de huidige visualisatie."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Automatic sensitivity:"
|
||||
msgstr "Automatische gevoeligheid:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Attempt to decrease sensitivity if the bars peak."
|
||||
msgstr ""
|
||||
"Probeer de gevoeligheid te verlagen zodra het maximale aantal balken bereikt "
|
||||
"is."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sensitivity:"
|
||||
msgstr "Gevoeligheidsgraad:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Manual sensitivity in %.\n"
|
||||
"If autosens is enabled, this will only be the initial value"
|
||||
msgstr ""
|
||||
"De handmatige gevoeligheidsgraad (in %).\n"
|
||||
"Als de automatische modus is ingeschakeld, dan wordt dit als startwaarde "
|
||||
"gebruikt."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Frequency range (Hz):"
|
||||
msgstr "Frequentiebereik (in Hz):"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Min"
|
||||
msgstr "Min."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Max"
|
||||
msgstr "Max."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Lower and higher cutoff frequencies for lowest and highest bars, the "
|
||||
"bandwidth of the visualizer.\n"
|
||||
"Note: Cava will automatically increase the higher cutoff if a too low band "
|
||||
"is specified."
|
||||
msgstr ""
|
||||
"Lagere en hogere afbreekfrequenties voor de laagste en hoogste balken, en de "
|
||||
"bandbreedte van de visualisatie.\n"
|
||||
"Let op: Cava zal deze waarde automatisch verhogen als een te lage band is "
|
||||
"opgegeven."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sleep timer (seconds):"
|
||||
msgstr "Slapen na (in seconden):"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Seconds with no input before cava goes to sleep mode.\n"
|
||||
"Cava will not perform FFT and only check for input once per second."
|
||||
msgstr ""
|
||||
"Het aantal seconden zonder invoer, waarna Cava in de slaapmodus gaat.\n"
|
||||
"Cava zal geen FFT uitvoeren en controleert de invoer slechts eenmaal per "
|
||||
"seconde."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Pause on:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Full screen window"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Maximized window"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Input"
|
||||
msgstr "Invoer"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Method:"
|
||||
msgstr "Methode:"
|
||||
|
||||
#: ../contents/ui/configCava.qml ../contents/ui/configGeneral.qml
|
||||
msgid "Default"
|
||||
msgstr "Standaard"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Audio capturing method.\n"
|
||||
"Defaults to 'oss', 'pipewire', 'sndio', 'jack', 'pulse', 'alsa', 'portaudio' "
|
||||
"or 'fifo', in that order, dependent on what support cava was built with.\n"
|
||||
msgstr ""
|
||||
"De audio-invoermethode.\n"
|
||||
"Standaard wordt ‘oss’, ‘pipewire’, ‘sndio’, ‘jack’, ‘pulse’, ‘alsa’, "
|
||||
"‘portaudio’ of ‘fifo’ in vaste volgorde gebruikt. De gekozen methode is "
|
||||
"afhankelijk van waar Cava mee gebouwd is.\r\n"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Source:"
|
||||
msgstr "Bron:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For pulseaudio and pipewire 'source' will be the source. Default: 'auto', "
|
||||
"which uses the monitor source of the default sink (all pulseaudio "
|
||||
"sinks(outputs) have 'monitor' sources(inputs) associated with them)."
|
||||
msgstr ""
|
||||
"Voor PulseAudio en PipeWire wordt ‘source’ gebruikt als de bron. Standaard "
|
||||
"staat deze waarde op ‘auto’, welke de bron van de standaardsink zal "
|
||||
"raadplegen (alle PulseAudio-sinks (uitvoeren) hebben ‘monitor’-bronnen "
|
||||
"(invoeren))."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For pipewire 'source' will be the object name or object.serial of the device "
|
||||
"to capture from. Both input and output devices are supported."
|
||||
msgstr ""
|
||||
"Voor PipeWire zal ‘source’ de objectnaam of object.serial zijn van het te "
|
||||
"gebruiken apparaat. Zowel in- als uitvoerapparaten kunnen worden gebruikt."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "For alsa 'source' will be the capture device."
|
||||
msgstr "Voor Alsa zal ‘source’ het opnameapparaat zijn."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "For fifo 'source' will be the path to fifo-file."
|
||||
msgstr "Voor fifo zal ‘source’ de locatie van het fifo-bestand zijn."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For shmem 'source' will be /squeezelite-AA:BB:CC:DD:EE:FF where 'AA:BB:CC:DD:"
|
||||
"EE:FF' will be squeezelite's MAC address."
|
||||
msgstr ""
|
||||
"Voor shmem zal ‘source’ /squeezelite-AA:BB:CC:DD:EE:FF zijn, waar ‘AA:BB:CC:"
|
||||
"DD:EE:FF’ staat voor squeezelites MAC-adres."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For sndio 'source' will be a raw recording audio descriptor or a monitoring "
|
||||
"sub-device, e.g. 'rsnd/2' or 'snd/1'. Default: 'default'."
|
||||
msgstr ""
|
||||
"Voor sndio zal ‘source’ een opname-audiobeschrijving of een monitorend "
|
||||
"subapparaat zijn, bijv. ‘rsnd/2’ of ‘snd/1’. Standaardwaarde: ‘default’."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For oss 'source' will be the path to a audio device, e.g. '/dev/dsp2'. "
|
||||
"Default: '/dev/dsp', i.e. the default audio device."
|
||||
msgstr ""
|
||||
"Voor oss zal ‘source’ de locatie van een audioapparaat zijn, bijv. ‘/dev/"
|
||||
"dsp2’. Standaardwaarde: ‘/dev/dsp’, oftewel het standaard audioapparaat."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For jack 'source' will be the name of the JACK server to connect to, e.g. "
|
||||
"'foobar'. Default: 'default'."
|
||||
msgstr ""
|
||||
"Voor jack zal ‘source’ de naam van de JACK-server zijn, bijv. ‘foobar’. "
|
||||
"Standaardwaarde: ‘default’."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sample rate:"
|
||||
msgstr "Samplesnelheid:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for fifo, pipewire, sndio, oss"
|
||||
msgstr "Alleen van toepassing op fifo, pipewire, sndio en oss"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sample bits:"
|
||||
msgstr "Samplebits:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Channels:"
|
||||
msgstr "Aantal kanalen:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for pipewire & cava>=0.10.6, sndio, oss, jack"
|
||||
msgstr "Alleen van toepassing op pipewire en cava>=0.10.6, sndio, oss en jack"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Auto connect:"
|
||||
msgstr "Automatisch verbinden:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for jack"
|
||||
msgstr "Alleen van toepassing op jack"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Active:"
|
||||
msgstr "Actief:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Only for pipewire & cava>=0.10.6. Force the node to always process. Useful "
|
||||
"for monitoring sources when no other application is active."
|
||||
msgstr ""
|
||||
"Alleen van toepassing op pipewire en cava>=0.10.6. Dwing het bijwerken van "
|
||||
"het knooppunt af. Handig voor het monitoren als er geen ander programma "
|
||||
"geopend is."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Remix:"
|
||||
msgstr "Remixen:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Only for pipewire & cava>=0.10.6. Allow to remix audio channels to match "
|
||||
"cava's channel count. Useful for surround sound."
|
||||
msgstr ""
|
||||
"Alleen van toepassing op pipewire en cava>=0.10.6. Sta het remixen van "
|
||||
"audiokanalen toe om overeen te komen met cava's kanalen. Handig voor "
|
||||
"surroundsound."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Virtual:"
|
||||
msgstr "Virtueel:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Only for pipewire & cava>=0.10.6. Set the node to virtual, to avoid "
|
||||
"recording notifications from the DE."
|
||||
msgstr ""
|
||||
"Alleen van toepassing op pipewire en cava>=0.10.6. Maak het knooppunt "
|
||||
"virtueel om opnamemeldingen van de werkomgeving te onderdrukken."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Output"
|
||||
msgstr "Uitvoer"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Visual channels:"
|
||||
msgstr "Visuele kanalen:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"'mono' outputs left to right lowest to highest frequencies.\n"
|
||||
"'stereo' mirrors both channels with low frequencies in center."
|
||||
msgstr ""
|
||||
"‘mono’ geeft uitvoer van links naar rechts, met de laagste tot hoogste "
|
||||
"frequenties;\n"
|
||||
"‘stereo’ geeft uitvoer op beide kanalen, met de laatste frequenties in het "
|
||||
"midden."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Mono channel:"
|
||||
msgstr "Monokanaal:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Display frequencies the other way around"
|
||||
msgstr "Verwissel de frequenties van plek"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Smoothing"
|
||||
msgstr "Vloeiendheid"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Noise reduction:"
|
||||
msgstr "Ruisonderdrukking:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"The raw visualization is very noisy, this factor adjusts the integral and "
|
||||
"gravity filters to keep the signal smooth.\n"
|
||||
"100 will be very slow and smooth, 0 will be fast but noisy."
|
||||
msgstr ""
|
||||
"De standaardvisualisatie bevat erg veel ruis. Met behulp van deze factor kun "
|
||||
"je de filters afstellen om het signaal vloeiend door te laten komen.\n"
|
||||
"100 is erg langzaam, maar wel vloeiend; 0 is snel, maar met veel ruis."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Monstercat:"
|
||||
msgstr "Monstercat:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Enable the so-called \"Monstercat smoothing\" with or without \"waves\"."
|
||||
msgstr ""
|
||||
"Schakel de zogeheten ‘Monstercat-vloeiendheid’ in, met of zonder golven."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Waves"
|
||||
msgstr "Golven"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Equalizer"
|
||||
msgstr "Equalizer"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Enabled:"
|
||||
msgstr "Ingeschakeld:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Adjust frequencies by a multiplication factor, more bands equals more "
|
||||
"precision."
|
||||
msgstr ""
|
||||
"Pas frequenties aan de hand van een vermenigvuldigingsfactoor aan. Meer "
|
||||
"banden = preciezer."
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Auto-hide when idle:"
|
||||
msgstr "Automatisch verbergen na inactiviteit:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "After"
|
||||
msgstr "Na"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "seconds"
|
||||
msgstr "seconden"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Desktop background:"
|
||||
msgstr "Bureaubladachtergrond:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Transparent"
|
||||
msgstr "Doorzichtig"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Transparent with shadow"
|
||||
msgstr "Doorzichtig, met schaduw"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Disable tooltip:"
|
||||
msgstr "Hulpballon uitschakelen"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Disable ToolTip that shows the widget name and description."
|
||||
msgstr "Schakel de hulpballon uit de de widgetnaam en -beschrijving toont."
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Disable left click:"
|
||||
msgstr "Linksklikken uitschakelen:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Applet popup will still be accessible from the right click menu."
|
||||
msgstr "De pop-up is nog toegankelijk via het rechtermuisknopmenu."
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Troubleshooting"
|
||||
msgstr "Probleemoplossing"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Debug mode:"
|
||||
msgstr "Foutopsporingsmodus:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid ""
|
||||
"Print additional messages to the system log. To make it easier to spot "
|
||||
"sizing issues, this will also force full height to the first visualizer bar "
|
||||
"and displays a grid over it."
|
||||
msgstr ""
|
||||
"Toon aanvullende berichten in het systeemlogboek. Ook wordt de eerste "
|
||||
"visualisatiebalk groter gemaakt en voorzien van een rooster, zodat problemen "
|
||||
"makkelijker te zien zijn."
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "height"
|
||||
msgstr "hoogte"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "width"
|
||||
msgstr "breedte"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Style:"
|
||||
msgstr "Stijl:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bars"
|
||||
msgstr "Balken"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Wave"
|
||||
msgstr "Golf"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Blocks"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fill wave"
|
||||
msgstr "Opgevulde golf"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Draw inactive blocks"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Circle mode:"
|
||||
msgstr "Cirkelmodus:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Circle size:"
|
||||
msgstr "Cirkelomvang:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Top"
|
||||
msgstr "Bovenkant"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bottom"
|
||||
msgstr "Onderkant"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Left"
|
||||
msgstr "Links"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Right"
|
||||
msgstr "Rechts"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fill panel %1:"
|
||||
msgstr "Paneel ‘%1’ opvullen:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fixed %1:"
|
||||
msgstr "Vaste %1:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fill panel thickness:"
|
||||
msgstr "Paneelopvulling:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Centered bars:"
|
||||
msgstr "Gecentreerde balken:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Rounded bars:"
|
||||
msgstr "Afgeronde balken:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Line width:"
|
||||
msgstr "Lijnbreedte:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bar width:"
|
||||
msgstr "Balkbreedte:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bar gap:"
|
||||
msgstr "Ruimte tussen balken:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Block height:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Block gap:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Wave Color"
|
||||
msgstr "Golfkleur"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bar Color"
|
||||
msgstr "Balkkleur"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Inactive block color"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Wave Fill Color"
|
||||
msgstr "Opgevulde golfkleur"
|
||||
|
||||
#: ../contents/ui/main.qml
|
||||
msgid "Show support information"
|
||||
msgstr "Ondersteuningsinformatie tonen"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The options 'sample_rate', 'sample_bits', 'channels' and 'autoconnect' "
|
||||
#~ "can be configured for some input methods:"
|
||||
#~ msgstr ""
|
||||
#~ "De opties ‘sample_rate’, ‘sample_bits’, ‘channels’ en ‘autoconnect’ "
|
||||
#~ "kunnen bij sommige invoermethoden nauwkeurig worden afgesteld:"
|
||||
|
||||
#~ msgid "Other methods ignore these settings."
|
||||
#~ msgstr "Andere methoden negeren deze instellingen."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "For 'sndio' and 'oss' they are only preferred values, i.e. if the values "
|
||||
#~ "are not supported by the chosen audio device, the device will use other "
|
||||
#~ "supported values instead."
|
||||
#~ msgstr ""
|
||||
#~ "Voor ‘sndio’ en ‘oss’ zijn dit slechts voorkeurswaarden. Als de waarden "
|
||||
#~ "niet ondersteund worden door het gekozen audioapparaat, zullen de andere, "
|
||||
#~ "ondersteunde waarden worden gebruikt."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Adjust frequencies by a multiplication factor, more bars equals more "
|
||||
#~ "precision."
|
||||
#~ msgstr ""
|
||||
#~ "Pas de frequenties aan met een vermenigvuldigingsfactor. Meer balken = "
|
||||
#~ "meer precisie."
|
||||
|
||||
#~ msgid "Waves:"
|
||||
#~ msgstr "Golven:"
|
||||
+747
@@ -0,0 +1,747 @@
|
||||
# Translation of visualizer in ru
|
||||
# Copyright (C) 2025
|
||||
# This file is distributed under the same license as the visualizer package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: visualizer\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/luisbocanegra/kurve\n"
|
||||
"POT-Creation-Date: 2025-12-13 18:30+0000\n"
|
||||
"PO-Revision-Date: 2025-11-15 03:51+0200\n"
|
||||
"Last-Translator: Mykjailo Aleksieiev <mishanya.bigimot@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: ru\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 3.8\n"
|
||||
|
||||
#: ../metadata.json
|
||||
msgid "Kurve"
|
||||
msgstr "Kurve"
|
||||
|
||||
#: ../metadata.json
|
||||
msgid "Audio visualizer powered by CAVA"
|
||||
msgstr "Аудио-визуализатор на базе CAVA"
|
||||
|
||||
#: ../contents/config/config.qml
|
||||
msgid "Visualizer"
|
||||
msgstr "Визуализатор"
|
||||
|
||||
#: ../contents/config/config.qml ../contents/ui/configCava.qml
|
||||
msgid "General"
|
||||
msgstr "Основное"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml
|
||||
msgid "Oh no! Something went wrong"
|
||||
msgstr "О нет! Что-то пошло не так"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml ../contents/ui/configCava.qml
|
||||
#: ../contents/ui/main.qml
|
||||
msgid "Stop CAVA"
|
||||
msgstr "Остановить CAVA"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml ../contents/ui/configCava.qml
|
||||
#: ../contents/ui/main.qml
|
||||
msgid "Start CAVA"
|
||||
msgstr "Запустить CAVA"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml
|
||||
msgid "Copy to clipboard"
|
||||
msgstr "Скопировать в буфер обмена"
|
||||
|
||||
#: ../contents/ui/components/ColorPickerGradientList.qml
|
||||
#: ../contents/ui/components/ColorPickerList.qml
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Widget background"
|
||||
msgstr "Задний фон виджета"
|
||||
|
||||
#: ../contents/ui/components/Eq.qml
|
||||
msgid "Remove band"
|
||||
msgstr "Удалить полосу"
|
||||
|
||||
#: ../contents/ui/components/Eq.qml
|
||||
msgid "Add band"
|
||||
msgstr "Добавить полосу"
|
||||
|
||||
#: ../contents/ui/components/Eq.qml
|
||||
msgid "Flat response"
|
||||
msgstr "Плоская АЧХ"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color"
|
||||
msgstr "Цвет"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Animation:"
|
||||
msgstr "Анимация:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Interval (ms):"
|
||||
msgstr "Интервал (мс):"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Smoothing (ms):"
|
||||
msgstr "Сглаживание (мс):"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color source:"
|
||||
msgstr "Источник цвета:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Custom"
|
||||
msgstr "Свой источник"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "A fixed custom color"
|
||||
msgstr "Свой фиксированный цвет"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "System"
|
||||
msgstr "Система"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color that updates with your System theme"
|
||||
msgstr "Цвет который обновляется вместе с вашей темой системы"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Custom list"
|
||||
msgstr "Свой список"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid ""
|
||||
"Define a list of colors that will be applied to all the elements, wraps "
|
||||
"around if there are more elements than colors"
|
||||
msgstr ""
|
||||
"Задайте список цветов, которые будут применяться ко всем элементам; если "
|
||||
"элементов больше, чем цветов, список повторяется"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Random"
|
||||
msgstr "Случайный"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Random color for each element"
|
||||
msgstr "Случайный цвет для каждого элемента"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Follow"
|
||||
msgstr "Следовать"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Follow the color of a parent element"
|
||||
msgstr "Следовать цвету родительского элемента"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Gradient"
|
||||
msgstr "Градиент"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Horizontal or vertical customizable color gradient"
|
||||
msgstr "Горизонтальный или вертикальный цветовой градиент"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Image"
|
||||
msgstr "Изображение"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid ""
|
||||
"High resolution images can slow down the desktop when the panel or widget "
|
||||
"size changes!"
|
||||
msgstr ""
|
||||
"Изображения высокого качества могут замедлить рабочий стол, когда размер "
|
||||
"панели или виджета меняется!"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Hue"
|
||||
msgstr "Оттенок"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Automatically shifted color for each bar"
|
||||
msgstr "Автоматически меняющийся цвет для каждого столбика"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Element:"
|
||||
msgstr "Элемент:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Panel background"
|
||||
msgstr "Задний фон панели"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Tray widget background"
|
||||
msgstr "Задний фон виджета в трее"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Positioning:"
|
||||
msgstr "Расположение:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Stretch"
|
||||
msgstr "Растянутое"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Tile"
|
||||
msgstr "Плитка"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Scaled and Cropped"
|
||||
msgstr "Масштабированный и обрезанный"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Image:"
|
||||
msgstr "Изображение:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Pick a image file"
|
||||
msgstr "Выберите файл изображения"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Image files"
|
||||
msgstr "Файлы изображений"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "All files"
|
||||
msgstr "Все файлы"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color:"
|
||||
msgstr "Цвет:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color set:"
|
||||
msgstr "Набор цветов:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Colors:"
|
||||
msgstr "Цвета:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Range:"
|
||||
msgstr "Диапазон:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml ../contents/ui/configVisualizer.qml
|
||||
msgid "Orientation:"
|
||||
msgstr "Ориентация:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Horizontal"
|
||||
msgstr "Горизонтальная"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Vertical"
|
||||
msgstr "Вертикальная"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Gradient:"
|
||||
msgstr "Градиент:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml ../contents/ui/configCava.qml
|
||||
msgid "Reverse:"
|
||||
msgstr "Реверс:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Display colors the other way around"
|
||||
msgstr "Отображает цвета в обратном порядке"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Alpha:"
|
||||
msgstr "Прозрачность:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Contrast Correction"
|
||||
msgstr "Коррекция контраста"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Saturation:"
|
||||
msgstr "Насыщенность:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Lightness:"
|
||||
msgstr "Яркость:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Framerate:"
|
||||
msgstr "Частота кадров:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Number of bars:"
|
||||
msgstr "Количество столбиков:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Automatically calculated for the current visualizer style."
|
||||
msgstr "Автоматически рассчитано под текущий стиль визуализатора."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Automatic sensitivity:"
|
||||
msgstr "Авто-чувствительность:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Attempt to decrease sensitivity if the bars peak."
|
||||
msgstr ""
|
||||
"Пытается понизить чувствительность, если все столбики на пиковой высоте."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sensitivity:"
|
||||
msgstr "Чувствительность:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Manual sensitivity in %.\n"
|
||||
"If autosens is enabled, this will only be the initial value"
|
||||
msgstr ""
|
||||
"Ручная чувствительность в %\n"
|
||||
"Если включена авто-чувствительность, это будет лишь изначальным значением"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Frequency range (Hz):"
|
||||
msgstr "Частотный диапазон (Гц):"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Min"
|
||||
msgstr "Мин"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Max"
|
||||
msgstr "Макс"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Lower and higher cutoff frequencies for lowest and highest bars, the "
|
||||
"bandwidth of the visualizer.\n"
|
||||
"Note: Cava will automatically increase the higher cutoff if a too low band "
|
||||
"is specified."
|
||||
msgstr ""
|
||||
"Нижняя и верхняя частоты среза для самой низкой и самой высокой полосы, "
|
||||
"ширина полос визуализатора.\n"
|
||||
"Примечание: Cava автоматически увеличит верхнюю частоту среза, если указана "
|
||||
"слишком низкая полоса."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sleep timer (seconds):"
|
||||
msgstr "Таймер сна (в секундах):"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Seconds with no input before cava goes to sleep mode.\n"
|
||||
"Cava will not perform FFT and only check for input once per second."
|
||||
msgstr ""
|
||||
"Время в секундах без ввода, после которого CAVA отправится в режим сна.\n"
|
||||
"CAVA не будет осуществлять БПФ, и просто проверяет ввод раз в секунду."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Pause on:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Full screen window"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Maximized window"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Input"
|
||||
msgstr "Ввод"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Method:"
|
||||
msgstr "Метод:"
|
||||
|
||||
#: ../contents/ui/configCava.qml ../contents/ui/configGeneral.qml
|
||||
msgid "Default"
|
||||
msgstr "По умолчанию"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Audio capturing method.\n"
|
||||
"Defaults to 'oss', 'pipewire', 'sndio', 'jack', 'pulse', 'alsa', 'portaudio' "
|
||||
"or 'fifo', in that order, dependent on what support cava was built with.\n"
|
||||
msgstr ""
|
||||
"Метод захвата аудио.\n"
|
||||
"По умолчанию будет выбран 'oss', 'pipewire', 'sndio', 'jack', 'pulse', "
|
||||
"'alsa', 'portaudio' или 'fifo', в таком порядке, в зависимости от опций, с "
|
||||
"какими был собран CAVA.\n"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Source:"
|
||||
msgstr "Источник:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For pulseaudio and pipewire 'source' will be the source. Default: 'auto', "
|
||||
"which uses the monitor source of the default sink (all pulseaudio "
|
||||
"sinks(outputs) have 'monitor' sources(inputs) associated with them)."
|
||||
msgstr ""
|
||||
"Для pulseaudio и pipewire ‘source’ будет являться источником. По умолчанию: "
|
||||
"‘auto’, что использует мониторинг источника стандартного выхода (у всех "
|
||||
"выходов PulseAudio есть соответствующие ‘monitor’ источники(вводы))."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For pipewire 'source' will be the object name or object.serial of the device "
|
||||
"to capture from. Both input and output devices are supported."
|
||||
msgstr ""
|
||||
"Для pipewire ‘source’ будет именем объекта или object.serial устройства, с "
|
||||
"которого осуществляется захват. Поддерживаются как входные, так и выходные "
|
||||
"устройства."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "For alsa 'source' will be the capture device."
|
||||
msgstr "Для alsa 'source' будет устройством захвата."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "For fifo 'source' will be the path to fifo-file."
|
||||
msgstr "Для fifo 'source' будет путём к fifo-файлу."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For shmem 'source' will be /squeezelite-AA:BB:CC:DD:EE:FF where 'AA:BB:CC:DD:"
|
||||
"EE:FF' will be squeezelite's MAC address."
|
||||
msgstr ""
|
||||
"Для shmem 'source' будет /squeezelite-AA:BB:CC:DD:EE:FF, где AA:BB:CC:DD:EE:"
|
||||
"FF' это MAC-адрес squeezelite."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For sndio 'source' will be a raw recording audio descriptor or a monitoring "
|
||||
"sub-device, e.g. 'rsnd/2' or 'snd/1'. Default: 'default'."
|
||||
msgstr ""
|
||||
"Для sndio ‘source’ — это дескриптор записи или подустройство мониторинга, "
|
||||
"например, 'rsnd/2' или 'snd/1'. По умолчанию: 'default'."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For oss 'source' will be the path to a audio device, e.g. '/dev/dsp2'. "
|
||||
"Default: '/dev/dsp', i.e. the default audio device."
|
||||
msgstr ""
|
||||
"Для oss 'source' будет путём к устройству аудио, например '/dev/dsp2'. По "
|
||||
"умолчанию: '/dev/dsp', или устройство аудио по умолчанию."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For jack 'source' will be the name of the JACK server to connect to, e.g. "
|
||||
"'foobar'. Default: 'default'."
|
||||
msgstr ""
|
||||
"Для jack 'source' будет именем сервера JACK к котому надо подключиться, "
|
||||
"например 'foobar'. По умолчанию: 'default'."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sample rate:"
|
||||
msgstr "Частота дискретизации:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for fifo, pipewire, sndio, oss"
|
||||
msgstr "Только для fifo, pipewire, sndio, oss"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sample bits:"
|
||||
msgstr "Битовая глубина:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Channels:"
|
||||
msgstr "Каналы:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for pipewire & cava>=0.10.6, sndio, oss, jack"
|
||||
msgstr "Только для pipewire & cava>=0.10.6, sndio, jack"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Auto connect:"
|
||||
msgstr "Авто-подключение:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for jack"
|
||||
msgstr "Только для jack"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Active:"
|
||||
msgstr "Активный:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Only for pipewire & cava>=0.10.6. Force the node to always process. Useful "
|
||||
"for monitoring sources when no other application is active."
|
||||
msgstr ""
|
||||
"Только для pipewire & cava>=0.10.6. Принудительно заставляет узел (node) "
|
||||
"всегда обрабатывать сигнал. Полезно для мониторинга источников, когда другие "
|
||||
"приложения не активны."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Remix:"
|
||||
msgstr "Ремикс:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Only for pipewire & cava>=0.10.6. Allow to remix audio channels to match "
|
||||
"cava's channel count. Useful for surround sound."
|
||||
msgstr ""
|
||||
"Только для pipewire & cava>=0.10.6. Разрешить перемешивание аудиоканалов для "
|
||||
"соответствия количеству каналов Cava. Полезно для многоканального звука."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Virtual:"
|
||||
msgstr "Виртуальный:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Only for pipewire & cava>=0.10.6. Set the node to virtual, to avoid "
|
||||
"recording notifications from the DE."
|
||||
msgstr ""
|
||||
"Только для pipewire & cava>=0.10.6. Переключить узел в виртуальный, чтобы "
|
||||
"избежать записи звука уведомлений."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Output"
|
||||
msgstr "Вывод"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Visual channels:"
|
||||
msgstr "Визуальные каналы:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"'mono' outputs left to right lowest to highest frequencies.\n"
|
||||
"'stereo' mirrors both channels with low frequencies in center."
|
||||
msgstr ""
|
||||
"В режиме ‘mono’ выводится слева направо от низких к высоким частотам.\n"
|
||||
"В режиме ‘stereo’ оба канала отображаются зеркально, низкие частоты "
|
||||
"находятся по центру."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Mono channel:"
|
||||
msgstr "Моно-канал:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Display frequencies the other way around"
|
||||
msgstr "Отображать частоты наоборот"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Smoothing"
|
||||
msgstr "Сглаживание"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Noise reduction:"
|
||||
msgstr "Шумоподавление:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"The raw visualization is very noisy, this factor adjusts the integral and "
|
||||
"gravity filters to keep the signal smooth.\n"
|
||||
"100 will be very slow and smooth, 0 will be fast but noisy."
|
||||
msgstr ""
|
||||
"Сырая визуализация очень шумная, этот параметр настраивает интегральный и "
|
||||
"гравитационный фильтры, чтобы удерживать сигнал плавным.\n"
|
||||
"Значение 100 сделает движение очень медленным и гладким, значение 0 — "
|
||||
"быстрым, но шумным."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Monstercat:"
|
||||
msgstr "Monstercat:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Enable the so-called \"Monstercat smoothing\" with or without \"waves\"."
|
||||
msgstr "Включает так называемое \"Monstercat сглаживание\" с или без \"волн\"."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Waves"
|
||||
msgstr "Волны"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Equalizer"
|
||||
msgstr "Эквалайзер"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Enabled:"
|
||||
msgstr "Включён:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Adjust frequencies by a multiplication factor, more bands equals more "
|
||||
"precision."
|
||||
msgstr ""
|
||||
"Корректирует частоты с помощью коэффициента умножения; большее число полос "
|
||||
"означает более высокую точность."
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Auto-hide when idle:"
|
||||
msgstr "Автосокрытие при неактивности:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "After"
|
||||
msgstr "После"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "seconds"
|
||||
msgstr "секунд"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Desktop background:"
|
||||
msgstr "Задний фон рабочего стола:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Transparent"
|
||||
msgstr "Прозрачный"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Transparent with shadow"
|
||||
msgstr "Прозрачный с тенью"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Disable tooltip:"
|
||||
msgstr "Отключить всплывающую подсказку:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Disable ToolTip that shows the widget name and description."
|
||||
msgstr ""
|
||||
"Отключает всплывающую подсказку, которая показывает имя виджета и его "
|
||||
"описание."
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Disable left click:"
|
||||
msgstr "Отключить левый клик:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Applet popup will still be accessible from the right click menu."
|
||||
msgstr ""
|
||||
"Всплывающее окно апплета всё ещё будет доступно из контекстного меню по "
|
||||
"правому клику."
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Troubleshooting"
|
||||
msgstr "Решение проблем"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Debug mode:"
|
||||
msgstr "Режим отладки:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid ""
|
||||
"Print additional messages to the system log. To make it easier to spot "
|
||||
"sizing issues, this will also force full height to the first visualizer bar "
|
||||
"and displays a grid over it."
|
||||
msgstr ""
|
||||
"Выводить дополнительные сообщения в системный журнал. Чтобы упростить "
|
||||
"обнаружение проблем с размерами, этот режим также принудительно "
|
||||
"устанавливает полную высоту для первой полосы визуализатора и отображает "
|
||||
"поверх неё сетку."
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "height"
|
||||
msgstr "высота"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "width"
|
||||
msgstr "ширина"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Style:"
|
||||
msgstr "Стиль:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bars"
|
||||
msgstr "Столбики"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Wave"
|
||||
msgstr "Волны"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Blocks"
|
||||
msgstr "Блоки"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fill wave"
|
||||
msgstr "Заполнить волну"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Draw inactive blocks"
|
||||
msgstr "Рисовать неактивные блоки"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Circle mode:"
|
||||
msgstr "Круговой режим:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Circle size:"
|
||||
msgstr "Размер круга:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Top"
|
||||
msgstr "Сверху"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bottom"
|
||||
msgstr "Снизу"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Left"
|
||||
msgstr "Слева"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Right"
|
||||
msgstr "Справа"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fill panel %1:"
|
||||
msgstr "Заполнить панель %1:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fixed %1:"
|
||||
msgstr "Фиксированная %1:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fill panel thickness:"
|
||||
msgstr "Заполнить толщину панели:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Centered bars:"
|
||||
msgstr "Центрированные столбики:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Rounded bars:"
|
||||
msgstr "Закруглённые столбики:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Line width:"
|
||||
msgstr "Ширина линии:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bar width:"
|
||||
msgstr "Ширина столбика:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bar gap:"
|
||||
msgstr "Расстояние между столбиками:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Block height:"
|
||||
msgstr "Высота блока:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Block gap:"
|
||||
msgstr "Расстояние между блоками:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Wave Color"
|
||||
msgstr "Цвет волны"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bar Color"
|
||||
msgstr "Цвет столбика"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Inactive block color"
|
||||
msgstr "Цвет неактивного блока"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Wave Fill Color"
|
||||
msgstr "Цвет заливки волны"
|
||||
|
||||
#: ../contents/ui/main.qml
|
||||
msgid "Show support information"
|
||||
msgstr "Отображать информацию поддержки"
|
||||
+768
@@ -0,0 +1,768 @@
|
||||
# Translation of visualizer in sv
|
||||
# Copyright (C) 2025
|
||||
# This file is distributed under the same license as the visualizer package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: visualizer\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/luisbocanegra/kurve\n"
|
||||
"POT-Creation-Date: 2025-12-13 18:30+0000\n"
|
||||
"PO-Revision-Date: 2025-11-07 15:03+0000\n"
|
||||
"Last-Translator: Mathias Mårtensson <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: sv\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 3.6\n"
|
||||
|
||||
#: ../metadata.json
|
||||
msgid "Kurve"
|
||||
msgstr "Kurve"
|
||||
|
||||
#: ../metadata.json
|
||||
msgid "Audio visualizer powered by CAVA"
|
||||
msgstr "Ljudvisualisering som använder CAVA"
|
||||
|
||||
#: ../contents/config/config.qml
|
||||
msgid "Visualizer"
|
||||
msgstr "Visualiserare"
|
||||
|
||||
#: ../contents/config/config.qml ../contents/ui/configCava.qml
|
||||
msgid "General"
|
||||
msgstr "Allmänt"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml
|
||||
msgid "Oh no! Something went wrong"
|
||||
msgstr "Åh nej! Något gick fel"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml ../contents/ui/configCava.qml
|
||||
#: ../contents/ui/main.qml
|
||||
msgid "Stop CAVA"
|
||||
msgstr "Stoppa CAVA"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml ../contents/ui/configCava.qml
|
||||
#: ../contents/ui/main.qml
|
||||
msgid "Start CAVA"
|
||||
msgstr "Starta CAVA"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml
|
||||
msgid "Copy to clipboard"
|
||||
msgstr "Kopiera till klippbordet"
|
||||
|
||||
#: ../contents/ui/components/ColorPickerGradientList.qml
|
||||
#: ../contents/ui/components/ColorPickerList.qml
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Widget background"
|
||||
msgstr "Widgetbakgrund"
|
||||
|
||||
#: ../contents/ui/components/Eq.qml
|
||||
msgid "Remove band"
|
||||
msgstr "Ta bort band"
|
||||
|
||||
#: ../contents/ui/components/Eq.qml
|
||||
msgid "Add band"
|
||||
msgstr "Lägg till band"
|
||||
|
||||
#: ../contents/ui/components/Eq.qml
|
||||
msgid "Flat response"
|
||||
msgstr "Platt kurva"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color"
|
||||
msgstr "Färg"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Animation:"
|
||||
msgstr "Animation:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Interval (ms):"
|
||||
msgstr "Intervall (ms):"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Smoothing (ms):"
|
||||
msgstr "Utjämning (ms):"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color source:"
|
||||
msgstr "Färgkälla:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Custom"
|
||||
msgstr "Anpassad"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "A fixed custom color"
|
||||
msgstr "En fast anpassad färg"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "System"
|
||||
msgstr "System"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color that updates with your System theme"
|
||||
msgstr "Färg som följer ditt systemtema"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Custom list"
|
||||
msgstr "Anpassad lista"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid ""
|
||||
"Define a list of colors that will be applied to all the elements, wraps "
|
||||
"around if there are more elements than colors"
|
||||
msgstr ""
|
||||
"Definierar en lista av färger som appliceras på alla element, upprepar om "
|
||||
"det finns fler element än färger"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Random"
|
||||
msgstr "Slumpmässig"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Random color for each element"
|
||||
msgstr "Slumpmässig färg för varje element"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Follow"
|
||||
msgstr "Följer"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Follow the color of a parent element"
|
||||
msgstr "Följer färgen på ett överordnat element"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Gradient"
|
||||
msgstr "Färgövergång"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Horizontal or vertical customizable color gradient"
|
||||
msgstr "Horisontala eller vertikala anpassade färgövergångar"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Image"
|
||||
msgstr "Bild"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid ""
|
||||
"High resolution images can slow down the desktop when the panel or widget "
|
||||
"size changes!"
|
||||
msgstr ""
|
||||
"Hög upplösning på bilder kan ge sämre prestanda på skrivbordet när panelens "
|
||||
"eller widgetens storlek ändras!"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Hue"
|
||||
msgstr "Nyans"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Automatically shifted color for each bar"
|
||||
msgstr "Automatiskt ändrar färg för varje band"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Element:"
|
||||
msgstr "Element:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Panel background"
|
||||
msgstr "Panelbakgrund"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Tray widget background"
|
||||
msgstr "Tray Widgetbakgrund"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Positioning:"
|
||||
msgstr "Positionering:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Stretch"
|
||||
msgstr "Sträck"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Tile"
|
||||
msgstr "Bricka"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Scaled and Cropped"
|
||||
msgstr "Skalad och beskuren"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Image:"
|
||||
msgstr "Bild:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Pick a image file"
|
||||
msgstr "Välj en bildfil"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Image files"
|
||||
msgstr "Bildfiler"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "All files"
|
||||
msgstr "Alla filer"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color:"
|
||||
msgstr "Färg:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color set:"
|
||||
msgstr "Färguppsättning:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Colors:"
|
||||
msgstr "Färger:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Range:"
|
||||
msgstr "Räckvidd:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml ../contents/ui/configVisualizer.qml
|
||||
msgid "Orientation:"
|
||||
msgstr "Orientering:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Horizontal"
|
||||
msgstr "Horisontell"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Vertical"
|
||||
msgstr "Vertikal"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Gradient:"
|
||||
msgstr "Färgövergång:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml ../contents/ui/configCava.qml
|
||||
msgid "Reverse:"
|
||||
msgstr "Omvänd:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Display colors the other way around"
|
||||
msgstr "Visa färger i omvänd ordning"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Alpha:"
|
||||
msgstr "Alfa:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Contrast Correction"
|
||||
msgstr "Kontrastkorrigering"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Saturation:"
|
||||
msgstr "Mättnad:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Lightness:"
|
||||
msgstr "Ljusstyrka:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Framerate:"
|
||||
msgstr "Bildfrekvens:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Number of bars:"
|
||||
msgstr "Antal band:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Automatically calculated for the current visualizer style."
|
||||
msgstr "Automatiskt uträknad för den valda visualiseringsstilen."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Automatic sensitivity:"
|
||||
msgstr "Automatisk känslighet:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Attempt to decrease sensitivity if the bars peak."
|
||||
msgstr "Försöker att minska känsligheten om banden når sin topp."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sensitivity:"
|
||||
msgstr "Känslighet:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Manual sensitivity in %.\n"
|
||||
"If autosens is enabled, this will only be the initial value"
|
||||
msgstr ""
|
||||
"Manuell känslighet i %.\n"
|
||||
"Om automatisk känslighet är aktiverat kommer detta endast att vara det "
|
||||
"initiala värdet"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Frequency range (Hz):"
|
||||
msgstr "Frekvensomfång (Hz):"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Min"
|
||||
msgstr "Min"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Max"
|
||||
msgstr "Max"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Lower and higher cutoff frequencies for lowest and highest bars, the "
|
||||
"bandwidth of the visualizer.\n"
|
||||
"Note: Cava will automatically increase the higher cutoff if a too low band "
|
||||
"is specified."
|
||||
msgstr ""
|
||||
" Visualiserarens bandbredd för lägsta och högsta gränsfrekvenser för lägsta "
|
||||
"och högsta band.\n"
|
||||
"Observera att Cava automatiskt höjer till en högre gränsfrekvens om ett för "
|
||||
"lågt frekvensband läggs till."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sleep timer (seconds):"
|
||||
msgstr "Sleep timer (sekunder):"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Seconds with no input before cava goes to sleep mode.\n"
|
||||
"Cava will not perform FFT and only check for input once per second."
|
||||
msgstr ""
|
||||
"Sekunder utan inmatning innan Cava går in i viloläge.\n"
|
||||
"Cava utför inte FFT och kontrollerar bara inmatning en gång per sekund."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Pause on:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Full screen window"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Maximized window"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Input"
|
||||
msgstr "Indata"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Method:"
|
||||
msgstr "Metod:"
|
||||
|
||||
#: ../contents/ui/configCava.qml ../contents/ui/configGeneral.qml
|
||||
msgid "Default"
|
||||
msgstr "Förvald"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Audio capturing method.\n"
|
||||
"Defaults to 'oss', 'pipewire', 'sndio', 'jack', 'pulse', 'alsa', 'portaudio' "
|
||||
"or 'fifo', in that order, dependent on what support cava was built with.\n"
|
||||
msgstr ""
|
||||
"Ljudinspelningsmetod.\n"
|
||||
"Standardvärdena är 'oss', 'pipewire', 'sndio', 'jack', 'pulse', 'alsa', "
|
||||
"'portaudio' eller 'fifo', i den ordningen, beroende på vilket stöd Cava "
|
||||
"kompilerats för.\n"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Source:"
|
||||
msgstr "Källa:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For pulseaudio and pipewire 'source' will be the source. Default: 'auto', "
|
||||
"which uses the monitor source of the default sink (all pulseaudio "
|
||||
"sinks(outputs) have 'monitor' sources(inputs) associated with them)."
|
||||
msgstr ""
|
||||
"För pulseaudio och pipewire kommer 'source' att vara källan. Förvald: "
|
||||
"'auto', som använder sig av källan för förvald sink (alla pulseaudio-sinkar "
|
||||
"(utgångar) har 'monitor'-källor (ingångar) associerade med sig)."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For pipewire 'source' will be the object name or object.serial of the device "
|
||||
"to capture from. Both input and output devices are supported."
|
||||
msgstr ""
|
||||
"För pipewire kommer 'source' att vara objektnamnet eller object.serial för "
|
||||
"den enhet som det hämtas från. Både in- och utdataenheter stöds."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "For alsa 'source' will be the capture device."
|
||||
msgstr "För alsa kommer 'source' att vara inspelningsenheten."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "For fifo 'source' will be the path to fifo-file."
|
||||
msgstr "För fifo kommer 'source' att vara sökvägen till fifo-filen."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For shmem 'source' will be /squeezelite-AA:BB:CC:DD:EE:FF where 'AA:BB:CC:DD:"
|
||||
"EE:FF' will be squeezelite's MAC address."
|
||||
msgstr ""
|
||||
"För shmem kommer 'source' att vara /squeezelite-AA:BB:CC:DD:EE:FF där 'AA:BB:"
|
||||
"CC:DD:EE:FF' är squeezelites MAC-adress."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For sndio 'source' will be a raw recording audio descriptor or a monitoring "
|
||||
"sub-device, e.g. 'rsnd/2' or 'snd/1'. Default: 'default'."
|
||||
msgstr ""
|
||||
"För sndio kommer 'source' att vara en rå inspelningsenhet eller en "
|
||||
"underordnad övervakningsenhet, t.ex. 'rsnd/2' eller 'snd/1'. Standard: "
|
||||
"'default'."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For oss 'source' will be the path to a audio device, e.g. '/dev/dsp2'. "
|
||||
"Default: '/dev/dsp', i.e. the default audio device."
|
||||
msgstr ""
|
||||
"För oss kommer 'source' att vara sökvägen till en ljudenhet, t.ex. '/dev/"
|
||||
"dsp2'. Standard: '/dev/dsp', d.v.s. standardljudenheten."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For jack 'source' will be the name of the JACK server to connect to, e.g. "
|
||||
"'foobar'. Default: 'default'."
|
||||
msgstr ""
|
||||
"För jack kommer 'source' att vara namnet på JACK-servern att ansluta till, t."
|
||||
"ex. 'foobar'. Standard: 'default'."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sample rate:"
|
||||
msgstr "Samplingsfrekvens:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for fifo, pipewire, sndio, oss"
|
||||
msgstr "Endast för fifo, pipewire, sndio, oss"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sample bits:"
|
||||
msgstr "bitdjup:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Channels:"
|
||||
msgstr "Kanaler:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for pipewire & cava>=0.10.6, sndio, oss, jack"
|
||||
msgstr "Endast för pipewire & cava>=0.10.6, sndio, oss, jack"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Auto connect:"
|
||||
msgstr "Automatisk anslutning:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for jack"
|
||||
msgstr "Endast för jack"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Active:"
|
||||
msgstr "Aktiv:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Only for pipewire & cava>=0.10.6. Force the node to always process. Useful "
|
||||
"for monitoring sources when no other application is active."
|
||||
msgstr ""
|
||||
"Endast för pipewire & cava>=0.10.6. Tvinga noden att alltid bearbeta. "
|
||||
"Användbart för att övervaka källor när ingen annan applikation är aktiv."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Remix:"
|
||||
msgstr "Remix:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Only for pipewire & cava>=0.10.6. Allow to remix audio channels to match "
|
||||
"cava's channel count. Useful for surround sound."
|
||||
msgstr ""
|
||||
"Endast för pipewire & cava>=0.10.6. Tillåter att remixa ljudkanaler för att "
|
||||
"matcha Cavas kanalantal. Användbart för surroundljud."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Virtual:"
|
||||
msgstr "Virtuell:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Only for pipewire & cava>=0.10.6. Set the node to virtual, to avoid "
|
||||
"recording notifications from the DE."
|
||||
msgstr ""
|
||||
"Endast för pipewire & cava>=0.10.6. Ställ in noden på virtuell för att "
|
||||
"undvika att spela in aviseringar från skrivbordsmiljön."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Output"
|
||||
msgstr "Utdataenhet"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Visual channels:"
|
||||
msgstr "Visuella kanaler:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"'mono' outputs left to right lowest to highest frequencies.\n"
|
||||
"'stereo' mirrors both channels with low frequencies in center."
|
||||
msgstr ""
|
||||
"'mono' återger från vänster till höger, lägsta till högsta frekvenser.\n"
|
||||
"'stereo' speglar båda kanalerna med de låga frekvenser i mitten."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Mono channel:"
|
||||
msgstr "Monokanal:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Display frequencies the other way around"
|
||||
msgstr "Återger frekvenser omvänt"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Smoothing"
|
||||
msgstr "Utjämning"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Noise reduction:"
|
||||
msgstr "Brusreducering:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"The raw visualization is very noisy, this factor adjusts the integral and "
|
||||
"gravity filters to keep the signal smooth.\n"
|
||||
"100 will be very slow and smooth, 0 will be fast but noisy."
|
||||
msgstr ""
|
||||
"Den råa visualiseringen är mycket brusig, denna faktor justerar integral- "
|
||||
"och gravitationsfiltren så att signalen hålls jämn.\n"
|
||||
"100 kommer att vara väldigt långsam och jämn, 0 kommer att vara snabb men "
|
||||
"brusig."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Monstercat:"
|
||||
msgstr "Monstercat:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Enable the so-called \"Monstercat smoothing\" with or without \"waves\"."
|
||||
msgstr ""
|
||||
"Aktivera den så kallade \"Monstercat-utjämningen\" med eller utan \"Vågor\"."
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Waves"
|
||||
msgstr "Vågor"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Equalizer"
|
||||
msgstr "Equalizer"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Enabled:"
|
||||
msgstr "Aktiverad:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Adjust frequencies by a multiplication factor, more bands equals more "
|
||||
"precision."
|
||||
msgstr ""
|
||||
"Justera frekvenserna med en multiplikationsfaktor, desto fler band, desto "
|
||||
"högre precision."
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Auto-hide when idle:"
|
||||
msgstr "Dölj automatiskt vid inaktivitet:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "After"
|
||||
msgstr "Efter"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "seconds"
|
||||
msgstr "sekunder"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Desktop background:"
|
||||
msgstr "Bakgrundsfärg:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Transparent"
|
||||
msgstr "Transparent"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Transparent with shadow"
|
||||
msgstr "Transparent med skugga"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Disable tooltip:"
|
||||
msgstr "Inaktivera verktygstips:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Disable ToolTip that shows the widget name and description."
|
||||
msgstr "Inaktivera verktygstips som visar widgetens namn och beskrivning."
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Disable left click:"
|
||||
msgstr "Inaktivera vänsterklick:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Applet popup will still be accessible from the right click menu."
|
||||
msgstr ""
|
||||
"Applet-popupen kommer fortfarande att vara tillgänglig från högerklicksmenyn."
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Troubleshooting"
|
||||
msgstr "Felsökning"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Debug mode:"
|
||||
msgstr "Felsökningsläge:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid ""
|
||||
"Print additional messages to the system log. To make it easier to spot "
|
||||
"sizing issues, this will also force full height to the first visualizer bar "
|
||||
"and displays a grid over it."
|
||||
msgstr ""
|
||||
"Skriv ut ytterligare meddelanden till systemloggen. För att göra det lättare "
|
||||
"att upptäcka storleksproblem, detta kommer också att tvinga fram full höjd "
|
||||
"på det första visualiseringsfältet och visar ett rutnät över det."
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "height"
|
||||
msgstr "höjd"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "width"
|
||||
msgstr "bredd"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Style:"
|
||||
msgstr "Stil:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bars"
|
||||
msgstr "Band"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Wave"
|
||||
msgstr "Vågor"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Blocks"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fill wave"
|
||||
msgstr "Fyll vågor"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Draw inactive blocks"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Circle mode:"
|
||||
msgstr "Cirkelläge:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Circle size:"
|
||||
msgstr "Cirkelstorlek:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Top"
|
||||
msgstr "Topp"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bottom"
|
||||
msgstr "Botten"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Left"
|
||||
msgstr "Vänster"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Right"
|
||||
msgstr "Höger"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fill panel %1:"
|
||||
msgstr "Fyll panelens %1:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fixed %1:"
|
||||
msgstr "Fixerad %1:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fill panel thickness:"
|
||||
msgstr "Fyll panelens tjocklek:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Centered bars:"
|
||||
msgstr "Centrerade band:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Rounded bars:"
|
||||
msgstr "Rundade band:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Line width:"
|
||||
msgstr "Linjebredd:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bar width:"
|
||||
msgstr "Bandens bredd:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bar gap:"
|
||||
msgstr "Bandens mellanrum:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Block height:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Block gap:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Wave Color"
|
||||
msgstr "Vågfärg"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bar Color"
|
||||
msgstr "Bandfärg"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Inactive block color"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Wave Fill Color"
|
||||
msgstr "Vågfyllningsfärg"
|
||||
|
||||
#: ../contents/ui/main.qml
|
||||
msgid "Show support information"
|
||||
msgstr "Visa supportinformation"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The options 'sample_rate', 'sample_bits', 'channels' and 'autoconnect' "
|
||||
#~ "can be configured for some input methods:"
|
||||
#~ msgstr ""
|
||||
#~ "Alternativen 'sample_rate', 'sample_bits', 'channels' och 'autoconnect' "
|
||||
#~ "kan konfigureras för vissa inmatningsmetoder:"
|
||||
|
||||
#~ msgid "Other methods ignore these settings."
|
||||
#~ msgstr "Andra metoder ignorerar dessa inställningar."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "For 'sndio' and 'oss' they are only preferred values, i.e. if the values "
|
||||
#~ "are not supported by the chosen audio device, the device will use other "
|
||||
#~ "supported values instead."
|
||||
#~ msgstr ""
|
||||
#~ "För 'sndio' och 'oss' är endast föredragna värden, d.v.s. om värdena inte "
|
||||
#~ "stöds av den valda ljudenheten kommer enheten att använda andra värden "
|
||||
#~ "som stöds istället."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Adjust frequencies by a multiplication factor, more bars equals more "
|
||||
#~ "precision."
|
||||
#~ msgstr ""
|
||||
#~ "Justera frekvenserna med en multiplikationsfaktor, desto fler band, desto "
|
||||
#~ "högre precision."
|
||||
+656
@@ -0,0 +1,656 @@
|
||||
# Translation of visualizer in LANGUAGE
|
||||
# Copyright (C) 2025
|
||||
# This file is distributed under the same license as the visualizer package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: visualizer\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/luisbocanegra/kurve\n"
|
||||
"POT-Creation-Date: 2025-12-13 18:30+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: ../metadata.json
|
||||
msgid "Kurve"
|
||||
msgstr ""
|
||||
|
||||
#: ../metadata.json
|
||||
msgid "Audio visualizer powered by CAVA"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/config/config.qml
|
||||
msgid "Visualizer"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/config/config.qml ../contents/ui/configCava.qml
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml
|
||||
msgid "Oh no! Something went wrong"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml ../contents/ui/configCava.qml ../contents/ui/main.qml
|
||||
msgid "Stop CAVA"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml ../contents/ui/configCava.qml ../contents/ui/main.qml
|
||||
msgid "Start CAVA"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml
|
||||
msgid "Copy to clipboard"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/ColorPickerGradientList.qml ../contents/ui/components/ColorPickerList.qml ../contents/ui/components/FormColors.qml
|
||||
msgid "Widget background"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/Eq.qml
|
||||
msgid "Remove band"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/Eq.qml
|
||||
msgid "Add band"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/Eq.qml
|
||||
msgid "Flat response"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Animation:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Interval (ms):"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Smoothing (ms):"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color source:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Custom"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "A fixed custom color"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "System"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color that updates with your System theme"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Custom list"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Define a list of colors that will be applied to all the elements, wraps around if there are more elements than colors"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Random"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Random color for each element"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Follow"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Follow the color of a parent element"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Gradient"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Horizontal or vertical customizable color gradient"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Image"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "High resolution images can slow down the desktop when the panel or widget size changes!"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Hue"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Automatically shifted color for each bar"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Element:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Panel background"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Tray widget background"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Positioning:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Stretch"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Tile"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Scaled and Cropped"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Image:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Pick a image file"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Image files"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "All files"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color set:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Colors:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Range:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml ../contents/ui/configVisualizer.qml
|
||||
msgid "Orientation:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Horizontal"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Vertical"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Gradient:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml ../contents/ui/configCava.qml
|
||||
msgid "Reverse:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Display colors the other way around"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Alpha:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Contrast Correction"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Saturation:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Lightness:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Framerate:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Number of bars:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Automatically calculated for the current visualizer style."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Automatic sensitivity:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Attempt to decrease sensitivity if the bars peak."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sensitivity:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Manual sensitivity in %.\n"
|
||||
"If autosens is enabled, this will only be the initial value"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Frequency range (Hz):"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Min"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Max"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Lower and higher cutoff frequencies for lowest and highest bars, the bandwidth of the visualizer.\n"
|
||||
"Note: Cava will automatically increase the higher cutoff if a too low band is specified."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sleep timer (seconds):"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Seconds with no input before cava goes to sleep mode.\n"
|
||||
"Cava will not perform FFT and only check for input once per second."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Pause on:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Full screen window"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Maximized window"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Input"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Method:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml ../contents/ui/configGeneral.qml
|
||||
msgid "Default"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Audio capturing method.\n"
|
||||
"Defaults to 'oss', 'pipewire', 'sndio', 'jack', 'pulse', 'alsa', 'portaudio' or 'fifo', in that order, dependent on what support cava was built with.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Source:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For pulseaudio and pipewire 'source' will be the source. Default: 'auto', which uses the monitor source of the default sink (all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated "
|
||||
"with them)."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "For pipewire 'source' will be the object name or object.serial of the device to capture from. Both input and output devices are supported."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "For alsa 'source' will be the capture device."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "For fifo 'source' will be the path to fifo-file."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "For shmem 'source' will be /squeezelite-AA:BB:CC:DD:EE:FF where 'AA:BB:CC:DD:EE:FF' will be squeezelite's MAC address."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "For sndio 'source' will be a raw recording audio descriptor or a monitoring sub-device, e.g. 'rsnd/2' or 'snd/1'. Default: 'default'."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "For oss 'source' will be the path to a audio device, e.g. '/dev/dsp2'. Default: '/dev/dsp', i.e. the default audio device."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "For jack 'source' will be the name of the JACK server to connect to, e.g. 'foobar'. Default: 'default'."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sample rate:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for fifo, pipewire, sndio, oss"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sample bits:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Channels:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for pipewire & cava>=0.10.6, sndio, oss, jack"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Auto connect:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for jack"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Active:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for pipewire & cava>=0.10.6. Force the node to always process. Useful for monitoring sources when no other application is active."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Remix:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for pipewire & cava>=0.10.6. Allow to remix audio channels to match cava's channel count. Useful for surround sound."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Virtual:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for pipewire & cava>=0.10.6. Set the node to virtual, to avoid recording notifications from the DE."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Output"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Visual channels:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"'mono' outputs left to right lowest to highest frequencies.\n"
|
||||
"'stereo' mirrors both channels with low frequencies in center."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Mono channel:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Display frequencies the other way around"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Smoothing"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Noise reduction:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"The raw visualization is very noisy, this factor adjusts the integral and gravity filters to keep the signal smooth.\n"
|
||||
"100 will be very slow and smooth, 0 will be fast but noisy."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Monstercat:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Enable the so-called \"Monstercat smoothing\" with or without \"waves\"."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Waves"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Equalizer"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Enabled:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Adjust frequencies by a multiplication factor, more bands equals more precision."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Auto-hide when idle:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "After"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "seconds"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Desktop background:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Transparent"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Transparent with shadow"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Disable tooltip:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Disable ToolTip that shows the widget name and description."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Disable left click:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Applet popup will still be accessible from the right click menu."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Troubleshooting"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Debug mode:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Print additional messages to the system log. To make it easier to spot sizing issues, this will also force full height to the first visualizer bar and displays a grid over it."
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "height"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "width"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Style:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bars"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Wave"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Blocks"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fill wave"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Draw inactive blocks"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Circle mode:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Circle size:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Top"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bottom"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Left"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Right"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fill panel %1:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fixed %1:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fill panel thickness:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Centered bars:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Rounded bars:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Line width:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bar width:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bar gap:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Block height:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Block gap:"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Wave Color"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bar Color"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Inactive block color"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Wave Fill Color"
|
||||
msgstr ""
|
||||
|
||||
#: ../contents/ui/main.qml
|
||||
msgid "Show support information"
|
||||
msgstr ""
|
||||
+725
@@ -0,0 +1,725 @@
|
||||
# Translation of visualizer in Chinese (Simplified)
|
||||
# Copyright (C) 2025
|
||||
# This file is distributed under the same license as the visualizer package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: visualizer\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/luisbocanegra/kurve\n"
|
||||
"POT-Creation-Date: 2025-12-13 18:30+0000\n"
|
||||
"PO-Revision-Date: 2025-11-25 00:39+0800\n"
|
||||
"Last-Translator: BCTaoTao <165790460+BCTaoTao@users.noreply.github.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: zh_CN\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 3.6\n"
|
||||
|
||||
#: ../metadata.json
|
||||
msgid "Kurve"
|
||||
msgstr "Kurve"
|
||||
|
||||
#: ../metadata.json
|
||||
msgid "Audio visualizer powered by CAVA"
|
||||
msgstr "基于CAVA的音频可视化器"
|
||||
|
||||
#: ../contents/config/config.qml
|
||||
msgid "Visualizer"
|
||||
msgstr "可视化器"
|
||||
|
||||
#: ../contents/config/config.qml ../contents/ui/configCava.qml
|
||||
msgid "General"
|
||||
msgstr "常规"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml
|
||||
msgid "Oh no! Something went wrong"
|
||||
msgstr "糟糕!出错了"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml ../contents/ui/configCava.qml
|
||||
#: ../contents/ui/main.qml
|
||||
msgid "Stop CAVA"
|
||||
msgstr "停止 CAVA"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml ../contents/ui/configCava.qml
|
||||
#: ../contents/ui/main.qml
|
||||
msgid "Start CAVA"
|
||||
msgstr "启动 CAVA"
|
||||
|
||||
#: ../contents/ui/FullRepresentation.qml
|
||||
msgid "Copy to clipboard"
|
||||
msgstr "复制到剪贴板"
|
||||
|
||||
#: ../contents/ui/components/ColorPickerGradientList.qml
|
||||
#: ../contents/ui/components/ColorPickerList.qml
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Widget background"
|
||||
msgstr "小部件背景"
|
||||
|
||||
#: ../contents/ui/components/Eq.qml
|
||||
msgid "Remove band"
|
||||
msgstr "移除频段"
|
||||
|
||||
#: ../contents/ui/components/Eq.qml
|
||||
msgid "Add band"
|
||||
msgstr "添加频段"
|
||||
|
||||
#: ../contents/ui/components/Eq.qml
|
||||
msgid "Flat response"
|
||||
msgstr "平直响应"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color"
|
||||
msgstr "颜色"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Animation:"
|
||||
msgstr "动画:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Interval (ms):"
|
||||
msgstr "间隔(毫秒):"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Smoothing (ms):"
|
||||
msgstr "平滑(毫秒):"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color source:"
|
||||
msgstr "颜色来源:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Custom"
|
||||
msgstr "自定义"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "A fixed custom color"
|
||||
msgstr "固定的自定义颜色"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "System"
|
||||
msgstr "系统"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color that updates with your System theme"
|
||||
msgstr "随系统主题自动更新的颜色"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Custom list"
|
||||
msgstr "自定义颜色列表"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid ""
|
||||
"Define a list of colors that will be applied to all the elements, wraps "
|
||||
"around if there are more elements than colors"
|
||||
msgstr ""
|
||||
"定义一组颜色列表,依次应用于所有元素;若元素数量多于颜色数量,则循环使用"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Random"
|
||||
msgstr "随机"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Random color for each element"
|
||||
msgstr "为每个元素分配随机颜色"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Follow"
|
||||
msgstr "跟随"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Follow the color of a parent element"
|
||||
msgstr "跟随父级元素的颜色"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Gradient"
|
||||
msgstr "渐变"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Horizontal or vertical customizable color gradient"
|
||||
msgstr "可自定义的水平或垂直颜色渐变"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Image"
|
||||
msgstr "图像"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid ""
|
||||
"High resolution images can slow down the desktop when the panel or widget "
|
||||
"size changes!"
|
||||
msgstr "高分辨率图像在面板或小部件尺寸变化时可能导致桌面变慢!"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Hue"
|
||||
msgstr "色相"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Automatically shifted color for each bar"
|
||||
msgstr "为每根频谱柱自动偏移色相"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Element:"
|
||||
msgstr "元素:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Panel background"
|
||||
msgstr "面板背景"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Tray widget background"
|
||||
msgstr "托盘小部件背景"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Positioning:"
|
||||
msgstr "定位方式:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Stretch"
|
||||
msgstr "拉伸"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Tile"
|
||||
msgstr "平铺"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Scaled and Cropped"
|
||||
msgstr "缩放并裁剪"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Image:"
|
||||
msgstr "图像:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Pick a image file"
|
||||
msgstr "选择图像文件"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Image files"
|
||||
msgstr "图像文件"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "All files"
|
||||
msgstr "所有文件"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color:"
|
||||
msgstr "颜色:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Color set:"
|
||||
msgstr "颜色集:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Colors:"
|
||||
msgstr "颜色:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Range:"
|
||||
msgstr "范围:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml ../contents/ui/configVisualizer.qml
|
||||
msgid "Orientation:"
|
||||
msgstr "方向:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Horizontal"
|
||||
msgstr "水平"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Vertical"
|
||||
msgstr "垂直"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Gradient:"
|
||||
msgstr "渐变:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml ../contents/ui/configCava.qml
|
||||
msgid "Reverse:"
|
||||
msgstr "反转:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Display colors the other way around"
|
||||
msgstr "以相反顺序显示颜色"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Alpha:"
|
||||
msgstr "透明度:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Contrast Correction"
|
||||
msgstr "对比度校正"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Saturation:"
|
||||
msgstr "饱和度:"
|
||||
|
||||
#: ../contents/ui/components/FormColors.qml
|
||||
msgid "Lightness:"
|
||||
msgstr "亮度:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Framerate:"
|
||||
msgstr "帧率:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Number of bars:"
|
||||
msgstr "频谱柱数量:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Automatically calculated for the current visualizer style."
|
||||
msgstr "根据当前可视化样式自动计算。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Automatic sensitivity:"
|
||||
msgstr "自动灵敏度:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Attempt to decrease sensitivity if the bars peak."
|
||||
msgstr "当频谱柱达到峰值时,尝试降低灵敏度。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sensitivity:"
|
||||
msgstr "灵敏度:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Manual sensitivity in %.\n"
|
||||
"If autosens is enabled, this will only be the initial value"
|
||||
msgstr ""
|
||||
"手动灵敏度(百分比)。\n"
|
||||
"若启用自动灵敏度,此值仅作为初始值。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Frequency range (Hz):"
|
||||
msgstr "频率范围(Hz):"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Min"
|
||||
msgstr "最小"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Max"
|
||||
msgstr "最大"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Lower and higher cutoff frequencies for lowest and highest bars, the "
|
||||
"bandwidth of the visualizer.\n"
|
||||
"Note: Cava will automatically increase the higher cutoff if a too low band "
|
||||
"is specified."
|
||||
msgstr ""
|
||||
"最低和最高频谱柱对应的截止频率,即可视化器的带宽。\n"
|
||||
"注意:若指定的频带过窄,CAVA会自动提高高频截止值。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sleep timer (seconds):"
|
||||
msgstr "休眠计时器(秒):"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Seconds with no input before cava goes to sleep mode.\n"
|
||||
"Cava will not perform FFT and only check for input once per second."
|
||||
msgstr ""
|
||||
"无音频输入多少秒后进入休眠模式。\n"
|
||||
"休眠期间CAVA不执行FFT,仅每秒检查一次输入。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Pause on:"
|
||||
msgstr "何时暂停:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Full screen window"
|
||||
msgstr "全屏窗口时"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Maximized window"
|
||||
msgstr "最大化窗口时"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Input"
|
||||
msgstr "输入"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Method:"
|
||||
msgstr "方法:"
|
||||
|
||||
#: ../contents/ui/configCava.qml ../contents/ui/configGeneral.qml
|
||||
msgid "Default"
|
||||
msgstr "默认"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Audio capturing method.\n"
|
||||
"Defaults to 'oss', 'pipewire', 'sndio', 'jack', 'pulse', 'alsa', 'portaudio' "
|
||||
"or 'fifo', in that order, dependent on what support cava was built with.\n"
|
||||
msgstr ""
|
||||
"音频捕获方法。\n"
|
||||
"默认按以下顺序尝试:\n"
|
||||
"'oss'、'pipewire'、'sndio'、'jack'、'pulse'、'alsa'、'portaudio'或'fifo',\n"
|
||||
"具体取决于CAVA编译时所包含的支持。\n"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Source:"
|
||||
msgstr "源:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For pulseaudio and pipewire 'source' will be the source. Default: 'auto', "
|
||||
"which uses the monitor source of the default sink (all pulseaudio "
|
||||
"sinks(outputs) have 'monitor' sources(inputs) associated with them)."
|
||||
msgstr ""
|
||||
"对于PulseAudio和PipeWire,'source'指音频源。默认为'auto',即使用默认输出设备"
|
||||
"的监听源(所有PulseAudio输出设备均有对应的监听输入源)。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For pipewire 'source' will be the object name or object.serial of the device "
|
||||
"to capture from. Both input and output devices are supported."
|
||||
msgstr ""
|
||||
"对于PipeWire,'source'可为设备的对象名称或object.serial,支持输入和输出设备。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "For alsa 'source' will be the capture device."
|
||||
msgstr "对于ALSA,'source'为录音设备。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "For fifo 'source' will be the path to fifo-file."
|
||||
msgstr "对于FIFO,'source'为FIFO文件路径。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For shmem 'source' will be /squeezelite-AA:BB:CC:DD:EE:FF where 'AA:BB:CC:DD:"
|
||||
"EE:FF' will be squeezelite's MAC address."
|
||||
msgstr ""
|
||||
"对于shmem,'source'为/squeezelite-AA:BB:CC:DD:EE:FF,其中'AA:BB:CC:DD:EE:"
|
||||
"FF'为squeezelite的MAC地址。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For sndio 'source' will be a raw recording audio descriptor or a monitoring "
|
||||
"sub-device, e.g. 'rsnd/2' or 'snd/1'. Default: 'default'."
|
||||
msgstr ""
|
||||
"对于sndio,'source'为原始录音音频描述符或监听子设备(如'rsnd/2'或'snd/1')。"
|
||||
"默认值:'default'。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For oss 'source' will be the path to a audio device, e.g. '/dev/dsp2'. "
|
||||
"Default: '/dev/dsp', i.e. the default audio device."
|
||||
msgstr ""
|
||||
"对于OSS,'source'为音频设备路径(如'/dev/dsp2')。默认值:'/dev/dsp'(即默认"
|
||||
"音频设备)。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"For jack 'source' will be the name of the JACK server to connect to, e.g. "
|
||||
"'foobar'. Default: 'default'."
|
||||
msgstr ""
|
||||
"对于JACK,'source'为要连接的JACK服务器名称(如'foobar')。默认值:'default'。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sample rate:"
|
||||
msgstr "采样率:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for fifo, pipewire, sndio, oss"
|
||||
msgstr "仅适用于fifo、pipewire、sndio、oss"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Sample bits:"
|
||||
msgstr "采样位深:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Channels:"
|
||||
msgstr "声道数:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for pipewire & cava>=0.10.6, sndio, oss, jack"
|
||||
msgstr "仅适用于pipewire(CAVA ≥ 0.10.6)、sndio、oss、jack"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Auto connect:"
|
||||
msgstr "自动连接:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Only for jack"
|
||||
msgstr "仅适用于jack"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Active:"
|
||||
msgstr "激活:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Only for pipewire & cava>=0.10.6. Force the node to always process. Useful "
|
||||
"for monitoring sources when no other application is active."
|
||||
msgstr ""
|
||||
"仅适用于pipewire(CAVA ≥ 0.10.6)。强制节点始终处理音频,适用于无其他应用活跃"
|
||||
"时监听音频源。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Remix:"
|
||||
msgstr "混音:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Only for pipewire & cava>=0.10.6. Allow to remix audio channels to match "
|
||||
"cava's channel count. Useful for surround sound."
|
||||
msgstr ""
|
||||
"仅适用于pipewire(CAVA ≥ 0.10.6)。允许重混音频声道以匹配CAVA的声道数,适用于"
|
||||
"环绕声。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Virtual:"
|
||||
msgstr "虚拟:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Only for pipewire & cava>=0.10.6. Set the node to virtual, to avoid "
|
||||
"recording notifications from the DE."
|
||||
msgstr ""
|
||||
"仅适用于pipewire(CAVA ≥ 0.10.6)。将节点设为虚拟,避免桌面环境弹出录音通知。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Output"
|
||||
msgstr "输出"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Visual channels:"
|
||||
msgstr "可视化声道:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"'mono' outputs left to right lowest to highest frequencies.\n"
|
||||
"'stereo' mirrors both channels with low frequencies in center."
|
||||
msgstr ""
|
||||
"“单声道(mono)”从左到右显示从低到高的频率。\n"
|
||||
"“立体声(stereo)”镜像显示双声道,低频位于中央。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Mono channel:"
|
||||
msgstr "单声道选项:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Display frequencies the other way around"
|
||||
msgstr "以相反顺序显示频率"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Smoothing"
|
||||
msgstr "平滑"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Noise reduction:"
|
||||
msgstr "降噪:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"The raw visualization is very noisy, this factor adjusts the integral and "
|
||||
"gravity filters to keep the signal smooth.\n"
|
||||
"100 will be very slow and smooth, 0 will be fast but noisy."
|
||||
msgstr ""
|
||||
"原始可视化噪声较大,此参数通过积分与重力滤波器使信号平滑。\n"
|
||||
"100表示极慢且平滑,0表示快速但噪声明显。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Monstercat:"
|
||||
msgstr "Monstercat平滑:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Enable the so-called \"Monstercat smoothing\" with or without \"waves\"."
|
||||
msgstr "启用被称为“Monstercat平滑”的效果,可选择是否同时启用“波浪效果”。"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Waves"
|
||||
msgstr "波浪效果"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Equalizer"
|
||||
msgstr "均衡器"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid "Enabled:"
|
||||
msgstr "启用:"
|
||||
|
||||
#: ../contents/ui/configCava.qml
|
||||
msgid ""
|
||||
"Adjust frequencies by a multiplication factor, more bands equals more "
|
||||
"precision."
|
||||
msgstr "通过乘法因子调整频率,频段越多,精度越高。"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Auto-hide when idle:"
|
||||
msgstr "空闲时自动隐藏:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "After"
|
||||
msgstr "在"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "seconds"
|
||||
msgstr "秒后"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Desktop background:"
|
||||
msgstr "桌面背景:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Transparent"
|
||||
msgstr "透明"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Transparent with shadow"
|
||||
msgstr "透明带阴影"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Disable tooltip:"
|
||||
msgstr "禁用工具提示:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Disable ToolTip that shows the widget name and description."
|
||||
msgstr "禁用显示小部件名称和描述的工具提示。"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Disable left click:"
|
||||
msgstr "禁用左键点击:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Applet popup will still be accessible from the right click menu."
|
||||
msgstr "仍可通过右键菜单访问小部件弹出窗口。"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Troubleshooting"
|
||||
msgstr "故障排除"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid "Debug mode:"
|
||||
msgstr "调试模式:"
|
||||
|
||||
#: ../contents/ui/configGeneral.qml
|
||||
msgid ""
|
||||
"Print additional messages to the system log. To make it easier to spot "
|
||||
"sizing issues, this will also force full height to the first visualizer bar "
|
||||
"and displays a grid over it."
|
||||
msgstr ""
|
||||
"向系统日志输出额外信息。\n"
|
||||
"为便于发现尺寸问题,此选项还会强制将第一条频谱柱设为最大高度,并在整个区域上"
|
||||
"显示网格。"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "height"
|
||||
msgstr "高度"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "width"
|
||||
msgstr "宽度"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Style:"
|
||||
msgstr "样式:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bars"
|
||||
msgstr "柱状"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Wave"
|
||||
msgstr "波形"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Blocks"
|
||||
msgstr "块状"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fill wave"
|
||||
msgstr "填充波形"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Draw inactive blocks"
|
||||
msgstr "绘制非活动块"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Circle mode:"
|
||||
msgstr "环形模式"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Circle size:"
|
||||
msgstr "内环大小"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Top"
|
||||
msgstr "顶部"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bottom"
|
||||
msgstr "底部"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Left"
|
||||
msgstr "左侧"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Right"
|
||||
msgstr "右侧"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fill panel %1:"
|
||||
msgstr "填充面板%1:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fixed %1:"
|
||||
msgstr "固定%1:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Fill panel thickness:"
|
||||
msgstr "填充面板厚度:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Centered bars:"
|
||||
msgstr "居中柱:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Rounded bars:"
|
||||
msgstr "圆角柱:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Line width:"
|
||||
msgstr "线条宽度:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bar width:"
|
||||
msgstr "列宽度:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bar gap:"
|
||||
msgstr "列间距:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Block height:"
|
||||
msgstr "块高度:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Block gap:"
|
||||
msgstr "块间距:"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Wave Color"
|
||||
msgstr "波形颜色"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Bar Color"
|
||||
msgstr "频谱柱颜色"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Inactive block color"
|
||||
msgstr "非活动块颜色"
|
||||
|
||||
#: ../contents/ui/configVisualizer.qml
|
||||
msgid "Wave Fill Color"
|
||||
msgstr "波形填充颜色"
|
||||
|
||||
#: ../contents/ui/main.qml
|
||||
msgid "Show support information"
|
||||
msgstr "显示支持信息"
|
||||
Reference in New Issue
Block a user