Browse Source

Start of mixed C++ and Python for frontend, jack-app dialog first

pull/1723/head
falkTX 3 years ago
parent
commit
6cdfc2e9cd
8 changed files with 263 additions and 40 deletions
  1. +39
    -2
      source/frontend/Makefile
  2. +2
    -18
      source/frontend/carla_frontend.cpp
  3. +72
    -0
      source/frontend/carla_frontend.py
  4. +18
    -10
      source/frontend/carla_host.py
  5. +1
    -0
      source/frontend/carla_shared.py
  6. +39
    -10
      source/frontend/pluginlist/jackappdialog.cpp
  7. +18
    -0
      source/frontend/pluginlist/jackappdialog.hpp
  8. +74
    -0
      source/frontend/widgets/collapsablewidget.hpp

+ 39
- 2
source/frontend/Makefile View File

@@ -12,6 +12,20 @@ include $(CWD)/Makefile.mk
BINDIR := $(CWD)/../bin
RESDIR := $(CWD)/../resources

ifeq ($(DEBUG),true)
OBJDIR := $(CWD)/../build/frontend/Debug
else
OBJDIR := $(CWD)/../build/frontend/Release
endif

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

BUILD_CXX_FLAGS += -Iutils

BUILD_CXX_FLAGS += -I../backend
BUILD_CXX_FLAGS += -I../includes
BUILD_CXX_FLAGS += -I../utils

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

ifeq ($(WINDOWS),true)
@@ -38,6 +52,15 @@ endif
TSs = $(patsubst %,translations/carla_%.ts,$(I18N_LANGUAGES))
QMs = $(patsubst %,translations/carla_%.qm,$(I18N_LANGUAGES))

# ---------------------------------------------------------------------------------------------------------------------
# C++ files

CPP_FILES = \
carla_frontend.cpp \
pluginlist/jackappdialog.cpp

OBJS = $(CPP_FILES:%=$(OBJDIR)/%.o)

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

@@ -119,7 +142,7 @@ UIs += \

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

all: $(QMs) $(RES) $(UIs)
all: $(BINDIR)/libcarla_frontend$(LIB_EXT) $(QMs) $(RES) $(UIs)

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

@@ -149,8 +172,22 @@ $(BINDIR)/resources/zynaddsubfx-ui: ../native-plugins/resources/zynaddsubfx-ui

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

$(BINDIR)/libcarla_frontend$(LIB_EXT): $(OBJS) $(LIBS)
-@mkdir -p $(BINDIR)
@echo "Linking libcarla_frontend$(LIB_EXT)"
$(SILENT)$(CXX) $(OBJS) $(BUILD_CXX_FLAGS) $(QT5_LINK_FLAGS) $(SHARED) -o $@

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

-include $(OBJS:%.o=%.d)

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

clean:
rm -rf $(UIs) $(RES) $(QMs) __pycache__ *.pyc
rm -rf $(BINDIR)/libcarla_frontend$(LIB_EXT) $(UIs) $(RES) $(QMs) __pycache__ *.pyc
# old files
rm -f ui_carla_add_jack.py
rm -f ui_carla_database.py


+ 2
- 18
source/frontend/carla_frontend.cpp View File

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

#include "CarlaBackend.h"
#include "CarlaUtils.hpp"

namespace CB = CARLA_BACKEND_NAMESPACE;

// -------------------------------------------------------------------------------------------------------------------
// common files

struct WidgetResult {
union {
struct {
const char* command;
const char* name;
const char* labelSetup;
} jackappdialog;
};
};

CARLA_PLUGIN_EXPORT void* carla_frontend_create_widget(void* parent, const char* widgetType);

CARLA_PLUGIN_EXPORT void* carla_frontend_get_result(void* widget, const char* widgetType);
#include "utils/qsafesettings.cpp"

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

+ 72
- 0
source/frontend/carla_frontend.py View File

@@ -0,0 +1,72 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla Backend utils
# Copyright (C) 2011-2022 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
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.

# ------------------------------------------------------------------------------------------------------------
# Imports (Global)

# ------------------------------------------------------------------------------------------------------------
# Imports (ctypes)

from ctypes import (
c_bool, c_char_p, c_double, c_int, c_uint, c_uint32, c_void_p, cast,
cdll, Structure,
CFUNCTYPE, POINTER
)

from sip import voidptr

# ------------------------------------------------------------------------------------------------------------
# Imports (Custom)

from carla_backend import (
structToDict
)

# ---------------------------------------------------------------------------------------------------------------------
# Convert a ctypes struct into a python dict, or None if null

def structToDictOrNull(struct):
return structToDict(struct.contents) if struct else None

# ------------------------------------------------------------------------------------------------------------
# Carla Frontend API (C stuff)

class JackApplicationDialogResults(Structure):
_fields_ = [
("command", c_char_p),
("name", c_char_p),
("labelSetup", c_char_p)
]

# ------------------------------------------------------------------------------------------------------------
# Carla Frontend object using a DLL

class CarlaFrontendLib():
def __init__(self, filename):
self.lib = cdll.LoadLibrary(filename)

self.lib.carla_frontend_createAndExecJackApplicationW.argtypes = (c_void_p, c_char_p)
self.lib.carla_frontend_createAndExecJackApplicationW.restype = POINTER(JackApplicationDialogResults)

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

def createAndExecJackApplicationW(self, parent, projectFilename):
# FIXME cast(c_void_p, voidptr(parent))
return structToDictOrNull(self.lib.carla_frontend_createAndExecJackApplicationW(None, projectFilename.encode("utf-8")))

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

+ 18
- 10
source/frontend/carla_host.py View File

@@ -55,13 +55,14 @@ import ui_carla_host
from carla_app import *
from carla_backend import *
from carla_backend_qt import CarlaHostQtDLL, CarlaHostQtNull
from carla_frontend import CarlaFrontendLib
from carla_shared import *
from carla_settings import *
from carla_utils import *
from carla_widgets import *

from patchcanvas import patchcanvas
from pluginlist import PluginDatabaseW
from pluginlist import PluginDatabaseW, JackApplicationW
from widgets.digitalpeakmeter import DigitalPeakMeter
from widgets.pixmapkeyboard import PixmapKeyboardHArea

@@ -1235,16 +1236,16 @@ class HostWindow(QMainWindow):
return (btype, ptype, filename, label, uniqueId, extraPtr)

def showAddJackAppDialog(self):
dialog = JackApplicationW(self.fParentOrSelf, self.fProjectFilename)
ret = gCarla.felib.createAndExecJackApplicationW(self.fParentOrSelf, self.fProjectFilename)

if not dialog.exec_():
if not ret:
return

if not self.host.is_engine_running():
QMessageBox.warning(self, self.tr("Warning"), self.tr("Cannot add new plugins while engine is stopped"))
return

return dialog.getCommandAndFlags()
return ret

@pyqtSlot()
def slot_favoritePluginAdd(self):
@@ -1351,16 +1352,16 @@ class HostWindow(QMainWindow):
if data is None:
return

filename, name, label = data

if not filename:
if not data['command']:
CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Cannot add jack application"),
self.tr("command is empty"), QMessageBox.Ok, QMessageBox.Ok)
self.tr("command is empty"), QMessageBox.Ok, QMessageBox.Ok)
return

if not self.host.add_plugin(BINARY_NATIVE, PLUGIN_JACK, filename, name, label, 0, None, PLUGIN_OPTIONS_NULL):
if not self.host.add_plugin(BINARY_NATIVE, PLUGIN_JACK,
data['command'], data['name'], data['labelSetup'],
0, None, PLUGIN_OPTIONS_NULL):
CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to load plugin"),
self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)
self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)

# --------------------------------------------------------------------------------------------------------
# Plugins (macros)
@@ -3234,6 +3235,7 @@ def initHost(initName, libPrefix, isControl, isPlugin, failError, HostClass = No

libname = "libcarla_%s2.%s" % ("control" if isControl else "standalone", DLL_EXTENSION)
libname = os.path.join(pathBinaries, libname)
felibname = os.path.join(pathBinaries, "libcarla_frontend.%s" % (DLL_EXTENSION))
utilsname = os.path.join(pathBinaries, "libcarla_utils.%s" % (DLL_EXTENSION))

# --------------------------------------------------------------------------------------------------------
@@ -3275,6 +3277,12 @@ def initHost(initName, libPrefix, isControl, isPlugin, failError, HostClass = No
if not isControl:
host.nsmOK = host.nsm_init(os.getpid(), initName)

# --------------------------------------------------------------------------------------------------------
# Init frontend lib

if not gCarla.nogui:
gCarla.felib = CarlaFrontendLib(felibname)

# --------------------------------------------------------------------------------------------------------
# Init utils



+ 1
- 0
source/frontend/carla_shared.py View File

@@ -594,6 +594,7 @@ class CarlaObject():
self.gui = None # Host Window
self.nogui = False # Skip UI
self.term = False # Terminated by OS signal
self.felib = None # Frontend lib object
self.utils = None # Utils object

gCarla = CarlaObject()


+ 39
- 10
source/frontend/pluginlist/jackappdialog.cpp View File

@@ -38,8 +38,10 @@
# pragma GCC diagnostic pop
#endif

#include "../utils/qsafesettings.hpp"
#include "../../includes/CarlaLibJackHints.h"
#include "qsafesettings.hpp"

#include "CarlaLibJackHints.h"
#include "CarlaString.hpp"

// --------------------------------------------------------------------------------------------------------------------
// Jack Application Dialog
@@ -113,7 +115,7 @@ JackApplicationW::CommandAndFlags JackApplicationW::getCommandAndFlags() const
}

SessionManager smgr;
switch(self.ui.cb_session_mgr->currentIndex())
switch (self.ui.cb_session_mgr->currentIndex())
{
case UI_SESSION_LADISH:
smgr = LIBJACK_SESSION_MANAGER_LADISH;
@@ -238,6 +240,35 @@ void JackApplicationW::slot_saveSettings()
settings.setValue("MidiOutMixdown", self.ui.cb_out_midi_mixdown->isChecked());
}

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

JackApplicationDialogResults* carla_frontend_createAndExecJackApplicationW(void* const parent, const char* const projectFilename)
{
JackApplicationW gui(reinterpret_cast<QWidget*>(parent), projectFilename);

if (gui.exec())
{
static JackApplicationDialogResults ret = {};
static CarlaString retCommand;
static CarlaString retName;
static CarlaString retLabelSetup;

const JackApplicationW::CommandAndFlags cafs = gui.getCommandAndFlags();
retCommand = cafs.command.toUtf8().constData();
retName = cafs.name.toUtf8().constData();
retLabelSetup = cafs.labelSetup.toUtf8().constData();

ret.command = retCommand;
ret.name = retName;
ret.labelSetup = retLabelSetup;

return &ret;
}

return nullptr;
}

#if 0
// --------------------------------------------------------------------------------------------------------------------
// Testing

@@ -246,19 +277,17 @@ void JackApplicationW::slot_saveSettings()
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
JackApplicationW gui(nullptr, "");
gui.show();

if (gui.exec())
if (JackApplicationDialogResults* const res = carla_frontend_createAndExecJackApplicationW(nullptr, ""))
{
auto cf = gui.getCommandAndFlags();
printf("Results:\n");
printf("\tCommand: %s\n", cf.command.toUtf8().constData());
printf("\tName: %s\n", cf.name.toUtf8().constData());
printf("\tLabelSetup: %s\n", cf.labelSetup.toUtf8().constData());
printf("\tCommand: %s\n", res->command);
printf("\tName: %s\n", res->name);
printf("\tLabelSetup: %s\n", res->labelSetup);
}

return 0;
}
#endif

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

+ 18
- 0
source/frontend/pluginlist/jackappdialog.hpp View File

@@ -35,6 +35,8 @@

#include "../utils/qcarlastring.hpp"

#include "CarlaDefines.h"

// --------------------------------------------------------------------------------------------------------------------
// Jack Application Dialog

@@ -43,6 +45,8 @@ class JackApplicationW : public QDialog
struct Self;
Self& self;

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

public:
explicit JackApplicationW(QWidget* parent, const char* projectFilename);
~JackApplicationW() override;
@@ -74,3 +78,17 @@ private slots:
};

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

extern "C" {

struct JackApplicationDialogResults {
const char* command;
const char* name;
const char* labelSetup;
};

CARLA_API JackApplicationDialogResults* carla_frontend_createAndExecJackApplicationW(void* parent, const char* projectFilename);

}

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

+ 74
- 0
source/frontend/widgets/collapsablewidget.hpp View File

@@ -0,0 +1,74 @@
/*
* Carla plugin host
* Copyright (C) 2011-2022 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
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#include "QtWidgets/qboxlayout.h"
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy"
# pragma clang diagnostic ignored "-Wdeprecated-register"
#elif defined(__GNUC__) && __GNUC__ >= 8
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wclass-memaccess"
# pragma GCC diagnostic ignored "-Wdeprecated-copy"
#endif

#include <QtWidgets/QFrame>
#include <QtWidgets/QVBoxLayout>

#ifdef __clang__
# pragma clang diagnostic pop
#elif defined(__GNUC__) && __GNUC__ >= 8
# pragma GCC diagnostic pop
#endif

#include "CarlaDefines.h"

// --------------------------------------------------------------------------------------------------------------------
// Jack Application Dialog

class CollapsibleBox : public QFrame
{
struct Self;
Self& self;

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

public:
explicit CollapsibleBox(QWidget* parent);
~CollapsibleBox() override;

// ----------------------------------------------------------------------------------------------------------------
// public methods

QVBoxLayout* getContentLayout() const noexcept;

// ----------------------------------------------------------------------------------------------------------------
// private slots

private slots:
void toolButtonPressed(bool toggled);
};

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

extern "C" {

CARLA_API void* carla_frontend_createCollapsibleBox(void* parent);

}

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

Loading…
Cancel
Save