November 25, 2020, 04:55:40 AM

Author Topic: [bmx] TextArea undo module by JoshK [ 1+ years ago ]  (Read 553 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bmx] TextArea undo module by JoshK [ 1+ years ago ]
« on: June 29, 2017, 12:28:41 AM »
Title : TextArea undo module
Author : JoshK
Posted : 1+ years ago

Description : Command set for undo/redo with textarea gadgets

Code :
Code: BlitzMax
  1. 'Rem
  2. Module leadwerks.textareaundo
  3.  
  4. Import BRL.FileSystem
  5. Import BRL.System
  6. Import BRL.Win32MaxGUI
  7. Import BRL.Retro
  8.  
  9.  
  10. 'EndRem
  11.  
  12. Private
  13.  
  14. Type TUndoContext
  15.         Global list:TList=New TList
  16.        
  17.         Field link:TLink
  18.         Field gadget:TGadget
  19.         Field undostates:TList=New TList
  20.         Field current:TUndoState
  21.         Field change
  22.         Field disabled
  23.  
  24.         Method New()
  25.                 link=list.addlast(Self)
  26.         EndMethod
  27.        
  28.         Method CreateUndoState:TUndostate(force=0)
  29.                 If current current.clearafter
  30.                 undostate:TUndoState=New TUndoState
  31.                 undostate.context=Self
  32.                 undostate.link=undostates.addlast(undostate)
  33.                 undostate.selpos=TextAreaCursor(gadget)
  34.                 undostate.sellen=TextAreaSelLen(gadget)
  35.                 undostate.update
  36.                 undostate.force=force
  37.                 current=undostate
  38.                 Return undostate
  39.         EndMethod
  40.                
  41.         Method CanUndo:TUndoState(undostate:TUndoState=Null)
  42.                 If undostate=Null undostate=current
  43.                 If undostate
  44.                         If undostate.link.prevlink()
  45.                                 prevundostate:TUndoState=TUndoState(undostate.link.prevlink().value())
  46.                                 If prevundostate.force=-1
  47.                                         Return TUndoState(prevundostate.link.prevlink().value())
  48.                                 Else
  49.                                         Return prevundostate
  50.                                 EndIf
  51.                         EndIf
  52.                 EndIf
  53.                 Return Null
  54.         EndMethod
  55.        
  56.         Method CanRedo:TUndoState(undostate:TUndoState=Null)
  57.                 If undostate=Null undostate=current
  58.                 If undostate
  59.                         If undostate.link.nextlink()
  60.                                 nextundostate:TUndoState=TUndoState(undostate.link.nextlink().value())
  61.                                 If nextundostate.force=1
  62.                                         Return TUndoState(nextundostate.link.nextlink().value())
  63.                                 Else
  64.                                         Return nextundostate
  65.                                 EndIf
  66.                         EndIf
  67.                 EndIf
  68.                 Return Null
  69.         EndMethod
  70.  
  71.         Method Undo:Int()
  72.                 If current
  73.                         If canundo()
  74.                                 current.undo
  75.                                 current=canundo()
  76.                                 Return True
  77.                         EndIf
  78.                 EndIf
  79.                 Return False
  80.         EndMethod
  81.  
  82.         Method Redo:Int()
  83.                 undostate:TUndoState=CanRedo()
  84.                 If undostate
  85.                         undostate.redo
  86.                         current=undostate
  87.                         Return True
  88.                 EndIf
  89.                 Return False
  90.         EndMethod
  91.  
  92.         Method Flush()
  93.                 For undostate:TUndoState=EachIn undostates
  94.                         undostate.kill
  95.                 Next
  96.                 undostates.clear
  97.                 current=Null
  98.                 createundostate
  99.         EndMethod
  100.        
  101.         Method Kill()
  102.                 flush
  103.                 undostates=Null
  104.                 gadget=Null
  105.                 RemoveLink link
  106.                 link=Null
  107.         EndMethod
  108.  
  109.         Function Callback:Object(id:Int,data:Object,context:Object)
  110.                 Local event:TEvent=TEvent(data)
  111.                 Select event.id
  112.                        
  113.                         Case EVENT_GADGETSELECT
  114.                                 For undocontext:TUndoContext=EachIn TUndoContext.list
  115.                                         If event.source=undocontext.gadget
  116.                                                 If undocontext.current
  117.                                                         If Not undocontext.disabled
  118.                                                                 If undocontext.current.text=TextAreaText(undocontext.gadget)
  119.                                                                         undocontext.current.selpos=TextAreaCursor(undocontext.gadget)
  120.                                                                         undocontext.current.sellen=TextAreaSelLen(undocontext.gadget)
  121.                                                                         undocontext.current.removetext=TextAreaText(undocontext.gadget,undocontext.current.selpos,undocontext.current.sellen)
  122.                                                                 EndIf
  123.                                                         EndIf
  124.                                                 EndIf
  125.                                                 Exit
  126.                                         EndIf
  127.                                 Next
  128.                        
  129.                         Case EVENT_GADGETACTION
  130.                                 For undocontext:TUndoContext=EachIn TUndoContext.list
  131.                                         If event.source=undocontext.gadget
  132.                                                 If Not undocontext.disabled
  133.                                                         If undocontext.current
  134.                                                                 If undocontext.current.text=TextAreaText(undocontext.gadget) Return Null
  135.                                                         EndIf
  136.                                                         undostate:TUndoState=undocontext.createundostate()
  137.                                                         event.data=undostate.change
  138.                                                 EndIf
  139.                                                 Exit
  140.                                         EndIf
  141.                                 Next
  142.                                
  143.                 EndSelect
  144.                 Return data
  145.         EndFunction
  146.        
  147. EndType
  148.  
  149. Function CreateUndoContext:TUndocontext(gadget:TGadget)
  150.         undocontext:TUndoContext=New TUndoContext
  151.         undocontext.gadget=gadget
  152.         undocontext.createundostate
  153.         Return undocontext
  154. EndFunction
  155.  
  156. Type TUndostate
  157.         Field link:TLink
  158.         Field context:TUndoContext
  159.         Field text$
  160.         Field undotext$
  161.         Field redotext$
  162.         Field selpos
  163.         Field sellen
  164.         Field undolen
  165.         Field undopos
  166.         Field change
  167.         Field force
  168.        
  169.         Field removetext$
  170.         Field removeposition
  171.        
  172.         Field addtext$
  173.         Field addposition
  174.  
  175.         Method Update()
  176.                 text$=TextAreaText(context.gadget)
  177.                 selpos=TextAreaCursor(context.gadget)
  178.                 sellen=TextAreaSelLen(context.gadget)
  179.                
  180.                 removetext=TextAreaText(context.gadget,selpos,sellen)
  181.                
  182.                 lastundostate:TUndoState=context.canundo(Self)
  183.                 If lastundostate
  184.                         change=text.length-lastundostate.text.length
  185.                         change=change+lastundostate.sellen
  186.                 Else
  187.                         change=text.length
  188.                 EndIf
  189.                                
  190.                 If change<0
  191.                         undopos=selpos
  192.                         undolen=-change
  193.                         If lastundostate
  194.                                 undotext=Mid(lastundostate.text,undopos+1,-change)
  195.                         EndIf
  196.                 Else
  197.                         undopos=selpos-change
  198.                         undolen=change
  199.                         If lastundostate
  200.                                 undotext=Mid(text,undopos+1,change)
  201.                         EndIf
  202.                 EndIf
  203.  
  204.         EndMethod
  205.  
  206.         Method Undo()
  207.                 start=TextAreaCursor(context.gadget)
  208.                 prevundostate:TUndoState=context.canundo(Self)
  209.                 nextundostate:TUndoState=context.canredo(Self)
  210.                 LockTextArea context.gadget
  211.                 If change>0
  212.                         SetTextAreaText context.gadget,"",undopos,undolen
  213.                 Else
  214.                         SetTextAreaText context.gadget,undotext,undopos,0
  215.                 EndIf
  216.                 UnlockTextArea context.gadget
  217.                 prevundostate:TUndoState=context.canundo(Self)
  218.                 If prevundostate               
  219.                         SetTextAreaText context.gadget,prevundostate.removetext,prevundostate.selpos,0
  220.                         SelectTextAreaText context.gadget,prevundostate.selpos,prevundostate.sellen
  221.                 Else
  222.                         SelectTextAreaText context.gadget,0,0
  223.                 EndIf
  224.                
  225.                 stop=TextAreaCursor(context.gadget)
  226.                 size=Abs(start-stop)+TextAreaSelLen(context.gadget)
  227.                 context.disabled=True
  228.                 EmitEvent CreateEvent(EVENT_GADGETACTION,context.gadget,size)
  229.                 context.disabled=False
  230.         EndMethod
  231.        
  232.         Method Redo()
  233.                 start=TextAreaCursor(context.gadget)
  234.                 prevundostate:TUndoState=context.canundo(Self)
  235.                 nextundostate:TUndoState=context.canredo(Self)
  236.                 LockTextArea context.gadget
  237.                 If change<0
  238.                         SetTextAreaText context.gadget,"",undopos,undolen
  239.                 Else
  240.                         If prevundostate l=prevundostate.sellen
  241.                         SetTextAreaText context.gadget,undotext,undopos,l
  242.                 EndIf
  243.                 UnlockTextArea context.gadget
  244.                 SelectTextAreaText context.gadget,selpos,sellen
  245.                
  246.                 stop=TextAreaCursor(context.gadget)
  247.                 size=Abs(start-stop)+TextAreaSelLen(context.gadget)
  248.                 context.disabled=True
  249.                 EmitEvent CreateEvent(EVENT_GADGETACTION,context.gadget,size)
  250.                 context.disabled=False
  251.         EndMethod
  252.        
  253.         Method ClearAfter()
  254.                 Local sublink:TLink
  255.                 Local nextsublink:TLink
  256.                 sublink=link.nextlink()
  257.                 While sublink
  258.                         nextsublink=sublink.nextlink()
  259.                         TUndoState(sublink.value()).kill
  260.                         sublink=nextsublink                    
  261.                 Wend
  262.         EndMethod
  263.        
  264.         Method Kill()
  265.                 If link.prevlink()
  266.                         current=TUndostate(link.prevlink().value())
  267.                 Else
  268.                         current=Null
  269.                 EndIf
  270.                 RemoveLink link
  271.                 link=Null
  272.         EndMethod
  273.  
  274. EndType
  275.  
  276. AddHook EmitEventHook,TUndoContext.Callback
  277.  
  278. Function FindUndoContext:TUndoContext(gadget:TGadget)
  279.         For undocontext:TUndoContext=EachIn TUndoContext.list
  280.                 If undocontext.gadget=gadget Return undocontext
  281.         Next
  282.         undocontext=CreateUndoContext(gadget)
  283.         Return undocontext
  284. EndFunction
  285.  
  286. Public
  287.  
  288. 'Helper Functions
  289. Function TextAreaUndo:Int(gadget:TGadget)
  290.         Return FindUndoContext(gadget).undo()
  291. EndFunction
  292.  
  293. Function TextAreaRedo:Int(gadget:TGadget)
  294.         Return FindUndoContext(gadget).redo()
  295. EndFunction
  296.  
  297. Function TextAreaCanUndo:Int(gadget:TGadget)
  298.         Return (FindUndoContext(gadget).canundo()<>Null)
  299. EndFunction
  300.  
  301. Function TextAreaCanRedo:Int(gadget:TGadget)
  302.         Return (FindUndoContext(gadget).canredo()<>Null)
  303. EndFunction
  304.  
  305. Function TextAreaFlushUndos:Int(gadget:TGadget)
  306.         FindUndoContext(gadget).flush()
  307. EndFunction
  308.  
  309. Function TextAreaCreateUndoState()
  310.         FindUndoContext(gadget).createundostate
  311. EndFunction


Comments :


danielos(Posted 1+ years ago)

 well, it looks good, but can you do that also for BB+ ? I'd be great!Anyway, it is in the wrong Section "Code archives/BlitzPlus Gui/TextArea undo module"...


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal