mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
PR: Fixing settings && Adding a option for cursor scale (#11)
* Adding slider widget * feat: Add mouse cursor scale commands and settings improvement speed * Correct wallpaper scanning and thumbnail loading
This commit is contained in:
parent
36ed0d4a9e
commit
cfae88f9f5
8 changed files with 429 additions and 123 deletions
|
|
@ -1476,6 +1476,11 @@ static uint64_t sys_cmd_set_mouse_speed(const syscall_args_t *args) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static uint64_t sys_cmd_set_mouse_cursor_scale(const syscall_args_t *args) {
|
||||
wm_set_cursor_scale_tenths((int)args->arg2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint64_t sys_cmd_network_init(const syscall_args_t *args) {
|
||||
(void)args;
|
||||
extern int network_init(void);
|
||||
|
|
@ -1501,6 +1506,11 @@ static uint64_t sys_cmd_get_mouse_speed(const syscall_args_t *args) {
|
|||
return mouse_speed;
|
||||
}
|
||||
|
||||
static uint64_t sys_cmd_get_mouse_cursor_scale(const syscall_args_t *args) {
|
||||
(void)args;
|
||||
return (uint64_t)wm_get_cursor_scale_tenths();
|
||||
}
|
||||
|
||||
static uint64_t sys_cmd_get_wallpaper_thumb(const syscall_args_t *args) {
|
||||
(void)args;
|
||||
return -1;
|
||||
|
|
@ -2415,6 +2425,8 @@ static const syscall_handler_fn sys_cmd_table[SYS_CMD_TABLE_SIZE] = {
|
|||
[SYSTEM_CMD_PARALLEL_RUN] = sys_cmd_parallel_run,
|
||||
[SYSTEM_CMD_SET_KEYBOARD_LAYOUT] = sys_cmd_set_keyboard_layout,
|
||||
[SYSTEM_CMD_GET_KEYBOARD_LAYOUT] = sys_cmd_get_keyboard_layout,
|
||||
[SYSTEM_CMD_SET_MOUSE_CURSOR_SCALE] = sys_cmd_set_mouse_cursor_scale,
|
||||
[SYSTEM_CMD_GET_MOUSE_CURSOR_SCALE] = sys_cmd_get_mouse_cursor_scale,
|
||||
[SYSTEM_CMD_TTY_CREATE] = sys_cmd_tty_create,
|
||||
[SYSTEM_CMD_TTY_READ_OUT] = sys_cmd_tty_read_out,
|
||||
[SYSTEM_CMD_TTY_WRITE_IN] = sys_cmd_tty_write_in,
|
||||
|
|
|
|||
|
|
@ -103,6 +103,8 @@ typedef struct {
|
|||
#define SYSTEM_CMD_SET_KEYBOARD_LAYOUT 49
|
||||
#define SYSTEM_CMD_PARALLEL_RUN 50
|
||||
#define SYSTEM_CMD_GET_KEYBOARD_LAYOUT 51
|
||||
#define SYSTEM_CMD_SET_MOUSE_CURSOR_SCALE 52
|
||||
#define SYSTEM_CMD_GET_MOUSE_CURSOR_SCALE 53
|
||||
#define SYSTEM_CMD_TTY_CREATE 60
|
||||
#define SYSTEM_CMD_TTY_READ_OUT 61
|
||||
#define SYSTEM_CMD_TTY_WRITE_IN 62
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ static widget_dropdown_t drop_keyboard;
|
|||
static widget_textbox_t tb_r, tb_g, tb_b;
|
||||
static widget_textbox_t tb_ip, tb_dns;
|
||||
static widget_button_t btn_apply, btn_back;
|
||||
static widget_slider_t slider_mouse;
|
||||
static widget_slider_t slider_cursor_size;
|
||||
|
||||
#define MAX_WALLPAPERS 10
|
||||
|
||||
|
|
@ -199,16 +201,20 @@ typedef struct {
|
|||
char name[64];
|
||||
uint32_t thumb[WALLPAPER_THUMB_W * WALLPAPER_THUMB_H];
|
||||
_Bool valid;
|
||||
_Bool thumb_loaded;
|
||||
} wallpaper_entry_t;
|
||||
|
||||
static wallpaper_entry_t wallpapers[MAX_WALLPAPERS];
|
||||
static int wallpaper_count = 0;
|
||||
static _Bool wallpapers_scanned = 0;
|
||||
static int next_wallpaper_thumb = 0;
|
||||
|
||||
static _Bool desktop_snap_to_grid = 1;
|
||||
static _Bool desktop_auto_align = 1;
|
||||
static int desktop_max_rows_per_col = 10;
|
||||
static int desktop_max_cols = 10;
|
||||
static int mouse_speed = 10;
|
||||
static int mouse_cursor_scale_tenths = 10;
|
||||
|
||||
static int font_count = 0;
|
||||
static int selected_font = -1;
|
||||
|
|
@ -229,6 +235,22 @@ static void cli_itoa(int num, char *str) {
|
|||
}
|
||||
}
|
||||
|
||||
static void format_scale_tenths(int scale_tenths, char *str) {
|
||||
if (scale_tenths < 10) scale_tenths = 10;
|
||||
if (scale_tenths > 40) scale_tenths = 40;
|
||||
|
||||
char whole[4];
|
||||
cli_itoa(scale_tenths / 10, whole);
|
||||
strcpy(str, whole);
|
||||
|
||||
int len = 0;
|
||||
while (str[len]) len++;
|
||||
str[len++] = '.';
|
||||
str[len++] = (char)('0' + (scale_tenths % 10));
|
||||
str[len++] = 'x';
|
||||
str[len] = 0;
|
||||
}
|
||||
|
||||
static void generate_lumberjack_pattern(void) {
|
||||
uint32_t red = 0xFFDC143C;
|
||||
uint32_t dark_grey = 0xFF404040;
|
||||
|
|
@ -388,9 +410,15 @@ static void load_settings_icons(void) {
|
|||
static void decode_wallpapers_task(void *arg) {
|
||||
(void)arg;
|
||||
wallpaper_count = 0;
|
||||
next_wallpaper_thumb = 0;
|
||||
wallpapers_scanned = 0;
|
||||
|
||||
FAT32_FileInfo info[MAX_WALLPAPERS];
|
||||
int count = sys_list("/Library/images/Wallpapers", info, MAX_WALLPAPERS);
|
||||
if (count < 0) return;
|
||||
if (count < 0) {
|
||||
wallpapers_scanned = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count && wallpaper_count < MAX_WALLPAPERS; i++) {
|
||||
if (info[i].is_directory) continue; // Skip directories
|
||||
|
|
@ -404,6 +432,9 @@ static void decode_wallpapers_task(void *arg) {
|
|||
if (c1 != 'g' || c2 != 'p' || c3 != 'j') continue;
|
||||
|
||||
wallpaper_entry_t *wp = &wallpapers[wallpaper_count];
|
||||
wp->valid = 0;
|
||||
wp->thumb_loaded = 0;
|
||||
|
||||
// Set path
|
||||
char *pref = "/Library/images/Wallpapers/";
|
||||
int pl = 0; while (pref[pl]) { wp->path[pl] = pref[pl]; pl++; }
|
||||
|
|
@ -414,68 +445,87 @@ static void decode_wallpapers_task(void *arg) {
|
|||
for (int j = 0; j < nl - 4 && j < 63; j++) wp->name[j] = info[i].name[j];
|
||||
wp->name[(nl-4 < 63) ? nl-4 : 63] = 0;
|
||||
|
||||
// Load and generate thumbnail
|
||||
int tx = (wallpaper_count % 3) * (WALLPAPER_THUMB_W + 15);
|
||||
int ty = (wallpaper_count / 3) * (WALLPAPER_THUMB_H + 30);
|
||||
widget_button_init(&btn_wp_thumbs[wallpaper_count], 8 + tx, 306 + ty, WALLPAPER_THUMB_W + 8, WALLPAPER_THUMB_H + 26, "");
|
||||
wallpaper_count++;
|
||||
}
|
||||
|
||||
wallpapers_scanned = 1;
|
||||
}
|
||||
|
||||
static void load_wallpapers(void) {
|
||||
void *job_args[1] = { NULL };
|
||||
sys_parallel_run(decode_wallpapers_task, job_args, 1);
|
||||
}
|
||||
|
||||
static bool load_next_wallpaper_thumb(void) {
|
||||
if (!wallpapers_scanned) return false;
|
||||
|
||||
while (next_wallpaper_thumb < wallpaper_count) {
|
||||
wallpaper_entry_t *wp = &wallpapers[next_wallpaper_thumb];
|
||||
next_wallpaper_thumb++;
|
||||
|
||||
if (wp->thumb_loaded) continue;
|
||||
wp->thumb_loaded = 1;
|
||||
|
||||
char cache_path[256];
|
||||
int cp = 0;
|
||||
char *cpref = "/Library/Caches/Thumbnails/";
|
||||
while (cpref[cp]) { cache_path[cp] = cpref[cp]; cp++; }
|
||||
|
||||
int prefix_len = 0;
|
||||
char *pref = "/Library/images/Wallpapers/";
|
||||
while (pref[prefix_len] && wp->path[prefix_len] == pref[prefix_len]) prefix_len++;
|
||||
|
||||
int cn = 0;
|
||||
while (info[i].name[cn]) { cache_path[cp+cn] = info[i].name[cn]; cn++; }
|
||||
while (wp->path[prefix_len + cn]) { cache_path[cp + cn] = wp->path[prefix_len + cn]; cn++; }
|
||||
char *csuf = ".bin";
|
||||
int cs = 0;
|
||||
while (csuf[cs]) { cache_path[cp+cn+cs] = csuf[cs]; cs++; }
|
||||
cache_path[cp+cn+cs] = 0;
|
||||
while (csuf[cs]) { cache_path[cp + cn + cs] = csuf[cs]; cs++; }
|
||||
cache_path[cp + cn + cs] = 0;
|
||||
|
||||
int cfd = sys_open(cache_path, "r");
|
||||
if (cfd >= 0) {
|
||||
sys_read(cfd, wp->thumb, WALLPAPER_THUMB_W * WALLPAPER_THUMB_H * 4);
|
||||
sys_close(cfd);
|
||||
wp->valid = 1;
|
||||
} else {
|
||||
int fd = sys_open(wp->path, "r");
|
||||
if (fd >= 0) {
|
||||
int size = sys_seek(fd, 0, 2); // SEEK_END
|
||||
sys_seek(fd, 0, 0); // SEEK_SET
|
||||
if (size > 0 && size < 8 * 1024 * 1024) {
|
||||
unsigned char *buf = (unsigned char *)malloc(size);
|
||||
if (buf) {
|
||||
sys_read(fd, buf, size);
|
||||
int img_w, img_h, channels;
|
||||
unsigned char *img = stbi_load_from_memory(buf, size, &img_w, &img_h, &channels, 4);
|
||||
if (img && img_w > 0 && img_h > 0) {
|
||||
scale_rgba_to_argb(img, img_w, img_h, wp->thumb, WALLPAPER_THUMB_W, WALLPAPER_THUMB_H);
|
||||
wp->valid = 1;
|
||||
stbi_image_free(img);
|
||||
|
||||
// Save to cache
|
||||
sys_mkdir("/Library/Caches");
|
||||
sys_mkdir("/Library/Caches/Thumbnails");
|
||||
int swfd = sys_open(cache_path, "w");
|
||||
if (swfd >= 0) {
|
||||
sys_write_fs(swfd, wp->thumb, WALLPAPER_THUMB_W * WALLPAPER_THUMB_H * 4);
|
||||
sys_close(swfd);
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
sys_close(fd);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
wallpaper_count++;
|
||||
}
|
||||
}
|
||||
int fd = sys_open(wp->path, "r");
|
||||
if (fd >= 0) {
|
||||
int size = sys_seek(fd, 0, 2); // SEEK_END
|
||||
sys_seek(fd, 0, 0); // SEEK_SET
|
||||
if (size > 0 && size < 8 * 1024 * 1024) {
|
||||
unsigned char *buf = (unsigned char *)malloc(size);
|
||||
if (buf) {
|
||||
sys_read(fd, buf, size);
|
||||
int img_w, img_h, channels;
|
||||
unsigned char *img = stbi_load_from_memory(buf, size, &img_w, &img_h, &channels, 4);
|
||||
if (img && img_w > 0 && img_h > 0) {
|
||||
scale_rgba_to_argb(img, img_w, img_h, wp->thumb, WALLPAPER_THUMB_W, WALLPAPER_THUMB_H);
|
||||
wp->valid = 1;
|
||||
|
||||
static void load_wallpapers(void) {
|
||||
void *job_args[1] = { NULL };
|
||||
sys_parallel_run(decode_wallpapers_task, job_args, 1);
|
||||
sys_mkdir("/Library/Caches");
|
||||
sys_mkdir("/Library/Caches/Thumbnails");
|
||||
int swfd = sys_open(cache_path, "w");
|
||||
if (swfd >= 0) {
|
||||
sys_write_fs(swfd, wp->thumb, WALLPAPER_THUMB_W * WALLPAPER_THUMB_H * 4);
|
||||
sys_close(swfd);
|
||||
}
|
||||
}
|
||||
if (img) stbi_image_free(img);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
sys_close(fd);
|
||||
}
|
||||
|
||||
for (int i = 0; i < wallpaper_count; i++) {
|
||||
int tx = (i % 3) * (WALLPAPER_THUMB_W + 15);
|
||||
int ty = (i / 3) * (WALLPAPER_THUMB_H + 30);
|
||||
widget_button_init(&btn_wp_thumbs[i], 8 + tx, 306 + ty, WALLPAPER_THUMB_W + 8, WALLPAPER_THUMB_H + 20, "");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint32_t parse_rgb_separate(const char *r, const char *g, const char *b) {
|
||||
|
|
@ -498,7 +548,6 @@ static uint32_t parse_rgb_separate(const char *r, const char *g, const char *b)
|
|||
static void control_panel_paint_main(ui_window_t win) {
|
||||
int offset_x = 8;
|
||||
int offset_y = 6;
|
||||
int win_w = 350;
|
||||
|
||||
int item_y = 0;
|
||||
int item_h = 60;
|
||||
|
|
@ -815,15 +864,23 @@ static void control_panel_paint_mouse(ui_window_t win) {
|
|||
int section_y = offset_y + 65;
|
||||
ui_draw_string(win, offset_x, section_y, "Speed:", COLOR_DARK_TEXT);
|
||||
|
||||
ui_draw_rounded_rect_filled(win, offset_x + 60, section_y + 8, 200, 8, 4, COLOR_DARK_PANEL);
|
||||
|
||||
int knob_x = offset_x + 60 + (mouse_speed - 1) * 190 / 49;
|
||||
ui_draw_rounded_rect_filled(win, knob_x, section_y + 2, 10, 14, 3, 0xFF4A90E2);
|
||||
slider_mouse.value = (float)mouse_speed;
|
||||
widget_slider_draw(&settings_ctx, &slider_mouse);
|
||||
|
||||
ui_draw_string(win, offset_x + 270, section_y + 4, "x", COLOR_DARK_TEXT);
|
||||
char speed_str[4];
|
||||
cli_itoa(mouse_speed, speed_str);
|
||||
ui_draw_string(win, offset_x + 280, section_y + 4, speed_str, COLOR_DARK_TEXT);
|
||||
|
||||
section_y += 40;
|
||||
ui_draw_string(win, offset_x, section_y, "Size:", COLOR_DARK_TEXT);
|
||||
|
||||
slider_cursor_size.value = (float)mouse_cursor_scale_tenths;
|
||||
widget_slider_draw(&settings_ctx, &slider_cursor_size);
|
||||
|
||||
char scale_str[8];
|
||||
format_scale_tenths(mouse_cursor_scale_tenths, scale_str);
|
||||
ui_draw_string(win, offset_x + 270, section_y + 4, scale_str, COLOR_DARK_TEXT);
|
||||
}
|
||||
|
||||
static void on_font_scroll(void *user_data, int new_scroll_y) {
|
||||
|
|
@ -982,6 +1039,7 @@ static void save_desktop_config(void) {
|
|||
|
||||
static void save_mouse_config(void) {
|
||||
sys_system(SYSTEM_CMD_SET_MOUSE_SPEED, mouse_speed, 0, 0, 0);
|
||||
sys_system(SYSTEM_CMD_SET_MOUSE_CURSOR_SCALE, mouse_cursor_scale_tenths, 0, 0, 0);
|
||||
}
|
||||
|
||||
static int parse_ip(const char* str, net_ipv4_address_t* ip) {
|
||||
|
|
@ -1006,41 +1064,7 @@ static int parse_ip(const char* str, net_ipv4_address_t* ip) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void fetch_kernel_state(void) {
|
||||
desktop_snap_to_grid = sys_system(SYSTEM_CMD_GET_DESKTOP_PROP, 1, 0, 0, 0);
|
||||
desktop_auto_align = sys_system(SYSTEM_CMD_GET_DESKTOP_PROP, 2, 0, 0, 0);
|
||||
desktop_max_rows_per_col = sys_system(SYSTEM_CMD_GET_DESKTOP_PROP, 3, 0, 0, 0);
|
||||
desktop_max_cols = sys_system(SYSTEM_CMD_GET_DESKTOP_PROP, 4, 0, 0, 0);
|
||||
mouse_speed = sys_system(SYSTEM_CMD_GET_MOUSE_SPEED, 0, 0, 0, 0);
|
||||
|
||||
net_ipv4_address_t kip;
|
||||
if (sys_network_get_ip(&kip) == 0) {
|
||||
char bp[4];
|
||||
net_ip[0] = 0;
|
||||
for (int i=0; i<4; i++) {
|
||||
cli_itoa(kip.bytes[i], bp);
|
||||
strcat(net_ip, bp);
|
||||
if (i < 3) strcat(net_ip, ".");
|
||||
}
|
||||
}
|
||||
|
||||
if (sys_get_dns_server(&kip) == 0) {
|
||||
char bp[4];
|
||||
net_dns[0] = 0;
|
||||
for (int i=0; i<4; i++) {
|
||||
cli_itoa(kip.bytes[i], bp);
|
||||
strcat(net_dns, bp);
|
||||
if (i < 3) strcat(net_dns, ".");
|
||||
}
|
||||
}
|
||||
|
||||
init_dynamic_resolutions();
|
||||
load_wallpapers();
|
||||
}
|
||||
|
||||
static void control_panel_handle_mouse(int x, int y, bool is_down, bool is_click) {
|
||||
int win_w = 350;
|
||||
|
||||
if (current_view != VIEW_MAIN && widget_button_handle_mouse(&btn_back, x, y, is_down, is_click, NULL)) {
|
||||
if (is_click) {
|
||||
current_view = VIEW_MAIN;
|
||||
|
|
@ -1218,7 +1242,12 @@ static void control_panel_handle_mouse(int x, int y, bool is_down, bool is_click
|
|||
|
||||
if (current_view == VIEW_MAIN) {
|
||||
if (widget_button_handle_mouse(&btn_main_wallpaper, x, y, is_down, is_click, NULL)) {
|
||||
if (is_click) { current_view = VIEW_WALLPAPER; focused_field = -1; btn_main_wallpaper.pressed = false; }
|
||||
if (is_click) {
|
||||
current_view = VIEW_WALLPAPER;
|
||||
focused_field = -1;
|
||||
btn_main_wallpaper.pressed = false;
|
||||
load_wallpapers();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (widget_button_handle_mouse(&btn_main_network, x, y, is_down, is_click, NULL)) {
|
||||
|
|
@ -1255,18 +1284,26 @@ static void control_panel_handle_mouse(int x, int y, bool is_down, bool is_click
|
|||
}
|
||||
|
||||
if (current_view == VIEW_MOUSE) {
|
||||
if (is_down || is_click) {
|
||||
int offset_x = 8;
|
||||
int offset_y = 6;
|
||||
int section_y = offset_y + 65;
|
||||
if (x >= offset_x + 60 && x <= offset_x + 260 && y >= section_y && y <= section_y + 20) {
|
||||
int new_speed = 1 + (x - (offset_x + 60)) * 49 / 200;
|
||||
if (new_speed < 1) new_speed = 1;
|
||||
if (new_speed > 50) new_speed = 50;
|
||||
if (widget_slider_handle_mouse(&slider_mouse, x, y, is_down, is_click, NULL)) {
|
||||
int new_speed = (int)(slider_mouse.value);
|
||||
focused_field = -1; // slider doesn't use textbox, so clear focus on click
|
||||
|
||||
if (new_speed != mouse_speed) {
|
||||
mouse_speed = new_speed;
|
||||
save_mouse_config();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (widget_slider_handle_mouse(&slider_cursor_size, x, y, is_down, is_click, NULL)) {
|
||||
int new_scale = (int)(slider_cursor_size.value);
|
||||
focused_field = -1;
|
||||
|
||||
if (new_scale != mouse_cursor_scale_tenths) {
|
||||
mouse_cursor_scale_tenths = new_scale;
|
||||
save_mouse_config();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1385,6 +1422,12 @@ static void init_settings_widgets(void) {
|
|||
// Display View Textboxes
|
||||
widget_textbox_init(&tb_custom_w, 8, 276, 60, 25, custom_res_w, 5);
|
||||
widget_textbox_init(&tb_custom_h, 88, 276, 60, 25, custom_res_h, 5);
|
||||
|
||||
widget_slider_init(&slider_mouse, 68, 71, 200, 20, 1.0f, 50.0f, (float)mouse_speed);
|
||||
slider_mouse.step = 1.0f;
|
||||
|
||||
widget_slider_init(&slider_cursor_size, 68, 111, 200, 20, 10.0f, 40.0f, (float)mouse_cursor_scale_tenths);
|
||||
slider_cursor_size.step = 1.0f;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
|
@ -1404,6 +1447,9 @@ int main(int argc, char **argv) {
|
|||
desktop_max_rows_per_col = sys_system(SYSTEM_CMD_GET_DESKTOP_PROP, 3, 0, 0, 0);
|
||||
desktop_max_cols = sys_system(SYSTEM_CMD_GET_DESKTOP_PROP, 4, 0, 0, 0);
|
||||
mouse_speed = sys_system(SYSTEM_CMD_GET_MOUSE_SPEED, 0, 0, 0, 0);
|
||||
mouse_cursor_scale_tenths = sys_system(SYSTEM_CMD_GET_MOUSE_CURSOR_SCALE, 0, 0, 0, 0);
|
||||
if (mouse_cursor_scale_tenths < 10) mouse_cursor_scale_tenths = 10;
|
||||
if (mouse_cursor_scale_tenths > 40) mouse_cursor_scale_tenths = 40;
|
||||
load_settings_icons();
|
||||
|
||||
// Set initial widget states
|
||||
|
|
@ -1418,8 +1464,6 @@ int main(int argc, char **argv) {
|
|||
control_panel_paint(win);
|
||||
ui_mark_dirty(win, 0, 0, 350, 500);
|
||||
|
||||
load_wallpapers(); // load after first paint to avoid startup delay
|
||||
|
||||
gui_event_t ev;
|
||||
while (1) {
|
||||
bool dirty = false;
|
||||
|
|
@ -1429,12 +1473,11 @@ int main(int argc, char **argv) {
|
|||
dirty = true;
|
||||
|
||||
} else if (ev.type == GUI_EVENT_CLICK ||
|
||||
ev.type == GUI_EVENT_MOUSE_DOWN ||
|
||||
ev.type == GUI_EVENT_MOUSE_MOVE ||
|
||||
ev.type == GUI_EVENT_MOUSE_UP) {
|
||||
bool down = false;
|
||||
|
||||
if (ev.type == GUI_EVENT_MOUSE_DOWN || ev.type == GUI_EVENT_CLICK) {
|
||||
if (ev.type == GUI_EVENT_CLICK) {
|
||||
down = true;
|
||||
} else if (ev.type == GUI_EVENT_MOUSE_MOVE) {
|
||||
down = (ev.arg3 & 1);
|
||||
|
|
@ -1442,13 +1485,15 @@ int main(int argc, char **argv) {
|
|||
down = false;
|
||||
}
|
||||
|
||||
control_panel_handle_mouse(
|
||||
ev.arg1,
|
||||
ev.arg2,
|
||||
down,
|
||||
ev.type == GUI_EVENT_CLICK
|
||||
);
|
||||
dirty = true;
|
||||
if (ev.type != GUI_EVENT_MOUSE_MOVE || down) {
|
||||
control_panel_handle_mouse(
|
||||
ev.arg1,
|
||||
ev.arg2,
|
||||
down,
|
||||
ev.type == GUI_EVENT_CLICK
|
||||
);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
} else if (ev.type == GUI_EVENT_MOUSE_WHEEL) {
|
||||
if (current_view == VIEW_FONTS) {
|
||||
|
|
@ -1482,10 +1527,14 @@ int main(int argc, char **argv) {
|
|||
ui_mark_dirty(win, 0, 0, 350, 500);
|
||||
}
|
||||
} else {
|
||||
sleep(10);
|
||||
if (current_view == VIEW_WALLPAPER && load_next_wallpaper_thumb()) {
|
||||
control_panel_paint(win);
|
||||
ui_mark_dirty(win, 0, 0, 350, 500);
|
||||
} else {
|
||||
sleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@
|
|||
#define SYSTEM_CMD_NETWORK_GET_NIC_NAME 48
|
||||
#define SYSTEM_CMD_SET_KEYBOARD_LAYOUT 49
|
||||
#define SYSTEM_CMD_GET_KEYBOARD_LAYOUT 51
|
||||
#define SYSTEM_CMD_SET_MOUSE_CURSOR_SCALE 52
|
||||
#define SYSTEM_CMD_GET_MOUSE_CURSOR_SCALE 53
|
||||
#define SYSTEM_CMD_SET_TEXT_COLOR 29
|
||||
#define SYSTEM_CMD_SET_WALLPAPER_PATH 31
|
||||
#define SYSTEM_CMD_RTC_SET 32
|
||||
|
|
|
|||
|
|
@ -497,3 +497,149 @@ bool widget_checkbox_handle_mouse(widget_checkbox_t *cb, int mx, int my, bool mo
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --- Slider ---
|
||||
void widget_slider_init(widget_slider_t *sl, int x, int y, int w, int h, float min, float max, float value) {
|
||||
sl->x = x;
|
||||
sl->y = y;
|
||||
sl->w = w;
|
||||
sl->h = h;
|
||||
|
||||
sl->min = min;
|
||||
sl->max = max;
|
||||
sl->value = value;
|
||||
sl->step = 0.0f;
|
||||
|
||||
sl->dragging = false;
|
||||
sl->hovered = false;
|
||||
sl->on_change = NULL;
|
||||
}
|
||||
|
||||
void widget_slider_draw(widget_context_t *ctx, widget_slider_t *sl) {
|
||||
uint32_t track_bg = ctx->use_light_theme ? 0xFFD0D0D0 : 0xFF404040;
|
||||
uint32_t fill_color = ctx->use_light_theme ? 0xFF007AFF : 0xFF4A90E2;
|
||||
uint32_t thumb_color = ctx->use_light_theme ? 0xFF606060 : 0xFFDDDDDD;
|
||||
|
||||
if (sl->dragging) {
|
||||
thumb_color = ctx->use_light_theme ? 0xFF404040 : 0xFFFFFFFF;
|
||||
} else if (sl->hovered) {
|
||||
thumb_color = ctx->use_light_theme ? 0xFF505050 : 0xFFF0F0F0;
|
||||
}
|
||||
|
||||
int track_h = 4;
|
||||
int track_y = sl->y + (sl->h - track_h) / 2;
|
||||
|
||||
float t = (sl->value - sl->min) / (sl->max - sl->min);
|
||||
if (t < 0) t = 0;
|
||||
if (t > 1) t = 1;
|
||||
|
||||
int thumb_x = sl->x + (int)(t * sl->w);
|
||||
|
||||
if (ctx->draw_rounded_rect_filled) {
|
||||
ctx->draw_rounded_rect_filled(ctx->user_data, sl->x, track_y, sl->w, track_h, 2, track_bg);
|
||||
} else {
|
||||
ctx->draw_rect(ctx->user_data, sl->x, track_y, sl->w, track_h, track_bg);
|
||||
}
|
||||
|
||||
if (ctx->draw_rounded_rect_filled) {
|
||||
ctx->draw_rounded_rect_filled(ctx->user_data, sl->x, track_y, thumb_x - sl->x, track_h, 2, fill_color);
|
||||
} else {
|
||||
ctx->draw_rect(ctx->user_data, sl->x, track_y, thumb_x - sl->x, track_h, fill_color);
|
||||
}
|
||||
|
||||
int radius = sl->h / 2;
|
||||
int cx = thumb_x - radius;
|
||||
|
||||
if (ctx->draw_rounded_rect_filled) {
|
||||
ctx->draw_rounded_rect_filled(ctx->user_data, cx, sl->y, sl->h, sl->h, radius, thumb_color);
|
||||
} else {
|
||||
ctx->draw_rect(ctx->user_data, cx, sl->y, sl->h, sl->h, thumb_color);
|
||||
}
|
||||
}
|
||||
|
||||
static float widget_roundf(float x) {
|
||||
return (x >= 0.0f) ? (float)((int)(x + 0.5f)) : (float)((int)(x - 0.5f));
|
||||
}
|
||||
|
||||
bool widget_slider_handle_mouse(widget_slider_t *sl, int mx, int my, bool mouse_down, bool mouse_clicked, void *user_data) {
|
||||
bool in_bounds = (mx >= sl->x && mx < sl->x + sl->w &&
|
||||
my >= sl->y && my < sl->y + sl->h);
|
||||
|
||||
sl->hovered = in_bounds;
|
||||
|
||||
if (mouse_clicked && in_bounds) {
|
||||
sl->dragging = true;
|
||||
}
|
||||
|
||||
if (!mouse_down) {
|
||||
sl->dragging = false;
|
||||
}
|
||||
|
||||
if (sl->dragging) {
|
||||
float t = (float)(mx - sl->x) / (float)sl->w;
|
||||
|
||||
if (t < 0) t = 0;
|
||||
if (t > 1) t = 1;
|
||||
|
||||
float new_value = sl->min + t * (sl->max - sl->min);
|
||||
|
||||
if (sl->step > 0.0f) {
|
||||
new_value = sl->min + widget_roundf((new_value - sl->min) / sl->step) * sl->step;
|
||||
}
|
||||
|
||||
if (new_value != sl->value) {
|
||||
sl->value = new_value;
|
||||
if (sl->on_change) sl->on_change(user_data, sl->value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return in_bounds;
|
||||
}
|
||||
|
||||
static void widget_itoa(int value, char *buf) {
|
||||
int i = 0;
|
||||
int neg = 0;
|
||||
|
||||
if (value == 0) {
|
||||
buf[0] = '0';
|
||||
buf[1] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value < 0) {
|
||||
neg = 1;
|
||||
value = -value;
|
||||
}
|
||||
|
||||
while (value > 0) {
|
||||
buf[i++] = (char)('0' + (value % 10));
|
||||
value /= 10;
|
||||
}
|
||||
|
||||
if (neg) {
|
||||
buf[i++] = '-';
|
||||
}
|
||||
|
||||
buf[i] = 0;
|
||||
|
||||
for (int a = 0, b = i - 1; a < b; a++, b--) {
|
||||
char t = buf[a];
|
||||
buf[a] = buf[b];
|
||||
buf[b] = t;
|
||||
}
|
||||
}
|
||||
|
||||
void widget_slider_draw_value(widget_context_t *ctx, widget_slider_t *sl) {
|
||||
if (!ctx->draw_string) return;
|
||||
|
||||
char buf[16];
|
||||
widget_itoa((int)sl->value, buf);
|
||||
|
||||
ctx->draw_string(ctx->user_data,
|
||||
sl->x + sl->w + 8,
|
||||
sl->y + (sl->h - 8) / 2,
|
||||
buf,
|
||||
ctx->use_light_theme ? 0xFF000000 : 0xFFFFFFFF);
|
||||
}
|
||||
|
|
@ -86,6 +86,29 @@ typedef struct {
|
|||
void (*on_toggle)(void *user_data, bool new_state);
|
||||
} widget_checkbox_t;
|
||||
|
||||
// --- Slider ---
|
||||
typedef struct {
|
||||
int x, y, w, h;
|
||||
|
||||
float min;
|
||||
float max;
|
||||
float value;
|
||||
float step; // 0 = not steps
|
||||
|
||||
bool dragging;
|
||||
bool hovered;
|
||||
|
||||
void (*on_change)(void *user_data, float value);
|
||||
} widget_slider_t;
|
||||
void widget_slider_init(widget_slider_t *sl, int x, int y, int w, int h,
|
||||
float min, float max, float value);
|
||||
|
||||
void widget_slider_draw(widget_context_t *ctx, widget_slider_t *sl);
|
||||
|
||||
bool widget_slider_handle_mouse(widget_slider_t *sl, int mx, int my,
|
||||
bool mouse_down, bool mouse_clicked,
|
||||
void *user_data);
|
||||
|
||||
void widget_checkbox_init(widget_checkbox_t *cb, int x, int y, int w, int h, const char *text, bool is_radio);
|
||||
void widget_checkbox_draw(widget_context_t *ctx, widget_checkbox_t *cb);
|
||||
bool widget_checkbox_handle_mouse(widget_checkbox_t *cb, int mx, int my, bool mouse_clicked, void *user_data);
|
||||
|
|
|
|||
102
src/wm/wm.c
102
src/wm/wm.c
|
|
@ -408,9 +408,14 @@ static uint32_t timer_ticks = 0;
|
|||
|
||||
static int last_cursor_x = 400;
|
||||
static int last_cursor_y = 300;
|
||||
static int last_cursor_w = 18;
|
||||
static int last_cursor_h = 18;
|
||||
|
||||
#define CURSOR_W 18
|
||||
#define CURSOR_H 18
|
||||
#define CURSOR_BASE_W 18
|
||||
#define CURSOR_BASE_H 18
|
||||
#define CURSOR_SCALE_MIN_TENTHS 10
|
||||
#define CURSOR_SCALE_MAX_TENTHS 40
|
||||
#define CURSOR_SCALE_DEFAULT_TENTHS 10
|
||||
|
||||
static bool periodic_refresh_pending = false;
|
||||
|
||||
|
|
@ -433,10 +438,62 @@ int desktop_max_cols = 23;
|
|||
|
||||
// Mouse Settings
|
||||
int mouse_speed = 10;
|
||||
static int mouse_cursor_scale_tenths = CURSOR_SCALE_DEFAULT_TENTHS;
|
||||
static int mouse_accum_x = 0;
|
||||
static int mouse_accum_y = 0;
|
||||
Window *active_mouse_capture_win = NULL;
|
||||
|
||||
static int cursor_clamp_scale_tenths(int scale) {
|
||||
if (scale < CURSOR_SCALE_MIN_TENTHS) return CURSOR_SCALE_MIN_TENTHS;
|
||||
if (scale > CURSOR_SCALE_MAX_TENTHS) return CURSOR_SCALE_MAX_TENTHS;
|
||||
return scale;
|
||||
}
|
||||
|
||||
static int cursor_scaled_size(int base, int scale_tenths) {
|
||||
scale_tenths = cursor_clamp_scale_tenths(scale_tenths);
|
||||
return (base * scale_tenths + 9) / 10;
|
||||
}
|
||||
|
||||
static int cursor_width_for_scale(int scale_tenths) {
|
||||
return cursor_scaled_size(CURSOR_BASE_W, scale_tenths);
|
||||
}
|
||||
|
||||
static int cursor_height_for_scale(int scale_tenths) {
|
||||
return cursor_scaled_size(CURSOR_BASE_H, scale_tenths);
|
||||
}
|
||||
|
||||
static int cursor_current_width(void) {
|
||||
return cursor_width_for_scale(mouse_cursor_scale_tenths);
|
||||
}
|
||||
|
||||
static int cursor_current_height(void) {
|
||||
return cursor_height_for_scale(mouse_cursor_scale_tenths);
|
||||
}
|
||||
|
||||
void wm_set_cursor_scale_tenths(int scale) {
|
||||
scale = cursor_clamp_scale_tenths(scale);
|
||||
|
||||
uint64_t rflags = wm_lock_acquire();
|
||||
if (scale != mouse_cursor_scale_tenths) {
|
||||
int old_w = cursor_current_width();
|
||||
int old_h = cursor_current_height();
|
||||
|
||||
mouse_cursor_scale_tenths = scale;
|
||||
|
||||
wm_mark_dirty(last_cursor_x, last_cursor_y, last_cursor_w, last_cursor_h);
|
||||
wm_mark_dirty(mx, my, old_w, old_h);
|
||||
wm_mark_dirty(mx, my, cursor_current_width(), cursor_current_height());
|
||||
}
|
||||
wm_lock_release(rflags);
|
||||
}
|
||||
|
||||
int wm_get_cursor_scale_tenths(void) {
|
||||
uint64_t rflags = wm_lock_acquire();
|
||||
int scale = mouse_cursor_scale_tenths;
|
||||
wm_lock_release(rflags);
|
||||
return scale;
|
||||
}
|
||||
|
||||
// Helper to check if string ends with suffix
|
||||
static bool str_ends_with(const char *str, const char *suffix) {
|
||||
int str_len = 0; while(str[str_len]) str_len++;
|
||||
|
|
@ -2198,7 +2255,7 @@ void draw_window(Window *win) {
|
|||
|
||||
void draw_cursor(int x, int y) {
|
||||
// '.' transparent, 'w' white outline, 'b' black fill
|
||||
static const char cursor_bitmap[CURSOR_H][CURSOR_W + 1] = {
|
||||
static const char cursor_bitmap[CURSOR_BASE_H][CURSOR_BASE_W + 1] = {
|
||||
"w.................",
|
||||
"ww................",
|
||||
"wbw...............",
|
||||
|
|
@ -2216,16 +2273,21 @@ void draw_cursor(int x, int y) {
|
|||
"wwwwbbbw..........",
|
||||
"....wbbw..........",
|
||||
".....wbw..........",
|
||||
"......ww..........."
|
||||
"......ww.........."
|
||||
};
|
||||
|
||||
for (int r = 0; r < CURSOR_H; r++) {
|
||||
for (int c = 0; c < CURSOR_W; c++) {
|
||||
int draw_w = cursor_current_width();
|
||||
int draw_h = cursor_current_height();
|
||||
|
||||
for (int y_off = 0; y_off < draw_h; y_off++) {
|
||||
int r = (y_off * CURSOR_BASE_H) / draw_h;
|
||||
for (int x_off = 0; x_off < draw_w; x_off++) {
|
||||
int c = (x_off * CURSOR_BASE_W) / draw_w;
|
||||
char p = cursor_bitmap[r][c];
|
||||
if (p == 'w') {
|
||||
put_pixel(x + c, y + r, COLOR_WHITE);
|
||||
put_pixel(x + x_off, y + y_off, COLOR_WHITE);
|
||||
} else if (p == 'b') {
|
||||
put_pixel(x + c, y + r, COLOR_BLACK);
|
||||
put_pixel(x + x_off, y + y_off, COLOR_BLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2239,8 +2301,8 @@ static void erase_cursor(int x, int y) {
|
|||
// Clamp to screen
|
||||
int x1 = x < 0 ? 0 : x;
|
||||
int y1 = y < 0 ? 0 : y;
|
||||
int x2 = x + CURSOR_W > sw ? sw : x + CURSOR_W;
|
||||
int y2 = y + CURSOR_H > sh ? sh : y + CURSOR_H;
|
||||
int x2 = x + cursor_current_width() > sw ? sw : x + cursor_current_width();
|
||||
int y2 = y + cursor_current_height() > sh ? sh : y + cursor_current_height();
|
||||
int w = x2 - x1;
|
||||
int h = y2 - y1;
|
||||
|
||||
|
|
@ -2644,8 +2706,10 @@ void wm_paint(void) {
|
|||
int sh = get_screen_height();
|
||||
uint64_t rflags;
|
||||
rflags = wm_lock_acquire();
|
||||
wm_mark_dirty(last_cursor_x, last_cursor_y, CURSOR_W, CURSOR_H);
|
||||
wm_mark_dirty(mx, my, CURSOR_W, CURSOR_H);
|
||||
int cursor_w = cursor_current_width();
|
||||
int cursor_h = cursor_current_height();
|
||||
wm_mark_dirty(last_cursor_x, last_cursor_y, last_cursor_w, last_cursor_h);
|
||||
wm_mark_dirty(mx, my, cursor_w, cursor_h);
|
||||
|
||||
DirtyRect dirty = graphics_get_dirty_rect();
|
||||
if (menubar_dirty_pending) {
|
||||
|
|
@ -2719,6 +2783,8 @@ void wm_paint(void) {
|
|||
draw_cursor(mx, my);
|
||||
last_cursor_x = mx;
|
||||
last_cursor_y = my;
|
||||
last_cursor_w = cursor_w;
|
||||
last_cursor_h = cursor_h;
|
||||
graphics_flip_buffer();
|
||||
graphics_clear_dirty_no_lock();
|
||||
wm_lock_release(rflags);
|
||||
|
|
@ -3230,8 +3296,10 @@ static void wm_handle_mouse_internal(int dx, int dy, uint8_t buttons, int dz) {
|
|||
if (my >= sh) my = sh - 1;
|
||||
|
||||
if (move_x != 0 || move_y != 0) {
|
||||
wm_mark_dirty(prev_mx, prev_my, CURSOR_W, CURSOR_H);
|
||||
wm_mark_dirty(mx, my, CURSOR_W, CURSOR_H);
|
||||
int cursor_w = cursor_current_width();
|
||||
int cursor_h = cursor_current_height();
|
||||
wm_mark_dirty(prev_mx, prev_my, cursor_w, cursor_h);
|
||||
wm_mark_dirty(mx, my, cursor_w, cursor_h);
|
||||
}
|
||||
|
||||
if (dz != 0) {
|
||||
|
|
@ -3792,8 +3860,10 @@ static void wm_handle_mouse_internal(int dx, int dy, uint8_t buttons, int dz) {
|
|||
|
||||
if (prev_mx != mx || prev_my != my) {
|
||||
// Cursor moved - just mark dirty cursor areas
|
||||
wm_mark_dirty(prev_mx, prev_my, CURSOR_W, CURSOR_H);
|
||||
wm_mark_dirty(mx, my, CURSOR_W, CURSOR_H);
|
||||
int cursor_w = cursor_current_width();
|
||||
int cursor_h = cursor_current_height();
|
||||
wm_mark_dirty(prev_mx, prev_my, cursor_w, cursor_h);
|
||||
wm_mark_dirty(mx, my, cursor_w, cursor_h);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -152,5 +152,7 @@ extern int desktop_max_cols;
|
|||
|
||||
// Mouse Settings
|
||||
extern int mouse_speed;
|
||||
void wm_set_cursor_scale_tenths(int scale);
|
||||
int wm_get_cursor_scale_tenths(void);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue