Condensing Code for Similar Functions

Is it possible to condense code for check boxes that are very similar in function? I currently have the code below copied 30 times, each time for a different check box. The only difference between the code for one check box and another are the location in a window (as defined under command window) and the names (Series_1 vs 2 or CheckProc_1 vs 2, etc). Can I automate the process with a loop or let the program write in itself how many check boxes it will need to create and where to place them?

CheckBox Series,pos={151,70},size={64,14},proc=CheckProc,title="Series 1"
CheckBox Series,fStyle=17,variable= V

Function CheckProc(ctrlName, x) : CheckBoxControl
String ctrlName
Variable x
Another_function ()
End

So for example,
CheckBox Series_1,pos={151,70},size={64,14},proc=CheckProc_1,title="Series 1"
CheckBox Series_1,fStyle=17,variable= V_1
CheckBox Series_2,pos={151,95},size={64,14},proc=CheckProc_2,title="Series 2"
CheckBox Series_2,fStyle=17,variable= V_2
...
Function CheckProc_1(ctrlName, x) : CheckBoxControl
String ctrlName
Variable x
Another_function ()
End
Function CheckProc_2(ctrlName, x) : CheckBoxControl
String ctrlName
Variable x
Another_function ()
End
...


Many thanks!
First, you'll want to use the structured form of controls rather than the function form. Then, within your one checkbox control function, use a strswitch on the control name.


Function CheckProc(cba) : CheckBoxControl
	STRUCT WMCheckboxAction &cba

	switch( cba.eventCode )
		case 2: // mouse up
			Variable checked = cba.checked
			strswitch(cba.ctrlName)
				case "checkbox01":
					// do checkbox01 actions
					...
					break
				case "checkbox02":
					// do checkbox02 actions
					...
					break
				...	
			endswitch
			
			break
		case -1: // control being killed
			break
	endswitch

	return 0
End


--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
In your setup using structures, it seems that you would still have to retype the function every time under cases in the strswitch. Is there any way to avoid having to retype the function 30 times except with different names?
Is this what you had in mind?

It makes a panel and condenses the creation of as many checkboxes as you like in a loop. Checkboxes and their control variables share common base names with a numeric extension.

In this example a single, very simple example procedure is called when the boxes are "clicked".


Function LotsOCBPanel() : Panel

	String sCB_Name
	String sCB_BaseName = "CB_check"
	String sCB_VariableName
	String sCB_VariableBaseName = "vCBval"
	String sDataFolder = "root:CheckBoxPanel"
	String sProcName
	String sProcBaseName = "cbProc"
	
	Variable vCB_Position = 0
	Variable vIndex = 0
	
	NewDataFolder/O $sDataFolder	//for checkbox variables
	
	PauseUpdate; Silent 1		// building window...
	NewPanel /W=(403,135,777,485)
	
	Do
		sCB_Name = sCB_BaseName + num2str(vIndex)
		sCB_VariableName = sDataFolder + ":" + sCB_VariableBaseName + num2str(vIndex)
		sProcName = sProcBaseName //+ num2str(vIndex) //use this if there's a proc for each checkbox
		vCB_Position += 20  //y position of checkbox
		Variable/G $(sCB_VariableName) = 1 //create global variable for each checkbox, initial value is checked
		CheckBox $sCB_Name,pos={1,vCB_Position},size={40,14},variable= $sCB_VariableName
		CheckBox $sCB_Name,title=sCB_Name, proc=$sProcName
		vIndex += 1
	While(vIndex<5)
End


Function cbProc(cba) : CheckBoxControl
	STRUCT WMCheckboxAction &cba
	
	String sCtrlName = cba.ctrlName
	switch( cba.eventCode )
		case 2: // mouse up
			print cba.ctrlName
			print cba.checked
			break
		case -1: // control being killed
			break
	endswitch

	return 0
End
You can do the same with a structure by making a FUNCREF call to a variation of the cba.ctrlName.


Function check01(x)
   variable x
   ...
end

Function check02(x)
   variable x
   ...
end

Function CheckProc(cba) : CheckBoxControl
	STRUCT WMCheckboxAction &cba

        variable x = 2
	switch( cba.eventCode )
		case 2: // mouse up
			Variable checked = cba.checked
                        FUNCREF myprotofunc f = $cba.ctrlName
                        f(x)
			break
		case -1: // control being killed
			break
	endswitch
 
	return 0
End


(EDIT)

Oh. My apologies. Now I understand. You want to have a code create a panel for you. For that, use the code by jtigor, however the procedure name can just be CheckProc with the above code to automatically call depending on check box name.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
Perhaps part of what you are stuck on is the use of a separate action procedure for each checkbox control. That is not required- you can use the same action procedure for as many checkboxes as you like. That's why the control name is part of the input to the action procedure- it allows you to distinguish which checkbox caused the action procedure to be called.

You *do* have to have a different action procedure for different types of controls because they each carry different kinds of information.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
Yea, I wasn't sure whether there was a need for each control to have a unique function associated with it, so my code was cluttered up with many unnecessary functions. The code showing how to create an arbitrary number of checkboxes and place them helped me make my code more flexible and gave me a better understanding of how to effectively refer to controls with similar functions. Thank you.