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

mcallegari / qlcplus / 6914951527

18 Nov 2023 04:07PM UTC coverage: 32.019% (-0.04%) from 32.058%
6914951527

push

github

web-flow
Merge pull request #1482 from Itay-Lifshitz/webaccess_animation_widget

Animation(Matrix) widget is now supported.

0 of 59 new or added lines in 1 file covered. (0.0%)

11 existing lines in 1 file now uncovered.

15109 of 47187 relevant lines covered (32.02%)

23544.93 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
    m_startColorButton = new QToolButton(this);
×
83
    m_startColorButton->setFixedSize(48, 48);
×
84
    m_startColorButton->setIconSize(QSize(42, 42));
×
85

NEW
86
    m_startColor = Qt::red;
×
87

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

97
    connect(m_scCnGWidget, SIGNAL(colorChanged(QRgb)),
×
98
            this, SLOT(slotStartColorChanged(QRgb)));
99

100
    m_endColorButton = new QToolButton(this);
×
101
    m_endColorButton->setFixedSize(48, 48);
×
102
    m_endColorButton->setIconSize(QSize(42, 42));
×
103

NEW
104
    m_endColor = QColor();
×
105

106
    QWidgetAction* ecAction = new QWidgetAction(this);
×
107
    m_ecCnGWidget = new ClickAndGoWidget();
×
108
    m_ecCnGWidget->setType(ClickAndGoWidget::RGB, NULL);
×
109
    ecAction->setDefaultWidget(m_ecCnGWidget);
×
110
    QMenu *endColorMenu = new QMenu();
×
111
    endColorMenu->addAction(ecAction);
×
112
    m_endColorButton->setMenu(endColorMenu);
×
113
    m_endColorButton->setPopupMode(QToolButton::InstantPopup);
×
114

115
    connect(m_ecCnGWidget, SIGNAL(colorChanged(QRgb)),
×
116
            this, SLOT(slotEndColorChanged(QRgb)));
117

118
    m_label = new QLabel(this);
×
119
    m_label->setAlignment(Qt::AlignCenter);
×
120
    m_label->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
×
121
    vbox->addWidget(m_label);
×
122

123
    QHBoxLayout *btnHbox = new QHBoxLayout();
×
124

125
    btnHbox->addWidget(m_startColorButton);
×
126
    btnHbox->addWidget(m_endColorButton);
×
127

128
    vbox->addLayout(btnHbox);
×
129

130
    m_presetCombo = new QComboBox(this);
×
131
    //m_presetCombo->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
132
    m_presetCombo->addItems(RGBAlgorithm::algorithms(m_doc));
×
133
    connect(m_presetCombo, SIGNAL(currentIndexChanged(QString)),
×
134
            this, SLOT(slotAnimationChanged(QString)));
135
    vbox->addWidget(m_presetCombo);
×
136

137
    hBox->addLayout(vbox);
×
138

139
    m_controlsLayout = new FlowLayout();
×
140
    vbox->addLayout(m_controlsLayout);
×
141

142
    setType(VCWidget::AnimationWidget);
×
143
    setCaption(QString());
×
144
    /* Initial size */
145
    QSettings settings;
×
146
    QVariant var = settings.value(SETTINGS_RGBMATRIX_SIZE);
×
147
    if (var.isValid() == true)
×
148
        resize(var.toSize());
×
149
    else
150
        resize(defaultSize);
×
151

152
    /* Update timer */
153
    m_updateTimer = new QTimer(this);
×
154
    connect(m_updateTimer, SIGNAL(timeout()),
×
155
            this, SLOT(slotUpdate()));
156
    m_updateTimer->setSingleShot(true);
×
157

158
    /* Update the slider according to current mode */
159
    slotModeChanged(m_doc->mode());
×
160
    setLiveEdit(m_liveEdit);
×
161
}
×
162

163
VCMatrix::~VCMatrix()
×
164
{
165
    foreach(VCMatrixControl* control, m_controls)
×
166
    {
167
        delete control;
×
168
    }
169
}
×
170

171
void VCMatrix::setID(quint32 id)
×
172
{
173
    VCWidget::setID(id);
×
174

175
    if (caption().isEmpty())
×
176
        setCaption(tr("Animation %1").arg(id));
×
177
}
×
178

179
/*********************************************************************
180
 * Clipboard
181
 *********************************************************************/
182

183
VCWidget *VCMatrix::createCopy(VCWidget *parent)
×
184
{
185
    Q_ASSERT(parent != NULL);
×
186

187
    VCMatrix* matrix = new VCMatrix(parent, m_doc);
×
188
    if (matrix->copyFrom(this) == false)
×
189
    {
190
        delete matrix;
×
191
        matrix = NULL;
×
192
    }
193

194
    return matrix;
×
195
}
196

197
bool VCMatrix::copyFrom(const VCWidget* widget)
×
198
{
199
    const VCMatrix* matrix = qobject_cast <const VCMatrix*> (widget);
×
200
    if (matrix == NULL)
×
201
        return false;
×
202

203
    /* Copy vcmatrix-specific stuff */
204
    setFunction(matrix->function());
×
205
    setInstantChanges(matrix->instantChanges());
×
206
    setVisibilityMask(matrix->visibilityMask());
×
207

208
    resetCustomControls();
×
209
    foreach (VCMatrixControl const* control, matrix->customControls())
×
210
    {
211
        addCustomControl(*control);
×
212
    }
213

214
    /* Copy common stuff */
215
    return VCWidget::copyFrom(widget);
×
216
}
217

218
/*********************************************************************
219
 * GUI
220
 *********************************************************************/
221

222
void VCMatrix::setCaption(const QString &text)
×
223
{
224
    VCWidget::setCaption(text);
×
225
    m_label->setText(text);
×
226
}
×
227

228
void VCMatrix::enableWidgetUI(bool enable)
×
229
{
230
    m_slider->setEnabled(enable);
×
231
    m_startColorButton->setEnabled(enable);
×
232
    m_endColorButton->setEnabled(enable);
×
233
    m_presetCombo->setEnabled(enable);
×
234

235
    foreach(QWidget *ctlBtn, m_controls.keys())
×
236
        ctlBtn->setEnabled(enable);
×
237

238
    // Update buttons state
239
    if (enable)
×
240
        slotUpdate();
×
241
}
×
242

NEW
243
void VCMatrix::slotSetSliderValue(int value)
×
244
{
NEW
245
    m_slider->setValue(value);
×
NEW
246
    slotSliderMoved(value);
×
NEW
247
}
×
248

UNCOV
249
void VCMatrix::slotSliderMoved(int value)
×
250
{
NEW
251
    emit sliderValueChanged(value);
×
252

253
    Function* function = m_doc->function(m_matrixID);
×
254
    if (function == NULL || mode() == Doc::Design)
×
255
        return;
×
256

257
    if (m_sliderExternalMovement)
×
258
        return;
×
259

260
    if (value == 0)
×
261
    {
262
        // Make sure we ignore the fade out time
263
        adjustFunctionIntensity(function, 0);
×
264
        if (function->stopped() == false)
×
265
        {
266
            function->stop(functionParent());
×
267
            resetIntensityOverrideAttribute();
×
268
        }
269
    }
270
    else
271
    {
272
        qreal pIntensity = qreal(value) / qreal(UCHAR_MAX);
×
273
        emit functionStarting(m_matrixID, pIntensity);
×
274
        adjustFunctionIntensity(function, pIntensity * intensity());
×
275
        if (function->stopped() == true)
×
276
        {
277
            // TODO once #758 is fixed: function started by a fader -> override fade in time
278
            function->start(m_doc->masterTimer(), functionParent());
×
279
        }
280
    }
281
}
282

NEW
283
int VCMatrix::sliderValue()
×
284
{
NEW
285
    return m_slider->value();
×
286
}
287

NEW
288
void VCMatrix::slotSetStartColor(QColor color)
×
289
{
NEW
290
    m_startColor = color;
×
NEW
291
    emit startColorChanged();
×
NEW
292
}
×
293

NEW
294
QColor VCMatrix::startColor()
×
295
{
NEW
296
    return m_startColor;
×
297
}
298

UNCOV
299
void VCMatrix::slotStartColorChanged(QRgb color)
×
300
{
301
    QColor col(color);
×
NEW
302
    slotSetStartColor(col);
×
303
    QPixmap px(42, 42);
×
304
    px.fill(col);
×
305
    m_startColorButton->setIcon(px);
×
306

307
    RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
308
    if (matrix == NULL || mode() == Doc::Design)
×
309
        return;
×
310

311
    matrix->setStartColor(col);
×
312
    if (instantChanges() == true)
×
313
        matrix->updateColorDelta();
×
314
}
315

NEW
316
void VCMatrix::slotSetEndColor(QColor color)
×
317
{
NEW
318
    m_endColor = color;
×
NEW
319
    emit endColorChanged();
×
NEW
320
}
×
321

NEW
322
QColor VCMatrix::endColor()
×
323
{
NEW
324
    return m_endColor;
×
325
}
326

UNCOV
327
void VCMatrix::slotEndColorChanged(QRgb color)
×
328
{
329
    QColor col(color);
×
NEW
330
    slotSetEndColor(col);
×
331
    QPixmap px(42, 42);
×
332
    px.fill(col);
×
333
    m_endColorButton->setIcon(px);
×
334

335
    RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
336
    if (matrix == NULL || mode() == Doc::Design)
×
337
        return;
×
338

339
    matrix->setEndColor(col);
×
340
    if (instantChanges() == true)
×
341
        matrix->updateColorDelta();
×
342
}
343

NEW
344
void VCMatrix::slotSetAnimationValue(QString name)
×
345
{
NEW
346
    m_presetCombo->setCurrentText(name);
×
NEW
347
    slotAnimationChanged(name);
×
NEW
348
}
×
349

UNCOV
350
void VCMatrix::slotAnimationChanged(QString name)
×
351
{
NEW
352
    emit animationValueChanged(name);
×
353
    RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
354
    if (matrix == NULL || mode() == Doc::Design)
×
355
        return;
×
356

357
    RGBAlgorithm* algo = RGBAlgorithm::algorithm(m_doc, name);
×
358
    matrix->setAlgorithm(algo);
×
359
    if (instantChanges() == true)
×
360
        matrix->updateColorDelta();
×
361
}
362

NEW
363
QString VCMatrix::animationValue()
×
364
{
NEW
365
    return m_presetCombo->currentText();
×
366
}
367

UNCOV
368
void VCMatrix::setVisibilityMask(quint32 mask)
×
369
{
370
    if (mask & ShowSlider) m_slider->show();
×
371
    else m_slider->hide();
×
372

373
    if (mask & ShowLabel) m_label->show();
×
374
    else m_label->hide();
×
375

376
    if (mask & ShowStartColorButton) m_startColorButton->show();
×
377
    else m_startColorButton->hide();
×
378

379
    if (mask & ShowEndColorButton) m_endColorButton->show();
×
380
    else m_endColorButton->hide();
×
381

382
    if (mask & ShowPresetCombo) m_presetCombo->show();
×
383
    else m_presetCombo->hide();
×
384

385
    m_visibilityMask = mask;
×
386
}
×
387

388
quint32 VCMatrix::visibilityMask() const
×
389
{
390
    return m_visibilityMask;
×
391
}
392

393
quint32 VCMatrix::defaultVisibilityMask()
×
394
{
395
    return ShowSlider
396
        | ShowLabel
397
        | ShowStartColorButton
398
        | ShowEndColorButton
399
        | ShowPresetCombo
×
400
        ;
401
}
402

403
/*********************************************************************
404
 * Properties
405
 *********************************************************************/
406

407
void VCMatrix::editProperties()
×
408
{
409
    VCMatrixProperties prop(this, m_doc);
×
410
    if (prop.exec() == QDialog::Accepted)
×
411
        m_doc->setModified();
×
412
}
×
413

414
/*************************************************************************
415
 * VCWidget-inherited
416
 *************************************************************************/
417

418
void VCMatrix::adjustIntensity(qreal val)
×
419
{
420
    VCWidget::adjustIntensity(val);
×
421
    this->slotSliderMoved(this->m_slider->value());
×
422
}
×
423

424
/*********************************************************************
425
 * Function attachment
426
 *********************************************************************/
427

428
void VCMatrix::setFunction(quint32 id)
×
429
{
430
    Function *old = m_doc->function(m_matrixID);
×
431
    if (old != NULL)
×
432
    {
433
        disconnect(old, SIGNAL(stopped(quint32)),
×
434
                this, SLOT(slotFunctionStopped()));
435
        disconnect(old, SIGNAL(changed(quint32)),
×
436
                this, SLOT(slotFunctionChanged()));
437
    }
438

439
    RGBMatrix* matrix = qobject_cast<RGBMatrix*> (m_doc->function(id));
×
440

441
    if (matrix == NULL)
×
442
        m_matrixID = Function::invalidId();
×
443
    else
444
    {
445
        m_matrixID = id;
×
446
        connect(matrix, SIGNAL(stopped(quint32)),
×
447
                this, SLOT(slotFunctionStopped()));
448
        connect(matrix, SIGNAL(changed(quint32)),
×
449
                this, SLOT(slotFunctionChanged()));
450
    }
451

452
    slotUpdate();
×
453
}
×
454

455
quint32 VCMatrix::function() const
×
456
{
457
    return m_matrixID;
×
458
}
459

460
void VCMatrix::notifyFunctionStarting(quint32 fid, qreal functionIntensity)
×
461
{
462
    if (mode() == Doc::Design)
×
463
        return;
×
464

465
    if (fid == m_matrixID)
×
466
        return;
×
467

468
    int value = SCALE(1.0 - functionIntensity,
×
469
            0, 1.0,
470
            m_slider->minimum(), m_slider->maximum());
471
    if (m_slider->value() > value)
×
472
    {
473
        m_sliderExternalMovement = true;
×
474
        m_slider->setValue(value);
×
475
        m_sliderExternalMovement = false;
×
476

477
        Function* function = m_doc->function(m_matrixID);
×
478
        if (function != NULL)
×
479
        {
480
            qreal pIntensity = qreal(value) / qreal(UCHAR_MAX);
×
481
            adjustFunctionIntensity(function, pIntensity * intensity());
×
482
            if (value == 0 && !function->stopped())
×
483
            {
484
                function->stop(functionParent());
×
485
                resetIntensityOverrideAttribute();
×
486
            }
487
        }
488
    }
489
}
490

491
void VCMatrix::slotFunctionStopped()
×
492
{
493
    m_slider->blockSignals(true);
×
494
    m_slider->setValue(0);
×
495
    resetIntensityOverrideAttribute();
×
496
    m_slider->blockSignals(false);
×
497
}
×
498

499
void VCMatrix::slotFunctionChanged()
×
500
{
501
    m_updateTimer->start(UPDATE_TIMEOUT);
×
502
}
×
503

504
void VCMatrix::slotUpdate()
×
505
{
506
    if (m_matrixID == Function::invalidId())
×
507
        return;
×
508

509
    RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
510
    if (matrix == NULL)
×
511
        return;
×
512

513
    QColor startColor = matrix->startColor();
×
514
    QColor endColor = matrix->endColor();
×
515
    QString algorithmName;
×
516
    RGBAlgorithm::Type algorithmType = RGBAlgorithm::Plain;
×
517
    QHash<QString, QString> algorithmProperties;
×
518
    QString algorithmText;
×
519

520
    {
521
        QMutexLocker(&matrix->algorithmMutex());
×
522

523
        RGBAlgorithm* algo = matrix->algorithm();
×
524
        if (algo != NULL)
×
525
        {
526
            algorithmName = algo->name();
×
527
            algorithmType = algo->type();
×
528
            if (algorithmType == RGBAlgorithm::Script)
×
529
            {
530
                algorithmProperties = reinterpret_cast<RGBScript*>(algo)->propertiesAsStrings();
×
531
            }
532
            else if (algorithmType == RGBAlgorithm::Text)
×
533
            {
534
                algorithmText = reinterpret_cast<RGBText*>(algo)->text();
×
535
            }
536
        }
537
    }
538

539
    // Start / End color buttons
540
    QPixmap px(42, 42);
×
541
    px.fill(startColor);
×
542
    m_startColorButton->setIcon(px);
×
NEW
543
    slotSetStartColor(startColor);
×
544

545
    if (endColor == QColor())
×
546
        px.fill(Qt::transparent);
×
547
    else
548
        px.fill(endColor);
×
549
    m_endColorButton->setIcon(px);
×
NEW
550
    slotSetEndColor(endColor);
×
551

552
    // Algo combo box
553
    if (algorithmName != QString())
×
554
    {
555
        m_presetCombo->blockSignals(true);
×
556
        m_presetCombo->setCurrentText(algorithmName);
×
557
        m_presetCombo->blockSignals(false);
×
558
    }
559

560
    // Custom Buttons
561
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
562
            it != m_controls.end(); ++it)
×
563
    {
564
        QWidget* widget = it.key();
×
565
        VCMatrixControl* control = it.value();
×
566

567
        if (control->m_type == VCMatrixControl::StartColorKnob)
×
568
        {
569
            KnobWidget* knob = reinterpret_cast<KnobWidget*>(widget);
×
570
            knob->blockSignals(true);
×
NEW
571
            knob->setValue(control->rgbToValue(startColor.rgb()));            
×
NEW
572
            emit matrixControlKnobValueChanged(control->m_id, knob->value());
×
UNCOV
573
            knob->blockSignals(false);
×
574
        }
575
        else if (control->m_type == VCMatrixControl::EndColorKnob)
×
576
        {
577
            KnobWidget* knob = reinterpret_cast<KnobWidget*>(widget);
×
578
            knob->blockSignals(true);
×
579
            knob->setValue(control->rgbToValue(endColor.rgb()));
×
NEW
580
            emit matrixControlKnobValueChanged(control->m_id, knob->value());
×
UNCOV
581
            knob->blockSignals(false);
×
582
        }
583
        else if (control->m_type == VCMatrixControl::StartColor)
×
584
        {
585
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
586
            button->setDown(startColor == control->m_color);
×
587
        }
588
        else if (control->m_type == VCMatrixControl::EndColor)
×
589
        {
590
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
591
            button->setDown(endColor == control->m_color);
×
592
        }
593
        else if (control->m_type == VCMatrixControl::Animation)
×
594
        {
595
            bool on = false;
×
596
            if (algorithmType == RGBAlgorithm::Script)
×
597
            {
598
                if (algorithmName == control->m_resource)
×
599
                {
600
                    on = true;
×
601
                    for (QHash<QString, QString>::const_iterator it = control->m_properties.begin();
×
602
                            it != control->m_properties.end(); ++it)
×
603
                    {
604
                        if (algorithmProperties.value(it.key(), QString()) != it.value())
×
605
                            on = false;
×
606
                    }
607
                }
608
            }
609
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
610
            button->setDown(on);
×
611
        }
612
        else if (control->m_type == VCMatrixControl::Text)
×
613
        {
614
            bool on = false;
×
615
            if (algorithmType == RGBAlgorithm::Text)
×
616
            {
617
                if (algorithmText == control->m_resource)
×
618
                {
619
                    on = true;
×
620
                }
621
            }
622
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
623
            button->setDown(on);
×
624
        }
625
    }
626

627
    updateFeedback();
×
628
}
629

630
FunctionParent VCMatrix::functionParent() const
×
631
{
632
    return FunctionParent(FunctionParent::ManualVCWidget, id());
×
633
}
634

635
/*********************************************************************
636
 * Instant changes apply
637
 *********************************************************************/
638

639
void VCMatrix::setInstantChanges(bool instantly)
×
640
{
641
    m_instantApply = instantly;
×
642
}
×
643

