diff --git a/roo-e/src/gui/gui.c b/roo-e/src/gui/gui.c index 1a36b7a..16c3f4e 100644 --- a/roo-e/src/gui/gui.c +++ b/roo-e/src/gui/gui.c @@ -315,7 +315,7 @@ void widgetMove(WidgetT *widget, int16_t x, int16_t y) { void widgetPaintManually(WidgetT *widget, int16_t x, int16_t y) { - RectT r = widget->r; + RectWT r = widget->r; widgetDirtySet(widget, 1); widget->r.x = x; diff --git a/roo-e/src/gui/gui.h b/roo-e/src/gui/gui.h index 6b4368e..89d40fa 100644 --- a/roo-e/src/gui/gui.h +++ b/roo-e/src/gui/gui.h @@ -57,18 +57,19 @@ typedef struct PointS { } PointT; typedef struct RectS { - int16_t x; - int16_t y; - union { - int16_t w; - int16_t x2; - }; - union { - int16_t h; - int16_t y2; - }; + int16_t x; + int16_t y; + int16_t x2; + int16_t y2; } RectT; +typedef struct RectWS { + int16_t x; + int16_t y; + int16_t w; + int16_t h; +} RectWT; + typedef struct RegisterS { char *widgetName; // Text name of widget. ClickHandlerT click; // Click handler. @@ -79,7 +80,7 @@ typedef struct RegisterS { typedef struct WidgetS { uint8_t magic; // Magic ID of widget. Must be first! - RectT r; // Outer bounds of widget. NOTE: USES WIDTH/HEIGHT, NOT X2/Y2! + RectWT r; // Outer bounds of widget. NOTE: USES WIDTH/HEIGHT, NOT X2/Y2! RegisterT *reg; // Registration information. void *data; // Pointer to arbitrary data for user. uint16_t flags; // Widget flags (see defines above). diff --git a/roo-e/src/gui/widgets/button.c b/roo-e/src/gui/widgets/button.c index cdf75d3..b9f4508 100644 --- a/roo-e/src/gui/widgets/button.c +++ b/roo-e/src/gui/widgets/button.c @@ -109,9 +109,9 @@ static void buttonPaint(struct WidgetS *widget, ...) { if (widgetDirtyGet(widget)) { widgetDirtySet(widget, 0); // Paint button. - surfaceBoxHighlight(b->base.r.x, b->base.r.y, b->base.r.x + b->base.r.x2 - 1, b->base.r.y + b->base.r.y2 - 1, h, s); - surfaceBoxHighlight(b->base.r.x + 1, b->base.r.y + 1, b->base.r.x + b->base.r.x2 - 2, b->base.r.y + b->base.r.y2 - 2, h, s); - surfaceBoxFilled(b->base.r.x + 2, b->base.r.y + 2, b->base.r.x + b->base.r.x2 - 3, b->base.r.y + b->base.r.y2 - 3, GUI_LIGHTGRAY); + surfaceBoxHighlight(b->base.r.x, b->base.r.y, b->base.r.x + b->base.r.w - 1, b->base.r.y + b->base.r.h - 1, h, s); + surfaceBoxHighlight(b->base.r.x + 1, b->base.r.y + 1, b->base.r.x + b->base.r.w - 2, b->base.r.y + b->base.r.h - 2, h, s); + surfaceBoxFilled(b->base.r.x + 2, b->base.r.y + 2, b->base.r.x + b->base.r.w - 3, b->base.r.y + b->base.r.h - 3, GUI_LIGHTGRAY); // Paint label. widgetPaintManually(W(b->label), b->base.r.x + b->offset.x + b->isPressed, b->base.r.y + b->offset.y + b->isPressed); } diff --git a/roo-e/src/gui/widgets/hscroll.c b/roo-e/src/gui/widgets/hscroll.c index fb79ab2..991062b 100644 --- a/roo-e/src/gui/widgets/hscroll.c +++ b/roo-e/src/gui/widgets/hscroll.c @@ -151,7 +151,8 @@ static void hscrollPaint(struct WidgetS *widget, ...) { widgetColor = GUI_DARKGRAY; } // Find coordinates. - r = h->base.r; + r.x = h->base.r.x; + r.y = h->base.r.y; r.x2 = r.x + h->base.r.w - 1; r.y2 = r.y + h->base.r.h - 1; // Paint scrollbar. @@ -162,14 +163,6 @@ static void hscrollPaint(struct WidgetS *widget, ...) { // Prepare font. fontSet(__guiFontVGA8x8); fontColorSet(widgetColor, scrollBackgroundColor); - // ***TODO*** - /* - // If we have both horizontal and vertical scroll bars, we need to fix a shadow. - if (w->flags & WIN_SCROLL_V) { - surfaceLineV(w->scrollh.x2 - 1, w->scrollh.y, w->scrollh.y2, GUI_BLACK); - surfaceLineV(w->scrollh.x2, w->scrollh.y, w->scrollh.y2, GUI_WHITE); - } - */ // Draw arrows. fontRender("\x11", r.x + 7, r.y + 7); fontRender("\x10", r.x2 - 12, r.y + 7); @@ -183,7 +176,7 @@ static void hscrollPaint(struct WidgetS *widget, ...) { h->thumb.y = r.y + 1; h->thumb.y2 = r.y2 - 1; // Clamp overflow due to doubles and my off-by-one brain. - if (h->thumb.x2 >= h->thumb.x + i - 1) h->thumb.x2 = h->thumb.x + i - 1; + if (h->thumb.x2 >= r.x + GADGET_SIZE + i - 1) h->thumb.x2 = r.x + GADGET_SIZE + i - 1; // Draw thumb. surfaceBoxFilled(h->thumb.x + 1, h->thumb.y + 1, h->thumb.x2 - 1, h->thumb.y2 - 1, GUI_LIGHTGRAY); surfaceBoxHighlight(h->thumb.x, h->thumb.y, h->thumb.x2, h->thumb.y2, GUI_WHITE, GUI_BLACK); diff --git a/roo-e/src/gui/widgets/scroll.c b/roo-e/src/gui/widgets/scroll.c index abcef5a..abdf3c9 100644 --- a/roo-e/src/gui/widgets/scroll.c +++ b/roo-e/src/gui/widgets/scroll.c @@ -53,30 +53,33 @@ static void scrollableClickHandler(WidgetT *widget, uint16_t x, uint16_t y, uint // Passing "flags" as a default int provides proper alignment for the following va_args list. -ScrollableT *scrollableCreate(int16_t width, int16_t height, int16_t totalWidth, int16_t totalHeight, int flags, ...) { +ScrollableT *scrollableCreate(int16_t visibleWidth, int16_t visibleHeight, int16_t totalWidth, int16_t totalHeight, int flags, ...) { ScrollableT *s = NULL; SurfaceT *t = surfaceGet(); - int16_t w = 0; NEW(ScrollableT, s); memset(s, 0, sizeof(ScrollableT)); - widgetBaseSet(W(s), __MAGIC_SCROLLABLE, width, height); + widgetBaseSet(W(s), __MAGIC_SCROLLABLE, visibleWidth, visibleHeight); - s->original.x = width; - s->original.y = height; + // Remember the original size of the visible area we're painting into because we're going to resize the widget to make room for scroll bars. + s->original.x = visibleWidth; + s->original.y = visibleHeight; + + logWrite("scrollableCreate: %dx%d\n", s->original.x, s->original.y); // Set up desired scroll bars. s->flags = flags; if (s->flags & SCROLLABLE_SCROLL_V) { + // Vertical scroll bar. s->flags |= SCROLLABLE_NOT_SETUP; - s->scrollv = vscrollCreate(height, scrollableClickHandler, s); + s->scrollv = vscrollCreate(visibleHeight, scrollableClickHandler, s); vscrollRangeSet(s->scrollv, 0, totalHeight- 1); - w = s->scrollv->base.r.w; // Used when creating horizontal scroll bar below. } if (s->flags & SCROLLABLE_SCROLL_H) { + // Horizontal scroll bar. s->flags |= SCROLLABLE_NOT_SETUP; - s->scrollh = hscrollCreate(width - w, scrollableClickHandler, s); + s->scrollh = hscrollCreate(visibleWidth, scrollableClickHandler, s); hscrollRangeSet(s->scrollh, 0, totalWidth - 1); } @@ -110,38 +113,34 @@ static void scrollableDestroy(struct WidgetS *widget, ...) { static void scrollableFixupSizes(ScrollableT *s) { - int16_t w = 0; - // Vertical scrollbar. if (s->scrollv) { - // Position for vertical scrollbar. - s->sizes.x = s->original.x - s->scrollv->base.r.w; + // Position for vertical scrollbar. Also used as width of area to blit. + s->position.x = s->original.x - s->scrollv->base.r.w + 1; // Make scroll area smaller to make room for scrollbar. s->base.r.w = s->original.x - s->scrollv->base.r.w; // Resize vertical scrollbar. - vscrollHeightSet(s->scrollv, s->original.y); + vscrollHeightSet(s->scrollv, s->original.y - (s->scrollh ? s->scrollh->base.r.h - 1 : 0)); // Position vertical scrollbar. - widgetMove(W(s->scrollv), s->base.r.x + s->sizes.x, s->base.r.y); - // Used when positioning vertical scrollbar below. - w = s->scrollv->base.r.w; + widgetMove(W(s->scrollv), s->base.r.x + s->position.x, s->base.r.y); } else { - // No vertical scrollbar. Set this to a non-zero value. - s->sizes.x = s->base.r.w; + // No vertical scrollbar. Set this to width of scroll area. + s->position.x = s->base.r.w; } // Horizontal scrollbar. if (s->scrollh) { - // Position for horizontal scrollbar. - s->sizes.y = s->original.y - s->scrollh->base.r.h; + // Position for horizontal scrollbar. Also used as height of area to blit. + s->position.y = s->original.y - s->scrollh->base.r.h + 1; // Make scroll area smaller to make room for scrollbar. s->base.r.h = s->original.y - s->scrollh->base.r.h; // Resize horizontal scrollbar. - hscrollWidthSet(s->scrollh, s->original.x - w); + hscrollWidthSet(s->scrollh, s->original.x - - (s->scrollv ? s->scrollv->base.r.w - 1: 0)); // Position horizontal scrollbar. - widgetMove(W(s->scrollh), s->base.r.x, s->base.r.y + s->sizes.y); + widgetMove(W(s->scrollh), s->base.r.x, s->base.r.y + s->position.y); } else { - // No horizontal scrollbar. Set this to a non-zero value. - s->sizes.y = s->base.r.h; + // No horizontal scrollbar. Set this to height of scroll area. + s->position.y = s->base.r.h; } } @@ -167,11 +166,11 @@ static void scrollablePaint(struct WidgetS *widget, ...) { scrollableFixupSizes(s); if (s->scrollh) { if (s->base.flags & WIDGET_IS_WINDOW) s->scrollh->base.flags |= WIDGET_IS_WINDOW; - widgetAdd(s->base.parent, s->base.r.x, s->base.r.y + s->sizes.y, W(s->scrollh)); + widgetAdd(s->base.parent, s->base.r.x, s->base.r.y + s->position.y, W(s->scrollh)); } if (s->scrollv) { if (s->base.flags & WIDGET_IS_WINDOW) s->scrollv->base.flags |= WIDGET_IS_WINDOW; - widgetAdd(s->base.parent, s->base.r.x + s->sizes.x, s->base.r.y, W(s->scrollv)); + widgetAdd(s->base.parent, s->base.r.x + s->position.x, s->base.r.y, W(s->scrollv)); } } @@ -191,6 +190,7 @@ static void scrollablePaint(struct WidgetS *widget, ...) { s->base.r.y = o.y; // Blit. + /* // if ((s->offset.x + s->sizes.x > surfaceWidthGet(s->area)) || (s->offset.y + s->sizes.y > surfaceHeightGet(s->area))) { logWrite("%dx%d %dx%d-%dx%d %dx%d %dx%d %d %d\n", s->base.r.x, s->base.r.y, @@ -200,7 +200,8 @@ static void scrollablePaint(struct WidgetS *widget, ...) { s->offset.x + s->sizes.x, s->offset.y + s->sizes.y, hscrollValueGet(s->scrollh), vscrollValueGet(s->scrollv)); // } - surfaceBlit(s->base.r.x, s->base.r.y, s->offset.x, s->offset.y, s->sizes.x, s->sizes.y, s->area); + */ + surfaceBlit(s->base.r.x, s->base.r.y, s->offset.x, s->offset.y, s->position.x, s->position.y, s->area); } } diff --git a/roo-e/src/gui/widgets/scroll.h b/roo-e/src/gui/widgets/scroll.h index bacf635..794c096 100644 --- a/roo-e/src/gui/widgets/scroll.h +++ b/roo-e/src/gui/widgets/scroll.h @@ -46,7 +46,7 @@ typedef struct ScrollableS { SurfaceT *area; // Scrollable area buffer. HscrollT *scrollh; // Horizontal scroll bar. VscrollT *scrollv; // Vertical scroll bar. - PointT sizes; // Scroll bar width and height info. + PointT position; // Horizontan and Veritcal Scroll bar X and Y positions. Also used as area to blit. PointT original; // Original size of widget before being resized to make room for scollbars. uint8_t flags; // Flag bits. } ScrollableT; @@ -55,7 +55,7 @@ typedef struct ScrollableS { extern uint8_t __MAGIC_SCROLLABLE; // Magic ID assigned to us from the GUI. -ScrollableT *scrollableCreate(int16_t width, int16_t height, int16_t totalWidth, int16_t totalHeight, int flags, ...); +ScrollableT *scrollableCreate(int16_t visibleWidth, int16_t visibleHeight, int16_t totalWidth, int16_t totalHeight, int flags, ...); void scrollableHeightSet(ScrollableT *scroll, int16_t h); RegisterT *scrollableRegister(uint8_t magic); void scrollableWidthSet(ScrollableT *scroll, int16_t w); diff --git a/roo-e/src/gui/widgets/vscroll.c b/roo-e/src/gui/widgets/vscroll.c index 45afd6a..932e6ca 100644 --- a/roo-e/src/gui/widgets/vscroll.c +++ b/roo-e/src/gui/widgets/vscroll.c @@ -35,10 +35,11 @@ uint8_t __MAGIC_VSCROLL = 0; static void vscrollClick(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, void *data); static void vscrollDestroy(struct WidgetS *widget, ...); static void vscrollPaint(struct WidgetS *widget, ...); +static void vscrollRecalculate(VscrollT *v); static void vscrollClick(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, void *data) { - VscrollT *v = (VscrollT *)widget; + VscrollT *v = (VscrollT *)widget; (void)data; @@ -47,7 +48,7 @@ static void vscrollClick(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, // Move content up. v->value -= SCROLL_SPEED_SLOW; // Clip. - if (v->value < v->min) v->value = v->min; + if (v->value < 0) v->value = 0; // Update. widgetDirtySet(widget, 1); // Call the actual click event. @@ -60,8 +61,7 @@ static void vscrollClick(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, // Move content down. v->value += SCROLL_SPEED_SLOW; // Clip. - logWrite("%d > %d - %d = %d\n", v->value, v->max, v->base.r.h, v->max - v->base.r.h); - if (v->value > v->max - v->base.r.h) v->value = v->max - v->base.r.h; + if (v->value > v->maxValue) v->value = v->maxValue; // Update. widgetDirtySet(widget, 1); // Call the actual click event. @@ -69,6 +69,7 @@ static void vscrollClick(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, return; } + /* // Clicking above thumb? Also fakes dragging. if (y < v->thumb.y) { // Move content up. @@ -94,6 +95,7 @@ static void vscrollClick(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, if (v->handler) v->handler(widget, x, y, event, v->base.data); return; } + */ } @@ -128,7 +130,6 @@ VscrollT *vscrollCreate(int16_t h, ClickHandlerT handler, void *data, ...) { static void vscrollDestroy(struct WidgetS *widget, ...) { VscrollT *v = (VscrollT *)widget; - DEL(v); } @@ -136,9 +137,9 @@ static void vscrollDestroy(struct WidgetS *widget, ...) { void vscrollHeightSet(VscrollT *vscroll, int16_t h) { // Make sure it's at least tall enough to draw. if (h < GADGET_SIZE * 3) h = GADGET_SIZE * 3; - vscroll->base.r.h = h; - + // This doesn't check that you haven't set some insane value for the height. Up to caller. + vscrollRecalculate(vscroll); widgetDirtySet(W(vscroll), 1); } @@ -148,8 +149,6 @@ static void vscrollPaint(struct WidgetS *widget, ...) { ColorT scrollBackgroundColor; ColorT widgetColor; RectT r; - int16_t i; - double d; if (widgetDirtyGet(widget)) { widgetDirtySet(widget, 0); @@ -161,8 +160,11 @@ static void vscrollPaint(struct WidgetS *widget, ...) { scrollBackgroundColor = GUI_LIGHTGRAY; widgetColor = GUI_DARKGRAY; } - // Find coordinates. - r = v->base.r; + // Do the math. + vscrollRecalculate(v); + // Find coordinates to draw scrollbar. + r.x = v->base.r.x; + r.y = v->base.r.y; r.x2 = r.x + v->base.r.w - 1; r.y2 = r.y + v->base.r.h - 1; // Paint scrollbar. @@ -176,17 +178,6 @@ static void vscrollPaint(struct WidgetS *widget, ...) { // Draw arrows. fontRender("\x1e", r.x + 7, r.y + 7); fontRender("\x1f", r.x + 7, r.y2 - 12); - // Distance between arrow buttons on scroll bar. - i = r.y2 - r.y - (GADGET_SIZE * 2 - 2) - 2; - // Percentage to scale content height to scroll bar height. - d = (double)i / (double)(v->max - v->min); - // Find position and size of thumb. - v->thumb.x = r.x + 1; - v->thumb.x2 = r.x2 - 1; - v->thumb.y = r.y + GADGET_SIZE + (v->value * d); - v->thumb.y2 = v->thumb.y + (v->base.r.h * d); - // Clamp overflow due to doubles and my off-by-one brain. - if (v->thumb.y2 >= v->thumb.y + i - 1) v->thumb.y2 = v->thumb.y + i - 1; // Draw thumb. surfaceBoxFilled(v->thumb.x + 1, v->thumb.y + 1, v->thumb.x2 - 1, v->thumb.y2 - 1, GUI_LIGHTGRAY); surfaceBoxHighlight(v->thumb.x, v->thumb.y, v->thumb.x2, v->thumb.y2, GUI_WHITE, GUI_BLACK); @@ -206,6 +197,48 @@ void vscrollRangeSet(VscrollT *vscroll, int32_t min, int32_t max) { } +static void vscrollRecalculate(VscrollT *v) { + int16_t range; + int16_t areaTop; + int16_t area; + int16_t areaBottom; + int16_t thumbSize; + float percent; + RectT r; + + // Range of scroll. + range = v->max - v->min + 1; + + // Find coordinates to draw scrollbar. Setting r to be one smaller than the widget's size makes later math cleaner. + r.x = v->base.r.x; + r.y = v->base.r.y; + r.x2 = r.x + v->base.r.w - 1; + r.y2 = r.y + v->base.r.h - 1; + + // Find coordinates of thumb area. + areaTop = r.y + GADGET_SIZE + 1; + areaBottom = r.y2 - GADGET_SIZE - 1; + area = areaBottom - areaTop + 1; + + // Find scale percentage. + percent = (float)area / (float)range; + + // Find thumb position and size. + thumbSize = (int16_t)(percent * (float)area); + v->thumb.x = r.x + 1; + v->thumb.x2 = r.x2 - 1; + v->thumb.y = (int16_t)((float)v->value * percent) + areaTop; + v->thumb.y2 = v->thumb.y + thumbSize; + v->maxValue = (area - thumbSize) / percent; + + // Clamp. + logWrite("maxValue %d + area %d >= range %d\n", v->maxValue, area, range); + //if (v->maxValue + area >= range) v->maxValue = range - area - 1; + if (v->maxValue < 0) v->maxValue = 0; + if (v->value > v->maxValue) vscrollValueSet(v, v->maxValue); +} + + RegisterT *vscrollRegister(uint8_t magic) { static RegisterT reg = { "Vscroll", @@ -223,15 +256,17 @@ RegisterT *vscrollRegister(uint8_t magic) { int32_t vscrollValueGet(VscrollT *vscroll) { - return vscroll->value; + // Internal value is always 0 based, so adjust for min. + return vscroll->value + vscroll->min; } void vscrollValueSet(VscrollT *vscroll, int32_t value) { + // Clamp. if (value < vscroll->min) value = vscroll->min; if (value > vscroll->max) value = vscroll->max; - if (vscroll->value != value) { - vscroll->value = value; - widgetDirtySet(W(vscroll), 1); - } + // Internal value is always 0 based, so adjust for min. + vscroll->value = value - vscroll->min; + vscrollRecalculate(vscroll); + widgetDirtySet(W(vscroll), 1); } diff --git a/roo-e/src/gui/widgets/vscroll.h b/roo-e/src/gui/widgets/vscroll.h index aee928d..b7eae91 100644 --- a/roo-e/src/gui/widgets/vscroll.h +++ b/roo-e/src/gui/widgets/vscroll.h @@ -35,6 +35,7 @@ typedef struct VscrollS { int32_t min; int32_t max; int32_t value; + int32_t maxValue; RectT thumb; ClickHandlerT handler; // Actual event handler. } VscrollT; diff --git a/roo-e/src/gui/wmwindow.c b/roo-e/src/gui/wmwindow.c index 7c4619c..8c75a5f 100644 --- a/roo-e/src/gui/wmwindow.c +++ b/roo-e/src/gui/wmwindow.c @@ -235,8 +235,8 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) { // Passing "flags" as a default int provides proper alignment for the following va_args list. WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title, int flags, ...) { - int16_t width; - int16_t height; + PointT visibleSize; + PointT totalSize; va_list args; WindowT *win = NULL; int8_t sflags = SCROLLABLE_NONE; @@ -249,24 +249,29 @@ WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *titl win->title = strdup(title); win->flags = (uint8_t)flags; + logWrite("windowCreate: %dx%d\n", win->base.r.w, win->base.r.h); + + // Cache the window so we get valid bounds values. + windowCache(win, 1); + visibleSize.x = win->bounds.x2 - win->bounds.x + 1; + visibleSize.y = win->bounds.y2 - win->bounds.y + 1; + // If the window is resizable, we need to get two more arguments for the content size. if (win->flags & WIN_RESIZE) { va_start(args, flags); - width = va_arg(args, int); - height = va_arg(args, int); + totalSize.x = va_arg(args, int); + totalSize.y = va_arg(args, int); va_end(args); sflags = SCROLLABLE_STANDARD; } else { // Use whatever the default content area is. This causes an extra draw on create. Oh well. - windowCache(win, 1); - width = win->bounds.x2 - win->bounds.x; - height = win->bounds.y2 - win->bounds.y; + totalSize = visibleSize; widgetDirtySet(W(win), 1); if (flags & WIN_SCROLL_H) sflags |= SCROLLABLE_SCROLL_H; if (flags & WIN_SCROLL_V) sflags |= SCROLLABLE_SCROLL_V; } - win->scroll = scrollableCreate(w, h, width, height, sflags); + win->scroll = scrollableCreate(visibleSize.x, visibleSize.y, totalSize.x, totalSize.y, sflags); win->scroll->base.flags |= WIDGET_IS_WINDOW; widgetAdd(W(win), 0, 0, W(win->scroll)); @@ -561,11 +566,18 @@ void windowResize(WindowT *win, uint16_t width, uint16_t height) { int16_t y = 0; int16_t content = 0; int16_t change = 0; + PointT chrome; + + // Find size of window chrome. + chrome.x = win->base.r.w - (win->bounds.x2 - win->bounds.x) + 1; + chrome.y = win->base.r.h - (win->bounds.y2 - win->bounds.y) + 1; // Too small? - if (width < (GADGET_SIZE * 4) + 15) width = (GADGET_SIZE * 4) + 15; - if (height < (GADGET_SIZE * 4) + 15) height = (GADGET_SIZE * 4) + 15; +// if (width < (GADGET_SIZE * 4) + 15) width = (GADGET_SIZE * 4) + 15; + if (height < (GADGET_SIZE * 4) + chrome.y) height = (GADGET_SIZE * 4) + chrome.y; +// logWrite("Chrome Y: %d Height: %d\n", chrome.y, height); +/* // Too big? Horizontal. // Get the current view offset. x = scrollableValueHGet(win->scroll); @@ -590,22 +602,28 @@ void windowResize(WindowT *win, uint16_t width, uint16_t height) { // Clamp. x = win->base.r.w - content + surfaceWidthGet(win->scroll->area); if (width > x) width = x; +*/ // Too big? Vertical. // Get the current view offset. y = scrollableValueVGet(win->scroll); // Height of content area of window. - content = win->bounds.y2 - win->bounds.y; + content = win->bounds.y2 - win->bounds.y + 1; + // Do we have a vertical scroll bar? if (win->scroll->scrollv) { // Do we need to take the height of the horizontal scroll bar into account? if (win->scroll->scrollh) content -= win->scroll->scrollh->base.r.h; // Change in height. change = height - win->base.r.h; + // Is the visible content area with this change offset by the scrollbar taller than the total content area? if (content + change + y > surfaceHeightGet(win->scroll->area)) { // Do we have room to scroll content into view? if (y > 0) { + // Find out how far we're trying to scroll. delta = height - win->base.r.h; + // Clamp to available scroll area. if (delta > y) delta = y; + // Scroll. scrollableValueVSet(win->scroll, y - delta); } height = (win->base.r.h - content - y + surfaceHeightGet(win->scroll->area)); @@ -613,6 +631,7 @@ void windowResize(WindowT *win, uint16_t width, uint16_t height) { } // Clamp. y = win->base.r.h - content + surfaceHeightGet(win->scroll->area); +// logWrite("Y Clamp: %d > %d Chrome: %d\n", height, y, win->base.r.h - content); if (height > y) height = y; // Did the size change? @@ -690,7 +709,7 @@ void wmUpdate(EventT *event) { } // If we're over a widget that has raw input processing enabled and we haven't started a click on another widget yet, send to target for raw processing. - if (widgetOver && !widgetDown && !dragging && (widgetOver->flags & WIDGET_RAW_INPUT) && (event->buttons != 0)) { + if (widgetOver && !widgetDown && !dragging && !resizing && (widgetOver->flags & WIDGET_RAW_INPUT) && (event->buttons != 0)) { if (widgetOver->reg->click) { rawEvent.event = event; rawEvent.data = widget->data; @@ -720,7 +739,7 @@ void wmUpdate(EventT *event) { // DEBUG - draw active regions. surfaceSet(__guiBackBuffer); surfaceBox(win->base.r.x, win->base.r.y, x2, y2, GUI_YELLOW); - surfaceBox(win->bounds.x, win->bounds.y, win->bounds.x2, win->bounds.y2, GUI_CYAN); + surfaceBox(win->bounds.x, win->bounds.y, win->bounds.x2, win->bounds.y2, GUI_YELLOW); surfaceBox(win->close.x, win->close.y, win->close.x2, win->close.y2, GUI_LIGHTBLUE); surfaceBox(win->titlebar.x, win->titlebar.y, win->titlebar.x2, win->titlebar.y2, GUI_LIGHTCYAN); surfaceBox(win->minimize.x, win->minimize.y, win->minimize.x2, win->minimize.y2, GUI_LIGHTGREEN); @@ -916,7 +935,7 @@ static WidgetT *wuWidgetUnderMouseGet(WindowT *win, EventT *event, int16_t *loca // Find widget under mouse. for (i=0; ibase.children); i++) { widget = win->base.children[i]; - if (*localX >= widget->r.x && *localX < widget->r.x + widget->r.x2 && *localY >= widget->r.y && *localY < widget->r.y + widget->r.y2) { + if (*localX >= widget->r.x && *localX < widget->r.x + widget->r.w && *localY >= widget->r.y && *localY < widget->r.y + widget->r.h) { //logWrite("Over %s\n", widget->reg->widgetName); // Return this widget. return widget; diff --git a/roo-e/src/gui/wmwindow.h b/roo-e/src/gui/wmwindow.h index e435fbc..45da53e 100644 --- a/roo-e/src/gui/wmwindow.h +++ b/roo-e/src/gui/wmwindow.h @@ -60,7 +60,7 @@ typedef struct WindowS { RectT resize1; // First resize area. RectT resize2; // Second resize area. ScrollableT *scroll; // Window contents and scroll bars. - RectT restore; // Size of window if they restore from maximized. + RectWT restore; // Size of window if they restore from maximized. PointT restoreOffset; // Scroll position if they restore from maximized. RectT bounds; // Inside edge of window frame. /* diff --git a/roo-e/src/main.c b/roo-e/src/main.c index 1a1005e..9e1af3f 100644 --- a/roo-e/src/main.c +++ b/roo-e/src/main.c @@ -66,7 +66,7 @@ int main(int argc, char *argv[]) { if (guiStartup(800, 600, 16) == SUCCESS) { - for (i=1; i<4; i++) { + for (i=1; i<2; i++) { sprintf(title, "Testing %d", i); w = windowCreate(i * 50, i * 50, 600, 400, title, WIN_STANDARD, 640, 480); @@ -95,6 +95,7 @@ int main(int argc, char *argv[]) { r = radioCreate("Radio C", 1, 0); widgetAdd(W(w), 220, 140, W(r)); + /* _v = vscrollCreate(100, clickHandler, NULL); vscrollRangeSet(_v, 0, 640); widgetAdd(W(w), 200, 5, W(_v)); @@ -105,6 +106,7 @@ int main(int argc, char *argv[]) { s = scrollableCreate(300, 200, 648, 480, SCROLLABLE_STANDARD); widgetAdd(W(w), 20, 170, W(s)); + */ } guiRun(); guiShutdown();