diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-16 09:33:49 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-16 09:33:49 +0200 |
commit | 49bc5bba5df94f2bcbe12b513255b92599c052c2 (patch) | |
tree | 80faf1f591fb7498dc512d5826457b52c56fc5f3 /src/ui/util.c | |
parent | 63d1b8562c655d5f482846c99ec95ba666587e81 (diff) |
Mobile: Dialog layout fixes
Orientation and safe inset changes are now applied to phone dialogs.
There is still the occasional unscrollable dialog, but it seems random?
Diffstat (limited to 'src/ui/util.c')
-rw-r--r-- | src/ui/util.c | 85 |
1 files changed, 54 insertions, 31 deletions
diff --git a/src/ui/util.c b/src/ui/util.c index 18ed7ba2..c1e27751 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -403,6 +403,7 @@ static iBool isCommandIgnoredByMenus_(const char *cmd) { | |||
403 | equal_Command(cmd, "document.changed") || | 403 | equal_Command(cmd, "document.changed") || |
404 | equal_Command(cmd, "visited.changed") || | 404 | equal_Command(cmd, "visited.changed") || |
405 | (deviceType_App() == desktop_AppDeviceType && equal_Command(cmd, "window.resized")) || | 405 | (deviceType_App() == desktop_AppDeviceType && equal_Command(cmd, "window.resized")) || |
406 | equal_Command(cmd, "widget.overflow") || | ||
406 | equal_Command(cmd, "window.reload.update") || | 407 | equal_Command(cmd, "window.reload.update") || |
407 | equal_Command(cmd, "window.mouse.exited") || | 408 | equal_Command(cmd, "window.mouse.exited") || |
408 | equal_Command(cmd, "window.mouse.entered") || | 409 | equal_Command(cmd, "window.mouse.entered") || |
@@ -909,6 +910,23 @@ iWidget *makeSheet_Widget(const char *id) { | |||
909 | return sheet; | 910 | return sheet; |
910 | } | 911 | } |
911 | 912 | ||
913 | static void updateSheetPanelMetrics_(iWidget *sheet) { | ||
914 | iWidget *navi = findChild_Widget(sheet, "panel.navi"); | ||
915 | iWidget *naviPad = child_Widget(navi, 0); | ||
916 | int naviHeight = lineHeight_Text(defaultBig_FontId) + 4 * gap_UI; | ||
917 | #if defined (iPlatformAppleMobile) | ||
918 | float left, right, top, bottom; | ||
919 | safeAreaInsets_iOS(&left, &top, &right, &bottom); | ||
920 | setPadding_Widget(sheet, left, 0, right, 0); | ||
921 | navi->rect.pos = init_I2(left, top); | ||
922 | iConstForEach(PtrArray, i, findChildren_Widget(sheet, "panel.toppad")) { | ||
923 | iWidget *pad = *i.value; | ||
924 | setSize_Widget(pad, init1_I2(naviHeight)); | ||
925 | } | ||
926 | #endif | ||
927 | setSize_Widget(navi, init_I2(-1, naviHeight)); | ||
928 | } | ||
929 | |||
912 | static iBool slidePanelHandler_(iWidget *d, const char *cmd) { | 930 | static iBool slidePanelHandler_(iWidget *d, const char *cmd) { |
913 | if (equal_Command(cmd, "panel.open")) { | 931 | if (equal_Command(cmd, "panel.open")) { |
914 | iWidget *button = pointer_Command(cmd); | 932 | iWidget *button = pointer_Command(cmd); |
@@ -944,19 +962,9 @@ static iBool slidePanelHandler_(iWidget *d, const char *cmd) { | |||
944 | return iTrue; | 962 | return iTrue; |
945 | } | 963 | } |
946 | if (equal_Command(cmd, "window.resized")) { | 964 | if (equal_Command(cmd, "window.resized")) { |
947 | iWidget *sheet = parent_Widget(d); | 965 | updateSheetPanelMetrics_(parent_Widget(d)); |
948 | #if defined (iPlatformAppleMobile) | 966 | } |
949 | float left, top, right, bottom; | 967 | return iFalse; |
950 | safeAreaInsets_iOS(&left, &top, &right, &bottom); | ||
951 | /* TODO: incorrect */ | ||
952 | if (isLandscape_App()) { | ||
953 | setPadding_Widget(sheet, left, 0, right, 0); | ||
954 | } | ||
955 | else { | ||
956 | setPadding1_Widget(sheet, 0); | ||
957 | } | ||
958 | #endif | ||
959 | } return iFalse; | ||
960 | } | 968 | } |
961 | 969 | ||
962 | static iBool isTwoColumnPage_(iWidget *d) { | 970 | static iBool isTwoColumnPage_(iWidget *d) { |
@@ -1082,19 +1090,6 @@ void finalizeSheet_Widget(iWidget *sheet) { | |||
1082 | can be taller than the display. In hindsight, it may have been easier to | 1090 | can be taller than the display. In hindsight, it may have been easier to |
1083 | create phone versions of each dialog, but at least this works with any future | 1091 | create phone versions of each dialog, but at least this works with any future |
1084 | changes to the UI (..."works"). */ | 1092 | changes to the UI (..."works"). */ |
1085 | int topSafe = 0; | ||
1086 | int navBarHeight = lineHeight_Text(defaultBig_FontId) + 4 * gap_UI; | ||
1087 | #if defined (iPlatformAppleMobile) | ||
1088 | /* Safe area insets. */ { | ||
1089 | /* TODO: Must be updated when orientation changes; use a widget flag? */ | ||
1090 | float l, t, r, b; | ||
1091 | safeAreaInsets_iOS(&l, &t, &r, &b); | ||
1092 | // setPadding_Widget(sheet, l, t, r, b); | ||
1093 | setPadding1_Widget(sheet, 0); | ||
1094 | topSafe = t; | ||
1095 | navBarHeight += t; | ||
1096 | } | ||
1097 | #endif | ||
1098 | setFlags_Widget(sheet, | 1093 | setFlags_Widget(sheet, |
1099 | keepOnTop_WidgetFlag | | 1094 | keepOnTop_WidgetFlag | |
1100 | parentCannotResize_WidgetFlag | | 1095 | parentCannotResize_WidgetFlag | |
@@ -1110,6 +1105,7 @@ void finalizeSheet_Widget(iWidget *sheet) { | |||
1110 | resizeWidthOfChildren_WidgetFlag, | 1105 | resizeWidthOfChildren_WidgetFlag, |
1111 | iTrue); | 1106 | iTrue); |
1112 | setBackgroundColor_Widget(sheet, uiBackground_ColorId); | 1107 | setBackgroundColor_Widget(sheet, uiBackground_ColorId); |
1108 | setPadding1_Widget(sheet, 0); | ||
1113 | iPtrArray *contents = collect_PtrArray(new_PtrArray()); /* two-column pages */ | 1109 | iPtrArray *contents = collect_PtrArray(new_PtrArray()); /* two-column pages */ |
1114 | iPtrArray *panelButtons = collect_PtrArray(new_PtrArray()); | 1110 | iPtrArray *panelButtons = collect_PtrArray(new_PtrArray()); |
1115 | iWidget *tabs = findChild_Widget(sheet, "prefs.tabs"); | 1111 | iWidget *tabs = findChild_Widget(sheet, "prefs.tabs"); |
@@ -1166,7 +1162,6 @@ void finalizeSheet_Widget(iWidget *sheet) { | |||
1166 | } | 1162 | } |
1167 | } | 1163 | } |
1168 | const iBool useSlidePanels = (size_PtrArray(contents) == size_PtrArray(panelButtons)); | 1164 | const iBool useSlidePanels = (size_PtrArray(contents) == size_PtrArray(panelButtons)); |
1169 | topPanel->rect.pos = init_I2(0, navBarHeight); | ||
1170 | addChildFlags_Widget(sheet, iClob(topPanel), | 1165 | addChildFlags_Widget(sheet, iClob(topPanel), |
1171 | arrangeVertical_WidgetFlag | | 1166 | arrangeVertical_WidgetFlag | |
1172 | resizeWidthOfChildren_WidgetFlag | arrangeHeight_WidgetFlag | | 1167 | resizeWidthOfChildren_WidgetFlag | arrangeHeight_WidgetFlag | |
@@ -1182,7 +1177,7 @@ void finalizeSheet_Widget(iWidget *sheet) { | |||
1182 | setId_Widget(owner, "panel"); | 1177 | setId_Widget(owner, "panel"); |
1183 | setUserData_Object(button, owner); | 1178 | setUserData_Object(button, owner); |
1184 | setBackgroundColor_Widget(owner, uiBackground_ColorId); | 1179 | setBackgroundColor_Widget(owner, uiBackground_ColorId); |
1185 | addChild_Widget(owner, iClob(makePadding_Widget(navBarHeight - topSafe))); | 1180 | setId_Widget(addChild_Widget(owner, iClob(makePadding_Widget(0))), "panel.toppad"); |
1186 | iLabelWidget *title = addChildFlags_Widget(owner, | 1181 | iLabelWidget *title = addChildFlags_Widget(owner, |
1187 | iClob(new_LabelWidget(cstrCollect_String(upper_String(text_LabelWidget(button))), NULL)), alignLeft_WidgetFlag | frameless_WidgetFlag); | 1182 | iClob(new_LabelWidget(cstrCollect_String(upper_String(text_LabelWidget(button))), NULL)), alignLeft_WidgetFlag | frameless_WidgetFlag); |
1188 | setFont_LabelWidget(title, uiLabelLargeBold_FontId); | 1183 | setFont_LabelWidget(title, uiLabelLargeBold_FontId); |
@@ -1192,6 +1187,7 @@ void finalizeSheet_Widget(iWidget *sheet) { | |||
1192 | focusRoot_WidgetFlag | | 1187 | focusRoot_WidgetFlag | |
1193 | hidden_WidgetFlag | | 1188 | hidden_WidgetFlag | |
1194 | disabled_WidgetFlag | | 1189 | disabled_WidgetFlag | |
1190 | //safePadding_WidgetFlag | | ||
1195 | arrangeVertical_WidgetFlag | | 1191 | arrangeVertical_WidgetFlag | |
1196 | resizeWidthOfChildren_WidgetFlag | | 1192 | resizeWidthOfChildren_WidgetFlag | |
1197 | arrangeHeight_WidgetFlag | | 1193 | arrangeHeight_WidgetFlag | |
@@ -1337,6 +1333,7 @@ void finalizeSheet_Widget(iWidget *sheet) { | |||
1337 | chevron_WidgetFlag); | 1333 | chevron_WidgetFlag); |
1338 | } | 1334 | } |
1339 | else { | 1335 | else { |
1336 | setFlags_Widget(topPanel, overflowScrollable_WidgetFlag, iTrue); | ||
1340 | /* Update heading style. */ | 1337 | /* Update heading style. */ |
1341 | setFont_LabelWidget((iLabelWidget *) dialogHeading, uiLabelLargeBold_FontId); | 1338 | setFont_LabelWidget((iLabelWidget *) dialogHeading, uiLabelLargeBold_FontId); |
1342 | setFlags_Widget(dialogHeading, alignLeft_WidgetFlag, iTrue); | 1339 | setFlags_Widget(dialogHeading, alignLeft_WidgetFlag, iTrue); |
@@ -1348,11 +1345,16 @@ void finalizeSheet_Widget(iWidget *sheet) { | |||
1348 | removeChild_Widget(parent_Widget(input), input); | 1345 | removeChild_Widget(parent_Widget(input), input); |
1349 | addChild_Widget(topPanel, iClob(makeValuePadding_(as_Widget(input)))); | 1346 | addChild_Widget(topPanel, iClob(makeValuePadding_(as_Widget(input)))); |
1350 | } | 1347 | } |
1348 | /* Top padding for each panel, to account for the overlaid navbar. */ { | ||
1349 | setId_Widget(addChildPos_Widget(topPanel, | ||
1350 | iClob(makePadding_Widget(0)), front_WidgetAddPos), | ||
1351 | "panel.toppad"); | ||
1352 | } | ||
1351 | /* Navbar. */ { | 1353 | /* Navbar. */ { |
1352 | iWidget *navi = new_Widget(); | 1354 | iWidget *navi = new_Widget(); |
1353 | setSize_Widget(navi, init_I2(-1, navBarHeight)); | 1355 | setId_Widget(navi, "panel.navi"); |
1354 | setBackgroundColor_Widget(navi, uiBackground_ColorId); | 1356 | setBackgroundColor_Widget(navi, uiBackground_ColorId); |
1355 | addChild_Widget(navi, iClob(makePadding_Widget(topSafe))); | 1357 | addChild_Widget(navi, iClob(makePadding_Widget(0))); |
1356 | iLabelWidget *back = addChildFlags_Widget(navi, | 1358 | iLabelWidget *back = addChildFlags_Widget(navi, |
1357 | iClob(new_LabelWidget(leftAngle_Icon " Back", "panel.close")), | 1359 | iClob(new_LabelWidget(leftAngle_Icon " Back", "panel.close")), |
1358 | noBackground_WidgetFlag | frameless_WidgetFlag | | 1360 | noBackground_WidgetFlag | frameless_WidgetFlag | |
@@ -1361,6 +1363,7 @@ void finalizeSheet_Widget(iWidget *sheet) { | |||
1361 | setId_Widget(as_Widget(back), "panel.back"); | 1363 | setId_Widget(as_Widget(back), "panel.back"); |
1362 | setFont_LabelWidget(back, defaultBig_FontId); | 1364 | setFont_LabelWidget(back, defaultBig_FontId); |
1363 | if (!isPrefs) { | 1365 | if (!isPrefs) { |
1366 | /* Pick up the dialog buttons for the navbar. */ | ||
1364 | iWidget *buttons = findChild_Widget(sheet, "dialogbuttons"); | 1367 | iWidget *buttons = findChild_Widget(sheet, "dialogbuttons"); |
1365 | iLabelWidget *cancel = findMenuItem_Widget(buttons, "cancel"); | 1368 | iLabelWidget *cancel = findMenuItem_Widget(buttons, "cancel"); |
1366 | if (cancel) { | 1369 | if (cancel) { |
@@ -1385,7 +1388,22 @@ void finalizeSheet_Widget(iWidget *sheet) { | |||
1385 | addChildFlags_Widget(as_Widget(back), iClob(def), moveToParentRightEdge_WidgetFlag); | 1388 | addChildFlags_Widget(as_Widget(back), iClob(def), moveToParentRightEdge_WidgetFlag); |
1386 | updateSize_LabelWidget(def); | 1389 | updateSize_LabelWidget(def); |
1387 | } | 1390 | } |
1388 | /* TODO: Action buttons should be added in the bottom as extra buttons. */ | 1391 | /* Action buttons are added in the bottom as extra buttons. */ { |
1392 | iBool isFirstAction = iTrue; | ||
1393 | iForEach(ObjectList, i, children_Widget(buttons)) { | ||
1394 | if (isInstance_Object(i.object, &Class_LabelWidget) && | ||
1395 | i.object != cancel && i.object != def) { | ||
1396 | iLabelWidget *item = i.object; | ||
1397 | setBackgroundColor_Widget(i.object, uiBackgroundSidebar_ColorId); | ||
1398 | setFont_LabelWidget(item, defaultBig_FontId); | ||
1399 | removeChild_Widget(buttons, item); | ||
1400 | addChildFlags_Widget(topPanel, iClob(item), panelButtonFlags | | ||
1401 | (isFirstAction ? borderTop_WidgetFlag : 0)); | ||
1402 | updateSize_LabelWidget(item); | ||
1403 | isFirstAction = iFalse; | ||
1404 | } | ||
1405 | } | ||
1406 | } | ||
1389 | iRelease(removeChild_Widget(parent_Widget(buttons), buttons)); | 1407 | iRelease(removeChild_Widget(parent_Widget(buttons), buttons)); |
1390 | /* Styling for remaining elements. */ | 1408 | /* Styling for remaining elements. */ |
1391 | iForEach(ObjectList, i, children_Widget(topPanel)) { | 1409 | iForEach(ObjectList, i, children_Widget(topPanel)) { |
@@ -1400,10 +1418,14 @@ void finalizeSheet_Widget(iWidget *sheet) { | |||
1400 | } | 1418 | } |
1401 | } | 1419 | } |
1402 | addChildFlags_Widget(sheet, iClob(navi), | 1420 | addChildFlags_Widget(sheet, iClob(navi), |
1421 | drawBackgroundToVerticalSafeArea_WidgetFlag | | ||
1403 | arrangeHeight_WidgetFlag | resizeWidthOfChildren_WidgetFlag | | 1422 | arrangeHeight_WidgetFlag | resizeWidthOfChildren_WidgetFlag | |
1404 | resizeToParentWidth_WidgetFlag | arrangeVertical_WidgetFlag); | 1423 | resizeToParentWidth_WidgetFlag | arrangeVertical_WidgetFlag); |
1405 | } | 1424 | } |
1425 | updateSheetPanelMetrics_(sheet); | ||
1406 | arrange_Widget(sheet->parent); | 1426 | arrange_Widget(sheet->parent); |
1427 | postCommand_App("widget.overflow"); /* with the correct dimensions */ | ||
1428 | // printTree_Widget(sheet); | ||
1407 | } | 1429 | } |
1408 | else { | 1430 | else { |
1409 | arrange_Widget(sheet); | 1431 | arrange_Widget(sheet); |
@@ -1613,6 +1635,7 @@ static iBool messageHandler_(iWidget *msg, const char *cmd) { | |||
1613 | equal_Command(cmd, "document.autoreload") || | 1635 | equal_Command(cmd, "document.autoreload") || |
1614 | equal_Command(cmd, "document.reload") || | 1636 | equal_Command(cmd, "document.reload") || |
1615 | equal_Command(cmd, "document.request.updated") || | 1637 | equal_Command(cmd, "document.request.updated") || |
1638 | equal_Command(cmd, "widget.overflow") || | ||
1616 | startsWith_CStr(cmd, "window."))) { | 1639 | startsWith_CStr(cmd, "window."))) { |
1617 | destroy_Widget(msg); | 1640 | destroy_Widget(msg); |
1618 | } | 1641 | } |