138 kTriforceGold = GetThemedColor(
"triforce_gold", kTriforceGoldFallback);
139 kHyruleGreen = GetThemedColor(
"hyrule_green", kHyruleGreenFallback);
140 kMasterSwordBlue = GetThemedColor(
"master_sword_blue", kMasterSwordBlueFallback);
141 kGanonPurple = GetThemedColor(
"ganon_purple", kGanonPurpleFallback);
142 kHeartRed = GetThemedColor(
"heart_red", kHeartRedFallback);
143 kSpiritOrange = GetThemedColor(
"spirit_orange", kSpiritOrangeFallback);
148 ImVec2 mouse_pos = ImGui::GetMousePos();
150 bool action_taken =
false;
153 ImGuiViewport* viewport = ImGui::GetMainViewport();
154 ImVec2 center = viewport->GetCenter();
155 ImVec2 viewport_size = viewport->Size;
157 float width = std::min(viewport_size.x * 0.8f, 1400.0f);
158 float height = std::min(viewport_size.y * 0.85f, 900.0f);
160 ImGui::SetNextWindowPos(center, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
161 ImGui::SetNextWindowSize(ImVec2(width, height), ImGuiCond_Always);
167 ImGui::SetNextWindowCollapsed(
false);
168 ImGui::SetNextWindowFocus();
172 ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoCollapse |
173 ImGuiWindowFlags_NoResize |
174 ImGuiWindowFlags_NoMove;
176 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 20));
178 if (ImGui::Begin(
"##WelcomeScreen", p_open, window_flags)) {
179 ImDrawList* bg_draw_list = ImGui::GetWindowDrawList();
180 ImVec2 window_pos = ImGui::GetWindowPos();
181 ImVec2 window_size = ImGui::GetWindowSize();
184 struct TriforceConfig {
188 float repel_distance;
191 TriforceConfig triforce_configs[] = {
192 {0.08f, 0.12f, 36.0f, 0.025f, 50.0f},
193 {0.92f, 0.15f, 34.0f, 0.022f, 50.0f},
194 {0.06f, 0.88f, 32.0f, 0.020f, 45.0f},
195 {0.94f, 0.85f, 34.0f, 0.023f, 50.0f},
196 {0.50f, 0.08f, 38.0f, 0.028f, 55.0f},
197 {0.50f, 0.92f, 32.0f, 0.020f, 45.0f},
203 float x = window_pos.x + window_size.x * triforce_configs[i].x_pct;
204 float y = window_pos.y + window_size.y * triforce_configs[i].y_pct;
214 float base_x = window_pos.x + window_size.x * triforce_configs[i].x_pct;
215 float base_y = window_pos.y + window_size.y * triforce_configs[i].y_pct;
219 float time_offset = i * 1.2f;
226 float float_x = std::sin(
animation_time_ * float_speed_x + time_offset) * float_amount_x;
227 float float_y = std::cos(
animation_time_ * float_speed_y + time_offset * 1.2f) * float_amount_y;
232 float dist = std::sqrt(dx * dx + dy * dy);
236 float repel_radius = 200.0f;
239 target_pos.x += float_x;
240 target_pos.y += float_y;
245 float dir_x = dx / dist;
246 float dir_y = dy / dist;
249 float normalized_dist = dist / repel_radius;
250 float repel_strength = (1.0f - normalized_dist * normalized_dist) * triforce_configs[i].repel_distance;
252 target_pos.x += dir_x * repel_strength;
253 target_pos.y += dir_y * repel_strength;
266 adjusted_size, adjusted_alpha, 0.0f);
272 static float spawn_accumulator = 0.0f;
283 float angle = (rand() % 360) * (
M_PI / 180.0f);
284 float speed = 20.0f + (rand() % 40);
295 spawn_accumulator -= 1.0f;
299 float dt = ImGui::GetIO().DeltaTime;
318 ImU32 particle_color = ImGui::GetColorU32(ImVec4(1.0f, 0.843f, 0.0f, alpha));
330 ImDrawList* draw_list = ImGui::GetWindowDrawList();
331 ImVec2 separator_start = ImGui::GetCursorScreenPos();
332 ImVec2 separator_end(separator_start.x + ImGui::GetContentRegionAvail().x, separator_start.y + 1);
333 ImVec4 gold_faded = kTriforceGold;
335 ImVec4 blue_faded = kMasterSwordBlue;
337 draw_list->AddRectFilledMultiColor(
338 separator_start, separator_end,
339 ImGui::GetColorU32(gold_faded),
340 ImGui::GetColorU32(blue_faded),
341 ImGui::GetColorU32(blue_faded),
342 ImGui::GetColorU32(gold_faded));
344 ImGui::Dummy(ImVec2(0, 10));
346 ImGui::BeginChild(
"WelcomeContent", ImVec2(0, -60),
false);
349 ImGui::BeginChild(
"LeftPanel", ImVec2(ImGui::GetContentRegionAvail().x * 0.3f, 0),
true,
350 ImGuiWindowFlags_NoScrollbar);
355 ImVec2 sep_start = ImGui::GetCursorScreenPos();
358 ImVec2(sep_start.x + ImGui::GetContentRegionAvail().x, sep_start.y),
359 ImGui::GetColorU32(ImVec4(kTriforceGold.x, kTriforceGold.y, kTriforceGold.z, 0.2f)),
362 ImGui::Dummy(ImVec2(0, 5));
369 ImGui::BeginChild(
"RightPanel", ImVec2(0, 0),
true);
374 sep_start = ImGui::GetCursorScreenPos();
377 ImVec2(sep_start.x + ImGui::GetContentRegionAvail().x, sep_start.y),
378 ImGui::GetColorU32(ImVec4(kMasterSwordBlue.x, kMasterSwordBlue.y, kMasterSwordBlue.z, 0.2f)),
381 ImGui::Dummy(ImVec2(0, 5));
388 ImVec2 footer_start = ImGui::GetCursorScreenPos();
389 ImVec2 footer_end(footer_start.x + ImGui::GetContentRegionAvail().x, footer_start.y + 1);
390 ImVec4 red_faded = kHeartRed;
392 ImVec4 green_faded = kHyruleGreen;
393 green_faded.w = 0.3f;
394 draw_list->AddRectFilledMultiColor(
395 footer_start, footer_end,
396 ImGui::GetColorU32(red_faded),
397 ImGui::GetColorU32(green_faded),
398 ImGui::GetColorU32(green_faded),
399 ImGui::GetColorU32(red_faded));
401 ImGui::Dummy(ImVec2(0, 5));
406 ImGui::PopStyleVar();
454 ImDrawList* draw_list = ImGui::GetWindowDrawList();
456 ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[2]);
460 auto windowWidth = ImGui::GetWindowSize().x;
461 auto textWidth = ImGui::CalcTextSize(title).x;
462 float xPos = (windowWidth - textWidth) * 0.5f;
464 ImGui::SetCursorPosX(xPos);
465 ImVec2 text_pos = ImGui::GetCursorScreenPos();
468 float glow_size = 30.0f;
469 ImU32 glow_color = ImGui::GetColorU32(ImVec4(kTriforceGold.x, kTriforceGold.y, kTriforceGold.z, 0.15f));
470 draw_list->AddCircleFilled(
471 ImVec2(text_pos.x + textWidth / 2, text_pos.y + 15),
477 ImGui::TextColored(kTriforceGold,
"%s", title);
481 const char* subtitle =
"Yet Another Zelda3 Editor";
482 textWidth = ImGui::CalcTextSize(subtitle).x;
483 ImGui::SetCursorPosX((windowWidth - textWidth) * 0.5f);
485 ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f),
"%s", subtitle);
489 ImVec2 left_tri_pos(xPos - 80, text_pos.y + 20);
490 ImVec2 right_tri_pos(xPos + textWidth + 50, text_pos.y + 20);
491 DrawTriforceBackground(draw_list, left_tri_pos, 20, 0.12f, 0.0f);
492 DrawTriforceBackground(draw_list, right_tri_pos, 20, 0.12f, 0.0f);
581 ImVec2 card_size(200, 95);
582 ImVec2 cursor_pos = ImGui::GetCursorScreenPos();
587 ImVec2 center(cursor_pos.x + card_size.x / 2, cursor_pos.y + card_size.y / 2);
588 cursor_pos.x = center.x - (card_size.x * scale) / 2;
589 cursor_pos.y = center.y - (card_size.y * scale) / 2;
590 card_size.x *= scale;
591 card_size.y *= scale;
595 ImDrawList* draw_list = ImGui::GetWindowDrawList();
598 ImU32 color_top = ImGui::GetColorU32(ImVec4(0.15f, 0.20f, 0.25f, 1.0f));
599 ImU32 color_bottom = ImGui::GetColorU32(ImVec4(0.10f, 0.15f, 0.20f, 1.0f));
600 draw_list->AddRectFilledMultiColor(
602 ImVec2(cursor_pos.x + card_size.x, cursor_pos.y + card_size.y),
603 color_top, color_top, color_bottom, color_bottom);
606 ImVec4 border_color_base = (index % 3 == 0) ? kHyruleGreen :
607 (index % 3 == 1) ? kMasterSwordBlue : kTriforceGold;
608 ImU32 border_color = ImGui::GetColorU32(
609 ImVec4(border_color_base.x, border_color_base.y, border_color_base.z, 0.5f));
611 draw_list->AddRect(cursor_pos,
612 ImVec2(cursor_pos.x + card_size.x, cursor_pos.y + card_size.y),
613 border_color, 6.0f, 0, 2.0f);
616 ImGui::SetCursorScreenPos(cursor_pos);
617 ImGui::InvisibleButton(absl::StrFormat(
"ProjectCard_%d", index).c_str(), card_size);
618 bool is_hovered = ImGui::IsItemHovered();
619 bool is_clicked = ImGui::IsItemClicked();
625 ImU32 hover_color = ImGui::GetColorU32(ImVec4(kTriforceGold.x, kTriforceGold.y, kTriforceGold.z, 0.15f));
626 draw_list->AddRectFilled(cursor_pos,
627 ImVec2(cursor_pos.x + card_size.x, cursor_pos.y + card_size.y),
632 ImVec2 content_pos(cursor_pos.x + 8, cursor_pos.y + 8);
635 ImVec2 icon_center(content_pos.x + 13, content_pos.y + 13);
636 ImU32 icon_bg = ImGui::GetColorU32(border_color_base);
637 draw_list->AddCircleFilled(icon_center, 15, icon_bg, 24);
641 ImGui::SetCursorScreenPos(ImVec2(icon_center.x - icon_size.x / 2, icon_center.y - icon_size.y / 2));
642 ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1, 1, 1, 1));
644 ImGui::PopStyleColor();
647 ImGui::SetCursorScreenPos(ImVec2(content_pos.x + 32, content_pos.y + 8));
648 ImGui::PushTextWrapPos(cursor_pos.x + card_size.x - 8);
649 ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[0]);
650 std::string short_name = project.
name;
651 if (short_name.length() > 22) {
652 short_name = short_name.substr(0, 19) +
"...";
654 ImGui::TextColored(kTriforceGold,
"%s", short_name.c_str());
656 ImGui::PopTextWrapPos();
659 ImGui::SetCursorScreenPos(ImVec2(content_pos.x + 4, content_pos.y + 35));
660 ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.65f, 0.65f, 0.65f, 1.0f));
662 ImGui::PopStyleColor();
665 ImGui::SetCursorScreenPos(ImVec2(content_pos.x + 4, content_pos.y + 58));
666 ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.4f, 0.4f, 0.4f, 1.0f));
667 std::string short_path = project.
filepath;
668 if (short_path.length() > 26) {
669 short_path =
"..." + short_path.substr(short_path.length() - 23);
672 ImGui::PopStyleColor();
676 ImGui::BeginTooltip();
677 ImGui::TextColored(kMasterSwordBlue,
ICON_MD_INFO " Project Details");
679 ImGui::Text(
"Name: %s", project.
name.c_str());
680 ImGui::Text(
"ROM: %s", project.
rom_title.c_str());
681 ImGui::Text(
"Path: %s", project.
filepath.c_str());
697 float content_width = ImGui::GetContentRegionAvail().x;
699 ImGui::SameLine(content_width - 25);
703 if (ImGui::IsItemHovered()) {
711 ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.18f, 0.15f, 0.22f, 0.4f));
712 ImGui::BeginChild(
"VisualSettingsCompact", ImVec2(0, 115),
true, ImGuiWindowFlags_NoScrollbar);
718 ImGui::SetNextItemWidth(-1);
722 ImGui::SetNextItemWidth(-1);
739 ImGui::PopStyleColor();
751 Template templates[] = {
753 {
ICON_MD_MAP,
"ZSCustomOverworld v3", kMasterSwordBlue},
756 for (
int i = 0; i < 2; ++i) {
761 ImGui::PushStyleColor(ImGuiCol_Header,
762 ImVec4(templates[i].color.x * 0.6f, templates[i].color.y * 0.6f,
763 templates[i].color.z * 0.6f, 0.6f));
766 if (ImGui::Selectable(absl::StrFormat(
"%s %s", templates[i].icon, templates[i].name).c_str(),
772 ImGui::PopStyleColor();
775 if (ImGui::IsItemHovered()) {
776 ImGui::SetTooltip(
ICON_MD_STAR " Start with a %s template", templates[i].name);
781 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(kSpiritOrange.x * 0.6f, kSpiritOrange.y * 0.6f, kSpiritOrange.z * 0.6f, 0.8f));
782 ImGui::PushStyleColor(ImGuiCol_ButtonHovered, kSpiritOrange);
783 ImGui::BeginDisabled(
true);
786 ImGui::EndDisabled();
787 ImGui::PopStyleColor(2);