644
bool VCMatrix::instantChanges() const
×
645
{
646
    return m_instantApply;
×
647
}
648

649
/*********************************************************************
650
 * Custom controls
651
 *********************************************************************/
652

NEW
653
void VCMatrix::slotMatrixControlKnobValueChanged(int controlID, int value)
×
654
{
NEW
655
    QList<VCMatrixControl *> customControls = this->customControls();
×
NEW
656
    for (int i = 0; i < customControls.length(); i++) {
×
NEW
657
        if (customControls[i]->m_id == controlID) {
×
NEW
658
            if (customControls[i]->m_type == VCMatrixControl::StartColorKnob || customControls[i]->m_type == VCMatrixControl::EndColorKnob) {
×
NEW
659
                KnobWidget *knob = qobject_cast<KnobWidget*>(this->getWidget(customControls[i]));
×
NEW
660
                knob->setValue(value);
×
NEW
661
                break;
×
662
            }
663
        }
664
    }
NEW
665
}
×
666

NEW
667
void VCMatrix::slotMatrixControlPushButtonClicked(int controlID)
×
668
{
NEW
669
    QList<VCMatrixControl *> customControls = this->customControls();
×
NEW
670
    for (int i = 0; i < customControls.length(); i++) {
×
NEW
671
        if (customControls[i]->m_id == controlID) {
×
NEW
672
            QPushButton *btn = qobject_cast<QPushButton*>(this->getWidget(customControls[i]));;
×
NEW
673
            emit btn->clicked();
×
NEW
674
            break;
×
675
        }
676
    }
NEW
677
}
×
678

UNCOV
679
void VCMatrix::addCustomControl(VCMatrixControl const& control)
×
680
{
681
    QWidget *controlWidget = NULL;
×
682

683
    if (control.m_type == VCMatrixControl::StartColor)
×
684
    {
685
        QPushButton *controlButton = new QPushButton(this);
×
686
        controlWidget = controlButton;
×
687
        controlButton->setStyleSheet(controlBtnSS.arg(control.m_color.name()));
×
688
        controlButton->setFixedWidth(36);
×
689
        controlButton->setFocusPolicy(Qt::TabFocus);
×
690
        controlButton->setText("S");
×
691
    }
692
    else if (control.m_type == VCMatrixControl::EndColor)
×
693
    {
694
        QPushButton *controlButton = new QPushButton(this);
×
695
        controlWidget = controlButton;
×
696
        controlButton->setStyleSheet(controlBtnSS.arg(control.m_color.name()));
×
697
        controlButton->setFixedWidth(36);
×
698
        controlButton->setFocusPolicy(Qt::TabFocus);
×
699
        controlButton->setText("E");
×
700
    }
701
    else if (control.m_type == VCMatrixControl::ResetEndColor)
×
702
    {
703
        QPushButton *controlButton = new QPushButton(this);
×
704
        controlWidget = controlButton;
×
705
        controlButton->setStyleSheet(controlBtnSS.arg("#BBBBBB"));
×
706
        controlButton->setMinimumWidth(36);
×
707
        controlButton->setMaximumWidth(80);
×
708
        controlButton->setFocusPolicy(Qt::TabFocus);
×
709
        QString btnLabel = tr("End Color Reset");
×
710
        controlButton->setToolTip(btnLabel);
×
711
        controlButton->setText(fontMetrics().elidedText(btnLabel, Qt::ElideRight, 72));
×
712
    }
713
    else if (control.m_type == VCMatrixControl::Animation ||
×
714
             control.m_type == VCMatrixControl::Text)
×
715
    {
716
        QPushButton *controlButton = new QPushButton(this);
×
717
        controlWidget = controlButton;
×
718
        controlButton->setStyleSheet(controlBtnSS.arg("#BBBBBB"));
×
719
        controlButton->setMinimumWidth(36);
×
720
        controlButton->setMaximumWidth(80);
×
721
        controlButton->setFocusPolicy(Qt::TabFocus);
×
722
        QString btnLabel = control.m_resource;
×
723
        if (!control.m_properties.isEmpty())
×
724
        {
725
            btnLabel += " (";
×
726
            QHashIterator<QString, QString> it(control.m_properties);
×
727
            while(it.hasNext())
×
728
            {
729
                it.next();
×
730
                btnLabel += it.value();
×
731
                if (it.hasNext())
×
732
                    btnLabel += ",";
×
733
            }
734
            btnLabel += ")";
×
735
        }
736
        controlButton->setToolTip(btnLabel);
×
737
        controlButton->setText(fontMetrics().elidedText(btnLabel, Qt::ElideRight, 72));
×
738
    }
739
    else if (control.m_type == VCMatrixControl::StartColorKnob)
×
740
    {
741
        KnobWidget *controlKnob = new KnobWidget(this);
×
742
        controlWidget = controlKnob;
×
743
        controlKnob->setColor(control.m_color);
×
744
        controlKnob->setFixedWidth(36);
×
745
        controlKnob->setFixedHeight(36);
×
746
        QString knobLabel;
×
747
        if (control.m_color == Qt::red)
×
748
            knobLabel = tr("Start color Red component");
×
749
        else if (control.m_color == Qt::green)
×
750
            knobLabel = tr("Start color Green component");
×
751
        else if (control.m_color == Qt::blue)
×
752
            knobLabel = tr("Start color Blue component");
×
753
        controlKnob->setToolTip(knobLabel);
×
754
    }
755
    else if (control.m_type == VCMatrixControl::EndColorKnob)
×
756
    {
757
        KnobWidget *controlKnob = new KnobWidget(this);
×
758
        controlWidget = controlKnob;
×
759
        controlKnob->setColor(control.m_color.darker(250));
×
760
        controlKnob->setFixedWidth(36);
×
761
        controlKnob->setFixedHeight(36);
×
762
        QString knobLabel;
×
763
        if (control.m_color == Qt::red)
×
764
            knobLabel = tr("End color Red component");
×
765
        else if (control.m_color == Qt::green)
×
766
            knobLabel = tr("End color Green component");
×
767
        else if (control.m_color == Qt::blue)
×
768
            knobLabel = tr("End color Blue component");
×
769
        controlKnob->setToolTip(knobLabel);
×
770
    }
771

772
    Q_ASSERT(controlWidget != NULL);
×
773

774
    if (control.widgetType() == VCMatrixControl::Knob)
×
775
    {
776
        connect(reinterpret_cast<KnobWidget*>(controlWidget), SIGNAL(valueChanged(int)),
×
777
                this, SLOT(slotCustomControlValueChanged()));
778
    }
779
    else
780
    {
781
        connect(reinterpret_cast<QPushButton*>(controlWidget), SIGNAL(clicked()),
×
782
                this, SLOT(slotCustomControlClicked()));
783
    }
784

785

786
    if (mode() == Doc::Design)
×
787
        controlWidget->setEnabled(false);
×
788

NEW
789
    VCMatrixControl *c_control = new VCMatrixControl(control);
×
NEW
790
    m_controls[controlWidget] = c_control;
×
NEW
791
    m_widgets[c_control] = controlWidget;
×
792

UNCOV
793
    m_controlsLayout->addWidget(controlWidget);
×
794

795
    if (m_controls[controlWidget]->m_inputSource != NULL)
×
796
    {
797
        setInputSource(m_controls[controlWidget]->m_inputSource, m_controls[controlWidget]->m_id);
×
798
    }
799

800
    slotFunctionChanged(); // Start update timer
×
801
}
×
802

803
void VCMatrix::resetCustomControls()
×
804
{
805
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
806
            it != m_controls.end(); ++it)
×
807
    {
808
        QWidget* widget = it.key();
×
809
        m_controlsLayout->removeWidget(widget);
×
810
        delete widget;
×
811

812
        VCMatrixControl* control = it.value();
×
813
        if (!control->m_inputSource.isNull())
×
814
            setInputSource(QSharedPointer<QLCInputSource>(), control->m_id);
×
815
        delete control;
×
816
    }
817
    m_controls.clear();
×
NEW
818
    m_widgets.clear();
×
UNCOV
819
}
×
820

821
QList<VCMatrixControl *> VCMatrix::customControls() const
×
822
{
823
    QList<VCMatrixControl*> controls = m_controls.values();
×
824
    std::sort(controls.begin(), controls.end(), VCMatrixControl::compare);
×
825
    return controls;
×
826
}
827

NEW
828
QWidget *VCMatrix::getWidget(VCMatrixControl* control) const
×
829
{
NEW
830
    return m_widgets[control];
×
831
}
832

UNCOV
833
void VCMatrix::slotCustomControlClicked()
×
834
{
835
    QPushButton *btn = qobject_cast<QPushButton*>(sender());
×
836
    VCMatrixControl *control = m_controls[btn];
×
837
    if (control != NULL)
×
838
    {
839
        RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
840
        if (matrix == NULL || mode() == Doc::Design)
×
841
            return;
×
842

843
        if (control->m_type == VCMatrixControl::StartColor)
×
844
        {
845
            matrix->setStartColor(control->m_color);
×
846
            if (instantChanges() == true)
×
847
                matrix->updateColorDelta();
×
848
            btn->setDown(true);
×
849
        }
850
        else if (control->m_type == VCMatrixControl::EndColor)
×
851
        {
852
            matrix->setEndColor(control->m_color);
×
853
            if (instantChanges() == true)
×
854
                matrix->updateColorDelta();
×
855
            btn->setDown(true);
×
856
        }
857
        else if (control->m_type == VCMatrixControl::ResetEndColor)
×
858
        {
859
            matrix->setEndColor(QColor());
×
860
            if (instantChanges() == true)
×
861
                matrix->updateColorDelta();
×
862
        }
863
        else if (control->m_type == VCMatrixControl::Animation)
×
864
        {
865
            RGBAlgorithm* algo = RGBAlgorithm::algorithm(m_doc, control->m_resource);
×
866
            if (!control->m_properties.isEmpty())
×
867
            {
868
                RGBScript *script = static_cast<RGBScript*> (algo);
×
869
                QHashIterator<QString, QString> it(control->m_properties);
×
870
                while(it.hasNext())
×
871
                {
872
                    it.next();
×
873
                    script->setProperty(it.key(), it.value());
×
874
                    matrix->setProperty(it.key(), it.value());
×
875
                }
876
            }
877
            matrix->setAlgorithm(algo);
×
878
            if (instantChanges() == true)
×
879
                matrix->updateColorDelta();
×
880
            btn->setDown(true);
×
881
        }
882
        else if (control->m_type == VCMatrixControl::Text)
×
883
        {
884
            RGBAlgorithm* algo = RGBAlgorithm::algorithm(m_doc, "Text");
×
885
            RGBText* text = static_cast<RGBText*> (algo);
×
886
            text->setText(control->m_resource);
×
887
            matrix->setAlgorithm(algo);
×
888
            if (instantChanges() == true)
×
889
                matrix->updateColorDelta();
×
890
            btn->setDown(true);
×
891
        }
892
    }
893
}
894

895
void VCMatrix::slotCustomControlValueChanged()
×
896
{
897
    KnobWidget *knob = qobject_cast<KnobWidget*>(sender());
×
898
    VCMatrixControl *control = m_controls[knob];
×
899
    if (control != NULL)
×
900
    {
NEW
901
        emit matrixControlKnobValueChanged(control->m_id, knob->value());
×
902
        RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
903
        if (matrix == NULL || mode() == Doc::Design)
×
904
            return;
×
905

906
        if (control->m_type == VCMatrixControl::StartColorKnob)
×
907
        {
908
            QRgb color = matrix->startColor().rgb();
×
909
            QRgb knobValueColor = control->valueToRgb(knob->value());
×
910
            color = (color & ~control->m_color.rgb()) | (knobValueColor & control->m_color.rgb());
×
911

912
            matrix->setStartColor(color);
×
913
            if (instantChanges() == true)
×
914
                matrix->updateColorDelta();
×
915
        }
916
        else if (control->m_type == VCMatrixControl::EndColorKnob)
×
917
        {
918
            QRgb color = matrix->endColor().rgb();
×
919
            QRgb knobValueColor = control->valueToRgb(knob->value());
×
920
            color = (color & ~control->m_color.rgb()) | (knobValueColor & control->m_color.rgb());
×
921

922
            matrix->setEndColor(color);
×
923
            if (instantChanges() == true)
×
924
                matrix->updateColorDelta();
×
925
        }
926
        else
927
        {
928
            // We are not supposed to be here
929
            Q_ASSERT(false);
×
930
        }
931
    }
932
}
933

934
void VCMatrix::slotModeChanged(Doc::Mode mode)
×
935
{
936
    if (mode == Doc::Operate)
×
937
        enableWidgetUI(true);
×
938
    else
939
        enableWidgetUI(false);
×
940

941
    VCWidget::slotModeChanged(mode);
×
942
}
×
943

944
/*********************************************************************
945
 * External input
946
 *********************************************************************/
947

948
void VCMatrix::slotKeyPressed(const QKeySequence &keySequence)
×
949
{
950
    if (acceptsInput() == false)
×
951
        return;
×
952

953
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
954
            it != m_controls.end(); ++it)
×
955
    {
956
        VCMatrixControl *control = it.value();
×
957
        if (control->m_keySequence == keySequence &&
×
958
                control->widgetType() == VCMatrixControl::Button) // Only for buttons
×
959
        {
960
            QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
961
            button->click();
×
962
        }
963
    }
964
}
965

966
void VCMatrix::updateFeedback()
×
967
{
968
    sendFeedback(m_slider->value());
×
969

970
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
971
            it != m_controls.end(); ++it)
×
972
    {
973
        VCMatrixControl *control = it.value();
×
974
        if (control->m_inputSource != NULL)
×
975
        {
976
            if (control->widgetType() == VCMatrixControl::Knob)
×
977
            {
978
                KnobWidget* knob = reinterpret_cast<KnobWidget*>(it.key());
×
979
                sendFeedback(knob->value(), control->m_inputSource);
×
980
            }
981
            else // if (control->widgetType() == VCMatrixControl::Button)
982
            {
983
                QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
984
                sendFeedback(button->isDown() ?
×
985
                                 control->m_inputSource->upperValue() :
×
986
                                 control->m_inputSource->lowerValue(),
×
987
                                 control->m_inputSource);
×
988
            }
989
        }
990
    }
991
}
×
992

993
void VCMatrix::slotInputValueChanged(quint32 universe, quint32 channel, uchar value)
×
994
{
995
    /* Don't let input data through in design mode or if disabled */
996
    if (acceptsInput() == false)
×
997
        return;
×
998

999
    quint32 pagedCh = (page() << 16) | channel;
×
1000

1001
    if (checkInputSource(universe, pagedCh, value, sender()))
×
1002
    {
1003
        m_slider->setValue((int) value);
×
1004
        return;
×
1005
    }
1006

1007
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
1008
            it != m_controls.end(); ++it)
×
1009
    {
1010
        VCMatrixControl *control = it.value();
×
1011
        if (control->m_inputSource != NULL &&
×
1012
                control->m_inputSource->universe() == universe &&
×
1013
                control->m_inputSource->channel() == pagedCh)
×
1014
        {
1015
            if (control->widgetType() == VCMatrixControl::Knob)
×
1016
            {
1017
                KnobWidget* knob = reinterpret_cast<KnobWidget*>(it.key());
×
1018
                knob->setValue(value);
×
1019
            }
1020
            else
1021
            {
1022
                QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
1023
                button->click();
×
1024
            }
1025
        }
1026
    }
1027
}
1028

1029
bool VCMatrix::loadXML(QXmlStreamReader &root)
×
1030
{
1031
    QString str;
×
1032

1033
    if (root.name() != KXMLQLCVCMatrix)
×
1034
    {
1035
        qWarning() << Q_FUNC_INFO << "Matrix node not found";
×
1036
        return false;
×
1037
    }
1038

1039
    /* Widget commons */
1040
    loadXMLCommon(root);
×
1041

1042
    // Sorted list for new controls
1043
    QList<VCMatrixControl> newControls;
×
1044

1045
    /* Children */
1046
    while (root.readNextStartElement())
×
1047
    {
1048
        if (root.name() == KXMLQLCWindowState)
×
1049
        {
1050
            bool visible = false;
×
1051
            int x = 0, y = 0, w = 0, h = 0;
×
1052
            loadXMLWindowState(root, &x, &y, &w, &h, &visible);
×
1053
            setGeometry(x, y, w, h);
×
1054
        }
1055
        else if (root.name() == KXMLQLCVCWidgetAppearance)
×
1056
        {
1057
            loadXMLAppearance(root);
×
1058
        }
1059
        else if (root.name() == KXMLQLCVCMatrixFunction)
×
1060
        {
1061
            QXmlStreamAttributes attrs = root.attributes();
×
1062
            str = attrs.value(KXMLQLCVCMatrixFunctionID).toString();
×
1063
            setFunction(str.toUInt());
×
1064
            if (attrs.hasAttribute(KXMLQLCVCMatrixInstantApply))
×
1065
                setInstantChanges(true);
×
1066
            root.skipCurrentElement();
×
1067
        }
1068
        else if (root.name() == KXMLQLCVCWidgetInput)
×
1069
        {
1070
            loadXMLInput(root);
×
1071
        }
1072
        else if(root.name() == KXMLQLCVCMatrixControl)
×
1073
        {
1074
            VCMatrixControl control(0xff);
×
1075
            if (control.loadXML(root))
×
1076
                newControls.insert(std::lower_bound(newControls.begin(), newControls.end(), control), control);
×
1077
        }
1078
        else if (root.name() == KXMLQLCVCMatrixVisibilityMask)
×
1079
        {
1080
            setVisibilityMask(root.readElementText().toUInt());
×
1081
        }
1082
        else
1083
        {
1084
            qWarning() << Q_FUNC_INFO << "Unknown VCMatrix tag:" << root.name().toString();
×
1085
            root.skipCurrentElement();
×
1086
        }
1087
    }
1088

1089
    foreach (VCMatrixControl const& control, newControls)
×
1090
        addCustomControl(control);
×
1091

1092
    return true;
×
1093
}
1094

1095
bool VCMatrix::saveXML(QXmlStreamWriter *doc)
×
1096
{
1097
    Q_ASSERT(doc != NULL);
×
1098

1099
    /* VC button entry */
1100
    doc->writeStartElement(KXMLQLCVCMatrix);
×
1101

1102
    saveXMLCommon(doc);
×
1103

1104
    /* Window state */
1105
    saveXMLWindowState(doc);
×
1106

1107
    /* Appearance */
1108
    saveXMLAppearance(doc);
×
1109

1110
    /* Function */
1111
    doc->writeStartElement(KXMLQLCVCMatrixFunction);
×
1112
    doc->writeAttribute(KXMLQLCVCMatrixFunctionID, QString::number(function()));
×
1113

1114
    if (instantChanges() == true)
×
1115
        doc->writeAttribute(KXMLQLCVCMatrixInstantApply, "true");
×
1116
    doc->writeEndElement();
×
1117

1118
    /* Default controls visibility  */
1119
    if (m_visibilityMask != VCMatrix::defaultVisibilityMask())
×
1120
        doc->writeTextElement(KXMLQLCVCMatrixVisibilityMask, QString::number(m_visibilityMask));
×
1121

1122
    /* Slider External input */
1123
    saveXMLInput(doc);
×
1124

1125
    foreach(VCMatrixControl *control, customControls())
×
1126
        control->saveXML(doc);
×
1127

1128
    /* End the <Matrix> tag */
1129
    doc->writeEndElement();
×
1130

1131
    return true;
×
1132
}
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