Code archives/BlitzPlus Gui/MaxIDE
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
Requires MaxGUI. | |||||
' maxide.bmx - blitzmax native integrated development environment ' released under the Blitz Shared Source Code License ' (c)2005 Blitz Research ' initial release version by simonarmstrong@blitzbasic.com ' v120d ' added external help option for linux users ' v120c ' add doc modules option to program menu and fixed syncmods so no restart required ' fixed wrong window activation ugliness in TRequester.Hide ' fixed TDebugTree.SetStack synchronization bug ' v120b ' added autobackup code to SaveSource method ' fixed autoindent bug including tabs to the right of the cursor ' v120 ' Ripped out isupdate stuff ' About requester now shows runtime BCC version ' v118 ' Added file filter to SaveAs requester ' Edit method of TOpenCode now activates cursor and refreshes status ' TQuickHelp tokenizer now uses faster TToken map ' ReadSource and WriteSource now use unicode LoadText and SaveText commands ' v112b ' added .doc file type to filters list ' added trycatch for bmxpath not found ' prepends bmx filenames loaded from help with "." to protect original source ' fixed unblanced quotes in wordatpos() stuffing up quick help ' fixed exception when debugging function pointer values ' v112 ' isupgrade - version check on ini file for ranlibdir and quick build disable ' debug step tools now respect cancontinue flag ' tidied up debug stdio buffers and flushing of process pipes ' linux defaults for closedocument-CtrlW nextdoc-AltRight prevdoc-AltLeft ' end of lines converted to chr(13)+chr(10) for all saved source files ' ReplaceAll uses locktextarea for speedup ' added print option for helppage ' filtering tab key in opencode for original block in/outdent ' removed vertical tabs from source ' added .bbdoc filetype to filters$ ' fixed null href help tree entries (index node) ' new textareafilter code for the Ouput console emulator ' refreshes pointer in splitter on EVENT_MOUSEMOVE ' v111 ' fixed open locked file not found at startup crash ' buildandrun continues from debugstop else kills task and rebuilds ' fixed bug on freshly loaded source being dirty ' fixed bug with options cancel ' MacOS specific hotkey bindings updated ' added .m to file FILTERS$ ' adjusted GOTO and IDEOptions requesters ' v110 ' DebugSource now calls ShowGadget on IDE window to bring debugger to front ' v109 ' fixed WordAtPos to include underscore ' v108 ' windows release version ' v107 ' activate current panel when window receives focus ' fixed multiple lock build file bug ' fixed command highlighting for functions with # and ! return types ' sourcefile already open check now case insensitive ' block indent outdent now ctrl-[ and ctrl-] ' commandline args fixed ' v106b ' new defaults ' fixed replace all garbage ' removed extra endrem highlight ' v106 ' added demo version support ' fixed delete / backspace undo redo issues ' added syntaxhighlight disable option ' fixed block indent / outdent highlighting issue ' added flushmem to replaceall loop ' set window title to full path of current document ' fixed double highlight for endrem ' v105c ' code view now includes labels etc. on first line ' textarea activated when panel open ' autohide output on exit now always returns to last active panel ' optimized code change algorithm ' like compiler, rem and endrem must be first code on line ' fixed up linux line spacing, font selection and code tree / create panel crashes ' new linux help system, style setting and popup menu support ' v105b ' added tabbing support in dialogs ' fixed pollsystem event debacle ' fixed lineselection out of view ' fixed highlighting for pasting code blocks ' fixed treeview memory leak and speedissues ' uses -x switch from bmk for build and run option ' debugging now opens source when stepping in ' v105 ' activating window selects current panel ' fixed closing output window causing crash ' frees gadgets ' dirty flags now clears only if source=file and undobuffer=empty ' tidied up console window madness ' fixed gcc error check hang ' fixed label detection in code view ' fixed debugger crash with local block variable decls ' fixed codenode refresh with saveas ' v104 ' fixed debug tree update and debugreset ' fixed incorrect navbar size for maximized window ' added \ option ' notify gcc compiler errors in output ' v103 ' navbar options left/right ' added copy paste menu for output window ' added font color options for output and navbar windows ' fixed win32 paste from clipboard to use plain ascii ' stdio debugger handler ' save currentpanel, cursorpositions ' replace default "~\" requestfile path with a currentpath ' fixed pipe handling problem in quickhelp ' v102 ' specify openfile from commandline ' hides main window till all files openned ' checks window bounds against desktop size ' added deferred capitalizing cludge ' fixed rem/endrem updating problem ' fixed highlight / redraw noise ' drag&drop file support added ' dropdown menu in textarea added ' run with commandline arguments ' block indent/outdent ' fixed drag&drop text crash ' added escape handler to output window, removed autohide Strict Framework brl.maxgui Import brl.win32maxgui Import brl.cocoamaxgui Import brl.fltkmaxgui Import brl.standardio Import brl.retro Import brl.filesystem Import brl.system Import pub.freeprocess Import brl.pngloader Import brl.timer Import brl.maxutil ?win32 Import "maxicons.o" ? Incbin "icons.PNG" Incbin "syncmodsblurb.txt" Const IDE_VERSION$="1.20" Global BCC_VERSION$="{unknown}" 'not valid until codeplay opened Const EOL$="~n" Const SPLITWIDTH=4 Const ABOUT$=.. "{bcc_version} - Copyright Blitz Research Ltd~n~n"+.. "Please visit www.blitzbasic.com for all your Blitz related needs!" Const ABOUTDEMO$=.. "This demo features both the core BlitzMax package and optional MaxGUI module.~n~n"+.. "Please note that the MaxGUI module must be purchased separately." Const FILTERS$="Code Files:bmx,bbdoc,txt,vp,doc,plist,bb,cpp,c,m,cxx,s,fs,vs,p,fp,glsl,h,hpp,html,htm,css,js,bat;All Files:*" Const NodeFileTypes$="|bmx|bbdoc|cpp|cxx|c|m|h|s|fs|vs|p|fp|glsl|txt|html|js|css|bb|java|bat|ini|jpg|png|bmp|tga|wav|pl|doc|plist|" Global MODOPTIONS$[]=["BRL","PUB","AXE"] ',"MAK","GMAN","BIRDIE"] Global MODINFO$[]=["BlitzMax Core Modules","Public Domain Core Modules","User Contributed Modules"] '"Mark Sibly's Module Collection","Simon Armstrong's Module Collection","Garrit Grandberg's Module Collection","Dave Bird's Module Collection"] ?MacOS Const DEFAULTFONT$="Courier" Const DEFAULTFONTSIZE=12 Const HOMEPAGE$="/doc/index.html" ? ?Win32 Const DEFAULTFONT$="Courier" Const DEFAULTFONTSIZE=10 Const HOMEPAGE$="/doc/index.html" ? ?Linux Const DEFAULTFONT$="Lucida" Const DEFAULTFONTSIZE=12 Const HOMEPAGE$="/doc/index.html" 'Const HOMEPAGE$="/doc/home.html" ? Const MENUNEW=1 Const MENUOPEN=2 Const MENUCLOSE=3 Const MENUSAVE=4 Const MENUSAVEAS=5 Const MENUSAVEALL=6 Const MENUPRINT=7 Const MENUQUIT=8 Const MENUUNDO=9 Const MENUREDO=10 Const MENUCUT=11 Const MENUCOPY=12 Const MENUPASTE=13 Const MENUSELECTALL=14 Const MENUGOTO=15 Const MENUINDENT=16 Const MENUOUTDENT=17 Const MENUFIND=18 Const MENUFINDNEXT=19 Const MENUREPLACE=20 Const MENUNEXT=21 Const MENUPREV=22 Const MENUBUILD=23 Const MENURUN=24 Const MENUSTEP=25 Const MENUSTEPIN=26 Const MENUSTEPOUT=27 Const MENUSTOP=28 Const MENULOCKBUILD=29 Const MENUUNLOCKBUILD=30 Const MENUBUILDMODULES=31 Const MENUBUILDALLMODULES=32 Const MENUQUICKENABLED=33 Const MENUDEBUGENABLED=34 Const MENUGUIENABLED=35 Const MENUCOMMANDLINE=36 Const MENUSYNCMODS=37 Const MENUIMPORTBB=38 Const MENUFINDINFILES=39 Const MENUPROJECTMANAGER=40 Const MENUSHOWCONSOLE=41 Const MENUOPTIONS=42 Const MENUHOME=43 Const MENUBACK=44 Const MENUFORWARD=45 Const MENUQUICKHELP=46 Const MENUABOUT=47 Const MENUNEWVIEW=48 Const MENUDOCMODS=49 Const MENUTRIGGERDOCMODS=50 Const MENUTRIGGERSYNCDOCS=51 Const MENUCLOSEALL=53 Const MENURECENT=256 Const TAB$=Chr(9) Const QUOTES$=Chr(34) Global TEMPCOUNT Global is_demo Global codeplay:TCodePlay Function CheckDemo() If Not is_demo Return 1 Notify "This feature is unavailable in the demo version of BlitzMax" Return 0 End Function codeplay=New TCodePlay codeplay.Initialize While codeplay.running codeplay.poll Wend End Function Quote$(a$) 'add quotes to arg if spaces found Local p If a.length=0 Return If a[0]=34 Return a 'already quoted p=a.find(" ") If p=-1 Return a 'no spaces Return Chr(34)+a+Chr(34) End Function Type TToken Field token$ Field help$ Field ref$ Method Create:TToken(t$,h$,r$) token=t help=h ref=r Return Self End Method End Type Type TQuickHelp Field map:TMap=New TMap 'key=lower(token) value=token:TToken Method AddCommand:TQuickHelp(t$,l$,a$) map.Insert Lower(t$),New TToken.Create(t$,l$,a$) End Method Method Token$(cmd$) Local t:TToken t=TToken(map.ValueForKey(cmd.toLower())) If t Return t.token End Method Method Help$(cmd$) Local t:TToken t=TToken(map.ValueForKey(cmd.toLower())) If t Return t.help End Method Method Link$(cmd$) Local t:TToken t=TToken(map.ValueForKey(cmd.toLower())) If t Return t.ref End Method Function LoadCommandsTxt:TQuickHelp(bmxpath$) Local stream:TStream Local qh:TQuickHelp Local l$,c$,p,q Local token$,help$,anchor$ stream=ReadFile(bmxpath+"/doc/bmxmods/commands.txt") If stream=Null Return Null qh=New TQuickHelp While Not Eof(stream) l$=ReadLine(stream) Local i For i=0 Until l.length Local c=l[i] If c=Asc("_") Continue If c>=Asc("0") And c<=Asc("9") Continue If c>=Asc("a") And c<=Asc("z") Continue If c>=Asc("A") And c<=Asc("Z") Continue Exit Next token$=l[..i] help$="" anchor$="" q=l.find("|") If q help=l[..q] anchor=l[q+1..] EndIf qh.AddCommand token,help,anchor Wend stream.Close Return qh End Function End Type Const TOOLSHOW=1 Const TOOLREFRESH=2 Const TOOLNEW=3 Const TOOLOPEN=4 Const TOOLCLOSE=5 Const TOOLSAVE=6 Const TOOLHELP=7 Const TOOLUNDO=8 Const TOOLREDO=9 Const TOOLCUT=10 Const TOOLCOPY=11 Const TOOLPASTE=12 Const TOOLQUICKSAVE=13 Const TOOLSAVEAS=14 Const TOOLGOTO=15 Const TOOLFIND=16 Const TOOLFINDNEXT=17 Const TOOLREPLACE=18 Const TOOLBUILD=19 Const TOOLRUN=20 Const TOOLLOCK=21 Const TOOLUNLOCK=22 Const TOOLSELECT=23 Const TOOLSELECTALL=24 Const TOOLINDENT=25 Const TOOLOUTDENT=26 Const TOOLACTIVATE=27 Const TOOLNAVIGATE=28 Const TOOLNEWVIEW=29 Const TOOLMENU=30 Const TOOLPRINT=31 Type TTool Method Invoke(command,argument:Object=Null) End Method End Type Type TRequester Field host:TCodePlay Field window:TGadget,ok:TGadget,cancel:TGadget Field centered Method initrequester(owner:TCodeplay,label$,w=280,h=128,flags=3) host=owner window=CreateWindow(label,0,0,w,h,Null,1+64) If flags&1 cancel=CreateButton("Cancel",8,ClientHeight(window)-34,80,24,window,BUTTON_CANCEL) If flags&2 ok=CreateButton("OK",ClientWidth(window)-88,ClientHeight(window)-34,80,24,window,BUTTON_OK) End Method Method Show() Local x,y,w,h,win:TGadget DisableGadget host.window If Not centered win=host.window w=GadgetWidth(window) h=GadgetHeight(window) x=GadgetX(win)+(GadgetWidth(win)-w)/2 y=GadgetY(win)+(GadgetHeight(win)-h)/2 SetGadgetShape window,x,y,w,h centered=True EndIf ShowGadget window ActivateGadget window host.SetRequester Self PollSystem End Method Method Hide() EnableGadget host.window HideGadget window host.SetRequester Null ' host.SelectPanel host.currentpanel End Method Method Poll() End Method End Type Type TProgressRequester Extends TRequester Field message$,value Field showing Field label:TGadget Field progbar:TGadget Method Show() 'returns false if cancelled showing=True Super.Show End Method Method Hide() showing=False Super.Hide() End Method Method Open(title$) SetGadgetText window,title Show End Method Method Update(msg$,val) If msg$<>message message=msg If label FreeGadget label label=CreateLabel(message,8,8,260,20,window) EndIf If showing And (val&$fc)<>(value&$fc) 'only update every 4 percent UpdateProgBar( progbar,val/100.0 ) PollSystem EndIf value=val End Method Function Create:TProgressRequester(host:TCodePlay) Local progress:TProgressRequester progress=New TProgressRequester progress.initrequester(host,"ProgressRequester",280,128,1) '1 for cancel button progress.progbar=CreateProgBar( 8,32,260,20,progress.window ) Return progress End Function End Type Type TPanelRequester Extends TRequester Field tabber:TGadget Field panels:TGadget[] Field index Method InitPanelRequester(owner:TCodeplay,label$,w=280,h=128) InitRequester owner,label,w,h w=ClientWidth(window) h=ClientHeight(window)-40 tabber=CreateTabber(4,4,w-8,h-8,window) SetGadgetLayout tabber,1,1,1,1 End Method Method SetPanelIndex(i) HideGadget panels[index] index=i ShowGadget panels[index] SelectGadgetItem tabber,index End Method Method SetPanel(panel:TGadget) Local p:TGadget,i For p=EachIn panels If p=panel SetPanelIndex i;Exit i:+1 Next End Method Method AddPanel:TGadget(name$) Local panel:TGadget panel=CreatePanel(0,0,ClientWidth(tabber),ClientHeight(tabber),tabber) SetGadgetLayout panel,1,1,1,1 HideGadget panel AddGadgetItem tabber,name panels=panels[..panels.length+1] panels[panels.length-1]=panel Return panel End Method Method RemovePanel(panel) End Method End Type Type TCmdLineRequester Extends TRequester Field label:TGadget,textfield:TGadget Method Poll() Local id,data id=EventID() data=EventData() Select EventSource() Case window If EventID()=EVENT_WINDOWCLOSE Hide EndIf Case ok host.SetCommandLine TextFieldText(textfield) Hide Case cancel SetGadgetText textfield,host.GetCommandLine() Hide End Select End Method Method Show() SetGadgetText textfield,host.GetCommandLine() Super.Show() ActivateGadget textfield End Method Function Create:TCmdLineRequester(host:TCodePlay) Local cmd:TCmdLineRequester cmd=New TCmdLineRequester cmd.initrequester(host,"Program Command Line") cmd.label=CreateLabel("Program command line:",8,8,260,20,cmd.window) cmd.textfield=CreateTextField(8,32,260,20,cmd.window) Return cmd End Function End Type Type TGotoRequester Extends TRequester Field linenumber:TGadget Method Show() Super.Show() ActivateGadget linenumber End Method Method Poll() Local line,data Select EventSource() Case window If EventID()=EVENT_WINDOWCLOSE Hide EndIf Case ok line=Int(TextFieldText(linenumber)) Hide host.activepanel.Invoke TOOLGOTO,String(line) Case cancel Hide End Select End Method Function Create:TGotoRequester(host:TCodePlay) Local seek:TGotoRequester seek=New TGotoRequester seek.initrequester(host,"Goto Line",260,128) CreateLabel("Line Number:",20,24,114,20,seek.window) seek.linenumber=CreateTextField(134,20,100,20,seek.window) Return seek End Function End Type Type TColor Field red,green,blue Method Set(rgb) red=(rgb Shr 16)&255 green=(rgb Shr 8)&255 blue=rgb&255 End Method Method ToString$() Return ""+red+","+green+","+blue End Method Method FromString(s$) Local p,q p=s.Find(",")+1 If Not p Return q=s.Find(",",p)+1 If Not q Return red=Int(s[..p-1]) green=Int(s[p..q-1]) blue=Int(s[q..]) End Method Method Request() If RequestColor(red,green,blue) red=RequestedRed() green=RequestedGreen() blue=RequestedBlue() Return True EndIf End Method End Type Type TTextStyle Field label:TGadget,panel:TGadget,combo:TGadget Field color:TColor Field flags Method Set(rgb,bolditalic) color.set(rgb) flags=bolditalic End Method Method Format(textarea:TGadget,pos,length) FormatTextAreaText textarea,color.red,color.green,color.blue,flags,pos,length End Method Method ToString$() Return ""+color.red+","+color.green+","+color.blue+","+flags End Method Method FromString(s$) Local p,q,r p=s.Find(",")+1;If Not p Return q=s.Find(",",p)+1;If Not q Return r=s.Find(",",q)+1;If Not r Return color.red=Int(s[..p-1]) color.green=Int(s[p..q-1]) color.blue=Int(s[q..r-1]) flags=Int(s[r..]) End Method Method Poll() Select EventSource() Case panel If EventID()=EVENT_MOUSEDOWN Return color.Request() EndIf Case combo flags=SelectedGadgetItem(combo) Return True End Select End Method Method Refresh() SetPanelColor panel,color.red,color.green,color.blue SelectGadgetItem combo,flags End Method Function Create:TTextStyle(name$,xpos,ypos,window:TGadget) Local s:TTextStyle s=New TTextStyle s.color=New TColor s.label=CreateLabel(name,xpos,ypos+4,80,24,window) s.panel=CreatePanel(xpos+84,ypos,24,24,window,PANEL_BORDER|PANEL_ACTIVE) SetPanelColor s.panel,255,255,0 s.combo=CreateComboBox(xpos+112,ypos,96,24,window) AddGadgetItem s.combo,"Normal" AddGadgetItem s.combo,"Bold" AddGadgetItem s.combo,"Italic" AddGadgetItem s.combo,"Bold+Italic" Return s End Function End Type Type TGadgetStyle Field label:TGadget,fpanel:TGadget,bpanel:TGadget,fbutton:TGadget Field font_name$,font_size Field fg:TColor Field bg:TColor Field font:TGUIFont Method Apply(gadget:TGadget) SetGadgetFont gadget,font SetGadgetColor gadget,bg.red,bg.green,bg.blue,True SetGadgetColor gadget,fg.red,fg.green,fg.blue,False End Method Method Set(fg_rgb,bg_rgb,fname$,fsize) fg.set(fg_rgb) bg.set(bg_rgb) font_name=fname font_size=fsize End Method Method ToString$() Return font_name+","+font_size+","+fg.ToString()+","+bg.ToString() End Method Function GetArg$(a$ Var) Local p,r$ p=a.Find(",")+1 If p=0 p=Len a$+1 r$=a$[..p-1] a$=a$[p..] Return r$ End Function Method FromString(s$) font_name=GetArg(s$) font_size=Int(GetArg(s$)) fg.red=Int(GetArg(s$)) fg.green=Int(GetArg(s$)) fg.blue=Int(GetArg(s$)) bg.red=Int(GetArg(s$)) bg.green=Int(GetArg(s$)) bg.blue=Int(GetArg(s$)) End Method Method Poll() Local f:TGUIFont Select EventSource() Case fpanel If EventID()=EVENT_MOUSEDOWN Return fg.Request() EndIf Case bpanel If EventID()=EVENT_MOUSEDOWN Return bg.Request() EndIf Case fbutton f=RequestFont(font) If f font_name=FontName(f) font_size=FontSize(f) Return True EndIf End Select End Method Method Refresh() font=LoadGuiFont(font_name,font_size) SetPanelColor fpanel,fg.red,fg.green,fg.blue SetPanelColor bpanel,bg.red,bg.green,bg.blue SetGadgetText fbutton,font_name+":"+font_size End Method Function Create:TGadgetStyle(name$,xpos,ypos,window:TGadget) Local s:TGadgetStyle s=New TGadgetStyle s.fg=New TColor s.bg=New TColor s.label=CreateLabel(name,xpos,ypos+4,56,24,window) s.fpanel=CreatePanel(xpos+58,ypos,24,24,window,PANEL_BORDER|PANEL_ACTIVE) s.bpanel=CreatePanel(xpos+86,ypos,24,24,window,PANEL_BORDER|PANEL_ACTIVE) s.fbutton=CreateButton("..",xpos+112,ypos,180,24,window) Return s End Function End Type Const NORMAL=0 Const COMMENT=1 Const QUOTED=2 Const KEYWORD=3 Type TOptionsRequester Extends TPanelRequester ' panels Field optionspanel:TGadget,editorpanel:TGadget,toolpanel:TGadget ' settings Field showtoolbar,restoreopenfiles,autocapitalize,syntaxhighlight,autobackup,autoindent,hideoutput,externalhelp Field tabsize Field editfontname$,editfontsize,editcolor:TColor Field outputfontname$,outputfontsize,outputcolor:TColor ' states Field editfont:TGUIFont ' gadgets Field tabbutton:TGadget Field editpanel:TGadget,editbutton:TGadget Field buttons:TGadget[9] Field styles:TTextStyle[4] Field textarea:TGadget Field outputstyle:TGadgetStyle Field navstyle:TGadgetStyle Field navswapbutton:TGadget,navswap Field dirty Field undo:TBank Method Snapshot() If Not undo undo=CreateBank(8192) Local stream:TStream=CreateBankStream(undo) write stream stream.close End Method Method Restore() If Not undo Return Local stream:TStream=CreateBankStream(undo) Read stream stream.close End Method Method SetDefaults() showtoolbar=True restoreopenfiles=True autocapitalize=True syntaxhighlight=True autobackup=True autoindent=True tabsize=4 editfontname$=DEFAULTFONT editfontsize=DEFAULTFONTSIZE editcolor.set($01516b) styles[NORMAL].set($ffffff,0) styles[COMMENT].set($b1e7eb,0) styles[QUOTED].set($ff66,0) styles[KEYWORD].set($ffff00,0) outputstyle.set(0,-1,DEFAULTFONT,DEFAULTFONTSIZE) navstyle.set(0,-1,DEFAULTFONT,DEFAULTFONTSIZE) navswap=0 RefreshGadgets End Method Method Write(stream:TStream) Local i stream.WriteLine "[Options]" stream.WriteLine "showtoolbar="+showtoolbar stream.WriteLine "restoreopenfiles="+restoreopenfiles stream.WriteLine "autocapitalize="+autocapitalize stream.WriteLine "syntaxhighlight="+syntaxhighlight stream.WriteLine "autobackup="+autobackup stream.WriteLine "autoindent="+autoindent stream.WriteLine "tabsize="+tabsize stream.WriteLine "editfontname="+editfontname stream.WriteLine "editfontsize="+editfontsize stream.WriteLine "editcolor="+editcolor.ToString() stream.WriteLine "normal_style="+styles[0].ToString() stream.WriteLine "comment_style="+styles[1].ToString() stream.WriteLine "quote_style="+styles[2].ToString() stream.WriteLine "keyword_style="+styles[3].ToString() stream.WriteLine "output_style="+outputstyle.ToString() stream.WriteLine "nav_style="+navstyle.ToString() stream.WriteLine "nav_swap="+navswap stream.WriteLine "hide_output="+hideoutput stream.WriteLine "external_help="+externalhelp End Method Method Read(stream:TStream) Local f$,p,a$,b$,t While Not stream.Eof() f$=stream.ReadLine() If f$="" Or (f$[..1]="[" And f$<>"[Options]") Exit p=f.find("=") a$=f[..p] b$=f[p+1..] t=Int(b) Select a$ Case "showtoolbar" showtoolbar=t Case "restoreopenfiles" restoreopenfiles=t Case "autocapitalize" autocapitalize=t Case "syntaxhighlight" syntaxhighlight=t Case "autobackup" autobackup=t Case "autoindent" autoindent=t Case "tabsize" tabsize=t Case "editfontname" editfontname=b Case "editfontsize" editfontsize=t Case "editcolor" editcolor.FromString(b) Case "normal_style" styles[0].FromString(b) Case "comment_style" styles[1].FromString(b) Case "quote_style" styles[2].FromString(b) Case "keyword_style" styles[3].FromString(b) Case "output_style" outputstyle.FromString(b) Case "nav_style" navstyle.FromString(b) Case "nav_swap" navswap=t Case "hide_output" hideoutput=t Case "external_help" externalhelp=t End Select Wend RefreshGadgets End Method Method RefreshGadgets() Local i,rgb:TColor editfont=LoadGuiFont(editfontname,editfontsize) SetButtonState buttons[0],showtoolbar SetButtonState buttons[1],restoreopenfiles SetButtonState buttons[2],autocapitalize SetButtonState buttons[3],syntaxhighlight SetButtonState buttons[4],autobackup SetButtonState buttons[5],autoindent SetButtonState buttons[6],hideoutput SetButtonState buttons[7],externalhelp SelectGadgetItem tabbutton,Min(Max(tabsize/2-1,0),7) SetPanelColor editpanel,editcolor.red,editcolor.green,editcolor.blue SetGadgetText editbutton,editfontname+":"+editfontsize For i=0 To 3 styles[i].Refresh Next LockTextArea textarea SetTextAreaColor textarea,editcolor.red,editcolor.green,editcolor.blue,True SetGadgetFont textarea,editfont styles[0].format(textarea,0,-1) styles[1].format(textarea,0,17) styles[2].format(textarea,26,8) styles[3].format(textarea,36,5) UnlockTextArea textarea outputstyle.Refresh navstyle.Refresh SelectGadgetItem navswapbutton,Min(Max(navswap,0),1) dirty=True End Method Method Poll() Local i,font:TGUIFont,refresh For i=0 To 3 refresh=refresh|styles[i].Poll() Next refresh=refresh|outputstyle.Poll() refresh=refresh|navstyle.Poll() If EventSource()=buttons[0] showtoolbar=ButtonState(buttons[0]);dirty=True If EventSource()=buttons[1] restoreopenfiles=ButtonState(buttons[1]) If EventSource()=buttons[2] autocapitalize=ButtonState(buttons[2]);dirty=True If EventSource()=buttons[3] syntaxhighlight=ButtonState(buttons[3]);dirty=True If EventSource()=buttons[4] autobackup=ButtonState(buttons[4]) If EventSource()=buttons[5] autoindent=ButtonState(buttons[5]) If EventSource()=buttons[6] hideoutput=ButtonState(buttons[6]) If EventSource()=buttons[7] externalhelp=ButtonState(buttons[7]) Select EventSource() Case tabber SetPanelIndex SelectedGadgetItem(tabber) Case ok Hide If dirty host.RefreshAll dirty=False SnapShot Case window If EventID()=EVENT_WINDOWCLOSE Restore dirty=False Hide EndIf Case cancel Restore dirty=False Hide Case tabbutton tabsize=(SelectedGadgetItem(tabbutton)+1)*2 refresh=True Case editpanel If EventID()=EVENT_MOUSEDOWN refresh=editcolor.Request() EndIf Case editbutton font=RequestFont(editfont) If font editfontname=FontName(font) editfontsize=FontSize(font) refresh=True EndIf Case navswapbutton navswap=SelectedGadgetItem(navswapbutton) refresh=True End Select If refresh RefreshGadgets End Method Method InitOptionsRequester(host:TCodePlay) Local w:TGadget ' o=New TOptionsRequester InitPanelRequester(host,"Options",320,440) ' init values editcolor=New TColor ' init gadgets optionspanel=AddPanel("Options") editorpanel=AddPanel("Editor") toolpanel=AddPanel("Tools") w=optionspanel buttons[0]=CreateButton("Show ToolBar",10,10,280,24,w,2) buttons[1]=CreateButton("Open Files At Startup",10,34,280,24,w,2) buttons[2]=CreateButton("Auto Capitalize",10,58,280,24,w,2) buttons[3]=CreateButton("Syntax Highlighting",10,82,280,24,w,2) buttons[4]=CreateButton("Auto Backup",10,106,280,24,w,2) buttons[5]=CreateButton("Auto Indent",10,130,280,24,w,2) buttons[6]=CreateButton("Hide Output When Process Complete",10,154,280,24,w,2) buttons[7]=CreateButton("Use External Help Browser",10,178,280,24,w,2) w=editorpanel CreateLabel("Background",4,12+4,80,24,w) editpanel=CreatePanel(88,12,24,24,w,PANEL_BORDER|PANEL_ACTIVE) editbutton=CreateButton("..",116,12,180,24,w) styles=New TTextStyle[4] styles[0]=TTextStyle.Create("PlainText:",4,40,w) styles[1]=TTextStyle.Create("Remarks:",4,68,w) styles[2]=TTextStyle.Create("Strings:",4,96,w) styles[3]=TTextStyle.Create("KeyWords:",4,124,w) tabbutton=CreateComboBox(20,180,128,24,w) For Local i=1 To 8 AddGadgetItem tabbutton,"TabSize="+(i*2) Next textarea=CreateTextArea(10,220,ClientWidth(w)-20,140,w,TEXTAREA_READONLY) SetTextAreaText textarea,"' Example Listing~n~nname$=~qBlitzMax~q~nPrint name$~n" w=toolpanel outputstyle=TGadgetStyle.Create("Output",4,12,w) navstyle=TGadgetStyle.Create("Navbar",4,40,w) navswapbutton=CreateComboBox(20,66,128,24,w) AddGadgetItem navswapbutton,"Navbar on right" AddGadgetItem navswapbutton,"Navbar on left" SetDefaults() SetPanel optionspanel SnapShot End Method Function Create:TOptionsRequester(host:TCodePlay) Local o:TOptionsRequester o=New TOptionsRequester o.InitOptionsRequester host Return o End Function End Type Type TFindRequester Extends TRequester Field findterm:TGadget Method ShowFind(term$="") If term SetGadgetText(findterm,term) Super.Show() ActivateGadget findterm End Method Method Poll() Local find$,data Select EventSource() Case window If EventID()=EVENT_WINDOWCLOSE Hide EndIf Case ok find=TextFieldText(findterm) Hide PollSystem host.activepanel.Invoke TOOLFINDNEXT,find Case cancel Hide End Select End Method Function Create:TFindRequester(host:TCodePlay) Local seek:TFindRequester seek=New TFindRequester seek.initrequester(host,"Find",280,128) CreateLabel("Find What",8,16,80,24,seek.window) seek.findterm=CreateTextField(88,12,180,20,seek.window) Return seek End Function End Type Type TReplaceRequester Extends TRequester Field findterm:TGadget,replaceterm:TGadget Field findnext:TGadget,replaceit:TGadget,replaceall:TGadget Method Show() Super.Show() ActivateGadget findterm End Method Method Poll() Local find$,Replace$ Select EventSource() Case window If EventID()=EVENT_WINDOWCLOSE Hide EndIf Case ok Hide Case cancel Hide Case findnext find=TextFieldText(findterm) host.activepanel.Invoke TOOLFINDNEXT,find Case replaceit Replace=TextFieldText(replaceterm) If host.activepanel.Invoke(TOOLREPLACE,Replace) host.activepanel.Invoke TOOLFINDNEXT,find EndIf Case replaceall find=TextFieldText(findterm) Replace=TextFieldText(replaceterm) host.activepanel.Invoke TOOLREPLACE,find+Chr(0)+Replace End Select End Method Function Create:TReplaceRequester(host:TCodePlay) Local x,y Local seek:TReplaceRequester seek=New TReplaceRequester seek.initrequester(host,"Find and Replace",380,200) y=14 CreateLabel( "Find What",8,y+4,88,24,seek.window ) seek.findterm=CreateTextField( 96,y,168,20,seek.window ) y:+32 CreateLabel( "Replace With",8,y+4,88,24,seek.window ) seek.replaceterm=CreateTextField( 96,y,168,20,seek.window ) x=ClientWidth(seek.window)-104 y=12 seek.findnext=CreateButton("Find Next",x,y,96,24,seek.window) seek.replaceit=CreateButton("Replace",x,y+32,96,24,seek.window) seek.replaceall=CreateButton("Replace All",x,y+64,96,24,seek.window) Return seek End Function End Type Type TSyncModsRequester Extends TRequester Field label:TGadget,user:TGadget,password:TGadget,proxy:TGadget Field options:TGadget[] Method SyncMods() Local u$,p$,x$,cmd$,i,n u$=quote(TextFieldText(user)) p$=quote(TextFieldText(password)) x$=TextFieldText(proxy) cmd$=quote(host.bmxpath+"/bin/syncmods") cmd$:+" -u "+u$+" -p "+p$ If x cmd$:+" -y "+x n=MODOPTIONS.length For Local i=0 Until n If ButtonState(options[i]) cmd$:+" "+MODOPTIONS[i] Next Hide host.execute cmd,"Synchronize Modules"',MENUTRIGGERDOCMODS End Method Method Poll() Select EventSource() Case window If EventID()=EVENT_WINDOWCLOSE Hide EndIf Case ok SyncMods Case cancel Hide End Select End Method Method Show() Super.Show() ActivateGadget user End Method Function Create:TSyncModsRequester(host:TCodePlay) Local sync:TSyncModsRequester Local m$ m$=LoadString("incbin::syncmodsblurb.txt") sync=New TSyncModsRequester sync.initrequester(host,"Synchronize modules",420,420) ' sync.label=CreateLabel(m$,8,20,380,160,sync.window) sync.label=CreateTextArea(8,8,400,160,sync.window,TEXTAREA_READONLY|TEXTAREA_WORDWRAP) SetGadgetText sync.label,m$ Local i,n,y y=180 CreateLabel("Username",20,y+4,80,24,sync.window) sync.user=CreateTextField(108,y,160,20,sync.window) y:+30 CreateLabel("Password",20,y+4,80,24,sync.window) sync.password=CreateTextField(108,y,160,20,sync.window,TEXTFIELD_PASSWORD) y:+30 CreateLabel("Proxy Server",20,y+4,80,24,sync.window) sync.proxy=CreateTextField(108,y,160,20,sync.window) y:+30 n=MODOPTIONS.length sync.options=New TGadget[n] For Local i=0 Until n sync.options[i]=CreateButton(MODOPTIONS[i],20,y,60,24,sync.window,BUTTON_CHECKBOX) If i<2 SetButtonState sync.options[i],True DisableGadget sync.options[i] EndIf CreateLabel MODINFO[i],80,y+4,220,24,sync.window y:+26 Next Return sync End Function Function GetArg$(a$ Var) Local p,r$ p=a.Find(",")+1 If p=0 p=Len a$+1 r$=a$[..p-1] a$=a$[p..] Return r$ End Function Function Crypt$(a$) Local b$,c:Byte,i For i=0 Until Len a c=a[i] If c>63 And c<192 c:~(i*-41)&63 b:+Chr(c) Next Return b End Function Method FromString(s$) Local a$,i,n SetGadgetText user,GetArg(s$) SetGadgetText password,Crypt(GetArg(s$)) SetGadgetText proxy,GetArg(s$) n=MODOPTIONS.length While s$ a$=GetArg(s$) For Local i=2 Until n If a$=MODOPTIONS[i] SetButtonState options[i],True Next Wend End Method Method ToString$() Local sync$,i,n sync=TextFieldText(user) sync:+","+Crypt(TextFieldText(password)) sync:+","+TextFieldText(proxy) n=MODOPTIONS.length For Local i=2 Until n If ButtonState(options[i]) sync:+","+MODOPTIONS[i] Next Return sync End Method End Type Type TEventHandler Extends TTool Method OnEvent() Abstract End Type Type TSplitter Extends TEventHandler Const HORIZONTAL=0 Const VERTICAL=1 Field axis,gadget0:TGadget,gadget1:TGadget,group:TGadget Field panel:TGadget,pos,flipped,snap,oldpos,oldsize Method Position(p) Move p-pos End Method Method Move(d) Local w,h,p pos:+d w=ClientWidth(group) h=ClientHeight(group) If pos<0 pos=0 If axis=VERTICAL If pos>w-SPLITWIDTH pos=w-SPLITWIDTH If (d<0)~flipped SetGadgetShape gadget0,0,0,pos-SPLITWIDTH,h SetGadgetShape panel,pos-SPLITWIDTH,0,SPLITWIDTH*2,h SetGadgetShape gadget1,pos+SPLITWIDTH,0,w-(pos+SPLITWIDTH),h Else SetGadgetShape gadget1,pos+SPLITWIDTH,0,w-(pos+SPLITWIDTH),h SetGadgetShape panel,pos-SPLITWIDTH,0,SPLITWIDTH*2,h SetGadgetShape gadget0,0,0,pos-SPLITWIDTH,h EndIf Else If pos>h-SPLITWIDTH pos=h-SPLITWIDTH If (d<0)~flipped SetGadgetShape gadget0,0,0,w,pos-SPLITWIDTH SetGadgetShape panel,0,pos-SPLITWIDTH,w,SPLITWIDTH*2 SetGadgetShape gadget1,0,pos+SPLITWIDTH,w,h-(pos+SPLITWIDTH) Else SetGadgetShape gadget1,0,pos+SPLITWIDTH,w,h-(pos+SPLITWIDTH) SetGadgetShape panel,0,pos-SPLITWIDTH,w,SPLITWIDTH*2 SetGadgetShape gadget0,0,0,w,pos-SPLITWIDTH EndIf EndIf End Method Method Resize() If axis=VERTICAL pos=GadgetX(panel)+SPLITWIDTH If pos<0 Or pos>ClientWidth(group) move(0) Else pos=GadgetY(panel)+SPLITWIDTH If pos<0 Or pos>ClientHeight(group) move(0) EndIf End Method Method OnEvent() If EventSource()<>panel Return Select EventID() Case EVENT_MOUSEDOWN snap=True If axis oldpos=EventX() Else oldpos=EventY() EndIf Case EVENT_MOUSEENTER If axis SetPointer POINTER_SIZEWE Else SetPointer POINTER_SIZENS EndIf Case EVENT_MOUSELEAVE SetPointer POINTER_DEFAULT Case EVENT_MOUSEUP snap=False Case EVENT_MOUSEMOVE If axis SetPointer POINTER_SIZEWE Else SetPointer POINTER_SIZENS EndIf If snap If axis Move EventX()-oldpos Else Move EventY()-oldpos EndIf EndIf End Select End Method Method SetFlip(f,init=True) Local t:TGadget If f<>flipped flipped=f t=gadget0;gadget0=gadget1;gadget1=t If init If axis=VERTICAL pos=ClientWidth(group)-pos-1 Else pos=ClientHeight(group)-pos-1 EndIf EndIf EndIf If axis If flipped SetGadgetLayout gadget0,1,0,1,1 SetGadgetLayout gadget1,1,1,1,1 SetGadgetLayout panel,1,0,1,1 Else SetGadgetLayout gadget0,1,1,1,1 SetGadgetLayout gadget1,0,1,1,1 SetGadgetLayout panel,0,1,1,1 EndIf Else If flipped SetGadgetLayout gadget0,1,1,1,0 SetGadgetLayout gadget1,1,1,1,1 SetGadgetLayout panel,1,1,1,0 Else SetGadgetLayout gadget0,1,1,1,1 SetGadgetLayout gadget1,1,1,0,1 SetGadgetLayout panel,1,1,0,1 EndIf EndIf Position pos End Method Function Create:TSplitter(axis,pos,flipped,gadget0:TGadget,gadget1:TGadget) Local s:TSplitter s=New TSplitter s.axis=axis s.gadget0=gadget0 s.gadget1=gadget1 s.group=GadgetGroup(gadget0) s.panel=CreatePanel(0,0,0,0,s.group,PANEL_ACTIVE)'|PANEL_BORDER) s.pos=pos s.setflip flipped,False Return s End Function End Type Type TToolPanel Extends TEventHandler Field name$,path$ Field panel:TGadget Field index Field active Method Show() End Method End Type Type TView Field node:TGadget,state End Type Type TNode Extends TTool Const HIDESTATE=0 Const CLOSEDSTATE=1 Const OPENSTATE=2 Field name$,sortname$ Field parent:TNode Field kids:TList=New TList Field views:TView[] ' activate program Field target:TTool Field action Field argument:Object Method SortKids( ascending=True ) Local term:TLink=kids._head Repeat Local link:TLink=kids._head._succ Local sorted=True Repeat Local succ:TLink=link._succ If succ=term Exit Local cc=TNode(link._value).sortname.Compare( TNode(succ._value).sortname ) If (cc>0 And ascending) Or (cc<0 And Not ascending) Local link_pred:TLink=link._pred Local succ_succ:TLink=succ._succ link_pred._succ=succ succ._succ=link succ._pred=link_pred link._succ=succ_succ link._pred=succ succ_succ._pred=link sorted=False Else link=succ EndIf Forever If sorted Return term=link Forever End Method Method FindArgument:TNode(arg:Object) Local n:TNode,r:TNode,a$ If arg.Compare(argument)=0 Return Self a$=(String(arg)).ToLower() If a And a=(String(argument)).toLower() Return Self For n=EachIn kids r=n.FindArgument(arg) If r Return r Next End Method Method Dump(indent$="") Local n:TNode Print indent+name indent:+"~t" For n=EachIn kids n.Dump indent Next End Method Method IsHidden() Local v:TView If Not parent Return False For v=EachIn parent.views If v.state=OPENSTATE Return False Next Return True End Method Method SetAction(tool:TTool,cmd,arg:Object=Null) target=tool action=cmd argument=arg End Method Method Hide(v:TView=Null) 'null means hide in all views Local n:TNode For n=EachIn kids n.hide v Next If v If v.node FreeTreeViewNode v.node;v.node=Null Else For v=EachIn views If v.node FreeTreeViewNode v.node;v.node=Null Next EndIf End Method Method Detach() Hide If parent parent.kids.remove Self parent=Null End Method Method FreeKids() Local n:TNode For n=EachIn kids n.free Next End Method Method Free() Local n:TNode For n=EachIn kids n.free Next Detach 'Hide() views=Null End Method Method Invoke(command,arg:Object=Null) Select command Case TOOLACTIVATE If target Return target.Invoke(action,argument) End Select End Method Method Find:TNode(treeviewnode:TGadget,view=0) Local n:TNode,r:TNode Local v:TView v=getview(view) If v And v.node=treeviewnode Return Self For n=EachIn kids r=n.Find(treeviewnode,view) If r Return r Next End Method Method SetNode(treeviewnode:TGadget,view=0) Local v:TView v=getview(view) v.node=treeviewnode open view End Method Method HighLight(view=-1) Local v:TView If view=-1 For view=0 To views.length HighLight view Next Return EndIf v=GetView(view) If v.node SelectTreeViewNode v.node End Method Method Open(view=-1) Local v:TView If view=-1 For view=0 To views.length Open view Next Return EndIf v=GetView(view) If v.state<>OPENSTATE v.state=OPENSTATE RefreshView view ' if v.node ExpandTreeViewNode v.node EndIf End Method Method Close(view=0) Local v:TView v=GetView(view) If v.state<>CLOSEDSTATE v.state=CLOSEDSTATE ' if v.node CollapseTreeViewNode v.node EndIf End Method Method GetState(view=0) Local v:TView v=GetView(view) Return v.state End Method Method GetView:TView(view=0) If view>=views.length views=views[..view+1] views[view]=New TView EndIf If views[view]=Null views[view]=New TView Return views[view] End Method Method GetIndex() Local node:TNode Local i If parent For node=EachIn parent.kids If node=Self Return i i:+1 Next EndIf End Method Method Refresh() Local i For i=0 To views.length-1 RefreshView i Next End Method Method RefreshView(view=0) Local n:TNode,quick Local v:TView,vv:TView Local node If parent And parent.getstate(view)=CLOSEDSTATE quick=True v=getview(view) If v.node And parent ModifyTreeViewNode v.node,name Else If parent And name vv=parent.getview(view) If vv.node ' v.node=AddTreeViewNode(name,vv.node) v.node=InsertTreeViewNode(GetIndex(),name,vv.node) If v.state=HIDESTATE v.state=CLOSEDSTATE If vv.state=OPENSTATE ExpandTreeViewNode vv.node quick=False EndIf EndIf EndIf If quick Return If Not kids Return For n=EachIn kids n.RefreshView view Next End Method Method NodeAfter:TNode(node:TNode) Local link:TLink If node link=kids.FindLink(node) If link link=link.NextLink() If link Return TNode(link.Value()) End Method Method Sync(snap:TNode) Local snapkid:TNode Local currentkid:TNode Local kid:TNode Local t:TNode Local link:TLink If snap.name<>name Return If kids.Count() currentkid=TNode(kids.First()) For snapkid=EachIn snap.kids ' if same name in list kid=currentkid While kid If kid.name=snapkid.name Exit kid=NodeAfter(kid) Wend ' then remove entries in front If kid While currentkid<>kid t=currentkid currentkid=NodeAfter(currentkid) t.free() Wend EndIf ' if same name sync else insert If currentkid And currentkid.name=snapkid.name 'merge values if same name currentkid.Sync snapkid currentkid=NodeAfter(currentkid) Else snapkid.detach If currentkid link=kids.FindLink(currentkid) kids.InsertBeforeLink snapkid,link Else kids.AddLast snapkid EndIf snapkid.parent=Self EndIf Next ' remove any entries at end While currentkid t=currentkid currentkid=NodeAfter(currentkid) t.free() Wend Refresh() End Method Method SetName(n$) name=n End Method Method AddNode:TNode(name$) Local v:TNode v=New TNode v.setname name Append v Return v End Method Method Append(v:TNode) v.parent=Self kids.AddLast v End Method Function Create:TNode(name$) Local node:TNode node=New TNode node.setname name Return node End Function End Type Type THelpPanel Extends TToolPanel Field host:TCodePlay Field htmlview:TGadget Field root:TNode Field user:TNode Field lang:TNode Field mods:TNode Method AddLink:TNode(parent:TNode,name$,href$) Local n:TNode n=parent.AddNode(name) If href href=RealPath(href) n.SetAction(Self,TOOLNAVIGATE,href) Return n End Method Method ImportLinks(root:TNode,path$) Local stream:TStream Local c$,l$,p,q,a$,n$,cat Local node:TNode stream=ReadFile(path) If Not stream Return path=ExtractDir(path) node=root While Not Eof(stream) c=ReadLine(stream) If c="" Continue If c.Find("Alphabetic index")<>-1 node=AddLink(root,"Index","") Continue EndIf l=c.ToLower() l=l.Replace(QUOTES$,"'") p=l.Find("<a") If p=-1 Continue a$="" q=l.find("href=",p)+1 If q If l[q+4]=39 '"'" p=q+5 q=l.find("'",p) Else p=q+4 q=l.find(" ",p) EndIf If q>p a$=path+"/"+c[p..q] EndIf EndIf p=c.Find(">",q)+1 If p And c[p]=60 p=c.Find(">",p)+1 q=c.Find("<",p) If q<=p Continue n$=c[p..q] ' print n$ If l.find("onclick=toggle")<>-1 node=AddLink(root,n$,a$) Else AddLink(node,n$,a$) EndIf Wend stream.Close End Method Method SyncDocs() mods.FreeKids AddLink(mods,"Welcome",host.bmxpath+"/doc/bmxmods/welcome.html") ImportLinks mods,host.bmxpath+"/doc/bmxmods/navbar.html" mods.Refresh End Method Method BuildTree() root=host.helproot user=root.AddNode("UserGuide") ImportLinks user,host.bmxpath+"/doc/bmxuser/navbar.html" lang=root.AddNode("Language") ImportLinks lang,host.bmxpath+"/doc/bmxlang/navbar.html" mods=root.AddNode("Modules") SyncDocs AddLink root,"Samples",host.bmxpath+"/samples/index.html" root.refresh End Method Method Invoke(command,argument:Object=Null) Local href$ If Not htmlview Return Select command Case TOOLCUT GadgetCut htmlview Case TOOLCOPY GadgetCopy htmlview Case TOOLPASTE GadgetPaste htmlview Case TOOLSHOW ActivateGadget htmlview host.SetTitle Case TOOLNAVIGATE href$=String(argument) If href Go href Case TOOLPRINT GadgetPrint htmlview End Select End Method Method OnEvent() Local url$,p,t$ If EventSource()=htmlview Select EventID() Case EVENT_GADGETACTION 'NAVIGATEREQUEST url$=String( EventExtra() ) If url[..5]="http:" OpenURL url Else p=url.findlast(".") If p>-1 t$=url[p..].tolower() If t$=".bmx" If url.Find( "file://" )=0 url=url[7..] ?Win32 url=url[1..] ? EndIf url=url.replace("%20"," ") Local source:TOpenCode=host.OpenSource(url) If source source.MakePathTemp Else url=url.Replace("\","/") url=url.Replace("user/index","user/welcome") url=url.Replace("lang/index","lang/welcome") url=url.Replace("mods/index","mods/welcome") Go url$ EndIf EndIf EndIf End Select EndIf End Method Method Go(url$,internal=False) Local node:TNode If host.options.externalhelp And Not internal PollSystem OpenURL url MinimizeWindow host.window PollSystem Return EndIf HtmlViewGo htmlview,url$ host.SelectPanel Self node=host.helproot.FindArgument(RealPath(url)) If node node.Highlight Else ' print "node not found" EndIf ActivateGadget htmlview End Method Method Home() Go host.bmxpath+HOMEPAGE,True End Method Method Forward() HtmlViewForward htmlview End Method Method Back() HtmlViewBack htmlview End Method Function Create:THelpPanel(host:TCodePlay) Local p:THelpPanel Local root,style p=New THelpPanel p.host=host p.name="Help" codeplay.addpanel(p) style=HTMLVIEW_NONAVIGATE 'HTMLVIEW_NOCONTEXTMENU p.htmlview=CreateHTMLView(0,0,ClientWidth(p.panel),ClientHeight(p.panel),p.panel,style) SetGadgetLayout p.htmlview,1,1,1,1 ' p.Home p.buildtree Return p End Function End Type Type TSearchRequester Extends TRequester Field findbox:TGadget,typebox:TGadget,pathbox:TGadget,pathbutton:TGadget Method Poll() Local id,data,index id=EventID() data=EventData() Select EventSource() Case window If EventID()=EVENT_WINDOWCLOSE Hide EndIf Case ok Hide Case cancel Hide End Select End Method Function Create:TSearchRequester(host:TCodePlay) Local search:TSearchRequester search=New TSearchRequester search.initrequester(host,"Find In Files",400,256) CreateLabel("Find What",6,18,80,24,search.window) search.findbox=CreateTextField(88,14,180,20,search.window) CreateLabel("File Types",6,48,80,24,search.window) search.typebox=CreateTextField(88,44,180,20,search.window) CreateLabel("Search Path",6,78,80,24,search.window) search.pathbox=CreateTextField(88,74,180,20,search.window) Return search End Function End Type Type TProjectRequester Extends TRequester Field projects:TProjects Field listbox:TGadget,add:TGadget,remove:TGadget,props:TGadget Method Invoke(command,arg:Object=Null) Select command Case TOOLACTIVATE Refresh End Select End Method Method Poll() Local id,data,index id=EventID() data=EventData() Select EventSource() Case window If EventID()=EVENT_WINDOWCLOSE Hide EndIf Case add projects.AddProject Refresh Case remove projects.RemoveProject SelectedGadgetItem(listbox) Refresh Case ok Hide Case cancel Hide End Select End Method Method Refresh() Local node:TNode ClearGadgetItems listbox For node=EachIn projects.kids If TFolderNode(node)'node.argument AddGadgetItem listbox,node.name EndIf Next End Method Method Open(projnode:TProjects) projects=projnode Refresh Show End Method Function Create:TProjectRequester(host:TCodePlay) Local x,y Local proj:TProjectRequester proj=New TProjectRequester proj.initrequester(host,"Project Manager",400,256) proj.listbox=CreateListBox( 8,8,248,184,proj.window ) x=ClientWidth(proj.window)-136 proj.add=CreateButton("Add Project",x,8,128,24,proj.window) proj.remove=CreateButton("Remove Project",x,40,128,24,proj.window) proj.props=CreateButton("Properties",x,72,128,24,proj.window) DisableGadget proj.props Return proj End Function End Type Type TFolderNode Extends TNode Field path$ Field scanned Field owner:TNode Method Open(view=-1) If Not scanned ScanKids 'Path name,path EndIf Super.Open view End Method Method AddFileNode:TNode(file$) Local n:TNode Local ext$ If NodeFileTypes.find("|"+ExtractExt(file).toLower()+"|")<0 Return n=AddNode(StripDir(file)) n.SetAction(owner,TOOLOPEN,file) ext=ExtractExt(file$).ToLower() n.sortname=ext+n.name Return n End Method Method AddFolderNode:TNode(path$) Local n:TNode n=TFolderNode.Create(path) n.sortname=" "+n.name Append n Return n End Method Method Scan(o:TNode) Local flist:TList Local dir,f$,p$,t owner=o flist=New TList dir=ReadDir(path) If dir Repeat f$=NextFile(dir) If f$="" Exit If f[..1]="." Continue p$=path+"/"+f Select FileType(p$) Case FILETYPE_FILE AddFileNode p$ Case FILETYPE_DIR AddFolderNode p$ End Select Forever CloseDir dir EndIf SortKids End Method Method ScanKids() Local f:TFolderNode If scanned Return For f=EachIn kids f.Scan owner Next scanned=True End Method Function Create:TFolderNode(path$) Local n:TFolderNode ' print "create foldernode "+path n=New TFolderNode n.setname StripDir(path) n.path=path Return n End Function End Type Type TProjects Extends TNode Field host:TCodePlay Field addproj:TNode Method RemoveProject(index) Local node:TNode If index<0 Or index>=kids.Count() Return node=TNode(kids.ValueAtIndex(index)) If node node.Free Refresh End Method Method AddProject() Local path$,name$,stream:TStream path=RequestDir("Select the project folder") If Not path Return Add path,path ' addproj.Detach ' Append TFolderNode.Create(path) ' name=StripDir(path) ' If Not ScanPath(Self,name,path) ' If Confirm("No source files found, create "+name+".bmx?") ' stream=WriteStream(path+"/"+name+".bmx") ' If stream CloseStream stream ' ScanPath(Self,name,path) ' EndIf ' EndIf ' Append addproj ' Refresh End Method Method Add(name$,path$) Local folder:TFolderNode addproj.Detach folder=TFolderNode.Create(path) folder.Scan Self Append folder Append addproj Refresh End Method Method Write(stream:TStream) Local project:TFolderNode For project=EachIn kids stream.WriteLine "proj_node="+project.name+"|"+project.path'node.argument.ToString() Next End Method Method Invoke(command,argument:Object=Null) Select command Case TOOLNEW AddProject Case TOOLOPEN host.OpenSource String(argument) End Select End Method Function CreateProjects:TProjects(host:TCodePlay) Local p:TProjects p=New TProjects p.SetName("Projects") p.host=host p.addproj=p.AddNode("Add Project") p.addproj.SetAction p,TOOLNEW Return p End Function End Type Type TByteBuffer Extends TStream Field bytes:Byte[] Field readpointer Method Read( buf:Byte Ptr,count ) If count>readpointer count=readpointer If count=0 Return MemCopy buf,bytes,count readpointer:-count If readpointer MemMove bytes,Varptr bytes[count],readpointer Return count End Method Method Write( buf:Byte Ptr,count ) Local n,m n=readpointer+count If n>bytes.length m=Max(bytes.length*1.5,n) bytes=bytes[..m] EndIf MemCopy Varptr bytes[readpointer],buf,count readpointer=n Return count End Method Method LineAvail() Local i For i=0 Until readpointer If bytes[i]=10 Return True Next End Method Method FlushBytes:Byte[]() Local res:Byte[]=bytes[..readpointer] readpointer=0 Return res End Method End Type Type TObj Field addr$,sync,refs End Type Type TVar Extends TNode Field owner:TDebugTree Field obj:Object Method Free() If obj owner.RemoveObj obj obj=Null Super.Free() End Method Method SetVarName(n$) Local p name=n ' if object ref set addr$ field If name.find("$=")=-1 And name.find(")=$")=-1 p=name.find("=$") If p<>-1 TDebugTree.RemoveObj obj obj=TDebugTree.AddObj(name[p+2..]) EndIf p=name.find("=Null") If p<>-1 FreeKids TDebugTree.RemoveObj obj obj=Null EndIf EndIf End Method Method AddVar(name$) Local v:TVar v=New TVar v.setvarname name v.owner=owner Append v End Method Method SetValue(val:TVar) Local v:TVar,w:TVar,i ' if this is a reference to same object refresh values If obj And obj=val.obj ' sync=val.sync If kids.IsEmpty() For v=EachIn val.kids AddVar v.name Next Else For v=EachIn val.kids If i<kids.count() w=TVar(kids.ValueAtIndex(i)) If w w.SetVarName v.name Else AddVar v.name EndIf i:+1 Next EndIf Refresh EndIf ' recurse so all references are updated If IsHidden() Return 'parent And parent.state=CLOSEDSTATE Return For v=EachIn kids v.SetValue val Next End Method Method Open(view=0) owner.sync:+1 Super.Open view owner.SyncVars End Method End Type Type TScope Extends TVar Field tree:TDebugTree Field file$,line,column Method Invoke(command,argument:Object=Null) Select command Case TOOLACTIVATE tree.SelectScope Self,True End Select End Method Method SetScope(s:TScope) Local v:TVar file=s.file line=s.line column=s.column s.obj=Self SetValue s End Method Method SetFile(debugtree:TDebugTree,f$) Local p,q,r tree=debugtree p=Instr(f,"<") q=Instr(f,">") r=Instr(f,",") If p And q And r file=f[..p-1] line=Int(f[p..r-1]) column=Int(f[r..q-1]) EndIf obj=Self End Method End Type Type TDebugTree Extends TVar Global sync Global objlist:TList Field host:TCodePlay Field instack:TList Field inscope:TScope Field invar:TVar Field infile$ Field inexception$ Field firststop Field cancontinue Method Reset() host.SetMode host.DEBUGMODE SetStack New TList objlist=New TList instack=Null inscope=Null invar=Null infile="" inexception="" sync=0 firststop=True cancontinue=False End Method Function AddObj:TObj(addr$) Local o:TObj For o=EachIn objlist If o.addr=addr o.refs:+1 Return o EndIf Next o=New TObj o.addr=addr o.refs=1 objlist.addlast o Return o End Function Function FindObj:TObj(addr$) Local o:TObj For o=EachIn objlist If o.addr=addr Return o Next End Function Function RemoveObj(obj:Object) ':TObj Local o:TObj o=TObj(obj) If Not o Return o.refs:-1 If o.refs=0 objlist.Remove o EndIf End Function Method SyncVars() Local o:TObj For o=EachIn objlist If o.sync<sync o.sync=sync host.output.WritePipe "d"+o.addr EndIf Next End Method Method SetStack(list:TList) Local scope:TScope Local openscope:TScope Local s:TScope Local count,i count=kids.count() 'root.varlist.count() For scope=EachIn list If i>=count Append scope 'root.Append scope s=scope Else s=TScope(kids.ValueAtIndex(i)) ' simon was here If s.name=scope.name s.SetScope scope scope.Free Else While kids.count()>i s=TScope(kids.ValueAtIndex(i)) s.free Wend Append scope s=scope count=i+1 EndIf EndIf If firststop If host.IsSourceOpen(s.file) openscope=s Else openscope=s EndIf i:+1 Next While kids.count()>i scope=TScope(kids.ValueAtIndex(i)) scope.free Wend If list.isempty() Return If Not openscope openscope=TScope(list.First()) If openscope SelectScope openscope,True Refresh firststop=False End Method Method SelectScope(scope:TScope,open) If Not scope Return If scope.file host.DebugSource scope.file,scope.line,scope.column scope.Open ' If open ' SelectTreeViewNode scope.node ' scope.open ' EndIf End Method Method ProcessError$(line$) Local p While line[..1]=">" line=line[1..] Wend If Not line Return If line[..2]<>"~~>" Return line line=line[2..] If invar If line="}" SetValue invar 'root invar.Free invar=Null Else ' If Not invar.name ' invar.name=line ' Else invar.AddVar line ' EndIf EndIf Return EndIf If instack If line="}" sync:+1 SetStack instack instack=Null inscope=Null SyncVars If inexception Notify inexception inexception="" EndIf Return EndIf If infile If line="Local <local>" Else inscope=New TScope ' Print "inscope.line="+line inscope.name=line inscope.owner=Self instack.AddLast inscope EndIf If inscope inscope.setfile Self,infile infile="" Return EndIf If Instr(line,"@")=1 And Instr(line,"<") infile=line[1..] Else If inscope inscope.AddVar line EndIf Return EndIf If line[..20]="Unhandled Exception:" inexception=line host.output.WritePipe "t" cancontinue=False Return EndIf If line="StackTrace{" instack=New TList Return EndIf If line="Debug:" Or line="DebugStop:" host.output.WritePipe "t" cancontinue=True Return EndIf If line[..11]="ObjectDump@" p=line.find("{") If p=-1 Return line line=line[11..p] invar=New TVar ' invar.obj=AddObj(line) invar.obj=FindObj(line) 'simon come here invar.owner=Self Return EndIf End Method Function CreateDebugTree:TDebugTree(host:TCodePlay) Local d:TDebugTree objlist=New TList d=New TDebugTree d.owner=d d.SetName "Debug" d.host=host d.Open Return d End Function End Type Type TNodeView Field owner:TNavBar Field root:TNode Field treeview:TGadget Field index Method NewView() Local n:TNode,hnode:TGadget hnode=SelectedTreeViewNode(treeview) n=root.Find(hnode,index) If n And n.parent owner.AddView n End Method Method OnEvent() Local n:TNode n=root.Find(TGadget(EventExtra()),index) If Not n Return Select EventID() Case EVENT_GADGETSELECT n.invoke(TOOLSELECT) Case EVENT_GADGETACTION n.invoke(TOOLACTIVATE) Case EVENT_GADGETMENU n.invoke(TOOLMENU,Self) Case EVENT_GADGETOPEN n.open index Case EVENT_GADGETCLOSE n.close index End Select End Method End Type Type TNavBar Extends TEventHandler Field host:TCodePlay Field tabber:TGadget Field viewlist:TList=New TList Field selected:TNodeView Field navmenu:TGadget Method SelectedView() If selected Return selected.index End Method Method SelectView(index) Local n:TNodeView If index>=viewlist.count() Return n=TNodeView(viewlist.ValueAtIndex(index)) If Not n Print "selectview failed";Return If n<>selected If selected HideGadget selected.treeview selected=n EndIf ShowGadget n.treeview SelectGadgetItem tabber,index End Method Method AddView(node:TNode) Local n:TNodeView Local index,root:TGadget For n=EachIn viewlist If n.root=node SelectView n.index;Return Next n=New TNodeView n.owner=Self n.root=node n.treeview=CreateTreeView(0,0,ClientWidth(tabber),ClientHeight(tabber),tabber) host.options.navstyle.Apply n.treeview SetGadgetLayout n.treeview,1,1,1,1 HideGadget n.treeview viewlist.AddLast n n.index=viewlist.Count() AddGadgetItem tabber,node.name root=TreeViewRoot(n.treeview) node.setnode root,n.index SelectView n.index Return n.index End Method Method OnEvent() If EventSource()=tabber SelectView SelectedGadgetItem(tabber) End If If selected And EventSource()=selected.treeview selected.OnEvent EndIf End Method Method Refresh() Local view:TNodeView For view=EachIn viewlist host.options.navstyle.Apply view.treeview Next End Method Method Invoke(command,argument:Object=Null) If command=TOOLREFRESH Refresh() If command=TOOLNEWVIEW And selected selected.NewView End Method Function CreateNavMenu:TGadget() Local edit:TGadget edit=CreateMenu("&Nav",0,Null) CreateMenu "&New View",MENUNEWVIEW,edit Return edit End Function Function Create:TNavBar(host:TCodePlay) ',root:TNode) Local n:TNavBar n=New TNavBar n.host=host n.tabber=CreateTabber(0,0,1,1,host.client) ' n.AddView root n.navmenu=CreateNavMenu() Return n End Function End Type |
Comments
| ||
Oops, gets cut off. part 2: Type TOutputPanel Extends TToolPanel 'used build and run Field host:TCodePlay Field output:TGadget Field process:TProcess Field user$,cmdline$,err$,post$ Field errbuffer:TByteBuffer Field outputmenu:TGadget Method Clear() If Not output Open() SetGadgetText output,"" End Method Method Write(mess$) If Not output Open() AddTextAreaText output,mess End Method Method Execute(cmd$,mess$="",exe$="",home=True) If Not output Open() If Not mess$ mess$=cmd$ err$="" post$=exe host.SelectPanel Self host.debugtree.Reset If process And ProcessStatus(process) Delay 500 If ProcessStatus(process) Notify "Current process still busy "+cmdline Return EndIf EndIf cmd=cmd.Trim() process=CreateProcess(cmd$,HIDECONSOLE) If Not process Notify "Process Failure with "+cmd;Return If Not process.status() Notify "Process Failed to start "+cmd;Return cmdline=cmd If home Clear Write mess$+"~n" errbuffer=New TByteBuffer host.RefreshToolbar End Method Method WritePipe(l$) Local pipe:TPipeStream If Not process Return pipe=process.pipe pipe.WriteLine(l$) End Method Method Go() WritePipe "r" End Method Method StepOver() WritePipe "s" End Method Method StepIn() WritePipe "e" End Method Method StepOut() WritePipe "l" End Method Method Stop() If Not process Return process.Terminate FlushPipes process.pipe,process.err process.Close process=Null Write "~nProcess terminated~n" host.DebugExit Close End Method Method Wait() While process And process.status() PollSystem Wend End Method Method Invoke(command,argument:Object=Null) Select command Case TOOLSHOW host.SetTitle If output ActivateGadget output Case TOOLCLOSE host.RemovePanel Self output=Null Case TOOLCUT GadgetCut output Case TOOLCOPY GadgetCopy output Case TOOLPASTE GadgetPaste output Case TOOLSELECTALL If output SelectTextAreaText output Case TOOLREFRESH host.options.outputstyle.apply output End Select End Method Method Close() host.SelectPanel host.activepanel End Method Method Escape() Stop Close End Method Function outputfilter(event:TEvent,context:Object) Local out:TOutputPanel=TOutputPanel(context) If Not out Return Select event.id Case EVENT_KEYDOWN If event.data=27 out.Escape() Return 0 EndIf Case EVENT_KEYCHAR ' Print "output_keychar "+event.data out.writechar(event.data) End Select Return 1 End Function Method OnEvent() If EventSource()=output If EventID()=EVENT_GADGETMENU PopupWindowMenu host.window,outputmenu EndIf EndIf ' Case EVENT_TIMERTICK If Not process Return ReadPipes process.pipe,process.err Local status=process.status() If status=0 process.terminate FlushPipes process.pipe,process.err process.close process=Null Write "~nProcess complete~n" host.DebugExit host.SelectPanel Self If err host.ParseError err Else If post$ Local menuaction=Int(post) If menuaction host.OnMenu menuaction Else ' Execute post$,"","",False,0 EndIf Else If host.options.hideoutput Close EndIf EndIf Return EndIf End Method Method FlushPipes(pipe:TPipeStream,errpipe:TPipeStream) ReadPipes(pipe,errpipe) Local bytes:Byte[]=errbuffer.flushbytes() If bytes Local line$=String.FromBytes(bytes,Len bytes) line=line.Replace$(Chr(13),"") If line<>">" Write line EndIf End Method Method ReadPipes(pipe:TPipeStream,errpipe:TPipeStream) Local status Local bytes:Byte[],line$ bytes=pipe.ReadPipe() If bytes line$=String.FromBytes(bytes,Len bytes) line=line.Replace$(Chr(13),"") Write line EndIf ' While buffer.LineAvail() ' line$=buffer.ReadLine() ' line=host.debugtree.ProcessError(line) ' If line ' Write line+"~n" ' err:+line+"~n" ' EndIf ' Wend bytes=errpipe.ReadPipe() If bytes errbuffer.WriteBytes bytes,Len bytes ' If bytes Write String.FromBytes(bytes,bytes.length) While errbuffer.LineAvail() line$=errbuffer.ReadLine() line=host.debugtree.ProcessError(line) If line Write line+"~n" err:+line+"~n" EndIf Wend End Method Method WriteChar(char) Local pipe:TPipeStream If Not process Return pipe=process.pipe If char=3 'CTRL-C Stop() EndIf If char=13 'ENTER ' Write Chr(10) pipe.WriteLine user$ user$="" EndIf If char=8 'DELETE If Len user ' Local pos=TextAreaLen(output) ' If pos SetTextAreaText output,"",pos-1,1,TEXTAREA_CHARS user=user[..Len user-1] EndIf EndIf If char>31 ' Write Chr(char) user:+Chr(char) EndIf End Method Method Open() If output codeplay.SelectPanel Self;Return codeplay.addpanel(Self) output=CreateTextArea(0,0,ClientWidth(panel),ClientHeight(panel),panel,TEXTAREA_WORDWRAP) SetGadgetLayout output,1,1,1,1 SetGadgetFilter output,outputfilter,Self SetGadgetText output," " 'simon was here host.options.outputstyle.apply output End Method Function CreateOutputMenu:TGadget() Local edit:TGadget edit=CreateMenu("Edit",0,Null) CreateMenu "Cut",MENUCUT,edit CreateMenu "Copy",MENUCOPY,edit CreateMenu "Paste",MENUPASTE,edit CreateMenu "",0,edit CreateMenu "Stop",MENUSTOP,edit Return edit End Function Function Create:TOutputPanel(host:TCodePlay) Local o:TOutputPanel o=New TOutputPanel o.host=host o.name="Output" o.outputmenu=CreateOutputMenu() ' o.Open Return o End Function End Type Type TCodeNode Extends TNode Field owner:TOpenCode Field pos,count Method Invoke(command,argument:Object=Null) Select command Case TOOLACTIVATE owner.ShowPos(pos) End Select End Method Method Sync(snap:TNode) Local n:TCodeNode If snap.name<>name SetName(snap.name) n=TCodeNode(snap) If n pos=n.pos;count=n.count Super.Sync(snap) End Method Method SetName(n$) Local p p=n.find("'") If p<>-1 n=n[..p] name=n.Trim() End Method Method AddCodeNode:TCodeNode(n$,p0,p1) Local c:TCodeNode ' print "AddCodeNode "+n$ c=New TCodeNode c.owner=owner c.setname n$ c.pos=p0 c.count=p1-p0 Append c Return c End Method End Type Type TDiff Field pos,count,del$,add$,pos0,count0,pos1 End Type Type TOpenCode Extends TToolPanel Field host:TCodePlay Field textarea:TGadget Field dirty=True Field filesrc$,cleansrc$,cleansrcl$ Field current:TDiff Field undolist:TList=New TList Field redolist:TList=New TList Field helpcmd$,helpstring$ Field seek$ Field cursorpos,cursorlen,cursorline Field oldpos,oldlen Field isbmx,isc,iscpp,ishtml Field deferpos Field editmenu:TGadget Field codenode:TNode Field dirtynode,uc Function IsNotAlpha(c) If c<48 Return True If c>=58 And c<65 Return True If c>=91 And c<95 Return True If c>=96 And c<97 Return True If c>=123 Return True End Function Function WordAtPos$(a$,p) Local c,q,r,n ' string literal q=a.findlast(EOL$,a.length-p) If q=-1 q=0 For q=q To p-1 If a$[q]=34 n=Not n;r=q Next If n q=a.Find(Chr(34),r+1)+1 If q=0 q=a.length Return a[r..q] EndIf ' alphanumeric For p=p To 0 Step -1 If IsNotAlpha(a$[p]) Continue Exit Next For q=p-1 To 0 Step -1 If IsNotAlpha(a$[q]) Exit Next For r=p To a.length-1 If IsNotAlpha(a$[r]) Exit Next Return a$[q+1..r] End Function Function FirstDiff(s0$,s1$) Local n,i n=Min(s0.length,s1.length) For i=0 Until n If s0[i]<>s1[i] Return i Next Return n End Function Function LastDiff(s0$,s1$) Local n,i,j n=Min(s0.length,s1.length) i=s0.length-1 j=s1.length-1 While n>0 If s0[i]<>s1[j] Exit i:-1;j:-1;n:-1 Wend Return i+1 End Function Method GetNode:TNode() Local root:TCodeNode,n:TCodeNode Local src$,line,col Local p,p1,r,t,m,f,l,e ' if codenode return codenode n=New TCodeNode n.name=StripDir(path) n.owner=Self n.count=src.length root=n 'update rem,type,method,function,label pointers src=cleansrcl p1=src.length p=-1;r=-1;t=-1;m=-1;f=-1;l=-1 While p<p1 'src.length While r<=p r=FindToken("rem",src,r+1) Wend While t<=p t=FindToken("type",src,t+1) Wend While m<=p m=FindToken("method",src,m+1) Wend While f<=p f=FindToken("function",src,f+1) Wend While l<=p l=FindLabel(src,l+1) Wend If r<t And r<m And r<f And r<l p=FindEndToken("rem",src,r+1,True) Continue EndIf p=Min(t,Min(m,Min(f,l))) If p=src.length Exit While (n And n.parent And p>n.pos+n.count) n=TCodeNode(n.parent) Wend If t<m And t<f And t<l e=src.find(EOL,t) n=n.AddCodeNode(cleansrc[t..e],t,FindEndToken("type",src,t,True)) p=t+1 Continue EndIf If m<f And m<l e=src.find(EOL,m) n.AddCodeNode(cleansrc[m..e],m,e) p=m+1 Continue EndIf If f<l e=src.find(EOL,f) n.AddCodeNode(cleansrc[f..e],f,e) p=f+1 Continue Else e=src.find(EOL,l) n.AddCodeNode(cleansrc[l..e],l,e) p=l+1 Continue EndIf Wend If codenode codenode.Sync(root) root.Free Else codenode=root EndIf Return codenode End Method Method ShowPos(pos) host.SelectPanel Self SelectTextAreaText textarea,TextAreaLine(textarea,pos),0,TEXTAREA_LINES SelectTextAreaText textarea,TextAreaLine(textarea,pos),1,TEXTAREA_LINES UpdateCursor ActivateGadget textarea End Method Method Debug(line,column) SelectTextAreaText textarea,line-1,0,TEXTAREA_LINES SelectTextAreaText textarea,line-1,1,TEXTAREA_LINES End Method Method Edit() SelectTextAreaText textarea,cursorpos,0,TEXTAREA_CHARS ActivateGadget textarea UpdateStatus End Method Method UpdateStatus() Local c c=cursorpos+cursorlen If cursorline c=c-TextAreaChar(textarea,cursorline-1) host.SetStatus helpstring+"~t~t"+"Line: "+(cursorline)+" Char: "+(c+1)+" " End Method Method UpdateCursor() Local l oldpos=cursorpos oldlen=cursorlen cursorpos=TextAreaCursor(textarea,TEXTAREA_CHARS) cursorlen=TextAreaSelLen(textarea,TEXTAREA_CHARS) If cursorpos<>oldpos Or cursorlen<>oldlen l=TextAreaLine(textarea,cursorpos)+1 If l<>cursorline And dirtynode GetNode().Refresh dirtynode=False If deferpos UpdateCode 'SetCode cleansrc EndIf cursorline=l UpdateStatus() PollSystem EndIf End Method ' tdiff - pos del$ add$ Method CalcDiff:TDiff(src$) Local d:TDiff If src.length<>cleansrc.length d=New TDiff d.pos0=cursorpos d.count0=cursorlen d.pos=oldpos d.count=oldlen If cursorlen And oldlen 'block modified d.del=cleansrc[oldpos..oldpos+oldlen] d.add=src[oldpos..cursorpos+cursorlen] d.pos1=oldpos Else If cursorpos<=oldpos And cursorlen<=oldlen 'backspace d.del=cleansrc[cursorpos..cursorpos+cleansrc.length-src.length] d.pos1=cursorpos Else 'insert d.del=cleansrc[oldpos..oldpos+oldlen] d.add=src[oldpos..cursorpos+cursorlen] d.pos1=oldpos EndIf EndIf Return d EndIf If cursorpos>oldpos 'overwrite d=New TDiff d.pos0=cursorpos d.count0=cursorlen d.pos=oldpos d.count=oldlen d.del=cleansrc[oldpos..cursorpos] d.add=src[oldpos..cursorpos] d.pos1=oldpos Return d EndIf End Method Method UpdateCode(makeundo=True) Local cpos,src$ Local d:TDiff src=TextAreaText(textarea) d=CalcDiff(src) If d If makeundo undolist.AddLast d redolist.Clear EndIf SetCode src,d dirtynode=True Else If deferpos SetCode src EndIf End Method Method Undo() Local d:TDiff If undolist.isempty() Return d=TDiff(undolist.RemoveLast()) redolist.AddLast d SetTextAreaText textarea,d.del,d.pos1,d.add.length SelectTextAreaText(textarea,d.pos,d.count) SetCode TextAreaText(textarea),d UpdateCursor End Method Method Redo() Local d:TDiff If redolist.isempty() Return d=TDiff(redolist.RemoveLast()) undolist.AddLast d SetTextAreaText textarea,d.add,d.pos,d.del.length SelectTextAreaText(textarea,d.pos0,d.count0) UpdateCursor SetCode TextAreaText(textarea),d End Method Method Refresh() Local rgb:TColor Local src$ SetTextAreaTabs textarea,host.options.tabsize SetTextAreaFont textarea,host.options.editfont rgb=host.options.editcolor SetTextAreaColor textarea,rgb.red,rgb.green,rgb.blue,True rgb=host.options.styles[0].color SetTextAreaColor textarea,rgb.red,rgb.green,rgb.blue,False src=cleansrc cleansrc="" cleansrcl="" cursorpos=0 SetCode(src) End Method Function IsntAlphaNumeric(c) 'lowercase test only If c<47 Return True If c>=58 And c<95 Return True If c=96 Return True If c>=123 Return True End Function Function IsntAlphaNumericOrQuote(c) 'lowercase test only If c=34 Return False If c<47 Return True If c>=58 And c<95 Return True If c=96 Return True If c>=123 Return True End Function Function IsCode(src$,p) Local l,q,n l=src.FindLast(EOL$,src.length-p) If l=-1 l=0 q=src.Find("'",l) If q<>-1 And q<p Return q=l While q<p q=src.Find(QUOTES$,q)+1 If q=0 Exit If q<=p n:+1 Wend If n&1 Return Return True End Function Function FindLabel(src$,pos) Local p,q,c While pos>=0 p=src.Find("#",pos) If p=-1 Exit q=p While q>0 q:-1 c=src[q] If c=13 Return p If c=10 Return p If c=32 Or c=9 Continue Exit Wend If q=0 Return p pos=p+1 Wend Return src.length End Function Function FindToken(token$,src$,pos) 'lowercase src only! Local p,c,n n=token.length While pos>=0 p=src.Find(token,pos) If p=-1 Exit c=10 If p>0 c=src[p-1] If isntalphanumeric(c) If p+n<src.length c=src[p+n] If isntalphanumeric(c) If iscode(src,p) If p<4 Or src[p-4..p]<>"end " Return p EndIf EndIf EndIf pos=p+1 Wend Return src.length End Function Function FindEndToken(token$,src$,pos,returnlast=False) 'if true returns first character after endtoken Local p,q,e$,n p=pos e$="end"+token n=e.length While p<src.length p=src.Find(e$,p) If p=-1 Exit If p+n=src.length Or isntalphanumeric(src[p+n]) If iscode(src,p) If p=0 Or isntalphanumeric(src[p-1]) Exit EndIf EndIf p=p+n Wend If p=-1 p=src.length Else If returnlast p:+n q=pos e$="end "+token n=e.length While q<src.length q=src.Find(e$,q) If q=-1 Exit If q+n=src.length Or isntalphanumeric(src[q+n]) If iscode(src,q) If q=0 Or isntalphanumeric(src[q-1]) Exit EndIf EndIf q=q+n Wend If q=-1 q=src.length Else If returnlast q:+n Return Min(p,q) End Function Function IsFirstCharOnLine(src$,pos) Local i,c For i=1 To pos c=src[pos-i] If c=10 Or c=13 Return True If c>32 Return False Next Return True End Function ' rem and endrem must be first nonwhitespace on line - following funcs are for lowercase src only Function FindRem(src$,pos) While pos<src.length pos=FindToken("rem",src,pos) If pos=src.length Exit If IsFirstCharOnLine(src,pos) Return pos pos:+1 Wend Return pos End Function Function FindEndRem(src$,pos,returnlast=False) Local i,c While pos<src.length pos=FindEndToken("rem",src,pos) If pos=src.length Exit If IsFirstCharOnLine(src,pos) If returnlast If src[pos+5]=Asc("e") Or src[pos+5]=Asc("E") pos:+1 pos:+6 EndIf Return pos EndIf pos:+1 Wend Return src.length End Function Function FindPrevRem(src$,pos) 'lowercase src only! Local p,c While pos>0 If pos>src.length Exit p=src.FindLast("rem",src.length-pos) If p=-1 Exit If isntalphanumeric(src[p+3]) And IsFirstCharOnLine(src,p) Return p pos=p-1 Wend Return -1 End Function Method WasRemmed(pos,src$) Local s$,p s$=cleansrcl p=src.length-s.length If p<0 pos:-p p=FindPrevRem(s$,pos+3) If p=-1 Return p=FindEndRem(s$,p) If pos<p Return True End Method Method CheckDirty(src$) Local bool bool=True If src=filesrc And undolist.isempty() bool=False SetDirty bool End Method Method SetCode(src$,diff:TDiff=Null) Local i,p,p1,q,r,a,t$,h$,lsrc$,r0,r1,cpos,autocap Local style:TTextStyle[4],s:TTextStyle ' update dirty flag CheckDirty src If src=cleansrc And Not deferpos And Not diff Return If Not isbmx Or Not host.quickhelp Or Not host.options.syntaxhighlight cleansrc=src cleansrcl=src.ToLower() Return EndIf ' doit autocap=host.options.autocapitalize lsrc=src.ToLower() cpos=TextAreaCursor(textarea,TEXTAREA_CHARS) LockTextArea textarea style=host.options.styles ' calculate highlight region If deferpos p=deferpos p1=p deferpos=0 Else If diff p=diff.pos p1=p+diff.add.length Else p=firstdiff(src,cleansrc) p1=lastdiff(src,cleansrc) EndIf q=src.length-cleansrc.length If p1-p<q p1=p+q If p1<p p1=p EndIf ' round region to line breaks ' Print "p="+p+" p1="+p1 If p>0 p:-1 If p>src.length p=src.length p=src.findlast(EOL,src.length-p)+1 p1=src.find(EOL,p1)+1 If p1=0 p1=Len src ' if endrem between p0,p1 and next rem after p1 move p1 forwards r1=FindEndRem(lsrc,p) If r1<p1 And wasremmed(r1+6,lsrc) r0=FindRem(lsrc,r1+6) If r0>p1 p1=r0 EndIf ' if rem between p0,p1 and matching endrem after p1 move p1 forewards r0=FindPrevRem(lsrc,p1) If r0>=p And r0+3<>cpos 'defer fix r1=FindEndRem(lsrc,r0,True) If r1>p1 p1=r1 EndIf ' if rem before p0 and matching endrem after p0 highlight to endrem and move p0 forwards r0=FindPrevRem(lsrc,p) If r0<>-1 And r0<p r1=FindEndRem(lsrc,r0,True) If r1>p s=style[COMMENT] If r1>p s.Format(textarea,p,r1-p) If autocap And r1<src.length If lsrc[r1-6..r1]="endrem" And src[r1-6..r1]<>"EndRem" SetTextAreaText textarea,"EndRem",r1-6,6 If lsrc[r1-7..r1]="end rem" And src[r1-7..r1]<>"End Rem" SetTextAreaText textarea,"End Rem",r1-7,7 EndIf p=r1 EndIf EndIf ' if was remmed and now isn't move p1 down to nearest rem or endrem If WasRemmed(p,lsrc) r0=FindRem(lsrc,p) r1=FindEndRem(lsrc,r0,True) p1=Max(p1,Min(r0,r1)) EndIf ' highlight code s=style[NORMAL] If p1>p s.format(textarea,p,p1-p) While p<p1 host.UpdateProgress("Highlighting Code",(p*100)/p1) a=src[p] ' quoted strings If a=34 q=p1 r=src.find(Chr(34),p+1) If r>-1 And r<q q=r+1 r=src.find(EOL,p+1) If r>-1 And r<q q=r s=style[QUOTED] s.format(textarea,p,q-p) p=q Continue EndIf ' single line comments If a=39 q=p1 r=src.find(EOL,p+1) If r>-1 And r<q q=r s=style[COMMENT] s.format(textarea,p,q-p) p=q Continue EndIf ' tokens If (a>=65 And a<91) Or (a>=97 And a<123) Or (a=95) q=p+1 While q<p1 a=src[q] If a<46 Exit If a=47 Exit If a>=58 And a<65 Exit If a>=91 And a<95 Exit If a=96 Exit If a>122 Exit q:+1 Wend t$=src[p..q] h$=host.quickhelp.token(t$) If h$ If h$<>t$ And autocap If q<>cpos SetTextAreaText textarea,h$,p,Len h Else deferpos=q EndIf EndIf s=style[KEYWORD] If h$="Rem" And IsFirstCharOnLine(lsrc,p) ' Not (p>4 And lsrc[p-4..p]="end ") If q<>cpos q=FindEndRem(lsrc,p,True) s=style[COMMENT] Else deferpos=q EndIf EndIf s.format(textarea,p,q-p) EndIf p=q Continue EndIf p:+1 Wend UnlockTextArea textarea cleansrc=src cleansrcl=lsrc ' CheckDirty src simon was here End Method Method AutoIndent() Local t$,p,q,c,n c=TextAreaCursor(textarea,TEXTAREA_CHARS) n=TextAreaSelLen(textarea,TEXTAREA_CHARS) If c p=cleansrc.FindLast(EOL$,cleansrc.length-(c-1))+1 q=p While cleansrc[q]=9 q:+1 Wend If q>c q=c EndIf SetTextAreaText textarea,EOL$+cleansrc[p..q],c,n SelectTextAreaText textarea,c+1+q-p,0 UpdateCursor UpdateCode End Method Method IndentCode() Local cpos,p0,p1,i,a$ ' blockindent p0=TextAreaCursor(textarea,TEXTAREA_LINES) p1=TextAreaSelLen(textarea,TEXTAREA_LINES) For i=0 Until p1 a$="~t"+TextAreaText(textarea,p0+i,1,TEXTAREA_LINES) SetTextAreaText textarea,a$,p0+i,1,TEXTAREA_LINES Next SelectTextAreaText textarea,p0,p1,TEXTAREA_LINES UpdateCursor UpdateCode End Method Method OutdentCode() Local cpos,p0,p1,i,a$,modified ' blockoutdent p0=TextAreaCursor(textarea,TEXTAREA_LINES) p1=TextAreaSelLen(textarea,TEXTAREA_LINES) For i=0 Until p1 a$=TextAreaText(textarea,p0+i,1,TEXTAREA_LINES) If a[0]=9 a$=a$[1..];modified=True SetTextAreaText textarea,a$,p0+i,1,TEXTAREA_LINES Next If Not modified For i=0 Until p1 a$=TextAreaText(textarea,p0+i,1,TEXTAREA_LINES) If a[0]=32 a$=a$[1..] SetTextAreaText textarea,a$,p0+i,1,TEXTAREA_LINES Next EndIf SelectTextAreaText textarea,p0,p1,TEXTAREA_LINES UpdateCursor UpdateCode End Method Function FilterKey(event:TEvent,context:Object) Local this:TOpenCode Local id,key,mods ' If event.id<>EVENT_KEYCHAR Return 1 id=event.id key=event.data mods=event.mods this=TOpenCode(context) ?MacOS If key=25 And mods=1 key=9 ? If id=EVENT_KEYCHAR And this And key=9 And TextAreaSelLen( this.textarea,TEXTAREA_CHARS ) Select mods Case 0 this.IndentCode Case 1 this.OutdentCode End Select Return 0 EndIf If id=EVENT_KEYDOWN And this And key=13 And this.host.options.autoindent this.AutoIndent Return 0 EndIf Return 1 End Function Method OnEvent() Select EventSource() Case textarea Select EventID() Case EVENT_GADGETMENU PopupWindowMenu host.window,editmenu Case EVENT_GADGETACTION UpdateCode Case EVENT_GADGETSELECT UpdateCursor End Select End Select End Method Method SetDirty( bool ) If dirty=bool Return dirty=bool name=StripDir(path) If (dirty) name:+"*" If (host.lockedpanel=Self) name="build:"+name host.RefreshPanel Self PollSystem End Method Method SetLocked( bool ) Local locked:TOpenCode locked=TOpenCode(host.lockedpanel) If locked And locked<>Self locked.SetLocked False name=StripDir(path) If (dirty) name:+"*" If (bool) name="build:"+name host.lockedpanel=Self Else host.lockedpanel=Null EndIf host.RefreshPanel Self End Method Method Help() Local p,l$,a$ If Not host.quickhelp Return p=TextAreaCursor(textarea,TEXTAREA_CHARS) a$=WordAtPos(cleansrc,p) If a$=helpcmd l$=host.quickhelp.link(a$) If l$ host.helppanel.go host.bmxpath+l$ EndIf Else helpcmd=a$ helpstring$=host.quickhelp.help(a$) UpdateStatus 'host.setstatus helpstring$ EndIf End Method Method Find() Local p,l$,a$ p=TextAreaCursor(textarea,TEXTAREA_CHARS) a$=WordAtPos(cleansrc,p) host.findreq.ShowFind a$ End Method Method FindNext(s$) Local p,l$ If s seek=s Else s=seek p=TextAreaCursor(textarea,TEXTAREA_CHARS) p:+TextAreaSelLen(textarea,TEXTAREA_CHARS) ' case insensitive l$=s.toLower() p=cleansrcl.Find(l$,p) If p=-1 p=cleansrcl.Find(l$) ' case sensitive ' p=cleansrc.Find(s$,p+1) ' if p=-1 p=cleansrc.Find(s$) If p=-1 Notify "Could not find "+s$ Return False Else SelectTextAreaText textarea,p,Len s,TEXTAREA_CHARS UpdateCursor Return True EndIf End Method Method ReplaceAll(s$,r$) Local p,c,l$,src$ LockTextArea textarea c=TextAreaCursor(textarea,TEXTAREA_CHARS) s$=s.toLower() While True src=TextAreaText(textarea) l=src.ToLower() p=l.Find(s$,p) If p=-1 Exit SelectTextAreaText textarea,p,s.length UpdateCursor UpdateCode SetTextAreaText textarea,r,p,s.length If p<c c=c+r.length-s.length p=p+r.length SelectTextAreaText textarea,p,0 UpdateCursor UpdateCode Wend SelectTextAreaText textarea,c,0 UpdateCursor UnlockTextArea textarea End Method Method FindReplace(r$) Local p,n,f$,x$ p=r.Find(Chr(0)) If p>0 f$=r[..p] r$=r[p+1..] ReplaceAll f$,r$ Else p=TextAreaCursor(textarea,TEXTAREA_CHARS) n=TextAreaSelLen(textarea,TEXTAREA_CHARS) If n=0 Return SetTextAreaText textarea,r$,p,n SelectTextAreaText textarea,p+Len r,0 UpdateCursor UpdateCode EndIf Return True End Method Method ReadSource(path$) Local src$ src=LoadText(path) src=src.Replace(Chr(13),"") src=src.Replace(Chr(11),"") LockTextArea textarea SetTextAreaText textarea,src UnlockTextArea textarea filesrc=TextAreaText(textarea) cleansrc="" cleansrcl="" ActivateGadget textarea End Method Method SaveSource(file$) Local src$ If host.options.autobackup DeleteFile file+".bak" RenameFile file,file+".bak" EndIf src=TextAreaText(textarea) filesrc=src src=src.Replace$(Chr(13),Chr(10)) src=src.Replace$(Chr(11),"") Local txt$=src.Replace$(Chr(10),Chr(13)+Chr(10)) SaveText txt,file path=host.FullPath$(file) dirty=True SetDirty False host.AddRecent(path$) Return True End Method Method BuildSource(quick,debug,gui,run) Local cmd$,out$,arg$ If isbmx Or isc Or iscpp cmd$=quote(host.bmkpath) cmd$:+" makeapp" If run cmd$:+" -x" If debug cmd$:+" -d" Else cmd$:+" -r" '-v If gui cmd$:+" -t gui" If Not quick cmd$:+" -a" If debug out$=StripExt(host.FullPath(path))+".debug" cmd$:+" -o "+quote(out$)+" " 'QUOTES+out$+QUOTES+" " EndIf cmd$:+" "+quote(host.FullPath(path)) If run arg$=host.GetCommandLine() If arg cmd$:+" "+arg EndIf host.execute cmd,"Building "+StripExt(StripDir(path)) ',exe$ Else If ishtml host.helppanel.Go "file://"+path Else 'see what the system shell thinks of the file Local cd$=CurrentDir() ChangeDir ExtractDir(path) cmd=StripDir(path) host.execute cmd,"Building "+cmd ChangeDir cd EndIf EndIf ' print cmd End Method Method Save() Local file$ file=path If host.IsTempPath(path) file=RequestFile("Save As",FILTERS,True,"") If file="" Return False If ExtractExt(file)="" file=file+".bmx" dirty=True EndIf If dirty SaveSource(file) Return True End Method ' common command interface Method Invoke(command,argument:Object=Null) Local file$,ex$ Local p,res Select command Case TOOLSHOW host.SetCodeNode GetNode() host.SetTitle path If textarea Edit Case TOOLCLOSE If dirty p=Proceed("Save changes to "+name) 'the current file? If p=-1 Return True If p=1 If Not Save() Return True EndIf EndIf If codenode codenode.detach;codenode=Null host.RemovePanel Self Case TOOLSAVE Save Case TOOLQUICKSAVE file=path If dirty SaveSource(file) Case TOOLSAVEAS file=path If host.IsTempPath(path) file$="" file=RequestFile("Save As",FILTERS,True,file) If file="" Return ex$=ExtractExt(file) If ex$="" file=file+".bmx" isbmx=True Else isbmx=(ex.ToLower()="bmx") ishtml=(ex.ToLower()="html") isc=(ex.ToLower()="c") iscpp=(ex.ToLower()="cpp" Or ex.ToLower()="cxx") EndIf SaveSource(file$) Refresh GetNode().Refresh setdirty False host.SetTitle path Case TOOLGOTO Local line=Int(String(argument)) SelectTextAreaText textarea,line-1,0,TEXTAREA_LINES UpdateCursor ActivateGadget textarea Case TOOLFIND Find Case TOOLFINDNEXT res=FindNext(String(argument)) ' ActivateGadget textarea Return res Case TOOLREPLACE Return FindReplace(String(argument)) Case TOOLBUILD BuildSource host.quickenabled,host.debugenabled,host.guienabled,False Case TOOLRUN BuildSource host.quickenabled,host.debugenabled,host.guienabled,True Case TOOLLOCK SetLocked True Case TOOLUNLOCK SetLocked False Case TOOLHELP Help Case TOOLUNDO Undo Case TOOLREDO Redo Case TOOLREFRESH Refresh Case TOOLCUT GadgetCut textarea Case TOOLCOPY GadgetCopy textarea Case TOOLPASTE GadgetPaste textarea Case TOOLSELECTALL SelectTextAreaText textarea Case TOOLINDENT IndentCode Case TOOLOUTDENT OutdentCode Case TOOLPRINT GadgetPrint textarea End Select End Method Function CreateEditMenu:TGadget() Local edit:TGadget edit=CreateMenu("&Edit",0,Null) CreateMenu "Quick Help",MENUQUICKHELP,edit CreateMenu "",0,edit CreateMenu "Cut",MENUCUT,edit CreateMenu "Copy",MENUCOPY,edit CreateMenu "Paste",MENUPASTE,edit CreateMenu "",0,edit CreateMenu "Select All",MENUSELECTALL,edit CreateMenu "",0,edit CreateMenu "Block Indent",MENUINDENT,edit CreateMenu "Block Outdent",MENUOUTDENT,edit CreateMenu "",0,edit CreateMenu "Find",MENUFIND,edit CreateMenu "Find Next",MENUFINDNEXT,edit CreateMenu "Replace",MENUREPLACE,edit CreateMenu "Goto Line",MENUGOTO,edit Return edit End Function Method MakePathTemp() ' prepends "." to file name with code borrowed from SaveAs Local file$=ExtractDir(path)+"/."+StripDir(path) SaveSource(file$) ' Refresh GetNode().Refresh ' setdirty False host.SetTitle path End Method Function Create:TOpenCode(path$,host:TCodePlay) Local code:TOpenCode Local stream:TStream Local isnew If path stream=ReadFile(path) If Not stream ' Notify "Open could not read from "+path Return Null EndIf CloseFile stream Else TEMPCOUNT:+1 path=host.bmxpath+"/tmp/untitled"+TEMPCOUNT+".bmx" isnew=True EndIf code=New TOpenCode code.host=host code.active=True code.path=host.FullPath(path) code.editmenu=CreateEditMenu() codeplay.addpanel(code) code.textarea=CreateTextArea(0,0,ClientWidth(code.panel),ClientHeight(code.panel),code.panel,0) SetGadgetFilter code.textarea,code.FilterKey,code SetTextAreaText code.textarea,"~n" SetGadgetLayout code.textarea,1,1,1,1 code.Refresh() If isnew code.SaveSource path code.filesrc="~n" ActivateGadget code.textarea Else host.UpdateProgress "Reading Stream" code.ReadSource(path) EndIf If ExtractExt(path).toLower()="bmx" code.isbmx=True If ExtractExt(path).toLower()="c" code.isc=True If ExtractExt(path).toLower()="cpp" code.iscpp=True If ExtractExt(path).toLower()="cxx" code.iscpp=True If ExtractExt(path).toLower()="html" code.ishtml=True If ExtractExt(path).toLower()="htm" code.ishtml=True code.UpdateCode False code.filesrc=TextAreaText(code.textarea) Return code End Function End Type Type TRect Field x,y,w,h Method Set(xpos,ypos,width,height) x=xpos;y=ypos;w=width;h=height End Method Method ToString$() Return ""+x+","+y+","+w+","+h End Method Method FromString(s$) Local p,q,r p=s.Find(",")+1;If Not p Return q=s.Find(",",p)+1;If Not q Return r=s.Find(",",q)+1;If Not r Return x=Int(s[..p-1]) y=Int(s[p..q-1]) w=Int(s[q..r-1]) h=Int(s[r..]) End Method Method IsOutside(tx,ty,tw,th) If x+w<=tx Or y+h<=ty Return True If x>=tx+tw Or y>=ty+th Return True End Method End Type Type TCodePlay Const EDITMODE=1 Const DEBUGMODE=2 Field bmxpath$,bmkpath$ Field panels:TToolPanel[] Field helppanel:THelpPanel Field currentpanel:TToolPanel Field output:TOutputPanel Field lockedpanel:TToolPanel Field activepanel:TToolPanel Field cmdlinereq:TCmdLineRequester Field cmdline$ Field syncmodsreq:TSyncModsRequester Field gotoreq:TGotoRequester Field findreq:TFindRequester Field replacereq:TReplaceRequester Field options:TOptionsRequester ' Field progress:TProgressRequester Field activerequester:TRequester Field projectreq:TProjectRequester Field searchreq:TSearchRequester Field eventhandlers:TList=New TList Field window:TGadget,menubar:TGadget,toolbar:TGadget,client:TGadget,tabbar:TGadget Field split:TSplitter Field debugtree:TDebugTree Field root:TNode Field helproot:TNode Field projects:TProjects Field coderoot:TNode Field navbar:TNavBar Field mode Field debugcode:TOpenCode Field quickenable:TGadget,quickenabled 'menu,state Field debugenable:TGadget,debugenabled 'menu,state Field guienable:TGadget,guienabled 'menu,state Field quickhelp:TQuickHelp Field running Field recentmenu:TGadget Field recentfiles:TList=New TList Field recentmenus:TGadget[] Field openlist:TList=New TList Field openlock$ Field projlist:TList=New TList Field winsize:TRect=New TRect Field winmax,tooly,splitpos,debugview,navtab Field progress Method CheckVersion$() Local process:TProcess Local bytes:Byte[] Local cmd$,version$ cmd$=bmxpath+"/bin/bcc" ?win32 cmd:+".exe" ? cmd=Quote(cmd) process=CreateProcess(cmd$,HIDECONSOLE) If process While True bytes=process.pipe.ReadPipe() If bytes version:+String.FromBytes(bytes,Len bytes) EndIf If Not process.status() Exit Delay 10 Wend EndIf If version="" Notify "Unable to locate required files.~n~nPlease reinstall BlitzMax to repair this problem." End EndIf BCC_VERSION=version.Trim() ' print "bcc version="+version If version.find("(expired)")>-1 'Demo timed out Notify "This demo version of BlitzMax has expired.~n~nPlease visit www.blitzbasic.com to buy the full version." End EndIf If version.find("Demo Version")>-1 'Demo timed out is_demo=True Notify version+"~nTo purchase the full version please visit www.blitzbasic.com." Notify ABOUTDEMO EndIf End Method Method OpenProgress(message$) ' progress.Open message DisableGadget window SetStatus message progress=-1 End Method Method CloseProgress() ' progress.Hide SetStatus "" EnableGadget window progress=0 End Method Method UpdateProgress(message$,value=0) 'returns false if cancelled ' Return progress.Update(message,value) If progress If progress/5<>value/5 SetStatus message+" "+value+"%" progress=value ' Pollsystem EndIf EndIf End Method Method FullPath$(path$) If path[..8]="$BMXPATH" path=bmxpath+path[8..] path=RealPath(path) ?win32 path=path.Replace("\","/") ? Return path End Method Method IsTempPath(path$) If path[..Len bmxpath+5]=bmxpath+"/tmp/" Return True End Method Method ReadConfig() Local stream:TStream Local f$,p,a$,b$ ' defaults Local wh=GadgetHeight(Desktop())-80'32 Local ww=wh Local wx=(GadgetWidth(Desktop())-ww)/2 Local wy=(GadgetHeight(Desktop())-wh)/2 winsize.set( wx,wy,ww,wh ) quickenabled=False debugenabled=True guienabled=True splitpos=ww-200 ' read ini stream=ReadFile(bmxpath+"/cfg/ide.ini") If Not stream projlist.AddLast "samples|samples" projlist.AddLast "brl.mod|mod/brl.mod" projlist.AddLast "pub.mod|mod/pub.mod" projlist.AddLast "src|src" Return EndIf options.read(stream) options.Snapshot While Not stream.Eof() f$=stream.ReadLine() p=f.find("=") If p=-1 Continue a$=f[..p] b$=f[p+1..] Select a$ Case "ide_version" Case "file_recent" recentfiles.addlast b$ Case "file_open" openlist.addlast b$ Case "prg_quick" quickenabled=Int(b$) Case "prg_debug" debugenabled=Int(b$) Case "prg_gui" guienabled=Int(b$) Case "cmd_line" cmdline=b$ Case "prg_locked" openlock=b$ Case "win_size" winsize.FromString(b$) Case "win_max" winmax=Int(b$) Case "split_pos" splitpos=Int(b$) Case "proj_node" projlist.AddLast b$ Case "sync_state" syncmodsreq.FromString b$ End Select Wend stream.close End Method Method WriteConfig() Local panel:TToolPanel Local stream:TStream Local node:TNode Local f$ stream=WriteFile(bmxpath+"/cfg/ide.ini") If Not stream Return ' options options.write(stream) ' defaults stream.WriteLine "[Defaults]" stream.WriteLine "ide_version="+IDE_VERSION$ stream.WriteLine "prg_quick="+quickenabled stream.WriteLine "prg_debug="+debugenabled stream.WriteLine "prg_gui="+guienabled stream.WriteLine "win_size="+winsize.ToString() stream.WriteLine "win_max="+winmax stream.WriteLine "split_pos="+split.pos stream.WriteLine "cmd_line="+cmdline stream.WriteLine "sync_state="+syncmodsreq.ToString() If lockedpanel stream.WriteLine "prg_locked="+lockedpanel.path For f$=EachIn recentfiles stream.WriteLine "file_recent="+f$ Next For panel=EachIn panels f$=panel.path If f$ And Not IsTempPath(f$) stream.WriteLine "file_open="+f$ Next projects.write(stream) stream.close End Method Method CloseAll(dontask) 'returns true if successful Local panel:TToolPanel Local mypanels:TToolPanel[] Local cancel,count For panel=EachIn panels If TOpenCode(panel) count=count+1 Next If count=0 dontask=True If dontask Or Confirm("MaxIDE needs to close all documents before continuing") mypanels=panels For panel=EachIn mypanels If panel.invoke(TOOLCLOSE) cancel=True Next Return Not cancel EndIf End Method Method Quit() WriteConfig If CloseAll(True) running=False End Method Method DebugExit() If debugcode debugcode.Edit 'restore cursor etc. debugcode=Null EndIf SetMode EDITMODE End Method Method DebugSource(path$,line,column) Local code:TOpenCode path=FullPath(path) code=OpenSource(path) If code=Null Notify("Failed to Open "+path) Return EndIf If debugcode And debugcode<>code debugcode.Edit 'restore cusor etc. debugcode=code debugcode.debug(line,column) ActivateWindow window PollSystem End Method Method SetMode(m) If mode=m Return ActivateWindow window Select m Case DEBUGMODE navtab=navbar.SelectedView() navbar.SelectView debugview Case EDITMODE navbar.SelectView navtab End Select mode=m RefreshToolbar End Method Method RefreshToolbar() Local i ' sourceedit buttons If THelpPanel(CurrentPanel) DisableGadgetItem toolbar,2 Else EnableGadgetItem toolbar,2 EndIf If TOpenCode(CurrentPanel) EnableGadgetItem toolbar,3 For i=5 To 8 EnableGadgetItem toolbar,i Next Else DisableGadgetItem toolbar,3 For i=5 To 8 DisableGadgetItem toolbar,i Next EndIf ' debug buttons If mode=DEBUGMODE And debugtree.cancontinue For i=12 To 14 EnableGadgetItem toolbar,i Next Else For i=12 To 14 DisableGadgetItem toolbar,i Next EndIf ' stop button If output And output.process EnableGadgetItem toolbar,15 Else DisableGadgetItem toolbar,15 EndIf End Method Method IsSourceOpen(path$) Local panel:TToolPanel Local p$ p$=FullPath(path) For panel=EachIn panels If panel.path=p Return True Next End Method Method OpenSource:TOpenCode(path$) Local code:TOpenCode Local panel:TToolPanel Local ext$,p$ If path$="." path$=RequestFile("Open File",FILTERS ) If path$="" Return EndIf ' check if already open p$=FullPath(path).ToLower() For panel=EachIn panels If panel.path.ToLower()=p SelectPanel panel Return TOpenCode(panel) EndIf Next ' open based on extension ' Select ExtractExt(Upper(path$)) ' Case "BMX","TXT","BB","CPP","C","S","I","H","HTML","CSS","BAT","FS","VS","README","" OpenProgress "Loading "+StripDir(path) code=TOpenCode.Create(path,Self) If code AddRecent code.path ' opencoderoot.Append code.GetNode() ' opencoderoot.Refresh ' opencoderoot.Open EndIf CloseProgress If code ActivateGadget code.textarea code.GetNode().Refresh EndIf Return code ' end select End Method Method AddRecent(path$) Local f$ For f$=EachIn recentfiles If f$=path$ recentfiles.Remove(f$);Exit Next recentfiles.AddFirst(path$) RefreshRecentFiles UpdateWindowMenu window End Method Method RefreshRecentFiles() Local n,f$ Local m:TGadget For m=EachIn recentmenus FreeMenu m Next n=Min(recentfiles.count(),16) recentmenus=New TGadget[n] n=0 For f$=EachIn recentfiles recentmenus[n]=CreateMenu(f$,MENURECENT+n,recentmenu) n:+1 If n=16 Exit Next End Method Method BuildModules(buildall) Local cmd$,out$,exe$ output.stop SaveAll cmd$=quote(bmkpath) cmd$:+" makemods " ' If debugenabled cmd$:+"-d " Else cmd$:+"-r " If buildall cmd$:+"-a " Execute cmd,"Building Modules" End Method Method ImportBB() Local f$,cmd$,path$ f$=RequestFile("Import .bb File","bb" ) If Not f$ Return cmd$=quote(bmkpath$) cmd$:+" convertbb " cmd$:+quote(FullPath(f$)) Execute cmd,"Converting "+StripExt(StripDir(f$)) output.wait OpenSource(StripExt(f$)+".bmx") End Method Method GetCommandLine$() Return cmdline End Method Method SetCommandLine(text$) cmdline=text End Method Method SetStatus(text$) SetStatusText window,text End Method Method Execute(cmd$,mess$="",post$="",home=True) If Not output output=TOutputPanel.Create(Self) output.execute cmd$,mess$,post$,home End Method Method SelectError(path$,column,line) Local panel:TToolPanel,found For panel=EachIn panels If panel.path=path found=True;Exit Next If Not found panel=OpenSource(path) If panel SelectPanel panel panel.Invoke TOOLGOTO,String(line) EndIf End Method Method ParseError(err$) Local mess$,file$,p,q Local line,column ' bcc error If err$[..13]="Compile Error" err=err[14..] p=err.find(EOL$) If p=-1 p=Len err mess=err[..p] err=err[p+1..] If err[..1]="[" p=err.find("]") If p=-1 p=Len err file$=err[1..p] p=file.find(";")+1 If p=0 p=Len err q=file.find(";",p)+1 If q=0 q=Len err line=Int(file[p..q-1]) column=Int(file[q..]) file=FullPath(file[..p-1]) SelectError file,column,line EndIf Notify "Compile Error"+EOL+mess SetStatus mess Return EndIf ' gcc error err=err.Replace(EOL+" "," ") While err p=err.find(EOL) If p=-1 p=(Len err)-1 mess=err[..p] err=err[p+1..] p=0 While True p=mess.Find(":",p)+1 If p=0 Exit q=mess.Find(":",p) If q<>-1 file=mess[..p-1] line=Int(mess[p..q]) If line mess=mess[q+1..] SelectError file,column,line Notify "Compile Error"+EOL+mess Return EndIf p=q+1 EndIf Wend Wend End Method Method AddPanel(tabpanel:TToolPanel) Local panel:TGadget,index index=CountGadgetItems(tabbar) If panels.length<=index panels=panels[..index+1] AddGadgetItem(tabbar,tabpanel.name$,True) panel=CreatePanel(0,0,ClientWidth(tabbar),ClientHeight(tabbar),tabbar,0) 'name SetGadgetLayout panel,1,1,1,1 tabpanel.panel=panel tabpanel.index=index panels[index]=tabpanel SelectPanel tabpanel eventhandlers.addlast tabpanel End Method Method AddHandler(handler:TEventHandler) eventhandlers.addlast handler End Method Method RemovePanel(tabpanel:TToolPanel) Local p:TToolPanel[] Local index eventhandlers.remove tabpanel ' unset debugcode If debugcode=tabpanel debugcode=Null ' activate next panel If tabpanel=activepanel activepanel=helppanel If tabpanel=lockedpanel lockedpanel=Null If tabpanel=currentpanel index=tabpanel.index+1 If index>=panels.length index=panels.length-2 SelectPanel panels[index] EndIf ' remove from array p=panels panels=panels[..panels.length-1] For index=tabpanel.index To panels.length-1 panels[index]=p[index+1] panels[index].index=index Next ' remove gadget - simon come here, placing before remove needs fix in fltk FreeGadget tabpanel.panel RemoveGadgetItem tabbar,tabpanel.index tabpanel.panel=Null End Method Method SetRequester(req:TRequester) activerequester=req End Method Method SetTitle(title$="") If title title=" - "+title SetGadgetText window,"MaxIDE"+title End Method Method SelectPanel(panel:TToolPanel) Local current:TToolPanel current=currentpanel currentpanel=panel If current And current<>currentpanel SelectGadgetItem tabbar,panel.index ShowGadget panel.panel If panel.active activepanel=panel HideGadget current.panel RefreshToolbar EndIf currentpanel.Invoke TOOLSHOW End Method Method RefreshPanel(panel:TToolPanel) 'call after a name change ModifyGadgetItem( tabbar,panel.index,panel.name ) End Method Function OutsideDesktop(winrect:TRect) Local desk:TGadget,x,y,w,h desk=Desktop() x=GadgetX(desk) y=GadgetY(desk) w=GadgetWidth(desk) h=GadgetHeight(desk) Return winrect.IsOutside(x,y,w,h) End Function Method SetCodeNode(code:TNode) Local node:TNode If coderoot.kids.count() node=TNode(coderoot.kids.First()) If node=code Return If node node.Detach If code coderoot.Append code coderoot.Refresh coderoot.Open code.Open EndIf End Method Method Initialize() Local open:TOpenCode Local i,dir$,nomods,pname$,p Local stream:TStream Try bmxpath=BlitzMaxPath() Catch err$ Notify "Could not find BlitzMax compiler (bin/bcc), please Reinstall~nappdir="+AppDir End EndTry CreateDir BlitzMaxPath()+"/tmp" bmkpath=bmxpath+"/bin/bmk" ?win32 bmkpath:+".exe" ? dir$=bmxpath+"/mod" If FileType(dir)=0 If Not CreateDir(dir) Notify "Failed to Create Module Directory "+dir End EndIf nomods=True EndIf dir$=bmxpath+"/tmp" If FileType(dir)=0 If Not CreateDir(dir) Notify "Failed to Create Temp Directory "+dir End EndIf EndIf dir$=bmxpath+"/cfg" If FileType(dir)=0 If Not CreateDir(dir) Notify "Failed to Create Config Directory "+dir End EndIf EndIf cmdlinereq=TCmdLineRequester.Create(Self) syncmodsreq=TSyncModsRequester.Create(Self) gotoreq=TGotoRequester.Create(Self) findreq=TFindRequester.Create(Self) replacereq=TReplaceRequester.Create(Self) options=TOptionsRequester.Create(Self) ' progress=TProgressRequester.Create(Self) projectreq=TProjectRequester.Create(Self) searchreq=TSearchRequester.Create(Self) ReadConfig If OutsideDesktop(winsize) winsize.set(20,20,760,540) EndIf window=CreateWindow("MaxIDE",winsize.x,winsize.y,winsize.w,winsize.h,Null,15|WINDOW_HIDDEN|WINDOW_ACCEPTFILES) If winmax MaximizeWindow(window) toolbar=CreateToolBar("incbin::icons.PNG",0,0,0,0,window ) SetToolBarTips toolbar,["New","Open","Close","Save","","Cut","Copy","Paste","Find","","Build","Build And Run","Step","Step In","Step Out","Stop" ,"","Home","Back","Forward" ] ' InsertToolBarSeparator toolbar,5 If options.showtoolbar tooly=GadgetHeight(toolbar) Else HideGadget toolbar tooly=0 EndIf ?MacOS client=window ' cludge for window growing from adding of toolbar If Not winmax SetGadgetShape window,winsize.x,winsize.y,winsize.w,winsize.h ? If Not client client=CreatePanel(0,tooly,ClientWidth(window),ClientHeight(window)-tooly,window,4) SetGadgetLayout client,1,1,1,1 EndIf tabbar=CreateTabber(0,0,0,0,client) 'clientwidth(window),clientheight(window)-tooly,window,0) debugtree=TDebugTree.CreateDebugTree(Self) root=TNode.Create("Home") helproot=root.AddNode("Help") helproot.Open projects=TProjects.CreateProjects(Self) root.Append projects projects.Open ' opencoderoot=root.AddNode("Open") coderoot=TNode.Create("Code") 'root.AddNode("Open") coderoot.Open navbar=TNavBar.Create(Self) navbar.AddView root navbar.AddView coderoot debugview=navbar.AddView(debugtree) navbar.SelectView 0 split=TSplitter.Create(TSplitter.VERTICAL,splitpos,options.navswap,tabbar,navbar.tabber) 'treeview) AddHandler navbar AddHandler split SetMode EDITMODE CreateTimer(10) quickhelp=TQuickHelp.LoadCommandsTxt(bmxpath) helppanel=THelpPanel.Create(Self) output=TOutputPanel.Create(Self) activepanel=helppanel InitMenu InitHotkeys ShowGadget window RefreshAll PollSystem 'allow repaint helppanel.Home ' open files from .ini restorelist If options.restoreopenfiles For Local f$=EachIn openlist open=OpenSource(f$) If open And f$=openlock open.SetLocked(True) Next EndIf ' open files specified in command line For i=1 To AppArgs.length-1 open=OpenSource(AppArgs[i]) Next ' scan projects in projlist For pname$=EachIn projlist p=pname.Find("|") If p<>-1 projects.Add pname[..p],pname[p+1..] EndIf Next ' RefreshAll ' showgadget window PollSystem running=True CheckVersion If nomods syncmodsreq.Show End Method Method DocMods() Local cmd$ cmd$=quote(bmxpath+"/bin/docmods") execute cmd,"Document Modules",MENUTRIGGERSYNCDOCS End Method Method SyncDocs() helppanel.SyncDocs() quickhelp=TQuickHelp.LoadCommandsTxt(bmxpath) End Method Method InitMenu() Local menu:TGadget,file:TGadget,edit:TGadget,program:TGadget,tools:TGadget Local help:TGadget,options:TGadget Local buildmods:TGadget,buildallmods:TGadget,syncmods:TGadget,docmods:TGadget Const MENUMOD=MODIFIER_COMMAND menu=WindowMenu(window) file=CreateMenu("&File",0,menu) CreateMenu "&New",MENUNEW,file,KEY_N,MENUMOD CreateMenu "&Open...",MENUOPEN,file,KEY_O,MENUMOD recentmenu=CreateMenu("Open &Recent",0,file) CreateMenu "&Close",MENUCLOSE,file,KEY_W,MENUMOD CreateMenu "Close All",MENUCLOSEALL,file,KEY_W,MENUMOD|MODIFIER_SHIFT CreateMenu "",0,file CreateMenu "&Save",MENUSAVE,file,KEY_S,MENUMOD CreateMenu "Save &As",MENUSAVEAS,file,KEY_S,MENUMOD|MODIFIER_SHIFT CreateMenu "Save A&ll",MENUSAVEALL,file CreateMenu "",0,file ?MacOS CreateMenu "&Next File",MENUNEXT,file,KEY_RIGHT,MENUMOD CreateMenu "&Previous File",MENUPREV,file,KEY_LEFT,MENUMOD ?Win32 CreateMenu "&Next File",MENUNEXT,file,KEY_RIGHT,MENUMOD CreateMenu "&Previous File",MENUPREV,file,KEY_LEFT,MENUMOD ?Linux CreateMenu "&Next File",MENUNEXT,file,KEY_RIGHT,MODIFIER_ALT CreateMenu "&Previous File",MENUPREV,file,KEY_LEFT,MODIFIER_ALT ? CreateMenu "",0,file CreateMenu "IDE Options...",MENUOPTIONS,file CreateMenu "&Project Manager...",MENUPROJECTMANAGER,file CreateMenu "&Import BB Project...",MENUIMPORTBB,file CreateMenu "",0,file CreateMenu "Print...",MENUPRINT,file ?Win32 CreateMenu "",0,file CreateMenu "E&xit",MENUQUIT,file ?Linux CreateMenu "",0,file CreateMenu "E&xit",MENUQUIT,file ? edit=CreateMenu("&Edit",0,menu) CreateMenu "&Undo",MENUUNDO,edit,KEY_Z,MENUMOD ?MacOS CreateMenu "&Redo",MENUREDO,edit,KEY_Z,MENUMOD|MODIFIER_SHIFT ?Win32 CreateMenu "&Redo",MENUREDO,edit,KEY_Y,MENUMOD ?Linux CreateMenu "&Redo",MENUREDO,edit,KEY_Y,MENUMOD ? CreateMenu "",0,edit CreateMenu "Cu&t",MENUCUT,edit,KEY_X,MENUMOD CreateMenu "&Copy",MENUCOPY,edit,KEY_C,MENUMOD CreateMenu "&Paste",MENUPASTE,edit,KEY_V,MENUMOD CreateMenu "",0,edit CreateMenu "Select &All",MENUSELECTALL,edit,KEY_A,MENUMOD CreateMenu "",0,edit CreateMenu "Block Indent",MENUINDENT,edit,KEY_CLOSEBRACKET,MENUMOD CreateMenu "Block Outdent",MENUOUTDENT,edit,KEY_OPENBRACKET,MENUMOD CreateMenu "",0,edit CreateMenu "&Find...",MENUFIND,edit,KEY_F,MENUMOD ?MacOS CreateMenu "Find Next",MENUFINDNEXT,edit,KEY_G,MENUMOD CreateMenu "&Replace...",MENUREPLACE,edit,KEY_H,MENUMOD CreateMenu "&Goto Line...",MENUGOTO,edit,KEY_L,MENUMOD ?Win32 CreateMenu "Find Next",MENUFINDNEXT,edit,KEY_F3 CreateMenu "&Replace...",MENUREPLACE,edit,KEY_H,MENUMOD CreateMenu "&Goto Line...",MENUGOTO,edit,KEY_G,MENUMOD ?Linux CreateMenu "Find Next",MENUFINDNEXT,edit,KEY_F3 CreateMenu "&Replace...",MENUREPLACE,edit,KEY_H,MENUMOD CreateMenu "&Goto Line...",MENUGOTO,edit,KEY_G,MENUMOD ? program=CreateMenu("&Program",0,menu) CreateMenu "&Build",MENUBUILD,program,KEY_B,MENUMOD CreateMenu "Build and &Run",MENURUN,program,KEY_R,MENUMOD CreateMenu "Command &Line...",MENUCOMMANDLINE,program CreateMenu "",0,program CreateMenu "&Step",MENUSTEP,program,KEY_F9 CreateMenu "Step &In",MENUSTEPIN,program,KEY_F10 CreateMenu "Step &Out",MENUSTEPOUT,program,KEY_F11 CreateMenu "&Halt",MENUSTOP,program options=CreateMenu("Build Options",0,program) quickenable=CreateMenu("Quick Build",MENUQUICKENABLED,options) debugenable=CreateMenu("Debug Build",MENUDEBUGENABLED,options) guienable=CreateMenu("Build GUI App",MENUGUIENABLED,options) CreateMenu "",0,program CreateMenu "&Lock Build File",MENULOCKBUILD,program CreateMenu "&Unlock Build File",MENUUNLOCKBUILD,program CreateMenu "",0,program syncmods=CreateMenu("&Synchronize Modules...",MENUSYNCMODS,program) CreateMenu "",0,program buildmods=CreateMenu("Build &Modules",MENUBUILDMODULES,program,KEY_D,MENUMOD) buildallmods=CreateMenu("Rebuild &All Modules",MENUBUILDALLMODULES,program) docmods=CreateMenu("&Document Modules...",MENUDOCMODS,program) help=CreateMenu("&Help",0,menu) CreateMenu "&Home",MENUHOME,help CreateMenu "&Back",MENUBACK,help CreateMenu "&Forward",MENUFORWARD,help CreateMenu "&Quick Help",MENUQUICKHELP,help,KEY_F1 CreateMenu "&About BlitzMax",MENUABOUT,help If quickenabled CheckMenu quickenable If debugenabled CheckMenu debugenable If guienabled CheckMenu guienable ?win32 Local mingw$=getenv_("MINGW") If Not mingw DisableMenu buildmods DisableMenu buildallmods EndIf ? If is_demo DisableMenu syncmods EndIf RefreshRecentFiles UpdateWindowMenu window End Method Method RunCode() If mode=DEBUGMODE And debugtree.cancontinue output.go Return EndIf output.stop SaveAll If lockedpanel lockedpanel.invoke TOOLRUN Else activepanel.invoke TOOLRUN EndIf End Method Method BuildCode() output.stop SaveAll If lockedpanel lockedpanel.invoke TOOLBUILD Else activepanel.invoke TOOLBUILD EndIf End Method Method AddEventHotKey(key,mods,id,data) SetHotKeyEvent key,mods,CreateEvent(id,Null,data) End Method Method InitHotkeys() AddEventHotKey KEY_F5,MODIFIER_NONE,EVENT_MENUACTION,MENURUN AddEventHotKey KEY_F7,MODIFIER_NONE,EVENT_MENUACTION,MENUBUILD End Method Method SaveAll() Local panel:TToolPanel For panel=EachIn panels panel.invoke TOOLQUICKSAVE Next End Method Method RefreshAll() Local panel:TToolPanel ' flip navbar split.SetFlip options.navswap ' hide/show toolbar If options.showtoolbar If GadgetHidden(toolbar) tooly=GadgetHeight(toolbar) ShowGadget toolbar SetGadgetShape client,0,tooly,ClientWidth(window),ClientHeight(window)-tooly ' SetGadgetShape tabbar,0,tooly,clientwidth(window),clientheight(window)-tooly EndIf Else If Not GadgetHidden(toolbar) tooly=0 HideGadget toolbar SetGadgetShape client,0,tooly,ClientWidth(window),ClientHeight(window)-tooly ' SetGadgetShape tabbar,0,tooly,clientwidth(window),clientheight(window)-tooly EndIf EndIf ' refresh panels For panel=EachIn panels panel.invoke TOOLREFRESH Next ' refresh navbar navbar.invoke TOOLREFRESH End Method Method SnapshotWindow() If WindowMaximized(window) winmax=True Else If Not WindowMinimized(window) winmax=False winsize.x=GadgetX(window) winsize.y=GadgetY(window) winsize.w=GadgetWidth(window) winsize.h=GadgetHeight(window) EndIf EndIf End Method Method OnMenu(menu) Local index Select menu Case MENUNEW OpenSource "" Case MENUOPEN OpenSource "." Case MENUCLOSE currentpanel.invoke TOOLCLOSE Case MENUCLOSEALL CloseAll True Case MENUSAVE currentpanel.invoke TOOLSAVE Case MENUSAVEAS currentpanel.invoke TOOLSAVEAS Case MENUSAVEALL SaveAll Case MENUPRINT currentpanel.invoke TOOLPRINT Case MENUQUIT Quit Case MENUGOTO gotoreq.Show Case MENUFIND currentpanel.invoke TOOLFIND Case MENUFINDNEXT currentpanel.invoke TOOLFINDNEXT Case MENUREPLACE replacereq.Show Case MENUUNDO currentpanel.invoke TOOLUNDO Case MENUREDO currentpanel.invoke TOOLREDO Case MENUCUT currentpanel.invoke TOOLCUT Case MENUCOPY currentpanel.invoke TOOLCOPY Case MENUPASTE currentpanel.invoke TOOLPASTE Case MENUSELECTALL currentpanel.invoke TOOLSELECTALL Case MENUBUILD BuildCode Case MENURUN RunCode Case MENUBUILDMODULES If CheckDemo() BuildModules False Case MENUBUILDALLMODULES If CheckDemo() BuildModules True Case MENUSYNCMODS If CheckDemo() And CloseAll(False) syncmodsreq.Show Case MENUDOCMODS If CheckDemo() And CloseAll(False) DocMods Case MENUTRIGGERDOCMODS DocMods Case MENUTRIGGERSYNCDOCS SyncDocs Case MENUSTEP If output output.stepover Case MENUSTEPIN If output output.stepin Case MENUSTEPOUT If output output.stepout Case MENUSTOP If output output.stop Case MENULOCKBUILD activepanel.invoke TOOLLOCK Case MENUUNLOCKBUILD If lockedpanel lockedpanel.invoke TOOLUNLOCK Case MENUCOMMANDLINE cmdlinereq.Show Case MENUQUICKENABLED If quickenabled quickenabled=False UncheckMenu quickenable Else quickenabled=True CheckMenu quickenable EndIf UpdateWindowMenu window Case MENUDEBUGENABLED If debugenabled debugenabled=False UncheckMenu debugenable Else debugenabled=True CheckMenu debugenable EndIf UpdateWindowMenu window Case MENUGUIENABLED If guienabled guienabled=False UncheckMenu guienable Else guienabled=True CheckMenu guienable EndIf UpdateWindowMenu window Case MENUIMPORTBB ImportBB Case MENUFINDINFILES searchreq.Show Case MENUPROJECTMANAGER projectreq.Open projects Case MENUSHOWCONSOLE If output output.Open Case MENUOPTIONS options.Show Case MENUNEXT If Not currentpanel Return index=currentpanel.index+1 If index=panels.length index=0 SelectPanel panels[index] Case MENUPREV If Not currentpanel Return index=currentpanel.index-1 If index<0 index=panels.length-1 SelectPanel panels[index] Case MENUQUICKHELP currentpanel.invoke TOOLHELP Case MENUHOME helppanel.Home SelectPanel helppanel Case MENUBACK helppanel.Back SelectPanel helppanel Case MENUFORWARD helppanel.Forward SelectPanel helppanel Case MENUABOUT Local typ$ If is_demo typ="Demo" Else typ="Release" Local msg$=ABOUT.Replace( "{bcc_version}",BCC_VERSION ) Notify msg Case MENUINDENT currentpanel.invoke TOOLINDENT Case MENUOUTDENT currentpanel.invoke TOOLOUTDENT Case MENUNEWVIEW navbar.invoke TOOLNEWVIEW End Select If menu>=MENURECENT Local f$=String(recentfiles.ValueAtIndex(menu-MENURECENT)) If f$ OpenSource f$ EndIf End Method Method poll() Local handler:TEventHandler Local requester:TRequester Local src:TGadget,file$,EventID Local index EventID=WaitEvent() If activerequester activerequester.Poll Return EndIf For handler=EachIn eventhandlers handler.OnEvent() Next Select EventID Case EVENT_GADGETACTION Select EventSource() Case toolbar Select EventData() Case 0 OpenSource "" Case 1 OpenSource "." Case 2 currentpanel.invoke TOOLCLOSE Case 3 currentpanel.invoke TOOLSAVE Case 5 currentpanel.invoke TOOLCUT Case 6 currentpanel.invoke TOOLCOPY Case 7 currentpanel.invoke TOOLPASTE Case 8 currentpanel.invoke TOOLFIND Case 10 BuildCode Case 11 RunCode Case 12 If output output.stepover Case 13 If output output.stepin Case 14 If output output.stepout Case 15 If output output.stop Case 17 helppanel.Home;SelectPanel helppanel Case 18 helppanel.Back;SelectPanel helppanel Case 19 helppanel.Forward;SelectPanel helppanel End Select Case tabbar index=EventData() If index>=0 And index<panels.length SelectPanel panels[index] EndIf End Select Case EVENT_APPOPENFILE OpenSource EventText() Case EVENT_APPTERMINATE Quit Case EVENT_WINDOWACTIVATE SelectPanel currentpanel Case EVENT_WINDOWCLOSE src=TGadget(EventSource()) For requester=EachIn eventhandlers If src=requester.window requester.Hide Next If src=window Quit Case EVENT_WINDOWMOVE If EventSource()=window SnapshotWindow Case EVENT_WINDOWSIZE If EventSource()=window SnapshotWindow split.Resize EndIf Case EVENT_WINDOWACCEPT OpenSource String( EventExtra() ) Case EVENT_MENUACTION OnMenu EventData() Case EVENT_APPTERMINATE OnMenu MENUQUIT End Select End Method End Type |
| ||
[codebox]? |
| ||
[codebox]? can't in code archives |
| ||
Can in the comments (part 2). ;o) |
| ||
Isn't this already at Sourceforge (or, if it's the official one, the usual location in "BlitzMax\src\maxide"), or is this a different IDE altogether? Perhaps the Toolbox would be a more orderly place to put this, even if it is source code. My use of the code archives is generally to do with handy functions while I trust the Toolbox for things like IDEs :) Anyhow, thanks! This is actually a really good IDE by Blitz's standards :P |
Code Archives Forum