Example #1
0
void KisImagePyramid::alignSourceRect(QRect& rect, qreal scale)
{
    qint32 index = findFirstGoodPlaneIndex(scale, rect.size());
    qint32 alignment = 1 << index;

    dbgRender << "Before alignment:\t" << rect;

    /**
     * Assume that KisImage pixels are always positive
     * It allows us to use binary op-s for aligning
     */
    Q_ASSERT(rect.left() >= 0 && rect.top() >= 0);

    qint32 x1, y1, x2, y2;
    rect.getCoords(&x1, &y1, &x2, &y2);

    alignByPow2Lo(x1, alignment);
    alignByPow2Lo(y1, alignment);
    /**
     * Here is a workaround of Qt's QRect::right()/bottom()
     * "historical reasons". It should be one pixel smaller
     * than actual right/bottom position
     */
    alignByPow2ButOneHi(x2, alignment);
    alignByPow2ButOneHi(y2, alignment);

    rect.setCoords(x1, y1, x2, y2);

    dbgRender << "After alignment:\t" << rect;
}
Example #2
0
void CustomStyle::drawHoverRect(QPainter *painter, const QRect &rect) const
{
/*    double h = r.height();
double h2 = r.height() / 2.0;
QPainterPath path;
path.addRect(r.x() + h2, r.y() + 0, r.width() - h2 * 2, r.height());
path.addEllipse(r.x(), r.y(), h, h);
path.addEllipse(r.x() + r.width() - h, r.y(), h, h);
path.setFillRule(Qt::WindingFill);
painter->setPen(Qt::NoPen);
painter->setBrush(QColor(191, 215, 191));
painter->setRenderHint(QPainter::Antialiasing);
    painter->drawPath(path);*/
    int radius = qMin(rect.width(), rect.height()) / 2;
    int diam = 2 * radius;

    int x1, y1, x2, y2;
    rect.getCoords(&x1, &y1, &x2, &y2);
    QPainterPath path;
    QColor color;
    color = mergedColors(QColor(0x06, 0x4C, 0xA4), QColor(0xd6, 0xd6, 0xd6));
    QPen pen(color, 4);
    painter->setPen(pen);
    path.moveTo(x2, y1 + radius);
    path.arcTo(QRect(x2 - diam, y1, diam, diam), 0.0, +90.0);
    path.lineTo(x1 + radius, y1);
    path.arcTo(QRect(x1, y1, diam, diam), 90.0, +90.0);
    path.lineTo(x1, y2 - radius);
    path.arcTo(QRect(x1, y2 - diam, diam, diam), 180.0, +90.0);
    path.lineTo(x1 + radius, y2);
    path.arcTo(QRect(x2 - diam, y2 - diam, diam, diam), 270.0, +90.0);
    painter->drawPath(path);
}
Example #3
0
QPainterPath CustomStyle::roundRectPath(const QRect &rect)
{
//      int radius = qMin(rect.width()-2, rect.height()-2) / 2;
//     int diam = 2 * radius;

    int x1, y1, x2, y2;
    rect.getCoords(&x1, &y1, &x2, &y2);
//     x1+=1;y1+=1;x2-=1;y2-=1;
    QPainterPath path;
//      path.moveTo(x2, y1 + radius);
//      path.arcTo(QRect(x2 - diam, y1, diam, diam), 0.0, +90.0);
//      path.lineTo(x1 + radius, y1);
//      path.arcTo(QRect(x1, y1, diam, diam), 90.0, +90.0);
//      path.lineTo(x1, y2 - radius);
//      path.arcTo(QRect(x1, y2 - diam, diam, diam), 180.0, +90.0);
//      path.lineTo(x1 + radius, y2);
//      path.arcTo(QRect(x2 - diam, y2 - diam, diam, diam), 270.0, +90.0);

    path.moveTo(x1+2, y1);
    path.lineTo(x2-2, y1);
    path.lineTo(x2, y1+2);
    path.lineTo(x2, y2-2);
    path.lineTo(x2-2, y2);
    path.lineTo(x1+2, y2);
    path.lineTo(x1, y2-2);
    path.lineTo(x1, y1+2);
    path.lineTo(x1+2, y1);

    path.closeSubpath();
    return path;
}
void
PartitionBarsView::setSelection( const QRect& rect, QItemSelectionModel::SelectionFlags flags )
{
    //HACK: this is an utterly awful workaround, which is unfortunately necessary.
    //      QAbstractItemView::mousePressedEvent calls setSelection, but before that,
    //      for some mental reason, it works under the assumption that every item is a
    //      rectangle. This rectangle is provided by visualRect, and the idea mostly
    //      works, except when the item is an extended partition item, which is of course
    //      a rectangle with a rectangular hole in the middle.
    //      QAbstractItemView::mousePressEvent builds a QRect with x1, y1 in the center
    //      of said visualRect, and x2, y2 in the real QMouseEvent position.
    //      This may very well yield a QRect with negative size, which is meaningless.
    //      Therefore the QRect we get here is totally bogus, and its topLeft is outside
    //      the actual area of the item we need.
    //      What we need are the real coordinates of the QMouseEvent, and the only way to
    //      get them is by fetching the private x2, y2 from the rect.
    //      TL;DR: this sucks, look away. -- Teo 12/2015
    int x1, y1, x2, y2;
    rect.getCoords( &x1, &y1, &x2, &y2 );

    QModelIndex eventIndex = indexAt( QPoint( x2, y2 ) );
    if ( canBeSelected( eventIndex ) )
        selectionModel()->select( eventIndex, flags );

    viewport()->repaint();
}
Example #5
0
void DownloadRegionDialog::updateTilesCount()
{
    if ( !isVisible() || !d->hasTextureLayer() ) {
        return;
    }

    qint64 tilesCount = 0;
    QString themeId( d->m_model->mapThemeId() );
    QVector<TileCoordsPyramid> const pyramid = region();
    Q_ASSERT( !pyramid.isEmpty() );
    if( pyramid.size() == 1 ) {
        tilesCount = pyramid[0].tilesCount();
    }
    else {
        for( int level = pyramid[0].bottomLevel(); level>= pyramid[0].topLevel(); --level ) {
            QSet<TileId> tileIdSet;
            for( int i = 0; i < pyramid.size(); ++i ) {
                QRect const coords = pyramid[i].coords( level );
                int x1, y1, x2, y2;
                coords.getCoords( &x1, &y1, &x2, &y2 );
                for ( int x = x1; x <= x2; ++x ) {
                    for ( int y = y1; y <= y2; ++y ) {
                        TileId const tileId( 0, level, x, y );
                        tileIdSet.insert( tileId );
                    }
                }
            }
            tilesCount += tileIdSet.count();
        }
    }

    if ( tilesCount > maxTilesCount ) {
        d->m_tileSizeInfo->setToolTip( QString() );
        d->m_tileSizeInfo->setText( tr( "There is a limit of %n tiles to download.", "",
                                               maxTilesCount ) );
    } else if ( themeId == "earth/openstreetmap/openstreetmap.dgml" ) {
        qreal tileDownloadSize = tilesCount * averageTileSize;

        d->m_tileSizeInfo->setToolTip( tr( "Approximate size of the tiles to be downloaded" ) );

        if( tileDownloadSize > 1024 ) {
            tileDownloadSize = tileDownloadSize / 1024;
            d->m_tileSizeInfo->setText( tr( "Estimated download size: %1 MB" ).arg( ceil( tileDownloadSize ) ) );
        }
        else {
            d->m_tileSizeInfo->setText( tr( "Estimated download size: %1 kB" ).arg( tileDownloadSize ) );
        }

    }
    else {
        d->m_tileSizeInfo->setToolTip( QString() );
        d->m_tileSizeInfo->clear();
    }

    d->m_tilesCountLabel->setText( QString::number( tilesCount ) );
    bool const tilesCountWithinLimits = tilesCount > 0 && tilesCount <= maxTilesCount;
    d->m_okButton->setEnabled( tilesCountWithinLimits );
    d->m_applyButton->setEnabled( tilesCountWithinLimits );
}
Example #6
0
QSet<TileId> PlacemarkLayout::visibleTiles( const ViewportParams *viewport )
{
    int zoomLevel = qLn( viewport->radius() *4 / 256 ) / qLn( 2.0 );

    /*
     * rely on m_placemarkCache to find the placemarks for the tiles which
     * matter. The top level tiles have the more popular placemarks,
     * the bottom level tiles have the smaller ones, and we only get the ones
     * matching our latLonAltBox.
     */

    qreal north, south, east, west;
    viewport->viewLatLonAltBox().boundaries(north, south, east, west);
    QSet<TileId> tileIdSet;
    QVector<QRectF> geoRects;
    if( west <= east ) {
        geoRects << QRectF(west, north, east - west, south - north);
    } else {
        geoRects << QRectF(west, north, M_PI - west, south - north);
        geoRects << QRectF(-M_PI, north, east + M_PI, south - north);
    }
    foreach( const QRectF &geoRect, geoRects ) {
        TileId key;
        QRect rect;

        key = TileId::fromCoordinates( GeoDataCoordinates(geoRect.left(), north, 0), zoomLevel);
        rect.setLeft( key.x() );
        rect.setTop( key.y() );

        key = TileId::fromCoordinates( GeoDataCoordinates(geoRect.right(), south, 0), zoomLevel);
        rect.setRight( key.x() );
        rect.setBottom( key.y() );

        TileCoordsPyramid pyramid(0, zoomLevel );
        pyramid.setBottomLevelCoords( rect );

        for ( int level = pyramid.topLevel(); level <= pyramid.bottomLevel(); ++level ) {
        QRect const coords = pyramid.coords( level );
        int x1, y1, x2, y2;
        coords.getCoords( &x1, &y1, &x2, &y2 );
            for ( int x = x1; x <= x2; ++x ) {
                for ( int y = y1; y <= y2; ++y ) {
                    TileId const tileId( 0, level, x, y );
                    tileIdSet.insert(tileId);
                }
            }
        }
    }
Example #7
0
//sheetの座標からContents座標への変換
QRect SXBSchView::SheetToContents(const QRect& rc)
{
    int x1,y1,x2,y2;
    rc.getCoords(&x1,&y1,&x2,&y2);
    x1 = x1*m_viewScaleMul/m_viewScale;
    y1 = y1*m_viewScaleMul/m_viewScale;
    x2 = x2*m_viewScaleMul/m_viewScale;
    y2 = y2*m_viewScaleMul/m_viewScale;
    QRect r;
    r.setCoords(x1,y1,x2,y2);
    //    QRect r(    rc.left()    /m_viewScale,
    //    	    	rc.top()    /m_viewScale,
    //    	    	rc.width()    /m_viewScale,
    //    	    	rc.height()    /m_viewScale);
    return r;
}
Example #8
0
void MarbleMap::downloadRegion( QVector<TileCoordsPyramid> const & pyramid )
{
    Q_ASSERT( textureLayer() );
    Q_ASSERT( !pyramid.isEmpty() );
    QTime t;
    t.start();

    // When downloading a region (the author of these lines thinks) most users probably expect
    // the download to begin with the low resolution tiles and then procede level-wise to
    // higher resolution tiles. In order to achieve this, we start requesting downloads of
    // high resolution tiles and request the low resolution tiles at the end because
    // DownloadQueueSet (silly name) is implemented as stack.


    int const first = 0;
    int tilesCount = 0;

     for ( int level = pyramid[first].bottomLevel(); level >= pyramid[first].topLevel(); --level ) {
         QSet<TileId> tileIdSet;
          for( int i = 0; i < pyramid.size(); ++i ) {
            QRect const coords = pyramid[i].coords( level );
            mDebug() << "MarbleMap::downloadRegion level:" << level << "tile coords:" << coords;
            int x1, y1, x2, y2;
            coords.getCoords( &x1, &y1, &x2, &y2 );
            for ( int x = x1; x <= x2; ++x ) {
                for ( int y = y1; y <= y2; ++y ) {
                    TileId const stackedTileId( 0, level, x, y );
                    tileIdSet.insert( stackedTileId );
                    // FIXME: use lazy evaluation to not generate up to 100k tiles in one go
                    // this can take considerable time even on very fast systems
                    // in contrast generating the TileIds on the fly when they are needed
                    // does not seem to affect download speed.
                }
            }
         }
         QSetIterator<TileId> i( tileIdSet );
         while( i.hasNext() ) {
             TileId const stackedTileId = i.next();
             d->m_textureLayer.downloadStackedTile( stackedTileId );
         }
         tilesCount += tileIdSet.count();
     }
    // Needed for downloading unique tiles only. Much faster than if tiles for each level is downloaded separately

    int const elapsedMs = t.elapsed();
    mDebug() << "MarbleMap::downloadRegion:" << tilesCount << "tiles, " << elapsedMs << "ms";
}
Example #9
0
QList< GeoGraphicsItem* > GeoGraphicsScene::items( const Marble::GeoDataLatLonAltBox& box, int maxZoomLevel ) const
{
    QList< GeoGraphicsItem* > result;
    QRect rect;
    qreal north, south, east, west;
    box.boundaries( north, south, east, west );
    TileId key;
    int zoomLevel = maxZoomLevel < s_tileZoomLevel ? maxZoomLevel : s_tileZoomLevel;

    key = d->coordToTileId( GeoDataCoordinates(west, north, 0), zoomLevel );
    rect.setLeft( key.x() );
    rect.setTop( key.y() );

    key = d->coordToTileId( GeoDataCoordinates(east, south, 0), zoomLevel );
    rect.setRight( key.x() );
    rect.setBottom( key.y() );
    
    TileCoordsPyramid pyramid( 0, zoomLevel );
    pyramid.setBottomLevelCoords( rect );

    for ( int level = pyramid.topLevel(); level <= pyramid.bottomLevel(); ++level ) {
        QRect const coords = pyramid.coords( level );
        int x1, y1, x2, y2;
        coords.getCoords( &x1, &y1, &x2, &y2 );
        for ( int x = x1; x <= x2; ++x ) {
            for ( int y = y1; y <= y2; ++y ) {
                TileId const tileId( "", level, x, y );
                const QList< GeoGraphicsItem* > &objects = d->m_items.value(tileId);
                QList< GeoGraphicsItem* >::iterator before = result.begin();
                QList< GeoGraphicsItem* >::const_iterator currentItem = objects.constBegin();
                while( currentItem != objects.end() )
                {  
                    while( ( currentItem != objects.end() )
                      && ( ( before == result.end() ) || ( (*currentItem)->zValue() < (*before)->zValue() ) ) )
                    {
                        if( (*currentItem)->minZoomLevel() <= maxZoomLevel )
                            before = result.insert( before, *currentItem );
                        currentItem++;
                    }
                    if ( before != result.end() )
                        before++;
                }
            }
        }
    }
    return result;
}
QPainterPath NorwegianWoodStyle::roundRectPath(const QRect &rect)
{
    int radius = qMin(rect.width(), rect.height()) / 2;
    int diam = 2 * radius;

    int x1, y1, x2, y2;
    rect.getCoords(&x1, &y1, &x2, &y2);

    QPainterPath path;
    path.moveTo(x2, y1 + radius);
    path.arcTo(QRect(x2 - diam, y1, diam, diam), 0.0, +90.0);
    path.lineTo(x1 + radius, y1);
    path.arcTo(QRect(x1, y1, diam, diam), 90.0, +90.0);
    path.lineTo(x1, y2 - radius);
    path.arcTo(QRect(x1, y2 - diam, diam, diam), 180.0, +90.0);
    path.lineTo(x1 + radius, y2);
    path.arcTo(QRect(x2 - diam, y2 - diam, diam, diam), 270, +90.0);
    path.closeSubpath();
    
    return path; 
}
void xRenderRoundBox(Picture pict, const QRect &rect, int , const QColor &c)
{
    XRenderPicture fill = xRenderFill(c);
    int op = c.alpha() == 255 ? PictOpSrc : PictOpOver;
    // TODO: implement second paramenter "roundness"
    // so rather use ?? XRenderCompositeTriFan (dpy, op, src, dst, maskFormat, xSrc, ySrc,
    //XPointFixed *points, npoint);
    // this will require "points on a circle" calculation, however...

    int s = qMin(CS, qMin(rect.height() / 2, rect.width() / 2));
    int x, y, b, r;
    rect.getCoords(&x, &y, &r, &b);
    r -= (s - 1);
    b -= (s - 1);
    XRenderComposite(display(), PictOpOver, fill, *circle(0), pict, 0, 0, 0, 0, x, y, CS, CS);
    XRenderComposite(display(), PictOpOver, fill, *circle(1), pict, 0, 0, CS - s, 0, r, y, s, s);
    XRenderComposite(display(), PictOpOver, fill, *circle(2), pict, 0, 0, CS - s, CS - s, r, b, s, s);
    XRenderComposite(display(), PictOpOver, fill, *circle(3), pict, 0, 0, 0, CS - s, x, b, s, s);
    XRenderComposite(display(), op, fill, 0, pict, 0, 0, 0, 0, x + s, y, rect.width() - 2 * s, s);
    XRenderComposite(display(), op, fill, 0, pict, 0, 0, 0, 0, x, y + s, rect.width(), rect.height() - 2 * s);
    XRenderComposite(display(), op, fill, 0, pict, 0, 0, 0, 0, x + s, b, rect.width() - 2 * s, s);
}
Example #12
0
File: map.cpp Project: KDE/krusader
void
RadialMap::Map::paint(unsigned int scaleFactor)
{
    if (scaleFactor == 0)  //just in case
        scaleFactor = 1;

    QPainter paint;
    QRect rect = m_rect;
    int step = m_ringBreadth;
    int excess = -1;

    //scale the pixmap, or do intelligent distribution of excess to prevent nasty resizing
    if (scaleFactor > 1) {
        int x1, y1, x2, y2;
        rect.getCoords(&x1, &y1, &x2, &y2);
        x1 *= scaleFactor;
        y1 *= scaleFactor;
        x2 *= scaleFactor;
        y2 *= scaleFactor;
        rect.setCoords(x1, y1, x2, y2);

        step *= scaleFactor;
        QPixmap::operator=(QPixmap(this->size() * (int)scaleFactor));
    } else if (m_ringBreadth != MAX_RING_BREADTH && m_ringBreadth != MIN_RING_BREADTH) {
        excess = rect.width() % m_ringBreadth;
        ++step;
    }

    //**** best option you can think of is to make the circles slightly less perfect,
    //  ** i.e. slightly eliptic when resizing inbetween


    paint.begin(this);

    fill(); //erase background

    for (int x = m_visibleDepth; x >= 0; --x) {
        int width = rect.width() / 2;
        //clever geometric trick to find largest angle that will give biggest arrow head
        int a_max = int(acos((double)width / double((width + 5) * scaleFactor)) * (180 * 16 / M_PI));

        for (ConstIterator<Segment> it = m_signature[x].constIterator(); it != m_signature[x].end(); ++it) {
            //draw the pie segments, most of this code is concerned with drawing the little
            //arrows on the ends of segments when they have hidden files

            paint.setPen((*it)->pen());

            if ((*it)->hasHiddenChildren()) {
                //draw arrow head to indicate undisplayed files/directories
                QPolygon pts(3);
                QPoint pos, cpos = rect.center();
                int a[3] = {static_cast<int>((*it)->start()), static_cast<int>((*it)->length()), 0 };

                a[2] = a[0] + (a[1] / 2); //assign to halfway between
                if (a[1] > a_max) {
                    a[1] = a_max;
                    a[0] = a[2] - a_max / 2;
                }

                a[1] += a[0];

                for (int i = 0, radius = width; i < 3; ++i) {
                    double ra = M_PI / (180 * 16) * a[i], sinra, cosra;

                    if (i == 2)
                        radius += 5 * scaleFactor;
#if 0
                    sincos(ra, &sinra, &cosra);
#endif
                    sinra = sin(ra); cosra = cos(ra);
                    pos.rx() = cpos.x() + static_cast<int>(cosra * radius);
                    pos.ry() = cpos.y() - static_cast<int>(sinra * radius);
                    pts.setPoint(i, pos);
                }

                paint.setBrush((*it)->pen());
                paint.drawPolygon(pts);
            }

            paint.setBrush((*it)->brush());
            paint.drawPie(rect, (*it)->start(), (*it)->length());

            if ((*it)->hasHiddenChildren()) {
                //**** code is bloated!
                paint.save();
                QPen pen = paint.pen();
                int width = 2 * scaleFactor;
                pen.setWidth(width);
                paint.setPen(pen);
                QRect rect2 = rect;
                width /= 2;
                rect2.adjust(width, width, -width, -width);
                paint.drawArc(rect2, (*it)->start(), (*it)->length());
                paint.restore();
            }
        }

        if (excess >= 0) {  //excess allows us to resize more smoothly (still crud tho)
            if (excess < 2)  //only decrease rect by more if even number of excesses left
                --step;
            excess -= 2;
        }

        rect.adjust(step, step, -step, -step);
    }

    //  if( excess > 0 ) rect.adjust( excess, excess, 0, 0 ); //ugly

    paint.setPen(COLOR_GREY);
    paint.setBrush(Qt::white);
    paint.drawEllipse(rect);

    if (scaleFactor > 1) {
        //have to end in order to smoothscale()
        paint.end();

        int x1, y1, x2, y2;
        rect.getCoords(&x1, &y1, &x2, &y2);
        x1 /= scaleFactor;
        y1 /= scaleFactor;
        x2 /= scaleFactor;
        y2 /= scaleFactor;
        rect.setCoords(x1, y1, x2, y2);

        QImage img = this->toImage();
        img = img.scaled(this->size() / (int)scaleFactor, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
        this->QPixmap::operator=(fromImage(img, Qt::AutoColor));

        paint.begin(this);
        paint.setPen(COLOR_GREY);
        paint.setBrush(Qt::white);
    }

    paint.drawText(rect, Qt::AlignCenter, m_centerText);

    m_innerRadius = rect.width() / 2; //rect.width should be multiple of 2

    paint.end();
}
void NcWidgetData::resizeWidget( const QPoint& globalMousePos )
{
  QRect origRect;

  if ( d->mUseRubberBandOnResize )
    origRect = mRubberBand->frameGeometry();
  else
    origRect = mWidget->frameGeometry();


  int left = origRect.left();
  int top = origRect.top();
  int right = origRect.right();
  int bottom = origRect.bottom();
  origRect.getCoords( &left, &top, &right, &bottom );

  int minWidth = mWidget->minimumWidth();
  int minHeight = mWidget->minimumHeight();

  if ( mPressedMousePos.onTopLeftEdge )
  {
    left = globalMousePos.x();
    top = globalMousePos.y();
  }
  else if ( mPressedMousePos.onBottomLeftEdge )
  {
    left = globalMousePos.x();
    bottom = globalMousePos.y();
  }
  else if ( mPressedMousePos.onTopRightEdge )
  {
    right = globalMousePos.x();
    top = globalMousePos.y();
  }
  else if ( mPressedMousePos.onBottomRightEdge )
  {
    right = globalMousePos.x();
    bottom = globalMousePos.y();
  }
  else if ( mPressedMousePos.onLeftEdge )
  {
    left = globalMousePos.x();
  }
  else if ( mPressedMousePos.onRightEdge )
  {
    right = globalMousePos.x();
  }
  else if ( mPressedMousePos.onTopEdge )
  {
    top = globalMousePos.y();
  }
  else if ( mPressedMousePos.onBottomEdge )
  {
    bottom = globalMousePos.y();
  }

  QRect newRect( QPoint(left, top), QPoint(right, bottom) );

  if ( newRect.isValid() )
  {
    if ( minWidth > newRect.width() )
    {
      //determine what has caused the width change.
      if( left != origRect.left() )
        newRect.setLeft( origRect.left() );
      else
        newRect.setRight( origRect.right() );
    }
    if ( minHeight > newRect.height() )
    {
      //determine what has caused the height change.
      if ( top != origRect.top() )
        newRect.setTop( origRect.top() );
      else
        newRect.setBottom( origRect.bottom() );
    }

    if ( d->mUseRubberBandOnResize )
    {
      mRubberBand->setGeometry( newRect );
    }
    else
    {
      mWidget->setGeometry( newRect );
    }
  }
  else
  {
    //qDebug() << "Calculated Rect is not valid" << newRect;
  }

}
void PlastikClient::paintEvent(QPaintEvent *e)
{
    QRegion region = e->region();

    PlastikHandler *handler = Handler();

    if (oldCaption != caption() )
        clearCaptionPixmaps();

    bool active = isActive();
    bool toolWindow = isToolWindow();

    QPainter painter(widget() );

    // often needed coordinates
    QRect r = widget()->rect();

    int r_w = r.width();
//     int r_h = r.height();
    int r_x, r_y, r_x2, r_y2;
    r.getCoords(&r_x, &r_y, &r_x2, &r_y2);
    const int borderLeft = layoutMetric(LM_BorderLeft);
    const int borderRight = layoutMetric(LM_BorderRight);
    const int borderBottom = layoutMetric(LM_BorderBottom);
    const int titleHeight = layoutMetric(LM_TitleHeight);
    const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
    const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
    const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft);
    const int titleEdgeRight = layoutMetric(LM_TitleEdgeRight);

    const int borderBottomTop = r_y2-borderBottom+1;
    const int borderLeftRight = r_x+borderLeft-1;
    const int borderRightLeft = r_x2-borderRight+1;
    const int titleEdgeBottomBottom = r_y+titleEdgeTop+titleHeight+titleEdgeBottom-1;

    const int sideHeight = borderBottomTop-titleEdgeBottomBottom-1;

    QRect Rtitle = QRect(r_x+titleEdgeLeft+buttonsLeftWidth(), r_y+titleEdgeTop,
                         r_x2-titleEdgeRight-buttonsRightWidth()-(r_x+titleEdgeLeft+buttonsLeftWidth()),
                         titleEdgeBottomBottom-(r_y+titleEdgeTop) );

    QRect tempRect;

    // topSpacer
    if(titleEdgeTop > 0)
    {
        tempRect.setRect(r_x+2, r_y, r_w-2*2, titleEdgeTop );
        if (tempRect.isValid() && region.contains(tempRect) ) {
            painter.drawTiledPixmap(tempRect, handler->pixmap(qubes_label, TitleBarTileTop, active, toolWindow) );
        }
    }

    // leftTitleSpacer
    int titleMarginLeft = 0;
    int titleMarginRight = 0;
    if(titleEdgeLeft > 0)
    {
        tempRect.setRect(r_x, r_y, borderLeft, titleEdgeTop+titleHeight+titleEdgeBottom);
        if (tempRect.isValid() && region.contains(tempRect) ) {
            painter.drawTiledPixmap(tempRect, handler->pixmap(qubes_label, TitleBarLeft, active, toolWindow) );
            titleMarginLeft = borderLeft;
        }
    }

    // rightTitleSpacer
    if(titleEdgeRight > 0)
    {
        tempRect.setRect(borderRightLeft, r_y, borderRight, titleEdgeTop+titleHeight+titleEdgeBottom);
        if (tempRect.isValid() && region.contains(tempRect) ) {
            painter.drawTiledPixmap(tempRect, handler->pixmap(qubes_label, TitleBarRight, active, toolWindow) );
            titleMarginRight = borderRight;
        }
    }

    // titleSpacer
    const QPixmap &caption = captionPixmap();
    if(Rtitle.width() > 0)
    {
        m_captionRect = captionRect(); // also update m_captionRect!
        if (m_captionRect.isValid() && region.contains(m_captionRect) )
        {
            painter.drawTiledPixmap(m_captionRect, caption);
        }

        // left to the title
        tempRect.setRect(r_x+titleMarginLeft, m_captionRect.top(),
                         m_captionRect.left() - (r_x+titleMarginLeft), m_captionRect.height() );
        if (tempRect.isValid() && region.contains(tempRect) ) {
            painter.drawTiledPixmap(tempRect, handler->pixmap(qubes_label, TitleBarTile, active, toolWindow) );
        }

        // right to the title
        tempRect.setRect(m_captionRect.right()+1, m_captionRect.top(),
                         (r_x2-titleMarginRight) - m_captionRect.right(), m_captionRect.height() );
        if (tempRect.isValid() && region.contains(tempRect) ) {
            painter.drawTiledPixmap(tempRect, handler->pixmap(qubes_label, TitleBarTile, active, toolWindow) );
        }

    }

    // leftSpacer
    if(borderLeft > 0 && sideHeight > 0)
    {
        tempRect.setCoords(r_x, titleEdgeBottomBottom+1, borderLeftRight, borderBottomTop-1);
        if (tempRect.isValid() && region.contains(tempRect) ) {
            painter.drawTiledPixmap(tempRect, handler->pixmap(qubes_label, BorderLeftTile, active, toolWindow) );
        }
    }

    // rightSpacer
    if(borderRight > 0 && sideHeight > 0)
    {
        tempRect.setCoords(borderRightLeft, titleEdgeBottomBottom+1, r_x2, borderBottomTop-1);
        if (tempRect.isValid() && region.contains(tempRect) ) {
            painter.drawTiledPixmap(tempRect, handler->pixmap(qubes_label, BorderRightTile, active, toolWindow) );
        }
    }

    // bottomSpacer
    if(borderBottom > 0)
    {
        int l = r_x;
        int r = r_x2;

        tempRect.setRect(r_x, borderBottomTop, borderLeft, borderBottom);
        if (tempRect.isValid() && region.contains(tempRect) ) {
            painter.drawTiledPixmap(tempRect, handler->pixmap(qubes_label, BorderBottomLeft, active, toolWindow) );
            l = tempRect.right()+1;
        }

        tempRect.setRect(borderRightLeft, borderBottomTop, borderLeft, borderBottom);
        if (tempRect.isValid() && region.contains(tempRect) ) {
            painter.drawTiledPixmap(tempRect, handler->pixmap(qubes_label, BorderBottomRight, active, toolWindow) );
            r = tempRect.left()-1;
        }

        tempRect.setCoords(l, borderBottomTop, r, r_y2);
        if (tempRect.isValid() && region.contains(tempRect) ) {
            painter.drawTiledPixmap(tempRect, handler->pixmap(qubes_label, BorderBottomTile, active, toolWindow) );
        }
    }
}