1 
2 #include "system_pngs.h"
3 #include "studiox_includes.h"
4 #include "config_languages_dlg.h"
5 #include "string_export_dlg.h"
6 #include "gx_api.h"
7 
8 
9 #ifdef _DEBUG
10 #define new DEBUG_NEW
11 #endif
12 
13 extern "C" {
14 extern GX_FONT _gx_system_font_8bpp;
15 extern GX_FONT _gx_system_font_4bpp;
16 extern GX_FONT _gx_system_font_mono;
17 extern GX_FONT _gx_dave2d_system_font_4bpp;
18 extern GX_FONT _gx_dave2d_system_font_mono;
19 };
20 
21 #define SYSTEM_FONT_8BPP_STORAGE 7992
22 #define SYSTEM_FONT_4BPP_STORAGE 5084
23 #define SYSTEM_FONT_MONO_STORAGE 1763
24 
25 // KGM FIXME: Why aren't we using the GUIX color format definitions here??????
26 
27 #define GXS_IMG_SAVE_ALPHA          (1 << 2)
28 #define GXS_IMG_DO_COMPRESSION      (1 << 3)
29 #define GXS_IMG_COLOR_DEPTH_24XRGB  1
30 
31 #define RANGE_CHECK(val, min, max) \
32            if(val > max)           \
33            {                       \
34                val = max;          \
35            }                       \
36            else if (val < min)     \
37            {                       \
38                val = min;          \
39            }
40 
41 #define RANGE_MIN_CHECK(val, min) \
42            if(val < min)          \
43            {                      \
44                val = min;         \
45            }
46 
47 //extern WIDGET_TABLE_ENTRY widget_table[];
48 
49 STRING_VAL_PAIR res_types[] = {
50     {L"HEADER",   RES_TYPE_HEADER},
51     {L"GROUP",    RES_TYPE_GROUP},
52     {L"FOLDER",   RES_TYPE_FOLDER},
53     {L"FONT",     RES_TYPE_FONT},
54     {L"COLOR",    RES_TYPE_COLOR},
55     {L"PIXELMAP", RES_TYPE_PIXELMAP},
56     {L"STRING",   RES_TYPE_STRING},
57     {NULL, 0}
58 };
59 
60 STRING_VAL_PAIR res_folder_ids[] = {
61     {L"DEFAULT_COLOR_FOLDER", DEFAULT_COLOR_FOLDER},
62     {L"CUSTOM_COLOR_FOLDER", CUSTOM_COLOR_FOLDER},
63     {L"DEFAULT_FONT_FOLDER", DEFAULT_FONT_FOLDER},
64     {L"CUSTOM_FONT_FOLDER", CUSTOM_FONT_FOLDER},
65     {L"DEFAULT_PIXELMAP_FOLDER", DEFAULT_PIXELMAP_FOLDER},
66     {L"CUSTOM_PIXELMAP_FOLDER", CUSTOM_PIXELMAP_FOLDER},
67     // Backward compatibility
68     {L"4096", DEFAULT_COLOR_FOLDER},
69     {L"4097", CUSTOM_COLOR_FOLDER},
70     {L"4098", DEFAULT_FONT_FOLDER},
71     {L"4099", CUSTOM_FONT_FOLDER},
72     {L"4100", DEFAULT_PIXELMAP_FOLDER},
73     {L"4101", CUSTOM_PIXELMAP_FOLDER},
74     {L"", 0}
75 };
76 
77 STRING_VAL_PAIR res_group_ids[] = {
78     {L"COLOR_GROUP", COLOR_GROUP},
79     {L"FONT_GROUP", FONT_GROUP},
80     {L"PIXELMAP_GROUP", PIXELMAP_GROUP},
81     {L"STRING_GROUP", STRING_GROUP},
82     // Backward compatibility
83     {L"4096", COLOR_GROUP},
84     {L"4097", FONT_GROUP},
85     {L"4098", PIXELMAP_GROUP},
86     {L"4099", STRING_GROUP},
87     {L"", 0}
88 };
89 
90 STRING_VAL_PAIR res_header_ids[] = {
91     {L"THEME_HEADER", THEME_HEADER},
92     // Backward compatibility
93     {L"4096", THEME_HEADER},
94     {L"", 0}
95 };
96 
97 
98 #define DEFAULT_COLOR_CANVAS                     GX_COLOR_BLACK
99 #define DEFAULT_COLOR_WIDGET_FILL                0xff787c78
100 #define DEFAULT_COLOR_WINDOW_FILL                0xffe2e2e2
101 #define DEFAULT_COLOR_STANDARD_BORDER            0xff9b9b73
102 #define DEFAULT_COLOR_WINDOW_BORDER              0xff7599aa
103 #define DEFAULT_COLOR_NORMAL_TEXT                GX_COLOR_BLACK
104 #define DEFAULT_COLOR_SELECTED_TEXT              GX_COLOR_WHITE
105 #define DEFAULT_COLOR_SELECTED_FILL              GX_COLOR_BLUE
106 #define DEFAULT_COLOR_DISABLED_TEXT              0xffa0a0a0
107 #define DEFAULT_COLOR_DISABLED_FILL              0xff787c78
108 
109 #define DEFAULT_COLOR_SHADOW                     GX_COLOR_DARKGRAY
110 #define DEFAULT_COLOR_SHINE                      0xffdadada
111 
112 #define DEFAULT_COLOR_BUTTON_BORDER              0xffe0c060
113 #define DEFAULT_COLOR_BUTTON_UPPER               0xfff8f8e0
114 #define DEFAULT_COLOR_BUTTON_LOWER               0xfff8ecb0
115 #define DEFAULT_COLOR_BUTTON_TEXT                GX_COLOR_BLACK
116 
117 #define DEFAULT_COLOR_SCROLL_FILL                0xffbababa
118 #define DEFAULT_COLOR_SCROLL_BUTTON              0xff7d7d7d
119 #define DEFAULT_COLOR_TEXT_INPUT_TEXT            GX_COLOR_BLACK
120 #define DEFAULT_COLOR_TEXT_INPUT_FILL            GX_COLOR_WHITE
121 #define DEFAULT_COLOR_READONLY_TEXT              GX_COLOR_WHITE
122 #define DEFAULT_COLOR_READONLY_FILL              0xff787c78
123 
124 #define DEFAULT_COLOR_SLIDER_TICK                GX_COLOR_BLACK
125 #define DEFAULT_COLOR_SLIDER_GROOVE_TOP          GX_COLOR_LIGHTGRAY
126 #define DEFAULT_COLOR_SLIDER_GROOVE_BOTTOM       GX_COLOR_WHITE
127 #define DEFAULT_COLOR_SLIDER_NEEDLE_OUTLINE      GX_COLOR_BLACK
128 #define DEFAULT_COLOR_SLIDER_NEEDLE_FILL         GX_COLOR_DARKGRAY
129 
130 ///////////////////////////////////////////////////////////////////////////////
131 COLOR_RECORD DEFAULT_COLOR_TABLE[] = {
132     {"CANVAS",                GX_COLOR_ID_CANVAS,                DEFAULT_COLOR_CANVAS},
133     {"WIDGET_FILL",           GX_COLOR_ID_WIDGET_FILL,           DEFAULT_COLOR_WIDGET_FILL},
134     {"WINDOW_FILL",           GX_COLOR_ID_WINDOW_FILL,           DEFAULT_COLOR_WINDOW_FILL},
135     {"DEFAULT_BORDER",        GX_COLOR_ID_DEFAULT_BORDER,        DEFAULT_COLOR_STANDARD_BORDER},
136     {"WINDOW_BORDER",         GX_COLOR_ID_WINDOW_BORDER,         DEFAULT_COLOR_WINDOW_BORDER},
137     {"TEXT",                  GX_COLOR_ID_TEXT,                  DEFAULT_COLOR_NORMAL_TEXT},
138     {"SELECTED_TEXT",         GX_COLOR_ID_SELECTED_TEXT,         DEFAULT_COLOR_SELECTED_TEXT},
139     {"SELECTED_FILL",         GX_COLOR_ID_SELECTED_FILL,         DEFAULT_COLOR_SELECTED_FILL},
140     {"SHADOW",                GX_COLOR_ID_SHADOW,                DEFAULT_COLOR_SHADOW},
141     {"SHINE",                 GX_COLOR_ID_SHINE,                 DEFAULT_COLOR_SHINE},
142     {"BTN_BORDER",            GX_COLOR_ID_BUTTON_BORDER,         DEFAULT_COLOR_BUTTON_BORDER},
143     {"BTN_UPPER",             GX_COLOR_ID_BUTTON_UPPER,          DEFAULT_COLOR_BUTTON_UPPER},
144     {"BTN_LOWER",             GX_COLOR_ID_BUTTON_LOWER,          DEFAULT_COLOR_BUTTON_LOWER},
145     {"BTN_TEXT",              GX_COLOR_ID_BUTTON_TEXT,           DEFAULT_COLOR_BUTTON_TEXT},
146     {"SCROLL_FILL",           GX_COLOR_ID_SCROLL_FILL,           DEFAULT_COLOR_SCROLL_FILL},
147     {"SCROLL_BUTTON",         GX_COLOR_ID_SCROLL_BUTTON,         DEFAULT_COLOR_SCROLL_BUTTON},
148     {"TEXT_INPUT_TEXT",       GX_COLOR_ID_TEXT_INPUT_TEXT,       GX_COLOR_WHITE},
149     {"TEXT_INPUT_FILL",       GX_COLOR_ID_TEXT_INPUT_FILL,       DEFAULT_COLOR_WINDOW_FILL},
150     {"SLIDER_TICK",           GX_COLOR_ID_SLIDER_TICK,           DEFAULT_COLOR_SLIDER_TICK},
151     {"SLIDER_GROOVE_TOP",     GX_COLOR_ID_SLIDER_GROOVE_TOP,     DEFAULT_COLOR_SLIDER_GROOVE_TOP},
152     {"SLIDER_GROOVE_BOTTOM",  GX_COLOR_ID_SLIDER_GROOVE_BOTTOM,  DEFAULT_COLOR_SLIDER_GROOVE_BOTTOM},
153     {"SLIDER_NEEDLE_OUTLINE", GX_COLOR_ID_SLIDER_NEEDLE_OUTLINE, DEFAULT_COLOR_SLIDER_NEEDLE_OUTLINE},
154     {"SLIDER_NEEDLE_FILL",    GX_COLOR_ID_SLIDER_NEEDLE_FILL,    DEFAULT_COLOR_SLIDER_NEEDLE_FILL},
155     {"SLIDER_NEEDLE_LINE1",   GX_COLOR_ID_SLIDER_NEEDLE_LINE1,   GX_COLOR_LIGHTGRAY},
156     {"SLIDER_NEEDLE_LINE2",   GX_COLOR_ID_SLIDER_NEEDLE_LINE2,   DEFAULT_COLOR_BUTTON_BORDER},
157     { "DISABLED_TEXT", GX_COLOR_ID_DISABLED_TEXT, DEFAULT_COLOR_DISABLED_TEXT },
158     { "DISABLED_FILL", GX_COLOR_ID_DISABLED_FILL, DEFAULT_COLOR_DISABLED_FILL },
159     { "READONLY_TEXT", GX_COLOR_ID_READONLY_TEXT, DEFAULT_COLOR_READONLY_TEXT },
160     { "READONLY_FILL", GX_COLOR_ID_READONLY_FILL, DEFAULT_COLOR_READONLY_FILL },
161     {NULL,                    0,                                 0}
162 };
163 
164 /* Pre-define color which used for 2bpp and 4bpp grayscale */
165 #define GX_COLOR_LIGHTGRAY_GRAYSCALE             0x55555555
166 #define GX_COLOR_DARKGRAY_GRAYSCALE              0xaaaaaaaa
167 ///////////////////////////////////////////////////////////////////////////////
168 /* member of DEFAULT_COLOR_TABLE_GRAYSCALE[] should be same with DEFAULT_COLOR_TABLE[] */
169 COLOR_RECORD DEFAULT_COLOR_TABLE_GRAYSCALE[] = {
170     { "CANVAS",          GX_COLOR_ID_CANVAS,          GX_COLOR_BLACK },
171     { "WIDGET_FILL",     GX_COLOR_ID_WIDGET_FILL,     GX_COLOR_LIGHTGRAY_GRAYSCALE },
172     { "WINDOW_FILL",     GX_COLOR_ID_WINDOW_FILL,     GX_COLOR_DARKGRAY_GRAYSCALE },
173     { "DEFAULT_BORDER",  GX_COLOR_ID_DEFAULT_BORDER,  GX_COLOR_BLACK },
174     { "WINDOW_BORDER",   GX_COLOR_ID_WINDOW_BORDER,   GX_COLOR_BLACK },
175     { "TEXT",            GX_COLOR_ID_TEXT,            GX_COLOR_BLACK },
176     { "SELECTED_TEXT",   GX_COLOR_ID_SELECTED_TEXT,   GX_COLOR_WHITE },
177     { "SELECTED_FILL",   GX_COLOR_ID_SELECTED_FILL,   GX_COLOR_BLACK },
178     { "SHADOW",          GX_COLOR_ID_SHADOW,          GX_COLOR_DARKGRAY_GRAYSCALE },
179     { "SHINE",           GX_COLOR_ID_SHINE,           GX_COLOR_LIGHTGRAY_GRAYSCALE },
180     { "BTN_BORDER",      GX_COLOR_ID_BUTTON_BORDER,   GX_COLOR_BLACK },
181     { "BTN_UPPER",       GX_COLOR_ID_BUTTON_UPPER,    GX_COLOR_DARKGRAY_GRAYSCALE },
182     { "BTN_LOWER",       GX_COLOR_ID_BUTTON_LOWER,    GX_COLOR_LIGHTGRAY_GRAYSCALE },
183     { "BTN_TEXT",        GX_COLOR_ID_BUTTON_TEXT,     GX_COLOR_BLACK },
184     { "SCROLL_FILL",     GX_COLOR_ID_SCROLL_FILL,     GX_COLOR_LIGHTGRAY_GRAYSCALE },
185     { "SCROLL_BUTTON",   GX_COLOR_ID_SCROLL_BUTTON,   GX_COLOR_DARKGRAY_GRAYSCALE },
186     { "TEXT_INPUT_TEXT", GX_COLOR_ID_TEXT_INPUT_TEXT, GX_COLOR_WHITE },
187     { "TEXT_INPUT_FILL", GX_COLOR_ID_TEXT_INPUT_FILL, GX_COLOR_DARKGRAY_GRAYSCALE },
188     { "SLIDER_TICK",       GX_COLOR_ID_SLIDER_TICK,    GX_COLOR_WHITE },
189     { "SLIDER_GROOVE_TOP", GX_COLOR_ID_SLIDER_GROOVE_TOP, GX_COLOR_WHITE },
190     { "SLIDER_GROOVE_BOTTOM", GX_COLOR_ID_SLIDER_GROOVE_BOTTOM, GX_COLOR_BLACK },
191     { "SLIDER_NEEDLE_OUTLINE", GX_COLOR_ID_SLIDER_NEEDLE_OUTLINE, GX_COLOR_BLACK },
192     { "SLIDER_NEEDLE_FILL",  GX_COLOR_ID_SLIDER_NEEDLE_FILL, GX_COLOR_WHITE },
193     { "SLIDER_NEEDLE_LINE1", GX_COLOR_ID_SLIDER_NEEDLE_LINE1, GX_COLOR_DARKGRAY_GRAYSCALE },
194     { "SLIDER_NEEDLE_LINE2", GX_COLOR_ID_SLIDER_NEEDLE_LINE2, GX_COLOR_LIGHTGRAY_GRAYSCALE },
195     { "DISABLED_TEXT", GX_COLOR_ID_DISABLED_TEXT, GX_COLOR_LIGHTGRAY_GRAYSCALE },
196     { "DISABLED_FILL", GX_COLOR_ID_DISABLED_FILL, GX_COLOR_DARKGRAY_GRAYSCALE },
197     { "READONLY_TEXT", GX_COLOR_ID_READONLY_TEXT, GX_COLOR_WHITE },
198     { "READONLY_FILL", GX_COLOR_ID_READONLY_FILL, GX_COLOR_LIGHTGRAY_GRAYSCALE },
199     { NULL, 0, 0 }
200 };
201 
202 /* member of DEFAULT_COLOR_TABLE_GRAYSCALE[] should be same with DEFAULT_COLOR_TABLE[] */
203 COLOR_RECORD DEFAULT_COLOR_TABLE_MONOCHROME[] = {
204     { "CANVAS",          GX_COLOR_ID_CANVAS,          GX_COLOR_BLACK },
205     { "WIDGET_FILL",     GX_COLOR_ID_WIDGET_FILL,     GX_COLOR_BLACK },
206     { "WINDOW_FILL",     GX_COLOR_ID_WINDOW_FILL,     GX_COLOR_BLACK },
207     { "DEFAULT_BORDER",  GX_COLOR_ID_DEFAULT_BORDER,  GX_COLOR_WHITE },
208     { "WINDOW_BORDER",   GX_COLOR_ID_WINDOW_BORDER,   GX_COLOR_WHITE },
209     { "TEXT",            GX_COLOR_ID_TEXT,            GX_COLOR_WHITE },
210     { "SELECTED_TEXT",   GX_COLOR_ID_SELECTED_TEXT,   GX_COLOR_WHITE },
211     { "SELECTED_FILL",   GX_COLOR_ID_SELECTED_FILL,   GX_COLOR_BLACK },
212     { "SHADOW",          GX_COLOR_ID_SHADOW,          GX_COLOR_BLACK },
213     { "SHINE",           GX_COLOR_ID_SHINE,           GX_COLOR_BLACK },
214     { "BTN_BORDER",      GX_COLOR_ID_BUTTON_BORDER,   GX_COLOR_WHITE },
215     { "BTN_UPPER",       GX_COLOR_ID_BUTTON_UPPER,    GX_COLOR_BLACK },
216     { "BTN_LOWER",       GX_COLOR_ID_BUTTON_LOWER,    GX_COLOR_BLACK },
217     { "BTN_TEXT",        GX_COLOR_ID_BUTTON_TEXT,     GX_COLOR_WHITE },
218     { "SCROLL_FILL",     GX_COLOR_ID_SCROLL_FILL,     GX_COLOR_BLACK },
219     { "SCROLL_BUTTON",   GX_COLOR_ID_SCROLL_BUTTON,   GX_COLOR_BLACK },
220     { "TEXT_INPUT_TEXT", GX_COLOR_ID_TEXT_INPUT_TEXT, GX_COLOR_WHITE },
221     { "TEXT_INPUT_FILL", GX_COLOR_ID_TEXT_INPUT_FILL, GX_COLOR_BLACK },
222     { "SLIDER_TICK",       GX_COLOR_ID_SLIDER_TICK,    GX_COLOR_WHITE },
223     { "SLIDER_GROOVE_TOP", GX_COLOR_ID_SLIDER_GROOVE_TOP, GX_COLOR_BLACK },
224     { "SLIDER_GROOVE_BOTTOM", GX_COLOR_ID_SLIDER_GROOVE_BOTTOM, GX_COLOR_BLACK },
225     { "SLIDER_NEEDLE_OUTLINE", GX_COLOR_ID_SLIDER_NEEDLE_OUTLINE, GX_COLOR_WHITE },
226     { "SLIDER_NEEDLE_FILL",  GX_COLOR_ID_SLIDER_NEEDLE_FILL, GX_COLOR_BLACK },
227     { "SLIDER_NEEDLE_LINE1", GX_COLOR_ID_SLIDER_NEEDLE_LINE1, GX_COLOR_WHITE },
228     { "SLIDER_NEEDLE_LINE2", GX_COLOR_ID_SLIDER_NEEDLE_LINE2, GX_COLOR_WHITE },
229     { "DISABLED_TEXT", GX_COLOR_ID_DISABLED_TEXT, GX_COLOR_WHITE },
230     { "DISABLED_FILL", GX_COLOR_ID_DISABLED_FILL, GX_COLOR_BLACK },
231     { "READONLY_TEXT", GX_COLOR_ID_READONLY_TEXT, GX_COLOR_WHITE },
232     { "READONLY_FILL", GX_COLOR_ID_READONLY_FILL, GX_COLOR_BLACK },
233     { NULL, 0, 0 }
234 };
235 
236 ///////////////////////////////////////////////////////////////////////////////
237 FONT_RECORD DEFAULT_FONT_TABLE[] = {
238     {"SYSTEM",        GX_FONT_ID_DEFAULT,       &_gx_system_font_8bpp},
239     {"BUTTON",        GX_FONT_ID_BUTTON,        &_gx_system_font_8bpp},
240     {"PROMPT",        GX_FONT_ID_PROMPT,        &_gx_system_font_8bpp},
241     {"TEXT_INPUT",    GX_FONT_ID_TEXT_INPUT,    &_gx_system_font_8bpp},
242     {NULL, -1, NULL}
243 };
244 
245 extern IMAGE_INFO _system_png_radio_on;
246 extern IMAGE_INFO _system_png_radio_off;
247 extern IMAGE_INFO _system_png_checkbox_on;
248 extern IMAGE_INFO _system_png_checkbox_off;
249 
250 // FIXME: do we want to use hardcoded path?
251 PIXELMAP_RECORD DEFAULT_PIXELMAP_TABLE[] = {
252     { "RADIO_ON", GX_PIXELMAP_RADIO_ON_ID, TRUE, &_system_png_radio_on},
253     { "RADIO_OFF", GX_PIXELMAP_RADIO_OFF_ID, TRUE, &_system_png_radio_off },
254     { "CHECKBOX_ON", GX_PIXELMAP_CHECKBOX_ON_ID, FALSE, &_system_png_checkbox_on },
255     { "CHECKBOX_OFF", GX_PIXELMAP_CHECKBOX_OFF_ID, FALSE, &_system_png_checkbox_off },
256     {NULL, 0, NULL}
257 };
258 
259 /*---------------------------------------------------------------------------*/
260 /*---------------------------------------------------------------------------*/
261 // the normal constructor
widget_info()262 widget_info::widget_info()
263 {
264     init(GX_TYPE_WIDGET);
265 }
266 
267 ///////////////////////////////////////////////////////////////////////////////
widget_info(int type)268 widget_info::widget_info(int type)
269 {
270     init(type);
271 }
272 
273 ///////////////////////////////////////////////////////////////////////////////
274 // the copy constructor
widget_info(const widget_info & other,BOOL copy_next)275 widget_info::widget_info(const widget_info &other, BOOL copy_next)
276 {
277     copy(other);
278 
279     widget_info *sib_put;
280     const widget_info *sib_get;
281 
282     if (other.child)
283     {
284         this->child = new widget_info(*other.child, TRUE);
285     }
286     if (copy_next)
287     {
288         sib_put = this;
289         sib_get = &other;
290 
291         while(sib_get->next)
292         {
293             sib_put->next = new widget_info(*sib_get->next, FALSE);
294             sib_put = sib_put->next;
295             sib_get = sib_get->next;
296         }
297     }
298 }
299 
300 ///////////////////////////////////////////////////////////////////////////////
operator =(const widget_info & other)301 widget_info &widget_info::operator=(const widget_info &other)
302 {
303     copy(other);
304     return *this;
305 }
306 
307 ///////////////////////////////////////////////////////////////////////////////
~widget_info()308 widget_info::~widget_info()
309 {
310     widget_info *test;
311     widget_info *temp;
312 
313     switch(basetype)
314     {
315     case GX_TYPE_SPRITE:
316         if (ewi.sprite.framelist)
317         {
318             delete [] ewi.sprite.framelist;
319         }
320         break;
321 
322     case GX_TYPE_STRING_SCROLL_WHEEL:
323         if (ewi.string_scroll_wheel.string_id_list)
324         {
325             delete ewi.string_scroll_wheel.string_id_list;
326             ewi.string_scroll_wheel.string_id_list = NULL;
327         }
328         break;
329     }
330 
331     if (child)
332     {
333         delete child;
334         child = NULL;
335     }
336 
337     test = next;
338     next = NULL;
339 
340     while(test)
341     {
342         temp = test->next;
343         test->next = NULL;
344         delete test;
345         test = temp;
346     }
347 
348     if (widget)
349     {
350         widget_factory::CleanupWidgets(this);
351     }
352 }
353 
354 ///////////////////////////////////////////////////////////////////////////////
copy(const widget_info & other)355 void widget_info::copy(const widget_info &other)
356 {
357     int index;
358     init(other.basetype);
359 
360     size = other.size;
361 
362     for (index = 0; index < NUM_WIDGET_COLORS; index++)
363     {
364         color_id[index] = other.color_id[index];
365     }
366     for (index = 0; index < NUM_WIDGET_PIXELMAPS; index++)
367     {
368         pixelmap_id[index] = other.pixelmap_id[index];
369     }
370     font_id[0] = other.font_id[0];
371     font_id[1] = other.font_id[1];
372     string_id[0] = other.string_id[0];
373     string_id[1] = other.string_id[1];
374 
375     style = other.style;
376 
377     is_template = other.is_template;
378     visible_at_startup = other.visible_at_startup;
379     event_func = other.event_func;
380     draw_func = other.draw_func;
381     callback_func = other.callback_func;
382     format_func = other.format_func;
383 
384     id_name = other.id_name;
385     app_name = other.app_name;          // handy name passed to create
386     base_name = other.base_name;        // control structure name
387     custom_name = other.custom_name;    // user-defined custom structure name
388     user_data = other.user_data;
389 
390     ewi = other.ewi;                   // copy the union
391 
392     // if copying a sprite, make a new sprite framelist
393     if (other.basetype == GX_TYPE_SPRITE)
394     {
395         if (other.ewi.sprite.framelist)
396         {
397             ewi.sprite.framelist = new GX_SPRITE_FRAME[ewi.sprite.frame_count];
398 
399             for (index = 0; index < ewi.sprite.frame_count; index++)
400             {
401                 ewi.sprite.framelist[index] = other.ewi.sprite.framelist[index];
402             }
403         }
404     }
405 
406     if (other.basetype == GX_TYPE_STRING_SCROLL_WHEEL)
407     {
408         if (other.ewi.string_scroll_wheel.string_id_list)
409         {
410             int total_rows = other.ewi.string_scroll_wheel.base.total_rows;
411             ewi.string_scroll_wheel.string_id_list = new GX_RESOURCE_ID[total_rows];
412             memcpy_s(ewi.string_scroll_wheel.string_id_list, total_rows * sizeof(GX_RESOURCE_ID), other.ewi.string_scroll_wheel.string_id_list, total_rows * sizeof(GX_RESOURCE_ID));
413         }
414     }
415 
416     allocation = other.allocation;
417     accepts_focus = other.accepts_focus;
418 
419     misc_value = other.misc_value;
420 
421     this->widget = NULL;
422     this->next = NULL;
423     this->child = NULL;
424 
425     if (other.widget)
426     {
427         this->copied_widget = other.widget;
428     }
429     else
430     {
431         this->copied_widget = other.copied_widget;
432     }
433 }
434 
435 ///////////////////////////////////////////////////////////////////////////////
init(int type)436 void widget_info::init(int type)
437 {
438     int index;
439 
440     basetype = type;
441     base_name = widget_factory::WidgetTypeToString(type);
442     custom_name = "";
443 
444     app_name = "";
445     event_func = "";
446     draw_func = "";
447     user_data = "";
448     id_name = "";
449     callback_func = "";
450     format_func = "";
451     allocation = STATICALLY_ALLOCATED;
452     misc_value = 0;
453 
454     memset(&ewi, 0, sizeof(extended_widget_info));
455 
456     size.gx_rectangle_left = size.gx_rectangle_top = size.gx_rectangle_right = size.gx_rectangle_bottom = 0;
457     style = 0;
458 
459     for (index = 0; index < NUM_WIDGET_COLORS; index++)
460     {
461         color_id[index] = 0;
462     }
463     for (index = 0; index < NUM_WIDGET_PIXELMAPS; index++)
464     {
465         pixelmap_id[index] = 0;
466     }
467     for (index = 0; index < NUM_WIDGET_FONTS; index++)
468     {
469         font_id[index] = 0;
470     }
471     string_id[0] = 0;
472     string_id[1] = 0;
473 
474     widget = NULL;
475     child = NULL;
476     next = NULL;
477     copied_widget = NULL;
478     is_template = FALSE;
479     visible_at_startup = FALSE;
480 }
481 
482 ///////////////////////////////////////////////////////////////////////////////
SetChildWidgetInfo(widget_info * info)483 void widget_info::SetChildWidgetInfo(widget_info *info)
484 {
485     this->child = info;
486 }
487 
488 ///////////////////////////////////////////////////////////////////////////////
SetNextWidgetInfo(widget_info * info)489 void widget_info::SetNextWidgetInfo(widget_info *info)
490 {
491     this->next = info;
492 }
493 
494 /*---------------------------------------------------------------------------*/
495 /*---------------------------------------------------------------------------*/
res_info(int ResType)496 res_info::res_info(int ResType)
497 {
498     type = ResType;
499 
500     switch (type)
501     {
502     case RES_TYPE_ADD_COLOR:
503         name = "Add New Color";
504         break;
505 
506     case RES_TYPE_ADD_FONT:
507         name = "Add New Font";
508         break;
509 
510     case RES_TYPE_ADD_PIXELMAP:
511         name = "Add New Pixelmap";
512         break;
513 
514     case RES_TYPE_ADD_STRING:
515         name = "Add New String";
516         break;
517 
518     default:
519         name = "";
520         break;
521     }
522 
523     pathinfo.pathname = "";
524     pathinfo.pathtype = PATH_TYPE_PROJECT_RELATIVE;
525     next = NULL;
526     child = NULL;
527     parent = NULL;
528 
529     if (ResType == RES_TYPE_PIXELMAP)
530     {
531         compress = TRUE;
532     }
533     else
534     {
535         compress = FALSE;
536     }
537 
538     keep_alpha = FALSE;
539     dither = FALSE;
540     raw = FALSE;
541     palette_type = PALETTE_TYPE_NONE;
542     font_height = 0;
543     font_bits = 8;
544     font_charset_include_string_table = FALSE;
545     font_pages = NULL;
546     font_pages_count = 0;
547     font_support_extended_unicode = FALSE;
548     map_list.RemoveAll();
549     map_delay_list.RemoveAll();
550     thumbnail = NULL;
551     font = NULL;
552     colorval = RGB(0, 0, 0);
553     folder_id = 0;
554     storage_size = 0;
555     output_color_format = 0;
556     output_file_enabled = FALSE;
557     output_file = "";
558     binary_mode = FALSE;
559     is_default = FALSE;
560     enabled = TRUE;
561 
562     is_modified = FALSE;
563 }
564 
565 ///////////////////////////////////////////////////////////////////////////////
566 // the copy constructor
res_info(const res_info * in_parent,const res_info & other,BOOL copy_next)567 res_info::res_info(const res_info *in_parent, const res_info &other, BOOL copy_next)
568 {
569     type = other.type;
570     name = other.name;
571     pathinfo.pathname = other.pathinfo.pathname;
572     pathinfo.pathtype = other.pathinfo.pathtype;
573     next = NULL;
574     child = NULL;
575     parent = (res_info *) in_parent;
576     compress = other.compress;
577     font_kerning = other.font_kerning;
578     keep_alpha = other.keep_alpha;
579     dither = other.dither;
580     raw = other.raw;
581     palette_type = other.palette_type;
582     storage_size = other.storage_size;
583     output_color_format = other.output_color_format;
584     output_file_enabled = other.output_file_enabled;
585     output_file = other.output_file;
586     binary_mode = other.binary_mode;
587 
588     font_height = other.font_height;
589     font_bits = other.font_bits;
590     font_charset_include_string_table = other.font_charset_include_string_table;
591     font_pages = NULL;
592     font_pages_count = 0;
593     font_support_extended_unicode = other.font_support_extended_unicode;
594 
595     int page_count = NUM_FONT_CHAR_RANGES;
596     if (other.font_support_extended_unicode)
597     {
598         page_count += NUM_FONT_EXTENDED_CHAR_RANGES;
599     }
600 
601     if (other.font_pages)
602     {
603         font_pages = new font_page_info[page_count];
604         memcpy_s(font_pages, sizeof(font_page_info) * page_count, other.font_pages, sizeof(font_page_info) * page_count);
605     }
606 
607     colorval = other.colorval;
608     folder_id = other.folder_id;
609     is_default = other.is_default;
610     enabled = other.enabled;
611 
612     map_list.RemoveAll();
613     map_delay_list.RemoveAll();
614     thumbnail = NULL;
615     font = NULL;
616 
617     if (other.child)
618     {
619         child = new res_info(this, *other.child, TRUE);
620     }
621 
622     if (copy_next)
623     {
624         res_info *sib_put = this;
625         const res_info *sib_get = &other;
626 
627         while(sib_get->next)
628         {
629             sib_put->next = new res_info(parent, *sib_get->next, FALSE);
630             sib_put = sib_put->next;
631             sib_get = sib_get->next;
632         }
633     }
634 
635     is_modified = FALSE;
636 }
637 
638 ///////////////////////////////////////////////////////////////////////////////
~res_info()639 res_info::~res_info()
640 {
641     res_info *test;
642 
643     switch(type)
644     {
645     case RES_TYPE_FONT:
646         if (font)
647         {
648             if (!is_default || !pathinfo.pathname.IsEmpty())
649             {
650                 DestroyFont(font);
651             }
652         }
653         if (font_pages)
654         {
655             delete [] font_pages;
656             font_pages = NULL;
657         }
658         break;
659 
660     case RES_TYPE_PIXELMAP:
661         if (map_list.GetCount())
662         {
663             pixelmap_list_destroy(map_list);
664         }
665         if (thumbnail)
666         {
667             pixelmap_destroy(thumbnail);
668         }
669         map_delay_list.RemoveAll();
670         break;
671 
672     default:
673         break;
674     }
675     while(child)
676     {
677         test = child->next;
678         delete child;
679         child = test;
680     }
681 }
682 
683 ///////////////////////////////////////////////////////////////////////////////
Attach(res_info * pRes)684 void res_info::Attach(res_info *pRes)
685 {
686     res_info *test;
687     pRes->next = NULL;
688 
689     if (child)
690     {
691         test = child;
692         while(test->next)
693         {
694             test = test->next;
695         }
696         test->next = pRes;
697     }
698     else
699     {
700         child = pRes;
701     }
702     pRes->parent = this;
703 }
704 
705 ///////////////////////////////////////////////////////////////////////////////
Detach()706 void res_info::Detach()
707 {
708 
709     res_info *previous;
710 
711     if (parent)
712     {
713         if (parent->child == this)
714         {
715             // the easy case, first child:
716             parent->child = next;
717         }
718         else
719         {
720             previous = parent->child;
721             while (previous->next != this)
722             {
723                 previous = previous->next;
724             }
725             previous->next = next;
726         }
727     }
728     next = NULL;
729     parent = NULL;
730 }
731 
732 ///////////////////////////////////////////////////////////////////////////////
GetPixelmap(int frame_id)733 GX_PIXELMAP *res_info::GetPixelmap(int frame_id)
734 {
735 
736     if (frame_id < map_list.GetCount())
737     {
738         return map_list.GetAt(frame_id);
739     }
740 
741     return NULL;
742 }
743 
744 ///////////////////////////////////////////////////////////////////////////////
GetPixelmapDelayTime(int frame_id)745 INT res_info::GetPixelmapDelayTime(int frame_id)
746 {
747     if (frame_id < map_delay_list.GetCount())
748     {
749         return map_delay_list.GetAt(frame_id);
750     }
751 
752     return 0;
753 }
754 
755 ///////////////////////////////////////////////////////////////////////////////
ResTypeToString(int type)756 CString studiox_project::ResTypeToString(int type)
757 {
758     return FindPairString(res_types, type);
759 }
760 
761 ///////////////////////////////////////////////////////////////////////////////
ResStringToType(CString & name)762 int studiox_project::ResStringToType(CString &name)
763 {
764     return FindPairVal(res_types, name);
765 }
766 
767 ///////////////////////////////////////////////////////////////////////////////
FindFolderIdString(int res_type,int val)768 CString studiox_project::FindFolderIdString(int res_type, int val)
769 {
770     STRING_VAL_PAIR *entry = NULL;
771 
772     switch (res_type)
773     {
774     case RES_TYPE_GROUP:
775         entry = res_group_ids;
776         break;
777 
778     case RES_TYPE_FOLDER:
779         entry = res_folder_ids;
780         break;
781 
782     case RES_TYPE_HEADER:
783         entry = res_header_ids;
784         break;
785 
786     default:
787         break;
788     }
789 
790     if (entry)
791     {
792         return FindPairString(entry, val);
793     }
794 
795     return L"";
796 }
797 
798 ///////////////////////////////////////////////////////////////////////////////
FindFolderIdVal(int res_type,CString string)799 int studiox_project::FindFolderIdVal(int res_type, CString string)
800 {
801     STRING_VAL_PAIR *entry = NULL;
802 
803     switch (res_type)
804     {
805     case RES_TYPE_GROUP:
806         entry = res_group_ids;
807         break;
808 
809     case RES_TYPE_FOLDER:
810         entry = res_folder_ids;
811         break;
812 
813     case RES_TYPE_HEADER:
814         entry = res_header_ids;
815         break;
816 
817     default:
818         break;
819     }
820 
821     if (entry)
822     {
823         return FindPairVal(entry, string);
824     }
825 
826     return 0;
827 }
828 
829 ///////////////////////////////////////////////////////////////////////////////
830 /*---------------------------------------------------------------------------*/
831 /*---------------------------------------------------------------------------*/
studiox_project(const CString & path,const CString & name,BOOL bNewProject)832 studiox_project::studiox_project(const CString &path, const CString &name, BOOL bNewProject)
833 {
834     InitProjectHeader(bNewProject);
835     mHeader.project_path = path;
836     mHeader.project_name = name;
837     is_modified = FALSE;
838 }
839 
840 ///////////////////////////////////////////////////////////////////////////////
~studiox_project()841 studiox_project::~studiox_project()
842 {
843     for (int index = 0; index < MAX_DISPLAYS; index++)
844     {
845         if (mDisplays[index].GetFirstChildFolder())
846         {
847             const folder_info *test = mDisplays[index].GetFirstChildFolder();
848 
849             if (test)
850             {
851                 delete test;
852             }
853         }
854         CleanupDisplayResources(&mDisplays[index]);
855 
856         if (mDisplays[index].stable)
857         {
858             delete mDisplays[index].stable;
859         }
860 
861         if (mDisplays[index].screenflow)
862         {
863             delete mDisplays[index].screenflow;
864         }
865     }
866 }
867 
868 ///////////////////////////////////////////////////////////////////////////////
InitStringExportHeader()869 void studiox_project::InitStringExportHeader()
870 {
871     mHeader.string_export_src = 0;
872     mHeader.string_export_target = 1;
873     mHeader.string_export_version = 2;
874     mHeader.string_export_path = ".\\";
875     mHeader.string_export_filename = "";
876     mHeader.string_export_filetype = STRING_EXPORT_TYPE_XLIFF;
877 }
878 
879 ///////////////////////////////////////////////////////////////////////////////
InitProjectHeader(BOOL bNewProject)880 void studiox_project::InitProjectHeader(BOOL bNewProject)
881 {
882     CString screen_name;
883     CString theme_name;
884     char    index_char[4];
885 
886     mHeader.project_version = PROJECT_VERSION;
887     mHeader.guix_version = GuixVersionFieldsToVersionNumber(GUIX_MAJOR_VERSION, GUIX_MINOR_VERSION, GUIX_PATCH_VERSION);
888     mHeader.studio_version = CalculateStudioVersion();
889 
890     mHeader.num_displays = 1;
891     mHeader.num_languages = 1;
892     mHeader.languages[0].name = CString("English");
893 
894     for (int index = 0; index < MAX_LANGUAGES; index++)
895     {
896         mHeader.languages[index].support_bidi_text = FALSE;
897         mHeader.languages[index].gen_reordered_bidi_text = FALSE;
898         mHeader.languages[index].support_thai_glyph_shaping = FALSE;
899         mHeader.languages[index].gen_adjusted_thai_string = FALSE;
900         mHeader.languages[index].statically_defined = TRUE;
901     }
902 
903     mHeader.max_displays = MAX_DISPLAYS;
904 
905     // configure defaults for all screen info stuctures
906     for (int index = 0; index < MAX_DISPLAYS; index++)
907     {
908         screen_name = "display_";
909         _ltoa_s(index + 1, index_char, 4, 10);
910         screen_name += index_char;
911         mDisplays[index].name = screen_name;
912         mDisplays[index].num_themes = 1;
913 
914         mDisplays[index].xres = 320;
915         mDisplays[index].yres = 240;
916         mDisplays[index].bits_per_pix = 16;
917         mDisplays[index].grayscale = FALSE;
918         mDisplays[index].packed_format = FALSE;
919         mDisplays[index].reverse_order = FALSE;
920         mDisplays[index].format_555 = FALSE;
921         mDisplays[index].format_4444 = FALSE;
922         mDisplays[index].format_332 = FALSE;
923         mDisplays[index].colorformat = GX_COLOR_FORMAT_565RGB;
924         mDisplays[index].SetFirstChildFolder(NULL);
925         mDisplays[index].enabled = TRUE;
926         mDisplays[index].default_map_format = TRUE;
927         mDisplays[index].allocate_canvas = TRUE;
928         mDisplays[index].rotation_angle = GX_SCREEN_ROTATION_NONE;
929         InitDisplayThemes(index);
930 
931         for (int language = 0; language < mHeader.num_languages; language++)
932         {
933             mDisplays[index].gen_string_table[language] = TRUE;
934         }
935 
936         mDisplays[index].stable = NULL;
937         mDisplays[index].screenflow = NULL;
938 
939         if (bNewProject)
940         {
941             CreateDefaultResources(index, mDisplays[index].active_theme);
942         }
943     }
944 
945     // configure defaults for directories:
946     mHeader.header_path = ".\\";
947     mHeader.source_path = ".\\";
948     mHeader.resource_path = ".\\";
949     mHeader.malloc_name = "";
950     mHeader.free_name = "";
951     mHeader.additional_headers = "";
952     mHeader.insert_headers_before = FALSE;
953     mHeader.target_cpu = CPU_GENERIC;
954     mHeader.target_tools = TOOLS_GENERIC;
955     mHeader.big_endian = FALSE;
956     mHeader.dave2d_graph_accelerator = TRUE;
957     mHeader.renesas_png_decoder = DECODER_TYPE_NONE;
958     mHeader.renesas_jpeg_decoder = DECODER_TYPE_HW;
959     mHeader.grid_enabled = FALSE;
960     mHeader.snap_enabled = FALSE;
961     mHeader.snap_to_widget_enabled = FALSE;
962     mHeader.grid_spacing = 10;
963     mHeader.snap_spacing = 10;
964     mHeader.gen_binary = FALSE;
965     mHeader.gen_res_header = TRUE;
966     mHeader.binary_file_format = BINARY_FILE_FORMAT_SREC;
967     mHeader.memory_offset = 0;
968     mHeader.custom_resource_enabled = FALSE;
969     mHeader.custom_resource_file_name = "";
970     if (bNewProject)
971     {
972         mHeader.b_new_project = TRUE;
973     }
974     else
975     {
976         mHeader.b_new_project = FALSE;
977     }
978     mHeader.app_execute_xpos = 20;
979     mHeader.app_execute_ypos = 20;
980     mHeader.is_widget_position_locked = FALSE;
981     mHeader.palette_mode_aa_text_colors = 8;
982 
983     InitStringExportHeader();
984 }
985 
986 
987 ///////////////////////////////////////////////////////////////////////////////
Clone(const studiox_project * src)988 studiox_project *studiox_project::Clone(const studiox_project *src)
989 {
990     int index;
991     int display;
992     int theme;
993 
994     studiox_project *new_project = new studiox_project(
995         src->mHeader.project_path, src->mHeader.project_name, FALSE);
996 
997     new_project->mHeader.project_version = PROJECT_VERSION;
998     new_project->mHeader.guix_version = src->mHeader.guix_version;
999     new_project->mHeader.studio_version = src->mHeader.studio_version;
1000     new_project->mHeader.max_displays = MAX_DISPLAYS;
1001 
1002     new_project->mHeader.num_displays = src->mHeader.num_displays;
1003     new_project->mHeader.num_languages = src->mHeader.num_languages;
1004     new_project->mHeader.header_path = src->mHeader.header_path;
1005     new_project->mHeader.source_path = src->mHeader.source_path;
1006     new_project->mHeader.resource_path = src->mHeader.resource_path;
1007 
1008     new_project->mHeader.malloc_name = src->mHeader.malloc_name;
1009     new_project->mHeader.free_name = src->mHeader.free_name;
1010     new_project->mHeader.additional_headers = src->mHeader.additional_headers;
1011     new_project->mHeader.insert_headers_before = src->mHeader.insert_headers_before;
1012     new_project->mHeader.target_cpu = src->mHeader.target_cpu;
1013     new_project->mHeader.target_tools = src->mHeader.target_tools;
1014     new_project->mHeader.big_endian = src->mHeader.big_endian;
1015     new_project->mHeader.dave2d_graph_accelerator = src->mHeader.dave2d_graph_accelerator;
1016     new_project->mHeader.renesas_png_decoder = src->mHeader.renesas_png_decoder;
1017     new_project->mHeader.renesas_jpeg_decoder = src->mHeader.renesas_jpeg_decoder;
1018     new_project->mHeader.grid_enabled = src->mHeader.grid_enabled;
1019     new_project->mHeader.snap_enabled = src->mHeader.snap_enabled;
1020     new_project->mHeader.snap_to_widget_enabled = src->mHeader.snap_to_widget_enabled;
1021     new_project->mHeader.grid_spacing = src->mHeader.grid_spacing;
1022     new_project->mHeader.snap_spacing = src->mHeader.snap_spacing;
1023     new_project->mHeader.gen_binary = src->mHeader.gen_binary;
1024     new_project->mHeader.gen_res_header = src->mHeader.gen_res_header;
1025     new_project->mHeader.memory_offset = src->mHeader.memory_offset;
1026     new_project->mHeader.binary_file_format = src->mHeader.binary_file_format;
1027     new_project->mHeader.custom_resource_enabled = src->mHeader.custom_resource_enabled;
1028     new_project->mHeader.custom_resource_file_name = src->mHeader.custom_resource_file_name;
1029     new_project->mHeader.app_execute_xpos = src->mHeader.app_execute_xpos;
1030     new_project->mHeader.app_execute_ypos = src->mHeader.app_execute_ypos;
1031     new_project->mHeader.is_widget_position_locked = src->mHeader.is_widget_position_locked;
1032     new_project->mHeader.palette_mode_aa_text_colors = src->mHeader.palette_mode_aa_text_colors;
1033 
1034     new_project->mHeader.string_export_src = src->mHeader.string_export_src;
1035     new_project->mHeader.string_export_target = src->mHeader.string_export_target;
1036     new_project->mHeader.string_export_version = src->mHeader.string_export_version;
1037     new_project->mHeader.string_export_path = src->mHeader.string_export_path;
1038     new_project->mHeader.string_export_filename = src->mHeader.string_export_filename;
1039     new_project->mHeader.string_export_filetype = src->mHeader.string_export_filetype;
1040 
1041     // clone language names
1042     for (index = 0; index < new_project->mHeader.num_languages; index++)
1043     {
1044         new_project->mHeader.languages[index].name = src->mHeader.languages[index].name;
1045         new_project->mHeader.languages[index].support_bidi_text = src->mHeader.languages[index].support_bidi_text;
1046         new_project->mHeader.languages[index].gen_reordered_bidi_text = src->mHeader.languages[index].gen_reordered_bidi_text;
1047         new_project->mHeader.languages[index].support_thai_glyph_shaping = src->mHeader.languages[index].support_thai_glyph_shaping;
1048         new_project->mHeader.languages[index].gen_adjusted_thai_string = src->mHeader.languages[index].gen_adjusted_thai_string;
1049         new_project->mHeader.languages[index].statically_defined = src->mHeader.languages[index].statically_defined;
1050     }
1051 
1052     // clone dislay info
1053     for (display = 0; display < MAX_DISPLAYS; display++)
1054     {
1055         new_project->mDisplays[display].name = src->mDisplays[display].name;
1056         new_project->mDisplays[display].num_themes = src->mDisplays[display].num_themes;
1057         new_project->mDisplays[display].active_theme = src->mDisplays[display].active_theme;
1058 
1059         for (theme = 0; theme < MAX_THEMES; theme++)
1060         {
1061             new_project->mDisplays[display].themes[theme].SetFirstResourceInfo(NULL);
1062 
1063             new_project->mDisplays[display].themes[theme].theme_name = src->mDisplays[display].themes[theme].theme_name;
1064             new_project->mDisplays[display].themes[theme].VScrollAppearance = src->mDisplays[display].themes[theme].VScrollAppearance;
1065             new_project->mDisplays[display].themes[theme].HScrollAppearance, src ->mDisplays[display].themes[theme].HScrollAppearance;
1066             new_project->mDisplays[display].themes[theme].VScrollStyle = src->mDisplays[display].themes[theme].VScrollStyle;
1067             new_project->mDisplays[display].themes[theme].HScrollStyle = src->mDisplays[display].themes[theme].HScrollStyle;
1068 
1069             new_project->mDisplays[display].themes[theme].palette_total_size = src->mDisplays[display].themes[theme].palette_total_size;
1070             new_project->mDisplays[display].themes[theme].palette_predefined = src->mDisplays[display].themes[theme].palette_predefined;
1071             new_project->mDisplays[display].themes[theme].gen_color_table = src->mDisplays[display].themes[theme].gen_color_table;
1072             new_project->mDisplays[display].themes[theme].gen_font_table = src->mDisplays[display].themes[theme].gen_font_table;
1073             new_project->mDisplays[display].themes[theme].gen_pixelmap_table = src->mDisplays[display].themes[theme].gen_pixelmap_table;
1074             new_project->mDisplays[display].themes[theme].enabled = src->mDisplays[display].themes[theme].enabled;
1075             new_project->mDisplays[display].themes[theme].statically_defined = src->mDisplays[display].themes[theme].statically_defined;
1076 
1077             if (src->mDisplays[display].themes[theme].palette)
1078             {
1079                 theme_info *des_tinfo = &new_project->mDisplays[display].themes[theme];
1080                 const theme_info *src_tinfo = &src->mDisplays[display].themes[theme];
1081 
1082                 switch(src->mDisplays[display].colorformat)
1083                 {
1084                 case GX_COLOR_FORMAT_8BIT_PALETTE:
1085                     new_project->mDisplays[display].themes[theme].palette = new GX_COLOR[256];
1086                     break;
1087 
1088                 case GX_COLOR_FORMAT_4BIT_GRAY:
1089                     new_project->mDisplays[display].themes[theme].palette = new GX_COLOR[16];
1090                     break;
1091 
1092                 default:
1093                     new_project->mDisplays[display].themes[theme].palette = new GX_COLOR[2];
1094                     break;
1095                 }
1096 
1097                 memcpy_s(des_tinfo->palette, des_tinfo->palette_total_size * sizeof(GX_COLOR), src_tinfo->palette, src_tinfo->palette_total_size * sizeof(GX_COLOR));
1098             }
1099 
1100             for (index = 0; index < MAX_LANGUAGES; index++)
1101             {
1102                 new_project->mDisplays[display].gen_string_table[index] = src->mDisplays[display].gen_string_table[index];
1103             }
1104         }
1105         new_project->mDisplays[display].xres = src->mDisplays[display].xres;
1106         new_project->mDisplays[display].yres = src->mDisplays[display].yres;
1107         new_project->mDisplays[display].bits_per_pix = src->mDisplays[display].bits_per_pix;
1108         new_project->mDisplays[display].grayscale = src->mDisplays[display].grayscale;
1109         new_project->mDisplays[display].packed_format = src->mDisplays[display].packed_format;
1110         new_project->mDisplays[display].reverse_order = src->mDisplays[display].reverse_order;
1111         new_project->mDisplays[display].format_555 = src->mDisplays[display].format_555;
1112         new_project->mDisplays[display].format_4444 = src->mDisplays[display].format_4444;
1113         new_project->mDisplays[display].format_332 = src->mDisplays[display].format_332;
1114         new_project->mDisplays[display].colorformat = src->mDisplays[display].colorformat;
1115         new_project->mDisplays[display].SetFirstChildFolder(NULL);
1116         new_project->mDisplays[display].enabled = src->mDisplays[display].enabled;
1117         new_project->mDisplays[display].default_map_format = src->mDisplays[display].default_map_format;
1118         new_project->mDisplays[display].allocate_canvas = src->mDisplays[display].allocate_canvas;
1119 
1120         new_project->mDisplays[display].stable = NULL;
1121         new_project->mDisplays[display].screenflow = NULL;
1122 
1123         // clone the widget info
1124         if (src->mDisplays[display].GetFirstChildFolder())
1125         {
1126             folder_info *folder = new folder_info(*src->mDisplays[display].GetFirstChildFolder(), TRUE);
1127             new_project->mDisplays[display].SetFirstChildFolder(folder);
1128         }
1129 
1130         // clone the resource info
1131 
1132         for (theme = 0; theme < src->mDisplays[display].num_themes; theme++)
1133         {
1134             if (src->mDisplays[display].themes[theme].GetFirstResourceInfo())
1135             {
1136                 res_info * info = new res_info(NULL, *src->mDisplays[display].themes[theme].GetFirstResourceInfo(), TRUE);
1137                 if (info)
1138                 {
1139                     new_project->mDisplays[display].themes[theme].SetFirstResourceInfo(info);
1140 
1141                 }
1142             }
1143         }
1144 
1145         // clone the string table:
1146         if (src->mDisplays[display].stable)
1147         {
1148             new_project->mDisplays[display].stable = new string_table(*src->mDisplays[display].stable);
1149         }
1150 
1151         // clone the screen flow information
1152         if (src->mDisplays[display].screenflow)
1153         {
1154             new_project->mDisplays[display].screenflow = new screen_flow(*src->mDisplays[display].screenflow);
1155         }
1156     }
1157     return new_project;
1158 }
1159 
1160 ////////////////////////////////////////////////////////////////////////////////
GetDefaultPixelmapRecord(CString name)1161 PIXELMAP_RECORD *studiox_project::GetDefaultPixelmapRecord(CString name)
1162 {
1163     // Retrieve default pixelmap record according to id name.
1164 
1165     PIXELMAP_RECORD *record = DEFAULT_PIXELMAP_TABLE;
1166 
1167     while (record->name && record->image_info)
1168     {
1169         if (record->name == name)
1170         {
1171             return record;
1172         }
1173 
1174         record++;
1175     }
1176 
1177     return NULL;
1178 }
1179 
1180 
1181 ////////////////////////////////////////////////////////////////////////////////
CheckEmptyScreenFlow()1182 void studiox_project::CheckEmptyScreenFlow()
1183 {
1184     int item_count;
1185     int index;
1186     flow_item *item;
1187     BOOL no_triggers;
1188 
1189     for (int display = 0; display < mHeader.num_displays; display++)
1190     {
1191         screen_flow *flow = mDisplays[display].screenflow;
1192         if (flow)
1193         {
1194             item_count = flow->GetFlowListCount();
1195 
1196             if (!item_count)
1197             {
1198                 delete flow;
1199                 mDisplays[display].screenflow = NULL;
1200             }
1201             else
1202             {
1203                 no_triggers = TRUE;
1204                 for (index = 0; index < item_count; index++)
1205                 {
1206                     item = flow->GetFlowItem(index);
1207                     if (item->trigger_list)
1208                     {
1209                         no_triggers = FALSE;
1210                         break;
1211                     }
1212                 }
1213 
1214                 if (no_triggers)
1215                 {
1216                     delete flow;
1217                     mDisplays[display].screenflow = NULL;
1218                 }
1219             }
1220         }
1221     }
1222 }
1223 
1224 ////////////////////////////////////////////////////////////////////////////////
CleanupThemeResources(display_info * display,int ThemeIndex)1225 void studiox_project::CleanupThemeResources(display_info *display, int ThemeIndex)
1226 {
1227     res_info *current = display->themes[ThemeIndex].GetFirstResourceInfo();
1228     res_info *next;
1229 
1230     while (current)
1231     {
1232         next = current->next;
1233         delete current;
1234         current = next;
1235     }
1236 
1237     if (display->themes[ThemeIndex].palette)
1238     {
1239         delete[] display->themes[ThemeIndex].palette;
1240         display->themes[ThemeIndex].palette = NULL;
1241     }
1242 
1243     display->themes[ThemeIndex].SetFirstResourceInfo(NULL);
1244 }
1245 
1246 
1247 ///////////////////////////////////////////////////////////////////////////////
CleanupDisplayResources(display_info * display)1248 void studiox_project::CleanupDisplayResources(display_info *display)
1249 {
1250 
1251     //Clean up resources of all themes of the given display
1252     for (int theme = 0; theme < display->num_themes; theme++)
1253     {
1254         CleanupThemeResources(display, theme);
1255     }
1256 }
1257 
1258 ///////////////////////////////////////////////////////////////////////////////
1259 // This function initializes font and pixelmap resources by reading a converting
1260 // the resource source file into a pixelmap or GX_FONT.
1261 //
1262 // This is done after a project is cloned, or after a project file is read,
1263 // rather than doing it inline because it takes time and the cloned project
1264 // might never even be used.
1265 //
1266 // Called when a new project is opened
1267 ///////////////////////////////////////////////////////////////////////////////
1268 
InitializeProjectResourcesThreadEntry(LPVOID thread_input)1269 static DWORD WINAPI InitializeProjectResourcesThreadEntry(LPVOID thread_input)
1270 {
1271     studiox_project *project = GetOpenProject();
1272 
1273     if (project)
1274     {
1275         project->InitializeAllPixelmaps();
1276 
1277         for (int display = 0; display < MAX_DISPLAYS; display++)
1278         {
1279             if (display >= project->mHeader.num_displays)
1280             {
1281                 project->mHeader.warn_missing_font = FALSE;
1282             }
1283             else
1284             {
1285                 project->mHeader.warn_missing_font = TRUE;
1286             }
1287 
1288             for (int theme = 0; theme < MAX_THEMES; theme++)
1289             {
1290                 project->InitializeFonts(project->mDisplays[display].themes[theme].GetFirstResourceInfo(), display);
1291             }
1292         }
1293     }
1294 
1295     EndBusyMsg();
1296 
1297     return TRUE;
1298 }
1299 
InitializeProjectResources()1300 void studiox_project::InitializeProjectResources()
1301 {
1302     StartWorkThread(InitializeProjectResourcesThreadEntry, 0, "Initializing Resources.", TRUE);
1303 }
1304 
1305 ///////////////////////////////////////////////////////////////////////////////
1306 // This is called by the configure_theme_dialog when the user adds a new theme
InitializeThemeResources(int display,int theme,res_info * start)1307 void studiox_project::InitializeThemeResources(int display, int theme, res_info *start)
1308 {
1309     InitializeThemePixelmaps(GetDisplayIndex(start), theme);
1310     InitializeFonts(start, display);
1311 }
1312 
1313 ///////////////////////////////////////////////////////////////////////////////
ConfigureDefaultFont(res_info * put,int display)1314 void studiox_project::ConfigureDefaultFont(res_info *put, int display)
1315 {
1316     GX_FONT *def_font = NULL;
1317 
1318     switch(put->font_bits)
1319     {
1320     case 1:
1321         if (IsDave2dFontFormat(GetOpenProject(), display))
1322         {
1323             def_font = &_gx_dave2d_system_font_mono;
1324         }
1325         else
1326         {
1327             def_font = &_gx_system_font_mono;
1328         }
1329         put->storage_size = SYSTEM_FONT_MONO_STORAGE;
1330         break;
1331 
1332     case 4:
1333         if (IsRenesasDave2D(GetOpenProject()))
1334         {
1335             def_font = &_gx_dave2d_system_font_4bpp;
1336         }
1337         else
1338         {
1339             def_font = &_gx_system_font_4bpp;
1340         }
1341         put->storage_size = SYSTEM_FONT_4BPP_STORAGE;
1342         break;
1343 
1344     case 8:
1345         def_font = &_gx_system_font_8bpp;
1346         put->storage_size = SYSTEM_FONT_8BPP_STORAGE;
1347         break;
1348     }
1349 
1350     put->font = def_font;
1351     put->font_height = def_font->gx_font_line_height;
1352     put->font_bits = GetFontBits(def_font->gx_font_format);
1353     put->compress = FALSE;
1354     put->font_kerning = FALSE;
1355 
1356     if (put->font_pages)
1357     {
1358         put->font_pages[0].first_char = def_font->gx_font_first_glyph;
1359         put->font_pages[0].last_char = def_font->gx_font_last_glyph;
1360     }
1361 }
1362 
1363 ///////////////////////////////////////////////////////////////////////////////
InitializeFonts(res_info * info,int display)1364 void studiox_project::InitializeFonts(res_info *info, int display)
1365 {
1366     GX_FONT *font;
1367 
1368     while(info)
1369     {
1370         if (info->type == RES_TYPE_FONT)
1371         {
1372             // first clean up any existing font
1373             if (info->font)
1374             {
1375                 if (!info->is_default || !info->pathinfo.pathname.IsEmpty())
1376                 {
1377                     DestroyFont(info->font);
1378                 }
1379             }
1380             if (info->is_default && info->pathinfo.pathname.IsEmpty())
1381             {
1382                 ConfigureDefaultFont(info, display);
1383             }
1384             else
1385             {
1386                 font = MakeFont(info, display, mHeader.warn_missing_font);
1387                 info->font = font;
1388 
1389                 /* Get output font size. */
1390                 if (!info->font_charset_include_string_table)
1391                 {
1392                     info->storage_size = GetFontStorage(info, this, display);
1393                 }
1394 
1395                 if (!font)
1396                 {
1397                     // just warn one time
1398                     mHeader.warn_missing_font = FALSE;
1399                 }
1400             }
1401         }
1402         if (info->child)
1403         {
1404             InitializeFonts(info->child, display);
1405         }
1406         info = info->next;
1407     }
1408 }
1409 
1410 
1411 ///////////////////////////////////////////////////////////////////////////////
AssignSharedPaletteToPixelmaps(res_info * info)1412 void studiox_project::AssignSharedPaletteToPixelmaps(res_info *info)
1413 {
1414     while(info)
1415     {
1416         if (info->type == RES_TYPE_PIXELMAP)
1417         {
1418             info->palette_type = PALETTE_TYPE_SHARED;
1419         }
1420         if (info->child)
1421         {
1422             AssignSharedPaletteToPixelmaps(info->child);
1423         }
1424         info = info->next;
1425     }
1426 }
1427 
1428 
1429 ///////////////////////////////////////////////////////////////////////////////
CheckAssignSharedPaletteToPixelmaps()1430 void studiox_project::CheckAssignSharedPaletteToPixelmaps()
1431 {
1432     int display;
1433     int theme;
1434     int display_color_format;
1435 
1436     /* private and shared palettes are only supported when running
1437        at 16 bpp and higher color depths. In 8 bit palette mode,
1438        we only support a single global palette right now (needs to be improved).
1439     */
1440     for (display = 0; display <  MAX_DISPLAYS; display++)
1441     {
1442         display_color_format = mDisplays[display].colorformat;
1443 
1444         if (display_color_format == GX_COLOR_FORMAT_8BIT_PALETTE)
1445         {
1446             for (theme = 0; theme < MAX_THEMES; theme++)
1447             {
1448                 AssignSharedPaletteToPixelmaps(mDisplays[display].themes[theme].GetFirstResourceInfo());
1449             }
1450         }
1451     }
1452 }
1453 
1454 ///////////////////////////////////////////////////////////////////////////////
InitializeOnePixelmap(res_info * info,palette_info * theme_palette,int display_color_format)1455 BOOL studiox_project::InitializeOnePixelmap(res_info *info, palette_info *theme_palette, int display_color_format)
1456 {
1457     int display_index = -1;
1458     int color_format;
1459     palette_creater palCreator;
1460     palette_info private_palette;
1461 
1462     GX_PIXELMAP *pmap = NULL;
1463 
1464     if (info->GetPixelmapFrameCount())
1465     {
1466         pixelmap_list_destroy(info->map_list);
1467         info->map_delay_list.RemoveAll();
1468     }
1469     if (info->thumbnail)
1470     {
1471         pixelmap_destroy(info->thumbnail);
1472         info->thumbnail = NULL;
1473     }
1474 
1475     if (display_color_format == -1)
1476     {
1477         display_color_format = GetDisplayColorFormat(info);
1478     }
1479 
1480     // test for Dave2D incompatible format, force output format to format that will
1481     // work with Dave2d. This test is only required because old project may have
1482     // incompatible format, before we were doing the right checks
1483 
1484     if (IsRenesasDave2D(this))
1485     {
1486         if (display_color_format == GX_COLOR_FORMAT_565RGB)
1487         {
1488             if (info->keep_alpha)
1489             {
1490                 if (!IsAlphaFormat(info->output_color_format))
1491                 {
1492                     info->output_color_format = GX_COLOR_FORMAT_32ARGB;
1493                 }
1494             }
1495         }
1496         else
1497         {
1498             if ((display_color_format == GX_COLOR_FORMAT_24XRGB) || (display_color_format == GX_COLOR_FORMAT_32ARGB))
1499             {
1500                 if (info->keep_alpha && (info->output_color_format == GX_COLOR_FORMAT_565RGB))
1501                 {
1502                     info->output_color_format = GX_COLOR_FORMAT_32ARGB;
1503                 }
1504             }
1505         }
1506     }
1507 
1508     info->storage_size = 0;
1509 
1510     image_reader *pReader = NULL;
1511     CString abspath;
1512     IMAGE_INFO *default_image_info = NULL;
1513     int frame_count = 1;
1514     int frame_id = -1;
1515 
1516     if (info->pathinfo.pathname.IsEmpty())
1517     {
1518         if (info->is_default)
1519         {
1520             // Read image from internally linked system png data.
1521             PIXELMAP_RECORD *record = GetDefaultPixelmapRecord(info->name);
1522             if (record)
1523             {
1524                 default_image_info = record->image_info;
1525                 pReader = image_reader::CreateProperReader(default_image_info->data, default_image_info->data_len);
1526             }
1527         }
1528     }
1529     else
1530     {
1531         abspath = MakeAbsolutePathname(info->pathinfo);
1532         pReader = image_reader::CreateProperReader(abspath);
1533 
1534         if (info->raw)
1535         {
1536             frame_id = 0;
1537         }
1538         else
1539         {
1540             frame_count = image_reader::GetFrameCount(abspath);
1541         }
1542     }
1543 
1544     BOOL result = FALSE;
1545 
1546     if (pReader)
1547     {
1548         if (info->output_color_format)
1549         {
1550             color_format = info->output_color_format;
1551 
1552             // info passed from palette_creater do not have a parent
1553             if (info->parent)
1554             {
1555                 display_index = GetDisplayIndex(info);
1556                 mDisplays[display_index].default_map_format = FALSE;
1557             }
1558         }
1559         else
1560         {
1561             color_format = display_color_format;
1562         }
1563 
1564         pReader->SetDither(info->dither);
1565 
1566         if (info->keep_alpha)
1567         {
1568             pReader->SetSaveAlphaVal(TRUE);
1569         }
1570         else
1571         {
1572             pReader->SetSaveAlphaVal(FALSE);
1573         }
1574 
1575         pReader->SetOutputColorFormat(color_format, display_color_format);
1576 
1577         if (color_format == GX_COLOR_FORMAT_8BIT_PALETTE)
1578         {
1579             switch(info->palette_type)
1580             {
1581             case PALETTE_TYPE_PRIVATE:
1582                 palCreator.CreatePaletteForOnePixelmap(info, &private_palette);
1583                 pReader->SetPalette(private_palette.palette, private_palette.total_size, private_palette.used_size);
1584                 break;
1585 
1586             case PALETTE_TYPE_SHARED:
1587                 if (theme_palette)
1588                 {
1589                     if (display_color_format > GX_COLOR_FORMAT_8BIT_PALETTE)
1590                     {
1591                         // If the display color format is > 8bpp palette, then the image requires
1592                         // image.pAuxData points at the palette. This might be a shared or a private palette.
1593                         // When we delete the image, we don't know if the palette is shared, so make a copy
1594                         // of the palette so that we can always delete it when the image is deleted.
1595                         private_palette.palette = new GX_COLOR[theme_palette->total_size];
1596                         memcpy_s(private_palette.palette, theme_palette->total_size * sizeof(GX_COLOR), theme_palette->palette, (theme_palette->total_size * sizeof(GX_COLOR)));
1597                         pReader->SetPalette(private_palette.palette,
1598                                     theme_palette->total_size,
1599                                     theme_palette->used_size);
1600                     }
1601                     else
1602                     {
1603                         // if the display color format is 8bpp palette, then the image pAuxData will be set to NULL,
1604                         // because the palette is a global palette that is not attached to any image.
1605                         pReader->SetPalette(theme_palette->palette,
1606                                     theme_palette->total_size,
1607                                     theme_palette->used_size);
1608                     }
1609                 }
1610                 break;
1611 
1612             default:
1613                 ErrorMsg("Internal Error: Invalid image palette type");
1614                 delete pReader;
1615                 return FALSE;
1616             }
1617         }
1618 
1619         if (default_image_info)
1620         {
1621             result = pReader->ReadImage(default_image_info->data, default_image_info->data_len);
1622         }
1623         else
1624         {
1625             result = pReader->ReadImage(abspath, frame_id);
1626         }
1627     }
1628 
1629     if (result)
1630     {
1631         for (int index = 0; index < frame_count; index++)
1632         {
1633             pmap = pReader->GetPixelmap(index);
1634             info->map_list.Add(pmap);
1635 
1636             if (frame_count > 1)
1637             {
1638                 info->map_delay_list.Add(pReader->GetDelayTime(index));
1639             }
1640 
1641             if (!info->thumbnail)
1642             {
1643 
1644                 // Make thumbnail.
1645                 if (pmap->gx_pixelmap_width > THUMBNAIL_SIZE ||
1646                     pmap->gx_pixelmap_height > THUMBNAIL_SIZE)
1647                 {
1648                     int xstretch = pmap->gx_pixelmap_width * 100 / THUMBNAIL_SIZE;
1649                     int ystretch = pmap->gx_pixelmap_height * 100 / THUMBNAIL_SIZE;
1650 
1651                     if (xstretch >= ystretch)
1652                     {
1653                         ystretch = pmap->gx_pixelmap_height * 100 / xstretch;
1654                         xstretch = pmap->gx_pixelmap_width * 100 / xstretch;
1655                     }
1656                     else
1657                     {
1658                         xstretch = pmap->gx_pixelmap_width * 100 / ystretch;
1659                         ystretch = pmap->gx_pixelmap_height * 100 / ystretch;
1660                     }
1661                     GX_PIXELMAP* thumbnail = pReader->ResizeImage(pmap, xstretch, ystretch);
1662 
1663                     if (thumbnail)
1664                     {
1665                         info->thumbnail = thumbnail;
1666                     }
1667                 }
1668             }
1669 
1670             // now compress the image
1671             if (info->compress)
1672             {
1673                 BOOL result;
1674 
1675                 pReader->DoCompress(TRUE);
1676                 if (IsRenesasDave2D(this))
1677                 {
1678                     result = pReader->RleEncode(pmap, TRUE);
1679                 }
1680                 else
1681                 {
1682                     result = pReader->RleEncode(pmap);
1683                 }
1684 
1685                 if (display_index < 0)
1686                 {
1687                     display_index = GetDisplayIndex(info);
1688                 }
1689 
1690                 if ((mDisplays[display_index].rotation_angle == GX_SCREEN_ROTATION_NONE) && (result == FALSE))
1691                 {
1692                     info->compress = FALSE;
1693                 }
1694             }
1695         }
1696 
1697         /* Calculate pixelmap storage */
1698         info->storage_size = GetPixelmapStorage(info);
1699     }
1700     else
1701     {
1702         if (mHeader.warn_missing_image)
1703         {
1704             CString msg;
1705             msg.Format(_T("Pixelmap Name = %s\nUnable to open Image file: %s"), info->name, abspath);
1706             ErrorMsg(msg);
1707 
1708             // just issue one warning
1709             mHeader.warn_missing_image = FALSE;
1710         }
1711     }
1712 
1713     if (pReader)
1714     {
1715         delete pReader;
1716     }
1717 
1718     return result;
1719 }
1720 
1721 
1722 ///////////////////////////////////////////////////////////////////////////////
1723 // This function is called when the user changes the display color depth
1724 // settings. We need to re-read all of our pixelmaps to make sure they are
1725 // formatted correctly for each display.
1726 ///////////////////////////////////////////////////////////////////////////////
InitializePixelmaps(res_info * info,palette_info * theme_palette)1727 void studiox_project::InitializePixelmaps(res_info *info, palette_info *theme_palette)
1728 {
1729     while(info)
1730     {
1731         if (info->type == RES_TYPE_PIXELMAP)
1732         {
1733             InitializeOnePixelmap(info, theme_palette);
1734         }
1735         if (info->child)
1736         {
1737             InitializePixelmaps(info->child, theme_palette);
1738         }
1739         info = info->next;
1740     }
1741 }
1742 
1743 ///////////////////////////////////////////////////////////////////////////////
1744 // CreateThemePalette
1745 //
1746 // Called by InitializeThemePixelmaps and by resource_gen::WritePalette
CreateThemePalette(int display,int theme,palette_info * theme_palette)1747 void studiox_project::CreateThemePalette(int display, int theme, palette_info *theme_palette)
1748 {
1749     res_info *info;
1750     palette_creater palCreator;
1751     palette_info image_palette;
1752     int free_slots;
1753 
1754     // if this theme does not yet have a palette, create a default palette:
1755     if (mDisplays[display].themes[theme].palette == NULL)
1756     {
1757         ProjectConfigDlg::CreateDefaultPalette(this, display, theme);
1758     }
1759 
1760     info = mDisplays[display].themes[theme].GetFirstResourceInfo();
1761 
1762     if (!info || mDisplays[display].themes[theme].palette == NULL)
1763     {
1764         return;
1765     }
1766     // create optimal palette for this display[theme]
1767     free_slots = mDisplays[display].themes[theme].palette_total_size;
1768     free_slots -= mDisplays[display].themes[theme].palette_predefined + 1;
1769 
1770     if (free_slots > 0)
1771     {
1772         palCreator.CreatePaletteForPixelmaps(info, &image_palette, TRUE, free_slots);
1773 
1774         if (image_palette.palette)
1775         {
1776             // safety check, should not happen
1777             if (image_palette.used_size > free_slots)
1778             {
1779                 image_palette.used_size = free_slots;
1780             }
1781 
1782             // merge the optimal palette with our reserved palette:
1783             theme_info* tinfo = &mDisplays[display].themes[theme];
1784             GX_COLOR* put = tinfo->palette;
1785             put += tinfo->palette_predefined;
1786             memcpy_s(put, tinfo->palette_total_size * sizeof(GX_COLOR), image_palette.palette, image_palette.used_size * sizeof(GX_COLOR));
1787             delete[] image_palette.palette;
1788         }
1789     }
1790 
1791     // the theme_palette is the merged predefined and image palette:
1792     if (theme_palette)
1793     {
1794         theme_palette->palette = mDisplays[display].themes[theme].palette;
1795         theme_palette->total_size = mDisplays[display].themes[theme].palette_total_size;
1796         theme_palette->used_size = mDisplays[display].themes[theme].palette_total_size;
1797     }
1798 }
1799 
1800 ///////////////////////////////////////////////////////////////////////////////
TestForPixelmapsUsingGlobalPalette(const res_info * info) const1801 BOOL studiox_project::TestForPixelmapsUsingGlobalPalette(const res_info *info) const
1802 {
1803     while(info)
1804     {
1805         if (info->type == RES_TYPE_PIXELMAP)
1806         {
1807             if ((info->palette_type == PALETTE_TYPE_SHARED) && (!info->raw))
1808             {
1809                 return TRUE;
1810             }
1811         }
1812         if (info->child)
1813         {
1814             if (TestForPixelmapsUsingGlobalPalette(info->child))
1815             {
1816                 return TRUE;
1817             }
1818         }
1819         info = info->next;
1820     }
1821     return FALSE;
1822 }
1823 
1824 ///////////////////////////////////////////////////////////////////////////////
InitializeThemePixelmaps(int display,int theme)1825 void studiox_project::InitializeThemePixelmaps(int display, int theme)
1826 {
1827     res_info *info;
1828     int display_color_format;
1829     palette_info theme_palette;
1830     BOOL need_palette = FALSE;
1831 
1832     info = mDisplays[display].themes[theme].GetFirstResourceInfo();
1833 
1834     if (info)
1835     {
1836         display_color_format = mDisplays[display].colorformat;
1837 
1838         if (display_color_format == GX_COLOR_FORMAT_8BIT_PALETTE)
1839         {
1840             need_palette = TRUE;
1841         }
1842         else
1843         {
1844             if (display_color_format >= GX_COLOR_FORMAT_5551BGRX &&
1845                 TestForPixelmapsUsingGlobalPalette(info))
1846             {
1847                 need_palette = TRUE;
1848             }
1849         }
1850         if (need_palette)
1851         {
1852             CreateThemePalette(display, theme, &theme_palette);
1853         }
1854         else
1855         {
1856             // this theme doesn't need a palette. If it has one, delete it
1857             if (mDisplays[display].themes[theme].palette)
1858             {
1859                 delete [] mDisplays[display].themes[theme].palette;
1860                 mDisplays[display].themes[theme].palette = NULL;
1861                 mDisplays[display].themes[theme].palette_total_size = 0;
1862             }
1863         }
1864 
1865         InitializePixelmaps(info, &theme_palette);
1866     }
1867 }
1868 
TaskInitializeAllPixelmaps()1869 void studiox_project::TaskInitializeAllPixelmaps()
1870 {
1871     // This is done in case we somehow converted the project to 8bpp palette
1872     // mode but did not correctly reset the palette type. Shouldn't happen,
1873     // but just in case!
1874     CheckAssignSharedPaletteToPixelmaps();
1875 
1876     for (int display = 0; display < MAX_DISPLAYS; display++)
1877     {
1878         if (display >= mHeader.num_displays)
1879         {
1880             mHeader.warn_missing_image = FALSE;
1881         }
1882         else
1883         {
1884             mHeader.warn_missing_image = TRUE;
1885         }
1886         for (int theme = 0; theme < MAX_THEMES; theme++)
1887         {
1888             InitializeThemePixelmaps(display, theme);
1889         }
1890     }
1891 }
1892 
TaskInitializeAllPixelmapsThreadEntry(LPVOID thread_input)1893 static DWORD WINAPI TaskInitializeAllPixelmapsThreadEntry(LPVOID thread_input)
1894 {
1895     studiox_project* project = GetOpenProject();
1896 
1897     if (project)
1898     {
1899         project->TaskInitializeAllPixelmaps();
1900     }
1901 
1902     EndBusyMsg();
1903 
1904     return TRUE;
1905 }
1906 
1907 ///////////////////////////////////////////////////////////////////////////////
1908 // Called when the display format is changed.
InitializeAllPixelmaps()1909 void studiox_project::InitializeAllPixelmaps()
1910 {
1911     StartWorkThread(TaskInitializeAllPixelmapsThreadEntry, 0, "Initializing Pixelmaps.", TRUE);
1912 }
1913 
1914 ///////////////////////////////////////////////////////////////////////////////
InitializeFontsThreadEntry(LPVOID thread_input)1915 static DWORD WINAPI InitializeFontsThreadEntry(LPVOID thread_input)
1916 {
1917     studiox_project* project = GetOpenProject();
1918 
1919     if (project)
1920     {
1921         int display;
1922         int theme;
1923         res_info* info;
1924         project->mHeader.warn_missing_font = TRUE;
1925 
1926         for (display = 0; display < MAX_DISPLAYS; display++)
1927         {
1928             if (display > project->mHeader.num_displays - 1)
1929             {
1930                 project->mHeader.warn_missing_font = FALSE;
1931             }
1932             for (theme = 0; theme < MAX_THEMES; theme++)
1933             {
1934                 info = project->mDisplays[display].themes[theme].GetFirstResourceInfo();
1935 
1936                 if (info)
1937                 {
1938                     project->InitializeFonts(info, display);
1939                 }
1940             }
1941         }
1942     }
1943 
1944     EndBusyMsg();
1945 
1946     return TRUE;
1947 }
1948 
1949 ///////////////////////////////////////////////////////////////////////////////
InitializeFonts()1950 void studiox_project::InitializeFonts()
1951 {
1952     StartWorkThread(InitializeFontsThreadEntry, 0, "Initializing Fonts.", TRUE);
1953 }
1954 
1955 ///////////////////////////////////////////////////////////////////////////////
DefaultScrollbarAppearance(display_info * pInfo,int theme)1956 void studiox_project::DefaultScrollbarAppearance(display_info *pInfo, int theme)
1957 {
1958     memset(&pInfo->themes[theme].VScrollAppearance, 0, sizeof(GX_SCROLLBAR_APPEARANCE));
1959     pInfo->themes[theme].VScrollAppearance.gx_scroll_width = 20;
1960     pInfo->themes[theme].VScrollAppearance.gx_scroll_thumb_travel_min = 20;
1961     pInfo->themes[theme].VScrollAppearance.gx_scroll_thumb_travel_max = 20;
1962     pInfo->themes[theme].VScrollAppearance.gx_scroll_thumb_width = 18;
1963     pInfo->themes[theme].VScrollAppearance.gx_scroll_thumb_color = GX_COLOR_ID_SCROLL_BUTTON;
1964     pInfo->themes[theme].VScrollAppearance.gx_scroll_thumb_border_color = GX_COLOR_ID_SCROLL_BUTTON;
1965     pInfo->themes[theme].VScrollAppearance.gx_scroll_button_color = GX_COLOR_ID_SCROLL_BUTTON;
1966     pInfo->themes[theme].VScrollAppearance.gx_scroll_thumb_border_style = GX_STYLE_BORDER_THIN;
1967     pInfo->themes[theme].VScrollStyle =  GX_SCROLLBAR_VERTICAL | GX_SCROLLBAR_RELATIVE_THUMB | GX_SCROLLBAR_END_BUTTONS;
1968 
1969     memset(&pInfo->themes[theme].HScrollAppearance, 0, sizeof(GX_SCROLLBAR_APPEARANCE));
1970     pInfo->themes[theme].HScrollAppearance.gx_scroll_width = 20;
1971     pInfo->themes[theme].HScrollAppearance.gx_scroll_thumb_travel_min = 20;
1972     pInfo->themes[theme].HScrollAppearance.gx_scroll_thumb_travel_max = 20;
1973     pInfo->themes[theme].HScrollAppearance.gx_scroll_thumb_width = 18;
1974     pInfo->themes[theme].HScrollAppearance.gx_scroll_thumb_color = GX_COLOR_ID_SCROLL_BUTTON;
1975     pInfo->themes[theme].VScrollAppearance.gx_scroll_thumb_border_color = GX_COLOR_ID_SCROLL_BUTTON;
1976     pInfo->themes[theme].HScrollAppearance.gx_scroll_button_color = GX_COLOR_ID_SCROLL_BUTTON;
1977     pInfo->themes[theme].HScrollAppearance.gx_scroll_thumb_border_style = GX_STYLE_BORDER_THIN;
1978     pInfo->themes[theme].HScrollStyle =  GX_SCROLLBAR_HORIZONTAL | GX_SCROLLBAR_RELATIVE_THUMB | GX_SCROLLBAR_END_BUTTONS;
1979 }
1980 
1981 ///////////////////////////////////////////////////////////////////////////////
InitDisplayThemes(int DisplayIndex)1982 void studiox_project::InitDisplayThemes(int DisplayIndex)
1983 {
1984     CString theme_name;
1985     display_info *pInfo = &mDisplays[DisplayIndex];
1986     pInfo->num_themes = 1;
1987     pInfo->active_theme = DEFAULT_THEME;
1988 
1989     for (int theme = 0; theme < MAX_THEMES; theme++)
1990     {
1991         theme_name.Format(_T("theme_%d"), theme + 1);
1992         mDisplays[DisplayIndex].themes[theme].theme_name = theme_name;
1993         mDisplays[DisplayIndex].themes[theme].palette = NULL;
1994         mDisplays[DisplayIndex].themes[theme].palette_total_size = 0;
1995         mDisplays[DisplayIndex].themes[theme].SetFirstResourceInfo(NULL);
1996         mDisplays[DisplayIndex].themes[theme].gen_color_table = TRUE;
1997         mDisplays[DisplayIndex].themes[theme].gen_font_table = TRUE;
1998         mDisplays[DisplayIndex].themes[theme].gen_pixelmap_table = TRUE;
1999         mDisplays[DisplayIndex].themes[theme].enabled = TRUE;
2000         mDisplays[DisplayIndex].themes[theme].statically_defined = TRUE;
2001         DefaultScrollbarAppearance(pInfo, theme);
2002     }
2003 }
2004 
2005 ///////////////////////////////////////////////////////////////////////////////
CreateDefaultResources(int DisplayIndex,int ThemeIndex)2006 void studiox_project::CreateDefaultResources(int DisplayIndex, int ThemeIndex)
2007 {
2008     display_info *pInfo = &mDisplays[DisplayIndex];
2009     CleanupThemeResources(pInfo, ThemeIndex);
2010 
2011     pInfo->colorformat = GX_COLOR_FORMAT_565RGB;
2012 
2013     /* Add theme header */
2014     res_info *pThemeHeader = new res_info(RES_TYPE_HEADER);
2015     pThemeHeader->folder_id = THEME_HEADER;
2016     pThemeHeader->name = pInfo->themes[ThemeIndex].theme_name;
2017     pInfo->themes[ThemeIndex].SetFirstResourceInfo(pThemeHeader);
2018 
2019     /* Add the Color group */
2020     res_info *pGroup = new res_info(RES_TYPE_GROUP);
2021     pGroup->name = _T("Colors");
2022     pGroup->folder_id = COLOR_GROUP;
2023 
2024     pThemeHeader->next = pGroup;
2025     //pInfo->themes[ThemeIndex].first_resource = pGroup;
2026 
2027     /* add default color folder */
2028     res_info *pDefaultColors = new res_info(RES_TYPE_FOLDER);
2029     pDefaultColors->folder_id = DEFAULT_COLOR_FOLDER;
2030     pDefaultColors->name = _T("Defaults");
2031     pGroup->Attach(pDefaultColors);
2032 
2033     /* add default colors to folder */
2034     COLOR_RECORD *pRecord = DEFAULT_COLOR_TABLE;
2035 
2036     if (pRecord)
2037     {
2038         while (pRecord->name)
2039         {
2040             res_info *pColor = new res_info(RES_TYPE_COLOR);
2041             pColor->name = pRecord->name;
2042             pColor->colorval = pRecord->rgb_val;
2043             pColor->is_default = TRUE;
2044             pDefaultColors->Attach(pColor);
2045             if (ThemeIndex == 0)
2046             {
2047                 AddToResourceDictionary(DisplayIndex, pColor);
2048             }
2049             pRecord++;
2050         }
2051     }
2052 
2053     /* add custom color folder */
2054 
2055     res_info *pCustomColors = new res_info(RES_TYPE_FOLDER);
2056     pCustomColors->folder_id = CUSTOM_COLOR_FOLDER;
2057     pCustomColors->name = _T("Custom");
2058     pGroup->Attach(pCustomColors);
2059 
2060     // Add color add item
2061     res_info* pColorAdd = new res_info(RES_TYPE_ADD_COLOR);
2062     pCustomColors->Attach(pColorAdd);
2063 
2064     /* Add the font group */
2065 
2066     res_info *pFontGroup = new res_info(RES_TYPE_GROUP);
2067     pFontGroup->name = _T("Fonts");
2068     pFontGroup->folder_id = FONT_GROUP;
2069     pGroup->next = pFontGroup;
2070     pGroup = pFontGroup;
2071 
2072     /* Add default font folder to font group */
2073     res_info *pDefaultFontFolder = new res_info(RES_TYPE_FOLDER);
2074     pDefaultFontFolder->name = _T("Defaults");
2075     pDefaultFontFolder->folder_id = DEFAULT_FONT_FOLDER;
2076     pFontGroup->Attach(pDefaultFontFolder);
2077 
2078     /* Add the default fonts to the default font folder */
2079     FONT_RECORD *pFontRec = DEFAULT_FONT_TABLE;
2080 
2081     while (pFontRec->font)
2082     {
2083         res_info *pFont = new res_info(RES_TYPE_FONT);
2084         pFont->name = pFontRec->name;
2085         pFont->font = pFontRec->font;
2086         pFont->font_bits = 8;
2087         pFont->is_default = TRUE;
2088         pFont->font_pages = font_path_dialog::CreateDefaultFontPages();
2089         pFont->font_pages[0].first_char = pFontRec->font->gx_font_first_glyph;
2090         pFont->font_pages[0].last_char = pFontRec->font->gx_font_last_glyph;
2091         pFont->font_height = pFontRec->font->gx_font_line_height;
2092         pDefaultFontFolder->Attach(pFont);
2093         if (ThemeIndex == 0)
2094         {
2095             AddToResourceDictionary(DisplayIndex, pFont);
2096         }
2097         pFontRec++;
2098     }
2099 
2100     /* Add custom font folder to font group */
2101     res_info *pCustomFontFolder = new res_info(RES_TYPE_FOLDER);
2102     pCustomFontFolder->name = _T("Custom");
2103     pCustomFontFolder->folder_id = CUSTOM_FONT_FOLDER;
2104     pFontGroup->Attach(pCustomFontFolder);
2105 
2106     // Add font add item
2107     res_info* pFontAdd = new res_info(RES_TYPE_ADD_FONT);
2108     pCustomFontFolder->Attach(pFontAdd);
2109 
2110     /* Add the pixelmap group */
2111 
2112     res_info *pPixGroup = new res_info(RES_TYPE_GROUP);
2113     pPixGroup->name = _T("Pixelmaps");
2114     pPixGroup->folder_id = PIXELMAP_GROUP;
2115     pGroup->next = pPixGroup;
2116     pGroup = pPixGroup;
2117 
2118     /* Add system pixelmap folder to pixmap group */
2119     res_info *pSysMaps = new res_info(RES_TYPE_FOLDER);
2120     pSysMaps->name = _T("System");
2121     pSysMaps->folder_id = DEFAULT_PIXELMAP_FOLDER;
2122     pPixGroup->Attach(pSysMaps);
2123 
2124     /* Add the default pixelmaps to the system pixelmap folder */
2125     PIXELMAP_RECORD *pPixRec = DEFAULT_PIXELMAP_TABLE;
2126     while (pPixRec->name && pPixRec->image_info)
2127     {
2128         res_info *pmap = new res_info(RES_TYPE_PIXELMAP);
2129         pmap->name = pPixRec->name;
2130         pmap->keep_alpha = pPixRec->include_alpha;
2131         pmap->is_default = TRUE;
2132         pSysMaps->Attach(pmap);
2133 
2134         if (ThemeIndex == 0)
2135         {
2136             AddToResourceDictionary(DisplayIndex, pmap);
2137         }
2138         pPixRec++;
2139     }
2140 
2141     /* Add user pixelmap folder to pixmap group */
2142     res_info *pUserMaps = new res_info(RES_TYPE_FOLDER);
2143     pUserMaps->name = _T("Custom");
2144     pUserMaps->folder_id = CUSTOM_PIXELMAP_FOLDER;
2145     pPixGroup->Attach(pUserMaps);
2146 
2147     // Add pixelmap add item
2148     res_info* pPixelmapAdd = new res_info(RES_TYPE_ADD_PIXELMAP);
2149     pUserMaps->Attach(pPixelmapAdd);
2150 
2151     /* Add the string group */
2152 
2153     res_info *pStringGroup = new res_info(RES_TYPE_GROUP);
2154     pStringGroup->name = _T("Strings");
2155     pStringGroup->folder_id = STRING_GROUP;
2156     pGroup->next = pStringGroup;
2157 
2158     // Add string add item
2159     res_info* pStringAdd = new res_info(RES_TYPE_ADD_STRING);
2160     pStringGroup->Attach(pStringAdd);
2161 
2162     /* create a string table instance */
2163     if (!pInfo->stable)
2164     {
2165         pInfo->stable = new string_table();
2166         pInfo->stable->Initialize(1, 1);
2167     }
2168 }
2169 
2170 ///////////////////////////////////////////////////////////////////////////////
CountResources(int DisplayIndex,int type) const2171 int studiox_project::CountResources(int DisplayIndex, int type) const
2172 {
2173     switch(type)
2174     {
2175     case RES_TYPE_COLOR:
2176         return color_dictionary[DisplayIndex].GetCount();
2177 
2178     case RES_TYPE_FONT:
2179         return font_dictionary[DisplayIndex].GetCount();
2180 
2181     case RES_TYPE_PIXELMAP:
2182         return pixelmap_dictionary[DisplayIndex].GetCount();
2183 
2184     default:
2185         return 0;
2186     }
2187 }
2188 
2189 ///////////////////////////////////////////////////////////////////////////////
LockUlockWidgetPositions(BOOL lock)2190 void studiox_project::LockUlockWidgetPositions(BOOL lock)
2191 {
2192     mHeader.is_widget_position_locked = lock;
2193     SetModified();
2194 }
2195 
2196 ///////////////////////////////////////////////////////////////////////////////
AddLanguage(int name_index)2197 int studiox_project::AddLanguage(int name_index)
2198 {
2199     int target_table_column = mHeader.num_languages;
2200 
2201     for (int display = 0; display < MAX_DISPLAYS; display++)
2202     {
2203         if (mDisplays[display].stable != NULL)
2204         {
2205             mDisplays[display].stable->AddLanguage();
2206         }
2207     }
2208     mHeader.num_languages += 1;
2209     mHeader.languages[target_table_column].name = config_languages_dlg::GetLanguageName(name_index);
2210     return target_table_column;
2211 }
2212 
2213 ///////////////////////////////////////////////////////////////////////////////
AddCustomColor(GX_COLOR color,CString & name,res_info * parent)2214 res_info *studiox_project::AddCustomColor(GX_COLOR color, CString &name, res_info *parent)
2215 {
2216     res_info *newcolor = NULL;
2217 
2218     GX_DISPLAY *display = get_target_view_display();
2219 
2220     int display_index = GetDisplayIndex(parent);
2221 
2222     newcolor = new res_info(RES_TYPE_COLOR);
2223     newcolor->colorval = color;
2224     newcolor->name = name;
2225     newcolor->compress = FALSE;
2226     newcolor->is_default = FALSE;
2227     parent->Attach(newcolor);
2228     AddToResourceDictionary(display_index, newcolor);
2229     SetModified();
2230 
2231     return newcolor;
2232 }
2233 
2234 ///////////////////////////////////////////////////////////////////////////////
DeleteResource(res_info * which)2235 void studiox_project::DeleteResource(res_info *which)
2236 {
2237     res_info *parent;
2238     res_info *previous;
2239 
2240     parent = which->parent;
2241 
2242     if (parent)
2243     {
2244         if (which->parent->child == which)
2245         {
2246             // first child of parent, the easy case
2247             which->parent->child = which->next;
2248         }
2249         else
2250         {
2251             // not first child, find previous sib:
2252             previous = which->parent->child;
2253             while(previous->next != which)
2254             {
2255                 previous = previous->next;
2256             }
2257             previous->next = which->next;
2258         }
2259     }
2260 
2261     int display = GetDisplayIndex(which);
2262     which->parent = NULL;
2263     which->next = NULL;
2264 
2265     if (display >= 0)
2266     {
2267         if (parent && (parent->type == RES_TYPE_FOLDER))
2268         {
2269             // if parent is a folder, loop resources from folder group
2270             parent = parent->parent;
2271         }
2272 
2273         RemoveFromResourceDictionary(display, which);
2274     }
2275     delete which;
2276     SetModified();
2277 }
2278 
2279 ///////////////////////////////////////////////////////////////////////////////
CountEnabledThemes(int DisplayIndex) const2280 int studiox_project::CountEnabledThemes(int DisplayIndex) const
2281 {
2282     USHORT count = 0;
2283 
2284     CCommandInfo *pCmdInfo = GetCmdInfo();
2285     BOOL enabled;
2286 
2287     for (int theme = 0; theme < mDisplays[DisplayIndex].num_themes; theme++)
2288     {
2289         if (pCmdInfo->IsNoGui())
2290         {
2291             enabled = pCmdInfo->IsThemeEnabled(mDisplays[DisplayIndex].themes[theme].theme_name);
2292         }
2293         else
2294         {
2295             enabled = mDisplays[DisplayIndex].themes[theme].enabled;
2296         }
2297 
2298         if (enabled)
2299         {
2300             count++;
2301         }
2302     }
2303 
2304     return count;
2305 }
2306 
2307 ///////////////////////////////////////////////////////////////////////////////
CountEnabledLanguages(int DisplayIndex) const2308 int studiox_project::CountEnabledLanguages(int DisplayIndex) const
2309 {
2310     USHORT count = 0;
2311 
2312     CCommandInfo *pCmdInfo = GetCmdInfo();
2313     BOOL enabled;
2314 
2315     for (int language = 0; language < mHeader.num_languages; language++)
2316     {
2317         if (pCmdInfo->IsNoGui())
2318         {
2319             enabled = pCmdInfo->IsLanguageEnabled(mHeader.languages[language].name);
2320         }
2321         else
2322         {
2323             enabled = mDisplays[DisplayIndex].gen_string_table[language];
2324         }
2325 
2326         if (enabled)
2327         {
2328             count++;
2329         }
2330     }
2331 
2332     return count;
2333 }
2334 
2335 ///////////////////////////////////////////////////////////////////////////////
CountEnabledDisplays() const2336 int studiox_project::CountEnabledDisplays() const
2337 {
2338     USHORT count = 0;
2339 
2340     CCommandInfo *pCmdInfo = GetCmdInfo();
2341     BOOL enabled;
2342 
2343     for (int display = 0; display < mHeader.num_displays; display++)
2344     {
2345         if (pCmdInfo->IsNoGui())
2346         {
2347             enabled = pCmdInfo->IsDisplayEnabled(mDisplays[display].name);
2348         }
2349         else
2350         {
2351             enabled = mDisplays[display].enabled;
2352         }
2353 
2354         if (enabled)
2355         {
2356             count++;
2357         }
2358     }
2359 
2360     return count;
2361 }
2362 
2363 
2364 ///////////////////////////////////////////////////////////////////////////////
CountStaticallyDefinedThemes(int display)2365 int studiox_project::CountStaticallyDefinedThemes(int display)
2366 {
2367     int count = 0;
2368     display_info *info = &mDisplays[display];
2369     for (int index = 0; index < info->num_themes; index++)
2370     {
2371         if (info->themes[index].statically_defined)
2372         {
2373             count++;
2374         }
2375     }
2376 
2377     return count;
2378 }
2379 
2380 ///////////////////////////////////////////////////////////////////////////////
CountStaticallyDefinedLanguages()2381 int studiox_project::CountStaticallyDefinedLanguages()
2382 {
2383     int count = 0;
2384     for (int index = 0; index < mHeader.num_languages; index++)
2385     {
2386         if (mHeader.languages[index].statically_defined)
2387         {
2388             count++;
2389         }
2390     }
2391 
2392     return count;
2393 }
2394 
2395 ///////////////////////////////////////////////////////////////////////////////
DeleteFolder(folder_info * folder)2396 void studiox_project::DeleteFolder(folder_info *folder)
2397 {
2398     int display_index = GetDisplayIndex(folder);
2399     folder_info *folder_item = mDisplays[display_index].GetFirstChildFolder();
2400 
2401     if (folder_item == folder)
2402     {
2403         folder_info *next = folder->GetNextFolder();
2404         mDisplays[display_index].SetFirstChildFolder(next);
2405     }
2406     else
2407     {
2408         folder_info *pre = NULL;
2409 
2410         while (folder_item)
2411         {
2412             if (folder_item->GetNextFolder() == folder)
2413             {
2414                 folder_item->SetNextFolder(folder->GetNextFolder());
2415                 break;
2416             }
2417             folder_item = folder_item->GetNextFolder();
2418         }
2419     }
2420 
2421     folder->SetNextFolder(NULL);
2422     delete folder;
2423     SetModified();
2424 }
2425 
2426 ///////////////////////////////////////////////////////////////////////////////
DeleteWidget(widget_info * which)2427 void studiox_project::DeleteWidget(widget_info *which)
2428 {
2429     widget_info *parent_info = NULL;
2430     parent_info = FindParentInfo(which);
2431 
2432     if (parent_info)
2433     {
2434         if (parent_info->GetChildWidgetInfo() == which)
2435         {
2436             // first child of parent, the easy case
2437             parent_info->SetChildWidgetInfo(which->GetNextWidgetInfo());
2438         }
2439         else
2440         {
2441             // not first child, find previous sib:
2442             widget_info *previous;
2443             previous = parent_info->GetChildWidgetInfo();
2444             while (previous->GetNextWidgetInfo() != which)
2445             {
2446                 previous = previous->GetNextWidgetInfo();
2447             }
2448             previous->SetNextWidgetInfo(which->GetNextWidgetInfo());
2449         }
2450     }
2451     else
2452     {
2453         // here if we don't have parent info, should be a top-level widget.
2454         // unlink it from its parent folder
2455         folder_info *widget_folder;
2456         widget_info *current;
2457 
2458         widget_folder = FindParentFolderInfo(which);
2459 
2460         if (widget_folder)
2461         {
2462             widget_info *prev = NULL;
2463             current = widget_folder->GetFirstChildWidget();
2464             while (current)
2465             {
2466                 if (current == which)
2467                 {
2468                     if (prev)
2469                     {
2470                         prev->SetNextWidgetInfo(which->GetNextWidgetInfo());
2471                     }
2472                     else
2473                     {
2474                         widget_folder->SetFirstChildWidget(which->GetNextWidgetInfo());
2475                     }
2476                     break;
2477                 }
2478                 prev = current;
2479                 current = current->GetNextWidgetInfo();
2480             }
2481         }
2482     }
2483 
2484     which->SetNextWidgetInfo(NULL);
2485     delete which;
2486 
2487     SetModified();
2488 }
2489 
2490 ///////////////////////////////////////////////////////////////////////////////
AddFolderToDisplay(int DisplayIndex,folder_info * info)2491 void studiox_project::AddFolderToDisplay(int DisplayIndex, folder_info *info)
2492 {
2493     if (DisplayIndex < MAX_DISPLAYS)
2494     {
2495         folder_info *next = mDisplays[DisplayIndex].GetFirstChildFolder();
2496         info->SetNextFolder(next);
2497         mDisplays[DisplayIndex].SetFirstChildFolder(info);
2498         GetProjectView()->InsertFolder(info);
2499         SetModified();
2500     }
2501 }
2502 
2503 ///////////////////////////////////////////////////////////////////////////////
IsPaletteMode(int display) const2504 BOOL studiox_project::IsPaletteMode(int display) const
2505 {
2506     if (display < MAX_DISPLAYS)
2507     {
2508         if (mDisplays[display].colorformat == GX_COLOR_FORMAT_8BIT_PALETTE)
2509         {
2510             return TRUE;
2511         }
2512     }
2513     return FALSE;
2514 }
2515 
2516 
2517 ///////////////////////////////////////////////////////////////////////////////
AddWidgetToFolder(folder_info * folder,widget_info * info)2518 void studiox_project::AddWidgetToFolder(folder_info *folder, widget_info *info)
2519 {
2520     project_view *pview = GetProjectView();
2521 
2522     if (!pview)
2523     {
2524         return;
2525     }
2526 
2527     if (info->GetNextWidgetInfo())
2528     {
2529         pview->InsertTreeChild(folder, info);
2530 
2531         widget_info *last = info;
2532         while(last->GetNextWidgetInfo())
2533         {
2534             last = last->GetNextWidgetInfo();
2535         }
2536         last->SetNextWidgetInfo(folder->GetFirstChildWidget());
2537         folder->SetFirstChildWidget(info);
2538     }
2539     else
2540     {
2541         widget_info *next = folder->GetFirstChildWidget();
2542         info->SetNextWidgetInfo(next);
2543         folder->SetFirstChildWidget(info);
2544         pview->InsertTopLevelWidget(info);
2545     }
2546 
2547     SetModified();
2548 }
2549 
2550 ///////////////////////////////////////////////////////////////////////////////
IsWidgetInInfoTree(const widget_info * start,const widget_info * find) const2551 BOOL studiox_project::IsWidgetInInfoTree(const widget_info *start, const widget_info *find) const
2552 {
2553     while(start)
2554     {
2555         if (start == find)
2556         {
2557             return TRUE;
2558         }
2559         if (start->GetChildWidgetInfo())
2560         {
2561             if (IsWidgetInInfoTree(start->GetChildWidgetInfo(), find))
2562             {
2563                 return TRUE;
2564             }
2565         }
2566         start = start->GetNextWidgetInfo();
2567     }
2568     return FALSE;
2569 }
2570 
2571 
2572 ///////////////////////////////////////////////////////////////////////////////
GetDisplayIndex(const folder_info * folder) const2573 int studiox_project::GetDisplayIndex(const folder_info *folder) const
2574 {
2575     for (int DisplayIndex = 0; DisplayIndex < MAX_DISPLAYS; DisplayIndex++)
2576     {
2577         folder_info *info = mDisplays[DisplayIndex].GetFirstChildFolder();
2578         while (info)
2579         {
2580             if (info == folder)
2581             {
2582                 return DisplayIndex;
2583             }
2584             info = info->GetNextFolder();
2585         }
2586     }
2587     return -1;
2588 }
2589 
2590 ///////////////////////////////////////////////////////////////////////////////
GetDisplayIndex(const widget_info * info) const2591 int studiox_project::GetDisplayIndex(const widget_info *info) const
2592 {
2593     // find out which display this widget belongs to
2594     for (int DisplayIndex = 0; DisplayIndex < MAX_DISPLAYS; DisplayIndex++)
2595     {
2596         folder_info *folder = mDisplays[DisplayIndex].GetFirstChildFolder();
2597         while(folder)
2598         {
2599             if (IsWidgetInInfoTree(folder->GetFirstChildWidget(), info))
2600             {
2601                 return DisplayIndex;
2602             }
2603             folder = folder->GetNextFolder();
2604         }
2605     }
2606     return -1;
2607 }
2608 
2609 ///////////////////////////////////////////////////////////////////////////////
GetDisplayIndex(const res_info * info) const2610 int studiox_project::GetDisplayIndex(const res_info *info) const
2611 {
2612     // find out which display this widget belongs to
2613     // get top-level node
2614     while(info->parent)
2615     {
2616         info = info->parent;
2617     }
2618 
2619     for (int DisplayIndex = 0; DisplayIndex < MAX_DISPLAYS; DisplayIndex++)
2620     {
2621         // loop through top-level nodes
2622         for(int ThemeIndex = 0; ThemeIndex < mDisplays[DisplayIndex].num_themes; ThemeIndex++)
2623         {
2624             res_info *test = mDisplays[DisplayIndex].themes[ThemeIndex].GetFirstResourceInfo();
2625             while (test)
2626             {
2627                 if (test == info)
2628                 {
2629                     return DisplayIndex;
2630                 }
2631                 test = test->next;
2632             }
2633         }
2634     }
2635     ErrorMsg("Internal Error: failed to find display associated with resource");
2636     return -1;
2637 }
2638 
2639 ///////////////////////////////////////////////////////////////////////////////
GetDisplayColorFormat(const res_info * info) const2640 int studiox_project::GetDisplayColorFormat(const res_info *info) const
2641 {
2642     int display = GetDisplayIndex(info);
2643 
2644     if (display >= 0 && display < MAX_DISPLAYS)
2645     {
2646         return mDisplays[display].colorformat;
2647     }
2648     return GX_COLOR_FORMAT_MONOCHROME;
2649 }
2650 
2651 ///////////////////////////////////////////////////////////////////////////////
AddWidgetToParent(widget_info * parent_info,widget_info * child_info)2652 void studiox_project::AddWidgetToParent(widget_info *parent_info, widget_info *child_info)
2653 {
2654     //info->next = NULL;
2655 
2656     if (!parent_info)
2657     {
2658         ErrorMsg("Internal Error: Invalid parent widget.");
2659         return;
2660     }
2661 
2662     if (parent_info->widget)
2663     {
2664         if (child_info->widget == NULL)
2665         {
2666             widget_factory::GenerateWidgets(parent_info->widget, child_info, TRUE, FALSE);
2667         }
2668     }
2669 
2670     if ((parent_info->basetype == GX_TYPE_MENU) &&
2671         (parent_info->ewi.menu.insert_as_menu_item))
2672     {
2673         if (parent_info->widget && child_info->widget)
2674         {
2675             gx_menu_insert((GX_MENU *)parent_info->widget, child_info->widget);
2676         }
2677         parent_info->ewi.menu.list_total_count++;
2678     }
2679 
2680     GetProjectView()->InsertTreeChild(parent_info, child_info);
2681 
2682     // assume the allocation type of the parent:
2683     if (mHeader.guix_version > 50000)
2684     {
2685         if (parent_info->allocation == STATICALLY_ALLOCATED)
2686         {
2687             properties_win::SetChildAllocation(child_info, STATICALLY_ALLOCATED);
2688         }
2689         else
2690         {
2691             properties_win::SetChildAllocation(child_info, DYNAMIC_ALLOCATION_CHILD);
2692         }
2693     }
2694     else
2695     {
2696         properties_win::SetChildAllocation(child_info, STATICALLY_ALLOCATED);
2697     }
2698 
2699     if (parent_info->GetChildWidgetInfo())
2700     {
2701         if ((parent_info->basetype == GX_TYPE_MENU) &&
2702             (parent_info->ewi.menu.insert_as_menu_item))
2703         {
2704             //if the inserted widget is a menu item, we should link
2705             //the widget to the last menu item
2706             int list_count = 0;
2707             int list_total_count = parent_info->ewi.menu.list_total_count;
2708 
2709             if (list_total_count == 0)
2710             {
2711                 child_info->SetNextWidgetInfo(parent_info->GetChildWidgetInfo());
2712                 parent_info->SetChildWidgetInfo(child_info);
2713             }
2714             else
2715             {
2716                 widget_info *sib = parent_info->GetChildWidgetInfo();
2717                 while (sib->GetNextWidgetInfo() && (list_count + 1 < list_total_count))
2718                 {
2719                     sib = sib->GetNextWidgetInfo();
2720                     list_count++;
2721                 }
2722                 child_info->SetNextWidgetInfo(sib->GetNextWidgetInfo());
2723                 sib->SetNextWidgetInfo(child_info);
2724             }
2725         }
2726         else
2727         {
2728             widget_info *sib = parent_info->GetChildWidgetInfo();
2729             while (sib->GetNextWidgetInfo())
2730             {
2731                 sib = sib->GetNextWidgetInfo();
2732             }
2733             sib->SetNextWidgetInfo(child_info);
2734         }
2735     }
2736     else
2737     {
2738         parent_info->SetChildWidgetInfo(child_info);
2739     }
2740 
2741     SetModified();
2742 }
2743 
2744 ///////////////////////////////////////////////////////////////////////////////
MoveInfoToFront(widget_info * info)2745 void studiox_project::MoveInfoToFront(widget_info *info)
2746 {
2747     if (info->GetNextWidgetInfo() == NULL)
2748     {
2749         // nothing to do
2750         return;
2751     }
2752     // Move to front actually means we want this widget to be last in list:
2753     widget_info *parent = FindParentInfo(info);
2754     widget_info *previous = NULL;
2755 
2756     if (parent)
2757     {
2758         if (parent->GetChildWidgetInfo() == info)
2759         {
2760             parent->SetChildWidgetInfo(info->GetNextWidgetInfo());
2761         }
2762 
2763         // remove from linked list
2764         previous = parent->GetChildWidgetInfo();
2765         while(previous->GetNextWidgetInfo())
2766         {
2767             if (previous->GetNextWidgetInfo() == info)
2768             {
2769                 previous->SetNextWidgetInfo(info->GetNextWidgetInfo());
2770             }
2771             previous = previous->GetNextWidgetInfo();
2772         }
2773         // and link at tail position
2774         previous->SetNextWidgetInfo(info);
2775         info->SetNextWidgetInfo(NULL);
2776         SetModified();
2777     }
2778 }
2779 
2780 ///////////////////////////////////////////////////////////////////////////////
MoveInfoToBack(widget_info * info)2781 void studiox_project::MoveInfoToBack(widget_info *info)
2782 {
2783     // Move to back actually means we want this widget to be first in child list:
2784     widget_info *parent = FindParentInfo(info);
2785     widget_info *previous = NULL;
2786 
2787     if (parent)
2788     {
2789         if (parent->GetChildWidgetInfo() == info)
2790         {
2791            // already in back, return
2792             return;
2793         }
2794 
2795         // remove from linked list
2796         previous = parent->GetChildWidgetInfo();
2797         while(previous->GetNextWidgetInfo())
2798         {
2799             if (previous->GetNextWidgetInfo() == info)
2800             {
2801                 previous->SetNextWidgetInfo(info->GetNextWidgetInfo());
2802                 break;
2803             }
2804             previous = previous->GetNextWidgetInfo();
2805         }
2806         // link at list head
2807         info->SetNextWidgetInfo(parent->GetChildWidgetInfo());
2808         parent->SetChildWidgetInfo(info);
2809         SetModified();
2810     }
2811 }
2812 
2813 ///////////////////////////////////////////////////////////////////////////////
WritePaletteType(xml_writer & writer,res_info * res)2814 void studiox_project::WritePaletteType(xml_writer &writer, res_info *res)
2815 {
2816     switch(res->palette_type)
2817     {
2818     case PALETTE_TYPE_PRIVATE:
2819         writer.WriteString("palette_type", "Private");
2820         break;
2821 
2822     case PALETTE_TYPE_SHARED:
2823         writer.WriteString("palette_type", "Shared");
2824         break;
2825 
2826     case PALETTE_TYPE_NONE:
2827     default:
2828         writer.WriteString("palette_type", "None");
2829         break;
2830     }
2831 }
2832 
2833 
2834 
2835 ///////////////////////////////////////////////////////////////////////////////
WriteOneResource(xml_writer & writer,res_info * res,GX_BOOL xml_mode)2836 void studiox_project::WriteOneResource(xml_writer &writer, res_info *res, GX_BOOL xml_mode)
2837 {
2838     int page_count;
2839 
2840     writer.WriteString("type", ResTypeToString(res->type));
2841     writer.WriteString("name", res->name);
2842     writer.WritePathInfo(res->pathinfo);
2843 
2844     if(!xml_mode)
2845     {
2846         writer.WriteBool("is_default", res->is_default);
2847         writer.WriteBool("enabled", res->enabled);
2848     }
2849     writer.WriteBool("compress", res->compress);
2850 
2851     switch(res->type)
2852     {
2853     case RES_TYPE_PIXELMAP:
2854         writer.WriteBool("alpha", res->keep_alpha);
2855         writer.WriteBool("dither", res->dither);
2856         writer.WriteBool("raw", res->raw);
2857         writer.WriteString("color_format", resource_gen::GetColorFormatName(res->output_color_format));
2858         if (!xml_mode)
2859         {
2860             writer.WriteBool("output_file_enabled", res->output_file_enabled);
2861             writer.WriteString("output_file", res->output_file);
2862             writer.WriteBool("binary_mode", res->binary_mode);
2863         }
2864         WritePaletteType(writer, res);
2865         break;
2866 
2867     case RES_TYPE_COLOR:
2868         writer.WriteUnsigned("colorval", res->colorval);
2869         break;
2870 
2871     case RES_TYPE_FONT:
2872         writer.WriteInt("height", res->font_height);
2873         writer.WriteInt("font_bits", res->font_bits);
2874         writer.WriteBool("font_kerning", res->font_kerning);
2875 
2876         page_count = NUM_FONT_CHAR_RANGES;
2877 
2878         if (res->font_support_extended_unicode)
2879         {
2880             page_count += NUM_FONT_EXTENDED_CHAR_RANGES;
2881         }
2882 
2883         if (xml_mode)
2884         {
2885             for (int loop = 0; loop < page_count; loop++)
2886             {
2887                 if (res->font_pages[loop].enabled)
2888                 {
2889                     writer.OpenTag("font_page_data");
2890                     writer.WriteInt("first_char", res->font_pages[loop].first_char);
2891                     writer.WriteInt("last_char", res->font_pages[loop].last_char);
2892                     writer.CloseTag("font_page_data");
2893                 }
2894             }
2895         }
2896         else
2897         {
2898             writer.WriteBool("font_include_st_glyphs", res->font_charset_include_string_table);
2899             writer.WriteBool("font_support_extended_unicode", res->font_support_extended_unicode);
2900             writer.WriteBool("output_file_enabled", res->output_file_enabled);
2901             writer.WriteString("output_file", res->output_file);
2902             writer.WriteBool("binary_mode", res->binary_mode);
2903 
2904             writer.OpenTag("font_page_data");
2905 
2906             for (int loop = 0; loop < page_count; loop++)
2907             {
2908                 writer.WriteBool("enabled", res->font_pages[loop].enabled);
2909                 writer.WriteInt("first_char", res->font_pages[loop].first_char);
2910                 writer.WriteInt("last_char", res->font_pages[loop].last_char);
2911             }
2912             writer.CloseTag("font_page_data");
2913         }
2914         break;
2915 
2916     case RES_TYPE_ADD_COLOR:
2917     case RES_TYPE_ADD_FONT:
2918     case RES_TYPE_ADD_PIXELMAP:
2919     case RES_TYPE_ADD_STRING:
2920         break;
2921 
2922     default:
2923         writer.WriteString("folder_id", FindFolderIdString(res->type, res->folder_id));
2924         break;
2925     }
2926 }
2927 
2928 ///////////////////////////////////////////////////////////////////////////////
WriteThemeScrollbars(xml_writer & writer,int display,int theme)2929 void studiox_project::WriteThemeScrollbars(xml_writer &writer, int display, int theme)
2930 {
2931     display_info *info = &mDisplays[display];
2932 
2933     writer.OpenTag("vscroll_appearance");
2934     vscroll_service_provider::WriteScrollbarAppearance(writer, this, display, info->themes[theme].VScrollAppearance);
2935     writer.WriteUnsigned("scroll_style", info->themes[theme].VScrollStyle);
2936     writer.CloseTag("vscroll_appearance");
2937 
2938     writer.OpenTag("hscroll_appearance");
2939     vscroll_service_provider::WriteScrollbarAppearance(writer, this, display, info->themes[theme].HScrollAppearance);
2940     writer.WriteUnsigned("scroll_style", info->themes[theme].HScrollStyle);
2941     writer.CloseTag("hscroll_appearance");
2942 }
2943 
2944 ///////////////////////////////////////////////////////////////////////////////
WriteResources(xml_writer & writer,res_info * start,GX_BOOL xml_mode)2945 void studiox_project::WriteResources(xml_writer &writer, res_info *start, GX_BOOL xml_mode)
2946 {
2947     /* KGM notes:
2948 
2949         I decided to just write out ALL of the resource values, even
2950         if I don't think we will use the saved values for things like
2951         fixed colors. I think it's better to just have the writer save
2952         everything, and then the reader can pick and choose what it
2953         will use from the saved data. So if you notice that the reader is
2954         not using the Fixed color folder when it reads in a project, that's
2955         OK, that's how it's supposed to work.
2956     */
2957 
2958     while(start)
2959     {
2960         if (!xml_mode || start->type == RES_TYPE_FONT || start->type == RES_TYPE_PIXELMAP)
2961         {
2962             writer.OpenTag("resource");
2963 
2964             WriteOneResource(writer, start, xml_mode);
2965         }
2966 
2967         if (start->child)
2968         {
2969             WriteResources(writer, start->child, xml_mode);
2970         }
2971 
2972         if (!xml_mode || start->type == RES_TYPE_FONT || start->type == RES_TYPE_PIXELMAP)
2973         {
2974             writer.CloseTag("resource");
2975         }
2976         start = start->next;
2977     }
2978 }
2979 
2980 ///////////////////////////////////////////////////////////////////////////////
WriteThemePaletteInfo(xml_writer & writer,theme_info * theme,BOOL xml_mode)2981 void studiox_project::WriteThemePaletteInfo(xml_writer& writer, theme_info *theme, BOOL xml_mode)
2982 {
2983 int palette_index;
2984 GX_COLOR* pal;
2985 
2986     writer.OpenTag("palette");
2987     writer.WriteInt("total_size", theme->palette_total_size);
2988     if (!xml_mode)
2989     {
2990         writer.WriteInt("predefined", theme->palette_predefined);
2991     }
2992     pal = theme->palette;
2993 
2994     for (palette_index = 0; palette_index < theme->palette_predefined; palette_index++)
2995     {
2996         writer.WriteUnsigned("rgb", *pal);
2997         pal++;
2998     }
2999     writer.CloseTag("palette");
3000 }
3001 
3002 ///////////////////////////////////////////////////////////////////////////////
WriteDisplayInfo(xml_writer & writer,int display_index)3003 void studiox_project::WriteDisplayInfo(xml_writer &writer, int display_index)
3004 {
3005 
3006     display_info *pInfo = &mDisplays[display_index];
3007     writer.OpenTag("display_info");
3008     writer.WriteInt("display_index", display_index);
3009     writer.WriteString("display_name", pInfo->name);
3010     writer.WriteInt("xres", pInfo->xres);
3011     writer.WriteInt("yres", pInfo->yres);
3012     writer.WriteInt("bits_per_pix", pInfo->bits_per_pix);
3013     writer.WriteBool("packed_format", pInfo->packed_format);
3014     writer.WriteBool("format_555", pInfo->format_555);
3015     writer.WriteBool("format_4444", pInfo->format_4444);
3016     writer.WriteBool("format_332", pInfo->format_332);
3017     writer.WriteBool("grayscale", pInfo->grayscale);
3018     writer.WriteBool("reverse_order", pInfo->reverse_order);
3019     writer.WriteBool("allocate_canvas", pInfo->allocate_canvas);
3020     writer.WriteBool("enabled", pInfo->enabled);
3021     writer.WriteString("rotation_angle", ProjectConfigDlg::FindScreenRotationName(pInfo->rotation_angle));
3022     writer.WriteBool("default_map_format", pInfo->default_map_format);
3023 
3024     writer.OpenTag("theme_info");
3025     writer.WriteInt("num_themes", pInfo->num_themes);
3026     writer.WriteInt("active_theme", pInfo->active_theme);
3027 
3028     for (int theme = 0; theme < pInfo->num_themes; theme++)
3029     {
3030         writer.WriteString("theme_name", pInfo->themes[theme].theme_name);
3031         writer.WriteBool("gen_color_table", pInfo->themes[theme].gen_color_table);
3032         writer.WriteBool("gen_font_table", pInfo->themes[theme].gen_font_table);
3033         writer.WriteBool("gen_pixelmap_table", pInfo->themes[theme].gen_pixelmap_table);
3034         writer.WriteBool("enabled", pInfo->themes[theme].enabled);
3035         writer.WriteBool("statically_defined", pInfo->themes[theme].statically_defined);
3036         writer.OpenTag("theme_data");
3037 
3038         WriteResources(writer, pInfo->themes[theme].GetFirstResourceInfo());
3039         WriteThemeScrollbars(writer, display_index, theme);
3040 
3041         if (pInfo->themes[theme].palette)
3042         {
3043             WriteThemePaletteInfo(writer, &pInfo->themes[theme]);
3044         }
3045 
3046         writer.CloseTag("theme_data");
3047     }
3048     writer.CloseTag("theme_info");
3049 
3050     for (int index = 0; index < mHeader.num_languages; index++)
3051     {
3052         writer.WriteBool(CT2A(mHeader.languages[index].name), mDisplays[display_index].gen_string_table[index]);
3053     }
3054 
3055     if (display_index < mHeader.num_displays)
3056     {
3057         WriteStringTable(writer, pInfo->stable);
3058         WriteScreenFlow(writer, pInfo->screenflow);
3059     }
3060     widget_writer::WriteWidgetFolders(writer, this, display_index, pInfo->GetFirstChildFolder());
3061 
3062     writer.CloseTag("display_info");
3063 }
3064 
3065 ///////////////////////////////////////////////////////////////////////////////
WriteStringTable(xml_writer & writer,string_table * table)3066 void studiox_project::WriteStringTable(xml_writer &writer, string_table *table)
3067 {
3068     int string_id;
3069     int num_strings;
3070     int language;
3071     string_table_record record;
3072     CString id_name;
3073 
3074     writer.OpenTag("string_table");
3075     if (table)
3076     {
3077         num_strings = table->CountStrings();
3078         writer.WriteInt("sort_column", table->GetSortColumn());
3079         writer.WriteInt("num_strings", num_strings);
3080         writer.WriteInt("num_languages", table->CountLanguages());
3081 
3082         if (table->CountLanguages() != mHeader.num_languages)
3083         {
3084             ErrorMsg("Internal Error: Language count discrepency");
3085         }
3086 
3087         for (string_id = 1; string_id < num_strings; string_id++)
3088         {
3089             id_name = table->GetResourceIdName(string_id);
3090             record = table->GetRecord(id_name);
3091             writer.OpenTag("string_record");
3092             writer.WriteString("id", record.id_name);
3093             writer.WriteInt("font", record.font_id);
3094             writer.WriteString("notes", record.notes);
3095 
3096             for (language = 0; language < table->CountLanguages(); language++)
3097             {
3098                 writer.WriteString("val", record.strings[language], TRUE);
3099             }
3100             writer.CloseTag("string_record");
3101         }
3102     }
3103 
3104     writer.CloseTag("string_table");
3105 }
3106 
3107 ///////////////////////////////////////////////////////////////////////////////
WriteScreenFlow(xml_writer & writer,screen_flow * screen_flow)3108 void studiox_project::WriteScreenFlow(xml_writer &writer, screen_flow *screen_flow)
3109 {
3110 
3111     if (screen_flow)
3112     {
3113 
3114         int index;
3115 
3116         writer.OpenTag("screen_flow");
3117 
3118         flow_item *item;
3119 
3120         writer.WriteInt("scale", screen_flow->GetScale());
3121 
3122         for (index = 0; index < screen_flow->GetFlowListCount(); index++)
3123         {
3124             item = screen_flow->GetFlowItem(index);
3125             WriteFlowItem(writer, item);
3126         }
3127         writer.CloseTag("screen_flow");
3128     }
3129 }
3130 
3131 ///////////////////////////////////////////////////////////////////////////////
WriteFlowItem(xml_writer & writer,flow_item * item)3132 void studiox_project::WriteFlowItem(xml_writer &writer, flow_item *item)
3133 {
3134     if (item)
3135     {
3136         GX_RECTANGLE rect;
3137         rect.gx_rectangle_left = (GX_VALUE)item->rect.left;
3138         rect.gx_rectangle_top = (GX_VALUE)item->rect.top;
3139         rect.gx_rectangle_right = (GX_VALUE)item->rect.right;
3140         rect.gx_rectangle_bottom = (GX_VALUE)item->rect.bottom;
3141 
3142         writer.OpenTag("flow_item");
3143         writer.WriteString("screen_name", item->screen_name);
3144         writer.WriteRect("rect", rect);
3145         writer.WriteBool("enabled", item->enabled);
3146 
3147         trigger_info *trigger = item->trigger_list;
3148 
3149         WriteTriggerInfo(writer, trigger);
3150 
3151         writer.CloseTag("flow_item");
3152     }
3153 }
3154 
3155 ///////////////////////////////////////////////////////////////////////////////
WriteTriggerInfo(xml_writer & writer,trigger_info * trigger)3156 void studiox_project::WriteTriggerInfo(xml_writer &writer, trigger_info *trigger)
3157 {
3158     CArray<action_info *> *action_list;
3159     action_info *action;
3160     int id;
3161 
3162     while (trigger)
3163     {
3164         CString type_name;
3165 
3166         writer.OpenTag("trigger_info");
3167         writer.WriteString("trigger_name", trigger->trigger_name);
3168         writer.WriteString("signal_id_name", trigger->signal_id_name);
3169         type_name = trigger_edit_dlg::GetTriggerTypeName(trigger->trigger_type);
3170         writer.WriteString("trigger_type", type_name);
3171         type_name = trigger_edit_dlg::GetEventTypeName(trigger->event_type);
3172         writer.WriteString("event_type", type_name);
3173         writer.WriteString("system_event_animat_id_name", trigger->system_event_animat_id_name);
3174         writer.WriteString("user_event_id_name", trigger->user_event_id_name);
3175 
3176 
3177         writer.OpenTag("action_list");
3178 
3179         action_list = &trigger->action_list;
3180 
3181         for (int count = 0; count < action_list->GetCount(); count++)
3182         {
3183             action = action_list->GetAt(count);
3184             writer.OpenTag("action_info");
3185             writer.WriteString("action_name", action->action_name);
3186             type_name = trigger_action_select_dlg::GetActionTypeName(action->action_type);
3187             writer.WriteString("action_type", type_name);
3188             writer.WriteString("target_widget_name", action->target_widget_name);
3189             writer.WriteString("parent_widget_name", action->parent_widget_name);
3190             writer.WriteString("animation_id_name", action->animation_id_name);
3191             writer.WriteBool("target_show_child_widgets", action->target_show_child_widgets);
3192             writer.WriteBool("parent_show_child_widgets", action->parent_show_child_widgets);
3193 
3194             if (action->animation)
3195             {
3196                 writer.OpenTag("animation_info");
3197                 writer.WriteInt("start_x", action->animation->gx_animation_start_position.gx_point_x);
3198                 writer.WriteInt("start_y", action->animation->gx_animation_start_position.gx_point_y);
3199                 writer.WriteInt("end_x", action->animation->gx_animation_end_position.gx_point_x);
3200                 writer.WriteInt("end_y", action->animation->gx_animation_end_position.gx_point_y);
3201                 writer.WriteUByte("steps", action->animation->gx_animation_steps);
3202                 writer.WriteUnsigned("frame_interval", action->animation->gx_animation_frame_interval);
3203                 writer.WriteUnsigned("start_delay", action->animation->gx_animation_start_delay);
3204                 writer.WriteUByte("start_alpha", action->animation->gx_animation_start_alpha);
3205                 writer.WriteUByte("end_alpha", action->animation->gx_animation_end_alpha);
3206                 writer.WriteBool("detach_target", action->animation->gx_animation_style & GX_ANIMATION_DETACH);
3207                 writer.WriteBool("push_target", action->animation->gx_animation_style & GX_ANIMATION_PUSH_STACK);
3208 
3209                 id = action->animation->gx_animation_style & GX_ANIMATION_EASING_FUNC_MASK;
3210                 writer.WriteString("easing_func_id_name", easing_function_select_dlg::GetEasingFuncIdName(id));
3211                 writer.CloseTag("animation_info");
3212             }
3213             writer.CloseTag("action_info");
3214         }
3215 
3216         writer.CloseTag("action_list");
3217 
3218         writer.CloseTag("trigger_info");
3219         trigger = trigger->next;
3220     }
3221 }
3222 
3223 ///////////////////////////////////////////////////////////////////////////////
WriteProjectHeader(xml_writer & writer)3224 void studiox_project::WriteProjectHeader(xml_writer &writer)
3225 {
3226     int index;
3227 
3228     writer.OpenTag("header");
3229     writer.WriteInt("project_version", mHeader.project_version);
3230     writer.WriteInt("guix_version", mHeader.guix_version);
3231     writer.WriteInt("studio_version", mHeader.studio_version);
3232 
3233     writer.WriteString("project_name", mHeader.project_name);
3234     writer.WriteString("source_path", mHeader.source_path);
3235     writer.WriteString("header_path", mHeader.header_path);
3236     writer.WriteString("resource_path", mHeader.resource_path);
3237     writer.WriteString("allocator_function", mHeader.malloc_name);
3238     writer.WriteString("free_function", mHeader.free_name);
3239     writer.WriteString("additional_headers", mHeader.additional_headers);
3240     writer.WriteBool("insert_headers_before", mHeader.insert_headers_before);
3241 
3242     writer.WriteInt("target_cpu", mHeader.target_cpu);
3243     writer.WriteInt("target_tools", mHeader.target_tools);
3244     writer.WriteBool("big_endian", mHeader.big_endian);
3245     writer.WriteBool("dave2d_graph_accelerator", mHeader.dave2d_graph_accelerator);
3246     writer.WriteInt("renesas_jpeg_decoder", mHeader.renesas_jpeg_decoder);
3247     writer.WriteInt("renesas_png_decoder", mHeader.renesas_png_decoder);
3248 
3249     writer.WriteBool("grid_enabled", mHeader.grid_enabled);
3250     writer.WriteBool("snap_enabled", mHeader.snap_enabled);
3251     writer.WriteBool("snap_to_widget_enabled", mHeader.snap_to_widget_enabled);
3252     writer.WriteInt("grid_spacing", mHeader.grid_spacing);
3253     writer.WriteInt("snap_spacing", mHeader.snap_spacing);
3254 
3255     writer.WriteBool("gen_binary", mHeader.gen_binary);
3256     writer.WriteUnsigned("binary_file_format", mHeader.binary_file_format);
3257     writer.WriteUnsigned("memory_offset", mHeader.memory_offset);
3258     writer.WriteBool("gen_res_header", mHeader.gen_res_header);
3259 
3260     writer.WriteBool("custom_resource_enabled", mHeader.custom_resource_enabled);
3261     writer.WriteString("custom_resource_file_name", mHeader.custom_resource_file_name);
3262     writer.WriteInt("app_execute_xpos", mHeader.app_execute_xpos);
3263     writer.WriteInt("app_execute_ypos", mHeader.app_execute_ypos);
3264     writer.WriteBool("is_widget_position_locked", mHeader.is_widget_position_locked);
3265     writer.WriteInt("palette_mode_aa_text_colors", mHeader.palette_mode_aa_text_colors);
3266 
3267     writer.WriteInt("num_displays", mHeader.num_displays);
3268     writer.WriteInt("max_displays", mHeader.max_displays);
3269     writer.WriteInt("num_languages", mHeader.num_languages);
3270     writer.OpenTag("language_names");
3271 
3272     for (index = 0; index < mHeader.num_languages; index++)
3273     {
3274         writer.WriteString("language", mHeader.languages[index].name);
3275         writer.WriteBool("support_bidi_text", mHeader.languages[index].support_bidi_text);
3276         writer.WriteBool("gen_reordered_bidi_text", mHeader.languages[index].gen_reordered_bidi_text);
3277         writer.WriteBool("support_thai_glyph_shaping", mHeader.languages[index].support_thai_glyph_shaping);
3278         writer.WriteBool("gen_adjusted_thai_string", mHeader.languages[index].gen_adjusted_thai_string);
3279         writer.WriteBool("statically_defined", mHeader.languages[index].statically_defined);
3280     }
3281     writer.CloseTag("language_names");
3282 
3283     writer.OpenTag("string_export");
3284     writer.WriteInt("string_export_src", mHeader.string_export_src);
3285     writer.WriteInt("string_export_target", mHeader.string_export_target);
3286     writer.WriteInt("string_export_version", mHeader.string_export_version);
3287     writer.WriteString("string_export_path", mHeader.string_export_path);
3288     writer.WriteString("string_export_name", mHeader.string_export_filename);
3289 
3290     CString file_typename = string_export_dlg::GetStringExportTypeName(mHeader.string_export_filetype);
3291     writer.WriteString("string_export_filetype", file_typename);
3292     writer.CloseTag("string_export");
3293 
3294     writer.CloseTag("header");
3295 }
3296 
3297 ///////////////////////////////////////////////////////////////////////////////
Save()3298 BOOL studiox_project::Save()
3299 {
3300     if (GetPropsWin())
3301     {
3302         //send a kill focus message to the current focus owner.
3303         GetPropsWin()->SendEditFocusLoseMessage();
3304     }
3305 
3306     CString pathname = mHeader.project_path;
3307     pathname += "\\";
3308     pathname += mHeader.project_name;
3309 
3310     pathname += ".gxp";
3311     xml_writer writer;
3312     if (!writer.OpenFile(pathname))
3313     {
3314 
3315         ErrorMsg("Unable to open project file.");
3316         return FALSE;
3317     }
3318 
3319     writer.WriteHeader("GUIX_Studio_Project");
3320     writer.OpenTag("project");
3321     WriteProjectHeader(writer);
3322 
3323     for (int index = 0; index < mHeader.max_displays; index++)
3324     {
3325         WriteDisplayInfo(writer, index);
3326     }
3327     writer.CloseTag("project");
3328     writer.CloseFile();
3329     is_modified = FALSE;
3330     return TRUE;
3331 }
3332 
3333 ///////////////////////////////////////////////////////////////////////////////
SaveAs()3334 BOOL studiox_project::SaveAs()
3335 {
3336     CString old_pathname = mHeader.project_path;
3337     CString old_project_name = mHeader.project_name;
3338 
3339     TCHAR SavePathname[MAX_PATH];
3340     TCHAR FileName[MAX_PATH];
3341 
3342     SavePathname[0] = 0;
3343     FileName[0] = 0;
3344     _tcscpy(SavePathname, mHeader.project_name.GetBuffer());
3345 
3346     if (GetOutputFileName(SavePathname, FileName,
3347                           _T("Save Project As"),
3348                           _T("GUIX Studio Projects\0*.gxp\0\0"),
3349                           mHeader.project_path.GetBuffer(),
3350                           _T("gxp")))
3351     {
3352 
3353         UndoManager()->Reset();
3354         CString new_path(SavePathname);
3355         CString new_name(FileName);
3356         new_path = new_path.Left(new_path.GetLength() - new_name.GetLength());
3357         new_path.TrimRight('\\');
3358 
3359         // string the extension
3360         new_name = new_name.Left(new_name.GetLength() - 4);
3361         mHeader.project_path = new_path;
3362         mHeader.project_name = new_name;
3363         BOOL val = Save();
3364         //SetProjectDirectory(new_path);
3365 
3366         // KGM- restore original path and name, in case they saved it somewhere else we don't
3367         // want everything to be broken
3368         mHeader.project_path = old_pathname;
3369         mHeader.project_name = old_project_name;
3370         return val;
3371     }
3372     return FALSE;
3373 }
3374 
3375 ///////////////////////////////////////////////////////////////////////////////
GetResourceType(res_info * start)3376 int studiox_project::GetResourceType(res_info* start)
3377 {
3378     while (start)
3379     {
3380         switch (start->type)
3381         {
3382         case RES_TYPE_GROUP:
3383         case RES_TYPE_FOLDER:
3384             return GetResourceType(start->child);
3385         case RES_TYPE_PIXELMAP:
3386         case RES_TYPE_FONT:
3387             return start->type;
3388         default:
3389             break;
3390         }
3391 
3392         start = start->next;
3393     }
3394 
3395     return 0;
3396 }
3397 
3398 ///////////////////////////////////////////////////////////////////////////////
GenerateResourceXml(CString & pathname,CString & filename,res_info * start)3399 void studiox_project::GenerateResourceXml(CString &pathname, CString &filename, res_info *start)
3400 {
3401     if (!start)
3402     {
3403         return;
3404     }
3405 
3406     xml_writer writer;
3407     if (!writer.OpenFile(pathname))
3408     {
3409 
3410         ErrorMsg("Unable to open xml file.");
3411     }
3412 
3413     writer.WriteHeader("GUIX_Studio_Resource");
3414 
3415     writer.OpenTag("resource_project");
3416 
3417     // Write header.
3418     writer.OpenTag("header");
3419     writer.WriteString("name", filename);
3420     writer.WriteInt("version", mHeader.project_version);
3421     writer.WriteString("converter", "GUIX Studio");
3422     writer.WriteInt("studio_version", mHeader.studio_version);
3423     writer.WriteInt("guix_version", mHeader.guix_version);
3424     writer.WriteString("target_cpu", ProjectConfigDlg::FindTargetCPUName(mHeader.target_cpu));
3425     writer.WriteString("target_tools", ProjectConfigDlg::FindTargetCompilerName(mHeader.target_tools));
3426     writer.WriteBool("dave2d_graph_accelerator", mHeader.dave2d_graph_accelerator);
3427     writer.CloseTag("header");
3428 
3429     // Write display information
3430     int display = GetProjectView()->GetActiveDisplay();
3431     display_info *dinfo = &mDisplays[display];
3432     theme_info *theme = &dinfo->themes[dinfo->active_theme];
3433     writer.OpenTag("display_info");
3434     writer.WriteString("display_color_format", resource_gen::GetColorFormatName(dinfo->colorformat));
3435     writer.WriteString("rotation_angle", ProjectConfigDlg::FindScreenRotationName(dinfo->rotation_angle));
3436     if (theme->palette && (GetResourceType(start) == RES_TYPE_PIXELMAP) && (dinfo->colorformat < GX_COLOR_FORMAT_5551BGRX))
3437     {
3438         CreateThemePalette(display, dinfo->active_theme, NULL);
3439         theme->palette_predefined = theme->palette_total_size;
3440         WriteThemePaletteInfo(writer, theme, TRUE);
3441     }
3442     writer.CloseTag("display_info");
3443 
3444     // Write resource information
3445     if (start->type == RES_TYPE_FONT || start->type == RES_TYPE_PIXELMAP)
3446     {
3447         writer.OpenTag("resource");
3448         WriteOneResource(writer, start, TRUE);
3449         writer.CloseTag("resource");
3450     }
3451     else if (start->child)
3452     {
3453         WriteResources(writer, start->child, TRUE);
3454     }
3455 
3456     writer.CloseTag("resource_project");
3457     writer.CloseFile();
3458 }
3459 
3460 ///////////////////////////////////////////////////////////////////////////////
ReadXMLFile(CString & pathname)3461 BOOL studiox_project::ReadXMLFile(CString &pathname)
3462 {
3463     xml_reader reader;
3464 
3465     if (!reader.ReadFile(pathname))
3466     {
3467         CString error("Unable to read xml file: ");
3468         error += pathname;
3469         ErrorMsg(error);
3470         return FALSE;
3471     }
3472 
3473     CString filename;
3474     INT version;
3475     CString converter;
3476     CString string;
3477 
3478     // Read header.
3479     if (reader.EnterSection("resource_project"))
3480     {
3481         if (reader.EnterSection("header"))
3482         {
3483             reader.ReadString("name", filename);
3484             reader.ReadInt("version", version);
3485 
3486             if (version < PROJECT_VERSION_INITIAL_RESOURCE_XML)
3487             {
3488                 ErrorMsg("Invalid Project Version!");
3489                 return FALSE;
3490             }
3491 
3492             reader.ReadString("converter", converter);
3493 
3494             if (converter != L"GUIX Studio")
3495             {
3496                 ErrorMsg("Unkown converter!");
3497                 return FALSE;
3498             }
3499 
3500             reader.ReadInt("studio_version", mHeader.studio_version);
3501 
3502             if (mHeader.studio_version > CalculateStudioVersion())
3503             {
3504                 ErrorMsg("The version of GUIX Studio being utilized is below the required version!");
3505                 return FALSE;
3506             }
3507 
3508             reader.ReadInt("guix_version", mHeader.guix_version);
3509             reader.ReadString("target_cpu", string);
3510             mHeader.target_cpu = ProjectConfigDlg::FindTargetCPUVal(string);
3511             reader.ReadString("target_tools", string);
3512             mHeader.target_tools = ProjectConfigDlg::FindTargetCompilerVal(string);
3513             reader.ReadBool("dave2d_graph_accelerator", mHeader.dave2d_graph_accelerator);
3514             reader.CloseSection(TRUE, TRUE);
3515 
3516             mHeader.num_displays = 1;
3517             mDisplays[0].num_themes = 1;
3518 
3519             if (reader.EnterSection("display_info"))
3520             {
3521                 reader.ReadString("display_color_format", string);
3522                 mDisplays[0].colorformat = resource_gen::GetColorFormatVal(string);
3523                 reader.ReadString("rotation_angle", string);
3524                 mDisplays[0].rotation_angle = ProjectConfigDlg::FindScreenRotationVal(string);
3525                 ReadThemePaletteInfo(reader, &mDisplays[0].themes[0], TRUE);
3526                 reader.CloseSection(TRUE, TRUE);
3527             }
3528 
3529             ReadResources(reader, 0, 0, NULL);
3530             reader.CloseSection();
3531 
3532             TaskInitializeAllPixelmaps();
3533 
3534             return TRUE;
3535         }
3536     }
3537     else
3538     {
3539         ErrorMsg("The selected file is not a valid GUIX Studio resource file.");
3540     }
3541 
3542     return FALSE;
3543 }
3544 
3545 ///////////////////////////////////////////////////////////////////////////////
ReadWidgetFolders(xml_reader & reader,int index)3546 void studiox_project::ReadWidgetFolders(xml_reader &reader, int index)
3547 {
3548     display_info *pInfo = &mDisplays[index];
3549     pInfo->SetFirstChildFolder(NULL);
3550     //if (mHeader.studio_version < 5040001)
3551     if (!reader.EnterSection("widget_folder"))
3552     {
3553         /* Create default folder for old version */
3554         folder_info * folder = new folder_info(CString("default_folder"));
3555         if (folder)
3556         {
3557             pInfo->SetFirstChildFolder(folder);
3558         }
3559         widget_reader::ReadWidgets(reader, this, index, pInfo->GetFirstChildFolder());
3560     }
3561     else
3562     {
3563         reader.CloseSection(FALSE, FALSE);
3564         widget_reader::ReadWidgetFolders(reader, this, index);
3565     }
3566 }
3567 
3568 ///////////////////////////////////////////////////////////////////////////////
ReadPaletteType(int display_color_format,xml_reader & reader,res_info * res)3569 void studiox_project::ReadPaletteType(int display_color_format, xml_reader &reader, res_info *res)
3570 {
3571     char palette_type[40];
3572     res->palette_type = PALETTE_TYPE_NONE;
3573 
3574     memset(palette_type, 0, 40);
3575 
3576     if (display_color_format == GX_COLOR_FORMAT_8BIT_PALETTE)
3577     {
3578         res->palette_type = PALETTE_TYPE_SHARED;
3579         return;
3580     }
3581     else
3582     {
3583         if (res->output_color_format != GX_COLOR_FORMAT_8BIT_PALETTE)
3584         {
3585             res->palette_type = PALETTE_TYPE_NONE;
3586             return;
3587         }
3588     }
3589 
3590     if (reader.ReadString("palette_type", palette_type, 40))
3591     {
3592         if (strlen(palette_type) > 1)
3593         {
3594             if (strcmp(palette_type, "Private") == 0)
3595             {
3596                 res->palette_type = PALETTE_TYPE_PRIVATE;
3597             }
3598             else
3599             {
3600                 if (strcmp(palette_type, "Shared") == 0)
3601                 {
3602                     res->palette_type = PALETTE_TYPE_SHARED;
3603                 }
3604             }
3605         }
3606         else
3607         {
3608             // here for older projects. The palette type was saved as a number.
3609             //    PALETTE_TYPE_PRIVATE = 0
3610             //    PALETTE_TYPE_SHARED = 1
3611             //    PALETTE_TYPE_GLOBAL = 2
3612 
3613             if (palette_type[0] == '0')
3614             {
3615                 res->palette_type = PALETTE_TYPE_PRIVATE;
3616             }
3617             else
3618             {
3619                 if (palette_type[0] == '1' ||
3620                     palette_type[0] == '2')
3621                 {
3622                     res->palette_type = PALETTE_TYPE_SHARED;
3623                 }
3624             }
3625         }
3626     }
3627 }
3628 
3629 
3630 ///////////////////////////////////////////////////////////////////////////////
ReadOneResource(xml_reader & reader,int display_index,res_info * put)3631 void studiox_project::ReadOneResource(xml_reader &reader, int display_index, res_info *put)
3632 {
3633     ULONG gxColor;
3634     int page_count;
3635     int res_id;
3636     CString message;
3637     CString name;
3638     CString num;
3639     CString base_name;
3640     CCommandInfo *pCmdInfo = GetCmdInfo();
3641 
3642     reader.ReadString("name", put->name);
3643     reader.ReadPathInfo(put->pathinfo);
3644 
3645     if (put->type == RES_TYPE_PIXELMAP ||
3646         put->type == RES_TYPE_FONT ||
3647         put->type == RES_TYPE_COLOR)
3648     {
3649         if (!TestInputName(put->name, NULL, NULL, FALSE))
3650         {
3651             message = _T("The project contains an invalid resource name: ");
3652 
3653             // trim the bad name (in case it is really really long)
3654             put->name = put->name.Left(40);
3655             message += put->name;
3656 
3657             base_name = _T("RESOURCE_");
3658             res_id = 1;
3659 
3660             while(1)
3661             {
3662                 num.Format(_T("%d"), res_id);
3663                 name = base_name + num;
3664 
3665                 if (!NameExists(display_index, put->type, name))
3666                 {
3667                     put->name = name;
3668                     break;
3669                 }
3670                 res_id++;
3671             }
3672 
3673             message += (_T(". Resetting the resource Id to: "));
3674             message += name;
3675             ErrorMsg(message);
3676         }
3677     }
3678 
3679 
3680     if (mHeader.project_version <= 52)
3681     {
3682         reader.ReadInt("resource_id", res_id);
3683 
3684         if (put->type == RES_TYPE_FOLDER ||
3685             put->type == RES_TYPE_HEADER ||
3686             put->type == RES_TYPE_GROUP)
3687         {
3688             put->folder_id = res_id;
3689         }
3690     }
3691     else
3692     {
3693         res_id = -1;
3694 
3695         reader.ReadString("folder_id", name);
3696         put->folder_id = FindFolderIdVal(put->type, name);
3697     }
3698 
3699     reader.ReadBool("is_default", put->is_default);
3700 
3701     if (!reader.ReadBool("enabled", put->enabled))
3702     {
3703         put->enabled = TRUE;
3704     }
3705 
3706     switch(put->type)
3707     {
3708     case RES_TYPE_COLOR:
3709         reader.ReadUnsigned("colorval", gxColor);
3710         put->colorval = gxColor;
3711         put->compress = FALSE;
3712         AddToResourceDictionary(display_index, put, res_id);
3713         break;
3714 
3715     case RES_TYPE_FONT:
3716 
3717         reader.ReadInt("height", put->font_height);
3718         RANGE_CHECK(put->font_height, 1, 255);
3719 
3720         reader.ReadInt("font_bits", put->font_bits, 8);
3721 
3722         if (!IsFontBitsSupported(put->font_bits))
3723         {
3724             put->font_bits = 8;
3725         }
3726 
3727         reader.ReadBool("font_include_st_glyphs", put->font_charset_include_string_table);
3728         reader.ReadBool("font_support_extended_unicode", put->font_support_extended_unicode);
3729 
3730         // older projects did not support font compression:
3731         if ((mHeader.project_version >= 51)&&
3732             (IsRenesasDave2D(this)) &&
3733             (mDisplays[display_index].colorformat > GX_COLOR_FORMAT_8BIT_PALETTE))
3734         {
3735             reader.ReadBool("compress", put->compress);
3736         }
3737         else
3738         {
3739             put->compress = FALSE;
3740         }
3741 
3742         if ((mHeader.project_version >= 53) &&
3743             (!IsRenesasDave2D(this)))
3744         {
3745             reader.ReadBool("font_kerning", put->font_kerning);
3746         }
3747         else
3748         {
3749             put->font_kerning = FALSE;
3750         }
3751 
3752         reader.ReadBool("output_file_enabled", put->output_file_enabled);
3753         reader.ReadString("output_file", put->output_file);
3754         reader.ReadBool("binary_mode", put->binary_mode);
3755 
3756         if (pCmdInfo->IsXmlMode())
3757         {
3758             CArray<font_page_info> pages;
3759             font_page_info page_info;
3760             while (reader.EnterSection("font_page_data"))
3761             {
3762                 page_info.enabled = TRUE;
3763                 reader.ReadInt("first_char", page_info.first_char);
3764                 RANGE_CHECK(page_info.first_char, 0, GX_MAX_GLYPH_CODE);
3765                 reader.ReadInt("last_char", page_info.last_char);
3766                 RANGE_CHECK(page_info.last_char, 0, GX_MAX_GLYPH_CODE);
3767                 pages.Add(page_info);
3768                 reader.CloseSection(TRUE, TRUE);
3769             }
3770 
3771             put->font_pages_count = pages.GetCount();
3772 
3773             if (pages.GetCount())
3774             {
3775                 put->font_pages = new font_page_info[pages.GetCount()];
3776                 for (int index = 0; index < pages.GetCount(); index++)
3777                 {
3778                     put->font_pages[index] = pages.GetAt(index);
3779                 }
3780             }
3781         }
3782         else
3783         {
3784 
3785             page_count = NUM_FONT_CHAR_RANGES;
3786 
3787             if (put->font_support_extended_unicode)
3788             {
3789                 put->font_pages = font_path_dialog::CreateDefaultFontPages(TRUE);
3790                 page_count += NUM_FONT_EXTENDED_CHAR_RANGES;
3791             }
3792             else
3793             {
3794                 put->font_pages = font_path_dialog::CreateDefaultFontPages();
3795             }
3796 
3797             if (reader.EnterSection("font_page_data"))
3798             {
3799                 for (int loop = 0; loop < page_count; loop++)
3800                 {
3801                     reader.ReadBool("enabled", put->font_pages[loop].enabled);
3802 
3803                     reader.ReadInt("first_char", put->font_pages[loop].first_char);
3804                     RANGE_CHECK(put->font_pages[loop].first_char, 0, GX_MAX_GLYPH_CODE);
3805                     reader.ReadInt("last_char", put->font_pages[loop].last_char);
3806                     RANGE_CHECK(put->font_pages[loop].last_char, 0, GX_MAX_GLYPH_CODE);
3807                 }
3808                 reader.CloseSection(TRUE, TRUE);
3809             }
3810             else
3811             {
3812                 // old projects do not have font_page_data section,
3813                 // so read the first and last char data into first page data
3814 
3815                 reader.ReadInt("firstchar", put->font_pages[0].first_char);
3816                 RANGE_CHECK(put->font_pages[0].first_char, 0, GX_MAX_GLYPH_CODE);
3817                 reader.ReadInt("lastchar", put->font_pages[0].last_char);
3818                 RANGE_CHECK(put->font_pages[0].last_char, 0, GX_MAX_GLYPH_CODE);
3819             }
3820         }
3821 
3822         put->font = NULL;
3823         AddToResourceDictionary(display_index, put, res_id);
3824 
3825         if (put -> is_default && put->pathinfo.pathname.IsEmpty())
3826         {
3827             ConfigureDefaultFont(put, display_index);
3828         }
3829         break;
3830 
3831     case RES_TYPE_PIXELMAP:
3832         if (mHeader.studio_version < STUDIO_VERSION_USE_INTERNAL_SYSTEM_PNG_DATA)
3833         {
3834             if (put->is_default)
3835             {
3836                 if (put->pathinfo.pathname.Find(L"graphics\\system_png\\radiobutton_on.png") >= 0 ||
3837                     put->pathinfo.pathname.Find(L"graphics\\system_png\\radiobutton_off.png") >= 0 ||
3838                     put->pathinfo.pathname.Find(L"graphics\\system_png\\checkbox_on.png") >= 0 ||
3839                     put->pathinfo.pathname.Find(L"graphics\\system_png\\checkbox_off.png") >= 0)
3840                 {
3841                     // Clear path information to use internally linked system pngs.
3842                     put->pathinfo.pathtype = PATH_TYPE_PROJECT_RELATIVE;
3843                     put->pathinfo.pathname = "";
3844                 }
3845             }
3846         }
3847         reader.ReadBool("alpha", put->keep_alpha);
3848         reader.ReadBool("dither", put->dither);
3849         reader.ReadBool("raw", put->raw);
3850         if (mHeader.project_version >= PROJECT_VERSION_WRITE_COLOR_FORMAT_NAME)
3851         {
3852             reader.ReadString("color_format", name);
3853             put->output_color_format = resource_gen::GetColorFormatVal(name);
3854         }
3855         else
3856         {
3857             reader.ReadInt("color_format", put->output_color_format, 0);
3858         }
3859 
3860         reader.ReadBool("output_file_enabled", put->output_file_enabled);
3861         reader.ReadString("output_file", put->output_file);
3862         reader.ReadBool("binary_mode", put->binary_mode);
3863         ReadPaletteType(mDisplays[display_index].colorformat, reader, put);
3864         reader.ReadBool("compress", put->compress);
3865         AddToResourceDictionary(display_index, put, res_id);
3866 
3867         // sanity check
3868 
3869         if (put->output_color_format < 0 || put->output_color_format > 50)
3870         {
3871             put->output_color_format = 0;
3872         }
3873         break;
3874 
3875     default:
3876         break;
3877     }
3878 
3879 }
3880 
3881 ///////////////////////////////////////////////////////////////////////////////
ReadResources(xml_reader & reader,int DisplayIndex,int theme_index,res_info * parent)3882 void studiox_project::ReadResources(xml_reader &reader, int DisplayIndex,
3883     int theme_index, res_info *parent)
3884 {
3885     display_info *pInfo = &mDisplays[DisplayIndex];
3886 
3887     int restype;
3888     CString res_type_name;
3889     res_info *newres;
3890     res_info *previous = NULL;
3891 
3892     while(reader.EnterSection("resource"))
3893     {
3894         newres = NULL;
3895         reader.ReadString("type", res_type_name);
3896         restype = ResStringToType(res_type_name);
3897 
3898         if (restype)
3899         {
3900             newres = new res_info(restype);
3901             ReadOneResource(reader, DisplayIndex, newres);
3902 
3903             if (newres->type == RES_TYPE_COLOR)
3904             {
3905                 if (FindResource(parent, RES_TYPE_COLOR, newres->name))
3906                 {
3907                     //This is a duplicate color resource, continue processing.
3908                     delete newres;
3909                     reader.CloseSection(TRUE, TRUE);
3910                     continue;
3911                 }
3912             }
3913             else if (newres->type == RES_TYPE_FOLDER)
3914             {
3915                 res_info* pAdd = NULL;
3916 
3917                 switch (newres->folder_id)
3918                 {
3919                 case CUSTOM_COLOR_FOLDER:
3920                     pAdd = new res_info(RES_TYPE_ADD_COLOR);
3921                     newres->Attach(pAdd);
3922                     break;
3923 
3924                 case CUSTOM_FONT_FOLDER:
3925                     pAdd = new res_info(RES_TYPE_ADD_FONT);
3926                     newres->Attach(pAdd);
3927                     break;
3928 
3929                 case CUSTOM_PIXELMAP_FOLDER:
3930                     pAdd = new res_info(RES_TYPE_ADD_PIXELMAP);
3931                     newres->Attach(pAdd);
3932                     break;
3933 
3934                 default:
3935                     break;
3936                 }
3937             }
3938             else if (newres->type == RES_TYPE_GROUP)
3939             {
3940                 if (newres->folder_id == STRING_GROUP)
3941                 {
3942                     res_info *pAdd = new res_info(RES_TYPE_ADD_STRING);
3943                     newres->Attach(pAdd);
3944                 }
3945             }
3946 
3947             if (parent)
3948             {
3949                 parent->Attach(newres);
3950             }
3951             else
3952             {
3953                 if (pInfo->themes[theme_index].GetFirstResourceInfo())
3954                 {
3955                     previous = pInfo->themes[theme_index].GetFirstResourceInfo();
3956                     while(previous->next)
3957                     {
3958                         previous = previous->next;
3959                     }
3960                     previous->next = newres;
3961                 }
3962                 else
3963                 {
3964                     pInfo->themes[theme_index].SetFirstResourceInfo(newres);
3965                 }
3966             }
3967         }
3968 
3969         if (newres)
3970         {
3971             ReadResources(reader, DisplayIndex, theme_index, newres);
3972         }
3973         reader.CloseSection(TRUE, TRUE);
3974     }
3975 
3976     if (parent == NULL)
3977     {
3978         newres = pInfo->themes[theme_index].GetFirstResourceInfo();
3979         if (newres)
3980         {
3981             if ((newres->type != RES_TYPE_HEADER) ||
3982                 (newres->folder_id != THEME_HEADER))
3983             {
3984                 //Add theme header resource info
3985                 res_info *pThemeHeader = new res_info(RES_TYPE_HEADER);
3986                 pThemeHeader->folder_id = THEME_HEADER;
3987                 pThemeHeader->name = pInfo->themes[theme_index].theme_name;
3988                 pThemeHeader->next = pInfo->themes[theme_index].GetFirstResourceInfo();
3989                 pInfo->themes[theme_index].SetFirstResourceInfo(pThemeHeader);
3990             }
3991         }
3992         else
3993         {
3994             // Inform the user that the project has issues:
3995             ErrorMsg("Internal Error: The project resource tree is invalid and is being reconstructed.");
3996 
3997             //Create default theme resources
3998             CreateDefaultResources(DisplayIndex, theme_index);
3999         }
4000     }
4001 }
4002 
4003 ///////////////////////////////////////////////////////////////////////////////
ReadStringTable(xml_reader & reader,display_info * info)4004 void studiox_project::ReadStringTable(xml_reader &reader, display_info *info)
4005 {
4006     int index;
4007     int font_id;
4008     int sort_column;
4009     int num_strings;
4010     int num_languages;
4011     int language;
4012     CString temp_id;
4013     CString temp_val;
4014 
4015     if (info->stable)
4016     {
4017         delete info->stable;
4018     }
4019     string_table *table = new string_table;
4020     info->stable = table;
4021 
4022     if (reader.EnterSection("string_table"))
4023     {
4024         reader.ReadInt("sort_column", sort_column, -1);
4025 
4026         table->SetSortColumn(sort_column);
4027 
4028         reader.ReadInt("num_strings", num_strings, 1);
4029         reader.ReadInt("num_languages", num_languages, 1);
4030 
4031         RANGE_CHECK(num_languages, 1, MAX_LANGUAGES);
4032         RANGE_CHECK(num_strings, 1, MAX_STRING_TABLE_STRINGS);
4033 
4034         table->Initialize(num_languages, num_strings);
4035 
4036         index = 1;
4037         while (index < num_strings)
4038         {
4039             if (reader.EnterSection("string_record"))
4040             {
4041                 reader.ReadString("id", temp_id);
4042                 table->AddToDictionary(temp_id, index);
4043                 reader.ReadInt("font", font_id);
4044                 table->SetDisplayFont(index, font_id);
4045                 reader.ReadString("notes", temp_val);
4046                 if (!temp_val.IsEmpty())
4047                 {
4048                     table->SetNotes(index, temp_val);
4049                 }
4050 
4051                 reader.ReadString("val", temp_val);
4052                 table->SetString(index, temp_id, 0, temp_val, FALSE);
4053 
4054                 for (language = 1; language < num_languages; language++)
4055                 {
4056                     reader.ReadString("val", temp_val);
4057                     table->SetString(index, language, temp_val, FALSE);
4058                 }
4059                 reader.CloseSection(TRUE, TRUE);
4060                 index++;
4061             }
4062             else
4063             {
4064                 table->RemoveString(index);
4065                 num_strings--;
4066             }
4067         }
4068         reader.CloseSection(TRUE, TRUE);
4069 
4070         //Sort string table according to specified column
4071         table->Sort();
4072     }
4073     else
4074     {
4075         // if the string table is missing, initialize to
4076         // one language and one string
4077         table->Initialize(1, 1);
4078     }
4079 
4080     table->SetActiveLanguage(0);
4081 }
4082 
4083 ///////////////////////////////////////////////////////////////////////////////
ReadScreenFlow(xml_reader & reader,int display_index)4084 void studiox_project::ReadScreenFlow(xml_reader &reader, int display_index)
4085 {
4086     display_info *info = &mDisplays[display_index];
4087 
4088     if (info->screenflow)
4089     {
4090         delete info->screenflow;
4091         info->screenflow = NULL;
4092     }
4093 
4094     if (reader.EnterSection("screen_flow"))
4095     {
4096         info->screenflow = new screen_flow;
4097 
4098         int scale;
4099 
4100         if (!reader.ReadInt("scale", scale))
4101         {
4102             scale = 100;
4103         }
4104 
4105         RANGE_CHECK(scale, SCREEN_FLOW_MIN_SCALE, SCREEN_FLOW_MAX_SCALE);
4106 
4107         info->screenflow->SetScale(scale);
4108 
4109         ReadFlowItem(reader, display_index);
4110         reader.CloseSection(TRUE, TRUE);
4111     }
4112 }
4113 
4114 ///////////////////////////////////////////////////////////////////////////////
ReadFlowItem(xml_reader & reader,int display_index)4115 void studiox_project::ReadFlowItem(xml_reader &reader, int display_index)
4116 {
4117     screen_flow *flow= mDisplays[display_index].screenflow;
4118 
4119     flow_item *item;
4120     GX_RECTANGLE rect;
4121     while (reader.EnterSection("flow_item"))
4122     {
4123         item = new flow_item;
4124         reader.ReadString("screen_name", item->screen_name);
4125         reader.ReadRect("rect", rect);
4126         item->rect.left = rect.gx_rectangle_left;
4127         item->rect.top = rect.gx_rectangle_top;
4128         item->rect.right = rect.gx_rectangle_right;
4129         item->rect.bottom = rect.gx_rectangle_bottom;
4130         if (!reader.ReadBool("enabled", item->enabled))
4131         {
4132             item->enabled = TRUE;
4133         }
4134         ReadTriggerInfo(reader, display_index, item);
4135 
4136         flow->AddFlowItem(item);
4137 
4138         reader.CloseSection(TRUE, TRUE);
4139     }
4140 }
4141 
4142 ///////////////////////////////////////////////////////////////////////////////
ReadTriggerInfo(xml_reader & reader,int display_index,flow_item * item)4143 void studiox_project::ReadTriggerInfo(xml_reader &reader, int display_index, flow_item *item)
4144 {
4145     trigger_info *head = NULL;
4146     trigger_info *pre = NULL;
4147     trigger_info *trigger;
4148     GX_BOOL detach;
4149     GX_BOOL push_target;
4150 
4151     while (reader.EnterSection("trigger_info"))
4152     {
4153         trigger = new trigger_info;
4154         CString type_name;
4155         reader.ReadString("trigger_name", trigger->trigger_name);
4156         reader.ReadString("signal_id_name", trigger->signal_id_name);
4157         reader.ReadString("trigger_type", type_name);
4158         trigger->trigger_type = trigger_edit_dlg::GetTriggerType(type_name);
4159         reader.ReadString("event_type", type_name);
4160         trigger->event_type = trigger_edit_dlg::GetEventType(type_name);
4161         reader.ReadString("system_event_animat_id_name", trigger->system_event_animat_id_name);
4162         reader.ReadString("user_event_id_name", trigger->user_event_id_name);
4163         trigger->next = NULL;
4164 
4165         if (reader.EnterSection("action_list"))
4166         {
4167             while (reader.EnterSection("action_info"))
4168             {
4169                 action_info *action = new action_info;
4170 
4171                 reader.ReadString("action_name", action->action_name);
4172                 reader.ReadString("action_type", type_name);
4173                 action->action_type = trigger_action_select_dlg::GetActionType(type_name);
4174 
4175                 if (action->action_type)
4176                 {
4177                     reader.ReadString("target_widget_name", action->target_widget_name);
4178                     reader.ReadString("parent_widget_name", action->parent_widget_name);
4179                     reader.ReadString("animation_id_name", action->animation_id_name);
4180 
4181                     if (!action->animation_id_name.IsEmpty())
4182                     {
4183                         //add to animation id dictionary
4184                         AddToIdDictionary(display_index, ID_TYPE_ANIMATION, action->animation_id_name);
4185                     }
4186 
4187                     if (!reader.ReadBool("target_show_child_widgets", action->target_show_child_widgets))
4188                     {
4189                         action->target_show_child_widgets = FALSE;
4190                     }
4191 
4192                     if (!reader.ReadBool("parent_show_child_widgets", action->parent_show_child_widgets))
4193                     {
4194                         action->parent_show_child_widgets = FALSE;
4195                     }
4196 
4197                     if (reader.EnterSection("animation_info"))
4198                     {
4199                         action->animation = new GX_ANIMATION_INFO;
4200                         memset(action->animation, 0, sizeof(GX_ANIMATION_INFO));
4201 
4202                         reader.ReadValue("start_x", action->animation->gx_animation_start_position.gx_point_x);
4203                         reader.ReadValue("start_y", action->animation->gx_animation_start_position.gx_point_y);
4204                         reader.ReadValue("end_x", action->animation->gx_animation_end_position.gx_point_x);
4205                         reader.ReadValue("end_y", action->animation->gx_animation_end_position.gx_point_y);
4206                         reader.ReadUByte("steps", action->animation->gx_animation_steps);
4207 
4208                         if (!reader.ReadUShort("frame_interval", action->animation->gx_animation_frame_interval))
4209                         {
4210                             reader.ReadUShort("delay_time", action->animation->gx_animation_frame_interval);
4211                         }
4212 
4213                         if (!reader.ReadUShort("start_delay", action->animation->gx_animation_start_delay))
4214                         {
4215                             reader.ReadUShort("delay_before", action->animation->gx_animation_start_delay);
4216                         }
4217                         reader.ReadUByte("start_alpha", action->animation->gx_animation_start_alpha);
4218                         reader.ReadUByte("end_alpha", action->animation->gx_animation_end_alpha);
4219                         reader.ReadBool("detach_target", detach);
4220                         reader.ReadBool("push_target", push_target);
4221 
4222                         /* we only support translate style animation in Studio project today */
4223                         action->animation->gx_animation_style = GX_ANIMATION_TRANSLATE;
4224                         if (detach)
4225                         {
4226                             action->animation->gx_animation_style |= GX_ANIMATION_DETACH;
4227                         }
4228 
4229                         if (push_target)
4230                         {
4231                             action->animation->gx_animation_style |= GX_ANIMATION_PUSH_STACK;
4232                         }
4233 
4234                         CString id_name;
4235                         reader.ReadString("easing_func_id_name", id_name);
4236                         action->animation->gx_animation_style |= easing_function_select_dlg::GetEasingFuncId(id_name);
4237 
4238                         reader.CloseSection(TRUE, TRUE);
4239                     }
4240                     trigger->action_list.Add(action);
4241                 }
4242                 else
4243                 {
4244                     delete action;
4245                 }
4246 
4247                 reader.CloseSection(TRUE, TRUE);
4248             }
4249 
4250 
4251             reader.CloseSection(TRUE, TRUE);
4252         }
4253 
4254         if (!head)
4255         {
4256             head = trigger;
4257         }
4258 
4259         if (pre)
4260         {
4261             pre->next = trigger;
4262         }
4263         pre = trigger;
4264         reader.CloseSection(TRUE, TRUE);
4265     }
4266 
4267     item->trigger_list = head;
4268 }
4269 
4270 ///////////////////////////////////////////////////////////////////////////////
ReadThemeScrollbars(xml_reader & reader,int display,int theme)4271 void studiox_project::ReadThemeScrollbars(xml_reader &reader, int display, int theme)
4272 {
4273     display_info *info = &mDisplays[display];
4274 
4275     if (reader.EnterSection("vscroll_appearance"))
4276     {
4277         vscroll_service_provider::ReadScrollbarAppearance(reader, this, display, info->themes[theme].VScrollAppearance);
4278         reader.ReadUnsigned("scroll_style", info->themes[theme].VScrollStyle);
4279         reader.CloseSection();
4280     }
4281     if (reader.EnterSection("hscroll_appearance"))
4282     {
4283         vscroll_service_provider::ReadScrollbarAppearance(reader, this, display, info->themes[theme].HScrollAppearance);
4284         reader.ReadUnsigned("scroll_style", info->themes[theme].HScrollStyle);
4285         reader.CloseSection();
4286     }
4287 }
4288 
4289 ///////////////////////////////////////////////////////////////////////////////
ReadThemePaletteInfo(xml_reader & reader,theme_info * theme,BOOL xml_mode)4290 void studiox_project::ReadThemePaletteInfo(xml_reader& reader, theme_info *theme, BOOL xml_mode)
4291 {
4292     int palette_index;
4293     int test_size;
4294     GX_COLOR* pal;
4295 
4296     if (reader.EnterSection("palette"))
4297     {
4298         reader.ReadInt("total_size", test_size);
4299 
4300         // sanity check
4301         if (test_size > 256)
4302         {
4303             test_size = 256;
4304         }
4305         theme->palette_total_size = test_size;
4306 
4307         if (xml_mode)
4308         {
4309             test_size = theme->palette_total_size;
4310         }
4311         else
4312         {
4313             reader.ReadInt("predefined", test_size);
4314         }
4315 
4316         // sanity check
4317         if (test_size > theme->palette_total_size)
4318         {
4319             test_size = theme->palette_total_size;
4320         }
4321         if (test_size < 0)
4322         {
4323             test_size = 0;
4324         }
4325         theme->palette_predefined = test_size;
4326 
4327         if (theme->palette_total_size > 0)
4328         {
4329             theme->palette = new GX_COLOR[256];
4330             pal = theme->palette;
4331             memset(pal, 0, 256 * sizeof(GX_COLOR));
4332 
4333             for (palette_index = 0; palette_index < theme->palette_predefined; palette_index++)
4334             {
4335                 reader.ReadUnsigned("rgb", *pal);
4336 
4337                 if (mHeader.project_version < 52)
4338                 {
4339                     //default alpha value as 0xff
4340                     (*pal) |= 0xff000000;
4341                 }
4342 
4343                 pal++;
4344             }
4345         }
4346         reader.CloseSection(TRUE, TRUE);
4347     }
4348     else
4349     {
4350         theme->palette = NULL;
4351         theme->palette_total_size = 0;
4352     }
4353 }
4354 
4355 ///////////////////////////////////////////////////////////////////////////////
ReadDisplayInfo(xml_reader & reader,int index)4356 BOOL studiox_project::ReadDisplayInfo(xml_reader &reader, int index)
4357 {
4358     int open_index;
4359     int theme;
4360     int enabled;
4361 
4362     // KGM FIXME:
4363     //
4364     // this flag is just so that we can temporarily read old project files.
4365     // rid of this flag as soon as we have updated all the old projects.
4366 
4367     BOOL old_theme_data_format = FALSE;
4368 
4369     color_dictionary[index].RemoveAll();
4370     font_dictionary[index].RemoveAll();
4371     pixelmap_dictionary[index].RemoveAll();
4372     pixelmap_dictionary[index].Add(CString(""));
4373 
4374     widget_id_dictionary[index].RemoveAll();
4375     animation_id_dictionary[index].RemoveAll();
4376 
4377     display_info *pInfo = &mDisplays[index];
4378     if (reader.EnterSection("display_info"))
4379     {
4380         reader.ReadInt("display_index", open_index);
4381         if (open_index == index)
4382         {
4383             reader.ReadString("display_name", pInfo->name);
4384             reader.ReadInt("xres", pInfo->xres);
4385             reader.ReadInt("yres", pInfo->yres);
4386 
4387             // if display resolution is not valid, default to
4388             // 320x240
4389 
4390             if (pInfo->xres > GX_MAX_DISPLAY_RESOLUTION || pInfo->xres <= 0)
4391             {
4392                 pInfo->xres = 320;
4393             }
4394             if (pInfo->yres > GX_MAX_DISPLAY_RESOLUTION || pInfo->yres <= 0)
4395             {
4396                 pInfo->yres = 240;
4397             }
4398 
4399             reader.ReadInt("bits_per_pix", pInfo->bits_per_pix);
4400 
4401 
4402             /* Fixme KGM */
4403             reader.ReadBool("packed_format", pInfo->packed_format);
4404             reader.ReadBool("format_555", pInfo->format_555);
4405             reader.ReadBool("format_4444", pInfo->format_4444);
4406             reader.ReadBool("format_332", pInfo->format_332);
4407             reader.ReadBool("grayscale", pInfo->grayscale);
4408             reader.ReadBool("reverse_order", pInfo->reverse_order);
4409             reader.ReadBool("enabled", pInfo->enabled);
4410 
4411             CString string;
4412             reader.ReadString("rotation_angle", string);
4413             pInfo->rotation_angle = ProjectConfigDlg::FindScreenRotationVal(string);
4414 
4415             reader.ReadBool("default_map_format", pInfo->default_map_format);
4416 
4417             /* KGM - this is a fix for previous versions of Studio allowing invalid
4418                      Dave2D display format
4419             */
4420             if (IsCpuWithDave2D(mHeader.target_cpu))
4421             {
4422                 pInfo->packed_format = FALSE;
4423                 pInfo->format_555 = FALSE;
4424                 pInfo->format_332 = FALSE;
4425                 pInfo->reverse_order = FALSE;
4426             }
4427 
4428             if (!reader.ReadBool("allocate_canvas", pInfo->allocate_canvas))
4429             {
4430                 // old project without this flag, default to TRUE
4431                 pInfo->allocate_canvas = TRUE;
4432             }
4433 
4434             /* KGM fixeme: This should be determined by bits-per-pix and FLAGS */
4435             switch(pInfo->bits_per_pix)
4436             {
4437             case 1:
4438                 pInfo->colorformat = GX_COLOR_FORMAT_MONOCHROME;
4439                 break;
4440 
4441             case 2:
4442                 ErrorMsg("This project specifies an unsupported output format. Closing.");
4443                 return FALSE;
4444 
4445             case 4:
4446                 pInfo->colorformat = GX_COLOR_FORMAT_4BIT_GRAY;
4447                 break;
4448 
4449             case 8:
4450                 if (pInfo->format_332)
4451                 {
4452                     pInfo->colorformat = GX_COLOR_FORMAT_8BIT_PACKED_PIXEL;
4453                 }
4454                 else
4455                 {
4456                     pInfo->colorformat = GX_COLOR_FORMAT_8BIT_PALETTE;
4457                 }
4458                 break;
4459 
4460             case 24:
4461                 if (pInfo->packed_format)
4462                 {
4463                     pInfo->colorformat = GX_COLOR_FORMAT_24RGB;
4464                 }
4465                 else
4466                 {
4467                     pInfo->colorformat = GX_COLOR_FORMAT_24XRGB;
4468                 }
4469                 break;
4470 
4471             case 32:
4472                 if (pInfo->reverse_order)
4473                 {
4474                     pInfo->colorformat = GX_COLOR_FORMAT_32BGRA;
4475                 }
4476                 else
4477                 {
4478                     pInfo->colorformat = GX_COLOR_FORMAT_32ARGB;
4479                 }
4480                 break;
4481 
4482             default:
4483                 pInfo->bits_per_pix = 16;
4484 
4485                 if (pInfo->format_4444)
4486                 {
4487                     if (pInfo->reverse_order)
4488                     {
4489                         pInfo->colorformat = GX_COLOR_FORMAT_4444BGRA;
4490                     }
4491                     else
4492                     {
4493                         pInfo->colorformat = GX_COLOR_FORMAT_4444ARGB;
4494                     }
4495                 }
4496                 else if (pInfo->format_555)
4497                 {
4498                     if (pInfo->reverse_order)
4499                     {
4500                         pInfo->colorformat = GX_COLOR_FORMAT_5551BGRX;
4501                     }
4502                     else
4503                     {
4504                         pInfo->colorformat = GX_COLOR_FORMAT_1555XRGB;
4505                     }
4506                 }
4507                 else
4508                 {
4509                     if (pInfo->reverse_order)
4510                     {
4511                         pInfo->colorformat = GX_COLOR_FORMAT_565BGR;
4512                     }
4513                     else
4514                     {
4515                         pInfo->colorformat = GX_COLOR_FORMAT_565RGB;
4516                     }
4517                 }
4518             }
4519 
4520             CleanupDisplayResources(pInfo);
4521 
4522             if (reader.EnterSection("theme_info"))
4523             {
4524                 reader.ReadInt("num_themes", pInfo->num_themes, 1);
4525 
4526                 if (!reader.ReadInt("active_theme", pInfo->active_theme))
4527                 {
4528                     pInfo->active_theme = DEFAULT_THEME;
4529                 }
4530 
4531                 if (pInfo->num_themes <= 0 || pInfo->num_themes > MAX_THEMES)
4532                 {
4533                     // corrupt or missing theme info, create defaults
4534                     pInfo->num_themes = 1;
4535                     pInfo->active_theme = DEFAULT_THEME;
4536                     InitDisplayThemes(index);
4537                 }
4538                 else
4539                 {
4540                     if (pInfo->active_theme < 0 || pInfo->active_theme >= pInfo->num_themes)
4541                     {
4542                         ErrorMsg("The project file is corrupted, restoring defaults.");
4543                         pInfo->active_theme = DEFAULT_THEME;
4544                     }
4545 
4546                     for (theme = 0; theme < pInfo->num_themes; theme++)
4547                     {
4548                         DefaultScrollbarAppearance(pInfo, theme);
4549 
4550                         reader.ReadString("theme_name", pInfo->themes[theme].theme_name);
4551 
4552                         if (!reader.ReadBool("gen_color_table", pInfo->themes[theme].gen_color_table))
4553                         {
4554                             pInfo->themes[theme].gen_color_table = TRUE;
4555                         }
4556 
4557                         if (!reader.ReadBool("gen_font_table", pInfo->themes[theme].gen_font_table))
4558                         {
4559                             pInfo->themes[theme].gen_font_table = TRUE;
4560                         }
4561 
4562                         if (!reader.ReadBool("gen_pixelmap_table", pInfo->themes[theme].gen_pixelmap_table))
4563                         {
4564                             pInfo->themes[theme].gen_pixelmap_table = TRUE;
4565                         }
4566 
4567                         if (!reader.ReadBool("enabled", pInfo->themes[theme].enabled))
4568                         {
4569                             pInfo->themes[theme].enabled = TRUE;
4570                         }
4571 
4572                         if (!reader.ReadBool("statically_defined", pInfo->themes[theme].statically_defined))
4573                         {
4574                             pInfo->themes[theme].statically_defined = TRUE;
4575                         }
4576 
4577                         if (reader.EnterSection("theme_data"))
4578                         {
4579                             if (mHeader.project_version >= 53)
4580                             {
4581                                 // resources come first in the new schema
4582                                 ReadResources(reader, index, theme, NULL);
4583                             }
4584 
4585                             ReadThemeScrollbars(reader, index, theme);
4586 
4587                             ReadThemePaletteInfo(reader, &pInfo->themes[theme]);
4588 
4589                             if (mHeader.project_version <= 52)
4590                             {
4591                                 // in older projects, resources come after the theme info
4592                                 ReadResources(reader, index, theme, NULL);
4593                             }
4594                             reader.CloseSection(TRUE, TRUE);
4595 
4596 
4597                             if (mHeader.project_version <= 54)
4598                             {
4599                                 //add default "disabled text color", "disabled fill color"
4600                                 //            "readonly text color", "readonly fill color"
4601 
4602                                 res_info *parent = FindResourceFolder(pInfo->themes[theme].GetFirstResourceInfo(), RES_TYPE_FOLDER, DEFAULT_COLOR_FOLDER);
4603                                 COLOR_RECORD *default_record = ProjectConfigDlg::GetDefaultColorTable(pInfo->colorformat);
4604 
4605                                 res_info *newres;
4606                                 while (default_record->name)
4607                                 {
4608                                     switch (default_record->color_id)
4609                                     {
4610                                     case GX_COLOR_ID_DISABLED_TEXT:
4611                                     case GX_COLOR_ID_DISABLED_FILL:
4612                                     case GX_COLOR_ID_READONLY_TEXT:
4613                                     case GX_COLOR_ID_READONLY_FILL:
4614                                         if (FindResource(parent, RES_TYPE_COLOR, CString(default_record->name)) == NULL)
4615                                         {
4616                                             newres = new res_info(RES_TYPE_COLOR);
4617 
4618                                             newres->colorval = ProjectConfigDlg::GetColorVal(default_record->rgb_val,
4619                                                                                             pInfo->themes[theme].palette,
4620                                                                                             pInfo->themes[theme].palette_predefined,
4621                                                                                             pInfo->colorformat);
4622                                             newres->name = default_record->name;
4623                                             newres->is_default = TRUE;
4624                                             parent->Attach(newres);
4625                                         }
4626                                         break;
4627                                     default:
4628                                         break;
4629                                     }
4630 
4631                                     default_record++;
4632                                 }
4633                             }
4634                         }
4635                         else
4636                         {
4637                             old_theme_data_format = TRUE;
4638                         }
4639                     }
4640                 }
4641                 reader.CloseSection(TRUE, TRUE);
4642             }
4643             else
4644             {
4645                 return FALSE;
4646             }
4647 
4648             for (int language = 0; language < mHeader.num_languages; language++)
4649             {
4650                 if (reader.ReadBool(CT2A(mHeader.languages[language].name), enabled))
4651                 {
4652                     mDisplays[index].gen_string_table[language] = enabled;
4653                 }
4654             }
4655 
4656             if (mHeader.project_version <= 52)
4657             {
4658                 ReadWidgetFolders(reader, index);
4659 
4660                 if (old_theme_data_format)
4661                 {
4662                     ReadResources(reader, index, 0, NULL);
4663                 }
4664                 ReadStringTable(reader, pInfo);
4665             }
4666             else
4667             {
4668                 ReadStringTable(reader, pInfo);
4669                 ReadScreenFlow(reader, index);
4670                 ReadWidgetFolders(reader, index);
4671             }
4672         }
4673         reader.CloseSection(TRUE, TRUE);
4674     }
4675     return TRUE;
4676 }
4677 
4678 ///////////////////////////////////////////////////////////////////////////////
ReadProjectHeader(xml_reader & reader)4679 void studiox_project::ReadProjectHeader(xml_reader &reader)
4680 {
4681     InitProjectHeader(FALSE);
4682     int index;
4683 
4684     mHeader.warn_missing_image = TRUE;
4685     mHeader.warn_missing_font = TRUE;
4686 
4687     if (reader.EnterSection("header"))
4688     {
4689         reader.ReadInt("project_version", mHeader.project_version, PROJECT_VERSION);
4690 
4691         // default to the original version, 5.0, if no version information
4692         reader.ReadInt("guix_version", mHeader.guix_version, 50000);
4693 
4694         // default to version 5.3.2.0, if no version information
4695         reader.ReadInt("studio_version", mHeader.studio_version, 5030200);
4696 
4697         if (mHeader.guix_version < 50000)
4698         {
4699             int version = mHeader.guix_version;
4700             // convert to new format
4701             int major = version / 10;
4702             version -= (major * 10);
4703             int minor = version;
4704             mHeader.guix_version = GuixVersionFieldsToVersionNumber(major, minor, 0);
4705         }
4706 
4707         reader.ReadString("project_name", mHeader.project_name);
4708         reader.ReadString("source_path", mHeader.source_path);
4709         reader.ReadString("header_path", mHeader.header_path);
4710         reader.ReadString("resource_path", mHeader.resource_path);
4711         reader.ReadString("allocator_function", mHeader.malloc_name);
4712         reader.ReadString("free_function", mHeader.free_name);
4713         reader.ReadString("additional_headers", mHeader.additional_headers);
4714         reader.ReadBool("insert_headers_before", mHeader.insert_headers_before);
4715 
4716         reader.ReadInt("target_cpu", mHeader.target_cpu);
4717         reader.ReadInt("target_tools", mHeader.target_tools);
4718         reader.ReadBool("big_endian", mHeader.big_endian);
4719 
4720         if (IsCpuWithDave2D(mHeader.target_cpu))
4721         {
4722             if (!reader.ReadBool("dave2d_graph_accelerator", mHeader.dave2d_graph_accelerator))
4723             {
4724                 if (!reader.ReadBool("synergy_graph_accelerator", mHeader.dave2d_graph_accelerator))
4725                 {
4726                     mHeader.dave2d_graph_accelerator = TRUE;
4727                 }
4728             }
4729 
4730             if (!reader.ReadInt("renesas_jpeg_decoder", mHeader.renesas_jpeg_decoder))
4731             {
4732                 if (!reader.ReadInt("synergy_jpeg_decoder", mHeader.renesas_jpeg_decoder))
4733                 {
4734                     mHeader.renesas_jpeg_decoder = DECODER_TYPE_HW;
4735                 }
4736             }
4737 
4738             if (!reader.ReadInt("renesas_png_decoder", mHeader.renesas_png_decoder))
4739             {
4740                 if (!reader.ReadInt("synergy_png_decoder", mHeader.renesas_png_decoder))
4741                 {
4742                     mHeader.renesas_png_decoder = DECODER_TYPE_NONE;
4743                 }
4744             }
4745         }
4746         else
4747         {
4748             mHeader.dave2d_graph_accelerator = FALSE;
4749             mHeader.renesas_jpeg_decoder = DECODER_TYPE_NONE;
4750             mHeader.renesas_png_decoder = DECODER_TYPE_NONE;
4751         }
4752 
4753         if (!reader.ReadBool("grid_enabled", mHeader.grid_enabled))
4754         {
4755             mHeader.grid_enabled = FALSE;
4756         }
4757 
4758         if (!reader.ReadBool("snap_enabled", mHeader.snap_enabled))
4759         {
4760             mHeader.snap_enabled = FALSE;
4761         }
4762 
4763         if (!reader.ReadBool("snap_to_widget_enabled", mHeader.snap_to_widget_enabled))
4764         {
4765             mHeader.snap_to_widget_enabled = FALSE;
4766         }
4767 
4768         if (!reader.ReadInt("grid_spacing", mHeader.grid_spacing))
4769         {
4770             mHeader.grid_spacing = 10;
4771         }
4772 
4773         RANGE_CHECK(mHeader.grid_spacing, MIN_GRID_SNAP_SPACE, MAX_GRID_SNAP_SPACE);
4774 
4775         if (!reader.ReadInt("snap_spacing", mHeader.snap_spacing))
4776         {
4777             mHeader.snap_spacing = 10;
4778         }
4779 
4780         RANGE_CHECK(mHeader.snap_spacing, MIN_GRID_SNAP_SPACE, MAX_GRID_SNAP_SPACE);
4781 
4782         reader.ReadBool("gen_binary", mHeader.gen_binary);
4783         reader.ReadUnsigned("binary_file_format", mHeader.binary_file_format, BINARY_FILE_FORMAT_SREC);
4784         reader.ReadUnsigned("memory_offset", mHeader.memory_offset, 0);
4785 
4786         if (!reader.ReadBool("gen_res_header", mHeader.gen_res_header))
4787         {
4788             mHeader.gen_res_header = TRUE;
4789         }
4790 
4791         if (!reader.ReadBool("custom_resource_enabled", mHeader.custom_resource_enabled))
4792         {
4793             mHeader.custom_resource_enabled = FALSE;
4794         }
4795 
4796         if (!reader.ReadString("custom_resource_file_name", mHeader.custom_resource_file_name))
4797         {
4798             mHeader.custom_resource_file_name = "";
4799         }
4800 
4801         // app execute position will be checked before use, so no need to do range check here.
4802 
4803         reader.ReadInt("app_execute_xpos", mHeader.app_execute_xpos);
4804         reader.ReadInt("app_execute_ypos", mHeader.app_execute_ypos);
4805 
4806         reader.ReadBool("is_widget_position_locked", mHeader.is_widget_position_locked);
4807 
4808         if (!reader.ReadInt("palette_mode_aa_text_colors", mHeader.palette_mode_aa_text_colors))
4809         {
4810             mHeader.palette_mode_aa_text_colors = 8;
4811         }
4812 
4813         reader.ReadInt("num_displays", mHeader.num_displays, 1);
4814         RANGE_CHECK(mHeader.num_displays, 1, MAX_DISPLAYS);
4815         reader.ReadInt("max_displays", mHeader.max_displays, 4);
4816         RANGE_CHECK(mHeader.max_displays, mHeader.num_displays, MAX_DISPLAYS);
4817         reader.ReadInt("num_languages", mHeader.num_languages, 1);
4818         RANGE_CHECK(mHeader.num_languages, 1, MAX_LANGUAGES);
4819 
4820         BOOL enabled;
4821         if (reader.EnterSection("language_names"))
4822         {
4823             for (index = 0; index < mHeader.num_languages; index++)
4824             {
4825                 // we used to save the combined name in the project,
4826                 // i.e. the language name + the { symbol }. Now
4827                 // we just save the language name, so check for the
4828                 // symbol and get rid of it if it is there:
4829 
4830                 CString temp_name;
4831                 int symbol_index;
4832 
4833                 reader.ReadString("language", temp_name);
4834                 symbol_index = temp_name.ReverseFind('{');
4835 
4836                 if (symbol_index > 0)
4837                 {
4838                     temp_name = temp_name.Left(symbol_index - 1);
4839                 }
4840 
4841                 mHeader.languages[index].name = config_languages_dlg::ConvertOldLanguageName(temp_name);
4842 
4843                 if (reader.ReadBool("enabled", enabled))
4844                 {
4845                     for (int display_index = 0; display_index < mHeader.num_displays; display_index++)
4846                     {
4847                         mDisplays[display_index].gen_string_table[index] = enabled;
4848                     }
4849                 }
4850 
4851                 if (!reader.ReadBool("support_bidi_text", mHeader.languages[index].support_bidi_text))
4852                 {
4853                     mHeader.languages[index].support_bidi_text = FALSE;
4854                 }
4855 
4856                 if (!reader.ReadBool("gen_reordered_bidi_text", mHeader.languages[index].gen_reordered_bidi_text))
4857                 {
4858                     mHeader.languages[index].gen_reordered_bidi_text = FALSE;
4859                 }
4860 
4861                 if (!reader.ReadBool("support_thai_glyph_shaping", mHeader.languages[index].support_thai_glyph_shaping))
4862                 {
4863                     mHeader.languages[index].support_thai_glyph_shaping = FALSE;
4864                 }
4865 
4866                 if (!reader.ReadBool("gen_adjusted_thai_string", mHeader.languages[index].gen_adjusted_thai_string))
4867                 {
4868                     mHeader.languages[index].gen_adjusted_thai_string = FALSE;
4869                 }
4870 
4871                 if (!reader.ReadBool("statically_defined", mHeader.languages[index].statically_defined))
4872                 {
4873                     mHeader.languages[index].statically_defined = TRUE;
4874                 }
4875             }
4876             reader.CloseSection(TRUE, TRUE);
4877         }
4878 
4879         if (reader.EnterSection("string_export"))
4880         {
4881             reader.ReadInt("string_export_src", mHeader.string_export_src);
4882             reader.ReadInt("string_export_target", mHeader.string_export_target);
4883             reader.ReadInt("string_export_version", mHeader.string_export_version);
4884             reader.ReadString("string_export_path", mHeader.string_export_path);
4885             reader.ReadString("string_export_name", mHeader.string_export_filename);
4886 
4887             CString file_typename;
4888             reader.ReadString("string_export_filetype", file_typename);
4889             mHeader.string_export_filetype = string_export_dlg::GetStringExportType(file_typename);
4890 
4891             reader.CloseSection(TRUE, TRUE);
4892         }
4893         else if (reader.EnterSection("xliff"))
4894         {
4895             reader.ReadInt("xliff_src", mHeader.string_export_src);
4896             reader.ReadInt("xliff_target", mHeader.string_export_target);
4897             reader.ReadInt("xliff_version", mHeader.string_export_version);
4898             reader.ReadString("xliff_path", mHeader.string_export_path);
4899             reader.ReadString("xliff_name", mHeader.string_export_filename);
4900             reader.CloseSection(TRUE, TRUE);
4901         }
4902         else
4903         {
4904             InitStringExportHeader();
4905         }
4906 
4907         reader.CloseSection(TRUE, TRUE);
4908     }
4909 }
4910 
4911 ///////////////////////////////////////////////////////////////////////////////
Read(CString & pathname)4912 BOOL studiox_project::Read(CString &pathname)
4913 {
4914     xml_reader reader;
4915 
4916     if (!reader.ReadFile(pathname))
4917     {
4918         CString error("Unable to read project file: ");
4919         error += pathname;
4920         ErrorMsg(error);
4921         return FALSE;
4922     }
4923 
4924     if (reader.EnterSection("project"))
4925     {
4926         ReadProjectHeader(reader);
4927 
4928         int studio_version = CalculateStudioVersion();
4929 
4930         #ifdef ENABLE_STUDIO_VERSION_TEST
4931         if ((mHeader.project_version > PROJECT_VERSION) ||
4932             (mHeader.studio_version > studio_version))
4933         {
4934             if (!AskUser("This project was created by a newer release of GUIX Studio. Do you want to continue?"))
4935             {
4936                 return FALSE;
4937             }
4938         }
4939         #endif
4940 
4941         // make sure the project name matches the actual filename, which can
4942         // happen if the user copies a project:
4943         mHeader.project_name = pathname;
4944         int index = mHeader.project_name.ReverseFind('\\');
4945         if (index > 0)
4946         {
4947             mHeader.project_name = mHeader.project_name.Mid(index + 1);
4948         }
4949 
4950         index = mHeader.project_name.ReverseFind('.');
4951         if (index > 0)
4952         {
4953             mHeader.project_name = mHeader.project_name.Left(index);
4954         }
4955 
4956         for (int index = 0; index < mHeader.max_displays; index++)
4957         {
4958             if (!ReadDisplayInfo(reader, index))
4959             {
4960                 ErrorMsg("Invalid project file, unable to open project.");
4961                 return FALSE;
4962             }
4963         }
4964         InitializeProjectResources();
4965 
4966         if (mDisplays[0].themes[0].GetFirstResourceInfo() == GX_NULL)
4967         {
4968             ErrorMsg("Invalid project file, unable to open project.");
4969             return FALSE;
4970         }
4971 
4972         reader.CloseSection();
4973 
4974         // update to the current studio version and project version
4975         if ((mHeader.studio_version != studio_version)||
4976             (mHeader.project_version != PROJECT_VERSION))
4977         {
4978             mHeader.studio_version = studio_version;
4979             mHeader.project_version = PROJECT_VERSION;
4980             is_modified = TRUE;
4981         }
4982         else
4983         {
4984             is_modified = FALSE;
4985         }
4986         return TRUE;
4987     }
4988     else
4989     {
4990         ErrorMsg("The selected file is not a valid GUIX Studio project.");
4991         return FALSE;
4992     }
4993 }
4994 
4995 ///////////////////////////////////////////////////////////////////////////////
AddToIdDictionary(int DisplayIndex,int id_type,CString & id_name)4996  BOOL studiox_project::AddToIdDictionary(int DisplayIndex, int id_type, CString &id_name)
4997  {
4998      CArray<id_info> *dictionary;
4999      id_info         *get_info;
5000      id_info          new_info;
5001 
5002      if (DisplayIndex < 0)
5003      {
5004          return FALSE;
5005      }
5006 
5007      switch (id_type)
5008      {
5009      case ID_TYPE_WIDGET:
5010          dictionary = &widget_id_dictionary[DisplayIndex];
5011          if (id_name == "ID_DROP_LIST_BUTTON")
5012          {
5013              //ID_DROP_LIST_BUTTON is defined internal
5014              return FALSE;
5015          }
5016          break;
5017 
5018      case ID_TYPE_ANIMATION:
5019          dictionary = &animation_id_dictionary[DisplayIndex];
5020          break;
5021 
5022      default:
5023          return FALSE;
5024      }
5025 
5026      if (dictionary->GetCount() == 0)
5027      {
5028          new_info.id_name = "";
5029          new_info.reference_count = 0;
5030          dictionary->Add(new_info);
5031      }
5032 
5033     for (int index = 0; index < dictionary->GetCount(); index++)
5034     {
5035         get_info = &dictionary->GetAt(index);
5036 
5037         /* Check if the id name already exist. */
5038         if(get_info->id_name == id_name)
5039         {
5040             get_info->reference_count++;
5041             return GX_FALSE;
5042         }
5043     }
5044 
5045     new_info.id_name = id_name;
5046     new_info.reference_count = 1;
5047 
5048     dictionary->Add(new_info);
5049     return GX_TRUE;
5050 }
5051 
5052 ///////////////////////////////////////////////////////////////////////////////
RemoveFromIdDictionary(int DisplayIndex,int id_type,CString & id_name)5053 BOOL studiox_project::RemoveFromIdDictionary(int DisplayIndex, int id_type, CString &id_name)
5054 {
5055      CArray<id_info> *dictionary;
5056      id_info *get_info;
5057 
5058      if (DisplayIndex < 0)
5059      {
5060          return FALSE;
5061      }
5062 
5063      switch (id_type)
5064      {
5065      case ID_TYPE_WIDGET:
5066          dictionary = &widget_id_dictionary[DisplayIndex];
5067          break;
5068 
5069      case ID_TYPE_ANIMATION:
5070          dictionary = &animation_id_dictionary[DisplayIndex];
5071          break;
5072 
5073      default:
5074          return FALSE;
5075      }
5076 
5077      for (int index = 0; index < dictionary->GetCount(); index++)
5078      {
5079          get_info = &dictionary->GetAt(index);
5080 
5081          if (get_info->id_name == id_name)
5082          {
5083              if (get_info->reference_count == 1)
5084              {
5085                  /* Remove the id name from the id dictionary. */
5086                  dictionary->RemoveAt(index);
5087                  return GX_TRUE;
5088              }
5089              else
5090              {
5091                  get_info->reference_count--;
5092                  return GX_FALSE;
5093              }
5094          }
5095      }
5096 
5097      return GX_FALSE;
5098 }
5099 
GetIdIndex(const CArray<id_info> & dictionary,const CString & id_name) const5100 INT studiox_project::GetIdIndex(const CArray<id_info> &dictionary, const CString &id_name) const
5101 {
5102     for (int index = 1; index < dictionary.GetCount(); index++)
5103     {
5104         if (dictionary.GetAt(index).id_name == id_name)
5105         {
5106             /* Set id value according to dictionary index. */
5107             return index;
5108         }
5109     }
5110 
5111     return 0;
5112 }
5113 
5114 ///////////////////////////////////////////////////////////////////////////////
GetIdIndex(int DisplayIndex,int id_type,const CString & id_name) const5115 INT studiox_project::GetIdIndex(int DisplayIndex, int id_type, const CString &id_name) const
5116 {
5117     if (DisplayIndex < 0)
5118     {
5119         return 0;
5120     }
5121 
5122     switch (id_type)
5123     {
5124     case ID_TYPE_WIDGET:
5125         if (id_name == "ID_DROP_LIST_BUTTON")
5126         {
5127             //ID_DROP_LIST_BUTTON is defined internal
5128             return ID_DROP_LIST_BUTTON;
5129         }
5130         else
5131         {
5132             return GetIdIndex(widget_id_dictionary[DisplayIndex], id_name);
5133         }
5134 
5135     case ID_TYPE_ANIMATION:
5136         return GetIdIndex(animation_id_dictionary[DisplayIndex], id_name);
5137 
5138     default:
5139         return 0;
5140     }
5141 
5142     return 0;
5143 }
5144 
5145 ///////////////////////////////////////////////////////////////////////////////
GetIdName(int DisplayIndex,int id_type,int index) const5146 CString studiox_project::GetIdName(int DisplayIndex, int id_type, int index) const
5147 {
5148     const CArray<id_info> *dictionary;
5149 
5150     if (DisplayIndex < 0)
5151     {
5152         return  _T("");
5153     }
5154 
5155     switch (id_type)
5156     {
5157     case ID_TYPE_WIDGET:
5158         dictionary = &widget_id_dictionary[DisplayIndex];
5159         break;
5160 
5161     case ID_TYPE_ANIMATION:
5162         dictionary = &animation_id_dictionary[DisplayIndex];
5163         break;
5164 
5165     default:
5166         return _T("");
5167     }
5168 
5169     if (index < dictionary->GetCount())
5170     {
5171         return dictionary->GetAt(index).id_name;
5172     }
5173 
5174     return _T("");
5175 }
5176 
5177 ///////////////////////////////////////////////////////////////////////////////
CleanupIdDictionary(int DisplayIndex,int id_type)5178 void studiox_project::CleanupIdDictionary(int DisplayIndex, int id_type)
5179 {
5180     CArray<id_info> *dictionary;
5181 
5182     if (DisplayIndex < 0)
5183     {
5184         return ;
5185     }
5186 
5187     switch (id_type)
5188     {
5189     case ID_TYPE_WIDGET:
5190         dictionary = &widget_id_dictionary[DisplayIndex];
5191         break;
5192 
5193     case ID_TYPE_ANIMATION:
5194         dictionary = &animation_id_dictionary[DisplayIndex];
5195         break;
5196 
5197     default:
5198         return;
5199     }
5200 
5201     dictionary->RemoveAll();
5202 }
5203 
5204 ///////////////////////////////////////////////////////////////////////////////
CopyIdDictionary(int DisplayIndex,int id_type,CArray<id_info> * copied_dictionary)5205 BOOL studiox_project::CopyIdDictionary(int DisplayIndex, int id_type, CArray<id_info> *copied_dictionary)
5206 {
5207     if (copied_dictionary)
5208     {
5209         const CArray<id_info> *dictionary;
5210 
5211         switch (id_type)
5212         {
5213         case ID_TYPE_WIDGET:
5214             dictionary = &widget_id_dictionary[DisplayIndex];
5215             break;
5216 
5217         case ID_TYPE_ANIMATION:
5218             dictionary = &animation_id_dictionary[DisplayIndex];
5219             break;
5220 
5221         default:
5222             return FALSE;
5223         }
5224 
5225         copied_dictionary->RemoveAll();
5226         for (int index = 0; index < dictionary->GetCount(); index++)
5227         {
5228             copied_dictionary->Add(dictionary->GetAt(index));
5229         }
5230 
5231         return TRUE;
5232     }
5233     else
5234     {
5235         return FALSE;
5236     }
5237 }
5238 
compare_id(id_info * id_1,id_info * id_2)5239 static int compare_id(id_info *id_1, id_info *id_2)
5240 {
5241     return id_1->id_name.Compare(id_2->id_name);
5242 }
5243 
5244 ///////////////////////////////////////////////////////////////////////////////
SortIdDictionary(CArray<id_info> * dictionary)5245 void studiox_project::SortIdDictionary(CArray<id_info> *dictionary)
5246 {
5247 
5248     if(dictionary->GetSize() > 2)
5249     {
5250         qsort(&dictionary->GetAt(1), dictionary->GetSize() - 1, sizeof(id_info), (int(*)(const void *, const void *))compare_id);
5251     }
5252 }
5253 
5254 ///////////////////////////////////////////////////////////////////////////////
AddToResourceDictionary(int DisplayIndex,res_info * info,int res_id)5255 BOOL studiox_project::AddToResourceDictionary(int DisplayIndex, res_info *info, int res_id)
5256 {
5257     int index;
5258     CArray<CString> *dictionary;
5259 
5260     switch (info->type)
5261     {
5262     case RES_TYPE_COLOR:
5263         dictionary = &color_dictionary[DisplayIndex];
5264         if ((mHeader.project_version <= 54) &&
5265             (dictionary->GetCount() == 0))
5266         {
5267             //Add default color ids
5268             COLOR_RECORD *color_record = DEFAULT_COLOR_TABLE;
5269             while (color_record->name)
5270             {
5271                 dictionary->Add(CString(color_record->name));
5272                 color_record++;
5273             }
5274         }
5275         break;
5276 
5277     case RES_TYPE_FONT:
5278         dictionary = &font_dictionary[DisplayIndex];
5279         break;
5280 
5281     case RES_TYPE_PIXELMAP:
5282         dictionary = &pixelmap_dictionary[DisplayIndex];
5283         if (dictionary->GetCount() == 0)
5284         {
5285             dictionary->Add(CString(""));
5286         }
5287         break;
5288 
5289     default:
5290         return FALSE;
5291     }
5292 
5293     for (index = 0; index < dictionary->GetCount(); index++)
5294     {
5295         if (dictionary->GetAt(index) == info->name)
5296         {
5297             return FALSE;
5298         }
5299     }
5300 
5301     if (res_id == -1)
5302     {
5303         dictionary->Add(info->name);
5304     }
5305     else
5306     {
5307         dictionary->SetAtGrow(res_id, info->name);
5308     }
5309     return TRUE;
5310 }
5311 
5312 ///////////////////////////////////////////////////////////////////////////////
RemoveFromResourceDictionary(int DisplayIndex,res_info * info)5313 BOOL studiox_project::RemoveFromResourceDictionary(int DisplayIndex, res_info *info)
5314 {
5315     int index;
5316     CArray<CString> *dictionary;
5317 
5318     switch (info->type)
5319     {
5320     case RES_TYPE_COLOR:
5321         dictionary = &color_dictionary[DisplayIndex];
5322         break;
5323 
5324     case RES_TYPE_FONT:
5325         dictionary = &font_dictionary[DisplayIndex];
5326         break;
5327 
5328     case RES_TYPE_PIXELMAP:
5329         dictionary = &pixelmap_dictionary[DisplayIndex];
5330         break;
5331 
5332     default:
5333         return FALSE;
5334     }
5335 
5336     for (index = 0; index < dictionary->GetCount(); index++)
5337     {
5338         if (dictionary->GetAt(index) == info->name)
5339         {
5340             dictionary->RemoveAt(index);
5341             return TRUE;
5342         }
5343     }
5344 
5345     return FALSE;
5346 }
5347 
5348 ///////////////////////////////////////////////////////////////////////////////
UpdateDictionaryResourceName(int DisplayIndex,CString & old_name,res_info * info)5349 BOOL studiox_project::UpdateDictionaryResourceName(int DisplayIndex, CString &old_name, res_info *info)
5350 {
5351     int index;
5352     CArray<CString> *dictionary;
5353 
5354     switch (info->type)
5355     {
5356     case RES_TYPE_COLOR:
5357         dictionary = &color_dictionary[DisplayIndex];
5358         break;
5359 
5360     case RES_TYPE_FONT:
5361         dictionary = &font_dictionary[DisplayIndex];
5362         break;
5363 
5364     case RES_TYPE_PIXELMAP:
5365         dictionary = &pixelmap_dictionary[DisplayIndex];
5366         break;
5367 
5368     default:
5369         return FALSE;
5370     }
5371 
5372     for (index = 0; index < dictionary->GetCount(); index++)
5373     {
5374         if (dictionary->GetAt(index) == old_name)
5375         {
5376             dictionary->SetAt(index, info->name);
5377             return TRUE;
5378         }
5379     }
5380 
5381     return FALSE;
5382 }
5383 
5384 ///////////////////////////////////////////////////////////////////////////////
GetResourceName(int Display,int res_type,int index,CString & return_name) const5385 BOOL studiox_project::GetResourceName(int Display, int res_type, int index, CString &return_name) const
5386 {
5387     const CArray<CString> *dictionary;
5388     BOOL found = FALSE;
5389     return_name.Empty();
5390 
5391     switch(res_type)
5392     {
5393     case RES_TYPE_COLOR:
5394         dictionary = &color_dictionary[Display];
5395         break;
5396 
5397     case RES_TYPE_FONT:
5398         dictionary = &font_dictionary[Display];
5399         break;
5400 
5401     case RES_TYPE_PIXELMAP:
5402         dictionary = &pixelmap_dictionary[Display];
5403         break;
5404 
5405     default:
5406         return FALSE;
5407     }
5408 
5409     if (index < dictionary->GetCount())
5410     {
5411         return_name = dictionary->GetAt(index);
5412         return TRUE;
5413     }
5414     return FALSE;
5415 }
5416 
5417 ///////////////////////////////////////////////////////////////////////////////
CopyDictionary(int Display,int res_type,CArray<CString> * copied_dictionary)5418 BOOL studiox_project::CopyDictionary(int Display, int res_type, CArray<CString> *copied_dictionary)
5419 {
5420     if (copied_dictionary)
5421     {
5422         const CArray<CString> *dictionary;
5423 
5424         switch (res_type)
5425         {
5426         case RES_TYPE_COLOR:
5427             dictionary = &color_dictionary[Display];
5428             break;
5429 
5430         case RES_TYPE_FONT:
5431             dictionary = &font_dictionary[Display];
5432             break;
5433 
5434         case RES_TYPE_PIXELMAP:
5435             dictionary = &pixelmap_dictionary[Display];
5436             break;
5437 
5438         default:
5439             return FALSE;
5440         }
5441 
5442         copied_dictionary->RemoveAll();
5443         for (int index = 0; index < dictionary->GetCount(); index++)
5444         {
5445             copied_dictionary->Add(dictionary->GetAt(index));
5446         }
5447 
5448         return TRUE;
5449     }
5450     else
5451     {
5452         return FALSE;
5453     }
5454 }
5455 
compare_string(CString * record_1,CString * record_2)5456 static int compare_string(CString *record_1, CString *record_2)
5457 {
5458     return record_1->Compare(*record_2);
5459 }
5460 
5461 ///////////////////////////////////////////////////////////////////////////////
SortResDictionary(INT res_type,CArray<CString> * dictionary)5462 void studiox_project::SortResDictionary(INT res_type, CArray<CString> *dictionary)
5463 {
5464     int skip_count = 0;
5465 
5466     switch (res_type)
5467     {
5468     case RES_TYPE_PIXELMAP:
5469     {
5470         CCommandInfo* pCmdInfo = GetCmdInfo();
5471         if (!pCmdInfo->IsXmlMode())
5472         {
5473             skip_count = GX_DEFAULT_PIXELMAP_COUNT;
5474         }
5475     }
5476         break;
5477 
5478     case RES_TYPE_FONT:
5479     case RES_TYPE_COLOR:
5480         break;
5481 
5482     default:
5483         return;
5484     }
5485 
5486     if (dictionary->GetSize() > skip_count + 1)
5487     {
5488         qsort(&dictionary->GetAt(skip_count), dictionary->GetSize() - skip_count,
5489             sizeof(CString), (int(*)(const void *, const void *))compare_string);
5490     }
5491 }
5492 
5493 ///////////////////////////////////////////////////////////////////////////////
GetResourceId(int Display,const int res_type,const CString & name) const5494 GX_RESOURCE_ID studiox_project::GetResourceId(int Display, const int res_type, const CString &name) const
5495 {
5496     const CArray<CString> *dictionary;
5497     int index;
5498 
5499     if (name.IsEmpty())
5500     {
5501         return 0;
5502     }
5503 
5504     switch(res_type)
5505     {
5506     case RES_TYPE_COLOR:
5507         dictionary = &color_dictionary[Display];
5508         break;
5509 
5510     case RES_TYPE_FONT:
5511         dictionary = &font_dictionary[Display];
5512         break;
5513 
5514     case RES_TYPE_PIXELMAP:
5515         dictionary = &pixelmap_dictionary[Display];
5516         break;
5517 
5518     default:
5519         return 0;
5520     }
5521 
5522     for (index = 0; index < dictionary->GetCount(); index++)
5523     {
5524         if (dictionary->GetAt(index) == name)
5525         {
5526             return index;
5527         }
5528     }
5529     return 0;
5530 }
5531 
5532 ///////////////////////////////////////////////////////////////////////////////
GetResourceId(int Display,const res_info * info) const5533 GX_RESOURCE_ID studiox_project::GetResourceId(int Display, const res_info *info) const
5534 {
5535     return GetResourceId(Display, info->type, info->name);
5536 }
5537 
5538 ///////////////////////////////////////////////////////////////////////////////
FindResource(int Display,int theme,int restype,const CString & name) const5539 res_info *studiox_project::FindResource(int Display, int theme, int restype, const CString &name) const
5540 {
5541     return FindResource(mDisplays[Display].themes[theme].GetFirstResourceInfo(), restype, name);
5542 }
5543 
5544 
5545 ///////////////////////////////////////////////////////////////////////////////
FindResource(int Display,int theme_id,int res_type,GX_RESOURCE_ID res_id) const5546 res_info *studiox_project::FindResource(int Display, int theme_id, int res_type, GX_RESOURCE_ID res_id) const
5547 {
5548     CString name;
5549     const CArray<CString> *dictionary;
5550 
5551     res_info *pRes = mDisplays[Display].themes[theme_id].GetFirstResourceInfo();
5552 
5553     switch(res_type)
5554     {
5555     case RES_TYPE_COLOR:
5556         dictionary = &color_dictionary[Display];
5557         if (res_id < (ULONG) dictionary->GetCount())
5558         {
5559             name = dictionary->GetAt(res_id);
5560             return FindResource(pRes, res_type, name);
5561         }
5562         else
5563         {
5564             return NULL;
5565         }
5566         break;
5567 
5568     case RES_TYPE_FONT:
5569         dictionary = &font_dictionary[Display];
5570         if (res_id < (ULONG) dictionary->GetCount())
5571         {
5572             name = dictionary->GetAt(res_id);
5573             return FindResource(pRes, res_type, name);
5574         }
5575         else
5576         {
5577             return NULL;
5578         }
5579         break;
5580 
5581     case RES_TYPE_PIXELMAP:
5582         dictionary = &pixelmap_dictionary[Display];
5583 
5584         if (res_id < (ULONG) dictionary->GetCount())
5585         {
5586             name = dictionary->GetAt(res_id);
5587             return FindResource(pRes, res_type, name);
5588         }
5589         else
5590         {
5591             return NULL;
5592         }
5593         break;
5594 
5595     default:
5596         return FindResourceFolder(pRes, res_type, res_id);
5597     }
5598 }
5599 
5600 
5601 
5602 
5603 ///////////////////////////////////////////////////////////////////////////////
FindResource(const res_info * pRes,int restype,const CString & name) const5604 res_info *studiox_project::FindResource(const res_info *pRes, int restype, const CString &name) const
5605 {
5606     res_info *found = NULL;
5607 
5608     while(pRes)
5609     {
5610         if (pRes->type == restype &&
5611             pRes->name == name)
5612         {
5613             return (res_info *)pRes;
5614         }
5615         if (pRes->child)
5616         {
5617             found = FindResource(pRes->child, restype, name);
5618             if (found)
5619             {
5620                 return found;
5621             }
5622         }
5623         pRes = pRes->next;
5624     }
5625     return NULL;
5626 }
5627 
5628 ///////////////////////////////////////////////////////////////////////////////
FindResourceFolder(int Display,int theme_id,int res_type,GX_RESOURCE_ID res_id,const CString & name) const5629 res_info* studiox_project::FindResourceFolder(int Display, int theme_id, int res_type, GX_RESOURCE_ID res_id, const CString& name) const
5630 {
5631     return  FindResourceFolder(mDisplays[Display].themes[theme_id].GetFirstResourceInfo(), res_type, res_id, name);
5632 }
5633 
5634 ///////////////////////////////////////////////////////////////////////////////
FindResourceFolder(const res_info * pRes,int restype,int folder_id,CString name) const5635 res_info *studiox_project::FindResourceFolder(const res_info *pRes, int restype, int folder_id, CString name) const
5636 {
5637     res_info *found = NULL;
5638 
5639     while(pRes)
5640     {
5641 
5642         if (pRes->type == restype &&
5643             pRes->folder_id == folder_id &&
5644             ((pRes->name == name) || name.IsEmpty()))
5645         {
5646             return (res_info *)pRes;
5647         }
5648         if (pRes->child)
5649         {
5650             found = FindResourceFolder(pRes->child, restype, folder_id, name);
5651             if (found)
5652             {
5653                 return found;
5654             }
5655         }
5656         pRes = pRes->next;
5657     }
5658     return NULL;
5659 }
5660 
5661 ///////////////////////////////////////////////////////////////////////////////
FindParentInfo(const widget_info * start,const widget_info * child) const5662 widget_info *studiox_project::FindParentInfo(const widget_info *start, const widget_info *child) const
5663 {
5664     widget_info *test;
5665     widget_info *found;
5666 
5667     while(start)
5668     {
5669         test = start->GetChildWidgetInfo();
5670 
5671         while(test)
5672         {
5673             if (test == child)
5674             {
5675                 return (widget_info *)start;
5676             }
5677             found = FindParentInfo(test, child);
5678             if (found)
5679             {
5680                 return found;
5681             }
5682             test = test->GetNextWidgetInfo();
5683         }
5684         start = start->GetNextWidgetInfo();
5685     }
5686     return NULL;
5687 }
5688 
5689 ///////////////////////////////////////////////////////////////////////////////
FindParentInfo(const widget_info * child) const5690 widget_info *studiox_project::FindParentInfo(const widget_info *child) const
5691 {
5692     widget_info *found = NULL;
5693 
5694     for (int Display = 0; Display < MAX_DISPLAYS; Display++)
5695     {
5696         folder_info *pInfo = mDisplays[Display].GetFirstChildFolder();
5697         found = FindParentInfo(pInfo, child);
5698         if (found)
5699         {
5700             return found;
5701         }
5702     }
5703     return NULL;
5704 }
5705 
5706 ///////////////////////////////////////////////////////////////////////////////
FindParentInfo(const folder_info * folder,const widget_info * child) const5707 widget_info *studiox_project::FindParentInfo(const folder_info *folder, const widget_info *child) const
5708 {
5709     widget_info *found = GX_NULL;
5710     while (folder)
5711     {
5712         found = FindParentInfo(folder->GetFirstChildWidget(), child);
5713         if (found)
5714         {
5715             return found;
5716         }
5717         folder = folder->GetNextFolder();
5718     }
5719     return GX_NULL;
5720 }
5721 
5722 ///////////////////////////////////////////////////////////////////////////////
FindWidgetInfo(const folder_info * folder,const CString & name,BOOL search_child) const5723 widget_info *studiox_project::FindWidgetInfo(const folder_info *folder, const CString &name, BOOL search_child) const
5724 {
5725     widget_info *found = GX_NULL;
5726 
5727     while (folder)
5728     {
5729         found = FindWidgetInfo(folder->GetFirstChildWidget(), name, search_child);
5730         if (found)
5731         {
5732             return found;
5733         }
5734         folder = folder->GetNextFolder();
5735     }
5736     return GX_NULL;
5737 }
5738 
5739 ///////////////////////////////////////////////////////////////////////////////
FindWidgetInfo(const widget_info * start,const CString & name,BOOL search_child) const5740 widget_info *studiox_project::FindWidgetInfo(const widget_info *start, const CString &name, BOOL search_child) const
5741 {
5742     widget_info *found = NULL;
5743 
5744     while(start)
5745     {
5746         if (start->app_name == name)
5747         {
5748             return (widget_info *)start;
5749         }
5750 
5751         if (search_child && start->GetChildWidgetInfo())
5752         {
5753             found = FindWidgetInfo(start->GetChildWidgetInfo(), name, search_child);
5754 
5755             if (found)
5756             {
5757                 return found;
5758             }
5759         }
5760         start = start->GetNextWidgetInfo();
5761     }
5762     return NULL;
5763 }
5764 
5765 ///////////////////////////////////////////////////////////////////////////////
GetTailInfo(const widget_info * info) const5766 const widget_info *studiox_project::GetTailInfo(const widget_info *info) const
5767 {
5768     const widget_info *tail = info;
5769     while (tail->GetNextWidgetInfo())
5770     {
5771         tail = tail->GetNextWidgetInfo();
5772     }
5773 
5774     return tail;
5775 }
5776 
5777 ///////////////////////////////////////////////////////////////////////////////
FindFolderInfo(const folder_info * start,const CString & name) const5778 folder_info *studiox_project::FindFolderInfo(const folder_info *start, const CString &name) const
5779 {
5780     while (start)
5781     {
5782         if (start->folder_name == name)
5783         {
5784             return (folder_info *)start;
5785         }
5786         start = start->GetNextFolder();
5787     }
5788     return NULL;
5789 }
5790 
5791 ///////////////////////////////////////////////////////////////////////////////
FindFolderInfo(int display_index,const CString & name) const5792 folder_info *studiox_project::FindFolderInfo(int display_index, const CString &name) const
5793 {
5794     folder_info *found = NULL;
5795 
5796     if (display_index < MAX_DISPLAYS)
5797     {
5798         found = FindFolderInfo(mDisplays[display_index].GetFirstChildFolder(), name);
5799         if (found)
5800         {
5801             return found;
5802         }
5803     }
5804 
5805     return NULL;
5806 }
5807 
5808 ///////////////////////////////////////////////////////////////////////////////
FindParentFolderInfo(const widget_info * child) const5809 folder_info *studiox_project::FindParentFolderInfo(const widget_info *child) const
5810 {
5811     for (int DisplayIndex = 0; DisplayIndex < MAX_DISPLAYS; DisplayIndex++)
5812     {
5813         folder_info *folder = mDisplays[DisplayIndex].GetFirstChildFolder();
5814         while (folder)
5815         {
5816             if (IsWidgetInInfoTree(folder->GetFirstChildWidget(), child))
5817             {
5818                 return folder;
5819             }
5820             folder = folder->GetNextFolder();
5821         }
5822     }
5823 
5824     return NULL;
5825 }
5826 
5827 
5828 ///////////////////////////////////////////////////////////////////////////////
FindWidgetInfo(const GX_WIDGET * widget) const5829 widget_info *studiox_project::FindWidgetInfo(const GX_WIDGET *widget) const
5830 {
5831     widget_info *found = NULL;
5832 
5833     if (widget && (widget->gx_widget_type == GX_TYPE_MENU_LIST))
5834     {
5835         widget = ((GX_MENU_LIST *)widget)->gx_menu_list_owner;
5836     }
5837 
5838     for (int Display = 0; Display < MAX_DISPLAYS; Display++)
5839     {
5840         folder_info *pFolder = mDisplays[Display].GetFirstChildFolder();
5841         found = FindWidgetInfo(pFolder, widget);
5842         if (found)
5843         {
5844             return found;
5845         }
5846     }
5847     return NULL;
5848 }
5849 
5850 ///////////////////////////////////////////////////////////////////////////////
FindWidgetInfo(const folder_info * folder,const GX_WIDGET * widget) const5851 widget_info *studiox_project::FindWidgetInfo(const folder_info *folder, const GX_WIDGET *widget) const
5852 {
5853     widget_info *found = NULL;
5854     while (folder)
5855     {
5856         widget_info *child = folder->GetFirstChildWidget();
5857 
5858         if (child)
5859         {
5860             if (child->widget == widget)
5861             {
5862                 return child;
5863             }
5864             found = FindWidgetInfo(child, widget);
5865 
5866             if (found)
5867             {
5868                 return found;
5869             }
5870         }
5871         folder = folder->GetNextFolder();
5872     }
5873     return NULL;
5874 }
5875 
5876 ///////////////////////////////////////////////////////////////////////////////
FindWidgetInfo(const widget_info * start,const GX_WIDGET * widget) const5877 widget_info *studiox_project::FindWidgetInfo(const widget_info *start, const GX_WIDGET *widget) const
5878 {
5879     widget_info *found = NULL;
5880 
5881     while(start)
5882     {
5883         if (start->widget == widget)
5884         {
5885             return (widget_info *)start;
5886         }
5887 
5888         if (start->GetChildWidgetInfo())
5889         {
5890             found = FindWidgetInfo(start->GetChildWidgetInfo(), widget);
5891 
5892             if (found)
5893             {
5894                 return found;
5895             }
5896         }
5897         start = start->GetNextWidgetInfo();
5898     }
5899     return NULL;
5900 }
5901 
5902 ///////////////////////////////////////////////////////////////////////////////
copy(const folder_info & other)5903 void folder_info::copy(const folder_info &other)
5904 {
5905     folder_name = other.folder_name;
5906     output_filename = other.output_filename;
5907     this->first_widget = NULL;
5908     this->next = NULL;
5909 }
5910 
5911 ///////////////////////////////////////////////////////////////////////////////
operator =(const folder_info & other)5912 folder_info &folder_info::operator=(const folder_info &other)
5913 {
5914     copy(other);
5915     return *this;
5916 }
5917 
5918 ///////////////////////////////////////////////////////////////////////////////
folder_info()5919 folder_info::folder_info()
5920 {
5921     folder_name.Empty();
5922     output_filename.Empty();
5923     first_widget = NULL;
5924     next = NULL;
5925 }
5926 
5927 ///////////////////////////////////////////////////////////////////////////////
folder_info(const folder_info & other,BOOL copy_next)5928 folder_info::folder_info(const folder_info &other, BOOL copy_next)  // copy constructor
5929 {
5930     copy(other);
5931 
5932     folder_info * sib_dst;
5933     const folder_info *sib_src;
5934 
5935     if (other.first_widget)
5936     {
5937         this->first_widget = new widget_info(*other.first_widget, TRUE);
5938     }
5939 
5940     if (copy_next)
5941     {
5942         sib_dst = this;
5943         sib_src = &other;
5944 
5945         while (sib_src->next)
5946         {
5947             sib_dst->next = new folder_info(*sib_src->next, FALSE);
5948             sib_dst = sib_dst->next;
5949             sib_src = sib_src->next;
5950         }
5951     }
5952 
5953 }
5954 
5955 ///////////////////////////////////////////////////////////////////////////////
SetFirstChildFolder(folder_info * folder)5956 void display_info::SetFirstChildFolder(folder_info *folder)
5957 {
5958     this->first_folder = folder;
5959 }
5960 
5961 ///////////////////////////////////////////////////////////////////////////////
folder_info(CString name)5962 folder_info::folder_info(CString name)
5963 {
5964     folder_name = name;
5965     output_filename.Empty();
5966     first_widget = NULL;
5967     next = NULL;
5968 }
5969 
5970 ///////////////////////////////////////////////////////////////////////////////
~folder_info()5971 folder_info::~folder_info()
5972 {
5973     folder_info *temp;
5974     folder_info *test;
5975     if (first_widget)
5976     {
5977         delete first_widget;
5978         first_widget = NULL;
5979     }
5980 
5981 
5982     test = next;
5983     next = NULL;
5984     while (test)
5985     {
5986         temp = test->next;
5987         test->next = NULL;
5988         delete test;
5989         test = temp;
5990     }
5991 }
5992 
5993 ///////////////////////////////////////////////////////////////////////////////
SetFirstChildWidget(widget_info * info)5994 void folder_info::SetFirstChildWidget(widget_info *info)
5995 {
5996     //if (first_widget)
5997     //{
5998     //    info->next = first_widget;
5999     //}
6000     first_widget = info;
6001 }
6002 
6003 ///////////////////////////////////////////////////////////////////////////////
SetNextFolder(folder_info * info)6004 void folder_info::SetNextFolder(folder_info *info)
6005 {
6006     next = info;
6007 }
6008 
SetFirstResourceInfo(res_info * info)6009 void theme_info::SetFirstResourceInfo(res_info *info)
6010 {
6011     first_resource = info;
6012 }