GEPS 019: Improved Sidebar and Split Views
This GEPS (Gramps Enhancement Proposal) is closed and available in the version of Gramps indicated below.
Finished included in Gramps 3.3
Several ideas are floating around to change the main interface of Gramps for 3.3. This GEPS collects these ideas and must result in a design document
Gramps 3.2 allows views as plugins. The main organization is now: The sidebar is used to navigate to categories, a category can contain several views.
- keep it simple for the user. There is no need to let him every time choose which person listview he wants to use. If he is in the person category, he uses the person listview he last viewed.
- no overload of views. Organizing the views in categories avoids an overload in the sidebar, eg, we don't want the interface to look cluttered
- The sidebar does not allow scrolling, while users can add plugins in new categories. In other words, we need to rewrite sidebar for the case there are more categories than fit on a screen
- Users might not discover the other views because they are only a button in the toolbar, sometimes hidden among a lot of other buttons
- You are on the person view, and want to move to the pedigreeview, but last view in the category was the fanchart
- You want to minimize the sidebar so as to have more space on your screen for data
- You want to embed some gramplets next to a person view
- You want to display a pedigree view below a person tree view
- Add use cases here
- menu: the top menu in Gramps. Reacts to the active view
- toolbar: the toolbar of the active view
- category sidebar: the bar to the left to select category/view in category.
- workspace: the widget holding the are where views/filtersidebar can be shown.
- main view: the primary view which is created with the workspace and cannot be removed. (the left view or the top view)
- secondary view: the extra view that can be added, changed or removed as per the users requirement.
- workspace sidepane: a sidepane that can be added to a workspace to hold eg the filter sidebar which can be added to listviews to filter the lists.
- active view: the view that has focus.
- Should a filter/query open up a new tabbed view?
- Should view widgets be able to send/receive all signals? Should that be configurable? For example, some gramplets can both send change_active signals and react to change_active signals. Should this be better thought about who is the controller, and who is along for the ride?
In version 3.2 we have the concept of a navigation group. All views and gramplets within the same group share the same signals. At present only a single group is used. Could this be useful in the design? - NH
How to configure a split view?
We should look at reuse the Options (aka Menu, Report Options) for the Configure View. We already have a set of gui widgets for gramps that allow one to set items for the reports and tools, and I've been using these for Gramplets, too, for the last year or two. It might take a little work to integrate with a Configure, but it should be worth it. Otherwise, we have to duplicate all of those widgets.
We should also work on a hierarchical Configure paradigm. It should be the case that a top-level object composed of many, small widgets should ask each of the subwidgets if they want to be configured, and they can report back their options. Workspaces should ask views for options, and views ask gramplets, etc. One can do this manually (see sidebarviews.py) but we can do better.
So, for example, a Workspace contains two views and gramplet sidepane. The Workspace would obtain configuration details from each view and the sidepane. The gramplet sidepane in turn would obtain details from each gramplet that it contains.
We may also want to abstract the ui_definition, and make it part of this future Configure. This could be an object that is added to/subtracted from, and displays the "<ui>...</ui>" when needed.
Split View prototype
There is a prototype in gramps-addons/code/branches/gramps32 :
This uses the following decisions:
- A split pane is either in vertical, horizontal, or no-split orientation
- A split view is composed of exactly the regular view and (optionally) a gramplet view
- The gramplet pane (if there is one) is either on the right, or below.
- A config file is composed based on the "Splitviews_NAME_gramplets.ini" in the root of version directory
- orientation, columns, and pane divider position are stored in the [Gramplet View Options] section.
- config file is a gramplet config file (needs to be updated to use new config)
- Pane divider position should be "-1" until manually set.
- There should be some thought into widget controls:
- should the widget/view emit a change-selected-object signal?
- should the widget/view listen to a change-selected-object signal?
- what about other signals?
This prototype was added to trunk in commit r15029.
- To make the Sidebar a plugin.
- To separate the Sidebar code from the View Manager code.
- To enable the use of multiple Sidebar plugins.
- A SideBar class was created to hold Sidebar plugins.
- A new SIDEBAR plugin type was created.
- A Sidebar plugin was written to provide the same functionality of the existing Sidebar.
- The View Manager loads the available Sidebar plugins at startup.
- Separating out the Sidebar code from the View Manager may be beneficial.
- Using more than one plugin with this approach could hide core functionality.
- Although the layout of the Sidebar itself needs improving, this protoype does not intend to do that. The idea was that by making the Sidebar pluggable, developers could experiment with designs more easily.
Multiple View prototype
This prototype is in the form of a patch which can be found on the Bugtracker issue 1644 (multiview.patch). If you add a note to this issue then I will provide a fresh patch.
- To allow more than one view to be displayed at the same time.
- To allow gramplets to be displayed alongside views.
- To investigate the concept of a Workspace.
- To assess the impact on existing code.
- A Workspace class was created to hold two views and a sidepane. The prototype has two views vertically one above the other and a sidepane to the right of them. There is no reason why the Workspace should not provide other layouts of the views and sidebar.
- The View Manager was modified to manage Workspaces rather than Views.
- A sidepane was created for gramplets. The gramplet pane uses the same code written for Doug's Split View prototype.
- Filter functionality was removed from the views and placed in the sidepane.
- A Workspace can only let one view control the main UI. The UI definition in views was split between the ui_definition method (which is used to hold the main UI) used when the Workspace considers the view 'primary', and the additional_ui_definitions method (which is used to hold the popup UI) used when the Workspace considers the view 'secondary'.
- For the prototype I have created one Workspace per View. This was for convenience and is not intended to be the final solution.
- A "Views" button was added to the toolbar to select a secondary view to add to a Workspace. For the prototype there is no way to remove a view from a Workspace. Benny suggested using the mechanism used by Dolphin which seems to be the way to go with this.
- No more than two views per Workspace are needed. By using the prototype it is clear that more than two views would not be practical.
- The filter sidebar needs to come out of views and placed as a separate sidepane in the Workspace. When developing the prototype I initially kept the filter sidebars in the views, but it didn't look right.
- To best utilise screen space the gramplet sidepane should share the same sidepane in the Workspace. The prototype demonstrates this.
- The prototype allows any view as the secondary view. It is possible to put a media view below a source view. This was done deliberately so that we could see how useful this might be. On using the prototype it becomes obvious that some combinations are more useful than others. Perhaps we should restrict the secondary view to be of the same navigation type as the primary view.
- We need to think carefully about how we create Workspaces and what Workspaces are created by default. I don't have an answer to this yet, but some ideas:
- Start with no Workspaces open and just an empty screen. The Sidebar will quickly and easily allow the user to open the Workspaces they require. Workspaces will be remembered on shutdown for use in the next session.
- As above, but with a few pre-defined 'core' Workspaces defined. Maybe some could be defined with more than one view. Perhaps the Sidebar could have some entries for pre-defined 'dual' views.
- One Workspace per category. Filter results could still open a new Workspace.
- We should give the option for users to close Workspaces. At the moment, in 3.2, all the views are opened when Gramps starts. Users may only want a few Workspaces / Views open.
- The new sidebar must be easy to use, and not in the way. There are ways to use split views, the sidebar should take this into account.
- We do not want to allow everything.
- We do not want to allow an eventview next to a noteview. First, the user must be protected from draining the resources of his computer. Second, we need to keep design simple. If there is no good use case, do not allow it
- We do not want more than two side by side views. It would be nice to allow the user to decide if vertical next to each other, or horizontal.
Several ideas for a reworked main interface. Focus is on usability, so how the use cases are handled
Design idea - 1
- Sidebar as vertically placed buttons with vertical text to choose category (scrollable if needed). Context menu to go to view in category immediately.
- Workspace to the right of sidebar
- Toolbar to the top of workspace. Holds icons to switch view in category, icons to split workspace, icons defined by the active view
Design idea - 2
The viewmanager is the controller for the GUI elements on the main view. It holds the category sidebar, the workspace, the menu, the status bar and the toolbar. These elements use the viewmanager API to do actions that concern them all. The broker is DisplayState with holds callbacks related to the GUI
These methods control creation, deletion and display of workspaces.
- create_page(plugin_data, view_class)
Best would be a signal before view will change, so all widgets can lock themselves and not emit other commands until the change is finished (??)
With multiple views the view manager becomes more like a workspace manager or gui manager.
Workspaces can display one or two views and a gramplet pane which may be hidden.
Workspaces act as controllers for the views and gramplets that they contain. When the display status of a workspace changes it will in turn notify the components that it contains.
Workspaces are responsible for obtaning the UI and configuration definitions from their components.
The following control the secondary view in the workspace:
The following control the pysical layout of the workspace components:
The following methods are called by the view manager when the display status of a workspace changes. The workspace can the call the corresponding methods of its components.
- post - called when a view is created
- set_inactive - called when a view is no longer displayed (before UI is removed)
- set_active - called when a view is displayed (before UI is added)
- change_page - called when a view is displayed (after UI is added)
- on_delete - called when a view is removed
The following methods are called by the view manager to obtain UI definitions. The workspace obtains the definitions from its components. In views it may be useful to use the ui_definition method for the main interface when the view is primary and the additional_ui_definitions method for popup definitions used when the view is secondary.
The following methods are called by the view manager to obtain configuration definitions. The workspace obtains the definitions from its components.
The Sidebar provides a mechanism for creating and switching between workspaces containing views. It arranges available views into categories so that they are easy for the user to find.
A sidebar must do the following:
- Action on the sidebar that should change to the workspace shown should call one of viewmanager.next_workspace/previous_workspace/goto_workspace and then wait for view-changed to update itself.
- Allow the user to create a workspace containing any view.
- Connect to view-changed from displaystate, and set it's content to match that.
- Sidebar might have different representations for how above methods can be called.
- Otherwise, the sidebar is independent of the rest of Gramps.
- Possibly, allow the user to add a secondary view to a workspace.
- get_top - Returns the top level gtk widget.
- view_changed(page_nr) - Called when a page is changed in the viewmanager.
- handlers_block - Called before the viewmanager changes a page.
- handlers_unblock - Called after the viewmanager changes a page.
handlers_block and handlers_unblock are used in the category sidebar to block the button handlers. This may be useful to prevent recursive calls or to prevent spurious effects.
The DisplayState holds the history of objects and provides utilities to control the status bar.