mirror of
https://github.com/onyx-and-iris/voicemeeter-compact.git
synced 2026-04-19 05:53:31 +00:00
Compare commits
22 Commits
v1.9.7
...
b0f634f1e8
| Author | SHA1 | Date | |
|---|---|---|---|
| b0f634f1e8 | |||
| 5e5ae33e6a | |||
| 0d04a2f33e | |||
| 81a5497a32 | |||
| edc76db88e | |||
| 3b701a074d | |||
| 66cabb68cf | |||
|
|
37d7e58704 | ||
| 293bccc5ba | |||
| 1d8ffdc756 | |||
| e4d87334cb | |||
| ad3020809e | |||
| 76c6630892 | |||
| cc46fc31f8 | |||
| 8657e8846a | |||
| 43aad156a0 | |||
| 5101ff01f2 | |||
| c437ae5843 | |||
| ae59ba30f9 | |||
| a3fa227ac1 | |||
| b1b6c66828 | |||
| cb00de36f0 |
@@ -9,6 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
- [ ]
|
- [ ]
|
||||||
|
|
||||||
|
## [1.9.8] - 2025-01-22
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- vm-compact config dirs now override _internal/configs (if using build from releases). See [TOML Files](https://github.com/onyx-and-iris/voicemeeter-compact?tab=readme-ov-file#toml-files) section in README.
|
||||||
|
- after disconnecting from a vban connection, vban menus are re-enabled after 500ms.
|
||||||
|
|
||||||
## [1.9.5] - 2024-07-03
|
## [1.9.5] - 2024-07-03
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
24
README.md
24
README.md
@@ -65,15 +65,18 @@ Set the kind of Voicemeeter, KIND_ID may be:
|
|||||||
|
|
||||||
## TOML Files
|
## TOML Files
|
||||||
|
|
||||||
This is how your files should be organised. Wherever your `__main__.py` file is located (after install this can be any location), `configs` should be in the same location.
|
If you've downloaded the binary from [Releases][releases] you can find configs included in the `_internal/configs` directory.
|
||||||
Directly inside of configs directory you may place an app.toml, vban.toml and a directory for each kind.
|
|
||||||
Inside each kind directory you may place as many custom toml configurations as you wish.
|
You may override these configs by placing a directory `vm-compact` in one of the following locations:
|
||||||
|
|
||||||
|
- `user home directory / .config`
|
||||||
|
- `user home directory / Documents / Voicemeeter`
|
||||||
|
|
||||||
|
The contents should match the following directory structure:
|
||||||
|
|
||||||
.
|
.
|
||||||
|
|
||||||
├── `__main__.py`
|
├── vm-compact
|
||||||
|
|
||||||
├── configs
|
|
||||||
|
|
||||||
├── app.toml
|
├── app.toml
|
||||||
|
|
||||||
@@ -111,7 +114,7 @@ Configure certain startup states for the app.
|
|||||||
Configure a user config to load on app startup. Don't include the .toml extension in the config name.
|
Configure a user config to load on app startup. Don't include the .toml extension in the config name.
|
||||||
|
|
||||||
- `theme`
|
- `theme`
|
||||||
By default the app loads up the [Sun Valley light or dark theme][def] by @rdbende. You have the option to load up the app without any theme loaded. Simply set `enabled` to false and `mode` will take no effect.
|
By default the app loads up the [Sun Valley light or dark theme][releases] by @rdbende. You have the option to load up the app without any theme loaded. Simply set `enabled` to false and `mode` will take no effect.
|
||||||
|
|
||||||
- `extends`
|
- `extends`
|
||||||
Extending the app will show both strips and buses. In reduced mode only one or the other. This app will extend both horizontally and vertically, simply set `extends_horizontal` true or false accordingly.
|
Extending the app will show both strips and buses. In reduced mode only one or the other. This app will extend both horizontally and vertically, simply set `extends_horizontal` true or false accordingly.
|
||||||
@@ -136,13 +139,13 @@ A valid `vban.toml` might look like this:
|
|||||||
```toml
|
```toml
|
||||||
[connection-1]
|
[connection-1]
|
||||||
kind = 'banana'
|
kind = 'banana'
|
||||||
ip = '192.168.1.2'
|
host = '192.168.1.2'
|
||||||
streamname = 'worklaptop'
|
streamname = 'worklaptop'
|
||||||
port = 6980
|
port = 6980
|
||||||
|
|
||||||
[connection-2]
|
[connection-2]
|
||||||
kind = 'potato'
|
kind = 'potato'
|
||||||
ip = '192.168.1.3'
|
host = '192.168.1.3'
|
||||||
streamname = 'streampc'
|
streamname = 'streampc'
|
||||||
port = 6990
|
port = 6990
|
||||||
```
|
```
|
||||||
@@ -164,4 +167,5 @@ User configs may be loaded at any time via the menu.
|
|||||||
[Rdbende](https://github.com/rdbende) for creating the beautiful [Sun Valley theme][sv-theme].
|
[Rdbende](https://github.com/rdbende) for creating the beautiful [Sun Valley theme][sv-theme].
|
||||||
|
|
||||||
|
|
||||||
[sv-theme]: https://github.com/rdbende/Sun-Valley-ttk-theme
|
[sv-theme]: https://github.com/rdbende/Sun-Valley-ttk-theme
|
||||||
|
[releases]: https://github.com/onyx-and-iris/voicemeeter-compact/releases
|
||||||
40
Taskfile.azure.yml
Normal file
40
Taskfile.azure.yml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
build:
|
||||||
|
desc: Build Azure artifacts
|
||||||
|
deps: [rewrite]
|
||||||
|
cmds:
|
||||||
|
- defer: { task: restore }
|
||||||
|
- for:
|
||||||
|
matrix:
|
||||||
|
KIND: [basic, banana, potato]
|
||||||
|
THEME: [azure-light, azure-dark]
|
||||||
|
cmd: poetry run pyinstaller --noconfirm --distpath dist/{{.ITEM.THEME}}-{{.ITEM.KIND}} spec/azure/{{.ITEM.THEME}}-{{.ITEM.KIND}}.spec
|
||||||
|
|
||||||
|
rewrite:
|
||||||
|
internal: true
|
||||||
|
desc: Run the source code rewriter
|
||||||
|
cmds:
|
||||||
|
- poetry run python tools/rewriter.py --rewrite --theme {{.THEME}}
|
||||||
|
|
||||||
|
restore:
|
||||||
|
internal: true
|
||||||
|
desc: Restore the backup files
|
||||||
|
cmds:
|
||||||
|
- poetry run python tools/rewriter.py --restore
|
||||||
|
|
||||||
|
compress:
|
||||||
|
desc: Compress Azure artifacts
|
||||||
|
cmds:
|
||||||
|
- for:
|
||||||
|
matrix:
|
||||||
|
KIND: [basic, banana, potato]
|
||||||
|
THEME: [azure-light, azure-dark]
|
||||||
|
cmd: '{{.SHELL}} -Command "Compress-Archive -Path dist/{{.ITEM.THEME}}-{{.ITEM.KIND}} -DestinationPath dist/{{.ITEM.THEME}}-{{.ITEM.KIND}}.zip -Force"'
|
||||||
|
|
||||||
|
clean:
|
||||||
|
desc: Clean build and dist directories
|
||||||
|
cmds:
|
||||||
|
- |
|
||||||
|
{{.SHELL}} -Command "Remove-Item -Path build/azure-*,dist/azure-* -Recurse -Force"
|
||||||
40
Taskfile.forest.yml
Normal file
40
Taskfile.forest.yml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
build:
|
||||||
|
desc: Build Forest artifacts
|
||||||
|
deps: [rewrite]
|
||||||
|
cmds:
|
||||||
|
- defer: { task: restore }
|
||||||
|
- for:
|
||||||
|
matrix:
|
||||||
|
KIND: [basic, banana, potato]
|
||||||
|
THEME: [forest-light, forest-dark]
|
||||||
|
cmd: poetry run pyinstaller --noconfirm --distpath dist/{{.ITEM.THEME}}-{{.ITEM.KIND}} spec/forest/{{.ITEM.THEME}}-{{.ITEM.KIND}}.spec
|
||||||
|
|
||||||
|
rewrite:
|
||||||
|
internal: true
|
||||||
|
desc: Run the source code rewriter
|
||||||
|
cmds:
|
||||||
|
- poetry run python tools/rewriter.py --rewrite --theme {{.THEME}}
|
||||||
|
|
||||||
|
restore:
|
||||||
|
internal: true
|
||||||
|
desc: Restore the backup files
|
||||||
|
cmds:
|
||||||
|
- poetry run python tools/rewriter.py --restore
|
||||||
|
|
||||||
|
compress:
|
||||||
|
desc: Compress Forest artifacts
|
||||||
|
cmds:
|
||||||
|
- for:
|
||||||
|
matrix:
|
||||||
|
KIND: [basic, banana, potato]
|
||||||
|
THEME: [forest-light, forest-dark]
|
||||||
|
cmd: '{{.SHELL}} -Command "Compress-Archive -Path dist/{{.ITEM.THEME}}-{{.ITEM.KIND}} -DestinationPath dist/{{.ITEM.THEME}}-{{.ITEM.KIND}}.zip -Force"'
|
||||||
|
|
||||||
|
clean:
|
||||||
|
desc: Clean build and dist directories
|
||||||
|
cmds:
|
||||||
|
- |
|
||||||
|
{{.SHELL}} -Command "Remove-Item -Path build/forest-*,dist/forest-* -Recurse -Force"
|
||||||
24
Taskfile.sunvalley.yml
Normal file
24
Taskfile.sunvalley.yml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
build:
|
||||||
|
desc: Build Sunvalley artifacts
|
||||||
|
cmds:
|
||||||
|
- for:
|
||||||
|
matrix:
|
||||||
|
KIND: [basic, banana, potato]
|
||||||
|
cmd: poetry run pyinstaller --noconfirm --distpath dist/sunvalley-{{.ITEM.KIND}} spec/sunvalley/sunvalley-{{.ITEM.KIND}}.spec
|
||||||
|
|
||||||
|
compress:
|
||||||
|
desc: Compress Sunvalley artifacts
|
||||||
|
cmds:
|
||||||
|
- for:
|
||||||
|
matrix:
|
||||||
|
KIND: [basic, banana, potato]
|
||||||
|
cmd: '{{.SHELL}} -Command "Compress-Archive -Path dist/sunvalley-{{.ITEM.KIND}} -DestinationPath dist/sunvalley-{{.ITEM.KIND}}.zip -Force"'
|
||||||
|
|
||||||
|
clean:
|
||||||
|
desc: Clean build and dist directories
|
||||||
|
cmds:
|
||||||
|
- |
|
||||||
|
{{.SHELL}} -Command "Remove-Item -Path build/sunvalley-*,dist/sunvalley-* -Recurse -Force"
|
||||||
55
Taskfile.yml
Normal file
55
Taskfile.yml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
includes:
|
||||||
|
sunvalley:
|
||||||
|
taskfile: ./Taskfile.sunvalley.yml
|
||||||
|
vars:
|
||||||
|
THEME: sunvalley
|
||||||
|
forest:
|
||||||
|
taskfile: ./Taskfile.forest.yml
|
||||||
|
vars:
|
||||||
|
THEME: forest
|
||||||
|
azure:
|
||||||
|
taskfile: ./Taskfile.azure.yml
|
||||||
|
vars:
|
||||||
|
THEME: azure
|
||||||
|
|
||||||
|
vars:
|
||||||
|
SHELL: pwsh
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
default:
|
||||||
|
desc: Prepare artifacts for release
|
||||||
|
cmds:
|
||||||
|
- task: release
|
||||||
|
|
||||||
|
release:
|
||||||
|
desc: Build and compress all artifacts
|
||||||
|
cmds:
|
||||||
|
- task: build
|
||||||
|
- task: compress
|
||||||
|
- echo "Release complete"
|
||||||
|
|
||||||
|
build:
|
||||||
|
desc: Build all artifacts
|
||||||
|
cmds:
|
||||||
|
- for:
|
||||||
|
matrix:
|
||||||
|
THEME: [sunvalley, forest, azure]
|
||||||
|
task: '{{.ITEM.THEME}}:build'
|
||||||
|
|
||||||
|
compress:
|
||||||
|
desc: Compress all artifacts
|
||||||
|
cmds:
|
||||||
|
- for:
|
||||||
|
matrix:
|
||||||
|
THEME: [sunvalley, forest, azure]
|
||||||
|
task: '{{.ITEM.THEME}}:compress'
|
||||||
|
|
||||||
|
clean:
|
||||||
|
desc: Clean up build and dist directories
|
||||||
|
cmds:
|
||||||
|
- for:
|
||||||
|
matrix:
|
||||||
|
THEME: [sunvalley, forest, azure]
|
||||||
|
task: '{{.ITEM.THEME}}:clean'
|
||||||
41
build.ps1
41
build.ps1
@@ -1,41 +0,0 @@
|
|||||||
param(
|
|
||||||
[Parameter(Mandatory = $true)]
|
|
||||||
[string]$prefix,
|
|
||||||
[string]$theme
|
|
||||||
)
|
|
||||||
|
|
||||||
function Format-SpecName {
|
|
||||||
param(
|
|
||||||
[string]$Kind
|
|
||||||
)
|
|
||||||
return @(
|
|
||||||
$prefix,
|
|
||||||
(& { if ($theme) { $theme } else { "" } }),
|
|
||||||
$Kind
|
|
||||||
).Where({ $_ -ne "" }) -Join "_"
|
|
||||||
}
|
|
||||||
|
|
||||||
function Compress-Builds {
|
|
||||||
$target = Join-Path -Path $PSScriptRoot -ChildPath "dist"
|
|
||||||
@("basic", "banana", "potato") | ForEach-Object {
|
|
||||||
$compressPath = Format-SpecName -Kind $_
|
|
||||||
Compress-Archive -Path (Join-Path -Path $target -ChildPath $compressPath) -DestinationPath (Join-Path -Path $target -ChildPath "${compressPath}.zip") -Force
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Get-Builds {
|
|
||||||
@("basic", "banana", "potato") | ForEach-Object {
|
|
||||||
$specName = Format-SpecName -Kind $_
|
|
||||||
|
|
||||||
Write-Host "building $specName"
|
|
||||||
|
|
||||||
poetry run pyinstaller --noconfirm --distpath (Join-Path -Path "dist" -ChildPath $specName) (Join-Path -Path "spec" -ChildPath "${specName}.spec")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function main {
|
|
||||||
Get-Builds
|
|
||||||
Compress-Builds
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($MyInvocation.InvocationName -ne '.') { main }
|
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
# load a specific profile on start (file name without .toml ext)
|
# load a specific profile on start (file name without .toml ext)
|
||||||
# [configs]
|
# [configs]
|
||||||
# config="example"
|
# config="example"
|
||||||
# load with themes enabled? set the default mode
|
# load with themes enabled?
|
||||||
[theme]
|
[theme]
|
||||||
enabled = true
|
enabled = true
|
||||||
mode = "light"
|
|
||||||
# load in extended mode? if so which orientation
|
# load in extended mode? if so which orientation
|
||||||
[extends]
|
[extends]
|
||||||
extended = true
|
extended = true
|
||||||
@@ -22,4 +21,4 @@ size = 3
|
|||||||
default = 0
|
default = 0
|
||||||
# show the navigation frame?
|
# show the navigation frame?
|
||||||
[navigation]
|
[navigation]
|
||||||
show = true
|
show = false
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
### set the ip then uncomment
|
### set the ip then uncomment
|
||||||
# [connection-1]
|
# [connection-1]
|
||||||
# kind = 'banana'
|
# kind = 'banana'
|
||||||
# ip = '<ip address 1>'
|
# ip = 'localhost'
|
||||||
# streamname = 'Command1'
|
# streamname = 'Command1'
|
||||||
# port = 6980
|
# port = 6980
|
||||||
|
|
||||||
# [connection-2]
|
# [connection-2]
|
||||||
# kind = 'potato'
|
# kind = 'potato'
|
||||||
# ip = '<ip address 2>'
|
# ip = 'gamepc.local'
|
||||||
# streamname = 'Command1'
|
# streamname = 'Command1'
|
||||||
# port = 6980
|
# port = 6980
|
||||||
|
|||||||
52
poetry.lock
generated
52
poetry.lock
generated
@@ -1,4 +1,4 @@
|
|||||||
# This file is automatically @generated by Poetry 2.0.1 and should not be changed by hand.
|
# This file is automatically @generated by Poetry 2.3.2 and should not be changed by hand.
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "altgraph"
|
name = "altgraph"
|
||||||
@@ -147,24 +147,24 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "setuptools"
|
name = "setuptools"
|
||||||
version = "75.8.0"
|
version = "78.1.1"
|
||||||
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
groups = ["build"]
|
groups = ["build"]
|
||||||
files = [
|
files = [
|
||||||
{file = "setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3"},
|
{file = "setuptools-78.1.1-py3-none-any.whl", hash = "sha256:c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561"},
|
||||||
{file = "setuptools-75.8.0.tar.gz", hash = "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6"},
|
{file = "setuptools-78.1.1.tar.gz", hash = "sha256:fcc17fd9cd898242f6b4adfaca46137a9edef687f43e6f78469692a5e70d851d"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.8.0)"]
|
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""]
|
||||||
core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
|
core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"]
|
||||||
cover = ["pytest-cov"]
|
cover = ["pytest-cov"]
|
||||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
|
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
|
||||||
enabler = ["pytest-enabler (>=2.2)"]
|
enabler = ["pytest-enabler (>=2.2)"]
|
||||||
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
|
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
|
||||||
type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.14.*)", "pytest-mypy"]
|
type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sv-ttk"
|
name = "sv-ttk"
|
||||||
@@ -184,8 +184,8 @@ version = "2.2.1"
|
|||||||
description = "A lil' TOML parser"
|
description = "A lil' TOML parser"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
groups = ["main"]
|
groups = ["main", "dev"]
|
||||||
markers = "python_version < \"3.11\""
|
markers = "python_version == \"3.10\""
|
||||||
files = [
|
files = [
|
||||||
{file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
|
{file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
|
||||||
{file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
|
{file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
|
||||||
@@ -223,35 +223,39 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vban-cmd"
|
name = "vban-cmd"
|
||||||
version = "2.5.0"
|
version = "2.10.1"
|
||||||
description = "Python interface for the VBAN RT Packet Service (Sendtext)"
|
description = "Python interface for the VBAN RT Packet Service (Sendtext)"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.10"
|
python-versions = ">=3.10"
|
||||||
groups = ["main"]
|
groups = ["main", "dev"]
|
||||||
files = [
|
files = []
|
||||||
{file = "vban_cmd-2.5.0-py3-none-any.whl", hash = "sha256:22a19037066487d464a61941a3b85a0331b498a9efb1bcacdc932e9d06c5bf87"},
|
develop = true
|
||||||
{file = "vban_cmd-2.5.0.tar.gz", hash = "sha256:691a852e5052e50103839b06a0a9d0746b90df3346545c2cf4f10b099d9666e4"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
tomli = {version = ">=2.0.1,<3.0", markers = "python_version < \"3.11\""}
|
tomli = {version = ">=2.0.1,<3.0", markers = "python_version < \"3.11\""}
|
||||||
|
|
||||||
|
[package.source]
|
||||||
|
type = "directory"
|
||||||
|
url = "../vban-cmd-python"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "voicemeeter-api"
|
name = "voicemeeter-api"
|
||||||
version = "2.6.1"
|
version = "2.7.2"
|
||||||
description = "A Python wrapper for the Voiceemeter API"
|
description = "A Python wrapper for the Voiceemeter API"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "<4.0,>=3.10"
|
python-versions = ">=3.10"
|
||||||
groups = ["main"]
|
groups = ["main", "dev"]
|
||||||
files = [
|
files = []
|
||||||
{file = "voicemeeter_api-2.6.1-py3-none-any.whl", hash = "sha256:8ae3bce0f9ad6bbad78f2f69f522b6fb2e229d314918a075ad83d4009aff7020"},
|
develop = true
|
||||||
{file = "voicemeeter_api-2.6.1.tar.gz", hash = "sha256:34d8672603ec66197f2d61fd8f038f46d8451759c81fbe222b00e7d3ccccd1f5"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
tomli = {version = ">=2.0.1,<3.0", markers = "python_version < \"3.11\""}
|
tomli = {version = ">=2.0.1,<3.0", markers = "python_version < \"3.11\""}
|
||||||
|
|
||||||
|
[package.source]
|
||||||
|
type = "directory"
|
||||||
|
url = "../voicemeeter-api-python"
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.1"
|
lock-version = "2.1"
|
||||||
python-versions = ">=3.10,<3.14"
|
python-versions = ">=3.10,<3.14"
|
||||||
content-hash = "19c384acd36868a5bfdc3f3173f444858136603694c3f1134c0d30cd17157651"
|
content-hash = "171da15ce55f47b4e651aade40ab21afd5ef589ff7ff26e51caf6840d25b98a1"
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "voicemeeter-compact"
|
name = "voicemeeter-compact"
|
||||||
version = "1.9.7"
|
version = "1.9.8"
|
||||||
description = "A Compact Voicemeeter Remote App"
|
description = "A Compact Voicemeeter Remote App"
|
||||||
authors = [
|
authors = [{ name = "Onyx and Iris", email = "code@onyxandiris.online" }]
|
||||||
{name = "Onyx and Iris",email = "code@onyxandiris.online"}
|
license = { text = "MIT" }
|
||||||
]
|
|
||||||
license = {text = "MIT"}
|
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10,<3.14"
|
requires-python = ">=3.10,<3.14"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"voicemeeter-api (>=2.6.1,<3.0.0)",
|
"voicemeeter-api (>=2.7.2,<3.0.0)",
|
||||||
"vban-cmd (>=2.5.0,<3.0.0)",
|
"vban-cmd (>=2.10.1,<3.0.0)",
|
||||||
"sv-ttk (>=2.6.0,<3.0.0)",
|
"sv-ttk (>=2.6.0,<3.0.0)",
|
||||||
"tomli (>=2.0.1,<3.0) ; python_version < '3.11'",
|
"tomli (>=2.0.1,<3.0) ; python_version < '3.11'",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
gui-basic = "vmcompact.gui.basic:run"
|
gui-basic-compact = "vmcompact.gui.basic:run"
|
||||||
gui-banana = "vmcompact.gui.banana:run"
|
gui-banana-compact = "vmcompact.gui.banana:run"
|
||||||
gui-potato = "vmcompact.gui.potato:run"
|
gui-potato-compact = "vmcompact.gui.potato:run"
|
||||||
|
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
packages = [{ include = "vmcompact" }]
|
packages = [{ include = "vmcompact" }]
|
||||||
include = ["vmcompact/img/cat.ico"]
|
include = ["vmcompact/img/cat.ico"]
|
||||||
|
|
||||||
[tool.poetry.requires-plugins]
|
[tool.poetry.requires-plugins]
|
||||||
poethepoet = "^0.32.1"
|
poethepoet = ">=0.42.0"
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
ruff = "^0.9.1"
|
ruff = "^0.9.1"
|
||||||
|
voicemeeter-api = { path = "../voicemeeter-api-python/", develop = true }
|
||||||
|
vban-cmd = { path = "../vban-cmd-python/", develop = true }
|
||||||
|
|
||||||
[tool.poetry.group.build.dependencies]
|
[tool.poetry.group.build.dependencies]
|
||||||
pyinstaller = "^6.11.1"
|
pyinstaller = "^6.11.1"
|
||||||
@@ -38,9 +38,14 @@ requires = ["poetry-core>=2.0.0,<3.0.0"]
|
|||||||
build-backend = "poetry.core.masonry.api"
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
[tool.poe.tasks]
|
[tool.poe.tasks]
|
||||||
build_sunvalley.script = "scripts:build_sunvalley"
|
build-sunvalley = "task build-sunvalley"
|
||||||
build_forest.script = "scripts:build_forest"
|
build-forest = "task build-forest"
|
||||||
build_all.script = "scripts:build_all"
|
release = [
|
||||||
|
{ ref = "build-sunvalley" },
|
||||||
|
{ ref = "build-forest" },
|
||||||
|
{ cmd = "task compress-sunvalley" },
|
||||||
|
{ cmd = "task compress-forest" },
|
||||||
|
]
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
exclude = [
|
exclude = [
|
||||||
@@ -120,7 +125,4 @@ docstring-code-line-length = "dynamic"
|
|||||||
max-complexity = 10
|
max-complexity = 10
|
||||||
|
|
||||||
[tool.ruff.lint.per-file-ignores]
|
[tool.ruff.lint.per-file-ignores]
|
||||||
"__init__.py" = [
|
"__init__.py" = ["E402", "F401"]
|
||||||
"E402",
|
|
||||||
"F401",
|
|
||||||
]
|
|
||||||
|
|||||||
24
scripts.py
24
scripts.py
@@ -1,24 +0,0 @@
|
|||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
|
|
||||||
def build_sunvalley():
|
|
||||||
buildscript = Path.cwd() / "build.ps1"
|
|
||||||
subprocess.run(["powershell", str(buildscript), "sv"])
|
|
||||||
|
|
||||||
|
|
||||||
def build_forest():
|
|
||||||
rewriter = Path.cwd() / "tools" / "rewriter.py"
|
|
||||||
subprocess.run([sys.executable, str(rewriter), "-r"])
|
|
||||||
|
|
||||||
buildscript = Path.cwd() / "build.ps1"
|
|
||||||
for theme in ("light", "dark"):
|
|
||||||
subprocess.run(["powershell", str(buildscript), "fst", theme])
|
|
||||||
|
|
||||||
subprocess.run([sys.executable, str(rewriter), "-c"])
|
|
||||||
|
|
||||||
|
|
||||||
def build_all():
|
|
||||||
steps = (build_sunvalley, build_forest)
|
|
||||||
[step() for step in steps]
|
|
||||||
@@ -4,11 +4,11 @@ from pathlib import Path
|
|||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
logger = logging.getLogger("vm-compact-rewriter")
|
logger = logging.getLogger('vm-compact-rewriter')
|
||||||
|
|
||||||
PACKAGE_DIR = Path(__file__).parent.parent / "vmcompact"
|
PACKAGE_DIR = Path(__file__).parent.parent / 'vmcompact'
|
||||||
|
|
||||||
SRC_DIR = Path(__file__).parent / "src"
|
SRC_DIR = Path(__file__).parent / 'src'
|
||||||
|
|
||||||
|
|
||||||
def write_outs(output, outs: tuple):
|
def write_outs(output, outs: tuple):
|
||||||
@@ -16,235 +16,256 @@ def write_outs(output, outs: tuple):
|
|||||||
output.write(out)
|
output.write(out)
|
||||||
|
|
||||||
|
|
||||||
def rewrite_app():
|
def rewrite_app(theme):
|
||||||
app_logger = logger.getChild("app")
|
app_logger = logger.getChild('app')
|
||||||
app_logger.info("rewriting app.py")
|
app_logger.info('rewriting app.py')
|
||||||
infile = Path(SRC_DIR) / "app.bk"
|
infile = Path(SRC_DIR) / 'app.bk'
|
||||||
outfile = Path(PACKAGE_DIR) / "app.py"
|
outfile = Path(PACKAGE_DIR) / 'app.py'
|
||||||
with open(infile, "r") as input:
|
with open(infile, 'r') as input:
|
||||||
with open(outfile, "w") as output:
|
with open(outfile, 'w') as output:
|
||||||
for line in input:
|
for line in input:
|
||||||
match line:
|
match line:
|
||||||
# App init()
|
# App init()
|
||||||
case " def __init__(self, vmr):\n":
|
case ' def __init__(self, vmr):\n':
|
||||||
output.write(" def __init__(self, vmr, theme):\n")
|
output.write(' def __init__(self, vmr, theme):\n')
|
||||||
case " self._vmr = vmr\n":
|
case ' self._vmr = vmr\n':
|
||||||
write_outs(
|
write_outs(
|
||||||
output,
|
output,
|
||||||
(
|
(
|
||||||
" self._vmr = vmr\n",
|
' self._vmr = vmr\n',
|
||||||
" self._theme = theme\n",
|
' self._theme = theme\n',
|
||||||
|
' self._theme_name = theme.split("-")[0]\n',
|
||||||
|
' self._theme_type = theme.split("-")[-1]\n',
|
||||||
' tcldir = Path.cwd() / "theme"\n',
|
' tcldir = Path.cwd() / "theme"\n',
|
||||||
" if not tcldir.is_dir():\n",
|
' if not tcldir.is_dir():\n',
|
||||||
' tcldir = Path.cwd() / "_internal" / "theme"\n',
|
' tcldir = Path.cwd() / "_internal" / "theme"\n',
|
||||||
' self.tk.call("source", tcldir.resolve() / f"forest-{self._theme}.tcl")\n',
|
' match self._theme_name:\n',
|
||||||
|
' case "forest":\n',
|
||||||
|
' self.tk.call("source", tcldir.resolve() / f"{self._theme}.tcl")\n',
|
||||||
|
' case "azure":\n',
|
||||||
|
' self.tk.call("source", tcldir.resolve() / f"{self._theme_name}.tcl")\n',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
# def connect()
|
# def connect()
|
||||||
case "def connect(kind_id: str, vmr) -> App:\n":
|
case 'def connect(kind_id: str, vmr) -> App:\n':
|
||||||
output.write(
|
output.write('def connect(kind_id: str, vmr, theme) -> App:\n')
|
||||||
'def connect(kind_id: str, vmr, theme="light") -> App:\n'
|
case ' return VMMIN_cls(vmr)\n':
|
||||||
)
|
output.write(' return VMMIN_cls(vmr, theme)\n')
|
||||||
case " return VMMIN_cls(vmr)\n":
|
|
||||||
output.write(" return VMMIN_cls(vmr, theme)\n")
|
|
||||||
case _:
|
case _:
|
||||||
output.write(line)
|
output.write(line)
|
||||||
|
|
||||||
|
|
||||||
def rewrite_builders():
|
def rewrite_builders(theme):
|
||||||
builders_logger = logger.getChild("builders")
|
builders_logger = logger.getChild('builders')
|
||||||
builders_logger.info("rewriting builders.py")
|
builders_logger.info('rewriting builders.py')
|
||||||
infile = Path(SRC_DIR) / "builders.bk"
|
infile = Path(SRC_DIR) / 'builders.bk'
|
||||||
outfile = Path(PACKAGE_DIR) / "builders.py"
|
outfile = Path(PACKAGE_DIR) / 'builders.py'
|
||||||
with open(infile, "r") as input:
|
with open(infile, 'r') as input:
|
||||||
with open(outfile, "w") as output:
|
with open(outfile, 'w') as output:
|
||||||
ignore_next_lines = 0
|
ignore_next_lines = 0
|
||||||
|
|
||||||
for line in input:
|
for line in input:
|
||||||
if ignore_next_lines > 0:
|
if ignore_next_lines > 0:
|
||||||
builders_logger.info(f"ignoring: {line}")
|
builders_logger.info(f'ignoring: {line}')
|
||||||
ignore_next_lines -= 1
|
ignore_next_lines -= 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
match line:
|
match line:
|
||||||
# loading themes
|
# loading themes
|
||||||
case "import sv_ttk\n":
|
case 'import sv_ttk\n':
|
||||||
output.write("#import sv_ttk\n")
|
output.write('#import sv_ttk\n')
|
||||||
case " self.app.resizable(False, False)\n":
|
case ' self.app.resizable(False, False)\n':
|
||||||
write_outs(
|
if theme.startswith('forest'):
|
||||||
output,
|
write_outs(
|
||||||
(
|
output,
|
||||||
" self.app.resizable(False, False)\n"
|
(
|
||||||
" if _configuration.themes_enabled:\n",
|
' self.app.resizable(False, False)\n'
|
||||||
' ttk.Style().theme_use(f"forest-{self.app._theme}")\n',
|
' if _configuration.themes_enabled:\n',
|
||||||
' self.logger.info(f"Forest Theme applied")\n',
|
' ttk.Style().theme_use(self.app._theme)\n',
|
||||||
),
|
' self.logger.info(f"{self.app._theme} Theme applied")\n',
|
||||||
)
|
),
|
||||||
|
)
|
||||||
|
elif theme.startswith('azure'):
|
||||||
|
write_outs(
|
||||||
|
output,
|
||||||
|
(
|
||||||
|
' self.app.resizable(False, False)\n'
|
||||||
|
' if _configuration.themes_enabled:\n',
|
||||||
|
' self.app.tk.call("set_theme", self.app._theme_type)\n',
|
||||||
|
' self.logger.info(f"Azure {self.app._theme_type} Theme applied")\n',
|
||||||
|
),
|
||||||
|
)
|
||||||
ignore_next_lines = 6
|
ignore_next_lines = 6
|
||||||
# setting navframe button widths
|
# setting navframe button widths
|
||||||
case " variable=self.navframe.submix,\n":
|
case ' variable=self.navframe.submix,\n':
|
||||||
write_outs(
|
write_outs(
|
||||||
output,
|
output,
|
||||||
(
|
(
|
||||||
" variable=self.navframe.submix,\n"
|
' variable=self.navframe.submix,\n'
|
||||||
" width=8,\n",
|
' width=8,\n',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
case " variable=self.navframe.channel,\n":
|
case ' variable=self.navframe.channel,\n':
|
||||||
write_outs(
|
write_outs(
|
||||||
output,
|
output,
|
||||||
(
|
(
|
||||||
" variable=self.navframe.channel,\n"
|
' variable=self.navframe.channel,\n'
|
||||||
" width=8,\n",
|
' width=8,\n',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
case " variable=self.navframe.extend,\n":
|
case ' variable=self.navframe.extend,\n':
|
||||||
write_outs(
|
write_outs(
|
||||||
output,
|
output,
|
||||||
(
|
(
|
||||||
" variable=self.navframe.extend,\n"
|
' variable=self.navframe.extend,\n'
|
||||||
" width=8,\n",
|
' width=8,\n',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
case " variable=self.navframe.info,\n":
|
case ' variable=self.navframe.info,\n':
|
||||||
write_outs(
|
write_outs(
|
||||||
output,
|
output,
|
||||||
(
|
(
|
||||||
" variable=self.navframe.info,\n"
|
' variable=self.navframe.info,\n'
|
||||||
" width=8,\n",
|
' width=8,\n',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
# set channelframe button widths
|
# set channelframe button widths
|
||||||
case " variable=self.labelframe.mute,\n":
|
case ' variable=self.labelframe.mute,\n':
|
||||||
write_outs(
|
write_outs(
|
||||||
output,
|
output,
|
||||||
(
|
(
|
||||||
" variable=self.labelframe.mute,\n"
|
' variable=self.labelframe.mute,\n'
|
||||||
" width=7,\n",
|
' width=7,\n',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
case " variable=self.labelframe.conf,\n":
|
case ' variable=self.labelframe.conf,\n':
|
||||||
write_outs(
|
write_outs(
|
||||||
output,
|
output,
|
||||||
(
|
(
|
||||||
" variable=self.labelframe.conf,\n"
|
' variable=self.labelframe.conf,\n'
|
||||||
" width=7,\n",
|
' width=7,\n',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
case " variable=self.labelframe.on,\n":
|
case ' variable=self.labelframe.on,\n':
|
||||||
write_outs(
|
write_outs(
|
||||||
output,
|
output,
|
||||||
(
|
(
|
||||||
" variable=self.labelframe.on,\n"
|
' variable=self.labelframe.on,\n'
|
||||||
" width=7,\n",
|
' width=7,\n',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
# set stripconfigframe button widths
|
# set stripconfigframe button widths
|
||||||
case " self.configframe.phys_out_params.index(param)\n":
|
case ' self.configframe.phys_out_params.index(param)\n':
|
||||||
write_outs(
|
write_outs(
|
||||||
output,
|
output,
|
||||||
(
|
(
|
||||||
" self.configframe.phys_out_params.index(param)\n",
|
' self.configframe.phys_out_params.index(param)\n',
|
||||||
" ],\n",
|
' ],\n',
|
||||||
" width=6,\n",
|
' width=6,\n',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
ignore_next_lines = 1
|
ignore_next_lines = 1
|
||||||
case " self.configframe.virt_out_params.index(param)\n":
|
case ' self.configframe.virt_out_params.index(param)\n':
|
||||||
write_outs(
|
write_outs(
|
||||||
output,
|
output,
|
||||||
(
|
(
|
||||||
" self.configframe.virt_out_params.index(param)\n",
|
' self.configframe.virt_out_params.index(param)\n',
|
||||||
" ],\n",
|
' ],\n',
|
||||||
" width=6,\n",
|
' width=6,\n',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
ignore_next_lines = 1
|
ignore_next_lines = 1
|
||||||
# This does both strip and bus param vars buttons
|
# This does both strip and bus param vars buttons
|
||||||
case " variable=self.configframe.param_vars[i],\n":
|
case ' variable=self.configframe.param_vars[i],\n':
|
||||||
write_outs(
|
write_outs(
|
||||||
output,
|
output,
|
||||||
(
|
(
|
||||||
" variable=self.configframe.param_vars[i],\n",
|
' variable=self.configframe.param_vars[i],\n',
|
||||||
" width=6,\n",
|
' width=6,\n',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
case _:
|
case _:
|
||||||
if "Toggle.TButton" in line:
|
if 'Toggle.TButton' in line:
|
||||||
output.write(line.replace("Toggle.TButton", "ToggleButton"))
|
if theme.startswith('forest'):
|
||||||
|
output.write(
|
||||||
|
line.replace('Toggle.TButton', 'ToggleButton')
|
||||||
|
)
|
||||||
|
elif theme.startswith('azure'):
|
||||||
|
output.write(
|
||||||
|
line.replace(
|
||||||
|
'Toggle.TButton', 'Switch.TCheckbutton'
|
||||||
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
output.write(line)
|
output.write(line)
|
||||||
|
|
||||||
|
|
||||||
def rewrite_menu():
|
def rewrite_menu(theme):
|
||||||
menu_logger = logger.getChild("menu")
|
menu_logger = logger.getChild('menu')
|
||||||
menu_logger.info("rewriting menu.py")
|
menu_logger.info('rewriting menu.py')
|
||||||
infile = Path(SRC_DIR) / "menu.bk"
|
infile = Path(SRC_DIR) / 'menu.bk'
|
||||||
outfile = Path(PACKAGE_DIR) / "menu.py"
|
outfile = Path(PACKAGE_DIR) / 'menu.py'
|
||||||
with open(infile, "r") as input:
|
with open(infile, 'r') as input:
|
||||||
with open(outfile, "w") as output:
|
with open(outfile, 'w') as output:
|
||||||
ignore_next_lines = 0
|
ignore_next_lines = 0
|
||||||
|
|
||||||
for line in input:
|
for line in input:
|
||||||
if ignore_next_lines > 0:
|
if ignore_next_lines > 0:
|
||||||
menu_logger.info(f"ignoring: {line}")
|
menu_logger.info(f'ignoring: {line}')
|
||||||
ignore_next_lines -= 1
|
ignore_next_lines -= 1
|
||||||
continue
|
continue
|
||||||
match line:
|
match line:
|
||||||
case "import sv_ttk\n":
|
case 'import sv_ttk\n':
|
||||||
output.write("#import sv_ttk\n")
|
output.write('#import sv_ttk\n')
|
||||||
case " # layout/themes\n":
|
case ' # layout/themes\n':
|
||||||
ignore_next_lines = 14
|
ignore_next_lines = 14
|
||||||
case _:
|
case _:
|
||||||
output.write(line)
|
output.write(line)
|
||||||
|
|
||||||
|
|
||||||
def prepare_for_build():
|
def prepare_for_build(theme):
|
||||||
################# MOVE FILES FROM PACKAGE DIR INTO SRC DIR #########################
|
################# MOVE FILES FROM PACKAGE DIR INTO SRC DIR #########################
|
||||||
for file in (
|
for file in (
|
||||||
PACKAGE_DIR / "app.py",
|
PACKAGE_DIR / 'app.py',
|
||||||
PACKAGE_DIR / "builders.py",
|
PACKAGE_DIR / 'builders.py',
|
||||||
PACKAGE_DIR / "menu.py",
|
PACKAGE_DIR / 'menu.py',
|
||||||
):
|
):
|
||||||
if file.exists():
|
if file.exists():
|
||||||
logger.debug(f"moving {str(file)}")
|
logger.debug(f'moving {str(file)}')
|
||||||
file.rename(SRC_DIR / f"{file.stem}.bk")
|
file.rename(SRC_DIR / f'{file.stem}.bk')
|
||||||
|
|
||||||
###################### RUN THE FILE REWRITER FOR EACH *.BK #########################
|
###################### RUN THE FILE REWRITER FOR EACH *.BK #########################
|
||||||
steps = (
|
for step in (rewrite_app, rewrite_builders, rewrite_menu):
|
||||||
rewrite_app,
|
step(theme)
|
||||||
rewrite_builders,
|
|
||||||
rewrite_menu,
|
|
||||||
)
|
|
||||||
[step() for step in steps]
|
|
||||||
|
|
||||||
|
|
||||||
def cleanup():
|
def cleanup():
|
||||||
########################## RESTORE *.BK FILES #####################################
|
########################## RESTORE *.BK FILES #####################################
|
||||||
for file in (
|
for file in (
|
||||||
PACKAGE_DIR / "app.py",
|
PACKAGE_DIR / 'app.py',
|
||||||
PACKAGE_DIR / "builders.py",
|
PACKAGE_DIR / 'builders.py',
|
||||||
PACKAGE_DIR / "menu.py",
|
PACKAGE_DIR / 'menu.py',
|
||||||
):
|
):
|
||||||
file.unlink()
|
file.unlink()
|
||||||
|
|
||||||
for file in (
|
for file in (
|
||||||
SRC_DIR / "app.bk",
|
SRC_DIR / 'app.bk',
|
||||||
SRC_DIR / "builders.bk",
|
SRC_DIR / 'builders.bk',
|
||||||
SRC_DIR / "menu.bk",
|
SRC_DIR / 'menu.bk',
|
||||||
):
|
):
|
||||||
file.rename(PACKAGE_DIR / f"{file.stem}.py")
|
file.rename(PACKAGE_DIR / f'{file.stem}.py')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("-r", "--rewrite", action="store_true")
|
parser.add_argument('--rewrite', action='store_true')
|
||||||
parser.add_argument("-c", "--cleanup", action="store_true")
|
parser.add_argument('--theme', type=str, default='forest')
|
||||||
|
parser.add_argument('--restore', action='store_true')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.rewrite:
|
if args.rewrite:
|
||||||
logger.info("preparing files for build")
|
logger.info('preparing files for build')
|
||||||
prepare_for_build()
|
prepare_for_build(args.theme)
|
||||||
elif args.cleanup:
|
elif args.restore:
|
||||||
logger.info("cleaning up files")
|
logger.info('cleaning up files')
|
||||||
cleanup()
|
cleanup()
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ class ChannelLabelFrameBuilder(AbstractBuilder):
|
|||||||
"""Adds a progress bar widget to a single label frame"""
|
"""Adds a progress bar widget to a single label frame"""
|
||||||
self.labelframe.pb = ttk.Progressbar(
|
self.labelframe.pb = ttk.Progressbar(
|
||||||
self.labelframe,
|
self.labelframe,
|
||||||
maximum=72,
|
maximum=72, # Range: 0 = -60dB, 72 = +12dB (72dB total range)
|
||||||
orient='vertical',
|
orient='vertical',
|
||||||
mode='determinate',
|
mode='determinate',
|
||||||
variable=self.labelframe.level,
|
variable=self.labelframe.level,
|
||||||
@@ -362,15 +362,15 @@ class StripConfigFrameBuilder(ChannelConfigFrameBuilder):
|
|||||||
tk.BooleanVar() for _ in self.configframe.virt_out_params
|
tk.BooleanVar() for _ in self.configframe.virt_out_params
|
||||||
]
|
]
|
||||||
|
|
||||||
self.configframe.params = ('mono', 'solo')
|
self.configframe.bool_params = ('mono', 'solo')
|
||||||
self.configframe.param_vars = list(
|
self.configframe.bool_param_vars = list(
|
||||||
tk.BooleanVar() for _ in self.configframe.params
|
tk.BooleanVar() for _ in self.configframe.bool_params
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.configframe.parent.kind.name in ('banana', 'potato'):
|
if self.configframe.parent.kind.name in ('banana', 'potato'):
|
||||||
if self.configframe.index == self.configframe.phys_in:
|
if self.configframe.index == self.configframe.phys_in:
|
||||||
self.configframe.params = list(
|
self.configframe.params = list(
|
||||||
map(lambda x: x.replace('mono', 'mc'), self.configframe.params)
|
map(lambda x: x.replace('mono', 'mc'), self.configframe.bool_params)
|
||||||
)
|
)
|
||||||
if self.configframe.parent.kind.name == 'banana':
|
if self.configframe.parent.kind.name == 'banana':
|
||||||
pass
|
pass
|
||||||
@@ -388,7 +388,10 @@ class StripConfigFrameBuilder(ChannelConfigFrameBuilder):
|
|||||||
== self.configframe.phys_in + self.configframe.virt_in - 1
|
== self.configframe.phys_in + self.configframe.virt_in - 1
|
||||||
):
|
):
|
||||||
self.configframe.params = list(
|
self.configframe.params = list(
|
||||||
map(lambda x: x.replace('mono', 'mc'), self.configframe.params)
|
map(
|
||||||
|
lambda x: x.replace('mono', 'mc'),
|
||||||
|
self.configframe.bool_params,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def create_comp_slider(self):
|
def create_comp_slider(self):
|
||||||
@@ -542,9 +545,9 @@ class StripConfigFrameBuilder(ChannelConfigFrameBuilder):
|
|||||||
self.configframe.pause_updates, self.configframe.toggle_p, param
|
self.configframe.pause_updates, self.configframe.toggle_p, param
|
||||||
),
|
),
|
||||||
style=f'{"Toggle.TButton" if _configuration.themes_enabled else f"{param}.TButton"}',
|
style=f'{"Toggle.TButton" if _configuration.themes_enabled else f"{param}.TButton"}',
|
||||||
variable=self.configframe.param_vars[i],
|
variable=self.configframe.bool_param_vars[i],
|
||||||
)
|
)
|
||||||
for i, param in enumerate(self.configframe.params)
|
for i, param in enumerate(self.configframe.bool_params)
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
button.grid(
|
button.grid(
|
||||||
@@ -574,10 +577,22 @@ class BusConfigFrameBuilder(ChannelConfigFrameBuilder):
|
|||||||
"lfeonly": "LFE Only",
|
"lfeonly": "LFE Only",
|
||||||
"rearonly": "Rear Only",
|
"rearonly": "Rear Only",
|
||||||
}
|
}
|
||||||
|
self.configframe.bus_mode_map_reverse = {v: k for k, v in self.configframe.bus_mode_map.items()}
|
||||||
self.configframe.bus_modes = list(self.configframe.bus_mode_map.keys())
|
self.configframe.bus_modes = list(self.configframe.bus_mode_map.keys())
|
||||||
# fmt: on
|
# fmt: on
|
||||||
self.configframe.params = ('mono', 'eq.on', 'eq.ab')
|
self.configframe.int_params = ('mono',)
|
||||||
self.configframe.param_vars = [tk.BooleanVar() for _ in self.configframe.params]
|
self.configframe.int_param_vars = [
|
||||||
|
tk.IntVar(value=getattr(self.configframe.target, param))
|
||||||
|
for param in self.configframe.int_params
|
||||||
|
]
|
||||||
|
self.configframe.mono_modes = ['mono: off', 'mono: on', 'stereo reverse']
|
||||||
|
self.configframe.bus_mono_label_text = tk.StringVar(
|
||||||
|
value=self.configframe.mono_modes[self.configframe.target.mono]
|
||||||
|
)
|
||||||
|
self.configframe.bool_params = ('eq.on', 'eq.ab')
|
||||||
|
self.configframe.bool_param_vars = [
|
||||||
|
tk.BooleanVar() for _ in self.configframe.bool_params
|
||||||
|
]
|
||||||
self.configframe.bus_mode_label_text = tk.StringVar(
|
self.configframe.bus_mode_label_text = tk.StringVar(
|
||||||
value=self.configframe.bus_mode_map[self.configframe.current_bus_mode()]
|
value=self.configframe.bus_mode_map[self.configframe.current_bus_mode()]
|
||||||
)
|
)
|
||||||
@@ -602,6 +617,20 @@ class BusConfigFrameBuilder(ChannelConfigFrameBuilder):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def create_bus_mono_button(self):
|
||||||
|
self.configframe.mono_button = ttk.Button(
|
||||||
|
self.configframe, textvariable=self.configframe.bus_mono_label_text
|
||||||
|
)
|
||||||
|
self.configframe.mono_button.bind(
|
||||||
|
'<Button-1>',
|
||||||
|
partial(self.configframe.pause_updates, self.configframe.rotate_mono_right),
|
||||||
|
)
|
||||||
|
self.configframe.mono_button.bind(
|
||||||
|
'<Button-3>',
|
||||||
|
partial(self.configframe.pause_updates, self.configframe.rotate_mono_left),
|
||||||
|
)
|
||||||
|
self.configframe.mono_button.grid(column=0, row=1, sticky=(tk.W))
|
||||||
|
|
||||||
def create_param_buttons(self):
|
def create_param_buttons(self):
|
||||||
param_buttons = [
|
param_buttons = [
|
||||||
ttk.Checkbutton(
|
ttk.Checkbutton(
|
||||||
@@ -611,13 +640,13 @@ class BusConfigFrameBuilder(ChannelConfigFrameBuilder):
|
|||||||
self.configframe.pause_updates, self.configframe.toggle_p, param
|
self.configframe.pause_updates, self.configframe.toggle_p, param
|
||||||
),
|
),
|
||||||
style=f'{"Toggle.TButton" if _configuration.themes_enabled else f"{param}.TButton"}',
|
style=f'{"Toggle.TButton" if _configuration.themes_enabled else f"{param}.TButton"}',
|
||||||
variable=self.configframe.param_vars[i],
|
variable=self.configframe.bool_param_vars[i],
|
||||||
)
|
)
|
||||||
for i, param in enumerate(self.configframe.params)
|
for i, param in enumerate(self.configframe.bool_params)
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
button.grid(
|
button.grid(
|
||||||
column=i,
|
column=i + 1,
|
||||||
row=1,
|
row=1,
|
||||||
)
|
)
|
||||||
for i, button in enumerate(param_buttons)
|
for i, button in enumerate(param_buttons)
|
||||||
|
|||||||
@@ -197,14 +197,22 @@ class Strip(ChannelLabelFrame):
|
|||||||
|
|
||||||
def upd_levels(self):
|
def upd_levels(self):
|
||||||
"""
|
"""
|
||||||
Updates level values.
|
Updates level values using direct dB values.
|
||||||
"""
|
"""
|
||||||
if self.index < self.parent.parent.kind.num_strip:
|
if self.index < self.parent.parent.kind.num_strip:
|
||||||
if self.target.levels.is_updated:
|
if self.target.levels.is_updated:
|
||||||
val = max(self.target.levels.prefader)
|
val = max(self.target.levels.prefader)
|
||||||
self.level.set(
|
if val < -72:
|
||||||
(0 if self.mute.get() else 72 + val - 12 + self.gain.get())
|
if self.level.get() != 0:
|
||||||
)
|
self.level.set(0)
|
||||||
|
return
|
||||||
|
# Convert dB to progressbar: -60dB=0, 0dB=60, +12dB=72
|
||||||
|
if self.mute.get():
|
||||||
|
level_display = 0
|
||||||
|
else:
|
||||||
|
level_db = val + self.gain.get()
|
||||||
|
level_display = max(0, min(72, level_db + 60))
|
||||||
|
self.level.set(level_display)
|
||||||
|
|
||||||
|
|
||||||
class Bus(ChannelLabelFrame):
|
class Bus(ChannelLabelFrame):
|
||||||
@@ -223,9 +231,18 @@ class Bus(ChannelLabelFrame):
|
|||||||
|
|
||||||
def upd_levels(self):
|
def upd_levels(self):
|
||||||
if self.index < self.parent.parent.kind.num_bus:
|
if self.index < self.parent.parent.kind.num_bus:
|
||||||
if self.target.levels.is_updated or self.level.get() != -118:
|
if self.target.levels.is_updated:
|
||||||
val = max(self.target.levels.all)
|
val = max(self.target.levels.all)
|
||||||
self.level.set((0 if self.mute.get() else 72 + val - 12))
|
if val < -72:
|
||||||
|
if self.level.get() != 0:
|
||||||
|
self.level.set(0)
|
||||||
|
return
|
||||||
|
# Convert dB to progressbar: -60dB=0, 0dB=60, +12dB=72
|
||||||
|
if self.mute.get():
|
||||||
|
level_display = 0
|
||||||
|
else:
|
||||||
|
level_display = max(0, min(72, val + 60))
|
||||||
|
self.level.set(level_display)
|
||||||
|
|
||||||
|
|
||||||
class ChannelFrame(ttk.Frame):
|
class ChannelFrame(ttk.Frame):
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ class Config(ttk.Frame):
|
|||||||
self.slider_vars[self.slider_params.index(param)].set(val)
|
self.slider_vars[self.slider_params.index(param)].set(val)
|
||||||
|
|
||||||
def toggle_p(self, param):
|
def toggle_p(self, param):
|
||||||
val = self.param_vars[self.params.index(param)].get()
|
val = self.bool_param_vars[self.bool_params.index(param)].get()
|
||||||
self.setter(param, val)
|
self.setter(param, val)
|
||||||
if not _configuration.themes_enabled:
|
if not _configuration.themes_enabled:
|
||||||
self.styletable.configure(
|
self.styletable.configure(
|
||||||
@@ -177,15 +177,14 @@ class StripConfig(Config):
|
|||||||
for i, param in enumerate(self.virt_out_params)
|
for i, param in enumerate(self.virt_out_params)
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
self.param_vars[i].set(self.getter(param))
|
self.bool_param_vars[i].set(self.getter(param))
|
||||||
for i, param in enumerate(self.params)
|
for i, param in enumerate(self.bool_params)
|
||||||
|
]
|
||||||
|
[
|
||||||
|
self.slider_vars[i].set(self.getter(param))
|
||||||
|
for i, param in enumerate(self.slider_params)
|
||||||
|
if self.index < self.phys_in
|
||||||
]
|
]
|
||||||
if not _base_values.vban_connected: # slider vars not defined in RT Packet
|
|
||||||
[
|
|
||||||
self.slider_vars[i].set(self.getter(param))
|
|
||||||
for i, param in enumerate(self.slider_params)
|
|
||||||
if self.index < self.phys_in
|
|
||||||
]
|
|
||||||
|
|
||||||
if not _configuration.themes_enabled:
|
if not _configuration.themes_enabled:
|
||||||
[
|
[
|
||||||
@@ -207,7 +206,7 @@ class StripConfig(Config):
|
|||||||
f'{param}.TButton',
|
f'{param}.TButton',
|
||||||
background=f'{"green" if self.param_vars[i].get() else "white"}',
|
background=f'{"green" if self.param_vars[i].get() else "white"}',
|
||||||
)
|
)
|
||||||
for i, param in enumerate(self.params)
|
for i, param in enumerate(self.bool_params)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -238,53 +237,56 @@ class BusConfig(Config):
|
|||||||
self.builder.create_bus_mode_button()
|
self.builder.create_bus_mode_button()
|
||||||
|
|
||||||
def make_row_1(self):
|
def make_row_1(self):
|
||||||
|
self.builder.create_bus_mono_button()
|
||||||
self.builder.create_param_buttons()
|
self.builder.create_param_buttons()
|
||||||
|
|
||||||
def current_bus_mode(self):
|
def current_bus_mode(self):
|
||||||
return self.target.mode.get()
|
return self.target.mode.get()
|
||||||
|
|
||||||
def rotate_bus_modes_right(self, *args):
|
def rotate_bus_modes_right(self, *args):
|
||||||
current_mode = self.current_bus_mode()
|
current_mode = self.bus_mode_map_reverse[self.bus_mode_label_text.get()]
|
||||||
next = self.bus_modes.index(current_mode) + 1
|
current_index = self.bus_modes.index(current_mode)
|
||||||
if next < len(self.bus_modes):
|
next_index = (current_index + 1) % len(self.bus_modes)
|
||||||
setattr(
|
next_mode = self.bus_modes[next_index]
|
||||||
self.target.mode,
|
|
||||||
self.bus_modes[next],
|
setattr(self.target.mode, next_mode, True)
|
||||||
True,
|
self.bus_mode_label_text.set(self.bus_mode_map[next_mode])
|
||||||
)
|
|
||||||
self.bus_mode_label_text.set(self.bus_mode_map[self.bus_modes[next]])
|
|
||||||
else:
|
|
||||||
self.target.mode.normal = True
|
|
||||||
self.bus_mode_label_text.set('Normal')
|
|
||||||
|
|
||||||
def rotate_bus_modes_left(self, *args):
|
def rotate_bus_modes_left(self, *args):
|
||||||
current_mode = self.current_bus_mode()
|
current_mode = self.bus_mode_map_reverse[self.bus_mode_label_text.get()]
|
||||||
prev = self.bus_modes.index(current_mode) - 1
|
current_index = self.bus_modes.index(current_mode)
|
||||||
if prev < 0:
|
prev_index = (current_index - 1) % len(self.bus_modes)
|
||||||
self.target.mode.rearonly = True
|
prev_mode = self.bus_modes[prev_index]
|
||||||
self.bus_mode_label_text.set('Rear Only')
|
|
||||||
else:
|
setattr(self.target.mode, prev_mode, True)
|
||||||
setattr(
|
self.bus_mode_label_text.set(self.bus_mode_map[prev_mode])
|
||||||
self.target.mode,
|
|
||||||
self.bus_modes[prev],
|
def rotate_mono_right(self, *args):
|
||||||
True,
|
current_val = self.mono_modes.index(self.bus_mono_label_text.get())
|
||||||
)
|
next_val = (current_val + 1) % 3
|
||||||
self.bus_mode_label_text.set(self.bus_mode_map[self.bus_modes[prev]])
|
self.bus_mono_label_text.set(self.mono_modes[next_val])
|
||||||
|
self.setter('mono', next_val)
|
||||||
|
|
||||||
|
def rotate_mono_left(self, *args):
|
||||||
|
current_val = self.mono_modes.index(self.bus_mono_label_text.get())
|
||||||
|
next_val = (current_val - 1) % 3
|
||||||
|
self.bus_mono_label_text.set(self.mono_modes[next_val])
|
||||||
|
self.setter('mono', next_val)
|
||||||
|
|
||||||
def teardown(self):
|
def teardown(self):
|
||||||
self.builder.teardown()
|
self.builder.teardown()
|
||||||
|
|
||||||
def sync(self):
|
def sync(self):
|
||||||
[
|
[
|
||||||
self.param_vars[i].set(self.getter(param))
|
self.bool_param_vars[i].set(self.getter(param))
|
||||||
for i, param in enumerate(self.params)
|
for i, param in enumerate(self.bool_params)
|
||||||
]
|
]
|
||||||
self.bus_mode_label_text.set(self.bus_mode_map[self.current_bus_mode()])
|
self.bus_mode_label_text.set(self.bus_mode_map[self.current_bus_mode()])
|
||||||
if not _configuration.themes_enabled:
|
if not _configuration.themes_enabled:
|
||||||
[
|
[
|
||||||
self.styletable.configure(
|
self.styletable.configure(
|
||||||
f'{param}.TButton',
|
f'{param}.TButton',
|
||||||
background=f'{"green" if self.param_vars[i].get() else "white"}',
|
background=f'{"green" if self.bool_param_vars[i].get() else "white"}',
|
||||||
)
|
)
|
||||||
for i, param in enumerate(self.params)
|
for i, param in enumerate(self.bool_params)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ configuration = {}
|
|||||||
|
|
||||||
|
|
||||||
def get_configpath():
|
def get_configpath():
|
||||||
configpaths = [
|
for pn in (
|
||||||
|
Path.home() / '.config' / 'vm-compact',
|
||||||
|
Path.home() / 'Documents' / 'Voicemeeter' / 'vm-compact',
|
||||||
|
Path.cwd() / '_internal' / 'configs',
|
||||||
Path.cwd() / 'configs',
|
Path.cwd() / 'configs',
|
||||||
Path.home() / '.config' / 'vm-compact' / 'configs',
|
):
|
||||||
Path.home() / 'Documents' / 'Voicemeeter' / 'configs',
|
if pn.exists():
|
||||||
]
|
return pn
|
||||||
for configpath in configpaths:
|
|
||||||
if configpath.exists():
|
|
||||||
return configpath
|
|
||||||
|
|
||||||
|
|
||||||
if configpath := get_configpath():
|
if configpath := get_configpath():
|
||||||
@@ -60,7 +60,7 @@ _defaults = {
|
|||||||
'submixes': {
|
'submixes': {
|
||||||
'default': 0,
|
'default': 0,
|
||||||
},
|
},
|
||||||
'navigation': {'show': True},
|
'navigation': {'show': False},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -161,17 +161,18 @@ class GainLayer(ttk.LabelFrame):
|
|||||||
"""
|
"""
|
||||||
Updates level values.
|
Updates level values.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.parent.target.strip[self.index].levels.is_updated:
|
if self.parent.target.strip[self.index].levels.is_updated:
|
||||||
val = max(self.parent.target.strip[self.index].levels.prefader)
|
val = max(self.parent.target.strip[self.index].levels.prefader)
|
||||||
self.level.set(
|
# Convert dB to progressbar: -60dB=0, 0dB=60, +12dB=72
|
||||||
(
|
if (
|
||||||
0
|
self.parent.parent.strip_frame.strips[self.index].mute.get()
|
||||||
if self.parent.parent.strip_frame.strips[self.index].mute.get()
|
or not self.on.get()
|
||||||
or not self.on.get()
|
):
|
||||||
else 72 + val - 12 + self.gain.get()
|
level_display = 0
|
||||||
)
|
else:
|
||||||
)
|
level_db = val + self.gain.get()
|
||||||
|
level_display = max(0, min(72, level_db + 60))
|
||||||
|
self.level.set(level_display)
|
||||||
|
|
||||||
def grid_configure(self):
|
def grid_configure(self):
|
||||||
self.grid(padx=_configuration.channel_xpadding, sticky=(tk.N, tk.S))
|
self.grid(padx=_configuration.channel_xpadding, sticky=(tk.N, tk.S))
|
||||||
|
|||||||
@@ -357,15 +357,17 @@ class Menus(tk.Menu):
|
|||||||
opts = {}
|
opts = {}
|
||||||
opts |= self.vban_config[f'connection-{i + 1}']
|
opts |= self.vban_config[f'connection-{i + 1}']
|
||||||
kind_id = opts.pop('kind')
|
kind_id = opts.pop('kind')
|
||||||
|
if 'ip' in opts:
|
||||||
|
opts['host'] = opts.pop('ip')
|
||||||
self.vban = vban_cmd.api(kind_id, **opts)
|
self.vban = vban_cmd.api(kind_id, **opts)
|
||||||
# login to vban interface
|
# login to vban interface
|
||||||
try:
|
try:
|
||||||
self.logger.info(f'Attempting vban connection to {opts.get("ip")}')
|
self.logger.info(f'Attempting vban connection to {opts.get("host")}')
|
||||||
self.vban.login()
|
self.vban.login()
|
||||||
except VBANCMDConnectionError as e:
|
except VBANCMDConnectionError as e:
|
||||||
self.vban.logout()
|
self.vban.logout()
|
||||||
msg = (
|
msg = (
|
||||||
f'Timeout attempting to establish connection to {opts.get("ip")}',
|
f'Timeout attempting to establish connection to {opts.get("host")}',
|
||||||
'Please check your connection settings',
|
'Please check your connection settings',
|
||||||
)
|
)
|
||||||
messagebox.showerror('Connection Error', '\n'.join(msg))
|
messagebox.showerror('Connection Error', '\n'.join(msg))
|
||||||
@@ -421,7 +423,7 @@ class Menus(tk.Menu):
|
|||||||
del self.parent.__dict__['userconfigs']
|
del self.parent.__dict__['userconfigs']
|
||||||
self.menu_setup()
|
self.menu_setup()
|
||||||
|
|
||||||
self.after(15000, self.enable_vban_menus)
|
self.after(50, self.enable_vban_menus)
|
||||||
|
|
||||||
def documentation(self):
|
def documentation(self):
|
||||||
webbrowser.open_new(r'https://voicemeeter.com/')
|
webbrowser.open_new(r'https://voicemeeter.com/')
|
||||||
|
|||||||
Reference in New Issue
Block a user