OSDN Git Service

[denncoCreator] Implementing save functionality. The work is still in progress.
[dennco/denncoCreator.git] / Source / visualizer / eventhandler / dcvterminalfromaxonmodehandler.cpp
1 //  Copyright (c) 2012 Dennco Project
2 //
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 //
17 //  Created by tkawata on Sep-30, 2012.
18 //
19 #include "dcvterminalfromaxonmodehandler.h"
20
21 #include "dcglvisualizerwidget.h"
22 #include "dcvcomponent.h"
23 #include "dcvcpage.h"
24 #include "dcscene.h"
25 #include "dccreator.h"
26 #include "dcglwidget.h"
27
28 #include "dccell.h"
29 #include "dcaxon.h"
30 #include "dcvceditmodecursor.h"
31
32
33 DCVTerminalFromAxonModeHandler::DCVTerminalFromAxonModeHandler(DCUIGraphicsScene *widget, DCCreator *creator, DCScene *scene, DCAxon *editAxon, DCVCEditModeCursor *cursor) :
34     DCVEventHandler(widget, creator, scene), d_draggedObject(NULL), d_inResigingDrag(false), d_editAxon(editAxon), d_cursor(cursor)
35 {
36     switch(getScene()->getEditMode())
37     {
38     case DCScene::DCV_EDITMODE_TERMINAL_FROM_AXON:
39         d_mode = TERMINAL_FROM_AXON;
40         break;
41     case DCScene::DCV_EDITMODE_TERMINAL_FROM_RECEPTOR:
42         d_mode = TERMINAL_FROM_RECEPTOR;
43         break;
44     default:
45         Q_ASSERT(0);
46     }
47 }
48
49 DCVTerminalFromAxonModeHandler::~DCVTerminalFromAxonModeHandler()
50 {
51     d_cursor->setDropTarget(NULL);
52 }
53
54 int DCVTerminalFromAxonModeHandler::getHandlerType() const
55 {
56     if (d_mode == TERMINAL_FROM_AXON)
57     {
58         return DCScene::DCV_EDITMODE_TERMINAL_FROM_AXON;
59     }
60     else
61     {
62         return DCScene::DCV_EDITMODE_TERMINAL_FROM_RECEPTOR;
63     }
64 }
65
66 void DCVTerminalFromAxonModeHandler::mousePressEvent(QGraphicsSceneMouseEvent *event)
67 {
68     bool shift = event->modifiers() & Qt::ShiftModifier;
69
70     QPointF mousePos = event->scenePos();
71
72     DCVComponent *obj = getView()->getObjectAt(mousePos.x(), mousePos.y(), d_cursor);
73     if (!obj)
74         return;
75
76     DCVCPage *page = dynamic_cast<DCVCPage*>(obj->getPageBelonging());
77     if (!page)
78         return;
79
80     if (obj !=  getScene()->getTerminalEditCursor() && obj != page)
81             return;
82
83     switch(getScene()->getPersMode())
84     {
85     case DCScene::DCV_PERSMODE_NAVIGATION:
86         {
87             if (obj != page)
88             {
89                 getController()->selectPage(this, page, shift);
90                 if (obj->getIsSelectable())
91                 {
92                     float pageX, pageZ;
93                     getView()->toObjectCoordinateXZ(mousePos.x(), mousePos.y(), page, &pageX, &pageZ);
94                     if (obj->startDrag(pageX, 0, pageZ, false))
95                     {
96                         getScene()->updateVisiblity();
97                         getView()->requestRedraw(true);
98                         d_draggedObject = obj;
99                         d_inResigingDrag = false;
100                     }
101                 }
102             }
103             else
104             {
105                 d_draggedObject = obj;
106                 d_inResigingDrag = false;
107             }
108         }
109         break;
110
111     case DCScene::DCV_PERSMODE_PAGEEDIT:
112         {
113             float pageX, pageZ;
114             getView()->toObjectCoordinateXZ(mousePos.x(), mousePos.y(), page, &pageX, &pageZ);
115             if (obj->startDrag(pageX, 0, pageZ, false))
116             {
117                 getScene()->updateVisiblity();
118                 getView()->requestRedraw(true);
119             }
120             d_draggedObject = obj;
121             d_inResigingDrag = false;
122         }
123         break;
124     }
125
126     event->accept();
127 }
128
129 void DCVTerminalFromAxonModeHandler::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
130 {
131     DCVComponent *obj = d_draggedObject;
132
133     if (!obj)
134         return;
135
136     DCVComponent *page = obj->getPageBelonging();
137     if (!page)
138         return;
139
140     switch(getScene()->getPersMode())
141     {
142     case DCScene::DCV_PERSMODE_NAVIGATION:
143         {
144             getController()->changePersMode(this, DCCreator::DC_PERSMODE_PAGEEDIT);
145             d_draggedObject = NULL;
146         }
147
148         break;
149
150     case DCScene::DCV_PERSMODE_PAGEEDIT:
151          {
152             if (obj == page)
153             {
154                 getController()->changePersMode(this, DCCreator::DC_PERSMODE_NAVIGATION);
155                 d_draggedObject = NULL;
156             }
157             else if (obj == d_cursor)
158             {
159
160                 getController()->doCommandCancelAddAxonTerminal(this);
161             }
162
163         }
164         break;
165     }
166
167     event->accept();
168 }
169
170 void DCVTerminalFromAxonModeHandler::mouseMoveEvent(QGraphicsSceneMouseEvent *event, int clickTimeElapsed)
171 {
172     QPointF mousePos = event->scenePos();
173     QPointF mousePrevPos = event->lastScenePos();
174
175     // This method will be called continuously while the mouse is moving.
176     // Some process we want to execute here may become heavyer and it will affect the performance.
177     // To privent this to affect the performance, we only execute the potentially heavyer
178     // process 12.5 times in a second in maximum.
179     static int lastCheckTime = 0;
180     bool canProcessHeavyTask = clickTimeElapsed - lastCheckTime < 0 || clickTimeElapsed - lastCheckTime >= 80;
181     if (canProcessHeavyTask)
182         lastCheckTime = clickTimeElapsed;
183
184     if (event->buttons() == Qt::LeftButton)
185     {
186         //dragging
187         bool shift = event->modifiers() & Qt::ShiftModifier;
188         float dx = mousePos.x() - mousePrevPos.x();
189         float dy = mousePos.y() - mousePrevPos.y();
190
191
192         if (canProcessHeavyTask && d_draggedObject && d_draggedObject != d_draggedObject->getPageBelonging())
193         {
194             d_draggedObject->setSelectable(false);
195             DCVComponent *obj = getView()->getObjectAt(mousePos.x(), mousePos.y());
196             d_draggedObject->setSelectable(true);
197
198             if (d_cursor->getDropTarget() && d_cursor->getDropTarget() != obj)
199             {
200                 getController()->unselectCellObject(this, d_cursor->getDropTarget());
201                 getController()->selectCellObject(this, d_editAxon->getOwnerCell()->getVComponent());
202             }
203             if (obj && obj != obj->getPageBelonging() && obj->getPageBelonging() == d_draggedObject->getPageBelonging())
204             {
205                 getController()->selectCellObject(this, obj, true);
206                 d_cursor->setDropTarget(obj);
207             }
208             else
209             {
210                 d_cursor->setDropTarget(NULL);
211             }
212         }
213
214         switch(getScene()->getPersMode())
215         {
216         case DCScene::DCV_PERSMODE_NAVIGATION:
217             if (d_draggedObject && d_draggedObject->getPageBelonging() && d_draggedObject != d_draggedObject->getPageBelonging())
218             {
219                 float pageX, pageZ;
220                 getView()->toObjectCoordinateXZ(mousePos.x(), mousePos.y(), d_draggedObject->getPageBelonging(), &pageX, &pageZ);
221
222                 if (d_draggedObject->dragging(pageX, 0, pageZ, false))
223                 {
224                     DCGLWidget::singleton()->setCursor(Qt::OpenHandCursor);
225                     getView()->requestRedraw(false);
226                 }
227             }
228             else if (!shift)
229             {
230                 getController()->rotateScene(this, dy / 5.0, dx / 5.0);
231             }
232             else
233             {
234                 getController()->translateBrowsModeScene(this, dx, dy);
235             }
236             break;
237
238         case DCScene::DCV_PERSMODE_PAGEEDIT:
239             if (d_draggedObject && d_draggedObject->getPageBelonging())
240             {
241                 if (d_draggedObject == d_draggedObject->getPageBelonging())
242                 {
243                     getController()->translateEditModeScene(this, dx, dy);
244                 }
245                 else
246                 {
247                     float pageX, pageZ;
248                     getView()->toObjectCoordinateXZ(mousePos.x(), mousePos.y(), d_draggedObject->getPageBelonging(), &pageX, &pageZ);
249                     if (d_draggedObject->dragging(pageX, 0, pageZ, false))
250                     {
251                         DCGLWidget::singleton()->setCursor(Qt::OpenHandCursor);
252                         getView()->requestRedraw(false);
253                     }
254                 }
255             }
256             break;
257         }
258     }
259
260     event->accept();
261 }
262
263 void DCVTerminalFromAxonModeHandler::mouseReleaseEvent(QGraphicsSceneMouseEvent *event, bool wasDrag)
264 {
265     bool shift = event->modifiers() & Qt::ShiftModifier;
266     QPointF mousePos = event->scenePos();
267
268     if (d_draggedObject && d_draggedObject->getPageBelonging())
269     {
270         float pageX, pageZ;
271         getView()->toObjectCoordinateXZ(mousePos.x(), mousePos.y(), d_draggedObject->getPageBelonging(), &pageX, &pageZ);
272         d_draggedObject->endDrag(pageX, 0, pageZ, d_inResigingDrag);
273     }
274
275     switch(getScene()->getPersMode())
276     {
277     case DCScene::DCV_PERSMODE_NAVIGATION:
278     {
279         DCVCPage *page = NULL;
280         if (d_draggedObject)
281         {
282             page = d_draggedObject->getPageBelonging();
283         }
284
285         if (wasDrag)
286         {
287             if (d_cursor->getDropTarget())
288             {
289                 getController()->doCommandCommitAddAxonTerminal(this, d_editAxon, d_cursor->getDropTarget()->getOwnerCell());
290             }
291         }
292         else
293         {
294             if (page)
295             {
296                 getController()->selectPage(this, page, shift);
297                 d_cursor->changePageBelonging(page);
298             }
299             else
300             {
301                 getController()->unselectPageAll(this);
302             }
303         }
304     }
305         break;
306
307     case DCScene::DCV_PERSMODE_PAGEEDIT:
308         if (wasDrag)
309         {
310             if (d_cursor->getDropTarget())
311             {
312                 getController()->doCommandCommitAddAxonTerminal(this, d_editAxon, d_cursor->getDropTarget()->getOwnerCell());
313             }
314         }
315
316         break;
317     }
318
319     getScene()->updateVisiblity();
320     getView()->requestRedraw(true);
321     event->accept();
322 }
323
324 void DCVTerminalFromAxonModeHandler::wheelEvent(QGraphicsSceneWheelEvent  *event)
325 {
326     if (event->isAccepted()) return;
327
328     getController()->changeSceneScale(this, getScene()->getScale() + event->delta()/5);
329
330     event->accept();
331 }
332
333 void DCVTerminalFromAxonModeHandler::keyPressEvent(QKeyEvent *event)
334 {
335
336 }
337
338 void DCVTerminalFromAxonModeHandler::keyReleaseEvent(QKeyEvent *event)
339 {
340
341 }
342