Beispiel #1
0
MatrixResizer::FollowMode
MatrixResizer::handleMouseMove(const MatrixMouseEvent *e)
{
    if (!e) return NoFollow;

    setBasicContextHelp();

    if (!m_currentElement || !m_currentViewSegment) return NoFollow;

    if (getSnapGrid()->getSnapSetting() != SnapGrid::NoSnap) {
        setContextHelp(tr("Hold Shift to avoid snapping to beat grid"));
    } else {
        clearContextHelp();
    }

    // snap in the closest direction
    timeT snapTime = e->snappedLeftTime;
    if (e->snappedRightTime - e->time < e->time - e->snappedLeftTime) {
        snapTime = e->snappedRightTime;
    }

    timeT newDuration = snapTime - m_currentElement->getViewAbsoluteTime();
    timeT durationDiff = newDuration - m_currentElement->getViewDuration();

    EventSelection* selection = m_scene->getSelection();
    if (!selection || selection->getAddedEvents() == 0) return NoFollow;

    EventSelection::eventcontainer::iterator it =
        selection->getSegmentEvents().begin();

    for (; it != selection->getSegmentEvents().end(); ++it) {

        MatrixElement *element = 0;
        ViewElementList::iterator vi = m_currentViewSegment->findEvent(*it);
        if (vi != m_currentViewSegment->getViewElementList()->end()) {
            element = static_cast<MatrixElement *>(*vi);
        }
        if (!element) continue;

        timeT t = element->getViewAbsoluteTime();
        timeT d = element->getViewDuration();
        
        d = d + durationDiff;
        if (d < 0) {
            t = t + d;
            d = -d;
        } else if (d == 0) {
            d = getSnapGrid()->getSnapTime(t);
        }

        element->reconfigure(t, d);
//            m_currentStaff->positionElement(element);
//        }
    }

//    m_mParentView->canvas()->update();
    return FollowHorizontal;
}
Beispiel #2
0
void
MatrixSelector::setContextHelpFor(const MatrixMouseEvent *e, bool ctrlPressed)
{
    QSettings settings;
    settings.beginGroup( GeneralOptionsConfigGroup );

    if (! qStrToBool( settings.value("toolcontexthelp", "true" ) ) ) {
        settings.endGroup();
        return;
    }
    settings.endGroup();

    MatrixElement *element = e->element;

    if (!element) {
        
        setContextHelp
            (tr("Click and drag to select; middle-click and drag to draw new note"));

    } else {
        
        // same logic as in handleLeftButtonPress
        
        float x = element->getLayoutX();
        float width = element->getWidth();
        float resizeStart = int(double(width) * 0.85) + x;

        // max size of 10
        if ((x + width) - resizeStart > 10) resizeStart = x + width - 10;

        EventSelection *s = m_scene->getSelection();

        if (e->sceneX > resizeStart) {
            if (s && s->getAddedEvents() > 1) {
                setContextHelp(tr("Click and drag to resize selected notes"));
            } else {
                setContextHelp(tr("Click and drag to resize note"));
            }
        } else {
            if (s && s->getAddedEvents() > 1) {
                if (!ctrlPressed) {
                    setContextHelp(tr("Click and drag to move selected notes; hold Ctrl as well to copy"));
                } else {
                    setContextHelp(tr("Click and drag to copy selected notes"));
                }
            } else {
                if (!ctrlPressed) {
                    setContextHelp(tr("Click and drag to move note; hold Ctrl as well to copy"));
                } else {
                    setContextHelp(tr("Click and drag to copy note"));
                }
            }                
        }
    }
}
Beispiel #3
0
bool
MatrixSelector::getSelection(EventSelection *&selection)
{
    if (!m_selectionRect || !m_selectionRect->isVisible()) return 0;

    Segment& originalSegment = m_currentViewSegment->getSegment();
    selection = new EventSelection(originalSegment);

    // get the selections
    //
    QList<QGraphicsItem *> l = m_selectionRect->collidingItems
        (Qt::IntersectsItemShape);

    // This is a nasty optimisation, just to avoid re-creating the
    // selection if the items we span are unchanged.  It's not very
    // effective, either, because the colliding items returned
    // includes things like the horizontal and vertical background
    // lines -- and so it changes often: every time we cross a line.
    // More thought needed.

    // It might be better to use the event properties (i.e. time and
    // pitch) to calculate this "from first principles" rather than
    // doing it graphically.  That might also be helpful to avoid us
    // dragging off the logical edges of the scene.

    // (Come to think of it, though, that would be troublesome just
    // because of the requirement to use all events that have any part
    // inside the selection.  Quickly finding all events that start
    // within a time range is trivial, finding all events that
    // intersect one is more of a pain.)
    if (l == m_previousCollisions) return false;
    m_previousCollisions = l;

    if (!l.empty()) {
        for (int i = 0; i < l.size(); ++i) {
            QGraphicsItem *item = l[i];
            MatrixElement *element = MatrixElement::getMatrixElement(item);
            if (element) {
                //!!! NB. In principle, this element might not come
                //!!! from the right segment (in practice we only have
                //!!! one segment, but that may change)
                selection->addEvent(element->event());
            }
        }
    }

    if (selection->getAddedEvents() == 0) {
        delete selection;
        selection = 0;
    }

    return true;
}
void
MatrixViewSegment::updateElements(timeT from, timeT to)
{
    if (!m_viewElementList) return;
    ViewElementList::iterator i = m_viewElementList->findTime(from);
    ViewElementList::iterator j = m_viewElementList->findTime(to);
    while (i != m_viewElementList->end()) {
        MatrixElement *e = static_cast<MatrixElement *>(*i);
        e->reconfigure();
        if (i == j) break;
        ++i;
    }
}
Beispiel #5
0
MatrixTool::FollowMode
MatrixMover::handleMouseMove(const MatrixMouseEvent *e)
{
    if (!e) return NoFollow;

    MATRIX_DEBUG << "MatrixMover::handleMouseMove() snapped time = "
                 << e->snappedLeftTime << endl;

    setBasicContextHelp(e->modifiers & Qt::ControlModifier);

    if (!m_currentElement || !m_currentViewSegment) return NoFollow;

    if (getSnapGrid()->getSnapSetting() != SnapGrid::NoSnap) {
        setContextHelp(tr("Hold Shift to avoid snapping to beat grid"));
    } else {
        clearContextHelp();
    }

    timeT newTime = m_currentElement->getViewAbsoluteTime() +
        (e->snappedLeftTime - m_clickSnappedLeftTime);
    int newPitch = e->pitch;

    emit hoveredOverNoteChanged(newPitch, true, newTime);

    // get a basic pitch difference calculation comparing the current element's
    // pitch to the clicked pitch (this does not take the transpose factor into
    // account, so in a -9 segment, the initial result winds up being 9
    // semitones too low)
    using BaseProperties::PITCH;
    int diffPitch = 0;
    if (m_currentElement->event()->has(PITCH)) {
        diffPitch = newPitch - m_currentElement->event()->get<Int>(PITCH);
    }
    
    EventSelection* selection = m_scene->getSelection();

    // factor in transpose to adjust the height calculation
    long pitchOffset = selection->getSegment().getTranspose();
    diffPitch += (pitchOffset * -1);

    for (EventSelection::eventcontainer::iterator it =
             selection->getSegmentEvents().begin();
         it != selection->getSegmentEvents().end(); ++it) {

        MatrixElement *element = 0;
        ViewElementList::iterator vi = m_currentViewSegment->findEvent(*it);
        if (vi != m_currentViewSegment->getViewElementList()->end()) {
            element = static_cast<MatrixElement *>(*vi);
        }
        if (!element) continue;

        timeT diffTime = element->getViewAbsoluteTime() -
            m_currentElement->getViewAbsoluteTime();

        int epitch = 0;
        if (element->event()->has(PITCH)) {
            epitch = element->event()->get<Int>(PITCH);
        }

        element->reconfigure(newTime + diffTime,
                             element->getViewDuration(),
                             epitch + diffPitch);
                             
        element->setSelected(true);
            
    }

    if (newPitch != m_lastPlayedPitch) {
        long velocity = m_widget->getCurrentVelocity();
        m_currentElement->event()->get<Int>(BaseProperties::VELOCITY, velocity);
        m_scene->playNote(m_currentViewSegment->getSegment(), newPitch + (pitchOffset * -1), velocity);
        m_lastPlayedPitch = newPitch;
    }

    return FollowMode(FollowHorizontal | FollowVertical);
}
Beispiel #6
0
void
MatrixSelector::handleMouseDoubleClick(const MatrixMouseEvent *e)
{
    // Don't use m_clickedElement here, as it's reset to 0 on mouse
    // release, which occurs before our dialog completes (and we need
    // to know the element after that)
    MatrixElement *element = e->element;

    MatrixViewSegment *vs = e->viewSegment;
    if (!vs) return;

    if (element) {

        if (element->event()->isa(Note::EventType) &&
            element->event()->has(BaseProperties::TRIGGER_SEGMENT_ID)) {

            int id = element->event()->get<Int>(BaseProperties::TRIGGER_SEGMENT_ID);
            emit editTriggerSegment(id);
            return;
        }

        if (e->modifiers & Qt::ShiftModifier) { // advanced edit

            EventEditDialog dialog(m_widget, *element->event(), true);

            if (dialog.exec() == QDialog::Accepted &&
                dialog.isModified()) {

                EventEditCommand *command = new EventEditCommand
                    (vs->getSegment(), element->event(),
                     dialog.getEvent());

                CommandHistory::getInstance()->addCommand(command);
            }

        } else {

            SimpleEventEditDialog dialog
                (m_widget, m_scene->getDocument(), *element->event(), false);

            if (dialog.exec() == QDialog::Accepted &&
                dialog.isModified()) {

                EventEditCommand *command = new EventEditCommand
                    (vs->getSegment(), element->event(), dialog.getEvent());

                CommandHistory::getInstance()->addCommand(command);
            }
        }

    } /*
    	  
          #988167: Matrix:Multiclick select methods don't work in matrix editor
          Postponing this, as it falls foul of world-matrix transformation
          etiquette and other such niceties
     
    	  else {
     
    	QRect rect = staff->getBarExtents(ev->x(), ev->y());
     
    	m_selectionRect->setX(rect.x() + 2);
    	m_selectionRect->setY(rect.y());
    	m_selectionRect->setSize(rect.width() - 4, rect.height());
     
    	m_selectionRect->show();
    	m_updateRect = false;
    	
    	m_justSelectedBar = true;
    	QTimer::singleShot(QApplication::doubleClickInterval(), this,
    			   SLOT(slotClickTimeout()));
        } */
}