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

mcallegari / qlcplus / 8961243534

05 May 2024 09:23PM UTC coverage: 32.068% (+4.0%) from 28.094%
8961243534

push

github

mcallegari
Merge branch 'master' into qmltoqt6

902 of 2557 new or added lines in 140 files covered. (35.28%)

166 existing lines in 76 files now uncovered.

15395 of 48008 relevant lines covered (32.07%)

22949.67 hits per line

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

0.0
/ui/src/speeddial.cpp
1
/*
2
  Q Light Controller
3
  speeddial.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 <QElapsedTimer>
21
#include <QHBoxLayout>
22
#include <QVBoxLayout>
23
#include <QFocusEvent>
24
#include <QPushButton>
25
#include <QToolButton>
26
#include <QCheckBox>
27
#include <QLabel>
28
#include <QTimer>
29
#include <QDebug>
30
#include <QDial>
31
#include <qmath.h>
32

33
#include "speeddial.h"
34
#include "qlcmacros.h"
35
#include "function.h"
36

37
#define THRESHOLD 10
38
#define HRS_MAX   (596 - 1) // INT_MAX can hold 596h 31m 23s 647ms
39
#define MIN_MAX   59
40
#define SEC_MAX   59
41
#define MS_MAX    999
42

43
#define TIMER_HOLD       250
44
#define TIMER_REPEAT     10
45
#define TAP_STOP_TIMEOUT 30000
46
#define MIN_FLASH_TIME   125
47

48
#define DEFAULT_VISIBILITY_MASK 0x00FF
49

50
const QString tapDefaultSS = "QPushButton { background-color: #DDDDDD; border: 2px solid #6A6A6A; border-radius: 5px; }"
51
                             "QPushButton:pressed { background-color: #AAAAAA; }"
52
                             "QPushButton:disabled { border: 2px solid #BBBBBB; }";
53

54
const QString tapTickSS = "QPushButton { background-color: #DDDDDD; border: 3px solid #2B2595; border-radius: 5px; }"
55
                          "QPushButton:pressed { background-color: #AAAAAA; }"
56
                          "QPushButton:disabled { border: 2px solid #BBBBBB; }";
57

58

59
/****************************************************************************
60
 * FocusSpinBox
61
 ****************************************************************************/
62

63
FocusSpinBox::FocusSpinBox(QWidget* parent)
×
64
    : QSpinBox(parent)
×
65
{
66
}
×
67

68
void FocusSpinBox::focusInEvent(QFocusEvent* event)
×
69
{
70
    if (event->gotFocus() == true)
×
71
        emit focusGained();
×
72
}
×
73

74
/****************************************************************************
75
 * SpeedDial
76
 ****************************************************************************/
77

78
SpeedDial::SpeedDial(QWidget* parent)
×
79
    : QGroupBox(parent)
80
    , m_timer(new QTimer(this))
×
81
    , m_dial(NULL)
82
    , m_hrs(NULL)
83
    , m_min(NULL)
84
    , m_sec(NULL)
85
    , m_ms(NULL)
86
    , m_focus(NULL)
87
    , m_previousDialValue(0)
88
    , m_preventSignals(false)
89
    , m_value(0)
90
    , m_tapTick(false)
91
    , m_tapTime(NULL)
92
    , m_tapTickTimer(NULL)
93
    , m_tapTickElapseTimer(NULL)
94
    , m_visibilityMask(DEFAULT_VISIBILITY_MASK)
×
95
{
96
    new QVBoxLayout(this);
×
97
    layout()->setSpacing(0);
×
98
    layout()->setContentsMargins(2, 2, 2, 2);
×
99

100
    QHBoxLayout* topHBox = new QHBoxLayout();
×
101
    QVBoxLayout* pmVBox1 = new QVBoxLayout();
×
102
    QVBoxLayout* taVBox3 = new QVBoxLayout();
×
103
    layout()->addItem(topHBox);
×
104

105
    m_plus = new QToolButton(this);
×
106
    m_plus->setIconSize(QSize(32, 32));
×
107
    m_plus->setIcon(QIcon(":/edit_add.png"));
×
108
    pmVBox1->addWidget(m_plus, Qt::AlignVCenter | Qt::AlignLeft);
×
109
    connect(m_plus, SIGNAL(pressed()), this, SLOT(slotPlusMinus()));
×
110
    connect(m_plus, SIGNAL(released()), this, SLOT(slotPlusMinus()));
×
111

112
    m_minus = new QToolButton(this);
×
113
    m_minus->setIconSize(QSize(32, 32));
×
114
    m_minus->setIcon(QIcon(":/edit_remove.png"));
×
115
    pmVBox1->addWidget(m_minus, Qt::AlignVCenter | Qt::AlignLeft);
×
116
    connect(m_minus, SIGNAL(pressed()), this, SLOT(slotPlusMinus()));
×
117
    connect(m_minus, SIGNAL(released()), this, SLOT(slotPlusMinus()));
×
118
    topHBox->addItem(pmVBox1);
×
119

120
    m_dial = new QDial(this);
×
121
    m_dial->setWrapping(true);
×
122
    m_dial->setNotchesVisible(true);
×
123
    m_dial->setNotchTarget(15);
×
124
    m_dial->setTracking(true);
×
125
    topHBox->addWidget(m_dial);
×
126
    connect(m_dial, SIGNAL(valueChanged(int)), this, SLOT(slotDialChanged(int)));
×
127

128
    m_tap = new QPushButton(tr("Tap"), this);
×
129
    m_tap->setStyleSheet(tapDefaultSS);
×
130
    m_tap->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
×
131
    taVBox3->addWidget(m_tap);
×
132
    connect(m_tap, SIGNAL(clicked()), this, SLOT(slotTapClicked()));
×
133

134
    topHBox->addItem (taVBox3);
×
135

136
    QHBoxLayout* timeHBox = new QHBoxLayout();
×
137
    layout()->addItem(timeHBox);
×
138

139
    m_hrs = new FocusSpinBox(this);
×
140
    m_hrs->setRange(0, HRS_MAX);
×
141
    m_hrs->setSuffix("h");
×
142
    m_hrs->setButtonSymbols(QSpinBox::NoButtons);
×
143
    m_hrs->setToolTip(tr("Hours"));
×
144
    timeHBox->addWidget(m_hrs);
×
145
    connect(m_hrs, SIGNAL(valueChanged(int)), this, SLOT(slotHoursChanged()));
×
146
    connect(m_hrs, SIGNAL(focusGained()), this, SLOT(slotSpinFocusGained()));
×
147

148
    m_min = new FocusSpinBox(this);
×
149
    m_min->setRange(0, MIN_MAX);
×
150
    m_min->setSuffix("m");
×
151
    m_min->setButtonSymbols(QSpinBox::NoButtons);
×
152
    m_min->setToolTip(tr("Minutes"));
×
153
    timeHBox->addWidget(m_min);
×
154
    connect(m_min, SIGNAL(valueChanged(int)), this, SLOT(slotMinutesChanged()));
×
155
    connect(m_min, SIGNAL(focusGained()), this, SLOT(slotSpinFocusGained()));
×
156

157
    m_sec = new FocusSpinBox(this);
×
158
    m_sec->setRange(0, SEC_MAX);
×
159
    m_sec->setSuffix("s");
×
160
    m_sec->setButtonSymbols(QSpinBox::NoButtons);
×
161
    m_sec->setToolTip(tr("Seconds"));
×
162
    timeHBox->addWidget(m_sec);
×
163
    connect(m_sec, SIGNAL(valueChanged(int)), this, SLOT(slotSecondsChanged()));
×
164
    connect(m_sec, SIGNAL(focusGained()), this, SLOT(slotSpinFocusGained()));
×
165

166
    m_ms = new FocusSpinBox(this);
×
167
    m_ms->setRange(0, MS_MAX);
×
168
    m_ms->setSuffix("ms");
×
169
    m_ms->setButtonSymbols(QSpinBox::NoButtons);
×
170
    m_ms->setToolTip(tr("Milliseconds"));
×
171
    timeHBox->addWidget(m_ms);
×
172
    connect(m_ms, SIGNAL(valueChanged(int)), this, SLOT(slotMSChanged()));
×
173
    connect(m_ms, SIGNAL(focusGained()), this, SLOT(slotSpinFocusGained()));
×
174

175
    m_infiniteCheck = new QCheckBox(this);
×
176
    m_infiniteCheck->setText(tr("Infinite"));
×
177
    layout()->addWidget(m_infiniteCheck);
×
178
    connect(m_infiniteCheck, SIGNAL(toggled(bool)), this, SLOT(slotInfiniteChecked(bool)));
×
179

180
    m_focus = m_ms;
×
181
    m_dial->setRange(m_focus->minimum(), m_focus->maximum());
×
182
    m_dial->setSingleStep(m_focus->singleStep());
×
183

184
    m_timer->setInterval(TIMER_HOLD);
×
185
    connect(m_timer, SIGNAL(timeout()), this, SLOT(slotPlusMinusTimeout()));
×
186

187
    m_tapTickElapseTimer = new QTimer();
×
188
    m_tapTickElapseTimer->setTimerType(Qt::PreciseTimer);
×
189
    m_tapTickElapseTimer->setSingleShot(true);
×
190
    connect(m_tapTickElapseTimer, SIGNAL(timeout()),
×
191
                this, SLOT(slotTapTimeout()));
192

193
    //Hide elements according to current visibility mask
194
    setVisibilityMask(m_visibilityMask);
×
195
}
×
196

