Mercurial > hg > svgui
diff view/Pane.cpp @ 374:64e84e5efb76 spectrogram-cache-rejig
* Merge from trunk
author | Chris Cannam |
---|---|
date | Wed, 27 Feb 2008 11:59:42 +0000 |
parents | 29fcf125f98b |
children |
line wrap: on
line diff
--- a/view/Pane.cpp Mon Nov 19 15:50:37 2007 +0000 +++ b/view/Pane.cpp Wed Feb 27 11:59:42 2008 +0000 @@ -22,6 +22,7 @@ #include "ViewManager.h" #include "base/CommandHistory.h" #include "base/TextAbbrev.h" +#include "base/Preferences.h" #include "layer/WaveformLayer.h" //!!! ugh @@ -49,6 +50,8 @@ #include "widgets/KeyReference.h" //!!! should probably split KeyReference into a data class in base and another that shows the widget +//#define DEBUG_PANE + using std::cerr; using std::endl; @@ -63,6 +66,8 @@ m_ctrlPressed(false), m_navigating(false), m_resizing(false), + m_editing(false), + m_releasing(false), m_centreLineVisible(true), m_scaleWidth(0), m_headsUpDisplay(0), @@ -388,6 +393,7 @@ View::paintEvent(e); paint.begin(this); + setPaintFont(paint); if (e) paint.setClipRect(r); @@ -1209,6 +1215,8 @@ return; } +// std::cerr << "mousePressEvent" << std::endl; + m_clickPos = e->pos(); m_mousePos = m_clickPos; m_clickedInRange = true; @@ -1222,6 +1230,9 @@ if (m_manager) mode = m_manager->getToolMode(); m_navigating = false; + m_resizing = false; + m_editing = false; + m_releasing = false; if (mode == ViewManager::NavigateMode || (e->buttons() & Qt::MidButton) || @@ -1276,9 +1287,10 @@ if (snapFrame < 0) snapFrame = 0; m_selectionStartFrame = snapFrame; if (m_manager) { - m_manager->setInProgressSelection(Selection(snapFrame, - snapFrame + resolution), - !m_ctrlPressed); + m_manager->setInProgressSelection + (Selection(alignToReference(snapFrame), + alignToReference(snapFrame + resolution)), + !m_ctrlPressed); } m_resizing = false; @@ -1293,14 +1305,17 @@ layer->drawStart(this, e); } + } else if (mode == ViewManager::EraseMode) { + + Layer *layer = getSelectedLayer(); + if (layer && layer->isLayerEditable()) { + layer->eraseStart(this, e); + } + } else if (mode == ViewManager::EditMode) { - if (!editSelectionStart(e)) { - Layer *layer = getSelectedLayer(); - if (layer && layer->isLayerEditable()) { - layer->editStart(this, e); - } - } + // Do nothing here -- we'll do it in mouseMoveEvent when the + // drag threshold has been passed } else if (mode == ViewManager::MeasureMode) { @@ -1319,9 +1334,13 @@ return; } +// std::cerr << "mouseReleaseEvent" << std::endl; + ViewManager::ToolMode mode = ViewManager::NavigateMode; if (m_manager) mode = m_manager->getToolMode(); + m_releasing = true; + if (m_clickedInRange) { mouseMoveEvent(e); } @@ -1348,7 +1367,10 @@ } else if (mode == ViewManager::SelectMode) { - if (!hasTopLayerTimeXAxis()) return; + if (!hasTopLayerTimeXAxis()) { + m_releasing = false; + return; + } if (m_manager && m_manager->haveInProgressSelection()) { @@ -1378,15 +1400,25 @@ update(); } + } else if (mode == ViewManager::EraseMode) { + + Layer *layer = getSelectedLayer(); + if (layer && layer->isLayerEditable()) { + layer->eraseEnd(this, e); + update(); + } + } else if (mode == ViewManager::EditMode) { - if (!editSelectionEnd(e)) { - Layer *layer = getSelectedLayer(); - if (layer && layer->isLayerEditable()) { - layer->editEnd(this, e); - update(); - } - } + if (m_editing) { + if (!editSelectionEnd(e)) { + Layer *layer = getSelectedLayer(); + if (layer && layer->isLayerEditable()) { + layer->editEnd(this, e); + update(); + } + } + } } else if (mode == ViewManager::MeasureMode) { @@ -1397,6 +1429,7 @@ } m_clickedInRange = false; + m_releasing = false; emit paneInteractedWith(); } @@ -1408,8 +1441,24 @@ return; } +// std::cerr << "mouseMoveEvent" << std::endl; + updateContextHelp(&e->pos()); + if (m_navigating && m_clickedInRange && !m_releasing) { + + // if no buttons pressed, and not called from + // mouseReleaseEvent, we want to reset clicked-ness (to avoid + // annoying continual drags when we moved the mouse outside + // the window after pressing button first time). + + if (!(e->buttons() & Qt::LeftButton) && + !(e->buttons() & Qt::MidButton)) { + m_clickedInRange = false; + return; + } + } + ViewManager::ToolMode mode = ViewManager::NavigateMode; if (m_manager) mode = m_manager->getToolMode(); @@ -1484,14 +1533,53 @@ layer->drawDrag(this, e); } + } else if (mode == ViewManager::EraseMode) { + + Layer *layer = getSelectedLayer(); + if (layer && layer->isLayerEditable()) { + layer->eraseDrag(this, e); + } + } else if (mode == ViewManager::EditMode) { - if (!editSelectionDrag(e)) { - Layer *layer = getSelectedLayer(); - if (layer && layer->isLayerEditable()) { - layer->editDrag(this, e); - } - } + if (m_editing) { + if (!editSelectionDrag(e)) { + Layer *layer = getSelectedLayer(); + if (layer && layer->isLayerEditable()) { + layer->editDrag(this, e); + } + } + } + + if (!m_editing) { + + DragMode newDragMode = updateDragMode + (m_dragMode, + m_clickPos, + e->pos(), + true, // can move horiz + true, // can move vert + true, // resist horiz + true); // resist vert + + if (newDragMode != UnresolvedDrag) { + + m_editing = true; + + QMouseEvent clickEvent(QEvent::MouseButtonPress, + m_clickPos, + Qt::NoButton, + e->buttons(), + e->modifiers()); + + if (!editSelectionStart(&clickEvent)) { + Layer *layer = getSelectedLayer(); + if (layer && layer->isLayerEditable()) { + layer->editStart(this, &clickEvent); + } + } + } + } } else if (mode == ViewManager::MeasureMode) { @@ -1592,51 +1680,17 @@ // If the top layer is incapable of being dragged // vertically, the logic is short circuited. - int xdiff = e->x() - m_clickPos.x(); - int ydiff = e->y() - m_clickPos.y(); - int smallThreshold = 10, bigThreshold = 50; + m_dragMode = updateDragMode + (m_dragMode, + m_clickPos, + e->pos(), + true, // can move horiz + canTopLayerMoveVertical(), // can move vert + canTopLayerMoveVertical() || (m_manager && m_manager->isPlaying()), // resist horiz + !(m_manager && m_manager->isPlaying())); // resist vert - bool canMoveVertical = canTopLayerMoveVertical(); - bool canMoveHorizontal = true; - - if (!canMoveHorizontal) { - m_dragMode = HorizontalDrag; - } - - if (m_dragMode == UnresolvedDrag) { - - if (abs(ydiff) > smallThreshold && - abs(ydiff) > abs(xdiff) * 2) { - m_dragMode = VerticalDrag; - } else if (abs(xdiff) > smallThreshold && - abs(xdiff) > abs(ydiff) * 2) { - m_dragMode = HorizontalDrag; - } else if (abs(xdiff) > smallThreshold && - abs(ydiff) > smallThreshold) { - m_dragMode = FreeDrag; - } else { - // When playing, we don't want to disturb the play - // position too easily; when not playing, we don't - // want to move up/down too easily - if (m_manager && m_manager->isPlaying()) { - canMoveHorizontal = false; - } else { - canMoveVertical = false; - } - } - } - - if (m_dragMode == VerticalDrag) { - if (abs(xdiff) > bigThreshold) m_dragMode = FreeDrag; - else canMoveHorizontal = false; - } - - if (m_dragMode == HorizontalDrag && canMoveVertical) { - if (abs(ydiff) > bigThreshold) m_dragMode = FreeDrag; - else canMoveVertical = false; - } - - if (canMoveHorizontal) { + if (m_dragMode == HorizontalDrag || + m_dragMode == FreeDrag) { long frameOff = getFrameForX(e->x()) - getFrameForX(m_clickPos.x()); @@ -1649,7 +1703,12 @@ } else { newCentreFrame = 0; } - + +#ifdef DEBUG_PANE + std::cerr << "Pane::dragTopLayer: newCentreFrame = " << newCentreFrame << + ", models end frame = " << getModelsEndFrame() << std::endl; +#endif + if (newCentreFrame >= getModelsEndFrame()) { newCentreFrame = getModelsEndFrame(); if (newCentreFrame > 0) --newCentreFrame; @@ -1660,7 +1719,8 @@ } } - if (canMoveVertical) { + if (m_dragMode == VerticalDrag || + m_dragMode == FreeDrag) { float vmin = 0.f, vmax = 0.f; float dmin = 0.f, dmax = 0.f; @@ -1669,10 +1729,15 @@ // std::cerr << "ydiff = " << ydiff << std::endl; + int ydiff = e->y() - m_clickPos.y(); float perpix = (dmax - dmin) / height(); float valdiff = ydiff * perpix; // std::cerr << "valdiff = " << valdiff << std::endl; + if (m_dragMode == UnresolvedDrag && ydiff != 0) { + m_dragMode = VerticalDrag; + } + float newmin = m_dragStartMinValue + valdiff; float newmax = m_dragStartMinValue + (dmax - dmin) + valdiff; if (newmin < vmin) { @@ -1692,6 +1757,65 @@ } } +Pane::DragMode +Pane::updateDragMode(DragMode dragMode, + QPoint origin, + QPoint point, + bool canMoveHorizontal, + bool canMoveVertical, + bool resistHorizontal, + bool resistVertical) +{ + int xdiff = point.x() - origin.x(); + int ydiff = point.y() - origin.y(); + + int smallThreshold = 10, bigThreshold = 80; + +// std::cerr << "Pane::updateDragMode: xdiff = " << xdiff << ", ydiff = " +// << ydiff << ", canMoveVertical = " << canMoveVertical << ", drag mode = " << m_dragMode << std::endl; + + if (dragMode == UnresolvedDrag) { + + if (abs(ydiff) > smallThreshold && + abs(ydiff) > abs(xdiff) * 2 && + canMoveVertical) { +// std::cerr << "Pane::updateDragMode: passed vertical threshold" << std::endl; + dragMode = VerticalDrag; + } else if (abs(xdiff) > smallThreshold && + abs(xdiff) > abs(ydiff) * 2 && + canMoveHorizontal) { +// std::cerr << "Pane::updateDragMode: passed horizontal threshold" << std::endl; + dragMode = HorizontalDrag; + } else if (abs(xdiff) > smallThreshold && + abs(ydiff) > smallThreshold && + canMoveVertical && + canMoveHorizontal) { +// std::cerr << "Pane::updateDragMode: passed both thresholds" << std::endl; + dragMode = FreeDrag; + } + } + + if (dragMode == VerticalDrag && canMoveHorizontal) { + if (abs(xdiff) > bigThreshold) dragMode = FreeDrag; + } + + if (dragMode == HorizontalDrag && canMoveVertical) { + if (abs(ydiff) > bigThreshold) dragMode = FreeDrag; + } + + if (dragMode == UnresolvedDrag) { + if (!resistHorizontal && xdiff != 0) { + dragMode = HorizontalDrag; + } + if (!resistVertical && ydiff != 0) { + if (dragMode == HorizontalDrag) dragMode = FreeDrag; + else dragMode = VerticalDrag; + } + } + + return dragMode; +} + void Pane::dragExtendSelection(QMouseEvent *e) { @@ -1727,7 +1851,8 @@ } if (m_manager) { - m_manager->setInProgressSelection(Selection(min, max), + m_manager->setInProgressSelection(Selection(alignToReference(min), + alignToReference(max)), !m_resizing && !m_ctrlPressed); } @@ -2187,6 +2312,10 @@ case ViewManager::DrawMode: setCursor(Qt::CrossCursor); break; + + case ViewManager::EraseMode: + setCursor(Qt::CrossCursor); + break; case ViewManager::MeasureMode: if (m_measureCursor1) setCursor(*m_measureCursor1); @@ -2326,6 +2455,13 @@ if (editable) { help = tr("Click to add a new item in the active layer"); } + + } else if (mode == ViewManager::EraseMode) { + + //!!! could call through to a layer function to find out exact meaning + if (editable) { + help = tr("Click to erase an item from the active layer"); + } } else if (mode == ViewManager::EditMode) {