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 "piecepool.h"
16 PiecePool::PiecePool(int num
, Board
* b
, const AnimationSettings
& animSettings
, KGameCanvasAbstract
* parent
)
17 : ClickableCanvas(parent
)
24 , m_anim_settings(animSettings
) {
25 m_main_animation
= new MainAnimation( 1.0 );
30 PiecePool::~PiecePool() {
31 delete m_main_animation
;
35 QPoint
PiecePool::toReal(int i
) const {
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
)
62 int retv
= y
* m_width
+ x
;
63 if (retv
< 0 || static_cast<unsigned int>(retv
) >= m_sprites
.size())
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() {
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
)
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 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
)
127 if(m_dragged
&& index
> m_dragged_index
)
130 if(index
< 0 || index
>= (int)m_sprites
.size() ) {
131 ERROR("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;
146 if(m_dragged
&& index
> m_dragged_index
)
149 if(index
< 0 || index
>= (int)m_sprites
.size() ) {
150 ERROR("invalid index " << 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;
167 ERROR("Only the sprite being dropped can be taken from the pool.");
168 return NamedSprite();
170 if(m_dragged
&& index
> m_dragged_index
)
173 if(index
< 0 || index
>= (int)m_sprites
.size() ) {
174 ERROR("invalid index " << index
);
175 return NamedSprite();
178 return takeSpriteAt(index
);
183 NamedSprite
PiecePool::takeSpriteAt(int index
) {
184 if(index
< 0 || index
>= (int)m_sprites
.size() ) {
185 ERROR("invalid index " << index
);
186 return NamedSprite();
189 NamedSprite retv
= m_sprites
[index
];
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);
205 void PiecePool::cancelDragging(bool fadeOff
) {
210 NamedSprite phantom
= m_dragged
.duplicate();
211 animate(Animate::Pool::disappear(phantom
));
214 m_dragged
.sprite()->putInCanvas(this);
215 m_dragged
.sprite()->setPixmap( m_loader( 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 animate(Animate::Pool::move(m_sprites
[i
], i
));
233 void PiecePool::onResize(int new_size
, bool force_reload
) {
234 if (m_square_size
== new_size
&& !force_reload
)
237 m_square_size
= new_size
;
238 m_loader
.setSize(m_square_size
);
240 // update the sprites
241 for (int i
=0;i
<(int)m_sprites
.size(); i
++) {
242 m_sprites
[i
].sprite()->setPixmap( m_loader( m_sprites
[i
].name() ) );
243 m_main_animation
->addAnimation(AnimationPtr(new InstantAnimation(m_sprites
[i
].sprite(), toReal(i
))));
248 void PiecePool::onMouseRelease(const QPoint
& pos
, int button
) {
249 if (button
!= Qt::LeftButton
|| !m_dragged
)
252 m_board
->m_dropped_pool
= m_pool_num
;
253 m_board
->m_dropped_index
= m_dragged_index
;
255 /* did the board take this sprite? */
256 m_board
->dropOn( m_pool_num
, m_dragged_index
, pos
+ this->pos() - m_board
->pos() );
258 m_board
->m_dropped_pool
= -1;
259 m_board
->m_dropped_index
= -1;
261 cancelDragging(true);
265 void PiecePool::onMousePress(const QPoint
& pos
, int button
) {
266 if (button
!= Qt::LeftButton
)
270 ERROR("Eh? We are already dragging?");
271 cancelDragging(); //never remove implicitly a piece from the pool
274 int index
= toLogical(pos
);
277 NamedSprite got
= takeSpriteAt(index
);
281 got
.sprite()->hide();
283 /* recreate the sprite, as "got" may be being animated */
284 QPixmap px
= m_board
->m_loader( got
.name() );
285 QPoint at
= pos
+ this->pos() - m_board
->pos() - QPoint(px
.width(), px
.height())/2;
286 m_dragged
= NamedSprite( got
.name(), SpritePtr(new Sprite(px
, m_board
->piecesGroup(), at
) ) );
287 m_dragged
.sprite()->raise();
288 m_dragged
.sprite()->show();
289 m_dragged_index
= index
;
293 void PiecePool::onMouseMove(const QPoint
& pos
, int /*button*/) {
295 m_dragged
.sprite()->moveTo(pos
+ this->pos() - m_board
->pos()
296 - QPoint(m_dragged
.sprite()->pixmap().width(),
297 m_dragged
.sprite()->pixmap().height() ) / 2 );
298 m_board
->draggingOn( m_pool_num
, m_dragged_index
, pos
+ this->pos() - m_board
->pos() );