Restored Pool animations.
[tagua/yd.git] / src / chesstable.cpp
blob76a0a4572a6fdc607d037e53454d068434a7c8cd
1 /*
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.
9 */
11 #include <iostream>
12 #include <QLayout>
13 #include <QSplitter>
14 #include <QMouseEvent>
16 #include <KDebug>
18 #include <core/color.h>
20 #include "chesstable.h"
21 #include "game.h"
22 #include "gameinfo.h"
23 #include "connection.h"
24 #include "piecepool.h"
25 #include "clock.h"
26 #include "mastersettings.h"
27 #include "movelist_table.h"
28 #include "infodisplay.h"
30 using namespace boost;
32 ChessTable::ChessTable(Variant* variant, QWidget* parent)
33 : KGameCanvasWidget(parent)
34 , m_wallpaper(NULL)
35 , m_current(NULL)
36 , m_mousegrab(NULL)
37 , m_need_reload(false)
38 , m_components(variant) {
40 setMouseTracking(true);
42 // create m_board
43 m_board = new ChessBoard(&m_components, &m_anim_manager, this);
44 m_board->show();
46 // create move list
47 m_movelist = new MoveList::Table;
49 // create clocks
50 for(int i=0;i<2;i++) {
51 m_clocks[i] = new Clock(i, this);
52 m_clocks[i]->show();
54 m_clocks[0]->activate(0);
56 // create info display
57 m_info = new InfoDisplay(this);
58 // m_info->show();
60 // create pools
61 // FIXME what to do for more than 2 players?
62 for (int i = 0; i < 2; i++) {
63 const IColor* color = m_components.player(i);
64 if (color) {
65 m_pools[i] = new PiecePool(color, m_board, &m_anim_manager, this);
66 m_pools[i]->show();
70 m_board->raise();
71 settingsChanged();
74 ChessTable::~ChessTable() {
75 for(int i=0;i<2;i++)
76 delete m_clocks[i];
77 delete m_movelist;
78 delete m_board;
79 for(int i=0;i<2;i++)
80 delete m_pools[i];
81 delete m_info;
84 void ChessTable::settingsChanged() {
85 m_anim_manager.reload();
87 m_board->settingsChanged();
88 for(int i=0;i<2;i++)
89 m_clocks[i]->settingsChanged();
90 m_info->settingsChanged();
91 for(int i=0;i<2;i++)
92 m_pools[i]->settingsChanged();
94 if(m_wallpaper)
95 delete m_wallpaper;
97 QPixmap bg = m_board->controlsLoader()->getStaticValue<QPixmap>("wallpaper", 0, true);
98 if (!bg.isNull()) {
99 m_wallpaper = new KGameCanvasTiledPixmap(bg, QSize(), QPoint(), false, this);
100 m_wallpaper->lower();
101 m_wallpaper->show();
103 else
104 m_wallpaper = 0;
106 /* redo the layout, forcing reload */
107 if(isVisible())
108 layout(true);
109 else
110 m_need_reload = true;
113 ClickableCanvas* ChessTable::eventItemAt(QPoint pos) {
114 if (m_board->boardRect().contains(pos))
115 return m_board;
117 for (int i=0; i<2; i++)
118 if (m_pools[i]->boardRect().contains(pos))
119 return m_pools[i];
121 for (int i=0; i<2; i++)
122 if (m_clocks[i]->rect().contains(pos))
123 return m_clocks[i];
125 return NULL;
128 void ChessTable::setEntity(const boost::shared_ptr<UserEntity>& entity) {
129 m_board->setEntity(entity);
132 void ChessTable::layout(bool force_reload) {
133 force_reload |= m_need_reload;
134 m_need_reload = false;
136 if (m_wallpaper) {
137 m_wallpaper->setSize(size());
138 QSize delta = (m_wallpaper->pixmap().size()-size())/2;
139 m_wallpaper->setOrigin(QPoint(delta.width(), delta.height()));
142 ::LuaApi::LuaValueMap params;
143 params["width"] = width();
144 params["height"] = height();
145 params["grid_size"] = QPointF(m_board->gridSize());
147 ::LuaApi::LuaValueMap lvals = m_board->controlsLoader()->getStaticValue< ::LuaApi::LuaValueMap>("layout", &params);
149 #if 0
150 for(::LuaApi::LuaValueMap::iterator it = lvals.begin(); it != lvals.end(); ++it)
151 if(double* val = boost::get<double>(&it.value()))
152 std::cout << "lvals[" << it.key() << "] = " << *val << std::endl;
153 else if(QPointF* val = boost::get<QPointF>(&it.value()))
154 std::cout << "lvals[" << it.key() << "] = Point(" << val->x() << "," << val->y() << ")" << std::endl;
155 else if(QRectF* val = boost::get<QRectF>(&it.value()))
156 std::cout << "lvals[" << it.key() << "] = Rect(" << val->x() << "," << val->y()
157 << "," << val->width() << "," << val->height() << ")" << std::endl;
158 #endif
160 #define GET_INT(name) \
161 int name = 0; \
162 {::LuaApi::LuaValueMap::iterator it = lvals.find(#name);\
163 if(double* val = (it==lvals.end()) ? 0 : boost::get<double>(&lvals[#name]) ) \
164 name = (int)*val; \
165 else \
166 ERROR("Hey Jack, please set "<<#name<<" to a number in the layout!");}
168 #define GET_POINT(name) \
169 QPoint name; \
170 {::LuaApi::LuaValueMap::iterator it = lvals.find(#name);\
171 if(QPointF* val = (it==lvals.end()) ? 0 : boost::get<QPointF>(&lvals[#name]) ) \
172 name = val->toPoint(); \
173 else \
174 ERROR("Hey Jack, please set "<<#name<<" to a point in the layout!");}
176 GET_POINT(board_position);
177 GET_INT(square_size);
178 GET_INT(border_size);
179 GET_INT(border_text_near);
180 GET_INT(border_text_far);
181 GET_POINT(clock0_position);
182 GET_POINT(clock1_position);
183 GET_INT(clock_size);
184 GET_POINT(pool0_position);
185 GET_POINT(pool1_position);
186 GET_INT(pool_piece_size);
187 GET_INT(pool_width);
189 m_board->moveTo(board_position.x(), board_position.y());
190 m_board->onResize( square_size, border_size, border_text_near, border_text_far, force_reload);
192 int x = !m_board->flipped();
194 m_clocks[x]->resize(clock_size);
195 m_clocks[x]->moveTo(clock0_position.x(), clock0_position.y());
196 // std::cout << "moving clock " << x << " to " << clock0_position.y() << std::endl;
198 m_clocks[!x]->resize(clock_size);
199 m_clocks[!x]->moveTo(clock1_position.x(), clock1_position.y());
200 // std::cout << "moving clock " << !x << " to " << clock1_position.y() << std::endl;
202 m_pools[x]->m_flipped = false;
203 m_pools[x]->onResize(pool_piece_size, force_reload);
204 m_pools[x]->moveTo(pool0_position.x(), pool0_position.y());
205 m_pools[x]->setGridWidth(pool_width);
207 m_pools[!x]->m_flipped = true;
208 m_pools[!x]->onResize(pool_piece_size, force_reload);
209 m_pools[!x]->moveTo(pool1_position.x(), pool1_position.y());
210 m_pools[!x]->setGridWidth(pool_width);
213 void ChessTable::resizeEvent(QResizeEvent* /*e*/) {
214 layout();
217 void ChessTable::mouseReleaseEvent(QMouseEvent* e) {
219 if(m_mousegrab) {
220 m_mousegrab->onMouseRelease(e->pos() - m_mousegrab->pos(), e->button() );
221 if(!e->buttons()) {
222 m_mousegrab = NULL;
224 ClickableCanvas* cb = eventItemAt(e->pos());
225 if(cb != m_current) {
226 if(m_current)
227 m_current->onMouseLeave();
228 if(cb) {
229 cb->onMouseEnter();
230 cb->onMouseMove(e->pos() - cb->pos(), 0);
232 m_current = cb;
235 return;
239 void ChessTable::mousePressEvent(QMouseEvent* e) {
240 if(m_mousegrab) {
241 m_mousegrab->onMousePress(e->pos() - m_mousegrab->pos(), e->button() );
242 return;
245 ClickableCanvas* cb = eventItemAt(e->pos());
246 if(cb != m_current) {
247 if(m_current)
248 m_current->onMouseLeave();
249 if(cb)
250 cb->onMouseEnter();
251 m_current = cb;
253 if(cb) {
254 cb->onMousePress(e->pos() - cb->pos(), e->button() );
255 m_mousegrab = cb;
259 void ChessTable::mouseMoveEvent(QMouseEvent* e) {
260 if(m_mousegrab) {
261 m_mousegrab->onMouseMove(e->pos() - m_mousegrab->pos(), e->button() );
262 return;
265 ClickableCanvas* cb = eventItemAt(e->pos());
266 if(cb != m_current) {
267 if(m_current)
268 m_current->onMouseLeave();
269 if(cb)
270 cb->onMouseEnter();
271 m_current = cb;
273 if(cb)
274 cb->onMouseMove(e->pos() - cb->pos(), e->button() );
277 void ChessTable::enterEvent(QEvent*) { }
279 void ChessTable::leaveEvent(QEvent*) {
280 if(m_current)
281 m_current->onMouseLeave();
282 m_current = NULL;
285 void ChessTable::flip() {
286 m_board->flip();
288 int delta = qAbs(m_pools[0]->pos().y() - m_pools[1]->pos().y());
289 for(int i=0;i<2;i++)
290 m_pools[i]->flipAndMoveBy( QPoint(0, delta) );
292 // flip clocks
293 QPoint pos = m_clocks[0]->pos();
294 m_clocks[0]->moveTo(m_clocks[1]->pos());
295 m_clocks[1]->moveTo(pos);
298 void ChessTable::flip(bool flipped) {
299 if(m_board->flipped() != flipped)
300 flip();
303 void ChessTable::changeClock(int color) {
304 if(m_clocks[0]->running() || m_clocks[1]->running())
305 for(int i=0;i<2;i++) {
306 if ( (i == color) != m_clocks[i]->running() )
307 if( i==color )
308 m_clocks[i]->start();
309 else
310 m_clocks[i]->stop();
314 void ChessTable::updateTurn(int color) {
315 for(int i=0; i<2; i++)
316 m_clocks[i]->activate(color == i);
319 void ChessTable::stopClocks() {
320 for(int i=0; i<2; i++)
321 m_clocks[i]->stop();
324 void ChessTable::updateTime(int white, int black) {
325 m_clocks[0]->setTime(white);
326 m_clocks[1]->setTime(black);
329 void ChessTable::resetClock() {
330 stopClocks();
331 updateTime(0, 0);
332 for(int i=0; i<2; i++)
333 m_clocks[i]->setPlayer(Player());
336 void ChessTable::setPlayers(const Player& white, const Player& black) {
337 m_clocks[0]->setPlayer(white);
338 m_clocks[1]->setPlayer(black);
341 void ChessTable::run() {
342 for(int i=0;i<2;i++)
343 if(m_clocks[i]->active() && !m_clocks[i]->running())
344 m_clocks[i]->start();
347 void ChessTable::displayMessage(const QString& msg) {
348 std::cout << msg << std::endl;
349 message(msg);
352 AnimationManager* ChessTable::animationManager() { return &m_anim_manager; }
353 const AnimationManager* ChessTable::animationManager() const { return &m_anim_manager; }
355 void ChessTable::setVariant(Variant* variant) {
356 m_components.setVariant(variant);
359 Components* ChessTable::components() { return &m_components; }