Dynamic PopupMenus in panels with subwindows
rhjpires
I have several popupmenus in multiple subwindows of a panel.
For some of the popupmenus I need a dynamic display of contents so that the list is populated depending on other controls within that panel. For that, I have defined the value of those popupmenus as a function that returns a list depending on choices made by the users on other controls within the same panel. That function I call here "FuncSelectList" (e.g.
PopupMenu Dynamic_PU, title="Select Something", value=FuncSelectList()
). I would like now to generate/pass awareness of which panel was clicked when I click on one of these dynamic popupmenus. My problem is that the moment that a dynamic PopupMenu is clicked, FuncSelectList() is called and I do not see how I can generate/pass subwindow awareness within that function. For a Proc() I would use an inbuilt structure in order to access the WIN variable, such as :
Function Proc_SelectData(PU_Struct) : PopupMenuControl
STRUCT WMPopupAction &PU_Struct
String sWin = PU_Struct.win
SetActiveSubwindow $sWin
//some more code goes here
End
STRUCT WMPopupAction &PU_Struct
String sWin = PU_Struct.win
SetActiveSubwindow $sWin
//some more code goes here
End
Is there a way I could take advantage of a structure within FuncSelectList() so that I can access the WIN variable? Or is there any other way I can raise window awareness within FuncSelectList()?
Thanks in advance,
R.
EccentricXPS#XPSViewPopUpWaveList(2, SubWindow, DataFolderPopUp)
every time the popup menu is clicked. Keep in mind that in your example the popup menu list is only generated once when the menu is created (if I remember correctly). To make the list dynamic you need the #("xxxxx"). There is a long description somewhere in the popup menu help.PopupMenu DisplayedWavePopUp value=#("EccentricXPS#XPSViewPopUpWaveList(2, \""+SubWindow+"\", \"DataFolderPopUp\")")
November 2, 2017 at 12:56 am - Permalink
How you are actually defining your
SubWindow
variable? I think that is my main question.Below is how I have implemented the dynamic aspect of the second
PopupMenu SelectSection
whose value is defined byFuncSelectList1()
using a Strswhich-Case-EndSwitch statement. For proper use, the user has to first make a selection on the left side PopupMenu (SelectData) which contains a simple list. Upon interaction with that popupmenu, the SubWindow number is passed to a global variableActiveSubPanel
which is recalled by FuncSelectList1() upon interaction with the dynamicPopupMenu SelectSection
which then uses that to read the selection of the SelectData popupmenu of the same panel.The problem of this approach is that correct functioning requires the user to first select the popupmenu on the left (
PopupMenu SelectData
) and then proceed to popupmenu on the right (PopupMenu SelectSection
). I would like for the subwindow to be detected and that being passed to the value ofPopupMenu SelectSection
NewPanel /W=(0,0,1200,400) /N=ResultsPanel1 /K=1
//Define Vertical guides
DefineGuide UGV0={FL,200},UGV1={UGV0,0.33333333,FR},UGV2={UGV0,0.66666666, FR}
//Define Horizonzal guides
DefineGuide UGH0={FB,0.5,FT}
Variable /G ActiveSubPanel
ActiveSubPanel = 0
string quote = "\""
String DataTypeList = quote + "A;B;C;D;E;F;G;" + quote
String sSubPanelName
Variable /G PlotCase = 1
//Create subpanels/subwindows where data will be displayed according to user input on controls
Variable i
for(i = 0; i < 2; i += 1)
switch(i)
case 0:
NewPanel/FG=(UGV0,FT,UGV1,UGH0) /HOST=ResultsPanel1
break
case 1:
NewPanel/FG=(UGV1,FT,UGV2,UGH0) /HOST=ResultsPanel1
break
endswitch
sSubPanelName = "P" + num2istr(i)
RenameWindow #,$sSubPanelName //Each subwindow has a name
//Indicate controls needed
PopupMenu SelectData, title="Data Type", mode=1, bodyWidth=110, value=#DataTypeList, pos={125,10},Proc=Proc_SelectData1
PopupMenu SelectSection, title="Section", mode=1, bodyWidth=100, value=FuncSelectList1(), pos={265,10}
// add more controls here...
SetActiveSubwindow ## //Go back to parent window
endfor
End
//---------------------------------------------------------------------------------------------------------------
Function/S FuncSelectList1()
//take the number of the active subwindow from the global variable
NVAR ActiveSubPanel
String /G Path2SubPanel = "#P"+num2str(ActiveSubPanel)
Print "Path2Subpanel is:"+Path2SubPanel
//Use the active subwindow path to extract info (S_value) on the other popupbox
SetActiveSubwindow $Path2SubPanel
ControlInfo SelectData
String SectionList
Strswitch(S_Value)
Case "A":
Case "B":
SectionList = "First;Second;Third;Fourth;"
break
Case "C":
Case "D":
SectionList = "Primeiro;Segundo;Terceiro;Quarto;"
break
Case "E":
Case "F":
Case "G":
SectionList = "Erste; Zweite; Dritte; Vierte;"
break
EndSwitch
SetActiveSubWindow ## //return to host window
return SectionList
End
//---------------------------------------------------------------------------------------------------------------
Function Proc_SelectData1(PU_Struct) : PopupMenuControl
STRUCT WMPopupAction &PU_Struct
String sWin = PU_Struct.win
SetActiveSubwindow $sWin //This activates the subpanel where controls were selected
//extract the subwindow number from the panel name
String sSubPanelNumber
SplitString/E=("#P([[:digit:]]+)") sWin, sSubPanelNumber
print sSubPanelNumber + "eheheh"
Variable vSubPanelNumber = str2num(sSubPanelNumber)
//pass the number of the active subwindow onto a global variable
NVAR ActiveSubPanel
ActiveSubPanel = vSubPanelNumber
if(PU_Struct.eventCode == 2) // mouse up
//some come for proc
Return 0
Else
Return 0
EndIf
SetActiveSubwindow ## //return to host window
End
November 2, 2017 at 08:32 am - Permalink
NewPanel /W=(0,0,1200,400) /N=ResultsPanel1 /K=1
//Define Vertical guides
DefineGuide UGV0={FL,200},UGV1={UGV0,0.33333333,FR},UGV2={UGV0,0.66666666, FR}
//Define Horizonzal guides
DefineGuide UGH0={FB,0.5,FT}
string quote = "\""
String DataTypeList = quote + "A;B;C;D;E;F;G;" + quote
String sSubPanelName
Variable /G PlotCase = 1
//Create subpanels/subwindows where data will be displayed according to user input on controls
Variable i
for(i = 0; i < 2; i += 1)
switch(i)
case 0:
NewPanel/FG=(UGV0,FT,UGV1,UGH0) /HOST=ResultsPanel1
break
case 1:
NewPanel/FG=(UGV1,FT,UGV2,UGH0) /HOST=ResultsPanel1
break
endswitch
sSubPanelName = "P" + num2istr(i)
RenameWindow #,$sSubPanelName //Each subwindow has a name
//Indicate controls needed
PopupMenu SelectData, title="Data Type", mode=1, bodyWidth=110, value=#DataTypeList, pos={125,10},Proc=Proc_SelectData1
PopupMenu SelectSection, title="Section", mode=1, bodyWidth=100, value=#("FuncSelectList1(\""+WinName(0, 64) + "#" + sSubPanelName+"\")"), pos={265,10}
// add more controls here...
SetActiveSubwindow ## //Go back to parent window
endfor
End
//---------------------------------------------------------------------------------------------------------------
Function/S FuncSelectList1(sSubWinName)
String sSubWinName
Print "Path2Subpanel is:"+sSubWinName
ControlInfo/W=$sSubWinName SelectData
String SectionList
Strswitch(S_Value)
Case "A":
Case "B":
SectionList = "First;Second;Third;Fourth;"
break
Case "C":
Case "D":
SectionList = "Primeiro;Segundo;Terceiro;Quarto;"
break
Case "E":
Case "F":
Case "G":
SectionList = "Erste; Zweite; Dritte; Vierte;"
break
EndSwitch
return SectionList
End
//---------------------------------------------------------------------------------------------------------------
Function Proc_SelectData1(PU_Struct) : PopupMenuControl
STRUCT WMPopupAction &PU_Struct
String sWin = PU_Struct.win
SetActiveSubwindow $sWin //This activates the subpanel where controls were selected
//extract the subwindow number from the panel name
String sSubPanelNumber
SplitString/E=("#P([[:digit:]]+)") sWin, sSubPanelNumber
print sSubPanelNumber + "eheheh"
Variable vSubPanelNumber = str2num(sSubPanelNumber)
//pass the number of the active subwindow onto a global variable
NVAR ActiveSubPanel
ActiveSubPanel = vSubPanelNumber
if(PU_Struct.eventCode == 2) // mouse up
//some come for proc
Return 0
Else
Return 0
EndIf
SetActiveSubwindow ## //return to host window
End
Regards,
Kurt
November 2, 2017 at 08:49 am - Permalink
Quick question though: what might be the best approach to write this if for instance I would instead force the dynamic popupmenu to be populated upon interaction with the first (static) popupmenu, rather than, as I do now, for the list to be defined only upon user interaction with the dynamic popupmenu.
I'am actually quite happy that it works, but was wondering of how could be written differently.
Many thanks again!
Cheers,
R.
November 2, 2017 at 10:40 am - Permalink
Variable i=0
String WindowName=""
for (i=0; i<4; i+=1)
Display/K=1
WindowName=S_name
PopUpMenu PopUpOne value="one;two;three;four;"
PopUpMenu PopUpTwo value=#("PopUpValue(\""+WindowName+"\")")
endfor
end
Function/S PopUpValue(WindowName)
String WindowName
ControlInfo /W=$WindowName PopUpOne
Return S_Value+" monkey;"+S_Value+" cat;"+S_Value+" dog;"+S_Value+" pig;"
end
November 2, 2017 at 01:20 pm - Permalink
I see the commonalities between your example
value=#("PopUpValue(\""+WindowName+"\")")
and Kurt's
value=#("FuncSelectList1(\""+WinName(0, 64) + "#" + sSubPanelName+"\")")
Both of which are helpful in my case.
However, I was also wondering if it is possible to use the statitc PopUpMenu (PopUpOne) to dynamically push the value to be taken by the dynamic PopupMenu (PopUpTwo, in your case), in a way refreshing/updating that control, rather than having PopupTwo reading the status of PopOne only when interacted with. Any guesses if this possible at all?
November 2, 2017 at 11:56 pm - Permalink
Try this function (substitute it into the code I provided previously):
STRUCT WMPopupAction &PU_Struct
String sWin = PU_Struct.win
//extract the subwindow number from the panel name
String sSubPanelNumber
SplitString/E=("#P([[:digit:]]+)") sWin, sSubPanelNumber
print sSubPanelNumber + "eheheh"
Variable vSubPanelNumber = str2num(sSubPanelNumber)
if(PU_Struct.eventCode == 2) // mouse up
PopupMenu SelectSection, win=$sWin, mode=1
Else
EndIf
return 0
End
Cheers,
Kurt
November 3, 2017 at 01:01 am - Permalink
Variable i=0
for (i=0; i<4; i+=1)
Display/K=1
PopUpMenu PopUpOne value="one;two;three;four;", proc=PopUpProc
PopUpMenu PopUpTwo value="one monkey;one cat;one dog;one pig;"
endfor
end
Function PopUpProc(PU_Struct) : PopupMenuControl
Struct WMPopupAction &PU_Struct
String ValueStr="\""+PU_Struct.popStr+" monkey;"+PU_Struct.popStr+" cat;"+PU_Struct.popStr+" dog;"+PU_Struct.popStr+" pig;\""
PopUpMenu PopUpTwo mode=1, value=#ValueStr, win=$PU_Struct.win
end
November 3, 2017 at 01:04 am - Permalink
Cheers Kurt & Olelytken!
R.
November 3, 2017 at 01:16 am - Permalink