3#include "absl/strings/str_format.h"
9#include "imgui/imgui.h"
12#include "yaze_config.h"
19 ImGui::TextDisabled(
"No project loaded");
22 "Open a .yaze project file or create a new project to access "
23 "project management features.");
52 if (project_version.empty()) {
58 project_version.c_str());
59 if (ImGui::IsItemHovered()) {
60 ImGui::SetTooltip(
"Project saved with v%s; running v%s",
64 ImGui::Text(
"%s", project_version.c_str());
75 ImGuiSelectableFlags_None,
76 ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
82 if (ImGui::IsItemHovered()) {
83 ImGui::SetTooltip(
"Click to copy path");
90 static char name_buffer[256] = {};
92 strncpy(name_buffer,
project_->
name.c_str(),
sizeof(name_buffer) - 1);
94 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
95 if (ImGui::InputText(
"##project_name", name_buffer,
sizeof(name_buffer))) {
102 static char author_buffer[256] = {};
105 sizeof(author_buffer) - 1);
107 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
108 if (ImGui::InputText(
"##author", author_buffer,
sizeof(author_buffer))) {
115 static char desc_buffer[1024] = {};
118 sizeof(desc_buffer) - 1);
120 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
121 if (ImGui::InputTextMultiline(
"##description", desc_buffer,
122 sizeof(desc_buffer), ImVec2(0, 60))) {
135 "Primary data lives under the .yaze root. Click any path to copy it.");
139 if (!app_root.ok()) {
142 "Storage unavailable: %s",
143 std::string(app_root.status().message()).c_str());
147 std::vector<std::pair<const char*, std::filesystem::path>> locations = {
149 {
"Projects", *app_root /
"projects"},
150 {
"Layouts", *app_root /
"layouts"},
151 {
"Workspaces", *app_root /
"workspaces"},
152 {
"Logs", *app_root /
"logs"},
153 {
"Agent", *app_root /
"agent"}};
156 if (temp_root.ok()) {
157 locations.emplace_back(
"Temp", *temp_root);
160 if (ImGui::BeginTable(
"##storage_locations", 2,
161 ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersInnerV |
162 ImGuiTableFlags_SizingStretchProp)) {
163 ImGui::TableSetupColumn(
"Location", ImGuiTableColumnFlags_WidthFixed,
165 ImGui::TableSetupColumn(
"Path", ImGuiTableColumnFlags_WidthStretch);
166 for (
const auto& entry : locations) {
167 ImGui::TableNextRow();
168 ImGui::TableNextColumn();
170 ImGui::TableNextColumn();
171 const std::string display_path =
173 ImGui::PushID(entry.first);
174 if (ImGui::Selectable(display_path.c_str(),
false,
175 ImGuiSelectableFlags_SpanAllColumns)) {
176 ImGui::SetClipboardText(display_path.c_str());
181 if (ImGui::IsItemHovered()) {
182 ImGui::SetTooltip(
"Click to copy");
205 size_t pos = filename.find_last_of(
"/\\");
206 if (pos != std::string::npos) {
207 filename = filename.substr(pos + 1);
209 ImGui::Text(
"%s", filename.c_str());
210 if (ImGui::IsItemHovered()) {
219 ImGui::Text(
"%s",
rom_->
title().c_str());
223 ImGui::Text(
"%.2f MB",
static_cast<float>(
rom_->
size()) / (1024 * 1024));
235 float button_width = (ImGui::GetContentRegionAvail().x - 8) / 2;
242 if (ImGui::IsItemHovered()) {
243 ImGui::SetTooltip(
"Replace the ROM file for this project");
248 if (ImGui::Button(
ICON_MD_REFRESH " Reload", ImVec2(button_width, 0))) {
253 if (ImGui::IsItemHovered()) {
254 ImGui::SetTooltip(
"Reload ROM from disk");
266 ImGui::TextDisabled(
"Version manager not available");
272 if (!git_initialized) {
274 "Git is not initialized for this project. Initialize Git to enable "
275 "version control and snapshots.");
279 ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
289 absl::StrFormat(
"Failed to initialize Git: %s", status.message()),
299 if (!current_hash.empty()) {
302 ImGui::Text(
"%s", current_hash.substr(0, 7).c_str());
308 ImGui::Text(
"Create Snapshot:");
309 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
310 ImGui::InputTextWithHint(
"##snapshot_msg",
"Snapshot message...",
314 ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
321 absl::StrFormat(
"Snapshot created: %s", result->commit_hash),
329 absl::StrFormat(
"Snapshot failed: %s", result.status().message()),
334 if (ImGui::IsItemHovered()) {
336 "Create a snapshot of your project (Git commit + ROM backup)");
349 if (ImGui::CollapsingHeader(
ICON_MD_LIST " Recent Snapshots",
350 ImGuiTreeNodeFlags_DefaultOpen)) {
358 ImGui::TextDisabled(
"No snapshots yet");
362 size_t space_pos = entry.find(
' ');
364 space_pos != std::string::npos ? entry.substr(0, 7) : entry;
365 std::string message =
366 space_pos != std::string::npos ? entry.substr(space_pos + 1) :
"";
370 ImGui::TextWrapped(
"%s", message.c_str());
380 float button_width = ImGui::GetContentRegionAvail().x;
390 if (ImGui::Button(
ICON_MD_SAVE " Save Project", ImVec2(button_width, 0))) {
401 static char code_buffer[512] = {};
404 sizeof(code_buffer) - 1);
406 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - 32);
407 if (ImGui::InputText(
"##code_folder", code_buffer,
sizeof(code_buffer))) {
417 if (ImGui::IsItemHovered()) {
418 ImGui::SetTooltip(
"Browse for code folder");
423 static char assets_buffer[512] = {};
426 sizeof(assets_buffer) - 1);
428 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - 32);
429 if (ImGui::InputText(
"##assets_folder", assets_buffer,
430 sizeof(assets_buffer))) {
440 if (ImGui::IsItemHovered()) {
441 ImGui::SetTooltip(
"Browse for assets folder");
446 static char build_buffer[256] = {};
449 sizeof(build_buffer) - 1);
451 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
452 if (ImGui::InputText(
"##build_target", build_buffer,
sizeof(build_buffer))) {
459 static char script_buffer[512] = {};
462 sizeof(script_buffer) - 1);
464 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
465 if (ImGui::InputText(
"##build_script", script_buffer,
466 sizeof(script_buffer))) {
std::vector< std::string > GetHistory(int limit=10) const
absl::Status InitializeGit()
std::string GetCurrentHash() const
absl::StatusOr< SnapshotResult > CreateSnapshot(const std::string &message)
bool IsGitInitialized() const
char snapshot_message_[256]
SwapRomCallback swap_rom_callback_
void DrawProjectOverview()
SaveProjectCallback save_project_callback_
core::VersionManager * version_manager_
void DrawVersionControl()
ToastManager * toast_manager_
project::YazeProject * project_
ReloadRomCallback reload_rom_callback_
void DrawStorageLocations()
void DrawSnapshotHistory()
std::vector< std::string > history_cache_
BrowseFolderCallback browse_folder_callback_
void Show(const std::string &message, ToastType type=ToastType::kInfo, float ttl_seconds=3.0f)
const Theme & GetCurrentTheme() const
static ThemeManager & Get()
#define YAZE_VERSION_STRING
#define ICON_MD_FOLDER_OPEN
#define ICON_MD_FOLDER_SPECIAL
#define ICON_MD_CAMERA_ALT
#define ICON_MD_SWAP_HORIZ
ImVec4 ConvertColorToImVec4(const Color &color)
void ColoredText(const char *text, const ImVec4 &color)
ImVec4 GetTextSecondaryVec4()
void ColoredTextF(const ImVec4 &color, const char *fmt,...)
std::string assets_folder