#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 #pragma version=1.05 // by tony.withers@uwo.ca // Use the shortcut "cmd + 9" to start CalcPad. CalcPad turns a notebook // into a command-line type interface. Use up and down arrows to insert // previously executed lines. Use shift-up/down to replace selection with // previous answers. Execution environment is current data folder. Global // variables v_CalcPad and s_CalcPad are created temporarily in the // current data folder. Some easy-to-edit options are marked by comments // in the function CalcPad(). // If you find this package to be useful, I recommend editing the next // line of code to convert this procedure to an independent module. // Simply change the 0 to 1. If you put this file in the Igor Procedures // folder CalcPad will then be always available using the cmd + 9 // shortcut or through the Analysis > Packages menu. The default setting // of 0 allows you to read this file and test the package. #if 0 #pragma IndependentModule = CalcPad menu "Analysis" submenu "Packages" "CalcPad/9", /Q, CalcPad#CalcPad() end end #else menu "Macros" "CalcPad/9", /Q, CalcPad() end #endif function CalcPad() NewDataFolder /O root:Packages NewDataFolder /O root:Packages:CalcPad DFREF dfr = root:Packages:CalcPad make /o/n=5 dfr:w_options /wave=options make /o/n=3 dfr:w_txtRGB /wave=RGB_text make /o/n=3 dfr:w_ansRGB /wave=RGB_answer make /free/n=3 RGB_background variable font_size, window_width, window_height, window_left, window_top SetDimLabel 0, 0, null, options SetDimLabel 0, 1, AllowEnterToCopy, options SetDimLabel 0, 2, InLine, options SetDimLabel 0, 3, StringEval, options options[%null]=nan // ------ set some default options here ------- font_size=14 // font size window_width=350 // window width window_height=250 // window height window_left=20 // window horizontal position window_top=50 // window vertical position RGB_background={65535, 65535, 65535} // edit default window background color here RGB_text={0,0,0} // default font color RGB_answer={0,0,65280} // default color for answers options[%AllowEnterToCopy]=1 // allow enter key to copy selected history text to end of last line options[%InLine]=1 // answers on same line as input options[%StringEval]=1 // allow fallback to string evaluation // ------- end user editable options ---------- if(waveexists(dfr:w_history)==0) make /o/T/N=0 dfr:w_history, dfr:w_answers variable /G dfr:v_ans=0, dfr:v_hist=0 endif if (strlen(WinList("CalcPadNB", ";", "WIN:16"))) dowindow /F CalcPadNB else NewNotebook /K=1 /F=1 /W=(window_left, window_top, window_left+window_width, window_top+window_height) /N=CalcPadNB as "CalcPad" notebook CalcPadNB showRuler=0, fSize=font_size notebook CalcPadNB backRGB=(RGB_background[0],RGB_background[1],RGB_background[2]) notebook CalcPadNB textRGB=(RGB_text[0],RGB_text[1],RGB_text[2]) endif SetWindow CalcPadNB, hook(hCalcPad)=CalcPadHook return 1 end function CalcPadHook(H_Struct) STRUCT WMWinHookStruct &H_Struct DFREF dfr = root:Packages:CalcPad wave /T w_hist=dfr:w_history, w_ans=dfr:w_answers NVAR v_ans=dfr:v_ans, v_hist=dfr:v_hist wave g=dfr:w_options wave /SDFR=dfr w_txtRGB, w_ansRGB, w_options if(H_Struct.eventcode==11) // keyboard event if(H_Struct.keycode==28 || H_Struct.keycode==29) // left or right arrow return 0 // allow these for selecting text endif // make sure that we're typing on the last line GetSelection notebook, CalcPadNB, 1 // get current position in notebook // store position make /free w={V_startParagraph, V_startPos, V_endParagraph, V_endPos} // find last paragraph notebook CalcPadNB selection={endOfFile,endofFile} GetSelection notebook, CalcPadNB, 1 if (V_startParagraph==w[0]) // we're writing on the last line // restore current position notebook CalcPadNB selection={(w[0],w[1]), (w[2],w[3])} else if(w_options[%AllowEnterToCopy] && (H_Struct.keycode==13 || H_Struct.keycode==3)) // return or enter notebook CalcPadNB selection={(w[0],w[1]), (w[2],w[3])} GetSelection notebook, CalcPadNB, 2 // sets S_selection notebook CalcPadNB selection={endOfFile,endofFile} if (strlen(s_selection)) Notebook CalcPadNB text=s_selection endif endif notebook CalcPadNB findText={"",1} // jump to end of last line return 1 endif // this allows select, copy within notebook // typing allowed on the last line only // trying to type elsewhere sends cursor to end of file if (H_Struct.keycode==30 || H_Struct.keycode==31) // up or down arrow string s_insert if (H_Struct.eventMod & 2) // shift key // replace currently highlighted text with a previous answer GetSelection notebook, CalcPadNB, 1 w={V_startParagraph, V_startPos, V_endParagraph, V_endPos} v_ans+=1-2*(H_Struct.keycode==30) v_ans=max(0, v_ans) if (v_ansnumpnts(w_hist)-1) s_insert="" else s_insert=w_hist(v_hist) endif v_hist=min(v_hist, numpnts(w_hist)) notebook CalcPadNB text=s_insert notebook CalcPadNB selection={endOfFile,endofFile} endif return 1 endif if (H_Struct.keycode==8) // delete GetSelection notebook, CalcPadNB, 1 // get current position in notebook if(V_startPos==0 && V_endPos==0) // Don't delete the start of the last line return 1 endif endif if (H_Struct.keycode==13) // return // select the last paragraph notebook CalcPadNB selection={startOfParagraph, endOfChars} GetSelection notebook, CalcPadNB, 2 // sets S_selection if (strlen(s_selection)==0) return 1 endif notebook CalcPadNB selection={endOfParagraph, endOfParagraph} w_hist[numpnts(w_hist)]={s_selection} v_hist=numpnts(w_hist) variable /G v_CalcPad=nan // work with a global variable in the current data folder so that // we can be folder aware execute /z/q "v_CalcPad = "+S_selection NVAR v_result=v_CalcPad string s_result if(w_options[%StringEval] && numtype(v_result)!=0) // not a normal number, so try to evaluate as text string /G s_CalcPad="" execute /Z/Q "s_CalcPad = "+S_selection if (strlen(s_CalcPad)) sprintf s_result, "\"%s\"", s_CalcPad else sprintf s_result, "%g", v_result endif else sprintf s_result, "%g", v_result endif w_ans[numpnts(w_ans)]={s_result} v_ans=numpnts(w_ans) notebook CalcPadNB textRGB=(w_ansRGB[0],w_ansRGB[1],w_ansRGB[2]) if(w_options[%InLine]) Notebook CalcPadNB text=" = " else Notebook CalcPadNB text="\r\t" endif Notebook CalcPadNB text=s_result +"\r" notebook CalcPadNB textRGB=(w_txtRGB[0],w_txtRGB[1],w_txtRGB[2]) KillVariables /Z v_result KillStrings /Z s_CalcPad return 1 endif endif if(H_Struct.eventcode==10) // menu if (stringmatch(H_Struct.menuItem, "Paste")) GetSelection notebook, CalcPadNB, 1 // get current position in notebook // store position make /free w={V_startParagraph, V_startPos, V_endParagraph, V_endPos} // find last paragraph notebook CalcPadNB selection={endOfFile,endofFile} GetSelection notebook, CalcPadNB, 1 if (V_startParagraph==w[0]) // we're writing on the last line // restore current position notebook CalcPadNB selection={(w[0],w[1]), (w[2],w[3])} else // trying to paste somewhere else return 1 endif endif endif if(H_Struct.eventcode==2) // kill window killdatafolder /Z dfr endif return 0 end