197
SpeedDial::~SpeedDial()
×
198
{
199
    if (m_tapTickElapseTimer)
×
200
    {
201
        delete m_tapTickElapseTimer;
×
202
        m_tapTickElapseTimer = NULL;
×
203
    }
204
    stopTimers();
×
205
}
×
206

207
void SpeedDial::setValue(int ms, bool emitValue)
×
208
{
209
    if (emitValue == false)
×
210
        m_preventSignals = true;
×
211

212
    m_value = ms;
×
213
    setSpinValues(ms);
×
214

215
    if (ms == (int) Function::infiniteSpeed())
×
216
        m_infiniteCheck->setChecked(true);
×
217
    else
218
        m_infiniteCheck->setChecked(false);
×
219

220
    // time has changed - update tap button blinking
221
    updateTapTimer();
×
222

223
    m_preventSignals = false;
×
224
}
×
225

226
int SpeedDial::value() const
×
227
{
228
    return m_value;
×
229
}
230

231
void SpeedDial::tap()
×
232
{
233
    m_tap->click();
×
234
}
×
235

236
void SpeedDial::toggleInfinite()
×
237
{
238
    m_infiniteCheck->toggle();
×
239
}
×
240

241
void SpeedDial::stopTimers(bool stopTime, bool stopTapTimer)
×
242
{
243
    if (stopTime && m_tapTime != NULL)
×
244
    {
245
        delete m_tapTime;
×
246
        m_tapTime = NULL;
×
247
    }
248
    if (stopTapTimer && m_tapTickTimer != NULL)
×
249
    {
250
        m_tapTickTimer->stop();
×
251
        delete m_tapTickTimer;
×
252
        m_tapTickTimer = NULL;
×
253
        m_tap->setStyleSheet(tapDefaultSS);
×
254
        m_tapTick = false;
×
255
    }
256
}
×
257

258
bool SpeedDial::isTapTick()
×
259
{
260
    return m_tapTick;
×
261
}
262

263
/*****************************************************************************
264
 * Private
265
 *****************************************************************************/
266

267
void SpeedDial::updateTapTimer()
×
268
{
269
    // Synchronize timer ticks
270
    if (m_tapTickTimer)
×
271
        m_tapTickTimer->stop();
×
272

273
    if (m_value != (int) Function::infiniteSpeed()
×
274
       && m_tapTickTimer == NULL)
×
275
    {
276
        m_tapTickTimer = new QTimer();
×
277
        m_tapTickTimer->setTimerType(Qt::PreciseTimer);
×
278

279
        connect(m_tapTickTimer, SIGNAL(timeout()), this, SLOT(slotTapTimeout()));
×
280
    }
281

282
    if (m_tapTickTimer)
×
283
    {
284
        m_tapTickTimer->setInterval(m_value);
×
285
        // Limit m_tapTickElapseTimer's interval to 20/200ms for nice effect
286
        if (m_value > 1000)
×
287
            m_tapTickElapseTimer->setInterval(200);
×
288
        else
289
            m_tapTickElapseTimer->setInterval(m_value / 3);
×
290
        m_tapTickTimer->start();
×
291
    }
292
}
×
293

