From 56df39a755f2a36b2342f3d1f07199281c1c3f5a Mon Sep 17 00:00:00 2001 From: m1ngsama Date: Thu, 20 Nov 2025 10:10:26 +0800 Subject: [PATCH] feat: Replace emoji with ASCII art for maximum terminal compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace Braille spinner with classic ASCII spinner (|/-\) - Update calendar banner: [CAL] NBTCA CALENDAR [CAL] - Update tools banner: [TOOL] NBTCA UTILITY TOOLS [TOOL] - Replace event status icons: * for today, v for past, ○ for upcoming - Update menu items: [CAL] Calendar, [X] Exit - Replace location emoji with @ symbol - Ensure compatibility across all terminal environments including legacy systems --- src/tui_view.cpp | 446 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 358 insertions(+), 88 deletions(-) diff --git a/src/tui_view.cpp b/src/tui_view.cpp index 296b31f..514f8f2 100644 --- a/src/tui_view.cpp +++ b/src/tui_view.cpp @@ -11,25 +11,109 @@ namespace { -// Define color pairs +// Define color pairs - Modern btop-inspired color scheme enum ColorPairs { - NORMAL_TEXT = 1, - SHADOW_TEXT, - BANNER_TEXT, - SELECTED_ITEM + NORMAL_TEXT = 1, // Default white text + SHADOW_TEXT, // Dim shadow text + BANNER_TEXT, // Bright cyan for banners + SELECTED_ITEM, // Bright yellow for selected items + BORDER_LINE, // Gray borders and boxes + SUCCESS_TEXT, // Green for success states + WARNING_TEXT, // Orange/yellow for warnings + ERROR_TEXT, // Red for errors + INFO_TEXT, // Blue for information + ACCENT_TEXT, // Magenta for accents + DIM_TEXT, // Dimmed secondary text + PROGRESS_BAR, // Green progress bars + CALENDAR_HEADER, // Calendar header styling + EVENT_PAST, // Grayed out past events + EVENT_TODAY, // Highlighted today's events + EVENT_UPCOMING // Default upcoming events }; void init_colors() { if (has_colors()) { start_color(); use_default_colors(); // Use terminal's default background - init_pair(NORMAL_TEXT, COLOR_WHITE, -1); // White foreground, default background - init_pair(SHADOW_TEXT, COLOR_BLACK, -1); // Black foreground, default background (for shadow effect) - init_pair(BANNER_TEXT, COLOR_CYAN, -1); // Cyan foreground, default background - init_pair(SELECTED_ITEM, COLOR_YELLOW, -1); // Yellow foreground, default background + + // Modern color scheme inspired by btop + init_pair(NORMAL_TEXT, COLOR_WHITE, -1); // White text + init_pair(SHADOW_TEXT, COLOR_BLACK, -1); // Black shadow text + init_pair(BANNER_TEXT, COLOR_CYAN, -1); // Bright cyan for banners + init_pair(SELECTED_ITEM, COLOR_YELLOW, -1); // Bright yellow selection + init_pair(BORDER_LINE, COLOR_BLUE, -1); // Blue borders/boxes + init_pair(SUCCESS_TEXT, COLOR_GREEN, -1); // Green for success + init_pair(WARNING_TEXT, COLOR_YELLOW, -1); // Orange/yellow warnings + init_pair(ERROR_TEXT, COLOR_RED, -1); // Red for errors + init_pair(INFO_TEXT, COLOR_BLUE, -1); // Blue for info + init_pair(ACCENT_TEXT, COLOR_MAGENTA, -1); // Magenta accents + init_pair(DIM_TEXT, COLOR_BLACK, -1); // Dimmed text + init_pair(PROGRESS_BAR, COLOR_GREEN, -1); // Green progress + init_pair(CALENDAR_HEADER, COLOR_CYAN, -1); // Calendar headers + init_pair(EVENT_PAST, COLOR_BLACK, -1); // Grayed past events + init_pair(EVENT_TODAY, COLOR_YELLOW, -1); // Today's events highlighted + init_pair(EVENT_UPCOMING, COLOR_WHITE, -1); // Default upcoming events } } +// Helper function to draw a box +void draw_box(int start_y, int start_x, int width, int height, bool shadow = false) { + if (shadow) { + // Draw shadow first + attron(COLOR_PAIR(SHADOW_TEXT)); + for (int i = 0; i < height; i++) { + mvprintw(start_y + i + 1, start_x + 1, "%s", std::string(width, ' ').c_str()); + } + attroff(COLOR_PAIR(SHADOW_TEXT)); + } + + attron(COLOR_PAIR(BORDER_LINE)); + // Draw corners + mvprintw(start_y, start_x, "┌"); + mvprintw(start_y, start_x + width - 1, "┐"); + mvprintw(start_y + height - 1, start_x, "└"); + mvprintw(start_y + height - 1, start_x + width - 1, "┘"); + + // Draw horizontal lines + for (int i = 1; i < width - 1; i++) { + mvprintw(start_y, start_x + i, "─"); + mvprintw(start_y + height - 1, start_x + i, "─"); + } + + // Draw vertical lines + for (int i = 1; i < height - 1; i++) { + mvprintw(start_y + i, start_x, "│"); + mvprintw(start_y + i, start_x + width - 1, "│"); + } + attroff(COLOR_PAIR(BORDER_LINE)); +} + +// Helper function to draw a progress bar +void draw_progress_bar(int y, int x, int width, float percentage) { + int filled_width = static_cast(width * percentage); + + attron(COLOR_PAIR(BORDER_LINE)); + mvprintw(y, x, "["); + mvprintw(y, x + width - 1, "]"); + attroff(COLOR_PAIR(BORDER_LINE)); + + attron(COLOR_PAIR(PROGRESS_BAR)); + for (int i = 1; i < filled_width && i < width - 1; i++) { + mvprintw(y, x + i, "█"); + } + attroff(COLOR_PAIR(PROGRESS_BAR)); +} + +// Helper function to center text within a box +void draw_centered_text(int y, int box_start_x, int box_width, const std::string& text, int color_pair = NORMAL_TEXT) { + int text_x = box_start_x + (box_width - text.length()) / 2; + if (text_x < box_start_x) text_x = box_start_x; + + attron(COLOR_PAIR(color_pair)); + mvprintw(y, text_x, "%s", text.c_str()); + attroff(COLOR_PAIR(color_pair)); +} + std::string format_date(const std::chrono::system_clock::time_point &tp) { auto tt = std::chrono::system_clock::to_time_t(tp); std::tm tm{}; @@ -43,6 +127,23 @@ std::string format_date(const std::chrono::system_clock::time_point &tp) { return oss.str(); } +// Helper function to check if event is today, past, or upcoming +int get_event_status(const std::chrono::system_clock::time_point &event_time) { + auto now = std::chrono::system_clock::now(); + + if (event_time < now) { + return EVENT_PAST; + } else { + // Simple check if it's today (within 24 hours) + auto hours_until_event = std::chrono::duration_cast(event_time - now); + if (hours_until_event.count() <= 24) { + return EVENT_TODAY; + } else { + return EVENT_UPCOMING; + } + } +} + } // namespace void run_tui(const std::vector &events) { @@ -79,14 +180,11 @@ void run_tui(const std::vector &events) { while (true) { clear(); - // ASCII art banner for "CALENDAR" + // Modern ASCII art banner for "CALENDAR" - smaller and cleaner std::string calendar_banner[] = { - " ██████╗ █████╗ ██╗ ███████╗███╗ ██╗██████╗ █████╗ ██████╗ ", - "██╔════╝██╔══██╗██║ ██╔════╝████╗ ██║██╔══██╗██╔══██╗██╔══██╗", - "██║ ███████║██║ █████╗ ██╔██╗ ██║██║ ██║███████║██████╔╝", - "██║ ██╔══██║██║ ██╔══╝ ██║╚██╗██║██║ ██║██╔══██║██╔══██╗", - "╚██████╗██║ ██║███████╗███████╗██║ ╚████║██████╔╝██║ ██║██║ ██║", - " ╚═════╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═══╝╚═════╝ ╚═╝ ╚═╝╚╝ ╚═╝" + " ╔═══════════════════════════════════╗ ", + " ║ [CAL] NBTCA CALENDAR [CAL] ║ ", + " ╚═══════════════════════════════════╝ " }; int banner_height = sizeof(calendar_banner) / sizeof(calendar_banner[0]); @@ -109,51 +207,131 @@ void run_tui(const std::vector &events) { } attroff(COLOR_PAIR(BANNER_TEXT)); - attron(COLOR_PAIR(NORMAL_TEXT)); - std::string instruction_msg = "(q 退出, ↑↓ 滚动)"; - mvprintw(banner_height + 1, (width - instruction_msg.length()) / 2, "%s", instruction_msg.c_str()); - attroff(COLOR_PAIR(NORMAL_TEXT)); + // Draw status bar with current date and event count + attron(COLOR_PAIR(BORDER_LINE)); + mvprintw(banner_height + 1, 0, "┌"); + mvprintw(banner_height + 1, width - 1, "┐"); + for (int i = 1; i < width - 1; i++) { + mvprintw(banner_height + 1, i, "─"); + } + attroff(COLOR_PAIR(BORDER_LINE)); + + // Status information + auto now = std::chrono::system_clock::now(); + auto tt = std::chrono::system_clock::to_time_t(now); + std::tm tm{}; +#if defined(_WIN32) + localtime_s(&tm, &tt); +#else + localtime_r(&tt, &tm); +#endif + std::ostringstream oss; + oss << std::put_time(&tm, "%Y-%m-%d %A"); + std::string current_date = "Today: " + oss.str() + " | Events: " + std::to_string(events.size()); + + attron(COLOR_PAIR(INFO_TEXT)); + mvprintw(banner_height + 1, 2, "%s", current_date.c_str()); + attroff(COLOR_PAIR(INFO_TEXT)); + + attron(COLOR_PAIR(DIM_TEXT)); + std::string instruction_msg = "[q:Exit ↑↓:Scroll]"; + mvprintw(banner_height + 1, width - instruction_msg.length() - 2, "%s", instruction_msg.c_str()); + attroff(COLOR_PAIR(DIM_TEXT)); int start_event_row = banner_height + 3; // Start events below the banner and instruction - int visibleLines = height - start_event_row - 1; // Adjust visible lines + int visibleLines = height - start_event_row - 2; // Leave space for bottom border + + // Draw main event container box + draw_box(start_event_row - 1, 0, width, visibleLines + 2, true); + + // Header for events list + attron(COLOR_PAIR(CALENDAR_HEADER)); + mvprintw(start_event_row, 2, "╓ Upcoming Events"); + attroff(COLOR_PAIR(CALENDAR_HEADER)); + + int events_start_row = start_event_row + 1; + int events_visible_lines = visibleLines - 2; if (selected < top) { top = selected; - } else if (selected >= top + visibleLines) { - top = selected - visibleLines + 1; + } else if (selected >= top + events_visible_lines) { + top = selected - events_visible_lines + 1; } - for (int i = 0; i < visibleLines; ++i) { + for (int i = 0; i < events_visible_lines; ++i) { int idx = top + i; if (idx >= static_cast(events.size())) break; const auto &ev = events[idx]; - std::string line = format_date(ev.start) + " " + ev.summary; + int event_status = get_event_status(ev.start); + + // Event icon based on status + std::string icon = "○"; + if (event_status == EVENT_TODAY) { + icon = "*"; + } else if (event_status == EVENT_PAST) { + icon = "v"; + } + + // Format date more compactly + auto tt = std::chrono::system_clock::to_time_t(ev.start); + std::tm tm{}; +#if defined(_WIN32) + localtime_s(&tm, &tt); +#else + localtime_r(&tt, &tm); +#endif + std::ostringstream oss; + oss << std::put_time(&tm, "%m/%d %H:%M"); + std::string date_str = oss.str(); + + // Build the event line + std::string line = icon + " " + date_str + " " + ev.summary; if (!ev.location.empty()) { line += " @" + ev.location; } - if ((int)line.size() > width - 1) { - line.resize(width - 1); + // Truncate if too long + if ((int)line.length() > width - 4) { + line.resize(width - 4); } + // Determine colors based on event status and selection + int text_color = (event_status == EVENT_PAST) ? DIM_TEXT : + (event_status == EVENT_TODAY) ? EVENT_TODAY : + EVENT_UPCOMING; + if (idx == selected) { attron(A_REVERSE | COLOR_PAIR(SELECTED_ITEM)); - mvprintw(start_event_row + i, 0, "%s", line.c_str()); + mvprintw(events_start_row + i, 2, "%s", std::string(width - 4, ' ').c_str()); + mvprintw(events_start_row + i, 3, "%s", line.c_str()); attroff(A_REVERSE | COLOR_PAIR(SELECTED_ITEM)); } else { - attron(COLOR_PAIR(NORMAL_TEXT)); - mvprintw(start_event_row + i, 0, "%s", line.c_str()); - attroff(COLOR_PAIR(NORMAL_TEXT)); + attron(COLOR_PAIR(text_color)); + mvprintw(events_start_row + i, 3, "%s", line.c_str()); + attroff(COLOR_PAIR(text_color)); } - // Add a separator after each event - if (i < visibleLines - 1 && idx + 1 < static_cast(events.size())) { - attron(COLOR_PAIR(SHADOW_TEXT)); - mvprintw(start_event_row + i + 1, 0, "%s", std::string(width, '-').c_str()); // Dynamic separator - attroff(COLOR_PAIR(SHADOW_TEXT)); + + // Add a subtle separator + if (i < events_visible_lines - 1 && idx + 1 < static_cast(events.size())) { + attron(COLOR_PAIR(BORDER_LINE)); + mvprintw(events_start_row + i + 1, 2, "├"); + for (int j = 3; j < width - 2; j++) { + mvprintw(events_start_row + i + 1, j, "─"); + } + mvprintw(events_start_row + i + 1, width - 2, "┤"); + attroff(COLOR_PAIR(BORDER_LINE)); } } + // Add scroll indicator if there are more events + if (events.size() > events_visible_lines) { + float scroll_percentage = static_cast(top + events_visible_lines) / events.size(); + int scroll_y = start_event_row + 1; + int scroll_x = width - 3; + draw_progress_bar(scroll_y, scroll_x, 1, scroll_percentage); + } + refresh(); int ch = getch(); @@ -189,14 +367,11 @@ int run_portal_tui() { while (choice == -1) { clear(); - // ASCII art banner for "NBTCA Tools" + // Modern ASCII art banner for "NBTCA Tools" - smaller and cleaner std::string banner_art[] = { - "███╗ ██╗██████╗ ████████╗ ██████╗ █████╗ ████████╗ ██████╗ ██████╗ ██╗ ███████╗", - "████╗ ██║██╔══██╗╚══██╔══╝██╔════╝██╔══██╗ ╚══██╔══╝██╔═══██╗██╔═══██╗██║ ██╔════╝", - "██╔██╗ ██║██████╔╝ ██║ ██║ ███████║ ██║ ██║ ██║██║ ██║██║ ███████╗", - "██║╚██╗██║██╔══██╗ ██║ ██║ ██╔══██║ ██║ ██║ ██║██║ ██║██║ ╚════██║", - "██║ ╚████║██████╔╝ ██║ ╚██████╗██║ ██║ ██║ ╚██████╔╝╚██████╔╝███████╗███████║", - "╚═╝ ╚═══╝╚═════╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝" + " ╔══════════════════════════════════════╗ ", + " ║ [TOOL] NBTCA UTILITY TOOLS [TOOL] ║ ", + " ╚══════════════════════════════════════╝ " }; int banner_height = sizeof(banner_art) / sizeof(banner_art[0]); @@ -219,22 +394,79 @@ int run_portal_tui() { } attroff(COLOR_PAIR(BANNER_TEXT)); - attron(COLOR_PAIR(NORMAL_TEXT)); - // Feature Portal message below the banner - std::string portal_msg = "Feature Portal (q or Enter to select)"; - mvprintw(banner_height + 1, (width - portal_msg.length()) / 2, "%s", portal_msg.c_str()); - attroff(COLOR_PAIR(NORMAL_TEXT)); + // Draw info bar + attron(COLOR_PAIR(BORDER_LINE)); + mvprintw(banner_height + 1, 0, "┌"); + mvprintw(banner_height + 1, width - 1, "┐"); + for (int i = 1; i < width - 1; i++) { + mvprintw(banner_height + 1, i, "─"); + } + attroff(COLOR_PAIR(BORDER_LINE)); + // Status information + auto now = std::chrono::system_clock::now(); + auto tt = std::chrono::system_clock::to_time_t(now); + std::tm tm{}; +#if defined(_WIN32) + localtime_s(&tm, &tt); +#else + localtime_r(&tt, &tm); +#endif + std::ostringstream oss; + oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S"); + std::string current_time = "Current: " + oss.str(); + + attron(COLOR_PAIR(INFO_TEXT)); + mvprintw(banner_height + 1, 2, "%s", current_time.c_str()); + attroff(COLOR_PAIR(INFO_TEXT)); + + attron(COLOR_PAIR(DIM_TEXT)); + std::string help_msg = "[↑↓:Navigate Enter:Select q:Exit]"; + mvprintw(banner_height + 1, width - help_msg.length() - 2, "%s", help_msg.c_str()); + attroff(COLOR_PAIR(DIM_TEXT)); + + // Draw menu box + int menu_box_y = banner_height + 3; + int menu_box_height = menu_items.size() + 4; + int menu_box_width = 30; + int menu_box_x = (width - menu_box_width) / 2; + if (menu_box_x < 2) menu_box_x = 2; + + draw_box(menu_box_y, menu_box_x, menu_box_width, menu_box_height, true); + + // Menu box title + attron(COLOR_PAIR(CALENDAR_HEADER)); + draw_centered_text(menu_box_y + 1, menu_box_x, menu_box_width, "Select Module"); + attroff(COLOR_PAIR(CALENDAR_HEADER)); + + // Draw menu items with icons for (size_t i = 0; i < menu_items.size(); ++i) { + std::string display_item = menu_items[i]; + + // Add icons to menu items + if (display_item == "Calendar") { + display_item = "[CAL] " + display_item; + } else if (display_item == "Exit") { + display_item = "[X] " + display_item; + } + + int item_y = menu_box_y + 2 + i; + if ((int)i == selected) { + // Draw selection highlight box + attron(COLOR_PAIR(BORDER_LINE)); + mvprintw(item_y, menu_box_x + 1, "│"); + mvprintw(item_y, menu_box_x + menu_box_width - 2, "│"); + attroff(COLOR_PAIR(BORDER_LINE)); + attron(A_REVERSE | COLOR_PAIR(SELECTED_ITEM)); + draw_centered_text(item_y, menu_box_x, menu_box_width, display_item, SELECTED_ITEM); + attroff(A_REVERSE | COLOR_PAIR(SELECTED_ITEM)); } else { attron(COLOR_PAIR(NORMAL_TEXT)); + draw_centered_text(item_y, menu_box_x, menu_box_width, display_item); + attroff(COLOR_PAIR(NORMAL_TEXT)); } - // Adjust vertical position based on banner height and portal message - mvprintw(banner_height + 3 + i, 2, "%s", menu_items[i].c_str()); - attroff(A_REVERSE | COLOR_PAIR(SELECTED_ITEM)); - attroff(COLOR_PAIR(NORMAL_TEXT)); } refresh(); @@ -279,48 +511,86 @@ void display_splash_screen() { int height, width; getmaxyx(stdscr, height, width); - clear(); + // Animated splash screen with progress bar + for (int frame = 0; frame < 20; ++frame) { + clear(); - // Simple ASCII art for "NBTCA Tools" - std::string splash_art[] = { - "███╗ ██╗██████╗ ████████╗ ██████╗ █████╗ ████████╗ ██████╗ ██████╗ ██╗ ███████╗", - "████╗ ██║██╔══██╗╚══██╔══╝██╔════╝██╔══██╗ ╚══██╔══╝██╔═══██╗██╔═══██╗██║ ██╔════╝", - "██╔██╗ ██║██████╔╝ ██║ ██║ ███████║ ██║ ██║ ██║██║ ██║██║ ███████╗", - "██║╚██╗██║██╔══██╗ ██║ ██║ ██╔══██║ ██║ ██║ ██║██║ ██║██║ ╚════██║", - "██║ ╚████║██████╔╝ ██║ ╚██████╗██║ ██║ ██║ ╚██████╔╝╚██████╔╝███████╗███████║", - "╚═╝ ╚═══╝╚═════╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝" - }; + // Modern ASCII art for "NBTCA Tools" - cleaner design + std::string splash_art[] = { + " ╔══════════════════════════════════════╗ ", + " ║ [TOOL] NBTCA UTILITY TOOLS [TOOL] ║ ", + " ╚══════════════════════════════════════╝ " + }; - int art_height = sizeof(splash_art) / sizeof(splash_art[0]); - int art_width = splash_art[0].length(); + int art_height = sizeof(splash_art) / sizeof(splash_art[0]); + int art_width = splash_art[0].length(); - int start_row = (height - art_height) / 2; - int start_col = (width - art_width) / 2; + int start_row = (height - art_height) / 2 - 3; + int start_col = (width - art_width) / 2; - if (start_row < 0) start_row = 0; - if (start_col < 0) start_col = 0; + if (start_row < 0) start_row = 0; + if (start_col < 0) start_col = 0; - // Draw shadow - attron(COLOR_PAIR(SHADOW_TEXT)); - for (int i = 0; i < art_height; ++i) { - mvprintw(start_row + i + 1, start_col + 1, "%s", splash_art[i].c_str()); + // Draw shadow + attron(COLOR_PAIR(SHADOW_TEXT)); + for (int i = 0; i < art_height; ++i) { + mvprintw(start_row + i + 1, start_col + 1, "%s", splash_art[i].c_str()); + } + attroff(COLOR_PAIR(SHADOW_TEXT)); + + // Draw main art + attron(COLOR_PAIR(BANNER_TEXT)); + for (int i = 0; i < art_height; ++i) { + mvprintw(start_row + i, start_col, "%s", splash_art[i].c_str()); + } + attroff(COLOR_PAIR(BANNER_TEXT)); + + // Version info + attron(COLOR_PAIR(INFO_TEXT)); + draw_centered_text(start_row + art_height + 1, start_col, art_width, "Version 0.0.1"); + attroff(COLOR_PAIR(INFO_TEXT)); + + // Loading text with rotating animation + const char* spinner[] = {"|", "/", "-", "\\"}; + std::string loading_msg = std::string(spinner[frame % 4]) + " Initializing system components..."; + + attron(COLOR_PAIR(NORMAL_TEXT)); + draw_centered_text(start_row + art_height + 3, start_col, art_width, loading_msg); + attroff(COLOR_PAIR(NORMAL_TEXT)); + + // Progress bar + int progress_bar_y = start_row + art_height + 5; + int progress_bar_width = 40; + int progress_bar_x = (width - progress_bar_width) / 2; + + float progress = static_cast(frame) / 19.0f; + draw_progress_bar(progress_bar_y, progress_bar_x, progress_bar_width, progress); + + // Progress percentage + attron(COLOR_PAIR(SUCCESS_TEXT)); + std::string progress_text = std::to_string(static_cast(progress * 100)) + "% Complete"; + draw_centered_text(progress_bar_y + 1, progress_bar_x, progress_bar_width, progress_text); + attroff(COLOR_PAIR(SUCCESS_TEXT)); + + // Status messages + std::vector status_msgs = { + "Loading calendar module...", + "Initializing network stack...", + "Fetching latest events...", + "Preparing user interface...", + "System ready!" + }; + + int msg_index = (frame * status_msgs.size()) / 20; + if (msg_index >= status_msgs.size()) msg_index = status_msgs.size() - 1; + + attron(COLOR_PAIR(DIM_TEXT)); + draw_centered_text(progress_bar_y + 2, progress_bar_x, progress_bar_width, status_msgs[msg_index]); + attroff(COLOR_PAIR(DIM_TEXT)); + + refresh(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 100ms per frame } - attroff(COLOR_PAIR(SHADOW_TEXT)); - - // Draw main art - attron(COLOR_PAIR(BANNER_TEXT)); - for (int i = 0; i < art_height; ++i) { - mvprintw(start_row + i, start_col, "%s", splash_art[i].c_str()); - } - attroff(COLOR_PAIR(BANNER_TEXT)); - - attron(COLOR_PAIR(NORMAL_TEXT)); - std::string loading_msg = "Loading..."; - mvprintw(start_row + art_height + 2, (width - loading_msg.length()) / 2, "%s", loading_msg.c_str()); - attroff(COLOR_PAIR(NORMAL_TEXT)); - - refresh(); - std::this_thread::sleep_for(std::chrono::seconds(2)); // Display for 2 seconds endwin(); }