GraphEditorUI.py 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917
  1. """
  2. Defines Graph Editor
  3. """
  4. import wx
  5. import math
  6. from .PaletteTreeCtrl import *
  7. from . import ObjectGlobals as OG
  8. from . import AnimGlobals as AG
  9. from wx.lib.embeddedimage import PyEmbeddedImage
  10. property = [
  11. "translateX",
  12. "translateY",
  13. "translateZ"
  14. ]
  15. #----------------------------------------------------------------------
  16. ZoomIn = PyEmbeddedImage(
  17. "iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAIAAAD9b0jDAAAAA3NCSVQICAjb4U/gAAACgklE"
  18. "QVRIid3VW0vjQBQA4DlJMziZlCKCSB/9Bf4a3wRtNU6SHyXK6pay2nVbQbasskXFO15SqmwL"
  19. "LtYnn7Zg20zSyT50wZikXsCHxXk9Z74ZZuacgebtLXrvIb27+PFQjDEADIoqiiLL8htQAMAY"
  20. "Hx4dPTw8SHEuIaRWqzWbzUQi8SoUAIaGhgqFgn15SSn1Iwmqqh4fH5c2NpLJpO8/xhORzEeR"
  21. "EJLL5VqtViaT8TxPCBFMoJTu7e1tb28zxpLJpOu6L6D9PS6vrHQ6nWw267puVNzZ2alUKqZh"
  22. "UE0LivFoX/y0vOxynpmZ4ZxHxZ+Vyu7urmmaqqqGxBhUkiSM8eLiIgDMTE87EVHTtB9bW4cH"
  23. "B5ZpEkKiYhjt3/XCwoKiKFNTU47jRPf4vVw+PTmxLAtjHCs+QQEAAJaWljRNm5yc7Ha7wQtF"
  24. "CGGMy+WybduWZSmK4nlerIiCTwoAOOfX19cTExMSgPDDT0iSJNu2x8fHU6nUM+ITVAhBCLFM"
  25. "83MuV63VKCGhVM65ruv1RqNYLFJKX4UihFzXTafTc7Oz+XzerlZVVQ1GhRCyLJuGcXV1VSqV"
  26. "QtGBKEKo6zhjY2Pzur66tnZxcRGa2ev1AMA0zXqj8W3wfmPK1HGc0dFRNj//dX397Ows6iKE"
  27. "DMZ+39wUCgVKabTXxNe+4zgjIyMGY8VS6eT0NOr6vs8Yu7u7+7K6SggJuQMbCud8eHjYYGxz"
  28. "c3N/f19RlJDb6/V0Xb+/v8/n829ofZzzVCqlz82dn5//abUk6UmyEEIIkc1k2u32r3o9uCq8"
  29. "+PHJsuz7vud5IfTffABZljnnwejLnb9/grEiQih2vVd9J36kup4fH+w3/S/QvwejQg8ibHgo"
  30. "AAAAAElFTkSuQmCC")
  31. #----------------------------------------------------------------------
  32. ZoomOut = PyEmbeddedImage(
  33. "iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAIAAAD9b0jDAAAAA3NCSVQICAjb4U/gAAACmUlE"
  34. "QVRIieXVz0sbQRQH8NmdH8smh3jwEIIlB+tNEW1NVps0WxPBv0BQXKQx4N2/xR2xTYQ9iIHc"
  35. "/A+shyqevHiQVBGLeqgoxM1kNjHTQ8DayWb14KX0Hfe9+fDd4bGr/Ly4AK9d6quL/y6qKIqm"
  36. "aQHThBBVfT7HnwlFUTjn3/f3MUKKoviMqurh4WG9XkcIvRQVQoRCodPT0+1yWdO0bhchxD2v"
  37. "WCxyzjHGL0IBAA8PD9biIgDAcRxN06Q39Tzvk2kahmHbNmMswP3rmBCi0WhYlkUI2dzcxBhL"
  38. "ruu6mUwmnU6v2bbrur1c+dY77sLCQjgcLpVKGKFuN5VKmaZpU1qr1Qghz6OP7vz8fF9f39di"
  39. "Efq5H6amcrkcpfTu7q7b9d8PIQRjbG5urr+//8vGBoSw200mErOzs3R9/fb2VnLh6uqqrwsA"
  40. "aLVao6OjV9fX3/b2RkZGJLfZbMbj8UgkUqlU3g4NhcNhIURQ0k612+12u/1ufPxHtcoY6157"
  41. "z/OGh4fv7++vLi8hhI/Pg9ZY1/Xz83PHcVZWViKRSLPZfNpFCHmeRynNZrNjY2ONRuOx1TOp"
  42. "rutnZ2eO41iWNTg4KIkYY875mm2/n5iYnp5+KvZMqut6tVrd2tpaWlqKx+OMMUmsM0YpnZqc"
  43. "NE3TdV3puA+q6/rJycl2ufw5n38zMCClwBjXXdem9GMmk06lukUfNBQKHR8fVyqVwvJyLBaT"
  44. "REJIrVbr3KNhGL6ijGKMj46OdnZ2CoVCNBqVRAjhr5ubUqmUm5kxksleIpA+fYyxg4ODfD4f"
  45. "jUY559IohHB3dzebzSYTiQARAKA8/fEJIVRVhRC2Wi3faSEEIUTahKCknbAAgF4iAEBV1WdF"
  46. "Ge1kCZgO7vZEX6X+c/Q3Qy8zmmCLWqIAAAAASUVORK5CYII=")
  47. #----------------------------------------------------------------------
  48. OneTangent = PyEmbeddedImage(
  49. "iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAIAAAD9b0jDAAAAA3NCSVQICAjb4U/gAAACKUlE"
  50. "QVRIia2Wz2saURDH5/3Yt6aVsE3SomArGO0phxCSU6A2EFgSklP+qPwrXkOQkBCoaG8eQrBQ"
  51. "KRYVU1tabUij3V1337weAtZI1FX3e9qF2c/OzJv9zpKbRgMGRAhRSsF8oo9uOCeUMk0LDEo1"
  52. "rVUuF46Pv2SzhDEgJBhoLZer5/OViwu32yWUjnlsvHj/SrluPJ222m3GORMC5ugsGTwoyjkT"
  53. "4nuxeFetvj06ko4zG/RRjeh5rmVFNjeZrt8UCnxhIQAoAIBSnm0n9vb+1Gq/y2Wm60FAAUAp"
  54. "UGr18LCRz9vtNuH8iZipoQAopW4Yb3Z2vmazgDjtJIyMlo7zIpUyksnq2RkTIhgoAHiWFdve"
  55. "RsTmx4IuNP/ZToiUvV7CNNt3natb61b57cKEMIXIOeu+N0uof5IaEl8f7+R3K1SG8sKc0FqF"
  56. "oPTjCZOhEiDF0Vyk8da3+occC4UCgAKAAhBe73X6Xa/T+VEs8klcv0eKCtD1kgcHP6+v7xsN"
  57. "OtZzp5hqhUh1PbG/Xz0/l5ZFGAsACgDous+j0cjWVuX0lI428qmdWNr2q/X10NJS/fJyVHNn"
  58. "sXfPtuO7u39brV+lkgiHmRBDKZOhbepThDHpOJ8zmZ7jLMZiq6YJhPSXxYyLSEkZMgx9ebl8"
  59. "clLKZO6bTTbgkFN7ZV+e47xcW4tubIQjkWcrKyjl/zpmK/9BlDH0vIfZUogBZAoAKCWhVCk1"
  60. "tHrnggLAk/9I/wC0eekA1bLbIQAAAABJRU5ErkJggg==")
  61. #----------------------------------------------------------------------
  62. TwoTangents = PyEmbeddedImage(
  63. "iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAIAAAD9b0jDAAAAA3NCSVQICAjb4U/gAAACL0lE"
  64. "QVRIie3UzU8TQRQA8DczO1vatRgh1YhWD/WD+kG91FgOXLhx4+CpiYnE9L8g/gVwJHhp4lUP"
  65. "pPHgQRMOGiEaDabV1LRAtdjUAG23m3W/Znc8YEo/trRNOGjCO+7M++3MezODdopFOO7Axy6e"
  66. "oC0oAqAEY4QGyCcE4faVtaII7dQUy7b7dDEheq3GdB0R4o76KH2+kZ158uzxyzcO56iXS0Rx"
  67. "N5tdnZ9fW1w0FaXZPUQxRl/Le7+q8mruh2paQsem2kLweCq5XGVrq7K5adTruGk+ahx+AeOS"
  68. "rLz4ktctdtYvPYje0i3Gu22cUr1a3VheHg6FhoPBC9EoBwDO21EOQDH2igIALL39NOrz3r8z"
  69. "rppWp3jQmQ8LC5enp4NTU0zTmGG0/PJwKgBzHEU3VcN6eHfie7X++ltBEmknSoaG0snkSDg8"
  70. "Njmp12ptIrieU4dzAEjEIu8KPz8Wy14qNI9SScqvrHCA67Ozlqq6F8f1K3McL6WPYpFUOre9"
  71. "L3uEv50VfL7S+vpuJjMxN8cMo1HEvlAAMG37nF+KR28+fZ/e/62JBAuiWC8U8qlUJJFAhHDH"
  72. "6ZZ71LnRLXY1MDJzI5Rc+6wwR5PlTDIZjsd9gYBjuTSwEajneypR4dV2qXxq1F/dG5fLodg9"
  73. "U9OOThGOHgYAg7FrF8fKKqjng/4rl+xeYl+ozeEMsNsiwmCftnnXQg6EcgABICxyAGAcut2x"
  74. "wdADt+uFdYv/9OU/Qf9d9A9dhOgRU8MmewAAAABJRU5ErkJggg==")
  75. #----------------------------------------------------------------------
  76. class GraphEditorWindow(wx.Window):
  77. """
  78. This is the main graph editor window.
  79. """
  80. def __init__(self, parent, windowSize, property, xRange, yRange, curFrame, object):
  81. wx.Window.__init__(self, parent, size = windowSize, style = wx.SUNKEN_BORDER)
  82. self._mainDialog = wx.GetTopLevelParent(self)
  83. self.w,self.h = self.GetClientSize()
  84. self.zoom = float(2)
  85. self._mouseIn = False
  86. self._selectRec = False
  87. self._selectHandler = False
  88. self._OneTangent = True
  89. self.object = object
  90. self.curFrame = curFrame
  91. self.property = property
  92. self.zeroPos = (float(0), self.h/float(2))
  93. self.zero = 0
  94. self.unitWidth = self.w/float(xRange)
  95. self.unitHeight = self.h/float(yRange)
  96. self.generateInfo()
  97. self.InitBuffer()
  98. self.Bind(wx.EVT_PAINT, self.OnPaint)
  99. self.Bind(wx.EVT_SIZE, self.OnSize)
  100. self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
  101. self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
  102. self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown)
  103. self.Bind(wx.EVT_MIDDLE_UP, self.OnMiddleUp)
  104. self.Bind(wx.EVT_MOTION, self.OnMotion)
  105. def refresh(self):
  106. self._mouseIn = False
  107. self._selectRec = False
  108. self._selectHandler = False
  109. self.generateInfo()
  110. def generateInfo(self):
  111. #generate the information for animation curve generation
  112. self.X = []
  113. self.Y = []
  114. self.Z = []
  115. if self._mainDialog.editor.animMgr.keyFramesInfo != {}:
  116. self.keyFramesInfo = self._mainDialog.editor.animMgr.keyFramesInfo
  117. for key in self.keyFramesInfo:
  118. if key == (self.object[OG.OBJ_UID], 'X'):
  119. for i in range(len(self.keyFramesInfo[key])):
  120. item = self.keyFramesInfo[key][i]
  121. handler = self.generateHandler(item)
  122. self.X.append([key, i, handler[0], handler[1], handler[2], handler[3], handler[4]])
  123. if key == (self.object[OG.OBJ_UID], 'Y'):
  124. for i in range(len(self.keyFramesInfo[key])):
  125. item = self.keyFramesInfo[key][i]
  126. handler = self.generateHandler(item)
  127. self.Y.append([key, i, handler[0], handler[1], handler[2], handler[3], handler[4]])
  128. if key == (self.object[OG.OBJ_UID], 'Z'):
  129. for i in range(len(self.keyFramesInfo[key])):
  130. item = self.keyFramesInfo[key][i]
  131. handler = self.generateHandler(item)
  132. self.Z.append([key, i, handler[0], handler[1], handler[2], handler[3], handler[4]])
  133. def generateHandler(self, item):
  134. #generate the position for the control handler
  135. x1 = self.zeroPos[0] + float(item[AG.FRAME])*self.unitWidth
  136. y1 = self.zeroPos[1] - float(item[AG.VALUE])*self.unitHeight
  137. t1x = item[AG.INSLOPE][0]*self.unitWidth
  138. t1y = item[AG.INSLOPE][1]*self.unitHeight
  139. t2x = item[AG.OUTSLOPE][0]*self.unitWidth
  140. t2y = item[AG.OUTSLOPE][1]*self.unitHeight
  141. tanA = t1y/t1x
  142. temp1 = float(1)/(tanA**2+1)
  143. if t1x <0 :
  144. cosA = -math.sqrt(abs(temp1))
  145. if t1x >=0:
  146. cosA = math.sqrt(abs(temp1))
  147. temp2 = (tanA**2)*temp1
  148. if t1y <0 :
  149. sinA = -math.sqrt(abs(temp2))
  150. if t1y >=0:
  151. sinA = math.sqrt(abs(temp2))
  152. x2 = x1-float(self.unitWidth*self.zoom)*cosA
  153. y2 = y1+float(self.unitWidth*self.zoom)*sinA
  154. tanA = t2y/t2x
  155. temp1 = float(1)/(tanA**2+1)
  156. if t2x <0 :
  157. cosA = -math.sqrt(abs(temp1))
  158. if t2x >=0:
  159. cosA = math.sqrt(abs(temp1))
  160. temp2 = (tanA**2)*temp1
  161. if t2y <0 :
  162. sinA = -math.sqrt(abs(temp2))
  163. if t2y >=0:
  164. sinA = math.sqrt(abs(temp2))
  165. x3 = x1+float(self.unitWidth*self.zoom)*cosA
  166. y3 = y1-float(self.unitWidth*self.zoom)*sinA
  167. return [[(x1,y1),0],[(x2,y2),0],[(x3,y3),0],[t1x,t1y],[t2x,t2y]]
  168. def InitBuffer(self):
  169. self.buffer = wx.EmptyBitmap(self.w, self.h)
  170. dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
  171. self.DrawXCoord(dc)
  172. self.DrawYCoord(dc)
  173. self.DrawFrame(dc)
  174. self.DrawCurve(dc)
  175. self.DrawSelectRec(dc)
  176. def SetGraphEditorData(self, property, curFrame = 1):
  177. self.curFrame = curFrame
  178. self.property = property
  179. self.InitBuffer()
  180. def OnPaint(self, evt):
  181. dc = wx.BufferedPaintDC(self, self.buffer)
  182. def DrawXCoord(self,dc):
  183. dc.SetBackground(wx.Brush(wx.Colour(200, 200, 200)))
  184. dc.Clear()
  185. dc.SetPen(wx.BLACK_PEN)
  186. dc.SetBrush(wx.BLACK_BRUSH)
  187. dc.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL))
  188. dc.DrawLine(self.zeroPos[0], float(0), self.zeroPos[0], self.h)
  189. st = str(self.zero)
  190. self.tw,self.th = dc.GetTextExtent(st)
  191. dc.DrawText(st, self.zeroPos[0]+1.0, self.h-self.th-0.5)
  192. dc.SetPen(wx.Pen(wx.Colour(150, 150, 150)))
  193. dc.SetBrush(wx.Brush(wx.Colour(150, 150, 150)))
  194. if self.unitWidth >= 25:
  195. posPos = self.zeroPos[0]+self.unitWidth
  196. posNum = self.zero + 1
  197. while posPos <= self.w:
  198. dc.DrawLine(posPos, float(0), posPos, self.h)
  199. st = str(posNum)
  200. self.drawXNumber(dc, st, posPos)
  201. posPos += self.unitWidth
  202. posNum += 1
  203. negPos = self.zeroPos[0]-self.unitWidth
  204. negNum = self.zero - 1
  205. while negPos >= float(0):
  206. dc.DrawLine(negPos, float(0), negPos, self.h)
  207. st = str(negNum)
  208. self.drawXNumber(dc, st, negPos)
  209. negPos -= self.unitWidth
  210. posNum -= 1
  211. elif self.unitWidth >= 10 and self.unitWidth <= 25:
  212. posPos = self.zeroPos[0]+self.unitWidth*float(2)
  213. posNum = self.zero + 2
  214. while posPos <= self.w:
  215. dc.DrawLine(posPos, float(0), posPos, self.h)
  216. st = str(posNum)
  217. self.drawXNumber(dc, st, posPos)
  218. posPos += self.unitWidth*float(2)
  219. posNum += 2
  220. negPos = self.zeroPos[0]-self.unitWidth*float(2)
  221. negNum = self.zero - 2
  222. while negPos >= float(0):
  223. dc.DrawLine(negPos, float(0), negPos, self.h)
  224. st = str(negNum)
  225. self.drawXNumber(dc, st, negPos)
  226. negPos -= self.unitWidth*float(2)
  227. posNum -= 2
  228. elif self.unitWidth >= 2 and self.unitWidth <= 10:
  229. posPos = self.zeroPos[0]+self.unitWidth*float(5)
  230. posNum = self.zero + 5
  231. while posPos <= self.w:
  232. dc.DrawLine(posPos, float(0), posPos, self.h)
  233. st = str(posNum)
  234. self.drawXNumber(dc, st, posPos)
  235. posPos += self.unitWidth*float(5)
  236. posNum += 5
  237. negPos = self.zeroPos[0]-self.unitWidth*float(5)
  238. negNum = self.zero - 5
  239. while negPos >= float(0):
  240. dc.DrawLine(negPos, float(0), negPos, self.h)
  241. st = str(negNum)
  242. self.drawXNumber(dc, st, negPos)
  243. negPos -= self.unitWidth*float(5)
  244. posNum -= 5
  245. def DrawYCoord(self,dc):
  246. dc.SetPen(wx.BLACK_PEN)
  247. dc.SetBrush(wx.BLACK_BRUSH)
  248. dc.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL))
  249. dc.DrawLine(float(0), self.zeroPos[1], self.w, self.zeroPos[1])
  250. st = str(self.zero)
  251. dc.DrawText(st, 5.0, self.zeroPos[1]-1.0)
  252. dc.SetPen(wx.Pen(wx.Colour(150, 150, 150)))
  253. dc.SetBrush(wx.Brush(wx.Colour(150, 150, 150)))
  254. dc.SetLogicalFunction(wx.AND)
  255. posPos = self.zeroPos[1]-self.unitHeight*float(5)
  256. posNum = self.zero + 5
  257. while posPos >= float(0):
  258. dc.DrawLine(float(0), posPos, self.w, posPos)
  259. st = str(posNum)
  260. self.drawYNumber(dc, st, posPos)
  261. posPos -= self.unitHeight*float(5)
  262. posNum += 5
  263. negPos = self.zeroPos[1]+self.unitHeight*float(5)
  264. negNum = self.zero - 5
  265. while negPos <= self.h:
  266. dc.DrawLine(float(0), negPos, self.w, negPos)
  267. st = str(negNum)
  268. self.drawYNumber(dc, st, negPos)
  269. negPos += self.unitHeight*float(5)
  270. negNum -= 5
  271. def drawXNumber(self, dc, st, pos):
  272. oldPen, oldBrush, oldMode = dc.GetPen(), dc.GetBrush(), dc.GetLogicalFunction()
  273. dc.SetPen(wx.BLACK_PEN)
  274. dc.SetBrush(wx.BLACK_BRUSH)
  275. dc.DrawText(st, pos+1.0, self.h-self.th-0.5)
  276. dc.SetPen(oldPen)
  277. dc.SetBrush(oldBrush)
  278. dc.SetLogicalFunction(oldMode)
  279. def drawYNumber(self, dc, st, pos):
  280. oldPen, oldBrush, oldMode = dc.GetPen(), dc.GetBrush(), dc.GetLogicalFunction()
  281. dc.SetPen(wx.BLACK_PEN)
  282. dc.SetBrush(wx.BLACK_BRUSH)
  283. dc.DrawText(st, 5.0, pos-1.0)
  284. dc.SetPen(oldPen)
  285. dc.SetBrush(oldBrush)
  286. dc.SetLogicalFunction(oldMode)
  287. def DrawFrame(self, dc):
  288. if self._mainDialog.editor.mode == self._mainDialog.editor.ANIM_MODE:
  289. curFramePos = self.zeroPos[0]+self.curFrame*self.unitWidth
  290. dc.SetPen(wx.Pen("red"))
  291. dc.SetBrush(wx.Brush("red"))
  292. dc.DrawLine(curFramePos, float(0), curFramePos, self.h)
  293. else:
  294. pass
  295. def drawX(self, dc):
  296. dc.SetPen(wx.Pen("red"))
  297. dc.SetBrush(wx.Brush("red"))
  298. self.drawSingleCurve(self.X, dc)
  299. self.drawKeys(self.X, dc)
  300. self.drawHandler(self.X, dc)
  301. def drawY(self, dc):
  302. dc.SetPen(wx.Pen("green"))
  303. dc.SetBrush(wx.Brush("green"))
  304. self.drawSingleCurve(self.Y, dc)
  305. self.drawKeys(self.Y, dc)
  306. self.drawHandler(self.Y, dc)
  307. def drawZ(self, dc):
  308. dc.SetPen(wx.Pen("blue"))
  309. dc.SetBrush(wx.Brush("blue"))
  310. self.drawSingleCurve(self.Z, dc)
  311. self.drawKeys(self.Z, dc)
  312. self.drawHandler(self.Z, dc)
  313. def DrawCurve(self, dc):
  314. if self.property == self._mainDialog.namestr:
  315. self.drawX(dc)
  316. self.drawY(dc)
  317. self.drawZ(dc)
  318. return
  319. if self.property == property[AG.X]:
  320. self.drawX(dc)
  321. return
  322. if self.property == property[AG.Y]:
  323. self.drawY(dc)
  324. return
  325. if self.property == property[AG.Z]:
  326. self.drawZ(dc)
  327. return
  328. def drawSingleCurve(self, list, dc):
  329. if len(list) == 1:
  330. dc.DrawPoint(list[0][AG.KEYFRAME][AG.LOCAL_VALUE][0], list[0][AG.KEYFRAME][AG.LOCAL_VALUE][1])
  331. return
  332. if len(list) == 2:
  333. 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])
  334. return
  335. if len(list)>=3 :
  336. for i in range(len(list)-1):
  337. x1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]
  338. y1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]
  339. x4 = list[i+1][AG.KEYFRAME][AG.LOCAL_VALUE][0]
  340. y4 = list[i+1][AG.KEYFRAME][AG.LOCAL_VALUE][1]
  341. t1x = list[i][AG.OUT_SLOPE][0]
  342. t1y = list[i][AG.OUT_SLOPE][1]
  343. t2x = list[i+1][AG.IN_SLOPE][0]
  344. t2y = list[i+1][AG.IN_SLOPE][1]
  345. x2 = x1 + (x4 - x1) / float(3);
  346. scale1 = (x2 - x1) / t1x;
  347. y2 = y1 - t1y * scale1;
  348. x3 = x4 - (x4 - x1) / float(3);
  349. scale2 = (x4 - x3) / t2x;
  350. y3 = y4 + t2y * scale2;
  351. ax = - float(1) * x1 + float(3) * x2 - float(3) * x3 + float(1) * x4;
  352. bx = float(3) * x1 - float(6) * x2 + float(3) * x3 + float(0) * x4;
  353. cx = - float(3) * x1 + float(3) * x2 + float(0) * x3 + float(0) * x4;
  354. dx = float(1) * x1 + float(0) * x2 - float(0) * x3 + float(0) * x4;
  355. ay = - float(1) * y1 + float(3) * y2 - float(3) * y3 + float(1) * y4;
  356. by = float(3) * y1 - float(6) * y2 + float(3) * y3 + float(0) * y4;
  357. cy = - float(3) * y1 + float(3) * y2 + float(0) * y3 + float(0) * y4;
  358. dy = float(1) * y1 + float(0) * y2 - float(0) * y3 + float(0) * y4;
  359. preX = x1
  360. preY = y1
  361. t = 0.001
  362. while t<=float(1):
  363. x = ax * t*t*t + bx * t*t + cx * t + dx;
  364. y = ay * t*t*t + by * t*t + cy * t + dy;
  365. curX = x
  366. curY = y
  367. dc.DrawLine(preX, preY, curX, curY)
  368. preX = curX
  369. preY = curY
  370. t += 0.001
  371. def drawKeys(self, list, dc):
  372. for i in range(len(list)):
  373. pointX = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]
  374. pointY = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]
  375. if list[i][AG.KEYFRAME][AG.SELECT] == 0:
  376. dc.SetPen(wx.Pen("black",3))
  377. dc.SetBrush(wx.Brush("black"))
  378. dc.DrawCircle(pointX, pointY, 2)
  379. if list[i][AG.KEYFRAME][AG.SELECT] == 1:
  380. dc.SetPen(wx.Pen("cyan",3))
  381. dc.SetBrush(wx.Brush("cyan"))
  382. dc.DrawCircle(pointX, pointY, 2)
  383. def drawHandler(self, list, dc):
  384. for i in range(len(list)):
  385. if list[i][AG.KEYFRAME][AG.SELECT] == 1:
  386. X1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]
  387. Y1 = list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]
  388. if self._OneTangent == True:
  389. for j in range(3,5):
  390. X = list[i][j][AG.LOCAL_VALUE][0]
  391. Y = list[i][j][AG.LOCAL_VALUE][1]
  392. if list[i][j][AG.SELECT] == 1:
  393. dc.SetPen(wx.Pen("cyan",3))
  394. dc.SetBrush(wx.Brush("cyan"))
  395. dc.DrawCircle(X, Y, 2)
  396. dc.SetPen(wx.Pen("cyan",1))
  397. dc.DrawLine(X1, Y1, X, Y)
  398. if list[i][j][AG.SELECT] == 0:
  399. dc.SetPen(wx.Pen("brown",3))
  400. dc.SetBrush(wx.Brush("brown"))
  401. dc.DrawCircle(X, Y, 2)
  402. dc.SetPen(wx.Pen("brown",1))
  403. dc.DrawLine(X1, Y1, X, Y)
  404. if self._OneTangent == False:
  405. if list[i][AG.IN_TANGENT][AG.SELECT] == 1:
  406. X = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][0]
  407. Y = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][1]
  408. dc.SetPen(wx.Pen("cyan",3))
  409. dc.SetBrush(wx.Brush("cyan"))
  410. dc.DrawCircle(X, Y, 2)
  411. dc.SetPen(wx.Pen("cyan",1))
  412. dc.DrawLine(X1, Y1, X, Y)
  413. if list[i][AG.IN_TANGENT][AG.SELECT] == 0:
  414. X = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][0]
  415. Y = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][1]
  416. dc.SetPen(wx.Pen("navy",3))
  417. dc.SetBrush(wx.Brush("navy"))
  418. dc.DrawCircle(X, Y, 2)
  419. dc.SetPen(wx.Pen("navy",1))
  420. dc.DrawLine(X1, Y1, X, Y)
  421. if list[i][AG.OUT_TANGENT][AG.SELECT] == 1:
  422. X = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][0]
  423. Y = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][1]
  424. dc.SetPen(wx.Pen("cyan",3))
  425. dc.SetBrush(wx.Brush("cyan"))
  426. dc.DrawCircle(X, Y, 2)
  427. dc.SetPen(wx.Pen("cyan",1))
  428. dc.DrawLine(X1, Y1, X, Y)
  429. if list[i][AG.OUT_TANGENT][AG.SELECT] == 0:
  430. X = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][0]
  431. Y = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][1]
  432. dc.SetPen(wx.Pen("brown",3))
  433. dc.SetBrush(wx.Brush("brown"))
  434. dc.DrawCircle(X, Y, 2)
  435. dc.SetPen(wx.Pen("brown",1))
  436. dc.DrawLine(X1, Y1, X, Y)
  437. def DrawSelectRec(self, dc):
  438. if self._selectRec == True:
  439. dc.SetPen(wx.Pen("navy", 1))
  440. dc.SetBrush(wx.Brush("navy"))
  441. ## dc.SetLogicalFunction(wx.AND)
  442. dc.DrawLine(self.pos[0], self.pos[1], self.pos[0], self.newPos[1])
  443. dc.DrawLine(self.pos[0], self.pos[1], self.newPos[0], self.pos[1])
  444. dc.DrawLine(self.newPos[0], self.newPos[1], self.pos[0], self.newPos[1])
  445. dc.DrawLine(self.newPos[0], self.newPos[1], self.newPos[0], self.pos[1])
  446. def OnSize(self,evt):
  447. self.InitBuffer()
  448. def OnLeftDown(self,evt):
  449. point = (evt.GetX(), evt.GetY())
  450. if point[1]>= float(0) and point[1]<= float(self.h):
  451. if point[0]>= float(0) and point[0]<= float(self.w):
  452. self._mouseIn = True
  453. if self._mouseIn:
  454. self.CaptureMouse()
  455. self.pos = point
  456. def OnLeftUp(self,evt):
  457. if self.GetCapture():
  458. self.ReleaseMouse()
  459. self._mouseIn = False
  460. self._selectRec = False
  461. self.setSelection()
  462. self.SetGraphEditorData(self.property, self.curFrame)
  463. def OnMiddleDown(self,evt):
  464. point = (evt.GetX(), evt.GetY())
  465. if point[1]>= float(0) and point[1]<= float(self.h):
  466. if point[0]>= float(0) and point[0]<= float(self.w):
  467. self._mouseIn = True
  468. if self._mouseIn:
  469. self.CaptureMouse()
  470. self.midPos = point
  471. def OnMiddleUp(self, evt):
  472. if self.GetCapture():
  473. self.ReleaseMouse()
  474. def OnMotion(self,evt):
  475. self._mouseIn = False
  476. if evt.Dragging() and evt.LeftIsDown():
  477. self.newPos = (evt.GetX(), evt.GetY())
  478. if self.newPos[1]>= float(0) and self.newPos[1]<= float(self.h):
  479. if self.newPos[0]>= float(0) and self.newPos[0]<= float(self.w):
  480. self._mouseIn = True
  481. if self._mouseIn:
  482. if self.newPos == self.pos:
  483. evt.Skip()
  484. self._mouseIn = False
  485. else:
  486. self._selectRec = True
  487. self.SetGraphEditorData(self.property, self.curFrame)
  488. if evt.Dragging() and evt.MiddleIsDown():
  489. self.newMidPos = (evt.GetX(), evt.GetY())
  490. if self.newMidPos[1]>= float(0) and self.newMidPos[1]<= float(self.h):
  491. if self.newMidPos[0]>= float(0) and self.newMidPos[0]<= float(self.w):
  492. self._mouseIn = True
  493. if self._mouseIn:
  494. if self.newMidPos == self.midPos:
  495. evt.Skip()
  496. self._mouseIn = False
  497. else:
  498. self.recalculateSlope()
  499. self.onAnimation()
  500. self.midPos = self.newMidPos
  501. evt.Skip()
  502. self._mouseIn = False
  503. self._selectRec = False
  504. def setExistKey(self, list):
  505. flag = False
  506. for i in range(len(list)):
  507. if list[i][AG.KEYFRAME][AG.SELECT] == 1:
  508. inside = self.inside(self.pos, self.newPos, (list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0], list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]))
  509. if inside == True:
  510. list[i][AG.KEYFRAME][AG.SELECT] = 0
  511. if inside == False:
  512. find = False
  513. for j in range(3,5):
  514. inside = self.inside(self.pos, self.newPos, (list[i][j][AG.LOCAL_VALUE][0], list[i][j][AG.LOCAL_VALUE][1]))
  515. if inside == False:
  516. list[i][j][AG.SELECT] = 0
  517. if inside == True:
  518. list[i][j][AG.SELECT] = 1
  519. find = True
  520. flag = True
  521. if find == False:
  522. list[i][AG.KEYFRAME][AG.SELECT] == 0
  523. return flag
  524. def setNewKey(self, list):
  525. for i in range(len(list)):
  526. inside = self.inside(self.pos, self.newPos, (list[i][2][0][0], list[i][2][0][1]))
  527. if inside == True:
  528. list[i][AG.KEYFRAME][AG.SELECT] = 1
  529. if inside == False:
  530. list[i][AG.KEYFRAME][AG.SELECT] = 0
  531. def setSelection(self):
  532. if self.property == self._mainDialog.namestr:
  533. self.setSelectionBase(self.X)
  534. self.setSelectionBase(self.Y)
  535. self.setSelectionBase(self.Z)
  536. return
  537. if self.property == property[AG.X]:
  538. self.setSelectionBase(self.X)
  539. return
  540. if self.property == property[AG.Y]:
  541. self.setSelectionBase(self.Y)
  542. return
  543. if self.property == property[AG.Z]:
  544. self.setSelectionBase(self.Z)
  545. return
  546. def setSelectionBase(self, list):
  547. self.setExistKey(list)
  548. if self.setExistKey(list) == True:
  549. return
  550. else:
  551. self.setNewKey(list)
  552. def inside(self, point0, point1, point):
  553. if point0[0]<=point1[0] and point0[1]<=point1[1]:
  554. if point0[0]<point[0] and point[0]<point1[0] and point0[1]<point[1] and point[1]<point1[1]:
  555. return True
  556. else:
  557. return False
  558. elif point1[0]<=point0[0] and point0[1]<=point1[1]:
  559. if point1[0]<point[0] and point[0]<point0[0] and point0[1]<point[1] and point[1]<point1[1]:
  560. return True
  561. else:
  562. return False
  563. elif point0[0]<=point1[0] and point1[1]<=point0[1]:
  564. if point0[0]<point[0] and point[0]<point1[0] and point1[1]<point[1] and point[1]<point0[1]:
  565. return True
  566. else:
  567. return False
  568. elif point1[0]<=point0[0] and point1[1]<=point0[1]:
  569. if point1[0]<point[0] and point[0]<point0[0] and point1[1]<point[1] and point[1]<point0[1]:
  570. return True
  571. else:
  572. return False
  573. else:
  574. return False
  575. def recalculateSlope(self):
  576. if self.property == self._mainDialog.namestr:
  577. self.recalculateSlopeBase(self.X)
  578. self.recalculateSlopeBase(self.Y)
  579. self.recalculateSlopeBase(self.Z)
  580. return
  581. if self.property == property[AG.X]:
  582. self.recalculateSlopeBase(self.X)
  583. return
  584. if self.property == property[AG.Y]:
  585. self.recalculateSlopeBase(self.Y)
  586. return
  587. if self.property == property[AG.Z]:
  588. self.recalculateSlopeBase(self.Z)
  589. return
  590. def recalculateSlopeBase(self, list):
  591. #recalculate the tangent slope
  592. moveX = self.newMidPos[0]-self.midPos[0]
  593. moveY = self.newMidPos[1]-self.midPos[1]
  594. for i in range(len(list)):
  595. if list[i][AG.KEYFRAME][AG.SELECT] == 1:
  596. if list[i][AG.IN_TANGENT][AG.SELECT] == 1:
  597. newPointX = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][0] + moveX
  598. newPointY = list[i][AG.IN_TANGENT][AG.LOCAL_VALUE][1] + moveY
  599. newSlope = [list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0] - newPointX , newPointY - list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1]]
  600. temp0 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][0]
  601. temp1 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][1]
  602. self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][0] = newSlope[0]/self.unitWidth
  603. self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][1] = newSlope[1]/self.unitHeight
  604. handler = self.generateHandler(self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]])
  605. if handler[1][0][0]>= list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]:
  606. self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][0] = temp0
  607. self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][1] = temp1
  608. return
  609. if handler[1][0][0] < list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]:
  610. if self._OneTangent == False:
  611. list[i][AG.IN_TANGENT][0] = handler[1][0]
  612. list[i][AG.IN_SLOPE][0] = handler[3][0]
  613. list[i][AG.IN_SLOPE][1] = handler[3][1]
  614. if self._OneTangent == True:
  615. self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][0] = newSlope[0]/self.unitWidth
  616. self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][1] = newSlope[1]/self.unitHeight
  617. handler = self.generateHandler(self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]])
  618. list[i][AG.IN_TANGENT][0] = handler[1][0]
  619. list[i][AG.OUT_TANGENT][0] = handler[2][0]
  620. list[i][AG.IN_SLOPE][0] = handler[3][0]
  621. list[i][AG.IN_SLOPE][1] = handler[3][1]
  622. list[i][AG.OUT_SLOPE][0] = handler[4][0]
  623. list[i][AG.OUT_SLOPE][1] = handler[4][1]
  624. self.SetGraphEditorData(self.property, self.curFrame)
  625. if list[i][AG.OUT_TANGENT][AG.SELECT] == 1:
  626. newPointX = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][0] + moveX
  627. newPointY = list[i][AG.OUT_TANGENT][AG.LOCAL_VALUE][1] + moveY
  628. newSlope = [newPointX - list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0] , list[i][AG.KEYFRAME][AG.LOCAL_VALUE][1] - newPointY]
  629. temp0 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][0]
  630. temp1 = self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][1]
  631. self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][0] = newSlope[0]/self.unitWidth
  632. self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][1] = newSlope[1]/self.unitHeight
  633. handler = self.generateHandler(self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]])
  634. if handler[2][0][0] <= list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]:
  635. self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][0] = temp0
  636. self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.OUTSLOPE][1] = temp1
  637. return
  638. if handler[2][0][0] > list[i][AG.KEYFRAME][AG.LOCAL_VALUE][0]:
  639. if self._OneTangent == False:
  640. list[i][AG.OUT_TANGENT][0] = handler[2][0]
  641. list[i][AG.OUT_SLOPE][0] = handler[4][0]
  642. list[i][AG.OUT_SLOPE][1] = handler[4][1]
  643. if self._OneTangent == True:
  644. self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][0] = newSlope[0]/self.unitWidth
  645. self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]][AG.INSLOPE][1] = newSlope[1]/self.unitHeight
  646. handler = self.generateHandler(self._mainDialog.editor.animMgr.keyFramesInfo[list[i][AG.KEY]][list[i][AG.I]])
  647. list[i][AG.IN_TANGENT][0] = handler[1][0]
  648. list[i][AG.OUT_TANGENT][0] = handler[2][0]
  649. list[i][AG.IN_SLOPE][0] = handler[3][0]
  650. list[i][AG.IN_SLOPE][1] = handler[3][1]
  651. list[i][AG.OUT_SLOPE][0] = handler[4][0]
  652. list[i][AG.OUT_SLOPE][1] = handler[4][1]
  653. self.SetGraphEditorData(self.property, self.curFrame)
  654. def selectHandler(self):
  655. self._selectHandler = False
  656. def onAnimation(self):
  657. if self._mainDialog.editor.mode == self._mainDialog.editor.ANIM_MODE:
  658. self._mainDialog.editor.ui.animUI.OnAnimation(self._mainDialog.editor.ui.animUI.curFrame)
  659. else:
  660. pass
  661. class GraphEditorUI(wx.Dialog):
  662. """
  663. This is the graph editor main class implementation.
  664. """
  665. def __init__(self, parent, editor, object):
  666. wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title="Graph Editor",
  667. pos=wx.DefaultPosition, size=(735, 535))
  668. self.editor = editor
  669. self.editor.GRAPH_EDITOR = True
  670. self.object = object
  671. self.xRange = 24+1
  672. self.yRange = 50
  673. if self.editor.mode == self.editor.ANIM_MODE:
  674. self.curFrame = self.editor.ui.animUI.curFrame
  675. self.curFrame = 1
  676. self.mainPanel1 = wx.Panel(self, -1)
  677. bmpZoomIn = ZoomIn.GetBitmap()
  678. bmpZoomOut = ZoomOut.GetBitmap()
  679. bmpOneTangent = OneTangent.GetBitmap()
  680. bmpTwoTangents = TwoTangents.GetBitmap()
  681. self.buttonZoomIn = wx.BitmapButton(self.mainPanel1, -1, bmpZoomIn, size = (30,30),style = wx.BU_AUTODRAW)
  682. self.buttonZoomOut = wx.BitmapButton(self.mainPanel1, -1, bmpZoomOut, size = (30,30),style = wx.BU_AUTODRAW)
  683. self.buttonOneTangent = wx.BitmapButton(self.mainPanel1, -1, bmpOneTangent, size = (30,30),style = wx.BU_AUTODRAW)
  684. self.buttonTwoTangents = wx.BitmapButton(self.mainPanel1, -1, bmpTwoTangents, size = (30,30),style = wx.BU_AUTODRAW)
  685. self.mainPanel2 = wx.Panel(self, -1)
  686. 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")
  687. self.namestr = "%s"%(object[OG.OBJ_DEF].name)
  688. self.root = self.tree.AddRoot(self.namestr)
  689. self.AddTreeNodes(self.root, property)
  690. self.tree.Expand(self.root)
  691. self.tree.SelectItem(self.root,select=True)
  692. self.str = self.tree.GetItemText(self.root)
  693. self.graphEditorWindow =GraphEditorWindow(self.mainPanel2, wx.Size(500, 450), str(object[OG.OBJ_DEF].name), self.xRange, self.yRange, self.curFrame, self.object)
  694. self.SetProperties()
  695. self.DoLayout()
  696. self.Bind(wx.EVT_BUTTON, self.OnZoomIn, self.buttonZoomIn)
  697. self.Bind(wx.EVT_BUTTON, self.OnZoomOut, self.buttonZoomOut)
  698. self.Bind(wx.EVT_BUTTON, self.OnOneTangent, self.buttonOneTangent)
  699. self.Bind(wx.EVT_BUTTON, self.OnTwoTangents, self.buttonTwoTangents)
  700. self.Bind(wx.EVT_CLOSE, self.OnExit)
  701. self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged)
  702. def SetProperties(self):
  703. pass
  704. def DoLayout(self):
  705. dialogSizer = wx.BoxSizer(wx.VERTICAL)
  706. mainSizer1 = wx.FlexGridSizer(1, 4, 0, 0)
  707. mainSizer2 = wx.FlexGridSizer(1, 2, 0, 0)
  708. mainSizer1.Add(self.buttonOneTangent, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 570)
  709. mainSizer1.Add(self.buttonTwoTangents, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 10)
  710. mainSizer1.Add(self.buttonZoomIn, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 10)
  711. mainSizer1.Add(self.buttonZoomOut, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 10)
  712. mainSizer2.Add(self.tree, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 10)
  713. mainSizer2.Add(self.graphEditorWindow, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 10)
  714. self.mainPanel1.SetSizerAndFit(mainSizer1)
  715. self.mainPanel2.SetSizer(mainSizer2)
  716. dialogSizer.Add(self.mainPanel2, 0, wx.ALIGN_CENTER_VERTICAL|wx.TOP, 10)
  717. dialogSizer.Add(self.mainPanel1, 0, wx.ALIGN_CENTER_VERTICAL|wx.TOP, 5)
  718. self.SetSizer(dialogSizer)
  719. self.Layout()
  720. self.dialogSizer = dialogSizer
  721. def AddTreeNodes(self, parentItem, items):
  722. for item in items:
  723. if type(item) == str:
  724. self.tree.AppendItem(parentItem, item)
  725. def OnSelChanged(self, evt):
  726. item = evt.GetItem()
  727. if item:
  728. self.str = self.tree.GetItemText(item)
  729. self.graphEditorWindow.refresh()
  730. self.graphEditorWindow.SetGraphEditorData(self.str, self.curFrame)
  731. def OnZoomIn(self,evt):
  732. self.graphEditorWindow.zoom = self.graphEditorWindow.zoom/float(1.2)
  733. self.graphEditorWindow.unitWidth = self.graphEditorWindow.unitWidth*float(1.2)
  734. self.graphEditorWindow.unitHeight = self.graphEditorWindow.unitHeight*float(1.2)
  735. self.graphEditorWindow.generateInfo()
  736. self.graphEditorWindow.SetGraphEditorData(self.str, self.curFrame)
  737. def OnZoomOut(self,evt):
  738. self.graphEditorWindow.zoom = self.graphEditorWindow.zoom*float(1.2)
  739. self.graphEditorWindow.unitWidth = self.graphEditorWindow.unitWidth/float(1.2)
  740. self.graphEditorWindow.unitHeight = self.graphEditorWindow.unitHeight/float(1.2)
  741. self.graphEditorWindow.generateInfo()
  742. self.graphEditorWindow.SetGraphEditorData(self.str, self.curFrame)
  743. def OnOneTangent(self,evt):
  744. self.graphEditorWindow._OneTangent = True
  745. self.graphEditorWindow.SetGraphEditorData(self.str, self.curFrame)
  746. def OnTwoTangents(self,evt):
  747. self.graphEditorWindow._OneTangent = False
  748. self.graphEditorWindow.SetGraphEditorData(self.str, self.curFrame)
  749. def curFrameChange(self):
  750. if self.editor.mode == self.editor.ANIM_MODE:
  751. self.curFrame = self.editor.ui.animUI.curFrame
  752. self.graphEditorWindow.SetGraphEditorData(self.str, self.curFrame)
  753. else:
  754. pass
  755. def OnExit(self,evt):
  756. self.Destroy()
  757. self.editor.ui.graphEditorMenuItem.Check(False)
  758. self.object = None
  759. self.editor.GRAPH_EDITOR = False