2
$\begingroup$

I am trying to modify the parameters of a system by clicking on its graphics. I am using ClickPane with DialogInput. A code example is as follows.

DynamicModule[{},
 ClickPane[
  Framed[Graphics[{Red, Disk[{0, 0}, 1]}, PlotRange -> {{-2, 2}, {-2, 2}}]], 
  (If[Norm[#] < 1, DialogInput[Grid[{{CancelButton[], DefaultButton[DialogReturn[1]]}}]]];) &
 ]
]

As expected, the Dialog window appears with a click in the red circle. However, it takes a long time before it is enabled. I am new with Dynamic modules. Could someone explain the reason of this?

$\endgroup$
  • 3
    $\begingroup$ That's because it uses Preemptive link. You need a controller with Method->"Queued" to prompt a dialog, which is a Button or an ActionMenu. $\endgroup$ – Kuba Oct 21 '15 at 20:19
  • $\begingroup$ Welcome to Mathematica.SE! I hope you will become a regular contributor. To get started, 1) take the introductory tour now, 2) when you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge, 3) remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign, and 4) give help too, by answering questions in your areas of expertise. $\endgroup$ – bbgodfrey Oct 21 '15 at 20:32
  • $\begingroup$ Here's more info, take a look at John Fultz's comment too 5357 $\endgroup$ – Kuba Oct 21 '15 at 21:45
2
$\begingroup$

I can not get a click pane to play nice with an input dialog. I offer the following as a work-around that suggests another way for you to accomplish your goal.

DynamicModule[{grid, color = Red, r = 1., controls = ""},
  grid =
    Grid[{
      {Style["Color", "SR"], RadioButtonBar[Dynamic[color], {Red, Green, Blue}]},
      {Style["Radius", "SR"], RadioButtonBar[Dynamic[r], {1., 1.5}]}}];
  Column[{
    ClickPane[
      Framed[
        Dynamic @
          Graphics[{color, Disk[{0, 0}, r]}, 
            PlotRange -> {{-2, 2}, {-2, 2}},
            ImageSize -> Medium]],
      If[Norm[#] < r, controls = grid, controls = ""] &],
    Dynamic @ controls},
    Center]]

When the above code is evaluated, the output cell it generates looks like this

initial-disk

After clicking inside the disk, the controls become visible, and the disk can be adjusted and be made to look this.

disk-with-controls

Clicking outside the disk hides the controls.

I chose radio button bars for the controls in this example, but any controls can be put in the control grid.

| improve this answer | |
$\endgroup$
  • $\begingroup$ @Karsten7. From DialogInput under Possible Issues: "DialogInput blocks the queued evaluation channel, preventing queued controls from working". $\endgroup$ – m_goldberg Oct 23 '15 at 2:03
  • $\begingroup$ @Karsten7. I made the change you suggested concerning Norm[#] < r. Good catch. $\endgroup$ – m_goldberg Oct 23 '15 at 2:06
  • $\begingroup$ Thank you for the clarification. I modified your code in my answer to have the controls switch on or off by the DialogInput. $\endgroup$ – Karsten 7. Oct 23 '15 at 4:09
1
$\begingroup$

A modification of the code in the anwer by m_goldberg, that uses DialogInput to switch the controls on and off:

DynamicModule[{grid, color = Red, r = 1., controls = ""}, 
 grid = Grid[{{Style["Color", "SR"], 
     RadioButtonBar[Dynamic[color], {Red, Green, Blue}]}, {Style[
      "Radius", "SR"], RadioButtonBar[Dynamic[r], {1., 1.5}]}}];
 Column[{Dynamic@
    ClickPane[
     Framed[Graphics[{color, Disk[{0, 0}, r]}, 
       PlotRange -> {{-2, 2}, {-2, 2}}, ImageSize -> Medium]], 
     If[Norm[#] < r, 
       controls = 
        DialogInput[
         Grid[{{CancelButton[DialogReturn[""]], 
            DefaultButton[DialogReturn[grid]]}}]], controls = ""] &, 
     Method -> "Queued"], Dynamic@controls}, Center]]
| improve this answer | |
$\endgroup$
  • $\begingroup$ good finding, ClickPane now does have the Method option as well, although not yet documented. That of course solves the OPs problem in the most straightforward way... $\endgroup$ – Albert Retey Oct 24 '15 at 18:25
  • 1
    $\begingroup$ just for completeness: the Method option for ClickPane seems to be new for version 10.2, in all older versions it isn't listed in the Options, and it also doesn't seem to work for those... $\endgroup$ – Albert Retey Oct 24 '15 at 18:32
  • $\begingroup$ @AlbertRetey Thanks for pointing that out. I wasn't aware of that. Mathematica v9 got messed up, as I just tried to run my code. $\endgroup$ – Karsten 7. Oct 24 '15 at 19:00
1
$\begingroup$

As others have explained the trick to get this working with a modal dialog is to not use the preemptive but the queued method. The easiest way to achieve this is to just use a button which doesn't look like one. Here is a straightforward translation of your ClickPane example:

Button[
   Framed[Graphics[{Red, Disk[{0, 0}, 1]}, 
     PlotRange -> {{-2, 2}, {-2, 2}}]], 
     Function[If[Norm[#] < 1, 
       DialogInput[
         Grid[{{#, SpanFromLeft}, {CancelButton[], 
         DefaultButton[DialogReturn[1]]}}]]];
     ][MousePosition["Graphics"]],
  Method -> "Queued",
  Appearance -> None
]

but for what you describe as your actual goal it would be even easier to use a button for the object you want to change directly:

Framed[Graphics[{
  Red,
  Button[
    Disk[{0, 0}, 1], 
    DialogInput[
      Grid[{{CancelButton[], DefaultButton[DialogReturn[1]]}}]], 
      Method -> "Queued",
      Appearance -> None
    ]
  },
  PlotRange -> {{-2, 2}, {-2, 2}}
]]
| improve this answer | |
$\endgroup$
  • $\begingroup$ The first way works well. The second way is still slow. Is this related to using Mac OS? $\endgroup$ – Christian Mullon Oct 23 '15 at 10:16
  • $\begingroup$ @ChristianMullon: it might be Mac OS but it also could be the Mathematica version you are using. I tried this with Mathematica 10.2 on Windows 7 and it does not run into the timeout as the clickplane version does... $\endgroup$ – Albert Retey Oct 24 '15 at 18:20
  • $\begingroup$ As Karsten found Clickpane does itself have a Method->"Queued" option which I think is the most simple and probably best to use for your example... $\endgroup$ – Albert Retey Oct 24 '15 at 18:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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