From: Ariel SepĂșlveda on
Hi Jason:

I had dynamic content in a docked cell in a M6 application and it stopped
working in M7. I asked for WRI support and they told me that there is a bug
that doesn't permit docked cells to behave as expected with dynamic content.
Thanks for your question as it will make this issue more important for them.

Ariel

-----Original Message-----
From: Jason Ledbetter [mailto:jasonbrent(a)gmail.com]
Sent: Tuesday, October 20, 2009 4:55 AM
Subject: Question on Dynamic with "DockedCell"

Folk,
I'm attempting to create a dynamically-appearing set of choices/menus using
ButtonBar in a notebook window but I've been unable to get the desired
affect to date. I've cobbled together the following code which almost does
what I'm looking for but I could use some pointers in getting the rest of
the way.

The goal here is for the "topMenu" items to appear when the notebook is
first instantiated and for the "secondMenu" option to appear when a
"topMenu" option is selected. As it stands now, I'm having to start with the
"secondMenu" option pre-defined to a bogus value.

If I were to abstract my goal some more, I'm trying to figure out how to
dynamically add/remove RowBox items that include ButtonBars from the
notebook based on options that are selected.

I'm guessing that I somehow need to programmatically generate the contents
of a Dynamically wrapped RowBox (e.g., Dynamic[RowBox[...]]) but I'm not
quite sure how to go about that just yet.

Any help is greatly appreciated...

Here's what I have thus far:

