void Glissando::layout()
      {
      Chord* chord = static_cast<Chord*>(parent());
      if (chord == 0)
            return;
      Note* anchor2   = chord->upNote();
      Segment* s = chord->segment();
      s = s->prev1();
      while (s) {
            if ((s->segmentType() & (Segment::SegChordRest)) && s->element(track()))
                  break;
            s = s->prev1();
            }
      if (s == 0) {
            qDebug("no segment for first note of glissando found\n");
            return;
            }
      ChordRest* cr = static_cast<ChordRest*>(s->element(track()));
      if (cr == 0 || cr->type() != CHORD) {
            qDebug("no first note for glissando found, track %d", track());
            return;
            }
      qreal _spatium = spatium();
      Note* anchor1 = static_cast<Chord*>(cr)->upNote();

      setPos(0.0, 0.0);
      adjustReadPos();

      QPointF cp1    = anchor1->pagePos();
      QPointF cp2    = anchor2->pagePos();

      // line starting point
      int dots = static_cast<Chord*>(cr)->dots();
      LedgerLine * ledLin = static_cast<Chord*>(cr)->ledgerLines();
      // if dots, from right of last dot (assume a standard dot with of 1/4 sp)
      // if no dots, from right of ledger line, if any; from right of note head, if no ledger line
      qreal x1 = (dots ? anchor1->dot(dots-1)->pos().x() + anchor1->dot(dots-1)->width()
                  : (ledLin ? ledLin->pos().x() + ledLin->width() : anchor1->headWidth()) )
            - (cp2.x() - cp1.x());              // make relative to end note
      qreal y1 = anchor1->pos().y();
      // line end point: left of note head
      qreal x2 = anchor2->pos().x();
      qreal y2 = anchor2->pos().y();

      // angle glissando between notes with the same pitch letter
      if (anchor1->line() == anchor2->line()) {
            int upDown = anchor2->pitch() - anchor1->pitch();
            if (upDown != 0)
                  upDown /= abs(upDown);
            y1 += _spatium * 0.25 * upDown;
            y2 -= _spatium * 0.25 * upDown;
            }

      // on TAB's, adjust lower end point from string line height to base of note height (= ca. half line spacing)
      if (chord->staff()->isTabStaff()) {
            qreal yOff = chord->staff()->lineDistance() * 0.3 * _spatium;
            if (anchor1->pitch() > anchor2->pitch()) {  // descending glissando:
                  y2 += yOff;
                  y1 -= yOff;
                  }                                     // move ending point to base of note
            else {                                      // ascending glissando:
                  y1 += yOff;                               // move starting point to base of note
                  y2 -= yOff;
                  }
            }

      // shorten line to avoid end note ledger line
      ledLin=anchor2->chord()->ledgerLines();
      if (ledLin)
            x2 = ledLin->pos().x();
      // shorten line so it doesn't go through end note accidental or arpeggio
      if (Accidental* a = anchor2->accidental()) {
            x2 = a->pos().x() + a->userOff().x();
            }
      if (Arpeggio* a = chord->arpeggio()) {
            x2 = a->pos().x() + a->userOff().x();
            }

      QLineF fullLine(x1, y1, x2, y2);

      // shorten line on each side by offsets
      qreal xo = _spatium * .5;
      qreal yo = xo;   // spatium() * .5;
      QPointF p1 = fullLine.pointAt(xo / fullLine.length());
      QPointF p2 = fullLine.pointAt(1 - (yo / fullLine.length()));

      line = QLineF(p1, p2);
      qreal lw = _spatium * .15 * .5;
      QRectF r = QRectF(line.p1(), line.p2()).normalized();
      setbbox(r.adjusted(-lw, -lw, lw, lw));
      }
TableHandle PageItem_Table::hitTest(const QPointF& point, double threshold) const
{
	const QPointF framePoint = getTransform().inverted().map(point);
	const QPointF gridPoint = framePoint - gridOffset();
	const QRectF gridRect = QRectF(0.0, 0.0, tableWidth(), tableHeight());

	// Test if hit is outside frame.
	if (!QRectF(0.0, 0.0, width(), height()).contains(framePoint))
		return TableHandle(TableHandle::None);

	// Test if hit is outside table.
	if (!gridRect.adjusted(-threshold, -threshold, threshold, threshold).contains(gridPoint))
		return TableHandle(TableHandle::None);

	const double tableHeight = this->tableHeight();
	const double tableWidth = this->tableWidth();
	const double x = gridPoint.x();
	const double y = gridPoint.y();

	// Test if hit is on left edge of table.
	if (x <= threshold)
		return TableHandle(TableHandle::RowSelect);

	// Test if hit is on top edge of table.
	if (y <= threshold)
		return TableHandle(TableHandle::ColumnSelect);

	// Test if hit is on bottom right corner of table.
	if (x >= tableWidth - threshold && y >= tableHeight - threshold)
		return TableHandle(TableHandle::TableResize);

	// Test if hit is on right edge of table.
	if (y >= tableHeight - threshold && y <= tableHeight + threshold)
		return TableHandle(TableHandle::RowResize, rows() - 1);

	// Test if hit is on bottom edge of table.
	if (x >= tableWidth - threshold && x <= tableWidth + threshold)
		return TableHandle(TableHandle::ColumnResize, columns() - 1);

	const TableCell hitCell = cellAt(point);
	const QRectF hitRect = hitCell.boundingRect();

	// Test if hit is on cell interior.
	if (hitRect.adjusted(threshold, threshold, -threshold, -threshold).contains(gridPoint))
		return TableHandle(TableHandle::CellSelect); // Hit interior of cell.

	const double toLeft = x - hitRect.left();
	const double toRight = hitRect.right() - x;
	const double toTop = y - hitRect.top();
	const double toBottom = hitRect.bottom() - y;
	TableHandle handle(TableHandle::None);

	// Test which side of the cell was hit.
	if (qMin(toLeft, toRight) < qMin(toTop, toBottom))
	{
		handle.setType(TableHandle::ColumnResize);
		handle.setIndex((toLeft < toRight ? hitCell.column() : hitCell.column() + hitCell.columnSpan()) - 1);
	}
	else
	{
		handle.setType(TableHandle::RowResize);
		handle.setIndex((toTop < toBottom ? hitCell.row() : hitCell.row() + hitCell.rowSpan()) - 1);
	}
	return handle;
}
Exemple #3
0
void Glissando::layout()
      {
      qreal _spatium    = spatium();

      if (score() == gscore || !startElement() || !endElement()) {  // for use in palettes or while dragging
            if (spannerSegments().empty())
                  add(createLineSegment());
            LineSegment* s = frontSegment();
            s->setPos(QPointF());
            s->setPos2(QPointF(_spatium * GLISS_PALETTE_WIDTH, -_spatium * GLISS_PALETTE_HEIGHT));
            s->layout();
            return;
            }

      SLine::layout();
      setPos(0.0, 0.0);
      adjustReadPos();

      Note*       anchor1     = static_cast<Note*>(startElement());
      Note*       anchor2     = static_cast<Note*>(endElement());
      Chord*      cr1         = anchor1->chord();
      Chord*      cr2         = anchor2->chord();
      GlissandoSegment*       segm1 = static_cast<GlissandoSegment*>(frontSegment());
      GlissandoSegment*       segm2 = static_cast<GlissandoSegment*>(backSegment());

      // Note: line segments are defined by
      // initial point: ipos() (relative to system origin)
      // ending point:  pos2() (relative to initial point)

      // LINE ENDING POINTS TO NOTEHEAD CENTRES

      // assume gliss. line goes from centre of initial note centre to centre of ending note:
      // move first segment origin and last segment ending point from notehead origin to notehead centre
      QPointF     offs1       = QPointF(anchor1->headWidth() * 0.5, 0.0);
      QPointF     offs2       = QPointF(anchor2->headWidth() * 0.5, 0.0);

      // AVOID HORIZONTAL LINES

      int         upDown      = (0 < (anchor2->pitch() - anchor1->pitch())) - ((anchor2->pitch() - anchor1->pitch()) < 0);
      // on TAB's, glissando are by necessity on the same string, this gives an horizontal glissando line;
      // make bottom end point lower and top ending point higher
      if (cr1->staff()->isTabStaff()) {
                  qreal yOff = cr1->staff()->lineDistance() * 0.4 * _spatium;
                  offs1.ry() += yOff * upDown;
                  offs2.ry() -= yOff * upDown;
            }
      // if not TAB, angle glissando between notes on the same line
      else {
            if (anchor1->line() == anchor2->line()) {
                  offs1.ry() += _spatium * 0.25 * upDown;
                  offs2.ry() -= _spatium * 0.25 * upDown;
                  }
            }

      // move initial point of first segment and adjust its length accordingly
      segm1->setPos (segm1->ipos()  + offs1);
      segm1->setPos2(segm1->ipos2() - offs1);
      // adjust ending point of last segment
      segm2->setPos2(segm2->ipos2() + offs2);

      // FINAL SYSTEM-INITIAL NOTE
      // if the last gliss. segment attaches to a system-initial note, some extra width has to be added
      if (cr2->segment()->measure() == cr2->segment()->system()->firstMeasure() && cr2->rtick() == 0
                  // but ignore graces after, as they are not the first note of the system,
                  // even if their segment is the first segment of the system
                  && !(cr2->noteType() == NoteType::GRACE8_AFTER
                        || cr2->noteType() == NoteType::GRACE16_AFTER || cr2->noteType() == NoteType::GRACE32_AFTER)
                  // also ignore if cr1 is a child of cr2, which means cr1 is a grace-before of cr2
                  && !(cr1->parent() == cr2))
            {
            segm2->rxpos() -= GLISS_STARTOFSYSTEM_WIDTH * _spatium;
            segm2->rxpos2()+= GLISS_STARTOFSYSTEM_WIDTH * _spatium;
            }

      // INTERPOLATION OF INTERMEDIATE POINTS
      // This probably belongs to SLine class itself; currently it does not seem
      // to be needed for anything else than Glissando, though

      // get total x-width and total y-height of all segments
      qreal xTot = 0.0;
      for (SpannerSegment* segm : spannerSegments())
            xTot += segm->ipos2().x();
      qreal y0   = segm1->ipos().y();
      qreal yTot = segm2->ipos().y() + segm2->ipos2().y() - y0;
      qreal ratio = yTot / xTot;
      // interpolate y-coord of intermediate points across total width and height
      qreal xCurr = 0.0;
      qreal yCurr;
      for (int i = 0; i < spannerSegments().count()-1; i++) {
           SpannerSegment* segm = segmentAt(i);
           xCurr += segm->ipos2().x();
           yCurr = y0 + ratio * xCurr;
           segm->rypos2() = yCurr - segm->ipos().y();       // position segm. end point at yCurr
           // next segment shall start where this segment stopped
           segm = segmentAt(i+1);
           segm->rypos2() += segm->ipos().y() - yCurr;      // adjust next segm. vertical length
           segm->rypos() = yCurr;                           // position next segm. start point at yCurr
            }

      // STAY CLEAR OF NOTE APPENDAGES

      // initial note dots / ledger line / notehead
      offs1 *= -1.0;          // discount changes already applied
      int dots = cr1->dots();
      LedgerLine * ledLin = cr1->ledgerLines();
      // if dots, start at right of last dot
      // if no dots, from right of ledger line, if any; from right of notehead, if no ledger line
      offs1.rx() += (dots && anchor1->dot(dots-1) ? anchor1->dot(dots-1)->pos().x() + anchor1->dot(dots-1)->width()
                  : (ledLin ? ledLin->pos().x() + ledLin->width() : anchor1->headWidth()) );

      // final note arpeggio / accidental / ledger line / accidental / arpeggio (i.e. from outermost to innermost)
      offs2 *= -1.0;          // discount changes already applied
      if (Arpeggio* a = cr2->arpeggio())
            offs2.rx() += a->pos().x() + a->userOff().x();
      else if (Accidental* a = anchor2->accidental())
            offs2.rx() += a->pos().x() + a->userOff().x();
      else if ( (ledLin = cr2->ledgerLines()) != nullptr)
            offs2.rx() += ledLin->pos().x();

      // add another a quarter spatium of 'air'
      offs1.rx() += _spatium * 0.25;
      offs2.rx() -= _spatium * 0.25;

      // apply offsets: shorten first segment by x1 (and proportionally y) and adjust its length accordingly
      offs1.ry() = segm1->ipos2().y() * offs1.x() / segm1->ipos2().x();
      segm1->setPos(segm1->ipos() + offs1);
      segm1->setPos2(segm1->ipos2() - offs1);
      // adjust last segment length by x2 (and proportionally y)
      offs2.ry() = segm2->ipos2().y() * offs2.x() / segm2->ipos2().x();
      segm2->setPos2(segm2->ipos2() + offs2);

      for (SpannerSegment* segm : spannerSegments())
            static_cast<GlissandoSegment*>(segm)->layout();

      // compute glissando bbox as the bbox of the last segment, relative to the end anchor note
      QPointF anchor2PagePos = anchor2->pagePos();
      QPointF system2PagePos = cr2->segment()->system()->pagePos();
      QPointF anchor2SystPos = anchor2PagePos - system2PagePos;
      QRectF r = QRectF(anchor2SystPos - segm2->pos(), anchor2SystPos - segm2->pos() - segm2->pos2()).normalized();
      qreal lw = _spatium * lineWidth().val() * .5;
      setbbox(r.adjusted(-lw, -lw, lw, lw));
      }
Exemple #4
0
/*!
  Draw step function

  The direction of the steps depends on Inverted attribute.

  \param painter Painter
  \param xMap x map
  \param yMap y map
  \param canvasRect Contents rectangle of the canvas
  \param from index of the first point to be painted
  \param to index of the last point to be painted

  \sa CurveAttribute, setCurveAttribute(),
      draw(), drawCurve(), drawDots(), drawLines(), drawSticks()
*/
void QwtPlotCurve::drawSteps( QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    const QRectF &canvasRect, int from, int to ) const
{
    const bool doAlign = QwtPainter::roundingAlignment( painter );

    QPolygonF polygon( 2 * ( to - from ) + 1 );
    QPointF *points = polygon.data();

    bool inverted = orientation() == Qt::Vertical;
    if ( d_data->attributes & Inverted )
        inverted = !inverted;

    const QwtSeriesData<QPointF> *series = data();

    int i, ip;
    for ( i = from, ip = 0; i <= to; i++, ip += 2 )
    {
        const QPointF sample = series->sample( i );
        double xi = xMap.transform( sample.x() );
        double yi = yMap.transform( sample.y() );
        if ( doAlign )
        {
            xi = qRound( xi );
            yi = qRound( yi );
        }

        if ( ip > 0 )
        {
            const QPointF &p0 = points[ip - 2];
            QPointF &p = points[ip - 1];

            if ( inverted )
            {
                p.rx() = p0.x();
                p.ry() = yi;
            }
            else
            {
                p.rx() = xi;
                p.ry() = p0.y();
            }
        }

        points[ip].rx() = xi;
        points[ip].ry() = yi;
    }

    if ( d_data->paintAttributes & ClipPolygons )
    {
        qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF());
        const QRectF clipRect = canvasRect.adjusted(-pw, -pw, pw, pw);
        
        const QPolygonF clipped = QwtClipper::clipPolygonF( 
            clipRect, polygon, false );

        QwtPainter::drawPolyline( painter, clipped );
    }
    else
    {
        QwtPainter::drawPolyline( painter, polygon );
    }

    if ( d_data->brush.style() != Qt::NoBrush )
        fillCurve( painter, xMap, yMap, canvasRect, polygon );
}
/*!
  Draw a tube

  Builds 2 curves from the upper and lower limits of the intervals
  and draws them with the pen(). The area between the curves is
  filled with the brush().

  \param painter Painter
  \param xMap Maps x-values into pixel coordinates.
  \param yMap Maps y-values into pixel coordinates.
  \param canvasRect Contents rect of the canvas
  \param from Index of the first sample to be painted
  \param to Index of the last sample to be painted. If to < 0 the
         series will be painted to its last sample.

  \sa drawSeries(), drawSymbols()
*/
void QwtPlotIntervalCurve::drawTube( QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    const QRectF &canvasRect, int from, int to ) const
{
    const bool doAlign = QwtPainter::roundingAlignment( painter );

    painter->save();

    const size_t size = to - from + 1;
    QPolygonF polygon( 2 * size );
    QPointF *points = polygon.data();

    for ( uint i = 0; i < size; i++ )
    {
        QPointF &minValue = points[i];
        QPointF &maxValue = points[2 * size - 1 - i];

        const QwtIntervalSample intervalSample = sample( from + i );
        if ( orientation() == Qt::Vertical )
        {
            double x = xMap.transform( intervalSample.value );
            double y1 = yMap.transform( intervalSample.interval.minValue() );
            double y2 = yMap.transform( intervalSample.interval.maxValue() );
            if ( doAlign )
            {
                x = qRound( x );
                y1 = qRound( y1 );
                y2 = qRound( y2 );
            }

            minValue.rx() = x;
            minValue.ry() = y1;
            maxValue.rx() = x;
            maxValue.ry() = y2;
        }
        else
        {
            double y = yMap.transform( intervalSample.value );
            double x1 = xMap.transform( intervalSample.interval.minValue() );
            double x2 = xMap.transform( intervalSample.interval.maxValue() );
            if ( doAlign )
            {
                y = qRound( y );
                x1 = qRound( x1 );
                x2 = qRound( x2 );
            }

            minValue.rx() = x1;
            minValue.ry() = y;
            maxValue.rx() = x2;
            maxValue.ry() = y;
        }
    }

    if ( d_data->brush.style() != Qt::NoBrush )
    {
        painter->setPen( QPen( Qt::NoPen ) );
        painter->setBrush( d_data->brush );

        if ( d_data->paintAttributes & ClipPolygons )
        {
            const qreal m = 1.0;
            const QPolygonF p = QwtClipper::clipPolygonF( 
                canvasRect.adjusted(-m, -m, m, m), polygon, true );

            QwtPainter::drawPolygon( painter, p );
        }
        else
        {
            QwtPainter::drawPolygon( painter, polygon );
        }
    }

    if ( d_data->pen.style() != Qt::NoPen )
    {
        painter->setPen( d_data->pen );
        painter->setBrush( Qt::NoBrush );

        if ( d_data->paintAttributes & ClipPolygons )
        {
            qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF());
            const QRectF clipRect = canvasRect.adjusted(-pw, -pw, pw, pw);

            QPolygonF p;

            p.resize( size );
            qMemCopy( p.data(), points, size * sizeof( QPointF ) );
            p = QwtClipper::clipPolygonF( canvasRect, p );
            QwtPainter::drawPolyline( painter, p );

            p.resize( size );
            qMemCopy( p.data(), points + size, size * sizeof( QPointF ) );
            p = QwtClipper::clipPolygonF( canvasRect, p );
            QwtPainter::drawPolyline( painter, p );
        }
        else
        {
            QwtPainter::drawPolyline( painter, points, size );
            QwtPainter::drawPolyline( painter, points + size, size );
        }
    }

    painter->restore();
}
Exemple #6
0
/*!
  Draw a rectangular frame

  \param painter Painter
  \param rect Frame rectangle
  \param palette Palette
  \param foregroundRole Foreground role used for QFrame::Plain
  \param frameWidth Frame width
  \param midLineWidth Used for QFrame::Box
  \param frameStyle bitwise OR´ed value of QFrame::Shape and QFrame::Shadow
*/
void QwtPainter::drawFrame( QPainter *painter, const QRectF &rect,
    const QPalette &palette, QPalette::ColorRole foregroundRole,
    int frameWidth, int midLineWidth, int frameStyle )
{
    if ( frameWidth <= 0 || rect.isEmpty() )
        return;

    const int shadow = frameStyle & QFrame::Shadow_Mask;

    painter->save();

    if ( shadow == QFrame::Plain )
    {
        const QRectF outerRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 );
        const QRectF innerRect = outerRect.adjusted(
            frameWidth, frameWidth, -frameWidth, -frameWidth );

        QPainterPath path;
        path.addRect( outerRect );
        path.addRect( innerRect );

        painter->setPen( Qt::NoPen );
        painter->setBrush( palette.color( foregroundRole ) );

        painter->drawPath( path );
    }
    else
    {
        const int shape = frameStyle & QFrame::Shape_Mask;

        if ( shape == QFrame::Box )
        {
            const QRectF outerRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 );
            const QRectF midRect1 = outerRect.adjusted(
                frameWidth, frameWidth, -frameWidth, -frameWidth );
            const QRectF midRect2 = midRect1.adjusted(
                midLineWidth, midLineWidth, -midLineWidth, -midLineWidth );

            const QRectF innerRect = midRect2.adjusted(
                frameWidth, frameWidth, -frameWidth, -frameWidth );

            QPainterPath path1;
            path1.moveTo( outerRect.bottomLeft() );
            path1.lineTo( outerRect.topLeft() );
            path1.lineTo( outerRect.topRight() );
            path1.lineTo( midRect1.topRight() );
            path1.lineTo( midRect1.topLeft() );
            path1.lineTo( midRect1.bottomLeft() );

            QPainterPath path2;
            path2.moveTo( outerRect.bottomLeft() );
            path2.lineTo( outerRect.bottomRight() );
            path2.lineTo( outerRect.topRight() );
            path2.lineTo( midRect1.topRight() );
            path2.lineTo( midRect1.bottomRight() );
            path2.lineTo( midRect1.bottomLeft() );

            QPainterPath path3;
            path3.moveTo( midRect2.bottomLeft() );
            path3.lineTo( midRect2.topLeft() );
            path3.lineTo( midRect2.topRight() );
            path3.lineTo( innerRect.topRight() );
            path3.lineTo( innerRect.topLeft() );
            path3.lineTo( innerRect.bottomLeft() );

            QPainterPath path4;
            path4.moveTo( midRect2.bottomLeft() );
            path4.lineTo( midRect2.bottomRight() );
            path4.lineTo( midRect2.topRight() );
            path4.lineTo( innerRect.topRight() );
            path4.lineTo( innerRect.bottomRight() );
            path4.lineTo( innerRect.bottomLeft() );

            QPainterPath path5;
            path5.addRect( midRect1 );
            path5.addRect( midRect2 );

            painter->setPen( Qt::NoPen );

            QBrush brush1 = palette.dark().color();
            QBrush brush2 = palette.light().color();

            if ( shadow == QFrame::Raised )
                qSwap( brush1, brush2 );

            painter->setBrush( brush1 );
            painter->drawPath( path1 );
            painter->drawPath( path4 );

            painter->setBrush( brush2 );
            painter->drawPath( path2 );
            painter->drawPath( path3 );

            painter->setBrush( palette.mid() );
            painter->drawPath( path5 );
        }
#if 0
        // qDrawWinPanel doesn't result in something nice
        // on a scalable document like PDF. Better draw a
        // Panel.

        else if ( shape == QFrame::WinPanel )
        {
            painter->setRenderHint( QPainter::NonCosmeticDefaultPen, true );
            qDrawWinPanel ( painter, rect.toRect(), palette,
                frameStyle & QFrame::Sunken );
        }
        else if ( shape == QFrame::StyledPanel )
        {
        }
#endif
        else
        {
            const QRectF outerRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 );
            const QRectF innerRect = outerRect.adjusted(
                frameWidth - 1.0, frameWidth - 1.0,
                -( frameWidth - 1.0 ), -( frameWidth - 1.0 ) );

            QPainterPath path1;
            path1.moveTo( outerRect.bottomLeft() );
            path1.lineTo( outerRect.topLeft() );
            path1.lineTo( outerRect.topRight() );
            path1.lineTo( innerRect.topRight() );
            path1.lineTo( innerRect.topLeft() );
            path1.lineTo( innerRect.bottomLeft() );


            QPainterPath path2;
            path2.moveTo( outerRect.bottomLeft() );
            path2.lineTo( outerRect.bottomRight() );
            path2.lineTo( outerRect.topRight() );
            path2.lineTo( innerRect.topRight() );
            path2.lineTo( innerRect.bottomRight() );
            path2.lineTo( innerRect.bottomLeft() );

            painter->setPen( Qt::NoPen );

            QBrush brush1 = palette.dark().color();
            QBrush brush2 = palette.light().color();

            if ( shadow == QFrame::Raised )
                qSwap( brush1, brush2 );

            painter->setBrush( brush1 );
            painter->drawPath( path1 );

            painter->setBrush( brush2 );
            painter->drawPath( path2 );
        }

    }

    painter->restore();
}
void QwtPainter::drawRoundedFrame( QPainter *painter, 
    const QRectF &rect, double xRadius, double yRadius, 
    const QPalette &palette, int lineWidth, int frameStyle )
{
    painter->save();
    painter->setRenderHint( QPainter::Antialiasing, true );
    painter->setBrush( Qt::NoBrush );

    double lw2 = lineWidth * 0.5;
    QRectF r = rect.adjusted( lw2, lw2, -lw2, -lw2 );

    QPainterPath path;
    path.addRoundedRect( r, xRadius, yRadius );

    enum Style
    {
        Plain,
        Sunken,
        Raised
    };

    Style style = Plain;
    if ( (frameStyle & QFrame::Sunken) == QFrame::Sunken )
        style = Sunken;
    else if ( (frameStyle & QFrame::Raised) == QFrame::Raised )
        style = Raised;

    if ( style != Plain && path.elementCount() == 17 )
    {
        // move + 4 * ( cubicTo + lineTo )
        QPainterPath pathList[8];
        
        for ( int i = 0; i < 4; i++ )
        {
            const int j = i * 4 + 1;
            
            pathList[ 2 * i ].moveTo(
                path.elementAt(j - 1).x, path.elementAt( j - 1 ).y
            );  
            
            pathList[ 2 * i ].cubicTo(
                path.elementAt(j + 0).x, path.elementAt(j + 0).y,
                path.elementAt(j + 1).x, path.elementAt(j + 1).y,
                path.elementAt(j + 2).x, path.elementAt(j + 2).y );
                
            pathList[ 2 * i + 1 ].moveTo(
                path.elementAt(j + 2).x, path.elementAt(j + 2).y
            );  
            pathList[ 2 * i + 1 ].lineTo(
                path.elementAt(j + 3).x, path.elementAt(j + 3).y
            );  
        }   

        QColor c1( palette.color( QPalette::Dark ) );
        QColor c2( palette.color( QPalette::Light ) );

        if ( style == Raised )
            qSwap( c1, c2 );

        for ( int i = 0; i < 4; i++ )
        {
            QRectF r = pathList[2 * i].controlPointRect();

            QPen arcPen;
            arcPen.setWidth( lineWidth );

            QPen linePen;
            linePen.setWidth( lineWidth );

            switch( i )
            {
                case 0:
                {
                    arcPen.setColor( c1 );
                    linePen.setColor( c1 );
                    break;
                }
                case 1:
                {
                    QLinearGradient gradient;
                    gradient.setStart( r.topLeft() );
                    gradient.setFinalStop( r.bottomRight() );
                    gradient.setColorAt( 0.0, c1 );
                    gradient.setColorAt( 1.0, c2 );

                    arcPen.setBrush( gradient );
                    linePen.setColor( c2 );
                    break;
                }
                case 2:
                {
                    arcPen.setColor( c2 );
                    linePen.setColor( c2 );
                    break;
                }
                case 3:
                {
                    QLinearGradient gradient;

                    gradient.setStart( r.bottomRight() );
                    gradient.setFinalStop( r.topLeft() );
                    gradient.setColorAt( 0.0, c2 );
                    gradient.setColorAt( 1.0, c1 );

                    arcPen.setBrush( gradient );
                    linePen.setColor( c1 );
                    break;
                }
            }


            painter->setPen( arcPen );
            painter->drawPath( pathList[ 2 * i] );

            painter->setPen( linePen );
            painter->drawPath( pathList[ 2 * i + 1] );
        }
    }
    else
    {
        QPen pen( palette.color( QPalette::WindowText ), lineWidth );
        painter->setPen( pen );
        painter->drawPath( path );
    }

    painter->restore();
}
Exemple #8
0
bool ItemSpace::positionedProperly(const QRectF& itemGeom)
{
    QRectF fullGeom = itemGeom.adjusted(-placementSpacing, -placementSpacing, placementSpacing, placementSpacing);
    return (QRectF(QPointF(), workingGeom).contains(fullGeom));
}
Exemple #9
0
void ItemSpace::ItemGroup::Request::activate (ItemSpace *itemSpace, ItemGroup *group)
{
    // don't do anything if the group was already asked to move at
    // least as much as we ask
    if (group->m_largestPushRequested >= m_pushRequested) {
        return;
    }

    qreal largest = group->m_largestPushRequested;
    // record our request as the largest
    group->m_largestPushRequested = m_pushRequested;
    // don't do anything if the group already hit an unmovable obstacle
    if (group->m_pushAvailable < largest) {
        return;
    }

    // set the available push to our requested value
    // and limit it as obstacles are found
    group->m_pushAvailable = m_pushRequested;

    // look for obstacles for every item in the group
    for (int itemId = 0; itemId < group->m_groupItems.size(); itemId++) {
        ItemSpaceItem &item = group->m_groupItems[itemId];
        QRectF origGeom = item.lastGeometry;
        QRectF fullGeom = origGeom.adjusted(-itemSpace->shiftingSpacing, -itemSpace->shiftingSpacing,
                                            itemSpace->shiftingSpacing, itemSpace->shiftingSpacing);

        // limit push by screen boundaries
        if (!(itemSpace->m_power & PushOverBorder)) {
            qreal limit;
            switch (itemSpace->m_direction) {
                case DirLeft:
                    limit = origGeom.left() - itemSpace->screenSpacing;
                    break;
                case DirRight:
                    limit = itemSpace->workingGeom.width() - itemSpace->screenSpacing - origGeom.right();
                    break;
                case DirUp:
                    limit = origGeom.top() - itemSpace->screenSpacing;
                    break;
                case DirDown:
                    limit = itemSpace->workingGeom.height() - itemSpace->screenSpacing - origGeom.bottom();
                    break;
            }
            group->m_pushAvailable = qMax(qreal(0.0), qMin(group->m_pushAvailable, limit));
            if (group->m_pushAvailable == 0) {
                break;
            }
        }

        // limit push to not push the item away from its preferred position
        if (!(itemSpace->m_power & PushAwayFromPreferred) && item.pushBack) {
            QRectF preferredGeometry = QRectF(item.preferredPosition, item.lastGeometry.size());
            qreal limit;
            switch (itemSpace->m_direction) {
                case DirLeft:
                    limit = origGeom.left() - preferredGeometry.left();
                    break;
                case DirRight:
                    limit = -(origGeom.left() - preferredGeometry.left());
                    break;
                case DirUp:
                    limit = origGeom.top() - preferredGeometry.top();
                    break;
                case DirDown:
                    limit = -(origGeom.top() - preferredGeometry.top());
                    break;
            }
            limit = qMax(qreal(0.0), limit);
            group->m_pushAvailable = qMin(group->m_pushAvailable, limit);
            if (group->m_pushAvailable == 0) {
                break;
            }
        }

        // look for items in the way
        for (int testGroupId = 0; testGroupId < itemSpace->m_groups.size(); testGroupId++) {
            QList<int> asa;
            if (testGroupId == group->m_id || group->groupIsAbove(itemSpace, asa, testGroupId)) {
                continue;
            }
            ItemGroup &testGroup = itemSpace->m_groups[testGroupId];

            // calculate how much the offending group needs to be pushed
            qreal groupPush = 0;
            for (int testItemId = 0; testItemId < testGroup.m_groupItems.size(); testItemId++) {
                ItemSpaceItem &testItem = testGroup.m_groupItems[testItemId];

                QRectF newlyTakenSpace;
                qreal push;
                switch (itemSpace->m_direction) {
                case DirLeft:
                    newlyTakenSpace = QRectF(fullGeom.left() - group->m_pushAvailable, fullGeom.top(), group->m_pushAvailable, fullGeom.height());
                    push = testItem.lastGeometry.right() - newlyTakenSpace.left();
                    break;
                case DirRight:
                    newlyTakenSpace = QRectF(fullGeom.right(), fullGeom.top(), group->m_pushAvailable, fullGeom.height());
                    push = newlyTakenSpace.right() - testItem.lastGeometry.left();
                    break;
                case DirUp:
                    newlyTakenSpace = QRectF(fullGeom.left(), fullGeom.top() - group->m_pushAvailable, fullGeom.width(), group->m_pushAvailable);
                    push = testItem.lastGeometry.bottom() - newlyTakenSpace.top();
                    break;
                case DirDown:
                    newlyTakenSpace = QRectF(fullGeom.left(), fullGeom.bottom(), fullGeom.width(), group->m_pushAvailable);
                    push = newlyTakenSpace.bottom() - testItem.lastGeometry.top();
                    break;
                }

                // check if it is an obstacle
                if (testItem.lastGeometry.intersects(newlyTakenSpace)) {
                    groupPush = qMax(groupPush, push);
                }
            }

            if (groupPush == 0) {
                continue;
            }

            // post a move request to the obstacle
            if (!group->m_obstacles.contains(testGroupId)) {
                group->m_obstacles.append(testGroupId);
            }
            testGroup.addRequest(itemSpace, Request(group->m_id, group->m_pushAvailable, groupPush));

            // limit our push by how much the obstacle can actually move
            if (testGroup.m_pushAvailable < groupPush) {
                group->m_pushAvailable = qMax(qreal(0.0), group->m_pushAvailable - (groupPush - testGroup.m_pushAvailable));
                if (group->m_pushAvailable == 0) {
                    break;
                }
            }
        }
    }
}
void SceneImageExporter::GraphicsSceneToPrinter(
        QGraphicsScene *scene, QPrinter& printer,
        QString fileName, QString documentName __attribute__((unused)),
        bool bSizeToOneSheet)
{
    if (!fileName.isEmpty() && fileName != "" && fileName.endsWith(".pdf",Qt::CaseInsensitive))
    {
        printer.setOutputFormat(QPrinter::PdfFormat);
        printer.setOutputFileName(fileName);
    }

    // When printing, use full page mode, IE ignore hardware margins. It's up
    // to users to set them as they desire.
    printer.setFullPage(true);
    printer.setPaperSize(QSizeF(PrintingPreferences::prefs().selectedMeasure().width(),
                                PrintingPreferences::prefs().selectedMeasure().height()),
                         QPrinter::Millimeter);
    printer.setPageMargins(PrintingPreferences::prefs().leftMargin(),
                           PrintingPreferences::prefs().topMargin(),
                           PrintingPreferences::prefs().rightMargin(),
                           PrintingPreferences::prefs().bottomMargin(),
                           QPrinter::Millimeter);


    if (!bSizeToOneSheet) {

        //here, I print using selected sheets and divisions.
        QPainter painter(&printer);
        qreal left,top,right,bottom;
        printer.getPageMargins(&left,&top,&right,&bottom,QPrinter::DevicePixel);

        // get the FULL PAGE RECTANGLE and adjust margins.
        QRectF pageRect = printer.paperRect();
        pageRect.adjust(left,top,-right, -bottom);


        //get height/width page rect ratio
        double pageRatio = pageRect.width()/pageRect.height();

        //get scene rectangle and calculating pages.
        int stepY = PrintingPreferences::prefs().yDivisions();
        QRectF sceneRect = scene->sceneRect();
        double scene_dy = sceneRect.height()/( (double)stepY);
        double scene_dx = scene_dy * pageRatio;


        double o_scene_dx = scene_dx * 1.1;
        double o_scene_dy = scene_dy * 1.1;

        double o_rect_dx = pageRect.width() / 1.1;
        double o_rect_dy = pageRect.height() / 1.1;

        double odx = ( pageRect.width() -o_rect_dx)/2.0;
        double ody = (pageRect.height() - o_rect_dy)/ 2.0;

        QRectF pageRectInner = QRectF (pageRect.left() + odx,
                                       pageRect.top() + ody,
                                       o_rect_dx, o_rect_dy);

        int stepX = 1+ (int)(sceneRect.width() / scene_dx);

        //ok, calculated my boxes. NOW, let's print everything out.
        QColor transparent(0,0,0,0);
        QColor transBorder (0,0,0,128);
        QPen pen (transBorder);
        pen.setStyle(Qt::DotLine);
        QBrush brush(transparent);

        bool bNewPage = false;

        for (int y = 0; y < stepY; y++) {
            for (int x = 0; x < stepX; x++) {
                if (bNewPage)
                    printer.newPage();
                else
                    bNewPage = true;

                //I've already got my target rectangle
                QRectF sourceRect = QRectF (
                        sceneRect.left()+((double)x * scene_dx  + (o_scene_dx - scene_dx)/2.0 ),
                        sceneRect.top()+((double)y * scene_dy + (o_scene_dy - scene_dy)/2.0),
                        o_scene_dx,o_scene_dy);


                scene->render(&painter,pageRect, sourceRect);

                QBrush oldBrush = painter.brush();
                QPen oldPen = painter.pen();

                //qDebug() << "pageRect " << pageRect;
                //qDebug() << "pageRectInner " << pageRectInner;

                painter.setPen(pen);
                painter.setBrush(brush);
                painter.drawRect(pageRect);
                painter.drawRect(pageRectInner);

                painter.setPen(oldPen);
                painter.setBrush(oldBrush);

            }
        }
        painter.end();
    }
    else {
        QRectF sceneRect = scene->sceneRect();
        //qDebug() << "scene Rect:" << sceneRect;
        printer.setResolution(96);
        printer.setPaperSize(QSizeF (
                scene->sceneRect().width()+(76*2),
                scene->sceneRect().height()+(76*2)), QPrinter::DevicePixel);

        printer.setFullPage(true);
        printer.setPageMargins( 76.0,76.0,76.0,76.0, QPrinter::DevicePixel);
        QPainter painter(&printer);
        qreal left,top,right,bottom;
        printer.getPageMargins(&left,&top,&right,&bottom,QPrinter::DevicePixel);
        QRectF pageRect = printer.paperRect();

        //qDebug() << "pageRect: " << pageRect;

        pageRect = pageRect.adjusted(left,top,-right,-bottom);

        //qDebug() << "pageRect: " << pageRect;
        //qDebug() << "sceneRect: " << sceneRect;

        scene->render(&painter,pageRect, sceneRect, Qt::IgnoreAspectRatio);

        //qDebug() << left << "," << right << "," << top << "," << bottom;
        //qDebug() << printer.paperRect().left() << ","
        //        << printer.paperRect().width() << ","
        //        << printer.paperRect().top() << ","
        //        << printer.paperRect().height();
        pageRect = printer.pageRect();
        //qDebug() << pageRect.left() << ","
        //        << pageRect.width() << ","
        //        << pageRect.top() << ","
        //        << pageRect.height();

        QColor transparent(0,0,0,0);
        QColor transBorder (0,0,0,128);
        QPen pen (transBorder);
        pen.setStyle(Qt::DotLine);
        QBrush brush(transparent);

        painter.setPen(pen);
        painter.setBrush(brush);
        painter.drawRect(pageRect);
        painter.end();
    }
}
Exemple #11
0
void ManhattanStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
                                   QPainter *painter, const QWidget *widget) const
{
    if (!panelWidget(widget))
        return QProxyStyle::drawPrimitive(element, option, painter, widget);

    bool animating = (option->state & State_Animating);
    int state = option->state;
    QRect rect = option->rect;
    QRect oldRect;
    QRect newRect;
    if (widget && (element == PE_PanelButtonTool) && !animating) {
        QWidget *w = const_cast<QWidget *> (widget);
        int oldState = w->property("_q_stylestate").toInt();
        oldRect = w->property("_q_stylerect").toRect();
        newRect = w->rect();
        w->setProperty("_q_stylestate", (int)option->state);
        w->setProperty("_q_stylerect", w->rect());

        // Determine the animated transition
        bool doTransition = ((state & State_On)         != (oldState & State_On)     ||
                             (state & State_MouseOver)  != (oldState & State_MouseOver));
        if (oldRect != newRect)
        {
            doTransition = false;
            d->animator.stopAnimation(widget);
        }

        if (doTransition) {
            QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
            QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
            Animation *anim = d->animator.widgetAnimation(widget);
            QStyleOption opt = *option;
            opt.state = (QStyle::State)oldState;
            opt.state |= (State)State_Animating;
            startImage.fill(0);
            Transition *t = new Transition;
            t->setWidget(w);
            QPainter startPainter(&startImage);
            if (!anim) {
                drawPrimitive(element, &opt, &startPainter, widget);
            } else {
                anim->paint(&startPainter, &opt);
                d->animator.stopAnimation(widget);
            }
            QStyleOption endOpt = *option;
            endOpt.state |= (State)State_Animating;
            t->setStartImage(startImage);
            d->animator.startAnimation(t);
            endImage.fill(0);
            QPainter endPainter(&endImage);
            drawPrimitive(element, &endOpt, &endPainter, widget);
            t->setEndImage(endImage);
            if (oldState & State_MouseOver)
                t->setDuration(150);
            else
                t->setDuration(75);
            t->setStartTime(QTime::currentTime());
        }
    }

    switch (element) {
    case PE_IndicatorDockWidgetResizeHandle:
        painter->fillRect(option->rect, Utils::StyleHelper::borderColor());
        break;
    case PE_FrameDockWidget:
        QCommonStyle::drawPrimitive(element, option, painter, widget);
        break;
    case PE_PanelLineEdit:
        {
            painter->save();

            // Fill the line edit background
            QRect filledRect = option->rect.adjusted(1, 1, -1, -1);
            painter->setBrushOrigin(filledRect.topLeft());
            painter->fillRect(filledRect, option->palette.base());

            if (option->state & State_Enabled)
                Utils::StyleHelper::drawCornerImage(d->lineeditImage, painter, option->rect, 5, 5, 5, 5);
            else
                Utils::StyleHelper::drawCornerImage(d->lineeditImage_disabled, painter, option->rect, 5, 5, 5, 5);

            if (option->state & State_HasFocus || option->state & State_MouseOver) {
                QColor hover = Utils::StyleHelper::baseColor();
                if (state & State_HasFocus)
                    hover.setAlpha(100);
                else
                    hover.setAlpha(50);

                painter->setPen(QPen(hover, 1));
                painter->drawRect(option->rect.adjusted(1, 1, -2 ,-2));
            }
            painter->restore();
        }
        break;

    case PE_FrameStatusBarItem:
        break;

    case PE_PanelButtonTool: {
            Animation *anim = d->animator.widgetAnimation(widget);
            if (!animating && anim) {
                anim->paint(painter, option);
            } else {
                bool pressed = option->state & State_Sunken || option->state & State_On;
                QColor shadow(0, 0, 0, 30);
                painter->setPen(shadow);
                if (pressed) {
                    QColor shade(0, 0, 0, 40);
                    painter->fillRect(rect, shade);
                    painter->drawLine(rect.topLeft() + QPoint(1, 0), rect.topRight() - QPoint(1, 0));
                    painter->drawLine(rect.topLeft(), rect.bottomLeft());
                    painter->drawLine(rect.topRight(), rect.bottomRight());
                   // painter->drawLine(rect.bottomLeft()  + QPoint(1, 0), rect.bottomRight()  - QPoint(1, 0));
                    QColor highlight(255, 255, 255, 30);
                    painter->setPen(highlight);
                }
                else if (option->state & State_Enabled &&
                         option->state & State_MouseOver) {
                    QColor lighter(255, 255, 255, 37);
                    painter->fillRect(rect, lighter);
                }
                if (option->state & State_HasFocus && (option->state & State_KeyboardFocusChange)) {
                    QColor highlight = option->palette.highlight().color();
                    highlight.setAlphaF(0.4);
                    painter->setPen(QPen(highlight.lighter(), 1));
                    highlight.setAlphaF(0.3);
                    painter->setBrush(highlight);
                    painter->setRenderHint(QPainter::Antialiasing);
                    QRectF rect = option->rect;
                    rect.translate(0.5, 0.5);
                    painter->drawRoundedRect(rect.adjusted(2, 2, -3, -3), 2, 2);
                }
           }
        }
        break;

    case PE_PanelStatusBar:
        {
            painter->save();
            QLinearGradient grad(option->rect.topLeft(), QPoint(rect.center().x(), rect.bottom()));
            QColor startColor = Utils::StyleHelper::shadowColor().darker(164);
            QColor endColor = Utils::StyleHelper::baseColor().darker(130);
            grad.setColorAt(0, startColor);
            grad.setColorAt(1, endColor);
            painter->fillRect(option->rect, grad);
            painter->setPen(QColor(255, 255, 255, 60));
            painter->drawLine(rect.topLeft() + QPoint(0,1),
                              rect.topRight()+ QPoint(0,1));
            painter->setPen(Utils::StyleHelper::borderColor().darker(110));
            painter->drawLine(rect.topLeft(), rect.topRight());
            painter->restore();
        }
        break;

    case PE_IndicatorToolBarSeparator:
        {
            QColor separatorColor = Utils::StyleHelper::borderColor();
            separatorColor.setAlpha(100);
            painter->setPen(separatorColor);
            const int margin = 6;
            if (option->state & State_Horizontal) {
                const int offset = rect.width()/2;
                painter->drawLine(rect.bottomLeft().x() + offset,
                            rect.bottomLeft().y() - margin,
                            rect.topLeft().x() + offset,
                            rect.topLeft().y() + margin);
            } else { //Draw vertical separator
                const int offset = rect.height()/2;
                painter->setPen(QPen(option->palette.background().color().darker(110)));
                painter->drawLine(rect.topLeft().x() + margin ,
                            rect.topLeft().y() + offset,
                            rect.topRight().x() - margin,
                            rect.topRight().y() + offset);
            }
        }
        break;

    case PE_IndicatorToolBarHandle:
        {
            bool horizontal = option->state & State_Horizontal;
            painter->save();
            QPainterPath path;
            int x = option->rect.x() + (horizontal ? 2 : 6);
            int y = option->rect.y() + (horizontal ? 6 : 2);
            static const int RectHeight = 2;
            if (horizontal) {
                while (y < option->rect.height() - RectHeight - 6) {
                    path.moveTo(x, y);
                    path.addRect(x, y, RectHeight, RectHeight);
                    y += 6;
                }
            } else {
                while (x < option->rect.width() - RectHeight - 6) {
                    path.moveTo(x, y);
                    path.addRect(x, y, RectHeight, RectHeight);
                    x += 6;
                }
            }

            painter->setPen(Qt::NoPen);
            QColor dark = Utils::StyleHelper::borderColor();
            dark.setAlphaF(0.4);

            QColor light = Utils::StyleHelper::baseColor();
            light.setAlphaF(0.4);

            painter->fillPath(path, light);
            painter->save();
            painter->translate(1, 1);
            painter->fillPath(path, dark);
            painter->restore();
            painter->translate(3, 3);
            painter->fillPath(path, light);
            painter->translate(1, 1);
            painter->fillPath(path, dark);
            painter->restore();
        }
        break;
    case PE_IndicatorArrowUp:
    case PE_IndicatorArrowDown:
    case PE_IndicatorArrowRight:
    case PE_IndicatorArrowLeft:
        {
            Utils::StyleHelper::drawArrow(element, painter, option);
        }
        break;

    default:
        QProxyStyle::drawPrimitive(element, option, painter, widget);
        break;
    }
}
QRectF MapObjectLabel::boundingRect() const
{
    return mBoundingRect.adjusted(0, 0, 1, 1);
}
// if painter is nullptr, the method calculate the bounding rectangle of the text and save it to textRect
void FolderItemDelegate::drawText(QPainter* painter, QStyleOptionViewItemV4& opt, QRectF& textRect) const {
  QTextLayout layout(opt.text, opt.font);
  QTextOption textOption;
  textOption.setAlignment(opt.displayAlignment);
  textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
  textOption.setTextDirection(opt.direction);
  layout.setTextOption(textOption);
  qreal height = 0;
  qreal width = 0;
  int visibleLines = 0;
  layout.beginLayout();
  QString elidedText;
  textRect.adjust(2, 2, -2, -2); // a 2-px margin is considered at FolderView::updateGridSize()
  for(;;) {
    QTextLine line = layout.createLine();
    if(!line.isValid())
      break;
    line.setLineWidth(textRect.width());
    height += opt.fontMetrics.leading();
    line.setPosition(QPointF(0, height));
    if((height + line.height() + textRect.y()) > textRect.bottom()) {
      // if part of this line falls outside the textRect, ignore it and quit.
      QTextLine lastLine = layout.lineAt(visibleLines - 1);
      elidedText = opt.text.mid(lastLine.textStart());
      elidedText = opt.fontMetrics.elidedText(elidedText, opt.textElideMode, textRect.width());
      if(visibleLines == 1) // this is the only visible line
        width = textRect.width();
      break;
    }
    height += line.height();
    width = qMax(width, line.naturalTextWidth());
    ++ visibleLines;
  }
  layout.endLayout();
  width = qMax(width, (qreal)opt.fontMetrics.width(elidedText));

  // draw background for selected item
  QRectF boundRect = layout.boundingRect();
  //qDebug() << "bound rect: " << boundRect << "width: " << width;
  boundRect.setWidth(width);
  boundRect.setHeight(height);
  boundRect.moveTo(textRect.x() + (textRect.width() - width)/2, textRect.y());

  QRectF selRect = boundRect.adjusted(-2, -2, 2, 2);

  if(!painter) { // no painter, calculate the bounding rect only
    textRect = selRect;
    return;
  }

  QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
  if(opt.state & QStyle::State_Selected) {
    painter->fillRect(selRect, opt.palette.highlight());
    painter->setPen(opt.palette.color(cg, QPalette::HighlightedText));
  }
  else
    painter->setPen(opt.palette.color(cg, QPalette::Text));

  // draw text
  for(int i = 0; i < visibleLines; ++i) {
    QTextLine line = layout.lineAt(i);
    if(i == (visibleLines - 1) && !elidedText.isEmpty()) { // the last line, draw elided text
      QPointF pos(boundRect.x() + line.position().x(), boundRect.y() + line.y() + line.ascent());
      painter->drawText(pos, elidedText);
    }
    else {
      line.draw(painter, textRect.topLeft());
    }
  }

  if(opt.state & QStyle::State_HasFocus) {
    // draw focus rect
    QStyleOptionFocusRect o;
    o.QStyleOption::operator=(opt);
    o.rect = selRect.toRect(); // subElementRect(SE_ItemViewItemFocusRect, vopt, widget);
    o.state |= QStyle::State_KeyboardFocusChange;
    o.state |= QStyle::State_Item;
    QPalette::ColorGroup cg = (opt.state & QStyle::State_Enabled)
                  ? QPalette::Normal : QPalette::Disabled;
    o.backgroundColor = opt.palette.color(cg, (opt.state & QStyle::State_Selected)
                                  ? QPalette::Highlight : QPalette::Window);
    if (const QWidget* widget = opt.widget) {
      QStyle* style = widget->style() ? widget->style() : qApp->style();
      style->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter, widget);
    }
  }
}
Exemple #14
0
QRectF Clef::boundingRect()
{
    qreal hpw = m_pen->width() / 2;
    QRectF rect = getRectForClef();
    return rect.adjusted( -hpw, -hpw, hpw, hpw );
}
void tst_QPixmapFilter::dropShadowBoundingRectFor()
{
    QPixmapDropShadowFilter filter;
    filter.setBlurRadius(0);

    QCOMPARE(filter.blurRadius(), 0.);

    const QRectF rect1(0, 0, 50, 50);
    const QRectF rect2(30, 20, 10, 40);
    const QRectF rect3(2.2, 6.3, 11.4, 47.5);

    filter.setOffset(QPointF(0,0));
    QCOMPARE(filter.boundingRectFor(rect1), rect1);
    QCOMPARE(filter.boundingRectFor(rect2), rect2);
    QCOMPARE(filter.boundingRectFor(rect3), rect3);

    filter.setOffset(QPointF(1,1));
    QCOMPARE(filter.offset(), QPointF(1, 1));
    QCOMPARE(filter.boundingRectFor(rect1), rect1.adjusted(0, 0, 1, 1));
    QCOMPARE(filter.boundingRectFor(rect2), rect2.adjusted(0, 0, 1, 1));
    QCOMPARE(filter.boundingRectFor(rect3), rect3.adjusted(0, 0, 1, 1));

    filter.setOffset(QPointF(-1,-1));
    QCOMPARE(filter.boundingRectFor(rect1), rect1.adjusted(-1, -1, 0, 0));
    QCOMPARE(filter.boundingRectFor(rect2), rect2.adjusted(-1, -1, 0, 0));
    QCOMPARE(filter.boundingRectFor(rect3), rect3.adjusted(-1, -1, 0, 0));

    filter.setBlurRadius(2);
    filter.setOffset(QPointF(0,0));
    qreal delta = 2;
    QCOMPARE(filter.boundingRectFor(rect1), rect1.adjusted(-delta, -delta, delta, delta));
    QCOMPARE(filter.boundingRectFor(rect2), rect2.adjusted(-delta, -delta, delta, delta));
    QCOMPARE(filter.boundingRectFor(rect3), rect3.adjusted(-delta, -delta, delta, delta));

    filter.setOffset(QPointF(1,1));
    QCOMPARE(filter.boundingRectFor(rect1), rect1.adjusted(-delta + 1, -delta + 1, delta + 1, delta + 1));
    QCOMPARE(filter.boundingRectFor(rect2), rect2.adjusted(-delta + 1, -delta + 1, delta + 1, delta + 1));
    QCOMPARE(filter.boundingRectFor(rect3), rect3.adjusted(-delta + 1, -delta + 1, delta + 1, delta + 1));

    filter.setOffset(QPointF(-10,-10));
    QCOMPARE(filter.boundingRectFor(rect1), rect1.adjusted(-delta - 10, -delta - 10, 0, 0));
    QCOMPARE(filter.boundingRectFor(rect2), rect2.adjusted(-delta - 10, -delta - 10, 0, 0));
    QCOMPARE(filter.boundingRectFor(rect3), rect3.adjusted(-delta - 10, -delta - 10, 0, 0));
}
/*!
  Draw the shape item

  \param painter Painter
  \param xMap X-Scale Map
  \param yMap Y-Scale Map
  \param canvasRect Contents rect of the plot canvas
*/
void QwtPlotShapeItem::draw( QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    const QRectF &canvasRect ) const
{
    if ( d_data->shape.isEmpty() )
        return;

    if ( d_data->pen.style() == Qt::NoPen
        && d_data->brush.style() == Qt::NoBrush )
    {
        return;
    }

    const QRectF cr = QwtScaleMap::invTransform(
        xMap, yMap, canvasRect.toRect() );

    const QRectF &br = d_data->boundingRect;

    if ( ( br.left() > cr.right() ) || ( br.right() < cr.left() )
        || ( br.top() > cr.bottom() ) || ( br.bottom() < cr.top() ) )
    {
        // outside the visisble area
        return;
    }

    const bool doAlign = QwtPainter::roundingAlignment( painter );

    QPainterPath path = qwtTransformPath( xMap, yMap,
        d_data->shape, doAlign );

    if ( testPaintAttribute( QwtPlotShapeItem::ClipPolygons ) )
    {
        const qreal pw = QwtPainter::effectivePenWidth( painter->pen() );
        const QRectF clipRect = canvasRect.adjusted( -pw, -pw, pw, pw );

        QPainterPath clippedPath;
        clippedPath.setFillRule( path.fillRule() );

        QList<QPolygonF> polygons = path.toSubpathPolygons();
        for ( int i = 0; i < polygons.size(); i++ )
        {
            QwtClipper::clipPolygonF( clipRect, polygons[i], true );
            clippedPath.addPolygon( polygons[i] );

        }

        path = clippedPath;
    }

    if ( d_data->renderTolerance > 0.0 )
    {
        QwtWeedingCurveFitter fitter( d_data->renderTolerance );

        QPainterPath fittedPath;
        fittedPath.setFillRule( path.fillRule() );

        const QList<QPolygonF> polygons = path.toSubpathPolygons();
        for ( int i = 0; i < polygons.size(); i++ )
            fittedPath.addPolygon( fitter.fitCurve( polygons[ i ] ) );

        path = fittedPath;
    }

    painter->setPen( d_data->pen );
    painter->setBrush( d_data->brush );

    painter->drawPath( path );
}
/*!
  Draw the shape item

  \param painter Painter
  \param xMap X-Scale Map
  \param yMap Y-Scale Map
  \param canvasRect Contents rect of the plot canvas
*/
void QwtPlotShapeItem::draw( QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    const QRectF &canvasRect ) const
{
    if ( d_data->shape.isEmpty() )
        return;

    if ( d_data->pen.style() == Qt::NoPen 
        && d_data->brush.style() == Qt::NoBrush )
    {
        return;
    }

    const QRectF cRect = QwtScaleMap::invTransform(
        xMap, yMap, canvasRect.toRect() );

    if ( d_data->boundingRect.intersects( cRect ) )
    {
        const bool doAlign = QwtPainter::roundingAlignment( painter );

        QPainterPath path = qwtTransformPath( xMap, yMap, 
            d_data->shape, doAlign );

        if ( testPaintAttribute( QwtPlotShapeItem::ClipPolygons ) )
        {
            qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF());
            QRectF clipRect = canvasRect.adjusted( -pw, -pw, pw, pw );

            QPainterPath clippedPath;
            clippedPath.setFillRule( path.fillRule() );

            const QList<QPolygonF> polygons = path.toSubpathPolygons();
            for ( int i = 0; i < polygons.size(); i++ )
            {
                const QPolygonF p = QwtClipper::clipPolygonF(
                    clipRect, polygons[i], true );

                clippedPath.addPolygon( p );

            }

            path = clippedPath;
        }

        if ( d_data->renderTolerance > 0.0 )
        {
            QwtWeedingCurveFitter fitter( d_data->renderTolerance );

            QPainterPath fittedPath;
            fittedPath.setFillRule( path.fillRule() );

            const QList<QPolygonF> polygons = path.toSubpathPolygons();
            for ( int i = 0; i < polygons.size(); i++ )
                fittedPath.addPolygon( fitter.fitCurve( polygons[ i ] ) );

            path = fittedPath;
        }

        painter->setPen( d_data->pen );
        painter->setBrush( d_data->brush );

        painter->drawPath( path );
    }
}
void PhasesSceneArrowItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);
    
    painter->setRenderHint(QPainter::Antialiasing);
    QRectF rect = boundingRect();
    
    //painter->fillRect(rect, QColor(0, 255, 0, 30));
    
    int penWidth = 1;
    QColor color = mEditing ? QColor(77, 180, 62) : QColor(0, 0, 0);
    //if(isUnderMouse())
    //   color = QColor(30, 50, 150);
    
    painter->setPen(QPen(color, penWidth, mEditing ? Qt::DashLine : Qt::SolidLine));
    painter->drawLine(mXStart, mYStart, mXEnd, mYEnd);
    
    // arrows
    
    float angle_rad = atanf(rect.width() / rect.height());
    float angle_deg = angle_rad * 180. / M_PI;
    
    QPainterPath path;
    int arrow_w = 10;
    int arrow_l = 15;
    path.moveTo(-arrow_w/2, arrow_l/2);
    path.lineTo(arrow_w/2, arrow_l/2);
    path.lineTo(0, -arrow_l/2);
    path.closeSubpath();
    
    float posX = rect.width()/2;
    float posY = rect.height()/2;
    float posX1 = rect.width()/3;
    float posX2 = 2*rect.width()/3;
    float posY1 = rect.height()/3;
    float posY2 = 2*rect.height()/3;
    
    if(mXStart < mXEnd && mYStart > mYEnd)
    {
        if(mConstraint->mGammaType == PhaseConstraint::eGammaUnknown)
        {
            painter->save();
            painter->translate(rect.x() + posX, rect.y() + posY);
            painter->rotate(angle_deg);
            painter->fillPath(path, color);
            painter->restore();
        }
        else
        {
            painter->save();
            painter->translate(rect.x() + posX1, rect.y() + posY2);
            painter->rotate(angle_deg);
            painter->fillPath(path, color);
            painter->restore();
            
            painter->save();
            painter->translate(rect.x() + posX2, rect.y() + posY1);
            painter->rotate(angle_deg);
            painter->fillPath(path, color);
            painter->restore();
        }
    }
    else if(mXStart < mXEnd && mYStart < mYEnd)
    {
        if(mConstraint->mGammaType == PhaseConstraint::eGammaUnknown)
        {
            painter->save();
            painter->translate(rect.x() + posX, rect.y() + posY);
            painter->rotate(180 - angle_deg);
            painter->fillPath(path, color);
            painter->restore();
        }
        else
        {
            painter->save();
            painter->translate(rect.x() + posX1, rect.y() + posY1);
            painter->rotate(180 - angle_deg);
            painter->fillPath(path, color);
            painter->restore();
            
            painter->save();
            painter->translate(rect.x() + posX2, rect.y() + posY2);
            painter->rotate(180 - angle_deg);
            painter->fillPath(path, color);
            painter->restore();
        }
    }
    else if(mXStart > mXEnd && mYStart < mYEnd)
    {
        if(mConstraint->mGammaType == PhaseConstraint::eGammaUnknown)
        {
            painter->save();
            painter->translate(rect.x() + posX, rect.y() + posY);
            painter->rotate(180 + angle_deg);
            painter->fillPath(path, color);
            painter->restore();
        }
        else
        {
            painter->save();
            painter->translate(rect.x() + posX2, rect.y() + posY1);
            painter->rotate(180 + angle_deg);
            painter->fillPath(path, color);
            painter->restore();
            
            painter->save();
            painter->translate(rect.x() + posX1, rect.y() + posY2);
            painter->rotate(180 + angle_deg);
            painter->fillPath(path, color);
            painter->restore();
        }
    }
    else if(mXStart > mXEnd && mYStart > mYEnd)
    {
        if(mConstraint->mGammaType == PhaseConstraint::eGammaUnknown)
        {
            painter->save();
            painter->translate(rect.x() + rect.width()/2, rect.y() + rect.height()/2);
            painter->rotate(-angle_deg);
            painter->fillPath(path, color);
            painter->restore();
        }
        else
        {
            painter->save();
            painter->translate(rect.x() + 2*rect.width()/3, rect.y() + 2*rect.height()/3);
            painter->rotate(-angle_deg);
            painter->fillPath(path, color);
            painter->restore();
            
            painter->save();
            painter->translate(rect.x() + rect.width()/3, rect.y() + rect.height()/3);
            painter->rotate(-angle_deg);
            painter->fillPath(path, color);
            painter->restore();
        }
    }
    
    // Bubble
    
    switch(mConstraint->mGammaType)
    {
        case PhaseConstraint::eGammaUnknown:
        {
            break;
        }
        case PhaseConstraint::eGammaFixed:
        {
            break;
        }
        case PhaseConstraint::eGammaRange:
        {
            QFont font = painter->font();
            font.setPointSizeF(pointSize(11));
            painter->setFont(font);
            QRectF r = getBubbleRect();
            
            painter->setPen(color);
            painter->setBrush(Qt::white);
            painter->drawRoundedRect(r, 5, 5);
            
            //painter->setPen(QColor(120, 120, 120));
            painter->drawText(r.adjusted(0, 0, 0, -r.height()/2), Qt::AlignCenter, QString::number(mConstraint->mGammaMin));
            painter->drawText(r.adjusted(0, r.height()/2, 0, 0), Qt::AlignCenter, QString::number(mConstraint->mGammaMax));
            painter->drawLine(r.x() + 4, r.y() + r.height()/2, r.x() + r.width() - 4, r.y() + r.height()/2);
            break;
        }
        default:
            break;
    }
}
/*!
  Render the canvas into a given rectangle.

  \param plot Plot widget
  \param painter Painter
  \param map Maps mapping between plot and paint device coordinates
  \param canvasRect Canvas rectangle
*/
void QwtPlotRenderer::renderCanvas( const QwtPlot *plot,
    QPainter *painter, const QRectF &canvasRect, 
    const QwtScaleMap *map ) const
{
    painter->save();

    QPainterPath clipPath;

    QRectF r = canvasRect.adjusted( 0.0, 0.0, -1.0, -1.0 );

    if ( d_data->layoutFlags & FrameWithScales )
    {
        r.adjust( -1.0, -1.0, 1.0, 1.0 );
        painter->setPen( QPen( Qt::black ) );

        if ( !( d_data->discardFlags & DiscardCanvasBackground ) )
        {
            const QBrush bgBrush =
                plot->canvas()->palette().brush( plot->backgroundRole() );
            painter->setBrush( bgBrush );
        }

        QwtPainter::drawRect( painter, r );
    }
    else
    {
        if ( !( d_data->discardFlags & DiscardCanvasBackground ) )
        {
            qwtRenderBackground( painter, r, plot->canvas() );

            if ( plot->canvas()->testAttribute( Qt::WA_StyledBackground ) )
            {
                // The clip region is calculated in integers
                // To avoid too much rounding errors better
                // calculate it in target device resolution
                // TODO ...

                int x1 = qCeil( canvasRect.left() );
                int x2 = qFloor( canvasRect.right() );
                int y1 = qCeil( canvasRect.top() );
                int y2 = qFloor( canvasRect.bottom() );

                clipPath = plot->canvas()->borderPath( 
                    QRect( x1, y1, x2 - x1 - 1, y2 - y1 - 1 ) );
            }
        }
    }

    painter->restore();

    painter->save();

    if ( clipPath.isEmpty() )
        painter->setClipRect( canvasRect );
    else
        painter->setClipPath( clipPath );

    plot->drawItems( painter, canvasRect, map );

    painter->restore();
}
void QcMultiSlider::paintEvent( QPaintEvent *e )
{
  using namespace QtCollider::Style;
  using QtCollider::Style::Ellipse;
  using QtCollider::Style::RoundRect;

  Q_UNUSED(e);
  QPainter p(this);
  p.setRenderHint( QPainter::Antialiasing, true );

  RoundRect frame(rect(), 2);
  drawSunken( &p, palette(), frame, background(), hasFocus() ? focusColor() : QColor() );

  if( !_values.count() ) return;

  p.setRenderHint( QPainter::Antialiasing, false );

  bool horiz = ort == Qt::Horizontal;

  QRect bounds( contentsRect() );

  p.setClipRect( bounds );

  if( horiz ) {
    p.translate( bounds.topLeft() );
    p.rotate(90);
    p.scale(1.0, -1.0);
    bounds.setSize( QSize( bounds.height(), bounds.width() ) );
  }
  else {
    p.translate( bounds.left(), bounds.top() + bounds.height() );
    p.scale(1.0, -1.0);
  }

  int count = _values.count() - startIndex;
  qreal spacing, width, yscale;

  spacing = elastic ? (qreal) bounds.width() / count : thumbSize.width() + gap;
  width = elastic ? qMin( spacing, (qreal) thumbSize.width() ) : thumbSize.width();
  yscale = bounds.height();
  if( !isFilled ) yscale -= thumbSize.height();

  const QColor & fillClr = fillColor();

  // selection

  if( highlight ) {
    int i = _currentIndex - startIndex;
    int c = qMin( count - i, _selectionSize );
    if(c) {
      QRect r;
      r.setHeight( bounds.height() );
      r.setWidth( c * spacing );
      r.moveLeft( i * spacing );

      QColor hlColor = fillClr;
      hlColor.setAlpha( 70 );
      p.fillRect( r, hlColor );
    }
  }

  QPen pen;
  pen.setColor(strokeColor());
  pen.setWidth(0);
  p.setPen(pen);

  // lines

  if( drawLines ) {
    bool fill = isFilled & !drawRects;

    p.save();

    p.setRenderHint( QPainter::Antialiasing, true );
    p.translate( spacing * 0.5, isFilled ? 0.0 : thumbSize.height() * 0.5 );
    p.scale( 1.0, (qreal) yscale );
    if( fill ) p.setBrush( fillClr );

    QPainterPath path;

    // value line

    path.moveTo( 0, _values[startIndex] );
    for( int i = 1; i < count; ++i )
      path.lineTo( (qreal) i * spacing, _values[i + startIndex] );

    // reference line

    int refcount = _ref.count() - startIndex;
    if( refcount > 0 || fill ) {
      qreal x, y;
      int i = count - 1;

      x = i * spacing;
      y = i < refcount ? _ref[i + startIndex] : 0.f;
      if( fill ) path.lineTo(x, y);
      else path.moveTo(x, y);

      while( --i >= 0 ) {
        x = i * spacing;
        y = i < refcount ? _ref[i + startIndex] : 0.f;
        path.lineTo(x, y);
      }

      if( fill ) path.closeSubpath();
    }

    p.drawPath( path );

    p.restore();
  }

  // rects

  if( drawRects ) {
    p.setRenderHint( QPainter::Antialiasing, false );
    p.translate( (spacing - width) * 0.5, 0 );
    p.setBrush( fillClr );

    QRectF r;
    r.setWidth( width );

    if( isFilled ) {
      int refcount = _ref.count() - startIndex;
      for( int i = 0; i < count; ++i ) {
        int ref = (i < refcount ? _ref[i + startIndex] : 0.f) * yscale;
        int val = _values[i + startIndex] * yscale;
        r.moveLeft( i * spacing );
        r.moveTop( ref );
        r.setHeight( val - ref );
        if(horiz) p.drawRect(r.normalized().adjusted(0,0,-1,-1));
        else p.drawRect(r.normalized().adjusted(0,1,-1,0));
      }
    }
    else {
      r.setHeight( thumbSize.height() );
      for( int i = 0; i < count; ++i ) {
        r.moveLeft( i * spacing );
        r.moveTop( _values[i + startIndex] * yscale );
        if(horiz) p.drawRect(r.adjusted(0,0,-1,-1));
        else p.drawRect(r.adjusted(0,1,-1,0));
      }
    }
  }
}
Exemple #21
0
/*!
  \brief Draw lines

  If the CurveAttribute Fitted is enabled a QwtCurveFitter tries
  to interpolate/smooth the curve, before it is painted.

  \param painter Painter
  \param xMap x map
  \param yMap y map
  \param canvasRect Contents rectangle of the canvas
  \param from index of the first point to be painted
  \param to index of the last point to be painted

  \sa setCurveAttribute(), setCurveFitter(), draw(),
      drawLines(), drawDots(), drawSteps(), drawSticks()
*/
void QwtPlotCurve::drawLines( QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    const QRectF &canvasRect, int from, int to ) const
{
    if ( from > to )
        return;

    const bool doAlign = QwtPainter::roundingAlignment( painter );
    const bool doFit = ( d_data->attributes & Fitted ) && d_data->curveFitter;
    const bool doFill = ( d_data->brush.style() != Qt::NoBrush )
            && ( d_data->brush.color().alpha() > 0 );

    QRectF clipRect;
    if ( d_data->paintAttributes & ClipPolygons )
    {
        qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF());
        clipRect = canvasRect.adjusted(-pw, -pw, pw, pw);
    }

    bool doIntegers = false;

#if QT_VERSION < 0x040800

    // For Qt <= 4.7 the raster paint engine is significantly faster
    // for rendering QPolygon than for QPolygonF. So let's
    // see if we can use it.

    if ( painter->paintEngine()->type() == QPaintEngine::Raster )
    {
        // In case of filling or fitting performance doesn't count
        // because both operations are much more expensive
        // then drawing the polyline itself

        if ( !doFit && !doFill )
            doIntegers = true; 
    }
#endif

    const bool noDuplicates = d_data->paintAttributes & FilterPoints;

    QwtPointMapper mapper;
    mapper.setFlag( QwtPointMapper::RoundPoints, doAlign );
    mapper.setFlag( QwtPointMapper::WeedOutPoints, noDuplicates );
    mapper.setBoundingRect( canvasRect );

    if ( doIntegers )
    {
        QPolygon polyline = mapper.toPolygon( 
            xMap, yMap, data(), from, to );

        if ( d_data->paintAttributes & ClipPolygons )
        {
            polyline = QwtClipper::clipPolygon( 
                clipRect.toAlignedRect(), polyline, false );
        }

        QwtPainter::drawPolyline( painter, polyline );
    }
    else
    {
        QPolygonF polyline = mapper.toPolygonF( xMap, yMap, data(), from, to );

        if ( doFit )
            polyline = d_data->curveFitter->fitCurve( polyline );

        if ( doFill )
        {
            if ( painter->pen().style() != Qt::NoPen )
            {
                // here we are wasting memory for the filled copy,
                // do polygon clipping twice etc .. TODO

                QPolygonF filled = polyline;
                fillCurve( painter, xMap, yMap, canvasRect, filled );
                filled.clear();

                if ( d_data->paintAttributes & ClipPolygons )
                {
                    polyline = QwtClipper::clipPolygonF( 
                        clipRect, polyline, false );
                }

                QwtPainter::drawPolyline( painter, polyline );
            }
            else
            {
                fillCurve( painter, xMap, yMap, canvasRect, polyline );
            }
        }
        else
        {
            if ( d_data->paintAttributes & ClipPolygons )
            {
                polyline = QwtClipper::clipPolygonF(
                    clipRect, polyline, false );
            }

            QwtPainter::drawPolyline( painter, polyline );
        }
    }
}
void CanvasMode_EditMeshGradient::keyPressEvent(QKeyEvent *e)
{
    if (m_selectedMeshPoints.count() == 0)
        return;
    int kk = e->key();
    if (m_keyRepeat)
        return;
    m_keyRepeat = true;
    e->accept();
    Qt::KeyboardModifiers buttonModifiers = e->modifiers();
    if ((!m_view->m_ScMW->zoomSpinBox->hasFocus()) && (!m_view->m_ScMW->pageSelector->hasFocus()))
    {
        if (m_doc->m_Selection->count() != 0)
        {
            double moveBy = 1.0;
            double moveX = 0.0;
            double moveY = 0.0;
            bool isMoving = false;
            bool doUpdate = false;
            if ((buttonModifiers & Qt::ShiftModifier) && !(buttonModifiers & Qt::ControlModifier) && !(buttonModifiers & Qt::AltModifier))
                moveBy=0.1;
            else if (!(buttonModifiers & Qt::ShiftModifier) && (buttonModifiers & Qt::ControlModifier) && !(buttonModifiers & Qt::AltModifier))
                moveBy=10.0;
            else if ((buttonModifiers & Qt::ShiftModifier) && (buttonModifiers & Qt::ControlModifier) && !(buttonModifiers & Qt::AltModifier))
                moveBy=0.01;
            moveBy/=m_doc->unitRatio();//Lets allow movement by the current doc ratio, not only points
            moveBy /= m_canvas->m_viewMode.scale;
            PageItem *currItem = m_doc->m_Selection->itemAt(0);
            switch (kk)
            {
            case Qt::Key_7:
                moveX = -moveBy;
                moveY = -moveBy;
                isMoving = true;
                doUpdate = true;
                break;
            case Qt::Key_9:
                moveX = moveBy;
                moveY = -moveBy;
                isMoving = true;
                doUpdate = true;
                break;
            case Qt::Key_3:
                moveX = moveBy;
                moveY = moveBy;
                isMoving = true;
                doUpdate = true;
                break;
            case Qt::Key_1:
                moveX = -moveBy;
                moveY = moveBy;
                isMoving = true;
                doUpdate = true;
                break;
            case Qt::Key_Left:
            case Qt::Key_4:
                moveX = -moveBy;
                isMoving = true;
                doUpdate = true;
                break;
            case Qt::Key_Right:
            case Qt::Key_6:
                moveX = moveBy;
                isMoving = true;
                doUpdate = true;
                break;
            case Qt::Key_Up:
            case Qt::Key_8:
                moveY = -moveBy;
                isMoving = true;
                doUpdate = true;
                break;
            case Qt::Key_Down:
            case Qt::Key_2:
                moveY = moveBy;
                isMoving = true;
                doUpdate = true;
                break;
            case Qt::Key_5:
                if (m_view->editStrokeGradient == 6)
                {
                    QPair<int, int> selP = m_selectedMeshPoints[0];
                    currItem->meshGradientArray[selP.first][selP.second].controlColor = currItem->meshGradientArray[selP.first][selP.second].gridPoint;
                    doUpdate = true;
                }
                else if (m_view->editStrokeGradient == 7)
                {
                    QPair<int, int> selP = m_selectedMeshPoints[0];
                    if (m_gradientPoint == useControlT)
                        currItem->meshGradientArray[selP.first][selP.second].controlTop = currItem->meshGradientArray[selP.first][selP.second].gridPoint;
                    else if (m_gradientPoint == useControlB)
                        currItem->meshGradientArray[selP.first][selP.second].controlBottom = currItem->meshGradientArray[selP.first][selP.second].gridPoint;
                    else if (m_gradientPoint == useControlL)
                        currItem->meshGradientArray[selP.first][selP.second].controlLeft = currItem->meshGradientArray[selP.first][selP.second].gridPoint;
                    else if (m_gradientPoint == useControlR)
                        currItem->meshGradientArray[selP.first][selP.second].controlRight = currItem->meshGradientArray[selP.first][selP.second].gridPoint;
                    doUpdate = true;
                }
                break;
            }
            if (isMoving)
            {
                if (m_view->editStrokeGradient == 5)
                {
                    for (int mo = 0; mo < m_selectedMeshPoints.count(); mo++)
                    {
                        QPair<int, int> selP = m_selectedMeshPoints[mo];
                        currItem->meshGradientArray[selP.first][selP.second].moveRel(moveX, moveY);
                    }
                }
                else if (m_view->editStrokeGradient == 6)
                {
                    QPair<int, int> selP = m_selectedMeshPoints[0];
                    currItem->meshGradientArray[selP.first][selP.second].controlColor += FPoint(moveX, moveY);
                }
                else if (m_view->editStrokeGradient == 7)
                {
                    QPair<int, int> selP = m_selectedMeshPoints[0];
                    if (m_gradientPoint == useControlT)
                        currItem->meshGradientArray[selP.first][selP.second].controlTop += FPoint(moveX, moveY);
                    else if (m_gradientPoint == useControlB)
                        currItem->meshGradientArray[selP.first][selP.second].controlBottom += FPoint(moveX, moveY);
                    else if (m_gradientPoint == useControlL)
                        currItem->meshGradientArray[selP.first][selP.second].controlLeft += FPoint(moveX, moveY);
                    else if (m_gradientPoint == useControlR)
                        currItem->meshGradientArray[selP.first][selP.second].controlRight += FPoint(moveX, moveY);
                }
            }
            if (doUpdate)
            {
                currItem->update();
                QRectF upRect;
                upRect = QRectF(QPointF(0, 0), QPointF(currItem->width(), currItem->height())).normalized();
                upRect.translate(currItem->xPos(), currItem->yPos());
                m_doc->regionsChanged()->update(upRect.adjusted(-10.0 - currItem->width() / 2.0, -10.0 - currItem->height() / 2.0, 10.0 + currItem->width() / 2.0, 10.0 + currItem->height() / 2.0));
            }
        }
    }
    m_keyRepeat = false;
}
void KDReports::SpreadsheetReportLayout::paintPageContent(int pageNumber, QPainter &painter)
{
    //qDebug() << "painting with" << m_tableLayout.scaledFont();
    QAbstractItemModel* model = m_tableLayout.m_model;
    const qreal padding = m_tableLayout.scaledCellPadding();
    const QRect cellCoords = m_pageRects[pageNumber];
    //qDebug() << "painting page" << pageNumber << "cellCoords=" << cellCoords;
    qreal y = 0 /*m_topMargin*/; // in pixels
    const qreal rowHeight = m_tableLayout.rowHeight();

    if ( m_tableLayout.m_horizontalHeaderVisible ) {
        qreal x = 0 /*m_leftMargin*/;
        if ( m_tableLayout.m_verticalHeaderVisible ) {
            x += m_tableLayout.vHeaderWidth();
        }
        for ( int col = cellCoords.left(); col <= cellCoords.right(); ++col )
        {
            const QRectF cellRect( x, y, m_tableLayout.m_columnWidths[ col ], m_tableLayout.hHeaderHeight() );
            paintTableHorizontalHeader( cellRect, painter, col );
            x += cellRect.width();
        }
        y += m_tableLayout.hHeaderHeight();
    }

    const int firstRow = cellCoords.top();
    const int firstColumn = cellCoords.left();
    const int numRows = cellCoords.height();
    const int numColumns = cellCoords.width();

    // This won't work across page breaks....
    QVector<QBitArray> coveredCells;
    coveredCells.resize( numRows );
    for ( int row = firstRow; row <= cellCoords.bottom(); ++row )
        coveredCells[row - firstRow].resize( numColumns );

    for ( int row = firstRow; row <= cellCoords.bottom(); ++row )
    {
        qreal x = 0 /*m_leftMargin*/;
        if ( m_tableLayout.m_verticalHeaderVisible ) {
            x = paintTableVerticalHeader( x, y, painter, row );
        }
        painter.setFont( m_tableLayout.scaledFont() );
        for ( int col = cellCoords.left(); col <= cellCoords.right(); ++col )
        {
            if (coveredCells[row - firstRow].testBit(col - firstColumn)) {
                x += m_tableLayout.m_columnWidths[ col ];
                continue;
            }

            const QModelIndex index = model->index( row, col );

            const QSize span = model->span( index );
            if (span.isValid()) {
                for (int r = row; r < row + span.height() && r < numRows; ++r) {
                    for (int c = col; c < col + span.width() && c < numColumns; ++c) {
                        coveredCells[r - firstRow].setBit(c - firstColumn);
                    }
                }
            }

            const QRectF cellRect( x, y, cellWidth( col, span.width() ), qMax(1, span.height()) * rowHeight );
            const QRectF cellContentsRect = cellRect.adjusted( padding, padding, -padding, -padding );
            //qDebug() << "cell" << row << col << "rect=" << cellRect;

            const QString cellText = model->data( index, Qt::DisplayRole ).toString();
            const QColor foreground = qvariant_cast<QColor>( model->data( index, Qt::ForegroundRole ) );
            const QColor background = qvariant_cast<QColor>( model->data( index, Qt::BackgroundRole ) );
            const Qt::Alignment alignment( model->data( index, Qt::TextAlignmentRole ).toInt() );
            const QVariant decorationAlignment( model->data( index, KDReports::AutoTableElement::DecorationAlignmentRole ) );
            const QVariant cellDecoration( model->data( index, Qt::DecorationRole ) );

            if ( background.isValid() ) {
                painter.fillRect( cellRect, QBrush( background ) );
            } else if ( span.isValid() ) {
                painter.fillRect( cellRect, Qt::white );
            }
            drawBorder(cellRect, painter);

            // Per-cell font is not supported, on purpose. All rows use the same font,
            // otherwise the calculations for making things fit into a number of pages
            // become quite complex and slow.
            //const QVariant cellFont = model->data( index, Qt::FontRole );
            //if ( cellFont.isValid() )
            //    painter.setFont( qvariant_cast<QFont>( cellFont ) );
            //else
            //    painter.setFont( scaledFont );

            if ( foreground.isValid() )
                painter.setPen( foreground );

            paintTextAndIcon( painter, cellContentsRect, cellText, cellDecoration, decorationAlignment, alignment );

            if ( foreground.isValid() )
                painter.setPen( Qt::black );

            x += m_tableLayout.m_columnWidths[ col ];
        }
        y += rowHeight;
    }
}
Exemple #24
0
void
ComboBox::paintEvent(QPaintEvent* /*e*/)
{
    QStyleOption opt;

    opt.initFrom(this);

    QPainter p(this);
    QRectF bRect = rect();

    {
        ///Now draw the frame

        QColor fillColor;
        if (_clicked || _dirty) {
            fillColor = Qt::black;
        } else {
            double r, g, b;
            switch (_animation) {
            case 0:
            default: {
                appPTR->getCurrentSettings()->getRaisedColor(&r, &g, &b);
                break;
            }
            case 1: {
                appPTR->getCurrentSettings()->getInterpolatedColor(&r, &g, &b);
                break;
            }
            case 2: {
                appPTR->getCurrentSettings()->getKeyframeColor(&r, &g, &b);
                break;
            }
            case 3: {
                appPTR->getCurrentSettings()->getExprColor(&r, &g, &b);
                break;
            }
            }
            fillColor.setRgb( Color::floatToInt<256>(r),
                              Color::floatToInt<256>(g),
                              Color::floatToInt<256>(b) );
        }

        double fw = frameWidth();
        QPen pen;
        if ( !hasFocus() ) {
            pen.setColor(Qt::black);
        } else {
            double r, g, b;
            appPTR->getCurrentSettings()->getSelectionColor(&r, &g, &b);
            QColor c;
            c.setRgb( Color::floatToInt<256>(r),
                      Color::floatToInt<256>(g),
                      Color::floatToInt<256>(b) );
            fw = 2;
        }
        p.setPen(pen);


        QRectF roundedRect = bRect.adjusted(fw / 2., fw / 2., -fw, -fw);
        bRect.adjust(fw, fw, -fw, -fw);
        p.fillRect(bRect, fillColor);
        double roundPixels = 3;
        QPainterPath path;
        path.addRoundedRect(roundedRect, roundPixels, roundPixels);
        p.drawPath(path);
    }
    QColor textColor;
    if (_readOnly) {
        textColor.setRgb(100, 100, 100);
    } else if (_altered) {
        double aR, aG, aB;
        appPTR->getCurrentSettings()->getAltTextColor(&aR, &aG, &aB);
        textColor.setRgbF(aR, aG, aB);
    } else if (!_enabled) {
        textColor = Qt::black;
    } else {
        double r, g, b;
        appPTR->getCurrentSettings()->getTextColor(&r, &g, &b);
        textColor.setRgb( Color::floatToInt<256>(r),
                          Color::floatToInt<256>(g),
                          Color::floatToInt<256>(b) );
    }
    {
        Qt::Alignment align = QStyle::visualAlignment( Qt::LeftToRight, QFlag(_align) );
        int flags = align | Qt::TextForceLeftToRight;

        ///Draw the text
        QPen pen = p.pen();
        if (_currentIndex == -1) {
            QFont f = p.font();
            f.setItalic(true);
            p.setFont(f);
        }
        pen.setColor(textColor);
        p.setPen(pen);

        QRectF lr = layoutRect().toAlignedRect();
        p.drawText(lr.toRect(), flags, _currentText);
    }

    {
        ///Draw the dropdown icon
        QPainterPath path;
        QPolygonF poly;
        poly.push_back( QPointF(bRect.right() - DROP_DOWN_ICON_SIZE * 3. / 2., bRect.height() / 2. - DROP_DOWN_ICON_SIZE / 2.) );
        poly.push_back( QPointF(bRect.right() - DROP_DOWN_ICON_SIZE / 2., bRect.height() / 2. - DROP_DOWN_ICON_SIZE / 2.) );
        poly.push_back( QPointF(bRect.right() - DROP_DOWN_ICON_SIZE, bRect.height() / 2. + DROP_DOWN_ICON_SIZE / 2.) );
        path.addPolygon(poly);
        p.fillPath(path, textColor);
    }
} // ComboBox::paintEvent
Exemple #25
0
void QtViewportHandler::zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& targetArea)
{
    // This can only happen as a result of a user interaction.
    ASSERT(m_hadUserInteraction);

    if (!targetArea.isValid())
        return;

    if (m_suspendCount)
        return;

    const int margin = 10; // We want at least a little bit of margin.
    QRectF endArea = itemRectFromCSS(targetArea.adjusted(-margin, -margin, margin, margin));

    const QRectF viewportRect = m_viewportItem->boundingRect();

    qreal targetCSSScale = viewportRect.size().width() / endArea.size().width();
    qreal endCSSScale = innerBoundedCSSScale(qMin(targetCSSScale, qreal(2.5)));
    qreal endItemScale = itemScaleFromCSS(endCSSScale);
    qreal currentScale = m_pageItem->contentsScale();

    // We want to end up with the target area filling the whole width of the viewport (if possible),
    // and centralized vertically where the user requested zoom. Thus our hotspot is the center of
    // the targetArea x-wise and the requested zoom position, y-wise.
    const QPointF hotspot = QPointF(endArea.center().x(), itemCoordFromCSS(touchPoint.y()));
    const QPointF viewportHotspot = viewportRect.center();

    QPointF endPosition = hotspot * endCSSScale - viewportHotspot;

    QRectF endPosRange = computePosRangeForPageItemAtScale(endItemScale);
    endPosition = boundPosition(endPosRange.topLeft(), endPosition, endPosRange.bottomRight());

    QRectF endVisibleContentRect(endPosition / endItemScale, viewportRect.size() / endItemScale);

    enum { ZoomIn, ZoomBack, ZoomOut, NoZoom } zoomAction = ZoomIn;

    if (!m_scaleStack.isEmpty()) {
        // Zoom back out if attempting to scale to the same current scale, or
        // attempting to continue scaling out from the inner most level.
        // Use fuzzy compare with a fixed error to be able to deal with largish differences due to pixel rounding.
        if (fuzzyCompare(endItemScale, currentScale, 0.01)) {
            // If moving the viewport would expose more of the targetRect and move at least 40 pixels, update position but do not scale out.
            QRectF currentContentRect(m_viewportItem->contentPos() / currentScale, viewportRect.size() / currentScale);
            QRectF targetIntersection = endVisibleContentRect.intersected(targetArea);
            if (!currentContentRect.contains(targetIntersection) && (qAbs(endVisibleContentRect.top() - currentContentRect.top()) >= 40 || qAbs(endVisibleContentRect.left() - currentContentRect.left()) >= 40))
                zoomAction = NoZoom;
            else
                zoomAction = ZoomBack;
        } else if (fuzzyCompare(endItemScale, m_zoomOutScale, 0.01))
            zoomAction = ZoomBack;
        else if (endItemScale < currentScale)
            zoomAction = ZoomOut;
    }

    switch (zoomAction) {
    case ZoomIn:
        m_scaleStack.append(ScaleStackItem(currentScale, m_viewportItem->contentPos().x()));
        m_zoomOutScale = endItemScale;
        break;
    case ZoomBack: {
        ScaleStackItem lastScale = m_scaleStack.takeLast();
        endItemScale = lastScale.scale;
        endCSSScale = cssScaleFromItem(lastScale.scale);
        // Recalculate endPosition and bound it according to new scale.
        endPosition.setY(hotspot.y() * endCSSScale - viewportHotspot.y());
        endPosition.setX(lastScale.xPosition);
        endPosRange = computePosRangeForPageItemAtScale(endItemScale);
        endPosition = boundPosition(endPosRange.topLeft(), endPosition, endPosRange.bottomRight());
        endVisibleContentRect = QRectF(endPosition / endItemScale, viewportRect.size() / endItemScale);
        break;
    }
    case ZoomOut:
        // Unstack all scale-levels deeper than the new level, so a zoom-back won't end up zooming in.
        while (!m_scaleStack.isEmpty() && m_scaleStack.last().scale >= endItemScale)
            m_scaleStack.removeLast();
        m_zoomOutScale = endItemScale;
        break;
    case NoZoom:
        break;
    }

    animatePageItemRectVisible(endVisibleContentRect);
}
/*!
  \brief Draw lines

  If the CurveAttribute Fitted is enabled a QwtCurveFitter tries
  to interpolate/smooth the curve, before it is painted.

  \param painter Painter
  \param xMap x map
  \param yMap y map
  \param canvasRect Contents rectangle of the canvas
  \param from index of the first point to be painted
  \param to index of the last point to be painted

  \sa setCurveAttribute(), setCurveFitter(), draw(),
      drawLines(), drawDots(), drawSteps(), drawSticks()
*/
void QwtPlotCurve::drawLines( QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    const QRectF &canvasRect, int from, int to ) const
{
    if ( from > to )
        return;

    const bool doFit = ( d_data->attributes & Fitted ) && d_data->curveFitter;
    const bool doAlign = !doFit && QwtPainter::roundingAlignment( painter );
    const bool doFill = ( d_data->brush.style() != Qt::NoBrush )
            && ( d_data->brush.color().alpha() > 0 );

    QRectF clipRect;
    if ( d_data->paintAttributes & ClipPolygons )
    {
        clipRect = qwtIntersectedClipRect( canvasRect, painter );

        const qreal pw = QwtPainter::effectivePenWidth( painter->pen() );
        clipRect = clipRect.adjusted(-pw, -pw, pw, pw);
    }

    bool doIntegers = false;

#if QT_VERSION < 0x040800
    if ( painter->paintEngine()->type() == QPaintEngine::Raster )
    {

        // For Qt <= 4.7 the raster paint engine is significantly faster
        // for rendering QPolygon than for QPolygonF. So let's
        // see if we can use it.

        // In case of filling or fitting performance doesn't count
        // because both operations are much more expensive
        // then drawing the polyline itself

        if ( !doFit && !doFill )
            doIntegers = true;
    }
#endif

    QwtPointMapper mapper;

    if ( doAlign )
    {
        mapper.setFlag( QwtPointMapper::RoundPoints, true );
        mapper.setFlag( QwtPointMapper::WeedOutIntermediatePoints,
            testPaintAttribute( FilterPointsAggressive ) );
    }

    mapper.setFlag( QwtPointMapper::WeedOutPoints,
        testPaintAttribute( FilterPoints ) ||
        testPaintAttribute( FilterPointsAggressive ) );

    mapper.setBoundingRect( canvasRect );

    if ( doIntegers )
    {
        QPolygon polyline = mapper.toPolygon(
            xMap, yMap, data(), from, to );

        if ( testPaintAttribute( ClipPolygons ) )
        {
            QwtClipper::clipPolygon( clipRect, polyline, false );
        }

        QwtPainter::drawPolyline( painter, polyline );
    }
    else
    {
        QPolygonF polyline = mapper.toPolygonF( xMap, yMap, data(), from, to );

        if ( doFill )
        {
            if ( doFit )
            {
                // it might be better to extend and draw the curvePath, but for
                // the moment we keep an implementation, where we translate the
                // path back to a polyline.

                polyline = d_data->curveFitter->fitCurve( polyline );
            }

            if ( painter->pen().style() != Qt::NoPen )
            {
                // here we are wasting memory for the filled copy,
                // do polygon clipping twice etc .. TODO

                QPolygonF filled = polyline;
                fillCurve( painter, xMap, yMap, canvasRect, filled );
                filled.clear();

                if ( d_data->paintAttributes & ClipPolygons )
                    QwtClipper::clipPolygonF( clipRect, polyline, false );

                QwtPainter::drawPolyline( painter, polyline );
            }
            else
            {
                fillCurve( painter, xMap, yMap, canvasRect, polyline );
            }
        }
        else
        {
            if ( testPaintAttribute( ClipPolygons ) )
            {
                QwtClipper::clipPolygonF( clipRect, polyline, false );
            }

            if ( doFit )
            {
                if ( d_data->curveFitter->mode() == QwtCurveFitter::Path )
                {
                    const QPainterPath curvePath =
                        d_data->curveFitter->fitCurvePath( polyline );

                    painter->drawPath( curvePath );
                }
                else
                {
                    polyline = d_data->curveFitter->fitCurve( polyline );
                    QwtPainter::drawPolyline( painter, polyline );
                }
            }
            else
            {
                QwtPainter::drawPolyline( painter, polyline );
            }
        }
    }
}
/**
 * Overrides the standard paint event.
 */
void ActivityWidget::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
{
    QRectF r = rect();
    const QSizeF sz = size();
    qreal w = sz.width();
    qreal h = sz.height();

    p->setPen(QPen(lineColor(), lineWidth()));
    p->setBrush(brush());

    switch(m_activityType) 
    {
    case Normal:
        p->drawRoundRect(r, (h * 60) / w, 60);
        break;

    case Initial:
        p->setBrush(QBrush(lineColor()));
        p->drawEllipse(r);
        break;

    case Final:
        p->setBrush(Qt::NoBrush);
        p->drawEllipse(r);
        Widget_Utils::drawCrossInEllipse(p, r);
        break;

    case End:
    {
        p->setBrush(Qt::NoBrush);
        qreal adj = lineWidth() + 1;
        p->drawEllipse(r.adjusted(+adj, +adj, -adj, -adj));

        p->setBrush(lineColor());
        adj = lineWidth() + 3;
        p->drawEllipse(r.adjusted(+adj, +adj, -adj, -adj));
        break;
    }

    case Branch:
    {
        QPolygonF array(4);
        array[0] = QPointF(w / 2, 0);
        array[1] = QPointF(w, h / 2);
        array[2] = QPointF(w / 2, h);
        array[3] = QPointF(0, h / 2);
        p->drawPolygon(array);
    }
    break;

    case Invok:
        p->drawRoundRect(r, (h * 60) / w, 60);
        {
            qreal x = w - (w/5);
            qreal y = h - (h/3);

            p->drawLine(QLineF(x,  y, x, y + 20));
            p->drawLine(QLineF(x - 10, y + 10, x + 10, y + 10));
            p->drawLine(QLineF(x - 10, y + 10, x - 10, y + 20));
            p->drawLine(QLineF(x + 10, y + 10, x + 10, y + 20));
        }
        break;

    case Param:
        p->drawRoundRect(r, (h * 60) / w, 60);
        break;
    }
}
Exemple #28
0
void
GraphicsMovieItem::paintRect( QPainter* painter, const QStyleOptionGraphicsItem* option )
{
    QRectF drawRect;
    bool drawRound;

    // Disable the matrix transformations
    painter->setWorldMatrixEnabled( false );

    painter->setRenderHint( QPainter::Antialiasing );

    // Get the transformations required to map the text on the viewport
    QTransform viewPortTransform = Timeline::getInstance()->tracksView()->viewportTransform();

    // Determine if a drawing optimization can be used
    if ( option->exposedRect.left() > AbstractGraphicsItem::RounderRectRadius &&
         option->exposedRect.right() < boundingRect().right() - AbstractGraphicsItem::RounderRectRadius )
    {
        // Optimized: paint only the exposed (horizontal) area
        drawRect = QRectF( option->exposedRect.left(),
                           boundingRect().top(),
                           option->exposedRect.right(),
                           boundingRect().bottom() );
        drawRound = false;
    }
    else
    {
        // Unoptimized: the item must be fully repaint
        drawRect = boundingRect();
        drawRound = true;
    }

    // Do the transformation
    QRectF mapped = deviceTransform( viewPortTransform ).mapRect( drawRect );

    QLinearGradient gradient( mapped.topLeft(), mapped.bottomLeft() );
    gradient.setColorAt( 0, QColor::fromRgb( 78, 78, 78 ) );
    gradient.setColorAt( 0.4, QColor::fromRgb( 72, 72, 72 ) );
    gradient.setColorAt( 0.4, QColor::fromRgb( 50, 50, 50 ) );
    gradient.setColorAt( 1, QColor::fromRgb( 45, 45, 45 ) );

    painter->setPen( Qt::NoPen );
    painter->setBrush( QBrush( gradient ) );

    if ( drawRound )
        painter->drawRoundedRect( mapped, AbstractGraphicsItem::RounderRectRadius,
                                  AbstractGraphicsItem::RounderRectRadius );
    else
        painter->drawRect( mapped );

    if ( itemColor().isValid() )
    {
        QRectF mediaColorRect = mapped.adjusted( 3, 2, -3, -2 );
        painter->setPen( QPen( itemColor(), 2 ) );
        painter->drawLine( mediaColorRect.topLeft(), mediaColorRect.topRight() );
    }

    if ( isSelected() )
    {
        setZValue( zSelected() );
        painter->setPen( Qt::yellow );
        painter->setBrush( Qt::NoBrush );
        mapped.adjust( 0, 0, 0, -1 );
        if ( drawRound )
            painter->drawRoundedRect( mapped, AbstractGraphicsItem::RounderRectRadius,
                                      AbstractGraphicsItem::RounderRectRadius);
        else
            painter->drawRect( mapped );
    }
    else
        setZValue( zNotSelected() );
}
Exemple #29
0
 QRectF boundingRectFor(const QRectF &rect) const
 { return rect.adjusted(-m_margin, -m_margin, m_margin, m_margin); }
