diff --git a/brewos.iso b/brewos.iso index eccc901..3bee791 100644 Binary files a/brewos.iso and b/brewos.iso differ diff --git a/build/brewos.elf b/build/brewos.elf index 3c8bbd1..c7ac4d9 100755 Binary files a/build/brewos.elf and b/build/brewos.elf differ diff --git a/build/control_panel.o b/build/control_panel.o index 69017e7..b33233f 100644 Binary files a/build/control_panel.o and b/build/control_panel.o differ diff --git a/build/explorer.o b/build/explorer.o index f1510a7..7b522d1 100644 Binary files a/build/explorer.o and b/build/explorer.o differ diff --git a/iso_root/brewos.elf b/iso_root/brewos.elf index 3c8bbd1..c7ac4d9 100755 Binary files a/iso_root/brewos.elf and b/iso_root/brewos.elf differ diff --git a/src/kernel/about.c b/src/kernel/about.c index 0deffd4..b8f82bb 100644 --- a/src/kernel/about.c +++ b/src/kernel/about.c @@ -35,7 +35,7 @@ static void about_paint(Window *win) { // Version info draw_string(offset_x, offset_y + 105, "BrewOS", COLOR_BLACK); - draw_string(offset_x, offset_y + 120, "BrewOS Version 1.10", COLOR_BLACK); + draw_string(offset_x, offset_y + 120, "BrewOS Version 1.12", COLOR_BLACK); draw_string(offset_x, offset_y + 135, "Kernel Version 2.1.0", COLOR_BLACK); // Copyright diff --git a/src/kernel/cli_apps/about.c b/src/kernel/cli_apps/about.c index ebc7100..668a770 100644 --- a/src/kernel/cli_apps/about.c +++ b/src/kernel/cli_apps/about.c @@ -2,6 +2,6 @@ void cli_cmd_brewver(char *args) { (void)args; - cli_write("BrewOS v1.10 Alpha\n"); + cli_write("BrewOS v1.12 Alpha\n"); cli_write("BrewOS Kernel V2.1.0 Pre-Alpha\n"); } diff --git a/src/kernel/control_panel.c b/src/kernel/control_panel.c index 3afe1ed..60a5776 100644 --- a/src/kernel/control_panel.c +++ b/src/kernel/control_panel.c @@ -44,17 +44,18 @@ static uint32_t pattern_lumberjack[PATTERN_SIZE * PATTERN_SIZE]; static uint32_t pattern_blue_diamond[PATTERN_SIZE * PATTERN_SIZE]; static void generate_lumberjack_pattern(void) { - // Lumberjack pattern: 3x3 repeating cell + // Lumberjack pattern: 3x3 repeating cell, scaled 5x // Red corners, dark grey cross (top/left/right/bottom), black center uint32_t red = 0xFFDC143C; uint32_t dark_grey = 0xFF404040; uint32_t black = 0xFF000000; + int scale = 5; // Fill entire pattern with the 3x3 repeating cell for (int y = 0; y < PATTERN_SIZE; y++) { for (int x = 0; x < PATTERN_SIZE; x++) { - int cell_x = x % 3; - int cell_y = y % 3; + int cell_x = (x / scale) % 3; + int cell_y = (y / scale) % 3; uint32_t color; diff --git a/src/kernel/explorer.c b/src/kernel/explorer.c index a22916f..fcba2cf 100644 --- a/src/kernel/explorer.c +++ b/src/kernel/explorer.c @@ -28,6 +28,7 @@ typedef struct { char name[256]; bool is_directory; uint32_t size; + uint32_t color; } ExplorerItem; typedef enum { @@ -239,6 +240,41 @@ static void dropdown_menu_toggle(void) { // === Explorer Logic === +static uint32_t explorer_get_folder_color(const char *folder_path) { + char color_file_path[256]; + explorer_strcpy(color_file_path, folder_path); + if (color_file_path[explorer_strlen(color_file_path) - 1] != '/') { + explorer_strcat(color_file_path, "/"); + } + explorer_strcat(color_file_path, ".color"); + + FAT32_FileHandle *file = fat32_open(color_file_path, "r"); + if (file) { + uint32_t color = 0; + int bytes_read = fat32_read(file, &color, sizeof(uint32_t)); + fat32_close(file); + if (bytes_read == sizeof(uint32_t)) { + return color; + } + } + return COLOR_APPLE_YELLOW; +} + +static void explorer_set_folder_color(const char *folder_path, uint32_t color) { + char color_file_path[256]; + explorer_strcpy(color_file_path, folder_path); + if (color_file_path[explorer_strlen(color_file_path) - 1] != '/') { + explorer_strcat(color_file_path, "/"); + } + explorer_strcat(color_file_path, ".color"); + + FAT32_FileHandle *file = fat32_open(color_file_path, "w"); + if (file) { + fat32_write(file, &color, sizeof(uint32_t)); + fat32_close(file); + } +} + static void explorer_load_directory(const char *path) { explorer_strcpy(current_path, path); @@ -247,9 +283,26 @@ static void explorer_load_directory(const char *path) { item_count = 0; for (int i = 0; i < count && i < EXPLORER_MAX_FILES; i++) { - explorer_strcpy(items[i].name, entries[i].name); - items[i].is_directory = entries[i].is_directory; - items[i].size = entries[i].size; + // Skip .color files + if (explorer_strcmp(entries[i].name, ".color") == 0) { + continue; + } + + explorer_strcpy(items[item_count].name, entries[i].name); + items[item_count].is_directory = entries[i].is_directory; + items[item_count].size = entries[i].size; + + if (items[item_count].is_directory) { + char subfolder_path[256]; + explorer_strcpy(subfolder_path, current_path); + if (subfolder_path[explorer_strlen(subfolder_path) - 1] != '/') { + explorer_strcat(subfolder_path, "/"); + } + explorer_strcat(subfolder_path, items[item_count].name); + items[item_count].color = explorer_get_folder_color(subfolder_path); + } else { + items[item_count].color = COLOR_APPLE_YELLOW; + } item_count++; } @@ -291,15 +344,21 @@ static void explorer_navigate_to(const char *dirname) { } // Draw a simple file icon -static void explorer_draw_file_icon(int x, int y, bool is_dir) { +static void explorer_draw_file_icon(int x, int y, bool is_dir, uint32_t color) { if (is_dir) { - // Folder icon - larger - draw_rect(x + 10, y + 10, 30, 5, COLOR_BLUE); // Tab - draw_rect(x + 10, y + 15, 30, 25, COLOR_WHITE); // Main folder - draw_rect(x + 10, y + 15, 2, 25, COLOR_BLACK); - draw_rect(x + 10, y + 15, 30, 2, COLOR_BLACK); - draw_rect(x + 38, y + 15, 2, 25, COLOR_BLACK); - draw_rect(x + 10, y + 38, 30, 2, COLOR_BLACK); + // Folder icon (colored folder) - Desktop style + // Folder tab + draw_rect(x + 10, y + 10, 15, 6, COLOR_LTGRAY); + draw_rect(x + 10, y + 10, 15, 1, COLOR_BLACK); + draw_rect(x + 10, y + 10, 1, 6, COLOR_BLACK); + draw_rect(x + 24, y + 10, 1, 6, COLOR_BLACK); + + // Folder body + draw_rect(x + 10, y + 16, 25, 15, color); + draw_rect(x + 10, y + 16, 25, 1, COLOR_BLACK); + draw_rect(x + 10, y + 16, 1, 15, COLOR_BLACK); + draw_rect(x + 34, y + 16, 1, 15, COLOR_BLACK); + draw_rect(x + 10, y + 30, 25, 1, COLOR_BLACK); } else { // Document icon - larger draw_rect(x + 12, y + 10, 20, 25, COLOR_WHITE); @@ -367,7 +426,7 @@ static void explorer_paint(Window *win) { draw_rect(item_x + 2, item_y + 2, EXPLORER_ITEM_WIDTH - 4, EXPLORER_ITEM_HEIGHT - 4, bg_color); // Draw icon (larger area) - explorer_draw_file_icon(item_x + 5, item_y + 5, items[i].is_directory); + explorer_draw_file_icon(item_x + 5, item_y + 5, items[i].is_directory, items[i].color); // Draw name below icon with text wrapping uint32_t text_color = (i == selected_item) ? COLOR_WHITE : COLOR_BLACK; @@ -458,19 +517,37 @@ static void explorer_paint(Window *win) { int menu_screen_x = win->x + file_context_menu_x; int menu_screen_y = win->y + file_context_menu_y; - // Draw menu background - draw_rect(menu_screen_x, menu_screen_y, FILE_CONTEXT_MENU_WIDTH, FILE_CONTEXT_MENU_HEIGHT, COLOR_LTGRAY); - draw_bevel_rect(menu_screen_x, menu_screen_y, FILE_CONTEXT_MENU_WIDTH, FILE_CONTEXT_MENU_HEIGHT, true); - - // Draw menu items - int item_height = FILE_CONTEXT_MENU_HEIGHT / FILE_CONTEXT_ITEMS; - - // Item 1: "Open with Text Editor" - draw_string(menu_screen_x + 5, menu_screen_y + 5, "Open w/ Editor", COLOR_BLACK); - - // Item 2: "Open with Markdown Viewer" (only show if file is .md) - if (explorer_is_markdown_file(items[file_context_menu_item].name)) { - draw_string(menu_screen_x + 5, menu_screen_y + item_height + 5, "Open w/ Markdown", COLOR_BLACK); + if (items[file_context_menu_item].is_directory) { + // Folder context menu (Color selection) + int menu_height = 25 * 5; // 5 items, 25px each + + // Draw menu background + draw_rect(menu_screen_x, menu_screen_y, FILE_CONTEXT_MENU_WIDTH, menu_height, COLOR_LTGRAY); + draw_bevel_rect(menu_screen_x, menu_screen_y, FILE_CONTEXT_MENU_WIDTH, menu_height, true); + + // Draw menu items + int item_h = 25; + draw_string(menu_screen_x + 5, menu_screen_y + 5, "Blue", COLOR_APPLE_BLUE); + draw_string(menu_screen_x + 5, menu_screen_y + item_h + 5, "Red", COLOR_RED); + draw_string(menu_screen_x + 5, menu_screen_y + item_h * 2 + 5, "Yellow", COLOR_APPLE_YELLOW); // Text might be hard to read, but requested + draw_string(menu_screen_x + 5, menu_screen_y + item_h * 3 + 5, "Green", COLOR_APPLE_GREEN); + draw_string(menu_screen_x + 5, menu_screen_y + item_h * 4 + 5, "Black", COLOR_BLACK); + } else { + // File context menu + // Draw menu background + draw_rect(menu_screen_x, menu_screen_y, FILE_CONTEXT_MENU_WIDTH, FILE_CONTEXT_MENU_HEIGHT, COLOR_LTGRAY); + draw_bevel_rect(menu_screen_x, menu_screen_y, FILE_CONTEXT_MENU_WIDTH, FILE_CONTEXT_MENU_HEIGHT, true); + + // Draw menu items + int item_height = FILE_CONTEXT_MENU_HEIGHT / FILE_CONTEXT_ITEMS; + + // Item 1: "Open with Text Editor" + draw_string(menu_screen_x + 5, menu_screen_y + 5, "Open w/ Editor", COLOR_BLACK); + + // Item 2: "Open with Markdown Viewer" (only show if file is .md) + if (explorer_is_markdown_file(items[file_context_menu_item].name)) { + draw_string(menu_screen_x + 5, menu_screen_y + item_height + 5, "Open w/ Markdown", COLOR_BLACK); + } } } } @@ -770,15 +847,13 @@ static void explorer_handle_right_click(Window *win, int x, int y) { if (x >= item_x && x < item_x + EXPLORER_ITEM_WIDTH && y >= item_y && y < item_y + EXPLORER_ITEM_HEIGHT) { - // Right-click on a file item - if (!items[i].is_directory) { - // Show context menu - file_context_menu_visible = true; - file_context_menu_item = i; - file_context_menu_x = x; - file_context_menu_y = y; - return; - } + // Right-click on a file or folder item + // Show context menu + file_context_menu_visible = true; + file_context_menu_item = i; + file_context_menu_x = x; + file_context_menu_y = y; + return; } } @@ -798,49 +873,78 @@ static void explorer_handle_file_context_menu_click(Window *win, int x, int y) { int relative_x = x - file_context_menu_x; int relative_y = y - file_context_menu_y; + int menu_height; + if (items[file_context_menu_item].is_directory) { + menu_height = 25 * 5; + } else { + menu_height = FILE_CONTEXT_MENU_HEIGHT; + } + if (relative_x < 0 || relative_x > FILE_CONTEXT_MENU_WIDTH || - relative_y < 0 || relative_y > FILE_CONTEXT_MENU_HEIGHT) { + relative_y < 0 || relative_y > menu_height) { // Clicked outside menu - close it file_context_menu_visible = false; file_context_menu_item = -1; return; } - int item_height = FILE_CONTEXT_MENU_HEIGHT / FILE_CONTEXT_ITEMS; - int clicked_item = relative_y / item_height; - - // Build full path - char full_path[256]; - explorer_strcpy(full_path, current_path); - if (full_path[explorer_strlen(full_path) - 1] != '/') { - explorer_strcat(full_path, "/"); - } - explorer_strcat(full_path, items[file_context_menu_item].name); - - if (clicked_item == 0) { - // "Open with Text Editor" - win_editor.visible = true; - win_editor.focused = true; - int max_z = 0; - if (win_explorer.z_index > max_z) max_z = win_explorer.z_index; - if (win_cmd.z_index > max_z) max_z = win_cmd.z_index; - if (win_notepad.z_index > max_z) max_z = win_notepad.z_index; - if (win_calculator.z_index > max_z) max_z = win_calculator.z_index; - if (win_markdown.z_index > max_z) max_z = win_markdown.z_index; - win_editor.z_index = max_z + 1; - editor_open_file(full_path); - } else if (clicked_item == 1 && explorer_is_markdown_file(items[file_context_menu_item].name)) { - // "Open with Markdown Viewer" - win_markdown.visible = true; - win_markdown.focused = true; - int max_z = 0; - if (win_explorer.z_index > max_z) max_z = win_explorer.z_index; - if (win_cmd.z_index > max_z) max_z = win_cmd.z_index; - if (win_notepad.z_index > max_z) max_z = win_notepad.z_index; - if (win_calculator.z_index > max_z) max_z = win_calculator.z_index; - if (win_editor.z_index > max_z) max_z = win_editor.z_index; - win_markdown.z_index = max_z + 1; - markdown_open_file(full_path); + if (items[file_context_menu_item].is_directory) { + int clicked_item = relative_y / 25; + uint32_t new_color = items[file_context_menu_item].color; + + if (clicked_item == 0) new_color = COLOR_APPLE_BLUE; + else if (clicked_item == 1) new_color = COLOR_RED; + else if (clicked_item == 2) new_color = COLOR_APPLE_YELLOW; + else if (clicked_item == 3) new_color = COLOR_APPLE_GREEN; + else if (clicked_item == 4) new_color = COLOR_BLACK; + + items[file_context_menu_item].color = new_color; + + // Save to file + char full_path[256]; + explorer_strcpy(full_path, current_path); + if (full_path[explorer_strlen(full_path) - 1] != '/') { + explorer_strcat(full_path, "/"); + } + explorer_strcat(full_path, items[file_context_menu_item].name); + explorer_set_folder_color(full_path, new_color); + } else { + int item_height = FILE_CONTEXT_MENU_HEIGHT / FILE_CONTEXT_ITEMS; + int clicked_item = relative_y / item_height; + + // Build full path + char full_path[256]; + explorer_strcpy(full_path, current_path); + if (full_path[explorer_strlen(full_path) - 1] != '/') { + explorer_strcat(full_path, "/"); + } + explorer_strcat(full_path, items[file_context_menu_item].name); + + if (clicked_item == 0) { + // "Open with Text Editor" + win_editor.visible = true; + win_editor.focused = true; + int max_z = 0; + if (win_explorer.z_index > max_z) max_z = win_explorer.z_index; + if (win_cmd.z_index > max_z) max_z = win_cmd.z_index; + if (win_notepad.z_index > max_z) max_z = win_notepad.z_index; + if (win_calculator.z_index > max_z) max_z = win_calculator.z_index; + if (win_markdown.z_index > max_z) max_z = win_markdown.z_index; + win_editor.z_index = max_z + 1; + editor_open_file(full_path); + } else if (clicked_item == 1 && explorer_is_markdown_file(items[file_context_menu_item].name)) { + // "Open with Markdown Viewer" + win_markdown.visible = true; + win_markdown.focused = true; + int max_z = 0; + if (win_explorer.z_index > max_z) max_z = win_explorer.z_index; + if (win_cmd.z_index > max_z) max_z = win_cmd.z_index; + if (win_notepad.z_index > max_z) max_z = win_notepad.z_index; + if (win_calculator.z_index > max_z) max_z = win_calculator.z_index; + if (win_editor.z_index > max_z) max_z = win_editor.z_index; + win_markdown.z_index = max_z + 1; + markdown_open_file(full_path); + } } file_context_menu_visible = false; diff --git a/src/kernel/font.h b/src/kernel/font.h index c595c58..e95b915 100644 --- a/src/kernel/font.h +++ b/src/kernel/font.h @@ -11,8 +11,8 @@ static const uint8_t font8x8_basic[128][8] = { {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, // 32 Space {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - // 33 ! - {0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, + // 33 ! + {0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x00}, // 34 " {0x66, 0x66, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00}, // 35 #