User Settings

Involved development of the OpenMW construction set.
graffy
Posts: 142
Joined: 06 Feb 2013, 19:30

Re: User Settings

Post by graffy » 28 Mar 2013, 12:46

Zini wrote:I don't think this link is applicable here. The idea about plugins was to use a python as a scripting system, which would totally bypass all of Qt.
Looking at the docs, it appears the lower-level API might be well-suited for our needs, at least here. It would be nice to leave all of the property page layout in the hands of the plugin devs. We'd provide a base settings page class from which their custom pages must be derived, along with some helper functions for signaling and other stuff. We would only need to instance whatever settings page they've built, attach it to the tab widget and connect the signals and slots... Of course, this means everyone's creating a unique class for each settings page, but at this point, it seems much less of an issue to me than it did before. Frankly, I see it as a great solution for what we're dealing with here - why not use it?

Also, regarding sections being equivalent to pages, I think that will be the best assuming that the plugin sections do not require sections of their own (sub-sections, I suppose). Even with a moderately complex settings file, I don't see that we'd ever need to do anything different.

User avatar
Zini
Posts: 5134
Joined: 06 Aug 2011, 15:16

Re: User Settings

Post by Zini » 28 Mar 2013, 13:16

Looking at the docs, it appears the lower-level API might be well-suited for our needs, at least here. It would be nice to leave all of the property page layout in the hands of the plugin devs. We'd provide a base settings page class from which their custom pages must be derived, along with some helper functions for signaling and other stuff. We would only need to instance whatever settings page they've built, attach it to the tab widget and connect the signals and slots... Of course, this means everyone's creating a unique class for each settings page, but at this point, it seems much less of an issue to me than it did before. Frankly, I see it as a great solution for what we're dealing with here - why not use it?
This stuff is for Qt Plugins. I don't think that is what we want. In the context of the CS I see a plugin as a python script, optionally with additional resources files.

Maybe I am reading the documentation wrong and Qt can be used in this way. I have no experience with the Qt Plugin system. Anyway, that is a post 1.0 feature. We will investigate how to deal with it after we have 1.0 out. I only mentioned the plugin issue to illustrate the possibility of a potentially unlimited number of settings pages. We probably shouldn't put too much thought into it at this point.

User avatar
pvdk
Posts: 517
Joined: 12 Aug 2011, 16:34

Re: User Settings

Post by pvdk » 28 Mar 2013, 13:45

graffy wrote:Looking at the docs, it appears the lower-level API might be well-suited for our needs, at least here.

Yes I was thinking the same, that's why I linked it.
graffy wrote:It would be nice to leave all of the property page layout in the hands of the plugin devs. We'd provide a base settings page class from which their custom pages must be derived, along with some helper functions for signaling and other stuff.
Don't forget automatic signal/slot connecting, it could be useful here. See this.
graffy wrote:Of course, this means everyone's creating a unique class for each settings page, but at this point, it seems much less of an issue to me than it did before.
Or merely a subclass of a basic settings .ui file.

graffy
Posts: 142
Joined: 06 Feb 2013, 19:30

Re: User Settings

Post by graffy » 29 Mar 2013, 01:36

As it stands then, I'll probably build a SettingsPageBase class, but otherwise will just continue with the class-per-page system as we have been... Not knowing how the future will work out, that seems like a reasonable position at this point.

graffy
Posts: 142
Joined: 06 Feb 2013, 19:30

Re: User Settings

Post by graffy » 05 Apr 2013, 05:02

Ok,

So, I've prototyped the user settings dialog. In so doing, I've actually built a class which (somewhat) dynamically generates user settings widgets.

Here's a sample using just the four settings thus far identified for the editor:
usersettings1.png
User settings prototype
There are some basic formatting constraints I imposed in an effort to keep the code as manageable as possible. The basic rules are pretty simple:

1. Property widgets are right-aligned with corresponding labels left-aligned.
2. Each property is encased in a group box whose title bears the property's name in bold.
3. Each tab bears the name of each property section.
usersettings2.png
Widget component descriptions
The few settings we have identified for the editor actually gave me a chance to design for a fairly complex layout. For example, in many cases, a property will simply consist of one widget (or a group of widgets - like radio buttons) to manage the property value. The "Undo Stack Size", "Maximum Top-Level Windows", and "Re-Use Sub Windows" properties demonstrate this.

However, the "Default Window Size" property has two additional complexities: a "composite widget" nested within a "toggle widget group"

A "Composite Widget" is really a way to combine two separate properties in the same group. Technically, it consists of more than one widget which may represent more than one property. For example, suppose in the settings file there are two screen settings: WindowWidth and WindowHeight. There are two ways in which the user can specify these two properties - by choosing a default, pre-defined resolution, or by specifying the width and height separately.

Internally, three property widgets are created - a combo box for the pre-defined resolutions, and two line edits for the custom resolutions. The line edits are combined into a composite widget, and then the composite widget and the combo box widget are nested together on the right side of the "toggle widget group".

Note that I wrote the toggle widget group code so that a radio button or check box can be used for the toggling widget. Also, I've allowed for vertical / horizontal orientations of groups, widgets and labels at every level. Further, additional properties could easily be added below these initial ones, or alongside in a second column.

Notes on updaing / saving properties:

Using this design should help simplify linking widget changes to actual application variables and saving property values, as well as ensuring corrupted settings files are corrected.

Regarding saving settings, I do not intend to do any file writing until the user settings dialog is closed (via the missing "done" button). Property changes will update the application behavior immediately, but I felt it would be best to defer file writing until the user was done making changes altogether.

