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 "animationmanager.h"
16 #include "chessboard.h"
19 PiecePool::PiecePool(const IColor
* pool
, ChessBoard
* b
,
20 AnimationManager
* animManager
,
21 KGameCanvasAbstract
* parent
)
22 : ClickableCanvas(parent
)
29 , m_anim_manager(animManager
) {
34 PiecePool::~PiecePool() { }
37 QPoint
PiecePool::toReal(int i
) const {
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
)
64 int retv
= y
* m_width
+ x
;
65 if (retv
< 0 || static_cast<unsigned int>(retv
) >= m_sprites
.size())
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() {
98 void PiecePool::insertSprite(int index
, const NamedSprite
& nsprite
) {
99 if(m_dragged
&& index
> m_dragged_index
)
102 if(index
< 0 || index
> fill() ) {
103 ERROR("invalid index " << index
);
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
)
128 if(m_dragged
&& index
> m_dragged_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;
147 if(m_dragged
&& index
> m_dragged_index
)
150 if(index
< 0 || index
>= (int)m_sprites
.size() ) {
151 ERROR("invalid index " << 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;
168 ERROR("Only the sprite being dropped can be taken from the pool.");
169 return NamedSprite();
171 if(m_dragged
&& index
> m_dragged_index
)
174 if(index
< 0 || index
>= (int)m_sprites
.size() ) {
175 ERROR("invalid index " << index
);
176 return NamedSprite();
179 return takeSpriteAt(index
);
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
];
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);
207 void PiecePool::cancelDragging(bool 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
)
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
)
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
)
277 ERROR("Eh? We are already dragging?");
278 cancelDragging(); //never remove implicitly a piece from the pool
281 int index
= toLogical(pos
);
284 NamedSprite got
= takeSpriteAt(index
);
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*/) {
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; }