6#include "absl/strings/str_format.h"
12#include "imgui/imgui.h"
15#include "yaze_config.h"
23void CopyToBuffer(std::array<char, N>* buffer,
const std::string& value) {
25 const size_t length = std::min(value.size(), N - 1);
26 std::copy_n(value.data(), length, buffer->data());
32 return ImVec4(0.45f, 0.70f, 0.95f, 1.0f);
34 return ImVec4(0.35f, 0.80f, 0.45f, 1.0f);
36 return ImVec4(0.90f, 0.35f, 0.35f, 1.0f);
58 const char* fallback_icon) {
64 WorkflowColor(status.
state),
"%s %s",
65 WorkflowIcon(status.
state, fallback_icon),
67 if (!status.
detail.empty()) {
68 ImGui::TextWrapped(
"%s", status.
detail.c_str());
71 ImGui::TextWrapped(
"%s", status.
output_tail.c_str());
109 return absl::FailedPreconditionError(
"Project save callback unavailable");
120 ImGui::TextDisabled(tr(
"No project loaded"));
123 tr(
"Open a .yaze project file or create a new project to access "
124 "project management features."));
154 if (project_version.empty()) {
160 project_version.c_str());
161 if (ImGui::IsItemHovered()) {
162 ImGui::SetTooltip(tr(
"Project saved with v%s; running v%s"),
166 ImGui::Text(
"%s", project_version.c_str());
177 ImGui::BeginDisabled(!has_project_path);
178 const std::string project_path_label =
180 : std::string(
"(no project file)##project_path");
181 if (ImGui::Selectable(project_path_label.c_str(),
false,
182 ImGuiSelectableFlags_None,
183 ImVec2(ImGui::GetContentRegionAvail().x, 0)) &&
190 if (has_project_path && ImGui::IsItemHovered()) {
191 ImGui::SetTooltip(tr(
"Click to copy path"));
193 ImGui::EndDisabled();
199 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
200 if (ImGui::InputText(
"##project_name",
name_buffer_.data(),
208 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
217 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
231 ImGui::TextWrapped(tr(
232 "Primary data lives under the .yaze root. Click any path to copy it."));
236 if (!app_root.ok()) {
239 tr(
"Storage unavailable: %s"),
240 std::string(app_root.status().message()).c_str());
244 std::vector<std::pair<const char*, std::filesystem::path>> locations = {
246 {
"Projects", *app_root /
"projects"},
247 {
"Layouts", *app_root /
"layouts"},
248 {
"Workspaces", *app_root /
"workspaces"},
249 {
"Logs", *app_root /
"logs"},
250 {
"Agent", *app_root /
"agent"}};
253 if (temp_root.ok()) {
254 locations.emplace_back(
"Temp", *temp_root);
257 if (ImGui::BeginTable(
"##storage_locations", 2,
258 ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersInnerV |
259 ImGuiTableFlags_SizingStretchProp)) {
260 ImGui::TableSetupColumn(
"Location", ImGuiTableColumnFlags_WidthFixed,
262 ImGui::TableSetupColumn(
"Path", ImGuiTableColumnFlags_WidthStretch);
263 for (
const auto& entry : locations) {
264 ImGui::TableNextRow();
265 ImGui::TableNextColumn();
267 ImGui::TableNextColumn();
268 const std::string display_path =
270 ImGui::PushID(entry.first);
271 if (ImGui::Selectable(display_path.c_str(),
false,
272 ImGuiSelectableFlags_SpanAllColumns)) {
273 ImGui::SetClipboardText(display_path.c_str());
278 if (ImGui::IsItemHovered()) {
279 ImGui::SetTooltip(tr(
"Click to copy"));
298 tr(
"Not configured"));
302 size_t pos = filename.find_last_of(
"/\\");
303 if (pos != std::string::npos) {
304 filename = filename.substr(pos + 1);
306 ImGui::Text(
"%s", filename.c_str());
307 if (ImGui::IsItemHovered()) {
316 ImGui::Text(
"%s",
rom_->
title().c_str());
320 ImGui::Text(tr(
"%.2f MB"),
321 static_cast<float>(
rom_->
size()) / (1024 * 1024));
333 float button_width = (ImGui::GetContentRegionAvail().x - 8) / 2;
340 if (ImGui::IsItemHovered()) {
341 ImGui::SetTooltip(tr(
"Replace the ROM file for this project"));
346 if (ImGui::Button(
ICON_MD_REFRESH " Reload", ImVec2(button_width, 0))) {
351 if (ImGui::IsItemHovered()) {
352 ImGui::SetTooltip(tr(
"Reload ROM from disk"));
364 ImGui::TextDisabled(tr(
"Version manager not available"));
370 if (!git_initialized) {
372 tr(
"Git is not initialized for this project. Initialize Git to enable "
373 "version control and snapshots."));
377 ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
387 absl::StrFormat(
"Failed to initialize Git: %s", status.message()),
397 if (!current_hash.empty()) {
400 ImGui::Text(
"%s", current_hash.substr(0, 7).c_str());
406 ImGui::Text(tr(
"Create Snapshot:"));
407 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
408 ImGui::InputTextWithHint(
"##snapshot_msg",
"Snapshot message...",
412 ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
419 absl::StrFormat(
"Snapshot created: %s", result->commit_hash),
427 absl::StrFormat(
"Snapshot failed: %s", result.status().message()),
432 if (ImGui::IsItemHovered()) {
434 tr(
"Create a snapshot of your project (Git commit + ROM backup)"));
447 if (ImGui::CollapsingHeader(
ICON_MD_LIST " Recent Snapshots",
448 ImGuiTreeNodeFlags_DefaultOpen)) {
456 ImGui::TextDisabled(tr(
"No snapshots yet"));
460 size_t space_pos = entry.find(
' ');
462 space_pos != std::string::npos ? entry.substr(0, 7) : entry;
463 std::string message =
464 space_pos != std::string::npos ? entry.substr(space_pos + 1) :
"";
468 ImGui::TextWrapped(
"%s", message.c_str());
478 float button_width = ImGui::GetContentRegionAvail().x;
488 if (ImGui::Button(
ICON_MD_SAVE " Save Project", ImVec2(button_width, 0))) {
492 if (ImGui::Button(
ICON_MD_BUILD " Build Project", ImVec2(button_width, 0))) {
501 ImVec2(button_width, 0))) {
507 ImVec2(button_width, 0))) {
522 ImGui::BeginChild(
"##build_output_log", ImVec2(0, 140),
true,
523 ImGuiWindowFlags_HorizontalScrollbar);
525 if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) {
526 ImGui::SetScrollHereY(1.0f);
540 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - 32);
541 if (ImGui::InputText(
"##code_folder",
code_buffer_.data(),
552 if (ImGui::IsItemHovered()) {
553 ImGui::SetTooltip(tr(
"Browse for code folder"));
558 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - 32);
570 if (ImGui::IsItemHovered()) {
571 ImGui::SetTooltip(tr(
"Browse for assets folder"));
576 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
585 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
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
BuildProjectCallback build_project_callback_
absl::Status SaveProjectEdits()
std::string build_log_output_
char snapshot_message_[256]
SwapRomCallback swap_rom_callback_
void DrawProjectOverview()
std::array< char, 1024 > description_buffer_
SaveProjectCallback save_project_callback_
core::VersionManager * version_manager_
void ReloadProjectBuffers()
void DrawVersionControl()
RunProjectCallback run_project_callback_
std::array< char, 512 > code_buffer_
std::array< char, 256 > author_buffer_
void SetProject(project::YazeProject *project, bool dirty=false)
std::array< char, 256 > build_buffer_
ToastManager * toast_manager_
project::YazeProject * project_
ReloadRomCallback reload_rom_callback_
CancelBuildCallback cancel_build_callback_
std::array< char, 256 > name_buffer_
ProjectWorkflowStatus build_status_
std::array< char, 512 > assets_buffer_
void DrawStorageLocations()
ProjectWorkflowStatus run_status_
void DrawSnapshotHistory()
std::vector< std::string > history_cache_
BrowseFolderCallback browse_folder_callback_
std::array< char, 512 > script_buffer_
void Show(const std::string &message, ToastType type=ToastType::kInfo, float ttl_seconds=3.0f, std::string action_label={}, std::function< void()> on_action=nullptr)
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_PLAY_ARROW
#define ICON_MD_SWAP_HORIZ
#define ICON_MD_CHECK_CIRCLE
void DrawWorkflowCard(const ProjectWorkflowStatus &status, const char *fallback_icon)
void CopyToBuffer(std::array< char, N > *buffer, const std::string &value)
ImVec4 ConvertColorToImVec4(const Color &color)
void ColoredText(const char *text, const ImVec4 &color)
ImVec4 GetTextSecondaryVec4()
void ColoredTextF(const ImVec4 &color, const char *fmt,...)
ProjectWorkflowState state
Modern project structure with comprehensive settings consolidation.
std::string assets_folder