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

mcallegari / qlcplus / 9397136830

06 Jun 2024 07:53AM UTC coverage: 31.62% (-0.4%) from 32.027%
9397136830

Pull #1422

github

web-flow
Merge 05fd4b369 into abeec908b
Pull Request #1422: RgbScript make stage colors available to scripts

51 of 892 new or added lines in 11 files covered. (5.72%)

21 existing lines in 6 files now uncovered.

14039 of 44399 relevant lines covered (31.62%)

26669.82 hits per line

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

0.0
/ui/src/rgbmatrixeditor.cpp
1
/*
2
  Q Light Controller
3
  rgbmatrixeditor.cpp
4

5
  Copyright (c) Heikki Junnila
6

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

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

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

20
#include <QGraphicsEllipseItem>
21
#include <QGraphicsRectItem>
22
#include <QGraphicsEffect>
23
#include <QGraphicsScene>
24
#include <QGraphicsView>
25
#include <QColorDialog>
26
#include <QFileDialog>
27
#include <QFontDialog>
28
#include <QGradient>
29
#include <QSettings>
30
#include <QComboBox>
31
#include <QLineEdit>
32
#include <QSpinBox>
33
#include <QLabel>
34
#include <QTimer>
35
#include <QDebug>
36
#include <QMutex>
37

38
#include "fixtureselection.h"
39
#include "speeddialwidget.h"
40
#include "rgbmatrixeditor.h"
41
#include "qlcfixturehead.h"
42
#include "qlcmacros.h"
43
#include "rgbimage.h"
44
#include "sequence.h"
45
#include "rgbitem.h"
46
#include "rgbtext.h"
47
#include "scene.h"
48

49
#define SETTINGS_GEOMETRY "rgbmatrixeditor/geometry"
50
#define RECT_SIZE 30
51
#define RECT_PADDING 0
52
#define ITEM_SIZE 28
53
#define ITEM_PADDING 2
54

55
/****************************************************************************
56
 * Initialization
57
 ****************************************************************************/
58

59
RGBMatrixEditor::RGBMatrixEditor(QWidget* parent, RGBMatrix* mtx, Doc* doc)
×
60
    : QWidget(parent)
61
    , m_doc(doc)
62
    , m_matrix(mtx)
63
    , m_previewHandler(new RGBMatrixStep())
×
64
    , m_speedDials(NULL)
65
    , m_scene(new QGraphicsScene(this))
×
66
    , m_previewTimer(new QTimer(this))
×
67
    , m_previewIterator(0)
×
68
{
69
    Q_ASSERT(doc != NULL);
70
    Q_ASSERT(mtx != NULL);
71

72
    setupUi(this);
×
73

74
    // Set a nice gradient backdrop
75
    m_scene->setBackgroundBrush(Qt::darkGray);
×
76
    QLinearGradient gradient(200, 200, 200, 2000);
×
77
    gradient.setSpread(QGradient::ReflectSpread);
78
    m_scene->setBackgroundBrush(gradient);
×
79

80
    connect(m_previewTimer, SIGNAL(timeout()), this, SLOT(slotPreviewTimeout()));
×
81
    connect(m_doc, SIGNAL(modeChanged(Doc::Mode)), this, SLOT(slotModeChanged(Doc::Mode)));
×
82
    connect(m_doc, SIGNAL(fixtureGroupAdded(quint32)), this, SLOT(slotFixtureGroupAdded()));
×
83
    connect(m_doc, SIGNAL(fixtureGroupRemoved(quint32)), this, SLOT(slotFixtureGroupRemoved()));
×
84
    connect(m_doc, SIGNAL(fixtureGroupChanged(quint32)), this, SLOT(slotFixtureGroupChanged(quint32)));
×
85

86
    init();
×
87

88
    slotModeChanged(m_doc->mode());
×
89

90
    // Set focus to the editor
91
    m_nameEdit->setFocus();
×
92
}
×
93

94
RGBMatrixEditor::~RGBMatrixEditor()
×
95
{
96
    m_previewTimer->stop();
×
97

98
    if (m_testButton->isChecked() == true)
×
99
        m_matrix->stopAndWait();
×
100

101
    delete m_previewHandler;
×
102
}
×
103

104
void RGBMatrixEditor::stopTest()
×
105
{
106
    if (m_testButton->isChecked() == true)
×
107
        m_testButton->click();
×
108
}
×
109

110
void RGBMatrixEditor::slotFunctionManagerActive(bool active)
×
111
{
112
    if (active == true)
×
113
    {
114
        if (m_speedDials == NULL)
×
115
            updateSpeedDials();
×
116
    }
117
    else
118
    {
119
        if (m_speedDials != NULL)
×
120
            m_speedDials->deleteLater();
×
121
        m_speedDials = NULL;
×
122
    }
123
}
×
124

125
void RGBMatrixEditor::init()
×
126
{
127
    /* Name */
128
    m_nameEdit->setText(m_matrix->name());
×
129
    m_nameEdit->setSelection(0, m_matrix->name().length());
×
130

131
    /* Running order */
132
    switch (m_matrix->runOrder())
×
133
    {
134
        default:
×
135
        case Function::Loop:
136
            m_loop->setChecked(true);
×
137
        break;
138
        case Function::PingPong:
×
139
            m_pingPong->setChecked(true);
×
140
        break;
141
        case Function::SingleShot:
×
142
            m_singleShot->setChecked(true);
×
143
        break;
144
    }
145

146
    /* Running direction */
147
    switch (m_matrix->direction())
×
148
    {
149
        default:
×
150
        case Function::Forward:
151
            m_forward->setChecked(true);
×
152
        break;
153
        case Function::Backward:
×
154
            m_backward->setChecked(true);
×
155
        break;
156
    }
157

158

159
    /* Blend mode */
160
    m_blendModeCombo->setCurrentIndex(m_matrix->blendMode());
×
161

162
    /* Color mode */
163
    m_controlModeCombo->setCurrentIndex(m_matrix->controlMode());
×
164

165
    /* Dimmer control */
166
    if (m_matrix->dimmerControl())
×
167
        m_dimmerControlCb->setChecked(m_matrix->dimmerControl());
×
168
    else
169
        m_intensityGroup->hide();
×
170

171
    fillPatternCombo();
×
172
    fillFixtureGroupCombo();
×
173
    fillAnimationCombo();
×
174
    fillImageAnimationCombo();
×
175

176
    QPixmap pm(50, 26);
×
NEW
177
    pm.fill(m_matrix->getColor(0));
×
NEW
178
    m_mtxColor1Button->setIcon(QIcon(pm));
×
179

NEW
180
    if (m_matrix->getColor(1).isValid())
×
NEW
181
        pm.fill(m_matrix->getColor(1));
×
182
    else
183
        pm.fill(Qt::transparent);
×
NEW
184
    m_mtxColor2Button->setIcon(QIcon(pm));
×
185

NEW
186
    if (m_matrix->getColor(2).isValid())
×
NEW
187
        pm.fill(m_matrix->getColor(2));
×
188
    else
NEW
189
        pm.fill(Qt::transparent);
×
NEW
190
    m_mtxColor3Button->setIcon(QIcon(pm));
×
191

NEW
192
    if (m_matrix->getColor(3).isValid())
×
NEW
193
        pm.fill(m_matrix->getColor(3));
×
194
    else
NEW
195
        pm.fill(Qt::transparent);
×
NEW
196
    m_mtxColor4Button->setIcon(QIcon(pm));
×
197

NEW
198
    if (m_matrix->getColor(4).isValid())
×
NEW
199
        pm.fill(m_matrix->getColor(4));
×
200
    else
NEW
201
        pm.fill(Qt::transparent);
×
NEW
202
    m_mtxColor5Button->setIcon(QIcon(pm));
×
203

204
    updateExtraOptions();
×
205
    updateSpeedDials();
×
206

207
    connect(m_nameEdit, SIGNAL(textEdited(const QString&)),
×
208
            this, SLOT(slotNameEdited(const QString&)));
209
    connect(m_speedDialButton, SIGNAL(toggled(bool)),
×
210
            this, SLOT(slotSpeedDialToggle(bool)));
211
    connect(m_saveToSequenceButton, SIGNAL(clicked()),
×
212
            this, SLOT(slotSaveToSequenceClicked()));
213
    connect(m_shapeButton, SIGNAL(toggled(bool)),
×
214
            this, SLOT(slotShapeToggle(bool)));
215
    connect(m_patternCombo, SIGNAL(activated(int)),
×
216
            this, SLOT(slotPatternActivated(int)));
217
    connect(m_fixtureGroupCombo, SIGNAL(activated(int)),
×
218
            this, SLOT(slotFixtureGroupActivated(int)));
219
    connect(m_blendModeCombo, SIGNAL(activated(int)),
×
220
            this, SLOT(slotBlendModeChanged(int)));
221
    connect(m_controlModeCombo, SIGNAL(activated(int)),
×
222
            this, SLOT(slotControlModeChanged(int)));
NEW
223
    connect(m_mtxColor1Button, SIGNAL(clicked()),
×
224
            this, SLOT(slotMtxColor1ButtonClicked()));
NEW
225
    connect(m_mtxColor2Button, SIGNAL(clicked()),
×
226
            this, SLOT(slotMtxColor2ButtonClicked()));
NEW
227
    connect(m_resetMtxColor2Button, SIGNAL(clicked()),
×
228
            this, SLOT(slotResetMtxColor2ButtonClicked()));
NEW
229
    connect(m_mtxColor3Button, SIGNAL(clicked()),
×
230
            this, SLOT(slotMtxColor3ButtonClicked()));
NEW
231
    connect(m_resetMtxColor3Button, SIGNAL(clicked()),
×
232
            this, SLOT(slotResetMtxColor3ButtonClicked()));
NEW
233
    connect(m_mtxColor4Button, SIGNAL(clicked()),
×
234
            this, SLOT(slotMtxColor4ButtonClicked()));
NEW
235
    connect(m_resetMtxColor4Button, SIGNAL(clicked()),
×
236
            this, SLOT(slotResetMtxColor4ButtonClicked()));
NEW
237
    connect(m_mtxColor5Button, SIGNAL(clicked()),
×
238
            this, SLOT(slotMtxColor5ButtonClicked()));
NEW
239
    connect(m_resetMtxColor5Button, SIGNAL(clicked()),
×
240
            this, SLOT(slotResetMtxColor5ButtonClicked()));
UNCOV
241
    connect(m_textEdit, SIGNAL(textEdited(const QString&)),
×
242
            this, SLOT(slotTextEdited(const QString&)));
243
    connect(m_fontButton, SIGNAL(clicked()),
×
244
            this, SLOT(slotFontButtonClicked()));
245
    connect(m_animationCombo, SIGNAL(activated(int)),
×
246
            this, SLOT(slotAnimationActivated(int)));
247
    connect(m_imageEdit, SIGNAL(editingFinished()),
×
248
            this, SLOT(slotImageEdited()));
249
    connect(m_imageButton, SIGNAL(clicked()),
×
250
            this, SLOT(slotImageButtonClicked()));
251
    connect(m_imageAnimationCombo, SIGNAL(activated(int)),
×
252
            this, SLOT(slotImageAnimationActivated(int)));
253
    connect(m_xOffsetSpin, SIGNAL(valueChanged(int)),
×
254
            this, SLOT(slotOffsetSpinChanged()));
255
    connect(m_yOffsetSpin, SIGNAL(valueChanged(int)),
×
256
            this, SLOT(slotOffsetSpinChanged()));
257

258
    connect(m_loop, SIGNAL(clicked()), this, SLOT(slotLoopClicked()));
×
259
    connect(m_pingPong, SIGNAL(clicked()), this, SLOT(slotPingPongClicked()));
×
260
    connect(m_singleShot, SIGNAL(clicked()), this, SLOT(slotSingleShotClicked()));
×
261
    connect(m_forward, SIGNAL(clicked()), this, SLOT(slotForwardClicked()));
×
262
    connect(m_backward, SIGNAL(clicked()), this, SLOT(slotBackwardClicked()));
×
263
    connect(m_dimmerControlCb, SIGNAL(clicked()), this, SLOT(slotDimmerControlClicked()));
×
264

265
    // Test slots
266
    connect(m_testButton, SIGNAL(clicked(bool)),
×
267
            this, SLOT(slotTestClicked()));
268

269
    m_preview->setScene(m_scene);
×
270
    if (createPreviewItems() == true)
×
271
        m_previewTimer->start(MasterTimer::tick());
×
272
}
×
273

274
void RGBMatrixEditor::updateSpeedDials()
×
275
{
276
    if (m_speedDialButton->isChecked() == false)
×
277
        return;
278

279
    if (m_speedDials != NULL)
×
280
        return;
281

282
    m_speedDials = new SpeedDialWidget(this);
×
283
    m_speedDials->setAttribute(Qt::WA_DeleteOnClose);
×
284
    m_speedDials->setWindowTitle(m_matrix->name());
×
285
    m_speedDials->show();
×
286
    m_speedDials->setFadeInSpeed(m_matrix->fadeInSpeed());
×
287
    m_speedDials->setFadeOutSpeed(m_matrix->fadeOutSpeed());
×
288
    if ((int)m_matrix->duration() < 0)
×
289
        m_speedDials->setDuration(m_matrix->duration());
×
290
    else
291
        m_speedDials->setDuration(m_matrix->duration() - m_matrix->fadeInSpeed());
×
292
    connect(m_speedDials, SIGNAL(fadeInChanged(int)), this, SLOT(slotFadeInChanged(int)));
×
293
    connect(m_speedDials, SIGNAL(fadeOutChanged(int)), this, SLOT(slotFadeOutChanged(int)));
×
294
    connect(m_speedDials, SIGNAL(holdChanged(int)), this, SLOT(slotHoldChanged(int)));
×
295
    connect(m_speedDials, SIGNAL(holdTapped()), this, SLOT(slotDurationTapped()));
×
296
    connect(m_speedDials, SIGNAL(destroyed(QObject*)), this, SLOT(slotDialDestroyed(QObject*)));
×
297
}
298

299
void RGBMatrixEditor::fillPatternCombo()
×
300
{
301
    m_patternCombo->addItems(RGBAlgorithm::algorithms(m_doc));
×
302
    if (m_matrix->algorithm() != NULL)
×
303
    {
304
        int index = m_patternCombo->findText(m_matrix->algorithm()->name());
×
305
        if (index >= 0)
×
306
            m_patternCombo->setCurrentIndex(index);
×
307
    }
308
}
×
309

310
void RGBMatrixEditor::fillFixtureGroupCombo()
×
311
{
312
    m_fixtureGroupCombo->clear();
×
313
    m_fixtureGroupCombo->addItem(tr("None"));
×
314

315
    QListIterator <FixtureGroup*> it(m_doc->fixtureGroups());
×
316
    while (it.hasNext() == true)
×
317
    {
318
        FixtureGroup* grp(it.next());
×
319
        Q_ASSERT(grp != NULL);
320
        m_fixtureGroupCombo->addItem(grp->name(), grp->id());
×
321
        if (m_matrix->fixtureGroup() == grp->id())
×
322
            m_fixtureGroupCombo->setCurrentIndex(m_fixtureGroupCombo->count() - 1);
×
323
    }
324
}
×
325

326
void RGBMatrixEditor::fillAnimationCombo()
×
327
{
328
    m_animationCombo->addItems(RGBText::animationStyles());
×
329
}
×
330

331
void RGBMatrixEditor::fillImageAnimationCombo()
×
332
{
333
    m_imageAnimationCombo->addItems(RGBImage::animationStyles());
×
334
}
×
335

