/* * Roo/E, the Kangaroo Punch Portable GUI Toolkit * Copyright (C) 2022 Scott Duensing * * http://kangaroopunch.com * * * This file is part of Roo/E. * * Roo/E is free software: you can redistribute it and/or modify it under the * terms of the GNU Affero General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) * any later version. * * Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License * along with Roo/E. If not, see . * */ #include "../wmwindow.h" #include "scroll.h" uint8_t __MAGIC_SCROLLABLE = 0; static void scrollableClickHandler(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, void *data); static void scrollableDestroy(struct WidgetS *widget, ...); static void scrollablePaint(struct WidgetS *widget, ...); static void scrollableClickHandler(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, void *data) { ScrollableT *s = (ScrollableT *)data; (void)widget; (void)x; (void)y; (void)event; logWrite("Event from scrollable - %d %d\n", hscrollValueGet(s->scrollh), vscrollValueGet(s->scrollv)); s->offset.x = hscrollValueGet(s->scrollh); s->offset.y = vscrollValueGet(s->scrollv); } // 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 *s = NULL; SurfaceT *t = surfaceGet(); int16_t w = 0; NEW(ScrollableT, s); memset(s, 0, sizeof(ScrollableT)); widgetBaseSet(W(s), __MAGIC_SCROLLABLE, width, height); // Set up desired scroll bars. s->flags = flags; if (s->flags & SCROLLABLE_SCROLL_V) { s->scrollv = vscrollCreate(height, 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) { s->scrollh = hscrollCreate(width - w, scrollableClickHandler, s); hscrollRangeSet(s->scrollh, 0, totalWidth - 1); } // Create scrollable surface. s->area = surfaceCreate(totalWidth, totalHeight); if (!s->area) { DEL(s); return NULL; } surfaceSet(s->area); surfaceClear(GUI_LIGHTBLUE); surfaceSet(t); return s; } static void scrollableDestroy(struct WidgetS *widget, ...) { ScrollableT *s = (ScrollableT *)widget; // Do not destroy scroll bars here - the parent owns them at this point. if (s->area) surfaceDestroy(&s->area); DEL(s); } static void scrollablePaint(struct WidgetS *widget, ...) { ScrollableT *s = (ScrollableT *)widget; if (widgetDirtyGet(widget)) { widgetDirtySet(widget, 0); // Finish initializing? if (s->sizes.x == 0 && s->sizes.y == 0) { if (s->scrollh) { s->sizes.y = s->base.r.h - s->scrollh->base.r.h; s->base.r.h -= s->scrollh->base.r.h; windowWidgetAdd(s->base.parent, s->base.r.x, s->base.r.y + s->sizes.y, W(s->scrollh)); } else { s->sizes.y = s->base.r.h; } if (s->scrollv) { s->sizes.x = s->base.r.w - s->scrollv->base.r.w; s->base.r.w -= s->scrollv->base.r.w; windowWidgetAdd(s->base.parent, s->base.r.x + s->sizes.x, s->base.r.y, W(s->scrollv)); } else { s->sizes.x = s->base.r.w; } } // Blit. surfaceBlit(s->base.r.x, s->base.r.y, s->offset.x, s->offset.y, s->sizes.x, s->sizes.y, s->area); } } RegisterT *scrollableRegister(uint8_t magic) { static RegisterT reg = { "Scrollable", NULL, // No default on-click handler. scrollableDestroy, scrollablePaint, NULL // No unregister handler. }; // One-time widget startup code. __MAGIC_SCROLLABLE = magic; return ® }