Skip to content

Commit

Permalink
vc/xypad: add pan/tilt fine external controls
Browse files Browse the repository at this point in the history
  • Loading branch information
mcallegari committed Jan 9, 2025
1 parent 8480d67 commit 3af6ff3
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 67 deletions.
1 change: 1 addition & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ qlcplus (4.14.0) stable; urgency=low
* Virtual Console/Slider: send feedback on override button press
* Virtual Console/Sped Dial: fix foreground color setting on Windows
* Virtual Console/Frame: fix widget page initialization on Operate mode
* Virtual Console/XY Pad: added Pan/Tilt fine external controls
* Plugins/OS2L: fix receiving multiple messages at once
* Web Access: reworked websocket implementation
* Web Access: fix grand master stopping running functions
Expand Down
90 changes: 57 additions & 33 deletions ui/src/virtualconsole/vcxypad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ const quint8 VCXYPad::panInputSourceId = 0;
const quint8 VCXYPad::tiltInputSourceId = 1;
const quint8 VCXYPad::widthInputSourceId = 2;
const quint8 VCXYPad::heightInputSourceId = 3;
const quint8 VCXYPad::panFineInputSourceId = 4;
const quint8 VCXYPad::tiltFineInputSourceId = 5;

const qreal MAX_VALUE = 256.0;
const qreal MAX_DMX_VALUE = MAX_VALUE - 1.0/256;
Expand Down Expand Up @@ -950,66 +952,95 @@ void VCXYPad::updateFeedback()
*/
}

void VCXYPad::updatePosition()
{
QPointF pt = m_area->position(false);
qreal xOffset = 0;
qreal yOffset = 0;
qreal areaWidth = MAX_VALUE;
qreal areaHeight = MAX_VALUE;

QRectF rangeWindow = m_area->rangeWindow();
if (rangeWindow.isValid())
{
xOffset = rangeWindow.x();
yOffset = rangeWindow.y();
areaWidth = rangeWindow.width();
areaHeight = rangeWindow.height();
}

pt.setX(xOffset + SCALE((qreal(m_lastPos.x()) * 256.0) + qreal(m_lastPos.width()), qreal(0), qreal(65535),
qreal(0), areaWidth));

if (invertedAppearance() == false)
pt.setY(yOffset + SCALE((qreal(m_lastPos.y()) * 256.0) + qreal(m_lastPos.height()), qreal(0), qreal(65535),
qreal(0), areaHeight));
else
pt.setY(yOffset + SCALE((qreal(m_lastPos.y()) * 256.0) + qreal(m_lastPos.height()), qreal(65535), qreal(0),
qreal(0), areaHeight));

m_inputValueChanged = true;

m_area->setPosition(pt);
m_area->update();
}

void VCXYPad::slotInputValueChanged(quint32 universe, quint32 channel,
uchar value)
{
/* Don't let input data through in design mode or if disabled */
if (acceptsInput() == false)
return;

QPointF pt = m_area->position(false);
quint32 pagedCh = (page() << 16) | channel;

if (checkInputSource(universe, pagedCh, value, sender(), panInputSourceId))
{
if (m_efx == NULL)
{
qreal areaWidth = MAX_VALUE;
qreal xOffset = 0;
QRectF rangeWindow = m_area->rangeWindow();
if (rangeWindow.isValid())
{
areaWidth = rangeWindow.width();
xOffset = rangeWindow.x();
}
pt.setX(xOffset + SCALE(qreal(value), qreal(0), qreal(255),
qreal(0), areaWidth));
m_lastPos.setX(value);
updatePosition();
}
else
{
if (m_efx->isRunning() == false)
return;

m_hRangeSlider->setMinimumValue(value);
slotRangeValueChanged();
return;
}
}
else if (checkInputSource(universe, pagedCh, value, sender(), panFineInputSourceId))
{
if (m_efx == NULL)
{
m_lastPos.setWidth(value);
updatePosition();
}
}
else if (checkInputSource(universe, pagedCh, value, sender(), tiltInputSourceId))
{
if (m_efx == NULL)
{
qreal yOffset = 0;
qreal areaHeight = MAX_VALUE;
QRectF rangeWindow = m_area->rangeWindow();
if (rangeWindow.isValid())
{
areaHeight = rangeWindow.height();
yOffset = rangeWindow.y();
}
if (invertedAppearance() == false)
pt.setY(yOffset + SCALE(qreal(value), qreal(0), qreal(255),
qreal(0), areaHeight));
else
pt.setY(yOffset + SCALE(qreal(value), qreal(255), qreal(0),
qreal(0), areaHeight));
m_lastPos.setY(value);
updatePosition();
}
else
{
if (m_efx->isRunning() == false)
return;

m_vRangeSlider->setMinimumValue(value);
slotRangeValueChanged();
return;
}
}
else if (checkInputSource(universe, pagedCh, value, sender(), tiltFineInputSourceId))
{
if (m_efx == NULL)
{
m_lastPos.setHeight(value);
updatePosition();
}
}
else if (checkInputSource(universe, pagedCh, value, sender(), widthInputSourceId))
Expand All @@ -1019,7 +1050,6 @@ void VCXYPad::slotInputValueChanged(quint32 universe, quint32 channel,
m_hRangeSlider->setMaximumValue(value);
slotRangeValueChanged();
}
return;
}
else if (checkInputSource(universe, pagedCh, value, sender(), heightInputSourceId))
{
Expand All @@ -1028,7 +1058,6 @@ void VCXYPad::slotInputValueChanged(quint32 universe, quint32 channel,
m_vRangeSlider->setMaximumValue(value);
slotRangeValueChanged();
}
return;
}
else
{
Expand All @@ -1048,11 +1077,6 @@ void VCXYPad::slotInputValueChanged(quint32 universe, quint32 channel,
}
}
}

m_inputValueChanged = true;

m_area->setPosition(pt);
m_area->update();
}

void VCXYPad::slotKeyPressed(const QKeySequence &keySequence)
Expand Down
24 changes: 16 additions & 8 deletions ui/src/virtualconsole/vcxypad.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ class VCXYPad : public VCWidget, public DMXSource
static const quint8 tiltInputSourceId;
static const quint8 widthInputSourceId;
static const quint8 heightInputSourceId;
static const quint8 panFineInputSourceId;
static const quint8 tiltFineInputSourceId;

/*************************************************************************
* Initialization
Expand All @@ -100,16 +102,16 @@ class VCXYPad : public VCWidget, public DMXSource
void enableWidgetUI(bool enable);

private:
QVBoxLayout* m_mainVbox; // main vertical layout
QHBoxLayout* m_padBox; // box containing sliders and XYPad
QVBoxLayout* m_lvbox; // left vertical box (vertical ctkSlider)
QVBoxLayout* m_cvbox; // center vertical box (horizontal ctkSlider + XYPad + horizontal slider)
QVBoxLayout* m_rvbox; // right vertical box (vertical slider)
QSlider* m_vSlider; // tilt slider
QSlider* m_hSlider; // pan slider
QVBoxLayout *m_mainVbox; // main vertical layout
QHBoxLayout *m_padBox; // box containing sliders and XYPad
QVBoxLayout *m_lvbox; // left vertical box (vertical ctkSlider)
QVBoxLayout *m_cvbox; // center vertical box (horizontal ctkSlider + XYPad + horizontal slider)
QVBoxLayout *m_rvbox; // right vertical box (vertical slider)
QSlider *m_vSlider; // tilt slider
QSlider *m_hSlider; // pan slider
ctkRangeSlider *m_vRangeSlider; // range window height control
ctkRangeSlider *m_hRangeSlider; // range window width control
VCXYPadArea* m_area;
VCXYPadArea *m_area;
FlowLayout *m_presetsLayout;

/*************************************************************************
Expand Down Expand Up @@ -242,11 +244,17 @@ protected slots:
public:
void updateFeedback();

protected:
void updatePosition();

protected slots:
/** Called when an external input device produces input data */
void slotInputValueChanged(quint32 universe, quint32 channel, uchar value);
void slotKeyPressed(const QKeySequence& keySequence);

private:
QRect m_lastPos;

/*************************************************************************
* QLC+ mode
*************************************************************************/
Expand Down
80 changes: 76 additions & 4 deletions ui/src/virtualconsole/vcxypadproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,19 @@ VCXYPadProperties::VCXYPadProperties(VCXYPad* xypad, Doc* doc)
connect(m_panInputWidget, SIGNAL(inputValueChanged(quint32,quint32)),
this, SLOT(slotPanInputValueChanged(quint32,quint32)));

m_panFineInputWidget = new InputSelectionWidget(m_doc, this);
m_panFineInputWidget->setTitle(tr("Pan Fine"));
m_panFineInputWidget->setKeyInputVisibility(false);
m_panFineInputWidget->setInputSource(m_xypad->inputSource(VCXYPad::panFineInputSourceId));
m_panFineInputWidget->setWidgetPage(m_xypad->page());
m_panFineInputWidget->emitOddValues(true);
m_panFineInputWidget->show();
m_extFineInputLayout->addWidget(m_panFineInputWidget);
connect(m_panFineInputWidget, SIGNAL(autoDetectToggled(bool)),
this, SLOT(slotPanFineAutoDetectToggled(bool)));
connect(m_panFineInputWidget, SIGNAL(inputValueChanged(quint32,quint32)),
this, SLOT(slotPanFineInputValueChanged(quint32,quint32)));

m_tiltInputWidget = new InputSelectionWidget(m_doc, this);
m_tiltInputWidget->setTitle(tr("Tilt / Vertical Axis"));
m_tiltInputWidget->setKeyInputVisibility(false);
Expand All @@ -106,6 +119,19 @@ VCXYPadProperties::VCXYPadProperties(VCXYPad* xypad, Doc* doc)
connect(m_tiltInputWidget, SIGNAL(inputValueChanged(quint32,quint32)),
this, SLOT(slotTiltInputValueChanged(quint32,quint32)));

m_tiltFineInputWidget = new InputSelectionWidget(m_doc, this);
m_tiltFineInputWidget->setTitle(tr("Tilt Fine"));
m_tiltFineInputWidget->setKeyInputVisibility(false);
m_tiltFineInputWidget->setInputSource(m_xypad->inputSource(VCXYPad::tiltFineInputSourceId));
m_tiltFineInputWidget->setWidgetPage(m_xypad->page());
m_tiltFineInputWidget->emitOddValues(true);
m_tiltFineInputWidget->show();
m_extFineInputLayout->addWidget(m_tiltFineInputWidget);
connect(m_tiltFineInputWidget, SIGNAL(autoDetectToggled(bool)),
this, SLOT(slotTiltFineAutoDetectToggled(bool)));
connect(m_tiltFineInputWidget, SIGNAL(inputValueChanged(quint32,quint32)),
this, SLOT(slotTiltFineInputValueChanged(quint32,quint32)));

m_widthInputWidget = new InputSelectionWidget(m_doc, this);
m_widthInputWidget->setTitle(tr("Width"));
m_widthInputWidget->setKeyInputVisibility(false);
Expand Down Expand Up @@ -432,10 +458,26 @@ void VCXYPadProperties::slotDMXRadioChecked()
* Input page
****************************************************************************/

void VCXYPadProperties::slotPanAutoDetectToggled(bool toggled)
void VCXYPadProperties::stopAutodetection(quint8 sourceId)
{
if (toggled == true && m_tiltInputWidget->isAutoDetecting())
if (sourceId != VCXYPad::panInputSourceId)
m_panInputWidget->stopAutoDetection();
if (sourceId != VCXYPad::panFineInputSourceId)
m_panFineInputWidget->stopAutoDetection();
if (sourceId != VCXYPad::tiltInputSourceId)
m_tiltInputWidget->stopAutoDetection();
if (sourceId != VCXYPad::tiltFineInputSourceId)
m_tiltFineInputWidget->stopAutoDetection();
if (sourceId != VCXYPad::widthInputSourceId)
m_widthInputWidget->stopAutoDetection();
if (sourceId != VCXYPad::heightInputSourceId)
m_heightInputWidget->stopAutoDetection();
}

void VCXYPadProperties::slotPanAutoDetectToggled(bool toggled)
{
if (toggled == true)
stopAutodetection(VCXYPad::panInputSourceId);
}

void VCXYPadProperties::slotPanInputValueChanged(quint32 uni, quint32 ch)
Expand All @@ -446,10 +488,24 @@ void VCXYPadProperties::slotPanInputValueChanged(quint32 uni, quint32 ch)
QSharedPointer<QLCInputSource>(new QLCInputSource(uni, ch)));
}

void VCXYPadProperties::slotPanFineAutoDetectToggled(bool toggled)
{
if (toggled == true)
stopAutodetection(VCXYPad::panFineInputSourceId);
}

void VCXYPadProperties::slotPanFineInputValueChanged(quint32 uni, quint32 ch)
{
QSharedPointer<QLCInputSource> tmpSource = m_panFineInputWidget->inputSource();
if (tmpSource->universe() != uni || tmpSource->channel() != ch)
m_tiltFineInputWidget->setInputSource(
QSharedPointer<QLCInputSource>(new QLCInputSource(uni, ch)));
}

void VCXYPadProperties::slotTiltAutoDetectToggled(bool toggled)
{
if (toggled == true && m_panInputWidget->isAutoDetecting())
m_panInputWidget->stopAutoDetection();
if (toggled == true)
stopAutodetection(VCXYPad::tiltInputSourceId);
}

void VCXYPadProperties::slotTiltInputValueChanged(quint32 uni, quint32 ch)
Expand All @@ -460,6 +516,20 @@ void VCXYPadProperties::slotTiltInputValueChanged(quint32 uni, quint32 ch)
QSharedPointer<QLCInputSource>(new QLCInputSource(uni, ch)));
}

void VCXYPadProperties::slotTiltFineAutoDetectToggled(bool toggled)
{
if (toggled == true)
stopAutodetection(VCXYPad::tiltFineInputSourceId);
}

void VCXYPadProperties::slotTiltFineInputValueChanged(quint32 uni, quint32 ch)
{
QSharedPointer<QLCInputSource> tmpSource = m_tiltFineInputWidget->inputSource();
if (tmpSource->universe() != uni || tmpSource->channel() != ch)
m_panFineInputWidget->setInputSource(
QSharedPointer<QLCInputSource>(new QLCInputSource(uni, ch)));
}

void VCXYPadProperties::writeDMX(MasterTimer *timer, QList<Universe *> universes)
{
Q_UNUSED(timer);
Expand Down Expand Up @@ -933,7 +1003,9 @@ void VCXYPadProperties::accept()
m_xypad->clearFixtures();
m_xypad->setCaption(m_nameEdit->text());
m_xypad->setInputSource(m_panInputWidget->inputSource(), VCXYPad::panInputSourceId);
m_xypad->setInputSource(m_panFineInputWidget->inputSource(), VCXYPad::panFineInputSourceId);
m_xypad->setInputSource(m_tiltInputWidget->inputSource(), VCXYPad::tiltInputSourceId);
m_xypad->setInputSource(m_tiltFineInputWidget->inputSource(), VCXYPad::tiltFineInputSourceId);
m_xypad->setInputSource(m_widthInputWidget->inputSource(), VCXYPad::widthInputSourceId);
m_xypad->setInputSource(m_heightInputWidget->inputSource(), VCXYPad::heightInputSourceId);
if (m_YNormalRadio->isChecked())
Expand Down
8 changes: 8 additions & 0 deletions ui/src/virtualconsole/vcxypadproperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ class VCXYPadProperties : public QDialog, public Ui_VCXYPadProperties, public DM
VCXYPad *m_xypad;
Doc *m_doc;
InputSelectionWidget *m_panInputWidget;
InputSelectionWidget *m_panFineInputWidget;
InputSelectionWidget *m_tiltInputWidget;
InputSelectionWidget *m_tiltFineInputWidget;
InputSelectionWidget *m_widthInputWidget;
InputSelectionWidget *m_heightInputWidget;

Expand All @@ -69,6 +71,8 @@ class VCXYPadProperties : public QDialog, public Ui_VCXYPadProperties, public DM
void updateFixtureItem(QTreeWidgetItem* item, const VCXYPadFixture& fxi);
void removeFixtureItem(GroupHead const & head);

void stopAutodetection(quint8 sourceId);

private slots:
void slotAddClicked();
void slotRemoveClicked();
Expand All @@ -85,8 +89,12 @@ private slots:
private slots:
void slotPanAutoDetectToggled(bool toggled);
void slotPanInputValueChanged(quint32 uni, quint32 ch);
void slotPanFineAutoDetectToggled(bool toggled);
void slotPanFineInputValueChanged(quint32 uni, quint32 ch);
void slotTiltAutoDetectToggled(bool toggled);
void slotTiltInputValueChanged(quint32 uni, quint32 ch);
void slotTiltFineAutoDetectToggled(bool toggled);
void slotTiltFineInputValueChanged(quint32 uni, quint32 ch);

/********************************************************************
* Presets
Expand Down
Loading

0 comments on commit 3af6ff3

Please sign in to comment.