mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
FEAT: resizing of window in viewer.c
This commit is contained in:
parent
9634ebb086
commit
2e28f860cb
2 changed files with 70 additions and 46 deletions
|
|
@ -9,8 +9,8 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define VIEWER_MAX_W 800
|
||||
#define VIEWER_MAX_H 600
|
||||
#define VIEWER_MAX_W 4096
|
||||
#define VIEWER_MAX_H 4096
|
||||
|
||||
static uint32_t *viewer_pixels = NULL;
|
||||
static uint32_t **viewer_frames = NULL;
|
||||
|
|
@ -24,6 +24,8 @@ static int viewer_img_h = 0;
|
|||
static char viewer_title[64] = "Viewer";
|
||||
static bool viewer_has_image = false;
|
||||
static char viewer_file_path[256];
|
||||
static bool resize_pending = false;
|
||||
static uint64_t last_resize_tick = 0;
|
||||
|
||||
static int win_w = 500;
|
||||
static int win_h = 400;
|
||||
|
|
@ -80,11 +82,13 @@ static void viewer_scale_rgba_to_argb(const unsigned char *rgba, int src_w, int
|
|||
}
|
||||
|
||||
static void viewer_paint(ui_window_t win) {
|
||||
int cx = 4;
|
||||
int cx = 0;
|
||||
int cy = 0;
|
||||
int cw = win_w - 8;
|
||||
int ch = win_h - 28;
|
||||
int cw = win_w;
|
||||
int ch = win_h - 20; // 20px header
|
||||
|
||||
// Clear background
|
||||
ui_draw_rect(win, 0, 0, win_w, win_h, 0xFF000000); // Black background
|
||||
|
||||
if (!viewer_has_image) {
|
||||
ui_draw_string(win, cx + 20, cy + ch / 2, "No image loaded", 0xFF888888);
|
||||
|
|
@ -94,46 +98,42 @@ static void viewer_paint(ui_window_t win) {
|
|||
uint32_t *pixels = viewer_pixels;
|
||||
if (viewer_frames) pixels = viewer_frames[viewer_current_frame];
|
||||
|
||||
// Maintain aspect ratio while fitting to window
|
||||
int disp_w = viewer_img_w;
|
||||
int disp_h = viewer_img_h;
|
||||
|
||||
if (disp_w > cw - 8) {
|
||||
disp_h = disp_h * (cw - 8) / disp_w;
|
||||
disp_w = cw - 8;
|
||||
}
|
||||
if (disp_h > ch - 40) {
|
||||
disp_w = disp_w * (ch - 40) / disp_h;
|
||||
disp_h = ch - 40;
|
||||
}
|
||||
|
||||
float sw = (float)cw / (float)viewer_img_w;
|
||||
float sh = (float)ch / (float)viewer_img_h;
|
||||
float scale = (sw < sh) ? sw : sh;
|
||||
|
||||
disp_w = (int)(viewer_img_w * scale);
|
||||
disp_h = (int)(viewer_img_h * scale);
|
||||
|
||||
int ox = cx + (cw - disp_w) / 2;
|
||||
int oy = cy + (ch - disp_h) / 2;
|
||||
|
||||
if (disp_w <= 0 || disp_h <= 0) return;
|
||||
|
||||
uint32_t *temp_buf = malloc(disp_w * disp_h * sizeof(uint32_t));
|
||||
if (temp_buf) {
|
||||
if (disp_w == viewer_img_w && disp_h == viewer_img_h) {
|
||||
// Fast path: 1:1
|
||||
for (int i = 0; i < disp_w * disp_h; i++) temp_buf[i] = pixels[i];
|
||||
} else {
|
||||
// Fixed-point 16.16
|
||||
uint32_t step_x = (viewer_img_w << 16) / disp_w;
|
||||
uint32_t step_y = (viewer_img_h << 16) / disp_h;
|
||||
uint32_t curr_y = 0;
|
||||
// Fixed-point 16.16
|
||||
uint32_t step_x = (viewer_img_w << 16) / disp_w;
|
||||
uint32_t step_y = (viewer_img_h << 16) / disp_h;
|
||||
uint32_t curr_y = 0;
|
||||
|
||||
for (int y = 0; y < disp_h; y++) {
|
||||
uint32_t src_y = curr_y >> 16;
|
||||
if (src_y >= (uint32_t)viewer_img_h) src_y = viewer_img_h - 1;
|
||||
uint32_t curr_x = 0;
|
||||
uint32_t src_row_off = src_y * viewer_img_w;
|
||||
uint32_t dst_row_off = y * disp_w;
|
||||
for (int x = 0; x < disp_w; x++) {
|
||||
uint32_t src_x = curr_x >> 16;
|
||||
if (src_x >= (uint32_t)viewer_img_w) src_x = viewer_img_w - 1;
|
||||
temp_buf[dst_row_off + x] = pixels[src_row_off + src_x];
|
||||
curr_x += step_x;
|
||||
}
|
||||
curr_y += step_y;
|
||||
for (int y = 0; y < disp_h; y++) {
|
||||
uint32_t src_y = curr_y >> 16;
|
||||
if (src_y >= (uint32_t)viewer_img_h) src_y = viewer_img_h - 1;
|
||||
uint32_t curr_x = 0;
|
||||
uint32_t src_row_off = src_y * viewer_img_w;
|
||||
uint32_t dst_row_off = y * disp_w;
|
||||
for (int x = 0; x < disp_w; x++) {
|
||||
uint32_t src_x = curr_x >> 16;
|
||||
if (src_x >= (uint32_t)viewer_img_w) src_x = viewer_img_w - 1;
|
||||
temp_buf[dst_row_off + x] = pixels[src_row_off + src_x];
|
||||
curr_x += step_x;
|
||||
}
|
||||
curr_y += step_y;
|
||||
}
|
||||
ui_draw_image(win, ox, oy, disp_w, disp_h, temp_buf);
|
||||
free(temp_buf);
|
||||
|
|
@ -271,8 +271,13 @@ void viewer_open_file(const char *path) {
|
|||
viewer_title[ti] = 0;
|
||||
|
||||
win_w = fit_w + 16;
|
||||
if (win_w < 200) win_w = 200;
|
||||
win_h = fit_h + 34;
|
||||
|
||||
// Cap initial window size to 1024x768 (or image size if smaller)
|
||||
if (win_w > 1024) win_w = 1024;
|
||||
if (win_h > 768) win_h = 768;
|
||||
|
||||
if (win_w < 200) win_w = 200;
|
||||
if (win_h < 100) win_h = 100;
|
||||
}
|
||||
|
||||
|
|
@ -284,18 +289,37 @@ int main(int argc, char **argv) {
|
|||
ui_window_t win = ui_window_create(viewer_title, 100, 50, win_w, win_h);
|
||||
if (!win) return 1;
|
||||
|
||||
ui_window_set_resizable(win, true);
|
||||
|
||||
gui_event_t ev;
|
||||
while (1) {
|
||||
if (ui_get_event(win, &ev)) {
|
||||
if (ev.type == GUI_EVENT_PAINT) {
|
||||
viewer_paint(win);
|
||||
ui_mark_dirty(win, 0, 0, win_w, win_h - 20);
|
||||
} else if (ev.type == GUI_EVENT_RESIZE) {
|
||||
win_w = ev.arg1;
|
||||
win_h = ev.arg2;
|
||||
resize_pending = true;
|
||||
last_resize_tick = sys_system(16, 0, 0, 0, 0);
|
||||
// Fast background clear during active resize
|
||||
ui_draw_rect(win, 0, 0, win_w, win_h, 0xFF000000);
|
||||
ui_mark_dirty(win, 0, 0, win_w, win_h - 20);
|
||||
} else if (ev.type == GUI_EVENT_CLICK) {
|
||||
// No actions currently
|
||||
} else if (ev.type == GUI_EVENT_CLOSE) {
|
||||
sys_exit(0);
|
||||
}
|
||||
} else {
|
||||
if (resize_pending) {
|
||||
uint64_t now = sys_system(16, 0, 0, 0, 0);
|
||||
if (now > last_resize_tick + 10) {
|
||||
viewer_paint(win);
|
||||
ui_mark_dirty(win, 0, 0, win_w, win_h - 20);
|
||||
resize_pending = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (viewer_has_image && viewer_frame_count > 1) {
|
||||
uint64_t now = sys_system(16, 0, 0, 0, 0);
|
||||
if (now >= viewer_next_frame_tick) {
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ bool explorer_delete_recursive(const char *path) {
|
|||
for (int k = i + 1; k < len; k++) filename[j++] = path[k];
|
||||
filename[j] = 0;
|
||||
|
||||
char drive_prefix[3] = "A:";
|
||||
char drive_prefix[3] = "/";
|
||||
if (path[0] && path[1] == ':') {
|
||||
drive_prefix[0] = path[0];
|
||||
}
|
||||
|
|
@ -810,15 +810,15 @@ static void explorer_open_target(const char *path) {
|
|||
if (explorer_str_ends_with(path, ".elf")) {
|
||||
process_create_elf(path, NULL);
|
||||
} else if (explorer_str_ends_with(path, ".pdf")) {
|
||||
process_create_elf("A:/bin/boredword.elf", path);
|
||||
process_create_elf("/bin/boredword.elf", path);
|
||||
} else if (explorer_is_markdown_file(path)) {
|
||||
process_create_elf("A:/bin/markdown.elf", path);
|
||||
process_create_elf("/bin/markdown.elf", path);
|
||||
} else if (explorer_str_ends_with(path, ".pnt")) {
|
||||
process_create_elf("A:/bin/paint.elf", path);
|
||||
process_create_elf("/bin/paint.elf", path);
|
||||
} else if (explorer_is_image_file(path)) {
|
||||
process_create_elf("A:/bin/viewer.elf", path);
|
||||
process_create_elf("/bin/viewer.elf", path);
|
||||
} else {
|
||||
process_create_elf("A:/bin/txtedit.elf", path);
|
||||
process_create_elf("/bin/txtedit.elf", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1702,7 +1702,7 @@ static void explorer_handle_file_context_menu_click(Window *win, int x, int y) {
|
|||
state->dialog_input_cursor = explorer_strlen(state->dialog_input);
|
||||
explorer_strcpy(state->dialog_target_path, full_path);
|
||||
} else if (clicked_action == 110) { // Open with Text Editor
|
||||
process_create_elf("A:/bin/txtedit.elf", full_path);
|
||||
process_create_elf("/bin/txtedit.elf", full_path);
|
||||
} else if (clicked_action == ACTION_RESTORE) {
|
||||
explorer_restore_file(win, state->file_context_menu_item);
|
||||
} else if (clicked_action == ACTION_CREATE_SHORTCUT) {
|
||||
|
|
@ -1886,7 +1886,7 @@ Window* explorer_create_window(const char *path) {
|
|||
state->explorer_scroll_row = 0;
|
||||
state->dialog_state = DIALOG_NONE;
|
||||
|
||||
if (explorer_strcmp(path, "/") == 0) explorer_load_directory(win, "A:/");
|
||||
if (explorer_strcmp(path, "/") == 0) explorer_load_directory(win, "/");
|
||||
else explorer_load_directory(win, path);
|
||||
|
||||
explorer_wins[explorer_win_count++] = win;
|
||||
|
|
@ -1923,11 +1923,11 @@ void explorer_init(void) {
|
|||
state->dialog_state = DIALOG_NONE;
|
||||
|
||||
explorer_wins[explorer_win_count++] = &win_explorer;
|
||||
explorer_load_directory(&win_explorer, "A:/");
|
||||
explorer_load_directory(&win_explorer, "/");
|
||||
}
|
||||
void explorer_reset(void) {
|
||||
ExplorerState *state = (ExplorerState*)win_explorer.data;
|
||||
explorer_load_directory(&win_explorer, "A:/");
|
||||
explorer_load_directory(&win_explorer, "/");
|
||||
state->explorer_scroll_row = 0;
|
||||
win_explorer.focused = false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue