Can one put event listeners to parts of StandardForm expression?

1

I have a StandardForm expression

enter image description here

Is it possible to add an event listener to the variables, parentheses, and plus signs so that when I click them their color changes for example. Maybe it would be somehow possible to get the box dimensions and locations for each of these elements. Here I've highlighted the box for b by selecting it:

enter image description here

I tried this but it didn't work.

ToBoxes[(a + b) c^d + p]
RowBox[{RowBox[{RowBox[{"(", RowBox[{"a", "+", "b"}], ")"}], " ", 
    SuperscriptBox["c", "d"]}], "+", "p"}]
ToExpression[
  RowBox[{RowBox[{RowBox[{"(", 
       RowBox[{EventHandler[
          "a", {"MouseClicked" :> (thing = "clicked")}], "+", "b"}], 
       ")"}], " ", SuperscriptBox["c", "d"]}], "+", "p"}]]
$Failed

I also tried this but it didn't work either.

EventHandler["(", {"MouseClicked" :> (thing = "clicked")}]
EventHandler["a", {"MouseClicked" :> (thing = "clicked")}] 
EventHandler["+", {"MouseClicked" :> (thing = "clicked")}] 
EventHandler["b", {"MouseClicked" :> (thing = "clicked")}] 
EventHandler[")", {"MouseClicked" :> (thing = "clicked")}]

enter image description here

The elements of the expression are in wrong order.
Any ideas on new approaches?

user

Posted 2015-05-09T01:03:07.700

Reputation: 1 827

Answers

2

When working with Box form you must keep all expressions in Box form; you cannot insert a non-Box-form expression such as EventHandler[. . .] into it and have it remain valid. You must also convert the the EventHandler into Box form, e.g.:

EventHandler["a", {"MouseClicked" :> (thing = "clicked")}] // ToBoxes
TagBox["\"a\"", 
 EventHandlerTag[{"MouseClicked" :> (thing = "clicked"),
 PassEventsDown -> Automatic, PassEventsUp -> True}]]

Also if you wish to preserve the order of your expression MakeBoxes does not evaluate its first argument, therefore I would use:

DisplayForm[
  MakeBoxes[(a + b) + c^d + p] /. 
    s_String :> 
      MakeBoxes @ EventHandler[s, {"MouseClicked" :> (Print["clicked: ", s])}]
]

enter image description here

You could be able to click any character in the output and get a printed message.


The code above results in a becoming "a" -- this avoids that but the spacing is not quite right and ( and ) are not clickable characters:

MakeBoxes[(a + b) + c^d + p] /. 
  s_String :> 
   TagBox[s, EventHandlerTag[{"MouseClicked" :> (Print["clicked: ", s])}]] // 
     DisplayForm

Mr.Wizard

Posted 2015-05-09T01:03:07.700

Reputation: 259 163