
Create a panel representing equipment status


aclight
To use the code, copy it into a procedure window and compile the code. Then, you'll need to create two waves.
The first wave is named
gwDigitalInputChan0
. The code gets the name of each channel from the row dimension labels of this wave. For example:Make/O/N=16 gwDigitalInputChan0 SetDimLabel 0, 0, A, gwDigitalInputChan0 SetDimLabel 0, 1, B, gwDigitalInputChan0 SetDimLabel 0, 2, C, gwDigitalInputChan0
The second wave,
wSwitches0
represents the status of each bit (on or off). Changing values in this wave will change the fill color of the corresponding circle on the control panel. If the panel is set to be in control mode, then pressing one of the colored "buttons" on the control panel will toggle the value of the corresponding point in the wave. For example:Make/o/n=16 wSwitches0 wSwitches0[0,3] = 1
Now, after you have executed the code above, you can build the panel. Do this by executing the following command at the Igor command line:
BuildDigInputPanel("test", 4, channelNum = 0)
#pragma rtGlobals=1 // Use modern global access method. Function pnlDigitalInput0() DoWindow/F pnlDigitalInputChan0 if (!V_flag) // TODO: Retrieve the type of panel to get from settings Variable x0, y0 BuildDigInputPanel("pnlDigitalInputChan0", 4, channelNum = 0) endif End Function DigInputButtonPress(s) STRUCT WMWinHookStruct &s switch (s.eventCode) Case 3: // mouse down String buttonPressed = "" Variable buttonFound buttonFound = FindControl(s, buttonPressed) // Change the color and frame of the button to make // it looked like it has been toggled. if (buttonFound) ControlInfo/W=$(s.winName) $(buttonPressed) if (V_flag == 4) // Make sure this control is a ValDisplay Variable buttonValue if (ValDisplay_getValue(s.winName, buttonPressed, buttonValue)) if (buttonValue) // Button has been clicked, so change frame to indented. ValDisplay $(buttonPressed) win=$(s.winName), frame = 4 else // Button has been unclicked, so change frame to raised. ValDisplay $(buttonPressed) win=$(s.winName), frame = 1 endif buttonValue = !(buttonValue) ValDisplay_setValue(s.winName, buttonPressed, buttonValue) return 1 endif endif endif break EndSwitch return 0 End //** // Determines if the mouse cursor is currently over a control // and provides the name of the control. // // @param s // This is an instance of the WMWinHookStruct structure which // is the structured that is passed to a named window hook function. // @param controlName // Name of control the the mouse cursor is currently over. This is // the output parameter of this function. // @param controlType // [OPTIONAL] If provided, only controls of this type will be considered. // For a list of types and their meanings, look at the ControlInfo // command help and look at the V_flag parameter set for each control type. // By default, the type of a control is ignored. // @param excludedState // [OPTIONAL] If non-zero, controls will be considered from consideration // if they are disabled and/or hidden. Use the following values to exclude // controls in the following states: // Value State // 1 Hidden // 2 Disabled (but visible) // 3 Hidden OR Disabled (but visible) // By default, the disable state of a control is ignored. // // @return // If a control was found meeting the criteria specified in the parameters, // the function will return 1. If no control is found, 0 will be returned. //* Function FindControl(s, controlName, [controlType, excludedState]) STRUCT WMWinHookStruct &s String &controlName Variable controlType Variable excludedState Variable controlFound controlName = "" if (ParamIsDefault(controlType)) // Match all types of controls controlType = 0 endif String controlList = ControlNameList(s.winName, ";", "*") Variable numControls = ItemsInList(controlList, ";") String currentControlName Variable n For (n=0; n<numControls; n+=1) currentControlName = StringFromList(n, controlList, ";") ControlInfo/W=$(s.winName) $(currentControlName) // Exclude this control if only controls of a certain type should // be considered. if (controlType != 0 && controlType != V_flag) continue endif // Possibly exclude this control if it is hidden or disabled if (V_disable != 0) if (V_disable & excludedState) continue endif endif // Determine if this control was clicked on. Variable controlClicked controlClicked = DoesCursorOverlap(s, V_height, V_width, V_top, V_left) if (controlClicked) controlName = currentControlName controlFound = 1 endif EndFor return controlFound End //** // Determines if the current mouse position falls within a certain boundary. // // @param s // This is an instance of the WMWinHookStruct structure which // is the structured that is passed to a named window hook function. // @param V_height // Height of target area, in pixels. // @param V_width // Width of target area, in pixels. // @param V_top // Top of target area, in pixels. // @param V_left // Left of target area, in pixels. // // @return // If the mouse cursor overlaps the target area, 1 is returned. Otherwise, 0 is returned. //* Function DoesCursorOverlap(s, V_height, V_width, V_top, V_left) STRUCT WMWinHookStruct &s Variable V_height Variable V_width Variable V_top Variable V_left // Check vertical location if (s.mouseLoc.v >= V_top && s.mouseLoc.v <= V_top + V_height) // Check horizontal location if (s.mouseLoc.h >= V_left && s.mouseLoc.h <= V_left + V_width) return 1 endif endif return 0 End //** // Get the value currently displayed in a ValDisplay control. // // @param win // Name of window with control. // @param ctrlName // Name of ValDisplay control. // @param valueVar // Variable passed by reference where the value will be stored. // // @return // 0 if there was an error or 1 if there was no error. //* Function ValDisplay_getValue(win, ctrlName, valueVar) String win String ctrlName Variable &valueVar ControlInfo/W=$(win) $(ctrlName) if (WinType(win) != 0 && abs(V_flag) != 4) // Make sure this control is a ValDisplay return 0 // Error else valueVar = V_value return 1 // Success endif End //** // Sets the value currently displayed in a ValDisplay control by // writing that value to the point in the wave attached to the ValDisplay // control. Obviously this assumes that the ValDisplay control is // associated with a wave and not a variable. // // @param win // Name of window with control. // @param ctrlName // Name of ValDisplay control. // @param valueVar // Variable passed by reference containing the value that should be // set in whatever point in whatever wave controls the ValDisplay control.. // // @return // 0 if there was an error or 1 if there was no error. //* Function ValDisplay_setValue(win, ctrlName, valueVar) String win String ctrlName Variable &valueVar Variable result String currentDF = GetDataFolder(1) SetDataFolder root: ControlInfo/W=$(win) $(ctrlName) String source = S_value if (WinType(win) != 0 && V_flag != 4) // Make sure this control is a ValDisplay result = 0 // Error else // Get the name of the wave and point of wave controlling // the value displayed in this control. String wName, rowString, colString Variable rowNum = NaN, colNum = NaN String regExp = "([[:alnum:]:_]+)\[([%[:alnum:]_%]+)\](?:\[([%[:alnum:]_%]+)\])?" SplitString/E=regExp source, wName, rowString, colString if (V_flag >= 2) WAVE/Z controllingWave = $(wName) if (WaveExists(controllingWave)) if (V_flag >= 3) // Determine what column number to use. if (numtype(str2num(colString)) == 0) colNum = str2num(colString) else colNum = FindDimLabel(controllingWave, 0, colString[1, strlen(colString) - 1]) endif endif // Determine what row number to use. if (numtype(str2num(rowString)) == 0) rowNum = str2num(rowString) else rowNum = FindDimLabel(controllingWave, 0, rowString[1, strlen(rowString) - 1]) endif // Set the value of the wave to the specified value. if (numtype(colNum) != 0 && rowNum >= 0) // Only use a row number. controllingWave[rowNum] = valueVar result = 1 elseif (numtype(colNum) == 0 && colNum >= 0) // Use a row and a column. controllingWave[rowNum][colNum] = valueVar result = 1 else result = 0 endif else result = 0 endif else result = 0 endif endif SetDataFolder currentDF return result End Function Button_DigitalInputMenu(ba) : ButtonControl STRUCT WMButtonAction &ba switch( ba.eventCode ) case 2: // mouse up String menuChoices = "Control bits 0-7;Control bits 8-16;Control all bits;Monitor digital inputs;" Variable controlSelection controlSelection = str2num(GetUserData(ba.win, "", "controlSelection")) if (numtype(controlSelection) != 0 || controlSelection <1 || controlSelection > 4) controlSelection = 4 endif // Add a check mark to the appropriate menu item to indicate what is currently selected. String selectedMenuString = StringFromList(controlSelection - 1, menuChoices, ";") menuChoices = RemoveListItem(controlSelection - 1, menuChoices, ";") menuChoices = AddListItem("\\M1" + selectedMenuString + "!" + num2char(18), menuChoices, ";", controlSelection - 1) PopupContextualMenu menuChoices if (V_flag >= 1) // User made a selection SetWindow $(ba.win) userdata(controlSelection)=num2str(V_flag) // Redraw the panel based on the selection BuildDigInputPanel(ba.win, V_flag) endif return 1 break endswitch return 0 End //** // Build (or rebuild) the Digital Input panel. // // @param panelName // Name of the Digital input panel. // @param type // Type of panel to create. The possible options are: // Value Description // 1 Control bits 0-7 // 2 Control bits 8-15 // 3 Control all bits (0-15) // 4 Monitor digital inputs (read only) // @param channelNum // [OPTIONAL] Channel number that panel will control. If this is not given, // an attempt will be made to pull this information from the panel's "channelNum" named // user data. If that fails, then the function will return silently. // @param x0 // [OPTIONAL] X coordinate of upper left corner of panel, in pixels. Default is 0. // @param y0 // [OPTIONAL] Y coordinate of upper left corner of panel, in pixels. Default is 0. //* Function BuildDigInputPanel(panelName, type, [channelNum, x0, y0]) String panelName Variable type Variable channelNum Variable x0 Variable y0 String wName if (ParamIsDefault(channelNum)) channelNum = str2num(GetUserData(panelName, "", "channelNum")) if (numtype(channelNum) != 0) return 0 endif endif sprintf wName, "root:gwDigitalInputChan%d", channelNum WAVE/Z gwDigitalInputChan = $(wName) if (!WaveExists(gwDigitalInputChan)) return 0 endif if (ParamIsDefault(x0)) x0 = 50 endif if (ParamIsDefault(y0)) y0 = 50 endif Variable buttonWidth = 20 Variable buttonHeight = 20 Variable menuButtonWidth = 15 Variable spacing = buttonWidth + 6 // Distance from left edge of one button to left edge of next button Variable numButtons Variable firstButtonNumber numButtons = (type == 1 || type == 2) ? 8 : 16 firstButtonNumber = (type == 2) ? 8 : 0 Variable totalWidth, totalHeight Variable buttonTop = 3 Variable currentLeftPos totalHeight = buttonTop + buttonHeight + 3 + 35 + 3 // top spacing + buttonHeight + middle spacing + number height + bottom spacing totalWidth = (spacing/1.25) + ((numButtons - 1) * spacing) + (1.25 * spacing) + (spacing/4) // left spacing + width of buttons and spacing between them + between buttons and menu button spacing + right side spacing if (WinType(panelName)) // Store upper left coordinates of panel so when recreated it doesn't move GetWindow $(panelName) wsize x0 = V_left * ScreenResolution / 72 y0 = V_top * ScreenResolution / 72 KillWindow $(panelName) endif NewPanel/K=1/FLT=1/W=(x0, y0, x0 + totalWidth, y0 + totalHeight)/N=$(panelName) as "Digital Input" // Write channel number into named user data. SetWindow $(panelName), userdata(channelNum) = num2istr(channelNum) // Determine if buttons should be drawn as circular LEDs (for monitoring inputs) or square LEDs (for controlling inputs) Variable buttonMode buttonMode = (type < 4) ? 2 : 1 // Draw menu button currentLeftPos = trunc(totalWidth - (spacing/4) - menuButtonWidth) Button buttonMenu win=$(panelName),pos={currentLeftPos,buttonTop},size={menuButtonWidth,buttonHeight},proc=Button_DigitalInputMenu,title="\\W623" currentLeftPos -= spacing // Draw the rest of the buttons and label them Variable currentBitNum String currentButtonName, currentValueSource, currentBitName For (currentBitNum = firstButtonNumber; currentBitNum < numButtons + firstButtonNumber; currentBitNum += 1) currentButtonName = "toggle" + num2str(currentBitNum) currentBitName = GetDimLabel(gwDigitalInputChan, 0, currentBitNum) // Don't display the "SW_" part of the name, if that's how the bit is named if (cmpstr(currentBitName[0,2], "SW_") == 0) currentBitName = currentBitName[3, strlen(currentBitName) - 1] endif sprintf currentValueSource, "root:wSwitches%d[%d]", channelNum, currentBitNum ValDisplay $(currentButtonName) win=$(panelName),pos={currentLeftPos,buttonTop},size={buttonWidth, buttonHeight} ValDisplay $(currentButtonName) win=$(panelName),limits={-50,1,0},barmisc={0,0},bodyWidth= 20,mode= buttonMode,highColor= (0,52224,0),zeroColor= (56576,56576,56576) ValDisplay $(currentButtonName) win=$(panelName),value= #currentValueSource ValDisplay $(currentButtonName) win=$(panelName),help={currentBitName} // Display bit number under button. SetDrawEnv/W=$(panelName) textxjust= 1,textyjust= 2, fsize = 12 DrawText/W=$(panelName) trunc((currentLeftPos + (buttonWidth / 2))), (buttonTop + buttonHeight + 3), num2str(currentBitNum) // Display the name of the bit. SetDrawEnv textxjust= 1,textyjust= 2,fsize=10 DrawText/W=$(panelName) trunc((currentLeftPos + (buttonWidth / 2))), (buttonTop + buttonHeight + 17 + (12 * mod(currentBitNum, 2))), currentBitName // Set the proper frame for the button. Switch (type) Case 1: // Control bits 0-7 Case 2: // Control bits 8-15 Case 3: // Control all bits ControlInfo/W=$(panelName) $(currentButtonName) if (V_value) // Set frame to raised ValDisplay $(currentButtonName) win=$(panelName),frame=1 else // Set frame to indented ValDisplay $(currentButtonName) win=$(panelName),frame=4 endif break default: // Monitor digital inputs, so set to no frame. ValDisplay $(currentButtonName) win=$(panelName),frame=0 EndSwitch currentLeftPos -= spacing EndFor // Only set window hook if we're not monitoring values if (type < 4 && type > 0) SetWindow kwTopWin,hook(buttonPress)=DigInputButtonPress else SetWindow kwTopWin, hook(buttonPress)=$"" endif SetWindow $(panelName),userdata(controlSelection)= num2str(type) if (strlen(FunctionInfo("AClampAcquisition_WindowHook")) > 0) SetWindow $(panelName), hook(AClampAcquisition_WindowHook)=AClampAcquisition_WindowHook endif SetActiveSubwindow _endfloat_ End

Forum

Support

Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More