Implemented in lua better selection tags.
[tagua/yd.git] / src / graphicalgame.cpp
blob484bf6afb57a42cc45c48d8563c630a96176d2f9
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 <iostream>
12 #include "graphicalgame.h"
13 #include "game.h"
14 #include "game_p.h"
15 #include "global.h"
16 #include "settings.h"
17 #include "graphicalsystem.h"
18 #include "movelist_table.h"
19 #include "decoratedmove.h"
20 #include "entities/userentity.h"
21 #include <iostream>
23 using namespace GamePrivate; // is this ok?
25 class CtrlAction {
26 Game* m_game;
27 bool m_done;
28 Index m_index;
29 public:
30 CtrlAction(Game* game)
31 : m_game(game)
32 , m_index(game->index()) {
33 m_done = m_game->back();
36 void forfait() { m_done = false; }
38 ~CtrlAction() {
39 if (m_done) m_game->goTo(m_index);
43 GraphicalGame::GraphicalGame(GraphicalSystem* graphical,
44 MoveList::Table* m)
45 : Game()
46 , m_graphical(graphical)
47 , m_movelist(m)
48 , m_anim_sequence(false) {
49 if(m_movelist) {
50 m_movelist->reset();
51 m_movelist->setLayoutStyle(graphical->m_variant->moveListLayout());
52 m_movelist->setNotifier( static_cast<MoveList::Notifier*>(this) );
53 m_movelist->show();
55 settings.onChange(this, SLOT(settingsChanged()));
56 settingsChanged();
59 GraphicalGame::~GraphicalGame() {
60 if(m_movelist) {
61 Q_ASSERT(m_movelist->getNotifier() == static_cast<MoveList::Notifier*>(this));
63 m_movelist->setNotifier(NULL, false);
67 void GraphicalGame::settingsChanged() {
68 m_anim_sequence = settings.flag("animations", true)
69 && settings("animations").flag("sequence", true);
70 m_anim_sequence_max = settings("animations")("sequence")[QString("max")] | 10;
73 void GraphicalGame::onAdded(const Index& ix) {
74 onAddedInternal(ix);
77 void GraphicalGame::onAddedInternal(const Index& ix, bool confirm_promotion) {
78 if(!m_movelist)
79 return;
81 int at;
82 History *vec = fetchRef(ix, &at);
83 if(!vec) {
84 std::cout << "--> Error in GraphicalGame::onAdded, invalid index "<< ix << std::endl;
85 return;
88 m_movelist->remove(ix, confirm_promotion); //clear existing, if any
90 Index index = ix;
91 for(int i=at;i<(int)vec->size();i++) {
92 Entry* e = &(*vec)[i];
93 PositionPtr prev = position(index.prev());
94 DecoratedMove mv = (e->move && prev) ? e->move->toDecoratedMove(prev) :
95 DecoratedMove() << MovePart(e->position ? "(-)" : "???");
96 int turn = prev ? prev->turn() : (index.totalNumMoves()+1)%2;
97 //mv += " " + QString::number(turn);
98 m_movelist->setMove(index, turn, mv, e->comment, confirm_promotion);
100 for (Variations::const_iterator it = e->variations.begin();
101 it != e->variations.end(); ++it)
102 onAddedInternal(index.next(it->first), confirm_promotion);
103 for (VComments::const_iterator it = e->vcomments.begin();
104 it != e->vcomments.end(); ++it)
105 m_movelist->setVComment(index, it->first, it->second, confirm_promotion);
107 index = index.next();
111 void GraphicalGame::onEntryChanged(const Index& at, int propagate) {
112 if(at <= Index(0)) {
113 Entry* e = fetch(at);
114 if(!e)
115 return;
116 if(at == current && e->position)
117 m_graphical->warp(e->move, e->position);
118 return;
121 if(m_movelist) {
122 Entry* e = fetch(at);
123 if(!e)
124 return;
126 Entry* pe = fetch(at.prev());
128 AbstractPosition::Ptr last_pos;
129 if (pe) last_pos = pe->position;
131 DecoratedMove mv = (e->move && last_pos) ? e->move->toDecoratedMove(last_pos) :
132 DecoratedMove() << MovePart(e->position ? "(-)" : "???");
133 int turn = last_pos ? last_pos->turn() : (at.totalNumMoves()+1)%2;
134 m_movelist->setMove(at, turn, mv, e->comment);
135 if(at == current && e->position)
136 m_graphical->warp(e->move, e->position);
138 // when an entry changes, chances are that we get some more information about the
139 // next ones as well
140 if(propagate) {
141 onEntryChanged(at.next(), propagate-1);
142 for (Variations::const_iterator it = e->variations.begin();
143 it != e->variations.end(); ++it)
144 onEntryChanged(at.next(it->first), propagate-1);
149 void GraphicalGame::onRemoved(const Index& i) {
150 if(m_movelist)
151 m_movelist->remove(i);
154 void GraphicalGame::onPromoteVariation(const Index& i, int v) {
155 if(m_movelist) {
156 m_movelist->promoteVariation(i,v);
157 onAddedInternal(i.next(), true);
158 onAddedInternal(i.next(v), true);
159 VComments vc = fetch(i)->vcomments;
160 VComments::const_iterator it = vc.find(v);
161 if(it != vc.end())
162 m_movelist->setVComment(i, v, it->second, true);
163 m_movelist->select(current, true);
167 void GraphicalGame::onSetComment(const Index& i, const QString& s) {
168 if(m_movelist)
169 m_movelist->setComment(i, s);
172 void GraphicalGame::onSetVComment(const Index& i, int v, const QString& s) {
173 if(m_movelist)
174 m_movelist->setVComment(i, v, s);
177 void GraphicalGame::onCurrentIndexChanged(const Index& old_c) {
178 if (m_ctrl) m_ctrl->forfait();
180 if(m_movelist)
181 m_movelist->select(current);
183 Entry *oe = fetch(old_c);
184 Entry *e = fetch(current);
185 std::pair<int, int> steps = old_c.stepsTo(current);
187 if(!e || !e->position)
188 return;
190 if(!oe || !oe->position) {
191 m_graphical->warp(move(), position());
192 return;
195 bool can_animate = (steps.first+steps.second <= 1) || (m_anim_sequence
196 && (steps.first+steps.second <= m_anim_sequence_max));
198 if(can_animate)
199 for(int i=1;i<=steps.first;i++)
200 if( !move(old_c.prev(i-1)) || !position(old_c.prev(i))) {
201 can_animate = false;
202 break;
205 if(can_animate)
206 for(int i=steps.second-1;i>=0;i--)
207 if( !move(current.prev(i)) || !position(current.prev(i))) {
208 can_animate = false;
209 break;
212 if(can_animate) {
213 for(int i=1;i<=steps.first;i++)
214 m_graphical->back( move(old_c.prev(i)), move(old_c.prev(i-1)), position(old_c.prev(i)));
215 for(int i=steps.second-1;i>=0;i--)
216 m_graphical->forward( move(current.prev(i)), position(current.prev(i)));
218 else
219 m_graphical->warp( move(), position());
222 void GraphicalGame::onAvailableUndo(bool e) {
223 if(m_movelist)
224 m_movelist->enableUndo(e);
227 void GraphicalGame::onAvailableRedo(bool e) {
228 if(m_movelist)
229 m_movelist->enableRedo(e);
232 void GraphicalGame::onUserSelectMove(const Index& i) {
233 if (boost::shared_ptr<UserEntity> entity = m_listener_entity.lock())
234 if (entity->goTo(i))
235 return;
237 // fallback
238 goTo(i);
241 void GraphicalGame::onUserSetComment(const Index& i, QString s) {
242 setComment(i, s);
245 void GraphicalGame::onUserSetVComment(const Index& i, int v, QString s) {
246 setVComment(i, v, s);
249 void GraphicalGame::onUserClearVariations(const Index& i) {
250 clearVariations(i);
253 void GraphicalGame::onUserTruncate(const Index& i) {
254 if (i == index())
255 if (boost::shared_ptr<UserEntity> entity = m_listener_entity.lock())
256 if (entity->truncate())
257 return;
259 // fallback
260 truncate(i);
263 void GraphicalGame::onUserPromoteVariation(const Index& i) {
264 if (i == index())
265 if (boost::shared_ptr<UserEntity> entity = m_listener_entity.lock())
266 if (entity->promoteVariation())
267 return;
269 // fallback
270 promoteVariation(i);
273 void GraphicalGame::onUserRemoveVariation(const Index& i) {
274 removeVariation(i);
277 void GraphicalGame::onUserUndo() {
278 if (boost::shared_ptr<UserEntity> entity = m_listener_entity.lock())
279 if (entity->undo())
280 return;
282 // fallback
283 undo();
286 void GraphicalGame::onUserRedo() {
287 if (boost::shared_ptr<UserEntity> entity = m_listener_entity.lock())
288 if (entity->redo())
289 return;
291 // fallback
292 redo();
295 void GraphicalGame::onDetachNotifier() {
296 Q_ASSERT(m_movelist->getNotifier() == static_cast<MoveList::Notifier*>(this));
298 m_movelist = NULL;
301 void GraphicalGame::createCtrlAction() {
302 m_ctrl = boost::shared_ptr<CtrlAction>(new CtrlAction(this));
305 void GraphicalGame::destroyCtrlAction() {
306 m_ctrl.reset();