Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Palette & Fanning #1203

Merged
merged 28 commits into from
Nov 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f9315d9
qmlui: handle enabled property in labels
mcallegari Oct 9, 2019
2e6d9fc
qmlui: move position helper into Fixture class
mcallegari Oct 9, 2019
7902c79
qmlui: started to add palettes
mcallegari Oct 9, 2019
4a14feb
qmlui: replace some more hardcoded color with UISettings
mcallegari Oct 10, 2019
5857b5e
qmlui: more work on palettes
mcallegari Oct 10, 2019
893dfb0
engine: QLCPalette iconResource method and code style
mcallegari Oct 13, 2019
9df0b06
engine: Scene now considers fixture groups and palettes
mcallegari Oct 13, 2019
c455c5e
qmlui: changes to Scene Editor to consider palettes and fixture groups
mcallegari Oct 13, 2019
6b64752
qmlui: fix kiosk mode not handled properly
mcallegari Oct 13, 2019
d1709d4
engine: allow pan/tilt-only palettes
mcallegari Oct 14, 2019
9c9c5c0
engine: include fanning into palettes + start testing
mcallegari Oct 15, 2019
019b28a
qmlui: fix application exit programmatically
mcallegari Oct 16, 2019
c8345fd
engine: more testing of Doc and QLCFile
mcallegari Oct 16, 2019
12677d9
engine: more testing on QLCPalette
mcallegari Oct 16, 2019
d0a7323
qmlui: update palette list on project load
mcallegari Oct 16, 2019
6da0ad5
resources: add fanning icons
mcallegari Oct 17, 2019
639493e
qmlui: move position helper in context manager
mcallegari Oct 17, 2019
45f91f4
qmlui: remove debug + cosmetics
mcallegari Oct 17, 2019
b8f0827
qmlui: add dedicated panel for fanning settings
mcallegari Oct 17, 2019
2921fce
qmlui: move context property export inside their classes
mcallegari Oct 18, 2019
fea9ee8
qmlui: handle key modifier on rectangle selection
mcallegari Oct 18, 2019
1e05379
qmlui: add also fanning layout
mcallegari Oct 18, 2019
1d31552
Merge branch 'master' into goodies
mcallegari Nov 2, 2019
ae4a948
qmlui: currentValue can no longer be used in 5.14
mcallegari Nov 17, 2019
c866a3f
qmlui: started to implement fanning curve maths
mcallegari Nov 17, 2019
2de5bdc
engine: more fanning handling
mcallegari Nov 20, 2019
c968382
qmlui: color fanning too
mcallegari Nov 25, 2019
3b9d1fa
engine: fix sine fanning factor calculation
mcallegari Nov 25, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
111 changes: 104 additions & 7 deletions engine/src/doc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ Doc::Doc(QObject* parent, int universes)
, m_latestFixtureId(0)
, m_latestFixtureGroupId(0)
, m_latestChannelsGroupId(0)
, m_latestPaletteId(0)
, m_latestFunctionId(0)
, m_startupFunctionId(Function::invalidId())
{
Expand Down Expand Up @@ -134,7 +135,16 @@ void Doc::clearContents()
delete func;
}

// Delete all channels groups
// Delete all palettes
QListIterator <quint32> palIt(m_palettes.keys());
while (palIt.hasNext() == true)
{
QLCPalette *palette = m_palettes.take(palIt.next());
emit paletteRemoved(palette->id());
delete palette;
}

// Delete all channel groups
QListIterator <quint32> grpchans(m_channelsGroups.keys());
while (grpchans.hasNext() == true)
{
Expand Down Expand Up @@ -170,6 +180,7 @@ void Doc::clearContents()
m_latestFixtureId = 0;
m_latestFixtureGroupId = 0;
m_latestChannelsGroupId = 0;
m_latestPaletteId = 0;
m_addresses.clear();
m_loadStatus = Cleared;

Expand Down Expand Up @@ -890,6 +901,79 @@ quint32 Doc::createChannelsGroupId()
return m_latestChannelsGroupId;
}

/*********************************************************************
* Palettes
*********************************************************************/

bool Doc::addPalette(QLCPalette *palette, quint32 id)
{
Q_ASSERT(palette != NULL);

// No ID given, this method can assign one
if (id == QLCPalette::invalidId())
id = createPaletteId();

if (m_palettes.contains(id) == true || id == QLCPalette::invalidId())
{
qWarning() << Q_FUNC_INFO << "a palette with ID" << id << "already exists!";
return false;
}
else
{
palette->setID(id);
m_palettes[id] = palette;

emit paletteAdded(id);
setModified();
}

return true;
}

bool Doc::deletePalette(quint32 id)
{
if (m_palettes.contains(id) == true)
{
QLCPalette *palette = m_palettes.take(id);
Q_ASSERT(palette != NULL);

emit paletteRemoved(id);
setModified();
delete palette;

return true;
}
else
{
qWarning() << Q_FUNC_INFO << "No palette with id" << id;
return false;
}
}

QLCPalette *Doc::palette(quint32 id) const
{
if (m_palettes.contains(id) == true)
return m_palettes[id];
else
return NULL;
}

QList<QLCPalette *> Doc::palettes() const
{
return m_palettes.values();
}

quint32 Doc::createPaletteId()
{
while (m_palettes.contains(m_latestPaletteId) == true ||
m_latestPaletteId == FixtureGroup::invalidId())
{
m_latestPaletteId++;
}

return m_latestPaletteId;
}

/*****************************************************************************
* Functions
*****************************************************************************/
Expand Down Expand Up @@ -1161,6 +1245,11 @@ bool Doc::loadXML(QXmlStreamReader &doc)
{
ChannelsGroup::loader(doc, this);
}
else if (doc.name() == KXMLQLCPalette)
{
QLCPalette::loader(doc, this);
doc.skipCurrentElement();
}
else if (doc.name() == KXMLQLCFunction)
{
//qDebug() << doc.attributes().value("Name").toString();
Expand Down Expand Up @@ -1200,18 +1289,17 @@ bool Doc::saveXML(QXmlStreamWriter *doc)

/* Create the master Engine node */
doc->writeStartElement(KXMLQLCEngine);

if (startupFunction() != Function::invalidId())
{
doc->writeAttribute(KXMLQLCStartupFunction, QString::number(startupFunction()));
}

m_ioMap->saveXML(doc);

/* Write fixtures into an XML document */
QListIterator <Fixture*> fxit(fixtures());
while (fxit.hasNext() == true)
{
Fixture* fxi(fxit.next());
Fixture *fxi(fxit.next());
Q_ASSERT(fxi != NULL);
fxi->saveXML(doc);
}
Expand All @@ -1220,7 +1308,7 @@ bool Doc::saveXML(QXmlStreamWriter *doc)
QListIterator <FixtureGroup*> grpit(fixtureGroups());
while (grpit.hasNext() == true)
{
FixtureGroup* grp(grpit.next());
FixtureGroup *grp(grpit.next());
Q_ASSERT(grp != NULL);
grp->saveXML(doc);
}
Expand All @@ -1229,16 +1317,25 @@ bool Doc::saveXML(QXmlStreamWriter *doc)
QListIterator <ChannelsGroup*> chanGroups(channelsGroups());
while (chanGroups.hasNext() == true)
{
ChannelsGroup* grp(chanGroups.next());
ChannelsGroup *grp(chanGroups.next());
Q_ASSERT(grp != NULL);
grp->saveXML(doc);
}

/* Write palettes into an XML document */
QListIterator <QLCPalette*> paletteIt(palettes());
while (paletteIt.hasNext() == true)
{
QLCPalette *palette(paletteIt.next());
Q_ASSERT(palette != NULL);
palette->saveXML(doc);
}

/* Write functions into an XML document */
QListIterator <Function*> funcit(functions());
while (funcit.hasNext() == true)
{
Function* func(funcit.next());
Function *func(funcit.next());
Q_ASSERT(func != NULL);
func->saveXML(doc);
}
Expand Down
42 changes: 40 additions & 2 deletions engine/src/doc.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "fixturegroup.h"
#include "qlcclipboard.h"
#include "mastertimer.h"
#include "qlcpalette.h"
#include "function.h"
#include "fixture.h"

Expand Down Expand Up @@ -391,7 +392,7 @@ private slots:
*********************************************************************/
public:
/** Add a new channels group. Doc takes ownership of the group. */
bool addChannelsGroup(ChannelsGroup *grp, quint32 id = FixtureGroup::invalidId());
bool addChannelsGroup(ChannelsGroup *grp, quint32 id = ChannelsGroup::invalidId());

/**
* Remove and delete a channels group.
Expand Down Expand Up @@ -427,9 +428,46 @@ private slots:
* in the Fixture Manager panel */
QList <quint32> m_orderedGroups;

/** Latest assigned fixture group ID */
/** Latest assigned channel group ID */
quint32 m_latestChannelsGroupId;

/*********************************************************************
* Palettes
*********************************************************************/
public:
/** Add a new palette. Doc takes ownership of it */
bool addPalette(QLCPalette *palette, quint32 id = QLCPalette::invalidId());

/**
* Remove and delete a palette.
* The Palette pointer is invalid after this call.
*/
bool deletePalette(quint32 id);

/** Get a palette by id */
QLCPalette *palette(quint32 id) const;

/** Get a list of Doc's palettes */
QList <QLCPalette*> palettes() const;

private:
/** Create a new palette ID */
quint32 createPaletteId();

signals:
/** Inform the listeners that a new palette has been added */
void paletteAdded(quint32 id);

/** Inform the listeners that a new palette has been removed */
void paletteRemoved(quint32 id);

private:
/** Palettes */
QMap <quint32,QLCPalette*> m_palettes;

/** Latest assigned palette ID */
quint32 m_latestPaletteId;

/*********************************************************************
* Functions
*********************************************************************/
Expand Down
103 changes: 90 additions & 13 deletions engine/src/fixture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include <QString>
#include <QtMath>
#include <QDebug>

#include "qlcfixturedefcache.h"
Expand Down Expand Up @@ -308,6 +309,82 @@ QVector <quint32> Fixture::cmyChannels(int head) const
return m_fixtureMode->heads().at(head).cmyChannels();
}

