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

mcallegari / qlcplus / 7252848206

18 Dec 2023 07:26PM UTC coverage: 32.067% (+0.001%) from 32.066%
7252848206

push

github

mcallegari
Code style review #1427

199 of 628 new or added lines in 101 files covered. (31.69%)

8 existing lines in 2 files now uncovered.

15169 of 47304 relevant lines covered (32.07%)

23733.74 hits per line

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

5.69
/ui/src/clickandgowidget.cpp
1
/*
2
  Q Light Controller Plus
3
  clickandgowidget.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 <QApplication>
21
#include <QMouseEvent>
22
#include <QPainter>
23
#include <QScreen>
24
#include <qmath.h>
25
#include <QDebug>
26
#include <QImage>
27

28
#include "clickandgowidget.h"
29
#include "qlccapability.h"
30
#include "qlcmacros.h"
31
#include "gradient.h"
32

33
#define CELL_W  150
34
#define CELL_H  45
35
#define TITLE_H  18
36

37
ClickAndGoWidget::ClickAndGoWidget(QWidget *parent) :
1✔
38
    QWidget(parent)
1✔
39
{
40
    // This makes the application crash when a clickAndGoWidget
41
    // is created in a QDialog.
42
    //    setAttribute(Qt::WA_StaticContents);
43

44
    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
1✔
45
    setMouseTracking(true);
1✔
46

47
    m_type = None;
1✔
48
    m_linearColor = false;
1✔
49
    m_width = 10;
1✔
50
    m_height = 10;
1✔
51
    m_cols = 0;
1✔
52
    m_rows = 0;
1✔
53
    m_cellWidth = CELL_W;
1✔
54
    m_hoverCellIdx = -1;
1✔
55
    m_cellBarXpos = 1;
1✔
56
    m_cellBarYpos = 1;
1✔
57
    m_cellBarWidth = 0;
1✔
58
}
1✔
59

60
void ClickAndGoWidget::setupGradient(QColor begin, QColor end)
×
61
{
62
    QLinearGradient linearGrad(QPointF(10,0), QPointF(266, 0));
×
63
    linearGrad.setColorAt(0, begin);
×
64
    linearGrad.setColorAt(1, end);
×
65

66
    // create image and fill it with gradient
67
    m_width = 276;
×
68
    m_height = 40;
×
69
    m_image = QImage(m_width, m_height, QImage::Format_RGB32);
×
70
    QPainter painter(&m_image);
×
71
    painter.fillRect(m_image.rect(), linearGrad);
×
72

73
    m_linearColor = true;
×
74
}
×
75

76
void ClickAndGoWidget::setupColorPicker()
×
77
{
78
    int cw = 15;
×
79

80
    m_width = 256 + 30;
×
81
    m_height = 256;
×
82
    m_image = QImage(m_width, m_height, QImage::Format_RGB32);
×
83
    QPainter painter(&m_image);
×
84

85
    // Draw 16 default color squares
86
    painter.fillRect(0, 0, cw, 32, QColor(Qt::white));
×
87
    painter.fillRect(cw, 0, cw, 32, QColor(Qt::black));
×
88
    painter.fillRect(0, 32, cw, 64, QColor(Qt::red));
×
89
    painter.fillRect(cw, 32, cw, 64, QColor(Qt::darkRed));
×
90
    painter.fillRect(0, 64, cw, 96, QColor(Qt::green));
×
91
    painter.fillRect(cw, 64, cw, 96, QColor(Qt::darkGreen));
×
92
    painter.fillRect(0, 96, cw, 128, QColor(Qt::blue));
×
93
    painter.fillRect(cw, 96, cw, 128, QColor(Qt::darkBlue));
×
94
    painter.fillRect(0, 128, cw, 160, QColor(Qt::cyan));
×
95
    painter.fillRect(cw, 128, cw, 160, QColor(Qt::darkCyan));
×
96
    painter.fillRect(0, 160, cw, 192, QColor(Qt::magenta));
×
97
    painter.fillRect(cw, 160, cw, 192, QColor(Qt::darkMagenta));
×
98
    painter.fillRect(0, 192, cw, 224, QColor(Qt::yellow));
×
99
    painter.fillRect(cw, 192, cw, 224, QColor(Qt::darkYellow));
×
100
    painter.fillRect(0, 224, cw, 256, QColor(Qt::gray));
×
101
    painter.fillRect(cw, 224, cw, 256, QColor(Qt::darkGray));
×
102

103
    painter.drawImage(cw * 2, 0, Gradient::getRGBGradient());
×
104
}
×
105

106
void ClickAndGoWidget::setType(int type, const QLCChannel *chan)
×
107
{
108
    m_linearColor = false;
×
109
    //qDebug() << Q_FUNC_INFO << "Type: " << type;
110
    if (type == None)
×
111
    {
112
        m_image = QImage();
×
113
    }
114
    else if (type == Red)
×
115
        setupGradient(Qt::black, Qt::red);
×
116
    else if (type == Green)
×
117
        setupGradient(Qt::black, Qt::green);
×
118
    else if (type == Blue)
×
119
        setupGradient(Qt::black, Qt::blue);
×
120
    else if (type == Cyan)
×
121
        setupGradient(Qt::white, Qt::cyan);
×
122
    else if (type == Magenta)
×
123
        setupGradient(Qt::white, Qt::magenta);
×
124
    else if (type == Yellow)
×
125
        setupGradient(Qt::white, Qt::yellow);
×
126
    else if (type == Amber)
×
127
        setupGradient(Qt::black, 0xFFFF7E00);
×
128
    else if (type == White)
×
129
        setupGradient(Qt::black, Qt::white);
×
130
    else if (type == UV)
×
131
        setupGradient(Qt::black, 0xFF9400D3);
×
132
    else if (type == Lime)
×
133
        setupGradient(Qt::black, 0xFFADFF2F);
×
134
    else if (type == Indigo)
×
135
        setupGradient(Qt::black, 0xFF4B0082);
×
136
    else if (type == RGB || type == CMY)
×
137
    {
138
        setupColorPicker();
×
139
    }
140
    else if (type == Preset)
×
141
    {
142
        createPresetList(chan);
×
143
        setupPresetPicker();
×
144
    }
145

146
    m_type = type;
×
147
}
×
148

149
int ClickAndGoWidget::getType()
×
150
{
151
    return m_type;
×
152
}
153

154
QString ClickAndGoWidget::clickAndGoTypeToString(ClickAndGoWidget::ClickAndGo type)
×
155
{
156
    switch (type)
×
157
    {
158
        default:
×
159
        case None: return "None"; break;
×
160
        case Red: return "Red"; break;
×
161
        case Green: return "Green"; break;
×
162
        case Blue: return "Blue"; break;
×
163
        case Cyan: return "Cyan"; break;
×
164
        case Magenta: return "Magenta"; break;
×
165
        case Yellow: return "Yellow"; break;
×
166
        case Amber: return "Amber"; break;
×
167
        case White: return "White"; break;
×
168
        case UV: return "UV"; break;
×
169
        case Lime: return "Lime"; break;
×
170
        case Indigo: return "Indigo"; break;
×
171
        case RGB: return "RGB"; break;
×
172
        case CMY: return "CMY"; break;
×
173
        case Preset: return "Preset"; break;
×
174
    }
175
}
176

177
ClickAndGoWidget::ClickAndGo ClickAndGoWidget::stringToClickAndGoType(QString str)
×
178
{
179
    if (str == "Red") return Red;
×
180
    else if (str == "Green") return Green;
×
181
    else if (str == "Blue") return Blue;
×
182
    else if (str == "Cyan") return Cyan;
×
183
    else if (str == "Magenta") return Magenta;
×
184
    else if (str == "Yellow") return Yellow;
×
185
    else if (str == "Amber") return Amber;
×
186
    else if (str == "White") return White;
×
187
    else if (str == "UV") return UV;
×
188
    else if (str == "Lime") return Lime;
×
189
    else if (str == "Indigo") return Indigo;
×
190
    else if (str == "RGB") return RGB;
×
191
    else if (str == "CMY") return CMY;
×
192
    else if (str == "Preset") return Preset;
×
193

194
    return None;
×
195
}
196

197
QColor ClickAndGoWidget::getColorAt(uchar pos)
×
198
{
199
    if (m_linearColor == true)
×
200
    {
201
        QRgb col = m_image.pixel(10 + pos, 10);
×
202
        return QColor(col);
×
203
    }
204
    return QColor(0,0,0);
×
205
}
206

207
QImage ClickAndGoWidget::getImageFromValue(uchar value)
×
208
{
209
    /** If the widget type is a Preset, return directly
210
     *  the pre-loaded resource */
