Can individual locators in LocatorPane be temporarily disabled?
A simple way to do this is to change the Dynamic
so that it updates only the points you want to be editable. Here is a very simple demonstration:
pts = {{6, 0}, {0, 9}, {3, 0}, {0, 7}};
updatable = Range@Length@pts;
Button["Fixate point 3", (updatable = {1, 2, 4})]
LocatorPane[Dynamic[pts, (pts[[updatable]] = #[[updatable]]) &],
Dynamic@Graphics[Point /@ pts, PlotRange -> {{-10, 10}, {-10, 10}}]]
I like @jVincent's approach.
Here is a different approach Overlay
ing LocatorPanes
inside Manipulate
:
locPane[Dynamic[pts_], shape_, color_] :=
LocatorPane[Dynamic[pts],
Dynamic@Module[{x = pts[[1, 1]], y = pts[[2, 2]]},
Graphics[{{color, Line[{-m*{x, y}, m*{x, y}}]},
Line[{{x, 0}, {x, y}}], Line[{{x, y}, {0, y}}]}, PlotRange -> m,
Axes -> True, ImageSize -> {300, 300}]],
{{{-m, 0}, {m, 0}, {1, 0}}, {{0, -m}, {0, m}, {0, 1}}},
Appearance -> {shape, shape}];
(* locator apperance graphics *)
redCircle = Graphics[{Red, Table[Circle[{0, 0}, i], {i, 2}]}, ImageSize -> 10];
blueCircle = Graphics[{Blue, Table[Circle[{0, 0}, i], {i, 2}]}, ImageSize -> 10];
grayDisk = Graphics[{Lighter@Lighter@Gray, Disk[{0, 0}, 2],
Gray, Circle[{0, 0}, 3]}, ImageSize -> 10];
Method 1: Overlay
two instances of locPane
inside a Manipulate
Manipulate[m = 15;
Overlay[{
locPane[Dynamic[pts], Dynamic@If[layer == 1, redCircle, grayDisk], Red],
locPane[Dynamic[pts2], Dynamic@If[layer == 2, blueCircle, grayDisk], Blue]},
All, Dynamic[layer]],
{{pts, {{6, 0}, {0, 9}}}, ControlType -> None},
{{pts2, {{7, 0}, {0, 7}}}, ControlType -> None},
{{layer, 1, "layer"}, {1, 2}}]
to get
Method 2: Overlay
two instances of locPane
inside an EventHandler
and Manipulate
:
Right-mouse-click toggles between two locator panes:
DynamicModule[{layer = 1}, EventHandler[Manipulate[m = 15;
Overlay[
{locPane[Dynamic[pts], Dynamic@If[layer == 1, redCircle, grayDisk], Red],
locPane[Dynamic[pts2], Dynamic@If[layer == 2, blueCircle, grayDisk], Blue]},
All, Dynamic[layer]],
{{pts, {{6, 0}, {0, 9}}}, ControlType -> None},
{{pts2, {{7, 0}, {0, 7}}}, ControlType -> None}],
{{"MouseClicked", 2} :> ((layer = layer /. {1 -> 2, 2 -> 1}))},
PassEventsDown -> True]]