displaying/hiding a graph on a tab in a panel
igorisfun
Function my_panel()
my_globals() //makes some globals
PauseUpdate; Silent 1 // building window...
NewPanel/N=my_panel/K=1 /W=(104,71,804,621) as "My Panel"
ModifyPanel fixedSize=1
SetDrawLayer UserBack
SetDrawEnv fsize= 28,fstyle= 1,textrgb= (1,1,1)
DrawText 10,33,"My Panel Aide"
TabControl size_cal_tab,pos={5,70},size={690,475},proc=my_tabcontrol
TabControl size_cal_tab,tabLabel(0)="Tab1",tabLabel(1)="Tab2", tabLabel(2)="Tab3", tabLabel(3)="Tab4"
//a bunch of extraneous code that successfully creates controls, e.g. buttons, setvars, etc.
display/N=not_graph/HOST=my_panel0 root:testwv //not sure why NewPanel appends 0 to the end of the panel name but it does...
End
Function my_tabcontrol(ctrlName, tabNum) : TabControl
String ctrlName
Variable tabNum
variable cont_disp,idex,nCont
string cont_list, cont_item
cont_list=controlnamelist("")
nCont=itemsinlist(cont_list)
for (idex=0;idex<nCont;idex+=1)
cont_item=stringfromlist(idex,cont_list)
strswitch (cont_item[0,3])
//......
//extraneous code that successfully hides/shows controls like buttons when various tabs are clicked
endfor
string myWInList, winStr
variable num
myWInList = ChildWindowList("my_panel0")
num= ItemsInList(myWinList)
for(idex=0;idex<num;idex+=1)
winStr = stringFromList(idex, myWInList)
if(tabNum!=1)
if (stringmatch("not", winStr[0,2]) )
KillWindow $"my_Panel0#"+winStr
endif
endif
endfor
End
my_globals() //makes some globals
PauseUpdate; Silent 1 // building window...
NewPanel/N=my_panel/K=1 /W=(104,71,804,621) as "My Panel"
ModifyPanel fixedSize=1
SetDrawLayer UserBack
SetDrawEnv fsize= 28,fstyle= 1,textrgb= (1,1,1)
DrawText 10,33,"My Panel Aide"
TabControl size_cal_tab,pos={5,70},size={690,475},proc=my_tabcontrol
TabControl size_cal_tab,tabLabel(0)="Tab1",tabLabel(1)="Tab2", tabLabel(2)="Tab3", tabLabel(3)="Tab4"
//a bunch of extraneous code that successfully creates controls, e.g. buttons, setvars, etc.
display/N=not_graph/HOST=my_panel0 root:testwv //not sure why NewPanel appends 0 to the end of the panel name but it does...
End
Function my_tabcontrol(ctrlName, tabNum) : TabControl
String ctrlName
Variable tabNum
variable cont_disp,idex,nCont
string cont_list, cont_item
cont_list=controlnamelist("")
nCont=itemsinlist(cont_list)
for (idex=0;idex<nCont;idex+=1)
cont_item=stringfromlist(idex,cont_list)
strswitch (cont_item[0,3])
//......
//extraneous code that successfully hides/shows controls like buttons when various tabs are clicked
endfor
string myWInList, winStr
variable num
myWInList = ChildWindowList("my_panel0")
num= ItemsInList(myWinList)
for(idex=0;idex<num;idex+=1)
winStr = stringFromList(idex, myWInList)
if(tabNum!=1)
if (stringmatch("not", winStr[0,2]) )
KillWindow $"my_Panel0#"+winStr
endif
endif
endfor
End
When clicking a tab that is not tab 1 (0th indexed), the graph display of testwv is successfully killed. The problem is that 1) the graph is displayed on tab 0 at startup of the panel and 2) the graph does not reappear if it is killed and then the user clicks on tab 1...
Is there a better method to write the display command? Do I need to use something akin to what is in the
DisplayHelpTopic "TabControl"
where it discusses using a predefined structure WMTabControlAction
? Will I need to rewrite my above tabcontrol to fit in that or can i add it for only 1 specific tab?
Instead of killing your graph, how about hiding it? SetWindow $"my_Panel0#"+winStr, hide = 1 or 0
You should be able to create the graph hidden with Display/HIDE=1. That has some problems sometimes, but you could give it a try. Things that don't work that way are likely bugs, which you will report to us :)
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
January 23, 2018 at 12:07 pm - Permalink
I rewrote my tab control in the form:
Int32 eventcode
Int32 tab
EndStructure
Function my_tabcontrol_new(tca) : TabControl
STRUCT WMTabControlAction &tca
switch(tca.eventCode)
case 2:
String controlsin_tab0 = ControlNameList("",";","tab0_*")
String controlsin_xxtab = ControlNameList("",";","xxtab_*")
//etc.
if(tca.tab==0)
ModifyControlList controlsin_tab0 disable = 0
ModifyControlList controlsin_xxtab disable = 1
SetWindow $"my_Panel0#not_graph", hide = 1
endif
//analogous code for tca.tab==1, etc.
endswitch
return 0
end
I know it's not the most elegant solution, but it works for my purposes of learning igor structures and tabs...
The above code works for me as long as I put a setwindow hide=1 right after the display command in the panel creation function.
However....the popupsetvars from my other question are not hiding correctly. The title of them disappears but the outline and arrow to bring up the popup box remain. Not sure if that is a bug or my own poor programming.
EDIT: using the old style of tabcontrol, the popupsetvars do disappear completely on the non-relevant tabs
January 23, 2018 at 09:37 pm - Permalink
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
January 24, 2018 at 09:39 am - Permalink
Using version 6.3.7.2. Unable to upgrade to 7 yet because some of the custom ipf's I use have not been fully error checked in 7...
Both the old style and new style tab controls are there, just comment/decomment the appropriate 2 lines in size_cal_panel()
Also, I know that a better way to write the new style tabcontrol for hiding the tab buttons would be to rename the tabs to something procedural (e.g. tab0_*, tab1_*, etc) but I already started this way and don't want to rework it right now. If you have a suggestion of a way to do the modifycontrollist calls in 1 call instead of 4, without renaming anything, I'd love to hear it though!
#include <WaveSelectorWidget>
#include <PopupWaveSelector>
Menu "SizeCal"
"Size Cal Aide/4", /q,SC_getSCwin()
End
Function SC_getSCwin()
string windows=winlist("size_cal_panel",";","WIN:64")
if(strlen(windows)>0)
dowindow/f size_cal_panel
else
size_cal_globals()
size_cal_panel()
endif
End
Function size_cal_panel()
size_cal_globals()
PauseUpdate; Silent 1 // building window...
NewPanel/N=size_cal_panel/K=1 /W=(104,71,804,621) as "Size Calibration Panel"
ModifyPanel fixedSize=1
SetDrawLayer UserBack
SetDrawEnv fsize= 28,fstyle= 1,textrgb= (1,1,1)
DrawText 10,33,"AMS Size Calibration Aide"
// TabControl size_cal_tab,pos={5,70},size={690,475},proc=size_cal_tabcontrol
// TabControl size_cal_tab,tabLabel(0)="Identify Waves",tabLabel(1)="Determine Rising Edge", tabLabel(2)="Perform Calculations", tabLabel(3)="Fit Function"
TabControl size_cal_tab,pos={5,70},size={690,475},proc=size_cal_tabcontrol_new
TabControl size_cal_tab,tabLabel(0)="Identify Waves",tabLabel(1)="Determine Rising Edge", tabLabel(2)="Perform Calculations", tabLabel(3)="Fit Function"
GroupBox idWv_SqReqs,pos={10,100},size={675,250}, title="Using this Panel"
GroupBox idWv_SqReqs,fStyle=1,fColor=(43520,43520,0)
//unimportant strings to display in the groupbox go here
SetVariable idWv_PopupWvSelectorSV_smallest,pos={30,360},size={300,15},bodyWidth= 150,title="Smallest Size"
MakeSetVarIntoWSPopupButton("size_Cal_panel0", "idWv_PopupWvSelectorSV_smallest", "DemoPopupWaveSelectorNotify", "root:SizeCalPanel:output_smallest", options=PopupWS_OptionFloat+PopupWS_OptionSVFramed)
SetVariable idWv_PopupWvSelectorSV_small,pos={30,390},size={300,15},bodyWidth= 150,title="Small Size "
MakeSetVarIntoWSPopupButton("size_Cal_panel0", "idWv_PopupWvSelectorSV_small", "DemoPopupWaveSelectorNotify", "root:SizeCalPanel:output_small", options=PopupWS_OptionFloat+PopupWS_OptionSVFramed)
SetVariable idWv_PopupWvSelectorSV_large,pos={30,420},size={300,15},bodyWidth= 150,title="Large Size"
MakeSetVarIntoWSPopupButton("size_Cal_panel0", "idWv_PopupWvSelectorSV_large", "DemoPopupWaveSelectorNotify", "root:SizeCalPanel:output_large", options=PopupWS_OptionFloat+PopupWS_OptionSVFramed)
SetVariable idWv_PopupWvSelectorSV_largest,pos={30,450},size={300,15},bodyWidth= 150,title="Largest Size"
MakeSetVarIntoWSPopupButton("size_Cal_panel0", "idWv_PopupWvSelectorSV_largest", "DemoPopupWaveSelectorNotify", "root:SizeCalPanel:output_largest", options=PopupWS_OptionFloat+PopupWS_OptionSVFramed)
SetVariable idWv_sizeinnm_smallest, pos={405,360}, size={75,15},title="Size in nm", bodyWidth=75, value=root:SizeCalPanel:output_smallest_nm
SetVariable idWv_sizeinnm_small, pos={405,390}, size={75,15},title="Size in nm", bodyWidth=75, value=root:SizeCalPanel:output_small_nm
SetVariable idWv_sizeinnm_large, pos={405,420}, size={75,15},title="Size in nm", bodyWidth=75, value=root:SizeCalPanel:output_large_nm
SetVariable idWv_sizeinnm_largest, pos={405,450}, size={75,15},title="Size in nm", bodyWidth=75, value=root:SizeCalPanel:output_largest_nm
Button idWv_prelimcalcs title="Do Preliminary \rCalculations",size={120,75},fSize=14, fstyle=1, pos={530,380}, proc=idWv_prelimcalcs_proc
//2nd panel things ; temporary placeholder below
SetVariable DRE_testvar, pos={450,450}, size={75,15},title="test", bodyWidth=75,value=root:SizeCalPanel:testvar
//make sure upon initialization that only 1st tab things show up
string contlist = ControlNameList("",";","!idWv*")
contlist = removefromlist("size_cal_tab", contlist) //otherwise the tabs are hidden too.
ModifyControlList contlist, disable=1
display/N=DRE_graph/HOST=size_cal_panel0
SetWindow $"size_cal_Panel0#DRE_graph", hide = 1
End
Function create_DRE_graph() ///function to append the traces to the DRE graph that were selected by user via popup bars
///to be called by button
if(Waveexists(root:testwave))
// if(Waveexists(
endif
End
Function DemoPopupWaveSelectorNotify(event, wavepath, windowName, ctrlName)
Variable event
String wavepath
String windowName
String ctrlName
print "Selected wave:",wavepath, " using control", ctrlName
if(!DataFolderExists("root:SizeCalPanel:outputwaves"))
NewDataFolder root:SizeCalPanel:outputwaves
endif
string dfSav = GetDataFolder(1)
strswitch (ctrlName)
case "idWv_PopupWvSelectorSV_smallest":
SetDataFolder root:SizeCalPanel:outputwaves
SVAR output_smallest
if(!SVAR_exists(output_smallest)) //is this if necessary? why not just kill and reinitialize every time?
initglobal_SVAR("output_smallest", wavepath)
else
KillStrings output_smallest
initglobal_SVAR("output_smallest", wavepath)
endif
SetDataFolder $dfSav
case "idWv_PopupWvSelectorSV_small":
SetDataFolder root:SizeCalPanel:outputwaves
SVAR output_small
if(!SVAR_exists(output_small))
initglobal_SVAR("output_small", wavepath)
else
KillStrings output_small
initglobal_SVAR("output_small", wavepath)
endif
SetDataFolder $dfSav
case "idWv_PopupWvSelectorSV_large":
SetDataFolder root:SizeCalPanel:outputwaves
SVAR output_large
if(!SVAR_exists(output_large))
initglobal_SVAR("output_large", wavepath)
else
KillStrings output_large
initglobal_SVAR("output_large", wavepath)
endif
SetDataFolder $dfSav
case "idWv_PopupWvSelectorSV_largest":
SetDataFolder root:SizeCalPanel:outputwaves
SVAR output_largest
if(!SVAR_exists(output_largest))
initglobal_SVAR("output_largest", wavepath)
else
KillStrings output_largest
initglobal_SVAR("output_largest", wavepath)
endif
SetDataFolder $dfSav
endswitch
traceongraph("size_cal_Panel0#DRE_graph", wavepath)
//Appendtograph/W=$"size_cal_Panel0#DRE_graph" $wavepath
//string/G tempstr = wavepath
//rename tempstr, $ctrlname
//SetFullDirectory_userinputs()
//print PopupWS_GetSelectionFullPath(windowName, ctrlName)
end
Function traceongraph(graphname, tracename) ///needs rework
string graphname, tracename
string existingtraces = tracenamelist(graphname,";",0)
if(!stringmatch(existingtraces,tracename))
AppendtoGraph/W=$graphname $tracename
else
RemoveFromGraph/W=$graphname $tracename
AppendtoGraph/W=$graphname $tracename
endif
End
Function size_cal_globals()
if ( datafolderexists( "root:SizeCalPanel" ) != 1 )
newdatafolder root:SizeCalPanel
endif
//string variables for setvars
initglobal_SVAR("root:SizeCalpanel:output_smallest","")
initglobal_SVAR("root:SizeCalpanel:output_small","")
initglobal_SVAR("root:SizeCalpanel:output_large","")
initglobal_SVAR("root:SizeCalpanel:output_largest","")
//numeric variables
initglobal_NVAR("root:SizeCalPanel:testvar",nan)
End
Function initglobal_SVAR(SVarName, SVarVal)
string SVarName
string SVarVal
svar/z myVar = $SVarName
if (!SVar_Exists(myVar))
string/g $SVarName
SVar/z myVar = $SVarName
myVar = SVarVal
endif
End
Function initglobal_NVAR(NVarName, NVarVal)
string NVarName
variable NVarVal
Nvar/z myVar = $NVarName
if (!NVar_Exists(myVar))
string/g $NVarName
NVar/z myVar = $NVarName
myVar = NVarVal
endif
End
Function size_cal_tabcontrol(ctrlName, tabNum) : TabControl
//ripped almost directly from something else
String ctrlName
Variable tabNum
variable cont_disp,idex,nCont
string cont_list, cont_item
cont_list=controlnamelist("")
nCont=itemsinlist(cont_list)
for (idex=0;idex<nCont;idex+=1)
cont_item=stringfromlist(idex,cont_list)
strswitch (cont_item[0,3])
case "Gen": // outside of tabs
cont_disp=0
break
case "idWv":
cont_disp=tabNum!=0
break
case "DRE_":
cont_disp=tabNum!=1
break
case "PCal":
cont_disp=tabNum!=2
break
case "FtFn":
cont_disp=tabNum!=3
break
endswitch
controlinfo /w=Size_cal_Panel0 $cont_item
switch (abs(v_flag))
case 1:
button $cont_item disable=cont_disp
break
case 2:
checkbox $cont_item disable=cont_disp
break
case 3:
popupmenu $cont_item disable=cont_disp
break
case 4:
valdisplay $cont_item disable=cont_disp
break
case 5:
setvariable $cont_item disable=cont_disp
break
case 6:
chart $cont_item disable=cont_disp
break
case 7:
slider $cont_item disable=cont_disp
break
case 8:
tabcontrol $cont_item disable=cont_disp
break
case 9:
groupbox $cont_item disable=cont_disp
break
case 10:
titlebox $cont_item disable=cont_disp
break
case 11:
listbox $cont_item disable=cont_disp
break
endswitch
endfor
string myWInList, winStr
variable num
myWInList = ChildWindowList("size_Cal_panel0")
num= ItemsInList(myWinList)
for(idex=0;idex<num;idex+=1)
winStr = stringFromList(idex, myWInList)
if(tabNum!=1)
if (stringmatch("DRE", winStr[0,2]) )
SetWindow $"size_Cal_Panel0#"+winStr,hide=1
endif
endif
if(tabNum==1)
if(stringmatch("DRE", winStr[0,2]) )
SetWindow $"size_Cal_Panel0#"+winStr,hide=0
endif
endif
endfor
End
Structure size_cal_tabinfo
Int32 eventcode
Int32 tab
EndStructure
Function size_cal_tabcontrol_new(tca) : TabControl
STRUCT WMTabControlAction &tca
string cont_list, cont_item
variable ncont
cont_list=controlnamelist("")
nCont=itemsinlist(cont_list)
switch(tca.eventCode)
case 2:
String controlsin_idWv = ControlNameList("",";","idWv_*")
String controlsin_DRE = ControlNameList("",";","DRE_*")
String controlsin_PCal = ControlNameList("",";","PCal_*")
String controlsin_FtFn = ControlNameList("",";","FtFn_*")
String myWInList = ChildWindowList("size_cal_panel0")
if(tca.tab==0)
ModifyControlList controlsin_idWv disable = 0
ModifyControlList controlsin_DRE disable = 1
ModifyControlList controlsin_PCal disable = 1
ModifyControlList controlsin_FtFn disable = 1
SetWindow $"size_cal_Panel0#DRE_graph", hide = 1
endif
if(tca.tab==1)
ModifyControlList controlsin_idWv disable = 1
ModifyControlList controlsin_DRE disable = 0
ModifyControlList controlsin_PCal disable = 1
ModifyControlList controlsin_FtFn disable = 1
SetWindow $"size_cal_Panel0#DRE_graph", hide = 0
endif
if(tca.tab==2)
ModifyControlList controlsin_idWv disable = 1
ModifyControlList controlsin_DRE disable = 1
ModifyControlList controlsin_PCal disable = 0
ModifyControlList controlsin_FtFn disable = 1
SetWindow $"size_cal_Panel0#DRE_graph", hide = 1
endif
if(tca.tab==3)
ModifyControlList controlsin_idWv disable = 1
ModifyControlList controlsin_DRE disable = 1
ModifyControlList controlsin_PCal disable = 1
ModifyControlList controlsin_FtFn disable = 0
SetWindow $"size_cal_Panel0#DRE_graph", hide = 1
endif
endswitch
return 0
End
Structure idWv_prelimcalcs_butt_info
Int32 eventcode
EndStructure
Function idWv_prelimcalcs_proc(B_Struct) : ButtonControl
STRUCT WMButtonAction &B_Struct
switch(B_struct.eventcode)
case 2:
//run some functions to do wave appending
endswitch
End
January 24, 2018 at 11:24 pm - Permalink
Is it possible to trick the new style tabcontrol into thinking an event code is being sent from something else? I would like to make the tab advance when the user clicks a button. For the old style tab control I have above, all I need to do is size_cal_tabcontrol("windowname",tabnumber) but it's less obvious if i can pass a tca.eventcode=2, tca.tab=1 kind of argument in the new style...
January 25, 2018 at 01:41 am - Permalink
Is it possible to trick the new style tabcontrol into thinking an event code is being sent from something else? I would like to make the tab advance when the user clicks a button. For the old style tab control I have above, all I need to do is size_cal_tabcontrol("windowname",tabnumber) but it's less obvious if i can pass a tca.eventcode=2, tca.tab=1 kind of argument in the new style...
January 25, 2018 at 01:41 am - Permalink
Assuming that you want to create a function that calls your tabcontrol function, the answer is yes.
You can create an instance of the tabcontrol structure and pass it to your tabcontrol fuction. Just initialize the elements of the structure that your tabcontrol function needs.
January 25, 2018 at 06:04 am - Permalink
Yes, this _can_ be done. The better approach and habit to cultivate is however to create a function that is dedicated solely to switch the tab. Call it when the user clicks the button. The temptation to use a different function to populate the structure that is passed to a panel control panel control opens the door to complications that eventually are not worth the effort. For example ... Gosh, this should work. (three days of hair pulling effort later) ... Oh! I forgot to define this specific element of the structure that I pass to the tabcontrol function and so the code is just jumping out on entry. (speaking from experience here).
--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
January 25, 2018 at 07:06 am - Permalink
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
January 25, 2018 at 12:53 pm - Permalink
Can you tell us how to run it so that we can see the problem? It would be helpful if the instructions include some comments like, "at this point you should see..., but instead it shows (or doesn't show) this thing...".
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
January 25, 2018 at 12:57 pm - Permalink
I might bump this after nearly a year. I have found some odd behavior with ModifyControlList. Sometimes, it gives an error "Expected control name" (or equivalent). This seems to be especially true immediately after the controls are added to the panel.
I have found that this problem disappears when I add a ControlUpdate/A/W=... BEFORE I do any modifications to show/hide. So, the properly working code might have to look like this ...
ControlUpdate/A/W=$k_panelName // update all controls (seems to be essential)
// hide prior controls
ptab = "*_tab"+ptabstr
tabList = ControlNameList(k_panelName,";",ptab)
ModifyControlList tabList disable=1
// show new controls
ptab = "*_tab"+ctabstr
tabList = ControlNameList(k_panelName,";",ptab)
ModifyControlList tabList disable=0
December 26, 2019 at 02:11 pm - Permalink
So, after further testing, I have a MWE to demonstrate the problem. When controls are located on sub-window panels, you must use the SetActiveSubWindow operation BEFORE the ModifyControlList. Otherwise, you run the danger that, when you click off the panel itself, ModifyControlList will not recognize where the controls are located.
make/N=(10)/O somewave = sin(x)
display/N=MyGraph somewave as "Test"
NewPanel/EXT=0/HOST=#/N=MyPanel/W=(0,0,0.1,0.1)
Button testit_tab0, title="Test0"
Button testit_tab1, title="Test1"
return 0
end
Function TestOnOff(onoff)
variable onoff
string tablist
// comment out the next code line
// then activate the GRAPH
// when you run the TestOnOff, you will get an error message
SetActiveSubwindow MyGraph#MyPanel
tablist = ControlNameList("MyPanel",";","*_tab0")
ModifyControlList tablist disable=(onoff)
tablist = ControlNameList("MyPanel",";","*_tab1")
ModifyControlList tablist disable=(1-onoff)
return 0
end
Run MakeGraph().
Run TestOnOff(...) with either 1 or 0.
Now, comment out the SetActiveSubWindow operation. Go to the graph and "touch" it to make it active (in the front of the sub-window panel).
Re-run the TestOnOff(...) function. You should get an error that
--> While executing ModifyControlList, the following error occurred: Expected control name
It seems that perhaps ModifyControlList could benefit by a /W=winname flag.
January 12, 2020 at 04:10 pm - Permalink
Add the win= keyword to the command.
January 13, 2020 at 09:22 am - Permalink
Oh. Yes. I see it now in the list. Apologies and thanks!!!
January 13, 2020 at 10:54 am - Permalink
It took me a while to see it in the list, too.
January 13, 2020 at 12:33 pm - Permalink