Open Ocupe opened 7 years ago
Hells yes. This is exactly the sort of thing I had in my head! Thanks for the great writeup.
A couple more ideas to throw into your thoughts:
.rc
file in the project home directory style)@freakboy3742 and everyone else. Before I run in the completely wrong direction I would like to get your feedback on this. Especially the part of 'The Normalized Settings Structure'
In this section we really go deep and try to find the lowest common denominator for a general settings API.
It is clear that the integration of settings on iOS and Android is similar but still different. Because we try to provide a common interface, that works for all platforms, we are left with the challenging and tedious job to compare all the existing API's and then find a good way to generalise them into a toga settings API.
The following table shows what platform specific 'things'/widgets your specified toga SettingsItem would resolves to.
For example, when you specify a toga toggle, you get a Toggle Switch on iOS and something called SwitchPreference on Android.
Links to the official documentations:
toga | iOS | android | macOS | Windows | Linux |
---|---|---|---|---|---|
toggle | Toggle Switch Element | CheckBoxPreference, SwitchPreference | |||
text field | Text Field Element | EditTextPreference | |||
pick one | Radio Group Element | ListPreference | |||
multi value | Multi Value Element | MultiSelectListPreference | |||
slider | Slider Element |
This is a proposal how the interface between toga.core and the respective system integrations of toga could look like. The following idea is derived from the fact that iOS and android store their settings in a .plist and .xml files. I though we could translate the in code specified settings to a normalised from. This agreed upon normalized form than acts as the base of all the system specific integrations.
# defining the settings
settings = toga.Settings(version='1.0.0')
switch = toga.SettingsItem('switch', label='My Switch', default=True)
slider = toga.SettingsItem('slider', label='My Slider', default=5, min=0, max=10)
group = toga.SettingsGroup('My Settings', [switch, slider])
settings.add_group(group)
# When printing the normalized form we end up whit something like this.
pprint(settings.get_normal_form())
{'settings':
{
'version': '1.0.0',
'groups':
[{'group':
{
'title': 'My Settings',
'items':
[{
'default': True,
'key': 'my_switch',
'label': 'My Switch',
'type': 'switch'},
{
'default': 5,
'key': 'my_slider',
'label': 'My Slider',
'max': 10,
'min': 0,
'type': 'slider'
}]
}
}]
}
}
This normalized form, here proposed as a dictionary, can now be passed to the platform specific integration of toga. As a nice side effect we end up with something that can easily be stored in a xml or similar file format and is platform independent.
YES - this looks almost exactly what I had in mind. No particular feedback, other than "MOAR OF THIS". 😸
Thanks for that contribution. I've taken a quick look, and while it looks like there's a good starting point there, there's a lot missing from the design discussion raised above.
schema
as a library; I can't rule it out, but there are other much better known schema management tools out there (pydantic and marshmallow being two that I'm familiar with)Obviously, none of this stops you from using your package externally (and thank you for using the togax- prefix on your package name); but if you're aiming to have that work merged into Toga's core, these are issues that will need to be addressed (and there's likely more that a detailed teardown would reveal).
Thank you for taking a look, I appreciate it
I'll keep working on this as an external project for now, but the closer it stays to upstream standards, the better Thanks again, and thanks for the great project!
- Thanks for the tips on pydantic and marshmallow, I'll take a look at these and see if they can be used. Do you have any preference on these? I selected schema as it seemed like a simple way to define the schema with no extra dependencies but I'm happy to change it.
I don't have a hard preference. If anything, my preference is really "can we do this without a third party dependency at all?". After all, this isn't a user-modifiable file - we're in control of reading and writing the file. In those conditions... what do we gain by using a schema library?
That said - of the candidates on the table, Pydantic is the one that I have seen getting the most attention of late - at least in part because it can also be used as the core of an ORM, as well as some other use cases. On that basis, it would be my (very weak) preference... although it also has a Rust-based binary component, and we don't currently have a compilation recipe for it on iOS or Android, so that complicates adoption. However, I'm also willing to be convinced of the merits of another option (based on feature set, filesize, community vitality etc).
I don't really know much about iOS development and how the settings api would work on there, so I probably won't be able to work much on that right now.
To be clear - we don't expect a contributor to implement every API for every platform. If nothing else, it's a rare developer who has a Mac, Windows, Linux, iOS and Android machine available for development and testing. We don't even expect a developer to become an expert the APIs of all those frameworks. However, we do need to have some degree of confidence that the API being proposed could be implemented on all platforms by someone who has access to the hardware and knowledge.
I'll keep working on this as an external project for now, but the closer it stays to upstream standards, the better Thanks again, and thanks for the great project!
Glad you're enjoying it!
Settings API for Toga
I wrote this short text after a brief discussion with @freakboy3742. My intention is to kick off a conversation about a possible 'Settings API' for the toga project. This text is badly written and possibly full of bad ideas. But it is a start! :)
Settings API
The settings API is the attempt to provide us programmers with a abstract interface to easily create settings/preferences panels that work on all platforms. A Mac user should feel just as 'at home' as a windows or linux user. On top of that, it should be possible to port a desktop settings window to mobile without the need of rewriting it.
Native desktop settings in the wild
To get a better understanding about how native settings look like on different platforms I added this small overview.
Desktop Examples:
Mobile Examples:
Basic Structure
I think that all settings representations, no matter on what platform, have a common structure. They try to group settings which are related into some kind of settings group. On desktop platforms they use some sort of tab functionality, on mobile the use nested table views. These groups are then again grouped into a settings menu. On desktop often represented in form of a single settings window and on mobile in form of a settings view which holds a table view with navigation.
Basic Hierarchy:
Write once, use everywhere
I see the future of the toga settings API as write one, use everywhere! The translation from a desktop settings window to a mobile settings table view shouldn't be the problem as long as all settings items are implemented on all platforms.
'Translations'
In this section I describes possible 'translations' from desktop to mobile.
Settings Items
A list of possible settings items that one can use with the settings api. I don't see a problem if we allow the user to use all input widgets defined in the toga documentations. Again, as long as we make the settings items available on all platforms or find fitting 'translations' from desktop to mobile and vice versa.
Under the Hood
I don't know a clever way of implementing a Settings API. But at least I can share how I would like to interact with a potential Settings API and what things I would expect from it.
Notes