211
    if (m_type == Preset)
×
212
    {
NEW
213
        foreach (PresetResource res, m_resources)
×
214
        {
215
            if (value >= res.m_min && value <= res.m_max)
×
216
                return res.m_thumbnail;
×
217
        }
218
    }
219

220
    QImage img(42, 42, QImage::Format_RGB32);
×
221
    if (m_type == None)
×
222
    {
223
        img.fill(Qt::black);
×
224
    }
225
    else if (m_linearColor == true)
×
226
    {
227
        QRgb col = m_image.pixel(10 + value, 10);
×
228
        img.fill(QColor(col).rgb());
×
229
    }
230

231
    return img;
×
232
}
233

234
void ClickAndGoWidget::createPresetList(const QLCChannel *chan)
×
235
{
236
    int i = 1;
×
237
    if (chan == NULL)
×
238
        return;
×
239

240
    m_title = chan->name();
×
241
    m_resources.clear();
×
242

243
    //qDebug() << Q_FUNC_INFO << "cap #" << chan->capabilities().size();
244

NEW
245
    foreach (QLCCapability* cap, chan->capabilities())
×
246
    {
247
        if (cap->presetType() == QLCCapability::Picture)
×
248
        {
249
            m_resources.append(PresetResource(cap->resource(0).toString(), cap->name(),
×
250
                                              cap->min(), cap->max()));
×
251
        }
252
        else if (cap->presetType() == QLCCapability::SingleColor)
×
253
        {
254
            QColor col1 = cap->resource(0).value<QColor>();
×
255
            m_resources.append(PresetResource(col1, QColor(), cap->name(), cap->min(), cap->max()));
×
256
        }
257
        else if (cap->presetType() == QLCCapability::DoubleColor)
×
258
        {
259
            QColor col1 = cap->resource(0).value<QColor>();
×
260
            QColor col2 = cap->resource(1).value<QColor>();
×
261
            m_resources.append(PresetResource(col1, col2, cap->name(), cap->min(), cap->max()));
×
262
        }
263
        else
264
        {
265
            m_resources.append(PresetResource(i, cap->name(), cap->min(), cap->max()));
×
266
        }
267
        i++;
×
268
    }
269
}
270

