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

paulmthompson / WhiskerToolbox / 18018707227

25 Sep 2025 07:35PM UTC coverage: 68.577% (-0.3%) from 68.889%
18018707227

push

github

paulmthompson
selection for lines appears to work well

11 of 59 new or added lines in 2 files covered. (18.64%)

797 existing lines in 9 files now uncovered.

42024 of 61280 relevant lines covered (68.58%)

1133.34 hits per line

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

18.56
/src/WhiskerToolbox/Media_Widget/MediaPoint_Widget/MediaPoint_Widget.cpp
1
#include "MediaPoint_Widget.hpp"
2
#include "ui_MediaPoint_Widget.h"
3

4
#include "DataManager/DataManager.hpp"
5
#include "DataManager/Points/Point_Data.hpp"
6
#include "Media_Widget/Media_Window/Media_Window.hpp"
7
#include "Media_Widget/DisplayOptions/DisplayOptions.hpp"
8

9
#include <iostream>
10
#include <cmath>
11
#include <QPointF>
12

13
MediaPoint_Widget::MediaPoint_Widget(std::shared_ptr<DataManager> data_manager, Media_Window * scene, QWidget * parent)
3✔
14
    : QWidget(parent),
15
      ui(new Ui::MediaPoint_Widget),
6✔
16
      _data_manager{std::move(data_manager)},
3✔
17
      _scene{scene}
6✔
18
{
19
    ui->setupUi(this);
3✔
20

21
    connect(ui->color_picker, &ColorPicker_Widget::colorChanged,
9✔
22
            this, &MediaPoint_Widget::_setPointColor);
6✔
23
    connect(ui->color_picker, &ColorPicker_Widget::alphaChanged,
9✔
24
            this, &MediaPoint_Widget::_setPointAlpha);
6✔
25
    
26
    // Connect point size controls
27
    connect(ui->point_size_slider, &QSlider::valueChanged,
9✔
28
            this, &MediaPoint_Widget::_setPointSize);
6✔
29
    connect(ui->point_size_spinbox, QOverload<int>::of(&QSpinBox::valueChanged),
9✔
30
            this, &MediaPoint_Widget::_setPointSize);
6✔
31
    
32
    // Connect marker shape control
33
    connect(ui->marker_shape_combo, QOverload<int>::of(&QComboBox::currentIndexChanged),
9✔
34
            this, &MediaPoint_Widget::_setMarkerShape);
6✔
35
    
36
    // Synchronize slider and spinbox
37
    connect(ui->point_size_slider, &QSlider::valueChanged,
9✔
38
            ui->point_size_spinbox, &QSpinBox::setValue);
6✔
39
    connect(ui->point_size_spinbox, QOverload<int>::of(&QSpinBox::valueChanged),
9✔
40
            ui->point_size_slider, &QSlider::setValue);
6✔
41
}
3✔
42

43
MediaPoint_Widget::~MediaPoint_Widget() {
6✔
44
    delete ui;
3✔
45
}
6✔
46

UNCOV
47
void MediaPoint_Widget::showEvent(QShowEvent * event) {
×
48

49
    static_cast<void>(event);
50

UNCOV
51
    std::cout << "Show Event" << std::endl;
×
52
    // Connect to the new signal that provides modifier information
UNCOV
53
    connect(_scene, &Media_Window::leftClickMediaWithEvent, this, &MediaPoint_Widget::_handlePointClickWithModifiers);
×
54

UNCOV
55
}
×
56

57
void MediaPoint_Widget::hideEvent(QHideEvent * event) {
3✔
58

59
    static_cast<void>(event);
60

61
    std::cout << "Hide Event" << std::endl;
3✔
62
    disconnect(_scene, &Media_Window::leftClickMediaWithEvent, this, &MediaPoint_Widget::_handlePointClickWithModifiers);
3✔
63
    _clearPointSelection(); // Clear selection when widget is hidden
3✔
64
}
3✔
65

UNCOV
66
void MediaPoint_Widget::setActiveKey(std::string const & key) {
×
UNCOV
67
    _active_key = key;
×
68
    ui->name_label->setText(QString::fromStdString(key));
×
69
    _selection_enabled = !key.empty();
×
70

71
    // Set the color picker to the current point color if available
72
    if (!key.empty()) {
×
73
        auto config = _scene->getPointConfig(key);
×
74

UNCOV
75
        if (config) {
×
76
            ui->color_picker->setColor(QString::fromStdString(config.value()->hex_color));
×
77
            ui->color_picker->setAlpha(static_cast<int>(config.value()->alpha * 100));
×
78
            
79
            // Set point size controls
80
            ui->point_size_slider->blockSignals(true);
×
81
            ui->point_size_spinbox->blockSignals(true);
×
UNCOV
82
            ui->point_size_slider->setValue(config.value()->point_size);
×
UNCOV
83
            ui->point_size_spinbox->setValue(config.value()->point_size);
×
84
            ui->point_size_slider->blockSignals(false);
×
85
            ui->point_size_spinbox->blockSignals(false);
×
86
            
87
            // Set marker shape control
UNCOV
88
            ui->marker_shape_combo->blockSignals(true);
×
89
            ui->marker_shape_combo->setCurrentIndex(static_cast<int>(config.value()->marker_shape));
×
UNCOV
90
            ui->marker_shape_combo->blockSignals(false);
×
91
        }
92
    }
93
}
×
94

95

96
void MediaPoint_Widget::_handlePointClickWithModifiers(qreal x_media, qreal y_media, Qt::KeyboardModifiers modifiers) {
×
UNCOV
97
    if (!_selection_enabled || _active_key.empty())
×
98
        return;
×
99

100
    // Check if Ctrl is held for point movement
UNCOV
101
    if (modifiers & Qt::ControlModifier) {
×
102
        // Ctrl+click: move selected point if one is selected
103
        if (_selected_point_id != 0) {
×
UNCOV
104
            _moveSelectedPoint(x_media, y_media);
×
105
        }
106
        return;
×
107
    }
108
    
109
    // Regular click: select nearby point if exists
UNCOV
110
    EntityId nearby_point = _findNearestPoint(x_media, y_media, _selection_threshold);
×
111
    if (nearby_point != 0) {
×
112
        _selectPoint(nearby_point);
×
113
    } else {
114
        _clearPointSelection();
×
115
    }
116
}
117

UNCOV
118
EntityId MediaPoint_Widget::_findNearestPoint(qreal x_media, qreal y_media, float max_distance) {
×
119
    if (_active_key.empty())
×
UNCOV
120
        return 0;
×
121
    
122
    auto point_data = _data_manager->getData<PointData>(_active_key);
×
123
    if (!point_data)
×
124
        return 0;
×
125
    
UNCOV
126
    auto current_time = _data_manager->getCurrentTime();
×
127
    
128
    // Handle timeframe conversion if necessary
129
    auto video_timeframe = _data_manager->getTime(TimeKey("time"));
×
UNCOV
130
    auto point_timeframe_key = _data_manager->getTimeKey(_active_key);
×
131
    
132
    if (!point_timeframe_key.empty()) {
×
UNCOV
133
        auto point_timeframe = _data_manager->getTime(point_timeframe_key);
×
134
        if (video_timeframe.get() != point_timeframe.get()) {
×
135
            current_time = video_timeframe->getTimeAtIndex(TimeFrameIndex(current_time));
×
136
            current_time = point_timeframe->getIndexAtTime(current_time).getValue();
×
137
        }
UNCOV
138
    }
×
139
    
UNCOV
140
    auto points = point_data->getAtTime(TimeFrameIndex(current_time));
×
141
    if (points.empty())
×
UNCOV
142
        return 0;
×
143
    float min_distance = max_distance;
×
144
    int closest_point_index = -1;
×
145
    for (const auto& point : points) {
×
146
        float dx = point.x - static_cast<float>(x_media);
×
147
        float dy = point.y - static_cast<float>(y_media);
×
UNCOV
148
        float distance = std::sqrt(dx * dx + dy * dy);
×
149

UNCOV
150
        if (distance < min_distance) {
×
UNCOV
151
            min_distance = distance;
×
UNCOV
152
            closest_point_index = &point - &points[0]; // Get index of the closest point
×
153
        }
154
        
155
    }
156

157
    if (closest_point_index != -1) {
×
158
        auto entity_ids = point_data->getEntityIdsAtTime(TimeFrameIndex(current_time));
×
159
        if (closest_point_index < static_cast<int>(entity_ids.size())) {
×
160
            return entity_ids[closest_point_index];
×
161
        }
UNCOV
162
    }
×
163
    
UNCOV
164
    return 0;
×
165
}
×
166

167
void MediaPoint_Widget::_selectPoint(EntityId point_id) {
×
168
    _selected_point_id = point_id;
×
169
    
170
    // Use Media_Window's selection system for visual feedback
171
    _scene->selectEntity(point_id, _active_key, "point");
×
UNCOV
172
    std::cout << "Selected point with ID: " << point_id << std::endl;
×
173
}
×
174

175
void MediaPoint_Widget::_clearPointSelection() {
3✔
176
    if (_selected_point_id != 0) {
3✔
UNCOV
177
        _selected_point_id = 0;
×
UNCOV
178
        _scene->clearAllSelections(); // Clear all selections in scene
×
UNCOV
179
        _scene->UpdateCanvas(); // Refresh to remove selection highlight
×
UNCOV
180
        std::cout << "Cleared point selection" << std::endl;
×
181
    }
182
}
3✔
183

UNCOV
184
void MediaPoint_Widget::_moveSelectedPoint(qreal x_media, qreal y_media) {
×
UNCOV
185
    if (_selected_point_id == 0 || _active_key.empty())
×
UNCOV
186
        return;
×
187
    
UNCOV
188
    auto current_time = _data_manager->getCurrentTime();
×
189
    
190
    // Handle timeframe conversion if necessary
UNCOV
191
    auto video_timeframe = _data_manager->getTime(TimeKey("time"));
×
UNCOV
192
    auto point_timeframe_key = _data_manager->getTimeKey(_active_key);
×
193
    
UNCOV
194
    if (!point_timeframe_key.empty()) {
×
UNCOV
195
        auto point_timeframe = _data_manager->getTime(point_timeframe_key);
×
UNCOV
196
        if (video_timeframe.get() != point_timeframe.get()) {
×
UNCOV
197
            current_time = video_timeframe->getTimeAtIndex(TimeFrameIndex(current_time));
×
UNCOV
198
            current_time = point_timeframe->getIndexAtTime(current_time).getValue();
×
199
        }
UNCOV
200
    }
×
201
    
UNCOV
202
    auto point = _data_manager->getData<PointData>(_active_key);
×
UNCOV
203
    if (point) {
×
UNCOV
204
        point->overwritePointAtTime(TimeFrameIndex(current_time), 
×
205
                                    Point2D<float>(static_cast<float>(x_media), static_cast<float>(y_media)));
UNCOV
206
        _scene->UpdateCanvas();
×
UNCOV
207
        std::cout << "Moved point to: (" << x_media << ", " << y_media << ")" << std::endl;
×
208
    }
UNCOV
209
}
×
210

UNCOV
211
void MediaPoint_Widget::_assignPoint(qreal x_media, qreal y_media) {
×
212
    // Legacy method - now just calls the move function for compatibility
UNCOV
213
    _moveSelectedPoint(x_media, y_media);
×
UNCOV
214
}
×
215

UNCOV
216
void MediaPoint_Widget::_setPointColor(const QString& hex_color) {
×
UNCOV
217
    if (!_active_key.empty()) {
×
UNCOV
218
        auto point_opts = _scene->getPointConfig(_active_key);
×
UNCOV
219
        if (point_opts.has_value()) {
×
UNCOV
220
            point_opts.value()->hex_color = hex_color.toStdString();
×
221
        }
UNCOV
222
        _scene->UpdateCanvas();
×
223
    }
UNCOV
224
}
×
225

UNCOV
226
void MediaPoint_Widget::_setPointAlpha(int alpha) {
×
UNCOV
227
    float const alpha_float = static_cast<float>(alpha) / 100;
×
228

UNCOV
229
    if (!_active_key.empty()) {
×
UNCOV
230
        auto point_opts = _scene->getPointConfig(_active_key);
×
UNCOV
231
        if (point_opts.has_value()) {
×
UNCOV
232
            point_opts.value()->alpha = alpha_float;
×
233
        }
UNCOV
234
        _scene->UpdateCanvas();
×
235
    }
UNCOV
236
}
×
237

UNCOV
238
void MediaPoint_Widget::_setPointSize(int size) {
×
UNCOV
239
    if (!_active_key.empty()) {
×
UNCOV
240
        auto point_opts = _scene->getPointConfig(_active_key);
×
UNCOV
241
        if (point_opts.has_value()) {
×
UNCOV
242
            point_opts.value()->point_size = size;
×
243
        }
UNCOV
244
        _scene->UpdateCanvas();
×
245
    }
246
    
247
    // Synchronize slider and spinbox if the signal came from one of them
UNCOV
248
    QObject* sender_obj = sender();
×
UNCOV
249
    if (sender_obj == ui->point_size_slider) {
×
UNCOV
250
        ui->point_size_spinbox->blockSignals(true);
×
UNCOV
251
        ui->point_size_spinbox->setValue(size);
×
UNCOV
252
        ui->point_size_spinbox->blockSignals(false);
×
UNCOV
253
    } else if (sender_obj == ui->point_size_spinbox) {
×
UNCOV
254
        ui->point_size_slider->blockSignals(true);
×
UNCOV
255
        ui->point_size_slider->setValue(size);
×
UNCOV
256
        ui->point_size_slider->blockSignals(false);
×
257
    }
UNCOV
258
}
×
259

UNCOV
260
void MediaPoint_Widget::_setMarkerShape(int shapeIndex) {
×
UNCOV
261
    if (!_active_key.empty() && shapeIndex >= 0) {
×
UNCOV
262
        auto point_opts = _scene->getPointConfig(_active_key);
×
UNCOV
263
        if (point_opts.has_value()) {
×
UNCOV
264
            point_opts.value()->marker_shape = static_cast<PointMarkerShape>(shapeIndex);
×
265
        }
UNCOV
266
        _scene->UpdateCanvas();
×
267
    }
UNCOV
268
}
×
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