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.Table #2011

Merged
merged 46 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
88d8b29
Update docstrings and port Table tests to pytest.
freakboy3742 Jun 23, 2023
de52103
Add docs for Table.
freakboy3742 Jun 23, 2023
e6137c4
Add changenotes.
freakboy3742 Jun 23, 2023
0ddc6ab
Add deletion by index to sources, and notifications for new attribute…
freakboy3742 Jun 24, 2023
e36ca88
Cocoa Table tested for all but icons and widget cells.
freakboy3742 Jun 24, 2023
f63c715
100% coverage and testbed for icons.
freakboy3742 Jun 25, 2023
7f1d922
Run spell check before links; it's faster, and more likely to fail.
freakboy3742 Jun 25, 2023
c7dba15
iOS doesn't have a Table widget.
freakboy3742 Jun 25, 2023
a474991
Include test files in manifest.
freakboy3742 Jun 25, 2023
1e6e44d
Test fixes for py3.7 and tox.
freakboy3742 Jun 25, 2023
3be907c
Cocoa Table to 100% coverage.
freakboy3742 Jun 26, 2023
399baf3
Correct row position calculation.
freakboy3742 Jun 26, 2023
564ab0f
Simplify activation handler.
freakboy3742 Jun 26, 2023
8e9e521
Update examples to reflect changes to table.
freakboy3742 Jun 26, 2023
cf121f4
Fix Windows failure
mhsmith Jun 26, 2023
bf7404a
Make Selection consistently unfocusable on Android
mhsmith Jun 26, 2023
e8c8983
Add explicit warnings for handler name change.
freakboy3742 Jun 26, 2023
dd70006
Add an explicit note that ListSource is list-like.
freakboy3742 Jun 26, 2023
81a4f25
Remove a platform test that is no longer needed.
freakboy3742 Jun 27, 2023
358cdc1
Switch GTK to use GdkPixBuf as the native Icon widget, and require a …
freakboy3742 Jun 27, 2023
0e4c2ad
Make the pause after a keystroke a default behavior.
freakboy3742 Jun 27, 2023
e05b675
GTK Table widget to 100%.
freakboy3742 Jun 27, 2023
77a7e4d
Add documentation notes about icons and widgets in Table.
freakboy3742 Jun 27, 2023
0e09760
Mark Android as 'done'; the implementation isn't complete enough for …
freakboy3742 Jun 27, 2023
8c57ecf
Add test that columns fill the available space.
freakboy3742 Jun 27, 2023
903fb17
Increase the allowance for inter-column padding.
freakboy3742 Jun 28, 2023
80b9853
Small cleanups of core API tests.
freakboy3742 Jun 29, 2023
210402d
Add keyboard shortcuts for select-all on Cocoa (copied from Tree)
freakboy3742 Jun 29, 2023
c92f36a
Add error handling for bad icon files.
freakboy3742 Jul 8, 2023
347abf9
Merge branch 'main' into audit-table
freakboy3742 Jul 17, 2023
fef0258
Merge branch 'main' into audit-table
freakboy3742 Jul 26, 2023
e0124c7
Merge branch 'main' into audit-table
freakboy3742 Jul 26, 2023
b23d4d5
Merge branch 'main' into audit-table
freakboy3742 Aug 4, 2023
ec1ac83
Merge branch 'main' into audit-table
mhsmith Aug 22, 2023
1e8deea
Documentation cleanups
mhsmith Aug 22, 2023
0c17678
Icon documentation cleanups
mhsmith Aug 22, 2023
b76e453
Apply suggestions from code review
mhsmith Aug 23, 2023
7c67ded
Avoid wrapping in examples
mhsmith Aug 23, 2023
ef88f58
More docs clarifications
mhsmith Aug 23, 2023
673b061
Merge branch 'main' into audit-table
mhsmith Aug 23, 2023
3d3641c
Winforms Table to 100% coverage
mhsmith Aug 24, 2023
37540d1
Winforms Icon to 100% coverage
mhsmith Aug 24, 2023
284b13f
Don't require final scroll position to be equal to starting position
mhsmith Aug 24, 2023
6e116c9
Android Table to 100% coverage
mhsmith Aug 27, 2023
1784000
Android Icon to 100% coverage
mhsmith Aug 27, 2023
b6c0d04
Add tests for accessors returning None, and fix on Cocoa and Winforms
mhsmith Aug 27, 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
14 changes: 4 additions & 10 deletions android/src/toga_android/widgets/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from .base import Widget


class TogaOnClickListener(OnClickListener):
class TogaOnClickListener(OnClickListener): # pragma: no cover
def __init__(self, impl):
super().__init__()
self.impl = impl
Expand All @@ -41,7 +41,7 @@ def onClick(self, view):
self.impl.interface.on_select(self.impl.interface, row=row)


class Table(Widget):
class Table(Widget): # pragma: no cover
table_layout = None
color_selected = None
color_unselected = None
Expand Down Expand Up @@ -184,7 +184,7 @@ def get_selection(self):
selection = []
for row_index in range(len(self.interface.data)):
if row_index in self.selection:
selection.append(self.selection[row_index])
selection.append(row_index)
if len(selection) == 0:
selection = None
elif not self.interface.multiple_select:
Expand All @@ -209,13 +209,7 @@ def remove(self, item, index):
def scroll_to_row(self, row):
pass

def set_on_select(self, handler):
pass

def set_on_double_click(self, handler):
self.interface.factory.not_implemented("Table.set_on_double_click()")

def add_column(self, heading, accessor):
def insert_column(self, index, heading, accessor):
self.change_source(self.interface.data)

def remove_column(self, accessor):
Expand Down
32 changes: 32 additions & 0 deletions android/tests_backend/icons.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import pytest

from .probe import BaseProbe


class IconProbe(BaseProbe):
# Android only supports 1 format, so the alternate is the same as the primary.
alternate_resource = "resources/icons/blue"

def __init__(self, app, icon):
super().__init__()
self.app = app
self.icon = icon
# At least for now, there's no native object.
# assert isinstance(self.icon._impl.native, NSImage)

def assert_icon_content(self, path):
if path == "resources/icons/green":
assert (
self.icon._impl.path
== self.app.paths.app / "resources" / "icons" / "green.png"
)
elif path == "resources/icons/blue":
assert (
self.icon._impl.path
== self.app.paths.app / "resources" / "icons" / "blue.png"
)
else:
pytest.fail("Unknown icon resource")

def assert_default_icon_content(self):
assert self.icon._impl.path == self.app.paths.toga / "resources" / "toga.png"
1 change: 1 addition & 0 deletions changes/2011.feature.1.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The Table widget now has 100% test coverage and complete API documentation.
1 change: 1 addition & 0 deletions changes/2011.feature.2.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Tables can now omit the header row by specifying ``headings=None`` and providing accessors.
1 change: 1 addition & 0 deletions changes/2011.removal.1.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
``Table.on_double_click`` has been renamed ``Table.on_activate``.
1 change: 1 addition & 0 deletions changes/2011.removal.2.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Tables now use an empty string for the default missing value on a Table.
1 change: 1 addition & 0 deletions changes/2011.removal.3.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
``Table.add_column()`` has been deprecated in favor of ``Table.append_column()`` and ``Table.insert_column()``
23 changes: 22 additions & 1 deletion cocoa/src/toga_cocoa/icons.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,26 @@ def __init__(self, interface, path):
self.interface = interface
self.interface._impl = self
self.path = path
try:
# We *should* be able to do a direct NSImage.alloc.init...(), but if the
# image file is invalid, the init fails, and returns NULL - but we've
# created an ObjC instance, so when the object passes out of scope, Rubicon
# tries to free it, which segfaults. To avoid this, we retain result of the
# alloc() (overriding the default Rubicon behavior of alloc), then release
# that reference once we're done. If the image was created successfully, we
# temporarily have a reference count that is 1 higher than it needs to be;
# if it fails, we don't end up with a stray release.
image = NSImage.alloc().retain()
self.native = image.initWithContentsOfFile(str(path))
if self.native is None:
raise ValueError(f"Unable to load icon from {path}")
finally:
image.release()

self.native = NSImage.alloc().initWithContentsOfFile(str(path))
# Multiple icon interface instances can end up referencing the same native
# instance, so make sure we retain a reference count at the impl level.
self.native.retain()

def __del__(self):
if self.native:
self.native.release()
13 changes: 8 additions & 5 deletions cocoa/src/toga_cocoa/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ def __init__(self, interface, path=None, data=None):
self.interface = interface

try:
# We *should* be able to do a direct NSImage.alloc.init...(),
# but for some reason, this segfaults in some environments
# when loading invalid images. On iOS we can avoid this by
# using the class-level constructors; on macOS we need to
# ensure we have a valid allocated image, then try to init it.
# We *should* be able to do a direct NSImage.alloc.init...(), but if the
# image file is invalid, the init fails, and returns NULL - but we've
# created an ObjC instance, so when the object passes out of scope, Rubicon
# tries to free it, which segfaults. To avoid this, we retain result of the
# alloc() (overriding the default Rubicon behavior of alloc), then release
# that reference once we're done. If the image was created successfully, we
# temporarily have a reference count that is 1 higher than it needs to be;
# if it fails, we don't end up with a stray release.
image = NSImage.alloc().retain()
if path:
self.native = image.initWithContentsOfFile(str(path))
Expand Down
4 changes: 3 additions & 1 deletion cocoa/src/toga_cocoa/widgets/internal/cells.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ def setup(self):

@objc_method
def setImage_(self, image):
if not self.imageView:
# This branch is here for future protection - but the image is *never* set
# before the text, so it can't ever happen.
if not self.imageView: # pragma: no cover
self.setup()

if image:
Expand Down
Loading