diff --git a/programs/src/installer/components.cpp b/programs/src/installer/components.cpp index 66e5a4a..7e47395 100644 --- a/programs/src/installer/components.cpp +++ b/programs/src/installer/components.cpp @@ -39,7 +39,7 @@ Component g_components[] = { { "sdk", "Montauk SDK", "Native development kit under 0:/sdk: headers, libc, libstdc++ and tools", -1, "sdk/include", {"sdk", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "gcc", "GNU C/C++ compiler (gcc, g++)", "Native GCC 14 with C and C++ support (needs binutils)", @@ -47,7 +47,7 @@ Component g_components[] = { {"sdk/bin/gcc.elf", "sdk/bin/g++.elf", "sdk/bin/cpp.elf", "sdk/libexec", "sdk/lib/gcc", nullptr}, true, CI_BINUTILS, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "binutils", "GNU binutils (as, ld, ar, ...)", "Assembler, linker and object file tools", @@ -58,82 +58,82 @@ Component g_components[] = { "sdk/bin/strings.elf", "sdk/bin/addr2line.elf", "sdk/bin/c++filt.elf", "sdk/bin/elfedit.elf", nullptr}, true, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "tcc", "Tiny C Compiler", "Lightweight single-pass C compiler (tcc) with its own headers", CI_SDK, "sdk/tcc", {"sdk/tcc", "os/tcc.elf", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "lua", "Lua 5.4", "Lua interpreter (lua) with static library and headers", CI_SDK, "sdk/lua", {"sdk/lua", "os/lua.elf", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "games", "Games & demos", "Games and graphics demos", -1, nullptr, {nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "doom", "DOOM", "id Software's DOOM on the doomgeneric engine", CI_GAMES, "apps/doom", {"apps/doom", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "2048", "2048", "Sliding tile puzzle game", CI_GAMES, "apps/2048", {"apps/2048", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "rpgdemo", "RPG demo", "Top-down RPG game engine demo", CI_GAMES, "apps/rpgdemo", {"apps/rpgdemo", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "mandelbrot", "Mandelbrot", "Fractal explorer", CI_GAMES, "apps/mandelbrot", {"apps/mandelbrot", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "office", "Office & productivity", "Document, spreadsheet and PDF applications", -1, nullptr, {nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "wordprocessor", "Word Processor", "Rich text documents with printing support", CI_OFFICE, "apps/wordprocessor", {"apps/wordprocessor", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "spreadsheet", "Spreadsheet", "Formula-based spreadsheet", CI_OFFICE, "apps/spreadsheet", {"apps/spreadsheet", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "pdfviewer", "PDF Viewer", "PDF document viewer", CI_OFFICE, "apps/pdfviewer", {"apps/pdfviewer", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "internet", "Internet apps", "Optional network applications", -1, nullptr, {nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "wikipedia", "Wikipedia", "Wikipedia reader (GUI app and wiki CLI)", CI_INTERNET, "apps/wikipedia", {"apps/wikipedia", "os/wiki.elf", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "weather", "Weather", "Weather forecast app", CI_INTERNET, "apps/weather", {"apps/weather", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "irc", "IRC client", "Command-line IRC client", CI_INTERNET, "os/irc.elf", {"os/irc.elf", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "printing", "Printing support", "Print spooler daemon (printd), printer setup app and print tools", @@ -141,17 +141,17 @@ Component g_components[] = { {"os/printd.elf", "os/printctl.elf", "os/printersapplet.lib", "apps/printers", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "httpd", "HTTP server (experimental)", "Experimental web server (httpd) with 0:/www content", -1, "os/httpd.elf", {"os/httpd.elf", "www", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, { "sdr", "SDR tools (experimental)", "RTL-SDR software defined radio demo (sdr CLI)", -1, "os/sdr.elf", {"os/sdr.elf", nullptr}, false, -1, - false, false, false, false, 0 }, + false, false, false, false, 0, 0 }, }; const int g_component_count = CI_COUNT; @@ -235,6 +235,7 @@ void components_init() { Component& c = g_components[i]; c.expanded = false; c.bytes = 0; + c.total_bytes = 0; c.base_present = c.probe ? rel_exists(c.probe) : false; c.present = c.base_present; c.checked = c.base_present; @@ -356,13 +357,14 @@ void components_compute_sizes() { c.bytes += du_walk(c.paths[p], i); } - // Pure groups display the sum of their children. - for (int i = 0; i < g_component_count; i++) { - if (!comp_is_group(i)) continue; - for (int j = 0; j < g_component_count; j++) - if (g_components[j].parent == i) - g_components[i].bytes += g_components[j].bytes; - } + // Each row shows its own payload plus everything nested under it, so a + // parent (SDK, or a pure group) is never displayed smaller than the + // children listed beneath it. `bytes` stays exclusive for selection sums. + for (int i = 0; i < g_component_count; i++) + g_components[i].total_bytes = g_components[i].bytes; + for (int i = 0; i < g_component_count; i++) + for (int p = g_components[i].parent; p >= 0; p = g_components[p].parent) + g_components[p].total_bytes += g_components[i].bytes; g_sizes_ready = true; } diff --git a/programs/src/installer/installer.h b/programs/src/installer/installer.h index e408d0d..8561898 100644 --- a/programs/src/installer/installer.h +++ b/programs/src/installer/installer.h @@ -112,6 +112,7 @@ struct Component { bool present; // this component (or a child) exists in the image bool base_present; // own probe exists (parents with own payload) uint64_t bytes; // exclusive payload size in the source image + uint64_t total_bytes; // bytes plus everything nested under this row }; extern Component g_components[]; diff --git a/programs/src/installer/render.cpp b/programs/src/installer/render.cpp index 503fa6d..1ed65bf 100644 --- a/programs/src/installer/render.cpp +++ b/programs/src/installer/render.cpp @@ -280,8 +280,8 @@ static void render_components(Canvas& c, const mtk::Theme& theme) { right[0] = '\0'; if (!comp.present) snprintf(right, sizeof(right), "not in image"); - else if (components_sizes_ready() && comp.bytes > 0) - format_bytes(right, sizeof(right), comp.bytes); + else if (components_sizes_ready() && comp.total_bytes > 0) + format_bytes(right, sizeof(right), comp.total_bytes); if (right[0]) { int rw = text_width(right);