4Misc_StartT4PlatformT¿@9èVersionCheckè ¬xHHô@îÿîÿRg(üšHHdh ¬xHHô@îÿîÿRg(üšHHdh ¬x HHô@îÿîÿRg(üšHHdh ^Graph*opWDashSettings#úÿ  !¶‚ ©É6Normalÿÿÿÿ@ ÿMonacoÿÿÿÿÿÿ<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿHHHH$$4 4 4 4 4 4 ãhome¯_dÿÿÿÿMacintosh HD:Users:jim:Documents:Development Stuff:For 8:Tables:P Macintosh HDBDÿÿÿÿTablesÿÿÿÿ cuFor 85/:Users:jim:Documents:Development Stuff:For 8:Tables/Tables Macintosh HD2Users/jim/Documents/Development Stuff/For 8/Tables/ ÿÿôRecentWindowsÀAdvanced Topics.ihfAdvancedTopics:AdvancedTopicsTableHooks.ifndemoPanelIgor Reference.ihfInteracting with the User.ihfModifyTableEntryMode:ModifyTableEntryMode.ifnTables.ihfWMMenus.ipf 4Misc_EndTTXOPState_Start TPeakFunctions2-64fs;4XOPState_EndTðV_Flagð?V_isInvisibleS_valuesible12] •preptabbedpanel() •preptabbedpanel() •preptabbedpanel() •preptabbedpanel() •preptabbedpanel() •preptabbedpanel() •preptabbedpanel() •preptabbedpanel() •preptabbedpanel() •preptabbedpanel() •preptabbedpanel() •preptabbedpanel() •preptabbedpanel() •ShowTools/A arrow •preptabbedpanel() •ShowTools/A arrow •preptabbedpanel() •preptabbedpanel() •preptabbedpanel() •preptabbedpanel() •preptabbedpanel() •ShowTools/A arrow •preptabbedpanel() •preptabbedpanel() •preptabbedpanel() •make testWave = {{0,1,2,3},{4,5,6,7},{8,9,10,11}} •Edit testWave •make /O testWave ={{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},{0, 10, 20, 30, 40, 50, 60, 70, 80, 90},{0, 100, 200, 300, 400, 500, 600, 700, 800, 900},{0,1000,2000,3000,4000,5000,6000,7000,8000,9000}} •preptabbedpanel() •print workPos[3][5] 3000 •print workPos[3][2] 300 •preptabbedpanel() •preptabbedpanel() tableEntryAccepted tableEntryAccepted tableEntryAccepted tableEntryAccepted tableEntryAccepted workPos [1][0] must be between 0 and 1 tableEntryAccepted workPos [0][0] must be between 0 and 1 tableEntryAccepted workPos [0][0] must be between 0 and 1 tableEntryAccepted workPos [0][2] must be between 2 and 100 tableEntryAccepted tableEntryAccepted workPos[0][1] must be between 1 and 10 tableEntryAccepted tableEntryAccepted tableEntryAccepted tableEntryAccepted tableEntryAccepted workPos[0][3] must be between 3 and 1000 tableEntryAccepted tableEntryCancelled tableEntryCancelled tableEntryAccepted workPos[0][0] must be between 0 and 1 tableEntryAccepted workPos[0][0] must be between 0 and 1 tableEntryCancelled tableEntryAccepted workPos[0][0] must be between 0 and 1 tableEntryCancelled •NewNotebook/F=1/N=AdvancedTopics •DoWindow/R demoPanel •modifyTable/W=demoPanel#tSeqPos entryMode=0 •print S_Value 1 •modifyTable/W=demoPanel#tSeqPos entryMode=0 •print S_Value 1888 •modifyTable/W=demoPanel#tSeqPos entryMode=0;print S_Value 1888 tableEntryAccepted workPos[0][0] must be between 0 and 1 •modifyTable/W=demoPanel#tSeqPos entryMode=0;print S_Value 1 tableEntryAccepted workPos[0][0] must be between 0 and 1 •printEntry() in macro: S_Value= 1777 in function: S_Value = 1777 tableEntryAccepted workPos[0][0] must be between 0 and 1 •printEntry() in macro: S_Value= 1 in function: S_Value = 1 •NewNotebook/F=1/N=ModifyTableEntryMode •ForceEntryAcceptance() tableEntryAccepted workPos[0][0] must be between 0 and 1 Entry before acceptance = "999", after = "999" •ForceEntryReject() tableEntryCancelled Entry before cancellation = "5555", after = "1" •ForceEntryAcceptance() Entry before acceptance = "not a value", after = "not a value" tableEntryCancelled •ForceEntryAcceptance() Entry before acceptance = "1", after = "1" •ForceEntryReject() tableEntryCancelled Entry before cancellation = "not a value", after = "1" •ForceEntryAcceptance() tableEntryAccepted workPos[0][0] must be between 0 and 1 Entry before acceptance = "1123456789", after = "1123456789" •ForceEntryReject() tableEntryCancelled Entry before cancellation = "1563", after = "1" •printEntry() in macro: S_Value= 1 in function: S_Value = 1 •printEntry() in macro: S_Value= 12 in function: S_Value = 12 •NewNotebook/F=1/N=Notebook0 !¬ˆª3HoK¼®×K¼®× panelPosð?ð?ð?ð?¨ß%hy·®×N·®× workPosX ð?ð?ð?ð?ÈB€?@@@€@ @À@à@AA¨~%h$·®×·®× workPosY ð?ð?ð?ð? A AðA BHBpBŒB B´B¨&$h|·®×·®× workPosZ ð?ð?ð?ð?ÈBHC–CÈCúCD/DHDaD¨8*hj·®×·®× workPosT ð?ð?ð?ð?zDúD€;EzE@œE€»EÀÚEúE  FŽ Pkæv´×æv´×posWaveð?ð?ð?ð?À nàÙḮ×Ḯ×(testWave ð?ð?ð?ð?€?@@@€@ @À@à@AA A AðA BHBpBŒB B´BÈBHC–CÈCúCD/DHDaDzDúD€;EzE@œE€»EÀÚEúE  F0Y¥ð}9Ï®×æv´×,workPos ð?ð?ð?ð?€?€?@@@€@ @À@à@AA€? A AðA BHBÐI@ŒB B´BÈBÈBHCÈBHC–CÈCúC/DHDaD@@zDúD€;EzE@œE€»EÀÚEúE  F*4// Platform=Macintosh, IGORVersion=8.020, architecture=Intel, systemTextEncoding="MacRoman", historyTextEncoding="UTF-8", procwinTextEncoding="UTF-8", recreationTextEncoding="UTF-8", build=32405 #pragma TextEncoding = "UTF-8" Silent 101 // use | as bitwise or -- not comment. DefaultFont "Arial" MoveWindow/C 35,397,1262,659 String/G root:gWMSetNextTextFilesTextEncoding = "MacRoman" // Text encoding for AdvancedTopics. Used by Igor Pro 7. OpenNotebook/N=AdvancedTopics/W=(1127,53,2200,931)/P=home "AdvancedTopicsTableHooks.ifn" demoPanel() String/G root:gWMSetNextTextFilesTextEncoding = "MacRoman" // Text encoding for ModifyTableEntryMode. Used by Igor Pro 7. OpenNotebook/N=ModifyTableEntryMode/W=(1058,95,2169,901)/P=home "ModifyTableEntryMode.ifn" MoveWindow/P 937,141,2249,1284 KillStrings/Z root:gWMSetNextTextFilesTextEncoding Window demoPanel() : Panel PauseUpdate; Silent 1 // building window... NewPanel /W=(3,54,653,429) TabControl tabSetup,pos={5.00,5.00},size={610.00,330.00},proc=TabProc,fSize=12 TabControl tabSetup,tabLabel(0)="Tab 0",tabLabel(1)="Tab 1",tabLabel(2)="Tab 2" TabControl tabSetup,tabLabel(3)="Tab 3",value= 0 Button button1,pos={29.00,41.00},size={50.00,20.00},disable=1,title="Btn1" Button button2,pos={23.00,39.00},size={50.00,20.00},disable=1,title="Btn2" Button button3,pos={16.00,36.00},size={50.00,20.00},disable=1,title="Btn3" SetWindow kwTopWin,hook(MyHook)=Func_WinHookFunc Edit/W=(10,25,609,329)/HOST=# workPos ModifyTable format(Point)=1 ModifyTable statsArea=85 RenameWindow #,tSeqPos SetActiveSubwindow ## EndMacro Ç%#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma IgorVersion=8.02 // for ModifyTable entryMode and TableHook events 24 ("tableEntryAccepted") and 25 ("tableEntryCancelled"). // This file illustrates a puzzle I have about using the table window in Igor 8. (So far, I've been testing only under Windows 10.) // // I'd like to be able to directly read the value of a cell in the table, independent of reading the value of the point // in the wave associated with that cell. I esp. want to do this from within a hook function when the user steps away from // the cell, ex. by pressing or , an arrow key, or PageUp/PageDown. Doing so will let my code check the user's // latest edits for validity, illustrated here by the function HoldInBounds(). // To test: // 1. run the function PrepTabbedPanel() from the command window. // 2. Set a debugging breakpoint on the line below (approx. line 189) that reads // // proposedNewVal = HoldInBounds (workPos[thisRow][thisCol], minOK, maxOK) // // 3. Click on cell in the table, notice its initial value, and then type some different value into the cell. // 4. Click Enter to end editing the cell. // 5. When the breakpoint trips, note the value contained in workPos[thisRow][thisCol], and compare it to the value typed in the cell. // static constant PNL_HEIGHT = 375 static constant PNL_WIDTH = 650 function testFunc () struct point testPoint GetSelection table, demoPanel#tSeqPos, 0x05 // Determine which cell(s) is(are) selected in tSeqPos Table GetCellTopLeftCorner (V_startRow, V_startCol, testPoint) printf "(%d,%d)\n", testPoint.h, testPoint.v end Function TabProc(tca) : TabControl STRUCT WMTabControlAction &tca switch( tca.eventCode ) case 2: // mouse up Variable tab = tca.tab UI_SetupForTab (tab) break case -1: // control being killed break endswitch return 0 End static function UI_SetupForTab (variable tab) // tab 0 setwindow demoPanel#tSeqPos hide=(tab!=0) // tab 1 button button1 disable=(tab!=1) // tab 2 button button2 disable=(tab!=2) // tab 3 button button3 disable=(tab!=3) end function PrepTabbedPanel() PauseUpdate; Silent 1 // building window... NewPanel /W=(100, 100, 100+PNL_WIDTH, 100+PNL_HEIGHT) /N=demoPanel SetWindow demoPanel, hook(MyHook)=Func_WinHookFunc // Install named window hook and userdata TabControl tabSetup,pos={5.00,5.00},size={610,330},proc=TabProc,fSize=12 TabControl tabSetup,tabLabel(0)="Tab 0", value= 0 TabControl tabSetup,tabLabel(1)="Tab 1" TabControl tabSetup,tabLabel(2)="Tab 2" TabControl tabSetup,tabLabel(3)="Tab 3" Button button1,pos={29.00,41.00},size={50.00,20.00},disable=1,title="Btn1" Button button2,pos={23.00,39.00},size={50.00,20.00},disable=1,title="Btn2" Button button3,pos={16.00,36.00},size={50.00,20.00},disable=1,title="Btn3" //PopupMenu popup0,pos={117.00,448.00},size={73.00,19.00},proc=PopMenuProc //PopupMenu popup0,mode=3,popvalue="Maybe so",value= #"\"Yes;No;Maybe so;Not Sure;Could be;\"" make /O workPos = {{-1, 1, 2, 3, 4, 5, 6, 7, 8, 9}, {-10, 10, 20, 30, 40, 50, 60, 70, 80, 90},{-100, 100, 200, 300, 400, 500, 600, 700, 800, 900},{-1000,1000,2000,3000,4000,5000,6000,7000,8000,9000}} Edit /W=(10,25,609,329) /HOST=demoPanel /N=tSeqPos workPos dowindow /F/HIDE=0 tSeqPos end Function Func_WinHookFunc(s) STRUCT WMWinHookStruct &s Variable hookResult = 0 // 0 if we do not handle event, 1 if we handle it. GetWindow $s.winName activeSW String activeSubwindow = S_value variable strPos = strsearch(activeSubwindow,"#tSeqPos",0,2) if ( strPos > 0) // ... found the table's name => the event occurred in the table string parentWinName = activeSubwindow[0,strPos-1] hookResult = Func_TableHook(s, parentWinName) else // handle events in parent window here endif return hookResult // If non-zero, we handled event and Igor will ignore it. End function Func_TableHook(STRUCT WMWinHookStruct &s, string &parentWindowName) Variable hookResult = 0 // 0 if we do not handle event, 1 if we handle it. //printf "Func_TableHook() eventCode:0x%x\tkeyCode:0x%x\tspecialKeyCode:0x%x\n", s.eventCode, s.keyCode, s.specialKeyCode GetSelection table, $(parentWindowName)#tSeqPos, 0x05 // Determine which cell(s) is(are) selected in WorkPos Table switch(s.eventCode) case 3: // mouse down break case 5: // mouse up //printf "TableHook(%d,%d)\t(%d,%d)\t(%d,%d)\n", s.mouseLoc.h, s.mouseLoc.v, V_startCol, V_startRow, V_endCol, V_endRow if ((V_startCol==0)&&(V_endCol==0)&&(V_startRow==V_endRow)) // exactly one cell in col 0 is selected endif break case 11: // keyboard event //printf "Func_TableHook() eventCode:0x%x\tkeyCode:0x%x\tspecialKeyCode:0x%x\n", s.eventCode, s.keyCode, s.specialKeyCode switch (s.keyCode) case 0x03: // Enter case 0x0d: // return // user is stepping away from current cell: perform bounds check // Func_WorkPosTableBoundsCheck () // hookResult = 1 break case 0x1c: // left arrow break case 0x1d: // right arrow break case 0x1e: // up arrow break case 0x1f: // down arrow break default: break endswitch break case 24: // tableEntryAccepted in Igor 8.02+ Print s.eventName // "tableEntryAccepted" Func_WorkPosTableBoundsCheck() break case 25: // tableEntryCancelled in Igor 8.02+ Print s.eventName // "tableEntryCancelled" break default: break endswitch return hookResult end function Func_WorkPosTableBoundsCheck() WAVE workPos GetSelection table, demoPanel#tSeqPos, 0x05 // Determine which cell(s) is(are) selected in table if (V_flag==0) // nothing selected (apparently) return 0 endif make /O /n=4 posWave variable minOK, maxOK, proposedNewVal, currentVal int thisRow, thisCol, anyError=0 for (thisCol=V_StartCol; thisCol<=V_endCol; thisCol++) if (thisCol==0) minOK = 0 maxOK = 1 elseif (thisCol==1) minOK = 1 maxOK = 10 elseif (thisCol==2) minOK = 2 maxOK = 100 elseif (thisCol==3) minOK = 3 maxOK = 1000 else printf "Func_WorkPosTableBoundsCheck() invalid col:%d\n", thisCol endif for (thisRow=V_StartRow; thisRow<=V_endRow; thisRow++) // In my tests, the value of the point in the wave extracted in the right side of this assignment // contains the orig value in the wave, not the value typed into the table's cell just before pressing . currentVal = workPos[thisRow][thisCol] proposedNewVal = HoldInBounds (currentVal, minOK, maxOK) if( currentVal != proposedNewVal ) anyError=1 // break // what point is there in going on? // maybe this? workPos[thisRow][thisCol] = proposedNewVal printf "%s[%d][%d] must be between %g and %g\n", NameOfWave(workPos), thisRow,thisCol, minOK, maxOK endif // We want to be able to read directly the value currently contained in the table's cell, // independently from the value of the corresponding point in the wave. endfor endfor end function HoldInBounds (variable proposed, variable minPermitted, variable maxPermitted) if (proposed < minPermitted) return minPermitted elseif (proposed > maxPermitted) return maxPermitted else return proposed endif end function GetCellTopLeftCorner (int thisRow, int thisCol, STRUCT point &cornerPt) int i, wStartPosInStr, wStopPosInStr, maxStrLen, left = 0, top = 0 string strRslts, widthStr for (i=-1;i=0) && (wStartPosInStr