5 static __attribute__((unused)) void UnusedFunction()
14 a.OnEdit(null,null,0,0,0,0,0);
15 a.OnDisplay(null,0,0,0,0,0,0);
19 extern int __ecereVMethodID_class_OnEdit;
20 extern int __ecereVMethodID_class_OnDisplay;
21 extern int __ecereVMethodID_class_OnGetString;
22 extern int __ecereVMethodID_class_OnFree;
23 extern int __ecereVMethodID_class_OnCompare;
24 extern int __ecereVMethodID_class_OnCopy;
25 extern int __ecereVMethodID_class_OnSaveEdit;
27 //#define SHOW_METHODS
30 // *** THESE METHODS SHOULD BE IMPROVED UPON AND USED TO SET PROPERTIES FROM NOW ON ***
31 // (Other locations where this will be useful: JSON (DataValue version?), CodeEditor, ...)
32 // This takes in a value according to the any_object rules
34 void SetPropValue(Property prop, void * object, any_object value)
36 Class type = prop.dataTypeClass;
38 type = prop.dataTypeClass = eSystem_FindClass(prop._class.module, prop.dataTypeString);
40 if(type.type == normalClass || type.type == noHeadClass || type.type == structClass)
42 ((void (*)(void *, void *))(void *)prop.Set)(object, value);
44 // TOFIX: How to swiftly handle classes with base data type?
45 else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
47 ((void (*)(void *, double))(void *)prop.Set)(object, *(double *)value);
49 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
51 ((void (*)(void *, float))(void *)prop.Set)(object, *(float *)value);
53 else if(type.typeSize == sizeof(int64))// || !strcmp(type.dataTypeString, "int64") || !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
55 ((void (*)(void *, int64))(void *)prop.Set)(object, *(int64 *)value);
57 else if(type.typeSize == sizeof(int))// || !strcmp(type.dataTypeString, "int") || !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
59 ((void (*)(void *, int))(void *)prop.Set)(object, *(int *)value);
61 else if(type.typeSize == sizeof(short int)) // || !strcmp(type.dataTypeString, "short") || !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") || !strcmp(type.dataTypeString, "int16"))
63 ((void (*)(void *, short))(void *)prop.Set)(object, *(short *)value);
65 else if(type.typeSize == sizeof(byte))// || !strcmp(type.dataTypeString, "char") || !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
67 ((void (*)(void *, byte))(void *)prop.Set)(object, *(byte *)value);
71 ((void (*)(void *, void *))(void *)prop.Set)(object, value);
76 any_object GetPropValue(Property prop, Instance object)
80 Class type = prop.dataTypeClass;
83 type = prop.dataTypeClass = eSystem_FindClass(prop._class.module, prop.dataTypeString);
86 if(type.type == normalClass || type.type == noHeadClass || type.type == structClass)
88 return ((void*(*)())(void *)prop.Get)(object);
90 // TOFIX: How to swiftly handle classes with base data type?
91 else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
93 // NOTE: must return double by reference
94 double d = ((double(*)(void *))(void *)prop.Get)(object);
97 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
99 // NOTE: must return float by reference
100 float f =((float(*)(void *))(void *)prop.Get)(object);
103 else if(type.typeSize == sizeof(int64))// || !strcmp(type.dataTypeString, "int64") || !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
105 return ((int64(*)(void *))(void *)prop.Get)(object);
107 else if(type.typeSize == sizeof(int))// || !strcmp(type.dataTypeString, "int") || !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
109 return ((int(*)(void *))(void *)prop.Get)(object);
111 else if(type.typeSize == sizeof(short int)) // || !strcmp(type.dataTypeString, "short") || !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") || !strcmp(type.dataTypeString, "int16"))
113 return ((short(*)(void *))(void *)prop.Get)(object);
115 else if(type.typeSize == sizeof(byte))// || !strcmp(type.dataTypeString, "char") || !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
117 return ((byte(*)(void *))(void *)prop.Get)(object);
121 return ((int (*)(void *))(void *)prop.Get)(object);
128 void CopyProperty(Property prop, Instance dest, Instance src)
130 Class type = prop.dataTypeClass;
132 type = prop.dataTypeClass = eSystem_FindClass(prop._class.module, prop.dataTypeString);
134 if(type.type == structClass)
136 void * propData = new0 byte[type.structSize];
137 ((void (*)(void *, void *))(void *)prop.Get)(src, propData);
138 ((void (*)(void *, void *))(void *)prop.Set)(dest, propData);
141 else if(type.type == normalClass || type.type == noHeadClass)
143 // TOCHECK: Why was there a return here?
144 /*return */((void (*)(void *, void *))(void *)prop.Set)(dest, ((void*(*)(void *))(void *)prop.Get)(src));
146 // TOFIX: How to swiftly handle classes with base data type?
147 else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
149 ((void (*)(void *, double))(void *)prop.Set)(dest, ((double(*)(void *))(void *)prop.Get)(src));
151 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
153 ((void (*)(void *, float))(void *)prop.Set)(dest, ((float(*)(void *))(void *)prop.Get)(src));
155 else if(type.typeSize == sizeof(int64))// || !strcmp(type.dataTypeString, "int64") || !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
157 ((void (*)(void *, int64))(void *)prop.Set)(dest, ((int64(*)(void *))(void *)prop.Get)(src));
159 else if(type.typeSize == sizeof(int))// || !strcmp(type.dataTypeString, "int") || !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
161 ((void (*)(void *, int))(void *)prop.Set)(dest, ((int(*)(void *))(void *)prop.Get)(src));
163 else if(type.typeSize == sizeof(short int)) // || !strcmp(type.dataTypeString, "short") || !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") || !strcmp(type.dataTypeString, "int16"))
165 ((void (*)(void *, short))(void *)prop.Set)(dest, ((short(*)(void *))(void *)prop.Get)(src));
167 else if(type.typeSize == sizeof(byte))// || !strcmp(type.dataTypeString, "char") || !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
169 ((void (*)(void *, byte))(void *)prop.Set)(dest, ((byte(*)(void *))(void *)prop.Get)(src));
173 ((void (*)(void *, int))(void *)prop.Set)(dest, ((int (*)(void *))(void *)prop.Get)(src));
177 void GetProperty(Property prop, Instance object, DataValue value)
181 Class type = prop.dataTypeClass;
184 type = prop.dataTypeClass = eSystem_FindClass(prop._class.module, prop.dataTypeString);
186 if(prop._class.module.application == __thisModule &&
187 prop.dataTypeClass.module.application == ((Designer)GetActiveDesigner()).codeEditor.privateModule)
192 if(type.type == normalClass || type.type == noHeadClass || type.type == structClass)
194 value.p = ((void*(*)(void *))(void *)prop.Get)(object);
196 // TOFIX: How to swiftly handle classes with base data type?
197 else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
199 value.d = ((double(*)(void *))(void *)prop.Get)(object);
201 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
203 value.f = ((float(*)(void *))(void *)prop.Get)(object);
205 else if(type.typeSize == sizeof(int64))// || !strcmp(type.dataTypeString, "int64") || !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
207 value.i64 = ((int64(*)(void *))(void *)prop.Get)(object);
209 else if(type.typeSize == sizeof(int))// || !strcmp(type.dataTypeString, "int") || !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
211 value.i = ((int(*)(void *))(void *)prop.Get)(object);
213 else if(type.typeSize == sizeof(short int)) // || !strcmp(type.dataTypeString, "short") || !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") || !strcmp(type.dataTypeString, "int16"))
215 value.s = ((short(*)(void *))(void *)prop.Get)(object);
217 else if(type.typeSize == sizeof(byte))// || !strcmp(type.dataTypeString, "char") || !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
219 value.uc = ((byte(*)(void *))(void *)prop.Get)(object);
223 value.i = ((int (*)(void *))(void *)prop.Get)(object);
230 void SetProperty(Property prop, Instance object, DataValue value)
234 Class type = prop.dataTypeClass;
236 type = prop.dataTypeClass = eSystem_FindClass(prop._class.module, prop.dataTypeString);
238 if(type.type == normalClass || type.type == noHeadClass || type.type == structClass)
240 ((void (*)(void *, void *))(void *)prop.Set)(object, value);
242 // TOFIX: How to swiftly handle classes with base data type?
243 else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
245 ((void (*)(void *, double))(void *)prop.Set)(object, value.d);
247 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
249 ((void (*)(void *, float))(void *)prop.Set)(object, value.f);
251 else if(type.typeSize == sizeof(int64))// || !strcmp(type.dataTypeString, "int64") || !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
253 ((void (*)(void *, int64))(void *)prop.Set)(object, value.i64);
255 else if(type.typeSize == sizeof(int))// || !strcmp(type.dataTypeString, "int") || !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
257 ((void (*)(void *, int))(void *)prop.Set)(object, value.i);
259 else if(type.typeSize == sizeof(short int)) // || !strcmp(type.dataTypeString, "short") || !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") || !strcmp(type.dataTypeString, "int16"))
261 ((void (*)(void *, short))(void *)prop.Set)(object, value.s);
263 else if(type.typeSize == sizeof(byte))// || !strcmp(type.dataTypeString, "char") || !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
265 ((void (*)(void *, byte))(void *)prop.Set)(object, value.uc);
269 ((void (*)(void *, int))(void *)prop.Set)(object, value.i);
277 borderStyle = sizable;
281 anchor = { left = 0, top = 0, bottom = 0 };
282 background = formColor;
286 dropBox.AddField(dropField);
287 properties.AddField(propertyName);
288 properties.AddField(propertyValue);
289 methods.AddField(methodName);
294 categories.Free(null);
300 anchor = { left = 0, top = 0, right = 0 };
302 bool NotifySelect(DropBox control, DataRow row, Modifiers keyFlags)
304 ObjectInfo selected = (ObjectInfo)(row ? (void *)(intptr)row.tag : null);
305 ToolBox toolBox = ((IDEWorkSpace)parent).toolBox;
307 if(codeEditor && selected)
308 codeEditor.SelectObject(selected);
310 // TODO: Get containing class of object
311 toolBox.selectedClass = selected ? selected.oClass : null;
313 object = selected ? selected.instance : null;
316 ListProperties(true);
320 row = methods.currentRow;
322 strcpy(selectedMethod, ((CodeObject)row.GetData(methodName)).name);
326 if(selected && selected.instance && codeEditor)
329 int rowHeight = methods.rowHeight;
331 propertyValue.userData = (void *)selected.instance;
333 // Fill up the methods
337 for(_class = selected.instance._class; _class && _class.type != systemClass; _class = _class.base)
340 for(id = _class.base ? _class.base.vTblSize : 0; id<_class.vTblSize; id++)
343 for(method = (Method)_class.methods.first; method; method = (Method)((BTNode)method).next)
345 if(method.type == virtualMethod && method.vid == id)
348 method.dataType = ProcessTypeString(method.dataTypeString, false);
350 type = method.dataType.thisClass ? typeEvent : typeMethod;
352 DataRow row = methods.AddRow();
353 CodeObject codeObject
355 eventsUp = (selected.oClass == selected) ? false : true;
359 overriden = codeEditor.FindMethod(method.name, &codeObject.function, null);
361 if(!codeObject.overriden || codeObject.overriden == 2)
362 codeEditor.FindCompatibleMethods(method, codeObject.compatible);
364 row.SetData(methodName, codeObject);
366 if(!strcmp(method.name, selectedMethod))
367 methods.currentRow = row;
375 methods.Sort(methodName, 1);
378 for(row = methods.firstRow; row; row = row.next)
380 CodeObject codeObject = row.GetData(methodName);
381 CreateButtons(codeObject, row.index * rowHeight, rowHeight, row);
388 DataField dropField { dataType = class(CodeObject) };
392 this, inactive = true, text = $"Properties", bevelOver = true, isRadio = true;
394 anchor = { left = 0, bottom = 3, right = 0.5 };
397 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
399 text = $"Properties";
400 button.font = { $"Tahoma", 8.25f, bold = true };
403 methods.visible = false;
404 methBtn.Activate(); // Ensure proper cycling (until tab order?)
405 properties.visible = true;
407 alphabetical.disabled = false;
408 categorized.disabled = false;
410 properties.Activate();
412 // ((IDEWorkSpace)master).SheetSelected(Properties);
419 this, inactive = true, bevelOver = true;
424 anchor = { bottom = 3, left = 0.5, right = 0 };
426 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
429 button.font = { $"Tahoma", 8.25f, bold = true };
432 properties.visible = false;
433 methBtn.Activate(); // Ensure proper cycling (until tab order?)
434 methods.visible = true;
436 alphabetical.disabled = true;
437 categorized.disabled = true;
441 // ((IDEWorkSpace)master).SheetSelected(Methods);
448 MenuPlacement editMenu { menu, text = $"Edit" };
449 Menu viewMenu { menu, text = $"View" };
454 this, anchor = { left = 0, right = 0, top = 50, bottom = 25 };
455 hasVertScroll = true, alwaysEdit = true, collapseControl = true, resizable = true;
457 background = colorScheme.viewsBackground;
458 foreground = colorScheme.viewsText;
459 selectionText = colorScheme.sheetSelectionText;
460 selectionColor = colorScheme.sheetSelectionColor;
463 bool NotifySelect(ListBox control, DataRow row, Modifiers keyFlags)
468 strcpy(selectedProp, (char *)row.GetData(propertyName));
469 selectedScroll = properties.scroll.y;
470 selectedScroll -= row.index * properties.rowHeight;
476 prop = ((PropertyInfo)row.GetData(propertyValue)).prop;
485 DataField propertyName { dataType = class(char *), width = 130 };
486 DataField propertyValue { dataType = class(PropertyInfo), width = 0, editable = true };
491 this, anchor = { left = 0, right = 0, top = 50, bottom = 25 };
492 hasVertScroll = true;
494 background = colorScheme.viewsBackground;
495 foreground = colorScheme.viewsText;
497 // alwaysEdit = true;
500 bool NotifyDoubleClick(ListBox control, int x, int y, Modifiers mods)
502 CodeObject object = control.GetData(methodName);
504 codeEditor.AddMethod(object.method);
508 bool NotifyRightClick(ListBox control, int x, int y, Modifiers mods)
510 CodeObject object = control.GetData(methodName);
513 if(object.overriden == 0)
515 MenuItem { menu, $"Override", o, enter, bold = true, NotifySelect = OverrideMethodSelected };
516 if(object.compatible.count)
518 Menu attachMenu { menu, $"Attach", a };
520 for(compatible = object.compatible.first; compatible; compatible = compatible.next)
522 ClassFunction function = compatible.data;
523 MenuItem { attachMenu, function.declarator.symbol.string, id = (int64)(intptr)function, NotifySelect = AttachMethodSelected };
527 else if(object.overriden == 1)
529 MenuItem { menu, $"Go to", g, enter, bold = true, NotifySelect = GotoMethodSelected };
530 MenuItem { menu, $"Detach", d, d, NotifySelect = DetachMethodSelected };
531 MenuItem { menu, $"Delete", del, del, NotifySelect = DeleteMethodSelected };
533 else if(object.overriden == 2)
535 MenuItem { menu, $"Go to", g, enter, bold = true, NotifySelect = GotoMethodSelected };
536 MenuItem { menu, $"Detach", d, d, NotifySelect = DetachMethodSelected };
537 if(object.compatible.count > 1)
539 Menu attachMenu { menu, $"Reattach", r };
541 for(compatible = object.compatible.first; compatible; compatible = compatible.next)
543 ClassFunction function = compatible.data;
544 if(function != object.function)
546 MenuItem { attachMenu, function.declarator.symbol.string, id = (int64)(intptr)function, NotifySelect = ReattachMethodSelected };
552 attachMethod = object.method;
553 popupMenu = PopupMenu { menu = menu, master = this, position =
555 x + control.absPosition.x - app.desktop.absPosition.x,
556 y + control.absPosition.y - app.desktop.absPosition.y
559 // popupMenu.Capture();
563 bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
567 CodeObject object = row.GetData(methodName);
568 switch((SmartKey)key)
571 if(!object.overriden)
572 listBox.NotifyDoubleClick(this, listBox, 0,0, 0);
574 codeEditor.GoToMethod(object.method.name);
578 object.deleteBtn.NotifyClicked(this, object.deleteBtn, 0,0,0);
579 else if(object.detachBtn)
580 object.detachBtn.NotifyClicked(this, object.detachBtn, 0,0,0);
584 object.attachBtn.NotifyPushed(this, object.attachBtn, 0,0,0);
588 object.detachBtn.NotifyClicked(this, object.detachBtn, 0,0,0);
596 DataField methodName { dataType = class(CodeObject) };
599 methBtn.font = { $"Tahoma", 8.25, bold = true };
600 methBtn.checked = true;
601 properties.visible = false;
604 propBtn.font = { $"Tahoma", 8.25f, bold = true };
605 propBtn.checked = true;
606 methods.visible = false;
607 text = $"Properties";
612 this, bevelOver = true, inactive = true, position = { 25, 25 }, size = { 24, 24 };
613 bitmap = { "<:ecere>elements/orderAscending.png" };
616 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
618 if(!alphabetical.checked)
620 alphabetical.checked = true;
621 categorized.checked = false;
623 ListProperties(true);
631 this, bevelOver = true, checked = true, inactive = true, position = { 0, 25 }, size = { 24, 24 };
632 bitmap = { "<:ecere>elements/orderCategorized.png" };
635 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
637 if(!categorized.checked)
639 categorized.checked = true;
640 alphabetical.checked = false;
642 ListProperties(true);
648 property CodeEditor codeEditor
652 if(codeEditor != value)
657 dropField.userData = codeEditor;
658 methodName.userData = codeEditor;
661 codeEditor.EnumerateObjects(this);
670 property SheetType sheetSelected
674 if(methBtn.checked != (value == SheetType::methods))
679 return methBtn.checked ? methods : properties;
683 bool OnClose(bool parentClosing)
693 bool OnKeyDown(Key key, unichar ch)
699 else if(key == escape)
701 Window activeClient = ide.activeClient;
703 activeClient.Activate();
705 ide.RepositionWindows(true);
710 bool OnKeyHit(Key key, unichar ch)
712 return properties.OnKeyHit(key, ch);
715 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
717 if(active && codeEditor)
718 codeEditor.EnsureUpToDate();
722 void ListProperties(bool clear)
724 DataRow row = dropBox.currentRow;
725 ObjectInfo selected = row ? (ObjectInfo)(intptr)row.tag : null;
728 bool categorized = this.categorized.checked;
729 bool currentRow = false;
730 char selectedProp[1024];
735 DataRow row = properties.currentRow;
738 DataRow propRow = row;
740 while(propRow && propRow.parent && !propRow.parent.isHeader)
741 propRow = row.parent;
743 propName = propRow.GetData(propertyName);
744 strcpy(this.selectedProp, propName);
745 selectedScroll = properties.scroll.y;
746 selectedScroll -= propRow.index * properties.rowHeight;
748 currentRow = this.selectedProp[0] ? true : false;
750 for(cat = categories.first; cat; cat = cat.next)
752 cat.collapsed = cat.row.collapsed;
756 // Preserve selected property (PropertySheetSelect will null it)
757 strcpy(selectedProp, this.selectedProp);
759 strcpy(this.selectedProp, selectedProp);
761 if(selected && selected.instance && codeEditor)
763 Instance test = eInstance_New(selected.instance._class);
767 // Put it in the same desktop window...
768 if(selected.classDefinition)
769 codeEditor.designer.PrepareTestObject(test);
771 // Fill up the properties
772 while(_class != selected.instance._class)
774 Class lastClass = _class;
777 for(_class = selected.instance._class; _class.base != lastClass && _class.base.type != systemClass && _class.inheritanceAccess != privateAccess; _class = _class.base);
779 for(propIt = _class.membersAndProperties.first; propIt; propIt = propIt.next)
781 if(propIt.isProperty)
783 Property prop = eClass_FindProperty(selected.instance._class, propIt.name, GetPrivateModule());
785 if(prop && prop.Set && prop.Get && prop.compiled && (!prop.category || strcmpi(prop.category, $"Deprecated")))
787 bool disabled = Code_IsPropertyDisabled(selected, prop.name);
789 Class dataType = prop.dataTypeClass;
791 dataType = prop.dataTypeClass = eSystem_FindClass(codeEditor.privateModule, prop.dataTypeString);
793 if(!strcmp(_class.name, "DesignerBase"))
795 bold = !disabled && Code_IsPropertyModified(test, selected, prop);
800 PropertyInfo info { prop, disabled, bold ? codeEditor.boldFont : codeEditor.normalFont };
801 const char * name = prop.category ? prop.category : $"Misc";
802 Category category = categories.FindName(name, false);
804 // Hide properties like this for now..
805 if(name && !strcmp(name, "Private"))
813 category = Category { name = name };
814 categories.AddName(category);
816 if(!category.row && categorized)
818 PropertyInfo catInfo { null, false, null, name };
819 category.row = properties.AddRow();
820 category.row.SetData(propertyName, name );
821 category.row.SetData(propertyValue, catInfo);
822 category.row.isHeader = true;
823 category.row.collapsed = category.collapsed;
828 row = categorized ? category.row.FindRow((int64)(intptr)prop) : properties.FindRow((int64)(intptr)prop);
830 row = categorized ? category.row.AddRow() : properties.AddRow();
831 row.tag = (int64)(intptr)prop;
834 row = categorized ? category.row.FindRow((int64)(intptr)prop) : properties.FindRow((int64)(intptr)prop);
836 row.SetData(propertyName, prop.name);
837 row.SetData(propertyValue, info);
839 if(clear && !strcmp(prop.name, this.selectedProp))
840 properties.currentRow = row;
842 if(!dataType.noExpansion && (dataType.type == structClass || dataType.type == normalClass || dataType.type == noHeadClass || dataType.type == bitClass))
847 row.collapsed = true;
849 for(member = dataType.membersAndProperties.first; member; member = member.next)
851 if(member.isProperty)
853 Property subProp = (Property)member;
854 if(!subProp.conversion && subProp.Get && subProp.Set)
857 PropertyInfo info { prop, disabled, bold ? codeEditor.boldFont : codeEditor.normalFont, null, null, subProp };
861 subRow = row.AddRow();
862 subRow.tag = (int64)(intptr)subProp;
865 subRow = row.FindRow((int64)(intptr)subProp);
867 subRow.SetData(propertyName, subProp.name);
868 subRow.SetData(propertyValue, info);
874 PropertyInfo info { prop, disabled, bold ? codeEditor.boldFont : codeEditor.normalFont, null, member, null };
877 subRow = row.AddRow();
878 subRow.tag = (int64)(intptr)member;
881 subRow = row.FindRow((int64)(intptr)member);
883 subRow.SetData(propertyName, member.name);
884 subRow.SetData(propertyValue, info);
888 DataMember subMember;
889 for(subMember = member.members.first; subMember; subMember = subMember.next)
892 PropertyInfo info { prop, disabled, bold ? codeEditor.boldFont : codeEditor.normalFont, null, subMember, null, member.offset };
895 subRow = row.AddRow();
896 subRow.tag = (int64)(intptr)subMember;
899 subRow = row.FindRow((int64)(intptr)subMember);
901 subRow.SetData(propertyName, subMember.name);
902 subRow.SetData(propertyValue, info);
913 // Sort alphabetically for now...
916 // properties.Sort(null, 1);
917 properties.Sort(propertyValue, 1);
918 if(!properties.currentRow)
922 for(_class = selected.instance._class; _class; _class = _class.base)
925 for(prop = _class.membersAndProperties.first; prop; prop = prop.next)
927 if(prop.isProperty && prop.Set && prop.Get && prop.compiled)
929 if(_class.defaultProperty && !strcmp(prop.name, _class.defaultProperty))
932 const char * name = prop.category ? prop.category : $"Misc";
933 Category category = categories.FindName(name, false);
934 row = category ? (categorized ? category.row.FindRow((int64)(intptr)prop) : properties.FindRow((int64)(intptr)prop)) : null;
935 properties.currentRow = row;
944 properties.currentRow = properties.firstRow;
949 DataRow row = properties.currentRow;
950 properties.scroll.y = selectedScroll + row.index * properties.rowHeight;
956 void AddObject(ObjectInfo object, const char * name, CodeObjectType type, bool select)
958 DataRow after = null;
960 CodeObject codeObject;
961 char * bitmap = null;
962 bool foundClass = false;
964 for(row = dropBox.firstRow; row; row = row.next)
966 CodeObject codeObject = row.GetData(null);
967 if(codeObject.object.oClass == object.oClass)
974 row = (DataRow)dropBox.AddRowAfter(after);
976 row.tag = (int64)(intptr)object;
983 indent = (type == typeClass) ? 0 : 1;
986 if(type != typeClass)
987 bitmap = (char *)(intptr)eClass_GetProperty(object.instance._class, "icon");
990 codeObject.bitmap = { bitmap };
991 AddResource(codeObject.bitmap);
994 row.SetData(null, codeObject);
998 this.object = object ? object.instance : null;
999 propertyValue.userData = object ? (void *)object.instance : null;
1000 dropBox.SelectRow(row);
1004 void DeleteObject(ObjectInfo object)
1006 DataRow row = dropBox.FindRow((int64)(intptr)object);
1009 CodeObject codeObject = row.GetData(null);
1011 if(codeObject.bitmap)
1012 RemoveResource(codeObject.bitmap);
1013 dropBox.DeleteRow(row);
1017 void SelectObject(ObjectInfo object)
1021 DataRow row = dropBox.FindRow((int64)(intptr)object);
1022 this.object = object ? object.instance : null;
1023 propertyValue.userData = object ? (void *)object.instance : null;
1024 dropBox.SelectRow(row);
1028 void RenameObject(ObjectInfo object, const char * name)
1030 DataRow row = dropBox.FindRow((int64)(intptr)object);
1031 CodeObject codeObject = row.GetData(null);
1032 // Isn't this useless? Shouldn't it be after?
1033 codeObject.name = name;
1034 // row.SetData(null, codeObject); // Is this necessary?
1037 void DataBox::EditSetData(any_object setValue, bool closingDropDown)
1039 ((Sheet)master.master).SetData(setValue, this);
1042 void SetData(any_object setValue, DataBox dataBox)
1044 //PropertyInfo propertyPtr = row.GetData(null);
1045 PropertyInfo propertyPtr = properties.GetData(null);
1046 Property prop = propertyPtr ? propertyPtr.prop : null;
1047 Instance object = this.object;
1050 Class dataType = prop.dataTypeClass;
1052 dataType = prop.dataTypeClass = eSystem_FindClass(codeEditor.privateModule, prop.dataTypeString);
1053 if(propertyPtr.subMember)
1055 DataMember member = propertyPtr.subMember;
1056 Class subDataType = member.dataTypeClass;
1057 if(!member.dataTypeClass)
1058 subDataType = member.dataTypeClass = eSystem_FindClass(codeEditor.privateModule, member.dataTypeString);
1062 if(!subDataType.dataType)
1063 subDataType.dataType = ProcessTypeString(subDataType.dataTypeString, false);
1065 if(dataType.type == structClass)
1067 data = new0 byte[dataType.structSize];
1068 ((void (*)(void *, void *))(void *)prop.Get)(object, data);
1069 // CopyBytes((byte *)data + member.offset + propertyPtr.extraOffset, &setValue, subDataType.size);
1070 CopyBytes((byte *)data + member.offset + propertyPtr.extraOffset, (void *)setValue, subDataType.dataType.size);
1071 ((void (*)(void *, void *))(void *)prop.Set)(object, data);
1073 else if(dataType.type == normalClass || dataType.type == noHeadClass)
1078 if(dataType.type == bitClass)
1080 BitMember bitMember = (BitMember) member;
1083 DataValue value { 0 };
1084 value.ui = ((uint (*)(void *))(void *)prop.Get)(object);
1085 value.ui &= ~ (uint)bitMember.mask;
1086 value.ui |= *(uint32 *)setValue << bitMember.pos;
1087 ((void (*)(void *, uint))(void *)prop.Set)(object, value.ui);
1092 // TODO: What does this handle?
1093 data = dataType.typeSize ? new0 byte[dataType.typeSize] : null;
1094 ((void (*)(void *, void *))(void *)prop.Get)(object, data);
1095 // CopyBytes((byte *)data + member.offset + propertyPtr.extraOffset, &setValue, subDataType.typeSize);
1096 CopyBytes((byte *)data + member.offset + propertyPtr.extraOffset, (void *)setValue, subDataType.dataType.size);
1097 // TODO: Support non 32 bit datatypes here
1098 ((void (*)(void *, void *))(void *)prop.Set)(object, data);
1102 if(data) ((void (*)(void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnFree])(dataType,&data);
1106 else if(propertyPtr.subProperty)
1108 Property subProperty = propertyPtr.subProperty;
1109 Class subDataType = subProperty.dataTypeClass;
1111 subDataType = subProperty.dataTypeClass = eSystem_FindClass(codeEditor.privateModule, subProperty.dataTypeString);
1116 if(dataType.type == structClass)
1118 data = new0 byte[dataType.structSize];
1119 ((void (*)(void *, void *))(void *)prop.Get)(object, data);
1120 ((void (*)(void *, uint))(void *)subProperty.Set)(data, *(uint32 *)setValue);
1121 ((void (*)(void *, void *))(void *)prop.Set)(object, data);
1123 else if(dataType.type == normalClass || dataType.type == noHeadClass)
1125 Instance current = (Instance)((void *(*)(void *))(void *)prop.Get)(object);
1126 Instance propObject = eInstance_New(dataType);
1127 CopyInstanceData(dataType, propObject, current);
1128 ((void (*)(void *, uint))(void *)subProperty.Set)(propObject, (uint32)setValue);
1129 ((void (*)(void *, void *))(void *)prop.Set)(object, propObject);
1133 data = dataType.typeSize ? new0 byte[dataType.typeSize] : null;
1134 ((void (*)(void *, void *))(void *)prop.Get)(object, data);
1135 ((void (*)(void *, uint))(void *)subProperty.Set)(data, (uint32)setValue);
1136 // TODO: Support not 32 bit data types here
1137 ((void (*)(void *, void *))(void *)prop.Set)(object, data);
1140 if(data) ((void (*)(void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnFree])(dataType,&data);
1146 SetPropValue(prop, object, (uint32)setValue);
1148 Code_FixProperty(propertyPtr.prop, object);
1150 properties.Update(null);
1151 dropBox.Update(null);
1152 codeEditor.designer.Update(null);
1153 codeEditor.Update(null); // patch for redraw bug if on top
1155 ListProperties(false);
1156 // DataRow values were changed by ListProperties, need to re-query
1157 propertyPtr = properties.GetData(null);
1159 dataBox.editor.font = { propertyPtr.font.faceName, propertyPtr.font.size, propertyPtr.font.bold };
1161 codeEditor.ModifyCode();
1165 bool SaveEdit(PropertyInfo propertyPtr, Instance object)
1167 codeEditor.designer.Update(null);
1168 codeEditor.Update(null); // patch for redraw bug if on top
1169 properties.Update(null);
1170 dropBox.Update(null);
1172 Code_FixProperty(propertyPtr.prop, object);
1173 ListProperties(false);
1175 codeEditor.ModifyCode();
1181 if(!propBtn.checked)
1183 propBtn.checked = true;
1184 propBtn.NotifyClicked(this, propBtn, 0,0,0);
1188 methBtn.checked = true;
1189 methBtn.NotifyClicked(this, methBtn, 0,0,0);
1193 bool AttachMethodSelected(MenuItem selection, Modifiers mods)
1195 ClassFunction function = (ClassFunction)(intptr)selection.id;
1196 codeEditor.AttachMethod(attachMethod, function);
1200 bool ReattachMethodSelected(MenuItem selection, Modifiers mods)
1202 ClassFunction function = (ClassFunction)(intptr)selection.id;
1203 codeEditor.ReAttachMethod(attachMethod, function);
1207 bool OverrideMethodSelected(MenuItem selection, Modifiers mods)
1209 CodeObject object = methods.GetData(methodName);
1211 codeEditor.AddMethod(object.method);
1215 bool GotoMethodSelected(MenuItem selection, Modifiers mods)
1217 CodeObject object = methods.GetData(methodName);
1219 codeEditor.GoToMethod(object.method.name);
1223 bool DetachMethodSelected(MenuItem selection, Modifiers mods)
1225 CodeObject object = methods.GetData(methodName);
1227 codeEditor.DetachMethod(object.method, object.function, object.overriden);
1231 bool DeleteMethodSelected(MenuItem selection, Modifiers mods)
1233 CodeObject object = methods.GetData(methodName);
1235 object.deleteBtn.NotifyClicked(this, object.deleteBtn, 0,0,0);
1239 bool AddMethodClicked(Button button, int x, int y, Modifiers mods)
1241 DataRow row = (DataRow)(intptr)button.id;
1242 CodeObject object = row.GetData(methodName);
1243 codeEditor.AddMethod(object.method);
1247 void CreateButtons(CodeObject codeObject, int y, int h, DataRow row)
1249 if(codeObject.overriden)
1251 if(codeObject.overriden == 1)
1253 codeObject.deleteBtn = Button
1255 methods, master = this,
1257 bitmap = { ":actions/delete.png", alphaBlend = true },
1258 anchor = { right = 16, top = y },
1260 id = (int64)(intptr)row;
1262 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1264 CodeObject codeObject = ((DataRow)(intptr)button.id).GetData(null);
1265 bool confirmation = !Code_IsFunctionEmpty(codeObject.function, codeObject.method, codeEditor.selected);
1270 sprintf(title, $"Delete %s", codeObject.name);
1273 master = parent, type = okCancel, text = title,
1274 contents = $"Method still contains code. Are you sure you want to delete it?"
1276 confirmation = false;
1279 if(!confirmation && codeObject.function.attached.count)
1282 sprintf(title, $"Delete %s", codeObject.name);
1283 confirmation = true;
1286 master = parent, type = okCancel, text = title,
1287 contents = $"Other methods are still attached to this method. Are you sure you want to delete it?"
1289 confirmation = false;
1294 codeEditor.DeleteMethod(codeObject.function);
1299 incref codeObject.deleteBtn;
1300 codeObject.deleteBtn.Create();
1303 if(codeObject.overriden == 2 || !codeObject.function.attached.count)
1305 codeObject.detachBtn = Button
1308 master = methods.master,
1310 bitmap = { ":actions/detach.png" },
1311 anchor = { right = 0, top = y },
1313 id = (int64)(intptr)row;
1315 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1317 DataRow row = (DataRow)(intptr)button.id;
1318 CodeObject object = row.GetData(methodName);
1320 codeEditor.DetachMethod(object.method, object.function, object.overriden);
1324 incref codeObject.detachBtn;
1325 codeObject.detachBtn.Create();
1330 if(codeObject.compatible.count)
1332 codeObject.attachBtn = Button
1334 parent = methods, master = methods.master,
1336 bitmap = { ":actions/attach.png" },
1337 anchor = { right = 0, top = y },
1339 id = (int64)(intptr)row;
1341 bool NotifyPushed(Button button, int x, int y, Modifiers mods)
1344 DataRow row = (DataRow)(intptr)button.id;
1345 CodeObject object = row.GetData(methodName);
1347 PopupMenu popupMenu;
1351 for(compatible = object.compatible.first; compatible; compatible = compatible.next)
1353 ClassFunction function = compatible.data;
1354 MenuItem { menu, function.declarator.symbol.string, id = (int64)(intptr)function, NotifySelect = AttachMethodSelected };
1356 attachMethod = object.method;
1358 popupMenu = PopupMenu
1360 master = this, menu = menu,
1363 button.absPosition.x - app.desktop.position.x,
1364 button.absPosition.y - app.desktop.position.y + button.size.h
1368 button.ReleaseCapture();
1369 popupMenu.Capture();
1373 incref codeObject.attachBtn;
1374 codeObject.attachBtn.Create();
1379 Method attachMethod;
1380 char selectedMethod[1024];
1381 CodeEditor codeEditor;
1383 char selectedProp[1024];
1387 static int String_OnCompare(const char ** string1, const char ** string2)
1390 if(*string1 && *string2)
1391 result = strcmpi(*string1, *string2);
1392 else if(!*string1 && *string2)
1394 else if(*string1 && !*string2)
1399 static void CopyInstanceData(Class dataType, Instance propObject, Instance current)
1402 for(_class = dataType; _class && _class.type != systemClass; _class = _class.base)
1405 for(member = _class.membersAndProperties.first; member; member = member.next)
1407 Class memberType = member.dataTypeClass;
1409 memberType = member.dataTypeClass = eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, member.dataTypeString);
1410 if(member.isProperty)
1412 Property subProp = (Property) member;
1413 if(subProp.Get && subProp.Set)
1414 CopyProperty(subProp, propObject, current);
1416 else if(member.id > -1)
1419 // TOCHECK: I have serious doubts this works in many cases.
1420 ((void (*)(void *, void *, void *))(void *)memberType._vTbl[__ecereVMethodID_class_OnCopy])(memberType, (byte *)propObject + member.offset, (byte *)current + member.offset);
1422 memcpy((byte *)propObject + member.offset, (byte *)current + member.offset, member.memberOffset);
1428 class PropertyInfo : struct
1434 const char * categoryName;
1435 DataMember subMember;
1436 Property subProperty;
1439 void OnDisplay(Surface surface, int x, int y, int width, Instance object, Alignment alignment, DataDisplayFlags displayFlags)
1441 Property prop = this.prop;
1443 surface.TextFont(font.font);
1446 surface.SetBackground(Color { 170, 170, 170 });
1447 surface.Area(0,0, x+width-1, y+100);
1449 else if(prop && prop.dataTypeString)
1451 Class dataType = prop.dataTypeClass;
1452 Module module = ((Designer)GetActiveDesigner()).codeEditor.privateModule;
1454 dataType = prop.dataTypeClass = eSystem_FindClass(module, prop.dataTypeString);
1456 if(dataType && prop.Get)
1458 void * dataPtr, * data = null, * subData = null;
1459 DataValue valueData, valueSubData;
1463 if(dataType.type == structClass)
1465 data = new0 byte[dataType.structSize];
1466 ((void (*)(void *, void *))(void *)prop.Get)(object, data);
1471 GetProperty(prop, object, &valueData);
1473 if(dataType.type == normalClass)
1474 dataPtr = valueData.p;
1476 dataPtr = &valueData;
1482 DataMember member = this.subMember;
1483 Class subDataType = member.dataTypeClass;
1485 subDataType = member.dataTypeClass = eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, member.dataTypeString);
1488 if(dataType.type == bitClass)
1490 BitMember bitMember = (BitMember)member;
1491 bitValue = (valueData.ui64 & bitMember.mask) >> bitMember.pos;
1492 // TOCHECK: endian safe?
1493 dataPtr = &bitValue;
1496 dataPtr = (byte *)dataPtr + member.offset + this.extraOffset;
1498 dataType = subDataType;
1500 else if(this.subProperty)
1502 Property subProperty = this.subProperty;
1503 Class subDataType = subProperty.dataTypeClass;
1505 subDataType = subProperty.dataTypeClass = eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, subProperty.dataTypeString);
1506 if(!subProperty.Get) subDataType = null;
1509 if(subDataType.type == structClass)
1511 subData = new0 byte[subDataType.structSize];
1512 ((void (*)(void *, void *))(void *)subProperty.Get)(dataPtr, subData);
1517 GetProperty(subProperty, dataPtr, &valueSubData);
1518 if(subDataType.type == normalClass)
1519 dataPtr = valueSubData.p;
1521 dataPtr = &valueSubData;
1524 dataType = subDataType;
1528 ((void (*)(void *, void *, void *, int, int, int, void *, uint, uint))(void *)dataType._vTbl[__ecereVMethodID_class_OnDisplay])(dataType, dataPtr, surface, x, y, width, null, alignment, displayFlags);
1536 Window OnEdit(DataBox dataBox, Window obsolete, int x, int y, int w, int h, void * unused)
1538 Window editData = null;
1539 Property prop = this.prop;
1541 dataBox.SetData = Sheet::EditSetData;
1542 if(prop && prop.dataTypeString && !this.disabled)
1544 Sheet propertyWindow = (Sheet)dataBox.master.master;
1545 Instance object = propertyWindow.object;
1546 Class dataType = prop.dataTypeClass;
1548 dataType = prop.dataTypeClass = eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, prop.dataTypeString);
1550 if(dataType && prop.Get)
1552 void * dataPtr, * data = null, * subData = null;
1553 DataValue valueData, valueSubData;
1555 bool isEditBoxMultiLineContents = false;
1558 if(dataType.type == structClass)
1560 data = new0 byte[dataType.structSize];
1561 ((void (*)(void *, void *))(void *)prop.Get)(object, data);
1566 //bool freeDataForm = false, freeDataTest = false;
1567 // Because contents property is broken for mutiline EditBox at the moment
1568 if(!strcmp(prop.name, "contents") && !strcmp(prop._class.name, "EditBox") && ((EditBox)object).multiLine)
1570 isEditBoxMultiLineContents = true;
1571 dataType = eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, "MultiLineString");
1572 valueData.p = ((EditBox)object).multiLineContents;
1573 dataBox.size.h = 3*(h-2);
1574 h = dataBox.clientSize.h;
1577 GetProperty(prop, object, &valueData);
1579 if(dataType.type == normalClass)
1580 dataPtr = valueData.p;
1582 dataPtr = &valueData;
1588 DataMember member = this.subMember;
1589 Class subDataType = member.dataTypeClass;
1591 subDataType = member.dataTypeClass = eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, member.dataTypeString);
1594 if(dataType.type == bitClass)
1596 BitMember bitMember = (BitMember)member;
1597 bitValue = (valueData.ui64 & bitMember.mask) >> bitMember.pos;
1598 // TOCHECK: endian safe?
1599 dataPtr = &bitValue;
1602 dataPtr = (byte *)dataPtr + member.offset + this.extraOffset;
1604 dataType = subDataType;
1606 else if(this.subProperty)
1608 Property subProperty = this.subProperty;
1609 Class subDataType = subProperty.dataTypeClass;
1611 subDataType = subProperty.dataTypeClass = eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, subProperty.dataTypeString);
1612 if(!subProperty.Get) subDataType = null;
1615 if(subDataType.type == structClass)
1617 subData = new0 byte[subDataType.structSize];
1618 ((void (*)(void *, void *))(void *)subProperty.Get)(dataPtr, subData);
1623 GetProperty(subProperty, dataPtr, &valueSubData);
1624 if(subDataType.type == normalClass)
1625 dataPtr = valueSubData.p;
1627 dataPtr = &valueSubData;
1630 dataType = subDataType;
1635 Window (* onEdit)(void *, void *, DataBox, void *, int, int, int, int, void*) = (void *)dataType._vTbl[__ecereVMethodID_class_OnEdit];
1637 editData = onEdit(dataType, dataPtr, dataBox, obsolete, x, y, w, h, object /*unused*/);
1643 if(isEditBoxMultiLineContents)
1646 dataBox.background = Color { 90, 120, 150 };
1647 // dataBox.background = viewsBackground;
1648 editData.font = { font.faceName, font.size, font.bold };
1650 if(eClass_IsDerived(editData._class, class(DropBox)))
1652 DropBox db = (DropBox)editData;
1653 db.selectionColor = colorScheme.sheetSelectionColor;
1654 db.selectionText = colorScheme.viewsBackground;
1656 else if(eClass_IsDerived(editData._class, class(EditBox)))
1658 EditBox eb = (EditBox)editData;
1659 eb.selectionColor = colorScheme.sheetSelectionColor;
1660 eb.selectionText = colorScheme.viewsBackground;
1667 int OnCompare(PropertyInfo data2)
1669 const char * category1 = prop ? prop.category : categoryName;
1670 const char * category2 = data2.prop ? data2.prop.category : data2.categoryName;
1673 if(!category1) category1 = $"Misc";
1674 if(!category2) category2 = $"Misc";
1678 result = String_OnCompare(&category1, &category2);
1683 if(subMember && !data2.subMember)
1687 else if(!subMember && data2.subMember)
1691 else if(subMember && data2.subMember)
1693 if(subMember.id < data2.subMember.id)
1695 else if(subMember.id > data2.subMember.id)
1700 else if(subProperty && !data2.subProperty)
1704 else if(!subProperty && data2.subProperty)
1708 else if(subProperty && data2.subProperty)
1710 if(subProperty.id < data2.subProperty.id)
1712 else if(subProperty.id > data2.subProperty.id)
1717 else if(prop && !data2.prop)
1719 else if(!prop && data2.prop)
1722 // result = ((String)prop.name).OnCompare(data2.prop.name);
1723 // result = String::OnCompare((String)prop.name, (String)data2.prop.name);
1724 result = String_OnCompare((const char **)&prop.name, (const char **)&data2.prop.name);
1729 bool OnSaveEdit(Window editControl, void * unusedData)
1731 Property prop = this.prop;
1734 Sheet sheet = (Sheet)editControl.master.master.master;
1735 Instance object = sheet.object;
1736 Class mainDataType = prop.dataTypeClass;
1738 bool result = false;
1739 void * dataPtr, * data = null, * subData = null;
1740 void * propObject = null;
1741 DataValue valueData { 0 };
1742 DataValue valueSubData { 0 };
1746 mainDataType = prop.dataTypeClass = eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, prop.dataTypeString);
1747 dataType = mainDataType;
1749 // Because contents property is broken for mutiline EditBox at the moment
1750 if(!strcmp(prop.name, "contents") && !strcmp(prop._class.name, "EditBox") && ((EditBox)object).multiLine)
1751 dataType = eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, "MultiLineString");
1753 // Prepare main prop
1754 if(dataType.type == structClass)
1756 data = new0 byte[dataType.structSize];
1757 if(this.subMember || this.subProperty)
1758 ((void (*)(void *, void *))(void *)prop.Get)(object, data);
1762 else if(dataType.type == normalClass || dataType.type == noHeadClass)
1764 dataPtr = &valueData;
1766 if(this.subMember || this.subProperty)
1768 Instance current = (Instance)((void *(*)(void *))(void *)prop.Get)(object);
1769 propObject = valueData.p = eInstance_New(dataType);
1770 CopyInstanceData(dataType, propObject, current);
1776 if(this.subMember || this.subProperty)
1777 GetProperty(prop, object, &valueData);
1779 dataPtr = &valueData;
1780 propObject = &valueData;
1786 DataMember member = this.subMember;
1787 Class subDataType = member.dataTypeClass;
1789 subDataType = member.dataTypeClass = eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, member.dataTypeString);
1792 if(dataType.type == bitClass)
1794 BitMember bitMember = (BitMember)member;
1795 bitValue = (valueData.ui64 & bitMember.mask) >> bitMember.pos;
1796 // TOCHECK: endian safe?
1797 dataPtr = &bitValue;
1800 dataPtr = (byte *)dataPtr + member.offset + this.extraOffset;
1802 dataType = subDataType;
1804 else if(this.subProperty)
1806 Property subProperty = this.subProperty;
1807 Class subDataType = subProperty.dataTypeClass;
1810 subDataType = subProperty.dataTypeClass =
1811 eSystem_FindClass(((Designer)GetActiveDesigner()).codeEditor.privateModule, subProperty.dataTypeString);
1812 if(!subProperty.Get) subDataType = null;
1815 if(subDataType.type == structClass)
1817 subData = new0 byte[subDataType.structSize];
1821 dataPtr = &valueSubData;
1823 dataType = subDataType;
1828 bool (* onSaveEdit)(void *, void *, Window, void *) = (void *)dataType._vTbl[__ecereVMethodID_class_OnSaveEdit];
1829 if(!onSaveEdit || onSaveEdit(dataType, dataPtr, editControl, null))
1831 if(mainDataType.type == bitClass && this.subMember)
1833 BitMember bitMember = (BitMember)this.subMember;
1834 valueData.ui64 &= ~bitMember.mask;
1835 valueData.ui64 |= bitValue << bitMember.pos;
1837 if(this.subProperty)
1839 if(dataType.type == structClass)
1840 ((void (*)(void *, void *))(void *)this.subProperty.Set)(propObject, subData);
1841 else if(dataType.type == unitClass || dataType.type == enumClass || dataType.type == bitClass || dataType.type == systemClass)
1843 if(!strcmp(dataType.dataTypeString, "float"))
1844 ((void(*)(void *,float))(void *)this.subProperty.Set)(propObject, valueSubData.f);
1845 else if(!strcmp(dataType.dataTypeString, "double"))
1846 ((void(*)(void *,double))(void *)this.subProperty.Set)(propObject, valueSubData.d);
1847 else if(!strcmp(dataType.dataTypeString, "byte"))
1848 ((void(*)(void *,byte))(void *)this.subProperty.Set)(propObject, valueSubData.uc);
1849 else if(!strcmp(dataType.dataTypeString, "uint16"))
1850 ((void(*)(void *,uint16))(void *)this.subProperty.Set)(propObject, valueSubData.us);
1852 ((void (*)(void *, uint))(void *)this.subProperty.Set)(propObject, valueSubData.ui);
1855 ((void (*)(void *, void *))(void *)this.subProperty.Set)(propObject, valueSubData.p);
1857 if(mainDataType.type == structClass)
1858 ((void (*)(void *, void *))(void *)prop.Set)(object, data);
1859 else if(mainDataType.type == unitClass || mainDataType.type == enumClass || mainDataType.type == bitClass || mainDataType.type == systemClass)
1861 if(!strcmp(mainDataType.dataTypeString, "float"))
1862 ((void(*)(void *,float))(void *)prop.Set)(object, valueData.f);
1863 else if(!strcmp(mainDataType.dataTypeString, "double"))
1864 ((void(*)(void *,double))(void *)prop.Set)(object, valueData.d);
1865 else if(!strcmp(mainDataType.dataTypeString, "byte"))
1866 ((void(*)(void *,byte))(void *)prop.Set)(object, valueData.uc);
1867 else if(!strcmp(mainDataType.dataTypeString, "uint16"))
1868 ((void(*)(void *,uint16))(void *)prop.Set)(object, valueData.us);
1870 ((void (*)(void *, uint))(void *)prop.Set)(object, valueData.ui);
1873 ((void (*)(void *, void *))(void *)prop.Set)(object, valueData.p);
1877 if(data == dataPtr) ((void (*)(void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnFree])(dataType, &data);
1878 if(subData == dataPtr) ((void (*)(void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnFree])(dataType, &subData);
1884 return sheet.SaveEdit(this, object);
1890 class Category : struct
1892 Category prev, next;