Initial porting to the new component API.
[tagua/yd.git] / src / chesstable.cpp
blob3e3233423e145e58ce7ae8556763f3ff63ede3e0
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 <core/color.h>
17 #include <core/variant.h>
19 #include "chesstable.h"
20 #include "game.h"
21 #include "gameinfo.h"
22 #include "connection.h"
23 #include "piecepool.h"
24 #include "clock.h"
25 #include "mastersettings.h"
26 #include "movelist_table.h"
27 #include "infodisplay.h"
29 using namespace boost;
31 ChessTable::ChessTable(Variant* variant, QWidget* parent)
32 : KGameCanvasWidget(parent)
33 , m_wallpaper(NULL)
34 , m_current(NULL)
35 , m_mousegrab(NULL)
36 , m_need_reload(false) {
38 setMouseTracking(true);
40 // create m_board
41 m_board = new ChessBoard(variant, m_anim_settings, this);
42 m_board->show();
44 // create move list
45 m_movelist = new MoveList::Table;
47 // create clocks
48 for(int i=0;i<2;i++) {
49 m_clocks[i] = new Clock(i, this);
50 m_clocks[i]->show();
52 m_clocks[0]->activate(0);
54 // create info display
55 m_info = new InfoDisplay(this);
56 // m_info->show();
58 // create pools
59 // FIXME what to do for more than 2 players?
60 for (int i = 0; i < 2; i++) {
61 const IColor* color = requestComponent<IColor>(
62 variant, "player/" + QString::number(i));
63 m_pools[i] = new PiecePool(color, m_board, m_anim_settings, this);
64 m_pools[i]->show();
67 m_board->raise();
68 settingsChanged();
71 ChessTable::~ChessTable() {
72 for(int i=0;i<2;i++)
73 delete m_clocks[i];
74 delete m_movelist;
75 delete m_board;
76 for(int i=0;i<2;i++)
77 delete m_pools[i];
78 delete m_info;
81 void ChessTable::settingsChanged() {
82 m_anim_settings.reload();
84 m_board->settingsChanged();
85 for(int i=0;i<2;i++)
86 m_clocks[i]->settingsChanged();
87 m_info->settingsChanged();
88 for(int i=0;i<2;i++)
89 m_pools[i]->settingsChanged();
91 if(m_wallpaper)
92 delete m_wallpaper;
94 QPixmap bg = m_board->controlsLoader()->getStaticValue<QPixmap>("wallpaper", 0, true);
95 if (!bg.isNull()) {
96 m_wallpaper = new KGameCanvasTiledPixmap(bg, QSize(), QPoint(), false, this);
97 m_wallpaper->lower();
98 m_wallpaper->show();
100 else
101 m_wallpaper = 0;
103 /* redo the layout, forcing reload */
104 if(isVisible())
105 layout(true);
106 else
107 m_need_reload = true;
110 ClickableCanvas* ChessTable::eventItemAt(QPoint pos) {
111 if (m_board->boardRect().contains(pos))
112 return m_board;
114 for (int i=0; i<2; i++)
115 if (m_pools[i]->boardRect().contains(pos))
116 return m_pools[i];
118 for (int i=0; i<2; i++)
119 if (m_clocks[i]->rect().contains(pos))
120 return m_clocks[i];
122 return NULL;
125 void ChessTable::setEntity(const boost::shared_ptr<UserEntity>& entity) {
126 m_board->setEntity(entity);
129 void ChessTable::layout(bool force_reload) {
130 force_reload |= m_need_reload;
131 m_need_reload = false;
133 if (m_wallpaper) {
134 m_wallpaper->setSize(size());
135 QSize delta = (m_wallpaper->pixmap().size()-size())/2;
136 m_wallpaper->setOrigin(QPoint(delta.width(), delta.height()));
139 ::LuaApi::LuaValueMap params;
140 params["width"] = width();
141 params["height"] = height();
142 params["grid_size"] = QPointF(m_board->gridSize());
144 ::LuaApi::LuaValueMap lvals = m_board->controlsLoader()->getStaticValue< ::LuaApi::LuaValueMap>("layout", &params);
146 #if 0
147 for(::LuaApi::LuaValueMap::iterator it = lvals.begin(); it != lvals.end(); ++it)
148 if(double* val = boost::get<double>(&it.value()))
149 std::cout << "lvals[" << it.key() << "] = " << *val << std::endl;
150 else if(QPointF* val = boost::get<QPointF>(&it.value()))
151 std::cout << "lvals[" << it.key() << "] = Point(" << val->x() << "," << val->y() << ")" << std::endl;
152 else if(QRectF* val = boost::get<QRectF>(&it.value()))
153 std::cout << "lvals[" << it.key() << "] = Rect(" << val->x() << "," << val->y()
154 << "," << val->width() << "," << val->height() << ")" << std::endl;
155 #endif
157 #define GET_INT(name) \
158 int name = 0; \
159 {::LuaApi::LuaValueMap::iterator it = lvals.find(#name);\
160 if(double* val = (it==lvals.end()) ? 0 : boost::get<double>(&lvals[#name]) ) \
161 name = (int)*val; \
162 else \
163 ERROR("Hey Jack, please set "<<#name<<" to a number in the layout!");}
165 #define GET_POINT(name) \
166 QPoint name; \
167 {::LuaApi::LuaValueMap::iterator it = lvals.find(#name);\
168 if(QPointF* val = (it==lvals.end()) ? 0 : boost::get<QPointF>(&lvals[#name]) ) \
169 name = val->toPoint(); \
170 else \
171 ERROR("Hey Jack, please set "<<#name<<" to a point in the layout!");}
173 GET_POINT(board_position);
174 GET_INT(square_size);
175 GET_INT(border_size);
176 GET_INT(border_text_near);
177 GET_INT(border_text_far);
178 GET_POINT(clock0_position);
179 GET_POINT(clock1_position);
180 GET_INT(clock_size);
181 GET_POINT(pool0_position);
182 GET_POINT(pool1_position);
183 GET_INT(pool_piece_size);
184 GET_INT(pool_width);
186 m_board->moveTo(board_position.x(), board_position.y());
187 m_board->onResize( square_size, border_size, border_text_near, border_text_far, force_reload);
189 int x = !m_board->flipped();
191 m_clocks[x]->resize(clock_size);
192 m_clocks[x]->moveTo(clock0_position.x(), clock0_position.y());
193 // std::cout << "moving clock " << x << " to " << clock0_position.y() << std::endl;
195 m_clocks[!x]->resize(clock_size);
196 m_clocks[!x]->moveTo(clock1_position.x(), clock1_position.y());
197 // std::cout << "moving clock " << !x << " to " << clock1_position.y() << std::endl;
199 m_pools[x]->m_flipped = false;
200 m_pools[x]->onResize(pool_piece_size, force_reload);
201 m_pools[x]->moveTo(pool0_position.x(), pool0_position.y());
202 m_pools[x]->setGridWidth(pool_width);
204 m_pools[!x]->m_flipped = true;
205 m_pools[!x]->onResize(pool_piece_size, force_reload);
206 m_pools[!x]->moveTo(pool1_position.x(), pool1_position.y());
207 m_pools[!x]->setGridWidth(pool_width);
210 void ChessTable::resizeEvent(QResizeEvent* /*e*/) {
211 layout();
214 void ChessTable::mouseReleaseEvent(QMouseEvent* e) {
216 if(m_mousegrab) {
217 m_mousegrab->onMouseRelease(e->pos() - m_mousegrab->pos(), e->button() );
218 if(!e->buttons()) {
219 m_mousegrab = NULL;
221 ClickableCanvas* cb = eventItemAt(e->pos());
222 if(cb != m_current) {
223 if(m_current)
224 m_current->onMouseLeave();
225 if(cb) {
226 cb->onMouseEnter();
227 cb->onMouseMove(e->pos() - cb->pos(), 0);
229 m_current = cb;
232 return;
236 void ChessTable::mousePressEvent(QMouseEvent* e) {
237 if(m_mousegrab) {
238 m_mousegrab->onMousePress(e->pos() - m_mousegrab->pos(), e->button() );
239 return;
242 ClickableCanvas* cb = eventItemAt(e->pos());
243 if(cb != m_current) {
244 if(m_current)
245 m_current->onMouseLeave();
246 if(cb)
247 cb->onMouseEnter();
248 m_current = cb;
250 if(cb) {
251 cb->onMousePress(e->pos() - cb->pos(), e->button() );
252 m_mousegrab = cb;
256 void ChessTable::mouseMoveEvent(QMouseEvent* e) {
257 if(m_mousegrab) {
258 m_mousegrab->onMouseMove(e->pos() - m_mousegrab->pos(), e->button() );
259 return;
262 ClickableCanvas* cb = eventItemAt(e->pos());
263 if(cb != m_current) {
264 if(m_current)
265 m_current->onMouseLeave();
266 if(cb)
267 cb->onMouseEnter();
268 m_current = cb;
270 if(cb)
271 cb->onMouseMove(e->pos() - cb->pos(), e->button() );
274 void ChessTable::enterEvent(QEvent*) { }
276 void ChessTable::leaveEvent(QEvent*) {
277 if(m_current)
278 m_current->onMouseLeave();
279 m_current = NULL;
282 void ChessTable::flip() {
283 m_board->flip();
285 int delta = qAbs(m_pools[0]->pos().y() - m_pools[1]->pos().y());
286 for(int i=0;i<2;i++)
287 m_pools[i]->flipAndMoveBy( QPoint(0, delta) );
289 // flip clocks
290 QPoint pos = m_clocks[0]->pos();
291 m_clocks[0]->moveTo(m_clocks[1]->pos());
292 m_clocks[1]->moveTo(pos);
295 void ChessTable::flip(bool flipped) {
296 if(m_board->flipped() != flipped)
297 flip();
300 void ChessTable::changeClock(int color) {
301 if(m_clocks[0]->running() || m_clocks[1]->running())
302 for(int i=0;i<2;i++) {
303 if ( (i == color) != m_clocks[i]->running() )
304 if( i==color )
305 m_clocks[i]->start();
306 else
307 m_clocks[i]->stop();
311 void ChessTable::updateTurn(int color) {
312 for(int i=0; i<2; i++)
313 m_clocks[i]->activate(color == i);
316 void ChessTable::stopClocks() {
317 for(int i=0; i<2; i++)
318 m_clocks[i]->stop();
321 void ChessTable::updateTime(int white, int black) {
322 m_clocks[0]->setTime(white);
323 m_clocks[1]->setTime(black);
326 void ChessTable::resetClock() {
327 stopClocks();
328 updateTime(0, 0);
329 for(int i=0; i<2; i++)
330 m_clocks[i]->setPlayer(Player());
333 void ChessTable::setPlayers(const Player& white, const Player& black) {
334 m_clocks[0]->setPlayer(white);
335 m_clocks[1]->setPlayer(black);
338 void ChessTable::run() {
339 for(int i=0;i<2;i++)
340 if(m_clocks[i]->active() && !m_clocks[i]->running())
341 m_clocks[i]->start();
344 void ChessTable::displayMessage(const QString& msg) {
345 std::cout << msg << std::endl;
346 message(msg);
349 const AnimationSettings& ChessTable::animationSettings() const {
350 return m_anim_settings;