0
$\begingroup$

In the following code changing the InputField does not result in observing changes in a result from FindGeometricTransform, but moving the Locator does.

This is related to a previous answer would seem to have a solution, but the fix from that solution doesn't fix the observed behavior, or rather, it causes other problems.

Manipulate not working inside DialogInput

In this Question/Answer, LocalizeVariables is set to False for the Manipulate, and the control in question is explicitly set as Dynamic. This then allows the Manipulate to respond appropriately.

However, my FindGeometricTransform breaks when I try this.

In playing around with the system, I think that I have found that the situation is actually a bit more subtle than I thought. Using Nasser's suggestion, moving the Manipulate to the outside of the Module does partially solve the problem. I can get the GeometricTransform to update whenever I change the fields.

That would seem to solve the problem, however, it has a similar problem when I try to add data points to a table based upon the transform (my eventual goal). Here is a new function named maniTransform2 that illustrates the observed behavior.

    imageIUsed = ExampleData[{"TestImage", "Clock"}]
    maniTransform2[image_] := Manipulate[Module[{func, points},
        func = 
         Dynamic[FindGeometricTransform[{{coord1x, coord1y}, {coord2x, 
              coord2y}}, {loc[[1]], loc[[2]]}][[2]]];
        points = 
        If[Length[loc] > 2, 
           Setting@func[loc[[3 ;; Length[loc]]]], {}];

        Row[{Show[{
            Image[image],
            Graphics[{Red, PointSize -> Large, 
              Point[{{coord1x, coord1y}, {coord2x, coord2y}}]}]}],
          func, Spacer[40], 
          Grid[Join[{{"X-coord", "Y-Coord"}}, points
            ]
           ]
          }]], {{loc, {{10, 10}, {20, 20}}}, Locator, 
        LocatorAutoCreate -> True}, {{coord1x, 50, "x-Position"}, 
        InputField[#, Number] &}, {{coord1y, 50, "y-position"}, 
        InputField[#, Number] &}, {{coord2x, 100, "x-Position"}, 
        InputField[#, Number] &}, {{coord2y, 100, "y-position"}, 
        InputField[#, Number] &}];

    holderFunc := DynamicModule[{img = imageIUsed},
      switcher = 
       Panel[TabView[{Dynamic[maniTransform2[img]], "Other Functions"}]];
      DialogInput[Row[{Dynamic[switcher], InputField[Dynamic[img]]}]]]

So, calling maniTransform2[imageIUsed] directly, the GeometricTransform updates whenever I move one of the Locator points or if I change a value in one of the various InputFields.

If I call holderFunc, then if I move any of the Locator points the GeometricTranform2 updates. It also updates when I change one of the fields.

When I add a Locator (command-Click on a Mac), the procedure adds it to the Table of points below the transform function. Whatever the values are in the input fields are frozen for the transform at that point. Changing the values in the input fields will change the transform function, but they won't change the values of the points in the Table. For that matter, the If statement in general is frozen. I.e. it needs to be wrapped in a Dynamic somehow. However, doing so then places the func into a Dynamic and since func is declared in the Module, this is a no-no and it turns red.

$\endgroup$
2
  • $\begingroup$ do not put manipulate inside module. Put module inside Manipulate. Specially since you have the same symbol based to the outside module and used inside Manipulate. Manipulate should always (at least that is what I would do) be the outermost. This set up : Module[{a},Dynamic[a]] is what causing the problem I think, without even trying it (where a here is your imag). Manipulate is a DynamicModule. $\endgroup$
    – Nasser
    Commented Feb 28, 2014 at 14:23
  • $\begingroup$ @Nasser, Thanks for the tip. I am pretty sure that I tried it in one of my various iterations on the original code. I tried it here, and the simple flip of the two (and necessary rearrangement of the brackets) didn't fix the weird behavior. I'll continue to fiddle with your hint though. $\endgroup$ Commented Feb 28, 2014 at 14:30

1 Answer 1

1
$\begingroup$

The following code works. But, I am not sure if it was you are trying to achieve:

Version 1 creating a dialog as seems to be your intent (your code but with an additional image:

imageIUsed = ExampleData[{"TestImage", "Clock"}]
anotherImage = ExampleData[{"TestImage", "Airplane"}]
maniTransform[image_] := 
  Manipulate[
   Row[{Show[{Image[image], 
       Graphics[{Red, PointSize -> Large, 
         Point[{{coord1x, coord1y}, {coord2x, coord2y}}]}]}], 
     func[{{coord1x, coord1y}, {coord2x, coord2y}}, {loc[[1]], 
       loc[[2]]}]}], {{loc, {{10, 10}, {20, 20}}}, Locator, 
    LocatorAutoCreate -> True}, {{coord1x, 50, "x-Position"}, 
    InputField[#, Number] &}, {{coord1y, 50, "y-position"}, 
    InputField[#, Number] &}, {{coord2x, 100, "x-Position"}, 
    InputField[#, Number] &}, {{coord2y, 100, "y-position"}, 
    InputField[#, Number] &}, 
    Initialization :> (func[pointsInput_, pointsLoc_] := 
      FindGeometricTransform[pointsInput, pointsLoc])];

and using CreateDialog

 DynamicModule[{img = imageIUsed, switcher}, 
  switcher = 
  Panel[TabView[{Dynamic[maniTransform[img]], "Other Functions"}]];
  CreateDialog[Row[{Dynamic[switcher], InputField[Dynamic[img]]}]]];

Version 2 which I believe may be something closer to what you want (Manipulate within a Manipulate)

DynamicModule[{switcher},
 Manipulate[
  switcher = 
   Panel[TabView[{Dynamic[maniTransform[img]], "Other Functions"}]];
  Row[{Dynamic[switcher], InputField[Dynamic[img]]}],
  {img, {imageIUsed, anotherImage}}
  ]
 ]
$\endgroup$
3
  • $\begingroup$ I worked on implementing the CreateDialog on the actual code (because that in fact is what my actual situation looks like), but it failed to solve the problem, although it clearly does in my simpler example. I think I need to understand the fundamental failing of the code with DialogInput, because maybe that will give me a clue what is going on relative to all of the other moving parts in the actual code. $\endgroup$ Commented Mar 1, 2014 at 3:35
  • $\begingroup$ I worked with your solution a bit more to see if I could make it work in my code. One of the biggest problems that I had was that I really need DialogInput as a Blocking dialog. I can make CreateDialog Modal, but it doesn't block and this causes problems with another part of my code. I am sure that this could be reworked, and that may be what I need in the end. As you can see from my edits to the question above, the underlying problem of the updates to the FindGeometricTransform is more problematic than I at first realized. Sometimes it does, sometimes it doesn't. $\endgroup$ Commented Mar 1, 2014 at 16:45
  • $\begingroup$ I went to check and see if your solution works with the newest problem, and I think it does. I think it is the best workaround, although I wish I could figure out why the DialogInput itself doesn't work. I am going to accept your answer as the solution. $\endgroup$ Commented Mar 1, 2014 at 16:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.