Textarea, Undo
BlitzMax Forums/BlitzMax Beginners Area/Textarea, Undo
| ||
Hello everyone. I'm having big time trouble getting a Undo function to work correctly for a textarea... If I type "This is a undo test" in the textarea and click "undo" from the menu, this is how it will look: This is a undo testThis is a undo test This is a undo tesThis is a undo test This is a undo teThis is a undo test This is a undo tThis is a undo test This is a undo This is a undo test This is a undThis is a undo test This is a unThis is a undo test ...well, you get the picture. So, it somehow works but still it don't... :-) CalculateDiff Method: Method CalculateDiff:TDiff(src:String) Local d:TDiff d = New TDiff ' Store the new cursor position d.pos0 = cursorpos d.count0 = cursorlen ' And the previous cursor position ' The following works in most instances d.del = cleansrc[oldpos..oldpos + oldlen] d.add = src[oldpos..cursorpos + cursorlen] d.pos1 = oldpos If src.length = cleansrc.length If cursorpos > oldpos d.del = cleansrc[oldpos..cursorpos] d.add = src[oldpos..cursorpos] d.pos1 = oldpos ElseIf cursorpos < oldpos d.del = cleansrc[cursorpos..oldpos] d.add = src[cursorpos..oldpos] d.pos1 = oldpos Else EndIf ElseIf cursorlen = 0 And cursorpos = oldpos d.del = cleansrc[cursorpos..cursorpos + cleansrc.length - src.length] d.add = "" ElseIf cursorlen = 0 And cursorpos < oldpos d.del = cleansrc[cursorpos..cursorpos + cleansrc.length - src.length] d.add = "" d.pos1 = cursorpos EndIf If d.del.length = 0 And d.add.length = 0 d = Null Return d EndMethod Undo Method: Method Undo() Local d:TDiff If Not undolist.isEmpty() ' Take the diff out of the undo-list, and put it in the redo-list d = TDiff(undolist.RemoveLast() ) redolist.AddLast d ' Replace the added text (d.add) at the correct position (d.pos1) with the deleted text (d.del) SetTextAreaText textarea , d.del , d.pos1 , d.add.length ' Move the cursor and select what was selected before SelectTextAreaText(textarea , d.pos , d.count) ' Update the view SetDocument TextAreaText(textarea), d UpdateCursor UpdateDocument EndIf EndMethod UpdateDocument Method: Method UpdateDocument(makeundo:Int = True) Local cpos:Int , src$ Local d:TDiff src = TextAreaText(textarea) d = CalculateDiff(src) If d Then If makeundo Then AddToUndoList d redolist.clear EndIf SetDocument src , d Else SetDocument src EndIf EndMethod SetDocument Method: Method SetDocument:Int(src$ , diff:TDiff = Null) Local result:Int = False Local p:Int , p1:Int Local cpos:Int , clen:Int CheckDirty src If src = cleansrc result = True If Not result Then cpos = TextAreaCursor(textarea , TEXTAREA_CHARS) clen = TextAreaSelLen(textarea) SelectTextAreaText textarea , cpos , clen , TEXTAREA_CHARS EndIf cleansrc = src Return result EndMethod |