Re: Multi-level Menu (ActionMenu)
- To: mathgroup at smc.vnet.net
- Subject: [mg100623] Re: [mg100591] Multi-level Menu (ActionMenu)
- From: Leonid Shifrin <lshifr at gmail.com>
- Date: Tue, 9 Jun 2009 03:58:22 -0400 (EDT)
- References: <200906081018.GAA26491@smc.vnet.net>
Hi Chris, Below is the closest analog I found (I am not a UI person and you will probably get better solutions from others, but still) : suppose your menu data is in such a structure: In[1] = menuItems = {{"Africa", {{"Algeria", {"Algiers", "Oran"}}, {"Angola", {"Luanda", "Huambo"}}} }, {"North America", {{"United States", {"New York", "Washington"}}, {"Canada", {"Toronto", "Montreal"}}} }}; The first auxiliary function adds actions to the lower-level menu items: In[2] = Clear[addLowestItemActions]; addLowestItemActions[menuItemTree_, f_] := Map[# :> f[#] &, menuItemTree, {Depth[menuItemTree] - 1}]; Example: In[3] = Clear[h]; addLowestItemActions[menuItems, h] Out[3] = {{"Africa", {{"Algeria", {"Algiers" :> h["Algiers"], "Oran" :> h["Oran"]}}, {"Angola", {"Luanda" :> h["Luanda"], "Huambo" :> h["Huambo"]}}}}, {"North America", {{"United States", {"New York" :> h["New York"], "Washington" :> h["Washington"]}}, {"Canada", {"Toronto" :> h["Toronto"], "Montreal" :> h["Montreal"]}}}}} Another auxilliary function will transform the structure as needed in ActionMenu: In[4] = Clear[menuItemsConvert]; menuItemsConvert[itemsAndActions_, menuDepth_Integer, submenuConstructionFnames_List] /; Length[submenuConstructionFnames] == menuDepth - 1 := Fold[Function[{expr, fandlevel}, With[{fn = fandlevel[[1]]}, Apply[# :> fn[##] &, expr, fandlevel[[2]]]]], itemsAndActions, Transpose[{submenuConstructionFnames, List /@ Range[2*menuDepth - 3, 1, -2]}]]; Example: In[5] = Clear[f,g]; menuItemsConvert[addLowesItemActions[menuItems, h], 3, {f, g}] Out[5] = {"Africa" :> g["Africa", {"Algeria" :> f["Algeria", {"Algiers" :> h["Algiers"], "Oran" :> h["Oran"]}], "Angola" :> f["Angola", {"Luanda" :> h["Luanda"], "Huambo" :> h["Huambo"]}]}], "North America" :> g["North America", {"United States" :> f["United States", {"New York" :> h["New York"], "Washington" :> h["Washington"]}], "Canada" :> f["Canada", {"Toronto" :> h["Toronto"], "Montreal" :> h["Montreal"]}]}]} Finally, the main menu-building function: Clear[createDepth3CountryDataMenu]; createDepth3CountryDataMenu[menuItemTree_, actionF_] := With[{menudepth = 3}, Module[{name , subname, sub, subsub, subBack, makeSub, subsubBack, makeSubSub, subsubname = "Cities"}, subBack[] := (sub = ""; name = "Continent"); subsubBack[] := (subsub = ""; subname = "Country"); subsubBack[]; subBack[]; makeSub[nm_String, actions_List] := (name = nm; sub := ActionMenu[subname, Prepend[actions, "Back" :> (subsubBack[]; subBack[])]]); makeSubSub[nm_String, actions_List] := (subname = nm; subsub := ActionMenu[subsubname, Prepend[actions, "Back" :> subsubBack[]]]); With[{menuContent = menuItemsConvert[ addLowestItemActions[menuItemTree, actionF], menudepth, {makeSubSub, makeSub}]}, Dynamic[Row[{ActionMenu[name, menuContent], sub, subsub}]]]]] It is less generic than the previous two. It is possible to write it in a more generic way to allow it to automatically adjust to the input menu structure, but the code will look more complex. It will however then become more elegant and robust. In particular, it is possible to generate functions like makeSub, makeSubSub automatically, as well as variables <sub>, <subsub>. Note that all functions rely on a particular list data structure used to store the menu items. The usage (for example): createDepth3CountryDataMenu[menuItems , Print["The city you chose is ", #] &] Hope this helps. Regards, Leonid On Mon, Jun 8, 2009 at 3:18 AM, Chris Degnen <degnen at cwgsy.net> wrote: > Hi, Any suggestions for creating a multi-level menu, such as this: > > http://www.cafewebmaster.com/demo/css-menu/css-dhtml-menu.png > >
- References:
- Multi-level Menu (ActionMenu)
- From: Chris Degnen <degnen@cwgsy.net>
- Multi-level Menu (ActionMenu)