Mercurial > hg > svgui
comparison view/Pane.cpp @ 343:1b6879d03cb6
* Fix #1848191 double clicking on time instants causes move
Also fix tendency for navigate mode to continue navigating even
after button release
author | Chris Cannam |
---|---|
date | Tue, 18 Dec 2007 10:35:55 +0000 |
parents | 998786b3174f |
children | 6167a28d25fc |
comparison
equal
deleted
inserted
replaced
342:a904364dfb6e | 343:1b6879d03cb6 |
---|---|
62 m_clickedInRange(false), | 62 m_clickedInRange(false), |
63 m_shiftPressed(false), | 63 m_shiftPressed(false), |
64 m_ctrlPressed(false), | 64 m_ctrlPressed(false), |
65 m_navigating(false), | 65 m_navigating(false), |
66 m_resizing(false), | 66 m_resizing(false), |
67 m_editing(false), | |
68 m_releasing(false), | |
67 m_centreLineVisible(true), | 69 m_centreLineVisible(true), |
68 m_scaleWidth(0), | 70 m_scaleWidth(0), |
69 m_headsUpDisplay(0), | 71 m_headsUpDisplay(0), |
70 m_vpan(0), | 72 m_vpan(0), |
71 m_hthumb(0), | 73 m_hthumb(0), |
1209 emit contextHelpChanged(""); | 1211 emit contextHelpChanged(""); |
1210 emit rightButtonMenuRequested(mapToGlobal(e->pos())); | 1212 emit rightButtonMenuRequested(mapToGlobal(e->pos())); |
1211 return; | 1213 return; |
1212 } | 1214 } |
1213 | 1215 |
1214 std::cerr << "mousePressEvent" << std::endl; | 1216 // std::cerr << "mousePressEvent" << std::endl; |
1215 | |
1216 | |
1217 //!!! need to avoid spurious mouse events when e.g. double-clicking. | |
1218 | |
1219 // when double clicking, we get: | |
1220 // mousePressEvent | |
1221 // mouseReleaseEvent | |
1222 // mouseMoveEvent <- called from mouseReleaseEvent | |
1223 // mouseDoubleClickEvent | |
1224 // mouseReleaseEvent | |
1225 // mouseMoveEvent <- called from mouseReleaseEvent | |
1226 | |
1227 // so we set a timer on the first press, if we're in a mode in | |
1228 // which moving the mouse will do something | |
1229 | |
1230 // the move method doesn't do anything unless that timer has | |
1231 // elapsed | |
1232 | |
1233 | 1217 |
1234 m_clickPos = e->pos(); | 1218 m_clickPos = e->pos(); |
1235 m_mousePos = m_clickPos; | 1219 m_mousePos = m_clickPos; |
1236 m_clickedInRange = true; | 1220 m_clickedInRange = true; |
1237 m_editingSelection = Selection(); | 1221 m_editingSelection = Selection(); |
1242 | 1226 |
1243 ViewManager::ToolMode mode = ViewManager::NavigateMode; | 1227 ViewManager::ToolMode mode = ViewManager::NavigateMode; |
1244 if (m_manager) mode = m_manager->getToolMode(); | 1228 if (m_manager) mode = m_manager->getToolMode(); |
1245 | 1229 |
1246 m_navigating = false; | 1230 m_navigating = false; |
1231 m_resizing = false; | |
1232 m_editing = false; | |
1233 m_releasing = false; | |
1247 | 1234 |
1248 if (mode == ViewManager::NavigateMode || | 1235 if (mode == ViewManager::NavigateMode || |
1249 (e->buttons() & Qt::MidButton) || | 1236 (e->buttons() & Qt::MidButton) || |
1250 (mode == ViewManager::MeasureMode && | 1237 (mode == ViewManager::MeasureMode && |
1251 (e->buttons() & Qt::LeftButton) && m_shiftPressed)) { | 1238 (e->buttons() & Qt::LeftButton) && m_shiftPressed)) { |
1323 layer->eraseStart(this, e); | 1310 layer->eraseStart(this, e); |
1324 } | 1311 } |
1325 | 1312 |
1326 } else if (mode == ViewManager::EditMode) { | 1313 } else if (mode == ViewManager::EditMode) { |
1327 | 1314 |
1328 if (!editSelectionStart(e)) { | 1315 // Do nothing here -- we'll do it in mouseMoveEvent when the |
1329 Layer *layer = getSelectedLayer(); | 1316 // drag threshold has been passed |
1330 if (layer && layer->isLayerEditable()) { | |
1331 layer->editStart(this, e); | |
1332 } | |
1333 } | |
1334 | 1317 |
1335 } else if (mode == ViewManager::MeasureMode) { | 1318 } else if (mode == ViewManager::MeasureMode) { |
1336 | 1319 |
1337 Layer *layer = getTopLayer(); | 1320 Layer *layer = getTopLayer(); |
1338 if (layer) layer->measureStart(this, e); | 1321 if (layer) layer->measureStart(this, e); |
1347 { | 1330 { |
1348 if (e->buttons() & Qt::RightButton) { | 1331 if (e->buttons() & Qt::RightButton) { |
1349 return; | 1332 return; |
1350 } | 1333 } |
1351 | 1334 |
1352 std::cerr << "mouseReleaseEvent" << std::endl; | 1335 // std::cerr << "mouseReleaseEvent" << std::endl; |
1353 | 1336 |
1354 ViewManager::ToolMode mode = ViewManager::NavigateMode; | 1337 ViewManager::ToolMode mode = ViewManager::NavigateMode; |
1355 if (m_manager) mode = m_manager->getToolMode(); | 1338 if (m_manager) mode = m_manager->getToolMode(); |
1339 | |
1340 m_releasing = true; | |
1356 | 1341 |
1357 if (m_clickedInRange) { | 1342 if (m_clickedInRange) { |
1358 mouseMoveEvent(e); | 1343 mouseMoveEvent(e); |
1359 } | 1344 } |
1360 | 1345 |
1378 zoomToRegion(x0, y0, x1, y1); | 1363 zoomToRegion(x0, y0, x1, y1); |
1379 } | 1364 } |
1380 | 1365 |
1381 } else if (mode == ViewManager::SelectMode) { | 1366 } else if (mode == ViewManager::SelectMode) { |
1382 | 1367 |
1383 if (!hasTopLayerTimeXAxis()) return; | 1368 if (!hasTopLayerTimeXAxis()) { |
1369 m_releasing = false; | |
1370 return; | |
1371 } | |
1384 | 1372 |
1385 if (m_manager && m_manager->haveInProgressSelection()) { | 1373 if (m_manager && m_manager->haveInProgressSelection()) { |
1386 | 1374 |
1387 bool exclusive; | 1375 bool exclusive; |
1388 Selection selection = m_manager->getInProgressSelection(exclusive); | 1376 Selection selection = m_manager->getInProgressSelection(exclusive); |
1418 update(); | 1406 update(); |
1419 } | 1407 } |
1420 | 1408 |
1421 } else if (mode == ViewManager::EditMode) { | 1409 } else if (mode == ViewManager::EditMode) { |
1422 | 1410 |
1423 if (!editSelectionEnd(e)) { | 1411 if (m_editing) { |
1424 Layer *layer = getSelectedLayer(); | 1412 if (!editSelectionEnd(e)) { |
1425 if (layer && layer->isLayerEditable()) { | 1413 Layer *layer = getSelectedLayer(); |
1426 layer->editEnd(this, e); | 1414 if (layer && layer->isLayerEditable()) { |
1427 update(); | 1415 layer->editEnd(this, e); |
1428 } | 1416 update(); |
1429 } | 1417 } |
1418 } | |
1419 } | |
1430 | 1420 |
1431 } else if (mode == ViewManager::MeasureMode) { | 1421 } else if (mode == ViewManager::MeasureMode) { |
1432 | 1422 |
1433 Layer *layer = getTopLayer(); | 1423 Layer *layer = getTopLayer(); |
1434 if (layer) layer->measureEnd(this, e); | 1424 if (layer) layer->measureEnd(this, e); |
1435 if (m_measureCursor1) setCursor(*m_measureCursor1); | 1425 if (m_measureCursor1) setCursor(*m_measureCursor1); |
1436 update(); | 1426 update(); |
1437 } | 1427 } |
1438 | 1428 |
1439 m_clickedInRange = false; | 1429 m_clickedInRange = false; |
1430 m_releasing = false; | |
1440 | 1431 |
1441 emit paneInteractedWith(); | 1432 emit paneInteractedWith(); |
1442 } | 1433 } |
1443 | 1434 |
1444 void | 1435 void |
1446 { | 1437 { |
1447 if (e->buttons() & Qt::RightButton) { | 1438 if (e->buttons() & Qt::RightButton) { |
1448 return; | 1439 return; |
1449 } | 1440 } |
1450 | 1441 |
1451 std::cerr << "mouseMoveEvent" << std::endl; | 1442 // std::cerr << "mouseMoveEvent" << std::endl; |
1452 | |
1453 //!!! if no buttons pressed, and not called from | |
1454 //mouseReleaseEvent, we want to reset clicked-ness (to avoid | |
1455 //annoying continual drags when we moved the mouse outside the | |
1456 //window after pressing button first time). | |
1457 | 1443 |
1458 updateContextHelp(&e->pos()); | 1444 updateContextHelp(&e->pos()); |
1445 | |
1446 if (m_navigating && m_clickedInRange && !m_releasing) { | |
1447 | |
1448 // if no buttons pressed, and not called from | |
1449 // mouseReleaseEvent, we want to reset clicked-ness (to avoid | |
1450 // annoying continual drags when we moved the mouse outside | |
1451 // the window after pressing button first time). | |
1452 | |
1453 if (!(e->buttons() & Qt::LeftButton) && | |
1454 !(e->buttons() & Qt::MidButton)) { | |
1455 m_clickedInRange = false; | |
1456 return; | |
1457 } | |
1458 } | |
1459 | 1459 |
1460 ViewManager::ToolMode mode = ViewManager::NavigateMode; | 1460 ViewManager::ToolMode mode = ViewManager::NavigateMode; |
1461 if (m_manager) mode = m_manager->getToolMode(); | 1461 if (m_manager) mode = m_manager->getToolMode(); |
1462 | 1462 |
1463 QPoint prevPoint = m_identifyPoint; | 1463 QPoint prevPoint = m_identifyPoint; |
1538 layer->eraseDrag(this, e); | 1538 layer->eraseDrag(this, e); |
1539 } | 1539 } |
1540 | 1540 |
1541 } else if (mode == ViewManager::EditMode) { | 1541 } else if (mode == ViewManager::EditMode) { |
1542 | 1542 |
1543 if (!editSelectionDrag(e)) { | 1543 if (m_editing) { |
1544 Layer *layer = getSelectedLayer(); | 1544 if (!editSelectionDrag(e)) { |
1545 if (layer && layer->isLayerEditable()) { | 1545 Layer *layer = getSelectedLayer(); |
1546 layer->editDrag(this, e); | 1546 if (layer && layer->isLayerEditable()) { |
1547 } | 1547 layer->editDrag(this, e); |
1548 } | 1548 } |
1549 } | |
1550 } | |
1551 | |
1552 if (!m_editing) { | |
1553 | |
1554 DragMode newDragMode = updateDragMode | |
1555 (m_dragMode, | |
1556 m_clickPos, | |
1557 e->pos(), | |
1558 true, // can move horiz | |
1559 true, // can move vert | |
1560 true, // resist horiz | |
1561 true); // resist vert | |
1562 | |
1563 if (newDragMode != UnresolvedDrag) { | |
1564 | |
1565 m_editing = true; | |
1566 | |
1567 QMouseEvent clickEvent(QEvent::MouseButtonPress, | |
1568 m_clickPos, | |
1569 Qt::NoButton, | |
1570 e->buttons(), | |
1571 e->modifiers()); | |
1572 | |
1573 if (!editSelectionStart(&clickEvent)) { | |
1574 Layer *layer = getSelectedLayer(); | |
1575 if (layer && layer->isLayerEditable()) { | |
1576 layer->editStart(this, &clickEvent); | |
1577 } | |
1578 } | |
1579 } | |
1580 } | |
1549 | 1581 |
1550 } else if (mode == ViewManager::MeasureMode) { | 1582 } else if (mode == ViewManager::MeasureMode) { |
1551 | 1583 |
1552 if (m_measureCursor2) setCursor(*m_measureCursor2); | 1584 if (m_measureCursor2) setCursor(*m_measureCursor2); |
1553 | 1585 |
1644 // other direction as well, we may switch into free mode. | 1676 // other direction as well, we may switch into free mode. |
1645 // | 1677 // |
1646 // If the top layer is incapable of being dragged | 1678 // If the top layer is incapable of being dragged |
1647 // vertically, the logic is short circuited. | 1679 // vertically, the logic is short circuited. |
1648 | 1680 |
1649 int xdiff = e->x() - m_clickPos.x(); | 1681 m_dragMode = updateDragMode |
1650 int ydiff = e->y() - m_clickPos.y(); | 1682 (m_dragMode, |
1651 int smallThreshold = 10, bigThreshold = 50; | 1683 m_clickPos, |
1652 | 1684 e->pos(), |
1653 bool canMoveVertical = canTopLayerMoveVertical(); | 1685 true, // can move horiz |
1654 bool canMoveHorizontal = true; | 1686 canTopLayerMoveVertical(), // can move vert |
1655 | 1687 canTopLayerMoveVertical() || (m_manager && m_manager->isPlaying()), // resist horiz |
1656 if (!canMoveHorizontal) { | 1688 !(m_manager && m_manager->isPlaying())); // resist vert |
1657 m_dragMode = HorizontalDrag; | 1689 |
1658 } | 1690 if (m_dragMode == HorizontalDrag || |
1659 | 1691 m_dragMode == FreeDrag) { |
1660 if (m_dragMode == UnresolvedDrag) { | |
1661 | |
1662 if (abs(ydiff) > smallThreshold && | |
1663 abs(ydiff) > abs(xdiff) * 2) { | |
1664 m_dragMode = VerticalDrag; | |
1665 } else if (abs(xdiff) > smallThreshold && | |
1666 abs(xdiff) > abs(ydiff) * 2) { | |
1667 m_dragMode = HorizontalDrag; | |
1668 } else if (abs(xdiff) > smallThreshold && | |
1669 abs(ydiff) > smallThreshold) { | |
1670 m_dragMode = FreeDrag; | |
1671 } else { | |
1672 // When playing, we don't want to disturb the play | |
1673 // position too easily; when not playing, we don't | |
1674 // want to move up/down too easily | |
1675 if (m_manager && m_manager->isPlaying()) { | |
1676 canMoveHorizontal = false; | |
1677 } else { | |
1678 canMoveVertical = false; | |
1679 } | |
1680 } | |
1681 } | |
1682 | |
1683 if (m_dragMode == VerticalDrag) { | |
1684 if (abs(xdiff) > bigThreshold) m_dragMode = FreeDrag; | |
1685 else canMoveHorizontal = false; | |
1686 } | |
1687 | |
1688 if (m_dragMode == HorizontalDrag && canMoveVertical) { | |
1689 if (abs(ydiff) > bigThreshold) m_dragMode = FreeDrag; | |
1690 else canMoveVertical = false; | |
1691 } | |
1692 | |
1693 if (canMoveHorizontal) { | |
1694 | 1692 |
1695 long frameOff = getFrameForX(e->x()) - getFrameForX(m_clickPos.x()); | 1693 long frameOff = getFrameForX(e->x()) - getFrameForX(m_clickPos.x()); |
1696 | 1694 |
1697 size_t newCentreFrame = m_dragCentreFrame; | 1695 size_t newCentreFrame = m_dragCentreFrame; |
1698 | 1696 |
1715 if (getXForFrame(m_centreFrame) != getXForFrame(newCentreFrame)) { | 1713 if (getXForFrame(m_centreFrame) != getXForFrame(newCentreFrame)) { |
1716 setCentreFrame(newCentreFrame); | 1714 setCentreFrame(newCentreFrame); |
1717 } | 1715 } |
1718 } | 1716 } |
1719 | 1717 |
1720 if (canMoveVertical) { | 1718 if (m_dragMode == VerticalDrag || |
1719 m_dragMode == FreeDrag) { | |
1721 | 1720 |
1722 float vmin = 0.f, vmax = 0.f; | 1721 float vmin = 0.f, vmax = 0.f; |
1723 float dmin = 0.f, dmax = 0.f; | 1722 float dmin = 0.f, dmax = 0.f; |
1724 | 1723 |
1725 if (getTopLayerDisplayExtents(vmin, vmax, dmin, dmax)) { | 1724 if (getTopLayerDisplayExtents(vmin, vmax, dmin, dmax)) { |
1726 | 1725 |
1727 // std::cerr << "ydiff = " << ydiff << std::endl; | 1726 // std::cerr << "ydiff = " << ydiff << std::endl; |
1728 | 1727 |
1728 int ydiff = e->y() - m_clickPos.y(); | |
1729 float perpix = (dmax - dmin) / height(); | 1729 float perpix = (dmax - dmin) / height(); |
1730 float valdiff = ydiff * perpix; | 1730 float valdiff = ydiff * perpix; |
1731 // std::cerr << "valdiff = " << valdiff << std::endl; | 1731 // std::cerr << "valdiff = " << valdiff << std::endl; |
1732 | |
1733 if (m_dragMode == UnresolvedDrag && ydiff != 0) { | |
1734 m_dragMode = VerticalDrag; | |
1735 } | |
1732 | 1736 |
1733 float newmin = m_dragStartMinValue + valdiff; | 1737 float newmin = m_dragStartMinValue + valdiff; |
1734 float newmax = m_dragStartMinValue + (dmax - dmin) + valdiff; | 1738 float newmax = m_dragStartMinValue + (dmax - dmin) + valdiff; |
1735 if (newmin < vmin) { | 1739 if (newmin < vmin) { |
1736 newmax += vmin - newmin; | 1740 newmax += vmin - newmin; |
1745 | 1749 |
1746 setTopLayerDisplayExtents(newmin, newmax); | 1750 setTopLayerDisplayExtents(newmin, newmax); |
1747 updateVerticalPanner(); | 1751 updateVerticalPanner(); |
1748 } | 1752 } |
1749 } | 1753 } |
1754 } | |
1755 | |
1756 Pane::DragMode | |
1757 Pane::updateDragMode(DragMode dragMode, | |
1758 QPoint origin, | |
1759 QPoint point, | |
1760 bool canMoveHorizontal, | |
1761 bool canMoveVertical, | |
1762 bool resistHorizontal, | |
1763 bool resistVertical) | |
1764 { | |
1765 int xdiff = point.x() - origin.x(); | |
1766 int ydiff = point.y() - origin.y(); | |
1767 | |
1768 int smallThreshold = 10, bigThreshold = 80; | |
1769 | |
1770 // std::cerr << "Pane::updateDragMode: xdiff = " << xdiff << ", ydiff = " | |
1771 // << ydiff << ", canMoveVertical = " << canMoveVertical << ", drag mode = " << m_dragMode << std::endl; | |
1772 | |
1773 if (dragMode == UnresolvedDrag) { | |
1774 | |
1775 if (abs(ydiff) > smallThreshold && | |
1776 abs(ydiff) > abs(xdiff) * 2 && | |
1777 canMoveVertical) { | |
1778 // std::cerr << "Pane::updateDragMode: passed vertical threshold" << std::endl; | |
1779 dragMode = VerticalDrag; | |
1780 } else if (abs(xdiff) > smallThreshold && | |
1781 abs(xdiff) > abs(ydiff) * 2 && | |
1782 canMoveHorizontal) { | |
1783 // std::cerr << "Pane::updateDragMode: passed horizontal threshold" << std::endl; | |
1784 dragMode = HorizontalDrag; | |
1785 } else if (abs(xdiff) > smallThreshold && | |
1786 abs(ydiff) > smallThreshold && | |
1787 canMoveVertical && | |
1788 canMoveHorizontal) { | |
1789 // std::cerr << "Pane::updateDragMode: passed both thresholds" << std::endl; | |
1790 dragMode = FreeDrag; | |
1791 } | |
1792 } | |
1793 | |
1794 if (dragMode == VerticalDrag && canMoveHorizontal) { | |
1795 if (abs(xdiff) > bigThreshold) dragMode = FreeDrag; | |
1796 } | |
1797 | |
1798 if (dragMode == HorizontalDrag && canMoveVertical) { | |
1799 if (abs(ydiff) > bigThreshold) dragMode = FreeDrag; | |
1800 } | |
1801 | |
1802 if (dragMode == UnresolvedDrag) { | |
1803 if (!resistHorizontal && xdiff != 0) { | |
1804 dragMode = HorizontalDrag; | |
1805 } | |
1806 if (!resistVertical && ydiff != 0) { | |
1807 if (dragMode == HorizontalDrag) dragMode = FreeDrag; | |
1808 else dragMode = VerticalDrag; | |
1809 } | |
1810 } | |
1811 | |
1812 return dragMode; | |
1750 } | 1813 } |
1751 | 1814 |
1752 void | 1815 void |
1753 Pane::dragExtendSelection(QMouseEvent *e) | 1816 Pane::dragExtendSelection(QMouseEvent *e) |
1754 { | 1817 { |
1826 { | 1889 { |
1827 if (e->buttons() & Qt::RightButton) { | 1890 if (e->buttons() & Qt::RightButton) { |
1828 return; | 1891 return; |
1829 } | 1892 } |
1830 | 1893 |
1831 std::cerr << "mouseDoubleClickEvent" << std::endl; | 1894 // std::cerr << "mouseDoubleClickEvent" << std::endl; |
1832 | 1895 |
1833 m_clickPos = e->pos(); | 1896 m_clickPos = e->pos(); |
1834 m_clickedInRange = true; | 1897 m_clickedInRange = true; |
1835 m_shiftPressed = (e->modifiers() & Qt::ShiftModifier); | 1898 m_shiftPressed = (e->modifiers() & Qt::ShiftModifier); |
1836 m_ctrlPressed = (e->modifiers() & Qt::ControlModifier); | 1899 m_ctrlPressed = (e->modifiers() & Qt::ControlModifier); |