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

API Poposal - Preferences command #1084

Closed
saroad2 opened this issue Sep 27, 2020 · 2 comments
Closed

API Poposal - Preferences command #1084

saroad2 opened this issue Sep 27, 2020 · 2 comments
Labels
enhancement New features, or improvements to existing features.

Comments

@saroad2
Copy link
Member

saroad2 commented Sep 27, 2020

Taking inspiration from here, I would like to propose the following API for implementing the preferences command in Toga:

First, we should implement a toga.Preferences class with the following API:

import toga as toga

preferences = toga.Preferences()

# Set tabs and settings in each tab dynamically

# Set preferences in first tab
preferences.tab_name.add_setting(
    "name",
    label="Your name",
    type_or_widget=str,  # Initialize with toga.TextInput automatically
    on_change=on_name_change,
)
preferences.tab_name.add_setting(
    "approve",
    label="Approve me or not",
    type_or_widget=bool,  # Initialize with toga.Switch automatically
    on_change=on_approve_change,
    default=True,  # One can set default value to setting
)
preferences.tab_name.add_setting(
    "age",
    label="Your age",
    type_or_widget=int,  # Initialize with toga.NumberInput automatically
    on_change=on_age_change,
)

# Set preferences in second tab
preferences.tab_name2.add_setting(
    "language",
    label="Operation language",
    type_or_widget=toga.Selection,  # Since toga.Selection has been chosen specifically, using it.
    on_change=on_language_change,
    items=[
        "English",
        "Spanish",
        "Hebrew",
    ],  # Can read extra kwargs and set them correctly in widget constructor
)

# Getters and setters
print(preferences.tab_name.name)  # Get name value
preferences.tab_name.approve = False  # Set approve value

We will assign a toga.App.preferences property and use it in this way. When using the Preferences command, a new window will open using toga.OptionContainer to navigate between tabs, each option containing the designated widgets to set its settings.

In the end. it should look like this:

preferences

What do you think? If you approve, I'll go on implementing it.

@saroad2 saroad2 added the enhancement New features, or improvements to existing features. label Sep 27, 2020
@freakboy3742
Copy link
Member

For reference - there is some earlier discussion on #90.

I think you've got the right idea in the broad strokes; but I don't completely agree with the "spelling" of the API.

My immediate thought about this problem is that there's a lot of overlap with the sort of thing that web frameworks (like Django) do with Forms. There's a need to describe key-value pairs, along with validation conditions and a serialisation scheme. The only thing that is "Settings" specific about the process is the mechanism for loading/saving settings, and the GUI panel wrapping the content for display.

More generally, a "form" is a common pattern for parts of an app GUI; so if it's possible to have a general "GUI forms" framework fall out of this work, that would be icing on the cake.

A related piece of work that might make this easier is to expand the use of Sources to support data other than Lists and Trees. I've been intending to build "simple value" sources for a while, and use those as backing elements for text input, switches and so on. If any input widget can be backed by a Source, the Preferences object becomes a collection of Sources organized into sections; and the preferences panel becomes a Form for all sources in a given preferences section.

Does that make sense?

@freakboy3742
Copy link
Member

Closing in favour of #90.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New features, or improvements to existing features.
Projects
None yet
Development

No branches or pull requests

2 participants