ide/designer: (#1112) Fixed toggling Form designer moving caret
[sdk] / ide / src / designer / Designer.ec
1 import "ide"
2
3 class Designer : DesignerBase
4 {
5    ~Designer()
6    {
7       if(GetActiveDesigner() == this)
8       {
9          SetActiveDesigner(null);
10       }
11       if(classDesigner)
12          delete classDesigner;
13    }
14
15    // *** DesignerBase Implementation ***
16
17    void ModifyCode()
18    {
19       codeEditor.ModifyCode();
20    }
21
22    void UpdateProperties()
23    {
24       codeEditor.DesignerModifiedObject();
25    }
26
27    void CodeAddObject(Instance instance, ObjectInfo * object)
28    {
29       codeEditor.AddObject(instance, object);
30    }
31
32    void SheetAddObject(ObjectInfo object)
33    {
34       codeEditor.sheet.AddObject(object, object.name, typeData, true); //className, true);
35    }
36
37    void AddToolBoxClass(Class _class)
38    {
39       ((IDEWorkSpace)master).toolBox.AddControl(_class);
40    }
41
42    void AddDefaultMethod(Instance instance, Instance classInstance)
43    {
44       Class _class = instance._class;
45       Method defaultMethod = null;
46
47       for( ; _class; _class = _class.base)
48       {
49          Method method;
50          int minID = MAXINT;
51          for(method = (Method)_class.methods.first; method; method = (Method)((BTNode)method).next)
52          {
53             if(method.type == virtualMethod)
54             {
55                if(!method.dataType)
56                   method.dataType = ProcessTypeString(method.dataTypeString, false);
57                if(method.vid < minID && (instance == classInstance || (method.dataType.thisClass && eClass_IsDerived(classInstance._class, method.dataType.thisClass.registered))))
58                {
59                   defaultMethod = method;
60                   minID = method.vid;
61                }
62             }
63          }
64          if(defaultMethod)
65             break;
66       }
67       codeEditor.AddMethod(defaultMethod);
68    }
69
70    bool ObjectContainsCode(ObjectInfo object)
71    {
72       // Confirmation if control contains code
73       if(object.instCode)
74       {
75          MembersInit members;
76          if(object.instCode.members)
77          {
78             for(members = object.instCode.members->first; members; members = members.next)
79             {
80                if(members.type == methodMembersInit)
81                {
82                   //if(!Code_IsFunctionEmpty(members.function))
83                   {
84                      return true;
85                   }
86                }
87             }
88          }
89       }
90       return false;
91    }
92
93    void DeleteObject(ObjectInfo object)
94    {
95       if(codeEditor)
96          codeEditor.DeleteObject(object);
97    }
98
99    void RenameObject(ObjectInfo object, const char * name)
100    {
101       if(object && (name || !object.classDefinition))
102          codeEditor.RenameObject(object, name);
103    }
104
105    bool FindObject(Instance * object, const char * string)
106    {
107       ObjectInfo classObject;
108       for(classObject = codeEditor.classes.first; classObject; classObject = classObject.next)
109       {
110          ObjectInfo check;
111          if(classObject.name && !strcmp(string, classObject.name))
112          {
113             *object = classObject.instance;
114             break;
115          }
116          for(check = classObject.instances.first; check; check = check.next)
117          {
118             if(check.name && !strcmp(string, check.name))
119             {
120                *object = check.instance;
121                break;
122             }
123          }
124          if(check)
125             return true;
126       }
127       return false;
128    }
129
130    void SelectObjectFromDesigner(ObjectInfo object)
131    {
132       codeEditor.SelectObjectFromDesigner(object);
133    }
134
135    borderStyle = sizable;
136    isActiveClient = true;
137    hasVertScroll = true;
138    hasHorzScroll = true;
139    hasClose = true;
140    hasMaximize = true;
141    hasMinimize = true;
142    text = $"Designer";
143    menu = Menu { };
144    anchor = Anchor { left = 300, right = 150, top = 0, bottom = 0 };
145
146    ToolBox toolBox;
147    CodeEditor codeEditor;
148
149    Menu fileMenu { menu, $"File", f };
150    MenuItem fileSaveItem
151    {
152       fileMenu, $"Save", s, ctrlS;
153       bool NotifySelect(MenuItem selection, Modifiers mods)
154       {
155          return codeEditor.MenuFileSave(selection, mods);
156       }
157    };
158    MenuItem fileSaveAsItem
159    {
160       fileMenu, $"Save As...", a;
161       bool NotifySelect(MenuItem selection, Modifiers mods)
162       {
163          return codeEditor.MenuFileSaveAs(selection, mods);
164       }
165    };
166    bool debugClosing;
167
168    bool OnClose(bool parentClosing)
169    {
170       if(!parentClosing)
171       {
172          if(codeEditor && codeEditor.inUseDebug && !debugClosing)
173          {
174             debugClosing = true;
175             closing = false;
176             if(CloseConfirmation(false))
177             {
178                visible = false;
179                if(modifiedDocument)
180                   OnFileModified({ modified = true }, null);
181             }
182             debugClosing = false;
183             return false;
184          }
185          if(codeEditor && !codeEditor.closing && !debugClosing)
186          {
187             if(!codeEditor.visible)
188             {
189                if(!codeEditor.Destroy(0))
190                   return false;
191                else
192                   codeEditor = null;
193             }
194             else
195             {
196                visible = false;
197                return false;
198             }
199          }
200       }
201       return true;
202    }
203
204    bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
205    {
206       if(active)
207          codeEditor.EnsureUpToDate();
208       return true;
209    }
210
211    bool OnKeyHit(Key key, unichar ch)
212    {
213       return codeEditor.sheet.OnKeyHit(key, ch);
214    }
215
216    watch(modifiedDocument)
217    {
218       fileSaveItem.disabled = !modifiedDocument && codeEditor.fileName;
219    };
220
221    // *** METHODS ACCESSED FROM PROPERTY SHEET/TOOLBOX/CODE EDITOR ***
222    void Reset()
223    {
224       if(classDesigner)
225       {
226          classDesigner.Reset();
227          classDesigner.SelectObject(null, null);
228          classDesigner.Destroy(0);
229          delete classDesigner;
230       }
231    }
232
233    void FillToolBox()
234    {
235       if(this && classDesigner)
236          classDesigner.ListToolBoxClasses(this);
237    }
238
239    void SelectObject(ObjectInfo object, Instance instance)
240    {
241       ClassDesignerBase classDesigner = this.classDesigner;
242 #ifdef _DEBUG
243       if(instance && instance._class.module.application != codeEditor.privateModule)
244          printf("warning: SelectObject: instance._class.module.application != codeEditor.privateModule\n");
245 #endif
246       if(!classDesigner || !instance || classDesigner._class != (Class)eInstance_GetDesigner(instance))
247       {
248          if(classDesigner)
249          {
250             classDesigner.SelectObject(null, null);
251             classDesigner.Destroy(0);
252             classDesigner = null;
253             delete this.classDesigner;
254          }
255          if(instance)
256          {
257             this.classDesigner = classDesigner = eInstance_New(eInstance_GetDesigner(instance));
258             incref classDesigner;
259             //if(!classDesigner.parent)
260             {
261                classDesigner.parent = this;
262                classDesigner.anchor = Anchor { left = 0, right = 0, top = 0, bottom = 0 };
263             }
264             classDesigner.Create();
265          }
266       }
267       // Call class editor SelectObject
268       if(classDesigner)
269          classDesigner.SelectObject(object, instance);
270    }
271
272    void AddObject()
273    {
274       // Call class editor AddObject
275       if(classDesigner)
276          classDesigner.AddObject();
277       if(visible)
278          Activate();
279       else
280          codeEditor.Activate();
281    }
282
283    void CreateObject(Instance instance, ObjectInfo object, bool isClass, Instance iclass)
284    {
285       subclass(ClassDesignerBase) designerClass = eInstance_GetDesigner(instance);
286
287       // Call class editor CreateObject
288       if(designerClass)
289          designerClass.CreateObject(this, instance, object, isClass, iclass);
290    }
291
292    void ::PostCreateObject(Instance instance, ObjectInfo object, bool isClass, Instance iclass)
293    {
294       subclass(ClassDesignerBase) designerClass = eInstance_GetDesigner(instance);
295
296       // Call class editor PostCreateObject
297       if(designerClass)
298          designerClass.PostCreateObject(instance, object, isClass, iclass);
299    }
300
301    void ::DroppedObject(Instance instance, ObjectInfo object, bool isClass, Instance iclass)
302    {
303       subclass(ClassDesignerBase) designerClass = eInstance_GetDesigner(instance);
304
305       // Call class editor PostCreateObject
306       if(designerClass)
307          designerClass.DroppedObject(instance, object, isClass, iclass);
308    }
309
310    void PrepareTestObject(Instance instance)
311    {
312       subclass(ClassDesignerBase) designerClass = eInstance_GetDesigner(instance);
313       if(designerClass)
314          designerClass.PrepareTestObject(this, instance);
315    }
316
317    void ::DestroyObject(Instance instance)
318    {
319       subclass(ClassDesignerBase) designerClass = eInstance_GetDesigner(instance);
320       if(designerClass)
321          designerClass.DestroyObject(instance);
322    }
323
324    void ::FixProperty(Property prop, Instance instance)
325    {
326       subclass(ClassDesignerBase) designerClass = eInstance_GetDesigner(instance);
327       if(designerClass)
328          designerClass.FixProperty(prop, instance);
329    }
330 }