Start of scrollable area widget.

This commit is contained in:
Scott Duensing 2022-07-16 17:27:12 -05:00
parent 93b29de643
commit b27ef131c7
6 changed files with 207 additions and 12 deletions

View file

@ -59,6 +59,7 @@ HEADERS += \
src/gui/widgets/picture.h \
src/gui/widgets/radio.h \
src/gui/widgets/hscroll.h \
src/gui/widgets/scroll.h \
src/gui/widgets/vscroll.h \
src/gui/wmwindow.h \
src/os.h \
@ -81,6 +82,7 @@ SOURCES += \
src/gui/widgets/picture.c \
src/gui/widgets/radio.c \
src/gui/widgets/hscroll.c \
src/gui/widgets/scroll.c \
src/gui/widgets/vscroll.c \
src/gui/wmwindow.c \
src/main.c \

View file

@ -38,6 +38,7 @@
#include "widgets/radio.h"
#include "widgets/vscroll.h"
#include "widgets/hscroll.h"
#include "widgets/scroll.h"
#endif // GUIALL_H

View file

@ -199,6 +199,7 @@ uint8_t guiStartup(int16_t width, int16_t height, int16_t depth) {
guiRegister(radioRegister);
guiRegister(vscrollRegister);
guiRegister(hscrollRegister);
guiRegister(scrollableRegister); // After hscroll and vscroll.
return SUCCESS;
}

View file

@ -0,0 +1,130 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*
*/
#include "../image.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) {
}
// 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));
// Set up desired scroll bars.
s->flags = flags;
if (s->flags & SCROLLABLE_SCROLL_V) {
s->scrollv = vscrollCreate(height, scrollableClickHandler, NULL);
vscrollRangeSet(s->scrollv, 0, totalHeight- 1);
w = s->scrollv->base.r.w;
}
if (s->flags & SCROLLABLE_SCROLL_H) {
s->scrollh = hscrollCreate(width - w, scrollableClickHandler, NULL);
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);
widgetBaseSet(W(s), __MAGIC_SCROLLABLE, width, height);
return s;
}
static void scrollableDestroy(struct WidgetS *widget, ...) {
ScrollableT *s = (ScrollableT *)widget;
if (s->scrollh) widgetDestroy(W(s->scrollh));
if (s->scrollv) widgetDestroy(W(s->scrollv));
if (s->area) surfaceDestroy(&s->area);
DEL(s);
}
static void scrollablePaint(struct WidgetS *widget, ...) {
ScrollableT *s = (ScrollableT *)widget;
int16_t width;
int16_t height;
if (widgetDirtyGet(widget)) {
widgetDirtySet(widget, 0);
// Find height and width of blittable area, based on presence of scrollbars.
if (s->scrollh) {
height = s->base.r.h - s->scrollh->base.r.h;
widgetPaintManually(W(s->scrollh), s->base.r.x, s->base.r.y + height);
} else {
height = s->base.r.h;
}
if (s->scrollv) {
width = s->base.r.w - s->scrollv->base.r.w;
widgetPaintManually(W(s->scrollv), s->base.r.x + width, s->base.r.y);
} else {
width = s->base.r.w;
}
// Blit.
surfaceBlit(s->base.r.x, s->base.r.y, s->offset.x, s->offset.y, width, height, 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 &reg;
}

View file

@ -0,0 +1,59 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*
*/
#ifndef SCROLL_H
#define SCROLL_H
#include "../gui.h"
#include "hscroll.h"
#include "vscroll.h"
#define SCROLLABLE_NONE 0
#define SCROLLABLE_SCROLL_V 1
#define SCROLLABLE_SCROLL_H 2
#define SCROLLABLE_STANDARD (SCROLLABLE_SCROLL_V | SCROLLABLE_SCROLL_H)
typedef struct ScrollableS {
WidgetT base; // Required by all widgets.
PointT offset; // View offset.
SurfaceT *area; // Scrollable area buffer.
HscrollT *scrollh; // Horizontal scroll bar.
VscrollT *scrollv; // Vertical scroll bar.
uint8_t flags; // Flag bits.
} ScrollableT;
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, ...);
RegisterT *scrollableRegister(uint8_t magic);
#endif // SCROLL_H

View file

@ -27,7 +27,7 @@
VscrollT *_v = NULL;
VscrollT *_h = NULL;
HscrollT *_h = NULL;
void clickHandler(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, void *data) {
@ -37,20 +37,19 @@ void clickHandler(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event, void *
int main(int argc, char *argv[]) {
char title[256];
uint16_t i;
WindowT *w = NULL;
LabelT *l = NULL;
ButtonT *b = NULL;
CheckboxT *c = NULL;
RadioT *r = NULL;
char title[256];
uint16_t i;
WindowT *w = NULL;
LabelT *l = NULL;
ButtonT *b = NULL;
CheckboxT *c = NULL;
RadioT *r = NULL;
ScrollableT *s = NULL;
// frame
// scrollarea
// vscroll
// hscroll
// listbox
// textbox
// up/down
@ -69,7 +68,7 @@ int main(int argc, char *argv[]) {
for (i=1; i<4; i++) {
sprintf(title, "Testing %d", i);
w = windowCreate(i * 50, i * 50, 300, 200, title, WIN_STANDARD, 640, 480);
w = windowCreate(i * 50, i * 50, 600, 400, title, WIN_STANDARD, 640, 480);
l = labelCreate(LABEL_ALIGN_LEFT, __guiFontVGA8x16, "Label");
labelColorSet(l, __guiBaseColors[i], GUI_BLACK);
@ -102,7 +101,10 @@ int main(int argc, char *argv[]) {
_h = hscrollCreate(100, clickHandler, NULL);
hscrollRangeSet(_h, 0, 640);
windowWidgetAdd(w, 70, 5, W(_h));
windowWidgetAdd(w, 100, 5, W(_h));
s = scrollableCreate(300, 200, 648, 480, SCROLLABLE_STANDARD);
windowWidgetAdd(w, 20, 170, W(s));
}
guiRun();
guiShutdown();