mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
Major redesign 1.60
This commit is contained in:
parent
6f68538b86
commit
b4cccb0eb3
30 changed files with 495 additions and 332 deletions
BIN
boredos.iso
BIN
boredos.iso
Binary file not shown.
BIN
build/about.o
BIN
build/about.o
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/cmd.o
BIN
build/cmd.o
Binary file not shown.
Binary file not shown.
BIN
build/editor.o
BIN
build/editor.o
Binary file not shown.
BIN
build/explorer.o
BIN
build/explorer.o
Binary file not shown.
BIN
build/graphics.o
BIN
build/graphics.o
Binary file not shown.
BIN
build/markdown.o
BIN
build/markdown.o
Binary file not shown.
Binary file not shown.
BIN
build/notepad.o
BIN
build/notepad.o
Binary file not shown.
BIN
build/paint.o
BIN
build/paint.o
Binary file not shown.
BIN
build/wm.o
BIN
build/wm.o
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
||||||
# BoredOS 1.50
|
# BoredOS 1.51
|
||||||
BoredOS has now exited Beta stage and is "stable enough" to be put out as a "stable" product.
|
BoredOS has now exited Beta stage and is "stable enough" to be put out as a "stable" product.
|
||||||
|
|
||||||
<img src="bored.svg" width="200" /> </br>
|
<img src="bored.svg" width="200" /> </br>
|
||||||
|
|
@ -9,6 +9,7 @@ It features a DE (and WM), a FAT32 filesystem, customizable UI and much much mor
|
||||||
*this screenshot might be outdated*
|
*this screenshot might be outdated*
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
- Disk manager
|
||||||
- Drag and drop mouse centered UI
|
- Drag and drop mouse centered UI
|
||||||
- Customizable UI
|
- Customizable UI
|
||||||
- Basic Networking Stack
|
- Basic Networking Stack
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -13,13 +13,13 @@ static void about_paint(Window *win) {
|
||||||
draw_boredos_logo(win->x + 60, offset_y, 4);
|
draw_boredos_logo(win->x + 60, offset_y, 4);
|
||||||
|
|
||||||
// Version info
|
// Version info
|
||||||
draw_string(offset_x, offset_y + 105, "BoredOS 'Panda'", COLOR_BLACK);
|
draw_string(offset_x, offset_y + 105, "BoredOS 'Panda'", COLOR_WHITE);
|
||||||
draw_string(offset_x, offset_y + 120, "BoredOS Version 1.51", COLOR_BLACK);
|
draw_string(offset_x, offset_y + 120, "BoredOS Version 1.51", COLOR_WHITE);
|
||||||
draw_string(offset_x, offset_y + 135, "Kernel Version 2.5.0", COLOR_BLACK);
|
draw_string(offset_x, offset_y + 135, "Kernel Version 2.5.0", COLOR_WHITE);
|
||||||
|
|
||||||
// Copyright
|
// Copyright
|
||||||
draw_string(offset_x, offset_y + 150, "(C) 2026 boreddevnl.", COLOR_BLACK);
|
draw_string(offset_x, offset_y + 150, "(C) 2026 boreddevnl.", COLOR_WHITE);
|
||||||
draw_string(offset_x, offset_y + 165, "All rights reserved.", COLOR_BLACK);
|
draw_string(offset_x, offset_y + 165, "All rights reserved.", COLOR_WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void about_click(Window *win, int x, int y) {
|
static void about_click(Window *win, int x, int y) {
|
||||||
|
|
|
||||||
|
|
@ -100,17 +100,16 @@ static void update_display(Window *win) {
|
||||||
|
|
||||||
static void calculator_paint(Window *win) {
|
static void calculator_paint(Window *win) {
|
||||||
// Background
|
// Background
|
||||||
draw_rect(win->x + 4, win->y + 24, win->w - 8, win->h - 28, COLOR_LTGRAY);
|
draw_rect(win->x + 4, win->y + 30, win->w - 8, win->h - 34, COLOR_DARK_BG);
|
||||||
|
|
||||||
// Display Area
|
// Display Area with dark mode styling
|
||||||
draw_bevel_rect(win->x + 10, win->y + 30, win->w - 20, 25, true);
|
draw_rounded_rect_filled(win->x + 10, win->y + 36, win->w - 20, 25, 6, COLOR_DARK_PANEL);
|
||||||
// Right align text
|
// Right align text
|
||||||
int text_w = win->buf_len * 8;
|
int text_w = win->buf_len * 8;
|
||||||
int text_x = win->x + win->w - 15 - text_w;
|
int text_x = win->x + win->w - 15 - text_w;
|
||||||
draw_string(text_x, win->y + 38, win->buffer, COLOR_BLACK);
|
draw_string(text_x, win->y + 44, win->buffer, COLOR_DARK_TEXT);
|
||||||
|
|
||||||
// Buttons
|
// Buttons - macOS style squircle buttons
|
||||||
// Layout 4 columns x 5 rows
|
|
||||||
const char *labels[] = {
|
const char *labels[] = {
|
||||||
"C", "sqr", "rt", "/",
|
"C", "sqr", "rt", "/",
|
||||||
"7", "8", "9", "*",
|
"7", "8", "9", "*",
|
||||||
|
|
@ -123,14 +122,18 @@ static void calculator_paint(Window *win) {
|
||||||
int bh = 25;
|
int bh = 25;
|
||||||
int gap = 5;
|
int gap = 5;
|
||||||
int start_x = win->x + 10;
|
int start_x = win->x + 10;
|
||||||
int start_y = win->y + 65;
|
int start_y = win->y + 70;
|
||||||
|
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 20; i++) {
|
||||||
int r = i / 4;
|
int r = i / 4;
|
||||||
int c = i % 4;
|
int c = i % 4;
|
||||||
|
|
||||||
// Special drawing for some buttons?
|
// Draw rounded button backgrounds
|
||||||
draw_button(start_x + c*(bw+gap), start_y + r*(bh+gap), bw, bh, labels[i], false);
|
draw_rounded_rect_filled(start_x + c*(bw+gap), start_y + r*(bh+gap), bw, bh, 4, COLOR_DARK_BORDER);
|
||||||
|
// Draw button text
|
||||||
|
int label_x = start_x + c*(bw+gap) + 5;
|
||||||
|
int label_y = start_y + r*(bh+gap) + 9;
|
||||||
|
draw_string(label_x, label_y, labels[i], COLOR_DARK_TEXT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ Window win_cmd;
|
||||||
static CharCell screen_buffer[CMD_ROWS][CMD_COLS];
|
static CharCell screen_buffer[CMD_ROWS][CMD_COLS];
|
||||||
static int cursor_row = 0;
|
static int cursor_row = 0;
|
||||||
static int cursor_col = 0;
|
static int cursor_col = 0;
|
||||||
static uint32_t current_color = COLOR_LTGRAY;
|
static uint32_t current_color = COLOR_DARK_TEXT;
|
||||||
static CmdState *cmd_state = NULL; // Will be set in cmd_init
|
static CmdState *cmd_state = NULL; // Will be set in cmd_init
|
||||||
|
|
||||||
// Pager State
|
// Pager State
|
||||||
|
|
@ -272,7 +272,7 @@ void cmd_screen_clear() {
|
||||||
for(int r=0; r<CMD_ROWS; r++) {
|
for(int r=0; r<CMD_ROWS; r++) {
|
||||||
for(int c=0; c<CMD_COLS; c++) {
|
for(int c=0; c<CMD_COLS; c++) {
|
||||||
screen_buffer[r][c].c = ' ';
|
screen_buffer[r][c].c = ' ';
|
||||||
screen_buffer[r][c].color = COLOR_LTGRAY;
|
screen_buffer[r][c].color = COLOR_DARK_TEXT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cursor_row = 0;
|
cursor_row = 0;
|
||||||
|
|
@ -1297,8 +1297,8 @@ static void cmd_paint(Window *win) {
|
||||||
int offset_x = win->x + 4;
|
int offset_x = win->x + 4;
|
||||||
int offset_y = win->y + 24;
|
int offset_y = win->y + 24;
|
||||||
|
|
||||||
// Fill background
|
// Fill background - dark mode terminal
|
||||||
draw_rect(win->x + 4, win->y + 24, win->w - 8, win->h - 28, COLOR_BLACK);
|
draw_rect(win->x + 4, win->y + 30, win->w - 8, win->h - 34, COLOR_DARK_BG);
|
||||||
|
|
||||||
int start_y = offset_y + 4;
|
int start_y = offset_y + 4;
|
||||||
int start_x = offset_x + 4;
|
int start_x = offset_x + 4;
|
||||||
|
|
@ -1306,11 +1306,11 @@ static void cmd_paint(Window *win) {
|
||||||
if (current_mode == MODE_PAGER) {
|
if (current_mode == MODE_PAGER) {
|
||||||
// Draw Pager Content (Wrapped)
|
// Draw Pager Content (Wrapped)
|
||||||
for (int i = 0; i < CMD_ROWS && (pager_top_line + i) < pager_total_lines; i++) {
|
for (int i = 0; i < CMD_ROWS && (pager_top_line + i) < pager_total_lines; i++) {
|
||||||
draw_string(start_x, start_y + (i * LINE_HEIGHT), pager_wrapped_lines[pager_top_line + i], COLOR_LTGRAY);
|
draw_string(start_x, start_y + (i * LINE_HEIGHT), pager_wrapped_lines[pager_top_line + i], COLOR_DARK_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status Bar
|
// Status Bar
|
||||||
draw_string(start_x, start_y + (CMD_ROWS * LINE_HEIGHT), "-- Press Q to quit --", COLOR_WHITE);
|
draw_string(start_x, start_y + (CMD_ROWS * LINE_HEIGHT), "-- Press Q to quit --", COLOR_DARK_TEXT);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Draw Shell Buffer
|
// Draw Shell Buffer
|
||||||
|
|
|
||||||
|
|
@ -152,81 +152,54 @@ static void control_panel_paint_main(Window *win) {
|
||||||
int offset_x = win->x + 8;
|
int offset_x = win->x + 8;
|
||||||
int offset_y = win->y + 30;
|
int offset_y = win->y + 30;
|
||||||
|
|
||||||
// Draw wallpaper painting icon
|
// Background
|
||||||
// Frame
|
draw_rect(win->x, win->y + 30, win->w, win->h - 30, COLOR_DARK_BG);
|
||||||
draw_rect(offset_x + 5, offset_y + 2, 28, 20, 0xFF8B4513); // Brown frame
|
|
||||||
draw_rect(offset_x + 6, offset_y + 3, 26, 18, 0xFFFFFFFF); // White canvas
|
|
||||||
|
|
||||||
// Paint strokes (simple landscape)
|
// Draw settings items with rounded boxes
|
||||||
draw_rect(offset_x + 8, offset_y + 5, 22, 7, 0xFF87CEEB); // Sky blue
|
int item_y = 30 + 15;
|
||||||
draw_rect(offset_x + 8, offset_y + 12, 22, 5, 0xFF90EE90); // Light green grass
|
int item_h = 60;
|
||||||
draw_rect(offset_x + 15, offset_y + 8, 3, 4, 0xFF8B4513); // Tree trunk
|
int item_spacing = 10;
|
||||||
draw_rect(offset_x + 13, offset_y + 5, 7, 4, 0xFF228B22); // Tree leaves
|
|
||||||
draw_rect(offset_x + 24, offset_y + 6, 4, 3, 0xFFFFFF00); // Sun
|
|
||||||
|
|
||||||
draw_string(offset_x + 40, offset_y + 8, "Wallpaper", 0xFF000000);
|
// Wallpaper Settings
|
||||||
|
draw_rounded_rect_filled(offset_x, offset_y + item_y, win->w - 16, item_h, 8, COLOR_DARK_PANEL);
|
||||||
|
// Wallpaper icon: landscape
|
||||||
|
draw_rect(offset_x + 12, offset_y + item_y + 8, 40, 40, 0xFF87CEEB); // Sky
|
||||||
|
draw_rect(offset_x + 12, offset_y + item_y + 28, 40, 20, 0xFF90EE90); // Grass
|
||||||
|
draw_rect(offset_x + 24, offset_y + item_y + 22, 3, 6, 0xFF654321); // Tree trunk
|
||||||
|
draw_rect(offset_x + 21, offset_y + item_y + 18, 9, 8, 0xFF228B22); // Tree leaves
|
||||||
|
draw_string(offset_x + 60, offset_y + item_y + 15, "Wallpaper", COLOR_DARK_TEXT);
|
||||||
|
draw_string(offset_x + 60, offset_y + item_y + 35, "Choose background design", COLOR_DKGRAY);
|
||||||
|
|
||||||
// Draw network globe icon
|
// Network Settings
|
||||||
int net_offset_y = offset_y + 35;
|
item_y += item_h + item_spacing;
|
||||||
|
draw_rounded_rect_filled(offset_x, offset_y + item_y, win->w - 16, item_h, 8, COLOR_DARK_PANEL);
|
||||||
|
// Network icon
|
||||||
|
draw_rect(offset_x + 18, offset_y + item_y + 12, 24, 24, 0xFF4169E1);
|
||||||
|
draw_rect(offset_x + 22, offset_y + item_y + 16, 16, 16, 0xFF87CEEB);
|
||||||
|
draw_string(offset_x + 60, offset_y + item_y + 15, "Network", COLOR_DARK_TEXT);
|
||||||
|
draw_string(offset_x + 60, offset_y + item_y + 35, "Internet and connectivity", COLOR_DKGRAY);
|
||||||
|
|
||||||
// Globe circle (approximate with rectangles for filled circle)
|
// Desktop Settings
|
||||||
uint32_t globe_color = 0xFF4169E1; // Royal blue
|
item_y += item_h + item_spacing;
|
||||||
|
if (offset_y + item_y + item_h < win->y + win->h) {
|
||||||
|
draw_rounded_rect_filled(offset_x, offset_y + item_y, win->w - 16, item_h, 8, COLOR_DARK_PANEL);
|
||||||
|
// Desktop icon: folder
|
||||||
|
draw_rect(offset_x + 12, offset_y + item_y + 10, 36, 8, 0xFFE0C060);
|
||||||
|
draw_rect(offset_x + 12, offset_y + item_y + 18, 36, 22, 0xFFD4A574);
|
||||||
|
draw_string(offset_x + 60, offset_y + item_y + 15, "Desktop", COLOR_DARK_TEXT);
|
||||||
|
draw_string(offset_x + 60, offset_y + item_y + 35, "Desktop appearance&icons", COLOR_DKGRAY);
|
||||||
|
}
|
||||||
|
|
||||||
// Draw filled circle using rectangles (simplified)
|
// Mouse Settings
|
||||||
draw_rect(offset_x + 11, net_offset_y + 3, 12, 1, globe_color);
|
item_y += item_h + item_spacing;
|
||||||
draw_rect(offset_x + 9, net_offset_y + 4, 16, 1, globe_color);
|
if (offset_y + item_y + item_h < win->y + win->h) {
|
||||||
draw_rect(offset_x + 8, net_offset_y + 5, 18, 1, globe_color);
|
draw_rounded_rect_filled(offset_x, offset_y + item_y, win->w - 16, item_h, 8, COLOR_DARK_PANEL);
|
||||||
draw_rect(offset_x + 7, net_offset_y + 6, 20, 1, globe_color);
|
// Mouse icon
|
||||||
draw_rect(offset_x + 6, net_offset_y + 7, 22, 1, globe_color);
|
draw_rect(offset_x + 18, offset_y + item_y + 8, 20, 28, 0xFFD3D3D3);
|
||||||
draw_rect(offset_x + 6, net_offset_y + 8, 22, 1, globe_color);
|
draw_rect(offset_x + 20, offset_y + item_y + 10, 16, 10, 0xFFB0B0B0);
|
||||||
draw_rect(offset_x + 6, net_offset_y + 9, 22, 1, globe_color);
|
draw_string(offset_x + 60, offset_y + item_y + 15, "Mouse", COLOR_DARK_TEXT);
|
||||||
draw_rect(offset_x + 6, net_offset_y + 10, 22, 1, globe_color);
|
draw_string(offset_x + 60, offset_y + item_y + 35, "Pointer and trackpad", COLOR_DKGRAY);
|
||||||
draw_rect(offset_x + 6, net_offset_y + 11, 22, 1, globe_color);
|
}
|
||||||
draw_rect(offset_x + 6, net_offset_y + 12, 22, 1, globe_color);
|
|
||||||
draw_rect(offset_x + 6, net_offset_y + 13, 22, 1, globe_color);
|
|
||||||
draw_rect(offset_x + 7, net_offset_y + 14, 20, 1, globe_color);
|
|
||||||
draw_rect(offset_x + 8, net_offset_y + 15, 18, 1, globe_color);
|
|
||||||
draw_rect(offset_x + 9, net_offset_y + 16, 16, 1, globe_color);
|
|
||||||
draw_rect(offset_x + 11, net_offset_y + 17, 12, 1, globe_color);
|
|
||||||
|
|
||||||
// Latitude lines (white)
|
|
||||||
draw_rect(offset_x + 7, net_offset_y + 8, 20, 1, 0xFFFFFFFF);
|
|
||||||
draw_rect(offset_x + 7, net_offset_y + 12, 20, 1, 0xFFFFFFFF);
|
|
||||||
|
|
||||||
// Longitude line (vertical, white)
|
|
||||||
draw_rect(offset_x + 17, net_offset_y + 6, 1, 9, 0xFFFFFFFF);
|
|
||||||
|
|
||||||
// Curved longitude lines
|
|
||||||
draw_rect(offset_x + 11, net_offset_y + 5, 1, 11, 0xFFFFFFFF);
|
|
||||||
draw_rect(offset_x + 23, net_offset_y + 5, 1, 11, 0xFFFFFFFF);
|
|
||||||
|
|
||||||
draw_string(offset_x + 40, net_offset_y + 8, "Network", 0xFF000000);
|
|
||||||
|
|
||||||
// Draw Desktop Settings Icon
|
|
||||||
int desk_offset_y = net_offset_y + 35;
|
|
||||||
// Folder icon style
|
|
||||||
draw_rect(offset_x + 5, desk_offset_y + 2, 12, 4, COLOR_LTGRAY);
|
|
||||||
draw_rect(offset_x + 5, desk_offset_y + 2, 12, 1, COLOR_BLACK);
|
|
||||||
draw_rect(offset_x + 5, desk_offset_y + 6, 24, 14, 0xFFE0C060); // Tan folder
|
|
||||||
draw_rect(offset_x + 5, desk_offset_y + 6, 24, 1, COLOR_BLACK);
|
|
||||||
draw_rect(offset_x + 5, desk_offset_y + 6, 1, 14, COLOR_BLACK);
|
|
||||||
draw_string(offset_x + 40, desk_offset_y + 8, "Desktop", 0xFF000000);
|
|
||||||
|
|
||||||
// Draw Mouse Icon
|
|
||||||
int mouse_offset_y = desk_offset_y + 35;
|
|
||||||
// Mouse body
|
|
||||||
draw_rect(offset_x + 17, mouse_offset_y, 1, 2, COLOR_BLACK);
|
|
||||||
draw_rect(offset_x + 16, mouse_offset_y - 2, 1, 2, COLOR_BLACK);
|
|
||||||
draw_rect(offset_x + 10, mouse_offset_y + 2, 15, 20, MOUSE_BEIGE);
|
|
||||||
draw_rect(offset_x + 10, mouse_offset_y + 2, 15, 1, COLOR_BLACK);
|
|
||||||
draw_rect(offset_x + 10, mouse_offset_y + 2, 1, 20, COLOR_BLACK);
|
|
||||||
draw_rect(offset_x + 24, mouse_offset_y + 2, 1, 20, COLOR_BLACK);
|
|
||||||
draw_rect(offset_x + 10, mouse_offset_y + 21, 15, 1, COLOR_BLACK);
|
|
||||||
// Buttons separator
|
|
||||||
draw_rect(offset_x + 10, mouse_offset_y + 8, 15, 1, COLOR_BLACK);
|
|
||||||
draw_rect(offset_x + 17, mouse_offset_y + 2, 1, 6, COLOR_BLACK);
|
|
||||||
|
|
||||||
draw_string(offset_x + 40, mouse_offset_y + 8, "Mouse", 0xFF000000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void control_panel_paint_wallpaper(Window *win) {
|
static void control_panel_paint_wallpaper(Window *win) {
|
||||||
|
|
@ -532,32 +505,37 @@ static void control_panel_handle_click(Window *win, int x, int y) {
|
||||||
int offset_x = 8;
|
int offset_x = 8;
|
||||||
int offset_y = 30;
|
int offset_y = 30;
|
||||||
|
|
||||||
// Check wallpaper button click (icon + text)
|
// Settings items layout: each item is 60px tall with 10px spacing
|
||||||
if (x >= offset_x + 5 && x < offset_x + 120 &&
|
int item_h = 60;
|
||||||
y >= offset_y && y < offset_y + 25) {
|
int item_spacing = 10;
|
||||||
|
|
||||||
|
// Check wallpaper button click (entire card area)
|
||||||
|
int item_y = offset_y + 15;
|
||||||
|
if (x >= offset_x && x < win->w - 8 &&
|
||||||
|
y >= item_y && y < item_y + item_h) {
|
||||||
current_view = VIEW_WALLPAPER;
|
current_view = VIEW_WALLPAPER;
|
||||||
focused_field = -1;
|
focused_field = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check network button click (icon + text)
|
// Check network button click
|
||||||
int net_offset_y = offset_y + 35;
|
item_y += item_h + item_spacing;
|
||||||
if (x >= offset_x + 5 && x < offset_x + 120 &&
|
if (x >= offset_x && x < win->w - 8 &&
|
||||||
y >= net_offset_y && y < net_offset_y + 25) {
|
y >= item_y && y < item_y + item_h) {
|
||||||
current_view = VIEW_NETWORK;
|
current_view = VIEW_NETWORK;
|
||||||
focused_field = -1;
|
focused_field = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check desktop button
|
// Check desktop button
|
||||||
int desk_offset_y = net_offset_y + 35;
|
item_y += item_h + item_spacing;
|
||||||
if (x >= offset_x + 5 && x < offset_x + 120 &&
|
if (x >= offset_x && x < win->w - 8 &&
|
||||||
y >= desk_offset_y && y < desk_offset_y + 25) {
|
y >= item_y && y < item_y + item_h) {
|
||||||
current_view = VIEW_DESKTOP;
|
current_view = VIEW_DESKTOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check mouse button
|
// Check mouse button
|
||||||
int mouse_offset_y = desk_offset_y + 35;
|
item_y += item_h + item_spacing;
|
||||||
if (x >= offset_x + 5 && x < offset_x + 120 &&
|
if (x >= offset_x && x < win->w - 8 &&
|
||||||
y >= mouse_offset_y && y < mouse_offset_y + 25) {
|
y >= item_y && y < item_y + item_h) {
|
||||||
current_view = VIEW_MOUSE;
|
current_view = VIEW_MOUSE;
|
||||||
}
|
}
|
||||||
} else if (current_view == VIEW_WALLPAPER) {
|
} else if (current_view == VIEW_WALLPAPER) {
|
||||||
|
|
@ -1027,7 +1005,7 @@ static void control_panel_handle_key(Window *win, char c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void control_panel_init(void) {
|
void control_panel_init(void) {
|
||||||
win_control_panel.title = "Control Panel";
|
win_control_panel.title = "Settings";
|
||||||
win_control_panel.x = 200;
|
win_control_panel.x = 200;
|
||||||
win_control_panel.y = 150;
|
win_control_panel.y = 150;
|
||||||
win_control_panel.w = 350;
|
win_control_panel.w = 350;
|
||||||
|
|
|
||||||
|
|
@ -252,8 +252,8 @@ static void editor_paint(Window *win) {
|
||||||
|
|
||||||
// Draw filename and save button area at top of content
|
// Draw filename and save button area at top of content
|
||||||
draw_rect(offset_x, offset_y, content_width, 25, COLOR_GRAY);
|
draw_rect(offset_x, offset_y, content_width, 25, COLOR_GRAY);
|
||||||
draw_string(offset_x + 10, offset_y + 5, "File", COLOR_BLACK);
|
draw_string(offset_x + 10, offset_y + 5, "File", COLOR_DARK_TEXT);
|
||||||
draw_string(offset_x + 55, offset_y + 5, open_filename, COLOR_BLACK);
|
draw_string(offset_x + 55, offset_y + 5, open_filename, COLOR_DARK_TEXT);
|
||||||
|
|
||||||
// Draw save button
|
// Draw save button
|
||||||
draw_button(offset_x + content_width - 80, offset_y + 3, 70, 20, "Save", false);
|
draw_button(offset_x + content_width - 80, offset_y + 3, 70, 20, "Save", false);
|
||||||
|
|
@ -263,8 +263,8 @@ static void editor_paint(Window *win) {
|
||||||
draw_string(offset_x + content_width - 200, offset_y + 5, "[Modified]", COLOR_RED);
|
draw_string(offset_x + content_width - 200, offset_y + 5, "[Modified]", COLOR_RED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill editor background
|
// Fill editor background - dark mode
|
||||||
draw_rect(win->x + 4, win->y + 54, win->w - 8, win->h - 58, COLOR_WHITE);
|
draw_rect(win->x + 4, win->y + 54, win->w - 8, win->h - 58, COLOR_DARK_BG);
|
||||||
|
|
||||||
// Calculate available width for text (accounting for line numbers)
|
// Calculate available width for text (accounting for line numbers)
|
||||||
int text_start_x = offset_x + 40;
|
int text_start_x = offset_x + 40;
|
||||||
|
|
@ -350,7 +350,7 @@ static void editor_paint(Window *win) {
|
||||||
|
|
||||||
// Draw the text segment
|
// Draw the text segment
|
||||||
if (segment_len > 0) {
|
if (segment_len > 0) {
|
||||||
draw_string(text_start_x, current_display_y, segment, COLOR_BLACK);
|
draw_string(text_start_x, current_display_y, segment, COLOR_DARK_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw cursor if on this line and wrapped segment
|
// Draw cursor if on this line and wrapped segment
|
||||||
|
|
@ -379,7 +379,7 @@ static void editor_paint(Window *win) {
|
||||||
|
|
||||||
// Draw status bar at bottom
|
// Draw status bar at bottom
|
||||||
draw_rect(offset_x, offset_y + content_height - 20, content_width, 20, COLOR_GRAY);
|
draw_rect(offset_x, offset_y + content_height - 20, content_width, 20, COLOR_GRAY);
|
||||||
draw_string(offset_x + 10, offset_y + content_height - 15, "Line: ", COLOR_WHITE);
|
draw_string(offset_x + 10, offset_y + content_height - 15, "Line: ", COLOR_DARK_TEXT);
|
||||||
|
|
||||||
char line_str[32];
|
char line_str[32];
|
||||||
int temp = cursor_line + 1;
|
int temp = cursor_line + 1;
|
||||||
|
|
@ -395,8 +395,8 @@ static void editor_paint(Window *win) {
|
||||||
}
|
}
|
||||||
line_str[idx] = 0;
|
line_str[idx] = 0;
|
||||||
|
|
||||||
draw_string(offset_x + 60, offset_y + content_height - 15, line_str, COLOR_WHITE);
|
draw_string(offset_x + 60, offset_y + content_height - 15, line_str, COLOR_DARK_TEXT);
|
||||||
draw_string(offset_x + 100, offset_y + content_height - 15, " Col: ", COLOR_WHITE);
|
draw_string(offset_x + 100, offset_y + content_height - 15, " Col: ", COLOR_DARK_TEXT);
|
||||||
|
|
||||||
char col_str[32];
|
char col_str[32];
|
||||||
temp = cursor_col + 1;
|
temp = cursor_col + 1;
|
||||||
|
|
@ -412,7 +412,7 @@ static void editor_paint(Window *win) {
|
||||||
}
|
}
|
||||||
col_str[idx] = 0;
|
col_str[idx] = 0;
|
||||||
|
|
||||||
draw_string(offset_x + 170, offset_y + content_height - 15, col_str, COLOR_WHITE);
|
draw_string(offset_x + 170, offset_y + content_height - 15, col_str, COLOR_DARK_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// === Key Handler ===
|
// === Key Handler ===
|
||||||
|
|
|
||||||
|
|
@ -215,8 +215,8 @@ static bool check_desktop_limit_explorer(Window *win) {
|
||||||
ExplorerState *state = (ExplorerState*)win->data;
|
ExplorerState *state = (ExplorerState*)win->data;
|
||||||
if (explorer_str_starts_with(state->current_path, "/Desktop")) {
|
if (explorer_str_starts_with(state->current_path, "/Desktop")) {
|
||||||
// Check if root desktop
|
// Check if root desktop
|
||||||
if (explorer_strcmp(state->current_path, "/Desktop") == 0 || explorer_strcmp(state->current_path, "/Desktop/") == 0) {
|
if (explorer_strcmp(state->current_path, "/Desktop") == 0 || explorer_strcmp(state->current_path, "/Desktop/") == 0) { // Check if root desktop
|
||||||
if (state->item_count >= desktop_max_cols * desktop_max_rows_per_col) {
|
if (state->item_count >= desktop_max_cols * (desktop_max_rows_per_col > 1 ? desktop_max_rows_per_col - 1 : 0)) {
|
||||||
state->dialog_state = DIALOG_ERROR;
|
state->dialog_state = DIALOG_ERROR;
|
||||||
explorer_strcpy(state->dialog_input, "Desktop is full!");
|
explorer_strcpy(state->dialog_input, "Desktop is full!");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -951,10 +951,10 @@ static void explorer_paint(Window *win) {
|
||||||
int offset_y = win->y + 24;
|
int offset_y = win->y + 24;
|
||||||
DirtyRect dirty = graphics_get_dirty_rect();
|
DirtyRect dirty = graphics_get_dirty_rect();
|
||||||
|
|
||||||
// Fill background
|
// Fill background with dark mode
|
||||||
draw_rect(offset_x, offset_y, win->w - 8, win->h - 28, COLOR_LTGRAY);
|
draw_rect(offset_x, offset_y, win->w - 8, win->h - 28, COLOR_DARK_BG);
|
||||||
|
|
||||||
// Draw Drive Button
|
// Draw Drive Button (modern rounded style)
|
||||||
char drive_label[8];
|
char drive_label[8];
|
||||||
// Extract drive from the window's current_path instead of using global current_drive
|
// Extract drive from the window's current_path instead of using global current_drive
|
||||||
char current_drv = 'A';
|
char current_drv = 'A';
|
||||||
|
|
@ -973,28 +973,32 @@ static void explorer_paint(Window *win) {
|
||||||
drive_label[6] = ' ';
|
drive_label[6] = ' ';
|
||||||
drive_label[7] = ']';
|
drive_label[7] = ']';
|
||||||
|
|
||||||
// Button at x+4, y+4, w=60
|
// Button at x+4, y+4, w=60 (rounded)
|
||||||
draw_button(win->x + 4, offset_y + 4, 60, 30, "", false);
|
draw_rounded_rect_filled(win->x + 4, offset_y + 4, 60, 30, 6, COLOR_DARK_PANEL);
|
||||||
draw_string(win->x + 12, offset_y + 12, drive_label, COLOR_BLACK);
|
draw_string(win->x + 12, offset_y + 12, drive_label, COLOR_DARK_TEXT);
|
||||||
|
|
||||||
// Draw path bar (shifted right)
|
// Draw path bar (shifted right, rounded, dark mode)
|
||||||
int path_height = 30;
|
int path_height = 30;
|
||||||
int path_x = offset_x + 64;
|
int path_x = offset_x + 64;
|
||||||
int path_w = win->w - 16 - 64;
|
int path_w = win->w - 16 - 64;
|
||||||
draw_bevel_rect(path_x, offset_y + 4, path_w, path_height, true);
|
draw_rounded_rect_filled(path_x, offset_y + 4, path_w, path_height, 6, COLOR_DARK_PANEL);
|
||||||
draw_string(path_x + 6, offset_y + 10, "Path", COLOR_BLACK);
|
draw_string(path_x + 6, offset_y + 10, "Path", COLOR_DARK_TEXT);
|
||||||
draw_string(path_x + 46, offset_y + 10, state->current_path, COLOR_BLACK);
|
draw_string(path_x + 46, offset_y + 10, state->current_path, COLOR_DARK_TEXT);
|
||||||
|
|
||||||
// Draw dropdown menu button (right-aligned, before back button)
|
// Draw dropdown menu button (right-aligned, before back button, rounded)
|
||||||
int dropdown_btn_x = win->x + win->w - 90;
|
int dropdown_btn_x = win->x + win->w - 90;
|
||||||
draw_button(dropdown_btn_x, offset_y + 4, 35, 30, "...", false);
|
draw_rounded_rect_filled(dropdown_btn_x, offset_y + 4, 35, 30, 6, COLOR_DARK_PANEL);
|
||||||
|
draw_string(dropdown_btn_x + 10, offset_y + 10, "...", COLOR_DARK_TEXT);
|
||||||
|
|
||||||
// Draw back button (right-aligned)
|
// Draw back button (right-aligned, rounded)
|
||||||
draw_button(win->x + win->w - 40, offset_y + 4, 30, 30, "<", false);
|
draw_rounded_rect_filled(win->x + win->w - 40, offset_y + 4, 30, 30, 6, COLOR_DARK_PANEL);
|
||||||
|
draw_string(win->x + win->w - 32, offset_y + 10, "<", COLOR_DARK_TEXT);
|
||||||
|
|
||||||
// Draw scroll buttons (left of dropdown)
|
// Draw scroll buttons (left of dropdown, rounded)
|
||||||
draw_button(win->x + win->w - 160, offset_y + 4, 30, 30, "^", false);
|
draw_rounded_rect_filled(win->x + win->w - 160, offset_y + 4, 30, 30, 6, COLOR_DARK_PANEL);
|
||||||
draw_button(win->x + win->w - 125, offset_y + 4, 30, 30, "v", false);
|
draw_string(win->x + win->w - 150, offset_y + 10, "^", COLOR_DARK_TEXT);
|
||||||
|
draw_rounded_rect_filled(win->x + win->w - 125, offset_y + 4, 30, 30, 6, COLOR_DARK_PANEL);
|
||||||
|
draw_string(win->x + win->w - 115, offset_y + 10, "v", COLOR_DARK_TEXT);
|
||||||
|
|
||||||
// Draw file list
|
// Draw file list
|
||||||
int content_start_y = offset_y + 40;
|
int content_start_y = offset_y + 40;
|
||||||
|
|
@ -1013,10 +1017,10 @@ static void explorer_paint(Window *win) {
|
||||||
int item_x = offset_x + 10 + (col * (EXPLORER_ITEM_WIDTH + EXPLORER_PADDING));
|
int item_x = offset_x + 10 + (col * (EXPLORER_ITEM_WIDTH + EXPLORER_PADDING));
|
||||||
int item_y = content_start_y + ((row - state->explorer_scroll_row) * (EXPLORER_ITEM_HEIGHT + EXPLORER_PADDING));
|
int item_y = content_start_y + ((row - state->explorer_scroll_row) * (EXPLORER_ITEM_HEIGHT + EXPLORER_PADDING));
|
||||||
|
|
||||||
// Draw item background
|
// Draw item background (dark mode with rounded corners)
|
||||||
uint32_t bg_color = (i == state->selected_item) ? COLOR_BLUE : COLOR_WHITE;
|
uint32_t bg_color = (i == state->selected_item) ? 0xFF4A90E2 : COLOR_DARK_PANEL;
|
||||||
draw_bevel_rect(item_x, item_y, EXPLORER_ITEM_WIDTH, EXPLORER_ITEM_HEIGHT, false);
|
uint32_t text_color = (i == state->selected_item) ? COLOR_WHITE : COLOR_DARK_TEXT;
|
||||||
draw_rect(item_x + 2, item_y + 2, EXPLORER_ITEM_WIDTH - 4, EXPLORER_ITEM_HEIGHT - 4, bg_color);
|
draw_rounded_rect_filled(item_x, item_y, EXPLORER_ITEM_WIDTH, EXPLORER_ITEM_HEIGHT, 6, bg_color);
|
||||||
|
|
||||||
// Draw icon (larger area)
|
// Draw icon (larger area)
|
||||||
explorer_draw_file_icon(item_x + 5, item_y + 5, state->items[i].is_directory, state->items[i].color, state->items[i].name);
|
explorer_draw_file_icon(item_x + 5, item_y + 5, state->items[i].is_directory, state->items[i].color, state->items[i].name);
|
||||||
|
|
@ -1026,7 +1030,7 @@ static void explorer_paint(Window *win) {
|
||||||
if (explorer_strcmp(state->items[i].name, "RecycleBin") == 0) {
|
if (explorer_strcmp(state->items[i].name, "RecycleBin") == 0) {
|
||||||
display_name = "Recycle Bin";
|
display_name = "Recycle Bin";
|
||||||
}
|
}
|
||||||
explorer_draw_icon_label(item_x, item_y, display_name, (i == state->selected_item) ? COLOR_WHITE : COLOR_BLACK);
|
explorer_draw_icon_label(item_x, item_y, display_name, text_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore dirty-rect clipping instead of clearing it entirely.
|
// Restore dirty-rect clipping instead of clearing it entirely.
|
||||||
|
|
@ -1037,7 +1041,7 @@ static void explorer_paint(Window *win) {
|
||||||
graphics_clear_clipping();
|
graphics_clear_clipping();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw Drive Menu if visible
|
// Draw Drive Menu if visible (dark mode)
|
||||||
if (state->drive_menu_visible) {
|
if (state->drive_menu_visible) {
|
||||||
int menu_x = win->x + 4;
|
int menu_x = win->x + 4;
|
||||||
int menu_y = offset_y + 34;
|
int menu_y = offset_y + 34;
|
||||||
|
|
@ -1045,8 +1049,7 @@ static void explorer_paint(Window *win) {
|
||||||
int count = disk_get_count();
|
int count = disk_get_count();
|
||||||
int menu_h = count * 25;
|
int menu_h = count * 25;
|
||||||
|
|
||||||
draw_rect(menu_x, menu_y, menu_w, menu_h, COLOR_LTGRAY);
|
draw_rounded_rect_filled(menu_x, menu_y, menu_w, menu_h, 6, COLOR_DARK_PANEL);
|
||||||
draw_bevel_rect(menu_x, menu_y, menu_w, menu_h, true);
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
Disk *d = disk_get_by_index(i);
|
Disk *d = disk_get_by_index(i);
|
||||||
|
|
@ -1059,9 +1062,9 @@ static void explorer_paint(Window *win) {
|
||||||
int n = 0; while(d->name[n] && n < 10) { buf[3+n] = d->name[n]; n++; }
|
int n = 0; while(d->name[n] && n < 10) { buf[3+n] = d->name[n]; n++; }
|
||||||
buf[3+n] = 0;
|
buf[3+n] = 0;
|
||||||
|
|
||||||
// Highlight current
|
// Highlight current (dark blue)
|
||||||
if (d->letter == current_drv) {
|
if (d->letter == current_drv) {
|
||||||
draw_rect(menu_x + 2, menu_y + i*25 + 2, menu_w - 4, 21, COLOR_BLUE);
|
draw_rounded_rect_filled(menu_x + 2, menu_y + i*25 + 2, menu_w - 4, 21, 4, 0xFF4A90E2);
|
||||||
draw_string(menu_x + 5, menu_y + i*25 + 6, buf, COLOR_WHITE);
|
draw_string(menu_x + 5, menu_y + i*25 + 6, buf, COLOR_WHITE);
|
||||||
} else {
|
} else {
|
||||||
draw_string(menu_x + 5, menu_y + i*25 + 6, buf, COLOR_BLACK);
|
draw_string(menu_x + 5, menu_y + i*25 + 6, buf, COLOR_BLACK);
|
||||||
|
|
@ -1981,7 +1984,7 @@ Window* explorer_create_window(const char *path) {
|
||||||
Window *win = (Window*)kmalloc(sizeof(Window));
|
Window *win = (Window*)kmalloc(sizeof(Window));
|
||||||
ExplorerState *state = (ExplorerState*)kmalloc(sizeof(ExplorerState));
|
ExplorerState *state = (ExplorerState*)kmalloc(sizeof(ExplorerState));
|
||||||
|
|
||||||
win->title = "File Explorer";
|
win->title = "Files";
|
||||||
win->x = 300 + (explorer_win_count * 30);
|
win->x = 300 + (explorer_win_count * 30);
|
||||||
win->y = 100 + (explorer_win_count * 30);
|
win->y = 100 + (explorer_win_count * 30);
|
||||||
win->w = 600;
|
win->w = 600;
|
||||||
|
|
@ -2014,7 +2017,7 @@ Window* explorer_create_window(const char *path) {
|
||||||
|
|
||||||
void explorer_init(void) {
|
void explorer_init(void) {
|
||||||
ExplorerState *state = (ExplorerState*)kmalloc(sizeof(ExplorerState));
|
ExplorerState *state = (ExplorerState*)kmalloc(sizeof(ExplorerState));
|
||||||
win_explorer.title = "File Explorer";
|
win_explorer.title = "Files";
|
||||||
win_explorer.x = 300;
|
win_explorer.x = 300;
|
||||||
win_explorer.y = 100;
|
win_explorer.y = 100;
|
||||||
win_explorer.w = 600;
|
win_explorer.w = 600;
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,81 @@ void draw_rect(int x, int y, int w, int h, uint32_t color) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simple integer-based square root approximation
|
||||||
|
static int isqrt(int n) {
|
||||||
|
if (n < 0) return 0;
|
||||||
|
if (n == 0) return 0;
|
||||||
|
int x = n;
|
||||||
|
int y = (x + 1) / 2;
|
||||||
|
while (y < x) {
|
||||||
|
x = y;
|
||||||
|
y = (x + n / x) / 2;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw rounded rectangle outline
|
||||||
|
void draw_rounded_rect(int x, int y, int w, int h, int radius, uint32_t color) {
|
||||||
|
if (radius > w / 2) radius = w / 2;
|
||||||
|
if (radius > h / 2) radius = h / 2;
|
||||||
|
if (radius < 1) radius = 1;
|
||||||
|
|
||||||
|
// Draw top and bottom edges
|
||||||
|
draw_rect(x + radius, y, w - 2*radius, 1, color);
|
||||||
|
draw_rect(x + radius, y + h - 1, w - 2*radius, 1, color);
|
||||||
|
|
||||||
|
// Draw left and right edges
|
||||||
|
draw_rect(x, y + radius, 1, h - 2*radius, color);
|
||||||
|
draw_rect(x + w - 1, y + radius, 1, h - 2*radius, color);
|
||||||
|
|
||||||
|
// Draw corner circles using integer approximation
|
||||||
|
for (int i = 0; i < radius; i++) {
|
||||||
|
int j = isqrt(radius*radius - i*i);
|
||||||
|
|
||||||
|
// Top-left corner
|
||||||
|
put_pixel(x + radius - i - 1, y + radius - j, color);
|
||||||
|
// Top-right corner
|
||||||
|
put_pixel(x + w - radius + i, y + radius - j, color);
|
||||||
|
// Bottom-left corner
|
||||||
|
put_pixel(x + radius - i - 1, y + h - radius + j - 1, color);
|
||||||
|
// Bottom-right corner
|
||||||
|
put_pixel(x + w - radius + i, y + h - radius + j - 1, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw filled rounded rectangle
|
||||||
|
void draw_rounded_rect_filled(int x, int y, int w, int h, int radius, uint32_t color) {
|
||||||
|
if (radius > w / 2) radius = w / 2;
|
||||||
|
if (radius > h / 2) radius = h / 2;
|
||||||
|
if (radius < 1) radius = 1;
|
||||||
|
|
||||||
|
// Draw main rectangle body (center part without corners)
|
||||||
|
draw_rect(x + radius, y, w - 2*radius, h, color);
|
||||||
|
draw_rect(x, y + radius, radius, h - 2*radius, color);
|
||||||
|
draw_rect(x + w - radius, y + radius, radius, h - 2*radius, color);
|
||||||
|
|
||||||
|
// Draw rounded corners using scanline approach (fills gaps properly)
|
||||||
|
for (int dy = 0; dy < radius; dy++) {
|
||||||
|
// For top corners: distance formula inverted (narrow at top, wide at junction)
|
||||||
|
int dx_top = isqrt(radius*radius - (radius - dy) * (radius - dy));
|
||||||
|
|
||||||
|
// For bottom corners: distance formula normal (wide at junction, narrow at bottom)
|
||||||
|
int dx_bottom = isqrt(radius*radius - dy*dy);
|
||||||
|
|
||||||
|
// Top-left corner - horizontal scanline
|
||||||
|
draw_rect(x + radius - dx_top, y + dy, dx_top, 1, color);
|
||||||
|
|
||||||
|
// Top-right corner - horizontal scanline
|
||||||
|
draw_rect(x + w - radius, y + dy, dx_top, 1, color);
|
||||||
|
|
||||||
|
// Bottom-left corner - horizontal scanline
|
||||||
|
draw_rect(x + radius - dx_bottom, y + h - radius + dy, dx_bottom, 1, color);
|
||||||
|
|
||||||
|
// Bottom-right corner - horizontal scanline
|
||||||
|
draw_rect(x + w - radius, y + h - radius + dy, dx_bottom, 1, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void draw_char(int x, int y, char c, uint32_t color) {
|
void draw_char(int x, int y, char c, uint32_t color) {
|
||||||
unsigned char uc = (unsigned char)c;
|
unsigned char uc = (unsigned char)c;
|
||||||
if (uc > 127) return;
|
if (uc > 127) return;
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ typedef struct {
|
||||||
void graphics_init(struct limine_framebuffer *fb);
|
void graphics_init(struct limine_framebuffer *fb);
|
||||||
void put_pixel(int x, int y, uint32_t color);
|
void put_pixel(int x, int y, uint32_t color);
|
||||||
void draw_rect(int x, int y, int w, int h, uint32_t color);
|
void draw_rect(int x, int y, int w, int h, uint32_t color);
|
||||||
|
void draw_rounded_rect(int x, int y, int w, int h, int radius, uint32_t color);
|
||||||
|
void draw_rounded_rect_filled(int x, int y, int w, int h, int radius, uint32_t color);
|
||||||
void draw_char(int x, int y, char c, uint32_t color);
|
void draw_char(int x, int y, char c, uint32_t color);
|
||||||
void draw_string(int x, int y, const char *s, uint32_t color);
|
void draw_string(int x, int y, const char *s, uint32_t color);
|
||||||
void draw_desktop_background(void);
|
void draw_desktop_background(void);
|
||||||
|
|
|
||||||
|
|
@ -288,16 +288,18 @@ static void md_paint(Window *win) {
|
||||||
int content_width = win->w - 8;
|
int content_width = win->w - 8;
|
||||||
int content_height = win->h - 28;
|
int content_height = win->h - 28;
|
||||||
|
|
||||||
// Draw filename bar below title
|
// Draw filename bar below title (dark mode)
|
||||||
draw_rect(offset_x, offset_y, content_width, 20, COLOR_GRAY);
|
draw_rounded_rect_filled(offset_x, offset_y, content_width, 20, 6, COLOR_DARK_PANEL);
|
||||||
draw_string(offset_x + 4, offset_y + 4, "File", COLOR_BLACK);
|
draw_string(offset_x + 4, offset_y + 4, "File", COLOR_DARK_TEXT);
|
||||||
draw_string(offset_x + 50, offset_y + 4, open_filename, COLOR_BLACK);
|
draw_string(offset_x + 50, offset_y + 4, open_filename, COLOR_DARK_TEXT);
|
||||||
|
|
||||||
// Draw scroll buttons on top right
|
// Draw scroll buttons on top right with rounded style
|
||||||
int btn_x_up = offset_x + content_width - 50;
|
int btn_x_up = offset_x + content_width - 50;
|
||||||
int btn_y = offset_y + 2;
|
int btn_y = offset_y + 2;
|
||||||
draw_button(btn_x_up, btn_y, 20, 16, "^", false);
|
draw_rounded_rect_filled(btn_x_up, btn_y, 20, 16, 4, COLOR_DARK_TITLEBAR);
|
||||||
draw_button(btn_x_up + 24, btn_y, 20, 16, "v", false);
|
draw_string(btn_x_up + 6, btn_y, "^", COLOR_DARK_TEXT);
|
||||||
|
draw_rounded_rect_filled(btn_x_up + 24, btn_y, 20, 16, 4, COLOR_DARK_TITLEBAR);
|
||||||
|
draw_string(btn_x_up + 30, btn_y, "v", COLOR_DARK_TEXT);
|
||||||
|
|
||||||
// Content area - starts below filename bar
|
// Content area - starts below filename bar
|
||||||
int content_start_y = offset_y + 24;
|
int content_start_y = offset_y + 24;
|
||||||
|
|
@ -306,8 +308,8 @@ static void md_paint(Window *win) {
|
||||||
int usable_content_height = content_height - 28;
|
int usable_content_height = content_height - 28;
|
||||||
int max_display_lines = usable_content_height / MD_LINE_HEIGHT;
|
int max_display_lines = usable_content_height / MD_LINE_HEIGHT;
|
||||||
|
|
||||||
// Draw content background
|
// Draw content background (dark mode)
|
||||||
draw_rect(win->x + 4, content_start_y, win->w - 24, usable_content_height, COLOR_WHITE);
|
draw_rounded_rect_filled(win->x + 4, content_start_y, win->w - 24, usable_content_height, 6, COLOR_DARK_BG);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -317,38 +319,38 @@ static void md_paint(Window *win) {
|
||||||
while (i < line_count && display_line < max_display_lines) {
|
while (i < line_count && display_line < max_display_lines) {
|
||||||
MDLine *line = &lines[i];
|
MDLine *line = &lines[i];
|
||||||
|
|
||||||
// Determine spacing and text properties based on heading level
|
// Determine spacing and text properties based on heading level (dark mode colors)
|
||||||
int line_height = MD_LINE_HEIGHT;
|
int line_height = MD_LINE_HEIGHT;
|
||||||
int extra_spacing = 0;
|
int extra_spacing = 0;
|
||||||
uint32_t text_color = COLOR_BLACK;
|
uint32_t text_color = COLOR_DARK_TEXT;
|
||||||
bool use_bold = false;
|
bool use_bold = false;
|
||||||
|
|
||||||
switch (line->type) {
|
switch (line->type) {
|
||||||
case MD_LINE_HEADING1:
|
case MD_LINE_HEADING1:
|
||||||
line_height = MD_LINE_HEIGHT * 2; // Double height
|
line_height = MD_LINE_HEIGHT * 2; // Double height
|
||||||
text_color = 0xFF004080; // Dark blue
|
text_color = 0xFF87CEEB; // Light blue
|
||||||
use_bold = true;
|
use_bold = true;
|
||||||
extra_spacing = 4;
|
extra_spacing = 4;
|
||||||
break;
|
break;
|
||||||
case MD_LINE_HEADING2:
|
case MD_LINE_HEADING2:
|
||||||
line_height = MD_LINE_HEIGHT + 6; // 1.5x height
|
line_height = MD_LINE_HEIGHT + 6; // 1.5x height
|
||||||
text_color = 0xFF1060A0; // Medium blue
|
text_color = 0xFF4A90E2; // Medium blue
|
||||||
use_bold = true;
|
use_bold = true;
|
||||||
extra_spacing = 2;
|
extra_spacing = 2;
|
||||||
break;
|
break;
|
||||||
case MD_LINE_HEADING3:
|
case MD_LINE_HEADING3:
|
||||||
line_height = MD_LINE_HEIGHT + 2; // Slightly larger
|
line_height = MD_LINE_HEIGHT + 2; // Slightly larger
|
||||||
text_color = 0xFF2080C0; // Light blue
|
text_color = 0xFF87CEEB; // Light blue
|
||||||
use_bold = false;
|
use_bold = false;
|
||||||
break;
|
break;
|
||||||
case MD_LINE_BLOCKQUOTE:
|
case MD_LINE_BLOCKQUOTE:
|
||||||
text_color = 0xFF808080; // Gray
|
text_color = 0xFFA0A0A0; // Light gray
|
||||||
break;
|
break;
|
||||||
case MD_LINE_CODE:
|
case MD_LINE_CODE:
|
||||||
text_color = COLOR_WHITE;
|
text_color = 0xFF90EE90; // Light green for code
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
text_color = COLOR_BLACK;
|
text_color = COLOR_DARK_TEXT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -151,21 +151,21 @@ static void minesweeper_right_click(Window *win, int x, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void minesweeper_paint(Window *win) {
|
static void minesweeper_paint(Window *win) {
|
||||||
// Background
|
// Background - dark mode
|
||||||
draw_rect(win->x + 4, win->y + 24, win->w - 8, win->h - 28, COLOR_LTGRAY);
|
draw_rect(win->x + 4, win->y + 30, win->w - 8, win->h - 34, COLOR_DARK_BG);
|
||||||
|
|
||||||
// Game status
|
// Game status
|
||||||
if (game_over) {
|
if (game_over) {
|
||||||
draw_string(win->x + 10, win->y + 30, "Game Over!", COLOR_RED);
|
draw_string(win->x + 10, win->y + 36, "Game Over!", COLOR_TRAFFIC_RED);
|
||||||
} else if (game_won) {
|
} else if (game_won) {
|
||||||
draw_string(win->x + 10, win->y + 30, "You Won!", COLOR_BLUE);
|
draw_string(win->x + 10, win->y + 36, "You Won!", 0xFF00FF00); // Bright green
|
||||||
} else {
|
} else {
|
||||||
draw_string(win->x + 10, win->y + 30, "", COLOR_BLACK);
|
draw_string(win->x + 10, win->y + 36, "", COLOR_DARK_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw grid
|
// Draw grid
|
||||||
int grid_start_x = win->x + 10;
|
int grid_start_x = win->x + 10;
|
||||||
int grid_start_y = win->y + 50;
|
int grid_start_y = win->y + 56;
|
||||||
|
|
||||||
for (int y = 0; y < GRID_HEIGHT; y++) {
|
for (int y = 0; y < GRID_HEIGHT; y++) {
|
||||||
for (int x = 0; x < GRID_WIDTH; x++) {
|
for (int x = 0; x < GRID_WIDTH; x++) {
|
||||||
|
|
@ -173,32 +173,33 @@ static void minesweeper_paint(Window *win) {
|
||||||
int py = grid_start_y + y * CELL_SIZE;
|
int py = grid_start_y + y * CELL_SIZE;
|
||||||
|
|
||||||
if (revealed[y][x]) {
|
if (revealed[y][x]) {
|
||||||
// Revealed cell - sunken
|
// Revealed cell - dark mode
|
||||||
draw_bevel_rect(px, py, CELL_SIZE, CELL_SIZE, true);
|
draw_rounded_rect_filled(px, py, CELL_SIZE, CELL_SIZE, 2, COLOR_DARK_PANEL);
|
||||||
|
|
||||||
if (grid[y][x] == -1) {
|
if (grid[y][x] == -1) {
|
||||||
// Mine
|
// Mine
|
||||||
draw_string(px + 8, py + 6, "*", COLOR_RED);
|
draw_string(px + 8, py + 6, "*", COLOR_TRAFFIC_RED);
|
||||||
} else if (grid[y][x] > 0) {
|
} else if (grid[y][x] > 0) {
|
||||||
// Number
|
// Number
|
||||||
char num[2] = { '0' + grid[y][x], 0 };
|
char num[2] = { '0' + grid[y][x], 0 };
|
||||||
draw_string(px + 8, py + 6, num, COLOR_BLACK);
|
draw_string(px + 8, py + 6, num, COLOR_DARK_TEXT);
|
||||||
}
|
}
|
||||||
// 0 = empty, nothing to draw
|
// 0 = empty, nothing to draw
|
||||||
} else {
|
} else {
|
||||||
// Unrevealed cell - raised
|
// Unrevealed cell - raised/button look
|
||||||
draw_bevel_rect(px, py, CELL_SIZE, CELL_SIZE, false);
|
draw_rounded_rect_filled(px, py, CELL_SIZE, CELL_SIZE, 2, COLOR_DARK_BORDER);
|
||||||
|
|
||||||
if (flagged[y][x]) {
|
if (flagged[y][x]) {
|
||||||
draw_string(px + 7, py + 6, "F", COLOR_RED);
|
draw_string(px + 7, py + 6, "F", COLOR_TRAFFIC_RED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw new game button
|
// Draw new game button (narrower, less dead space)
|
||||||
int btn_y = grid_start_y + GRID_HEIGHT * CELL_SIZE + 10;
|
int btn_y = grid_start_y + GRID_HEIGHT * CELL_SIZE + 10;
|
||||||
draw_button(grid_start_x, btn_y, 90, 24, "New Game", false);
|
draw_rounded_rect_filled(grid_start_x, btn_y, 70, 24, 4, COLOR_DARK_BORDER);
|
||||||
|
draw_string(grid_start_x + 6, btn_y + 8, "New Game", COLOR_DARK_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void minesweeper_click(Window *win, int x, int y) {
|
static void minesweeper_click(Window *win, int x, int y) {
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,12 @@ static void notepad_ensure_cursor_visible(Window *win) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void notepad_paint(Window *win) {
|
static void notepad_paint(Window *win) {
|
||||||
// Explicitly draw white background for text
|
// Dark mode background for text
|
||||||
draw_rect(win->x + 4, win->y + 24, win->w - 8, win->h - 28, COLOR_WHITE);
|
draw_rect(win->x + 4, win->y + 30, win->w - 8, win->h - 34, COLOR_DARK_BG);
|
||||||
|
|
||||||
int visual_line = 0;
|
int visual_line = 0;
|
||||||
int current_x = win->x + 8;
|
int current_x = win->x + 8;
|
||||||
int current_y = win->y + 30;
|
int current_y = win->y + 36;
|
||||||
int window_right = win->x + win->w - 16;
|
int window_right = win->x + win->w - 16;
|
||||||
|
|
||||||
for (int i = 0; i < win->buf_len; i++) {
|
for (int i = 0; i < win->buf_len; i++) {
|
||||||
|
|
@ -37,7 +37,7 @@ static void notepad_paint(Window *win) {
|
||||||
if (win->buffer[i] == '\n') {
|
if (win->buffer[i] == '\n') {
|
||||||
visual_line++;
|
visual_line++;
|
||||||
current_x = win->x + 8;
|
current_x = win->x + 8;
|
||||||
current_y = win->y + 30;
|
current_y = win->y + 36;
|
||||||
} else {
|
} else {
|
||||||
if (current_x >= window_right) {
|
if (current_x >= window_right) {
|
||||||
visual_line++;
|
visual_line++;
|
||||||
|
|
@ -69,7 +69,7 @@ static void notepad_paint(Window *win) {
|
||||||
}
|
}
|
||||||
|
|
||||||
char ch[2] = {win->buffer[i], 0};
|
char ch[2] = {win->buffer[i], 0};
|
||||||
draw_string(current_x, current_y, ch, COLOR_BLACK);
|
draw_string(current_x, current_y, ch, COLOR_DARK_TEXT);
|
||||||
current_x += 8;
|
current_x += 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -77,7 +77,7 @@ static void notepad_paint(Window *win) {
|
||||||
// Cursor
|
// Cursor
|
||||||
if (win->focused) {
|
if (win->focused) {
|
||||||
int cx = win->x + 8;
|
int cx = win->x + 8;
|
||||||
int cy = win->y + 30;
|
int cy = win->y + 36;
|
||||||
int visual_line = 0;
|
int visual_line = 0;
|
||||||
int window_right = win->x + win->w - 16; // Right boundary with padding
|
int window_right = win->x + win->w - 16; // Right boundary with padding
|
||||||
|
|
||||||
|
|
@ -98,7 +98,7 @@ static void notepad_paint(Window *win) {
|
||||||
|
|
||||||
if (visual_line >= notepad_scroll_line &&
|
if (visual_line >= notepad_scroll_line &&
|
||||||
visual_line < notepad_scroll_line + (win->h - 40) / 10) {
|
visual_line < notepad_scroll_line + (win->h - 40) / 10) {
|
||||||
draw_rect(cx, cy, 2, 8, COLOR_BLACK);
|
draw_rect(cx, cy, 2, 8, COLOR_DARK_TEXT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,35 +21,32 @@ static void paint_strcpy(char *dest, const char *src) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void paint_paint(Window *win) {
|
static void paint_paint(Window *win) {
|
||||||
// Toolbar area
|
// Toolbar area - dark mode
|
||||||
draw_rect(win->x + 10, win->y + 30, 40, win->h - 40, COLOR_GRAY);
|
draw_rounded_rect_filled(win->x + 10, win->y + 30, 40, win->h - 40, 6, COLOR_DARK_PANEL);
|
||||||
draw_bevel_rect(win->x + 10, win->y + 30, 40, win->h - 40, true);
|
|
||||||
|
|
||||||
// Color Palette
|
// Color Palette with rounded corners
|
||||||
uint32_t colors[] = {COLOR_BLACK, COLOR_RED, COLOR_APPLE_GREEN, COLOR_APPLE_BLUE, COLOR_APPLE_YELLOW, COLOR_WHITE};
|
uint32_t colors[] = {COLOR_BLACK, COLOR_RED, COLOR_APPLE_GREEN, COLOR_APPLE_BLUE, COLOR_APPLE_YELLOW, COLOR_WHITE};
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
int cy = win->y + 40 + (i * 25);
|
int cy = win->y + 40 + (i * 25);
|
||||||
draw_rect(win->x + 15, cy, 30, 20, colors[i]);
|
draw_rounded_rect_filled(win->x + 15, cy, 30, 20, 3, colors[i]);
|
||||||
draw_rect(win->x + 15, cy, 30, 1, COLOR_BLACK);
|
|
||||||
draw_rect(win->x + 15, cy, 1, 20, COLOR_BLACK);
|
|
||||||
draw_rect(win->x + 44, cy, 1, 20, COLOR_BLACK);
|
|
||||||
draw_rect(win->x + 15, cy + 19, 30, 1, COLOR_BLACK);
|
|
||||||
|
|
||||||
// Highlight selected color
|
// Highlight selected color with border
|
||||||
if (current_color == colors[i]) {
|
if (current_color == colors[i]) {
|
||||||
draw_rect(win->x + 13, cy - 2, 34, 2, COLOR_WHITE);
|
draw_rounded_rect(win->x + 13, cy - 2, 34, 24, 4, COLOR_DARK_TEXT);
|
||||||
draw_rect(win->x + 13, cy + 20, 34, 2, COLOR_WHITE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toolbar Buttons
|
// Toolbar Buttons - dark mode with rounded corners
|
||||||
draw_button(win->x + 12, win->y + win->h - 65, 36, 20, "CLR", false);
|
draw_rounded_rect_filled(win->x + 12, win->y + win->h - 65, 36, 20, 4, COLOR_DARK_BORDER);
|
||||||
draw_button(win->x + 12, win->y + win->h - 40, 36, 20, "SAV", false);
|
draw_string(win->x + 18, win->y + win->h - 58, "CLR", COLOR_DARK_TEXT);
|
||||||
|
|
||||||
|
draw_rounded_rect_filled(win->x + 12, win->y + win->h - 40, 36, 20, 4, COLOR_DARK_BORDER);
|
||||||
|
draw_string(win->x + 18, win->y + win->h - 33, "SAV", COLOR_DARK_TEXT);
|
||||||
|
|
||||||
// Canvas Area
|
// Canvas Area with dark background and rounded corners
|
||||||
int canvas_x = win->x + 60;
|
int canvas_x = win->x + 60;
|
||||||
int canvas_y = win->y + 30;
|
int canvas_y = win->y + 30;
|
||||||
draw_bevel_rect(canvas_x - 2, canvas_y - 2, CANVAS_W + 4, CANVAS_H + 4, true);
|
draw_rounded_rect_filled(canvas_x - 2, canvas_y - 2, CANVAS_W + 4, CANVAS_H + 4, 4, COLOR_DARK_BG);
|
||||||
|
|
||||||
if (canvas_buffer) {
|
if (canvas_buffer) {
|
||||||
for (int y = 0; y < CANVAS_H; y++) {
|
for (int y = 0; y < CANVAS_H; y++) {
|
||||||
|
|
|
||||||
344
src/kernel/wm.c
344
src/kernel/wm.c
|
|
@ -124,7 +124,7 @@ static int str_eq(const char *s1, const char *s2) {
|
||||||
|
|
||||||
static void refresh_desktop_icons(void) {
|
static void refresh_desktop_icons(void) {
|
||||||
// Update limit in FS
|
// Update limit in FS
|
||||||
fat32_set_desktop_limit(desktop_max_cols * desktop_max_rows_per_col);
|
fat32_set_desktop_limit(desktop_max_cols * (desktop_max_rows_per_col > 1 ? desktop_max_rows_per_col - 1 : 0));
|
||||||
|
|
||||||
FAT32_FileInfo *files = (FAT32_FileInfo*)kmalloc(MAX_DESKTOP_ICONS * sizeof(FAT32_FileInfo));
|
FAT32_FileInfo *files = (FAT32_FileInfo*)kmalloc(MAX_DESKTOP_ICONS * sizeof(FAT32_FileInfo));
|
||||||
if (!files) return;
|
if (!files) return;
|
||||||
|
|
@ -184,8 +184,8 @@ static void refresh_desktop_icons(void) {
|
||||||
|
|
||||||
// 3. Layout Icons
|
// 3. Layout Icons
|
||||||
if (desktop_auto_align) {
|
if (desktop_auto_align) {
|
||||||
int start_x = 20;
|
int start_x = 20; // Starting X position for icons
|
||||||
int start_y = 20;
|
int start_y = 20 + DESKTOP_TOP_DEADSPACE_HEIGHT; // Starting Y position for icons, offset by dead space
|
||||||
int grid_x = 0;
|
int grid_x = 0;
|
||||||
int grid_y = 0;
|
int grid_y = 0;
|
||||||
|
|
||||||
|
|
@ -200,8 +200,8 @@ static void refresh_desktop_icons(void) {
|
||||||
|
|
||||||
// Place Recycle Bin at bottom-right of grid
|
// Place Recycle Bin at bottom-right of grid
|
||||||
if (recycle_idx != -1) {
|
if (recycle_idx != -1) {
|
||||||
desktop_icons[recycle_idx].x = start_x + (desktop_max_cols - 1) * 80;
|
desktop_icons[recycle_idx].x = start_x + (desktop_max_cols - 1) * 80; // Align to the last column
|
||||||
desktop_icons[recycle_idx].y = start_y + (desktop_max_rows_per_col - 1) * 80;
|
desktop_icons[recycle_idx].y = start_y + (desktop_max_rows_per_col - 2) * 80; // Align to the second to last row (since one is dead space)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < desktop_icon_count; i++) {
|
for (int i = 0; i < desktop_icon_count; i++) {
|
||||||
|
|
@ -210,7 +210,7 @@ static void refresh_desktop_icons(void) {
|
||||||
desktop_icons[i].x = start_x + (grid_x * 80);
|
desktop_icons[i].x = start_x + (grid_x * 80);
|
||||||
desktop_icons[i].y = start_y + (grid_y * 80);
|
desktop_icons[i].y = start_y + (grid_y * 80);
|
||||||
|
|
||||||
grid_y++;
|
grid_y++; // Increment grid_y for the next icon
|
||||||
if (grid_y >= desktop_max_rows_per_col) {
|
if (grid_y >= desktop_max_rows_per_col) {
|
||||||
grid_y = 0;
|
grid_y = 0;
|
||||||
grid_x++;
|
grid_x++;
|
||||||
|
|
@ -224,7 +224,7 @@ static void refresh_desktop_icons(void) {
|
||||||
if (desktop_icons[i].x != -1) {
|
if (desktop_icons[i].x != -1) {
|
||||||
int col = (desktop_icons[i].x - 20) / 80;
|
int col = (desktop_icons[i].x - 20) / 80;
|
||||||
int row = (desktop_icons[i].y - 20) / 80;
|
int row = (desktop_icons[i].y - 20) / 80;
|
||||||
if (col >= 0 && col < 16 && row >= 0 && row < 16) occupied[col][row] = true;
|
if (col >= 0 && col < 16 && row >= 0 && row < 16) occupied[col][row] = true; // Mark occupied cells
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -233,13 +233,13 @@ static void refresh_desktop_icons(void) {
|
||||||
int found_col = -1, found_row = -1;
|
int found_col = -1, found_row = -1;
|
||||||
for (int c = 0; c < 16; c++) {
|
for (int c = 0; c < 16; c++) {
|
||||||
for (int r = 0; r < desktop_max_rows_per_col; r++) {
|
for (int r = 0; r < desktop_max_rows_per_col; r++) {
|
||||||
if (!occupied[c][r]) {
|
if (!occupied[c][r] && r > 0) { // Ensure not in the dead space row
|
||||||
found_col = c; found_row = r;
|
found_col = c; found_row = r;
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
found:
|
found:
|
||||||
if (found_col != -1) {
|
if (found_col != -1) {
|
||||||
desktop_icons[i].x = 20 + found_col * 80;
|
desktop_icons[i].x = 20 + found_col * 80;
|
||||||
desktop_icons[i].y = 20 + found_row * 80;
|
desktop_icons[i].y = 20 + found_row * 80;
|
||||||
|
|
@ -563,22 +563,62 @@ void draw_paint_icon(int x, int y, const char *label) {
|
||||||
draw_icon_label(x, y, label);
|
draw_icon_label(x, y, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New macOS-style drawing functions
|
||||||
|
|
||||||
|
// Draw traffic light (close button - red)
|
||||||
|
void draw_traffic_light(int x, int y) {
|
||||||
|
// Red close button
|
||||||
|
draw_rounded_rect_filled(x, y, 12, 12, 3, COLOR_TRAFFIC_RED);
|
||||||
|
// X mark
|
||||||
|
draw_rect(x + 4, y + 4, 1, 4, COLOR_WHITE); // Vertical
|
||||||
|
draw_rect(x + 5, y + 5, 1, 1, COLOR_WHITE);
|
||||||
|
draw_rect(x + 5, y + 6, 1, 1, COLOR_WHITE);
|
||||||
|
draw_rect(x + 6, y + 5, 1, 2, COLOR_WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a squircle-style app icon
|
||||||
|
void draw_squircle_icon(int x, int y, const char *label, uint32_t bg_color) {
|
||||||
|
// Simplified squircle using rounded rectangle
|
||||||
|
draw_rounded_rect_filled(x + 12, y, 56, 56, 12, bg_color);
|
||||||
|
draw_icon_label(x, y + 60, label);
|
||||||
|
}
|
||||||
|
|
||||||
|
// macOS Files icon (folder style)
|
||||||
|
void draw_files_icon(int x, int y, const char *label) {
|
||||||
|
// Blue folder icon with macOS styling
|
||||||
|
draw_rounded_rect_filled(x + 27, y + 6, 25, 15, 3, 0xFF4A90E2); // Blue color
|
||||||
|
draw_squircle_icon(x, y, label, 0xFF4A90E2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// macOS Settings/Gear icon
|
||||||
|
void draw_settings_icon(int x, int y, const char *label) {
|
||||||
|
// Gear icon with dark background
|
||||||
|
draw_squircle_icon(x, y, label, 0xFF666666);
|
||||||
|
// Simple gear shape in the middle of squircle
|
||||||
|
int cx = x + 12 + 28;
|
||||||
|
int cy = y + 28;
|
||||||
|
draw_rect(cx - 2, cy - 2, 4, 4, COLOR_WHITE); // Center
|
||||||
|
}
|
||||||
|
|
||||||
void draw_window(Window *win) {
|
void draw_window(Window *win) {
|
||||||
if (!win->visible) return;
|
if (!win->visible) return;
|
||||||
|
|
||||||
// Main Body
|
// Dark mode window with rounded corners
|
||||||
draw_bevel_rect(win->x, win->y, win->w, win->h, false);
|
// Border/Shadow effect
|
||||||
|
draw_rounded_rect_filled(win->x - 1, win->y - 1, win->w + 2, win->h + 2, 8, 0xFF000000);
|
||||||
|
|
||||||
|
// Main window body
|
||||||
|
draw_rounded_rect_filled(win->x, win->y, win->w, win->h, 8, COLOR_DARK_PANEL);
|
||||||
|
|
||||||
// Title Bar
|
// Title Bar
|
||||||
uint32_t title_color = win->focused ? COLOR_RED : COLOR_DKGRAY;
|
draw_rounded_rect_filled(win->x, win->y, win->w, 22, 8, COLOR_DARK_TITLEBAR);
|
||||||
draw_rect(win->x + 3, win->y + 3, win->w - 6, 18, title_color);
|
draw_string(win->x + 28, win->y + 7, win->title, COLOR_DARK_TEXT);
|
||||||
draw_string(win->x + 8, win->y + 8, win->title, COLOR_WHITE);
|
|
||||||
|
|
||||||
// Close Button (X)
|
// Traffic Light (close button - red)
|
||||||
draw_button(win->x + win->w - 20, win->y + 5, 14, 14, "X", false);
|
draw_traffic_light(win->x + 8, win->y + 5);
|
||||||
|
|
||||||
// Client Area
|
// Client Area with dark background (no rounding)
|
||||||
draw_rect(win->x + 4, win->y + 24, win->w - 8, win->h - 28, COLOR_LTGRAY);
|
draw_rect(win->x, win->y + 22, win->w, win->h - 22, COLOR_DARK_BG);
|
||||||
|
|
||||||
if (win->paint) {
|
if (win->paint) {
|
||||||
win->paint(win);
|
win->paint(win);
|
||||||
|
|
@ -665,7 +705,7 @@ static void draw_clock(int x, int y) {
|
||||||
buf[7] = '0' + (s % 10);
|
buf[7] = '0' + (s % 10);
|
||||||
buf[8] = 0;
|
buf[8] = 0;
|
||||||
|
|
||||||
draw_string(x, y, buf, COLOR_BLACK);
|
draw_string(x, y, buf, COLOR_WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Main Paint Function ---
|
// --- Main Paint Function ---
|
||||||
|
|
@ -673,7 +713,6 @@ void wm_paint(void) {
|
||||||
int sw = get_screen_width();
|
int sw = get_screen_width();
|
||||||
int sh = get_screen_height();
|
int sh = get_screen_height();
|
||||||
|
|
||||||
|
|
||||||
DirtyRect dirty = graphics_get_dirty_rect();
|
DirtyRect dirty = graphics_get_dirty_rect();
|
||||||
if (dirty.active) {
|
if (dirty.active) {
|
||||||
graphics_set_clipping(dirty.x, dirty.y, dirty.w, dirty.h);
|
graphics_set_clipping(dirty.x, dirty.y, dirty.w, dirty.h);
|
||||||
|
|
@ -681,8 +720,8 @@ void wm_paint(void) {
|
||||||
graphics_clear_clipping();
|
graphics_clear_clipping();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. Desktop
|
// 1. Desktop Background (dark mode)
|
||||||
draw_desktop_background();
|
draw_rect(0, 0, sw, sh, COLOR_DARK_BG);
|
||||||
|
|
||||||
// Draw Desktop Icons
|
// Draw Desktop Icons
|
||||||
for (int i = 0; i < desktop_icon_count; i++) {
|
for (int i = 0; i < desktop_icon_count; i++) {
|
||||||
|
|
@ -695,12 +734,11 @@ void wm_paint(void) {
|
||||||
}
|
}
|
||||||
if (icon->type == 1) draw_folder_icon(icon->x, icon->y, icon->name);
|
if (icon->type == 1) draw_folder_icon(icon->x, icon->y, icon->name);
|
||||||
else if (icon->type == 2) {
|
else if (icon->type == 2) {
|
||||||
// App icon - strip .app for display
|
// App icon - strip .shortcut for display
|
||||||
char label[64];
|
char label[64];
|
||||||
int len = 0;
|
int len = 0;
|
||||||
while(icon->name[len] && len < 63) { label[len] = icon->name[len]; len++; }
|
while(icon->name[len] && len < 63) { label[len] = icon->name[len]; len++; }
|
||||||
label[len] = 0;
|
label[len] = 0;
|
||||||
// Remove .app suffix if present
|
|
||||||
if (len > 9 && str_ends_with(label, ".shortcut")) {
|
if (len > 9 && str_ends_with(label, ".shortcut")) {
|
||||||
label[len-9] = 0;
|
label[len-9] = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -709,17 +747,17 @@ void wm_paint(void) {
|
||||||
else if (str_starts_with(icon->name, "Calculator")) draw_calculator_icon(icon->x, icon->y, label);
|
else if (str_starts_with(icon->name, "Calculator")) draw_calculator_icon(icon->x, icon->y, label);
|
||||||
else if (str_starts_with(icon->name, "Terminal")) draw_terminal_icon(icon->x, icon->y, label);
|
else if (str_starts_with(icon->name, "Terminal")) draw_terminal_icon(icon->x, icon->y, label);
|
||||||
else if (str_starts_with(icon->name, "Minesweeper")) draw_minesweeper_icon(icon->x, icon->y, label);
|
else if (str_starts_with(icon->name, "Minesweeper")) draw_minesweeper_icon(icon->x, icon->y, label);
|
||||||
else if (str_starts_with(icon->name, "Control Panel")) draw_control_panel_icon(icon->x, icon->y, label);
|
else if (str_starts_with(icon->name, "Settings")) draw_settings_icon(icon->x, icon->y, label);
|
||||||
else if (str_starts_with(icon->name, "About")) draw_about_icon(icon->x, icon->y, label);
|
else if (str_starts_with(icon->name, "About")) draw_about_icon(icon->x, icon->y, label);
|
||||||
else if (str_starts_with(icon->name, "Recycle Bin")) draw_recycle_bin_icon(icon->x, icon->y, label);
|
else if (str_starts_with(icon->name, "Recycle Bin")) draw_recycle_bin_icon(icon->x, icon->y, label);
|
||||||
else if (str_starts_with(icon->name, "Explorer")) draw_folder_icon(icon->x, icon->y, label);
|
else if (str_starts_with(icon->name, "Files")) draw_files_icon(icon->x, icon->y, label);
|
||||||
else if (str_starts_with(icon->name, "Paint")) draw_paint_icon(icon->x, icon->y, label);
|
else if (str_starts_with(icon->name, "Paint")) draw_paint_icon(icon->x, icon->y, label);
|
||||||
else draw_icon(icon->x, icon->y, label);
|
else draw_icon(icon->x, icon->y, label);
|
||||||
} else {
|
} else {
|
||||||
if (str_ends_with(icon->name, ".pnt")) draw_paint_icon(icon->x, icon->y, icon->name);
|
if (str_ends_with(icon->name, ".pnt")) draw_paint_icon(icon->x, icon->y, icon->name);
|
||||||
else if (str_ends_with(icon->name, ".md")) {
|
else if (str_ends_with(icon->name, ".md")) {
|
||||||
draw_document_icon(icon->x, icon->y, icon->name);
|
draw_document_icon(icon->x, icon->y, icon->name);
|
||||||
draw_string(icon->x + 31, icon->y + 2, "MD", COLOR_BLACK);
|
draw_string(icon->x + 31, icon->y + 2, "MD", COLOR_DARK_TEXT);
|
||||||
} else if (str_ends_with(icon->name, ".c") || str_ends_with(icon->name, ".C")) {
|
} else if (str_ends_with(icon->name, ".c") || str_ends_with(icon->name, ".C")) {
|
||||||
draw_document_icon(icon->x, icon->y, icon->name);
|
draw_document_icon(icon->x, icon->y, icon->name);
|
||||||
draw_string(icon->x + 31, icon->y + 2, "C", COLOR_APPLE_BLUE);
|
draw_string(icon->x + 31, icon->y + 2, "C", COLOR_APPLE_BLUE);
|
||||||
|
|
@ -729,7 +767,6 @@ void wm_paint(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Windows - sort by z-index and draw
|
// 3. Windows - sort by z-index and draw
|
||||||
// Simple bubble sort by z-index
|
|
||||||
Window *sorted_windows[32];
|
Window *sorted_windows[32];
|
||||||
for (int i = 0; i < window_count; i++) {
|
for (int i = 0; i < window_count; i++) {
|
||||||
sorted_windows[i] = all_windows[i];
|
sorted_windows[i] = all_windows[i];
|
||||||
|
|
@ -750,7 +787,6 @@ void wm_paint(void) {
|
||||||
Window *win = sorted_windows[i];
|
Window *win = sorted_windows[i];
|
||||||
if (!win->visible) continue;
|
if (!win->visible) continue;
|
||||||
|
|
||||||
|
|
||||||
if (dirty.active && !win->focused) {
|
if (dirty.active && !win->focused) {
|
||||||
if (win->x + win->w <= dirty.x || win->x >= dirty.x + dirty.w ||
|
if (win->x + win->w <= dirty.x || win->x >= dirty.x + dirty.w ||
|
||||||
win->y + win->h <= dirty.y || win->y >= dirty.y + dirty.h) {
|
win->y + win->h <= dirty.y || win->y >= dirty.y + dirty.h) {
|
||||||
|
|
@ -760,109 +796,131 @@ void wm_paint(void) {
|
||||||
draw_window(win);
|
draw_window(win);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Taskbar
|
// 4. Top Menu Bar (macOS style)
|
||||||
draw_rect(0, sh - 28, sw, 28, COLOR_GRAY);
|
draw_rect(0, 0, sw, 40, COLOR_TOPBAR_BG);
|
||||||
draw_rect(0, sh - 28, sw, 2, COLOR_WHITE); // Top highlight
|
|
||||||
|
|
||||||
// 5. Start Button
|
// Logo dropdown (top-left)
|
||||||
draw_bevel_rect(2, sh - 26, 90, 24, start_menu_open);
|
draw_boredos_logo(8, 8, 1);
|
||||||
// Draw Boredos logo
|
|
||||||
draw_boredos_logo(6, sh - 22, 1);
|
|
||||||
// Draw BoredOS text
|
|
||||||
draw_string(35, sh - 18, "BoredOS", COLOR_BLACK);
|
|
||||||
|
|
||||||
// Clock
|
// Clock (top-right)
|
||||||
draw_clock(sw - 80, sh - 20);
|
draw_clock(sw - 80, 12);
|
||||||
|
|
||||||
// 6. Start Menu (if open)
|
// Top menu dropdown (if logo clicked)
|
||||||
if (start_menu_open) {
|
if (start_menu_open) {
|
||||||
int menu_h = 250;
|
int menu_h = 100;
|
||||||
int menu_y = sh - 28 - menu_h;
|
draw_rounded_rect_filled(8, 40, 160, menu_h, 8, COLOR_DARK_PANEL);
|
||||||
draw_bevel_rect(0, menu_y, 120, menu_h, false);
|
draw_string(20, 48, "About BoredOS", COLOR_DARK_TEXT);
|
||||||
|
draw_string(20, 68, "Settings", COLOR_DARK_TEXT);
|
||||||
// Items
|
draw_string(20, 88, "Shutdown", COLOR_DARK_TEXT);
|
||||||
draw_string(8, menu_y + 8, "Explorer", COLOR_BLACK);
|
draw_string(20, 108, "Restart", COLOR_DARK_TEXT);
|
||||||
draw_string(8, menu_y + 28, "Notepad", COLOR_BLACK);
|
|
||||||
draw_string(8, menu_y + 48, "Editor", COLOR_BLACK);
|
|
||||||
draw_string(8, menu_y + 68, "CMD", COLOR_BLACK);
|
|
||||||
draw_string(8, menu_y + 88, "Calculator", COLOR_BLACK);
|
|
||||||
draw_string(8, menu_y + 108, "Minesweeper", COLOR_BLACK);
|
|
||||||
draw_string(8, menu_y + 128, "Control Panel", COLOR_BLACK);
|
|
||||||
draw_string(8, menu_y + 148, "Paint", COLOR_BLACK);
|
|
||||||
draw_string(8, menu_y + 168, "About BoredOS", COLOR_BLACK);
|
|
||||||
|
|
||||||
// Separator line
|
|
||||||
draw_rect(5, menu_y + 185, 110, 1, COLOR_BLACK);
|
|
||||||
|
|
||||||
// Power options at bottom
|
|
||||||
draw_string(8, menu_y + 195, "Shutdown", COLOR_BLACK);
|
|
||||||
draw_string(8, menu_y + 215, "Restart", COLOR_BLACK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Desktop Context Menu
|
// 5. Dock (bottom - macOS style, floating with rounded corners)
|
||||||
|
int dock_h = 60;
|
||||||
|
int dock_y = sh - dock_h - 6; // Float above bottom
|
||||||
|
int dock_item_size = 48;
|
||||||
|
int dock_spacing = 10;
|
||||||
|
int total_dock_width = 8 * (dock_item_size + dock_spacing);
|
||||||
|
int dock_bg_x = (sw - total_dock_width) / 2 - 12; // Rounded background extends beyond icons
|
||||||
|
int dock_bg_w = total_dock_width + 24;
|
||||||
|
draw_rounded_rect_filled(dock_bg_x, dock_y, dock_bg_w, dock_h, 18, COLOR_DOCK_BG);
|
||||||
|
|
||||||
|
// Draw dock apps (centered)
|
||||||
|
int dock_x = (sw - total_dock_width) / 2;
|
||||||
|
int dock_item_y = dock_y + 6;
|
||||||
|
|
||||||
|
// Files app
|
||||||
|
draw_rounded_rect_filled(dock_x, dock_item_y, dock_item_size, dock_item_size, 10, 0xFF4A90E2);
|
||||||
|
dock_x += dock_item_size + dock_spacing;
|
||||||
|
|
||||||
|
// Settings app
|
||||||
|
draw_rounded_rect_filled(dock_x, dock_item_y, dock_item_size, dock_item_size, 10, 0xFF888888);
|
||||||
|
dock_x += dock_item_size + dock_spacing;
|
||||||
|
|
||||||
|
// Notepad
|
||||||
|
draw_rounded_rect_filled(dock_x, dock_item_y, dock_item_size, dock_item_size, 10, 0xFFFFD700);
|
||||||
|
dock_x += dock_item_size + dock_spacing;
|
||||||
|
|
||||||
|
// Calculator
|
||||||
|
draw_rounded_rect_filled(dock_x, dock_item_y, dock_item_size, dock_item_size, 10, 0xFFFF6B6B);
|
||||||
|
dock_x += dock_item_size + dock_spacing;
|
||||||
|
|
||||||
|
// Terminal
|
||||||
|
draw_rounded_rect_filled(dock_x, dock_item_y, dock_item_size, dock_item_size, 10, 0xFF000000);
|
||||||
|
dock_x += dock_item_size + dock_spacing;
|
||||||
|
|
||||||
|
// Minesweeper
|
||||||
|
draw_rounded_rect_filled(dock_x, dock_item_y, dock_item_size, dock_item_size, 10, 0xFF808080);
|
||||||
|
dock_x += dock_item_size + dock_spacing;
|
||||||
|
|
||||||
|
// Paint
|
||||||
|
draw_rounded_rect_filled(dock_x, dock_item_y, dock_item_size, dock_item_size, 10, 0xFF4CAF50);
|
||||||
|
dock_x += dock_item_size + dock_spacing;
|
||||||
|
|
||||||
|
// Editor
|
||||||
|
draw_rounded_rect_filled(dock_x, dock_item_y, dock_item_size, dock_item_size, 10, 0xFF2196F3);
|
||||||
|
|
||||||
|
// Desktop Context Menu (with rounded corners)
|
||||||
if (desktop_menu_visible) {
|
if (desktop_menu_visible) {
|
||||||
int menu_w = 140;
|
int menu_w = 140;
|
||||||
int item_h = 25;
|
int item_h = 25;
|
||||||
int menu_h = (desktop_menu_target_icon != -1) ? 125 : 75;
|
int menu_h = (desktop_menu_target_icon != -1) ? 125 : 75;
|
||||||
|
|
||||||
draw_rect(desktop_menu_x, desktop_menu_y, menu_w, menu_h, COLOR_LTGRAY);
|
draw_rounded_rect_filled(desktop_menu_x, desktop_menu_y, menu_w, menu_h, 8, COLOR_DARK_PANEL);
|
||||||
draw_bevel_rect(desktop_menu_x, desktop_menu_y, menu_w, menu_h, true);
|
|
||||||
|
|
||||||
if (desktop_menu_target_icon != -1) {
|
if (desktop_menu_target_icon != -1) {
|
||||||
bool can_paste = explorer_clipboard_has_content();
|
bool can_paste = explorer_clipboard_has_content();
|
||||||
DesktopIcon *icon = &desktop_icons[desktop_menu_target_icon];
|
draw_string(desktop_menu_x + 10, desktop_menu_y + 5, "Cut", COLOR_DARK_TEXT);
|
||||||
if (icon->type != 1) can_paste = false; // 1 is folder
|
draw_string(desktop_menu_x + 10, desktop_menu_y + 5 + item_h, "Copy", COLOR_DARK_TEXT);
|
||||||
|
draw_string(desktop_menu_x + 10, desktop_menu_y + 5 + item_h * 2, "Paste", can_paste ? COLOR_DARK_TEXT : COLOR_DKGRAY);
|
||||||
draw_string(desktop_menu_x + 5, desktop_menu_y + 5, "Cut", COLOR_BLACK);
|
draw_string(desktop_menu_x + 10, desktop_menu_y + 5 + item_h * 3, "Delete", COLOR_TRAFFIC_RED);
|
||||||
draw_string(desktop_menu_x + 5, desktop_menu_y + 5 + item_h, "Copy", COLOR_BLACK);
|
draw_string(desktop_menu_x + 10, desktop_menu_y + 5 + item_h * 4, "Rename", COLOR_DARK_TEXT);
|
||||||
draw_string(desktop_menu_x + 5, desktop_menu_y + 5 + item_h * 2, "Paste", can_paste ? COLOR_BLACK : COLOR_DKGRAY);
|
|
||||||
draw_string(desktop_menu_x + 5, desktop_menu_y + 5 + item_h * 3, "Delete", COLOR_RED);
|
|
||||||
draw_string(desktop_menu_x + 5, desktop_menu_y + 5 + item_h * 4, "Rename", COLOR_BLACK);
|
|
||||||
} else {
|
} else {
|
||||||
bool can_paste = explorer_clipboard_has_content();
|
bool can_paste = explorer_clipboard_has_content();
|
||||||
draw_string(desktop_menu_x + 5, desktop_menu_y + 5, "New File", COLOR_BLACK);
|
draw_string(desktop_menu_x + 10, desktop_menu_y + 5, "New File", COLOR_DARK_TEXT);
|
||||||
draw_string(desktop_menu_x + 5, desktop_menu_y + 5 + item_h, "New Folder", COLOR_BLACK);
|
draw_string(desktop_menu_x + 10, desktop_menu_y + 5 + item_h, "New Folder", COLOR_DARK_TEXT);
|
||||||
draw_string(desktop_menu_x + 5, desktop_menu_y + 5 + item_h * 2, "Paste", can_paste ? COLOR_BLACK : COLOR_DKGRAY);
|
draw_string(desktop_menu_x + 10, desktop_menu_y + 5 + item_h * 2, "Paste", can_paste ? COLOR_DARK_TEXT : COLOR_DKGRAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Desktop Dialogs
|
// Desktop Dialogs (dark mode)
|
||||||
if (desktop_dialog_state != 0) {
|
if (desktop_dialog_state != 0) {
|
||||||
int dlg_w = 300; int dlg_h = 110;
|
int dlg_w = 300; int dlg_h = 110;
|
||||||
int dlg_x = (sw - dlg_w) / 2;
|
int dlg_x = (sw - dlg_w) / 2;
|
||||||
int dlg_y = (sh - dlg_h) / 2;
|
int dlg_y = (sh - dlg_h) / 2;
|
||||||
|
|
||||||
draw_rect(dlg_x - 5, dlg_y - 5, dlg_w + 10, dlg_h + 10, COLOR_LTGRAY);
|
draw_rounded_rect_filled(dlg_x, dlg_y, dlg_w, dlg_h, 8, COLOR_DARK_PANEL);
|
||||||
draw_bevel_rect(dlg_x, dlg_y, dlg_w, dlg_h, true);
|
|
||||||
|
|
||||||
const char *title = "Rename";
|
const char *title = "Rename";
|
||||||
const char *btn_text = "Rename";
|
const char *btn_text = "Rename";
|
||||||
if (desktop_dialog_state == 1) { title = "Create New File"; btn_text = "Create"; }
|
if (desktop_dialog_state == 1) { title = "Create New File"; btn_text = "Create"; }
|
||||||
else if (desktop_dialog_state == 2) { title = "Create New Folder"; btn_text = "Create"; }
|
else if (desktop_dialog_state == 2) { title = "Create New Folder"; btn_text = "Create"; }
|
||||||
|
|
||||||
draw_string(dlg_x + 10, dlg_y + 10, title, COLOR_BLACK);
|
draw_string(dlg_x + 10, dlg_y + 10, title, COLOR_DARK_TEXT);
|
||||||
draw_bevel_rect(dlg_x + 10, dlg_y + 35, 280, 20, false);
|
draw_rounded_rect_filled(dlg_x + 10, dlg_y + 35, 280, 20, 4, COLOR_DARK_BG);
|
||||||
draw_string(dlg_x + 15, dlg_y + 40, desktop_dialog_input, COLOR_BLACK);
|
draw_string(dlg_x + 15, dlg_y + 40, desktop_dialog_input, COLOR_DARK_TEXT);
|
||||||
// Cursor
|
// Cursor
|
||||||
draw_rect(dlg_x + 15 + desktop_dialog_cursor * 8, dlg_y + 39, 2, 12, COLOR_BLACK);
|
draw_rect(dlg_x + 15 + desktop_dialog_cursor * 8, dlg_y + 39, 2, 12, COLOR_DARK_TEXT);
|
||||||
|
|
||||||
draw_button(dlg_x + 50, dlg_y + 65, 80, 25, btn_text, false);
|
draw_rounded_rect_filled(dlg_x + 50, dlg_y + 65, 80, 25, 4, COLOR_DARK_BORDER);
|
||||||
draw_button(dlg_x + 170, dlg_y + 65, 80, 25, "Cancel", false);
|
draw_string(dlg_x + 70, dlg_y + 72, btn_text, COLOR_DARK_TEXT);
|
||||||
|
|
||||||
|
draw_rounded_rect_filled(dlg_x + 170, dlg_y + 65, 80, 25, 4, COLOR_DARK_BORDER);
|
||||||
|
draw_string(dlg_x + 185, dlg_y + 72, "Cancel", COLOR_DARK_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Message Box
|
// Message Box (dark mode)
|
||||||
if (msg_box_visible) {
|
if (msg_box_visible) {
|
||||||
int mw = 320;
|
int mw = 320;
|
||||||
int mh = 100;
|
int mh = 100;
|
||||||
int mx = (sw - mw) / 2;
|
int mx = (sw - mw) / 2;
|
||||||
int my = (sh - mh) / 2;
|
int my = (sh - mh) / 2;
|
||||||
|
|
||||||
draw_rect(mx, my, mw, mh, COLOR_LTGRAY);
|
draw_rounded_rect_filled(mx, my, mw, mh, 8, COLOR_DARK_PANEL);
|
||||||
draw_bevel_rect(mx, my, mw, mh, false);
|
draw_string(mx + 15, my + 10, msg_box_title, COLOR_DARK_TEXT);
|
||||||
draw_rect(mx + 3, my + 3, mw - 6, 20, COLOR_BLUE);
|
draw_string(mx + 10, my + 40, msg_box_text, COLOR_DARK_TEXT);
|
||||||
draw_string(mx + 8, my + 8, msg_box_title, COLOR_WHITE);
|
draw_rounded_rect_filled(mx + mw/2 - 30, my + 70, 60, 20, 4, COLOR_DARK_BORDER);
|
||||||
draw_string(mx + 10, my + 40, msg_box_text, COLOR_BLACK);
|
draw_string(mx + mw/2 - 18, my + 75, "OK", COLOR_DARK_TEXT);
|
||||||
draw_button(mx + mw/2 - 30, my + 70, 60, 20, "OK", false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom Overlay (VM Graphics)
|
// Custom Overlay (VM Graphics)
|
||||||
|
|
@ -872,8 +930,6 @@ void wm_paint(void) {
|
||||||
|
|
||||||
// Draw Dragged Icon
|
// Draw Dragged Icon
|
||||||
if (is_dragging_file) {
|
if (is_dragging_file) {
|
||||||
// Extract filename for label
|
|
||||||
// Just draw a generic icon at mouse pos
|
|
||||||
if (drag_icon_type == 1) draw_folder_icon(mx - 20, my - 20, "Moving...");
|
if (drag_icon_type == 1) draw_folder_icon(mx - 20, my - 20, "Moving...");
|
||||||
else if (drag_icon_type == 2) draw_icon(mx - 20, my - 20, "Moving...");
|
else if (drag_icon_type == 2) draw_icon(mx - 20, my - 20, "Moving...");
|
||||||
else draw_document_icon(mx - 20, my - 20, "Moving...");
|
else draw_document_icon(mx - 20, my - 20, "Moving...");
|
||||||
|
|
@ -1035,7 +1091,7 @@ void wm_handle_click(int x, int y) {
|
||||||
}
|
}
|
||||||
} else if (desktop_dialog_state == 1 || desktop_dialog_state == 2) { // Create File/Folder
|
} else if (desktop_dialog_state == 1 || desktop_dialog_state == 2) { // Create File/Folder
|
||||||
if (desktop_icon_count >= desktop_max_cols * desktop_max_rows_per_col) {
|
if (desktop_icon_count >= desktop_max_cols * desktop_max_rows_per_col) {
|
||||||
wm_show_message("Error", "Desktop is full!");
|
wm_show_message("Error", "Desktop is full!"); // This message is now based on the adjusted limit
|
||||||
} else if (desktop_dialog_input[0] != 0) {
|
} else if (desktop_dialog_input[0] != 0) {
|
||||||
char path[128] = "/Desktop/";
|
char path[128] = "/Desktop/";
|
||||||
int p=9; int n=0; while(desktop_dialog_input[n]) path[p++] = desktop_dialog_input[n++]; path[p]=0;
|
int p=9; int n=0; while(desktop_dialog_input[n]) path[p++] = desktop_dialog_input[n++]; path[p]=0;
|
||||||
|
|
@ -1067,15 +1123,33 @@ void wm_handle_click(int x, int y) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check Start Button
|
// Check Top Bar Logo (toggle dropdown menu)
|
||||||
if (rect_contains(2, sh - 26, 90, 24, x, y)) {
|
if (rect_contains(8, 8, 24, 24, x, y)) {
|
||||||
start_menu_open = !start_menu_open;
|
start_menu_open = !start_menu_open;
|
||||||
force_redraw = true;
|
force_redraw = true;
|
||||||
pending_desktop_icon_click = -1;
|
pending_desktop_icon_click = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start Menu items handled in wm_handle_mouse (on up/drag) to support dragging shortcuts.
|
// Handle top bar dropdown menu items
|
||||||
|
if (start_menu_open && rect_contains(8, 40, 160, 120, x, y)) {
|
||||||
|
int rel_y = y - 40;
|
||||||
|
int item = rel_y / 20;
|
||||||
|
|
||||||
|
if (item == 0) { // About
|
||||||
|
wm_bring_to_front(&win_about);
|
||||||
|
} else if (item == 1) { // Settings
|
||||||
|
wm_bring_to_front(&win_control_panel);
|
||||||
|
} else if (item == 2) { // Shutdown
|
||||||
|
cli_cmd_shutdown(NULL);
|
||||||
|
} else if (item == 3) { // Restart
|
||||||
|
cli_cmd_reboot(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
start_menu_open = false;
|
||||||
|
force_redraw = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Find topmost window at click location
|
// Find topmost window at click location
|
||||||
Window *topmost = NULL;
|
Window *topmost = NULL;
|
||||||
|
|
@ -1095,8 +1169,8 @@ void wm_handle_click(int x, int y) {
|
||||||
if (topmost != NULL) {
|
if (topmost != NULL) {
|
||||||
wm_bring_to_front(topmost);
|
wm_bring_to_front(topmost);
|
||||||
|
|
||||||
// Check close button
|
// Check traffic light close button (now at top-left)
|
||||||
if (rect_contains(topmost->x + topmost->w - 20, topmost->y + 5, 14, 14, x, y)) {
|
if (rect_contains(topmost->x + 8, topmost->y + 9, 12, 12, x, y)) {
|
||||||
topmost->visible = false;
|
topmost->visible = false;
|
||||||
// Reset window state on close
|
// Reset window state on close
|
||||||
if (topmost == &win_explorer) {
|
if (topmost == &win_explorer) {
|
||||||
|
|
@ -1108,7 +1182,7 @@ void wm_handle_click(int x, int y) {
|
||||||
} else if (topmost == &win_paint) {
|
} else if (topmost == &win_paint) {
|
||||||
paint_reset();
|
paint_reset();
|
||||||
}
|
}
|
||||||
} else if (y < topmost->y + 24) {
|
} else if (y < topmost->y + 30) {
|
||||||
// Dragging the title bar
|
// Dragging the title bar
|
||||||
is_dragging = true;
|
is_dragging = true;
|
||||||
drag_window = topmost;
|
drag_window = topmost;
|
||||||
|
|
@ -1140,7 +1214,7 @@ void wm_handle_click(int x, int y) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close start menu if clicked elsewhere
|
// Close dropdown menu if clicked elsewhere
|
||||||
if (start_menu_open) {
|
if (start_menu_open) {
|
||||||
start_menu_open = false;
|
start_menu_open = false;
|
||||||
}
|
}
|
||||||
|
|
@ -1229,24 +1303,30 @@ void wm_handle_right_click(int x, int y) {
|
||||||
paint_reset_last_pos();
|
paint_reset_last_pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check Start Menu for potential drag
|
// Check Dock for app clicks (bottom of screen, floating)
|
||||||
if (start_menu_open) {
|
int dock_h = 60;
|
||||||
int menu_h = 250;
|
int dock_y = sh - dock_h - 6; // Float above bottom
|
||||||
int menu_y = sh - 28 - menu_h;
|
int dock_item_size = 48;
|
||||||
if (rect_contains(0, menu_y, 120, menu_h, mx, my)) {
|
int dock_spacing = 10;
|
||||||
if (my < menu_y + 25) start_menu_pending_app = "Explorer";
|
int total_dock_width = 8 * (dock_item_size + dock_spacing);
|
||||||
else if (my < menu_y + 45) start_menu_pending_app = "Notepad";
|
int dock_bg_x = (sw - total_dock_width) / 2 - 12;
|
||||||
else if (my < menu_y + 65) start_menu_pending_app = "Editor";
|
int dock_bg_w = total_dock_width + 24;
|
||||||
else if (my < menu_y + 85) start_menu_pending_app = "Terminal";
|
|
||||||
else if (my < menu_y + 105) start_menu_pending_app = "Calculator";
|
if (rect_contains(dock_bg_x, dock_y, dock_bg_w, dock_h, mx, my)) {
|
||||||
else if (my < menu_y + 125) start_menu_pending_app = "Minesweeper";
|
int dock_x = (sw - total_dock_width) / 2;
|
||||||
else if (my < menu_y + 145) start_menu_pending_app = "Control Panel";
|
|
||||||
else if (my < menu_y + 165) start_menu_pending_app = "Paint";
|
// Check which dock item was clicked
|
||||||
else if (my < menu_y + 185) start_menu_pending_app = "About";
|
int item_x = mx - dock_x;
|
||||||
else if (my < menu_y + 205) start_menu_pending_app = "Shutdown";
|
if (item_x >= 0) {
|
||||||
else start_menu_pending_app = "Restart";
|
int item = item_x / (dock_item_size + dock_spacing);
|
||||||
} else {
|
if (item == 0) start_menu_pending_app = "Files";
|
||||||
wm_handle_click(mx, my);
|
else if (item == 1) start_menu_pending_app = "Settings";
|
||||||
|
else if (item == 2) start_menu_pending_app = "Notepad";
|
||||||
|
else if (item == 3) start_menu_pending_app = "Calculator";
|
||||||
|
else if (item == 4) start_menu_pending_app = "Terminal";
|
||||||
|
else if (item == 5) start_menu_pending_app = "Minesweeper";
|
||||||
|
else if (item == 6) start_menu_pending_app = "Paint";
|
||||||
|
else if (item == 7) start_menu_pending_app = "Editor";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wm_handle_click(mx, my);
|
wm_handle_click(mx, my);
|
||||||
|
|
@ -1313,7 +1393,7 @@ void wm_handle_right_click(int x, int y) {
|
||||||
for (int w = 0; w < window_count; w++) {
|
for (int w = 0; w < window_count; w++) {
|
||||||
Window *win = all_windows[w];
|
Window *win = all_windows[w];
|
||||||
if (win->visible && rect_contains(win->x, win->y, win->w, win->h, drag_start_x, drag_start_y)) {
|
if (win->visible && rect_contains(win->x, win->y, win->w, win->h, drag_start_x, drag_start_y)) {
|
||||||
if (str_starts_with(win->title, "File Explorer")) {
|
if (str_starts_with(win->title, "Files")) {
|
||||||
drag_src_win = win;
|
drag_src_win = win;
|
||||||
explorer_clear_click_state(win);
|
explorer_clear_click_state(win);
|
||||||
}
|
}
|
||||||
|
|
@ -1332,12 +1412,14 @@ void wm_handle_right_click(int x, int y) {
|
||||||
force_redraw = true;
|
force_redraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Start Menu Click (Mouse Up without Drag)
|
// Handle Dock App Click (Mouse Up without Drag)
|
||||||
if (start_menu_pending_app) {
|
if (start_menu_pending_app) {
|
||||||
// Launch App
|
// Launch App
|
||||||
if (str_starts_with(start_menu_pending_app, "Explorer")) {
|
if (str_starts_with(start_menu_pending_app, "Files")) {
|
||||||
explorer_open_directory("/");
|
explorer_reset();
|
||||||
|
wm_bring_to_front(&win_explorer);
|
||||||
} else if (str_starts_with(start_menu_pending_app, "Notepad")) {
|
} else if (str_starts_with(start_menu_pending_app, "Notepad")) {
|
||||||
|
notepad_reset();
|
||||||
wm_bring_to_front(&win_notepad);
|
wm_bring_to_front(&win_notepad);
|
||||||
} else if (str_starts_with(start_menu_pending_app, "Editor")) {
|
} else if (str_starts_with(start_menu_pending_app, "Editor")) {
|
||||||
wm_bring_to_front(&win_editor);
|
wm_bring_to_front(&win_editor);
|
||||||
|
|
@ -1347,7 +1429,7 @@ void wm_handle_right_click(int x, int y) {
|
||||||
wm_bring_to_front(&win_calculator);
|
wm_bring_to_front(&win_calculator);
|
||||||
} else if (str_starts_with(start_menu_pending_app, "Minesweeper")) {
|
} else if (str_starts_with(start_menu_pending_app, "Minesweeper")) {
|
||||||
wm_bring_to_front(&win_minesweeper);
|
wm_bring_to_front(&win_minesweeper);
|
||||||
} else if (str_starts_with(start_menu_pending_app, "Control Panel")) {
|
} else if (str_starts_with(start_menu_pending_app, "Settings")) {
|
||||||
wm_bring_to_front(&win_control_panel);
|
wm_bring_to_front(&win_control_panel);
|
||||||
} else if (str_starts_with(start_menu_pending_app, "Paint")) {
|
} else if (str_starts_with(start_menu_pending_app, "Paint")) {
|
||||||
wm_bring_to_front(&win_paint);
|
wm_bring_to_front(&win_paint);
|
||||||
|
|
@ -1359,7 +1441,6 @@ void wm_handle_right_click(int x, int y) {
|
||||||
cli_cmd_reboot(NULL);
|
cli_cmd_reboot(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
start_menu_open = false;
|
|
||||||
start_menu_pending_app = NULL;
|
start_menu_pending_app = NULL;
|
||||||
force_redraw = true;
|
force_redraw = true;
|
||||||
}
|
}
|
||||||
|
|
@ -1378,14 +1459,15 @@ void wm_handle_right_click(int x, int y) {
|
||||||
wm_bring_to_front(&win_calculator); handled = true;
|
wm_bring_to_front(&win_calculator); handled = true;
|
||||||
} else if (str_ends_with(icon->name, "Minesweeper.shortcut")) {
|
} else if (str_ends_with(icon->name, "Minesweeper.shortcut")) {
|
||||||
wm_bring_to_front(&win_minesweeper); handled = true;
|
wm_bring_to_front(&win_minesweeper); handled = true;
|
||||||
} else if (str_ends_with(icon->name, "Control Panel.shortcut")) {
|
} else if (str_ends_with(icon->name, "Settings.shortcut")) {
|
||||||
wm_bring_to_front(&win_control_panel); handled = true;
|
wm_bring_to_front(&win_control_panel); handled = true;
|
||||||
} else if (str_ends_with(icon->name, "Terminal.shortcut")) {
|
} else if (str_ends_with(icon->name, "Terminal.shortcut")) {
|
||||||
wm_bring_to_front(&win_cmd); handled = true;
|
wm_bring_to_front(&win_cmd); handled = true;
|
||||||
} else if (str_ends_with(icon->name, "About.shortcut")) {
|
} else if (str_ends_with(icon->name, "About.shortcut")) {
|
||||||
wm_bring_to_front(&win_about); handled = true;
|
wm_bring_to_front(&win_about); handled = true;
|
||||||
} else if (str_ends_with(icon->name, "Explorer.shortcut")) {
|
} else if (str_ends_with(icon->name, "Explorer.shortcut")) { // Files
|
||||||
explorer_open_directory("/"); handled = true;
|
explorer_reset();
|
||||||
|
wm_bring_to_front(&win_explorer);
|
||||||
} else if (str_ends_with(icon->name, "Recycle Bin.shortcut")) {
|
} else if (str_ends_with(icon->name, "Recycle Bin.shortcut")) {
|
||||||
explorer_open_directory("/RecycleBin"); handled = true;
|
explorer_open_directory("/RecycleBin"); handled = true;
|
||||||
} else if (str_ends_with(icon->name, "Paint.shortcut")) {
|
} else if (str_ends_with(icon->name, "Paint.shortcut")) {
|
||||||
|
|
@ -1450,7 +1532,7 @@ void wm_handle_right_click(int x, int y) {
|
||||||
for (int w = 0; w < window_count; w++) {
|
for (int w = 0; w < window_count; w++) {
|
||||||
Window *win = all_windows[w];
|
Window *win = all_windows[w];
|
||||||
if (win->visible && rect_contains(win->x, win->y, win->w, win->h, mx, my)) {
|
if (win->visible && rect_contains(win->x, win->y, win->w, win->h, mx, my)) {
|
||||||
if (win->z_index > topmost_z && str_starts_with(win->title, "File Explorer")) {
|
if (win->z_index > topmost_z && str_starts_with(win->title, "Files")) {
|
||||||
drop_win = win;
|
drop_win = win;
|
||||||
topmost_z = win->z_index;
|
topmost_z = win->z_index;
|
||||||
}
|
}
|
||||||
|
|
@ -1511,7 +1593,7 @@ void wm_handle_right_click(int x, int y) {
|
||||||
if (!dropped_on_target && !from_desktop) {
|
if (!dropped_on_target && !from_desktop) {
|
||||||
// Dragged from Explorer to Desktop
|
// Dragged from Explorer to Desktop
|
||||||
// Check limit first
|
// Check limit first
|
||||||
if (desktop_icon_count >= desktop_max_cols * desktop_max_rows_per_col) {
|
if (desktop_icon_count >= desktop_max_cols * (desktop_max_rows_per_col > 1 ? desktop_max_rows_per_col - 1 : 0)) {
|
||||||
wm_show_message("Error", "Desktop is full!");
|
wm_show_message("Error", "Desktop is full!");
|
||||||
} else {
|
} else {
|
||||||
explorer_import_file_to(&win_explorer, drag_file_path, "/Desktop");
|
explorer_import_file_to(&win_explorer, drag_file_path, "/Desktop");
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,19 @@
|
||||||
#define COLOR_APPLE_INDIGO 0xFF4B0082
|
#define COLOR_APPLE_INDIGO 0xFF4B0082
|
||||||
#define COLOR_APPLE_VIOLET 0xFF9400D3
|
#define COLOR_APPLE_VIOLET 0xFF9400D3
|
||||||
|
|
||||||
|
// --- Dark Mode Colors (macOS Style) ---
|
||||||
|
#define COLOR_DARK_BG 0xFF1E1E1E // Main dark background
|
||||||
|
#define COLOR_DARK_PANEL 0xFF2D2D2D // Slightly lighter panel background
|
||||||
|
#define COLOR_DARK_TITLEBAR 0xFF282828 // Darker for title bar
|
||||||
|
#define COLOR_DARK_TEXT 0xFFF0F0F0 // Light gray text
|
||||||
|
#define COLOR_DARK_BORDER 0xFF3A3A3A // Border color
|
||||||
|
#define COLOR_DOCK_BG 0xFF3A3A3A // Dock background
|
||||||
|
#define COLOR_TOPBAR_BG 0xFF1A1A1A // Top bar background
|
||||||
|
#define COLOR_TRAFFIC_RED 0xFFED6158 // Close button red
|
||||||
|
#define COLOR_TRAFFIC_YELLOW 0xFFFCC02E // Minimize button (not used for now)
|
||||||
|
#define COLOR_TRAFFIC_GREEN 0xFF5FC038 // Zoom button (not used for now)
|
||||||
|
|
||||||
|
#define DESKTOP_TOP_DEADSPACE_HEIGHT 80 // Height of the dead space at the top of the desktop grid
|
||||||
typedef struct Window Window;
|
typedef struct Window Window;
|
||||||
struct Window {
|
struct Window {
|
||||||
char *title;
|
char *title;
|
||||||
|
|
@ -67,6 +80,9 @@ extern void (*wm_custom_paint_hook)(void);
|
||||||
// Drawing helpers
|
// Drawing helpers
|
||||||
void draw_bevel_rect(int x, int y, int w, int h, bool sunken);
|
void draw_bevel_rect(int x, int y, int w, int h, bool sunken);
|
||||||
void draw_button(int x, int y, int w, int h, const char *text, bool pressed);
|
void draw_button(int x, int y, int w, int h, const char *text, bool pressed);
|
||||||
|
void draw_rounded_rect(int x, int y, int w, int h, int radius, uint32_t color);
|
||||||
|
void draw_rounded_rect_filled(int x, int y, int w, int h, int radius, uint32_t color);
|
||||||
|
void draw_traffic_light(int x, int y); // Red close button only
|
||||||
void draw_icon(int x, int y, const char *label);
|
void draw_icon(int x, int y, const char *label);
|
||||||
void draw_folder_icon(int x, int y, const char *label);
|
void draw_folder_icon(int x, int y, const char *label);
|
||||||
void draw_document_icon(int x, int y, const char *label);
|
void draw_document_icon(int x, int y, const char *label);
|
||||||
|
|
@ -78,6 +94,9 @@ void draw_control_panel_icon(int x, int y, const char *label);
|
||||||
void draw_about_icon(int x, int y, const char *label);
|
void draw_about_icon(int x, int y, const char *label);
|
||||||
void draw_recycle_bin_icon(int x, int y, const char *label);
|
void draw_recycle_bin_icon(int x, int y, const char *label);
|
||||||
void draw_paint_icon(int x, int y, const char *label);
|
void draw_paint_icon(int x, int y, const char *label);
|
||||||
|
void draw_squircle_icon(int x, int y, const char *label, uint32_t bg_color);
|
||||||
|
void draw_files_icon(int x, int y, const char *label);
|
||||||
|
void draw_settings_icon(int x, int y, const char *label);
|
||||||
|
|
||||||
// Desktop Settings
|
// Desktop Settings
|
||||||
extern bool desktop_snap_to_grid;
|
extern bool desktop_snap_to_grid;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue