An open source DAW for GNU/Linux, inspired by modular synths. http://noisicaa.odahoda.de/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
noisicaa/noisicaa/ui/ui_base.py

148 lines
4.1 KiB

#!/usr/bin/python3
# @begin:license
#
# Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# @end:license
import asyncio
import functools
import io
import typing
from typing import Any, Optional, Dict, Tuple, Callable, Awaitable
from PySide2 import QtCore
from PySide2 import QtGui
# from noisicaa.core.typing_extra import down_cast
# from noisicaa import audioproc
# from noisicaa import music
# from noisicaa import core
if typing.TYPE_CHECKING:
from noisicaa import engine as engine_lib
# from noisicaa import instrument_db as instrument_db_lib
# from noisicaa import node_db as node_db_lib
# from noisicaa import runtime_settings as runtime_settings_lib
# from noisicaa import lv2
# from . import clipboard
# from . import device_list
# from . import instrument_list as instrument_list_lib
from . import main
from . import project as project_lib
# from . import editor_window
# from . import engine_state as engine_state_lib
def async_cb(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
task = asyncio.create_task(func(*args, **kwargs))
return wrapper
def ConstProperty(pytype, qtype=None):
if qtype is None:
qtype = pytype
def decorator(func):
return QtCore.Property(qtype, fget=func, constant=True)
return decorator
def Property(name, pytype, qtype=None, *, default=None, validate=None):
if qtype is None:
qtype = pytype
if default is None:
default = pytype()
sig = QtCore.Signal(qtype)
def setter(self, value):
if validate is not None:
validate(self, value)
old_value = self._ui_property_values.get(name, default)
if value != old_value:
self._ui_property_values[name] = value
sig.__get__(self).emit(value)
def getter(self):
return self._ui_property_values.get(name, default)
prop = QtCore.Property(qtype, fget=getter, fset=setter, notify=sig)
return prop, sig
class PropertyContainer(object):
def __init__(self, **kwargs) -> None:
super().__init__(**kwargs)
self._ui_property_values = {} # type: Dict[str, Any]
class CommonContext(object):
def __init__(self, *, app: 'main.App') -> None:
self.app = app
class CommonMixin(object):
def __init__(self, *, context: CommonContext, **kwargs: Any) -> None:
self._context = context
# This is a mixin class, so actual super class is not object.
super().__init__(**kwargs) # type: ignore[call-arg]
@property
def context(self) -> CommonContext:
return self._context
@property
def qtApp(self) -> QtGui.QGuiApplication:
return self._context.app.qtApp
@ConstProperty(QtCore.QObject)
def app(self) -> 'main.App':
return self._context.app
@property
def dataDir(self) -> str:
return self._context.app.dataDir
@property
def engine(self) -> 'engine_lib.Engine':
return self._context.app.engine
class ProjectContext(CommonContext):
def __init__(
self, *,
project: 'project_lib.Project',
**kwargs: Any) -> None:
super().__init__(**kwargs)
self.project = project
class ProjectMixin(CommonMixin):
_context = None # type: ProjectContext
def project(self) -> 'project_lib.Project':
return self._context.project
project = QtCore.Property(QtCore.QObject, fget=project, constant=True)