comparison layer/BoxLayer.cpp @ 1546:ec837d223bd9

Update getPointToDrag to prefer boxes that are containing the mouse position in height as well as width
author Chris Cannam
date Thu, 17 Oct 2019 10:26:21 +0100
parents 4f8c72adbf43
children e6362cf5ff1d
comparison
equal deleted inserted replaced
1545:bdf284b29722 1546:ec837d223bd9
263 return {}; 263 return {};
264 } 264 }
265 265
266 bool 266 bool
267 BoxLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, 267 BoxLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y,
268 Event &point) const 268 Event &point) const
269 { 269 {
270 auto model = ModelById::getAs<BoxModel>(m_model); 270 auto model = ModelById::getAs<BoxModel>(m_model);
271 if (!model) return false; 271 if (!model) return false;
272 272
273 sv_frame_t frame = v->getFrameForX(x); 273 sv_frame_t frame = v->getFrameForX(x);
274 274
275 EventVector onPoints = model->getEventsCovering(frame); 275 EventVector onPoints = model->getEventsCovering(frame);
276 if (onPoints.empty()) return false; 276 if (onPoints.empty()) return false;
277 277
278 int nearestDistance = -1; 278 Event bestContaining;
279 for (const auto &p: onPoints) { 279 for (const auto &p: onPoints) {
280 int distance = getYForValue(v, p.getValue()) - y; 280 auto r = getRange(p);
281 if (distance < 0) distance = -distance; 281 if (y > getYForValue(v, r.first) || y < getYForValue(v, r.second)) {
282 if (nearestDistance == -1 || distance < nearestDistance) { 282 SVCERR << "inPoints: rejecting " << p.toXmlString() << endl;
283 nearestDistance = distance; 283 continue;
284 point = p; 284 }
285 SVCERR << "inPoints: looking at " << p.toXmlString() << endl;
286 if (bestContaining == Event()) {
287 bestContaining = p;
288 continue;
289 }
290 auto br = getRange(bestContaining);
291 if (r.first < br.first && r.second > br.second) {
292 continue;
293 }
294 if (r.first > br.first && r.second < br.second) {
295 bestContaining = p;
296 continue;
297 }
298 if (p.getFrame() > bestContaining.getFrame() &&
299 p.getFrame() + p.getDuration() <
300 bestContaining.getFrame() + bestContaining.getDuration()) {
301 bestContaining = p;
302 continue;
303 }
304 }
305
306 if (bestContaining != Event()) {
307 point = bestContaining;
308 } else {
309 int nearestDistance = -1;
310 for (const auto &p: onPoints) {
311 int distance = std::min
312 (getYForValue(v, p.getValue()) - y,
313 getYForValue(v, p.getValue() + fabsf(p.getLevel())) - y);
314 if (distance < 0) distance = -distance;
315 if (nearestDistance == -1 || distance < nearestDistance) {
316 nearestDistance = distance;
317 point = p;
318 }
285 } 319 }
286 } 320 }
287 321
288 return true; 322 return true;
289 } 323 }
305 return QString(); 339 return QString();
306 } 340 }
307 341
308 QString 342 QString
309 BoxLayer::getFeatureDescription(LayerGeometryProvider *v, 343 BoxLayer::getFeatureDescription(LayerGeometryProvider *v,
310 QPoint &pos) const 344 QPoint &pos) const
311 { 345 {
312 int x = pos.x(); 346 int x = pos.x();
313 347
314 auto model = ModelById::getAs<BoxModel>(m_model); 348 auto model = ModelById::getAs<BoxModel>(m_model);
315 if (!model || !model->getSampleRate()) return ""; 349 if (!model || !model->getSampleRate()) return "";
371 return text; 405 return text;
372 } 406 }
373 407
374 bool 408 bool
375 BoxLayer::snapToFeatureFrame(LayerGeometryProvider *v, 409 BoxLayer::snapToFeatureFrame(LayerGeometryProvider *v,
376 sv_frame_t &frame, 410 sv_frame_t &frame,
377 int &resolution, 411 int &resolution,
378 SnapType snap) const 412 SnapType snap) const
379 { 413 {
380 auto model = ModelById::getAs<BoxModel>(m_model); 414 auto model = ModelById::getAs<BoxModel>(m_model);
381 if (!model) { 415 if (!model) {
382 return Layer::snapToFeatureFrame(v, frame, resolution, snap); 416 return Layer::snapToFeatureFrame(v, frame, resolution, snap);
383 } 417 }