336
void RGBMatrixEditor::updateExtraOptions()
×
337
{
338
    resetProperties(m_propertiesLayout->layout());
×
339
    m_propertiesGroup->hide();
×
340

341
    if (m_matrix->algorithm() == NULL ||
×
342
        m_matrix->algorithm()->type() == RGBAlgorithm::Script ||
×
343
        m_matrix->algorithm()->type() == RGBAlgorithm::Audio)
×
344
    {
345
        m_textGroup->hide();
×
346
        m_imageGroup->hide();
×
347
        m_offsetGroup->hide();
×
348

349
        if (m_matrix->algorithm() != NULL && m_matrix->algorithm()->type() == RGBAlgorithm::Script)
×
350
        {
351
            RGBScript *script = static_cast<RGBScript*> (m_matrix->algorithm());
×
352
            displayProperties(script);
×
353
        }
354
    }
355
    else if (m_matrix->algorithm()->type() == RGBAlgorithm::Plain)
×
356
    {
357
        m_textGroup->hide();
×
358
        m_imageGroup->hide();
×
359
        m_offsetGroup->hide();
×
360
    }
361
    else if (m_matrix->algorithm()->type() == RGBAlgorithm::Image)
×
362
    {
363
        m_textGroup->hide();
×
364
        m_imageGroup->show();
×
365
        m_offsetGroup->show();
×
366

367
        RGBImage *image = static_cast<RGBImage*> (m_matrix->algorithm());
×
368
        Q_ASSERT(image != NULL);
369
        m_imageEdit->setText(image->filename());
×
370

371
        int index = m_imageAnimationCombo->findText(RGBImage::animationStyleToString(image->animationStyle()));
×
372
        if (index != -1)
×
373
            m_imageAnimationCombo->setCurrentIndex(index);
×
374

375
        m_xOffsetSpin->setValue(image->xOffset());
×
376
        m_yOffsetSpin->setValue(image->yOffset());
×
377

378
    }
379
    else if (m_matrix->algorithm()->type() == RGBAlgorithm::Text)
×
380
    {
381
        m_textGroup->show();
×
382
        m_offsetGroup->show();
×
383
        m_imageGroup->hide();
×
384

385
        RGBText *text = static_cast<RGBText*> (m_matrix->algorithm());
×
386
        Q_ASSERT(text != NULL);
387
        m_textEdit->setText(text->text());
×
388

389
        int index = m_animationCombo->findText(RGBText::animationStyleToString(text->animationStyle()));
×
390
        if (index != -1)
×
391
            m_animationCombo->setCurrentIndex(index);
×
392

393
        m_xOffsetSpin->setValue(text->xOffset());
×
394
        m_yOffsetSpin->setValue(text->yOffset());
×
395
    }
396

397
    if (m_matrix->algorithm() != NULL)
×
398
    {
399
        int accColors = m_matrix->algorithm()->acceptColors();
×
400
        if (accColors == 0)
×
401
        {
NEW
402
            m_mtxColor1Button->hide();
×
NEW
403
            m_mtxColor2Button->hide();
×
NEW
404
            m_resetMtxColor2Button->hide();
×
NEW
405
            m_mtxColor3Button->hide();
×
NEW
406
            m_resetMtxColor3Button->hide();
×
NEW
407
            m_mtxColor4Button->hide();
×
NEW
408
            m_resetMtxColor4Button->hide();
×
NEW
409
            m_mtxColor5Button->hide();
×
NEW
410
            m_resetMtxColor5Button->hide();
×
411
            m_blendModeLabel->hide();
×
412
            m_blendModeCombo->hide();
×
413
        }
414
        else
415
        {
NEW
416
            m_mtxColor1Button->show();
×
417

418
            if (accColors == 1 || m_blendModeCombo->currentIndex() == Universe::MaskBlend)
×
419
            {
NEW
420
                m_mtxColor2Button->hide();
×
NEW
421
                m_resetMtxColor2Button->hide();
×
NEW
422
                m_mtxColor3Button->hide();
×
NEW
423
                m_resetMtxColor3Button->hide();
×
NEW
424
                m_mtxColor4Button->hide();
×
NEW
425
                m_resetMtxColor4Button->hide();
×
NEW
426
                m_mtxColor5Button->hide();
×
NEW
427
                m_resetMtxColor5Button->hide();
×
428
            }
NEW
429
            else if (accColors == 2)
×
430
            {
NEW
431
                m_mtxColor2Button->show();
×
NEW
432
                m_resetMtxColor2Button->show();
×
NEW
433
                m_mtxColor3Button->hide();
×
NEW
434
                m_resetMtxColor3Button->hide();
×
NEW
435
                m_mtxColor4Button->hide();
×
NEW
436
                m_resetMtxColor4Button->hide();
×
NEW
437
                m_mtxColor5Button->hide();
×
NEW
438
                m_resetMtxColor5Button->hide();
×
439
            }
NEW
440
            else if (accColors == 3)
×
441
            {
NEW
442
                m_mtxColor2Button->show();
×
NEW
443
                m_resetMtxColor2Button->show();
×
NEW
444
                m_mtxColor3Button->show();
×
NEW
445
                m_resetMtxColor3Button->show();
×
NEW
446
                m_mtxColor4Button->hide();
×
NEW
447
                m_resetMtxColor4Button->hide();
×
NEW
448
                m_mtxColor5Button->hide();
×
NEW
449
                m_resetMtxColor5Button->hide();
×
450
            }
NEW
451
            else if (accColors == 4)
×
452
            {
NEW
453
                m_mtxColor2Button->show();
×
NEW
454
                m_resetMtxColor2Button->show();
×
NEW
455
                m_mtxColor3Button->show();
×
NEW
456
                m_resetMtxColor3Button->show();
×
NEW
457
                m_mtxColor4Button->show();
×
NEW
458
                m_resetMtxColor4Button->show();
×
NEW
459
                m_mtxColor5Button->hide();
×
NEW
460
                m_resetMtxColor5Button->hide();
×
461
            }
462
            else
463
            {
NEW
464
                m_mtxColor2Button->show();
×
NEW
465
                m_resetMtxColor2Button->show();
×
NEW
466
                m_mtxColor3Button->show();
×
NEW
467
                m_resetMtxColor3Button->show();
×
NEW
468
                m_mtxColor4Button->show();
×
NEW
469
                m_resetMtxColor4Button->show();
×
NEW
470
                m_mtxColor5Button->show();
×
NEW
471
                m_resetMtxColor5Button->show();
×
472
            }
473
            m_blendModeLabel->show();
×
474
            m_blendModeCombo->show();
×
475
        }
476
    }
477
}
×
478

479
void RGBMatrixEditor::updateColors()
×
480
{
481
    if (m_matrix->algorithm() != NULL)
×
482
    {
483
        int accColors = m_matrix->algorithm()->acceptColors();
×
484
        if (accColors > 0)
×
485
        {
486
            if (m_matrix->blendMode() == Universe::MaskBlend)
×
487
            {
NEW
488
                m_matrix->setColor(0, Qt::white);
×
489
                // Overwrite more colors only if applied.
NEW
490
                if (accColors <= 2)
×
NEW
491
                    m_matrix->setColor(1, QColor());
×
NEW
492
                if (accColors <= 3)
×
NEW
493
                    m_matrix->setColor(2, QColor());
×
NEW
494
                if (accColors <= 4)
×
NEW
495
                    m_matrix->setColor(3, QColor());
×
NEW
496
                if (accColors <= 5)
×
NEW
497
                    m_matrix->setColor(4, QColor());
×
498

NEW
499
                m_previewHandler->calculateColorDelta(m_matrix->getColor(0), m_matrix->getColor(1),
×
NEW
500
                        m_matrix->algorithm());
×
501

502
                QPixmap pm(50, 26);
×
503
                pm.fill(Qt::white);
×
NEW
504
                m_mtxColor1Button->setIcon(QIcon(pm));
×
505

NEW
506
                pm.fill(Qt::transparent);
×
NEW
507
                m_mtxColor2Button->setIcon(QIcon(pm));
×
NEW
508
                m_mtxColor3Button->setIcon(QIcon(pm));
×
NEW
509
                m_mtxColor4Button->setIcon(QIcon(pm));
×
NEW
510
                m_mtxColor5Button->setIcon(QIcon(pm));
×
511
            }
512
            else if (m_controlModeCombo->currentIndex() != RGBMatrix::ControlModeRgb)
×
513
            {
514
                // Convert color 1 to grayscale for single color modes
NEW
515
                uchar gray = qGray(m_matrix->getColor(0).rgb());
×
NEW
516
                m_matrix->setColor(0, QColor(gray, gray, gray));
×
517
                QPixmap pm(50, 26);
×
518
                pm.fill(QColor(gray, gray, gray));
×
NEW
519
                m_mtxColor1Button->setIcon(QIcon(pm));
×
520

521
                // Convert color 2 and following to grayscale for single color modes
NEW
522
                if (accColors < 2)
×
NEW
523
                    m_matrix->setColor(1, QColor());
×
NEW
524
                if (m_matrix->getColor(1) == QColor())
×
525
                {
NEW
526
                    pm.fill(Qt::transparent);
×
527
                }
528
                else
529
                {
NEW
530
                    gray = qGray(m_matrix->getColor(1).rgb());
×
NEW
531
                    m_matrix->setColor(1, QColor(gray, gray, gray));
×
NEW
532
                    pm.fill(QColor(gray, gray, gray));
×
533
                }
NEW
534
                m_mtxColor2Button->setIcon(QIcon(pm));
×
535

NEW
536
                if (accColors < 3)
×
NEW
537
                    m_matrix->setColor(2, QColor());
×
NEW
538
                if (m_matrix->getColor(2) == QColor())
×
539
                {
NEW
540
                    pm.fill(Qt::transparent);
×
541
                }
542
                else
543
                {
NEW
544
                    gray = qGray(m_matrix->getColor(2).rgb());
×
NEW
545
                    m_matrix->setColor(2, QColor(gray, gray, gray));
×
NEW
546
                    pm.fill(QColor(gray, gray, gray));
×
547
                }
NEW
548
                m_mtxColor3Button->setIcon(QIcon(pm));
×
549

NEW
550
                if (accColors < 4)
×
NEW
551
                    m_matrix->setColor(3, QColor());
×
NEW
552
                if (m_matrix->getColor(3) == QColor())
×
553
                {
NEW
554
                    pm.fill(Qt::transparent);
×
555
                }
556
                else
557
                {
NEW
558
                    gray = qGray(m_matrix->getColor(3).rgb());
×
NEW
559
                    m_matrix->setColor(3, QColor(gray, gray, gray));
×
NEW
560
                    pm.fill(QColor(gray, gray, gray));
×
561
                }
NEW
562
                m_mtxColor4Button->setIcon(QIcon(pm));
×
563

NEW
564
                if (accColors < 5)
×
NEW
565
                    m_matrix->setColor(4, QColor());
×
NEW
566
                if (m_matrix->getColor(4) == QColor())
×
567
                {
NEW
568
                    pm.fill(Qt::transparent);
×
569
                }
570
                else
571
                {
NEW
572
                    gray = qGray(m_matrix->getColor(4).rgb());
×
NEW
573
                    m_matrix->setColor(4, QColor(gray, gray, gray));
×
NEW
574
                    pm.fill(QColor(gray, gray, gray));
×
575
                }
NEW
576
                m_mtxColor5Button->setIcon(QIcon(pm));
×
577

NEW
578
                m_previewHandler->calculateColorDelta(m_matrix->getColor(0), m_matrix->getColor(1),
×
NEW
579
                        m_matrix->algorithm());
×
580
            }
581
            else 
582
            {
583
                QPixmap pm(50, 26);
×
NEW
584
                pm.fill(m_matrix->getColor(0));
×
NEW
585
                m_mtxColor1Button->setIcon(QIcon(pm));
×
586

587
                // Preserve the colors (do not set them to QColor().
588
                // RGBMatrixStep::calculateColorDelta will ensure correct color application
NEW
589
                if (m_matrix->getColor(1) == QColor())
×
NEW
590
                    pm.fill(Qt::transparent);
×
591
                else
NEW
592
                    pm.fill(m_matrix->getColor(1));
×
NEW
593
                m_mtxColor2Button->setIcon(QIcon(pm));
×
594

NEW
595
                if (m_matrix->getColor(2) == QColor())
×
NEW
596
                    pm.fill(Qt::transparent);
×
597
                else
NEW
598
                    pm.fill(m_matrix->getColor(2));
×
NEW
599
                m_mtxColor3Button->setIcon(QIcon(pm));
×
600

NEW
601
                if (m_matrix->getColor(3) == QColor())
×
NEW
602
                    pm.fill(Qt::transparent);
×
603
                else
NEW
604
                    pm.fill(m_matrix->getColor(3));
×
NEW
605
                m_mtxColor4Button->setIcon(QIcon(pm));
×
606

NEW
607
                if (m_matrix->getColor(4) == QColor())
×
NEW
608
                    pm.fill(Qt::transparent);
×
609
                else
NEW
610
                    pm.fill(m_matrix->getColor(4));
×
NEW
611
                m_mtxColor5Button->setIcon(QIcon(pm));
×
612

NEW
613
                m_previewHandler->calculateColorDelta(m_matrix->getColor(0), m_matrix->getColor(1),
×
NEW
614
                        m_matrix->algorithm());
×
615
            }
616
        }
617
    }
618
}
×
619

