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.
13 #include "animation.h"
14 #include "piecepool.h"
16 PiecePool::PiecePool(Board
* b
, Canvas::Abstract
* parent
)
24 PiecePool::~PiecePool() {
27 void PiecePool::settingsChanged() {
28 PieceGroup::settingsChanged();
31 Point
PiecePool::flipPoint(const Point
& p
) const {
33 if((retv
.y
>=0 ? retv
.y
: -1-retv
.y
) % 2 == 1)
34 retv
.x
= gridSize().x
-1-retv
.x
;
40 void PiecePool::setGridWidth(int w
) {
41 m_sprites
.changeSize(w
, (m_fill
+w
-1)/w
);
44 int PiecePool::fill() {
48 void PiecePool::setFill(int f
) {
51 m_sprites
.changeSize(0,0);
55 m_sprites
.changeSize(w
, (f
+w
-1)/w
);
60 void PiecePool::clear() {
64 void PiecePool::insertSprite(int index
, const NamedSprite
& nsprite
) {
65 if(m_dragged
&& index
> m_dragged_index
)
68 if(index
< 0 || index
> fill() ) {
69 std::cout
<< "invalid index " << index
<< " in PiecePool::insertPiece" << std::endl
;
74 Point i
= m_sprites
.nTh(index
);
76 NamedSprite replacep
= m_sprites
[i
];
77 m_sprites
[i
] = nsprite
;
78 m_sprites
[i
].sprite()->show();
79 m_sprites
[i
].sprite()->moveTo(converter()->toReal(i
));
83 for( i
=m_sprites
.next(i
); i
<=m_sprites
.last(); i
=m_sprites
.next(i
)) {
86 NamedSprite tmp
= replacep
;
87 replacep
= m_sprites
[i
];
89 animatePiece(m_sprites
[i
].sprite(), i
, (1.0+1.0/speed
)*0.4);
94 NamedSprite
PiecePool::getSprite(int index
) {
95 if(m_dragged
&& index
== m_dragged_index
)
98 if(m_dragged
&& index
> m_dragged_index
)
101 if(index
< 0 || index
>= fill() ) {
102 ERROR("invalid index " << index
);
103 return NamedSprite();
106 Point i
= m_sprites
.nTh(index
);
110 NamedSprite
PiecePool::takeSprite(int index
) {
111 if(m_dragged
&& index
== m_dragged_index
) {
112 NamedSprite retv
= m_dragged
;
113 m_dragged
= NamedSprite();
114 m_dragged_index
= -1;
119 if(m_dragged
&& index
> m_dragged_index
)
122 if(index
< 0 || index
>= fill() ) {
123 ERROR("invalid index " << index
);
124 return NamedSprite();
127 Point i
= m_sprites
.nTh(index
);
128 NamedSprite piece
= takeNamedSprite(i
);
133 NamedSprite
PiecePool::takeNamedSprite(const Point
& _i
) {
135 if(i
< m_sprites
.first() || m_sprites
.last() < i
) {
136 ERROR("invalid index " << i
);
137 return NamedSprite();
140 NamedSprite piece
= m_sprites
[i
];
142 return NamedSprite();
146 i
= m_sprites
.next(i
);
147 for(; i
<=m_sprites
.last(); i
=m_sprites
.next(i
)) {
148 m_sprites
[previ
] = m_sprites
[i
];
150 if(m_sprites
[previ
]) {
151 animatePiece(m_sprites
[previ
].sprite(), previ
, (1.0+1.0/speed
)*0.4);
157 m_sprites
[previ
] = NamedSprite();
163 Canvas::Abstract
* PiecePool::piecesGroup() {
167 void PiecePool::clearDrag(bool fadeOff
) {
171 m_dragged
.sprite()->setPixmap( m_loader( m_dragged
.name() ) );
172 m_dragged
.sprite()->putInCanvas(piecesGroup());
175 SpritePtr phantom
= SpritePtr(m_dragged
.sprite()->duplicate());
177 enqueue( boost::shared_ptr
<Animation
>(new FadeAnimation(phantom
, phantom
->pos(), 255, 0)) );
179 enqueue( boost::shared_ptr
<Animation
>(new CaptureAnimation(phantom
)) );
182 insertSprite(m_dragged_index
, m_dragged
);
184 m_dragged
= NamedSprite();
185 m_dragged_index
= -1;
188 void PiecePool::flipAndMoveBy(QPoint p
) {
189 QPoint deltapos
= m_flipped
? -p
: p
;
190 moveTo(pos() + deltapos
);
191 m_flipped
= !m_flipped
;
193 for(Point i
=m_sprites
.first(); i
<=m_sprites
.last(); i
=m_sprites
.next(i
))
195 if(m_anim_movement
) {
196 enqueue(boost::shared_ptr
<Animation
>(new InstantAnimation(m_sprites
[i
].sprite(),
197 m_sprites
[i
].sprite()->pos() - deltapos
)));
198 enqueue(boost::shared_ptr
<Animation
>(new MovementAnimation(m_sprites
[i
].sprite(),
199 converter()->toReal(i
), 1.0)));
202 enqueue(boost::shared_ptr
<Animation
>(new InstantAnimation(m_sprites
[i
].sprite(),
203 converter()->toReal(i
))));
207 void PiecePool::updateSprites() {
208 // adjust piece positions
209 for (Point i
= m_sprites
.first(); i
<= m_sprites
.last(); i
= m_sprites
.next(i
)) {
210 boost::shared_ptr
<Sprite
> p
= m_sprites
[i
].sprite();
214 p
->setPixmap( m_loader( m_sprites
[i
].name() ) );
220 void PiecePool::onResize(int new_size
, bool force_reload
) {
221 if(m_square_size
== new_size
&& !force_reload
)
224 PieceGroup::onResize(new_size
);
226 // update the sprites
230 void PiecePool::onMouseRelease(const QPoint
& pos
, int button
) {
231 if (button
!= Qt::LeftButton
|| !m_dragged
)
234 /* did the board take this sprite? */
235 m_board
->dropOn( 0/*BROKEN*/, m_dragged_index
, pos
+ this->pos() - m_board
->pos() );
238 if(!m_board
->m_drop_sprite
&& m_dragged
) {
240 //this happens if the animator used the piece being dropped but removed another piece from the pool
241 //for instance it remove another piece of the same type.
242 m_dragged
= NamedSprite( m_dragged
.name(), SpritePtr(m_dragged
.sprite()->duplicate()) );
245 m_board
->m_drop_sprite
= NamedSprite();
249 void PiecePool::onMousePress(const QPoint
& pos
, int button
) {
250 if (button
!= Qt::LeftButton
)
254 std::cout
<< "Eh? We are already dragging?" << std::endl
;
255 m_board
->m_drop_sprite
= NamedSprite();
256 clearDrag(); //never remove implicitly a piece from the pool
259 Point p
= converter()->toLogical(pos
);
260 NamedSprite got
= takeNamedSprite(p
);
264 got
.sprite()->hide();
266 /* recreate the sprite, as "got" may be being animated */
267 QPixmap px
= m_board
->m_loader( got
.name() );
268 QPoint at
= pos
+ this->pos() - m_board
->pos() - QPoint(px
.width(), px
.height())/2;
269 m_dragged
= NamedSprite( got
.name(), SpritePtr(new Sprite(px
, m_board
->piecesGroup(), at
)) );
270 m_dragged
.sprite()->raise();
271 m_dragged
.sprite()->show();
272 m_board
->m_drop_sprite
= m_dragged
;
275 void PiecePool::onMouseMove(const QPoint
& pos
, int /*button*/) {
277 m_dragged
.sprite()->moveTo(pos
+ this->pos() - m_board
->pos()
278 - QPoint(m_dragged
.sprite()->pixmap().width(),
279 m_dragged
.sprite()->pixmap().height() ) / 2 );
280 m_board
->draggingOn( 0/*BROKEN*/, m_dragged_index
, pos
+ this->pos() - m_board
->pos() );