mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
1.42
Paint added and other bug fixes
This commit is contained in:
parent
904dc2f1a5
commit
23972f8951
30 changed files with 829 additions and 637 deletions
BIN
.DS_Store
vendored
BIN
.DS_Store
vendored
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
||||||
# Brew OS 1.42 Beta
|
# Brew OS 1.43 Beta
|
||||||
BrewOS is now in a Beta stage as i have brought over all apps from brewkernel and have made the DE a lot more usable and stable.
|
BrewOS is now in a Beta stage as i have brought over all apps from brewkernel and have made the DE a lot more usable and stable.
|
||||||
|
|
||||||
## Brewkernel is now BrewOS!
|
## Brewkernel is now BrewOS!
|
||||||
|
|
|
||||||
BIN
brewos.iso
BIN
brewos.iso
Binary file not shown.
BIN
build/about.o
BIN
build/about.o
Binary file not shown.
BIN
build/brewos.elf
BIN
build/brewos.elf
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/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.
Binary file not shown.
|
|
@ -14,9 +14,6 @@ Window win_about;
|
||||||
#define COLOR_CYAN_LOGO 0xFF368DF7
|
#define COLOR_CYAN_LOGO 0xFF368DF7
|
||||||
|
|
||||||
static void about_paint(Window *win) {
|
static void about_paint(Window *win) {
|
||||||
// Background
|
|
||||||
draw_rect(win->x + 4, win->y + 24, win->w - 8, win->h - 28, COLOR_LTGRAY);
|
|
||||||
|
|
||||||
int offset_x = win->x + 15;
|
int offset_x = win->x + 15;
|
||||||
int offset_y = win->y + 35;
|
int offset_y = win->y + 35;
|
||||||
|
|
||||||
|
|
@ -35,7 +32,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.42", COLOR_BLACK);
|
draw_string(offset_x, offset_y + 120, "BrewOS Version 1.43", COLOR_BLACK);
|
||||||
draw_string(offset_x, offset_y + 135, "Kernel Version 2.3.1", COLOR_BLACK);
|
draw_string(offset_x, offset_y + 135, "Kernel Version 2.3.1", COLOR_BLACK);
|
||||||
|
|
||||||
// Copyright
|
// Copyright
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,7 @@ static void calculator_click(Window *win, int x, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
update_display(win);
|
update_display(win);
|
||||||
wm_paint(); // Request repaint
|
wm_mark_dirty(win->x, win->y, win->w, win->h);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,6 @@
|
||||||
|
|
||||||
void cli_cmd_brewver(char *args) {
|
void cli_cmd_brewver(char *args) {
|
||||||
(void)args;
|
(void)args;
|
||||||
cli_write("BrewOS v1.42 Beta\n");
|
cli_write("BrewOS v1.43 Beta\n");
|
||||||
cli_write("BrewOS Kernel V2.3.1 Beta\n");
|
cli_write("BrewOS Kernel V2.3.1 Beta\n");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -800,7 +800,7 @@ static void cmd_paint(Window *win) {
|
||||||
int offset_y = win->y + 24;
|
int offset_y = win->y + 24;
|
||||||
|
|
||||||
// Fill background
|
// Fill background
|
||||||
draw_rect(offset_x, offset_y, win->w - 8, win->h - 28, COLOR_BLACK);
|
draw_rect(win->x + 4, win->y + 24, win->w - 8, win->h - 28, COLOR_BLACK);
|
||||||
|
|
||||||
int start_y = offset_y + 4;
|
int start_y = offset_y + 4;
|
||||||
int start_x = offset_x + 4;
|
int start_x = offset_x + 4;
|
||||||
|
|
|
||||||
|
|
@ -265,7 +265,7 @@ static void editor_paint(Window *win) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill editor background
|
// Fill editor background
|
||||||
draw_rect(offset_x, offset_y + 30, content_width, content_height - 55, COLOR_WHITE);
|
draw_rect(win->x + 4, win->y + 54, win->w - 8, win->h - 58, COLOR_WHITE);
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -2,7 +2,9 @@
|
||||||
#define EXPLORER_H
|
#define EXPLORER_H
|
||||||
|
|
||||||
#include "wm.h"
|
#include "wm.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// External windows references (for opening other apps)
|
||||||
extern Window win_explorer;
|
extern Window win_explorer;
|
||||||
extern Window win_editor;
|
extern Window win_editor;
|
||||||
extern Window win_cmd;
|
extern Window win_cmd;
|
||||||
|
|
@ -10,27 +12,73 @@ extern Window win_notepad;
|
||||||
extern Window win_calculator;
|
extern Window win_calculator;
|
||||||
extern Window win_markdown;
|
extern Window win_markdown;
|
||||||
|
|
||||||
|
#define EXPLORER_MAX_FILES 64
|
||||||
|
#define DIALOG_INPUT_MAX 256
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char name[256];
|
||||||
|
bool is_directory;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t color;
|
||||||
|
} ExplorerItem;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ExplorerItem items[EXPLORER_MAX_FILES];
|
||||||
|
int item_count;
|
||||||
|
int selected_item;
|
||||||
|
char current_path[256];
|
||||||
|
int last_clicked_item;
|
||||||
|
uint32_t last_click_time;
|
||||||
|
int explorer_scroll_row;
|
||||||
|
|
||||||
|
// Dialog state
|
||||||
|
int dialog_state;
|
||||||
|
char dialog_input[DIALOG_INPUT_MAX];
|
||||||
|
int dialog_input_cursor;
|
||||||
|
char dialog_target_path[256];
|
||||||
|
bool dialog_target_is_dir;
|
||||||
|
char dialog_dest_dir[256];
|
||||||
|
char dialog_creation_path[256];
|
||||||
|
char dialog_move_src[256];
|
||||||
|
|
||||||
|
// Dropdown menu state
|
||||||
|
bool dropdown_menu_visible;
|
||||||
|
|
||||||
|
// File context menu state
|
||||||
|
bool file_context_menu_visible;
|
||||||
|
int file_context_menu_x;
|
||||||
|
int file_context_menu_y;
|
||||||
|
int file_context_menu_item;
|
||||||
|
|
||||||
|
} ExplorerState;
|
||||||
|
|
||||||
void explorer_init(void);
|
void explorer_init(void);
|
||||||
void explorer_reset(void);
|
void explorer_reset(void);
|
||||||
void explorer_refresh(void);
|
void explorer_open_directory(const char *path); // Creates a NEW window
|
||||||
void explorer_clear_click_state(void);
|
|
||||||
|
|
||||||
// Drag and Drop support
|
// Drag and Drop support
|
||||||
|
// This now needs to find WHICH explorer window is under the mouse
|
||||||
bool explorer_get_file_at(int screen_x, int screen_y, char *out_path, bool *is_dir);
|
bool explorer_get_file_at(int screen_x, int screen_y, char *out_path, bool *is_dir);
|
||||||
void explorer_import_file(const char *source_path);
|
void explorer_import_file(Window *win, const char *source_path); // To focused or default
|
||||||
void explorer_import_file_to(const char *source_path, const char *dest_dir);
|
void explorer_import_file_to(Window *win, const char *source_path, const char *dest_dir);
|
||||||
|
void explorer_refresh(Window *win);
|
||||||
|
void explorer_refresh_all(void);
|
||||||
|
void explorer_clear_click_state(Window *win);
|
||||||
|
|
||||||
// Clipboard
|
// String Helpers
|
||||||
|
size_t explorer_strlen(const char *str);
|
||||||
|
void explorer_strcpy(char *dest, const char *src);
|
||||||
|
void explorer_strcat(char *dest, const char *src);
|
||||||
|
|
||||||
|
// Clipboard (System-wide)
|
||||||
void explorer_clipboard_copy(const char *path);
|
void explorer_clipboard_copy(const char *path);
|
||||||
void explorer_clipboard_cut(const char *path);
|
void explorer_clipboard_cut(const char *path);
|
||||||
void explorer_clipboard_paste(const char *dest_dir);
|
void explorer_clipboard_paste(Window *win, const char *dest_dir);
|
||||||
bool explorer_clipboard_has_content(void);
|
bool explorer_clipboard_has_content(void);
|
||||||
|
|
||||||
// File Operations
|
// File Operations
|
||||||
bool explorer_delete_permanently(const char *path);
|
bool explorer_delete_permanently(const char *path);
|
||||||
bool explorer_delete_recursive(const char *path);
|
bool explorer_delete_recursive(const char *path);
|
||||||
void explorer_create_shortcut(const char *target_path);
|
void explorer_create_shortcut(Window *win, const char *target_path);
|
||||||
|
|
||||||
void explorer_open_directory(const char *path);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -293,7 +293,7 @@ static void md_paint(Window *win) {
|
||||||
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
|
||||||
draw_rect(offset_x, content_start_y, content_width - 20, usable_content_height, COLOR_WHITE);
|
draw_rect(win->x + 4, content_start_y, win->w - 24, usable_content_height, COLOR_WHITE);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ static void minesweeper_right_click(Window *win, int x, int y) {
|
||||||
int cell_y = (y - grid_start_y) / CELL_SIZE;
|
int cell_y = (y - grid_start_y) / CELL_SIZE;
|
||||||
|
|
||||||
flag_cell(cell_x, cell_y);
|
flag_cell(cell_x, cell_y);
|
||||||
wm_paint();
|
wm_mark_dirty(win->x, win->y, win->w, win->h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,7 +211,7 @@ static void minesweeper_click(Window *win, int x, int y) {
|
||||||
if (x >= grid_start_x && x < grid_start_x + 90 &&
|
if (x >= grid_start_x && x < grid_start_x + 90 &&
|
||||||
y >= btn_y && y < btn_y + 24) {
|
y >= btn_y && y < btn_y + 24) {
|
||||||
init_game();
|
init_game();
|
||||||
wm_paint();
|
wm_mark_dirty(win->x, win->y, win->w, win->h);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -226,7 +226,7 @@ static void minesweeper_click(Window *win, int x, int y) {
|
||||||
|
|
||||||
reveal_cell(cell_x, cell_y);
|
reveal_cell(cell_x, cell_y);
|
||||||
|
|
||||||
wm_paint();
|
wm_mark_dirty(win->x, win->y, win->w, win->h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,9 @@ 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
|
||||||
|
draw_rect(win->x + 4, win->y + 24, win->w - 8, win->h - 28, COLOR_WHITE);
|
||||||
|
|
||||||
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 + 30;
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,6 @@ static void paint_strcpy(char *dest, const char *src) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void paint_paint(Window *win) {
|
static void paint_paint(Window *win) {
|
||||||
// Background
|
|
||||||
draw_rect(win->x + 4, win->y + 24, win->w - 8, win->h - 28, COLOR_LTGRAY);
|
|
||||||
|
|
||||||
// Toolbar area
|
// Toolbar area
|
||||||
draw_rect(win->x + 10, win->y + 30, 40, win->h - 40, COLOR_GRAY);
|
draw_rect(win->x + 10, win->y + 30, 40, win->h - 40, COLOR_GRAY);
|
||||||
draw_bevel_rect(win->x + 10, win->y + 30, 40, win->h - 40, true);
|
draw_bevel_rect(win->x + 10, win->y + 30, 40, win->h - 40, true);
|
||||||
|
|
|
||||||
330
src/kernel/wm.c
330
src/kernel/wm.c
|
|
@ -51,16 +51,17 @@ static int drag_offset_x = 0;
|
||||||
static int drag_offset_y = 0;
|
static int drag_offset_y = 0;
|
||||||
|
|
||||||
// File Dragging State
|
// File Dragging State
|
||||||
static bool is_dragging_file = false;
|
bool is_dragging_file = false;
|
||||||
static char drag_file_path[256];
|
static char drag_file_path[256];
|
||||||
static int drag_icon_type = 0; // 0=File, 1=Folder, 2=App
|
static int drag_icon_type = 0; // 0=File, 1=Folder, 2=App
|
||||||
static int drag_start_x = 0;
|
static int drag_start_x = 0;
|
||||||
static int drag_start_y = 0;
|
static int drag_start_y = 0;
|
||||||
static int drag_icon_orig_x = 0;
|
static int drag_icon_orig_x = 0;
|
||||||
static int drag_icon_orig_y = 0;
|
static int drag_icon_orig_y = 0;
|
||||||
|
static Window *drag_src_win = NULL;
|
||||||
|
|
||||||
// Windows array for z-order management
|
// Windows array for z-order management
|
||||||
static Window *all_windows[10];
|
static Window *all_windows[32];
|
||||||
static int window_count = 0;
|
static int window_count = 0;
|
||||||
|
|
||||||
// Redraw system
|
// Redraw system
|
||||||
|
|
@ -79,7 +80,6 @@ typedef struct {
|
||||||
char name[64];
|
char name[64];
|
||||||
int x, y;
|
int x, y;
|
||||||
int type; // 0=File, 1=Folder, 2=App
|
int type; // 0=File, 1=Folder, 2=App
|
||||||
bool selected;
|
|
||||||
} DesktopIcon;
|
} DesktopIcon;
|
||||||
|
|
||||||
static DesktopIcon desktop_icons[MAX_DESKTOP_ICONS];
|
static DesktopIcon desktop_icons[MAX_DESKTOP_ICONS];
|
||||||
|
|
@ -165,8 +165,6 @@ static void refresh_desktop_icons(void) {
|
||||||
if (files[i].is_directory) dest->type = 1;
|
if (files[i].is_directory) dest->type = 1;
|
||||||
else if (str_ends_with(dest->name, ".shortcut")) dest->type = 2;
|
else if (str_ends_with(dest->name, ".shortcut")) dest->type = 2;
|
||||||
else dest->type = 0;
|
else dest->type = 0;
|
||||||
|
|
||||||
dest->selected = false;
|
|
||||||
dest->x = -1; // Mark as new for layout
|
dest->x = -1; // Mark as new for layout
|
||||||
dest->y = -1;
|
dest->y = -1;
|
||||||
|
|
||||||
|
|
@ -276,49 +274,55 @@ void wm_show_message(const char *title, const char *message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_icon_label(int x, int y, const char *label) {
|
static void draw_icon_label(int x, int y, const char *label) {
|
||||||
char line1[10] = {0};
|
char line1[11] = {0}; // 10 chars + null
|
||||||
char line2[10] = {0};
|
char line2[11] = {0}; // 10 chars + null
|
||||||
int len = 0; while(label[len]) len++;
|
int len = 0; while(label[len]) len++;
|
||||||
|
|
||||||
if (len <= 8) {
|
if (len <= 10) {
|
||||||
int i=0; while(i<len) { line1[i] = label[i]; i++; }
|
for (int i = 0; i < len; i++) line1[i] = label[i];
|
||||||
line1[i] = 0;
|
|
||||||
} else {
|
} else {
|
||||||
int split = 8;
|
// Dot-based wrap: keep extension together if prefix fits
|
||||||
// Smart wrap: look for separator in first 8 chars (backwards)
|
int dot_pos = -1;
|
||||||
// Prioritize keeping extension together (e.g. SEVENCH.MD -> split at 7)
|
for (int i = len - 1; i >= 0; i--) {
|
||||||
int best_split = -1;
|
if (label[i] == '.') { dot_pos = i; break; }
|
||||||
for (int i = 7; i >= 1; i--) {
|
}
|
||||||
if (label[i] == ' ' || label[i] == '.') {
|
|
||||||
best_split = i;
|
int split = -1;
|
||||||
|
if (dot_pos != -1 && dot_pos > 0 && dot_pos <= 10) {
|
||||||
|
split = dot_pos;
|
||||||
|
} else {
|
||||||
|
// Word-based wrap: look for space in the first 11 characters
|
||||||
|
for (int i = 10; i >= 0; i--) {
|
||||||
|
if (label[i] == ' ') {
|
||||||
|
split = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best_split != -1) {
|
|
||||||
split = best_split;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy line 1
|
if (split != -1) {
|
||||||
int i;
|
for (int i = 0; i < split; i++) line1[i] = label[i];
|
||||||
for (i = 0; i < split; i++) line1[i] = label[i];
|
int start2 = (label[split] == ' ') ? split + 1 : split;
|
||||||
line1[i] = 0;
|
|
||||||
|
|
||||||
// Copy line 2
|
|
||||||
int start2 = split;
|
|
||||||
if (label[split] == ' ') start2++; // Skip space at start of line 2
|
|
||||||
|
|
||||||
int j = 0;
|
int j = 0;
|
||||||
while (label[start2 + j] && j < 8) {
|
while (label[start2 + j] && j < 10) {
|
||||||
line2[j] = label[start2 + j];
|
line2[j] = label[start2 + j];
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
line2[j] = 0;
|
|
||||||
|
|
||||||
// Truncate with .. if longer than 16 (or if line 2 overflows)
|
|
||||||
if (label[start2 + j] != 0) {
|
if (label[start2 + j] != 0) {
|
||||||
if (j > 6) { line2[6] = '.'; line2[7] = '.'; line2[8] = 0; }
|
int t = (j > 8) ? 8 : j;
|
||||||
else { line2[j++] = '.'; line2[j++] = '.'; line2[j] = 0; }
|
line2[t] = '.'; line2[t+1] = '.'; line2[t+2] = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < 10; i++) line1[i] = label[i];
|
||||||
|
int j = 0;
|
||||||
|
while (label[10 + j] && j < 10) {
|
||||||
|
line2[j] = label[10 + j];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
if (label[10 + j] != 0) {
|
||||||
|
int t = (j > 8) ? 8 : j;
|
||||||
|
line2[t] = '.'; line2[t+1] = '.'; line2[t+2] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -338,7 +342,6 @@ static void draw_icon_label(int x, int y, const char *label) {
|
||||||
|
|
||||||
// --- Drawing Helpers ---
|
// --- Drawing Helpers ---
|
||||||
|
|
||||||
// Draw a bevelled box (Win 3.1 style)
|
|
||||||
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) {
|
||||||
draw_rect(x, y, w, h, COLOR_GRAY);
|
draw_rect(x, y, w, h, COLOR_GRAY);
|
||||||
|
|
||||||
|
|
@ -377,16 +380,14 @@ void draw_coffee_cup(int x, int y, int size) {
|
||||||
draw_rect(x + cup_w - 2, y + 2, 1, cup_h - 3, COLOR_BLACK); // Right
|
draw_rect(x + cup_w - 2, y + 2, 1, cup_h - 3, COLOR_BLACK); // Right
|
||||||
draw_rect(x + 1, y + cup_h - 1, cup_w - 2, 1, COLOR_BLACK); // Bottom
|
draw_rect(x + 1, y + cup_h - 1, cup_w - 2, 1, COLOR_BLACK); // Bottom
|
||||||
|
|
||||||
// Rounded bottom corners
|
|
||||||
draw_rect(x + 1, y + cup_h - 1, 1, 1, COLOR_LTGRAY);
|
draw_rect(x + 1, y + cup_h - 1, 1, 1, COLOR_LTGRAY);
|
||||||
draw_rect(x + cup_w - 2, y + cup_h - 1, 1, 1, COLOR_LTGRAY);
|
draw_rect(x + cup_w - 2, y + cup_h - 1, 1, 1, COLOR_LTGRAY);
|
||||||
|
|
||||||
// Handle - much bigger (on the right side, pointing inward)
|
|
||||||
draw_rect(x + cup_w, y + 3, 2, 8, COLOR_BLACK);
|
draw_rect(x + cup_w, y + 3, 2, 8, COLOR_BLACK);
|
||||||
draw_rect(x + cup_w - 2, y + 3, 2, 1, COLOR_BLACK);
|
draw_rect(x + cup_w - 2, y + 3, 2, 1, COLOR_BLACK);
|
||||||
draw_rect(x + cup_w - 2, y + 10, 2, 1, COLOR_BLACK);
|
draw_rect(x + cup_w - 2, y + 10, 2, 1, COLOR_BLACK);
|
||||||
|
|
||||||
// Coffee liquid inside - rainbow Apple logo stripes (blue, green, yellow, red, purple, blue)
|
|
||||||
int stripe_height = (cup_h - 5) / 6;
|
int stripe_height = (cup_h - 5) / 6;
|
||||||
int coffee_y = y + 4;
|
int coffee_y = y + 4;
|
||||||
draw_rect(x + 2, coffee_y, cup_w - 4, stripe_height, COLOR_APPLE_BLUE);
|
draw_rect(x + 2, coffee_y, cup_w - 4, stripe_height, COLOR_APPLE_BLUE);
|
||||||
|
|
@ -601,7 +602,7 @@ void draw_window(Window *win) {
|
||||||
draw_button(win->x + win->w - 20, win->y + 5, 14, 14, "X", false);
|
draw_button(win->x + win->w - 20, win->y + 5, 14, 14, "X", false);
|
||||||
|
|
||||||
// Client Area
|
// Client Area
|
||||||
draw_rect(win->x + 4, win->y + 24, win->w - 8, win->h - 28, COLOR_WHITE);
|
draw_rect(win->x + 4, win->y + 24, win->w - 8, win->h - 28, COLOR_LTGRAY);
|
||||||
|
|
||||||
if (win->paint) {
|
if (win->paint) {
|
||||||
win->paint(win);
|
win->paint(win);
|
||||||
|
|
@ -696,6 +697,9 @@ void wm_paint(void) {
|
||||||
int sw = get_screen_width();
|
int sw = get_screen_width();
|
||||||
int sh = get_screen_height();
|
int sh = get_screen_height();
|
||||||
|
|
||||||
|
// Ensure no stale clipping state interferes with the new frame
|
||||||
|
graphics_clear_clipping();
|
||||||
|
|
||||||
// First, erase the old cursor (before redrawing anything)
|
// First, erase the old cursor (before redrawing anything)
|
||||||
if (cursor_visible) {
|
if (cursor_visible) {
|
||||||
erase_cursor(last_cursor_x, last_cursor_y);
|
erase_cursor(last_cursor_x, last_cursor_y);
|
||||||
|
|
@ -734,14 +738,17 @@ void wm_paint(void) {
|
||||||
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_BLACK);
|
||||||
|
} else if (str_ends_with(icon->name, ".c") || str_ends_with(icon->name, ".C")) {
|
||||||
|
draw_document_icon(icon->x, icon->y, icon->name);
|
||||||
|
draw_string(icon->x + 31, icon->y + 2, "C", COLOR_APPLE_BLUE);
|
||||||
}
|
}
|
||||||
else draw_document_icon(icon->x, icon->y, icon->name);
|
else draw_document_icon(icon->x, icon->y, icon->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Windows - sort by z-index and draw
|
// 3. Windows - sort by z-index and draw
|
||||||
// Simple bubble sort by z-index (5 windows max)
|
// Simple bubble sort by z-index
|
||||||
Window *sorted_windows[6];
|
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];
|
||||||
}
|
}
|
||||||
|
|
@ -803,30 +810,32 @@ void wm_paint(void) {
|
||||||
// Desktop Context Menu
|
// Desktop Context Menu
|
||||||
if (desktop_menu_visible) {
|
if (desktop_menu_visible) {
|
||||||
int menu_w = 140;
|
int menu_w = 140;
|
||||||
int menu_h = 125; // 5 items * 25
|
int item_h = 25;
|
||||||
|
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_rect(desktop_menu_x, desktop_menu_y, menu_w, menu_h, COLOR_LTGRAY);
|
||||||
draw_bevel_rect(desktop_menu_x, desktop_menu_y, menu_w, menu_h, true);
|
draw_bevel_rect(desktop_menu_x, desktop_menu_y, menu_w, menu_h, true);
|
||||||
|
|
||||||
bool can_cut_copy = (desktop_menu_target_icon != -1);
|
|
||||||
bool can_paste = explorer_clipboard_has_content();
|
|
||||||
|
|
||||||
// If target is a file (not folder), paste is disabled
|
|
||||||
if (desktop_menu_target_icon != -1) {
|
if (desktop_menu_target_icon != -1) {
|
||||||
|
bool can_paste = explorer_clipboard_has_content();
|
||||||
DesktopIcon *icon = &desktop_icons[desktop_menu_target_icon];
|
DesktopIcon *icon = &desktop_icons[desktop_menu_target_icon];
|
||||||
if (icon->type != 1) can_paste = false; // 1 is folder
|
if (icon->type != 1) can_paste = false; // 1 is folder
|
||||||
}
|
|
||||||
|
|
||||||
int item_h = 25;
|
draw_string(desktop_menu_x + 5, desktop_menu_y + 5, "Cut", COLOR_BLACK);
|
||||||
draw_string(desktop_menu_x + 5, desktop_menu_y + 5, "Cut", can_cut_copy ? COLOR_BLACK : COLOR_DKGRAY);
|
draw_string(desktop_menu_x + 5, desktop_menu_y + 5 + item_h, "Copy", COLOR_BLACK);
|
||||||
draw_string(desktop_menu_x + 5, desktop_menu_y + 5 + item_h, "Copy", can_cut_copy ? COLOR_BLACK : COLOR_DKGRAY);
|
|
||||||
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 * 2, "Paste", can_paste ? COLOR_BLACK : COLOR_DKGRAY);
|
||||||
draw_string(desktop_menu_x + 5, desktop_menu_y + 5 + item_h * 3, "Delete", can_cut_copy ? COLOR_RED : 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", can_cut_copy ? COLOR_BLACK : COLOR_DKGRAY);
|
draw_string(desktop_menu_x + 5, desktop_menu_y + 5 + item_h * 4, "Rename", COLOR_BLACK);
|
||||||
|
} else {
|
||||||
|
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 + 5, desktop_menu_y + 5 + item_h, "New Folder", COLOR_BLACK);
|
||||||
|
draw_string(desktop_menu_x + 5, desktop_menu_y + 5 + item_h * 2, "Paste", can_paste ? COLOR_BLACK : COLOR_DKGRAY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Desktop Rename Dialog
|
// Desktop Dialogs
|
||||||
if (desktop_dialog_state == 8) {
|
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;
|
||||||
|
|
@ -834,13 +843,18 @@ void wm_paint(void) {
|
||||||
draw_rect(dlg_x - 5, dlg_y - 5, dlg_w + 10, dlg_h + 10, COLOR_LTGRAY);
|
draw_rect(dlg_x - 5, dlg_y - 5, dlg_w + 10, dlg_h + 10, COLOR_LTGRAY);
|
||||||
draw_bevel_rect(dlg_x, dlg_y, dlg_w, dlg_h, true);
|
draw_bevel_rect(dlg_x, dlg_y, dlg_w, dlg_h, true);
|
||||||
|
|
||||||
draw_string(dlg_x + 10, dlg_y + 10, "Rename", COLOR_BLACK);
|
const char *title = "Rename";
|
||||||
|
const char *btn_text = "Rename";
|
||||||
|
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"; }
|
||||||
|
|
||||||
|
draw_string(dlg_x + 10, dlg_y + 10, title, COLOR_BLACK);
|
||||||
draw_bevel_rect(dlg_x + 10, dlg_y + 35, 280, 20, false);
|
draw_bevel_rect(dlg_x + 10, dlg_y + 35, 280, 20, false);
|
||||||
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_BLACK);
|
||||||
// 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_BLACK);
|
||||||
|
|
||||||
draw_button(dlg_x + 50, dlg_y + 65, 80, 25, "Rename", false);
|
draw_button(dlg_x + 50, dlg_y + 65, 80, 25, btn_text, false);
|
||||||
draw_button(dlg_x + 170, dlg_y + 65, 80, 25, "Cancel", false);
|
draw_button(dlg_x + 170, dlg_y + 65, 80, 25, "Cancel", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -888,7 +902,7 @@ bool rect_contains(int x, int y, int w, int h, int px, int py) {
|
||||||
return px >= x && px < x + w && py >= y && py < y + h;
|
return px >= x && px < x + w && py >= y && py < y + h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wm_bring_to_front(Window *win) {
|
void wm_bring_to_front(Window *win) {
|
||||||
// Clear focus from all windows
|
// Clear focus from all windows
|
||||||
for (int i = 0; i < window_count; i++) {
|
for (int i = 0; i < window_count; i++) {
|
||||||
all_windows[i]->focused = false;
|
all_windows[i]->focused = false;
|
||||||
|
|
@ -905,6 +919,12 @@ static void wm_bring_to_front(Window *win) {
|
||||||
win->z_index = max_z + 1;
|
win->z_index = max_z + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wm_add_window(Window *win) {
|
||||||
|
if (window_count < 32) {
|
||||||
|
all_windows[window_count++] = win;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void wm_handle_click(int x, int y) {
|
void wm_handle_click(int x, int y) {
|
||||||
int sh = get_screen_height();
|
int sh = get_screen_height();
|
||||||
int sw = get_screen_width();
|
int sw = get_screen_width();
|
||||||
|
|
@ -924,7 +944,8 @@ void wm_handle_click(int x, int y) {
|
||||||
// Handle Desktop Context Menu Click
|
// Handle Desktop Context Menu Click
|
||||||
if (desktop_menu_visible) {
|
if (desktop_menu_visible) {
|
||||||
int menu_w = 140;
|
int menu_w = 140;
|
||||||
int menu_h = 125;
|
int menu_h = (desktop_menu_target_icon != -1) ? 125 : 75;
|
||||||
|
|
||||||
if (rect_contains(desktop_menu_x, desktop_menu_y, menu_w, menu_h, x, y)) {
|
if (rect_contains(desktop_menu_x, desktop_menu_y, menu_w, menu_h, x, y)) {
|
||||||
int rel_y = y - desktop_menu_y;
|
int rel_y = y - desktop_menu_y;
|
||||||
int item = rel_y / 25;
|
int item = rel_y / 25;
|
||||||
|
|
@ -939,6 +960,14 @@ void wm_handle_click(int x, int y) {
|
||||||
char path[128] = "/Desktop/";
|
char path[128] = "/Desktop/";
|
||||||
int p=9; int n=0; while(icon->name[n]) path[p++] = icon->name[n++]; path[p]=0;
|
int p=9; int n=0; while(icon->name[n]) path[p++] = icon->name[n++]; path[p]=0;
|
||||||
explorer_clipboard_copy(path);
|
explorer_clipboard_copy(path);
|
||||||
|
} else if (item == 0 && desktop_menu_target_icon == -1) { // New File
|
||||||
|
desktop_dialog_state = 1;
|
||||||
|
desktop_dialog_input[0] = 0;
|
||||||
|
desktop_dialog_cursor = 0;
|
||||||
|
} else if (item == 1 && desktop_menu_target_icon == -1) { // New Folder
|
||||||
|
desktop_dialog_state = 2;
|
||||||
|
desktop_dialog_input[0] = 0;
|
||||||
|
desktop_dialog_cursor = 0;
|
||||||
} else if (item == 2) { // Paste
|
} else if (item == 2) { // Paste
|
||||||
bool can_paste = explorer_clipboard_has_content();
|
bool can_paste = explorer_clipboard_has_content();
|
||||||
if (desktop_menu_target_icon != -1) {
|
if (desktop_menu_target_icon != -1) {
|
||||||
|
|
@ -952,10 +981,10 @@ void wm_handle_click(int x, int y) {
|
||||||
char path[128] = "/Desktop/";
|
char path[128] = "/Desktop/";
|
||||||
DesktopIcon *icon = &desktop_icons[desktop_menu_target_icon];
|
DesktopIcon *icon = &desktop_icons[desktop_menu_target_icon];
|
||||||
int p=9; int n=0; while(icon->name[n]) path[p++] = icon->name[n++]; path[p]=0;
|
int p=9; int n=0; while(icon->name[n]) path[p++] = icon->name[n++]; path[p]=0;
|
||||||
explorer_clipboard_paste(path);
|
explorer_clipboard_paste(&win_explorer, path);
|
||||||
} else {
|
} else {
|
||||||
// Paste to desktop
|
// Paste to desktop
|
||||||
explorer_clipboard_paste("/Desktop");
|
explorer_clipboard_paste(&win_explorer, "/Desktop");
|
||||||
}
|
}
|
||||||
refresh_desktop_icons();
|
refresh_desktop_icons();
|
||||||
}
|
}
|
||||||
|
|
@ -984,15 +1013,35 @@ void wm_handle_click(int x, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Desktop Dialog Clicks
|
// Handle Desktop Dialog Clicks
|
||||||
if (desktop_dialog_state == 8) {
|
if (desktop_dialog_state != 0) {
|
||||||
int dlg_x = (sw - 300) / 2; int dlg_y = (sh - 110) / 2;
|
int dlg_x = (sw - 300) / 2; int dlg_y = (sh - 110) / 2;
|
||||||
if (rect_contains(dlg_x + 50, dlg_y + 65, 80, 25, x, y)) { // Rename
|
if (rect_contains(dlg_x + 50, dlg_y + 65, 80, 25, x, y)) { // Confirm
|
||||||
|
if (desktop_dialog_state == 8) { // Rename
|
||||||
char old_path[128] = "/Desktop/";
|
char old_path[128] = "/Desktop/";
|
||||||
char new_path[128] = "/Desktop/";
|
char new_path[128] = "/Desktop/";
|
||||||
int p=9; int n=0; while(desktop_icons[desktop_dialog_target].name[n]) old_path[p++] = desktop_icons[desktop_dialog_target].name[n++]; old_path[p]=0;
|
int p=9; int n=0; while(desktop_icons[desktop_dialog_target].name[n]) old_path[p++] = desktop_icons[desktop_dialog_target].name[n++]; old_path[p]=0;
|
||||||
p=9; n=0; while(desktop_dialog_input[n]) new_path[p++] = desktop_dialog_input[n++]; new_path[p]=0;
|
p=9; n=0; while(desktop_dialog_input[n]) new_path[p++] = desktop_dialog_input[n++]; new_path[p]=0;
|
||||||
|
|
||||||
if (fat32_rename(old_path, new_path)) refresh_desktop_icons();
|
if (fat32_rename(old_path, new_path)) {
|
||||||
|
refresh_desktop_icons();
|
||||||
|
explorer_refresh_all();
|
||||||
|
}
|
||||||
|
} 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) {
|
||||||
|
wm_show_message("Error", "Desktop is full!");
|
||||||
|
} else if (desktop_dialog_input[0] != 0) {
|
||||||
|
char path[128] = "/Desktop/";
|
||||||
|
int p=9; int n=0; while(desktop_dialog_input[n]) path[p++] = desktop_dialog_input[n++]; path[p]=0;
|
||||||
|
if (desktop_dialog_state == 1) {
|
||||||
|
FAT32_FileHandle *fh = fat32_open(path, "w");
|
||||||
|
if (fh) fat32_close(fh);
|
||||||
|
} else {
|
||||||
|
fat32_mkdir(path);
|
||||||
|
}
|
||||||
|
refresh_desktop_icons();
|
||||||
|
explorer_refresh_all();
|
||||||
|
}
|
||||||
|
}
|
||||||
desktop_dialog_state = 0;
|
desktop_dialog_state = 0;
|
||||||
force_redraw = true;
|
force_redraw = true;
|
||||||
return;
|
return;
|
||||||
|
|
@ -1242,7 +1291,19 @@ void wm_handle_right_click(int x, int y) {
|
||||||
if (explorer_get_file_at(drag_start_x, drag_start_y, drag_file_path, &is_dir)) {
|
if (explorer_get_file_at(drag_start_x, drag_start_y, drag_file_path, &is_dir)) {
|
||||||
is_dragging_file = true;
|
is_dragging_file = true;
|
||||||
drag_icon_type = is_dir ? 1 : 0;
|
drag_icon_type = is_dir ? 1 : 0;
|
||||||
explorer_clear_click_state();
|
drag_src_win = NULL;
|
||||||
|
|
||||||
|
// Find which explorer window was clicked to clear its state
|
||||||
|
for (int w = 0; w < window_count; 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)) {
|
||||||
|
// This is a bit of a hack, but we check if it's an explorer window
|
||||||
|
if (str_starts_with(win->title, "File Explorer")) {
|
||||||
|
drag_src_win = win;
|
||||||
|
explorer_clear_click_state(win);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1260,7 +1321,7 @@ void wm_handle_right_click(int x, int y) {
|
||||||
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, "Explorer")) {
|
||||||
explorer_reset(); wm_bring_to_front(&win_explorer);
|
explorer_open_directory("/");
|
||||||
} else if (str_starts_with(start_menu_pending_app, "Notepad")) {
|
} else if (str_starts_with(start_menu_pending_app, "Notepad")) {
|
||||||
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")) {
|
||||||
|
|
@ -1308,9 +1369,9 @@ void wm_handle_right_click(int x, int y) {
|
||||||
} else if (str_ends_with(icon->name, "About.shortcut")) {
|
} else if (str_ends_with(icon->name, "About.shortcut")) {
|
||||||
wm_bring_to_front(&win_about);
|
wm_bring_to_front(&win_about);
|
||||||
} else if (str_ends_with(icon->name, "Explorer.shortcut")) {
|
} else if (str_ends_with(icon->name, "Explorer.shortcut")) {
|
||||||
explorer_reset(); wm_bring_to_front(&win_explorer);
|
explorer_open_directory("/");
|
||||||
} else if (str_ends_with(icon->name, "Recycle Bin.shortcut")) {
|
} else if (str_ends_with(icon->name, "Recycle Bin.shortcut")) {
|
||||||
explorer_open_directory("/RecycleBin"); wm_bring_to_front(&win_explorer);
|
explorer_open_directory("/RecycleBin");
|
||||||
} else if (str_ends_with(icon->name, "Paint.shortcut")) {
|
} else if (str_ends_with(icon->name, "Paint.shortcut")) {
|
||||||
wm_bring_to_front(&win_paint);
|
wm_bring_to_front(&win_paint);
|
||||||
}
|
}
|
||||||
|
|
@ -1329,7 +1390,6 @@ void wm_handle_right_click(int x, int y) {
|
||||||
buf[len] = 0;
|
buf[len] = 0;
|
||||||
if (fat32_is_directory(buf)) {
|
if (fat32_is_directory(buf)) {
|
||||||
explorer_open_directory(buf);
|
explorer_open_directory(buf);
|
||||||
wm_bring_to_front(&win_explorer);
|
|
||||||
} else {
|
} else {
|
||||||
editor_open_file(buf);
|
editor_open_file(buf);
|
||||||
wm_bring_to_front(&win_editor);
|
wm_bring_to_front(&win_editor);
|
||||||
|
|
@ -1343,7 +1403,6 @@ void wm_handle_right_click(int x, int y) {
|
||||||
char path[128] = "/Desktop/";
|
char path[128] = "/Desktop/";
|
||||||
int p=9; int n=0; while(icon->name[n]) path[p++] = icon->name[n++]; path[p]=0;
|
int p=9; int n=0; while(icon->name[n]) path[p++] = icon->name[n++]; path[p]=0;
|
||||||
explorer_open_directory(path);
|
explorer_open_directory(path);
|
||||||
wm_bring_to_front(&win_explorer);
|
|
||||||
} else { // File
|
} else { // File
|
||||||
char path[128] = "/Desktop/";
|
char path[128] = "/Desktop/";
|
||||||
int p=9; int n=0; while(icon->name[n]) path[p++] = icon->name[n++]; path[p]=0;
|
int p=9; int n=0; while(icon->name[n]) path[p++] = icon->name[n++]; path[p]=0;
|
||||||
|
|
@ -1366,25 +1425,31 @@ void wm_handle_right_click(int x, int y) {
|
||||||
if (is_dragging_file) {
|
if (is_dragging_file) {
|
||||||
// Drop logic
|
// Drop logic
|
||||||
|
|
||||||
// Check drop target
|
// Check drop target - iterate through all windows to find if dropped on an Explorer
|
||||||
if (win_explorer.visible && rect_contains(win_explorer.x, win_explorer.y, win_explorer.w, win_explorer.h, mx, my)) {
|
Window *drop_win = NULL;
|
||||||
// Dropped on Explorer
|
int topmost_z = -1;
|
||||||
// If source was desktop, we need to refresh desktop to remove the icon
|
for (int w = 0; w < window_count; w++) {
|
||||||
bool from_desktop = str_starts_with(drag_file_path, "/Desktop/");
|
Window *win = all_windows[w];
|
||||||
|
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")) {
|
||||||
|
drop_win = win;
|
||||||
|
topmost_z = win->z_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (drag_file_path[0] != ':') {
|
if (drop_win) {
|
||||||
char target_path[256];
|
char target_path[256];
|
||||||
bool is_dir;
|
bool is_dir;
|
||||||
// Check if dropped on a folder inside explorer
|
// Check if dropped on a folder inside this explorer
|
||||||
if (explorer_get_file_at(mx, my, target_path, &is_dir) && is_dir) {
|
if (explorer_get_file_at(mx, my, target_path, &is_dir) && is_dir) {
|
||||||
explorer_import_file_to(drag_file_path, target_path);
|
explorer_import_file_to(drop_win, drag_file_path, target_path);
|
||||||
} else {
|
} else {
|
||||||
// Dropped in current dir
|
// Dropped in current dir of this explorer
|
||||||
explorer_import_file(drag_file_path);
|
explorer_import_file(drop_win, drag_file_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
if (str_starts_with(drag_file_path, "/Desktop/")) {
|
||||||
if (from_desktop) {
|
|
||||||
refresh_desktop_icons();
|
refresh_desktop_icons();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1396,13 +1461,41 @@ void wm_handle_right_click(int x, int y) {
|
||||||
// If source was NOT desktop, move to desktop
|
// If source was NOT desktop, move to desktop
|
||||||
// Check if path starts with /Desktop/
|
// Check if path starts with /Desktop/
|
||||||
bool from_desktop = (drag_file_path[0]=='/' && drag_file_path[1]=='D' && drag_file_path[2]=='e');
|
bool from_desktop = (drag_file_path[0]=='/' && drag_file_path[1]=='D' && drag_file_path[2]=='e');
|
||||||
if (!from_desktop) {
|
bool dropped_on_target = false;
|
||||||
|
for (int i = 0; i < desktop_icon_count; i++) {
|
||||||
|
if (from_desktop) {
|
||||||
|
char path[128] = "/Desktop/";
|
||||||
|
int p=9; int n=0; while(desktop_icons[i].name[n]) path[p++] = desktop_icons[i].name[n++]; path[p]=0;
|
||||||
|
if (str_eq(path, drag_file_path) == 0) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rect_contains(desktop_icons[i].x + 20, desktop_icons[i].y, 40, 40, mx, my)) {
|
||||||
|
if (desktop_icons[i].type == 1) {
|
||||||
|
char target_path[256] = "/Desktop/";
|
||||||
|
int p=9; int n=0; while(desktop_icons[i].name[n]) target_path[p++] = desktop_icons[i].name[n++]; target_path[p]=0;
|
||||||
|
explorer_import_file_to(&win_explorer, drag_file_path, target_path);
|
||||||
|
refresh_desktop_icons();
|
||||||
|
dropped_on_target = true;
|
||||||
|
break;
|
||||||
|
} else if (desktop_icons[i].type == 2 && str_starts_with(desktop_icons[i].name, "Recycle Bin")) {
|
||||||
|
explorer_import_file_to(&win_explorer, drag_file_path, "/RecycleBin");
|
||||||
|
refresh_desktop_icons();
|
||||||
|
dropped_on_target = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
dropped_on_target = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
wm_show_message("Error", "Desktop is full!");
|
wm_show_message("Error", "Desktop is full!");
|
||||||
} else {
|
} else {
|
||||||
explorer_import_file_to(drag_file_path, "/Desktop");
|
explorer_import_file_to(&win_explorer, drag_file_path, "/Desktop");
|
||||||
refresh_desktop_icons();
|
refresh_desktop_icons();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1442,7 +1535,7 @@ void wm_handle_right_click(int x, int y) {
|
||||||
refresh_desktop_icons(); // Re-apply layout
|
refresh_desktop_icons(); // Re-apply layout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!dropped_on_target) {
|
||||||
// Moved within desktop
|
// Moved within desktop
|
||||||
// Find which icon was dragged
|
// Find which icon was dragged
|
||||||
int dragged_idx = -1;
|
int dragged_idx = -1;
|
||||||
|
|
@ -1456,32 +1549,7 @@ void wm_handle_right_click(int x, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dragged_idx != -1) {
|
if (dragged_idx != -1) {
|
||||||
// Check for drop on folder (Priority over placement)
|
if (desktop_auto_align) {
|
||||||
bool dropped_on_folder = false;
|
|
||||||
for (int i = 0; i < desktop_icon_count; i++) {
|
|
||||||
if (i == dragged_idx) continue;
|
|
||||||
if (desktop_icons[i].type == 1) { // Folder
|
|
||||||
// Check if mouse is over this folder icon
|
|
||||||
if (rect_contains(desktop_icons[i].x + 20, desktop_icons[i].y, 40, 40, mx, my)) {
|
|
||||||
char target_path[256] = "/Desktop/";
|
|
||||||
int p=9; int n=0; while(desktop_icons[i].name[n]) target_path[p++] = desktop_icons[i].name[n++]; target_path[p]=0;
|
|
||||||
explorer_import_file_to(drag_file_path, target_path);
|
|
||||||
refresh_desktop_icons();
|
|
||||||
dropped_on_folder = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (desktop_icons[i].type == 2 && str_starts_with(desktop_icons[i].name, "Recycle Bin")) {
|
|
||||||
if (rect_contains(desktop_icons[i].x + 20, desktop_icons[i].y, 40, 40, mx, my)) {
|
|
||||||
// Move to Recycle Bin
|
|
||||||
explorer_import_file_to(drag_file_path, "/RecycleBin");
|
|
||||||
refresh_desktop_icons();
|
|
||||||
dropped_on_folder = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dropped_on_folder && desktop_auto_align) {
|
|
||||||
int cell_h = 80;
|
int cell_h = 80;
|
||||||
int rel_y = my - 20;
|
int rel_y = my - 20;
|
||||||
if (rel_y < 0) rel_y = 0;
|
if (rel_y < 0) rel_y = 0;
|
||||||
|
|
@ -1509,7 +1577,7 @@ void wm_handle_right_click(int x, int y) {
|
||||||
}
|
}
|
||||||
desktop_icons[target_idx] = temp;
|
desktop_icons[target_idx] = temp;
|
||||||
refresh_desktop_icons(); // Re-applies layout
|
refresh_desktop_icons(); // Re-applies layout
|
||||||
} else if (!dropped_on_folder) {
|
} else {
|
||||||
desktop_icons[dragged_idx].x = mx - 20;
|
desktop_icons[dragged_idx].x = mx - 20;
|
||||||
desktop_icons[dragged_idx].y = my - 20;
|
desktop_icons[dragged_idx].y = my - 20;
|
||||||
if (desktop_snap_to_grid) {
|
if (desktop_snap_to_grid) {
|
||||||
|
|
@ -1571,14 +1639,34 @@ static volatile int key_head = 0;
|
||||||
static volatile int key_tail = 0;
|
static volatile int key_tail = 0;
|
||||||
|
|
||||||
static void wm_dispatch_key(char c) {
|
static void wm_dispatch_key(char c) {
|
||||||
if (desktop_dialog_state == 8) {
|
if (desktop_dialog_state != 0) {
|
||||||
int len = 0; while(desktop_dialog_input[len]) len++;
|
int len = 0; while(desktop_dialog_input[len]) len++;
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
|
if (desktop_dialog_state == 8) { // Rename
|
||||||
char old_path[128] = "/Desktop/";
|
char old_path[128] = "/Desktop/";
|
||||||
char new_path[128] = "/Desktop/";
|
char new_path[128] = "/Desktop/";
|
||||||
int p=9; int n=0; while(desktop_icons[desktop_dialog_target].name[n]) old_path[p++] = desktop_icons[desktop_dialog_target].name[n++]; old_path[p]=0;
|
int p=9; int n=0; while(desktop_icons[desktop_dialog_target].name[n]) old_path[p++] = desktop_icons[desktop_dialog_target].name[n++]; old_path[p]=0;
|
||||||
p=9; n=0; while(desktop_dialog_input[n]) new_path[p++] = desktop_dialog_input[n++]; new_path[p]=0;
|
p=9; n=0; while(desktop_dialog_input[n]) new_path[p++] = desktop_dialog_input[n++]; new_path[p]=0;
|
||||||
if (fat32_rename(old_path, new_path)) refresh_desktop_icons();
|
if (fat32_rename(old_path, new_path)) {
|
||||||
|
refresh_desktop_icons();
|
||||||
|
explorer_refresh_all();
|
||||||
|
}
|
||||||
|
} 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) {
|
||||||
|
wm_show_message("Error", "Desktop is full!");
|
||||||
|
} else if (desktop_dialog_input[0] != 0) {
|
||||||
|
char path[128] = "/Desktop/";
|
||||||
|
int p=9; int n=0; while(desktop_dialog_input[n]) path[p++] = desktop_dialog_input[n++]; path[p]=0;
|
||||||
|
if (desktop_dialog_state == 1) {
|
||||||
|
FAT32_FileHandle *fh = fat32_open(path, "w");
|
||||||
|
if (fh) fat32_close(fh);
|
||||||
|
} else {
|
||||||
|
fat32_mkdir(path);
|
||||||
|
}
|
||||||
|
refresh_desktop_icons();
|
||||||
|
explorer_refresh_all();
|
||||||
|
}
|
||||||
|
}
|
||||||
desktop_dialog_state = 0;
|
desktop_dialog_state = 0;
|
||||||
} else if (c == 27) {
|
} else if (c == 27) {
|
||||||
desktop_dialog_state = 0;
|
desktop_dialog_state = 0;
|
||||||
|
|
@ -1601,13 +1689,12 @@ static void wm_dispatch_key(char c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Window *target = NULL;
|
Window *target = NULL;
|
||||||
if (win_notepad.focused && win_notepad.visible) target = &win_notepad;
|
for (int i = 0; i < window_count; i++) {
|
||||||
else if (win_cmd.focused && win_cmd.visible) target = &win_cmd;
|
if (all_windows[i]->focused && all_windows[i]->visible) {
|
||||||
else if (win_calculator.focused && win_calculator.visible) target = &win_calculator;
|
target = all_windows[i];
|
||||||
else if (win_explorer.focused && win_explorer.visible) target = &win_explorer;
|
break;
|
||||||
else if (win_editor.focused && win_editor.visible) target = &win_editor;
|
}
|
||||||
else if (win_markdown.focused && win_markdown.visible) target = &win_markdown;
|
}
|
||||||
else if (win_control_panel.focused && win_control_panel.visible) target = &win_control_panel;
|
|
||||||
|
|
||||||
if (!target) return;
|
if (!target) return;
|
||||||
|
|
||||||
|
|
@ -1717,6 +1804,7 @@ void wm_timer_tick(void) {
|
||||||
desktop_refresh_timer++;
|
desktop_refresh_timer++;
|
||||||
if (desktop_refresh_timer >= 60) {
|
if (desktop_refresh_timer >= 60) {
|
||||||
refresh_desktop_icons();
|
refresh_desktop_icons();
|
||||||
|
explorer_refresh_all();
|
||||||
desktop_refresh_timer = 0;
|
desktop_refresh_timer = 0;
|
||||||
force_redraw = true;
|
force_redraw = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ struct Window {
|
||||||
int cursor_pos;
|
int cursor_pos;
|
||||||
bool focused;
|
bool focused;
|
||||||
int z_index; // Layering depth (higher = on top)
|
int z_index; // Layering depth (higher = on top)
|
||||||
|
void *data; // Per-window private data
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
void (*paint)(Window *win);
|
void (*paint)(Window *win);
|
||||||
|
|
@ -47,6 +48,8 @@ void wm_handle_key(char c);
|
||||||
void wm_handle_click(int x, int y);
|
void wm_handle_click(int x, int y);
|
||||||
void wm_handle_right_click(int x, int y);
|
void wm_handle_right_click(int x, int y);
|
||||||
void wm_process_input(void);
|
void wm_process_input(void);
|
||||||
|
void wm_add_window(Window *win);
|
||||||
|
void wm_bring_to_front(Window *win);
|
||||||
|
|
||||||
// Redraw system
|
// Redraw system
|
||||||
void wm_mark_dirty(int x, int y, int w, int h);
|
void wm_mark_dirty(int x, int y, int w, int h);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue