comparison view/Pane.cpp @ 373:0895517bb2d1 1.2-stable

* merge from trunk (1.2 ended up being tracked from trunk, but we may want this branch for fixes later)
author Chris Cannam
date Wed, 27 Feb 2008 10:32:45 +0000
parents 2f83b6e3b8ca
children
comparison
equal deleted inserted replaced
337:813170c57b13 373:0895517bb2d1
20 #include "base/RealTime.h" 20 #include "base/RealTime.h"
21 #include "base/Profiler.h" 21 #include "base/Profiler.h"
22 #include "ViewManager.h" 22 #include "ViewManager.h"
23 #include "base/CommandHistory.h" 23 #include "base/CommandHistory.h"
24 #include "base/TextAbbrev.h" 24 #include "base/TextAbbrev.h"
25 #include "base/Preferences.h"
25 #include "layer/WaveformLayer.h" 26 #include "layer/WaveformLayer.h"
26 27
27 //!!! ugh 28 //!!! ugh
28 #include "data/model/WaveFileModel.h" 29 #include "data/model/WaveFileModel.h"
29 30
47 #include "widgets/RangeInputDialog.h" 48 #include "widgets/RangeInputDialog.h"
48 #include "widgets/NotifyingPushButton.h" 49 #include "widgets/NotifyingPushButton.h"
49 50
50 #include "widgets/KeyReference.h" //!!! should probably split KeyReference into a data class in base and another that shows the widget 51 #include "widgets/KeyReference.h" //!!! should probably split KeyReference into a data class in base and another that shows the widget
51 52
53 //#define DEBUG_PANE
54
52 using std::cerr; 55 using std::cerr;
53 using std::endl; 56 using std::endl;
54 57
55 QCursor *Pane::m_measureCursor1 = 0; 58 QCursor *Pane::m_measureCursor1 = 0;
56 QCursor *Pane::m_measureCursor2 = 0; 59 QCursor *Pane::m_measureCursor2 = 0;
61 m_clickedInRange(false), 64 m_clickedInRange(false),
62 m_shiftPressed(false), 65 m_shiftPressed(false),
63 m_ctrlPressed(false), 66 m_ctrlPressed(false),
64 m_navigating(false), 67 m_navigating(false),
65 m_resizing(false), 68 m_resizing(false),
69 m_editing(false),
70 m_releasing(false),
66 m_centreLineVisible(true), 71 m_centreLineVisible(true),
67 m_scaleWidth(0), 72 m_scaleWidth(0),
68 m_headsUpDisplay(0), 73 m_headsUpDisplay(0),
69 m_vpan(0), 74 m_vpan(0),
70 m_hthumb(0), 75 m_hthumb(0),
386 if (e) r = e->rect(); 391 if (e) r = e->rect();
387 392
388 View::paintEvent(e); 393 View::paintEvent(e);
389 394
390 paint.begin(this); 395 paint.begin(this);
396 setPaintFont(paint);
391 397
392 if (e) paint.setClipRect(r); 398 if (e) paint.setClipRect(r);
393 399
394 ViewManager::ToolMode toolMode = m_manager->getToolMode(); 400 ViewManager::ToolMode toolMode = m_manager->getToolMode();
395 401
1207 emit contextHelpChanged(""); 1213 emit contextHelpChanged("");
1208 emit rightButtonMenuRequested(mapToGlobal(e->pos())); 1214 emit rightButtonMenuRequested(mapToGlobal(e->pos()));
1209 return; 1215 return;
1210 } 1216 }
1211 1217
1218 // std::cerr << "mousePressEvent" << std::endl;
1219
1212 m_clickPos = e->pos(); 1220 m_clickPos = e->pos();
1213 m_mousePos = m_clickPos; 1221 m_mousePos = m_clickPos;
1214 m_clickedInRange = true; 1222 m_clickedInRange = true;
1215 m_editingSelection = Selection(); 1223 m_editingSelection = Selection();
1216 m_editingSelectionEdge = 0; 1224 m_editingSelectionEdge = 0;
1220 1228
1221 ViewManager::ToolMode mode = ViewManager::NavigateMode; 1229 ViewManager::ToolMode mode = ViewManager::NavigateMode;
1222 if (m_manager) mode = m_manager->getToolMode(); 1230 if (m_manager) mode = m_manager->getToolMode();
1223 1231
1224 m_navigating = false; 1232 m_navigating = false;
1233 m_resizing = false;
1234 m_editing = false;
1235 m_releasing = false;
1225 1236
1226 if (mode == ViewManager::NavigateMode || 1237 if (mode == ViewManager::NavigateMode ||
1227 (e->buttons() & Qt::MidButton) || 1238 (e->buttons() & Qt::MidButton) ||
1228 (mode == ViewManager::MeasureMode && 1239 (mode == ViewManager::MeasureMode &&
1229 (e->buttons() & Qt::LeftButton) && m_shiftPressed)) { 1240 (e->buttons() & Qt::LeftButton) && m_shiftPressed)) {
1301 layer->eraseStart(this, e); 1312 layer->eraseStart(this, e);
1302 } 1313 }
1303 1314
1304 } else if (mode == ViewManager::EditMode) { 1315 } else if (mode == ViewManager::EditMode) {
1305 1316
1306 if (!editSelectionStart(e)) { 1317 // Do nothing here -- we'll do it in mouseMoveEvent when the
1307 Layer *layer = getSelectedLayer(); 1318 // drag threshold has been passed
1308 if (layer && layer->isLayerEditable()) {
1309 layer->editStart(this, e);
1310 }
1311 }
1312 1319
1313 } else if (mode == ViewManager::MeasureMode) { 1320 } else if (mode == ViewManager::MeasureMode) {
1314 1321
1315 Layer *layer = getTopLayer(); 1322 Layer *layer = getTopLayer();
1316 if (layer) layer->measureStart(this, e); 1323 if (layer) layer->measureStart(this, e);
1325 { 1332 {
1326 if (e->buttons() & Qt::RightButton) { 1333 if (e->buttons() & Qt::RightButton) {
1327 return; 1334 return;
1328 } 1335 }
1329 1336
1337 // std::cerr << "mouseReleaseEvent" << std::endl;
1338
1330 ViewManager::ToolMode mode = ViewManager::NavigateMode; 1339 ViewManager::ToolMode mode = ViewManager::NavigateMode;
1331 if (m_manager) mode = m_manager->getToolMode(); 1340 if (m_manager) mode = m_manager->getToolMode();
1341
1342 m_releasing = true;
1332 1343
1333 if (m_clickedInRange) { 1344 if (m_clickedInRange) {
1334 mouseMoveEvent(e); 1345 mouseMoveEvent(e);
1335 } 1346 }
1336 1347
1354 zoomToRegion(x0, y0, x1, y1); 1365 zoomToRegion(x0, y0, x1, y1);
1355 } 1366 }
1356 1367
1357 } else if (mode == ViewManager::SelectMode) { 1368 } else if (mode == ViewManager::SelectMode) {
1358 1369
1359 if (!hasTopLayerTimeXAxis()) return; 1370 if (!hasTopLayerTimeXAxis()) {
1371 m_releasing = false;
1372 return;
1373 }
1360 1374
1361 if (m_manager && m_manager->haveInProgressSelection()) { 1375 if (m_manager && m_manager->haveInProgressSelection()) {
1362 1376
1363 bool exclusive; 1377 bool exclusive;
1364 Selection selection = m_manager->getInProgressSelection(exclusive); 1378 Selection selection = m_manager->getInProgressSelection(exclusive);
1394 update(); 1408 update();
1395 } 1409 }
1396 1410
1397 } else if (mode == ViewManager::EditMode) { 1411 } else if (mode == ViewManager::EditMode) {
1398 1412
1399 if (!editSelectionEnd(e)) { 1413 if (m_editing) {
1400 Layer *layer = getSelectedLayer(); 1414 if (!editSelectionEnd(e)) {
1401 if (layer && layer->isLayerEditable()) { 1415 Layer *layer = getSelectedLayer();
1402 layer->editEnd(this, e); 1416 if (layer && layer->isLayerEditable()) {
1403 update(); 1417 layer->editEnd(this, e);
1404 } 1418 update();
1405 } 1419 }
1420 }
1421 }
1406 1422
1407 } else if (mode == ViewManager::MeasureMode) { 1423 } else if (mode == ViewManager::MeasureMode) {
1408 1424
1409 Layer *layer = getTopLayer(); 1425 Layer *layer = getTopLayer();
1410 if (layer) layer->measureEnd(this, e); 1426 if (layer) layer->measureEnd(this, e);
1411 if (m_measureCursor1) setCursor(*m_measureCursor1); 1427 if (m_measureCursor1) setCursor(*m_measureCursor1);
1412 update(); 1428 update();
1413 } 1429 }
1414 1430
1415 m_clickedInRange = false; 1431 m_clickedInRange = false;
1432 m_releasing = false;
1416 1433
1417 emit paneInteractedWith(); 1434 emit paneInteractedWith();
1418 } 1435 }
1419 1436
1420 void 1437 void
1422 { 1439 {
1423 if (e->buttons() & Qt::RightButton) { 1440 if (e->buttons() & Qt::RightButton) {
1424 return; 1441 return;
1425 } 1442 }
1426 1443
1444 // std::cerr << "mouseMoveEvent" << std::endl;
1445
1427 updateContextHelp(&e->pos()); 1446 updateContextHelp(&e->pos());
1447
1448 if (m_navigating && m_clickedInRange && !m_releasing) {
1449
1450 // if no buttons pressed, and not called from
1451 // mouseReleaseEvent, we want to reset clicked-ness (to avoid
1452 // annoying continual drags when we moved the mouse outside
1453 // the window after pressing button first time).
1454
1455 if (!(e->buttons() & Qt::LeftButton) &&
1456 !(e->buttons() & Qt::MidButton)) {
1457 m_clickedInRange = false;
1458 return;
1459 }
1460 }
1428 1461
1429 ViewManager::ToolMode mode = ViewManager::NavigateMode; 1462 ViewManager::ToolMode mode = ViewManager::NavigateMode;
1430 if (m_manager) mode = m_manager->getToolMode(); 1463 if (m_manager) mode = m_manager->getToolMode();
1431 1464
1432 QPoint prevPoint = m_identifyPoint; 1465 QPoint prevPoint = m_identifyPoint;
1507 layer->eraseDrag(this, e); 1540 layer->eraseDrag(this, e);
1508 } 1541 }
1509 1542
1510 } else if (mode == ViewManager::EditMode) { 1543 } else if (mode == ViewManager::EditMode) {
1511 1544
1512 if (!editSelectionDrag(e)) { 1545 if (m_editing) {
1513 Layer *layer = getSelectedLayer(); 1546 if (!editSelectionDrag(e)) {
1514 if (layer && layer->isLayerEditable()) { 1547 Layer *layer = getSelectedLayer();
1515 layer->editDrag(this, e); 1548 if (layer && layer->isLayerEditable()) {
1516 } 1549 layer->editDrag(this, e);
1517 } 1550 }
1551 }
1552 }
1553
1554 if (!m_editing) {
1555
1556 DragMode newDragMode = updateDragMode
1557 (m_dragMode,
1558 m_clickPos,
1559 e->pos(),
1560 true, // can move horiz
1561 true, // can move vert
1562 true, // resist horiz
1563 true); // resist vert
1564
1565 if (newDragMode != UnresolvedDrag) {
1566
1567 m_editing = true;
1568
1569 QMouseEvent clickEvent(QEvent::MouseButtonPress,
1570 m_clickPos,
1571 Qt::NoButton,
1572 e->buttons(),
1573 e->modifiers());
1574
1575 if (!editSelectionStart(&clickEvent)) {
1576 Layer *layer = getSelectedLayer();
1577 if (layer && layer->isLayerEditable()) {
1578 layer->editStart(this, &clickEvent);
1579 }
1580 }
1581 }
1582 }
1518 1583
1519 } else if (mode == ViewManager::MeasureMode) { 1584 } else if (mode == ViewManager::MeasureMode) {
1520 1585
1521 if (m_measureCursor2) setCursor(*m_measureCursor2); 1586 if (m_measureCursor2) setCursor(*m_measureCursor2);
1522 1587
1613 // other direction as well, we may switch into free mode. 1678 // other direction as well, we may switch into free mode.
1614 // 1679 //
1615 // If the top layer is incapable of being dragged 1680 // If the top layer is incapable of being dragged
1616 // vertically, the logic is short circuited. 1681 // vertically, the logic is short circuited.
1617 1682
1618 int xdiff = e->x() - m_clickPos.x(); 1683 m_dragMode = updateDragMode
1619 int ydiff = e->y() - m_clickPos.y(); 1684 (m_dragMode,
1620 int smallThreshold = 10, bigThreshold = 50; 1685 m_clickPos,
1621 1686 e->pos(),
1622 bool canMoveVertical = canTopLayerMoveVertical(); 1687 true, // can move horiz
1623 bool canMoveHorizontal = true; 1688 canTopLayerMoveVertical(), // can move vert
1624 1689 canTopLayerMoveVertical() || (m_manager && m_manager->isPlaying()), // resist horiz
1625 if (!canMoveHorizontal) { 1690 !(m_manager && m_manager->isPlaying())); // resist vert
1626 m_dragMode = HorizontalDrag; 1691
1627 } 1692 if (m_dragMode == HorizontalDrag ||
1628 1693 m_dragMode == FreeDrag) {
1629 if (m_dragMode == UnresolvedDrag) {
1630
1631 if (abs(ydiff) > smallThreshold &&
1632 abs(ydiff) > abs(xdiff) * 2) {
1633 m_dragMode = VerticalDrag;
1634 } else if (abs(xdiff) > smallThreshold &&
1635 abs(xdiff) > abs(ydiff) * 2) {
1636 m_dragMode = HorizontalDrag;
1637 } else if (abs(xdiff) > smallThreshold &&
1638 abs(ydiff) > smallThreshold) {
1639 m_dragMode = FreeDrag;
1640 } else {
1641 // When playing, we don't want to disturb the play
1642 // position too easily; when not playing, we don't
1643 // want to move up/down too easily
1644 if (m_manager && m_manager->isPlaying()) {
1645 canMoveHorizontal = false;
1646 } else {
1647 canMoveVertical = false;
1648 }
1649 }
1650 }
1651
1652 if (m_dragMode == VerticalDrag) {
1653 if (abs(xdiff) > bigThreshold) m_dragMode = FreeDrag;
1654 else canMoveHorizontal = false;
1655 }
1656
1657 if (m_dragMode == HorizontalDrag && canMoveVertical) {
1658 if (abs(ydiff) > bigThreshold) m_dragMode = FreeDrag;
1659 else canMoveVertical = false;
1660 }
1661
1662 if (canMoveHorizontal) {
1663 1694
1664 long frameOff = getFrameForX(e->x()) - getFrameForX(m_clickPos.x()); 1695 long frameOff = getFrameForX(e->x()) - getFrameForX(m_clickPos.x());
1665 1696
1666 size_t newCentreFrame = m_dragCentreFrame; 1697 size_t newCentreFrame = m_dragCentreFrame;
1667 1698
1670 } else if (newCentreFrame >= size_t(frameOff)) { 1701 } else if (newCentreFrame >= size_t(frameOff)) {
1671 newCentreFrame -= frameOff; 1702 newCentreFrame -= frameOff;
1672 } else { 1703 } else {
1673 newCentreFrame = 0; 1704 newCentreFrame = 0;
1674 } 1705 }
1675 1706
1707 #ifdef DEBUG_PANE
1708 std::cerr << "Pane::dragTopLayer: newCentreFrame = " << newCentreFrame <<
1709 ", models end frame = " << getModelsEndFrame() << std::endl;
1710 #endif
1711
1676 if (newCentreFrame >= getModelsEndFrame()) { 1712 if (newCentreFrame >= getModelsEndFrame()) {
1677 newCentreFrame = getModelsEndFrame(); 1713 newCentreFrame = getModelsEndFrame();
1678 if (newCentreFrame > 0) --newCentreFrame; 1714 if (newCentreFrame > 0) --newCentreFrame;
1679 } 1715 }
1680 1716
1681 if (getXForFrame(m_centreFrame) != getXForFrame(newCentreFrame)) { 1717 if (getXForFrame(m_centreFrame) != getXForFrame(newCentreFrame)) {
1682 setCentreFrame(newCentreFrame); 1718 setCentreFrame(newCentreFrame);
1683 } 1719 }
1684 } 1720 }
1685 1721
1686 if (canMoveVertical) { 1722 if (m_dragMode == VerticalDrag ||
1723 m_dragMode == FreeDrag) {
1687 1724
1688 float vmin = 0.f, vmax = 0.f; 1725 float vmin = 0.f, vmax = 0.f;
1689 float dmin = 0.f, dmax = 0.f; 1726 float dmin = 0.f, dmax = 0.f;
1690 1727
1691 if (getTopLayerDisplayExtents(vmin, vmax, dmin, dmax)) { 1728 if (getTopLayerDisplayExtents(vmin, vmax, dmin, dmax)) {
1692 1729
1693 // std::cerr << "ydiff = " << ydiff << std::endl; 1730 // std::cerr << "ydiff = " << ydiff << std::endl;
1694 1731
1732 int ydiff = e->y() - m_clickPos.y();
1695 float perpix = (dmax - dmin) / height(); 1733 float perpix = (dmax - dmin) / height();
1696 float valdiff = ydiff * perpix; 1734 float valdiff = ydiff * perpix;
1697 // std::cerr << "valdiff = " << valdiff << std::endl; 1735 // std::cerr << "valdiff = " << valdiff << std::endl;
1736
1737 if (m_dragMode == UnresolvedDrag && ydiff != 0) {
1738 m_dragMode = VerticalDrag;
1739 }
1698 1740
1699 float newmin = m_dragStartMinValue + valdiff; 1741 float newmin = m_dragStartMinValue + valdiff;
1700 float newmax = m_dragStartMinValue + (dmax - dmin) + valdiff; 1742 float newmax = m_dragStartMinValue + (dmax - dmin) + valdiff;
1701 if (newmin < vmin) { 1743 if (newmin < vmin) {
1702 newmax += vmin - newmin; 1744 newmax += vmin - newmin;
1711 1753
1712 setTopLayerDisplayExtents(newmin, newmax); 1754 setTopLayerDisplayExtents(newmin, newmax);
1713 updateVerticalPanner(); 1755 updateVerticalPanner();
1714 } 1756 }
1715 } 1757 }
1758 }
1759
1760 Pane::DragMode
1761 Pane::updateDragMode(DragMode dragMode,
1762 QPoint origin,
1763 QPoint point,
1764 bool canMoveHorizontal,
1765 bool canMoveVertical,
1766 bool resistHorizontal,
1767 bool resistVertical)
1768 {
1769 int xdiff = point.x() - origin.x();
1770 int ydiff = point.y() - origin.y();
1771
1772 int smallThreshold = 10, bigThreshold = 80;
1773
1774 // std::cerr << "Pane::updateDragMode: xdiff = " << xdiff << ", ydiff = "
1775 // << ydiff << ", canMoveVertical = " << canMoveVertical << ", drag mode = " << m_dragMode << std::endl;
1776
1777 if (dragMode == UnresolvedDrag) {
1778
1779 if (abs(ydiff) > smallThreshold &&
1780 abs(ydiff) > abs(xdiff) * 2 &&
1781 canMoveVertical) {
1782 // std::cerr << "Pane::updateDragMode: passed vertical threshold" << std::endl;
1783 dragMode = VerticalDrag;
1784 } else if (abs(xdiff) > smallThreshold &&
1785 abs(xdiff) > abs(ydiff) * 2 &&
1786 canMoveHorizontal) {
1787 // std::cerr << "Pane::updateDragMode: passed horizontal threshold" << std::endl;
1788 dragMode = HorizontalDrag;
1789 } else if (abs(xdiff) > smallThreshold &&
1790 abs(ydiff) > smallThreshold &&
1791 canMoveVertical &&
1792 canMoveHorizontal) {
1793 // std::cerr << "Pane::updateDragMode: passed both thresholds" << std::endl;
1794 dragMode = FreeDrag;
1795 }
1796 }
1797
1798 if (dragMode == VerticalDrag && canMoveHorizontal) {
1799 if (abs(xdiff) > bigThreshold) dragMode = FreeDrag;
1800 }
1801
1802 if (dragMode == HorizontalDrag && canMoveVertical) {
1803 if (abs(ydiff) > bigThreshold) dragMode = FreeDrag;
1804 }
1805
1806 if (dragMode == UnresolvedDrag) {
1807 if (!resistHorizontal && xdiff != 0) {
1808 dragMode = HorizontalDrag;
1809 }
1810 if (!resistVertical && ydiff != 0) {
1811 if (dragMode == HorizontalDrag) dragMode = FreeDrag;
1812 else dragMode = VerticalDrag;
1813 }
1814 }
1815
1816 return dragMode;
1716 } 1817 }
1717 1818
1718 void 1819 void
1719 Pane::dragExtendSelection(QMouseEvent *e) 1820 Pane::dragExtendSelection(QMouseEvent *e)
1720 { 1821 {