3. GUI Design Considerations

Involved development of the OpenMW construction set.
Locked
User avatar
lgromanowski
Site Admin
Posts: 1193
Joined: 05 Aug 2011, 22:21
Location: Wroclaw, Poland
Contact:

3. GUI Design Considerations

Post by lgromanowski »

Zini wrote: 3a. Multi-Document-Capacity

Every editor should be able to handle multiple documents at once (without starting a second copy of itself). The reason for this design rule are manifold.

First, for most editor types it is obvious that you want to be able to edit more than one document at a time. What might not be so obvious is that this is true for the CS too. Reuse of existing stuff is extremely common in the MW modding community. A usage scenario would be a plugin, that already implements a feature, that you want in your own project. Since copying it directly might not be viable, you will want to have the plugin open in a separate window alongside your own project.

Second, running multiple instances of the editor can cause all kind of problems. One example would be a race-condition when writing user preferences to disc.
In our case there is another argument. Currently all mods and TCs use the same resources file directory tree (textures, meshes and such). That means usually if you have two group of master/plugin files, the intersection of the resources used by these two groups will be non-empty. In most cases it even will be pretty big. By running only one instance we can make OGRE load these shared resources only once. That is potentially a huge optimisation.

And thirdly, implementing this feature is completely trivial. Usually. Just avoid document-related static variables and close the application when the last document is closed.

There is a problem with this approach though. OGRE insists on a primary rendering context (i.e. a rendering window/widget). Once this is gone, OGRE can't continue to run. This won't work with two documents open at once in the same instance, when they are closed in the wrong order. Actually, this problem will bite us in a few more cases (see 3b and 3c).

There are two possible workarounds:

I. AFAIK OGRE 1.8 fixes this problem. Just waiting for the next major OGRE release should sort everything out. If we do the rendering components last, we may not even have to wait.

II. When the primary window/widget is closed, close all rendering widgets. Shutdown Ogre. Startup Ogre again and recreate all rendering widgets. More work and probably slower, but should work with 1.7.


3b. Model <-> View is a 1 <-> n relation

This is a very old feature and I am rather surprised, that it hasn't caught on more. Of all major applications I can only name three that do support it (OpenOffice, Inkscape, Gimp). Its a shame, because this is an incredibly useful feature and once you got used to it using an application without it, is about as comfortable as using an application without copy & paste functions.

Here are some usage scenarios related to the CS:

I. Multiple 3D rendering components

You definitely want these. To compare two locations. To view a location from multiple viewpoints at once.

II. Multiple ID lists

Now we discussed already that ID lists should be filtered. That means you need different filter settings during an editing session. You can simply switch filters within one view. But having multiple specialised palettes open at once will make worldbuilding much easier.


We could continue like this and argue for each editing component why having multiple views can be useful. And I am sure, if we look around long enough, we will find arguments for each component. So just lets make this short and declare that all models should have multiple views.

Again this feature should be pretty simple to implement. If we ignore the primary rendering context problem, OGRE delivers it out of the box and I hope Qt does the same.


3c. Don't force everything into one window

Not everyone works in the same way. Being configurable is a very important feature of a GUI.

Keep in mind that not everybody is comfortable with working in maximized/full-screen mode. Some people prefer to have individual windows that can be moved around individually on their desktop. Also people may want to spread out their stuff across multiple workspaces. And finally, some people have multiple screens. Having a few editing components on one screen and a few others on the second can be pretty useful.

This is already true for a much more simple type of editor. But our CS consists of collection of semi-autonomous sub-editors with only loose coupling. Maximum flexibility is a must here.

We may use some kind of docking system (either tabs or sub-windows or both) to satisfy the needs of people with only one screen and one workspace. But it must be unobtrusive and not get in the way of a more distributed workflow.

One possible way to implement this is to have a top level window (any number of top level windows), that acts as a container for one or more editing component. In this case the editor needs a setting that determines, if a new editing component is opened in a new window or in the same. Maybe even some more fine-grained settings would be useful.


3d. Modal dialogues are evil

Most usability guides today try to downplay the role of modal dialogue. The general advice is to not use them if you can avoid it.

I'll add my personal position on this:

"GUI developers should avoid modal dialogues at all cost. Those that don't follow this rule, should be hunted down, skinned alive and then slowly be roasted."

You can quote me on this, if you want.

The reasons against modal dialogues should be obvious. A modal dialogue can block the workflow badly. Its also extremely unintuitive.
We should try to minimise the use of dialogues in general, but especially we should avoid modal dialogues.
sir_herrbatka wrote: Beer for Zini! 8-)

Yes, yes, yes. I agree, you are RIGHT.
pvdk wrote: My, a long post. First of all, I agree with most of it :)
Some additions:

3a. You point out a problem with Ogre needing a primary render widget. I had a look at Ogre and I don't remember encountering this. I used an Ogre::Root object and createRenderWindow(). I would have to try it out later but I believe the Ogre::Root stays there when the render window is destroyed.

Our approach might look like this:
Create MDI and Ogre::Root object, create render window subwidget, when document gets closed destroy it's render widget but keep Ogre::Root.

3b. Could you elaborate on what you mean here? If I understand this correctly you are referring to one of Qt's main strenghts, namely the Model/View framework. Basically it works like this: you have a model (ex: ID list) this model can have proxy models doing filtering/sorting without modifying the original data. The model can also have different types of views for showing and editing the data.

3c: I can see something like this working: dialogs are by default subwindows inside the MDI, but can be "disconnected" from the MDI area and act like a normal dialog, with it's own taskbar entry etc. That way the user can put windows on different (virtual) desktops.

3d: Yes I agree, with the possible exception of input dialogs but that's not what you are referring to here I believe. If I recall correctly the original CS had quite a few modal dialogues which always needed some information which could only be found in another window. Hated it!

Another thing: You talk about being able to edit/view different plugins at the time (without having multiple instances of OpenCS?)
I was thinking of something like multiple project windows with each their own MDI interface but I can't think of a sensible way to do this.

Well, like sir_herrbatka said, time for Bier!
Zini wrote:
3a. You point out a problem with Ogre needing a primary render widget. I had a look at Ogre and I don't remember encountering this. I used an Ogre::Root object and createRenderWindow(). I would have to try it out later but I believe the Ogre::Root stays there when the render window is destroyed.
That is not a problem of Ogre::Root, but the underlying rendering systems. By default, once the first window you open with Ogre is closed all other rendering windows are toast. There is at least one thread about it on the Ogre forum. At least with earlier versions of Ogre this was a problem, but I am pretty sure it has not been addressed in 1.7.
3b. Could you elaborate on what you mean here? If I understand this correctly you are referring to one of Qt's main strenghts, namely the Model/View framework. Basically it works like this: you have a model (ex: ID list) this model can have proxy models doing filtering/sorting without modifying the original data. The model can also have different types of views for showing and editing the data.
Good to hear. I primarily meant Model/View implementations for common Widget types like treeviews, tables and textviews.
3c: I can see something like this working: dialogs are by default subwindows inside the MDI, but can be "disconnected" from the MDI area and act like a normal dialog, with it's own taskbar entry etc. That way the user can put windows on different (virtual) desktops.
Please don't say dialogue. We should avoid dialogues. Lets stick with the term component.
What you describe is one way to handle it, but I think it would be better, if we can put these detached components into new top-level windows instead so we have controls like the main menu available everywhere.
3d: Yes I agree, with the possible exception of input dialogs but that's not what you are referring to here I believe.
No exceptions. Modal dialogues should be banned from desktops. Completely. Blocking the entire application, because of a single dialogue is an atrocity.
Another thing: You talk about being able to edit/view different plugins at the time (without having multiple instances of OpenCS?)
I was thinking of something like multiple project windows with each their own MDI interface but I can't think of a sensible way to do this.
Think of it as running two instances of the editor in parallel. Each with a completely separate set of windows. And then change the implementation so that it is internally running in one process.
pvdk wrote:
Zini wrote:Please don't say dialogue. We should avoid dialogues. Lets stick with the term component.
What you describe is one way to handle it, but I think it would be better, if we can put these detached components into new top-level windows instead so we have controls like the main menu available everywhere.
Sorry, I won't. Hadn't read your framework post yet when I replied.
Hmm so you want to be able to move subwindows from one MDI to another? Don't know if that's possible.
Zini wrote:No exceptions. Modal dialogues should be banned from desktops. Completely. Blocking the entire application, because of a single dialogue is an atrocity.
Let me clarify what I mean with input dialogs: Open file, Save File and the New Profile name entry dialog you can see in the launcher. Should they be non-modal?
Zini wrote:Think of it as running two instances of the editor in parallel. Each with a completely separate set of windows. And then change the implementation so that it is internally running in one process.
So you would have an underlying editor with multiple mainwindows. Could be done I think. I was thinking of having different projects in a horizontal tab structure with their own MDI area below. (With the tabs being detachable to create new mainwindows)

Not unlike this:
http://alt.dailyautocad.com/wp-content/ ... /mdi-3.png
Zini wrote:
Hmm so you want to be able to move subwindows from one MDI to another? Don't know if that's possible.
That would be bad. Having only a single main window is quite limiting. I could come up with tons of usage scenarios, but honestly I am too sleepy now.
Let me clarify what I mean with input dialogs: Open file, Save File and the New Profile name entry dialog you can see in the launcher. Should they be non-modal?
Absolutely! Why anyone would ever want these to be modal is completely beyond me.
So you would have an underlying editor with multiple mainwindows. Could be done I think. I was thinking of having different projects in a horizontal tab structure with their own MDI area below. (With the tabs being detachable to create new mainwindows)
The editor will be complex enough already. Let's not increase the complexity further by mixing multiple plugins in the same window.
pvdk wrote:
Zini wrote:That would be bad. Having only a single main window is quite limiting. I could come up with tons of usage scenarios, but honestly I am too sleepy now.
No need for usage scenarios, I get it. I looked it up and it's possible to drag and drop between applications. Problem: QMdiSubWindows usually can't leave their QMdiArea. Possible solution: subclass QMdiSubWindow to imitate some behaviour of QDockWidget (provides a widget that can be docked inside a QMainWindow or floated as a top-level window on the desktop.)

Who said impossible? Just hard it is!
Zini wrote:Absolutely! Why anyone would ever want these to be modal is completely beyond me.
Where did it go wrong :) Is it because of RISC OS? Welll non-modal it is.
Zini wrote:The editor will be complex enough already. Let's not increase the complexity further by mixing multiple plugins in the same window.
True dat. Good night Zini!
pvdk wrote: Yesterday I was in the process of writing a lenghty post when my computer crashed (bad ram). Here's what I recall writing:

Since the launcher is mostly done I can shift my attention a bit towards the editor. I made a quick mockup of some ideas I would like to share:

