Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Sources/OvCore/include/OvCore/Helpers/GUIHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ namespace OvCore::Helpers
std::string tooltip;
uint32_t iconID = 0;
std::function<void()> onSelected;
bool alwaysVisible = false;
};

class PickerItemList
Expand All @@ -60,6 +61,7 @@ namespace OvCore::Helpers
using FileItemBuilderCallback = std::function<PickerItemList(OvTools::Utils::PathParser::EFileType, std::function<void(std::string)>, bool, bool)>;
using OpenProviderCallback = std::function<void(const std::string&)>;
using PickerProviderCallback = std::function<void(PickerItemList, std::string)>;
using PickerSearchTextProviderCallback = std::function<std::string()>;
using IconProviderCallback = std::function<uint32_t(OvTools::Utils::PathParser::EFileType)>;
using ActorSelectionProviderCallback = std::function<void(uint64_t)>;
using AssetExistsCallback = std::function<bool(const std::string&)>;
Expand All @@ -85,6 +87,9 @@ namespace OvCore::Helpers
static void SetPickerProvider(PickerProviderCallback p_provider);
static void OpenPicker(PickerItemList p_items, std::string p_title);

static void SetPickerSearchTextProvider(PickerSearchTextProviderCallback p_provider);
static std::string GetPickerSearchText();

static void SetActorIconID(uint32_t p_id);
static uint32_t GetActorIconID();

Expand Down
11 changes: 11 additions & 0 deletions Sources/OvCore/src/OvCore/Helpers/GUIHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace
OvRendering::Resources::Texture* __EMPTY_TEXTURE = nullptr;
OvCore::Helpers::GUIHelpers::FileItemBuilderCallback __FILE_ITEM_BUILDER;
OvCore::Helpers::GUIHelpers::PickerProviderCallback __PICKER_PROVIDER;
OvCore::Helpers::GUIHelpers::PickerSearchTextProviderCallback __PICKER_SEARCH_TEXT_PROVIDER;
OvCore::Helpers::GUIHelpers::IconProviderCallback __ICON_PROVIDER;
OvCore::Helpers::GUIHelpers::OpenProviderCallback __OPEN_PROVIDER;
OvCore::Helpers::GUIHelpers::ActorSelectionProviderCallback __ACTOR_SELECTION_PROVIDER;
Expand Down Expand Up @@ -103,6 +104,16 @@ void OvCore::Helpers::GUIHelpers::OpenPicker(PickerItemList p_items, std::string
__PICKER_PROVIDER(std::move(p_items), std::move(p_title));
}

void OvCore::Helpers::GUIHelpers::SetPickerSearchTextProvider(PickerSearchTextProviderCallback p_provider)
{
__PICKER_SEARCH_TEXT_PROVIDER = std::move(p_provider);
}

std::string OvCore::Helpers::GUIHelpers::GetPickerSearchText()
{
return __PICKER_SEARCH_TEXT_PROVIDER ? __PICKER_SEARCH_TEXT_PROVIDER() : "";
}

void OvCore::Helpers::GUIHelpers::SetActorIconID(uint32_t p_id)
{
__ACTOR_ICON_ID = p_id;
Expand Down
8 changes: 8 additions & 0 deletions Sources/OvEditor/include/OvEditor/Core/EditorActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,14 @@ namespace OvEditor::Core
*/
bool ImportAsset(const std::string& p_initialDestinationDirectory);

/**
* Open a save dialog to create a new script file at a user-chosen location.
* Returns the absolute path of the created script, or empty on cancellation.
* @param p_initialDirectory Directory the dialog opens in
* @param p_initialName Suggested filename (without extension)
*/
std::string CreateScript(const std::string& p_initialDirectory, const std::string& p_initialName);

/**
* Import an asset at location
* @param p_destination
Expand Down
4 changes: 3 additions & 1 deletion Sources/OvEditor/include/OvEditor/Helpers/PickerHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ namespace OvEditor::Helpers::PickerHelpers
* @param p_onSelected Called with the resource path when the item is selected
* @param p_searchProject Include project assets
* @param p_searchEngine Include engine assets
* @param p_filter Optional predicate; return false to exclude an item (receives resource path)
*/
void AddFileItems(
OvCore::Helpers::GUIHelpers::PickerItemList& p_list,
OvTools::Utils::PathParser::EFileType p_fileType,
std::function<void(std::string)> p_onSelected,
bool p_searchProject = true,
bool p_searchEngine = true
bool p_searchEngine = true,
std::function<bool(const std::string&)> p_filter = {}
);
}
15 changes: 13 additions & 2 deletions Sources/OvEditor/include/OvEditor/Panels/ItemPicker.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ namespace OvEditor::Panels
*/
void Open(OvCore::Helpers::GUIHelpers::PickerItemList p_items, std::string p_title);

/**
* Returns the current text in the search field.
*/
std::string GetSearchText() const;

private:
void _Draw_Impl() override;
void Populate();
Expand All @@ -65,7 +70,13 @@ namespace OvEditor::Panels
OvUI::Widgets::InputFields::InputText* m_searchField = nullptr;
OvUI::Widgets::Layout::Group* m_listGroup = nullptr;

/* Each entry: (search key, row widget) */
std::vector<std::pair<std::string, OvUI::Widgets::Layout::Group*>> m_rows;
/* Each entry: search key, always-visible flag, and row widget */
struct RowEntry
{
std::string key;
bool alwaysVisible;
OvUI::Widgets::Layout::Group* widget;
};
std::vector<RowEntry> m_rows;
};
}
4 changes: 4 additions & 0 deletions Sources/OvEditor/src/OvEditor/Core/Editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ void OvEditor::Core::Editor::SetupUI()
}
);

OvCore::Helpers::GUIHelpers::SetPickerSearchTextProvider(
[this]() { return m_itemPicker->GetSearchText(); }
);

OvCore::Helpers::GUIHelpers::SetIconProvider(
[this](OvTools::Utils::PathParser::EFileType p_fileType) -> uint32_t {
auto* texture = m_context.editorResources->GetTexture(OvTools::Utils::PathParser::FileTypeToString(p_fileType));
Expand Down
37 changes: 37 additions & 0 deletions Sources/OvEditor/src/OvEditor/Core/EditorActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <OvEditor/Core/EditorActions.h>
#include <OvEditor/Core/GizmoBehaviour.h>
#include <OvEditor/Helpers/PickerHelpers.h>
#include <OvEditor/Panels/AssetBrowser.h>
#include <OvEditor/Panels/AssetView.h>
#include <OvEditor/Panels/GameView.h>
#include <OvEditor/Panels/Inspector.h>
Expand Down Expand Up @@ -1101,6 +1102,42 @@ bool OvEditor::Core::EditorActions::ImportAsset(const std::string& p_initialDest
return false;
}

std::string OvEditor::Core::EditorActions::CreateScript(const std::string& p_initialDirectory, const std::string& p_initialName)
{
using namespace OvWindowing::Dialogs;

const std::string extension = m_context.scriptEngine->GetDefaultExtension();

SaveFileDialog dialog("Create Script");
dialog.SetInitialDirectory(p_initialDirectory);
dialog.SetInitialFilename(p_initialName);
dialog.DefineExtension("Script", extension);
dialog.Show(
EExplorerFlags::DONTADDTORECENT |
EExplorerFlags::PATHMUSTEXIST |
EExplorerFlags::HIDEREADONLY |
EExplorerFlags::NOCHANGEDIR
);

if (!dialog.HasSucceeded())
return {};

const std::string destination = dialog.GetSelectedFilePath();

if (!std::filesystem::exists(destination))
{
const std::string scriptName = std::filesystem::path{ destination }.stem().string();
const std::string fileContent = m_context.scriptEngine->GetDefaultScriptContent(scriptName);

std::ofstream outfile(destination);
outfile << fileContent << std::endl;

EDITOR_PANEL(Panels::AssetBrowser, "Asset Browser").Refresh();
}

return destination;
}

bool OvEditor::Core::EditorActions::ImportAssetAtLocation(const std::string& p_destination)
{
using namespace OvWindowing::Dialogs;
Expand Down
14 changes: 10 additions & 4 deletions Sources/OvEditor/src/OvEditor/Helpers/PickerHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ namespace
const std::filesystem::path& p_directory,
bool p_isEngine,
PathParser::EFileType p_fileType,
const std::function<void(std::string)>& p_onSelected)
const std::function<void(std::string)>& p_onSelected,
const std::function<bool(const std::string&)>& p_filter)
{
if (!std::filesystem::exists(p_directory))
return;
Expand All @@ -41,6 +42,10 @@ namespace
continue;

const std::string resourcePath = EDITOR_EXEC(GetResourcePath(path, p_isEngine));

if (p_filter && !p_filter(resourcePath))
continue;

const std::string filename = PathParser::GetElementName(resourcePath);
const std::string friendlyPath = PathParser::GetFriendlyPath(resourcePath);
const uint32_t iconID = EDITOR_CONTEXT(editorResources)->GetFileIcon(path)->GetTexture().GetID();
Expand All @@ -61,11 +66,12 @@ void OvEditor::Helpers::PickerHelpers::AddFileItems(
PathParser::EFileType p_fileType,
std::function<void(std::string)> p_onSelected,
bool p_searchProject,
bool p_searchEngine)
bool p_searchEngine,
std::function<bool(const std::string&)> p_filter)
{
if (p_searchProject)
CollectFromDirectory(p_list, EDITOR_CONTEXT(projectAssetsPath), false, p_fileType, p_onSelected);
CollectFromDirectory(p_list, EDITOR_CONTEXT(projectAssetsPath), false, p_fileType, p_onSelected, p_filter);

if (p_searchEngine)
CollectFromDirectory(p_list, EDITOR_CONTEXT(engineAssetsPath), true, p_fileType, p_onSelected);
CollectFromDirectory(p_list, EDITOR_CONTEXT(engineAssetsPath), true, p_fileType, p_onSelected, p_filter);
}
42 changes: 41 additions & 1 deletion Sources/OvEditor/src/OvEditor/Panels/Inspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ void OvEditor::Panels::Inspector::_DrawAddSection()
return;

const uint32_t componentIconID = EDITOR_CONTEXT(editorResources)->GetTexture("Component")->GetTexture().GetID();
const uint32_t scriptIconID = EDITOR_CONTEXT(editorResources)->GetTexture("Script")->GetTexture().GetID();

OvCore::Helpers::GUIHelpers::PickerItemList items;

Expand Down Expand Up @@ -307,9 +308,48 @@ void OvEditor::Panels::Inspector::_DrawAddSection()

m_targetActor->AddBehaviour(scriptPath);
},
true, false
true, false,
[this](const std::string& p_resourcePath) {
const std::string scriptPath = EDITOR_EXEC(GetScriptPath(p_resourcePath));
return !m_targetActor->GetBehaviour(scriptPath);
}
);

items.Add({
"Create Script...",
"Create Script...",
"Create Script...",
scriptIconID,
[this] {
if (!m_targetActor.has_value())
return;

const std::string searchText = OvCore::Helpers::GUIHelpers::GetPickerSearchText();
const std::string initialDir = EDITOR_CONTEXT(projectAssetsPath).string();
const std::string destination = EDITOR_EXEC(CreateScript(initialDir, searchText));

if (destination.empty())
return;

const std::string scriptPath = EDITOR_EXEC(GetScriptPath(destination));
const std::string displayName = OvTools::Utils::PathParser::GetElementName(scriptPath);

if (m_targetActor->GetBehaviour(scriptPath))
{
OvWindowing::Dialogs::MessageBox(
"Script already attached",
"The script \"" + displayName + "\" is already attached to this actor.",
OvWindowing::Dialogs::MessageBox::EMessageType::ERROR,
OvWindowing::Dialogs::MessageBox::EButtonLayout::OK
);
return;
}

m_targetActor->AddBehaviour(scriptPath);
},
true /* alwaysVisible */
});

OvCore::Helpers::GUIHelpers::OpenPicker(std::move(items), "Add Component");
};
}
Expand Down
13 changes: 9 additions & 4 deletions Sources/OvEditor/src/OvEditor/Panels/ItemPicker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void ItemPicker::_Draw_Impl()
const auto& items = m_items.Items();
for (size_t i = 0; i < m_rows.size() && i < items.size(); ++i)
{
if (m_rows[i].second->enabled)
if (m_rows[i].widget->enabled)
{
items[i].onSelected();
Close();
Expand Down Expand Up @@ -164,12 +164,17 @@ void ItemPicker::Populate()
Close();
};

m_rows.emplace_back(item.key, &row);
m_rows.emplace_back(item.key, item.alwaysVisible, &row);
}
}

void ItemPicker::FilterList(const std::string& p_search)
{
for (auto& [key, row] : m_rows)
row->enabled = ContainsCaseInsensitive(key, p_search);
for (auto& entry : m_rows)
entry.widget->enabled = entry.alwaysVisible || ContainsCaseInsensitive(entry.key, p_search);
}

std::string ItemPicker::GetSearchText() const
{
return m_searchField ? m_searchField->content : "";
}
3 changes: 0 additions & 3 deletions Sources/OvWindowing/src/OvWindowing/Dialogs/FileDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ void OvWindowing::Dialogs::FileDialog::Show(EExplorerFlags p_flags)
#ifdef _WIN32
OPENFILENAME ofn;

if (!m_initialDirectory.empty())
m_filepath = m_initialDirectory;

if (!m_initialFilename.empty())
m_filepath = (std::filesystem::path{ m_initialDirectory } / m_initialFilename).string();

Expand Down
Loading