Browse Source

- 新增"渐变线"样式

- 完善简介与翻译
- 修复默认预设排序无效的问题
master
mashiros 2 years ago
parent
commit
d3748e68a9
  1. BIN
      Locales/ja_JP.qm
  2. BIN
      Locales/zh.qm
  3. BIN
      Locales/zh_CN.qm
  4. 4
      Presets/Gradient_Line/preset.json
  5. BIN
      Presets/Gradient_Line/preview.png
  6. 8
      Presets/Gradient_Line/settings.xml
  7. 91
      package.json
  8. 7
      qml/Common.qml
  9. 2
      qml/api/CfgAPI.qml
  10. 161
      styles/Preset_gradient_line/Config.qml
  11. 187
      styles/Preset_gradient_line/Style.qml

BIN
Locales/ja_JP.qm

Binary file not shown.

BIN
Locales/zh.qm

Binary file not shown.

BIN
Locales/zh_CN.qm

Binary file not shown.

4
Presets/Gradient_Line/preset.json

@ -0,0 +1,4 @@
{
"source": "nvg://advp.widget.mashiros.top/widget",
"settings": "settings.xml"
}

BIN
Presets/Gradient_Line/preview.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

8
Presets/Gradient_Line/settings.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<map>
<value name="nvg://advp.widget.mashiros.top/advp-style-preset_line#Style.qml">{"__version":"1.0.0","__cfg_height":580,"Center Line":true,"Center Color":"#ff4500","Line Color":"#ff4500","Line Position":0,"Data Length":0,"Channel":2,"Reverse":false,"Rotate Settings":{"Center Enable":false,"Center Angle":10,"Line Enable":false,"Line Angle":10},"Data Settings":{"Auto Normalizing":true,"Amplitude":4,"Unit Style":0}}</value>
<value name="styles">{"index":1}</value>
<value name="current_style">"nvg://advp.widget.mashiros.top/advp-style-preset/gradient_line#Style.qml"</value>
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/line#Style.qml">{"__version":"1.0.0","__cfg_height":580,"Center Line":true,"Center Color":"#ff4500","Line Color":"#ff4500","Line Position":0,"Data Length":0,"Channel":2,"Reverse":false,"Rotate Settings":{"Center Enable":false,"Center Angle":10,"Line Enable":false,"Line Angle":10},"Data Settings":{"Auto Normalizing":true,"Amplitude":10,"Unit Style":0}}</value>
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/gradient_line#Style.qml">{"__version":"1.0.0","__cfg_height":600,"Gradient Direction":0,"Start Position Color":"#f44336","Middle Position Color":"#4caf50","End Position Color":"#03a9f4","Center Line":true,"Line Position":0,"Data Length":0,"Channel":2,"Reverse":false,"Rotate Settings":{"Center Enable":false,"Center Angle":10,"Line Enable":false,"Line Angle":10},"Data Settings":{"Auto Normalizing":true,"Amplitude":10,"Unit Style":0}}</value>
</map>

91
package.json

@ -1,6 +1,6 @@
{
"name": "top.mashiros.widget.advp",
"version": "1.0.0",
"version": "1.1.0",
"title": {
"en": "ADV Plugin",
@ -10,10 +10,10 @@
},
"description": {
"en": "Audio visualization plugin for SAO Utils 2",
"zh": "用于SAO Utils 2的音频可视化插件",
"zh_TW": "用于SAO Utils 2的音頻可視化插件",
"ja": "SAO Utils 2用の音声視覚化プラグイン"
"en": "Audio visualization plugin for SAO Utils 2, includes 6 preset styles and provides API for third-party style extensions.",
"zh": "用于SAO Utils 2的音频可视化插件,包含6种预设频谱样式,并为第三方频谱样式扩展提供了接口。",
"zh_TW": "用於SAO Utils 2的音頻可視化插件,包含6種預設頻譜樣式,並為第三方頻譜樣式擴展提供了接口。",
"ja": "SAO Utils 2のオーディオ視覚化プラグインには、6つのプリセットスペクトルスタイルが含まれており、サードパーティのスペクトルスタイル拡張用のインターフェイスを提供します。"
},
"homepage": "https://nvg.dev/Mashiro_Sorata/ADV-Plugin",
@ -51,51 +51,62 @@
"entry": "qml/Main.qml"
},
{
"location": "/advp-style-preset_line",
"location": "/advp-style-preset/line",
"catalog": "top.mashiros.advp-style",
"title": {
"en": "Preset Line",
"zh": "预置 Line",
"zh_TW": "預置 Line",
"ja": "プリセット Line"
"zh": "预置 线",
"zh_TW": "預置 ",
"ja": "プリセット "
},
"entry": "./styles/Preset_line"
},
{
"location": "/advp-style-preset_waves",
"location": "/advp-style-preset/gradient_line",
"catalog": "top.mashiros.advp-style",
"title": {
"en": "Preset Gradient Line",
"zh": "预置 渐变线",
"zh_TW": "預置 漸變線",
"ja": "プリセット グラデーションライン"
},
"entry": "./styles/Preset_gradient_line"
},
{
"location": "/advp-style-preset/waves",
"catalog": "top.mashiros.advp-style",
"title": {
"en": "Preset Waves",
"zh": "预置 Waves",
"zh_TW": "預置 Waves",
"ja": "プリセット Waves"
"zh": "预置 波浪",
"zh_TW": "預置 波浪",
"ja": "プリセット 波浪"
},
"entry": "./styles/Preset_waves"
},
{
"location": "/advp-style-preset-circle",
"location": "/advp-style-preset/circle",
"catalog": "top.mashiros.advp-style",
"title": {
"en": "Preset Circle",
"zh": "预置 Circle",
"zh_TW": "預置 Circle",
"ja": "プリセット Circle"
"zh": "预置 ",
"zh_TW": "預置 ",
"ja": "プリセット "
},
"entry": "./styles/Preset_circle"
},
{
"location": "/advp-style-preset-solidcircle",
"location": "/advp-style-preset/solidcircle",
"catalog": "top.mashiros.advp-style",
"title": {
"en": "Preset Solid-circle",
"zh": "预置 Solid-circle",
"zh_TW": "預置 Solid-circle",
"ja": "プリセット Solid-circle"
"zh": "预置 实心圆",
"zh_TW": "預置 實心圓",
"ja": "プリセット 固形円"
},
"entry": "./styles/Preset_solidcircle"
},
{
"location": "/advp-style-preset-ordinal_scale_ui_bottom",
"location": "/advp-style-preset/ordinal_scale_ui_bottom",
"catalog": "top.mashiros.advp-style",
"title": {
"en": "Preset Ordinal Scale UI bottom",
@ -110,21 +121,33 @@
"catalog": "preset/widget",
"title": {
"en": "ADV Preset Line",
"zh": "ADV预置 Line",
"zh_TW": "ADV預置 Line",
"ja": "ADVプリセット Line"
"zh": "ADV预置 线",
"zh_TW": "ADV預置 ",
"ja": "ADVプリセット "
},
"preview": "Presets/Line/preview.png",
"entry": "Presets/Line/preset.json"
},
{
"location": "/preset/advp-style-preset_gradient_line",
"catalog": "preset/widget",
"title": {
"en": "ADV Preset Gradient Line",
"zh": "ADV预置 渐变线",
"zh_TW": "ADV預置 漸變線",
"ja": "ADVプリセット グラデーションライン"
},
"preview": "Presets/Gradient_Line/preview.png",
"entry": "Presets/Gradient_Line/preset.json"
},
{
"location": "/preset/advp-style-preset_waves",
"catalog": "preset/widget",
"title": {
"en": "ADV Preset Waves",
"zh": "ADV预置 Waves",
"zh_TW": "ADV預置 Waves",
"ja": "ADVプリセット Waves"
"zh": "ADV预置 波浪",
"zh_TW": "ADV預置 波浪",
"ja": "ADVプリセット 波浪"
},
"preview": "Presets/Waves/preview.png",
"entry": "Presets/Waves/preset.json"
@ -134,9 +157,9 @@
"catalog": "preset/widget",
"title": {
"en": "ADV Preset Circle",
"zh": "ADV预置 Circle",
"zh_TW": "ADV預置 Circle",
"ja": "ADVプリセット Circle"
"zh": "ADV预置 ",
"zh_TW": "ADV預置 ",
"ja": "ADVプリセット "
},
"preview": "Presets/Circle/preview.png",
"entry": "Presets/Circle/preset.json"
@ -146,9 +169,9 @@
"catalog": "preset/widget",
"title": {
"en": "ADV Preset Solid-circle",
"zh": "ADV预置 Solid-circle",
"zh_TW": "ADV預置 Solid-circle",
"ja": "ADVプリセット Solid-circle"
"zh": "ADV预置 实心圆",
"zh_TW": "ADV預置 實心圓",
"ja": "ADVプリセット 固形円"
},
"preview": "Presets/Solidcircle/preview.png",
"entry": "Presets/Solidcircle/preset.json"

7
qml/Common.qml

@ -94,10 +94,10 @@ Item {
function parse_resource(resource_list, sort) {
if (sort)
resource_list.sort(function (x, y) {
let preset_order = ["Preset Line", "Preset Waves", "Preset Circle", "Preset Solid-circle", "Preset Ordinal Scale UI bottom"];
if (preset_order.indexOf(x.title) < preset_order.indexOf(y.title))
let preset_order = ["/advp-style-preset/line", "/advp-style-preset/gradient_line", "/advp-style-preset/waves", "/advp-style-preset/circle", "/advp-style-preset/solidcircle", "/advp-style-preset/ordinal_scale_ui_bottom"];
if (preset_order.indexOf(x.location) < preset_order.indexOf(y.location))
return -1;
else if(preset_order.indexOf(x.title) > preset_order.indexOf(y.title))
else if(preset_order.indexOf(x.location) > preset_order.indexOf(y.location))
return 1;
else
return 0;
@ -117,7 +117,6 @@ Item {
styles.push(name);
stylesURL.push(styleURL);
stylesCFG.push(styleCFG);
}
});
}

2
qml/api/CfgAPI.qml

@ -38,4 +38,6 @@ P.DialogPreference {
font.weight: Font.DemiBold
}
}
P.Separator {}
}

161
styles/Preset_gradient_line/Config.qml

@ -0,0 +1,161 @@
import QtQuick 2.12
import NERvGear.Preferences 1.0 as P
import "../../qml/api" //CfgAPI.qml
CfgAPI {
version: "1.0.0"
cfg_height: 660
P.SelectPreference {
name: "Gradient Direction"
label: qsTr("Gradient Direction")
defaultValue: 0
model: [qsTr("Horizontal"), qsTr("Vertical"), qsTr("Oblique Upward"), qsTr("Oblique downward")]
}
P.ColorPreference {
name: "Start Position Color"
label: qsTr("Start Position Color")
defaultValue: "#f44336"
}
P.ColorPreference {
name: "Middle Position Color"
label: qsTr("Middle Position Color")
defaultValue: "#4caf50"
}
P.ColorPreference {
name: "End Position Color"
label: qsTr("End Position Color")
defaultValue: "#03a9f4"
}
P.Separator {}
P.SwitchPreference {
name: "Center Line"
label: qsTr("Show Center Line")
defaultValue: true
}
P.SelectPreference {
name: "Line Position"
label: qsTr("Spectrum Line Position")
defaultValue: 0
model: [qsTr("Both"), qsTr("Up"), qsTr("Down")]
}
P.SelectPreference {
name: "Data Length"
label: qsTr("Spectrum Length")
defaultValue: 0
model: [64, 32, 16, 8]
}
P.Separator {}
P.SpinPreference {
id: _cfg_preset_line_Channel
name: "Channel"
label: qsTr("Channel")
message: "1 to 2"
display: P.TextFieldPreference.ExpandLabel
editable: false
from: 1
to: 2
defaultValue: 2
}
P.SwitchPreference {
name: "Reverse"
label: qsTr("Reverse Spectrum")
enabled: _cfg_preset_line_Channel.value === 1
defaultValue: false
}
P.Separator {}
P.DialogPreference {
name: "Rotate Settings"
label: qsTr("Rotate Settings")
live: true
icon.name: "regular:\uf1de"
P.SwitchPreference {
id: _cfg_preset_line_Rotate_Center_Enable
name: "Center Enable"
label: qsTr("Rotate Center Line")
defaultValue: false
}
P.SliderPreference {
name: "Center Angle"
label: qsTr("Angle of Center Line")
enabled: _cfg_preset_line_Rotate_Center_Enable.value
from: -45
to: 45
stepSize: 1
defaultValue: 10
displayValue: value + "°"
}
P.Separator {}
P.SwitchPreference {
id: _cfg_preset_line_Rotate_Line_Enable
name: "Line Enable"
label: qsTr("Rotate Spectrum Line")
defaultValue: false
}
P.SliderPreference {
name: "Line Angle"
label: qsTr("Angle of Spectrum Line")
enabled: _cfg_preset_line_Rotate_Line_Enable.value
from: -75
to: 75
stepSize: 1
defaultValue: 10
displayValue: value + "°"
}
}
P.Separator {}
P.DialogPreference {
name: "Data Settings"
label: qsTr("Data Settings")
live: true
icon.name: "regular:\uf1de"
P.SwitchPreference {
id: _cfg_preset_line_dataSettings_autoNormalizing
name: "Auto Normalizing"
label: qsTr("Auto Normalizing")
defaultValue: true
}
P.SpinPreference {
name: "Amplitude"
label: qsTr("Amplitude Ratio")
enabled: !_cfg_preset_line_dataSettings_autoNormalizing.value
message: "1 to 100"
display: P.TextFieldPreference.ExpandLabel
editable: true
from: 1
to: 100
defaultValue: 10
}
P.Separator {}
P.SelectPreference {
name: "Unit Style"
label: qsTr("Display Style")
defaultValue: 0
model: [qsTr("Linear"), qsTr("Decibel")]
}
}
}

187
styles/Preset_gradient_line/Style.qml

@ -0,0 +1,187 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtGraphicalEffects 1.12
import "../../qml/api" //CfgAPI.qml
Rectangle {
width: widget.width;
height: widget.height;
LinearGradient {
id: gradient_mask
anchors.fill: parent
gradient: Gradient {
GradientStop { id: p_start; position: 0.0 }
GradientStop { id: p_middle; position: 0.5 }
GradientStop { id: p_end; position: 1.0 }
}
}
layer.enabled: true
layer.effect: OpacityMask{
maskSource: StyleAPI {
readonly property var audioData: new Array(128)
readonly property bool centerLineFlag: configs["Center Line"]
readonly property int linePosition: configs["Line Position"]
readonly property int uDataLen: Math.pow(2, configs["Data Length"]);
readonly property int dataLength: 64/uDataLen
readonly property int channel: configs["Channel"]
readonly property bool reverse: configs["Reverse"]
readonly property bool centerRotateFlag: configs["Rotate Settings"]["Center Enable"]
readonly property real centerRotateAngle: configs["Rotate Settings"]["Center Angle"]
readonly property bool lineRotateFlag: configs["Rotate Settings"]["Line Enable"]
readonly property real lineRotateAngle: configs["Rotate Settings"]["Line Angle"]
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
readonly property real amplitude: configs["Data Settings"]["Amplitude"] / 400.0
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
property int total: channel * dataLength
property real logAmplitude: Math.log10(amplitude)
property real degUnit: Math.PI / 180
property real halfWidth: width/2
property real halfHeight: height/2
onConfigsUpdated: {
context.fillStyle = "black";
gradient_mask.start = Qt.point(0, height*(configs["Gradient Direction"]===2))
gradient_mask.end = Qt.point(width*(configs["Gradient Direction"]!==1), height*(configs["Gradient Direction"]%2))
p_start.color = configs["Start Position Color"];
p_middle.color = configs["Middle Position Color"];
p_end.color = configs["End Position Color"];
}
onAudioDataUpdeted: {
if(autoNormalizing) {
if (unitStyle) {
//
for(let i=0; i<dataLength; i++) {
audioData[i] = 0;
for(let j=0; j<uDataLen; j++) {
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[64-i*uDataLen-j-1]/data[128])) + 1.0);
}
audioData[i] /= uDataLen;
}
if (channel === 2) {
for(let i=dataLength; i<total; i++) {
audioData[i] = 0;
for(let j=0; j<uDataLen; j++) {
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[64+(i-dataLength)*uDataLen+j]/data[128])) + 1.0);
}
audioData[i] /= uDataLen;
}
}
} else {
//线
for(let i=0; i<dataLength; i++) {
audioData[i] = 0;
for(let j=0; j<uDataLen; j++) {
audioData[i] += data[64-i*uDataLen-j-1];
}
audioData[i] /= (uDataLen * data[128]);
}
if (channel === 2) {
for(let i=dataLength; i<total; i++) {
audioData[i] = 0;
for(let j=0; j<uDataLen; j++) {
audioData[i] += data[64+(i-dataLength)*uDataLen+j];
}
audioData[i] /= (uDataLen * data[128]);
}
}
}
} else {
if (unitStyle) {
//
for(let i=0; i<dataLength; i++) {
audioData[i] = 0;
for(let j=0; j<uDataLen; j++) {
audioData[i] += Math.max(0, 0.35 * (Math.log10(data[64-i*uDataLen-j-1])+logAmplitude) + 1.0);
}
audioData[i] /= uDataLen;
}
if (channel === 2) {
for(let i=dataLength; i<total; i++) {
audioData[i] = 0;
for(let j=0; j<uDataLen; j++) {
audioData[i] += Math.max(0, 0.35 * (Math.log10(data[64+(i-dataLength)*uDataLen+j])+logAmplitude) + 1.0);
}
audioData[i] /= uDataLen;
}
}
} else {
//线
for(let i=0; i<dataLength; i++) {
audioData[i] = 0;
for(let j=0; j<uDataLen; j++) {
audioData[i] += data[64-i*uDataLen-j-1];
}
audioData[i] /= (uDataLen/amplitude);
}
if (channel === 2) {
for(let i=dataLength; i<total; i++) {
audioData[i] = 0;
for(let j=0; j<uDataLen; j++) {
audioData[i] += data[64+(i-dataLength)*uDataLen+j];
}
audioData[i] /= (uDataLen/amplitude);
}
}
}
}
let _dy;
let _y_dy = centerRotateFlag*Math.tan(centerRotateAngle*degUnit)*halfWidth;
let _ux = width/total;
let _dx = Math.round(_ux/2);
let _y = halfHeight-_y_dy
context.clearRect(0, 0, width+32, height+32);
if(lineRotateFlag || centerRotateFlag) {
context.transform(1, centerRotateFlag*centerRotateAngle * degUnit, -lineRotateFlag*lineRotateAngle * degUnit, 1, lineRotateFlag*Math.sin(1.05*lineRotateAngle*degUnit)*_y, 0);
}
if (centerLineFlag) {
context.fillRect(0, _y, width, 2);
}
//
if (channel === 1 && reverse) {
for (let i = 0; i < dataLength; i++) {
let index = dataLength - i - 1;
_y = halfHeight*(1-(linePosition!==2)*audioData[index])-_y_dy;
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[index];
context.fillRect(_ux * i, _y, _dx, _dy);
}
} else {
for (let j = 0; j < channel; j++) {
for (let i = 0; i < dataLength; i++) {
let index = j ? ((total - dataLength) + i) : i;
_y = halfHeight*(1-(linePosition!==2)*audioData[index])-_y_dy;
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[index];
context.fillRect(_ux * (i + j * dataLength), _y, _dx, _dy);
}
}
}
if (centerRotateFlag || lineRotateFlag)
context.resetTransform();
context.fill();
requestPaint();
}
Component.onCompleted: {
for (let i = 0; i < 128; i++) {
audioData[i] = 0;
}
}
}
}
}
Loading…
Cancel
Save