2#include "imgui_widgets/utils.h"
9#include <hpp/optional.hpp>
11#include <filedialog/filedialog.h>
12#include <imgui/imgui.h>
13#include <imgui_widgets/markdown.h>
30void draw_item(
const std::vector<project_item>& v, std::function<
void(ImVec2)> callback)
34 auto pos = ImGui::GetCursorPos();
37 for(
const auto& item : v)
47 height += ImGui::GetFrameHeightWithSpacing();
59 ImVec2 item_size(ImGui::GetContentRegionAvail().
x, height);
62 bool hovered = ImGui::IsItemHovered();
63 ImGui::SetCursorPos(pos);
83 for(
const auto& item : v)
85 ImGui::AlignTextToFramePadding();
86 ImGui::Text(
"%s", item.tag.c_str());
99 ImGui::AlignTextToFramePadding();
100 if(i == 0 && hovered)
102 ImGui::TextLink(fmt::format(
"{}", item.name).c_str());
106 ImGui::Text(
"%s", item.name.c_str());
128auto hub::draw_project_card(
const std::string&
id,
129 const std::string&
name,
130 const std::string& directory,
131 const std::chrono::system_clock::time_point& last_modified,
133 bool enable_interaction,
134 float form_width) ->
bool
137 ImVec2 card_size(form_width, 0);
140 ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 8.0f);
141 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(16, 12));
142 ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 8.0f);
144 bool is_hovered =
false;
149 ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetColorU32(ImGuiCol_ButtonActive, 0.4f));
153 ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetColorU32(ImGuiCol_FrameBg, 0.6f));
156 if(ImGui::BeginChild(
id.c_str(), card_size, ImGuiChildFlags_FrameStyle| ImGuiChildFlags_Borders | ImGuiChildFlags_AutoResizeY))
158 is_hovered = ImGui::IsWindowHovered();
163 ImDrawList* draw_list = ImGui::GetWindowDrawList();
164 ImVec2 p_min = ImGui::GetWindowPos();
165 ImVec2 p_max = ImVec2(p_min.x + ImGui::GetWindowSize().x, p_min.y + ImGui::GetWindowSize().y);
166 draw_list->AddRectFilled(p_min, p_max, ImGui::GetColorU32(ImGuiCol_ButtonHovered, 0.4f), 8.0f);
171 draw_list->AddRect(p_min, p_max, ImGui::GetColorU32(ImGuiCol_ButtonActive, 0.8f), 8.0f, 0, 2.0f);
175 draw_list->AddRect(p_min, p_max, ImGui::GetColorU32(ImGuiCol_ButtonActive, 0.6f), 8.0f, 0, 2.0f);
181 ImDrawList* draw_list = ImGui::GetWindowDrawList();
182 ImVec2 p_min = ImGui::GetWindowPos();
183 ImVec2 p_max = ImVec2(p_min.x + ImGui::GetWindowSize().x, p_min.y + ImGui::GetWindowSize().y);
184 draw_list->AddRect(p_min, p_max, ImGui::GetColorU32(ImGuiCol_ButtonActive, 0.6f), 8.0f, 0, 1.5f);
188 ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPosX() + 8, ImGui::GetCursorPosY() + 4));
195 if(is_hovered || is_selected)
197 ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_ButtonActive));
198 ImGui::Text(
"%s",
name.c_str());
199 ImGui::PopStyleColor();
203 ImGui::Text(
"%s",
name.c_str());
213 ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_TextDisabled, 0.9f));
223 float date_width = ImGui::CalcTextSize(date_text.c_str()).x;
224 float available_width = ImGui::GetContentRegionAvail().x;
226 ImGui::AlignedItem(1.0f,
231 ImGui::Text(
"%s", date_text.c_str());
237 float date_width = ImGui::CalcTextSize(unknown_text).x;
238 float available_width = ImGui::GetContentRegionAvail().x;
240 ImGui::AlignedItem(1.0f,
245 ImGui::Text(
"%s", unknown_text);
249 ImGui::PopStyleColor();
257 ImGui::PopStyleVar(3);
258 ImGui::PopStyleColor();
260 return is_hovered && enable_interaction;
268 ev.on_frame_update.connect(sentinel_,
this, &hub::on_frame_update);
269 ev.on_frame_before_render.connect(sentinel_,
this, &hub::on_frame_before_render);
270 ev.on_frame_render.connect(sentinel_,
this, &hub::on_frame_render);
271 ev.on_play_begin.connect(sentinel_, -999,
this, &hub::on_play_begin);
272 ev.on_script_recompile.connect(sentinel_, 10000,
this, &hub::on_script_recompile);
273 ev.on_os_event.connect(sentinel_, 10000,
this, &hub::on_os_event);
280 APPLOG_TRACE(
"{}::{}", hpp::type_name_str(*
this), __func__);
289 APPLOG_TRACE(
"{}::{}", hpp::type_name_str(*
this), __func__);
300 if(!pm.has_open_project())
312 if(!pm.has_open_project())
323 if(!pm.has_open_project())
334 if(!pm.has_open_project())
345 if(!pm.has_open_project())
347 on_start_page_render(ctx);
351 on_opened_project_render(ctx);
368 if(!pm.has_open_project())
373 if(
e.type == os::events::drop_position)
377 else if(
e.type == os::events::drop_begin)
381 else if(
e.type == os::events::drop_file)
385 else if(
e.type == os::events::drop_complete)
389 else if(
e.type == os::events::window)
391 if(
e.window.type == os::window_event_id::close)
393 auto window_id =
e.window.window_id;
396 auto render_window = rend.get_main_window();
399 if(render_window->get_window().get_id() == window_id)
419 const ImGuiViewport* viewport = ImGui::GetMainViewport();
420 ImGui::SetNextWindowPos(viewport->WorkPos);
421 ImGui::SetNextWindowSize(viewport->WorkSize);
422 ImGui::SetNextWindowViewport(viewport->ID);
423 ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
424 ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
426 ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking;
428 ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
429 window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
430 ImGui::Begin(
"START PAGE",
nullptr, window_flags);
431 ImGui::PopStyleVar(2);
433 ImGui::OpenPopup(
"PROJECTS");
436 ImVec2 viewport_size = ImGui::GetMainViewport()->Size;
437 ImVec2 popup_size = ImVec2(viewport_size.x * 0.5f, viewport_size.y * 0.5f);
438 ImGui::SetNextWindowSize(popup_size, ImGuiCond_Appearing);
441 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(24.0f, 20.0f));
442 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(12.0f, 10.0f));
444 if(ImGui::BeginPopupModal(
"PROJECTS",
nullptr, ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar))
446 switch(current_view_)
448 case view_state::projects_list:
449 render_projects_list_view(ctx);
451 case view_state::new_project_creator:
452 render_new_project_creator_view(ctx);
454 case view_state::project_remover:
455 render_project_remover_view(ctx);
462 ImGui::PopStyleVar(2);
471 auto on_open_project = [&](
const std::string&
p)
473 auto path = fs::path(p).make_preferred();
474 pm.open_project(ctx, path);
481 ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_TextDisabled, 0.8f));
482 ImGui::Text(
"Open an existing project or create a new one");
483 ImGui::PopStyleColor();
491 ImGui::PushStyleColor(ImGuiCol_Separator, ImGui::GetColorU32(ImGuiCol_TextDisabled, 0.3f));
493 ImGui::PopStyleColor();
499 float sidebar_width = 200.0f;
500 float content_spacing = 20.0f;
501 float content_width = ImGui::GetContentRegionAvail().x - sidebar_width - content_spacing;
507 ImGui::Text(
"Projects");
513 ImGuiWindowFlags flags = ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_NoSavedSettings;
515 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(16.0f, 16.0f));
516 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 12.0f));
517 ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 8.0f);
518 ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetColorU32(ImGuiCol_WindowBg, 0.8f));
520 if(ImGui::BeginChild(
"projects_content", ImVec2(content_width, ImGui::GetContentRegionAvail().
y - 24), ImGuiChildFlags_Borders, flags))
522 const auto& recent_projects = pm.get_editor_settings().projects.recent_projects;
524 if(recent_projects.empty())
527 ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 60);
530 float center_x = (ImGui::GetContentRegionAvail().x - 200) * 0.5f;
531 ImGui::SetCursorPosX(ImGui::GetCursorPosX() + center_x);
534 ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_TextDisabled));
535 ImGui::Text(
"No recent projects found");
536 ImGui::PopStyleColor();
539 ImGui::SetCursorPosX(ImGui::GetCursorPosX() + center_x - 30);
540 ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_TextDisabled, 0.7f));
541 ImGui::Text(
"Create a new project or browse for an existing one");
542 ImGui::PopStyleColor();
548 for(
size_t i = 0;
i < recent_projects.size(); ++
i)
550 const auto& prj = recent_projects[
i];
551 auto p = fs::path(prj);
555 auto ftime = fs::last_write_time(p /
"settings" /
"settings.cfg", ec);
556 auto system_time = std::chrono::time_point_cast<std::chrono::system_clock::duration>(
557 ftime - fs::file_time_type::clock::now() + std::chrono::system_clock::now());
559 auto name =
p.stem().string();
560 auto dir =
p.parent_path().string();
563 bool is_selected = (selected_project_ == prj.string());
566 bool is_hovered = draw_project_card(
567 fmt::format(
"project_card_{}", i),
580 if(ImGui::IsMouseClicked(0))
582 selected_project_ = prj.string();
586 if(ImGui::IsMouseDoubleClicked(0))
588 on_open_project(prj.string());
592 if(ImGui::IsMouseClicked(1))
594 selected_project_ = prj.string();
595 ImGui::OpenPopup(fmt::format(
"project_context_menu_{}", i).c_str());
600 if(ImGui::BeginPopup(fmt::format(
"project_context_menu_{}", i).c_str()))
603 ImGui::Text(
"%s",
name.c_str());
607 if(ImGui::MenuItem(
"Open Project"))
609 on_open_project(prj.string());
614 if(ImGui::MenuItem(
"Remove from Recents"))
616 auto& recent_projects = pm.get_editor_settings().projects.recent_projects;
617 auto it = std::find(recent_projects.begin(), recent_projects.end(), fs::path(prj.string()));
618 if(it != recent_projects.end())
620 recent_projects.erase(it);
621 pm.save_editor_settings();
622 if(selected_project_ == prj.string())
624 selected_project_.clear();
629 if(ImGui::MenuItem(
"Delete Project Folder"))
632 auto& recent_projects = pm.get_editor_settings().projects.recent_projects;
633 auto it = std::find(recent_projects.begin(), recent_projects.end(), fs::path(prj.string()));
634 if(it != recent_projects.end())
636 recent_projects.erase(it);
637 pm.save_editor_settings();
638 if(selected_project_ == prj.string())
640 selected_project_.clear();
652 ImGui::PopStyleVar(3);
653 ImGui::PopStyleColor();
657 ImGui::SameLine(0, content_spacing);
663 ImGui::Text(
"Actions");
669 ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 6.0f);
670 ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_ButtonActive, 0.9f));
671 ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetColorU32(ImGuiCol_ButtonActive, 1.1f));
672 ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetColorU32(ImGuiCol_ButtonActive, 1.2f));
675 if(ImGui::Button(
"New Project", ImVec2(sidebar_width, 45)))
677 current_view_ = view_state::new_project_creator;
679 project_directory_ =
"";
683 ImGui::PopStyleColor(3);
688 bool has_selection = !selected_project_.empty();
691 ImGui::BeginDisabled();
694 if(ImGui::Button(
"Open Selected", ImVec2(sidebar_width, 35)))
698 on_open_project(selected_project_);
704 ImGui::EndDisabled();
709 auto project_name = fs::path(selected_project_).stem().string();
710 ImGui::SetItemTooltipEx(
"Open: %s", project_name.c_str());
716 if(ImGui::Button(
"Browse for Project", ImVec2(sidebar_width, 35)))
719 if(native::pick_folder_dialog(path))
721 on_open_project(path);
730 ImGui::BeginDisabled();
733 if(ImGui::Button(
"Remove Selected", ImVec2(sidebar_width, 35)))
737 project_to_remove_ = selected_project_;
738 current_view_ = view_state::project_remover;
744 ImGui::EndDisabled();
749 auto project_name = fs::path(selected_project_).stem().string();
750 ImGui::SetItemTooltipEx(
"Remove: %s", project_name.c_str());
753 ImGui::PopStyleVar();
759 ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_TextDisabled, 0.8f));
761 ImGui::TextWrapped(
"Click to select, double-click to open, or right-click for options.");
763 ImGui::PopStyleColor();
772 auto on_create_project = [&](
const std::string&
p)
774 auto path = fs::path(p).make_preferred();
775 pm.create_project(ctx, path);
782 ImGui::Text(
"Create New Project");
785 ImGui::SameLine(ImGui::GetContentRegionAvail().
x - 80);
786 if(ImGui::Button(
"Back", ImVec2(80, 0)))
788 current_view_ = view_state::projects_list;
789 project_name_.clear();
790 project_directory_.clear();
800 float form_width = 600.0f;
801 float center_offset = (ImGui::GetContentRegionAvail().x - form_width) * 0.5f;
802 if(center_offset > 0)
804 ImGui::SetCursorPosX(ImGui::GetCursorPosX() + center_offset);
811 ImGui::Text(
"Project Name");
815 ImGui::SetNextItemWidth(form_width);
816 ImGui::InputTextWidget(
"##project_name", project_name_,
false);
818 if(project_name_.empty())
820 ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_TextDisabled));
821 ImGui::Text(
"Enter a name for your project");
822 ImGui::PopStyleColor();
831 ImGui::Text(
"Project Location");
837 float button_width = 40.0f;
838 float input_width = form_width - button_width - ImGui::GetStyle().ItemSpacing.x;
840 ImGui::SetNextItemWidth(input_width);
841 ImGui::InputTextWidget(
"##project_directory", project_directory_,
false);
846 std::string picked_dir;
847 if(native::pick_folder_dialog(picked_dir))
849 project_directory_ = picked_dir;
852 ImGui::SetItemTooltipEx(
"Browse for folder...");
858 if(project_directory_.empty())
860 ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_TextDisabled));
861 float text_width = ImGui::CalcTextSize(
"Choose where to create your project").x;
862 float available_width = ImGui::GetContentRegionAvail().x;
863 ImGui::AlignedItem(0.5f, available_width, text_width, [&]() {
864 ImGui::Text(
"Choose where to create your project");
866 ImGui::PopStyleColor();
870 ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_TextDisabled));
871 std::string text = fmt::format(
"Project will be created at: {}", (fs::path(project_directory_) / project_name_).
string());
872 float text_width = ImGui::CalcTextSize(text.c_str()).x;
873 float available_width = ImGui::GetContentRegionAvail().x;
874 ImGui::AlignedItem(0.5f, available_width, text_width, [&]() {
875 ImGui::Text(
"%s", text.c_str());
877 ImGui::PopStyleColor();
886 bool can_create = !project_name_.empty() && !project_directory_.empty();
889 float button_width = 120.0f;
890 float buttons_total_width = button_width * 2 + ImGui::GetStyle().ItemSpacing.x;
891 float button_center_offset = (form_width - buttons_total_width) * 0.5f;
895 ImGui::AlignedItem(0.5f,
896 ImGui::GetContentRegionAvail().
x,
905 ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_ButtonActive));
906 ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetColorU32(ImGuiCol_ButtonActive, 1.2f));
910 ImGui::BeginDisabled();
913 if(ImGui::Button(
"Create Project", ImVec2(button_width, 35)))
917 auto project_path = fs::path(project_directory_) / project_name_;
918 on_create_project(project_path.string());
919 ImGui::CloseCurrentPopup();
920 current_view_ = view_state::projects_list;
921 project_name_.clear();
922 project_directory_.clear();
928 ImGui::PopStyleColor(2);
932 ImGui::EndDisabled();
937 if(ImGui::Button(
"Cancel", ImVec2(button_width, 35)))
939 current_view_ = view_state::projects_list;
940 project_name_.clear();
941 project_directory_.clear();
958 ImGui::Text(
"Remove Project");
961 ImGui::SameLine(ImGui::GetContentRegionAvail().
x - 80);
962 if(ImGui::Button(
"Back", ImVec2(80, 0)))
964 current_view_ = view_state::projects_list;
965 project_to_remove_.clear();
975 float form_width = ImGui::GetContentRegionAvail().x * 0.8f;
976 float center_offset = (ImGui::GetContentRegionAvail().x - form_width) * 0.5f;
977 if(center_offset > 0)
979 ImGui::SetCursorPosX(ImGui::GetCursorPosX() + center_offset);
985 if(project_to_remove_.empty())
988 ImGui::Text(
"Select Project to Remove");
993 const auto& recent_projects = pm.get_editor_settings().projects.recent_projects;
994 if(!recent_projects.empty())
996 static int selected_project = 0;
999 std::vector<std::string> project_names;
1000 for(
const auto& prj : recent_projects)
1002 auto p = fs::path(prj);
1003 project_names.push_back(
p.stem().string());
1006 ImGui::SetNextItemWidth(form_width);
1007 if(ImGui::BeginCombo(
"##project_select", project_names[selected_project].c_str()))
1009 for(
int i = 0;
i < project_names.size(); ++
i)
1011 bool is_selected = (selected_project ==
i);
1012 if(ImGui::Selectable(project_names[i].c_str(), is_selected))
1014 selected_project =
i;
1015 project_to_remove_ = recent_projects[
i].string();
1019 ImGui::SetItemDefaultFocus();
1025 if(selected_project >= 0 && selected_project < recent_projects.size())
1027 project_to_remove_ = recent_projects[selected_project].string();
1037 if(!project_to_remove_.empty())
1039 auto project_path = fs::path(project_to_remove_);
1040 auto project_name = project_path.stem().string();
1041 auto project_dir = project_path.parent_path().string();
1045 auto ftime = fs::last_write_time(project_path /
"settings" /
"settings.cfg", ec);
1046 auto system_time = std::chrono::time_point_cast<std::chrono::system_clock::duration>(
1047 ftime - fs::file_time_type::clock::now() + std::chrono::system_clock::now());
1050 ImGui::Text(
"Project Information");
1056 "project_card_removal",
1071 ImGui::Text(
"Choose Removal Action");
1075 ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_TextDisabled, 0.9f));
1076 ImGui::TextWrapped(
"Select how you want to remove this project from your workspace:");
1077 ImGui::PopStyleColor();
1084 float button_spacing = 15.0f;
1085 float total_spacing = button_spacing * 2;
1086 float button_width = (form_width - total_spacing) / 3.0f;
1087 float button_height = 55.0f;
1090 ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 8.0f);
1091 ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_ButtonActive, 0.8f));
1092 ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetColorU32(ImGuiCol_ButtonActive, 1.0f));
1093 ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetColorU32(ImGuiCol_ButtonActive, 1.2f));
1096 if(ImGui::Button(
"Remove from Recents", ImVec2(button_width, button_height)))
1098 auto& recent_projects = pm.get_editor_settings().projects.recent_projects;
1099 auto it = std::find(recent_projects.begin(), recent_projects.end(), fs::path(project_to_remove_));
1100 if(it != recent_projects.end())
1102 recent_projects.erase(it);
1103 pm.save_editor_settings();
1105 current_view_ = view_state::projects_list;
1106 project_to_remove_.clear();
1110 ImGui::PopStyleColor(3);
1112 ImGui::SetItemTooltipEx(
"Remove from recent projects list\n(Project folder remains untouched)");
1115 ImGui::SameLine(0, button_spacing);
1118 ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(180, 60, 60, 255));
1119 ImGui::PushStyleColor(ImGuiCol_ButtonHovered, IM_COL32(220, 80, 80, 255));
1120 ImGui::PushStyleColor(ImGuiCol_ButtonActive, IM_COL32(255, 100, 100, 255));
1123 if(ImGui::Button(
"Delete Folder", ImVec2(button_width, button_height)))
1126 auto& recent_projects = pm.get_editor_settings().projects.recent_projects;
1127 auto it = std::find(recent_projects.begin(), recent_projects.end(), fs::path(project_to_remove_));
1128 if(it != recent_projects.end())
1130 recent_projects.erase(it);
1131 pm.save_editor_settings();
1134 fs::remove_all(project_to_remove_);
1136 current_view_ = view_state::projects_list;
1137 project_to_remove_.clear();
1141 ImGui::PopStyleColor(3);
1143 ImGui::SetItemTooltipEx(
"DANGER: Permanently delete the entire\nproject folder and all its contents");
1146 ImGui::SameLine(0, button_spacing);
1149 if(ImGui::Button(
"Cancel", ImVec2(button_width, button_height)))
1151 current_view_ = view_state::projects_list;
1152 project_to_remove_.clear();
1155 ImGui::PopStyleVar();
1157 ImGui::SetItemTooltipEx(
"Return to projects list without making changes");
1164 ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_TextDisabled, 0.7f));
1166 ImGui::TextWrapped(
"Tip: 'Remove from Recents' is the safer option if you want to keep the project files.");
1168 ImGui::PopStyleColor();
void open_project_settings(rtti::context &ctx, const std::string &hint)
auto deinit(rtti::context &ctx) -> bool
auto init(rtti::context &ctx) -> bool
void set_external_drop_in_progress(bool in_progress)
void add_external_drop_file(const std::string &file)
void on_frame_ui_render(rtti::context &ctx)
auto get_project_settings_panel() -> project_settings_panel &
void on_frame_update(rtti::context &ctx, delta_t dt)
void on_frame_render(rtti::context &ctx, delta_t dt)
void on_frame_before_render(rtti::context &ctx, delta_t dt)
auto get_console_log_panel() -> console_log_panel &
void set_external_drop_position(ImVec2 pos)
std::chrono::duration< float > delta_t
#define ICON_MDI_CLOCK_OUTLINE
#define ICON_MDI_FOLDER_OPEN
#define APPLOG_TRACE(...)
void PushFont(Font::Enum _font)
void PopWindowFontScale()
void PushWindowFontScale(float scale)
static auto prompt_save_scene(rtti::context &ctx, const std::function< void()> &on_continue) -> bool
static auto interrupt() -> bool
hpp::event< void(rtti::context &, delta_t)> on_frame_ui_render