Lagrange [work/v1.12]

Mobile: Bottom URL/tab bars on tablet

=> 659564e2b2a4060a135bd134e2ed3a92bb590799

diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index d0d565d7..3ac9f1cb 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -881,7 +881,7 @@ static void updateVisible_DocumentView_(iDocumentView *d) {
     /* After scrolling/resizing stops, begin pre-rendering the visbuf contents. */ {
         removeTicker_App(prerender_DocumentWidget_, d->owner);
         remove_Periodic(periodic_App(), d);
-        if (~d->owner->flags & animationPlaceholder_DocumentWidgetFlag) {
+        if (~d->owner->widget.flags & destroyPending_WidgetFlag) {
             add_Periodic(periodic_App(), d->owner, "document.render");
         }
     }
@@ -5640,9 +5640,21 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) {
     draw_DocumentView_(&d->view);
     iPaint p;
     init_Paint(&p);
-    if (colorTheme_App() == pureWhite_ColorTheme) {
+    if (colorTheme_App() == pureWhite_ColorTheme &&
+        !(prefs_App()->bottomNavBar && prefs_App()->bottomTabBar)) {
+        /* A subtle separator between UI and content. */
         drawHLine_Paint(&p, topLeft_Rect(bounds), width_Rect(bounds), uiSeparator_ColorId);
     }
+    if (isPortraitPhone_App() && prefs_App()->bottomNavBar) {
+        /* Fill the top safe area. */
+        if (topSafeInset_Mobile() > 0) {
+            const iRect docBounds = documentBounds_DocumentView_(&d->view);
+            fillRect_Paint(&p, initCorners_Rect(zero_I2(), topRight_Rect(safeRect_Root(w->root))),
+                            !isEmpty_Banner(d->banner) && docBounds.pos.y + viewPos_DocumentView_(&d->view) -
+                                documentTopPad_DocumentView_(&d->view) > bounds.pos.y ?
+                                tmBannerBackground_ColorId : tmBackground_ColorId);
+        }
+    }
     /* Pull action indicator. */
     if (deviceType_App() != desktop_AppDeviceType) {
         float pullPos = pullActionPos_SmoothScroll(&d->view.scrollY);
diff --git a/src/ui/lookupwidget.c b/src/ui/lookupwidget.c
index afd9c10e..120b6562 100644
--- a/src/ui/lookupwidget.c
+++ b/src/ui/lookupwidget.c
@@ -687,10 +687,11 @@ static iBool processEvent_LookupWidget_(iLookupWidget *d, const SDL_Event *ev) {
                 }
                 else {
                     w->rect.pos = windowToLocal_Widget(w, visibleRect_Root(root).pos);
-                    w->rect.size.y = height_Rect(visibleRect_Root(root)) - height_Rect(navBarBounds);
+                    w->rect.size.y = height_Rect(visibleRect_Root(root)) - height_Rect(navBarBounds) +
+                        (!isPortraitPhone_App() ? bottomSafeInset_Mobile() : 0);
                 }
 #   if defined (iPlatformAppleMobile)
-                if (deviceType_App() == phone_AppDeviceType) {
+                if (deviceType_App() != desktop_AppDeviceType) {
                     float l = 0.0f, r = 0.0f;
                     safeAreaInsets_iOS(&l, NULL, &r, NULL);
                     w->rect.size.x = size_Root(root).x - l - r;
diff --git a/src/ui/mobile.c b/src/ui/mobile.c
index 3b47d4a1..5acc0c88 100644
--- a/src/ui/mobile.c
+++ b/src/ui/mobile.c
@@ -1037,6 +1037,15 @@ int leftSafeInset_Mobile(void) {
 #endif
 }
 
+int topSafeInset_Mobile(void) {
+#if defined (iPlatformAppleMobile)
+    float top;
+    safeAreaInsets_iOS(NULL, &top, NULL, NULL);
+    return iRound(top);
+#else
+    return 0;
+#endif
+}
 
 int bottomSafeInset_Mobile(void) {
 #if defined (iPlatformAppleMobile)
diff --git a/src/ui/mobile.h b/src/ui/mobile.h
index 79986771..3a12ff07 100644
--- a/src/ui/mobile.h
+++ b/src/ui/mobile.h
@@ -69,4 +69,5 @@ void        setupMenuTransition_Mobile  (iWidget *menu,  iBool isIncoming);
 void        setupSheetTransition_Mobile (iWidget *sheet, int flags);
 
 int         leftSafeInset_Mobile        (void);
+int         topSafeInset_Mobile         (void);
 int         bottomSafeInset_Mobile      (void);
diff --git a/src/ui/root.c b/src/ui/root.c
index 7f96cc9f..a93b9a6a 100644
--- a/src/ui/root.c
+++ b/src/ui/root.c
@@ -238,10 +238,10 @@ static const char *stopSeqCStr_[] = {
 
 static const int loadAnimIntervalMs_ = 133;
 static int       loadAnimIndex_      = 0;
-
-static iRoot *   activeRoot_     = NULL;
+static iRoot *   activeRoot_         = NULL;
 
 static void     setupMovableElements_Root_  (iRoot *);
+static void     setBottomBarPosition_       (iWidget *bottomBar, iBool show, iBool animate);
 
 iDefineTypeConstruction(Root)
 iDefineAudienceGetter(Root, visualOffsetsChanged)
@@ -549,6 +549,13 @@ static iBool handleRootCommands_(iWidget *root, const char *cmd) {
     }
     else if (equal_Command(cmd, "root.movable")) {
         setupMovableElements_Root_(root->root);
+        arrange_Widget(root);
+        iWidget *bottomBar = findChild_Widget(root, "bottombar");
+        if (bottomBar) {
+            /* Update bottom bar height and position. */
+            setBottomBarPosition_(bottomBar, isVisible_Widget(bottomBar), iFalse);
+            updateToolbarColors_Root(root->root);
+        }
         return iFalse; /* all roots must handle this */
     }
     else if (equal_Command(cmd, "theme.changed")) {
@@ -801,7 +808,8 @@ static void updateNavBarSize_(iWidget *navBar) {
         int vPad   = gap_UI * 3 / 2;
         int botPad = vPad / 2;
         int topPad = !findWidget_Root("winbar") ? gap_UI / 2 : 0;
-        if (isLandscape_App() && prefs_App()->bottomNavBar) {
+        if (prefs_App()->bottomNavBar &&
+            ((isPhone && isLandscape_App()) || deviceType_App() == tablet_AppDeviceType)) {
             botPad += bottomSafeInset_Mobile();
             hPad += leftSafeInset_Mobile();
         }
@@ -1103,6 +1111,17 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) {
         }
         return iTrue;
     }
+    else if (deviceType_App() == tablet_AppDeviceType && equal_Command(cmd, "keyboard.changed")) {
+        const int keyboardHeight = arg_Command(cmd);
+        if (focus_Widget() == findChild_Widget(navBar, "url")) {
+            setVisualOffset_Widget(navBar, -keyboardHeight + bottomSafeInset_Mobile(),
+                                   400, easeOut_AnimFlag | softer_AnimFlag);
+        }
+        else {
+            setVisualOffset_Widget(navBar, 0, 400, easeOut_AnimFlag | softer_AnimFlag);
+        }
+        return iFalse;
+    }
     return iFalse;
 }
 
@@ -1207,7 +1226,8 @@ static iBool handleToolBarCommands_(iWidget *toolBar, const char *cmd) {
         if (!bottomBar) {
             return iFalse;
         }
-        if (focus_Widget() == findChild_Widget(root_Widget(toolBar), "url") && height > 0) {
+        iWidget *navBar = findChild_Widget(root_Widget(toolBar), "navbar");
+        if (focus_Widget() == findChild_Widget(navBar, "url") && height > 0) {
             int inputHeight = 5 * gap_UI; /* TODO: Why this amount? Something's funny here. */
             int keyboardPad = height - (isPortrait_App() ? height_Widget(toolBar) : inputHeight);
             bottomBar->padding[3] = keyboardPad;
@@ -1817,6 +1837,7 @@ static void setupMovableElements_Root_(iRoot *d) {
     iWidget *div       = findChild_Widget(d->widget, "navdiv");
     iWidget *docTabs   = findChild_Widget(d->widget, "doctabs");
     iWidget *tabBar    = findChild_Widget(docTabs, "tabs.buttons");
+    iChangeFlags(navBar->flags2, permanentVisualOffset_WidgetFlag2, iFalse);
     if (prefs->bottomNavBar) {
         if (deviceType_App() == phone_AppDeviceType) {
             /* When at the bottom, the navbar is at the top of the bottombar, and gets fully hidden
@@ -1832,6 +1853,9 @@ static void setupMovableElements_Root_(iRoot *d) {
             removeChild_Widget(navBar->parent, navBar);
             addChildPos_Widget(div, navBar, back_WidgetAddPos);
             iRelease(navBar);
+            /* We'll need to be able to move the input field from under the keyboard. */
+            iChangeFlags(navBar->flags2, permanentVisualOffset_WidgetFlag2,
+                         deviceType_App() == tablet_AppDeviceType);
         }
     }
     else {
@@ -1847,9 +1871,17 @@ static void setupMovableElements_Root_(iRoot *d) {
         iRelease(navBar);
     }
     iChangeFlags(tabBar->flags2, permanentVisualOffset_WidgetFlag2, prefs->bottomTabBar);
+    /* Adjust safe area paddings. */
+    if (deviceType_App() == tablet_AppDeviceType && prefs->bottomTabBar && !prefs->bottomNavBar) {
+        tabBar->padding[3] = bottomSafeInset_Mobile();
+    }
+    else {
+        tabBar->padding[3] = 0;
+    }
     setTabBarPosition_Widget(docTabs, prefs->bottomTabBar);
     arrange_Widget(d->widget);
     postRefresh_App();
+    postCommand_App("window.resized"); /* not really, but some widgets will update their layout */
 }
 
 static void setBottomBarPosition_(iWidget *bottomBar, iBool show, iBool animate) {
@@ -1863,7 +1895,7 @@ static void setBottomBarPosition_(iWidget *bottomBar, iBool show, iBool animate)
     iWidget *docTabs = findChild_Widget(root->widget, "doctabs");
     iWidget *toolBar = findChild_Widget(bottomBar, "toolbar");
     iWidget *navBar = findChild_Widget(root->widget, "navbar");
-    const int height = size_Root(root).y - top_Rect(boundsWithoutVisualOffset_Widget(bottomBar));
+    const int height = height_Widget(bottomBar);
     size_t numPages = 0;
     iBool bottomTabBar = prefs->bottomTabBar;
     if (prefs->bottomTabBar || prefs->bottomNavBar) {
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c
index 17a4e87b..3536d2fc 100644
--- a/src/ui/sidebarwidget.c
+++ b/src/ui/sidebarwidget.c
@@ -908,10 +908,9 @@ void init_SidebarWidget(iSidebarWidget *d, enum iSidebarSide side) {
     setId_Widget(
         addChildPosFlags_Widget(listAndActions,
                                 iClob(d->actions = new_Widget()),
-                                /*isPhone ? front_WidgetAddPos :*/ back_WidgetAddPos,
+                                back_WidgetAddPos,
                                 arrangeHorizontal_WidgetFlag | arrangeHeight_WidgetFlag |
-                                    resizeWidthOfChildren_WidgetFlag), // |
-        //                                             drawBackgroundToHorizontalSafeArea_WidgetFlag),
+                                    resizeWidthOfChildren_WidgetFlag),
         "actions");
     if (deviceType_App() != desktop_AppDeviceType) {
         setFlags_Widget(findChild_Widget(w, "sidebar.title"), borderTop_WidgetFlag, iTrue);
@@ -1366,11 +1365,14 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev)
                             isPortrait_App());
             setBackgroundColor_Widget(w, isPortrait_App() ? uiBackgroundSidebar_ColorId : none_ColorId);
         }
-        if (!isPortraitPhone_App()) {
+        if (!isPortraitPhone_App() && !prefs_App()->bottomTabBar && !prefs_App()->bottomNavBar) {
             /* In sliding sheet mode, sidebar is resized to fit in the safe area. */
             setPadding_Widget(d->actions, 0, 0, 0, bottomSafeInset_Mobile());
         }
-            return iFalse;
+        else {
+            setPadding_Widget(d->actions, 0, 0, 0, 0);
+        }
+        return iFalse;
     }
     else if (isMetricsChange_UserEvent(ev)) {
         w->rect.size.x = d->widthAsGaps * gap_UI;
diff --git a/src/ui/util.c b/src/ui/util.c
index a6567016..6827ea08 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -2527,10 +2527,9 @@ iWidget *makePreferences_Widget(void) {
         const iMenuItem uiPanelItems[] = {
             { "title id:heading.prefs.interface" },
             { "dropdown device:0 id:prefs.returnkey", 0, 0, (const void *) returnKeyBehaviors },
-            { "padding device:1" },
+            { "toggle device:2 id:prefs.hidetoolbarscroll" },
             { "toggle id:prefs.bottomnavbar" },
             { "toggle id:prefs.bottomtabbar" },
-            { "toggle device:2 id:prefs.hidetoolbarscroll" },
             { "heading device:2 id:heading.prefs.toolbaractions" },
             { "dropdown device:2 id:prefs.toolbaraction1", 0, 0, (const void *) toolbarActionItems[0] },
             { "dropdown device:2 id:prefs.toolbaraction2", 0, 0, (const void *) toolbarActionItems[1] },
@@ -2577,17 +2576,18 @@ iWidget *makePreferences_Widget(void) {
             { "title id:heading.prefs.style" },
             { "radio horizontal:1 id:prefs.linewidth", 0, 0, (const void *) lineWidthItems },
             { "padding" },
+            { "toggle id:prefs.justify" },
+            { "toggle id:prefs.plaintext.wrap" },
+            { "toggle id:prefs.biglede" },
+            { "padding" },
             { "input id:prefs.linespacing maxlen:5" },
             { "input id:prefs.tabwidth maxlen:3" },
             { "radio id:prefs.quoteicon", 0, 0, (const void *) quoteItems },
             { "buttons id:prefs.boldlink", 0, 0, (const void *) boldLinkItems },
             { "padding" },
-            { "toggle id:prefs.justify" },
-            { "toggle id:prefs.biglede" },
-            { "toggle id:prefs.plaintext.wrap" },
-            { "toggle id:prefs.collapsepreonload" },
             { "toggle id:prefs.sideicon" },
-            { "toggle id:prefs.centershort" },            
+            { "toggle id:prefs.centershort" },
+            { "toggle id:prefs.collapsepreonload" },
             { NULL }    
         };
         const iMenuItem networkPanelItems[] = {
diff --git a/src/ui/widget.c b/src/ui/widget.c
index 82ff4c57..61c8a37e 100644
--- a/src/ui/widget.c
+++ b/src/ui/widget.c
@@ -1509,10 +1509,10 @@ void drawLayerEffects_Widget(const iWidget *d) {
             }
         }
         if (d->flags & drawBackgroundToVerticalSafeArea_WidgetFlag) {
-            if (top_Rect(rect) > center.y) {
+            if (top_Rect(rect) > center.y * 3 / 2) {
                 bottom = rootSize.y - bottom_Rect(rect);
             }
-            if (bottom_Rect(rect) < center.y) {
+            if (bottom_Rect(rect) < center.y / 2) {
                 top = -top_Rect(rect);
             }
         }
Proxy Information
Original URL
gemini://git.skyjake.fi/lagrange/work%2Fv1.12/cdiff/659564e2b2a4060a135bd134e2ed3a92bb590799
Status Code
Success (20)
Meta
text/gemini; charset=utf-8
Capsule Response Time
136.062767 milliseconds
Gemini-to-HTML Time
0.898996 milliseconds

This content has been proxied by September (3851b).