feat: make Files app list view columns draggable horizontally

This commit is contained in:
daniel committed 2026-10-26 16:17:06 +01:00
1 parent 559c3e2875
commit be84506fdf
7 files changed
+181 -40

No files matched your search

+1 -1
View File
@@ -12,4 +12,4 @@
#pragma once #pragma once
#define MONTAUK_BUILD_NUMBER 107 #define MONTAUK_BUILD_NUMBER 109
+5
View File
@@ -43,6 +43,11 @@ static void open_filemanager_internal(DesktopState* ds, const char* initial_path
prefs_load(ds); prefs_load(ds);
fm->show_hidden = prefs_show_hidden(); fm->show_hidden = prefs_show_hidden();
fm->sidebar_width = prefs_sidebar_width(); fm->sidebar_width = prefs_sidebar_width();
fm->col_resizing = -1;
for (int col = 0; col < FM_COL_COUNT; col++) {
int w = prefs_column_width(col);
fm->list_col_w[col] = w > 0 ? w : FM_COL_DEFAULT_W[col];
}
fm->scrollbar.init(0, 0, FM_SCROLLBAR_W, 100); fm->scrollbar.init(0, 0, FM_SCROLLBAR_W, 100);
+55 -4
View File
@@ -55,6 +55,53 @@ static bool filemanager_click_entry(FileManagerState* fm, int idx) {
return false; return false;
} }
// List view column divider under (x, y) in the header row, -1 if none.
static int filemanager_column_divider_at(FileManagerState* fm, const FileManagerLayout& l,
int x, int y) {
if (fm->grid_view || y < l.body_y || y >= l.list_y) return -1;
FileManagerListColumns cols = filemanager_list_columns(fm, l.view_x, l.view_w);
for (int col = 0; col < FM_COL_COUNT; col++) {
int cx = cols.x(col);
if (cx >= 0 && x >= cx - 4 - FM_COL_GRIP && x <= cx - 4 + FM_COL_GRIP) return col;
}
return -1;
}
// Dragging a column divider in the list view header. The divider is the
// column's left edge: the column grows leftwards and Name gives up the room.
// Returns true if the event was consumed; sets *grip over a divider.
static bool filemanager_column_resize_mouse(FileManagerState* fm, const FileManagerLayout& l,
int x, int y, MouseEvent& ev, bool* grip) {
if (fm->col_resizing >= 0) {
int col = fm->col_resizing;
if (ev.left_held()) {
int w = fm->col_drag_right - (x - fm->col_drag_dx);
fm->list_col_w[col] = gui_clamp(w, FM_COL_MIN_W, fm->col_drag_max);
} else {
fm->col_resizing = -1;
prefs_set_column_widths(fm->desktop, fm->list_col_w);
}
return true;
}
int col = filemanager_column_divider_at(fm, l, x, y);
if (col < 0) return false;
*grip = true;
if (!ev.left_pressed()) return false;
FileManagerListColumns cols = filemanager_list_columns(fm, l.view_x, l.view_w);
int divider = cols.x(col) - 4;
fm->col_resizing = col;
fm->col_drag_dx = x - divider;
fm->col_drag_right = divider + cols.w[col];
// Name may shrink to its minimum, never further: past that a column
// would be dropped mid-drag.
int slack = cols.name_right + 8 - (l.view_x + FM_LIST_MIN_NAME_W);
fm->col_drag_max = gui_max(gui_min(cols.w[col] + slack, FM_COL_MAX_W), cols.w[col]);
if (fm->pathbar_editing) filemanager_cancel_pathbar(fm);
return true;
}
void filemanager_on_mouse(Window* win, MouseEvent& ev) { void filemanager_on_mouse(Window* win, MouseEvent& ev) {
FileManagerState* fm = (FileManagerState*)win->app_data; FileManagerState* fm = (FileManagerState*)win->app_data;
if (!fm) return; if (!fm) return;
@@ -203,10 +250,14 @@ void filemanager_on_mouse(Window* win, MouseEvent& ev) {
FileManagerLayout l = filemanager_layout(fm, fm->grid_view, cw); FileManagerLayout l = filemanager_layout(fm, fm->grid_view, cw);
// ---- Sidebar edge: drag to resize ---- // ---- Sidebar edge and list column dividers: drag to resize ----
if (!fm->marquee_active && fm->press_idx < 0 && !fm->scrollbar.dragging && if (!fm->marquee_active && fm->press_idx < 0 && !fm->scrollbar.dragging) {
filemanager_sidebar_resize_mouse(win, fm, l, local_x, local_y, ev)) bool grip = false;
if (filemanager_sidebar_resize_mouse(win, fm, l, local_x, local_y, ev, &grip) ||
filemanager_column_resize_mouse(fm, l, local_x, local_y, ev, &grip))
return; return;
filemanager_set_cursor(win, fm, grip ? CURSOR_RESIZE_H : CURSOR_ARROW);
}
// ---- Cancel rename on click outside rename area ---- // ---- Cancel rename on click outside rename area ----
if (fm->rename_active && ev.left_pressed()) { if (fm->rename_active && ev.left_pressed()) {
@@ -277,7 +328,7 @@ void filemanager_on_mouse(Window* win, MouseEvent& ev) {
// Column header click (list view): sort by that column, again = reverse. // Column header click (list view): sort by that column, again = reverse.
if (!fm->grid_view && local_y >= l.body_y && local_y < l.list_y && if (!fm->grid_view && local_y >= l.body_y && local_y < l.list_y &&
local_x >= l.view_x && filemanager_is_listing(fm)) { local_x >= l.view_x && filemanager_is_listing(fm)) {
FileManagerListColumns cols = filemanager_list_columns(l.view_x, l.view_w); FileManagerListColumns cols = filemanager_list_columns(fm, l.view_x, l.view_w);
if (cols.type_x >= 0 && local_x >= cols.type_x) if (cols.type_x >= 0 && local_x >= cols.type_x)
filemanager_set_sort(fm, FM_SORT_TYPE); filemanager_set_sort(fm, FM_SORT_TYPE);
else if (cols.size_x >= 0 && local_x >= cols.size_x) else if (cols.size_x >= 0 && local_x >= cols.size_x)
+51 -16
View File
@@ -205,6 +205,14 @@ struct FileManagerState {
int sidebar_width; // wanted width (prefs); the layout clamps it to the window int sidebar_width; // wanted width (prefs); the layout clamps it to the window
bool sidebar_resizing; // dragging the sidebar's right edge bool sidebar_resizing; // dragging the sidebar's right edge
int sidebar_drag_dx; // pointer offset from the edge when the drag began int sidebar_drag_dx; // pointer offset from the edge when the drag began
// List view column widths (FileManagerListColumn order; prefs) and the
// divider being dragged, -1 = none. A drag keeps the column's right edge
// fixed, so the name column absorbs the change.
int list_col_w[3];
int col_resizing;
int col_drag_dx; // pointer offset from the divider when the drag began
int col_drag_right; // the column's right edge during the drag
int col_drag_max; // widest it may get without dropping a column
int cursor_style; // CursorStyle last sent to the Window Server int cursor_style; // CursorStyle last sent to the Window Server
// Undo / redo of the last file operations (undo.cpp). // Undo / redo of the last file operations (undo.cpp).
@@ -284,34 +292,56 @@ inline FileManagerLayout filemanager_layout(const FileManagerState* fm, bool gri
return l; return l;
} }
// List view columns right of Name, in screen order. Name takes the rest.
enum FileManagerListColumn : int {
FM_COL_MODIFIED = 0,
FM_COL_SIZE,
FM_COL_TYPE,
FM_COL_COUNT,
};
inline constexpr int FM_COL_DEFAULT_W[FM_COL_COUNT] = {132, 76, 96};
inline constexpr int FM_COL_MIN_W = 48;
inline constexpr int FM_COL_MAX_W = 400;
inline constexpr int FM_LIST_MIN_NAME_W = 160;
inline constexpr int FM_COL_GRIP = 3; // drag zone either side of a divider
// List view column layout. Columns are dropped right to left as the window // List view column layout. Columns are dropped right to left as the window
// narrows (Modified first, then Type, then Size) so the name keeps room. // narrows (Modified first, then Type, then Size) so the name keeps room.
// A column's text starts at its x; its divider line sits at x - 4.
struct FileManagerListColumns { struct FileManagerListColumns {
int name_x; int name_x;
int name_right; // right edge available to the name text int name_right; // right edge available to the name text
int modified_x; // -1 = hidden int modified_x; // -1 = hidden
int size_x; // -1 = hidden int size_x; // -1 = hidden
int type_x; // -1 = hidden int type_x; // -1 = hidden
int w[FM_COL_COUNT];
int x(int col) const {
return col == FM_COL_MODIFIED ? modified_x : col == FM_COL_SIZE ? size_x : type_x;
}
}; };
// Columns of a list view occupying [x0, x0 + view_w). // Columns of a list view occupying [x0, x0 + view_w).
inline FileManagerListColumns filemanager_list_columns(int x0, int view_w) { inline FileManagerListColumns filemanager_list_columns(const FileManagerState* fm,
static constexpr int MIN_NAME_W = 160; int x0, int view_w) {
static constexpr int TYPE_W = 96; FileManagerListColumns cols = {x0 + 8, 0, -1, -1, -1, {}};
static constexpr int SIZE_W = 76; for (int i = 0; i < FM_COL_COUNT; i++) cols.w[i] = fm->list_col_w[i];
static constexpr int MODIFIED_W = 132; const int* w = cols.w;
FileManagerListColumns cols = {x0 + 8, 0, -1, -1, -1}; int min_right = x0 + FM_LIST_MIN_NAME_W;
int min_right = x0 + MIN_NAME_W;
int right = x0 + view_w; int right = x0 + view_w;
if (right - SIZE_W >= min_right) { right -= SIZE_W; cols.size_x = right; } if (right - w[FM_COL_SIZE] >= min_right) { right -= w[FM_COL_SIZE]; cols.size_x = right; }
if (right - TYPE_W >= min_right) { if (right - w[FM_COL_TYPE] >= min_right) {
// Type sits right of Size; shift Size left to make room. // Type sits right of Size; shift Size left to make room.
cols.type_x = x0 + view_w - TYPE_W; cols.type_x = x0 + view_w - w[FM_COL_TYPE];
if (cols.size_x >= 0) cols.size_x -= TYPE_W; if (cols.size_x >= 0) cols.size_x -= w[FM_COL_TYPE];
right -= TYPE_W; right -= w[FM_COL_TYPE];
}
if (right - w[FM_COL_MODIFIED] >= min_right) {
right -= w[FM_COL_MODIFIED];
cols.modified_x = right;
} }
if (right - MODIFIED_W >= min_right) { right -= MODIFIED_W; cols.modified_x = right; }
cols.name_right = right - 8; cols.name_right = right - 8;
return cols; return cols;
} }
@@ -547,6 +577,8 @@ bool prefs_show_hidden();
void prefs_set_show_hidden(DesktopState* ds, bool show); void prefs_set_show_hidden(DesktopState* ds, bool show);
int prefs_sidebar_width(); // 0 = default int prefs_sidebar_width(); // 0 = default
void prefs_set_sidebar_width(DesktopState* ds, int width); void prefs_set_sidebar_width(DesktopState* ds, int width);
int prefs_column_width(int col); // FileManagerListColumn, 0 = default
void prefs_set_column_widths(DesktopState* ds, const int* widths);
int prefs_bookmark_count(); int prefs_bookmark_count();
const char* prefs_bookmark(int i); const char* prefs_bookmark(int i);
bool prefs_has_bookmark(const char* path); bool prefs_has_bookmark(const char* path);
@@ -564,9 +596,12 @@ void filemanager_sidebar_draw(Canvas& c, FileManagerState* fm, const FileManager
bool filemanager_sidebar_mouse(FileManagerState* fm, const FileManagerLayout& l, bool filemanager_sidebar_mouse(FileManagerState* fm, const FileManagerLayout& l,
int x, int y, MouseEvent& ev, int ch); int x, int y, MouseEvent& ev, int ch);
// Dragging the sidebar's right edge to resize it. Returns true if the event // Dragging the sidebar's right edge to resize it. Returns true if the event
// was consumed (a drag is in progress or just began). // was consumed (a drag is in progress or just began); sets *grip when the
bool filemanager_sidebar_resize_mouse(Window* win, FileManagerState* fm, // pointer is over the edge.
const FileManagerLayout& l, int x, int y, MouseEvent& ev); bool filemanager_sidebar_resize_mouse(Window* win, FileManagerState* fm, const FileManagerLayout& l,
int x, int y, MouseEvent& ev, bool* grip);
// The Window Server cursor for this window (CursorStyle), sent on change only.
void filemanager_set_cursor(Window* win, FileManagerState* fm, int style);
int filemanager_sidebar_item_at(FileManagerState* fm, const FileManagerLayout& l, int x, int y); int filemanager_sidebar_item_at(FileManagerState* fm, const FileManagerLayout& l, int x, int y);
void filemanager_sidebar_open(FileManagerState* fm, int idx); void filemanager_sidebar_open(FileManagerState* fm, int idx);
// Folder a sidebar row stands for, for drops ("" for Computer/headers). // Folder a sidebar row stands for, for drops ("" for Computer/headers).
+30
View File
@@ -13,6 +13,8 @@ namespace filemanager {
// Layout of files.toml: // Layout of files.toml:
// [view] // [view]
// show_hidden = false // show_hidden = false
// [list]
// modified_width = 132 (also size_width, type_width; absent = default)
// [sidebar] // [sidebar]
// width = 160 // width = 160
// bookmarks = ["0:/users/me/Projects", ...] // bookmarks = ["0:/users/me/Projects", ...]
@@ -24,6 +26,10 @@ namespace filemanager {
static constexpr const char* PREFS_NAME = "files"; static constexpr const char* PREFS_NAME = "files";
static constexpr int MAX_BOOKMARKS = 32; static constexpr int MAX_BOOKMARKS = 32;
static constexpr int MAX_FOLDER_VIEWS = 128; static constexpr int MAX_FOLDER_VIEWS = 128;
// Keys of the list view column widths, FileManagerListColumn order.
static constexpr const char* COLUMN_WIDTH_KEYS[FM_COL_COUNT] = {
"list.modified_width", "list.size_width", "list.type_width",
};
struct FolderView { struct FolderView {
char path[256]; char path[256];
@@ -35,6 +41,7 @@ struct FolderView {
struct Prefs { struct Prefs {
bool show_hidden; bool show_hidden;
int sidebar_width; // 0 = default int sidebar_width; // 0 = default
int column_widths[FM_COL_COUNT]; // 0 = default
char bookmarks[MAX_BOOKMARKS][256]; char bookmarks[MAX_BOOKMARKS][256];
int bookmark_count; int bookmark_count;
FolderView views[MAX_FOLDER_VIEWS]; FolderView views[MAX_FOLDER_VIEWS];
@@ -99,6 +106,10 @@ static void read_from_disk(DesktopState* ds) {
g_prefs.show_hidden = doc.get_bool("view.show_hidden", false); g_prefs.show_hidden = doc.get_bool("view.show_hidden", false);
int64_t width = doc.get_int("sidebar.width", 0); int64_t width = doc.get_int("sidebar.width", 0);
g_prefs.sidebar_width = width > 0 && width <= FM_SIDEBAR_MAX_W ? (int)width : 0; g_prefs.sidebar_width = width > 0 && width <= FM_SIDEBAR_MAX_W ? (int)width : 0;
for (int col = 0; col < FM_COL_COUNT; col++) {
int64_t cw = doc.get_int(COLUMN_WIDTH_KEYS[col], 0);
g_prefs.column_widths[col] = cw >= FM_COL_MIN_W && cw <= FM_COL_MAX_W ? (int)cw : 0;
}
if (auto* arr = doc.get_array("sidebar.bookmarks")) { if (auto* arr = doc.get_array("sidebar.bookmarks")) {
for (int i = 0; i < arr->array.count && g_prefs.bookmark_count < MAX_BOOKMARKS; i++) { for (int i = 0; i < arr->array.count && g_prefs.bookmark_count < MAX_BOOKMARKS; i++) {
@@ -133,6 +144,10 @@ static void write_to_disk(DesktopState* ds) {
montauk::config::set_bool(&doc, "view.show_hidden", g_prefs.show_hidden); montauk::config::set_bool(&doc, "view.show_hidden", g_prefs.show_hidden);
if (g_prefs.sidebar_width > 0) if (g_prefs.sidebar_width > 0)
montauk::config::set_int(&doc, "sidebar.width", g_prefs.sidebar_width); montauk::config::set_int(&doc, "sidebar.width", g_prefs.sidebar_width);
for (int col = 0; col < FM_COL_COUNT; col++) {
if (g_prefs.column_widths[col] > 0)
montauk::config::set_int(&doc, COLUMN_WIDTH_KEYS[col], g_prefs.column_widths[col]);
}
auto* bookmarks = string_array("sidebar.bookmarks"); auto* bookmarks = string_array("sidebar.bookmarks");
for (int i = 0; i < g_prefs.bookmark_count; i++) push_string(bookmarks, g_prefs.bookmarks[i]); for (int i = 0; i < g_prefs.bookmark_count; i++) push_string(bookmarks, g_prefs.bookmarks[i]);
@@ -177,6 +192,21 @@ void prefs_set_sidebar_width(DesktopState* ds, int width) {
write_to_disk(ds); write_to_disk(ds);
} }
int prefs_column_width(int col) {
return col >= 0 && col < FM_COL_COUNT ? g_prefs.column_widths[col] : 0;
}
void prefs_set_column_widths(DesktopState* ds, const int* widths) {
read_from_disk(ds);
bool changed = false;
for (int col = 0; col < FM_COL_COUNT; col++) {
int w = widths[col] == FM_COL_DEFAULT_W[col] ? 0 : widths[col];
if (g_prefs.column_widths[col] != w) changed = true;
g_prefs.column_widths[col] = w;
}
if (changed) write_to_disk(ds);
}
int prefs_bookmark_count() { int prefs_bookmark_count() {
return g_prefs.bookmark_count; return g_prefs.bookmark_count;
} }
+35 -15
View File
@@ -135,13 +135,16 @@ static void draw_marquee(Canvas& c, FileManagerState* fm, int list_y) {
} }
} }
// Column title, plus a small arrow when it is the active sort column. // Column title, plus a small arrow when it is the active sort column and
static void draw_column_header(Canvas& c, int x, int header_y, const char* label, // there is room for it. max_w is the width the title may take.
static void draw_column_header(Canvas& c, int x, int header_y, const char* label, int max_w,
bool active, bool desc, Color color) { bool active, bool desc, Color color) {
c.text(x, header_y + 2, label, active ? colors::TEXT_COLOR : color); char fit[32];
if (!active) return; fit_label_with_ellipsis(fit, sizeof(fit), label, max_w);
c.text(x, header_y + 2, fit, active ? colors::TEXT_COLOR : color);
int ax = x + text_width(fit) + 6;
if (!active || ax + 7 > x + max_w) return;
int ax = x + text_width(label) + 6;
int ay = header_y + FM_HEADER_H / 2 - 2; int ay = header_y + FM_HEADER_H / 2 - 2;
for (int r = 0; r < 4; r++) { for (int r = 0; r < 4; r++) {
// Ascending points up, descending points down. // Ascending points up, descending points down.
@@ -337,7 +340,7 @@ bool filemanager_rename_box(FileManagerState* fm, const FileManagerLayout& l, in
r = {x, cell_y + FM_GRID_PAD + FM_GRID_ICON, w, fh + 6}; r = {x, cell_y + FM_GRID_PAD + FM_GRID_ICON, w, fh + 6};
} else { } else {
// Over the name column; text lines up with the names (view_x + 30). // Over the name column; text lines up with the names (view_x + 30).
FileManagerListColumns cols = filemanager_list_columns(l.view_x, l.view_w); FileManagerListColumns cols = filemanager_list_columns(fm, l.view_x, l.view_w);
int iy = l.list_y + i * FM_ITEM_H - fm->scrollbar.scroll_offset; int iy = l.list_y + i * FM_ITEM_H - fm->scrollbar.scroll_offset;
int x = l.view_x + 30 - fm->rename.pad; int x = l.view_x + 30 - fm->rename.pad;
r = {x, iy + 2, gui_max(cols.name_right - x, 60), FM_ITEM_H - 4}; r = {x, iy + 2, gui_max(cols.name_right - x, 60), FM_ITEM_H - 4};
@@ -480,31 +483,42 @@ void filemanager_on_draw(Window* win, Framebuffer& fb) {
int header_y = l.body_y; int header_y = l.body_y;
c.fill_rect(l.view_x, header_y, c.w - l.view_x, FM_HEADER_H, Color::from_rgb(0xF8, 0xF8, 0xF8)); c.fill_rect(l.view_x, header_y, c.w - l.view_x, FM_HEADER_H, Color::from_rgb(0xF8, 0xF8, 0xF8));
FileManagerListColumns cols = filemanager_list_columns(l.view_x, l.view_w); FileManagerListColumns cols = filemanager_list_columns(fm, l.view_x, l.view_w);
// Text room of each column: up to the next divider, less a gap.
// Type runs to the view's right edge.
int col_text_w[FM_COL_COUNT];
for (int col = 0; col < FM_COL_COUNT; col++) col_text_w[col] = cols.w[col] - 8;
col_text_w[FM_COL_TYPE] = l.view_x + l.view_w - cols.type_x - 4;
// Sorting only applies to real directories; Computer and the virtual // Sorting only applies to real directories; Computer and the virtual
// views keep their curated order and show no sort arrow. // views keep their curated order and show no sort arrow.
bool sortable = !filemanager_is_computer_view(fm) && !filemanager_is_virtual_view(fm); bool sortable = !filemanager_is_computer_view(fm) && !filemanager_is_virtual_view(fm);
draw_column_header(c, cols.name_x, header_y, "Name", draw_column_header(c, cols.name_x, header_y, "Name", cols.name_right - cols.name_x,
sortable && fm->sort_key == FM_SORT_NAME, fm->sort_desc, dim); sortable && fm->sort_key == FM_SORT_NAME, fm->sort_desc, dim);
if (cols.modified_x >= 0) if (cols.modified_x >= 0)
draw_column_header(c, cols.modified_x, header_y, "Modified", draw_column_header(c, cols.modified_x, header_y, "Modified", col_text_w[FM_COL_MODIFIED],
sortable && fm->sort_key == FM_SORT_MODIFIED, fm->sort_desc, dim); sortable && fm->sort_key == FM_SORT_MODIFIED, fm->sort_desc, dim);
if (cols.size_x >= 0) if (cols.size_x >= 0)
draw_column_header(c, cols.size_x, header_y, "Size", draw_column_header(c, cols.size_x, header_y, "Size", col_text_w[FM_COL_SIZE],
sortable && fm->sort_key == FM_SORT_SIZE, fm->sort_desc, dim); sortable && fm->sort_key == FM_SORT_SIZE, fm->sort_desc, dim);
if (cols.type_x >= 0) if (cols.type_x >= 0)
draw_column_header(c, cols.type_x, header_y, "Type", draw_column_header(c, cols.type_x, header_y, "Type", col_text_w[FM_COL_TYPE],
sortable && fm->sort_key == FM_SORT_TYPE, fm->sort_desc, dim); sortable && fm->sort_key == FM_SORT_TYPE, fm->sort_desc, dim);
// Header separator // Header separator
c.hline(l.view_x, header_y + FM_HEADER_H - 1, c.w - l.view_x, colors::BORDER); c.hline(l.view_x, header_y + FM_HEADER_H - 1, c.w - l.view_x, colors::BORDER);
// Column separator lines // Column separator lines: the one after Name runs down the list,
// the rest mark the draggable dividers in the header.
int first_col_x = cols.modified_x >= 0 ? cols.modified_x int first_col_x = cols.modified_x >= 0 ? cols.modified_x
: cols.size_x >= 0 ? cols.size_x : cols.type_x; : cols.size_x >= 0 ? cols.size_x : cols.type_x;
if (first_col_x >= 0) if (first_col_x >= 0)
c.vline(first_col_x - 4, header_y, c.h - header_y, colors::BORDER); c.vline(first_col_x - 4, header_y, c.h - header_y, colors::BORDER);
for (int col = 0; col < FM_COL_COUNT; col++) {
int cx = cols.x(col);
if (cx >= 0 && cx != first_col_x)
c.vline(cx - 4, header_y, FM_HEADER_H, colors::BORDER);
}
int tz = montauk::gettz(); int tz = montauk::gettz();
// ---- File entries ---- // ---- File entries ----
@@ -605,14 +619,20 @@ void filemanager_on_draw(Window* win, Framebuffer& fb) {
if (cols.modified_x >= 0 && row_text_visible && fm->entry_mtimes[i] > 0) { if (cols.modified_x >= 0 && row_text_visible && fm->entry_mtimes[i] > 0) {
char date_str[24]; char date_str[24];
format_datetime(date_str, sizeof(date_str), fm->entry_mtimes[i], tz); format_datetime(date_str, sizeof(date_str), fm->entry_mtimes[i], tz);
c.text(cols.modified_x, ty, date_str, dim); char date_fit[24];
fit_label_with_ellipsis(date_fit, sizeof(date_fit), date_str,
col_text_w[FM_COL_MODIFIED]);
c.text(cols.modified_x, ty, date_fit, dim);
} }
// Size // Size
if (cols.size_x >= 0 && !fm->is_dir[i] && row_text_visible) { if (cols.size_x >= 0 && !fm->is_dir[i] && row_text_visible) {
char size_str[16]; char size_str[16];
format_size(size_str, fm->entry_sizes[i]); format_size(size_str, fm->entry_sizes[i]);
c.text(cols.size_x, ty, size_str, dim); char size_fit[16];
fit_label_with_ellipsis(size_fit, sizeof(size_fit), size_str,
col_text_w[FM_COL_SIZE]);
c.text(cols.size_x, ty, size_fit, dim);
} }
// Type // Type
@@ -621,7 +641,7 @@ void filemanager_on_draw(Window* win, Framebuffer& fb) {
filemanager_type_label(fm, i, type_str, sizeof(type_str)); filemanager_type_label(fm, i, type_str, sizeof(type_str));
char type_fit[24]; char type_fit[24];
fit_label_with_ellipsis(type_fit, sizeof(type_fit), type_str, fit_label_with_ellipsis(type_fit, sizeof(type_fit), type_str,
l.view_x + l.view_w - cols.type_x - 4); col_text_w[FM_COL_TYPE]);
c.text(cols.type_x, ty, type_fit, dim); c.text(cols.type_x, ty, type_fit, dim);
} }
} }
+4 -4
View File
@@ -226,14 +226,14 @@ bool filemanager_sidebar_target_path(FileManagerState* fm, int idx, char* out, i
return true; return true;
} }
static void set_window_cursor(Window* win, FileManagerState* fm, int style) { void filemanager_set_cursor(Window* win, FileManagerState* fm, int style) {
if (fm->cursor_style == style) return; if (fm->cursor_style == style) return;
fm->cursor_style = style; fm->cursor_style = style;
montauk::win_setcursor(win->ext_win_id, style); montauk::win_setcursor(win->ext_win_id, style);
} }
bool filemanager_sidebar_resize_mouse(Window* win, FileManagerState* fm, bool filemanager_sidebar_resize_mouse(Window* win, FileManagerState* fm, const FileManagerLayout& l,
const FileManagerLayout& l, int x, int y, MouseEvent& ev) { int x, int y, MouseEvent& ev, bool* grip) {
if (fm->sidebar_resizing) { if (fm->sidebar_resizing) {
if (ev.left_held()) { if (ev.left_held()) {
fm->sidebar_width = filemanager_sidebar_width(x - fm->sidebar_drag_dx, fm->sidebar_width = filemanager_sidebar_width(x - fm->sidebar_drag_dx,
@@ -248,7 +248,7 @@ bool filemanager_sidebar_resize_mouse(Window* win, FileManagerState* fm,
// The grip straddles the border line at sidebar_w - 1. // The grip straddles the border line at sidebar_w - 1.
bool on_edge = l.sidebar_w > 0 && y >= l.body_y && bool on_edge = l.sidebar_w > 0 && y >= l.body_y &&
x >= l.sidebar_w - FM_SIDEBAR_GRIP && x < l.sidebar_w + FM_SIDEBAR_GRIP; x >= l.sidebar_w - FM_SIDEBAR_GRIP && x < l.sidebar_w + FM_SIDEBAR_GRIP;
set_window_cursor(win, fm, on_edge ? CURSOR_RESIZE_H : CURSOR_ARROW); if (on_edge) *grip = true;
if (!on_edge || !ev.left_pressed()) return false; if (!on_edge || !ev.left_pressed()) return false;
fm->sidebar_resizing = true; fm->sidebar_resizing = true;