Added legality checking to shogi.
[tagua/yd.git] / src / chesstable.cpp
blob38c6e8b3d7c6be5654e37f6f9c2e94cb8db420d0
1 /*
2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@sns.it>
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>
15 #include "chesstable.h"
16 #include "game.h"
17 #include "gameinfo.h"
18 #include "connection.h"
19 #include "piecepool.h"
20 #include "clock.h"
21 #include "mastersettings.h"
22 #include "movelist_table.h"
23 #include "infodisplay.h"
25 using namespace boost;
27 ChessTable::ChessTable(QWidget* parent)
28 : KGameCanvasWidget(parent)
29 , m_wallpaper(NULL)
30 , m_current(NULL)
31 , m_mousegrab(NULL)
32 , m_need_reload(false) {
34 setMouseTracking(true);
36 // create m_board
37 m_board = new Board(m_anim_settings, this);
38 m_board->show();
40 // create move list
41 m_movelist = new MoveList::Table;
43 // create clocks
44 for(int i=0;i<2;i++) {
45 m_clocks[i] = new Clock(i, this);
46 m_clocks[i]->show();
48 m_clocks[0]->activate(0);
50 // create info display
51 m_info = new InfoDisplay(this);
52 // m_info->show();
54 // create pools
55 for(int i=0;i<2;i++) {
56 m_pools[i] = new PiecePool(i, m_board, m_anim_settings, this);
57 m_pools[i]->show();
60 m_board->raise();
61 settingsChanged();
64 ChessTable::~ChessTable() {
65 for(int i=0;i<2;i++)
66 delete m_clocks[i];
67 delete m_movelist;
68 delete m_board;
69 for(int i=0;i<2;i++)
70 delete m_pools[i];
71 delete m_info;
74 void ChessTable::settingsChanged() {
75 m_anim_settings.reload();
77 m_board->settingsChanged();
78 for(int i=0;i<2;i++)
79 m_clocks[i]->settingsChanged();
80 m_info->settingsChanged();
81 for(int i=0;i<2;i++)
82 m_pools[i]->settingsChanged();
84 if(m_wallpaper)
85 delete m_wallpaper;
87 QPixmap bg = m_board->controlsLoader()->getStaticValue<QPixmap>("wallpaper");
88 if(!bg.isNull()) {
89 m_wallpaper = new KGameCanvasTiledPixmap(bg, QSize(), QPoint(), false, this);
90 m_wallpaper->lower();
91 m_wallpaper->show();
93 else
94 m_wallpaper = 0;
96 /* redo the layout, forcing reload */
97 if(isVisible())
98 layout(true);
99 else
100 m_need_reload = true;
103 ClickableCanvas* ChessTable::eventItemAt(QPoint pos) {
104 if (m_board->boardRect().contains(pos))
105 return m_board;
107 for (int i=0; i<2; i++)
108 if (m_pools[i]->boardRect().contains(pos))
109 return m_pools[i];
111 for (int i=0; i<2; i++)
112 if (m_clocks[i]->rect().contains(pos))
113 return m_clocks[i];
115 return NULL;
118 void ChessTable::setEntity(const boost::shared_ptr<UserEntity>& entity) {
119 m_board->setEntity(entity);
122 void ChessTable::layout(bool force_reload) {
123 force_reload |= m_need_reload;
124 m_need_reload = false;
126 if (m_wallpaper) {
127 m_wallpaper->setSize(size());
128 QSize delta = (m_wallpaper->pixmap().size()-size())/2;
129 m_wallpaper->setOrigin(QPoint(delta.width(), delta.height()));
132 ::LuaApi::LuaValueMap params;
133 params["width"] = width();
134 params["height"] = height();
135 params["grid_size"] = QPointF(m_board->gridSize());
137 ::LuaApi::LuaValueMap lvals = m_board->controlsLoader()->getStaticValue< ::LuaApi::LuaValueMap>("layout", &params);
139 #if 0
140 for(::LuaApi::LuaValueMap::iterator it = lvals.begin(); it != lvals.end(); ++it)
141 if(double* val = boost::get<double>(&it.value()))
142 std::cout << "lvals[" << it.key() << "] = " << *val << std::endl;
143 else if(QPointF* val = boost::get<QPointF>(&it.value()))
144 std::cout << "lvals[" << it.key() << "] = Point(" << val->x() << "," << val->y() << ")" << std::endl;
145 else if(QRectF* val = boost::get<QRectF>(&it.value()))
146 std::cout << "lvals[" << it.key() << "] = Rect(" << val->x() << "," << val->y()
147 << "," << val->width() << "," << val->height() << ")" << std::endl;
148 #endif
150 #define GET_INT(name) \
151 int name = 0; \
152 {::LuaApi::LuaValueMap::iterator it = lvals.find(#name);\
153 if(double* val = (it==lvals.end()) ? 0 : boost::get<double>(&lvals[#name]) ) \
154 name = (int)*val; \
155 else \
156 ERROR("Hey Jack, please set "<<#name<<" to a number in the layout!");}
158 #define GET_POINT(name) \
159 QPoint name; \
160 {::LuaApi::LuaValueMap::iterator it = lvals.find(#name);\
161 if(QPointF* val = (it==lvals.end()) ? 0 : boost::get<QPointF>(&lvals[#name]) ) \
162 name = val->toPoint(); \
163 else \
164 ERROR("Hey Jack, please set "<<#name<<" to a point in the layout!");}
166 GET_POINT(board_position);
167 GET_INT(square_size);
168 GET_INT(border_size);
169 GET_INT(border_text_near);
170 GET_INT(border_text_far);
171 GET_POINT(clock0_position);
172 GET_POINT(clock1_position);
173 GET_INT(clock_size);
174 GET_POINT(pool0_position);
175 GET_POINT(pool1_position);
176 GET_INT(pool_piece_size);
177 GET_INT(pool_width);
179 m_board->moveTo(board_position.x(), board_position.y());
180 m_board->onResize( square_size, border_size, border_text_near, border_text_far, force_reload);
182 int x = !m_board->flipped();
184 m_clocks[x]->resize(clock_size);
185 m_clocks[x]->moveTo(clock0_position.x(), clock0_position.y());
187 m_clocks[!x]->resize(clock_size);
188 m_clocks[!x]->moveTo(clock1_position.x(), clock1_position.y());
190 m_pools[x]->m_flipped = false;
191 m_pools[x]->onResize(pool_piece_size, force_reload);
192 m_pools[x]->moveTo(pool0_position.x(), pool0_position.y());
193 m_pools[x]->setGridWidth(pool_width);
195 m_pools[!x]->m_flipped = true;
196 m_pools[!x]->onResize(pool_piece_size, force_reload);
197 m_pools[!x]->moveTo(pool1_position.x(), pool1_position.y());
198 m_pools[!x]->setGridWidth(pool_width);
201 void ChessTable::resizeEvent(QResizeEvent* /*e*/) {
202 layout();
205 void ChessTable::mouseReleaseEvent(QMouseEvent* e) {
207 if(m_mousegrab) {
208 m_mousegrab->onMouseRelease(e->pos() - m_mousegrab->pos(), e->button() );
209 if(!e->buttons()) {
210 m_mousegrab = NULL;
212 ClickableCanvas* cb = eventItemAt(e->pos());
213 if(cb != m_current) {
214 if(m_current)
215 m_current->onMouseLeave();
216 if(cb) {
217 cb->onMouseEnter();
218 cb->onMouseMove(e->pos() - cb->pos(), 0);
220 m_current = cb;
223 return;
227 void ChessTable::mousePressEvent(QMouseEvent* e) {
228 if(m_mousegrab) {
229 m_mousegrab->onMousePress(e->pos() - m_mousegrab->pos(), e->button() );
230 return;
233 ClickableCanvas* cb = eventItemAt(e->pos());
234 if(cb != m_current) {
235 if(m_current)
236 m_current->onMouseLeave();
237 if(cb)
238 cb->onMouseEnter();
239 m_current = cb;
241 if(cb) {
242 cb->onMousePress(e->pos() - cb->pos(), e->button() );
243 m_mousegrab = cb;
247 void ChessTable::mouseMoveEvent(QMouseEvent* e) {
248 if(m_mousegrab) {
249 m_mousegrab->onMouseMove(e->pos() - m_mousegrab->pos(), e->button() );
250 return;
253 ClickableCanvas* cb = eventItemAt(e->pos());
254 if(cb != m_current) {
255 if(m_current)
256 m_current->onMouseLeave();
257 if(cb)
258 cb->onMouseEnter();
259 m_current = cb;
261 if(cb)
262 cb->onMouseMove(e->pos() - cb->pos(), e->button() );
265 void ChessTable::enterEvent(QEvent*) { }
267 void ChessTable::leaveEvent(QEvent*) {
268 if(m_current)
269 m_current->onMouseLeave();
270 m_current = NULL;
273 void ChessTable::flip() {
274 m_board->flip();
276 int delta = qAbs(m_pools[0]->pos().y() - m_pools[1]->pos().y());
277 for(int i=0;i<2;i++)
278 m_pools[i]->flipAndMoveBy( QPoint(0, delta) );
281 void ChessTable::flip(bool flipped) {
282 if(m_board->flipped() != flipped)
283 flip();
286 void ChessTable::changeClock(int color) {
287 if(m_clocks[0]->running() || m_clocks[1]->running())
288 for(int i=0;i<2;i++) {
289 if ( (i == color) != m_clocks[i]->running() )
290 if( i==color )
291 m_clocks[i]->start();
292 else
293 m_clocks[i]->stop();
297 void ChessTable::updateTurn(int color) {
298 for(int i=0; i<2; i++)
299 m_clocks[i]->activate(color == i);
302 void ChessTable::stopClocks() {
303 for(int i=0; i<2; i++)
304 m_clocks[i]->stop();
307 void ChessTable::updateTime(int white, int black) {
308 m_clocks[0]->setTime(white);
309 m_clocks[1]->setTime(black);
312 void ChessTable::resetClock() {
313 stopClocks();
314 updateTime(0, 0);
315 for(int i=0; i<2; i++)
316 m_clocks[i]->setPlayer(Player());
319 void ChessTable::setPlayers(const Player& white, const Player& black) {
320 m_clocks[0]->setPlayer(white);
321 m_clocks[1]->setPlayer(black);
324 void ChessTable::run() {
325 for(int i=0;i<2;i++)
326 if(m_clocks[i]->active() && !m_clocks[i]->running())
327 m_clocks[i]->start();
330 void ChessTable::displayMessage(const QString& msg) {
331 std::cout << msg << std::endl;
332 message(msg);
335 const AnimationSettings& ChessTable::animationSettings() const {
336 return m_anim_settings;