Skip to content

Commit

Permalink
Begin implementing PluginPinConnectorView
Browse files Browse the repository at this point in the history
  • Loading branch information
messmerd committed Aug 14, 2024
1 parent 853d80c commit 7935718
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 10 deletions.
7 changes: 3 additions & 4 deletions include/PluginPinConnector.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#ifndef LMMS_PLUGIN_PIN_CONNECTOR_H
#define LMMS_PLUGIN_PIN_CONNECTOR_H

#include <QObject>
#include <vector>

#include "AutomatableModel.h"
Expand All @@ -42,13 +41,13 @@ namespace lmms
namespace gui
{

class PluginPinConnectorWidget;
class PluginPinConnectorView;

} // namespace gui

//! Configure channel routing for a plugin's mono/stereo in/out ports
class LMMS_EXPORT PluginPinConnector
: public QObject
: public Model
, public SerializingObject
{
Q_OBJECT
Expand Down Expand Up @@ -123,7 +122,7 @@ class LMMS_EXPORT PluginPinConnector
void loadSettings(const QDomElement& elem) override;
auto nodeName() const -> QString override { return "pins"; }

auto instantiateView(QWidget* parent = nullptr) -> gui::PluginPinConnectorWidget*;
auto instantiateView(QWidget* parent = nullptr) -> gui::PluginPinConnectorView*;

static constexpr int MaxTrackChannels = 256;

Expand Down
66 changes: 66 additions & 0 deletions include/PluginPinConnectorView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* PluginPinConnectorView.h - Displays pin connectors
*
* Copyright (c) 2024 Dalton Messmer <messmer.dalton/at/gmail.com>
*
* This file is part of LMMS - https://lmms.io
*
* 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 (at your option) 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.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/

#ifndef LMMS_GUI_PLUGIN_PIN_CONNECTOR_VIEW_H
#define LMMS_GUI_PLUGIN_PIN_CONNECTOR_VIEW_H

#include <QWidget>

#include "ModelView.h"
#include "embed.h"

namespace lmms
{

namespace gui
{

class PluginPinConnectorView
: public QWidget
, public ModelView
{
public:
PluginPinConnectorView(QWidget* parent);

auto sizeHint() const -> QSize override;

protected:
void mousePressEvent(QMouseEvent* me) override;
void paintEvent(QPaintEvent* pe) override;

private:
QRect m_pinsInRect;
QRect m_pinsOutRect;

QPixmap m_buttonOffBlack = embed::getIconPixmap("step_btn_off");
QPixmap m_buttonOffGray = embed::getIconPixmap("step_btn_off_light");
//QPixmap m_buttonOn0 = embed::getIconPixmap("step_btn_on_0");
QPixmap m_buttonOn = embed::getIconPixmap("step_btn_on_200");
};

} // namespace gui

} // namespace lmms

#endif // LMMS_GUI_PLUGIN_PIN_CONNECTOR_VIEW_H
7 changes: 7 additions & 0 deletions plugins/VstEffect/VstEffectControls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "embed.h"
#include "ComboBox.h"
#include "CustomTextKnob.h"
#include "PluginPinConnectorView.h"
#include "VstEffectControls.h"
#include "VstEffectControlDialog.h"
#include "VstEffect.h"
Expand Down Expand Up @@ -372,6 +373,12 @@ ManageVSTEffectView::ManageVSTEffectView( VstEffect * _eff, VstEffectControls *
l->addWidget(m_portConfig, 0, 2, 1, 3, Qt::AlignLeft);
}*/

if (auto pc = m_vi->pinConnector())
{
m_pinConnector = pc->instantiateView(widget);
l->addWidget(m_pinConnector, 0, 2, 1, 3, Qt::AlignLeft);
}

for( int i = 0; i < 10; i++ )
{
l->addItem( new QSpacerItem( 68, 45, QSizePolicy::Fixed, QSizePolicy::Fixed ), 0, i );
Expand Down
4 changes: 2 additions & 2 deletions plugins/VstEffect/VstEffectControls.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ class VstEffect;

namespace gui
{
class ComboBox;
class CustomTextKnob;
class ManageVSTEffectView;
class PluginPinConnectorView;
class VstEffectControlDialog;
}

Expand Down Expand Up @@ -140,7 +140,7 @@ protected slots:

QPushButton * m_syncButton;
QPushButton * m_displayAutomatedOnly;
ComboBox* m_portConfig;
PluginPinConnectorView* m_pinConnector;
CustomTextKnob ** vstKnobs;

} ;
Expand Down
11 changes: 7 additions & 4 deletions src/core/PluginPinConnector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,18 @@

#include "AudioEngine.h"
#include "Model.h"
#include "PluginPinConnectorView.h"

namespace lmms
{

PluginPinConnector::PluginPinConnector(Model* parent)
: QObject{parent}
: Model{parent}
{
}

PluginPinConnector::PluginPinConnector(int pluginInCount, int pluginOutCount, Model* parent)
: QObject{parent}
: Model{parent}
{
setChannelCounts(pluginInCount, pluginOutCount);
}
Expand Down Expand Up @@ -440,9 +441,11 @@ void PluginPinConnector::setChannelCount(int newCount, PluginPinConnector::PinMa
oldCount = newCount;
};

auto PluginPinConnector::instantiateView(QWidget* parent) -> gui::PluginPinConnectorWidget*
auto PluginPinConnector::instantiateView(QWidget* parent) -> gui::PluginPinConnectorView*
{
throw std::runtime_error{"Not implemented yet"};
auto view = new gui::PluginPinConnectorView{parent};
view->setModel(this);
return view;
}

void PluginPinConnector::updateOptions()
Expand Down
1 change: 1 addition & 0 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ SET(LMMS_SRCS
gui/ModelView.cpp
gui/PeakControllerDialog.cpp
gui/PluginBrowser.cpp
gui/PluginPinConnectorView.cpp
gui/ProjectNotes.cpp
gui/RowTableView.cpp
gui/SampleLoader.cpp
Expand Down
160 changes: 160 additions & 0 deletions src/gui/PluginPinConnectorView.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*
* PluginPinConnectorView.cpp - Displays pin connectors
*
* Copyright (c) 2024 Dalton Messmer <messmer.dalton/at/gmail.com>
*
* This file is part of LMMS - https://lmms.io
*
* 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 (at your option) 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.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/

#include "PluginPinConnectorView.h"

#include <QMouseEvent>
#include <QPainter>

#include "PluginPinConnector.h"

#include "gui_templates.h"

namespace lmms
{

namespace gui
{

namespace
{

constexpr auto MarginSize = 2;

} // namespace

PluginPinConnectorView::PluginPinConnectorView(QWidget* parent)
: QWidget{parent}
, ModelView{nullptr, this}
{
}

auto PluginPinConnectorView::sizeHint() const -> QSize
{
return QSize{512, 256};
}

void PluginPinConnectorView::mousePressEvent(QMouseEvent* me)
{
if (me->button() != Qt::LeftButton) { return; }

const auto* pinConnector = castModel<PluginPinConnector>();
if (!pinConnector) { return; }

const int buttonW = m_buttonOn.width();
const int buttonH = m_buttonOn.height();

auto handleClick = [&](const PluginPinConnector::PinMap& pins, QRect rect) -> bool {
if (!rect.contains(me->pos(), true)) { return false; }

const auto relMousePos = me->pos() - rect.topLeft();
const int xIdx = relMousePos.x() / (buttonW + MarginSize);
const int yIdx = relMousePos.y() / (buttonH + MarginSize);

// Check if within margin
int relPos = relMousePos.x() - xIdx * buttonW;
if (relPos >= buttonW || relPos <= 0) { return false; }
relPos = relMousePos.y() - yIdx * buttonH;
if (relPos >= buttonH || relPos <= 0) { return false; }

BoolModel* model = pins.at(yIdx).at(xIdx);
model->setValue(!model->value());

me->accept();
update();

return true;
};

if (!handleClick(pinConnector->pinMapIn(), m_pinsInRect))
{
if (!handleClick(pinConnector->pinMapOut(), m_pinsOutRect))
{
me->ignore();
}
}
}

void PluginPinConnectorView::paintEvent(QPaintEvent*)
{


auto p = QPainter{this};
p.setRenderHint(QPainter::Antialiasing);



// Draw the graph background
//p.drawPixmap(rect(), m_lfoGraph);

const auto* pinConnector = castModel<PluginPinConnector>();
if (!pinConnector) { return; }

const auto& pinsIn = pinConnector->pinMapIn();
const auto& pinsOut = pinConnector->pinMapOut();

//const auto w = width();
//const auto h = height();
const auto buttonW = m_buttonOn.width();
const auto buttonH = m_buttonOn.height();

p.fillRect(rect(), Qt::yellow);

auto drawGrid = [&](const PluginPinConnector::PinMap& pins, QPoint xy) -> QRect {
if (pins.empty() || pins[0].empty()) { return QRect{xy, xy}; }

const auto* offIcon = &m_buttonOffBlack;

auto drawXY = QPoint{};
drawXY.ry() = xy.y();

for (std::size_t tcIdx = 0; tcIdx < pins.size(); ++tcIdx)
{
drawXY.rx() = xy.x();

auto& pluginChannels = pins[tcIdx];
for (std::size_t pcIdx = 0; pcIdx < pluginChannels.size(); ++pcIdx)
{
const BoolModel* pin = pluginChannels[pcIdx];
p.drawPixmap(drawXY, pin->value() ? m_buttonOn : *offIcon);

// TODO: Alternate b/w black and gray icons

drawXY.rx() += buttonW + MarginSize;
}

drawXY.ry() += buttonH + MarginSize;
}

return QRect{xy, drawXY - QPoint{MarginSize, MarginSize}};
};

m_pinsInRect = drawGrid(pinsIn, QPoint{5, 10});
m_pinsOutRect = drawGrid(pinsOut, m_pinsInRect.topRight() + QPoint{5, 0});
}


} // namespace gui

} // namespace lmms

0 comments on commit 7935718

Please sign in to comment.