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 }