Skip to content

Commit

Permalink
Merge branch 'marcusbirkin-feature/#163' into 2.1-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
docsteer committed Dec 4, 2018
2 parents ad7e17d + 540d913 commit 01e938a
Show file tree
Hide file tree
Showing 16 changed files with 3,572 additions and 2,849 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,5 @@ install/linux/build/
install/linux/fpm-checkout/

translations/sACNView\.ts

libs/\.gclient_entries
Binary file added res/ledgreen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added res/ledred.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions res/resources.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
<file>spin_up_dark.png</file>
<file>capture_playback.png</file>
<file>clear.png</file>
<file>ledgreen.png</file>
<file>ledred.png</file>
</qresource>
<qresource prefix="/">
<file>Logo.png</file>
Expand Down
6 changes: 4 additions & 2 deletions sACNView.pro
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ SOURCES += src/main.cpp\
src/theme/darkstyle.cpp \
src/ipc.cpp \
src/sacn/sacndiscovery.cpp \
src/sacn/sacndiscoveredsourcelistmodel.cpp
src/sacn/sacndiscoveredsourcelistmodel.cpp \
src/clssnapshot.cpp

HEADERS += src/mdimainwindow.h \
src/scopewindow.h \
Expand Down Expand Up @@ -167,7 +168,8 @@ HEADERS += src/mdimainwindow.h \
src/ipc.h \
src/qt56.h \
src/sacn/sacndiscovery.h \
src/sacn/sacndiscoveredsourcelistmodel.h
src/sacn/sacndiscoveredsourcelistmodel.h \
src/clssnapshot.h

FORMS += ui/mdimainwindow.ui \
ui/scopewindow.ui \
Expand Down
232 changes: 232 additions & 0 deletions src/clssnapshot.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
#include "clssnapshot.h"
#include <QPainter>
#include <QHBoxLayout>

clsSnapshot::clsSnapshot(quint16 universe, CID cid, QString name, QWidget *parent) : QWidget(parent),
m_universe(universe),
m_priority(DEFAULT_SACN_PRIORITY),
m_cid(cid),
m_sbUniverse(new QSpinBox(this)),
m_sbPriority(new QSpinBox(this)),
m_btnPlayback(new QToolButton(this)),
m_lblStatus(new QLabel(this)),
m_controlWidget(new QWidget(this)),
m_sender(Q_NULLPTR),
m_listener(Q_NULLPTR),
m_camera(new QSound(":/sound/camera.wav", this)),
m_backgroundMatches(false)
{
m_sbUniverse->setMinimum(MIN_SACN_UNIVERSE);
m_sbUniverse->setMaximum(MAX_SACN_UNIVERSE);
m_sbUniverse->setValue(m_universe);
connect(m_sbUniverse, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, [this](int value) { setUniverse(value); } );

m_sbPriority->setMinimum(MIN_SACN_PRIORITY);
m_sbPriority->setMaximum(MAX_SACN_PRIORITY);
m_sbPriority->setValue(m_priority);
connect(m_sbPriority, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, [this](int value) { setPriority(value); } );

connect(m_btnPlayback, SIGNAL(clicked(bool)), this, SLOT(btnEnableClicked(bool)));
updateIcons();

m_sender = sACNManager::getInstance()->getSender(m_universe, m_cid);
m_sender->setName(name);
connect(m_sender.data(), &sACNSentUniverse::sendingTimeout, [this]() { emit senderTimedOut();} );
setUniverse(m_universe);

m_btnPlayback->setAutoRaise(true);
m_controlWidget->setAutoFillBackground(true);
QHBoxLayout *layout = new QHBoxLayout(m_controlWidget);
layout->setMargin(0);
layout->setContentsMargins(0,0,0,0);
layout->addStretch();
layout->addWidget(m_btnPlayback);
layout->addWidget(m_lblStatus);
layout->addStretch();
}

clsSnapshot::~clsSnapshot() {
}

void clsSnapshot::setUniverse(quint16 universe) {
Q_ASSERT(universe >= MIN_SACN_UNIVERSE);
Q_ASSERT(universe <= MAX_SACN_UNIVERSE);

m_universe = universe;

m_sbUniverse->setValue(m_universe);

if (m_listener)
m_listener->deleteLater();
m_listener = sACNManager::getInstance()->getListener(m_universe);
connect(m_listener.data(), SIGNAL(levelsChanged()), this, SLOT(levelsChanged()));
connect(m_listener.data(), SIGNAL(sourceFound()), this, SLOT(levelsChanged()));
connect(m_listener.data(), SIGNAL(sourceLost()), this, SLOT(levelsChanged()));
connect(m_listener.data(), SIGNAL(sourceResumed()), this, SLOT(levelsChanged()));

m_sender->setUniverse(m_universe);
}

void clsSnapshot::setPriority(quint8 priority) {
Q_ASSERT(priority >= MIN_SACN_PRIORITY);
Q_ASSERT(priority <= MAX_SACN_PRIORITY);

m_priority = priority;

m_sbPriority->setValue(m_priority);

m_sender->setPerSourcePriority(m_priority);
}

void clsSnapshot::updateIcons() {
if (!hasData())
m_btnPlayback->setIcon(icons[ICON_SNAPSHOT]);
else if (m_sender->isSending())
{
m_btnPlayback->setIcon(icons[ICON_PAUSE]);
}
else
m_btnPlayback->setIcon(icons[ICON_PLAY]);

if(!hasData())
{
m_lblStatus->setPixmap(statusIcons[STATUSICON_NONE]);
m_lblStatus->setToolTip(statusIconTooltips[STATUSICON_NONE]);
}
else if(!m_sender->isSending())
{
m_lblStatus->setPixmap(statusIcons[STATUSICON_NONE]);
m_lblStatus->setToolTip(statusIconTooltips[STATUSICON_NONE]);
}
else if(m_backgroundMatches)
{
m_lblStatus->setPixmap(statusIcons[STATUSICON_MATCHING]);
m_lblStatus->setToolTip(statusIconTooltips[STATUSICON_MATCHING]);
}
else
{
m_lblStatus->setPixmap(statusIcons[STATUSICON_NOTMATCHING]);
m_lblStatus->setToolTip(statusIconTooltips[STATUSICON_NOTMATCHING]);
}

// Enabled status
m_sbUniverse->setEnabled(!isPlaying());
m_sbPriority->setEnabled(!isPlaying());
}

void clsSnapshot::takeSnapshot() {
m_levelData.clear();

// Copy current merged universe
for(int addr=0; addr<MAX_DMX_ADDRESS; addr++)
{
if (m_listener->mergedLevels().at(addr).level == -1)
m_levelData.append(static_cast<char>(0));
else
m_levelData.append(m_listener->mergedLevels().at(addr).level);
}

updateIcons();

emit snapshotTaken();
}

void clsSnapshot::playSnapshot() {
if (!hasData())
{
updateIcons();
return;
}

m_sender->startSending();
m_sender->setLevel(reinterpret_cast<const quint8*>(m_levelData.constData()), std::min(m_levelData.count(), MAX_DMX_ADDRESS));
updateIcons();
emit senderStarted();
}

void clsSnapshot::stopSnapshot() {
if (!hasData())
{
updateIcons();
return;
}

m_sender->stopSending();
updateIcons();
emit senderStopped();
}

void clsSnapshot::btnEnableClicked(bool value) {
Q_UNUSED(value);
if (!hasData())
{
m_camera->play();
takeSnapshot();
return;
} else if (isPlaying())
stopSnapshot();
else
playSnapshot();
}

void clsSnapshot::levelsChanged()
{
QByteArray background;

int addr = 0;
for (auto merged: m_listener->mergedLevels())
{
int level = 0;
if ((merged.winningSource) && (merged.winningSource->src_cid == m_sender->cid()))
{
// I'm winning....
if (merged.otherSources.isEmpty())
{
//...and the only source
level = merged.level;
} else {
// ...find highest background priority
int priority = 0;
for (auto source: merged.otherSources)
{
if (source->doing_per_channel)
{
if (source->priority_array[addr] > priority)
{
priority = source->priority;
level = source->level_array[addr];
}
} else {
if (source->priority > priority)
{
priority = source->priority;
level = source->level_array[addr];
}
}
}
}
}
else
{
// I'm not winning...
level = merged.level;
}

background.append(level);

if (addr < MAX_DMX_ADDRESS)
addr++;
}

if ((background == m_levelData) != m_backgroundMatches)
{
if (background == m_levelData)
emit snapshotMatches();
else
emit snapshotDiffers();
}

m_backgroundMatches = (background == m_levelData);
updateIcons();
}

106 changes: 106 additions & 0 deletions src/clssnapshot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#ifndef CLSSNAPSHOT_H
#define CLSSNAPSHOT_H

#include <QObject>
#include <QSpinBox>
#include <QToolButton>
#include <QMap>
#include <QSound>
#include <QLabel>
#include "streamingacn.h"
#include "sacnlistener.h"
#include "sacnsender.h"

class clsSnapshot : public QWidget
{
Q_OBJECT
public:
explicit clsSnapshot(quint16 universe, CID cid, QString name, QWidget *parent = nullptr);
~clsSnapshot();

void takeSnapshot();
void playSnapshot();
void stopSnapshot();

bool hasData() { return !m_levelData.isEmpty(); }

bool isPlaying() { return (m_sender ? m_sender->isSending() : false); }

quint16 getUniverse() {return m_universe;}
void setUniverse(quint16 universe);

quint8 getPriority() {return m_priority;}
void setPriority(quint8 priority);

QSpinBox *getSbUniverse() {return m_sbUniverse;}
QSpinBox *getSbPriority() {return m_sbPriority;}
QWidget *getControlWidget() {return m_controlWidget;}

enum e_icons {
ICON_NONE,
ICON_PLAY,
ICON_PAUSE,
ICON_SNAPSHOT,
};

const QMap<e_icons, QIcon> icons{
{ICON_NONE, QIcon()},
{ICON_PLAY, QIcon(":/icons/play.png")},
{ICON_PAUSE, QIcon(":/icons/pause.png")},
{ICON_SNAPSHOT, QIcon(":/icons/snapshot.png")}
};

enum e_statusIcons {
STATUSICON_NONE,
STATUSICON_MATCHING,
STATUSICON_NOTMATCHING
};

const QMap<e_statusIcons, QPixmap> statusIcons{
{STATUSICON_NONE, QPixmap()},
{STATUSICON_MATCHING, QPixmap(":/icons/ledgreen.png")},
{STATUSICON_NOTMATCHING, QPixmap(":/icons/ledred.png")}
};

const QMap<e_statusIcons, QString> statusIconTooltips{
{STATUSICON_NONE, QString()},
{STATUSICON_MATCHING, tr("The snapshot <i>matches</i> the other sources in this universe")},
{STATUSICON_NOTMATCHING, tr("The snapshot <i>does not match</i> the other sources in this universe")}
};

signals:
void senderStarted();
void senderStopped();
void senderTimedOut();
void snapshotTaken();
void snapshotMatches();
void snapshotDiffers();

public slots:

private slots:
void btnEnableClicked(bool value);
void levelsChanged();

private:
void updateIcons();

quint16 m_universe;
quint8 m_priority;
CID m_cid;

QByteArray m_levelData;
QSpinBox* m_sbUniverse;
QSpinBox* m_sbPriority;
QToolButton* m_btnPlayback;
QLabel* m_lblStatus;
QWidget *m_controlWidget;
sACNManager::tSender m_sender;
sACNManager::tListener m_listener;

QSound *m_camera;

bool m_backgroundMatches;
};

#endif // CLSSNAPSHOT_H
4 changes: 3 additions & 1 deletion src/sacn/sacnsender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ void sACNSentUniverse::setHorizontalBar(quint16 index, quint8 level)

void sACNSentUniverse::setName(const QString &name)
{
m_name = name;
auto tmpStr = name.trimmed();
tmpStr.truncate(MAX_SOURCE_NAME_LEN);
m_name = tmpStr;
if(isSending())
{
QByteArray arr = name.toUtf8();
Expand Down
Loading

0 comments on commit 01e938a

Please sign in to comment.