GSoC: Settings API and Basic Inward Facing Testing API
See original GitHub issue!!! Proofreading in Progress. The corrected version will follow later. I thought feedback is more important than correct spelling. !!!
GSoC Proposal - Toga Settings API and Basic Inward Facing Testing API
Introduction
Programs and settings are a inseparably bound with each other. Every professional application gives users the freedom to change default values to there needs and liking. Toga should realise this need and provide a strong and compelling solution to create beautiful and platform native settings.
The Toga project is completely untested at the moment. As a first step to tackle the not trivial problem, that cross platform testing is, I want to build up a inward facing testing system to test toga core and it’s interface.
Project Goals
In short, the main goal of this Google Summer of Code project is to create a strong and compelling Settings API in toga core that is then also implemented in toga.cocoa and toga.iOS.
Implementation
I’m dividing the Settings API implementation into two stages. Conceptualising and Implementing.
Conceptualising the Settings API
Because Toga aims to be platform independent, what also includes it has to be device independent (pc, mobile), we have to create a Settings API that considers for all of that. In https://github.com/pybee/toga/issues/90 I go into great detail about the main challenge of creating a Settings API that works on mobile as well as on Desktop. Some issues to resolve are.
- What are the minimum properties that a settings widget needs? Find common denominator between platforms.
- Translation of widgets that only exist on mobile or desktop
- At what point in time are the settings created? During runtime or before compile time (like iOS requires)?
- Setting and getting of settings values.
How is the end user going to experience the Settings API?
On key feature of Toga is its use of native widgets that makes the user feel at ‘home’ on his/her platform machine. The Settings API should not be any different. Users are going to find and open their preferences on the same locations that are normally used for settings. (File > Preferences on Mac, Settings App on iOS …). The Settings API is also going to provide functionality to save settings in a platform nativ fashion (.plist files on osX/iOS, .xml for Android…).
How is the developer going to use the Settings API?
Another big challenge is to design the Settings API to be easy and a pleasure to use for whom which are actually going to use it - the developers. Some aspects that I have in mind are:
- Make it a simple and a streamlined process to create settings though the use of context managers (
with
). - Give the developer a elegant way to set and get settings values and the possibility to define a function that is called on value change.
- Make it easy to save settings to platform native places.
- Give the possibility for application settings as well as project settings.
- Give a simple solution for settings migration to support versioning.
Under the Hood - a glimps of the implementation
To give a better understanding of how I envision the implementation I give some use cases.
Standard way to use Settings API
import toga
# Instantiating the settings class takes care of creating the settings window/view.
# All the platform specific bootstrapping should be taken care of and set to native defaults.
settings = toga.Settings()
# A the settings group should have a label and the possibility to add a icon to it.
group = toga.SettingsGroup('General'. icon='icon.png')
# creating setting item
switch = Switch(label='Show line numbers')
# adding setting item to the setting group
group.add(switch)
# adding group to settings
settings.add(group)
# add settings to app
app.settings = settings
# you should be able to open the settings window/view by just calling the open() function.
app.settings.open()
Elegant way of using the Settings API:
with app.Settings:
with toga.SettingsGroup('General'. icon='icon.png'):
# add all settings items for this group
toga.Switch(label='Show line numbers')
toga.Slider(label='Nr of lines to show')
toga.Switch(label='...', ...)
...
with toga.SettingsGroup(...):
toga.Switch(label='...', ...)
...
app.settings.open()
How can other toga contributors integrate the Settings API on their platforms.
I’m aware that there is a universal outside the Apple galaxy and we need to support other platforms as well. I picked macOS and iOS just because I’m comfortable developing for those platforms. I already included Android into my considerations how the core Settings API should look like to not exclude any platform or even make it hart for them to implement the developed Settings API.
As I mentioned in https://github.com/pybee/toga/issues/90 I want a clean Interface between toga.core and the respective platform integration of the Settings API. This interface converts the defined settings in code to a normalised form. That form is then passed to the platform specific integration of the Toga Settings API integration. This is best explained with a simplified example.
# 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)
After the definition, the platform specific integration of the Toga Settings API, calls the get_normal_form()
function to receive the normalised form of the before defined settings, which looks like this:
# When printing the normalised 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 agreed upon normalised form than acts as the base for all the system specific integrations. For example, a Android developer can now translate this dictionary to a suitable and platform native representation for a settings view.
The normalised from has the nice side effect that we can easily save it as a platform independent settings file (For example as a xml or json file). This allows also for settings syncing over cloud solutions.
Timeline
>>> GSOC.community_bonding('May 4 - 30, 2017')
- Dive deep into existing native Linux, Windows and Android integration for their settings APIs to find a common denominator and don’t exclude any platform though an avoidable design mistake.
- further development of the normal_form
- discussions with the community
- research about how to set up a expandable and good structured testing system for a project like toga
>>> GSOC.week(1, 'May 30 - June 2')
- Setting Up a basic inward facing test system for toga core.
- Setting up a test structure for the upcomming Settings API core classes.
- toga.src.core.Settings
- toga.src.core.SettingsGroup
- toga.src.core.SettingsItem
>>> GSOC.week(2, 'June 5 - 9')
- Implementing
class SettingsItem
with- switch
- text field
- single value pick
- mule value pick
- slider
- translating SettingsItem to normal_form
>>> GSOC.week(3, 'June 12 - 16')
- Implementing
class SettingsGroup
- Group icon
- tranlate to normal_form
- functionality to add SettingsItems
>>> GSOC.week(4, 'June 19 - 23')
- Implement
class Settings()
- how to distinguish between project and application settings
- tranlate to normal_form
- show() to open settings window/view
- add Settings group
>>> GSOC.week(5, 'June 26 - 30')
- Implement
- Settings extraction
- save platform independent settings format
- load settings from file
>>> GSOC.week(6, 'July 3 - 7')
- Implement
- versioning and migration
>>> GSOC.week(7, 'July 10 - 14')
- Prepare and modify macOS widgets
- enable widgets to have an on_change callback
- Integrate missing widgets
- slider
- switch
- multi-value element
>>> GSOC.week(8, 'July 17 - 21')
- Implement Settings API for macOS
- translate normal_form into platform native widgets
>>> GSOC.week(9, 'July 24 - 28')
- Prepare and modify iOS widgets
- enable widgets to have an on_change callback
- Integrate missing widgets
- slider
- switch
- multi-value element
>>> GSOC.week(10, 'July 31 - August 14')
- Implement Settings API for iOS
- translate normal_form into iOS Settings Bundle
>>> GSOC.week(11, 'August 7 - 11')
- Implement iOS settings bundle creation into briefcase
- iOS Settings Bundle has to be created before app compile time
>>> GSOC.week(12, 'August 14 - 2')
Because the iOS documentation recommends a custom UI for frequently changed preferences instead of the settings bundle, I’m going to implement a solution that gives the developer the possibility to deploy their settings to a normal table view as well. In this form the settings view is just another view in the app and not part of the iOS Settings app.
- Implement iOS Settings API stage two
- translate normal_form into platform native widgets
About me
Hey Bees, thanks for reading my proposal. I’m Jonas and I studied Digital Media. Programming is not a requirement for my masters programs. This should show you that I don’t program because I have to but because I love to. Wait, am I then qualified you ask? Even though I’m mostly self taught I had my fair share of university programming courses.
I tried to keep the proposal short, if a more detailed explanation is desired I am happy to expand on any subject.
I look forward to feedback and comments.
Academic History
University of Applied Sciences Düsseldorf
Acquired my Bachelors Degree in Media Engineering. First contact with C and Java and the beginning of my interest for programming.
Drexel University Philadelphia
Because of the performance during my bachelors program I was able to get funding though the Fulbright Foundation. This funding enabled me to study for one year at Drexel University in Philadelphia. I was enrolled in the Digital Media masters program, which was focused on different domains in the field of Digital Media (Game Design and Programming, Interactive Web-development, 3D-Animation and Rendering and Media Theory).
University of the Arts Bremen & University of Bremen
At the moment I am completing my masters degree in Digital Media. My studies here are a joint program of two universities. The University of Bremen, which is responsible for the informatics part of the program and the University of Arts which is dedicated to the media theory and artistic part of the program.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:11 (11 by maintainers)
This proposal was accepted for the 2017 GSoC. Project progress updates will be posted here by @Ocupe.
@danyeaw I don’t see a reason. Let’s clean up 😃