Blog

Taking a custom morph screenshot with GTInspector

When writing a report, you might end up wanting to embed a screenshot of a particular part of the screen.

For example, recently there was a request on the Moose mailing list for taking a screenshot from only a part of a Glamour browser. One solution would be to have the possibility to script the browser to know how to take a screenshot of the desired part. However, this is not possible with the Glamour current model. We need a different angle to approach this problem pragmatically.

The browser is rendered using morphs. And morphs are objects that are nested, like in any other user interface framework, and that have a model. We could try to query the morphs based on the attached model to identify the desired sub part to take a screenshot of. The problem is that the morphs are not quite uniform, and it is hard to query them because of that. With this occasion, I also saw that Glamour does not have a consistent way of mapping to morphs either which makes things even more complicated for querying.

However, for the problem of generating a one-time screenshot, we do not need a fully automatic solution. A different approach would be to build a tool that makes it reasonably cheap to take a highly customized screenshot.

And it so happens that the tool already exists: the GTInspector. Here is the recipe:

  • open your browser and bring it in the desired constellation
  • on the window title bar invoke Ctrl+Shift+RightClick
  • from the menu choose explore
  • in the GTInspector that opens, choose the Submorphs tab
  • start selecting nodes
  • in the pane to the right, choose the Morph tab and you will get a preview of what is selected
  • continue selecting from the left pane until you get to the desired morph
  • from the right pane, choose the top right menu and export to PNG

The video below shows how it looks.

Automation is perfect when it fits. But, when it does not fit, you can greatly benefit from custom interactive tools that exploit your visual capabilities to discern relevant information. Such tools should be integral part of any software engineering toolkits.

Posted by Tudor Girba at 4 June 2013, 8:50 am with tags moose, analysis, demo link
|

Introducing the Glamorous Debugger for Smalltalk (alpha)

Over the last following days, Andrei Chis and I have worked on getting the Glamorous Debugger for Pharo in a usable state (based on the original effort of Toon Verwaest).

This debugger is part of the Glamorous Toolkit project, and it is based on the Glamour browsing engine. The goal of this project is to provide the infrastructure for new types of debuggers.

When loaded, the debugger installs as a new button in the small debugger.

The goal is to provide the possibility of having the GTDebugger next to the classic debugger until the inevitable errors are ironed out. When choosing to debug glamorously, you get into the GTDebugger.

At this point, the debugger mostly mimics the classic debugger. However, it does it with the long term goal of reinventing what debuggers can be.

Currently, there are two interesting characteristics:

  1. It has an integrated inspector that shows all variables in one GTInspector. There are two benefits:
    • you can see all relevant variables and their value at one glance
    • you can inspect the current context in place using the finder like navigation
  2. Code-wise, the debugger comes with an explicit model that relies neither on the old Debugger nor on the CodeHolder. The model is rather small and intelligible. In total, the entire code totals 399 lines of code (at the moment). To put it into perspective, the Debugger class alone has 1096 lines of code (not counting the extra code used by it).

We consider the code to be in a solid alpha, and we need more eyeballs and clicks to test it.

If you are interested in playing with it, you can either find it in the Moose image, or you can load it in Pharo 1.4 via:

 Gofer new
 squeaksource: 'glamoroust';
 package: 'ConfigurationOfGlamoroust';
 load.
(Smalltalk at: #ConfigurationOfGlamoroust) loadDevelopment
Posted by Tudor Girba at 25 November 2012, 1:11 am with tags demo, moose link
|

Every object should have equal browsing opportunity

Essentially, all objects are created equal. However, in reality, not all of them are treated equally.

Let's consider Pharo. Packages, classes and methods have their own browser. Code history related objects have their own browser. Setting objects have their own browser. Processes have their own browser. A couple of others have such dedicated browsers as well, but that is about it.

The rest of objects (and my current image has some 4.5 million of them) are treated as second rate citizens: the only thing they are offered is a poor basic Inspector. It is true that the Inspector is more than nothing, but it still feels like discrimination.

Why did we get here? Mostly because of the high costs associated to building a browser. The game has changed in the meantime, and as a consequence, we should reconsider our position.

A while ago I announced the Glamorous Inspector as an alternative to the classic Inspector. It uses a metaphor similar to the one of the Moose Finder which, in its turn, is inspired from the Mac Finder:

  • every object gets a pane and has the possibility of spawning another pane for another object to the right, and
  • every object can have multiple presentations through which it can be interacted with.

The responsibility of defining the presentations lies with the object. The definitions are accomplished via extension methods that are marked by means of a pragma. The browser asks each object for methods defining the pragma and builds the presentations from them.

For example, if you get to a Morph object, beside the default list of instance variables, you can also obtain a preview of how it renders based on the following definition:

Morph>>gtInspectorMorphIn: composite
  <gtInspectorPresentationOrder: 90>
  composite morph
    title: 'Morph';
    display: [:each | each imageForm asMorph ]

The method gets as a parameter a Glamour CompositePresentation that can be extended with new presentations. In this case, we show the morph object with a MorphPresentation.

The gtInspectorPresentationOrder: pragma signals the inspector that this presentation should be offered for a morph object. The number argument (90 in our case) is used as a means to order the rendered tabs.

Another way to understand a morph is to browse its children structure. This is defined as:

Morph>>gtInspectorSubmorphsIn: composite
  <gtInspectorPresentationOrder: 80>
  composite tree
    title: 'Submorphs';
    rootsExpanded;
    display: [:each | {each} ];
    icon: [:each |
         | morphForm |
         morphForm := each imageForm.
         (morphForm extent x > 0 and: [morphForm extent y > 0 ])
              ifTrue: [(morphForm scaledToSize: 16@16) asMorph]
              ifFalse: [Form extent: 16@16] ];
    children: [:each | each submorphs];
    when: [:each | each submorphs notEmpty]

This is a slightly more complicated method, but most of the complexity comes from building the icon that should be shown for each of the child morphs. Below you can see a screenshot of inspecting the result of UITheme exampleOtherControls.

Gtinspector-on-morph.png

The Glamorous Inspector relies on a simple and extensible design. You add an extension method with a new presentation and this will appear as a tab in the inspector. This is uniformly applied to all objects.

For instance, Object offers a presentation for handling the object state (i.e., instance variables), and another one for the handling the code of the class of the object (including changing the code). For example, to the left of the picture below you can see the methods associated with the class (in this case it's actually the Morph superclass) of our morph object. Given that the selected method (imageForm) is a unary one, you can simply executed on the spot and open the resulting object to the right. In this case, our object is a Form, and thus, it can also be previewed.

Gtinspector-on-morph-methods.png

The consequence of this design is that you can accommodate several workflows within one integrated Inspector, depending on the context. It also means that you can change the shape of your inspector at runtime. That is, even during analysis, if you need an extra presentation for your current object, you add a little method and you continue your analysis through dedicated interaction.

Every object should be allowed to aspire to its own browser. With Glamour and the Glamorous Inspector, we get a step closer. It is now up to you, especially if you program in Pharo, to listen to your objects and offer them the means to express themselves.


The Glamorous Inspector ships together with the Moose distribution, but it can also be installed separately.

Posted by Tudor Girba at 21 July 2012, 10:34 am with tags assessment, demo, moose, tooling link
|

Moose demo: browsing class naming cohesion

A previous post demonstrated how to build a simple visualization to explore the overall class name cohesion. In that case, the visualization showed a picture of how classes that have similar names are also placed in the same package.

The result was a global view that was applicable to all classes. But, what if we want to get the naming cohesion of classes on a per package basis? Simple, we need a browser that enables us to explore the packages in the system, and for each of these to show the visualization. And, as we do not have it yet, we have to build one.

Take a look.

The code for the browser can be seen below.

composer tabulator with: [:t |
  t column: #namespaces; column: #classes.
  t transmit to: #namespaces; andShow: [:a |
    a tree
    display: [:mooseModel | mooseModel allNamespaces select: #isRoot ];
    format: #name;
    children: #childScopes ].
  t transmit from: #namespaces; to: #classes; andShow: [:a |
    a mondrian
      painting: [:view :namespace |
        view shape rectangle
          size: #nameLength.
        view nodes: namespace classes.
        view edgesToAll: [ :class |
          namespace classes select: [ :eachTarget |
            (eachTarget name pairsDistanceFrom: class name) > 0.5]].
        view graphvizLayout neato ]]].
composer startOn: model
Posted by Tudor Girba at 26 March 2012, 12:48 am with tags moose, demo, tooling link
|

Moose demo: Manipulating custom annotations

Most software analysis tools focus solely on automatically extracting relevant information from data (e.g., source code). However, in most cases, important external information is also available in the form of developer or context specific knowledge. These pieces of information can provide extra insights if they could be taken into account during analysis.

Moose offers multiple mechanisms that help the analyst contextualize the analysis. One particular engine is called Metanool, and it offers a means to integrate custom information in the model by means of annotations. Furthermore, the engine comes with a simple user interface that is integrated directly in the analysis flow.

Take a look at the demo below. In this demo, we get a list of classes, and based on extra information we decide which ones we should look into, and which of these we should take extra care to analyze. Once the annotations are added to the model, they can be used directly. And everything happens while performing the analysis.

The current incarnation of Metanool is the result of a complete rewrite. However, the original intention and implementation ideas are preserved. If you are interested in learning more about the internal meta-modeling mechanisms, you are invited to read the article we wrote three years ago: http://scg.unibe.ch/archive/papers/Brue08b-Metanool.pdf

Posted by Tudor Girba at 30 December 2011, 5:44 pm with tags moose, demo, tooling link
|
<< 1 2 3 >>