void ContentWindowGraphicsItem::drawMovieControls_( QPainter* painter )
{
    ContentWindowManagerPtr contentWindowManager = getContentWindowManager();

    float buttonWidth, buttonHeight;
    getButtonDimensions(buttonWidth, buttonHeight);

    QPen pen;

    if( contentWindowManager->getContent()->getType() == CONTENT_TYPE_MOVIE &&
        g_configuration->getOptions()->getShowMovieControls( ))
    {
        // play/pause
        QRectF playPauseRect(coordinates_.x() + coordinates_.width()/2 - buttonWidth, coordinates_.y() + coordinates_.height() - buttonHeight,
                              buttonWidth, buttonHeight);
        pen.setColor(QColor(contentWindowManager->getControlState() & STATE_PAUSED ? 128 :200,0,0));
        painter->setPen(pen);
        painter->fillRect(playPauseRect, pen.color());

        // loop
        QRectF loopRect(coordinates_.x() + coordinates_.width()/2, coordinates_.y() + coordinates_.height() - buttonHeight,
                        buttonWidth, buttonHeight);
        pen.setColor(QColor(0,contentWindowManager->getControlState() & STATE_LOOP ? 200 :128,0));
        painter->setPen(pen);
        painter->fillRect(loopRect, pen.color());
    }
}
void ContentWindowGraphicsItem::wheelEvent(QGraphicsSceneWheelEvent * event)
{
    // on Mac we've seen that mouse events can go to the wrong graphics item
    // this is due to the bug: https://bugreports.qt.nokia.com/browse/QTBUG-20493
    // here we ignore the event if it shouldn't have been sent to us, which ensures
    // it will go to the correct item...
    if(boundingRect().contains(event->pos()) == false)
    {
        event->ignore();
        return;
    }

    ContentWindowManagerPtr contentWindow = getContentWindowManager();

    if( contentWindow )
    {
        // handle wheel movements differently depending on state of item window
        if (selected())
        {
            contentWindow->getInteractionDelegate().wheelEvent(event);
        }
        else
        {
            // scale size based on wheel delta
            // typical delta value is 120, so scale based on that
            double factor = 1. + (double)event->delta() / (10. * 120.);

            scaleSize(factor);
        }
    }
}
void ContentWindowGraphicsItem::keyReleaseEvent(QKeyEvent *event)
{
    if (selected())
    {
        ContentWindowManagerPtr contentWindow = getContentWindowManager();

        if( contentWindow )
        {
            contentWindow->getInteractionDelegate().keyReleaseEvent(event);
        }
    }
}
void MovieContent::advance(FactoriesPtr factories, ContentWindowManagerPtr window, const boost::posix_time::time_duration timeSinceLastFrame)
{
    // Stop decoding when the window is moving to avoid saccades when reaching a new GLWindow
    // The decoding resumes when the movement is finished
    if( blockAdvance_ )
        return;

    boost::shared_ptr< Movie > movie = factories->getMovieFactory().getObject(getURI());

    // skip a frame if the Content rectangle is not visible in any window; otherwise decode normally
    const bool skipDecoding = !movie->getRenderContext()->isRegionVisible(window->getCoordinates());

    movie->setPause( window->getControlState() & STATE_PAUSED );
    movie->setLoop( window->getControlState() & STATE_LOOP );
    movie->nextFrame(timeSinceLastFrame, skipDecoding);
}
void ContentWindowGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
{
    // handle mouse movements differently depending on selected mode of item
    if(!selected())
    {
        if(event->buttons().testFlag(Qt::LeftButton))
        {
            if(resizing_)
            {
                QRectF r = boundingRect();
                QPointF eventPos = event->pos();

                r.setBottomRight(eventPos);

                QRectF sceneRect = mapRectToScene(r);

                double w = sceneRect.width();
                double h = sceneRect.height();

                setSize(w, h);
            }
            else
            {
                QPointF delta = event->pos() - event->lastPos();

                double new_x = coordinates_.x() + delta.x();
                double new_y = coordinates_.y() + delta.y();

                setPosition(new_x, new_y);
            }
        }
    }
    else
    {
        ContentWindowManagerPtr contentWindow = getContentWindowManager();
        if(contentWindow)
        {
            // Zoom or forward event depending on type
            contentWindow->getInteractionDelegate().mouseMoveEvent(event);

            // force a redraw to update window info label
            update();
        }
    }
}
void ContentWindowGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
{
    resizing_ = false;
    moving_ = false;

    ContentWindowManagerPtr contentWindow = getContentWindowManager();

    if( contentWindow )
    {
        contentWindow->getContent()->blockAdvance( false );

        if (selected())
        {
            contentWindow->getInteractionDelegate().mouseReleaseEvent(event);
        }
    }

    QGraphicsItem::mouseReleaseEvent(event);
}
void DisplayGroupManager::addContentWindowManager(ContentWindowManagerPtr contentWindowManager, DisplayGroupInterface * source)
{
    DisplayGroupInterface::addContentWindowManager(contentWindowManager, source);

    if(source != this)
    {
        // set display group in content window manager object
        contentWindowManager->setDisplayGroupManager(shared_from_this());

        sendDisplayGroup();

        if (contentWindowManager->getContent()->getType() != CONTENT_TYPE_PIXEL_STREAM)
        {
            // TODO initialize all content dimensions on creation so we can remove this procedure
            // make sure we have its dimensions so we can constrain its aspect ratio
            sendContentsDimensionsRequest();
        }
    }
}
void DisplayGroupManager::removeContentWindowManager(ContentWindowManagerPtr contentWindowManager, DisplayGroupInterface * source)
{
    DisplayGroupInterface::removeContentWindowManager(contentWindowManager, source);

    if(source != this)
    {
        // Notify the (local) pixel stream source of the deletion of the window so the source can be removed too
        if (contentWindowManager->getContent()->getType() == CONTENT_TYPE_PIXEL_STREAM)
        {
            const QString& uri = contentWindowManager->getContent()->getURI();
            closePixelStream(uri);
            emit(pixelStreamViewClosed(uri));
        }

        // set null display group in content window manager object
        contentWindowManager->setDisplayGroupManager(DisplayGroupManagerPtr());

        sendDisplayGroup();
    }
}
void ContentWindowGraphicsItem::drawTextLabel_( QPainter* painter )
{
    ContentWindowManagerPtr contentWindowManager = getContentWindowManager();

    float buttonWidth, buttonHeight;
    getButtonDimensions(buttonWidth, buttonHeight);

    const float fontSize = 24.;

    QFont font;
    font.setPixelSize(fontSize);
    painter->setFont(font);

    // color the text black
    QPen pen;
    pen.setColor(QColor(0,0,0));
    painter->setPen(pen);

    // scale the text size down to the height of the graphics view
    // and, calculate the bounding rectangle for the text based on this scale
    // the dimensions of the view need to be corrected for the tiled display aspect ratio
    // recall the tiled display UI is only part of the graphics view since we show it at the correct aspect ratio
    // TODO refactor this for clarity!
    float viewWidth = (float)scene()->views()[0]->width();
    float viewHeight = (float)scene()->views()[0]->height();

    const float tiledDisplayAspect = g_configuration->getAspectRatio();

    if(viewWidth / viewHeight > tiledDisplayAspect)
    {
        viewWidth = viewHeight * tiledDisplayAspect;
    }
    else if(viewWidth / viewHeight <= tiledDisplayAspect)
    {
        viewHeight = viewWidth / tiledDisplayAspect;
    }

    float verticalTextScale = 1. / viewHeight;
    float horizontalTextScale = viewHeight / viewWidth * verticalTextScale;

    painter->scale(horizontalTextScale, verticalTextScale);

    QRectF textBoundingRect = QRectF(coordinates_.x() / horizontalTextScale,
                                     coordinates_.y() / verticalTextScale,
                                     coordinates_.width() / horizontalTextScale,
                                     coordinates_.height() / verticalTextScale);

    // get the label and render it
    QString label(contentWindowManager->getContent()->getURI());
    QString labelSection = label.section("/", -1, -1).prepend(" ");
    painter->drawText(textBoundingRect, Qt::AlignLeft | Qt::AlignTop, labelSection);

    // draw window info at smaller scale
    verticalTextScale *= 0.5;
    horizontalTextScale *= 0.5;

    painter->scale(0.5, 0.5);

    textBoundingRect = QRectF((coordinates_.x()+buttonWidth) / horizontalTextScale,
                               coordinates_.y() / verticalTextScale,
                              (coordinates_.width()-buttonWidth) / horizontalTextScale,
                               coordinates_.height() / verticalTextScale);

    QString coordinatesLabel = QString(" (") + QString::number(coordinates_.x(), 'f', 2) + QString(" ,") +
                                               QString::number(coordinates_.y(), 'f', 2) + QString(", ") +
                                               QString::number(coordinates_.width(), 'f', 2) + QString(", ") +
                                               QString::number(coordinates_.height(), 'f', 2) + QString(")\n");
    QString zoomCenterLabel = QString(" zoom = ") + QString::number(zoom_, 'f', 2) + QString(" @ (") +
                              QString::number(centerX_, 'f', 2) + QString(", ") +
                              QString::number(centerY_, 'f', 2) + QString(")");
    QString interactionLabel = QString(" x: ") +
            QString::number(latestEvent_.mouseX, 'f', 2) +
            QString(" y: ") + QString::number(latestEvent_.mouseY, 'f', 2) +
            QString(" mouseLeft: ") + QString::number((int) latestEvent_.mouseLeft, 'b', 1) +
            QString(" mouseMiddle: ") + QString::number((int) latestEvent_.mouseMiddle, 'b', 1) +
            QString(" mouseRight: ") + QString::number((int) latestEvent_.mouseRight, 'b', 1);

    QString windowInfoLabel = coordinatesLabel + zoomCenterLabel + interactionLabel;
    painter->drawText(textBoundingRect, Qt::AlignLeft | Qt::AlignBottom, windowInfoLabel);
}
void ContentWindowGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent * event)
{
    // on Mac we've seen that mouse events can go to the wrong graphics item
    // this is due to the bug: https://bugreports.qt.nokia.com/browse/QTBUG-20493
    // here we ignore the event if it shouldn't have been sent to us, which ensures
    // it will go to the correct item...
    if(boundingRect().contains(event->pos()) == false)
    {
        event->ignore();
        return;
    }

    // button dimensions
    float buttonWidth, buttonHeight;
    getButtonDimensions(buttonWidth, buttonHeight);

    // item rectangle and event position
    QRectF r = boundingRect();
    QPointF eventPos = event->pos();

    // check to see if user clicked on the close button
    if(fabs((r.x()+r.width()) - eventPos.x()) <= buttonWidth &&
       fabs(r.y() - eventPos.y()) <= buttonHeight)
    {
        close();

        return;
    }

    // move to the front of the GUI display
    moveToFront();

    ContentWindowManagerPtr contentWindow = getContentWindowManager();
    if (!contentWindow)
        return;

    if (selected())
    {
        contentWindow->getInteractionDelegate().mousePressEvent(event);
        return;
    }

    contentWindow->getContent()->blockAdvance( true );

    // check to see if user clicked on the resize button
    if(fabs((r.x()+r.width()) - eventPos.x()) <= buttonWidth &&
       fabs((r.y()+r.height()) - eventPos.y()) <= buttonHeight)
    {
        resizing_ = true;
    }
    // check to see if user clicked on the fullscreen button
    else if(fabs(r.x() - eventPos.x()) <= buttonWidth &&
            fabs((r.y()+r.height()) - eventPos.y()) <= buttonHeight)
    {
        toggleFullscreen();
    }
    else if(fabs(((r.x()+r.width())/2) - eventPos.x() - buttonWidth) <= buttonWidth &&
            fabs((r.y()+r.height()) - eventPos.y()) <= buttonHeight &&
            g_configuration->getOptions()->getShowMovieControls( ))
    {
        contentWindow->setControlState( ControlState(contentWindow->getControlState() ^ STATE_PAUSED) );
    }
    else if(fabs(((r.x()+r.width())/2) - eventPos.x()) <= buttonWidth &&
            fabs((r.y()+r.height()) - eventPos.y()) <= buttonHeight &&
            g_configuration->getOptions()->getShowMovieControls( ))
    {
        contentWindow->setControlState( ControlState(contentWindow->getControlState() ^ STATE_LOOP) );
    }
    else
        moving_ = true;

    QGraphicsItem::mousePressEvent(event);
}
Esempio n. 11
0
void Content::render(ContentWindowManagerPtr window)
{
    double x, y, w, h;
    window->getCoordinates(x, y, w, h);

    double centerX, centerY;
    window->getCenter(centerX, centerY);

    double zoom = window->getZoom();

    // calculate texture coordinates
    float tX = centerX - 0.5 / zoom;
    float tY = centerY - 0.5 / zoom;
    float tW = 1./zoom;
    float tH = 1./zoom;

    // transform to a normalize coordinate system so the content can be rendered at (x,y,w,h) = (0,0,1,1)
    glPushMatrix();

    glTranslatef(x, y, 0.);
    glScalef(w, h, 1.);

    // render the factory object
    renderFactoryObject(tX, tY, tW, tH);

    // render the context view
    if(g_displayGroupManager->getOptions()->getShowZoomContext() == true && zoom > 1.)
    {
        float sizeFactor = 0.25;
        float padding = 0.02;
        float deltaZ = 0.001;
        float alpha = 0.5;
        float borderPixels = 5.;

        glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_LINE_BIT);
        glPushMatrix();

        // position at lower left
        glTranslatef(padding, 1. - sizeFactor - padding, deltaZ);
        glScalef(sizeFactor, sizeFactor, 1.);

        // render border rectangle
        glColor4f(1,1,1,1);

        glLineWidth(borderPixels);

        glBegin(GL_LINE_LOOP);

        glVertex2d(0., 0.);
        glVertex2d(1., 0.);
        glVertex2d(1., 1.);
        glVertex2d(0., 1.);

        glEnd();

        // render the factory object (full view)
        glTranslatef(0., 0., deltaZ);
        renderFactoryObject(0., 0., 1., 1.);

        // draw context rectangle border
        glTranslatef(0., 0., deltaZ);

        glLineWidth(borderPixels);

        glBegin(GL_LINE_LOOP);

        glVertex2d(tX, tY);
        glVertex2d(tX + tW, tY);
        glVertex2d(tX + tW, tY + tH);
        glVertex2d(tX, tY + tH);

        glEnd();

        // draw context rectangle blended
        glTranslatef(0., 0., deltaZ);

        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        glColor4f(1.,1.,1., alpha);
        GLWindow::drawRectangle(tX, tY, tW, tH);

        glPopMatrix();
        glPopAttrib();
    }

    glPopMatrix();
}
void PixelStreamContent::preRenderUpdate(Factories& factories, ContentWindowManagerPtr window, WallToWallChannel& wallToWallChannel)
{
    const QRectF& windowRect = window->getCoordinates();
    factories.getPixelStreamFactory().getObject(getURI())->preRenderUpdate(windowRect, wallToWallChannel);
}
void PixelStreamContent::advance(FactoriesPtr factories, ContentWindowManagerPtr window, const boost::posix_time::time_duration)
{
    const QRectF& windowRect = window->getCoordinates();
    factories->getPixelStreamFactory().getObject(getURI())->preRenderUpdate(windowRect);
}