ide; added fast math option to ProjectSettings dialog and equal to optimize functiona...
[sdk] / ide / src / dialogs / NewProjectDialog.ec
1 import "ide"
2
3 FileDialog fileDialog { type = selectDir, text = $"Select project directory" };
4
5 class NewProjectDialog : Window
6 {
7    background = formColor;
8    minClientSize = { 316, 170 };
9    maxClientSize = { 640, 170 };
10    borderStyle = sizable;
11    tabCycle = true;
12    hasClose = true;
13    text = $"New Project";
14
15    char path[MAX_LOCATION];
16    char name[MAX_FILENAME];
17
18    PathBox locationEditBox
19    {
20       this, position = { 10, 80 }, size = { 120, 22 }, anchor = { left = 10, top = 80, right = 10 };
21       hotKey = altL, text = $"Location";
22       typeExpected = directory, browseDialog = fileDialog;
23
24       NotifyModified = NotifyModifiedLocation;
25    };
26    Label { this, position = { 10, 60 }, labeledWindow = locationEditBox };
27
28    DropBox targetType { this, position = { 10, 130 }, size = { 130 }, hotKey = altT, text = $"Target Type" };
29
30    Label { this, position = { 10, 110 }, labeledWindow = targetType };
31
32    Button okBtn
33    {
34       parent = this, isDefault = true, disabled = true, position = { 170, 130 }, size = { 60 }, text = $"OK";
35       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
36       {
37          char * location = locationEditBox.slashPath;
38          char * prjName = projectName.contents;
39          char filePath[MAX_LOCATION];
40          char fileName[MAX_LOCATION];  // Windows Friendly path
41          char extension[MAX_EXTENSION];
42          FileAttribs exists;
43          Project project;
44          Workspace workspace;
45          ProjectView projectWindow;
46          ProjectConfig debug, release;
47          
48          if(!FileExists(location).isDirectory)
49          {
50             if(MessageBox { type = yesNo, master = this, 
51                   text = $"Directory doesn't exist", contents = $"Create directory?" }.Modal() == yes)
52             {
53                if(!MakeDir(location))
54                {
55                   MessageBox { type = ok, master = this, text = location, contents = $"Error creating directory" }.Modal();
56                   return true;
57                }
58             }
59             else
60                return true;
61          }
62
63          strcpy(filePath, location);
64          PathCatSlash(filePath, prjName);
65          GetExtension(filePath, extension);
66          //if(!extension[0])
67             ChangeExtension(filePath, ProjectExtension, filePath);
68
69          GetSystemPathBuffer(fileName, filePath);
70          exists = FileExists(filePath);
71
72          if(exists)
73          {
74             if(MessageBox { type = yesNo, master = this, 
75                   text = $"Project Already Exists", contents = $"Replace existing project?" }.Modal() == no)
76                return true;
77          }
78
79          debug = ProjectConfig
80          {
81             name = CopyString("Debug");
82             options = 
83             {
84                optimization = none;
85                debug = true;
86                preprocessorDefinitions = { [ CopyString("_DEBUG") ] };
87             };
88             makingModified = true;
89             compilingModified = true;
90             linkingModified = true;
91          };
92
93          release = ProjectConfig
94          {
95             name = CopyString("Release");
96             options =
97             {
98                optimization = speed;
99                fastMath = true;
100                debug = false;
101             };
102             makingModified = true;
103             compilingModified = true;
104             linkingModified = true;
105          };
106
107          /* error: too few arguments to function ‘__ecereProp_DirExpression_Set_char__PTR_’ -- debug.objDir = "debug";*/ 
108
109          project = Project
110          {
111             filePath = filePath;
112             moduleName = CopyString(name);
113             topNode.type = NodeTypes::project;
114             config = debug;
115          };
116          /*project.topNode.options = */project.options =
117          {
118             warnings = all;
119             // TOFIX: Precomp problems withou the extra ( )
120             targetType = ((TargetTypes)targetType.GetTag());
121             targetFileName = /*CopyString(*/name/*)*/;
122          };
123          if(project.options.targetType != staticLibrary)
124          {
125             project.options.libraries = { [ CopyString("ecere") ] };
126          }
127
128          {
129             char workspaceFile[MAX_LOCATION];
130             strcpy(workspaceFile, filePath);
131             ChangeExtension(workspaceFile, WorkspaceExtension, workspaceFile);
132             workspace = Workspace { compiler = ideSettings.defaultCompiler, workspaceFile = workspaceFile };
133          } 
134          workspace.projects.Add(project);
135
136          project.topNode.configurations = /*project.configurations = */{ [ debug, release ] };
137          project.resNode = project.topNode.Add(project, "Resources", null, resources, archiveFile, false);
138
139          if(!project.Save(filePath))
140          {
141             MessageBox { type = ok, master = this, text = filePath, contents = $"Error writing project file" }.Modal();
142             delete project;
143             return true;
144          }
145
146          projectWindow = ide.CreateProjectView(workspace, fileName);
147          
148          {
149             char newWorkingDir[MAX_LOCATION];
150             StripLastDirectory(filePath, newWorkingDir);
151
152             ide.ChangeFileDialogsDirectory(newWorkingDir, false);
153             
154             StripLastDirectory(newWorkingDir, newWorkingDir);
155             ide.ChangeProjectFileDialogDirectory(newWorkingDir);
156          }
157
158          if(createForm.checked)
159          {
160             char className[256];
161             char varName[256];
162             CodeEditor codeEditor = projectWindow.CreateNew("Form", "form", "Window", className);
163             EditBox editBox = codeEditor.editBox;
164             strcpy(varName, className);
165             if(islower(varName[0]))
166             {
167                memmove(varName+1, varName, strlen(varName)+1);
168                varName[0] = '_';
169             }
170             else
171                varName[0] = (char)tolower(varName[0]);
172
173             editBox.End();
174             editBox.Printf("\n%s %s {};\n", className, varName);
175
176             codeEditor.EnsureUpToDate();
177
178             project.Save(filePath);
179
180             projectWindow.modifiedDocument = false;
181             project.topNode.modified = false;
182
183             /*
184             editBox.Printf("class FormApplication : GuiApplication\n");
185             editBox.Printf("{\n");
186             editBox.Printf("   %s %s {};\n", className, varName);
187             editBox.Printf("}\n");
188             editBox.Home();
189             */
190          }
191          project.StartMonitoring();
192
193          if(project && projectWindow)
194          {
195             CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
196             ProjectConfig config = project.config;
197             projectWindow.ShowOutputBuildLog(true);
198             projectWindow.DisplayCompiler(compiler, false);
199             projectWindow.ProjectPrepareCompiler(project, compiler);
200             projectWindow.ProjectPrepareMakefile(project, force, compiler, config);
201             delete compiler;
202          }
203
204          Destroy(0);
205          return true;
206       }
207    };
208    
209    Button
210    {
211       parent = this, position = { 240, 130 }, size = { 60 }, hotKey = escape, text = $"Cancel";
212       NotifyClicked = ButtonCloseDialog;
213    };
214    Button createForm
215    {
216       parent = this, text = $"Create Form", hotKey = altF, position = { 200, 30 };
217       isCheckbox = true, checked = true;
218    };
219    
220    EditBox projectName
221    {
222       parent = this, textHorzScroll = true, position = { 10, 30 }, size = { 160 };
223       hotKey = altP, text = $"Project Name";
224       NotifyUpdate = EditBoxUpdate;
225
226       bool NotifyModified(EditBox editBox)
227       {
228          char name[MAX_FILENAME];
229          char lastPart[MAX_LOCATION];
230          char * text = editBox.contents;
231
232          // drop leading path stuff that has no business here
233          GetLastDirectory(text, name);
234
235          GetLastDirectory(path, lastPart);
236          if(name[0] && (!strcmp(path, lastPart) || !path[0] || !strcmp(this.name, lastPart)))
237          {
238             if(strcmp(path, lastPart))
239                StripLastDirectory(path, path);
240             PathCatSlash(path, name);
241             locationEditBox.path = path;
242          }
243          else if(!name[0] && !strcmp(this.name, lastPart))
244          {
245             if(strcmp(path, lastPart))
246                StripLastDirectory(path, path);
247             locationEditBox.path = path;
248          }
249          else if(strcmp(name, lastPart))
250          {
251             PathCatSlash(path, name);
252             locationEditBox.path = path;
253          }
254          strcpy(this.name, name);
255          editBox.contents = name;
256          return true;
257       }
258    };
259    Label { this, position = { 10, 10 }, labeledWindow = projectName };
260
261    void EditBoxUpdate(EditBox editBox)
262    {
263       okBtn.disabled = !(locationEditBox.path[0] && projectName.contents[0]);
264    }
265
266    bool NotifyModifiedLocation(PathBox pathBox)
267    {
268       char location[MAX_LOCATION];
269       char lastPart[MAX_FILENAME];
270       char * text = pathBox.slashPath;
271
272       //replacing this: NotifyUpdate = EditBoxUpdate;
273       okBtn.disabled = !(text[0] && projectName.contents[0]);
274
275       GetWorkingDir(location, sizeof(location) - 1);
276       PathCatSlash(location, text);
277
278       GetLastDirectory(path, lastPart);
279       /*if(text[0] && (!name[0] || !strcmp(lastPart, name)))
280       {
281          char newName[MAX_FILENAME];
282          GetLastDirectory(location, newName);
283          if(strcmp(newName, location))
284          {
285             strcpy(name, newName);
286             projectName.contents = name;
287          }
288       }*/
289       strcpy(path, location);
290       pathBox.path = path;
291       return true;
292    }
293
294    NewProjectDialog()
295    {
296       char location[MAX_LOCATION];
297
298       if(ideSettings.ideProjectFileDialogLocation)
299          strcpy(location, ideSettings.ideProjectFileDialogLocation);
300       else
301          GetWorkingDir(location, sizeof(location) - 1);
302
303       locationEditBox.path = location;
304       strcpy(path, location);
305
306       {
307          DataRow row;
308
309          //targetType.AddField("String", null, 0);
310
311          row = targetType.AddRow();
312          row.tag = TargetTypes::executable;
313          row.SetData(null, $"Executable");
314
315          row = targetType.AddRow();
316          row.tag = TargetTypes::sharedLibrary;
317          row.SetData(null, $"Shared Library");
318
319          row = targetType.AddRow();
320          row.tag = TargetTypes::staticLibrary;
321          row.SetData(null, $"Static Library");
322
323          targetType.currentRow = targetType.FindRow(TargetTypes::executable);
324       }
325    }
326 }
327
328 class QuickProjectDialog : Window
329 {
330    background = formColor;
331    minClientSize = { 316, 110 };
332    maxClientSize = { 640, 110 };
333    borderStyle = sizable;
334    tabCycle = true;
335    hasClose = true;
336    text = $"Quick Project";
337
338    char path[MAX_LOCATION];
339    char name[MAX_FILENAME];
340
341    Label message { this, position = { 10, 10 }, text = $"Do you want to quickly create a temporary project?" };
342
343    DropBox targetType { this, position = { 10, 70 }, size = { 130 }, hotKey = altT, text = $"Target Type" };
344    Label { this, position = { 10, 50 }, labeledWindow = targetType };
345
346    Button okBtn
347    {
348       parent = this, isDefault = true, position = { 170, 70 }, size = { 60 }, text = $"OK";
349       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
350       {
351          char tempDir[MAX_LOCATION] = "";
352          char filePath[MAX_LOCATION];
353          char prjName[MAX_LOCATION] = "quick_project";
354          Project project;
355          Workspace workspace;
356          ProjectView projectWindow;
357          ProjectConfig debug, release;
358
359          /*if(!*/CreateTemporaryDir(tempDir, "ecereide");/*)
360          {
361             MessageBox { type = ok, master = this, text = tempDir, contents = "Error creating temporary directory." }.Modal();
362             return true;
363          }*/
364
365          GetLastDirectory(tempDir, prjName);
366          {
367             char * dot;
368             if((dot = strstr(prjName, ".")))
369                dot[0] = '_';
370          }
371
372          if(!FileExists(tempDir).isDirectory)
373          {
374             MessageBox { type = ok, master = this, text = tempDir, contents = $"Temporary directory does not exist." }.Modal();
375             return true;
376          }
377          
378          ide.tmpPrjDir = tempDir;
379
380          strcpy(filePath, tempDir);
381          PathCatSlash(filePath, prjName);
382          //GetExtension(filePath, extension);
383          //if(!extension[0])
384             ChangeExtension(filePath, ProjectExtension, filePath);
385          GetSystemPathBuffer(filePath, filePath);
386
387          debug = ProjectConfig
388          {
389             name = CopyString("Debug");
390             options = 
391             {
392                optimization = none;
393                debug = true;
394                preprocessorDefinitions = { [ CopyString("_DEBUG") ] };
395             };
396             makingModified = true;
397             compilingModified = true;
398             linkingModified = true;
399          };
400
401          release = ProjectConfig
402          {
403             name = CopyString("Release");
404             options =
405             {
406                optimization = speed;
407                fastMath = true;
408                debug = false;
409             };
410             makingModified = true;
411             compilingModified = true;
412             linkingModified = true;
413          };
414
415          project = Project
416          {
417             filePath = filePath;
418             moduleName = CopyString(prjName);
419             topNode.type = NodeTypes::project;
420             config = debug;
421          };
422          /*project.topNode.options = */project.options =
423          {
424             warnings = all;
425             // TOFIX: Precomp problems withou the extra ( )
426             targetType = ((TargetTypes)targetType.GetTag());
427             targetFileName = /*CopyString(*/prjName/*)*/;
428          };
429
430          if(project.options.targetType != staticLibrary)
431          {
432             project.options.libraries = { [ CopyString("ecere") ] };
433          }
434
435          {
436             char workspaceFile[MAX_LOCATION];
437             strcpy(workspaceFile, filePath);
438             ChangeExtension(workspaceFile, WorkspaceExtension, workspaceFile);
439             workspace = Workspace { compiler = ideSettings.defaultCompiler, workspaceFile = workspaceFile };
440          } 
441
442          workspace.projects.Add(project);
443
444          // *** Don't set this directly on project, it must be set on top ProjectNode ***
445          project.topNode.configurations = { [ debug, release ] };
446
447          project.resNode = project.topNode.Add(project, "Resources", null, resources, archiveFile, false);
448
449          if(!project.Save(filePath))
450          {
451             MessageBox { type = ok, master = this, text = filePath, contents = $"Error writing project file" }.Modal();
452             delete project;
453             delete workspace;
454             ide.DestroyTemporaryProjectDir();
455             return true;
456          }
457
458          projectWindow = ide.CreateProjectView(workspace, filePath);
459
460          {
461             char extension[MAX_EXTENSION];
462             Window document = null;
463             for(document = ide.firstChild; document; document = document.next)
464             {
465                char * fileName = document.fileName;
466                if(document.isDocument && document._class == class(CodeEditor) && document.created && fileName)
467                {
468                   CodeEditor codeEditor = (CodeEditor)document;
469                   ide.projectView.AddFile(project.topNode, fileName, false, false);
470                   codeEditor.DebugMenusDisabled();
471                }
472             }
473          }
474
475          if(project.topNode.modified)
476          {
477             project.Save(filePath);
478             projectWindow.modifiedDocument = false;
479             project.topNode.modified = false;
480          }
481          else
482          {
483             // TOCHECK: Why is the Quick project creating a form???
484             char className[256];
485             char varName[256];
486             CodeEditor codeEditor = projectWindow.CreateNew("Form", "form", "Window", className);
487             EditBox editBox = codeEditor.editBox;
488             strcpy(varName, className);
489             if(islower(varName[0]))
490             {
491                memmove(varName+1, varName, strlen(varName)+1);
492                varName[0] = '_';
493             }
494             else
495                varName[0] = (char)tolower(varName[0]);
496
497             editBox.End();
498             editBox.Printf("\n%s %s {};\n", className, varName);
499
500             codeEditor.EnsureUpToDate();
501
502             // TODO: how to save that new file?
503
504             project.Save(filePath);
505             projectWindow.modifiedDocument = false;
506             project.topNode.modified = false;
507          }
508          project.StartMonitoring();
509
510          visible = false;
511
512          if(project && projectWindow)
513          {
514             CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
515             ProjectConfig config = project.config;
516             projectWindow.ShowOutputBuildLog(true);
517             projectWindow.DisplayCompiler(compiler, false);
518             projectWindow.ProjectPrepareCompiler(project, compiler);
519             projectWindow.ProjectPrepareMakefile(project, force, compiler, config);
520             delete compiler;
521          }
522
523          ide.projectView.ProjectBuild(null, Modifiers { });
524
525          Destroy(0);
526          return true;
527       }
528    };
529    
530    Button
531    {
532       parent = this, position = { 240, 70 }, size = { 60 }, hotKey = escape, text = $"Cancel";
533       NotifyClicked = ButtonCloseDialog;
534    };
535    
536    QuickProjectDialog()
537    {
538       DataRow row;
539
540       row = targetType.AddRow();
541       row.tag = TargetTypes::executable;
542       row.SetData(null, $"Executable");
543
544       row = targetType.AddRow();
545       row.tag = TargetTypes::sharedLibrary;
546       row.SetData(null, $"Shared Library");
547
548       row = targetType.AddRow();
549       row.tag = TargetTypes::staticLibrary;
550       row.SetData(null, $"Static Library");
551
552       targetType.currentRow = targetType.FindRow(TargetTypes::executable);
553    }
554 }