|
|
|
|
@ -94,28 +94,43 @@ void render_body_list_ui(SimulationState* sim, RenderState* render_state, UIStat
|
|
|
|
|
// Create list string for raygui (NULL-terminated)
|
|
|
|
|
// Include both bodies and spacecraft
|
|
|
|
|
int total_items = sim->body_count + sim->craft_count; |
|
|
|
|
int buffer_size = total_items * (64 + 3 + 1) + 1; // Extra space for "🚀 " prefix
|
|
|
|
|
char* list_text = (char*)malloc(buffer_size); |
|
|
|
|
if (!list_text) return; |
|
|
|
|
|
|
|
|
|
list_text[0] = '\0'; |
|
|
|
|
int offset = 0; |
|
|
|
|
int item_index = 0; |
|
|
|
|
|
|
|
|
|
// Add bodies to list
|
|
|
|
|
for (int i = 0; i < sim->body_count; i++) { |
|
|
|
|
if (item_index > 0) { |
|
|
|
|
offset += snprintf(list_text + offset, buffer_size - offset, ";"); |
|
|
|
|
|
|
|
|
|
// Check if buffer needs rebuilding
|
|
|
|
|
bool needs_rebuild = (ui_state->sim_version != sim->version) || (ui_state->body_list_buffer == NULL); |
|
|
|
|
|
|
|
|
|
if (needs_rebuild) { |
|
|
|
|
int buffer_size = total_items * (64 + 3 + 1) + 1; |
|
|
|
|
|
|
|
|
|
if (ui_state->body_list_buffer == NULL || ui_state->body_list_buffer_size < buffer_size) { |
|
|
|
|
if (ui_state->body_list_buffer != NULL) { |
|
|
|
|
free(ui_state->body_list_buffer); |
|
|
|
|
} |
|
|
|
|
ui_state->body_list_buffer = (char*)malloc(buffer_size); |
|
|
|
|
if (!ui_state->body_list_buffer) return; |
|
|
|
|
ui_state->body_list_buffer_size = buffer_size; |
|
|
|
|
} |
|
|
|
|
offset += snprintf(list_text + offset, buffer_size - offset, "%s", sim->bodies[i].name); |
|
|
|
|
item_index++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Add spacecraft to list with "🚀 " prefix
|
|
|
|
|
for (int i = 0; i < sim->craft_count; i++) { |
|
|
|
|
offset += snprintf(list_text + offset, buffer_size - offset, ";"); |
|
|
|
|
offset += snprintf(list_text + offset, buffer_size - offset, "🚀 %s", sim->spacecraft[i].name); |
|
|
|
|
item_index++; |
|
|
|
|
ui_state->body_list_buffer[0] = '\0'; |
|
|
|
|
int offset = 0; |
|
|
|
|
int item_index = 0; |
|
|
|
|
|
|
|
|
|
// Add bodies to list
|
|
|
|
|
for (int i = 0; i < sim->body_count; i++) { |
|
|
|
|
if (item_index > 0) { |
|
|
|
|
offset += snprintf(ui_state->body_list_buffer + offset, ui_state->body_list_buffer_size - offset, ";"); |
|
|
|
|
} |
|
|
|
|
offset += snprintf(ui_state->body_list_buffer + offset, ui_state->body_list_buffer_size - offset, "%s", sim->bodies[i].name); |
|
|
|
|
item_index++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Add spacecraft to list with "🚀 " prefix
|
|
|
|
|
for (int i = 0; i < sim->craft_count; i++) { |
|
|
|
|
offset += snprintf(ui_state->body_list_buffer + offset, ui_state->body_list_buffer_size - offset, ";"); |
|
|
|
|
offset += snprintf(ui_state->body_list_buffer + offset, ui_state->body_list_buffer_size - offset, "🚀 %s", sim->spacecraft[i].name); |
|
|
|
|
item_index++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ui_state->sim_version = sim->version; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Draw window (no close button - panels always shown)
|
|
|
|
|
@ -130,7 +145,7 @@ void render_body_list_ui(SimulationState* sim, RenderState* render_state, UIStat
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
int previous_active = ui_state->body_list_active; |
|
|
|
|
GuiListView(list_bounds, list_text, &ui_state->body_list_scroll, &ui_state->body_list_active); |
|
|
|
|
GuiListView(list_bounds, ui_state->body_list_buffer, &ui_state->body_list_scroll, &ui_state->body_list_active); |
|
|
|
|
|
|
|
|
|
// Check if an item was selected
|
|
|
|
|
if (ui_state->body_list_active >= 0 && ui_state->body_list_active != previous_active) { |
|
|
|
|
@ -150,8 +165,6 @@ void render_body_list_ui(SimulationState* sim, RenderState* render_state, UIStat
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
free(list_text); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Render body information UI panel
|
|
|
|
|
@ -381,25 +394,45 @@ void render_maneuver_list_ui(SimulationState* sim, RenderState* render_state, UI
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int buffer_size = craft_maneuver_count * (64 + 10 + 1) + 1; |
|
|
|
|
char* maneuver_list_text = (char*)malloc(buffer_size); |
|
|
|
|
if (!maneuver_list_text) return; |
|
|
|
|
|
|
|
|
|
maneuver_list_text[0] = '\0'; |
|
|
|
|
int offset = 0; |
|
|
|
|
int maneuver_indices[craft_maneuver_count]; |
|
|
|
|
int maneuver_index_count = 0; |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < sim->maneuver_count; i++) { |
|
|
|
|
if (sim->maneuvers[i].craft_index == ui_state->selected_craft_index) { |
|
|
|
|
maneuver_indices[maneuver_index_count++] = i; |
|
|
|
|
if (offset > 0) { |
|
|
|
|
offset += snprintf(maneuver_list_text + offset, buffer_size - offset, ";"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Check if buffer needs rebuilding
|
|
|
|
|
bool needs_rebuild = (ui_state->sim_version != sim->version) || (ui_state->maneuver_list_buffer == NULL); |
|
|
|
|
|
|
|
|
|
if (needs_rebuild) { |
|
|
|
|
int buffer_size = craft_maneuver_count * (64 + 10 + 1) + 1; |
|
|
|
|
|
|
|
|
|
if (ui_state->maneuver_list_buffer == NULL || ui_state->maneuver_list_buffer_size < buffer_size) { |
|
|
|
|
if (ui_state->maneuver_list_buffer != NULL) { |
|
|
|
|
free(ui_state->maneuver_list_buffer); |
|
|
|
|
} |
|
|
|
|
ui_state->maneuver_list_buffer = (char*)malloc(buffer_size); |
|
|
|
|
if (!ui_state->maneuver_list_buffer) return; |
|
|
|
|
ui_state->maneuver_list_buffer_size = buffer_size; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ui_state->maneuver_list_buffer[0] = '\0'; |
|
|
|
|
int offset = 0; |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < sim->maneuver_count; i++) { |
|
|
|
|
if (sim->maneuvers[i].craft_index == ui_state->selected_craft_index) { |
|
|
|
|
if (offset > 0) { |
|
|
|
|
offset += snprintf(ui_state->maneuver_list_buffer + offset, ui_state->maneuver_list_buffer_size - offset, ";"); |
|
|
|
|
} |
|
|
|
|
const char* status_char = sim->maneuvers[i].executed ? "[DONE]" : "[PENDING]"; |
|
|
|
|
offset += snprintf(ui_state->maneuver_list_buffer + offset, ui_state->maneuver_list_buffer_size - offset, "%s %s", |
|
|
|
|
status_char, sim->maneuvers[i].name); |
|
|
|
|
} |
|
|
|
|
const char* status_char = sim->maneuvers[i].executed ? "[DONE]" : "[PENDING]"; |
|
|
|
|
offset += snprintf(maneuver_list_text + offset, buffer_size - offset, "%s %s", |
|
|
|
|
status_char, sim->maneuvers[i].name); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ui_state->sim_version = sim->version; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Rectangle list_bounds = { |
|
|
|
|
@ -410,7 +443,7 @@ void render_maneuver_list_ui(SimulationState* sim, RenderState* render_state, UI
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
int previous_active = ui_state->maneuver_list_active; |
|
|
|
|
GuiListView(list_bounds, maneuver_list_text, &ui_state->maneuver_list_scroll, &ui_state->maneuver_list_active); |
|
|
|
|
GuiListView(list_bounds, ui_state->maneuver_list_buffer, &ui_state->maneuver_list_scroll, &ui_state->maneuver_list_active); |
|
|
|
|
|
|
|
|
|
if (ui_state->maneuver_list_active >= 0 && ui_state->maneuver_list_active != previous_active) { |
|
|
|
|
if (ui_state->maneuver_list_active >= 0 && ui_state->maneuver_list_active < maneuver_index_count) { |
|
|
|
|
@ -527,8 +560,6 @@ void render_maneuver_list_ui(SimulationState* sim, RenderState* render_state, UI
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
free(maneuver_list_text); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void render_maneuver_create_tab(SimulationState* sim, UIState* ui_state, int x, int y, int width, int height) { |
|
|
|
|
@ -713,6 +744,50 @@ void render_maneuver_hohmann_tab(SimulationState* sim, UIState* ui_state, int x,
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (ui_state->sim_version != sim->version) { |
|
|
|
|
int craft_buffer_size = sim->craft_count * 64 + 1; |
|
|
|
|
|
|
|
|
|
if (ui_state->craft_list_buffer == NULL || ui_state->craft_list_buffer_size < craft_buffer_size) { |
|
|
|
|
if (ui_state->craft_list_buffer != NULL) { |
|
|
|
|
free(ui_state->craft_list_buffer); |
|
|
|
|
} |
|
|
|
|
ui_state->craft_list_buffer = (char*)malloc(craft_buffer_size); |
|
|
|
|
if (!ui_state->craft_list_buffer) return; |
|
|
|
|
ui_state->craft_list_buffer_size = craft_buffer_size; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ui_state->craft_list_buffer[0] = '\0'; |
|
|
|
|
int offset = 0; |
|
|
|
|
for (int i = 0; i < sim->craft_count; i++) { |
|
|
|
|
if (i > 0) { |
|
|
|
|
offset += snprintf(ui_state->craft_list_buffer + offset, ui_state->craft_list_buffer_size - offset, ";"); |
|
|
|
|
} |
|
|
|
|
offset += snprintf(ui_state->craft_list_buffer + offset, ui_state->craft_list_buffer_size - offset, "%s", sim->spacecraft[i].name); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int body_buffer_size = sim->body_count * 64 + 1; |
|
|
|
|
|
|
|
|
|
if (ui_state->body_dropdown_buffer == NULL || ui_state->body_dropdown_buffer_size < body_buffer_size) { |
|
|
|
|
if (ui_state->body_dropdown_buffer != NULL) { |
|
|
|
|
free(ui_state->body_dropdown_buffer); |
|
|
|
|
} |
|
|
|
|
ui_state->body_dropdown_buffer = (char*)malloc(body_buffer_size); |
|
|
|
|
if (!ui_state->body_dropdown_buffer) return; |
|
|
|
|
ui_state->body_dropdown_buffer_size = body_buffer_size; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ui_state->body_dropdown_buffer[0] = '\0'; |
|
|
|
|
offset = 0; |
|
|
|
|
for (int i = 0; i < sim->body_count; i++) { |
|
|
|
|
if (i > 0) { |
|
|
|
|
offset += snprintf(ui_state->body_dropdown_buffer + offset, ui_state->body_dropdown_buffer_size - offset, ";"); |
|
|
|
|
} |
|
|
|
|
offset += snprintf(ui_state->body_dropdown_buffer + offset, ui_state->body_dropdown_buffer_size - offset, "%s", sim->bodies[i].name); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ui_state->sim_version = sim->version; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
GuiLabel({(float)x, (float)current_y, (float)width, 25}, "Calculate optimal Hohmann transfer between orbits"); |
|
|
|
|
current_y += 30; |
|
|
|
|
|
|
|
|
|
@ -721,25 +796,11 @@ void render_maneuver_hohmann_tab(SimulationState* sim, UIState* ui_state, int x,
|
|
|
|
|
|
|
|
|
|
if (sim->craft_count > 0) { |
|
|
|
|
static bool edit_mode_spacecraft = false; |
|
|
|
|
int craft_buffer_size = sim->craft_count * 64 + 1; |
|
|
|
|
char* craft_list = (char*)malloc(craft_buffer_size); |
|
|
|
|
if (craft_list) { |
|
|
|
|
craft_list[0] = '\0'; |
|
|
|
|
int offset = 0; |
|
|
|
|
for (int i = 0; i < sim->craft_count; i++) { |
|
|
|
|
if (i > 0) { |
|
|
|
|
offset += snprintf(craft_list + offset, craft_buffer_size - offset, ";"); |
|
|
|
|
} |
|
|
|
|
offset += snprintf(craft_list + offset, craft_buffer_size - offset, "%s", sim->spacecraft[i].name); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (GuiDropdownBox({(float)x + 120, (float)(current_y - 35), (float)(width - 130), 25}, |
|
|
|
|
craft_list, &ui_state->maneuver_dialog.craft_index, edit_mode_spacecraft)) { |
|
|
|
|
edit_mode_spacecraft = !edit_mode_spacecraft; |
|
|
|
|
} |
|
|
|
|
free(craft_list); |
|
|
|
|
if (edit_mode_spacecraft) return; |
|
|
|
|
if (GuiDropdownBox({(float)x + 120, (float)(current_y - 35), (float)(width - 130), 25}, |
|
|
|
|
ui_state->craft_list_buffer, &ui_state->maneuver_dialog.craft_index, edit_mode_spacecraft)) { |
|
|
|
|
edit_mode_spacecraft = !edit_mode_spacecraft; |
|
|
|
|
} |
|
|
|
|
if (edit_mode_spacecraft) return; |
|
|
|
|
} |
|
|
|
|
current_y += 35; |
|
|
|
|
|
|
|
|
|
@ -748,25 +809,11 @@ void render_maneuver_hohmann_tab(SimulationState* sim, UIState* ui_state, int x,
|
|
|
|
|
|
|
|
|
|
if (sim->body_count > 0) { |
|
|
|
|
static bool edit_mode_transfer_parent = false; |
|
|
|
|
int body_buffer_size = sim->body_count * 64 + 1; |
|
|
|
|
char* body_list = (char*)malloc(body_buffer_size); |
|
|
|
|
if (body_list) { |
|
|
|
|
body_list[0] = '\0'; |
|
|
|
|
int offset = 0; |
|
|
|
|
for (int i = 0; i < sim->body_count; i++) { |
|
|
|
|
if (i > 0) { |
|
|
|
|
offset += snprintf(body_list + offset, body_buffer_size - offset, ";"); |
|
|
|
|
} |
|
|
|
|
offset += snprintf(body_list + offset, body_buffer_size - offset, "%s", sim->bodies[i].name); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (GuiDropdownBox({(float)x + 120, (float)(current_y - 35), (float)(width - 130), 25}, |
|
|
|
|
body_list, &ui_state->maneuver_dialog.transfer_body_index, edit_mode_transfer_parent)) { |
|
|
|
|
edit_mode_transfer_parent = !edit_mode_transfer_parent; |
|
|
|
|
} |
|
|
|
|
free(body_list); |
|
|
|
|
if (edit_mode_transfer_parent) return; |
|
|
|
|
if (GuiDropdownBox({(float)x + 120, (float)(current_y - 35), (float)(width - 130), 25}, |
|
|
|
|
ui_state->body_dropdown_buffer, &ui_state->maneuver_dialog.transfer_body_index, edit_mode_transfer_parent)) { |
|
|
|
|
edit_mode_transfer_parent = !edit_mode_transfer_parent; |
|
|
|
|
} |
|
|
|
|
if (edit_mode_transfer_parent) return; |
|
|
|
|
} |
|
|
|
|
current_y += 35; |
|
|
|
|
|
|
|
|
|
@ -775,25 +822,11 @@ void render_maneuver_hohmann_tab(SimulationState* sim, UIState* ui_state, int x,
|
|
|
|
|
|
|
|
|
|
if (sim->body_count > 0) { |
|
|
|
|
static bool edit_mode_current_body = false; |
|
|
|
|
int body_buffer_size = sim->body_count * 64 + 1; |
|
|
|
|
char* body_list = (char*)malloc(body_buffer_size); |
|
|
|
|
if (body_list) { |
|
|
|
|
body_list[0] = '\0'; |
|
|
|
|
int offset = 0; |
|
|
|
|
for (int i = 0; i < sim->body_count; i++) { |
|
|
|
|
if (i > 0) { |
|
|
|
|
offset += snprintf(body_list + offset, body_buffer_size - offset, ";"); |
|
|
|
|
} |
|
|
|
|
offset += snprintf(body_list + offset, body_buffer_size - offset, "%s", sim->bodies[i].name); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (GuiDropdownBox({(float)x + 120, (float)(current_y - 35), (float)(width - 130), 25}, |
|
|
|
|
body_list, &ui_state->maneuver_dialog.current_body_index, edit_mode_current_body)) { |
|
|
|
|
edit_mode_current_body = !edit_mode_current_body; |
|
|
|
|
} |
|
|
|
|
free(body_list); |
|
|
|
|
if (edit_mode_current_body) return; |
|
|
|
|
if (GuiDropdownBox({(float)x + 120, (float)(current_y - 35), (float)(width - 130), 25}, |
|
|
|
|
ui_state->body_dropdown_buffer, &ui_state->maneuver_dialog.current_body_index, edit_mode_current_body)) { |
|
|
|
|
edit_mode_current_body = !edit_mode_current_body; |
|
|
|
|
} |
|
|
|
|
if (edit_mode_current_body) return; |
|
|
|
|
} |
|
|
|
|
current_y += 35; |
|
|
|
|
|
|
|
|
|
@ -802,25 +835,11 @@ void render_maneuver_hohmann_tab(SimulationState* sim, UIState* ui_state, int x,
|
|
|
|
|
|
|
|
|
|
if (sim->body_count > 0) { |
|
|
|
|
static bool edit_mode_target_body = false; |
|
|
|
|
int body_buffer_size = sim->body_count * 64 + 1; |
|
|
|
|
char* body_list = (char*)malloc(body_buffer_size); |
|
|
|
|
if (body_list) { |
|
|
|
|
body_list[0] = '\0'; |
|
|
|
|
int offset = 0; |
|
|
|
|
for (int i = 0; i < sim->body_count; i++) { |
|
|
|
|
if (i > 0) { |
|
|
|
|
offset += snprintf(body_list + offset, body_buffer_size - offset, ";"); |
|
|
|
|
} |
|
|
|
|
offset += snprintf(body_list + offset, body_buffer_size - offset, "%s", sim->bodies[i].name); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (GuiDropdownBox({(float)x + 120, (float)(current_y - 35), (float)(width - 130), 25}, |
|
|
|
|
body_list, &ui_state->maneuver_dialog.target_body_index, edit_mode_target_body)) { |
|
|
|
|
edit_mode_target_body = !edit_mode_target_body; |
|
|
|
|
} |
|
|
|
|
free(body_list); |
|
|
|
|
if (edit_mode_target_body) return; |
|
|
|
|
if (GuiDropdownBox({(float)x + 120, (float)(current_y - 35), (float)(width - 130), 25}, |
|
|
|
|
ui_state->body_dropdown_buffer, &ui_state->maneuver_dialog.target_body_index, edit_mode_target_body)) { |
|
|
|
|
edit_mode_target_body = !edit_mode_target_body; |
|
|
|
|
} |
|
|
|
|
if (edit_mode_target_body) return; |
|
|
|
|
} |
|
|
|
|
current_y += 35; |
|
|
|
|
|
|
|
|
|
@ -1409,3 +1428,41 @@ void delete_maneuver_from_dialog(SimulationState* sim, UIState* ui_state) {
|
|
|
|
|
ui_state->maneuver_dialog.open = false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ui_state_init_buffers(UIState* ui_state) { |
|
|
|
|
ui_state->sim_version = 0; |
|
|
|
|
ui_state->body_list_buffer_size = 0; |
|
|
|
|
ui_state->body_list_buffer = NULL; |
|
|
|
|
ui_state->craft_list_buffer_size = 0; |
|
|
|
|
ui_state->craft_list_buffer = NULL; |
|
|
|
|
ui_state->body_dropdown_buffer_size = 0; |
|
|
|
|
ui_state->body_dropdown_buffer = NULL; |
|
|
|
|
ui_state->maneuver_list_buffer_size = 0; |
|
|
|
|
ui_state->maneuver_list_buffer = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ui_state_free_buffers(UIState* ui_state) { |
|
|
|
|
if (ui_state->body_list_buffer != NULL) { |
|
|
|
|
free(ui_state->body_list_buffer); |
|
|
|
|
ui_state->body_list_buffer = NULL; |
|
|
|
|
} |
|
|
|
|
ui_state->body_list_buffer_size = 0; |
|
|
|
|
|
|
|
|
|
if (ui_state->craft_list_buffer != NULL) { |
|
|
|
|
free(ui_state->craft_list_buffer); |
|
|
|
|
ui_state->craft_list_buffer = NULL; |
|
|
|
|
} |
|
|
|
|
ui_state->craft_list_buffer_size = 0; |
|
|
|
|
|
|
|
|
|
if (ui_state->body_dropdown_buffer != NULL) { |
|
|
|
|
free(ui_state->body_dropdown_buffer); |
|
|
|
|
ui_state->body_dropdown_buffer = NULL; |
|
|
|
|
} |
|
|
|
|
ui_state->body_dropdown_buffer_size = 0; |
|
|
|
|
|
|
|
|
|
if (ui_state->maneuver_list_buffer != NULL) { |
|
|
|
|
free(ui_state->maneuver_list_buffer); |
|
|
|
|
ui_state->maneuver_list_buffer = NULL; |
|
|
|
|
} |
|
|
|
|
ui_state->maneuver_list_buffer_size = 0; |
|
|
|
|
} |
|
|
|
|
|