Added real animations to the Shogi animator.
[tagua.git] / src / graphicalinfo.cpp__
blob2c54dce972b2f19e3b5b08d48b435a38696eb6e0
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 */
11 #include "graphicalinfo.h"
12 #include "chesstable.h"
13 #include "board.h"
14 #include "piecepool.h"
15 #include "pointconverter.h"
16 #include "piecesprite.h"
17 #include "animation.h"
18 #include "pref_theme.h"
19 #include "movelist_table.h"
20 #include "global.h"
22 using namespace boost;
24 void GraphicalInfoProxy::settingsChanged() {
25   m_info->settingsChanged();
28 //BEGIN GraphicalInfo
30 GraphicalInfo::GraphicalInfo(ChessTable* view,
31                              AbstractPosition::Ptr startingPosition,
32                              VariantInfo* variant)
33 : m_view(view)
34 , m_variant(variant) {
36   m_pos = startingPosition->clone();
37   Point s = m_pos->size();
38   for(int i=0;i<s.x;i++)
39   for(int j=0;j<s.y;j++)
40     m_pos->set(Point(i,j), AbstractPiece::Ptr());
42   m_board = view->board();
44   m_board->createGrid(m_pos->size(), m_pos->borderCoords());
45   m_board->reset();
47   m_view->pool(0)->clear();
48   m_view->pool(1)->clear();
50   m_animator = m_variant->createAnimator(m_board->converter(), this);
52   m_proxy = new GraphicalInfoProxy(this);
53   settings.onChange(m_proxy, SLOT(settingsChanged()));
54   settingsChanged();
56   if (startingPosition)
57     warp(AbstractMove::Ptr(), startingPosition);
60 GraphicalInfo::~GraphicalInfo() {
61   delete m_proxy;
64 void GraphicalInfo::settingsChanged() {
66   /* recreate the animator to reload its settings */
67   m_animator = m_variant->createAnimator(m_board->converter(), this);
69   QString theme = PrefTheme::getBestTheme(m_variant);
70   QString sqtheme = PrefTheme::getBestTheme(m_variant, PrefTheme::Squares);
71   QString figtheme = PrefTheme::getBestTheme(m_variant, PrefTheme::Figurines);
73   m_board->loader()->setBasePath( theme );
74   m_board->tagsLoader()->setBasePath( sqtheme );
76   m_view->pool(0)->loader()->setBasePath( theme );
77   m_view->pool(1)->loader()->setBasePath( theme );
79   m_view->moveListTable()->setLoaderBasePath( figtheme );
80   m_view->moveListTable()->settingsChanged();
82   //clear board and pool, forcing reload
83   m_view->settingsChanged();
86 void GraphicalInfo::setup(const shared_ptr<UserEntity>& entity) {
87   m_view->setEntity(entity);
90 int GraphicalInfo::getIntSetting(const QString& key, int def_value) const {
91   QStringList l = key.split(".");
92   if (l.size() == 0)
93     return def_value;
95   Settings s = settings;
96   for(int i = 0; i < l.size() - 1; i++) {
97     s = s.group(l[i]);
98   }
99   return s[l.last()] | def_value;
102 bool GraphicalInfo::getBoolSetting(const QString& key, bool def_value) const {
103   QStringList l = key.split(".");
104   if(l.size()==0)
105     return def_value;
107   SettingGroup s = settings.group(l[0]);
108   for(int i=1;i<l.size();i++)
109     s = s.group(l[i]);
111   return s.flag("enabled", def_value);
114 QString GraphicalInfo::getStringSetting(const QString& key, const QString& def_value) const {
115   QStringList l = key.split(".");
116   if(l.size()==0)
117     return def_value;
119   Settings s = settings;
120   for(int i=0;i<l.size()-1;i++)
121     s = s.group(l[i]);
122   return s[l[l.size()-1]] | def_value;
125 GraphicalInfo::SpritePtr GraphicalInfo::getSprite(const Point& p) const {
126   if (!m_board->m_sprites.valid(p))
127     return shared_ptr<PieceSprite>();
129   return m_board->m_sprites[p].sprite();
132 GraphicalInfo::SpritePtr GraphicalInfo::setPiece(const Point& p,
133                               AbstractPiece::Ptr piece, bool usedrop, bool show) {
134   Q_ASSERT(piece);
135   if(!m_board->m_sprites.valid(p))
136     return SpritePtr();
138   m_pos->set(p, piece);
139   QPixmap px = m_board->m_loader(piece->name());
141   SpritePtr s;
142   if(usedrop && m_board->m_drop_sprite &&
143         m_board->m_drop_sprite.piece()->equals(piece) ) {
144     s = m_board->m_drop_sprite.sprite();
145     m_board->m_drop_sprite = Element();
146   }
147   else {
148     s = m_board->createSprite(px, p);
149     if (show) s->show();
150   }
151   m_board->m_sprites[p] = Board::BoardSprite(piece->name(), s);
152   return s;
155 Element GraphicalInfo::getElement(const Point& p) const {
156   if(!m_board->m_sprites.valid(p))
157     return Element();
159   return Element(m_pos->get(p), m_board->m_sprites[p].sprite());
162 void GraphicalInfo::setElement(const Point& p, const Element& e) {
163   if(!m_board->m_sprites.valid(p))
164     return;
166   AbstractPiece::Ptr piece = e.piece();
167   m_pos->set(p, piece);
168   m_board->m_sprites[p] = Board::BoardSprite( piece ? piece->name() : 0, e.sprite() );
171 void GraphicalInfo::removeElement(const Point& p) {
172   if(!m_board->m_sprites.valid(p))
173     return;
175   setElement(p, Element());
178 void GraphicalInfo::updatePool(AbstractPosition::PoolPtr pool) {
180   AbstractPosition::PoolPtr curr = m_pos->pool();
182   AbstractPosition::AbstractPool::iterator oldit = curr->begin();
183   AbstractPosition::AbstractPool::iterator newit = pool->begin();
185   while(oldit != curr->end() || newit != pool->end()) {
186     if(newit == pool->end() || (oldit != curr->end()
187             && oldit->first->less(newit->first) )) {
188       removeFromPool(oldit->first, oldit->second);
189       ++oldit;
190     }
191     else if (oldit == curr->end() || (newit != pool->end()
192             && newit->first->less(oldit->first) )) {
193       addToPool(newit->first, newit->second);
194       ++newit;
195     }
196     else {
197       Q_ASSERT(newit->first->equals(oldit->first));
198       if(oldit->second < newit->second)
199         addToPool(newit->first, newit->second - oldit->second);
200       else if(oldit->second > newit->second)
201         removeFromPool(newit->first, oldit->second - newit->second);
202       ++newit;
203       ++oldit;
204     }
205   }
208 void GraphicalInfo::addToPool(AbstractPiece::Ptr piece, int n) {
209   PiecePool *pool = m_view->pool(!piece->color());
210   QPixmap px = pool->m_loader(piece->name());
212   for(int i=0;i<n;i++) {
213     SpritePtr s = SpritePtr( new PieceSprite( px, pool->piecesGroup(), QPoint() ) );
214     pool->addPiece(Element(piece, s));
215   }
217   m_pos->addToPool(piece, n);
220 void GraphicalInfo::removeFromPool(AbstractPiece::Ptr piece, int n) {
221   PiecePool *pool = m_view->pool(!piece->color());
223   for(int i=0;i<n;i++)
224     pool->takePiece(piece);
225   m_pos->removeFromPool(piece, n);
228 void GraphicalInfo::addTag(const QString& name, Point pt, bool over) {
229   m_board->addTag(name, pt, over);
232 void GraphicalInfo::clearTags(const QString& name) {
233   m_board->clearTags(name);
236 void GraphicalInfo::setTags(const QString& name, Point p1, Point p2,
237                         Point p3, Point p4, Point p5, Point p6 ) {
238   m_board->setTags(name, p1, p2, p3, p4, p5, p6);
241 bool GraphicalInfo::consistent() const {
242   for (Point i = first(); i <= last(); i = next(i)) {
243     Element e = getElement(i);
244     if (static_cast<bool>(e.piece()) ^
245         static_cast<bool>(e.sprite())) return false;
246   }
247   return true;
250 Point GraphicalInfo::first() const { return m_board->m_sprites.first(); }
251 Point GraphicalInfo::last() const { return m_board->m_sprites.last(); }
252 Point GraphicalInfo::next(const Point& p) const { return m_board->m_sprites.next(p); }
253 bool GraphicalInfo::valid(const Point& p) const { return m_board->m_sprites.valid(p); }
256 void GraphicalInfo::forward(AbstractMove::Ptr move, AbstractPosition::Ptr pos,
257   const shared_ptr<PieceSprite>& /*movingSprite*/) {
258   AbstractPiece::Ptr sel1 = m_pos->get(m_board->selection);
260   if (move) {
261     shared_ptr<AnimationGroup> animation = m_animator->forward(pos, move);
262     animation->setChainAbortions(false);
263     m_board->enqueue(animation);
264     m_board->setTags("highlighting", move->toUserMove().from, move->toUserMove().to);
265   }
266   else
267     warp(AbstractMove::Ptr(), pos);
269   AbstractPiece::Ptr sel2 = m_pos->get(m_board->selection);
270   if(!(sel1 && sel2 && sel1->equals(sel2)))
271     m_board->cancelSelection();
273   m_board->cancelPremove();
274   m_view->updateTurn(pos->turn());
275   m_board->onPositionChanged();
278 void GraphicalInfo::back(AbstractMove::Ptr lastMove,
279                          AbstractMove::Ptr move,
280                          AbstractPosition::Ptr pos) {
281   AbstractPiece::Ptr sel1 = m_pos->get(m_board->selection);
283   if (move) {
284     shared_ptr<AnimationGroup> animation = m_animator->back(pos, move);
285     animation->setChainAbortions(false);
286     m_board->enqueue(animation);
287   }
288   else
289     warp(lastMove, pos);
291   if (lastMove)
292     m_board->setTags("highlighting", lastMove->toUserMove().from, lastMove->toUserMove().to);
293   else
294     m_board->clearTags("highlighting");
296   AbstractPiece::Ptr sel2 = m_pos->get(m_board->selection);
297   if(!(sel1 && sel2 && sel1->equals(sel2)))
298     m_board->cancelSelection();
299   m_board->cancelPremove();
300   m_view->updateTurn(pos->turn());
301   m_board->onPositionChanged();
304 void GraphicalInfo::warp(AbstractMove::Ptr lastMove, AbstractPosition::Ptr pos) {
306   AbstractPiece::Ptr sel1 = m_pos->get(m_board->selection);
307   shared_ptr<AnimationGroup> animation = m_animator->warp(pos);
308   animation->setChainAbortions(false);
310   m_board->enqueue(animation);
312   if (lastMove)
313     m_board->setTags("highlighting", lastMove->toUserMove().from, lastMove->toUserMove().to);
314   else
315     m_board->clearTags("highlighting");
317   AbstractPiece::Ptr sel2 = m_pos->get(m_board->selection);
318   if(!(sel1 && sel2 && sel1->equals(sel2)))
319     m_board->cancelSelection();
320   m_view->updateTurn(pos->turn());
321   m_board->onPositionChanged();
324 void GraphicalInfo::adjustSprite(const Point& p) {
325   SpritePtr sprite = m_board->m_sprites[p].sprite();
326   Q_ASSERT(sprite);
327   QPoint destination = m_board->converter()->toReal(p);
328   shared_ptr<Animation> animation(new MovementAnimation(sprite, destination));
329   m_board->enqueue(animation);
332 void GraphicalInfo::setTurn(int turn) {
333   m_pos->setTurn(turn);
334   m_view->updateTurn(m_pos->turn());
337 #include "graphicalinfo.moc"