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

mcallegari / qlcplus / 16450929051

22 Jul 2025 05:09PM UTC coverage: 34.174% (-0.1%) from 34.286%
16450929051

Pull #1782

github

web-flow
Merge f80a306ab into 8a22b7b84
Pull Request #1782: Feature: Control RGB Matrix script properties with VC Knobs in animation widget

7 of 189 new or added lines in 6 files covered. (3.7%)

9 existing lines in 4 files now uncovered.

17704 of 51806 relevant lines covered (34.17%)

19373.32 hits per line

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

0.0
/ui/src/virtualconsole/vcmatrix.cpp
1
/*
2
  Q Light Controller Plus
3
  vcmatrix.cpp
4

5
  Copyright (c) Massimo Callegari
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 <QXmlStreamReader>
21
#include <QXmlStreamWriter>
22
#include <QWidgetAction>
23
#include <QComboBox>
24
#include <QSettings>
25
#include <QLayout>
26
#include <QDebug>
27
#include <QTimer>
28
#include <QLabel>
29
#include <QMenu>
30
#include <math.h>
31

32
#include "vcmatrixproperties.h"
33
#include "vcpropertieseditor.h"
34
#include "clickandgoslider.h"
35
#include "clickandgowidget.h"
36
#include "knobwidget.h"
37
#include "qlcmacros.h"
38
#include "rgbalgorithm.h"
39
#include "flowlayout.h"
40
#include "rgbmatrix.h"
41
#include "vcmatrix.h"
42
#include "function.h"
43
#include "rgbtext.h"
44
#include "doc.h"
45

46
#define UPDATE_TIMEOUT 50
47

48
static const QString controlBtnSS = "QPushButton { background-color: %1; height: 32px; border: 2px solid #6A6A6A; border-radius: 5px; }"
49
                                    "QPushButton:pressed { border: 2px solid #0000FF; }"
50
                                    "QPushButton:disabled { border: 2px solid #BBBBBB; color: #8f8f8f }";
51

52
const QSize VCMatrix::defaultSize(QSize(160, 120));
53

54
VCMatrix::VCMatrix(QWidget *parent, Doc *doc)
×
55
    : VCWidget(parent, doc)
56
    , m_sliderExternalMovement(false)
×
57
    , m_matrixID(Function::invalidId())
×
58
    , m_instantApply(true)
×
59
    , m_visibilityMask(VCMatrix::defaultVisibilityMask())
×
60
{
61
    /* Set the class name "VCMatrix" as the object name as well */
62
    setObjectName(VCMatrix::staticMetaObject.className());
×
63
    setFrameStyle(KVCFrameStyleSunken);
×
64

65
    QHBoxLayout *hBox = new QHBoxLayout(this);
×
66
    //hBox->setContentsMargins(3, 3, 3, 10);
67
    //hBox->setSpacing(5);
68

69
    m_slider = new ClickAndGoSlider();
×
70
    m_slider->setSliderStyleSheet(CNG_DEFAULT_STYLE);
×
71
    m_slider->setFixedWidth(32);
×
72
    m_slider->setRange(0, 255);
×
73
    m_slider->setPageStep(1);
×
74
    m_slider->setInvertedAppearance(false);
×
75
    hBox->addWidget(m_slider);
×
76

77
    connect(m_slider, SIGNAL(valueChanged(int)),
×
78
            this, SLOT(slotSliderMoved(int)));
79

80
    QVBoxLayout *vbox = new QVBoxLayout();
×
81

82
    /* Color 1 Button */
83
    m_mtxColor1Button = new QToolButton(this);
×
84
    m_mtxColor1Button->setFixedSize(48, 48);
×
85
    m_mtxColor1Button->setIconSize(QSize(42, 42));
×
86

87
    QWidgetAction* scAction = new QWidgetAction(this);
×
88
    m_mtxColor1CnGWidget = new ClickAndGoWidget();
×
89
    m_mtxColor1CnGWidget->setType(ClickAndGoWidget::RGB, NULL);
×
90
    scAction->setDefaultWidget(m_mtxColor1CnGWidget);
×
91
    QMenu *color1Menu = new QMenu();
×
92
    color1Menu->addAction(scAction);
×
93
    m_mtxColor1Button->setMenu(color1Menu);
×
94
    m_mtxColor1Button->setPopupMode(QToolButton::InstantPopup);
×
95

96
    connect(m_mtxColor1CnGWidget, SIGNAL(colorChanged(QRgb)),
×
97
            this, SLOT(slotColor1Changed(QRgb)));
98

99
    /* Color 2 Button */
100
    m_mtxColor2Button = new QToolButton(this);
×
101
    m_mtxColor2Button->setFixedSize(48, 48);
×
102
    m_mtxColor2Button->setIconSize(QSize(42, 42));
×
103

104
    QWidgetAction* ecAction2 = new QWidgetAction(this);
×
105
    m_mtxColor2CnGWidget = new ClickAndGoWidget();
×
106
    m_mtxColor2CnGWidget->setType(ClickAndGoWidget::RGB, NULL);
×
107
    ecAction2->setDefaultWidget(m_mtxColor2CnGWidget);
×
108
    QMenu *color2Menu = new QMenu();
×
109
    color2Menu->addAction(ecAction2);
×
110
    m_mtxColor2Button->setMenu(color2Menu);
×
111
    m_mtxColor2Button->setPopupMode(QToolButton::InstantPopup);
×
112

113
    connect(m_mtxColor2CnGWidget, SIGNAL(colorChanged(QRgb)),
×
114
            this, SLOT(slotColor2Changed(QRgb)));
115

116
    /* 3rd Color Button */
117
    m_mtxColor3Button = new QToolButton(this);
×
118
    m_mtxColor3Button->setFixedSize(48, 48);
×
119
    m_mtxColor3Button->setIconSize(QSize(42, 42));
×
120

121
    QWidgetAction* ecAction3 = new QWidgetAction(this);
×
122
    m_mtxColor3CnGWidget = new ClickAndGoWidget();
×
123
    m_mtxColor3CnGWidget->setType(ClickAndGoWidget::RGB, NULL);
×
124
    ecAction3->setDefaultWidget(m_mtxColor3CnGWidget);
×
125
    QMenu *color3Menu = new QMenu();
×
126
    color3Menu->addAction(ecAction3);
×
127
    m_mtxColor3Button->setMenu(color3Menu);
×
128
    m_mtxColor3Button->setPopupMode(QToolButton::InstantPopup);
×
129

130
    connect(m_mtxColor3CnGWidget, SIGNAL(colorChanged(QRgb)),
×
131
            this, SLOT(slotColor3Changed(QRgb)));
132

133
    /* 4th Color Button */
134
    m_mtxColor4Button = new QToolButton(this);
×
135
    m_mtxColor4Button->setFixedSize(48, 48);
×
136
    m_mtxColor4Button->setIconSize(QSize(42, 42));
×
137

138
    QWidgetAction* ecAction4 = new QWidgetAction(this);
×
139
    m_mtxColor4CnGWidget = new ClickAndGoWidget();
×
140
    m_mtxColor4CnGWidget->setType(ClickAndGoWidget::RGB, NULL);
×
141
    ecAction4->setDefaultWidget(m_mtxColor4CnGWidget);
×
142
    QMenu *color4Menu = new QMenu();
×
143
    color4Menu->addAction(ecAction4);
×
144
    m_mtxColor4Button->setMenu(color4Menu);
×
145
    m_mtxColor4Button->setPopupMode(QToolButton::InstantPopup);
×
146

147
    connect(m_mtxColor4CnGWidget, SIGNAL(colorChanged(QRgb)),
×
148
            this, SLOT(slotColor4Changed(QRgb)));
149

150
    /* 5th Color Button */
151
    m_mtxColor5Button = new QToolButton(this);
×
152
    m_mtxColor5Button->setFixedSize(48, 48);
×
153
    m_mtxColor5Button->setIconSize(QSize(42, 42));
×
154

155
    QWidgetAction* ecAction5 = new QWidgetAction(this);
×
156
    m_mtxColor5CnGWidget = new ClickAndGoWidget();
×
157
    m_mtxColor5CnGWidget->setType(ClickAndGoWidget::RGB, NULL);
×
158
    ecAction5->setDefaultWidget(m_mtxColor5CnGWidget);
×
159
    QMenu *color5Menu = new QMenu();
×
160
    color5Menu->addAction(ecAction5);
×
161
    m_mtxColor5Button->setMenu(color5Menu);
×
162
    m_mtxColor5Button->setPopupMode(QToolButton::InstantPopup);
×
163

164
    connect(m_mtxColor5CnGWidget, SIGNAL(colorChanged(QRgb)),
×
165
            this, SLOT(slotColor5Changed(QRgb)));
166

167
    m_label = new QLabel(this);
×
168
    m_label->setAlignment(Qt::AlignCenter);
×
169
    m_label->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
×
170
    vbox->addWidget(m_label);
×
171

172
    QHBoxLayout *btnHbox = new QHBoxLayout();
×
173

174
    btnHbox->addWidget(m_mtxColor1Button);
×
175
    btnHbox->addWidget(m_mtxColor2Button);
×
176
    btnHbox->addWidget(m_mtxColor3Button);
×
177
    btnHbox->addWidget(m_mtxColor4Button);
×
178
    btnHbox->addWidget(m_mtxColor5Button);
×
179

180
    vbox->addLayout(btnHbox);
×
181

182
    m_presetCombo = new QComboBox(this);
×
183
    //m_presetCombo->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
184
    m_presetCombo->addItems(RGBAlgorithm::algorithms(m_doc));
×
185
    connect(m_presetCombo, SIGNAL(currentIndexChanged(int)),
×
186
            this, SLOT(slotAnimationChanged(int)));
187
    vbox->addWidget(m_presetCombo);
×
188

189
    hBox->addLayout(vbox);
×
190

191
    m_controlsLayout = new FlowLayout();
×
192
    vbox->addLayout(m_controlsLayout);
×
193

194
    setType(VCWidget::AnimationWidget);
×
195
    setCaption(QString());
×
196
    /* Initial size */
197
    QSettings settings;
×
198
    QVariant var = settings.value(SETTINGS_RGBMATRIX_SIZE);
×
199
    if (var.isValid() == true)
×
200
        resize(var.toSize());
×
201
    else
202
        resize(defaultSize);
×
203

204
    /* Update timer */
205
    m_updateTimer = new QTimer(this);
×
206
    connect(m_updateTimer, SIGNAL(timeout()),
×
207
            this, SLOT(slotUpdate()));
208
    m_updateTimer->setSingleShot(true);
×
209

210
    /* Update the slider according to current mode */
211
    slotModeChanged(m_doc->mode());
×
212
    setLiveEdit(m_liveEdit);
×
213
}
×
214

215
VCMatrix::~VCMatrix()
×
216
{
217
    foreach (VCMatrixControl* control, m_controls)
×
218
    {
219
        delete control;
×
220
    }
×
221
}
×
222

223
void VCMatrix::setID(quint32 id)
×
224
{
225
    VCWidget::setID(id);
×
226

227
    if (caption().isEmpty())
×
228
        setCaption(tr("Animation %1").arg(id));
×
229
}
×
230

231
/*********************************************************************
232
 * Clipboard
233
 *********************************************************************/
234

235
VCWidget *VCMatrix::createCopy(VCWidget *parent)
×
236
{
237
    Q_ASSERT(parent != NULL);
×
238

239
    VCMatrix* matrix = new VCMatrix(parent, m_doc);
×
240
    if (matrix->copyFrom(this) == false)
×
241
    {
242
        delete matrix;
×
243
        matrix = NULL;
×
244
    }
245

246
    return matrix;
×
247
}
248

249
bool VCMatrix::copyFrom(const VCWidget* widget)
×
250
{
251
    const VCMatrix* matrix = qobject_cast <const VCMatrix*> (widget);
×
252
    if (matrix == NULL)
×
253
        return false;
×
254

255
    /* Copy vcmatrix-specific stuff */
256
    setFunction(matrix->function());
×
257
    setInstantChanges(matrix->instantChanges());
×
258
    setVisibilityMask(matrix->visibilityMask());
×
259

260
    resetCustomControls();
×
261
    foreach (VCMatrixControl const* control, matrix->customControls())
×
262
    {
263
        addCustomControl(*control);
×
264
    }
×
265

266
    /* Copy common stuff */
267
    return VCWidget::copyFrom(widget);
×
268
}
269

270
/*********************************************************************
271
 * GUI
272
 *********************************************************************/
273

274
void VCMatrix::setCaption(const QString &text)
×
275
{
276
    VCWidget::setCaption(text);
×
277
    m_label->setText(text);
×
278
}
×
279

280
void VCMatrix::enableWidgetUI(bool enable)
×
281
{
282
    m_slider->setEnabled(enable);
×
283
    m_mtxColor1Button->setEnabled(enable);
×
284
    m_mtxColor2Button->setEnabled(enable);
×
285
    m_mtxColor3Button->setEnabled(enable);
×
286
    m_mtxColor4Button->setEnabled(enable);
×
287
    m_mtxColor5Button->setEnabled(enable);
×
288
    m_presetCombo->setEnabled(enable);
×
289

290
    foreach (QWidget *ctlBtn, m_controls.keys())
×
291
        ctlBtn->setEnabled(enable);
×
292

293
    // Update buttons state
294
    if (enable)
×
295
        slotUpdate();
×
296
}
×
297

298
void VCMatrix::slotSetSliderValue(int value)
×
299
{
300
    m_slider->setValue(value);
×
301
    slotSliderMoved(value);
×
302
}
×
303

304
void VCMatrix::slotSliderMoved(int value)
×
305
{
306
    Function* function = m_doc->function(m_matrixID);
×
307
    if (function == NULL || mode() == Doc::Design)
×
308
        return;
×
309

310
    if (m_sliderExternalMovement)
×
311
        return;
×
312

313
    if (value == 0)
×
314
    {
315
        // Make sure we ignore the fade out time
316
        adjustFunctionIntensity(function, 0);
×
317
        if (function->stopped() == false)
×
318
        {
319
            function->stop(functionParent());
×
320
            resetIntensityOverrideAttribute();
×
321
        }
322
    }
323
    else
324
    {
325
        qreal pIntensity = qreal(value) / qreal(UCHAR_MAX);
×
326
        emit functionStarting(m_matrixID, pIntensity);
×
327
        adjustFunctionIntensity(function, pIntensity * intensity());
×
328
        if (function->stopped() == true)
×
329
        {
330
            // TODO once #758 is fixed: function started by a fader -> override fade in time
331
            function->start(m_doc->masterTimer(), functionParent());
×
332
        }
333
    }
334

335
    emit sliderValueChanged(value);
×
336
}
337

338
int VCMatrix::sliderValue()
×
339
{
340
    return m_slider->value();
×
341
}
342

343
void VCMatrix::slotSetColor1(QColor color)
×
344
{
345
    RGBMatrix *matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
346
    if (matrix == NULL)
×
347
        return;
×
348

349
    if (matrix->getColor(0) != color)
×
350
    {
351
        matrix->setColor(0, color);
×
352
        emit mtxColor1Changed();
×
353
    }
354
}
355

356
void VCMatrix::slotSetColor2(QColor color)
×
357
{
358
    RGBMatrix *matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
359
    if (matrix == NULL)
×
360
        return;
×
361

362
    if (matrix->getColor(1) != color)
×
363
    {
364
        matrix->setColor(1, color);
×
365
        emit mtxColor2Changed();
×
366
    }
367
}
368

369
void VCMatrix::slotSetColor3(QColor color)
×
370
{
371
    RGBMatrix *matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
372
    if (matrix == NULL)
×
373
        return;
×
374

375
    if (matrix->getColor(2) != color)
×
376
    {
377
        matrix->setColor(2, color);
×
378
        emit mtxColor3Changed();
×
379
    }
380
}
381

382
void VCMatrix::slotSetColor4(QColor color)
×
383
{
384
    RGBMatrix *matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
385
    if (matrix == NULL)
×
386
        return;
×
387

388
    if (matrix->getColor(3) != color)
×
389
    {
390
        matrix->setColor(3, color);
×
391
        emit mtxColor4Changed();
×
392
    }
393
}
394

395
void VCMatrix::slotSetColor5(QColor color)
×
396
{
397
    RGBMatrix *matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
398
    if (matrix == NULL)
×
399
        return;
×
400

401
    if (matrix->getColor(4) != color)
×
402
    {
403
        matrix->setColor(4, color);
×
404
        emit mtxColor5Changed();
×
405
    }
406
}
407

408
QColor VCMatrix::mtxColor(int id)
×
409
{
410
    RGBMatrix *matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
411
    if (matrix == NULL)
×
412
        return QColor();
×
413

414
    return matrix->getColor(id);
×
415
}
416

417
void VCMatrix::slotColor1Changed(QRgb color)
×
418
{
419
    QColor col(color);
×
420
    slotSetColor1(col);
×
421
    QPixmap px(42, 42);
×
422
    px.fill(col);
×
423
    m_mtxColor1Button->setIcon(px);
×
424

425
    RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
426
    if (matrix == NULL || mode() == Doc::Design)
×
427
        return;
×
428

429
    matrix->setColor(0, col);
×
430
    if (instantChanges() == true)
×
431
        matrix->updateColorDelta();
×
432
}
×
433

434
void VCMatrix::slotColor2Changed(QRgb color)
×
435
{
436
    QColor col(color);
×
437
    slotSetColor2(col);
×
438
    QPixmap px(42, 42);
×
439
    px.fill(col);
×
440
    m_mtxColor2Button->setIcon(px);
×
441

442
    RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
443
    if (matrix == NULL || mode() == Doc::Design)
×
444
        return;
×
445

446
    matrix->setColor(1, col);
×
447
    if (instantChanges() == true)
×
448
        matrix->updateColorDelta();
×
449
}
×
450

451
void VCMatrix::slotColor3Changed(QRgb color)
×
452
{
453
    QColor col(color);
×
454
    slotSetColor3(col);
×
455
    QPixmap px(42, 42);
×
456
    px.fill(col);
×
457
    m_mtxColor3Button->setIcon(px);
×
458

459
    RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
460
    if (matrix == NULL || mode() == Doc::Design)
×
461
        return;
×
462

463
    matrix->setColor(2, col);
×
464
}
×
465

466
void VCMatrix::slotColor4Changed(QRgb color)
×
467
{
468
    QColor col(color);
×
469
    slotSetColor4(col);
×
470
    QPixmap px(42, 42);
×
471
    px.fill(col);
×
472
    m_mtxColor4Button->setIcon(px);
×
473

474
    RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
475
    if (matrix == NULL || mode() == Doc::Design)
×
476
        return;
×
477

478
    matrix->setColor(3, col);
×
479
}
×
480

481
void VCMatrix::slotColor5Changed(QRgb color)
×
482
{
483
    QColor col(color);
×
484
    slotSetColor5(col);
×
485
    QPixmap px(42, 42);
×
486
    px.fill(col);
×
487
    m_mtxColor5Button->setIcon(px);
×
488

489
    RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
490
    if (matrix == NULL || mode() == Doc::Design)
×
491
        return;
×
492

493
    matrix->setColor(4, col);
×
494
}
×
495

496
void VCMatrix::slotSetAnimationValue(QString name)
×
497
{
498
    for (int i = 0; i < m_presetCombo->count(); i++)
×
499
    {
500
        if (name == m_presetCombo->itemText(i))
×
501
        {
502
            m_presetCombo->setCurrentIndex(i);
×
503
            slotAnimationChanged(i);
×
504
            return;
×
505
        }
506
    }
507
}
508

509
void VCMatrix::slotAnimationChanged(int index)
×
510
{
511
    RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
512
    if (matrix == NULL || mode() == Doc::Design)
×
513
        return;
×
514

515
    QString pValue = m_presetCombo->itemText(index);
×
516
    RGBAlgorithm* algo = RGBAlgorithm::algorithm(m_doc, pValue);
×
517
    matrix->setAlgorithm(algo);
×
518
    if (instantChanges() == true)
×
519
        matrix->updateColorDelta();
×
520

521
    emit animationValueChanged(pValue);
×
522
}
×
523

524
QString VCMatrix::animationValue()
×
525
{
526
    return m_presetCombo->currentText();
×
527
}
528

529
void VCMatrix::setVisibilityMask(quint32 mask)
×
530
{
531
    if (mask & ShowSlider) m_slider->show();
×
532
    else m_slider->hide();
×
533

534
    if (mask & ShowLabel) m_label->show();
×
535
    else m_label->hide();
×
536

537
    if (mask & ShowColor1Button) m_mtxColor1Button->show();
×
538
    else m_mtxColor1Button->hide();
×
539

540
    if (mask & ShowColor2Button) m_mtxColor2Button->show();
×
541
    else m_mtxColor2Button->hide();
×
542

543
    if (mask & ShowColor3Button) m_mtxColor3Button->show();
×
544
    else m_mtxColor3Button->hide();
×
545

546
    if (mask & ShowColor4Button) m_mtxColor4Button->show();
×
547
    else m_mtxColor4Button->hide();
×
548

549
    if (mask & ShowColor5Button) m_mtxColor5Button->show();
×
550
    else m_mtxColor5Button->hide();
×
551

552
    if (mask & ShowPresetCombo) m_presetCombo->show();
×
553
    else m_presetCombo->hide();
×
554

555
    m_visibilityMask = mask;
×
556
}
×
557

558
quint32 VCMatrix::visibilityMask() const
×
559
{
560
    return m_visibilityMask;
×
561
}
562

563
quint32 VCMatrix::defaultVisibilityMask()
×
564
{
565
    return ShowSlider
566
        | ShowLabel
567
        | ShowPresetCombo
568
        | ShowColor1Button
569
        | ShowColor2Button
570
        | ShowColor3Button
571
        | ShowColor4Button
572
        | ShowColor5Button
×
573
        ;
574
}
575

576
/*********************************************************************
577
 * Properties
578
 *********************************************************************/
579

580
void VCMatrix::editProperties()
×
581
{
582
    VCMatrixProperties prop(this, m_doc);
×
583
    if (prop.exec() == QDialog::Accepted)
×
584
        m_doc->setModified();
×
585
}
×
586

587
/*************************************************************************
588
 * VCWidget-inherited
589
 *************************************************************************/
590

591
void VCMatrix::adjustIntensity(qreal val)
×
592
{
593
    VCWidget::adjustIntensity(val);
×
594
    this->slotSliderMoved(this->m_slider->value());
×
595
}
×
596

597
/*********************************************************************
598
 * Function attachment
599
 *********************************************************************/
600

601
void VCMatrix::setFunction(quint32 id)
×
602
{
603
    Function *old = m_doc->function(m_matrixID);
×
604
    if (old != NULL)
×
605
    {
606
        disconnect(old, SIGNAL(stopped(quint32)),
×
607
                this, SLOT(slotFunctionStopped()));
608
        disconnect(old, SIGNAL(changed(quint32)),
×
609
                this, SLOT(slotFunctionChanged()));
610
    }
611

612
    RGBMatrix* matrix = qobject_cast<RGBMatrix*> (m_doc->function(id));
×
613

614
    if (matrix == NULL)
×
615
        m_matrixID = Function::invalidId();
×
616
    else
617
    {
618
        m_matrixID = id;
×
619
        connect(matrix, SIGNAL(stopped(quint32)),
×
620
                this, SLOT(slotFunctionStopped()));
621
        connect(matrix, SIGNAL(changed(quint32)),
×
622
                this, SLOT(slotFunctionChanged()));
623
    }
624

625
    slotUpdate();
×
626
}
×
627

628
quint32 VCMatrix::function() const
×
629
{
630
    return m_matrixID;
×
631
}
632

633
void VCMatrix::notifyFunctionStarting(quint32 fid, qreal functionIntensity)
×
634
{
635
    if (mode() == Doc::Design)
×
636
        return;
×
637

638
    if (fid == m_matrixID)
×
639
        return;
×
640

641
    int value = SCALE(1.0 - functionIntensity,
×
642
            0, 1.0,
643
            m_slider->minimum(), m_slider->maximum());
644
    if (m_slider->value() > value)
×
645
    {
646
        m_sliderExternalMovement = true;
×
647
        m_slider->setValue(value);
×
648
        m_sliderExternalMovement = false;
×
649

650
        Function* function = m_doc->function(m_matrixID);
×
651
        if (function != NULL)
×
652
        {
653
            qreal pIntensity = qreal(value) / qreal(UCHAR_MAX);
×
654
            adjustFunctionIntensity(function, pIntensity * intensity());
×
655
            if (value == 0 && !function->stopped())
×
656
            {
657
                function->stop(functionParent());
×
658
                resetIntensityOverrideAttribute();
×
659
            }
660
        }
661
    }
662
}
663

664
void VCMatrix::slotFunctionStopped()
×
665
{
666
    m_slider->blockSignals(true);
×
667
    m_slider->setValue(0);
×
668
    resetIntensityOverrideAttribute();
×
669
    m_slider->blockSignals(false);
×
670
}
×
671

672
void VCMatrix::slotFunctionChanged()
×
673
{
674
    m_updateTimer->start(UPDATE_TIMEOUT);
×
675
}
×
676

677
void VCMatrix::slotUpdate()
×
678
{
679
    if (m_matrixID == Function::invalidId())
×
680
        return;
×
681

682
    RGBMatrix *matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
683
    if (matrix == NULL)
×
684
        return;
×
685

686
    QString algorithmName;
×
687
    RGBAlgorithm::Type algorithmType = RGBAlgorithm::Plain;
×
688
    QHash<QString, QString> algorithmProperties;
×
689
    QString algorithmText;
×
690

691
    {
692
        QMutexLocker locker(&matrix->algorithmMutex());
×
693

694
        RGBAlgorithm *algo = matrix->algorithm();
×
695
        if (algo != NULL)
×
696
        {
697
            algorithmName = algo->name();
×
698
            algorithmType = algo->type();
×
699
            if (algorithmType == RGBAlgorithm::Script)
×
700
            {
701
                algorithmProperties = reinterpret_cast<RGBScript*>(algo)->propertiesAsStrings();
×
702
            }
703
            else if (algorithmType == RGBAlgorithm::Text)
×
704
            {
705
                algorithmText = reinterpret_cast<RGBText*>(algo)->text();
×
706
            }
707
        }
708
    }
×
709

710
    // Color buttons
711
    QPixmap px(42, 42);
×
712
    px.fill(matrix->getColor(0));
×
713
    m_mtxColor1Button->setIcon(px);
×
714

715
    if (matrix->getColor(1) == QColor())
×
716
        px.fill(Qt::transparent);
×
717
    else
718
        px.fill(matrix->getColor(1));
×
719
    m_mtxColor2Button->setIcon(px);
×
720

721
    if (matrix->getColor(2) == QColor())
×
722
        px.fill(Qt::transparent);
×
723
    else
724
        px.fill(matrix->getColor(2));
×
725
    m_mtxColor3Button->setIcon(px);
×
726

727
    if (matrix->getColor(3) == QColor())
×
728
        px.fill(Qt::transparent);
×
729
    else
730
        px.fill(matrix->getColor(3));
×
731
    m_mtxColor4Button->setIcon(px);
×
732

733
    if (matrix->getColor(4) == QColor())
×
734
        px.fill(Qt::transparent);
×
735
    else
736
        px.fill(matrix->getColor(4));
×
737
    m_mtxColor5Button->setIcon(px);
×
738

739
    // Algo combo box
740
    if (algorithmName != QString())
×
741
    {
742
        m_presetCombo->blockSignals(true);
×
743
        m_presetCombo->setCurrentText(algorithmName);
×
744
        m_presetCombo->blockSignals(false);
×
745
    }
746

747
    // Custom Buttons
748
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
749
         it != m_controls.end(); ++it)
×
750
    {
751
        QWidget *widget = it.key();
×
752
        VCMatrixControl *control = it.value();
×
753

754
        if (control->m_type == VCMatrixControl::Color1Knob)
×
755
        {
756
            KnobWidget *knob = reinterpret_cast<KnobWidget*>(widget);
×
757
            int val = control->rgbToValue(matrix->getColor(0).rgb());
×
758
            if (knob->value() != val)
×
759
            {
760
                knob->blockSignals(true);
×
761
                knob->setValue(val);
×
762
                emit matrixControlKnobValueChanged(control->m_id, val);
×
763
                knob->blockSignals(false);
×
764
            }
765
        }
766
        else if (control->m_type == VCMatrixControl::Color2Knob)
×
767
        {
768
            KnobWidget *knob = reinterpret_cast<KnobWidget*>(widget);
×
769
            int val = control->rgbToValue(matrix->getColor(1).rgb());
×
770
            if (knob->value() != val)
×
771
            {
772
                knob->blockSignals(true);
×
773
                knob->setValue(val);
×
774
                emit matrixControlKnobValueChanged(control->m_id, val);
×
775
                knob->blockSignals(false);
×
776
            }
777
        }
778
        else if (control->m_type == VCMatrixControl::Color3Knob)
×
779
        {
780
            KnobWidget *knob = reinterpret_cast<KnobWidget*>(widget);
×
781
            int val = control->rgbToValue(matrix->getColor(2).rgb());
×
782
            if (knob->value() != val)
×
783
            {
784
                knob->blockSignals(true);
×
785
                knob->setValue(val);
×
786
                emit matrixControlKnobValueChanged(control->m_id, val);
×
787
                knob->blockSignals(false);
×
788
            }
789
        }
790
        else if (control->m_type == VCMatrixControl::Color4Knob)
×
791
        {
792
            KnobWidget *knob = reinterpret_cast<KnobWidget*>(widget);
×
793
            int val = control->rgbToValue(matrix->getColor(3).rgb());
×
794
            if (knob->value() != val)
×
795
            {
796
                knob->blockSignals(true);
×
797
                knob->setValue(val);
×
798
                emit matrixControlKnobValueChanged(control->m_id, val);
×
799
                knob->blockSignals(false);
×
800
            }
801
        }
802
        else if (control->m_type == VCMatrixControl::Color5Knob)
×
803
        {
804
            KnobWidget *knob = reinterpret_cast<KnobWidget*>(widget);
×
805
            int val = control->rgbToValue(matrix->getColor(4).rgb());
×
806
            if (knob->value() != val)
×
807
            {
808
                knob->blockSignals(true);
×
809
                knob->setValue(val);
×
810
                emit matrixControlKnobValueChanged(control->m_id, val);
×
811
                knob->blockSignals(false);
×
812
            }
813
        }
NEW
814
        else if (control->m_type == VCMatrixControl::AnimationKnob)
×
815
        {
NEW
816
            if (algorithmType == RGBAlgorithm::Script)
×
817
            {
NEW
818
                KnobWidget *knob = reinterpret_cast<KnobWidget*>(widget);
×
NEW
819
                RGBScript *script = static_cast<RGBScript*>(matrix->algorithm());
×
NEW
820
                QString propValue = script->property(control->m_resource);
×
NEW
821
                int val = 0;
×
822

NEW
823
                foreach (RGBScriptProperty prop, script->properties())
×
824
                {
NEW
825
                    if (prop.m_name == control->m_resource)
×
826
                    {
NEW
827
                        if (prop.m_type == RGBScriptProperty::List)
×
828
                        {
NEW
829
                            val = prop.m_listValues.indexOf(propValue);
×
830
                        }
831
                        else
832
                        {
NEW
833
                            val = propValue.toInt();
×
834
                        }
NEW
835
                        break;
×
836
                    }
NEW
837
                }
×
838

NEW
839
                if (knob->value() != val)
×
840
                {
NEW
841
                    knob->blockSignals(true);
×
NEW
842
                    knob->setValue(val);
×
NEW
843
                    emit matrixControlKnobValueChanged(control->m_id, val);
×
NEW
844
                    knob->blockSignals(false);
×
845
                }
NEW
846
            }
×
847
        }
UNCOV
848
        else if (control->m_type == VCMatrixControl::Color1)
×
849
        {
850
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
851
            button->setDown(matrix->getColor(0) == control->m_color);
×
852
        }
853
        else if (control->m_type == VCMatrixControl::Color2)
×
854
        {
855
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
856
            button->setDown(matrix->getColor(1) == control->m_color);
×
857
        }
858
        else if (control->m_type == VCMatrixControl::Color3)
×
859
        {
860
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
861
            button->setDown(matrix->getColor(2) == control->m_color);
×
862
        }
863
        else if (control->m_type == VCMatrixControl::Color4)
×
864
        {
865
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
866
            button->setDown(matrix->getColor(3) == control->m_color);
×
867
        }
868
        else if (control->m_type == VCMatrixControl::Color5)
×
869
        {
870
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
871
            button->setDown(matrix->getColor(4) == control->m_color);
×
872
        }
873
        else if (control->m_type == VCMatrixControl::Animation)
×
874
        {
875
            bool on = false;
×
876
            if (algorithmType == RGBAlgorithm::Script &&
×
877
                algorithmName == control->m_resource)
×
878
            {
879
                on = true;
×
880
                for (QMap<QString, QString>::const_iterator it = control->m_properties.begin();
×
881
                        it != control->m_properties.end(); ++it)
×
882
                {
883
                    if (algorithmProperties.value(it.key(), QString()) != it.value())
×
884
                        on = false;
×
885
                }
886
            }
887

888
            QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
889
            button->setDown(on);
×
890
        }
891
        else if (control->m_type == VCMatrixControl::Text)
×
892
        {
893
            bool on = false;
×
894
            if (algorithmType == RGBAlgorithm::Text &&
×
895
                algorithmText == control->m_resource)
×
896
            {
897
                on = true;
×
898
            }
899

900
            QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
901
            button->setDown(on);
×
902
        }
903
    }
904

905
    updateFeedback();
×
906
}
×
907

908
FunctionParent VCMatrix::functionParent() const
×
909
{
910
    return FunctionParent(FunctionParent::ManualVCWidget, id());
×
911
}
912

913
/*********************************************************************
914
 * Instant changes apply
915
 *********************************************************************/
916

917
void VCMatrix::setInstantChanges(bool instantly)
×
918
{
919
    m_instantApply = instantly;
×
920
}
×
921

922
bool VCMatrix::instantChanges() const
×
923
{
924
    return m_instantApply;
×
925
}
926

927
/*********************************************************************
928
 * Custom controls
929
 *********************************************************************/
930

931
void VCMatrix::addCustomControl(VCMatrixControl const& control)
×
932
{
933
    QWidget *controlWidget = NULL;
×
934

935
    if (control.m_type == VCMatrixControl::Color1)
×
936
    {
937
        QPushButton *controlButton = new QPushButton(this);
×
938
        controlWidget = controlButton;
×
939
        controlButton->setStyleSheet(controlBtnSS.arg(control.m_color.name()));
×
940
        controlButton->setFixedWidth(36);
×
941
        controlButton->setFocusPolicy(Qt::TabFocus);
×
942
        controlButton->setText("1");
×
943
    }
944
    else if (control.m_type == VCMatrixControl::Color2)
×
945
    {
946
        QPushButton *controlButton = new QPushButton(this);
×
947
        controlWidget = controlButton;
×
948
        controlButton->setStyleSheet(controlBtnSS.arg(control.m_color.name()));
×
949
        controlButton->setFixedWidth(36);
×
950
        controlButton->setFocusPolicy(Qt::TabFocus);
×
951
        controlButton->setText("2");
×
952
    }
953
    else if (control.m_type == VCMatrixControl::Color3)
×
954
    {
955
        QPushButton *controlButton = new QPushButton(this);
×
956
        controlWidget = controlButton;
×
957
        controlButton->setStyleSheet(controlBtnSS.arg(control.m_color.name()));
×
958
        controlButton->setFixedWidth(36);
×
959
        controlButton->setFocusPolicy(Qt::TabFocus);
×
960
        controlButton->setText("3");
×
961
    }
962
    else if (control.m_type == VCMatrixControl::Color4)
×
963
    {
964
        QPushButton *controlButton = new QPushButton(this);
×
965
        controlWidget = controlButton;
×
966
        controlButton->setStyleSheet(controlBtnSS.arg(control.m_color.name()));
×
967
        controlButton->setFixedWidth(36);
×
968
        controlButton->setFocusPolicy(Qt::TabFocus);
×
969
        controlButton->setText("4");
×
970
    }
971
    else if (control.m_type == VCMatrixControl::Color5)
×
972
    {
973
        QPushButton *controlButton = new QPushButton(this);
×
974
        controlWidget = controlButton;
×
975
        controlButton->setStyleSheet(controlBtnSS.arg(control.m_color.name()));
×
976
        controlButton->setFixedWidth(36);
×
977
        controlButton->setFocusPolicy(Qt::TabFocus);
×
978
        controlButton->setText("5");
×
979
    }
980
    else if (control.m_type == VCMatrixControl::Color2Reset)
×
981
    {
982
        QPushButton *controlButton = new QPushButton(this);
×
983
        controlWidget = controlButton;
×
984
        controlButton->setStyleSheet(controlBtnSS.arg("#BBBBBB"));
×
985
        controlButton->setMinimumWidth(36);
×
986
        controlButton->setMaximumWidth(80);
×
987
        controlButton->setFocusPolicy(Qt::TabFocus);
×
988
        QString btnLabel = tr("Color 2 Reset");
×
989
        controlButton->setToolTip(btnLabel);
×
990
        controlButton->setText(fontMetrics().elidedText(btnLabel, Qt::ElideRight, 72));
×
991
    }
×
992
    else if (control.m_type == VCMatrixControl::Color3Reset)
×
993
    {
994
        QPushButton *controlButton = new QPushButton(this);
×
995
        controlWidget = controlButton;
×
996
        controlButton->setStyleSheet(controlBtnSS.arg("#BBBBBB"));
×
997
        controlButton->setMinimumWidth(36);
×
998
        controlButton->setMaximumWidth(80);
×
999
        controlButton->setFocusPolicy(Qt::TabFocus);
×
1000
        QString btnLabel = tr("Color 3 Reset");
×
1001
        controlButton->setToolTip(btnLabel);
×
1002
        controlButton->setText(fontMetrics().elidedText(btnLabel, Qt::ElideRight, 72));
×
1003
    }
×
1004
    else if (control.m_type == VCMatrixControl::Color4Reset)
×
1005
    {
1006
        QPushButton *controlButton = new QPushButton(this);
×
1007
        controlWidget = controlButton;
×
1008
        controlButton->setStyleSheet(controlBtnSS.arg("#BBBBBB"));
×
1009
        controlButton->setMinimumWidth(36);
×
1010
        controlButton->setMaximumWidth(80);
×
1011
        controlButton->setFocusPolicy(Qt::TabFocus);
×
1012
        QString btnLabel = tr("Color 4 Reset");
×
1013
        controlButton->setToolTip(btnLabel);
×
1014
        controlButton->setText(fontMetrics().elidedText(btnLabel, Qt::ElideRight, 72));
×
1015
    }
×
1016
    else if (control.m_type == VCMatrixControl::Color5Reset)
×
1017
    {
1018
        QPushButton *controlButton = new QPushButton(this);
×
1019
        controlWidget = controlButton;
×
1020
        controlButton->setStyleSheet(controlBtnSS.arg("#BBBBBB"));
×
1021
        controlButton->setMinimumWidth(36);
×
1022
        controlButton->setMaximumWidth(80);
×
1023
        controlButton->setFocusPolicy(Qt::TabFocus);
×
1024
        QString btnLabel = tr("Color 5 Reset");
×
1025
        controlButton->setToolTip(btnLabel);
×
1026
        controlButton->setText(fontMetrics().elidedText(btnLabel, Qt::ElideRight, 72));
×
1027
    }
×
1028
    else if (control.m_type == VCMatrixControl::Animation ||
×
1029
             control.m_type == VCMatrixControl::Text)
×
1030
    {
1031
        QPushButton *controlButton = new QPushButton(this);
×
1032
        controlWidget = controlButton;
×
1033
        controlButton->setStyleSheet(controlBtnSS.arg("#BBBBBB"));
×
1034
        controlButton->setMinimumWidth(36);
×
1035
        controlButton->setMaximumWidth(80);
×
1036
        controlButton->setFocusPolicy(Qt::TabFocus);
×
1037
        QString btnLabel = control.m_resource;
×
1038
        if (!control.m_properties.isEmpty())
×
1039
        {
1040
            btnLabel += " (";
×
1041
            QMapIterator<QString, QString> it(control.m_properties);
×
1042
            while (it.hasNext())
×
1043
            {
1044
                it.next();
×
1045
                btnLabel += it.value();
×
1046
                if (it.hasNext())
×
1047
                    btnLabel += ",";
×
1048
            }
1049
            btnLabel += ")";
×
1050
        }
×
1051
        controlButton->setToolTip(btnLabel);
×
1052
        controlButton->setText(fontMetrics().elidedText(btnLabel, Qt::ElideRight, 72));
×
1053
    }
×
1054
    else if (control.m_type == VCMatrixControl::Color1Knob)
×
1055
    {
1056
        KnobWidget *controlKnob = new KnobWidget(this);
×
1057
        controlWidget = controlKnob;
×
1058
        controlKnob->setColor(control.m_color);
×
1059
        controlKnob->setFixedWidth(36);
×
1060
        controlKnob->setFixedHeight(36);
×
1061
        QString knobLabel;
×
1062
        if (control.m_color == Qt::red)
×
1063
            knobLabel = tr("Color 1 Red component");
×
1064
        else if (control.m_color == Qt::green)
×
1065
            knobLabel = tr("Color 1 Green component");
×
1066
        else if (control.m_color == Qt::blue)
×
1067
            knobLabel = tr("Color 1 Blue component");
×
1068
        controlKnob->setToolTip(knobLabel);
×
1069
    }
×
1070
    else if (control.m_type == VCMatrixControl::Color2Knob)
×
1071
    {
1072
        KnobWidget *controlKnob = new KnobWidget(this);
×
1073
        controlWidget = controlKnob;
×
1074
        controlKnob->setColor(control.m_color.darker(250));
×
1075
        controlKnob->setFixedWidth(36);
×
1076
        controlKnob->setFixedHeight(36);
×
1077
        QString knobLabel;
×
1078
        if (control.m_color == Qt::red)
×
1079
            knobLabel = tr("Color 2 Red component");
×
1080
        else if (control.m_color == Qt::green)
×
1081
            knobLabel = tr("Color 2 Green component");
×
1082
        else if (control.m_color == Qt::blue)
×
1083
            knobLabel = tr("Color 2 Blue component");
×
1084
        controlKnob->setToolTip(knobLabel);
×
1085
    }
×
1086
    else if (control.m_type == VCMatrixControl::Color3Knob)
×
1087
    {
1088
        KnobWidget *controlKnob = new KnobWidget(this);
×
1089
        controlWidget = controlKnob;
×
1090
        controlKnob->setColor(control.m_color.darker(250));
×
1091
        controlKnob->setFixedWidth(36);
×
1092
        controlKnob->setFixedHeight(36);
×
1093
        QString knobLabel;
×
1094
        if (control.m_color == Qt::red)
×
1095
            knobLabel = tr("Color 3 Red component");
×
1096
        else if (control.m_color == Qt::green)
×
1097
            knobLabel = tr("Color 3 Green component");
×
1098
        else if (control.m_color == Qt::blue)
×
1099
            knobLabel = tr("Color 3 Blue component");
×
1100
        controlKnob->setToolTip(knobLabel);
×
1101
    }
×
1102
    else if (control.m_type == VCMatrixControl::Color4Knob)
×
1103
    {
1104
        KnobWidget *controlKnob = new KnobWidget(this);
×
1105
        controlWidget = controlKnob;
×
1106
        controlKnob->setColor(control.m_color.darker(250));
×
1107
        controlKnob->setFixedWidth(36);
×
1108
        controlKnob->setFixedHeight(36);
×
1109
        QString knobLabel;
×
1110
        if (control.m_color == Qt::red)
×
1111
            knobLabel = tr("Color 4 Red component");
×
1112
        else if (control.m_color == Qt::green)
×
1113
            knobLabel = tr("Color 4 Green component");
×
1114
        else if (control.m_color == Qt::blue)
×
1115
            knobLabel = tr("Color 4 Blue component");
×
1116
        controlKnob->setToolTip(knobLabel);
×
1117
    }
×
1118
    else if (control.m_type == VCMatrixControl::Color5Knob)
×
1119
    {
1120
        KnobWidget *controlKnob = new KnobWidget(this);
×
1121
        controlWidget = controlKnob;
×
1122
        controlKnob->setColor(control.m_color.darker(250));
×
1123
        controlKnob->setFixedWidth(36);
×
1124
        controlKnob->setFixedHeight(36);
×
1125
        QString knobLabel;
×
1126
        if (control.m_color == Qt::red)
×
1127
            knobLabel = tr("Color 5 Red component");
×
1128
        else if (control.m_color == Qt::green)
×
1129
            knobLabel = tr("Color 5 Green component");
×
1130
        else if (control.m_color == Qt::blue)
×
1131
            knobLabel = tr("Color 5 Blue component");
×
1132
        controlKnob->setToolTip(knobLabel);
×
1133
    }
×
NEW
1134
    else if (control.m_type == VCMatrixControl::AnimationKnob)
×
1135
    {
NEW
1136
        KnobWidget *controlKnob = new KnobWidget(this);
×
NEW
1137
        controlWidget = controlKnob;
×
NEW
1138
        controlKnob->setColor(QColor(Qt::gray));
×
NEW
1139
        controlKnob->setFixedWidth(36);
×
NEW
1140
        controlKnob->setFixedHeight(36);
×
NEW
1141
        controlKnob->setToolTip(control.m_resource);
×
1142

NEW
1143
        RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
NEW
1144
        if (matrix && matrix->algorithm() && matrix->algorithm()->type() == RGBAlgorithm::Script)
×
1145
        {
NEW
1146
            RGBScript *script = static_cast<RGBScript*>(matrix->algorithm());
×
NEW
1147
            foreach (RGBScriptProperty prop, script->properties())
×
1148
            {
NEW
1149
                if (prop.m_name == control.m_resource)
×
1150
                {
NEW
1151
                    if (prop.m_type == RGBScriptProperty::List)
×
1152
                    {
NEW
1153
                        controlKnob->setRange(0, prop.m_listValues.count() - 1);
×
NEW
1154
                        controlKnob->setValue(prop.m_listValues.indexOf(script->property(prop.m_name)));
×
1155
                    }
NEW
1156
                    else if (prop.m_type == RGBScriptProperty::Range)
×
1157
                    {
NEW
1158
                        controlKnob->setRange(prop.m_rangeMinValue, prop.m_rangeMaxValue);
×
NEW
1159
                        controlKnob->setValue(script->property(prop.m_name).toInt());
×
1160
                    }
NEW
1161
                    else if (prop.m_type == RGBScriptProperty::Float)
×
1162
                    {
NEW
1163
                        controlKnob->setRange(0, 255);
×
NEW
1164
                        controlKnob->setValue(script->property(prop.m_name).toInt());
×
1165
                    }
NEW
1166
                    break;
×
1167
                }
NEW
1168
            }
×
1169
        }
1170
    }
1171

1172
    Q_ASSERT(controlWidget != NULL);
×
1173

1174
    if (control.widgetType() == VCMatrixControl::Knob)
×
1175
    {
1176
        connect(reinterpret_cast<KnobWidget*>(controlWidget), SIGNAL(valueChanged(int)),
×
1177
                this, SLOT(slotCustomControlValueChanged()));
1178
    }
1179
    else
1180
    {
1181
        connect(reinterpret_cast<QPushButton*>(controlWidget), SIGNAL(clicked()),
×
1182
                this, SLOT(slotCustomControlClicked()));
1183
    }
1184

1185

1186
    if (mode() == Doc::Design)
×
1187
        controlWidget->setEnabled(false);
×
1188

1189
    VCMatrixControl *c_control = new VCMatrixControl(control);
×
1190
    m_controls[controlWidget] = c_control;
×
1191
    m_widgets[c_control] = controlWidget;
×
1192

1193
    m_controlsLayout->addWidget(controlWidget);
×
1194

1195
    if (m_controls[controlWidget]->m_inputSource != NULL)
×
1196
    {
1197
        setInputSource(m_controls[controlWidget]->m_inputSource, m_controls[controlWidget]->m_id);
×
1198
    }
1199

1200
    slotFunctionChanged(); // Start update timer
×
1201
}
×
1202

1203
void VCMatrix::resetCustomControls()
×
1204
{
1205
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
1206
            it != m_controls.end(); ++it)
×
1207
    {
1208
        QWidget* widget = it.key();
×
1209
        m_controlsLayout->removeWidget(widget);
×
1210
        delete widget;
×
1211

1212
        VCMatrixControl* control = it.value();
×
1213
        if (!control->m_inputSource.isNull())
×
1214
            setInputSource(QSharedPointer<QLCInputSource>(), control->m_id);
×
1215
        delete control;
×
1216
    }
1217
    m_controls.clear();
×
1218
    m_widgets.clear();
×
1219
}
×
1220

1221
QList<VCMatrixControl *> VCMatrix::customControls() const
×
1222
{
1223
    QList<VCMatrixControl*> controls = m_controls.values();
×
1224
    std::sort(controls.begin(), controls.end(), VCMatrixControl::compare);
×
1225
    return controls;
×
1226
}
×
1227

1228
QMap<quint32,QString> VCMatrix::customControlsMap() const
×
1229
{
1230
    QMap<quint32,QString> map;
×
1231

1232
    foreach (VCMatrixControl *control, m_controls)
×
1233
        map.insert(control->m_id, VCMatrixControl::typeToString(control->m_type));
×
1234

1235
    return map;
×
1236
}
×
1237

1238
QWidget *VCMatrix::getWidget(VCMatrixControl* control) const
×
1239
{
1240
    return m_widgets[control];
×
1241
}
1242

1243
void VCMatrix::slotCustomControlClicked()
×
1244
{
1245
    QPushButton *btn = qobject_cast<QPushButton*>(sender());
×
1246
    VCMatrixControl *control = m_controls[btn];
×
1247
    if (control != NULL)
×
1248
    {
1249
        RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
1250
        if (matrix == NULL || mode() == Doc::Design)
×
1251
            return;
×
1252

1253
        if (control->m_type == VCMatrixControl::Color1)
×
1254
        {
1255
            matrix->setColor(0, control->m_color);
×
1256
            if (instantChanges() == true)
×
1257
                matrix->updateColorDelta();
×
1258
            btn->setDown(true);
×
1259
            emit mtxColor1Changed();
×
1260
        }
1261
        else if (control->m_type == VCMatrixControl::Color2)
×
1262
        {
1263
            matrix->setColor(1, control->m_color);
×
1264
            if (instantChanges() == true)
×
1265
                matrix->updateColorDelta();
×
1266
            btn->setDown(true);
×
1267
            emit mtxColor2Changed();
×
1268
        }
1269
        else if (control->m_type == VCMatrixControl::Color3)
×
1270
        {
1271
            matrix->setColor(2, control->m_color);
×
1272
            btn->setDown(true);
×
1273
            emit mtxColor3Changed();
×
1274
        }
1275
        else if (control->m_type == VCMatrixControl::Color4)
×
1276
        {
1277
            matrix->setColor(3, control->m_color);
×
1278
            btn->setDown(true);
×
1279
            emit mtxColor4Changed();
×
1280
        }
1281
        else if (control->m_type == VCMatrixControl::Color5)
×
1282
        {
1283
            matrix->setColor(4, control->m_color);
×
1284
            btn->setDown(true);
×
1285
            emit mtxColor5Changed();
×
1286
        }
1287
        else if (control->m_type == VCMatrixControl::Color2Reset)
×
1288
        {
1289
            matrix->setColor(1, QColor());
×
1290
            if (instantChanges() == true)
×
1291
                matrix->updateColorDelta();
×
1292
            emit mtxColor2Changed();
×
1293
        }
1294
        else if (control->m_type == VCMatrixControl::Color3Reset)
×
1295
        {
1296
            matrix->setColor(2, QColor());
×
1297
            emit mtxColor3Changed();
×
1298
        }
1299
        else if (control->m_type == VCMatrixControl::Color4Reset)
×
1300
        {
1301
            matrix->setColor(3, QColor());
×
1302
            emit mtxColor4Changed();
×
1303
        }
1304
        else if (control->m_type == VCMatrixControl::Color5Reset)
×
1305
        {
1306
            matrix->setColor(4, QColor());
×
1307
            emit mtxColor5Changed();
×
1308
        }
1309
        else if (control->m_type == VCMatrixControl::Animation)
×
1310
        {
1311
            RGBAlgorithm* algo = RGBAlgorithm::algorithm(m_doc, control->m_resource);
×
1312
            if (!control->m_properties.isEmpty())
×
1313
            {
1314
                RGBScript *script = static_cast<RGBScript*> (algo);
×
1315
                QMapIterator<QString, QString> it(control->m_properties);
×
1316
                while (it.hasNext())
×
1317
                {
1318
                    it.next();
×
1319
                    script->setProperty(it.key(), it.value());
×
1320
                    matrix->setProperty(it.key(), it.value());
×
1321
                }
1322
            }
×
1323
            matrix->setAlgorithm(algo);
×
1324
            if (instantChanges() == true)
×
1325
                matrix->updateColorDelta();
×
1326
            btn->setDown(true);
×
1327
        }
1328
        else if (control->m_type == VCMatrixControl::Text)
×
1329
        {
1330
            RGBAlgorithm* algo = RGBAlgorithm::algorithm(m_doc, "Text");
×
1331
            RGBText* text = static_cast<RGBText*> (algo);
×
1332
            text->setText(control->m_resource);
×
1333
            matrix->setAlgorithm(algo);
×
1334
            if (instantChanges() == true)
×
1335
                matrix->updateColorDelta();
×
1336
            btn->setDown(true);
×
1337
        }
1338
    }
1339
}
1340

1341
void VCMatrix::slotCustomControlValueChanged()
×
1342
{
1343
    KnobWidget *knob = qobject_cast<KnobWidget*>(sender());
×
1344
    VCMatrixControl *control = m_controls[knob];
×
1345
    if (control != NULL)
×
1346
    {
1347
        RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
1348
        if (matrix == NULL || mode() == Doc::Design)
×
1349
            return;
×
1350

1351
        if (control->m_type == VCMatrixControl::Color1Knob)
×
1352
        {
1353
            QRgb color = matrix->getColor(0).rgb();
×
1354
            QRgb knobValueColor = control->valueToRgb(knob->value());
×
1355
            color = (color & ~control->m_color.rgb()) | (knobValueColor & control->m_color.rgb());
×
1356

1357
            matrix->setColor(0, color);
×
1358
            if (instantChanges() == true)
×
1359
                matrix->updateColorDelta();
×
1360
            emit mtxColor1Changed();
×
1361
        }
1362
        else if (control->m_type == VCMatrixControl::Color2Knob)
×
1363
        {
1364
            QRgb color = matrix->getColor(1).rgb();
×
1365
            QRgb knobValueColor = control->valueToRgb(knob->value());
×
1366
            color = (color & ~control->m_color.rgb()) | (knobValueColor & control->m_color.rgb());
×
1367

1368
            matrix->setColor(1, color);
×
1369
            if (instantChanges() == true)
×
1370
                matrix->updateColorDelta();
×
1371
            emit mtxColor2Changed();
×
1372
        }
1373
        else if (control->m_type == VCMatrixControl::Color3Knob)
×
1374
        {
1375
            QRgb color = matrix->getColor(2).rgb();
×
1376
            QRgb knobValueColor = control->valueToRgb(knob->value());
×
1377
            color = (color & ~control->m_color.rgb()) | (knobValueColor & control->m_color.rgb());
×
1378

1379
            matrix->setColor(2, color);
×
1380
            emit mtxColor3Changed();
×
1381
        }
1382
        else if (control->m_type == VCMatrixControl::Color4Knob)
×
1383
        {
1384
            QRgb color = matrix->getColor(3).rgb();
×
1385
            QRgb knobValueColor = control->valueToRgb(knob->value());
×
1386
            color = (color & ~control->m_color.rgb()) | (knobValueColor & control->m_color.rgb());
×
1387

1388
            matrix->setColor(3, color);
×
1389
            emit mtxColor4Changed();
×
1390
        }
1391
        else if (control->m_type == VCMatrixControl::Color5Knob)
×
1392
        {
1393
            QRgb color = matrix->getColor(4).rgb();
×
1394
            QRgb knobValueColor = control->valueToRgb(knob->value());
×
1395
            color = (color & ~control->m_color.rgb()) | (knobValueColor & control->m_color.rgb());
×
1396

1397
            matrix->setColor(4, color);
×
1398
            emit mtxColor5Changed();
×
1399
        }
NEW
1400
        else if (control->m_type == VCMatrixControl::AnimationKnob)
×
1401
        {
NEW
1402
            if (matrix->algorithm() && matrix->algorithm()->type() == RGBAlgorithm::Script)
×
1403
            {
NEW
1404
                RGBScript *script = static_cast<RGBScript*>(matrix->algorithm());
×
NEW
1405
                foreach (RGBScriptProperty prop, script->properties())
×
1406
                {
NEW
1407
                    if (prop.m_name == control->m_resource)
×
1408
                    {
NEW
1409
                        if (prop.m_type == RGBScriptProperty::List)
×
1410
                        {
NEW
1411
                            if (knob->value() < prop.m_listValues.count())
×
NEW
1412
                                script->setProperty(control->m_resource, prop.m_listValues.at(knob->value()));
×
1413
                        }
1414
                        else
NEW
1415
                            script->setProperty(control->m_resource, QString::number(knob->value()));
×
NEW
1416
                        break;
×
1417
                    }
NEW
1418
                }
×
1419
            }
1420
        }
1421
        else
1422
        {
1423
            // We are not supposed to be here
1424
            Q_ASSERT(false);
×
1425
        }
1426
        emit matrixControlKnobValueChanged(control->m_id, knob->value());
×
1427
    }
1428
}
1429

1430
void VCMatrix::slotMatrixControlKnobValueChanged(int controlID, int value)
×
1431
{
1432
    QList<VCMatrixControl *> customControls = this->customControls();
×
1433
    for (int i = 0; i < customControls.length(); i++)
×
1434
    {
1435
        if (customControls[i]->m_id == controlID)
×
1436
        {
1437
            if (customControls[i]->m_type == VCMatrixControl::Color1Knob
×
1438
                    || customControls[i]->m_type == VCMatrixControl::Color2Knob
×
1439
                    || customControls[i]->m_type == VCMatrixControl::Color3Knob
×
1440
                    || customControls[i]->m_type == VCMatrixControl::Color4Knob
×
1441
                    || customControls[i]->m_type == VCMatrixControl::Color5Knob)
×
1442
            {
1443
                KnobWidget *knob = qobject_cast<KnobWidget*>(this->getWidget(customControls[i]));
×
1444
                knob->setValue(value);
×
1445
                break;
×
1446
            }
1447
        }
1448
    }
1449
}
×
1450

1451
void VCMatrix::slotMatrixControlPushButtonClicked(int controlID)
×
1452
{
1453
    QList<VCMatrixControl *> customControls = this->customControls();
×
1454
    for (int i = 0; i < customControls.length(); i++)
×
1455
    {
1456
        if (customControls[i]->m_id == controlID)
×
1457
        {
1458
            QPushButton *btn = qobject_cast<QPushButton*>(this->getWidget(customControls[i]));
×
1459
            btn->click();
×
1460
            break;
×
1461
        }
1462
    }
1463
}
×
1464

1465
void VCMatrix::slotModeChanged(Doc::Mode mode)
×
1466
{
1467
    if (mode == Doc::Operate)
×
1468
        enableWidgetUI(true);
×
1469
    else
1470
        enableWidgetUI(false);
×
1471

1472
    VCWidget::slotModeChanged(mode);
×
1473
}
×
1474

1475
/*********************************************************************
1476
 * External input
1477
 *********************************************************************/
1478

1479
void VCMatrix::slotKeyPressed(const QKeySequence &keySequence)
×
1480
{
1481
    if (acceptsInput() == false)
×
1482
        return;
×
1483

1484
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
1485
            it != m_controls.end(); ++it)
×
1486
    {
1487
        VCMatrixControl *control = it.value();
×
1488
        if (control->m_keySequence == keySequence &&
×
1489
                control->widgetType() == VCMatrixControl::Button) // Only for buttons
×
1490
        {
1491
            QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
1492
            button->click();
×
1493
        }
1494
    }
1495
}
1496

1497
void VCMatrix::updateFeedback()
×
1498
{
1499
    sendFeedback(m_slider->value());
×
1500

1501
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
1502
            it != m_controls.end(); ++it)
×
1503
    {
1504
        VCMatrixControl *control = it.value();
×
1505
        if (control->m_inputSource != NULL)
×
1506
        {
1507
            if (control->widgetType() == VCMatrixControl::Knob)
×
1508
            {
1509
                KnobWidget* knob = reinterpret_cast<KnobWidget*>(it.key());
×
1510
                sendFeedback(knob->value(), control->m_inputSource);
×
1511
            }
1512
            else // if (control->widgetType() == VCMatrixControl::Button)
1513
            {
1514
                QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
1515
                sendFeedback(button->isDown() ?
×
1516
                                 control->m_inputSource->feedbackValue(QLCInputFeedback::UpperValue) :
×
1517
                                 control->m_inputSource->feedbackValue(QLCInputFeedback::LowerValue),
×
1518
                                 control->m_inputSource);
×
1519
            }
1520
        }
1521
    }
1522
}
×
1523

1524
void VCMatrix::slotInputValueChanged(quint32 universe, quint32 channel, uchar value)
×
1525
{
1526
    /* Don't let input data through in design mode or if disabled */
1527
    if (acceptsInput() == false)
×
1528
        return;
×
1529

1530
    quint32 pagedCh = (page() << 16) | channel;
×
1531

1532
    if (checkInputSource(universe, pagedCh, value, sender()))
×
1533
    {
1534
        m_slider->setValue((int) value);
×
1535
        return;
×
1536
    }
1537

1538
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
1539
            it != m_controls.end(); ++it)
×
1540
    {
1541
        VCMatrixControl *control = it.value();
×
1542
        if (control->m_inputSource != NULL &&
×
1543
                control->m_inputSource->universe() == universe &&
×
1544
                control->m_inputSource->channel() == pagedCh)
×
1545
        {
1546
            if (control->widgetType() == VCMatrixControl::Knob)
×
1547
            {
1548
                KnobWidget* knob = reinterpret_cast<KnobWidget*>(it.key());
×
1549
                knob->setValue(value);
×
1550
            }
1551
            else
1552
            {
1553
                QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
1554
                button->click();
×
1555
            }
1556
        }
1557
    }
1558

NEW
1559
    RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
NEW
1560
    if (matrix == NULL || mode() == Doc::Design)
×
NEW
1561
        return;
×
1562

1563
    // Check if the received signal is for a dynamic property of the current preset
1564
    // TODO: reimplement this
1565
}
1566

1567
bool VCMatrix::loadXML(QXmlStreamReader &root)
×
1568
{
1569
    QString str;
×
1570

1571
    if (root.name() != KXMLQLCVCMatrix)
×
1572
    {
1573
        qWarning() << Q_FUNC_INFO << "Matrix node not found";
×
1574
        return false;
×
1575
    }
1576

1577
    /* Widget commons */
1578
    loadXMLCommon(root);
×
1579

1580
    // Sorted list for new controls
1581
    QList<VCMatrixControl> newControls;
×
1582

1583
    /* Children */
1584
    while (root.readNextStartElement())
×
1585
    {
1586
        if (root.name() == KXMLQLCWindowState)
×
1587
        {
1588
            bool visible = false;
×
1589
            int x = 0, y = 0, w = 0, h = 0;
×
1590
            loadXMLWindowState(root, &x, &y, &w, &h, &visible);
×
1591
            setGeometry(x, y, w, h);
×
1592
        }
1593
        else if (root.name() == KXMLQLCVCWidgetAppearance)
×
1594
        {
1595
            loadXMLAppearance(root);
×
1596
        }
1597
        else if (root.name() == KXMLQLCVCMatrixFunction)
×
1598
        {
1599
            QXmlStreamAttributes attrs = root.attributes();
×
1600
            str = attrs.value(KXMLQLCVCMatrixFunctionID).toString();
×
1601
            setFunction(str.toUInt());
×
1602
            if (attrs.hasAttribute(KXMLQLCVCMatrixInstantApply))
×
1603
                setInstantChanges(true);
×
1604
            root.skipCurrentElement();
×
1605
        }
×
1606
        else if (root.name() == KXMLQLCVCWidgetInput)
×
1607
        {
1608
            loadXMLInput(root);
×
1609
        }
1610
        else if (root.name() == KXMLQLCVCMatrixControl)
×
1611
        {
1612
            VCMatrixControl control(0xff);
×
1613
            if (control.loadXML(root))
×
1614
                newControls.insert(std::lower_bound(newControls.begin(), newControls.end(), control), control);
×
1615
        }
×
1616
        else if (root.name() == KXMLQLCVCMatrixVisibilityMask)
×
1617
        {
1618
            setVisibilityMask(root.readElementText().toUInt());
×
1619
        }
1620
        else
1621
        {
1622
            qWarning() << Q_FUNC_INFO << "Unknown VCMatrix tag:" << root.name().toString();
×
1623
            root.skipCurrentElement();
×
1624
        }
1625
    }
1626

1627
    foreach (VCMatrixControl const& control, newControls)
×
1628
        addCustomControl(control);
×
1629

1630
    return true;
×
1631
}
×
1632

1633
bool VCMatrix::saveXML(QXmlStreamWriter *doc)
×
1634
{
1635
    Q_ASSERT(doc != NULL);
×
1636

1637
    /* VC button entry */
1638
    doc->writeStartElement(KXMLQLCVCMatrix);
×
1639

1640
    saveXMLCommon(doc);
×
1641

1642
    /* Window state */
1643
    saveXMLWindowState(doc);
×
1644

1645
    /* Appearance */
1646
    saveXMLAppearance(doc);
×
1647

1648
    /* Function */
1649
    doc->writeStartElement(KXMLQLCVCMatrixFunction);
×
1650
    doc->writeAttribute(KXMLQLCVCMatrixFunctionID, QString::number(function()));
×
1651

1652
    if (instantChanges() == true)
×
1653
        doc->writeAttribute(KXMLQLCVCMatrixInstantApply, "true");
×
1654
    doc->writeEndElement();
×
1655

1656
    /* Default controls visibility  */
1657
    if (m_visibilityMask != VCMatrix::defaultVisibilityMask())
×
1658
        doc->writeTextElement(KXMLQLCVCMatrixVisibilityMask, QString::number(m_visibilityMask));
×
1659

1660
    /* Slider External input */
1661
    saveXMLInput(doc);
×
1662

1663
    foreach (VCMatrixControl *control, customControls())
×
1664
        control->saveXML(doc);
×
1665

1666
    /* End the <Matrix> tag */
1667
    doc->writeEndElement();
×
1668

1669
    return true;
×
1670
}
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

© 2026 Coveralls, Inc