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

paulmthompson / WhiskerToolbox / 18762825348

23 Oct 2025 09:42PM UTC coverage: 72.822% (+0.3%) from 72.522%
18762825348

push

github

paulmthompson
add boolean digital interval logic test

693 of 711 new or added lines in 5 files covered. (97.47%)

718 existing lines in 10 files now uncovered.

54997 of 75522 relevant lines covered (72.82%)

45740.9 hits per line

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

20.39
/src/WhiskerToolbox/DataViewer_Widget/AnalogTimeSeries/AnalogViewer_Widget.cpp
1
#include "AnalogViewer_Widget.hpp"
2
#include "ui_AnalogViewer_Widget.h"
3

4
#include "DataManager/DataManager.hpp"
5
#include "DataViewer/AnalogTimeSeries/AnalogTimeSeriesDisplayOptions.hpp"
6
#include "DataViewer_Widget/OpenGLWidget.hpp"
7

8
#include <QColorDialog>
9
#include <iostream>
10

11
AnalogViewer_Widget::AnalogViewer_Widget(std::shared_ptr<DataManager> data_manager, OpenGLWidget * opengl_widget, QWidget * parent)
20✔
12
    : QWidget(parent),
13
      ui(new Ui::AnalogViewer_Widget),
40✔
14
      _data_manager{std::move(data_manager)},
20✔
15
      _opengl_widget{opengl_widget}
40✔
16
{
17
    ui->setupUi(this);
20✔
18
    
19
    // Set the color display button to be flat and show just the color
20
    ui->color_display_button->setFlat(false);
20✔
21
    ui->color_display_button->setEnabled(false); // Make it non-clickable, just for display
20✔
22
    
23
    connect(ui->color_button, &QPushButton::clicked,
60✔
24
            this, &AnalogViewer_Widget::_openColorDialog);
40✔
25
    connect(ui->scale_spinbox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
60✔
26
            this, &AnalogViewer_Widget::_setAnalogScaleFactor);
40✔
27
    connect(ui->line_thickness_spinbox, QOverload<int>::of(&QSpinBox::valueChanged),
60✔
28
            this, &AnalogViewer_Widget::_setLineThickness);
40✔
29
    
30
    // Connect gap handling controls
31
    connect(ui->gap_mode_combo, QOverload<int>::of(&QComboBox::currentIndexChanged),
60✔
32
            this, &AnalogViewer_Widget::_setGapHandlingMode);
40✔
33
    connect(ui->gap_threshold_spinbox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
60✔
34
            this, &AnalogViewer_Widget::_setGapThreshold);
40✔
35
}
20✔
36

37
AnalogViewer_Widget::~AnalogViewer_Widget() {
40✔
38
    delete ui;
20✔
39
}
40✔
40

41
void AnalogViewer_Widget::setActiveKey(std::string const & key) {
×
42
    _active_key = key;
×
43
    ui->name_label->setText(QString::fromStdString(key));
×
44
    
45
    // Set the color and scale factor to current values from display options if available
46
    if (!key.empty()) {
×
47
        auto config = _opengl_widget->getAnalogConfig(key);
×
48
        if (config.has_value()) {
×
49
            _updateColorDisplay(QString::fromStdString(config.value()->hex_color));
×
50
            
51
            // Set scale factor from the scaling config (not legacy user_scale_factor)
52
            ui->scale_spinbox->setValue(static_cast<double>(config.value()->scaling.user_scale_factor));
×
53
            
54
            // Set line thickness
55
            ui->line_thickness_spinbox->setValue(config.value()->line_thickness);
×
56
            
57
            // Set gap handling controls
58
            ui->gap_mode_combo->setCurrentIndex(static_cast<int>(config.value()->gap_handling));
×
59
            ui->gap_threshold_spinbox->setValue(static_cast<double>(config.value()->gap_threshold));
×
60
        } else {
61
            _updateColorDisplay("#0000FF"); // Default blue
×
62
            ui->scale_spinbox->setValue(1.0); // Default scale
×
63
            ui->line_thickness_spinbox->setValue(1); // Default line thickness
×
64
            ui->gap_mode_combo->setCurrentIndex(0); // Default to AlwaysConnect
×
65
            ui->gap_threshold_spinbox->setValue(5.0); // Default threshold
×
66
        }
67
    }
68
    
69
    std::cout << "AnalogViewer_Widget: Active key set to " << key << std::endl;
×
70
}
×
71

72
void AnalogViewer_Widget::_openColorDialog() {
×
73
    if (_active_key.empty()) {
×
74
        return;
×
75
    }
76
    
77
    // Get current color
78
    QColor currentColor;
×
79
    auto config = _opengl_widget->getAnalogConfig(_active_key);
×
80
    if (config.has_value()) {
×
81
        currentColor = QColor(QString::fromStdString(config.value()->hex_color));
×
82
    } else {
83
        currentColor = QColor("#0000FF");
×
84
    }
85
    
86
    // Open color dialog
87
    QColor color = QColorDialog::getColor(currentColor, this, "Choose Color");
×
88
    
89
    if (color.isValid()) {
×
90
        QString hex_color = color.name();
×
91
        _updateColorDisplay(hex_color);
×
92
        _setAnalogColor(hex_color);
×
93
    }
×
94
}
95

96
void AnalogViewer_Widget::_updateColorDisplay(QString const & hex_color) {
×
97
    // Update the color display button with the new color
98
    ui->color_display_button->setStyleSheet(
×
99
        QString("QPushButton { background-color: %1; border: 1px solid #808080; }").arg(hex_color)
×
100
    );
101
}
×
102

103
void AnalogViewer_Widget::_setAnalogColor(const QString& hex_color) {
×
104
    if (!_active_key.empty()) {
×
105
        auto config = _opengl_widget->getAnalogConfig(_active_key);
×
106
        if (config.has_value()) {
×
107
            config.value()->hex_color = hex_color.toStdString();
×
108
            emit colorChanged(_active_key, hex_color.toStdString());
×
109
            // Trigger immediate repaint
110
            _opengl_widget->update();
×
111
        }
112
    }
UNCOV
113
}
×
114

115
void AnalogViewer_Widget::_setAnalogAlpha(int alpha) {
×
116
    if (!_active_key.empty()) {
×
117
        float const alpha_float = static_cast<float>(alpha) / 100.0f;
×
118
        auto config = _opengl_widget->getAnalogConfig(_active_key);
×
119
        if (config.has_value()) {
×
120
            config.value()->alpha = alpha_float;
×
UNCOV
121
            emit alphaChanged(_active_key, alpha_float);
×
122
            // Trigger immediate repaint
UNCOV
123
            _opengl_widget->update();
×
124
        }
125
    }
126
}
×
127

128
void AnalogViewer_Widget::_setAnalogScaleFactor(double scale_factor) {
×
129
    if (!_active_key.empty()) {
×
UNCOV
130
        auto config = _opengl_widget->getAnalogConfig(_active_key);
×
131
        if (config.has_value()) {
×
132
            // Update the scaling config (the actual one used in rendering)
UNCOV
133
            config.value()->scaling.user_scale_factor = static_cast<float>(scale_factor);
×
134
            // Also update legacy field for compatibility
135
            config.value()->user_scale_factor = static_cast<float>(scale_factor);
×
136
            // Trigger immediate repaint
137
            _opengl_widget->update();
×
138
        }
139
    }
140
}
×
141

142
void AnalogViewer_Widget::_setLineThickness(int thickness) {
×
UNCOV
143
    if (!_active_key.empty()) {
×
UNCOV
144
        auto config = _opengl_widget->getAnalogConfig(_active_key);
×
145
        if (config.has_value()) {
×
UNCOV
146
            config.value()->line_thickness = thickness;
×
147
            // Trigger immediate repaint
148
            _opengl_widget->update();
×
149
        }
150
    }
151
}
×
152

UNCOV
153
void AnalogViewer_Widget::_setGapHandlingMode(int mode_index) {
×
UNCOV
154
    if (!_active_key.empty()) {
×
155
        auto config = _opengl_widget->getAnalogConfig(_active_key);
×
UNCOV
156
        if (config.has_value()) {
×
157
            config.value()->gap_handling = static_cast<AnalogGapHandling>(mode_index);
×
158
            // Trigger immediate repaint
159
            _opengl_widget->update();
×
160
        }
161
    }
162
}
×
163

UNCOV
164
void AnalogViewer_Widget::_setGapThreshold(double threshold) {
×
165
    if (!_active_key.empty()) {
×
UNCOV
166
        auto config = _opengl_widget->getAnalogConfig(_active_key);
×
UNCOV
167
        if (config.has_value()) {
×
UNCOV
168
            config.value()->gap_threshold = static_cast<float>(threshold);
×
169
            // Trigger immediate repaint
UNCOV
170
            _opengl_widget->update();
×
171
        }
172
    }
UNCOV
173
} 
×
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