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

mcallegari / qlcplus / 10668847825

02 Sep 2024 02:18PM UTC coverage: 31.426% (-0.07%) from 31.498%
10668847825

push

github

web-flow
Merge pull request #1610 from Ledjlale/fix/qt6_rebase2

qmltoqt6 rebasing

25 of 290 new or added lines in 19 files covered. (8.62%)

25 existing lines in 11 files now uncovered.

15012 of 47769 relevant lines covered (31.43%)

19745.74 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

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

95
    connect(m_scCnGWidget, SIGNAL(colorChanged(QRgb)),
×
96
            this, SLOT(slotStartColorChanged(QRgb)));
97

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

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

111
    connect(m_ecCnGWidget, SIGNAL(colorChanged(QRgb)),
×
112
            this, SLOT(slotEndColorChanged(QRgb)));
113

114
    m_label = new QLabel(this);
×
115
    m_label->setAlignment(Qt::AlignCenter);
×
116
    m_label->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
×
117
    vbox->addWidget(m_label);
×
118

119
    QHBoxLayout *btnHbox = new QHBoxLayout();
×
120

121
    btnHbox->addWidget(m_startColorButton);
×
122
    btnHbox->addWidget(m_endColorButton);
×
123

124
    vbox->addLayout(btnHbox);
×
125

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

133
    hBox->addLayout(vbox);
×
134

135
    m_controlsLayout = new FlowLayout();
×
136
    vbox->addLayout(m_controlsLayout);
×
137

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

148
    /* Update timer */
149
    m_updateTimer = new QTimer(this);
×
150
    connect(m_updateTimer, SIGNAL(timeout()),
×
151
            this, SLOT(slotUpdate()));
152
    m_updateTimer->setSingleShot(true);
×
153

154
    /* Update the slider according to current mode */
155
    slotModeChanged(m_doc->mode());
×
156
    setLiveEdit(m_liveEdit);
×
157
}
×
158

159
VCMatrix::~VCMatrix()
×
160
{
161
    foreach (VCMatrixControl* control, m_controls)
×
162
    {
163
        delete control;
×
164
    }
165
}
×
166

167
void VCMatrix::setID(quint32 id)
×
168
{
169
    VCWidget::setID(id);
×
170

171
    if (caption().isEmpty())
×
172
        setCaption(tr("Animation %1").arg(id));
×
173
}
×
174

175
/*********************************************************************
176
 * Clipboard
177
 *********************************************************************/
178

179
VCWidget *VCMatrix::createCopy(VCWidget *parent)
×
180
{
181
    Q_ASSERT(parent != NULL);
×
182

183
    VCMatrix* matrix = new VCMatrix(parent, m_doc);
×
184
    if (matrix->copyFrom(this) == false)
×
185
    {
186
        delete matrix;
×
187
        matrix = NULL;
×
188
    }
189

190
    return matrix;
×
191
}
192

193
bool VCMatrix::copyFrom(const VCWidget* widget)
×
194
{
195
    const VCMatrix* matrix = qobject_cast <const VCMatrix*> (widget);
×
196
    if (matrix == NULL)
×
197
        return false;
×
198

199
    /* Copy vcmatrix-specific stuff */
200
    setFunction(matrix->function());
×
201
    setInstantChanges(matrix->instantChanges());
×
202
    setVisibilityMask(matrix->visibilityMask());
×
203

204
    resetCustomControls();
×
205
    foreach (VCMatrixControl const* control, matrix->customControls())
×
206
    {
207
        addCustomControl(*control);
×
208
    }
209

210
    /* Copy common stuff */
211
    return VCWidget::copyFrom(widget);
×
212
}
213

214
/*********************************************************************
215
 * GUI
216
 *********************************************************************/
217

218
void VCMatrix::setCaption(const QString &text)
×
219
{
220
    VCWidget::setCaption(text);
×
221
    m_label->setText(text);
×
222
}
×
223

224
void VCMatrix::enableWidgetUI(bool enable)
×
225
{
226
    m_slider->setEnabled(enable);
×
227
    m_startColorButton->setEnabled(enable);
×
228
    m_endColorButton->setEnabled(enable);
×
229
    m_presetCombo->setEnabled(enable);
×
230

231
    foreach (QWidget *ctlBtn, m_controls.keys())
×
232
        ctlBtn->setEnabled(enable);
×
233

234
    // Update buttons state
235
    if (enable)
×
236
        slotUpdate();
×
237
}
×
238

239
void VCMatrix::slotSetSliderValue(int value)
×
240
{
241
    m_slider->setValue(value);
×
242
    slotSliderMoved(value);
×
243
}
×
244

245
void VCMatrix::slotSliderMoved(int value)
×
246
{
247
    Function* function = m_doc->function(m_matrixID);
×
248
    if (function == NULL || mode() == Doc::Design)
×
249
        return;
×
250

251
    if (m_sliderExternalMovement)
×
252
        return;
×
253

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

276
    emit sliderValueChanged(value);
×
277
}
278

279
int VCMatrix::sliderValue()
×
280
{
281
    return m_slider->value();
×
282
}
283

284
void VCMatrix::slotSetStartColor(QColor color)
×
285
{
286
    RGBMatrix *matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
287
    if (matrix == NULL)
×
288
        return;
×
289

290
    if (matrix->startColor() != color)
×
291
    {
292
        matrix->setStartColor(color);
×
293
        emit startColorChanged();
×
294
    }
295
}
296

297
QColor VCMatrix::startColor()
×
298
{
299
    RGBMatrix *matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
300
    if (matrix == NULL)
×
301
        return QColor();
×
302

303
    return matrix->startColor();
×
304
}
305

306
void VCMatrix::slotStartColorChanged(QRgb color)
×
307
{
308
    QColor col(color);
×
309
    slotSetStartColor(col);
×
310
    QPixmap px(42, 42);
×
311
    px.fill(col);
×
312
    m_startColorButton->setIcon(px);
×
313

314
    RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
315
    if (matrix == NULL || mode() == Doc::Design)
×
316
        return;
×
317

318
    matrix->setStartColor(col);
×
319
    if (instantChanges() == true)
×
320
        matrix->updateColorDelta();
×
321
}
322

323
void VCMatrix::slotSetEndColor(QColor color)
×
324
{
325
    RGBMatrix *matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
326
    if (matrix == NULL)
×
327
        return;
×
328

329
    if (matrix->endColor() != color)
×
330
    {
331
        matrix->setEndColor(color);
×
332
        emit endColorChanged();
×
333
    }
334
}
335

336
QColor VCMatrix::endColor()
×
337
{
338
    RGBMatrix *matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
339
    if (matrix == NULL)
×
340
        return QColor();
×
341

342
    return matrix->endColor();
×
343
}
344

345
void VCMatrix::slotEndColorChanged(QRgb color)
×
346
{
347
    QColor col(color);
×
348
    slotSetEndColor(col);
×
349
    QPixmap px(42, 42);
×
350
    px.fill(col);
×
351
    m_endColorButton->setIcon(px);
×
352

353
    RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
354
    if (matrix == NULL || mode() == Doc::Design)
×
355
        return;
×
356

357
    matrix->setEndColor(col);
×
358
    if (instantChanges() == true)
×
359
        matrix->updateColorDelta();
×
360
}
361

362
void VCMatrix::slotSetAnimationValue(QString name)
×
363
{
364
    m_presetCombo->setCurrentText(name);
×
365
    slotAnimationChanged(name);
×
366
}
×
367

368
void VCMatrix::slotAnimationChanged(QString name)
×
369
{
370
    emit animationValueChanged(name);
×
371
    RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
372
    if (matrix == NULL || mode() == Doc::Design)
×
373
        return;
×
374

375
    RGBAlgorithm* algo = RGBAlgorithm::algorithm(m_doc, name);
×
376
    matrix->setAlgorithm(algo);
×
377
    if (instantChanges() == true)
×
378
        matrix->updateColorDelta();
×
379
}
380

381
QString VCMatrix::animationValue()
×
382
{
383
    return m_presetCombo->currentText();
×
384
}
385

386
void VCMatrix::setVisibilityMask(quint32 mask)
×
387
{
388
    if (mask & ShowSlider) m_slider->show();
×
389
    else m_slider->hide();
×
390

391
    if (mask & ShowLabel) m_label->show();
×
392
    else m_label->hide();
×
393

394
    if (mask & ShowStartColorButton) m_startColorButton->show();
×
395
    else m_startColorButton->hide();
×
396

397
    if (mask & ShowEndColorButton) m_endColorButton->show();
×
398
    else m_endColorButton->hide();
×
399

400
    if (mask & ShowPresetCombo) m_presetCombo->show();
×
401
    else m_presetCombo->hide();
×
402

403
    m_visibilityMask = mask;
×
404
}
×
405

406
quint32 VCMatrix::visibilityMask() const
×
407
{
408
    return m_visibilityMask;
×
409
}
410

411
quint32 VCMatrix::defaultVisibilityMask()
×
412
{
413
    return ShowSlider
414
        | ShowLabel
415
        | ShowStartColorButton
416
        | ShowEndColorButton
417
        | ShowPresetCombo
×
418
        ;
419
}
420

421
/*********************************************************************
422
 * Properties
423
 *********************************************************************/
424

425
void VCMatrix::editProperties()
×
426
{
427
    VCMatrixProperties prop(this, m_doc);
×
428
    if (prop.exec() == QDialog::Accepted)
×
429
        m_doc->setModified();
×
430
}
×
431

432
/*************************************************************************
433
 * VCWidget-inherited
434
 *************************************************************************/
435

436
void VCMatrix::adjustIntensity(qreal val)
×
437
{
438
    VCWidget::adjustIntensity(val);
×
439
    this->slotSliderMoved(this->m_slider->value());
×
440
}
×
441

442
/*********************************************************************
443
 * Function attachment
444
 *********************************************************************/
445

446
void VCMatrix::setFunction(quint32 id)
×
447
{
448
    Function *old = m_doc->function(m_matrixID);
×
449
    if (old != NULL)
×
450
    {
451
        disconnect(old, SIGNAL(stopped(quint32)),
×
452
                this, SLOT(slotFunctionStopped()));
453
        disconnect(old, SIGNAL(changed(quint32)),
×
454
                this, SLOT(slotFunctionChanged()));
455
    }
456

457
    RGBMatrix* matrix = qobject_cast<RGBMatrix*> (m_doc->function(id));
×
458

459
    if (matrix == NULL)
×
460
        m_matrixID = Function::invalidId();
×
461
    else
462
    {
463
        m_matrixID = id;
×
464
        connect(matrix, SIGNAL(stopped(quint32)),
×
465
                this, SLOT(slotFunctionStopped()));
466
        connect(matrix, SIGNAL(changed(quint32)),
×
467
                this, SLOT(slotFunctionChanged()));
468
    }
469

470
    slotUpdate();
×
471
}
×
472

473
quint32 VCMatrix::function() const
×
474
{
475
    return m_matrixID;
×
476
}
477

478
void VCMatrix::notifyFunctionStarting(quint32 fid, qreal functionIntensity)
×
479
{
480
    if (mode() == Doc::Design)
×
481
        return;
×
482

483
    if (fid == m_matrixID)
×
484
        return;
×
485

486
    int value = SCALE(1.0 - functionIntensity,
×
487
            0, 1.0,
488
            m_slider->minimum(), m_slider->maximum());
489
    if (m_slider->value() > value)
×
490
    {
491
        m_sliderExternalMovement = true;
×
492
        m_slider->setValue(value);
×
493
        m_sliderExternalMovement = false;
×
494

495
        Function* function = m_doc->function(m_matrixID);
×
496
        if (function != NULL)
×
497
        {
498
            qreal pIntensity = qreal(value) / qreal(UCHAR_MAX);
×
499
            adjustFunctionIntensity(function, pIntensity * intensity());
×
500
            if (value == 0 && !function->stopped())
×
501
            {
502
                function->stop(functionParent());
×
503
                resetIntensityOverrideAttribute();
×
504
            }
505
        }
506
    }
507
}
508

509
void VCMatrix::slotFunctionStopped()
×
510
{
511
    m_slider->blockSignals(true);
×
512
    m_slider->setValue(0);
×
513
    resetIntensityOverrideAttribute();
×
514
    m_slider->blockSignals(false);
×
515
}
×
516

517
void VCMatrix::slotFunctionChanged()
×
518
{
519
    m_updateTimer->start(UPDATE_TIMEOUT);
×
520
}
×
521

522
void VCMatrix::slotUpdate()
×
523
{
524
    if (m_matrixID == Function::invalidId())
×
525
        return;
×
526

527
    RGBMatrix *matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
528
    if (matrix == NULL)
×
529
        return;
×
530

531
    QColor startColor = matrix->startColor();
×
532
    QColor endColor = matrix->endColor();
×
533
    QString algorithmName;
×
534
    RGBAlgorithm::Type algorithmType = RGBAlgorithm::Plain;
×
535
    QHash<QString, QString> algorithmProperties;
×
536
    QString algorithmText;
×
537

538
    {
539
        QMutexLocker locker(&matrix->algorithmMutex());
×
540

541
        RGBAlgorithm *algo = matrix->algorithm();
×
542
        if (algo != NULL)
×
543
        {
544
            algorithmName = algo->name();
×
545
            algorithmType = algo->type();
×
546
            if (algorithmType == RGBAlgorithm::Script)
×
547
            {
548
                algorithmProperties = reinterpret_cast<RGBScript*>(algo)->propertiesAsStrings();
×
549
            }
550
            else if (algorithmType == RGBAlgorithm::Text)
×
551
            {
552
                algorithmText = reinterpret_cast<RGBText*>(algo)->text();
×
553
            }
554
        }
555
    }
556

557
    // Start / End color buttons
558
    QPixmap px(42, 42);
×
559
    px.fill(startColor);
×
560
    m_startColorButton->setIcon(px);
×
561
    slotSetStartColor(startColor);
×
562

563
    px.fill(endColor == QColor() ? Qt::transparent : endColor);
×
564
    m_endColorButton->setIcon(px);
×
565
    slotSetEndColor(endColor);
×
566

567
    // Algo combo box
568
    if (algorithmName != QString())
×
569
    {
570
        m_presetCombo->blockSignals(true);
×
571
        m_presetCombo->setCurrentText(algorithmName);
×
572
        m_presetCombo->blockSignals(false);
×
573
    }
574

575
    // Custom Buttons
576
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
577
            it != m_controls.end(); ++it)
×
578
    {
579
        QWidget *widget = it.key();
×
580
        VCMatrixControl *control = it.value();
×
581

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

631
            QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
632
            button->setDown(on);
×
633
        }
634
        else if (control->m_type == VCMatrixControl::Text)
×
635
        {
636
            bool on = false;
×
637
            if (algorithmType == RGBAlgorithm::Text &&
×
638
                algorithmText == control->m_resource)
×
639
            {
640
                on = true;
×
641
            }
642

643
            QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
644
            button->setDown(on);
×
645
        }
646
    }
647

648
    updateFeedback();
×
649
}
650

651
FunctionParent VCMatrix::functionParent() const
×
652
{
653
    return FunctionParent(FunctionParent::ManualVCWidget, id());
×
654
}
655

656
/*********************************************************************
657
 * Instant changes apply
658
 *********************************************************************/
659

660
void VCMatrix::setInstantChanges(bool instantly)
×
661
{
662
    m_instantApply = instantly;
×
663
}
×
664

665
bool VCMatrix::instantChanges() const
×
666
{
667
    return m_instantApply;
×
668
}
669

670
/*********************************************************************
671
 * Custom controls
672
 *********************************************************************/
673

674
void VCMatrix::addCustomControl(VCMatrixControl const& control)
×
675
{
676
    QWidget *controlWidget = NULL;
×
677

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

767
    Q_ASSERT(controlWidget != NULL);
×
768

769
    if (control.widgetType() == VCMatrixControl::Knob)
×
770
    {
771
        connect(reinterpret_cast<KnobWidget*>(controlWidget), SIGNAL(valueChanged(int)),
×
772
                this, SLOT(slotCustomControlValueChanged()));
773
    }
774
    else
775
    {
776
        connect(reinterpret_cast<QPushButton*>(controlWidget), SIGNAL(clicked()),
×
777
                this, SLOT(slotCustomControlClicked()));
778
    }
779

780

781
    if (mode() == Doc::Design)
×
782
        controlWidget->setEnabled(false);
×
783

784
    VCMatrixControl *c_control = new VCMatrixControl(control);
×
785
    m_controls[controlWidget] = c_control;
×
786
    m_widgets[c_control] = controlWidget;
×
787

788
    m_controlsLayout->addWidget(controlWidget);
×
789

790
    if (m_controls[controlWidget]->m_inputSource != NULL)
×
791
    {
792
        setInputSource(m_controls[controlWidget]->m_inputSource, m_controls[controlWidget]->m_id);
×
793
    }
794

795
    slotFunctionChanged(); // Start update timer
×
796
}
×
797

798
void VCMatrix::resetCustomControls()
×
799
{
800
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
801
            it != m_controls.end(); ++it)
×
802
    {
803
        QWidget* widget = it.key();
×
804
        m_controlsLayout->removeWidget(widget);
×
805
        delete widget;
×
806

807
        VCMatrixControl* control = it.value();
×
808
        if (!control->m_inputSource.isNull())
×
809
            setInputSource(QSharedPointer<QLCInputSource>(), control->m_id);
×
810
        delete control;
×
811
    }
812
    m_controls.clear();
×
813
    m_widgets.clear();
×
814
}
×
815

816
QList<VCMatrixControl *> VCMatrix::customControls() const
×
817
{
818
    QList<VCMatrixControl*> controls = m_controls.values();
×
819
    std::sort(controls.begin(), controls.end(), VCMatrixControl::compare);
×
820
    return controls;
×
821
}
822

NEW
823
QMap<quint32,QString> VCMatrix::customControlsMap() const
×
824
{
NEW
825
    QMap<quint32,QString> map;
×
826

NEW
827
    foreach (VCMatrixControl *control, m_controls.values())
×
NEW
828
        map.insert(control->m_id, VCMatrixControl::typeToString(control->m_type));
×
829

NEW
830
    return map;
×
831
}
832

UNCOV
833
QWidget *VCMatrix::getWidget(VCMatrixControl* control) const
×
834
{
835
    return m_widgets[control];
×
836
}
837

838
void VCMatrix::slotCustomControlClicked()
×
839
{
840
    QPushButton *btn = qobject_cast<QPushButton*>(sender());
×
841
    VCMatrixControl *control = m_controls[btn];
×
842
    if (control != NULL)
×
843
    {
844
        RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
845
        if (matrix == NULL || mode() == Doc::Design)
×
846
            return;
×
847

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

903
void VCMatrix::slotCustomControlValueChanged()
×
904
{
905
    KnobWidget *knob = qobject_cast<KnobWidget*>(sender());
×
906
    VCMatrixControl *control = m_controls[knob];
×
907
    if (control != NULL)
×
908
    {
909
        RGBMatrix* matrix = qobject_cast<RGBMatrix*>(m_doc->function(m_matrixID));
×
910
        if (matrix == NULL || mode() == Doc::Design)
×
911
            return;
×
912

913
        if (control->m_type == VCMatrixControl::StartColorKnob)
×
914
        {
915
            QRgb color = matrix->startColor().rgb();
×
916
            QRgb knobValueColor = control->valueToRgb(knob->value());
×
917
            color = (color & ~control->m_color.rgb()) | (knobValueColor & control->m_color.rgb());
×
918

919
            matrix->setStartColor(color);
×
920
            if (instantChanges() == true)
×
921
                matrix->updateColorDelta();
×
922
            emit startColorChanged();
×
923
        }
924
        else if (control->m_type == VCMatrixControl::EndColorKnob)
×
925
        {
926
            QRgb color = matrix->endColor().rgb();
×
927
            QRgb knobValueColor = control->valueToRgb(knob->value());
×
928
            color = (color & ~control->m_color.rgb()) | (knobValueColor & control->m_color.rgb());
×
929

930
            matrix->setEndColor(color);
×
931
            if (instantChanges() == true)
×
932
                matrix->updateColorDelta();
×
933
            emit endColorChanged();
×
934
        }
935
        else
936
        {
937
            // We are not supposed to be here
938
            Q_ASSERT(false);
×
939
        }
940
        emit matrixControlKnobValueChanged(control->m_id, knob->value());
×
941
    }
942
}
943

944
void VCMatrix::slotMatrixControlKnobValueChanged(int controlID, int value)
×
945
{
946
    QList<VCMatrixControl *> customControls = this->customControls();
×
947
    for (int i = 0; i < customControls.length(); i++)
×
948
    {
949
        if (customControls[i]->m_id == controlID)
×
950
        {
951
            if (customControls[i]->m_type == VCMatrixControl::StartColorKnob || customControls[i]->m_type == VCMatrixControl::EndColorKnob)
×
952
            {
953
                KnobWidget *knob = qobject_cast<KnobWidget*>(this->getWidget(customControls[i]));
×
954
                knob->setValue(value);
×
955
                break;
×
956
            }
957
        }
958
    }
959
}
×
960

961
void VCMatrix::slotMatrixControlPushButtonClicked(int controlID)
×
962
{
963
    QList<VCMatrixControl *> customControls = this->customControls();
×
964
    for (int i = 0; i < customControls.length(); i++)
×
965
    {
966
        if (customControls[i]->m_id == controlID)
×
967
        {
968
            QPushButton *btn = qobject_cast<QPushButton*>(this->getWidget(customControls[i]));
×
969
            btn->click();
×
970
            break;
×
971
        }
972
    }
973
}
×
974

975
void VCMatrix::slotModeChanged(Doc::Mode mode)
×
976
{
977
    if (mode == Doc::Operate)
×
978
        enableWidgetUI(true);
×
979
    else
980
        enableWidgetUI(false);
×
981

982
    VCWidget::slotModeChanged(mode);
×
983
}
×
984

985
/*********************************************************************
986
 * External input
987
 *********************************************************************/
988

989
void VCMatrix::slotKeyPressed(const QKeySequence &keySequence)
×
990
{
991
    if (acceptsInput() == false)
×
992
        return;
×
993

994
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
995
            it != m_controls.end(); ++it)
×
996
    {
997
        VCMatrixControl *control = it.value();
×
998
        if (control->m_keySequence == keySequence &&
×
999
                control->widgetType() == VCMatrixControl::Button) // Only for buttons
×
1000
        {
1001
            QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
1002
            button->click();
×
1003
        }
1004
    }
1005
}
1006

1007
void VCMatrix::updateFeedback()
×
1008
{
1009
    sendFeedback(m_slider->value());
×
1010

1011
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
1012
            it != m_controls.end(); ++it)
×
1013
    {
1014
        VCMatrixControl *control = it.value();
×
1015
        if (control->m_inputSource != NULL)
×
1016
        {
1017
            if (control->widgetType() == VCMatrixControl::Knob)
×
1018
            {
1019
                KnobWidget* knob = reinterpret_cast<KnobWidget*>(it.key());
×
1020
                sendFeedback(knob->value(), control->m_inputSource);
×
1021
            }
1022
            else // if (control->widgetType() == VCMatrixControl::Button)
1023
            {
1024
                QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
1025
                sendFeedback(button->isDown() ?
×
1026
                                 control->m_inputSource->feedbackValue(QLCInputFeedback::UpperValue) :
×
1027
                                 control->m_inputSource->feedbackValue(QLCInputFeedback::LowerValue),
×
1028
                                 control->m_inputSource);
×
1029
            }
1030
        }
1031
    }
1032
}
×
1033

1034
void VCMatrix::slotInputValueChanged(quint32 universe, quint32 channel, uchar value)
×
1035
{
1036
    /* Don't let input data through in design mode or if disabled */
1037
    if (acceptsInput() == false)
×
1038
        return;
×
1039

1040
    quint32 pagedCh = (page() << 16) | channel;
×
1041

1042
    if (checkInputSource(universe, pagedCh, value, sender()))
×
1043
    {
1044
        m_slider->setValue((int) value);
×
1045
        return;
×
1046
    }
1047

1048
    for (QHash<QWidget *, VCMatrixControl *>::iterator it = m_controls.begin();
×
1049
            it != m_controls.end(); ++it)
×
1050
    {
1051
        VCMatrixControl *control = it.value();
×
1052
        if (control->m_inputSource != NULL &&
×
1053
                control->m_inputSource->universe() == universe &&
×
1054
                control->m_inputSource->channel() == pagedCh)
×
1055
        {
1056
            if (control->widgetType() == VCMatrixControl::Knob)
×
1057
            {
1058
                KnobWidget* knob = reinterpret_cast<KnobWidget*>(it.key());
×
1059
                knob->setValue(value);
×
1060
            }
1061
            else
1062
            {
1063
                QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
1064
                button->click();
×
1065
            }
1066
        }
1067
    }
1068
}
1069

1070
bool VCMatrix::loadXML(QXmlStreamReader &root)
×
1071
{
1072
    QString str;
×
1073

1074
    if (root.name() != KXMLQLCVCMatrix)
×
1075
    {
1076
        qWarning() << Q_FUNC_INFO << "Matrix node not found";
×
1077
        return false;
×
1078
    }
1079

1080
    /* Widget commons */
1081
    loadXMLCommon(root);
×
1082

1083
    // Sorted list for new controls
1084
    QList<VCMatrixControl> newControls;
×
1085

1086
    /* Children */
1087
    while (root.readNextStartElement())
×
1088
    {
1089
        if (root.name() == KXMLQLCWindowState)
×
1090
        {
1091
            bool visible = false;
×
1092
            int x = 0, y = 0, w = 0, h = 0;
×
1093
            loadXMLWindowState(root, &x, &y, &w, &h, &visible);
×
1094
            setGeometry(x, y, w, h);
×
1095
        }
1096
        else if (root.name() == KXMLQLCVCWidgetAppearance)
×
1097
        {
1098
            loadXMLAppearance(root);
×
1099
        }
1100
        else if (root.name() == KXMLQLCVCMatrixFunction)
×
1101
        {
1102
            QXmlStreamAttributes attrs = root.attributes();
×
1103
            str = attrs.value(KXMLQLCVCMatrixFunctionID).toString();
×
1104
            setFunction(str.toUInt());
×
1105
            if (attrs.hasAttribute(KXMLQLCVCMatrixInstantApply))
×
1106
                setInstantChanges(true);
×
1107
            root.skipCurrentElement();
×
1108
        }
1109
        else if (root.name() == KXMLQLCVCWidgetInput)
×
1110
        {
1111
            loadXMLInput(root);
×
1112
        }
1113
        else if (root.name() == KXMLQLCVCMatrixControl)
×
1114
        {
1115
            VCMatrixControl control(0xff);
×
1116
            if (control.loadXML(root))
×
1117
                newControls.insert(std::lower_bound(newControls.begin(), newControls.end(), control), control);
×
1118
        }
1119
        else if (root.name() == KXMLQLCVCMatrixVisibilityMask)
×
1120
        {
1121
            setVisibilityMask(root.readElementText().toUInt());
×
1122
        }
1123
        else
1124
        {
1125
            qWarning() << Q_FUNC_INFO << "Unknown VCMatrix tag:" << root.name().toString();
×
1126
            root.skipCurrentElement();
×
1127
        }
1128
    }
1129

1130
    foreach (VCMatrixControl const& control, newControls)
×
1131
        addCustomControl(control);
×
1132

1133
    return true;
×
1134
}
1135

1136
bool VCMatrix::saveXML(QXmlStreamWriter *doc)
×
1137
{
1138
    Q_ASSERT(doc != NULL);
×
1139

1140
    /* VC button entry */
1141
    doc->writeStartElement(KXMLQLCVCMatrix);
×
1142

1143
    saveXMLCommon(doc);
×
1144

1145
    /* Window state */
1146
    saveXMLWindowState(doc);
×
1147

1148
    /* Appearance */
1149
    saveXMLAppearance(doc);
×
1150

1151
    /* Function */
1152
    doc->writeStartElement(KXMLQLCVCMatrixFunction);
×
1153
    doc->writeAttribute(KXMLQLCVCMatrixFunctionID, QString::number(function()));
×
1154

1155
    if (instantChanges() == true)
×
1156
        doc->writeAttribute(KXMLQLCVCMatrixInstantApply, "true");
×
1157
    doc->writeEndElement();
×
1158

1159
    /* Default controls visibility  */
1160
    if (m_visibilityMask != VCMatrix::defaultVisibilityMask())
×
1161
        doc->writeTextElement(KXMLQLCVCMatrixVisibilityMask, QString::number(m_visibilityMask));
×
1162

1163
    /* Slider External input */
1164
    saveXMLInput(doc);
×
1165

1166
    foreach (VCMatrixControl *control, customControls())
×
1167
        control->saveXML(doc);
×
1168

1169
    /* End the <Matrix> tag */
1170
    doc->writeEndElement();
×
1171

1172
    return true;
×
1173
}
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