1
2 #include "studiox_includes.h"
3 extern "C"{
4 #include "gx_utility.h"
5 }
6
7 #ifdef _DEBUG
8 #define new DEBUG_NEW
9 #endif
10
11 typedef struct {
12 USHORT widget_type;
13 char *event_process_name;
14 } event_process_entry;
15
16 event_process_entry default_event_process_table [] = {
17 {GX_TYPE_WIDGET, "gx_widget_event_process"},
18 {GX_TYPE_BUTTON, "gx_button_event_process"},
19 {GX_TYPE_TEXT_BUTTON, "gx_button_event_process"},
20 {GX_TYPE_MULTI_LINE_TEXT_BUTTON, "gx_multi_line_text_button_event_process"},
21 {GX_TYPE_RADIO_BUTTON, "gx_button_event_process"},
22 {GX_TYPE_CHECKBOX, "gx_checkbox_event_process"},
23 {GX_TYPE_PIXELMAP_BUTTON, "gx_pixelmap_button_event_process"},
24 {GX_TYPE_SHADOW_BUTTON, "gx_button_event_process"},
25 {GX_TYPE_ICON_BUTTON, "gx_button_event_process"},
26 {GX_TYPE_SPIN_BUTTON, "gx_button_event_process"},
27 {GX_TYPE_ICON, "gx_icon_event_process"},
28 {GX_TYPE_SPRITE, "gx_sprite_event_process"},
29 {GX_TYPE_CIRCULAR_GAUGE, "gx_circular_gauge_event_process"},
30 {GX_TYPE_SLIDER, "gx_slider_event_process"},
31 {GX_TYPE_PIXELMAP_SLIDER, "gx_pixelmap_slider_event_process"},
32 {GX_TYPE_VERTICAL_SCROLL, "gx_scrollbar_event_process"},
33 {GX_TYPE_HORIZONTAL_SCROLL, "gx_scrollbar_event_process"},
34 {GX_TYPE_PROGRESS_BAR, "gx_progress_bar_event_process"},
35 {GX_TYPE_RADIAL_PROGRESS_BAR, "gx_radial_progress_bar_event_process"},
36 {GX_TYPE_PROMPT, "gx_widget_event_process"},
37 {GX_TYPE_NUMERIC_PROMPT, "gx_widget_event_process"},
38 {GX_TYPE_PIXELMAP_PROMPT, "gx_widget_event_process"},
39 {GX_TYPE_NUMERIC_PIXELMAP_PROMPT, "gx_widget_event_process"},
40 {GX_TYPE_SINGLE_LINE_TEXT_INPUT, "gx_single_line_text_input_event_process"},
41 {GX_TYPE_PIXELMAP_TEXT_INPUT, "gx_single_line_text_input_event_process"},
42 {GX_TYPE_DROP_LIST, "gx_drop_list_event_process"},
43 {GX_TYPE_MENU_LIST, "gx_widget_event_process"},
44 {GX_TYPE_MENU, "gx_menu_event_process"},
45 {GX_TYPE_ACCORDION_MENU, "gx_accordion_menu_event_process"},
46 {GX_TYPE_WINDOW, "gx_window_event_process"},
47 {GX_TYPE_ROOT_WINDOW, "gx_window_event_process"},
48 {GX_TYPE_VERTICAL_LIST, "gx_vertical_list_event_process"},
49 {GX_TYPE_HORIZONTAL_LIST, "gx_horizontal_list_event_process"},
50 {GX_TYPE_POPUP_LIST, "gx_popup_list_event_process"},
51 {GX_TYPE_MULTI_LINE_TEXT_VIEW, "gx_multi_line_text_view_event_process"},
52 {GX_TYPE_MULTI_LINE_TEXT_INPUT, "gx_multi_line_text_input_event_process"},
53 {GX_TYPE_LINE_CHART, "gx_window_event_process"},
54 {GX_TYPE_DIALOG, "gx_window_event_process"},
55 {GX_TYPE_KEYBOARD, "gx_window_event_process"},
56 {GX_TYPE_SCROLL_WHEEL, "gx_scroll_wheel_event_process"},
57 {GX_TYPE_TEXT_SCROLL_WHEEL, "gx_scroll_wheel_event_process"},
58 {GX_TYPE_STRING_SCROLL_WHEEL, "gx_scroll_wheel_event_process"},
59 {GX_TYPE_NUMERIC_SCROLL_WHEEL, "gx_scroll_wheel_event_process"},
60 {GX_TYPE_GENERIC_SCROLL_WHEEL, "gx_generic_scroll_wheel_event_process"},
61 {GX_TYPE_TREE_VIEW, "gx_tree_view_event_process"},
62 {0, NULL}
63 };
64
65
66 ///////////////////////////////////////////////////////////////////////////////
widget_service_provider()67 widget_service_provider::widget_service_provider()
68 {
69 }
70
71 ///////////////////////////////////////////////////////////////////////////////
GetVarDeclaration()72 CString widget_service_provider::GetVarDeclaration()
73 {
74 return CString("GX_WIDGET_MEMBERS_DECLARE");
75 }
76
77 ///////////////////////////////////////////////////////////////////////////////
GetDefaultEventProcess(int widget_type)78 CString widget_service_provider::GetDefaultEventProcess(int widget_type)
79 {
80 event_process_entry *entry = default_event_process_table;
81 while(entry->widget_type)
82 {
83 if (entry->widget_type == widget_type)
84 {
85 return CString(entry->event_process_name);
86 }
87 entry++;
88 }
89 return CString("GX_NULL");
90 }
91
92 ///////////////////////////////////////////////////////////////////////////////
GetCreateFromDefFunctionName()93 CString widget_service_provider::GetCreateFromDefFunctionName()
94 {
95 return CString("gx_studio_widget_create");
96 }
97
MakeCreatePreamble(char * name,int version,CString & out)98 void widget_service_provider::MakeCreatePreamble(char *name, int version, CString &out)
99 {
100 CString string(name);
101
102 if (version > 50)
103 {
104 out.Format(_T("\nUINT gx_studio_%s_create(GX_CONST GX_STUDIO_WIDGET *info, GX_WIDGET *control_block, GX_WIDGET *parent)\n"), string);
105 }
106 else
107 {
108 out.Format(_T("\nUINT gx_studio_%s_create(GX_STUDIO_WIDGET *info, GX_WIDGET *control_block, GX_WIDGET *parent)\n"), string);
109 }
110 }
111
112 ///////////////////////////////////////////////////////////////////////////////
GetCreateFromDefFunction(int version)113 CString widget_service_provider::GetCreateFromDefFunction(int version)
114 {
115 CString out;
116 MakeCreatePreamble("widget", version, out);
117
118 out += "{\n"
119 " UINT status;\n"
120 " GX_WIDGET *widget = (GX_WIDGET *) control_block;\n"
121 " status = gx_widget_create(widget, info->widget_name, parent, info->style, info->widget_id, &info->size);\n"
122 " if (status == GX_SUCCESS)\n"
123 " {\n";
124
125 if (project_lib_version() > 50401)
126 {
127 "#if defined(GUIX_5_4_0_COMPATIBILITY)\n"
128 " gx_widget_fill_color_set(widget, info->normal_fill_color_id, info->selected_fill_color_id);\n"
129 "#else\n"
130 " gx_widget_fill_color_set(widget, info->normal_fill_color_id, info->selected_fill_color_id, info->disabled_fill_color_id);\n"
131 "#endif\n";
132 }
133 else
134 {
135 out += " gx_widget_fill_color_set(widget, info->normal_fill_color_id, info->selected_fill_color_id);\n";
136 }
137
138 out += " }\n"
139 " return status;\n"
140 "}\n";
141
142 return out;
143 }
144
145 ///////////////////////////////////////////////////////////////////////////////
DeclarePropertiesStruct()146 CString widget_service_provider::DeclarePropertiesStruct()
147 {
148 // GX_BOOL accepts_focus;\n"
149 CString out;
150
151 if (project_lib_version() > 50400)
152 {
153 out = ""
154 "typedef struct GX_STUDIO_WIDGET_STRUCT\n"
155 "{\n"
156 " GX_CHAR *widget_name;\n"
157 " USHORT widget_type;\n"
158 " USHORT widget_id;\n"
159 " #if defined(GX_WIDGET_USER_DATA)\n"
160 " INT user_data;\n"
161 " #endif\n"
162 " ULONG style;\n"
163 " ULONG status;\n"
164 " ULONG control_block_size;\n"
165 " GX_RESOURCE_ID normal_fill_color_id;\n"
166 " GX_RESOURCE_ID selected_fill_color_id;\n"
167 " GX_RESOURCE_ID disabled_fill_color_id;\n";
168 }
169 else if (project_lib_version() > 50205)
170 {
171 out = ""
172 "typedef struct GX_STUDIO_WIDGET_STRUCT\n"
173 "{\n"
174 " GX_CHAR *widget_name;\n"
175 " USHORT widget_type;\n"
176 " USHORT widget_id;\n"
177 " #if defined(GX_WIDGET_USER_DATA)\n"
178 " INT user_data;\n"
179 " #endif\n"
180 " ULONG style;\n"
181 " ULONG status;\n"
182 " ULONG control_block_size;\n"
183 " GX_RESOURCE_ID normal_fill_color_id;\n"
184 " GX_RESOURCE_ID selected_fill_color_id;\n";
185
186 }
187 else
188 {
189 out = ""
190 "typedef struct GX_STUDIO_WIDGET_STRUCT\n"
191 "{\n"
192 " GX_CHAR *widget_name;\n"
193 " USHORT widget_type;\n"
194 " USHORT widget_id;\n"
195 " ULONG style;\n"
196 " ULONG status;\n"
197 " ULONG control_block_size;\n"
198 " GX_RESOURCE_ID normal_fill_color_id;\n"
199 " GX_RESOURCE_ID selected_fill_color_id;\n";
200 }
201
202 if (project_lib_version() < 50100)
203 {
204 out += " UINT (*create_function) (struct GX_STUDIO_WIDGET_STRUCT *, GX_WIDGET *, GX_WIDGET *);\n";
205 }
206 else
207 {
208 out += " UINT (*create_function) (GX_CONST struct GX_STUDIO_WIDGET_STRUCT *, GX_WIDGET *, GX_WIDGET *);\n";
209 }
210 out += " void (*draw_function) (GX_WIDGET *);\n"
211 " UINT (*event_function) (GX_WIDGET *, GX_EVENT *);\n"
212 " GX_RECTANGLE size;\n";
213
214 if (project_lib_version() < 50100)
215 {
216 out += " struct GX_STUDIO_WIDGET_STRUCT *next_widget;\n"
217 " struct GX_STUDIO_WIDGET_STRUCT *child_widget;\n";
218 }
219 else
220 {
221 out += " GX_CONST struct GX_STUDIO_WIDGET_STRUCT *next_widget;\n"
222 " GX_CONST struct GX_STUDIO_WIDGET_STRUCT *child_widget;\n";
223 }
224 out += " ULONG control_block_offset;\n"
225 " GX_CONST void *properties;\n"
226 "} GX_STUDIO_WIDGET;\n\n";
227
228 out += "typedef struct\n"
229 "{\n"
230 " GX_CONST GX_STUDIO_WIDGET *widget_information;\n"
231 " GX_WIDGET *widget;\n"
232 "} GX_STUDIO_WIDGET_ENTRY;\n\n";
233
234 return out;
235 }
236
237
238
239 ///////////////////////////////////////////////////////////////////////////////
InitWidgetInfo(GX_WIDGET * child)240 widget_info *widget_service_provider::InitWidgetInfo(GX_WIDGET *child)
241 {
242 widget_info *info = new widget_info(child->gx_widget_type);
243 info->widget = child;
244 info->app_name = CString(child->gx_widget_name);
245 widget_factory::CreateUniqueAppNames(info);
246
247 info->style = child->gx_widget_style;
248 info->size = child->gx_widget_size;
249 if (child->gx_widget_status & GX_STATUS_ACCEPTS_FOCUS)
250 {
251 info->accepts_focus = TRUE;
252 }
253 else
254 {
255 info->accepts_focus = FALSE;
256 }
257 info->color_id[NORMAL_FILL_COLOR_INDEX] = child->gx_widget_normal_fill_color;
258 info->color_id[SELECTED_FILL_COLOR_INDEX] = child->gx_widget_selected_fill_color;
259 info->color_id[DISABLED_FILL_COLOR_INDEX] = child->gx_widget_disabled_fill_color;
260 return info;
261 }
262
263 ///////////////////////////////////////////////////////////////////////////////
GetStringId(char * string)264 GX_RESOURCE_ID widget_service_provider::GetStringId(char *string)
265 {
266 GX_RESOURCE_ID string_id = 0;
267 studiox_project *project = GetOpenProject();
268
269 if (project)
270 {
271 CString str(string);
272
273 int display = GetProjectView()->GetActiveDisplay();
274 string_table *table = project->mDisplays[display].stable;
275
276 if (table)
277 {
278 int string_index = table->CheckAddString(str);
279 CString id_name = table->GetStringId(string_index);
280 string_id = table->GetResourceId(id_name);
281 }
282 }
283 return string_id;
284 }
285
286 ///////////////////////////////////////////////////////////////////////////////
GetStringText(char * put,int size,widget_info * info)287 void widget_service_provider::GetStringText(char *put, int size, widget_info *info)
288 {
289 CString val;
290 studiox_project *project = GetOpenProject();
291
292 if (!project || !put || size <= 1)
293 {
294 return;
295 }
296 *put = 0;
297
298 int display = project->GetDisplayIndex(info);
299
300 if (display < 0)
301 {
302 display = GetProjectView()->GetActiveDisplay();
303 }
304
305 if (display >= 0)
306 {
307 string_table *table = project->mDisplays[display].stable;
308
309 if (table)
310 {
311 CString id_name = table->GetResourceIdName(info->string_id[0]);
312 val = table->GetString(id_name);
313 int char_count = val.GetLength();
314
315 if (char_count)
316 {
317 // The maximun UTF8 character is 6 bytes, calculate the maximun utf8 buffer size needed for the string.
318 int buffer_size = char_count * 6 + 1;
319 char *utf8buf = new char[buffer_size];
320 strcpy_s(utf8buf, buffer_size, CT2A(val.GetString(), CP_UTF8));
321
322 int len = strlen(utf8buf);
323
324 if (len < size)
325 {
326 strcpy_s(put, size, utf8buf);
327 }
328 else
329 {
330 GX_STRING string;
331 INT index;
332 INT glyph_len = 0;
333 index = 0;
334 string.gx_string_ptr = utf8buf;
335 string.gx_string_length = len;
336
337 /* Calculate the maximum bytes that could be set. */
338 while (index + glyph_len < size)
339 {
340 index += glyph_len;
341 _gx_utility_utf8_string_character_get(&string, GX_NULL, (UINT *)&glyph_len);
342 }
343 size = index;
344
345 strncpy(put, utf8buf, size);
346 put[size] = 0;
347 }
348
349 delete[] utf8buf;
350 }
351 }
352 }
353 }
354
355
356 ///////////////////////////////////////////////////////////////////////////////
CreateNewInstance(GX_WIDGET * parent)357 widget_info *widget_service_provider::CreateNewInstance(GX_WIDGET *parent)
358 {
359 GX_RECTANGLE size;
360 gx_utility_rectangle_define(&size, 0, 0, 79, 23);
361 gx_utility_rectangle_center(&size, &parent->gx_widget_size);
362
363 GX_WIDGET *widget = new GX_WIDGET;
364 gx_widget_create(widget, "widget", parent,
365 GX_STYLE_ENABLED, 0, &size);
366 widget_info *info = InitWidgetInfo(widget);
367 return info;
368 }
369
370 ///////////////////////////////////////////////////////////////////////////////
GenerateFromInfo(GX_WIDGET * parent,widget_info * info)371 GX_WIDGET *widget_service_provider::GenerateFromInfo(GX_WIDGET *parent, widget_info *info)
372 {
373 GX_WIDGET *widget = new GX_WIDGET;
374
375 gx_widget_create(widget,
376 (CHAR *) info->app_name.GetString(),
377 parent,
378 info->style,
379 0,
380 &info->size);
381
382 gx_widget_fill_color_set(widget,
383 info->color_id[NORMAL_FILL_COLOR_INDEX],
384 info->color_id[SELECTED_FILL_COLOR_INDEX],
385 info->color_id[DISABLED_FILL_COLOR_INDEX]);
386 return widget;
387 }
388
389 ///////////////////////////////////////////////////////////////////////////////
SaveToProject(xml_writer & writer,studiox_project * project,int display,widget_info * info)390 void widget_service_provider::SaveToProject(xml_writer &writer, studiox_project *project, int display, widget_info *info)
391 {
392 GX_WIDGET *widget = info->widget;
393
394 writer.WriteString("type", GetShortName());
395 writer.WriteString("app_name", info->app_name);
396 writer.WriteRect("size", info->size);
397 writer.WriteUnsigned("style", info->style);
398 writer.WriteInt("allocation", info->allocation);
399 writer.WriteBool("accepts_focus", info->accepts_focus);
400
401 WriteColorId(writer, project, display, "normal_fill_color", info->color_id[NORMAL_FILL_COLOR_INDEX]);
402 WriteColorId(writer, project, display, "selected_fill_color", info->color_id[SELECTED_FILL_COLOR_INDEX]);
403 WriteColorId(writer, project, display, "disabled_fill_color", info->color_id[DISABLED_FILL_COLOR_INDEX]);
404
405 if (!info->event_func.IsEmpty())
406 {
407 writer.WriteString("event_handler", info->event_func);
408 }
409 if (!info->draw_func.IsEmpty())
410 {
411 writer.WriteString("draw_func", info->draw_func);
412 }
413 if (!info->id_name.IsEmpty())
414 {
415 writer.WriteString("id_name", info->id_name);
416 }
417 if (!info->custom_name.IsEmpty())
418 {
419 writer.WriteString("custom_name", info->custom_name);
420 }
421 if (!info->user_data.IsEmpty())
422 {
423 writer.WriteString("user_data", info->user_data);
424 }
425
426 writer.WriteBool("template", info->is_template);
427 writer.WriteBool("visible_at_startup", info->visible_at_startup);
428 }
429
430 ///////////////////////////////////////////////////////////////////////////////
431 #define GLOBAL_STYLES GX_STYLE_BORDER_MASK|GX_STYLE_TRANSPARENT|GX_STYLE_DRAW_SELECTED|GX_STYLE_ENABLED
ReadFromProject(xml_reader & reader,studiox_project * project,int display,widget_info * info,ULONG valid_styles)432 void widget_service_provider::ReadFromProject(xml_reader &reader, studiox_project *project, int display, widget_info *info, ULONG valid_styles)
433 {
434 GX_WIDGET *widget = info->widget;
435 info->base_name = GetShortName();
436 reader.ReadString("app_name", info->app_name);
437 reader.ReadRect("size", info->size);
438 reader.ReadUnsigned("style", info->style);
439 reader.ReadInt("allocation", info->allocation);
440
441 valid_styles |= GLOBAL_STYLES;
442
443 if ((info->style & valid_styles) != info->style)
444 {
445 ErrorMsg("Project contains invalid widget styles. Resetting to default.");
446 info->style &= valid_styles;
447 }
448
449 if (!reader.ReadBool("accepts_focus", info->accepts_focus))
450 {
451 info->accepts_focus = TRUE;
452 }
453
454 info->color_id[NORMAL_FILL_COLOR_INDEX] = ReadColorId(reader, project, display, "normal_fill_color");
455 info->color_id[SELECTED_FILL_COLOR_INDEX] = ReadColorId(reader, project, display, "selected_fill_color");
456
457 if (project->mHeader.project_version > 54)
458 {
459 info->color_id[DISABLED_FILL_COLOR_INDEX] = ReadColorId(reader, project, display, "disabled_fill_color");
460 }
461 else
462 {
463 info->color_id[DISABLED_FILL_COLOR_INDEX] = info->color_id[NORMAL_FILL_COLOR_INDEX];
464 }
465
466 reader.ReadString("event_handler", info->event_func);
467 reader.ReadString("draw_func", info->draw_func);
468 reader.ReadString("id_name", info->id_name);
469 reader.ReadString("custom_name", info->custom_name);
470 reader.ReadString("user_data", info->user_data);
471
472 reader.ReadBool("template", info->is_template);
473 reader.ReadBool("visible_at_startup", info->visible_at_startup);
474 }
475
476 ///////////////////////////////////////////////////////////////////////////////
AssignColor(widget_info * info,int index,GX_RESOURCE_ID color_id)477 void widget_service_provider::AssignColor(widget_info *info, int index, GX_RESOURCE_ID color_id)
478 {
479 int save_id;
480 GX_WIDGET *widget = info->widget;
481
482 switch(index)
483 {
484 case NORMAL_FILL_COLOR_INDEX:
485 if (widget)
486 {
487 save_id = widget->gx_widget_selected_fill_color;
488 gx_widget_fill_color_set(widget, color_id, save_id, widget->gx_widget_disabled_fill_color);
489 }
490
491 info->color_id[NORMAL_FILL_COLOR_INDEX] = color_id;
492 break;
493
494 case SELECTED_FILL_COLOR_INDEX:
495 if (widget)
496 {
497 save_id = widget->gx_widget_normal_fill_color;
498 gx_widget_fill_color_set(widget, save_id, color_id, widget->gx_widget_disabled_fill_color);
499 }
500
501 info->color_id[SELECTED_FILL_COLOR_INDEX] = color_id;
502 break;
503
504 case DISABLED_FILL_COLOR_INDEX:
505 if (widget)
506 {
507 gx_widget_fill_color_set(widget, widget->gx_widget_normal_fill_color, widget->gx_widget_selected_fill_color, color_id);
508 }
509
510 info->color_id[DISABLED_FILL_COLOR_INDEX] = color_id;
511 break;
512 }
513 }
514
515 ///////////////////////////////////////////////////////////////////////////////
GetTextDimension(int base_type,GX_CONST GX_CHAR * text,GX_FONT * normal_font,GX_FONT * selected_font,INT & max_width,INT & max_height)516 void widget_service_provider::GetTextDimension(int base_type, GX_CONST GX_CHAR *text,
517 GX_FONT *normal_font, GX_FONT *selected_font, INT &max_width, INT &max_height)
518 {
519 GX_VALUE text_width = 0;
520 int text_height = 0;
521 GX_STRING string;
522
523 if (base_type == GX_TYPE_MULTI_LINE_TEXT_BUTTON)
524 {
525 // handle multi line text button
526 GX_CONST GX_CHAR *buffer = text;
527 GX_CONST GX_CHAR *line = NULL;
528 int line_index = 0;
529 int byte_count = 0;
530
531 while (buffer && (*buffer))
532 {
533 if ((*buffer == GX_KEY_CARRIAGE_RETURN) || (*buffer == GX_KEY_LINE_FEED))
534 {
535 if ((*buffer == GX_KEY_CARRIAGE_RETURN) && (*(buffer + 1) == GX_KEY_LINE_FEED))
536 {
537 buffer += 2;
538 }
539 else
540 {
541 buffer++;
542 }
543 line_index++;
544
545 if (line_index >= GX_MULTI_LINE_TEXT_BUTTON_MAX_LINES)
546 {
547 break;
548 }
549 else
550 {
551 string.gx_string_ptr = line;
552 string.gx_string_length = byte_count;
553
554 _gx_system_string_width_get_ext(normal_font, &string, &text_width);
555 if (text_width > max_width)
556 {
557 max_width = text_width;
558 }
559
560 text_height += normal_font->gx_font_line_height;
561
562 line = NULL;
563 byte_count = 0;
564 }
565 }
566 else
567 {
568 if (line == GX_NULL)
569 {
570 line = buffer;
571 }
572 byte_count++;
573 buffer++;
574 }
575 }
576
577 if (line)
578 {
579 string.gx_string_ptr = line;
580 string.gx_string_length = byte_count;
581
582 _gx_system_string_width_get_ext(normal_font, &string, &text_width);
583 if (text_width > max_width)
584 {
585 max_width = text_width;
586 }
587
588 text_height += normal_font->gx_font_line_height;
589 }
590
591 if (text_height > max_height)
592 {
593 max_height = text_height;
594 }
595 }
596 else
597 {
598 string.gx_string_ptr = text;
599 string.gx_string_length = strlen(text);
600 _gx_system_string_width_get_ext(normal_font, &string, &text_width);
601 text_height = normal_font->gx_font_line_height;
602
603 if (text_width > max_width)
604 {
605 max_width = text_width;
606 }
607
608 if (text_height > max_height)
609 {
610 max_height = text_height;
611 }
612
613 if (selected_font)
614 {
615 _gx_system_string_width_get_ext(selected_font, &string, &text_width);
616 text_height = selected_font->gx_font_line_height;
617
618 if (text_width > max_width)
619 {
620 max_width = text_width;
621 }
622
623 if (text_height > max_height)
624 {
625 max_height = text_height;
626 }
627 }
628 }
629 }
630
631 ///////////////////////////////////////////////////////////////////////////////
632 /* KGM- this should be change to create an instance of a widget (at least once),
633 and retrieve the border width for each border style (one time) and save this
634 information to an static array. Otherwise the GUIX libary and Studio can
635 conflict about the border width for each style.
636
637 This is a quick fix to get things working for now.
638
639 TECH_DEBT
640 */
GetBorderWidth(DWORD style)641 int widget_service_provider::GetBorderWidth(DWORD style)
642 {
643 int width = 0;
644
645 switch (style & GX_STYLE_BORDER_MASK)
646 {
647 case GX_STYLE_BORDER_RAISED:
648 case GX_STYLE_BORDER_RECESSED:
649 width = 2;
650 break;
651
652 case GX_STYLE_BORDER_THIN:
653 width = 1;
654 break;
655
656 case GX_STYLE_BORDER_THICK:
657 width = 5;
658 break;
659
660 case GX_STYLE_BORDER_NONE:
661 default:
662 width = 0;
663 break;
664 }
665 return width;
666 }
667
668 ///////////////////////////////////////////////////////////////////////////////
GetTextDrawDimension(widget_info * info,GX_DISPLAY * display,INT & draw_width,INT & draw_height)669 void widget_service_provider::GetTextDrawDimension(widget_info *info, GX_DISPLAY *display, INT &draw_width, INT &draw_height)
670 {
671 GX_VALUE border_width;
672
673 //pick up widget border
674 border_width = GetBorderWidth(info->style);
675
676 draw_width = (info->size.gx_rectangle_right - info->size.gx_rectangle_left + 1);
677 draw_width -= (border_width << 1);
678 draw_height = (info->size.gx_rectangle_bottom - info->size.gx_rectangle_top + 1);
679 draw_height -= (border_width << 1);
680
681 switch(info->basetype)
682 {
683 case GX_TYPE_STRING_SCROLL_WHEEL:
684 draw_height = info->ewi.string_scroll_wheel.base.row_height;
685 break;
686
687 case GX_TYPE_RADIO_BUTTON:
688 case GX_TYPE_CHECKBOX:
689 //for radio button and check box, removed pixemap draw area from client area
690 if (!(info->style & GX_STYLE_TEXT_CENTER))
691 {
692 GX_PIXELMAP *map = NULL;
693 UINT id;
694
695 if (info->basetype == GX_TYPE_RADIO_BUTTON)
696 {
697 id = info->pixelmap_id[RADIO_ON_PIXELMAP_INDEX];
698 if (!id)
699 {
700 id = GX_PIXELMAP_RADIO_ON_ID;
701 }
702 }
703 else
704 {
705 id = info->pixelmap_id[CHECKED_PIXELMAP_INDEX];
706 if (!id)
707 {
708 id = GX_PIXELMAP_CHECKBOX_ON_ID;
709 }
710 }
711
712 if (id < display->gx_display_pixelmap_table_size)
713 {
714 map = display->gx_display_pixelmap_table[id];
715 }
716
717 if (map)
718 {
719 draw_width -= map->gx_pixelmap_width * 3 / 2;
720 }
721 }
722 break;
723
724 case GX_TYPE_MENU:
725 draw_width -= info->ewi.menu.text_x_offset;
726 draw_height -= info->ewi.menu.text_y_offset;
727 break;
728
729 default:
730 break;
731 }
732
733 if (draw_width < 0)
734 {
735 draw_width = 0;
736 }
737
738 if (draw_height < 0)
739 {
740 draw_height = 0;
741 }
742 }
743
744 ///////////////////////////////////////////////////////////////////////////////
CalculateTextFitSize(widget_info * info,int display_index)745 GX_RECTANGLE widget_service_provider::CalculateTextFitSize(widget_info *info, int display_index)
746 {
747 studiox_project *project = GetOpenProject();
748 project_view *pview = GetProjectView();
749 GX_RECTANGLE newsize = info->size;
750
751 if (!project || !pview)
752 {
753 return newsize;
754 }
755
756 GX_DISPLAY *gx_display = get_target_view_display();
757 if (!gx_display)
758 {
759 return newsize;
760 }
761
762 display_info *display = &project->mDisplays[display_index];
763 string_table *stable = display->stable;
764 int index;
765 GX_RESOURCE_ID *id_list;
766 int id_count;
767 UINT normal_font_id = info->font_id[NORMAL_FONT_INDEX];
768 UINT selected_font_id = info->font_id[SELECTED_FONT_INDEX];
769 GX_FONT *normal_font = NULL;
770 GX_FONT *selected_font = NULL;
771 int text_draw_width;
772 int text_draw_height;
773
774 if (normal_font_id < gx_display->gx_display_font_table_size)
775 {
776 //pick up normal font
777 normal_font = gx_display->gx_display_font_table[normal_font_id];
778 }
779
780 if (!normal_font)
781 {
782 return newsize;
783 }
784
785 //calculate client width and height for text drawing
786 if (info->basetype == GX_TYPE_STRING_SCROLL_WHEEL)
787 {
788 // string scroll wheel haver selected font
789 id_list = info->ewi.string_scroll_wheel.string_id_list;
790 id_count = info->ewi.string_scroll_wheel.base.total_rows;
791
792 if (selected_font_id < gx_display->gx_display_font_table_size)
793 {
794 selected_font = gx_display->gx_display_font_table[selected_font_id];
795 }
796
797 if (!selected_font)
798 {
799 return newsize;
800 }
801 }
802 else
803 {
804 id_list = info->string_id;
805 id_count = NUM_WIDGET_STRINGS;
806 }
807
808 if (!id_list)
809 {
810 return newsize;
811 }
812
813 GetTextDrawDimension(info, gx_display, text_draw_width, text_draw_height);
814
815 CString string;
816 int language_count;
817 int language_index;
818
819 //calculate maximum text width and height
820 if ((info->basetype == GX_TYPE_NUMERIC_PIXELMAP_PROMPT) ||
821 (info->basetype == GX_TYPE_NUMERIC_PROMPT))
822 {
823 string.Format(_T("%d"), info->ewi.numeric_prompt_value);
824 id_count = 1;
825 language_count = 1;
826 }
827 else
828 {
829 language_count = stable->CountLanguages();
830 }
831
832 int text_width = 0;
833 int text_height = 0;
834 CString id_name;
835
836 for (language_index = 0; language_index < language_count; language_index++)
837 {
838 //calculate text dimension for one language
839 for (index = 0; index < id_count; index++)
840 {
841 if (id_list[index])
842 {
843 id_name = stable->GetResourceIdName(id_list[index]);
844 string = stable->GetString(id_name, language_index);
845 language_count = stable->CountLanguages();
846 }
847
848 if (!string.IsEmpty())
849 {
850 int char_count;
851 char *utf8buf;
852
853 // The maximun UTF8 character is 6 bytes, calculate the maximun utf8 buffer size needed for the string.
854 char_count = string.GetLength() * 6 + 1;
855 utf8buf = new char[char_count];
856 strcpy_s(utf8buf, char_count, CT2A(string.GetString(), CP_UTF8));
857
858 GetTextDimension(info->basetype, utf8buf, normal_font, selected_font, text_width, text_height);
859
860 delete[]utf8buf;
861 }
862
863 string.Empty();
864 }
865 }
866
867 newsize.gx_rectangle_right += (text_width - text_draw_width);
868 newsize.gx_rectangle_bottom += (text_height - text_draw_height);
869
870 return newsize;
871 }
872
873 ///////////////////////////////////////////////////////////////////////////////
CheckResizeToText(widget_info * info,INT resize_mode)874 BOOL widget_service_provider::CheckResizeToText(widget_info *info, INT resize_mode)
875 {
876 studiox_project *project = GetOpenProject();
877
878 if (!project || !info)
879 {
880 return FALSE;
881 }
882
883 int display = project->GetDisplayIndex(info);
884
885 if (display < 0)
886 {
887 return FALSE;
888 }
889
890 GX_RECTANGLE newsize = info->size;
891 GX_RECTANGLE fitsize = CalculateTextFitSize(info, display);
892 GX_VALUE border_width;
893
894 //pick up widget border
895 gx_widget_border_width_get(info->widget, &border_width);
896
897 if (border_width)
898 {
899 fitsize.gx_rectangle_right += 2;
900 fitsize.gx_rectangle_bottom += 2;
901 }
902
903 if (resize_mode == RESIZE_MODE_ALL ||
904 resize_mode == RESIZE_MODE_WIDTH)
905 {
906 newsize.gx_rectangle_right = fitsize.gx_rectangle_right;
907 }
908
909 if (resize_mode == RESIZE_MODE_ALL ||
910 resize_mode == RESIZE_MODE_HEIGHT)
911 {
912 newsize.gx_rectangle_bottom = fitsize.gx_rectangle_bottom;
913 }
914
915 if (!gx_utility_rectangle_compare(&newsize, &info->widget->gx_widget_size))
916 {
917 widget_factory::MoveWidget(info, newsize);
918 GetTargetScreen()->WidgetWasMoved(info);
919 GetPropsWin()->WidgetWasMoved();
920
921 return TRUE;
922 }
923
924 return FALSE;
925 }
926
927 ///////////////////////////////////////////////////////////////////////////////
CheckResizeToPixelmap(widget_info * info,int resize_mode,BOOL DontShrink)928 BOOL widget_service_provider::CheckResizeToPixelmap(widget_info *info,
929 int resize_mode, BOOL DontShrink)
930 {
931 GX_PIXELMAP *map = NULL;
932 GX_VALUE border_width;
933 int map_index;
934
935 int max_map_width = -1;
936 int max_map_height = -1;
937 studiox_project *project = GetOpenProject();
938
939 if (!project || !info)
940 {
941 return FALSE;
942 }
943
944 int display = project->GetDisplayIndex(info);
945 int active_theme = project->mDisplays[display].active_theme;
946
947 if (display >= 0)
948 {
949 for (map_index = 0; map_index < NUM_WIDGET_PIXELMAPS; map_index++)
950 {
951 if (info->pixelmap_id[map_index])
952 {
953 res_info *resource = project->FindResource(display, active_theme, RES_TYPE_PIXELMAP, info->pixelmap_id[map_index]);
954 if (resource)
955 {
956 map = resource->GetPixelmap();
957 if (map)
958 {
959 if (map->gx_pixelmap_width > max_map_width)
960 {
961 max_map_width = map->gx_pixelmap_width;
962 }
963 if (map->gx_pixelmap_height > max_map_height)
964 {
965 max_map_height = map->gx_pixelmap_height;
966 }
967 }
968 }
969 }
970 }
971 }
972
973 if (max_map_height <= 0 || max_map_width <= 0)
974 {
975 return FALSE;
976 }
977
978 // check to see if new size if any different
979
980 GX_RECTANGLE newsize = info->size;
981 //gx_widget_border_width_get(info->widget, &border_width);
982 border_width = GetBorderWidth(info->style);
983
984 if (resize_mode == RESIZE_MODE_ALL ||
985 resize_mode == RESIZE_MODE_WIDTH)
986 {
987 newsize.gx_rectangle_right = newsize.gx_rectangle_left + max_map_width + (border_width * 2) - 1;
988 }
989
990 if (resize_mode == RESIZE_MODE_ALL ||
991 resize_mode == RESIZE_MODE_HEIGHT)
992 {
993 newsize.gx_rectangle_bottom = newsize.gx_rectangle_top + max_map_height + (border_width * 2) - 1;
994 }
995
996 if (DontShrink)
997 {
998 if (newsize.gx_rectangle_bottom < info->size.gx_rectangle_bottom)
999 {
1000 return FALSE;
1001 }
1002 }
1003
1004 if (!gx_utility_rectangle_compare(&newsize, &info->widget->gx_widget_size))
1005 {
1006 if (info->widget)
1007 {
1008 gx_widget_resize(info->widget, &newsize);
1009 }
1010 info->size = newsize;
1011 GetPropsWin()->WidgetWasMoved();
1012 GetTargetScreen()->WidgetWasMoved(info);
1013 return TRUE;
1014 }
1015 return FALSE;
1016 }
1017
1018 ///////////////////////////////////////////////////////////////////////////////
WriteStringId(xml_writer & writer,studiox_project * project,int display,char * tag,GX_RESOURCE_ID resid)1019 void widget_service_provider::WriteStringId(xml_writer &writer, studiox_project *project, int display, char *tag, GX_RESOURCE_ID resid)
1020 {
1021 string_table *table = project->mDisplays[display].stable;
1022 CString idName;
1023
1024 if (!table)
1025 {
1026 return;
1027 }
1028
1029 idName = table->GetResourceIdName(resid);
1030
1031 if (!idName.IsEmpty())
1032 {
1033 writer.WriteString(tag, idName);
1034 }
1035 }
1036
1037 ///////////////////////////////////////////////////////////////////////////////
WriteFontId(xml_writer & writer,studiox_project * project,int display,char * tag,GX_RESOURCE_ID resid)1038 void widget_service_provider::WriteFontId(xml_writer &writer, studiox_project *project, int display, char *tag, GX_RESOURCE_ID resid)
1039 {
1040 CString FontName;
1041
1042 project->GetResourceName(display, RES_TYPE_FONT, resid, FontName);
1043
1044 if (!FontName.IsEmpty())
1045 {
1046 writer.WriteString(tag, FontName);
1047 }
1048 }
1049
1050 ///////////////////////////////////////////////////////////////////////////////
WritePixelmapId(xml_writer & writer,studiox_project * project,int display,char * tag,GX_RESOURCE_ID resid)1051 void widget_service_provider::WritePixelmapId(xml_writer &writer, studiox_project *project, int display, char *tag, GX_RESOURCE_ID resid)
1052 {
1053 CString PixName;
1054
1055 project->GetResourceName(display, RES_TYPE_PIXELMAP, resid, PixName);
1056
1057 if (!PixName.IsEmpty())
1058 {
1059 writer.WriteString(tag, PixName);
1060 }
1061 }
1062
1063 ///////////////////////////////////////////////////////////////////////////////
WriteColorId(xml_writer & writer,studiox_project * project,int display,char * tag,GX_RESOURCE_ID resid)1064 void widget_service_provider::WriteColorId(xml_writer &writer, studiox_project *project, int display, char *tag, GX_RESOURCE_ID resid)
1065 {
1066 CString ColorName;
1067
1068 project->GetResourceName(display, RES_TYPE_COLOR, resid, ColorName);
1069
1070 if (!ColorName.IsEmpty())
1071 {
1072 writer.WriteString(tag, ColorName);
1073 }
1074 }
1075
1076 ///////////////////////////////////////////////////////////////////////////////
ReadStringId(xml_reader & reader,studiox_project * project,int display,char * tag)1077 GX_RESOURCE_ID widget_service_provider::ReadStringId(xml_reader &reader, studiox_project *project, int display, char *tag)
1078 {
1079 ULONG res_id = 0;
1080 CString IdName;
1081
1082 if (project->mHeader.project_version <= 52)
1083 {
1084 reader.ReadUnsigned(tag, res_id, 0);
1085 }
1086 else
1087 {
1088 string_table *table = project->mDisplays[display].stable;
1089
1090 if (table)
1091 {
1092 reader.ReadString(tag, IdName);
1093 res_id = table->GetResourceId(IdName);
1094 }
1095 }
1096 return res_id;
1097 }
1098
1099 ///////////////////////////////////////////////////////////////////////////////
ReadFontId(xml_reader & reader,studiox_project * project,int display,char * tag)1100 GX_RESOURCE_ID widget_service_provider::ReadFontId(xml_reader &reader, studiox_project *project, int display, char *tag)
1101 {
1102 ULONG res_id = 0;
1103 CString IdName;
1104
1105 if (project->mHeader.project_version <= 52)
1106 {
1107 reader.ReadUnsigned(tag, res_id, 0);
1108
1109 // sanity check
1110 if (res_id > 10000)
1111 {
1112 res_id = 0;
1113 }
1114 }
1115 else
1116 {
1117 reader.ReadString(tag, IdName);
1118 res_id = project->GetResourceId(display, RES_TYPE_FONT, IdName);
1119 }
1120 return res_id;
1121 }
1122
1123 ///////////////////////////////////////////////////////////////////////////////
ReadPixelmapId(xml_reader & reader,studiox_project * project,int display,char * tag)1124 GX_RESOURCE_ID widget_service_provider::ReadPixelmapId(xml_reader &reader, studiox_project *project, int display, char *tag)
1125 {
1126 ULONG res_id = 0;
1127 CString IdName;
1128
1129 if (project->mHeader.project_version <= 52)
1130 {
1131 reader.ReadUnsigned(tag, res_id, 0);
1132
1133 // sanity check
1134 if (res_id > 10000)
1135 {
1136 res_id = 0;
1137 }
1138 }
1139 else
1140 {
1141 reader.ReadString(tag, IdName);
1142 res_id = project->GetResourceId(display, RES_TYPE_PIXELMAP, IdName);
1143 }
1144 return res_id;
1145
1146 }
1147
1148 ///////////////////////////////////////////////////////////////////////////////
ReadColorId(xml_reader & reader,studiox_project * project,int display,char * tag)1149 GX_RESOURCE_ID widget_service_provider::ReadColorId(xml_reader &reader, studiox_project *project, int display, char *tag)
1150 {
1151 ULONG res_id = 0;
1152 CString IdName;
1153
1154 if (project->mHeader.project_version <= 52)
1155 {
1156 reader.ReadUnsigned(tag, res_id, 0);
1157
1158 // sanity check
1159 if (res_id > 10000)
1160 {
1161 res_id = 0;
1162 }
1163 }
1164 else
1165 {
1166 reader.ReadString(tag, IdName);
1167 res_id = project->GetResourceId(display, RES_TYPE_COLOR, IdName);
1168 }
1169 return res_id;
1170
1171 }
1172
1173