More resize fixes.
This commit is contained in:
parent
74d4e05af9
commit
9433a63c1f
4 changed files with 118 additions and 35 deletions
|
@ -48,6 +48,7 @@ static void scrollableClickHandler(WidgetT *widget, uint16_t x, uint16_t y, uint
|
||||||
|
|
||||||
s->offset.x = hscrollValueGet(s->scrollh);
|
s->offset.x = hscrollValueGet(s->scrollh);
|
||||||
s->offset.y = vscrollValueGet(s->scrollv);
|
s->offset.y = vscrollValueGet(s->scrollv);
|
||||||
|
widgetDirtySet(W(s), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,7 +87,7 @@ ScrollableT *scrollableCreate(int16_t width, int16_t height, int16_t totalWidth,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
surfaceSet(s->area);
|
surfaceSet(s->area);
|
||||||
surfaceClear(GUI_LIGHTBLUE);
|
surfaceClear(GUI_LIGHTGRAY);
|
||||||
surfaceSet(t);
|
surfaceSet(t);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
@ -159,6 +160,7 @@ static void scrollablePaint(struct WidgetS *widget, ...) {
|
||||||
|
|
||||||
if (widgetDirtyGet(widget)) {
|
if (widgetDirtyGet(widget)) {
|
||||||
widgetDirtySet(widget, 0);
|
widgetDirtySet(widget, 0);
|
||||||
|
|
||||||
// Finish initializing?
|
// Finish initializing?
|
||||||
if (s->flags & SCROLLABLE_NOT_SETUP) {
|
if (s->flags & SCROLLABLE_NOT_SETUP) {
|
||||||
s->flags &= ~SCROLLABLE_NOT_SETUP;
|
s->flags &= ~SCROLLABLE_NOT_SETUP;
|
||||||
|
@ -172,17 +174,32 @@ static void scrollablePaint(struct WidgetS *widget, ...) {
|
||||||
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->sizes.x, s->base.r.y, W(s->scrollv));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Before painting contents, we need to offset everything by the window borders.
|
|
||||||
|
// Move the contents to 0,0 to draw it into it's own surface.
|
||||||
o.x = s->base.r.x;
|
o.x = s->base.r.x;
|
||||||
o.y = s->base.r.y;
|
o.y = s->base.r.y;
|
||||||
s->base.r.x = 0;
|
s->base.r.x = 0;
|
||||||
s->base.r.y = 0;
|
s->base.r.y = 0;
|
||||||
|
|
||||||
|
// Draw children onto surface.
|
||||||
surfaceSet(s->area);
|
surfaceSet(s->area);
|
||||||
widgetChildrenPaint(widget);
|
widgetChildrenPaint(widget);
|
||||||
surfaceSet(t);
|
surfaceSet(t);
|
||||||
|
|
||||||
|
// Put us back at the proper coodinates.
|
||||||
s->base.r.x = o.x;
|
s->base.r.x = o.x;
|
||||||
s->base.r.y = o.y;
|
s->base.r.y = o.y;
|
||||||
|
|
||||||
// Blit.
|
// 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,
|
||||||
|
s->offset.x, s->offset.y,
|
||||||
|
s->sizes.x, s->sizes.y,
|
||||||
|
surfaceWidthGet(s->area), surfaceHeightGet(s->area),
|
||||||
|
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->sizes.x, s->sizes.y, s->area);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,6 +221,30 @@ RegisterT *scrollableRegister(uint8_t magic) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t scrollableValueHGet(ScrollableT *scroll) {
|
||||||
|
return hscrollValueGet(scroll->scrollh);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void scrollableValueHSet(ScrollableT *scroll, int32_t value) {
|
||||||
|
hscrollValueSet(scroll->scrollh, value);
|
||||||
|
scroll->offset.x = hscrollValueGet(scroll->scrollh);
|
||||||
|
widgetDirtySet(W(scroll), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t scrollableValueVGet(ScrollableT *scroll) {
|
||||||
|
return vscrollValueGet(scroll->scrollv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void scrollableValueVSet(ScrollableT *scroll, int32_t value) {
|
||||||
|
vscrollValueSet(scroll->scrollv, value);
|
||||||
|
scroll->offset.y = vscrollValueGet(scroll->scrollv);
|
||||||
|
widgetDirtySet(W(scroll), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void scrollableWidthSet(ScrollableT *scroll, int16_t w) {
|
void scrollableWidthSet(ScrollableT *scroll, int16_t w) {
|
||||||
scroll->original.x = w;
|
scroll->original.x = w;
|
||||||
scrollableFixupSizes(scroll);
|
scrollableFixupSizes(scroll);
|
||||||
|
|
|
@ -59,6 +59,10 @@ ScrollableT *scrollableCreate(int16_t width, int16_t height, int16_t totalWidth,
|
||||||
void scrollableHeightSet(ScrollableT *scroll, int16_t h);
|
void scrollableHeightSet(ScrollableT *scroll, int16_t h);
|
||||||
RegisterT *scrollableRegister(uint8_t magic);
|
RegisterT *scrollableRegister(uint8_t magic);
|
||||||
void scrollableWidthSet(ScrollableT *scroll, int16_t w);
|
void scrollableWidthSet(ScrollableT *scroll, int16_t w);
|
||||||
|
int32_t scrollableValueHGet(ScrollableT *scroll);
|
||||||
|
void scrollableValueHSet(ScrollableT *scroll, int32_t value);
|
||||||
|
int32_t scrollableValueVGet(ScrollableT *scroll);
|
||||||
|
void scrollableValueVSet(ScrollableT *scroll, int32_t value);
|
||||||
|
|
||||||
|
|
||||||
#endif // SCROLL_H
|
#endif // SCROLL_H
|
||||||
|
|
|
@ -60,6 +60,7 @@ static void vscrollClick(WidgetT *widget, uint16_t x, uint16_t y, uint8_t event,
|
||||||
// Move content down.
|
// Move content down.
|
||||||
v->value += SCROLL_SPEED_SLOW;
|
v->value += SCROLL_SPEED_SLOW;
|
||||||
// Clip.
|
// 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->max - v->base.r.h) v->value = v->max - v->base.r.h;
|
||||||
// Update.
|
// Update.
|
||||||
widgetDirtySet(widget, 1);
|
widgetDirtySet(widget, 1);
|
||||||
|
|
|
@ -59,12 +59,6 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
||||||
ColorT gadgetColor;
|
ColorT gadgetColor;
|
||||||
SurfaceT *target = surfaceGet();
|
SurfaceT *target = surfaceGet();
|
||||||
|
|
||||||
// Move the window to 0,0 to draw it into it's own surface.
|
|
||||||
originalX = w->base.r.x;
|
|
||||||
originalY = w->base.r.y;
|
|
||||||
w->base.r.x = 0;
|
|
||||||
w->base.r.y = 0;
|
|
||||||
|
|
||||||
// Do we have a cached surface already?
|
// Do we have a cached surface already?
|
||||||
if (w->cached) {
|
if (w->cached) {
|
||||||
// Did the size change?
|
// Did the size change?
|
||||||
|
@ -81,7 +75,14 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
||||||
// Draw into cache.
|
// Draw into cache.
|
||||||
surfaceSet(w->cached);
|
surfaceSet(w->cached);
|
||||||
|
|
||||||
|
// Does the window itself need redrawn or just the contents?
|
||||||
if (redrawWindow) {
|
if (redrawWindow) {
|
||||||
|
// Move the window to 0,0 to draw it into it's own surface.
|
||||||
|
originalX = w->base.r.x;
|
||||||
|
originalY = w->base.r.y;
|
||||||
|
w->base.r.x = 0;
|
||||||
|
w->base.r.y = 0;
|
||||||
|
|
||||||
// Determine some colors.
|
// Determine some colors.
|
||||||
titleBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY;
|
titleBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY;
|
||||||
gadgetColor = (w == _windowTop) ? GUI_LIGHTGRAY : GUI_DARKGRAY;
|
gadgetColor = (w == _windowTop) ? GUI_LIGHTGRAY : GUI_DARKGRAY;
|
||||||
|
@ -220,12 +221,13 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
||||||
scrollableWidthSet(w->scroll, x2 - x1);
|
scrollableWidthSet(w->scroll, x2 - x1);
|
||||||
scrollableHeightSet(w->scroll, y2 - y1);
|
scrollableHeightSet(w->scroll, y2 - y1);
|
||||||
}
|
}
|
||||||
} // Redraw window.
|
|
||||||
|
|
||||||
widgetChildrenPaint(W(w));
|
|
||||||
|
|
||||||
// Fixup all the widget coordinates.
|
// Fixup all the widget coordinates.
|
||||||
windowMove(w, originalX, originalY);
|
windowMove(w, originalX, originalY);
|
||||||
|
} // Redraw window.
|
||||||
|
|
||||||
|
// Draw contents.
|
||||||
|
widgetChildrenPaint(W(w));
|
||||||
|
|
||||||
surfaceSet(target);
|
surfaceSet(target);
|
||||||
}
|
}
|
||||||
|
@ -557,38 +559,61 @@ void windowResize(WindowT *win, uint16_t width, uint16_t height) {
|
||||||
int16_t delta;
|
int16_t delta;
|
||||||
int16_t x = 0;
|
int16_t x = 0;
|
||||||
int16_t y = 0;
|
int16_t y = 0;
|
||||||
int16_t w = 0;
|
int16_t content = 0;
|
||||||
|
int16_t change = 0;
|
||||||
|
|
||||||
// Too small?
|
// Too small?
|
||||||
if (width < (GADGET_SIZE * 4) + 15) width = (GADGET_SIZE * 4) + 15;
|
if (width < (GADGET_SIZE * 4) + 15) width = (GADGET_SIZE * 4) + 15;
|
||||||
if (height < (GADGET_SIZE * 4) + 15) height = (GADGET_SIZE * 4) + 15;
|
if (height < (GADGET_SIZE * 4) + 15) height = (GADGET_SIZE * 4) + 15;
|
||||||
|
|
||||||
// Too big?
|
// Too big? Horizontal.
|
||||||
|
// Get the current view offset.
|
||||||
|
x = scrollableValueHGet(win->scroll);
|
||||||
|
// Width of content area of window.
|
||||||
|
content = win->bounds.x2 - win->bounds.x;
|
||||||
if (win->scroll->scrollh) {
|
if (win->scroll->scrollh) {
|
||||||
x = hscrollValueGet(win->scroll->scrollh);
|
// Do we need to take the width of the vertical scroll bar into account?
|
||||||
if (win->scroll->scrollv) w = win->scroll->scrollv->base.r.w;
|
if (win->scroll->scrollv) content -= win->scroll->scrollv->base.r.w;
|
||||||
if (win->bounds.w - win->bounds.x + (width - win->base.r.w) + x > surfaceWidthGet(win->scroll->area) + w) {
|
// Change in width.
|
||||||
|
change = width - win->base.r.w;
|
||||||
|
// If the new width is going to render content past the right edge of the area, we need to scroll the area.
|
||||||
|
if (content + change + x > surfaceWidthGet(win->scroll->area)) {
|
||||||
// Do we have room to scroll content into view?
|
// Do we have room to scroll content into view?
|
||||||
if (x > 0) {
|
if (x > 0) {
|
||||||
delta = width - win->base.r.w;
|
delta = width - win->base.r.w;
|
||||||
if (delta > x) delta = x;
|
if (delta > x) delta = x;
|
||||||
hscrollValueSet(win->scroll->scrollh, x - delta);
|
scrollableValueHSet(win->scroll, x - delta);
|
||||||
}
|
}
|
||||||
width = (win->base.r.w - (win->bounds.x2 - win->bounds.x) - x + surfaceWidthGet(win->scroll->area) + w);
|
width = (win->base.r.w - content - x + surfaceWidthGet(win->scroll->area));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 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;
|
||||||
if (win->scroll->scrollv) {
|
if (win->scroll->scrollv) {
|
||||||
y = vscrollValueGet(win->scroll->scrollv);
|
// Do we need to take the height of the horizontal scroll bar into account?
|
||||||
if (win->bounds.h - win->bounds.y + (height - win->base.r.h) + y > surfaceHeightGet(win->scroll->area)) {
|
if (win->scroll->scrollh) content -= win->scroll->scrollh->base.r.h;
|
||||||
|
// Change in height.
|
||||||
|
change = height - win->base.r.h;
|
||||||
|
if (content + change + y > surfaceHeightGet(win->scroll->area)) {
|
||||||
// Do we have room to scroll content into view?
|
// Do we have room to scroll content into view?
|
||||||
if (y > 0) {
|
if (y > 0) {
|
||||||
delta = height - win->base.r.h;
|
delta = height - win->base.r.h;
|
||||||
if (delta > y) delta = y;
|
if (delta > y) delta = y;
|
||||||
vscrollValueSet(win->scroll->scrollv, y - delta);
|
scrollableValueVSet(win->scroll, y - delta);
|
||||||
}
|
}
|
||||||
height = (win->base.r.h - (win->bounds.y2 - win->bounds.y) - y + surfaceHeightGet(win->scroll->area));
|
height = (win->base.r.h - content - y + surfaceHeightGet(win->scroll->area));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Clamp.
|
||||||
|
y = win->base.r.h - content + surfaceHeightGet(win->scroll->area);
|
||||||
|
if (height > y) height = y;
|
||||||
|
|
||||||
// Did the size change?
|
// Did the size change?
|
||||||
if (win->base.r.w != width || win->base.r.h !=height) {
|
if (win->base.r.w != width || win->base.r.h !=height) {
|
||||||
|
@ -598,7 +623,7 @@ void windowResize(WindowT *win, uint16_t width, uint16_t height) {
|
||||||
// Do resize.
|
// Do resize.
|
||||||
win->base.r.w = width;
|
win->base.r.w = width;
|
||||||
win->base.r.h =height;
|
win->base.r.h =height;
|
||||||
windowCache(win, 1);
|
widgetDirtySet(W(win), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,23 +676,25 @@ void wmUpdate(EventT *event) {
|
||||||
// Get top window.
|
// Get top window.
|
||||||
win = _windowTop;
|
win = _windowTop;
|
||||||
|
|
||||||
// If we found a window, get right/bottom.
|
// If we found a window, get right/bottom and widget.
|
||||||
if (win) {
|
if (win) {
|
||||||
|
// Find window outer bounds.
|
||||||
x2 = win->base.r.x + win->base.r.w - 1;
|
x2 = win->base.r.x + win->base.r.w - 1;
|
||||||
y2 = win->base.r.y + win->base.r.h - 1;
|
y2 = win->base.r.y + win->base.r.h - 1;
|
||||||
|
// Are we over a widget?
|
||||||
|
widgetOver = wuWidgetUnderMouseGet(win, event, &windowLocalX, &windowLocalY);
|
||||||
} else {
|
} else {
|
||||||
x2 = 0;
|
x2 = 0;
|
||||||
y2 = 0;
|
y2 = 0;
|
||||||
|
widgetOver = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we over a widget?
|
|
||||||
widgetOver = wuWidgetUnderMouseGet(win, event, &windowLocalX, &windowLocalY);
|
|
||||||
|
|
||||||
// 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 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 && (widgetOver->flags & WIDGET_RAW_INPUT) && (event->buttons != 0)) {
|
if (widgetOver && !widgetDown && !dragging && (widgetOver->flags & WIDGET_RAW_INPUT) && (event->buttons != 0)) {
|
||||||
if (widgetOver->reg->click) {
|
if (widgetOver->reg->click) {
|
||||||
rawEvent.event = event;
|
rawEvent.event = event;
|
||||||
rawEvent.data = widget->data;
|
rawEvent.data = widget->data;
|
||||||
|
//logWrite("Firing raw click for %s\n", widgetOver->reg->widgetName);
|
||||||
widgetOver->reg->click(widgetOver, windowLocalX - widgetOver->r.x, windowLocalY - widgetOver->r.y, CLICK_RAW_INPUT, &rawEvent);
|
widgetOver->reg->click(widgetOver, windowLocalX - widgetOver->r.x, windowLocalY - widgetOver->r.y, CLICK_RAW_INPUT, &rawEvent);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -868,24 +895,34 @@ void wmUpdate(EventT *event) {
|
||||||
|
|
||||||
static WidgetT *wuWidgetUnderMouseGet(WindowT *win, EventT *event, int16_t *localX, int16_t *localY) {
|
static WidgetT *wuWidgetUnderMouseGet(WindowT *win, EventT *event, int16_t *localX, int16_t *localY) {
|
||||||
int16_t i;
|
int16_t i;
|
||||||
|
int16_t x2;
|
||||||
|
int16_t y2;
|
||||||
|
PointT offset;
|
||||||
WidgetT *widget;
|
WidgetT *widget;
|
||||||
|
|
||||||
/*
|
// If we have scrollbars, get the offset for the view.
|
||||||
|
if (win->scroll->scrollh) offset.x = hscrollValueGet(win->scroll->scrollh);
|
||||||
|
if (win->scroll->scrollv) offset.y = vscrollValueGet(win->scroll->scrollv);
|
||||||
|
|
||||||
|
// Find window bounds.
|
||||||
|
x2 = win->base.r.x + win->base.r.w - 1;
|
||||||
|
y2 = win->base.r.y + win->base.r.h - 1;
|
||||||
|
|
||||||
// Are we over the provided window?
|
// 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) {
|
if (event->x <= x2 && event->x >= win->base.r.x && event->y <= y2 && event->y >= win->base.r.y) {
|
||||||
// Find window-local mouse coordinates.
|
// Find window-local mouse coordinates.
|
||||||
*localX = event->x - win->bounds.x + win->offset.x;
|
*localX = event->x - win->base.r.x;// + offset.x;
|
||||||
*localY = event->y - win->bounds.y + win->offset.y;
|
*localY = event->y - win->base.r.y;// + offset.y;
|
||||||
// Find widget under mouse.
|
// Find widget under mouse.
|
||||||
for (i=0; i<arrlen(win->base.children); i++) {
|
for (i=0; i<arrlen(win->base.children); i++) {
|
||||||
widget = win->base.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.x2 && *localY >= widget->r.y && *localY < widget->r.y + widget->r.y2) {
|
||||||
|
//logWrite("Over %s\n", widget->reg->widgetName);
|
||||||
// Return this widget.
|
// Return this widget.
|
||||||
return widget;
|
return widget;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue