Initial undo/redo

This commit is contained in:
Skyler Lehmkuhl 2013-01-03 12:59:10 -05:00
parent 146f4a5362
commit 195161e823
2 changed files with 106 additions and 7 deletions

View File

@ -42,11 +42,31 @@ LIGHTNINGBEAM_COMPAT = ["1.0-alpha1"]
#Global variables. Used to keep stuff together. #Global variables. Used to keep stuff together.
global root global root
global layers global layers
global undo_stack
global redo_stack
undo_stack = []
redo_stack = []
def clear(arr):
arr.__delslice__(0,len(arr))
def update_date(): def update_date():
return "Tue, January 10, 2012" return "Tue, January 10, 2012"
class edit:
def __init__(self, type, obj, from_attrs, to_attrs):
self.type = type
self.obj = obj
self.from_attrs = from_attrs
self.to_attrs = to_attrs
class maybe:
def __init__(self, type, obj, from_attrs):
self.edit = edit(type, obj, from_attrs, from_attrs)
self.type = type
def complete(self, to_attrs):
self.edit.to_attrs = to_attrs
return self.edit
def onLoadFrames(self): def onLoadFrames(self):
'''for i in range(2000): '''for i in range(2000):
@ -81,7 +101,7 @@ def onMouseDownGroup(self, x, y,button=1,clicks=1):
self.clicked = True self.clicked = True
elif svlgui.MODE in ["r", "e", "p"]: elif svlgui.MODE in ["r", "e", "p"]:
if svlgui.MODE=="r": if svlgui.MODE=="r":
#I can't remember what the 'c' stands for... # 'c' stands for 'current'
self.cshape = box(x, y, 0, 0) self.cshape = box(x, y, 0, 0)
elif svlgui.MODE=="e": elif svlgui.MODE=="e":
self.cshape = ellipse(x, y, 0, 0) self.cshape = ellipse(x, y, 0, 0)
@ -95,6 +115,7 @@ def onMouseDownGroup(self, x, y,button=1,clicks=1):
self.cshape.onMouseDrag = onMouseDragObj self.cshape.onMouseDrag = onMouseDragObj
self.cshape.onMouseUp = onMouseUpObj self.cshape.onMouseUp = onMouseUpObj
self.cshape.onKeyDown = onKeyDownObj self.cshape.onKeyDown = onKeyDownObj
undo_stack.append(maybe("add_object", self, {"frame":self.activelayer.currentframe, "layer":self.activelayer}))
self.clicked = True self.clicked = True
MainWindow.scriptwindow.text = self.activelayer.frames[self.activelayer.currentframe].actions MainWindow.scriptwindow.text = self.activelayer.frames[self.activelayer.currentframe].actions
elif svlgui.MODE in ["t"]: elif svlgui.MODE in ["t"]:
@ -106,6 +127,9 @@ def onMouseDownGroup(self, x, y,button=1,clicks=1):
self.ctext.onMouseUp = onMouseUpText self.ctext.onMouseUp = onMouseUpText
self.add(self.ctext) self.add(self.ctext)
self.ctext = None self.ctext = None
undo_stack.append(edit("add_object", self, {"frame":self.activelayer.currentframe, "layer":self.activelayer}, \
{"frame":self.activelayer.currentframe, "layer":self.activelayer, \
"obj":self.activelayer.frames[self.activelayer.currentframe].objs[-1]}))
self.activelayer.currentselect = self.activelayer.frames[self.activelayer.currentframe].objs[-1] self.activelayer.currentselect = self.activelayer.frames[self.activelayer.currentframe].objs[-1]
MainWindow.docbox.setvisible(True) MainWindow.docbox.setvisible(True)
MainWindow.textbox.setvisible(False) MainWindow.textbox.setvisible(False)
@ -114,7 +138,14 @@ def onMouseDownObj(self, x, y,button=1,clicks=1):
MainWindow.scriptwindow.text = root.descendItem().activelayer.frames[root.descendItem().activelayer.currentframe].actions MainWindow.scriptwindow.text = root.descendItem().activelayer.frames[root.descendItem().activelayer.currentframe].actions
self.clicked = True self.clicked = True
self.initx,self.inity = x-self.x, y-self.y self.initx,self.inity = x-self.x, y-self.y
if svlgui.MODE == "b": if svlgui.MODE == " ":
undo_stack.append(maybe("move", self, {"x":self.x, "y":self.y}))
elif svlgui.MODE == "s":
undo_stack.append(maybe("scale", self, {"x":self.x, "y":self.y, "xscale":self.xscale, "yscale":self.yscale}))
elif svlgui.MODE == "b":
if not (self.fillcolor.val == svlgui.FILLCOLOR.val and self.filled==True):
undo_stack.append(edit("fill", self, {"filled":self.filled, "fillcolor":self.fillcolor}, {"filled":True, "fillcolor":svlgui.FILLCOLOR}))
clear(redo_stack)
self.filled = True self.filled = True
self.fillcolor = svlgui.FILLCOLOR self.fillcolor = svlgui.FILLCOLOR
def onMouseDownText(self,x,y,button=1,clicks=1): def onMouseDownText(self,x,y,button=1,clicks=1):
@ -132,6 +163,12 @@ def onMouseUpGroup(self, x, y,button=1,clicks=1):
self.clicked = False self.clicked = False
if svlgui.MODE in ["r", "e"]: if svlgui.MODE in ["r", "e"]:
self.cshape = None self.cshape = None
cobj = self.activelayer.frames[self.activelayer.currentframe].objs[-1]
if isinstance(undo_stack[-1], maybe):
if undo_stack[-1].edit.obj==self:
if undo_stack[-1].type=="add_object":
undo_stack[-1] = undo_stack[-1].complete({"obj":cobj, "frame":self.activelayer.currentframe, "layer":self.activelayer})
clear(redo_stack)
elif svlgui.MODE=="p": elif svlgui.MODE=="p":
print len(self.cshape.shapedata) print len(self.cshape.shapedata)
self.cshape.shapedata = misc_funcs.simplify_shape(self.cshape.shapedata, svlgui.PMODE.split()[-1],1) self.cshape.shapedata = misc_funcs.simplify_shape(self.cshape.shapedata, svlgui.PMODE.split()[-1],1)
@ -140,6 +177,21 @@ def onMouseUpGroup(self, x, y,button=1,clicks=1):
MainWindow.stage.draw() MainWindow.stage.draw()
def onMouseUpObj(self, x, y,button=1,clicks=1): def onMouseUpObj(self, x, y,button=1,clicks=1):
self.clicked = False self.clicked = False
if isinstance(undo_stack[-1], maybe):
if undo_stack[-1].edit.obj==self:
if undo_stack[-1].type=="move":
if abs(self.x-undo_stack[-1].edit.from_attrs["x"])>0 or abs(self.y-undo_stack[-1].edit.from_attrs["y"])>0:
undo_stack[-1] = undo_stack[-1].complete({"x":self.x, "y":self.y})
clear(redo_stack)
else:
del undo_stack[-1]
elif undo_stack[-1].type=="scale":
if abs(self.x-undo_stack[-1].edit.from_attrs["x"])>0 or abs(self.y-undo_stack[-1].edit.from_attrs["y"])>0 \
or abs(self.xscale-undo_stack[-1].edit.from_attrs["xscale"])>0 or abs(self.yscale-undo_stack[-1].edit.from_attrs["yscale"])>0:
undo_stack[-1] = undo_stack[-1].complete({"x":self.x, "y":self.y, "xscale":self.xscale, "yscale":self.yscale})
clear(redo_stack)
else:
del undo_stack[-1]
def onMouseUpText(self, x, y,button=1,clicks=1): def onMouseUpText(self, x, y,button=1,clicks=1):
self.clicked = False self.clicked = False
def onMouseMoveGroup(self, x, y,button=1): def onMouseMoveGroup(self, x, y,button=1):
@ -520,6 +572,51 @@ def import_to_library(widget=None):
def quit(widget): def quit(widget):
svlgui.quit() svlgui.quit()
def undo(widget=None):
if len(undo_stack)>0:
if isinstance(undo_stack[-1], edit):
e = undo_stack.pop()
print e.from_attrs
print e.to_attrs
if e.type=="move":
e.obj.x = e.from_attrs["x"]
e.obj.y = e.from_attrs["y"]
elif e.type=="scale":
e.obj.x = e.from_attrs["x"]
e.obj.y = e.from_attrs["y"]
e.obj.xscale = e.from_attrs["xscale"]
e.obj.yscale = e.from_attrs["yscale"]
elif e.type=="fill":
e.obj.filled = e.from_attrs["filled"]
e.obj.fillcolor = e.from_attrs["fillcolor"]
elif e.type=="add_object":
if e.from_attrs["layer"].currentselect==e.to_attrs["obj"]:
e.from_attrs["layer"].currentselect = None
del e.from_attrs["layer"].frames[e.from_attrs["frame"]].objs[e.from_attrs["layer"].frames[e.from_attrs["frame"]].objs.index(e.to_attrs["obj"])]
redo_stack.append(e)
MainWindow.stage.draw()
def redo(widget=None):
if len(redo_stack)>0:
if isinstance(redo_stack[-1], edit):
e = redo_stack.pop()
print e.from_attrs
print e.to_attrs
if e.type=="move":
e.obj.x = e.to_attrs["x"]
e.obj.y = e.to_attrs["y"]
elif e.type=="scale":
e.obj.x = e.to_attrs["x"]
e.obj.y = e.to_attrs["y"]
e.obj.xscale = e.to_attrs["xscale"]
e.obj.yscale = e.to_attrs["yscale"]
elif e.type=="fill":
e.obj.filled = e.to_attrs["filled"]
e.obj.fillcolor = e.to_attrs["fillcolor"]
elif e.type=="add_object":
e.to_attrs["layer"].frames[e.from_attrs["frame"]].objs.append(e.to_attrs["obj"])
undo_stack.append(e)
MainWindow.stage.draw()
def add_keyframe(widget=None): def add_keyframe(widget=None):
print "af> ", root.descendItem().activeframe print "af> ", root.descendItem().activeframe
@ -595,8 +692,8 @@ svlgui.menufuncs([["File",
"Publish", "Publish",
("Quit",quit,"<Control>Q")], ("Quit",quit,"<Control>Q")],
["Edit", ["Edit",
"Undo", ("Undo", undo, "/z"),
"Redo", ("Redo", redo, "/^z"),
"Cut", "Cut",
"Copy", "Copy",
"Paste", "Paste",

View File

@ -309,6 +309,8 @@ if SYSTEM=="osx":
m.save_cmd.enabled = 1 m.save_cmd.enabled = 1
m.save_as_cmd.enabled = 1 m.save_as_cmd.enabled = 1
m.open_cmd.enabled = 1 m.open_cmd.enabled = 1
m.undo_cmd.enabled = 1
m.redo_cmd.enabled = 1
m.run_file.enabled = 1 m.run_file.enabled = 1
m.run_html.enabled = 1 m.run_html.enabled = 1
m.create_sc.enabled = 1 m.create_sc.enabled = 1
@ -539,7 +541,7 @@ def menufuncs(j):
menus.append(menu) menus.append(menu)
else: else:
cmds={"Save":"save_cmd", "Save As":"save_as_cmd", "Open":"open_cmd","About Lightningbeam...":"about_cmd",\ cmds={"Save":"save_cmd", "Save As":"save_as_cmd", "Open":"open_cmd","About Lightningbeam...":"about_cmd",\
"Preferences":"preferences_cmd"} "Preferences":"preferences_cmd", "Undo":"undo_cmd", "Redo":"redo_cmd"}
[setattr(app,cmds[k[0]],k[1]) for k in i if (k[0] in cmds)] [setattr(app,cmds[k[0]],k[1]) for k in i if (k[0] in cmds)]
class VBox(Widget): class VBox(Widget):
@ -2747,7 +2749,7 @@ class ColorSelectionWindow:
win.present() win.present()
elif SYSTEM=="osx": elif SYSTEM=="osx":
win = ModalDialog(width=336,height=208,resizable=False) win = ModalDialog(width=336,height=208,resizable=False)
def onClickRectFill(self,x,y): def onClickRectFill(self,x,y,button=None,clicks=None):
global FILLCOLOR global FILLCOLOR
FILLCOLOR = Color(colors.colorArray(int(x/16))[int(y/16)]) FILLCOLOR = Color(colors.colorArray(int(x/16))[int(y/16)])
if root.descendItem().activelayer.currentselect: if root.descendItem().activelayer.currentselect:
@ -2756,7 +2758,7 @@ class ColorSelectionWindow:
root.descendItem().activelayer.currentselect.update() root.descendItem().activelayer.currentselect.update()
self.window.dismiss() self.window.dismiss()
raise ObjectDeletedError raise ObjectDeletedError
def onClickRectLine(self,x,y): def onClickRectLine(self,x,y,button=None,clicks=None):
global LINECOLOR global LINECOLOR
LINECOLOR = Color(colors.colorArray(int(x/16))[int(y/16)]) LINECOLOR = Color(colors.colorArray(int(x/16))[int(y/16)])
if root.descendItem().activelayer.currentselect: if root.descendItem().activelayer.currentselect: