New ScrollableT windows are rendering. No clicking yet.
This commit is contained in:
parent
3bc40f02a5
commit
105a8a63a2
10 changed files with 255 additions and 366 deletions
|
@ -54,7 +54,8 @@ static uint8_t _mouseCurrent = MOUSE_POINTER;
|
|||
static PointT _mouseHotspot[MOUSE_COUNT] = { { 0, 0 }, { 8, 8 } };
|
||||
|
||||
|
||||
static void guiDeleteListProcess(void);
|
||||
static void guiDeleteListProcess(void);
|
||||
static uint8_t widgetChildrenDirtyPaint(WidgetT *widget, uint8_t paint);
|
||||
|
||||
|
||||
static void guiDeleteListProcess(void) {
|
||||
|
@ -212,10 +213,18 @@ void guiStop(void) {
|
|||
|
||||
|
||||
void widgetAdd(WidgetT *target, int16_t x, int16_t y, WidgetT *widget) {
|
||||
widget->parent = target;
|
||||
WidgetT *t = target;
|
||||
|
||||
// ***TODO*** I don't like that this generic widget method needs specific knowledge of other widgets to work properly.
|
||||
// If we're adding to a WindowT, then we REALLY want to add to the window's ScrollableT.
|
||||
if ((t->magic == __MAGIC_WINDOW) && !(widget->flags & WIDGET_IS_WINDOW)) t = W(((WindowT *)t)->scroll);
|
||||
|
||||
widget->parent = t;
|
||||
widget->r.x = x;
|
||||
widget->r.y = y;
|
||||
arrput(target->children, widget);
|
||||
arrput(t->children, widget);
|
||||
|
||||
logWrite("Adding %s to %s\n", widget->reg->widgetName, t->reg->widgetName);
|
||||
}
|
||||
|
||||
|
||||
|
@ -231,6 +240,42 @@ void widgetBaseSet(WidgetT *widget, uint8_t magic, uint16_t w, uint16_t h) {
|
|||
}
|
||||
|
||||
|
||||
uint8_t widgetChildrenDirty(WidgetT *widget) {
|
||||
return widgetChildrenDirtyPaint(widget, 0);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t widgetChildrenDirtyPaint(WidgetT *widget, uint8_t paint) {
|
||||
int16_t x;
|
||||
uint8_t updated = 0;
|
||||
SurfaceT *t = surfaceGet();
|
||||
|
||||
// Are any child widgets dirty?
|
||||
for (x=0; x<arrlen(widget->children); x++) {
|
||||
if (widgetDirtyGet(widget->children[x])) {
|
||||
// Are we painting? Can it paint?
|
||||
if (paint && widget->children[x]->reg->paint) {
|
||||
// This is a flag for later that we need to update the cached surface.
|
||||
updated = 1;
|
||||
// Paint it.
|
||||
widget->children[x]->reg->paint(widget->children[x]);
|
||||
logWrite("Painted %s on %s\n", widget->children[x]->reg->widgetName, widget->children[x]->parent->reg->widgetName);
|
||||
} else {
|
||||
updated = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
surfaceSet(t);
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
||||
uint8_t widgetChildrenPaint(WidgetT *widget) {
|
||||
return widgetChildrenDirtyPaint(widget, 1);
|
||||
}
|
||||
|
||||
|
||||
void widgetDestroy(WidgetT *widget) {
|
||||
// Add to list of widgets to delete.
|
||||
arrput(_deleteList, widget);
|
||||
|
@ -265,6 +310,13 @@ uint8_t widgetIsInWidget(WidgetT *widget, WidgetT *parent) {
|
|||
}
|
||||
|
||||
|
||||
void widgetMove(WidgetT *widget, int16_t x, int16_t y) {
|
||||
widget->r.x = x;
|
||||
widget->r.y = y;
|
||||
widgetDirtySet(widget, 1);
|
||||
}
|
||||
|
||||
|
||||
void widgetPaintManually(WidgetT *widget, int16_t x, int16_t y) {
|
||||
RectT r = widget->r;
|
||||
|
||||
|
|
|
@ -32,10 +32,11 @@
|
|||
#include "font.h"
|
||||
|
||||
|
||||
#define WIDGET_DIRTY 1
|
||||
#define WIDGET_HIDDEN 2
|
||||
#define WIDGET_DISABLED 4
|
||||
#define WIDGET_RAW_INPUT 8
|
||||
#define WIDGET_DIRTY 1
|
||||
#define WIDGET_HIDDEN 2
|
||||
#define WIDGET_DISABLED 4
|
||||
#define WIDGET_RAW_INPUT 8
|
||||
#define WIDGET_IS_WINDOW 16 // This lets us know if this widget is being used as one of the components of a window.
|
||||
|
||||
#define CLICK_RAW_INPUT 1
|
||||
#define CLICK_LEFT_CANCEL 2
|
||||
|
@ -81,7 +82,7 @@ typedef struct WidgetS {
|
|||
RectT r; // Outer bounds of widget. NOTE: USES WIDTH/HEIGHT, NOT X2/Y2!
|
||||
RegisterT *reg; // Registration information.
|
||||
void *data; // Pointer to arbitrary data for user.
|
||||
uint8_t flags; // Widget flags (see defines above).
|
||||
uint16_t flags; // Widget flags (see defines above).
|
||||
struct WidgetS *parent; // Who owns this widget?
|
||||
struct WidgetS **children; // Widgets contained in this widget.
|
||||
} WidgetT;
|
||||
|
@ -107,6 +108,10 @@ extern FontT *__guiFontVGA8x16;
|
|||
#define MOUSE_COUNT 2
|
||||
|
||||
|
||||
#define SCROLL_SPEED_SLOW 5
|
||||
#define SCROLL_SPEED_FAST 25
|
||||
|
||||
|
||||
#define GUI_BLACK __guiBaseColors[0]
|
||||
#define GUI_BLUE __guiBaseColors[1]
|
||||
#define GUI_GREEN __guiBaseColors[2]
|
||||
|
@ -140,11 +145,14 @@ void guiStop(void);
|
|||
|
||||
void widgetAdd(WidgetT *target, int16_t x, int16_t y, WidgetT *widget);
|
||||
void widgetBaseSet(WidgetT *widget, uint8_t magic, uint16_t w, uint16_t h);
|
||||
uint8_t widgetChildrenDirty(WidgetT *widget);
|
||||
uint8_t widgetChildrenPaint(WidgetT *widget);
|
||||
void widgetDestroy(WidgetT *widget);
|
||||
uint8_t widgetDirtyGet(WidgetT *widget);
|
||||
void widgetDirtySet(WidgetT *widget, uint8_t dirty);
|
||||
void widgetInputSetRaw(WidgetT *widget, uint8_t raw);
|
||||
uint8_t widgetIsInWidget(WidgetT *widget, WidgetT *parent);
|
||||
void widgetMove(WidgetT *widget, int16_t x, int16_t y);
|
||||
void widgetPaintManually(WidgetT *widget, int16_t x, int16_t y);
|
||||
void widgetRemove(WidgetT *target, WidgetT *widget);
|
||||
|
||||
|
|
|
@ -112,10 +112,10 @@ HscrollT *hscrollCreate(int16_t w, ClickHandlerT handler, void *data, ...) {
|
|||
h->max = 100;
|
||||
h->value = 1;
|
||||
|
||||
if (w < GADGET_SIZE * 3) w = GADGET_SIZE * 3;
|
||||
|
||||
widgetBaseSet(W(h), __MAGIC_HSCROLL, w, GADGET_SIZE);
|
||||
|
||||
hscrollWidthSet(h, w);
|
||||
|
||||
h->handler = handler;
|
||||
h->base.data = data;
|
||||
|
||||
|
@ -232,3 +232,13 @@ void hscrollValueSet(HscrollT *hscroll, int32_t value) {
|
|||
widgetDirtySet(W(hscroll), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void hscrollWidthSet(HscrollT *hscroll, int16_t w) {
|
||||
// Make sure it's at least wide enough to draw.
|
||||
if (w < GADGET_SIZE * 3) w = GADGET_SIZE * 3;
|
||||
|
||||
hscroll->base.r.w = w;
|
||||
|
||||
widgetDirtySet(W(hscroll), 1);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ void hscrollRangeSet(HscrollT *hscroll, int32_t min, int32_t max);
|
|||
RegisterT *hscrollRegister(uint8_t magic);
|
||||
int32_t hscrollValueGet(HscrollT *hscroll);
|
||||
void hscrollValueSet(HscrollT *hscroll, int32_t value);
|
||||
void hscrollWidthSet(HscrollT *hscroll, int16_t w);
|
||||
|
||||
|
||||
#endif // HSCROLL_H
|
||||
|
|
|
@ -26,12 +26,15 @@
|
|||
#include "../wmwindow.h"
|
||||
#include "scroll.h"
|
||||
|
||||
#include "array.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 scrollableFixupSizes(ScrollableT *s);
|
||||
static void scrollablePaint(struct WidgetS *widget, ...);
|
||||
|
||||
|
||||
|
@ -43,8 +46,6 @@ static void scrollableClickHandler(WidgetT *widget, uint16_t x, uint16_t y, uint
|
|||
(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);
|
||||
}
|
||||
|
@ -61,14 +62,19 @@ ScrollableT *scrollableCreate(int16_t width, int16_t height, int16_t totalWidth,
|
|||
|
||||
widgetBaseSet(W(s), __MAGIC_SCROLLABLE, width, height);
|
||||
|
||||
s->original.x = width;
|
||||
s->original.y = height;
|
||||
|
||||
// Set up desired scroll bars.
|
||||
s->flags = flags;
|
||||
if (s->flags & SCROLLABLE_SCROLL_V) {
|
||||
s->flags |= SCROLLABLE_NOT_SETUP;
|
||||
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->flags |= SCROLLABLE_NOT_SETUP;
|
||||
s->scrollh = hscrollCreate(width - w, scrollableClickHandler, s);
|
||||
hscrollRangeSet(s->scrollh, 0, totalWidth - 1);
|
||||
}
|
||||
|
@ -89,6 +95,11 @@ ScrollableT *scrollableCreate(int16_t width, int16_t height, int16_t totalWidth,
|
|||
|
||||
static void scrollableDestroy(struct WidgetS *widget, ...) {
|
||||
ScrollableT *s = (ScrollableT *)widget;
|
||||
uint16_t c;
|
||||
|
||||
// Free children.
|
||||
for (c=0; c<arrlen(s->base.children); c++) widgetDestroy(s->base.children[c]);
|
||||
arrfree(s->base.children);
|
||||
|
||||
// Do not destroy scroll bars here - the parent owns them at this point.
|
||||
if (s->area) surfaceDestroy(&s->area);
|
||||
|
@ -97,28 +108,80 @@ 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;
|
||||
// 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);
|
||||
// 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;
|
||||
} else {
|
||||
// No vertical scrollbar. Set this to a non-zero value.
|
||||
s->sizes.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;
|
||||
// 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);
|
||||
// Position horizontal scrollbar.
|
||||
widgetMove(W(s->scrollh), s->base.r.x, s->base.r.y + s->sizes.y);
|
||||
} else {
|
||||
// No horizontal scrollbar. Set this to a non-zero value.
|
||||
s->sizes.y = s->base.r.h;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void scrollableHeightSet(ScrollableT *scroll, int16_t h) {
|
||||
scroll->original.y = h;
|
||||
scrollableFixupSizes(scroll);
|
||||
widgetDirtySet(W(scroll), 1);
|
||||
}
|
||||
|
||||
|
||||
static void scrollablePaint(struct WidgetS *widget, ...) {
|
||||
ScrollableT *s = (ScrollableT *)widget;
|
||||
ScrollableT *s = (ScrollableT *)widget;
|
||||
SurfaceT *t = surfaceGet();
|
||||
PointT o;
|
||||
|
||||
if (widgetDirtyGet(widget)) {
|
||||
widgetDirtySet(widget, 0);
|
||||
// Finish initializing?
|
||||
if (s->sizes.x == 0 && s->sizes.y == 0) {
|
||||
if (s->flags & SCROLLABLE_NOT_SETUP) {
|
||||
s->flags &= ~SCROLLABLE_NOT_SETUP;
|
||||
scrollableFixupSizes(s);
|
||||
if (s->scrollh) {
|
||||
s->sizes.y = s->base.r.h - s->scrollh->base.r.h;
|
||||
s->base.r.h -= s->scrollh->base.r.h;
|
||||
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));
|
||||
} 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;
|
||||
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));
|
||||
} else {
|
||||
s->sizes.x = s->base.r.w;
|
||||
}
|
||||
}
|
||||
// Before painting contents, we need to offset everything by the window borders.
|
||||
o.x = s->base.r.x;
|
||||
o.y = s->base.r.y;
|
||||
s->base.r.x = 0;
|
||||
s->base.r.y = 0;
|
||||
surfaceSet(s->area);
|
||||
widgetChildrenPaint(widget);
|
||||
surfaceSet(t);
|
||||
s->base.r.x = o.x;
|
||||
s->base.r.y = o.y;
|
||||
// Blit.
|
||||
surfaceBlit(s->base.r.x, s->base.r.y, s->offset.x, s->offset.y, s->sizes.x, s->sizes.y, s->area);
|
||||
}
|
||||
|
@ -139,3 +202,11 @@ RegisterT *scrollableRegister(uint8_t magic) {
|
|||
|
||||
return ®
|
||||
}
|
||||
|
||||
|
||||
void scrollableWidthSet(ScrollableT *scroll, int16_t w) {
|
||||
scroll->original.x = w;
|
||||
scrollableFixupSizes(scroll);
|
||||
widgetDirtySet(W(scroll), 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#define SCROLLABLE_NONE 0
|
||||
#define SCROLLABLE_SCROLL_V 1
|
||||
#define SCROLLABLE_SCROLL_H 2
|
||||
#define SCROLLABLE_NOT_SETUP 4
|
||||
|
||||
#define SCROLLABLE_STANDARD (SCROLLABLE_SCROLL_V | SCROLLABLE_SCROLL_H)
|
||||
|
||||
|
@ -46,6 +47,7 @@ typedef struct ScrollableS {
|
|||
HscrollT *scrollh; // Horizontal scroll bar.
|
||||
VscrollT *scrollv; // Vertical scroll bar.
|
||||
PointT sizes; // Scroll bar width and height info.
|
||||
PointT original; // Original size of widget before being resized to make room for scollbars.
|
||||
uint8_t flags; // Flag bits.
|
||||
} ScrollableT;
|
||||
|
||||
|
@ -54,7 +56,9 @@ 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, ...);
|
||||
void scrollableHeightSet(ScrollableT *scroll, int16_t h);
|
||||
RegisterT *scrollableRegister(uint8_t magic);
|
||||
void scrollableWidthSet(ScrollableT *scroll, int16_t w);
|
||||
|
||||
|
||||
#endif // SCROLL_H
|
||||
|
|
|
@ -112,10 +112,10 @@ VscrollT *vscrollCreate(int16_t h, ClickHandlerT handler, void *data, ...) {
|
|||
v->max = 100;
|
||||
v->value = 1;
|
||||
|
||||
if (h < GADGET_SIZE * 3) h = GADGET_SIZE * 3;
|
||||
|
||||
widgetBaseSet(W(v), __MAGIC_VSCROLL, GADGET_SIZE, h);
|
||||
|
||||
vscrollHeightSet(v, h);
|
||||
|
||||
v->handler = handler;
|
||||
v->base.data = data;
|
||||
|
||||
|
@ -132,6 +132,16 @@ 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;
|
||||
|
||||
widgetDirtySet(W(vscroll), 1);
|
||||
}
|
||||
|
||||
|
||||
static void vscrollPaint(struct WidgetS *widget, ...) {
|
||||
VscrollT *v = (VscrollT *)widget;
|
||||
ColorT scrollBackgroundColor;
|
||||
|
|
|
@ -45,6 +45,7 @@ extern uint8_t __MAGIC_VSCROLL; // Magic ID assigned to us from the GUI.
|
|||
|
||||
void vscrollClickSet(VscrollT *vscroll, ClickHandlerT handler, void *data);
|
||||
VscrollT *vscrollCreate(int16_t h, ClickHandlerT handler, void *data, ...);
|
||||
void vscrollHeightSet(VscrollT *vscroll, int16_t h);
|
||||
void vscrollRangeSet(VscrollT *vscroll, int32_t min, int32_t max);
|
||||
RegisterT *vscrollRegister(uint8_t magic);
|
||||
int32_t vscrollValueGet(VscrollT *vscroll);
|
||||
|
|
|
@ -31,16 +31,14 @@
|
|||
uint8_t __MAGIC_WINDOW = 0;
|
||||
|
||||
|
||||
static WindowT **_windowList = NULL;
|
||||
static WindowT *_windowTop = NULL;
|
||||
static int16_t _iconCount = 0;
|
||||
static WindowT **_windowList = NULL;
|
||||
static WindowT *_windowTop = NULL;
|
||||
static int16_t _iconCount = 0;
|
||||
|
||||
|
||||
static void windowCache(WindowT *w, uint8_t redrawWindow);
|
||||
static void windowDestroy(struct WidgetS *widget, ...);
|
||||
static void windowPaint(struct WidgetS *widget, ...);
|
||||
static void windowScrollHorizontalHandler(EventT *e, WindowT *w);
|
||||
static void windowScrollVerticalHandler(EventT *e, WindowT *w);
|
||||
|
||||
static WidgetT *wuWidgetUnderMouseGet(WindowT *win, EventT *event, int16_t *localX, int16_t *localY);
|
||||
|
||||
|
@ -57,14 +55,12 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
int16_t ty2;
|
||||
int16_t originalX;
|
||||
int16_t originalY;
|
||||
double d;
|
||||
RectT originalBounds;
|
||||
ColorT scrollBackgroundColor;
|
||||
ColorT scrollThumbColor;
|
||||
ColorT titleBackgroundColor;
|
||||
ColorT widgetColor;
|
||||
ColorT gadgetColor;
|
||||
SurfaceT *target = surfaceGet();
|
||||
|
||||
logWrite("Caching window\n");
|
||||
|
||||
// Move the window to 0,0 to draw it into it's own surface.
|
||||
originalX = w->base.r.x;
|
||||
originalY = w->base.r.y;
|
||||
|
@ -82,6 +78,7 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
// Do we need to create a surface?
|
||||
if (!w->cached) {
|
||||
w->cached = surfaceCreate(w->base.r.w, w->base.r.h);
|
||||
logWrite("New cache surface\n");
|
||||
}
|
||||
|
||||
// Draw into cache.
|
||||
|
@ -89,10 +86,8 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
|
||||
if (redrawWindow) {
|
||||
// Determine some colors.
|
||||
scrollBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY;
|
||||
scrollThumbColor = GUI_LIGHTGRAY;
|
||||
titleBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY;
|
||||
widgetColor = (w == _windowTop) ? GUI_LIGHTGRAY : GUI_DARKGRAY;
|
||||
gadgetColor = (w == _windowTop) ? GUI_LIGHTGRAY : GUI_DARKGRAY;
|
||||
|
||||
// Get ready!
|
||||
x1 = w->base.r.x;
|
||||
|
@ -124,7 +119,7 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
w->close.x2 = tx1 - 1;
|
||||
w->close.y2 = ty2 - 1;
|
||||
surfaceBoxFilled(w->close.x + 1, w->close.y + 1, w->close.x2 - 1, w->close.y2 - 1, titleBackgroundColor);
|
||||
surfaceBoxHighlight(w->close.x + 3, w->close.y + 8, w->close.x2 - 3, w->close.y2 - 8, GUI_WHITE, widgetColor);
|
||||
surfaceBoxHighlight(w->close.x + 3, w->close.y + 8, w->close.x2 - 3, w->close.y2 - 8, GUI_WHITE, gadgetColor);
|
||||
surfaceBoxHighlight(w->close.x, w->close.y, w->close.x2, w->close.y2, GUI_WHITE, GUI_BLACK);
|
||||
} else {
|
||||
w->close.x = w->close.y = w->close.x2 = w->close.y2 = 0;
|
||||
|
@ -140,8 +135,8 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
surfaceBoxFilled(w->maximize.x + 1, w->maximize.y + 1, w->maximize.x2 - 1, w->maximize.y2 - 1, titleBackgroundColor);
|
||||
surfaceLine(w->maximize.x + 4, w->maximize.y + 10, w->maximize.x + 10, w->maximize.y + 4, GUI_WHITE);
|
||||
surfaceLine(w->maximize.x + 4, w->maximize.y + 10, w->maximize.x + 10, w->maximize.y2 - 3, GUI_WHITE);
|
||||
surfaceLine(w->maximize.x2 - 3, w->maximize.y + 10, w->maximize.x2 - 9, w->maximize.y + 4, widgetColor);
|
||||
surfaceLine(w->maximize.x2 - 3, w->maximize.y + 10, w->maximize.x2 - 9, w->maximize.y2 - 3, widgetColor);
|
||||
surfaceLine(w->maximize.x2 - 3, w->maximize.y + 10, w->maximize.x2 - 9, w->maximize.y + 4, gadgetColor);
|
||||
surfaceLine(w->maximize.x2 - 3, w->maximize.y + 10, w->maximize.x2 - 9, w->maximize.y2 - 3, gadgetColor);
|
||||
surfaceBoxHighlight(w->maximize.x, w->maximize.y, w->maximize.x2, w->maximize.y2, GUI_WHITE, GUI_BLACK);
|
||||
} else {
|
||||
w->maximize.x = w->maximize.y = w->maximize.x2 = w->maximize.y2 = 0;
|
||||
|
@ -155,7 +150,7 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
w->minimize.x2 = tx2 + GADGET_SIZE;
|
||||
w->minimize.y2 = ty2 - 1;
|
||||
surfaceBoxFilled(w->minimize.x + 1, w->minimize.y + 1, w->minimize.x2 - 1, w->minimize.y2 - 1, titleBackgroundColor);
|
||||
surfaceBoxHighlight(w->minimize.x + 7, w->minimize.y + 7, w->minimize.x2 - 7, w->minimize.y2 - 7, GUI_WHITE, widgetColor);
|
||||
surfaceBoxHighlight(w->minimize.x + 7, w->minimize.y + 7, w->minimize.x2 - 7, w->minimize.y2 - 7, GUI_WHITE, gadgetColor);
|
||||
surfaceBoxHighlight(w->minimize.x, w->minimize.y, w->minimize.x2, w->minimize.y2, GUI_WHITE, GUI_BLACK);
|
||||
} else {
|
||||
w->minimize.x = w->minimize.y = w->minimize.x2 = w->maximize.y2 = 0;
|
||||
|
@ -196,111 +191,6 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
w->titlebar.x = w->titlebar.y = w->titlebar.x2 = w->titlebar.y2 = 0;
|
||||
}
|
||||
|
||||
// Vertical Scroll Bar?
|
||||
if (w->flags & WIN_SCROLL_V) {
|
||||
w->scrollv.x2 = x2;
|
||||
w->scrollv.x = w->scrollv.x2 - (GADGET_SIZE - 1);
|
||||
w->scrollv.y = y1;
|
||||
w->scrollv.y2 = y2;
|
||||
// Draw scroll bar.
|
||||
surfaceBoxFilled(w->scrollv.x + 1, w->scrollv.y + 1, w->scrollv.x2 - 1, w->scrollv.y2 - 1, scrollBackgroundColor);
|
||||
surfaceBoxHighlight(w->scrollv.x, w->scrollv.y, w->scrollv.x2, w->scrollv.y2, GUI_WHITE, GUI_BLACK);
|
||||
surfaceLineH(w->scrollv.x + 1, w->scrollv.x2, w->scrollv.y + (GADGET_SIZE - 1), GUI_BLACK);
|
||||
surfaceLineH(w->scrollv.x + 1, w->scrollv.x2, w->scrollv.y2 - (GADGET_SIZE - 1), GUI_WHITE);
|
||||
// Prepare font.
|
||||
fontSet(__guiFontVGA8x8);
|
||||
fontColorSet(widgetColor, scrollBackgroundColor);
|
||||
// Draw arrows.
|
||||
fontRender("\x1e", w->scrollv.x + 7, w->scrollv.y + 7);
|
||||
fontRender("\x1f", w->scrollv.x + 7, w->scrollv.y2 - 12);
|
||||
|
||||
x2 -= (GADGET_SIZE - 1);
|
||||
} else {
|
||||
w->scrollv.x = w->scrollv.y = w->scrollv.x2 = w->scrollv.y2 = 0;
|
||||
}
|
||||
|
||||
// Horizontal Scroll Bar?
|
||||
if (w->flags & WIN_SCROLL_H) {
|
||||
w->scrollh.x = x1;
|
||||
w->scrollh.x2 = x2;
|
||||
w->scrollh.y2 = y2;
|
||||
w->scrollh.y = w->scrollh.y2 - (GADGET_SIZE - 1);
|
||||
// Draw scroll bar.
|
||||
surfaceBoxFilled(w->scrollh.x + 1, w->scrollh.y + 1, w->scrollh.x2 - 1, w->scrollh.y2 - 1, scrollBackgroundColor);
|
||||
surfaceBoxHighlight(w->scrollh.x, w->scrollh.y, w->scrollh.x2, w->scrollh.y2, GUI_WHITE, GUI_BLACK);
|
||||
surfaceLineV(w->scrollh.x + (GADGET_SIZE - 1), w->scrollh.y + 1, w->scrollh.y2, GUI_BLACK);
|
||||
surfaceLineV(w->scrollh.x2 - (GADGET_SIZE - 1), w->scrollh.y + 1, w->scrollh.y2, GUI_WHITE);
|
||||
// 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);
|
||||
}
|
||||
// Prepare font.
|
||||
fontSet(__guiFontVGA8x8);
|
||||
fontColorSet(widgetColor, scrollBackgroundColor);
|
||||
// Draw arrows.
|
||||
fontRender("\x11", w->scrollh.x + 7, w->scrollh.y + 7);
|
||||
fontRender("\x10", w->scrollh.x2 - 12, w->scrollh.y + 7);
|
||||
|
||||
y2 -= (GADGET_SIZE - 1);
|
||||
} else {
|
||||
w->scrollh.x = w->scrollh.y = w->scrollh.x2 = w->scrollh.y2 = 0;
|
||||
}
|
||||
|
||||
// Find content area.
|
||||
w->bounds.x = x1;
|
||||
w->bounds.y = y1;
|
||||
w->bounds.x2 = x2;
|
||||
w->bounds.y2 = y2;
|
||||
|
||||
// Do we have content yet?
|
||||
if (w->content) {
|
||||
|
||||
// Vertical Scroll Bar Thumb?
|
||||
if (w->flags & WIN_SCROLL_V) {
|
||||
// Distance between arrow buttons on scroll bar.
|
||||
i = w->scrollv.y2 - w->scrollv.y - (GADGET_SIZE * 2 - 2) - 2;
|
||||
// Percentage to scale content height to scroll bar height.
|
||||
d = (double)i / (double)surfaceHeightGet(w->content);
|
||||
// Find position and size of thumb.
|
||||
w->thumbv.x = w->scrollv.x + 1;
|
||||
w->thumbv.x2 = w->scrollv.x2 - 1;
|
||||
w->thumbv.y = w->scrollv.y + GADGET_SIZE + (w->offset.y * d);
|
||||
w->thumbv.y2 = w->thumbv.y + ((w->bounds.y2 - w->bounds.y) * d);
|
||||
// Clamp overflow due to doubles and my off-by-one brain.
|
||||
if (w->thumbv.y2 >= w->thumbv.y + i - 1) w->thumbv.y2 = w->thumbv.y + i - 1;
|
||||
// Draw thumb.
|
||||
surfaceBoxFilled(w->thumbv.x + 1, w->thumbv.y + 1, w->thumbv.x2 - 1, w->thumbv.y2 - 1, scrollThumbColor);
|
||||
surfaceBoxHighlight(w->thumbv.x, w->thumbv.y, w->thumbv.x2, w->thumbv.y2, GUI_WHITE, GUI_BLACK);
|
||||
} else {
|
||||
w->thumbv.x = w->thumbv.y = w->thumbv.x2 = w->thumbv.y2 = 0;
|
||||
}
|
||||
|
||||
// Horizontal Scroll Bar Thumb?
|
||||
if (w->flags & WIN_SCROLL_H) {
|
||||
// Distance between arrow buttons on scroll bar.
|
||||
i = w->scrollh.x2 - w->scrollh.x - (GADGET_SIZE * 2 - 2) - 2;
|
||||
// Percentage to scale content width to scroll bar width.
|
||||
d = (double)i / (double)surfaceWidthGet(w->content);
|
||||
// Find position and size of thumb.
|
||||
w->thumbh.x = w->scrollh.x + GADGET_SIZE + (w->offset.x * d);
|
||||
w->thumbh.x2 = w->thumbh.x + ((w->bounds.x2 - w->bounds.x) * d);
|
||||
w->thumbh.y = w->scrollh.y + 1;
|
||||
w->thumbh.y2 = w->scrollh.y2 - 1;
|
||||
// Clamp overflow due to doubles and my off-by-one brain.
|
||||
if (w->thumbh.x2 >= w->thumbh.x + i - 1) w->thumbh.x2 = w->thumbh.x + i - 1;
|
||||
// Draw thumb.
|
||||
surfaceBoxFilled(w->thumbh.x + 1, w->thumbh.y + 1, w->thumbh.x2 - 1, w->thumbh.y2 - 1, scrollThumbColor);
|
||||
surfaceBoxHighlight(w->thumbh.x, w->thumbh.y, w->thumbh.x2, w->thumbh.y2, GUI_WHITE, GUI_BLACK);
|
||||
} else {
|
||||
w->thumbh.x = w->thumbh.y = w->thumbh.x2 = w->thumbh.y2 = 0;
|
||||
}
|
||||
|
||||
} else { // Do we have content yet?
|
||||
w->thumbv.x = w->thumbv.y = w->thumbv.x2 = w->thumbv.y2 = 0;
|
||||
w->thumbh.x = w->thumbh.y = w->thumbh.x2 = w->thumbh.y2 = 0;
|
||||
}
|
||||
|
||||
// Resize handle.
|
||||
if (w->flags & WIN_RESIZE) {
|
||||
w->resize1.x2 = w->base.r.x + w->base.r.w - 2;
|
||||
|
@ -320,27 +210,25 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
w->resize2.x = w->resize2.y = w->resize2.x2 = w->resize2.y2 = 0;
|
||||
}
|
||||
|
||||
} else { // Redraw window.
|
||||
// Inside window frame.
|
||||
w->bounds.x = x1;
|
||||
w->bounds.y = y1;
|
||||
w->bounds.x2 = x2;
|
||||
w->bounds.y2 = y2;
|
||||
|
||||
// Since we didn't calculate them above, adjust bounds for content blit.
|
||||
originalBounds = w->bounds;
|
||||
w->bounds.x -= originalX;
|
||||
w->bounds.y -= originalY;
|
||||
w->bounds.x2 -= originalX;
|
||||
w->bounds.y2 -= originalY;
|
||||
}
|
||||
// Resize scrollable to fill window.
|
||||
if (w->scroll) {
|
||||
w->scroll->base.r.x = x1;
|
||||
w->scroll->base.r.y = y1;
|
||||
scrollableWidthSet(w->scroll, x2 - x1);
|
||||
scrollableHeightSet(w->scroll, y2 - y1);
|
||||
}
|
||||
} // Redraw window.
|
||||
|
||||
// Blit contents.
|
||||
if (w->content) surfaceBlit(w->bounds.x, w->bounds.y, w->offset.x, w->offset.y, w->bounds.x2 - w->bounds.x, w->bounds.y2 - w->bounds.y, w->content);
|
||||
widgetChildrenPaint(W(w));
|
||||
|
||||
// Fixup all the widget coordinates.
|
||||
if (redrawWindow) {
|
||||
windowMove(w, originalX, originalY);
|
||||
} else {
|
||||
w->bounds = originalBounds;
|
||||
w->base.r.x = originalX;
|
||||
w->base.r.y = originalY;
|
||||
}
|
||||
windowMove(w, originalX, originalY);
|
||||
|
||||
surfaceSet(target);
|
||||
}
|
||||
|
@ -352,7 +240,7 @@ WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *titl
|
|||
int16_t height;
|
||||
va_list args;
|
||||
WindowT *win = NULL;
|
||||
SurfaceT *t = surfaceGet();
|
||||
int8_t sflags = SCROLLABLE_NONE;
|
||||
|
||||
NEW(WindowT, win);
|
||||
memset(win, 0, sizeof(WindowT));
|
||||
|
@ -368,19 +256,20 @@ WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *titl
|
|||
width = va_arg(args, int);
|
||||
height = 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;
|
||||
widgetDirtySet(W(win), 1);
|
||||
if (flags & WIN_SCROLL_H) sflags |= SCROLLABLE_SCROLL_H;
|
||||
if (flags & WIN_SCROLL_V) sflags |= SCROLLABLE_SCROLL_V;
|
||||
}
|
||||
|
||||
// Create content surface and clear it.
|
||||
win->content = surfaceCreate(width, height);
|
||||
surfaceSet(win->content);
|
||||
surfaceClear(GUI_LIGHTGRAY);
|
||||
surfaceSet(t);
|
||||
win->scroll = scrollableCreate(w, h, width, height, sflags);
|
||||
win->scroll->base.flags |= WIDGET_IS_WINDOW;
|
||||
widgetAdd(W(win), 0, 0, W(win->scroll));
|
||||
|
||||
// Add to window list.
|
||||
arrput(_windowList, win);
|
||||
|
@ -418,8 +307,6 @@ static void windowDestroy(struct WidgetS *widget, ...) {
|
|||
arrfree(window->base.children);
|
||||
// Free cached surface.
|
||||
if (window->cached) surfaceDestroy(&window->cached);
|
||||
// Free content surface.
|
||||
if (window->content) surfaceDestroy(&window->content);
|
||||
// Delete the window.
|
||||
DEL(window);
|
||||
// Fixup focus.
|
||||
|
@ -494,24 +381,18 @@ void windowMaximizeRestore(WindowT *win) {
|
|||
// Restore to previous size.
|
||||
win->flags &= ~WIN_IS_MAX;
|
||||
win->base.r = win->restore;
|
||||
win->offset = win->restoreOffset;
|
||||
|
||||
} else { // Maximized?
|
||||
|
||||
// Maximize window. Reposition if needed.
|
||||
win->flags |= WIN_IS_MAX;
|
||||
|
||||
// Remember current size and position.
|
||||
// Remember current size.
|
||||
win->restore = win->base.r;
|
||||
win->restoreOffset = win->offset;
|
||||
|
||||
// Scroll contents to home.
|
||||
win->offset.x = 0;
|
||||
win->offset.y = 0;
|
||||
|
||||
// Expand to full contents.
|
||||
win->base.r.w = (win->base.r.w - (win->bounds.x2 - win->bounds.x) + surfaceWidthGet(win->content));
|
||||
win->base.r.h = (win->base.r.h - (win->bounds.y2 - win->bounds.y) + surfaceHeightGet(win->content));
|
||||
win->base.r.w = (win->base.r.w - (win->bounds.x2 - win->bounds.x) + win->scroll->original.x);
|
||||
win->base.r.h = (win->base.r.h - (win->bounds.y2 - win->bounds.y) + win->scroll->original.y);
|
||||
|
||||
// Does this go off the screen to the right?
|
||||
if (win->base.r.x + win->base.r.w >= videoDisplayWidthGet()) {
|
||||
|
@ -592,28 +473,6 @@ void windowMove(WindowT *w, uint16_t x, uint16_t y) {
|
|||
w->titlebar.y2 += dy;
|
||||
}
|
||||
|
||||
if (w->flags & WIN_SCROLL_V) {
|
||||
w->scrollv.x += dx;
|
||||
w->scrollv.y += dy;
|
||||
w->scrollv.x2 += dx;
|
||||
w->scrollv.y2 += dy;
|
||||
w->thumbv.x += dx;
|
||||
w->thumbv.y += dy;
|
||||
w->thumbv.x2 += dx;
|
||||
w->thumbv.y2 += dy;
|
||||
}
|
||||
|
||||
if (w->flags & WIN_SCROLL_H) {
|
||||
w->scrollh.x += dx;
|
||||
w->scrollh.y += dy;
|
||||
w->scrollh.x2 += dx;
|
||||
w->scrollh.y2 += dy;
|
||||
w->thumbh.x += dx;
|
||||
w->thumbh.y += dy;
|
||||
w->thumbh.x2 += dx;
|
||||
w->thumbh.y2 += dy;
|
||||
}
|
||||
|
||||
if (w->flags & WIN_RESIZE) {
|
||||
w->resize1.x += dx;
|
||||
w->resize1.y += dy;
|
||||
|
@ -636,7 +495,7 @@ void windowMove(WindowT *w, uint16_t x, uint16_t y) {
|
|||
|
||||
|
||||
static void windowPaint(struct WidgetS *widget, ...) {
|
||||
int16_t x;
|
||||
int16_t x = 0;
|
||||
int16_t y;
|
||||
int16_t px;
|
||||
int16_t py;
|
||||
|
@ -644,38 +503,22 @@ static void windowPaint(struct WidgetS *widget, ...) {
|
|||
int16_t yi;
|
||||
int16_t xc;
|
||||
int16_t yc;
|
||||
WindowT *w = (WindowT *)widget;
|
||||
SurfaceT *t = surfaceGet();
|
||||
|
||||
// Are any child widgets dirty?
|
||||
y = 0;
|
||||
for (x=0; x<arrlen(w->base.children); x++) {
|
||||
if (widgetDirtyGet(w->base.children[x])) {
|
||||
y = 1;
|
||||
if (w->base.children[x]->reg->paint) {
|
||||
surfaceSet(w->content);
|
||||
w->base.children[x]->reg->paint(w->base.children[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
surfaceSet(t);
|
||||
WindowT *w = (WindowT *)widget;
|
||||
|
||||
// Does the window itself need redrawn?
|
||||
if (widgetDirtyGet(widget)) {
|
||||
widgetDirtySet(widget, 0);
|
||||
x = 1;
|
||||
} else {
|
||||
x = 0;
|
||||
x = 1; // This is a flag for later that we need to update the cached surface.
|
||||
}
|
||||
|
||||
// Did a widget or the window need redrawn?
|
||||
if (x || y) windowCache(w, x);
|
||||
if (x || widgetChildrenDirty(widget)) windowCache(w, x);
|
||||
|
||||
// Are we minimized?
|
||||
if (w->flags & WIN_IS_ICON) {
|
||||
// Draw iconized version of contents. There are too many counters here but it's the only way it worked reliably.
|
||||
yi = (surfaceHeightGet(w->content) - 1) / ICON_SIZE;
|
||||
xi = (surfaceWidthGet(w->content) - 1) / ICON_SIZE;
|
||||
yi = (surfaceHeightGet(w->scroll->area) - 1) / ICON_SIZE;
|
||||
xi = (surfaceWidthGet(w->scroll->area) - 1) / ICON_SIZE;
|
||||
py = videoDisplayHeightGet() - ICON_SIZE;
|
||||
y = 0;
|
||||
x = 0;
|
||||
|
@ -684,7 +527,7 @@ static void windowPaint(struct WidgetS *widget, ...) {
|
|||
px = (ICON_SIZE + 1) * _iconCount;
|
||||
for (xc=0; xc<ICON_SIZE; xc++) {
|
||||
x += xi;
|
||||
surfacePixelSet(px++, py, surfacePixelGet(w->content, x, y));
|
||||
surfacePixelSet(px++, py, surfacePixelGet(w->scroll->area, x, y));
|
||||
}
|
||||
py++;
|
||||
}
|
||||
|
@ -714,6 +557,7 @@ RegisterT *windowRegister(uint8_t magic) {
|
|||
|
||||
void windowResize(WindowT *win, uint16_t width, uint16_t height) {
|
||||
|
||||
/*
|
||||
int16_t delta;
|
||||
|
||||
// Too small?
|
||||
|
@ -750,102 +594,7 @@ void windowResize(WindowT *win, uint16_t width, uint16_t height) {
|
|||
win->base.r.h =height;
|
||||
windowCache(win, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void windowScrollHorizontalHandler(EventT *e, WindowT *w) {
|
||||
|
||||
// Clicking in left arrow?
|
||||
if (e->x <= w->scrollh.x + GADGET_SIZE) {
|
||||
// Move content left.
|
||||
w->offset.x -= SCROLL_SPEED_SLOW;
|
||||
// Clip.
|
||||
if (w->offset.x < 0) w->offset.x = 0;
|
||||
// Update.
|
||||
windowCache(w, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Clicking in right arrow?
|
||||
if (e->x >= w->scrollh.x2 - GADGET_SIZE) {
|
||||
// Move content right.
|
||||
w->offset.x += SCROLL_SPEED_SLOW;
|
||||
// Clip.
|
||||
if (w->offset.x > surfaceWidthGet(w->content) - (w->bounds.x2 - w->bounds.x)) w->offset.x = surfaceWidthGet(w->content) - (w->bounds.x2 - w->bounds.x);
|
||||
// Update.
|
||||
windowCache(w, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Clicking left of thumb? Also fakes dragging.
|
||||
if (e->x < w->thumbh.x) {
|
||||
// Move content left.
|
||||
w->offset.x -= SCROLL_SPEED_FAST;
|
||||
// Clip.
|
||||
if (w->offset.x < 0) w->offset.x = 0;
|
||||
// Update.
|
||||
windowCache(w, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Clicking right of thumb? Also fakes dragging.
|
||||
if (e->x > w->thumbh.x2) {
|
||||
// Move content right.
|
||||
w->offset.x += SCROLL_SPEED_FAST;
|
||||
// Clip.
|
||||
if (w->offset.x > surfaceWidthGet(w->content) - (w->bounds.x2 - w->bounds.x)) w->offset.x = surfaceWidthGet(w->content) - (w->bounds.x2 - w->bounds.x);
|
||||
// Update.
|
||||
windowCache(w, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void windowScrollVerticalHandler(EventT *e, WindowT *w) {
|
||||
|
||||
// Clicking in up arrow?
|
||||
if (e->y <= w->scrollv.y + GADGET_SIZE) {
|
||||
// Move content up.
|
||||
w->offset.y -= SCROLL_SPEED_SLOW;
|
||||
// Clip.
|
||||
if (w->offset.y < 0) w->offset.y = 0;
|
||||
// Update.
|
||||
windowCache(w, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Clicking in down arrow?
|
||||
if (e->y >= w->scrollv.y2 - GADGET_SIZE) {
|
||||
// Move content down.
|
||||
w->offset.y += SCROLL_SPEED_SLOW;
|
||||
// Clip.
|
||||
if (w->offset.y > surfaceHeightGet(w->content) - (w->bounds.y2 - w->bounds.y)) w->offset.y = surfaceHeightGet(w->content) - (w->bounds.y2 - w->bounds.y);
|
||||
// Update.
|
||||
windowCache(w, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Clicking above thumb? Also fakes dragging.
|
||||
if (e->y < w->thumbv.y) {
|
||||
// Move content up.
|
||||
w->offset.y -= SCROLL_SPEED_FAST;
|
||||
// Clip.
|
||||
if (w->offset.y < 0) w->offset.y = 0;
|
||||
// Update.
|
||||
windowCache(w, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Clicking below thumb? Also fakes dragging.
|
||||
if (e->y > w->thumbv.y2) {
|
||||
// Move content down.
|
||||
w->offset.y += SCROLL_SPEED_FAST;
|
||||
// Clip.
|
||||
if (w->offset.y > surfaceHeightGet(w->content) - (w->bounds.y2 - w->bounds.y)) w->offset.y = surfaceHeightGet(w->content) - (w->bounds.y2 - w->bounds.y);
|
||||
// Update.
|
||||
windowCache(w, 1);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -936,7 +685,6 @@ void wmUpdate(EventT *event) {
|
|||
// Is the left mouse button down?
|
||||
if (event->buttons & BUTTON_LEFT) {
|
||||
|
||||
/*
|
||||
// DEBUG - draw active regions.
|
||||
surfaceSet(__guiBackBuffer);
|
||||
surfaceBox(win->base.r.x, win->base.r.y, x2, y2, GUI_YELLOW);
|
||||
|
@ -945,6 +693,7 @@ void wmUpdate(EventT *event) {
|
|||
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);
|
||||
surfaceBox(win->maximize.x, win->maximize.y, win->maximize.x2, win->maximize.y2, GUI_RED);
|
||||
/*
|
||||
surfaceBox(win->scrollv.x, win->scrollv.y, win->scrollv.x2, win->scrollv.y2, GUI_BLUE);
|
||||
surfaceBox(win->scrollh.x, win->scrollh.y, win->scrollh.x2, win->scrollh.y2, GUI_BROWN);
|
||||
*/
|
||||
|
@ -1013,18 +762,6 @@ void wmUpdate(EventT *event) {
|
|||
break;
|
||||
}
|
||||
|
||||
// Are we inside the vertical scroll bar? Does not include frame on purpose.
|
||||
if (win->flags & WIN_SCROLL_V &&event->x < win->scrollv.x2 && event->x > win->scrollv.x && event->y < win->scrollv.y2 && event->y > win->scrollv.y) {
|
||||
windowScrollVerticalHandler(event, win);
|
||||
break;
|
||||
}
|
||||
|
||||
// Are we inside the horizontal scroll bar? Does not include frame on purpose.
|
||||
if (win->flags & WIN_SCROLL_H &&event->x < win->scrollh.x2 && event->x > win->scrollh.x && event->y < win->scrollh.y2 && event->y > win->scrollh.y) {
|
||||
windowScrollHorizontalHandler(event, win);
|
||||
break;
|
||||
}
|
||||
|
||||
} else { // On topmost window.
|
||||
|
||||
// Not over topmost window. Search backwards to find first window we're inside.
|
||||
|
@ -1081,17 +818,7 @@ void wmUpdate(EventT *event) {
|
|||
|
||||
} else { // Button just went down / button being held down.
|
||||
|
||||
// Are we inside the vertical scroll bar? Does not include frame on purpose.
|
||||
if (win->flags & WIN_SCROLL_V &&event->x < win->scrollv.x2 && event->x > win->scrollv.x && event->y < win->scrollv.y2 && event->y > win->scrollv.y) {
|
||||
windowScrollVerticalHandler(event, win);
|
||||
break;
|
||||
}
|
||||
|
||||
// Are we inside the horizontal scroll bar? Does not include frame on purpose.
|
||||
if (win->flags & WIN_SCROLL_H &&event->x < win->scrollh.x2 && event->x > win->scrollh.x && event->y < win->scrollh.y2 && event->y > win->scrollh.y) {
|
||||
windowScrollHorizontalHandler(event, win);
|
||||
break;
|
||||
}
|
||||
// Nada
|
||||
|
||||
} // Left button held down.
|
||||
|
||||
|
@ -1138,6 +865,7 @@ static WidgetT *wuWidgetUnderMouseGet(WindowT *win, EventT *event, int16_t *loca
|
|||
int16_t i;
|
||||
WidgetT *widget;
|
||||
|
||||
/*
|
||||
// Are we over the provided window?
|
||||
if (event->x <= win->bounds.x2 && event->x >= win->bounds.x && event->y <= win->bounds.y2 && event->y >= win->bounds.y) {
|
||||
// Find window-local mouse coordinates.
|
||||
|
@ -1152,6 +880,7 @@ static WidgetT *wuWidgetUnderMouseGet(WindowT *win, EventT *event, int16_t *loca
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -29,11 +29,11 @@
|
|||
|
||||
#include "gui.h"
|
||||
|
||||
#include "widgets/scroll.h"
|
||||
|
||||
|
||||
#define ICON_SIZE 32
|
||||
#define GADGET_SIZE 20
|
||||
#define SCROLL_SPEED_SLOW 5 // ***TODO*** Move into GUI after we get scrollbar widgets.
|
||||
#define SCROLL_SPEED_FAST 25
|
||||
|
||||
|
||||
#define WIN_NONE 0
|
||||
|
@ -50,25 +50,28 @@
|
|||
|
||||
|
||||
typedef struct WindowS {
|
||||
WidgetT base; // Required by all widgets.
|
||||
char *title; // Title of window.
|
||||
uint8_t flags; // Window flags (see defines above).
|
||||
RectT close; // Coordinates of close box, if any.
|
||||
RectT titlebar; // Coordinates of title bar, if any.
|
||||
RectT minimize; // Coordinates of minimize box, if any.
|
||||
RectT maximize; // Coordinates of maximize box, if any.
|
||||
RectT resize1; // First resize area.
|
||||
RectT resize2; // Second resize area.
|
||||
RectT scrollv; // Vertical scroll bar.
|
||||
RectT scrollh; // Horizontal scroll bar.
|
||||
RectT thumbv; // Vertical scroll bar thumb.
|
||||
RectT thumbh; // Horizontal scroll bar thumb.
|
||||
RectT bounds; // Inside edge of window frame.
|
||||
RectT restore; // Size of window if they restore from maximized.
|
||||
PointT restoreOffset; // Scroll position if they restore from maximized.
|
||||
PointT offset; // Content scroll offset in window.
|
||||
SurfaceT *content; // Actual window contents - widgets and such.
|
||||
SurfaceT *cached; // Once rendered, keep a cached copy for faster redrawing.
|
||||
WidgetT base; // Required by all widgets.
|
||||
char *title; // Title of window.
|
||||
uint8_t flags; // Window flags (see defines above).
|
||||
RectT close; // Coordinates of close box, if any.
|
||||
RectT titlebar; // Coordinates of title bar, if any.
|
||||
RectT minimize; // Coordinates of minimize box, if any.
|
||||
RectT maximize; // Coordinates of maximize box, if any.
|
||||
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.
|
||||
PointT restoreOffset; // Scroll position if they restore from maximized.
|
||||
RectT bounds; // Inside edge of window frame.
|
||||
/*
|
||||
RectT scrollv; // Vertical scroll bar.
|
||||
RectT scrollh; // Horizontal scroll bar.
|
||||
RectT thumbv; // Vertical scroll bar thumb.
|
||||
RectT thumbh; // Horizontal scroll bar thumb.
|
||||
PointT offset; // Content scroll offset in window.
|
||||
SurfaceT *content; // Actual window contents - widgets and such.
|
||||
*/
|
||||
SurfaceT *cached; // Once rendered, keep a cached copy for faster redrawing.
|
||||
} WindowT;
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue