8

Compare the two dialog windows, created by the same code except in the first WindowSize has a value while I omit it in the second one. Note, that CreateDialog (and especially its default option WindowSize -> All) can lead to unexpected behaviour.

DynamicModule[{switch = 1},
  CreateDialog[
   DocumentNotebook@TextCell@Dynamic@Switch[switch, 1, "A", 2, "B"],
   WindowSize -> {200, 100}]];

DynamicModule[{switch = 1},
  CreateDialog[
   DocumentNotebook@TextCell@Dynamic@Switch[switch, 1, "A", 2, "B"]
   ]];

Mathematica graphics

While the value of the WindowSize option is recognized and used on the left, any explicit value prevents the evaluation of the dynamic content (be it a number, list of numbers, Automatic, Full, etc.). The same behavior is experience if Module is used instead of DynamicModule. Is it a bug? I need a workaround that works with a fullscreen window (i.e. WindowSize -> Full), any idea?

1. Update

Even more strange is the workaround that I've found by eliminating part of my code, expression-by-expression. I ended up with the following stripped piece:

DynamicModule[{a = 1, b, c, d, e, f, g, h, i, j, k},
  b = Plot3D[Join@{x, y}, {x, 0, 1}, {y, 0, 1}];
  CreateDialog[Dynamic@Switch[a, 1, "A"], WindowSize -> {200, 100}]
  ];

which correctly produces the dialog on the left, while (and this is the strangest bug I've ever experienced in Mathematica so far) when I comment out any part of this code it results in an unevaluated Switch in the dialog window (on the right)!

Mathematica graphics

Below are some examples, that obviously should not change the output, but they do, and are producing the above right dialog. I think this behaviour has something to do with the parsing of DynamicModule, but I am quite clueless...

DynamicModule[{a = 1, b(*,c,d,e,f,g,h,i,j,k*)},
  b = Plot3D[Join@{x, y}, {x, 0, 1}, {y, 0, 1}];
  CreateDialog[Dynamic@Switch[a, 1, "A"], WindowSize -> {200, 100}]
  ];

DynamicModule[{a = 1, b, c, d, e, f, g, h, i, j(*,k*)},
  b = Plot3D[Join@{x, y}, {x, 0, 1}, {y, 0, 1}];
  CreateDialog[Dynamic@Switch[a, 1, "A"], WindowSize -> {200, 100}]
  ];

DynamicModule[{a = 1, b, c, d, e, f, g, h, i, j, k},
  b = Plot3D[(*Join@*){x, y}, {x, 0, 1}, {y, 0, 1}];
  CreateDialog[Dynamic@Switch[a, 1, "A"], WindowSize -> {200, 100}]
  ];

DynamicModule[{a = 1, b, c, d, e, f, g, h, i, j, k},
  (*b =*)Plot3D[Join@{x, y}, {x, 0, 1}, {y, 0, 1}];
  CreateDialog[Dynamic@Switch[a, 1, "A"], WindowSize -> {200, 100}]
  ];

DynamicModule[{a = 1, b, c, d, e, f, g, h, i, j, k},
  (*b=Plot3D[Join@{x,y},{x,0,1},{y,0,1}];*)
  b = Plot3D[x, {x, 0, 1}, {y, 0, 1}];
  CreateDialog[Dynamic@Switch[a, 1, "A"], WindowSize -> {200, 100}]
  ];

Each of these were tried with a fresh kernel, without any user package loaded.

2. Update

The following example shows that the variable a displayed in the dialog has no initial value in spite of defining it two times (note however that the Initialization code is not evaluated at all, you can make sure about that by putting any Print in it):

DynamicModule[{a = None},
  Print[a];
  CreateDialog[{
    Dynamic@a,
    Dynamic@Switch[a, True, "A", False, "B", None, "C"],
    (*Checkbox@Dynamic@a*)
    }, WindowSize -> {200, 100}],
  Initialization :> (a = None)
  ];

None

Mathematica graphics

Thus a has a value (None) inside the DynamicModule but not inside the dialog. Uncommenting the commented line proves that the a displayed in the dialog is not the same as the a being locally defined in DynamicModule:

DynamicModule[{a = None},
  Print[a];
  CreateDialog[{
    Dynamic@a,
    Dynamic@Switch[a, True, "A", False, "B", None, "C"],
    Checkbox@Dynamic@a
    }, WindowSize -> {200, 100}],
  Initialization :> (a = None)
  ];

None

Mathematica graphics

that is: still printing None as the value of the DynamicModule-a, but displaying False as the dialog-a, which is the default value that Checkbox assignes to a variable without any value.

To conclude: a dialog does not necessarily inherit the variables of its enclosing (Dynamic)Module.

Printing Dynamic@a instead of simply a helps, as it forces the front-end to claim the dynamically displayed a of the wrapping module. Please correct me if I'm wrong.

DynamicModule[{a = None},
  Print[Dynamic@a];
  CreateDialog[{
    Dynamic@a,
    Dynamic@Switch[a, True, "A", False, "B", None, "C"],
    Checkbox@Dynamic@a
    }, WindowSize -> {200, 130}],
  Initialization :> (a = None)
  ];

Mathematica graphics

**3. Update: **

The purpose of this construction is to design a gui where the displayed content switches according to user interaction. While there might be easier ways to do this, I am now inclined to solve the underlyings of this behavior. The following example uses three "screens" as different contents (first, second, third). Changes made to dynamic controls in one screen should affect other screens (hence the variable x).

DynamicModule[{a = 1, x = .5, first, second, third},
  first := Column@{"First", Row@{"x: ", Slider@Dynamic@x}, Button["Next", a = 2]};
  second := Column@{"Second", Row@{"x: ", Dynamic@x}, Button["Next", a = 3]};
  third := Column@{"Third", Button["Reset x", x = .5], Button["Next", a = 1]};
  CreateDialog[Dynamic@Switch[a,
     1, first,
     2, second,
     3, third
     ], WindowSize -> {300, 200}]];
István Zachar
  • 47,032
  • 20
  • 143
  • 291
  • I don't think this has to do with the presence of the WindowSize option. I get the same behaviour in both windows. – Sjoerd C. de Vries May 09 '12 at 19:52
  • @SjoerdC.deVries the same correct or incorrect behaviour? Otherwise, you must be right, see my edit. – István Zachar May 09 '12 at 20:01
  • The same incorrect (or, better, unintended) behavior. I think this is a scoping issue. – Sjoerd C. de Vries May 09 '12 at 20:03
  • I noticed that the same code executed from a FrontEnd window that has its own Context works as I described, whereas a standard window does what you reported. – Sjoerd C. de Vries May 09 '12 at 20:06
  • 1
    The wormhole section of tutorial/AdvancedDynamicFunctionality might be relevant here – Sjoerd C. de Vries May 09 '12 at 20:11
  • @IstvánZachar, I get the same behaviour as you. A simple workaround seems to be to set nb=DocumentNotebook[...] and then CreateDialog[nb,...]. – Simon Woods May 09 '12 at 20:12
  • "The variables declared in a DynamicModule are localized to a particular rectangular area within one cell in a notebook. There are situations in which it is desirable to extend the scope of such a local variable to other cells or even other windows. For example, you might want to have a button in one cell that opens a dialog box that allows you to modify the value of a variable declared in the same scope as the button that opened the dialog." – Sjoerd C. de Vries May 09 '12 at 20:15
  • @Sjoerd, I will try to wrap my head around that, but I'm afraid this won't explain (or at least I fail to see how) the behaviour experienced in the update: neither of the examples should give different results, as neither of the changes affect the output. – István Zachar May 09 '12 at 20:19
  • I was still working on your first part and haven't looked at your update yet. I don't get the wormhole to work at the moment. – Sjoerd C. de Vries May 09 '12 at 20:21
  • The CreateDialog doc page says: "CreateDialog by default creates a notebook with options set so as to be suitable for the appearance and behavior of a typical dialog box. The option settings include Deployed->True, ShowCellBracket->False, WindowFloating->False and WindowSize->All." So, it seems as if WindowSize isn't an option of CreateDialog (it isn't present in the options section of the doc either). – Sjoerd C. de Vries May 09 '12 at 20:29
  • Your code works fine for me. {Mac OS X 7.3, MMA 8.0.4} – DavidC May 09 '12 at 20:44
  • By "works fine", I mean I am not able to reproduce any of your problems. – DavidC May 09 '12 at 20:45
  • @SimonWoods This does not work for me, neither with local (to DynamicModule) or global nb. Could you perhaps post a working example as an answer? I would appreciate that! – István Zachar May 10 '12 at 08:20
  • @IstvánZachar, example posted. – Simon Woods May 10 '12 at 09:11
  • While you are right that the behavior you reported looks rather inconsistent and could/should be improved, I woudn't consider that to be a problem in practice. What you do I'd consider to not be "within the specification" and doesn't seem to make much sense, honestly. Could you describe what you try to achieve? I think Sjoerds suggestion to look at the wormhole section of the advanced section will most probably provide a solution to what you try to achieve, but it's hard to say from just seeing your examples... – Albert Retey May 10 '12 at 14:18
  • @AlbertRetey Please see edit, hope it makes things clear. – István Zachar May 11 '12 at 19:14
  • I've seen the edit, but from what you show there the first suggestion of user840 will be a perfect solution, can you explain why that wouldn't work for you? I don't think it makes sense to try to understand the behavior of a construct which probably isn't considered to make sense by the developers. It could well be they would decide that the correct behavior would be to consistently not work at all. See Sjoerd's citation from the wormhole section of tutorial/AdvancedDynamicFunctionality for details why your construct isn't making sense as it is written. – Albert Retey May 13 '12 at 12:08

2 Answers2

5

The following works for me with Mathematica 8.0.4

DynamicModule[{switch = 1},
CreateDialog[
globalvar = DocumentNotebook@TextCell@Dynamic@Switch[switch, 1, "A", 2, "B"], 
WindowSize -> {200, 100}]];

However making the variable local to the DynamicModule does not work:

DynamicModule[{switch = 1, localvar},
CreateDialog[
localvar = DocumentNotebook@TextCell@Dynamic@Switch[switch, 1, "A", 2, "B"], 
WindowSize -> {200, 100}]];

It also fails if the variable is localized in a Module wrapping the whole thing:

Module[{localvar},
DynamicModule[{switch = 1},
CreateDialog[
localvar = DocumentNotebook@TextCell@Dynamic@Switch[switch, 1, "A", 2, "B"],
WindowSize -> {200, 100}]]];    
Simon Woods
  • 84,945
  • 8
  • 175
  • 324
  • Your first example (simply saving the dialog into a global variable) solves even my last problem of variables not referring to the same values (see latest edit in my post: module-a and dialog-a). Thanks! – István Zachar May 10 '12 at 09:51
3

Just replacing the DynamicModule in the right place may help...

CreateDialog[DynamicModule[{switch = 2}, 
  DocumentNotebook@TextCell@Switch[switch, 1, "A", 2, "B"]], 
  WindowSize -> {200, 100}];

or (see the comments below)

DynamicModule[{switch = True}, 
 CreateDialog[TextCell@{Dynamic@Switch[switch, True, "A", False, "B"],
 Checkbox@Dynamic@switch}, WindowSize -> {200, 100}]];
s.s.o
  • 4,559
  • 2
  • 27
  • 42
  • And what if switch is not local to the dialog? – István Zachar May 10 '12 at 07:59
  • switch = 2; CreateDialog[ DynamicModule[{}, DocumentNotebook@TextCell@Switch[switch, 1, "A", 2, "B"]], WindowSize -> {200, 100}]; also works. I think it's related to kernel-thread and gui-thread issue. the not running ones defined dynamic variables at kernel not at gui and there might be the problem. Just a guess. – s.s.o May 10 '12 at 08:33
  • While it displays correctly, but nothing tracks switch, so the content is not updated if switch changes, see example: switch = True; CreateDialog[DynamicModule[{}, TextCell@{Switch[switch, True, "A", False, "B"], Checkbox@Dynamic@switch}], WindowSize -> {200, 100}];. – István Zachar May 10 '12 at 08:52
  • So a working example would be like this: DynamicModule[{switch = True}, CreateDialog[TextCell@{Dynamic@Switch[switch, True, "A", False, "B"], Checkbox@Dynamic@switch}, WindowSize -> {200, 100}]];. – István Zachar May 10 '12 at 08:53