Segmented ui draw function into smaller functions and added some comments
This commit is contained in:
@@ -83,6 +83,7 @@ namespace Nuake
|
||||
|
||||
void WelcomeWindow::Draw()
|
||||
{
|
||||
// Make viewport fullscreen
|
||||
ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(viewport->GetWorkPos());
|
||||
ImGui::SetNextWindowSize(viewport->GetWorkSize());
|
||||
@@ -92,173 +93,23 @@ namespace Nuake
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(32.0f, 32.0f));
|
||||
ImGui::Begin("Welcome Screen", 0, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize);
|
||||
{
|
||||
// Draw Nuake logo
|
||||
{
|
||||
const Vector2 logoSize = _NuakeLogo->GetSize();
|
||||
const ImVec2 imguiSize = ImVec2(logoSize.x, logoSize.y);
|
||||
ImGui::Image((ImTextureID)_NuakeLogo->GetID(), imguiSize, ImVec2(0, 1), ImVec2(1, 0));
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
// Add padding under logo
|
||||
ImGui::Dummy(ImVec2(10, 25));
|
||||
|
||||
{
|
||||
UIFont boldfont = UIFont(Fonts::SubTitle);
|
||||
ImGui::Text("Open recent");
|
||||
}
|
||||
|
||||
ImVec2 projectsWindowSize = ImGui::GetContentRegionAvail();
|
||||
projectsWindowSize.x *= 0.8f;
|
||||
|
||||
ImGui::BeginChild("Projects", projectsWindowSize, true);
|
||||
{
|
||||
const uint32_t itemHeight = 120;
|
||||
|
||||
for (uint32_t i = 0; i < std::size(_Projects); i++)
|
||||
{
|
||||
|
||||
ProjectPreview& project = _Projects[i];
|
||||
|
||||
|
||||
float cursorYStart = ImGui::GetCursorPosY();
|
||||
|
||||
std::string selectableName = "##" + std::to_string(i);
|
||||
bool isSelected = SelectedProject == i;
|
||||
if (ImGui::Selectable(selectableName.c_str(), isSelected, ImGuiSelectableFlags_AllowItemOverlap, ImVec2(ImGui::GetContentRegionAvailWidth(), itemHeight)))
|
||||
{
|
||||
SelectedProject = i;
|
||||
}
|
||||
|
||||
const ImVec2 padding = ImVec2(25.0f, 20.0f);
|
||||
const ImVec2 iconSize = ImVec2(100, 100);
|
||||
ImGui::SetCursorPos(padding / 2.0 + ImVec2(0, cursorYStart));
|
||||
|
||||
ImGui::Image((ImTextureID)project.ProjectIcon->GetID(), iconSize, ImVec2(0, 1), ImVec2(1, 0));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(padding.x + iconSize.x + padding.x);
|
||||
|
||||
ImGui::SetCursorPosX(padding.x + iconSize.x + padding.x);
|
||||
ImGui::SetCursorPosY(cursorYStart + padding.y);
|
||||
{
|
||||
UIFont boldfont = UIFont(Fonts::LargeBold);
|
||||
ImGui::Text(project.Name.c_str());
|
||||
}
|
||||
|
||||
ImGui::SetCursorPosY(cursorYStart + padding.y + 35.f);
|
||||
{
|
||||
ImGui::SetCursorPosX(padding.x + iconSize.x + padding.x);
|
||||
UIFont boldfont = UIFont(Fonts::Bold);
|
||||
ImGui::Text(project.Description.c_str());
|
||||
}
|
||||
|
||||
ImGui::SetCursorPosY(cursorYStart + itemHeight);
|
||||
}
|
||||
|
||||
if (ImGui::Button("Import an existing project", ImVec2(ImGui::GetContentRegionAvailWidth(), itemHeight)))
|
||||
{
|
||||
std::string path = FileDialog::OpenFile("*.project");
|
||||
if (path != "")
|
||||
{
|
||||
bool alreadyContainsProject = false;
|
||||
for (auto& p : _Projects)
|
||||
{
|
||||
if (p.Path == path)
|
||||
alreadyContainsProject = true;
|
||||
}
|
||||
|
||||
if (!alreadyContainsProject)
|
||||
{
|
||||
_Projects.push_back(ProjectPreview(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
DrawRecentProjectsSection();
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0, 0, 0, 0));
|
||||
if (ImGui::BeginChild("Controls", ImGui::GetContentRegionAvail(), false))
|
||||
{
|
||||
ImVec2 buttonSize = ImVec2(ImGui::GetContentRegionAvailWidth(), 58);
|
||||
if (ImGui::Button("Create a new project", buttonSize))
|
||||
{
|
||||
std::string selectedProject = FileDialog::SaveFile("Project file\0*.project");
|
||||
|
||||
if (!selectedProject.empty())
|
||||
{
|
||||
if(!String::EndsWith(selectedProject, ".project"))
|
||||
selectedProject += ".project";
|
||||
|
||||
auto backslashSplits = String::Split(selectedProject, '\\');
|
||||
auto fileName = backslashSplits[backslashSplits.size() - 1];
|
||||
|
||||
std::string finalPath = String::Split(selectedProject, '.')[0];
|
||||
|
||||
if (String::EndsWith(fileName, ".project"))
|
||||
{
|
||||
// We need to create a folder
|
||||
if (const auto& dirPath = finalPath;
|
||||
!std::filesystem::create_directory(dirPath))
|
||||
{
|
||||
// Should we continue?
|
||||
Logger::Log("Failed creating project directory: " + dirPath);
|
||||
}
|
||||
|
||||
finalPath += "\\" + fileName;
|
||||
}
|
||||
|
||||
auto project = Project::New(String::Split(fileName, '.')[0], "no description", finalPath);
|
||||
Engine::LoadProject(project);
|
||||
Engine::LoadScene(Scene::New());
|
||||
project->Save();
|
||||
|
||||
auto projectPreview = ProjectPreview();
|
||||
projectPreview.Name = project->Name;
|
||||
projectPreview.Description = project->Description;
|
||||
projectPreview.Path = project->FullPath;
|
||||
|
||||
_Projects.push_back(projectPreview);
|
||||
}
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
if (SelectedProject != -1)
|
||||
{
|
||||
if (ImGui::Button("Open an existing Project", buttonSize))
|
||||
{
|
||||
assert(SelectedProject < std::size(_Projects));
|
||||
|
||||
using namespace Nuake;
|
||||
|
||||
SaveRecentFile();
|
||||
|
||||
std::string projectPath = _Projects[SelectedProject].Path;
|
||||
FileSystem::SetRootDirectory(projectPath + "/../");
|
||||
|
||||
auto project = Project::New();
|
||||
auto projectFileData = FileSystem::ReadFile(projectPath, true);
|
||||
try
|
||||
{
|
||||
project->Deserialize(projectFileData);
|
||||
project->FullPath = projectPath;
|
||||
|
||||
Engine::LoadProject(project);
|
||||
|
||||
_Editor->filesystem->m_CurrentDirectory = Nuake::FileSystem::RootDirectory;
|
||||
}
|
||||
catch (std::exception exception)
|
||||
{
|
||||
Logger::Log("Error loading project: " + projectPath, CRITICAL);
|
||||
Logger::Log(exception.what());
|
||||
}
|
||||
|
||||
Engine::GetCurrentWindow()->SetTitle("Nuake Engine - Editing " + project->Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleColor();
|
||||
DrawRightControls();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
@@ -266,6 +117,171 @@ namespace Nuake
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
void WelcomeWindow::DrawRecentProjectsSection()
|
||||
{
|
||||
// Recent projects section takes up 80% of the width
|
||||
ImVec2 projectsWindowSize = ImGui::GetContentRegionAvail();
|
||||
projectsWindowSize.x *= 0.8f;
|
||||
|
||||
ImGui::BeginChild("Projects", projectsWindowSize, true);
|
||||
{
|
||||
for (uint32_t i = 0; i < std::size(_Projects); i++)
|
||||
{
|
||||
DrawProjectItem(i);
|
||||
}
|
||||
|
||||
const float itemHeight = 120.0f;
|
||||
if (ImGui::Button("Import an existing project", ImVec2(ImGui::GetContentRegionAvailWidth(), itemHeight)))
|
||||
{
|
||||
const std::string path = FileDialog::OpenFile("Project file |*.project");
|
||||
if (path != "" && String::EndsWith(path, ".project"))
|
||||
{
|
||||
// Prevent importing the same project twice in the list
|
||||
bool alreadyContainsProject = false;
|
||||
for (auto& p : _Projects)
|
||||
{
|
||||
if (p.Path == path)
|
||||
{
|
||||
alreadyContainsProject = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!alreadyContainsProject)
|
||||
{
|
||||
_Projects.push_back(ProjectPreview(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
void WelcomeWindow::DrawProjectItem(const uint32_t itemIndex)
|
||||
{
|
||||
const ProjectPreview& project = _Projects[itemIndex];
|
||||
const uint32_t itemHeight = 120;
|
||||
const float cursorYStart = ImGui::GetCursorPosY();
|
||||
|
||||
const std::string selectableName = "##" + std::to_string(itemIndex);
|
||||
const bool isSelected = SelectedProject == itemIndex;
|
||||
if (ImGui::Selectable(selectableName.c_str(), isSelected, ImGuiSelectableFlags_AllowItemOverlap, ImVec2(ImGui::GetContentRegionAvailWidth(), itemHeight)))
|
||||
{
|
||||
SelectedProject = itemIndex;
|
||||
}
|
||||
|
||||
const ImVec2 padding = ImVec2(25.0f, 20.0f);
|
||||
const ImVec2 iconSize = ImVec2(100, 100);
|
||||
ImGui::SetCursorPos(padding / 2.0 + ImVec2(0, cursorYStart));
|
||||
|
||||
ImGui::Image((ImTextureID)project.ProjectIcon->GetID(), iconSize, ImVec2(0, 1), ImVec2(1, 0));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(padding.x + iconSize.x + padding.x);
|
||||
|
||||
ImGui::SetCursorPosX(padding.x + iconSize.x + padding.x);
|
||||
ImGui::SetCursorPosY(cursorYStart + padding.y);
|
||||
{
|
||||
UIFont boldfont = UIFont(Fonts::LargeBold);
|
||||
ImGui::Text(project.Name.c_str());
|
||||
}
|
||||
|
||||
ImGui::SetCursorPosY(cursorYStart + padding.y + 35.f);
|
||||
{
|
||||
ImGui::SetCursorPosX(padding.x + iconSize.x + padding.x);
|
||||
UIFont boldfont = UIFont(Fonts::Bold);
|
||||
ImGui::Text(project.Description.c_str());
|
||||
}
|
||||
|
||||
ImGui::SetCursorPosY(cursorYStart + itemHeight);
|
||||
}
|
||||
|
||||
void WelcomeWindow::DrawRightControls()
|
||||
{
|
||||
const float buttonHeight = 58.0f;
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0, 0, 0, 0));
|
||||
if (ImGui::BeginChild("Controls", ImGui::GetContentRegionAvail(), false))
|
||||
{
|
||||
const ImVec2 buttonSize = ImVec2(ImGui::GetContentRegionAvailWidth(), buttonHeight);
|
||||
if (ImGui::Button("Create a new project", buttonSize))
|
||||
{
|
||||
std::string selectedProject = FileDialog::SaveFile("Project file\0*.project");
|
||||
|
||||
if (!selectedProject.empty())
|
||||
{
|
||||
if(!String::EndsWith(selectedProject, ".project"))
|
||||
selectedProject += ".project";
|
||||
|
||||
auto backslashSplits = String::Split(selectedProject, '\\');
|
||||
auto fileName = backslashSplits[backslashSplits.size() - 1];
|
||||
|
||||
std::string finalPath = String::Split(selectedProject, '.')[0];
|
||||
|
||||
if (String::EndsWith(fileName, ".project"))
|
||||
{
|
||||
// We need to create a folder
|
||||
if (const auto& dirPath = finalPath;
|
||||
!std::filesystem::create_directory(dirPath))
|
||||
{
|
||||
// Should we continue?
|
||||
Logger::Log("Failed creating project directory: " + dirPath);
|
||||
}
|
||||
|
||||
finalPath += "\\" + fileName;
|
||||
}
|
||||
|
||||
auto project = Project::New(String::Split(fileName, '.')[0], "no description", finalPath);
|
||||
Engine::LoadProject(project);
|
||||
Engine::LoadScene(Scene::New());
|
||||
project->Save();
|
||||
|
||||
auto projectPreview = ProjectPreview();
|
||||
projectPreview.Name = project->Name;
|
||||
projectPreview.Description = project->Description;
|
||||
projectPreview.Path = project->FullPath;
|
||||
|
||||
_Projects.push_back(projectPreview);
|
||||
}
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
if (SelectedProject != -1)
|
||||
{
|
||||
if (ImGui::Button("Open an existing Project", buttonSize))
|
||||
{
|
||||
assert(SelectedProject < std::size(_Projects));
|
||||
|
||||
using namespace Nuake;
|
||||
|
||||
SaveRecentFile();
|
||||
|
||||
std::string projectPath = _Projects[SelectedProject].Path;
|
||||
FileSystem::SetRootDirectory(projectPath + "/../");
|
||||
|
||||
auto project = Project::New();
|
||||
auto projectFileData = FileSystem::ReadFile(projectPath, true);
|
||||
try
|
||||
{
|
||||
project->Deserialize(projectFileData);
|
||||
project->FullPath = projectPath;
|
||||
|
||||
Engine::LoadProject(project);
|
||||
|
||||
_Editor->filesystem->m_CurrentDirectory = Nuake::FileSystem::RootDirectory;
|
||||
}
|
||||
catch (std::exception exception)
|
||||
{
|
||||
Logger::Log("Error loading project: " + projectPath, CRITICAL);
|
||||
Logger::Log(exception.what());
|
||||
}
|
||||
|
||||
Engine::GetCurrentWindow()->SetTitle("Nuake Engine - Editing " + project->Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
void WelcomeWindow::ParseRecentFile()
|
||||
{
|
||||
if (!FileSystem::FileExists(_RecentProjectFilePath, true))
|
||||
|
||||
@@ -49,6 +49,10 @@ namespace Nuake
|
||||
void Draw();
|
||||
|
||||
private:
|
||||
void DrawRecentProjectsSection();
|
||||
void DrawProjectItem(const uint32_t projectPreview);
|
||||
void DrawRightControls();
|
||||
|
||||
void ParseRecentFile();
|
||||
void SaveRecentFile();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user