1 
2 #include "studiox_includes.h"
3 
4 #ifdef _DEBUG
5 #define new DEBUG_NEW
6 #endif
7 
menu_service_provider()8 menu_service_provider::menu_service_provider()
9 {
10 }
11 
GetVarDeclaration()12 CString menu_service_provider::GetVarDeclaration()
13 {
14     return CString("GX_MENU_MEMBERS_DECLARE");
15 }
16 
DeclarePropertiesStruct()17 CString menu_service_provider::DeclarePropertiesStruct()
18 {
19     CString out;
20 
21     out.Format(_T("typedef struct\n")
22         _T("{\n")
23         _T("%s\n")
24         _T("    GX_VALUE       text_x_offset;\n")
25         _T("    GX_VALUE       text_y_offset;\n")
26         _T("    GX_VALUE       list_total_count;\n")
27         _T("} GX_MENU_PROPERTIES;\n\n"),
28         pixelmap_prompt_service_provider::DeclarePropertiesStructContent());
29     return out;
30 }
31 
WriteExtendedProperties(screen_generator * gen,CString & prefix,widget_info * info)32 CString menu_service_provider::WriteExtendedProperties(screen_generator *gen, CString &prefix, widget_info *info)
33 {
34     CString out;
35     CString propname = prefix + info->app_name;
36     out.Format(_T("GX_MENU_PROPERTIES %s_properties =\n")
37         _T("{\n")
38         _T("%s\n")
39         _T("    %d, /* text display x offset*/\n")
40         _T("    %d, /* text display y offset*/\n")
41         _T("    %d, /* list_total_count*/\n")
42         _T("};\n"),
43         propname,
44         pixelmap_prompt_service_provider::WriteExtendedPropertiesContent(gen, info, TRUE),
45         info->ewi.menu.text_x_offset,
46         info->ewi.menu.text_y_offset,
47         info->ewi.menu.list_total_count);
48     return out;
49 }
50 
GetCreateFromDefFunctionName()51 CString menu_service_provider::GetCreateFromDefFunctionName()
52 {
53     return CString("gx_studio_menu_create");
54 }
55 
GetCreateFromDefFunction(int version)56 CString menu_service_provider::GetCreateFromDefFunction(int version)
57 {
58     CString out;
59     MakeCreatePreamble("menu", version, out);
60 
61     out += "{\n"
62         "    UINT status;\n"
63         "    GX_MENU *menu = (GX_MENU *) control_block;\n"
64         "    GX_MENU_PROPERTIES *props = (GX_MENU_PROPERTIES *) info->properties;\n"
65         "    status = gx_menu_create(menu, info->widget_name, parent,\n"
66         "               props->string_id,\n"
67         "               props->fill_map_id,\n"
68         "               info->style, info->widget_id, &info->size);\n"
69         "\n"
70         "    if (status == GX_SUCCESS)\n"
71         "    {\n"
72         "        menu->gx_menu_list_total_count = props->list_total_count;\n"
73         "        gx_menu_text_offset_set(menu, props->text_x_offset, props->text_y_offset);\n"
74         "        gx_pixelmap_prompt_pixelmap_set((GX_PIXELMAP_PROMPT *)menu,\n"
75         "                                        props->left_map_id,\n"
76         "                                        props->fill_map_id,\n"
77         "                                        props->right_map_id,\n"
78         "                                        props->selected_left_map_id,\n"
79         "                                        props->selected_fill_map_id,\n"
80         "                                        props->selected_right_map_id);\n"
81         "        gx_prompt_font_set((GX_PROMPT *)menu, props->font_id);\n";
82 
83     if (version > 50401)
84     {
85         out += "#if defined(GUIX_5_4_0_COMPATIBILITY)\n"
86             "        gx_prompt_text_color_set((GX_PROMPT *)menu, props->normal_text_color_id, props->selected_text_color_id);\n"
87             "#else\n"
88             "        gx_prompt_text_color_set((GX_PROMPT *)menu, props->normal_text_color_id, props->selected_text_color_id, props->disabled_text_color_id);\n"
89             "#endif\n";
90     }
91     else
92     {
93         out += "        gx_prompt_text_color_set((GX_PROMPT *)menu, props->normal_text_color_id, props->selected_text_color_id);\n";
94     }
95     out +=  "    }\n"
96             "    return status;\n"
97             "}\n";
98 
99     return out;
100 }
101 
CreateNewInstance(GX_WIDGET * parent)102 widget_info *menu_service_provider::CreateNewInstance(GX_WIDGET *parent)
103 {
104     GX_RECTANGLE size;
105     gx_utility_rectangle_define(&size, 0, 0, 99, 23);
106     gx_utility_rectangle_center(&size, &parent->gx_widget_size);
107 
108     GX_MENU *menu = new GX_MENU;
109     GX_RESOURCE_ID string_id = GetStringId("menu");
110 
111     gx_menu_create(menu, "menu", parent, string_id, 0,
112         GX_STYLE_ENABLED | GX_STYLE_BORDER_THIN | GX_STYLE_TEXT_LEFT, 0, &size);
113 
114     widget_info *info = InitWidgetInfo((GX_WIDGET *)menu);
115     info->pixelmap_id[FILL_PIXELMAP_INDEX] = 0;
116     info->pixelmap_id[LEFT_PIXELMAP_INDEX] = 0;
117     info->pixelmap_id[RIGHT_PIXELMAP_INDEX] = 0;
118     info->pixelmap_id[SELECTED_FILL_PIXELMAP_INDEX] = 0;
119     info->pixelmap_id[SELECTED_LEFT_PIXELMAP_INDEX] = 0;
120     info->pixelmap_id[SELECTED_RIGHT_PIXELMAP_INDEX] = 0;
121     info->string_id[0] = string_id;
122     info->font_id[0] = menu->gx_prompt_font_id;
123     info->color_id[NORMAL_TEXT_COLOR_INDEX] = menu->gx_prompt_normal_text_color;
124     info->color_id[SELECTED_TEXT_COLOR_INDEX] = menu->gx_prompt_selected_text_color;
125     info->color_id[DISABLED_TEXT_COLOR_INDEX] = menu->gx_prompt_disabled_text_color;
126     info->ewi.menu.text_x_offset = menu->gx_menu_text_x_offset;
127     info->ewi.menu.text_y_offset = menu->gx_menu_text_y_offset;
128     info->ewi.menu.list_total_count = menu->gx_menu_list_total_count;
129 
130     // if insert mode is true, every time we insert a widget to the menu,
131     // the inserted widget will be treat as a menu item
132     info->ewi.menu.insert_as_menu_item = TRUE;
133 
134     return info;
135 }
136 
GenerateFromInfo(GX_WIDGET * parent,widget_info * info)137 GX_WIDGET *menu_service_provider::GenerateFromInfo(GX_WIDGET *parent, widget_info *info)
138 {
139     GX_MENU *menu = new GX_MENU;
140 
141     gx_menu_create(menu,
142         (CHAR *)info->app_name.GetString(),
143         parent,
144         info->string_id[0],
145         info->pixelmap_id[FILL_PIXELMAP_INDEX],
146         info->style, 0, &info->size);
147 
148     gx_menu_text_offset_set(menu, info->ewi.menu.text_x_offset, info->ewi.menu.text_y_offset);
149 
150     gx_pixelmap_prompt_pixelmap_set((GX_PIXELMAP_PROMPT *)menu,
151         info->pixelmap_id[LEFT_PIXELMAP_INDEX],
152         info->pixelmap_id[FILL_PIXELMAP_INDEX],
153         info->pixelmap_id[RIGHT_PIXELMAP_INDEX],
154         info->pixelmap_id[SELECTED_LEFT_PIXELMAP_INDEX],
155         info->pixelmap_id[SELECTED_FILL_PIXELMAP_INDEX],
156         info->pixelmap_id[SELECTED_RIGHT_PIXELMAP_INDEX]);
157 
158     gx_widget_fill_color_set((GX_PROMPT *)menu,
159         info->color_id[NORMAL_FILL_COLOR_INDEX],
160         info->color_id[SELECTED_FILL_COLOR_INDEX],
161         info->color_id[DISABLED_FILL_COLOR_INDEX]);
162 
163     gx_prompt_text_color_set((GX_PROMPT *)menu,
164         info->color_id[NORMAL_TEXT_COLOR_INDEX],
165         info->color_id[SELECTED_TEXT_COLOR_INDEX],
166         info->color_id[DISABLED_TEXT_COLOR_INDEX]);
167     gx_prompt_font_set((GX_PROMPT *)menu, info->font_id[0]);
168 
169     menu->gx_menu_list_total_count = info->ewi.menu.list_total_count;
170 
171     return (GX_WIDGET *)menu;
172 }
173 
SaveToProject(xml_writer & writer,studiox_project * project,int display,widget_info * info)174 void menu_service_provider::SaveToProject(xml_writer &writer, studiox_project *project, int display, widget_info *info)
175 {
176     pixelmap_prompt_service_provider::SaveToProject(writer, project, display, info);
177     writer.WriteInt("text_x_offset", info->ewi.menu.text_x_offset);
178     writer.WriteInt("text_y_offset", info->ewi.menu.text_y_offset);
179     writer.WriteInt("list_total_count", info->ewi.menu.list_total_count);
180     writer.WriteBool("insert_as_menu_item", info->ewi.menu.insert_as_menu_item);
181 }
182 
ReadFromProject(xml_reader & reader,studiox_project * project,int display,widget_info * info,ULONG valid_styles)183 void menu_service_provider::ReadFromProject(xml_reader &reader, studiox_project *project, int display, widget_info *info, ULONG valid_styles)
184 {
185     valid_styles |= GX_STYLE_MENU_EXPANDED;
186     pixelmap_prompt_service_provider::ReadFromProject(reader, project, display, info, valid_styles);
187     reader.ReadInt("text_x_offset", info->ewi.menu.text_x_offset);
188     reader.ReadInt("text_y_offset", info->ewi.menu.text_y_offset);
189     reader.ReadInt("list_total_count", info->ewi.menu.list_total_count);
190     reader.ReadBool("insert_as_menu_item", info->ewi.menu.insert_as_menu_item);
191 }
192 
AssignTextOffset(widget_info * info,int text_x_offset,int text_y_offset)193 void menu_service_provider::AssignTextOffset(widget_info *info, int text_x_offset, int text_y_offset)
194 {
195     gx_menu_text_offset_set((GX_MENU *)info->widget, text_x_offset, text_y_offset);
196     info->ewi.menu.text_x_offset = text_x_offset;
197     info->ewi.menu.text_y_offset = text_y_offset;
198 }
199 
AssignStyle(widget_info * info,int style)200 void menu_service_provider::AssignStyle(widget_info *info, int style)
201 {
202     GX_WIDGET *parent = info->widget->gx_widget_parent;
203     GX_WIDGET *top_level_container;
204     GX_WIDGET *child;
205     widget_info *child_info;
206     studiox_project *project = GetOpenProject();
207     project_view *project_view = GetProjectView();
208     int old_style = info->style;
209     BOOL update_size = FALSE;
210     GX_RECTANGLE dirty;
211 
212     gx_widget_style_set(info->widget, style);
213     info->style = style;
214 
215     top_level_container = menu_service_provider::TopLevelMenuContainerFind(info->widget);
216 
217     if (!top_level_container)
218     {
219         //the menu is not a member of accordion menu or tree view,just return
220         return;
221     }
222 
223     if ((old_style & GX_STYLE_MENU_EXPANDED) !=
224         (style & GX_STYLE_MENU_EXPANDED))
225     {
226         if (project && parent && parent->gx_widget_type == GX_TYPE_ACCORDION_MENU)
227         {
228             if (style & GX_STYLE_MENU_EXPANDED)
229             {
230                 // Remove expanded style from neighbor widgets.
231                 child = parent->gx_widget_first_child;
232 
233                 while (child)
234                 {
235                     if ((child != info->widget) &&
236                         (child->gx_widget_type == GX_TYPE_MENU))
237                     {
238                         child_info = project->FindWidgetInfo(child);
239                         gx_widget_style_remove(child, GX_STYLE_MENU_EXPANDED);
240                         child_info->style = child->gx_widget_style;
241                     }
242 
243                     child = child->gx_widget_next;
244                 }
245             }
246         }
247 
248         update_size = TRUE;
249     }
250 
251     if (top_level_container != parent)
252     {
253         // If new style have GX_STYLE_MENU_EXPANDED,
254         // check if we need to add GX_STYLE_MENU_EXPANDED to the parent.
255         if (parent->gx_widget_type != GX_TYPE_MENU_LIST)
256         {
257             parent = parent->gx_widget_parent;
258         }
259 
260         if ((style & GX_STYLE_MENU_EXPANDED) &&
261             (parent->gx_widget_type == GX_TYPE_MENU_LIST))
262         {
263             child = ((GX_MENU_LIST *)parent)->gx_menu_list_owner;
264 
265             child_info = project->FindWidgetInfo(child);
266             AssignStyle(child_info, child->gx_widget_style | GX_STYLE_MENU_EXPANDED);
267         }
268     }
269 
270     if (update_size)
271     {
272         //Reposition accordion menu.
273         switch (top_level_container->gx_widget_type)
274         {
275         case GX_TYPE_ACCORDION_MENU:
276             gx_accordion_menu_position((GX_ACCORDION_MENU *)top_level_container);
277             break;
278         case GX_TYPE_TREE_VIEW:
279             gx_tree_view_position((GX_TREE_VIEW *)top_level_container);
280             dirty = top_level_container->gx_widget_size;
281             dirty.gx_rectangle_top = info->size.gx_rectangle_top;
282             gx_system_dirty_partial_add(top_level_container, &dirty);
283             break;
284         }
285 
286         if (project_view)
287         {
288             project_view->UpdateChildPositions(project->FindWidgetInfo(parent));
289         }
290     }
291 }
292 
TopLevelMenuContainerFind(GX_WIDGET * start)293 GX_WIDGET *menu_service_provider::TopLevelMenuContainerFind(GX_WIDGET *start)
294 {
295     GX_WIDGET *parent;
296     GX_WIDGET *found = GX_NULL;
297     GX_WIDGET *temp;
298 
299     if ((start->gx_widget_type == GX_TYPE_ACCORDION_MENU) ||
300         (start->gx_widget_type == GX_TYPE_TREE_VIEW))
301     {
302         found = start;
303     }
304 
305     parent = start->gx_widget_parent;
306     if (parent)
307     {
308         switch (parent->gx_widget_type)
309         {
310         case GX_TYPE_TREE_VIEW:
311             found = parent;
312             break;
313 
314         case GX_TYPE_ACCORDION_MENU:
315             //the accordion menu is the child of another accordion menu
316             temp = TopLevelMenuContainerFind(parent);
317             if (temp)
318             {
319                 found = temp;
320             }
321             break;
322 
323         case GX_TYPE_MENU_LIST:
324             //the accordion menu is the child of a menu list
325             parent = ((GX_MENU_LIST *)parent)->gx_menu_list_owner;
326             parent = parent->gx_widget_parent;
327             if (parent)
328             {
329                 //the menu list owner is the child of another accordion menu
330                 temp = TopLevelMenuContainerFind(parent);
331                 if (temp)
332                 {
333                     found = temp;
334                 }
335             }
336             break;
337         }
338     }
339 
340     return found;
341 }
342 
Autosize(widget_info * info)343 void menu_service_provider::Autosize(widget_info *info)
344 {
345     CheckResizeToText(info);
346     CheckResizeToPixelmap(info, RESIZE_MODE_HEIGHT);
347 }
348 
349