Further, I'm using the widgets themselves as the settings containers. That is, once the settings are loaded and the settings dialog is populated, the loaded settings are dumped. After the user makes whatever changes they feel necessary, the settings file is written by pulling values directly from the property widgets. This ensures that a corrupted settings file is corrected the next time the user attempts to edit it. (In fact, it could be triggered automatically and used to check for corrupted settings files, if that was ever necessary).

Note that I've written a wrapper class for the property widgets so that the property names in the settings file do not need to match the names which are displayed in the settings dialog. This is necessary for obvious reasons like in the case of the composite / toggle widget used to manage window size...

User avatar
Zini
Posts: 5134
Joined: 06 Aug 2011, 15:16

Re: User Settings

Post by Zini » 05 Apr 2013, 11:01

Nice. Quite a lot more than I expected. Looking forward to having it integrated into the CS.

I have a few points of critic:

1. The horizontal tabs are a no go (as discussed before). Maybe we should straight to a vertical arrangement, because currently it seems unlikely that we will get suitable icons for a horizontal layout.

2. I don't like the empty space on the right side. Too wasteful. Can we stretch the layout to take up all the space?

3. The UI looks a bit cluttered. I am okay with the horizontal dividing lines, but do we really need a frame around it?

graffy
Posts: 142
Joined: 06 Feb 2013, 19:30

Re: User Settings

Post by graffy » 05 Apr 2013, 11:38

Zini,

On your three points:

1. Tabs can be arranged any way you like. I'll set it up for vertical (left-adjusted) tabs.
2. The space is because the dialog doesn't currently size to the content. It's a small fix I hadn't bothered with yet.
3. And no, we certainly don't need a visual frame. However, in the case of multiple columns, I might consider a diminished vertical line separating the columns (much like the horizontal lines)...

Anyway, I've been crazy busy with seminars and travel, so I've had about no time to work on this in the last two weeks (and I developed most of this in the last two weeks, anyway :) ). Nevertheless, it all came together much more easily than I had anticipated, which is why I kinda went all out.

At this point, I think the class structure is good enough that we should be able to build other complex UI components ( much like the toggle widget group) fairly easily.

Also, I created a "SettingsDefinition" struct which contains the controlling parameters for building the property widgets (group title, default property value, label list, widget type, vertical / horizontal orientations, etc.). Presently, I use it to define the most basic widgets but haven't expanded it to manage the more complex ones - some further thought is required, there regarding potential widget heirarchy issues...

Nevertheless, the struct provides a fairly straightforward way of defining the page layout internally as well as providing a basic grammar roadmap for layout scripting system in the future, should we decide we wnat that.

User avatar
pvdk
Posts: 517
Joined: 12 Aug 2011, 16:34

Re: User Settings

Post by pvdk » 05 Apr 2013, 14:49

Very impressive graffy! I think some parts could be re-used for the launcher, at least the concept. For instance, using a composite widget for the custom resolution is clever, I wish I had thought of that instead of doing:

Code: Select all

customRadioButton->setEnabled(false);
customWidthSpinBox->setEnabled(false);
customHeightSpinBox->setEnabled(false);

graffy
Posts: 142
Joined: 06 Feb 2013, 19:30

Re: User Settings

Post by graffy » 05 Apr 2013, 18:30

Yeah, I've played around with this sort of things a few times in personal projects - beleive it or not using the VBA backend of MS Office. Given that VBA is VB6-lite, there's surprisingly much you can do with that.

Anyway, I'm going to tear it apart and rebuild - wasn't quite modular enough, but I'm definitely on the right track. The simplicity is in constraining the layout and piecing everything together, building-block style. Shouldn't be a big deal, though.

graffy
Posts: 142
Joined: 06 Feb 2013, 19:30

Re: User Settings

Post by graffy » 20 Apr 2013, 17:15

Ok, so I've got the UI modular components done. I did some pretty significant reorganizing, but it's overall similar to what I had before.
image3063.png
Overview of UI hierarchy
The UI is broken down into types of "blocks", with the setting data managed in "items".'

ItemBlock

The smallest block in the UI. It is synonymous with a single user setting. It contains the necessary widget(s) for the single setting and a reference to the setting data structure that is used for reading / writing.

Group Block

This block may contain one or several item blocks, and may or may not be the top-most block within a section.

Toggle Block

This is a customized Group Block. Most customization takes place in custom group blocks like the toggle block. In this case, the toggle block generates a toggle widget (either a radio button or check box) for each group block that it is passed.

Proxy Settings

Also note that the top group block on the right side of the toggle block (the pre-defined window size combo box) does not contain a legitimate setting, but rather a setting proxy. That is, the proxy is defined with a list of settings which are bound to it. Changes in the proxy update the underlying setting item values (in this case the individual screen width and height settings).

Section Block

The topmost block in the UI hierarchy. Correlates directly to a section in the configuration file.

Remaining Tasks

At present, the UI part is essentially complete. Unfortunately, there is no way to place tabs on the side of the tab widget while maintaining horizontal text in Qt. If there is, it'll take extensive work to pull it off, I think.

What remains is the save / load mechanisms that will update / retrieve the user settings. Also, a mechanism to signal the OpenCS Editor for changes in it's properties.

Finally, I did stub in some signal code for future expansion which will allow devs to retrieve values for settings in other sections - in case the plugin's settings depend upon the state of other plugins. It's by no means complete, but there because it seemed like a really good idea to me

There ya go. Brief overview. I don't know how soon I'll be done, but I'm hoping by the end of next week at the latest.

Fire away with questions or suggestions...

Joel

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest