Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[widget Audit] toga.SplitContainer #1984

Merged
merged 28 commits into from
Jul 17, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b9a1a38
Initial update to SplitContainer docs and API.
freakboy3742 Jun 14, 2023
5aac223
Correct docs typo.
freakboy3742 Jun 14, 2023
305a3f2
Update core tests for SplitContainer.
freakboy3742 Jun 14, 2023
89686bd
Cocoa SplitContainer to 100% coverage.
freakboy3742 Jun 16, 2023
d9e5737
Merge branch 'audit-scrollcontainer' into audit-splitcontainer
freakboy3742 Jun 18, 2023
134a3ff
Cleanups to Cocoa implementation.
freakboy3742 Jun 18, 2023
fd6d44b
GTK SplitContainer tests to 100%.
freakboy3742 Jun 18, 2023
8d64f1d
Fix markup issues with splitcontainer image.
freakboy3742 Jun 19, 2023
dbc6887
Update some test comments.
freakboy3742 Jun 19, 2023
8b83e64
Improve protection against double-setting the split.
freakboy3742 Jun 19, 2023
5c4cd00
Merge branch 'audit-scrollcontainer' into audit-splitcontainer
freakboy3742 Jun 20, 2023
a324c37
Merge branch 'audit-scrollcontainer' into audit-splitcontainer
freakboy3742 Jun 22, 2023
4195a8f
Merge branch 'audit-scrollcontainer' into audit-splitcontainer
freakboy3742 Jun 26, 2023
1b224c6
Merge branch 'audit-scrollcontainer' into audit-splitcontainer
freakboy3742 Jun 26, 2023
0414244
Merge branch 'audit-scrollcontainer' into audit-splitcontainer
freakboy3742 Jul 12, 2023
e7c945b
Add documentation for the constants module.
freakboy3742 Jul 12, 2023
b9cafba
Corrected inconsistent page titles.
freakboy3742 Jul 12, 2023
7374d4c
Apply suggestions from code review
freakboy3742 Jul 12, 2023
3399e45
Use direction constant consistently.
freakboy3742 Jul 12, 2023
87b8500
Allow empty content in split containers, and allow flex values <1
freakboy3742 Jul 12, 2023
88f1322
Update docs reference to <1 flex handling.
freakboy3742 Jul 12, 2023
489b0eb
Merge branch 'main' into audit-splitcontainer
mhsmith Jul 12, 2023
bd3f467
Documentation cleanups
mhsmith Jul 12, 2023
a9d06a4
Replace curved apostrophe which caused spell checking error
mhsmith Jul 12, 2023
dfb8361
Add splitcontainer example app
mhsmith Jul 12, 2023
b448213
Removed some redundant test cases.
freakboy3742 Jul 12, 2023
ae34946
Winforms to 100%
mhsmith Jul 15, 2023
a19aa46
Change mobile splitcontainer tests from `skip` back to `xfail`
mhsmith Jul 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions cocoa/src/toga_cocoa/widgets/splitcontainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ def create(self):
def set_bounds(self, x, y, width, height):
super().set_bounds(x, y, width, height)
for container in self.sub_containers:
container.content.interface.refresh()
if container.content:
container.content.interface.refresh()

# Apply any pending split
self.native.performSelector(
Expand All @@ -72,15 +73,19 @@ def set_content(self, content, flex):

for index, widget in enumerate(content):
# Compute the minimum layout for the content
widget.interface.style.layout(widget.interface, MinimumContainer())
min_width = widget.interface.layout.width
min_height = widget.interface.layout.height
if widget:
widget.interface.style.layout(widget.interface, MinimumContainer())
min_width = widget.interface.layout.width
min_height = widget.interface.layout.height

# Create a container with that minimum size, and assign the widget as content
self.sub_containers[index].min_width = min_width
self.sub_containers[index].min_height = min_height
# Create a container with that minimum size, and assign the widget as content
self.sub_containers[index].min_width = min_width
self.sub_containers[index].min_height = min_height

self.sub_containers[index].content = widget
self.sub_containers[index].content = widget
else:
self.sub_containers[index].min_width = 0
self.sub_containers[index].min_height = 0

# We now know the initial positions of the split. However, we can't *set* the
# because Cocoa requires a pixel position, and the widget isn't visible yet.
Expand Down
1 change: 1 addition & 0 deletions core/src/toga/constants/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@


class Direction(Enum):
"The direction a given property should act"
HORIZONTAL = 0
VERTICAL = 1
6 changes: 3 additions & 3 deletions core/src/toga/widgets/divider.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ def __init__(
:param style: A style object. If no style is provided, a default style will be
applied to the widget.
:param direction: The direction in which the divider will be drawn. Either
:attr:`~toga.widgets.SplitContainer.HORIZONTAL` or
:attr:`~toga.widgets.SplitContainer.VERTICAL`; defaults to
:attr:`~toga.widgets.SplitContainer.HORIZONTAL`
:attr:`~toga.constants.Direction.HORIZONTAL` or
:attr:`~toga.constants.Direction.VERTICAL`; defaults to
:attr:`~toga.constants.Direction.HORIZONTAL`
"""
super().__init__(id=id, style=style)

Expand Down
63 changes: 37 additions & 26 deletions core/src/toga/widgets/splitcontainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ def __init__(
id=None,
style=None,
direction: Direction = Direction.VERTICAL,
content: list[Widget | tuple[Widget, int]] | None = None,
content: tuple[Widget | tuple[Widget, int], Widget | tuple[Widget, int]] = (
None,
None,
),
):
"""Create a new SplitContainer.

Expand All @@ -24,26 +27,23 @@ def __init__(
:param style: A style object. If no style is provided, a default style will be
applied to the widget.
:param direction: The direction in which the divider will be drawn. Either
:attr:`~toga.widgets.SplitContainer.HORIZONTAL` or
:attr:`~toga.widgets.SplitContainer.VERTICAL`; defaults to
:attr:`~toga.widgets.SplitContainer.VERTICAL`
:attr:`~toga.constants.Direction.HORIZONTAL` or
:attr:`~toga.constants.Direction.VERTICAL`; defaults to
:attr:`~toga.constants.Direction.VERTICAL`
:param content: The content that will fill the panels of the SplitContainer. A
list with 2 elements; each item in the list is either:
tuple with 2 elements; each item in the tuple is either:

* A tuple containing of a widget and the initial flex value to apply to
* A tuple consisting of a widget and the initial flex value to apply to
that widget in the split.
* A widget. The widget will be given a flex value of 1.

"""
super().__init__(id=id, style=style)

self._content = []

# Create a platform specific implementation of a SplitContainer
self._impl = self.factory.SplitContainer(interface=self)

if content:
self.content = content
self.content = content
self.direction = direction

@property
Expand All @@ -64,26 +64,31 @@ def focus(self):
pass

@property
def content(self) -> list[Widget]:
def content(self) -> tuple[Widget, Widget]:
"""The widgets displayed in the SplitContainer.

When retrieved, only the list of widgets is returned.

When setting the value, the list must have at least 2 elements; each item in the
When setting the value, the list must have exactly 2 elements; each item in the
list can be either:

* A tuple containing of a widget and the initial flex value to apply to that
* A tuple consisting of a widget and the initial flex value to apply to that
widget in the split.
* A widget. The widget will be given a flex value of 1.

"""
return self._content

@content.setter
def content(self, content):
if content is None or len(content) != 2:
def content(
self, content: tuple[Widget | tuple[Widget, int], Widget | tuple[Widget, int]]
):
try:
if len(content) != 2:
raise TypeError()
except TypeError:
raise ValueError(
"SplitContainer content must be a list with exactly 2 elements"
"SplitContainer content must be a sequence with exactly 2 elements"
)

_content = []
Expand All @@ -92,8 +97,10 @@ def content(self, content):
if isinstance(item, tuple):
if len(item) == 2:
widget, flex_value = item
if flex_value < 1:
flex_value = 1
if flex_value <= 0:
raise ValueError(
"The flex value for an item in a SplitContainer must be >0"
)
else:
raise ValueError(
"An item in SplitContainer content must be a 2-tuple "
Expand All @@ -107,11 +114,15 @@ def content(self, content):
_content.append(widget)
flex.append(flex_value)

widget.app = self.app
widget.window = self.window
if widget:
widget.app = self.app
widget.window = self.window

self._impl.set_content([w._impl for w in _content], flex)
self._content = _content
self._impl.set_content(
tuple(w._impl if w is not None else None for w in _content),
flex,
)
self._content = tuple(_content)
self.refresh()

@Widget.app.setter
Expand All @@ -120,8 +131,8 @@ def app(self, app):
Widget.app.fset(self, app)

# Also assign the app to the content in the container
if self.content:
for content in self.content:
for content in self.content:
if content:
content.app = app

@Widget.window.setter
Expand All @@ -130,8 +141,8 @@ def window(self, window):
Widget.window.fset(self, window)

# Also assign the window to the content in the container
if self._content:
for content in self._content:
for content in self._content:
if content:
content.window = window

@property
Expand Down
Loading