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

mcallegari / qlcplus / 13633248611

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

push

github

web-flow
actions: add chrpath to profile

14689 of 46089 relevant lines covered (31.87%)

26426.11 hits per line

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

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
        }
814
        else if (control->m_type == VCMatrixControl::Color1)
815
        {
816
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
817
            button->setDown(matrix->getColor(0) == control->m_color);
×
818
        }
819
        else if (control->m_type == VCMatrixControl::Color2)
820
        {
821
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
822
            button->setDown(matrix->getColor(1) == control->m_color);
×
823
        }
824
        else if (control->m_type == VCMatrixControl::Color3)
825
        {
826
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
827
            button->setDown(matrix->getColor(2) == control->m_color);
×
828
        }
829
        else if (control->m_type == VCMatrixControl::Color4)
830
        {
831
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
832
            button->setDown(matrix->getColor(3) == control->m_color);
×
833
        }
834
        else if (control->m_type == VCMatrixControl::Color5)
835
        {
836
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
837
            button->setDown(matrix->getColor(4) == control->m_color);
×
838
        }
839
        else if (control->m_type == VCMatrixControl::Animation)
840
        {
841
            bool on = false;
842
            if (algorithmType == RGBAlgorithm::Script &&
×
843
                algorithmName == control->m_resource)
×
844
            {
845
                on = true;
846
                for (QHash<QString, QString>::const_iterator it = control->m_properties.begin();
×
847
                        it != control->m_properties.end(); ++it)
×
848
                {
849
                    if (algorithmProperties.value(it.key(), QString()) != it.value())
×
850
                        on = false;
851
                }
852
            }
853

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

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

871
    updateFeedback();
×
872
}
×
873

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

879
/*********************************************************************
880
 * Instant changes apply
881
 *********************************************************************/
882

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

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

893
/*********************************************************************
894
 * Custom controls
895
 *********************************************************************/
896

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

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

1101
    Q_ASSERT(controlWidget != NULL);
1102

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

1114

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

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

1122
    m_controlsLayout->addWidget(controlWidget);
×
1123

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

1129
    slotFunctionChanged(); // Start update timer
×
1130
}
×
1131

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

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

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

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

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

1164
    return map;
×
1165
}
×
1166

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

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

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

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

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

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

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

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

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

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

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

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

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

1380
    VCWidget::slotModeChanged(mode);
×
1381
}
×
1382

1383
/*********************************************************************
1384
 * External input
1385
 *********************************************************************/
1386

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

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

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

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

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

1438
    quint32 pagedCh = (page() << 16) | channel;
×
1439

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

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

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

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

1478
    /* Widget commons */
1479
    loadXMLCommon(root);
×
1480

1481
    // Sorted list for new controls
1482
    QList<VCMatrixControl> newControls;
1483

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

1528
    foreach (VCMatrixControl const& control, newControls)
×
1529
        addCustomControl(control);
×
1530

1531
    return true;
1532
}
×
1533

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

1538
    /* VC button entry */
1539
    doc->writeStartElement(KXMLQLCVCMatrix);
×
1540

1541
    saveXMLCommon(doc);
×
1542

1543
    /* Window state */
1544
    saveXMLWindowState(doc);
×
1545

1546
    /* Appearance */
1547
    saveXMLAppearance(doc);
×
1548

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

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

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

1561
    /* Slider External input */
1562
    saveXMLInput(doc);
×
1563

1564
    foreach (VCMatrixControl *control, customControls())
×
1565
        control->saveXML(doc);
×
1566

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

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

© 2025 Coveralls, Inc