Skip to content

Commit

Permalink
Merge pull request #2839 from freakboy3742/ios-topbar
Browse files Browse the repository at this point in the history
Ensure that the top bar size is included in iOS layout calculations.
  • Loading branch information
mhsmith authored Sep 17, 2024
2 parents 76ac0e1 + c02449a commit bf07c67
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 6 deletions.
11 changes: 11 additions & 0 deletions android/tests_backend/window.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from android.content import Context
from androidx.appcompat import R as appcompat_R

from .dialogs import DialogsMixin
Expand All @@ -20,6 +21,16 @@ def content_size(self):
self.root_view.getHeight() / self.scale_factor,
)

@property
def top_bar_height(self):
# Android doesn't require explicit allowances for the top bar in content layout;
# the size of the top bar is the difference between the screen and the root
# window content size.
context = self.app._impl.native.getApplicationContext()
window_manager = context.getSystemService(Context.WINDOW_SERVICE)
display = window_manager.getDefaultDisplay()
return (display.getHeight() - self.root_view.getHeight()) / self.scale_factor

def _native_menu(self):
return self.native.findViewById(appcompat_R.id.action_bar).getMenu()

Expand Down
1 change: 1 addition & 0 deletions changes/2836.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
iOS apps now correctly account for the size of the navigation bar when laying out app content.
7 changes: 1 addition & 6 deletions iOS/src/toga_iOS/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def width(self):

@property
def height(self):
return self.layout_native.bounds.size.height
return self.layout_native.bounds.size.height - self.top_offset

@property
def top_offset(self):
Expand Down Expand Up @@ -149,11 +149,6 @@ def __init__(
# Set the controller's view to be the root content widget
self.controller.view = self.native

# The testbed app won't instantiate a simple app, so we can't test these properties
@property
def height(self): # pragma: no cover
return self.layout_native.bounds.size.height - self.top_offset

# The testbed app won't instantiate a simple app, so we can't test these properties
@property
def top_offset(self): # pragma: no cover
Expand Down
7 changes: 7 additions & 0 deletions iOS/tests_backend/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,12 @@ def content_size(self):
),
)

@property
def top_bar_height(self):
return (
UIApplication.sharedApplication.statusBarFrame.size.height
+ self.native.rootViewController.navigationBar.frame.size.height
)

def has_toolbar(self):
pytest.skip("Toolbars not implemented on iOS")
18 changes: 18 additions & 0 deletions testbed/tests/app/test_mobile.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import pytest

import toga
from toga.colors import REBECCAPURPLE
from toga.style import Pack

####################################################################################
# Mobile platform tests
Expand All @@ -9,6 +11,22 @@
pytest.skip("Test is specific to desktop platforms", allow_module_level=True)


async def test_content_size(app, main_window, main_window_probe):
"""The content size doesn't spill outsize the viewable area."""

box = toga.Box(style=Pack(background_color=REBECCAPURPLE))
main_window.content = box

await main_window_probe.redraw("Content is a box")

# The overall layout has both the box, plus the top bar.
assert main_window.screen.size.height >= (
box.layout.content_height + main_window_probe.top_bar_height
)
# The box is the same width as the screen.
assert main_window.screen.size.width == box.layout.content_width


async def test_show_hide_cursor(app):
"""The app cursor methods can be invoked"""
# Invoke the methods to verify the endpoints exist. However, they're no-ops,
Expand Down

0 comments on commit bf07c67

Please sign in to comment.