Mercurial > hg > svgui
comparison view/View.cpp @ 1353:86429ff00f05
Merge from branch zoom
author | Chris Cannam |
---|---|
date | Wed, 10 Oct 2018 08:44:27 +0100 |
parents | 9fb7133dd818 4949061fcb8c |
children | 40b9a495a0e0 |
comparison
equal
deleted
inserted
replaced
1351:9fb7133dd818 | 1353:86429ff00f05 |
---|---|
52 | 52 |
53 View::View(QWidget *w, bool showProgress) : | 53 View::View(QWidget *w, bool showProgress) : |
54 QFrame(w), | 54 QFrame(w), |
55 m_id(getNextId()), | 55 m_id(getNextId()), |
56 m_centreFrame(0), | 56 m_centreFrame(0), |
57 m_zoomLevel(1024), | 57 m_zoomLevel(ZoomLevel::FramesPerPixel, 1024), |
58 m_followPan(true), | 58 m_followPan(true), |
59 m_followZoom(true), | 59 m_followZoom(true), |
60 m_followPlay(PlaybackScrollPageWithCentre), | 60 m_followPlay(PlaybackScrollPageWithCentre), |
61 m_followPlayIsDetached(false), | 61 m_followPlayIsDetached(false), |
62 m_playPointerFrame(0), | 62 m_playPointerFrame(0), |
63 m_showProgress(showProgress), | 63 m_showProgress(showProgress), |
64 m_cache(0), | 64 m_cache(0), |
65 m_buffer(0), | 65 m_buffer(0), |
66 m_cacheCentreFrame(0), | 66 m_cacheCentreFrame(0), |
67 m_cacheZoomLevel(1024), | 67 m_cacheZoomLevel(ZoomLevel::FramesPerPixel, 1024), |
68 m_selectionCached(false), | 68 m_selectionCached(false), |
69 m_deleting(false), | 69 m_deleting(false), |
70 m_haveSelectedLayer(false), | 70 m_haveSelectedLayer(false), |
71 m_manager(0), | 71 m_manager(0), |
72 m_propertyContainer(new ViewPropertyContainer(this)) | 72 m_propertyContainer(new ViewPropertyContainer(this)) |
317 } | 317 } |
318 | 318 |
319 void | 319 void |
320 View::setStartFrame(sv_frame_t f) | 320 View::setStartFrame(sv_frame_t f) |
321 { | 321 { |
322 setCentreFrame(f + m_zoomLevel * (width() / 2)); | 322 setCentreFrame(f + sv_frame_t(round |
323 (m_zoomLevel.pixelsToFrames(width() / 2)))); | |
323 } | 324 } |
324 | 325 |
325 bool | 326 bool |
326 View::setCentreFrame(sv_frame_t f, bool e) | 327 View::setCentreFrame(sv_frame_t f, bool e) |
327 { | 328 { |
328 bool changeVisible = false; | 329 bool changeVisible = false; |
329 | 330 |
331 #ifdef DEBUG_VIEW | |
332 SVCERR << "View::setCentreFrame: from " << m_centreFrame | |
333 << " to " << f << endl; | |
334 #endif | |
335 | |
330 if (m_centreFrame != f) { | 336 if (m_centreFrame != f) { |
331 | 337 |
332 int formerPixel = int(m_centreFrame / m_zoomLevel); | 338 sv_frame_t formerCentre = m_centreFrame; |
333 | |
334 m_centreFrame = f; | 339 m_centreFrame = f; |
335 | |
336 int newPixel = int(m_centreFrame / m_zoomLevel); | |
337 | 340 |
338 if (newPixel != formerPixel) { | 341 if (m_zoomLevel.zone == ZoomLevel::PixelsPerFrame) { |
339 | 342 |
340 #ifdef DEBUG_VIEW_WIDGET_PAINT | 343 #ifdef DEBUG_VIEW_WIDGET_PAINT |
341 cout << "View(" << this << ")::setCentreFrame: newPixel " << newPixel << ", formerPixel " << formerPixel << endl; | 344 SVCERR << "View(" << this << ")::setCentreFrame: in PixelsPerFrame zone, so change must be visible" << endl; |
342 #endif | 345 #endif |
343 update(); | 346 update(); |
344 | |
345 changeVisible = true; | 347 changeVisible = true; |
348 | |
349 } else { | |
350 | |
351 int formerPixel = int(formerCentre / m_zoomLevel.level); | |
352 int newPixel = int(m_centreFrame / m_zoomLevel.level); | |
353 | |
354 if (newPixel != formerPixel) { | |
355 | |
356 #ifdef DEBUG_VIEW_WIDGET_PAINT | |
357 SVCERR << "View(" << this << ")::setCentreFrame: newPixel " << newPixel << ", formerPixel " << formerPixel << endl; | |
358 #endif | |
359 // ensure the centre frame is a multiple of the zoom level | |
360 m_centreFrame = sv_frame_t(newPixel) * m_zoomLevel.level; | |
361 | |
362 update(); | |
363 changeVisible = true; | |
364 } | |
346 } | 365 } |
347 | 366 |
348 if (e) { | 367 if (e) { |
349 sv_frame_t rf = alignToReference(f); | 368 sv_frame_t rf = alignToReference(f); |
350 #ifdef DEBUG_VIEW | 369 #ifdef DEBUG_VIEW |
360 } | 379 } |
361 | 380 |
362 int | 381 int |
363 View::getXForFrame(sv_frame_t frame) const | 382 View::getXForFrame(sv_frame_t frame) const |
364 { | 383 { |
365 return int((frame - getStartFrame()) / m_zoomLevel); | 384 // In FramesPerPixel mode, the pixel should be the one "covering" |
385 // the given frame, i.e. to the "left" of it - not necessarily the | |
386 // nearest boundary. | |
387 | |
388 sv_frame_t level = m_zoomLevel.level; | |
389 sv_frame_t fdiff = frame - getCentreFrame(); | |
390 int diff, result; | |
391 | |
392 if (m_zoomLevel.zone == ZoomLevel::FramesPerPixel) { | |
393 diff = int(fdiff / level); | |
394 if ((fdiff < 0) && ((fdiff % level) != 0)) { | |
395 --diff; // round to the left | |
396 } | |
397 } else { | |
398 diff = int(fdiff * level); | |
399 } | |
400 | |
401 result = int(diff + (width()/2)); | |
402 return result; | |
366 } | 403 } |
367 | 404 |
368 sv_frame_t | 405 sv_frame_t |
369 View::getFrameForX(int x) const | 406 View::getFrameForX(int x) const |
370 { | 407 { |
371 sv_frame_t z = m_zoomLevel; // nb not just int, or multiplication may overflow | 408 // Note, this must always return a value that is on a zoom-level |
372 sv_frame_t frame = m_centreFrame - (width()/2) * z; | 409 // boundary - regardless of whether the nominal centre frame is on |
373 | 410 // such a boundary or not. |
374 frame = (frame / z) * z; // this is start frame | 411 |
375 frame = frame + x * z; | 412 // In PixelsPerFrame mode, the frame should be the one immediately |
376 | 413 // left of the given pixel, not necessarily the nearest. |
377 #ifdef DEBUG_VIEW_WIDGET_PAINT | 414 |
378 cerr << "View::getFrameForX(" << x << "): z = " << z << ", m_centreFrame = " << m_centreFrame << ", width() = " << width() << ", frame = " << frame << endl; | 415 int diff = x - (width()/2); |
379 #endif | 416 sv_frame_t level = m_zoomLevel.level; |
380 | 417 sv_frame_t fdiff, result; |
381 return frame; | 418 |
419 if (m_zoomLevel.zone == ZoomLevel::FramesPerPixel) { | |
420 fdiff = diff * level; | |
421 result = ((fdiff + m_centreFrame) / level) * level; | |
422 } else { | |
423 fdiff = diff / level; | |
424 if ((diff < 0) && ((diff % level) != 0)) { | |
425 --fdiff; // round to the left | |
426 } | |
427 result = fdiff + m_centreFrame; | |
428 } | |
429 | |
430 #ifdef DEBUG_VIEW | |
431 if (x == 0) { | |
432 SVCERR << "getFrameForX(" << x << "): diff = " << diff << ", fdiff = " | |
433 << fdiff << ", m_centreFrame = " << m_centreFrame | |
434 << ", level = " << m_zoomLevel.level | |
435 << ", diff % level = " << (diff % m_zoomLevel.level) | |
436 << ", nominal " << fdiff + m_centreFrame | |
437 << ", will return " << result | |
438 << endl; | |
439 } | |
440 #endif | |
441 | |
442 return result; | |
382 } | 443 } |
383 | 444 |
384 double | 445 double |
385 View::getYForFrequency(double frequency, | 446 View::getYForFrequency(double frequency, |
386 double minf, | 447 double minf, |
445 if (minf == maxf) return 0; | 506 if (minf == maxf) return 0; |
446 return minf + ((h - y) * (maxf - minf)) / h; | 507 return minf + ((h - y) * (maxf - minf)) / h; |
447 } | 508 } |
448 } | 509 } |
449 | 510 |
450 int | 511 ZoomLevel |
451 View::getZoomLevel() const | 512 View::getZoomLevel() const |
452 { | 513 { |
453 #ifdef DEBUG_VIEW_WIDGET_PAINT | 514 #ifdef DEBUG_VIEW_WIDGET_PAINT |
454 // cout << "zoom level: " << m_zoomLevel << endl; | 515 // cout << "zoom level: " << m_zoomLevel << endl; |
455 #endif | 516 #endif |
474 return 1; | 535 return 1; |
475 #endif | 536 #endif |
476 } | 537 } |
477 | 538 |
478 void | 539 void |
479 View::setZoomLevel(int z) | 540 View::setZoomLevel(ZoomLevel z) |
480 { | 541 { |
481 int dpratio = effectiveDevicePixelRatio(); | 542 //!!! int dpratio = effectiveDevicePixelRatio(); |
482 if (z < dpratio) return; | 543 // if (z < dpratio) return; |
483 if (z < 1) z = 1; | 544 // if (z < 1) z = 1; |
484 if (m_zoomLevel != int(z)) { | 545 if (m_zoomLevel == z) { |
485 m_zoomLevel = z; | 546 return; |
486 emit zoomLevelChanged(z, m_followZoom); | 547 } |
487 update(); | 548 m_zoomLevel = z; |
488 } | 549 emit zoomLevelChanged(z, m_followZoom); |
550 update(); | |
489 } | 551 } |
490 | 552 |
491 bool | 553 bool |
492 View::hasLightBackground() const | 554 View::hasLightBackground() const |
493 { | 555 { |
723 { | 785 { |
724 if (m_manager) { | 786 if (m_manager) { |
725 m_manager->disconnect(this, SLOT(globalCentreFrameChanged(sv_frame_t))); | 787 m_manager->disconnect(this, SLOT(globalCentreFrameChanged(sv_frame_t))); |
726 m_manager->disconnect(this, SLOT(viewCentreFrameChanged(View *, sv_frame_t))); | 788 m_manager->disconnect(this, SLOT(viewCentreFrameChanged(View *, sv_frame_t))); |
727 m_manager->disconnect(this, SLOT(viewManagerPlaybackFrameChanged(sv_frame_t))); | 789 m_manager->disconnect(this, SLOT(viewManagerPlaybackFrameChanged(sv_frame_t))); |
728 m_manager->disconnect(this, SLOT(viewZoomLevelChanged(View *, int, bool))); | 790 m_manager->disconnect(this, SLOT(viewZoomLevelChanged(View *, ZoomLevel, bool))); |
729 m_manager->disconnect(this, SLOT(toolModeChanged())); | 791 m_manager->disconnect(this, SLOT(toolModeChanged())); |
730 m_manager->disconnect(this, SLOT(selectionChanged())); | 792 m_manager->disconnect(this, SLOT(selectionChanged())); |
731 m_manager->disconnect(this, SLOT(overlayModeChanged())); | 793 m_manager->disconnect(this, SLOT(overlayModeChanged())); |
732 m_manager->disconnect(this, SLOT(zoomWheelsEnabledChanged())); | 794 m_manager->disconnect(this, SLOT(zoomWheelsEnabledChanged())); |
733 disconnect(m_manager, SLOT(viewCentreFrameChanged(sv_frame_t, bool, PlaybackFollowMode))); | 795 disconnect(m_manager, SLOT(viewCentreFrameChanged(sv_frame_t, bool, PlaybackFollowMode))); |
734 disconnect(m_manager, SLOT(zoomLevelChanged(int, bool))); | 796 disconnect(m_manager, SLOT(zoomLevelChanged(ZoomLevel, bool))); |
735 } | 797 } |
736 | 798 |
737 m_manager = manager; | 799 m_manager = manager; |
738 | 800 |
739 connect(m_manager, SIGNAL(globalCentreFrameChanged(sv_frame_t)), | 801 connect(m_manager, SIGNAL(globalCentreFrameChanged(sv_frame_t)), |
741 connect(m_manager, SIGNAL(viewCentreFrameChanged(View *, sv_frame_t)), | 803 connect(m_manager, SIGNAL(viewCentreFrameChanged(View *, sv_frame_t)), |
742 this, SLOT(viewCentreFrameChanged(View *, sv_frame_t))); | 804 this, SLOT(viewCentreFrameChanged(View *, sv_frame_t))); |
743 connect(m_manager, SIGNAL(playbackFrameChanged(sv_frame_t)), | 805 connect(m_manager, SIGNAL(playbackFrameChanged(sv_frame_t)), |
744 this, SLOT(viewManagerPlaybackFrameChanged(sv_frame_t))); | 806 this, SLOT(viewManagerPlaybackFrameChanged(sv_frame_t))); |
745 | 807 |
746 connect(m_manager, SIGNAL(viewZoomLevelChanged(View *, int, bool)), | 808 connect(m_manager, SIGNAL(viewZoomLevelChanged(View *, ZoomLevel, bool)), |
747 this, SLOT(viewZoomLevelChanged(View *, int, bool))); | 809 this, SLOT(viewZoomLevelChanged(View *, ZoomLevel, bool))); |
748 | 810 |
749 connect(m_manager, SIGNAL(toolModeChanged()), | 811 connect(m_manager, SIGNAL(toolModeChanged()), |
750 this, SLOT(toolModeChanged())); | 812 this, SLOT(toolModeChanged())); |
751 connect(m_manager, SIGNAL(selectionChanged()), | 813 connect(m_manager, SIGNAL(selectionChanged()), |
752 this, SLOT(selectionChanged())); | 814 this, SLOT(selectionChanged())); |
762 connect(this, SIGNAL(centreFrameChanged(sv_frame_t, bool, | 824 connect(this, SIGNAL(centreFrameChanged(sv_frame_t, bool, |
763 PlaybackFollowMode)), | 825 PlaybackFollowMode)), |
764 m_manager, SLOT(viewCentreFrameChanged(sv_frame_t, bool, | 826 m_manager, SLOT(viewCentreFrameChanged(sv_frame_t, bool, |
765 PlaybackFollowMode))); | 827 PlaybackFollowMode))); |
766 | 828 |
767 connect(this, SIGNAL(zoomLevelChanged(int, bool)), | 829 connect(this, SIGNAL(zoomLevelChanged(ZoomLevel, bool)), |
768 m_manager, SLOT(viewZoomLevelChanged(int, bool))); | 830 m_manager, SLOT(viewZoomLevelChanged(ZoomLevel, bool))); |
769 | 831 |
770 switch (m_followPlay) { | 832 switch (m_followPlay) { |
771 | 833 |
772 case PlaybackScrollPage: | 834 case PlaybackScrollPage: |
773 case PlaybackScrollPageWithCentre: | 835 case PlaybackScrollPageWithCentre: |
1125 break; | 1187 break; |
1126 } | 1188 } |
1127 } | 1189 } |
1128 | 1190 |
1129 void | 1191 void |
1130 View::viewZoomLevelChanged(View *p, int z, bool locked) | 1192 View::viewZoomLevelChanged(View *p, ZoomLevel z, bool locked) |
1131 { | 1193 { |
1132 #ifdef DEBUG_VIEW_WIDGET_PAINT | 1194 #ifdef DEBUG_VIEW_WIDGET_PAINT |
1133 cerr << "View[" << this << "]: viewZoomLevelChanged(" << p << ", " << z << ", " << locked << ")" << endl; | 1195 cerr << "View[" << this << "]: viewZoomLevelChanged(" << p << ", " << z << ", " << locked << ")" << endl; |
1134 #endif | 1196 #endif |
1135 if (m_followZoom && p != this && locked) { | 1197 if (m_followZoom && p != this && locked) { |
1398 } | 1460 } |
1399 | 1461 |
1400 return nonScrollables; | 1462 return nonScrollables; |
1401 } | 1463 } |
1402 | 1464 |
1403 int | 1465 ZoomLevel |
1404 View::getZoomConstraintBlockSize(int blockSize, | 1466 View::getZoomConstraintLevel(ZoomLevel zoomLevel, |
1405 ZoomConstraint::RoundingDirection dir) | 1467 ZoomConstraint::RoundingDirection dir) |
1406 const | 1468 const |
1407 { | 1469 { |
1408 int candidate = blockSize; | 1470 using namespace std::rel_ops; |
1471 | |
1472 ZoomLevel candidate = zoomLevel; | |
1409 bool haveCandidate = false; | 1473 bool haveCandidate = false; |
1410 | 1474 |
1411 PowerOfSqrtTwoZoomConstraint defaultZoomConstraint; | 1475 PowerOfSqrtTwoZoomConstraint defaultZoomConstraint; |
1412 | 1476 |
1413 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) { | 1477 for (auto i = m_layerStack.begin(); i != m_layerStack.end(); ++i) { |
1414 | 1478 |
1415 const ZoomConstraint *zoomConstraint = (*i)->getZoomConstraint(); | 1479 const ZoomConstraint *zoomConstraint = (*i)->getZoomConstraint(); |
1416 if (!zoomConstraint) zoomConstraint = &defaultZoomConstraint; | 1480 if (!zoomConstraint) zoomConstraint = &defaultZoomConstraint; |
1417 | 1481 |
1418 int thisBlockSize = | 1482 ZoomLevel thisLevel = |
1419 zoomConstraint->getNearestBlockSize(blockSize, dir); | 1483 zoomConstraint->getNearestZoomLevel(zoomLevel, dir); |
1420 | 1484 |
1421 // Go for the block size that's furthest from the one | 1485 // Go for the block size that's furthest from the one |
1422 // passed in. Most of the time, that's what we want. | 1486 // passed in. Most of the time, that's what we want. |
1423 if (!haveCandidate || | 1487 if (!haveCandidate || |
1424 (thisBlockSize > blockSize && thisBlockSize > candidate) || | 1488 (thisLevel > zoomLevel && thisLevel > candidate) || |
1425 (thisBlockSize < blockSize && thisBlockSize < candidate)) { | 1489 (thisLevel < zoomLevel && thisLevel < candidate)) { |
1426 candidate = thisBlockSize; | 1490 candidate = thisLevel; |
1427 haveCandidate = true; | 1491 haveCandidate = true; |
1428 } | 1492 } |
1429 } | 1493 } |
1430 | 1494 |
1431 return candidate; | 1495 return candidate; |
1452 } | 1516 } |
1453 | 1517 |
1454 void | 1518 void |
1455 View::zoom(bool in) | 1519 View::zoom(bool in) |
1456 { | 1520 { |
1457 int newZoomLevel = m_zoomLevel; | 1521 ZoomLevel newZoomLevel = m_zoomLevel; |
1458 | 1522 |
1459 if (in) { | 1523 if (in) { |
1460 newZoomLevel = getZoomConstraintBlockSize(newZoomLevel - 1, | 1524 newZoomLevel = getZoomConstraintLevel(m_zoomLevel.decremented(), |
1461 ZoomConstraint::RoundDown); | 1525 ZoomConstraint::RoundDown); |
1462 } else { | 1526 } else { |
1463 newZoomLevel = getZoomConstraintBlockSize(newZoomLevel + 1, | 1527 newZoomLevel = getZoomConstraintLevel(m_zoomLevel.incremented(), |
1464 ZoomConstraint::RoundUp); | 1528 ZoomConstraint::RoundUp); |
1465 } | 1529 } |
1466 | 1530 |
1531 using namespace std::rel_ops; | |
1532 | |
1467 if (newZoomLevel != m_zoomLevel) { | 1533 if (newZoomLevel != m_zoomLevel) { |
1468 setZoomLevel(newZoomLevel); | 1534 setZoomLevel(newZoomLevel); |
1469 } | 1535 } |
1470 } | 1536 } |
1471 | 1537 |
1763 #ifdef DEBUG_VIEW_WIDGET_PAINT | 1829 #ifdef DEBUG_VIEW_WIDGET_PAINT |
1764 cerr << "View(" << this << "): cache " << m_cache << ", cache zoom " | 1830 cerr << "View(" << this << "): cache " << m_cache << ", cache zoom " |
1765 << m_cacheZoomLevel << ", zoom " << m_zoomLevel << endl; | 1831 << m_cacheZoomLevel << ", zoom " << m_zoomLevel << endl; |
1766 #endif | 1832 #endif |
1767 | 1833 |
1834 using namespace std::rel_ops; | |
1835 | |
1768 if (!m_cache || | 1836 if (!m_cache || |
1769 m_cacheZoomLevel != m_zoomLevel || | 1837 m_cacheZoomLevel != m_zoomLevel || |
1770 scaledCacheSize != m_cache->size()) { | 1838 scaledCacheSize != m_cache->size()) { |
1771 | 1839 |
1772 // cache is not valid | 1840 // cache is not valid |
2368 } | 2436 } |
2369 | 2437 |
2370 bool | 2438 bool |
2371 View::render(QPainter &paint, int xorigin, sv_frame_t f0, sv_frame_t f1) | 2439 View::render(QPainter &paint, int xorigin, sv_frame_t f0, sv_frame_t f1) |
2372 { | 2440 { |
2373 int x0 = int(f0 / m_zoomLevel); | 2441 int x0 = int(round(m_zoomLevel.framesToPixels(double(f0)))); |
2374 int x1 = int(f1 / m_zoomLevel); | 2442 int x1 = int(round(m_zoomLevel.framesToPixels(double(f1)))); |
2375 | 2443 |
2376 int w = x1 - x0; | 2444 int w = x1 - x0; |
2377 | 2445 |
2378 sv_frame_t origCentreFrame = m_centreFrame; | 2446 sv_frame_t origCentreFrame = m_centreFrame; |
2379 | 2447 |
2431 m_centreFrame = origCentreFrame; | 2499 m_centreFrame = origCentreFrame; |
2432 update(); | 2500 update(); |
2433 return false; | 2501 return false; |
2434 } | 2502 } |
2435 | 2503 |
2436 m_centreFrame = f0 + (x + width()/2) * m_zoomLevel; | 2504 m_centreFrame = f0 + sv_frame_t(round(m_zoomLevel.pixelsToFrames |
2505 (x + width()/2))); | |
2437 | 2506 |
2438 QRect chunk(0, 0, width(), height()); | 2507 QRect chunk(0, 0, width(), height()); |
2439 | 2508 |
2440 paint.setPen(getBackground()); | 2509 paint.setPen(getBackground()); |
2441 paint.setBrush(getBackground()); | 2510 paint.setBrush(getBackground()); |
2482 } | 2551 } |
2483 | 2552 |
2484 QImage * | 2553 QImage * |
2485 View::renderPartToNewImage(sv_frame_t f0, sv_frame_t f1) | 2554 View::renderPartToNewImage(sv_frame_t f0, sv_frame_t f1) |
2486 { | 2555 { |
2487 int x0 = int(f0 / getZoomLevel()); | 2556 int x0 = int(round(getZoomLevel().framesToPixels(double(f0)))); |
2488 int x1 = int(f1 / getZoomLevel()); | 2557 int x1 = int(round(getZoomLevel().framesToPixels(double(f1)))); |
2489 | 2558 |
2490 QImage *image = new QImage(x1 - x0, height(), QImage::Format_RGB32); | 2559 QImage *image = new QImage(x1 - x0, height(), QImage::Format_RGB32); |
2491 | 2560 |
2492 QPainter *paint = new QPainter(image); | 2561 QPainter *paint = new QPainter(image); |
2493 if (!render(*paint, 0, f0, f1)) { | 2562 if (!render(*paint, 0, f0, f1)) { |
2510 } | 2579 } |
2511 | 2580 |
2512 QSize | 2581 QSize |
2513 View::getRenderedPartImageSize(sv_frame_t f0, sv_frame_t f1) | 2582 View::getRenderedPartImageSize(sv_frame_t f0, sv_frame_t f1) |
2514 { | 2583 { |
2515 int x0 = int(f0 / getZoomLevel()); | 2584 int x0 = int(round(getZoomLevel().framesToPixels(double(f0)))); |
2516 int x1 = int(f1 / getZoomLevel()); | 2585 int x1 = int(round(getZoomLevel().framesToPixels(double(f1)))); |
2517 | 2586 |
2518 return QSize(x1 - x0, height()); | 2587 return QSize(x1 - x0, height()); |
2519 } | 2588 } |
2520 | 2589 |
2521 bool | 2590 bool |
2528 } | 2597 } |
2529 | 2598 |
2530 bool | 2599 bool |
2531 View::renderPartToSvgFile(QString filename, sv_frame_t f0, sv_frame_t f1) | 2600 View::renderPartToSvgFile(QString filename, sv_frame_t f0, sv_frame_t f1) |
2532 { | 2601 { |
2533 int x0 = int(f0 / getZoomLevel()); | 2602 int x0 = int(round(getZoomLevel().framesToPixels(double(f0)))); |
2534 int x1 = int(f1 / getZoomLevel()); | 2603 int x1 = int(round(getZoomLevel().framesToPixels(double(f1)))); |
2535 | 2604 |
2536 QSvgGenerator generator; | 2605 QSvgGenerator generator; |
2537 generator.setFileName(filename); | 2606 generator.setFileName(filename); |
2538 generator.setSize(QSize(x1 - x0, height())); | 2607 generator.setSize(QSize(x1 - x0, height())); |
2539 generator.setViewBox(QRect(0, 0, x1 - x0, height())); | 2608 generator.setViewBox(QRect(0, 0, x1 - x0, height())); |
2551 View::toXml(QTextStream &stream, | 2620 View::toXml(QTextStream &stream, |
2552 QString indent, QString extraAttributes) const | 2621 QString indent, QString extraAttributes) const |
2553 { | 2622 { |
2554 stream << indent; | 2623 stream << indent; |
2555 | 2624 |
2625 int classicZoomValue, deepZoomValue; | |
2626 | |
2627 if (m_zoomLevel.zone == ZoomLevel::FramesPerPixel) { | |
2628 classicZoomValue = m_zoomLevel.level; | |
2629 deepZoomValue = 1; | |
2630 } else { | |
2631 classicZoomValue = 1; | |
2632 deepZoomValue = m_zoomLevel.level; | |
2633 } | |
2634 | |
2556 stream << QString("<view " | 2635 stream << QString("<view " |
2557 "centre=\"%1\" " | 2636 "centre=\"%1\" " |
2558 "zoom=\"%2\" " | 2637 "zoom=\"%2\" " |
2559 "followPan=\"%3\" " | 2638 "deepZoom=\"%3\" " |
2560 "followZoom=\"%4\" " | 2639 "followPan=\"%4\" " |
2561 "tracking=\"%5\" " | 2640 "followZoom=\"%5\" " |
2562 " %6>\n") | 2641 "tracking=\"%6\" " |
2642 " %7>\n") | |
2563 .arg(m_centreFrame) | 2643 .arg(m_centreFrame) |
2564 .arg(m_zoomLevel) | 2644 .arg(classicZoomValue) |
2645 .arg(deepZoomValue) | |
2565 .arg(m_followPan) | 2646 .arg(m_followPan) |
2566 .arg(m_followZoom) | 2647 .arg(m_followZoom) |
2567 .arg(m_followPlay == PlaybackScrollContinuous ? "scroll" : | 2648 .arg(m_followPlay == PlaybackScrollContinuous ? "scroll" : |
2568 m_followPlay == PlaybackScrollPageWithCentre ? "page" : | 2649 m_followPlay == PlaybackScrollPageWithCentre ? "page" : |
2569 m_followPlay == PlaybackScrollPage ? "daw" : | 2650 m_followPlay == PlaybackScrollPage ? "daw" : |