Looking for a methodology where the user can move the points of a Locator and then click a button to ask for calculations to proceed. The motivation for this is that the calculations of the full system are time consuming, perhaps several minutes. ContinuousAction -> False for the LocatorPane would cause the calculations to proceed after the user finished moving each Locator point. Since the user may want move move, add, or delete, several Locator points before starting the calculations, I want to place the the execution of the calculations under the user's control.
Below is a simple example of this using Manipulate.
The Manipulate uses TrackedSymbols to identify when a hidden parameter, iUpdate, is changed. Clicking the buttons will change the value of iUpdate. In the body of the Manipulate, the code uses iUpdate to do a meaningless calculation, so that the Manipulate recognizes that "something" affected by the tracked symbol has changed.
Some helpful information related to this question, includes a discussion of making buttons for manipulate for Manipulate, the tutorial pages for Manipulate and Dynamic and the Advanced Dynamic tutorial page
Below is a working methodology. Am asking for alternative or improvements to this implementation.
Also, one other question: in the code for each button, the change to the value of iUpdate is placed after the FinishDynamic statement -- not sure about this; however, placing it before the FinishDynamic created problems.
Below is the code use for this example. Thanks for your comments and help.
Clear[adjYvalues]
adjYvalues[xyPts_, yAdj_?NumericQ] := Module[{},
xyPts + ConstantArray[{0, yAdj}, Length@xyPts]
]
Clear[makeLcpInterpFunc]
makeLcpInterpFunc[xyPts_] :=
Module[{xyNew, xMin = 0, xMax = 2 π, xMinData, xMaxData},
xyNew = Sort[xyPts];
xyNew =
If[xMin < xyNew[[1, 1]], Prepend[xyNew, {xMin, xyNew[[1, 2]]}],
xyNew];
xyNew =
If[xMax > xyNew[[-1, 1]], Append[xyNew, {xMax, xyNew[[-1, 2]]}],
xyNew];
Interpolation[xyNew, InterpolationOrder -> 1]
]
Clear[makeLcpBackground]
makeLcpBackground[f1_, xyPts_, f2_] := Module[{fInterp, epsX = 0.05},
(*fInterp = makeLcpInterpFunc[xyPts];*)
Plot[{f1[x], f2[x]}, {x, 0, 2 π}
, PlotRange -> {{0 - epsX, 2 π + epsX}, {-1.3, +1.3}}
, Frame -> True
, GridLines -> {{0, π/2, 2 π/2, 3 π/2, 4 π/2},
Automatic}
, ImageSize -> 600
, Epilog -> {Red, AbsolutePointSize[4], Point[xyPts] }]
]
manipLocPaneWithButtons =
DynamicModule[{lcPtsInit = {{0, 0}, {π/2,
1}, {3 π/2, -1}, {4 π/2, 0}}, lcPts
, status =
Style["Ready to start", Bold, 16, RGBColor[0.27, 0.5, 0.17]]
, yAdj = 0
, iCount = 0
, fRef = Sin
, fInterp
, lcpBackground
, errCurrent, errPrevoius},
Manipulate[
(*analysis *)
(*lcPts = If[iOpt \[Equal] 1, findNewYvaluesFromFunc[Sin, {0,
2π}, {-1.5, 1.5},lcPts,3] , lcPts];*)
iCount = iUpdate;
lcPts = adjYvalues[lcPts, yAdj];
yAdj = 0;
fInterp = makeLcpInterpFunc[lcPts ] ;
lcpBackground = makeLcpBackground[fRef, lcPts, fInterp] ;
(*display *)
Grid[{{status ~~ " iCount:" ~~ ToString[iCount]
}, (*end Row 1*)
{
LocatorPane[ Dynamic[lcPts], lcpBackground,
LocatorAutoCreate -> True, ContinuousAction -> False]
}(*end Row 2*)
}(*end Grid{{}} *)
, Frame -> All
] (*end Grid[]*)
(*controls*)
, Delimiter
, Style["Calculation Control", Black, Italic, 12]
, Delimiter
, Button["Reset"
, status = Style["reseting points ...", Darker@Blue, 14, Bold];
lcPts = lcPtsInit;
FinishDynamic[];
iUpdate = 0;
, Method -> "Queued"
]
, Delimiter
, Button["Update / Calculate"
, yAdj = +0.0;
status = Style["updating ...", Darker@Blue, 14, Bold];
FinishDynamic[];
iUpdate += 1;
, Method -> "Queued"
]
, Delimiter
, Button["Move Up"
, yAdj = +0.1;
status = Style["move up ...", Darker@Blue, 14, Bold];
FinishDynamic[];
iUpdate += 1;
, Method -> "Queued"
]
, Delimiter
, Button["Move Down"
, yAdj = -0.1;
status = Style["move down ...", Darker@Blue, 14, Bold];
FinishDynamic[];
iUpdate += 1;
, Method -> "Queued"
]
, {iUpdate, None}
, ControlPlacement :> {Left, Left}
, TrackedSymbols :> {iUpdate, status}
, Initialization :> (
lcPts = lcPtsInit;
iUpdate = 0;
iCount = 0;
)
, SynchronousUpdating -> False
, LocalizeVariables -> False
] (*end Manipulate*)
];(*end DynamicModule*)
Button["start Test", CellPrint@manipLocPaneWithButtons ]