ControlItem* ControllerEventsRuler::addControlItem(Event *event)
{
    EventControlItem *controlItem = new EventControlItem(this, new ControllerEventAdapter(event), QPolygonF());
    controlItem->updateFromEvent();

    ControlRuler::addControlItem(controlItem);
    return controlItem;
}
ControlItem* ControllerEventsRuler::addControlItem(float x, float y)
{
    // Adds a ControlItem in the absence of an event (used by ControlPainter)
    clearSelectedItems();
    EventControlItem *item = new EventControlItem(this, new ControllerEventAdapter(0), QPolygonF());
    item->reconfigure(x,y);
    item->setSelected(true);
//    m_selectedItems.push_back(item);
//    if (isVisible(item)) {
//        m_visibleItems.push_back(item);
//    }
    ControlRuler::addControlItem(item);
    
    return item;
}
Example #3
0
ControlTool::FollowMode
ControlMover::handleMouseMove(const ControlMouseEvent *e)
{
    if (e->buttons == Qt::NoButton) {
        // No button pressed, set cursor style
        setCursor(e);
    }

    if ((e->buttons & Qt::LeftButton) && m_overItem) {
        // A drag action is in progress        
        float deltaX = (e->x-m_mouseStartX);
        float deltaY = (e->y-m_mouseStartY);

        double xscale = m_ruler->getXScale();
        double yscale = m_ruler->getYScale();
        float dScreenX = deltaX / xscale;
        float dScreenY = deltaY / yscale;

        if (e->modifiers & Qt::ControlModifier) {
            // If the control key is held down, restrict movement to either horizontal or vertical
            //    depending on the direction the item has been moved
            
            // For small displacements from the starting position, use the direction of this movement
            //    rather than the actual displacement - makes dragging through the original position
            //    less likely to switch constraint axis
            if ((fabs(dScreenX) < CONTROL_SMALL_DISTANCE) && (fabs(dScreenY) < CONTROL_SMALL_DISTANCE)) {
                dScreenX = dScreenX-m_lastDScreenX;
                dScreenY = dScreenY-m_lastDScreenY;
            }
        
            if (fabs(dScreenX) > fabs(dScreenY)) {
                deltaY = 0;
            } else {
                deltaX = 0;
            }
        }
        
        m_lastDScreenX = dScreenX;
        m_lastDScreenY = dScreenY;
        
        EventControlItem *item;
        ControlItemList *selected = m_ruler->getSelectedItems();
        std::vector<QPointF>::iterator pIt = m_startPointList.begin();
        for (ControlItemList::iterator it = selected->begin(); it != selected->end(); ++it) {
            item = dynamic_cast <EventControlItem*> (*it);

            float x = pIt->x()+deltaX;
            float xmin = m_ruler->getXMin() * xscale;
            float xmax = (m_ruler->getXMax() - 1) * xscale;
            x = std::max(x,xmin);
            x = std::min(x,xmax);

            float y = pIt->y()+deltaY;
            y = std::max(y,0.0f);
            y = std::min(y,1.0f);
            if (item) item->reconfigure(x,y);
            ++pIt;
        }
        return FollowHorizontal;
    }

    m_ruler->update();
    
    return NoFollow;
}
void ControllerEventsRuler::paintEvent(QPaintEvent *event)
{
    ControlRuler::paintEvent(event);

    // If this is the first time we've drawn this view,
    //  reconfigure all items to make sure their icons
    //  come out the right size
    ///@TODO Only reconfigure all items if zoom has changed
    if (m_lastDrawnRect != m_pannedRect) {
        EventControlItem *item;
        for (ControlItemMap::iterator it = m_controlItemMap.begin(); it != m_controlItemMap.end(); ++it) {
            item = static_cast <EventControlItem *> (it->second);
            item->reconfigure();
        }
        m_lastDrawnRect = m_pannedRect;
    }

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    QBrush brush(GUIPalette::getColour(GUIPalette::ControlItem),Qt::SolidPattern);

//    QPen highlightPen(GUIPalette::getColour(GUIPalette::SelectedElement),
//            2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin);
    QPen pen(GUIPalette::getColour(GUIPalette::MatrixElementBorder),
            0.5, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin);

    painter.setBrush(brush);
    painter.setPen(pen);

    QString str;
//    str = QString::fromStdString(m_controller->getName());
//    painter.drawText(10,20,str.toUpper());
    
    ControlItemMap::iterator mapIt;
    float lastX, lastY;
    lastX = m_rulerScale->getXForTime(m_segment->getStartTime());

    if (m_nextItemLeft != m_controlItemMap.end()) {
        EventControlItem *item = static_cast<EventControlItem*> (m_nextItemLeft->second);
        lastY = item->y();
    } else {
        lastY = valueToY(m_controller->getDefault());
    }
    
    mapIt = m_firstVisibleItem;
    while (mapIt != m_controlItemMap.end()) {
        EventControlItem *item = static_cast<EventControlItem*> (mapIt->second);
        painter.drawLine(mapXToWidget(lastX),mapYToWidget(lastY),
                mapXToWidget(item->xStart()),mapYToWidget(lastY));
        painter.drawLine(mapXToWidget(item->xStart()),mapYToWidget(lastY),
                mapXToWidget(item->xStart()),mapYToWidget(item->y()));
        lastX = item->xStart();
        lastY = item->y();
        if (mapIt == m_lastVisibleItem) {
            mapIt = m_controlItemMap.end();
        } else {
            ++mapIt;
        }
    }
    
    painter.drawLine(mapXToWidget(lastX),mapYToWidget(lastY),
            mapXToWidget(m_rulerScale->getXForTime(m_segment->getEndTime())*m_xScale),
            mapYToWidget(lastY));
    
    // Use a fast vector list to record selected items that are currently visible so that they
    //  can be drawn last - can't use m_selectedItems as this covers all selected, visible or not
    std::vector<ControlItem*> selectedvector;

    for (ControlItemList::iterator it = m_visibleItems.begin(); it != m_visibleItems.end(); ++it) {
        if (!(*it)->isSelected()) {
            painter.drawPolygon(mapItemToWidget(*it));
        } else {
            selectedvector.push_back(*it);
        }
    }

//    painter.setBrush(brush);
    pen.setColor(GUIPalette::getColour(GUIPalette::SelectedElement));
    pen.setWidthF(2.0);
    painter.setPen(pen);
    QFontMetrics fontMetrics(painter.font());
    int fontHeight = fontMetrics.height();
    int fontOffset = fontMetrics.width('+');
    
    for (std::vector<ControlItem*>::iterator it = selectedvector.begin(); it != selectedvector.end(); ++it)
    {
        // Draw the marker
        painter.drawPolygon(mapItemToWidget(*it));

        // For selected items, draw the value in text alongside the marker
        // By preference, this should sit on top of the new line that represents this value change
        str = QString::number(yToValue((*it)->y())-m_controller->getDefault());
        int x = mapXToWidget((*it)->xStart())+0.4*fontOffset;
        int y = std::max(mapYToWidget((*it)->y())-0.2f*fontHeight,float(fontHeight));
        
        painter.setPen(QPen(Qt::NoPen));
        painter.setBrush(QBrush(Qt::white));
        painter.drawRect(QRect(x,y+2,fontMetrics.width(str),-(fontMetrics.height()-2)));
        painter.setPen(pen);
        painter.setBrush(brush);
        painter.drawText(x,y,str);
    }

    if (m_selectionRect) {
        pen.setColor(GUIPalette::getColour(GUIPalette::MatrixElementBorder));
        pen.setWidthF(0.5);
        painter.setPen(pen);
        brush.setStyle(Qt::NoBrush);
        painter.setBrush(brush);
        painter.drawRect(mapItemToWidget(m_selectionRect));
    }

    // draw the rubber band indicating where a line of controllers will go
    if (m_rubberBand && m_rubberBandVisible) {
        int x1 = mapXToWidget(m_rubberBand->x1());
        int y1 = mapYToWidget(m_rubberBand->y1());
        int x2 = mapXToWidget(m_rubberBand->x2());
        int y2 = mapYToWidget(m_rubberBand->y2());
        painter.setPen(Qt::red);
        painter.drawLine(x1, y1, x2, y2);
    }
}