summaryrefslogtreecommitdiff
path: root/src/ui/widget.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-09-12 21:00:44 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-09-12 21:00:44 +0300
commit0e7060d5306fef1f585982cc78223250d3ee8551 (patch)
treed21bb496f85cd275707db85ebac17e7e5f2a9adf /src/ui/widget.c
parent12262e7642489f1764018ef23b4913c203ddd9ab (diff)
Mobile: Better Settings tap targets; fixed safe area drawing
Diffstat (limited to 'src/ui/widget.c')
-rw-r--r--src/ui/widget.c75
1 files changed, 64 insertions, 11 deletions
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. */