Fixed coordinate conversion.
[tagua/yd.git] / src / piecepool.cpp
blob4845d617bcf4d35a8e27d1bab07ba47b545389d2
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 */
12 #include "board.h"
13 #include "animation.h"
14 #include "piecepool.h"
16 /*****************************************************************************************/
17 PiecePool::PiecePool(int num, Board* b, KGameCanvasAbstract* parent)
18 : ClickableCanvas(parent)
19 , m_pool_num(num)
20 , m_board(b)
21 , m_flipped(false)
22 , m_square_size(0)
23 , m_width(1)
24 , m_dragged_index(-1) {
25 m_main_animation = new MainAnimation( 1.0 );
26 setGridWidth(1);
29 /*****************************************************************************************/
30 PiecePool::~PiecePool() {
31 delete m_main_animation;
34 /*****************************************************************************************/
35 QPoint PiecePool::toReal(int i) {
36 int x = i%m_width;
37 int y = i/m_width;
38 if(y&1)
39 x = m_width-1-x;
40 if(m_flipped)
41 y = -1-y;
43 return QPoint(m_square_size*x, m_square_size*y);
46 /*****************************************************************************************/
47 int PiecePool::toLogical(const QPoint& p) {
48 int x = p.x()/m_square_size;
49 int y = p.y()/m_square_size;
51 if(x<0 || x>= m_width)
52 return -1;
53 if(m_flipped)
54 y = -y;
55 if(y&1)
56 x = m_width-1-x;
58 int retv = y*m_width + x;
59 if(retv < 0 || retv >= (int)m_sprites.size())
60 return -1;
61 return retv;
64 /*****************************************************************************************/
65 void PiecePool::settingsChanged() {
66 //PieceGroup::settingsChanged();
69 /*****************************************************************************************/
70 void PiecePool::setGridWidth(int w) {
71 m_width = w;
74 /*****************************************************************************************/
75 int PiecePool::fill() {
76 return m_sprites.size();
79 /*****************************************************************************************/
80 void PiecePool::clear() {
81 m_sprites.clear();
84 /*****************************************************************************************/
85 void PiecePool::insertSprite(int index, const NamedSprite& nsprite) {
86 if(m_dragged && index > m_dragged_index)
87 index--;
89 if(index < 0 || index > fill() ) {
90 ERROR("invalid index " << index); TRAP();
91 return;
94 m_sprites.resize(m_sprites.size()+1);
96 for(int i = m_sprites.size()-1; i > index; i--) {
97 double speed = (1.0+1.0/(i - index + 1))*0.4;
98 m_sprites[i] = m_sprites[i-1];
99 m_sprites[i].sprite()->moveTo(toReal(i)); //BROKEN animate to that point?
102 m_sprites[index] = nsprite;
103 m_sprites[index].sprite()->show();
104 m_sprites[index].sprite()->moveTo(toReal(index));
105 //BROKEN fadeIn(index);
108 /*****************************************************************************************/
109 NamedSprite PiecePool::getSprite(int index) {
110 if(m_dragged && index == m_dragged_index)
111 return m_dragged;
113 if(m_dragged && index > m_dragged_index)
114 index--;
116 if(index < 0 || index >= (int)m_sprites.size() ) {
117 ERROR("invalid index " << index);
118 return NamedSprite();
121 return m_sprites[index];
124 /*****************************************************************************************/
125 NamedSprite PiecePool::takeSprite(int index) {
126 if(m_dragged && index == m_dragged_index) {
127 NamedSprite retv = m_dragged;
128 m_dragged = NamedSprite();
129 m_dragged_index = -1;
131 return retv;
134 if(m_dragged && index > m_dragged_index)
135 index--;
137 if(index < 0 || index >= (int)m_sprites.size() ) {
138 ERROR("invalid index " << index);
139 return NamedSprite();
142 return takeSpriteAt(index);
145 /*****************************************************************************************/
146 NamedSprite PiecePool::takeSpriteAt(int index) {
147 if(index < 0 || index >= (int)m_sprites.size() ) {
148 ERROR("invalid index " << index); TRAP();
149 return NamedSprite();
152 NamedSprite retv = m_sprites[index];
153 if(!retv)
154 return NamedSprite();
156 for(int i = index; i < (int)m_sprites.size()-1; i++) {
157 double speed = (1.0+1.0/(i - index + 1))*0.4;
158 m_sprites[i] = m_sprites[i+1];
159 m_sprites[i].sprite()->moveTo(toReal(i)); //BROKEN animate to that point?
161 m_sprites.resize(m_sprites.size()-1);
163 return retv;
166 /*****************************************************************************************/
167 KGameCanvasAbstract* PiecePool::piecesGroup() {
168 return this;
171 /*****************************************************************************************/
172 void PiecePool::cancelDragging(bool fadeOff) {
173 if(!m_dragged)
174 return;
176 m_dragged.sprite()->setPixmap( m_loader( m_dragged.name() ) );
177 m_dragged.sprite()->putInCanvas(piecesGroup());
179 if (fadeOff) {
180 SpritePtr phantom = SpritePtr(m_dragged.sprite()->duplicate());
181 if(1/*BROKEN m_anim_fade*/)
182 m_main_animation->addAnimation( AnimationPtr(new FadeAnimation(phantom, phantom->pos(), 255, 0)) );
183 else
184 m_main_animation->addAnimation( AnimationPtr(new CaptureAnimation(phantom)) );
187 insertSprite(m_dragged_index, m_dragged);
189 m_dragged = NamedSprite();
190 m_dragged_index = -1;
193 /*****************************************************************************************/
194 void PiecePool::flipAndMoveBy(QPoint p) {
195 QPoint deltapos = m_flipped ? -p : p;
196 moveTo(pos() + deltapos);
197 m_flipped = !m_flipped;
199 for(int i=0;i<(int)m_sprites.size(); i++)
200 if(1/*BROKEN m_anim_movement*/) {
201 m_main_animation->addAnimation(AnimationPtr(new InstantAnimation(m_sprites[i].sprite(),
202 m_sprites[i].sprite()->pos() - deltapos)));
203 m_main_animation->addAnimation(AnimationPtr(new MovementAnimation(m_sprites[i].sprite(),
204 toReal(i), 1.0)));
206 else
207 m_main_animation->addAnimation(AnimationPtr(new InstantAnimation(m_sprites[i].sprite(),
208 toReal(i))));
211 /*****************************************************************************************/
212 void PiecePool::onResize(int new_size, bool force_reload) {
213 if(m_square_size == new_size && !force_reload)
214 return;
216 m_square_size = new_size;
217 m_loader.setSize(m_square_size);
219 // update the sprites
220 for (int i=0;i<(int)m_sprites.size(); i++) {
221 m_sprites[i].sprite()->setPixmap( m_loader( m_sprites[i].name() ) );
222 m_main_animation->addAnimation(AnimationPtr(new InstantAnimation(m_sprites[i].sprite(), toReal(i))));
226 /*****************************************************************************************/
227 void PiecePool::onMouseRelease(const QPoint& pos, int button) {
228 if (button != Qt::LeftButton || !m_dragged)
229 return;
231 m_board->m_dropped_pool = m_pool_num;
232 m_board->m_dropped_index = m_dragged_index;
234 /* did the board take this sprite? */
235 m_board->dropOn( m_pool_num, m_dragged_index, pos + this->pos() - m_board->pos() );
237 m_board->m_dropped_pool = -1;
238 m_board->m_dropped_index = -1;
240 #if 0
241 bool fadeOff = true;
242 if(!m_board->m_drop_sprite && m_dragged) {
244 //this happens if the animator used the piece being dropped but removed another piece from the pool
245 //for instance it remove another piece of the same type.
246 m_dragged = NamedSprite( m_dragged.name(), SpritePtr(m_dragged.sprite()->duplicate()) );
247 fadeOff = false;
249 m_board->m_drop_sprite = NamedSprite();
250 cancelDragging(fadeOff);
251 #endif
253 cancelDragging(true);
256 /*****************************************************************************************/
257 void PiecePool::onMousePress(const QPoint& pos, int button) {
258 if (button != Qt::LeftButton)
259 return;
261 if(m_dragged) {
262 std::cout << "Eh? We are already dragging?" << std::endl;
263 #if 0
264 m_board->m_drop_sprite = NamedSprite();
265 #endif
266 cancelDragging(); //never remove implicitly a piece from the pool
269 int index = toLogical(pos);
270 NamedSprite got = takeSpriteAt(index);
271 if(!got)
272 return;
274 got.sprite()->hide();
276 /* recreate the sprite, as "got" may be being animated */
277 QPixmap px = m_board->m_loader( got.name() );
278 QPoint at = pos + this->pos() - m_board->pos() - QPoint(px.width(), px.height())/2;
279 m_dragged = NamedSprite( got.name(), SpritePtr(new Sprite(px, m_board->piecesGroup(), at) ) );
280 m_dragged.sprite()->raise();
281 m_dragged.sprite()->show();
282 m_dragged_index = index;
283 #if 0
284 m_board->m_drop_sprite = m_dragged;
285 #endif
288 /*****************************************************************************************/
289 void PiecePool::onMouseMove(const QPoint& pos, int /*button*/) {
290 if(m_dragged) {
291 m_dragged.sprite()->moveTo(pos + this->pos() - m_board->pos()
292 - QPoint(m_dragged.sprite()->pixmap().width(),
293 m_dragged.sprite()->pixmap().height() ) / 2 );
294 m_board->draggingOn( m_pool_num, m_dragged_index, pos + this->pos() - m_board->pos() );