• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mcallegari / qlcplus / 13633248611

03 Mar 2025 02:31PM UTC coverage: 31.871% (+0.4%) from 31.5%
13633248611

push

github

web-flow
actions: add chrpath to profile

14689 of 46089 relevant lines covered (31.87%)

26426.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

69.79
/engine/src/efxfixture.cpp
1
/*
2
  Q Light Controller Plus
3
  efxfixture.cpp
4

5
  Copyright (c) Heikki Junnila
6
                Massimo Callegari
7

8
  Licensed under the Apache License, Version 2.0 (the "License");
9
  you may not use this file except in compliance with the License.
10
  You may obtain a copy of the License at
11

12
      http://www.apache.org/licenses/LICENSE-2.0.txt
13

14
  Unless required by applicable law or agreed to in writing, software
15
  distributed under the License is distributed on an "AS IS" BASIS,
16
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
  See the License for the specific language governing permissions and
18
  limitations under the License.
19
*/
20

21
#include <QXmlStreamReader>
22
#include <QXmlStreamWriter>
23
#include <QDebug>
24
#include <math.h>
25

26
#include "genericfader.h"
27
#include "fadechannel.h"
28
#include "mastertimer.h"
29
#include "efxfixture.h"
30
#include "qlcmacros.h"
31
#include "function.h"
32
#include "universe.h"
33
#include "gradient.h"
34
#include "efx.h"
35
#include "doc.h"
36

37
/*****************************************************************************
38
 * Initialization
39
 *****************************************************************************/
40
QImage EFXFixture::m_rgbGradient = QImage();
41

42
EFXFixture::EFXFixture(const EFX* parent)
54✔
43
    : m_parent(parent)
54✔
44
    , m_head()
54✔
45
    , m_universe(Universe::invalid())
54✔
46
    , m_direction(Function::Forward)
54✔
47
    , m_startOffset(0)
54✔
48
    , m_mode(EFXFixture::PanTilt)
54✔
49

50
    , m_serialNumber(0)
54✔
51
    , m_runTimeDirection(Function::Forward)
54✔
52
    , m_done(false)
54✔
53
    , m_started(false)
54✔
54
    , m_elapsed(0)
54✔
55
    , m_currentAngle(0)
54✔
56

57
    , m_firstMsbChannel(QLCChannel::invalid())
54✔
58
    , m_firstLsbChannel(QLCChannel::invalid())
54✔
59
    , m_secondMsbChannel(QLCChannel::invalid())
54✔
60
    , m_secondLsbChannel(QLCChannel::invalid())
54✔
61
{
62
    Q_ASSERT(parent != NULL);
63

64
    if (m_rgbGradient.isNull ())
54✔
65
        m_rgbGradient = Gradient::getRGBGradient (256, 256);
3✔
66
}
54✔
67

68
void EFXFixture::copyFrom(const EFXFixture* ef)
7✔
69
{
70
    // Don't copy m_parent because it is already assigned in constructor and might
71
    // be different than $ef's
72
    m_head = ef->m_head;
7✔
73
    m_universe = ef->m_universe;
7✔
74
    m_direction = ef->m_direction;
7✔
75
    m_startOffset = ef->m_startOffset;
7✔
76
    m_mode = ef->m_mode;
7✔
77

78
    m_serialNumber = ef->m_serialNumber;
7✔
79
    m_runTimeDirection = ef->m_runTimeDirection;
7✔
80
    m_done = ef->m_done;
7✔
81
    m_started = ef->m_started;
7✔
82
    m_elapsed = ef->m_elapsed;
7✔
83
    m_currentAngle = ef->m_currentAngle;
7✔
84
}
7✔
85

86
EFXFixture::~EFXFixture()
53✔
87
{
88
}
53✔
89

90
/****************************************************************************
91
 * Public properties
92
 ****************************************************************************/
93

94
void EFXFixture::setHead(GroupHead const & head)
44✔
95
{
96
    m_head = head;
44✔
97

98
    Fixture *fxi = doc()->fixture(head.fxi);
44✔
99
    if (fxi == NULL)
44✔
100
        return;
30✔
101

102
    m_universe = fxi->universe();
14✔
103

104
    QList<Mode> modes;
105

106
    if (fxi->channelNumber(QLCChannel::Pan, QLCChannel::MSB, head.head) != QLCChannel::invalid() ||
16✔
107
        fxi->channelNumber(QLCChannel::Tilt, QLCChannel::MSB, head.head) != QLCChannel::invalid())
2✔
108
        modes << PanTilt;
14✔
109

110
    if (fxi->masterIntensityChannel() != QLCChannel::invalid() ||
16✔
111
        fxi->channelNumber(QLCChannel::Intensity, QLCChannel::MSB, head.head) != QLCChannel::invalid())
2✔
112
        modes << Dimmer;
12✔
113

114
    if (fxi->rgbChannels(head.head).size() >= 3)
14✔
115
        modes << RGB;
2✔
116

117
    if (!modes.contains(m_mode))
14✔
118
    {
119
        if (modes.size() > 0)
×
120
            m_mode = modes[0];
×
121
    }
122
}
14✔
123

124
GroupHead const & EFXFixture::head() const
941✔
125
{
126
    return m_head;
941✔
127
}
128

129
void EFXFixture::setDirection(Function::Direction dir)
18✔
130
{
131
    m_direction = dir;
18✔
132
    m_runTimeDirection = dir;
18✔
133
}
18✔
134

135
Function::Direction EFXFixture::direction() const
13✔
136
{
137
    return m_direction;
13✔
138
}
139

140
void EFXFixture::setStartOffset(int startOffset)
5✔
141
{
142
    m_startOffset = CLAMP(startOffset, 0, 359);
5✔
143
}
5✔
144

145
int EFXFixture::startOffset() const
9✔
146
{
147
    return m_startOffset;
9✔
148
}
149

150
void EFXFixture::setMode(Mode mode)
×
151
{
152
    m_mode = mode;
×
153
}
×
154

155
EFXFixture::Mode EFXFixture::mode() const
4✔
156
{
157
    return m_mode;
4✔
158
}
159

160
quint32 EFXFixture::universe()
156✔
161
{
162
    return m_universe;
156✔
163
}
164

165
bool EFXFixture::isValid() const
158✔
166
{
167
    Fixture *fxi = doc()->fixture(head().fxi);
158✔
168

169
    if (fxi == NULL)
158✔
170
        return false;
171
    else if (head().head >= fxi->heads())
156✔
172
        return false;
173
    else if (m_mode == PanTilt &&
156✔
174
             fxi->channelNumber(QLCChannel::Pan, QLCChannel::MSB, head().head) == QLCChannel::invalid() && // Maybe a device can pan OR tilt
156✔
175
             fxi->channelNumber(QLCChannel::Tilt, QLCChannel::MSB, head().head) == QLCChannel::invalid())   // but not both
×
176
        return false;
177
    else if (m_mode == Dimmer &&
×
178
             fxi->masterIntensityChannel() == QLCChannel::invalid() &&
156✔
179
             fxi->channelNumber(QLCChannel::Intensity, QLCChannel::MSB, head().head) == QLCChannel::invalid())
×
180
        return false;
181
    else if (m_mode == RGB && fxi->rgbChannels(head().head).size () == 0)
156✔
182
        return false;
183
    else
184
        return true;
156✔
185
}
186

187
void EFXFixture::durationChanged()
3✔
188
{
189
    // To avoid jumps when changing duration,
190
    // the elapsed time is rescaled to the
191
    // new duration.
192
    m_elapsed = SCALE(float(m_currentAngle),
3✔
193
            float(0), float(M_PI * 2),
194
            float(0), float(m_parent->loopDuration()));
195

196
    // Serial or Asymmetric propagation mode:
197
    // we must substract the offset from the current position
198
    if (timeOffset())
3✔
199
    {
200
        if (m_elapsed < timeOffset())
×
201
            m_elapsed += m_parent->loopDuration();
×
202
        m_elapsed -= timeOffset();
×
203
    }
204
}
3✔
205

206
QStringList EFXFixture::modeList()
×
207
{
208
    Fixture* fxi = doc()->fixture(head().fxi);
×
209
    Q_ASSERT(fxi != NULL);
210

211
    QStringList modes;
212

213
    if (fxi->channelNumber(QLCChannel::Pan, QLCChannel::MSB, head().head) != QLCChannel::invalid() ||
×
214
       fxi->channelNumber(QLCChannel::Tilt, QLCChannel::MSB, head().head) != QLCChannel::invalid())
×
215
        modes << KXMLQLCEFXFixtureModePanTilt;
×
216

217
    if (fxi->masterIntensityChannel() != QLCChannel::invalid() ||
×
218
       fxi->channelNumber(QLCChannel::Intensity, QLCChannel::MSB, head().head) != QLCChannel::invalid())
×
219
        modes << KXMLQLCEFXFixtureModeDimmer;
×
220

221
    if (fxi->rgbChannels(head().head).size() >= 3)
×
222
        modes << KXMLQLCEFXFixtureModeRGB;
×
223

224
    return modes;
×
225
}
226

227
QString EFXFixture::modeToString(Mode mode)
×
228
{
229
    switch (mode)
×
230
    {
231
        default:
×
232
        case PanTilt:
233
            return QString(KXMLQLCEFXFixtureModePanTilt);
×
234
        case Dimmer:
×
235
            return QString(KXMLQLCEFXFixtureModeDimmer);
×
236
        case RGB:
×
237
            return QString(KXMLQLCEFXFixtureModeRGB);
×
238
    }
239
}
240

241
EFXFixture::Mode EFXFixture::stringToMode(const QString& str)
×
242
{
243
    if (str == QString(KXMLQLCEFXFixtureModePanTilt))
×
244
        return PanTilt;
245
    else if (str == QString(KXMLQLCEFXFixtureModeDimmer))
×
246
        return Dimmer;
247
    else if (str == QString(KXMLQLCEFXFixtureModeRGB))
×
248
        return RGB;
249
    else
250
        return PanTilt;
×
251
}
252

253
/*****************************************************************************
254
 * Load & Save
255
 *****************************************************************************/
256

257
bool EFXFixture::loadXML(QXmlStreamReader &root)
13✔
258
{
259
    if (root.name() != KXMLQLCEFXFixture)
26✔
260
    {
261
        qWarning("EFX Fixture node not found!");
1✔
262
        return false;
1✔
263
    }
264

265
    GroupHead head;
12✔
266
    head.head = 0;
12✔
267

268
    /* New file format contains sub tags */
269
    while (root.readNextStartElement())
38✔
270
    {
271
        if (root.name() == KXMLQLCEFXFixtureID)
52✔
272
        {
273
            /* Fixture ID */
274
            head.fxi = root.readElementText().toInt();
12✔
275
        }
276
        else if (root.name() == KXMLQLCEFXFixtureHead)
28✔
277
        {
278
            /* Fixture Head */
279
            head.head = root.readElementText().toInt();
1✔
280
        }
281
        else if (root.name() == KXMLQLCEFXFixtureMode)
26✔
282
        {
283
            /* Fixture Mode */
284
            setMode ((Mode) root.readElementText().toInt());
×
285
        }
286
        else if (root.name() == KXMLQLCEFXFixtureDirection)
26✔
287
        {
288
            /* Direction */
289
            Function::Direction dir = Function::stringToDirection(root.readElementText());
12✔
290
            setDirection(dir);
12✔
291
        }
292
        else if (root.name() == KXMLQLCEFXFixtureStartOffset)
2✔
293
        {
294
            /* Start offset */
295
            setStartOffset(root.readElementText().toInt());
×
296
        }
297
        else if (root.name() == KXMLQLCEFXFixtureIntensity)
2✔
298
        {
299
            /* Intensity - LEGACY */
300
            root.skipCurrentElement();
×
301
        }
302
        else
303
        {
304
            qWarning() << "Unknown EFX Fixture tag:" << root.name();
1✔
305
            root.skipCurrentElement();
1✔
306
        }
307
    }
308

309
    if (head.fxi != Fixture::invalidId())
12✔
310
       setHead(head);
12✔
311

312
    return true;
313
}
12✔
314

315
bool EFXFixture::saveXML(QXmlStreamWriter *doc) const
4✔
316
{
317
    Q_ASSERT(doc != NULL);
318

319
    /* EFXFixture */
320
    doc->writeStartElement(KXMLQLCEFXFixture);
4✔
321

322
    /* Fixture ID */
323
    doc->writeTextElement(KXMLQLCEFXFixtureID, QString("%1").arg(head().fxi));
4✔
324
    /* Fixture Head */
325
    doc->writeTextElement(KXMLQLCEFXFixtureHead, QString("%1").arg(head().head));
4✔
326
    /* Mode */
327
    doc->writeTextElement(KXMLQLCEFXFixtureMode, QString::number(mode()));
4✔
328
    /* Direction */
329
    doc->writeTextElement(KXMLQLCEFXFixtureDirection, Function::directionToString(m_direction));
4✔
330
    /* Start offset */
331
    doc->writeTextElement(KXMLQLCEFXFixtureStartOffset, QString::number(startOffset()));
4✔
332

333
    /* End the <Fixture> tag */
334
    doc->writeEndElement();
4✔
335

336
    return true;
4✔
337
}
338

339
/****************************************************************************
340
 * Run-time properties
341
 ****************************************************************************/
342

343
const Doc* EFXFixture::doc() const
521✔
344
{
345
    Q_ASSERT(m_parent != NULL);
346
    return m_parent->doc();
521✔
347
}
348

349
void EFXFixture::setSerialNumber(int number)
13✔
350
{
351
    m_serialNumber = number;
13✔
352
}
13✔
353

354
int EFXFixture::serialNumber() const
5✔
355
{
356
    return m_serialNumber;
5✔
357
}
358

359
void EFXFixture::reset()
10✔
360
{
361
    m_done = false;
10✔
362
    m_runTimeDirection = m_direction;
10✔
363
    m_started = false;
10✔
364
    m_elapsed = 0;
10✔
365
    m_currentAngle = 0;
10✔
366
}
10✔
367

368
bool EFXFixture::isDone() const
206✔
369
{
370
    return m_done;
206✔
371
}
372

373
uint EFXFixture::timeOffset() const
155✔
374
{
375
    if (m_parent->propagationMode() == EFX::Asymmetric ||
310✔
376
        m_parent->propagationMode() == EFX::Serial)
155✔
377
    {
378
        return m_parent->loopDuration() / (m_parent->fixtures().size() + 1) * serialNumber();
3✔
379
    }
380
    else
381
    {
382
        return 0;
383
    }
384
}
385

386
/*****************************************************************************
387
 * Running
388
 *****************************************************************************/
389

390
void EFXFixture::start(QSharedPointer<GenericFader> fader)
7✔
391
{
392
    Fixture *fxi = doc()->fixture(head().fxi);
7✔
393

394
    /* Cache channels to reduce processing while running */
395
    switch (m_mode)
7✔
396
    {
397
        case PanTilt:
7✔
398
        {
399
            m_firstMsbChannel = fxi->channelNumber(QLCChannel::Pan, QLCChannel::MSB, head().head);
7✔
400
            m_firstLsbChannel = fxi->channelNumber(QLCChannel::Pan, QLCChannel::LSB, head().head);
7✔
401
            m_secondMsbChannel = fxi->channelNumber(QLCChannel::Tilt, QLCChannel::MSB, head().head);
7✔
402
            m_secondLsbChannel = fxi->channelNumber(QLCChannel::Tilt, QLCChannel::LSB, head().head);
7✔
403

404
            /* Check for non-contiguous channels */
405
            if ((m_firstLsbChannel != QLCChannel::invalid() && m_firstLsbChannel - m_firstMsbChannel != 1) ||
13✔
406
                (m_secondLsbChannel != QLCChannel::invalid() && m_secondLsbChannel - m_secondMsbChannel != 1))
6✔
407
            {
408
                fader->setHandleSecondary(false);
1✔
409
            }
410
        }
411
        break;
412

413
        case RGB:
414
        break;
415

416
        case Dimmer:
×
417
        {
418
            m_firstMsbChannel = fxi->channelNumber(QLCChannel::Intensity, QLCChannel::MSB, head().head);
×
419
            if (m_firstMsbChannel != QLCChannel::invalid())
×
420
            {
421
                m_firstLsbChannel = fxi->channelNumber(QLCChannel::Intensity, QLCChannel::LSB, head().head);
×
422

423
                /* Check for non-contiguous channels */
424
                if (m_firstLsbChannel != QLCChannel::invalid() && m_firstLsbChannel - m_firstMsbChannel != 1)
×
425
                {
426
                    fader->setHandleSecondary(false);
×
427
                }
428
            }
429
            else
430
            {
431
                m_firstMsbChannel = fxi->masterIntensityChannel();
×
432
            }
433
        }
434
        break;
435
    }
436
    m_started = true;
7✔
437
}
7✔
438

