[FEATURE UPDATE]
Colored folders are now added allowing users to right click a folder and then set it's color. This data is saved in the colored folder as: >colored folder</.color with the .color folder holding the data for the folder icon color!
This commit is contained in:
Chris 2026-02-05 23:16:46 +01:00
parent a90f41d8a3
commit 2fd6f6f64f
10 changed files with 182 additions and 77 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -35,7 +35,7 @@ static void about_paint(Window *win) {
// Version info // Version info
draw_string(offset_x, offset_y + 105, "BrewOS", COLOR_BLACK); 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); draw_string(offset_x, offset_y + 135, "Kernel Version 2.1.0", COLOR_BLACK);
// Copyright // Copyright

View file

@ -2,6 +2,6 @@
void cli_cmd_brewver(char *args) { void cli_cmd_brewver(char *args) {
(void)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"); cli_write("BrewOS Kernel V2.1.0 Pre-Alpha\n");
} }

View file

@ -44,17 +44,18 @@ static uint32_t pattern_lumberjack[PATTERN_SIZE * PATTERN_SIZE];
static uint32_t pattern_blue_diamond[PATTERN_SIZE * PATTERN_SIZE]; static uint32_t pattern_blue_diamond[PATTERN_SIZE * PATTERN_SIZE];
static void generate_lumberjack_pattern(void) { 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 // Red corners, dark grey cross (top/left/right/bottom), black center
uint32_t red = 0xFFDC143C; uint32_t red = 0xFFDC143C;
uint32_t dark_grey = 0xFF404040; uint32_t dark_grey = 0xFF404040;
uint32_t black = 0xFF000000; uint32_t black = 0xFF000000;
int scale = 5;
// Fill entire pattern with the 3x3 repeating cell // Fill entire pattern with the 3x3 repeating cell
for (int y = 0; y < PATTERN_SIZE; y++) { for (int y = 0; y < PATTERN_SIZE; y++) {
for (int x = 0; x < PATTERN_SIZE; x++) { for (int x = 0; x < PATTERN_SIZE; x++) {
int cell_x = x % 3; int cell_x = (x / scale) % 3;
int cell_y = y % 3; int cell_y = (y / scale) % 3;
uint32_t color; uint32_t color;

View file

@ -28,6 +28,7 @@ typedef struct {
char name[256]; char name[256];
bool is_directory; bool is_directory;
uint32_t size; uint32_t size;
uint32_t color;
} ExplorerItem; } ExplorerItem;
typedef enum { typedef enum {
@ -239,6 +240,41 @@ static void dropdown_menu_toggle(void) {
// === Explorer Logic === // === 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) { static void explorer_load_directory(const char *path) {
explorer_strcpy(current_path, path); explorer_strcpy(current_path, path);
@ -247,9 +283,26 @@ static void explorer_load_directory(const char *path) {
item_count = 0; item_count = 0;
for (int i = 0; i < count && i < EXPLORER_MAX_FILES; i++) { for (int i = 0; i < count && i < EXPLORER_MAX_FILES; i++) {
explorer_strcpy(items[i].name, entries[i].name); // Skip .color files
items[i].is_directory = entries[i].is_directory; if (explorer_strcmp(entries[i].name, ".color") == 0) {
items[i].size = entries[i].size; 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++; item_count++;
} }
@ -291,15 +344,21 @@ static void explorer_navigate_to(const char *dirname) {
} }
// Draw a simple file icon // 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) { if (is_dir) {
// Folder icon - larger // Folder icon (colored folder) - Desktop style
draw_rect(x + 10, y + 10, 30, 5, COLOR_BLUE); // Tab // Folder tab
draw_rect(x + 10, y + 15, 30, 25, COLOR_WHITE); // Main folder draw_rect(x + 10, y + 10, 15, 6, COLOR_LTGRAY);
draw_rect(x + 10, y + 15, 2, 25, COLOR_BLACK); draw_rect(x + 10, y + 10, 15, 1, COLOR_BLACK);
draw_rect(x + 10, y + 15, 30, 2, COLOR_BLACK); draw_rect(x + 10, y + 10, 1, 6, COLOR_BLACK);
draw_rect(x + 38, y + 15, 2, 25, COLOR_BLACK); draw_rect(x + 24, y + 10, 1, 6, COLOR_BLACK);
draw_rect(x + 10, y + 38, 30, 2, 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 { } else {
// Document icon - larger // Document icon - larger
draw_rect(x + 12, y + 10, 20, 25, COLOR_WHITE); 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_rect(item_x + 2, item_y + 2, EXPLORER_ITEM_WIDTH - 4, EXPLORER_ITEM_HEIGHT - 4, bg_color);
// Draw icon (larger area) // 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 // Draw name below icon with text wrapping
uint32_t text_color = (i == selected_item) ? COLOR_WHITE : COLOR_BLACK; uint32_t text_color = (i == selected_item) ? COLOR_WHITE : COLOR_BLACK;
@ -458,6 +517,23 @@ static void explorer_paint(Window *win) {
int menu_screen_x = win->x + file_context_menu_x; int menu_screen_x = win->x + file_context_menu_x;
int menu_screen_y = win->y + file_context_menu_y; int menu_screen_y = win->y + file_context_menu_y;
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 menu background
draw_rect(menu_screen_x, menu_screen_y, FILE_CONTEXT_MENU_WIDTH, FILE_CONTEXT_MENU_HEIGHT, COLOR_LTGRAY); 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_bevel_rect(menu_screen_x, menu_screen_y, FILE_CONTEXT_MENU_WIDTH, FILE_CONTEXT_MENU_HEIGHT, true);
@ -473,6 +549,7 @@ static void explorer_paint(Window *win) {
draw_string(menu_screen_x + 5, menu_screen_y + item_height + 5, "Open w/ Markdown", COLOR_BLACK); draw_string(menu_screen_x + 5, menu_screen_y + item_height + 5, "Open w/ Markdown", COLOR_BLACK);
} }
} }
}
} }
// === Mouse Handler === // === Mouse Handler ===
@ -770,8 +847,7 @@ static void explorer_handle_right_click(Window *win, int x, int y) {
if (x >= item_x && x < item_x + EXPLORER_ITEM_WIDTH && if (x >= item_x && x < item_x + EXPLORER_ITEM_WIDTH &&
y >= item_y && y < item_y + EXPLORER_ITEM_HEIGHT) { y >= item_y && y < item_y + EXPLORER_ITEM_HEIGHT) {
// Right-click on a file item // Right-click on a file or folder item
if (!items[i].is_directory) {
// Show context menu // Show context menu
file_context_menu_visible = true; file_context_menu_visible = true;
file_context_menu_item = i; file_context_menu_item = i;
@ -780,7 +856,6 @@ static void explorer_handle_right_click(Window *win, int x, int y) {
return; return;
} }
} }
}
// Close menu if clicking elsewhere // Close menu if clicking elsewhere
file_context_menu_visible = false; file_context_menu_visible = false;
@ -798,14 +873,42 @@ static void explorer_handle_file_context_menu_click(Window *win, int x, int y) {
int relative_x = x - file_context_menu_x; int relative_x = x - file_context_menu_x;
int relative_y = y - file_context_menu_y; 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 || 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 // Clicked outside menu - close it
file_context_menu_visible = false; file_context_menu_visible = false;
file_context_menu_item = -1; file_context_menu_item = -1;
return; return;
} }
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 item_height = FILE_CONTEXT_MENU_HEIGHT / FILE_CONTEXT_ITEMS;
int clicked_item = relative_y / item_height; int clicked_item = relative_y / item_height;
@ -842,6 +945,7 @@ static void explorer_handle_file_context_menu_click(Window *win, int x, int y) {
win_markdown.z_index = max_z + 1; win_markdown.z_index = max_z + 1;
markdown_open_file(full_path); markdown_open_file(full_path);
} }
}
file_context_menu_visible = false; file_context_menu_visible = false;
file_context_menu_item = -1; file_context_menu_item = -1;

View file

@ -12,7 +12,7 @@ static const uint8_t font8x8_basic[128][8] = {
// 32 Space // 32 Space
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
// 33 ! // 33 !
{0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, {0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x00},
// 34 " // 34 "
{0x66, 0x66, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x66, 0x66, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00},
// 35 # // 35 #