--snip--
Module[

{topMenu, secondMenu},

topMenu = {"option1", "option2"};
secondMenu = {"No option selected"};

menuChoice[choice_] := Module[{},
Switch[choice,
"option1", secondMenu = {"one", "selected"},
"option2", secondMenu = {"two", "selected"}, _, Print[choice]
]];

CreateWindow[DockedCells -> Cell[
RowBox[
{
ToBoxes[
ButtonBar[ToString[#] :> menuChoice[#] & /@ topMenu]
],
ToBoxes[
Dynamic[
ButtonBar[ToString[#] :> menuChoice[#] & /@ secondMenu]
]
]
}
],
"DockedCell"],
TextAlignment -> Center
]
];

--snip--


thanks,


-jbl


From: David Reiss on
Hi Jason,

I have run into this as well when I wanted to create a menu in a
DockedCell that displayed the current set of files in a particular
directory. One issue is that one has to trigger any Dynamic that is
in the cell, and for some cases one doesn't want something constantly
testing the cou=mputer's filesystem for changes. I had played with
Refresh and things like that.

A solution that I came up with, that served my particular application
needs was to create a reason for a menu to update.

So, my menu was generated through a function likethe following. Note
that it has an argument, but the parameter in the arrument is not used
in the funtion:

myMenu[z_] :=
ActionMenu["Open...",
FileNameTake[#, -1] :> SystemOpen[#] & /@
FileNames[{"*"}, {$UserDocumentsDirectory}]]

Note that if you create a cell with this menu in it it will not update
if you add or remove a file in $UserDocumentsDirector:

TextCell[Dynamic[myMenu[1]], "Text"] // CellPrint

The trick now is to introduce a new function which has as its only
purpose to change the value of a parameter: $MysteryParameter. Make
sure that that parameter is Unprotected if it is in a Package.
$MysteryParameter will be used in the argument to myMenu to force it
to trigger the Dynamic. And this will be acomplished by having the
Cell that contains the menu have a CellEventAction.

$MysteryParameter = 1;

Toggle$MysteryParameter[] :=
Switch[$MysteryParameter,

1,
$MysteryParameter = 2,

2,
$MysteryParameter = 1,

_,
$MysteryParameter = 1];

And finally one intruduces a CellEventAction to the cell that causes
the value of $MysteryParameter to change and thereby causes the myMenu
in the Dynamic to update because its argument has changed.

TextCell[Dynamic[myMenu[$MysteryParameter]], "Text",
CellEventActions -> {"MouseMoved" :> (Toggle$MysteryParameter
[])}] // \
CellPrint

Or, in a DockedCell

SetOptions[EvaluationNotebook[],
DockedCells -> {
MakeBoxes@
TextCell[Dynamic[myMenu[$MysteryParameter]], "DockedCell",
CellEventActions -> {"MouseMoved" :> (Toggle$MysteryParameter
[])},
StripOnInput -> True]}
]

I hope this helps....

--David
http://scientificarts.com/worklife




On Oct 20, 4:51 am, Jason Ledbetter <jasonbr...(a)gmail.com> wrote:
> Folk,
> I'm attempting to create a dynamically-appearing set of choices/menus usi=
ng
> ButtonBar in a notebook window but I've been unable to get the desired
> affect to date. I've cobbled together the following code which almost doe=
s
> what I'm looking for but I could use some pointers in getting the rest of
> the way.
>
> The goal here is for the "topMenu" items to appear when the notebook is
> first instantiated and for the "secondMenu" option to appear when a
> "topMenu" option is selected. As it stands now, I'm having to start with =
the
> "secondMenu" option pre-defined to a bogus value.
>
> If I were to abstract my goal some more, I'm trying to figure out how to
> dynamically add/remove RowBox items that include ButtonBars from the
> notebook based on options that are selected.
>
> I'm guessing that I somehow need to programmatically generate the content=
s
> of a Dynamically wrapped RowBox (e.g., Dynamic[RowBox[...]]) but I'm not
> quite sure how to go about that just yet.
>
> Any help is greatly appreciated...
>
> Here's what I have thus far:
>
> --snip--
> Module[
>
> {topMenu, secondMenu},
>
> topMenu = {"option1", "option2"};
> secondMenu = {"No option selected"};
>
> menuChoice[choice_] := Module[{},
> Switch[choice,
> "option1", secondMenu = {"one", "selected"},
> "option2", secondMenu = {"two", "selected"}, _, Print[choice=
]
> ]];
>
> CreateWindow[DockedCells -> Cell[
> RowBox[
> {
> ToBoxes[
> ButtonBar[ToString[#] :> menuChoice[#] & /@ topMenu]
> ],
> ToBoxes[
> Dynamic[
> ButtonBar[ToString[#] :> menuChoice[#] & /@ secondMenu=
]
> ]
> ]
> }
> ],
> "DockedCell"],
> TextAlignment -> Center
> ]
> ];
>
> --snip--
>
> thanks,
>
> -jbl


From: Jason Ledbetter on
Adam,
Thank you- that actually helped a lot. I've got something passible, albeit
hard coded at the moment that works as I was hoping. Going through and
looking at low-level constructs helped a ton in comprehending what was going
on here.

That said, one question I'm hoping someone can answer.

How can this be cleaned up (current code below) so that I'm not reusing the
"topMenu" code on both sides of a Dynamic[If[...]?

I previously just wrapped the secondMenu Row[..] in the Dynamic[If[...] but
that resulted in "Null" being printed in the docked cell until a top level
menu item was selected.

--snip--

Module[
{topMenu, secondMenu, secondEnable},

secondEnable = False;
topMenu = {"option1", "option2"};


menuChoice[choice_] := Module[{},
Switch[choice,
"option1", (secondEnable = True; secondMenu = {"one", "selected"}),
"option2", (secondEnable = True; secondMenu = {"two", "selected"}), _,
Print[choice]
]];

CreateWindow[DockedCells -> Cell[BoxData[ToBoxes(a)DynamicModule[{},

Dynamic[If[secondEnable == True,
Column[{
Row[{
Style["Top:", Bold],
ButtonBar[ToString[#] :> menuChoice[#] & /@ topMenu]
}],

Row[{
Style["Second:", Bold],
ButtonBar[ ToString[#] :> menuChoice[#] & /@ secondMenu]
}]
}](*endColumn*),
Row[{
Style["Top:", Bold],
ButtonBar[ToString[#] :> menuChoice[#] & /@ topMenu]
}]
]]

](*endDynamicModule*)
](*endBoxData*)
, "DockedCell"],
TextAlignment -> Left](*endCreateWindow*)
];

--snip--

Thanks again for everyone's helpful responses to date.

-jbl

On Tue, Oct 20, 2009 at 4:57 PM, Adam Griffith <adamg(a)wolfram.com> wrote:

> Hi Jason,
>
> Yes, the documentation on these topics is in the works for a future
> Mathematica release.
>
> The trick here is to notice that the option DockedCells takes low-level
> cell expressions. So anything that is included must be written in the
> low-level box structure of the front end. For example, type something into
> an input cell, run it, and then choose Cell>Show Cell Expression on the
> output cell to view the low-level code.
>
> So what I did here:
> Notebook[........ , DockedCells->Cell[BoxData[ToBoxes(a)DynamicModule[.....
> all code.....]], "DockedCell"]]
>
> was to let the front end generate the necessary box structure for the
> DynamicModule by using ToBoxes[] since I didn't want to have to write it
> myself. For example,
>
> In[1]:= ToBoxes[a + b^2]
>
> Out[1]= RowBox[{"a", "+", SuperscriptBox["b", "2"]}]
>
> Then since we are dealing with boxes, the contents are wrapped in
> BoxData[].
>
> Hope this helps,
> -Adam
>
> Jason Ledbetter wrote:
>
>> Hmm. That organizational structure is different than what I'm using. I
>> guess I need to comprehend the box structure of mathematica... for example
>> "BoxData" doesn't seem to be a documented primitive (It is referenced
>> inside the Cell[] documentation as a one-liner).
>>
>> Is there a how-to or otherwise some documentation that describes when to
>> use BoxData vs. ToBoxes vs. whatever or is it one of those "It depends and
>> it's complicated" things?
>>
>> -jbl
>>
>> On Tue, Oct 20, 2009 at 2:09 PM, Adam Griffith <adamg(a)wolfram.com<mailto:
>> adamg(a)wolfram.com>> wrote:
>>
>> I would suggest placing the code for the menus in a DynamicModule.
>>
>>
>> Notebook[........ ,
>> DockedCells->Cell[BoxData[ToBoxes(a)DynamicModule[..... all
>> code.....], "DockedCell"]]
>>
>> -Adam
>>
>>
>> Jason Ledbetter wrote:
>>
>> Folk,
>> I'm attempting to create a dynamically-appearing set of
>> choices/menus using
>> ButtonBar in a notebook window but I've been unable to get the
>> desired
>> affect to date. I've cobbled together the following code which
>> almost does
>> what I'm looking for but I could use some pointers in getting
>> the rest of
>> the way.
>>
>> The goal here is for the "topMenu" items to appear when the
>> notebook is
>> first instantiated and for the "secondMenu" option to appear
>> when a
>> "topMenu" option is selected. As it stands now, I'm having to
>> start with the
>> "secondMenu" option pre-defined to a bogus value.
>>
>> If I were to abstract my goal some more, I'm trying to figure
>> out how to
>> dynamically add/remove RowBox items that include ButtonBars
>> from the
>> notebook based on options that are selected.
>>
>> I'm guessing that I somehow need to programmatically generate
>> the contents
>> of a Dynamically wrapped RowBox (e.g., Dynamic[RowBox[...]])
>> but I'm not
>> quite sure how to go about that just yet.
>>
>> Any help is greatly appreciated...
>>
>> Here's what I have thus far:
>>
>> --snip--
>> Module[
>>
>> {topMenu, secondMenu},
>>
>> topMenu = {"option1", "option2"};
>> secondMenu = {"No option selected"};
>>
>> menuChoice[choice_] := Module[{},
>> Switch[choice,
>> "option1", secondMenu = {"one", "selected"},
>> "option2", secondMenu = {"two", "selected"}, _, Print[choice]
>> ]];
>>
>> CreateWindow[DockedCells -> Cell[
>> RowBox[
>> {
>> ToBoxes[
>> ButtonBar[ToString[#] :> menuChoice[#] & /@ topMenu]
>> ],
>> ToBoxes[
>> Dynamic[
>> ButtonBar[ToString[#] :> menuChoice[#] & /@ secondMenu]
>> ]
>> ]
>> }
>> ],
>> "DockedCell"],
>> TextAlignment -> Center
>> ]
>> ];
>>
>> --snip--
>>
>>
>> thanks,
>>
>>
>> -jbl
>>
>>
>>


From: John Fultz on
Ariel:

Whoa, there!!!

I can't vouch for exactly what WRI support told you, or what may not have worked
in your case. But the general statement, as you made it, that "there is a bug
that doesn't permit docked cells to behave as expected with dynamic content", is
patently false. Dynamic content is used all the time in docked cells in
built-in parts of Mathematica. In the most visible example, the help viewer
toolbar is absolutely riddled with dynamic content.

I'd be happy to discuss more with you about whatever your specific problem was,
although I'm pretty busy right now (but if you're coming to the conference, you
can track me down there).


Jason:

I haven't responded to the original post due, in part, to a lack of time, and
also I thought that others might be able to answer this question. Adam
Griffith's responses are a great place to begin. If you're still having
problems, feel free to ping me again.

Sincerely,

John Fultz
jfultz(a)wolfram.com
User Interface Group
Wolfram Research, Inc.



On Wed, 21 Oct 2009 06:33:33 -0400 (EDT), Ariel SepFAlveda wrote:
> Hi Jason:
>
> I had dynamic content in a docked cell in a M6 application and it stopped
> working in M7. I asked for WRI support and they told me that there is a
> bug that doesn't permit docked cells to behave as expected with dynamic
> content. Thanks for your question as it will make this issue more
> important for them.
>
> Ariel
>
> -----Original Message-----
> From: Jason Ledbetter [mailto:jasonbrent(a)gmail.com]
> Sent: Tuesday, October 20, 2009 4:55 AM
> To: mathgroup(a)smc.vnet.net
> Subject: Question on Dynamic with "DockedCell"
>
> Folk,
> I'm attempting to create a dynamically-appearing set of choices/menus
> using
> ButtonBar in a notebook window but I've been unable to get the desired
> affect to date. I've cobbled together the following code which almost does
> what I'm looking for but I could use some pointers in getting the rest of
> the way.
>
> The goal here is for the "topMenu" items to appear when the notebook is
> first instantiated and for the "secondMenu" option to appear when a
> "topMenu" option is selected. As it stands now, I'm having to start with
> the
> "secondMenu" option pre-defined to a bogus value.
>
> If I were to abstract my goal some more, I'm trying to figure out how to
> dynamically add/remove RowBox items that include ButtonBars from the
> notebook based on options that are selected.
>
> I'm guessing that I somehow need to programmatically generate the contents
> of a Dynamically wrapped RowBox (e.g., Dynamic[RowBox[...]]) but I'm not
> quite sure how to go about that just yet.
>
> Any help is greatly appreciated...
>
> Here's what I have thus far:
>
> --snip--
> Module[
>
> {topMenu, secondMenu},
>
> topMenu = {"option1", "option2"};
> secondMenu = {"No option selected"};
>
> menuChoice[choice_] := Module[{},
> Switch[choice,
> "option1", secondMenu = {"one", "selected"},
> "option2", secondMenu = {"two", "selected"}, _, Print[choice]
> ]];
>
> CreateWindow[DockedCells -> Cell[
> RowBox[
> {
> ToBoxes[
> ButtonBar[ToString[#] :> menuChoice[#] & /@ topMenu]
> ],
> ToBoxes[
> Dynamic[
> ButtonBar[ToString[#] :> menuChoice[#] & /@ secondMenu]
> ]
> ]
> }
> ],
> "DockedCell"],
> TextAlignment -> Center
> ]
> ];
>
> --snip--
>
>
> thanks,
>
>
> -jbl