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.
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
)
28 , m_anim_settings(animSettings
) {
29 m_main_animation
= new MainAnimation( 1.0 );
34 PiecePool::~PiecePool() {
35 delete m_main_animation
;
39 QPoint
PiecePool::toReal(int i
) const {
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
)
66 int retv
= y
* m_width
+ x
;
67 if (retv
< 0 || static_cast<unsigned int>(retv
) >= m_sprites
.size())
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() {
100 void PiecePool::insertSprite(int index
, const NamedSprite
& nsprite
) {
101 if(m_dragged
&& index
> m_dragged_index
)
104 if(index
< 0 || index
> fill() ) {
105 ERROR("invalid index " << index
);
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
)
130 if(m_dragged
&& index
> m_dragged_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;
149 if(m_dragged
&& index
> m_dragged_index
)
152 if(index
< 0 || index
>= (int)m_sprites
.size() ) {
153 ERROR("invalid index " << 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;
170 ERROR("Only the sprite being dropped can be taken from the pool.");
171 return NamedSprite();
173 if(m_dragged
&& index
> m_dragged_index
)
176 if(index
< 0 || index
>= (int)m_sprites
.size() ) {
177 ERROR("invalid index " << index
);
178 return NamedSprite();
181 return takeSpriteAt(index
);
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
];
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);
210 void PiecePool::cancelDragging(bool 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
)
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
)
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
)
280 ERROR("Eh? We are already dragging?");
281 cancelDragging(); //never remove implicitly a piece from the pool
284 int index
= toLogical(pos
);
287 NamedSprite got
= takeSpriteAt(index
);
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*/) {
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());