439
void EFXFixture::stop()
5✔
440
{
441
    m_started = false;
5✔
442
}
5✔
443

444
void EFXFixture::nextStep(QList<Universe *> universes, QSharedPointer<GenericFader> fader)
202✔
445
{
446
    // Nothing to do
447
    if (m_parent->loopDuration() == 0)
202✔
448
        return;
50✔
449

450
    // Bail out without doing anything if this fixture is ready (after single-shot)
451
    // or it has no pan&tilt channels (not valid).
452
    if (m_done == true || isValid() == false)
152✔
453
        return;
×
454

455
    m_elapsed += MasterTimer::tick();
152✔
456

457
    // Check time wrapping
458
    if (m_elapsed > m_parent->loopDuration())
152✔
459
    {
460
        if (m_parent->runOrder() == Function::PingPong)
2✔
461
        {
462
            /* Reverse direction for ping-pong EFX. */
463
            if (m_runTimeDirection == Function::Forward)
×
464
                m_runTimeDirection = Function::Backward;
×
465
            else
466
                m_runTimeDirection = Function::Forward;
×
467
        }
468
        else if (m_parent->runOrder() == Function::SingleShot)
2✔
469
        {
470
            /* De-initialize the fixture and mark as ready. */
471
            m_done = true;
1✔
472
            stop();
1✔
473
        }
474

475
        m_elapsed = 0;
2✔
476
    }
477

478
    // Bail out without doing anything if this fixture is waiting for its turn.
479
    if (m_parent->propagationMode() == EFX::Serial && m_elapsed < timeOffset() && !m_started)
152✔
480
        return;
481

482
    // Fade in
483
    if (m_started == false)
152✔
484
        start(fader);
6✔
485

486
    // Scale from elapsed time in relation to overall duration to a point in a circle
487
    uint pos = (m_elapsed + timeOffset()) % m_parent->loopDuration();
152✔
488
    m_currentAngle = SCALE(float(pos),
152✔
489
                           float(0), float(m_parent->loopDuration()),
490
                           float(0), float(M_PI * 2));
491

492
    float valX = 0;
152✔
493
    float valY = 0;
152✔
494

495
    m_parent->calculatePoint(m_runTimeDirection, m_startOffset, m_currentAngle, &valX, &valY);
152✔
496

497
    /* Set target values on faders/universes */
498
    switch (m_mode)
152✔
499
    {
500
        case PanTilt:
152✔
501
            setPointPanTilt(universes, fader, valX, valY);
304✔
502
        break;
152✔
503

504
        case RGB:
×
505
            setPointRGB(universes, fader, valX, valY);
×
506
        break;
×
507

508
        case Dimmer:
×
509
            //Use Y for coherence with RGB gradient.
510
            setPointDimmer(universes, fader, valY);
×
511
        break;
×
512
    }
513
}
514

515
void EFXFixture::updateFaderValues(FadeChannel *fc, quint32 value)
312✔
516
{
517
    fc->setStart(fc->current());
312✔
518
    fc->setTarget(value);
312✔
519
    fc->setElapsed(0);
312✔
520
    fc->setReady(false);
312✔
521
    fc->setFadeTime(0);
312✔
522
}
312✔
523

524
void EFXFixture::setPointPanTilt(QList<Universe *> universes, QSharedPointer<GenericFader> fader,
156✔
525
                                 float pan, float tilt)
526
{
527
    if (fader.isNull())
156✔
528
        return;
529

530
    Universe *uni = universes[universe()];
156✔
531

532
    //qDebug() << "Pan value: " << pan << ", tilt value:" << tilt;
533

534
    /* Check for outbound values */
535
    if (pan < 0)
156✔
536
        pan = 0;
537

538
    if (tilt < 0)
156✔
539
        tilt = 0;
540

541
    /* Write full 16bit point data to universes */
542
    if (m_firstMsbChannel != QLCChannel::invalid())
156✔
543
    {
544
        quint32 panValue = quint32(pan);
155✔
545
        FadeChannel *fc = fader->getChannelFader(doc(), uni, head().fxi, m_firstMsbChannel);
155✔
546
        if (m_firstLsbChannel != QLCChannel::invalid())
155✔
547
        {
548
            if (fader->handleSecondary())
1✔
549
            {
550
                fc = fader->getChannelFader(doc(), uni, head().fxi, m_firstLsbChannel);
×
551
                panValue = (panValue << 8) + quint32((pan - floor(pan)) * float(UCHAR_MAX));
×
552
            }
553
            else
554
            {
555
                FadeChannel *lsbFc = fader->getChannelFader(doc(), uni, head().fxi, m_firstLsbChannel);
1✔
556
                updateFaderValues(lsbFc, quint32((pan - floor(pan)) * float(UCHAR_MAX)));
1✔
557
            }
558
        }
559
        if (m_parent->isRelative())
155✔
560
            fc->addFlag(FadeChannel::Relative);
×
561

562
        updateFaderValues(fc, panValue);
155✔
563
    }
564
    if (m_secondMsbChannel != QLCChannel::invalid())
156✔
565
    {
566
        quint32 tiltValue = quint32(tilt);
155✔
567
        FadeChannel *fc = fader->getChannelFader(doc(), uni, head().fxi, m_secondMsbChannel);
155✔
568
        if (m_secondLsbChannel != QLCChannel::invalid())
155✔
569
        {
570
            if (fader->handleSecondary())
1✔
571
            {
572
                fc = fader->getChannelFader(doc(), uni, head().fxi, m_secondLsbChannel);
×
573
                tiltValue = (tiltValue << 8) + quint32((tilt - floor(tilt)) * float(UCHAR_MAX));
×
574
            }
575
            else
576
            {
577
                FadeChannel *lsbFc = fader->getChannelFader(doc(), uni, head().fxi, m_secondLsbChannel);
1✔
578
                updateFaderValues(lsbFc, quint32((tilt - floor(tilt)) * float(UCHAR_MAX)));
1✔
579
            }
580
        }
581
        if (m_parent->isRelative())
155✔
582
            fc->addFlag(FadeChannel::Relative);
×
583

584
        updateFaderValues(fc, tiltValue);
155✔
585
    }
586
}
587

588
void EFXFixture::setPointDimmer(QList<Universe *> universes, QSharedPointer<GenericFader> fader, float dimmer)
×
589
{
590
    if (fader.isNull())
×
591
        return;
592

593
    Universe *uni = universes[universe()];
×
594

595
    /* Don't write dimmer data directly to universes but use FadeChannel to avoid steps at EFX loop restart */
596
    if (m_firstMsbChannel != QLCChannel::invalid())
×
597
    {
598
        quint32 dimmerValue = quint32(dimmer);
×
599
        FadeChannel *fc = fader->getChannelFader(doc(), uni, head().fxi, m_firstMsbChannel);
×
600

601
        if (m_firstLsbChannel != QLCChannel::invalid())
×
602
        {
603
            if (fader->handleSecondary())
×
604
            {
605
                fc = fader->getChannelFader(doc(), uni, head().fxi, m_firstLsbChannel);
×
606
                dimmerValue = (dimmerValue << 8) + quint32((dimmer - floor(dimmer)) * float(UCHAR_MAX));
×
607
            }
608
        }
609
        updateFaderValues(fc, dimmerValue);
×
610
    }
611
}
612

613
void EFXFixture::setPointRGB(QList<Universe *> universes, QSharedPointer<GenericFader> fader, float x, float y)
×
614
{
615
    if (fader.isNull())
×
616
        return;
×
617

618
    Fixture* fxi = doc()->fixture(head().fxi);
×
619
    Q_ASSERT(fxi != NULL);
620
    Universe *uni = universes[universe()];
×
621

622
    QVector<quint32> rgbChannels = fxi->rgbChannels(head().head);
×
623

624
    /* Don't write dimmer data directly to universes but use FadeChannel to avoid steps at EFX loop restart */
625
    if (rgbChannels.size() >= 3 && !fader.isNull())
×
626
    {
627
        QColor pixel = m_rgbGradient.pixel(x, y);
×
628

629
        FadeChannel *fc = fader->getChannelFader(doc(), uni, fxi->id(), rgbChannels[0]);
×
630
        updateFaderValues(fc, pixel.red());
×
631
        fc = fader->getChannelFader(doc(), uni, fxi->id(), rgbChannels[1]);
×
632
        updateFaderValues(fc, pixel.green());
×
633
        fc = fader->getChannelFader(doc(), uni, fxi->id(), rgbChannels[2]);
×
634
        updateFaderValues(fc, pixel.blue());
×
635
    }
636
}
×
637

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc