Prepare 1.0 alpha3 release.
[tagua/yd.git] / src / piecepool.cpp
blob4017d174deafb2cef6e3551c8e1fa0031618d3b0
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"
13 #include "board.h"
14 #include <KDebug>
16 PiecePool::PiecePool(int num, Board* b, const AnimationSettings& animSettings, KGameCanvasAbstract* parent)
17 : ClickableCanvas(parent)
18 , m_pool_num(num)
19 , m_board(b)
20 , m_flipped(false)
21 , m_square_size(0)
22 , m_width(1)
23 , m_dragged_index(-1)
24 , m_anim_settings(animSettings) {
25 m_main_animation = new MainAnimation( 1.0 );
26 setGridWidth(1);
30 PiecePool::~PiecePool() {
31 delete m_main_animation;
35 QPoint PiecePool::toReal(int i) const {
36 int x = i % m_width;
37 int y = i / m_width;
39 if (y & 1)
40 x = m_width - 1 - x;
42 if (m_flipped)
43 y = -1 - y;
45 return QPoint(x, y) * m_square_size;
49 int PiecePool::toLogical(const QPoint& p) const {
50 int x = p.x() / m_square_size;
51 int y = p.y() / m_square_size;
53 if (x<0 || x >= m_width)
54 return -1;
56 if (m_flipped)
57 y = -y;
59 if (y & 1)
60 x = m_width - 1 - x;
62 int retv = y * m_width + x;
63 if (retv < 0 || static_cast<unsigned int>(retv) >= m_sprites.size())
64 return -1;
66 return retv;
70 void PiecePool::settingsChanged() {
75 void PiecePool::setGridWidth(int w) {
76 m_width = w > 0 ? w : 1;
79 QRect PiecePool::boardRect() {
80 Q_ASSERT(m_width > 0);
81 int height = (m_sprites.size() + m_width - 1) / m_width;
82 QSize sz(m_width, m_flipped ? -height : height);
83 return QRect(pos(), sz * m_square_size);
87 int PiecePool::fill() {
88 return m_sprites.size();
92 void PiecePool::clear() {
93 m_sprites.clear();
96 void PiecePool::animate(const Animate::Pool::Scheme& scheme, Animate::AnimationType type) {
97 m_main_animation->addAnimation(scheme.run(m_anim_settings, this, type));
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 kError() << "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 animate(Animate::Pool::move(m_sprites[i], i));
117 m_sprites[index] = nsprite;
118 animate(Animate::Pool::move(m_sprites[index], index), Animate::Instant);
119 animate(Animate::Pool::appear(m_sprites[index]));
123 NamedSprite PiecePool::getSprite(int index) {
124 if(m_dragged && index == m_dragged_index)
125 return m_dragged;
127 if(m_dragged && index > m_dragged_index)
128 index--;
130 if(index < 0 || index >= (int)m_sprites.size() ) {
131 kError() << "invalid index" << index;
132 return NamedSprite();
135 return m_sprites[index];
139 void PiecePool::removeSprite(int index) {
140 if(m_dragged && index == m_dragged_index) {
141 m_dragged = NamedSprite();
142 m_dragged_index = -1;
143 return;
146 if(m_dragged && index > m_dragged_index)
147 index--;
149 if(index < 0 || index >= (int)m_sprites.size() ) {
150 kError() << "invalid index" << index;
151 return;
154 takeSpriteAt(index);
158 NamedSprite PiecePool::takeSprite(int index) {
159 if(m_dragged && index == m_dragged_index) {
160 NamedSprite retv = m_dragged;
161 m_dragged = NamedSprite();
162 m_dragged_index = -1;
164 return retv;
167 kError() << "Only the sprite being dropped can be taken from the pool.";
168 return NamedSprite();
169 #if 0
170 if(m_dragged && index > m_dragged_index)
171 index--;
173 if(index < 0 || index >= (int)m_sprites.size() ) {
174 kError() << "invalid index" << index;
175 return NamedSprite();
178 return takeSpriteAt(index);
179 #endif
183 NamedSprite PiecePool::takeSpriteAt(int index) {
184 if(index < 0 || index >= (int)m_sprites.size() ) {
185 kError() << "invalid index" << index;
186 return NamedSprite();
189 NamedSprite retv = m_sprites[index];
190 if (!retv)
191 return NamedSprite();
192 animate(Animate::Pool::disappear(retv));
194 for(int i = index; i < (int)m_sprites.size()-1; i++) {
195 // double speed = (1.0 + 1.0 / (i - index + 1)) * 0.4;
196 m_sprites[i] = m_sprites[i+1];
197 animate(Animate::Pool::move(m_sprites[i], i));
199 m_sprites.resize(m_sprites.size()-1);
201 return retv;
205 void PiecePool::cancelDragging(bool fadeOff) {
206 if(!m_dragged)
207 return;
209 if (fadeOff) {
210 NamedSprite phantom = m_dragged.duplicate();
211 animate(Animate::Pool::disappear(phantom));
214 m_dragged.sprite()->putInCanvas(this);
215 m_dragged.sprite()->setPixmap(loadSprite(m_dragged.name()));
216 insertSprite(m_dragged_index, m_dragged);
218 m_dragged = NamedSprite();
219 m_dragged_index = -1;
223 void PiecePool::flipAndMoveBy(QPoint p) {
224 QPoint deltapos = m_flipped ? -p : p;
225 moveTo(pos() + deltapos);
226 m_flipped = !m_flipped;
228 for(int i=0;i<(int)m_sprites.size(); i++) {
229 SpritePtr p = m_sprites[i].sprite();
230 p->setPixmap(loadSprite(m_sprites[i].name()));
231 animate(Animate::Pool::move(m_sprites[i], i), Animate::Instant);
236 void PiecePool::onResize(int new_size, bool force_reload) {
237 if (m_square_size == new_size && !force_reload)
238 return;
240 m_square_size = new_size;
241 m_loader.setSize(m_square_size);
243 // update the sprites
244 for (int i=0;i<(int)m_sprites.size(); i++) {
245 m_sprites[i].sprite()->setPixmap(loadSprite(m_sprites[i].name()));
246 m_main_animation->addAnimation(AnimationPtr(new InstantAnimation(m_sprites[i].sprite(), toReal(i))));
251 void PiecePool::onMouseRelease(const QPoint& pos, int button) {
252 if (button != Qt::LeftButton || !m_dragged)
253 return;
255 m_board->m_dropped_pool = m_pool_num;
256 m_board->m_dropped_index = m_dragged_index;
258 /* did the board take this sprite? */
259 m_board->dropOn( m_pool_num, m_dragged_index, pos + this->pos() - m_board->pos() );
261 m_board->m_dropped_pool = -1;
262 m_board->m_dropped_index = -1;
264 cancelDragging(true);
268 void PiecePool::onMousePress(const QPoint& pos, int button) {
269 if (button != Qt::LeftButton)
270 return;
272 if(m_dragged) {
273 kError() << "Eh? We are already dragging?";
274 cancelDragging(); //never remove implicitly a piece from the pool
277 int index = toLogical(pos);
278 if(index == -1)
279 return;
280 NamedSprite got = takeSpriteAt(index);
281 if(!got)
282 return;
284 got.sprite()->hide();
286 /* recreate the sprite, as "got" may be being animated */
287 QPixmap px = m_board->loadSprite(got.name());
288 QPoint at = pos + this->pos() - m_board->pos() - QPoint(px.width(), px.height())/2;
289 m_dragged = NamedSprite( got.name(), SpritePtr(new Sprite(px, m_board->piecesGroup(), at) ) );
290 m_dragged.sprite()->raise();
291 m_dragged.sprite()->show();
292 m_dragged_index = index;
296 void PiecePool::onMouseMove(const QPoint& pos, int /*button*/) {
297 if(m_dragged) {
298 m_dragged.sprite()->moveTo(pos + this->pos() - m_board->pos()
299 - QPoint(m_dragged.sprite()->pixmap().width(),
300 m_dragged.sprite()->pixmap().height() ) / 2 );
301 m_board->draggingOn( m_pool_num, m_dragged_index, pos + this->pos() - m_board->pos() );
305 QPixmap PiecePool::loadSprite(const QString& id) {
306 // use board flipped state here, because the pool
307 // flipping only refers to the displaying of pieces
308 // and should not affect their orientation (which should
309 // stay coherent with that of the pieces on the board).
310 return m_loader.piecePixmap(id, m_board->flipped());