feat: port Disks app to MTK
This commit is contained in:
+94
-82
@@ -15,7 +15,6 @@ int g_win_w = INIT_W;
|
||||
int g_win_h = INIT_H;
|
||||
|
||||
DiskToolState g_state;
|
||||
TrueTypeFont* g_font = nullptr;
|
||||
|
||||
const Color part_colors[NUM_PART_COLORS] = {
|
||||
Color::from_rgb(0x42, 0x7A, 0xB5),
|
||||
@@ -66,61 +65,44 @@ void format_disk_size(char* buf, int bufsize, uint64_t sectors, uint16_t sectorS
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Toolbar hit testing (returns button widths matching render layout)
|
||||
// Toolbar hit testing
|
||||
// ============================================================================
|
||||
|
||||
static int disk_btn_width(int idx) {
|
||||
char label[8];
|
||||
snprintf(label, sizeof(label), "Disk %d", idx);
|
||||
int lw = g_font ? g_font->measure_text(label, FONT_SIZE) + 16 : 48;
|
||||
return lw;
|
||||
}
|
||||
|
||||
static bool handle_toolbar_click(int mx, int my) {
|
||||
if (my >= TOOLBAR_H || my < TB_BTN_Y) return false;
|
||||
|
||||
auto& dt = g_state;
|
||||
if (dt.disk_count == 0) return false;
|
||||
bool has_sel = dt.selected_part >= 0;
|
||||
|
||||
// Disk selector buttons
|
||||
int bx = 8;
|
||||
for (int i = 0; i < dt.disk_count; i++) {
|
||||
int lw = disk_btn_width(i);
|
||||
if (mx >= bx && mx < bx + lw && my >= TB_BTN_Y && my < TB_BTN_Y + TB_BTN_H) {
|
||||
if (toolbar_disk_button_rect(i).contains(mx, my)) {
|
||||
dt.selected_disk = i;
|
||||
dt.selected_part = -1;
|
||||
dt.scroll_y = 0;
|
||||
return true;
|
||||
}
|
||||
bx += lw + 6;
|
||||
}
|
||||
|
||||
// Right-side buttons (must match render layout)
|
||||
int rx = g_win_w - 8;
|
||||
|
||||
int ref_w = 64; rx -= ref_w;
|
||||
if (mx >= rx && mx < rx + ref_w && my >= TB_BTN_Y && my < TB_BTN_Y + TB_BTN_H) {
|
||||
if (toolbar_refresh_button_rect().contains(mx, my)) {
|
||||
disktool_refresh();
|
||||
set_status("Refreshed");
|
||||
return true;
|
||||
}
|
||||
rx -= 6;
|
||||
|
||||
int mnt_w = 60; rx -= mnt_w;
|
||||
if (mx >= rx && mx < rx + mnt_w && my >= TB_BTN_Y && my < TB_BTN_Y + TB_BTN_H) {
|
||||
if (has_sel && toolbar_mount_button_rect().contains(mx, my)) {
|
||||
do_mount_partition();
|
||||
return true;
|
||||
}
|
||||
rx -= 6;
|
||||
|
||||
int fmt_w = 64; rx -= fmt_w;
|
||||
if (mx >= rx && mx < rx + fmt_w && my >= TB_BTN_Y && my < TB_BTN_Y + TB_BTN_H) {
|
||||
if (has_sel && toolbar_format_button_rect().contains(mx, my)) {
|
||||
open_format_dialog();
|
||||
return true;
|
||||
}
|
||||
rx -= 6;
|
||||
|
||||
int np_w = 74; rx -= np_w;
|
||||
if (mx >= rx && mx < rx + np_w && my >= TB_BTN_Y && my < TB_BTN_Y + TB_BTN_H) {
|
||||
if (toolbar_newpart_button_rect().contains(mx, my)) {
|
||||
do_create_partition();
|
||||
return true;
|
||||
}
|
||||
@@ -136,8 +118,7 @@ static bool handle_content_click(int mx, int my) {
|
||||
auto& dt = g_state;
|
||||
if (dt.disk_count == 0 || dt.selected_disk < 0) return false;
|
||||
|
||||
int fh = g_font ? g_font->get_cache(FONT_SIZE)->ascent - g_font->get_cache(FONT_SIZE)->descent : 16;
|
||||
int y = TOOLBAR_H + 8 + fh + 8;
|
||||
int y = partition_map_y();
|
||||
|
||||
// Partition map bar click
|
||||
int map_x = MAP_PAD;
|
||||
@@ -163,12 +144,9 @@ static bool handle_content_click(int mx, int my) {
|
||||
return true;
|
||||
}
|
||||
|
||||
y += MAP_H + 8 + HEADER_H;
|
||||
|
||||
// Partition list click
|
||||
int list_bottom = g_win_h - STATUS_H;
|
||||
if (my >= y && my < list_bottom) {
|
||||
int row = (my - y + dt.scroll_y) / ITEM_H;
|
||||
if (my >= partition_list_y() && my < g_win_h - STATUS_H) {
|
||||
int row = (my - partition_list_y() + dt.scroll_y) / ITEM_H;
|
||||
int part_indices[MAX_PARTS];
|
||||
int nparts = get_disk_parts(part_indices, MAX_PARTS);
|
||||
if (row >= 0 && row < nparts)
|
||||
@@ -189,16 +167,10 @@ static bool handle_newpart_dialog_click(int mx, int my, bool clicked) {
|
||||
auto& dlg = g_state.np_dlg;
|
||||
if (!dlg.open) return false;
|
||||
|
||||
int dw = NP_DLG_W, dh = NP_DLG_H;
|
||||
|
||||
int btn_w = 90, btn_h = 30;
|
||||
int btn_y = dh - btn_h - 16;
|
||||
int gap = 16;
|
||||
int total_w = btn_w * 2 + gap;
|
||||
int bx = (dw - total_w) / 2;
|
||||
|
||||
dlg.hover_confirm = (mx >= bx && mx < bx + btn_w && my >= btn_y && my < btn_y + btn_h);
|
||||
dlg.hover_cancel = (mx >= bx + btn_w + gap && mx < bx + btn_w * 2 + gap && my >= btn_y && my < btn_y + btn_h);
|
||||
Rect confirm = dialog_primary_button_rect(NP_DLG_W, NP_DLG_H);
|
||||
Rect cancel = dialog_secondary_button_rect(NP_DLG_W, NP_DLG_H);
|
||||
dlg.hover_confirm = confirm.contains(mx, my);
|
||||
dlg.hover_cancel = cancel.contains(mx, my);
|
||||
|
||||
if (!clicked) return true;
|
||||
|
||||
@@ -223,27 +195,17 @@ static bool handle_format_dialog_click(int mx, int my, bool clicked) {
|
||||
auto& dlg = g_state.fmt_dlg;
|
||||
if (!dlg.open) return false;
|
||||
|
||||
int dw = FMT_DLG_W, dh = FMT_DLG_H;
|
||||
int fh = g_font ? g_font->get_cache(FONT_SIZE)->ascent - g_font->get_cache(FONT_SIZE)->descent : 16;
|
||||
|
||||
// Button hit testing
|
||||
int btn_w = 90, btn_h = 30;
|
||||
int btn_y = dh - btn_h - 16;
|
||||
int gap = 16;
|
||||
int total_w = btn_w * 2 + gap;
|
||||
int bx = (dw - total_w) / 2;
|
||||
|
||||
dlg.hover_format = (mx >= bx && mx < bx + btn_w && my >= btn_y && my < btn_y + btn_h);
|
||||
dlg.hover_cancel = (mx >= bx + btn_w + gap && mx < bx + btn_w * 2 + gap && my >= btn_y && my < btn_y + btn_h);
|
||||
Rect format_btn = dialog_primary_button_rect(FMT_DLG_W, FMT_DLG_H);
|
||||
Rect cancel_btn = dialog_secondary_button_rect(FMT_DLG_W, FMT_DLG_H);
|
||||
dlg.hover_format = format_btn.contains(mx, my);
|
||||
dlg.hover_cancel = cancel_btn.contains(mx, my);
|
||||
|
||||
if (!clicked) return true;
|
||||
|
||||
// FS type selector
|
||||
int sel_y = 12 + fh * 2 + 18;
|
||||
int opt_y = sel_y + fh + 8;
|
||||
for (int i = 0; i < NUM_FS_TYPES; i++) {
|
||||
int iy = opt_y + i * 32;
|
||||
if (mx >= 24 && mx < dw - 24 && my >= iy && my < iy + 28) {
|
||||
if (format_option_rect(FMT_DLG_W, i).contains(mx, my)) {
|
||||
dlg.selected_fs = i;
|
||||
return true;
|
||||
}
|
||||
@@ -262,6 +224,74 @@ static bool handle_format_dialog_click(int mx, int my, bool clicked) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int hovered_disk_button(int mx, int my) {
|
||||
for (int i = 0; i < g_state.disk_count; i++) {
|
||||
if (toolbar_disk_button_rect(i).contains(mx, my))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int hovered_partition_row(int mx, int my) {
|
||||
if (g_state.disk_count == 0 || g_state.selected_disk < 0) return -1;
|
||||
if (my < partition_list_y() || my >= g_win_h - STATUS_H) return -1;
|
||||
|
||||
int part_indices[MAX_PARTS];
|
||||
int nparts = get_disk_parts(part_indices, MAX_PARTS);
|
||||
int row = (my - partition_list_y() + g_state.scroll_y) / ITEM_H;
|
||||
if (row < 0 || row >= nparts) return -1;
|
||||
return row;
|
||||
}
|
||||
|
||||
static int max_scroll_y() {
|
||||
int part_indices[MAX_PARTS];
|
||||
int nparts = get_disk_parts(part_indices, MAX_PARTS);
|
||||
int visible_h = g_win_h - STATUS_H - partition_list_y();
|
||||
int total_h = nparts * ITEM_H;
|
||||
if (total_h <= visible_h) return 0;
|
||||
return total_h - visible_h;
|
||||
}
|
||||
|
||||
static void clamp_scroll() {
|
||||
g_state.scroll_y = gui_clamp(g_state.scroll_y, 0, max_scroll_y());
|
||||
}
|
||||
|
||||
static bool handle_mouse(const Montauk::WinEvent& ev) {
|
||||
int prev_x = g_state.mouse_x;
|
||||
int prev_y = g_state.mouse_y;
|
||||
int prev_disk_hover = hovered_disk_button(prev_x, prev_y);
|
||||
int prev_part_hover = hovered_partition_row(prev_x, prev_y);
|
||||
bool prev_refresh_hover = toolbar_refresh_button_rect().contains(prev_x, prev_y);
|
||||
bool prev_mount_hover = toolbar_mount_button_rect().contains(prev_x, prev_y);
|
||||
bool prev_format_hover = toolbar_format_button_rect().contains(prev_x, prev_y);
|
||||
bool prev_newpart_hover = toolbar_newpart_button_rect().contains(prev_x, prev_y);
|
||||
|
||||
g_state.mouse_x = ev.mouse.x;
|
||||
g_state.mouse_y = ev.mouse.y;
|
||||
|
||||
bool redraw = false;
|
||||
redraw |= (prev_disk_hover != hovered_disk_button(g_state.mouse_x, g_state.mouse_y));
|
||||
redraw |= (prev_part_hover != hovered_partition_row(g_state.mouse_x, g_state.mouse_y));
|
||||
redraw |= (prev_refresh_hover != toolbar_refresh_button_rect().contains(g_state.mouse_x, g_state.mouse_y));
|
||||
redraw |= (prev_mount_hover != toolbar_mount_button_rect().contains(g_state.mouse_x, g_state.mouse_y));
|
||||
redraw |= (prev_format_hover != toolbar_format_button_rect().contains(g_state.mouse_x, g_state.mouse_y));
|
||||
redraw |= (prev_newpart_hover != toolbar_newpart_button_rect().contains(g_state.mouse_x, g_state.mouse_y));
|
||||
|
||||
if (ev.mouse.scroll != 0) {
|
||||
g_state.scroll_y -= ev.mouse.scroll * 20;
|
||||
clamp_scroll();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool clicked = (ev.mouse.buttons & 1) && !(ev.mouse.prev_buttons & 1);
|
||||
if (clicked) {
|
||||
if (handle_toolbar_click(ev.mouse.x, ev.mouse.y) || handle_content_click(ev.mouse.x, ev.mouse.y))
|
||||
return true;
|
||||
}
|
||||
|
||||
return redraw;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Key handling
|
||||
// ============================================================================
|
||||
@@ -329,16 +359,11 @@ extern "C" void _start() {
|
||||
montauk::memset(&g_state, 0, sizeof(g_state));
|
||||
g_state.selected_disk = 0;
|
||||
g_state.selected_part = -1;
|
||||
g_state.mouse_x = -1;
|
||||
g_state.mouse_y = -1;
|
||||
|
||||
// Load font
|
||||
{
|
||||
TrueTypeFont* f = (TrueTypeFont*)montauk::malloc(sizeof(TrueTypeFont));
|
||||
if (f) {
|
||||
montauk::memset(f, 0, sizeof(TrueTypeFont));
|
||||
if (!f->init("0:/fonts/Roboto-Medium.ttf")) { montauk::mfree(f); f = nullptr; }
|
||||
}
|
||||
g_font = f;
|
||||
}
|
||||
if (!fonts::init())
|
||||
montauk::exit(1);
|
||||
|
||||
disktool_refresh();
|
||||
|
||||
@@ -418,6 +443,7 @@ extern "C" void _start() {
|
||||
g_win_w = win.width;
|
||||
g_win_h = win.height;
|
||||
pixels = win.pixels;
|
||||
clamp_scroll();
|
||||
redraw_main = true;
|
||||
}
|
||||
|
||||
@@ -430,21 +456,7 @@ extern "C" void _start() {
|
||||
|
||||
// Mouse
|
||||
if (ev.type == 1) {
|
||||
int mx = ev.mouse.x;
|
||||
int my = ev.mouse.y;
|
||||
bool clicked = (ev.mouse.buttons & 1) && !(ev.mouse.prev_buttons & 1);
|
||||
|
||||
// Scroll
|
||||
if (ev.mouse.scroll != 0) {
|
||||
g_state.scroll_y -= ev.mouse.scroll * 20;
|
||||
if (g_state.scroll_y < 0) g_state.scroll_y = 0;
|
||||
redraw_main = true;
|
||||
}
|
||||
|
||||
if (clicked) {
|
||||
if (handle_toolbar_click(mx, my) || handle_content_click(mx, my))
|
||||
redraw_main = true;
|
||||
}
|
||||
redraw_main |= handle_mouse(ev);
|
||||
}
|
||||
|
||||
if (redraw_main) { render(pixels); win.present(); }
|
||||
|
||||
Reference in New Issue
Block a user