Browse Source

Made it possible to create new projects from templates in the wizard application.

David Piuva 7 months ago
parent
commit
f42acb764c

+ 1 - 2
Source/tools/processing/cloneProject/main.cpp

@@ -3,9 +3,8 @@
 
 // TODO:
 // * Give a warning when the source and target paths are on different drives, because absolute paths do not work across different operating systems.
-// * Create a visual interface for creating new projects from templates in the Wizard application.
-//   Choose to create a new project, choose a template, choose a new name and location.
 // * Filter out files using patterns, to avoid cloning executable files and descriptions of template projects.
+//   build.sh files are currently not handled due to the complex syntax, so paths there might have to be updated manually.
 
 #include "../../../DFPSR/includeEssentials.h"
 

+ 87 - 14
Source/tools/wizard/main.cpp

@@ -1,12 +1,7 @@
 
 // TODO:
-// * A catalogue of SDK examples with images and descriptions loaded automatically from their folder.
-//     Offer one-click build and execution of SDK examples on multiple platforms, while explaining how the building works.
-//     How can the file library execute other applications and scripts in a portable way when scripts need to select a terminal application to execute them?
-//     Maybe call the builder as a static library and have it call the compiler directly in a simulated terminal window embedded into the wizard, instead of using unreliable scripts?
-// * Let the user browse a file system and select a location for a new or existing project.
-//     Should a multi-frame tab container be created to allow having multiple frames in the same container?
-//         Can let frames have a caption for when used within a container.
+// * Create a reusable file explorer component with lots of features and settings.
+//   Then use it to select a cloning destination for new projects.
 
 #include "../../DFPSR/includeFramework.h"
 #include "../../SDK/SoundEngine/soundEngine.h"
@@ -18,10 +13,18 @@ bool running = true;
 Window window;
 
 // Visual components
-Component projectList;
-Component launchButton;
-Component descriptionLabel;
-Component previewPicture;
+Component selectPanel;
+	Component previewPicture;
+	Component descriptionLabel;
+	Component projectList;
+	Component launchButton;
+	Component cloneButton;
+Component clonePanel;
+	Component sourceBox;
+	Component targetBox;
+	Component nameBox;
+	Component cancelCloneButton;
+	Component acceptCloneButton;
 
 // Media
 int boomSound;
@@ -147,6 +150,29 @@ static void populateInterface() {
 	selectProject(0);
 }
 
+static void cloneProject(const ReadableString &toolPath, const ReadableString &sourceFolderPath, const ReadableString &targetFolderPath, const ReadableString &projectName) {
+	printText(U"Cloning project from ", sourceFolderPath, U" to ", targetFolderPath, U" using project name ", projectName, U"\n");
+	if (file_getEntryType(toolPath) != EntryType::File) {
+		throwError(U"Could not find the cloning tool at ", toolPath, U"! Make sure that it is compiled and located where it should be.\n");
+	}
+	// TODO: Create a waiting panel to allow showing the progress of a process while waiting for results.
+	DsrProcess process = process_execute(toolPath, List<String>(U"-s", sourceFolderPath, U"-t", targetFolderPath, U"-n", projectName));
+	while (true) {
+		DsrProcessStatus status = process_getStatus(process);
+		if (status == DsrProcessStatus::Completed) {
+			printText(U"Done cloning the project.\n");
+			break;
+		} else if (status == DsrProcessStatus::Crashed) {
+			printText(U"The cloning tool failed!\n");
+			break;
+		} else if (status == DsrProcessStatus::NotStarted) {
+			printText(U"Failed to start the cloning tool!\n");
+			break;
+		}
+		time_sleepSeconds(0.001);
+	}	
+}
+
 DSR_MAIN_CALLER(dsrMain)
 void dsrMain(List<String> args) {
 	// Get the application folder.
@@ -172,6 +198,14 @@ void dsrMain(List<String> args) {
 	// Find components.
 	projectList = window_findComponentByName(window, U"projectList");
 	launchButton = window_findComponentByName(window, U"launchButton");
+	cloneButton = window_findComponentByName(window, U"cloneButton");
+	sourceBox = window_findComponentByName(window, U"sourceBox");
+	targetBox = window_findComponentByName(window, U"targetBox");
+	nameBox = window_findComponentByName(window, U"nameBox");
+	cancelCloneButton = window_findComponentByName(window, U"cancelCloneButton");
+	acceptCloneButton = window_findComponentByName(window, U"acceptCloneButton");
+	selectPanel = window_findComponentByName(window, U"selectPanel");
+	clonePanel = window_findComponentByName(window, U"clonePanel");
 	descriptionLabel = window_findComponentByName(window, U"descriptionLabel");
 	previewPicture = window_findComponentByName(window, U"previewPicture");
 
@@ -191,6 +225,48 @@ void dsrMain(List<String> args) {
 			}
 		}
 	});
+	component_setPressedEvent(cloneButton, []() {
+		// Get the project index.
+		int projectIndex = component_getProperty_integer(projectList, U"SelectedIndex", true);
+		// Check if the project index is valid.
+		if (projectIndex >= 0 && projectIndex < projects.length()) {
+			ReadableString projectFilePath = projects[projectIndex].projectFilePath;
+			ReadableString sourceFolder = file_getAbsoluteParentFolder(projectFilePath);
+			ReadableString projectName = file_getExtensionless(file_getPathlessName(projectFilePath));
+			// Show the clone panel and fill in some information.
+			component_setProperty_string(sourceBox, U"Text", sourceFolder, true);
+			component_setProperty_string(targetBox, U"Text", U"?", true);
+			component_setProperty_string(nameBox, U"Text", projectName, true);
+			component_setProperty_integer(selectPanel, U"Visible", 0, true);
+			component_setProperty_integer(clonePanel, U"Visible", 1, true);
+			soundEngine_playSound(boomSound, false);
+		}
+	});
+	component_setPressedEvent(cancelCloneButton, []() {
+		soundEngine_playSound(boomSound, false);
+		// Show the select panel.
+		component_setProperty_integer(selectPanel, U"Visible", 1, true);
+		component_setProperty_integer(clonePanel, U"Visible", 0, true);
+	});
+	component_setPressedEvent(acceptCloneButton, [applicationFolder]() {
+		soundEngine_playSound(boomSound, false);
+		// Try to clone the selected project.
+		// TODO: Can a reusable function generate executable filenames without hardcoding them in each program?
+		#ifdef USE_MICROSOFT_WINDOWS
+			String cloneExecutableFile = U"Clone.exe";
+		#else
+			String cloneExecutableFile = U"Clone";
+		#endif
+		cloneProject(
+		  file_combinePaths(applicationFolder, U"..", U"processing", U"cloneProject", cloneExecutableFile),
+		  component_getProperty_string(sourceBox, U"Text", true),
+		  component_getProperty_string(targetBox, U"Text", true),
+		  component_getProperty_string(nameBox  , U"Text", true)
+		);
+		// Show the select panel.
+		component_setProperty_integer(selectPanel, U"Visible", 1, true);
+		component_setProperty_integer(clonePanel, U"Visible", 0, true);
+	});
 	component_setPressedEvent(launchButton, []() {
 		soundEngine_playSound(boomSound, false);
 		int projectIndex = component_getProperty_integer(projectList, U"SelectedIndex", true);
@@ -232,9 +308,6 @@ void dsrMain(List<String> args) {
 		while (!(window_executeEvents(window) || updateInterface(false))) {
 			time_sleepSeconds(0.01);
 		}
-		// Fill the background.
-		AlignedImageRgbaU8 canvas = window_getCanvas(window);
-		image_fill(canvas, ColorRgbaI32(64, 64, 64, 255));
 		// Draw interface.
 		window_drawComponents(window);
 		// Show the final image.

+ 90 - 12
Source/tools/wizard/media/Interface.lof

@@ -1,32 +1,28 @@
 Begin : Panel
 	Name = "mainPanel"
-	Solid = 0
+	Solid = 1
+	Color = 0,0,0
+	Plain = 1
 	Begin : Panel
-		Name = "upperPanel"
-		Bottom = 50
+		Name = "selectPanel"
 		Solid = 1
-		Color = 190,255,190
-	End
-	Begin : Panel
-		Name = "lowerPanel"
-		Solid = 1
-		Top = 50
 		Color = 0,0,0
 		Plain = 1
+		Visible = 1
 		Begin : Picture
 			Name = "previewPicture"
 			Interpolation = 1
 			Left = 5
 			Top = 5
 			Right = 90%-105
-			Bottom = 70%-5
+			Bottom = 70%-40
 		End
 		Begin : Label
 			Name = "descriptionLabel"
 			Color = 190,255,190
 			Left = 5
 			Right = 90%-105
-			Top = 70%
+			Top = 70%-35
 			Bottom = 100%-5
 		End
 		Begin : ListBox
@@ -39,12 +35,94 @@
 		End
 		Begin : Button
 			Name = "launchButton"
-			Text = "Launch"
+			Text = "Try"
 			Color = 190,255,190
 			Left = 90%-100
+			Right = 95%-55
+			Top = 100%-45
+			Bottom = 100%-5
+		End
+		Begin : Button
+			Name = "cloneButton"
+			Text = "Clone"
+			Color = 190,255,190
+			Left = 95%-50
 			Right = 100%-5
 			Top = 100%-45
 			Bottom = 100%-5
 		End
 	End
+	Begin : Panel
+		Name = "clonePanel"
+		Solid = 1
+		Color = 200,200,150
+		Plain = 0
+		Visible = 0
+		Begin : Label
+			Name = "sourceLabel"
+			Text = "Source path:"
+			Left = 10
+			Right = 100%-10
+			Top = 10
+			Bottom = 30
+		End
+		Begin : TextBox
+			Name = "sourceBox"
+			Text = ""
+			Left = 10
+			Right = 100%-10
+			Top = 30
+			Bottom = 55
+		End
+		Begin : Label
+			Name = "targetLabel"
+			Text = "Target path:"
+			Left = 10
+			Right = 100%-10
+			Top = 70
+			Bottom = 90
+		End
+		Begin : TextBox
+			Name = "targetBox"
+			Text = ""
+			Left = 10
+			Right = 100%-10
+			Top = 90
+			Bottom = 115
+		End
+		Begin : Label
+			Name = "nameLabel"
+			Text = "New project name:"
+			Left = 10
+			Right = 100%-10
+			Top = 130
+			Bottom = 150
+		End
+		Begin : TextBox
+			Name = "nameBox"
+			Text = ""
+			Left = 10
+			Right = 100%-10
+			Top = 150
+			Bottom = 175
+		End
+		Begin : Button
+			Name = "cancelCloneButton"
+			Text = "Cancel"
+			Color = 255,190,190
+			Left = 10
+			Right = 50%-5
+			Top = 100%-45
+			Bottom = 100%-10
+		End
+		Begin : Button
+			Name = "acceptCloneButton"
+			Text = "Begin cloning"
+			Color = 190,255,190
+			Left = 50%+5
+			Right = 100%-10
+			Top = 100%-45
+			Bottom = 100%-10
+		End
+	End
 End

+ 4 - 2
Source/tools/wizard/media/Theme.ini

@@ -29,22 +29,24 @@ focusOffsetX = 16
 focusOffsetY = 0
 
 [VerticalScrollKnob]
-method = "PressableDiffuseSpecular1x1"
+method = "PressableDiffuseSpecular3x3"
 sourceLeft = 96
 sourceTop = 64
 sourceWidth = 16
 sourceHeight = 32
 pressOffsetX = 16
 pressOffsetY = 0
+preserved = 3
 
 [HorizontalScrollKnob]
-method = "PressableDiffuseSpecular1x1"
+method = "PressableDiffuseSpecular3x3"
 sourceLeft = 96
 sourceTop = 96
 sourceWidth = 32
 sourceHeight = 16
 pressOffsetX = 0
 pressOffsetY = 16
+preserved = 3
 
 [VerticalScrollList]
 method = "VerticalScrollList"