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);