Task Manager display fixed. ListView can now auto-size columns to fit content.
This commit is contained in:
parent
8550fbbbf2
commit
fa8ab9da27
9 changed files with 72 additions and 14 deletions
|
|
@ -254,7 +254,8 @@ static void buildTaskManager(void) {
|
||||||
WidgetT *root = wgtInitWindow(sAc, sTmWindow);
|
WidgetT *root = wgtInitWindow(sAc, sTmWindow);
|
||||||
|
|
||||||
// ListView with Name (descriptor), File (basename), Type, Status columns.
|
// ListView with Name (descriptor), File (basename), Type, Status columns.
|
||||||
ListViewColT tmCols[TM_COL_COUNT];
|
// Static: wgtListViewSetColumns stores a pointer, not a copy.
|
||||||
|
static ListViewColT tmCols[TM_COL_COUNT];
|
||||||
tmCols[0].title = "Name";
|
tmCols[0].title = "Name";
|
||||||
tmCols[0].width = wgtPercent(35);
|
tmCols[0].width = wgtPercent(35);
|
||||||
tmCols[0].align = ListViewAlignLeftE;
|
tmCols[0].align = ListViewAlignLeftE;
|
||||||
|
|
|
||||||
|
|
@ -2718,7 +2718,7 @@ static void pollAnsiTermWidgetsWalk(AppContextT *ctx, WidgetT *w, WindowT *win)
|
||||||
static void pollKeyboard(AppContextT *ctx) {
|
static void pollKeyboard(AppContextT *ctx) {
|
||||||
int32_t shiftFlags = platformKeyboardGetModifiers();
|
int32_t shiftFlags = platformKeyboardGetModifiers();
|
||||||
ctx->keyModifiers = shiftFlags;
|
ctx->keyModifiers = shiftFlags;
|
||||||
bool shiftHeld = (shiftFlags & 0x03) != 0; // left or right shift
|
bool shiftHeld = (shiftFlags & KEY_MOD_SHIFT) != 0;
|
||||||
|
|
||||||
PlatformKeyEventT evt;
|
PlatformKeyEventT evt;
|
||||||
|
|
||||||
|
|
@ -2937,7 +2937,7 @@ static void pollKeyboard(AppContextT *ctx) {
|
||||||
// Alt+Space — open/close system menu
|
// Alt+Space — open/close system menu
|
||||||
// Enhanced INT 16h: Alt+Space returns scancode 0x39, ascii 0x20
|
// Enhanced INT 16h: Alt+Space returns scancode 0x39, ascii 0x20
|
||||||
// Must check Alt modifier (bit 3) to distinguish from plain Space
|
// Must check Alt modifier (bit 3) to distinguish from plain Space
|
||||||
if (scancode == 0x39 && ascii == 0x20 && (shiftFlags & 0x08)) {
|
if (scancode == 0x39 && ascii == 0x20 && (shiftFlags & KEY_MOD_ALT)) {
|
||||||
if (ctx->sysMenu.active) {
|
if (ctx->sysMenu.active) {
|
||||||
closeSysMenu(ctx);
|
closeSysMenu(ctx);
|
||||||
} else if (ctx->stack.focusedIdx >= 0) {
|
} else if (ctx->stack.focusedIdx >= 0) {
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ WidgetT *sResizeListView = NULL; // ListView undergoing column resize
|
||||||
int32_t sResizeCol = -1; // which column is being resized
|
int32_t sResizeCol = -1; // which column is being resized
|
||||||
int32_t sResizeStartX = 0; // mouse X at resize start
|
int32_t sResizeStartX = 0; // mouse X at resize start
|
||||||
int32_t sResizeOrigW = 0; // column width at resize start
|
int32_t sResizeOrigW = 0; // column width at resize start
|
||||||
|
bool sResizeDragging = false; // true once mouse moves during column resize
|
||||||
WidgetT *sDragSplitter = NULL; // splitter being dragged
|
WidgetT *sDragSplitter = NULL; // splitter being dragged
|
||||||
int32_t sDragSplitStart = 0; // mouse offset from splitter edge at drag start
|
int32_t sDragSplitStart = 0; // mouse offset from splitter edge at drag start
|
||||||
WidgetT *sDragReorder = NULL; // list/tree widget in drag-reorder mode
|
WidgetT *sDragReorder = NULL; // list/tree widget in drag-reorder mode
|
||||||
|
|
@ -202,6 +203,7 @@ void widgetDestroyChildren(WidgetT *w) {
|
||||||
if (sResizeListView == child) {
|
if (sResizeListView == child) {
|
||||||
sResizeListView = NULL;
|
sResizeListView = NULL;
|
||||||
sResizeCol = -1;
|
sResizeCol = -1;
|
||||||
|
sResizeDragging = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sDragScrollbar == child) {
|
if (sDragScrollbar == child) {
|
||||||
|
|
|
||||||
|
|
@ -313,11 +313,25 @@ void widgetOnMouse(WindowT *win, int32_t x, int32_t y, int32_t buttons) {
|
||||||
if (sResizeListView && !(buttons & MOUSE_LEFT)) {
|
if (sResizeListView && !(buttons & MOUSE_LEFT)) {
|
||||||
sResizeListView = NULL;
|
sResizeListView = NULL;
|
||||||
sResizeCol = -1;
|
sResizeCol = -1;
|
||||||
|
sResizeDragging = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle ListView column resize drag
|
// Handle ListView column resize drag. The drag is deferred: on the
|
||||||
|
// initial click sResizeDragging is false and no resize happens until
|
||||||
|
// the mouse actually moves from the click point. This allows double-
|
||||||
|
// click auto-size to work (the first click sets sResizeListView but
|
||||||
|
// doesn't start dragging; the release clears it; the second click
|
||||||
|
// reaches widgetListViewOnMouse where multiClickDetect returns 2).
|
||||||
if (sResizeListView && (buttons & MOUSE_LEFT)) {
|
if (sResizeListView && (buttons & MOUSE_LEFT)) {
|
||||||
|
if (!sResizeDragging) {
|
||||||
|
if (x == sResizeStartX) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sResizeDragging = true;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t delta = x - sResizeStartX;
|
int32_t delta = x - sResizeStartX;
|
||||||
int32_t newW = sResizeOrigW + delta;
|
int32_t newW = sResizeOrigW + delta;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -188,6 +188,7 @@ extern WidgetT *sResizeListView; // listview whose column is being resized
|
||||||
extern int32_t sResizeCol; // which column is being resized
|
extern int32_t sResizeCol; // which column is being resized
|
||||||
extern int32_t sResizeStartX; // mouse X at start of column resize
|
extern int32_t sResizeStartX; // mouse X at start of column resize
|
||||||
extern int32_t sResizeOrigW; // original column width at start of resize
|
extern int32_t sResizeOrigW; // original column width at start of resize
|
||||||
|
extern bool sResizeDragging; // true once mouse has moved from click point
|
||||||
extern WidgetT *sDragSplitter; // splitter being dragged
|
extern WidgetT *sDragSplitter; // splitter being dragged
|
||||||
extern int32_t sDragSplitStart; // mouse position at start of splitter drag
|
extern int32_t sDragSplitStart; // mouse position at start of splitter drag
|
||||||
extern WidgetT *sDragReorder; // listbox/treeview item being drag-reordered
|
extern WidgetT *sDragReorder; // listbox/treeview item being drag-reordered
|
||||||
|
|
|
||||||
|
|
@ -893,11 +893,48 @@ void widgetListViewOnMouse(WidgetT *hit, WidgetT *root, int32_t vx, int32_t vy)
|
||||||
int32_t border = colX + cw;
|
int32_t border = colX + cw;
|
||||||
|
|
||||||
if (vx >= border - 3 && vx <= border + 3 && c < hit->as.listView->colCount) {
|
if (vx >= border - 3 && vx <= border + 3 && c < hit->as.listView->colCount) {
|
||||||
// Start column resize drag
|
if (multiClickDetect(vx, vy) >= 2) {
|
||||||
|
// Double-click on column border: auto-size to fit content
|
||||||
|
int32_t maxLen = (int32_t)strlen(hit->as.listView->cols[c].title);
|
||||||
|
|
||||||
|
for (int32_t r = 0; r < hit->as.listView->rowCount; r++) {
|
||||||
|
const char *cell = hit->as.listView->cellData[r * hit->as.listView->colCount + c];
|
||||||
|
|
||||||
|
if (cell) {
|
||||||
|
int32_t slen = (int32_t)strlen(cell);
|
||||||
|
|
||||||
|
if (slen > maxLen) {
|
||||||
|
maxLen = slen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t newW = maxLen * font->charWidth + LISTVIEW_COL_PAD;
|
||||||
|
|
||||||
|
if (newW < LISTVIEW_MIN_COL_W) {
|
||||||
|
newW = LISTVIEW_MIN_COL_W;
|
||||||
|
}
|
||||||
|
|
||||||
|
hit->as.listView->resolvedColW[c] = newW;
|
||||||
|
|
||||||
|
// Recalculate totalColW
|
||||||
|
int32_t total = 0;
|
||||||
|
|
||||||
|
for (int32_t tc = 0; tc < hit->as.listView->colCount; tc++) {
|
||||||
|
total += hit->as.listView->resolvedColW[tc];
|
||||||
|
}
|
||||||
|
|
||||||
|
hit->as.listView->totalColW = total;
|
||||||
|
wgtInvalidatePaint(hit);
|
||||||
|
} else {
|
||||||
|
// Start column resize drag (deferred until mouse moves)
|
||||||
sResizeListView = hit;
|
sResizeListView = hit;
|
||||||
sResizeCol = c;
|
sResizeCol = c;
|
||||||
sResizeStartX = vx;
|
sResizeStartX = vx;
|
||||||
sResizeOrigW = cw;
|
sResizeOrigW = cw;
|
||||||
|
sResizeDragging = false;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -415,6 +415,7 @@ int32_t shellLoadApp(AppContextT *ctx, const char *path) {
|
||||||
app->state = AppStateRunningE;
|
app->state = AppStateRunningE;
|
||||||
|
|
||||||
shellLog("Shell: loaded '%s' (id=%ld, mainLoop=%s, entry=0x%08lx, desc=0x%08lx)", app->name, (long)id, app->hasMainLoop ? "yes" : "no", (unsigned long)entry, (unsigned long)desc);
|
shellLog("Shell: loaded '%s' (id=%ld, mainLoop=%s, entry=0x%08lx, desc=0x%08lx)", app->name, (long)id, app->hasMainLoop ? "yes" : "no", (unsigned long)entry, (unsigned long)desc);
|
||||||
|
shellDesktopUpdate();
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -178,4 +178,7 @@ void shellExportInit(void);
|
||||||
// and is the only consumer.
|
// and is the only consumer.
|
||||||
void shellRegisterDesktopUpdate(void (*updateFn)(void));
|
void shellRegisterDesktopUpdate(void (*updateFn)(void));
|
||||||
|
|
||||||
|
// Notify the desktop app that app state has changed (load, reap, crash).
|
||||||
|
void shellDesktopUpdate(void);
|
||||||
|
|
||||||
#endif // SHELL_APP_H
|
#endif // SHELL_APP_H
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,6 @@ static void (*sDesktopUpdateFn)(void) = NULL;
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void crashHandler(int sig);
|
static void crashHandler(int sig);
|
||||||
static void desktopUpdate(void);
|
|
||||||
static void idleYield(void *ctx);
|
static void idleYield(void *ctx);
|
||||||
static void installCrashHandler(void);
|
static void installCrashHandler(void);
|
||||||
static void logCrash(int sig);
|
static void logCrash(int sig);
|
||||||
|
|
@ -89,10 +88,10 @@ static void crashHandler(int sig) {
|
||||||
|
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// desktopUpdate — notify desktop app of state change
|
// shellDesktopUpdate — notify desktop app of state change
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
static void desktopUpdate(void) {
|
void shellDesktopUpdate(void) {
|
||||||
if (sDesktopUpdateFn) {
|
if (sDesktopUpdateFn) {
|
||||||
sDesktopUpdateFn();
|
sDesktopUpdateFn();
|
||||||
}
|
}
|
||||||
|
|
@ -326,7 +325,7 @@ int main(void) {
|
||||||
|
|
||||||
sCurrentAppId = 0;
|
sCurrentAppId = 0;
|
||||||
sCrashSignal = 0;
|
sCrashSignal = 0;
|
||||||
desktopUpdate();
|
shellDesktopUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main loop — runs until dvxQuit() sets sCtx.running = false.
|
// Main loop — runs until dvxQuit() sets sCtx.running = false.
|
||||||
|
|
@ -347,7 +346,7 @@ int main(void) {
|
||||||
// This is the safe point for cleanup — we're at the top of the
|
// This is the safe point for cleanup — we're at the top of the
|
||||||
// main loop, not inside any callback or compositor operation.
|
// main loop, not inside any callback or compositor operation.
|
||||||
if (shellReapApps(&sCtx)) {
|
if (shellReapApps(&sCtx)) {
|
||||||
desktopUpdate();
|
shellDesktopUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue