2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@gmail.com>
3 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
13 #include <QMouseEvent>
15 #include <core/color.h>
16 #include "chesstable.h"
19 #include "connection.h"
20 #include "piecepool.h"
22 #include "mastersettings.h"
23 #include "movelist_table.h"
24 #include "infodisplay.h"
26 using namespace boost
;
28 ChessTable::ChessTable(Variant
* variant
, QWidget
* parent
)
29 : KGameCanvasWidget(parent
)
33 , m_need_reload(false)
34 , m_components(variant
) {
36 setMouseTracking(true);
39 m_board
= new ChessBoard(&m_components
, &m_anim_manager
, this);
43 m_movelist
= new MoveList::Table
;
46 for(int i
=0;i
<2;i
++) {
47 m_clocks
[i
] = new Clock(i
, this);
50 m_clocks
[0]->activate(0);
52 // create info display
53 m_info
= new InfoDisplay(this);
57 // FIXME what to do for more than 2 players?
58 for (int i
= 0; i
< 2; i
++) {
59 const IColor
* color
= m_components
.player(i
);
61 m_pools
[i
] = new PiecePool(color
, m_board
, &m_anim_manager
, this);
70 ChessTable::~ChessTable() {
80 void ChessTable::renderWallpaper() {
81 if (!m_background_pixmap
.isNull()) {
82 QPixmap bg
= m_background_pixmap
;
83 // scale & crop background
84 double ratio_x
= (double) width() / m_background_pixmap
.width();
85 double ratio_y
= (double) height() / m_background_pixmap
.height();
86 if (ratio_x
> ratio_y
)
87 bg
= bg
.scaledToWidth(width(), Qt::SmoothTransformation
);
89 bg
= bg
.scaledToHeight(height(), Qt::SmoothTransformation
);
90 QSize
size(width(), height());
91 QImage
res(size
, QImage::Format_ARGB32_Premultiplied
);
94 (bg
.width() - width()) / 2,
95 (bg
.height() - height()) / 2);
96 kDebug() << "img size" << bg
.size();
97 kDebug() << "size" << size
;
98 kDebug() << "pos" << pos
;
100 p
.drawPixmap(QPoint(0,0), bg
, QRectF(pos
, size
));
103 bg
= QPixmap::fromImage(res
);
105 m_wallpaper
->setPixmap(bg
);
109 m_wallpaper
= new KGameCanvasPixmap(QPixmap::fromImage(res
), this);
110 m_wallpaper
->lower();
120 void ChessTable::settingsChanged() {
121 m_anim_manager
.reload();
123 m_board
->settingsChanged();
125 m_clocks
[i
]->settingsChanged();
126 m_info
->settingsChanged();
128 m_pools
[i
]->settingsChanged();
130 m_background_pixmap
= m_board
->controlsLoader()->getStaticValue
<QPixmap
>("wallpaper", 0, true);
133 /* redo the layout, forcing reload */
137 m_need_reload
= true;
140 ClickableCanvas
* ChessTable::eventItemAt(QPoint pos
) {
141 if (m_board
->boardRect().contains(pos
))
144 for (int i
=0; i
<2; i
++)
145 if (m_pools
[i
]->boardRect().contains(pos
))
148 for (int i
=0; i
<2; i
++)
149 if (m_clocks
[i
]->rect().contains(pos
))
155 void ChessTable::setEntity(const boost::shared_ptr
<UserEntity
>& entity
) {
156 m_board
->setEntity(entity
);
159 void ChessTable::layout(bool force_reload
) {
160 force_reload
|= m_need_reload
;
161 m_need_reload
= false;
165 ::LuaApi::LuaValueMap params
;
166 params
["width"] = width();
167 params
["height"] = height();
168 params
["grid_size"] = QPointF(m_board
->gridSize());
170 ::LuaApi::LuaValueMap lvals
= m_board
->controlsLoader()->getStaticValue
< ::LuaApi::LuaValueMap
>("layout", ¶ms
);
173 for(::LuaApi::LuaValueMap::iterator it
= lvals
.begin(); it
!= lvals
.end(); ++it
)
174 if(double* val
= boost::get
<double>(&it
.value()))
175 kDebug() << "lvals[" << it
.key() << "] = " << *val
;
176 else if(QPointF
* val
= boost::get
<QPointF
>(&it
.value()))
177 kDebug() << "lvals[" << it
.key() << "] = Point(" << val
->x() << "," << val
->y() << ")";
178 else if(QRectF
* val
= boost::get
<QRectF
>(&it
.value()))
179 kDebug() << "lvals[" << it
.key() << "] = Rect(" << val
->x() << "," << val
->y()
180 << "," << val
->width() << "," << val
->height() << ")";
183 #define GET_INT(name) \
185 {::LuaApi::LuaValueMap::iterator it = lvals.find(#name);\
186 if(double* val = (it==lvals.end()) ? 0 : boost::get<double>(&lvals[#name]) ) \
189 kError() << "Theme error:" << #name << "should be set to a number in the layout";}
191 #define GET_POINT(name) \
193 {::LuaApi::LuaValueMap::iterator it = lvals.find(#name);\
194 if(QPointF* val = (it==lvals.end()) ? 0 : boost::get<QPointF>(&lvals[#name]) ) \
195 name = val->toPoint(); \
197 kError() << "Theme error:" << #name << "should be set to a point in the layout";}
199 GET_POINT(board_position
);
200 GET_INT(square_size
);
201 GET_INT(border_size
);
202 GET_INT(border_text_near
);
203 GET_INT(border_text_far
);
204 GET_POINT(clock0_position
);
205 GET_POINT(clock1_position
);
207 GET_POINT(pool0_position
);
208 GET_POINT(pool1_position
);
209 GET_INT(pool_piece_size
);
212 m_board
->moveTo(board_position
.x(), board_position
.y());
213 m_board
->onResize( square_size
, border_size
, border_text_near
, border_text_far
, force_reload
);
215 int x
= !m_board
->flipped();
217 m_clocks
[x
]->resize(clock_size
);
218 m_clocks
[x
]->moveTo(clock0_position
.x(), clock0_position
.y());
219 // kDebug() << "moving clock " << x << " to " << clock0_position.y();
221 m_clocks
[!x
]->resize(clock_size
);
222 m_clocks
[!x
]->moveTo(clock1_position
.x(), clock1_position
.y());
223 // kDebug() << "moving clock " << !x << " to " << clock1_position.y();
225 m_pools
[x
]->m_flipped
= false;
226 m_pools
[x
]->onResize(pool_piece_size
, force_reload
);
227 m_pools
[x
]->moveTo(pool0_position
.x(), pool0_position
.y());
228 m_pools
[x
]->setGridWidth(pool_width
);
230 m_pools
[!x
]->m_flipped
= true;
231 m_pools
[!x
]->onResize(pool_piece_size
, force_reload
);
232 m_pools
[!x
]->moveTo(pool1_position
.x(), pool1_position
.y());
233 m_pools
[!x
]->setGridWidth(pool_width
);
236 void ChessTable::resizeEvent(QResizeEvent
* /*e*/) {
240 void ChessTable::mouseReleaseEvent(QMouseEvent
* e
) {
243 m_mousegrab
->onMouseRelease(e
->pos() - m_mousegrab
->pos(), e
->button() );
247 ClickableCanvas
* cb
= eventItemAt(e
->pos());
248 if(cb
!= m_current
) {
250 m_current
->onMouseLeave();
253 cb
->onMouseMove(e
->pos() - cb
->pos(), 0);
262 void ChessTable::mousePressEvent(QMouseEvent
* e
) {
264 m_mousegrab
->onMousePress(e
->pos() - m_mousegrab
->pos(), e
->button() );
268 ClickableCanvas
* cb
= eventItemAt(e
->pos());
269 if(cb
!= m_current
) {
271 m_current
->onMouseLeave();
277 cb
->onMousePress(e
->pos() - cb
->pos(), e
->button() );
282 void ChessTable::mouseMoveEvent(QMouseEvent
* e
) {
284 m_mousegrab
->onMouseMove(e
->pos() - m_mousegrab
->pos(), e
->button() );
288 ClickableCanvas
* cb
= eventItemAt(e
->pos());
289 if(cb
!= m_current
) {
291 m_current
->onMouseLeave();
297 cb
->onMouseMove(e
->pos() - cb
->pos(), e
->button() );
300 void ChessTable::enterEvent(QEvent
*) { }
302 void ChessTable::leaveEvent(QEvent
*) {
304 m_current
->onMouseLeave();
308 void ChessTable::flip() {
311 int delta
= qAbs(m_pools
[0]->pos().y() - m_pools
[1]->pos().y());
313 m_pools
[i
]->flipAndMoveBy( QPoint(0, delta
) );
316 QPoint pos
= m_clocks
[0]->pos();
317 m_clocks
[0]->moveTo(m_clocks
[1]->pos());
318 m_clocks
[1]->moveTo(pos
);
321 void ChessTable::flip(bool flipped
) {
322 if(m_board
->flipped() != flipped
)
326 void ChessTable::changeClock(int color
) {
327 if(m_clocks
[0]->running() || m_clocks
[1]->running())
328 for(int i
=0;i
<2;i
++) {
329 if ( (i
== color
) != m_clocks
[i
]->running() )
331 m_clocks
[i
]->start();
337 void ChessTable::updateTurn(int color
) {
338 for(int i
=0; i
<2; i
++)
339 m_clocks
[i
]->activate(color
== i
);
342 void ChessTable::stopClocks() {
343 for(int i
=0; i
<2; i
++)
347 void ChessTable::updateTime(int white
, int black
) {
348 m_clocks
[0]->setTime(white
);
349 m_clocks
[1]->setTime(black
);
352 void ChessTable::resetClock() {
355 for(int i
=0; i
<2; i
++)
356 m_clocks
[i
]->setPlayer(Player());
359 void ChessTable::setPlayers(const Player
& white
, const Player
& black
) {
360 m_clocks
[0]->setPlayer(white
);
361 m_clocks
[1]->setPlayer(black
);
364 void ChessTable::run() {
366 if(m_clocks
[i
]->active() && !m_clocks
[i
]->running())
367 m_clocks
[i
]->start();
370 void ChessTable::displayMessage(const QString
& msg
) {
375 AnimationManager
* ChessTable::animationManager() { return &m_anim_manager
; }
376 const AnimationManager
* ChessTable::animationManager() const { return &m_anim_manager
; }
378 void ChessTable::setVariant(Variant
* variant
) {
379 m_components
.setVariant(variant
);
382 Components
* ChessTable::components() { return &m_components
; }