Initial porting to the new component API.
[tagua/yd.git] / src / piecepool.cpp
blob5d0468805c1692bfdcb06ab9795ddbeafa539976
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 */
12 #include "piecepool.h"
14 #include <core/color.h>
15 #include <core/variant.h>
16 #include "chessboard.h"
18 PiecePool::PiecePool(const IColor* pool, ChessBoard* b,
19 const AnimationSettings& animSettings,
20 KGameCanvasAbstract* parent)
21 : ClickableCanvas(parent)
22 , m_pool(pool)
23 , m_board(b)
24 , m_flipped(false)
25 , m_square_size(0)
26 , m_width(1)
27 , m_dragged_index(-1)
28 , m_anim_settings(animSettings) {
29 m_main_animation = new MainAnimation( 1.0 );
30 setGridWidth(1);
34 PiecePool::~PiecePool() {
35 delete m_main_animation;
39 QPoint PiecePool::toReal(int i) const {
40 int x = i % m_width;
41 int y = i / m_width;
43 if (y & 1)
44 x = m_width - 1 - x;
46 if (m_flipped)
47 y = -1 - y;
49 return QPoint(x, y) * m_square_size;
53 int PiecePool::toLogical(const QPoint& p) const {
54 int x = p.x() / m_square_size;
55 int y = p.y() / m_square_size;
57 if (x<0 || x >= m_width)
58 return -1;
60 if (m_flipped)
61 y = -y;
63 if (y & 1)
64 x = m_width - 1 - x;
66 int retv = y * m_width + x;
67 if (retv < 0 || static_cast<unsigned int>(retv) >= m_sprites.size())
68 return -1;
70 return retv;
74 void PiecePool::settingsChanged() {
79 void PiecePool::setGridWidth(int w) {
80 m_width = w > 0 ? w : 1;
83 QRect PiecePool::boardRect() {
84 Q_ASSERT(m_width > 0);
85 int height = (m_sprites.size() + m_width - 1) / m_width;
86 QSize sz(m_width, m_flipped ? -height : height);
87 return QRect(pos(), sz * m_square_size);
91 int PiecePool::fill() {
92 return m_sprites.size();
96 void PiecePool::clear() {
97 m_sprites.clear();
100 void PiecePool::insertSprite(int index, const NamedSprite& nsprite) {
101 if(m_dragged && index > m_dragged_index)
102 index--;
104 if(index < 0 || index > fill() ) {
105 ERROR("invalid index " << index);
106 return;
109 m_sprites.resize(m_sprites.size()+1);
111 for(int i = m_sprites.size()-1; i > index; i--) {
112 // double speed = (1.0 + 1.0 / (i - index + 1)) * 0.4;
113 m_sprites[i] = m_sprites[i-1];
114 // FIXME restore pool animations
115 // animate(Animate::Pool::move(m_sprites[i], i));
118 m_sprites[index] = nsprite;
120 // FIXME restore pool animations
121 // animate(Animate::Pool::move(m_sprites[index], index), Animate::Instant);
122 // animate(Animate::Pool::appear(m_sprites[index]));
126 NamedSprite PiecePool::getSprite(int index) {
127 if(m_dragged && index == m_dragged_index)
128 return m_dragged;
130 if(m_dragged && index > m_dragged_index)
131 index--;
133 if(index < 0 || index >= (int)m_sprites.size() ) {
134 ERROR("invalid index " << index);
135 return NamedSprite();
138 return m_sprites[index];
142 void PiecePool::removeSprite(int index) {
143 if(m_dragged && index == m_dragged_index) {
144 m_dragged = NamedSprite();
145 m_dragged_index = -1;
146 return;
149 if(m_dragged && index > m_dragged_index)
150 index--;
152 if(index < 0 || index >= (int)m_sprites.size() ) {
153 ERROR("invalid index " << index);
154 return;
157 takeSpriteAt(index);
161 NamedSprite PiecePool::takeSprite(int index) {
162 if(m_dragged && index == m_dragged_index) {
163 NamedSprite retv = m_dragged;
164 m_dragged = NamedSprite();
165 m_dragged_index = -1;
167 return retv;
170 ERROR("Only the sprite being dropped can be taken from the pool.");
171 return NamedSprite();
172 #if 0
173 if(m_dragged && index > m_dragged_index)
174 index--;
176 if(index < 0 || index >= (int)m_sprites.size() ) {
177 ERROR("invalid index " << index);
178 return NamedSprite();
181 return takeSpriteAt(index);
182 #endif
186 NamedSprite PiecePool::takeSpriteAt(int index) {
187 if(index < 0 || index >= (int)m_sprites.size() ) {
188 ERROR("invalid index " << index);
189 return NamedSprite();
192 NamedSprite retv = m_sprites[index];
193 if (!retv)
194 return NamedSprite();
195 // FIXME restore pool animations
196 // animate(Animate::Pool::disappear(retv));
198 for(int i = index; i < (int)m_sprites.size()-1; i++) {
199 // double speed = (1.0 + 1.0 / (i - index + 1)) * 0.4;
200 m_sprites[i] = m_sprites[i+1];
201 // FIXME restore pool animations
202 // animate(Animate::Pool::move(m_sprites[i], i));
204 m_sprites.resize(m_sprites.size()-1);
206 return retv;
210 void PiecePool::cancelDragging(bool fadeOff) {
211 if(!m_dragged)
212 return;
214 if (fadeOff) {
215 NamedSprite phantom = duplicate(m_dragged);
216 // FIXME restore pool animations
217 // animate(Animate::Pool::disappear(phantom));
220 m_dragged.sprite()->putInCanvas(this);
221 m_dragged.sprite()->setPixmap(loadSprite(m_dragged.name()));
222 insertSprite(m_dragged_index, m_dragged);
224 m_dragged = NamedSprite();
225 m_dragged_index = -1;
229 void PiecePool::flipAndMoveBy(QPoint p) {
230 QPoint deltapos = m_flipped ? -p : p;
231 moveTo(pos() + deltapos);
232 m_flipped = !m_flipped;
234 for(int i=0;i<(int)m_sprites.size(); i++) {
235 SpritePtr p = m_sprites[i].sprite();
236 p->setPixmap(loadSprite(m_sprites[i].name()));
237 // FIXME restore pool animations
238 // animate(Animate::Pool::move(m_sprites[i], i), Animate::Instant);
243 void PiecePool::onResize(int new_size, bool force_reload) {
244 if (m_square_size == new_size && !force_reload)
245 return;
247 m_square_size = new_size;
248 m_loader.setSize(m_square_size);
250 // update the sprites
251 for (int i=0;i<(int)m_sprites.size(); i++) {
252 m_sprites[i].sprite()->setPixmap(loadSprite(m_sprites[i].name()));
253 m_main_animation->addAnimation(AnimationPtr(new InstantAnimation(m_sprites[i].sprite(), toReal(i))));
258 void PiecePool::onMouseRelease(const QPoint& pos, int button) {
259 if (button != Qt::LeftButton || !m_dragged)
260 return;
262 m_board->m_dropped_pool = m_pool;
263 m_board->m_dropped_index = m_dragged_index;
265 /* did the board take this sprite? */
266 m_board->dropOn( m_pool, m_dragged_index, pos + this->pos() - m_board->pos() );
268 m_board->m_dropped_pool = 0;
269 m_board->m_dropped_index = -1;
271 cancelDragging(true);
275 void PiecePool::onMousePress(const QPoint& pos, int button) {
276 if (button != Qt::LeftButton)
277 return;
279 if(m_dragged) {
280 ERROR("Eh? We are already dragging?");
281 cancelDragging(); //never remove implicitly a piece from the pool
284 int index = toLogical(pos);
285 if(index == -1)
286 return;
287 NamedSprite got = takeSpriteAt(index);
288 if(!got)
289 return;
291 got.sprite()->hide();
293 /* recreate the sprite, as "got" may be being animated */
294 QPixmap px = m_board->loadSprite(got.name());
295 QPoint at = pos + this->pos() - m_board->pos() - QPoint(px.width(), px.height())/2;
296 m_dragged = NamedSprite( got.name(), SpritePtr(new Sprite(px, m_board->piecesGroup(), at) ) );
297 m_dragged.sprite()->raise();
298 m_dragged.sprite()->show();
299 m_dragged_index = index;
303 void PiecePool::onMouseMove(const QPoint& pos, int /*button*/) {
304 if(m_dragged) {
305 m_dragged.sprite()->moveTo(pos + this->pos() - m_board->pos()
306 - QPoint(m_dragged.sprite()->pixmap().width(),
307 m_dragged.sprite()->pixmap().height() ) / 2 );
308 m_board->draggingOn( m_pool, m_dragged_index, pos + this->pos() - m_board->pos() );
312 QPixmap PiecePool::loadSprite(const QString& id) {
313 // use board flipped state here, because the pool
314 // flipping only refers to the displaying of pieces
315 // and should not affect their orientation (which should
316 // stay coherent with that of the pieces on the board).
317 return m_loader.piecePixmap(id, m_board->flipped());