comparison view/Pane.cpp @ 150:b1a3a9400284

* Add a bit of resistance to pane dragging so as to make it harder to inadvertently drag in the other axis from the one you intended
author Chris Cannam
date Fri, 22 Sep 2006 16:46:10 +0000
parents 4d132a06db9b
children 30d624900564
comparison
equal deleted inserted replaced
149:3dade4b025b7 150:b1a3a9400284
484 if (waveformModel && 484 if (waveformModel &&
485 m_manager && 485 m_manager &&
486 m_manager->getOverlayMode() != ViewManager::NoOverlays && 486 m_manager->getOverlayMode() != ViewManager::NoOverlays &&
487 r.y() + r.height() >= height() - fontHeight - 6) { 487 r.y() + r.height() >= height() - fontHeight - 6) {
488 488
489 size_t modelRate = waveformModel->getSampleRate();
489 size_t mainModelRate = m_manager->getMainModelSampleRate(); 490 size_t mainModelRate = m_manager->getMainModelSampleRate();
490 size_t playbackRate = m_manager->getPlaybackSampleRate(); 491 size_t playbackRate = m_manager->getPlaybackSampleRate();
491 492
492 QString srNote = ""; 493 QString srNote = "";
493 494
494 // Show (R) for waveform models that will be resampled on 495 // Show (R) for waveform models that will be resampled on
495 // playback, and (X) for waveform models that will be played 496 // playback, and (X) for waveform models that will be played
496 // at the wrong rate because their rate differs from that of 497 // at the wrong rate because their rate differs from that of
497 // the main model. 498 // the main model.
498 499
499 if (sampleRate == mainModelRate) { 500 if (modelRate == mainModelRate) {
500 if (sampleRate != playbackRate) srNote = " " + tr("(R)"); 501 if (modelRate != playbackRate) srNote = " " + tr("(R)");
501 } else { 502 } else {
502 std::cerr << "Sample rate = " << sampleRate << ", main model rate = " << mainModelRate << std::endl; 503 // std::cerr << "Sample rate = " << modelRate << ", main model rate = " << mainModelRate << std::endl;
503 srNote = " " + tr("(X)"); 504 srNote = " " + tr("(X)");
504 } 505 }
505 506
506 QString desc = tr("%1 / %2Hz%3") 507 QString desc = tr("%1 / %2Hz%3")
507 .arg(RealTime::frame2RealTime(waveformModel->getEndFrame(), 508 .arg(RealTime::frame2RealTime(waveformModel->getEndFrame(),
508 sampleRate) 509 sampleRate)
509 .toText(false).c_str()) 510 .toText(false).c_str())
510 .arg(sampleRate) 511 .arg(modelRate)
511 .arg(srNote); 512 .arg(srNote);
512 513
513 if (r.x() < verticalScaleWidth + 5 + paint.fontMetrics().width(desc)) { 514 if (r.x() < verticalScaleWidth + 5 + paint.fontMetrics().width(desc)) {
514 drawVisibleText(paint, verticalScaleWidth + 5, 515 drawVisibleText(paint, verticalScaleWidth + 5,
515 height() - fontHeight + fontAscent - 6, 516 height() - fontHeight + fontAscent - 6,
666 m_clickedInRange = true; 667 m_clickedInRange = true;
667 m_editingSelection = Selection(); 668 m_editingSelection = Selection();
668 m_editingSelectionEdge = 0; 669 m_editingSelectionEdge = 0;
669 m_shiftPressed = (e->modifiers() & Qt::ShiftModifier); 670 m_shiftPressed = (e->modifiers() & Qt::ShiftModifier);
670 m_ctrlPressed = (e->modifiers() & Qt::ControlModifier); 671 m_ctrlPressed = (e->modifiers() & Qt::ControlModifier);
672 m_dragMode = UnresolvedDrag;
671 673
672 ViewManager::ToolMode mode = ViewManager::NavigateMode; 674 ViewManager::ToolMode mode = ViewManager::NavigateMode;
673 if (m_manager) mode = m_manager->getToolMode(); 675 if (m_manager) mode = m_manager->getToolMode();
674 676
675 m_navigating = false; 677 m_navigating = false;
948 950
949 m_mousePos = e->pos(); 951 m_mousePos = e->pos();
950 update(); 952 update();
951 953
952 } else { 954 } else {
953
954 long frameOff = getFrameForX(e->x()) - getFrameForX(m_clickPos.x());
955
956 size_t newCentreFrame = m_dragCentreFrame;
957
958 if (frameOff < 0) {
959 newCentreFrame -= frameOff;
960 } else if (newCentreFrame >= size_t(frameOff)) {
961 newCentreFrame -= frameOff;
962 } else {
963 newCentreFrame = 0;
964 }
965
966 if (newCentreFrame >= getModelsEndFrame()) {
967 newCentreFrame = getModelsEndFrame();
968 if (newCentreFrame > 0) --newCentreFrame;
969 }
970
971 if (getXForFrame(m_centreFrame) != getXForFrame(newCentreFrame)) {
972 setCentreFrame(newCentreFrame);
973 }
974
975 //!!! For drag up/down, we need to: call getValueExtents
976 //and getDisplayExtents and see whether both return true
977 //(we can only drag up/down if they do); and check whether
978 //the ranges returned differ (likewise). Then, we know
979 //the height of the layer, so...
980
981 //!!! this should have its own function
982 955
983 //!!! want to do some cleverness to avoid dragging left/right 956 //!!! want to do some cleverness to avoid dragging left/right
984 // at the same time as up/down when the user moves the mouse 957 // at the same time as up/down when the user moves the mouse
985 // diagonally. 958 // diagonally.
986 // e.g. have horizontal and vertical thresholds and a series 959 // e.g. have horizontal and vertical thresholds and a series
995 // -> when it's moved more than say 10px in h or v 968 // -> when it's moved more than say 10px in h or v
996 // direction we lock into h or v constrained mode. If it 969 // direction we lock into h or v constrained mode. If it
997 // moves more than say 20px in the other direction 970 // moves more than say 20px in the other direction
998 // subsequently, then we switch into free mode. 971 // subsequently, then we switch into free mode.
999 972
1000 Layer *layer = 0; 973 int xdiff = e->x() - m_clickPos.x();
1001 if (getLayerCount() > 0) layer = getLayer(getLayerCount() - 1); 974 int ydiff = e->y() - m_clickPos.y();
1002 975 int smallThreshold = 10, bigThreshold = 50;
1003 if (layer) { 976
1004 977 bool canMoveVertical = true;
1005 float vmin = 0.f, vmax = 0.f; 978 bool canMoveHorizontal = true;
1006 bool vlog = false; 979
1007 QString vunit; 980 //!!! need to test whether the layer is actually draggable
1008 981 // vertically before we do any of this
1009 float dmin = 0.f, dmax = 0.f; 982
1010 983 if (m_dragMode == UnresolvedDrag) {
1011 if (layer->getValueExtents(vmin, vmax, vlog, vunit) && 984
1012 layer->getDisplayExtents(dmin, dmax) && 985 if (abs(ydiff) > smallThreshold &&
1013 (dmin > vmin || dmax < vmax)) { 986 abs(ydiff) > abs(xdiff) * 2) {
1014 987 m_dragMode = VerticalDrag;
1015 int ydiff = e->y() - m_clickPos.y(); 988 } else if (abs(xdiff) > smallThreshold &&
1016 std::cerr << "ydiff = " << ydiff << std::endl; 989 abs(xdiff) > abs(ydiff) * 2) {
1017 990 m_dragMode = HorizontalDrag;
1018 float perpix = (dmax - dmin) / height(); 991 } else if (abs(xdiff) > smallThreshold &&
1019 float valdiff = ydiff * perpix; 992 abs(ydiff) > smallThreshold) {
1020 std::cerr << "valdiff = " << valdiff << std::endl; 993 m_dragMode = FreeDrag;
1021 994 } else {
1022 float newmin = m_dragStartMinValue + valdiff; 995 // When playing, we don't want to disturb the play
1023 float newmax = m_dragStartMinValue + (dmax - dmin) + valdiff; 996 // position too easily; when not playing, we don't
1024 if (newmin < vmin) { 997 // want to move up/down too easily
1025 newmax += vmin - newmin; 998 if (m_manager && m_manager->isPlaying()) {
1026 newmin += vmin - newmin; 999 canMoveHorizontal = false;
1000 } else {
1001 canMoveVertical = false;
1027 } 1002 }
1028 if (newmax > vmax) { 1003 }
1029 newmin -= newmax - vmax; 1004 }
1030 newmax -= newmax - vmax; 1005
1006 if (m_dragMode == VerticalDrag) {
1007 if (abs(xdiff) > bigThreshold) m_dragMode = FreeDrag;
1008 else canMoveHorizontal = false;
1009 }
1010
1011 if (m_dragMode == HorizontalDrag) {
1012 if (abs(ydiff) > bigThreshold) m_dragMode = FreeDrag;
1013 else canMoveVertical = false;
1014 }
1015
1016 if (canMoveHorizontal) {
1017
1018 long frameOff = getFrameForX(e->x()) - getFrameForX(m_clickPos.x());
1019
1020 size_t newCentreFrame = m_dragCentreFrame;
1021
1022 if (frameOff < 0) {
1023 newCentreFrame -= frameOff;
1024 } else if (newCentreFrame >= size_t(frameOff)) {
1025 newCentreFrame -= frameOff;
1026 } else {
1027 newCentreFrame = 0;
1028 }
1029
1030 if (newCentreFrame >= getModelsEndFrame()) {
1031 newCentreFrame = getModelsEndFrame();
1032 if (newCentreFrame > 0) --newCentreFrame;
1033 }
1034
1035 if (getXForFrame(m_centreFrame) != getXForFrame(newCentreFrame)) {
1036 setCentreFrame(newCentreFrame);
1037 }
1038 }
1039
1040 //!!! For drag up/down, we need to: call getValueExtents
1041 //and getDisplayExtents and see whether both return true
1042 //(we can only drag up/down if they do); and check whether
1043 //the ranges returned differ (likewise). Then, we know
1044 //the height of the layer, so...
1045
1046 //!!! this should have its own function
1047
1048 if (canMoveVertical) {
1049
1050 Layer *layer = 0;
1051 if (getLayerCount() > 0) layer = getLayer(getLayerCount() - 1);
1052
1053 if (layer) {
1054
1055 float vmin = 0.f, vmax = 0.f;
1056 bool vlog = false;
1057 QString vunit;
1058
1059 float dmin = 0.f, dmax = 0.f;
1060
1061 if (layer->getValueExtents(vmin, vmax, vlog, vunit) &&
1062 layer->getDisplayExtents(dmin, dmax) &&
1063 (dmin > vmin || dmax < vmax)) {
1064
1065 std::cerr << "ydiff = " << ydiff << std::endl;
1066
1067 float perpix = (dmax - dmin) / height();
1068 float valdiff = ydiff * perpix;
1069 std::cerr << "valdiff = " << valdiff << std::endl;
1070
1071 float newmin = m_dragStartMinValue + valdiff;
1072 float newmax = m_dragStartMinValue + (dmax - dmin) + valdiff;
1073 if (newmin < vmin) {
1074 newmax += vmin - newmin;
1075 newmin += vmin - newmin;
1076 }
1077 if (newmax > vmax) {
1078 newmin -= newmax - vmax;
1079 newmax -= newmax - vmax;
1080 }
1081 std::cerr << "(" << dmin << ", " << dmax << ") -> ("
1082 << newmin << ", " << newmax << ") (drag start " << m_dragStartMinValue << ")" << std::endl;
1083 layer->setDisplayExtents(newmin, newmax);
1031 } 1084 }
1032 std::cerr << "(" << dmin << ", " << dmax << ") -> ("
1033 << newmin << ", " << newmax << ") (drag start " << m_dragStartMinValue << ")" << std::endl;
1034 layer->setDisplayExtents(newmin, newmax);
1035 } 1085 }
1036 } 1086 }
1037 } 1087 }
1038 1088
1039 } else if (mode == ViewManager::SelectMode) { 1089 } else if (mode == ViewManager::SelectMode) {
1040 1090
1041 int mouseFrame = getFrameForX(e->x()); 1091 int mouseFrame = getFrameForX(e->x());
1042 size_t resolution = 1; 1092 size_t resolution = 1;