GTInspector is moldable in two ways:
In a previous post, we saw that extending the GTInspector is a simple matter of adding a method annotated with a pragma in the class of the inspected object. When this simple mechanism is combined with concise widget descriptions, we get a new land of opportunities.
Obviously, with every opportunity come new challenges. In our case, the question is how to keep track of all the extensions. In the same previous post, we saw that we can retrieve the methods that use the pragmas with a simple query and browse the result with the inspector. However, passive browsing is not enough in this case. We also want to edit these methods.
Using the recent extensions that come with the inspector, we can first obtain a live editor by inspecting the result of the query below:
(Object withAllSubclasses flatCollect: [ :each | Pragma allNamed: #gtInspectorPresentationOrder: in: each ]) collect: [ :each | each method asRingDefinition ]
The query will return a collection of RGMethodDefinition
. A ring definition holds only a reference to the actual method, thus it offers the proper model to support editing operations: if you click the accept action on the top right (or Cmd+s), the method will change from within the inspector. In the example below, you can see the extension that shows the tree of submorphs for each morph.
As you can see, there are 53 GTInspector
extensions in my image. This is already great. But, having an overview of the extensions is a persistent requirement and it would be particularly interesting to have it around all the time. What to do?
Let’s persist it next to the main point of interest and extend the GTInspector
class itself. To do this, we inspect the class and in the methods pane, we create a new extension:
GTInspector class>>gtInspectorExtensionsIn: composite <gtInspectorPresentationOrder: 40> composite list title: 'Extensions'; display: [ (Object withAllSubclasses flatCollect: [ :each | (Pragma allNamed: #gtInspectorPresentationOrder: in: each) collect: [:p | p method asRingDefinition] ]) sorted ]; format: #gtDisplayString; filterOn: [ :text :each | each gtDisplayString includesSubstring: text caseSensitive: false ]
This method creates a new tab that keeps track of the extensions and it will appear only when inspecting the GTInspector
class.
This is important for at least one reason. The GTInspector thrives when you extend it. But, to extend it, you need to learn. And, to learn you need concrete examples. Now you have them.