Compare commits

..

No commits in common. "dacc972b1730924eb34f040b30d5248eb71f0e5a" and "bde9020471f0154f7ab9ad4369587ca5aff66ec5" have entirely different histories.

9 changed files with 22 additions and 157 deletions

View File

@ -131,11 +131,9 @@ For Gate BP Sidechain, Attack, Hold, Release you may use:
To reset a slider back to its default value you may use `Control + Shift + R`.
### Menu
#### `Menu`
#### `Voicemeeter`
The `Voicemeeter` menu can be opened using `Alt` and then `v`. It offers the following options:
A single menu item `Voicemeeter` can be opened using `Alt` and then `v`. The menu allows you to:
- Restart Voicemeeter audio engine
- Save/Load current settings (as an xml file)
@ -145,11 +143,7 @@ The `Save Settings` option opens a popup window with two buttons, `Browse` and `
`Load Settings` and `Load on Startup` both open an Open dialog box immediately.
#### `Theme`
The `Theme` menu can be opened using `Alt` and then `t`. Use this menu to select from a list of coloured themes. Some themes offer higher contrast colours. An application restart is required to load a new theme. Once a theme is selected it will become the default for future startups.
### Quick access binds
### `Quick access binds`
There are a number of quick binds available to assist with faster navigation and general use.

37
pdm.lock generated
View File

@ -5,7 +5,7 @@
groups = ["default", "build", "lint", "test"]
strategy = ["cross_platform"]
lock_version = "4.4"
content_hash = "sha256:4295f6824f37484ec423b53bd425334b0e039a51d81261b52c8890928fcf3948"
content_hash = "sha256:ca47eaae0de5aa6bcc3fde33b6c1fa7dc2476aeb680f00bb1c550fe06ad67c55"
[[package]]
name = "altgraph"
@ -74,31 +74,6 @@ files = [
{file = "macholib-1.16.2.tar.gz", hash = "sha256:557bbfa1bb255c20e9abafe7ed6cd8046b48d9525db2f9b77d3122a63a2a8bf8"},
]
[[package]]
name = "mypy"
version = "1.7.0"
requires_python = ">=3.8"
summary = "Optional static typing for Python"
dependencies = [
"mypy-extensions>=1.0.0",
"tomli>=1.1.0; python_version < \"3.11\"",
"typing-extensions>=4.1.0",
]
files = [
{file = "mypy-1.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5da84d7bf257fd8f66b4f759a904fd2c5a765f70d8b52dde62b521972a0a2357"},
{file = "mypy-1.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a3637c03f4025f6405737570d6cbfa4f1400eb3c649317634d273687a09ffc2f"},
{file = "mypy-1.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b633f188fc5ae1b6edca39dae566974d7ef4e9aaaae00bc36efe1f855e5173ac"},
{file = "mypy-1.7.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d6ed9a3997b90c6f891138e3f83fb8f475c74db4ccaa942a1c7bf99e83a989a1"},
{file = "mypy-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:1fe46e96ae319df21359c8db77e1aecac8e5949da4773c0274c0ef3d8d1268a9"},
{file = "mypy-1.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:df67fbeb666ee8828f675fee724cc2cbd2e4828cc3df56703e02fe6a421b7401"},
{file = "mypy-1.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a79cdc12a02eb526d808a32a934c6fe6df07b05f3573d210e41808020aed8b5d"},
{file = "mypy-1.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f65f385a6f43211effe8c682e8ec3f55d79391f70a201575def73d08db68ead1"},
{file = "mypy-1.7.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e81ffd120ee24959b449b647c4b2fbfcf8acf3465e082b8d58fd6c4c2b27e46"},
{file = "mypy-1.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:f29386804c3577c83d76520abf18cfcd7d68264c7e431c5907d250ab502658ee"},
{file = "mypy-1.7.0-py3-none-any.whl", hash = "sha256:96650d9a4c651bc2a4991cf46f100973f656d69edc7faf91844e87fe627f7e96"},
{file = "mypy-1.7.0.tar.gz", hash = "sha256:1e280b5697202efa698372d2f39e9a6713a0395a756b1c6bd48995f8d72690dc"},
]
[[package]]
name = "mypy-extensions"
version = "1.0.0"
@ -273,16 +248,6 @@ files = [
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
[[package]]
name = "typing-extensions"
version = "4.8.0"
requires_python = ">=3.8"
summary = "Backported and Experimental Type Hints for Python 3.8+"
files = [
{file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"},
{file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"},
]
[[package]]
name = "voicemeeter-api"
version = "2.5.2"

View File

@ -1,6 +1,6 @@
[project]
name = "nvda_voicemeeter"
version = "0.6.0"
version = "0.5.6"
description = "A Voicemeeter app compatible with NVDA"
authors = [
{ name = "onyx-and-iris", email = "code@onyxandiris.online" },
@ -23,7 +23,6 @@ build = [
lint = [
"black>=23.7.0",
"ruff>=0.0.291",
"mypy>=1.7.0",
]
test = [
"psgdemos>=1.12.1",

View File

@ -92,8 +92,6 @@ class Builder:
return [[menu], [tab_group]]
def make_menu(self) -> psg.Menu:
themes = [f"{theme}::MENU THEME" for theme in util.get_themes_list()]
themes.append("Default::MENU THEME")
menu_def = [
[
"&Voicemeeter",
@ -104,7 +102,6 @@ class Builder:
"Load Settings on Startup ::MENU",
],
],
["&Theme", themes],
]
return psg.Menu(menu_def, key="menus")

View File

@ -5,7 +5,7 @@ from pathlib import Path
from .errors import NVDAVMError
bits = 64 if ct.sizeof(ct.c_void_p) == 8 else 32
bits = 64 if ct.sizeof(ct.c_voidp) == 8 else 32
if platform.system() != "Windows":
raise NVDAVMError("Only Windows OS supported")

View File

@ -12,9 +12,6 @@ class LabelSlider(psg.Frame):
self.parent = parent
if param in ("AUDIBILITY", "DENOISER"):
size = 7
else:
if psg.theme() == "HighContrast":
size = 5
else:
size = 4
layout = [

View File

@ -1,34 +0,0 @@
import json
from pathlib import Path
SETTINGS = Path.cwd() / "settings.json"
def config_from_json():
data = {}
if not SETTINGS.exists():
return data
with open(SETTINGS, "r") as f:
data = json.load(f)
return data
config = config_from_json()
def get(key, default=None):
if key in config:
return config[key]
return default
def set(key, value):
config[key] = value
with open(SETTINGS, "w") as f:
json.dump(config, f)
def delete(key):
del config[key]
with open(SETTINGS, "w") as f:
json.dump(config, f)

View File

@ -1,7 +1,5 @@
from typing import Iterable
import PySimpleGUI as psg
def get_asio_input_spinbox_index(channel, num) -> int:
if channel == 0:
@ -198,45 +196,3 @@ def get_slider_modes() -> Iterable:
def _get_bus_assignments(kind) -> list:
return [f"A{i}" for i in range(1, kind.phys_out + 1)] + [f"B{i}" for i in range(1, kind.virt_out + 1)]
psg.theme_add_new(
"HighContrast",
{
"BACKGROUND": "#FFFFFF",
"TEXT": "#000000",
"INPUT": "#FAF9F6",
"TEXT_INPUT": "#000000",
"SCROLL": "#FAF9F6",
"BUTTON": ("#000000", "#FFFFFF"),
"PROGRESS": ("#000000", "#FFFFFF"),
"BORDER": 2,
"SLIDER_DEPTH": 3,
"PROGRESS_DEPTH": 0,
},
)
def get_themes_list() -> list:
return [
"Bright Colors",
"Dark Blue 14",
"Dark Brown 2",
"Dark Brown 3",
"Dark Green 2",
"Dark Grey 2",
"Dark Teal1",
"Dark Teal6",
"Kayak",
"Light Blue 2",
"Light Brown 2",
"Light Brown 5",
"Light Green",
"Light Green 3",
"Light Grey 2",
"Light Purple",
"Neutral Blue",
"Reds",
"Sandy Beach",
"High Contrast",
]

View File

@ -4,7 +4,7 @@ from pathlib import Path
import PySimpleGUI as psg
from . import configuration, models, util
from . import models, util
from .builder import Builder
from .nvda import Nvda
from .parser import Parser
@ -12,19 +12,18 @@ from .popup import Popup
logger = logging.getLogger(__name__)
psg.theme(configuration.get("default_theme", "Dark Blue 3"))
if psg.theme() == "HighContrast":
psg.set_options(font=("Arial", 14))
psg.theme("Dark Blue 3")
class NVDAVMWindow(psg.Window):
"""Represents the main window of the Voicemeeter NVDA application"""
SETTINGS = "settings.json"
def __init__(self, title, vm):
self.vm = vm
self.kind = self.vm.kind
self.logger = logger.getChild(type(self).__name__)
self.logger.debug(f"loaded with theme: {psg.theme()}")
self.cache = {
"hw_ins": models._make_hardware_ins_cache(self.vm),
"hw_outs": models._make_hardware_outs_cache(self.vm),
@ -64,11 +63,13 @@ class NVDAVMWindow(psg.Window):
self["tabgroup"].set_focus()
def __enter__(self):
settings_path = configuration.SETTINGS
settings_path = Path.cwd() / self.SETTINGS
if settings_path.exists():
try:
defaultconfig = Path(configuration.get("default_config", "")) # coerce the type
if defaultconfig.is_file() and defaultconfig.exists():
with open(settings_path, "r") as f:
data = json.load(f)
defaultconfig = Path(data["default_config"])
if defaultconfig.exists():
self.vm.set("command.load", str(defaultconfig))
self.logger.debug(f"config {defaultconfig} loaded")
self.TKroot.after(
@ -77,7 +78,7 @@ class NVDAVMWindow(psg.Window):
f"config {defaultconfig.stem} has been loaded",
)
except json.JSONDecodeError:
self.logger.debug("no default_config in settings.json. silently continuing...")
self.logger.debug("no data in settings.json. silently continuing...")
self.vm.init_thread()
self.vm.observer.add(self.on_pdirty)
@ -509,27 +510,17 @@ class NVDAVMWindow(psg.Window):
file_types=(("XML", ".xml"),),
):
filepath = Path(filepath)
configuration.set("default_settings", str(filepath))
with open(self.SETTINGS, "w") as f:
json.dump({"default_config": str(filepath)}, f)
self.TKroot.after(
200,
self.nvda.speak,
f"config {filepath.stem} set as default on startup",
)
else:
configuration.delete("default_settings")
self.logger.debug("default_settings removed from settings.json")
case [theme, ["MENU", "THEME"]]:
chosen = " ".join(theme)
if chosen == "Default":
chosen = "Dark Blue 3"
configuration.set("default_theme", chosen)
self.TKroot.after(
200,
self.nvda.speak,
f"theme {chosen} selected.",
)
self.logger.debug(f"theme {chosen} selected")
with open(self.SETTINGS, "wb") as f:
f.truncate()
self.logger.debug("settings.json was truncated")
# Tabs
case ["tabgroup"] | [["tabgroup"], ["FOCUS", "IN"]]: