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

mcallegari / qlcplus / 19409821768

16 Nov 2025 06:06PM UTC coverage: 34.233% (-0.01%) from 34.243%
19409821768

push

github

mcallegari
vc/soloframe: add an option to exclude functions monitored by buttons to be stopped

3 of 38 new or added lines in 9 files covered. (7.89%)

2 existing lines in 2 files now uncovered.

17724 of 51774 relevant lines covered (34.23%)

19630.45 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

NEW
633
void VCMatrix::notifyFunctionStarting(quint32 fid, qreal functionIntensity, bool excludeMonitored)
×
634
{
635
    Q_UNUSED(excludeMonitored)
636

637
    if (mode() == Doc::Design)
×
638
        return;
×
639

640
    if (fid == m_matrixID)
×
641
        return;
×
642

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

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

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

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

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

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

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

693
    {
694
        QMutexLocker locker(&matrix->algorithmMutex());
×
695

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

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

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

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

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

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

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

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

756
        if (control->m_type == VCMatrixControl::Color1Knob)
×
757
        {
758
            KnobWidget *knob = reinterpret_cast<KnobWidget*>(widget);
×
759
            int val = control->rgbToValue(matrix->getColor(0).rgb());
×
760
            if (knob->value() != val)
×
761
            {
762
                knob->blockSignals(true);
×
763
                knob->setValue(val);
×
764
                emit matrixControlKnobValueChanged(control->m_id, val);
×
765
                knob->blockSignals(false);
×
766
            }
767
        }
768
        else if (control->m_type == VCMatrixControl::Color2Knob)
×
769
        {
770
            KnobWidget *knob = reinterpret_cast<KnobWidget*>(widget);
×
771
            int val = control->rgbToValue(matrix->getColor(1).rgb());
×
772
            if (knob->value() != val)
×
773
            {
774
                knob->blockSignals(true);
×
775
                knob->setValue(val);
×
776
                emit matrixControlKnobValueChanged(control->m_id, val);
×
777
                knob->blockSignals(false);
×
778
            }
779
        }
780
        else if (control->m_type == VCMatrixControl::Color3Knob)
×
781
        {
782
            KnobWidget *knob = reinterpret_cast<KnobWidget*>(widget);
×
783
            int val = control->rgbToValue(matrix->getColor(2).rgb());
×
784
            if (knob->value() != val)
×
785
            {
786
                knob->blockSignals(true);
×
787
                knob->setValue(val);
×
788
                emit matrixControlKnobValueChanged(control->m_id, val);
×
789
                knob->blockSignals(false);
×
790
            }
791
        }
792
        else if (control->m_type == VCMatrixControl::Color4Knob)
×
793
        {
794
            KnobWidget *knob = reinterpret_cast<KnobWidget*>(widget);
×
795
            int val = control->rgbToValue(matrix->getColor(3).rgb());
×
796
            if (knob->value() != val)
×
797
            {
798
                knob->blockSignals(true);
×
799
                knob->setValue(val);
×
800
                emit matrixControlKnobValueChanged(control->m_id, val);
×
801
                knob->blockSignals(false);
×
802
            }
803
        }
804
        else if (control->m_type == VCMatrixControl::Color5Knob)
×
805
        {
806
            KnobWidget *knob = reinterpret_cast<KnobWidget*>(widget);
×
807
            int val = control->rgbToValue(matrix->getColor(4).rgb());
×
808
            if (knob->value() != val)
×
809
            {
810
                knob->blockSignals(true);
×
811
                knob->setValue(val);
×
812
                emit matrixControlKnobValueChanged(control->m_id, val);
×
813
                knob->blockSignals(false);
×
814
            }
815
        }
816
        else if (control->m_type == VCMatrixControl::Color1)
×
817
        {
818
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
819
            button->setDown(matrix->getColor(0) == control->m_color);
×
820
        }
821
        else if (control->m_type == VCMatrixControl::Color2)
×
822
        {
823
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
824
            button->setDown(matrix->getColor(1) == control->m_color);
×
825
        }
826
        else if (control->m_type == VCMatrixControl::Color3)
×
827
        {
828
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
829
            button->setDown(matrix->getColor(2) == control->m_color);
×
830
        }
831
        else if (control->m_type == VCMatrixControl::Color4)
×
832
        {
833
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
834
            button->setDown(matrix->getColor(3) == control->m_color);
×
835
        }
836
        else if (control->m_type == VCMatrixControl::Color5)
×
837
        {
838
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
839
            button->setDown(matrix->getColor(4) == control->m_color);
×
840
        }
841
        else if (control->m_type == VCMatrixControl::Animation)
×
842
        {
843
            bool on = false;
×
844
            if (algorithmType == RGBAlgorithm::Script &&
×
845
                algorithmName == control->m_resource)
×
846
            {
847
                on = true;
×
848
                for (QMap<QString, QString>::const_iterator it = control->m_properties.begin();
×
849
                        it != control->m_properties.end(); ++it)
×
850
                {
851
                    if (algorithmProperties.value(it.key(), QString()) != it.value())
×
852
                        on = false;
×
853
                }
854
            }
855

856
            QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
857
            button->setDown(on);
×
858
        }
859
        else if (control->m_type == VCMatrixControl::Text)
×
860
        {
861
            bool on = false;
×
862
            if (algorithmType == RGBAlgorithm::Text &&
×
863
                algorithmText == control->m_resource)
×
864
            {
865
                on = true;
×
866
            }
867

868
            QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
869
            button->setDown(on);
×
870
        }
871
    }
872

873
    updateFeedback();
×
874
}
×
875

876
FunctionParent VCMatrix::functionParent() const
×
877
{
878
    return FunctionParent(FunctionParent::ManualVCWidget, id());
×
879
}
880

881
/*********************************************************************
882
 * Instant changes apply
883
 *********************************************************************/
884

885
void VCMatrix::setInstantChanges(bool instantly)
×
886
{
887
    m_instantApply = instantly;
×
888
}
×
889

890
bool VCMatrix::instantChanges() const
×
891
{
892
    return m_instantApply;
×
893
}
894

895
/*********************************************************************
896
 * Custom controls
897
 *********************************************************************/
898

899
void VCMatrix::addCustomControl(VCMatrixControl const& control)
×
900
{
901
    QWidget *controlWidget = NULL;
×
902

903
    if (control.m_type == VCMatrixControl::Color1)
×
904
    {
905
        QPushButton *controlButton = new QPushButton(this);
×
906
        controlWidget = controlButton;
×
907
        controlButton->setStyleSheet(controlBtnSS.arg(control.m_color.name()));
×
908
        controlButton->setFixedWidth(36);
×
909
        controlButton->setFocusPolicy(Qt::TabFocus);
×
910
        controlButton->setText("1");
×
911
    }
912
    else if (control.m_type == VCMatrixControl::Color2)
×
913
    {
914
        QPushButton *controlButton = new QPushButton(this);
×
915
        controlWidget = controlButton;
×
916
        controlButton->setStyleSheet(controlBtnSS.arg(control.m_color.name()));
×
917
        controlButton->setFixedWidth(36);
×
918
        controlButton->setFocusPolicy(Qt::TabFocus);
×
919
        controlButton->setText("2");
×
920
    }
921
    else if (control.m_type == VCMatrixControl::Color3)
×
922
    {
923
        QPushButton *controlButton = new QPushButton(this);
×
924
        controlWidget = controlButton;
×
925
        controlButton->setStyleSheet(controlBtnSS.arg(control.m_color.name()));
×
926
        controlButton->setFixedWidth(36);
×
927
        controlButton->setFocusPolicy(Qt::TabFocus);
×
928
        controlButton->setText("3");
×
929
    }
930
    else if (control.m_type == VCMatrixControl::Color4)
×
931
    {
932
        QPushButton *controlButton = new QPushButton(this);
×
933
        controlWidget = controlButton;
×
934
        controlButton->setStyleSheet(controlBtnSS.arg(control.m_color.name()));
×
935
        controlButton->setFixedWidth(36);
×
936
        controlButton->setFocusPolicy(Qt::TabFocus);
×
937
        controlButton->setText("4");
×
938
    }
939
    else if (control.m_type == VCMatrixControl::Color5)
×
940
    {
941
        QPushButton *controlButton = new QPushButton(this);
×
942
        controlWidget = controlButton;
×
943
        controlButton->setStyleSheet(controlBtnSS.arg(control.m_color.name()));
×
944
        controlButton->setFixedWidth(36);
×
945
        controlButton->setFocusPolicy(Qt::TabFocus);
×
946
        controlButton->setText("5");
×
947
    }
948
    else if (control.m_type == VCMatrixControl::Color2Reset)
×
949
    {
950
        QPushButton *controlButton = new QPushButton(this);
×
951
        controlWidget = controlButton;
×
952
        controlButton->setStyleSheet(controlBtnSS.arg("#BBBBBB"));
×
953
        controlButton->setMinimumWidth(36);
×
954
        controlButton->setMaximumWidth(80);
×
955
        controlButton->setFocusPolicy(Qt::TabFocus);
×
956
        QString btnLabel = tr("Color 2 Reset");
×
957
        controlButton->setToolTip(btnLabel);
×
958
        controlButton->setText(fontMetrics().elidedText(btnLabel, Qt::ElideRight, 72));
×
959
    }
×
960
    else if (control.m_type == VCMatrixControl::Color3Reset)
×
961
    {
962
        QPushButton *controlButton = new QPushButton(this);
×
963
        controlWidget = controlButton;
×
964
        controlButton->setStyleSheet(controlBtnSS.arg("#BBBBBB"));
×
965
        controlButton->setMinimumWidth(36);
×
966
        controlButton->setMaximumWidth(80);
×
967
        controlButton->setFocusPolicy(Qt::TabFocus);
×
968
        QString btnLabel = tr("Color 3 Reset");
×
969
        controlButton->setToolTip(btnLabel);
×
970
        controlButton->setText(fontMetrics().elidedText(btnLabel, Qt::ElideRight, 72));
×
971
    }
×
972
    else if (control.m_type == VCMatrixControl::Color4Reset)
×
973
    {
974
        QPushButton *controlButton = new QPushButton(this);
×
975
        controlWidget = controlButton;
×
976
        controlButton->setStyleSheet(controlBtnSS.arg("#BBBBBB"));
×
977
        controlButton->setMinimumWidth(36);
×
978
        controlButton->setMaximumWidth(80);
×
979
        controlButton->setFocusPolicy(Qt::TabFocus);
×
980
        QString btnLabel = tr("Color 4 Reset");
×
981
        controlButton->setToolTip(btnLabel);
×
982
        controlButton->setText(fontMetrics().elidedText(btnLabel, Qt::ElideRight, 72));
×
983
    }
×
984
    else if (control.m_type == VCMatrixControl::Color5Reset)
×
985
    {
986
        QPushButton *controlButton = new QPushButton(this);
×
987
        controlWidget = controlButton;
×
988
        controlButton->setStyleSheet(controlBtnSS.arg("#BBBBBB"));
×
989
        controlButton->setMinimumWidth(36);
×
990
        controlButton->setMaximumWidth(80);
×
991
        controlButton->setFocusPolicy(Qt::TabFocus);
×
992
        QString btnLabel = tr("Color 5 Reset");
×
993
        controlButton->setToolTip(btnLabel);
×
994
        controlButton->setText(fontMetrics().elidedText(btnLabel, Qt::ElideRight, 72));
×
995
    }
×
996
    else if (control.m_type == VCMatrixControl::Animation ||
×
997
             control.m_type == VCMatrixControl::Text)
×
998
    {
999
        QPushButton *controlButton = new QPushButton(this);
×
1000
        controlWidget = controlButton;
×
1001
        controlButton->setStyleSheet(controlBtnSS.arg("#BBBBBB"));
×
1002
        controlButton->setMinimumWidth(36);
×
1003
        controlButton->setMaximumWidth(80);
×
1004
        controlButton->setFocusPolicy(Qt::TabFocus);
×
1005
        QString btnLabel = control.m_resource;
×
1006
        if (!control.m_properties.isEmpty())
×
1007
        {
1008
            btnLabel += " (";
×
1009
            QMapIterator<QString, QString> it(control.m_properties);
×
1010
            while (it.hasNext())
×
1011
            {
1012
                it.next();
×
1013
                btnLabel += it.value();
×
1014
                if (it.hasNext())
×
1015
                    btnLabel += ",";
×
1016
            }
1017
            btnLabel += ")";
×
1018
        }
×
1019
        controlButton->setToolTip(btnLabel);
×
1020
        controlButton->setText(fontMetrics().elidedText(btnLabel, Qt::ElideRight, 72));
×
1021
    }
×
1022
    else if (control.m_type == VCMatrixControl::Color1Knob)
×
1023
    {
1024
        KnobWidget *controlKnob = new KnobWidget(this);
×
1025
        controlWidget = controlKnob;
×
1026
        controlKnob->setColor(control.m_color);
×
1027
        controlKnob->setFixedWidth(36);
×
1028
        controlKnob->setFixedHeight(36);
×
1029
        QString knobLabel;
×
1030
        if (control.m_color == Qt::red)
×
1031
            knobLabel = tr("Color 1 Red component");
×
1032
        else if (control.m_color == Qt::green)
×
1033
            knobLabel = tr("Color 1 Green component");
×
1034
        else if (control.m_color == Qt::blue)
×
1035
            knobLabel = tr("Color 1 Blue component");
×
1036
        controlKnob->setToolTip(knobLabel);
×
1037
    }
×
1038
    else if (control.m_type == VCMatrixControl::Color2Knob)
×
1039
    {
1040
        KnobWidget *controlKnob = new KnobWidget(this);
×
1041
        controlWidget = controlKnob;
×
1042
        controlKnob->setColor(control.m_color.darker(250));
×
1043
        controlKnob->setFixedWidth(36);
×
1044
        controlKnob->setFixedHeight(36);
×
1045
        QString knobLabel;
×
1046
        if (control.m_color == Qt::red)
×
1047
            knobLabel = tr("Color 2 Red component");
×
1048
        else if (control.m_color == Qt::green)
×
1049
            knobLabel = tr("Color 2 Green component");
×
1050
        else if (control.m_color == Qt::blue)
×
1051
            knobLabel = tr("Color 2 Blue component");
×
1052
        controlKnob->setToolTip(knobLabel);
×
1053
    }
×
1054
    else if (control.m_type == VCMatrixControl::Color3Knob)
×
1055
    {
1056
        KnobWidget *controlKnob = new KnobWidget(this);
×
1057
        controlWidget = controlKnob;
×
1058
        controlKnob->setColor(control.m_color.darker(250));
×
1059
        controlKnob->setFixedWidth(36);
×
1060
        controlKnob->setFixedHeight(36);
×
1061
        QString knobLabel;
×
1062
        if (control.m_color == Qt::red)
×
1063
            knobLabel = tr("Color 3 Red component");
×
1064
        else if (control.m_color == Qt::green)
×
1065
            knobLabel = tr("Color 3 Green component");
×
1066
        else if (control.m_color == Qt::blue)
×
1067
            knobLabel = tr("Color 3 Blue component");
×
1068
        controlKnob->setToolTip(knobLabel);
×
1069
    }
×
1070
    else if (control.m_type == VCMatrixControl::Color4Knob)
×
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 4 Red component");
×
1080
        else if (control.m_color == Qt::green)
×
1081
            knobLabel = tr("Color 4 Green component");
×
1082
        else if (control.m_color == Qt::blue)
×
1083
            knobLabel = tr("Color 4 Blue component");
×
1084
        controlKnob->setToolTip(knobLabel);
×
1085
    }
×
1086
    else if (control.m_type == VCMatrixControl::Color5Knob)
×
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 5 Red component");
×
1096
        else if (control.m_color == Qt::green)
×
1097
            knobLabel = tr("Color 5 Green component");
×
1098
        else if (control.m_color == Qt::blue)
×
1099
            knobLabel = tr("Color 5 Blue component");
×
1100
        controlKnob->setToolTip(knobLabel);
×
1101
    }
×
1102

1103
    Q_ASSERT(controlWidget != NULL);
×
1104

1105
    if (control.widgetType() == VCMatrixControl::Knob)
×
1106
    {
1107
        connect(reinterpret_cast<KnobWidget*>(controlWidget), SIGNAL(valueChanged(int)),
×
1108
                this, SLOT(slotCustomControlValueChanged()));
1109
    }
1110
    else
1111
    {
1112
        connect(reinterpret_cast<QPushButton*>(controlWidget), SIGNAL(clicked()),
×
1113
                this, SLOT(slotCustomControlClicked()));
1114
    }
1115

1116

1117
    if (mode() == Doc::Design)
×
1118
        controlWidget->setEnabled(false);
×
1119

1120
    VCMatrixControl *c_control = new VCMatrixControl(control);
×
1121
    m_controls[controlWidget] = c_control;
×
1122
    m_widgets[c_control] = controlWidget;
×
1123

1124
    m_controlsLayout->addWidget(controlWidget);
×
1125

1126
    if (m_controls[controlWidget]->m_inputSource != NULL)
×
1127
    {
1128
        setInputSource(m_controls[controlWidget]->m_inputSource, m_controls[controlWidget]->m_id);
×
1129
    }
1130

1131
    slotFunctionChanged(); // Start update timer
×
1132
}
×
1133

1134
void VCMatrix::resetCustomControls()
×
1135
{
1136
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
1137
            it != m_controls.end(); ++it)
×
1138
    {
1139
        QWidget* widget = it.key();
×
1140
        m_controlsLayout->removeWidget(widget);
×
1141
        delete widget;
×
1142

1143
        VCMatrixControl* control = it.value();
×
1144
        if (!control->m_inputSource.isNull())
×
1145
            setInputSource(QSharedPointer<QLCInputSource>(), control->m_id);
×
1146
        delete control;
×
1147
    }
1148
    m_controls.clear();
×
1149
    m_widgets.clear();
×
1150
}
×
1151

1152
QList<VCMatrixControl *> VCMatrix::customControls() const
×
1153
{
1154
    QList<VCMatrixControl*> controls = m_controls.values();
×
1155
    std::sort(controls.begin(), controls.end(), VCMatrixControl::compare);
×
1156
    return controls;
×
1157
}
×
1158

1159
QMap<quint32,QString> VCMatrix::customControlsMap() const
×
1160
{
1161
    QMap<quint32,QString> map;
×
1162

1163
    foreach (VCMatrixControl *control, m_controls)
×
1164
        map.insert(control->m_id, VCMatrixControl::typeToString(control->m_type));
×
1165

1166
    return map;
×
1167
}
×
1168

1169
QWidget *VCMatrix::getWidget(VCMatrixControl* control) const
×
1170
{
1171
    return m_widgets[control];
×
1172
}
1173

1174
void VCMatrix::slotCustomControlClicked()
×
1175
{
1176
    QPushButton *btn = qobject_cast<QPushButton*>(sender());
×
1177
    VCMatrixControl *control = m_controls[btn];
×
1178
    if (control != NULL)
×
1179
    {
1180
        RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
1181
        if (matrix == NULL || mode() == Doc::Design)
×
1182
            return;
×
1183

1184
        if (control->m_type == VCMatrixControl::Color1)
×
1185
        {
1186
            matrix->setColor(0, control->m_color);
×
1187
            if (instantChanges() == true)
×
1188
                matrix->updateColorDelta();
×
1189
            btn->setDown(true);
×
1190
            emit mtxColor1Changed();
×
1191
        }
1192
        else if (control->m_type == VCMatrixControl::Color2)
×
1193
        {
1194
            matrix->setColor(1, control->m_color);
×
1195
            if (instantChanges() == true)
×
1196
                matrix->updateColorDelta();
×
1197
            btn->setDown(true);
×
1198
            emit mtxColor2Changed();
×
1199
        }
1200
        else if (control->m_type == VCMatrixControl::Color3)
×
1201
        {
1202
            matrix->setColor(2, control->m_color);
×
1203
            btn->setDown(true);
×
1204
            emit mtxColor3Changed();
×
1205
        }
1206
        else if (control->m_type == VCMatrixControl::Color4)
×
1207
        {
1208
            matrix->setColor(3, control->m_color);
×
1209
            btn->setDown(true);
×
1210
            emit mtxColor4Changed();
×
1211
        }
1212
        else if (control->m_type == VCMatrixControl::Color5)
×
1213
        {
1214
            matrix->setColor(4, control->m_color);
×
1215
            btn->setDown(true);
×
1216
            emit mtxColor5Changed();
×
1217
        }
1218
        else if (control->m_type == VCMatrixControl::Color2Reset)
×
1219
        {
1220
            matrix->setColor(1, QColor());
×
1221
            if (instantChanges() == true)
×
1222
                matrix->updateColorDelta();
×
1223
            emit mtxColor2Changed();
×
1224
        }
1225
        else if (control->m_type == VCMatrixControl::Color3Reset)
×
1226
        {
1227
            matrix->setColor(2, QColor());
×
1228
            emit mtxColor3Changed();
×
1229
        }
1230
        else if (control->m_type == VCMatrixControl::Color4Reset)
×
1231
        {
1232
            matrix->setColor(3, QColor());
×
1233
            emit mtxColor4Changed();
×
1234
        }
1235
        else if (control->m_type == VCMatrixControl::Color5Reset)
×
1236
        {
1237
            matrix->setColor(4, QColor());
×
1238
            emit mtxColor5Changed();
×
1239
        }
1240
        else if (control->m_type == VCMatrixControl::Animation)
×
1241
        {
1242
            RGBAlgorithm* algo = RGBAlgorithm::algorithm(m_doc, control->m_resource);
×
1243
            if (!control->m_properties.isEmpty())
×
1244
            {
1245
                RGBScript *script = static_cast<RGBScript*> (algo);
×
1246
                QMapIterator<QString, QString> it(control->m_properties);
×
1247
                while (it.hasNext())
×
1248
                {
1249
                    it.next();
×
1250
                    script->setProperty(it.key(), it.value());
×
1251
                    matrix->setProperty(it.key(), it.value());
×
1252
                }
1253
            }
×
1254
            matrix->setAlgorithm(algo);
×
1255
            if (instantChanges() == true)
×
1256
                matrix->updateColorDelta();
×
1257
            btn->setDown(true);
×
1258
        }
1259
        else if (control->m_type == VCMatrixControl::Text)
×
1260
        {
1261
            RGBAlgorithm* algo = RGBAlgorithm::algorithm(m_doc, "Text");
×
1262
            RGBText* text = static_cast<RGBText*> (algo);
×
1263
            text->setText(control->m_resource);
×
1264
            matrix->setAlgorithm(algo);
×
1265
            if (instantChanges() == true)
×
1266
                matrix->updateColorDelta();
×
1267
            btn->setDown(true);
×
1268
        }
1269
    }
1270
}
1271

1272
void VCMatrix::slotCustomControlValueChanged()
×
1273
{
1274
    KnobWidget *knob = qobject_cast<KnobWidget*>(sender());
×
1275
    VCMatrixControl *control = m_controls[knob];
×
1276
    if (control != NULL)
×
1277
    {
1278
        RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
1279
        if (matrix == NULL || mode() == Doc::Design)
×
1280
            return;
×
1281

1282
        if (control->m_type == VCMatrixControl::Color1Knob)
×
1283
        {
1284
            QRgb color = matrix->getColor(0).rgb();
×
1285
            QRgb knobValueColor = control->valueToRgb(knob->value());
×
1286
            color = (color & ~control->m_color.rgb()) | (knobValueColor & control->m_color.rgb());
×
1287

1288
            matrix->setColor(0, color);
×
1289
            if (instantChanges() == true)
×
1290
                matrix->updateColorDelta();
×
1291
            emit mtxColor1Changed();
×
1292
        }
1293
        else if (control->m_type == VCMatrixControl::Color2Knob)
×
1294
        {
1295
            QRgb color = matrix->getColor(1).rgb();
×
1296
            QRgb knobValueColor = control->valueToRgb(knob->value());
×
1297
            color = (color & ~control->m_color.rgb()) | (knobValueColor & control->m_color.rgb());
×
1298

1299
            matrix->setColor(1, color);
×
1300
            if (instantChanges() == true)
×
1301
                matrix->updateColorDelta();
×
1302
            emit mtxColor2Changed();
×
1303
        }
1304
        else if (control->m_type == VCMatrixControl::Color3Knob)
×
1305
        {
1306
            QRgb color = matrix->getColor(2).rgb();
×
1307
            QRgb knobValueColor = control->valueToRgb(knob->value());
×
1308
            color = (color & ~control->m_color.rgb()) | (knobValueColor & control->m_color.rgb());
×
1309

1310
            matrix->setColor(2, color);
×
1311
            emit mtxColor3Changed();
×
1312
        }
1313
        else if (control->m_type == VCMatrixControl::Color4Knob)
×
1314
        {
1315
            QRgb color = matrix->getColor(3).rgb();
×
1316
            QRgb knobValueColor = control->valueToRgb(knob->value());
×
1317
            color = (color & ~control->m_color.rgb()) | (knobValueColor & control->m_color.rgb());
×
1318

1319
            matrix->setColor(3, color);
×
1320
            emit mtxColor4Changed();
×
1321
        }
1322
        else if (control->m_type == VCMatrixControl::Color5Knob)
×
1323
        {
1324
            QRgb color = matrix->getColor(4).rgb();
×
1325
            QRgb knobValueColor = control->valueToRgb(knob->value());
×
1326
            color = (color & ~control->m_color.rgb()) | (knobValueColor & control->m_color.rgb());
×
1327

1328
            matrix->setColor(4, color);
×
1329
            emit mtxColor5Changed();
×
1330
        }
1331
        else
1332
        {
1333
            // We are not supposed to be here
1334
            Q_ASSERT(false);
×
1335
        }
1336
        emit matrixControlKnobValueChanged(control->m_id, knob->value());
×
1337
    }
1338
}
1339

1340
void VCMatrix::slotMatrixControlKnobValueChanged(int controlID, int value)
×
1341
{
1342
    QList<VCMatrixControl *> customControls = this->customControls();
×
1343
    for (int i = 0; i < customControls.length(); i++)
×
1344
    {
1345
        if (customControls[i]->m_id == controlID)
×
1346
        {
1347
            if (customControls[i]->m_type == VCMatrixControl::Color1Knob
×
1348
                    || customControls[i]->m_type == VCMatrixControl::Color2Knob
×
1349
                    || customControls[i]->m_type == VCMatrixControl::Color3Knob
×
1350
                    || customControls[i]->m_type == VCMatrixControl::Color4Knob
×
1351
                    || customControls[i]->m_type == VCMatrixControl::Color5Knob)
×
1352
            {
1353
                KnobWidget *knob = qobject_cast<KnobWidget*>(this->getWidget(customControls[i]));
×
1354
                knob->setValue(value);
×
1355
                break;
×
1356
            }
1357
        }
1358
    }
1359
}
×
1360

1361
void VCMatrix::slotMatrixControlPushButtonClicked(int controlID)
×
1362
{
1363
    QList<VCMatrixControl *> customControls = this->customControls();
×
1364
    for (int i = 0; i < customControls.length(); i++)
×
1365
    {
1366
        if (customControls[i]->m_id == controlID)
×
1367
        {
1368
            QPushButton *btn = qobject_cast<QPushButton*>(this->getWidget(customControls[i]));
×
1369
            btn->click();
×
1370
            break;
×
1371
        }
1372
    }
1373
}
×
1374

1375
void VCMatrix::slotModeChanged(Doc::Mode mode)
×
1376
{
1377
    if (mode == Doc::Operate)
×
1378
        enableWidgetUI(true);
×
1379
    else
1380
        enableWidgetUI(false);
×
1381

1382
    VCWidget::slotModeChanged(mode);
×
1383
}
×
1384

1385
/*********************************************************************
1386
 * External input
1387
 *********************************************************************/
1388

1389
void VCMatrix::slotKeyPressed(const QKeySequence &keySequence)
×
1390
{
1391
    if (acceptsInput() == false)
×
1392
        return;
×
1393

1394
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
1395
            it != m_controls.end(); ++it)
×
1396
    {
1397
        VCMatrixControl *control = it.value();
×
1398
        if (control->m_keySequence == keySequence &&
×
1399
                control->widgetType() == VCMatrixControl::Button) // Only for buttons
×
1400
        {
1401
            QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
1402
            button->click();
×
1403
        }
1404
    }
1405
}
1406

1407
void VCMatrix::updateFeedback()
×
1408
{
1409
    sendFeedback(m_slider->value());
×
1410

1411
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
1412
            it != m_controls.end(); ++it)
×
1413
    {
1414
        VCMatrixControl *control = it.value();
×
1415
        if (control->m_inputSource != NULL)
×
1416
        {
1417
            if (control->widgetType() == VCMatrixControl::Knob)
×
1418
            {
1419
                KnobWidget* knob = reinterpret_cast<KnobWidget*>(it.key());
×
1420
                sendFeedback(knob->value(), control->m_inputSource);
×
1421
            }
1422
            else // if (control->widgetType() == VCMatrixControl::Button)
1423
            {
1424
                QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
1425
                sendFeedback(button->isDown() ?
×
1426
                                 control->m_inputSource->feedbackValue(QLCInputFeedback::UpperValue) :
×
1427
                                 control->m_inputSource->feedbackValue(QLCInputFeedback::LowerValue),
×
1428
                                 control->m_inputSource);
×
1429
            }
1430
        }
1431
    }
1432
}
×
1433

1434
void VCMatrix::slotInputValueChanged(quint32 universe, quint32 channel, uchar value)
×
1435
{
1436
    /* Don't let input data through in design mode or if disabled */
1437
    if (acceptsInput() == false)
×
1438
        return;
×
1439

1440
    quint32 pagedCh = (page() << 16) | channel;
×
1441

1442
    if (checkInputSource(universe, pagedCh, value, sender()))
×
1443
    {
1444
        m_slider->setValue((int) value);
×
1445
        return;
×
1446
    }
1447

1448
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
1449
            it != m_controls.end(); ++it)
×
1450
    {
1451
        VCMatrixControl *control = it.value();
×
1452
        if (control->m_inputSource != NULL &&
×
1453
                control->m_inputSource->universe() == universe &&
×
1454
                control->m_inputSource->channel() == pagedCh)
×
1455
        {
1456
            if (control->widgetType() == VCMatrixControl::Knob)
×
1457
            {
1458
                KnobWidget* knob = reinterpret_cast<KnobWidget*>(it.key());
×
1459
                knob->setValue(value);
×
1460
            }
1461
            else
1462
            {
1463
                QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
1464
                button->click();
×
1465
            }
1466
        }
1467
    }
1468
}
1469

1470
bool VCMatrix::loadXML(QXmlStreamReader &root)
×
1471
{
1472
    QString str;
×
1473

1474
    if (root.name() != KXMLQLCVCMatrix)
×
1475
    {
1476
        qWarning() << Q_FUNC_INFO << "Matrix node not found";
×
1477
        return false;
×
1478
    }
1479

1480
    /* Widget commons */
1481
    loadXMLCommon(root);
×
1482

1483
    // Sorted list for new controls
1484
    QList<VCMatrixControl> newControls;
×
1485

1486
    /* Children */
1487
    while (root.readNextStartElement())
×
1488
    {
1489
        if (root.name() == KXMLQLCWindowState)
×
1490
        {
1491
            bool visible = false;
×
1492
            int x = 0, y = 0, w = 0, h = 0;
×
1493
            loadXMLWindowState(root, &x, &y, &w, &h, &visible);
×
1494
            setGeometry(x, y, w, h);
×
1495
        }
1496
        else if (root.name() == KXMLQLCVCWidgetAppearance)
×
1497
        {
1498
            loadXMLAppearance(root);
×
1499
        }
1500
        else if (root.name() == KXMLQLCVCMatrixFunction)
×
1501
        {
1502
            QXmlStreamAttributes attrs = root.attributes();
×
1503
            str = attrs.value(KXMLQLCVCMatrixFunctionID).toString();
×
1504
            setFunction(str.toUInt());
×
1505
            if (attrs.hasAttribute(KXMLQLCVCMatrixInstantApply))
×
1506
                setInstantChanges(true);
×
1507
            root.skipCurrentElement();
×
1508
        }
×
1509
        else if (root.name() == KXMLQLCVCWidgetInput)
×
1510
        {
1511
            loadXMLInput(root);
×
1512
        }
1513
        else if (root.name() == KXMLQLCVCMatrixControl)
×
1514
        {
1515
            VCMatrixControl control(0xff);
×
1516
            if (control.loadXML(root))
×
1517
                newControls.insert(std::lower_bound(newControls.begin(), newControls.end(), control), control);
×
1518
        }
×
1519
        else if (root.name() == KXMLQLCVCMatrixVisibilityMask)
×
1520
        {
1521
            setVisibilityMask(root.readElementText().toUInt());
×
1522
        }
1523
        else
1524
        {
1525
            qWarning() << Q_FUNC_INFO << "Unknown VCMatrix tag:" << root.name().toString();
×
1526
            root.skipCurrentElement();
×
1527
        }
1528
    }
1529

1530
    foreach (VCMatrixControl const& control, newControls)
×
1531
        addCustomControl(control);
×
1532

1533
    return true;
×
1534
}
×
1535

1536
bool VCMatrix::saveXML(QXmlStreamWriter *doc)
×
1537
{
1538
    Q_ASSERT(doc != NULL);
×
1539

1540
    /* VC button entry */
1541
    doc->writeStartElement(KXMLQLCVCMatrix);
×
1542

1543
    saveXMLCommon(doc);
×
1544

1545
    /* Window state */
1546
    saveXMLWindowState(doc);
×
1547

1548
    /* Appearance */
1549
    saveXMLAppearance(doc);
×
1550

1551
    /* Function */
1552
    doc->writeStartElement(KXMLQLCVCMatrixFunction);
×
1553
    doc->writeAttribute(KXMLQLCVCMatrixFunctionID, QString::number(function()));
×
1554

1555
    if (instantChanges() == true)
×
1556
        doc->writeAttribute(KXMLQLCVCMatrixInstantApply, "true");
×
1557
    doc->writeEndElement();
×
1558

1559
    /* Default controls visibility  */
1560
    if (m_visibilityMask != VCMatrix::defaultVisibilityMask())
×
1561
        doc->writeTextElement(KXMLQLCVCMatrixVisibilityMask, QString::number(m_visibilityMask));
×
1562

1563
    /* Slider External input */
1564
    saveXMLInput(doc);
×
1565

1566
    foreach (VCMatrixControl *control, customControls())
×
1567
        control->saveXML(doc);
×
1568

1569
    /* End the <Matrix> tag */
1570
    doc->writeEndElement();
×
1571

1572
    return true;
×
1573
}
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