📄 presentationwidget.cpp.svn-base
字号:
m_pagesEdit->setValidator( validator ); m_topBar->addWidget( m_pagesEdit ); connect( m_pagesEdit, SIGNAL( returnPressed() ), this, SLOT( slotPageChanged() ) ); m_topBar->addAction( KIcon("1rightarrow"), i18n("Next Page"), this, SLOT( slotNextPage() ) ); QWidget *spacer = new QWidget(m_topBar); spacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::MinimumExpanding ); m_topBar->addWidget( spacer ); m_topBar->addAction( KIcon("exit"), i18n("Exit Presentation Mode"), this, SLOT( close() ) ); m_topBar->setGeometry( 0, 0, m_width, 32 + 10 ); m_topBar->hide(); // change topbar background color QPalette p = m_topBar->palette(); p.setColor( QPalette::Active, QPalette::Button, Qt::gray ); p.setColor( QPalette::Active, QPalette::Background, Qt::darkGray ); m_topBar->setPalette( p ); // register this observer in document. events will come immediately m_document->addObserver( this ); // show summary if requested if ( KpdfSettings::slidesShowSummary() ) generatePage(); } // check painting rect consistancy QRect r = pe->rect().intersect( geometry() ); if ( r.isNull() || m_lastRenderedPixmap.isNull() ) return; // blit the pixmap to the screen QVector<QRect> allRects = pe->region().rects(); uint numRects = allRects.count(); QPainter painter( this ); for ( uint i = 0; i < numRects; i++ ) { const QRect & r = allRects[i]; if ( !r.isValid() ) continue;#ifdef ENABLE_PROGRESS_OVERLAY if ( KpdfSettings::slidesShowProgress() && r.intersects( m_overlayGeometry ) ) { // backbuffer the overlay operation QPixmap backPixmap( r.size() ); QPainter pixPainter( &backPixmap ); // first draw the background on the backbuffer pixPainter.drawPixmap( QPoint(0,0), m_lastRenderedPixmap, r ); // then blend the overlay (a piece of) over the background QRect ovr = m_overlayGeometry.intersect( r ); pixPainter.drawPixmap( ovr.left() - r.left(), ovr.top() - r.top(), m_lastRenderedOverlay, ovr.left() - m_overlayGeometry.left(), ovr.top() - m_overlayGeometry.top(), ovr.width(), ovr.height() ); // finally blit the pixmap to the screen pixPainter.end(); painter.drawPixmap( r.topLeft(), backPixmap, backPixmap.rect() ); } else#endif // copy the rendered pixmap to the screen painter.drawPixmap( r.topLeft(), m_lastRenderedPixmap, r ); } painter.end();}// </widget events>const KPDFLink * PresentationWidget::getLink( int x, int y, QRect * geometry ) const{ // no links on invalid pages if ( geometry && !geometry->isNull() ) geometry->setRect( 0, 0, 0, 0 ); if ( m_frameIndex < 0 || m_frameIndex >= (int)m_frames.size() ) return 0; // get frame, page and geometry const PresentationFrame * frame = m_frames[ m_frameIndex ]; const KPDFPage * page = frame->page; const QRect & frameGeometry = frame->geometry; // compute normalized x and y double nx = (double)(x - frameGeometry.left()) / (double)frameGeometry.width(); double ny = (double)(y - frameGeometry.top()) / (double)frameGeometry.height(); // no links outside the pages if ( nx < 0 || nx > 1 || ny < 0 || ny > 1 ) return 0; // check if 1) there is an object and 2) it's a link const ObjectRect * object = page->getObjectRect( ObjectRect::Link, nx, ny ); if ( !object ) return 0; // compute link geometry if destination rect present if ( geometry ) { *geometry = object->boundingRect( frameGeometry.width(), frameGeometry.height() ); geometry->translate( frameGeometry.left(), frameGeometry.top() ); } // return the link pointer return (KPDFLink *)object->pointer();}void PresentationWidget::testCursorOnLink( int x, int y ){ const KPDFLink * link = getLink( x, y, 0 ); // only react on changes (in/out from a link) if ( (link && !m_handCursor) || (!link && m_handCursor) ) { // change cursor shape m_handCursor = link != 0; setCursor( m_handCursor ? KCursor::handCursor() : KCursor::arrowCursor() ); }}void PresentationWidget::overlayClick( const QPoint & position ){ // clicking the progress indicator int xPos = position.x() - m_overlayGeometry.x() - m_overlayGeometry.width() / 2, yPos = m_overlayGeometry.height() / 2 - position.y(); if ( !xPos && !yPos ) return; // compute angle relative to indicator (note coord transformation) float angle = 0.5 + 0.5 * atan2( -xPos, -yPos ) / M_PI; int pageIndex = (int)( angle * ( m_frames.count() - 1 ) + 0.5 ); // go to selected page changePage( pageIndex );}void PresentationWidget::changePage( int newPage ){ if ( m_frameIndex == newPage ) return; // check if pixmap exists or else request it m_frameIndex = newPage; PresentationFrame * frame = m_frames[ m_frameIndex ]; int pixW = frame->geometry.width(); int pixH = frame->geometry.height(); int rot = frame->page->orientation(); bool signalsBlocked = m_pagesEdit->signalsBlocked(); m_pagesEdit->blockSignals( true ); m_pagesEdit->setText( QString::number( m_frameIndex + 1 ) ); m_pagesEdit->blockSignals( signalsBlocked ); // if pixmap not inside the KPDFPage we request it and wait for // notifyPixmapChanged call or else we can proceed to pixmap generation if ( !frame->page->hasPixmap( PRESENTATION_ID, pixW, pixH ) ) { // operation will take long: set busy cursor QApplication::setOverrideCursor( KCursor::workingCursor() ); // request the pixmap QLinkedList< PixmapRequest * > request; request.push_back( new PixmapRequest( PRESENTATION_ID, m_frameIndex, pixW, pixH, rot, PRESENTATION_PRIO ) ); m_document->requestPixmaps( request ); // restore cursor QApplication::restoreOverrideCursor(); } else { // make the background pixmap generatePage(); }}void PresentationWidget::generatePage(){ if ( m_lastRenderedPixmap.isNull() ) m_lastRenderedPixmap = QPixmap( m_width, m_height ); // opens the painter over the pixmap QPainter pixmapPainter; pixmapPainter.begin( &m_lastRenderedPixmap ); // generate welcome page if ( m_frameIndex == -1 ) generateIntroPage( pixmapPainter ); // generate a normal pixmap with extended margin filling if ( m_frameIndex >= 0 && m_frameIndex < (int)m_document->pages() ) generateContentsPage( m_frameIndex, pixmapPainter ); pixmapPainter.end(); // generate the top-right corner overlay#ifdef ENABLE_PROGRESS_OVERLAY if ( KpdfSettings::slidesShowProgress() && m_frameIndex != -1 ) generateOverlay();#endif // start transition on pages that have one const KPDFPageTransition * transition = m_frameIndex != -1 ? m_frames[ m_frameIndex ]->page->getTransition() : 0; if ( transition ) initTransition( transition ); else { KPDFPageTransition trans = defaultTransition(); initTransition( &trans ); } // update cursor + tooltip if ( KpdfSettings::slidesCursor() != KpdfSettings::EnumSlidesCursor::Hidden ) { QPoint p = mapFromGlobal( QCursor::pos() ); testCursorOnLink( p.x(), p.y() ); }}void PresentationWidget::generateIntroPage( QPainter & p ){ // use a vertical gray gradient background int blend1 = m_height / 10, blend2 = 9 * m_height / 10; int baseTint = QColor(Qt::gray).red(); for ( int i = 0; i < m_height; i++ ) { int k = baseTint; if ( i < blend1 ) k -= (int)( baseTint * (i-blend1)*(i-blend1) / (float)(blend1 * blend1) ); if ( i > blend2 ) k += (int)( (255-baseTint) * (i-blend2)*(i-blend2) / (float)(blend1 * blend1) ); p.fillRect( 0, i, m_width, 1, QColor( k, k, k ) ); } // draw okular logo in the four corners QPixmap logo = DesktopIcon( "okular", 64 ); if ( !logo.isNull() ) { p.drawPixmap( 5, 5, logo ); p.drawPixmap( m_width - 5 - logo.width(), 5, logo ); p.drawPixmap( m_width - 5 - logo.width(), m_height - 5 - logo.height(), logo ); p.drawPixmap( 5, m_height - 5 - logo.height(), logo ); } // draw metadata text (the last line is 'click to begin') int strNum = m_metaStrings.count(), strHeight = m_height / ( strNum + 4 ), fontHeight = 2 * strHeight / 3; QFont font( p.font() ); font.setPixelSize( fontHeight ); QFontMetrics metrics( font ); for ( int i = 0; i < strNum; i++ ) { // set a font to fit text width float wScale = (float)metrics.boundingRect( m_metaStrings[i] ).width() / (float)m_width; QFont f( font ); if ( wScale > 1.0 ) f.setPixelSize( (int)( (float)fontHeight / (float)wScale ) ); p.setFont( f ); // text shadow p.setPen( Qt::darkGray ); p.drawText( 2, m_height / 4 + strHeight * i + 2, m_width, strHeight, Qt::AlignHCenter | Qt::AlignVCenter, m_metaStrings[i] ); // text body p.setPen( 128 + (127 * i) / strNum ); p.drawText( 0, m_height / 4 + strHeight * i, m_width, strHeight, Qt::AlignHCenter | Qt::AlignVCenter, m_metaStrings[i] ); }}void PresentationWidget::generateContentsPage( int pageNum, QPainter & p ){ PresentationFrame * frame = m_frames[ pageNum ]; // translate painter and contents rect QRect geom( frame->geometry ); p.translate( geom.left(), geom.top() ); geom.translate( -geom.left(), -geom.top() ); // draw the page using the shared PagePainter class int flags = PagePainter::Accessibility; PagePainter::paintPageOnPainter( &p, frame->page, PRESENTATION_ID, flags, geom.width(), geom.height(), geom ); // restore painter p.translate( -frame->geometry.left(), -frame->geometry.top() ); // fill unpainted areas with background color QRegion unpainted( QRect( 0, 0, m_width, m_height ) ); QVector<QRect> rects = unpainted.subtract( frame->geometry ).rects(); for ( int i = 0; i < rects.count(); i++ ) { const QRect & r = rects[i]; p.fillRect( r, KpdfSettings::slidesBackgroundColor() ); }}// from Arthur - Qt4 - (is defined elsewhere as 'qt_div_255' to not break final compilation)inline int qt_div255(int x) { return (x + (x>>8) + 0x80) >> 8; }void PresentationWidget::generateOverlay(){#ifdef ENABLE_PROGRESS_OVERLAY // calculate overlay geometry and resize pixmap if needed int side = m_width / 16; m_overlayGeometry.setRect( m_width - side - 4, 4, side, side ); // note: to get a sort of antialiasing, we render the pixmap double sized // and the resulting image is smoothly scaled down. So here we open a // painter on the double sized pixmap. side *= 2; QPixmap doublePixmap( side, side ); doublePixmap.fill( Qt::black ); QPainter pixmapPainter( &doublePixmap ); // draw PIE SLICES in blue levels (the levels will then be the alpha component) int pages = m_document->pages(); if ( pages > 28 ) { // draw continuous slices int degrees = (int)( 360 * (float)(m_frameIndex + 1) / (float)pages ); pixmapPainter.setPen( 0x05 ); pixmapPainter.setBrush( QColor( 0x40 ) ); pixmapPainter.drawPie( 2, 2, side - 4, side - 4, 90*16, (360-degrees)*16 ); pixmapPainter.setPen( 0x40 ); pixmapPainter.setBrush( QColor( 0xF0 ) ); pixmapPainter.drawPie( 2, 2, side - 4, side - 4, 90*16, -degrees*16 ); } else { // draw discrete slices float oldCoord = -90; for ( int i = 0; i < pages; i++ ) { float newCoord = -90 + 360 * (float)(i + 1) / (float)pages; pixmapPainter.setPen( i <= m_frameIndex ? 0x40 : 0x05 ); pixmapPainter.setBrush( QColor( i <= m_frameIndex ? 0xF0 : 0x40 ) ); pixmapPainter.drawPie( 2, 2, side - 4, side - 4, (int)( -16*(oldCoord + 1) ), (int)( -16*(newCoord - (oldCoord + 2)) ) ); oldCoord = newCoord; } } int circleOut = side / 4; pixmapPainter.setPen( Qt::black ); pixmapPainter.setBrush( Qt::black ); pixmapPainter.drawEllipse( circleOut, circleOut, side - 2*circleOut, side - 2*circleOut ); // draw TEXT using maximum opacity QFont f( pixmapPainter.font() ); f.setPixelSize( side / 4 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -