gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

commit f27eeca5baff2dff2199f4398923a222a31d80eb
parent 2b7b3a4b6b00b8bace96c099d139039436dee12c
Author: dsp56300 <87139854+dsp56300@users.noreply.github.com>
Date:   Thu, 10 Mar 2022 20:01:35 +0100

Merge pull request #73 from 790/bothui

Both ui
Diffstat:
MCMakeLists.txt | 168++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msource/jucePlugin/CMakeLists.txt | 425++++++++++++++++++++++++++++++++++++++-----------------------------------------
Msource/jucePlugin/PluginEditor.cpp | 54+++++++++++++++++++++++++++++++++++++++++++++++-------
Msource/jucePlugin/PluginEditor.h | 3++-
Msource/jucePlugin/ui2/Ui_Utils.h | 123+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msource/jucePlugin/ui2/VirusEditor.cpp | 961+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/jucePlugin/ui2/VirusEditor.h | 12++++++++----
Msource/jucePlugin/ui2/Virus_Buttons.cpp | 210+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/jucePlugin/ui2/Virus_Buttons.h | 151+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/jucePlugin/ui2/Virus_LookAndFeel.cpp | 156+++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msource/jucePlugin/ui2/Virus_LookAndFeel.h | 275++++++++++++++++++++++++++++++++++++++-----------------------------------------
Msource/jucePlugin/ui2/Virus_Panel1_OscEditor.cpp | 545+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/jucePlugin/ui2/Virus_Panel1_OscEditor.h | 96+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/jucePlugin/ui2/Virus_Panel2_LfoEditor.cpp | 516+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msource/jucePlugin/ui2/Virus_Panel2_LfoEditor.h | 94++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msource/jucePlugin/ui2/Virus_Panel3_FxEditor.cpp | 659++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msource/jucePlugin/ui2/Virus_Panel3_FxEditor.h | 100++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msource/jucePlugin/ui2/Virus_Panel4_ArpEditor.cpp | 755+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/jucePlugin/ui2/Virus_Panel4_ArpEditor.h | 105+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msource/jucePlugin/ui2/Virus_Panel5_PatchBrowser.cpp | 1322++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msource/jucePlugin/ui2/Virus_Panel5_PatchBrowser.h | 308+++++++++++++++++++++++++++++++++++++++++--------------------------------------
21 files changed, 3623 insertions(+), 3415 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -1,84 +1,84 @@ -cmake_minimum_required(VERSION 3.15) - -# build a fat binary that runs on both intel and the new Apple M1 chip -set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "OS X Architectures") - -set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version") - -project(gearmulator VERSION 1.2.11) - -include(base.cmake) - -set(ASMJIT_STATIC TRUE) - -option(${PROJECT_NAME}_BUILD_JUCEPLUGIN "Build Juce plugin" on) - -add_subdirectory(source/dsp56300/source) -add_subdirectory(source/synthLib) -add_subdirectory(source/virusLib) -add_subdirectory(source/libresample) - -if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/source/vstsdk2.4.2/public.sdk/source/vst2.x/audioeffect.h) - set(JUCE_GLOBAL_VST2_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/source/vstsdk2.4.2/) -endif() - -# ----------------- Juce based audio plugin - -set_property(GLOBAL PROPERTY USE_FOLDERS YES) -if(${PROJECT_NAME}_BUILD_JUCEPLUGIN) - set(JUCE_ENABLE_MODULE_SOURCE_GROUPS ON CACHE BOOL "" FORCE) - add_subdirectory(source/JUCE) - add_subdirectory(source/jucePlugin) -endif() - -# ----------------- Test Console - -add_executable(virusTestConsole) -target_sources(virusTestConsole PRIVATE source/virusTestConsole/virusTestConsole.cpp) -target_link_libraries(virusTestConsole PUBLIC virusLib) - -if(UNIX AND NOT APPLE) - target_link_libraries(virusTestConsole PUBLIC -static-libgcc -static-libstdc++) -endif() - -install(TARGETS virusTestConsole DESTINATION . COMPONENT testConsole) - -if(MSVC) - install(DIRECTORY deploy/win/ DESTINATION . COMPONENT testConsole) -else() - install(DIRECTORY deploy/linux/ DESTINATION . COMPONENT testConsole) -endif() - -# ----------------- CPack - -get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS) -list(REMOVE_ITEM CPACK_COMPONENTS_ALL "Unspecified") - -message("CMAKE_SYSTEM_NAME: " ${CMAKE_SYSTEM_NAME}) -message("CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR}) - -if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") - set(CPACK_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}_${CMAKE_SYSTEM_PROCESSOR}) -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") - set(CPACK_SYSTEM_NAME "MacOS") -endif() - -set(CPACK_COMPONENTS_GROUPING IGNORE) -set(CPACK_ARCHIVE_COMPONENT_INSTALL ON) - -set(CPACK_PACKAGE_CONTACT "The Usual Suspects") -set(CPACK_PACKAGE_VENDOR "The Usual Suspects") -set(CPACK_PACKAGE_NAME "DSP56300Emu") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "DSP 56300 family emulator audio plugin") - -set(CPACK_DEB_COMPONENT_INSTALL ON) -set(CPACK_DEBIAN_PACKAGE_MAINTAINER "The Usual Suspects") -set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://dsp56300.wordpress.com") -set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) - -set(CPACK_RPM_COMPONENT_INSTALL ON) -set(CPACK_RPM_PACKAGE_AUTOREQ "yes") -set(CPACK_RPM_PACKAGE_URL ${CPACK_DEBIAN_PACKAGE_HOMEPAGE}) -set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}) - -include(CPack) +cmake_minimum_required(VERSION 3.15) + +# build a fat binary that runs on both intel and the new Apple M1 chip +set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "OS X Architectures") + +set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version") + +project(gearmulator VERSION 1.2.11) + +include(base.cmake) + +set(ASMJIT_STATIC TRUE) + +option(${PROJECT_NAME}_BUILD_JUCEPLUGIN "Build Juce plugin" on) + +add_subdirectory(source/dsp56300/source) +add_subdirectory(source/synthLib) +add_subdirectory(source/virusLib) +add_subdirectory(source/libresample) + +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/source/vstsdk2.4.2/public.sdk/source/vst2.x/audioeffect.h) + set(JUCE_GLOBAL_VST2_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/source/vstsdk2.4.2/) +endif() + +# ----------------- Juce based audio plugin + +set_property(GLOBAL PROPERTY USE_FOLDERS YES) +if(${PROJECT_NAME}_BUILD_JUCEPLUGIN) + set(JUCE_ENABLE_MODULE_SOURCE_GROUPS ON CACHE BOOL "" FORCE) + add_subdirectory(source/JUCE) + add_subdirectory(source/jucePlugin) +endif() + +# ----------------- Test Console + +add_executable(virusTestConsole) +target_sources(virusTestConsole PRIVATE source/virusTestConsole/virusTestConsole.cpp) +target_link_libraries(virusTestConsole PUBLIC virusLib) + +if(UNIX AND NOT APPLE) + target_link_libraries(virusTestConsole PUBLIC -static-libgcc -static-libstdc++) +endif() + +install(TARGETS virusTestConsole DESTINATION . COMPONENT testConsole) + +if(MSVC) + install(DIRECTORY deploy/win/ DESTINATION . COMPONENT testConsole) +else() + install(DIRECTORY deploy/linux/ DESTINATION . COMPONENT testConsole) +endif() + +# ----------------- CPack + +get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS) +list(REMOVE_ITEM CPACK_COMPONENTS_ALL "Unspecified") + +message("CMAKE_SYSTEM_NAME: " ${CMAKE_SYSTEM_NAME}) +message("CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR}) + +if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + set(CPACK_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}_${CMAKE_SYSTEM_PROCESSOR}) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + set(CPACK_SYSTEM_NAME "MacOS") +endif() + +set(CPACK_COMPONENTS_GROUPING IGNORE) +set(CPACK_ARCHIVE_COMPONENT_INSTALL ON) + +set(CPACK_PACKAGE_CONTACT "The Usual Suspects") +set(CPACK_PACKAGE_VENDOR "The Usual Suspects") +set(CPACK_PACKAGE_NAME "DSP56300Emu") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "DSP 56300 family emulator audio plugin") + +set(CPACK_DEB_COMPONENT_INSTALL ON) +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "The Usual Suspects") +set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://dsp56300.wordpress.com") +set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + +set(CPACK_RPM_COMPONENT_INSTALL ON) +set(CPACK_RPM_PACKAGE_AUTOREQ "yes") +set(CPACK_RPM_PACKAGE_URL ${CPACK_DEBIAN_PACKAGE_HOMEPAGE}) +set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}) + +include(CPack) diff --git a/source/jucePlugin/CMakeLists.txt b/source/jucePlugin/CMakeLists.txt @@ -1,220 +1,205 @@ - -cmake_minimum_required(VERSION 3.15) -project(jucePlugin VERSION ${CMAKE_PROJECT_VERSION}) - -option(${CMAKE_PROJECT_NAME}_BUILD_DARK_SKIN "Build plugin with dark skin" off) -option(${CMAKE_PROJECT_NAME}_BUILD_FX_PLUGIN "Build FX plugin variants" off) - -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_SOURCE_DIR}/version.h) - -if(JUCE_GLOBAL_VST2_SDK_PATH) - set(VST "VST") -else() - set(VST "") -endif() - -set(SOURCES - parameterDescriptions_C.json - PluginProcessor.cpp - PluginProcessor.h - VirusController.cpp - VirusController.h - VirusParameter.cpp - VirusParameter.h - VirusParameterBinding.cpp - VirusParameterBinding.h - VirusParameterDescription.cpp - VirusParameterDescription.h - VirusParameterDescriptions.cpp - VirusParameterDescriptions.h - version.h -) - -macro(createJucePlugin targetName productName isSynth plugin4CC sourcesUI binaryDataProject componentName) - - juce_add_plugin(${targetName} - # VERSION ... # Set this if the plugin version is different to the project version - # ICON_BIG ... # ICON_* arguments specify a path to an image file to use as an icon for the Standalone - # ICON_SMALL ... - COMPANY_NAME "The Usual Suspects" # Specify the name of the plugin's author - IS_SYNTH ${isSynth} # Is this a synth or an effect? - NEEDS_MIDI_INPUT TRUE # Does the plugin need midi input? - NEEDS_MIDI_OUTPUT TRUE # Does the plugin need midi output? - IS_MIDI_EFFECT FALSE # Is this plugin a MIDI effect? - EDITOR_WANTS_KEYBOARD_FOCUS TRUE # Does the editor need keyboard focus? - COPY_PLUGIN_AFTER_BUILD FALSE # Should the plugin be installed to a default location after building? - PLUGIN_MANUFACTURER_CODE TusP # A four-character manufacturer id with at least one upper-case character - PLUGIN_CODE ${plugin4CC} # A unique four-character plugin id with exactly one upper-case character - # GarageBand 10.3 requires the first letter to be upper-case, and the remaining letters to be lower-case - FORMATS AU VST3 ${VST} Standalone # The formats to build. Other valid formats are: AAX Unity VST AU AUv3 - PRODUCT_NAME ${productName} # The name of the final executable, which can differ from the target name - ) - - target_sources(${targetName} PRIVATE ${SOURCES} ${sourcesUI}) - - target_compile_definitions(${targetName} - PUBLIC - # JUCE_WEB_BROWSER and JUCE_USE_CURL would be on by default, but you might not need them. - JUCE_WEB_BROWSER=0 # If you remove this, add `NEEDS_WEB_BROWSER TRUE` to the `juce_add_plugin` call - JUCE_USE_CURL=0 # If you remove this, add `NEEDS_CURL TRUE` to the `juce_add_plugin` call - JUCE_VST3_CAN_REPLACE_VST2=0 - JUCE_WIN_PER_MONITOR_DPI_AWARE=0 - ) - - target_link_libraries(${targetName} - PRIVATE - ${binaryDataProject} - juce::juce_audio_utils - juce::juce_cryptography - PUBLIC - virusLib - #juce::juce_recommended_config_flags - #juce::juce_recommended_lto_flags - #juce::juce_recommended_warning_flags - ) - - if(UNIX AND NOT APPLE) - target_link_libraries(${targetName} PUBLIC -static-libgcc -static-libstdc++) - endif() - - if(MSVC OR APPLE) - if(JUCE_GLOBAL_VST2_SDK_PATH) - install(TARGETS ${targetName}_VST DESTINATION . COMPONENT VST2${componentName}) - endif() - install(TARGETS ${targetName}_VST3 DESTINATION . COMPONENT VST3${componentName}) - if(APPLE) - install(TARGETS ${targetName}_AU DESTINATION . COMPONENT AU${componentName}) - endif() - elseif(UNIX) - if(JUCE_GLOBAL_VST2_SDK_PATH) - install(TARGETS ${targetName}_VST LIBRARY DESTINATION /usr/local/lib/lxvst/ COMPONENT VST2${componentName}) - endif() - install(TARGETS ${targetName}_VST3 LIBRARY DESTINATION /usr/local/lib/vst3/ COMPONENT VST3${componentName}) - endif() -endmacro() - -macro(createJucePlugins postfix sourcesUI assets) - juce_add_binary_data(jucePlugin_BinaryData${postfix} SOURCES ${assets}) - - createJucePlugin(jucePlugin${postfix} "DSP56300Emu" TRUE "TusV" "${sourcesUI}" jucePlugin_BinaryData${postfix} "${postfix}") - - if(${CMAKE_PROJECT_NAME}_BUILD_FX_PLUGIN) - createJucePlugin(jucePlugin${postfix}_FX "DSP56300EmuFX" FALSE "TusF" "${sourcesUI}" jucePlugin_BinaryData${postfix} "${postfix}_FX") - endif() -endmacro() - -# SKIN 1 --------------------------------------------------------------------------------------------------------------------------------------- - -set(SOURCES_UI - PluginEditor.cpp - PluginEditor.h - ui/Virus_Buttons.cpp - ui/Virus_LookAndFeel.cpp - ui/VirusEditor.cpp - ui/Virus_ArpEditor.cpp - ui/Virus_FxEditor.cpp - ui/Virus_LfoEditor.cpp - ui/Virus_OscEditor.cpp - ui/Virus_PatchBrowser.cpp - ui/Virus_Parts.cpp - ui/Virus_Buttons.h - ui/Virus_LookAndFeel.h - ui/VirusEditor.h - ui/Virus_ArpEditor.h - ui/Virus_FxEditor.h - ui/Virus_LfoEditor.h - ui/Virus_OscEditor.h - ui/Virus_PatchBrowser.h - ui/Virus_Parts.h - ui/Ui_Utils.h -) - -set(ASSETS - "assets/bg_1377x800.png" - "assets/panels/bg_arp_1018x620.png" - "assets/panels/bg_fx_1018x620.png" - "assets/panels/bg_lfo_1018x620.png" - "assets/panels/bg_osc_1018x620.png" - "assets/panels/bg_fxreverb_481x234.png" - "assets/panels/bg_fxdelay_481x234.png" - "assets/buttons/GLOBAL_btn_arp_settings_141x26.png" - "assets/buttons/GLOBAL_btn_effects_141x26.png" - "assets/buttons/GLOBAL_btn_lfo_matrix_141x26.png" - "assets/buttons/GLOBAL_btn_osc_filter_141x26.png" - "assets/buttons/GLOBAL_btn_patch_browser_141x26.png" - "assets/buttons/env_pol_50x34.png" - "assets/buttons/lfo_btn_23_19.png" - "assets/buttons/link_vert_12x36.png" - "assets/buttons/link_horizon_36x12.png" - "assets/buttons/presets_btn_43_15.png" - "assets/buttons/Handle_18x47.png" - "assets/buttons/sync2_54x25.png" - "assets/buttons/part_select_btn_36x36.png" - "assets/buttons/arphold_btn_36x36.png" - "assets/knobs/Gen_70x70_100.png" - "assets/knobs/Gen_pol_70x70_100.png" - "assets/knobs/GenBlue_70x70_100.png" - "assets/knobs/GenRed_70x70_100.png" - "assets/knobs/multi_18x18_100.png" - "parameterDescriptions_C.json" -) - -createJucePlugins("" "${SOURCES_UI}" "${ASSETS}") - -# SKIN 2 --------------------------------------------------------------------------------------------------------------------------------------- - -set(DARK_SOURCES_UI - PluginEditorSkin2.cpp - PluginEditorSkin2.h - ui2/Virus_Buttons.cpp - ui2/Virus_LookAndFeel.cpp - ui2/VirusEditor.cpp - ui2/Virus_Panel4_ArpEditor.cpp - ui2/Virus_Panel3_FxEditor.cpp - ui2/Virus_Panel2_LfoEditor.cpp - ui2/Virus_Panel1_OscEditor.cpp - ui2/Virus_Panel5_PatchBrowser.cpp - ui2/Virus_Buttons.h - ui2/Virus_LookAndFeel.h - ui2/VirusEditor.h - ui2/Virus_Panel4_ArpEditor.h - ui2/Virus_Panel3_FxEditor.h - ui2/Virus_Panel2_LfoEditor.h - ui2/Virus_Panel1_OscEditor.h - ui2/Virus_Panel5_PatchBrowser.h - ui2/Ui_Utils.h -) - -set(DARK_ASSETS - "assets2/main_background.png" - "assets2/panels/panel_1.png" - "assets2/panels/panel_2.png" - "assets2/panels/panel_3.png" - "assets2/panels/panel_4.png" - "assets2/panels/panel_5.png" - "assets2/buttons/btn_main_1.png" - "assets2/buttons/btn_main_2.png" - "assets2/buttons/btn_main_3.png" - "assets2/buttons/btn_main_4.png" - "assets2/buttons/btn_main_5.png" - "assets2/buttons/btn_1.png" - "assets2/buttons/btn_2.png" - "assets2/buttons/btn_3.png" - "assets2/buttons/btn_4.png" - "assets2/buttons/btn_left.png" - "assets2/buttons/btn_right.png" - "assets2/buttons/btn_down.png" - "assets2/buttons/btn_menu.png" - "assets2/buttons/btn_load_bank.png" - "assets2/buttons/btn_save_preset.png" - "assets2/combobox/cmb_1.png" - "assets2/combobox/cmb_2.png" - "assets2/knobs/knob_1_128.png" - "assets2/knobs/knob_2_128.png" - "assets2/font/Digital" - "parameterDescriptions_C.json" -) - -if(${CMAKE_PROJECT_NAME}_BUILD_DARK_SKIN) - createJucePlugins("_Dark" "${DARK_SOURCES_UI}" "${DARK_ASSETS}") -endif() + +cmake_minimum_required(VERSION 3.15) +project(jucePlugin VERSION ${CMAKE_PROJECT_VERSION}) + +option(${CMAKE_PROJECT_NAME}_BUILD_FX_PLUGIN "Build FX plugin variants" off) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_SOURCE_DIR}/version.h) + +if(JUCE_GLOBAL_VST2_SDK_PATH) + set(VST "VST") +else() + set(VST "") +endif() + +set(SOURCES + parameterDescriptions_C.json + PluginProcessor.cpp + PluginProcessor.h + VirusController.cpp + VirusController.h + VirusParameter.cpp + VirusParameter.h + VirusParameterBinding.cpp + VirusParameterBinding.h + VirusParameterDescription.cpp + VirusParameterDescription.h + VirusParameterDescriptions.cpp + VirusParameterDescriptions.h + version.h +) + +macro(createJucePlugin targetName productName isSynth plugin4CC sourcesUI binaryDataProject componentName) + + juce_add_plugin(${targetName} + # VERSION ... # Set this if the plugin version is different to the project version + # ICON_BIG ... # ICON_* arguments specify a path to an image file to use as an icon for the Standalone + # ICON_SMALL ... + COMPANY_NAME "The Usual Suspects" # Specify the name of the plugin's author + IS_SYNTH ${isSynth} # Is this a synth or an effect? + NEEDS_MIDI_INPUT TRUE # Does the plugin need midi input? + NEEDS_MIDI_OUTPUT TRUE # Does the plugin need midi output? + IS_MIDI_EFFECT FALSE # Is this plugin a MIDI effect? + EDITOR_WANTS_KEYBOARD_FOCUS TRUE # Does the editor need keyboard focus? + COPY_PLUGIN_AFTER_BUILD FALSE # Should the plugin be installed to a default location after building? + PLUGIN_MANUFACTURER_CODE TusP # A four-character manufacturer id with at least one upper-case character + PLUGIN_CODE ${plugin4CC} # A unique four-character plugin id with exactly one upper-case character + # GarageBand 10.3 requires the first letter to be upper-case, and the remaining letters to be lower-case + FORMATS AU VST3 ${VST} Standalone # The formats to build. Other valid formats are: AAX Unity VST AU AUv3 + PRODUCT_NAME ${productName} # The name of the final executable, which can differ from the target name + ) + + target_sources(${targetName} PRIVATE ${SOURCES} ${sourcesUI}) + + target_compile_definitions(${targetName} + PUBLIC + # JUCE_WEB_BROWSER and JUCE_USE_CURL would be on by default, but you might not need them. + JUCE_WEB_BROWSER=0 # If you remove this, add `NEEDS_WEB_BROWSER TRUE` to the `juce_add_plugin` call + JUCE_USE_CURL=0 # If you remove this, add `NEEDS_CURL TRUE` to the `juce_add_plugin` call + JUCE_VST3_CAN_REPLACE_VST2=0 + JUCE_WIN_PER_MONITOR_DPI_AWARE=0 + ) + + target_link_libraries(${targetName} + PRIVATE + ${binaryDataProject} + juce::juce_audio_utils + juce::juce_cryptography + PUBLIC + virusLib + #juce::juce_recommended_config_flags + #juce::juce_recommended_lto_flags + #juce::juce_recommended_warning_flags + ) + + if(UNIX AND NOT APPLE) + target_link_libraries(${targetName} PUBLIC -static-libgcc -static-libstdc++) + endif() + + if(MSVC OR APPLE) + if(JUCE_GLOBAL_VST2_SDK_PATH) + install(TARGETS ${targetName}_VST DESTINATION . COMPONENT VST2${componentName}) + endif() + install(TARGETS ${targetName}_VST3 DESTINATION . COMPONENT VST3${componentName}) + if(APPLE) + install(TARGETS ${targetName}_AU DESTINATION . COMPONENT AU${componentName}) + endif() + elseif(UNIX) + if(JUCE_GLOBAL_VST2_SDK_PATH) + install(TARGETS ${targetName}_VST LIBRARY DESTINATION /usr/local/lib/lxvst/ COMPONENT VST2${componentName}) + endif() + install(TARGETS ${targetName}_VST3 LIBRARY DESTINATION /usr/local/lib/vst3/ COMPONENT VST3${componentName}) + endif() +endmacro() + +macro(createJucePlugins postfix sourcesUI assets) + juce_add_binary_data(jucePlugin_BinaryData${postfix} SOURCES ${assets}) + + createJucePlugin(jucePlugin${postfix} "DSP56300Emu" TRUE "TusV" "${sourcesUI}" jucePlugin_BinaryData${postfix} "${postfix}") + + if(${CMAKE_PROJECT_NAME}_BUILD_FX_PLUGIN) + createJucePlugin(jucePlugin${postfix}_FX "DSP56300EmuFX" FALSE "TusF" "${sourcesUI}" jucePlugin_BinaryData${postfix} "${postfix}_FX") + endif() +endmacro() + +set(SOURCES_UI + PluginEditor.cpp + PluginEditor.h + ui/Virus_Buttons.cpp + ui/Virus_LookAndFeel.cpp + ui/VirusEditor.cpp + ui/Virus_ArpEditor.cpp + ui/Virus_FxEditor.cpp + ui/Virus_LfoEditor.cpp + ui/Virus_OscEditor.cpp + ui/Virus_PatchBrowser.cpp + ui/Virus_Parts.cpp + ui/Virus_Buttons.h + ui/Virus_LookAndFeel.h + ui/VirusEditor.h + ui/Virus_ArpEditor.h + ui/Virus_FxEditor.h + ui/Virus_LfoEditor.h + ui/Virus_OscEditor.h + ui/Virus_PatchBrowser.h + ui/Virus_Parts.h + ui/Ui_Utils.h + + ui2/Ui_Utils.h + ui2/Virus_Buttons.cpp + ui2/Virus_Buttons.h + ui2/Virus_LookAndFeel.cpp + ui2/Virus_LookAndFeel.h + ui2/Virus_Panel1_OscEditor.cpp + ui2/Virus_Panel1_OscEditor.h + ui2/Virus_Panel2_LfoEditor.cpp + ui2/Virus_Panel2_LfoEditor.h + ui2/Virus_Panel3_FxEditor.cpp + ui2/Virus_Panel3_FxEditor.h + ui2/Virus_Panel4_ArpEditor.cpp + ui2/Virus_Panel4_ArpEditor.h + ui2/Virus_Panel5_PatchBrowser.cpp + ui2/Virus_Panel5_PatchBrowser.h + ui2/VirusEditor.cpp + ui2/VirusEditor.h +) + +# https://forum.juce.com/t/help-needed-using-binarydata-with-cmake-juce-6/40486 +# "This might be because the BinaryData files are generated during the build, so the IDE may not be able to find them until the build has been run once (and even then, some IDEs might need a bit of a nudge to re-index the binary directory…)" +SET(ASSETS + "assets/bg_1377x800.png" + "assets/panels/bg_arp_1018x620.png" + "assets/panels/bg_fx_1018x620.png" + "assets/panels/bg_lfo_1018x620.png" + "assets/panels/bg_osc_1018x620.png" + "assets/panels/bg_fxreverb_481x234.png" + "assets/panels/bg_fxdelay_481x234.png" + "assets/buttons/GLOBAL_btn_arp_settings_141x26.png" + "assets/buttons/GLOBAL_btn_effects_141x26.png" + "assets/buttons/GLOBAL_btn_lfo_matrix_141x26.png" + "assets/buttons/GLOBAL_btn_osc_filter_141x26.png" + "assets/buttons/GLOBAL_btn_patch_browser_141x26.png" + "assets/buttons/env_pol_50x34.png" + "assets/buttons/lfo_btn_23_19.png" + "assets/buttons/link_vert_12x36.png" + "assets/buttons/link_horizon_36x12.png" + "assets/buttons/presets_btn_43_15.png" + "assets/buttons/Handle_18x47.png" + "assets/buttons/sync2_54x25.png" + "assets/buttons/part_select_btn_36x36.png" + "assets/buttons/arphold_btn_36x36.png" + "assets/knobs/Gen_70x70_100.png" + "assets/knobs/Gen_pol_70x70_100.png" + "assets/knobs/GenBlue_70x70_100.png" + "assets/knobs/GenRed_70x70_100.png" + "assets/knobs/multi_18x18_100.png" + "assets2/main_background.png" + "assets2/panels/panel_1.png" + "assets2/panels/panel_2.png" + "assets2/panels/panel_3.png" + "assets2/panels/panel_4.png" + "assets2/panels/panel_5.png" + "assets2/buttons/btn_main_1.png" + "assets2/buttons/btn_main_2.png" + "assets2/buttons/btn_main_3.png" + "assets2/buttons/btn_main_4.png" + "assets2/buttons/btn_main_5.png" + "assets2/buttons/btn_1.png" + "assets2/buttons/btn_2.png" + "assets2/buttons/btn_3.png" + "assets2/buttons/btn_4.png" + "assets2/buttons/btn_left.png" + "assets2/buttons/btn_right.png" + "assets2/buttons/btn_down.png" + "assets2/buttons/btn_menu.png" + "assets2/buttons/btn_load_bank.png" + "assets2/buttons/btn_save_preset.png" + "assets2/combobox/cmb_1.png" + "assets2/combobox/cmb_2.png" + "assets2/knobs/knob_1_128.png" + "assets2/knobs/knob_2_128.png" + "assets2/font/Digital" + "parameterDescriptions_C.json" +) + +createJucePlugins("" "${SOURCES_UI}" "${ASSETS}") diff --git a/source/jucePlugin/PluginEditor.cpp b/source/jucePlugin/PluginEditor.cpp @@ -4,17 +4,18 @@ #include "version.h" #include "ui/VirusEditor.h" - +#include "ui2/VirusEditor.h" //============================================================================== AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor(AudioPluginAudioProcessor &p) : - AudioProcessorEditor(&p), processorRef(p), m_parameterBinding(p), m_virusEditor(new VirusEditor(m_parameterBinding, processorRef)), m_scale("Scale") + AudioProcessorEditor(&p), processorRef(p), m_parameterBinding(p), m_scale("Scale"), m_skin("Skin") { ignoreUnused (processorRef); setSize(1377, 800); const auto config = processorRef.getController().getConfig(); auto scale = config->getIntValue("scale", 100); - m_virusEditor->setTopLeftPosition(0, 0); + int skinId = config->getIntValue("skin", 0); + //m_virusEditor->setTopLeftPosition(0, 0); m_scale.setBounds(0,0,74,24); m_scale.addItem("50%", 50); m_scale.addItem("75%", 75); @@ -22,7 +23,7 @@ AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor(AudioPluginAudi m_scale.addItem("125%", 125); m_scale.addItem("150%", 150); m_scale.addItem("200%", 200); - + m_scale.setSelectedId(scale, juce::dontSendNotification); m_scale.setColour(juce::ComboBox::textColourId, juce::Colours::white); m_scale.onChange = [this, config]() { @@ -32,12 +33,51 @@ AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor(AudioPluginAudi config->saveIfNeeded(); }; setScaleFactor(scale/100.0f); - addAndMakeVisible(m_virusEditor); + + m_skin.setBounds(m_scale.getBounds().getRight() + 4, 0, 74, 24); + m_skin.addItem("Modern", 1); + m_skin.addItem("Classic", 2); + m_skin.setSelectedId(1, juce::dontSendNotification); + m_skin.setColour(juce::ComboBox::textColourId, juce::Colours::white); + m_skin.setSelectedItemIndex(skinId, juce::dontSendNotification); addAndMakeVisible(m_scale); + addAndMakeVisible(m_skin); + m_skin.onChange = [this, config]() { + int skinId = m_skin.getSelectedItemIndex(); + config->setValue("skin", skinId); + config->saveIfNeeded(); + LoadSkin(m_skin.getSelectedItemIndex()); + }; + + LoadSkin(skinId); + //addAndMakeVisible(m_virusEditor); } -AudioPluginAudioProcessorEditor::~AudioPluginAudioProcessorEditor() -{ +void AudioPluginAudioProcessorEditor::LoadSkin(int index) { + if (m_virusEditor != nullptr && getIndexOfChildComponent(m_virusEditor) > -1) + { + removeChildComponent(m_virusEditor); + delete m_virusEditor; + } + + if (index == 1) + { + auto virusEditor = new Trancy::VirusEditor(m_parameterBinding, processorRef); + setSize(virusEditor->iSkinSizeWidth, virusEditor->iSkinSizeHeight); + virusEditor->m_AudioPlugInEditor = (AudioPluginAudioProcessorEditor *)this; + m_virusEditor = (VirusEditor*)virusEditor; + } + else { + m_virusEditor = new VirusEditor(m_parameterBinding, processorRef); + setSize(1377, 800); + } + m_virusEditor->setTopLeftPosition(0, 0); + addAndMakeVisible(m_virusEditor); + m_scale.toFront(0); + m_skin.toFront(0); +} + +AudioPluginAudioProcessorEditor::~AudioPluginAudioProcessorEditor() { delete m_virusEditor; } diff --git a/source/jucePlugin/PluginEditor.h b/source/jucePlugin/PluginEditor.h @@ -18,7 +18,7 @@ public: private: void timerCallback() override; - + void LoadSkin(int index); // This reference is provided as a quick way for your editor to // access the processor object that created it. AudioPluginAudioProcessor& processorRef; @@ -27,6 +27,7 @@ private: // New "real" editor VirusEditor *m_virusEditor; juce::ComboBox m_scale; + juce::ComboBox m_skin; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginAudioProcessorEditor) diff --git a/source/jucePlugin/ui2/Ui_Utils.h b/source/jucePlugin/ui2/Ui_Utils.h @@ -1,67 +1,78 @@ #include "Virus_LookAndFeel.h" #include "../VirusController.h" #include "../../virusLib/microcontrollerTypes.h" - -constexpr auto knobSize = Virus::LookAndFeel::kKnobSize; -constexpr auto knobSizeSmall = Virus::LookAndFeelSmallButton::kKnobSize; - -class Controller; -using namespace virusLib; - -static void setupBackground(juce::Component &parent, std::unique_ptr<juce::Drawable> &bg, const void *data, - const size_t numBytes) +namespace Trancy { - bg = juce::Drawable::createFromImageData(data, numBytes); - parent.addAndMakeVisible(bg.get()); - bg->setBounds(bg->getDrawableBounds().toNearestIntEdges()); -} + using namespace VirusUI; + constexpr auto knobSize = LookAndFeel::kKnobSize; + constexpr auto knobSizeSmall = LookAndFeelSmallButton::kKnobSize; -static void setupRotary(juce::Component &parent, juce::Slider &slider) -{ - slider.setSliderStyle(juce::Slider::RotaryHorizontalVerticalDrag); - slider.setTextBoxStyle(juce::Slider::NoTextBox, false, 0, 0); - parent.addAndMakeVisible(slider); -} + class Controller; + using namespace virusLib; + static void setupBackground(juce::Component &parent, std::unique_ptr<juce::Drawable> &bg, const void *data, + const size_t numBytes) + { + bg = juce::Drawable::createFromImageData(data, numBytes); + parent.addAndMakeVisible(bg.get()); + bg->setBounds(bg->getDrawableBounds().toNearestIntEdges()); + } -static juce::String getCurrentPartBankStr(virusLib::BankNumber currentBank) -{ - switch (currentBank) + static void setupRotary(juce::Component &parent, juce::Slider &slider) { - case virusLib::BankNumber::A: return "A"; - case virusLib::BankNumber::B: return "B"; - case virusLib::BankNumber::C: return "C"; - case virusLib::BankNumber::D: return "D"; - case virusLib::BankNumber::E: return "E"; - case virusLib::BankNumber::F: return "F"; - case virusLib::BankNumber::G: return "G"; - case virusLib::BankNumber::H: return "H"; - case virusLib::BankNumber::EditBuffer: return "EB"; + slider.setSliderStyle(juce::Slider::RotaryHorizontalVerticalDrag); + slider.setTextBoxStyle(juce::Slider::NoTextBox, false, 0, 0); + parent.addAndMakeVisible(slider); } - return "ERR"; -} -static VirusModel guessVersion(uint8_t *data) -{ - if (data[51] > 3) - { - // check extra filter modes - return VirusModel::C; - } - if(data[179] == 0x40 && data[180] == 0x40) // soft knobs don't exist on B so they have fixed value - { - return VirusModel::B; - } - /*if (data[232] != 0x03 || data[235] != 0x6c || data[238] != 0x01) { // extra mod slots - return VirusModel::C; - }*/ - /*if(data[173] != 0x00 || data[174] != 0x00) // EQ - return VirusModel::C;*/ - /*if (data[220] != 0x40 || data[221] != 0x54 || data[222] != 0x20 || data[223] != 0x40 || data[224] != 0x40) { - // eq controls - return VirusModel::C; - }*/ - //return VirusModel::C; + static juce::String getCurrentPartBankStr(virusLib::BankNumber currentBank) + { + switch (currentBank) + { + case virusLib::BankNumber::A: + return "A"; + case virusLib::BankNumber::B: + return "B"; + case virusLib::BankNumber::C: + return "C"; + case virusLib::BankNumber::D: + return "D"; + case virusLib::BankNumber::E: + return "E"; + case virusLib::BankNumber::F: + return "F"; + case virusLib::BankNumber::G: + return "G"; + case virusLib::BankNumber::H: + return "H"; + case virusLib::BankNumber::EditBuffer: + return "EB"; + } + + return "ERR"; + } -} -\ No newline at end of file + static VirusModel guessVersion(uint8_t *data) + { + if (data[51] > 3) + { + // check extra filter modes + return VirusModel::C; + } + if (data[179] == 0x40 && data[180] == 0x40) // soft knobs don't exist on B so they have fixed value + { + return VirusModel::B; + } + /*if (data[232] != 0x03 || data[235] != 0x6c || data[238] != 0x01) { // extra mod slots + return VirusModel::C; + }*/ + /*if(data[173] != 0x00 || data[174] != 0x00) // EQ + return VirusModel::C;*/ + /*if (data[220] != 0x40 || data[221] != 0x54 || data[222] != 0x20 || data[223] != 0x40 || data[224] != 0x40) { + // eq controls + return VirusModel::C; + }*/ + // return VirusModel::C; + } +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/VirusEditor.cpp b/source/jucePlugin/ui2/VirusEditor.cpp @@ -9,483 +9,507 @@ #include "../VirusParameterBinding.h" #include "../VirusController.h" #include "Ui_Utils.h" - -using namespace juce; - -enum Tabs -{ - ArpSettings, - Effects, - LfoMatrix, - OscFilter, - Patches -}; -static uint8_t currentTab = Tabs::OscFilter; - -VirusEditor::VirusEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef) : - m_parameterBinding(_parameterBinding), processorRef(_processorRef), m_controller(_processorRef.getController()) ,m_controlLabel("ctrlLabel", ""), m_properties(_processorRef.getController().getConfig()) -{ - setLookAndFeel(&m_lookAndFeel); - - m_background = Drawable::createFromImageData(BinaryData::main_background_png, BinaryData::main_background_pngSize); - m_background->setBufferedToImage (true); - - addAndMakeVisible (*m_background); - addAndMakeVisible (m_mainButtons); - - m_arpEditor = std::make_unique<ArpEditor>(_parameterBinding, processorRef); - m_fxEditor = std::make_unique<FxEditor>(_parameterBinding, processorRef); - m_lfoEditor = std::make_unique<LfoEditor>(_parameterBinding); - m_oscEditor = std::make_unique<OscEditor>(_parameterBinding); - m_patchBrowser = std::make_unique<PatchBrowser>(_parameterBinding, processorRef); - - applyToSections([this](Component *s) { addChildComponent(s); }); - - //Init Keyboard - setWantsKeyboardFocus(true); - addKeyListener(this); - - // show/hide section from buttons.. - m_mainButtons.updateSection = [this]() { - if (m_mainButtons.m_arpSettings.getToggleState()) { - currentTab = Tabs::ArpSettings; - } - else if (m_mainButtons.m_effects.getToggleState()) { - currentTab = Tabs::Effects; - } - else if (m_mainButtons.m_lfoMatrix.getToggleState()) { - currentTab = Tabs::LfoMatrix; - } - else if (m_mainButtons.m_oscFilter.getToggleState()) { - currentTab = Tabs::OscFilter; - } - else if (m_mainButtons.m_patches.getToggleState()) { - currentTab = Tabs::Patches; - } - m_arpEditor->setVisible(m_mainButtons.m_arpSettings.getToggleState()); - m_fxEditor->setVisible(m_mainButtons.m_effects.getToggleState()); - m_lfoEditor->setVisible(m_mainButtons.m_lfoMatrix.getToggleState()); - m_oscEditor->setVisible(m_mainButtons.m_oscFilter.getToggleState()); - m_patchBrowser->setVisible(m_mainButtons.m_patches.getToggleState()); - }; - - uint8_t index = 0; - applyToSections([this, index](Component *s) mutable - { - if (currentTab == index) - { - s->setVisible(true); - } - index++; - }); - - index = 0; - m_mainButtons.applyToMainButtons([this, &index](DrawableButton *s) mutable - { - if (currentTab == index) - { - s->setToggleState(true, dontSendNotification); - } - index++; - }); - - //Draw Main Menu - ShowMainMenue(); - - //MainDisplay (Patchname) - m_patchName.setBounds(1473, 35, 480, 58); - m_patchName.setJustificationType(Justification::left); - m_patchName.setFont(Font("Register", "Normal", 30.f)); - m_patchName.setEditable(false, true, true); - addAndMakeVisible(m_patchName); - - //MainDisplay - m_controlLabel.setBounds(1473, 35, 650, 58); - m_controlLabel.setFont(Font("Register", "Normal", 30.f)); - addAndMakeVisible(m_controlLabel); - - //ToolTip - //m_ToolTip.setLookAndFeel(&m_landfToolTip); - m_ToolTip.setBounds(200, 50, 200, 200); - m_ToolTip.setFont(Font("Register", "Normal", 15.f)); - m_ToolTip.setColour(Label::ColourIds::backgroundColourId, Colours::black); - m_ToolTip.setColour(Label::ColourIds::textColourId, Colours::white); - m_ToolTip.setJustificationType(Justification::centred); - m_ToolTip.setAlpha(0.90); - addAndMakeVisible(m_ToolTip); - m_ToolTip.setVisible(false); - - //MainDisplay Value - m_controlLabelValue.setBounds(1900, 35, 197, 58); - m_controlLabelValue.setJustificationType(Justification::centredRight); - //m_controlLabelValue.setColour(Label::textColourId, Colours::red); - m_controlLabelValue.setFont(Font("Register", "Normal", 30.f)); - addAndMakeVisible(m_controlLabelValue); - - //PresetsSwitch - addAndMakeVisible(m_PresetLeft); - addAndMakeVisible(m_PresetRight); - m_PresetLeft.setBounds(2166 - m_PresetLeft.kWidth / 2, 62 - m_PresetLeft.kHeight / 2, m_PresetLeft.kWidth, m_PresetLeft.kHeight); - m_PresetRight.setBounds(2199 - m_PresetRight.kWidth / 2, 62 - m_PresetRight.kHeight / 2, m_PresetRight.kWidth, m_PresetRight.kHeight); - - m_PresetLeft.onClick = [this]() { - - postCommandMessage(VirusEditor::Commands::PrevPatch); - postCommandMessage(VirusEditor::Commands::UpdateParts); - }; - m_PresetRight.onClick = [this]() - { - postCommandMessage(VirusEditor::Commands::NextPatch); - postCommandMessage(VirusEditor::Commands::UpdateParts); - }; - - //Show Version - m_version.setText(std::string(g_pluginVersionString), NotificationType::dontSendNotification); - m_version.setBounds(250, 1123, 50, 17); - m_version.setColour(Label::textColourId, Colours::silver); - m_version.setFont(Font("Arial", "Bold", 20.f)); - m_version.setJustificationType(Justification::left); - m_version.setJustificationType(Justification::centred); - addAndMakeVisible(m_version); - - //Show Synth Model - m_SynthModel.setText(m_controller.getVirusModel() == virusLib::VirusModel::B ? "B" : "C", NotificationType::dontSendNotification); - m_SynthModel.setBounds(430, 1123, 50, 17); - m_SynthModel.setFont(Font("Arial", "Bold", 20.f)); - m_SynthModel.setJustificationType(Justification::left); - m_SynthModel.setColour(Label::textColourId, Colours::silver); - m_SynthModel.setJustificationType(Justification::centred); - addAndMakeVisible(m_SynthModel); - - //Show RomName - m_RomName.setText(_processorRef.getRomName()+".bin", NotificationType::dontSendNotification); - m_RomName.setBounds(642, 1123, 150, 17); - m_RomName.setColour(Label::textColourId, Colours::silver); - m_RomName.setFont(Font("Arial", "Bold", 20.f)); - m_RomName.setJustificationType(Justification::left); - m_RomName.setJustificationType(Justification::centred); - addAndMakeVisible(m_RomName); - - //Hyperlink - m_hyperLink.setBounds(900, 1115, 400, 35); - m_hyperLink.setColour(Label::textColourId, Colours::silver); - m_hyperLink.setFont(Font("Arial", "Bold", 20.f), true, dontSendNotification); - m_hyperLink.setJustificationType(Justification::left); - m_hyperLink.setJustificationType(Justification::centred); - addAndMakeVisible(m_hyperLink); - - - m_controller.onProgramChange = [this]() - { - updateParts(); - m_arpEditor->refreshParts(); - }; - m_controller.onMsgDone = [this]() - { - m_controller.onMsgDone = nullptr; - postCommandMessage(VirusEditor::Commands::InitPatches); - postCommandMessage(VirusEditor::Commands::SelectFirstPatch); - postCommandMessage(VirusEditor::Commands::UpdateParts); - }; - - m_controller.getBankCount(); - addMouseListener(this, true); - setSize (kPanelWidth, kPanelHeight); -} - -VirusEditor::~VirusEditor() -{ - m_controller.onProgramChange = nullptr; - m_mainMenu.onClick = nullptr; - selectorMenu.setLookAndFeel(nullptr); - SubSkinSizeSelector.setLookAndFeel(nullptr); - m_mainMenu.setLookAndFeel (nullptr); - selector.setLookAndFeel (nullptr); - setLookAndFeel(nullptr); -} - -bool VirusEditor::keyPressed(const KeyPress &k, Component *c) -{ - if( k.getKeyCode() == 65573) - { - postCommandMessage(VirusEditor::Commands::PrevPatch); - } - if( k.getKeyCode() == 65575) - { - postCommandMessage(VirusEditor::Commands::NextPatch); - } - //43 + - //45 - - return true; -} - -void VirusEditor::updateParts() -{ - const auto multiMode = m_controller.isMultiMode(); - for (auto pt = 0; pt < 16; pt++) - { - bool singlePartOrInMulti = pt == 0 || multiMode; - if (pt == m_controller.getCurrentPart()) - { - if (m_patchBrowser->GetIsFileMode()) - { - m_patchName.setText("["+String(m_controller.getCurrentPart()+1) - +"][FILE] " - + String(m_patchBrowser->GetTablePatchList()->getSelectedRow(0)+1)+": " + m_patchBrowser->GetLastPatchSelected(), dontSendNotification); - } - else - { - const auto patchName = m_controller.getCurrentPartPresetName(pt); - if(m_patchName.getText() != patchName) - { - String sZero; - m_patchName.setText("["+String(m_controller.getCurrentPart()+1) - +"][" + m_patchBrowser->GetSelectBankNum() + "] " - + String(processorRef.getController().getCurrentPartProgram(m_controller.getCurrentPart())+1)+": " + patchName, dontSendNotification); - } - } - } - } -} - - -void VirusEditor::ShowMainMenue() +class VirusParameterBinding; +namespace Trancy { - m_mainMenu.setLookAndFeel (&m_landfButtons); - - m_mainMenu.onClick = [this]() - { - selectorMenu.setLookAndFeel(&m_landfButtons); - selectorMenu.clear(); - SubSkinSizeSelector.setLookAndFeel(&m_landfButtons); - SubSkinSizeSelector.clear(); - - for (float d = 375; d < 1250; d = d + 125) - { - SubSkinSizeSelector.addItem(std::to_string(200 * int(d) / 1000) + "%", [this, d] - { - double dScaleFactor = float(d / 1000.0); - m_AudioPlugInEditor->setScaleFactor(dScaleFactor); - (*this).setSize(iSkinSizeWidth, iSkinSizeHeight); - m_properties->setValue("skin_scale_factor", String(dScaleFactor)); - m_properties->save(); - }); - } - - selectorMenu.addSubMenu("Skin size", SubSkinSizeSelector, true); - selectorMenu.addItem("About", [this]() { AboutWindow(); }); - selectorMenu.showMenu(PopupMenu::Options()); + using namespace juce; + + enum Tabs + { + ArpSettings, + Effects, + LfoMatrix, + OscFilter, + Patches }; + static uint8_t currentTab = Tabs::OscFilter; - //draw Main Menu Button - m_mainMenu.setBounds(2301 - m_mainMenu.kWidth / 2, 62 - m_mainMenu.kHeight / 2, m_mainMenu.kWidth, m_mainMenu.kHeight); - addAndMakeVisible(m_mainMenu); -} - - -void VirusEditor::applyToSections(std::function<void(Component *)> action) -{ - for (auto *section : {static_cast<Component *>(m_arpEditor.get()), static_cast<Component *>(m_fxEditor.get()), - static_cast<Component *>(m_lfoEditor.get()), static_cast<Component *>(m_oscEditor.get()), - static_cast<Component *>(m_patchBrowser.get())}) - { - action(section); - } -} - -void VirusEditor::MainButtons::applyToMainButtons(std::function<void(DrawableButton *)> action) -{ - for (auto *section : {static_cast<DrawableButton *>(&m_arpSettings), static_cast<DrawableButton *>(&m_effects), - static_cast<DrawableButton *>(&m_lfoMatrix), static_cast<DrawableButton *>(&m_oscFilter), - static_cast<DrawableButton *>(&m_patches)}) - { - action(section); - } -} - - -void VirusEditor::updateControlLabel(Component* eventComponent) -{ - auto props = eventComponent->getProperties(); - if(props.contains("type") && props["type"] == "slider") { - - auto comp = dynamic_cast<Slider*>(eventComponent); - if(comp && comp->isEnabled()) - { - int iValue = (props.contains("bipolar") && props["bipolar"])?roundToInt(comp->getValue())-64:roundToInt(comp->getValue()); - - //ToolTip handle - m_ToolTip.setVisible(true); - m_ToolTip.setText(std::to_string(iValue), dontSendNotification); - //todo --> ugly --> Need to be fixed - m_ToolTip.setBounds(comp->getX()+comp->getWidth()*2-43, comp->getY()+comp->getHeight()*2+83, 70,30); - m_ToolTip.toFront(true); - - //Main display handle - m_controlLabel.setVisible(true); - m_controlLabelValue.setVisible(true); - m_patchName.setVisible(false); - - if(m_paramDisplayLocal) - { - m_controlLabel.setColour(Label::ColourIds::backgroundColourId, Colours::black); - m_controlLabel.setColour(Label::ColourIds::outlineColourId, Colours::white); - } - - m_controlLabel.setText(props["name"].toString(), dontSendNotification); - m_controlLabelValue.setText(String(iValue), dontSendNotification); - } - } - -} -void VirusEditor::mouseDrag(const MouseEvent & event) -{ - updateControlLabel(event.eventComponent); -} - -void VirusEditor::mouseEnter(const MouseEvent& event) -{ - if (event.mouseWasDraggedSinceMouseDown()) { - return; - } - updateControlLabel(event.eventComponent); -} - -void VirusEditor::mouseExit(const MouseEvent& event) -{ - if (event.mouseWasDraggedSinceMouseDown()) { - return; - } - m_controlLabel.setText("", dontSendNotification); - m_controlLabel.setVisible(false); - m_controlLabelValue.setVisible(false); - m_patchName.setVisible(true); - m_ToolTip.setVisible(false); -} - -void VirusEditor::mouseDown(const MouseEvent &event) -{ -} - -void VirusEditor::mouseUp(const MouseEvent & event) -{ - m_controlLabel.setText("", dontSendNotification); - m_controlLabel.setVisible(false); - m_controlLabelValue.setVisible(false); - m_patchName.setVisible(true); - m_ToolTip.setVisible(false); -} -void VirusEditor::mouseWheelMove(const MouseEvent& event, const MouseWheelDetails& wheel) -{ - updateControlLabel(event.eventComponent); -} - - -void VirusEditor::resized() -{ - m_background->setBounds (getLocalBounds()); - - //Position of first main button (osc/filt) - m_mainButtons.setBounds(121, 36, m_mainButtons.getWidth(), m_mainButtons.getHeight()); - - // Panel Positions - applyToSections([this](Component *s) { s->setTopLeftPosition(101, 120); }); -} + VirusEditor::VirusEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef) : + m_parameterBinding(_parameterBinding), processorRef(_processorRef), m_controller(_processorRef.getController()), + m_controlLabel("ctrlLabel", ""), m_properties(_processorRef.getController().getConfig()) + { + setLookAndFeel(&m_lookAndFeel); -void VirusEditor::handleCommandMessage(int commandId) -{ - switch (commandId) { - case Commands::Rebind: recreateControls(); - case Commands::UpdateParts: - { - updateParts(); - m_arpEditor->refreshParts(); - }; break; - case Commands::InitPatches: - { - m_patchBrowser->IntiPatches(); - }; break; - case Commands::PrevPatch: - { - if (m_patchBrowser->GetTablePatchList()->getSelectedRow(0)>0) - { - m_patchBrowser->GetTablePatchList()->selectRow(m_patchBrowser->GetTablePatchList()->getSelectedRow(0)-1,false,false); - } - };break; - case Commands::NextPatch: - { - if (m_patchBrowser->GetTablePatchList()->getSelectedRow(0)<m_patchBrowser->GetTablePatchList()->getNumRows()-1) - { - m_patchBrowser->GetTablePatchList()->selectRow(m_patchBrowser->GetTablePatchList()->getSelectedRow(0)+1,false,false); - } - };break; - case Commands::SelectFirstPatch: - { - m_patchBrowser->GetTablePatchList()->selectRow(0,false,false); - };break; - - default: return; - } -} - -void VirusEditor::recreateControls() -{ - removeChildComponent(m_oscEditor.get()); - removeChildComponent(m_lfoEditor.get()); - removeChildComponent(m_fxEditor.get()); - removeChildComponent(m_arpEditor.get()); - // removeChildComponent(m_patchBrowser.get()); - - m_oscEditor = std::make_unique<OscEditor>(m_parameterBinding); - addChildComponent(m_oscEditor.get()); + m_background = + Drawable::createFromImageData(BinaryData::main_background_png, BinaryData::main_background_pngSize); + m_background->setBufferedToImage(true); - m_lfoEditor = std::make_unique<LfoEditor>(m_parameterBinding); - addChildComponent(m_lfoEditor.get()); + addAndMakeVisible(*m_background); + addAndMakeVisible(m_mainButtons); - m_fxEditor = std::make_unique<FxEditor>(m_parameterBinding, processorRef); - addChildComponent(m_fxEditor.get()); + m_arpEditor = std::make_unique<ArpEditor>(_parameterBinding, processorRef); + m_fxEditor = std::make_unique<FxEditor>(_parameterBinding, processorRef); + m_lfoEditor = std::make_unique<LfoEditor>(_parameterBinding); + m_oscEditor = std::make_unique<OscEditor>(_parameterBinding); + m_patchBrowser = std::make_unique<PatchBrowser>(_parameterBinding, processorRef); - m_arpEditor = std::make_unique<ArpEditor>(m_parameterBinding, processorRef); - addChildComponent(m_arpEditor.get()); + applyToSections([this](Component *s) { addChildComponent(s); }); - //m_patchBrowser = std::make_unique<PatchBrowser>(m_parameterBinding, processorRef); - //addChildComponent(m_patchBrowser.get()); + // Init Keyboard + setWantsKeyboardFocus(true); + addKeyListener(this); - m_mainButtons.updateSection(); - resized(); -} - -VirusEditor::MainButtons::MainButtons() -: m_oscFilter ("OSC|FILTER", DrawableButton::ImageRaw) -, m_lfoMatrix ("LFO|MATRIX", DrawableButton::ImageRaw) -, m_effects ("EFFECTS", DrawableButton::ImageRaw) -, m_arpSettings ("ARP|SETTINGS", DrawableButton::ImageRaw) -, m_patches("PATCHES", DrawableButton::ImageRaw) -{ - constexpr auto numOfMainButtons = 5; - setupButton(0, Drawable::createFromImageData(BinaryData::btn_main_1_png, BinaryData::btn_main_1_pngSize), m_oscFilter); - setupButton(1, Drawable::createFromImageData(BinaryData::btn_main_2_png, BinaryData::btn_main_2_pngSize), m_lfoMatrix); - setupButton(2, Drawable::createFromImageData(BinaryData::btn_main_3_png, BinaryData::btn_main_3_pngSize), m_effects); - setupButton(3, Drawable::createFromImageData(BinaryData::btn_main_4_png, BinaryData::btn_main_4_pngSize), m_arpSettings); - setupButton(4, Drawable::createFromImageData(BinaryData::btn_main_5_png, BinaryData::btn_main_5_pngSize), m_patches); - setSize ((kButtonWidth + kMargin) * numOfMainButtons, kButtonHeight); -} - - -void VirusEditor::MainButtons::valueChanged(Value &) { updateSection(); } - -void VirusEditor::MainButtons::setupButton (int i, std::unique_ptr<Drawable>&& btnImage, DrawableButton& btn) -{ - auto onImage = btnImage->createCopy(); - onImage->setOriginWithOriginalSize({0, -kButtonHeight}); - btn.setClickingTogglesState (true); - btn.setRadioGroupId (kGroupId); - btn.setImages (btnImage.get(), nullptr, nullptr, nullptr, onImage.get()); - btn.setBounds ((i > 1 ? -1 : 0) + i * (kButtonWidth + kMargin)-5, 0, kButtonWidth, kButtonHeight); - btn.getToggleStateValue().addListener(this); - addAndMakeVisible (btn); -} + // show/hide section from buttons.. + m_mainButtons.updateSection = [this]() { + if (m_mainButtons.m_arpSettings.getToggleState()) + { + currentTab = Tabs::ArpSettings; + } + else if (m_mainButtons.m_effects.getToggleState()) + { + currentTab = Tabs::Effects; + } + else if (m_mainButtons.m_lfoMatrix.getToggleState()) + { + currentTab = Tabs::LfoMatrix; + } + else if (m_mainButtons.m_oscFilter.getToggleState()) + { + currentTab = Tabs::OscFilter; + } + else if (m_mainButtons.m_patches.getToggleState()) + { + currentTab = Tabs::Patches; + } + m_arpEditor->setVisible(m_mainButtons.m_arpSettings.getToggleState()); + m_fxEditor->setVisible(m_mainButtons.m_effects.getToggleState()); + m_lfoEditor->setVisible(m_mainButtons.m_lfoMatrix.getToggleState()); + m_oscEditor->setVisible(m_mainButtons.m_oscFilter.getToggleState()); + m_patchBrowser->setVisible(m_mainButtons.m_patches.getToggleState()); + }; + + uint8_t index = 0; + applyToSections([this, index](Component *s) mutable { + if (currentTab == index) + { + s->setVisible(true); + } + index++; + }); + + index = 0; + m_mainButtons.applyToMainButtons([this, &index](DrawableButton *s) mutable { + if (currentTab == index) + { + s->setToggleState(true, dontSendNotification); + } + index++; + }); + + // Draw Main Menu + ShowMainMenue(); + + // MainDisplay (Patchname) + m_patchName.setBounds(1473, 35, 480, 58); + m_patchName.setJustificationType(Justification::left); + m_patchName.setFont(Font("Register", "Normal", 30.f)); + m_patchName.setEditable(false, true, true); + addAndMakeVisible(m_patchName); + + // MainDisplay + m_controlLabel.setBounds(1473, 35, 650, 58); + m_controlLabel.setFont(Font("Register", "Normal", 30.f)); + addAndMakeVisible(m_controlLabel); + + // ToolTip + // m_ToolTip.setLookAndFeel(&m_landfToolTip); + m_ToolTip.setBounds(200, 50, 200, 200); + m_ToolTip.setFont(Font("Register", "Normal", 15.f)); + m_ToolTip.setColour(Label::ColourIds::backgroundColourId, Colours::black); + m_ToolTip.setColour(Label::ColourIds::textColourId, Colours::white); + m_ToolTip.setJustificationType(Justification::centred); + m_ToolTip.setAlpha(0.90); + addAndMakeVisible(m_ToolTip); + m_ToolTip.setVisible(false); + + // MainDisplay Value + m_controlLabelValue.setBounds(1900, 35, 197, 58); + m_controlLabelValue.setJustificationType(Justification::centredRight); + // m_controlLabelValue.setColour(Label::textColourId, Colours::red); + m_controlLabelValue.setFont(Font("Register", "Normal", 30.f)); + addAndMakeVisible(m_controlLabelValue); + + // PresetsSwitch + addAndMakeVisible(m_PresetLeft); + addAndMakeVisible(m_PresetRight); + m_PresetLeft.setBounds(2166 - m_PresetLeft.kWidth / 2, 62 - m_PresetLeft.kHeight / 2, m_PresetLeft.kWidth, + m_PresetLeft.kHeight); + m_PresetRight.setBounds(2199 - m_PresetRight.kWidth / 2, 62 - m_PresetRight.kHeight / 2, m_PresetRight.kWidth, + m_PresetRight.kHeight); + + m_PresetLeft.onClick = [this]() { + postCommandMessage(VirusEditor::Commands::PrevPatch); + postCommandMessage(VirusEditor::Commands::UpdateParts); + }; + m_PresetRight.onClick = [this]() { + postCommandMessage(VirusEditor::Commands::NextPatch); + postCommandMessage(VirusEditor::Commands::UpdateParts); + }; + + // Show Version + m_version.setText(std::string(g_pluginVersionString), NotificationType::dontSendNotification); + m_version.setBounds(250, 1123, 50, 17); + m_version.setColour(Label::textColourId, Colours::silver); + m_version.setFont(Font("Arial", "Bold", 20.f)); + m_version.setJustificationType(Justification::left); + m_version.setJustificationType(Justification::centred); + addAndMakeVisible(m_version); + + // Show Synth Model + m_SynthModel.setText(m_controller.getVirusModel() == virusLib::VirusModel::B ? "B" : "C", + NotificationType::dontSendNotification); + m_SynthModel.setBounds(430, 1123, 50, 17); + m_SynthModel.setFont(Font("Arial", "Bold", 20.f)); + m_SynthModel.setJustificationType(Justification::left); + m_SynthModel.setColour(Label::textColourId, Colours::silver); + m_SynthModel.setJustificationType(Justification::centred); + addAndMakeVisible(m_SynthModel); + + // Show RomName + m_RomName.setText(_processorRef.getRomName() + ".bin", NotificationType::dontSendNotification); + m_RomName.setBounds(642, 1123, 150, 17); + m_RomName.setColour(Label::textColourId, Colours::silver); + m_RomName.setFont(Font("Arial", "Bold", 20.f)); + m_RomName.setJustificationType(Justification::left); + m_RomName.setJustificationType(Justification::centred); + addAndMakeVisible(m_RomName); + + // Hyperlink + m_hyperLink.setBounds(900, 1115, 400, 35); + m_hyperLink.setColour(Label::textColourId, Colours::silver); + m_hyperLink.setFont(Font("Arial", "Bold", 20.f), true, dontSendNotification); + m_hyperLink.setJustificationType(Justification::left); + m_hyperLink.setJustificationType(Justification::centred); + addAndMakeVisible(m_hyperLink); + + + m_controller.onProgramChange = [this]() { + updateParts(); + m_arpEditor->refreshParts(); + }; + m_controller.onMsgDone = [this]() { + m_controller.onMsgDone = nullptr; + postCommandMessage(VirusEditor::Commands::InitPatches); + postCommandMessage(VirusEditor::Commands::SelectFirstPatch); + postCommandMessage(VirusEditor::Commands::UpdateParts); + }; + + m_controller.getBankCount(); + addMouseListener(this, true); + setSize(kPanelWidth, kPanelHeight); + } + + VirusEditor::~VirusEditor() + { + m_controller.onProgramChange = nullptr; + m_mainMenu.onClick = nullptr; + selectorMenu.setLookAndFeel(nullptr); + SubSkinSizeSelector.setLookAndFeel(nullptr); + m_mainMenu.setLookAndFeel(nullptr); + selector.setLookAndFeel(nullptr); + setLookAndFeel(nullptr); + } + + bool VirusEditor::keyPressed(const KeyPress &k, Component *c) + { + if (k.getKeyCode() == 65573) + { + postCommandMessage(VirusEditor::Commands::PrevPatch); + } + if (k.getKeyCode() == 65575) + { + postCommandMessage(VirusEditor::Commands::NextPatch); + } + // 43 + + // 45 - + return true; + } + + void VirusEditor::updateParts() + { + const auto multiMode = m_controller.isMultiMode(); + for (auto pt = 0; pt < 16; pt++) + { + bool singlePartOrInMulti = pt == 0 || multiMode; + if (pt == m_controller.getCurrentPart()) + { + if (m_patchBrowser->GetIsFileMode()) + { + m_patchName.setText("[" + String(m_controller.getCurrentPart() + 1) + "][FILE] " + + String(m_patchBrowser->GetTablePatchList()->getSelectedRow(0) + 1) + ": " + + m_patchBrowser->GetLastPatchSelected(), + dontSendNotification); + } + else + { + const auto patchName = m_controller.getCurrentPartPresetName(pt); + if (m_patchName.getText() != patchName) + { + String sZero; + m_patchName.setText("[" + String(m_controller.getCurrentPart() + 1) + "][" + + m_patchBrowser->GetSelectBankNum() + "] " + + String(processorRef.getController().getCurrentPartProgram( + m_controller.getCurrentPart()) + + 1) + + ": " + patchName, + dontSendNotification); + } + } + } + } + } + + + void VirusEditor::ShowMainMenue() + { + m_mainMenu.setLookAndFeel(&m_landfButtons); + + m_mainMenu.onClick = [this]() { + selectorMenu.setLookAndFeel(&m_landfButtons); + selectorMenu.clear(); + SubSkinSizeSelector.setLookAndFeel(&m_landfButtons); + SubSkinSizeSelector.clear(); + + for (float d = 375; d < 1250; d = d + 125) + { + SubSkinSizeSelector.addItem(std::to_string(200 * int(d) / 1000) + "%", [this, d] { + double dScaleFactor = float(d / 1000.0); + m_AudioPlugInEditor->setScaleFactor(dScaleFactor); + (*this).setSize(iSkinSizeWidth, iSkinSizeHeight); + m_properties->setValue("skin_scale_factor", String(dScaleFactor)); + m_properties->save(); + }); + } + + selectorMenu.addSubMenu("Skin size", SubSkinSizeSelector, true); + selectorMenu.addItem("About", [this]() { AboutWindow(); }); + selectorMenu.showMenu(PopupMenu::Options()); + }; + + // draw Main Menu Button + m_mainMenu.setBounds(2301 - m_mainMenu.kWidth / 2, 62 - m_mainMenu.kHeight / 2, m_mainMenu.kWidth, + m_mainMenu.kHeight); + addAndMakeVisible(m_mainMenu); + } + + + void VirusEditor::applyToSections(std::function<void(Component *)> action) + { + for (auto *section : {static_cast<Component *>(m_arpEditor.get()), static_cast<Component *>(m_fxEditor.get()), + static_cast<Component *>(m_lfoEditor.get()), static_cast<Component *>(m_oscEditor.get()), + static_cast<Component *>(m_patchBrowser.get())}) + { + action(section); + } + } + + void VirusEditor::MainButtons::applyToMainButtons(std::function<void(DrawableButton *)> action) + { + for (auto *section : {static_cast<DrawableButton *>(&m_arpSettings), static_cast<DrawableButton *>(&m_effects), + static_cast<DrawableButton *>(&m_lfoMatrix), static_cast<DrawableButton *>(&m_oscFilter), + static_cast<DrawableButton *>(&m_patches)}) + { + action(section); + } + } -void VirusEditor::AboutWindow() {} + void VirusEditor::updateControlLabel(Component *eventComponent) + { + auto props = eventComponent->getProperties(); + if (props.contains("type") && props["type"] == "slider") + { + auto comp = dynamic_cast<Slider *>(eventComponent); + if (comp && comp->isEnabled()) + { + int iValue = (props.contains("bipolar") && props["bipolar"]) ? roundToInt(comp->getValue()) - 64 + : roundToInt(comp->getValue()); + + // ToolTip handle + m_ToolTip.setVisible(true); + m_ToolTip.setText(std::to_string(iValue), dontSendNotification); + // todo --> ugly --> Need to be fixed + m_ToolTip.setBounds(comp->getX() + comp->getWidth() * 2 - 43, comp->getY() + comp->getHeight() * 2 + 83, + 70, 30); + m_ToolTip.toFront(true); + + // Main display handle + m_controlLabel.setVisible(true); + m_controlLabelValue.setVisible(true); + m_patchName.setVisible(false); + + if (m_paramDisplayLocal) + { + m_controlLabel.setColour(Label::ColourIds::backgroundColourId, Colours::black); + m_controlLabel.setColour(Label::ColourIds::outlineColourId, Colours::white); + } + + m_controlLabel.setText(props["name"].toString(), dontSendNotification); + m_controlLabelValue.setText(String(iValue), dontSendNotification); + } + } + } + void VirusEditor::mouseDrag(const MouseEvent &event) { updateControlLabel(event.eventComponent); } + + void VirusEditor::mouseEnter(const MouseEvent &event) + { + if (event.mouseWasDraggedSinceMouseDown()) + { + return; + } + updateControlLabel(event.eventComponent); + } + + void VirusEditor::mouseExit(const MouseEvent &event) + { + if (event.mouseWasDraggedSinceMouseDown()) + { + return; + } + m_controlLabel.setText("", dontSendNotification); + m_controlLabel.setVisible(false); + m_controlLabelValue.setVisible(false); + m_patchName.setVisible(true); + m_ToolTip.setVisible(false); + } + + void VirusEditor::mouseDown(const MouseEvent &event) {} + + void VirusEditor::mouseUp(const MouseEvent &event) + { + m_controlLabel.setText("", dontSendNotification); + m_controlLabel.setVisible(false); + m_controlLabelValue.setVisible(false); + m_patchName.setVisible(true); + m_ToolTip.setVisible(false); + } + void VirusEditor::mouseWheelMove(const MouseEvent &event, const MouseWheelDetails &wheel) + { + updateControlLabel(event.eventComponent); + } + + + void VirusEditor::resized() + { + m_background->setBounds(getLocalBounds()); + + // Position of first main button (osc/filt) + m_mainButtons.setBounds(121, 36, m_mainButtons.getWidth(), m_mainButtons.getHeight()); + + // Panel Positions + applyToSections([this](Component *s) { s->setTopLeftPosition(101, 120); }); + } + + void VirusEditor::handleCommandMessage(int commandId) + { + switch (commandId) + { + case Commands::Rebind: + recreateControls(); + case Commands::UpdateParts: + { + updateParts(); + m_arpEditor->refreshParts(); + }; + break; + case Commands::InitPatches: + { + m_patchBrowser->IntiPatches(); + }; + break; + case Commands::PrevPatch: + { + if (m_patchBrowser->GetTablePatchList()->getSelectedRow(0) > 0) + { + m_patchBrowser->GetTablePatchList()->selectRow( + m_patchBrowser->GetTablePatchList()->getSelectedRow(0) - 1, false, false); + } + }; + break; + case Commands::NextPatch: + { + if (m_patchBrowser->GetTablePatchList()->getSelectedRow(0) < + m_patchBrowser->GetTablePatchList()->getNumRows() - 1) + { + m_patchBrowser->GetTablePatchList()->selectRow( + m_patchBrowser->GetTablePatchList()->getSelectedRow(0) + 1, false, false); + } + }; + break; + case Commands::SelectFirstPatch: + { + m_patchBrowser->GetTablePatchList()->selectRow(0, false, false); + }; + break; + + default: + return; + } + } + + void VirusEditor::recreateControls() + { + removeChildComponent(m_oscEditor.get()); + removeChildComponent(m_lfoEditor.get()); + removeChildComponent(m_fxEditor.get()); + removeChildComponent(m_arpEditor.get()); + // removeChildComponent(m_patchBrowser.get()); + + m_oscEditor = std::make_unique<OscEditor>(m_parameterBinding); + addChildComponent(m_oscEditor.get()); + + m_lfoEditor = std::make_unique<LfoEditor>(m_parameterBinding); + addChildComponent(m_lfoEditor.get()); + + m_fxEditor = std::make_unique<FxEditor>(m_parameterBinding, processorRef); + addChildComponent(m_fxEditor.get()); + + m_arpEditor = std::make_unique<ArpEditor>(m_parameterBinding, processorRef); + addChildComponent(m_arpEditor.get()); + + // m_patchBrowser = std::make_unique<PatchBrowser>(m_parameterBinding, processorRef); + // addChildComponent(m_patchBrowser.get()); + + m_mainButtons.updateSection(); + resized(); + } + + VirusEditor::MainButtons::MainButtons() : + m_oscFilter("OSC|FILTER", DrawableButton::ImageRaw), m_lfoMatrix("LFO|MATRIX", DrawableButton::ImageRaw), + m_effects("EFFECTS", DrawableButton::ImageRaw), m_arpSettings("ARP|SETTINGS", DrawableButton::ImageRaw), + m_patches("PATCHES", DrawableButton::ImageRaw) + { + constexpr auto numOfMainButtons = 5; + setupButton(0, Drawable::createFromImageData(BinaryData::btn_main_1_png, BinaryData::btn_main_1_pngSize), + m_oscFilter); + setupButton(1, Drawable::createFromImageData(BinaryData::btn_main_2_png, BinaryData::btn_main_2_pngSize), + m_lfoMatrix); + setupButton(2, Drawable::createFromImageData(BinaryData::btn_main_3_png, BinaryData::btn_main_3_pngSize), + m_effects); + setupButton(3, Drawable::createFromImageData(BinaryData::btn_main_4_png, BinaryData::btn_main_4_pngSize), + m_arpSettings); + setupButton(4, Drawable::createFromImageData(BinaryData::btn_main_5_png, BinaryData::btn_main_5_pngSize), + m_patches); + setSize((kButtonWidth + kMargin) * numOfMainButtons, kButtonHeight); + } + + + void VirusEditor::MainButtons::valueChanged(Value &) { updateSection(); } + + void VirusEditor::MainButtons::setupButton(int i, std::unique_ptr<Drawable> &&btnImage, DrawableButton &btn) + { + auto onImage = btnImage->createCopy(); + onImage->setOriginWithOriginalSize({0, -kButtonHeight}); + btn.setClickingTogglesState(true); + btn.setRadioGroupId(kGroupId); + btn.setImages(btnImage.get(), nullptr, nullptr, nullptr, onImage.get()); + btn.setBounds((i > 1 ? -1 : 0) + i * (kButtonWidth + kMargin) - 5, 0, kButtonWidth, kButtonHeight); + btn.getToggleStateValue().addListener(this); + addAndMakeVisible(btn); + } + + + void VirusEditor::AboutWindow() {} + +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/VirusEditor.h b/source/jucePlugin/ui2/VirusEditor.h @@ -6,8 +6,10 @@ #include "Virus_LookAndFeel.h" #include "../VirusController.h" #include "Virus_LookAndFeel.h" - class VirusParameterBinding; +namespace Trancy +{ + class OscEditor; class LfoEditor; class FxEditor; @@ -100,9 +102,9 @@ private: std::unique_ptr<PatchBrowser> m_patchBrowser; std::unique_ptr<juce::Drawable> m_background; - Virus::LookAndFeel m_lookAndFeel; - Virus::LookAndFeelButtons m_landfButtons; - Virus::CustomLAF m_landfToolTip; + VirusUI::LookAndFeel m_lookAndFeel; + VirusUI::LookAndFeelButtons m_landfButtons; + VirusUI::CustomLAF m_landfToolTip; juce::String m_previousPath; bool m_paramDisplayLocal = false; @@ -116,3 +118,4 @@ private: void mouseWheelMove (const juce::MouseEvent &event, const juce::MouseWheelDetails &wheel) override; }; +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Buttons.cpp b/source/jucePlugin/ui2/Virus_Buttons.cpp @@ -2,116 +2,121 @@ #include "BinaryData.h" #include "Virus_LookAndFeel.h" -using namespace juce; - -namespace Buttons +namespace Trancy { + using namespace juce; - Buttons::Button1::Button1() : DrawableButton("Button1", DrawableButton::ImageRaw) + namespace Buttons { - auto off = Drawable::createFromImageData(BinaryData::btn_1_png, BinaryData::btn_1_pngSize); - auto on = off->createCopy(); - on->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setClickingTogglesState(true); - on->setOriginWithOriginalSize({0, -kHeight}); - setImages(off.get(), nullptr, on.get(), nullptr, on.get()); - } - Buttons::Button2::Button2() : DrawableButton("Button2", DrawableButton::ImageRaw) - { - auto off = Drawable::createFromImageData(BinaryData::btn_2_png, BinaryData::btn_2_pngSize); - auto on = off->createCopy(); - on->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setClickingTogglesState(true); - on->setOriginWithOriginalSize({0, -kHeight}); - setImages(off.get(), nullptr, on.get(), nullptr, on.get()); - } + Buttons::Button1::Button1() : DrawableButton("Button1", DrawableButton::ImageRaw) + { + auto off = Drawable::createFromImageData(BinaryData::btn_1_png, BinaryData::btn_1_pngSize); + auto on = off->createCopy(); + on->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setClickingTogglesState(true); + on->setOriginWithOriginalSize({0, -kHeight}); + setImages(off.get(), nullptr, on.get(), nullptr, on.get()); + } - Buttons::Button3::Button3() : DrawableButton("Button3", DrawableButton::ImageRaw) - { - auto off = Drawable::createFromImageData(BinaryData::btn_3_png, BinaryData::btn_3_pngSize); - auto on = off->createCopy(); - on->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setClickingTogglesState(true); - on->setOriginWithOriginalSize({0, -kHeight}); - setImages(off.get(), nullptr, on.get(), nullptr, on.get()); - } + Buttons::Button2::Button2() : DrawableButton("Button2", DrawableButton::ImageRaw) + { + auto off = Drawable::createFromImageData(BinaryData::btn_2_png, BinaryData::btn_2_pngSize); + auto on = off->createCopy(); + on->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setClickingTogglesState(true); + on->setOriginWithOriginalSize({0, -kHeight}); + setImages(off.get(), nullptr, on.get(), nullptr, on.get()); + } - Buttons::Button4::Button4() : DrawableButton("Button4", DrawableButton::ImageRaw) - { - auto off = Drawable::createFromImageData(BinaryData::btn_4_png, BinaryData::btn_4_pngSize); - auto on = off->createCopy(); - on->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setClickingTogglesState(true); - on->setOriginWithOriginalSize({0, -kHeight}); - setImages(off.get(), nullptr, on.get(), nullptr, on.get()); - } - - Buttons::ButtonMenu::ButtonMenu() : DrawableButton("ButtonMenu", DrawableButton::ImageRaw) - { - auto normal = Drawable::createFromImageData(BinaryData::btn_menu_png, BinaryData::btn_menu_pngSize); - auto pressed = normal->createCopy(); - pressed->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); - } + Buttons::Button3::Button3() : DrawableButton("Button3", DrawableButton::ImageRaw) + { + auto off = Drawable::createFromImageData(BinaryData::btn_3_png, BinaryData::btn_3_pngSize); + auto on = off->createCopy(); + on->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setClickingTogglesState(true); + on->setOriginWithOriginalSize({0, -kHeight}); + setImages(off.get(), nullptr, on.get(), nullptr, on.get()); + } + + Buttons::Button4::Button4() : DrawableButton("Button4", DrawableButton::ImageRaw) + { + auto off = Drawable::createFromImageData(BinaryData::btn_4_png, BinaryData::btn_4_pngSize); + auto on = off->createCopy(); + on->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setClickingTogglesState(true); + on->setOriginWithOriginalSize({0, -kHeight}); + setImages(off.get(), nullptr, on.get(), nullptr, on.get()); + } + + Buttons::ButtonMenu::ButtonMenu() : DrawableButton("ButtonMenu", DrawableButton::ImageRaw) + { + auto normal = Drawable::createFromImageData(BinaryData::btn_menu_png, BinaryData::btn_menu_pngSize); + auto pressed = normal->createCopy(); + pressed->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); + } - Buttons::PresetButtonLeft::PresetButtonLeft() : DrawableButton("PresetButtonLeft", DrawableButton::ImageRaw) - { - auto normal = Drawable::createFromImageData(BinaryData::btn_left_png, BinaryData::btn_left_pngSize); - auto pressed = normal->createCopy(); - pressed->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); - } + Buttons::PresetButtonLeft::PresetButtonLeft() : DrawableButton("PresetButtonLeft", DrawableButton::ImageRaw) + { + auto normal = Drawable::createFromImageData(BinaryData::btn_left_png, BinaryData::btn_left_pngSize); + auto pressed = normal->createCopy(); + pressed->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); + } - Buttons::PresetButtonRight::PresetButtonRight() : DrawableButton("PresetButtonLeft", DrawableButton::ImageRaw) - { - auto normal = Drawable::createFromImageData(BinaryData::btn_right_png, BinaryData::btn_right_pngSize); - auto pressed = normal->createCopy(); - pressed->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); - } + Buttons::PresetButtonRight::PresetButtonRight() : DrawableButton("PresetButtonLeft", DrawableButton::ImageRaw) + { + auto normal = Drawable::createFromImageData(BinaryData::btn_right_png, BinaryData::btn_right_pngSize); + auto pressed = normal->createCopy(); + pressed->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); + } - Buttons::PresetButtonDown::PresetButtonDown() : DrawableButton("PresetButtonDown", DrawableButton::ImageRaw) - { - auto normal = Drawable::createFromImageData(BinaryData::btn_down_png, BinaryData::btn_down_pngSize); - auto pressed = normal->createCopy(); - pressed->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); - } + Buttons::PresetButtonDown::PresetButtonDown() : DrawableButton("PresetButtonDown", DrawableButton::ImageRaw) + { + auto normal = Drawable::createFromImageData(BinaryData::btn_down_png, BinaryData::btn_down_pngSize); + auto pressed = normal->createCopy(); + pressed->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); + } - Buttons::OptionButtonLoadBank::OptionButtonLoadBank() : DrawableButton("LoadBank", DrawableButton::ImageRaw) - { - auto normal = Drawable::createFromImageData(BinaryData::btn_load_bank_png, BinaryData::btn_load_bank_pngSize); - auto pressed = normal->createCopy(); - pressed->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); - } + Buttons::OptionButtonLoadBank::OptionButtonLoadBank() : DrawableButton("LoadBank", DrawableButton::ImageRaw) + { + auto normal = + Drawable::createFromImageData(BinaryData::btn_load_bank_png, BinaryData::btn_load_bank_pngSize); + auto pressed = normal->createCopy(); + pressed->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); + } - Buttons::OptionButtonSavePreset::OptionButtonSavePreset() : DrawableButton("LoadBank", DrawableButton::ImageRaw) - { - auto normal = Drawable::createFromImageData(BinaryData::btn_save_preset_png, BinaryData::btn_save_preset_pngSize); - auto pressed = normal->createCopy(); - pressed->setOriginWithOriginalSize({0, 2}); - setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); - setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); - setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); - } -}; // namespace Buttons + Buttons::OptionButtonSavePreset::OptionButtonSavePreset() : DrawableButton("LoadBank", DrawableButton::ImageRaw) + { + auto normal = + Drawable::createFromImageData(BinaryData::btn_save_preset_png, BinaryData::btn_save_preset_pngSize); + auto pressed = normal->createCopy(); + pressed->setOriginWithOriginalSize({0, 2}); + setColour(DrawableButton::ColourIds::backgroundColourId, Colours::transparentBlack); + setColour(DrawableButton::ColourIds::backgroundOnColourId, Colours::transparentBlack); + setImages(normal.get(), nullptr, pressed.get(), nullptr, pressed.get(), nullptr, normal.get()); + } + }; // namespace Buttons +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Buttons.h b/source/jucePlugin/ui2/Virus_Buttons.h @@ -1,87 +1,91 @@ #pragma once #include <juce_gui_extra/juce_gui_extra.h> - -namespace Buttons +namespace Trancy { - class Button1 : public juce::DrawableButton - { - public: - Button1(); - static constexpr auto kWidth = 36; - static constexpr auto kHeight = 136/2; - }; - class Button2 : public juce::DrawableButton + namespace Buttons { - public: - Button2(); - static constexpr auto kWidth = 69; - static constexpr auto kHeight = 134/2; - }; + class Button1 : public juce::DrawableButton + { + public: + Button1(); + static constexpr auto kWidth = 36; + static constexpr auto kHeight = 136 / 2; + }; - class Button3 : public juce::DrawableButton - { - public: - Button3(); - static constexpr auto kWidth = 69; - static constexpr auto kHeight = 134/2; - }; + class Button2 : public juce::DrawableButton + { + public: + Button2(); + static constexpr auto kWidth = 69; + static constexpr auto kHeight = 134 / 2; + }; - class Button4 : public juce::DrawableButton - { - public: - Button4(); - static constexpr auto kWidth = 68; - static constexpr auto kHeight = 72/2; - }; + class Button3 : public juce::DrawableButton + { + public: + Button3(); + static constexpr auto kWidth = 69; + static constexpr auto kHeight = 134 / 2; + }; - class ButtonMenu: public juce::DrawableButton - { - public: - static constexpr auto kWidth = 172; - static constexpr auto kHeight = 51; - ButtonMenu(); - }; + class Button4 : public juce::DrawableButton + { + public: + Button4(); + static constexpr auto kWidth = 68; + static constexpr auto kHeight = 72 / 2; + }; - class PresetButtonLeft: public juce::DrawableButton - { - public: - static constexpr auto kWidth = 33; - static constexpr auto kHeight = 51; - PresetButtonLeft(); - }; + class ButtonMenu : public juce::DrawableButton + { + public: + static constexpr auto kWidth = 172; + static constexpr auto kHeight = 51; + ButtonMenu(); + }; - class PresetButtonRight: public juce::DrawableButton - { - public: - static constexpr auto kWidth = 33; - static constexpr auto kHeight = 51; - PresetButtonRight(); - }; + class PresetButtonLeft : public juce::DrawableButton + { + public: + static constexpr auto kWidth = 33; + static constexpr auto kHeight = 51; + PresetButtonLeft(); + }; - class PresetButtonDown: public juce::DrawableButton - { - public: - static constexpr auto kWidth = 33; - static constexpr auto kHeight = 51; - PresetButtonDown(); - }; - - class OptionButtonLoadBank: public juce::DrawableButton - { - public: - static constexpr auto kWidth = 172; - static constexpr auto kHeight = 50; - OptionButtonLoadBank(); - }; + class PresetButtonRight : public juce::DrawableButton + { + public: + static constexpr auto kWidth = 33; + static constexpr auto kHeight = 51; + PresetButtonRight(); + }; - class OptionButtonSavePreset: public juce::DrawableButton - { - public: - static constexpr auto kWidth = 172; - static constexpr auto kHeight = 50; - OptionButtonSavePreset(); - }; + class PresetButtonDown : public juce::DrawableButton + { + public: + static constexpr auto kWidth = 33; + static constexpr auto kHeight = 51; + PresetButtonDown(); + }; + + class OptionButtonLoadBank : public juce::DrawableButton + { + public: + static constexpr auto kWidth = 172; + static constexpr auto kHeight = 50; + OptionButtonLoadBank(); + }; + + class OptionButtonSavePreset : public juce::DrawableButton + { + public: + static constexpr auto kWidth = 172; + static constexpr auto kHeight = 50; + OptionButtonSavePreset(); + }; + + } // namespace Buttons -} // namespace Buttons +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_LookAndFeel.cpp b/source/jucePlugin/ui2/Virus_LookAndFeel.cpp @@ -1,82 +1,85 @@ #include "Virus_LookAndFeel.h" #include "BinaryData.h" - -using namespace juce; - -namespace Virus +namespace Trancy { - const Font getCustomFont() - { - static auto typefaceDigiFont = Typeface::createSystemTypefaceFor(BinaryData::Digital, BinaryData::DigitalSize); - return Font (typefaceDigiFont); - } - - //LookAndFeel - LookAndFeelSmallButton::LookAndFeelSmallButton() - { - // setup knobs... - m_genKnob = Drawable::createFromImageData(BinaryData::knob_2_128_png, BinaryData::knob_2_128_pngSize); - - m_knobImageSteps.start = 1; - m_knobImageSteps.end = 127; - } - - void LookAndFeelSmallButton::drawRotarySlider(Graphics &g, int x, int y, int width, int height, float sliderPosProportional, - float rotaryStartAngle, float rotaryEndAngle, Slider &s) - { - Drawable *knob = m_genKnob.get(); - int step; - (s.isEnabled())?step=roundToInt(m_knobImageSteps.convertFrom0to1(sliderPosProportional)):step=0; + using namespace juce; - knob->setOriginWithOriginalSize({0.0f, -float(kKnobSize) * step}); - - // this won't support scaling! - knob->drawAt(g, x, y, 1.0f); - } - - LookAndFeel::LookAndFeel() - { - // setup knobs... - m_genKnob = Drawable::createFromImageData(BinaryData::knob_1_128_png, BinaryData::knob_1_128_pngSize); - - m_knobImageSteps.start = 1; - m_knobImageSteps.end = 127; - } - - void LookAndFeel::drawRotarySlider(Graphics &g, int x, int y, int width, int height, float sliderPosProportional, - float rotaryStartAngle, float rotaryEndAngle, Slider &s) - { - Drawable *knob = m_genKnob.get(); - - int step; - (s.isEnabled())?step=roundToInt(m_knobImageSteps.convertFrom0to1(sliderPosProportional)):step=0; - - knob->setOriginWithOriginalSize({0.0f, -float(kKnobSize) * step}); - - // this won't support scaling! - knob->drawAt(g, x, y, 1.0f); - } - - void LookAndFeel::drawComboBox (Graphics& gGrafik, int width, int height, bool isButtonDown, int buttonX, int buttonY, int buttonW, int buttonH, ComboBox& box) - { - //gGrafik.setOpacity(0); - //box.setColour(ComboBox::textColourId, Colours::red); - }; - - //LookAndFeelPatchBrowser - LookAndFeelPatchBrowser::LookAndFeelPatchBrowser() - { - } - - //LookAndFeelButtons - LookAndFeelButtons::LookAndFeelButtons() + namespace VirusUI { - } - - void LookAndFeelButtons::drawComboBox (Graphics& gGrafik, int width, int height, bool isButtonDown, int buttonX, int buttonY, int buttonW, int buttonH, ComboBox& box) - { - gGrafik.setOpacity(0); - }; - -} // namespace Virus + const Font getCustomFont() + { + static auto typefaceDigiFont = + Typeface::createSystemTypefaceFor(BinaryData::Digital, BinaryData::DigitalSize); + return Font(typefaceDigiFont); + } + + // LookAndFeel + LookAndFeelSmallButton::LookAndFeelSmallButton() + { + // setup knobs... + m_genKnob = Drawable::createFromImageData(BinaryData::knob_2_128_png, BinaryData::knob_2_128_pngSize); + + m_knobImageSteps.start = 1; + m_knobImageSteps.end = 127; + } + + void LookAndFeelSmallButton::drawRotarySlider(Graphics &g, int x, int y, int width, int height, + float sliderPosProportional, float rotaryStartAngle, + float rotaryEndAngle, Slider &s) + { + Drawable *knob = m_genKnob.get(); + + int step; + (s.isEnabled()) ? step = roundToInt(m_knobImageSteps.convertFrom0to1(sliderPosProportional)) : step = 0; + + knob->setOriginWithOriginalSize({0.0f, -float(kKnobSize) * step}); + + // this won't support scaling! + knob->drawAt(g, x, y, 1.0f); + } + + LookAndFeel::LookAndFeel() + { + // setup knobs... + m_genKnob = Drawable::createFromImageData(BinaryData::knob_1_128_png, BinaryData::knob_1_128_pngSize); + + m_knobImageSteps.start = 1; + m_knobImageSteps.end = 127; + } + + void LookAndFeel::drawRotarySlider(Graphics &g, int x, int y, int width, int height, + float sliderPosProportional, float rotaryStartAngle, float rotaryEndAngle, + Slider &s) + { + Drawable *knob = m_genKnob.get(); + + int step; + (s.isEnabled()) ? step = roundToInt(m_knobImageSteps.convertFrom0to1(sliderPosProportional)) : step = 0; + + knob->setOriginWithOriginalSize({0.0f, -float(kKnobSize) * step}); + + // this won't support scaling! + knob->drawAt(g, x, y, 1.0f); + } + + void LookAndFeel::drawComboBox(Graphics &gGrafik, int width, int height, bool isButtonDown, int buttonX, + int buttonY, int buttonW, int buttonH, ComboBox &box){ + // gGrafik.setOpacity(0); + // box.setColour(ComboBox::textColourId, Colours::red); + }; + + // LookAndFeelPatchBrowser + LookAndFeelPatchBrowser::LookAndFeelPatchBrowser() {} + + // LookAndFeelButtons + LookAndFeelButtons::LookAndFeelButtons() {} + + void LookAndFeelButtons::drawComboBox(Graphics &gGrafik, int width, int height, bool isButtonDown, int buttonX, + int buttonY, int buttonW, int buttonH, ComboBox &box) + { + gGrafik.setOpacity(0); + }; + + } // namespace Virus +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_LookAndFeel.h b/source/jucePlugin/ui2/Virus_LookAndFeel.h @@ -1,152 +1,140 @@ #pragma once #include <juce_gui_extra/juce_gui_extra.h> +namespace Trancy +{ -constexpr auto comboBoxHeight = 38; -constexpr auto comboBoxWidth = 126; + constexpr auto comboBoxHeight = 38; + constexpr auto comboBoxWidth = 126; + + constexpr auto comboBox2Height = 52; + constexpr auto comboBox2Width = 74; + + constexpr auto comboBox3Height = 52; + constexpr auto comboBox3Width = 186; -constexpr auto comboBox2Height = 52; -constexpr auto comboBox2Width = 74; + constexpr auto kPanelWidth = 2501; + constexpr auto kPanelHeight = 1152; -constexpr auto comboBox3Height = 52; -constexpr auto comboBox3Width = 186; + constexpr auto comboBoxXMargin = 5; -constexpr auto kPanelWidth = 2501; -constexpr auto kPanelHeight = 1152; + namespace VirusUI + { + const juce::Font getCustomFont(); -constexpr auto comboBoxXMargin = 5; + class CustomLAF : public juce::LookAndFeel_V4 + { + public: + void drawLabel(juce::Graphics &g, juce::Label &l) override + { + // g.fillAll (label.findColour (Label::backgroundColourId)); + g.setColour(l.findColour(juce::Label::backgroundColourId)); + g.fillRoundedRectangle(l.getLocalBounds().toFloat(), 5); -namespace Virus -{ - const juce::Font getCustomFont(); - - class CustomLAF : public juce::LookAndFeel_V4 - { - public: - void drawLabel(juce::Graphics& g, juce::Label& l) override - { - // g.fillAll (label.findColour (Label::backgroundColourId)); - g.setColour (l.findColour (juce::Label::backgroundColourId)); - g.fillRoundedRectangle (l.getLocalBounds().toFloat(), 5); - - // g.drawRect (label.getLocalBounds()); - g.drawRoundedRectangle (l.getLocalBounds().toFloat(), 10, 1); - } - juce::Font getLabelFont(juce::Label& label) override - { - juce::Font fFont(getCustomFont().getTypeface()); - fFont.setHeight(20.f); - return fFont; - } - }; - - class LookAndFeelSmallButton : public juce::LookAndFeel_V4/*, juce::Slider*/ - { - public: - LookAndFeelSmallButton(); - - static constexpr auto kKnobSize = 55; - static const char *KnobStyleProp; - - void drawRotarySlider(juce::Graphics &, int x, int y, int width, int height, float sliderPosProportional, - float rotaryStartAngle, float rotaryEndAngle, juce::Slider &sSlider) override; - - - private: - std::unique_ptr<juce::Drawable> m_genKnob; - juce::NormalisableRange<float> m_knobImageSteps; - }; - - - class LookAndFeel : public juce::LookAndFeel_V4/*, juce::Slider*/ - { - public: - LookAndFeel(); - - static constexpr auto kKnobSize = 75; - static const char *KnobStyleProp; - - void drawRotarySlider(juce::Graphics &, int x, int y, int width, int height, float sliderPosProportional, - float rotaryStartAngle, float rotaryEndAngle, juce::Slider &sSlider) override; - - - juce::Typeface::Ptr getTypefaceForFont (const juce::Font& f) override - { - return getCustomFont().getTypeface(); - } - - void drawComboBox (juce::Graphics& gGrafik, int width, int height, bool isButtonDown, int buttonX, int buttonY, int buttonW, int buttonH, juce::ComboBox& box) override; - - juce::Font getComboBoxFont (juce::ComboBox& ) override - { - juce::Font fFont(getCustomFont().getTypeface()); - fFont.setHeight(20.f); - return fFont; - } - - juce::Font getTextButtonFont(juce::TextButton& button, int buttonHeight) override - { - juce::Font fFont(getCustomFont().getTypeface()); - fFont.setHeight(20.f); - return fFont; - } - - juce::Font getPopupMenuFont() override - { - juce::Font fFont(getCustomFont().getTypeface()); - fFont.setHeight(20.f); - return fFont; - } - - private: - std::unique_ptr<juce::Drawable> m_genKnob; - juce::NormalisableRange<float> m_knobImageSteps; - }; - - class LookAndFeelPatchBrowser : public juce::LookAndFeel_V4 - { - public: - LookAndFeelPatchBrowser(); - - juce::Font getComboBoxFont (juce::ComboBox& /*box*/) override - { - return getCommonMenuFont(); - } - - juce::Font getPopupMenuFont() override - { - return getCommonMenuFont(); - } - - private: - juce::Font getCommonMenuFont() - { - return juce::Font("Arial", "Normal", 13.f); - } - }; - - class LookAndFeelButtons : public juce::LookAndFeel_V4 - { - public: - LookAndFeelButtons(); - - juce::Font getComboBoxFont (juce::ComboBox& /*box*/) override - { - return getCommonMenuFont(); - } - - juce::Font getPopupMenuFont() override - { - return getCommonMenuFont(); - } - - void drawComboBox (juce::Graphics& gGrafik, int width, int height, bool isButtonDown, int buttonX, int buttonY, int buttonW, int buttonH, juce::ComboBox& box) override; - - private: - juce::Font getCommonMenuFont() - { - return juce::Font("Arial", "Normal", 23.f); - } - }; - -} // namespace Virus + // g.drawRect (label.getLocalBounds()); + g.drawRoundedRectangle(l.getLocalBounds().toFloat(), 10, 1); + } + juce::Font getLabelFont(juce::Label &label) override + { + juce::Font fFont(getCustomFont().getTypeface()); + fFont.setHeight(20.f); + return fFont; + } + }; + + class LookAndFeelSmallButton : public juce::LookAndFeel_V4 /*, juce::Slider*/ + { + public: + LookAndFeelSmallButton(); + + static constexpr auto kKnobSize = 55; + static const char *KnobStyleProp; + + void drawRotarySlider(juce::Graphics &, int x, int y, int width, int height, float sliderPosProportional, + float rotaryStartAngle, float rotaryEndAngle, juce::Slider &sSlider) override; + + + private: + std::unique_ptr<juce::Drawable> m_genKnob; + juce::NormalisableRange<float> m_knobImageSteps; + }; + + + class LookAndFeel : public juce::LookAndFeel_V4 /*, juce::Slider*/ + { + public: + LookAndFeel(); + + static constexpr auto kKnobSize = 75; + static const char *KnobStyleProp; + + void drawRotarySlider(juce::Graphics &, int x, int y, int width, int height, float sliderPosProportional, + float rotaryStartAngle, float rotaryEndAngle, juce::Slider &sSlider) override; + + + juce::Typeface::Ptr getTypefaceForFont(const juce::Font &f) override + { + return getCustomFont().getTypeface(); + } + + void drawComboBox(juce::Graphics &gGrafik, int width, int height, bool isButtonDown, int buttonX, + int buttonY, int buttonW, int buttonH, juce::ComboBox &box) override; + + juce::Font getComboBoxFont(juce::ComboBox &) override + { + juce::Font fFont(getCustomFont().getTypeface()); + fFont.setHeight(20.f); + return fFont; + } + + juce::Font getTextButtonFont(juce::TextButton &button, int buttonHeight) override + { + juce::Font fFont(getCustomFont().getTypeface()); + fFont.setHeight(20.f); + return fFont; + } + + juce::Font getPopupMenuFont() override + { + juce::Font fFont(getCustomFont().getTypeface()); + fFont.setHeight(20.f); + return fFont; + } + + private: + std::unique_ptr<juce::Drawable> m_genKnob; + juce::NormalisableRange<float> m_knobImageSteps; + }; + + class LookAndFeelPatchBrowser : public juce::LookAndFeel_V4 + { + public: + LookAndFeelPatchBrowser(); + + juce::Font getComboBoxFont(juce::ComboBox & /*box*/) override { return getCommonMenuFont(); } + + juce::Font getPopupMenuFont() override { return getCommonMenuFont(); } + + private: + juce::Font getCommonMenuFont() { return juce::Font("Arial", "Normal", 13.f); } + }; + + class LookAndFeelButtons : public juce::LookAndFeel_V4 + { + public: + LookAndFeelButtons(); + + juce::Font getComboBoxFont(juce::ComboBox & /*box*/) override { return getCommonMenuFont(); } + + juce::Font getPopupMenuFont() override { return getCommonMenuFont(); } + + void drawComboBox(juce::Graphics &gGrafik, int width, int height, bool isButtonDown, int buttonX, + int buttonY, int buttonW, int buttonH, juce::ComboBox &box) override; + + private: + juce::Font getCommonMenuFont() { return juce::Font("Arial", "Normal", 23.f); } + }; + + } // namespace Virus + +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel1_OscEditor.cpp b/source/jucePlugin/ui2/Virus_Panel1_OscEditor.cpp @@ -3,270 +3,287 @@ #include "Ui_Utils.h" #include "../VirusParameterBinding.h" -using namespace juce; - -OscEditor::OscEditor(VirusParameterBinding& _parameterBinding) +namespace Trancy { - setupBackground(*this, m_background, BinaryData::panel_1_png, BinaryData::panel_1_pngSize); - setBounds(m_background->getDrawableBounds().toNearestIntEdges()); - - //setLookAndFeel(&m_lookAndFeel); - - for (auto *s : {&m_osc1Shape, &m_osc1PulseWidth, &m_osc1Semitone, &m_osc1KeyFollow}) - { - setupRotary(*this, *s); - } - - //OSC 1 - m_osc1Shape.setBounds(287 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); - m_osc1PulseWidth.setBounds(433 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); - m_osc1Semitone.setBounds(577 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); - m_osc1KeyFollow.setBounds(722 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_osc1WaveSelect); - m_osc1WaveSelect.setBounds(114+comboBoxXMargin - comboBoxWidth / 2, 103 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - - _parameterBinding.bind(m_osc1Semitone, Virus::Param_Osc1Semitone); - _parameterBinding.bind(m_osc1Shape, Virus::Param_Osc1Shape); - _parameterBinding.bind(m_osc1PulseWidth, Virus::Param_Osc1PW ); - _parameterBinding.bind(m_osc1KeyFollow, Virus::Param_Osc1Keyfollow ); - _parameterBinding.bind(m_osc1WaveSelect, Virus::Param_Osc1Wave); - - //OSC 2 - for (auto *s : {&m_osc2Shape, &m_osc2PulseWidth, &m_osc2Semitone, &m_osc2KeyFollow}) - { - setupRotary(*this, *s); - } - - m_osc2Shape.setBounds(287 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); - m_osc2PulseWidth.setBounds(433 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); - m_osc2Semitone.setBounds(577 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); - m_osc2KeyFollow.setBounds(722 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_osc2WaveSelect); - m_osc2WaveSelect.setBounds(114+comboBoxXMargin - comboBoxWidth / 2, 311 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - - for (auto *s : {&m_osc2FmAmount, &m_osc2Detune, &m_osc2EnvFm, &m_osc2envOSC, &m_osc2PhaseInit}) - { - setupRotary(*this, *s); - } - - m_osc2FmAmount.setBounds(287 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_osc2Detune.setBounds(433 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_osc2EnvFm.setBounds(577 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_osc2envOSC.setBounds(722 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_osc2PhaseInit.setBounds(871 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_osc2FmMode); - m_osc2FmMode.setBounds(114+comboBoxXMargin - comboBoxWidth / 2, 485 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - - addAndMakeVisible(m_syncOsc1Osc2); - m_syncOsc1Osc2.setBounds(871 - m_syncOsc1Osc2.kWidth/ 2, 308 - m_syncOsc1Osc2.kHeight / 2, m_syncOsc1Osc2.kWidth, m_syncOsc1Osc2.kHeight); - - _parameterBinding.bind(m_osc2Semitone, Virus::Param_Osc2Semitone); - _parameterBinding.bind(m_osc2Shape, Virus::Param_Osc2Shape); - _parameterBinding.bind(m_osc2PulseWidth, Virus::Param_Osc2PW); - _parameterBinding.bind(m_osc2KeyFollow, Virus::Param_Osc2Keyfollow); - _parameterBinding.bind(m_osc2WaveSelect, Virus::Param_Osc2Wave); - - _parameterBinding.bind(m_osc2FmAmount, Virus::Param_Osc2FMAmount); - _parameterBinding.bind(m_osc2Detune, Virus::Param_Osc2Detune); - _parameterBinding.bind(m_osc2EnvFm, Virus::Param_FMFiltEnvAmt); - _parameterBinding.bind(m_osc2envOSC, Virus::Param_Osc2FltEnvAmt); - _parameterBinding.bind(m_osc2PhaseInit, Virus::Param_OscInitPhase); - _parameterBinding.bind(m_osc2FmMode, Virus::Param_OscFMMode); - _parameterBinding.bind(m_syncOsc1Osc2, Virus::Param_Osc2Sync); - - //OSC 3 - for (auto *s : {&m_osc3Semitone, &m_osc3Detune, &m_osc3Level}) - { - setupRotary(*this, *s); - } - - m_osc3Semitone.setBounds(287 - knobSize / 2, 694 - knobSize / 2, knobSize, knobSize); - m_osc3Detune.setBounds(434 - knobSize / 2, 694 - knobSize / 2, knobSize, knobSize); - m_osc3Mode.setBounds(114+comboBoxXMargin - comboBoxWidth / 2, 694 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - addAndMakeVisible(m_osc3Mode); - - _parameterBinding.bind(m_osc3Semitone, Virus::Param_Osc3Semitone); - _parameterBinding.bind(m_osc3Detune, Virus::Param_Osc3Detune); - _parameterBinding.bind(m_osc3Mode, Virus::Param_Osc3Mode); - - // OSC SUB - setupRotary(*this, m_noiseColor); - m_noiseColor.setBounds(841 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); - m_subWaveform.setBounds(656 - m_subWaveform.kWidth / 2, 692 - m_subWaveform.kHeight / 2, m_subWaveform.kWidth, m_subWaveform.kHeight); - addAndMakeVisible(m_subWaveform); - _parameterBinding.bind(m_noiseColor, Virus::Param_NoiseColor); - _parameterBinding.bind(m_subWaveform, Virus::Param_SubOscShape); - - //UNISON - for (auto *s : {&m_detune, &m_panSpread, &m_lfoPhase}) - { - setupRotary(*this, *s); - } - - m_detune.setBounds(287 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); - m_panSpread.setBounds(434 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); - m_lfoPhase.setBounds(577 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); - addAndMakeVisible(m_unisonVoices); - m_unisonVoices.setBounds(114+comboBoxXMargin - comboBoxWidth / 2, 903 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - - _parameterBinding.bind(m_detune, Virus::Param_UnisonDetune); - _parameterBinding.bind(m_panSpread, Virus::Param_UnisonPanSpread); - _parameterBinding.bind(m_lfoPhase, Virus::Param_UnisonLfoPhase); - _parameterBinding.bind(m_unisonVoices, Virus::Param_UnisonMode); - - // Punch - setupRotary(*this, m_Punch); - m_Punch.setBounds(841 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); - _parameterBinding.bind(m_Punch, Virus::Param_PunchIntensity); - - // Mixer - for (auto *s : {&m_oscBalance, &m_oscLevel, &m_osc3Level, &m_oscSublevel, &m_noiseLevel, &m_ringModLevel}) - { - setupRotary(*this, *s); - } - - m_oscBalance.setBounds(1260 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_oscLevel.setBounds(1260 - knobSize / 2, 263 - knobSize / 2, knobSize, knobSize); - m_osc3Level.setBounds(1260 - knobSize / 2, 422 - knobSize / 2, knobSize, knobSize); - m_oscSublevel.setBounds(1260 - knobSize / 2, 579 - knobSize / 2, knobSize, knobSize); - m_noiseLevel.setBounds(1260 - knobSize / 2, 744 - knobSize / 2, knobSize, knobSize); - m_ringModLevel.setBounds(1260 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); - - _parameterBinding.bind(m_oscBalance, Virus::Param_OscBalance); - _parameterBinding.bind(m_oscLevel, Virus::Param_OscMainVolume); - _parameterBinding.bind(m_osc3Level, Virus::Param_Osc3Volume); - _parameterBinding.bind(m_oscSublevel, Virus::Param_SubOscVolume); - _parameterBinding.bind(m_noiseLevel, Virus::Param_NoiseVolume); - _parameterBinding.bind(m_ringModLevel, Virus::Param_RingModMVolume); - - //Velo mod - for (auto *s : {&m_osc1ShapeVelocity, &m_pulseWidthVelocity, &m_ampVelocity, &m_panoramaVelocity, &m_osc2ShapeVelocity, &m_fmAmountVelocity}) + using namespace juce; + using namespace Virus; + OscEditor::OscEditor(VirusParameterBinding &_parameterBinding) { - setupRotary(*this, *s); + setupBackground(*this, m_background, BinaryData::panel_1_png, BinaryData::panel_1_pngSize); + setBounds(m_background->getDrawableBounds().toNearestIntEdges()); + + // setLookAndFeel(&m_lookAndFeel); + + for (auto *s : {&m_osc1Shape, &m_osc1PulseWidth, &m_osc1Semitone, &m_osc1KeyFollow}) + { + setupRotary(*this, *s); + } + + // OSC 1 + m_osc1Shape.setBounds(287 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); + m_osc1PulseWidth.setBounds(433 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); + m_osc1Semitone.setBounds(577 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); + m_osc1KeyFollow.setBounds(722 - knobSize / 2, 103 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_osc1WaveSelect); + m_osc1WaveSelect.setBounds(114 + comboBoxXMargin - comboBoxWidth / 2, 103 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + + _parameterBinding.bind(m_osc1Semitone, Virus::Param_Osc1Semitone); + _parameterBinding.bind(m_osc1Shape, Virus::Param_Osc1Shape); + _parameterBinding.bind(m_osc1PulseWidth, Virus::Param_Osc1PW); + _parameterBinding.bind(m_osc1KeyFollow, Virus::Param_Osc1Keyfollow); + _parameterBinding.bind(m_osc1WaveSelect, Virus::Param_Osc1Wave); + + // OSC 2 + for (auto *s : {&m_osc2Shape, &m_osc2PulseWidth, &m_osc2Semitone, &m_osc2KeyFollow}) + { + setupRotary(*this, *s); + } + + m_osc2Shape.setBounds(287 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); + m_osc2PulseWidth.setBounds(433 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); + m_osc2Semitone.setBounds(577 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); + m_osc2KeyFollow.setBounds(722 - knobSize / 2, 311 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_osc2WaveSelect); + m_osc2WaveSelect.setBounds(114 + comboBoxXMargin - comboBoxWidth / 2, 311 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + + for (auto *s : {&m_osc2FmAmount, &m_osc2Detune, &m_osc2EnvFm, &m_osc2envOSC, &m_osc2PhaseInit}) + { + setupRotary(*this, *s); + } + + m_osc2FmAmount.setBounds(287 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_osc2Detune.setBounds(433 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_osc2EnvFm.setBounds(577 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_osc2envOSC.setBounds(722 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_osc2PhaseInit.setBounds(871 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_osc2FmMode); + m_osc2FmMode.setBounds(114 + comboBoxXMargin - comboBoxWidth / 2, 485 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + + addAndMakeVisible(m_syncOsc1Osc2); + m_syncOsc1Osc2.setBounds(871 - m_syncOsc1Osc2.kWidth / 2, 308 - m_syncOsc1Osc2.kHeight / 2, + m_syncOsc1Osc2.kWidth, m_syncOsc1Osc2.kHeight); + + _parameterBinding.bind(m_osc2Semitone, Virus::Param_Osc2Semitone); + _parameterBinding.bind(m_osc2Shape, Virus::Param_Osc2Shape); + _parameterBinding.bind(m_osc2PulseWidth, Virus::Param_Osc2PW); + _parameterBinding.bind(m_osc2KeyFollow, Virus::Param_Osc2Keyfollow); + _parameterBinding.bind(m_osc2WaveSelect, Virus::Param_Osc2Wave); + + _parameterBinding.bind(m_osc2FmAmount, Virus::Param_Osc2FMAmount); + _parameterBinding.bind(m_osc2Detune, Virus::Param_Osc2Detune); + _parameterBinding.bind(m_osc2EnvFm, Virus::Param_FMFiltEnvAmt); + _parameterBinding.bind(m_osc2envOSC, Virus::Param_Osc2FltEnvAmt); + _parameterBinding.bind(m_osc2PhaseInit, Virus::Param_OscInitPhase); + _parameterBinding.bind(m_osc2FmMode, Virus::Param_OscFMMode); + _parameterBinding.bind(m_syncOsc1Osc2, Virus::Param_Osc2Sync); + + // OSC 3 + for (auto *s : {&m_osc3Semitone, &m_osc3Detune, &m_osc3Level}) + { + setupRotary(*this, *s); + } + + m_osc3Semitone.setBounds(287 - knobSize / 2, 694 - knobSize / 2, knobSize, knobSize); + m_osc3Detune.setBounds(434 - knobSize / 2, 694 - knobSize / 2, knobSize, knobSize); + m_osc3Mode.setBounds(114 + comboBoxXMargin - comboBoxWidth / 2, 694 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + addAndMakeVisible(m_osc3Mode); + + _parameterBinding.bind(m_osc3Semitone, Virus::Param_Osc3Semitone); + _parameterBinding.bind(m_osc3Detune, Virus::Param_Osc3Detune); + _parameterBinding.bind(m_osc3Mode, Virus::Param_Osc3Mode); + + // OSC SUB + setupRotary(*this, m_noiseColor); + m_noiseColor.setBounds(841 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); + m_subWaveform.setBounds(656 - m_subWaveform.kWidth / 2, 692 - m_subWaveform.kHeight / 2, m_subWaveform.kWidth, + m_subWaveform.kHeight); + addAndMakeVisible(m_subWaveform); + _parameterBinding.bind(m_noiseColor, Virus::Param_NoiseColor); + _parameterBinding.bind(m_subWaveform, Virus::Param_SubOscShape); + + // UNISON + for (auto *s : {&m_detune, &m_panSpread, &m_lfoPhase}) + { + setupRotary(*this, *s); + } + + m_detune.setBounds(287 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); + m_panSpread.setBounds(434 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); + m_lfoPhase.setBounds(577 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); + addAndMakeVisible(m_unisonVoices); + m_unisonVoices.setBounds(114 + comboBoxXMargin - comboBoxWidth / 2, 903 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + + _parameterBinding.bind(m_detune, Virus::Param_UnisonDetune); + _parameterBinding.bind(m_panSpread, Virus::Param_UnisonPanSpread); + _parameterBinding.bind(m_lfoPhase, Virus::Param_UnisonLfoPhase); + _parameterBinding.bind(m_unisonVoices, Virus::Param_UnisonMode); + + // Punch + setupRotary(*this, m_Punch); + m_Punch.setBounds(841 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); + _parameterBinding.bind(m_Punch, Virus::Param_PunchIntensity); + + // Mixer + for (auto *s : {&m_oscBalance, &m_oscLevel, &m_osc3Level, &m_oscSublevel, &m_noiseLevel, &m_ringModLevel}) + { + setupRotary(*this, *s); + } + + m_oscBalance.setBounds(1260 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_oscLevel.setBounds(1260 - knobSize / 2, 263 - knobSize / 2, knobSize, knobSize); + m_osc3Level.setBounds(1260 - knobSize / 2, 422 - knobSize / 2, knobSize, knobSize); + m_oscSublevel.setBounds(1260 - knobSize / 2, 579 - knobSize / 2, knobSize, knobSize); + m_noiseLevel.setBounds(1260 - knobSize / 2, 744 - knobSize / 2, knobSize, knobSize); + m_ringModLevel.setBounds(1260 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); + + _parameterBinding.bind(m_oscBalance, Virus::Param_OscBalance); + _parameterBinding.bind(m_oscLevel, Virus::Param_OscMainVolume); + _parameterBinding.bind(m_osc3Level, Virus::Param_Osc3Volume); + _parameterBinding.bind(m_oscSublevel, Virus::Param_SubOscVolume); + _parameterBinding.bind(m_noiseLevel, Virus::Param_NoiseVolume); + _parameterBinding.bind(m_ringModLevel, Virus::Param_RingModMVolume); + + // Velo mod + for (auto *s : {&m_osc1ShapeVelocity, &m_pulseWidthVelocity, &m_ampVelocity, &m_panoramaVelocity, + &m_osc2ShapeVelocity, &m_fmAmountVelocity}) + { + setupRotary(*this, *s); + } + + m_osc1ShapeVelocity.setBounds(1067 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_osc2ShapeVelocity.setBounds(1067 - knobSize / 2, 264 - knobSize / 2, knobSize, knobSize); + m_pulseWidthVelocity.setBounds(1067 - knobSize / 2, 421 - knobSize / 2, knobSize, knobSize); + m_fmAmountVelocity.setBounds(1067 - knobSize / 2, 579 - knobSize / 2, knobSize, knobSize); + m_ampVelocity.setBounds(1067 - knobSize / 2, 743 - knobSize / 2, knobSize, knobSize); + m_panoramaVelocity.setBounds(1067 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); + + _parameterBinding.bind(m_osc1ShapeVelocity, Virus::Param_Osc1ShapeVelocity); + _parameterBinding.bind(m_pulseWidthVelocity, Virus::Param_PulseWidthVelocity); + _parameterBinding.bind(m_ampVelocity, Virus::Param_AmpVelocity); + _parameterBinding.bind(m_panoramaVelocity, Virus::Param_PanoramaVelocity); + _parameterBinding.bind(m_osc2ShapeVelocity, Virus::Param_Osc2ShapeVelocity); + _parameterBinding.bind(m_fmAmountVelocity, Virus::Param_FmAmountVelocity); + + // Filters + for (auto *s : {&m_cutoff1, &m_res1, &m_envAmount1, &m_keyTrack1, &m_resVel1, &m_envVel1, &m_cutoff2, &m_res2, + &m_envAmount2, &m_keyTrack2, &m_resVel2, &m_envVel2, &m_filterBalance}) + { + setupRotary(*this, *s); + } + + m_cutoff1.setBounds(1474 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_res1.setBounds(1618 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_envAmount1.setBounds(1762 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_keyTrack1.setBounds(1909 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_resVel1.setBounds(2053 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_envVel1.setBounds(2193 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); + m_cutoff2.setBounds(1474 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_res2.setBounds(1618 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_envAmount2.setBounds(1762 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_keyTrack2.setBounds(1909 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_resVel2.setBounds(2053 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_envVel2.setBounds(2193 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); + m_filterBalance.setBounds(1522 - knobSize / 2, 302 - knobSize / 2, knobSize, knobSize); + + m_filterMode1.setBounds(1710 + comboBoxXMargin - comboBox3Width / 2, 239 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_filterMode2.setBounds(1710 + comboBoxXMargin - comboBox3Width / 2, 353 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_filterRouting.setBounds(2017 + comboBoxXMargin - comboBox3Width / 2, 242 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + m_saturationCurve.setBounds(2017 + comboBoxXMargin - comboBox3Width / 2, 353 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + m_keyFollowBase.setBounds(1876 + comboBoxXMargin - comboBox2Width / 2, 303 - comboBox2Height / 2, + comboBox2Width, comboBox2Height); + + addAndMakeVisible(m_filterMode1); + addAndMakeVisible(m_filterMode2); + addAndMakeVisible(m_filterRouting); + addAndMakeVisible(m_saturationCurve); + addAndMakeVisible(m_keyFollowBase); + + m_envPol1.setBounds(2166 - m_envPol1.kWidth / 2, 241 - m_envPol1.kHeight / 2, m_envPol1.kWidth, + m_envPol1.kHeight); + m_envPol2.setBounds(2166 - m_envPol2.kWidth / 2, 351 - m_envPol2.kHeight / 2, m_envPol2.kWidth, + m_envPol2.kHeight); + m_link1.setBounds(1401 - m_link1.kWidth / 2, 302 - m_link1.kHeight / 2, m_link1.kWidth, m_link1.kHeight); + m_link2.setBounds(2266 - m_link2.kWidth / 2, 302 - m_link2.kHeight / 2, m_link2.kWidth, m_link2.kHeight); + + addAndMakeVisible(m_envPol1); + addAndMakeVisible(m_envPol2); + addAndMakeVisible(m_link1); + addAndMakeVisible(m_link2); + + _parameterBinding.bind(m_cutoff1, Virus::Param_FilterCutA); + _parameterBinding.bind(m_res1, Virus::Param_FilterResA); + _parameterBinding.bind(m_envAmount1, Virus::Param_FilterEnvAmtA); + _parameterBinding.bind(m_keyTrack1, Virus::Param_FilterKeyFollowA); + _parameterBinding.bind(m_resVel1, Virus::Param_Resonance1Velocity); + _parameterBinding.bind(m_envVel1, Virus::Param_Filter1EnvAmtVelocity); + _parameterBinding.bind(m_cutoff2, Virus::Param_FilterCutB); + _parameterBinding.bind(m_res2, Virus::Param_FilterResB); + _parameterBinding.bind(m_envAmount2, Virus::Param_FilterEnvAmtB); + _parameterBinding.bind(m_keyTrack2, Virus::Param_FilterKeyFollowB); + _parameterBinding.bind(m_resVel2, Virus::Param_Resonance2Velocity); + _parameterBinding.bind(m_envVel2, Virus::Param_Filter2EnvAmtVelocity); + _parameterBinding.bind(m_filterBalance, Virus::Param_FilterBalance); + + _parameterBinding.bind(m_filterMode1, Virus::Param_FilterModeA); + _parameterBinding.bind(m_filterMode2, Virus::Param_FilterModeB); + _parameterBinding.bind(m_filterRouting, Virus::Param_FilterRouting); + _parameterBinding.bind(m_saturationCurve, Virus::Param_SaturationCurve); + _parameterBinding.bind(m_keyFollowBase, Virus::Param_FilterKeytrackBase); + + _parameterBinding.bind(m_envPol1, Virus::Param_Filter1EnvPolarity); + _parameterBinding.bind(m_envPol2, Virus::Param_Filter2EnvPolarity); + _parameterBinding.bind(m_link1, Virus::Param_Filter2CutoffLink); + // todo no parameter for link2! + //_parameterBinding.bind(m_link2, Virus::Param_Filter ); + + // Env filter + for (auto *s : {&m_fltAttack, &m_fltDecay, &m_fltSustain, &m_fltTime, &m_fltRelease}) + { + setupRotary(*this, *s); + } + + m_fltAttack.setBounds(1474 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); + m_fltDecay.setBounds(1648 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); + m_fltSustain.setBounds(1830 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); + m_fltTime.setBounds(2016 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); + m_fltRelease.setBounds(2193 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); + + _parameterBinding.bind(m_fltAttack, Virus::Param_FilterEnvAttack); + _parameterBinding.bind(m_fltDecay, Virus::Param_FilterEnvDecay); + _parameterBinding.bind(m_fltSustain, Virus::Param_FilterEnvSustain); + _parameterBinding.bind(m_fltTime, Virus::Param_FilterEnvSustainTime); + _parameterBinding.bind(m_fltRelease, Virus::Param_FilterEnvRelease); + + // Env Amp + for (auto *s : {&m_ampAttack, &m_ampDecay, &m_ampSustain, &m_ampTime, &m_ampRelease}) + { + setupRotary(*this, *s); + } + + m_ampAttack.setBounds(1474 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); + m_ampDecay.setBounds(1648 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); + m_ampSustain.setBounds(1830 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); + m_ampTime.setBounds(2016 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); + m_ampRelease.setBounds(2193 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); + + _parameterBinding.bind(m_ampAttack, Virus::Param_AmpEnvAttack); + _parameterBinding.bind(m_ampDecay, Virus::Param_AmpEnvDecay); + _parameterBinding.bind(m_ampSustain, Virus::Param_AmpEnvSustain); + _parameterBinding.bind(m_ampTime, Virus::Param_AmpEnvSustainTime); + _parameterBinding.bind(m_ampRelease, Virus::Param_AmpEnvRelease); } - m_osc1ShapeVelocity.setBounds(1067 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_osc2ShapeVelocity.setBounds(1067 - knobSize / 2, 264 - knobSize / 2, knobSize, knobSize); - m_pulseWidthVelocity.setBounds(1067 - knobSize / 2, 421 - knobSize / 2, knobSize, knobSize); - m_fmAmountVelocity.setBounds(1067 - knobSize / 2, 579 - knobSize / 2, knobSize, knobSize); - m_ampVelocity.setBounds(1067 - knobSize / 2, 743 - knobSize / 2, knobSize, knobSize); - m_panoramaVelocity.setBounds(1067 - knobSize / 2, 903 - knobSize / 2, knobSize, knobSize); - - _parameterBinding.bind(m_osc1ShapeVelocity, Virus::Param_Osc1ShapeVelocity); - _parameterBinding.bind(m_pulseWidthVelocity, Virus::Param_PulseWidthVelocity); - _parameterBinding.bind(m_ampVelocity, Virus::Param_AmpVelocity); - _parameterBinding.bind(m_panoramaVelocity, Virus::Param_PanoramaVelocity); - _parameterBinding.bind(m_osc2ShapeVelocity, Virus::Param_Osc2ShapeVelocity); - _parameterBinding.bind(m_fmAmountVelocity, Virus::Param_FmAmountVelocity); - - //Filters - for (auto *s : {&m_cutoff1, &m_res1, &m_envAmount1, &m_keyTrack1, &m_resVel1, &m_envVel1, &m_cutoff2, &m_res2, &m_envAmount2, &m_keyTrack2, &m_resVel2, &m_envVel2, &m_filterBalance}) - { - setupRotary(*this, *s); - } - - m_cutoff1.setBounds(1474 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_res1.setBounds(1618 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_envAmount1.setBounds(1762 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_keyTrack1.setBounds(1909 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_resVel1.setBounds(2053 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_envVel1.setBounds(2193 - knobSize / 2, 102 - knobSize / 2, knobSize, knobSize); - m_cutoff2.setBounds(1474 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_res2.setBounds(1618 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_envAmount2.setBounds(1762 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_keyTrack2.setBounds(1909 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_resVel2.setBounds(2053 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_envVel2.setBounds(2193 - knobSize / 2, 485 - knobSize / 2, knobSize, knobSize); - m_filterBalance.setBounds(1522 - knobSize / 2, 302 - knobSize / 2, knobSize, knobSize); - - m_filterMode1.setBounds(1710+comboBoxXMargin - comboBox3Width / 2, 239 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - m_filterMode2.setBounds(1710+comboBoxXMargin - comboBox3Width / 2, 353 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - m_filterRouting.setBounds(2017+comboBoxXMargin - comboBox3Width / 2, 242 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - m_saturationCurve.setBounds(2017+comboBoxXMargin - comboBox3Width / 2, 353 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - m_keyFollowBase.setBounds(1876+comboBoxXMargin - comboBox2Width / 2, 303 - comboBox2Height / 2, comboBox2Width, comboBox2Height); - - addAndMakeVisible(m_filterMode1); - addAndMakeVisible(m_filterMode2); - addAndMakeVisible(m_filterRouting); - addAndMakeVisible(m_saturationCurve); - addAndMakeVisible(m_keyFollowBase); - - m_envPol1.setBounds(2166 - m_envPol1.kWidth / 2, 241 - m_envPol1.kHeight / 2, m_envPol1.kWidth, m_envPol1.kHeight); - m_envPol2.setBounds(2166 - m_envPol2.kWidth / 2, 351 - m_envPol2.kHeight / 2, m_envPol2.kWidth, m_envPol2.kHeight); - m_link1.setBounds(1401 - m_link1.kWidth / 2, 302 - m_link1.kHeight / 2, m_link1.kWidth, m_link1.kHeight); - m_link2.setBounds(2266 - m_link2.kWidth / 2, 302 - m_link2.kHeight / 2, m_link2.kWidth, m_link2.kHeight); - - addAndMakeVisible(m_envPol1); - addAndMakeVisible(m_envPol2); - addAndMakeVisible(m_link1); - addAndMakeVisible(m_link2); - - _parameterBinding.bind(m_cutoff1, Virus::Param_FilterCutA); - _parameterBinding.bind(m_res1, Virus::Param_FilterResA); - _parameterBinding.bind(m_envAmount1, Virus::Param_FilterEnvAmtA); - _parameterBinding.bind(m_keyTrack1, Virus::Param_FilterKeyFollowA); - _parameterBinding.bind(m_resVel1, Virus::Param_Resonance1Velocity); - _parameterBinding.bind(m_envVel1, Virus::Param_Filter1EnvAmtVelocity); - _parameterBinding.bind(m_cutoff2, Virus::Param_FilterCutB); - _parameterBinding.bind(m_res2, Virus::Param_FilterResB); - _parameterBinding.bind(m_envAmount2, Virus::Param_FilterEnvAmtB); - _parameterBinding.bind(m_keyTrack2, Virus::Param_FilterKeyFollowB); - _parameterBinding.bind(m_resVel2, Virus::Param_Resonance2Velocity); - _parameterBinding.bind(m_envVel2, Virus::Param_Filter2EnvAmtVelocity); - _parameterBinding.bind(m_filterBalance, Virus::Param_FilterBalance); - - _parameterBinding.bind(m_filterMode1, Virus::Param_FilterModeA); - _parameterBinding.bind(m_filterMode2, Virus::Param_FilterModeB); - _parameterBinding.bind(m_filterRouting, Virus::Param_FilterRouting); - _parameterBinding.bind(m_saturationCurve, Virus::Param_SaturationCurve); - _parameterBinding.bind(m_keyFollowBase, Virus::Param_FilterKeytrackBase); - - _parameterBinding.bind(m_envPol1, Virus::Param_Filter1EnvPolarity); - _parameterBinding.bind(m_envPol2, Virus::Param_Filter2EnvPolarity); - _parameterBinding.bind(m_link1, Virus::Param_Filter2CutoffLink); - //todo no parameter for link2! - //_parameterBinding.bind(m_link2, Virus::Param_Filter ); - - //Env filter - for (auto *s : {&m_fltAttack, &m_fltDecay, &m_fltSustain, &m_fltTime, &m_fltRelease}) - { - setupRotary(*this, *s); - } - - m_fltAttack.setBounds(1474 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); - m_fltDecay.setBounds(1648 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); - m_fltSustain.setBounds(1830 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); - m_fltTime.setBounds(2016 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); - m_fltRelease.setBounds(2193 - knobSize / 2, 695 - knobSize / 2, knobSize, knobSize); - - _parameterBinding.bind(m_fltAttack, Virus::Param_FilterEnvAttack); - _parameterBinding.bind(m_fltDecay, Virus::Param_FilterEnvDecay); - _parameterBinding.bind(m_fltSustain, Virus::Param_FilterEnvSustain); - _parameterBinding.bind(m_fltTime, Virus::Param_FilterEnvSustainTime); - _parameterBinding.bind(m_fltRelease, Virus::Param_FilterEnvRelease); - - //Env Amp - for (auto *s : {&m_ampAttack, &m_ampDecay, &m_ampSustain, &m_ampTime, &m_ampRelease}) - { - setupRotary(*this, *s); - } - - m_ampAttack.setBounds(1474 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); - m_ampDecay.setBounds(1648 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); - m_ampSustain.setBounds(1830 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); - m_ampTime.setBounds(2016 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); - m_ampRelease.setBounds(2193 - knobSize / 2, 904 - knobSize / 2, knobSize, knobSize); - - _parameterBinding.bind(m_ampAttack, Virus::Param_AmpEnvAttack); - _parameterBinding.bind(m_ampDecay, Virus::Param_AmpEnvDecay); - _parameterBinding.bind(m_ampSustain, Virus::Param_AmpEnvSustain); - _parameterBinding.bind(m_ampTime, Virus::Param_AmpEnvSustainTime); - _parameterBinding.bind(m_ampRelease, Virus::Param_AmpEnvRelease); -} - -void OscEditor::resized() -{ -} -\ No newline at end of file + void OscEditor::resized() {} +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel1_OscEditor.h b/source/jucePlugin/ui2/Virus_Panel1_OscEditor.h @@ -2,65 +2,68 @@ #include "../PluginProcessor.h" #include "Virus_Buttons.h" - class VirusParameterBinding; - -class OscEditor : public juce::Component +namespace Trancy { -public: - OscEditor(VirusParameterBinding& _parameterBinding); - void resized() override; -private: - - // OSC1 - juce::Slider m_osc1Shape, m_osc1PulseWidth, m_osc1Semitone, m_osc1KeyFollow; - juce::ComboBox m_osc1WaveSelect; + class OscEditor : public juce::Component + { + public: + OscEditor(VirusParameterBinding &_parameterBinding); + void resized() override; + + private: + // OSC1 + juce::Slider m_osc1Shape, m_osc1PulseWidth, m_osc1Semitone, m_osc1KeyFollow; + juce::ComboBox m_osc1WaveSelect; + + // OSC2 + juce::Slider m_osc2Shape, m_osc2PulseWidth, m_osc2Semitone, m_osc2KeyFollow; + juce::ComboBox m_osc2WaveSelect; + + juce::Slider m_osc2FmAmount, m_osc2Detune, m_osc2EnvFm, m_osc2envOSC, m_osc2PhaseInit; + juce::ComboBox m_osc2FmMode; - // OSC2 - juce::Slider m_osc2Shape,m_osc2PulseWidth,m_osc2Semitone,m_osc2KeyFollow; - juce::ComboBox m_osc2WaveSelect; + Buttons::Button3 m_syncOsc1Osc2; - juce::Slider m_osc2FmAmount, m_osc2Detune, m_osc2EnvFm, m_osc2envOSC, m_osc2PhaseInit; - juce::ComboBox m_osc2FmMode; - - Buttons::Button3 m_syncOsc1Osc2; + // OSC3 + juce::Slider m_osc3Semitone, m_osc3Detune; + juce::ComboBox m_osc3Mode; - // OSC3 - juce::Slider m_osc3Semitone,m_osc3Detune; - juce::ComboBox m_osc3Mode; + // OSC Sub + Buttons::Button2 m_subWaveform; + juce::Slider m_noiseColor; - // OSC Sub - Buttons::Button2 m_subWaveform; - juce::Slider m_noiseColor; + // Unison + juce::Slider m_detune, m_panSpread, m_lfoPhase; + juce::ComboBox m_unisonVoices; - // Unison - juce::Slider m_detune, m_panSpread,m_lfoPhase; - juce::ComboBox m_unisonVoices; + // Punch + juce::Slider m_Punch; - // Punch - juce::Slider m_Punch; + // Mixer : juce::Component + juce::Slider m_oscBalance, m_oscLevel, m_osc3Level, m_oscSublevel, m_noiseLevel, m_ringModLevel; - // Mixer : juce::Component - juce::Slider m_oscBalance,m_oscLevel,m_osc3Level, m_oscSublevel, m_noiseLevel,m_ringModLevel; + // Vel + juce::Slider m_osc1ShapeVelocity, m_pulseWidthVelocity, m_ampVelocity, m_panoramaVelocity, m_osc2ShapeVelocity, + m_fmAmountVelocity; - // Vel - juce::Slider m_osc1ShapeVelocity,m_pulseWidthVelocity,m_ampVelocity, m_panoramaVelocity,m_osc2ShapeVelocity,m_fmAmountVelocity; + // Filters + juce::Slider m_cutoff1, m_res1, m_envAmount1, m_keyTrack1, m_resVel1, m_envVel1; + juce::Slider m_cutoff2, m_res2, m_envAmount2, m_keyTrack2, m_resVel2, m_envVel2; + juce::Slider m_filterBalance; - // Filters - juce::Slider m_cutoff1,m_res1, m_envAmount1,m_keyTrack1,m_resVel1,m_envVel1; - juce::Slider m_cutoff2,m_res2, m_envAmount2, m_keyTrack2,m_resVel2,m_envVel2; - juce::Slider m_filterBalance; + Buttons::Button2 m_envPol1, m_envPol2; + Buttons::Button1 m_link1, m_link2; + juce::ComboBox m_filterMode1, m_filterMode2, m_filterRouting, m_saturationCurve, m_keyFollowBase; - Buttons::Button2 m_envPol1, m_envPol2; - Buttons::Button1 m_link1, m_link2; - juce::ComboBox m_filterMode1, m_filterMode2, m_filterRouting, m_saturationCurve, m_keyFollowBase; + // Filter Envelope + juce::Slider m_fltAttack, m_fltDecay, m_fltSustain, m_fltTime, m_fltRelease; - // Filter Envelope - juce::Slider m_fltAttack,m_fltDecay, m_fltSustain,m_fltTime,m_fltRelease; + // Amp Envelope + juce::Slider m_ampAttack, m_ampDecay, m_ampSustain, m_ampTime, m_ampRelease; - // Amp Envelope - juce::Slider m_ampAttack,m_ampDecay,m_ampSustain,m_ampTime,m_ampRelease; + std::unique_ptr<juce::Drawable> m_background; + }; - std::unique_ptr<juce::Drawable> m_background; -}; +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel2_LfoEditor.cpp b/source/jucePlugin/ui2/Virus_Panel2_LfoEditor.cpp @@ -3,243 +3,288 @@ #include "Ui_Utils.h" #include "../VirusParameterBinding.h" -using namespace juce; - - -LfoEditor::LfoEditor(VirusParameterBinding& _parameterBinding) +namespace Trancy { - setupBackground(*this, m_background, BinaryData::panel_2_png, BinaryData::panel_2_pngSize); - setBounds(m_background->getDrawableBounds().toNearestIntEdges()); + using namespace juce; - //LFO 1 - for (auto *s : {&m_lfo1Rate, &m_lfo1Symmetry, &m_lfo1Osc1Pitch, &m_lfo1Osc2Pitch, &m_lfo1Pw12, &m_lfo1Reso12, - &m_lfo1KeyFollow, &m_lfo1Keytrigger, &m_lfo1AssignAmount, &m_lfo1FilterGain}) - { - setupRotary(*this, *s); - } - m_lfo1Rate.setBounds(102 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); - m_lfo1Symmetry.setBounds(417 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); - m_lfo1Osc1Pitch.setBounds(102 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo1Osc2Pitch.setBounds(262 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo1Pw12.setBounds(417 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo1Reso12.setBounds(102 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); - m_lfo1KeyFollow.setBounds(258 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); - m_lfo1Keytrigger.setBounds(417 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); - m_lfo1AssignAmount.setBounds(102 - knobSize / 2, 705 - knobSize / 2, knobSize, knobSize); - m_lfo1FilterGain.setBounds(417 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_lfo1Clock); - m_lfo1Clock.setBounds(258+comboBoxXMargin - comboBoxWidth / 2, 84 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - addAndMakeVisible(m_lfo1Shape); - m_lfo1Shape.setBounds(258+comboBoxXMargin - comboBoxWidth / 2, 169 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - addAndMakeVisible(m_lfo1AssignDest); - m_lfo1AssignDest.setBounds(283+comboBoxXMargin - comboBox3Width / 2, 700 - comboBoxHeight / 2, comboBox3Width, comboBoxHeight); - - addAndMakeVisible(m_lfo1Link); - m_lfo1Link.setBounds(177 - m_lfo1Link.kWidth / 2, 416 - m_lfo1Link.kHeight / 2, m_lfo1Link.kWidth, m_lfo1Link.kHeight); - addAndMakeVisible(m_lfo1LfoMode); - m_lfo1LfoMode.setBounds(102 - m_lfo1LfoMode.kWidth / 2, 879 - m_lfo1LfoMode.kHeight / 2, m_lfo1LfoMode.kWidth, m_lfo1LfoMode.kHeight); - addAndMakeVisible(m_lfo1EnvMode); - m_lfo1EnvMode.setBounds(442 - m_lfo1EnvMode.kWidth / 2, 701 - m_lfo1EnvMode.kHeight / 2, m_lfo1EnvMode.kWidth, m_lfo1EnvMode.kHeight); - - _parameterBinding.bind(m_lfo1Rate, Virus::Param_Lfo1Rate); - _parameterBinding.bind(m_lfo1Symmetry, Virus::Param_Lfo1Symmetry); - _parameterBinding.bind(m_lfo1Osc1Pitch, Virus::Param_Osc1Lfo1Amount); - _parameterBinding.bind(m_lfo1Osc2Pitch, Virus::Param_Osc2Lfo1Amount); - _parameterBinding.bind(m_lfo1Pw12, Virus::Param_PWLfo1Amount); - _parameterBinding.bind(m_lfo1Reso12, Virus::Param_ResoLfo1Amount); - _parameterBinding.bind(m_lfo1KeyFollow, Virus::Param_Lfo1Keyfollow); - _parameterBinding.bind(m_lfo1Keytrigger, Virus::Param_Lfo1KeyTrigger); - _parameterBinding.bind(m_lfo1AssignAmount, Virus::Param_Lfo1AssignAmount); - _parameterBinding.bind(m_lfo1FilterGain, Virus::Param_FltGainLfo1Amount); - - _parameterBinding.bind(m_lfo1Clock, Virus::Param_Lfo1Clock); - _parameterBinding.bind(m_lfo1Shape, Virus::Param_Lfo1Shape); - _parameterBinding.bind(m_lfo1AssignDest, Virus::Param_Lfo1AssignDest); - - //todo no link! _parameterBinding.bind(m_lfo1Link, Virus::lfo); - _parameterBinding.bind(m_lfo1LfoMode, Virus::Param_Lfo1Mode); - _parameterBinding.bind(m_lfo1EnvMode, Virus::Param_Lfo1EnvMode); - - // LFO 2 - for (auto *s : {&m_lfo2Rate, &m_lfo2Symmetry, &m_lfo2Filter1Cutoff, &m_lfo2Filter2Cutoff, &m_lfo2Shape12, - &m_lfo2Panorama, &m_lfo2KeyFollow, &m_lfo2Keytrigger, &m_lfo2AssignAmount, &m_lfo2AmtFM}) + LfoEditor::LfoEditor(VirusParameterBinding &_parameterBinding) { - setupRotary(*this, *s); + setupBackground(*this, m_background, BinaryData::panel_2_png, BinaryData::panel_2_pngSize); + setBounds(m_background->getDrawableBounds().toNearestIntEdges()); + + // LFO 1 + for (auto *s : {&m_lfo1Rate, &m_lfo1Symmetry, &m_lfo1Osc1Pitch, &m_lfo1Osc2Pitch, &m_lfo1Pw12, &m_lfo1Reso12, + &m_lfo1KeyFollow, &m_lfo1Keytrigger, &m_lfo1AssignAmount, &m_lfo1FilterGain}) + { + setupRotary(*this, *s); + } + + m_lfo1Rate.setBounds(102 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); + m_lfo1Symmetry.setBounds(417 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); + m_lfo1Osc1Pitch.setBounds(102 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo1Osc2Pitch.setBounds(262 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo1Pw12.setBounds(417 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo1Reso12.setBounds(102 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); + m_lfo1KeyFollow.setBounds(258 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); + m_lfo1Keytrigger.setBounds(417 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); + m_lfo1AssignAmount.setBounds(102 - knobSize / 2, 705 - knobSize / 2, knobSize, knobSize); + m_lfo1FilterGain.setBounds(417 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_lfo1Clock); + m_lfo1Clock.setBounds(258 + comboBoxXMargin - comboBoxWidth / 2, 84 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + addAndMakeVisible(m_lfo1Shape); + m_lfo1Shape.setBounds(258 + comboBoxXMargin - comboBoxWidth / 2, 169 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + addAndMakeVisible(m_lfo1AssignDest); + m_lfo1AssignDest.setBounds(283 + comboBoxXMargin - comboBox3Width / 2, 700 - comboBoxHeight / 2, comboBox3Width, + comboBoxHeight); + + addAndMakeVisible(m_lfo1Link); + m_lfo1Link.setBounds(177 - m_lfo1Link.kWidth / 2, 416 - m_lfo1Link.kHeight / 2, m_lfo1Link.kWidth, + m_lfo1Link.kHeight); + addAndMakeVisible(m_lfo1LfoMode); + m_lfo1LfoMode.setBounds(102 - m_lfo1LfoMode.kWidth / 2, 879 - m_lfo1LfoMode.kHeight / 2, m_lfo1LfoMode.kWidth, + m_lfo1LfoMode.kHeight); + addAndMakeVisible(m_lfo1EnvMode); + m_lfo1EnvMode.setBounds(442 - m_lfo1EnvMode.kWidth / 2, 701 - m_lfo1EnvMode.kHeight / 2, m_lfo1EnvMode.kWidth, + m_lfo1EnvMode.kHeight); + + _parameterBinding.bind(m_lfo1Rate, Virus::Param_Lfo1Rate); + _parameterBinding.bind(m_lfo1Symmetry, Virus::Param_Lfo1Symmetry); + _parameterBinding.bind(m_lfo1Osc1Pitch, Virus::Param_Osc1Lfo1Amount); + _parameterBinding.bind(m_lfo1Osc2Pitch, Virus::Param_Osc2Lfo1Amount); + _parameterBinding.bind(m_lfo1Pw12, Virus::Param_PWLfo1Amount); + _parameterBinding.bind(m_lfo1Reso12, Virus::Param_ResoLfo1Amount); + _parameterBinding.bind(m_lfo1KeyFollow, Virus::Param_Lfo1Keyfollow); + _parameterBinding.bind(m_lfo1Keytrigger, Virus::Param_Lfo1KeyTrigger); + _parameterBinding.bind(m_lfo1AssignAmount, Virus::Param_Lfo1AssignAmount); + _parameterBinding.bind(m_lfo1FilterGain, Virus::Param_FltGainLfo1Amount); + + _parameterBinding.bind(m_lfo1Clock, Virus::Param_Lfo1Clock); + _parameterBinding.bind(m_lfo1Shape, Virus::Param_Lfo1Shape); + _parameterBinding.bind(m_lfo1AssignDest, Virus::Param_Lfo1AssignDest); + + // todo no link! _parameterBinding.bind(m_lfo1Link, Virus::lfo); + _parameterBinding.bind(m_lfo1LfoMode, Virus::Param_Lfo1Mode); + _parameterBinding.bind(m_lfo1EnvMode, Virus::Param_Lfo1EnvMode); + + // LFO 2 + for (auto *s : {&m_lfo2Rate, &m_lfo2Symmetry, &m_lfo2Filter1Cutoff, &m_lfo2Filter2Cutoff, &m_lfo2Shape12, + &m_lfo2Panorama, &m_lfo2KeyFollow, &m_lfo2Keytrigger, &m_lfo2AssignAmount, &m_lfo2AmtFM}) + { + setupRotary(*this, *s); + } + + m_lfo2Rate.setBounds(102 + 532 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); + m_lfo2Symmetry.setBounds(417 + 532 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); + m_lfo2Filter1Cutoff.setBounds(102 + 532 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo2Filter2Cutoff.setBounds(262 + 532 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo2Shape12.setBounds(417 + 532 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo2Panorama.setBounds(102 + 532 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); + m_lfo2KeyFollow.setBounds(258 + 532 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); + m_lfo2Keytrigger.setBounds(417 + 532 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); + m_lfo2AssignAmount.setBounds(102 + 532 - knobSize / 2, 705 - knobSize / 2, knobSize, knobSize); + m_lfo2AmtFM.setBounds(417 + 532 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_lfo2Clock); + m_lfo2Clock.setBounds(258 + 532 + comboBoxXMargin - comboBoxWidth / 2, 84 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + addAndMakeVisible(m_lfo2Shape); + m_lfo2Shape.setBounds(258 + 532 + comboBoxXMargin - comboBoxWidth / 2, 169 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + addAndMakeVisible(m_lfo2AssignDest); + m_lfo2AssignDest.setBounds(283 + 532 + comboBoxXMargin - comboBox3Width / 2, 700 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + addAndMakeVisible(m_lfo2Link); + m_lfo2Link.setBounds(177 + 532 - m_lfo2Link.kWidth / 2, 416 - m_lfo2Link.kHeight / 2, m_lfo2Link.kWidth, + m_lfo2Link.kHeight); + addAndMakeVisible(m_lfo2LfoMode); + m_lfo2LfoMode.setBounds(102 + 532 - m_lfo2LfoMode.kWidth / 2, 879 - m_lfo2LfoMode.kHeight / 2, + m_lfo2LfoMode.kWidth, m_lfo2LfoMode.kHeight); + addAndMakeVisible(m_lfo2EnvMode); + m_lfo2EnvMode.setBounds(442 + 532 - m_lfo2EnvMode.kWidth / 2, 701 - m_lfo2EnvMode.kHeight / 2, + m_lfo2EnvMode.kWidth, m_lfo2EnvMode.kHeight); + + _parameterBinding.bind(m_lfo2Rate, Virus::Param_Lfo2Rate); + _parameterBinding.bind(m_lfo2Symmetry, Virus::Param_Lfo2Symmetry); + _parameterBinding.bind(m_lfo2Filter1Cutoff, Virus::Param_Cutoff1Lfo2Amount); + _parameterBinding.bind(m_lfo2Filter2Cutoff, Virus::Param_Cutoff2Lfo2Amount); + _parameterBinding.bind(m_lfo2Shape12, Virus::Param_OscShapeLfo2Amount); + _parameterBinding.bind(m_lfo2Panorama, Virus::Param_PanoramaLfo2Amount); + _parameterBinding.bind(m_lfo2KeyFollow, Virus::Param_Lfo2Keyfollow); + _parameterBinding.bind(m_lfo2Keytrigger, Virus::Param_Lfo2Keytrigger); + _parameterBinding.bind(m_lfo2AssignAmount, Virus::Param_Lfo2AssignAmount); + _parameterBinding.bind(m_lfo2AmtFM, Virus::Param_FmAmountLfo2Amount); + + _parameterBinding.bind(m_lfo2Clock, Virus::Param_Lfo2Clock); + _parameterBinding.bind(m_lfo2Shape, Virus::Param_Lfo2Shape); + _parameterBinding.bind(m_lfo2AssignDest, Virus::Param_Lfo2AssignDest); + + // todo no link! _parameterBinding.bind(m_lfo2Link, Virus::lfo); + _parameterBinding.bind(m_lfo2LfoMode, Virus::Param_Lfo2Mode); + _parameterBinding.bind(m_lfo2EnvMode, Virus::Param_Lfo2EnvMode); + + + // LFO 3 + for (auto *s : { + &m_lfo3Rate, + &m_lfo3FadeIn, + &m_lfo3KeyFollow, + &m_lfo3AssignAmount, + }) + { + setupRotary(*this, *s); + } + + m_lfo3Rate.setBounds(1166 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); + m_lfo3FadeIn.setBounds(1166 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo3KeyFollow.setBounds(1322 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); + m_lfo3AssignAmount.setBounds(1166 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_lfo3Clock); + m_lfo3Clock.setBounds(1322 + comboBoxXMargin - comboBoxWidth / 2, 84 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + addAndMakeVisible(m_lfo3Shape); + m_lfo3Shape.setBounds(1322 + comboBoxXMargin - comboBoxWidth / 2, 169 - comboBoxHeight / 2, comboBoxWidth, + comboBoxHeight); + addAndMakeVisible(m_lfo3AssignDest); + m_lfo3AssignDest.setBounds(1211 + comboBoxXMargin - comboBox3Width / 2, 675 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + addAndMakeVisible(m_lfo3LfoMode); + m_lfo3LfoMode.setBounds(1305 - m_lfo3LfoMode.kWidth / 2, 509 - m_lfo3LfoMode.kHeight / 2, m_lfo3LfoMode.kWidth, + m_lfo3LfoMode.kHeight); + + _parameterBinding.bind(m_lfo3Rate, Virus::Param_Lfo3Rate); + _parameterBinding.bind(m_lfo3FadeIn, Virus::Param_Lfo3FadeInTime); + _parameterBinding.bind(m_lfo3KeyFollow, Virus::Param_Lfo3Keyfollow); + _parameterBinding.bind(m_lfo3AssignAmount, Virus::Param_OscLfo3Amount); + + _parameterBinding.bind(m_lfo3Clock, Virus::Param_Lfo3Clock); + _parameterBinding.bind(m_lfo3Shape, Virus::Param_Lfo3Shape); + _parameterBinding.bind(m_lfo3AssignDest, Virus::Param_Lfo3Destination); + + // todo no link! _parameterBinding.bind(m_lfo3Link, Virus::lfo); + _parameterBinding.bind(m_lfo3LfoMode, Virus::Param_Lfo3Mode); + + // Matrix Slo1 + for (auto *s : { + &m_MatSlot1Amount1, + &m_MatSlot1Amount2, + &m_MatSlot1Amount3, + &m_MatSlot1Amount4, + }) + { + setupRotary(*this, *s); + } + + m_MatSlot1Amount1.setBounds(1792 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); + m_MatSlot1Amount2.setBounds(2197 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); + m_MatSlot1Amount3.setBounds(1792 - knobSize / 2, 355 - knobSize / 2, knobSize, knobSize); + m_MatSlot1Amount4.setBounds(2197 - knobSize / 2, 355 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_MatSlot1Source1); + m_MatSlot1Source1.setBounds(1597 + comboBoxXMargin - comboBox3Width / 2, 82 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot1Source2); + m_MatSlot1Source2.setBounds(2002 + comboBoxXMargin - comboBox3Width / 2, 82 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot1Source3); + m_MatSlot1Source3.setBounds(1597 + comboBoxXMargin - comboBox3Width / 2, 313 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot1Source4); + m_MatSlot1Source4.setBounds(2002 + comboBoxXMargin - comboBox3Width / 2, 313 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot1AssignDest1); + m_MatSlot1AssignDest1.setBounds(1597 + comboBoxXMargin - comboBox3Width / 2, 171 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot1AssignDest2); + m_MatSlot1AssignDest2.setBounds(2002 + comboBoxXMargin - comboBox3Width / 2, 171 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot1AssignDest3); + m_MatSlot1AssignDest3.setBounds(1597 + comboBoxXMargin - comboBox3Width / 2, 400 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot1AssignDest4); + m_MatSlot1AssignDest4.setBounds(2002 + comboBoxXMargin - comboBox3Width / 2, 400 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + _parameterBinding.bind(m_MatSlot1Source1, Virus::Param_Assign1Source); + _parameterBinding.bind(m_MatSlot1Source2, Virus::Param_Assign4Source); + _parameterBinding.bind(m_MatSlot1Source3, Virus::Param_Assign5Source); + _parameterBinding.bind(m_MatSlot1Source4, Virus::Param_Assign6Source); + _parameterBinding.bind(m_MatSlot1Amount1, Virus::Param_Assign1Amount); + _parameterBinding.bind(m_MatSlot1Amount2, Virus::Param_Assign4Amount); + _parameterBinding.bind(m_MatSlot1Amount3, Virus::Param_Assign5Amount); + _parameterBinding.bind(m_MatSlot1Amount4, Virus::Param_Assign6Amount); + _parameterBinding.bind(m_MatSlot1AssignDest1, Virus::Param_Assign1Destination); + _parameterBinding.bind(m_MatSlot1AssignDest2, Virus::Param_Assign4Destination); + _parameterBinding.bind(m_MatSlot1AssignDest3, Virus::Param_Assign5Destination); + _parameterBinding.bind(m_MatSlot1AssignDest4, Virus::Param_Assign6Destination); + + // Matrix Slot 2 + for (auto *s : {&m_MatSlot2Amount1, &m_MatSlot2Amount2}) + { + setupRotary(*this, *s); + } + + m_MatSlot2Amount1.setBounds(1792 - knobSize / 2, 624 - knobSize / 2, knobSize, knobSize); + m_MatSlot2Amount2.setBounds(2197 - knobSize / 2, 624 - knobSize / 2, knobSize, knobSize); + addAndMakeVisible(m_MatSlot2Source12); + m_MatSlot2Source12.setBounds(1597 + comboBoxXMargin - comboBox3Width / 2, 576 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot2AssignDest1); + m_MatSlot2AssignDest1.setBounds(1597 + comboBoxXMargin - comboBox3Width / 2, 666 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + addAndMakeVisible(m_MatSlot2AssignDest2); + m_MatSlot2AssignDest2.setBounds(2002 + comboBoxXMargin - comboBox3Width / 2, 624 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + _parameterBinding.bind(m_MatSlot2Source12, Virus::Param_Assign2Source); + _parameterBinding.bind(m_MatSlot2Amount1, Virus::Param_Assign2Amount1); + _parameterBinding.bind(m_MatSlot2Amount2, Virus::Param_Assign2Amount2); + _parameterBinding.bind(m_MatSlot2AssignDest1, Virus::Param_Assign2Destination1); + _parameterBinding.bind(m_MatSlot2AssignDest2, Virus::Param_Assign2Destination2); + + + // Matrix Slot 3 + for (auto *s : {&m_MatSlot3Amount1, &m_MatSlot3Amount2, &m_MatSlot3Amount3}) + { + setupRotary(*this, *s); + } + + m_MatSlot3Amount1.setBounds(1404 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); + m_MatSlot3Amount2.setBounds(1792 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); + m_MatSlot3Amount3.setBounds(2197 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_MatSlot3Source123); + m_MatSlot3Source123.setBounds(1210 + comboBoxXMargin - comboBox3Width / 2, 838 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + addAndMakeVisible(m_MatSlot3AssignDest1); + m_MatSlot3AssignDest1.setBounds(1210 + comboBoxXMargin - comboBox3Width / 2, 928 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + addAndMakeVisible(m_MatSlot3AssignDest2); + m_MatSlot3AssignDest2.setBounds(1596 + comboBoxXMargin - comboBox3Width / 2, 888 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + addAndMakeVisible(m_MatSlot3AssignDest3); + m_MatSlot3AssignDest3.setBounds(2002 + comboBoxXMargin - comboBox3Width / 2, 888 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + _parameterBinding.bind(m_MatSlot3Source123, Virus::Param_Assign3Source); + + _parameterBinding.bind(m_MatSlot3Amount1, Virus::Param_Assign3Amount1); + _parameterBinding.bind(m_MatSlot3Amount2, Virus::Param_Assign3Amount2); + _parameterBinding.bind(m_MatSlot3Amount3, + Virus::Param_Assign2Amount3); // todo: need fix typ --> Param_Assign3Amount3 + + _parameterBinding.bind(m_MatSlot3AssignDest1, Virus::Param_Assign3Destination1); + _parameterBinding.bind(m_MatSlot3AssignDest2, Virus::Param_Assign3Destination2); + _parameterBinding.bind(m_MatSlot3AssignDest3, + Virus::Param_Assign2Destination3); // todo: need fix typ --> Param_Assign3Destination3 } - - m_lfo2Rate.setBounds(102 + 532 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); - m_lfo2Symmetry.setBounds(417 + 532 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); - m_lfo2Filter1Cutoff.setBounds(102 + 532 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo2Filter2Cutoff.setBounds(262 + 532 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo2Shape12.setBounds(417 + 532 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo2Panorama.setBounds(102 + 532 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); - m_lfo2KeyFollow.setBounds(258 + 532 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); - m_lfo2Keytrigger.setBounds(417 + 532 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); - m_lfo2AssignAmount.setBounds(102 + 532 - knobSize / 2, 705 - knobSize / 2, knobSize, knobSize); - m_lfo2AmtFM.setBounds(417 + 532 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_lfo2Clock); - m_lfo2Clock.setBounds(258 + 532 + comboBoxXMargin - comboBoxWidth / 2, 84 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - addAndMakeVisible(m_lfo2Shape); - m_lfo2Shape.setBounds(258 + 532 +comboBoxXMargin - comboBoxWidth / 2, 169 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - addAndMakeVisible(m_lfo2AssignDest); - m_lfo2AssignDest.setBounds(283 + 532 +comboBoxXMargin - comboBox3Width / 2, 700 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_lfo2Link); - m_lfo2Link.setBounds(177 + 532 - m_lfo2Link.kWidth / 2, 416 - m_lfo2Link.kHeight / 2, m_lfo2Link.kWidth, m_lfo2Link.kHeight); - addAndMakeVisible(m_lfo2LfoMode); - m_lfo2LfoMode.setBounds(102 + 532 - m_lfo2LfoMode.kWidth / 2, 879 - m_lfo2LfoMode.kHeight / 2, m_lfo2LfoMode.kWidth, m_lfo2LfoMode.kHeight); - addAndMakeVisible(m_lfo2EnvMode); - m_lfo2EnvMode.setBounds(442 + 532 - m_lfo2EnvMode.kWidth / 2, 701 - m_lfo2EnvMode.kHeight / 2, m_lfo2EnvMode.kWidth, m_lfo2EnvMode.kHeight); - - _parameterBinding.bind(m_lfo2Rate, Virus::Param_Lfo2Rate); - _parameterBinding.bind(m_lfo2Symmetry, Virus::Param_Lfo2Symmetry); - _parameterBinding.bind(m_lfo2Filter1Cutoff, Virus::Param_Cutoff1Lfo2Amount); - _parameterBinding.bind(m_lfo2Filter2Cutoff, Virus::Param_Cutoff2Lfo2Amount); - _parameterBinding.bind(m_lfo2Shape12, Virus::Param_OscShapeLfo2Amount); - _parameterBinding.bind(m_lfo2Panorama, Virus::Param_PanoramaLfo2Amount); - _parameterBinding.bind(m_lfo2KeyFollow, Virus::Param_Lfo2Keyfollow); - _parameterBinding.bind(m_lfo2Keytrigger, Virus::Param_Lfo2Keytrigger); - _parameterBinding.bind(m_lfo2AssignAmount, Virus::Param_Lfo2AssignAmount); - _parameterBinding.bind(m_lfo2AmtFM, Virus::Param_FmAmountLfo2Amount); - - _parameterBinding.bind(m_lfo2Clock, Virus::Param_Lfo2Clock); - _parameterBinding.bind(m_lfo2Shape, Virus::Param_Lfo2Shape); - _parameterBinding.bind(m_lfo2AssignDest, Virus::Param_Lfo2AssignDest); - - // todo no link! _parameterBinding.bind(m_lfo2Link, Virus::lfo); - _parameterBinding.bind(m_lfo2LfoMode, Virus::Param_Lfo2Mode); - _parameterBinding.bind(m_lfo2EnvMode, Virus::Param_Lfo2EnvMode); - - - // LFO 3 - for (auto *s : {&m_lfo3Rate, &m_lfo3FadeIn, &m_lfo3KeyFollow, &m_lfo3AssignAmount,}) - { - setupRotary(*this, *s); - } - - m_lfo3Rate.setBounds(1166 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); - m_lfo3FadeIn.setBounds(1166 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo3KeyFollow.setBounds(1322 - knobSize / 2, 313 - knobSize / 2, knobSize, knobSize); - m_lfo3AssignAmount.setBounds(1166 - knobSize / 2, 517 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_lfo3Clock); - m_lfo3Clock.setBounds(1322+comboBoxXMargin - comboBoxWidth / 2, 84 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - addAndMakeVisible(m_lfo3Shape); - m_lfo3Shape.setBounds(1322+comboBoxXMargin - comboBoxWidth / 2, 169 - comboBoxHeight / 2, comboBoxWidth, comboBoxHeight); - addAndMakeVisible(m_lfo3AssignDest); - m_lfo3AssignDest.setBounds(1211+comboBoxXMargin - comboBox3Width / 2, 675 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_lfo3LfoMode); - m_lfo3LfoMode.setBounds(1305 - m_lfo3LfoMode.kWidth / 2, 509 - m_lfo3LfoMode.kHeight / 2, m_lfo3LfoMode.kWidth, m_lfo3LfoMode.kHeight); - - _parameterBinding.bind(m_lfo3Rate, Virus::Param_Lfo3Rate); - _parameterBinding.bind(m_lfo3FadeIn, Virus::Param_Lfo3FadeInTime); - _parameterBinding.bind(m_lfo3KeyFollow, Virus::Param_Lfo3Keyfollow); - _parameterBinding.bind(m_lfo3AssignAmount, Virus::Param_OscLfo3Amount); - - _parameterBinding.bind(m_lfo3Clock, Virus::Param_Lfo3Clock); - _parameterBinding.bind(m_lfo3Shape, Virus::Param_Lfo3Shape); - _parameterBinding.bind(m_lfo3AssignDest, Virus::Param_Lfo3Destination); - - // todo no link! _parameterBinding.bind(m_lfo3Link, Virus::lfo); - _parameterBinding.bind(m_lfo3LfoMode, Virus::Param_Lfo3Mode); - - //Matrix Slo1 - for (auto *s : {&m_MatSlot1Amount1,&m_MatSlot1Amount2,&m_MatSlot1Amount3,&m_MatSlot1Amount4, - }) - { - setupRotary(*this, *s); - } - - m_MatSlot1Amount1.setBounds(1792 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); - m_MatSlot1Amount2.setBounds(2197 - knobSize / 2, 125 - knobSize / 2, knobSize, knobSize); - m_MatSlot1Amount3.setBounds(1792 - knobSize / 2, 355 - knobSize / 2, knobSize, knobSize); - m_MatSlot1Amount4.setBounds(2197 - knobSize / 2, 355 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_MatSlot1Source1); - m_MatSlot1Source1.setBounds(1597+comboBoxXMargin - comboBox3Width / 2, 82 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot1Source2); - m_MatSlot1Source2.setBounds(2002+comboBoxXMargin - comboBox3Width / 2, 82 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot1Source3); - m_MatSlot1Source3.setBounds(1597+comboBoxXMargin - comboBox3Width / 2, 313 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot1Source4); - m_MatSlot1Source4.setBounds(2002+comboBoxXMargin - comboBox3Width / 2, 313 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot1AssignDest1); - m_MatSlot1AssignDest1.setBounds(1597+comboBoxXMargin - comboBox3Width / 2, 171 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot1AssignDest2); - m_MatSlot1AssignDest2.setBounds(2002+comboBoxXMargin - comboBox3Width / 2, 171 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot1AssignDest3); - m_MatSlot1AssignDest3.setBounds(1597+comboBoxXMargin- comboBox3Width / 2, 400 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot1AssignDest4); - m_MatSlot1AssignDest4.setBounds(2002+comboBoxXMargin - comboBox3Width / 2, 400 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_MatSlot1Source1, Virus::Param_Assign1Source); - _parameterBinding.bind(m_MatSlot1Source2, Virus::Param_Assign4Source); - _parameterBinding.bind(m_MatSlot1Source3, Virus::Param_Assign5Source); - _parameterBinding.bind(m_MatSlot1Source4, Virus::Param_Assign6Source); - _parameterBinding.bind(m_MatSlot1Amount1, Virus::Param_Assign1Amount); - _parameterBinding.bind(m_MatSlot1Amount2, Virus::Param_Assign4Amount); - _parameterBinding.bind(m_MatSlot1Amount3, Virus::Param_Assign5Amount); - _parameterBinding.bind(m_MatSlot1Amount4, Virus::Param_Assign6Amount); - _parameterBinding.bind(m_MatSlot1AssignDest1, Virus::Param_Assign1Destination); - _parameterBinding.bind(m_MatSlot1AssignDest2, Virus::Param_Assign4Destination); - _parameterBinding.bind(m_MatSlot1AssignDest3, Virus::Param_Assign5Destination); - _parameterBinding.bind(m_MatSlot1AssignDest4, Virus::Param_Assign6Destination); - - // Matrix Slot 2 - for (auto *s : { &m_MatSlot2Amount1, &m_MatSlot2Amount2}) - { - setupRotary(*this, *s); - } - - m_MatSlot2Amount1.setBounds(1792 - knobSize / 2, 624 - knobSize / 2, knobSize, knobSize); - m_MatSlot2Amount2.setBounds(2197 - knobSize / 2, 624 - knobSize / 2, knobSize, knobSize); - addAndMakeVisible(m_MatSlot2Source12); - m_MatSlot2Source12.setBounds(1597+comboBoxXMargin - comboBox3Width / 2, 576 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot2AssignDest1); - m_MatSlot2AssignDest1.setBounds(1597+comboBoxXMargin - comboBox3Width / 2, 666 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_MatSlot2AssignDest2); - m_MatSlot2AssignDest2.setBounds(2002+comboBoxXMargin - comboBox3Width / 2, 624 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_MatSlot2Source12, Virus::Param_Assign2Source); - _parameterBinding.bind(m_MatSlot2Amount1, Virus::Param_Assign2Amount1); - _parameterBinding.bind(m_MatSlot2Amount2, Virus::Param_Assign2Amount2); - _parameterBinding.bind(m_MatSlot2AssignDest1, Virus::Param_Assign2Destination1); - _parameterBinding.bind(m_MatSlot2AssignDest2, Virus::Param_Assign2Destination2); - - - // Matrix Slot 3 - for (auto *s : {&m_MatSlot3Amount1,&m_MatSlot3Amount2,&m_MatSlot3Amount3}) - { - setupRotary(*this, *s); - } - - m_MatSlot3Amount1.setBounds(1404 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); - m_MatSlot3Amount2.setBounds(1792 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); - m_MatSlot3Amount3.setBounds(2197 - knobSize / 2, 886 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_MatSlot3Source123); - m_MatSlot3Source123.setBounds(1210+comboBoxXMargin - comboBox3Width / 2, 838 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_MatSlot3AssignDest1); - m_MatSlot3AssignDest1.setBounds(1210+comboBoxXMargin - comboBox3Width / 2, 928 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_MatSlot3AssignDest2); - m_MatSlot3AssignDest2.setBounds(1596+comboBoxXMargin - comboBox3Width / 2, 888 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_MatSlot3AssignDest3); - m_MatSlot3AssignDest3.setBounds(2002+comboBoxXMargin - comboBox3Width / 2, 888 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_MatSlot3Source123, Virus::Param_Assign3Source); - - _parameterBinding.bind(m_MatSlot3Amount1, Virus::Param_Assign3Amount1); - _parameterBinding.bind(m_MatSlot3Amount2, Virus::Param_Assign3Amount2); - _parameterBinding.bind(m_MatSlot3Amount3, Virus::Param_Assign2Amount3); //todo: need fix typ --> Param_Assign3Amount3 - - _parameterBinding.bind(m_MatSlot3AssignDest1, Virus::Param_Assign3Destination1); - _parameterBinding.bind(m_MatSlot3AssignDest2, Virus::Param_Assign3Destination2); - _parameterBinding.bind(m_MatSlot3AssignDest3, Virus::Param_Assign2Destination3); //todo: need fix typ --> Param_Assign3Destination3 -} +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel2_LfoEditor.h b/source/jucePlugin/ui2/Virus_Panel2_LfoEditor.h @@ -2,51 +2,52 @@ #include "../PluginProcessor.h" #include "Virus_Buttons.h" - - class VirusParameterBinding; - -class LfoEditor : public juce::Component +namespace Trancy { -public: - LfoEditor(VirusParameterBinding& _parameterBinding); - -private: - //LFO 1 - juce::Slider m_lfo1Rate, m_lfo1Symmetry, m_lfo1Osc1Pitch, m_lfo1Osc2Pitch, m_lfo1Pw12, m_lfo1Reso12, - m_lfo1KeyFollow, m_lfo1Keytrigger, m_lfo1AssignAmount, m_lfo1FilterGain; - juce::ComboBox m_lfo1Clock, m_lfo1Shape, m_lfo1AssignDest; - Buttons::Button4 m_lfo1Link; - Buttons::Button2 m_lfo1LfoMode; - Buttons::Button3 m_lfo1EnvMode; - - //LFO 2 - juce::Slider m_lfo2Rate, m_lfo2Symmetry, m_lfo2Filter1Cutoff, m_lfo2Filter2Cutoff, m_lfo2Shape12, m_lfo2Panorama, - m_lfo2KeyFollow, m_lfo2Keytrigger, m_lfo2AssignAmount, m_lfo2AmtFM; - juce::ComboBox m_lfo2Clock, m_lfo2Shape, m_lfo2AssignDest; - Buttons::Button4 m_lfo2Link; - Buttons::Button2 m_lfo2LfoMode; - Buttons::Button3 m_lfo2EnvMode; - - //LFO 3 - juce::Slider m_lfo3Rate, m_lfo3FadeIn, m_lfo3KeyFollow, m_lfo3AssignAmount; - juce::ComboBox m_lfo3Clock, m_lfo3Shape, m_lfo3AssignDest; - Buttons::Button2 m_lfo3LfoMode; - - //Matrix Slo1 - juce::Slider m_MatSlot1Amount1, m_MatSlot1Amount2, m_MatSlot1Amount3, m_MatSlot1Amount4; - juce::ComboBox m_MatSlot1Source1, m_MatSlot1Source2, m_MatSlot1Source3, m_MatSlot1Source4; - juce::ComboBox m_MatSlot1AssignDest1, m_MatSlot1AssignDest2, m_MatSlot1AssignDest3, m_MatSlot1AssignDest4; - - // Matrix Slo2 - juce::Slider m_MatSlot2Amount1, m_MatSlot2Amount2; - juce::ComboBox m_MatSlot2Source12; - juce::ComboBox m_MatSlot2AssignDest1, m_MatSlot2AssignDest2; - - // Matrix Slo3 - juce::Slider m_MatSlot3Amount1, m_MatSlot3Amount2, m_MatSlot3Amount3; - juce::ComboBox m_MatSlot3Source123; - juce::ComboBox m_MatSlot3AssignDest1, m_MatSlot3AssignDest2, m_MatSlot3AssignDest3; - - std::unique_ptr<juce::Drawable> m_background; -}; + class LfoEditor : public juce::Component + { + public: + LfoEditor(VirusParameterBinding &_parameterBinding); + + private: + // LFO 1 + juce::Slider m_lfo1Rate, m_lfo1Symmetry, m_lfo1Osc1Pitch, m_lfo1Osc2Pitch, m_lfo1Pw12, m_lfo1Reso12, + m_lfo1KeyFollow, m_lfo1Keytrigger, m_lfo1AssignAmount, m_lfo1FilterGain; + juce::ComboBox m_lfo1Clock, m_lfo1Shape, m_lfo1AssignDest; + Buttons::Button4 m_lfo1Link; + Buttons::Button2 m_lfo1LfoMode; + Buttons::Button3 m_lfo1EnvMode; + + // LFO 2 + juce::Slider m_lfo2Rate, m_lfo2Symmetry, m_lfo2Filter1Cutoff, m_lfo2Filter2Cutoff, m_lfo2Shape12, + m_lfo2Panorama, m_lfo2KeyFollow, m_lfo2Keytrigger, m_lfo2AssignAmount, m_lfo2AmtFM; + juce::ComboBox m_lfo2Clock, m_lfo2Shape, m_lfo2AssignDest; + Buttons::Button4 m_lfo2Link; + Buttons::Button2 m_lfo2LfoMode; + Buttons::Button3 m_lfo2EnvMode; + + // LFO 3 + juce::Slider m_lfo3Rate, m_lfo3FadeIn, m_lfo3KeyFollow, m_lfo3AssignAmount; + juce::ComboBox m_lfo3Clock, m_lfo3Shape, m_lfo3AssignDest; + Buttons::Button2 m_lfo3LfoMode; + + // Matrix Slo1 + juce::Slider m_MatSlot1Amount1, m_MatSlot1Amount2, m_MatSlot1Amount3, m_MatSlot1Amount4; + juce::ComboBox m_MatSlot1Source1, m_MatSlot1Source2, m_MatSlot1Source3, m_MatSlot1Source4; + juce::ComboBox m_MatSlot1AssignDest1, m_MatSlot1AssignDest2, m_MatSlot1AssignDest3, m_MatSlot1AssignDest4; + + // Matrix Slo2 + juce::Slider m_MatSlot2Amount1, m_MatSlot2Amount2; + juce::ComboBox m_MatSlot2Source12; + juce::ComboBox m_MatSlot2AssignDest1, m_MatSlot2AssignDest2; + + // Matrix Slo3 + juce::Slider m_MatSlot3Amount1, m_MatSlot3Amount2, m_MatSlot3Amount3; + juce::ComboBox m_MatSlot3Source123; + juce::ComboBox m_MatSlot3AssignDest1, m_MatSlot3AssignDest2, m_MatSlot3AssignDest3; + + std::unique_ptr<juce::Drawable> m_background; + }; + +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel3_FxEditor.cpp b/source/jucePlugin/ui2/Virus_Panel3_FxEditor.cpp @@ -3,174 +3,182 @@ #include "Ui_Utils.h" #include "../VirusParameterBinding.h" -using namespace juce; - - -FxEditor::FxEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef): m_controller(_processorRef.getController()) +namespace Trancy { - setupBackground(*this, m_background, BinaryData::panel_3_png, BinaryData::panel_3_pngSize); - setBounds(m_background->getDrawableBounds().toNearestIntEdges()); - - // envFollow - for (auto *s : {&m_envFollowLevel, &m_envFollowAttack, &m_eEnvFollowRelease}) - { - setupRotary(*this, *s); - } - - m_envFollowLevel.setBounds(219 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_envFollowAttack.setBounds(365 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_eEnvFollowRelease.setBounds(508 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_envFollow); - m_envFollow.setBounds(86 - m_envFollow.kWidth / 2, 113 - m_envFollow.kHeight / 2, m_envFollow.kWidth, m_envFollow.kHeight); - - _parameterBinding.bind(m_envFollow, Virus::Param_InputFollowMode); - _parameterBinding.bind(m_envFollowAttack, Virus::Param_FilterEnvAttack); - _parameterBinding.bind(m_eEnvFollowRelease, Virus::Param_FilterEnvDecay); - _parameterBinding.bind(m_envFollowLevel, Virus::Param_FilterEnvSustain); - - // Distortion - for (auto *s : {&m_distortionIntensity}) - { - setupRotary(*this, *s); - } - m_distortionIntensity.setBounds(905 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_distortionCurve); - m_distortionCurve.setBounds(741+comboBoxXMargin - comboBox3Width / 2, 113 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_distortionIntensity, Virus::Param_DistortionIntensity); - _parameterBinding.bind(m_distortionCurve, Virus::Param_DistortionCurve); - - // Chorus - for (auto *s : {&m_chorusRate, &m_chorusDepth, &m_chorusFeedback, &m_chorusMix, &m_chorusDelay}) - { - setupRotary(*this, *s); - } - m_chorusRate.setBounds(1299 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_chorusDepth.setBounds(1440 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_chorusFeedback.setBounds(1584 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_chorusMix.setBounds(1722 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_chorusDelay.setBounds(1861 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_choruslfoShape); - m_choruslfoShape.setBounds(1129+comboBoxXMargin - comboBox3Width / 2, 113 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_chorusRate, Virus::Param_ChorusRate); - _parameterBinding.bind(m_chorusDepth, Virus::Param_ChorusDepth); - _parameterBinding.bind(m_chorusFeedback, Virus::Param_ChorusFeedback); - _parameterBinding.bind(m_chorusMix, Virus::Param_ChorusMix); - _parameterBinding.bind(m_chorusDelay, Virus::Param_ChorusDelay); - _parameterBinding.bind(m_choruslfoShape, Virus::Param_ChorusLfoShape); - - // AnalogBoost - for (auto *s : {&m_analogBoostIntensity, &m_AnalogBoostTune}) - { - setupRotary(*this, *s); - } - - m_analogBoostIntensity.setBounds(2060 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_AnalogBoostTune.setBounds(2203 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - - _parameterBinding.bind(m_analogBoostIntensity, Virus::Param_BassIntensity); - _parameterBinding.bind(m_AnalogBoostTune, Virus::Param_BassTune); - - // Phaser - for (auto *s : {&m_phaserMix, &m_phaserSpread, &m_phaserRate, &m_phaserDepth, &m_phaserFreq, &m_phaserFeedback}) - { - setupRotary(*this, *s); - } - m_phaserMix.setBounds(283 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_phaserSpread.setBounds(420 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_phaserRate.setBounds(554 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_phaserDepth.setBounds(691 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_phaserFreq.setBounds(825 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_phaserFeedback.setBounds(961 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_stages); - m_stages.setBounds(114+comboBoxXMargin - comboBox3Width / 2, 339 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_phaserMix, Virus::Param_PhaserMix); - _parameterBinding.bind(m_phaserSpread, Virus::Param_PhaserSpread); - _parameterBinding.bind(m_phaserRate, Virus::Param_PhaserRate); - _parameterBinding.bind(m_phaserDepth, Virus::Param_PhaserDepth); - _parameterBinding.bind(m_phaserFreq, Virus::Param_PhaserFreq); - _parameterBinding.bind(m_phaserFeedback, Virus::Param_PhaserFeedback); - _parameterBinding.bind(m_stages, Virus::Param_PhaserMode); - - // Equalizer - m_equalizerLowGgain, m_equalizerLowFreq, m_equalizerMidGain, m_equalizerMidFreq, m_equalizerMidQ, m_equalizerHighGgain, m_equalizerHighFreq; - - for (auto *s : {&m_equalizerLowGgain, &m_equalizerLowFreq, &m_equalizerMidGain, &m_equalizerMidFreq, &m_equalizerMidQ, - &m_equalizerHighGgain, &m_equalizerHighFreq}) - { - setupRotary(*this, *s); - } - m_equalizerLowGgain.setBounds(1164 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_equalizerLowFreq.setBounds(1304 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_equalizerMidGain.setBounds(1448 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_equalizerMidFreq.setBounds(1588 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_equalizerMidQ.setBounds(1737 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_equalizerHighGgain.setBounds(1882 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - m_equalizerHighFreq.setBounds(2021 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - - _parameterBinding.bind(m_equalizerLowGgain, Virus::Param_LowEqGain); - _parameterBinding.bind(m_equalizerLowFreq, Virus::Param_LowEqFreq); - _parameterBinding.bind(m_equalizerMidGain, Virus::Param_MidEqGain); - _parameterBinding.bind(m_equalizerMidFreq, Virus::Param_MidEqFreq); - _parameterBinding.bind(m_equalizerMidQ, Virus::Param_MidEqQFactor); - _parameterBinding.bind(m_equalizerHighGgain, Virus::Param_HighEqGain); - _parameterBinding.bind(m_equalizerHighFreq, Virus::Param_HighEqFreq); - - // RingModInput - for (auto *s : {&m_ringModMix}) - { - setupRotary(*this, *s); - } - m_ringModMix.setBounds(2212 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); - - _parameterBinding.bind(m_ringModMix, Virus::Param_InputRingMod); + using namespace juce; - // Delay/Reverb - //Show hide Reverb - for (auto *s : {&m_delayReverbSend}) + FxEditor::FxEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef) : + m_controller(_processorRef.getController()) { - setupRotary(*this, *s); - } - m_delayReverbSend.setBounds(113 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_delayReverbMode); - m_delayReverbMode.setBounds(113+comboBoxXMargin - comboBox3Width / 2, 763 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_delayReverbSend, Virus::Param_EffectSend); - _parameterBinding.bind(m_delayReverbMode, Virus::Param_DelayReverbMode); - - auto p = m_controller.getParameter(Virus::Param_DelayReverbMode, 0); - if (p) { - const auto val = (int)p->getValueObject().getValueSource().getValue(); - DelayReverb(); - - p->onValueChanged = nullptr; - p->onValueChanged = [this, p]() { - DelayReverb(); - }; - } - - //Reverb selected - // Reverb - for (auto *s : {&m_reverbDecayTime, &m_reverbDaming, &m_reverbColoration, &m_reverbPredelay, &m_reverbFeedback}) - { - setupRotary(*this, *s); - } - - m_reverbDecayTime.setBounds(297 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); - m_reverbDaming.setBounds(632 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); - m_reverbColoration.setBounds(771 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); - m_reverbPredelay.setBounds(909 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); - m_reverbFeedback.setBounds(1052 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_reverbType); - m_reverbType.setBounds(467+comboBoxXMargin - comboBox3Width / 2, 854 - comboBox3Height / 2, comboBox3Width, comboBox3Height); + setupBackground(*this, m_background, BinaryData::panel_3_png, BinaryData::panel_3_pngSize); + setBounds(m_background->getDrawableBounds().toNearestIntEdges()); + + // envFollow + for (auto *s : {&m_envFollowLevel, &m_envFollowAttack, &m_eEnvFollowRelease}) + { + setupRotary(*this, *s); + } + + m_envFollowLevel.setBounds(219 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_envFollowAttack.setBounds(365 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_eEnvFollowRelease.setBounds(508 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_envFollow); + m_envFollow.setBounds(86 - m_envFollow.kWidth / 2, 113 - m_envFollow.kHeight / 2, m_envFollow.kWidth, + m_envFollow.kHeight); + + _parameterBinding.bind(m_envFollow, Virus::Param_InputFollowMode); + _parameterBinding.bind(m_envFollowAttack, Virus::Param_FilterEnvAttack); + _parameterBinding.bind(m_eEnvFollowRelease, Virus::Param_FilterEnvDecay); + _parameterBinding.bind(m_envFollowLevel, Virus::Param_FilterEnvSustain); + + // Distortion + for (auto *s : {&m_distortionIntensity}) + { + setupRotary(*this, *s); + } + m_distortionIntensity.setBounds(905 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_distortionCurve); + m_distortionCurve.setBounds(741 + comboBoxXMargin - comboBox3Width / 2, 113 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + _parameterBinding.bind(m_distortionIntensity, Virus::Param_DistortionIntensity); + _parameterBinding.bind(m_distortionCurve, Virus::Param_DistortionCurve); + + // Chorus + for (auto *s : {&m_chorusRate, &m_chorusDepth, &m_chorusFeedback, &m_chorusMix, &m_chorusDelay}) + { + setupRotary(*this, *s); + } + m_chorusRate.setBounds(1299 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_chorusDepth.setBounds(1440 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_chorusFeedback.setBounds(1584 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_chorusMix.setBounds(1722 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_chorusDelay.setBounds(1861 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_choruslfoShape); + m_choruslfoShape.setBounds(1129 + comboBoxXMargin - comboBox3Width / 2, 113 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + _parameterBinding.bind(m_chorusRate, Virus::Param_ChorusRate); + _parameterBinding.bind(m_chorusDepth, Virus::Param_ChorusDepth); + _parameterBinding.bind(m_chorusFeedback, Virus::Param_ChorusFeedback); + _parameterBinding.bind(m_chorusMix, Virus::Param_ChorusMix); + _parameterBinding.bind(m_chorusDelay, Virus::Param_ChorusDelay); + _parameterBinding.bind(m_choruslfoShape, Virus::Param_ChorusLfoShape); + + // AnalogBoost + for (auto *s : {&m_analogBoostIntensity, &m_AnalogBoostTune}) + { + setupRotary(*this, *s); + } + + m_analogBoostIntensity.setBounds(2060 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_AnalogBoostTune.setBounds(2203 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + + _parameterBinding.bind(m_analogBoostIntensity, Virus::Param_BassIntensity); + _parameterBinding.bind(m_AnalogBoostTune, Virus::Param_BassTune); + + // Phaser + for (auto *s : {&m_phaserMix, &m_phaserSpread, &m_phaserRate, &m_phaserDepth, &m_phaserFreq, &m_phaserFeedback}) + { + setupRotary(*this, *s); + } + m_phaserMix.setBounds(283 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_phaserSpread.setBounds(420 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_phaserRate.setBounds(554 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_phaserDepth.setBounds(691 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_phaserFreq.setBounds(825 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_phaserFeedback.setBounds(961 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_stages); + m_stages.setBounds(114 + comboBoxXMargin - comboBox3Width / 2, 339 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + _parameterBinding.bind(m_phaserMix, Virus::Param_PhaserMix); + _parameterBinding.bind(m_phaserSpread, Virus::Param_PhaserSpread); + _parameterBinding.bind(m_phaserRate, Virus::Param_PhaserRate); + _parameterBinding.bind(m_phaserDepth, Virus::Param_PhaserDepth); + _parameterBinding.bind(m_phaserFreq, Virus::Param_PhaserFreq); + _parameterBinding.bind(m_phaserFeedback, Virus::Param_PhaserFeedback); + _parameterBinding.bind(m_stages, Virus::Param_PhaserMode); + + // Equalizer + m_equalizerLowGgain, m_equalizerLowFreq, m_equalizerMidGain, m_equalizerMidFreq, m_equalizerMidQ, + m_equalizerHighGgain, m_equalizerHighFreq; + + for (auto *s : {&m_equalizerLowGgain, &m_equalizerLowFreq, &m_equalizerMidGain, &m_equalizerMidFreq, + &m_equalizerMidQ, &m_equalizerHighGgain, &m_equalizerHighFreq}) + { + setupRotary(*this, *s); + } + m_equalizerLowGgain.setBounds(1164 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_equalizerLowFreq.setBounds(1304 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_equalizerMidGain.setBounds(1448 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_equalizerMidFreq.setBounds(1588 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_equalizerMidQ.setBounds(1737 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_equalizerHighGgain.setBounds(1882 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + m_equalizerHighFreq.setBounds(2021 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + + _parameterBinding.bind(m_equalizerLowGgain, Virus::Param_LowEqGain); + _parameterBinding.bind(m_equalizerLowFreq, Virus::Param_LowEqFreq); + _parameterBinding.bind(m_equalizerMidGain, Virus::Param_MidEqGain); + _parameterBinding.bind(m_equalizerMidFreq, Virus::Param_MidEqFreq); + _parameterBinding.bind(m_equalizerMidQ, Virus::Param_MidEqQFactor); + _parameterBinding.bind(m_equalizerHighGgain, Virus::Param_HighEqGain); + _parameterBinding.bind(m_equalizerHighFreq, Virus::Param_HighEqFreq); + + // RingModInput + for (auto *s : {&m_ringModMix}) + { + setupRotary(*this, *s); + } + m_ringModMix.setBounds(2212 - knobSize / 2, 339 - knobSize / 2, knobSize, knobSize); + + _parameterBinding.bind(m_ringModMix, Virus::Param_InputRingMod); + + // Delay/Reverb + // Show hide Reverb + for (auto *s : {&m_delayReverbSend}) + { + setupRotary(*this, *s); + } + m_delayReverbSend.setBounds(113 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_delayReverbMode); + m_delayReverbMode.setBounds(113 + comboBoxXMargin - comboBox3Width / 2, 763 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + _parameterBinding.bind(m_delayReverbSend, Virus::Param_EffectSend); + _parameterBinding.bind(m_delayReverbMode, Virus::Param_DelayReverbMode); + + auto p = m_controller.getParameter(Virus::Param_DelayReverbMode, 0); + if (p) + { + const auto val = (int)p->getValueObject().getValueSource().getValue(); + DelayReverb(); + + p->onValueChanged = nullptr; + p->onValueChanged = [this, p]() { DelayReverb(); }; + } + + // Reverb selected + // Reverb + for (auto *s : {&m_reverbDecayTime, &m_reverbDaming, &m_reverbColoration, &m_reverbPredelay, &m_reverbFeedback}) + { + setupRotary(*this, *s); + } + + m_reverbDecayTime.setBounds(297 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); + m_reverbDaming.setBounds(632 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); + m_reverbColoration.setBounds(771 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); + m_reverbPredelay.setBounds(909 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); + m_reverbFeedback.setBounds(1052 - knobSize / 2, 854 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_reverbType); + m_reverbType.setBounds(467 + comboBoxXMargin - comboBox3Width / 2, 854 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); _parameterBinding.bind(m_reverbDecayTime, Virus::Param_DelayRateReverbDecayTime); _parameterBinding.bind(m_reverbDaming, Virus::Param_DelayLfoShape); @@ -179,23 +187,25 @@ FxEditor::FxEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioPro _parameterBinding.bind(m_reverbFeedback, Virus::Param_DelayFeedback); _parameterBinding.bind(m_reverbType, Virus::Param_ReverbRoomSize); - // todo Need to check these parameters bindings for delay and reverb - // Delay - for (auto *s : {&m_delayTime, &m_delayRate, &m_delayFeedback, &m_delayColoration, &m_delayDepth}) - { - setupRotary(*this, *s); - } - m_delayTime.setBounds(297 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); - m_delayRate.setBounds(632 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); - m_delayFeedback.setBounds(771 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); - m_delayColoration.setBounds(909 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); - m_delayDepth.setBounds(1052 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_delayClock); - m_delayClock.setBounds(467+comboBoxXMargin - comboBox3Width / 2, 555 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_delayShape); - m_delayShape.setBounds(467+comboBoxXMargin - comboBox3Width / 2, 653 - comboBox3Height / 2, comboBox3Width, comboBox3Height); + // todo Need to check these parameters bindings for delay and reverb + // Delay + for (auto *s : {&m_delayTime, &m_delayRate, &m_delayFeedback, &m_delayColoration, &m_delayDepth}) + { + setupRotary(*this, *s); + } + m_delayTime.setBounds(297 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); + m_delayRate.setBounds(632 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); + m_delayFeedback.setBounds(771 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); + m_delayColoration.setBounds(909 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); + m_delayDepth.setBounds(1052 - knobSize / 2, 607 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_delayClock); + m_delayClock.setBounds(467 + comboBoxXMargin - comboBox3Width / 2, 555 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + addAndMakeVisible(m_delayShape); + m_delayShape.setBounds(467 + comboBoxXMargin - comboBox3Width / 2, 653 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); _parameterBinding.bind(m_delayTime, Virus::Param_DelayTime); _parameterBinding.bind(m_delayRate, Virus::Param_DelayRateReverbDecayTime); @@ -205,147 +215,149 @@ FxEditor::FxEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioPro _parameterBinding.bind(m_delayClock, Virus::Param_DelayClock); _parameterBinding.bind(m_delayShape, Virus::Param_DelayLfoShape); - // Vocoder - for (auto *s : {&m_vocoderCenterFreq, &m_vocoderModOffset, &m_vocoderModQ, &m_vocoderModSpread, &m_vocoderCarrQ, - &m_vocoderCarrSpread, &m_vocoderSpectralBal, &m_vocoderBands, &m_vocoderAttack, &m_vocoderRelease, - &m_vocoderSourceBal}) + // Vocoder + for (auto *s : {&m_vocoderCenterFreq, &m_vocoderModOffset, &m_vocoderModQ, &m_vocoderModSpread, &m_vocoderCarrQ, + &m_vocoderCarrSpread, &m_vocoderSpectralBal, &m_vocoderBands, &m_vocoderAttack, + &m_vocoderRelease, &m_vocoderSourceBal}) + { + setupRotary(*this, *s); + } + + m_vocoderCenterFreq.setBounds(1487 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); + m_vocoderModOffset.setBounds(1625 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); + m_vocoderModQ.setBounds(1768 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); + m_vocoderModSpread.setBounds(1912 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); + m_vocoderCarrQ.setBounds(2055 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); + m_vocoderCarrSpread.setBounds(2198 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); + + m_vocoderSpectralBal.setBounds(1487 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); + m_vocoderBands.setBounds(1625 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); + m_vocoderAttack.setBounds(1768 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); + m_vocoderRelease.setBounds(1912 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); + m_vocoderSourceBal.setBounds(2055 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); + + addAndMakeVisible(m_vocoderMode); + m_vocoderMode.setBounds(1273 + comboBoxXMargin - comboBox3Width / 2, 672 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + addAndMakeVisible(m_vocoderModInput); + m_vocoderModInput.setBounds(1273 + comboBoxXMargin - comboBox3Width / 2, 787 - comboBox3Height / 2, + comboBox3Width, comboBox3Height); + + m_vocoderLink.setBounds(1987 - m_vocoderLink.kWidth / 2, 526 - m_vocoderLink.kHeight / 2, m_vocoderLink.kWidth, + m_vocoderLink.kHeight); + addAndMakeVisible(m_vocoderLink); + + // todo Need to check these parameters bindings + _parameterBinding.bind(m_vocoderCenterFreq, Virus::Param_FilterCutA); + _parameterBinding.bind(m_vocoderModOffset, Virus::Param_FilterCutB); + _parameterBinding.bind(m_vocoderModQ, Virus::Param_FilterResA); + _parameterBinding.bind(m_vocoderModSpread, Virus::Param_FilterKeyFollowA); + _parameterBinding.bind(m_vocoderCarrQ, Virus::Param_FilterResB); + _parameterBinding.bind(m_vocoderCarrSpread, Virus::Param_FilterKeyFollowB); + _parameterBinding.bind(m_vocoderSpectralBal, Virus::Param_FilterEnvSustainTime); + + _parameterBinding.bind(m_vocoderBands, Virus::Param_FilterEnvRelease); + _parameterBinding.bind(m_vocoderAttack, Virus::Param_FilterEnvAttack); + _parameterBinding.bind(m_vocoderRelease, Virus::Param_FilterEnvDecay); + _parameterBinding.bind(m_vocoderSourceBal, Virus::Param_FilterBalance); + + _parameterBinding.bind(m_vocoderMode, Virus::Param_VocoderMode); + _parameterBinding.bind(m_vocoderModInput, Virus::Param_InputSelect); + _parameterBinding.bind(m_vocoderLink, Virus::Param_Filter2CutoffLink); + + auto p1 = m_controller.getParameter(Virus::Param_VocoderMode, 0); + if (p1) + { + const auto val = (int)p1->getValueObject().getValueSource().getValue(); + Vocoder(); + + p1->onValueChanged = nullptr; + p1->onValueChanged = [this, p1]() { Vocoder(); }; + } + } + + void FxEditor::Vocoder() { - setupRotary(*this, *s); + // Vocoder + // m_vocoderMode + auto p = m_controller.getParameter(Virus::Param_VocoderMode, 0); + const auto value = (int)p->getValueObject().getValueSource().getValue(); + m_vocoderMode.setSelectedId(value + 1, dontSendNotification); + + int iSelectedIndex = m_vocoderMode.getSelectedItemIndex(); + bool bVocoder = (iSelectedIndex > 0); + float fAlpha = (bVocoder) ? 1.0f : 0.3f; + + m_vocoderCenterFreq.setEnabled(bVocoder); + m_vocoderCenterFreq.setAlpha(fAlpha); + m_vocoderModOffset.setEnabled(bVocoder); + m_vocoderModOffset.setAlpha(fAlpha); + m_vocoderModQ.setEnabled(bVocoder); + m_vocoderModQ.setAlpha(fAlpha); + m_vocoderModSpread.setEnabled(bVocoder); + m_vocoderModSpread.setAlpha(fAlpha); + m_vocoderCarrQ.setEnabled(bVocoder); + m_vocoderCarrQ.setAlpha(fAlpha); + m_vocoderCarrSpread.setEnabled(bVocoder); + m_vocoderCarrSpread.setAlpha(fAlpha); + m_vocoderSpectralBal.setEnabled(bVocoder); + m_vocoderSpectralBal.setAlpha(fAlpha); + m_vocoderBands.setEnabled(bVocoder); + m_vocoderBands.setAlpha(fAlpha); + m_vocoderAttack.setEnabled(bVocoder); + m_vocoderAttack.setAlpha(fAlpha); + m_vocoderRelease.setEnabled(bVocoder); + m_vocoderRelease.setAlpha(fAlpha); + m_vocoderSourceBal.setEnabled(bVocoder); + m_vocoderSourceBal.setAlpha(fAlpha); + // m_vocoderMode.setVisible(bVocoder); + m_vocoderModInput.setEnabled(bVocoder); + m_vocoderModInput.setAlpha(fAlpha); + m_vocoderLink.setEnabled(bVocoder); + m_vocoderLink.setAlpha(fAlpha); } - m_vocoderCenterFreq.setBounds(1487 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); - m_vocoderModOffset.setBounds(1625 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); - m_vocoderModQ.setBounds(1768 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); - m_vocoderModSpread.setBounds(1912 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); - m_vocoderCarrQ.setBounds(2055 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); - m_vocoderCarrSpread.setBounds(2198 - knobSize / 2, 625 - knobSize / 2, knobSize, knobSize); - - m_vocoderSpectralBal.setBounds(1487 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); - m_vocoderBands.setBounds(1625 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); - m_vocoderAttack.setBounds(1768 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); - m_vocoderRelease.setBounds(1912 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); - m_vocoderSourceBal.setBounds(2055 - knobSize / 2, 836 - knobSize / 2, knobSize, knobSize); - - addAndMakeVisible(m_vocoderMode); - m_vocoderMode.setBounds(1273+comboBoxXMargin - comboBox3Width / 2, 672 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_vocoderModInput); - m_vocoderModInput.setBounds(1273+comboBoxXMargin - comboBox3Width / 2, 787 - comboBox3Height / 2, comboBox3Width, comboBox3Height); - - m_vocoderLink.setBounds(1987 - m_vocoderLink.kWidth / 2, 526 - m_vocoderLink.kHeight / 2, m_vocoderLink.kWidth, m_vocoderLink.kHeight); - addAndMakeVisible(m_vocoderLink); - - //todo Need to check these parameters bindings - _parameterBinding.bind(m_vocoderCenterFreq, Virus::Param_FilterCutA); - _parameterBinding.bind(m_vocoderModOffset, Virus::Param_FilterCutB); - _parameterBinding.bind(m_vocoderModQ, Virus::Param_FilterResA); - _parameterBinding.bind(m_vocoderModSpread, Virus::Param_FilterKeyFollowA); - _parameterBinding.bind(m_vocoderCarrQ, Virus::Param_FilterResB); - _parameterBinding.bind(m_vocoderCarrSpread, Virus::Param_FilterKeyFollowB); - _parameterBinding.bind(m_vocoderSpectralBal, Virus::Param_FilterEnvSustainTime); - - _parameterBinding.bind(m_vocoderBands, Virus::Param_FilterEnvRelease); - _parameterBinding.bind(m_vocoderAttack, Virus::Param_FilterEnvAttack); - _parameterBinding.bind(m_vocoderRelease, Virus::Param_FilterEnvDecay); - _parameterBinding.bind(m_vocoderSourceBal, Virus::Param_FilterBalance); - - _parameterBinding.bind(m_vocoderMode, Virus::Param_VocoderMode); - _parameterBinding.bind(m_vocoderModInput, Virus::Param_InputSelect); - _parameterBinding.bind(m_vocoderLink, Virus::Param_Filter2CutoffLink); - - auto p1 = m_controller.getParameter(Virus::Param_VocoderMode, 0); - if (p1) { - const auto val = (int)p1->getValueObject().getValueSource().getValue(); - Vocoder(); - - p1->onValueChanged = nullptr; - p1->onValueChanged = [this, p1]() { - Vocoder(); - }; - } - -} - -void FxEditor::Vocoder() -{ - //Vocoder - //m_vocoderMode - auto p = m_controller.getParameter(Virus::Param_VocoderMode, 0); - const auto value = (int)p->getValueObject().getValueSource().getValue(); - m_vocoderMode.setSelectedId(value + 1, dontSendNotification); - - int iSelectedIndex = m_vocoderMode.getSelectedItemIndex(); - bool bVocoder = (iSelectedIndex > 0); - float fAlpha = (bVocoder)?1.0f:0.3f; - - m_vocoderCenterFreq.setEnabled(bVocoder); - m_vocoderCenterFreq.setAlpha(fAlpha); - m_vocoderModOffset.setEnabled(bVocoder); - m_vocoderModOffset.setAlpha(fAlpha); - m_vocoderModQ.setEnabled(bVocoder); - m_vocoderModQ.setAlpha(fAlpha); - m_vocoderModSpread.setEnabled(bVocoder); - m_vocoderModSpread.setAlpha(fAlpha); - m_vocoderCarrQ.setEnabled(bVocoder); - m_vocoderCarrQ.setAlpha(fAlpha); - m_vocoderCarrSpread.setEnabled(bVocoder); - m_vocoderCarrSpread.setAlpha(fAlpha); - m_vocoderSpectralBal.setEnabled(bVocoder); - m_vocoderSpectralBal.setAlpha(fAlpha); - m_vocoderBands.setEnabled(bVocoder); - m_vocoderBands.setAlpha(fAlpha); - m_vocoderAttack.setEnabled(bVocoder); - m_vocoderAttack.setAlpha(fAlpha); - m_vocoderRelease.setEnabled(bVocoder); - m_vocoderRelease.setAlpha(fAlpha); - m_vocoderSourceBal.setEnabled(bVocoder); - m_vocoderSourceBal.setAlpha(fAlpha); - //m_vocoderMode.setVisible(bVocoder); - m_vocoderModInput.setEnabled(bVocoder); - m_vocoderModInput.setAlpha(fAlpha); - m_vocoderLink.setEnabled(bVocoder); - m_vocoderLink.setAlpha(fAlpha); -} - -void FxEditor::DelayReverb() -{ - //rebind(); - auto p = m_controller.getParameter(Virus::Param_DelayReverbMode, 0); - const auto value = (int)p->getValueObject().getValueSource().getValue(); - m_delayReverbMode.setSelectedId(value + 1, dontSendNotification); - - //Delay/Reverb - int iSelectedIndex = m_delayReverbMode.getSelectedItemIndex(); - bool bReverb = (iSelectedIndex >= 2 && iSelectedIndex <= 4); - float fReverbAlpha = (bReverb)?1.0f:0.3f; - bool bDelay = (iSelectedIndex ==1 || iSelectedIndex >= 5); - float fDelayAlpha = (bDelay)?1.0f:0.3f; - - m_reverbDecayTime.setEnabled(bReverb); - m_reverbDecayTime.setAlpha(fReverbAlpha); - m_reverbDaming.setEnabled(bReverb); - m_reverbDaming.setAlpha(fReverbAlpha); - m_reverbColoration.setEnabled(bReverb); - m_reverbColoration.setAlpha(fReverbAlpha); - m_reverbPredelay.setEnabled(bReverb); - m_reverbPredelay.setAlpha(fReverbAlpha); - m_reverbFeedback.setEnabled(bReverb); - m_reverbFeedback.setAlpha(fReverbAlpha); - m_reverbType.setEnabled(bReverb); - m_reverbType.setAlpha(fReverbAlpha); - - m_delayTime.setEnabled(bDelay); - m_delayTime.setAlpha(fDelayAlpha); - m_delayRate.setEnabled(bDelay); - m_delayRate.setAlpha(fDelayAlpha); - m_delayFeedback.setEnabled(bDelay); - m_delayFeedback.setAlpha(fDelayAlpha); - m_delayColoration.setEnabled(bDelay); - m_delayColoration.setAlpha(fDelayAlpha); - m_delayDepth.setEnabled(bDelay); - m_delayDepth.setAlpha(fDelayAlpha); - m_delayClock.setEnabled(bDelay); - m_delayClock.setAlpha(fDelayAlpha); - m_delayShape.setEnabled(bDelay); - m_delayShape.setAlpha(fDelayAlpha); -} + void FxEditor::DelayReverb() + { + // rebind(); + auto p = m_controller.getParameter(Virus::Param_DelayReverbMode, 0); + const auto value = (int)p->getValueObject().getValueSource().getValue(); + m_delayReverbMode.setSelectedId(value + 1, dontSendNotification); + + // Delay/Reverb + int iSelectedIndex = m_delayReverbMode.getSelectedItemIndex(); + bool bReverb = (iSelectedIndex >= 2 && iSelectedIndex <= 4); + float fReverbAlpha = (bReverb) ? 1.0f : 0.3f; + bool bDelay = (iSelectedIndex == 1 || iSelectedIndex >= 5); + float fDelayAlpha = (bDelay) ? 1.0f : 0.3f; + + m_reverbDecayTime.setEnabled(bReverb); + m_reverbDecayTime.setAlpha(fReverbAlpha); + m_reverbDaming.setEnabled(bReverb); + m_reverbDaming.setAlpha(fReverbAlpha); + m_reverbColoration.setEnabled(bReverb); + m_reverbColoration.setAlpha(fReverbAlpha); + m_reverbPredelay.setEnabled(bReverb); + m_reverbPredelay.setAlpha(fReverbAlpha); + m_reverbFeedback.setEnabled(bReverb); + m_reverbFeedback.setAlpha(fReverbAlpha); + m_reverbType.setEnabled(bReverb); + m_reverbType.setAlpha(fReverbAlpha); + + m_delayTime.setEnabled(bDelay); + m_delayTime.setAlpha(fDelayAlpha); + m_delayRate.setEnabled(bDelay); + m_delayRate.setAlpha(fDelayAlpha); + m_delayFeedback.setEnabled(bDelay); + m_delayFeedback.setAlpha(fDelayAlpha); + m_delayColoration.setEnabled(bDelay); + m_delayColoration.setAlpha(fDelayAlpha); + m_delayDepth.setEnabled(bDelay); + m_delayDepth.setAlpha(fDelayAlpha); + m_delayClock.setEnabled(bDelay); + m_delayClock.setAlpha(fDelayAlpha); + m_delayShape.setEnabled(bDelay); + m_delayShape.setAlpha(fDelayAlpha); + } +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel3_FxEditor.h b/source/jucePlugin/ui2/Virus_Panel3_FxEditor.h @@ -2,66 +2,67 @@ #include "../PluginProcessor.h" #include "Virus_Buttons.h" +class VirusParameterBinding; +namespace Trancy +{ + class FxEditor : public juce::Component + { + public: + FxEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef); + private: + void DelayReverb(); + void Vocoder(); + Virus::Controller &m_controller; -class VirusParameterBinding; + // Env Follower + juce::Slider m_envFollowLevel, m_envFollowAttack, m_eEnvFollowRelease; + Buttons::Button3 m_envFollow; -class FxEditor : public juce::Component -{ -public: - FxEditor(VirusParameterBinding& _parameterBinding, AudioPluginAudioProcessor &_processorRef); + // Distortion + juce::Slider m_distortionIntensity; + juce::ComboBox m_distortionCurve; -private: - void DelayReverb(); - void Vocoder(); - Virus::Controller &m_controller; + // Chorus + juce::Slider m_chorusRate, m_chorusDepth, m_chorusFeedback, m_chorusMix, m_chorusDelay; + juce::ComboBox m_choruslfoShape; - // Env Follower - juce::Slider m_envFollowLevel, m_envFollowAttack, m_eEnvFollowRelease; - Buttons::Button3 m_envFollow; + // AnalogBoost + juce::Slider m_analogBoostIntensity, m_AnalogBoostTune; - // Distortion - juce::Slider m_distortionIntensity; - juce::ComboBox m_distortionCurve; + // Phaser + juce::Slider m_phaserMix, m_phaserSpread, m_phaserRate, m_phaserDepth, m_phaserFreq, m_phaserFeedback; + juce::ComboBox m_stages; - // Chorus - juce::Slider m_chorusRate, m_chorusDepth, m_chorusFeedback, m_chorusMix, m_chorusDelay; - juce::ComboBox m_choruslfoShape; + // Equalizer + juce::Slider m_equalizerLowGgain, m_equalizerLowFreq, m_equalizerMidGain, m_equalizerMidFreq, m_equalizerMidQ, + m_equalizerHighGgain, m_equalizerHighFreq; - // AnalogBoost - juce::Slider m_analogBoostIntensity, m_AnalogBoostTune; + // Ring Mod + juce::Slider m_ringModMix; - // Phaser - juce::Slider m_phaserMix, m_phaserSpread, m_phaserRate, m_phaserDepth, m_phaserFreq, m_phaserFeedback; - juce::ComboBox m_stages; + // Delay/Reverb + juce::Slider m_delayReverbSend; + juce::ComboBox m_delayReverbMode; - // Equalizer - juce::Slider m_equalizerLowGgain, m_equalizerLowFreq, m_equalizerMidGain, m_equalizerMidFreq, m_equalizerMidQ, - m_equalizerHighGgain, m_equalizerHighFreq; + // Delay + juce::Slider m_delayTime, m_delayRate, m_delayFeedback, m_delayColoration, m_delayDepth; + juce::ComboBox m_delayClock; + juce::ComboBox m_delayShape; - // Ring Mod - juce::Slider m_ringModMix; - - //Delay/Reverb - juce::Slider m_delayReverbSend; - juce::ComboBox m_delayReverbMode; - - //Delay - juce::Slider m_delayTime, m_delayRate, m_delayFeedback, m_delayColoration, m_delayDepth; - juce::ComboBox m_delayClock; - juce::ComboBox m_delayShape; - - //Reverb - juce::Slider m_reverbDecayTime, m_reverbDaming, m_reverbColoration, m_reverbPredelay, m_reverbFeedback; - juce::ComboBox m_reverbType; + // Reverb + juce::Slider m_reverbDecayTime, m_reverbDaming, m_reverbColoration, m_reverbPredelay, m_reverbFeedback; + juce::ComboBox m_reverbType; - //Vocoder - juce::Slider m_vocoderCenterFreq, m_vocoderModOffset, m_vocoderModQ, m_vocoderModSpread, m_vocoderCarrQ, - m_vocoderCarrSpread, m_vocoderSpectralBal, m_vocoderBands, m_vocoderAttack, m_vocoderRelease, m_vocoderSourceBal; + // Vocoder + juce::Slider m_vocoderCenterFreq, m_vocoderModOffset, m_vocoderModQ, m_vocoderModSpread, m_vocoderCarrQ, + m_vocoderCarrSpread, m_vocoderSpectralBal, m_vocoderBands, m_vocoderAttack, m_vocoderRelease, + m_vocoderSourceBal; - Buttons::Button4 m_vocoderLink; - juce::ComboBox m_vocoderMode; - juce::ComboBox m_vocoderModInput; + Buttons::Button4 m_vocoderLink; + juce::ComboBox m_vocoderMode; + juce::ComboBox m_vocoderModInput; - std::unique_ptr<juce::Drawable> m_background; -}; + std::unique_ptr<juce::Drawable> m_background; + }; +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel4_ArpEditor.cpp b/source/jucePlugin/ui2/Virus_Panel4_ArpEditor.cpp @@ -4,374 +4,404 @@ #include "../VirusParameterBinding.h" #include "VirusEditor.h" -using namespace juce; -using namespace virusLib; +namespace Trancy +{ + + using namespace juce; + using namespace virusLib; + static uint8_t g_playMode = 0; + ArpEditor::ArpEditor(::VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef) : + processorRef(_processorRef), m_properties(_processorRef.getController().getConfig()), + m_controller(_processorRef.getController()), m_parameterBinding(_parameterBinding) + { + setupBackground(*this, m_background, BinaryData::panel_4_png, BinaryData::panel_4_pngSize); + setBounds(m_background->getDrawableBounds().toNearestIntEdges()); + + int xPosMargin = 10; + + // Inputs + addAndMakeVisible(m_inputMode); + m_inputMode.setBounds(1488 + xPosMargin - comboBox3Width / 2, 821 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + addAndMakeVisible(m_inputSelect); + m_inputSelect.setBounds(1488 + xPosMargin - comboBox3Width / 2, 921 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + _parameterBinding.bind(m_inputMode, Virus::Param_InputMode); + _parameterBinding.bind(m_inputSelect, Virus::Param_InputSelect); + + // Arpeggiator + constexpr auto y = 18; + for (auto *s : {&m_globalTempo, &m_noteLength, &m_noteSwing}) + setupRotary(*this, *s); + + m_globalTempo.setBounds(1970 - knobSize / 2, 613 - knobSize / 2, knobSize, knobSize); + m_noteLength.setBounds(1424 - knobSize / 2, 613 - knobSize / 2, knobSize, knobSize); + m_noteSwing.setBounds(1574 - knobSize / 2, 613 - knobSize / 2, knobSize, knobSize); + + for (auto *c : {&m_mode, &m_pattern, &m_octaveRange, &m_resolution}) + addAndMakeVisible(c); + + m_mode.setBounds(1228 + xPosMargin - comboBox3Width / 2, 558 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_pattern.setBounds(1228 + xPosMargin - comboBox3Width / 2, 656 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_resolution.setBounds(1773 + xPosMargin - comboBox3Width / 2, 656 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_octaveRange.setBounds(1773 + xPosMargin - comboBox3Width / 2, 558 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + addAndMakeVisible(m_arpHold); + + m_arpHold.setBounds(2129 - m_arpHold.kWidth / 2, 613 - m_arpHold.kHeight / 2, m_arpHold.kWidth, + m_arpHold.kHeight); + m_globalTempo.setEnabled(false); + m_globalTempo.setAlpha(0.3f); + + _parameterBinding.bind(m_globalTempo, Virus::Param_ClockTempo, 0); + _parameterBinding.bind(m_noteLength, Virus::Param_ArpNoteLength); + _parameterBinding.bind(m_noteSwing, Virus::Param_ArpSwing); + _parameterBinding.bind(m_mode, Virus::Param_ArpMode); + _parameterBinding.bind(m_pattern, Virus::Param_ArpPatternSelect); + _parameterBinding.bind(m_octaveRange, Virus::Param_ArpOctaveRange); + _parameterBinding.bind(m_resolution, Virus::Param_ArpClock); + _parameterBinding.bind(m_arpHold, Virus::Param_ArpHoldEnable); + + // SoftKnobs + m_softknobFunc1.setBounds(1756 + xPosMargin - comboBox3Width / 2, 822 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_softknobFunc2.setBounds(1756 + xPosMargin - comboBox3Width / 2, 921 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_softknobName1.setBounds(1983 + xPosMargin - comboBox3Width / 2, 822 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_softknobName2.setBounds(1983 + xPosMargin - comboBox3Width / 2, 921 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + for (auto *c : {&m_softknobFunc1, &m_softknobFunc2, &m_softknobName1, &m_softknobName2}) + addAndMakeVisible(c); + + _parameterBinding.bind(m_softknobName1, Virus::Param_SoftKnob1ShortName); + _parameterBinding.bind(m_softknobName2, Virus::Param_SoftKnob2ShortName); + _parameterBinding.bind(m_softknobFunc1, Virus::Param_SoftKnob1Single); + _parameterBinding.bind(m_softknobFunc2, Virus::Param_SoftKnob2Single); + + // PatchSettings + for (auto *s : {&m_patchVolume, &m_panning, &m_outputBalance, &m_transpose}) + setupRotary(*this, *s); + + for (auto *c : {&m_patchVolume, &m_panning, &m_outputBalance, &m_transpose}) + addAndMakeVisible(c); + + m_patchVolume.setBounds(1428 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_panning.setBounds(1572 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_outputBalance.setBounds(1715 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + m_transpose.setBounds(1862 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); + + for (auto *c : {&m_keyMode, &m_bendUp, &m_bendDown, &m_bendScale, &m_smoothMode, &m_cat1, &m_cat2}) + addAndMakeVisible(c); + + m_keyMode.setBounds(1232 + xPosMargin - comboBox3Width / 2, 113 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_smoothMode.setBounds(1232 + xPosMargin - comboBox3Width / 2, 259 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_bendScale.setBounds(1436 + xPosMargin - comboBox3Width / 2, 259 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_bendUp.setBounds(1641 + xPosMargin - comboBox3Width / 2, 259 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_bendDown.setBounds(1848 + xPosMargin - comboBox3Width / 2, 259 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + m_cat1.setBounds(1232 + xPosMargin - comboBox3Width / 2, 382 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + m_cat2.setBounds(1436 + xPosMargin - comboBox3Width / 2, 382 - comboBox3Height / 2, comboBox3Width, + comboBox3Height); + + _parameterBinding.bind(m_patchVolume, Virus::Param_PatchVolume); + _parameterBinding.bind(m_panning, Virus::Param_Panorama); + //_parameterBinding.bind(m_outputBalance, Virus::Param_SecondOutputBalance); + _parameterBinding.bind(m_transpose, Virus::Param_Transpose); + _parameterBinding.bind(m_keyMode, Virus::Param_KeyMode); + _parameterBinding.bind(m_bendUp, Virus::Param_BenderRangeUp); + _parameterBinding.bind(m_bendDown, Virus::Param_BenderRangeDown); + _parameterBinding.bind(m_bendScale, Virus::Param_BenderScale); + _parameterBinding.bind(m_smoothMode, Virus::Param_ControlSmoothMode); + _parameterBinding.bind(m_cat1, Virus::Param_Category1); + _parameterBinding.bind(m_cat2, Virus::Param_Category2); + _parameterBinding.bind(m_secondaryOutput, Virus::Param_PartOutputSelect); + + // Channels + int iMarginYChannels = 118; + int iMarginXChannels = 0; + int iIndex = 0; + + for (auto pt = 0; pt < 16; pt++) + { + if (pt == 8) + { + iIndex = 0; + iMarginXChannels = 549; + } + + // Buttons + m_partSelect[pt].setBounds(95 - m_partSelect[pt].kWidth / 2 + iMarginXChannels, + 96 - m_partSelect[pt].kHeight / 2 + iIndex * (iMarginYChannels), + m_partSelect[pt].kWidth, m_partSelect[pt].kHeight); + m_partSelect[pt].setRadioGroupId(kPartGroupId); + m_partSelect[pt].setClickingTogglesState(true); + m_partSelect[pt].onClick = [this, pt]() { this->changePart(pt); }; + addAndMakeVisible(m_partSelect[pt]); + + m_presetNames[pt].setBounds(245 - 225 / 2 + iMarginXChannels, 97 - 70 / 2 + iIndex * (iMarginYChannels), + 225, 70); + m_presetNames[pt].setText(m_controller.getCurrentPartPresetName(pt), dontSendNotification); + m_presetNames[pt].setFont(Font("Register", "Normal", 23.f)); + m_presetNames[pt].setJustificationType(Justification::left); + + addAndMakeVisible(m_presetNames[pt]); + + // Knobs + for (auto *s : {&m_partVolumes[pt], &m_partPans[pt]}) + { + setupRotary(*this, *s); + } + + m_partVolumes[pt].setLookAndFeel(&m_lookAndFeelSmallButton); + m_partVolumes[pt].setBounds(407 - knobSizeSmall / 2 + iMarginXChannels, + 98 - knobSizeSmall / 2 + iIndex * (iMarginYChannels), knobSizeSmall, + knobSizeSmall); + _parameterBinding.bind(m_partVolumes[pt], Virus::Param_PartVolume, pt); + addAndMakeVisible(m_partVolumes[pt]); + + m_partPans[pt].setLookAndFeel(&m_lookAndFeelSmallButton); + m_partPans[pt].setBounds(495 - knobSizeSmall / 2 + iMarginXChannels, + 98 - knobSizeSmall / 2 + iIndex * (iMarginYChannels), knobSizeSmall, + knobSizeSmall); + _parameterBinding.bind(m_partPans[pt], Virus::Param_Panorama, pt); + addAndMakeVisible(m_partPans[pt]); + + iIndex++; + } + + m_btWorkingMode.setBounds(1203 - m_btWorkingMode.kWidth / 2, 868 - m_btWorkingMode.kHeight / 2, + m_btWorkingMode.kWidth, m_btWorkingMode.kHeight); + addAndMakeVisible(m_btWorkingMode); + m_btWorkingMode.onClick = [this]() { + if (m_btWorkingMode.getToggleState() == 1) + { + setPlayMode(virusLib::PlayMode::PlayModeSingle); + } + else + { + setPlayMode(virusLib::PlayMode::PlayModeMulti); + } + updatePlayModeButtons(); + }; + + m_partSelect[m_controller.getCurrentPart()].setToggleState(true, NotificationType::dontSendNotification); + refreshParts(); + + MidiInit(); + } + + ArpEditor::~ArpEditor() + { + for (auto pt = 0; pt < 16; pt++) + { + m_partVolumes[pt].setLookAndFeel(nullptr); + m_partPans[pt].setLookAndFeel(nullptr); + } + } + + void ArpEditor::MidiInit() + { + // MIDI settings + String midiIn = m_properties->getValue("midi_input", ""); + String midiOut = m_properties->getValue("midi_output", ""); + + if (midiIn != "") + { + processorRef.setMidiInput(midiIn); + } + if (midiOut != "") + { + processorRef.setMidiOutput(midiOut); + } -static uint8_t g_playMode = 0; + m_cmbMidiInput.setBounds(2138 - 250 / 2, 81 - 47 / 2, 250, 47); + m_cmbMidiOutput.setBounds(2138 - 250 / 2, 178 - 47 / 2, 250, 47); -ArpEditor::ArpEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef): - processorRef(_processorRef), m_properties(_processorRef.getController().getConfig()), m_controller(_processorRef.getController()), m_parameterBinding(_parameterBinding) -{ - setupBackground(*this, m_background, BinaryData::panel_4_png, BinaryData::panel_4_pngSize); - setBounds(m_background->getDrawableBounds().toNearestIntEdges()); - - int xPosMargin = 10; - - //Inputs - addAndMakeVisible(m_inputMode); - m_inputMode.setBounds(1488 + xPosMargin - comboBox3Width/2, 821 - comboBox3Height/2, comboBox3Width, comboBox3Height); - addAndMakeVisible(m_inputSelect); - m_inputSelect.setBounds(1488 + xPosMargin - comboBox3Width/2, 921 - comboBox3Height/2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_inputMode, Virus::Param_InputMode); - _parameterBinding.bind(m_inputSelect, Virus::Param_InputSelect); - - //Arpeggiator - constexpr auto y = 18; - for (auto *s : {&m_globalTempo, &m_noteLength, &m_noteSwing}) - setupRotary(*this, *s); - - m_globalTempo.setBounds(1970 - knobSize / 2, 613 - knobSize / 2, knobSize, knobSize); - m_noteLength.setBounds(1424 - knobSize / 2, 613 - knobSize / 2, knobSize, knobSize); - m_noteSwing.setBounds(1574 - knobSize / 2, 613 - knobSize / 2, knobSize, knobSize); - - for (auto *c : {&m_mode, &m_pattern, &m_octaveRange, &m_resolution}) - addAndMakeVisible(c); - - m_mode.setBounds(1228 + xPosMargin - comboBox3Width/2, 558 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_pattern.setBounds(1228 + xPosMargin - comboBox3Width/2, 656 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_resolution.setBounds(1773 + xPosMargin - comboBox3Width/2, 656 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_octaveRange.setBounds(1773 + xPosMargin - comboBox3Width/2, 558 - comboBox3Height/2, comboBox3Width, comboBox3Height); - - addAndMakeVisible(m_arpHold); - - m_arpHold.setBounds(2129 - m_arpHold.kWidth/ 2, 613 - m_arpHold.kHeight / 2, m_arpHold.kWidth, m_arpHold.kHeight); - m_globalTempo.setEnabled(false); - m_globalTempo.setAlpha(0.3f); - - _parameterBinding.bind(m_globalTempo, Virus::Param_ClockTempo, 0); - _parameterBinding.bind(m_noteLength, Virus::Param_ArpNoteLength); - _parameterBinding.bind(m_noteSwing, Virus::Param_ArpSwing); - _parameterBinding.bind(m_mode, Virus::Param_ArpMode); - _parameterBinding.bind(m_pattern, Virus::Param_ArpPatternSelect); - _parameterBinding.bind(m_octaveRange, Virus::Param_ArpOctaveRange); - _parameterBinding.bind(m_resolution, Virus::Param_ArpClock); - _parameterBinding.bind(m_arpHold, Virus::Param_ArpHoldEnable); - - //SoftKnobs - m_softknobFunc1.setBounds(1756 + xPosMargin - comboBox3Width/2, 822 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_softknobFunc2.setBounds(1756 + xPosMargin - comboBox3Width/2, 921 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_softknobName1.setBounds(1983 + xPosMargin - comboBox3Width/2, 822 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_softknobName2.setBounds(1983 + xPosMargin - comboBox3Width/2, 921 - comboBox3Height/2, comboBox3Width, comboBox3Height); - - for (auto *c : {&m_softknobFunc1, &m_softknobFunc2, &m_softknobName1, &m_softknobName2}) - addAndMakeVisible(c); - - _parameterBinding.bind(m_softknobName1, Virus::Param_SoftKnob1ShortName); - _parameterBinding.bind(m_softknobName2, Virus::Param_SoftKnob2ShortName); - _parameterBinding.bind(m_softknobFunc1, Virus::Param_SoftKnob1Single); - _parameterBinding.bind(m_softknobFunc2, Virus::Param_SoftKnob2Single); - - //PatchSettings - for (auto *s : {&m_patchVolume, &m_panning, &m_outputBalance, &m_transpose}) - setupRotary(*this, *s); - - for (auto *c : {&m_patchVolume, &m_panning, &m_outputBalance, &m_transpose}) - addAndMakeVisible(c); - - m_patchVolume.setBounds(1428 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_panning.setBounds(1572 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_outputBalance.setBounds(1715 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - m_transpose.setBounds(1862 - knobSize / 2, 113 - knobSize / 2, knobSize, knobSize); - - for (auto *c : {&m_keyMode, &m_bendUp, &m_bendDown, &m_bendScale, &m_smoothMode, &m_cat1, &m_cat2}) - addAndMakeVisible(c); - - m_keyMode.setBounds(1232 + xPosMargin - comboBox3Width/2, 113 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_smoothMode.setBounds(1232 + xPosMargin - comboBox3Width/2, 259 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_bendScale.setBounds(1436 + xPosMargin - comboBox3Width/2, 259 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_bendUp.setBounds(1641 + xPosMargin - comboBox3Width/2, 259 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_bendDown.setBounds(1848 + xPosMargin - comboBox3Width/2, 259 - comboBox3Height/2, comboBox3Width, comboBox3Height); - - m_cat1.setBounds(1232 + xPosMargin - comboBox3Width/2, 382 - comboBox3Height/2, comboBox3Width, comboBox3Height); - m_cat2.setBounds(1436 + xPosMargin - comboBox3Width/2, 382 - comboBox3Height/2, comboBox3Width, comboBox3Height); - - _parameterBinding.bind(m_patchVolume, Virus::Param_PatchVolume); - _parameterBinding.bind(m_panning, Virus::Param_Panorama); - //_parameterBinding.bind(m_outputBalance, Virus::Param_SecondOutputBalance); - _parameterBinding.bind(m_transpose, Virus::Param_Transpose); - _parameterBinding.bind(m_keyMode, Virus::Param_KeyMode); - _parameterBinding.bind(m_bendUp, Virus::Param_BenderRangeUp); - _parameterBinding.bind(m_bendDown, Virus::Param_BenderRangeDown); - _parameterBinding.bind(m_bendScale, Virus::Param_BenderScale); - _parameterBinding.bind(m_smoothMode, Virus::Param_ControlSmoothMode); - _parameterBinding.bind(m_cat1, Virus::Param_Category1); - _parameterBinding.bind(m_cat2, Virus::Param_Category2); - _parameterBinding.bind(m_secondaryOutput, Virus::Param_PartOutputSelect); - - //Channels - int iMarginYChannels = 118; - int iMarginXChannels = 0; - int iIndex = 0; - - for (auto pt = 0; pt < 16; pt++) - { - if (pt==8) - { - iIndex=0; - iMarginXChannels=549; - } - - //Buttons - m_partSelect[pt].setBounds(95 - m_partSelect[pt].kWidth/2 + iMarginXChannels, 96 - m_partSelect[pt].kHeight/2 + iIndex*(iMarginYChannels), m_partSelect[pt].kWidth, m_partSelect[pt].kHeight); - m_partSelect[pt].setRadioGroupId(kPartGroupId); - m_partSelect[pt].setClickingTogglesState(true); - m_partSelect[pt].onClick = [this, pt]() {this->changePart(pt);}; - addAndMakeVisible(m_partSelect[pt]); - - m_presetNames[pt].setBounds(245 - 225/2 + iMarginXChannels, 97 - 70/2 + iIndex * (iMarginYChannels), 225, 70); - m_presetNames[pt].setText(m_controller.getCurrentPartPresetName(pt), dontSendNotification); - m_presetNames[pt].setFont(Font("Register", "Normal", 23.f)); - m_presetNames[pt].setJustificationType(Justification::left); - - addAndMakeVisible(m_presetNames[pt]); - - //Knobs - for (auto *s : {&m_partVolumes[pt], &m_partPans[pt]}) - { - setupRotary(*this, *s); - } - - m_partVolumes[pt].setLookAndFeel(&m_lookAndFeelSmallButton); - m_partVolumes[pt].setBounds(407 - knobSizeSmall / 2 + iMarginXChannels, 98 - knobSizeSmall / 2 + iIndex * (iMarginYChannels), knobSizeSmall, knobSizeSmall); - _parameterBinding.bind(m_partVolumes[pt], Virus::Param_PartVolume, pt); - addAndMakeVisible(m_partVolumes[pt]); - - m_partPans[pt].setLookAndFeel(&m_lookAndFeelSmallButton); - m_partPans[pt].setBounds(495 - knobSizeSmall / 2 + iMarginXChannels, 98 - knobSizeSmall / 2 + iIndex * (iMarginYChannels), knobSizeSmall, knobSizeSmall); - _parameterBinding.bind(m_partPans[pt], Virus::Param_Panorama, pt); - addAndMakeVisible(m_partPans[pt]); - - iIndex++; - } - - m_btWorkingMode.setBounds(1203 - m_btWorkingMode.kWidth / 2, 868 - m_btWorkingMode.kHeight / 2, m_btWorkingMode.kWidth, m_btWorkingMode.kHeight); - addAndMakeVisible(m_btWorkingMode); - m_btWorkingMode.onClick = [this]() - { - if (m_btWorkingMode.getToggleState()==1) + addAndMakeVisible(m_cmbMidiInput); + addAndMakeVisible(m_cmbMidiOutput); + + m_cmbMidiInput.setTextWhenNoChoicesAvailable("No MIDI Inputs Enabled"); + auto midiInputs = MidiInput::getAvailableDevices(); + StringArray midiInputNames; + midiInputNames.add(" - Midi In - "); + auto inIndex = 0; + + for (int i = 0; i < midiInputs.size(); i++) + { + const auto input = midiInputs[i]; + if (processorRef.getMidiInput() != nullptr && + input.identifier == processorRef.getMidiInput()->getIdentifier()) + { + inIndex = i + 1; + } + midiInputNames.add(input.name); + } + + m_cmbMidiInput.addItemList(midiInputNames, 1); + m_cmbMidiInput.setSelectedItemIndex(inIndex, dontSendNotification); + m_cmbMidiOutput.setTextWhenNoChoicesAvailable("No MIDI Outputs Enabled"); + auto midiOutputs = MidiOutput::getAvailableDevices(); + StringArray midiOutputNames; + midiOutputNames.add(" - Midi Out - "); + auto outIndex = 0; + + for (int i = 0; i < midiOutputs.size(); i++) + { + const auto output = midiOutputs[i]; + if (processorRef.getMidiOutput() != nullptr && + output.identifier == processorRef.getMidiOutput()->getIdentifier()) + { + outIndex = i + 1; + } + midiOutputNames.add(output.name); + } + + m_cmbMidiOutput.addItemList(midiOutputNames, 1); + m_cmbMidiOutput.setSelectedItemIndex(outIndex, dontSendNotification); + m_cmbMidiInput.onChange = [this]() { updateMidiInput(m_cmbMidiInput.getSelectedItemIndex()); }; + m_cmbMidiOutput.onChange = [this]() { updateMidiOutput(m_cmbMidiOutput.getSelectedItemIndex()); }; + } + + + void ArpEditor::refreshParts() + { + const auto multiMode = m_controller.isMultiMode(); + for (auto pt = 0; pt < 16; pt++) + { + bool singlePartOrInMulti = pt == 0 || multiMode; + float fAlpha = (multiMode) ? 1.0 : 0.3; + + if (pt > 0) + { + m_partVolumes[pt].setEnabled(singlePartOrInMulti); + m_partVolumes[pt].setAlpha(fAlpha); + m_partPans[pt].setEnabled(singlePartOrInMulti); + m_partPans[pt].setAlpha(fAlpha); + m_partSelect[pt].setEnabled(singlePartOrInMulti); + m_partSelect[pt].setAlpha(fAlpha); + m_presetNames[pt].setEnabled(singlePartOrInMulti); + m_presetNames[pt].setAlpha(fAlpha); + } + if (singlePartOrInMulti) + m_presetNames[pt].setText(m_controller.getCurrentPartPresetName(pt), dontSendNotification); + else + m_presetNames[pt].setText("", dontSendNotification); + } + + updatePlayModeButtons(); + } + + void ArpEditor::changePart(uint8_t _part) + { + for (auto &p : m_partSelect) + { + p.setToggleState(false, dontSendNotification); + } + m_partSelect[_part].setToggleState(true, dontSendNotification); + m_parameterBinding.setPart(_part); + getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); + getParentComponent()->postCommandMessage(VirusEditor::Commands::Rebind); + } + + void ArpEditor::setPlayMode(uint8_t _mode) + { + m_controller.getParameter(Virus::Param_PlayMode)->setValue(_mode); + if (_mode == virusLib::PlayModeSingle && m_controller.getCurrentPart() != 0) + { + changePart(0); + } + getParentComponent()->postCommandMessage(VirusEditor::Commands::Rebind); + } + + + void ArpEditor::updatePlayModeButtons() + { + const auto modeParam = m_controller.getParameter(Virus::Param_PlayMode, 0); + if (modeParam == nullptr) + { + return; + } + const auto _mode = (int)modeParam->getValue(); + if (_mode == virusLib::PlayModeSingle) { - setPlayMode(virusLib::PlayMode::PlayModeSingle); - } - else + m_btWorkingMode.setToggleState(true, dontSendNotification); + } + else if (_mode == virusLib::PlayModeMulti || _mode == virusLib::PlayModeMultiSingle) { - setPlayMode(virusLib::PlayMode::PlayModeMulti); - } - updatePlayModeButtons(); - }; + m_btWorkingMode.setToggleState(false, dontSendNotification); + } + } - m_partSelect[m_controller.getCurrentPart()].setToggleState(true, NotificationType::dontSendNotification); - refreshParts(); + void ArpEditor::updateMidiInput(int index) + { + auto list = MidiInput::getAvailableDevices(); - MidiInit(); -} + if (index == 0) + { + m_properties->setValue("midi_input", ""); + m_properties->save(); + m_lastInputIndex = index; + m_cmbMidiInput.setSelectedItemIndex(index, dontSendNotification); + return; + } + index--; + auto newInput = list[index]; + + if (!deviceManager.isMidiInputDeviceEnabled(newInput.identifier)) + deviceManager.setMidiInputDeviceEnabled(newInput.identifier, true); + + if (!processorRef.setMidiInput(newInput.identifier)) + { + m_cmbMidiInput.setSelectedItemIndex(0, dontSendNotification); + m_lastInputIndex = 0; + return; + } -ArpEditor::~ArpEditor() -{ - for (auto pt = 0; pt < 16; pt++) - { - m_partVolumes[pt].setLookAndFeel(nullptr); - m_partPans[pt].setLookAndFeel(nullptr); - } -} - -void ArpEditor::MidiInit() -{ - //MIDI settings - String midiIn = m_properties->getValue("midi_input", ""); - String midiOut = m_properties->getValue("midi_output", ""); - - if (midiIn != "") - { - processorRef.setMidiInput(midiIn); - } - if (midiOut != "") - { - processorRef.setMidiOutput(midiOut); - } - - m_cmbMidiInput.setBounds(2138 - 250 / 2, 81 - 47 / 2, 250, 47); - m_cmbMidiOutput.setBounds(2138 - 250 / 2, 178 - 47 / 2, 250, 47); - - addAndMakeVisible(m_cmbMidiInput); - addAndMakeVisible(m_cmbMidiOutput); - - m_cmbMidiInput.setTextWhenNoChoicesAvailable("No MIDI Inputs Enabled"); - auto midiInputs = MidiInput::getAvailableDevices(); - StringArray midiInputNames; - midiInputNames.add(" - Midi In - "); - auto inIndex = 0; - - for (int i = 0; i < midiInputs.size(); i++) - { - const auto input = midiInputs[i]; - if (processorRef.getMidiInput() != nullptr && input.identifier == processorRef.getMidiInput()->getIdentifier()) - { - inIndex = i + 1; - } - midiInputNames.add(input.name); - } - - m_cmbMidiInput.addItemList(midiInputNames, 1); - m_cmbMidiInput.setSelectedItemIndex(inIndex, dontSendNotification); - m_cmbMidiOutput.setTextWhenNoChoicesAvailable("No MIDI Outputs Enabled"); - auto midiOutputs = MidiOutput::getAvailableDevices(); - StringArray midiOutputNames; - midiOutputNames.add(" - Midi Out - "); - auto outIndex = 0; - - for (int i = 0; i < midiOutputs.size(); i++) - { - const auto output = midiOutputs[i]; - if (processorRef.getMidiOutput() != nullptr && - output.identifier == processorRef.getMidiOutput()->getIdentifier()) - { - outIndex = i + 1; - } - midiOutputNames.add(output.name); - } - - m_cmbMidiOutput.addItemList(midiOutputNames, 1); - m_cmbMidiOutput.setSelectedItemIndex(outIndex, dontSendNotification); - m_cmbMidiInput.onChange = [this]() { updateMidiInput(m_cmbMidiInput.getSelectedItemIndex()); }; - m_cmbMidiOutput.onChange = [this]() { updateMidiOutput(m_cmbMidiOutput.getSelectedItemIndex()); }; -} - - -void ArpEditor::refreshParts() -{ - const auto multiMode = m_controller.isMultiMode(); - for (auto pt = 0; pt < 16; pt++) - { - bool singlePartOrInMulti = pt == 0 || multiMode; - float fAlpha=(multiMode)?1.0:0.3; - - if (pt>0) - { - m_partVolumes[pt].setEnabled(singlePartOrInMulti); - m_partVolumes[pt].setAlpha(fAlpha); - m_partPans[pt].setEnabled(singlePartOrInMulti); - m_partPans[pt].setAlpha(fAlpha); - m_partSelect[pt].setEnabled(singlePartOrInMulti); - m_partSelect[pt].setAlpha(fAlpha); - m_presetNames[pt].setEnabled(singlePartOrInMulti); - m_presetNames[pt].setAlpha(fAlpha); - } - if (singlePartOrInMulti) - m_presetNames[pt].setText(m_controller.getCurrentPartPresetName(pt), dontSendNotification); - else - m_presetNames[pt].setText("", dontSendNotification); - } - - updatePlayModeButtons(); -} - -void ArpEditor::changePart(uint8_t _part) -{ - for (auto &p : m_partSelect) - { - p.setToggleState(false, dontSendNotification); - } - m_partSelect[_part].setToggleState(true, dontSendNotification); - m_parameterBinding.setPart(_part); - getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); - getParentComponent()->postCommandMessage(VirusEditor::Commands::Rebind); -} - -void ArpEditor::setPlayMode(uint8_t _mode) -{ - m_controller.getParameter(Virus::Param_PlayMode)->setValue(_mode); - if (_mode == virusLib::PlayModeSingle && m_controller.getCurrentPart() != 0) - { - changePart(0); - } - getParentComponent()->postCommandMessage(VirusEditor::Commands::Rebind); -} + m_properties->setValue("midi_input", newInput.identifier); + m_properties->save(); + m_cmbMidiInput.setSelectedItemIndex(index + 1, dontSendNotification); + m_lastInputIndex = index; + } -void ArpEditor::updatePlayModeButtons() -{ - const auto modeParam = m_controller.getParameter(Virus::Param_PlayMode, 0); - if (modeParam == nullptr) { - return; - } - const auto _mode = (int)modeParam->getValue(); - if (_mode == virusLib::PlayModeSingle) - { - m_btWorkingMode.setToggleState(true, dontSendNotification); - } - else if (_mode == virusLib::PlayModeMulti || _mode == virusLib::PlayModeMultiSingle) - { - m_btWorkingMode.setToggleState(false, dontSendNotification); - } -} - -void ArpEditor::updateMidiInput(int index) -{ - auto list = MidiInput::getAvailableDevices(); - - if (index == 0) - { - m_properties->setValue("midi_input", ""); - m_properties->save(); - m_lastInputIndex = index; - m_cmbMidiInput.setSelectedItemIndex(index, dontSendNotification); - return; - } - index--; - auto newInput = list[index]; - - if (!deviceManager.isMidiInputDeviceEnabled(newInput.identifier)) - deviceManager.setMidiInputDeviceEnabled(newInput.identifier, true); - - if (!processorRef.setMidiInput(newInput.identifier)) - { - m_cmbMidiInput.setSelectedItemIndex(0, dontSendNotification); - m_lastInputIndex = 0; - return; - } - - m_properties->setValue("midi_input", newInput.identifier); - m_properties->save(); - - m_cmbMidiInput.setSelectedItemIndex(index + 1, dontSendNotification); - m_lastInputIndex = index; -} - -void ArpEditor::updateMidiOutput(int index) -{ - auto list = MidiOutput::getAvailableDevices(); - - if (index == 0) - { - m_properties->setValue("midi_output", ""); - m_properties->save(); - m_cmbMidiOutput.setSelectedItemIndex(index, dontSendNotification); - m_lastOutputIndex = index; - processorRef.setMidiOutput(""); - return; - } - index--; - auto newOutput = list[index]; - if (!processorRef.setMidiOutput(newOutput.identifier)) - { - m_cmbMidiOutput.setSelectedItemIndex(0, dontSendNotification); - m_lastOutputIndex = 0; - return; - } - m_properties->setValue("midi_output", newOutput.identifier); - m_properties->save(); - - m_cmbMidiOutput.setSelectedItemIndex(index + 1, dontSendNotification); - m_lastOutputIndex = index; -} + void ArpEditor::updateMidiOutput(int index) + { + auto list = MidiOutput::getAvailableDevices(); + + if (index == 0) + { + m_properties->setValue("midi_output", ""); + m_properties->save(); + m_cmbMidiOutput.setSelectedItemIndex(index, dontSendNotification); + m_lastOutputIndex = index; + processorRef.setMidiOutput(""); + return; + } + index--; + auto newOutput = list[index]; + if (!processorRef.setMidiOutput(newOutput.identifier)) + { + m_cmbMidiOutput.setSelectedItemIndex(0, dontSendNotification); + m_lastOutputIndex = 0; + return; + } + m_properties->setValue("midi_output", newOutput.identifier); + m_properties->save(); + + m_cmbMidiOutput.setSelectedItemIndex(index + 1, dontSendNotification); + m_lastOutputIndex = index; + } +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel4_ArpEditor.h b/source/jucePlugin/ui2/Virus_Panel4_ArpEditor.h @@ -5,64 +5,66 @@ #include <juce_gui_extra/juce_gui_extra.h> #include "../VirusController.h" #include "Virus_LookAndFeel.h" - class VirusParameterBinding; - -class ArpEditor : public juce::Component +namespace Trancy { -public: - ArpEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef); - ~ArpEditor() override; + class ArpEditor : public juce::Component + { + public: + ArpEditor(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef); + ~ArpEditor() override; + + static constexpr auto kPartGroupId = 0x3FBBC; + void refreshParts(); + + private: + void updateMidiInput(int index); + void updateMidiOutput(int index); + void MidiInit(); + VirusUI::LookAndFeelSmallButton m_lookAndFeelSmallButton; + + // WorkingMode + juce::ComboBox m_WorkingMode; + + // Channels + void changePart(uint8_t _part); + void setPlayMode(uint8_t _mode); + void updatePlayModeButtons(); + Virus::Controller &m_controller; + VirusParameterBinding &m_parameterBinding; - static constexpr auto kPartGroupId = 0x3FBBC; - void refreshParts(); -private: - void updateMidiInput(int index); - void updateMidiOutput(int index); - void MidiInit(); - Virus::LookAndFeelSmallButton m_lookAndFeelSmallButton; + Buttons::Button3 m_partSelect[16]; + juce::Label m_presetNames[16]; + juce::Slider m_partVolumes[16]; + juce::Slider m_partPans[16]; - //WorkingMode - juce::ComboBox m_WorkingMode; + Buttons::Button2 m_btWorkingMode; - //Channels - void changePart(uint8_t _part); - void setPlayMode(uint8_t _mode); - void updatePlayModeButtons(); - Virus::Controller &m_controller; - VirusParameterBinding &m_parameterBinding; + // MIDI Settings + juce::AudioDeviceManager deviceManager; + juce::ComboBox m_cmbMidiInput; + juce::ComboBox m_cmbMidiOutput; + int m_lastInputIndex = 0; + int m_lastOutputIndex = 0; + juce::PropertiesFile *m_properties; + AudioPluginAudioProcessor &processorRef; - Buttons::Button3 m_partSelect[16]; - juce::Label m_presetNames[16]; - juce::Slider m_partVolumes[16]; - juce::Slider m_partPans[16]; - - Buttons::Button2 m_btWorkingMode; + // Inputs + juce::ComboBox m_inputMode, m_inputSelect; - //MIDI Settings - juce::AudioDeviceManager deviceManager; - juce::ComboBox m_cmbMidiInput; - juce::ComboBox m_cmbMidiOutput; - int m_lastInputIndex = 0; - int m_lastOutputIndex = 0; - juce::PropertiesFile *m_properties; - AudioPluginAudioProcessor &processorRef; + // Arpeggiator + juce::Slider m_globalTempo, m_noteLength, m_noteSwing; + juce::ComboBox m_mode, m_pattern, m_octaveRange, m_resolution; + Buttons::Button3 m_arpHold; - //Inputs - juce::ComboBox m_inputMode, m_inputSelect; - - //Arpeggiator - juce::Slider m_globalTempo, m_noteLength, m_noteSwing; - juce::ComboBox m_mode, m_pattern, m_octaveRange, m_resolution; - Buttons::Button3 m_arpHold; + // SoftKnobs + juce::ComboBox m_softknobFunc1, m_softknobFunc2, m_softknobName1, m_softknobName2; - //SoftKnobs - juce::ComboBox m_softknobFunc1, m_softknobFunc2, m_softknobName1, m_softknobName2; + // PatchSettings + juce::Slider m_patchVolume, m_panning, m_outputBalance, m_transpose; + juce::ComboBox m_keyMode, m_secondaryOutput; + juce::ComboBox m_bendUp, m_bendDown, m_bendScale, m_smoothMode, m_cat1, m_cat2; - //PatchSettings - juce::Slider m_patchVolume, m_panning, m_outputBalance, m_transpose; - juce::ComboBox m_keyMode, m_secondaryOutput; - juce::ComboBox m_bendUp, m_bendDown, m_bendScale, m_smoothMode, m_cat1, m_cat2; - - std::unique_ptr<juce::Drawable> m_background; -}; + std::unique_ptr<juce::Drawable> m_background; + }; +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel5_PatchBrowser.cpp b/source/jucePlugin/ui2/Virus_Panel5_PatchBrowser.cpp @@ -6,679 +6,684 @@ #include <juce_cryptography/juce_cryptography.h> #include "VirusEditor.h" -using namespace juce; -using namespace virusLib; - -float fBrowserScaleFactor = 2.0f; - -const Array<String> categories = {"", "Lead", "Bass", "Pad", "Decay", "Pluck", - "Acid", "Classic", "Arpeggiator", "Effects", "Drums", "Percussion", - "Input", "Vocoder", "Favourite 1", "Favourite 2", "Favourite 3"}; - -PatchBrowser::PatchBrowser(VirusParameterBinding & _parameterBinding, AudioPluginAudioProcessor &_processorRef) : - m_parameterBinding(_parameterBinding), m_properties(_processorRef.getController().getConfig()), - m_controller(_processorRef.getController()), - m_patchList("Patch browser"), - m_fileFilter("*.syx;*.mid;*.midi", "*", "virus patch dumps"), - m_bankList(FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles, File::getSpecialLocation(File::SpecialLocationType::currentApplicationFile), &m_fileFilter, NULL), - m_search("Search Box") +namespace Trancy { - setupBackground(*this, m_background, BinaryData::panel_5_png, BinaryData::panel_5_pngSize); - - m_bankList.setLookAndFeel(&m_landf); - - //PatchBrowser - m_bankList.setBounds(0, 185/fBrowserScaleFactor , 1030/fBrowserScaleFactor , 810/fBrowserScaleFactor ); - auto bankDir = m_properties->getValue("virus_bank_dir", ""); - if (bankDir != "" && File(bankDir).isDirectory()) - { - m_bankList.setRoot(bankDir); - } - - setBounds(0, 0, kPanelWidth, kPanelHeight); - - //PatchList - m_patchList.setBounds(1049/fBrowserScaleFactor , 50/fBrowserScaleFactor , 1010/fBrowserScaleFactor , 870/fBrowserScaleFactor ); - - m_patchList.getHeader().addColumn("#", ColumnsPatch::INDEX, 32); - m_patchList.getHeader().addColumn("Name", ColumnsPatch::NAME, 130); - m_patchList.getHeader().addColumn("Category1", ColumnsPatch::CAT1, 84); - m_patchList.getHeader().addColumn("Category2", ColumnsPatch::CAT2, 84); - m_patchList.getHeader().addColumn("Arp", ColumnsPatch::ARP, 32); - m_patchList.getHeader().addColumn("Uni", ColumnsPatch::UNI, 32); - m_patchList.getHeader().addColumn("ST+-", ColumnsPatch::ST, 32); - m_patchList.getHeader().addColumn("Ver", ColumnsPatch::VER, 32); - - addAndMakeVisible(m_patchList); - - m_bankList.setTransform(AffineTransform::scale(fBrowserScaleFactor)); - m_patchList.setTransform(AffineTransform::scale(fBrowserScaleFactor)); - - m_bankList.addListener(this); - m_patchList.setModel(this); - - //Search - m_search.setTransform(AffineTransform::scale(fBrowserScaleFactor)); - m_search.setSize(m_patchList.getWidth(), 20); - m_search.setColour(TextEditor::textColourId, Colours::white); - - m_search.setTopLeftPosition(m_patchList.getBounds().getBottomLeft().translated(0, 8)); - - m_search.onTextChange = [this] { - m_filteredPatches.clear(); - for(auto patch : m_patches) { - const auto searchValue = m_search.getText(); - if (searchValue.isEmpty()) { - m_filteredPatches.add(patch); - } - else if(patch.name.containsIgnoreCase(searchValue)) { - if (patch.name!="") - m_filteredPatches.add(patch); - } - } - m_patchList.updateContent(); - m_patchList.deselectAllRows(); - m_patchList.repaint(); - }; - m_search.setTextToShowWhenEmpty("search...", Colours::grey); - addAndMakeVisible(m_search); - - //Show Options Buttons/Cmb - addAndMakeVisible(m_SavePreset); - addAndMakeVisible(m_ROMBankSelect); - addAndMakeVisible(m_bankList); - - m_ROMBankSelect.setBounds(510 - 961 / 2, 78 - 51 / 2, 961, 51); - for (int i=1; i<=m_controller.getBankCount();i++) + + using namespace juce; + using namespace virusLib; + + float fBrowserScaleFactor = 2.0f; + + const Array<String> categories = {"", "Lead", "Bass", "Pad", "Decay", "Pluck", + "Acid", "Classic", "Arpeggiator", "Effects", "Drums", "Percussion", + "Input", "Vocoder", "Favourite 1", "Favourite 2", "Favourite 3"}; + + PatchBrowser::PatchBrowser(::VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef) : + m_parameterBinding(_parameterBinding), m_properties(_processorRef.getController().getConfig()), + m_controller(_processorRef.getController()), m_patchList("Patch browser"), + m_fileFilter("*.syx;*.mid;*.midi", "*", "virus patch dumps"), + m_bankList(FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles, + File::getSpecialLocation(File::SpecialLocationType::currentApplicationFile), &m_fileFilter, NULL), + m_search("Search Box") { - m_ROMBankSelect.addItem("BANK: " + getCurrentPartBankStr((virusLib::BankNumber)i),i+1); - } - - m_ROMBankSelect.onChange = [this]() - { - m_LastBankRomNoUsed = m_ROMBankSelect.getSelectedItemIndex()+1; - LoadBankNr(m_LastBankRomNoUsed); - m_bIsFileMode = false; - m_search.setText("", true); - getParentComponent()->postCommandMessage(VirusEditor::Commands::SelectFirstPatch); - getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); - SaveSettings(); - }; - - m_SavePreset.setBounds(2197 - m_SavePreset.kWidth / 2, 72 - m_SavePreset.kHeight / 2, m_SavePreset.kWidth, m_SavePreset.kHeight); - m_SavePreset.onClick = [this]() { savePreset(); }; -} - -PatchBrowser::~PatchBrowser() -{ - setLookAndFeel(nullptr); - m_bankList.setLookAndFeel(nullptr); -} - -void PatchBrowser::IntiPatches() -{ - //Read Last Patch used from config file - m_bIsFileMode = m_properties->getBoolValue("is_file_used", false); - m_LastBankRomNoUsed = m_properties->getIntValue("last_bank_rom_no_used", 1); - m_LastFileUsed = m_properties->getValue("last_file_used", ""); + setupBackground(*this, m_background, BinaryData::panel_5_png, BinaryData::panel_5_pngSize); + + m_bankList.setLookAndFeel(&m_landf); + + // PatchBrowser + m_bankList.setBounds(0, 185 / fBrowserScaleFactor, 1030 / fBrowserScaleFactor, 810 / fBrowserScaleFactor); + auto bankDir = m_properties->getValue("virus_bank_dir", ""); + if (bankDir != "" && File(bankDir).isDirectory()) + { + m_bankList.setRoot(bankDir); + } + + setBounds(0, 0, kPanelWidth, kPanelHeight); + + // PatchList + m_patchList.setBounds(1049 / fBrowserScaleFactor, 50 / fBrowserScaleFactor, 1010 / fBrowserScaleFactor, + 870 / fBrowserScaleFactor); + + m_patchList.getHeader().addColumn("#", ColumnsPatch::INDEX, 32); + m_patchList.getHeader().addColumn("Name", ColumnsPatch::NAME, 130); + m_patchList.getHeader().addColumn("Category1", ColumnsPatch::CAT1, 84); + m_patchList.getHeader().addColumn("Category2", ColumnsPatch::CAT2, 84); + m_patchList.getHeader().addColumn("Arp", ColumnsPatch::ARP, 32); + m_patchList.getHeader().addColumn("Uni", ColumnsPatch::UNI, 32); + m_patchList.getHeader().addColumn("ST+-", ColumnsPatch::ST, 32); + m_patchList.getHeader().addColumn("Ver", ColumnsPatch::VER, 32); + + addAndMakeVisible(m_patchList); + + m_bankList.setTransform(AffineTransform::scale(fBrowserScaleFactor)); + m_patchList.setTransform(AffineTransform::scale(fBrowserScaleFactor)); + + m_bankList.addListener(this); + m_patchList.setModel(this); + + // Search + m_search.setTransform(AffineTransform::scale(fBrowserScaleFactor)); + m_search.setSize(m_patchList.getWidth(), 20); + m_search.setColour(TextEditor::textColourId, Colours::white); + + m_search.setTopLeftPosition(m_patchList.getBounds().getBottomLeft().translated(0, 8)); + + m_search.onTextChange = [this] { + m_filteredPatches.clear(); + for (auto patch : m_patches) + { + const auto searchValue = m_search.getText(); + if (searchValue.isEmpty()) + { + m_filteredPatches.add(patch); + } + else if (patch.name.containsIgnoreCase(searchValue)) + { + if (patch.name != "") + m_filteredPatches.add(patch); + } + } + m_patchList.updateContent(); + m_patchList.deselectAllRows(); + m_patchList.repaint(); + }; + m_search.setTextToShowWhenEmpty("search...", Colours::grey); + addAndMakeVisible(m_search); + + // Show Options Buttons/Cmb + addAndMakeVisible(m_SavePreset); + addAndMakeVisible(m_ROMBankSelect); + addAndMakeVisible(m_bankList); + + m_ROMBankSelect.setBounds(510 - 961 / 2, 78 - 51 / 2, 961, 51); + for (int i = 1; i <= m_controller.getBankCount(); i++) + { + m_ROMBankSelect.addItem("BANK: " + getCurrentPartBankStr((virusLib::BankNumber)i), i + 1); + } + + m_ROMBankSelect.onChange = [this]() { + m_LastBankRomNoUsed = m_ROMBankSelect.getSelectedItemIndex() + 1; + LoadBankNr(m_LastBankRomNoUsed); + m_bIsFileMode = false; + m_search.setText("", true); + getParentComponent()->postCommandMessage(VirusEditor::Commands::SelectFirstPatch); + getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); + SaveSettings(); + }; + + m_SavePreset.setBounds(2197 - m_SavePreset.kWidth / 2, 72 - m_SavePreset.kHeight / 2, m_SavePreset.kWidth, + m_SavePreset.kHeight); + m_SavePreset.onClick = [this]() { savePreset(); }; + } + + PatchBrowser::~PatchBrowser() + { + setLookAndFeel(nullptr); + m_bankList.setLookAndFeel(nullptr); + } - if(!m_bIsFileMode) + void PatchBrowser::IntiPatches() { - m_controller.setCurrentPartPreset(0,(virusLib::BankNumber)(m_LastBankRomNoUsed),0); - m_ROMBankSelect.setSelectedItemIndex(m_LastBankRomNoUsed-1, dontSendNotification); - LoadBankNr(m_LastBankRomNoUsed); - m_search.setText("", true); - - } - else - { - m_bankList.setFileName(m_LastFileUsed); - m_bankList.selectionChanged(); - const File &file(m_LastFileUsed); - LoadPatchesFromFile(file); - } -} - -void PatchBrowser::SaveSettings() -{ - m_properties->setValue("last_file_used", m_LastFileUsed); - m_properties->setValue("is_file_used", m_bIsFileMode); - m_properties->setValue("last_bank_rom_no_used", m_LastBankRomNoUsed); - m_properties->save(); -} + // Read Last Patch used from config file + m_bIsFileMode = m_properties->getBoolValue("is_file_used", false); + m_LastBankRomNoUsed = m_properties->getIntValue("last_bank_rom_no_used", 1); + m_LastFileUsed = m_properties->getValue("last_file_used", ""); + + if (!m_bIsFileMode) + { + m_controller.setCurrentPartPreset(0, (virusLib::BankNumber)(m_LastBankRomNoUsed), 0); + m_ROMBankSelect.setSelectedItemIndex(m_LastBankRomNoUsed - 1, dontSendNotification); + LoadBankNr(m_LastBankRomNoUsed); + m_search.setText("", true); + } + else + { + m_bankList.setFileName(m_LastFileUsed); + m_bankList.selectionChanged(); + const File &file(m_LastFileUsed); + LoadPatchesFromFile(file); + } + } + + void PatchBrowser::SaveSettings() + { + m_properties->setValue("last_file_used", m_LastFileUsed); + m_properties->setValue("is_file_used", m_bIsFileMode); + m_properties->setValue("last_bank_rom_no_used", m_LastBankRomNoUsed); + m_properties->save(); + } -String PatchBrowser::GetLastPatchSelected() -{ - return m_LastPatchSelected; -} + String PatchBrowser::GetLastPatchSelected() { return m_LastPatchSelected; } -TableListBox* PatchBrowser::GetTablePatchList() -{ - return &m_patchList; -} + TableListBox *PatchBrowser::GetTablePatchList() { return &m_patchList; } -String PatchBrowser::GetSelectBankNum() -{ - return getCurrentPartBankStr((virusLib::BankNumber)m_LastBankRomNoUsed); -} + String PatchBrowser::GetSelectBankNum() { return getCurrentPartBankStr((virusLib::BankNumber)m_LastBankRomNoUsed); } + bool PatchBrowser::GetIsFileMode() { return m_bIsFileMode; } + void PatchBrowser::selectionChanged() {} -bool PatchBrowser::GetIsFileMode() -{ - return m_bIsFileMode; -} + void PatchBrowser::LoadBankNr(int iBankNo) + { + StringArray patches = m_controller.getSinglePresetNames((virusLib::BankNumber)(iBankNo)); + m_patches.clear(); + + for (int i = 0; i < 128; i++) + { + Patch patch; + patch.progNumber = i; + // data.copyTo(patch.data, 267*index + 9, 256); + patch.name = patches.strings[i]; + patch.category1 = 0; + patch.category2 = 0; + patch.unison = 0; + patch.transpose = 0; + patch.model = VirusModel::A; + m_patches.add(patch); + } + + m_filteredPatches.clear(); + for (auto patch : m_patches) + { + const auto searchValue = m_search.getText(); + if (searchValue.isEmpty()) + { + m_filteredPatches.add(patch); + } + else if (patch.name.containsIgnoreCase(searchValue)) + { + m_filteredPatches.add(patch); + } + } + m_patchList.updateContent(); + m_patchList.deselectAllRows(); + m_patchList.repaint(); + } + + + int PatchBrowser::loadBankFile(const File &file, const int _startIndex = 0, const bool dedupe = false) + { + auto ext = file.getFileExtension().toLowerCase(); + auto path = file.getParentDirectory().getFullPathName(); + int loadedCount = 0; + int index = _startIndex; + if (ext == ".syx") + { + MemoryBlock data; + if (!file.loadFileAsData(data)) + { + return 0; + } + for (auto it = data.begin(); it != data.end(); it += 267) + { + if ((uint8_t)*it == (uint8_t)0xf0 && (uint8_t) * (it + 1) == (uint8_t)0x00 && + (uint8_t) * (it + 2) == (uint8_t)0x20 && (uint8_t) * (it + 3) == (uint8_t)0x33 && + (uint8_t) * (it + 4) == (uint8_t)0x01 && (uint8_t) * (it + 6) == (uint8_t)virusLib::DUMP_SINGLE) + { + Patch patch; + patch.progNumber = index; + data.copyTo(patch.data, 267 * index + 9, 256); + patch.name = parseAsciiText(patch.data, 128 + 112); + patch.category1 = patch.data[251]; + patch.category2 = patch.data[252]; + patch.unison = patch.data[97]; + patch.transpose = patch.data[93]; + if ((uint8_t) * (it + 266) != (uint8_t)0xf7 && (uint8_t) * (it + 266) != (uint8_t)0xf8) + { + patch.model = VirusModel::TI; + } + else + { + patch.model = guessVersion(patch.data); + } + auto md5 = MD5(it + 9 + 17, 256 - 17 - 3).toHexString(); + if (!dedupe || !m_checksums.contains(md5)) + { + m_checksums.set(md5, true); + m_patches.add(patch); + index++; + } + } + } + } + else if (ext == ".mid" || ext == ".midi") + { + MemoryBlock data; + if (!file.loadFileAsData(data)) + { + return 0; + } + + const uint8_t *ptr = (uint8_t *)data.getData(); + const auto end = ptr + data.getSize(); + + for (auto it = ptr; it < end; it += 1) + { + if ((uint8_t)*it == (uint8_t)0xf0 && + (it + 267) < end) // we don't check for sysex eof so we can load TI banks + { + if ((uint8_t) * (it + 1) == (uint8_t)0x00 && (uint8_t) * (it + 2) == 0x20 && + (uint8_t) * (it + 3) == 0x33 && (uint8_t) * (it + 4) == 0x01 && + (uint8_t) * (it + 6) == virusLib::DUMP_SINGLE) + { + auto syx = Virus::SysEx(it, it + 267); + syx[7] = 0x01; // force to bank a + syx[266] = 0xf7; + + Patch patch; + patch.progNumber = index; + std::copy(syx.begin() + 9, syx.end() - 2, patch.data); + patch.name = parseAsciiText(patch.data, 128 + 112); + patch.category1 = patch.data[251]; + patch.category2 = patch.data[252]; + patch.unison = patch.data[97]; + patch.transpose = patch.data[93]; + if ((uint8_t) * (it + 266) != (uint8_t)0xf7 && (uint8_t) * (it + 266) != (uint8_t)0xf8) + { + patch.model = VirusModel::TI; + } + else + { + patch.model = guessVersion(patch.data); + } + auto md5 = MD5(it + 9 + 17, 256 - 17 - 3).toHexString(); + if (!dedupe || !m_checksums.contains(md5)) + { + m_checksums.set(md5, true); + m_patches.add(patch); + index++; + } + + it += 266; + } + else if ((uint8_t) * (it + 3) == 0x00 // some midi files have two bytes after the 0xf0 + && (uint8_t) * (it + 4) == 0x20 && (uint8_t) * (it + 5) == 0x33 && + (uint8_t) * (it + 6) == 0x01 && (uint8_t) * (it + 8) == virusLib::DUMP_SINGLE) + { + auto syx = Virus::SysEx(); + syx.push_back(0xf0); + for (auto i = it + 3; i < it + 3 + 266; i++) + { + syx.push_back((uint8_t)*i); + } + syx[7] = 0x01; // force to bank a + syx[266] = 0xf7; + + Patch patch; + std::memcpy(patch.data, syx.data() + 9, 256); + patch.progNumber = index; + patch.name = parseAsciiText(patch.data, 128 + 112); + patch.category1 = patch.data[251]; + patch.category2 = patch.data[252]; + patch.unison = patch.data[97]; + patch.transpose = patch.data[93]; + if ((uint8_t) * (it + 2 + 266) != (uint8_t)0xf7 && (uint8_t) * (it + 2 + 266) != (uint8_t)0xf8) + { + patch.model = VirusModel::TI; + } + else + { + patch.model = guessVersion(patch.data); + } + auto md5 = MD5(it + 2 + 9 + 17, 256 - 17 - 3).toHexString(); + if (!dedupe || !m_checksums.contains(md5)) + { + m_checksums.set(md5, true); + m_patches.add(patch); + index++; + } + loadedCount++; + + it += 266; + } + } + } + } + return index; + } + + void PatchBrowser::fileClicked(const File &file, const MouseEvent &e) + { + auto ext = file.getFileExtension().toLowerCase(); + auto path = file.getParentDirectory().getFullPathName(); + + // Show popup only on directory + if (file.isDirectory() && e.mods.isRightButtonDown()) + { + auto p = PopupMenu(); + p.addItem("Add directory contents to patch list", [this, file]() { + m_patches.clear(); + m_checksums.clear(); + int lastIndex = 0; + for (auto f : RangedDirectoryIterator(file, false, "*.syx;*.mid;*.midi", File::findFiles)) + { + lastIndex = loadBankFile(f.getFile(), lastIndex, true); + } + m_filteredPatches.clear(); + for (auto patch : m_patches) + { + const auto searchValue = m_search.getText(); + if (searchValue.isEmpty()) + { + m_filteredPatches.add(patch); + } + else if (patch.name.containsIgnoreCase(searchValue)) + { + m_filteredPatches.add(patch); + } + } + m_patchList.updateContent(); + m_patchList.deselectAllRows(); + m_patchList.repaint(); + }); + p.showMenu(PopupMenu::Options()); + + return; + } + + m_properties->setValue("virus_bank_dir", path); + + if (file.existsAsFile() && ext == ".syx" || ext == ".midi" || ext == ".mid") + { + LoadPatchesFromFile(file); + m_LastFileUsed = file.getFullPathName(); + } + m_bIsFileMode = true; + m_search.setText("", true); + m_ROMBankSelect.setText("", true); + SaveSettings(); + getParentComponent()->postCommandMessage(VirusEditor::Commands::SelectFirstPatch); + getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); + } + + void PatchBrowser::LoadPatchesFromFile(const File &file) + { + m_patches.clear(); + loadBankFile(file); + m_filteredPatches.clear(); + for (auto patch : m_patches) + { + const auto searchValue = m_search.getText(); + if (searchValue.isEmpty()) + { + m_filteredPatches.add(patch); + } + else if (patch.name.containsIgnoreCase(searchValue)) + { + m_filteredPatches.add(patch); + } + } + m_patchList.updateContent(); + m_patchList.deselectAllRows(); + m_patchList.repaint(); + } + + + void PatchBrowser::fileDoubleClicked(const File &file) {} + + void PatchBrowser::browserRootChanged(const File &newRoot) {} + + int PatchBrowser::getNumRows() { return m_filteredPatches.size(); } + + void PatchBrowser::paintRowBackground(Graphics &g, int rowNumber, int width, int height, bool rowIsSelected) + { + auto alternateColour = getLookAndFeel() + .findColour(ListBox::backgroundColourId) + .interpolatedWith(getLookAndFeel().findColour(ListBox::textColourId), 0.03f); + if (rowIsSelected) + g.fillAll(Colours::lightblue); + else if (rowNumber % 2) + g.fillAll(alternateColour); + } + + void PatchBrowser::paintCell(Graphics &g, int rowNumber, int columnId, int width, int height, bool rowIsSelected) + { + // Banks from file + g.setColour(rowIsSelected ? Colours::darkblue : getLookAndFeel().findColour(ListBox::textColourId)); // [5] + + auto rowElement = m_filteredPatches[rowNumber]; + // auto text = rowElement.name; + String text = ""; + + if (m_bIsFileMode) + { + if (columnId == ColumnsPatch::INDEX) + text = String(rowElement.progNumber + 1); + else if (columnId == ColumnsPatch::NAME) + text = rowElement.name; + else if (columnId == ColumnsPatch::CAT1) + text = categories[rowElement.category1]; + else if (columnId == ColumnsPatch::CAT2) + text = categories[rowElement.category2]; + else if (columnId == ColumnsPatch::ARP) + text = rowElement.data[129] != 0 ? "Y" : " "; + else if (columnId == ColumnsPatch::UNI) + text = rowElement.unison == 0 ? " " : String(rowElement.unison + 1); + else if (columnId == ColumnsPatch::ST) + text = rowElement.transpose != 64 ? String(rowElement.transpose - 64) : " "; + else if (columnId == ColumnsPatch::VER) + { + if (rowElement.model < ModelList.size()) + text = ModelList[rowElement.model]; + } + } + else + { + if (columnId == ColumnsPatch::INDEX) + text = String(rowElement.progNumber + 1); + else if (columnId == ColumnsPatch::NAME) + text = rowElement.name; + } + + g.drawText(text, 2, 0, width - 4, height, Justification::centredLeft, true); // [6] + g.setColour(getLookAndFeel().findColour(ListBox::backgroundColourId)); + g.fillRect(width - 1, 0, 1, height); // [7] + } + + + void PatchBrowser::selectedRowsChanged(int lastRowSelected) + { + auto idx = m_patchList.getSelectedRow(); + if (idx == -1) + { + return; + } + + Component *c; + c = m_patchList.getCellComponent(1, idx); + + if (m_bIsFileMode) + { + uint8_t syxHeader[9] = {0xF0, 0x00, 0x20, 0x33, 0x01, 0x00, 0x10, 0x00, 0x00}; + syxHeader[8] = m_controller.isMultiMode() ? m_controller.getCurrentPart() + : virusLib::ProgramType::SINGLE; // set edit buffer + const uint8_t syxEof = 0xF7; + uint8_t cs = syxHeader[5] + syxHeader[6] + syxHeader[7] + syxHeader[8]; + uint8_t data[256]; + for (int i = 0; i < 256; i++) + { + data[i] = m_filteredPatches[idx].data[i]; + cs += data[i]; + } + cs = cs & 0x7f; + Virus::SysEx syx; + for (auto i : syxHeader) + { + syx.push_back(i); + } + for (auto i : data) + { + syx.push_back(i); + } + syx.push_back(cs); + syx.push_back(syxEof); + m_controller.sendSysEx(syx); // send to edit buffer + m_controller.parseMessage(syx); // update ui + + m_LastPatchSelected = parseAsciiText(data, 128 + 112); + getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); + } + else + { + m_controller.setCurrentPartPreset(m_controller.getCurrentPart(), (virusLib::BankNumber)m_LastBankRomNoUsed, + m_filteredPatches[idx].progNumber); + getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); + } + } + + void PatchBrowser::cellDoubleClicked(int rowNumber, int columnId, const MouseEvent &) + { + /* if(m_modeIndex==1) + { + selectedRowsChanged(0); + } + else if (m_modeIndex==0) + { + m_controller.setCurrentPartPreset(m_controller.getCurrentPart(),m_controller.getCurrentPartBank(m_controller.getCurrentPart()),lastRowSelected); + }*/ + } + + + void PatchBrowser::sortOrderChanged(int newSortColumnId, bool isForwards) + { + if (newSortColumnId != 0) + { + PatchBrowser::PatchBrowserSorter sorter(newSortColumnId, isForwards); + m_patches.sort(sorter); + m_patchList.updateContent(); + } + } -void PatchBrowser::selectionChanged() {} -void PatchBrowser::LoadBankNr(int iBankNo) -{ - StringArray patches = m_controller.getSinglePresetNames((virusLib::BankNumber)(iBankNo)); - m_patches.clear(); - - for (int i=0 ; i<128 ; i++) - { - Patch patch; - patch.progNumber = i; - //data.copyTo(patch.data, 267*index + 9, 256); - patch.name = patches.strings[i]; - patch.category1 = 0; - patch.category2 = 0; - patch.unison = 0; - patch.transpose = 0; - patch.model = VirusModel::A; - m_patches.add(patch); - } - - m_filteredPatches.clear(); - for(auto patch : m_patches) { - const auto searchValue = m_search.getText(); - if (searchValue.isEmpty()) { - m_filteredPatches.add(patch); - } - else if(patch.name.containsIgnoreCase(searchValue)) { - m_filteredPatches.add(patch); - } - } - m_patchList.updateContent(); - m_patchList.deselectAllRows(); - m_patchList.repaint(); -} - - -int PatchBrowser::loadBankFile(const File& file, const int _startIndex = 0, const bool dedupe = false) { - auto ext = file.getFileExtension().toLowerCase(); - auto path = file.getParentDirectory().getFullPathName(); - int loadedCount = 0; - int index = _startIndex; - if (ext == ".syx") - { - MemoryBlock data; - if (!file.loadFileAsData(data)) { - return 0; - } - for (auto it = data.begin(); it != data.end(); it += 267) - { - if ((uint8_t)*it == (uint8_t)0xf0 - && (uint8_t)*(it+1) == (uint8_t)0x00 - && (uint8_t)*(it+2) == (uint8_t)0x20 - && (uint8_t)*(it+3) == (uint8_t)0x33 - && (uint8_t)*(it+4) == (uint8_t)0x01 - && (uint8_t)*(it+6) == (uint8_t)virusLib::DUMP_SINGLE) - { - Patch patch; - patch.progNumber = index; - data.copyTo(patch.data, 267*index + 9, 256); - patch.name = parseAsciiText(patch.data, 128 + 112); - patch.category1 = patch.data[251]; - patch.category2 = patch.data[252]; - patch.unison = patch.data[97]; - patch.transpose = patch.data[93]; - if ((uint8_t)*(it + 266) != (uint8_t)0xf7 && (uint8_t)*(it + 266) != (uint8_t)0xf8) { - patch.model = VirusModel::TI; - } - else { - patch.model = guessVersion(patch.data); - } - auto md5 = MD5(it+9 + 17, 256-17-3).toHexString(); - if(!dedupe || !m_checksums.contains(md5)) { - m_checksums.set(md5, true); - m_patches.add(patch); - index++; - } - } - } - } - else if (ext == ".mid" || ext == ".midi") - { - MemoryBlock data; - if (!file.loadFileAsData(data)) - { - return 0; - } - - const uint8_t *ptr = (uint8_t *)data.getData(); - const auto end = ptr + data.getSize(); - - for (auto it = ptr; it < end; it += 1) - { - if ((uint8_t)*it == (uint8_t)0xf0 && (it + 267) < end) // we don't check for sysex eof so we can load TI banks - { - if ((uint8_t) *(it+1) == (uint8_t)0x00 - && (uint8_t)*(it+2) == 0x20 - && (uint8_t)*(it+3) == 0x33 - && (uint8_t)*(it+4) == 0x01 - && (uint8_t)*(it+6) == virusLib::DUMP_SINGLE) - { - auto syx = Virus::SysEx(it, it + 267); - syx[7] = 0x01; // force to bank a - syx[266] = 0xf7; - - Patch patch; - patch.progNumber = index; - std::copy(syx.begin() + 9, syx.end() - 2, patch.data); - patch.name = parseAsciiText(patch.data, 128 + 112); - patch.category1 = patch.data[251]; - patch.category2 = patch.data[252]; - patch.unison = patch.data[97]; - patch.transpose = patch.data[93]; - if ((uint8_t)*(it + 266) != (uint8_t)0xf7 && (uint8_t)*(it + 266) != (uint8_t)0xf8) { - patch.model = VirusModel::TI; - } - else { - patch.model = guessVersion(patch.data); - } - auto md5 = MD5(it+9 + 17, 256-17-3).toHexString(); - if(!dedupe || !m_checksums.contains(md5)) { - m_checksums.set(md5, true); - m_patches.add(patch); - index++; - } - - it += 266; - } - else if((uint8_t)*(it+3) == 0x00 // some midi files have two bytes after the 0xf0 - && (uint8_t)*(it+4) == 0x20 - && (uint8_t)*(it+5) == 0x33 - && (uint8_t)*(it+6) == 0x01 - && (uint8_t)*(it+8) == virusLib::DUMP_SINGLE) - { - auto syx = Virus::SysEx(); - syx.push_back(0xf0); - for (auto i = it + 3; i < it + 3 + 266; i++) - { - syx.push_back((uint8_t)*i); - } - syx[7] = 0x01; // force to bank a - syx[266] = 0xf7; - - Patch patch; - std::memcpy(patch.data, syx.data()+9, 256); - patch.progNumber = index; - patch.name = parseAsciiText(patch.data, 128 + 112); - patch.category1 = patch.data[251]; - patch.category2 = patch.data[252]; - patch.unison = patch.data[97]; - patch.transpose = patch.data[93]; - if ((uint8_t)*(it + 2 + 266) != (uint8_t)0xf7 && (uint8_t)*(it + 2 + 266) != (uint8_t)0xf8) { - patch.model = VirusModel::TI; - } - else { - patch.model = guessVersion(patch.data); - } - auto md5 = MD5(it+2+9 + 17, 256-17-3).toHexString(); - if(!dedupe || !m_checksums.contains(md5)) { - m_checksums.set(md5, true); - m_patches.add(patch); - index++; - } - loadedCount++; - - it += 266; - } - } - } - } - return index; -} - -void PatchBrowser::fileClicked(const File &file, const MouseEvent &e) -{ - auto ext = file.getFileExtension().toLowerCase(); - auto path = file.getParentDirectory().getFullPathName(); - - //Show popup only on directory - if (file.isDirectory() && e.mods.isRightButtonDown()) { - auto p = PopupMenu(); - p.addItem("Add directory contents to patch list", [this, file]() { - m_patches.clear(); - m_checksums.clear(); - int lastIndex = 0; - for (auto f : RangedDirectoryIterator(file, false, "*.syx;*.mid;*.midi", File::findFiles)) { - lastIndex = loadBankFile(f.getFile(), lastIndex, true); - } - m_filteredPatches.clear(); - for(auto patch : m_patches) { - const auto searchValue = m_search.getText(); - if (searchValue.isEmpty()) { - m_filteredPatches.add(patch); - } - else if(patch.name.containsIgnoreCase(searchValue)) { - m_filteredPatches.add(patch); - } - } - m_patchList.updateContent(); - m_patchList.deselectAllRows(); - m_patchList.repaint(); - }); - p.showMenu(PopupMenu::Options()); - - return; - } - - m_properties->setValue("virus_bank_dir", path); - - if(file.existsAsFile() && ext == ".syx" || ext == ".midi" || ext == ".mid") { - LoadPatchesFromFile(file); - m_LastFileUsed = file.getFullPathName(); - } - m_bIsFileMode = true; - m_search.setText("", true); - m_ROMBankSelect.setText("",true); - SaveSettings(); - getParentComponent()->postCommandMessage(VirusEditor::Commands::SelectFirstPatch); - getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); -} - -void PatchBrowser::LoadPatchesFromFile(const File &file) -{ - m_patches.clear(); - loadBankFile(file); - m_filteredPatches.clear(); - for(auto patch : m_patches) { - const auto searchValue = m_search.getText(); - if (searchValue.isEmpty()) { - m_filteredPatches.add(patch); - } - else if(patch.name.containsIgnoreCase(searchValue)) { - m_filteredPatches.add(patch); - } - } - m_patchList.updateContent(); - m_patchList.deselectAllRows(); - m_patchList.repaint(); -} - - -void PatchBrowser::fileDoubleClicked(const File &file) {} - -void PatchBrowser::browserRootChanged(const File &newRoot) {} - -int PatchBrowser::getNumRows() -{ - return m_filteredPatches.size(); -} - -void PatchBrowser::paintRowBackground(Graphics &g, int rowNumber, int width, int height, bool rowIsSelected) -{ - auto alternateColour = getLookAndFeel() - .findColour(ListBox::backgroundColourId) - .interpolatedWith(getLookAndFeel().findColour(ListBox::textColourId), 0.03f); - if (rowIsSelected) - g.fillAll(Colours::lightblue); - else if (rowNumber % 2) - g.fillAll(alternateColour); -} - -void PatchBrowser::paintCell(Graphics &g, int rowNumber, int columnId, int width, int height, bool rowIsSelected) -{ - //Banks from file - g.setColour(rowIsSelected ? Colours::darkblue - : getLookAndFeel().findColour(ListBox::textColourId)); // [5] - - auto rowElement = m_filteredPatches[rowNumber]; - //auto text = rowElement.name; - String text = ""; - - if (m_bIsFileMode) - { - if (columnId == ColumnsPatch::INDEX) - text = String(rowElement.progNumber+1); - else if (columnId == ColumnsPatch::NAME) - text = rowElement.name; - else if (columnId == ColumnsPatch::CAT1) - text = categories[rowElement.category1]; - else if (columnId == ColumnsPatch::CAT2) - text = categories[rowElement.category2]; - else if (columnId == ColumnsPatch::ARP) - text = rowElement.data[129] != 0 ? "Y" : " "; - else if(columnId == ColumnsPatch::UNI) - text = rowElement.unison == 0 ? " " : String(rowElement.unison+1); - else if(columnId == ColumnsPatch::ST) - text = rowElement.transpose != 64 ? String(rowElement.transpose - 64) : " "; - else if (columnId == ColumnsPatch::VER) { - if(rowElement.model < ModelList.size()) - text = ModelList[rowElement.model]; - } - } - else + void PatchBrowser::loadBankFileToRom(const File &file) { - if (columnId == ColumnsPatch::INDEX) - text = String(rowElement.progNumber+1); - else if (columnId == ColumnsPatch::NAME) - text = rowElement.name; - } - - g.drawText(text, 2, 0, width - 4, height, Justification::centredLeft, true); // [6] - g.setColour(getLookAndFeel().findColour(ListBox::backgroundColourId)); - g.fillRect(width - 1, 0, 1, height); // [7] - -} - - -void PatchBrowser::selectedRowsChanged(int lastRowSelected) { - auto idx = m_patchList.getSelectedRow(); - if (idx == -1) { - return; - } - - Component *c; - c = m_patchList.getCellComponent(1,idx); - - if (m_bIsFileMode) - { - uint8_t syxHeader[9] = {0xF0, 0x00, 0x20, 0x33, 0x01, 0x00, 0x10, 0x00, 0x00}; - syxHeader[8] = m_controller.isMultiMode() ? m_controller.getCurrentPart() : virusLib::ProgramType::SINGLE; // set edit buffer - const uint8_t syxEof = 0xF7; - uint8_t cs = syxHeader[5] + syxHeader[6] + syxHeader[7] + syxHeader[8]; - uint8_t data[256]; - for (int i = 0; i < 256; i++) - { - data[i] = m_filteredPatches[idx].data[i]; - cs += data[i]; - } - cs = cs & 0x7f; - Virus::SysEx syx; - for (auto i : syxHeader) - { - syx.push_back(i); - } - for (auto i : data) - { - syx.push_back(i); - } - syx.push_back(cs); - syx.push_back(syxEof); - m_controller.sendSysEx(syx); // send to edit buffer - m_controller.parseMessage(syx); // update ui - - m_LastPatchSelected = parseAsciiText(data, 128 + 112); - getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); - } - else - { - m_controller.setCurrentPartPreset(m_controller.getCurrentPart(), (virusLib::BankNumber) m_LastBankRomNoUsed, m_filteredPatches[idx].progNumber); - getParentComponent()->postCommandMessage(VirusEditor::Commands::UpdateParts); - } -} - -void PatchBrowser::cellDoubleClicked(int rowNumber, int columnId, const MouseEvent &) -{ - /* if(m_modeIndex==1) - { - selectedRowsChanged(0); - } - else if (m_modeIndex==0) - { - m_controller.setCurrentPartPreset(m_controller.getCurrentPart(),m_controller.getCurrentPartBank(m_controller.getCurrentPart()),lastRowSelected); - }*/ -} + bool sentData = false; + auto sExt = file.getFileExtension().toLowerCase(); + m_previousPath = file.getParentDirectory().getFullPathName(); + ; + MemoryBlock data; + + if (sExt == ".syx") + { + if (!file.loadFileAsData(data)) + { + return; + } + + for (auto it = data.begin(); it != data.end(); it += 267) + { + if ((it + 267) <= data.end()) + { + m_controller.sendSysEx(Virus::SysEx(it, it + 267)); + sentData = true; + } + } + } + else if (sExt == ".mid" || sExt == ".midi") + { + if (!file.loadFileAsData(data)) + { + return; + } + + const uint8_t *ptr = (uint8_t *)data.getData(); + const auto end = ptr + data.getSize(); + + for (auto it = ptr; it < end; it += 1) + { + if ((uint8_t)*it == (uint8_t)0xf0 && (it + 267) < end) + { + if ((uint8_t) * (it + 1) == 0x00 && (uint8_t) * (it + 2) == 0x20 && (uint8_t) * (it + 3) == 0x33 && + (uint8_t) * (it + 4) == 0x01 && (uint8_t) * (it + 6) == virusLib::DUMP_SINGLE) + { + auto syx = Virus::SysEx(it, it + 267); + syx[7] = 0x01; // force to bank a + syx[266] = 0xf7; + + m_controller.sendSysEx(syx); + + it += 266; + } + else if ((uint8_t) * (it + 3) == 0x00 && (uint8_t) * (it + 4) == 0x20 && + (uint8_t) * (it + 5) == 0x33 && (uint8_t) * (it + 6) == 0x01 && + (uint8_t) * (it + 8) == + virusLib::DUMP_SINGLE) // some midi files have two bytes after the 0xf0 + { + auto syx = Virus::SysEx(); + syx.push_back(0xf0); + for (auto i = it + 3; i < it + 3 + 266; i++) + { + syx.push_back((uint8_t)*i); + } + syx[7] = 0x01; // force to bank a + syx[266] = 0xf7; + m_controller.sendSysEx(syx); + it += 266; + } + + sentData = true; + } + } + } + + if (sentData) + { + m_controller.onStateLoaded(); + } + } + + + void PatchBrowser::loadFile() + { + MemoryBlock data; + FileChooser chooser("Choose syx/midi banks to import", + m_previousPath.isEmpty() + ? File::getSpecialLocation(File::currentApplicationFile).getParentDirectory() + : m_previousPath, + "*.syx,*.mid,*.midi", true); + if (!chooser.browseForFileToOpen()) + return; + loadBankFileToRom(chooser.getResult()); + } -void PatchBrowser::sortOrderChanged(int newSortColumnId, bool isForwards) -{ - if (newSortColumnId != 0) - { - PatchBrowser::PatchBrowserSorter sorter (newSortColumnId, isForwards); - m_patches.sort(sorter); - m_patchList.updateContent(); - } -} - - -void PatchBrowser::loadBankFileToRom(const File &file) -{ - bool sentData = false; - auto sExt = file.getFileExtension().toLowerCase(); - m_previousPath = file.getParentDirectory().getFullPathName();; - MemoryBlock data; - - if (sExt == ".syx") - { - if (!file.loadFileAsData(data)) - { - return; - } - - for (auto it = data.begin(); it != data.end(); it += 267) - { - if ((it + 267) <= data.end()) - { - m_controller.sendSysEx(Virus::SysEx(it, it + 267)); - sentData = true; - } - } - } - else if (sExt == ".mid" || sExt == ".midi") - { - if (!file.loadFileAsData(data)) - { - return; - } - - const uint8_t *ptr = (uint8_t *)data.getData(); - const auto end = ptr + data.getSize(); - - for (auto it = ptr; it < end; it += 1) - { - if ((uint8_t)*it == (uint8_t)0xf0 && (it + 267) < end) - { - if ((uint8_t)*(it+1) == 0x00 - && (uint8_t)*(it+2) == 0x20 - && (uint8_t)*(it+3) == 0x33 - && (uint8_t)*(it+4) == 0x01 - && (uint8_t)*(it+6) == virusLib::DUMP_SINGLE) - { - auto syx = Virus::SysEx(it, it + 267); - syx[7] = 0x01; // force to bank a - syx[266] = 0xf7; - - m_controller.sendSysEx(syx); - - it += 266; - } - else if((uint8_t)*(it+3) == 0x00 - && (uint8_t)*(it+4) == 0x20 - && (uint8_t)*(it+5) == 0x33 - && (uint8_t)*(it+6) == 0x01 - && (uint8_t)*(it+8) == virusLib::DUMP_SINGLE)// some midi files have two bytes after the 0xf0 - { - auto syx = Virus::SysEx(); - syx.push_back(0xf0); - for (auto i = it + 3; i < it + 3 + 266; i++) - { - syx.push_back((uint8_t)*i); - } - syx[7] = 0x01; // force to bank a - syx[266] = 0xf7; - m_controller.sendSysEx(syx); - it += 266; - } - - sentData = true; - } - } - } - - if (sentData) - { - m_controller.onStateLoaded(); - } -} - - -void PatchBrowser::loadFile() -{ - MemoryBlock data; - FileChooser chooser( - "Choose syx/midi banks to import", - m_previousPath.isEmpty() - ? File::getSpecialLocation(File::currentApplicationFile).getParentDirectory() - : m_previousPath, - "*.syx,*.mid,*.midi", true); - - if (!chooser.browseForFileToOpen()) - return; - - loadBankFileToRom(chooser.getResult()); -} - -void PatchBrowser::savePreset() { - FileChooser chooser( - "Save preset as syx", - m_previousPath.isEmpty() - ? File::getSpecialLocation(File::currentApplicationFile).getParentDirectory() - : m_previousPath, - "*.syx", true); - - if (!chooser.browseForFileToSave(true)) - return; - - bool sentData = false; - const auto result = chooser.getResult(); - m_previousPath = result.getParentDirectory().getFullPathName(); - const auto ext = result.getFileExtension().toLowerCase(); - - const uint8_t syxHeader[9] = {0xF0, 0x00, 0x20, 0x33, 0x01, 0x00, 0x10, 0x01, 0x00}; - const uint8_t syxEof[1] = {0xF7}; - uint8_t cs = syxHeader[5] + syxHeader[6] + syxHeader[7] + syxHeader[8]; - uint8_t data[256]; - for (int i = 0; i < 256; i++) - { - auto param = m_controller.getParamValue(m_controller.getCurrentPart(), i < 128 ? 0 : 1, i % 128); - - data[i] = param ? (int)param->getValue() : 0; - cs += data[i]; - } - cs = cs & 0x7f; - - result.deleteFile(); - result.create(); - result.appendData(syxHeader, 9); - result.appendData(data, 256); - result.appendData(&cs, 1); - result.appendData(syxEof, 1); -} + void PatchBrowser::savePreset() + { + FileChooser chooser("Save preset as syx", + m_previousPath.isEmpty() + ? File::getSpecialLocation(File::currentApplicationFile).getParentDirectory() + : m_previousPath, + "*.syx", true); + + if (!chooser.browseForFileToSave(true)) + return; + + bool sentData = false; + const auto result = chooser.getResult(); + m_previousPath = result.getParentDirectory().getFullPathName(); + const auto ext = result.getFileExtension().toLowerCase(); + + const uint8_t syxHeader[9] = {0xF0, 0x00, 0x20, 0x33, 0x01, 0x00, 0x10, 0x01, 0x00}; + const uint8_t syxEof[1] = {0xF7}; + uint8_t cs = syxHeader[5] + syxHeader[6] + syxHeader[7] + syxHeader[8]; + uint8_t data[256]; + for (int i = 0; i < 256; i++) + { + auto param = m_controller.getParamValue(m_controller.getCurrentPart(), i < 128 ? 0 : 1, i % 128); + + data[i] = param ? (int)param->getValue() : 0; + cs += data[i]; + } + cs = cs & 0x7f; + + result.deleteFile(); + result.create(); + result.appendData(syxHeader, 9); + result.appendData(data, 256); + result.appendData(&cs, 1); + result.appendData(syxEof, 1); + } +} // namespace Trancy +\ No newline at end of file diff --git a/source/jucePlugin/ui2/Virus_Panel5_PatchBrowser.h b/source/jucePlugin/ui2/Virus_Panel5_PatchBrowser.h @@ -5,151 +5,164 @@ #include <juce_gui_extra/juce_gui_extra.h> #include "../VirusController.h" -const juce::Array<juce::String> ModelList = {"A","B","C","TI"}; - -struct Patch -{ - int progNumber; - juce::String name; - uint8_t category1; - uint8_t category2; - uint8_t data[256]; - virusLib::VirusModel model; - uint8_t unison; - uint8_t transpose; -}; - - -class PatchBrowser : public juce::Component, juce::FileBrowserListener, juce::TableListBoxModel -{ - -public: - PatchBrowser(VirusParameterBinding &_parameterBinding, AudioPluginAudioProcessor &_processorRef); - ~PatchBrowser(); - void loadFile(); - void loadBankFileToRom(const juce::File &file); - void savePreset(); - bool GetIsFileMode(); - juce::String GetSelectBankNum(); - juce::String GetLastPatchSelected(); - juce::TableListBox* GetTablePatchList(); - - void IntiPatches(); -private: - - Virus::LookAndFeelPatchBrowser m_landf; - - VirusParameterBinding &m_parameterBinding; - Virus::Controller& m_controller; - - template <typename T> juce::String parseAsciiText(const T &msg, const int start) const - { - char text[Virus::Controller::kNameLength + 1]; - text[Virus::Controller::kNameLength] = 0; // termination - for (auto pos = 0; pos < Virus::Controller::kNameLength; ++pos) - text[pos] = msg[start + pos]; - return juce::String(text); - } - - juce::WildcardFileFilter m_fileFilter; - juce::FileBrowserComponent m_bankList; - - juce::TextEditor m_search; - juce::Array<Patch> m_patches; - juce::Array<Patch> m_filteredPatches; - juce::PropertiesFile *m_properties; - juce::HashMap<juce::String, bool> m_checksums; - int loadBankFile(const juce::File &file, const int _startIndex, const bool dedupe); - // Inherited via FileBrowserListener - Buttons::OptionButtonSavePreset m_SavePreset; - - void LoadBankNr(int iBankNo); - void SaveSettings(); - void LoadPatchesFromFile(const juce::File &file); - - juce::ComboBox m_ROMBankSelect; - juce::String m_previousPath; - juce::String m_LastFileUsed; - juce::TableListBox m_patchList; - juce::String m_LastPatchSelected; - - int m_LastBankRomNoUsed; - - bool m_bIsFileMode; - - // Inherited via FileBrowserListener - void selectionChanged() override; - void fileClicked(const juce::File &file, const juce::MouseEvent &e) override; - void fileDoubleClicked(const juce::File &file) override; - void browserRootChanged(const juce::File &newRoot) override; - - // Inherited via TableListBoxModel - virtual int getNumRows() override; - virtual void paintRowBackground(juce::Graphics &, int rowNumber, int width, int height, - bool rowIsSelected) override; - virtual void paintCell(juce::Graphics &, int rowNumber, int columnId, int width, int height, - bool rowIsSelected) override; - - virtual void selectedRowsChanged(int lastRowSelected) override; - virtual void cellDoubleClicked (int rowNumber, int columnId, const juce::MouseEvent &) override; - void sortOrderChanged(int newSortColumnId, bool isForwards) override; - class PatchBrowserSorter; - - enum ColumnsPatch { - INDEX = 1, - NAME = 2, - CAT1 = 3, - CAT2 = 4, - ARP = 5, - UNI = 6, - ST = 7, - VER = 8, - }; - - std::unique_ptr<juce::Drawable> m_background; -}; - - -class PatchBrowser::PatchBrowserSorter +namespace Trancy { -public: - PatchBrowserSorter (int attributeToSortBy, bool forwards) - : attributeToSort (attributeToSortBy), - direction (forwards ? 1 : -1) - {} - - int compareElements (Patch first, Patch second) const - { - if(attributeToSort == ColumnsPatch::INDEX) { - return direction * (first.progNumber - second.progNumber); - } - else if (attributeToSort == ColumnsPatch::NAME) { - return direction * first.name.compareIgnoreCase(second.name); - } - else if (attributeToSort == ColumnsPatch::CAT1) { - return direction * (first.category1 - second.category1); - } - else if (attributeToSort == ColumnsPatch::CAT2) { - return direction * (first.category2 - second.category2); - } - else if (attributeToSort == ColumnsPatch::ARP) { - return direction * (first.data[129]- second.data[129]); - } - else if (attributeToSort == ColumnsPatch::UNI) { - return direction * (first.unison - second.unison); - } - else if (attributeToSort == ColumnsPatch::VER) { - return direction * (first.model - second.model); - } - else if (attributeToSort == ColumnsPatch::ST) { - return direction * (first.transpose - second.transpose); - } - return direction * (first.progNumber - second.progNumber); - } - -private: - int attributeToSort; - int direction; -}; - - + using namespace juce; + const juce::Array<juce::String> ModelList = {"A", "B", "C", "TI"}; + + struct Patch + { + int progNumber; + juce::String name; + uint8_t category1; + uint8_t category2; + uint8_t data[256]; + virusLib::VirusModel model; + uint8_t unison; + uint8_t transpose; + }; + + + class PatchBrowser : public juce::Component, juce::FileBrowserListener, juce::TableListBoxModel + { + + public: + PatchBrowser(VirusParameterBinding & _parameterBinding, AudioPluginAudioProcessor &_processorRef); + ~PatchBrowser(); + void loadFile(); + void loadBankFileToRom(const juce::File &file); + void savePreset(); + bool GetIsFileMode(); + juce::String GetSelectBankNum(); + juce::String GetLastPatchSelected(); + juce::TableListBox *GetTablePatchList(); + + void IntiPatches(); + + private: + VirusUI::LookAndFeelPatchBrowser m_landf; + + VirusParameterBinding &m_parameterBinding; + Virus::Controller &m_controller; + + template <typename T> juce::String parseAsciiText(const T &msg, const int start) const + { + char text[Virus::Controller::kNameLength + 1]; + text[Virus::Controller::kNameLength] = 0; // termination + for (auto pos = 0; pos < Virus::Controller::kNameLength; ++pos) + text[pos] = msg[start + pos]; + return juce::String(text); + } + + juce::WildcardFileFilter m_fileFilter; + juce::FileBrowserComponent m_bankList; + + juce::TextEditor m_search; + juce::Array<Patch> m_patches; + juce::Array<Patch> m_filteredPatches; + juce::PropertiesFile *m_properties; + juce::HashMap<juce::String, bool> m_checksums; + int loadBankFile(const juce::File &file, const int _startIndex, const bool dedupe); + // Inherited via FileBrowserListener + Buttons::OptionButtonSavePreset m_SavePreset; + + void LoadBankNr(int iBankNo); + void SaveSettings(); + void LoadPatchesFromFile(const juce::File &file); + + juce::ComboBox m_ROMBankSelect; + juce::String m_previousPath; + juce::String m_LastFileUsed; + juce::TableListBox m_patchList; + juce::String m_LastPatchSelected; + + int m_LastBankRomNoUsed; + + bool m_bIsFileMode; + + // Inherited via FileBrowserListener + void selectionChanged() override; + void fileClicked(const juce::File &file, const juce::MouseEvent &e) override; + void fileDoubleClicked(const juce::File &file) override; + void browserRootChanged(const juce::File &newRoot) override; + + // Inherited via TableListBoxModel + virtual int getNumRows() override; + virtual void paintRowBackground(juce::Graphics &, int rowNumber, int width, int height, + bool rowIsSelected) override; + virtual void paintCell(juce::Graphics &, int rowNumber, int columnId, int width, int height, + bool rowIsSelected) override; + + virtual void selectedRowsChanged(int lastRowSelected) override; + virtual void cellDoubleClicked(int rowNumber, int columnId, const juce::MouseEvent &) override; + void sortOrderChanged(int newSortColumnId, bool isForwards) override; + class PatchBrowserSorter; + + enum ColumnsPatch + { + INDEX = 1, + NAME = 2, + CAT1 = 3, + CAT2 = 4, + ARP = 5, + UNI = 6, + ST = 7, + VER = 8, + }; + + std::unique_ptr<juce::Drawable> m_background; + }; + + + class PatchBrowser::PatchBrowserSorter + { + public: + PatchBrowserSorter(int attributeToSortBy, bool forwards) : + attributeToSort(attributeToSortBy), direction(forwards ? 1 : -1) + { + } + + int compareElements(Patch first, Patch second) const + { + if (attributeToSort == ColumnsPatch::INDEX) + { + return direction * (first.progNumber - second.progNumber); + } + else if (attributeToSort == ColumnsPatch::NAME) + { + return direction * first.name.compareIgnoreCase(second.name); + } + else if (attributeToSort == ColumnsPatch::CAT1) + { + return direction * (first.category1 - second.category1); + } + else if (attributeToSort == ColumnsPatch::CAT2) + { + return direction * (first.category2 - second.category2); + } + else if (attributeToSort == ColumnsPatch::ARP) + { + return direction * (first.data[129] - second.data[129]); + } + else if (attributeToSort == ColumnsPatch::UNI) + { + return direction * (first.unison - second.unison); + } + else if (attributeToSort == ColumnsPatch::VER) + { + return direction * (first.model - second.model); + } + else if (attributeToSort == ColumnsPatch::ST) + { + return direction * (first.transpose - second.transpose); + } + return direction * (first.progNumber - second.progNumber); + } + + private: + int attributeToSort; + int direction; + }; + + +} // namespace Trancy +\ No newline at end of file