Skip to content
Draft
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#pragma once

#include <OvEditor/Utils/ExternalTools.h>
#include <OvTools/Eventing/Event.h>

namespace OvEditor::Settings
Expand Down Expand Up @@ -92,5 +93,7 @@ namespace OvEditor::Settings
inline static Property<float> TranslationSnapUnit = { 1.0f };
inline static Property<float> RotationSnapUnit = { 15.0f };
inline static Property<float> ScalingSnapUnit = { 1.0f };
inline static Property<std::string> FolderExternalToolName = std::string{ Utils::ExternalTools.front().name};
inline static Property<std::string> FolderExternalToolCommand = std::string{ Utils::ExternalTools.front().command};
};
}
26 changes: 26 additions & 0 deletions Sources/Overload/OvEditor/include/OvEditor/Utils/ExternalTools.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* @project: Overload
* @author: Overload Tech.
* @licence: MIT
*/

#pragma once

#include <string>
#include <unordered_map>
#include <array>

namespace OvEditor::Utils
{
struct ExternalTool
{
const std::string_view name;
const std::string_view command;
};

constexpr auto ExternalTools = std::to_array<ExternalTool>({
ExternalTool{ "Visual Studio Code", "code {}" },
ExternalTool{ "Sublime Text", "subl {}" },
ExternalTool{ "Atom", "atom {}" },
});
}
37 changes: 37 additions & 0 deletions Sources/Overload/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include <fstream>
#include <iostream>

#include <OvEditor/Settings/EditorSettings.h>

#include <OvUI/Widgets/Texts/TextClickable.h>
#include <OvUI/Widgets/Visual/Image.h>
#include <OvUI/Widgets/Visual/Separator.h>
Expand Down Expand Up @@ -201,9 +203,27 @@ namespace

class FolderContextualMenu : public BrowserItemContextualMenu
{
private:
OvTools::Utils::OptRef<OvUI::Widgets::Menu::MenuItem> m_openInExternalTool;

public:
FolderContextualMenu(const std::string& p_filePath, bool p_protected = false) : BrowserItemContextualMenu(p_filePath, p_protected) {}

auto GetOpenInExternalToolName() const
{
return std::format(
"Open in {}",
OvEditor::Settings::EditorSettings::FolderExternalToolName.Get()
);
}
virtual void Execute(OvUI::Plugins::EPluginExecutionContext p_context) override
{
BrowserItemContextualMenu::Execute(p_context);

// Keep the "Open In External Tool" menu item label up to date
m_openInExternalTool->name = GetOpenInExternalToolName();
}

virtual void CreateList() override
{
auto& showInExplorer = CreateWidget<OvUI::Widgets::Menu::MenuItem>("Show in explorer");
Expand All @@ -212,6 +232,23 @@ namespace
OvTools::Utils::SystemCalls::ShowInExplorer(filePath);
};

m_openInExternalTool = CreateWidget<OvUI::Widgets::Menu::MenuItem>(GetOpenInExternalToolName());
m_openInExternalTool->ClickedEvent += [this]
{
const auto command = std::vformat(
OvEditor::Settings::EditorSettings::FolderExternalToolCommand.Get(),
std::make_format_args(filePath)
);

if (!OvTools::Utils::SystemCalls::ExecuteCommand(command))
{
OVLOG_ERROR(std::format(
"Failed to open {}",
OvEditor::Settings::EditorSettings::FolderExternalToolName.Get()
));
}
};

if (!m_protected)
{
auto& importAssetHere = CreateWidget<OvUI::Widgets::Menu::MenuItem>("Import Here...");
Expand Down
46 changes: 40 additions & 6 deletions Sources/Overload/OvEditor/src/OvEditor/Panels/MenuBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,20 @@
#include <OvCore/ECS/Components/CAudioSource.h>
#include <OvCore/ECS/Components/CAudioListener.h>

#include <OvUI/Widgets/Buttons/Button.h>
#include <OvUI/Widgets/Visual/Separator.h>
#include <OvUI/Widgets/Sliders/SliderInt.h>
#include <OvUI/Widgets/Sliders/SliderFloat.h>
#include <OvUI/Widgets/Drags/DragFloat.h>
#include <OvUI/Widgets/Selection/ColorEdit.h>

#include "OvEditor/Panels/MenuBar.h"
#include "OvEditor/Panels/SceneView.h"
#include "OvEditor/Panels/AssetView.h"
#include "OvEditor/Core/EditorActions.h"
#include "OvEditor/Settings/EditorSettings.h"
#include "OvEditor/Utils/ActorCreationMenu.h"
#include <OvEditor/Core/EditorActions.h>
#include <OvEditor/Panels/AssetView.h>
#include <OvEditor/Panels/MenuBar.h>
#include <OvEditor/Panels/SceneView.h>
#include <OvEditor/Settings/EditorSettings.h>
#include <OvEditor/Utils/ActorCreationMenu.h>
#include <OvEditor/Utils/ExternalTools.h>

using namespace OvUI::Panels;
using namespace OvUI::Widgets;
Expand Down Expand Up @@ -69,6 +71,38 @@ void OvEditor::Panels::MenuBar::HandleShortcuts(float p_deltaTime)

void OvEditor::Panels::MenuBar::InitializeSettingsMenu()
{
using namespace OvEditor::Settings;

auto& folderInExternalToolSettings = m_settingsMenu->CreateWidget<Menu::MenuList>("Folder External Tool...");
auto& folderExternalToolName = folderInExternalToolSettings.CreateWidget<InputFields::InputText>("", "Name");
auto& folderExternalToolCommand = folderInExternalToolSettings.CreateWidget<InputFields::InputText>("", "Command");
folderExternalToolCommand.selectAllOnClick = true;
folderInExternalToolSettings.ClickedEvent += [&folderExternalToolCommand, &folderExternalToolName]
{
folderExternalToolName.content = EditorSettings::FolderExternalToolName;
folderExternalToolCommand.content = EditorSettings::FolderExternalToolCommand;
};
folderExternalToolName.ContentChangedEvent += [](const auto& p_content)
{
EditorSettings::FolderExternalToolName = p_content;
};
folderExternalToolCommand.ContentChangedEvent += [](const auto& p_content)
{
EditorSettings::FolderExternalToolCommand = p_content;
};
folderInExternalToolSettings.CreateWidget<Visual::Separator>();
folderInExternalToolSettings.CreateWidget<Texts::Text>("Load External Tool Preset:");
for (auto& tool : Utils::ExternalTools)
{
folderInExternalToolSettings.CreateWidget<Buttons::Button>(std::string{ tool.name }, 300.0f).ClickedEvent += [&folderExternalToolName, &folderExternalToolCommand, &tool]
{
EditorSettings::FolderExternalToolName = std::string{ tool.name };
EditorSettings::FolderExternalToolCommand = std::string{ tool.command };
folderExternalToolName.content = tool.name;
folderExternalToolCommand.content = tool.command;
};
}

m_settingsMenu->CreateWidget<MenuItem>("Spawn actors at origin", "", true, true).ValueChangedEvent += EDITOR_BIND(SetActorSpawnAtOrigin, std::placeholders::_1);
m_settingsMenu->CreateWidget<MenuItem>("Vertical Synchronization", "", true, true).ValueChangedEvent += [this](bool p_value) { EDITOR_CONTEXT(device)->SetVsync(p_value); };
auto& cameraSpeedMenu = m_settingsMenu->CreateWidget<MenuList>("Camera Speed");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ void OvEditor::Settings::EditorSettings::Save()
iniFile.Add("translation_snap_unit", TranslationSnapUnit.Get());
iniFile.Add("rotation_snap_unit", RotationSnapUnit.Get());
iniFile.Add("scaling_snap_unit", ScalingSnapUnit.Get());
iniFile.Add("folder_external_tool_name", FolderExternalToolName.Get());
iniFile.Add("folder_external_tool_command", FolderExternalToolCommand.Get());
iniFile.Rewrite();
}

Expand All @@ -57,4 +59,6 @@ void OvEditor::Settings::EditorSettings::Load()
LoadIniEntry<float>(iniFile, "translation_snap_unit", TranslationSnapUnit);
LoadIniEntry<float>(iniFile, "rotation_snap_unit", RotationSnapUnit);
LoadIniEntry<float>(iniFile, "scaling_snap_unit", ScalingSnapUnit);
LoadIniEntry<std::string>(iniFile, "folder_external_tool_name", FolderExternalToolName);
LoadIniEntry<std::string>(iniFile, "folder_external_tool_command", FolderExternalToolCommand);
}
6 changes: 6 additions & 0 deletions Sources/Overload/OvTools/include/OvTools/Utils/SystemCalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ namespace OvTools::Utils
*/
static void EditFile(const std::string& p_file);

/**
* Execute a custom command. Returns true if the command invocation succeeded
* @param p_command
*/
static bool ExecuteCommand(const std::string_view p_command);

/**
* Open the given url with the default browser
* @param p_url
Expand Down
50 changes: 44 additions & 6 deletions Sources/Overload/OvTools/src/OvTools/Utils/SystemCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
* @licence: MIT
*/

#include "OvTools/Utils/PathParser.h"
#include "OvTools/Utils/SystemCalls.h"
#include <cassert>
#include <format>
#include <iostream>
#include <memory>

#include <OvTools/Utils/PathParser.h>
#include <OvTools/Utils/SystemCalls.h>

#include <Windows.h>
#include <ShlObj.h>
#include <memory>
#include <assert.h>
#include <Windows.h>

void OvTools::Utils::SystemCalls::ShowInExplorer(const std::string & p_path)
{
Expand All @@ -26,9 +29,44 @@ void OvTools::Utils::SystemCalls::OpenFile(const std::string & p_file, const std

void OvTools::Utils::SystemCalls::EditFile(const std::string & p_file)
{
ShellExecuteW(NULL, NULL, std::wstring(p_file.begin(), p_file.end()).c_str(), NULL, NULL, SW_NORMAL);
ShellExecuteW(NULL, NULL, std::wstring(p_file.begin(), p_file.end()).c_str(), NULL, NULL, SW_SHOWNORMAL);
}

bool OvTools::Utils::SystemCalls::ExecuteCommand(const std::string_view p_command)
{
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInfo;

ZeroMemory(&startupInfo, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
ZeroMemory(&processInfo, sizeof(processInfo));

std::string command = std::format("cmd.exe /c {}", p_command);

bool success = CreateProcess(
nullptr, // Application name (nullptr uses command line)
command.data(), // Command to execute
nullptr, // Process security attributes
nullptr, // Thread security attributes
FALSE, // Do not inherit handles
CREATE_NO_WINDOW, // Run the process without a window
nullptr, // Environment variables
nullptr, // Current directory
&startupInfo, // STARTUPINFO structure
&processInfo // PROCESS_INFORMATION structure
);

// Wait until child process exits.
WaitForSingleObject(processInfo.hProcess, INFINITE);

// Close the process and thread handles
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);

return success;
}


void OvTools::Utils::SystemCalls::OpenURL(const std::string& p_url)
{
ShellExecute(0, 0, p_url.c_str(), 0, 0, SW_SHOW);
Expand Down