Browse Source

Made a basic layout for the wizard application.

David Piuva 3 years ago
parent
commit
5a4d532d26
1 changed files with 115 additions and 6 deletions
  1. 115 6
      Source/tools/wizard/main.cpp

+ 115 - 6
Source/tools/wizard/main.cpp

@@ -1,7 +1,9 @@
 
 // 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.
+//     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.
 
 #include "../../DFPSR/includeFramework.h"
@@ -12,20 +14,110 @@ using namespace dsr;
 // Global
 bool running = true;
 Window window;
-Component mainPanel;
-Component toolPanel;
 
 String interfaceContent =
 UR"QUOTE(
 Begin : Panel
 	Name = "mainPanel"
 	Solid = 0
-	Color = 180,180,180
+	Begin : Panel
+		Name = "upperPanel"
+		Bottom = 50
+		Solid = 1
+		Color = 120,120,100
+	End
+	Begin : Panel
+		Name = "lowerPanel"
+		Solid = 1
+		Top = 50
+		Color = 120,120,100
+		Begin : ListBox
+			Name = "projectList"
+			Color = 180,180,140
+			Left = 90%-100
+			Right = 100%-5
+			Top = 5
+			Bottom = 100%-50
+		End
+		Begin : Button
+			Name = "buildButton"
+			Text = "Build and run"
+			Color = 160,150,150
+			Left = 90%-100
+			Right = 100%-5
+			Top = 100%-45
+			Bottom = 100%-5
+		End
+		Begin : Label
+			Name = "descriptionLabel"
+			Text = "DFPSR wizard application"
+			Left = 5
+			Right = 90%-105
+			Top = 5
+			Bottom = 100%-5
+		End
+	End
 End
 )QUOTE";
 
+// Visual components
+Component projectList;
+Component buildButton;
+Component descriptionLabel;
+
+// Media
 int boomSound;
 
+struct Project {
+	String buildScript; // To execute
+	String projectFolderName; // To display
+	Project(const ReadableString &buildScript, const ReadableString &projectFolderName)
+	: buildScript(buildScript), projectFolderName(projectFolderName) {}
+};
+List<Project> projects;
+
+static ReadableString findParent(const ReadableString& startPath, const ReadableString& parentName) {
+	int64_t pathEndIndex = -1; // Last character of path leading to Source.
+	file_getPathEntries(startPath, [&pathEndIndex, &parentName](ReadableString entry, int64_t firstIndex, int64_t lastIndex) {
+		if (string_match(entry, parentName)) {
+			pathEndIndex = lastIndex;
+		}
+	});
+	if (pathEndIndex == -1) {
+		throwError(U"Could not find the Source folder with SDK examples.");
+		return startPath;
+	} else {
+		return string_until(startPath, pathEndIndex);
+	}
+}
+
+static void findProjects(const ReadableString& folderPath) {
+	file_getFolderContent(folderPath, [](const ReadableString& entryPath, const ReadableString& entryName, EntryType entryType) {
+		if (entryType == EntryType::Folder) {
+			findProjects(entryPath);
+		} else if (entryType == EntryType::File) {
+			ReadableString extension = string_upperCase(file_getExtension(entryName));
+			// If we find a project within folderPath...
+			if (string_match(extension, U"DSRPROJ")) {
+				String projectFolderName = file_getPathlessName(file_getRelativeParentFolder(entryPath));
+				// ...and the folder is not namned wizard...
+				if (!string_match(projectFolderName, U"wizard")) {
+					// ...then add it to the list of projects.
+					projects.pushConstruct(entryPath, projectFolderName);
+				}
+			}
+		}
+	});
+}
+
+static void populateInterface(const ReadableString& folderPath) {
+	findProjects(folderPath);
+	for (int p = 0; p < projects.length(); p++) {
+		component_call(projectList, U"PushElement", projects[p].projectFolderName);
+	}
+	component_setProperty_integer(projectList, U"SelectedIndex", 0, false);
+}
+
 DSR_MAIN_CALLER(dsrMain)
 void dsrMain(List<String> args) {
 	// Start sound
@@ -37,7 +129,15 @@ void dsrMain(List<String> args) {
 	window_loadInterfaceFromString(window, interfaceContent);
 
 	// Find components
-	mainPanel = window_findComponentByName(window, U"mainPanel");
+	projectList = window_findComponentByName(window, U"projectList");
+	buildButton = window_findComponentByName(window, U"buildButton");
+	descriptionLabel = window_findComponentByName(window, U"descriptionLabel");
+
+	// Find projects to showcase
+	//   On systems that don't allow getting the application's folder, the program must be started somewhere within the Source folder.
+	String applicationFolder = file_getApplicationFolder();
+	String sourceFolder = findParent(applicationFolder, U"Source");
+	populateInterface(sourceFolder);
 
 	// Bind methods to events
 	window_setKeyboardEvent(window, [](const KeyboardEvent& event) {
@@ -48,12 +148,21 @@ void dsrMain(List<String> args) {
 			}
 		}
 	});
+	component_setPressedEvent(buildButton, []() {
+		// TODO: Implement building and running of the selected project.
+		component_setProperty_string(descriptionLabel, U"Text", U"Compiling and running projects from the wizard application is not yet implemented.");
+	});
+	component_setSelectEvent(projectList, [](int64_t index) {
+		// TODO: Load description from a text file with a specific name in the project's folder.
+		playSound(boomSound, false, 0.5, 0.5, 0.5);
+		component_setProperty_string(descriptionLabel, U"Text", string_combine(U"Project at ", projects[index].buildScript));
+	});
 	window_setCloseEvent(window, []() {
 		running = false;
 	});
 
 	// Execute
-	playSound(boomSound, false, 1.0, 1.0, 0.25); // TODO: Get the initial sound to play.
+	playSound(boomSound, false, 1.0, 1.0, 0.25);
 	while(running) {
 		// Wait for actions so that we don't render until an action has been recieved
 		// This will save battery on laptops for applications that don't require animation