QList<SceneValue> Fixture::positionToValues(int type, int degrees) const
{
QList<SceneValue> posList;
// cache a list of channels processed, to avoid duplicates
QList<quint32> chDone;

if (m_fixtureMode == NULL)
return posList;

QLCPhysical phy = fixtureMode()->physical();
float maxDegrees;
if (type == QLCChannel::Pan)
{
maxDegrees = phy.focusPanMax();
if (maxDegrees == 0) maxDegrees = 360;

for (int i = 0; i < heads(); i++)
{
quint32 panMSB = channelNumber(QLCChannel::Pan, QLCChannel::MSB, i);
if (panMSB == QLCChannel::invalid() || chDone.contains(panMSB))
continue;

float dmxValue = (float)(degrees * UCHAR_MAX) / maxDegrees;
posList.append(SceneValue(id(), panMSB, static_cast<uchar>(qFloor(dmxValue))));

qDebug() << "[getFixturePosition] Pan MSB:" << dmxValue;

quint32 panLSB = channelNumber(QLCChannel::Pan, QLCChannel::LSB, i);

if (panLSB != QLCChannel::invalid())
{
float lsbDegrees = (float)maxDegrees / (float)UCHAR_MAX;
float lsbValue = (float)((dmxValue - qFloor(dmxValue)) * UCHAR_MAX) / lsbDegrees;
posList.append(SceneValue(id(), panLSB, static_cast<uchar>(lsbValue)));

qDebug() << "[getFixturePosition] Pan LSB:" << lsbValue;
}

chDone.append(panMSB);
}
}
else if (type == QLCChannel::Tilt)
{
maxDegrees = phy.focusTiltMax();
if (maxDegrees == 0) maxDegrees = 270;

for (int i = 0; i < heads(); i++)
{
quint32 tiltMSB = channelNumber(QLCChannel::Tilt, QLCChannel::MSB, i);
if (tiltMSB == QLCChannel::invalid() || chDone.contains(tiltMSB))
continue;

float dmxValue = (float)(degrees * UCHAR_MAX) / maxDegrees;
posList.append(SceneValue(id(), tiltMSB, static_cast<uchar>(qFloor(dmxValue))));

qDebug() << "[getFixturePosition] Tilt MSB:" << dmxValue;

quint32 tiltLSB = channelNumber(QLCChannel::Tilt, QLCChannel::LSB, i);

if (tiltLSB != QLCChannel::invalid())
{
float lsbDegrees = (float)maxDegrees / (float)UCHAR_MAX;
float lsbValue = (float)((dmxValue - qFloor(dmxValue)) * UCHAR_MAX) / lsbDegrees;
posList.append(SceneValue(id(), tiltLSB, static_cast<uchar>(lsbValue)));

qDebug() << "[getFixturePosition] Tilt LSB:" << lsbValue;
}

chDone.append(tiltMSB);
}

}

return posList;
}

void Fixture::setExcludeFadeChannels(QList<int> indices)
{
if (indices.count() > (int)channels())
Expand Down Expand Up @@ -584,19 +661,19 @@ QString Fixture::iconResource(bool svg) const

switch(type())
{
case QLCFixtureDef::ColorChanger: return QString("%1:/fixture.%2").arg(prefix).arg(ext); break;
case QLCFixtureDef::Dimmer: return QString("%1:/dimmer.%2").arg(prefix).arg(ext); break;
case QLCFixtureDef::Effect: return QString("%1:/effect.%2").arg(prefix).arg(ext); break;
case QLCFixtureDef::Fan: return QString("%1:/fan.%2").arg(prefix).arg(ext); break;
case QLCFixtureDef::Flower: return QString("%1:/flower.%2").arg(prefix).arg(ext); break;
case QLCFixtureDef::Hazer: return QString("%1:/hazer.%2").arg(prefix).arg(ext); break;
case QLCFixtureDef::Laser: return QString("%1:/laser.%2").arg(prefix).arg(ext); break;
case QLCFixtureDef::MovingHead: return QString("%1:/movinghead.%2").arg(prefix).arg(ext); break;
case QLCFixtureDef::Scanner: return QString("%1:/scanner.%2").arg(prefix).arg(ext); break;
case QLCFixtureDef::Smoke: return QString("%1:/smoke.%2").arg(prefix).arg(ext); break;
case QLCFixtureDef::Strobe: return QString("%1:/strobe.%2").arg(prefix).arg(ext); break;
case QLCFixtureDef::LEDBarBeams: return QString("%1:/ledbar_beams.%2").arg(prefix).arg(ext); break;
case QLCFixtureDef::LEDBarPixels: return QString("%1:/ledbar_pixels.%2").arg(prefix).arg(ext); break;
case QLCFixtureDef::ColorChanger: return QString("%1:/fixture.%2").arg(prefix).arg(ext);
case QLCFixtureDef::Dimmer: return QString("%1:/dimmer.%2").arg(prefix).arg(ext);
case QLCFixtureDef::Effect: return QString("%1:/effect.%2").arg(prefix).arg(ext);
case QLCFixtureDef::Fan: return QString("%1:/fan.%2").arg(prefix).arg(ext);
case QLCFixtureDef::Flower: return QString("%1:/flower.%2").arg(prefix).arg(ext);
case QLCFixtureDef::Hazer: return QString("%1:/hazer.%2").arg(prefix).arg(ext);
case QLCFixtureDef::Laser: return QString("%1:/laser.%2").arg(prefix).arg(ext);
case QLCFixtureDef::MovingHead: return QString("%1:/movinghead.%2").arg(prefix).arg(ext);
case QLCFixtureDef::Scanner: return QString("%1:/scanner.%2").arg(prefix).arg(ext);
case QLCFixtureDef::Smoke: return QString("%1:/smoke.%2").arg(prefix).arg(ext);
case QLCFixtureDef::Strobe: return QString("%1:/strobe.%2").arg(prefix).arg(ext);
case QLCFixtureDef::LEDBarBeams: return QString("%1:/ledbar_beams.%2").arg(prefix).arg(ext);
case QLCFixtureDef::LEDBarPixels: return QString("%1:/ledbar_pixels.%2").arg(prefix).arg(ext);
default: break;
}

Expand Down
5 changes: 5 additions & 0 deletions engine/src/fixture.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class ChannelModifier;
class QLCFixtureMode;
class QLCFixtureHead;
class FixtureConsole;
class SceneValue;
class Doc;

/** @addtogroup engine Engine
Expand Down Expand Up @@ -274,6 +275,10 @@ class Fixture : public QObject
/** @see QLCFixtureHead */
QVector <quint32> cmyChannels(int head = 0) const;

/** Return a list of values based on the given position degrees
* and the provided type (Pan or Tilt) */
QList<SceneValue> positionToValues(int type, int degrees) const;

/** Set a list of channel indices to exclude from fade transitions */
void setExcludeFadeChannels(QList<int> indices);

Expand Down
1 change: 0 additions & 1 deletion engine/src/fixturegroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include "fixture.h"
#include "doc.h"

#define KXMLQLCFixtureGroupID "ID"
#define KXMLQLCFixtureGroupHead "Head"
#define KXMLQLCFixtureGroupSize "Size"
#define KXMLQLCFixtureGroupName "Name"
Expand Down