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.App #2075

Merged
merged 74 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
684a45d
Add documentation and test coverage for app and document.
freakboy3742 Aug 11, 2023
2e19256
Add an example DocumentApp
freakboy3742 Aug 11, 2023
8f77008
Add changenotes.
freakboy3742 Aug 11, 2023
d1a64a4
Correct usage of exit() by main window and quit menu items.
freakboy3742 Aug 11, 2023
2dfa2be
Correct usage of exit in testbed, and add a pause to ensure logs are …
freakboy3742 Aug 11, 2023
8f92cd3
Add docs, docstrings and type annotations for Command.
freakboy3742 Aug 11, 2023
2076dd9
Complete core test coverage for Command.
freakboy3742 Aug 12, 2023
f8c19b3
Remove CommandSet, GROUP_BREAK and SECTION_BREAK from public namespace.
freakboy3742 Aug 12, 2023
e0a46dc
Corrected some coverage issues with a late change to comparisons.
freakboy3742 Aug 12, 2023
fec495d
Factored out a common app fixture.
freakboy3742 Aug 12, 2023
dde078e
Cocoa to 100% (ish) coverage.
freakboy3742 Aug 15, 2023
d27307b
100% coverage of keys.
freakboy3742 Aug 15, 2023
d505c95
Insert a pause on app exit to make sure Briefcase gets all the app logs.
freakboy3742 Aug 16, 2023
035fc8b
Merge branch 'audit-window' into audit-app
freakboy3742 Aug 16, 2023
8219173
Merge branch 'audit-window' into audit-app
freakboy3742 Aug 16, 2023
fedd4fe
GTK app tests passing.
freakboy3742 Aug 16, 2023
6c8877c
hack around segfault for Gtk WebView tests
samschott Aug 16, 2023
596149f
Key tests at 100% on GTK.
samschott Aug 16, 2023
8140de2
Tweaks to get 100% coverage on GTK.
freakboy3742 Aug 17, 2023
adcecf2
Short delay to improve test reliability.
freakboy3742 Aug 17, 2023
ada9303
Add a missing await.
freakboy3742 Aug 17, 2023
cceeb5f
Add some CI debugging help.
freakboy3742 Aug 17, 2023
ca1471d
Merge branch 'audit-window' into audit-app
freakboy3742 Aug 23, 2023
9f24361
100% coverage of app on iOS.
freakboy3742 Aug 23, 2023
a5931ed
Merge branch 'audit-window' into audit-app
freakboy3742 Aug 24, 2023
c6fe640
Corrections to object lifecycle and test probes to pass CI.
freakboy3742 Aug 25, 2023
28771cf
Merge branch 'main' into audit-app
freakboy3742 Oct 18, 2023
1334fc6
Enable 100% coverage requirement on core tests.
freakboy3742 Oct 18, 2023
5cf47cd
Enable 100% test requirement on testbed tests.
freakboy3742 Oct 18, 2023
b7fe16c
Remove backend tests.
freakboy3742 Oct 18, 2023
98ef170
Update docs to remove references to py-core and backend tests.
freakboy3742 Oct 18, 2023
eea80a1
Correct some pre-commit issues.
freakboy3742 Oct 18, 2023
7f42fce
Tweaks for GTK test coverage.
freakboy3742 Oct 18, 2023
69e760b
Ensure constraints are retained until the container is destroyed.
freakboy3742 Oct 19, 2023
5c31e88
Merge branch 'main' into audit-app
freakboy3742 Oct 20, 2023
08b5b33
Increase tolerances for testing on cocoa.
freakboy3742 Oct 20, 2023
9f09703
Merge remote-tracking branch 'origin/main' into audit-app
mhsmith Oct 23, 2023
fb25864
Remove toga_dummy/test_implementation.py
mhsmith Oct 23, 2023
7222344
Update tox and isort comments
mhsmith Oct 23, 2023
3f67033
Clean up App constructor docs
mhsmith Oct 23, 2023
ca8410d
Document App.windows, and related fixes
mhsmith Oct 25, 2023
1a2baec
Deprecate redundant "id" and "name" properties
mhsmith Oct 25, 2023
9127104
Add `App.loop` property
mhsmith Oct 25, 2023
5fdf934
Replace uses of App.name
mhsmith Oct 25, 2023
59654ad
Merge branch 'main' into audit-app
mhsmith Oct 25, 2023
f20899a
Fix WinForms menu initialization
mhsmith Oct 25, 2023
51141bb
More App documentation cleanups
mhsmith Oct 26, 2023
b7977d2
Command documentation cleanups
mhsmith Oct 26, 2023
64064b8
DocumentApp documentation cleanups
mhsmith Oct 26, 2023
a8df430
Correct GTK file dialog usage in DocumentApp.
freakboy3742 Oct 27, 2023
1029f33
examples/command working correctly on WinForms
mhsmith Oct 27, 2023
d185acf
WinForms passing all tests
mhsmith Oct 27, 2023
3938b1e
WinForms app.py at 100% coverage
mhsmith Oct 28, 2023
688da96
All WinForms files at 100% coverage
mhsmith Oct 28, 2023
8b83148
Add debugging for cursor visibility
mhsmith Oct 28, 2023
500ec7f
More CI debugging
mhsmith Oct 28, 2023
74f79fe
More CI debugging
mhsmith Oct 29, 2023
40d7120
More CI debugging
mhsmith Oct 29, 2023
387a4aa
Remove CI debugging
mhsmith Oct 29, 2023
f063b37
examples/command working correctly on Android
mhsmith Oct 29, 2023
4cde00c
Android passing all tests
mhsmith Oct 29, 2023
2e69615
Android app.py at 100% coverage
mhsmith Oct 29, 2023
1583545
All Android files at 100% coverage
mhsmith Oct 29, 2023
ff64a99
Protect against an edge case of garbage collection.
freakboy3742 Oct 30, 2023
dd9babf
Restore WindowSet `__isub__` and `__iadd__` methods
mhsmith Oct 30, 2023
de3fff6
Revert rename of app_name to distribution_name
mhsmith Oct 30, 2023
3c2fa56
Fix link between Window.toolbar and App.commands
mhsmith Oct 30, 2023
3ba85dd
Document the behavior around implicit command registration.
freakboy3742 Oct 30, 2023
7f0b952
Make windowset +=/-= operations no-ops.
freakboy3742 Oct 30, 2023
2b05ca2
Make the app a required argument to commandset if it's going to be used.
freakboy3742 Oct 30, 2023
0df6ea2
Ensure stale references to menus are removed on re-creation.
freakboy3742 Oct 30, 2023
aaca421
An extra scrollcontainer assertion to validate an inconsistent code p…
freakboy3742 Oct 30, 2023
ce9cc85
Ensure Winforms table warnings are captured.
freakboy3742 Oct 31, 2023
207b440
Add a test of adding a command to both toolbar and menus
mhsmith Oct 31, 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
18 changes: 15 additions & 3 deletions core/src/toga/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,13 +275,15 @@ def __init__(
warn(
"App.app_name has been renamed to distribution_name",
DeprecationWarning,
stacklevel=2,
)
distribution_name = app_name

if id is not None:
warn(
"App.id is deprecated and will be ignored. Use app_id instead",
DeprecationWarning,
stacklevel=2,
)

if windows is not None:
Expand Down Expand Up @@ -419,7 +421,11 @@ def paths(self) -> Paths:
@property
def name(self) -> str:
"""**DEPRECATED** – Use :any:`formal_name`."""
warn("App.name is deprecated. Use formal_name instead", DeprecationWarning)
warn(
"App.name is deprecated. Use formal_name instead",
DeprecationWarning,
stacklevel=2,
)
return self._formal_name

@property
Expand All @@ -436,7 +442,11 @@ def distribution_name(self) -> str:
@property
def app_name(self) -> str:
"""**DEPRECATED** – Renamed to ``distribution_name``."""
warn("App.app_name has been renamed to distribution_name", DeprecationWarning)
warn(
"App.app_name has been renamed to distribution_name",
DeprecationWarning,
stacklevel=2,
)
return self._distribution_name

@property
Expand Down Expand Up @@ -471,7 +481,9 @@ def description(self) -> str | None:
@property
def id(self) -> str:
"""**DEPRECATED** – Use :any:`app_id`."""
warn("App.id is deprecated. Use app_id instead", DeprecationWarning)
warn(
"App.id is deprecated. Use app_id instead", DeprecationWarning, stacklevel=2
)
return self._app_id

@property
Expand Down
3 changes: 2 additions & 1 deletion core/src/toga/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ def __init__(
Commands may not use all the arguments - for example, on some platforms, menus
will contain icons; on other platforms they won't.

:param action: A handler that will be invoked when the command is activated.
:param action: A handler to invoke when the command is activated. If this is
``None``, the command will be disabled.
:param text: A label for the command.
:param shortcut: A key combination that can be used to invoke the command.
:param tooltip: A short description of what the command will do.
Expand Down
5 changes: 0 additions & 5 deletions docs/reference/api/resources/command.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,6 @@ a similar pattern.
It doesn't matter what order you add commands to the app - the group, section and order
will be used to display the commands in the right order.

If a command is added to a toolbar, it will automatically be added to the app
as well. It isn't possible to have functionality exposed on a toolbar that
isn't also exposed by the app. So, ``cmd2`` will be added to the app, even though
it wasn't explicitly added to the app commands.

mhsmith marked this conversation as resolved.
Show resolved Hide resolved

Reference
---------
Expand Down
12 changes: 6 additions & 6 deletions examples/command/command/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,9 @@ def startup(self):
tiberius_icon_256 = "resources/tiberius-256"

# Set up main window
self.main_window = toga.MainWindow(title=self.name)
self.main_window = toga.MainWindow(title=self.formal_name)

# Add commands
print("adding commands")
# Create a "Things" menu group to contain some of the commands.
# No explicit ordering is provided on the group, so it will appear
# after application-level menus, but *before* the Command group.
Expand Down Expand Up @@ -113,16 +112,18 @@ def startup(self):
)
cmd7 = toga.Command(
self.action7,
text="TB action 7",
text="TB Action 7",
tooltip="Perform toolbar action 7",
shortcut=toga.Key.MOD_1 + "p",
order=30,
icon=tiberius_icon_256,
group=sub_menu,
enabled=False,
)

def action4(widget):
print("action 4")
cmd3.enabled = not cmd3.enabled
cmd7.enabled = not cmd7.enabled
self.textpanel.value += "action 4\n"

cmd4 = toga.Command(
Expand All @@ -135,7 +136,7 @@ def action4(widget):

# The order in which commands are added to the app or the toolbar won't
# alter anything. Ordering is defined by the command definitions.
self.app.commands.add(cmd1, cmd0, cmd6, cmd4, cmd3)
self.app.commands.add(cmd1, cmd0, cmd6, cmd4, cmd3, cmd7)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not adding cmd7 here was an explicit test of the "adding to toolbar implies adding to app" case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted.

Copy link
Member

@mhsmith mhsmith Oct 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thoughts, I think it's worth keeping this to verify that adding a command to both places doesn't cause any problems. And I've added a similar case to the core tests.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as we've got an example of all three possibilities (app only, toolbar only, app and toolbar), 👍.

self.app.main_window.toolbar.add(cmd2, cmd5, cmd7)

# Buttons
Expand Down Expand Up @@ -164,7 +165,6 @@ def action4(widget):


def main():
print("app.main")
return ExampleTestCommandApp("Test Command", "org.beeware.widgets.command")


Expand Down
21 changes: 14 additions & 7 deletions winforms/src/toga_winforms/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,27 @@ def create(self):

# Call user code to populate the main window
self.interface._startup()
self.create_menus()
self._create_app_commands()
self.create_menus()
self.interface.main_window._impl.set_app(self)

def create_menus(self):
window = self.interface.main_window._impl
menubar = window.native.MainMenuStrip
if menubar:
menubar.Items.Clear()
else:
# The menu bar doesn't need to be positioned, because its `Dock` property
# defaults to `Top`.
menubar = WinForms.MenuStrip()
window.native.Controls.Add(menubar)
window.native.MainMenuStrip = menubar
menubar.SendToBack() # In a dock, "back" means "top".

self._menu_items = {}
self._menu_groups = {}

toga.Group.FILE.order = 0
menubar = WinForms.MenuStrip()
submenu = None
for cmd in self.interface.commands:
if cmd == GROUP_BREAK:
Expand All @@ -145,11 +156,7 @@ def create_menus(self):
self._menu_items[item] = cmd
submenu.DropDownItems.Add(item)

# The menu bar doesn't need to be positioned, because its `Dock` property
# defaults to `Top`.
self.interface.main_window._impl.native.Controls.Add(menubar)
self.interface.main_window._impl.native.MainMenuStrip = menubar
self.interface.main_window._impl.resize_content()
window.resize_content()

def _submenu(self, group, menubar):
try:
Expand Down
2 changes: 1 addition & 1 deletion winforms/src/toga_winforms/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def apply_layout(self, layout_width, layout_height):
)

def add_content(self, widget):
# The default appears to be to add new controls to the back of the Z-order.
# The default is to add new controls to the back of the Z-order.
self.native_content.Controls.Add(widget.native)
widget.native.BringToFront()

Expand Down
12 changes: 6 additions & 6 deletions winforms/src/toga_winforms/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,20 @@ def create_toolbar(self):
# defaults to `Top`.
self.toolbar_native = WinForms.ToolStrip()
self.native.Controls.Add(self.toolbar_native)
self.toolbar_native.BringToFront() # In a dock, "front" means "bottom".

for cmd in self.interface.toolbar:
if cmd == GROUP_BREAK:
item = WinForms.ToolStripSeparator()
elif cmd == SECTION_BREAK:
item = WinForms.ToolStripSeparator()
else:
item = WinForms.ToolStripMenuItem(cmd.text)
if cmd.tooltip is not None:
item.ToolTipText = cmd.tooltip
if cmd.icon is not None:
native_icon = cmd.icon._impl.native
item = WinForms.ToolStripMenuItem(
cmd.text, native_icon.ToBitmap()
)
else:
item = WinForms.ToolStripMenuItem(cmd.text)
item.Image = cmd.icon._impl.native.ToBitmap()
item.Enabled = cmd.enabled
item.Click += WeakrefCallable(cmd._impl.winforms_handler)
cmd._impl.native.append(item)
self.toolbar_native.Items.Add(item)
Expand Down