| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908 |
- """
- Defines Graph Editor
- """
- import wx
- import math
- from . import ObjectGlobals as OG
- from . import AnimGlobals as AG
- from wx.lib.embeddedimage import PyEmbeddedImage
- property = [
- "translateX",
- "translateY",
- "translateZ"
- ]
- #----------------------------------------------------------------------
- ZoomIn = PyEmbeddedImage(
- "iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAIAAAD9b0jDAAAAA3NCSVQICAjb4U/gAAACgklE"
- "QVRIid3VW0vjQBQA4DlJMziZlCKCSB/9Bf4a3wRtNU6SHyXK6pay2nVbQbasskXFO15SqmwL"
- "LtYnn7Zg20zSyT50wZikXsCHxXk9Z74ZZuacgebtLXrvIb27+PFQjDEADIoqiiLL8htQAMAY"
- "Hx4dPTw8SHEuIaRWqzWbzUQi8SoUAIaGhgqFgn15SSn1Iwmqqh4fH5c2NpLJpO8/xhORzEeR"
- "EJLL5VqtViaT8TxPCBFMoJTu7e1tb28zxpLJpOu6L6D9PS6vrHQ6nWw267puVNzZ2alUKqZh"
- "UE0LivFoX/y0vOxynpmZ4ZxHxZ+Vyu7urmmaqqqGxBhUkiSM8eLiIgDMTE87EVHTtB9bW4cH"
- "B5ZpEkKiYhjt3/XCwoKiKFNTU47jRPf4vVw+PTmxLAtjHCs+QQEAAJaWljRNm5yc7Ha7wQtF"
- "CGGMy+WybduWZSmK4nlerIiCTwoAOOfX19cTExMSgPDDT0iSJNu2x8fHU6nUM+ITVAhBCLFM"
- "83MuV63VKCGhVM65ruv1RqNYLFJKX4UihFzXTafTc7Oz+XzerlZVVQ1GhRCyLJuGcXV1VSqV"
- "QtGBKEKo6zhjY2Pzur66tnZxcRGa2ev1AMA0zXqj8W3wfmPK1HGc0dFRNj//dX397Ows6iKE"
- "DMZ+39wUCgVKabTXxNe+4zgjIyMGY8VS6eT0NOr6vs8Yu7u7+7K6SggJuQMbCud8eHjYYGxz"
- "c3N/f19RlJDb6/V0Xb+/v8/n829ofZzzVCqlz82dn5//abUk6UmyEEIIkc1k2u32r3o9uCq8"
- "+PHJsuz7vud5IfTffABZljnnwejLnb9/grEiQih2vVd9J36kup4fH+w3/S/QvwejQg8ibHgo"
- "AAAAAElFTkSuQmCC")
- #----------------------------------------------------------------------
- ZoomOut = PyEmbeddedImage(
- "iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAIAAAD9b0jDAAAAA3NCSVQICAjb4U/gAAACmUlE"
- "QVRIieXVz0sbQRQH8NmdH8smh3jwEIIlB+tNEW1NVps0WxPBv0BQXKQx4N2/xR2xTYQ9iIHc"
- "/A+shyqevHiQVBGLeqgoxM1kNjHTQ8DayWb14KX0Hfe9+fDd4bGr/Ly4AK9d6quL/y6qKIqm"
- "aQHThBBVfT7HnwlFUTjn3/f3MUKKoviMqurh4WG9XkcIvRQVQoRCodPT0+1yWdO0bhchxD2v"
- "WCxyzjHGL0IBAA8PD9biIgDAcRxN06Q39Tzvk2kahmHbNmMswP3rmBCi0WhYlkUI2dzcxBhL"
- "ruu6mUwmnU6v2bbrur1c+dY77sLCQjgcLpVKGKFuN5VKmaZpU1qr1Qghz6OP7vz8fF9f39di"
- "Efq5H6amcrkcpfTu7q7b9d8PIQRjbG5urr+//8vGBoSw200mErOzs3R9/fb2VnLh6uqqrwsA"
- "aLVao6OjV9fX3/b2RkZGJLfZbMbj8UgkUqlU3g4NhcNhIURQ0k612+12u/1ufPxHtcoY6157"
- "z/OGh4fv7++vLi8hhI/Pg9ZY1/Xz83PHcVZWViKRSLPZfNpFCHmeRynNZrNjY2ONRuOx1TOp"
- "rutnZ2eO41iWNTg4KIkYY875mm2/n5iYnp5+KvZMqut6tVrd2tpaWlqKx+OMMUmsM0YpnZqc"
- "NE3TdV3puA+q6/rJycl2ufw5n38zMCClwBjXXdem9GMmk06lukUfNBQKHR8fVyqVwvJyLBaT"
- "REJIrVbr3KNhGL6ijGKMj46OdnZ2CoVCNBqVRAjhr5ubUqmUm5kxksleIpA+fYyxg4ODfD4f"
- "jUY559IohHB3dzebzSYTiQARAKA8/fEJIVRVhRC2Wi3faSEEIUTahKCknbAAgF4iAEBV1WdF"
- "Ge1kCZgO7vZEX6X+c/Q3Qy8zmmCLWqIAAAAASUVORK5CYII=")
- #----------------------------------------------------------------------
- OneTangent = PyEmbeddedImage(
- "iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAIAAAD9b0jDAAAAA3NCSVQICAjb4U/gAAACKUlE"
- "QVRIia2Wz2saURDH5/3Yt6aVsE3SomArGO0phxCSU6A2EFgSklP+qPwrXkOQkBCoaG8eQrBQ"
- "KRYVU1tabUij3V1337weAtZI1FX3e9qF2c/OzJv9zpKbRgMGRAhRSsF8oo9uOCeUMk0LDEo1"
- "rVUuF46Pv2SzhDEgJBhoLZer5/OViwu32yWUjnlsvHj/SrluPJ222m3GORMC5ugsGTwoyjkT"
- "4nuxeFetvj06ko4zG/RRjeh5rmVFNjeZrt8UCnxhIQAoAIBSnm0n9vb+1Gq/y2Wm60FAAUAp"
- "UGr18LCRz9vtNuH8iZipoQAopW4Yb3Z2vmazgDjtJIyMlo7zIpUyksnq2RkTIhgoAHiWFdve"
- "RsTmx4IuNP/ZToiUvV7CNNt3natb61b57cKEMIXIOeu+N0uof5IaEl8f7+R3K1SG8sKc0FqF"
- "oPTjCZOhEiDF0Vyk8da3+occC4UCgAKAAhBe73X6Xa/T+VEs8klcv0eKCtD1kgcHP6+v7xsN"
- "OtZzp5hqhUh1PbG/Xz0/l5ZFGAsACgDous+j0cjWVuX0lI428qmdWNr2q/X10NJS/fJyVHNn"
- "sXfPtuO7u39brV+lkgiHmRBDKZOhbepThDHpOJ8zmZ7jLMZiq6YJhPSXxYyLSEkZMgx9ebl8"
- "clLKZO6bTTbgkFN7ZV+e47xcW4tubIQjkWcrKyjl/zpmK/9BlDH0vIfZUogBZAoAKCWhVCk1"
- "tHrnggLAk/9I/wC0eekA1bLbIQAAAABJRU5ErkJggg==")
- #----------------------------------------------------------------------
- TwoTangents = PyEmbeddedImage(
- "iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAIAAAD9b0jDAAAAA3NCSVQICAjb4U/gAAACL0lE"
- "QVRIie3UzU8TQRQA8DczO1vatRgh1YhWD/WD+kG91FgOXLhx4+CpiYnE9L8g/gVwJHhp4lUP"
- "pPHgQRMOGiEaDabV1LRAtdjUAG23m3W/Znc8YEo/trRNOGjCO+7M++3MezODdopFOO7Axy6e"
- "oC0oAqAEY4QGyCcE4faVtaII7dQUy7b7dDEheq3GdB0R4o76KH2+kZ158uzxyzcO56iXS0Rx"
- "N5tdnZ9fW1w0FaXZPUQxRl/Le7+q8mruh2paQsem2kLweCq5XGVrq7K5adTruGk+ahx+AeOS"
- "rLz4ktctdtYvPYje0i3Gu22cUr1a3VheHg6FhoPBC9EoBwDO21EOQDH2igIALL39NOrz3r8z"
- "rppWp3jQmQ8LC5enp4NTU0zTmGG0/PJwKgBzHEU3VcN6eHfie7X++ltBEmknSoaG0snkSDg8"
- "Njmp12ptIrieU4dzAEjEIu8KPz8Wy14qNI9SScqvrHCA67Ozlqq6F8f1K3McL6WPYpFUOre9"
- "L3uEv50VfL7S+vpuJjMxN8cMo1HEvlAAMG37nF+KR28+fZ/e/62JBAuiWC8U8qlUJJFAhHDH"
- "6ZZ71LnRLXY1MDJzI5Rc+6wwR5PlTDIZjsd9gYBjuTSwEajneypR4dV2qXxq1F/dG5fLodg9"
- "U9OOThGOHgYAg7FrF8fKKqjng/4rl+xeYl+ozeEMsNsiwmCftnnXQg6EcgABICxyAGAcut2x"
- "wdADt+uFdYv/9OU/Qf9d9A9dhOgRU8MmewAAAABJRU5ErkJggg==")
- #----------------------------------------------------------------------
- class GraphEditorWindow(wx.Window):
- """
- This is the main graph editor window.
- """
- def __init__(self, parent, windowSize, property, xRange, yRange, curFrame, object):
- wx.Window.__init__(self, parent, size = windowSize, style = wx.SUNKEN_BORDER)
- self._mainDialog = wx.GetTopLevelParent(self)
- self.w,self.h = self.GetClientSize()
- self.zoom = 2.0
- self._mouseIn = False
- self._selectRec = False
- self._selectHandler = False
- self._OneTangent = True
- self.object = object
- self.curFrame = curFrame
- self.property = property
- self.zeroPos = (0.0, self.h / 2.0)
- self.zero = 0
- self.unitWidth = self.w / float(xRange)
- self.unitHeight = self.h / float(yRange)
- self.generateInfo()
- self.InitBuffer()
- self.Bind(wx.EVT_PAINT, self.OnPaint)
- self.Bind(wx.EVT_SIZE, self.OnSize)
- self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
- self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
- self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown)
- self.Bind(wx.EVT_MIDDLE_UP, self.OnMiddleUp)
- self.Bind(wx.EVT_MOTION, self.OnMotion)
- def refresh(self):
- self._mouseIn = False
- self._selectRec = False
- self._selectHandler = False
- self.generateInfo()
- def generateInfo(self):
- #generate the information for animation curve generation
- self.X = []
- self.Y = []
- self.Z = []
- if self._mainDialog.editor.animMgr.keyFramesInfo != {}:
- self.keyFramesInfo = self._mainDialog.editor.animMgr.keyFramesInfo
- for key in self.keyFramesInfo:
- if key == (self.object[OG.OBJ_UID], 'X'):
- for i in range(len(self.keyFramesInfo[key])):
- item = self.keyFramesInfo[key][i]
- handler = self.generateHandler(item)
- self.X.append([key, i, handler[0], handler[1], handler[2], handler[3], handler[4]])
- if key == (self.object[OG.OBJ_UID], 'Y'):
- for i in range(len(self.keyFramesInfo[key])):
- item = self.keyFramesInfo[key][i]
- handler = self.generateHandler(item)
- self.Y.append([key, i, handler[0], handler[1], handler[2], handler[3], handler[4]])
- if key == (self.object[OG.OBJ_UID], 'Z'):
- for i in range(len(self.keyFramesInfo[key])):
- item = self.keyFramesInfo[key][i]
- handler = self.generateHandler(item)
- self.Z.append([key, i, handler[0], handler[1], handler[2], handler[3], handler[4]])
- def generateHandler(self, item):
- #generate the position for the control handler
- x1 = self.zeroPos[0] + float(item[AG.FRAME])*self.unitWidth
- y1 = self.zeroPos[1] - float(item[AG.VALUE])*self.unitHeight
- t1x = item[AG.INSLOPE][0]*self.unitWidth
- t1y = item[AG.INSLOPE][1]*self.unitHeight
- t2x = item[AG.OUTSLOPE][0]*self.unitWidth
- t2y = item[AG.OUTSLOPE][1]*self.unitHeight
- tanA = t1y / t1x
- temp1 = 1.0 / (tanA ** 2 + 1)
- if t1x < 0:
- cosA = -math.sqrt(abs(temp1))
- if t1x >= 0:
- cosA = math.sqrt(abs(temp1))
- temp2 = (tanA ** 2) * temp1
- if t1y < 0:
- sinA = -math.sqrt(abs(temp2))
- if t1y >= 0:
- sinA = math.sqrt(abs(temp2))
- x2 = x1-float(self.unitWidth*self.zoom)*cosA
- y2 = y1+float(self.unitWidth*self.zoom)*sinA
- tanA = t2y / t2x
- temp1 = 1.0 / (tanA ** 2 + 1)
- if t2x < 0:
- cosA = -math.sqrt(abs(temp1))
- if t2x >= 0:
- cosA = math.sqrt(abs(temp1))
- temp2 = (tanA ** 2) * temp1
- if t2y < 0:
- sinA = -math.sqrt(abs(temp2))
- if t2y >= 0:
- sinA = math.sqrt(abs(temp2))
- x3 = x1+float(self.unitWidth*self.zoom)*cosA
- y3 = y1-float(self.unitWidth*self.zoom)*sinA
- return [[(x1,y1),0],[(x2,y2),0],[(x3,y3),0],[t1x,t1y],[t2x,t2y]]
- def InitBuffer(self):
- self.buffer = wx.EmptyBitmap(self.w, self.h)
- dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
- self.DrawXCoord(dc)
- self.DrawYCoord(dc)
- self.DrawFrame(dc)
- self.DrawCurve(dc)
- self.DrawSelectRec(dc)
- def SetGraphEditorData(self, property, curFrame = 1):
- self.curFrame = curFrame
- self.property = property
- self.InitBuffer()
- def OnPaint(self, evt):
- dc = wx.BufferedPaintDC(self, self.buffer)
- def DrawXCoord(self,dc):
- dc.SetBackground(wx.Brush(wx.Colour(200, 200, 200)))
- dc.Clear()
- dc.SetPen(wx.BLACK_PEN)
- dc.SetBrush(wx.BLACK_BRUSH)
- dc.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL))
- dc.DrawLine(self.zeroPos[0], 0.0, self.zeroPos[0], self.h)
- st = str(self.zero)
- self.tw,self.th = dc.GetTextExtent(st)
- dc.DrawText(st, self.zeroPos[0]+1.0, self.h-self.th-0.5)
- dc.SetPen(wx.Pen(wx.Colour(150, 150, 150)))
- dc.SetBrush(wx.Brush(wx.Colour(150, 150, 150)))
- if self.unitWidth >= 25:
- posPos = self.zeroPos[0]+self.unitWidth
- posNum = self.zero + 1
- while posPos <= self.w:
- dc.DrawLine(posPos, 0.0, posPos, self.h)
- st = str(posNum)
- self.drawXNumber(dc, st, posPos)
- posPos += self.unitWidth
- posNum += 1
- negPos = self.zeroPos[0]-self.unitWidth
- negNum = self.zero - 1
- while negPos >= 0.0:
- dc.DrawLine(negPos, 0.0, negPos, self.h)
- st = str(negNum)
- self.drawXNumber(dc, st, negPos)
- negPos -= self.unitWidth
- posNum -= 1
- elif self.unitWidth >= 10 and self.unitWidth <= 25:
- posPos = self.zeroPos[0]+self.unitWidth*2.0
- posNum = self.zero + 2
- while posPos <= self.w:
- dc.DrawLine(posPos, 0.0, posPos, self.h)
- st = str(posNum)
- self.drawXNumber(dc, st, posPos)
- posPos += self.unitWidth*2.0
- posNum += 2
- negPos = self.zeroPos[0]-self.unitWidth*2.0
- negNum = self.zero - 2
- while negPos >= 0.0:
- dc.DrawLine(negPos, 0.0, negPos, self.h)
- st = str(negNum)
- self.drawXNumber(dc, st, negPos)
- negPos -= self.unitWidth*2.0
- posNum -= 2
- elif self.unitWidth >= 2 and self.unitWidth <= 10:
- posPos = self.zeroPos[0]+self.unitWidth*float(5)
- posNum = self.zero + 5
- while posPos <= self.w:
- dc.DrawLine(posPos, 0.0, posPos, self.h)
- st = str(posNum)
- self.drawXNumber(dc, st, posPos)
- posPos += self.unitWidth*float(5)
- posNum += 5
- negPos = self.zeroPos[0]-self.unitWidth*float(5)
- negNum = self.zero - 5
- while negPos >= 0.0:
- dc.DrawLine(negPos, 0.0, negPos, self.h)
- st = str(negNum)
- self.drawXNumber(dc, st, negPos)
- negPos -= self.unitWidth*float(5)
- posNum -= 5
- def DrawYCoord(self,dc):
- dc.SetPen(wx.BLACK_PEN)
- dc.SetBrush(wx.BLACK_BRUSH)
- dc.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL))
- dc.DrawLine(0.0, self.zeroPos[1], self.w, self.zeroPos[1])
- st = str(self.zero)
- dc.DrawText(st, 5.0, self.zeroPos[1]-1.0)
- dc.SetPen(wx.Pen(wx.Colour(150, 150, 150)))
- dc.SetBrush(wx.Brush(wx.Colour(150, 150, 150)))
- dc.SetLogicalFunction(wx.AND)
- posPos = self.zeroPos[1]-self.unitHeight*float(5)
- posNum = self.zero + 5
- while posPos >= 0.0:
- dc.DrawLine(0.0, posPos, self.w, posPos)
- st = str(posNum)
- self.drawYNumber(dc, st, posPos)
- posPos -= self.unitHeight*float(5)
- posNum += 5
- negPos = self.zeroPos[1]+self.unitHeight*float(5)
- negNum = self.zero - 5
- while negPos <= self.h:
- dc.DrawLine(0.0, negPos, self.w, negPos)
- st = str(negNum)
- self.drawYNumber(dc, st, negPos)
- negPos += self.unitHeight*float(5)
- negNum -= 5
- def drawXNumber(self, dc, st, pos):
- oldPen, oldBrush, oldMode = dc.GetPen(), dc.GetBrush(), dc.GetLogicalFunction()
- dc.SetPen(wx.BLACK_PEN)
- dc.SetBrush(wx.BLACK_BRUSH)
- dc.DrawText(st, pos+1.0, self.h-self.th-0.5)
- dc.SetPen(oldPen)
- dc.SetBrush(oldBrush)
- dc.SetLogicalFunction(oldMode)
- def drawYNumber(self, dc, st, pos):
- oldPen, oldBrush, oldMode = dc.GetPen(), dc.GetBrush(), dc.GetLogicalFunction()
- dc.SetPen(wx.BLACK_PEN)
- dc.SetBrush(wx.BLACK_BRUSH)
- dc.DrawText(st, 5.0, pos-1.0)
- dc.SetPen(oldPen)
- dc.SetBrush(oldBrush)
- dc.SetLogicalFunction(oldMode)
- def DrawFrame(self, dc):
- if self._mainDialog.editor.mode == self._mainDialog.editor.ANIM_MODE:
- curFramePos = self.zeroPos[0]+self.curFrame*self.unitWidth
- dc.SetPen(wx.Pen("red"))
- dc.SetBrush(wx.Brush("red"))
- dc.DrawLine(curFramePos, 0.0, curFramePos, self.h)
- else:
- pass
- def drawX(self, dc):
- dc.SetPen(wx.Pen("red"))
- dc.SetBrush(wx.Brush("red"))
- self.drawSingleCurve(self.X, dc)
- self.drawKeys(self.X, dc)
- self.drawHandler(self.X, dc)
- def drawY(self, dc):
- dc.SetPen(wx.Pen("green"))
- dc.SetBrush(wx.Brush("green"))
- self.drawSingleCurve(self.Y, dc)
- self.drawKeys(self.Y, dc)
- self.drawHandler(self.Y, dc)
- def drawZ(self, dc):
- dc.SetPen(wx.Pen("blue"))
- dc.SetBrush(wx.Brush("blue"))
- self.drawSingleCurve(self.Z, dc)
- self.drawKeys(self.Z, dc)
- self.drawHandler(self.Z, dc)
- def DrawCurve(self, dc):
- if self.property == self._mainDialog.namestr:
- self.drawX(dc)
- self.drawY(dc)
- self.drawZ(dc)
- return
- if self.property == property[AG.X]:
- self.drawX(dc)
- return
- if self.property == property[AG.Y]:
- self.drawY(dc)
- return
- if self.property == property[AG.Z]:
- self.drawZ(dc)
- return
- def drawSingleCurve(self, list, dc):
- if len(list) == 1:
- dc.DrawPoint(list[0][AG.KEYFRAME][AG.LOCAL_VALUE][0], list[0][AG.KEYFRAME][AG.LOCAL_VALUE][1])
- return
- if len(list) == 2:
- dc.DrawLine(list[0][AG.KEYFRAME][AG.LOCAL_VALUE][0], list[0][AG.KEYFRAME][AG.LOCAL_VALUE][1], list[1][AG.KEYFRAME][AG.LOCAL_VALUE][0], list[1][AG.KEYFRAME][AG.LOCAL_VALUE][1])
- return
- if len(list)>=3 :
- for i in range(len(list)-1):
- x1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]
- y1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]
- x4 = list[i+1][AG.KEYFRAME][AG.LOCAL_VALUE][0]
- y4 = list[i+1][AG.KEYFRAME][AG.LOCAL_VALUE][1]
- t1x = list[i][AG.OUT_SLOPE][0]
- t1y = list[i][AG.OUT_SLOPE][1]
- t2x = list[i+1][AG.IN_SLOPE][0]
- t2y = list[i+1][AG.IN_SLOPE][1]
- x2 = x1 + (x4 - x1) / 3.0
- scale1 = (x2 - x1) / t1x
- y2 = y1 - t1y * scale1
- x3 = x4 - (x4 - x1) / 3.0
- scale2 = (x4 - x3) / t2x
- y3 = y4 + t2y * scale2
- ax = - 1.0 * x1 + 3.0 * x2 - 3.0 * x3 + 1.0 * x4
- bx = 3.0 * x1 - 6.0 * x2 + 3.0 * x3 + 0.0 * x4
- cx = - 3.0 * x1 + 3.0 * x2 + 0.0 * x3 + 0.0 * x4
- dx = 1.0 * x1 + 0.0 * x2 - 0.0 * x3 + 0.0 * x4
- ay = - 1.0 * y1 + 3.0 * y2 - 3.0 * y3 + 1.0 * y4
- by = 3.0 * y1 - 6.0 * y2 + 3.0 * y3 + 0.0 * y4
- cy = - 3.0 * y1 + 3.0 * y2 + 0.0 * y3 + 0.0 * y4
- dy = 1.0 * y1 + 0.0 * y2 - 0.0 * y3 + 0.0 * y4
- preX = x1
- preY = y1
- t = 0.001
- while t <= 1.0:
- x = ax * t*t*t + bx * t*t + cx * t + dx
- y = ay * t*t*t + by * t*t + cy * t + dy
- curX = x
- curY = y
- dc.DrawLine(preX, preY, curX, curY)
- preX = curX
- preY = curY
- t += 0.001
- def drawKeys(self, list, dc):
- for i in range(len(list)):
- pointX = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]
- pointY = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]
- if list[i][AG.KEYFRAME][AG.SELECT] == 0:
- dc.SetPen(wx.Pen("black",3))
- dc.SetBrush(wx.Brush("black"))
- dc.DrawCircle(pointX, pointY, 2)
- if list[i][AG.KEYFRAME][AG.SELECT] == 1:
- dc.SetPen(wx.Pen("cyan",3))
- dc.SetBrush(wx.Brush("cyan"))
- dc.DrawCircle(pointX, pointY, 2)
- def drawHandler(self, list, dc):
- for i in range(len(list)):
- if list[i][AG.KEYFRAME][AG.SELECT] == 1:
- X1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]
- Y1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]
- if self._OneTangent == True:
- for j in range(3,5):
- X = list[i][j][AG.LOCAL_VALUE][0]
- Y = list[i][j][AG.LOCAL_VALUE][1]
- if list[i][j][AG.SELECT] == 1:
- dc.SetPen(wx.Pen("cyan",3))
- dc.SetBrush(wx.Brush("cyan"))
- dc.DrawCircle(X, Y, 2)
- dc.SetPen(wx.Pen("cyan",1))
- dc.DrawLine(X1, Y1, X, Y)
- if list[i][j][AG.SELECT] == 0:
- dc.SetPen(wx.Pen("brown",3))
- dc.SetBrush(wx.Brush("brown"))
- dc.DrawCircle(X, Y, 2)
- dc.SetPen(wx.Pen("brown",1))
- dc.DrawLine(X1, Y1, X, Y)
- if self._OneTangent == False:
- if list[i][AG.IN_TANGENT][AG.SELECT] == 1:
- X = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][0]
- Y = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][1]
- dc.SetPen(wx.Pen("cyan",3))
- dc.SetBrush(wx.Brush("cyan"))
- dc.DrawCircle(X, Y, 2)
- dc.SetPen(wx.Pen("cyan",1))
- dc.DrawLine(X1, Y1, X, Y)
- if list[i][AG.IN_TANGENT][AG.SELECT] == 0:
- X = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][0]
- Y = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][1]
- dc.SetPen(wx.Pen("navy",3))
- dc.SetBrush(wx.Brush("navy"))
- dc.DrawCircle(X, Y, 2)
- dc.SetPen(wx.Pen("navy",1))
- dc.DrawLine(X1, Y1, X, Y)
- if list[i][AG.OUT_TANGENT][AG.SELECT] == 1:
- X = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][0]
- Y = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][1]
- dc.SetPen(wx.Pen("cyan",3))
- dc.SetBrush(wx.Brush("cyan"))
- dc.DrawCircle(X, Y, 2)
- dc.SetPen(wx.Pen("cyan",1))
- dc.DrawLine(X1, Y1, X, Y)
- if list[i][AG.OUT_TANGENT][AG.SELECT] == 0:
- X = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][0]
- Y = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][1]
- dc.SetPen(wx.Pen("brown",3))
- dc.SetBrush(wx.Brush("brown"))
- dc.DrawCircle(X, Y, 2)
- dc.SetPen(wx.Pen("brown",1))
- dc.DrawLine(X1, Y1, X, Y)
- def DrawSelectRec(self, dc):
- if self._selectRec == True:
- dc.SetPen(wx.Pen("navy", 1))
- dc.SetBrush(wx.Brush("navy"))
- ## dc.SetLogicalFunction(wx.AND)
- dc.DrawLine(self.pos[0], self.pos[1], self.pos[0], self.newPos[1])
- dc.DrawLine(self.pos[0], self.pos[1], self.newPos[0], self.pos[1])
- dc.DrawLine(self.newPos[0], self.newPos[1], self.pos[0], self.newPos[1])
- dc.DrawLine(self.newPos[0], self.newPos[1], self.newPos[0], self.pos[1])
- def OnSize(self,evt):
- self.InitBuffer()
- def OnLeftDown(self,evt):
- point = (evt.GetX(), evt.GetY())
- if point[1]>= 0.0 and point[1]<= float(self.h):
- if point[0]>= 0.0 and point[0]<= float(self.w):
- self._mouseIn = True
- if self._mouseIn:
- self.CaptureMouse()
- self.pos = point
- def OnLeftUp(self,evt):
- if self.GetCapture():
- self.ReleaseMouse()
- self._mouseIn = False
- self._selectRec = False
- self.setSelection()
- self.SetGraphEditorData(self.property, self.curFrame)
- def OnMiddleDown(self,evt):
- point = (evt.GetX(), evt.GetY())
- if point[1]>= 0.0 and point[1]<= float(self.h):
- if point[0]>= 0.0 and point[0]<= float(self.w):
- self._mouseIn = True
- if self._mouseIn:
- self.CaptureMouse()
- self.midPos = point
- def OnMiddleUp(self, evt):
- if self.GetCapture():
- self.ReleaseMouse()
- def OnMotion(self,evt):
- self._mouseIn = False
- if evt.Dragging() and evt.LeftIsDown():
- self.newPos = (evt.GetX(), evt.GetY())
- if self.newPos[1]>= 0.0 and self.newPos[1]<= float(self.h):
- if self.newPos[0]>= 0.0 and self.newPos[0]<= float(self.w):
- self._mouseIn = True
- if self._mouseIn:
- if self.newPos == self.pos:
- evt.Skip()
- self._mouseIn = False
- else:
- self._selectRec = True
- self.SetGraphEditorData(self.property, self.curFrame)
- if evt.Dragging() and evt.MiddleIsDown():
- self.newMidPos = (evt.GetX(), evt.GetY())
- if self.newMidPos[1]>= 0.0 and self.newMidPos[1]<= float(self.h):
- if self.newMidPos[0]>= 0.0 and self.newMidPos[0]<= float(self.w):
- self._mouseIn = True
- if self._mouseIn:
- if self.newMidPos == self.midPos:
- evt.Skip()
- self._mouseIn = False
- else:
- self.recalculateSlope()
- self.onAnimation()
- self.midPos = self.newMidPos
- evt.Skip()
- self._mouseIn = False
- self._selectRec = False
- def setExistKey(self, list):
- flag = False
- for i in range(len(list)):
- if list[i][AG.KEYFRAME][AG.SELECT] == 1:
- inside = self.inside(self.pos, self.newPos, (list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0], list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]))
- if inside == True:
- list[i][AG.KEYFRAME][AG.SELECT] = 0
- if inside == False:
- find = False
- for j in range(3,5):
- inside = self.inside(self.pos, self.newPos, (list[i][j][AG.LOCAL_VALUE][0], list[i][j][AG.LOCAL_VALUE][1]))
- if inside == False:
- list[i][j][AG.SELECT] = 0
- if inside == True:
- list[i][j][AG.SELECT] = 1
- find = True
- flag = True
- if find == False:
- list[i][AG.KEYFRAME][AG.SELECT] == 0
- return flag
- def setNewKey(self, list):
- for i in range(len(list)):
- inside = self.inside(self.pos, self.newPos, (list[i][2][0][0], list[i][2][0][1]))
- if inside == True:
- list[i][AG.KEYFRAME][AG.SELECT] = 1
- if inside == False:
- list[i][AG.KEYFRAME][AG.SELECT] = 0
- def setSelection(self):
- if self.property == self._mainDialog.namestr:
- self.setSelectionBase(self.X)
- self.setSelectionBase(self.Y)
- self.setSelectionBase(self.Z)
- return
- if self.property == property[AG.X]:
- self.setSelectionBase(self.X)
- return
- if self.property == property[AG.Y]:
- self.setSelectionBase(self.Y)
- return
- if self.property == property[AG.Z]:
- self.setSelectionBase(self.Z)
- return
- def setSelectionBase(self, list):
- self.setExistKey(list)
- if self.setExistKey(list) == True:
- return
- else:
- self.setNewKey(list)
- def inside(self, point0, point1, point):
- if point0[0]<=point1[0] and point0[1]<=point1[1]:
- if point0[0]<point[0] and point[0]<point1[0] and point0[1]<point[1] and point[1]<point1[1]:
- return True
- else:
- return False
- elif point1[0]<=point0[0] and point0[1]<=point1[1]:
- if point1[0]<point[0] and point[0]<point0[0] and point0[1]<point[1] and point[1]<point1[1]:
- return True
- else:
- return False
- elif point0[0]<=point1[0] and point1[1]<=point0[1]:
- if point0[0]<point[0] and point[0]<point1[0] and point1[1]<point[1] and point[1]<point0[1]:
- return True
- else:
- return False
- elif point1[0]<=point0[0] and point1[1]<=point0[1]:
- if point1[0]<point[0] and point[0]<point0[0] and point1[1]<point[1] and point[1]<point0[1]:
- return True
- else:
- return False
- else:
- return False
- def recalculateSlope(self):
- if self.property == self._mainDialog.namestr:
- self.recalculateSlopeBase(self.X)
- self.recalculateSlopeBase(self.Y)
- self.recalculateSlopeBase(self.Z)
- return
- if self.property == property[AG.X]:
- self.recalculateSlopeBase(self.X)
- return
- if self.property == property[AG.Y]:
- self.recalculateSlopeBase(self.Y)
- return
- if self.property == property[AG.Z]:
- self.recalculateSlopeBase(self.Z)
- return
- def recalculateSlopeBase(self, list):
- #recalculate the tangent slope
- moveX = self.newMidPos[0]-self.midPos[0]
- moveY = self.newMidPos[1]-self.midPos[1]
- for i in range(len(list)):
- if list[i][AG.KEYFRAME][AG.SELECT] == 1:
- if list[i][AG.IN_TANGENT][AG.SELECT] == 1:
- newPointX = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][0] + moveX
- newPointY = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][1] + moveY
- newSlope = [list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0] - newPointX , newPointY - list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]]
- temp0 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][0]
- temp1 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][1]
- self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][0] = newSlope[0]/self.unitWidth
- self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][1] = newSlope[1]/self.unitHeight
- handler = self.generateHandler(self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]])
- if handler[1][0][0]>= list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]:
- self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][0] = temp0
- self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][1] = temp1
- return
- if handler[1][0][0] < list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]:
- if self._OneTangent == False:
- list[i][AG.IN_TANGENT][0] = handler[1][0]
- list[i][AG.IN_SLOPE][0] = handler[3][0]
- list[i][AG.IN_SLOPE][1] = handler[3][1]
- if self._OneTangent == True:
- self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][0] = newSlope[0]/self.unitWidth
- self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][1] = newSlope[1]/self.unitHeight
- handler = self.generateHandler(self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]])
- list[i][AG.IN_TANGENT][0] = handler[1][0]
- list[i][AG.OUT_TANGENT][0] = handler[2][0]
- list[i][AG.IN_SLOPE][0] = handler[3][0]
- list[i][AG.IN_SLOPE][1] = handler[3][1]
- list[i][AG.OUT_SLOPE][0] = handler[4][0]
- list[i][AG.OUT_SLOPE][1] = handler[4][1]
- self.SetGraphEditorData(self.property, self.curFrame)
- if list[i][AG.OUT_TANGENT][AG.SELECT] == 1:
- newPointX = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][0] + moveX
- newPointY = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][1] + moveY
- newSlope = [newPointX - list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0] , list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1] - newPointY]
- temp0 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][0]
- temp1 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][1]
- self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][0] = newSlope[0]/self.unitWidth
- self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][1] = newSlope[1]/self.unitHeight
- handler = self.generateHandler(self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]])
- if handler[2][0][0] <= list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]:
- self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][0] = temp0
- self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][1] = temp1
- return
- if handler[2][0][0] > list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]:
- if self._OneTangent == False:
- list[i][AG.OUT_TANGENT][0] = handler[2][0]
- list[i][AG.OUT_SLOPE][0] = handler[4][0]
- list[i][AG.OUT_SLOPE][1] = handler[4][1]
- if self._OneTangent == True:
- self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][0] = newSlope[0]/self.unitWidth
- self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][1] = newSlope[1]/self.unitHeight
- handler = self.generateHandler(self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]])
- list[i][AG.IN_TANGENT][0] = handler[1][0]
- list[i][AG.OUT_TANGENT][0] = handler[2][0]
- list[i][AG.IN_SLOPE][0] = handler[3][0]
- list[i][AG.IN_SLOPE][1] = handler[3][1]
- list[i][AG.OUT_SLOPE][0] = handler[4][0]
- list[i][AG.OUT_SLOPE][1] = handler[4][1]
- self.SetGraphEditorData(self.property, self.curFrame)
- def selectHandler(self):
- self._selectHandler = False
- def onAnimation(self):
- if self._mainDialog.editor.mode == self._mainDialog.editor.ANIM_MODE:
- self._mainDialog.editor.ui.animUI.OnAnimation(self._mainDialog.editor.ui.animUI.curFrame)
- else:
- pass
- class GraphEditorUI(wx.Dialog):
- """
- This is the graph editor main class implementation.
- """
- def __init__(self, parent, editor, object):
- wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title="Graph Editor",
- pos=wx.DefaultPosition, size=(735, 535))
- self.editor = editor
- self.editor.GRAPH_EDITOR = True
- self.object = object
- self.xRange = 24+1
- self.yRange = 50
- if self.editor.mode == self.editor.ANIM_MODE:
- self.curFrame = self.editor.ui.animUI.curFrame
- self.curFrame = 1
- self.mainPanel1 = wx.Panel(self, -1)
- bmpZoomIn = ZoomIn.GetBitmap()
- bmpZoomOut = ZoomOut.GetBitmap()
- bmpOneTangent = OneTangent.GetBitmap()
- bmpTwoTangents = TwoTangents.GetBitmap()
- self.buttonZoomIn = wx.BitmapButton(self.mainPanel1, -1, bmpZoomIn, size = (30,30),style = wx.BU_AUTODRAW)
- self.buttonZoomOut = wx.BitmapButton(self.mainPanel1, -1, bmpZoomOut, size = (30,30),style = wx.BU_AUTODRAW)
- self.buttonOneTangent = wx.BitmapButton(self.mainPanel1, -1, bmpOneTangent, size = (30,30),style = wx.BU_AUTODRAW)
- self.buttonTwoTangents = wx.BitmapButton(self.mainPanel1, -1, bmpTwoTangents, size = (30,30),style = wx.BU_AUTODRAW)
- self.mainPanel2 = wx.Panel(self, -1)
- self.tree = self.tree = wx.TreeCtrl(self.mainPanel2, id=-1, pos=wx.DefaultPosition,size=wx.Size(200, 450), style=wx.TR_MULTIPLE|wx.TR_DEFAULT_STYLE,validator=wx.DefaultValidator, name="treeCtrl")
- self.namestr = "%s"%(object[OG.OBJ_DEF].name)
- self.root = self.tree.AddRoot(self.namestr)
- self.AddTreeNodes(self.root, property)
- self.tree.Expand(self.root)
- self.tree.SelectItem(self.root,select=True)
- self.str = self.tree.GetItemText(self.root)
- self.graphEditorWindow =GraphEditorWindow(self.mainPanel2, wx.Size(500, 450), str(object[OG.OBJ_DEF].name), self.xRange, self.yRange, self.curFrame, self.object)
- self.SetProperties()
- self.DoLayout()
- self.Bind(wx.EVT_BUTTON, self.OnZoomIn, self.buttonZoomIn)
- self.Bind(wx.EVT_BUTTON, self.OnZoomOut, self.buttonZoomOut)
- self.Bind(wx.EVT_BUTTON, self.OnOneTangent, self.buttonOneTangent)
- self.Bind(wx.EVT_BUTTON, self.OnTwoTangents, self.buttonTwoTangents)
- self.Bind(wx.EVT_CLOSE, self.OnExit)
- self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged)
- def SetProperties(self):
- pass
- def DoLayout(self):
- dialogSizer = wx.BoxSizer(wx.VERTICAL)
- mainSizer1 = wx.FlexGridSizer(1, 4, 0, 0)
- mainSizer2 = wx.FlexGridSizer(1, 2, 0, 0)
- mainSizer1.Add(self.buttonOneTangent, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 570)
- mainSizer1.Add(self.buttonTwoTangents, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 10)
- mainSizer1.Add(self.buttonZoomIn, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 10)
- mainSizer1.Add(self.buttonZoomOut, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 10)
- mainSizer2.Add(self.tree, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 10)
- mainSizer2.Add(self.graphEditorWindow, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 10)
- self.mainPanel1.SetSizerAndFit(mainSizer1)
- self.mainPanel2.SetSizer(mainSizer2)
- dialogSizer.Add(self.mainPanel2, 0, wx.ALIGN_CENTER_VERTICAL|wx.TOP, 10)
- dialogSizer.Add(self.mainPanel1, 0, wx.ALIGN_CENTER_VERTICAL|wx.TOP, 5)
- self.SetSizer(dialogSizer)
- self.Layout()
- self.dialogSizer = dialogSizer
- def AddTreeNodes(self, parentItem, items):
- for item in items:
- if type(item) == str:
- self.tree.AppendItem(parentItem, item)
- def OnSelChanged(self, evt):
- item = evt.GetItem()
- if item:
- self.str = self.tree.GetItemText(item)
- self.graphEditorWindow.refresh()
- self.graphEditorWindow.SetGraphEditorData(self.str, self.curFrame)
- def OnZoomIn(self,evt):
- self.graphEditorWindow.zoom = self.graphEditorWindow.zoom/float(1.2)
- self.graphEditorWindow.unitWidth = self.graphEditorWindow.unitWidth*float(1.2)
- self.graphEditorWindow.unitHeight = self.graphEditorWindow.unitHeight*float(1.2)
- self.graphEditorWindow.generateInfo()
- self.graphEditorWindow.SetGraphEditorData(self.str, self.curFrame)
- def OnZoomOut(self,evt):
- self.graphEditorWindow.zoom = self.graphEditorWindow.zoom*float(1.2)
- self.graphEditorWindow.unitWidth = self.graphEditorWindow.unitWidth/float(1.2)
- self.graphEditorWindow.unitHeight = self.graphEditorWindow.unitHeight/float(1.2)
- self.graphEditorWindow.generateInfo()
- self.graphEditorWindow.SetGraphEditorData(self.str, self.curFrame)
- def OnOneTangent(self,evt):
- self.graphEditorWindow._OneTangent = True
- self.graphEditorWindow.SetGraphEditorData(self.str, self.curFrame)
- def OnTwoTangents(self,evt):
- self.graphEditorWindow._OneTangent = False
- self.graphEditorWindow.SetGraphEditorData(self.str, self.curFrame)
- def curFrameChange(self):
- if self.editor.mode == self.editor.ANIM_MODE:
- self.curFrame = self.editor.ui.animUI.curFrame
- self.graphEditorWindow.SetGraphEditorData(self.str, self.curFrame)
- else:
- pass
- def OnExit(self,evt):
- self.Destroy()
- self.editor.ui.graphEditorMenuItem.Check(False)
- self.object = None
- self.editor.GRAPH_EDITOR = False
|