|
Packit |
8e9c33 |
/*************************************************************************
|
|
Packit |
8e9c33 |
* Copyright (C) 2014 by Hugo Pereira Da Costa <hugo.pereira@free.fr> *
|
|
Packit |
8e9c33 |
* *
|
|
Packit |
8e9c33 |
* This program is free software; you can redistribute it and/or modify *
|
|
Packit |
8e9c33 |
* it under the terms of the GNU General Public License as published by *
|
|
Packit |
8e9c33 |
* the Free Software Foundation; either version 2 of the License, or *
|
|
Packit |
8e9c33 |
* (at your option) any later version. *
|
|
Packit |
8e9c33 |
* *
|
|
Packit |
8e9c33 |
* This program is distributed in the hope that it will be useful, *
|
|
Packit |
8e9c33 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
Packit |
8e9c33 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
Packit |
8e9c33 |
* GNU General Public License for more details. *
|
|
Packit |
8e9c33 |
* *
|
|
Packit |
8e9c33 |
* You should have received a copy of the GNU General Public License *
|
|
Packit |
8e9c33 |
* along with this program; if not, write to the *
|
|
Packit |
8e9c33 |
* Free Software Foundation, Inc., *
|
|
Packit |
8e9c33 |
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
|
|
Packit |
8e9c33 |
*************************************************************************/
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
#include "adwaitatileset.h"
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
#include <QPainter>
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
namespace Adwaita
|
|
Packit |
8e9c33 |
{
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
//___________________________________________________________
|
|
Packit |
8e9c33 |
inline bool bits(TileSet::Tiles flags, TileSet::Tiles testFlags)
|
|
Packit |
8e9c33 |
{ return (flags & testFlags) == testFlags; }
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
//______________________________________________________________________________________
|
|
Packit |
8e9c33 |
inline qreal devicePixelRatio( const QPixmap& pixmap )
|
|
Packit |
8e9c33 |
{
|
|
Packit |
8e9c33 |
#if QT_VERSION >= 0x050300
|
|
Packit |
8e9c33 |
return pixmap.devicePixelRatio();
|
|
Packit |
8e9c33 |
#else
|
|
Packit |
8e9c33 |
Q_UNUSED( pixmap );
|
|
Packit |
8e9c33 |
return 1;
|
|
Packit |
8e9c33 |
#endif
|
|
Packit |
8e9c33 |
}
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
//______________________________________________________________________________________
|
|
Packit |
8e9c33 |
inline void setDevicePixelRatio( QPixmap& pixmap, qreal value )
|
|
Packit |
8e9c33 |
{
|
|
Packit |
8e9c33 |
#if QT_VERSION >= 0x050300
|
|
Packit |
8e9c33 |
return pixmap.setDevicePixelRatio( value );
|
|
Packit |
8e9c33 |
#else
|
|
Packit |
8e9c33 |
Q_UNUSED( pixmap );
|
|
Packit |
8e9c33 |
Q_UNUSED( value );
|
|
Packit |
8e9c33 |
#endif
|
|
Packit |
8e9c33 |
}
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
//______________________________________________________________
|
|
Packit |
8e9c33 |
void TileSet::initPixmap( PixmapList& pixmaps, const QPixmap &source, int width, int height, const QRect &rect)
|
|
Packit |
8e9c33 |
{
|
|
Packit |
8e9c33 |
QSize size( width, height );
|
|
Packit |
8e9c33 |
if( !( size.isValid() && rect.isValid() ) )
|
|
Packit |
8e9c33 |
{
|
|
Packit |
8e9c33 |
pixmaps.append( QPixmap() );
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
} else if( size != rect.size() ) {
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
qreal dpiRatio( devicePixelRatio( source ) );
|
|
Packit |
8e9c33 |
QRect scaledRect( rect.topLeft()*dpiRatio, rect.size()*dpiRatio );
|
|
Packit |
8e9c33 |
QSize scaledSize( size*dpiRatio );
|
|
Packit |
8e9c33 |
QPixmap tile( source.copy(scaledRect) );
|
|
Packit |
8e9c33 |
QPixmap pixmap( scaledSize );
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
pixmap.fill(Qt::transparent);
|
|
Packit |
8e9c33 |
QPainter painter(&pixmap);
|
|
Packit |
8e9c33 |
painter.drawTiledPixmap(0, 0, scaledSize.width(), scaledSize.height(), tile);
|
|
Packit |
8e9c33 |
setDevicePixelRatio( pixmap, dpiRatio );
|
|
Packit |
8e9c33 |
pixmaps.append( pixmap );
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
} else {
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
qreal dpiRatio( devicePixelRatio( source ) );
|
|
Packit |
8e9c33 |
QRect scaledRect( rect.topLeft()*dpiRatio, rect.size()*dpiRatio );
|
|
Packit |
8e9c33 |
QPixmap pixmap( source.copy( scaledRect ) );
|
|
Packit |
8e9c33 |
setDevicePixelRatio( pixmap, dpiRatio );
|
|
Packit |
8e9c33 |
pixmaps.append( pixmap );
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
}
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
}
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
//______________________________________________________________
|
|
Packit |
8e9c33 |
TileSet::TileSet( void ):
|
|
Packit |
8e9c33 |
_w1(0),
|
|
Packit |
8e9c33 |
_h1(0),
|
|
Packit |
8e9c33 |
_w3(0),
|
|
Packit |
8e9c33 |
_h3(0)
|
|
Packit |
8e9c33 |
{ _pixmaps.reserve(9); }
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
//______________________________________________________________
|
|
Packit |
8e9c33 |
TileSet::TileSet(const QPixmap &source, int w1, int h1, int w2, int h2 ):
|
|
Packit |
8e9c33 |
_w1(w1),
|
|
Packit |
8e9c33 |
_h1(h1),
|
|
Packit |
8e9c33 |
_w3(0),
|
|
Packit |
8e9c33 |
_h3(0)
|
|
Packit |
8e9c33 |
{
|
|
Packit |
8e9c33 |
_pixmaps.reserve(9);
|
|
Packit |
8e9c33 |
if( source.isNull() ) return;
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
_w3 = source.width()/devicePixelRatio( source ) - (w1 + w2);
|
|
Packit |
8e9c33 |
_h3 = source.height()/devicePixelRatio( source ) - (h1 + h2);
|
|
Packit |
8e9c33 |
int w = w2;
|
|
Packit |
8e9c33 |
int h = h2;
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
// initialise pixmap array
|
|
Packit |
8e9c33 |
initPixmap( _pixmaps, source, _w1, _h1, QRect(0, 0, _w1, _h1) );
|
|
Packit |
8e9c33 |
initPixmap( _pixmaps, source, w, _h1, QRect(_w1, 0, w2, _h1) );
|
|
Packit |
8e9c33 |
initPixmap( _pixmaps, source, _w3, _h1, QRect(_w1+w2, 0, _w3, _h1) );
|
|
Packit |
8e9c33 |
initPixmap( _pixmaps, source, _w1, h, QRect(0, _h1, _w1, h2) );
|
|
Packit |
8e9c33 |
initPixmap( _pixmaps, source, w, h, QRect(_w1, _h1, w2, h2) );
|
|
Packit |
8e9c33 |
initPixmap( _pixmaps, source, _w3, h, QRect(_w1+w2, _h1, _w3, h2) );
|
|
Packit |
8e9c33 |
initPixmap( _pixmaps, source, _w1, _h3, QRect(0, _h1+h2, _w1, _h3) );
|
|
Packit |
8e9c33 |
initPixmap( _pixmaps, source, w, _h3, QRect(_w1, _h1+h2, w2, _h3) );
|
|
Packit |
8e9c33 |
initPixmap( _pixmaps, source, _w3, _h3, QRect(_w1+w2, _h1+h2, _w3, _h3) );
|
|
Packit |
8e9c33 |
}
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
//___________________________________________________________
|
|
Packit |
8e9c33 |
void TileSet::render(const QRect &constRect, QPainter *painter, Tiles tiles) const
|
|
Packit |
8e9c33 |
{
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
bool oldHint( painter->testRenderHint( QPainter::SmoothPixmapTransform ) );
|
|
Packit |
8e9c33 |
painter->setRenderHint( QPainter::SmoothPixmapTransform, true );
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
// check initialization
|
|
Packit |
8e9c33 |
if( _pixmaps.size() < 9 ) return;
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
// copy source rect
|
|
Packit |
8e9c33 |
QRect rect( constRect );
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
// get rect dimensions
|
|
Packit |
8e9c33 |
int x0, y0, w, h;
|
|
Packit |
8e9c33 |
rect.getRect(&x0, &y0, &w, &h);
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
// calculate pixmaps widths
|
|
Packit |
8e9c33 |
int wLeft(0);
|
|
Packit |
8e9c33 |
int wRight(0);
|
|
Packit |
8e9c33 |
if( _w1+_w3 > 0 )
|
|
Packit |
8e9c33 |
{
|
|
Packit |
8e9c33 |
qreal wRatio( qreal( _w1 )/qreal( _w1 + _w3 ) );
|
|
Packit |
8e9c33 |
wLeft = (tiles&Right) ? qMin( _w1, int(w*wRatio) ):_w1;
|
|
Packit |
8e9c33 |
wRight = (tiles&Left) ? qMin( _w3, int(w*(1.0-wRatio)) ):_w3;
|
|
Packit |
8e9c33 |
}
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
// calculate pixmap heights
|
|
Packit |
8e9c33 |
int hTop(0);
|
|
Packit |
8e9c33 |
int hBottom(0);
|
|
Packit |
8e9c33 |
if( _h1+_h3 > 0 )
|
|
Packit |
8e9c33 |
{
|
|
Packit |
8e9c33 |
qreal hRatio( qreal( _h1 )/qreal( _h1 + _h3 ) );
|
|
Packit |
8e9c33 |
hTop = (tiles&Bottom) ? qMin( _h1, int(h*hRatio) ):_h1;
|
|
Packit |
8e9c33 |
hBottom = (tiles&Top) ? qMin( _h3, int(h*(1.0-hRatio)) ):_h3;
|
|
Packit |
8e9c33 |
}
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
// calculate corner locations
|
|
Packit |
8e9c33 |
w -= wLeft + wRight;
|
|
Packit |
8e9c33 |
h -= hTop + hBottom;
|
|
Packit |
8e9c33 |
int x1 = x0 + wLeft;
|
|
Packit |
8e9c33 |
int x2 = x1 + w;
|
|
Packit |
8e9c33 |
int y1 = y0 + hTop;
|
|
Packit |
8e9c33 |
int y2 = y1 + h;
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
int w2 = _pixmaps.at(7).width()/devicePixelRatio( _pixmaps.at(7) );
|
|
Packit |
8e9c33 |
int h2 = _pixmaps.at(5).height()/devicePixelRatio( _pixmaps.at(5) );
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
// corner
|
|
Packit |
8e9c33 |
if( bits( tiles, Top|Left) ) painter->drawPixmap(x0, y0, _pixmaps.at(0), 0, 0, wLeft*devicePixelRatio( _pixmaps.at(0) ), hTop*devicePixelRatio( _pixmaps.at(0) ));
|
|
Packit |
8e9c33 |
if( bits( tiles, Top|Right) ) painter->drawPixmap(x2, y0, _pixmaps.at(2), (_w3-wRight)*devicePixelRatio( _pixmaps.at(2) ), 0, wRight*devicePixelRatio( _pixmaps.at(2) ), hTop*devicePixelRatio( _pixmaps.at(2) ) );
|
|
Packit |
8e9c33 |
if( bits( tiles, Bottom|Left) ) painter->drawPixmap(x0, y2, _pixmaps.at(6), 0, (_h3-hBottom)*devicePixelRatio( _pixmaps.at(6) ), wLeft*devicePixelRatio( _pixmaps.at(6) ), hBottom*devicePixelRatio( _pixmaps.at(6) ));
|
|
Packit |
8e9c33 |
if( bits( tiles, Bottom|Right) ) painter->drawPixmap(x2, y2, _pixmaps.at(8), (_w3-wRight)*devicePixelRatio( _pixmaps.at(8) ), (_h3-hBottom)*devicePixelRatio( _pixmaps.at(8) ), wRight*devicePixelRatio( _pixmaps.at(8) ), hBottom*devicePixelRatio( _pixmaps.at(8) ) );
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
// top and bottom
|
|
Packit |
8e9c33 |
if( w > 0 )
|
|
Packit |
8e9c33 |
{
|
|
Packit |
8e9c33 |
if( tiles&Top ) painter->drawPixmap(x1, y0, w, hTop, _pixmaps.at(1), 0, 0, w2*devicePixelRatio( _pixmaps.at(1) ), hTop*devicePixelRatio( _pixmaps.at(1) ) );
|
|
Packit |
8e9c33 |
if( tiles&Bottom ) painter->drawPixmap(x1, y2, w, hBottom, _pixmaps.at(7), 0, (_h3-hBottom)*devicePixelRatio( _pixmaps.at(7) ), w2*devicePixelRatio( _pixmaps.at(7) ), hBottom*devicePixelRatio( _pixmaps.at(7) ) );
|
|
Packit |
8e9c33 |
}
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
// left and right
|
|
Packit |
8e9c33 |
if( h > 0 )
|
|
Packit |
8e9c33 |
{
|
|
Packit |
8e9c33 |
if( tiles&Left ) painter->drawPixmap(x0, y1, wLeft, h, _pixmaps.at(3), 0, 0, wLeft*devicePixelRatio( _pixmaps.at(3) ), h2*devicePixelRatio( _pixmaps.at(3) ) );
|
|
Packit |
8e9c33 |
if( tiles&Right ) painter->drawPixmap(x2, y1, wRight, h, _pixmaps.at(5), (_w3-wRight)*devicePixelRatio( _pixmaps.at(5) ), 0, wRight*devicePixelRatio( _pixmaps.at(5) ), h2*devicePixelRatio( _pixmaps.at(5) ) );
|
|
Packit |
8e9c33 |
}
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
// center
|
|
Packit |
8e9c33 |
if( (tiles&Center) && h > 0 && w > 0 ) painter->drawPixmap(x1, y1, w, h, _pixmaps.at(4));
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
// restore
|
|
Packit |
8e9c33 |
painter->setRenderHint( QPainter::SmoothPixmapTransform, oldHint );
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
}
|
|
Packit |
8e9c33 |
|
|
Packit |
8e9c33 |
}
|