620
/**
621
 * Helper function. Deletes all child widgets of the given layout @a item.
622
 */
623
void RGBMatrixEditor::resetProperties(QLayoutItem *item)
×
624
{
625
    if (item->layout()) 
×
626
    {
627
        // Process all child items recursively.
628
        for (int i = item->layout()->count() - 1; i >= 0; i--)
×
629
            resetProperties(item->layout()->itemAt(i));
×
630
    }
631
    delete item->widget();
×
632
}
×
633

634
void RGBMatrixEditor::displayProperties(RGBScript *script)
×
635
{
636
    if (script == NULL)
×
637
        return;
×
638

639
    int gridRowIdx = 0;
640

641
    QList<RGBScriptProperty> properties = script->properties();
×
642
    if (properties.count() > 0)
×
643
        m_propertiesGroup->show();
×
644

645
    foreach (RGBScriptProperty prop, properties)
×
646
    {
647
        switch(prop.m_type)
×
648
        {
649
            case RGBScriptProperty::List:
650
            {
651
                QLabel *propLabel = new QLabel(prop.m_displayName);
×
652
                m_propertiesLayout->addWidget(propLabel, gridRowIdx, 0);
×
653
                QComboBox *propCombo = new QComboBox(this);
×
654
                propCombo->addItems(prop.m_listValues);
655
                propCombo->setProperty("pName", prop.m_name);
×
656
                connect(propCombo, SIGNAL(currentIndexChanged(QString)),
×
657
                        this, SLOT(slotPropertyComboChanged(QString)));
658
                m_propertiesLayout->addWidget(propCombo, gridRowIdx, 1);
×
659
                if (m_matrix != NULL)
×
660
                {
661
                    QString pValue = m_matrix->property(prop.m_name);
×
662
                    if (!pValue.isEmpty())
×
663
                    {
664
                        propCombo->setCurrentText(pValue);
×
665
                    }
666
                    else
667
                    {
668
                        pValue = script->property(prop.m_name);
×
669
                        if (!pValue.isEmpty())
×
670
                            propCombo->setCurrentText(pValue);
×
671
                    }
672
                }
673
                gridRowIdx++;
×
674
            }
675
            break;
×
676
            case RGBScriptProperty::Range:
677
            {
678
                QLabel *propLabel = new QLabel(prop.m_displayName);
×
679
                m_propertiesLayout->addWidget(propLabel, gridRowIdx, 0);
×
680
                QSpinBox *propSpin = new QSpinBox(this);
×
681
                propSpin->setRange(prop.m_rangeMinValue, prop.m_rangeMaxValue);
×
682
                propSpin->setProperty("pName", prop.m_name);
×
683
                connect(propSpin, SIGNAL(valueChanged(int)),
×
684
                        this, SLOT(slotPropertySpinChanged(int)));
685
                m_propertiesLayout->addWidget(propSpin, gridRowIdx, 1);
×
686
                if (m_matrix != NULL)
×
687
                {
688
                    QString pValue = m_matrix->property(prop.m_name);
×
689
                    if (!pValue.isEmpty())
×
690
                        propSpin->setValue(pValue.toInt());
×
691
                    else
692
                    {
693
                        pValue = script->property(prop.m_name);
×
694
                        if (!pValue.isEmpty())
×
695
                            propSpin->setValue(pValue.toInt());
×
696
                    }
697
                }
698
                gridRowIdx++;
×
699
            }
700
            break;
×
701
            case RGBScriptProperty::Float:
702
            {
703
                QLabel *propLabel = new QLabel(prop.m_displayName);
×
704
                m_propertiesLayout->addWidget(propLabel, gridRowIdx, 0);
×
705
                QDoubleSpinBox *propSpin = new QDoubleSpinBox(this);
×
706
                propSpin->setDecimals(3);
×
707
                propSpin->setRange(-1000000, 1000000);
×
708
                propSpin->setProperty("pName", prop.m_name);
×
709
                connect(propSpin, SIGNAL(valueChanged(double)),
×
710
                        this, SLOT(slotPropertyDoubleSpinChanged(double)));
711
                m_propertiesLayout->addWidget(propSpin, gridRowIdx, 1);
×
712
                if (m_matrix != NULL)
×
713
                {
714
                    QString pValue = m_matrix->property(prop.m_name);
×
715
                    if (!pValue.isEmpty())
×
716
                        propSpin->setValue(pValue.toDouble());
×
717
                    else
718
                    {
719
                        pValue = script->property(prop.m_name);
×
720
                        if (!pValue.isEmpty())
×
721
                            propSpin->setValue(pValue.toDouble());
×
722
                    }
723
                }
724
                gridRowIdx++;
×
725
            }
726
            break;
×
727
            case RGBScriptProperty::String:
728
            {
729
                QLabel *propLabel = new QLabel(prop.m_displayName);
×
730
                m_propertiesLayout->addWidget(propLabel, gridRowIdx, 0);
×
731
                QLineEdit *propEdit = new QLineEdit(this);
×
732
                propEdit->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
×
733
                propEdit->setProperty("pName", prop.m_name);
×
734
                connect(propEdit, SIGNAL(textEdited(QString)),
×
735
                        this, SLOT(slotPropertyEditChanged(QString)));
736
                m_propertiesLayout->addWidget(propEdit, gridRowIdx, 1);
×
737
                if (m_matrix != NULL)
×
738
                {
739
                    QString pValue = m_matrix->property(prop.m_name);
×
740
                    if (!pValue.isEmpty())
×
741
                        propEdit->setText(pValue);
×
742
                    else
743
                    {
744
                        pValue = script->property(prop.m_name);
×
745
                        if (!pValue.isEmpty())
×
746
                            propEdit->setText(pValue);
×
747
                    }
748
                }
749
                gridRowIdx++;
×
750
            }
751
            break;
×
752
            default:
753
                qWarning() << "Type" << prop.m_type << "not handled yet";
×
754
            break;
×
755
        }
756
    }
757
}
758

759
bool RGBMatrixEditor::createPreviewItems()
×
760
{
761
    m_previewHash.clear();
×
762
    m_scene->clear();
×
763

764
    FixtureGroup* grp = m_doc->fixtureGroup(m_matrix->fixtureGroup());
×
765
    if (grp == NULL)
×
766
    {
767
        QGraphicsTextItem* text = new QGraphicsTextItem(tr("No fixture group to control"));
×
768
        text->setDefaultTextColor(Qt::white);
×
769
        m_scene->addItem(text);
×
770
        return false;
×
771
    }
772

NEW
773
    m_previewHandler->initializeDirection(m_matrix->direction(), m_matrix->getColor(0),
×
NEW
774
                                      m_matrix->getColor(1), m_matrix->stepsCount(),
×
NEW
775
                                      m_matrix->algorithm());
×
776

777
    m_matrix->previewMap(m_previewHandler->currentStepIndex(), m_previewHandler);
×
778

779
    if (m_previewHandler->m_map.isEmpty())
×
780
        return false;
781

782
    for (int x = 0; x < grp->size().width(); x++)
×
783
    {
784
        for (int y = 0; y < grp->size().height(); y++)
×
785
        {
786
            QLCPoint pt(x, y);
×
787

788
            if (grp->headsMap().contains(pt) == true)
×
789
            {
790
                RGBItem *item;
791
                if (m_shapeButton->isChecked() == false)
×
792
                {
793
                    QGraphicsEllipseItem* circleItem = new QGraphicsEllipseItem();
×
794
                    circleItem->setRect(
×
795
                            x * RECT_SIZE + RECT_PADDING + ITEM_PADDING,
×
796
                            y * RECT_SIZE + RECT_PADDING + ITEM_PADDING,
×
797
                            ITEM_SIZE - (2 * ITEM_PADDING),
798
                            ITEM_SIZE - (2 * ITEM_PADDING));
799
                    item = new RGBItem(circleItem);
×
800
                }
801
                else
802
                {
803
                    QGraphicsRectItem *rectItem = new QGraphicsRectItem();
×
804
                    rectItem->setRect(
×
805
                            x * RECT_SIZE + RECT_PADDING + ITEM_PADDING,
×
806
                            y * RECT_SIZE + RECT_PADDING + ITEM_PADDING,
×
807
                            ITEM_SIZE - (2 * ITEM_PADDING),
808
                            ITEM_SIZE - (2 * ITEM_PADDING));
809
                    item = new RGBItem(rectItem);
×
810
                }
811

812
                item->setColor(m_previewHandler->m_map[y][x]);
×
813
                item->draw(0, 0);
×
814
                m_scene->addItem(item->graphicsItem());
×
815
                m_previewHash[pt] = item;
×
816
            }
817
        }
818
    }
819
    return true;
820
}
821

822
void RGBMatrixEditor::slotPreviewTimeout()
×
823
{
824
    if (m_matrix->duration() <= 0)
×
825
        return;
826

827
    m_previewIterator += MasterTimer::tick();
×
828
    uint elapsed = 0;
829
    while (m_previewIterator >= MAX(m_matrix->duration(), MasterTimer::tick()))
×
830
    {
NEW
831
        m_previewHandler->checkNextStep(m_matrix->runOrder(), m_matrix->getColor(0),
×
NEW
832
                                        m_matrix->getColor(1), m_matrix->stepsCount());
×
833

834
        m_matrix->previewMap(m_previewHandler->currentStepIndex(), m_previewHandler);
×
835

836
        m_previewIterator -= MAX(m_matrix->duration(), MasterTimer::tick());
×
837
        elapsed += MAX(m_matrix->duration(), MasterTimer::tick());
×
838
    }
839
    for (int y = 0; y < m_previewHandler->m_map.size(); y++)
×
840
    {
841
        for (int x = 0; x < m_previewHandler->m_map[y].size(); x++)
×
842
        {
843
            QLCPoint pt(x, y);
×
844
            if (m_previewHash.contains(pt) == true)
×
845
            {
846
                RGBItem* shape = m_previewHash[pt];
×
847
                if (shape->color() != QColor(m_previewHandler->m_map[y][x]).rgb())
×
848
                    shape->setColor(m_previewHandler->m_map[y][x]);
×
849

850
                if (shape->color() == QColor(Qt::black).rgb())
×
851
                    shape->draw(elapsed, m_matrix->fadeOutSpeed());
×
852
                else
853
                    shape->draw(elapsed, m_matrix->fadeInSpeed());
×
854
            }
855
        }
856
    }
857
}
858

859
void RGBMatrixEditor::slotNameEdited(const QString& text)
×
860
{
861
    m_matrix->setName(text);
×
862
    if (m_speedDials != NULL)
×
863
        m_speedDials->setWindowTitle(text);
×
864
}
×
865

866
void RGBMatrixEditor::slotSpeedDialToggle(bool state)
×
867
{
868
    if (state == true)
×
869
        updateSpeedDials();
×
870
    else
871
    {
872
        if (m_speedDials != NULL)
×
873
            m_speedDials->deleteLater();
×
874
        m_speedDials = NULL;
×
875
    }
876
}
×
877

878
void RGBMatrixEditor::slotDialDestroyed(QObject *)
×
879
{
880
    m_speedDialButton->setChecked(false);
×
881
}
×
882

883
void RGBMatrixEditor::slotPatternActivated(int patternIndex)
×
884
{
885
    QString algoName = m_patternCombo->itemText(patternIndex);
×
886
    RGBAlgorithm *algo = RGBAlgorithm::algorithm(m_doc, algoName);
×
887
    m_matrix->setAlgorithm(algo);
×
NEW
888
    if (algo != NULL) {
×
NEW
889
        updateColors();
×
890
#if (5 != RGBAlgorithmColorDisplayCount)
891
#error "Further colors need to be displayed."
892
#endif
893
        QVector<QColor> colors = {
NEW
894
                m_matrix->getColor(0),
×
NEW
895
                m_matrix->getColor(1),
×
NEW
896
                m_matrix->getColor(2),
×
NEW
897
                m_matrix->getColor(3),
×
NEW
898
                m_matrix->getColor(4)
×
NEW
899
        };
×
NEW
900
        algo->setColors(colors);
×
NEW
901
        m_previewHandler->calculateColorDelta(m_matrix->getColor(0), m_matrix->getColor(1),
×
NEW
902
                m_matrix->algorithm());
×
903
    }
UNCOV
904
    updateExtraOptions();
×
905

906
    slotRestartTest();
×
907
}
×
908

909
void RGBMatrixEditor::slotFixtureGroupActivated(int index)
×
910
{
911
    QVariant var = m_fixtureGroupCombo->itemData(index);
×
912
    if (var.isValid() == true)
×
913
    {
914
        m_matrix->setFixtureGroup(var.toUInt());
×
915
        slotRestartTest();
×
916
    }
917
    else
918
    {
919
        m_matrix->setFixtureGroup(FixtureGroup::invalidId());
×
920
        m_previewTimer->stop();
×
921
        m_scene->clear();
×
922
    }
923
}
×
924

925
void RGBMatrixEditor::slotBlendModeChanged(int index)
×
926
{
927
    m_matrix->setBlendMode(Universe::BlendMode(index));
×
928

929
    if (index == Universe::MaskBlend)
×
930
    {
NEW
931
        m_mtxColor1Button->setEnabled(false);
×
932
    }
933
    else
934
    {
NEW
935
        m_mtxColor1Button->setEnabled(true);
×
936
    }
937
    updateExtraOptions();
×
938
    updateColors();
×
939
    slotRestartTest();
×
940
}
×
941

942
void RGBMatrixEditor::slotControlModeChanged(int index)
×
943
{
944
    RGBMatrix::ControlMode mode = RGBMatrix::ControlMode(index);
×
945
    m_matrix->setControlMode(mode);
×
946
    updateColors();
×
947
    slotRestartTest();
×
948
}
×
949

NEW
950
void RGBMatrixEditor::slotMtxColor1ButtonClicked()
×
951
{
NEW
952
    QColor col = QColorDialog::getColor(m_matrix->getColor(0));
×
NEW
953
    if (col.isValid() == true)
×
954
    {
NEW
955
        m_matrix->setColor(0, col);
×
NEW
956
        updateColors();
×
NEW
957
        slotRestartTest();
×
958
    }
NEW
959
}
×
960

NEW
961
void RGBMatrixEditor::slotMtxColor2ButtonClicked()
×
962
{
NEW
963
    QColor col = QColorDialog::getColor(m_matrix->getColor(1));
×
NEW
964
    if (col.isValid() == true)
×
965
    {
NEW
966
        m_matrix->setColor(1, col);
×
NEW
967
        updateColors();
×
NEW
968
        slotRestartTest();
×
969
    }
NEW
970
}
×
971

NEW
972
void RGBMatrixEditor::slotResetMtxColor2ButtonClicked()
×
973
{
NEW
974
    m_matrix->setColor(1, QColor());
×
NEW
975
    updateColors();
×
NEW
976
    slotRestartTest();
×
NEW
977
}
×
978

NEW
979
void RGBMatrixEditor::slotMtxColor3ButtonClicked()
×
980
{
NEW
981
    QColor col = QColorDialog::getColor(m_matrix->getColor(2));
×
NEW
982
    if (col.isValid() == true)
×
983
    {
NEW
984
        m_matrix->setColor(2, col);
×
NEW
985
        updateColors();
×
NEW
986
        slotRestartTest();
×
987
    }
NEW
988
}
×
989

NEW
990
void RGBMatrixEditor::slotResetMtxColor3ButtonClicked()
×
991
{
NEW
992
    m_matrix->setColor(2, QColor());
×
NEW
993
    updateColors();
×
NEW
994
    slotRestartTest();
×
NEW
995
}
×
996

NEW
997
void RGBMatrixEditor::slotMtxColor4ButtonClicked()
×
998
{
NEW
999
    QColor col = QColorDialog::getColor(m_matrix->getColor(3));
×
1000
    if (col.isValid() == true)
×
1001
    {
NEW
1002
        m_matrix->setColor(3, col);
×
1003
        updateColors();
×
1004
        slotRestartTest();
×
1005
    }
1006
}
×
1007

NEW
1008
void RGBMatrixEditor::slotResetMtxColor4ButtonClicked()
×
1009
{
NEW
1010
    m_matrix->setColor(3, QColor());
×
NEW
1011
    updateColors();
×
NEW
1012
    slotRestartTest();
×
NEW
1013
}
×
1014

NEW
1015
void RGBMatrixEditor::slotMtxColor5ButtonClicked()
×
1016
{
NEW
1017
    QColor col = QColorDialog::getColor(m_matrix->getColor(4));
×
1018
    if (col.isValid() == true)
×
1019
    {
NEW
1020
        m_matrix->setColor(4, col);
×
1021
        updateColors();
×
1022
        slotRestartTest();
×
1023
    }
1024
}
×
1025

NEW
1026
void RGBMatrixEditor::slotResetMtxColor5ButtonClicked()
×
1027
{
NEW
1028
    m_matrix->setColor(4, QColor());
×
1029
    updateColors();
×
1030
    slotRestartTest();
×
1031
}
×
1032

1033
void RGBMatrixEditor::slotTextEdited(const QString& text)
×
1034
{
1035
    if (m_matrix->algorithm() != NULL && m_matrix->algorithm()->type() == RGBAlgorithm::Text)
×
1036
    {
1037
        RGBText *algo = static_cast<RGBText*> (m_matrix->algorithm());
×
1038
        Q_ASSERT(algo != NULL);
1039
        {
1040
            QMutexLocker algorithmLocker(&m_matrix->algorithmMutex());
×
1041
            algo->setText(text);
×
1042
        }
1043
        slotRestartTest();
×
1044
    }
1045
}
×
1046

1047
void RGBMatrixEditor::slotFontButtonClicked()
×
1048
{
1049
    if (m_matrix->algorithm() != NULL && m_matrix->algorithm()->type() == RGBAlgorithm::Text)
×
1050
    {
1051
        RGBText *algo = static_cast<RGBText*> (m_matrix->algorithm());
×
1052
        Q_ASSERT(algo != NULL);
1053

1054
        bool ok = false;
×
1055
        QFont font = QFontDialog::getFont(&ok, algo->font(), this);
×
1056
        if (ok == true)
×
1057
        {
1058
            {
1059
                QMutexLocker algorithmLocker(&m_matrix->algorithmMutex());
×
1060
                algo->setFont(font);
×
1061
            }
1062
            slotRestartTest();
×
1063
        }
1064
    }
1065
}
×
1066

1067
void RGBMatrixEditor::slotAnimationActivated(int index)
×
1068
{
1069
    if (m_matrix->algorithm() != NULL && m_matrix->algorithm()->type() == RGBAlgorithm::Text)
×
1070
    {
1071
        RGBText *algo = static_cast<RGBText*> (m_matrix->algorithm());
×
1072
        Q_ASSERT(algo != NULL);
1073
        {
1074
            QMutexLocker algorithmLocker(&m_matrix->algorithmMutex());
×
1075
            QString text = m_animationCombo->itemText(index);
×
1076
            algo->setAnimationStyle(RGBText::stringToAnimationStyle(text));
×
1077
        }
1078
        slotRestartTest();
×
1079
    }
1080
}
×
1081

1082
void RGBMatrixEditor::slotImageEdited()
×
1083
{
1084
    if (m_matrix->algorithm() != NULL && m_matrix->algorithm()->type() == RGBAlgorithm::Image)
×
1085
    {
1086
        RGBImage *algo = static_cast<RGBImage*> (m_matrix->algorithm());
×
1087
        Q_ASSERT(algo != NULL);
1088
        {
1089
            QMutexLocker algorithmLocker(&m_matrix->algorithmMutex());
×
1090
            algo->setFilename(m_imageEdit->text());
×
1091
        }
1092
        slotRestartTest();
×
1093
    }
1094
}
×
1095

1096
void RGBMatrixEditor::slotImageButtonClicked()
×
1097
{
1098
    if (m_matrix->algorithm() != NULL && m_matrix->algorithm()->type() == RGBAlgorithm::Image)
×
1099
    {
1100
        RGBImage *algo = static_cast<RGBImage*> (m_matrix->algorithm());
×
1101
        Q_ASSERT(algo != NULL);
1102

1103
        QString path = algo->filename();
×
1104
        path = QFileDialog::getOpenFileName(this,
×
1105
                                            tr("Select image"),
×
1106
                                            path,
1107
                                            QString("%1 (*.png *.bmp *.jpg *.jpeg *.gif)").arg(tr("Images")));
×
1108
        if (path.isEmpty() == false)
×
1109
        {
1110
            {
1111
                QMutexLocker algorithmLocker(&m_matrix->algorithmMutex());
×
1112
                algo->setFilename(path);
×
1113
            }
1114
            m_imageEdit->setText(path);
×
1115
            slotRestartTest();
×
1116
        }
1117
    }
1118
}
×
1119

1120
void RGBMatrixEditor::slotImageAnimationActivated(int index)
×
1121
{
1122
    if (m_matrix->algorithm() != NULL && m_matrix->algorithm()->type() == RGBAlgorithm::Image)
×
1123
    {
1124
        RGBImage *algo = static_cast<RGBImage*> (m_matrix->algorithm());
×
1125
        Q_ASSERT(algo != NULL);
1126
        {
1127
            QMutexLocker algorithmLocker(&m_matrix->algorithmMutex());
×
1128
            QString text = m_imageAnimationCombo->itemText(index);
×
1129
            algo->setAnimationStyle(RGBImage::stringToAnimationStyle(text));
×
1130
        }
1131
        slotRestartTest();
×
1132
    }
1133
}
×
1134

1135
void RGBMatrixEditor::slotOffsetSpinChanged()
×
1136
{
1137
    if (m_matrix->algorithm() != NULL && m_matrix->algorithm()->type() == RGBAlgorithm::Text)
×
1138
    {
1139
        RGBText *algo = static_cast<RGBText*> (m_matrix->algorithm());
×
1140
        Q_ASSERT(algo != NULL);
1141
        {
1142
            QMutexLocker algorithmLocker(&m_matrix->algorithmMutex());
×
1143
            algo->setXOffset(m_xOffsetSpin->value());
×
1144
            algo->setYOffset(m_yOffsetSpin->value());
×
1145
        }
1146
        slotRestartTest();
×
1147
    }
1148

1149
    if (m_matrix->algorithm() != NULL && m_matrix->algorithm()->type() == RGBAlgorithm::Image)
×
1150
    {
1151
        RGBImage *algo = static_cast<RGBImage*> (m_matrix->algorithm());
×
1152
        Q_ASSERT(algo != NULL);
1153
        {
1154
            QMutexLocker algorithmLocker(&m_matrix->algorithmMutex());
×
1155
            algo->setXOffset(m_xOffsetSpin->value());
×
1156
            algo->setYOffset(m_yOffsetSpin->value());
×
1157
        }
1158
        slotRestartTest();
×
1159
    }
1160
}
×
1161

1162
void RGBMatrixEditor::slotLoopClicked()
×
1163
{
1164
    m_matrix->setRunOrder(Function::Loop);
×
NEW
1165
    m_previewHandler->calculateColorDelta(m_matrix->getColor(0), m_matrix->getColor(1),
×
NEW
1166
            m_matrix->algorithm());
×
1167
    slotRestartTest();
×
1168
}
×
1169

1170
void RGBMatrixEditor::slotPingPongClicked()
×
1171
{
1172
    m_matrix->setRunOrder(Function::PingPong);
×
NEW
1173
    m_previewHandler->calculateColorDelta(m_matrix->getColor(0), m_matrix->getColor(1),
×
NEW
1174
            m_matrix->algorithm());
×
1175
    slotRestartTest();
×
1176
}
×
1177

1178
void RGBMatrixEditor::slotSingleShotClicked()
×
1179
{
1180
    m_matrix->setRunOrder(Function::SingleShot);
×
NEW
1181
    m_previewHandler->calculateColorDelta(m_matrix->getColor(0), m_matrix->getColor(1),
×
NEW
1182
            m_matrix->algorithm());
×
1183
    slotRestartTest();
×
1184
}
×
1185

1186
void RGBMatrixEditor::slotForwardClicked()
×
1187
{
1188
    m_matrix->setDirection(Function::Forward);
×
NEW
1189
    m_previewHandler->calculateColorDelta(m_matrix->getColor(0), m_matrix->getColor(1),
×
NEW
1190
            m_matrix->algorithm());
×
1191
    slotRestartTest();
×
1192
}
×
1193

1194
void RGBMatrixEditor::slotBackwardClicked()
×
1195
{
1196
    m_matrix->setDirection(Function::Backward);
×
NEW
1197
    m_previewHandler->calculateColorDelta(m_matrix->getColor(0), m_matrix->getColor(1),
×
NEW
1198
            m_matrix->algorithm());
×
1199
    slotRestartTest();
×
1200
}
×
1201

1202
void RGBMatrixEditor::slotDimmerControlClicked()
×
1203
{
1204
    m_matrix->setDimmerControl(m_dimmerControlCb->isChecked());
×
1205
    if (m_dimmerControlCb->isChecked() == false)
×
1206
        m_dimmerControlCb->setEnabled(false);
×
1207
}
×
1208

1209
void RGBMatrixEditor::slotFadeInChanged(int ms)
×
1210
{
1211
    m_matrix->setFadeInSpeed(ms);
×
1212
    uint duration = Function::speedAdd(ms, m_speedDials->duration());
×
1213
    m_matrix->setDuration(duration);
×
1214
}
×
1215

1216
void RGBMatrixEditor::slotFadeOutChanged(int ms)
×
1217
{
1218
    m_matrix->setFadeOutSpeed(ms);
×
1219
}
×
1220

1221
void RGBMatrixEditor::slotHoldChanged(int ms)
×
1222
{
1223
    uint duration = Function::speedAdd(m_matrix->fadeInSpeed(), ms);
×
1224
    m_matrix->setDuration(duration);
×
1225
}
×
1226

1227
void RGBMatrixEditor::slotDurationTapped()
×
1228
{
1229
    m_matrix->tap();
×
1230
}
×
1231

1232
void RGBMatrixEditor::slotTestClicked()
×
1233
{
1234
    if (m_testButton->isChecked() == true)
×
1235
        m_matrix->start(m_doc->masterTimer(), functionParent());
×
1236
    else
1237
        m_matrix->stopAndWait();
×
1238
}
×
1239

1240
void RGBMatrixEditor::slotRestartTest()
×
1241
{
1242
    m_previewTimer->stop();
×
1243

1244
    if (m_testButton->isChecked() == true)
×
1245
    {
1246
        // Toggle off, toggle on. Duh.
1247
        m_testButton->click();
×
1248
        m_testButton->click();
×
1249
    }
1250

1251
    if (createPreviewItems() == true)
×
1252
        m_previewTimer->start(MasterTimer::tick());
×
1253

1254
}
×
1255

1256
void RGBMatrixEditor::slotModeChanged(Doc::Mode mode)
×
1257
{
1258
    if (mode == Doc::Operate)
×
1259
    {
1260
        if (m_testButton->isChecked() == true)
×
1261
            m_matrix->stopAndWait();
×
1262
        m_testButton->setChecked(false);
×
1263
        m_testButton->setEnabled(false);
×
1264
    }
1265
    else
1266
    {
1267
        m_testButton->setEnabled(true);
×
1268
    }
1269
}
×
1270

1271
void RGBMatrixEditor::slotFixtureGroupAdded()
×
1272
{
1273
    fillFixtureGroupCombo();
×
1274
}
×
1275

1276
void RGBMatrixEditor::slotFixtureGroupRemoved()
×
1277
{
1278
    fillFixtureGroupCombo();
×
1279
    slotFixtureGroupActivated(m_fixtureGroupCombo->currentIndex());
×
1280
}
×
1281

1282
void RGBMatrixEditor::slotFixtureGroupChanged(quint32 id)
×
1283
{
1284
    if (id == m_matrix->fixtureGroup())
×
1285
    {
1286
        // Update the whole chain -> maybe the fixture layout has changed
1287
        fillFixtureGroupCombo();
×
1288
        slotFixtureGroupActivated(m_fixtureGroupCombo->currentIndex());
×
1289
    }
1290
    else
1291
    {
1292
        // Just change the name of the group, nothing else is interesting at this point
1293
        int index = m_fixtureGroupCombo->findData(id);
×
1294
        if (index != -1)
×
1295
        {
1296
            FixtureGroup* grp = m_doc->fixtureGroup(id);
×
1297
            m_fixtureGroupCombo->setItemText(index, grp->name());
×
1298
        }
1299
    }
1300
}
×
1301

1302
void RGBMatrixEditor::slotSaveToSequenceClicked()
×
1303
{
1304
    if (m_matrix == NULL || m_matrix->fixtureGroup() == FixtureGroup::invalidId())
×
1305
        return;
×
1306

1307
    FixtureGroup* grp = m_doc->fixtureGroup(m_matrix->fixtureGroup());
×
1308
    if (grp != NULL && m_matrix->algorithm() != NULL)
×
1309
    {
1310
        bool testRunning = false;
1311

1312
        if (m_testButton->isChecked() == true)
×
1313
        {
1314
            m_testButton->click();
×
1315
            testRunning = true;
1316
        }
1317
        else
1318
            m_previewTimer->stop();
×
1319

1320
        Scene *grpScene = new Scene(m_doc);
×
1321
        grpScene->setName(grp->name());
×
1322
        grpScene->setVisible(false);
×
1323

1324
        QList<GroupHead> headList = grp->headList();
×
1325
        foreach (GroupHead head, headList)
×
1326
        {
1327
            Fixture *fxi = m_doc->fixture(head.fxi);
×
1328
            if (fxi == NULL)
×
1329
                continue;
×
1330

1331
            if (m_controlModeCombo->currentIndex() == RGBMatrix::ControlModeRgb)
×
1332
            {
1333

1334
                    QVector <quint32> rgb = fxi->rgbChannels(head.head);
×
1335

1336
                    // in case of CMY, dump those channels
1337
                    if (rgb.count() == 0)
×
1338
                        rgb = fxi->cmyChannels(head.head);
×
1339

1340
                    if (rgb.count() == 3)
×
1341
                    {
1342
                        grpScene->setValue(head.fxi, rgb.at(0), 0);
×
1343
                        grpScene->setValue(head.fxi, rgb.at(1), 0);
×
1344
                        grpScene->setValue(head.fxi, rgb.at(2), 0);
×
1345
                    }
1346
            }
1347
            else if (m_controlModeCombo->currentIndex() == RGBMatrix::ControlModeDimmer)
×
1348
            {
1349
                quint32 channel = fxi->masterIntensityChannel();
×
1350

1351
                if (channel == QLCChannel::invalid())
×
1352
                    channel = fxi->channelNumber(QLCChannel::Intensity, QLCChannel::MSB, head.head);
×
1353

1354
                if (channel != QLCChannel::invalid())
×
1355
                    grpScene->setValue(head.fxi, channel, 0);
×
1356
            }
1357
            else
1358
            {
1359
                quint32 channel = QLCChannel::invalid();
×
1360
                if (m_controlModeCombo->currentIndex() == RGBMatrix::ControlModeWhite)
×
1361
                    channel = fxi->channelNumber(QLCChannel::White, QLCChannel::MSB, head.head);
×
1362
                else if (m_controlModeCombo->currentIndex() == RGBMatrix::ControlModeAmber)
×
1363
                    channel = fxi->channelNumber(QLCChannel::Amber, QLCChannel::MSB, head.head);
×
1364
                else if (m_controlModeCombo->currentIndex() == RGBMatrix::ControlModeUV)
×
1365
                    channel = fxi->channelNumber(QLCChannel::UV, QLCChannel::MSB, head.head);
×
1366
                else if (m_controlModeCombo->currentIndex() == RGBMatrix::ControlModeShutter)
×
1367
                {
1368
                    QLCFixtureHead fHead = fxi->head(head.head);
×
1369
                    QVector <quint32> shutters = fHead.shutterChannels();
×
1370
                    if (shutters.count())
×
1371
                        channel = shutters.first();
×
1372
                }
1373

1374
                if (channel != QLCChannel::invalid())
×
1375
                    grpScene->setValue(head.fxi, channel, 0);
×
1376
            }
1377
        }
1378
        m_doc->addFunction(grpScene);
×
1379

1380
        int totalSteps = m_matrix->stepsCount();
×
1381
        int increment = 1;
1382
        int currentStep = 0;
NEW
1383
        m_previewHandler->setStepColor(m_matrix->getColor(0));
×
1384

1385
        if (m_matrix->direction() == Function::Backward)
×
1386
        {
1387
            currentStep = totalSteps - 1;
×
1388
            increment = -1;
NEW
1389
            if (m_matrix->getColor(1).isValid())
×
NEW
1390
                m_previewHandler->setStepColor(m_matrix->getColor(1));
×
1391
        }
NEW
1392
        m_previewHandler->calculateColorDelta(m_matrix->getColor(0), m_matrix->getColor(1),
×
NEW
1393
                m_matrix->algorithm());
×
1394

1395
        if (m_matrix->runOrder() == RGBMatrix::PingPong)
×
1396
            totalSteps = (totalSteps * 2) - 1;
×
1397

1398
        Sequence *sequence = new Sequence(m_doc);
×
1399
        sequence->setName(QString("%1 %2").arg(m_matrix->name()).arg(tr("Sequence")));
×
1400
        sequence->setBoundSceneID(grpScene->id());
×
1401
        sequence->setDurationMode(Chaser::PerStep);
×
1402
        sequence->setDuration(m_matrix->duration());
×
1403

1404
        if (m_matrix->fadeInSpeed() != 0)
×
1405
        {
1406
            sequence->setFadeInMode(Chaser::PerStep);
×
1407
            sequence->setFadeInSpeed(m_matrix->fadeInSpeed());
×
1408
        }
1409
        if (m_matrix->fadeOutSpeed() != 0)
×
1410
        {
1411
            sequence->setFadeOutMode(Chaser::PerStep);
×
1412
            sequence->setFadeOutSpeed(m_matrix->fadeOutSpeed());
×
1413
        }
1414

1415
        for (int i = 0; i < totalSteps; i++)
×
1416
        {
1417
            m_matrix->previewMap(currentStep, m_previewHandler);
×
1418
            ChaserStep step;
×
1419
            step.fid = grpScene->id();
×
1420
            step.hold = m_matrix->duration() - m_matrix->fadeInSpeed();
×
1421
            step.duration = m_matrix->duration();
×
1422
            step.fadeIn = m_matrix->fadeInSpeed();
×
1423
            step.fadeOut = m_matrix->fadeOutSpeed();
×
1424

1425
            for (int y = 0; y < m_previewHandler->m_map.size(); y++)
×
1426
            {
1427
                for (int x = 0; x < m_previewHandler->m_map[y].size(); x++)
×
1428
                {
1429
                    uint col = m_previewHandler->m_map[y][x];
×
1430
                    GroupHead head = grp->head(QLCPoint(x, y));
×
1431

1432
                    Fixture *fxi = m_doc->fixture(head.fxi);
×
1433
                    if (fxi == NULL)
×
1434
                        continue;
×
1435

1436
                    if (m_controlModeCombo->currentIndex() == RGBMatrix::ControlModeRgb)
×
1437
                    {
1438
                        QVector <quint32> rgb = fxi->rgbChannels(head.head);
×
1439
                        QVector <quint32> cmy = fxi->cmyChannels(head.head);
×
1440

1441
                        if (rgb.count() == 3)
×
1442
                        {
1443
                            step.values.append(SceneValue(head.fxi, rgb.at(0), qRed(col)));
×
1444
                            step.values.append(SceneValue(head.fxi, rgb.at(1), qGreen(col)));
×
1445
                            step.values.append(SceneValue(head.fxi, rgb.at(2), qBlue(col)));
×
1446
                        }
1447

1448
                        if (cmy.count() == 3)
×
1449
                        {
1450
                            QColor cmyCol(col);
×
1451

1452
                            step.values.append(SceneValue(head.fxi, cmy.at(0), cmyCol.cyan()));
×
1453
                            step.values.append(SceneValue(head.fxi, cmy.at(1), cmyCol.magenta()));
×
1454
                            step.values.append(SceneValue(head.fxi, cmy.at(2), cmyCol.yellow()));
×
1455
                        }
1456
                    }
1457
                    else if (m_controlModeCombo->currentIndex() == RGBMatrix::ControlModeDimmer)
×
1458
                    {
1459
                        quint32 channel = fxi->masterIntensityChannel();
×
1460

1461
                        if (channel == QLCChannel::invalid())
×
1462
                            channel = fxi->channelNumber(QLCChannel::Intensity, QLCChannel::MSB, head.head);
×
1463

1464
                        if (channel != QLCChannel::invalid())
×
1465
                            step.values.append(SceneValue(head.fxi, channel, RGBMatrix::rgbToGrey(col)));
×
1466
                    }
1467
                    else
1468
                    {
1469
                        quint32 channel = QLCChannel::invalid();
×
1470
                        if (m_controlModeCombo->currentIndex() == RGBMatrix::ControlModeWhite)
×
1471
                            channel = fxi->channelNumber(QLCChannel::White, QLCChannel::MSB, head.head);
×
1472
                        else if (m_controlModeCombo->currentIndex() == RGBMatrix::ControlModeAmber)
×
1473
                            channel = fxi->channelNumber(QLCChannel::Amber, QLCChannel::MSB, head.head);
×
1474
                        else if (m_controlModeCombo->currentIndex() == RGBMatrix::ControlModeUV)
×
1475
                            channel = fxi->channelNumber(QLCChannel::UV, QLCChannel::MSB, head.head);
×
1476
                        else if (m_controlModeCombo->currentIndex() == RGBMatrix::ControlModeShutter)
×
1477
                        {
1478
                            QLCFixtureHead fHead = fxi->head(head.head);
×
1479
                            QVector <quint32> shutters = fHead.shutterChannels();
×
1480
                            if (shutters.count())
×
1481
                                channel = shutters.first();
×
1482
                        }
1483

1484
                        if (channel != QLCChannel::invalid())
×
1485
                            step.values.append(SceneValue(head.fxi, channel, RGBMatrix::rgbToGrey(col)));
×
1486
                    }
1487
                }
1488
            }
1489
            // !! Important !! matrix's heads can be displaced randomly but in a sequence
1490
            // we absolutely need ordered values. So do it now !
1491
            std::sort(step.values.begin(), step.values.end());
1492

1493
            sequence->addStep(step);
×
1494
            currentStep += increment;
×
1495
            if (currentStep == totalSteps && m_matrix->runOrder() == RGBMatrix::PingPong)
×
1496
            {
1497
                currentStep = totalSteps - 2;
×
1498
                increment = -1;
1499
            }
NEW
1500
            m_previewHandler->updateStepColor(currentStep, m_matrix->getColor(0), m_matrix->stepsCount());
×
1501
        }
1502

1503
        m_doc->addFunction(sequence);
×
1504

1505
        if (testRunning == true)
×
1506
            m_testButton->click();
×
1507
        else if (createPreviewItems() == true)
×
1508
            m_previewTimer->start(MasterTimer::tick());
×
1509
    }
1510
}
1511

1512
void RGBMatrixEditor::slotShapeToggle(bool)
×
1513
{
1514
    createPreviewItems();
×
1515
}
×
1516

1517
void RGBMatrixEditor::slotPropertyComboChanged(QString value)
×
1518
{
1519
    qDebug() << "Property combo changed to" << value;
1520
    if (m_matrix->algorithm() == NULL ||
×
1521
        m_matrix->algorithm()->type() == RGBAlgorithm::Script)
×
1522
    {
1523
        QComboBox *combo = qobject_cast<QComboBox *>(sender());
×
1524
        QString pName = combo->property("pName").toString();
×
1525
        m_matrix->setProperty(pName, value);
×
1526
    }
1527
}
×
1528

1529
void RGBMatrixEditor::slotPropertySpinChanged(int value)
×
1530
{
1531
    qDebug() << "Property spin changed to" << value;
1532
    if (m_matrix->algorithm() == NULL ||
×
1533
        m_matrix->algorithm()->type() == RGBAlgorithm::Script)
×
1534
    {
1535
        QSpinBox *spin = qobject_cast<QSpinBox *>(sender());
×
1536
        QString pName = spin->property("pName").toString();
×
1537
        m_matrix->setProperty(pName, QString::number(value));
×
1538
    }
1539
}
×
1540

1541
void RGBMatrixEditor::slotPropertyDoubleSpinChanged(double value)
×
1542
{
1543
    qDebug() << "Property float changed to" << value;
1544
    if (m_matrix->algorithm() == NULL ||
×
1545
        m_matrix->algorithm()->type() == RGBAlgorithm::Script)
×
1546
    {
1547
        QDoubleSpinBox *spin = qobject_cast<QDoubleSpinBox *>(sender());
×
1548
        QString pName = spin->property("pName").toString();
×
1549
        m_matrix->setProperty(pName, QString::number(value));
×
1550
    }
1551
}
×
1552

1553
void RGBMatrixEditor::slotPropertyEditChanged(QString text)
×
1554
{
1555
    qDebug() << "Property string changed to" << text;
1556
    if (m_matrix->algorithm() == NULL ||
×
1557
        m_matrix->algorithm()->type() == RGBAlgorithm::Script)
×
1558
    {
1559
        QLineEdit *edit = qobject_cast<QLineEdit *>(sender());
×
1560
        QString pName = edit->property("pName").toString();
×
1561
        m_matrix->setProperty(pName, text);
×
1562
    }
1563
}
×
1564

1565
FunctionParent RGBMatrixEditor::functionParent() const
×
1566
{
1567
    return FunctionParent::master();
×
1568
}
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