Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make selective drop down menu in Mathematica?

I am running out of space on the Manipulate interface. So, I am looking to see if I can overload a PopupMenu to serve more than one purpose.

Here is the problem:

I have a PopupMenu where I use to select an entry from it. But depending on another choice I make somewhere else, some of these entries in the menu will no longer make sense to select.

So, I was wondering, if I can make some of the entries in the PopupMenu 'selectable' based on a setting of a Dynamic? (may be disabled, or grayed out, or what would be best, have the whole list itself by dynamic, i.e. the whole popUp menu be dyanmic, so I can select different menus based on value of another dynamic. But I do not think this is possible)

Currently, the WHOLE PopupMenu can be enabled or disabled based on a dynamic setting. But I want to do this at the entry level inside the Popupmenu.

Here is an example to illustrate:

Manipulate[selection,
 Grid[{
   {"x", SetterBar[Dynamic[x], {1, 2}]},
   {"selection", PopupMenu[Dynamic[selection],
     {
      "NONE", "SOR", "SSOR"
      }, Enabled -> Dynamic[x == 1]], SpanFromLeft
    }
   }]
 ]

enter image description here

In the above, when X=1, the whole menu is enabled.

But what I want, if X=1, is to be able to select only say "NONE" (or the list just show "NONE"), and when X=2, then be able to select only "SOR" and "SSOR" (or the list just show these 2 choices).

i.e. the system will not let "SOR" be selected if x=2. Trying to select it will cause no change and the menu will remain on its previous setting and not change.

Again, I know I can break things into 2 popuMenus, and control each one based on X setting like this below, but I do not have more space to add more menus:

Manipulate[If[x == 1, selectionA, selectionB],
 Grid[{
   {"x", SetterBar[Dynamic[x], {1, 2}]},
   {"selection", PopupMenu[Dynamic[selectionA],
     {
      "NONE"
      }, Enabled -> Dynamic[x == 1]], SpanFromLeft
    },
   {"selection", PopupMenu[Dynamic[selectionB],
     {
      "SOR", "SSOR"
      }, Enabled -> Dynamic[x == 2]], SpanFromLeft
    }
   }]
 ]

enter image description here

My question is: Is there a way to do the above in Mathematica? I am using 8.04.

Best solution would be to have the list of items for the menu itself by Dynamic (or the whole menu be dynamic), so I can tell it to use listA when X=1 or use listB when X=2, etc.. But I do not know how to do this and do not know if it is even possible.

ps. This is my current attempt at a solution

Manipulate[selection,

 Grid[{
   {"x", SetterBar[Dynamic[x], {1, 2}]},
   {"selection", PopupMenu[Dynamic[selection],
     {
      Dynamic[If[x == 1, listA, listB]]
      }
     ]
    }
   }
  ],
 Initialization :>
  (
   listA = {"A", "B"};
   listB = {"C", "D"};
   )
 ]

But it is not working too well yet. Will keep at it....

thanks

Update:

Looking at Simon solution below inspired me a little more, so this is what I have so far:

Manipulate[selection,

 Grid[{
   {"x", SetterBar[Dynamic[x], {1, 2}]},
   {"selection",

    Dynamic[If[x == 1,
      (
       selection = "A";
       PopupMenu[Dynamic[selection], {"A", "B"}]
       ),
      (
       selection = "C";
       PopupMenu[Dynamic[selection], {"C", "D"}]
       )
      ]
     ]
    }
   }
  ]
 ]

enter image description here

like image 970
Nasser Avatar asked Dec 07 '11 12:12

Nasser


2 Answers

Is this the type of thing you're looking for?

Manipulate[
 Switch[x,
        1, If[selection =!= None, selection = None],
        2, If[selection === None, selection = "SOR"]];
 selection,
 {x, {1, 2}, ControlType -> SetterBar},
 {{selection, None}, Switch[x, 1, {None}, 2, {"SOR", "SSOR"}, _, {"huh"}], 
  ControlType -> PopupMenu}]

Note the Switch at the top that controls the defaults for selection when x is changed.


Edit:

Following your request to have the menu logic localised to the control Grid and stealing Heike's default mechanism, here's a new version:

Manipulate[selection,
 Grid[With[{menu = {{None}, {"A", "B"}, {"emu", "num"}}},
   {{"Which menu?", SetterBar[Dynamic[x], Range[Length[menu]]]},
    {"Menu selection:", Dynamic[
      If[MemberQ[menu[[x]], selection], selection = menu[[x, 1]]];
      PopupMenu[Dynamic[selection], menu[[x]]]]}}]],
 {{selection, None}, None}, {{x, 1}, None}]

a boring screenshot

Note that the menu list does not need to be localized with a With statement - it can be set elsewhere in the code.

like image 88
Simon Avatar answered Nov 15 '22 14:11

Simon


This solution is similar to Simon's answer, but it doesn't explicitly use the number of lists so it should work for an arbitrary number of lists

choices = {{"a", "b", "c"}, {None}, {"e", "f"}};

Manipulate[
 If[Not[MemberQ[x, selection]], selection = x[[1]]];
 selection,
 {{x, choices[[1]]}, MapIndexed[# -> #2[[1]] &, choices], SetterBar}, 
 {selection, x, ControlType -> PopupMenu}]
like image 34
Heike Avatar answered Nov 15 '22 12:11

Heike