I want to construct a graphics with a locator on top of it. This locator normally has to be invisible, but when I click somewhere in the graphics, the least that has to happen is that the locator becomes visible and moves to the clicked position.
Therefore, the easiest way for doing so seems to be to use a LocatorPane
with one locator. When we click somewhere in the displayed pane, the locator will move automatically to the clicked position.
A locator is a controller, and therefore the visibility/invisibility of the locator seems to be a trivial application of ControlActive
. However, it turns out to be more complicated. To illustrate the problem, consider the following example:
{a,b}={0.5,0.5};
LocatorPane[ Dynamic[{a,b}],
Graphics[{{Yellow, Rectangle[]},Locator[Dynamic[{a,b+0.1}], Dynamic[ControlActive["graphicsyes", "graphicsno"]]]}],
Appearance->Dynamic[ControlActive["paneyes", "paneno"]]]
The displayed pane has two locators. One is created by the LocatorPane
itself. I will call it the pane locator; it is shown as paneyes or paneno. The other one is part of the second argument of the locator pane. I will call it the graphics locator. It will be drawn a little bit above the pane locator and shown as graphicsyes or graphicsno.
When we click in the yellow square and keep the mouse pressed, we see that the pane locator moves to the clicked position and the graph locator to corresponding position above it. Since the mouse is pressed, controllers are active, but none of the locators is shown with yes. Despite the Dynamic
, the fact that controllers are active seems not to be detected.
It turns out that we can force the detection by using UpdateInterval
:
{a,b}={0.5,0.5};
LocatorPane[ Dynamic[{a,b}],
Graphics[{{Yellow, Rectangle[]},Locator[Dynamic[{a,b+0.1}], Dynamic[ControlActive["graphicsyes", "graphicsno"], UpdateInterval->0.5]]}],
Appearance->Dynamic[ControlActive["paneyes", "paneno"], UpdateInterval->0.5]]
Now, given that UpdateInterval
works, we can force the updating by simply wrapping the second argument in Dynamic
. When we click, the values of a
and b
change, and therefore the pane is redrawn.
{a,b}={0.5,0.5};
LocatorPane[ Dynamic[{a,b}],
Dynamic[Graphics[{{Yellow, Rectangle[]},Locator[{a,b+0.1}, ControlActive["graphicsyes", "graphicsno"]]}]],
Appearance->Dynamic[ControlActive["paneyes", "paneno"]]]
Observe that when we click in the pane, it is only the graphics locator that shows that controllers are active. The pane locator remains as it was.
Maybe it has a simple explanation, but I fail to see why we need UpdateInterval
, or why we should wrap the second argument of LocatorPane
in Dynamic
, for detecting that controllers are active. Any comment is highly appreciated.
This site encourages to answer your own question. So I present an answer, in which I give some solutions for my problem. I consider them as rather 'artificial'. I hope someone can provide a more straightforward solution.