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); }
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); }