Image
(Bear in mind: it's a mockup, disregard names etc.)

Basically the Components view is a dockable widget (so you can move it around) with all the available components in it. I used a list view but I think we should use a tree widget to show sub-catagories like Item Component - Weapon. When the user double-clicks on one of the components in the list, a new window gets created with a table containing all the items of that component. This view window is a generic widget subclass, so it's the same for every component. When a user double-clicks on one of the items in the list, a new window gets created for editing/viewing that particular item. This window is different for each component, as you need to be able to do different things for each item type.

What's not in the mockup and what I would like to implement is: Lock/unlock for each component, just like you can lock layers in Photoshop. I have some ideas how to show this in the created windows but that's stuff for later.

All the created windows show up in the Window menu, just like Photoshop. You can also have a Window dockable widget, wich shows all the created windows.

I hope this makes sense and that I used the correct terminology. I found out that Qt Designer allows switching (on-the-fly) between MDI-mode and Multiple top-level windows mode. This is something we can implement too, along with the ability to detach single windows.

Another thing: I recently figured out how to put Ogre in a QMdiSubWindow.
The window accepts basic input (zooming) and is resizable. This code and the stuff I learned from it could be helpful for implementing the render window. However, the code is in a branch named opencs, and the files also bear that name. I will change this and push it to my github if there's interest for it. In the mean time, here's how it looks:

Image

Should there be a separate thread for the render window component or is it too early for that?
Zini wrote: The screenshot looks like the MDI interface you could find on early Microsoft stuff (around Windows 3.11). I may be misinterpreting it, but these subwindows look like they are copying the window-metaphor with the parent-window functioning as an equivalent to the full desktop. I really thought we were beyond this kind of folly. My personal position on applications with this kind of interface is that I will uninstall them instantly.
The way the two sub-windows to the left are docked looks somewhat more sensible. Maybe we can use this method?

Regarding the component view: Not so sure if it makes sense to have it as a persistent window. After all the user will make us of it only occasionally and as such it is wasting screenspace. Maybe make it into something like a pop-up men??? Or simply an entry in the main menu? Also, I don't see anything in our component list, that would require a tree structure.

Also, please keep in mind, that not all top-level components contain lists.

Regarding the window list: I am not convinced that this is a useful feature. After all every desktop should provide the user with means to navigate between windows. We don't need to duplicate this functionality in the editor. At least I would expect this window to be optional, because again it is wasting screen space.
What's not in the mockup and what I would like to implement is: Lock/unlock for each component, just like you can lock layers in Photoshop. I have some ideas how to show this in the created windows but that's stuff for later.
I am not sure, if I understand what you mean. Sorry, never used Photoshop. If it is the same as in GIMP and you mean it as a user-invoked action, then I don't see what it would be used for. On the other hand, as I wrote somewhere else, the ability to lock components (or the model behind components) programmatically would be useful (e.g. the save scenario).

Regarding OGRE: This is one of the more complex topics. There is still the issue with the primary rendering context and the question of threading (which will have a huge impact on how OGRE is integrated into the CS). While we could start working on it now, I suggest we wait until we have the other basics of the framework sorted out.
pvdk wrote:
Zini wrote:I may be misinterpreting it, but these subwindows look like they are copying the window-metaphor with the parent-window functioning as an equivalent to the full desktop.
You're right on that, as I pointed out before: MDI subwindows don't have their own taskbar entry, they are not top-level windows but the MDI area is their "desktop," just like you interpreted it.
Zini wrote:My personal position on applications with this kind of interface is that I will uninstall them instantly.
That's why I proposed to implement the ability to switch between MDI-mode and top-level windows mode (latter = GIMP). As I personally dislike the top-level windows approach. I always loose my windows and close the wrong ones when I try to exit such app.
Zini wrote:The way the two sub-windows to the left are docked looks somewhat more sensible. Maybe we can use this method?
An app I know of which uses this method is Qt Creator:
Qt Creator
Zini wrote:Regarding the component view: Not so sure if it makes sense to have it as a persistent window. After all the user will make us of it only occasionally and as such it is wasting screenspace. Maybe make it into something like a pop-up men??? Or simply an entry in the main menu?
The window is not persistent, it's a dockable widget :) I was inspired by this piece of software:
Gluon Creator
I don't like the idea of a popup menu and components should be easily accessable without too many clicks. Also, it should be directly visible to the user, not hidden in a popup or in a menu.
Zini wrote:Also, I don't see anything in our component list, that would require a tree structure.
I was thinking of components with sub-catagories like this: Item Component which expands (should be expanded by default) and shows the available sub-catagories like Weapon, Book etc.

You're right about some components not containing lists, will keep that in mind.
Zini wrote:Regarding the window list: I am not convinced that this is a useful feature. After all every desktop should provide the user with means to navigate between windows. We don't need to duplicate this functionality in the editor. At least I would expect this window to be optional, because again it is wasting screen space.
Yeah like I said in my previous post: it's optional. Windows would appear in the Window menu and this dockable widget can be added. But with the MDI approach you need something like that to manage the MDI subwindows, because the desktop is not the parent of the subwindows, the MDI area is.

About the ability to lock components. I thought this would be a useful feature to put some components in read-only mode. That way you can mess around with the components without fearing for accidental modifications to data you don't want to be modified. I was referring to the "layers pallette" of Photoshop, which looks like this:

Image

You see there's a little lock icon on the right of the layer name, and a lock toolbutton above it. GIMP has a similar feature but doesn't show a lock icon.
Also, as you can see in the Qt Creator screenshot, there's a lock icon in the top-right corner of the file currently being edited. Something like that was what I figured would work with the individual item edit components and the list views. But maybe you're right, maybe this is not a useful feature at all.

OGRE: I looked at the code of a Qt-based editor for OGRE, called Ogitor. They don't use a thread for the render window, and I think it would only make our editor overly complex. I believe GUI lockups won't be a problem, just because of the way Qt works. But let's put it to rest for now.
Zini wrote:
An app I know of which uses this method is Qt Creator:
Qt Creator
That looks more sensible (if you like the everything-in-one window approach)
I don't like the idea of a popup menu and components should be easily accessable without too many clicks.
Funny. I was going to use the same argument, but for the opposite position.

Popup window (at mouse pointer location), accessable via keyboard-shortcut. Keypress, small mouse movement, one click -> done. It doesn't get any faster. After all, you also have to factor in the mouse movement distance.
Also, it should be directly visible to the user, not hidden in a popup or in a menu.
I guess we have to agree to disagree here. My position is that the amount of visible controls should be minimized to preserve screenspace and to reduce visual clutter.
I was thinking of components with sub-catagories like this: Item Component which expands (should be expanded by default) and shows the available sub-catagories like Weapon, Book etc.
I understood that. But per previous discussion we decided not to have these
kind of categories with sub-categories (Weapon lists, Book lists and such will be all merged into one component)
About the ability to lock components. I thought this would be a useful feature to put some components in read-only mode. That way you can mess around with the components without fearing for accidental modifications to data you don't want to be modified. I was referring to the "layers pallette" o
Okay, then I did understand you right. Well, I still fail to see an actual usage scenario. The layer stuff makes sense, because the layer all share the same window and you need a way protect them from accidental changes. But in our editor every component has a separate (sub-)window. There isn't really a change of an accidental change, unless you consider the possibility of your cat walking over your keyboard a real problem.
I believe GUI lockups won't be a problem, just because of the way Qt works. But let's put it to rest for now.
I can almost guarantee you, that it will be a problem. But yeah, let's put it to rest for now.
pvdk wrote:
Zini wrote:That looks more sensible (if you like the everything-in-one window approach)
Today I got myself a book on GUI design, Designing Interfaces from O'Reilly. I will do some reading and get back to you on this :)
One thing I would like to show you in mean time is MDI in tabbed view mode. It's one of the two view modes for Qt's MDI area and a good example is Opera, with the right settings enabled:

Image

In this mode the windows get tiled automatically, but the user can choose the way they are tiled or no tiling at all. The windows all have a tab which can be clicked to focus on that particular window or dragged to detach the window from the MDI area. This would eliminate the need for a Window dock widget and would offer the advantages of MDI applications without the troubles with subwindows overlapping eachother or getting lost. The user can also maximize the window, which could be useful for the render window for example, while allowing switching between the item component tab (I know this is not ideal) or having a separate item component window.

Opera also allows for tabs being stacked. I haven't tried that one out but I will when I get home. What I imagine we could do is: Grouped tabs with a number of subwindows in it would essentially be separate MDI areas residing in a tab. That way you could have a tab with a render window, a cell window and an item window, all tiled in a single view. In another tab group you could have subwindows for entirely different editor components.
Zini wrote:Popup window (at mouse pointer location), accessable via keyboard-shortcut. Keypress, small mouse movement, one click -> done. It doesn't get any faster. After all, you also have to factor in the mouse movement distance.
Maybe we could use a "collapsable" sidebar instead, that way you have quick access to the list of components while still preserving maximum screenspace. The sidebar should still be a dock widget or a panel so it can be moved or removed. In top-level window mode it should convert to a tool window.

The collapsed view could show icons for each component. Something like this:

Image
Zini wrote:I understood that. But per previous discussion we decided not to have these kind of categories with sub-categories (Weapon lists, Book lists and such will be all merged into one component)
I'm sorry, I must have missed that. However, that raises the question of how to show them in the viewer components.
Zini wrote:Well, I still fail to see an actual usage scenario. The layer stuff makes sense, because the layer all share the same window and you need a way protect them from accidental changes.
You're right, no apparent need for it. And if it turns out there is, then we still have the GUI locking feature used for saving, which could easily be turned into something which can be enabled/disabled. However, as "dirty" mods is a problem modders encounter, we should add some functionality to resolve this (as was discussed). We could do some basic cleaning by default on saving or enable advanced users to select what modified references get saved.
Zini wrote:I can almost guarantee you, that it will be a problem. But yeah, let's put it to rest for now.
I know we agreed to not talk Ogre integration anymore but one thing I would like to point out: Ogre is not thread-save. That doesn't mean of course that we can't put it in a thread, but it does mean that other threads won't be able to communicate with Ogre. I don't have experience with multi-threaded apps, so I'm not sure if this matters. I just wanted to point it out as I recall you proposed to put the file saving operation inside a thread.
Zini wrote:
One thing I would like to show you in mean time is MDI in tabbed view mode. It's one of the two view modes for Qt's MDI area and a good example is Opera, with the right settings enabled:
...
I guess the interface you are proposing is okay.
Maybe we could use a "collapsable" sidebar instead, that way you have quick access to the list of components while still preserving maximum screenspace. The sidebar should still be a dock widget or a panel so it can be moved or removed. In top-level window mode it should convert to a tool window.
Doesn't convince me. Still has most of the disadvantages I mentioned in the previous posts. Maybe just use a dockable window, that can be opened/closed via a keyboard shortcut?
I'm sorry, I must have missed that. However, that raises the question of how to show them in the viewer components.
If you mean the table view, we had some discussion about that in other threads too. We still need to look into the details. But that is something we can address later.
I know we agreed to not talk Ogre integration anymore
Looks like that is not going to work ;)

I know that OGRE is not thread-safe. But that doesn't stop us from using it in a multi-threading application. Just put it in one thread and don't touch it from outside this thread.
pvdk wrote:
Zini wrote:I guess the interface you are proposing is okay.
Hurray!
Zini wrote:Doesn't convince me. Still has most of the disadvantages I mentioned in the previous posts. Maybe just use a dockable window, that can be opened/closed via a keyboard shortcut?
Possible, we might also use a drop-down box in the toolbar and implement "add window" functionality in the tab bar, just like Firefox/Opera, with a + icon. Maybe even add a context-menu to the MDI area (should also have options like tile windows horizontally/vertically). I mean, the current cursor position is the best place for such menu to be.
Star-Demon wrote: Random thoughts:

- A button to move a selected dialogue response to the top of the list. This is done a lot when writing dialogue for NPCs, and would help a lot.

- Easier "create new from existing" function for items, allowing easy addition of items with the same meshes and textures.
Rhys wrote: What about having areas that can be split the further split to create whatever layout (horizontal or vertical), which are resizeable and can be assigned to display any component of the editor. The layout can be saved and switched between for different tasks.
Ala Blender. http://www.youtube.com/watch?v=AMBi1R7KB48
Image
Star-Demon wrote: If we decide have that, it'd be better if we had something like MSVC's easy-clip control for manipulating and joining/splitting windows.
Locked