271
void ClickAndGoWidget::setupPresetPicker()
×
272
{
273
    if (m_resources.size() == 0)
×
274
        return;
×
275

276
    QScreen *scr = QGuiApplication::screens().first();
×
277
    QRect screen = scr->availableGeometry();
×
278

279
    m_cols = 2;
×
280
    m_rows = qCeil((qreal)m_resources.size() / 2);
×
281
    m_width = m_cellWidth * m_cols;
×
282
    m_height = CELL_H * m_rows + TITLE_H;
×
283

284
    // first check if the menu fits vertically
285
    if (m_height > screen.height())
×
286
    {
287
        m_rows = qFloor((qreal)screen.height() / CELL_H);
×
288
        m_cols = qCeil((qreal)m_resources.size() / m_rows);
×
289
        m_width = m_cellWidth * m_cols;
×
290
        m_height = CELL_H * m_rows + TITLE_H;
×
291
    }
292

293
    // then check if it has to be rescaled horizontally
294
    if (m_width > screen.width())
×
295
    {
296
        m_cellWidth = screen.width() / m_cols;
×
297
        m_width = m_cellWidth * m_cols;
×
298
    }
299

300
    int x = 0;
×
301
    int y = 0;
×
302
    m_image = QImage(m_width, m_height, QImage::Format_RGB32);
×
303
    QPainter painter(&m_image);
×
304
    painter.setRenderHint(QPainter::Antialiasing);
×
305
    QLinearGradient presetGrad(QPointF(0,0), QPointF(0, m_height));
×
306
    presetGrad.setColorAt(0, QApplication::palette().window().color());
×
307
    presetGrad.setColorAt(1, QColor(173, 171, 179));
×
308
    painter.fillRect(0, 0, m_width, m_height, presetGrad);
×
309

310
    // title
311
    painter.setPen(Qt::black);
×
312
    painter.drawText(x + 3, y, m_width - 3, TITLE_H, Qt::AlignVCenter | Qt::TextSingleLine, m_title);
×
313
    y += TITLE_H;
×
314

315
    for (int i = 0; i < m_resources.size(); i++)
×
316
    {
317
        PresetResource res = m_resources.at(i);
×
318
        painter.setPen(Qt::black);
×
319
        painter.drawRect(x, y, m_cellWidth, CELL_H);
×
320
        painter.drawImage(x + 1, y + 4, res.m_thumbnail);
×
321
        painter.drawText(x + 43, y + 4, m_cellWidth - 42, CELL_H - 5, Qt::TextWordWrap|Qt::AlignVCenter, res.m_descr);
×
322
        if (i % m_cols == m_cols - 1)
×
323
        {
324
            y += CELL_H;
×
325
            x = 0;
×
326
        }
327
        else
328
            x += m_cellWidth;
×
329

330
    }
331
}
332

333
QSize ClickAndGoWidget::sizeHint() const
×
334
{
335
    return QSize(m_width, m_height);
×
336
}
337

338
void ClickAndGoWidget::mousePressEvent(QMouseEvent *event)
×
339
{
340
    if (m_linearColor == true)
×
341
    {
342
        if (event->pos().x() <= 10)
×
343
            emit levelChanged(0);
×
344
        else if (event->pos().x() > 10 && event->pos().x() < 256)
×
345
            emit levelChanged((uchar)(event->pos().x() - 10));
×
346
        else
347
            emit levelChanged(255);
×
348
    }
349
    else if (m_type == RGB || m_type == CMY)
×
350
    {
351
        emit colorChanged(m_image.pixel(event->pos().x(), event->pos().y()));
×
352
    }
353
    else if (m_type == Preset)
×
354
    {
355
        if (m_hoverCellIdx >= 0 && m_hoverCellIdx < m_resources.length())
×
356
        {
357
            PresetResource res = m_resources.at(m_hoverCellIdx);
×
358
            qDebug() << "Mouse press. cellW: " << m_cellBarWidth << "min: " << res.m_min << "max:" << res.m_max;
×
359

360
            float f = SCALE(float(m_cellBarWidth),
×
361
                        float(0),
362
                        float(m_cellWidth),
363
                        float(0), float(res.m_max - res.m_min));
364
            emit levelAndPresetChanged((uchar)f + res.m_min, res.m_thumbnail);
×
365
        }
366
    }
367
    QWidget::mousePressEvent(event);
×
368
}
×
369

370
void ClickAndGoWidget::mouseMoveEvent(QMouseEvent *event)
×
371
{
372
    if (m_linearColor == true && event->buttons() == Qt::LeftButton)
×
373
    {
374
        if (event->pos().x() <= 10)
×
375
            emit levelChanged(0);
×
376
        else if (event->pos().x() > 10 && event->pos().x() < 256)
×
377
            emit levelChanged((uchar)(event->pos().x() - 10));
×
378
        else
379
            emit levelChanged(255);
×
380
    }
381
    else if ((m_type == RGB || m_type == CMY) && event->buttons() == Qt::LeftButton)
×
382
    {
383
        emit colorChanged(m_image.pixel(event->pos().x(), event->pos().y()));
×
384
    }
385
    else if (m_type == Preset)
×
386
    {
387
        // calculate the index of the resource where the cursor is
388
        int floorX = qFloor(event->pos().x() / m_cellWidth);
×
389
        int floorY = qFloor((event->pos().y() - TITLE_H) / CELL_H);
×
390
        int tmpCellIDx = (floorY * m_cols) + floorX;
×
391
        if (event->pos().y() < TITLE_H || tmpCellIDx < 0 || tmpCellIDx >= m_resources.length())
×
392
        {
393
            m_hoverCellIdx = -1;
×
394
            update();
×
395
            return;
×
396
        }
397
        m_cellBarXpos = floorX * m_cellWidth;
×
398
        m_cellBarYpos = floorY * CELL_H + TITLE_H;
×
399
        m_cellBarWidth = event->pos().x() - m_cellBarXpos;
×
400
        m_hoverCellIdx = tmpCellIDx;
×
401
        update();
×
402
        qDebug() << "Idx:" << m_hoverCellIdx << "X:" << m_cellBarXpos << "mX:" << event->pos().x();
×
403
    }
404
}
405

406
void ClickAndGoWidget::paintEvent(QPaintEvent *event)
×
407
{
408
    Q_UNUSED(event)
409

410
    QPainter painter(this);
×
411
    painter.drawImage(QPoint(0, 0), m_image);
×
412
    if (m_type == Preset && m_hoverCellIdx >= 0)
×
413
    {
414
        painter.setPen(Qt::NoPen);
×
415
        painter.setBrush(QBrush(QColor(76, 136, 255, 255)));
×
416
        painter.drawRect(m_cellBarXpos, m_cellBarYpos + 1, m_cellBarWidth, 3);
×
417
    }
418
}
×
419

420

421
ClickAndGoWidget::PresetResource::PresetResource(QString path, QString text, uchar min, uchar max)
×
422
{
423
    m_descr = text;
×
424
    m_min = min;
×
425
    m_max = max;
×
426
    QImage px(path);
×
427
    m_thumbnail = QImage(40, 40, QImage::Format_RGB32);
×
428
    m_thumbnail.fill(Qt::white);
×
429
    QPainter painter(&m_thumbnail);
×
430
    painter.setRenderHint(QPainter::SmoothPixmapTransform);
×
431
    painter.drawImage(QRect(0,0,40,40), px);
×
432
    //qDebug() << "PATH: adding " << path << ", descr: " << text;
433
}
×
434

435
ClickAndGoWidget::PresetResource::PresetResource(QColor color1, QColor color2,
×
436
                                                 QString text, uchar min, uchar max)
×
437
{
438
    m_descr = text;
×
439
    m_min = min;
×
440
    m_max = max;
×
441
    m_thumbnail = QImage(40, 40, QImage::Format_RGB32);
×
442
    if (color2.isValid() == false)
×
443
        m_thumbnail.fill(color1.rgb());
×
444
    else
445
    {
446
        QPainter painter(&m_thumbnail);
×
447
        painter.fillRect(0, 0, 20, 40, color1);
×
448
        painter.fillRect(20, 0, 40, 40, color2);
×
449
    }
450
    //qDebug() << "COLOR: adding " << color1.name() << ", descr: " << text;
451
}
×
452

453
ClickAndGoWidget::PresetResource::PresetResource(int index, QString text, uchar min, uchar max)
×
454
{
455
    m_descr = text;
×
456
    m_min = min;
×
457
    m_max = max;
×
458
    m_thumbnail = QImage(40, 40, QImage::Format_RGB32);
×
459
    m_thumbnail.fill(Qt::white);
×
460
    QFont tfont = QApplication::font();
×
461
    tfont.setBold(true);
×
462
    tfont.setPixelSize(20);
×
463
    QPainter painter(&m_thumbnail);
×
464
    painter.setFont(tfont);
×
465
    painter.drawText(0, 0, 40, 40, Qt::AlignHCenter|Qt::AlignVCenter, QString("%1").arg(index));
×
466
    //qDebug() << "GENERIC: adding " << index << ", descr: " << text;
467
}
×
468

469

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