Purpose
There are a few places where registration happens in SMTK that do not use the new Schwarz counter and plugin management stuff that TJ put in:
- Qt view & item constructors are handled in
qtSMTKUtilities
; and
-
smtk::common::Extension
classes also use old-style static registration
We would like to refactor these so that the API is consistent and takes advantage of the new mechanism.
Proposal
Qt item and view constructors
With SMTK MR 1753, there is now an smtk::view::Manager
object that is more of a factory than anything else (it creates PhraseModel
and SubphraseGenerator
instances). We should expand its role to the creation of new views in a GUI-independent way.
Note that unlike the resource Manager (which manages resources but does not require resources to be managed to be useful), the view Manager will be necessary for most views to function properly.
This work will involve the following changes:
- In
smtk::view
, rename the View
class to Configuration
to avoid name collision/confusion below.
- Create a derived class
smtk:::extension::qtConfiguration
, and have it hold a weak pointer to the view Manager
that created it.
- Create a new
smtk::view::View
class and make qtBaseView
inherit it.
- Add a method to
smtk::view::Manager
named create(const view::Configuration&)
that will construct a new smtk::view::View
subclass, passing its constructor the view configuration.
- Create a new
smtk::extension::qtConfiguration
class that inherits smtk::view::Configuration
; its purpose is to take the place of smtk::extension::ViewInfo
(Qt-specific view configuration).
a. Since this object inherits view::Configuration
, it need not own an instance of it. By using emplacement and move semantics, it will be possible for a Qt view containers (i.e., ParaView panels or other application components) to efficiently convert a hierarchy of smtk::view::Configuration
objects into smtk::extension::qtConfiguration
instances as needed.
b. This class will own a QLayout dictionary and hold a pointer to a QWidget.
- Add methods to the
view::Manager
to register and unregister View
constructors.
- Create a subclass of
smtk::view::Manager
that is specific to Qt - smtk::extension::qtManager
. Beyond the basic view manager, this class will
a. have register and unregister methods for qtItem constructors
b. have register and unregister methods for qtModelView constructors (QTreeView, QListView, etc.)
c. provide methods currently housed in qtUIManager
that deal with application-wide configuration information such as colors and settings. Since every view holds a weak pointer to the manager which created it, it is accessible everywhere qtUIManager
is currently used.
- Remove the
qtSMTKUtilities
class (the view manager holds custom view constructors and the Qt-specific view manager holds custom item and modelview-widget constructors).
- Remove the
qtUIManager
class (the Qt-specific view manager, smtk::extension::qtManager
, should replace it).
Extension registration
We have two alternatives:
- a minimal change to the extensions to use the Registrar pattern while maintaining the existing pattern or
- adapting the
smtk::common::Generator
pattern to deal with extension-like behavior.
@tj.corona probably has strong opinions here; this page is a wiki so he can edit this section to provide more details of what he wants to see.
I have used all three patterns for registration (Extension, Generator and Registrar). I think the Extension and Generator are pretty similar, and are good for situations where feature extension is intended to be at global scope (such as registering a reader for a file type). They can probably be merged into one pattern. The Registrar pattern is more for augmenting the main features of SMTK; we should probably keep the number of manager types to a maintainable level.
Since the current view::View class (which will be named something like view::Configuration (or Spec, Specification, etc…) ) represents the serializable aspects of the View (XML or JSON) - I would hate to have it “contaminated” with none serializable information like pointers to view managers or QWidgets. That is the current role of the ViewInfo class(es). So I would propose we keep ViewInfo (maybe rename it) - and create a non-qt base class for it. Maybe call it view::Construction and a derived extension::qtViewConstruction (or qt::ViewConstruction if we decide to move all qt named classes into a qt:: namespace). The view::Construction class would simple hold onto a view::Configuration instance while the qt version would hold onto things like the View’s parent Widget).
Then all factory methods would take in a view::Construction instance.
@Bob_Obara I’ve changed the ViewConfiguration class name in a few more places above. The other thing we discussed offline was namespaces. I used smtk::qt::Configuration
and smtk::qt::Manager
, but to be consistent with what’s currently in SMTK we would use smtk::extension::qtConfiguration
and smtk::extension::qtManager
. I think putting Qt-specific stuff inside smtk::view
could be problematic unless we do something like smtk::view::qt
.
I am fine keeping the configuration (you also mentioned specification as an alternative) separate from the other “construction state” and will update the plan above some time soon.
Bob and I discussed, and we think reusing an existing name for this will be very confusing, and impossible to document accurately. I think we settled on smtk::view::BaseView
, as opposed to Base or BaseImplementation.
We’re also unsure of how the conversion from view::configuration
to extension::qtConfiguration
would work - would it seem like you are re-constructing the objects just to use them? Also, for consistency, the name might need to be extension::qtViewConfiguration
- if the extension
namespace is a grab-bag of stuff.
Gonna try to meet about it tomorrow.
After some discussion and reflection, here is another attempt to outline the new design, the reasons for it, and then the way we might work towards it in small steps instead of a cliff dive.
Proposed Design
The diagram above shows several new and renamed classes in the smtk::view namespace:
-
view::Manager
‒ Maintain a list of views, a list of view configurations (as read from project resources), and act as a factory for views and the items they contain.
-
view::Configuration
‒ Hold specifications for a view independent of any UI that is read from project resource files.
-
view::Confguration::Component
(or view::Configuration::Item
) ‒ Same as above but for components of a view rather than the view itself.
-
view::View
‒ A base class for all views (Qt-specific or not; attribute-specific or model-specific). Note that currently, all of SMTK’s views end up being ParaView panels. While it is possible that ParaView’s 2-D and 3-D visualization views might also become SMTK views, that would complicate saving server-manager state. The basic capabilities of a view are to:
- report their parent view (if any);
- contain items (optional);
- accept new
view::Configuration
s as the workflow requests changes; and
- respond to operations and other changes to SMTK objects.
-
view::Component
(or view::Item
) ‒ A base class for all visual components of views. The basic capabilities of an item are to:
- report their parent view and (if any) parent item;
- contain items (optional);
- accept new
view::Configuration::Component
s as the workflow requests changes; and
- respond to operations and other changes to SMTK objects.
-
view::Panel
— (not shown) a base class for application panels that contain views. This allows projects or plugins to specify a set of windows/panels each of which may be configured to show a view.
Qt-specific subclasses of view::View
and view::Item
would dual-inherit both the SMTK class and QWidget.
Benefits
The design above would
- allow the
view::Manager
class to maintain a list of views that applications could manage, rather than just act as a factory for views and items;
- refactor more of the UI code that need not be dependent on Qt into the smtk::view namespace (inside smtkCore);
- reduce the number of classes we maintain (by removing Qt-specific item and view “Info” classes)
- adopt a more Qt-like pattern for the widgets (where attribute, item, and view classes inherit QWidget instead of managing QWidgets).
- adopt a more SMTK-like manager-observer pattern for views.
- allow SMTK applications to manage GUIs built with other toolkits. An example would be a web environment where SMTK running through Python served a client web browser with HTML “renderings” of an attribute system that would update attributes on the server. This use case would let SMTK provide interactive renderings of large 3D models from the server while sending attribute panel components to the client.
Incremental Implementation
These changes could be made in several steps (largely outlined in the top post of this topic).
- Implement
view::View
and view::Item
as core classes, then change qtItem
and qtBaseView
to inherit them.
- Make attribute reader store
view::Configuration
in the view::Manager
rather than attribute resources.
- Refactor away
qtSMTKUtilities
into view::Manager
.
- Remove the factory API from
qtUIManager
in favor of view::Manager
.
- Change the inheritance of
qtItem
and qtBaseView
to QWidget
.This step would also need to refactor away Qt helper classes like qtAttributeItemInfo.
There was talk a while ago about smtk::view moving out of core. Is now a good time to revisit that possibility?
The only real barrier is smtk::attribute
, whose resource currently deserializes view::Configuration
.