Browse Source

Continue C++ ideas

tags/v2.1-rc1
falkTX 4 years ago
parent
commit
1b88881875
15 changed files with 1292 additions and 321 deletions
  1. +1
    -1
      .gitignore
  2. BIN
      resources/16x16/dialog-information.svgz
  3. +65
    -46
      source/frontend/Makefile
  4. +5
    -5
      source/frontend/carla_app.cpp
  5. +3
    -3
      source/frontend/carla_app.hpp
  6. +17
    -14
      source/frontend/carla_host.cpp
  7. +16
    -14
      source/frontend/carla_host.hpp
  8. +668
    -13
      source/frontend/carla_settings.cpp
  9. +114
    -3
      source/frontend/carla_settings.hpp
  10. +317
    -0
      source/frontend/carla_shared.cpp
  11. +86
    -222
      source/frontend/carla_shared.hpp
  12. +0
    -0
      source/frontend/widgets/canvaspreviewframe.h
  13. +0
    -0
      source/frontend/widgets/digitalpeakmeter.h
  14. +0
    -0
      source/frontend/widgets/draggablegraphicsview.h
  15. +0
    -0
      source/frontend/widgets/racklistwidget.h

+ 1
- 1
.gitignore View File

@@ -51,7 +51,7 @@ qrc_resources.cpp
*.pyc

# Qt files
*_rc.hpp
*_rc.cpp
*_rc.py
ui_*.hpp
ui_*.py


BIN
resources/16x16/dialog-information.svgz View File


+ 65
- 46
source/frontend/Makefile View File

@@ -28,51 +28,16 @@ BUILD_CXX_FLAGS += $(FLUIDSYNTH_FLAGS)
BUILD_CXX_FLAGS += $(QT5_FLAGS)

# ---------------------------------------------------------------------------------------------------------------------
# UI code
# mocs?

UIs = \
ui_carla_about.hpp \
ui_carla_about.py \
ui_carla_about_juce.hpp \
ui_carla_about_juce.py \
ui_carla_add_jack.hpp \
ui_carla_add_jack.py \
ui_carla_database.hpp \
ui_carla_database.py \
ui_carla_edit.hpp \
ui_carla_edit.py \
ui_carla_host.hpp \
ui_carla_host.py \
ui_carla_osc_connect.py \
ui_carla_osc_connect.hpp \
ui_carla_parameter.hpp \
ui_carla_parameter.py \
ui_carla_plugin_calf.hpp \
ui_carla_plugin_calf.py \
ui_carla_plugin_classic.hpp \
ui_carla_plugin_classic.py \
ui_carla_plugin_compact.hpp \
ui_carla_plugin_compact.py \
ui_carla_plugin_default.hpp \
ui_carla_plugin_default.py \
ui_carla_plugin_presets.hpp \
ui_carla_plugin_presets.py \
ui_carla_refresh.hpp \
ui_carla_refresh.py \
ui_carla_settings.hpp \
ui_carla_settings.py \
ui_carla_settings_driver.hpp \
ui_carla_settings_driver.py \
ui_inputdialog_value.hpp \
ui_inputdialog_value.py \
ui_midipattern.hpp \
ui_midipattern.py
MOCs = \
moc_carla_settings.cpp

# ---------------------------------------------------------------------------------------------------------------------
# Resources

RES = \
resources_rc.hpp \
resources_rc.cpp \
resources_rc.py \
$(BINDIR)/resources/patchcanvas \
$(BINDIR)/resources/widgets \
@@ -109,6 +74,47 @@ RES = \
$(BINDIR)/resources/ui_inputdialog_value.py \
$(BINDIR)/resources/ui_midipattern.py

# ---------------------------------------------------------------------------------------------------------------------
# UI code

UIs = \
ui_carla_about.hpp \
ui_carla_about.py \
ui_carla_about_juce.hpp \
ui_carla_about_juce.py \
ui_carla_add_jack.hpp \
ui_carla_add_jack.py \
ui_carla_database.hpp \
ui_carla_database.py \
ui_carla_edit.hpp \
ui_carla_edit.py \
ui_carla_host.hpp \
ui_carla_host.py \
ui_carla_osc_connect.py \
ui_carla_osc_connect.hpp \
ui_carla_parameter.hpp \
ui_carla_parameter.py \
ui_carla_plugin_calf.hpp \
ui_carla_plugin_calf.py \
ui_carla_plugin_classic.hpp \
ui_carla_plugin_classic.py \
ui_carla_plugin_compact.hpp \
ui_carla_plugin_compact.py \
ui_carla_plugin_default.hpp \
ui_carla_plugin_default.py \
ui_carla_plugin_presets.hpp \
ui_carla_plugin_presets.py \
ui_carla_refresh.hpp \
ui_carla_refresh.py \
ui_carla_settings.hpp \
ui_carla_settings.py \
ui_carla_settings_driver.hpp \
ui_carla_settings_driver.py \
ui_inputdialog_value.hpp \
ui_inputdialog_value.py \
ui_midipattern.hpp \
ui_midipattern.py

# ---------------------------------------------------------------------------------------------------------------------

LIBS = $(MODULEDIR)/carla_engine.a
@@ -185,12 +191,25 @@ endif

# ---------------------------------------------------------------------------------------------------------------------

OBJS = \
$(OBJDIR)/carla_app.cpp.o \
$(OBJDIR)/carla_host.cpp.o \
$(OBJDIR)/carla_settings.cpp.o \
$(OBJDIR)/carla_shared.cpp.o \
$(OBJDIR)/patchcanvas/theme.cpp.o \
$(OBJDIR)/moc_carla_host.cpp.o \
$(OBJDIR)/moc_carla_settings.cpp.o \
$(OBJDIR)/resources_rc.cpp.o \
$(OBJDIR)/CarlaStandalone.cpp.o

# ---------------------------------------------------------------------------------------------------------------------

TARGETS = $(BINDIR)/carla
TARGETS = carla

# ---------------------------------------------------------------------------------------------------------------------

all: $(UIs) $(RES)
all: $(MOCs) $(RES) $(UIs)

# ---------------------------------------------------------------------------------------------------------------------

@@ -200,10 +219,10 @@ carla: $(OBJS)
@echo "Linking carla"
$(CXX) $(OBJS) $(LIBS_START) $(LIBS) $(LIBS_END) $(LINK_FLAGS) -o $@

carla_settings: $(OBJDIR)/carla_settings.cpp.o $(OBJDIR)/carla_app.cpp.o $(OBJDIR)/carla_shared.cpp.o
carla_settings: $(OBJS)
-@mkdir -p $(BINDIR)
@echo "Linking carla"
$(CXX) $^ $(LIBS_START) $(LIBS) $(LIBS_END) $(LINK_FLAGS) -o $@
$(CXX) $(OBJS) $(LIBS_START) $(LIBS) $(LIBS_END) $(LINK_FLAGS) -o $@

# ---------------------------------------------------------------------------------------------------------------------

@@ -216,10 +235,10 @@ ui_%.hpp: $(RESDIR)/ui/%.ui
ui_%.py: $(RESDIR)/ui/%.ui
$(PYUIC) $< -o $@

resources_rc.hpp: $(RESDIR)/resources.qrc $(RESDIR)/*/*.png $(RESDIR)/*/*.svg
resources_rc.cpp: $(RESDIR)/resources.qrc $(RESDIR)/*/*.png $(RESDIR)/*/*.svg $(RESDIR)/*/*.svgz
$(RCC_QT5) $< -o $@

resources_rc.py: $(RESDIR)/resources.qrc $(RESDIR)/*/*.png $(RESDIR)/*/*.svg
resources_rc.py: $(RESDIR)/resources.qrc $(RESDIR)/*/*.png $(RESDIR)/*/*.svg $(RESDIR)/*/*.svgz
$(PYRCC) $< -o $@

$(BINDIR)/resources/%: %
@@ -227,8 +246,8 @@ $(BINDIR)/resources/%: %

# ---------------------------------------------------------------------------------------------------------------------

$(OBJDIR)/%.cpp.o: %.cpp $(UIs) $(RES)
-@mkdir -p $(OBJDIR)
$(OBJDIR)/%.cpp.o: %.cpp $(UIs)
-@mkdir -p $(OBJDIR)/patchcanvas
@echo "Compiling $<"
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@



+ 5
- 5
source/frontend/carla_app.cpp View File

@@ -1,6 +1,6 @@
/*
* Carla plugin host
* Copyright (C) 2011-2019 Filipe Coelho <falktx@falktx.com>
* Carla application
* Copyright (C) 2013-2019 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
@@ -15,6 +15,8 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#include "carla_app.hpp"

//---------------------------------------------------------------------------------------------------------------------
// Imports (Global)

@@ -29,7 +31,6 @@
//---------------------------------------------------------------------------------------------------------------------
// Imports (Custom)

#include "carla_app.hpp"
#include "carla_shared.hpp"

//---------------------------------------------------------------------------------------------------------------------
@@ -45,7 +46,7 @@ CarlaApplication::CarlaApplication(const QString appName, int& argc, char* argv[
if (os.path.exists(CWD))
QApplication.addLibraryPath(CWD)

# Needed for local wine build
// Needed for local wine build
if WINDOWS and CWD.endswith(("frontend", "resources")) and os.getenv("CXFREEZE") is None:
if kIs64bit:
path = "H:\\builds\\msys2-x86_64\\mingw64\\share\\qt5\\plugins"
@@ -159,7 +160,6 @@ CarlaApplication::CarlaApplication(const QString appName, int& argc, char* argv[
palBlack.setColor(QPalette::Inactive, QPalette::LinkVisited, QColor(230, 100, 230));
guiApp->setPalette(palBlack);
}

else if (proThemeColor == "blue")
{
QPalette palBlue;


+ 3
- 3
source/frontend/carla_app.hpp View File

@@ -1,6 +1,6 @@
/*
* Carla plugin host
* Copyright (C) 2011-2019 Filipe Coelho <falktx@falktx.com>
* Carla application
* Copyright (C) 2013-2019 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
@@ -29,7 +29,7 @@ class QApplication;
//---------------------------------------------------------------------------------------------------------------------
// Imports (Custom)

#include "../utils/CarlaJuceUtils.hpp"
#include "CarlaJuceUtils.hpp"

//---------------------------------------------------------------------------------------------------------------------



+ 17
- 14
source/frontend/carla_host.cpp View File

@@ -15,6 +15,8 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#include "carla_host.hpp"

//---------------------------------------------------------------------------------------------------------------------
// Imports (Global)

@@ -31,19 +33,20 @@
//---------------------------------------------------------------------------------------------------------------------
// Imports (Custom)

#include "host.hpp"
#include "ui_carla_host.hpp"

#include "../../backend/CarlaHost.h"
#include "../../backend/CarlaUtils.h"
#include "../../utils/CarlaBackendUtils.hpp"
#include "../../utils/CarlaMathUtils.hpp"
#include "../../utils/CarlaString.hpp"
#include "CarlaHost.h"
#include "CarlaUtils.h"

#include "CarlaBackendUtils.hpp"
#include "CarlaMathUtils.hpp"
#include "CarlaString.hpp"

//---------------------------------------------------------------------------------------------------------------------

Host::Host()
: isControl(false),
CarlaHost::CarlaHost()
: QObject(),
isControl(false),
isPlugin(false),
isRemote(false),
nsmOK(false),
@@ -160,9 +163,9 @@ struct CarlaHostWindow::PrivateData {
};

//---------------------------------------------------------------------------------------------------------------------
// Host Window
// Carla Host Window

CarlaHostWindow::CarlaHostWindow(Host& h, const bool withCanvas, QWidget* const parent)
CarlaHostWindow::CarlaHostWindow(CarlaHost& h, const bool withCanvas, QWidget* const parent)
: QMainWindow(parent),
host(h),
self(new PrivateData(this, withCanvas))
@@ -1541,7 +1544,7 @@ void _engineCallback(void* const ptr, EngineCallbackOpcode action, uint pluginId
ptr, action, EngineCallbackOpcode2Str(action), pluginId, value1, value2, value3, valuef, valueStr);
*/

Host* const host = (Host*)(ptr);
CarlaHost* const host = (CarlaHost*)(ptr);
CARLA_SAFE_ASSERT_RETURN(host != nullptr,);

switch (action)
@@ -1612,7 +1615,7 @@ static const char* _fileCallback(void*, const FileCallbackOpcode action, const b
//---------------------------------------------------------------------------------------------------------------------
// Init host

Host& initHost(const QString /*initName*/, const bool isControl, const bool isPlugin, const bool failError)
CarlaHost& initHost(const QString /*initName*/, const bool isControl, const bool isPlugin, const bool failError)
{
CarlaString pathBinaries, pathResources;
// = getPaths(libPrefix)
@@ -1636,7 +1639,7 @@ Host& initHost(const QString /*initName*/, const bool isControl, const bool isPl
// host = CarlaHostQtNull()
}

static Host host;
static CarlaHost host;
host.isControl = isControl;
host.isPlugin = isPlugin;

@@ -1666,7 +1669,7 @@ Host& initHost(const QString /*initName*/, const bool isControl, const bool isPl
//---------------------------------------------------------------------------------------------------------------------
// Load host settings

void loadHostSettings(Host& /*host*/)
void loadHostSettings(CarlaHost& /*host*/)
{
}



+ 16
- 14
source/frontend/carla_host.hpp View File

@@ -26,17 +26,20 @@
//---------------------------------------------------------------------------------------------------------------------
// Imports (Custom)

#include "shared.hpp"
#include "carla_shared.hpp"

#include "../../backend/CarlaBackend.h"
#include "../../utils/CarlaJuceUtils.hpp"
#include "CarlaBackend.h"
#include "CarlaJuceUtils.hpp"

CARLA_BACKEND_USE_NAMESPACE;

//---------------------------------------------------------------------------------------------------------------------

struct Host : public QObject
class CarlaHost : public QObject
{
Q_OBJECT

public:
// info about this host object
bool isControl;
bool isPlugin;
@@ -46,10 +49,10 @@ struct Host : public QObject
// settings
EngineProcessMode processMode;
EngineTransportMode transportMode;
QString transportExtra;
QCarlaString transportExtra;
EngineProcessMode nextProcessMode;
bool processModeForced;
QString audioDriverForced;
QCarlaString audioDriverForced;

// settings
bool experimental;
@@ -70,12 +73,11 @@ struct Host : public QObject
QString pathBinaries;
QString pathResources;

Host();
CarlaHost();

// Qt Stuff
Q_SIGNAL void EngineStartedCallback(uint, int, int, int, float, QString);
Q_SIGNAL void EngineStoppedCallback();
Q_OBJECT
};

//---------------------------------------------------------------------------------------------------------------------
@@ -98,11 +100,11 @@ class CarlaHostWindow : public QMainWindow
public:
//-----------------------------------------------------------------------------------------------------------------

CarlaHostWindow(Host& host, const bool withCanvas, QWidget* const parent = nullptr);
CarlaHostWindow(CarlaHost& host, const bool withCanvas, QWidget* const parent = nullptr);
~CarlaHostWindow() override;

private:
Host& host;
CarlaHost& host;
struct PrivateData;
PrivateData* const self;

@@ -258,7 +260,7 @@ private:
void getAndRefreshRuntimeInfo();
void idleFast();
void idleSlow();
void timerEvent(QTimerEvent* event);
void timerEvent(QTimerEvent* event) override;

//-----------------------------------------------------------------------------------------------------------------
// color/style change event
@@ -274,18 +276,18 @@ private:

//-----------------------------------------------------------------------------------------------------------------

// CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaHostWindow)
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaHostWindow)
};

//---------------------------------------------------------------------------------------------------------------------
// Init host

Host& initHost(const QString initName, const bool isControl, const bool isPlugin, const bool failError);
CarlaHost& initHost(const QString initName, const bool isControl, const bool isPlugin, const bool failError);

//---------------------------------------------------------------------------------------------------------------------
// Load host settings

void loadHostSettings(Host& host);
void loadHostSettings(CarlaHost& host);

//---------------------------------------------------------------------------------------------------------------------



+ 668
- 13
source/frontend/carla_settings.cpp View File

@@ -20,32 +20,689 @@
//---------------------------------------------------------------------------------------------------------------------
// Imports (Global)

#include <QtWidgets/QDialog>
#include <QtCore/QStringList>

//---------------------------------------------------------------------------------------------------------------------
// Imports (Custom)

#include "carla_app.hpp"
#include "carla_shared.hpp"
#include "resources_rc.hpp"
#include "ui_carla_settings.hpp"
#include "ui_carla_settings_driver.hpp"

#include "carla_host.hpp"
#include "patchcanvas/theme.hpp"

#include "CarlaHost.h"
#include "CarlaUtils.hpp"

// --------------------------------------------------------------------------------------------------------------------

static const char* const AUTOMATIC_OPTION = "(Auto)";

static const QList<uint> BUFFER_SIZE_LIST = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
static const QList<double> SAMPLE_RATE_LIST = { 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000 };

CARLA_BACKEND_USE_NAMESPACE;

// --------------------------------------------------------------------------------------------------------------------
// Driver Settings

class DriverSettingsW : public QDialog
struct DriverSettingsW::PrivateData {
Ui::DriverSettingsW ui;

uint fDriverIndex;
QString fDriverName;
QStringList fDeviceNames;

QList<uint> fBufferSizes;
QList<double> fSampleRates;

PrivateData(DriverSettingsW* const self, const uint driverIndex = 0, const QString driverName = "")
: ui(),
fDriverIndex(driverIndex),
fDriverName(driverName),
fDeviceNames(),
fBufferSizes(BUFFER_SIZE_LIST),
fSampleRates(SAMPLE_RATE_LIST)
{
ui.setupUi(self);

const char* const* const deviceNames = carla_get_engine_driver_device_names(driverIndex);
CARLA_SAFE_ASSERT_RETURN(deviceNames != nullptr,);

fillQStringListFromStringArray(fDeviceNames, deviceNames);
}

void loadSettings(DriverSettingsW* const self)
{
const QSafeSettings settings("falkTX", "Carla2");

const QString prefix(QString("%1%2").arg(CARLA_KEY_ENGINE_DRIVER_PREFIX).arg(fDriverName));

const QCarlaString audioDevice = settings.valueString(QString("%1/Device").arg(prefix), "");
const uint audioBufferSize = settings.valueUInt(QString("%1/BufferSize").arg(prefix), CARLA_DEFAULT_AUDIO_BUFFER_SIZE);
const uint audioSampleRate = settings.valueUInt(QString("%1/SampleRate").arg(prefix), CARLA_DEFAULT_AUDIO_SAMPLE_RATE);
const bool audioTripleBuffer = settings.valueBool(QString("%1/TripleBuffer").arg(prefix), CARLA_DEFAULT_AUDIO_TRIPLE_BUFFER);

if (audioDevice.isNotEmpty() && fDeviceNames.contains(audioDevice))
ui.cb_device->setCurrentIndex(fDeviceNames.indexOf(audioDevice));
else
ui.cb_device->setCurrentIndex(-1);

// fill combo-boxes first
self->slot_updateDeviceInfo();

if (audioBufferSize != 0 && fBufferSizes.contains(audioBufferSize))
ui.cb_buffersize->setCurrentIndex(fBufferSizes.indexOf(audioBufferSize));
else if (fBufferSizes == BUFFER_SIZE_LIST)
ui.cb_buffersize->setCurrentIndex(BUFFER_SIZE_LIST.indexOf(CARLA_DEFAULT_AUDIO_BUFFER_SIZE));
else
ui.cb_buffersize->setCurrentIndex(fBufferSizes.size()/2);

if (audioSampleRate != 0 && fSampleRates.contains(audioSampleRate))
ui.cb_samplerate->setCurrentIndex(fSampleRates.indexOf(audioSampleRate));
else if (fSampleRates == SAMPLE_RATE_LIST)
ui.cb_samplerate->setCurrentIndex(SAMPLE_RATE_LIST.indexOf(CARLA_DEFAULT_AUDIO_SAMPLE_RATE));
else
ui.cb_samplerate->setCurrentIndex(fSampleRates.size()/2);

ui.cb_triple_buffer->setChecked(audioTripleBuffer && ui.cb_triple_buffer->isEnabled());
}
};

DriverSettingsW::DriverSettingsW(QWidget* const parent)
: QDialog(parent),
self(new PrivateData(this))
{
// ----------------------------------------------------------------------------------------------------------------
// Set-up GUI

for (const auto& name : self->fDeviceNames)
self->ui.cb_device->addItem(name);

setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);

// ----------------------------------------------------------------------------------------------------------------
// Load settings

self->loadSettings(this);

// ----------------------------------------------------------------------------------------------------------------
// Set-up connections

connect(this, SIGNAL(accepted()), SLOT(slot_saveSettings()));
connect(self->ui.b_panel, SIGNAL(clicked()), SLOT(slot_showDevicePanel()));
connect(self->ui.cb_device, SIGNAL(currentIndexChanged(int)), SLOT(slot_updateDeviceInfo()));
}

DriverSettingsW::~DriverSettingsW()
{
delete self;
}

// --------------------------------------------------------------------------------------------------------------------

void DriverSettingsW::slot_saveSettings()
{
QSafeSettings settings("falkTX", "Carla2");

QString bufferSize = self->ui.cb_buffersize->currentText();
QString sampleRate = self->ui.cb_samplerate->currentText();

if (bufferSize == AUTOMATIC_OPTION)
bufferSize = "0";
if (sampleRate == AUTOMATIC_OPTION)
sampleRate = "0";

const QString prefix(QString("%1%2").arg(CARLA_KEY_ENGINE_DRIVER_PREFIX).arg(self->fDriverName));

settings.setValue(QString("%1/Device").arg(prefix), self->ui.cb_device->currentText());
settings.setValue(QString("%1/BufferSize").arg(prefix), bufferSize);
settings.setValue(QString("%1/SampleRate").arg(prefix), sampleRate);
settings.setValue(QString("%1/TripleBuffer").arg(prefix), self->ui.cb_triple_buffer->isChecked());
}

void DriverSettingsW::slot_showDevicePanel()
{
carla_show_engine_driver_device_control_panel(self->fDriverIndex, self->ui.cb_device->currentText().toUtf8());
}

void DriverSettingsW::slot_updateDeviceInfo()
{
const QString deviceName = self->ui.cb_device->currentText();

const QString oldBufferSize = self->ui.cb_buffersize->currentText();
const QString oldSampleRate = self->ui.cb_samplerate->currentText();

self->ui.cb_buffersize->clear();
self->ui.cb_samplerate->clear();

self->fBufferSizes.clear();
self->fSampleRates.clear();

const EngineDriverDeviceInfo* const driverDeviceInfo = carla_get_engine_driver_device_info(self->fDriverIndex, deviceName.toUtf8());
CARLA_SAFE_ASSERT_RETURN(driverDeviceInfo != nullptr,);

const uint driverDeviceHints = driverDeviceInfo->hints;

fillQUIntListFromUIntArray(self->fBufferSizes, driverDeviceInfo->bufferSizes);
fillQDoubleListFromDoubleArray(self->fSampleRates, driverDeviceInfo->sampleRates);

if (driverDeviceHints & ENGINE_DRIVER_DEVICE_CAN_TRIPLE_BUFFER)
self->ui.cb_triple_buffer->setEnabled(true);
else
self->ui.cb_triple_buffer->setEnabled(false);

if (driverDeviceHints & ENGINE_DRIVER_DEVICE_HAS_CONTROL_PANEL)
self->ui.b_panel->setEnabled(true);
else
self->ui.b_panel->setEnabled(false);

if (self->fBufferSizes.size() > 0)
{
for (const uint bsize : self->fBufferSizes)
{
const QString sbsize(QString("%1").arg(bsize));
self->ui.cb_buffersize->addItem(sbsize);

if (oldBufferSize == sbsize)
self->ui.cb_buffersize->setCurrentIndex(self->ui.cb_buffersize->count()-1);
}
}
else
{
self->ui.cb_buffersize->addItem(AUTOMATIC_OPTION);
self->ui.cb_buffersize->setCurrentIndex(0);
}

if (self->fSampleRates.size() > 0)
{
for (const double srate : self->fSampleRates)
{
const QString ssrate(QString("%1").arg(srate));
self->ui.cb_samplerate->addItem(ssrate);

if (oldSampleRate == ssrate)
self->ui.cb_samplerate->setCurrentIndex(self->ui.cb_samplerate->count()-1);
}
}
else
{
self->ui.cb_samplerate->addItem(AUTOMATIC_OPTION);
self->ui.cb_samplerate->setCurrentIndex(0);
}
}

// --------------------------------------------------------------------------------------------------------------------
// Runtime Driver Settings

struct RuntimeDriverSettingsW::PrivateData {
Ui::DriverSettingsW ui;

PrivateData(RuntimeDriverSettingsW* const self)
: ui()
{
ui.setupUi(self);
}
};

RuntimeDriverSettingsW::RuntimeDriverSettingsW(QWidget* const parent)
: QDialog(parent),
self(new PrivateData(this))
{
const CarlaRuntimeEngineDriverDeviceInfo* const driverDeviceInfo = carla_get_runtime_engine_driver_device_info();

QList<uint> bufferSizes;
fillQUIntListFromUIntArray(bufferSizes, driverDeviceInfo->bufferSizes);

QList<double> sampleRates;
fillQDoubleListFromDoubleArray(sampleRates, driverDeviceInfo->sampleRates);

// ----------------------------------------------------------------------------------------------------------------
// Set-up GUI

self->ui.cb_device->clear();
self->ui.cb_buffersize->clear();
self->ui.cb_samplerate->clear();
self->ui.cb_triple_buffer->hide();
self->ui.ico_restart->hide();
self->ui.label_restart->hide();

self->ui.layout_triple_buffer->takeAt(2);
self->ui.layout_triple_buffer->takeAt(1);
self->ui.layout_triple_buffer->takeAt(0);
self->ui.verticalLayout->removeItem(self->ui.layout_triple_buffer);

self->ui.layout_restart->takeAt(3);
self->ui.layout_restart->takeAt(2);
self->ui.layout_restart->takeAt(1);
self->ui.layout_restart->takeAt(0);
self->ui.verticalLayout->removeItem(self->ui.layout_restart);

adjustSize();
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);

// ----------------------------------------------------------------------------------------------------------------
// Load runtime settings

if (carla_is_engine_running())
{
self->ui.cb_device->addItem(driverDeviceInfo->name);
self->ui.cb_device->setCurrentIndex(0);
self->ui.cb_device->setEnabled(false);
}
else
{
self->ui.cb_device->addItem(driverDeviceInfo->name);
self->ui.cb_device->setCurrentIndex(0);
}

if (bufferSizes.size() > 0)
{
for (const uint bsize : bufferSizes)
{
const QString sbsize(QString("%1").arg(bsize));
self->ui.cb_buffersize->addItem(sbsize);

if (driverDeviceInfo->bufferSize == bsize)
self->ui.cb_buffersize->setCurrentIndex(self->ui.cb_buffersize->count()-1);
}
}
else
{
self->ui.cb_buffersize->addItem(AUTOMATIC_OPTION);
self->ui.cb_buffersize->setCurrentIndex(0);
}

if ((driverDeviceInfo->hints & ENGINE_DRIVER_DEVICE_VARIABLE_BUFFER_SIZE) == 0x0)
self->ui.cb_buffersize->setEnabled(false);

if (sampleRates.size() > 0)
{
for (const double srate : sampleRates)
{
const QString ssrate(QString("%1").arg(srate));
self->ui.cb_samplerate->addItem(ssrate);

if (driverDeviceInfo->sampleRate == srate)
self->ui.cb_samplerate->setCurrentIndex(self->ui.cb_samplerate->count()-1);
}
}
else
{
self->ui.cb_samplerate->addItem(AUTOMATIC_OPTION);
self->ui.cb_samplerate->setCurrentIndex(0);
}

if ((driverDeviceInfo->hints & ENGINE_DRIVER_DEVICE_VARIABLE_SAMPLE_RATE) == 0x0)
self->ui.cb_samplerate->setEnabled(false);

if ((driverDeviceInfo->hints & ENGINE_DRIVER_DEVICE_HAS_CONTROL_PANEL) == 0x0)
self->ui.b_panel->setEnabled(false);

// ----------------------------------------------------------------------------------------------------------------
// Set-up connections

connect(self->ui.b_panel, SIGNAL(clicked()), SLOT(slot_showDevicePanel()));
}

RuntimeDriverSettingsW::~RuntimeDriverSettingsW()
{
delete self;
}

void RuntimeDriverSettingsW::getValues(QString& retAudioDevice, uint& retBufferSize, double& retSampleRate)
{
const QString bufferSize = self->ui.cb_buffersize->currentText();
const QString sampleRate = self->ui.cb_samplerate->currentText();

if (bufferSize == AUTOMATIC_OPTION)
retBufferSize = 0;
else
retBufferSize = bufferSize.toUInt();

if (sampleRate == AUTOMATIC_OPTION)
retSampleRate = 0.0;
else
retSampleRate = sampleRate.toDouble();

retAudioDevice = self->ui.cb_buffersize->currentText();
}

void RuntimeDriverSettingsW::slot_showDevicePanel()
{
// static const char* const AUTOMATIC_OPTION = "(Auto)";
carla_show_engine_device_control_panel();
}

// --------------------------------------------------------------------------------------------------------------------
// Settings Dialog

enum TabIndexes {
TAB_INDEX_MAIN,
TAB_INDEX_CANVAS,
TAB_INDEX_ENGINE,
TAB_INDEX_OSC,
TAB_INDEX_FILEPATHS,
TAB_INDEX_PLUGINPATHS,
TAB_INDEX_WINE,
TAB_INDEX_EXPERIMENTAL,
TAB_INDEX_NONE,
};

enum FilePathIndexes {
FILEPATH_INDEX_AUDIO,
FILEPATH_INDEX_MIDI
};

enum PluginPathIndexes {
PLUGINPATH_INDEX_LADSPA,
PLUGINPATH_INDEX_DSSI,
PLUGINPATH_INDEX_LV2,
PLUGINPATH_INDEX_VST2,
PLUGINPATH_INDEX_VST3,
PLUGINPATH_INDEX_SF2,
PLUGINPATH_INDEX_SFZ
};

/*
Single and Multiple client mode is only for JACK,
but we still want to match QComboBox index to backend defines,
so add +2 pos padding if driverName != "JACK".
*/
#define PROCESS_MODE_NON_JACK_PADDING 2

struct CarlaSettingsW::PrivateData {
Ui::CarlaSettingsW ui;

PrivateData(CarlaSettingsW* const self)
: ui()
{
ui.setupUi(self);
}

void loadSettings()
{
}

public:
DriverSettingsW(QWidget* const parent = nullptr)
: QDialog(parent)
void resetExperimentalSettings()
{
}
};

CarlaSettingsW::CarlaSettingsW(QWidget* const parent, const CarlaHost& host, const bool hasCanvas, const bool hasCanvasGL)
: QDialog(parent),
self(new PrivateData(this))
{
// ----------------------------------------------------------------------------------------------------------------
// Set-up GUI

self->ui.lw_page->setFixedWidth(48 + 6*3 + fontMetricsHorizontalAdvance(self->ui.lw_page->fontMetrics(), " Experimental "));

for (uint i=0; i < carla_get_engine_driver_count(); ++i)
self->ui.cb_engine_audio_driver->addItem(carla_get_engine_driver_name(i));

for (uint i=0; i < Theme::THEME_MAX; ++i)
self->ui.cb_canvas_theme->addItem(getThemeName((Theme::List)i));

#ifdef CARLA_OS_MAC
self->ui.group_main_theme->setEnabled(false);
self->ui.group_main_theme->setVisible(false);
#endif

#ifdef CARLA_OS_Win
if (true)
#else
if (host.isControl)
#endif
{
self->ui.ch_main_show_logs->setEnabled(false);
self->ui.ch_main_show_logs->setVisible(false);
}

if (host.isControl)
{
self->ui.lw_page->hideRow(TAB_INDEX_ENGINE);
self->ui.lw_page->hideRow(TAB_INDEX_FILEPATHS);
self->ui.lw_page->hideRow(TAB_INDEX_PLUGINPATHS);
self->ui.ch_exp_export_lv2->hide();
self->ui.group_experimental_engine->hide();
}
else if (! hasCanvas)
{
self->ui.lw_page->hideRow(TAB_INDEX_CANVAS);
}
else if (! hasCanvasGL)
{
self->ui.cb_canvas_use_opengl->setEnabled(false);
self->ui.cb_canvas_render_hq_aa->setEnabled(false);
}

if (host.isPlugin)
self->ui.cb_engine_audio_driver->setEnabled(false);

if (host.audioDriverForced.isNotEmpty())
{
self->ui.cb_engine_audio_driver->setEnabled(false);
self->ui.tb_engine_driver_config->setEnabled(false);
}

if (host.processModeForced)
{
self->ui.cb_engine_process_mode_jack->setEnabled(false);
self->ui.cb_engine_process_mode_other->setEnabled(false);

if (host.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
self->ui.ch_engine_force_stereo->setEnabled(false);
}

if (host.isControl || host.isPlugin)
{
self->ui.ch_main_confirm_exit->hide();
self->ui.ch_exp_load_lib_global->hide();
self->ui.lw_page->hideRow(TAB_INDEX_OSC);
self->ui.lw_page->hideRow(TAB_INDEX_WINE);
}

#ifndef CARLA_OS_LINUX
self->ui.ch_exp_wine_bridges->setVisible(false);
self->ui.ch_exp_jack_apps->setVisible(false);
self->ui.ch_exp_prevent_bad_behaviour->setVisible(false);
self->ui.lw_page->hideRow(TAB_INDEX_WINE);
#endif

#ifndef CARLA_OS_MAC
self->ui.label_engine_ui_bridges_mac_note->setVisible(false);
#endif

// FIXME, not implemented yet
self->ui.ch_engine_uis_always_on_top->hide();

setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);

// ----------------------------------------------------------------------------------------------------------------
// Load settings

self->loadSettings();

// ----------------------------------------------------------------------------------------------------------------
// Set-up connections

connect(this, SIGNAL(accepted()), SLOT(slot_saveSettings()));
connect(self->ui.buttonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked()), SLOT(slot_resetSettings()));

connect(self->ui.b_main_proj_folder_open, SIGNAL(clicked()), SLOT(slot_getAndSetProjectPath()));

connect(self->ui.cb_engine_audio_driver, SIGNAL(currentIndexChanged(int)), SLOT(slot_engineAudioDriverChanged()));
connect(self->ui.tb_engine_driver_config, SIGNAL(clicked()), SLOT(slot_showAudioDriverSettings()));

connect(self->ui.b_paths_add, SIGNAL(clicked()), SLOT(slot_addPluginPath()));
connect(self->ui.b_paths_remove, SIGNAL(clicked()), SLOT(slot_removePluginPath()));
connect(self->ui.b_paths_change, SIGNAL(clicked()), SLOT(slot_changePluginPath()));
connect(self->ui.cb_paths, SIGNAL(currentIndexChanged(int)), SLOT(slot_pluginPathTabChanged(int)));
connect(self->ui.lw_ladspa, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
connect(self->ui.lw_dssi, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
connect(self->ui.lw_lv2, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
connect(self->ui.lw_vst, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
connect(self->ui.lw_vst3, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
connect(self->ui.lw_sf2, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
connect(self->ui.lw_sfz, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));

connect(self->ui.b_filepaths_add, SIGNAL(clicked()), SLOT(slot_addFilePath()));
connect(self->ui.b_filepaths_remove, SIGNAL(clicked()), SLOT(slot_removeFilePath()));
connect(self->ui.b_filepaths_change, SIGNAL(clicked()), SLOT(slot_changeFilePath()));
connect(self->ui.cb_filepaths, SIGNAL(currentIndexChanged(int)), SLOT(slot_filePathTabChanged(int)));
connect(self->ui.lw_files_audio, SIGNAL(currentRowChanged(int)), SLOT(slot_filePathRowChanged(int)));
connect(self->ui.lw_files_midi, SIGNAL(currentRowChanged(int)), SLOT(slot_filePathRowChanged(int)));

connect(self->ui.ch_main_experimental, SIGNAL(toggled(bool)), SLOT(slot_enableExperimental(bool)));
connect(self->ui.ch_exp_wine_bridges, SIGNAL(toggled(bool)), SLOT(slot_enableWineBridges(bool)));
connect(self->ui.cb_exp_plugin_bridges, SIGNAL(toggled(bool)), SLOT(slot_pluginBridgesToggled(bool)));
connect(self->ui.cb_canvas_eyecandy, SIGNAL(toggled(bool)), SLOT(slot_canvasEyeCandyToggled(bool)));
connect(self->ui.cb_canvas_fancy_eyecandy, SIGNAL(toggled(bool)), SLOT(slot_canvasFancyEyeCandyToggled(bool)));
connect(self->ui.cb_canvas_use_opengl, SIGNAL(toggled(bool)), SLOT(slot_canvasOpenGLToggled(bool)));

// ----------------------------------------------------------------------------------------------------------------
// Post-connect setup

self->ui.lw_ladspa->setCurrentRow(0);
self->ui.lw_dssi->setCurrentRow(0);
self->ui.lw_lv2->setCurrentRow(0);
self->ui.lw_vst->setCurrentRow(0);
self->ui.lw_vst3->setCurrentRow(0);
self->ui.lw_sf2->setCurrentRow(0);
self->ui.lw_sfz->setCurrentRow(0);

self->ui.lw_files_audio->setCurrentRow(0);
self->ui.lw_files_midi->setCurrentRow(0);

self->ui.lw_page->setCurrentCell(0, 0);

/*
slot_filePathTabChanged(0);
slot_pluginPathTabChanged(0);
*/

adjustSize();
}

CarlaSettingsW::~CarlaSettingsW()
{
delete self;
}

// --------------------------------------------------------------------------------------------------------------------

void CarlaSettingsW::slot_saveSettings()
{
}

void CarlaSettingsW::slot_resetSettings()
{
}


// --------------------------------------------------------------------------------------------------------------------

void CarlaSettingsW::slot_enableExperimental(bool toggled)
{
}

void CarlaSettingsW::slot_enableWineBridges(bool toggled)
{
}

void CarlaSettingsW::slot_pluginBridgesToggled(bool toggled)
{
}

void CarlaSettingsW::slot_canvasEyeCandyToggled(bool toggled)
{
}

void CarlaSettingsW::slot_canvasFancyEyeCandyToggled(bool toggled)
{
}

void CarlaSettingsW::slot_canvasOpenGLToggled(bool toggled)
{
}


// --------------------------------------------------------------------------------------------------------------------

void CarlaSettingsW::slot_getAndSetProjectPath()
{
}


// --------------------------------------------------------------------------------------------------------------------

void CarlaSettingsW::slot_engineAudioDriverChanged()
{
}

void CarlaSettingsW::slot_showAudioDriverSettings()
{
}


// --------------------------------------------------------------------------------------------------------------------

void CarlaSettingsW::slot_addPluginPath()
{
}

void CarlaSettingsW::slot_removePluginPath()
{
}

void CarlaSettingsW::slot_changePluginPath()
{
}


// --------------------------------------------------------------------------------------------------------------------

void CarlaSettingsW::slot_pluginPathTabChanged(int index)
{
}

void CarlaSettingsW::slot_pluginPathRowChanged(int row)
{
}


// --------------------------------------------------------------------------------------------------------------------

void CarlaSettingsW::slot_addFilePath()
{
}

void CarlaSettingsW::slot_removeFilePath()
{
}

void CarlaSettingsW::slot_changeFilePath()
{
}


// --------------------------------------------------------------------------------------------------------------------

void CarlaSettingsW::slot_filePathTabChanged(int index)
{
}

void CarlaSettingsW::slot_filePathRowChanged(int row)
{
}


// --------------------------------------------------------------------------------------------------------------------
// Main

#include "carla_app.hpp"
#include "carla_shared.hpp"

int main(int argc, char* argv[])
{
// ----------------------------------------------------------------------------------------------------------------
@@ -61,15 +718,13 @@ int main(int argc, char* argv[])
// ----------------------------------------------------------------------------------------------------------------
// Init host backend

/*
Host& host = initHost(initName, false, false, true);
CarlaHost& host = initHost(initName, false, false, true);
loadHostSettings(host);
*/

// ----------------------------------------------------------------------------------------------------------------
// Create GUI

DriverSettingsW gui;
CarlaSettingsW gui(nullptr, host, true, true);

// ----------------------------------------------------------------------------------------------------------------
// Show GUI


+ 114
- 3
source/frontend/carla_settings.hpp View File

@@ -21,11 +21,122 @@
//---------------------------------------------------------------------------------------------------------------------
// Imports (Global)

// from PyQt5.QtCore import pyqtSlot, QByteArray, QDir
// from PyQt5.QtGui import QColor, QCursor, QPainter, QPainterPath
// from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QFrame, QInputDialog, QLineEdit, QMenu, QVBoxLayout, QWidget
#include <QtWidgets/QDialog>

//---------------------------------------------------------------------------------------------------------------------
// Imports (Custom)

#include "CarlaJuceUtils.hpp"

struct CarlaHost;

// --------------------------------------------------------------------------------------------------------------------
// Driver Settings

class DriverSettingsW : public QDialog
{
Q_OBJECT

public:
DriverSettingsW(QWidget* parent = nullptr);
~DriverSettingsW() override;

private:
struct PrivateData;
PrivateData* const self;

Q_SLOT void slot_saveSettings();
Q_SLOT void slot_showDevicePanel();
Q_SLOT void slot_updateDeviceInfo();

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DriverSettingsW)
};

// --------------------------------------------------------------------------------------------------------------------
// Runtime Driver Settings

class RuntimeDriverSettingsW : public QDialog
{
Q_OBJECT

public:
RuntimeDriverSettingsW(QWidget* parent = nullptr);
~RuntimeDriverSettingsW() override;

void getValues(QString& audioDevice, uint& bufferSize, double& sampleRate);

private:
struct PrivateData;
PrivateData* const self;

Q_SLOT void slot_showDevicePanel();

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RuntimeDriverSettingsW)
};

// --------------------------------------------------------------------------------------------------------------------
// Settings Dialog

class CarlaSettingsW : public QDialog
{
Q_OBJECT

public:
CarlaSettingsW(QWidget* parent, const CarlaHost& host, bool hasCanvas, bool hasCanvasGL);
~CarlaSettingsW() override;

private:
struct PrivateData;
PrivateData* const self;

// ----------------------------------------------------------------------------------------------------------------

Q_SLOT void slot_saveSettings();
Q_SLOT void slot_resetSettings();

// ----------------------------------------------------------------------------------------------------------------

Q_SLOT void slot_enableExperimental(bool toggled);
Q_SLOT void slot_enableWineBridges(bool toggled);
Q_SLOT void slot_pluginBridgesToggled(bool toggled);
Q_SLOT void slot_canvasEyeCandyToggled(bool toggled);
Q_SLOT void slot_canvasFancyEyeCandyToggled(bool toggled);
Q_SLOT void slot_canvasOpenGLToggled(bool toggled);

// ----------------------------------------------------------------------------------------------------------------

Q_SLOT void slot_getAndSetProjectPath();

// ----------------------------------------------------------------------------------------------------------------

Q_SLOT void slot_engineAudioDriverChanged();
Q_SLOT void slot_showAudioDriverSettings();

// ----------------------------------------------------------------------------------------------------------------

Q_SLOT void slot_addPluginPath();
Q_SLOT void slot_removePluginPath();
Q_SLOT void slot_changePluginPath();

// ----------------------------------------------------------------------------------------------------------------

Q_SLOT void slot_pluginPathTabChanged(int index);
Q_SLOT void slot_pluginPathRowChanged(int row);

// ----------------------------------------------------------------------------------------------------------------

Q_SLOT void slot_addFilePath();
Q_SLOT void slot_removeFilePath();
Q_SLOT void slot_changeFilePath();

// ----------------------------------------------------------------------------------------------------------------

Q_SLOT void slot_filePathTabChanged(int index);
Q_SLOT void slot_filePathRowChanged(int row);

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaSettingsW)
};

//---------------------------------------------------------------------------------------------------------------------

#endif // CARLA_SETTINGS_HPP_INCLUDED

+ 317
- 0
source/frontend/carla_shared.cpp View File

@@ -18,7 +18,324 @@
#include "carla_shared.hpp"

//---------------------------------------------------------------------------------------------------------------------
// Imports (Global)

#include <QtGui/QFontMetrics>

#include <QtWidgets/QFileDialog>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QLineEdit>

//---------------------------------------------------------------------------------------------------------------------
// Imports (Custom)

#include "CarlaMathUtils.hpp"

//---------------------------------------------------------------------------------------------------------------------
// Global Carla object

CarlaObject::CarlaObject() noexcept
: gui(nullptr),
nogui(false),
term(false) {}

CarlaObject gCarla;

//---------------------------------------------------------------------------------------------------------------------
// Get Icon from user theme, using our own as backup (Oxygen)

QIcon getIcon(const QString icon, const int size)
{
return QIcon::fromTheme(icon, QIcon(QString(":/%1x%1/%2.png").arg(size).arg(icon)));
}

//---------------------------------------------------------------------------------------------------------------------
// Handle some basic command-line arguments shared between all carla variants

QString handleInitialCommandLineArguments(const int argc, char* argv[])
{
static const QStringList listArgsNoGUI = { "-n", "--n", "-no-gui", "--no-gui", "-nogui", "--nogui" };
static const QStringList listArgsHelp = { "-h", "--h", "-help", "--help" };
static const QStringList listArgsVersion = { "-v", "--v", "-version", "--version" };

QString initName(argv[0]); // = os.path.basename(file) if (file is not None and os.path.dirname(file) in PATH) else sys.argv[0]
// libPrefix = None

for (int i=1; i<argc; ++i)
{
const QString arg(argv[i]);

if (arg.startsWith("--with-appname="))
{
// initName = os.path.basename(arg.replace("--with-appname=", ""));
}
else if (arg.startsWith("--with-libprefix=") || arg == "--gdb")
{
pass();
}
else if (listArgsNoGUI.contains(arg))
{
gCarla.nogui = true;
}
else if (listArgsHelp.contains(arg))
{
carla_stdout("Usage: %s [OPTION]... [FILE|URL]", initName);
carla_stdout("");
carla_stdout(" where FILE can be a Carla project or preset file to be loaded, or URL if using Carla-Control");
carla_stdout("");
carla_stdout(" and OPTION can be one or more of the following:");
carla_stdout("");
carla_stdout(" --gdb \t Run Carla inside gdb.");
carla_stdout(" -n,--no-gui \t Run Carla headless, don't show UI.");
carla_stdout("");
carla_stdout(" -h,--help \t Print this help text and exit.");
carla_stdout(" -v,--version\t Print version information and exit.");
carla_stdout("");

std::exit(0);
}
else if (listArgsVersion.contains(arg))
{
/*
QString pathBinaries, pathResources = getPaths();
*/

carla_stdout("Using Carla version %s", CARLA_VERSION_STRING);
/*
carla_stdout(" Qt version: %s", QT_VERSION_STR);
carla_stdout(" Binary dir: %s", pathBinaries.toUtf8());
carla_stdout(" Resources dir: %s", pathResources.toUtf8());
*/

std::exit(0);
}
}

return initName;
}

//---------------------------------------------------------------------------------------------------------------------
// Get initial project file (as passed in the command-line parameters)

void getInitialProjectFile(void*, bool)
{
// TODO
}

//---------------------------------------------------------------------------------------------------------------------
// Get paths (binaries, resources)

void getPaths()
{
// TODO
}

//---------------------------------------------------------------------------------------------------------------------
// Signal handler

/*
void signalHandler(const int sig)
{
if (sig == SIGINT || sig == SIGTERM)
{
gCarla.term = true;
if (gCarla.gui != nullptr)
gCarla.gui.SIGTERM.emit();
}
else if (sig == SIGUSR1)
{
if (gCarla.gui != nullptr)
gCarla.gui.SIGUSR1.emit();
}
}
*/

void setUpSignals()
{
/*
signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler);
signal(SIGUSR1, signalHandler);
*/
}

//---------------------------------------------------------------------------------------------------------------------
// QLineEdit and QPushButton combo

QString getAndSetPath(QWidget* const parent, QLineEdit* const lineEdit)
{
const QCarlaString newPath = QFileDialog::getExistingDirectory(parent, parent->tr("Set Path"), lineEdit->text(), QFileDialog::ShowDirsOnly);
if (newPath.isNotEmpty())
lineEdit->setText(newPath);
return newPath;
}

//---------------------------------------------------------------------------------------------------------------------
// fill up a qlists from a C arrays

void fillQStringListFromStringArray(QStringList& list, const char* const* const stringArray)
{
uint count = 0;

// count number of strings first
for (; stringArray[count] != nullptr; ++count) {}

// allocate list
list.reserve(count);

// fill in strings
for (count = 0; stringArray[count] != nullptr; ++count)
list.append(stringArray[count]);
}

void fillQDoubleListFromDoubleArray(QList<double>& list, const double* const doubleArray)
{
uint count = 0;

// count number of strings first
for (; carla_isNotZero(doubleArray[count]); ++count) {}

// allocate list
list.reserve(count);

// fill in strings
for (count = 0; carla_isNotZero(doubleArray[count]); ++count)
list.append(doubleArray[count]);
}

void fillQUIntListFromUIntArray(QList<uint>& list, const uint* const uintArray)
{
uint count = 0;

// count number of strings first
for (; uintArray[count] != 0; ++count) {}

// allocate list
list.reserve(count);

// fill in strings
for (count = 0; uintArray[count] != 0; ++count)
list.append(uintArray[count]);
}

//---------------------------------------------------------------------------------------------------------------------
// Backwards-compatible horizontalAdvance/width call, depending on qt version

int fontMetricsHorizontalAdvance(const QFontMetrics& fm, const QString& s)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
return fm.horizontalAdvance(s);
#else
return fm.width(s);
#endif
}

//---------------------------------------------------------------------------------------------------------------------
// Check if a string array contains a string

bool stringArrayContainsString(const char* const* const stringArray, const char* const string) noexcept
{
for (uint i=0; stringArray[i] != nullptr; ++i)
{
if (std::strcmp(stringArray[i], string) == 0)
return true;
}

return false;
}

//---------------------------------------------------------------------------------------------------------------------
// Custom QMessageBox which resizes itself to fit text

void QMessageBoxWithBetterWidth::showEvent(QShowEvent* const event)
{
const QFontMetrics metrics(fontMetrics());
const QStringList lines(text().trimmed().split("\n") + informativeText().trimmed().split("\n"));

if (lines.size() > 0)
{
int width = 0;

for (const QString& line : lines)
width = std::max(fontMetricsHorizontalAdvance(metrics, line), width);

if (QGridLayout* const layout_ = dynamic_cast<QGridLayout*>(layout()))
layout_->setColumnMinimumWidth(2, width + 12);
}

QMessageBox::showEvent(event);
}

//---------------------------------------------------------------------------------------------------------------------
// Safer QSettings class, which does not throw if type mismatches

bool QSafeSettings::valueBool(const QString key, const bool defaultValue) const
{
QVariant var(value(key, defaultValue));
CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::Bool), defaultValue);

return var.isValid() ? var.toBool() : defaultValue;
}

uint QSafeSettings::valueUInt(const QString key, const uint defaultValue) const
{
QVariant var(value(key, defaultValue));
CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::UInt), defaultValue);

return var.isValid() ? var.toUInt() : defaultValue;
}

double QSafeSettings::valueDouble(const QString key, const double defaultValue) const
{
QVariant var(value(key, defaultValue));
CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::Double), defaultValue);

return var.isValid() ? var.toDouble() : defaultValue;
}

QString QSafeSettings::valueString(const QString key, const QString defaultValue) const
{
QVariant var(value(key, defaultValue));
CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::String), defaultValue);

return var.isValid() ? var.toString() : defaultValue;
}

QByteArray QSafeSettings::valueByteArray(const QString key, const QByteArray defaultValue) const
{
QVariant var(value(key, defaultValue));
CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::ByteArray), defaultValue);

return var.isValid() ? var.toByteArray() : defaultValue;
}

QStringList QSafeSettings::valueStringList(const QString key, const QStringList defaultValue) const
{
QVariant var(value(key, defaultValue));
CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::StringList), defaultValue);

return var.isValid() ? var.toStringList() : defaultValue;
}

//---------------------------------------------------------------------------------------------------------------------
// Custom MessageBox

int CustomMessageBox(QWidget* const parent,
const QMessageBox::Icon icon,
const QString title,
const QString text,
const QString extraText,
const QMessageBox::StandardButtons buttons,
const QMessageBox::StandardButton defButton)
{
QMessageBoxWithBetterWidth msgBox(parent);
msgBox.setIcon(icon);
msgBox.setWindowTitle(title);
msgBox.setText(text);
msgBox.setInformativeText(extraText);
msgBox.setStandardButtons(buttons);
msgBox.setDefaultButton(defButton);
return msgBox.exec();
}

//---------------------------------------------------------------------------------------------------------------------

+ 86
- 222
source/frontend/carla_shared.hpp View File

@@ -18,17 +18,25 @@
#ifndef CARLA_SHARED_HPP_INCLUDED
#define CARLA_SHARED_HPP_INCLUDED

#include "../utils/CarlaUtils.hpp"

//---------------------------------------------------------------------------------------------------------------------
// Imports (Global)

#include <QtCore/QSettings>
#include <QtCore/QStringList>

#include <QtGui/QFontMetrics>
#include <QtGui/QIcon>

#include <QtWidgets/QMessageBox>

class QFontMetrics;
class QLineEdit;
class QMainWindow;

//---------------------------------------------------------------------------------------------------------------------
// Imports (Custom)

#include "CarlaDefines.h"

//---------------------------------------------------------------------------------------------------------------------
// Static MIDI CC list

@@ -245,6 +253,25 @@ static const char* const* const MIDI_CC_LIST = {
#define CARLA_DEFAULT_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR false
#define CARLA_DEFAULT_EXPERIMENTAL_LOAD_LIB_GLOBAL false

//---------------------------------------------------------------------------------------------------------------------
// Default File Folders

#define CARLA_DEFAULT_FILE_PATH_AUDIO []
#define CARLA_DEFAULT_FILE_PATH_MIDI []

//---------------------------------------------------------------------------------------------------------------------
// Default Plugin Folders (get)

#define DEFAULT_LADSPA_PATH ""
#define DEFAULT_DSSI_PATH ""
#define DEFAULT_LV2_PATH ""
#define DEFAULT_VST2_PATH ""
#define DEFAULT_VST3_PATH ""
#define DEFAULT_SF2_PATH ""
#define DEFAULT_SFZ_PATH ""

// TODO

//---------------------------------------------------------------------------------------------------------------------
// Global Carla object

@@ -253,169 +280,68 @@ struct CarlaObject {
bool nogui; // Skip UI
bool term; // Terminated by OS signal

CarlaObject()
: gui(nullptr),
nogui(false),
term(false) {}
CarlaObject() noexcept;
};

extern CarlaObject gCarla;

//---------------------------------------------------------------------------------------------------------------------
// Signal handler
// Set DLL_EXTENSION

/*
void signalHandler(const int sig)
{
if (sig == SIGINT || sig == SIGTERM)
{
gCarla.term = true;
if (gCarla.gui != nullptr)
gCarla.gui.SIGTERM.emit();
}
else if (sig == SIGUSR1)
{
if (gCarla.gui != nullptr)
gCarla.gui.SIGUSR1.emit();
}
}
*/
#if defined(CARLA_OS_WIN)
# define DLL_EXTENSION "dll"
#elif defined(CARLA_OS_MAC)
# define DLL_EXTENSION "dylib"
#else
# define DLL_EXTENSION "so"
#endif

inline void setUpSignals()
{
/*
signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler);
signal(SIGUSR1, signalHandler);
*/
}
//---------------------------------------------------------------------------------------------------------------------
// Get Icon from user theme, using our own as backup (Oxygen)

QIcon getIcon(QString icon, int size = 16);

//---------------------------------------------------------------------------------------------------------------------
// Handle some basic command-line arguments shared between all carla variants

inline
QString handleInitialCommandLineArguments(const int argc, char* argv[])
{
static const QStringList listArgsNoGUI = { "-n", "--n", "-no-gui", "--no-gui", "-nogui", "--nogui" };
static const QStringList listArgsHelp = { "-h", "--h", "-help", "--help" };
static const QStringList listArgsVersion = { "-v", "--v", "-version", "--version" };

QString initName(argv[0]); // = os.path.basename(file) if (file is not None and os.path.dirname(file) in PATH) else sys.argv[0]
// libPrefix = None
QString handleInitialCommandLineArguments(const int argc, char* argv[]);

for (int i=1; i<argc; ++i)
{
const QString arg(argv[i]);

if (arg.startsWith("--with-appname="))
{
// initName = os.path.basename(arg.replace("--with-appname=", ""));
}
else if (arg.startsWith("--with-libprefix=") || arg == "--gdb")
{
pass();
}
else if (listArgsNoGUI.contains(arg))
{
gCarla.nogui = true;
}
else if (listArgsHelp.contains(arg))
{
carla_stdout("Usage: %s [OPTION]... [FILE|URL]", initName);
carla_stdout("");
carla_stdout(" where FILE can be a Carla project or preset file to be loaded, or URL if using Carla-Control");
carla_stdout("");
carla_stdout(" and OPTION can be one or more of the following:");
carla_stdout("");
carla_stdout(" --gdb \t Run Carla inside gdb.");
carla_stdout(" -n,--no-gui \t Run Carla headless, don't show UI.");
carla_stdout("");
carla_stdout(" -h,--help \t Print this help text and exit.");
carla_stdout(" -v,--version\t Print version information and exit.");
carla_stdout("");

std::exit(0);
}
else if (listArgsVersion.contains(arg))
{
/*
QString pathBinaries, pathResources = getPaths();
*/

carla_stdout("Using Carla version %s", CARLA_VERSION_STRING);
/*
carla_stdout(" Qt version: %s", QT_VERSION_STR);
carla_stdout(" Binary dir: %s", pathBinaries.toUtf8());
carla_stdout(" Resources dir: %s", pathResources.toUtf8());
*/

std::exit(0);
}
}
//---------------------------------------------------------------------------------------------------------------------
// Get initial project file (as passed in the command-line parameters)

return initName;
}
void getInitialProjectFile(void* app, bool skipExistCheck = false);

#if 0
//---------------------------------------------------------------------------------------------------------------------
// Get Icon from user theme, using our own as backup (Oxygen)
// Get paths (binaries, resources)

def getIcon(icon, size = 16):
return QIcon.fromTheme(icon, QIcon(":/%ix%i/%s.png" % (size, size, icon)))
void getPaths();

//---------------------------------------------------------------------------------------------------------------------
// QLineEdit and QPushButton combo
// Signal handler

def getAndSetPath(parent, lineEdit):
newPath = QFileDialog.getExistingDirectory(parent, parent.tr("Set Path"), lineEdit.text(), QFileDialog.ShowDirsOnly)
if newPath:
lineEdit.setText(newPath)
return newPath
#endif
void setUpSignals();

//---------------------------------------------------------------------------------------------------------------------
// Check if a string array contains a string

static inline
bool stringArrayContainsString(const char* const* const stringArray, const char* const string) noexcept
{
for (uint i=0; stringArray[i] != nullptr; ++i)
{
if (std::strcmp(stringArray[i], string) == 0)
return true;
}
// QLineEdit and QPushButton combo

return false;
}
QString getAndSetPath(QWidget* parent, QLineEdit* lineEdit);

static inline
void fillQStringListFromStringArray(QStringList& list, const char* const* const stringArray)
{
uint count = 0;
//---------------------------------------------------------------------------------------------------------------------
// fill up a qlists from a C arrays

// count number of strings first
for (; stringArray[count] != nullptr; ++count) {}
void fillQStringListFromStringArray(QStringList& list, const char* const* const stringArray);
void fillQDoubleListFromDoubleArray(QList<double>& list, const double* const doubleArray);
void fillQUIntListFromUIntArray(QList<uint>& list, const uint* const uintArray);

// allocate list
list.reserve(count);
//---------------------------------------------------------------------------------------------------------------------
// Backwards-compatible horizontalAdvance/width call, depending on qt version

// fill in strings
for (count = 0; stringArray[count] != nullptr; ++count)
list.replace(count, stringArray[count]);
}
int fontMetricsHorizontalAdvance(const QFontMetrics& fm, const QString& s);

//---------------------------------------------------------------------------------------------------------------------
// Backwards-compatible horizontalAdvance/width call, depending on qt version
// Check if a string array contains a string

static inline
int fontMetricsHorizontalAdvance(const QFontMetrics& fm, const QString& s)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
return fm.horizontalAdvance(s);
#else
return fm.width(s);
#endif
}
bool stringArrayContainsString(const char* const* const stringArray, const char* const string) noexcept;

//---------------------------------------------------------------------------------------------------------------------
// Custom QString class with a few extra methods
@@ -423,13 +349,13 @@ int fontMetricsHorizontalAdvance(const QFontMetrics& fm, const QString& s)
class QCarlaString : public QString
{
public:
QCarlaString()
inline QCarlaString()
: QString() {}

QCarlaString(const char* const ch)
inline QCarlaString(const char* const ch)
: QString(ch) {}

QCarlaString(const QString& s)
inline QCarlaString(const QString& s)
: QString(s) {}

inline bool isNotEmpty() const
@@ -443,29 +369,18 @@ public:
}
};

#if 0
//---------------------------------------------------------------------------------------------------------------------
// Custom QMessageBox which resizes itself to fit text

class QMessageBoxWithBetterWidth(QMessageBox):
def __init__(self, parent):
QMessageBox.__init__(self, parent)

def showEvent(self, event):
fontMetrics = self.fontMetrics()

lines = self.text().strip().split("\n") + self.informativeText().strip().split("\n")

if len(lines) > 0:
width = 0

for line in lines:
width = max(fontMetrics.width(line), width)

self.layout().setColumnMinimumWidth(2, width + 12)
class QMessageBoxWithBetterWidth : public QMessageBox
{
public:
inline QMessageBoxWithBetterWidth(QWidget* const parent)
: QMessageBox(parent) {}

QMessageBox.showEvent(self, event)
#endif
protected:
void showEvent(QShowEvent* event);
};

//---------------------------------------------------------------------------------------------------------------------
// Safer QSettings class, which does not throw if type mismatches
@@ -473,78 +388,27 @@ class QMessageBoxWithBetterWidth(QMessageBox):
class QSafeSettings : public QSettings
{
public:
QSafeSettings()
inline QSafeSettings()
: QSettings() {}

QSafeSettings(const QString organizationName, const QString applicationName)
inline QSafeSettings(const QString organizationName, const QString applicationName)
: QSettings(organizationName, applicationName) {}

bool valueBool(const QString key, const bool defaultValue) const
{
QVariant var(value(key, defaultValue));
CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::Bool), defaultValue);

return var.isValid() ? var.toBool() : defaultValue;
}

uint valueUInt(const QString key, const uint defaultValue) const
{
QVariant var(value(key, defaultValue));
CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::UInt), defaultValue);

return var.isValid() ? var.toUInt() : defaultValue;
}

double valueDouble(const QString key, const double defaultValue) const
{
QVariant var(value(key, defaultValue));
CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::Double), defaultValue);

return var.isValid() ? var.toDouble() : defaultValue;
}

QString valueString(const QString key, const QString defaultValue) const
{
QVariant var(value(key, defaultValue));
CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::String), defaultValue);

return var.isValid() ? var.toString() : defaultValue;
}

QByteArray valueByteArray(const QString key, const QByteArray defaultValue = QByteArray()) const
{
QVariant var(value(key, defaultValue));
CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::ByteArray), defaultValue);

return var.isValid() ? var.toByteArray() : defaultValue;
}

QStringList valueStringList(const QString key, const QStringList defaultValue = QStringList()) const
{
QVariant var(value(key, defaultValue));
CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::StringList), defaultValue);

return var.isValid() ? var.toStringList() : defaultValue;
}
bool valueBool(const QString key, const bool defaultValue) const;
uint valueUInt(const QString key, const uint defaultValue) const;
double valueDouble(const QString key, const double defaultValue) const;
QString valueString(const QString key, const QString defaultValue) const;
QByteArray valueByteArray(const QString key, const QByteArray defaultValue = QByteArray()) const;
QStringList valueStringList(const QString key, const QStringList defaultValue = QStringList()) const;
};

#if 0
//---------------------------------------------------------------------------------------------------------------------
// Custom MessageBox

def CustomMessageBox(parent, icon, title, text,
extraText="",
buttons=QMessageBox.Yes|QMessageBox.No,
defButton=QMessageBox.No):
msgBox = QMessageBoxWithBetterWidth(parent)
msgBox.setIcon(icon)
msgBox.setWindowTitle(title)
msgBox.setText(text)
msgBox.setInformativeText(extraText)
msgBox.setStandardButtons(buttons)
msgBox.setDefaultButton(defButton)
return msgBox.exec_()
#endif
int CustomMessageBox(QWidget* parent, QMessageBox::Icon icon, QString title, QString text,
QString extraText = "",
QMessageBox::StandardButtons buttons = QMessageBox::Yes|QMessageBox::No,
QMessageBox::StandardButton defButton = QMessageBox::No);

//---------------------------------------------------------------------------------------------------------------------



source/frontend/C++/widgets/canvaspreviewframe.h → source/frontend/widgets/canvaspreviewframe.h View File


source/frontend/C++/widgets/digitalpeakmeter.h → source/frontend/widgets/digitalpeakmeter.h View File


source/frontend/C++/widgets/draggablegraphicsview.h → source/frontend/widgets/draggablegraphicsview.h View File


source/frontend/C++/widgets/racklistwidget.h → source/frontend/widgets/racklistwidget.h View File


Loading…
Cancel
Save