Forum Archive

def Undo Action

avinashsah

How to define undo function in Pythonista

stephen

@avinashsah hello!

what are you going to undo/redo with?
- text input
- path drawing
- image eiting
...

cvp

@avinashsah if keyboard, see here

stephen

@avinashsah here is a rough example of a redo/undo delegate. from what i could find online you have to create your own.

@cvp if you dont mind, fom your experience, is this how you would do it?


from ui import *

class redo_undo:
    def __init__(self, main,  *args, **kwargs):
        # undo/redo View
        self.history_view = TextView(
            text='HISTORY',
            frame=(25, 275, 600, 400),
            editable=False,
            background_color='#dedede')
        main.add_subview(self.history_view)

        # Undo Button
        undo_btn=Button()
        undo_btn.frame=(25, 2, 100, 46)
        undo_btn.background_color='#686868'
        undo_btn.tint_color='#000000'
        undo_btn.title='undo'
        undo_btn.action=self.undo
        main.add_subview(undo_btn)

        # Redo Button
        redo_btn=Button()
        redo_btn.frame=(127, 2, 100, 46)
        redo_btn.background_color='#686868'
        redo_btn.tint_color='#000000'
        redo_btn.title='redo'
        redo_btn.action=self.redo
        main.add_subview(redo_btn)

        self.history=[]
        self.current_index=len(self.history)
        self.textview=None

    def append(self, text):
        if self.current_index < len(self.history):
            self.history=self.history[:self.current_index]
        self.current_index=len(self.history)
        self.history.append(text)   
        self.current_index+=1

        self.update_history(self.current_index)

    def update_history(self, index):
        self.history_view.text=''
        i=0
        for x in self.history:
            if i == index:
                self.history_view.text+=str(i)+' '+x+' <--'+'\n'
            elif x == self.history[-1] and index == len(self.history):
                self.history_view.text+=str(i)+' '+x+' <--'+'\n'
            else:
                self.history_view.text+=str(i)+' '+x+'\n'
            i+=1
    def redo(self, sender):
        if self.current_index == len(self.history):
            return 
        if self.current_index < len(self.history):
            self.current_index+=1
            self.textview.text = self.history[self.current_index-1]     
        self.update_history(self.current_index-1)

    def undo(self, sender):     
        if self.current_index == 0:
            return 
        self.current_index-=1
        self.textview.text = self.history[self.current_index-1] 
        self.update_history(self.current_index-1)

    def textview_should_begin_editing(self, textview):
        if textview.text=='INPUT TEXT ..':
            textview.text=''
        self.textview=textview
        return True

    def textview_did_change(self, textview):
        self.append(textview.text)
        self.update_history(self.current_index)
        pass

class Main(View):
    def __init__(self, *args, **kwargs):
        # Main Window
        self.width = 650
        self.height = 1000
        self.background_color="#8b8b8b"
        self.update_interval=1

        # Text Input Window
        self.tv = TextView(
            text='INPUT TEXT ..',
            frame=(25, 50, 600, 200),
            background_color='#dedede')
        self.add_subview(self.tv)
        self.tv.delegate=redo_undo(self)

if __name__ == '__main__':
    Main().present('sheet', hide_title_bar=True)


cvp

@stephen said:

is this how you would do it?

Sincerely, I don't know. And it is really better to ask an advice to @mikael , I'm far from to be a champion of Python. 😢

stephen

@cvp no problem. maybe @mikael can give insight on the matter \😁

mikael

@cvp, I think @stephen was asking your opinion on how (= approach) you would implement a history function, not how (= style) we would code Python.

I see no issues with the approacj, but would of course rather rely in the built-in undo, especially now that it is more convenient with the three-finger tap.

Interesting question of course how you could tap into that functionality from your own custom button.

stephen

@mikael tjank you. I could not find anywhere a way to tap into the “global” buffer if that even exists lol. But if you don’t see anything wrong or too taboo then it should cover OP’s request.

mikael

@stephen, ”too taboo” – has a nice ring to it. 😁

cvp

@mikael said:

would of course rather rely in the built-in undo, especially now that it is more convenient with the three-finger tap.

I agree

stephen

@mikael 😂 I just read that like 20 times..


@cvp @mikael

I agree i on using built in though we still are unsure of OP's use case. might be trying to create their own keyboard. but it was fun troubleshooting that little delegate class lol