294
void SpeedDial::setSpinValues(int ms)
×
295
{
296
    // block signals to prevent each single SpinBox to send
297
    // a valueChanged signal. For example going from 1m0s to 59s
298
    // would send two signals: 0 and then 59000.
299
    // We want to avoid that non-sense 0
300
    // Just send one single signal when everything has changed
301
    m_hrs->blockSignals(true);
×
302
    m_min->blockSignals(true);
×
303
    m_sec->blockSignals(true);
×
304
    m_ms->blockSignals(true);
×
305

306
    if (ms == (int) Function::infiniteSpeed())
×
307
    {
308
        m_hrs->setValue(m_hrs->minimum());
×
309
        m_min->setValue(m_min->minimum());
×
310
        m_sec->setValue(m_sec->minimum());
×
311
        m_ms->setValue(m_ms->minimum());
×
312
    }
313
    else
314
    {
315
        ms = CLAMP(ms, 0, INT_MAX);
×
316

317
        m_hrs->setValue(ms / MS_PER_HOUR);
×
318
        ms -= (m_hrs->value() * MS_PER_HOUR);
×
319

320
        m_min->setValue(ms / MS_PER_MINUTE);
×
321
        ms -= (m_min->value() * MS_PER_MINUTE);
×
322

323
        m_sec->setValue(ms / MS_PER_SECOND);
×
324
        ms -= (m_sec->value() * MS_PER_SECOND);
×
325

326
        m_ms->setValue(ms);
×
327
    }
328
    m_hrs->blockSignals(false);
×
329
    m_min->blockSignals(false);
×
330
    m_sec->blockSignals(false);
×
331
    m_ms->blockSignals(false);
×
332
    if (m_preventSignals == false)
×
333
    {
334
        m_value = spinValues();
×
335
        emit valueChanged(m_value);
×
336
    }
337
}
×
338

339
int SpeedDial::spinValues() const
×
340
{
341
    int value = 0;
×
342

343
    if (m_infiniteCheck->isChecked() == false)
×
344
    {
345
        value += m_hrs->value() * MS_PER_HOUR;
×
346
        value += m_min->value() * MS_PER_MINUTE;
×
347
        value += m_sec->value() * MS_PER_SECOND;
×
348
        value += m_ms->value();
×
349
    }
350
    else
351
    {
352
        value = Function::infiniteSpeed();
×
353
    }
354

355
    return CLAMP(value, 0, INT_MAX);
×
356
}
357

358
int SpeedDial::dialDiff(int value, int previous, int step)
×
359
{
360
    int diff = value - previous;
×
361
    if (diff > THRESHOLD)
×
362
        diff = -step;
×
363
    else if (diff < (-THRESHOLD))
×
364
        diff = step;
×
365
    return diff;
×
366
}
367

368
void SpeedDial::slotPlusMinus()
×
369
{
370
    if (m_minus->isDown() == true || m_plus->isDown() == true)
×
371
    {
372
        slotPlusMinusTimeout();
×
373
        m_timer->start(TIMER_HOLD);
×
374
    }
375
    else
376
    {
377
        m_timer->stop();
×
378
    }
379
}
×
380

381
void SpeedDial::slotPlusMinusTimeout()
×
382
{
383
    if (m_minus->isDown() == true)
×
384
    {
385
        if (m_dial->value() == m_dial->minimum())
×
386
            m_dial->setValue(m_dial->maximum()); // Wrap around
×
387
        else
388
            m_dial->setValue(m_dial->value() - m_dial->singleStep()); // Normal increment
×
389
        m_timer->start(TIMER_REPEAT);
×
390
    }
391
    else if (m_plus->isDown() == true)
×
392
    {
393
        if (m_dial->value() == m_dial->maximum())
×
394
            m_dial->setValue(m_dial->minimum()); // Wrap around
×
395
        else
396
            m_dial->setValue(m_dial->value() + m_dial->singleStep()); // Normal increment
×
397
        m_timer->start(TIMER_REPEAT);
×
398
    }
399
}
×
400

401
void SpeedDial::slotDialChanged(int value)
×
402
{
403
    Q_ASSERT(m_focus != NULL);
×
404

405
    int newValue = dialDiff(value, m_previousDialValue, m_dial->singleStep()) + m_focus->value();
×
406
    if (newValue > m_focus->maximum())
×
407
    {
408
        // Incremented value is above m_focus->maximum(). Spill the overflow to the
409
        // bigger number (unless already incrementing hours).
410
        if (m_focus == m_ms)
×
411
            m_value += m_ms->singleStep();
×
412
        else if (m_focus == m_sec)
×
413
            m_value += MS_PER_SECOND;
×
414
        else if (m_focus == m_min)
×
415
            m_value += MS_PER_MINUTE;
×
416

417
        m_value = CLAMP(m_value, 0, INT_MAX);
×
418
        setSpinValues(m_value);
×
419
    }
420
    else if (newValue < m_focus->minimum())
×
421
    {
422
        newValue = m_value;
×
423
        // Decremented value is below m_focus->minimum(). Spill the underflow to the
424
        // smaller number (unless already decrementing milliseconds).
425
        if (m_focus == m_ms)
×
426
            newValue -= m_ms->singleStep();
×
427
        else if (m_focus == m_sec)
×
428
            newValue -= MS_PER_SECOND;
×
429
        else if (m_focus == m_min)
×
430
            newValue -= MS_PER_MINUTE;
×
431

432
        if (newValue >= 0)
×
433
        {
434
            m_value = newValue;
×
435
            m_value = CLAMP(m_value, 0, INT_MAX);
×
436
            setSpinValues(m_value);
×
437
        }
438
    }
439
    else
440
    {
441
        // Normal value increment/decrement.
442
        m_value = newValue;
×
443
        m_value = CLAMP(m_value, 0, INT_MAX);
×
444
        m_focus->setValue(m_value);
×
445
    }
446

447
    // update tap button blinking
448
    updateTapTimer();
×
449

450
    // Store the current value so it can be compared on the next pass to determine the
451
    // dial's direction of rotation.
452
    m_previousDialValue = value;
×
453
}
×
454

455
void SpeedDial::slotHoursChanged()
×
456
{
457
    if (m_preventSignals == false)
×
458
    {
459
        m_value = spinValues();
×
460
        emit valueChanged(m_value);
×
461
    }
462
    // update tap button blinking
463
    updateTapTimer();
×
464
}
×
465

466
void SpeedDial::slotMinutesChanged()
×
467
{
468
    if (m_preventSignals == false)
×
469
    {
470
        m_value = spinValues();
×
471
        emit valueChanged(m_value);
×
472
    }
473
    // update tap button blinking
474
    updateTapTimer();
×
475
}
×
476

477
void SpeedDial::slotSecondsChanged()
×
478
{
479
    if (m_preventSignals == false)
×
480
    {
481
        m_value = spinValues();
×
482
        emit valueChanged(m_value);
×
483
    }
484
    // update tap button blinking
485
    updateTapTimer();
×
486
}
×
487

488
void SpeedDial::slotMSChanged()
×
489
{
490
    if (m_preventSignals == false)
×
491
    {
492
        m_value = spinValues();
×
493
        emit valueChanged(m_value);
×
494
    }
495
    // update tap button blinking
496
    updateTapTimer();
×
497
}
×
498

499
void SpeedDial::slotInfiniteChecked(bool state)
×
500
{
501
    m_minus->setEnabled(!state);
×
502
    m_dial->setEnabled(!state);
×
503
    m_plus->setEnabled(!state);
×
504
    m_hrs->setEnabled(!state);
×
505
    m_min->setEnabled(!state);
×
506
    m_sec->setEnabled(!state);
×
507
    m_ms->setEnabled(!state);
×
508
    m_tap->setEnabled(!state);
×
509

510
    if (state == true)
×
511
    {
512
        m_value = Function::infiniteSpeed();
×
513
        if (m_preventSignals == false)
×
514
            emit valueChanged(Function::infiniteSpeed());
×
515

516
        // stop tap button blinking if it was
517
        stopTimers();
×
518
    }
519
    else
520
    {
521
        m_value = spinValues();
×
522
        if (m_preventSignals == false)
×
523
            emit valueChanged(m_value);
×
524

525

526
        // update tap button blinking
527
        updateTapTimer();
×
528
    }
529
}
×
530

531
void SpeedDial::slotSpinFocusGained()
×
532
{
533
    m_focus = qobject_cast <FocusSpinBox*> (QObject::sender());
×
534
    Q_ASSERT(m_focus != NULL);
×
535
    m_dial->setRange(m_focus->minimum(), m_focus->maximum());
×
536
    m_dial->setSingleStep(m_focus->singleStep());
×
537
}
×
538

539
void SpeedDial::slotTapClicked()
×
540
{
541
    if (m_tapTime == NULL)
×
542
    {
543
        m_tapTime = new QElapsedTimer();
×
544
        m_tapTime->start();
×
545
        return;
×
546
    }
547
    // Round the elapsed time to the nearest full 10th ms.
548
    m_value = m_tapTime->elapsed();
×
549
    m_tapTime->restart();
×
550

551
    // If it's been a while since the last tap, reset the history and just use the time since the last tap
552
    if (m_value > 1500)
×
553
    {
554
        // TODO: shift the tempo slightly upward or downward and re-phase the tempo
555
        m_tapHistory.clear();
×
556
        // TODO: If m_value is above the widget's maximum, then ignore this tap altogether
557
        setSpinValues(m_value);
×
558
        updateTapTimer();
×
559
        emit tapped();
×
560
        return;
×
561
    }
562

563
    // If multiple taps have been input recently,
564
    // find the tempo that best passes through all of them.
565
    m_tapHistory.append(m_value);
×
566
    // This algorithm stabilizes around a tempo very quickly,
567
    // so keeping more than a few taps in the history merely complicates tempo changes.
NEW
568
    while (m_tapHistory.count() > 16)
×
569
        m_tapHistory.removeFirst();
×
570

571
    // Find the median time between taps, assume that the tempo is +-40% of this
572
    QList<int> tapHistorySorted(m_tapHistory);
×
573
    std::sort(tapHistorySorted.begin(), tapHistorySorted.end());
×
574
    int tapHistoryMedian = tapHistorySorted[tapHistorySorted.length()/2];
×
575

576
    // Tempo detection is not as easy as averaging together the durations,
577
    // which causes all but the first and last taps to cancel each other out.
578
    // Instead, plot each tap as time since first tap over the beat number,
579
    // and the tempo will be the slope of a linear regression through the points.
580
    // Initialize the data with the first tap at (0, 0).
581
    // Use a float, otherwise (n * sum_xy) will overflow very quickly.
582
    float n = 1, x = 0, y = 0, sum_x = 0, sum_y = 0, sum_xx = 0, sum_xy = 0;
×
583
    foreach (int interval_ms, m_tapHistory)
×
584
    {
585
        n += 1;
×
586
        // Divide by tapHistoryMedian to determine if a tap was skipped during input
587
        x += (tapHistoryMedian/2 + interval_ms) / tapHistoryMedian;
×
588
        y += interval_ms;
×
589
        sum_x += x;
×
590
        sum_y += y;
×
591
        sum_xx += x * x;
×
592
        sum_xy += x * y;
×
593
    }
594
    int slope = (n * sum_xy - sum_x * sum_y) / (n * sum_xx - sum_x * sum_x);
×
595
    setSpinValues(slope);
×
596

597
    // time has changed - update tap button blinking
598
    updateTapTimer();
×
599

600
    emit tapped();
×
601
}
602

603
void SpeedDial::slotTapTimeout()
×
604
{
605
    if (m_value <= MIN_FLASH_TIME)
×
606
        return;
×
607

608
    if (m_tapTick == false)
×
609
    {
610
        m_tapTickElapseTimer->start(); // turn off tap light after some time
×
611
        m_tap->setStyleSheet(tapTickSS);
×
612
    }
613
    else
614
    {
615
        m_tap->setStyleSheet(tapDefaultSS);
×
616
    }
617
    m_tapTick = !m_tapTick;
×
618

619
    if (m_tapTime && m_tapTime->elapsed() >= TAP_STOP_TIMEOUT)
×
620
    {
621
        stopTimers(true, false);
×
622
    }
623
    emit tapTimeout();
×
624
}
625

626
quint16 SpeedDial::defaultVisibilityMask()
×
627
{
628
    return DEFAULT_VISIBILITY_MASK;
×
629
}
630

631
quint16 SpeedDial::visibilityMask()
×
632
{
633
    return m_visibilityMask;
×
634
}
635

636
void SpeedDial::setVisibilityMask(quint16 mask)
×
637
{
638
    if (mask & PlusMinus)
×
639
    {
640
        m_plus->show();
×
641
        m_minus->show();
×
642
    }
643
    else
644
    {
645
        m_plus->hide();
×
646
        m_minus->hide();
×
647
    }
648

649
    if (mask & Dial) m_dial->show();
×
650
    else m_dial->hide();
×
651

652
    if (mask & Tap) m_tap->show();
×
653
    else m_tap->hide();
×
654

655
    if (mask & Hours) m_hrs->show();
×
656
    else m_hrs->hide();
×
657

658
    if (mask & Minutes) m_min->show();
×
659
    else m_min->hide();
×
660

661
    if (mask & Seconds) m_sec->show();
×
662
    else m_sec->hide();
×
663

664
    if (mask & Milliseconds) m_ms->show();
×
665
    else m_ms->hide();
×
666

667
    if (mask & Infinite) m_infiniteCheck->show();
×
668
    else m_infiniteCheck->hide();
×
669

670
    m_visibilityMask = mask;
×
UNCOV
671
}
×
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