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

mcallegari / qlcplus / 19144422256

06 Nov 2025 05:33PM UTC coverage: 34.256% (-0.1%) from 34.358%
19144422256

push

github

mcallegari
Back to 5.1.0 debug

17718 of 51723 relevant lines covered (34.26%)

19528.23 hits per line

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

63.72
/ui/src/grandmasterslider.cpp
1
/*
2
  Q Light Controller
3
  grandmasterslider.cpp
4

5
  Copyright (c) Heikki Junnila
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 <QVBoxLayout>
21
#include <QHBoxLayout>
22
#include <QSlider>
23
#include <QLabel>
24
#include <cmath>
25

26
#include "grandmasterslider.h"
27
#include "clickandgoslider.h"
28
#include "qlcinputchannel.h"
29
#include "virtualconsole.h"
30
#include "vcproperties.h"
31
#include "inputpatch.h"
32
#include "apputil.h"
33

34
GrandMasterSlider::GrandMasterSlider(QWidget* parent, InputOutputMap *ioMap)
76✔
35
    : QFrame(parent)
36
    , m_ioMap(ioMap)
76✔
37
{
38
    Q_ASSERT(ioMap != NULL);
76✔
39

40
    QString sStyle = AppUtil::getStyleSheet("GRANDMASTER");
76✔
41
    if (sStyle.isEmpty())
76✔
42
        sStyle = "QFrame { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #D6D2D0, stop: 1 #AFACAB); "
43
                 "border: 1px solid gray; border-radius: 4px; }";
76✔
44
    setStyleSheet(sStyle);
76✔
45
    setSizePolicy(QSizePolicy::Maximum, QSizePolicy::MinimumExpanding);
76✔
46

47
    setMinimumSize(QSize(40, 100));
76✔
48
    setMaximumSize(QSize(40, USHRT_MAX));
76✔
49

50
    new QVBoxLayout(this);
76✔
51
    layout()->setContentsMargins(2, 2, 2, 2);
76✔
52

53
    m_valueLabel = new QLabel(this);
76✔
54
    m_valueLabel->setAlignment(Qt::AlignHCenter);
76✔
55
    m_valueLabel->setStyleSheet("QFrame { background-color: transparent; border: 0px; border-radius: 0px; }");
76✔
56
    layout()->addWidget(m_valueLabel);
76✔
57

58
    m_slider = new ClickAndGoSlider(this);
76✔
59
    m_slider->setRange(0, UCHAR_MAX);
76✔
60
    m_slider->setStyleSheet(
76✔
61
        "QSlider::groove:vertical { background: transparent; width: 28px; } "
62

63
        "QSlider::handle:vertical { "
64
        "background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #A81919, stop:0.45 #DB2020, stop:0.50 #000, stop:0.55 #DB2020, stop:1 #A81919);"
65
        "border: 1px solid #5c5c5c;"
66
        "border-radius: 4px; margin: 0 -1px; height: 20px; }"
67

68
        "QSlider::handle:vertical:hover {"
69
        "background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #DB2020, stop:0.45 #F51C1C, stop:0.50 #fff, stop:0.55 #F51C1C, stop:1 #DB2020);"
70
        "border: 1px solid #000; }"
71

72
        "QSlider::add-page:vertical { background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #78d, stop: 1 #97CDEC );"
73
        "border: 1px solid #5288A7; margin: 0 11px; }"
74

75
        "QSlider::sub-page:vertical { background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #888, stop: 1 #ddd );"
76
        "border: 1px solid #8E8A86; margin: 0 11px; }"
77

78
        "QSlider::handle:vertical:disabled { background: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #ddd, stop:0.45 #888, stop:0.50 #444, stop:0.55 #888, stop:1 #999);"
79
        "border: 1px solid #666; }"
80
        );
81
    m_slider->setMinimumSize(QSize(30, 50));
76✔
82
    m_slider->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::MinimumExpanding);
76✔
83
    layout()->addWidget(m_slider);
76✔
84
    layout()->setAlignment(m_slider, Qt::AlignHCenter);
76✔
85
    m_slider->setValue(255);
76✔
86
    connect(m_slider, SIGNAL(valueChanged(int)),
76✔
87
            this, SLOT(slotValueChanged(int)));
88

89
    m_nameLabel = new QLabel(this);
76✔
90
    m_nameLabel->setWordWrap(true);
76✔
91
    m_nameLabel->setAlignment(Qt::AlignHCenter);
76✔
92
    m_nameLabel->setText(tr("GM"));
76✔
93
    layout()->addWidget(m_nameLabel);
76✔
94

95
    /* Listen to GM value changes */
96
    connect(m_ioMap, SIGNAL(grandMasterValueChanged(uchar)),
76✔
97
            this, SLOT(slotGrandMasterValueChanged(uchar)));
98
    connect(m_ioMap, SIGNAL(grandMasterValueModeChanged(GrandMaster::ValueMode)),
76✔
99
            this, SLOT(slotGrandMasterValueModeChanged(GrandMaster::ValueMode)));
100

101
    /* External input connection */
102
    connect(m_ioMap, SIGNAL(inputValueChanged(quint32, quint32, uchar)),
76✔
103
            this, SLOT(slotInputValueChanged(quint32, quint32, uchar)));
104

105
    updateTooltip();
76✔
106
    updateDisplayValue();
76✔
107
}
76✔
108

109
GrandMasterSlider::~GrandMasterSlider()
152✔
110
{
111
}
152✔
112

113
bool GrandMasterSlider::invertedAppearance() const
×
114
{
115
    Q_ASSERT(m_slider != NULL);
×
116
    return m_slider->invertedAppearance();
×
117
}
118

119
void GrandMasterSlider::setInvertedAppearance(bool invert)
76✔
120
{
121
    Q_ASSERT(m_slider != NULL);
76✔
122
    m_slider->setInvertedAppearance(invert);
76✔
123
    sendFeedback();
76✔
124
}
76✔
125

126
void GrandMasterSlider::slotValueChanged(int value)
×
127
{
128
    // Update display value
129
    updateDisplayValue();
×
130

131
    // Avoid double calls triggered by slotGrandMasterValueChanged
132
    int curval = m_ioMap->grandMasterValue();
×
133
    if (value != curval)
×
134
    {
135
        // Write new grand master value to universes
136
        m_ioMap->setGrandMasterValue(value);
×
137
    }
138
}
×
139

140
void GrandMasterSlider::updateTooltip()
76✔
141
{
142
    QString tooltip;
76✔
143

144
    switch (m_ioMap->grandMasterValueMode())
76✔
145
    {
146
        case GrandMaster::Limit:
×
147
            tooltip += tr("Grand Master <B>limits</B> the maximum value of");
×
148
            break;
×
149
        case GrandMaster::Reduce:
76✔
150
            tooltip += tr("Grand Master <B>reduces</B> the current value of");
76✔
151
            break;
76✔
152
    }
153

154
    tooltip += QString(" ");
76✔
155

156
    switch (m_ioMap->grandMasterChannelMode())
76✔
157
    {
158
        case GrandMaster::Intensity:
76✔
159
            tooltip += tr("intensity channels");
76✔
160
            break;
76✔
161
        case GrandMaster::AllChannels:
×
162
            tooltip += tr("all channels");
×
163
            break;
×
164
    }
165

166
    setToolTip(tooltip);
76✔
167
}
76✔
168

169
void GrandMasterSlider::updateDisplayValue()
76✔
170
{
171
    int value = m_slider->value();
76✔
172
    QString str;
76✔
173
    if (m_ioMap->grandMasterValueMode() == GrandMaster::Limit)
76✔
174
    {
175
        str = QString("%1").arg(value, 3, 10, QChar('0'));
×
176
    }
177
    else
178
    {
179
        int p = floor(((double(value) / double(UCHAR_MAX)) * double(100)) + 0.5);
76✔
180
        str = QString("%1%").arg(p, 2, 10, QChar('0'));
76✔
181
    }
182
    m_valueLabel->setText(str);
76✔
183
    sendFeedback();
76✔
184
}
76✔
185

186
void GrandMasterSlider::slotGrandMasterValueChanged(uchar value)
×
187
{
188
    m_slider->blockSignals(true);
×
189
    m_slider->setValue(value);
×
190
    m_slider->blockSignals(false);
×
191

192
    updateDisplayValue();
×
193
}
×
194

195
void GrandMasterSlider::slotGrandMasterValueModeChanged(GrandMaster::ValueMode mode)
×
196
{
197
    Q_UNUSED(mode);
198
    updateTooltip();
×
199
    updateDisplayValue();
×
200
}
×
201

202
void GrandMasterSlider::sendFeedback()
152✔
203
{
204
    quint32 universe = VirtualConsole::instance()->properties().grandMasterInputUniverse();
152✔
205
    quint32 channel = VirtualConsole::instance()->properties().grandMasterInputChannel();
152✔
206
    QString chName;
152✔
207

208
    if (universe == InputOutputMap::invalidUniverse() || channel == QLCChannel::invalid())
152✔
209
        return;
152✔
210

211
    InputPatch* pat = m_ioMap->inputPatch(universe);
×
212
    if (pat != NULL)
×
213
    {
214
        QLCInputProfile* profile = pat->profile();
×
215
        if (profile != NULL)
×
216
        {
217
            QLCInputChannel* ich = profile->channel(channel);
×
218
            if (ich != NULL)
×
219
                chName = ich->name();
×
220
        }
221
    }
222
    if (m_slider->invertedAppearance())
×
223
        m_ioMap->sendFeedBack(universe, channel, UCHAR_MAX - m_slider->value(), chName);
×
224
    else
225
        m_ioMap->sendFeedBack(universe, channel, m_slider->value(), chName);
×
226
}
152✔
227

228
/*****************************************************************************
229
 * External input
230
 *****************************************************************************/
231

232
void GrandMasterSlider::slotInputValueChanged(quint32 universe, quint32 channel, uchar value)
×
233
{
234
    if (universe == VirtualConsole::instance()->properties().grandMasterInputUniverse() &&
×
235
        channel == VirtualConsole::instance()->properties().grandMasterInputChannel())
×
236
    {
237
        m_slider->setValue(value);
×
238
    }
239
}
×
240

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

© 2026 Coveralls, Inc