Exemple #30
0
void PageViewportControllerClientQt::zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& targetArea)
{
    // This can only happen as a result of a user interaction.
    ASSERT(m_controller->hadUserInteraction());

    if (!targetArea.isValid())
        return;

    if (m_scrollChange.inProgress() || m_scaleChange.inProgress())
        return;

    const float margin = 10; // We want at least a little bit of margin.
    QRectF endArea = targetArea.adjusted(-margin, -margin, margin, margin);

    const QRectF viewportRect = m_viewportItem->boundingRect();

    qreal minViewportScale = qreal(2.5);
    qreal targetScale = viewportRect.size().width() / endArea.size().width();
    targetScale = m_controller->innerBoundedViewportScale(qMin(minViewportScale, targetScale));
    qreal currentScale = m_pageItem->contentsScale();

    // We want to end up with the target area filling the whole width of the viewport (if possible),
    // and centralized vertically where the user requested zoom. Thus our hotspot is the center of
    // the targetArea x-wise and the requested zoom position, y-wise.
    const QPointF hotspot = QPointF(endArea.center().x(), touchPoint.y());
    const QPointF viewportHotspot = viewportRect.center();

    QPointF endPosition = hotspot - viewportHotspot / targetScale;
    endPosition = m_controller->clampViewportToContents(endPosition, targetScale);
    QRectF endVisibleContentRect(endPosition, viewportRect.size() / targetScale);

    enum { ZoomIn, ZoomBack, ZoomOut, NoZoom } zoomAction = ZoomIn;

    // Zoom back out if attempting to scale to the same current scale, or
    // attempting to continue scaling out from the inner most level.
    // Use fuzzy compare with a fixed error to be able to deal with largish differences due to pixel rounding.
    if (!m_scaleStack.isEmpty() && fuzzyCompare(targetScale, currentScale, 0.01)) {
        // If moving the viewport would expose more of the targetRect and move at least 40 pixels, update position but do not scale out.
        QRectF currentContentRect(m_viewportItem->mapRectToWebContent(viewportRect));
        QRectF targetIntersection = endVisibleContentRect.intersected(targetArea);
        if (!currentContentRect.contains(targetIntersection)
            && (qAbs(endVisibleContentRect.top() - currentContentRect.top()) >= 40
            || qAbs(endVisibleContentRect.left() - currentContentRect.left()) >= 40))
            zoomAction = NoZoom;
        else
            zoomAction = ZoomBack;
    } else if (fuzzyCompare(targetScale, m_zoomOutScale, 0.01))
        zoomAction = ZoomBack;
    else if (targetScale < currentScale)
        zoomAction = ZoomOut;

    switch (zoomAction) {
    case ZoomIn:
        m_scaleStack.append(ScaleStackItem(currentScale, m_viewportItem->contentPos().x() / currentScale));
        m_zoomOutScale = targetScale;
        break;
    case ZoomBack: {
        if (m_scaleStack.isEmpty()) {
            targetScale = m_controller->minimumContentsScale();
            endPosition.setY(hotspot.y() - viewportHotspot.y() / targetScale);
            endPosition.setX(0);
            m_zoomOutScale = 0;
        } else {
            ScaleStackItem lastScale = m_scaleStack.takeLast();
            targetScale = lastScale.scale;
            // Recalculate endPosition and clamp it according to the new scale.
            endPosition.setY(hotspot.y() - viewportHotspot.y() / targetScale);
            endPosition.setX(lastScale.xPosition);
        }
        endPosition = m_controller->clampViewportToContents(endPosition, targetScale);
        endVisibleContentRect = QRectF(endPosition, viewportRect.size() / targetScale);
        break;
    }
    case ZoomOut:
        // Unstack all scale-levels deeper than the new level, so a zoom-back won't end up zooming in.
        while (!m_scaleStack.isEmpty() && m_scaleStack.last().scale >= targetScale)
            m_scaleStack.removeLast();
        m_zoomOutScale = targetScale;
        break;
    case NoZoom:
        break;
    }

    animateContentRectVisible(endVisibleContentRect);
}