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.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;
|
||||
}
|
||||
surfaceSet(s->area);
|
||||
surfaceClear(GUI_LIGHTBLUE);
|
||||
surfaceClear(GUI_LIGHTGRAY);
|
||||
surfaceSet(t);
|
||||
|
||||
return s;
|
||||
|
@ -159,6 +160,7 @@ static void scrollablePaint(struct WidgetS *widget, ...) {
|
|||
|
||||
if (widgetDirtyGet(widget)) {
|
||||
widgetDirtySet(widget, 0);
|
||||
|
||||
// Finish initializing?
|
||||
if (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));
|
||||
}
|
||||
}
|
||||
// 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.y = s->base.r.y;
|
||||
s->base.r.x = 0;
|
||||
s->base.r.y = 0;
|
||||
|
||||
// Draw children onto surface.
|
||||
surfaceSet(s->area);
|
||||
widgetChildrenPaint(widget);
|
||||
surfaceSet(t);
|
||||
|
||||
// Put us back at the proper coodinates.
|
||||
s->base.r.x = o.x;
|
||||
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,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
scroll->original.x = w;
|
||||
scrollableFixupSizes(scroll);
|
||||
|
|
|
@ -59,6 +59,10 @@ ScrollableT *scrollableCreate(int16_t width, int16_t height, int16_t totalWidth,
|
|||
void scrollableHeightSet(ScrollableT *scroll, int16_t h);
|
||||
RegisterT *scrollableRegister(uint8_t magic);
|
||||
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
|
||||
|
|
|
@ -60,6 +60,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;
|
||||
// Update.
|
||||
widgetDirtySet(widget, 1);
|
||||
|
|
|
@ -59,12 +59,6 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
ColorT gadgetColor;
|
||||
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?
|
||||
if (w->cached) {
|
||||
// Did the size change?
|
||||
|
@ -81,7 +75,14 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
// Draw into cache.
|
||||
surfaceSet(w->cached);
|
||||
|
||||
// Does the window itself need redrawn or just the contents?
|
||||
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.
|
||||
titleBackgroundColor = (w == _windowTop) ? GUI_DARKGRAY : GUI_LIGHTGRAY;
|
||||
gadgetColor = (w == _windowTop) ? GUI_LIGHTGRAY : GUI_DARKGRAY;
|
||||
|
@ -220,13 +221,14 @@ static void windowCache(WindowT *w, uint8_t redrawWindow) {
|
|||
scrollableWidthSet(w->scroll, x2 - x1);
|
||||
scrollableHeightSet(w->scroll, y2 - y1);
|
||||
}
|
||||
|
||||
// Fixup all the widget coordinates.
|
||||
windowMove(w, originalX, originalY);
|
||||
} // Redraw window.
|
||||
|
||||
// Draw contents.
|
||||
widgetChildrenPaint(W(w));
|
||||
|
||||
// Fixup all the widget coordinates.
|
||||
windowMove(w, originalX, originalY);
|
||||
|
||||
surfaceSet(target);
|
||||
}
|
||||
|
||||
|
@ -555,40 +557,63 @@ RegisterT *windowRegister(uint8_t magic) {
|
|||
void windowResize(WindowT *win, uint16_t width, uint16_t height) {
|
||||
|
||||
int16_t delta;
|
||||
int16_t x = 0;
|
||||
int16_t y = 0;
|
||||
int16_t w = 0;
|
||||
int16_t x = 0;
|
||||
int16_t y = 0;
|
||||
int16_t content = 0;
|
||||
int16_t change = 0;
|
||||
|
||||
// Too small?
|
||||
if (width < (GADGET_SIZE * 4) + 15) width = (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) {
|
||||
x = hscrollValueGet(win->scroll->scrollh);
|
||||
if (win->scroll->scrollv) w = win->scroll->scrollv->base.r.w;
|
||||
if (win->bounds.w - win->bounds.x + (width - win->base.r.w) + x > surfaceWidthGet(win->scroll->area) + w) {
|
||||
// Do we need to take the width of the vertical scroll bar into account?
|
||||
if (win->scroll->scrollv) content -= win->scroll->scrollv->base.r.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?
|
||||
if (x > 0) {
|
||||
delta = width - win->base.r.w;
|
||||
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) {
|
||||
y = vscrollValueGet(win->scroll->scrollv);
|
||||
if (win->bounds.h - win->bounds.y + (height - win->base.r.h) + y > surfaceHeightGet(win->scroll->area)) {
|
||||
// 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;
|
||||
if (content + change + y > surfaceHeightGet(win->scroll->area)) {
|
||||
// Do we have room to scroll content into view?
|
||||
if (y > 0) {
|
||||
delta = height - win->base.r.h;
|
||||
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?
|
||||
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.
|
||||
win->base.r.w = width;
|
||||
win->base.r.h =height;
|
||||
windowCache(win, 1);
|
||||
widgetDirtySet(W(win), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -651,23 +676,25 @@ void wmUpdate(EventT *event) {
|
|||
// Get top window.
|
||||
win = _windowTop;
|
||||
|
||||
// If we found a window, get right/bottom.
|
||||
// If we found a window, get right/bottom and widget.
|
||||
if (win) {
|
||||
// Find window outer bounds.
|
||||
x2 = win->base.r.x + win->base.r.w - 1;
|
||||
y2 = win->base.r.y + win->base.r.h - 1;
|
||||
// Are we over a widget?
|
||||
widgetOver = wuWidgetUnderMouseGet(win, event, &windowLocalX, &windowLocalY);
|
||||
} else {
|
||||
x2 = 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 (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) {
|
||||
rawEvent.event = event;
|
||||
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);
|
||||
}
|
||||
return;
|
||||
|
@ -868,24 +895,34 @@ void wmUpdate(EventT *event) {
|
|||
|
||||
static WidgetT *wuWidgetUnderMouseGet(WindowT *win, EventT *event, int16_t *localX, int16_t *localY) {
|
||||
int16_t i;
|
||||
int16_t x2;
|
||||
int16_t y2;
|
||||
PointT offset;
|
||||
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?
|
||||
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.
|
||||
*localX = event->x - win->bounds.x + win->offset.x;
|
||||
*localY = event->y - win->bounds.y + win->offset.y;
|
||||
*localX = event->x - win->base.r.x;// + offset.x;
|
||||
*localY = event->y - win->base.r.y;// + offset.y;
|
||||
// Find widget under mouse.
|
||||
for (i=0; i<arrlen(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) {
|
||||
//logWrite("Over %s\n", widget->reg->widgetName);
|
||||
// Return this widget.
|
||||
return widget;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue