Custom method icons

icons.png

In Nautilus (System Browser) you can have a wide range of icons accompanying the methods, such as:

  • go the the parent (children) method
  • execute test / example / script
  • method is abstract / contains halt
  • etc

And you can add your very own with just a single class and three simple methods.

Available icon actions

Adding custom Action Icon

As I am working on MetaLinks right now, I would like to easily see methods that have a MetaLink installed in them.

To start, you have to subclass AbstractMethodIconAction (see image above for all the available subclasses for inspiration).

Note: if you run into Red Cross of Death error, don’t fret and read the end.

1
2
3
4
AbstractMethodIconAction subclass: #MTMethodHasMetaLinkAction
instanceVariableNames: ''
classVariableNames: ''
package: 'MetaLinks-Toolkit-Utility'

1. actionOrder

Because only one icon can be seen at a time, you have to specify the order. The lower the number, the higher priority. (You can also adjust existing ones, if you find one of them more important to you).

1
2
3
4
actionOrder
"Return the priority of this action"
^0

2. isActionHandled

This method returns Boolean based on whether it applies to the current method. You also have a reference to the current method (instance of CompiledMethod) and the current browser at your disposal.

For my needs I know that I can ask the method whether it has any links.

1
2
3
4
isActionHandled
"Return true if the provided method fits this action requirement"
^method hasLinks

3(a). privateActionIcon - icon only

Now you need to specify the icon. You can use your own (instance of Form), or one of the system ones. Just inspect Smalltalk ui icons and see what is available.

1
2
3
4
privateActionIcon
"Return the icon for this action"
^ Smalltalk ui icons iconNamed: #breakpoint

3(b). privateActionIcon - button

Alternatively you can return a clickable IconicButton. That way you can do some action when you click on it. I want to inspect all the metalinks when I click on the button, so I will use that.

target: is an object on which actionSelector: will be executed and arguments: will be provided. I.e. clicking on the button will perform [ :aMethod | ... ] value: method.

1
2
3
4
5
6
7
8
9
10
11
12
privateActionIcon
"Return the icon for this action"
^ IconicButton new
target: [ :aMethod | ((aMethod ast allChildren collect: #links) reject: #isNil) flatten inspect ];
actionSelector: #value:;
arguments: {method};
labelGraphic: (Smalltalk ui icons iconNamed: #breakpoint);
color: Color transparent;
helpText: 'Inspect MetaLinks';
extent: self iconExtent;
borderWidth: 0

And we are done.

inspect.png

Common Error

Pharo is a live system, which means that as soon as you subclass AbstractMethodIconAction, your new Action will take effect in the system, which could easily end up looking like this:

error.png

Thankfully this is very easy to fix. For example you could start by subclassing Object and change to AbstractMethodIconAction only once you are done implementing the methods. Alternatively if you’ve already ran into the issue, you can simply fix it from Debugger, temporarily change the parent to Object, or fix it from some other code-editing capable tool, such as Message Browser.

System errors can sometimes be scary if you don’t know what’s happening, but once you get more familar with the system, they are actually pretty easy to fix.