From 0ceae99da38d75cd7986e0cbe86ad4c778294b1a Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Thu, 26 Mar 2026 14:29:11 -0500 Subject: [PATCH] Tabbing bugs fixed. --- core/dvxApp.c | 9 ++++++++ core/dvxWidget.h | 3 +++ core/platform/dvxPlatformDos.c | 3 --- shell/Makefile | 9 ++++---- widgets/widgetScrollPane.c | 41 ++++++++++++++++++++++++++++++++-- widgets/widgetScrollPane.h | 2 ++ 6 files changed, 58 insertions(+), 9 deletions(-) diff --git a/core/dvxApp.c b/core/dvxApp.c index 7f33953..e4a3297 100644 --- a/core/dvxApp.c +++ b/core/dvxApp.c @@ -4361,6 +4361,15 @@ static void pollKeyboard(AppContextT *ctx) { win->hScroll->value = clampInt(win->hScroll->value, win->hScroll->min, win->hScroll->max); } + // Scroll into view inside any scroll container ancestor + for (WidgetT *p = next->parent; p; p = p->parent) { + if (p->wclass && (p->wclass->flags & WCLASS_SCROLL_CONTAINER) && + p->wclass->scrollChildIntoView) { + p->wclass->scrollChildIntoView(p, next); + break; + } + } + wgtInvalidate(win->widgetRoot); } } diff --git a/core/dvxWidget.h b/core/dvxWidget.h index f04afb3..6570515 100644 --- a/core/dvxWidget.h +++ b/core/dvxWidget.h @@ -197,6 +197,9 @@ typedef struct WidgetClassT { // Text field width (for scroll calculations; 0 = use widget width) int32_t (*getTextFieldWidth)(const struct WidgetT *w); + // Scroll a child widget into the visible area (ScrollPane, etc.) + void (*scrollChildIntoView)(struct WidgetT *parent, const struct WidgetT *child); + // Scrollbar drag update (orient: 0=vert, 1=horiz) void (*scrollDragUpdate)(struct WidgetT *w, int32_t orient, int32_t dragOff, int32_t mouseX, int32_t mouseY); } WidgetClassT; diff --git a/core/platform/dvxPlatformDos.c b/core/platform/dvxPlatformDos.c index 3167a8a..ec358f6 100644 --- a/core/platform/dvxPlatformDos.c +++ b/core/platform/dvxPlatformDos.c @@ -1884,9 +1884,6 @@ int32_t platformVideoInit(DisplayT *d, int32_t requestedW, int32_t requestedH, i d->clipW = d->width; d->clipH = d->height; - fprintf(stderr, "VBE: Mode 0x%04X set: %ldx%ldx%ld, pitch=%ld\n", - bestMode, (long)d->width, (long)d->height, (long)d->format.bitsPerPixel, (long)d->pitch); - return 0; } diff --git a/shell/Makefile b/shell/Makefile index e03b6f3..8aecfcd 100644 --- a/shell/Makefile +++ b/shell/Makefile @@ -59,10 +59,11 @@ $(WPAPERDIR)/%.jpg: ../config/wpaper/%.jpg | $(WPAPERDIR) cp $< $@ # Dependencies -$(OBJDIR)/shellMain.o: shellMain.c shellApp.h -$(OBJDIR)/shellApp.o: shellApp.c shellApp.h -$(OBJDIR)/shellInfo.o: shellInfo.c shellInfo.h shellApp.h -$(OBJDIR)/shellTaskMgr.o: shellTaskMgr.c shellTaskMgr.h shellApp.h +SHELL_DEPS = shellApp.h ../core/dvxWidget.h ../core/dvxApp.h ../core/dvxTypes.h ../core/platform/dvxPlatform.h +$(OBJDIR)/shellMain.o: shellMain.c $(SHELL_DEPS) +$(OBJDIR)/shellApp.o: shellApp.c $(SHELL_DEPS) +$(OBJDIR)/shellInfo.o: shellInfo.c shellInfo.h $(SHELL_DEPS) +$(OBJDIR)/shellTaskMgr.o: shellTaskMgr.c shellTaskMgr.h $(SHELL_DEPS) clean: rm -f $(OBJS) $(TARGET) $(LIBSDIR)/dvxshell.dep diff --git a/widgets/widgetScrollPane.c b/widgets/widgetScrollPane.c index 74bcc4e..a9e477f 100644 --- a/widgets/widgetScrollPane.c +++ b/widgets/widgetScrollPane.c @@ -51,6 +51,7 @@ static void drawSPVScrollbar(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const static void spCalcNeeds(WidgetT *w, const BitmapFontT *font, int32_t *contentMinW, int32_t *contentMinH, int32_t *innerW, int32_t *innerH, bool *needVSb, bool *needHSb); static void widgetScrollPaneDestroy(WidgetT *w); static void widgetScrollPaneScrollDragUpdate(WidgetT *w, int32_t orient, int32_t dragOff, int32_t mouseX, int32_t mouseY); +void wgtScrollPaneScrollToChild(WidgetT *w, const WidgetT *child); // ============================================================ @@ -780,7 +781,8 @@ static const WidgetClassT sClassScrollPane = { .destroy = widgetScrollPaneDestroy, .getText = NULL, .setText = NULL, - .scrollDragUpdate = widgetScrollPaneScrollDragUpdate + .scrollChildIntoView = wgtScrollPaneScrollToChild, + .scrollDragUpdate = widgetScrollPaneScrollDragUpdate }; @@ -806,6 +808,39 @@ WidgetT *wgtScrollPane(WidgetT *parent) { } +void wgtScrollPaneScrollToChild(WidgetT *w, const WidgetT *child) { + VALIDATE_WIDGET_VOID(w, sTypeId); + ScrollPaneDataT *sp = (ScrollPaneDataT *)w->data; + AppContextT *ctx = wgtGetContext(w); + const BitmapFontT *font = &ctx->font; + + int32_t contentMinW; + int32_t contentMinH; + int32_t innerW; + int32_t innerH; + bool needVSb; + bool needHSb; + + spCalcNeeds(w, font, &contentMinW, &contentMinH, &innerW, &innerH, &needVSb, &needHSb); + + // Child's virtual offset within the scrollable content + int32_t childOffY = child->y - w->y - SP_BORDER + sp->scrollPosV; + int32_t maxScrollV = contentMinH - innerH; + + if (maxScrollV < 0) { + maxScrollV = 0; + } + + if (childOffY < sp->scrollPosV) { + sp->scrollPosV = childOffY; + } else if (childOffY + child->h > sp->scrollPosV + innerH) { + sp->scrollPosV = childOffY + child->h - innerH; + } + + sp->scrollPosV = clampInt(sp->scrollPosV, 0, maxScrollV); +} + + // ============================================================ // DXE registration // ============================================================ @@ -813,8 +848,10 @@ WidgetT *wgtScrollPane(WidgetT *parent) { static const struct { WidgetT *(*create)(WidgetT *parent); + void (*scrollToChild)(WidgetT *sp, const WidgetT *child); } sApi = { - .create = wgtScrollPane + .create = wgtScrollPane, + .scrollToChild = wgtScrollPaneScrollToChild }; void wgtRegister(void) { diff --git a/widgets/widgetScrollPane.h b/widgets/widgetScrollPane.h index d780c92..eca3479 100644 --- a/widgets/widgetScrollPane.h +++ b/widgets/widgetScrollPane.h @@ -6,6 +6,7 @@ typedef struct { WidgetT *(*create)(WidgetT *parent); + void (*scrollToChild)(WidgetT *sp, const WidgetT *child); } ScrollPaneApiT; static inline const ScrollPaneApiT *dvxScrollPaneApi(void) { @@ -15,5 +16,6 @@ static inline const ScrollPaneApiT *dvxScrollPaneApi(void) { } #define wgtScrollPane(parent) dvxScrollPaneApi()->create(parent) +#define wgtScrollPaneScrollToChild(sp, child) dvxScrollPaneApi()->scrollToChild((sp), (child)) #endif // WIDGET_SCROLLPANE_H