summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/app.c6
-rw-r--r--src/ui/inputwidget.c11
-rw-r--r--src/ui/listwidget.c1
-rw-r--r--src/ui/mobile.c33
-rw-r--r--src/ui/paint.c25
-rw-r--r--src/ui/root.c4
-rw-r--r--src/ui/touch.c7
-rw-r--r--src/ui/util.c9
-rw-r--r--src/ui/widget.c75
-rw-r--r--src/ui/widget.h1
-rw-r--r--src/ui/window.c11
11 files changed, 158 insertions, 25 deletions
diff --git a/src/app.c b/src/app.c
index e597edbe..fa601ac3 100644
--- a/src/app.c
+++ b/src/app.c
@@ -1273,6 +1273,7 @@ void processEvents_App(enum iAppEventMode eventMode) {
1273 } 1273 }
1274 } 1274 }
1275#endif 1275#endif
1276 const iWidget *oldHover = d->window->hover;
1276 iBool wasUsed = processEvent_Window(d->window, &ev); 1277 iBool wasUsed = processEvent_Window(d->window, &ev);
1277 if (!wasUsed) { 1278 if (!wasUsed) {
1278 /* There may be a key bindings for this. */ 1279 /* There may be a key bindings for this. */
@@ -1307,6 +1308,11 @@ void processEvents_App(enum iAppEventMode eventMode) {
1307 /* Allocated by postCommand_Apps(). */ 1308 /* Allocated by postCommand_Apps(). */
1308 free(ev.user.data1); 1309 free(ev.user.data1);
1309 } 1310 }
1311 /* Update when hover has changed. */
1312 if (oldHover != d->window->hover) {
1313 refresh_Widget(oldHover);
1314 refresh_Widget(d->window->hover);
1315 }
1310 break; 1316 break;
1311 } 1317 }
1312 } 1318 }
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c
index 802a2d6c..59d62544 100644
--- a/src/ui/inputwidget.c
+++ b/src/ui/inputwidget.c
@@ -27,6 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
27#include "keys.h" 27#include "keys.h"
28#include "prefs.h" 28#include "prefs.h"
29#include "lang.h" 29#include "lang.h"
30#include "touch.h"
30#include "app.h" 31#include "app.h"
31 32
32#include <the_Foundation/array.h> 33#include <the_Foundation/array.h>
@@ -1565,11 +1566,11 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
1565 } 1566 }
1566 switch (processEvent_Click(&d->click, ev)) { 1567 switch (processEvent_Click(&d->click, ev)) {
1567 case none_ClickResult: 1568 case none_ClickResult:
1568 if (ev->type == SDL_MOUSEBUTTONUP && 1569// if (ev->type == SDL_MOUSEBUTTONUP &&
1569 deviceType_App() != desktop_AppDeviceType && isFocused_Widget(d)) { 1570// deviceType_App() != desktop_AppDeviceType && isFocused_Widget(d)) {
1570 setFocus_Widget(NULL); 1571// setFocus_Widget(NULL);
1571 return iTrue; 1572// return iTrue;
1572 } 1573// }
1573 break; 1574 break;
1574 case started_ClickResult: { 1575 case started_ClickResult: {
1575 setFocus_Widget(w); 1576 setFocus_Widget(w);
diff --git a/src/ui/listwidget.c b/src/ui/listwidget.c
index 46d32e9a..6fa23986 100644
--- a/src/ui/listwidget.c
+++ b/src/ui/listwidget.c
@@ -391,6 +391,7 @@ static void draw_ListWidget_(const iListWidget *d) {
391 const int scrollY = pos_SmoothScroll(&d->scrollY); 391 const int scrollY = pos_SmoothScroll(&d->scrollY);
392 iPaint p; 392 iPaint p;
393 init_Paint(&p); 393 init_Paint(&p);
394 drawLayerEffects_Widget(w);
394 drawBackground_Widget(w); 395 drawBackground_Widget(w);
395 alloc_VisBuf(d->visBuf, bounds.size, d->itemHeight); 396 alloc_VisBuf(d->visBuf, bounds.size, d->itemHeight);
396 /* Update invalid regions/items. */ { 397 /* Update invalid regions/items. */ {
diff --git a/src/ui/mobile.c b/src/ui/mobile.c
index 9e2dc4f7..4c183ffa 100644
--- a/src/ui/mobile.c
+++ b/src/ui/mobile.c
@@ -129,6 +129,12 @@ static iBool mainDetailSplitHandler_(iWidget *mainDetailSplit, const char *cmd)
129 } 129 }
130 arrange_Widget(mainDetailSplit); 130 arrange_Widget(mainDetailSplit);
131 } 131 }
132 else if (equal_Command(cmd, "mouse.clicked") && arg_Command(cmd)) {
133 if (focus_Widget() && class_Widget(focus_Widget()) == &Class_InputWidget) {
134 setFocus_Widget(NULL);
135 return iTrue;
136 }
137 }
132 return iFalse; 138 return iFalse;
133} 139}
134 140
@@ -331,7 +337,7 @@ static iWidget *makeValuePaddingWithHeading_(iLabelWidget *heading, iWidget *val
331 //setFixedSize_Widget(as_Widget(heading), init_I2(-1, height_Widget(value))); 337 //setFixedSize_Widget(as_Widget(heading), init_I2(-1, height_Widget(value)));
332 setFont_LabelWidget(heading, labelFont_()); 338 setFont_LabelWidget(heading, labelFont_());
333 setTextColor_LabelWidget(heading, uiTextStrong_ColorId); 339 setTextColor_LabelWidget(heading, uiTextStrong_ColorId);
334 if (isInput) { 340 if (isInput && ~value->flags & fixedWidth_WidgetFlag) {
335 addChildFlags_Widget(div, iClob(value), expand_WidgetFlag); 341 addChildFlags_Widget(div, iClob(value), expand_WidgetFlag);
336 } 342 }
337 else if (isInstance_Object(value, &Class_LabelWidget) && 343 else if (isInstance_Object(value, &Class_LabelWidget) &&
@@ -388,6 +394,27 @@ static size_t countItems_(const iMenuItem *itemsNullTerminated) {
388 return num; 394 return num;
389} 395}
390 396
397static iBool dropdownHeadingHandler_(iWidget *d, const char *cmd) {
398 if (isVisible_Widget(d) &&
399 equal_Command(cmd, "mouse.clicked") && contains_Widget(d, coord_Command(cmd)) &&
400 arg_Command(cmd)) {
401 postCommand_Widget(userData_Object(d),
402 cstr_String(command_LabelWidget(userData_Object(d))));
403 return iTrue;
404 }
405 return iFalse;
406}
407
408static iBool inputHeadingHandler_(iWidget *d, const char *cmd) {
409 if (isVisible_Widget(d) &&
410 equal_Command(cmd, "mouse.clicked") && contains_Widget(d, coord_Command(cmd)) &&
411 arg_Command(cmd)) {
412 setFocus_Widget(userData_Object(d));
413 return iTrue;
414 }
415 return iFalse;
416}
417
391void makePanelItem_Mobile(iWidget *panel, const iMenuItem *item) { 418void makePanelItem_Mobile(iWidget *panel, const iMenuItem *item) {
392 iWidget * widget = NULL; 419 iWidget * widget = NULL;
393 iLabelWidget *heading = NULL; 420 iLabelWidget *heading = NULL;
@@ -434,6 +461,8 @@ void makePanelItem_Mobile(iWidget *panel, const iMenuItem *item) {
434 frameless_WidgetFlag, iTrue); 461 frameless_WidgetFlag, iTrue);
435 setId_Widget(as_Widget(drop), id); 462 setId_Widget(as_Widget(drop), id);
436 widget = makeValuePaddingWithHeading_(heading = makeHeading_Widget(label), as_Widget(drop)); 463 widget = makeValuePaddingWithHeading_(heading = makeHeading_Widget(label), as_Widget(drop));
464 setCommandHandler_Widget(widget, dropdownHeadingHandler_);
465 setUserData_Object(widget, drop);
437 } 466 }
438 else if (equal_Command(spec, "radio") || equal_Command(spec, "buttons")) { 467 else if (equal_Command(spec, "radio") || equal_Command(spec, "buttons")) {
439 const iBool isRadio = equal_Command(spec, "radio"); 468 const iBool isRadio = equal_Command(spec, "radio");
@@ -504,6 +533,8 @@ void makePanelItem_Mobile(iWidget *panel, const iMenuItem *item) {
504 } 533 }
505 widget = makeValuePaddingWithHeading_(heading = makeHeading_Widget(label), 534 widget = makeValuePaddingWithHeading_(heading = makeHeading_Widget(label),
506 as_Widget(input)); 535 as_Widget(input));
536 setCommandHandler_Widget(widget, inputHeadingHandler_);
537 setUserData_Object(widget, input);
507 } 538 }
508 } 539 }
509 else if (equal_Command(spec, "button")) { 540 else if (equal_Command(spec, "button")) {
diff --git a/src/ui/paint.c b/src/ui/paint.c
index af62f908..71ebb81d 100644
--- a/src/ui/paint.c
+++ b/src/ui/paint.c
@@ -65,10 +65,33 @@ void endTarget_Paint(iPaint *d) {
65 65
66void setClip_Paint(iPaint *d, iRect rect) { 66void setClip_Paint(iPaint *d, iRect rect) {
67 //rect = intersect_Rect(rect, rect_Root(get_Root())); 67 //rect = intersect_Rect(rect, rect_Root(get_Root()));
68 addv_I2(&rect.pos, origin_Paint);
68 if (isEmpty_Rect(rect)) { 69 if (isEmpty_Rect(rect)) {
69 rect = init_Rect(0, 0, 1, 1); 70 rect = init_Rect(0, 0, 1, 1);
70 } 71 }
71 addv_I2(&rect.pos, origin_Paint); 72// iRect root = rect_Root(get_Root());
73 iRect targetRect = zero_Rect();
74 SDL_Texture *target = SDL_GetRenderTarget(renderer_Paint_(d));
75 if (target) {
76 SDL_QueryTexture(target, NULL, NULL, &targetRect.size.x, &targetRect.size.y);
77 rect = intersect_Rect(rect, targetRect);
78 }
79 else {
80 rect = intersect_Rect(rect, rect_Root(get_Root()));
81 }
82
83 /*if (rect.pos.x < 0) {
84 adjustEdges_Rect(&rect, 0, 0, 0, -rect.pos.x);
85 }
86 if (rect.pos.y < 0) {
87 adjustEdges_Rect(&rect, -rect.pos.y, 0, 0, 0);
88 }
89 if (right_Rect(rect) > right_Rect(root)) {
90 adjustEdges_Rect(&rect, 0, right_Rect(root) - right_Rect(rect), 0, 0);
91 }
92 if (bottom_Rect(rect) > bottom_Rect(root)) {
93 adjustEdges_Rect(&rect, 0, bottom_Rect(root) - bottom_Rect(rect), 0, 0);
94 }*/
72 SDL_RenderSetClipRect(renderer_Paint_(d), (const SDL_Rect *) &rect); 95 SDL_RenderSetClipRect(renderer_Paint_(d), (const SDL_Rect *) &rect);
73} 96}
74 97
diff --git a/src/ui/root.c b/src/ui/root.c
index 7b2b5b15..59f98aa4 100644
--- a/src/ui/root.c
+++ b/src/ui/root.c
@@ -525,7 +525,9 @@ void updateToolbarColors_Root(iRoot *d) {
525#if defined (iPlatformMobile) 525#if defined (iPlatformMobile)
526 iWidget *toolBar = findChild_Widget(d->widget, "toolbar"); 526 iWidget *toolBar = findChild_Widget(d->widget, "toolbar");
527 if (toolBar) { 527 if (toolBar) {
528 const iBool isSidebarVisible = isVisible_Widget(findChild_Widget(d->widget, "sidebar")); 528 const iBool isSidebarVisible =
529 isVisible_Widget(findChild_Widget(d->widget, "sidebar")) ||
530 isVisible_Widget(findChild_Widget(d->widget, "sidebar2"));
529 const int bg = isSidebarVisible ? uiBackgroundSidebar_ColorId : 531 const int bg = isSidebarVisible ? uiBackgroundSidebar_ColorId :
530 tmBannerBackground_ColorId; 532 tmBannerBackground_ColorId;
531 setBackgroundColor_Widget(toolBar, bg); 533 setBackgroundColor_Widget(toolBar, bg);
diff --git a/src/ui/touch.c b/src/ui/touch.c
index f0456acb..5fc8f245 100644
--- a/src/ui/touch.c
+++ b/src/ui/touch.c
@@ -254,6 +254,8 @@ static iFloat3 gestureVector_Touch_(const iTouch *d) {
254} 254}
255 255
256static void update_TouchState_(void *ptr) { 256static void update_TouchState_(void *ptr) {
257 iWindow *win = get_Window();
258 const iWidget *oldHover = win->hover;
257 iTouchState *d = ptr; 259 iTouchState *d = ptr;
258 /* Check for long presses to simulate right clicks. */ 260 /* Check for long presses to simulate right clicks. */
259 const uint32_t nowTime = SDL_GetTicks(); 261 const uint32_t nowTime = SDL_GetTicks();
@@ -293,6 +295,7 @@ static void update_TouchState_(void *ptr) {
293 /* Looks like a possible tap. */ 295 /* Looks like a possible tap. */
294 dispatchNotification_Touch_(touch, widgetTapBegins_UserEventCode); 296 dispatchNotification_Touch_(touch, widgetTapBegins_UserEventCode);
295 dispatchMotion_Touch_(touch->pos[0], 0); 297 dispatchMotion_Touch_(touch->pos[0], 0);
298 refresh_Widget(touch->affinity);
296 touch->isTapBegun = iTrue; 299 touch->isTapBegun = iTrue;
297 } 300 }
298 if (!touch->isTapAndHold && nowTime - touch->startTime >= longPressSpanMs_ && 301 if (!touch->isTapAndHold && nowTime - touch->startTime >= longPressSpanMs_ &&
@@ -363,6 +366,10 @@ static void update_TouchState_(void *ptr) {
363 if (!isEmpty_Array(d->touches) || !isEmpty_Array(d->moms)) { 366 if (!isEmpty_Array(d->touches) || !isEmpty_Array(d->moms)) {
364 addTickerRoot_App(update_TouchState_, NULL, ptr); 367 addTickerRoot_App(update_TouchState_, NULL, ptr);
365 } 368 }
369 if (oldHover != win->hover) {
370 refresh_Widget(oldHover);
371 refresh_Widget(win->hover);
372 }
366} 373}
367 374
368#if 0 375#if 0
diff --git a/src/ui/util.c b/src/ui/util.c
index 05d39c01..48ed41a6 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -1349,10 +1349,17 @@ iWidget *makeValueInput_Widget(iWidget *parent, const iString *initialValue, con
1349 2))); 1349 2)));
1350// finalizeSheet_Mobile(dlg); 1350// finalizeSheet_Mobile(dlg);
1351 arrange_Widget(dlg); 1351 arrange_Widget(dlg);
1352 setupSheetTransition_Mobile(dlg, incoming_TransitionFlag | top_TransitionDir);
1353 if (parent) { 1352 if (parent) {
1354 setFocus_Widget(as_Widget(input)); 1353 setFocus_Widget(as_Widget(input));
1355 } 1354 }
1355 /* Check that the top is in the safe area. */ {
1356 int top = top_Rect(bounds_Widget(dlg));
1357 int delta = top - top_Rect(safeRect_Root(dlg->root));
1358 if (delta < 0) {
1359 dlg->rect.pos.y -= delta;
1360 }
1361 }
1362 setupSheetTransition_Mobile(dlg, incoming_TransitionFlag | top_TransitionDir);
1356 return dlg; 1363 return dlg;
1357} 1364}
1358 1365
diff --git a/src/ui/widget.c b/src/ui/widget.c
index 7665c5bc..0765bf9f 100644
--- a/src/ui/widget.c
+++ b/src/ui/widget.c
@@ -89,7 +89,7 @@ static void release_WidgetDrawBuffer(iWidgetDrawBuffer *d) {
89static iRect boundsForDraw_Widget_(const iWidget *d) { 89static iRect boundsForDraw_Widget_(const iWidget *d) {
90 iRect bounds = bounds_Widget(d); 90 iRect bounds = bounds_Widget(d);
91 if (d->flags & drawBackgroundToBottom_WidgetFlag) { 91 if (d->flags & drawBackgroundToBottom_WidgetFlag) {
92 bounds.size.y = iMaxi(bounds.size.y, size_Root(d->root).y - top_Rect(bounds)); 92 bounds.size.y = iMax(bounds.size.y, size_Root(d->root).y);
93 } 93 }
94 return bounds; 94 return bounds;
95} 95}
@@ -1218,7 +1218,7 @@ iLocalDef iBool isDrawn_Widget_(const iWidget *d) {
1218 return ~d->flags & hidden_WidgetFlag || d->flags & visualOffset_WidgetFlag; 1218 return ~d->flags & hidden_WidgetFlag || d->flags & visualOffset_WidgetFlag;
1219} 1219}
1220 1220
1221static void drawLayerEffects_Widget_(const iWidget *d) { 1221void drawLayerEffects_Widget(const iWidget *d) {
1222 /* Layered effects are not buffered, so they are drawn here separately. */ 1222 /* Layered effects are not buffered, so they are drawn here separately. */
1223 iAssert(isDrawn_Widget_(d)); 1223 iAssert(isDrawn_Widget_(d));
1224 iBool shadowBorder = (d->flags & keepOnTop_WidgetFlag && ~d->flags & mouseModal_WidgetFlag) != 0; 1224 iBool shadowBorder = (d->flags & keepOnTop_WidgetFlag && ~d->flags & mouseModal_WidgetFlag) != 0;
@@ -1248,6 +1248,48 @@ static void drawLayerEffects_Widget_(const iWidget *d) {
1248 fillRect_Paint(&p, rect_Root(d->root), backgroundFadeColor_Widget()); 1248 fillRect_Paint(&p, rect_Root(d->root), backgroundFadeColor_Widget());
1249 SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_NONE); 1249 SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_NONE);
1250 } 1250 }
1251#if defined (iPlatformAppleMobile)
1252 if (d->bgColor >= 0 && d->flags & (drawBackgroundToHorizontalSafeArea_WidgetFlag |
1253 drawBackgroundToVerticalSafeArea_WidgetFlag)) {
1254 iPaint p;
1255 init_Paint(&p);
1256 const iRect rect = bounds_Widget(d);
1257 const iInt2 rootSize = size_Root(d->root);
1258 const iInt2 center = divi_I2(rootSize, 2);
1259 int top = 0, right = 0, bottom = 0, left = 0;
1260 if (d->flags & drawBackgroundToHorizontalSafeArea_WidgetFlag) {
1261 const iBool isWide = width_Rect(rect) > rootSize.x * 9 / 10;
1262 if (isWide || mid_Rect(rect).x < center.x) {
1263 left = -left_Rect(rect);
1264 }
1265 if (isWide || mid_Rect(rect).x > center.x) {
1266 right = rootSize.x - right_Rect(rect);
1267 }
1268 }
1269 if (d->flags & drawBackgroundToVerticalSafeArea_WidgetFlag) {
1270 if (top_Rect(rect) > center.y) {
1271 bottom = rootSize.y - bottom_Rect(rect);
1272 }
1273 if (bottom_Rect(rect) < center.y) {
1274 top = -top_Rect(rect);
1275 }
1276 }
1277 if (top < 0) {
1278 fillRect_Paint(&p, (iRect){ init_I2(left_Rect(rect), 0),
1279 init_I2(width_Rect(rect), top_Rect(rect)) },
1280 d->bgColor);
1281 }
1282 if (left < 0) {
1283 fillRect_Paint(&p, (iRect){ init_I2(0, top_Rect(rect)),
1284 init_I2(left_Rect(rect), height_Rect(rect)) }, d->bgColor);
1285 }
1286 if (right > 0) {
1287 fillRect_Paint(&p, (iRect){ init_I2(right_Rect(rect), top_Rect(rect)),
1288 init_I2(right, height_Rect(rect)) }, d->bgColor);
1289 }
1290// adjustEdges_Rect(&rect, iMin(0, top), iMax(0, right), iMax(0, bottom), iMin(0, left));
1291 }
1292#endif
1251} 1293}
1252 1294
1253void drawBackground_Widget(const iWidget *d) { 1295void drawBackground_Widget(const iWidget *d) {
@@ -1261,12 +1303,13 @@ void drawBackground_Widget(const iWidget *d) {
1261 if (d->bgColor >= 0 || d->frameColor >= 0) { 1303 if (d->bgColor >= 0 || d->frameColor >= 0) {
1262 iRect rect = bounds_Widget(d); 1304 iRect rect = bounds_Widget(d);
1263 if (d->flags & drawBackgroundToBottom_WidgetFlag) { 1305 if (d->flags & drawBackgroundToBottom_WidgetFlag) {
1264 rect.size.y = iMax(rect.size.y, size_Root(d->root).y - top_Rect(rect)); 1306 rect.size.y += size_Root(d->root).y; // = iMax(rect.size.y, size_Root(d->root).y - top_Rect(rect));
1265 } 1307 }
1266 iPaint p; 1308 iPaint p;
1267 init_Paint(&p); 1309 init_Paint(&p);
1268 if (d->bgColor >= 0) { 1310 if (d->bgColor >= 0) {
1269#if defined (iPlatformAppleMobile) 1311#if 0 && defined (iPlatformAppleMobile)
1312 /* TODO: This is part of the unbuffered draw (layer effects). */
1270 if (d->flags & (drawBackgroundToHorizontalSafeArea_WidgetFlag | 1313 if (d->flags & (drawBackgroundToHorizontalSafeArea_WidgetFlag |
1271 drawBackgroundToVerticalSafeArea_WidgetFlag)) { 1314 drawBackgroundToVerticalSafeArea_WidgetFlag)) {
1272 const iInt2 rootSize = size_Root(d->root); 1315 const iInt2 rootSize = size_Root(d->root);
@@ -1289,7 +1332,7 @@ void drawBackground_Widget(const iWidget *d) {
1289 top = -top_Rect(rect); 1332 top = -top_Rect(rect);
1290 } 1333 }
1291 } 1334 }
1292 adjustEdges_Rect(&rect, top, right, bottom, left); 1335 adjustEdges_Rect(&rect, iMin(0, top), iMax(0, right), iMax(0, bottom), iMin(0, left));
1293 } 1336 }
1294#endif 1337#endif
1295 fillRect_Paint(&p, rect, d->bgColor); 1338 fillRect_Paint(&p, rect, d->bgColor);
@@ -1339,7 +1382,7 @@ static void addToPotentiallyVisible_Widget_(const iWidget *d, iPtrArray *pvs, iR
1339 if (isDrawn_Widget_(d)) { 1382 if (isDrawn_Widget_(d)) {
1340 iRect bounds = bounds_Widget(d); 1383 iRect bounds = bounds_Widget(d);
1341 if (d->flags & drawBackgroundToBottom_WidgetFlag) { 1384 if (d->flags & drawBackgroundToBottom_WidgetFlag) {
1342 bounds.size.y = size_Root(d->root).y - top_Rect(bounds); 1385 bounds.size.y += size_Root(d->root).y; // iMax(bounds.size.y, size_Root(d->root).y - top_Rect(bounds));
1343 } 1386 }
1344 if (isFullyContainedByOther_Rect(bounds, *fullyMasked)) { 1387 if (isFullyContainedByOther_Rect(bounds, *fullyMasked)) {
1345 return; /* can't be seen */ 1388 return; /* can't be seen */
@@ -1411,14 +1454,21 @@ void setDrawBufferEnabled_Widget(iWidget *d, iBool enable) {
1411 1454
1412static void beginBufferDraw_Widget_(const iWidget *d) { 1455static void beginBufferDraw_Widget_(const iWidget *d) {
1413 if (d->drawBuf) { 1456 if (d->drawBuf) {
1414// printf("[%p] drawbuffer update %d\n", d, d->drawBuf->isValid); 1457 printf("[%p] drawbuffer update %d\n", d, d->drawBuf->isValid);
1458 if (d->drawBuf->isValid) {
1459 iAssert(!isEqual_I2(d->drawBuf->size, boundsForDraw_Widget_(d).size));
1460// printf(" drawBuf:%dx%d boundsForDraw:%dx%d\n",
1461// d->drawBuf->size.x, d->drawBuf->size.y,
1462// boundsForDraw_Widget_(d).size.x,
1463// boundsForDraw_Widget_(d).size.y);
1464 }
1415 const iRect bounds = bounds_Widget(d); 1465 const iRect bounds = bounds_Widget(d);
1416 SDL_Renderer *render = renderer_Window(get_Window()); 1466 SDL_Renderer *render = renderer_Window(get_Window());
1417 d->drawBuf->oldTarget = SDL_GetRenderTarget(render); 1467 d->drawBuf->oldTarget = SDL_GetRenderTarget(render);
1418 d->drawBuf->oldOrigin = origin_Paint; 1468 d->drawBuf->oldOrigin = origin_Paint;
1419 realloc_WidgetDrawBuffer(d->drawBuf, render, boundsForDraw_Widget_(d).size); 1469 realloc_WidgetDrawBuffer(d->drawBuf, render, boundsForDraw_Widget_(d).size);
1420 SDL_SetRenderTarget(render, d->drawBuf->texture); 1470 SDL_SetRenderTarget(render, d->drawBuf->texture);
1421 //SDL_SetRenderDrawColor(render, 255, 0, 0, 128); 1471// SDL_SetRenderDrawColor(render, 255, 0, 0, 128);
1422 SDL_SetRenderDrawColor(render, 0, 0, 0, 0); 1472 SDL_SetRenderDrawColor(render, 0, 0, 0, 0);
1423 SDL_RenderClear(render); 1473 SDL_RenderClear(render);
1424 origin_Paint = neg_I2(bounds.pos); /* with current visual offset */ 1474 origin_Paint = neg_I2(bounds.pos); /* with current visual offset */
@@ -1445,7 +1495,7 @@ void draw_Widget(const iWidget *d) {
1445 } 1495 }
1446 return; 1496 return;
1447 } 1497 }
1448 drawLayerEffects_Widget_(d); 1498 drawLayerEffects_Widget(d);
1449 if (!d->drawBuf || !checkDrawBuffer_Widget_(d)) { 1499 if (!d->drawBuf || !checkDrawBuffer_Widget_(d)) {
1450 beginBufferDraw_Widget_(d); 1500 beginBufferDraw_Widget_(d);
1451 drawBackground_Widget(d); 1501 drawBackground_Widget(d);
@@ -1755,7 +1805,9 @@ iWidget *focus_Widget(void) {
1755} 1805}
1756 1806
1757void setHover_Widget(iWidget *d) { 1807void setHover_Widget(iWidget *d) {
1758 get_Window()->hover = d; 1808 iWindow *win = get_Window();
1809 iAssert(win);
1810 win->hover = d;
1759} 1811}
1760 1812
1761iWidget *hover_Widget(void) { 1813iWidget *hover_Widget(void) {
@@ -1850,7 +1902,8 @@ void postCommand_Widget(const iAnyObject *d, const char *cmd, ...) {
1850 deinit_String(&str); 1902 deinit_String(&str);
1851} 1903}
1852 1904
1853void refresh_Widget(const iAnyObject *d) { 1905void refresh_Widget(const iAnyObject *d) {
1906 if (!d) return;
1854 /* TODO: Could be widget specific, if parts of the tree are cached. */ 1907 /* TODO: Could be widget specific, if parts of the tree are cached. */
1855 /* TODO: The visbuffer in DocumentWidget and ListWidget could be moved to be a general 1908 /* TODO: The visbuffer in DocumentWidget and ListWidget could be moved to be a general
1856 purpose feature of Widget. */ 1909 purpose feature of Widget. */
diff --git a/src/ui/widget.h b/src/ui/widget.h
index fd4d8898..b46e5177 100644
--- a/src/ui/widget.h
+++ b/src/ui/widget.h
@@ -204,6 +204,7 @@ iAny * findFocusable_Widget (const iWidget *startFrom, enum iWidgetF
204iAny * findOverflowScrollable_Widget (iWidget *); 204iAny * findOverflowScrollable_Widget (iWidget *);
205size_t childCount_Widget (const iWidget *); 205size_t childCount_Widget (const iWidget *);
206void draw_Widget (const iWidget *); 206void draw_Widget (const iWidget *);
207void drawLayerEffects_Widget (const iWidget *);
207void drawBackground_Widget (const iWidget *); 208void drawBackground_Widget (const iWidget *);
208void drawChildren_Widget (const iWidget *); 209void drawChildren_Widget (const iWidget *);
209void drawRoot_Widget (const iWidget *); /* root only */ 210void drawRoot_Widget (const iWidget *); /* root only */
diff --git a/src/ui/window.c b/src/ui/window.c
index 3385f436..8034d858 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -875,7 +875,7 @@ iBool processEvent_Window(iWindow *d, const SDL_Event *ev) {
875 } 875 }
876 } 876 }
877 } 877 }
878 const iWidget *oldHover = d->hover; 878// const iWidget *oldHover = d->hover;
879 iBool wasUsed = iFalse; 879 iBool wasUsed = iFalse;
880 /* Dispatch first to the mouse-grabbed widget. */ 880 /* Dispatch first to the mouse-grabbed widget. */
881// iWidget *widget = d->root.widget; 881// iWidget *widget = d->root.widget;
@@ -929,9 +929,10 @@ iBool processEvent_Window(iWindow *d, const SDL_Event *ev) {
929 } 929 }
930 } 930 }
931 } 931 }
932 if (oldHover != d->hover) { 932// if (oldHover != d->hover) {
933 postRefresh_App(); 933// refresh_Widget(oldHover);
934 } 934// refresh_Widget(d->hover);
935// }
935 if (event.type == SDL_MOUSEMOTION) { 936 if (event.type == SDL_MOUSEMOTION) {
936 applyCursor_Window_(d); 937 applyCursor_Window_(d);
937 } 938 }
@@ -1107,7 +1108,7 @@ void draw_Window(iWindow *d) {
1107 } 1108 }
1108 setCurrent_Root(NULL); 1109 setCurrent_Root(NULL);
1109#if !defined (NDEBUG) 1110#if !defined (NDEBUG)
1110 draw_Text(defaultBold_FontId, zero_I2(), red_ColorId, "%d", drawCount_); 1111 draw_Text(defaultBold_FontId, safeRect_Root(d->roots[0]).pos, red_ColorId, "%d", drawCount_);
1111 drawCount_ = 0; 1112 drawCount_ = 0;
1112#endif 1113#endif
1113 } 1114 }