1 
2 #include "studiox_includes.h"
3 
4 #ifdef _DEBUG
5 #define new DEBUG_NEW
6 #endif
7 
8 //extern WIDGET_TABLE_ENTRY widget_table[];
9 #define PROVIDER_TABLE_SIZE 64
10 static widget_service_provider *service_providers[PROVIDER_TABLE_SIZE];
11 
12 ///////////////////////////////////////////////////////////////////////////////
widget_factory()13 widget_factory::widget_factory()
14 {
15 }
16 
17 ///////////////////////////////////////////////////////////////////////////////
InitServiceProviders()18 void widget_factory::InitServiceProviders()
19 {
20     memset(service_providers, 0, PROVIDER_TABLE_SIZE * sizeof(widget_service_provider *));
21 
22     int index = 0;
23     service_providers[index] = new widget_service_provider();
24     index++;
25     service_providers[index] = new button_service_provider();
26     index++;
27     service_providers[index] = new text_button_service_provider();
28     index++;
29     service_providers[index] = new mlt_button_service_provider();
30     index++;
31     service_providers[index] = new checkbox_service_provider();
32     index++;
33     service_providers[index] = new radio_button_service_provider();
34     index++;
35     service_providers[index] = new icon_button_service_provider();
36     index++;
37     service_providers[index] = new pixelmap_button_service_provider();
38     index++;
39     service_providers[index] = new icon_service_provider();
40     index++;
41     service_providers[index] = new slider_service_provider();
42     index++;
43     service_providers[index] = new pixelmap_slider_service_provider();
44     index++;
45     service_providers[index] = new progress_bar_service_provider();
46     index++;
47     service_providers[index] = new radial_progress_bar_service_provider();
48     index++;
49     service_providers[index] = new radial_slider_service_provider();
50     index++;
51     service_providers[index] = new sprite_service_provider();
52     index++;
53     service_providers[index] = new prompt_service_provider();
54     index++;
55     service_providers[index] = new numeric_prompt_service_provider();
56     index++;
57     service_providers[index] = new pixelmap_prompt_service_provider();
58     index++;
59     service_providers[index] = new numeric_pixelmap_prompt_service_provider();
60     index++;
61     service_providers[index] = new window_service_provider();
62     index++;
63     service_providers[index] = new vertical_list_service_provider();
64     index++;
65     service_providers[index] = new horizontal_list_service_provider();
66     index++;
67     service_providers[index] = new drop_list_service_provider();
68     index++;
69     service_providers[index] = new scroll_wheel_service_provider();
70     index++;
71     service_providers[index] = new text_scroll_wheel_service_provider();
72     index++;
73     service_providers[index] = new string_scroll_wheel_service_provider();
74     index++;
75     service_providers[index] = new numeric_scroll_wheel_service_provider();
76     index++;
77     service_providers[index] = new text_input_service_provider();
78     index++;
79     service_providers[index] = new ml_text_view_service_provider();
80     index++;
81     service_providers[index] = new ml_text_input_service_provider();
82     index++;
83     service_providers[index] = new hscroll_service_provider();
84     index++;
85     service_providers[index] = new vscroll_service_provider();
86     index++;
87     service_providers[index] = new circular_gauge_service_provider();
88     index++;
89     service_providers[index] = new line_chart_service_provider();
90     index++;
91     service_providers[index] = new template_service_provider();
92     index++;
93     service_providers[index] = new menu_service_provider();
94     index++;
95     service_providers[index] = new accordion_menu_service_provider();
96     index++;
97     service_providers[index] = new tree_view_service_provider();
98     index++;
99     service_providers[index] = new rich_text_view_service_provider();
100     index++;
101     service_providers[index] = new generic_scroll_wheel_service_provider();
102 }
103 
104 ///////////////////////////////////////////////////////////////////////////////
DeleteServiceProviders()105 void widget_factory::DeleteServiceProviders()
106 {
107     int index = 0;
108 
109     for (index = 0; index < PROVIDER_TABLE_SIZE; index++)
110     {
111         if (service_providers[index])
112         {
113             delete service_providers[index];
114             service_providers[index] = NULL;
115         }
116     }
117 }
118 
119 ///////////////////////////////////////////////////////////////////////////////
ResetServiceProviders(int provider_type)120 void widget_factory::ResetServiceProviders(int provider_type)
121 {
122     int index = 0;
123 
124     for (index = 0; index < PROVIDER_TABLE_SIZE; index++)
125     {
126         if (service_providers[index])
127         {
128             if (provider_type >= 0)
129             {
130                 if (service_providers[index]->GetType() == provider_type)
131                 {
132                     service_providers[index]->Reset();
133                     break;
134                 }
135             }
136             else
137             {
138                 service_providers[index]->Reset();
139             }
140         }
141     }
142 }
143 
144 ///////////////////////////////////////////////////////////////////////////////
GetWidgetType(int index)145 int widget_factory::GetWidgetType(int index)
146 {
147     if (index >= 0 && index < PROVIDER_TABLE_SIZE)
148     {
149         if (service_providers[index])
150         {
151             return(service_providers[index]->GetType());
152         }
153     }
154     return 0;
155 }
156 
157 ///////////////////////////////////////////////////////////////////////////////
GetServiceProvider(int type)158 widget_service_provider *widget_factory::GetServiceProvider(int type)
159 {
160     int index = 0;
161 
162     for (index = 0; index < PROVIDER_TABLE_SIZE; index++)
163     {
164         if (service_providers[index])
165         {
166             if (service_providers[index]->GetType() == type)
167             {
168                 return service_providers[index];
169             }
170         }
171         else
172         {
173             break;
174         }
175     }
176     return NULL;
177 }
178 
179 
180 ///////////////////////////////////////////////////////////////////////////////
WidgetTypeToString(int type)181 CString widget_factory::WidgetTypeToString(int type)
182 {
183     widget_service_provider *provider = widget_factory::GetServiceProvider(type);
184     if (provider)
185     {
186         return provider->GetShortName();
187     }
188     return CString("unknown");
189 }
190 
191 ///////////////////////////////////////////////////////////////////////////////
WidgetStringToType(CString & name)192 int widget_factory::WidgetStringToType(CString &name)
193 {
194     int index = 0;
195     widget_service_provider *provider;
196 
197     while(service_providers[index])
198     {
199         provider = service_providers[index];
200         if (name.Compare(provider->GetShortName()) == 0)
201         {
202             return provider->GetType();
203         }
204         index++;
205     }
206     return 0;
207 }
208 
209 ///////////////////////////////////////////////////////////////////////////////
210 #if 0
211 BOOL widget_factory::GenerateWidgets(folder_info *folder, BOOL save_ptrs)
212 {
213     studiox_project *project = GetOpenProject();
214     BOOL status = TRUE;
215     if (!project)
216     {
217         return FALSE;
218     }
219 
220     while (folder)
221     {
222         status |= GenerateWidgets(NULL, folder->GetFirstChildWidget(), save_ptrs);
223         folder = folder->GetNextFolder();
224     }
225 
226     return status;
227 }
228 #endif
229 
230 ///////////////////////////////////////////////////////////////////////////////
GenerateWidgets(GX_WIDGET * parent,widget_info * child,BOOL save_ptrs,BOOL do_siblings)231 BOOL widget_factory::GenerateWidgets(GX_WIDGET *parent, widget_info *child, BOOL save_ptrs, BOOL do_siblings)
232 {
233     BOOL status = TRUE;
234     GX_WIDGET *attach = parent;
235     GX_WIDGET *created;
236     studiox_project *project = GetOpenProject();
237     int display_index;
238     GX_VALUE   list_count = 0;
239     GX_VALUE   list_total_count = 0;
240     GX_WIDGET *list_child;
241 
242     if (!project)
243     {
244         return FALSE;
245     }
246 
247     if (parent)
248     {
249         if ((parent ->gx_widget_type == GX_TYPE_DROP_LIST) && (child->basetype == GX_TYPE_VERTICAL_LIST))
250         {
251             GX_DROP_LIST *drop = (GX_DROP_LIST *) parent;
252             GX_VERTICAL_LIST *list;
253             gx_drop_list_popup_get(drop, &list);
254             attach = (GX_WIDGET *) list;
255         }
256         else if (parent->gx_widget_type == GX_TYPE_MENU)
257         {
258             list_total_count = ((GX_MENU *)parent)->gx_menu_list_total_count;
259 
260             list_child = ((GX_MENU *)parent)->gx_menu_list.gx_widget_first_child;
261             while (list_child)
262             {
263                 list_count++;
264                 list_child = list_child->gx_widget_next;
265             }
266         }
267     }
268 
269     while(child && status)
270     {
271         widget_service_provider *provider = GetServiceProvider(child->basetype);
272 
273         if (provider)
274         {
275             if (list_count < list_total_count)
276             {
277                 created = provider->GenerateFromInfo(GX_NULL, child);
278                 gx_menu_insert((GX_MENU *)attach, created);
279                 ((GX_MENU *)attach)->gx_menu_list_total_count--;
280                 list_count++;
281             }
282             else
283             {
284                 created = provider->GenerateFromInfo(attach, child);
285             }
286 
287             if (!save_ptrs && created)
288             {
289                 if (!child->accepts_focus)
290                 {
291                     gx_widget_status_remove(created, GX_STATUS_ACCEPTS_FOCUS);
292                 }
293 
294                 if (!child->id_name.IsEmpty())
295                 {
296                     //create app screen.
297                     display_index = project->GetDisplayIndex(child);
298 
299                     if (display_index >= 0)
300                     {
301                         created->gx_widget_id = project->GetIdIndex(display_index, ID_TYPE_WIDGET, child->id_name);
302                     }
303                 }
304             }
305 
306             /* If we are creating the widget(s) for the target view, we want to save the widget
307                pointers in the WIDGET_INFO structures. If we are creating the widget(s) for the
308                runtime preview, we just create the widgets and they will be deleted when the
309                application window is closed
310             */
311 
312             if (save_ptrs)
313             {
314                 child->widget = created;
315 
316                 if (created)
317                 {
318                     if (created->gx_widget_type == GX_TYPE_SPRITE)
319                     {
320                         // don't pass auto or loop styles, we don't want the sprite running
321                         // inside the target view
322                         created->gx_widget_style &= ~(GX_STYLE_SPRITE_AUTO|GX_STYLE_SPRITE_LOOP);
323                     }
324                 }
325             }
326         }
327         else
328         {
329             ErrorMsg("Project contains invalid widget type.");
330             status = FALSE;
331         }
332         if (created && child->GetChildWidgetInfo() && status)
333         {
334             GenerateWidgets(created, child->GetChildWidgetInfo(), save_ptrs);
335         }
336 
337         if (do_siblings)
338         {
339             child = child->GetNextWidgetInfo();
340         }
341         else
342         {
343             child = NULL;
344         }
345     }
346     return status;
347 }
348 
349 ///////////////////////////////////////////////////////////////////////////////
GenerateAppScreen(GX_WIDGET * root,widget_info * child)350 GX_WIDGET *widget_factory::GenerateAppScreen(GX_WIDGET *root, widget_info *child)
351 {
352     GX_WIDGET *created = GX_NULL;
353 
354     widget_service_provider *provider = GetServiceProvider(child->basetype);
355     studiox_project *project = GetOpenProject();
356     int display_index;
357 
358     if (!project)
359     {
360         return FALSE;
361     }
362 
363     if (provider)
364     {
365         created = provider->GenerateFromInfo(root, child);
366 
367         if (!child->id_name.IsEmpty() && created)
368         {
369             display_index = project->GetDisplayIndex(child);
370             created->gx_widget_id = project->GetIdIndex(display_index, ID_TYPE_WIDGET, child->id_name);
371         }
372 
373         if (!created)
374         {
375             ErrorMsg("Unable to create application widget instance.");
376         }
377     }
378     else
379     {
380         ErrorMsg("Project contains invalid widget type.");
381     }
382     if (child->GetChildWidgetInfo() && created)
383     {
384         GenerateWidgets(created, child->GetChildWidgetInfo(), FALSE);
385     }
386     return created;
387 }
388 
389 
390 ///////////////////////////////////////////////////////////////////////////////
391 // When a widget is moved, either by dragging it or by typing new values into
392 // the properties window, this function is called to update the widget_info
393 // structures for the moved widget and all of it's children.
394 //////////////////////////////////////////////////////////////////////////////
395 ///////////////////////////////////////////////////////////////////////////////
PositionPopupList(widget_info * info,GX_DROP_LIST * drop)396 void widget_factory::PositionPopupList(widget_info *info, GX_DROP_LIST *drop)
397 {
398     GX_VERTICAL_LIST *list = &drop->gx_drop_list_popup.gx_popup_list_list;
399 
400     GX_RECTANGLE size;
401     size.gx_rectangle_top = drop->gx_widget_size.gx_rectangle_bottom + 1;
402     size.gx_rectangle_bottom = size.gx_rectangle_top + info->ewi.drop_list.open_height - 1;
403     size.gx_rectangle_left = drop ->gx_widget_size.gx_rectangle_left;
404     size.gx_rectangle_right = drop ->gx_widget_size.gx_rectangle_right;
405     gx_widget_resize(list, &size);
406 }
407 
408 ///////////////////////////////////////////////////////////////////////////////
UpdateWidgetInfoPositions(widget_info * info,int xshift,int yshift,BOOL do_next)409 void widget_factory::UpdateWidgetInfoPositions(widget_info *info, int xshift, int yshift, BOOL do_next)
410 {
411     while (info)
412     {
413         if (info->basetype == GX_TYPE_DROP_LIST)
414         {
415             if (info->widget)
416             {
417                 GX_DROP_LIST *list = (GX_DROP_LIST *) info->widget;
418                 PositionPopupList(info, list);
419             }
420         }
421         info->size.gx_rectangle_left += xshift;
422         info->size.gx_rectangle_right += xshift;
423         info->size.gx_rectangle_top += yshift;
424         info->size.gx_rectangle_bottom += yshift;
425 
426         //info->size = info->widget->gx_widget_size;
427 
428         if (info->GetChildWidgetInfo())
429         {
430             UpdateWidgetInfoPositions(info->GetChildWidgetInfo(), xshift, yshift, TRUE);
431         }
432 
433         if (do_next)
434         {
435             info = info->GetNextWidgetInfo();
436         }
437         else
438         {
439             break;
440         }
441     }
442 }
443 
444 ///////////////////////////////////////////////////////////////////////////////
MoveWidget(widget_info * info,GX_RECTANGLE & size)445 void widget_factory::MoveWidget(widget_info *info, GX_RECTANGLE &size)
446 {
447     int width;
448     int height;
449     int xshift;
450     int yshift;
451 
452     if (info->basetype == GX_TYPE_TEMPLATE)
453     {
454         int new_width = size.gx_rectangle_right - size.gx_rectangle_left + 1;
455         int new_height = size.gx_rectangle_bottom - size.gx_rectangle_top + 1;
456         width = info->size.gx_rectangle_right - info->size.gx_rectangle_left + 1;
457         height = info->size.gx_rectangle_bottom - info->size.gx_rectangle_top + 1;
458 
459         if ((new_width != width) || (new_height != height))
460         {
461             Notify("This widget is derived from a template, to resize the widget you must resize the template on which this widget is based.");
462             return;
463         }
464     }
465     if (info->widget)
466     {
467         gx_widget_resize(info->widget, &size);
468     }
469 
470     xshift = size.gx_rectangle_left - info->size.gx_rectangle_left;
471     yshift = size.gx_rectangle_top - info->size.gx_rectangle_top;
472     info->size = size;
473 
474     if (info->basetype == GX_TYPE_RADIAL_PROGRESS_BAR)
475     {
476         info->ewi.radial_progress = ((GX_RADIAL_PROGRESS_BAR *)info->widget)->gx_radial_progress_bar_info;
477     }
478 
479     if (xshift || yshift)
480     {
481         if (info->GetChildWidgetInfo())
482         {
483             UpdateWidgetInfoPositions(info->GetChildWidgetInfo(), xshift, yshift, TRUE);
484         }
485     }
486 }
487 
488 ///////////////////////////////////////////////////////////////////////////////
DeleteWidgets(GX_WIDGET * start)489 void widget_factory::DeleteWidgets(GX_WIDGET *start)
490 {
491     GX_WIDGET *next;
492     GX_MENU_LIST *list;
493 
494     while (start)
495     {
496         if (start->gx_widget_type == GX_TYPE_MENU_LIST)
497         {
498             /* Skip menu list type widgets. */
499             start = start->gx_widget_next;
500             continue;
501         }
502 
503         next = start->gx_widget_next;
504         while (next && next->gx_widget_type == GX_TYPE_MENU_LIST)
505         {
506             /* Skip menu list type widgets. */
507             next = next->gx_widget_next;
508         }
509 
510         if (start->gx_widget_first_child)
511         {
512             if (start->gx_widget_type != GX_TYPE_HORIZONTAL_SCROLL &&
513                 start->gx_widget_type != GX_TYPE_VERTICAL_SCROLL)
514             {
515                 DeleteWidgets(start->gx_widget_first_child);
516             }
517         }
518 
519         if (start->gx_widget_type == GX_TYPE_MENU)
520         {
521             /* Delete menu list of menu widget. */
522             list = &((GX_MENU *)start)->gx_menu_list;
523             if (list->gx_widget_first_child)
524             {
525                 DeleteWidgets(list->gx_widget_first_child);
526             }
527         }
528 
529         DeleteOneWidget(start);
530         start = next;
531     }
532 }
533 
534 ///////////////////////////////////////////////////////////////////////////////
DeleteOneWidget(GX_WIDGET * widget)535 void widget_factory::DeleteOneWidget(GX_WIDGET *widget)
536 {
537     if (!widget)
538     {
539         return;
540     }
541 
542     GX_WIDGET *parent = widget->gx_widget_parent;
543 
544     if (parent && parent->gx_widget_type == GX_TYPE_MENU_LIST)
545     {
546         parent = ((GX_MENU_LIST *)parent)->gx_menu_list_owner;
547         gx_menu_remove((GX_MENU *)parent, widget);
548     }
549 
550     // for the text input widget types, check to see if
551     // we need to delete the text buffer:
552 
553     switch(widget->gx_widget_type)
554     {
555     case GX_TYPE_DROP_LIST:
556         {
557         GX_DROP_LIST *drop = (GX_DROP_LIST *) widget;
558         gx_widget_delete(&drop->gx_drop_list_popup.gx_popup_list_list);
559         }
560         break;
561 
562     case GX_TYPE_MENU:
563         {
564             GX_MENU *menu = (GX_MENU *)widget;
565             gx_widget_delete(&menu->gx_menu_list);
566         }
567         break;
568 
569     case GX_TYPE_SINGLE_LINE_TEXT_INPUT:
570         {
571         GX_SINGLE_LINE_TEXT_INPUT *pi = (GX_SINGLE_LINE_TEXT_INPUT *) widget;
572         if (pi->gx_single_line_text_input_buffer)
573         {
574             delete [] pi->gx_single_line_text_input_buffer;
575             pi->gx_single_line_text_input_buffer = NULL;
576         }
577         }
578         break;
579 
580     case GX_TYPE_MULTI_LINE_TEXT_INPUT:
581         {
582         GX_MULTI_LINE_TEXT_INPUT *mi = (GX_MULTI_LINE_TEXT_INPUT *) widget;
583         if (mi->gx_multi_line_text_view_text.gx_string_ptr)
584         {
585             delete [] mi->gx_multi_line_text_view_text.gx_string_ptr;
586             mi->gx_multi_line_text_view_text.gx_string_ptr = NULL;
587             mi->gx_multi_line_text_view_text.gx_string_length = 0;
588         }
589         }
590         break;
591 
592     default:
593         break;
594     }
595 
596     gx_widget_delete(widget);
597     delete widget;
598 }
599 
600 ///////////////////////////////////////////////////////////////////////////////
CleanupWidgets(folder_info * start)601 void widget_factory::CleanupWidgets(folder_info *start)
602 {
603     while (start)
604     {
605         if (start->GetFirstChildWidget())
606         {
607             CleanupWidgets(start->GetFirstChildWidget(), TRUE, TRUE);
608         }
609         start = start->GetNextFolder();
610     }
611 }
612 
613 ///////////////////////////////////////////////////////////////////////////////
CleanupWidgets(widget_info * start,BOOL recursive,BOOL do_siblings)614 void widget_factory::CleanupWidgets(widget_info *start, BOOL recursive, BOOL do_siblings)
615 {
616     GX_WIDGET *template_child;
617 
618     while(start)
619     {
620         if (recursive && start->GetChildWidgetInfo())
621         {
622             CleanupWidgets(start->GetChildWidgetInfo(), TRUE, TRUE);
623         }
624 
625         if (start->basetype == GX_TYPE_TEMPLATE)
626         {
627             /* We delete the widget_info structures and associated GX_WIDGETs "bottom_up",
628                meaning we delete the child widget_info before deleting the parent. So if we
629                get to this stage a template widget still has chidren, those children do not
630                have their own widget_info, they were created as part of creating a template
631                instance. Delete them here.
632             */
633 
634             if (start->widget)
635             {
636                 while(start->widget->gx_widget_first_child)
637                 {
638                     template_child = start->widget->gx_widget_first_child;
639                     DeleteWidgets(template_child);
640                 }
641             }
642         }
643 
644         if (start->widget)
645         {
646             DeleteOneWidget(start->widget);
647             start->widget = NULL;
648         }
649         if (do_siblings)
650         {
651             start = start->GetNextWidgetInfo();
652         }
653         else
654         {
655             break;
656         }
657     }
658 }
659 
660 
661 ///////////////////////////////////////////////////////////////////////////////
FindAppName(widget_info * start,widget_info * find,BOOL search_child)662 BOOL widget_factory::FindAppName(widget_info *start, widget_info *find, BOOL search_child)
663 {
664     while(start)
665     {
666         if ((find != start) &&
667             (find->app_name == start->app_name))
668         {
669             return TRUE;
670         }
671         if (search_child && start->GetChildWidgetInfo())
672         {
673             if (FindAppName(start->GetChildWidgetInfo(), find, search_child))
674             {
675                 return TRUE;
676             }
677         }
678         start = start->GetNextWidgetInfo();
679     }
680     return FALSE;
681 }
682 
683 ///////////////////////////////////////////////////////////////////////////////
FindAppName(widget_info * start,CString & find_name,BOOL search_child)684 BOOL widget_factory::FindAppName(widget_info *start, CString &find_name, BOOL search_child)
685 {
686     while (start)
687     {
688         if (find_name == start->app_name)
689         {
690             return TRUE;
691         }
692         if (search_child && start->GetChildWidgetInfo())
693         {
694             if (FindAppName(start->GetChildWidgetInfo(), find_name, search_child))
695             {
696                 return TRUE;
697             }
698         }
699         start = start->GetNextWidgetInfo();
700     }
701     return FALSE;
702 }
703 
704 ///////////////////////////////////////////////////////////////////////////////
FindAppName(folder_info * folder,CString & find_name,BOOL search_child)705 BOOL widget_factory::FindAppName(folder_info *folder, CString &find_name, BOOL search_child)
706 {
707     while (folder)
708     {
709         if (FindAppName(folder->GetFirstChildWidget(), find_name, search_child))
710         {
711             return TRUE;
712         }
713         folder = folder->GetNextFolder();
714     }
715     return FALSE;
716 }
717 
718 ///////////////////////////////////////////////////////////////////////////////
FindAppName(folder_info * folder,widget_info * find,BOOL search_child)719 BOOL widget_factory::FindAppName(folder_info *folder, widget_info *find, BOOL search_child)
720 {
721     while (folder)
722     {
723         if (FindAppName(folder->GetFirstChildWidget(), find, search_child))
724         {
725             return TRUE;
726         }
727         folder = folder->GetNextFolder();
728     }
729     return FALSE;
730 }
731 
732 ///////////////////////////////////////////////////////////////////////////////
FindBaseName(CString & find_name)733 BOOL widget_factory::FindBaseName(CString &find_name)
734 {
735     widget_service_provider *provider = NULL;
736 
737     for (int index = 0; index < PROVIDER_TABLE_SIZE; index++)
738     {
739         provider = service_providers[index];
740 
741         if (provider)
742         {
743             if (find_name == provider->GetShortName())
744             {
745                 return TRUE;
746             }
747         }
748     }
749 
750     return FALSE;
751 }
752 
753 ///////////////////////////////////////////////////////////////////////////////
CreateUniqueAppNames(widget_info * start,widget_info * search_also,widget_info * search_start,BOOL is_top_level_widget)754 void widget_factory::CreateUniqueAppNames(widget_info *start, widget_info *search_also, widget_info *search_start, BOOL is_top_level_widget)
755 {
756     CString out;
757     BOOL search_child;
758     widget_info *new_search_also = search_also;
759 
760     if (is_top_level_widget)
761     {
762         search_child = FALSE;
763     }
764     else
765     {
766         search_child = TRUE;
767     }
768 
769     while(start)
770     {
771         CString seed = start->app_name;
772         folder_info *root_folder = NULL;
773         widget_info *root_widget = search_start;
774 
775         if (!root_widget)
776         {
777             root_folder = GetProjectView()->GetRootFolder();
778         }
779 
780         if (FindAppName(root_folder, start, search_child) || FindAppName(root_widget, start, search_child) ||
781             FindAppName(search_also, start, search_child))
782         {
783             int underscore = seed.ReverseFind('_');
784 
785             if (underscore > 0 && underscore > (seed.GetLength() - 3))
786             {
787                 if (seed.GetAt(underscore + 1) >= '0' &&
788                     seed.GetAt(underscore + 1) <= '9')
789                 {
790                     seed = seed.Left(underscore);
791                 }
792             }
793 
794             if (root_folder || root_widget)
795             {
796                 start->app_name = seed;
797 
798                 if (FindAppName(root_folder, start, search_child) || FindAppName(root_widget, start, search_child) ||
799                     FindAppName(search_also, start, search_child))
800                 {
801                     int index = 1;
802                     out.Format(_T("%s_%d"), seed, index);
803 
804                     start->app_name = out;
805                     while (FindAppName(root_folder, start, search_child) || FindAppName(root_widget, start, search_child) ||
806                            FindAppName(search_also, start, search_child))
807                     {
808                         index++;
809                         out.Format(_T("%s_%d"), seed, index);
810                         start->app_name = out;
811                     }
812                 }
813             }
814         }
815 
816         if (start->GetChildWidgetInfo())
817         {
818             if (is_top_level_widget)
819             {
820                 root_widget = start->GetChildWidgetInfo();
821                 new_search_also = start->GetChildWidgetInfo();
822             }
823             CreateUniqueAppNames(start->GetChildWidgetInfo(), new_search_also, root_widget, FALSE);
824         }
825         start = start->GetNextWidgetInfo();
826     }
827 }
828 
829 ///////////////////////////////////////////////////////////////////////////////
DecrementWidgetResourceIds(int res_type,folder_info * folder,GX_RESOURCE_ID resource_id)830 void widget_factory::DecrementWidgetResourceIds(int res_type, folder_info *folder, GX_RESOURCE_ID resource_id)
831 {
832     CArray<GX_RESOURCE_ID> resource_id_array;
833 
834     resource_id_array.Add(resource_id);
835     while (folder)
836     {
837         DecrementWidgetResourceIds(res_type, folder->GetFirstChildWidget(), resource_id_array);
838         folder = folder->GetNextFolder();
839     }
840 }
841 
842 ///////////////////////////////////////////////////////////////////////////////
DecrementWidgetResourceIds(int res_type,folder_info * folder,CArray<GX_RESOURCE_ID> & resource_id_array)843 void widget_factory::DecrementWidgetResourceIds(int res_type, folder_info* folder, CArray<GX_RESOURCE_ID> &resource_id_array)
844 {
845     while (folder)
846     {
847         DecrementWidgetResourceIds(res_type, folder->GetFirstChildWidget(), resource_id_array);
848         folder = folder->GetNextFolder();
849     }
850 }
851 
852 ///////////////////////////////////////////////////////////////////////////////
UpdateSpriteFrameInfos(widget_info * info,GX_RESOURCE_ID map_id)853 void widget_factory::UpdateSpriteFrameInfos(widget_info* info, GX_RESOURCE_ID map_id)
854 {
855     sprite_service_provider* provider;
856     BOOL updated = FALSE;
857 
858     while (info)
859     {
860         if(info->basetype == GX_TYPE_SPRITE)
861         {
862             if (info->pixelmap_id[NORMAL_PIXELMAP_INDEX] == map_id)
863             {
864                 provider = (sprite_service_provider *)GetServiceProvider(info->basetype);
865                 if (provider && info)
866                 {
867                     provider->UpdateSpriteFrameInfo(info);
868                     updated = TRUE;
869                 }
870             }
871         }
872 
873         if (info->GetChildWidgetInfo())
874         {
875             UpdateSpriteFrameInfos(info->GetChildWidgetInfo(), map_id);
876         }
877 
878         if (updated)
879         {
880             widget_info* screen_info = GetProjectView()->FindTopLevelWidget(info);
881 
882             if (screen_info && screen_info->is_template)
883             {
884                 template_service_provider::RebuildDerivedWidgets(screen_info);
885             }
886         }
887         info = info->GetNextWidgetInfo();
888     }
889 }
890 
891 ///////////////////////////////////////////////////////////////////////////////
UpdateSpriteFrameInfos(folder_info * folder,GX_RESOURCE_ID map_id)892 void widget_factory::UpdateSpriteFrameInfos(folder_info *folder, GX_RESOURCE_ID map_id)
893 {
894     while (folder)
895     {
896         UpdateSpriteFrameInfos(folder->GetFirstChildWidget(), map_id);
897         folder = folder->GetNextFolder();
898     }
899 }
900 
901 ///////////////////////////////////////////////////////////////////////////////
CalculateResourceIdDecrementCount(CArray<GX_RESOURCE_ID> & resource_id_array,GX_RESOURCE_ID resource_id)902 int widget_factory::CalculateResourceIdDecrementCount(CArray<GX_RESOURCE_ID> &resource_id_array, GX_RESOURCE_ID resource_id)
903 {
904     int count = 0;
905     GX_RESOURCE_ID deleted_id;
906 
907     for (int index = 0; index < resource_id_array.GetCount(); index++)
908     {
909         deleted_id = resource_id_array.GetAt(index);
910 
911         if (resource_id == deleted_id)
912         {
913             return -1;
914         }
915         else if (resource_id > deleted_id)
916         {
917             count++;
918         }
919     }
920 
921     return count;
922 }
923 
924 ///////////////////////////////////////////////////////////////////////////////
DecrementWidgetResourceIds(int res_type,widget_info * info,CArray<GX_RESOURCE_ID> & resource_id_array)925 void widget_factory::DecrementWidgetResourceIds(int res_type, widget_info *info, CArray<GX_RESOURCE_ID> &resource_id_array)
926 {
927     int index;
928     int count;
929     GX_RESOURCE_ID *id_list;
930     widget_service_provider *provider;
931     BOOL updated = FALSE;
932 
933     while(info)
934     {
935         switch(res_type)
936         {
937         case RES_TYPE_STRING:
938             if (info->basetype == GX_TYPE_STRING_SCROLL_WHEEL)
939             {
940                 count = info->ewi.string_scroll_wheel.base.total_rows;
941                 id_list = info->ewi.string_scroll_wheel.string_id_list;
942             }
943             else
944             {
945                 count = NUM_WIDGET_STRINGS;
946                 id_list = info->string_id;
947             }
948 
949             if (id_list)
950             {
951                 provider = GetServiceProvider(info->basetype);
952                 if (provider)
953                 {
954                     for (index = 0; index < count; index++)
955                     {
956                         if (id_list[index] == resource_id_array.GetAt(0))
957                         {
958                             provider->AssignText(info, index, 0);
959 
960                             updated = TRUE;
961                         }
962                         else
963                         {
964                             if (id_list[index] > resource_id_array.GetAt(0))
965                             {
966                                 provider->AssignText(info, index, id_list[index] - 1);
967 
968                                 updated = TRUE;
969                             }
970                         }
971                     }
972                 }
973             }
974             break;
975 
976         case RES_TYPE_COLOR:
977             for (index = 0; index < NUM_WIDGET_COLORS; index++)
978             {
979                 if (info->color_id[index] == resource_id_array.GetAt(0))
980                 {
981                     provider = GetServiceProvider(info->basetype);
982                     if (provider && info)
983                     {
984                         provider->AssignColor(info, index, 0);
985 
986                         updated = TRUE;
987                     }
988                 }
989                 else
990                 {
991                     if (info->color_id[index] > resource_id_array.GetAt(0))
992                     {
993                         provider = GetServiceProvider(info->basetype);
994                         if (provider && info)
995                         {
996                             provider->AssignColor(info, index, info->color_id[index] - 1);
997 
998                             updated = TRUE;
999                         }
1000                     }
1001                 }
1002             }
1003             break;
1004 
1005         case RES_TYPE_PIXELMAP:
1006             for (index = 0; index < NUM_WIDGET_PIXELMAPS; index++)
1007             {
1008                 if (!info->pixelmap_id[index])
1009                 {
1010                     continue;
1011                 }
1012 
1013                 count = CalculateResourceIdDecrementCount(resource_id_array, info->pixelmap_id[index]);
1014                 if (count == -1)
1015                 {
1016                     provider = GetServiceProvider(info->basetype);
1017                     if (provider && info)
1018                     {
1019                         provider->AssignPixelmap(info, index, 0);
1020 
1021                         updated = TRUE;
1022                     }
1023                 }
1024                 else
1025                 {
1026                     if (count > 0)
1027                     {
1028                         provider = GetServiceProvider(info->basetype);
1029                         if (provider && info)
1030                         {
1031                             provider->AssignPixelmap(info, index, info->pixelmap_id[index] - count);
1032 
1033                             updated = TRUE;
1034                         }
1035                     }
1036                 }
1037             }
1038 
1039             if (info->basetype == GX_TYPE_SPRITE)
1040             {
1041                 CheckReplaceSpritePixelmaps(info, resource_id_array);
1042             }
1043             break;
1044 
1045         case RES_TYPE_FONT:
1046             for (index = 0; index < NUM_WIDGET_FONTS; index++)
1047             {
1048                 if (info->font_id[index] == resource_id_array.GetAt(0))
1049                 {
1050                     provider = GetServiceProvider(info->basetype);
1051                     if (provider && info)
1052                     {
1053                         provider->AssignFont(info, index, 0);
1054 
1055                         updated = TRUE;
1056                     }
1057                 }
1058                 else
1059                 {
1060                     if (info->font_id[index] > resource_id_array.GetAt(0))
1061                     {
1062                         provider = GetServiceProvider(info->basetype);
1063                         if (provider && info)
1064                         {
1065                             provider->AssignFont(info, index, info->font_id[index] - 1);
1066 
1067                             updated = TRUE;
1068                         }
1069                     }
1070                 }
1071             }
1072             break;
1073         }
1074         if (info->GetChildWidgetInfo())
1075         {
1076             DecrementWidgetResourceIds(res_type, info->GetChildWidgetInfo(), resource_id_array);
1077         }
1078 
1079         if (updated)
1080         {
1081             widget_info *screen_info = GetProjectView()->FindTopLevelWidget(info);
1082 
1083             if (screen_info && screen_info->is_template)
1084             {
1085                 template_service_provider::RebuildDerivedWidgets(screen_info);
1086             }
1087         }
1088         info = info->GetNextWidgetInfo();
1089     }
1090 }
1091 
1092 ///////////////////////////////////////////////////////////////////////////////
StringDeleted(studiox_project * project,GX_RESOURCE_ID string_id)1093 void widget_factory::StringDeleted(studiox_project *project, GX_RESOURCE_ID string_id)
1094 {
1095     int display = GetProjectView()->GetActiveDisplay();
1096 
1097     folder_info *info = project->mDisplays[display].GetFirstChildFolder();
1098 
1099     if (info)
1100     {
1101         DecrementWidgetResourceIds(RES_TYPE_STRING, info, string_id);
1102     }
1103 
1104 }
1105 
1106 ///////////////////////////////////////////////////////////////////////////////
CountReferences(int res_type,widget_info * info,GX_RESOURCE_ID resource_id,int count,bool skip_template)1107 int widget_factory::CountReferences(int res_type, widget_info *info, GX_RESOURCE_ID resource_id, int count, bool skip_template)
1108 {
1109     int index;
1110     GX_RESOURCE_ID *string_list;
1111     int string_count;
1112 
1113     while(info)
1114     {
1115 
1116         if ((!skip_template) || (info->basetype != GX_TYPE_TEMPLATE))
1117         {
1118             switch (res_type)
1119             {
1120             case RES_TYPE_STRING:
1121                 if (info->basetype == GX_TYPE_STRING_SCROLL_WHEEL)
1122                 {
1123                     string_list = info->ewi.string_scroll_wheel.string_id_list;
1124                     string_count = info->ewi.string_scroll_wheel.base.total_rows;
1125                 }
1126                 else
1127                 {
1128                     string_list = info->string_id;
1129                     string_count = NUM_WIDGET_STRINGS;
1130                 }
1131                 if (string_list)
1132                 {
1133                     for (index = 0; index < string_count; index++)
1134                     {
1135                         if (string_list[index] == resource_id)
1136                         {
1137                             count++;
1138                         }
1139                     }
1140                 }
1141                 break;
1142 
1143             case RES_TYPE_COLOR:
1144                 for (index = 0; index < NUM_WIDGET_COLORS; index++)
1145                 {
1146                     if (info->color_id[index] == resource_id)
1147                     {
1148                         count++;
1149                     }
1150                 }
1151                 break;
1152 
1153             case RES_TYPE_PIXELMAP:
1154                 for (index = 0; index < NUM_WIDGET_PIXELMAPS; index++)
1155                 {
1156                     if (info->pixelmap_id[index] == resource_id)
1157                     {
1158                         count++;
1159                     }
1160                 }
1161                 break;
1162 
1163             case RES_TYPE_FONT:
1164                 for (index = 0; index < 2; index++)
1165                 {
1166                     if (info->font_id[index] == resource_id)
1167                     {
1168                         count++;
1169                     }
1170                 }
1171                 break;
1172             }
1173         }
1174 
1175         if (info->GetChildWidgetInfo())
1176         {
1177             count = CountReferences(res_type, info->GetChildWidgetInfo(), resource_id, count);
1178         }
1179         info = info->GetNextWidgetInfo();
1180     }
1181     return count;
1182 }
1183 
1184 ///////////////////////////////////////////////////////////////////////////////
CountReferences(studiox_project * project,int res_type,GX_RESOURCE_ID resource_id)1185 int widget_factory::CountReferences(studiox_project *project, int res_type, GX_RESOURCE_ID resource_id)
1186 {
1187     int count = 0;
1188 
1189     for (int Display = 0; Display < MAX_DISPLAYS; Display++)
1190     {
1191         folder_info *info = project->mDisplays[Display].GetFirstChildFolder();
1192 
1193         while (info)
1194         {
1195             count = CountReferences(res_type, info->GetFirstChildWidget(), resource_id, count);
1196             info = info->GetNextFolder();
1197         }
1198     }
1199     return count;
1200 }
1201 
1202 ///////////////////////////////////////////////////////////////////////////////
UpdateInputWidgetText(widget_info * info,GX_RESOURCE_ID resource_id)1203 void widget_factory::UpdateInputWidgetText(widget_info *info, GX_RESOURCE_ID resource_id)
1204 {
1205     while (info)
1206     {
1207         switch (info->basetype)
1208         {
1209         case GX_TYPE_MULTI_LINE_TEXT_INPUT:
1210         case GX_TYPE_SINGLE_LINE_TEXT_INPUT:
1211             if ((info->string_id[0] == resource_id) || (resource_id == -1))
1212             {
1213                 widget_service_provider * provider = widget_factory::GetServiceProvider(info->basetype);
1214 
1215                 if (provider && info->widget)
1216                 {
1217                     provider->AssignText(info, 0, info->string_id[0]);
1218                 }
1219             }
1220             break;
1221         }
1222 
1223         if (info->GetChildWidgetInfo())
1224         {
1225             UpdateInputWidgetText(info->GetChildWidgetInfo(), resource_id);
1226         }
1227 
1228         info = info->GetNextWidgetInfo();
1229     }
1230 }
1231 
1232 ///////////////////////////////////////////////////////////////////////////////
UpdateInputWidgetText(studiox_project * project,GX_RESOURCE_ID resource_id)1233 void widget_factory::UpdateInputWidgetText(studiox_project *project, GX_RESOURCE_ID resource_id)
1234 {
1235     for (int Display = 0; Display < MAX_DISPLAYS; Display++)
1236     {
1237         folder_info *info = project->mDisplays[Display].GetFirstChildFolder();
1238 
1239         while (info)
1240         {
1241             UpdateInputWidgetText(info->GetFirstChildWidget(), resource_id);
1242             info = info->GetNextFolder();
1243         }
1244     }
1245 }
1246 
1247 ///////////////////////////////////////////////////////////////////////////////
ReplaceScrollbar(widget_info * info,GX_SCROLLBAR_APPEARANCE * appearance)1248 void widget_factory::ReplaceScrollbar(widget_info *info, GX_SCROLLBAR_APPEARANCE *appearance)
1249 {
1250     info->ewi.scroll = *appearance;
1251 
1252     if (info->widget)
1253     {
1254         GX_WIDGET *new_scroll = NULL;
1255         GX_WIDGET *old_scroll = info->widget;
1256         GX_WINDOW *parent = (GX_WINDOW *)old_scroll->gx_widget_parent;
1257         gx_widget_detach(old_scroll);
1258         gx_widget_delete(old_scroll);
1259 
1260         widget_service_provider *provider = widget_factory::GetServiceProvider(info->basetype);
1261         new_scroll = provider->GenerateFromInfo((GX_WIDGET *)parent, info);
1262         info->widget = new_scroll;
1263 
1264         // GetTargetScreen()->WidgetWasReplaced(old_scroll, new_scroll);
1265         delete old_scroll;
1266     }
1267 }
1268 
1269 ///////////////////////////////////////////////////////////////////////////////
CheckReplaceSpritePixelmaps(widget_info * info,CArray<GX_RESOURCE_ID> & resource_id_array)1270 void widget_factory::CheckReplaceSpritePixelmaps(widget_info *info, CArray<GX_RESOURCE_ID> &resource_id_array)
1271 {
1272     if ((info->basetype != GX_TYPE_SPRITE) || (info->pixelmap_id[0] != 0))
1273     {
1274         return;
1275     }
1276 
1277     GX_SPRITE_FRAME *frame = info->ewi.sprite.framelist;
1278     int index;
1279     int decrement_count;
1280 
1281     for (index = 0; index < info->ewi.sprite.frame_count; index++)
1282     {
1283         decrement_count = CalculateResourceIdDecrementCount(resource_id_array, frame->gx_sprite_frame_pixelmap);
1284 
1285         if (decrement_count < 0)
1286         {
1287             frame ->gx_sprite_frame_pixelmap = 0;
1288         }
1289         else
1290         {
1291             if (decrement_count > 0)
1292             {
1293                 frame->gx_sprite_frame_pixelmap -= decrement_count;
1294             }
1295         }
1296         frame++;
1297     }
1298 
1299     widget_service_provider *provider;
1300     provider = GetServiceProvider(info->basetype);
1301     provider->AssignPixelmap(info, 0, 0);
1302 }