Signed-off-by: falkTX <falktx@falktx.com>tags/v1.5
@@ -22,7 +22,7 @@ | |||
# add_subdirectory(DPF) | |||
# | |||
# dpf_add_plugin(MyPlugin | |||
# TARGETS lv2 vst2 | |||
# TARGETS lv2 vst2 vst3 | |||
# UI_TYPE opengl | |||
# FILES_DSP | |||
# src/MyPlugin.cpp | |||
@@ -71,7 +71,7 @@ include(CMakeParseArguments) | |||
# | |||
# `TARGETS` <tgt1>...<tgtN> | |||
# a list of one of more of the following target types: | |||
# `jack`, `ladspa`, `dssi`, `lv2`, `vst2` | |||
# `jack`, `ladspa`, `dssi`, `lv2`, `vst2`, `vst3` | |||
# | |||
# `UI_TYPE` <type> | |||
# the user interface type: `opengl` (default), `cairo` | |||
@@ -153,6 +153,8 @@ function(dpf_add_plugin NAME) | |||
dpf__build_lv2("${NAME}" "${_dgl_library}" "${_dpf_plugin_MONOLITHIC}") | |||
elseif(_target STREQUAL "vst2") | |||
dpf__build_vst2("${NAME}" "${_dgl_library}") | |||
elseif(_target STREQUAL "vst3") | |||
dpf__build_vst3("${NAME}" "${_dgl_library}") | |||
else() | |||
message(FATAL_ERROR "Unrecognized target type for plugin: ${_target}") | |||
endif() | |||
@@ -199,7 +201,7 @@ endfunction() | |||
# dpf__build_ladspa | |||
# ------------------------------------------------------------------------------ | |||
# | |||
# Add build rules for a DSSI plugin. | |||
# Add build rules for a LADSPA plugin. | |||
# | |||
function(dpf__build_ladspa NAME) | |||
dpf__create_dummy_source_list(_no_srcs) | |||
@@ -259,7 +261,7 @@ endfunction() | |||
# dpf__build_lv2 | |||
# ------------------------------------------------------------------------------ | |||
# | |||
# Add build rules for a LV2 plugin. | |||
# Add build rules for an LV2 plugin. | |||
# | |||
function(dpf__build_lv2 NAME DGL_LIBRARY MONOLITHIC) | |||
dpf__create_dummy_source_list(_no_srcs) | |||
@@ -339,6 +341,95 @@ function(dpf__build_vst2 NAME DGL_LIBRARY) | |||
endif() | |||
endfunction() | |||
# dpf__determine_vst3_package_architecture | |||
# ------------------------------------------------------------------------------ | |||
# | |||
# Determines the package architecture for a VST3 plugin target. | |||
# | |||
function(dpf__determine_vst3_package_architecture OUTPUT_VARIABLE) | |||
# if set by variable, override the detection | |||
if(DPF_VST3_ARCHITECTURE) | |||
set("${OUTPUT_VARIABLE}" "${DPF_VST3_ARCHITECTURE}" PARENT_SCOPE) | |||
return() | |||
endif() | |||
# not used on Apple, which supports universal binary | |||
if(APPLE) | |||
set("${OUTPUT_VARIABLE}" "universal" PARENT_SCOPE) | |||
return() | |||
endif() | |||
# identify the target processor (special case of MSVC, problematic sometimes) | |||
if(MSVC) | |||
set(vst3_system_arch "${MSVC_CXX_ARCHITECTURE_ID}") | |||
else() | |||
set(vst3_system_arch "${CMAKE_SYSTEM_PROCESSOR}") | |||
endif() | |||
# transform the processor name to a format that VST3 recognizes | |||
if(vst3_system_arch MATCHES "^(x86_64|amd64|AMD64|x64|X64)$") | |||
set(vst3_package_arch "x86_64") | |||
elseif(vst3_system_arch MATCHES "^(i.86|x86|X86)$") | |||
if(WIN32) | |||
set(vst3_package_arch "x86") | |||
else() | |||
set(vst3_package_arch "i386") | |||
endif() | |||
elseif(vst3_system_arch MATCHES "^(armv[3-8][a-z]*)$") | |||
set(vst3_package_arch "${vst3_system_arch}") | |||
elseif(vst3_system_arch MATCHES "^(aarch64)$") | |||
set(vst3_package_arch "aarch64") | |||
else() | |||
message(FATAL_ERROR "We don't know this architecture for VST3: ${vst3_system_arch}.") | |||
endif() | |||
# TODO: the detections for Windows arm/arm64 when supported | |||
set("${OUTPUT_VARIABLE}" "${vst3_package_arch}" PARENT_SCOPE) | |||
endfunction() | |||
# dpf__build_vst3 | |||
# ------------------------------------------------------------------------------ | |||
# | |||
# Add build rules for a VST3 plugin. | |||
# | |||
function(dpf__build_vst3 NAME DGL_LIBRARY) | |||
dpf__determine_vst3_package_architecture(vst3_arch) | |||
dpf__create_dummy_source_list(_no_srcs) | |||
dpf__add_module("${NAME}-vst3" ${_no_srcs}) | |||
dpf__add_plugin_main("${NAME}-vst3" "vst3") | |||
dpf__add_ui_main("${NAME}-vst3" "vst3" "${DGL_LIBRARY}") | |||
dpf__set_module_export_list("${NAME}-vst3" "vst3") | |||
target_link_libraries("${NAME}-vst3" PRIVATE "${NAME}-dsp" "${NAME}-ui") | |||
set_target_properties("${NAME}-vst3" PROPERTIES | |||
ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/obj/vst3/$<0:>" | |||
OUTPUT_NAME "${NAME}" | |||
PREFIX "") | |||
if(APPLE) | |||
set_target_properties("${NAME}-vst3" PROPERTIES | |||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.vst3/Contents/MacOS/$<0:>" | |||
SUFFIX "") | |||
elseif(WIN32) | |||
set_target_properties("${NAME}-vst3" PROPERTIES | |||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.vst3/Contents/${vst3_arch}-win/$<0:>") | |||
else() | |||
set_target_properties("${NAME}-vst3" PROPERTIES | |||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/${NAME}.vst3/Contents/${vst3_arch}-linux/$<0:>") | |||
endif() | |||
if(APPLE) | |||
# Uses the same macOS bundle template as VST2 | |||
set(INFO_PLIST_PROJECT_NAME "${NAME}") | |||
configure_file("${DPF_ROOT_DIR}/utils/plugin.vst/Contents/Info.plist" | |||
"${PROJECT_BINARY_DIR}/bin/${NAME}.vst3/Contents/Info.plist" @ONLY) | |||
file(COPY "${DPF_ROOT_DIR}/utils/plugin.vst/Contents/PkgInfo" | |||
DESTINATION "${PROJECT_BINARY_DIR}/bin/${NAME}.vst3/Contents") | |||
endif() | |||
endfunction() | |||
# dpf__add_dgl_cairo | |||
# ------------------------------------------------------------------------------ | |||
# | |||
@@ -1 +0,0 @@ | |||
pugl-upstream/include/ |
@@ -310,9 +310,9 @@ ScopedUTF16String::ScopedUTF16String(const char* const s) noexcept | |||
: str(nullptr) | |||
{ | |||
const size_t len = strlen(s); | |||
str = (int16_t*)malloc(sizeof(int16_t) * len); | |||
str = (int16_t*)malloc(sizeof(int16_t) * (len + 1)); | |||
DISTRHO_SAFE_ASSERT_RETURN(str != nullptr,); | |||
strncpy_utf16(str, s, len); | |||
strncpy_utf16(str, s, len + 1); | |||
} | |||
ScopedUTF16String::~ScopedUTF16String() noexcept | |||
@@ -1402,11 +1402,11 @@ public: | |||
v3_result getParameterInfo(int32_t rindex, v3_param_info* const info) const noexcept | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(rindex >= 0, V3_INVALID_ARG); | |||
std::memset(info, 0, sizeof(v3_param_info)); | |||
#if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
if (rindex == 0) | |||
{ | |||
std::memset(info, 0, sizeof(v3_param_info)); | |||
info->param_id = rindex; | |||
info->flags = V3_PARAM_CAN_AUTOMATE | V3_PARAM_IS_LIST | V3_PARAM_PROGRAM_CHANGE; | |||
info->step_count = fProgramCountMinusOne; | |||
@@ -1417,10 +1417,12 @@ public: | |||
--rindex; | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
if (rindex <= 130*16) | |||
if (rindex < 130*16) | |||
{ | |||
std::memset(info, 0, sizeof(v3_param_info)); | |||
info->param_id = rindex; | |||
# if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
++info->param_id; | |||
# endif | |||
info->flags = V3_PARAM_CAN_AUTOMATE | V3_PARAM_IS_HIDDEN; | |||
info->step_count = 127; | |||
char ccstr[24]; | |||
@@ -1465,7 +1467,6 @@ public: | |||
if ((hints & kParameterIsInteger) && ranges.max - ranges.min > 1) | |||
step_count = ranges.max - ranges.min - 1; | |||
std::memset(info, 0, sizeof(v3_param_info)); | |||
info->param_id = index + fParameterOffset; | |||
info->flags = flags; | |||
info->step_count = step_count; | |||
@@ -1493,7 +1494,7 @@ public: | |||
--rindex; | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
if (rindex <= 130*16) | |||
if (rindex < 130*16) | |||
{ | |||
snprintf_f32_utf16(output, std::round(normalised * 127), 128); | |||
return V3_OK; | |||
@@ -1519,7 +1520,7 @@ public: | |||
--rindex; | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
if (rindex <= 130*16) | |||
if (rindex < 130*16) | |||
{ | |||
// TODO | |||
return V3_NOT_IMPLEMENTED; | |||
@@ -1542,7 +1543,7 @@ public: | |||
--rindex; | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
if (rindex <= 130*16) | |||
if (rindex < 130*16) | |||
return std::round(normalised * 127); | |||
rindex -= 130*16; | |||
#endif | |||
@@ -1561,7 +1562,7 @@ public: | |||
--rindex; | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
if (rindex <= 130*16) | |||
if (rindex < 130*16) | |||
return std::max(0.0, std::min(1.0, plain / 127)); | |||
rindex -= 130*16; | |||
#endif | |||
@@ -1580,7 +1581,7 @@ public: | |||
--rindex; | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
if (rindex <= 130*16) | |||
if (rindex < 130*16) | |||
{ | |||
// TODO | |||
return 0.0; | |||
@@ -1625,7 +1626,7 @@ public: | |||
--rindex; | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
if (rindex <= 130*16) | |||
if (rindex < 130*16) | |||
{ | |||
// TODO | |||
fChangedParameterValues[rindex] = true; | |||
@@ -1775,7 +1776,7 @@ public: | |||
--rindex; | |||
# endif | |||
# if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
if (rindex <= 130*16) | |||
if (rindex < 130*16) | |||
continue; | |||
rindex -= 130*16; | |||
# endif | |||
@@ -1835,26 +1836,42 @@ public: | |||
# if DISTRHO_PLUGIN_WANT_STATE | |||
if (std::strcmp(msgid, "state-set") == 0) | |||
{ | |||
int16_t* key16; | |||
int16_t* value16; | |||
uint32_t keySize, valueSize; | |||
int64_t keyLength = -1; | |||
int64_t valueLength = -1; | |||
v3_result res; | |||
res = v3_cpp_obj(attrs)->get_binary(attrs, "key", (const void**)&key16, &keySize); | |||
res = v3_cpp_obj(attrs)->get_int(attrs, "key:length", &keyLength); | |||
DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); | |||
DISTRHO_SAFE_ASSERT_INT_RETURN(keyLength >= 0, keyLength, V3_INTERNAL_ERR); | |||
res = v3_cpp_obj(attrs)->get_int(attrs, "value:length", &valueLength); | |||
DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); | |||
DISTRHO_SAFE_ASSERT_INT_RETURN(valueLength >= 0, valueLength, V3_INTERNAL_ERR); | |||
int16_t* const key16 = (int16_t*)std::malloc(sizeof(int16_t)*(keyLength + 1)); | |||
DISTRHO_SAFE_ASSERT_RETURN(key16 != nullptr, V3_NOMEM); | |||
int16_t* const value16 = (int16_t*)std::malloc(sizeof(int16_t)*(valueLength + 1)); | |||
DISTRHO_SAFE_ASSERT_RETURN(value16 != nullptr, V3_NOMEM); | |||
res = v3_cpp_obj(attrs)->get_string(attrs, "key", key16, sizeof(int16_t)*keyLength); | |||
DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); | |||
res = v3_cpp_obj(attrs)->get_binary(attrs, "value", (const void**)&value16, &valueSize); | |||
res = v3_cpp_obj(attrs)->get_string(attrs, "value", value16, sizeof(int16_t)*valueLength); | |||
DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); | |||
// do cheap inline conversion | |||
char* const key = (char*)key16; | |||
char* const value = (char*)value16; | |||
for (uint32_t i=0; i<keySize/sizeof(int16_t); ++i) | |||
for (int64_t i=0; i<keyLength; ++i) | |||
key[i] = key16[i]; | |||
for (uint32_t i=0; i<valueSize/sizeof(int16_t); ++i) | |||
for (int64_t i=0; i<valueLength; ++i) | |||
value[i] = value16[i]; | |||
key[keyLength] = '\0'; | |||
value[valueLength] = '\0'; | |||
fPlugin.setState(key, value); | |||
// save this key as needed | |||
@@ -1867,6 +1884,8 @@ public: | |||
if (dkey == key) | |||
{ | |||
it->second = value; | |||
std::free(key16); | |||
std::free(value16); | |||
return V3_OK; | |||
} | |||
} | |||
@@ -1874,6 +1893,8 @@ public: | |||
d_stderr("Failed to find plugin state with key \"%s\"", key); | |||
} | |||
std::free(key16); | |||
std::free(value16); | |||
return V3_OK; | |||
} | |||
# endif | |||
@@ -2042,6 +2063,8 @@ private: | |||
DISTRHO_SAFE_ASSERT_RETURN(attrlist != nullptr,); | |||
v3_cpp_obj(attrlist)->set_int(attrlist, "__dpf_msg_target__", 2); | |||
v3_cpp_obj(attrlist)->set_int(attrlist, "key:length", std::strlen(key)); | |||
v3_cpp_obj(attrlist)->set_int(attrlist, "value:length", std::strlen(value)); | |||
v3_cpp_obj(attrlist)->set_string(attrlist, "key", ScopedUTF16String(key)); | |||
v3_cpp_obj(attrlist)->set_string(attrlist, "value", ScopedUTF16String(value)); | |||
v3_cpp_obj(fConnection)->notify(fConnection, message); | |||
@@ -3085,6 +3108,10 @@ struct dpf_component : v3_component_cpp { | |||
hostContextFromFactory(h), | |||
hostContextFromInitialize(nullptr) | |||
{ | |||
// make sure context is valid through this component lifetime | |||
if (hostContextFromFactory != nullptr) | |||
v3_cpp_obj_ref(hostContextFromFactory); | |||
// v3_funknown, everything custom | |||
query_interface = query_interface_component; | |||
ref = ref_component; | |||
@@ -3541,6 +3568,10 @@ struct dpf_factory : v3_plugin_factory_cpp { | |||
~dpf_factory() | |||
{ | |||
// unref old context if there is one | |||
if (hostContext != nullptr) | |||
v3_cpp_obj_unref(hostContext); | |||
if (gComponentGarbage.size() == 0) | |||
return; | |||
@@ -3696,7 +3727,18 @@ struct dpf_factory : v3_plugin_factory_cpp { | |||
{ | |||
d_stdout("dpf_factory::set_host_context => %p %p", self, context); | |||
dpf_factory* const factory = *static_cast<dpf_factory**>(self); | |||
// unref old context if there is one | |||
if (factory->hostContext != nullptr) | |||
v3_cpp_obj_unref(factory->hostContext); | |||
// store new context | |||
factory->hostContext = context; | |||
// make sure the object keeps being valid for a while | |||
if (context != nullptr) | |||
v3_cpp_obj_ref(context); | |||
return V3_OK; | |||
} | |||
@@ -299,27 +299,46 @@ public: | |||
#if DISTRHO_PLUGIN_WANT_STATE | |||
if (std::strcmp(msgid, "state-set") == 0) | |||
{ | |||
int16_t* key16; | |||
int16_t* value16; | |||
uint32_t keySize, valueSize; | |||
int64_t keyLength = -1; | |||
int64_t valueLength = -1; | |||
v3_result res; | |||
res = v3_cpp_obj(attrs)->get_binary(attrs, "key", (const void**)&key16, &keySize); | |||
res = v3_cpp_obj(attrs)->get_int(attrs, "key:length", &keyLength); | |||
DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); | |||
DISTRHO_SAFE_ASSERT_INT_RETURN(keyLength >= 0, keyLength, V3_INTERNAL_ERR); | |||
res = v3_cpp_obj(attrs)->get_binary(attrs, "value", (const void**)&value16, &valueSize); | |||
res = v3_cpp_obj(attrs)->get_int(attrs, "value:length", &valueLength); | |||
DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); | |||
DISTRHO_SAFE_ASSERT_INT_RETURN(valueLength >= 0, valueLength, V3_INTERNAL_ERR); | |||
int16_t* const key16 = (int16_t*)std::malloc(sizeof(int16_t)*(keyLength + 1)); | |||
DISTRHO_SAFE_ASSERT_RETURN(key16 != nullptr, V3_NOMEM); | |||
int16_t* const value16 = (int16_t*)std::malloc(sizeof(int16_t)*(valueLength + 1)); | |||
DISTRHO_SAFE_ASSERT_RETURN(value16 != nullptr, V3_NOMEM); | |||
res = v3_cpp_obj(attrs)->get_string(attrs, "key", key16, sizeof(int16_t)*keyLength); | |||
DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); | |||
res = v3_cpp_obj(attrs)->get_string(attrs, "value", value16, sizeof(int16_t)*valueLength); | |||
DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); | |||
// do cheap inline conversion | |||
char* const key = (char*)key16; | |||
char* const value = (char*)value16; | |||
for (uint32_t i=0; i<keySize/sizeof(int16_t); ++i) | |||
for (int64_t i=0; i<keyLength; ++i) | |||
key[i] = key16[i]; | |||
for (uint32_t i=0; i<valueSize/sizeof(int16_t); ++i) | |||
for (int64_t i=0; i<valueLength; ++i) | |||
value[i] = value16[i]; | |||
key[keyLength] = '\0'; | |||
value[valueLength] = '\0'; | |||
fUI.stateChanged(key, value); | |||
std::free(key16); | |||
std::free(value16); | |||
return V3_OK; | |||
} | |||
#endif | |||
@@ -549,6 +568,8 @@ private: | |||
DISTRHO_SAFE_ASSERT_RETURN(attrlist != nullptr,); | |||
v3_cpp_obj(attrlist)->set_int(attrlist, "__dpf_msg_target__", 1); | |||
v3_cpp_obj(attrlist)->set_int(attrlist, "key:length", std::strlen(key)); | |||
v3_cpp_obj(attrlist)->set_int(attrlist, "value:length", std::strlen(value)); | |||
v3_cpp_obj(attrlist)->set_string(attrlist, "key", ScopedUTF16String(key)); | |||
v3_cpp_obj(attrlist)->set_string(attrlist, "value", ScopedUTF16String(value)); | |||
v3_cpp_obj(fConnection)->notify(fConnection, message); | |||
@@ -103,12 +103,13 @@ protected: | |||
void onDisplay() override | |||
{ | |||
const GraphicsContext& context(getGraphicsContext()); | |||
const double scaleFactor = getWindow().getScaleFactor(); | |||
const int iconSize = bgIcon.getWidth(); | |||
Color(0.027f, 0.027f, 0.027f).setFor(context); | |||
Rectangle<uint>(0, 0, getSize()).draw(context); | |||
bgIcon.setY(curPage*iconSize + curPage*3); | |||
bgIcon.setY(curPage * iconSize + curPage * 3 * scaleFactor); | |||
Color(0.129f, 0.129f, 0.129f).setFor(context); | |||
bgIcon.draw(context); | |||
@@ -118,7 +119,8 @@ protected: | |||
if (curHover != curPage && curHover != -1) | |||
{ | |||
Rectangle<int> rHover(1, curHover*iconSize + curHover*3, iconSize-2, iconSize-2); | |||
Rectangle<int> rHover(1 * scaleFactor, curHover * iconSize + curHover * 3 * scaleFactor, | |||
iconSize - 2 * scaleFactor, iconSize - 2 * scaleFactor); | |||
Color(0.071f, 0.071f, 0.071f).setFor(context); | |||
rHover.draw(context); | |||
@@ -146,13 +148,13 @@ protected: | |||
// draw some text | |||
nvg.beginFrame(this); | |||
nvg.fontSize(23.0f); | |||
nvg.fontSize(23.0f * scaleFactor); | |||
nvg.textAlign(NanoVG::ALIGN_LEFT|NanoVG::ALIGN_TOP); | |||
//nvg.textLineHeight(20.0f); | |||
nvg.fillColor(220,220,220,220); | |||
nvg.textBox(10, 420, iconSize, "Haha,", nullptr); | |||
nvg.textBox(15, 440, iconSize, "Look!", nullptr); | |||
nvg.textBox(10 * scaleFactor, 420 * scaleFactor, iconSize, "Haha,", nullptr); | |||
nvg.textBox(15 * scaleFactor, 440 * scaleFactor, iconSize, "Look!", nullptr); | |||
nvg.endFrame(); | |||
#endif | |||
@@ -226,9 +228,10 @@ protected: | |||
{ | |||
const uint width = ev.size.getWidth(); | |||
const uint height = ev.size.getHeight(); | |||
const double scaleFactor = getWindow().getScaleFactor(); | |||
bgIcon.setWidth(width-4); | |||
bgIcon.setHeight(width-4); | |||
bgIcon.setWidth(width - 4 * scaleFactor); | |||
bgIcon.setHeight(width - 4 * scaleFactor); | |||
lineSep.setStartPos(width, 0); | |||
lineSep.setEndPos(width, height); | |||
@@ -420,30 +423,31 @@ public: | |||
curWidget(nullptr) | |||
{ | |||
const ScopedGraphicsContext sgc(*this); | |||
const double scaleFactor = getScaleFactor(); | |||
wColor = new ExampleColorSubWidget(this); | |||
wColor->hide(); | |||
wColor->setAbsoluteX(kSidebarWidth); | |||
wColor->setAbsoluteX(kSidebarWidth * scaleFactor); | |||
wImages = new ExampleImagesSubWidget(this); | |||
wImages->hide(); | |||
wImages->setAbsoluteX(kSidebarWidth); | |||
wImages->setAbsoluteX(kSidebarWidth * scaleFactor); | |||
wRects = new ExampleRectanglesSubWidget(this); | |||
wRects->hide(); | |||
wRects->setAbsoluteX(kSidebarWidth); | |||
wRects->setAbsoluteX(kSidebarWidth * scaleFactor); | |||
wShapes = new ExampleShapesSubWidget(this); | |||
wShapes->hide(); | |||
wShapes->setAbsoluteX(kSidebarWidth); | |||
wShapes->setAbsoluteX(kSidebarWidth * scaleFactor); | |||
#ifdef DGL_OPENGL | |||
wText = new ExampleTextSubWidget(this), | |||
wText->hide(); | |||
wText->setAbsoluteX(kSidebarWidth); | |||
wText->setAbsoluteX(kSidebarWidth * scaleFactor); | |||
#endif | |||
wLeft = new LeftSideWidget(this, this), | |||
wLeft->setAbsolutePos(2, 2); | |||
wLeft->setAbsolutePos(2 * scaleFactor, 2 * scaleFactor); | |||
resizer = new ResizeHandle(this); | |||
@@ -493,10 +497,12 @@ protected: | |||
{ | |||
StandaloneWindow::onReshape(width, height); | |||
if (width < kSidebarWidth) | |||
const double scaleFactor = getScaleFactor(); | |||
if (width < kSidebarWidth * scaleFactor) | |||
return; | |||
Size<uint> size(width-kSidebarWidth, height); | |||
const Size<uint> size(width - kSidebarWidth * scaleFactor, height); | |||
wColor->setSize(size); | |||
wImages->setSize(size); | |||
wRects->setSize(size); | |||
@@ -504,7 +510,7 @@ protected: | |||
#ifdef DGL_OPENGL | |||
wText->setSize(size); | |||
#endif | |||
wLeft->setSize(kSidebarWidth-4, height-4); | |||
wLeft->setSize((kSidebarWidth - 4) * scaleFactor, (height - 4) * scaleFactor); | |||
} | |||
private: | |||
@@ -528,8 +534,9 @@ template <class ExampleWidgetStandaloneWindow> | |||
void createAndShowExampleWidgetStandaloneWindow(Application& app) | |||
{ | |||
ExampleWidgetStandaloneWindow swin(app); | |||
const double scaleFactor = swin.getScaleFactor(); | |||
swin.setResizable(true); | |||
swin.setSize(600, 500); | |||
swin.setSize(600 * scaleFactor, 500 * scaleFactor); | |||
swin.setTitle(ExampleWidgetStandaloneWindow::kExampleWidgetName); | |||
swin.show(); | |||
app.exec(); | |||
@@ -38,21 +38,26 @@ public: | |||
loadSharedResources(); | |||
#endif | |||
setResizable(true); | |||
setSize(500, 200); | |||
setGeometryConstraints(500, 200, true); | |||
setTitle("FileBrowserDialog"); | |||
const double scaleFactor = getScaleFactor(); | |||
setGeometryConstraints(500 * scaleFactor, 200 * scaleFactor, true); | |||
setSize(500 * scaleFactor, 200 * scaleFactor); | |||
done(); | |||
} | |||
protected: | |||
void onNanoDisplay() override | |||
{ | |||
const double scaleFactor = getScaleFactor(); | |||
// Selected file | |||
beginPath(); | |||
fontSize(14); | |||
fontSize(14 * scaleFactor); | |||
textAlign(ALIGN_LEFT | ALIGN_MIDDLE); | |||
fillColor(255, 255, 255, 255); | |||
text(20, getHeight()/2, selectedFile, NULL); | |||
text(20 * scaleFactor, getHeight()/2, selectedFile, NULL); | |||
closePath(); | |||
// Button background | |||
@@ -66,7 +71,7 @@ protected: | |||
// Button label | |||
beginPath(); | |||
fontSize(14); | |||
fontSize(14 * scaleFactor); | |||
Rectangle<float> buttonTextBounds; | |||
textBounds(0, 0, "Press me", NULL, buttonTextBounds); | |||
textAlign(ALIGN_CENTER | ALIGN_MIDDLE); | |||
@@ -138,8 +143,12 @@ protected: | |||
{ | |||
const uint width = ev.size.getWidth(); | |||
const uint height = ev.size.getHeight(); | |||
const double scaleFactor = getScaleFactor(); | |||
buttonBounds = Rectangle<uint>(width - 120, height/2 - 20, 100, 40); | |||
buttonBounds = Rectangle<uint>(width - 120 * scaleFactor, | |||
height/2 - 20 * scaleFactor, | |||
100 * scaleFactor, | |||
40 * scaleFactor); | |||
} | |||
void onFocus(const bool focus, CrossingMode) override | |||
@@ -85,7 +85,7 @@ public: | |||
setResizable(true); | |||
setSize(500, 500); | |||
// setGeometryConstraints(500, 500, false); | |||
setGeometryConstraints(500, 500, false, true); | |||
setTitle("NanoImage"); | |||
done(); | |||
@@ -42,23 +42,28 @@ public: | |||
// StandaloneWindow | |||
explicit ExampleTextWidget(Application& app); | |||
// helper | |||
double getScaleFactor(); | |||
protected: | |||
void onNanoDisplay() override | |||
{ | |||
const int width = BaseWidget::getWidth(); | |||
const int height = BaseWidget::getHeight(); | |||
const double scaleFactor = getScaleFactor(); | |||
NanoVG::fontSize(40.0f); | |||
NanoVG::fontSize(40.0f * scaleFactor); | |||
NanoVG::textAlign(NanoVG::Align(NanoVG::ALIGN_CENTER|NanoVG::ALIGN_MIDDLE)); | |||
NanoVG::textLineHeight(20.0f); | |||
NanoVG::textLineHeight(20.0f * scaleFactor); | |||
NanoVG::beginPath(); | |||
NanoVG::fillColor(220,220,220,255); | |||
NanoVG::roundedRect(10, height/4+10, width-20, height/2-20, 3); | |||
NanoVG::roundedRect(10 * scaleFactor, height/4 + 10 * scaleFactor, | |||
width - 20 * scaleFactor, height/2 - 20 * scaleFactor, 3 * scaleFactor); | |||
NanoVG::fill(); | |||
NanoVG::fillColor(0,150,0,220); | |||
NanoVG::textBox(10, height/2, width-20, "Hello World!", nullptr); | |||
NanoVG::textBox(10 * scaleFactor, height/2, width - 20 * scaleFactor, "Hello World!", nullptr); | |||
} | |||
}; | |||
@@ -71,6 +76,12 @@ ExampleTextWidget<NanoSubWidget>::ExampleTextWidget(Widget* const parent) | |||
setSize(500, 300); | |||
} | |||
template<> inline | |||
double ExampleTextWidget<NanoSubWidget>::getScaleFactor() | |||
{ | |||
return getWindow().getScaleFactor(); | |||
} | |||
// TopLevelWidget | |||
template<> inline | |||
ExampleTextWidget<NanoTopLevelWidget>::ExampleTextWidget(Window& windowToMapTo) | |||
@@ -80,6 +91,12 @@ ExampleTextWidget<NanoTopLevelWidget>::ExampleTextWidget(Window& windowToMapTo) | |||
setSize(500, 300); | |||
} | |||
template<> inline | |||
double ExampleTextWidget<NanoTopLevelWidget>::getScaleFactor() | |||
{ | |||
return NanoTopLevelWidget::getScaleFactor(); | |||
} | |||
// StandaloneWindow | |||
template<> inline | |||
ExampleTextWidget<NanoStandaloneWindow>::ExampleTextWidget(Application& app) | |||
@@ -90,6 +107,12 @@ ExampleTextWidget<NanoStandaloneWindow>::ExampleTextWidget(Application& app) | |||
done(); | |||
} | |||
template<> inline | |||
double ExampleTextWidget<NanoStandaloneWindow>::getScaleFactor() | |||
{ | |||
return Window::getScaleFactor(); | |||
} | |||
template class ExampleTextWidget<NanoSubWidget>; | |||
template class ExampleTextWidget<NanoTopLevelWidget>; | |||
template class ExampleTextWidget<NanoStandaloneWindow>; | |||
@@ -29,6 +29,7 @@ | |||
#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 | |||
#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 | |||
#define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:ReverbPlugin" | |||
#define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:ReverbPlugin" | |||
#define DISTRHO_PLUGIN_VST3_CATEGORIES "Fx|Reverb" | |||
#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED |
@@ -29,6 +29,7 @@ include ../../dpf/Makefile.plugins.mk | |||
TARGETS += jack | |||
TARGETS += ladspa | |||
TARGETS += lv2_sep | |||
TARGETS += vst2 | |||
TARGETS += vst3 | |||
@@ -38,12 +39,6 @@ TARGETS += dssi | |||
endif | |||
endif | |||
ifeq ($(HAVE_DGL),true) | |||
TARGETS += lv2_sep | |||
else | |||
TARGETS += lv2_dsp | |||
endif | |||
all: $(TARGETS) | |||
# -------------------------------------------------------------- |
@@ -14,7 +14,6 @@ | |||
* For a full copy of the license see the LICENSE file. | |||
*/ | |||
#include "libprojectM/projectM-opengl.h" | |||
#include "libprojectM/projectM.hpp" | |||
#include "DistrhoPluginProM.hpp" | |||
@@ -69,6 +68,12 @@ static String getCurrentExecutableDataDir() | |||
} | |||
else | |||
# endif | |||
if (datadir.endsWith("/x86_64-linux")) | |||
{ | |||
datadir.truncate(datadir.rfind('/')); | |||
datadir += "/Resources"; | |||
} | |||
else | |||
#endif | |||
{ | |||
datadir += "/resources"; | |||
@@ -166,9 +171,6 @@ void DistrhoUIProM::onDisplay() | |||
return; | |||
fPM->renderFrame(); | |||
// turn off shaders at the end of the drawing cycle, so other things can draw properly | |||
glUseProgram(0); | |||
} | |||
static projectMKeycode dgl2pmkey(const DGL_NAMESPACE::Key key) noexcept | |||
@@ -251,33 +253,6 @@ bool DistrhoUIProM::onKeyboard(const KeyboardEvent& ev) | |||
if (fPM == nullptr) | |||
return false; | |||
#if 0 | |||
if (ev.press && (ev.key == '1' || ev.key == '+' || ev.key == '-')) | |||
{ | |||
if (ev.key == '1') | |||
{ | |||
if (getWidth() != 512 || getHeight() != 512) | |||
setSize(512, 512); | |||
} | |||
else if (ev.key == '+') | |||
{ | |||
/**/ if (getWidth() < 1100 && getHeight() < 1100) | |||
setSize(getWidth()+100, getHeight()+100); | |||
else if (getWidth() != 1100 || getHeight() != 1100) | |||
setSize(1100, 1100); | |||
} | |||
else if (ev.key == '-') | |||
{ | |||
/**/ if (getWidth() >= 200 && getHeight() >= 200) | |||
setSize(getWidth()-100, getHeight()-100); | |||
else if (getWidth() != 100 || getHeight() != 100) | |||
setSize(100, 100); | |||
} | |||
return true; | |||
} | |||
#endif | |||
// special handling for text | |||
if (fPM->isTextInputActive(true) && !ev.press) | |||
{ | |||
@@ -357,20 +332,6 @@ bool DistrhoUIProM::onKeyboard(const KeyboardEvent& ev) | |||
return true; | |||
} | |||
bool DistrhoUIProM::onSpecial(const SpecialEvent& ev) | |||
{ | |||
if (fPM == nullptr) | |||
return false; | |||
const projectMKeycode pmKey = dgl2pmkey(ev.key); | |||
if (pmKey == PROJECTM_K_NONE) | |||
return false; | |||
fPM->default_key_handler(ev.press ? PROJECTM_KEYUP : PROJECTM_KEYDOWN, pmKey); | |||
return true; | |||
} | |||
// ----------------------------------------------------------------------- | |||
UI* createUI() | |||
@@ -49,7 +49,6 @@ protected: | |||
void onDisplay() override; | |||
bool onKeyboard(const KeyboardEvent&) override; | |||
bool onSpecial(const SpecialEvent&) override; | |||
private: | |||
ScopedPointer<projectM> fPM; | |||
@@ -195,9 +195,7 @@ LINK_FLAGS += -lpthread | |||
# -------------------------------------------------------------- | |||
# Enable all possible plugin types | |||
TARGETS += lv2 | |||
TARGETS += vst2 | |||
TARGETS += vst3 | |||
TARGETS = lv2 vst2 vst3 | |||
all: $(TARGETS) | |||
@@ -56,6 +56,11 @@ protected: | |||
const GraphicsContext& context(getGraphicsContext()); | |||
const double lineWidth = 1.0 * getScaleFactor(); | |||
#ifdef DGL_OPENGL | |||
glUseProgram(0); | |||
glMatrixMode(GL_MODELVIEW); | |||
#endif | |||
// draw white lines, 1px wide | |||
Color(1.0f, 1.0f, 1.0f).setFor(context); | |||
l1.draw(context, lineWidth); | |||
@@ -30,6 +30,7 @@ | |||
#define DISTRHO_PLUGIN_NUM_OUTPUTS 1 | |||
#define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 1 | |||
#define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:AnalyserPlugin" | |||
#define DISTRHO_PLUGIN_VST3_CATEGORIES "Fx|Analyzer" | |||
#define DISTRHO_UI_USER_RESIZABLE 1 | |||
enum Parameters { | |||
@@ -3,7 +3,7 @@ | |||
* Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies | |||
* Copyright (C) 2000 Christian Zander <phoenix@minion.de> | |||
* Copyright (C) 2015 Nedko Arnaudov | |||
* Copyright (C) 2016-2019 Filipe Coelho <falktx@falktx.com> | |||
* Copyright (C) 2016-2021 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU General Public License as | |||
@@ -27,9 +27,14 @@ START_NAMESPACE_DISTRHO | |||
DistrhoUIGLBars::DistrhoUIGLBars() | |||
: UI(512, 512), | |||
fInitialized(false) | |||
fInitialized(false), | |||
fResizeHandle(this) | |||
{ | |||
setGeometryConstraints(256, 256, true); | |||
// no need to show resize handle if window is user-resizable | |||
if (isResizable()) | |||
fResizeHandle.hide(); | |||
} | |||
DistrhoUIGLBars::~DistrhoUIGLBars() | |||
@@ -100,36 +105,6 @@ void DistrhoUIGLBars::onDisplay() | |||
fState.Render(); | |||
} | |||
bool DistrhoUIGLBars::onKeyboard(const KeyboardEvent& ev) | |||
{ | |||
if (ev.press && (ev.key == '1' || ev.key == '+' || ev.key == '-')) | |||
{ | |||
if (ev.key == '1') | |||
{ | |||
if (getWidth() != 512 || getHeight() != 512) | |||
setSize(512, 512); | |||
} | |||
else if (ev.key == '+') | |||
{ | |||
/**/ if (getWidth() < 1100 && getHeight() < 1100) | |||
setSize(std::min(getWidth()+100, 1100U), std::min(getHeight()+100, 1100U)); | |||
else if (getWidth() != 1100 || getHeight() != 1100) | |||
setSize(1100, 1100); | |||
} | |||
else if (ev.key == '-') | |||
{ | |||
/**/ if (getWidth() > 100 && getHeight() > 100) | |||
setSize(std::max(getWidth()-100, 100U), std::max(getHeight()-100, 100U)); | |||
else if (getWidth() != 100 || getHeight() != 100) | |||
setSize(100, 100); | |||
} | |||
return true; | |||
} | |||
return true; | |||
} | |||
// ----------------------------------------------------------------------- | |||
UI* createUI() | |||
@@ -3,7 +3,7 @@ | |||
* Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies | |||
* Copyright (C) 2000 Christian Zander <phoenix@minion.de> | |||
* Copyright (C) 2015 Nedko Arnaudov | |||
* Copyright (C) 2016-2019 Filipe Coelho <falktx@falktx.com> | |||
* Copyright (C) 2016-2021 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU General Public License as | |||
@@ -24,6 +24,7 @@ | |||
#include "DistrhoUI.hpp" | |||
#include "glBars.hpp" | |||
#include "ResizeHandle.hpp" | |||
START_NAMESPACE_DISTRHO | |||
@@ -50,11 +51,11 @@ protected: | |||
// Widget Callbacks | |||
void onDisplay() override; | |||
bool onKeyboard(const KeyboardEvent&) override; | |||
private: | |||
bool fInitialized; | |||
glBarsState fState; | |||
ResizeHandle fResizeHandle; | |||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DistrhoUIGLBars) | |||
}; | |||
@@ -31,10 +31,7 @@ LINK_FLAGS += -lpthread | |||
# -------------------------------------------------------------- | |||
# Enable all possible plugin types | |||
TARGETS += jack | |||
TARGETS += lv2 | |||
TARGETS += vst2 | |||
TARGETS += vst3 | |||
TARGETS = jack lv2 vst2 vst3 | |||
all: $(TARGETS) | |||