Fixed bug when block can slide over the same one
[vexed] / fieldview.cpp
1 #include <QtCore>
2 #include <QtGui>
3 #include <stdio.h>
4
5 #include "playfield.h"
6 #include "fieldview.h"
7
8 FieldView::FieldView(QWidget *parent) :
9         QWidget(parent)
10 {
11     selX=-1;
12     selY=-1;
13     moving=false;
14     moves=new QList<Animation*>();
15     playField=0;
16     solutionTimer=0;
17     inSolution=false;
18 }
19
20 void FieldView::mousePressEvent(QMouseEvent *event)
21 {
22     QPoint sel=cell(event->pos());
23
24     selX=sel.x();
25     selY=sel.y();
26     moveX=-1;
27     moveY=-1;
28     moving=true;
29     update();
30 }
31
32 void FieldView::mouseReleaseEvent(QMouseEvent *event)
33 {
34     if(moving)
35     {
36         moving=false;
37         QPoint mov=cell(event->pos());
38         moveX=mov.x();
39         moveY=mov.y();
40         if(moveX==selX && moveY==selY)
41         {
42             moveX=-1;
43             return;
44         }
45     }
46     move(selX,selY,moveX);
47 }
48
49 void FieldView::move(int x, int y, int dest_x)
50 {
51     delete moves;
52     moves=new QList<Animation*>();
53     playField->move(x, y, dest_x);
54     playMoves();
55     emit updateMoves(playField->moves);
56 }
57
58 PlayField* FieldView::setPlayField(PlayField *pf)
59 {
60         if(playField)
61         {
62                 delete playField;
63         }
64         playField = new PlayField(pf);
65         QObject::connect(playField,SIGNAL(cellMoved(int,int,int,int)),this,SLOT(cellMoved(int,int,int,int)));
66         QObject::connect(playField,SIGNAL(cellGone(int,int)),this,SLOT(cellGone(int,int)));
67
68         updateWidgets();
69         show();
70         emit updateMoves(playField->moves);
71         return playField;
72 }
73
74 void FieldView::cellMoved(int w, int h, int wnew, int hnew)
75 {
76         QRect c=coo(w,h);
77         QRect cnew=coo(wnew,hnew);
78         moves->append(new Move(c,cnew));
79 }
80 void FieldView::cellGone(int w, int h)
81 {
82         QRect c=coo(w,h);
83         moves->append(new Hide(c));
84 }
85 QWidget* FieldView::cellWidget(int w, int h)
86 {
87         return childAt(coo(w,h).topLeft());
88 }
89 void FieldView::playMove()
90 {
91         if(moves->size()>0)
92         {
93                 Animation *move=moves->at(0);
94                 QWidget *item=childAt(move->src.topLeft());
95                 if(!item)
96                 {
97                         QPoint p=cell(move->src.left(),move->src.top());
98                 }
99                 QPropertyAnimation *a=move->getAnimation(item);
100                 moves->removeAt(0);
101                 connect(a,SIGNAL(finished()),this,SLOT(playMove()));
102                 a->start();
103                 delete move;
104         } else
105         {
106             emit animationEnd();
107             if(playField->checkSolved())
108             {
109                 emit solved(playField->moves);
110             }
111         }
112 }
113
114 void FieldView::playMoves()
115 {
116     playMove();
117 }
118
119 void FieldView::undo()
120 {
121     playField->undo();
122     updateWidgets();
123     emit updateMoves(playField->moves);
124 }
125
126 void FieldView::updateWidgets()
127 {
128     QList<QWidget *> childs=findChildren<QWidget *>();
129     QListIterator<QWidget *> childsI(childs);
130     while(childsI.hasNext())
131     {
132         delete childsI.next();
133     }
134
135     for(int w=0;w<PF::FIELD_WIDTH;w++)
136         for(int h=0;h<PF::FIELD_HEIGHT;h++)
137         {
138         QRect r=coo(w,h,0);
139         int cell=playField->get(w,h);
140         QLabel *cellW;
141         switch(cell)
142         {
143                 case PF::CELL_EMPTY:
144             break;
145                 case PF::CELL_WALL:
146             cellW=new QLabel(this);
147             cellW->setPixmap(iconSet.wallIcon());
148             cellW->setGeometry(r);
149             cellW->setFrameStyle(QFrame::NoFrame);
150             cellW->show();
151             break;
152                 default:
153             cellW=new QLabel(this);
154             cellW->setPixmap(iconSet.icon(cell-2));
155             cellW->setGeometry(r);
156             cellW->setFrameStyle(QFrame::NoFrame);
157             cellW->show();
158         }
159     }
160 }
161
162
163 // level should be resetted to show solution!
164 // create new widget
165 void FieldView::showSolution()
166 {
167     stop();
168     inSolution=true;
169     solutionMove=0;
170     solutionTimer=new QTimer(this);
171     solutionTimer->setInterval(500);
172     solutionTimer->setSingleShot(true);
173     connect(this,SIGNAL(animationEnd()),solutionTimer,SLOT(start()));
174     connect(solutionTimer,SIGNAL(timeout()),this,SLOT(playSolutionMove()));
175     playSolutionMove();
176 }
177
178 void FieldView::stop()
179 {
180     if(solutionTimer!=0)
181     {
182         disconnect(this,SIGNAL(animationEnd()),solutionTimer,SLOT(start()));
183         solutionTimer->stop();
184         delete solutionTimer;
185         solutionTimer=0;
186     }
187 }
188
189 void FieldView::playSolutionMove()
190 {
191     if(solutionMove >= playField->solution.size() / 2)
192     {
193         //disconnect(solutionTimer,SIGNAL(timeout()),this,SLOT(playSolutionMove()));
194         //connect(solutionTimer,SIGNAL(timeout()),this,SLOT(stop()));
195         puts("no more. stop");
196         stop();
197     } else
198     {
199         // drawn from original
200         char chX=playField->solution.at(solutionMove * 2).toAscii();
201         char chY=playField->solution.at(solutionMove * 2 + 1).toAscii();
202
203         int x=chX-'a';
204         int dest_x=x+1;
205         if( chX<='Z')
206         {
207             x = chX-'A';
208             dest_x=x-1;
209         }
210
211         int y=chY-'a';
212         if(chY<='Z'){
213             y=chY-'A';
214             dest_x=x+1;
215         }
216
217         solutionMove++;
218         move(x,y,dest_x);
219     }
220 }