Exemplo n.º 1
0
void
SegmentTool::mousePressEvent(QMouseEvent *e)
{
    // We only care about the right button.
    if (e->button() != Qt::RightButton)
        return;

    if (m_changingSegment) // mouse button is pressed for some tool
        return ;

    // No need to propagate.
    e->accept();

    QPoint pos = m_canvas->viewportToContents(e->pos());

    setChangingSegment(m_canvas->getModel()->getSegmentAt(pos));

    if (m_changingSegment) {
        if (!m_canvas->getModel()->isSelected(m_changingSegment->getSegment())) {

            m_canvas->getModel()->clearSelected();
            m_canvas->getModel()->setSelected(m_changingSegment->getSegment());
            m_canvas->getModel()->selectionHasChanged();
        }
    }

    showMenu();

    setChangingSegment(ChangingSegmentPtr());
}
Exemplo n.º 2
0
void SegmentEraser::mousePressEvent(QMouseEvent *e)
{
    // Let the baseclass have a go.
    SegmentTool::mousePressEvent(e);

    // We only care about the left mouse button.
    if (e->button() != Qt::LeftButton)
        return;

    // No need to propagate.
    e->accept();

    QPoint pos = m_canvas->viewportToContents(e->pos());

    // Save the Segment for the mouse release event.
    setChangingSegment(m_canvas->getModel()->getSegmentAt(pos));
}
Exemplo n.º 3
0
void SegmentEraser::mouseReleaseEvent(QMouseEvent *e)
{
    // We only care about the left mouse button.
    if (e->button() != Qt::LeftButton)
        return;

    // No need to propagate.
    e->accept();

    // If a Segment was selected by the press event
    if (getChangingSegment()) {
        // Erase it
        CommandHistory::getInstance()->addCommand(
                new SegmentEraseCommand(getChangingSegment()->getSegment()));
    }

    // Clear the current Segment.
    setChangingSegment(ChangingSegmentPtr());
}
Exemplo n.º 4
0
void SegmentMover::mousePressEvent(QMouseEvent *e)
{
    // Let the baseclass have a go.
    SegmentTool::mousePressEvent(e);

    // We only care about the left mouse button.
    if (e->button() != Qt::LeftButton)
        return;

    // No need to propagate.
    e->accept();

    QPoint pos = m_canvas->viewportToContents(e->pos());

    CompositionModelImpl *model = m_canvas->getModel();

    // Get the Segment that was clicked.
    ChangingSegmentPtr changingSegment = model->getSegmentAt(pos);

    // If the segment canvas background was clicked, clear the selection.
    if (!changingSegment) {
        model->clearSelected();
        model->selectionHasChanged();
        m_canvas->update();
        return;
    }

    // The original segment in the composition.
    Segment *segment = changingSegment->getSegment();

    // If we're clicking on a segment that isn't in the selection
    if (!model->isSelected(segment)) {

        // Clear the selection.
        model->clearSelected();
        model->selectionHasChanged();
    }

    setChangingSegment(changingSegment);
    m_clickPoint = pos;

    setSnapTime(e, SnapGrid::SnapToBeat);

    int x = int(m_canvas->grid().getRulerScale()->getXForTime(
                    segment->getStartTime()));
    int y = m_canvas->grid().getYBinCoordinate(segment->getTrack());

    m_canvas->drawGuides(x, y);

    // If some segments are already selected
    if (model->haveSelection()) {

        // Start the move on all selected segments
        model->startChangeSelection(CompositionModelImpl::ChangeMove);

        // Find the clicked segment in the model.
        ChangingSegmentPtr newChangingSegment =
                model->findChangingSegment(segment);

        if (newChangingSegment) {
            // Toss the local "changing" segment since it isn't going to
            // be moving at all.  Swap it for the same changing segment in
            // the model.  That one *will* be moving and can be used to
            // drive the guides.
            setChangingSegment(newChangingSegment);
        }

    } else {  // Nothing selected, just move the one that was clicked
        model->startChange(changingSegment, CompositionModelImpl::ChangeMove);
    }

    m_canvas->update();
}
Exemplo n.º 5
0
void SegmentMover::mouseReleaseEvent(QMouseEvent *e)
{
    // We only care about the left mouse button.
    if (e->button() != Qt::LeftButton)
        return;

    // No need to propagate.
    e->accept();

    // If we weren't moving anything, bail.
    if (!getChangingSegment())
        return;

    if (m_changeMade) {

        QPoint pos = m_canvas->viewportToContents(e->pos());

        // Compute how far we've moved vertically.
        const int startTrackPos = m_canvas->grid().getYBin(m_clickPoint.y());
        const int currentTrackPos = m_canvas->grid().getYBin(pos.y());
        const int deltaTrack = currentTrackPos - startTrackPos;

        CompositionModelImpl::ChangingSegmentSet &changingSegments =
                m_canvas->getModel()->getChangingSegments();

        Composition &comp = m_doc->getComposition();

        SegmentReconfigureCommand *command =
            new SegmentReconfigureCommand(
                    changingSegments.size() == 1 ?
                            tr("Move Segment") :
                            tr("Move Segments"),
                    &comp);

        // For each changing segment
        for (CompositionModelImpl::ChangingSegmentSet::iterator it =
                 changingSegments.begin();
             it != changingSegments.end();
             ++it) {

            ChangingSegmentPtr changingSegment = *it;

            // The original Segment in the Composition.
            Segment *segment = changingSegment->getSegment();

            // New Track ID

            TrackId origTrackId = segment->getTrack();
            int trackPos = comp.getTrackPositionById(origTrackId) + deltaTrack;

            if (trackPos < 0) {
                trackPos = 0;
            } else if (trackPos >= (int)comp.getNbTracks()) {
                trackPos = comp.getNbTracks() - 1;
            }

            Track *newTrack = comp.getTrackByPosition(trackPos);

            int newTrackId = origTrackId;
            if (newTrack)
                newTrackId = newTrack->getId();

            // New start time

            timeT newStartTime = changingSegment->getStartTime(m_canvas->grid());

            // New end time

            // We absolutely don't want to snap the end time
            // to the grid.  We want it to remain exactly the same
            // as it was, but relative to the new start time.
            timeT newEndTime = newStartTime +
                    segment->getEndMarkerTime(false) - segment->getStartTime();

            // Add the changed segment to the command

            command->addSegment(segment,
                                newStartTime,
                                newEndTime,
                                newTrackId);
        }

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

        m_changeMade = false;
    }

    m_canvas->hideTextFloat();
    m_canvas->hideGuides();
    m_canvas->getModel()->endChange();
    m_canvas->slotUpdateAll();

    setChangingSegment(ChangingSegmentPtr());

    setBasicContextHelp();
}
Exemplo n.º 6
0
void
SegmentSelector::mousePressEvent(QMouseEvent *e)
{
    // Let the baseclass have a go.
    SegmentTool::mousePressEvent(e);

    // We only care about the left and middle mouse buttons.
    if (e->button() != Qt::LeftButton  &&
        e->button() != Qt::MidButton)
        return;

    // No need to propagate.
    e->accept();

    QPoint pos = m_canvas->viewportToContents(e->pos());

    // Get the segment that was clicked.
    ChangingSegmentPtr item = m_canvas->getModel()->getSegmentAt(pos);

    // If middle button...
    if (e->button() == Qt::MidButton) {
        // If clicked on the background, create a new segment.
        if (!item) {
            m_dispatchTool = m_canvas->getToolBox()->getTool(SegmentPencil::ToolName());

            if (m_dispatchTool) {
                m_dispatchTool->ready(); // set mouse cursor
                m_dispatchTool->mousePressEvent(e);
            }
        }

        return;
    }

    // Left button was pressed.
    // ??? Should we split this into a midPress(e) and a leftPress(e)?
    //     Might improve readability a little.

    // *** Adjust Selection

    // Shift key adds to selection.
    m_segmentAddMode = ((e->modifiers() & Qt::ShiftModifier) != 0);

    // if a segment was clicked
    if (item) {
        bool selected = m_canvas->getModel()->isSelected(item->getSegment());
        if (m_segmentAddMode) {
            // toggle item selection
            m_canvas->getModel()->setSelected(item->getSegment(), !selected);
        } else {
            if (!selected) {
                // make the item the selection
                m_canvas->getModel()->clearSelected();
                m_canvas->getModel()->setSelected(item->getSegment());
            }
        }
    } else {  // the background was clicked
        if (!m_segmentAddMode) {
            // clear the selection
            m_canvas->getModel()->clearSelected();
        }
    }

    // *** Perform Functions

    bool ctrl = ((e->modifiers() & Qt::ControlModifier) != 0);

    // if a segment was clicked
    if (item) {

        // * Resize

        // if only one segment is selected and clicked near the edge, resize
        if (m_canvas->getModel()->getSelectedSegments().size() == 1  &&
            isNearEdge(item->rect(), pos)) {

            SegmentResizer *segmentResizer = dynamic_cast<SegmentResizer *>(
                m_canvas->getToolBox()->getTool(SegmentResizer::ToolName()));

            // Turn it over to SegmentResizer.
            m_dispatchTool = segmentResizer;
            m_dispatchTool->ready(); // set mouse cursor
            m_dispatchTool->mousePressEvent(e);

            return;
        }

        // * Move

        // We don't dispatch to SegmentMover because SegmentMover
        // doesn't support copying/linking.

        bool alt = ((e->modifiers() & Qt::AltModifier) != 0);

        // Ctrl and Alt+Ctrl are segment copy.
        m_segmentCopyMode = ctrl;
        // Alt+Ctrl is copy as link.
        m_segmentCopyingAsLink = (alt && ctrl);

        // If the segment is selected, put it in move mode.
        if (m_canvas->getModel()->isSelected(item->getSegment())) {
            m_canvas->getModel()->startChange(
                    item, CompositionModelImpl::ChangeMove);
        }

        setChangingSegment(item);

        m_clickPoint = pos;

        int guideX = item->rect().x();
        int guideY = item->rect().y();

        m_canvas->drawGuides(guideX, guideY);

        setSnapTime(e, SnapGrid::SnapToBeat);

    } else {  // the background was clicked
        if (ctrl) {

            // * Create Segment

            m_dispatchTool = m_canvas->getToolBox()->getTool(
                    SegmentPencil::ToolName());

            if (m_dispatchTool) {
                m_dispatchTool->ready(); // set mouse cursor
                m_dispatchTool->mousePressEvent(e);
            }

            return;
        }

        // * Rubber Band

        m_canvas->drawSelectionRectPos1(pos);

    }

    // Make sure the Segment Parameters box is updated.  See
    // RosegardenMainViewWidget::slotSelectedSegments().
    m_canvas->getModel()->selectionHasChanged();

    m_passedInertiaEdge = false;
}
Exemplo n.º 7
0
int
SegmentSelector::mouseMoveEvent(QMouseEvent *e)
{
    // No need to propagate.
    e->accept();

    QPoint pos = m_canvas->viewportToContents(e->pos());
    m_lastMousePos = pos;

    // If no buttons are pressed, update the context help and bail.
    // Note: Mouse tracking must be on for this to work.  See
    //       QWidget::setMouseTracking().
    if (e->buttons() == Qt::NoButton) {
        setContextHelpFor(pos, e->modifiers());
        return RosegardenScrollView::NoFollow;
    }

    // If another tool has taken over, delegate.
    if (m_dispatchTool)
        return m_dispatchTool->mouseMoveEvent(e);

    // We only handle the left button.  The middle button is handled by
    // the dispatch tool (segment pencil) or ignored.
    if (e->buttons() != Qt::LeftButton)
        return RosegardenScrollView::NoFollow;

    // If we aren't moving anything, rubber band.
    if (!getChangingSegment()) {
        m_canvas->drawSelectionRectPos2(pos);
        m_canvas->getModel()->selectionHasChanged();

        return RosegardenScrollView::FollowHorizontal |
               RosegardenScrollView::FollowVertical;
    }

    // Moving

    // If the segment that was clicked on isn't selected, bail.
    if (!m_canvas->getModel()->isSelected(getChangingSegment()->getSegment()))
        return RosegardenScrollView::NoFollow;

    const int dx = pos.x() - m_clickPoint.x();
    const int dy = pos.y() - m_clickPoint.y();
    const int inertiaDistance = 8;

    // If we've not already exceeded the inertia distance, and we
    // still haven't, bail.
    if (!m_passedInertiaEdge  &&
        abs(dx) < inertiaDistance  &&
        abs(dy) < inertiaDistance) {
        return RosegardenScrollView::NoFollow;
    }

    m_passedInertiaEdge = true;

    m_canvas->viewport()->setCursor(Qt::SizeAllCursor);

#if 0
// ??? Moving to mouseReleaseEvent().
    if (m_segmentCopyMode  &&  !m_segmentQuickCopyDone) {
        // Make copies of the original Segment(s).  These copies will
        // take the place of the originals as the user drags the
        // the originals to a new location.

        MacroCommand *macroCommand = 0;
        
        if (m_segmentCopyingAsLink) {
            macroCommand = new MacroCommand(
                    SegmentQuickLinkCommand::getGlobalName());
        } else {
            macroCommand = new MacroCommand(
                    SegmentQuickCopyCommand::getGlobalName());
        }

        SegmentSelection selectedItems = m_canvas->getSelectedSegments();

        // for each selected segment
        for (SegmentSelection::iterator it = selectedItems.begin();
             it != selectedItems.end();
             ++it) {
            Segment *segment = *it;

            Command *command = 0;

            if (m_segmentCopyingAsLink) {
                command = new SegmentQuickLinkCommand(segment);
            } else {
                // if it's a link, copy as link
                if (segment->isTrulyLinked())
                    command = new SegmentQuickLinkCommand(segment);
                else  // copy as a non-link segment
                    command = new SegmentQuickCopyCommand(segment);
            }

            macroCommand->addCommand(command);
        }

        CommandHistory::getInstance()->addCommand(macroCommand);

        m_canvas->update();

        // Make sure we don't do it again.
        m_segmentQuickCopyDone = true;
    }
#endif

    setSnapTime(e, SnapGrid::SnapToBeat);

    // start move on selected items only once
    if (!m_selectionMoveStarted) {
        m_selectionMoveStarted = true;

        m_canvas->getModel()->startChangeSelection(
                m_segmentCopyMode ? CompositionModelImpl::ChangeCopy :
                                    CompositionModelImpl::ChangeMove);

        // The call to startChangeSelection() generates a new changing segment.
        // Get it.
        ChangingSegmentPtr newChangingSegment =
                m_canvas->getModel()->findChangingSegment(
                          getChangingSegment()->getSegment());

        if (newChangingSegment) {
            // Toss the local "changing" segment since it isn't going to
            // be moving at all.  Swap it for the same changing segment in
            // CompositionModelImpl.  That one *will* be moving and can be
            // used to drive the guides.
            setChangingSegment(newChangingSegment);
        }
    }

    // Display help for the Shift key.
    setContextHelpFor(pos, e->modifiers());

    Composition &comp = m_doc->getComposition();

    const int startDragTrackPos = m_canvas->grid().getYBin(m_clickPoint.y());
    const int currentTrackPos = m_canvas->grid().getYBin(pos.y());
    const int trackDiff = currentTrackPos - startDragTrackPos;

    CompositionModelImpl::ChangingSegmentSet &changingSegments =
            m_canvas->getModel()->getChangingSegments();

    // For each changing segment
    for (CompositionModelImpl::ChangingSegmentSet::iterator it =
                 changingSegments.begin();
         it != changingSegments.end();
         ++it) {
        ChangingSegmentPtr changingSegment = *it;

        const timeT newStartTime = m_canvas->grid().snapX(
                changingSegment->savedRect().x() + dx);

        const int newX = lround(
                m_canvas->grid().getRulerScale()->getXForTime(newStartTime));

        int newTrackPos = m_canvas->grid().getYBin(
                changingSegment->savedRect().y()) + trackDiff;

        // Limit to [0, comp.getNbTracks()-1].
        if (newTrackPos < 0)
            newTrackPos = 0;
        if (newTrackPos > static_cast<int>(comp.getNbTracks()) - 1)
            newTrackPos = comp.getNbTracks() - 1;

        const int newY = m_canvas->grid().getYBinCoordinate(newTrackPos);

        changingSegment->moveTo(newX, newY);
        m_changeMade = true;
    }

    if (m_changeMade) {
        // Make sure the segments are redrawn.
        // Note: The update() call below doesn't cause the segments to be
        //       redrawn.  It just updates from the cache.
        m_canvas->slotUpdateAll();
    }

    // Guides

    const int guideX = getChangingSegment()->rect().x();
    const int guideY = getChangingSegment()->rect().y();

    m_canvas->drawGuides(guideX, guideY);

    // Text Float

    const timeT guideTime = m_canvas->grid().snapX(guideX);

    RealTime time = comp.getElapsedRealTime(guideTime);
    QString msecs;
    msecs.sprintf("%03d", time.msec());

    int bar;
    int beat;
    int fraction;
    int remainder;
    comp.getMusicalTimeForAbsoluteTime(guideTime, bar, beat, fraction, remainder);

    QString posString = QString("%1.%2s (%3, %4, %5)").
            arg(time.sec).arg(msecs).arg(bar + 1).arg(beat).arg(fraction);

    m_canvas->drawTextFloat(guideX + 10, guideY - 30, posString);

    m_canvas->update();

    return RosegardenScrollView::FollowHorizontal |
           RosegardenScrollView::FollowVertical;
}
Exemplo n.º 8
0
void
SegmentSelector::mouseReleaseEvent(QMouseEvent *e)
{
    // We only care about the left and middle mouse buttons.
    if (e->button() != Qt::LeftButton  &&
        e->button() != Qt::MidButton)
        return;

    // No need to propagate.
    e->accept();

    QPoint pos = m_canvas->viewportToContents(e->pos());

    // If another tool (SegmentPencil or SegmentResizer) has taken
    // over, delegate.
    if (m_dispatchTool) {
        m_dispatchTool->mouseReleaseEvent(e);
        m_dispatchTool->stow();

        // Forget about the tool.
        // Note that this is not a memory leak.  There is only one instance
        // of each tool stored in BaseToolBox::m_tools.
        m_dispatchTool = 0;

        // Back to this tool.
        ready();

        return;
    }

    // We only handle the left button.  The middle button is handled by
    // the dispatch tool (segment pencil) or ignored.
    if (e->button() != Qt::LeftButton)
        return;

    // The left button has been released.

    m_canvas->hideGuides();
    m_canvas->hideTextFloat();

    // If rubber band mode
    if (!getChangingSegment()) {
        m_canvas->hideSelectionRect();
        m_canvas->getModel()->finalizeSelectionRect();
        m_canvas->getModel()->selectionHasChanged();
        return;
    }

    m_canvas->viewport()->setCursor(Qt::ArrowCursor);

    if (m_canvas->getModel()->isSelected(getChangingSegment()->getSegment())) {

        if (m_changeMade) {

            MacroCommand *macroCommand = 0;

            CompositionModelImpl::ChangingSegmentSet &changingSegments =
                    m_canvas->getModel()->getChangingSegments();

            if (m_segmentCopyMode) {
                if (m_segmentCopyingAsLink) {
                    macroCommand = new MacroCommand(
                            tr("Copy %n Segment(s) as link(s)", "", changingSegments.size()));
                } else {
                    macroCommand = new MacroCommand(
                            tr("Copy %n Segment(s)", "", changingSegments.size()));
                }
            } else {
                macroCommand = new MacroCommand(
                        tr("Move %n Segment(s)", "", changingSegments.size()));
            }

            if (m_segmentCopyMode) {
                // Make copies of the original Segment(s).  These copies will
                // take the place of the originals.

                SegmentSelection selectedItems = m_canvas->getSelectedSegments();

                // for each selected segment
                for (SegmentSelection::iterator it = selectedItems.begin();
                     it != selectedItems.end();
                     ++it) {
                    Segment *segment = *it;

                    Command *command = 0;

                    if (m_segmentCopyingAsLink) {
                        command = new SegmentQuickLinkCommand(segment);
                    } else {
                        // if it's a link, copy as link
                        if (segment->isTrulyLinked())
                            command = new SegmentQuickLinkCommand(segment);
                        else  // copy as a non-link segment
                            command = new SegmentQuickCopyCommand(segment);
                    }

                    macroCommand->addCommand(command);
                }
            }

            const int startDragTrackPos =
                    m_canvas->grid().getYBin(m_clickPoint.y());
            const int currentTrackPos = m_canvas->grid().getYBin(pos.y());
            const int trackDiff = currentTrackPos - startDragTrackPos;

            Composition &comp = m_doc->getComposition();

            SegmentReconfigureCommand *segmentReconfigureCommand =
                    new SegmentReconfigureCommand("", &comp);

            // For each changing segment, add the segment to the
            // SegmentReconfigureCommand.
            for (CompositionModelImpl::ChangingSegmentSet::iterator it =
                         changingSegments.begin();
                 it != changingSegments.end();
                 ++it) {
                ChangingSegmentPtr changingSegment = *it;
                Segment *segment = changingSegment->getSegment();

                TrackId origTrackId = segment->getTrack();
                int newTrackPos =
                        comp.getTrackPositionById(origTrackId) + trackDiff;

                // Limit to [0, comp.getNbTracks()-1]
                if (newTrackPos < 0)
                    newTrackPos = 0;
                if (newTrackPos > static_cast<int>(comp.getNbTracks()) - 1)
                    newTrackPos = comp.getNbTracks() - 1;

                Track *newTrack = comp.getTrackByPosition(newTrackPos);
                int newTrackId = origTrackId;
                if (newTrack)
                    newTrackId = newTrack->getId();

                timeT startTime =
                        changingSegment->getStartTime(m_canvas->grid());

                // endTime = startTime + segment duration
                // We absolutely don't want to snap the end time to
                // the grid.  We want it to remain exactly the same as
                // it was, but relative to the new start time.
                timeT endTime = startTime +
                        segment->getEndMarkerTime(false) -
                        segment->getStartTime();

                segmentReconfigureCommand->addSegment(
                        segment, startTime, endTime, newTrackId);
            }

            macroCommand->addCommand(segmentReconfigureCommand);

            CommandHistory::getInstance()->addCommand(macroCommand);

            m_canvas->update();
        }

        m_canvas->getModel()->endChange();
        m_canvas->slotUpdateAll();
    }

    // Get ready for the next button press.
    m_segmentQuickCopyDone = false;
    m_changeMade = false;
    m_selectionMoveStarted = false;
    setChangingSegment(ChangingSegmentPtr());

    setContextHelpFor(pos);
}