SuperStrictImport maxgui.driversType TLexer Field BACKGROUNDCOLOR_R:Int=224 Field BACKGROUNDCOLOR_G:Int=224 Field BACKGROUNDCOLOR_B:Int=224 Field FORMATCOLOR_PLAIN_R:Int=0 Field FORMATCOLOR_PLAIN_G:Int=0 Field FORMATCOLOR_PLAIN_B:Int=0 Field FORMATSTYLE_PLAIN:Int=0 Field FORMATCOLOR_STRING_R:Int=0 Field FORMATCOLOR_STRING_G:Int=128 Field FORMATCOLOR_STRING_B:Int=0 Field FORMATSTYLE_STRING:Int=TEXTFORMAT_ITALIC Field FORMATCOLOR_COMMENT_R:Int=128 Field FORMATCOLOR_COMMENT_G:Int=0 Field FORMATCOLOR_COMMENT_B:Int=128 Field FORMATSTYLE_COMMENT:Int=0 Field FORMATCOLOR_COMMAND_R:Int=0 Field FORMATCOLOR_COMMAND_G:Int=0 Field FORMATCOLOR_COMMAND_B:Int=255 Field FORMATSTYLE_COMMAND:Int=TEXTFORMAT_BOLD Field keywords:String[] Field lkeywords:String[] Method AddKeyword(word:String) Local count:Int count=keywords.length keywords=keywords[..count+1] lkeywords=lkeywords[..count+1] keywords[count]=word lkeywords[count]=word.tolower() EndMethod Method FormatText(gadget:TGadget,position:Int=0,length:Int=TEXTAREA_ALL) Local index:Int Local commentline:Int LockTextArea gadget If length=TEXTAREA_ALL length=TextAreaLen(gadget,TEXTAREA_LINES)-1-position For index=position To position+length Rem 'Check for Rem s$=Lower(TextAreaText(gadget,index,1,TEXTAREA_LINES)) s=Trim(s) If Not commentline If Left(s,3)="rem" c$=Mid(s,4,1) commentline=True If lb>=48 And lb<=57 commentline=False If lb>=65 And lb<=90 commentline=False If lb>=97 And lb<=122 commentline=False EndIf EndIf If commentline If Left(s,6)="endrem" c$=Mid(s,4,1) commentline=False If lb>=48 And lb<=57 commentline=True If lb>=65 And lb<=90 commentline=True If lb>=97 And lb<=122 commentline=True FormatTextAreaText(gadget,128,0,128,0,index,1,TEXTAREA_LINES) Continue EndIf EndIf EndRem If commentline FormatTextAreaText(gadget,128,0,128,0,index,1,TEXTAREA_LINES) Else FormatLine gadget,index EndIf Next UnlockTextArea gadget EndMethod Method FormatLine(gadget:TGadget,position:Int) Local s:String Local startpos:Int Local pos:Int Local ss:String Local pos2:Int Local stringoffset:Int Local firstpart:String Local lastpart:String Local space:String Local n:Int FormatTextAreaText(gadget,FORMATCOLOR_PLAIN_R,FORMATCOLOR_PLAIN_G,FORMATCOLOR_PLAIN_B,FORMATSTYLE_PLAIN,position,1,TEXTAREA_LINES) s$=Lower(TextAreaText(gadget,position,1,TEXTAREA_LINES)) startpos=TextAreaChar(gadget,position) 'Remove Comments pos=Instr(s,"'") If pos FormatTextAreaText(gadget,FORMATCOLOR_COMMENT_R,FORMATCOLOR_COMMENT_G,FORMATCOLOR_COMMENT_B,FORMATSTYLE_COMMENT,startpos+pos-1,s.length-pos) s=Left(s,pos) EndIf 'Strings ss$=s pos=Instr(ss,Chr(34)) stringoffset=0 While pos pos2=Instr(ss,Chr(34),pos+1) If pos2 FormatTextAreaText(gadget,FORMATCOLOR_STRING_R,FORMATCOLOR_STRING_G,FORMATCOLOR_STRING_B,FORMATSTYLE_STRING,startpos+pos+stringoffset-1,pos2-pos+1) firstpart$=Left(s,pos+stringoffset-1) lastpart$=Right(s,s.length-pos2-stringoffset) s$=firstpart space$="" For n=1 To ss.length-firstpart.length-lastpart.length-2 space$:+"?" Next s=s+Chr(34)+space+Chr(34)+lastpart Else Exit EndIf ss=Right(ss,ss.length-pos2) pos=Instr(ss,Chr(34)) stringoffset:+pos2 Wend 'Format Keywords Local text:String Local ltext:String Local leftokay:Int Local rightokay:Int Local lc:String Local lb:Int Local rc:String Local rb:Int Local r:Int,g:Int,b:Int Local length:Int For n=0 To keywords.length-1 text=keywords[n] ltext=lkeywords[n] pos=Instr(s,ltext) While pos 'Is word isolated? If pos>0 lc$=Mid(s,pos-1,1) lb=Asc(lc) leftokay=True If lb>=48 And lb<=57 leftokay=False If lb>=65 And lb<=90 leftokay=False If lb>=97 And lb<=122 leftokay=False Else leftokay=True EndIf 'Check the right side If leftokay If pos+text.length-1<=s.length rc$=Mid(s,pos+text.length,1) rb=Asc(rc) rightokay=True If rb>=48 And rb<=57 rightokay=False If rb>=65 And rb<=90 rightokay=False If rb>=97 And rb<=122 rightokay=False Else rightokay=True EndIf If rightokay SetTextAreaText gadget,text,startpos+pos-1,text.length r=FORMATCOLOR_COMMAND_R g=FORMATCOLOR_COMMAND_G b=FORMATCOLOR_COMMAND_B position=startpos+pos-1 length=text.length FormatTextAreaText(gadget,r,g,b,FORMATSTYLE_COMMAND,position,length) EndIf EndIf pos=Instr(s,ltext,pos+text.length) Wend Next EndMethod EndType
SuperStrictImport maxgui.driversType TUndoContext Field link:TLink Field gadget:TGadget Field undostates:TList=New TList Field Current:TUndoState Field change:Int Field disabled:Int Method CreateUndoState:TUndostate(force:Int=0) If Current Current.clearafter Local undostate:TUndoState=New TUndoState undostate.context=Self undostate.link=undostates.addlast(undostate) undostate.selpos=TextAreaCursor(gadget) undostate.sellen=TextAreaSelLen(gadget) undostate.update() undostate.force=force Current=undostate Return undostate EndMethod Method CanUndo:TUndoState(undostate:TUndoState=Null) If undostate=Null undostate=Current If undostate If undostate.link.prevlink() Local prevundostate:TUndoState=TUndoState(undostate.link.prevlink().value()) If prevundostate.force=-1 Return TUndoState(prevundostate.link.prevlink().value()) Else Return prevundostate EndIf EndIf EndIf Return Null EndMethod Method CanRedo:TUndoState(undostate:TUndoState=Null) If undostate=Null undostate=Current If undostate If undostate.link.nextlink() Local nextundostate:TUndoState=TUndoState(undostate.link.nextlink().value()) If nextundostate.force=1 Return TUndoState(nextundostate.link.nextlink().value()) Else Return nextundostate EndIf EndIf EndIf Return Null EndMethod Method Undo:Int() If Current If canundo() Current.undo Current=canundo() Return True EndIf EndIf Return False EndMethod Method Redo:Int() Local undostate:TUndoState=CanRedo() If undostate undostate.redo Current=undostate Return True EndIf Return False EndMethod Method Flush() For Local undostate:TUndoState=EachIn undostates undostate.kill Next undostates.clear Current=Null createundostate EndMethod Method Free() flush undostates=Null gadget=Null RemoveLink link link=Null EndMethod Function Create:TUndoContext(gadget:TGadget) Local undocontext:TUndoContext=New TUndoContext undocontext.gadget=gadget undocontext.createundostate Return undocontext EndFunction EndTypeType TUndostate Field link:TLink Field context:TUndoContext Field text$ Field undotext$ Field redotext$ Field selpos:Int Field sellen:Int Field undolen:Int Field undopos:Int Field change:Int Field force:Int Field removetext$ Field removeposition:Int Field addtext$ Field addposition:Int Method Update() text$=TextAreaText(context.gadget) selpos=TextAreaCursor(context.gadget) sellen=TextAreaSelLen(context.gadget) removetext=TextAreaText(context.gadget,selpos,sellen) Local lastundostate:TUndoState=context.canundo(Self) If lastundostate change=text.length-lastundostate.text.length change=change+lastundostate.sellen Else change=text.length EndIf If change<0 undopos=selpos undolen=-change If lastundostate undotext=Mid(lastundostate.text,undopos+1,-change) EndIf Else undopos=selpos-change undolen=change If lastundostate undotext=Mid(text,undopos+1,change) EndIf EndIf EndMethod Method Undo() Local start:Int=TextAreaCursor(context.gadget) Local prevundostate:TUndoState=context.canundo(Self) Local nextundostate:TUndoState=context.canredo(Self) 'LockTextArea context.gadget If change>0 SetTextAreaText context.gadget,"",undopos,undolen Else SetTextAreaText context.gadget,undotext,undopos,0 EndIf 'UnlockTextArea context.gadget prevundostate:TUndoState=context.canundo(Self) If prevundostate SetTextAreaText context.gadget,prevundostate.removetext,prevundostate.selpos,0 SelectTextAreaText context.gadget,prevundostate.selpos,prevundostate.sellen Else SelectTextAreaText context.gadget,0,0 EndIf Local stop:Int=TextAreaCursor(context.gadget) Local size:Int=Abs(start-stop)+TextAreaSelLen(context.gadget) context.disabled=True EmitEvent CreateEvent(EVENT_GADGETACTION,context.gadget,size) context.disabled=False EndMethod Method Redo() Local start:Int=TextAreaCursor(context.gadget) Local prevundostate:TUndoState=context.canundo(Self) Local nextundostate:TUndoState=context.canredo(Self) Local l:Int LockTextArea context.gadget If change<0 SetTextAreaText context.gadget,"",undopos,undolen Else If prevundostate l=prevundostate.sellen SetTextAreaText context.gadget,undotext,undopos,l EndIf UnlockTextArea context.gadget SelectTextAreaText context.gadget,selpos,sellen Local stop:Int=TextAreaCursor(context.gadget) Local size:Int=start-stop context.disabled=True EmitEvent CreateEvent(EVENT_GADGETACTION,context.gadget,size) context.disabled=False EndMethod Method ClearAfter() Local sublink:TLink Local nextsublink:TLink sublink=link.nextlink() While sublink nextsublink=sublink.nextlink() TUndoState(sublink.value()).kill sublink=nextsublink Wend EndMethod Method Kill() If link.prevlink() context.Current=TUndostate(link.prevlink().value()) Else context.Current=Null EndIf RemoveLink link link=Null EndMethodEndType
SuperStrictImport "CodeArea.bmx"Local window:TGadgetLocal menu:TGadgetLocal codearea:TCodeArea'Create windowwindow=CreateWindow("My Window",130,20,800,600,,15|WINDOW_ACCEPTFILES)menu=CreateMenu("Edit",0,WindowMenu(window))CreateMenu("Undo",0,menu,KEY_Z,MODIFIER_COMMAND)CreateMenu("Redo",0,menu,KEY_Z,MODIFIER_COMMAND|MODIFIER_OPTION)UpdateWindowMenu(window)'Create CodeArea gadgetcodearea=TCodeArea.Create(0,0,ClientWidth(window),ClientHeight(window),window)SetGadgetLayout codearea,1,1,1,1SetGadgetFont(codearea,LoadGuiFont("Courier",9))ActivateGadget codearea'Add keywordscodearea.lexer.AddKeyWord("If")codearea.lexer.AddKeyWord("EndIf")codearea.lexer.AddKeyWord("Next")codearea.lexer.AddKeyWord("Next")codearea.lexer.AddKeyWord("For")codearea.lexer.AddKeyWord("To")codearea.lexer.AddKeyWord("Local")codearea.lexer.AddKeyWord("Global")codearea.lexer.AddKeyWord("KeyHit")'Add some textAddTextAreaText codearea,"if keyhit(KEY_ESCAPE)~n"AddTextAreaText codearea," ~n"AddTextAreaText codearea,"endif~n"'Main loopWhile WaitEvent() Print CurrentEvent.ToString()+" "+EventSourceHandle() Select EventID() Case EVENT_MENUACTION Select GadgetText(TGadget(EventSource())) Case "Undo" codearea.Undo() Case "Redo" codearea.Redo() EndSelect Case EVENT_WINDOWCLOSE End Case EVENT_APPTERMINATE End End SelectWend