diff --git a/.vscode/settings.json b/.vscode/settings.json index 51d96066..ebed0f9e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -60,6 +60,7 @@ "C_Cpp.default.defines": [ "_DEBUG=1", "STONEYVCV_EXPERIMENTAL", + "STONEYVCV_BUILD_COMPONENTLIBRARY=1", "STONEYVCV_BUILD_PLUGIN=1", "STONEYVCV_BUILD_MODULES=1", "STONEYVCV_BUILD_HP4=1", diff --git a/CMakeLists.txt b/CMakeLists.txt index e964dfe8..4e695fa5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,68 +7,10 @@ set(STONEYVCV_SLUG "StoneyVCV" CACHE STRING "" FORCE) set(STONEYVCV_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" CACHE PATH "" FORCE) set(STONEYVCV_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE PATH "" FORCE) -# https://softwareengineering.stackexchange.com/questions/141973/how-do-you-achieve-a-numeric-versioning-scheme-with-git -# 'git rev-list HEAD | wc -l' -find_package(Git REQUIRED) -execute_process( - COMMAND "${GIT_EXECUTABLE}" "rev-list" "HEAD" - COMMAND "wc" "-l" - WORKING_DIRECTORY "${STONEYVCV_SOURCE_DIR}" - OUTPUT_VARIABLE _STONEYVCV_GIT_COMMIT_COUNT - ERROR_VARIABLE _STONEYVCV_GIT_COMMIT_COUNT_ERROR -) -if(_STONEYVCV_GIT_COMMIT_COUNT_ERROR) - message(SEND_ERROR "${_STONEYVCV_GIT_COMMIT_COUNT_ERROR}") -endif() -execute_process( - COMMAND "${GIT_EXECUTABLE}" "rev-parse" "HEAD" - WORKING_DIRECTORY "${STONEYVCV_SOURCE_DIR}" - OUTPUT_VARIABLE _STONEYVCV_GIT_REF_HEAD - ERROR_VARIABLE _STONEYVCV_GIT_REF_HEAD_ERROR -) -if(_STONEYVCV_GIT_REF_HEAD_ERROR) - message(SEND_ERROR "${_STONEYVCV_GIT_REF_HEAD_ERROR}") -endif() -execute_process( - COMMAND "${GIT_EXECUTABLE}" "rev-parse" "--short" "HEAD" - WORKING_DIRECTORY "${STONEYVCV_SOURCE_DIR}" - OUTPUT_VARIABLE _STONEYVCV_GIT_REF_HEAD_SHORT - ERROR_VARIABLE _STONEYVCV_GIT_REF_HEAD_SHORT_ERROR -) -if(_STONEYVCV_GIT_REF_HEAD_SHORT_ERROR) - message(SEND_ERROR "${_STONEYVCV_GIT_REF_HEAD_SHORT_ERROR}") -endif() -execute_process( - COMMAND "${GIT_EXECUTABLE}" rev-parse --abbrev-ref --symbolic-full-name HEAD - WORKING_DIRECTORY "${STONEYVCV_SOURCE_DIR}" - OUTPUT_VARIABLE _STONEYVCV_GIT_BRANCH - ERROR_VARIABLE _STONEYVCV_GIT_BRANCH_ERROR -) -if(_STONEYVCV_GIT_BRANCH_ERROR) - message(SEND_ERROR "${_STONEYVCV_GIT_BRANCH_ERROR}") -endif() -string(STRIP "${_STONEYVCV_GIT_COMMIT_COUNT}" STONEYVCV_GIT_COMMIT_COUNT) -string(STRIP "${_STONEYVCV_GIT_REF_HEAD}" _STONEYVCV_GIT_REF_HEAD) -string(STRIP "${_STONEYVCV_GIT_REF_HEAD_SHORT}" _STONEYVCV_GIT_REF_HEAD_SHORT) -string(STRIP "${_STONEYVCV_GIT_BRANCH}" STONEYVCV_GIT_BRANCH) - -string(HEX "${_STONEYVCV_GIT_REF_HEAD}" STONEYVCV_GIT_REF_HEAD) -string(HEX "${_STONEYVCV_GIT_REF_HEAD_SHORT}" STONEYVCV_GIT_REF_HEAD_SHORT) - -file(READ "${CMAKE_CURRENT_LIST_DIR}/plugin.json" STONEYVCV_PLUGIN_JSON) -string(CONFIGURE "2.0.@STONEYVCV_GIT_COMMIT_COUNT@" _STONEYVCV_PLUGIN_JSON_VERSION @ONLY) -string(JSON _STONEYVCV_PLUGIN_JSON ERROR_VARIABLE _STONEYVCV_PLUGIN_JSON_SET_ROOT_ERROR SET "${STONEYVCV_PLUGIN_JSON}" "version" "\"${_STONEYVCV_PLUGIN_JSON_VERSION}\"") +list(APPEND CMAKE_MODULE_PATH "${STONEYVCV_SOURCE_DIR}/share/cmake/Modules") -if(_STONEYVCV_PLUGIN_JSON_SET_ROOT_ERROR) - message(FATAL_ERROR "${_STONEYVCV_PLUGIN_JSON_SET_ROOT_ERROR}") -endif(_STONEYVCV_PLUGIN_JSON_SET_ROOT_ERROR) - -file(WRITE "${CMAKE_CURRENT_LIST_DIR}/plugin.json.tmp" "${_STONEYVCV_PLUGIN_JSON}") -execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_LIST_DIR}/plugin.json.tmp" "${CMAKE_CURRENT_LIST_DIR}/plugin.json") -file(REMOVE "${CMAKE_CURRENT_LIST_DIR}/plugin.json.tmp") - -unset(_STONEYVCV_PLUGIN_JSON) -unset(_STONEYVCV_PLUGIN_JSON_VERSION) +include(StoneyVCVVersionHelpers) +stoneyvcv_git_versions() #[==================================[project]==================================] project(STONEYVCV @@ -86,14 +28,15 @@ include(CMakeDependentOption) include(GNUInstallDirs) option(STONEYVCV_EXPERIMENTAL "Use '-DSTONEYVCV_EXPERIMENTAL=ON|OFF' when configuring to toggle this option." OFF) -option(STONEYVCV_BUILD_DOCS "" OFF) -option(STONEYVCV_BUILD_PLUGIN "Use '-DSTONEYVCV_BUILD_PLUGIN=ON|OFF' when configuring to toggle this option." ON) -cmake_dependent_option(STONEYVCV_BUILD_MODULES "Use '-DSTONEYVCV_BUILD_MODULES=ON|OFF' when configuring to toggle this option." ON "STONEYVCV_BUILD_PLUGIN" ON) -cmake_dependent_option(STONEYVCV_BUILD_HP1 "Use '-DSTONEYVCV_BUILD_HP1=ON|OFF' when configuring to toggle this option." ON "STONEYVCV_BUILD_MODULES" ON) -cmake_dependent_option(STONEYVCV_BUILD_HP2 "Use '-DSTONEYVCV_BUILD_HP2=ON|OFF' when configuring to toggle this option." ON "STONEYVCV_BUILD_MODULES" ON) -cmake_dependent_option(STONEYVCV_BUILD_HP4 "Use '-DSTONEYVCV_BUILD_HP4=ON|OFF' when configuring to toggle this option." ON "STONEYVCV_BUILD_MODULES" ON) -cmake_dependent_option(STONEYVCV_BUILD_VCA "Use '-DSTONEYVCV_BUILD_VCA=ON|OFF' when configuring to toggle this option." ON "STONEYVCV_BUILD_MODULES" ON) -cmake_dependent_option(STONEYVCV_BUILD_LFO "Use '-DSTONEYVCV_BUILD_LFO=ON|OFF' when configuring to toggle this option." ON "STONEYVCV_EXPERIMENTAL" ON) +option(STONEYVCV_BUILD_DOCS "" OFF) +option(STONEYVCV_BUILD_COMPONENTLIBRARY "" ON) +cmake_dependent_option(STONEYVCV_BUILD_PLUGIN "Use '-DSTONEYVCV_BUILD_PLUGIN=ON|OFF' when configuring to toggle this option." ON "STONEYVCV_BUILD_COMPONENTLIBRARY" ON) +cmake_dependent_option(STONEYVCV_BUILD_MODULES "Use '-DSTONEYVCV_BUILD_MODULES=ON|OFF' when configuring to toggle this option." ON "STONEYVCV_BUILD_PLUGIN;STONEYVCV_BUILD_COMPONENTLIBRARY" ON) +cmake_dependent_option(STONEYVCV_BUILD_HP1 "Use '-DSTONEYVCV_BUILD_HP1=ON|OFF' when configuring to toggle this option." ON "STONEYVCV_BUILD_MODULES;STONEYVCV_BUILD_PLUGIN;STONEYVCV_BUILD_COMPONENTLIBRARY" ON) +cmake_dependent_option(STONEYVCV_BUILD_HP2 "Use '-DSTONEYVCV_BUILD_HP2=ON|OFF' when configuring to toggle this option." ON "STONEYVCV_BUILD_MODULES;STONEYVCV_BUILD_PLUGIN;STONEYVCV_BUILD_COMPONENTLIBRARY" ON) +cmake_dependent_option(STONEYVCV_BUILD_HP4 "Use '-DSTONEYVCV_BUILD_HP4=ON|OFF' when configuring to toggle this option." ON "STONEYVCV_BUILD_MODULES;STONEYVCV_BUILD_PLUGIN;STONEYVCV_BUILD_COMPONENTLIBRARY" ON) +cmake_dependent_option(STONEYVCV_BUILD_VCA "Use '-DSTONEYVCV_BUILD_VCA=ON|OFF' when configuring to toggle this option." ON "STONEYVCV_BUILD_MODULES;STONEYVCV_BUILD_PLUGIN;STONEYVCV_BUILD_COMPONENTLIBRARY" ON) +cmake_dependent_option(STONEYVCV_BUILD_LFO "Use '-DSTONEYVCV_BUILD_LFO=ON|OFF' when configuring to toggle this option." ON "STONEYVCV_EXPERIMENTAL;STONEYVCV_BUILD_PLUGIN;STONEYVCV_BUILD_COMPONENTLIBRARY" ON) cmake_dependent_option(STONEYVCV_BUILD_TESTS "Use '-DSTONEYVCV_BUILD_TESTS=ON|OFF' when configuring to toggle this option." ON "STONEYVCV_IS_TOP_LEVEL" ON) # Put components in the correct order of their dependencies on eachother to save tears... @@ -108,72 +51,53 @@ set(STONEYVCV_VERSION "${CMAKE_PROJECT_VERSION}" CACHE STRING "" FORCE) # Validate plugin.json vcvrack_get_plugin_version() - -if(NOT "${VCVRACK_PLUGIN_VERSION}" STREQUAL "${STONEYVCV_VERSION_MAJOR}.${STONEYVCV_VERSION_MINOR}.${STONEYVCV_VERSION_PATCH}") - set(_STONEYVCV_ERROR_STRING [==[ - -There is a mismatch between plugin versions in 'plugin.json' and 'CMakeLists.txt': -plugin.json#version: @VCVRACK_PLUGIN_VERSION@ -project(VERSION @STONEYVCV_VERSION_MAJOR@.@STONEYVCV_VERSION_MINOR@.@STONEYVCV_VERSION_PATCH@ -Please update the version number in the following files in order to silence this error: -@STONEYVCV_SOURCE_DIR@/plugin.json -@STONEYVCV_SOURCE_DIR@/CMakeLists.txt - ]==]) - string(CONFIGURE "${_STONEYVCV_ERROR_STRING}" STONEYVCV_ERROR_STRING @ONLY) - if("${CMAKE_BUILD_TYPE}" STREQUAL "Release") - message(SEND_ERROR "${STONEYVCV_ERROR_STRING}") - return() - elseif("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - message(WARNING "${STONEYVCV_ERROR_STRING}") - endif() -endif() - -set(STONEYVCV_VERSION_FILE "${STONEYVCV_SOURCE_DIR}/VERSION") -file(WRITE "${STONEYVCV_VERSION_FILE}.tmp" "${STONEYVCV_VERSION_MAJOR}.${STONEYVCV_VERSION_MINOR}.${STONEYVCV_VERSION_PATCH}.${STONEYVCV_VERSION_TWEAK}\n") -execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${STONEYVCV_VERSION_FILE}.tmp" "${STONEYVCV_VERSION_FILE}") -file(REMOVE "${STONEYVCV_VERSION_FILE}.tmp") -set(STONEYVCV_VERSION_FILE "${STONEYVCV_VERSION_FILE}" CACHE INTERNAL "StoneyVCV current version file." FORCE) - +stoneyvcv_update_version_file() # Initialize list of targets to build set(STONEYVCV_TARGETS) #[=================================[StoneyVCV]=================================] # Core interface library - base dependency carrier for other developers -add_library("${STONEYVCV_SLUG}" INTERFACE) -add_library("${STONEYVCV_BRAND}::${STONEYVCV_SLUG}" ALIAS "${STONEYVCV_SLUG}") -configure_file("include/StoneyVCV.hpp" "include/StoneyVCV.hpp") -target_sources("${STONEYVCV_SLUG}" - INTERFACE - FILE_SET stoneyvcv_INTERFACE_HEADERS +add_library(${STONEYVCV_SLUG} OBJECT) +add_library(${STONEYVCV_BRAND}::${STONEYVCV_SLUG} ALIAS ${STONEYVCV_SLUG}) +configure_file("include/${STONEYVCV_SLUG}.hpp" "include/${STONEYVCV_SLUG}.hpp") +configure_file("include/${STONEYVCV_SLUG}/version.hpp" "include/${STONEYVCV_SLUG}/version.hpp") +target_sources(${STONEYVCV_SLUG} + PUBLIC + FILE_SET stoneyvcv_PUBLIC_HEADERS TYPE HEADERS BASE_DIRS $ $ FILES - $ - $ + $ + $ + $ + $ +) +target_sources(${STONEYVCV_SLUG} + PRIVATE + "src/${STONEYVCV_SLUG}.cpp" ) -target_sources("${STONEYVCV_SLUG}" PRIVATE "src/StoneyVCV.cpp") # Add project version number -set_target_properties("${STONEYVCV_SLUG}" +set_target_properties(${STONEYVCV_SLUG} PROPERTIES VERSION "${STONEYVCV_VERSION_MAJOR}.${STONEYVCV_VERSION_MINOR}.${STONEYVCV_VERSION_PATCH}" SOVERSION "${STONEYVCV_VERSION_MAJOR}" ) -target_compile_definitions("${STONEYVCV_SLUG}" - INTERFACE - "STONEYVCV_VERSION_MAJOR=${STONEYVCV_VERSION_MAJOR}" - "STONEYVCV_VERSION_MINOR=${STONEYVCV_VERSION_MINOR}" - "STONEYVCV_VERSION_PATCH=${STONEYVCV_VERSION_PATCH}" - "STONEYVCV_VERSION_TWEAK=${STONEYVCV_VERSION_TWEAK}" - "STONEYVCV_VERSION=${STONEYVCV_VERSION}" +target_compile_definitions(${STONEYVCV_SLUG} + PUBLIC + "STONEYVCV_VERSION_MAJOR=${STONEYVCV_VERSION_MAJOR}" + "STONEYVCV_VERSION_MINOR=${STONEYVCV_VERSION_MINOR}" + "STONEYVCV_VERSION_PATCH=${STONEYVCV_VERSION_PATCH}" + "STONEYVCV_VERSION_TWEAK=${STONEYVCV_VERSION_TWEAK}" + "STONEYVCV_VERSION=${STONEYVCV_VERSION}" ) # bump C++ version up from Rack-SDK -target_compile_features("${STONEYVCV_SLUG}" INTERFACE cxx_std_17) -target_compile_features("${STONEYVCV_SLUG}" INTERFACE c_std_17) -target_link_libraries("${STONEYVCV_SLUG}" - INTERFACE +target_compile_features(${STONEYVCV_SLUG} PUBLIC cxx_std_17) +target_compile_features(${STONEYVCV_SLUG} PUBLIC c_std_17) +target_link_libraries(${STONEYVCV_SLUG} + PUBLIC unofficial-vcvrack::rack-sdk::core StoneyDSP::Core ) @@ -184,7 +108,7 @@ install(TARGETS ${STONEYVCV_SLUG} ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" - FILE_SET stoneyvcv_INTERFACE_HEADERS DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + FILE_SET stoneyvcv_PUBLIC_HEADERS DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) install(EXPORT ${STONEYVCV_SLUG}Exports FILE "${STONEYVCV_BRAND}-${STONEYVCV_SLUG}-targets.cmake" @@ -194,11 +118,95 @@ install(EXPORT ${STONEYVCV_SLUG}Exports export(SETUP ${STONEYVCV_SLUG}Exports) export( EXPORT ${STONEYVCV_SLUG}Exports - FILE "lib/cmake/${STONEYVCV_BRAND}/$${STONEYVCV_BRAND}-${STONEYVCV_SLUG}-targets.cmake" + FILE "lib/cmake/${STONEYVCV_BRAND}/${STONEYVCV_BRAND}-${STONEYVCV_SLUG}-targets.cmake" NAMESPACE ${STONEYVCV_BRAND}:: ) message(STATUS "Added target: ${STONEYVCV_BRAND}::${STONEYVCV_SLUG} v${STONEYVCV_VERSION_MAJOR}.${STONEYVCV_VERSION_MINOR}.${STONEYVCV_VERSION_PATCH}") +#[=============================[ComponentLibrary]=============================]# +if(STONEYVCV_BUILD_COMPONENTLIBRARY) + + set(ComponentLibrary_VERSION_MAJOR "${STONEYVCV_VERSION_MAJOR}") + set(ComponentLibrary_VERSION_MINOR "${STONEYVCV_VERSION_MINOR}") + set(ComponentLibrary_VERSION_PATCH "${STONEYVCV_VERSION_PATCH}") + set(ComponentLibrary_VERSION "${ComponentLibrary_VERSION_MAJOR}.${ComponentLibrary_VERSION_MINOR}.${ComponentLibrary_VERSION_PATCH}") + + add_library(ComponentLibrary OBJECT) + add_library(${STONEYVCV_SLUG}::ComponentLibrary ALIAS ComponentLibrary) + add_library(${STONEYVCV_BRAND}::${STONEYVCV_SLUG}::ComponentLibrary ALIAS ComponentLibrary) + configure_file("include/${STONEYVCV_SLUG}/ComponentLibrary.hpp" "include/${STONEYVCV_SLUG}/ComponentLibrary.hpp") + configure_file("include/${STONEYVCV_SLUG}/ComponentLibrary/Widget.hpp" "include/${STONEYVCV_SLUG}/ComponentLibrary/Widget.hpp") + configure_file("include/${STONEYVCV_SLUG}/ComponentLibrary/PortWidget.hpp" "include/${STONEYVCV_SLUG}/ComponentLibrary/PortWidget.hpp") + configure_file("include/${STONEYVCV_SLUG}/ComponentLibrary/PanelWidget.hpp" "include/${STONEYVCV_SLUG}/ComponentLibrary/PanelWidget.hpp") + target_sources(ComponentLibrary + PUBLIC + FILE_SET stoneyvcv_COMPONENTLIBRARY_PUBLIC_HEADERS + TYPE HEADERS + BASE_DIRS + $ + $ + FILES + $ + $ + $ + $ + $ + $ + $ + $ + ) + target_sources(ComponentLibrary + PRIVATE + "src/${STONEYVCV_SLUG}/ComponentLibrary.cpp" + "src/${STONEYVCV_SLUG}/ComponentLibrary/Widget.cpp" + "src/${STONEYVCV_SLUG}/ComponentLibrary/PortWidget.cpp" + "src/${STONEYVCV_SLUG}/ComponentLibrary/PanelWidget.cpp" + ) + # Add project version number + set_target_properties(ComponentLibrary + PROPERTIES + VERSION "${ComponentLibrary_VERSION_MAJOR}.${ComponentLibrary_VERSION_MINOR}.${ComponentLibrary_VERSION_PATCH}" + SOVERSION "${ComponentLibrary_VERSION_MAJOR}" + ) + target_compile_definitions(ComponentLibrary + PUBLIC + "STONEYVCV_BUILD_COMPONENTLIBRARY=1" + "ComponentLibrary_VERSION_MAJOR=${ComponentLibrary_VERSION_MAJOR}" + "ComponentLibrary_VERSION_MINOR=${ComponentLibrary_VERSION_MINOR}" + "ComponentLibrary_VERSION_PATCH=${ComponentLibrary_VERSION_PATCH}" + "ComponentLibrary_VERSION_TWEAK=${ComponentLibrary_VERSION_TWEAK}" + "ComponentLibrary_VERSION_VERSION=${ComponentLibrary_VERSION}" + ) + target_link_libraries(ComponentLibrary + PUBLIC + unofficial-vcvrack::rack-sdk::core + StoneyDSP::Core + ) + install(TARGETS ComponentLibrary + EXPORT ComponentLibraryExports + COMPONENT ComponentLibrary + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + FILE_SET stoneyvcv_COMPONENTLIBRARY_PUBLIC_HEADERS DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + ) + install(EXPORT ComponentLibraryExports + FILE "${STONEYVCV_BRAND}-${STONEYVCV_SLUG}-ComponentLibrary-targets.cmake" + NAMESPACE ${STONEYVCV_BRAND}::${STONEYVCV_SLUG}:: + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${STONEYVCV_BRAND}" + ) + export(SETUP ComponentLibraryExports) + export( + EXPORT ComponentLibraryExports + FILE "lib/cmake/${STONEYVCV_BRAND}/${STONEYVCV_BRAND}-${STONEYVCV_SLUG}-ComponentLibrary-targets.cmake" + NAMESPACE ${STONEYVCV_BRAND}::${STONEYVCV_SLUG}:: + ) + + message(STATUS "Added target: ${STONEYVCV_BRAND}::${STONEYVCV_SLUG}::ComponentLibrary v${STONEYVCV_VERSION_MAJOR}.${STONEYVCV_VERSION_MINOR}.${STONEYVCV_VERSION_PATCH}") + +endif(STONEYVCV_BUILD_COMPONENTLIBRARY) + #[==================================[plugin]==================================]# if(STONEYVCV_BUILD_PLUGIN) @@ -214,18 +222,19 @@ if(STONEYVCV_BUILD_PLUGIN) BRAND "${STONEYVCV_BRAND}" HEADERS "include/${STONEYVCV_SLUG}/plugin.hpp" - "include/${STONEYVCV_SLUG}/version.hpp" - "include/${STONEYVCV_SLUG}/ComponentLibrary.hpp" SOURCES "src/${STONEYVCV_SLUG}/plugin.cpp" - "src/${STONEYVCV_SLUG}/ComponentLibrary.cpp" VERSION "${STONEYVCV_VERSION_MAJOR}.${STONEYVCV_VERSION_MINOR}.${STONEYVCV_VERSION_PATCH}" SOVERSION "${STONEYVCV_VERSION_MAJOR}" EXPORT INSTALL ) - target_link_libraries(plugin PUBLIC "${STONEYVCV_BRAND}::${STONEYVCV_SLUG}") + target_link_libraries(plugin + PUBLIC + "${STONEYVCV_BRAND}::${STONEYVCV_SLUG}" + "${STONEYVCV_BRAND}::${STONEYVCV_SLUG}::ComponentLibrary" + ) target_compile_definitions(plugin PUBLIC @@ -250,51 +259,11 @@ if(STONEYVCV_BUILD_PLUGIN) endif(STONEYVCV_BUILD_PLUGIN) -#[==[test]==] -function(stoneyvcv_add_test MODULE) - - set(tests_${MODULE}_VERSION_MAJOR "${STONEYVCV_VERSION_MAJOR}") - set(tests_${MODULE}_VERSION_MINOR "${STONEYVCV_VERSION_MINOR}") - set(tests_${MODULE}_VERSION_PATCH "${STONEYVCV_VERSION_PATCH}") - set(tests_${MODULE}_VERSION "${tests_${MODULE}_VERSION_MAJOR}.${tests_${MODULE}_VERSION_MINOR}.${tests_${MODULE}_VERSION_PATCH}") - - add_library(tests_${MODULE} OBJECT EXCLUDE_FROM_ALL) - add_library(${STONEYVCV_SLUG}::tests_${MODULE} ALIAS tests_${MODULE}) - add_library(${STONEYVCV_BRAND}::${STONEYVCV_SLUG}::tests_${MODULE} ALIAS tests_${MODULE}) - set_target_properties(tests_${MODULE} - PROPERTIES - VERSION "${tests_${MODULE}_VERSION}" - SOVERSION "${tests_${MODULE}_VERSION_MAJOR}" - ) - target_include_directories(tests_${MODULE} - PUBLIC - $ - $ - ) - target_sources(tests_${MODULE} - PRIVATE - "${STONEYVCV_SOURCE_DIR}/test/${STONEYVCV_SLUG}/${MODULE}.cpp" - ) - target_link_libraries(tests_${MODULE} - PUBLIC - unofficial-vcvrack::rack-sdk::core - ${STONEYVCV_BRAND}::${STONEYVCV_SLUG}::${MODULE} - Catch2::Catch2 - ) - target_compile_definitions(tests_${MODULE} - PUBLIC - "-Dtests_${MODULE}_VERSION_MAJOR=${tests_${MODULE}_VERSION_MAJOR}" - "-Dtests_${MODULE}_VERSION_MINOR=${tests_${MODULE}_VERSION_MINOR}" - "-Dtests_${MODULE}_VERSION_PATCH=${tests_${MODULE}_VERSION_PATCH}" - "-Dtests_${MODULE}_VERSION=${tests_${MODULE}_VERSION}" - ) - target_compile_features(tests_${MODULE} PUBLIC cxx_std_17) - target_compile_features(tests_${MODULE} PUBLIC c_std_17) - message(STATUS "Added target: ${STONEYVCV_BRAND}::${STONEYVCV_SLUG}::tests_${MODULE} v${tests_${MODULE}_VERSION}") -endfunction() - +#[===================================[test]===================================]# if(STONEYVCV_IS_TOP_LEVEL AND STONEYVCV_BUILD_TESTS) + include(StoneyVCVAddTest) + find_package(Catch2 3.5.2 REQUIRED) set(tests_VERSION_MAJOR "${STONEYVCV_VERSION_MAJOR}") @@ -324,9 +293,10 @@ if(STONEYVCV_IS_TOP_LEVEL AND STONEYVCV_BUILD_TESTS) ) target_link_libraries(tests PUBLIC - unofficial-vcvrack::rack-sdk::lib - ${STONEYVCV_BRAND}::${STONEYVCV_SLUG}::plugin - Catch2::Catch2WithMain + unofficial-vcvrack::rack-sdk::lib + ${STONEYVCV_BRAND}::${STONEYVCV_SLUG} + ${STONEYVCV_BRAND}::${STONEYVCV_SLUG}::plugin + Catch2::Catch2WithMain ) set_target_properties(tests PROPERTIES @@ -415,6 +385,11 @@ if(STONEYVCV_BUILD_MODULES) "-DSTONEYVCV_BUILD_${MODULE}=1" "-D${MODULE}_VERSION=${STONEYVCV_VERSION_MAJOR}.${STONEYVCV_VERSION_MINOR}.${${MODULE}_VERSION_PATCH}" ) + target_link_libraries(${MODULE} + PUBLIC + ${STONEYVCV_BRAND}::${STONEYVCV_SLUG} + ${STONEYVCV_BRAND}::${STONEYVCV_SLUG}::ComponentLibrary + ) list(APPEND STONEYVCV_TARGETS ${MODULE}) # Collect enabled modules message(STATUS "Added target: ${STONEYVCV_BRAND}::${STONEYVCV_SLUG}::${MODULE} v${${MODULE}_VERSION}") @@ -452,11 +427,11 @@ foreach(TARGET IN LISTS STONEYVCV_TARGETS) # Add project version number target_compile_definitions(${TARGET} PUBLIC - "STONEYVCV_VERSION_MAJOR=${STONEYVCV_VERSION_MAJOR}" - "STONEYVCV_VERSION_MINOR=${STONEYVCV_VERSION_MINOR}" - "STONEYVCV_VERSION_PATCH=${STONEYVCV_VERSION_PATCH}" - "STONEYVCV_VERSION_TWEAK=${STONEYVCV_VERSION_TWEAK}" - "STONEYVCV_VERSION=${STONEYVCV_VERSION}" + "STONEYVCV_VERSION_MAJOR=${STONEYVCV_VERSION_MAJOR}" + "STONEYVCV_VERSION_MINOR=${STONEYVCV_VERSION_MINOR}" + "STONEYVCV_VERSION_PATCH=${STONEYVCV_VERSION_PATCH}" + "STONEYVCV_VERSION_TWEAK=${STONEYVCV_VERSION_TWEAK}" + "STONEYVCV_VERSION=${STONEYVCV_VERSION}" ) # Toggle plugin module code diff --git a/CMakeOptions.json b/CMakeOptions.json index 7267f2ca..c7e36730 100644 --- a/CMakeOptions.json +++ b/CMakeOptions.json @@ -23,6 +23,10 @@ "value": "ON", "type": "BOOL" }, + "STONEYVCV_BUILD_COMPONENTLIBRARY": { + "value": "ON", + "type": "BOOL" + }, "STONEYVCV_BUILD_PLUGIN": { "value": "ON", "type": "BOOL" diff --git a/Makefile b/Makefile index 0cdedb10..84e1e293 100644 --- a/Makefile +++ b/Makefile @@ -112,6 +112,9 @@ FLAGS += -DSTONEYVCV_VERSION_TWEAK=$(STONEYVCV_VERSION_TWEAK) # Experimental? STONEYVCV_EXPERIMENTAL ?= 0 +# Component Library? +STONEYVCV_BUILD_COMPONENTLIBRARY ?= 1 + # Build plugin? STONEYVCV_BUILD_PLUGIN ?= 1 @@ -123,10 +126,23 @@ STONEYVCV_BUILD_HP1 ?= $(STONEYVCV_BUILD_MODULES) STONEYVCV_BUILD_VCA ?= $(STONEYVCV_BUILD_MODULES) STONEYVCV_BUILD_LFO ?= $(STONEYVCV_EXPERIMENTAL) +# ifneq ($(STONEYVCV_BUILD_COMPONENTLIBRARY),$(STONEYVCV_BUILD_PLUGIN)) +# $(error STONEYVCV_BUILD_PLUGIN requires that STONEYVCV_BUILD_COMPONENTLIBRARY=1) +# endif + +SOURCES += src/StoneyVCV.cpp + +ifeq ($(STONEYVCV_BUILD_COMPONENTLIBRARY),1) + FLAGS += -DSTONEYVCV_BUILD_COMPONENTLIBRARY=$(STONEYVCV_BUILD_COMPONENTLIBRARY) + SOURCES += src/StoneyVCV/ComponentLibrary.cpp + SOURCES += src/StoneyVCV/ComponentLibrary/Widget.cpp + SOURCES += src/StoneyVCV/ComponentLibrary/PortWidget.cpp + SOURCES += src/StoneyVCV/ComponentLibrary/PanelWidget.cpp +endif + ifeq ($(STONEYVCV_BUILD_PLUGIN),1) FLAGS += -DSTONEYVCV_BUILD_PLUGIN=$(STONEYVCV_BUILD_PLUGIN) SOURCES += src/StoneyVCV/plugin.cpp - SOURCES += src/StoneyVCV/ComponentLibrary.cpp ifeq ($(STONEYVCV_BUILD_MODULES),1) FLAGS += -DSTONEYVCV_BUILD_MODULES=$(STONEYVCV_BUILD_MODULES) diff --git a/VERSION b/VERSION index 9c8e5751..607ed0b5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.1233.37366161623664 +2.0.1265.37346335353431 diff --git a/include/StoneyVCV.hpp b/include/StoneyVCV.hpp index 4be25344..0a7b5891 100644 --- a/include/StoneyVCV.hpp +++ b/include/StoneyVCV.hpp @@ -39,6 +39,15 @@ //============================================================================== +#ifdef STONEYDSP_DEBUG +#include +#define DBG(msg, ...) do { ::std::cerr << std::string(msg, ##__VA_ARGS__) << std::endl; } while (0) +#else +#define DBG(msg, ...) ::StoneyDSP::ignoreUnused(msg, ##__VA_ARGS__) +#endif + +//============================================================================== + /** * @brief The `StoneyDSP` namespace. * @author Nathan J. Hood (nathanjhood@googlemail.com) @@ -66,6 +75,89 @@ namespace StoneyVCV * @{ */ +//============================================================================== + +namespace Tools { +/** @addtogroup Tools + * @{ + */ + +//============================================================================== + +const extern ::StoneyDSP::float_t vMin; +const extern ::StoneyDSP::float_t vMax; +const extern ::StoneyDSP::float_t vNominal; +const extern ::StoneyDSP::float_t vBias; +const extern ::StoneyDSP::float_t vGround; +const extern ::StoneyDSP::float_t vFloor; + +//============================================================================== + + /// @} group Tools +} // namespace Tools + +//============================================================================== + +// Declare an abstract base class with a pure virtual destructor. +// It's the simplest possible abstract class. +template +struct Engine +{ + + //========================================================================== + +public: + + //========================================================================== + + Engine() + { + DBG("Creating StoneyDSP::StoneyVCV::Engine"); + }; + + virtual ~Engine() noexcept = 0; // pure virtual + + //========================================================================== + + virtual void processSample(T* sample) = 0; // pure virtual + + //========================================================================== + +private: + + //========================================================================== + + STONEYDSP_DECLARE_NON_COPYABLE(Engine) + STONEYDSP_DECLARE_NON_MOVEABLE(Engine) +}; + +template +::StoneyDSP::StoneyVCV::Engine::~Engine() noexcept +{ + DBG("Destroying StoneyDSP::StoneyVCV::Engine"); +} + +template struct ::StoneyDSP::StoneyVCV::Engine<::StoneyDSP::float_t>; +template struct ::StoneyDSP::StoneyVCV::Engine<::StoneyDSP::double_t>; + +//============================================================================== + +template +TWidget *createWidgetSized(::rack::math::Vec pos, ::rack::math::Vec size) +{ + TWidget* o = ::rack::createWidget(pos); + o->box.size = size; + return o; +} + +template +TWidget* createWidgetCenteredSized(::rack::math::Vec pos, ::rack::math::Vec size) +{ + TWidget* o = ::rack::createWidgetCentered(pos); + o->box.size = size; + return o; +} + //============================================================================== /// @} group StoneyVCV @@ -77,3 +169,13 @@ namespace StoneyVCV } // namespace StoneyDSP //============================================================================== + +// #include +// #include +// #include +// #include +// #include +// #include +// #include + +//============================================================================== diff --git a/include/StoneyVCV/ComponentLibrary.hpp b/include/StoneyVCV/ComponentLibrary.hpp index b5f87cef..f0c94187 100644 --- a/include/StoneyVCV/ComponentLibrary.hpp +++ b/include/StoneyVCV/ComponentLibrary.hpp @@ -32,10 +32,11 @@ #define STONEYVCV_COMPONENTLIBRARY_HPP_INCLUDED 1 -#if defined (STONEYVCV_BUILD_PLUGIN) +#if defined (STONEYVCV_BUILD_COMPONENTLIBRARY) //============================================================================== +#include #include //============================================================================== @@ -45,6 +46,10 @@ //============================================================================== +#include + +//============================================================================== + namespace StoneyDSP { /** @addtogroup StoneyDSP @@ -84,8 +89,8 @@ const extern ::NVGcolor bgGradientBlackS0; const extern ::NVGcolor bgGradientBlackS1; const extern ::NVGcolor bgGradientWhiteS0; const extern ::NVGcolor bgGradientWhiteS1; -const extern ::StoneyDSP::float_t MIN_WIDTH; -const extern ::StoneyDSP::float_t MIN_HEIGHT; +const extern float MIN_WIDTH; +const extern float MIN_HEIGHT; extern void addScrewsToWidget(::rack::widget::Widget* widget); //============================================================================== @@ -108,197 +113,6 @@ namespace ComponentLibrary //============================================================================== -/** - * @brief The `ThemedPortWidget` struct. - * - * Provides a panel background to the `ThemedPortWidget` struct. - * - */ -struct ThemedPortWidgetPanel : virtual ::rack::widget::Widget -{ - - //========================================================================== - -public: - - //========================================================================== - - using DrawArgs = ::rack::widget::Widget::DrawArgs; - - //========================================================================== - - /** - * @brief Constructs a new `ThemedPortWidgetPanel` object. - * - */ - ThemedPortWidgetPanel(); - - virtual ~ThemedPortWidgetPanel(); - - //========================================================================== - - /** - * @brief Advances the module by one frame. - * Calls `::rack::widget::Widget::step()` internally. - * - */ - virtual void step() override; - - /** - * @brief Renders to the NanoVG context. - * Calls `::rack::widget::Widget::draw(args)` internally. - * - */ - virtual void draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel::DrawArgs &args) override; - - //========================================================================== - - ::std::string labelText; - - /** - * @brief Set whether the parent is an input or an output port. - * - */ - bool isOutput; - - //========================================================================== - -private: - - //========================================================================== - - STONEYDSP_DECLARE_NON_COPYABLE(ThemedPortWidgetPanel) - STONEYDSP_DECLARE_NON_MOVEABLE(ThemedPortWidgetPanel) -}; - -//============================================================================== - -/** - * @brief The `ThemedPortWidget` struct. - * - */ -struct ThemedPortWidget : virtual ::rack::app::ThemedSvgPort -{ - - //========================================================================== - -public: - - //========================================================================== - - using DrawArgs = ::rack::app::ThemedSvgPort::DrawArgs; - - ThemedPortWidget(); - - virtual ~ThemedPortWidget(); - - //========================================================================== - - virtual void step() override; - - virtual void draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidget::DrawArgs &args) override; - - //========================================================================== - - bool isOutput; - - ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel* panel; - - //========================================================================== - -private: - - //========================================================================== - - ::rack::FramebufferWidget* fb; - - bool lastPrefersDarkPanels; - - STONEYDSP_DECLARE_NON_COPYABLE(ThemedPortWidget) - STONEYDSP_DECLARE_NON_MOVEABLE(ThemedPortWidget) -}; - -/** - * @brief The `ThemedWidget` struct. - * - */ -struct ThemedWidget : virtual ::rack::widget::Widget -{ - - //========================================================================== - -public: - - using DrawArgs = ::rack::widget::Widget::DrawArgs; - - //========================================================================== - - /** - * @brief Construct a new `ThemedWidget` object. - * - */ - ThemedWidget(); - - /** - * @brief Destroys the `ThemedWidget` object. - * - */ - virtual ~ThemedWidget(); - - //========================================================================== - - /** - * @brief Advances the module by one frame. - * - */ - virtual void step() override; - - /** - * @brief Draws a themed background color to the widget's NanoVG context. - * - * @param args - */ - void drawThemedBg(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::DrawArgs &args); - - /** - * @brief Draws a set of lines for spacing to the widget's NanoVG context. - * - * @param args - */ - void drawDividerLines(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::DrawArgs &args); - - /** - * @brief Draws the widget to the NanoVG context. - * Calls the superclass's draw(args) to recurse to children. - * - * @param args - */ - virtual void draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::DrawArgs &args) override; - - //========================================================================== - -private: - - //========================================================================== - - /** - * @brief - * - */ - ::rack::FramebufferWidget *fb; - - /** - * @brief - * - */ - ::rack::app::PanelBorder *panelBorder; - - //========================================================================== - - STONEYDSP_DECLARE_NON_COPYABLE(ThemedWidget) - STONEYDSP_DECLARE_NON_MOVEABLE(ThemedWidget) -}; - //============================================================================== /// @} group ComponentLibrary @@ -316,6 +130,6 @@ struct ThemedWidget : virtual ::rack::widget::Widget //============================================================================== -#endif // STONEYVCV_BUILD_PLUGIN +#endif // STONEYVCV_BUILD_COMPONENTLIBRARY //============================================================================== diff --git a/include/StoneyVCV/ComponentLibrary/PanelWidget.hpp b/include/StoneyVCV/ComponentLibrary/PanelWidget.hpp new file mode 100644 index 00000000..564104b2 --- /dev/null +++ b/include/StoneyVCV/ComponentLibrary/PanelWidget.hpp @@ -0,0 +1,222 @@ +/******************************************************************************* + * @file include/StoneyVCV/ComponentLibrary/PanelWidget.hpp + * @author Nathan J. Hood + * @brief @PROJECT_DESCRIPTION@ + * @version @plugin_VERSION@ + * + * @copyright MIT License + * + * Copyright (c) 2024 Nathan J. Hood + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + ******************************************************************************/ + +#pragma once + +#define STONEYVCV_COMPONENTLIBRARY_PANELWIDGET_HPP_INCLUDED 1 + +#if defined (STONEYVCV_BUILD_COMPONENTLIBRARY) + +//============================================================================== + +#include +#include + +//============================================================================== + +#include +#include + +//============================================================================== + +#include +#include + +//============================================================================== + +namespace StoneyDSP +{ +/** @addtogroup StoneyDSP + * @{ + */ + +//============================================================================== + +namespace StoneyVCV +{ +/** @addtogroup StoneyVCV + * @{ + */ + +//============================================================================== + +namespace ComponentLibrary +{ +/** @addtogroup ComponentLibrary + * @{ + */ + +//============================================================================== + +/** + * @brief The `PanelLinesWidget` struct. + * Draws 4 lines around the inner edges of the module. + * Does not ssend or respond to events. + * + */ +struct PanelLinesWidget : virtual ::rack::widget::TransparentWidget +{ + + //========================================================================== + +public: + + using DrawArgs = ::rack::widget::TransparentWidget::DrawArgs; + + //========================================================================== + + /** + * @brief Construct a new `PanelLinesWidget` object. + * + */ + PanelLinesWidget() = default; + + /** + * @brief Draws a set of lines for spacing to the widget's NanoVG context. + * + * @param args + */ + virtual void draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::PanelLinesWidget::DrawArgs &args) override; + +private: + + //========================================================================== + + STONEYDSP_DECLARE_NON_COPYABLE(PanelLinesWidget) + STONEYDSP_DECLARE_NON_MOVEABLE(PanelLinesWidget) +}; + +//============================================================================== + +/** + * @brief The `ThemedPanelWidget` struct. + * + */ +struct ThemedPanelWidget : virtual ::rack::widget::Widget +{ + + //========================================================================== + +public: + + using DrawArgs = ::rack::widget::Widget::DrawArgs; + + //========================================================================== + + /** + * @brief Construct a new `ThemedPanelWidget` object. + * + */ + ThemedPanelWidget(); + + /** + * @brief Destroys the `ThemedPanelWidget` object. + * + */ + virtual ~ThemedPanelWidget(); + + //========================================================================== + + /** + * @brief Advances the module by one frame. + * + */ + virtual void step() override; + + /** + * @brief Draws a themed background to the widget's NanoVG context. + * Calls the superclass's draw(args) to recurse to children. + * + * @param args + */ + virtual void draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPanelWidget::DrawArgs &args) override; + + //========================================================================== + +private: + + //========================================================================== + + /** + * @brief + * + */ + ::rack::FramebufferWidget *fb; + + // /** + // * @brief + // * + // */ + // const ::std::array<::rack::math::Vec, 4> screwsPositions; + + // /** + // * @brief + // * + // */ + // const ::std::array<::rack::componentlibrary::ThemedScrew *, 4> screws; + + /** + * @brief + * + */ + ::StoneyDSP::StoneyVCV::ComponentLibrary::PanelLinesWidget *panelLines; + + /** + * @brief + * + */ + ::rack::app::PanelBorder *panelBorder; + + //========================================================================== + + STONEYDSP_DECLARE_NON_COPYABLE(ThemedPanelWidget) + STONEYDSP_DECLARE_NON_MOVEABLE(ThemedPanelWidget) +}; + +//============================================================================== + + /// @} group ComponentLibrary +} // namespace ComponentLibrary + +//============================================================================== + + /// @} group StoneyVCV +} // namespace StoneyVCV + +//============================================================================== + + /// @} group StoneyDSP +} // namespace StoneyDSP + +//============================================================================== + +#endif // STONEYVCV_BUILD_COMPONENTLIBRARY + +//============================================================================== diff --git a/include/StoneyVCV/ComponentLibrary/PortWidget.hpp b/include/StoneyVCV/ComponentLibrary/PortWidget.hpp new file mode 100644 index 00000000..b9a4be43 --- /dev/null +++ b/include/StoneyVCV/ComponentLibrary/PortWidget.hpp @@ -0,0 +1,202 @@ +/******************************************************************************* + * @file include/StoneyVCV/ComponentLibrary/PortWidget.hpp + * @author Nathan J. Hood + * @brief @PROJECT_DESCRIPTION@ + * @version @plugin_VERSION@ + * + * @copyright MIT License + * + * Copyright (c) 2024 Nathan J. Hood + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + ******************************************************************************/ + +#pragma once + +#define STONEYVCV_COMPONENTLIBRARY_PORTWIDGET_HPP_INCLUDED 1 + +#if defined (STONEYVCV_BUILD_COMPONENTLIBRARY) + +//============================================================================== + +#include +#include + +//============================================================================== + +#include +#include + +//============================================================================== + +namespace StoneyDSP +{ +/** @addtogroup StoneyDSP + * @{ + */ + +//============================================================================== + +namespace StoneyVCV +{ +/** @addtogroup StoneyVCV + * @{ + */ + +//============================================================================== + +namespace ComponentLibrary +{ +/** @addtogroup ComponentLibrary + * @{ + */ + +//============================================================================== + +/** + * @brief The `ThemedPortWidgetPanel` struct. + * + * Provides a panel background to the `ThemedPortWidget` struct. + * + */ +struct ThemedPortWidgetPanel : virtual ::rack::widget::TransparentWidget +{ + + //========================================================================== + +public: + + //========================================================================== + + using DrawArgs = ::rack::widget::TransparentWidget::DrawArgs; + + //========================================================================== + + /** + * @brief Constructs a new `ThemedPortWidgetPanel` object. + * + */ + ThemedPortWidgetPanel(); + + virtual ~ThemedPortWidgetPanel(); + + //========================================================================== + + /** + * @brief Advances the module by one frame. + * Calls `::rack::widget::Widget::step()` internally. + * + */ + virtual void step() override; + + /** + * @brief Renders to the NanoVG context. + * Calls `::rack::widget::Widget::draw(args)` internally. + * + */ + virtual void draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel::DrawArgs &args) override; + + //========================================================================== + + ::std::string labelText; + + /** + * @brief Set whether the parent is an input or an output port. + * + */ + bool isOutput; + + //========================================================================== + +private: + + //========================================================================== + + STONEYDSP_DECLARE_NON_COPYABLE(ThemedPortWidgetPanel) + STONEYDSP_DECLARE_NON_MOVEABLE(ThemedPortWidgetPanel) +}; + +//============================================================================== + +/** + * @brief The `ThemedPortWidget` struct. + * + */ +struct ThemedPortWidget : virtual ::rack::app::ThemedSvgPort +{ + + //========================================================================== + +public: + + //========================================================================== + + using DrawArgs = ::rack::app::ThemedSvgPort::DrawArgs; + + ThemedPortWidget(); + + virtual ~ThemedPortWidget(); + + //========================================================================== + + virtual void step() override; + + virtual void draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidget::DrawArgs &args) override; + + //========================================================================== + + bool isOutput; + + ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel* panel; + + //========================================================================== + +private: + + //========================================================================== + + ::rack::FramebufferWidget* fb; + + bool lastPrefersDarkPanels; + + STONEYDSP_DECLARE_NON_COPYABLE(ThemedPortWidget) + STONEYDSP_DECLARE_NON_MOVEABLE(ThemedPortWidget) +}; + +//============================================================================== + + /// @} group ComponentLibrary +} // namespace ComponentLibrary + +//============================================================================== + + /// @} group StoneyVCV +} // namespace StoneyVCV + +//============================================================================== + + /// @} group StoneyDSP +} // namespace StoneyDSP + +//============================================================================== + +#endif // STONEYVCV_BUILD_COMPONENTLIBRARY + +//============================================================================== diff --git a/include/StoneyVCV/ComponentLibrary/Widget.hpp b/include/StoneyVCV/ComponentLibrary/Widget.hpp new file mode 100644 index 00000000..fd1b7b6a --- /dev/null +++ b/include/StoneyVCV/ComponentLibrary/Widget.hpp @@ -0,0 +1,166 @@ +/******************************************************************************* + * @file include/StoneyVCV/ComponentLibrary/Widget.hpp + * @author Nathan J. Hood + * @brief @PROJECT_DESCRIPTION@ + * @version @plugin_VERSION@ + * + * @copyright MIT License + * + * Copyright (c) 2024 Nathan J. Hood + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + ******************************************************************************/ + +#pragma once + +#define STONEYVCV_COMPONENTLIBRARY_PANELWIDGET_HPP_INCLUDED 1 + +#if defined (STONEYVCV_BUILD_COMPONENTLIBRARY) + +//============================================================================== + +#include +#include + +//============================================================================== + +#include +#include + +//============================================================================== + +namespace StoneyDSP +{ +/** @addtogroup StoneyDSP + * @{ + */ + +//============================================================================== + +namespace StoneyVCV +{ +/** @addtogroup StoneyVCV + * @{ + */ + +//============================================================================== + +namespace ComponentLibrary +{ +/** @addtogroup ComponentLibrary + * @{ + */ + +//============================================================================== + +/** + * @brief The `ThemedWidget` struct. + * + */ +struct ThemedWidget : virtual ::rack::widget::Widget +{ + + //========================================================================== + +public: + + using DrawArgs = ::rack::widget::Widget::DrawArgs; + + //========================================================================== + + /** + * @brief Construct a new `ThemedWidget` object. + * + */ + ThemedWidget(); + + /** + * @brief Destroys the `ThemedWidget` object. + * + */ + virtual ~ThemedWidget(); + + //========================================================================== + + /** + * @brief Advances the module by one frame. + * + */ + virtual void step() override; + + /** + * @brief Draws a themed background color to the widget's NanoVG context. + * + * @param args + */ + void drawThemedBg(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::DrawArgs &args); + + /** + * @brief Draws the widget to the NanoVG context. + * Calls the superclass's draw(args) to recurse to children. + * + * @param args + */ + virtual void draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::DrawArgs &args) override; + + //========================================================================== + +private: + + //========================================================================== + + /** + * @brief + * + */ + ::rack::FramebufferWidget *fb; + + /** + * @brief + * + */ + ::rack::app::PanelBorder *panelBorder; + + //========================================================================== + + STONEYDSP_DECLARE_NON_COPYABLE(ThemedWidget) + STONEYDSP_DECLARE_NON_MOVEABLE(ThemedWidget) +}; + +//============================================================================== + + /// @} group ComponentLibrary +} // namespace ComponentLibrary + +//============================================================================== + + /// @} group StoneyVCV +} // namespace StoneyVCV + +//============================================================================== + + /// @} group StoneyDSP +} // namespace StoneyDSP + +//============================================================================== + +#endif // STONEYVCV_BUILD_COMPONENTLIBRARY + +//============================================================================== diff --git a/include/StoneyVCV/HP1.hpp b/include/StoneyVCV/HP1.hpp index f0315a06..f705e162 100644 --- a/include/StoneyVCV/HP1.hpp +++ b/include/StoneyVCV/HP1.hpp @@ -36,6 +36,8 @@ //============================================================================== +#include +#include #include //============================================================================== @@ -43,6 +45,8 @@ #include #include +//============================================================================== + #include //============================================================================== diff --git a/include/StoneyVCV/HP2.hpp b/include/StoneyVCV/HP2.hpp index 367f35fa..fdd1befa 100644 --- a/include/StoneyVCV/HP2.hpp +++ b/include/StoneyVCV/HP2.hpp @@ -36,6 +36,8 @@ //============================================================================== +#include +#include #include //============================================================================== @@ -43,6 +45,8 @@ #include #include +//============================================================================== + #include //============================================================================== diff --git a/include/StoneyVCV/HP4.hpp b/include/StoneyVCV/HP4.hpp index badffb8b..1362cb3d 100644 --- a/include/StoneyVCV/HP4.hpp +++ b/include/StoneyVCV/HP4.hpp @@ -36,6 +36,8 @@ //============================================================================== +#include +#include #include //============================================================================== @@ -43,6 +45,8 @@ #include #include +//============================================================================== + #include //============================================================================== diff --git a/include/StoneyVCV/LFO.hpp b/include/StoneyVCV/LFO.hpp index 7885397a..2f1f3053 100644 --- a/include/StoneyVCV/LFO.hpp +++ b/include/StoneyVCV/LFO.hpp @@ -36,6 +36,8 @@ //============================================================================== +#include +#include #include //============================================================================== @@ -45,6 +47,8 @@ #include #include +//============================================================================== + #include //============================================================================== diff --git a/include/StoneyVCV/VCA.hpp b/include/StoneyVCV/VCA.hpp index 0337820f..958d0dff 100644 --- a/include/StoneyVCV/VCA.hpp +++ b/include/StoneyVCV/VCA.hpp @@ -36,6 +36,9 @@ //============================================================================== +#include +#include +#include #include #include @@ -46,6 +49,8 @@ #include #include +//============================================================================== + #include //============================================================================== @@ -247,6 +252,18 @@ struct VCAModule final : virtual ::rack::engine::Module */ const ::StoneyDSP::float_t &vFloor = ::StoneyDSP::StoneyVCV::Tools::vFloor; + //========================================================================== + + ::rack::engine::Input* vcaInputPtr; + + ::rack::engine::Input* cvInputPtr; + + ::rack::engine::Param* gainParamPtr; + + ::rack::engine::Output* vcaOutputPtr; + + ::rack::engine::Light* blinkLightPtr; + STONEYDSP_DECLARE_NON_COPYABLE(VCAModule) STONEYDSP_DECLARE_NON_MOVEABLE(VCAModule) }; @@ -257,14 +274,14 @@ struct VCAModule final : virtual ::rack::engine::Module * @brief The `VCAWidget` struct. * */ -struct VCAWidget final : virtual ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget +struct VCAWidget final : virtual ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPanelWidget { //========================================================================== public: - using DrawArgs = ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::DrawArgs; + using DrawArgs = ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPanelWidget::DrawArgs; //========================================================================== @@ -333,6 +350,8 @@ struct VCAModuleWidget final : virtual ::rack::app::ModuleWidget public: + using DrawArgs = ::rack::app::ModuleWidget::DrawArgs; + //========================================================================== /** @@ -357,6 +376,8 @@ struct VCAModuleWidget final : virtual ::rack::app::ModuleWidget */ virtual void step() override; + virtual void draw(const ::StoneyDSP::StoneyVCV::VCA::VCAModuleWidget::DrawArgs &args) override; + //========================================================================== private: @@ -393,7 +414,7 @@ struct VCAModuleWidget final : virtual ::rack::app::ModuleWidget * @brief * */ - ::rack::componentlibrary::RoundBigBlackKnob *gainKnob; + ::rack::componentlibrary::RoundLargeBlackKnob *gainKnob; // ::rack::componentlibrary::VCVLightSlider<::rack::componentlibrary::YellowLight>* gainSlider; diff --git a/include/StoneyVCV/plugin.hpp b/include/StoneyVCV/plugin.hpp index 2e7ad00b..36784614 100644 --- a/include/StoneyVCV/plugin.hpp +++ b/include/StoneyVCV/plugin.hpp @@ -36,6 +36,7 @@ //============================================================================== +#include #include //============================================================================== @@ -45,15 +46,6 @@ //============================================================================== -#ifdef STONEYDSP_DEBUG -#include -#define DBG(msg, ...) do { ::std::cerr << std::string(msg, ##__VA_ARGS__) << std::endl; } while (0) -#else -#define DBG(msg, ...) ::StoneyDSP::ignoreUnused(msg, ##__VA_ARGS__) -#endif - -//============================================================================== - namespace StoneyDSP { /** @addtogroup StoneyDSP @@ -101,74 +93,66 @@ extern ::rack::plugin::Plugin* pluginInstance; // Declare each Model, defined in each module source file -#if (STONEYVCV_VERSION_MAJOR >= 2U) && (STONEYVCV_VERSION_MINOR >= 0U) && (STONEYVCV_VERSION_PATCH >= 2U) - - #if defined (STONEYVCV_BUILD_VCA) - namespace VCA { - /** @addtogroup VCA - * @{ - */ - - /** - * @brief Declaration of the `VCA` Model instance, defined in `VCA.cpp`. - */ - extern ::rack::plugin::Model* modelVCA; - - /// @} group VCA - } // namespace VCA - #endif // STONEYVCV_BUILD_VCA - -#endif // STONEYVCV_VERSION_PATCH >= 2 - -#if (STONEYVCV_VERSION_MAJOR >= 2U) && (STONEYVCV_VERSION_MINOR >= 0U) && (STONEYVCV_VERSION_PATCH >= 1U) - - #if defined (STONEYVCV_BUILD_HP4) - namespace HP4 { - /** @addtogroup HP4 - * @{ - */ - - /** - * @brief Declaration of the `HP4` Model instance, defined in `HP4.cpp`. - */ - extern ::rack::plugin::Model* modelHP4; - - - /// @} group HP4 - } // namespace HP4 - #endif // STONEYVCV_BUILD_HP4 - - #if defined (STONEYVCV_BUILD_HP2) - namespace HP2 { - /** @addtogroup HP2 - * @{ - */ - - /** - * @brief Declaration of the `HP2` Model instance, defined in `HP2.cpp`. - */ - extern ::rack::plugin::Model* modelHP2; - - /// @} group HP1 - } // namespace HP1 - #endif // STONEYVCV_BUILD_HP2 - - #if defined (STONEYVCV_BUILD_HP1) - namespace HP1 { - /** @addtogroup HP1 - * @{ - */ - - /** - * @brief Declaration of the `HP1` Model instance, defined in `HP1.cpp`. - */ - extern ::rack::plugin::Model* modelHP1; - - /// @} group HP1 - } // namespace HP1 - #endif // STONEYVCV_BUILD_HP1 - -#endif +#if defined (STONEYVCV_BUILD_VCA) + namespace VCA { + /** @addtogroup VCA + * @{ + */ + + /** + * @brief Declaration of the `VCA` Model instance, defined in `VCA.cpp`. + */ + extern ::rack::plugin::Model* modelVCA; + + /// @} group VCA + } // namespace VCA +#endif // STONEYVCV_BUILD_VCA + +#if defined (STONEYVCV_BUILD_HP4) + namespace HP4 { + /** @addtogroup HP4 + * @{ + */ + + /** + * @brief Declaration of the `HP4` Model instance, defined in `HP4.cpp`. + */ + extern ::rack::plugin::Model* modelHP4; + + + /// @} group HP4 + } // namespace HP4 +#endif // STONEYVCV_BUILD_HP4 + +#if defined (STONEYVCV_BUILD_HP2) + namespace HP2 { + /** @addtogroup HP2 + * @{ + */ + + /** + * @brief Declaration of the `HP2` Model instance, defined in `HP2.cpp`. + */ + extern ::rack::plugin::Model* modelHP2; + + /// @} group HP1 + } // namespace HP1 +#endif // STONEYVCV_BUILD_HP2 + +#if defined (STONEYVCV_BUILD_HP1) + namespace HP1 { + /** @addtogroup HP1 + * @{ + */ + + /** + * @brief Declaration of the `HP1` Model instance, defined in `HP1.cpp`. + */ + extern ::rack::plugin::Model* modelHP1; + + /// @} group HP1 + } // namespace HP1 +#endif // STONEYVCV_BUILD_HP1 #if (STONEYVCV_VERSION_MAJOR >= 2U) && (STONEYVCV_VERSION_MINOR >= 0U) && (STONEYVCV_VERSION_PATCH < 1U) #warning "No modules found..." @@ -212,55 +196,3 @@ extern ::rack::plugin::Plugin* pluginInstance; #endif // STONEYVCV_BUILD_PLUGIN //============================================================================== - -namespace StoneyDSP { -/** @addtogroup StoneyDSP - * @{ - */ - -namespace StoneyVCV { -/** @addtogroup StoneyVCV - * @{ - */ - -namespace Tools { -/** @addtogroup Tools - * @{ - */ -const extern ::StoneyDSP::float_t vMin; -const extern ::StoneyDSP::float_t vMax; -const extern ::StoneyDSP::float_t vNominal; -const extern ::StoneyDSP::float_t vBias; -const extern ::StoneyDSP::float_t vGround; -const extern ::StoneyDSP::float_t vFloor; - - /// @} group Tools -} // namespace Tools - -// Declare an abstract base class with a pure virtual destructor. -// It's the simplest possible abstract class. -template -struct Engine -{ -public: - Engine() { - DBG("Creating StoneyDSP::StoneyVCV::Engine"); - }; - virtual ~Engine() noexcept = 0; // pure virtual - virtual void processSample(T* sample) = 0; // pure virtual -}; - -template -::StoneyDSP::StoneyVCV::Engine::~Engine() noexcept -{ - DBG("Destroying StoneyDSP::StoneyVCV::Engine"); -} - -template struct ::StoneyDSP::StoneyVCV::Engine<::StoneyDSP::float_t>; -template struct ::StoneyDSP::StoneyVCV::Engine<::StoneyDSP::double_t>; - - /// @} group StoneyVCV -} // namespace StoneyVCV - - /// @} group StoneyDSP -} // namespace StoneyDSP diff --git a/plugin.json b/plugin.json index 53e6dc7f..a0678d78 100644 --- a/plugin.json +++ b/plugin.json @@ -40,5 +40,5 @@ "pluginUrl" : "https://github.com/StoneyDSP/StoneyVCV", "slug" : "StoneyDSP-StoneyVCV", "sourceUrl" : "https://github.com/StoneyDSP/StoneyVCV/blob/production", - "version" : "2.0.1233" + "version" : "2.0.1265" } \ No newline at end of file diff --git a/share/cmake/Modules/StoneyVCVAddTest.cmake b/share/cmake/Modules/StoneyVCVAddTest.cmake new file mode 100644 index 00000000..157bbafe --- /dev/null +++ b/share/cmake/Modules/StoneyVCVAddTest.cmake @@ -0,0 +1,47 @@ +function(stoneyvcv_add_test MODULE) + + set(tests_${MODULE}_VERSION_MAJOR "${STONEYVCV_VERSION_MAJOR}") + set(tests_${MODULE}_VERSION_MINOR "${STONEYVCV_VERSION_MINOR}") + set(tests_${MODULE}_VERSION_PATCH "${STONEYVCV_VERSION_PATCH}") + set(tests_${MODULE}_VERSION "${tests_${MODULE}_VERSION_MAJOR}.${tests_${MODULE}_VERSION_MINOR}.${tests_${MODULE}_VERSION_PATCH}") + + add_library(tests_${MODULE} OBJECT EXCLUDE_FROM_ALL) + add_library(${STONEYVCV_SLUG}::tests_${MODULE} ALIAS tests_${MODULE}) + add_library(${STONEYVCV_BRAND}::${STONEYVCV_SLUG}::tests_${MODULE} ALIAS tests_${MODULE}) + set_target_properties(tests_${MODULE} + PROPERTIES + VERSION "${tests_${MODULE}_VERSION}" + SOVERSION "${tests_${MODULE}_VERSION_MAJOR}" + ) + target_include_directories(tests_${MODULE} + PUBLIC + $ + $ + ) + target_sources(tests_${MODULE} + PRIVATE + "${STONEYVCV_SOURCE_DIR}/test/${STONEYVCV_SLUG}/${MODULE}.cpp" + ) + target_link_libraries(tests_${MODULE} + PUBLIC + unofficial-vcvrack::rack-sdk::core + ${STONEYVCV_BRAND}::${STONEYVCV_SLUG}::${MODULE} + Catch2::Catch2 + ) + target_compile_definitions(tests_${MODULE} + PUBLIC + "-Dtests_${MODULE}_VERSION_MAJOR=${tests_${MODULE}_VERSION_MAJOR}" + "-Dtests_${MODULE}_VERSION_MINOR=${tests_${MODULE}_VERSION_MINOR}" + "-Dtests_${MODULE}_VERSION_PATCH=${tests_${MODULE}_VERSION_PATCH}" + "-Dtests_${MODULE}_VERSION=${tests_${MODULE}_VERSION}" + ) + target_compile_features(tests_${MODULE} PUBLIC cxx_std_17) + target_compile_features(tests_${MODULE} PUBLIC c_std_17) + set(tests_${MODULE}_VERSION_MAJOR "${STONEYVCV_VERSION_MAJOR}" PARENT_SCOPE) + set(tests_${MODULE}_VERSION_MINOR "${STONEYVCV_VERSION_MINOR}" PARENT_SCOPE) + set(tests_${MODULE}_VERSION_PATCH "${STONEYVCV_VERSION_PATCH}" PARENT_SCOPE) + set(tests_${MODULE}_VERSION "${tests_${MODULE}_VERSION_MAJOR}.${tests_${MODULE}_VERSION_MINOR}.${tests_${MODULE}_VERSION_PATCH}" PARENT_SCOPE) + + message(STATUS "Added target: ${STONEYVCV_BRAND}::${STONEYVCV_SLUG}::tests_${MODULE} v${tests_${MODULE}_VERSION}") + +endfunction() diff --git a/share/cmake/Modules/StoneyVCVVersionHelpers.cmake b/share/cmake/Modules/StoneyVCVVersionHelpers.cmake new file mode 100644 index 00000000..eb43965c --- /dev/null +++ b/share/cmake/Modules/StoneyVCVVersionHelpers.cmake @@ -0,0 +1,97 @@ +## REQUIREMENTS: rack-sdk 2.5.2 + +macro(stoneyvcv_git_versions) + + # https://softwareengineering.stackexchange.com/questions/141973/how-do-you-achieve-a-numeric-versioning-scheme-with-git + # 'git rev-list HEAD | wc -l' + find_package(Git REQUIRED) + execute_process( + COMMAND "${GIT_EXECUTABLE}" "rev-list" "HEAD" + COMMAND "wc" "-l" + WORKING_DIRECTORY "${STONEYVCV_SOURCE_DIR}" + OUTPUT_VARIABLE _STONEYVCV_GIT_COMMIT_COUNT + ERROR_VARIABLE _STONEYVCV_GIT_COMMIT_COUNT_ERROR + ) + if(_STONEYVCV_GIT_COMMIT_COUNT_ERROR) + message(SEND_ERROR "${_STONEYVCV_GIT_COMMIT_COUNT_ERROR}") + endif() + execute_process( + COMMAND "${GIT_EXECUTABLE}" "rev-parse" "HEAD" + WORKING_DIRECTORY "${STONEYVCV_SOURCE_DIR}" + OUTPUT_VARIABLE _STONEYVCV_GIT_REF_HEAD + ERROR_VARIABLE _STONEYVCV_GIT_REF_HEAD_ERROR + ) + if(_STONEYVCV_GIT_REF_HEAD_ERROR) + message(SEND_ERROR "${_STONEYVCV_GIT_REF_HEAD_ERROR}") + endif() + execute_process( + COMMAND "${GIT_EXECUTABLE}" "rev-parse" "--short" "HEAD" + WORKING_DIRECTORY "${STONEYVCV_SOURCE_DIR}" + OUTPUT_VARIABLE _STONEYVCV_GIT_REF_HEAD_SHORT + ERROR_VARIABLE _STONEYVCV_GIT_REF_HEAD_SHORT_ERROR + ) + if(_STONEYVCV_GIT_REF_HEAD_SHORT_ERROR) + message(SEND_ERROR "${_STONEYVCV_GIT_REF_HEAD_SHORT_ERROR}") + endif() + execute_process( + COMMAND "${GIT_EXECUTABLE}" rev-parse --abbrev-ref --symbolic-full-name HEAD + WORKING_DIRECTORY "${STONEYVCV_SOURCE_DIR}" + OUTPUT_VARIABLE _STONEYVCV_GIT_BRANCH + ERROR_VARIABLE _STONEYVCV_GIT_BRANCH_ERROR + ) + if(_STONEYVCV_GIT_BRANCH_ERROR) + message(SEND_ERROR "${_STONEYVCV_GIT_BRANCH_ERROR}") + endif() + string(STRIP "${_STONEYVCV_GIT_COMMIT_COUNT}" STONEYVCV_GIT_COMMIT_COUNT) + string(STRIP "${_STONEYVCV_GIT_REF_HEAD}" _STONEYVCV_GIT_REF_HEAD) + string(STRIP "${_STONEYVCV_GIT_REF_HEAD_SHORT}" _STONEYVCV_GIT_REF_HEAD_SHORT) + string(STRIP "${_STONEYVCV_GIT_BRANCH}" STONEYVCV_GIT_BRANCH) + + string(HEX "${_STONEYVCV_GIT_REF_HEAD}" STONEYVCV_GIT_REF_HEAD) + string(HEX "${_STONEYVCV_GIT_REF_HEAD_SHORT}" STONEYVCV_GIT_REF_HEAD_SHORT) + + file(READ "${STONEYVCV_SOURCE_DIR}/plugin.json" STONEYVCV_PLUGIN_JSON) + string(CONFIGURE "2.0.@STONEYVCV_GIT_COMMIT_COUNT@" _STONEYVCV_PLUGIN_JSON_VERSION @ONLY) + string(JSON _STONEYVCV_PLUGIN_JSON ERROR_VARIABLE _STONEYVCV_PLUGIN_JSON_SET_ROOT_ERROR SET "${STONEYVCV_PLUGIN_JSON}" "version" "\"${_STONEYVCV_PLUGIN_JSON_VERSION}\"") + + if(_STONEYVCV_PLUGIN_JSON_SET_ROOT_ERROR) + message(FATAL_ERROR "${_STONEYVCV_PLUGIN_JSON_SET_ROOT_ERROR}") + endif(_STONEYVCV_PLUGIN_JSON_SET_ROOT_ERROR) + + file(WRITE "${STONEYVCV_SOURCE_DIR}/plugin.json.tmp" "${_STONEYVCV_PLUGIN_JSON}") + execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${STONEYVCV_SOURCE_DIR}/plugin.json.tmp" "${STONEYVCV_SOURCE_DIR}/plugin.json") + file(REMOVE "${STONEYVCV_SOURCE_DIR}/plugin.json.tmp") + + unset(_STONEYVCV_PLUGIN_JSON) + unset(_STONEYVCV_PLUGIN_JSON_VERSION) + +endmacro(stoneyvcv_git_versions) + +macro(stoneyvcv_update_version_file) + + if(NOT "${VCVRACK_PLUGIN_VERSION}" STREQUAL "${STONEYVCV_VERSION_MAJOR}.${STONEYVCV_VERSION_MINOR}.${STONEYVCV_VERSION_PATCH}") + set(_STONEYVCV_ERROR_STRING [==[ + + There is a mismatch between plugin versions in 'plugin.json' and 'CMakeLists.txt': + plugin.json#version: @VCVRACK_PLUGIN_VERSION@ + project(VERSION @STONEYVCV_VERSION_MAJOR@.@STONEYVCV_VERSION_MINOR@.@STONEYVCV_VERSION_PATCH@ + Please update the version number in the following files in order to silence this error: + @STONEYVCV_SOURCE_DIR@/plugin.json + @STONEYVCV_SOURCE_DIR@/CMakeLists.txt + ]==]) + string(CONFIGURE "${_STONEYVCV_ERROR_STRING}" STONEYVCV_ERROR_STRING @ONLY) + if("${CMAKE_BUILD_TYPE}" STREQUAL "Release") + message(SEND_ERROR "${STONEYVCV_ERROR_STRING}") + return() + elseif("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + message(WARNING "${STONEYVCV_ERROR_STRING}") + endif() + endif() + + set(STONEYVCV_VERSION_FILE "${STONEYVCV_SOURCE_DIR}/VERSION") + file(WRITE "${STONEYVCV_VERSION_FILE}.tmp" "${STONEYVCV_VERSION_MAJOR}.${STONEYVCV_VERSION_MINOR}.${STONEYVCV_VERSION_PATCH}.${STONEYVCV_VERSION_TWEAK}\n") + execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${STONEYVCV_VERSION_FILE}.tmp" "${STONEYVCV_VERSION_FILE}") + file(REMOVE "${STONEYVCV_VERSION_FILE}.tmp") + set(STONEYVCV_VERSION_FILE "${STONEYVCV_VERSION_FILE}" CACHE INTERNAL "StoneyVCV current version file." FORCE) + +endmacro() diff --git a/src/StoneyVCV.cpp b/src/StoneyVCV.cpp index a8c369c8..cbe78639 100644 --- a/src/StoneyVCV.cpp +++ b/src/StoneyVCV.cpp @@ -1,9 +1,6 @@ /******************************************************************************* * @file src/StoneyVCV.cpp * @author Nathan J. Hood - * @version 2.0.2 - * @date 2024-11-11 - * * @copyright Copyright (c) 2024 MIT License * ******************************************************************************/ @@ -11,3 +8,41 @@ #include //============================================================================== + +#include +#include + +//============================================================================== + +namespace StoneyDSP { + +//============================================================================== + +namespace StoneyVCV { + +//============================================================================== + +namespace Tools { + +//============================================================================== + +const ::StoneyDSP::float_t vMin = (-12.0F); +const ::StoneyDSP::float_t vMax = (12.0F); +const ::StoneyDSP::float_t vNominal = (10.0F); +const ::StoneyDSP::float_t vBias = (0.0F); +const ::StoneyDSP::float_t vGround = (0.0F); +const ::StoneyDSP::float_t vFloor = (0.0F); + +//============================================================================== + +} // namespace Tools + +//============================================================================== + +} // namespace StoneyVCV + +//============================================================================== + +} // namespace StoneyDSP + +//============================================================================== diff --git a/src/StoneyVCV/ComponentLibrary.cpp b/src/StoneyVCV/ComponentLibrary.cpp index 317d692e..23331d65 100644 --- a/src/StoneyVCV/ComponentLibrary.cpp +++ b/src/StoneyVCV/ComponentLibrary.cpp @@ -1,20 +1,25 @@ /******************************************************************************* * @file src/StoneyVCV/ComponentLibrary.cpp * @author Nathan J. Hood - * @version 2.0.2 - * @date 2024-11-11 - * * @copyright Copyright (c) 2024 MIT License * ******************************************************************************/ -#if defined (STONEYVCV_BUILD_PLUGIN) +#if defined (STONEYVCV_BUILD_COMPONENTLIBRARY) -#include #include //============================================================================== +#include + +//============================================================================== + +#include +#include + +//============================================================================== + #include //============================================================================== @@ -43,8 +48,8 @@ const ::NVGcolor bgGradientBlackS1 = ::nvgRGBA(23, 23, 23, 255); const ::NVGcolor borderColor = nvgRGBAf(0.5F, 0.5F, 0.5F, 0.5F); -const ::StoneyDSP::float_t MIN_WIDTH = 15.0F; //::rack::window::mm2px(5.079999999F); -const ::StoneyDSP::float_t MIN_HEIGHT = 380.0F; // ::rack::window::mm2px(128.693333312F); +const float MIN_WIDTH = 15.0F; //::rack::window::mm2px(5.079999999F); +const float MIN_HEIGHT = 380.0F; // ::rack::window::mm2px(128.693333312F); //============================================================================== @@ -91,351 +96,6 @@ void addScrewsToWidget(::rack::widget::Widget* widget) //============================================================================== -::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel::ThemedPortWidgetPanel() -: labelText(""), - isOutput(true) -{ - // TODO: Assertions... - this->setSize(::rack::math::Vec(28.55155F, 39.15691F)); -} - -::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel::~ThemedPortWidgetPanel() -{ - // Assertions - // DBG("Destroying StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel"); - assert(!this->parent); - - // Children - this->clearChildren(); -} - -void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel::step() -{ - this->setSize(::rack::math::Vec(28.55155F, 39.15691F)); - return ::rack::widget::Widget::step(); -} - -void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel::draw(const StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel::DrawArgs &args) -{ - const auto& bgBlack = this->isOutput ? ::StoneyDSP::StoneyVCV::Panels::bgPortBlack : ::StoneyDSP::StoneyVCV::Panels::bgPortWhite; - const auto& bgWhite = this->isOutput ? ::StoneyDSP::StoneyVCV::Panels::bgPortWhite : ::StoneyDSP::StoneyVCV::Panels::bgPortBlack; - const auto& bgColor = ::rack::settings::preferDarkPanels ? bgBlack : bgWhite; - // const auto& bgGradientS0 = ::rack::settings::preferDarkPanels ? ::StoneyDSP::StoneyVCV::Panels::bgGradientBlackS0 : ::StoneyDSP::StoneyVCV::Panels::bgGradientWhiteS0; - // const auto& bgGradientS1 = ::rack::settings::preferDarkPanels ? ::StoneyDSP::StoneyVCV::Panels::bgGradientBlackS1 : ::StoneyDSP::StoneyVCV::Panels::bgGradientWhiteS1; - // const auto& borderColor = ::StoneyDSP::StoneyVCV::Panels::borderColor; - const auto& textWhite = this->isOutput ? ::StoneyDSP::StoneyVCV::Panels::bgPortBlack : ::StoneyDSP::StoneyVCV::Panels::bgPortWhite; - const auto& textBlack = this->isOutput ? ::StoneyDSP::StoneyVCV::Panels::bgPortWhite : ::StoneyDSP::StoneyVCV::Panels::bgPortBlack; - const auto& textColor = ::rack::settings::preferDarkPanels ? textBlack : textWhite; - const auto& size = this->getSize(); - - // Load font from cache - ::std::shared_ptr<::rack::window::Font> font = APP->window->loadFont( - ::rack::asset::plugin( - ::StoneyDSP::StoneyVCV::Plugin::pluginInstance, "res/fonts/DejaVuSans.ttf" - ) - ); - - if(this->isOutput) - { - // Draw themed bg panel box - ::nvgBeginPath(args.vg); - ::nvgRoundedRect(args.vg, - /** x */0.0F, - /** y */0.0F, - /** w */size.x, - /** h */size.y, - /** rx */2.83465F - ); - ::nvgFillColor(args.vg, bgColor); - ::nvgFill(args.vg); - - // // Draw themed BG gradient - // const auto& bgGradient = ::nvgLinearGradient(args.vg, - // /** x */size.x * 0.5, - // /** Y */0.0F, - // /** w */size.x * 0.5, - // /** h */size.y, - // /** s1 */bgGradientS0, - // /** s2 */bgGradientS1 - // ); - // ::nvgBeginPath(args.vg); - // ::nvgRoundedRect(args.vg, - // /** x */0.0F, - // /** y */0.0F, - // /** w */size.x, - // /** h */size.y, - // /** rx */2.83465F - // ); - // ::nvgFillPaint(args.vg, bgGradient); - // ::nvgFill(args.vg); - - // // Draw border - // ::nvgBeginPath(args.vg); - // ::nvgRoundedRect(args.vg, - // /** x */0.0F, - // /** y */0.0F, - // /** w */size.x, - // /** h */size.y, - // /** rx */2.83465F - // ); - // ::nvgStrokeColor(args.vg, borderColor); - // ::nvgStrokeWidth(args.vg, 1.0F); - // ::nvgStroke(args.vg); - } - - // Don't draw text if font failed to load - if (font) { - ::nvgBeginPath(args.vg); - // Select font handle - ::nvgFontFaceId(args.vg, font->handle); - - // Set font size and alignment - ::nvgFontSize(args.vg, 8.0F); - ::nvgTextAlign(args.vg, - ::NVGalign::NVG_ALIGN_CENTER | ::NVGalign::NVG_ALIGN_BASELINE - ); - ::nvgFillColor(args.vg, textColor); - - // Draw the text at a position - ::nvgText(args.vg, - (this->getSize().x * 0.5F), - (8.0F + 2.425775F), - labelText.c_str(), - NULL - ); - } - - return ::rack::widget::Widget::draw(args); -} - -//============================================================================== - -::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidget::ThemedPortWidget() -: isOutput(true), - panel(::rack::createWidget<::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel>( - ::rack::math::Vec( - 0.0F - 2.425775F, - 0.0F - ((39.15691F - 23.7F) - 2.425775F) - ) - )), - fb(new ::rack::FramebufferWidget), - lastPrefersDarkPanels(::rack::settings::preferDarkPanels) -{ - // // TODO: Assertions - // DBG("Constructing StoneyVCV::ComponentLibrary::ThemedPortWidget"); - this->isOutput = this->type == ::rack::engine::Port::Type::OUTPUT; - this->panel->isOutput = this->isOutput; - - this->setSize(this->panel->getSize()); - this->fb->setSize(this->panel->getSize()); - this->addChildBottom(this->fb); - this->fb->addChild(this->panel); - - this->setSvg( - ::rack::window::Svg::load( - ::rack::asset::system("res/ComponentLibrary/PJ301M.svg") - ), - ::rack::window::Svg::load( - ::rack::asset::system("res/ComponentLibrary/PJ301M-dark.svg") - ) - ); -} - -::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidget::~ThemedPortWidget() -{ - // Assertions - // DBG("Destroying StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidget"); - assert(!this->parent); - - // Children - this->panel->clearChildren(); - this->fb->clearChildren(); - this->clearChildren(); -} - -void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidget::step() -{ - if (APP->window->pixelRatio < 2.0F) { - // Small details draw poorly at low DPI, - // so oversample when drawing to the framebuffer - this->fb->oversample = 2.0F; - } - else { - this->fb->oversample = 1.0F; - } - - if(this->lastPrefersDarkPanels != ::rack::settings::preferDarkPanels) { - this->fb->setDirty(); - this->lastPrefersDarkPanels = ::rack::settings::preferDarkPanels; - } - - // Update - this->isOutput = this->type == ::rack::engine::Port::Type::OUTPUT; - this->panel->isOutput = this->isOutput; - this->fb->setSize(this->panel->getSize()); - - return ::rack::app::ThemedSvgPort::step(); -} - -void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidget::draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidget::DrawArgs &args) -{ - return ::rack::app::ThemedSvgPort::draw(args); -}; - -//============================================================================== - -::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::ThemedWidget() -: fb(new ::rack::widget::FramebufferWidget), - panelBorder( - ::rack::createWidget<::rack::app::PanelBorder>( - ::rack::math::Vec(0.0F, 0.0F) - ) - ) -{ - // Assertions - // DBG("StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget"); - assert(this->fb != nullptr); - assert(this->panelBorder != nullptr); - - // Widgets - this->fb->setSize(this->getSize()); - this->addChild(this->fb); - - // Border - this->panelBorder->setSize(this->getSize()); - this->fb->addChild(this->panelBorder); -} - -::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::~ThemedWidget() -{ - // Assertions - // DBG("Destroying StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget"); - assert(!this->parent); - - // Children - this->panelBorder->clearChildren(); - this->fb->clearChildren(); - this->clearChildren(); -} - -void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::step() -{ - const auto& size = this->getSize(); - - this->panelBorder->setSize(size); - this->fb->setSize(size); - - return ::rack::widget::Widget::step(); -} - -void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::drawThemedBg(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::DrawArgs &args) -{ - const auto& bgBlack = ::StoneyDSP::StoneyVCV::Panels::bgBlack; - const auto& bgWhite = ::StoneyDSP::StoneyVCV::Panels::bgWhite; - const auto& bgColor = ::rack::settings::preferDarkPanels ? bgBlack : bgWhite; - const auto& bgGradientS0 = ::rack::settings::preferDarkPanels ? ::StoneyDSP::StoneyVCV::Panels::bgGradientBlackS0 : ::StoneyDSP::StoneyVCV::Panels::bgGradientWhiteS0; - const auto& bgGradientS1 = ::rack::settings::preferDarkPanels ? ::StoneyDSP::StoneyVCV::Panels::bgGradientBlackS1 : ::StoneyDSP::StoneyVCV::Panels::bgGradientWhiteS1; - const auto& size = this->getSize(); - - // draw Themed BG - ::nvgBeginPath(args.vg); - ::nvgRect(args.vg, - /** x */0.0F, - /** y */0.0F, - /** w */size.x, - /** h */size.y - ); - ::nvgFillColor(args.vg, bgColor); - ::nvgFill(args.vg); - - // Draw themed BG gradient - const auto& bgGradient = ::nvgLinearGradient(args.vg, - /** x */size.x * 0.5, - /** Y */0.0F, - /** w */size.x * 0.5, - /** h */size.y, - /** s1 */bgGradientS0, - /** s2 */bgGradientS1 - ); - ::nvgBeginPath(args.vg); - ::nvgRect(args.vg, - /** x */0.0F, - /** y */0.0F, - /** w */size.x, - /** h */size.y - ); - ::nvgFillPaint(args.vg, bgGradient); - ::nvgFill(args.vg); -} - -void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::drawDividerLines(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::DrawArgs &args) -{ - const auto& minWidth = ::StoneyDSP::StoneyVCV::Panels::MIN_WIDTH; - const auto& borderColor = ::StoneyDSP::StoneyVCV::Panels::borderColor; - const auto& size = this->getSize(); - - // Draw line L - ::nvgBeginPath(args.vg); - ::nvgMoveTo(args.vg, - /** x */minWidth * 0.5F, /** 0.5 screws right */ - /** y */minWidth + (minWidth * 0.5F)); /** 1.5 screws down */ - ::nvgLineTo(args.vg, - /** x */minWidth * 0.5F, /** 0.5 screws right */ - /** y */size.y - (minWidth + (minWidth * 0.5F)));/** 1.5 screws up */ - ::nvgStrokeColor(args.vg, borderColor); - ::nvgStrokeWidth(args.vg, 1.0F); - ::nvgStroke(args.vg); - - // Draw line R - ::nvgBeginPath(args.vg); - ::nvgMoveTo(args.vg, - /** x */size.x - (minWidth * 0.5F), /** 0.5 screws left */ - /** y */minWidth + (minWidth * 0.5F)); /** 1.5 screws down */ - ::nvgLineTo(args.vg, - /** x */size.x - (minWidth * 0.5F), /** 0.5 screws left */ - /** y */size.y - (minWidth + (minWidth * 0.5F)));/** 1.5 screws up */ - ::nvgStrokeColor(args.vg, borderColor); - ::nvgStrokeWidth(args.vg, 1.0F); - ::nvgStroke(args.vg); - - // Draw line T - ::nvgBeginPath(args.vg); - ::nvgMoveTo(args.vg, - /** x */minWidth + (minWidth * 0.5F), /** 1.5 screws right */ - /** y */minWidth * 0.5F); /** 0.5 screws down */ - ::nvgLineTo(args.vg, - /** x */size.x - (minWidth + (minWidth * 0.5F)), /** 1.5 screws left */ - /** y */minWidth * 0.5F); /** 0.5 screws down */ - ::nvgStrokeColor(args.vg, borderColor); - ::nvgStrokeWidth(args.vg, 1.0F); - ::nvgStroke(args.vg); - - // Draw line B - ::nvgBeginPath(args.vg); - ::nvgMoveTo(args.vg, - /** x */minWidth + (minWidth * 0.5F), /** 1.5 screws right */ - /** y */size.y - (minWidth * 0.5F)); /** 0.5 screws up */ - ::nvgLineTo(args.vg, - /** x */size.x - (minWidth + (minWidth * 0.5F)), /** 1.5 screws left */ - /** y */size.y - (minWidth * 0.5F)); /** 0.5 screws up */ - ::nvgStrokeColor(args.vg, borderColor); - ::nvgStrokeWidth(args.vg, 1.0F); - ::nvgStroke(args.vg); -} - -void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::DrawArgs &args) -{ - // draw Themed BG - this->drawThemedBg(args); - - // Draw lines - this->drawDividerLines(args); - - return ::rack::widget::Widget::draw(args); -} - -//============================================================================== - -#endif // defined (STONEYVCV_BUILD_PLUGIN) +#endif // defined (STONEYVCV_BUILD_COMPONENTLIBRARY) //============================================================================== diff --git a/src/StoneyVCV/ComponentLibrary/PanelWidget.cpp b/src/StoneyVCV/ComponentLibrary/PanelWidget.cpp new file mode 100644 index 00000000..bca9788d --- /dev/null +++ b/src/StoneyVCV/ComponentLibrary/PanelWidget.cpp @@ -0,0 +1,218 @@ +/******************************************************************************* + * @file src/StoneyVCV/ComponentLibrary/PortWidget.cpp + * @author Nathan J. Hood + * @copyright Copyright (c) 2025 MIT License + * + ******************************************************************************/ + +#include + +//============================================================================== + +#include +#include + +//============================================================================== + +#include +#include + +//============================================================================== + +void ::StoneyDSP::StoneyVCV::ComponentLibrary::PanelLinesWidget::draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::PanelLinesWidget::DrawArgs &args) +{ + const auto& minWidth = ::StoneyDSP::StoneyVCV::Panels::MIN_WIDTH; + const auto& borderColor = ::StoneyDSP::StoneyVCV::Panels::borderColor; + const auto& size = this->getSize(); + + // Draw line L + ::nvgBeginPath(args.vg); + ::nvgMoveTo(args.vg, + /** x */minWidth * 0.5F, /** 0.5 screws right */ + /** y */minWidth + (minWidth * 0.5F)); /** 1.5 screws down */ + ::nvgLineTo(args.vg, + /** x */minWidth * 0.5F, /** 0.5 screws right */ + /** y */size.y - (minWidth + (minWidth * 0.5F)));/** 1.5 screws up */ + ::nvgStrokeColor(args.vg, borderColor); + ::nvgStrokeWidth(args.vg, 1.0F); + ::nvgStroke(args.vg); + + // Draw line R + ::nvgBeginPath(args.vg); + ::nvgMoveTo(args.vg, + /** x */size.x - (minWidth * 0.5F), /** 0.5 screws left */ + /** y */minWidth + (minWidth * 0.5F)); /** 1.5 screws down */ + ::nvgLineTo(args.vg, + /** x */size.x - (minWidth * 0.5F), /** 0.5 screws left */ + /** y */size.y - (minWidth + (minWidth * 0.5F)));/** 1.5 screws up */ + ::nvgStrokeColor(args.vg, borderColor); + ::nvgStrokeWidth(args.vg, 1.0F); + ::nvgStroke(args.vg); + + // Draw line T + ::nvgBeginPath(args.vg); + ::nvgMoveTo(args.vg, + /** x */minWidth + (minWidth * 0.5F), /** 1.5 screws right */ + /** y */minWidth * 0.5F); /** 0.5 screws down */ + ::nvgLineTo(args.vg, + /** x */size.x - (minWidth + (minWidth * 0.5F)), /** 1.5 screws left */ + /** y */minWidth * 0.5F); /** 0.5 screws down */ + ::nvgStrokeColor(args.vg, borderColor); + ::nvgStrokeWidth(args.vg, 1.0F); + ::nvgStroke(args.vg); + + // Draw line B + ::nvgBeginPath(args.vg); + ::nvgMoveTo(args.vg, + /** x */minWidth + (minWidth * 0.5F), /** 1.5 screws right */ + /** y */size.y - (minWidth * 0.5F)); /** 0.5 screws up */ + ::nvgLineTo(args.vg, + /** x */size.x - (minWidth + (minWidth * 0.5F)), /** 1.5 screws left */ + /** y */size.y - (minWidth * 0.5F)); /** 0.5 screws up */ + ::nvgStrokeColor(args.vg, borderColor); + ::nvgStrokeWidth(args.vg, 1.0F); + ::nvgStroke(args.vg); +} + +//============================================================================== + +::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPanelWidget::ThemedPanelWidget() +: fb( + ::StoneyDSP::StoneyVCV::createWidgetSized<::rack::widget::FramebufferWidget>( + ::rack::math::Vec(0.0F, 0.0F), + this->getSize() + ) + ), + // screwsPositions{ + // ::rack::math::Vec( // top-left + // (::StoneyDSP::StoneyVCV::Panels::MIN_WIDTH * 0.5F), + // (::StoneyDSP::StoneyVCV::Panels::MIN_WIDTH * 0.5F) + // ), + // ::rack::math::Vec( // top-right + // (this->getSize().x - (::StoneyDSP::StoneyVCV::Panels::MIN_WIDTH * 0.5F)), + // (::StoneyDSP::StoneyVCV::Panels::MIN_WIDTH * 0.5F) + // ), + // ::rack::math::Vec( // bottom-left + // (::StoneyDSP::StoneyVCV::Panels::MIN_WIDTH * 0.5F), + // (this->getSize().y - (::StoneyDSP::StoneyVCV::Panels::MIN_WIDTH * 0.5F)) + // ), + // ::rack::math::Vec( // bottom-right + // (this->getSize().x - (::StoneyDSP::StoneyVCV::Panels::MIN_WIDTH * 0.5F)), + // (this->getSize().y - (::StoneyDSP::StoneyVCV::Panels::MIN_WIDTH * 0.5F)) + // ), + // }, + // screws{ + // ::rack::createWidgetCentered<::rack::componentlibrary::ThemedScrew>(this->screwsPositions[0]), + // ::rack::createWidgetCentered<::rack::componentlibrary::ThemedScrew>(this->screwsPositions[1]), + // ::rack::createWidgetCentered<::rack::componentlibrary::ThemedScrew>(this->screwsPositions[2]), + // ::rack::createWidgetCentered<::rack::componentlibrary::ThemedScrew>(this->screwsPositions[3]) + // }, + panelLines( + ::StoneyDSP::StoneyVCV::createWidgetSized<::StoneyDSP::StoneyVCV::ComponentLibrary::PanelLinesWidget>( + ::rack::math::Vec(0.0F, 0.0F), + this->getSize() + ) + ), + panelBorder( + ::StoneyDSP::StoneyVCV::createWidgetSized<::rack::app::PanelBorder>( + ::rack::math::Vec(0.0F, 0.0F), + this->getSize() + ) + ) +{ + // Assertions + DBG("StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPanelWidget"); + assert(this->fb != nullptr); + // assert(this->screws[0] != nullptr); + // assert(this->screws[1] != nullptr); + // assert(this->screws[2] != nullptr); + // assert(this->screws[3] != nullptr); + assert(this->panelLines != nullptr); + assert(this->panelBorder != nullptr); + + // Widgets + this->fb->setSize(this->getSize()); + this->addChild(this->fb); + + // Screws + // for(const auto& screw : this->screws) { + // this->fb->addChild(screw); + // } + + // Border + this->panelLines->setSize(this->getSize()); + this->fb->addChild(this->panelLines); + this->panelBorder->setSize(this->getSize()); + this->fb->addChild(this->panelBorder); +} + +::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPanelWidget::~ThemedPanelWidget() +{ + // Assertions + DBG("Destroying StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPanelWidget"); + assert(!this->parent); + + // Children + this->panelBorder->clearChildren(); + // for(const auto& screw : this->screws) { + // screw->clearChildren(); + // } + this->fb->clearChildren(); + this->clearChildren(); +} + +void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPanelWidget::step() +{ + const auto& size = this->getSize(); + + this->panelLines->setSize(size); + this->panelBorder->setSize(size); + this->fb->setSize(size); + + return ::rack::widget::Widget::step(); +} + +void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPanelWidget::draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPanelWidget::DrawArgs &args) +{ + // draw Themed BG + const auto& bgBlack = ::StoneyDSP::StoneyVCV::Panels::bgBlack; + const auto& bgWhite = ::StoneyDSP::StoneyVCV::Panels::bgWhite; + const auto& bgColor = ::rack::settings::preferDarkPanels ? bgBlack : bgWhite; + const auto& bgGradientS0 = ::rack::settings::preferDarkPanels ? ::StoneyDSP::StoneyVCV::Panels::bgGradientBlackS0 : ::StoneyDSP::StoneyVCV::Panels::bgGradientWhiteS0; + const auto& bgGradientS1 = ::rack::settings::preferDarkPanels ? ::StoneyDSP::StoneyVCV::Panels::bgGradientBlackS1 : ::StoneyDSP::StoneyVCV::Panels::bgGradientWhiteS1; + const auto& size = this->getSize(); + + // draw Themed BG + ::nvgBeginPath(args.vg); + ::nvgRect(args.vg, + /** x */0.0F, + /** y */0.0F, + /** w */size.x, + /** h */size.y + ); + ::nvgFillColor(args.vg, bgColor); + ::nvgFill(args.vg); + + // Draw themed BG gradient + const auto& bgGradient = ::nvgLinearGradient(args.vg, + /** x */size.x * 0.5, + /** Y */0.0F, + /** w */size.x * 0.5, + /** h */size.y, + /** s1 */bgGradientS0, + /** s2 */bgGradientS1 + ); + ::nvgBeginPath(args.vg); + ::nvgRect(args.vg, + /** x */0.0F, + /** y */0.0F, + /** w */size.x, + /** h */size.y + ); + ::nvgFillPaint(args.vg, bgGradient); + ::nvgFill(args.vg); + + return ::rack::widget::Widget::draw(args); +} + +//============================================================================== diff --git a/src/StoneyVCV/ComponentLibrary/PortWidget.cpp b/src/StoneyVCV/ComponentLibrary/PortWidget.cpp new file mode 100644 index 00000000..e11c4598 --- /dev/null +++ b/src/StoneyVCV/ComponentLibrary/PortWidget.cpp @@ -0,0 +1,217 @@ +/******************************************************************************* + * @file src/StoneyVCV/ComponentLibrary/PortWidget.cpp + * @author Nathan J. Hood + * @copyright Copyright (c) 2025 MIT License + * + ******************************************************************************/ + +#include + +//============================================================================== + +#include +#include + +//============================================================================== + +#include + +//============================================================================== + +::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel::ThemedPortWidgetPanel() +: labelText(""), + isOutput(true) +{ + // TODO: Assertions... + this->setSize(::rack::math::Vec(28.55155F, 39.15691F)); +} + +::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel::~ThemedPortWidgetPanel() +{ + // Assertions + // DBG("Destroying StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel"); + assert(!this->parent); + + // Children + this->clearChildren(); +} + +void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel::step() +{ + this->setSize(::rack::math::Vec(28.55155F, 39.15691F)); + return ::rack::widget::Widget::step(); +} + +void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel::draw(const StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel::DrawArgs &args) +{ + const auto& bgBlack = this->isOutput ? ::StoneyDSP::StoneyVCV::Panels::bgPortBlack : ::StoneyDSP::StoneyVCV::Panels::bgPortWhite; + const auto& bgWhite = this->isOutput ? ::StoneyDSP::StoneyVCV::Panels::bgPortWhite : ::StoneyDSP::StoneyVCV::Panels::bgPortBlack; + const auto& bgColor = ::rack::settings::preferDarkPanels ? bgBlack : bgWhite; + // const auto& bgGradientS0 = ::rack::settings::preferDarkPanels ? ::StoneyDSP::StoneyVCV::Panels::bgGradientBlackS0 : ::StoneyDSP::StoneyVCV::Panels::bgGradientWhiteS0; + // const auto& bgGradientS1 = ::rack::settings::preferDarkPanels ? ::StoneyDSP::StoneyVCV::Panels::bgGradientBlackS1 : ::StoneyDSP::StoneyVCV::Panels::bgGradientWhiteS1; + // const auto& borderColor = ::StoneyDSP::StoneyVCV::Panels::borderColor; + const auto& textWhite = this->isOutput ? ::StoneyDSP::StoneyVCV::Panels::bgPortBlack : ::StoneyDSP::StoneyVCV::Panels::bgPortWhite; + const auto& textBlack = this->isOutput ? ::StoneyDSP::StoneyVCV::Panels::bgPortWhite : ::StoneyDSP::StoneyVCV::Panels::bgPortBlack; + const auto& textColor = ::rack::settings::preferDarkPanels ? textBlack : textWhite; + const auto& size = this->getSize(); + + // Load font from cache + ::std::shared_ptr<::rack::window::Font> font = APP->window->loadFont( + ::rack::asset::system("res/fonts/DejaVuSans.ttf" + ) + ); + + if(this->isOutput) + { + // Draw themed bg panel box + ::nvgBeginPath(args.vg); + ::nvgRoundedRect(args.vg, + /** x */0.0F, + /** y */0.0F, + /** w */size.x, + /** h */size.y, + /** rx */2.83465F + ); + ::nvgFillColor(args.vg, bgColor); + ::nvgFill(args.vg); + + // // Draw themed BG gradient + // const auto& bgGradient = ::nvgLinearGradient(args.vg, + // /** x */size.x * 0.5, + // /** Y */0.0F, + // /** w */size.x * 0.5, + // /** h */size.y, + // /** s1 */bgGradientS0, + // /** s2 */bgGradientS1 + // ); + // ::nvgBeginPath(args.vg); + // ::nvgRoundedRect(args.vg, + // /** x */0.0F, + // /** y */0.0F, + // /** w */size.x, + // /** h */size.y, + // /** rx */2.83465F + // ); + // ::nvgFillPaint(args.vg, bgGradient); + // ::nvgFill(args.vg); + + // // Draw border + // ::nvgBeginPath(args.vg); + // ::nvgRoundedRect(args.vg, + // /** x */0.0F, + // /** y */0.0F, + // /** w */size.x, + // /** h */size.y, + // /** rx */2.83465F + // ); + // ::nvgStrokeColor(args.vg, borderColor); + // ::nvgStrokeWidth(args.vg, 1.0F); + // ::nvgStroke(args.vg); + } + + // Don't draw text if font failed to load + if (font) { + ::nvgBeginPath(args.vg); + // Select font handle + ::nvgFontFaceId(args.vg, font->handle); + + // Set font size and alignment + ::nvgFontSize(args.vg, 8.0F); + ::nvgTextAlign(args.vg, + ::NVGalign::NVG_ALIGN_CENTER | ::NVGalign::NVG_ALIGN_BASELINE + ); + ::nvgFillColor(args.vg, textColor); + + // Draw the text at a position + ::nvgText(args.vg, + (this->getSize().x * 0.5F), + (8.0F + 2.425775F), + labelText.c_str(), + NULL + ); + } + + return ::rack::widget::Widget::draw(args); +} + +//============================================================================== + +::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidget::ThemedPortWidget() +: isOutput(true), + panel( + ::rack::createWidget<::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidgetPanel>( + ::rack::math::Vec( + 0.0F - 2.425775F, + 0.0F - ((39.15691F - 23.7F) - 2.425775F) + ) + ) + ), + fb( + ::rack::createWidget<::rack::FramebufferWidget>( + ::rack::math::Vec(0.0F, 0.0F) + ) + ), + lastPrefersDarkPanels(::rack::settings::preferDarkPanels) +{ + // // TODO: Assertions + // DBG("Constructing StoneyVCV::ComponentLibrary::ThemedPortWidget"); + this->isOutput = this->type == ::rack::engine::Port::Type::OUTPUT; + this->panel->isOutput = this->isOutput; + + this->setSize(this->panel->getSize()); + this->fb->setSize(this->panel->getSize()); + this->addChildBottom(this->fb); + this->fb->addChild(this->panel); + + this->setSvg( + ::rack::window::Svg::load( + ::rack::asset::system("res/ComponentLibrary/PJ301M.svg") + ), + ::rack::window::Svg::load( + ::rack::asset::system("res/ComponentLibrary/PJ301M-dark.svg") + ) + ); +} + +::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidget::~ThemedPortWidget() +{ + // Assertions + // DBG("Destroying StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidget"); + assert(!this->parent); + + // Children + this->panel->clearChildren(); + this->fb->clearChildren(); + this->clearChildren(); +} + +void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidget::step() +{ + if (APP->window->pixelRatio < 2.0F) { + // Small details draw poorly at low DPI, + // so oversample when drawing to the framebuffer + this->fb->oversample = 2.0F; + } + else { + this->fb->oversample = 1.0F; + } + + if(this->lastPrefersDarkPanels != ::rack::settings::preferDarkPanels) { + this->fb->setDirty(); + this->lastPrefersDarkPanels = ::rack::settings::preferDarkPanels; + } + + // Update + this->isOutput = this->type == ::rack::engine::Port::Type::OUTPUT; + this->panel->isOutput = this->isOutput; + this->fb->setSize(this->panel->getSize()); + + return ::rack::app::ThemedSvgPort::step(); +} + +void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidget::draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPortWidget::DrawArgs &args) +{ + return ::rack::app::ThemedSvgPort::draw(args); +}; + +//============================================================================== diff --git a/src/StoneyVCV/ComponentLibrary/Widget.cpp b/src/StoneyVCV/ComponentLibrary/Widget.cpp new file mode 100644 index 00000000..b9d62af6 --- /dev/null +++ b/src/StoneyVCV/ComponentLibrary/Widget.cpp @@ -0,0 +1,117 @@ +/******************************************************************************* + * @file src/StoneyVCV/ComponentLibrary/Widget.cpp + * @author Nathan J. Hood + * @copyright Copyright (c) 2025 MIT License + * + ******************************************************************************/ + +#include + +//============================================================================== + +#include +#include + +//============================================================================== + +#include + +//============================================================================== + +::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::ThemedWidget() +: fb( + ::rack::createWidget<::rack::widget::FramebufferWidget>( + ::rack::math::Vec(0.0F, 0.0F) + ) + ), + panelBorder( + ::rack::createWidget<::rack::app::PanelBorder>( + ::rack::math::Vec(0.0F, 0.0F) + ) + ) +{ + // Assertions + // DBG("StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget"); + assert(this->fb != nullptr); + assert(this->panelBorder != nullptr); + + // Widgets + this->fb->setSize(this->getSize()); + this->addChild(this->fb); + + // Border + this->panelBorder->setSize(this->getSize()); + this->fb->addChild(this->panelBorder); +} + +::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::~ThemedWidget() +{ + // Assertions + // DBG("Destroying StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget"); + assert(!this->parent); + + // Children + this->panelBorder->clearChildren(); + this->fb->clearChildren(); + this->clearChildren(); +} + +void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::step() +{ + const auto& size = this->getSize(); + + this->panelBorder->setSize(size); + this->fb->setSize(size); + + return ::rack::widget::Widget::step(); +} + +void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::drawThemedBg(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::DrawArgs &args) +{ + const auto& bgBlack = ::StoneyDSP::StoneyVCV::Panels::bgBlack; + const auto& bgWhite = ::StoneyDSP::StoneyVCV::Panels::bgWhite; + const auto& bgColor = ::rack::settings::preferDarkPanels ? bgBlack : bgWhite; + const auto& bgGradientS0 = ::rack::settings::preferDarkPanels ? ::StoneyDSP::StoneyVCV::Panels::bgGradientBlackS0 : ::StoneyDSP::StoneyVCV::Panels::bgGradientWhiteS0; + const auto& bgGradientS1 = ::rack::settings::preferDarkPanels ? ::StoneyDSP::StoneyVCV::Panels::bgGradientBlackS1 : ::StoneyDSP::StoneyVCV::Panels::bgGradientWhiteS1; + const auto& size = this->getSize(); + + // draw Themed BG + ::nvgBeginPath(args.vg); + ::nvgRect(args.vg, + /** x */0.0F, + /** y */0.0F, + /** w */size.x, + /** h */size.y + ); + ::nvgFillColor(args.vg, bgColor); + ::nvgFill(args.vg); + + // Draw themed BG gradient + const auto& bgGradient = ::nvgLinearGradient(args.vg, + /** x */size.x * 0.5, + /** Y */0.0F, + /** w */size.x * 0.5, + /** h */size.y, + /** s1 */bgGradientS0, + /** s2 */bgGradientS1 + ); + ::nvgBeginPath(args.vg); + ::nvgRect(args.vg, + /** x */0.0F, + /** y */0.0F, + /** w */size.x, + /** h */size.y + ); + ::nvgFillPaint(args.vg, bgGradient); + ::nvgFill(args.vg); +} + +void ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::draw(const ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::DrawArgs &args) +{ + // draw Themed BG + this->drawThemedBg(args); + + return ::rack::widget::Widget::draw(args); +} + +//============================================================================== diff --git a/src/StoneyVCV/HP1.cpp b/src/StoneyVCV/HP1.cpp index d887c14f..4538d6eb 100644 --- a/src/StoneyVCV/HP1.cpp +++ b/src/StoneyVCV/HP1.cpp @@ -1,10 +1,6 @@ /******************************************************************************* * @file src/StoneyVCV/HP1.cpp * @author Nathan J. Hood - * @brief - * @version 2.0.2 - * @date 2024-11-11 - * * @copyright Copyright (c) 2024 MIT License * ******************************************************************************/ @@ -13,6 +9,7 @@ //============================================================================== +#include #include #include @@ -21,6 +18,8 @@ #include #include +//============================================================================== + #include //============================================================================== diff --git a/src/StoneyVCV/HP2.cpp b/src/StoneyVCV/HP2.cpp index 347a9dc5..0e1d8a10 100644 --- a/src/StoneyVCV/HP2.cpp +++ b/src/StoneyVCV/HP2.cpp @@ -1,10 +1,6 @@ /***************************************************************************//** * @file src/StoneyVCV/HP2.cpp * @author Nathan J. Hood - * @brief - * @version 2.0.2 - * @date 2024-11-11 - * * @copyright Copyright (c) 2024 MIT License * ******************************************************************************/ @@ -13,6 +9,7 @@ //============================================================================== +#include #include #include @@ -20,6 +17,8 @@ #include +//============================================================================== + #include //============================================================================== diff --git a/src/StoneyVCV/HP4.cpp b/src/StoneyVCV/HP4.cpp index f280d9b7..73c6707a 100644 --- a/src/StoneyVCV/HP4.cpp +++ b/src/StoneyVCV/HP4.cpp @@ -1,10 +1,6 @@ /******************************************************************************* * @file src/StoneyVCV/HP4.cpp * @author Nathan J. Hood - * @brief - * @version 2.0.2 - * @date 2024-11-11 - * * @copyright Copyright (c) 2024 MIT License * ******************************************************************************/ @@ -13,6 +9,7 @@ //============================================================================== +#include #include #include diff --git a/src/StoneyVCV/LFO.cpp b/src/StoneyVCV/LFO.cpp index 6c52438c..dc62c873 100644 --- a/src/StoneyVCV/LFO.cpp +++ b/src/StoneyVCV/LFO.cpp @@ -1,10 +1,6 @@ /******************************************************************************* * @file src/StoneyVCV/LFO.cpp * @author Nathan J. Hood - * @brief - * @version 2.0.2 - * @date 2024-11-11 - * * @copyright Copyright (c) 2024 MIT License * ******************************************************************************/ @@ -13,6 +9,7 @@ //============================================================================== +#include #include #include diff --git a/src/StoneyVCV/VCA.cpp b/src/StoneyVCV/VCA.cpp index c425ec51..3292d7a7 100644 --- a/src/StoneyVCV/VCA.cpp +++ b/src/StoneyVCV/VCA.cpp @@ -1,9 +1,6 @@ /******************************************************************************* * @file src/StoneyVCV/VCA.cpp * @author Nathan J. Hood - * @version 2.0.2 - * @date 2024-11-11 - * * @copyright Copyright (c) 2024 MIT License * ******************************************************************************/ @@ -12,6 +9,9 @@ //============================================================================== +#include +#include +#include #include #include @@ -121,9 +121,15 @@ template struct ::StoneyDSP::StoneyVCV::VCA::VCAEngine<::StoneyDSP::double_t>; //============================================================================== ::StoneyDSP::StoneyVCV::VCA::VCAModule::VCAModule() -: lightDivider(), +: ::rack::engine::Module::Module(), + lightDivider(), engine(), - lightGains{0.0F} + lightGains{0.0F}, + vcaInputPtr(nullptr), + cvInputPtr(nullptr), + gainParamPtr(nullptr), + vcaOutputPtr(nullptr), + blinkLightPtr(nullptr) { // Assertions DBG("Constructing StoneyVCV::VCA::VCAModule"); @@ -169,6 +175,18 @@ ::StoneyDSP::StoneyVCV::VCA::VCAModule::VCAModule() for(auto &e : this->engine) { e.setGain(0.0F); } + + this->vcaInputPtr = dynamic_cast<::rack::engine::Input*>(&this->inputs[::StoneyDSP::StoneyVCV::VCA::VCAModule::IdxInputs::VCA_INPUT]); + this->cvInputPtr = dynamic_cast<::rack::engine::Input*>(&this->inputs[::StoneyDSP::StoneyVCV::VCA::VCAModule::IdxInputs::CV_INPUT]); + this->gainParamPtr = dynamic_cast<::rack::engine::Param*>(&this->params[::StoneyDSP::StoneyVCV::VCA::VCAModule::IdxParams::GAIN_PARAM]); + this->vcaOutputPtr = dynamic_cast<::rack::engine::Output*>(&this->outputs[::StoneyDSP::StoneyVCV::VCA::VCAModule::IdxOutputs::VCA_OUTPUT]); + this->blinkLightPtr = dynamic_cast<::rack::engine::Light*>(&this->lights[::StoneyDSP::StoneyVCV::VCA::VCAModule::IdxLights::BLINK_LIGHT]); + + assert(this->vcaInputPtr != nullptr); + assert(this->cvInputPtr != nullptr); + assert(this->gainParamPtr != nullptr); + assert(this->vcaOutputPtr != nullptr); + assert(this->blinkLightPtr != nullptr); } ::StoneyDSP::StoneyVCV::VCA::VCAModule::~VCAModule() noexcept @@ -190,7 +208,8 @@ void ::StoneyDSP::StoneyVCV::VCA::VCAModule::process(const ::StoneyDSP::StoneyVC auto &cv_input = this->getCvInput(); auto &gain_param = this->getGainParam(); auto &vca_output = this->getVcaOutput(); - auto &blink_light = this->lights[::StoneyDSP::StoneyVCV::VCA::VCAModule::IdxLights::BLINK_LIGHT + 0]; + auto &blink_light = this->getBlinkLight(); + // auto &blink_light = this->lights[::StoneyDSP::StoneyVCV::VCA::VCAModule::IdxLights::BLINK_LIGHT + 0]; // auto &blink_light_r = this->lights[::StoneyDSP::StoneyVCV::VCA::VCAModule::IdxLights::BLINK_LIGHT + 1]; // if (!vca_input.isConnected() && !vca_output.isConnected() && !cv_input.isConnected()) { @@ -256,27 +275,27 @@ void ::StoneyDSP::StoneyVCV::VCA::VCAModule::process(const ::StoneyDSP::StoneyVC ::rack::engine::Input &::StoneyDSP::StoneyVCV::VCA::VCAModule::getVcaInput() noexcept { - return this->inputs[::StoneyDSP::StoneyVCV::VCA::VCAModule::IdxInputs::VCA_INPUT]; + return *this->vcaInputPtr; } ::rack::engine::Input &::StoneyDSP::StoneyVCV::VCA::VCAModule::getCvInput() noexcept { - return this->inputs[::StoneyDSP::StoneyVCV::VCA::VCAModule::IdxInputs::CV_INPUT]; + return *this->cvInputPtr; } ::rack::engine::Param &::StoneyDSP::StoneyVCV::VCA::VCAModule::getGainParam() noexcept { - return this->params[::StoneyDSP::StoneyVCV::VCA::VCAModule::IdxParams::GAIN_PARAM]; + return *this->gainParamPtr; } ::rack::engine::Output &::StoneyDSP::StoneyVCV::VCA::VCAModule::getVcaOutput() noexcept { - return this->outputs[::StoneyDSP::StoneyVCV::VCA::VCAModule::IdxOutputs::VCA_OUTPUT]; + return *this->vcaOutputPtr; } ::rack::engine::Light &::StoneyDSP::StoneyVCV::VCA::VCAModule::getBlinkLight() noexcept { - return this->lights[::StoneyDSP::StoneyVCV::VCA::VCAModule::IdxLights::BLINK_LIGHT]; + return *this->blinkLightPtr; } // ::json_t *::StoneyDSP::StoneyVCV::VCA::VCAModule::dataToJson() @@ -347,17 +366,53 @@ ::StoneyDSP::StoneyVCV::VCA::VCAWidget::~VCAWidget() assert(!this->parent); // Children + for(const auto& screw : this->screws) { + screw->clearChildren(); + } this->clearChildren(); } void ::StoneyDSP::StoneyVCV::VCA::VCAWidget::step() { - return ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::step(); + return ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPanelWidget::step(); } void ::StoneyDSP::StoneyVCV::VCA::VCAWidget::draw(const ::StoneyDSP::StoneyVCV::VCA::VCAWidget::DrawArgs &args) { - return ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedWidget::draw(args); + // const auto& textColor = ::rack::settings::preferDarkPanels ? ::StoneyDSP::StoneyVCV::Panels::bgWhite : ::StoneyDSP::StoneyVCV::Panels::bgBlack; + + // // Load font from cache + // ::std::shared_ptr<::rack::window::Font> font = APP->window->loadFont( + // ::rack::asset::plugin( + // ::StoneyDSP::StoneyVCV::Plugin::pluginInstance, "res/fonts/Roboto-Regular.ttf" + // ) + // ); + + // // Don't draw text if font failed to load + // if (font) { + // ::nvgBeginPath(args.vg); + // // Select font handle + // ::nvgFontFaceId(args.vg, font->handle); + + // // Set font size and alignment + // ::nvgFontSize(args.vg, 8.0F); + // ::nvgTextAlign(args.vg, + // ::NVGalign::NVG_ALIGN_CENTER | ::NVGalign::NVG_ALIGN_BASELINE + // ); + // ::nvgFillColor(args.vg, textColor); + + // ::std::string labelText = "VCA"; + + // // Draw the text at a position + // ::nvgText(args.vg, + // (this->getSize().x * 0.5F), + // (::StoneyDSP::StoneyVCV::Panels::MIN_WIDTH * 3.0F) + 8.0F, + // labelText.c_str(), + // NULL + // ); + // } + + return ::StoneyDSP::StoneyVCV::ComponentLibrary::ThemedPanelWidget::draw(args); } //============================================================================== @@ -376,14 +431,24 @@ ::StoneyDSP::StoneyVCV::VCA::VCAModuleWidget::VCAModuleWidget(::StoneyDSP::Stone ) ) ), - vcaWidget(::rack::createWidget<::StoneyDSP::StoneyVCV::VCA::VCAWidget>(::rack::math::Vec(0.0F, 0.0F))), - vcaModuleWidgetFrameBuffer(new ::rack::FramebufferWidget), + vcaWidget( + ::StoneyDSP::StoneyVCV::createWidgetSized<::StoneyDSP::StoneyVCV::VCA::VCAWidget>( + ::rack::math::Vec(0.0F, 0.0F), + ::StoneyDSP::StoneyVCV::VCA::VCADimensions + ) + ), + vcaModuleWidgetFrameBuffer( + ::StoneyDSP::StoneyVCV::createWidgetSized<::rack::FramebufferWidget>( + ::rack::math::Vec(0.0F, 0.0F), + ::StoneyDSP::StoneyVCV::VCA::VCADimensions + ) + ), // Params gainKnob( - ::rack::createParamCentered<::rack::componentlibrary::RoundBigBlackKnob>( + ::rack::createParamCentered<::rack::componentlibrary::RoundLargeBlackKnob>( ::rack::math::Vec( - ::StoneyDSP::StoneyVCV::VCA::VCADimensions.x * 0.5F, - 0.0F + ((::StoneyDSP::StoneyVCV::Panels::MIN_WIDTH * 0.5F) * 15.0F) + (::StoneyDSP::StoneyVCV::VCA::VCADimensions.x * 0.5F), + (0.0F + ((::StoneyDSP::StoneyVCV::Panels::MIN_WIDTH * 0.5F) * 15.0F)) ), module, ::StoneyDSP::StoneyVCV::VCA::VCAModule::IdxParams::GAIN_PARAM @@ -473,11 +538,9 @@ ::StoneyDSP::StoneyVCV::VCA::VCAModuleWidget::VCAModuleWidget(::StoneyDSP::Stone this->getPanel()->setSize(this->getSize()); // Frame Buffer - this->vcaModuleWidgetFrameBuffer->setSize(this->getSize()); this->addChild(this->vcaModuleWidgetFrameBuffer); // Widget - this->vcaWidget->setSize(this->getSize()); this->vcaModuleWidgetFrameBuffer->addChild(this->vcaWidget); // Params @@ -526,7 +589,12 @@ void ::StoneyDSP::StoneyVCV::VCA::VCAModuleWidget::step() this->lastPrefersDarkPanels = ::rack::settings::preferDarkPanels; } - return ::rack::Widget::step(); + return ::rack::app::ModuleWidget::step(); +} + +void ::StoneyDSP::StoneyVCV::VCA::VCAModuleWidget::draw(const ::StoneyDSP::StoneyVCV::VCA::VCAModuleWidget::DrawArgs &args) +{ + return ::rack::app::ModuleWidget::draw(args); } //============================================================================== diff --git a/src/StoneyVCV/plugin.cpp b/src/StoneyVCV/plugin.cpp index 29a27032..67b42d0d 100644 --- a/src/StoneyVCV/plugin.cpp +++ b/src/StoneyVCV/plugin.cpp @@ -1,10 +1,6 @@ /******************************************************************************* * @file src/StoneyVCV/plugin.cpp * @author Nathan J. Hood - * @brief - * @version 2.0.1 - * @date 2024-11-11 - * * @copyright Copyright (c) 2024 MIT License * ******************************************************************************/ @@ -17,6 +13,10 @@ //============================================================================== +#include + +//============================================================================== + #include //============================================================================== @@ -65,28 +65,20 @@ void init(::rack::plugin::Plugin* p) { ::StoneyDSP::StoneyVCV::Plugin::pluginInstance = p; -#if (STONEYVCV_VERSION_MAJOR >= 2U) && (STONEYVCV_VERSION_MINOR >= 0) && (STONEYVCV_VERSION_PATCH >= 2) - - #ifdef STONEYVCV_BUILD_VCA - p->addModel(::StoneyDSP::StoneyVCV::VCA::modelVCA); - #endif - -#endif // STONEYVCV_VERSION_PATCH >= 2 - -#if (STONEYVCV_VERSION_MAJOR >= 2U) && (STONEYVCV_VERSION_MINOR >= 0) && (STONEYVCV_VERSION_PATCH >= 1) - - #ifdef STONEYVCV_BUILD_HP4 - p->addModel(::StoneyDSP::StoneyVCV::HP4::modelHP4); - #endif +#ifdef STONEYVCV_BUILD_VCA + p->addModel(::StoneyDSP::StoneyVCV::VCA::modelVCA); +#endif - #ifdef STONEYVCV_BUILD_HP2 - p->addModel(::StoneyDSP::StoneyVCV::HP2::modelHP2); - #endif +#ifdef STONEYVCV_BUILD_HP4 + p->addModel(::StoneyDSP::StoneyVCV::HP4::modelHP4); +#endif - #ifdef STONEYVCV_BUILD_HP1 - p->addModel(::StoneyDSP::StoneyVCV::HP1::modelHP1); - #endif +#ifdef STONEYVCV_BUILD_HP2 + p->addModel(::StoneyDSP::StoneyVCV::HP2::modelHP2); +#endif +#ifdef STONEYVCV_BUILD_HP1 + p->addModel(::StoneyDSP::StoneyVCV::HP1::modelHP1); #endif #if (STONEYVCV_VERSION_MAJOR >= 2U) && (STONEYVCV_VERSION_MINOR >= 0) && (STONEYVCV_VERSION_PATCH < 1U) @@ -109,41 +101,6 @@ void init(::rack::plugin::Plugin* p) { // your module is created to reduce startup times of Rack. } -//============================================================================== - -namespace StoneyDSP { - -//============================================================================== - -namespace StoneyVCV { - -//============================================================================== - -namespace Tools { - -//============================================================================== - -const ::StoneyDSP::float_t vMin = (-12.0F); -const ::StoneyDSP::float_t vMax = (12.0F); -const ::StoneyDSP::float_t vNominal = (10.0F); -const ::StoneyDSP::float_t vBias = (0.0F); -const ::StoneyDSP::float_t vGround = (0.0F); -const ::StoneyDSP::float_t vFloor = (0.0F); - -//============================================================================== - -} // namespace Tools - -//============================================================================== - -} // namespace StoneyVCV - -//============================================================================== - -} // namespace StoneyDSP - -//============================================================================== - #endif // defined (STONEYVCV_BUILD_MODULES) //============================================================================== diff --git a/test/StoneyVCV/plugin.cpp b/test/StoneyVCV/plugin.cpp index 56d8e2d5..13e97c4a 100644 --- a/test/StoneyVCV/plugin.cpp +++ b/test/StoneyVCV/plugin.cpp @@ -57,30 +57,26 @@ TEST_CASE("plugin", "[plugin]") { #endif #endif -#if (STONEYVCV_VERSION_MAJOR >= 2U) && (STONEYVCV_VERSION_MINOR >= 0U) && (STONEYVCV_VERSION_PATCH >= 2U) - #ifdef STONEYVCV_BUILD_VCA - SECTION( "VCA" ) { - REQUIRE(::StoneyDSP::StoneyVCV::VCA::modelVCA != nullptr); - } - #endif +#ifdef STONEYVCV_BUILD_VCA + SECTION( "VCA" ) { + REQUIRE(::StoneyDSP::StoneyVCV::VCA::modelVCA != nullptr); + } #endif -#if (STONEYVCV_VERSION_MAJOR >= 2U) && (STONEYVCV_VERSION_MINOR >= 0U) && (STONEYVCV_VERSION_PATCH >= 1U) - #ifdef STONEYVCV_BUILD_HP4 - SECTION( "HP4" ) { - REQUIRE(::StoneyDSP::StoneyVCV::HP4::modelHP4 != nullptr); - } - #endif - #ifdef STONEYVCV_BUILD_HP2 - SECTION( "HP2" ) { - REQUIRE(::StoneyDSP::StoneyVCV::HP2::modelHP2 != nullptr); - } - #endif - #ifdef STONEYVCV_BUILD_HP1 - SECTION( "HP1" ) { - REQUIRE(::StoneyDSP::StoneyVCV::HP1::modelHP1 != nullptr); - } - #endif +#ifdef STONEYVCV_BUILD_HP4 + SECTION( "HP4" ) { + REQUIRE(::StoneyDSP::StoneyVCV::HP4::modelHP4 != nullptr); + } +#endif +#ifdef STONEYVCV_BUILD_HP2 + SECTION( "HP2" ) { + REQUIRE(::StoneyDSP::StoneyVCV::HP2::modelHP2 != nullptr); + } +#endif +#ifdef STONEYVCV_BUILD_HP1 + SECTION( "HP1" ) { + REQUIRE(::StoneyDSP::StoneyVCV::HP1::modelHP1 != nullptr); + } #endif #if (STONEYVCV_VERSION_MAJOR >= 2U) && (STONEYVCV_VERSION_MINOR >= 0U) && (STONEYVCV_VERSION_PATCH < 1U) diff --git a/test/StoneyVCV/test.hpp b/test/StoneyVCV/test.hpp index babd2074..270a186c 100644 --- a/test/StoneyVCV/test.hpp +++ b/test/StoneyVCV/test.hpp @@ -36,8 +36,8 @@ //============================================================================== +#include #include -#include //============================================================================== @@ -80,8 +80,7 @@ struct Spec { name(""), description("Unit test spec base class (internal)"), size( - ::rack::window::mm2px(::StoneyDSP::StoneyVCV::Panels::MIN_WIDTH), - ::rack::window::mm2px(::StoneyDSP::StoneyVCV::Panels::MIN_HEIGHT) + 0.0F, 0.0F ) {}; ~Spec() = default; diff --git a/vcpkg.json b/vcpkg.json index 0f2b81d3..c8e6236d 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -3,6 +3,26 @@ "version": "2.0.2", "license": "MIT", "supports": "(linux & x64)|(osx & x64)|(osx & arm64)|(windows & mingw & x64)", + "default-features": [ + "componentlibrary" + ], + "features": { + "componentlibrary": { + "description": "" + }, + "hp1": { + "description": "" + }, + "hp2": { + "description": "" + }, + "hp4": { + "description": "" + }, + "vca": { + "description": "" + } + }, "dependencies": [ { "name": "catch2",