예제 #1
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();
}
예제 #2
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;
}
예제 #3
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();
}
예제 #4
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);
}