Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/project-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ jobs:
publish-nightly:
name: "Publish Nightly"
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/heads/')
if: github.ref_type == 'branch'
needs: [ build-linux, build-windows, build-macos ]
steps:
- name: "Upload to nightly"
Expand Down
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.16)
project(Dexed VERSION 0.9.9)
project(Dexed VERSION 1.0.1)

#Compile commands, useful for some IDEs like VS-Code
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
Expand Down Expand Up @@ -72,4 +72,4 @@ target_compile_options(${PROJECT_NAME} PUBLIC
endif()

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/assets/installers")
include(installer)
include(installer)
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ Dexed Forks

Changelog
---------
#### Version 1.0.1
* Let DAW scale the UI and then let the user zoom it further if needed
* Fixed scaling issue with CLAP format
* Plugin parameters dialogs are now part of the main plugin window (no more separate windows)

#### Version 0.9.9
* Partial portamento implementation. Thanks @jpcima
* More accurate LFO implementation. Thanks @mtarenskeen
Expand Down
2 changes: 1 addition & 1 deletion Source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ endif()
message(STATUS "Building Dexed in formats: ${DEXED_JUCE_FORMATS}")

juce_add_plugin("${BaseTargetName}"
VERSION "1.0.0" # FORCING THIS SINCE OLDER VERSION WILL NOT BE ABLE TO SYNC PLUGIN DATA. THIS WILL GET UPDATED ONCE 1.0 is released.
VERSION "1.0.1"
ICON_BIG "../assets/ui/dexedIcon.png"
ICON_SMALL "../assets/ui/dexedIcon.png"
COMPANY_NAME "Digital Suburban"
Expand Down
10 changes: 6 additions & 4 deletions Source/GlobalEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ class AboutBox : public DialogWindow {
std::unique_ptr<juce::HyperlinkButton> dexed; // changed to std::unique_ptr from juce::ScopedPointer
std::unique_ptr<juce::HyperlinkButton> surge; // changed to std::unique_ptr from juce::ScopedPointer

AboutBox(Component *parent) : DialogWindow("About", Colour(0xFF000000), true),
AboutBox() : DialogWindow("About", Colour(0xFF000000), true),
dexed(std::make_unique<juce::HyperlinkButton>("https://asb2m10.github.io/dexed/", URL("https://asb2m10.github.io/dexed/"))),
surge(std::make_unique<juce::HyperlinkButton>("https://surge-synthesizer.github.io/", URL("https://surge-synthesizer.github.io/")))
{
setUsingNativeTitleBar(false);
setAlwaysOnTop(true);
logo_png = ImageCache::getFromMemory(BinaryData::dexedlogo_png, BinaryData::dexedlogo_pngSize);
setSize(logo_png.getWidth() + 8, 500);
centreAroundComponent(parent, getWidth(), getHeight());
//centreAroundComponent(parent, getWidth(), getHeight());

dexed->setColour(HyperlinkButton::ColourIds::textColourId, Colour(0xFF4ea097));
dexed->setJustificationType(Justification::left);
Expand Down Expand Up @@ -701,8 +701,10 @@ void GlobalEditor::buttonClicked (juce::Button* buttonThatWasClicked)
else if (buttonThatWasClicked == aboutButton.get())
{
//[UserButtonCode_aboutButton] -- add your button handler code here..
AboutBox about(this->getParentComponent());
about.runModalLoop();
aboutBox = std::make_unique<AboutBox>();
getParentComponent()->addAndMakeVisible(aboutBox.get());
aboutBox->centreWithSize(aboutBox->getWidth(), aboutBox->getHeight());
aboutBox->enterModalState(true,{});
//[/UserButtonCode_aboutButton]
}

Expand Down
2 changes: 2 additions & 0 deletions Source/GlobalEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ class GlobalEditor : public Component,

Image background;
Image imageLight;

std::unique_ptr<Component> aboutBox;
//[/UserVariables]

//==============================================================================
Expand Down
16 changes: 14 additions & 2 deletions Source/OperatorEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

#include "OperatorEditor.h"

#include "PluginEditor.h"


//[MiscUserDefs] You can add your own user definitions and misc code here...
#ifndef M_LN10
Expand Down Expand Up @@ -521,8 +523,6 @@ void OperatorEditor::buttonClicked (juce::Button* buttonThatWasClicked)
//[/UserbuttonClicked_Post]
}



//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
void OperatorEditor::bind(DexedAudioProcessor *parent, int op) {
parent->opCtrl[op].egLevel[0]->bind(s_egl1.get());
Expand Down Expand Up @@ -607,6 +607,11 @@ void OperatorEditor::mouseDown(const MouseEvent &event) {
popup.addSeparator();
popup.addItem(4, "Send current program to DX7");

if ( processor->getZoomFactor() > 1.0f ) {
popup.addSeparator();
popup.addItem(5, "Reset plugin UI scaling factor");
}

switch(popup.show()) {
case 1:
processor->copyToClipboard(internalOp);
Expand All @@ -623,6 +628,13 @@ void OperatorEditor::mouseDown(const MouseEvent &event) {
case 4:
processor->sendCurrentSysexProgram();
break;

case 5:
auto *editor = dynamic_cast<DexedAudioProcessorEditor*>(getParentComponent()->getParentComponent());
if ( editor != nullptr ) {
editor->resetZoomFactor();
}
break;
}

}
Expand Down
125 changes: 78 additions & 47 deletions Source/PluginEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "Dexed.h"
#include "math.h"
#include <fstream>
#include <memory>

#include "msfa/fm_op_kernel.h"

Expand All @@ -36,47 +37,52 @@ DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* owner
midiKeyboard (ownerFilter->keyboardState, MidiKeyboardComponent::horizontalKeyboard),
cartManager(this)
{
setSize(WINDOW_SIZE_X, (ownerFilter->showKeyboard ? WINDOW_SIZE_Y : WINDOW_SIZE_Y - 94));
setExplicitFocusOrder(1);
processor = ownerFilter;

// We have to set size at startup because the keyboard doesnt show up before being added
resetSize();
setExplicitFocusOrder(1);


frameComponent.setBounds(0,0, WINDOW_SIZE_X, (processor->showKeyboard ? WINDOW_SIZE_Y : WINDOW_SIZE_Y - 94));
addAndMakeVisible(&frameComponent);
lookAndFeel->setDefaultLookAndFeel(lookAndFeel);
background = lookAndFeel->background;

// OPERATORS
addAndMakeVisible(&(operators[0]));
frameComponent.addAndMakeVisible(&(operators[0]));
operators[0].setBounds(2, 1, 287, 218);
operators[0].bind(processor, 0);

addAndMakeVisible(&(operators[1]));
frameComponent.addAndMakeVisible(&(operators[1]));
operators[1].setBounds(290, 1, 287, 218);
operators[1].bind(processor, 1);

addAndMakeVisible(&(operators[2]));
frameComponent.addAndMakeVisible(&(operators[2]));
operators[2].setBounds(578, 1, 287, 218);
operators[2].bind(processor, 2);

addAndMakeVisible(&(operators[3]));
frameComponent.addAndMakeVisible(&(operators[3]));
operators[3].setBounds(2, 219, 287, 218);
operators[3].bind(processor, 3);

addAndMakeVisible(&(operators[4]));
frameComponent.addAndMakeVisible(&(operators[4]));
operators[4].setBounds(290, 219, 287, 218);
operators[4].bind(processor, 4);

addAndMakeVisible(&(operators[5]));
frameComponent.addAndMakeVisible(&(operators[5]));
operators[5].setBounds(578, 219, 287, 218);
operators[5].bind(processor, 5);

// add the midi keyboard component..
addAndMakeVisible (&midiKeyboard);
frameComponent.addAndMakeVisible (&midiKeyboard);

// The DX7 is a badass on the bass, keep it that way
midiKeyboard.setLowestVisibleKey(24);
midiKeyboard.setBounds(4, 581, getWidth() - 8, 90);
midiKeyboard.setTitle("Keyboard keys");

addAndMakeVisible(&global);
frameComponent.addAndMakeVisible(&global);
global.setBounds(2,436,864,144);
global.bind(this);

Expand All @@ -85,10 +91,13 @@ DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* owner
rebuildProgramCombobox();
global.programs->addListener(this);

addChildComponent(&cartManagerCover);
frameComponent.addChildComponent(&cartManagerCover);
cartManagerCover.addChildComponent(&cartManager);
cartManager.setVisible(true);

AffineTransform scale = AffineTransform::scale(processor->getZoomFactor());
frameComponent.setTransform(scale);
resetSize();
addKeyListener(this);
updateUI();
startTimer(100);
Expand Down Expand Up @@ -177,13 +186,23 @@ void DexedAudioProcessorEditor::tuningShow() {
auto dialogwindow = options.launchAsync();
}

// I don't know why closeButtonPressed is not implemented in the standard DialogWindow version.
class DexedDialogWindow : public juce::DialogWindow {
public:
DexedDialogWindow(const juce::String& title, juce::Colour backgroundColour)
: juce::DialogWindow(title, backgroundColour, true, false) {

}
void closeButtonPressed() override {
setVisible(false);
}
};

void DexedAudioProcessorEditor::parmShow() {
int tp = processor->getEngineType();
DialogWindow::LaunchOptions options;

auto param = new ParamDialog();
param->setColour(AlertWindow::backgroundColourId, Colour(0xFF323E44));
param->setDialogValues(processor->controllers, processor->sysexComm, tp, processor->showKeyboard, processor->getDpiScaleFactor());
param->setDialogValues(processor->controllers, processor->sysexComm, tp, processor->showKeyboard, processor->getZoomFactor());
param->setIsStandardTuning(processor->synthTuningState->is_standard_tuning() );
param->setTuningCallback([this](ParamDialog *p, ParamDialog::TuningAction which) {
switch(which)
Expand All @@ -205,33 +224,30 @@ void DexedAudioProcessorEditor::parmShow() {
p->setIsStandardTuning(this->processor->synthTuningState->is_standard_tuning() );
} );

options.content.setOwned(param);
options.dialogTitle = "dexed Parameters";
options.dialogBackgroundColour = Colour(0xFF323E44);
options.escapeKeyTriggersCloseButton = true;
options.useNativeTitleBar = false;
options.resizable = false;

auto generalCallback = [this](ParamDialog *param)
{
int tpo;
float scale = this->processor->getDpiScaleFactor();
float scale = this->processor->getZoomFactor();
bool ret = param->getDialogValues(this->processor->controllers, this->processor->sysexComm, &tpo, &this->processor->showKeyboard, &scale);
this->processor->setZoomFactor(scale);
this->processor->setEngineType(tpo);
this->processor->setDpiScaleFactor(scale);
this->processor->savePreference();

param->setSize(710, 355);
this->setSize(WINDOW_SIZE_X, (processor->showKeyboard ? WINDOW_SIZE_Y : WINDOW_SIZE_Y - 94));
this->midiKeyboard.repaint();
AffineTransform scaleAffine = AffineTransform::scale(this->processor->getZoomFactor());
frameComponent.setTransform(scaleAffine);
resetSize();

if ( ret == false ) {
AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Midi Interface", "Error opening midi ports");
}
};
param->setGeneralCallback(generalCallback);

auto dialogWindow = options.launchAsync();
dexedParameterDialog = std::make_unique<DexedDialogWindow>("dexed Parameters", Colour(0xFF323E44));
dexedParameterDialog->setContentOwned(param, true);
frameComponent.addAndMakeVisible(dexedParameterDialog.get());
dexedParameterDialog->centreAroundComponent(&frameComponent, param->getWidth(), param->getHeight() + dexedParameterDialog->getTitleBarHeight());
dexedParameterDialog->enterModalState(true,{});
}

void DexedAudioProcessorEditor::initProgram() {
Expand Down Expand Up @@ -438,27 +454,37 @@ void DexedAudioProcessorEditor::discoverMidiCC(Ctrl *ctrl) {
}

float DexedAudioProcessorEditor::getLargestScaleFactor() {
constexpr float TESTING_SCALE_FACTOR[] = { 4.0f, 3.0f, 2.0f, 1.5f, 1.0f };

for (float factor: TESTING_SCALE_FACTOR) {
const juce::Rectangle<int> rect(WINDOW_SIZE_X * factor, WINDOW_SIZE_Y * factor);

// validate if there is really a display that can show the complete plugin size
for (auto& display : Desktop::getInstance().getDisplays().displays) {
float ratio = display.scale;
int height = ratio * display.userArea.getHeight();
int width = ratio * display.userArea.getWidth();

TRACE("Testing size %d x %d < Dexed Window %d x %d", height, width, rect.getWidth(), rect.getHeight() );
if ( height > rect.getHeight() && width > rect.getWidth() ) {
TRACE("Found factor %f for display %s with size %d x %d", factor, display.userArea.toString().toRawUTF8(), height, width );
return factor;
}
}
}
// constexpr float TESTING_SCALE_FACTOR[] = { 4.0f, 3.0f, 2.0f, 1.5f, 1.0f };
//
// for (float factor: TESTING_SCALE_FACTOR) {
// const juce::Rectangle<int> rect(WINDOW_SIZE_X * factor, WINDOW_SIZE_Y * factor);
//
// // validate if there is really a display that can show the complete plugin size
// for (auto& display : Desktop::getInstance().getDisplays().displays) {
// int height = display.userArea.getHeight();
// int width = display.userArea.getWidth();
//
// TRACE("Testing size %d x %d < Dexed Window %d x %d", height, width, rect.getWidth(), rect.getHeight() );
// if ( height > rect.getHeight() && width > rect.getWidth() ) {
// TRACE("Found factor %f for display %s with size %d x %d", factor, display.userArea.toString().toRawUTF8(), height, width );
// return factor;
// }
// }
// }
//
// TRACE("No suitable display found, returning default scale factor 1.0");

// For now, always return 4.0f as the maximum scale factor.
return 4.0f;
}

TRACE("No suitable display found, returning default scale factor 1.0");
return 1.0f;
void DexedAudioProcessorEditor::resetZoomFactor() {
TRACE("Resetting zoom factor to 1.0");
processor->setZoomFactor(1.0);
processor->savePreference();
AffineTransform scale = AffineTransform::scale(processor->getZoomFactor());
frameComponent.setTransform(scale);
resetSize();
}

bool DexedAudioProcessorEditor::isInterestedInFileDrag (const StringArray &files)
Expand Down Expand Up @@ -583,4 +609,9 @@ bool DexedAudioProcessorEditor::keyPressed(const KeyPress& key, Component* origi
}

return false;
}

void DexedAudioProcessorEditor::resetSize() {
float factor = processor->getZoomFactor();
setSize(WINDOW_SIZE_X * factor, (processor->showKeyboard ? WINDOW_SIZE_Y : WINDOW_SIZE_Y - 94) * factor);
}
6 changes: 6 additions & 0 deletions Source/PluginEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,14 @@ class DexedAudioProcessorEditor : public AudioProcessorEditor, public ComboBox:
Component cartManagerCover;

SharedResourcePointer<DXLookNFeel> lookAndFeel;
std::unique_ptr<juce::DialogWindow> dexedParameterDialog;
#ifdef DEXED_EVENT_DEBUG
FocusLogger focusLogger;
#endif

void resetSize();

Component frameComponent;
public:
DexedAudioProcessor *processor;
GlobalEditor global;
Expand All @@ -66,6 +71,7 @@ class DexedAudioProcessorEditor : public AudioProcessorEditor, public ComboBox:
void discoverMidiCC(Ctrl *ctrl);

static float getLargestScaleFactor();
void resetZoomFactor();

virtual bool isInterestedInFileDrag (const StringArray &files) override;
virtual void filesDropped (const StringArray &files, int x, int y ) override;
Expand Down
Loading
Loading