refresh 080b1da3c594fb6ca84009c352cc5fb9cc294c43
[tagua/yd.git] / src / piecepool.cpp
blobbe636517581a66bcc730a03e0e58b899d1dcd986
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 "animationmanager.h"
16 #include "chessboard.h"
17 #include "sprite.h"
19 PiecePool::PiecePool(const IColor* pool, ChessBoard* b,
20 AnimationManager* animManager,
21 KGameCanvasAbstract* parent)
22 : ClickableCanvas(parent)
23 , m_pool(pool)
24 , m_board(b)
25 , m_flipped(false)
26 , m_square_size(0)
27 , m_width(1)
28 , m_dragged_index(-1)
29 , m_anim_manager(animManager) {
30 setGridWidth(1);
34 PiecePool::~PiecePool() { }
37 QPoint PiecePool::toReal(int i) const {
38 int x = i % m_width;
39 int y = i / m_width;
41 if (y & 1)
42 x = m_width - 1 - x;
44 if (m_flipped)
45 y = -1 - y;
47 return QPoint(x, y) * m_square_size;
51 int PiecePool::toLogical(const QPoint& p) const {
52 int x = p.x() / m_square_size;
53 int y = p.y() / m_square_size;
55 if (x<0 || x >= m_width)
56 return -1;
58 if (m_flipped)
59 y = -y;
61 if (y & 1)
62 x = m_width - 1 - x;
64 int retv = y * m_width + x;
65 if (retv < 0 || static_cast<unsigned int>(retv) >= m_sprites.size())
66 return -1;
68 return retv;
72 void PiecePool::settingsChanged() {
77 void PiecePool::setGridWidth(int w) {
78 m_width = w > 0 ? w : 1;
81 QRect PiecePool::boardRect() {
82 Q_ASSERT(m_width > 0);
83 int height = (m_sprites.size() + m_width - 1) / m_width;
84 QSize sz(m_width, m_flipped ? -height : height);
85 return QRect(pos(), sz * m_square_size);
89 int PiecePool::fill() {
90 return m_sprites.size();
94 void PiecePool::clear() {
95 m_sprites.clear();
98 void PiecePool::insertSprite(int index, const NamedSprite& nsprite) {
99 if(m_dragged && index > m_dragged_index)
100 index--;
102 if(index < 0 || index > fill() ) {
103 ERROR("invalid index " << index);
104 return;
107 m_sprites.resize(m_sprites.size()+1);
109 for(int i = m_sprites.size()-1; i > index; i--) {
110 // double speed = (1.0 + 1.0 / (i - index + 1)) * 0.4;
111 m_sprites[i] = m_sprites[i-1];
112 m_anim_manager->enqueue(
113 m_anim_manager->move(m_sprites[i], toReal(i), true, "default"));
116 m_sprites[index] = nsprite;
118 m_anim_manager->enqueue(
119 m_anim_manager->move(m_sprites[index], toReal(index), true, "instant"));
120 m_anim_manager->enqueue(m_anim_manager->appear(m_sprites[index], "default"));
124 NamedSprite PiecePool::getSprite(int index) {
125 if(m_dragged && index == m_dragged_index)
126 return m_dragged;
128 if(m_dragged && index > m_dragged_index)
129 index--;
131 if(index < 0 || index >= (int)m_sprites.size() ) {
132 ERROR("invalid index " << index);
133 return NamedSprite();
136 return m_sprites[index];
140 void PiecePool::removeSprite(int index) {
141 if(m_dragged && index == m_dragged_index) {
142 m_dragged = NamedSprite();
143 m_dragged_index = -1;
144 return;
147 if(m_dragged && index > m_dragged_index)
148 index--;
150 if(index < 0 || index >= (int)m_sprites.size() ) {
151 ERROR("invalid index " << index);
152 return;
155 takeSpriteAt(index);
159 NamedSprite PiecePool::takeSprite(int index) {
160 if(m_dragged && index == m_dragged_index) {
161 NamedSprite retv = m_dragged;
162 m_dragged = NamedSprite();
163 m_dragged_index = -1;
165 return retv;
168 ERROR("Only the sprite being dropped can be taken from the pool.");
169 return NamedSprite();
170 #if 0
171 if(m_dragged && index > m_dragged_index)
172 index--;
174 if(index < 0 || index >= (int)m_sprites.size() ) {
175 ERROR("invalid index " << index);
176 return NamedSprite();
179 return takeSpriteAt(index);
180 #endif
184 NamedSprite PiecePool::takeSpriteAt(int index) {
185 if(index < 0 || index >= (int)m_sprites.size() ) {
186 ERROR("invalid index " << index);
187 return NamedSprite();
190 NamedSprite retv = m_sprites[index];
191 if (!retv)
192 return NamedSprite();
193 m_anim_manager->enqueue(m_anim_manager->disappear(retv, "default"));
195 for(int i = index; i < (int)m_sprites.size()-1; i++) {
196 // double speed = (1.0 + 1.0 / (i - index + 1)) * 0.4;
197 m_sprites[i] = m_sprites[i+1];
198 m_anim_manager->enqueue(
199 m_anim_manager->move(m_sprites[i], toReal(i), true, "default"));
201 m_sprites.resize(m_sprites.size()-1);
203 return retv;
207 void PiecePool::cancelDragging(bool fadeOff) {
208 if(!m_dragged)
209 return;
211 if (fadeOff) {
212 NamedSprite phantom = duplicate(m_dragged);
213 m_anim_manager->enqueue(m_anim_manager->disappear(phantom, "default"));
216 m_dragged.sprite()->putInCanvas(this);
217 m_dragged.sprite()->setPixmap(loadSprite(m_dragged.name()));
218 insertSprite(m_dragged_index, m_dragged);
220 m_dragged = NamedSprite();
221 m_dragged_index = -1;
225 void PiecePool::flipAndMoveBy(QPoint p) {
226 QPoint deltapos = m_flipped ? -p : p;
227 moveTo(pos() + deltapos);
228 m_flipped = !m_flipped;
230 for(int i=0;i<(int)m_sprites.size(); i++) {
231 SpritePtr p = m_sprites[i].sprite();
232 p->setPixmap(loadSprite(m_sprites[i].name()));
233 m_anim_manager->enqueue(
234 m_anim_manager->move(m_sprites[i], toReal(i), true, "instant"));
239 void PiecePool::onResize(int new_size, bool force_reload) {
240 if (m_square_size == new_size && !force_reload)
241 return;
243 m_square_size = new_size;
244 m_loader.setSize(m_square_size);
246 // update the sprites
247 for (int i=0;i<(int)m_sprites.size(); i++) {
248 m_sprites[i].sprite()->setPixmap(loadSprite(m_sprites[i].name()));
249 m_anim_manager->enqueue(
250 m_anim_manager->move(m_sprites[i], toReal(i), true, "instant"));
255 void PiecePool::onMouseRelease(const QPoint& pos, int button) {
256 if (button != Qt::LeftButton || !m_dragged)
257 return;
259 m_board->m_dropped_pool = m_pool;
260 m_board->m_dropped_index = m_dragged_index;
262 /* did the board take this sprite? */
263 m_board->dropOn( m_pool, m_dragged_index, pos + this->pos() - m_board->pos() );
265 m_board->m_dropped_pool = 0;
266 m_board->m_dropped_index = -1;
268 cancelDragging(true);
272 void PiecePool::onMousePress(const QPoint& pos, int button) {
273 if (button != Qt::LeftButton)
274 return;
276 if(m_dragged) {
277 ERROR("Eh? We are already dragging?");
278 cancelDragging(); //never remove implicitly a piece from the pool
281 int index = toLogical(pos);
282 if(index == -1)
283 return;
284 NamedSprite got = takeSpriteAt(index);
285 if(!got)
286 return;
288 got.sprite()->hide();
290 /* recreate the sprite, as "got" may be being animated */
291 QPixmap px = m_board->loadSprite(got.name());
292 QPoint at = pos + this->pos() - m_board->pos() - QPoint(px.width(), px.height())/2;
293 m_dragged = NamedSprite( got.name(), SpritePtr(new Sprite(px, m_board->piecesGroup(), at) ) );
294 m_dragged.sprite()->raise();
295 m_dragged.sprite()->show();
296 m_dragged_index = index;
300 void PiecePool::onMouseMove(const QPoint& pos, int /*button*/) {
301 if(m_dragged) {
302 m_dragged.sprite()->moveTo(pos + this->pos() - m_board->pos()
303 - QPoint(m_dragged.sprite()->pixmap().width(),
304 m_dragged.sprite()->pixmap().height() ) / 2 );
305 m_board->draggingOn( m_pool, m_dragged_index, pos + this->pos() - m_board->pos() );
309 QPixmap PiecePool::loadSprite(const QString& id) {
310 // use board flipped state here, because the pool
311 // flipping only refers to the displaying of pieces
312 // and should not affect their orientation (which should
313 // stay coherent with that of the pieces on the board).
314 return m_loader.piecePixmap(id, m_board->flipped());
317 const IndexConverter* PiecePool::converter() const { return this; }