Commit 1d5bc657 authored by Dmitry Suzdalev's avatar Dmitry Suzdalev
Browse files

Introduce support for themeable border around the game field.

Idea belongs to (guess who) Eugene.
He already adjusted current default theme to include border for me to play with
while implementing this feature. Not sure if it's the final one :)

Ah, and older themes still will work - KLines will figure out whether theme has a border
element and act accordingly.

Waiting for new themes to come up! ;)


svn path=/trunk/KDE/kdegames/klines/; revision=772468
parent 9722ec38
......@@ -52,6 +52,16 @@ Example of IDs: e_born_1, e_born_2, ... e_born_N
7. Background image with ID: background
8. Optional border with ID: border
If theme author wishes, he can add a border element that will be painted
around game field, i.e. all cells will be painted inside border element's area
IMPORTANT NOTE: Game assumes that border visual side size will be half of field cell's size.
And will render it based on this assumtion. I.e. if border element exists in theme, game
will render cells slightly smaller, by decreasing their size on half of usual size.
Oh, hope you'll understand this :)
Better - just take a look at the current border rich themes as an example ;)
It's simple
That's all for SVG part. Let's move to simpler one: .desktop file :)
-= .desktop file =-
......
......@@ -43,6 +43,8 @@ MainWidget::MainWidget( QWidget* parent )
QGraphicsView::DontAdjustForAntialiasing );
mainLay->addWidget( klview );
setMinimumSize( 250, 250 );
}
MainWidget::~MainWidget()
......
......@@ -201,3 +201,17 @@ QPixmap KLinesRenderer::pixmapFromCache(const QString& svgName, const QSize& cus
}
return pix;
}
QPixmap KLinesRenderer::backgroundBorderPixmap( const QSize& size ) const
{
if( !hasBorderElement() )
return QPixmap();
return pixmapFromCache( "border", size );
}
bool KLinesRenderer::hasBorderElement() const
{
return m_renderer->elementExists( "border" );
}
......@@ -69,6 +69,13 @@ public:
* @return pixmap for background painting.
*/
QPixmap backgroundPixmap(const QSize& size) const;
/**
* @return pixmap for border surrounding the play field.
* Will return an invalid QPixmap if no such element exists
* in theme's svg file.
* @see hasBorderElement
*/
QPixmap backgroundBorderPixmap( const QSize& size ) const;
/**
* @return pixmap of background tile (cell)
*/
......@@ -86,6 +93,8 @@ public:
*/
int cellSize() const { return m_cellSize; }
bool hasBorderElement() const;
/**
* @return number of frames in animation sequence of type t
*/
......
......@@ -35,7 +35,7 @@
KLinesScene::KLinesScene( QObject* parent )
: QGraphicsScene(parent),
m_playFieldOrigin(0, 0 ), m_numFreeCells(FIELD_SIZE*FIELD_SIZE),
m_playFieldBorderSize(0), m_numFreeCells(FIELD_SIZE*FIELD_SIZE),
m_score(0), m_bonusScore(0), m_cellSize(32), m_previewZoneVisible(true)
{
m_animator = new KLinesAnimator(this);
......@@ -114,18 +114,30 @@ void KLinesScene::resizeScene(int width,int height)
// store focus item field pos (calculated using old cellSize)
FieldPos focusRectFieldPos = pixToField( m_focusItem->pos() );
bool hasBorder = KLinesRenderer::self()->hasBorderElement();
int minDim = qMin( width, height );
m_cellSize = minDim/FIELD_SIZE;
// border width is hardcoded to be half of cell size.
// take it into account if it exists
m_cellSize = hasBorder ? minDim/(FIELD_SIZE+1) : minDim/FIELD_SIZE;
// set it only if current theme supports it
m_playFieldBorderSize = hasBorder ? m_cellSize/2 : 0;
int boardSize = m_cellSize * FIELD_SIZE;
if (m_previewZoneVisible && boardSize + m_cellSize > width) // No space enough for balls preview
if ( m_previewZoneVisible && boardSize +m_playFieldBorderSize*2 + m_cellSize > width) // No space enough for balls preview
{
minDim = width;
m_cellSize = (minDim - m_cellSize)/FIELD_SIZE;
m_cellSize = hasBorder ? (minDim - m_cellSize - m_playFieldBorderSize*2)/FIELD_SIZE : (minDim - m_cellSize)/FIELD_SIZE;
boardSize = m_cellSize * FIELD_SIZE;
}
m_playFieldOrigin = QPoint( (width - (m_previewZoneVisible ? m_cellSize : 0))/2 - boardSize/2, height/2 - boardSize/2 );
m_playFieldRect.setX( (width - (m_previewZoneVisible ? m_cellSize : 0))/2 - boardSize/2 - m_playFieldBorderSize );
m_playFieldRect.setY( height/2 - boardSize/2 - m_playFieldBorderSize );
m_playFieldRect.setWidth( boardSize + m_playFieldBorderSize*2 );
m_playFieldRect.setHeight( boardSize + m_playFieldBorderSize*2 );
setSceneRect( 0, 0, width, height );
......@@ -233,8 +245,12 @@ BallItem* KLinesScene::randomlyPlaceBall(BallColor c)
void KLinesScene::mousePressEvent( QGraphicsSceneMouseEvent* ev )
{
QGraphicsScene::mousePressEvent(ev);
if ( !QRectF( m_playFieldOrigin.x(), m_playFieldOrigin.y(),
m_cellSize*FIELD_SIZE, m_cellSize*FIELD_SIZE ).contains( ev->scenePos() ) )
QRect boardRect = m_playFieldRect.adjusted( m_playFieldBorderSize,
m_playFieldBorderSize,
-m_playFieldBorderSize,
-m_playFieldBorderSize );
if ( !boardRect.contains( ev->scenePos().toPoint() ) )
return;
selectOrMove( pixToField(ev->scenePos()) );
......@@ -629,9 +645,17 @@ void KLinesScene::undo()
void KLinesScene::drawBackground(QPainter *p, const QRectF&)
{
QPixmap tile = KLinesRenderer::self()->backgroundTilePixmap();
p->drawPixmap( 0,0, KLinesRenderer::self()->backgroundPixmap(sceneRect().size().toSize()) );
for(int x=m_playFieldOrigin.x(); x<m_playFieldOrigin.x()+m_cellSize*FIELD_SIZE;x+=m_cellSize)
for(int y=m_playFieldOrigin.y(); y<m_playFieldOrigin.y()+m_cellSize*FIELD_SIZE;y+=m_cellSize)
p->drawPixmap( 0, 0, KLinesRenderer::self()->backgroundPixmap(sceneRect().size().toSize()) );
p->drawPixmap( m_playFieldRect.x(), m_playFieldRect.y(),
KLinesRenderer::self()->backgroundBorderPixmap( m_playFieldRect.size() ) );
int startX = m_playFieldRect.x()+m_playFieldBorderSize;
int maxX = m_playFieldRect.x()+m_cellSize*FIELD_SIZE;
int startY = m_playFieldRect.y()+m_playFieldBorderSize;
int maxY = m_playFieldRect.y()+m_cellSize*FIELD_SIZE;
for(int x=startX; x<maxX; x+=m_cellSize)
for(int y=startY; y<maxY; y+=m_cellSize)
p->drawPixmap( x, y, tile );
}
......
......@@ -83,16 +83,16 @@ public:
*/
inline QPointF fieldToPix(const FieldPos& fpos) const
{
return QPointF( m_playFieldOrigin.x()+fpos.x*m_cellSize,
m_playFieldOrigin.y()+fpos.y*m_cellSize );
return QPointF( m_playFieldRect.x() + m_playFieldBorderSize + fpos.x*m_cellSize,
m_playFieldRect.y() + m_playFieldBorderSize + fpos.y*m_cellSize );
}
/**
* Pixel coords to field coords
*/
inline FieldPos pixToField( const QPointF& p ) const
{
return FieldPos(static_cast<int>(( p.x()-m_playFieldOrigin.x() )/m_cellSize),
static_cast<int>(( p.y()-m_playFieldOrigin.y() )/m_cellSize));
return FieldPos(static_cast<int>(( p.x()-m_playFieldRect.x()-m_playFieldBorderSize )/m_cellSize),
static_cast<int>(( p.y()-m_playFieldRect.y()-m_playFieldBorderSize )/m_cellSize));
}
public slots:
/**
......@@ -182,9 +182,15 @@ private:
*/
KRandomSequence m_randomSeq;
/**
* Origin of playfield
* Area of playfield (with border included - if any exists in theme)
*/
QPoint m_playFieldOrigin;
QRect m_playFieldRect;
/**
* Size of a playfield border.
* Equals 0 if there's no border element in current theme
*/
int m_playFieldBorderSize;
/**
* Position of selected ball (-1,-1) if none
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment