1 #include "studiox_includes.h"
2
3 ///////////////////////////////////////////////////////////////////////////////
action_info()4 action_info::action_info()
5 {
6 action_type = 0;
7 action_name = "";
8 target_widget_name = "";
9 parent_widget_name = "";
10 animation_id_name = "";
11 target_show_child_widgets = FALSE;
12 parent_show_child_widgets = FALSE;
13 animation = NULL;
14 }
15
16 ///////////////////////////////////////////////////////////////////////////////
action_info(const action_info & other)17 action_info::action_info(const action_info &other)
18 {
19 copy(other);
20 }
21
22 ///////////////////////////////////////////////////////////////////////////////
~action_info()23 action_info::~action_info()
24 {
25 if (animation)
26 {
27 delete animation;
28 }
29 }
30
31 ///////////////////////////////////////////////////////////////////////////////
operator =(const action_info & other)32 action_info &action_info::operator=(const action_info &other)
33 {
34 copy(other);
35 return *this;
36 }
37
38 ///////////////////////////////////////////////////////////////////////////////
copy(const action_info & other)39 void action_info::copy(const action_info &other)
40 {
41 action_type = other.action_type;
42 action_name = other.action_name;
43 target_widget_name = other.target_widget_name;
44 parent_widget_name = other.parent_widget_name;
45 animation_id_name = other.animation_id_name;
46 target_show_child_widgets = other.target_show_child_widgets;
47 parent_show_child_widgets = other.parent_show_child_widgets;
48
49 if (other.animation)
50 {
51 animation = new GX_ANIMATION_INFO;
52 (*animation) = (*other.animation);
53 }
54 else
55 {
56 animation = NULL;
57 }
58 }
59
60 ///////////////////////////////////////////////////////////////////////////////
RemoveAnimationIdFromDictionary(int display_index)61 void action_info::RemoveAnimationIdFromDictionary(int display_index)
62 {
63 if (!animation_id_name.IsEmpty())
64 {
65 studiox_project *project = GetOpenProject();
66 if (project)
67 {
68 project->RemoveFromIdDictionary(display_index, ID_TYPE_ANIMATION, animation_id_name);
69 }
70 }
71 }
72
73 ///////////////////////////////////////////////////////////////////////////////
AddAnimationIdToDictionary(int display_index)74 void action_info::AddAnimationIdToDictionary(int display_index)
75 {
76 if (!animation_id_name.IsEmpty())
77 {
78 studiox_project *project = GetOpenProject();
79 if (project)
80 {
81 project->AddToIdDictionary(display_index, ID_TYPE_ANIMATION, animation_id_name);
82 }
83 }
84 }
85
86 ///////////////////////////////////////////////////////////////////////////////
trigger_info()87 trigger_info::trigger_info()
88 {
89 trigger_name = "";
90 system_event_animat_id_name = "";
91 signal_id_name = "";
92 user_event_id_name = "";
93 trigger_type = 0;
94 event_type = 0;
95 action_list.RemoveAll();
96 next = NULL;
97 }
98
99 ///////////////////////////////////////////////////////////////////////////////
trigger_info(const trigger_info & other)100 trigger_info::trigger_info(const trigger_info &other)
101 {
102 copy(other);
103 }
104
105 ///////////////////////////////////////////////////////////////////////////////
~trigger_info()106 trigger_info::~trigger_info()
107 {
108 trigger_info *test;
109 trigger_info *temp;
110
111 CleanActionList(action_list);
112
113 test = next;
114 while (test)
115 {
116 temp = test->next;
117 test->next = NULL;
118 delete test;
119 test = temp;
120 }
121 }
122
123 ///////////////////////////////////////////////////////////////////////////////
operator =(const trigger_info & other)124 trigger_info &trigger_info::operator=(const trigger_info &other)
125 {
126 copy(other);
127 return *this;
128 }
129
130 ///////////////////////////////////////////////////////////////////////////////
MergeActionInfo(trigger_info * add_trigger)131 void trigger_info::MergeActionInfo(trigger_info *add_trigger)
132 {
133 if (!add_trigger)
134 {
135 return;
136 }
137
138 CArray<action_info *> *add_action_list = &add_trigger->action_list;
139 action_info *add_action;
140
141 for (int index = 0; index < add_action_list->GetCount(); index++)
142 {
143 add_action = add_action_list->GetAt(index);
144
145 if (FindActionName(action_list, add_action->action_name))
146 {
147 CreateUniqueActionName(action_list, add_action);
148 }
149
150 action_list.Add(add_action);
151 }
152
153 add_action_list->RemoveAll();
154 }
155
156 ///////////////////////////////////////////////////////////////////////////////
GetActionInfo(CArray<action_info * > & ActionList,CString & action_name)157 action_info *trigger_info::GetActionInfo(CArray<action_info *> &ActionList, CString &action_name)
158 {
159 action_info *action;
160
161 for (int index = 0; index < ActionList.GetCount(); index++)
162 {
163 action = ActionList.GetAt(index);
164
165 if (action->action_name == action_name)
166 {
167 return action;
168 }
169 }
170
171 return NULL;
172 }
173
174 ///////////////////////////////////////////////////////////////////////////////
FindActionName(CArray<action_info * > & ActionList,CString & name)175 BOOL trigger_info::FindActionName(CArray<action_info *> &ActionList, CString &name)
176 {
177 action_info *action;
178 for (int index = 0; index < ActionList.GetCount(); index++)
179 {
180 action = ActionList.GetAt(index);
181
182 if (action->action_name == name)
183 {
184 return TRUE;
185 }
186 }
187
188 return FALSE;
189 }
190
191 ///////////////////////////////////////////////////////////////////////////////
CreateUniqueActionName(CArray<action_info * > & ActionList,action_info * action)192 void trigger_info::CreateUniqueActionName(CArray<action_info *> &ActionList, action_info *action)
193 {
194 if (!FindActionName(ActionList, action->action_name))
195 {
196 return;
197 }
198
199 CString base = action->action_name;
200 CString out;
201 int index = 1;
202
203
204 out.Format(_T("%s_%d"), base, index);
205 while (FindActionName(ActionList, out))
206 {
207 index++;
208 out.Format(_T("%s_%d"), base, index);
209 }
210
211 action->action_name = out;
212 }
213
214 ///////////////////////////////////////////////////////////////////////////////
CleanActionList(CArray<action_info * > & list)215 void trigger_info::CleanActionList(CArray<action_info *> &list)
216 {
217 for (int index = 0; index < list.GetCount(); index++)
218 {
219 delete list.GetAt(index);
220 }
221 list.RemoveAll();
222 }
223
224 ///////////////////////////////////////////////////////////////////////////////
copy(const trigger_info & other)225 void trigger_info::copy(const trigger_info &other)
226 {
227 trigger_name = other.trigger_name;
228 trigger_type = other.trigger_type;
229
230 system_event_animat_id_name = other.system_event_animat_id_name;
231 signal_id_name = other.signal_id_name;
232 user_event_id_name = other.user_event_id_name;
233
234 event_type = other.event_type;
235
236 action_info *action;
237
238 for (int index = 0; index < other.action_list.GetCount(); index++)
239 {
240 action = new action_info(*other.action_list.GetAt(index));
241
242 action_list.Add(action);
243 }
244
245 next = NULL;
246 }
247
248 ///////////////////////////////////////////////////////////////////////////////
RemoveAnimationIdFromDictionary(int display_index)249 void trigger_info::RemoveAnimationIdFromDictionary(int display_index)
250 {
251 action_info *action;
252
253 for (int index = 0; index < action_list.GetCount(); index++)
254 {
255 action = action_list.GetAt(index);
256 action->RemoveAnimationIdFromDictionary(display_index);
257 }
258 }
259
260 ///////////////////////////////////////////////////////////////////////////////
AddAnimationIdToDictionary(int display_index)261 void trigger_info::AddAnimationIdToDictionary(int display_index)
262 {
263 action_info *action;
264
265 for (int index = 0; index < action_list.GetCount(); index++)
266 {
267 action = action_list.GetAt(index);
268 action->AddAnimationIdToDictionary(display_index);
269 }
270 }
271
272 ///////////////////////////////////////////////////////////////////////////////
flow_item()273 flow_item::flow_item()
274 {
275 screen_name = "";
276 rect = CRect(0, 0, 0, 0);
277 trigger_list = NULL;
278 enabled = TRUE;
279 }
280
281 ///////////////////////////////////////////////////////////////////////////////
flow_item(const flow_item & other)282 flow_item::flow_item(const flow_item &other)
283 {
284 copy(other);
285 }
286
287 ///////////////////////////////////////////////////////////////////////////////
~flow_item()288 flow_item::~flow_item()
289 {
290 if (trigger_list)
291 {
292 delete trigger_list;
293 }
294 }
295
296 ///////////////////////////////////////////////////////////////////////////////
operator =(const flow_item & other)297 flow_item &flow_item::operator=(const flow_item &other)
298 {
299 copy(other);
300 return *this;
301 }
302
303 ///////////////////////////////////////////////////////////////////////////////
copy(const flow_item & other)304 void flow_item::copy(const flow_item &other)
305 {
306 screen_name = other.screen_name;
307 rect = other.rect;
308 enabled = other.enabled;
309 trigger_list = NULL;
310 trigger_info *trigger;
311 trigger_info *pre = NULL;
312 trigger_info *copy;
313
314 copy = other.trigger_list;
315
316 while (copy)
317 {
318 trigger = new trigger_info(*copy);
319
320 if (pre)
321 {
322 pre->next = trigger;
323 }
324 else
325 {
326 trigger_list = trigger;
327 }
328
329 pre = trigger;
330
331 copy = copy->next;
332 }
333 }
334
335 ///////////////////////////////////////////////////////////////////////////////
RemovedAnimationIdFromDictionary(int display_index)336 void flow_item::RemovedAnimationIdFromDictionary(int display_index)
337 {
338 trigger_info *trigger = trigger_list;
339
340 while (trigger)
341 {
342 trigger->RemoveAnimationIdFromDictionary(display_index);
343 trigger = trigger->next;
344 }
345 }
346
347 ///////////////////////////////////////////////////////////////////////////////
AddAnimationIdToDictionary(int display_index)348 void flow_item::AddAnimationIdToDictionary(int display_index)
349 {
350 trigger_info *trigger = trigger_list;
351
352 while (trigger)
353 {
354 trigger->AddAnimationIdToDictionary(display_index);
355 trigger = trigger->next;
356 }
357 }
358
359 ///////////////////////////////////////////////////////////////////////////////
screen_flow()360 screen_flow::screen_flow()
361 {
362 flow_list.RemoveAll();
363
364 mDiagramScale = 100;
365
366 int dpi = GetSystemDPI();
367 mScale = MulDiv(mDiagramScale, dpi, DEFAULT_DPI_96);
368 }
369
370 ///////////////////////////////////////////////////////////////////////////////
screen_flow(const screen_flow & other)371 screen_flow::screen_flow(const screen_flow &other)
372 {
373 flow_item *item;
374
375 for (int index = 0; index < other.flow_list.GetCount(); index++)
376 {
377 item = new flow_item(*other.flow_list.GetAt(index));
378 flow_list.Add(item);
379 }
380
381 mScale = other.mScale;
382 mDiagramScale = other.mDiagramScale;
383 }
384
385 ///////////////////////////////////////////////////////////////////////////////
~screen_flow()386 screen_flow::~screen_flow()
387 {
388 flow_item *item;
389
390 for (int index = 0; index < flow_list.GetCount(); index++)
391 {
392 item = flow_list.GetAt(index);
393 delete item;
394 }
395
396 flow_list.RemoveAll();
397 }
398
399 ///////////////////////////////////////////////////////////////////////////////
UpdateScreenName(CString screen_name,CString new_name)400 void screen_flow::UpdateScreenName(CString screen_name, CString new_name)
401 {
402 flow_item *item;
403 trigger_info *trigger;
404 CArray<action_info *> *action_list;
405
406 for (int index = 0; index < GetFlowListCount(); index++)
407 {
408 item = GetFlowItem(index);
409
410 if (item->screen_name == screen_name)
411 {
412 item->screen_name = new_name;
413 }
414
415 trigger = item->trigger_list;
416 while (trigger)
417 {
418 action_list = &trigger->action_list;
419 for (int count = 0; count < action_list->GetCount(); count++)
420 {
421 if (action_list->GetAt(count)->target_widget_name == screen_name)
422 {
423 action_list->GetAt(count)->target_widget_name = new_name;
424 }
425 }
426
427 trigger = trigger->next;
428 }
429 }
430 }
431
432 ///////////////////////////////////////////////////////////////////////////////
UpdateIdName(widget_info * info,CString old_id_name,CString new_name)433 void screen_flow::UpdateIdName(widget_info *info, CString old_id_name, CString new_name)
434 {
435 flow_item *item;
436 trigger_info *trigger;
437 widget_info *screen_info = NULL;
438
439 studiox_project *project = GetOpenProject();
440
441 screen_info = GetProjectView()->FindTopLevelWidget(info);
442
443 if ((!screen_info) || !project || new_name.IsEmpty())
444 {
445 return;
446 }
447
448 item = GetFlowItem(screen_info->app_name);
449
450 if (item)
451 {
452 trigger = item->trigger_list;
453 CString trigger_name;
454 int pos;
455
456 while (trigger)
457 {
458 if (trigger->signal_id_name == old_id_name)
459 {
460 trigger->signal_id_name = new_name;
461
462 //update trigger name
463 pos = trigger->trigger_name.Find('(');
464 trigger_name = trigger->trigger_name.Left(pos + 1);
465 trigger_name.Append(new_name.MakeLower());
466 pos = trigger->trigger_name.Find(',');
467 trigger_name.Append(trigger->trigger_name.Mid(pos));
468
469 trigger->trigger_name = trigger_name;
470 }
471 trigger = trigger->next;
472 }
473 }
474 }
475
476 ///////////////////////////////////////////////////////////////////////////////
CheckAddFlowItem(CString screen_name,int diagram_width,int diagram_height)477 void screen_flow::CheckAddFlowItem(CString screen_name, int diagram_width, int diagram_height)
478 {
479 flow_item *item = GetFlowItem(screen_name);
480
481 if (item)
482 {
483 // test invalid screen box size
484 if (item->rect.right < item->rect.left + 10)
485 {
486 item->rect.right = item->rect.left + 10;
487 }
488 if (item->rect.bottom < item->rect.top + 10)
489 {
490 item->rect.bottom = item->rect.top + 10;
491 }
492 }
493 else
494 {
495 flow_item *info = new flow_item;
496 CRect rect;
497 rect.SetRectEmpty();
498 InitFlowItemRect(rect, diagram_width, diagram_height);
499
500 info->screen_name = screen_name;
501 info->trigger_list = NULL;
502 info->rect.CopyRect(rect);
503 flow_list.Add(info);
504 }
505 }
506
507 ///////////////////////////////////////////////////////////////////////////////
DeleteFlowItem(CString & screen_name,int display_index)508 void screen_flow::DeleteFlowItem(CString &screen_name, int display_index)
509 {
510 flow_item *item;
511 trigger_info *trigger;
512 trigger_info *pre;
513 CArray<action_info *> *action_list;
514 int count;
515
516 //remove flow item
517 int index = GetFlowItemIndex(screen_name);
518 if (index >= 0 && index < GetFlowListCount())
519 {
520 item = GetFlowItem(index);
521 item->RemovedAnimationIdFromDictionary(display_index);
522 delete item;
523 flow_list.RemoveAt(index);
524 }
525
526 for (index = 0; index < GetFlowListCount(); index++)
527 {
528 item = GetFlowItem(index);
529 trigger = item->trigger_list;
530 pre = NULL;
531
532 while (trigger)
533 {
534 action_list = &trigger->action_list;
535
536 //remove actions that target to the delete screen
537 count = 0;
538 while(count < action_list->GetCount())
539 {
540 if (action_list->GetAt(count)->target_widget_name == screen_name)
541 {
542 delete action_list->GetAt(count);
543 action_list->RemoveAt(count);
544 }
545 else
546 {
547 count++;
548 }
549 }
550
551 //if no action exist, delete the trigger
552 if (action_list->GetCount() == 0)
553 {
554 if (pre)
555 {
556 pre->next = trigger->next;
557 }
558 else
559 {
560 item->trigger_list = trigger->next;
561 }
562 trigger->next = NULL;
563 delete trigger;
564
565 if (pre)
566 {
567 trigger = pre->next;
568 }
569 else
570 {
571 trigger = item->trigger_list;
572 }
573 }
574 else
575 {
576 pre = trigger;
577 trigger = trigger->next;
578 }
579 }
580 }
581 }
582
583 ///////////////////////////////////////////////////////////////////////////////
GetFlowItem(CPoint point,BOOL move_front)584 flow_item *screen_flow::GetFlowItem(CPoint point, BOOL move_front)
585 {
586 flow_item *info;
587
588 point.x = point.x * 100 / mScale;
589 point.y = point.y * 100 / mScale;
590
591 for (int index = flow_list.GetCount() - 1; index >= 0; index--)
592 {
593 info = flow_list.GetAt(index);
594
595 if (info->enabled && info->rect.PtInRect(point))
596 {
597 if (move_front)
598 {
599 flow_list.RemoveAt(index);
600 flow_list.Add(info);
601 }
602 return info;
603 }
604 }
605
606 return NULL;
607 }
608
609 ///////////////////////////////////////////////////////////////////////////////
GetFlowItem(CString & screen_name)610 flow_item *screen_flow::GetFlowItem(CString &screen_name)
611 {
612 flow_item *info;
613
614 for (int index = 0; index < flow_list.GetCount(); index++)
615 {
616 info = flow_list.GetAt(index);
617
618 if (info->screen_name == screen_name)
619 {
620 return info;
621 }
622 }
623
624 return NULL;
625 }
626
627 ///////////////////////////////////////////////////////////////////////////////
GetFlowItemIndex(CString screen_name)628 int screen_flow::GetFlowItemIndex(CString screen_name)
629 {
630 flow_item *info;
631 for (int index = 0; index < flow_list.GetCount(); index++)
632 {
633 info = flow_list.GetAt(index);
634
635 if (info->screen_name == screen_name)
636 {
637 return index;
638 }
639 }
640
641 return -1;
642 }
643
644 ///////////////////////////////////////////////////////////////////////////////
InitFlowItemRect(CRect & return_rect,int diagram_width,int diagram_heihgt)645 void screen_flow::InitFlowItemRect(CRect &return_rect, int diagram_width, int diagram_heihgt)
646 {
647 int interval_x;
648 int interval_y;
649 int width;
650 int height;
651 CRect new_rect;
652 CRect rect;
653
654 if (return_rect.IsRectEmpty())
655 {
656 interval_x = diagram_heihgt / 4;
657 interval_y = diagram_heihgt / 4;
658 width = (interval_x - 20) * mScale / 100;
659 height = (interval_y - 20) * mScale / 100;
660
661 new_rect = CRect(10, 40, 10 + width - 1, 10 + height - 1);
662 }
663 else
664 {
665 new_rect = return_rect;
666
667 width = new_rect.Width();
668 height = new_rect.Height();
669 interval_x = width + 20;
670 interval_y = height + 20;
671 }
672
673 flow_item *info;
674 BOOL overlap = FALSE;
675
676 while (1)
677 {
678 while (new_rect.left + width < diagram_width)
679 {
680 for (int index = 0; index < flow_list.GetCount(); index++)
681 {
682 info = flow_list.GetAt(index);
683 rect = info->rect;
684 if (info->enabled && rect.IntersectRect(&rect, &new_rect))
685 {
686 overlap = TRUE;
687 break;
688 }
689 }
690
691 if (!overlap)
692 {
693 return_rect = new_rect;
694 return;
695 }
696
697 overlap = FALSE;
698 new_rect.left += interval_x;
699 new_rect.right += interval_x;
700 }
701
702 new_rect.left = 10;
703 new_rect.right = new_rect.left + width;
704 new_rect.top += interval_y;
705 new_rect.bottom += interval_y;
706 }
707
708 return_rect = CRect(10, 40, 10 + width - 1, 10 + height - 1);
709 }
710
711 ///////////////////////////////////////////////////////////////////////////////
UpdateFlowItemRect(flow_item * item,int diagram_width,int diagram_height)712 void screen_flow::UpdateFlowItemRect(flow_item *item, int diagram_width, int diagram_height)
713 {
714 flow_item *info;
715 CRect rect;
716 BOOL overlap = FALSE;
717
718 for (int index = 0; index < flow_list.GetCount(); index++)
719 {
720 info = flow_list.GetAt(index);
721 if (info != item)
722 {
723 rect = info->rect;
724 if (info->enabled && rect.IntersectRect(&rect, &item->rect))
725 {
726 overlap = TRUE;
727 break;
728 }
729 }
730 }
731
732 if (overlap)
733 {
734 rect = item->rect;
735 InitFlowItemRect(rect, diagram_width, diagram_height);
736 item->rect = rect;
737 }
738 }
739
740 ///////////////////////////////////////////////////////////////////////////////
FindTrigger(flow_item * item,CString id_name)741 trigger_info* screen_flow::FindTrigger(flow_item *item, CString id_name)
742 {
743 if (item)
744 {
745 trigger_info *trigger = item->trigger_list;
746 CString trigger_name;
747
748 while (trigger)
749 {
750 if (trigger->signal_id_name == id_name)
751 {
752 return trigger;
753 }
754 trigger = trigger->next;
755 }
756 }
757 return NULL;
758 }
759
760 ///////////////////////////////////////////////////////////////////////////////
RemoveTrigger(flow_item * item,trigger_info * del_trigger)761 void screen_flow::RemoveTrigger(flow_item *item, trigger_info *del_trigger)
762 {
763 trigger_info *trigger = item->trigger_list;
764 trigger_info *pre = NULL;
765
766 while (trigger)
767 {
768 if (trigger == del_trigger)
769 {
770 if (pre)
771 {
772 pre->next = trigger->next;
773 }
774 else
775 {
776 item->trigger_list = trigger->next;
777 }
778
779 trigger->next = NULL;
780 delete trigger;
781 break;
782 }
783
784 pre = trigger;
785 trigger = trigger->next;
786 }
787 }
788
789 ///////////////////////////////////////////////////////////////////////////////
CheckAddTrigger(flow_item * item,trigger_info * add_trigger,CWnd * parent)790 BOOL screen_flow::CheckAddTrigger(flow_item *item, trigger_info *add_trigger, CWnd *parent)
791 {
792 trigger_info *trigger = item->trigger_list;
793 trigger_info *pre = NULL;
794 BOOL Add = TRUE;
795
796 while (trigger)
797 {
798 if (trigger == add_trigger)
799 {
800 Add = FALSE;
801 }
802 else if(trigger->trigger_name == add_trigger->trigger_name)
803 {
804 if (!AskUser("The trigger already exist, do merging?", parent))
805 {
806 return FALSE;
807 }
808 else
809 {
810 trigger->MergeActionInfo(add_trigger);
811 add_trigger->event_type = 0;
812 return TRUE;
813 }
814 }
815 pre = trigger;
816 trigger = trigger->next;
817 }
818
819 if (Add)
820 {
821 if (pre)
822 {
823 pre->next = add_trigger;
824 }
825 else
826 {
827 item->trigger_list = add_trigger;
828 }
829 }
830
831 return TRUE;
832 }
833
SetScale(int scale)834 void screen_flow::SetScale(int scale)
835 {
836 int dpi = GetSystemDPI();
837 mDiagramScale = scale;
838 mScale = MulDiv(scale, dpi, DEFAULT_DPI_96);
839 }
840
841 ///////////////////////////////////////////////////////////////////////////////
RebuildAnimationIdDictionary(int display_index)842 void screen_flow::RebuildAnimationIdDictionary(int display_index)
843 {
844 studiox_project *project = GetOpenProject();
845
846 if (!project)
847 {
848 return;
849 }
850
851 project->CleanupIdDictionary(display_index, ID_TYPE_ANIMATION);
852
853 flow_item *item;
854 for (int index = 0; index < flow_list.GetCount(); index++)
855 {
856 item = flow_list.GetAt(index);
857 item->AddAnimationIdToDictionary(display_index);
858 }
859
860 }
861
862 ///////////////////////////////////////////////////////////////////////////////
IsAnimationIdBeReferenced(CString id_name)863 BOOL screen_flow::IsAnimationIdBeReferenced(CString id_name)
864 {
865 trigger_info *trigger;
866 flow_item *item;
867
868 for (int index = 0; index < flow_list.GetCount(); index++)
869 {
870 item = flow_list.GetAt(index);
871
872 trigger = item->trigger_list;
873 while (trigger)
874 {
875 if ((trigger->event_type == GX_EVENT_ANIMATION_COMPLETE) &&
876 (trigger->system_event_animat_id_name == id_name))
877 {
878 return TRUE;
879 }
880 trigger = trigger->next;
881 }
882 }
883
884 return FALSE;
885 }