studio_assetLayer.py 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139
  1. # THIS FILE IS A PART OF VCStudio
  2. # PYTHON 3
  3. # This a console project manager.
  4. import os
  5. # GTK module ( Graphical interface
  6. import gi
  7. gi.require_version('Gtk', '3.0')
  8. from gi.repository import Gtk
  9. from gi.repository import GLib
  10. from gi.repository import Gdk
  11. import cairo
  12. # Own modules
  13. from settings import settings
  14. from settings import talk
  15. from settings import fileformats
  16. from settings import oscalls
  17. from project_manager import pm_project
  18. #UI modules
  19. from UI import UI_elements
  20. from UI import UI_color
  21. # story
  22. from studio import story
  23. from studio import checklist
  24. from studio import analytics
  25. from studio import studio_dialogs
  26. from studio import schedule
  27. from studio import history
  28. def layer(win):
  29. # Making the layer
  30. surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, win.current['w'],
  31. win.current['h'])
  32. layer = cairo.Context(surface)
  33. #text setting
  34. layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
  35. UI_color.set(layer, win, "dark_overdrop")
  36. layer.rectangle(
  37. 0,
  38. 0,
  39. win.current["w"],
  40. win.current["h"],
  41. )
  42. layer.fill()
  43. UI_color.set(layer, win, "node_background")
  44. UI_elements.roundrect(layer, win,
  45. win.current["w"]/4,
  46. 150,
  47. win.current["w"]/2,
  48. win.current["h"]-190,
  49. 10)
  50. ############################################################################
  51. # This file will be showing stuff about an asset. It's almost like a folder
  52. # / folders of the asset. But with some extendet functionality. Stuff that
  53. # will be on screen will include.
  54. # Progress Bar
  55. # Checklist
  56. # Scenes list in which the asset is mentioned
  57. # History / Schedules
  58. # It's similar to the old Blender Organizer's Asset thing. But a bit more
  59. # modern looking. I would say.
  60. ############################################################################
  61. # before we start I want to make a little safe mechanism. Just in case the
  62. # win.cur is not written properly.
  63. # Parsing the cur to get name and type
  64. name = win.cur[win.cur.rfind("/")+1:]
  65. acur = win.cur.replace(name, "").replace("/", "")
  66. if not os.path.exists(win.project+"/dev/"+win.cur) or not win.cur:
  67. def select_character(win, var):
  68. if var:
  69. win.url = "assets"
  70. win.cur = var
  71. else:
  72. win.url = "story_editor"
  73. if not acur:
  74. acur = "chr"
  75. studio_dialogs.asset_select(win, "select_asset_check", select_character, force=True, cur=acur, SEARCH=name)
  76. if not "asset_cur_folder" in win.current:
  77. win.current["asset_cur_folder"] = "blender"
  78. ####### MIDDLE PANNEL #######
  79. def do():
  80. oscalls.Open(win.project+"/dev"+win.cur)
  81. UI_elements.roundrect(layer, win,
  82. win.current["w"]/4+20,
  83. 350,
  84. 40,
  85. 40,
  86. 10,
  87. do,
  88. "folder")
  89. folds = {
  90. "blender":"blend_files_folder",
  91. "idea":"reference_folder",
  92. "texture":"tex_folder",
  93. "render":"renders_folder"
  94. }
  95. for num, cur in enumerate(folds):
  96. if win.current["asset_cur_folder"] == cur:
  97. UI_color.set(layer, win, "progress_time")
  98. UI_elements.roundrect(layer, win,
  99. win.current["w"]/4+150+(40*num),
  100. 350,
  101. 40,
  102. 40,
  103. 10)
  104. def do():
  105. win.current["asset_cur_folder"] = cur
  106. UI_elements.roundrect(layer, win,
  107. win.current["w"]/4+150+(40*num),
  108. 350,
  109. 40,
  110. 40,
  111. 10,
  112. do,
  113. cur,
  114. tip=talk.text(folds[cur]))
  115. # Preview
  116. # Making the layer
  117. nodesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 300, 300)
  118. node = cairo.Context(nodesurface)
  119. node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
  120. UI_elements.roundrect(node, win,
  121. 0,
  122. 0,
  123. 300,
  124. 300,
  125. 10,
  126. fill=False)
  127. node.clip()
  128. if os.path.exists(win.project+"/dev"+win.cur+"/renders/Preview.png"):
  129. UI_elements.image(node, win,
  130. win.project+"/dev"+win.cur+"/renders/Preview.png",
  131. 0, 0, 300, 300, cell="big_asset_previews")
  132. elif os.path.exists(win.project+"/dev"+win.cur+"/renders/Preview.jpg"):
  133. UI_elements.image(node, win,
  134. win.project+"/dev"+win.cur+"/renders/Preview.jpg",
  135. 0, 0, 300, 300, cell="big_asset_previews")
  136. else:
  137. UI_color.set(node, win, "dark_overdrop")
  138. node.rectangle(0,0,300, 300)
  139. node.fill()
  140. UI_elements.image(node, win,
  141. "settings/themes/"+win.settings["Theme"]+"/icons/"+acur+".png",
  142. 130, 130, 40, 40)
  143. def do():
  144. def after(win, var):
  145. win.current["asset_file_selected"] = ""
  146. win.images = {}
  147. if var:
  148. for t in fileformats.images:
  149. if var.endswith(t):
  150. oscalls.copy_file(
  151. win,
  152. var,
  153. "/dev"+win.cur+"/renders/",
  154. "Preview.png")
  155. break
  156. studio_dialogs.file_select(win, name+"_preview", after, force=True,
  157. IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True,
  158. LOC=True, OBJ=True, RND=False, FOLDER=False, SEARCH=win.cur+" renders")
  159. UI_elements.roundrect(node, win,
  160. 2,
  161. 2,
  162. 296,
  163. 296,
  164. 10,
  165. button=do,
  166. fill=False,
  167. offset=[
  168. win.current["w"]/4+20,
  169. 20
  170. ]
  171. )
  172. node.stroke()
  173. # Outputting the layer
  174. layer.set_source_surface(nodesurface,
  175. win.current["w"]/4+20,
  176. 20)
  177. layer.paint()
  178. # Name of the asset
  179. UI_elements.image(layer, win,
  180. "settings/themes/"+win.settings["Theme"]+"/icons/"+acur+".png",
  181. win.current["w"]/4+360, 210, 40, 40)
  182. UI_color.set(layer, win, "text_normal")
  183. layer.set_font_size(30)
  184. layer.move_to(win.current["w"]/4+410,240)
  185. layer.show_text(name)
  186. # Fraction
  187. fraction = story.get_asset_data(win, win.cur)["fraction"]
  188. UI_color.set(layer, win, "progress_background")
  189. UI_elements.roundrect(layer, win,
  190. win.current["w"]/4+350,
  191. 270,
  192. (win.current["w"]/2-370),
  193. 0,
  194. 10)
  195. UI_color.set(layer, win, "progress_active")
  196. UI_elements.roundrect(layer, win,
  197. win.current["w"]/4+350,
  198. 270,
  199. (win.current["w"]/2-370)*fraction,
  200. 0,
  201. 10)
  202. # Before search. On the other side when you have done the asset there will
  203. # be a little configure icon. This is configuration for linking. Creating
  204. # the /ast/ blend.file and autolink.data file. So the linker could link
  205. # the files into the animation scene.
  206. #
  207. # See:
  208. # studio/studio_shot_linkLayer.py
  209. # studio/bpy_do_linking.py
  210. # studio/studio_asset_configureLayer.py
  211. def do():
  212. def after(win, var):
  213. print(var)
  214. studio_dialogs.asset_configure(win, "configuring_asset", after, win.cur)
  215. UI_elements.roundrect(layer, win,
  216. win.current["w"]/4*3-60,
  217. 210,
  218. 40,
  219. 40,
  220. 10,
  221. button=do,
  222. icon="link_configure")
  223. # Search
  224. UI_elements.image(layer, win, "settings/themes/"\
  225. +win.settings["Theme"]+"/icons/search.png",
  226. win.current["w"]-280-win.current["w"]/4,
  227. 350,
  228. 40,
  229. 40)
  230. UI_elements.text(layer, win, "in_asset",
  231. win.current["w"]-240-win.current["w"]/4,
  232. 350,
  233. 220,
  234. 40)
  235. # FILES
  236. # In case the user made the folder manually.
  237. try:
  238. os.mkdir(win.project+"/dev/"+win.cur)
  239. except:
  240. pass
  241. try:
  242. os.mkdir(win.project+"/dev/"+win.cur+"/renders")
  243. os.mkdir(win.project+"/dev/"+win.cur+"/reference")
  244. os.mkdir(win.project+"/dev/"+win.cur+"/tex")
  245. except:
  246. pass
  247. # Now let's prepare the frame
  248. width = win.current["w"]/2- 40
  249. height = win.current["h"] - 500
  250. # Making the layer
  251. nodesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
  252. node = cairo.Context(nodesurface)
  253. node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
  254. UI_elements.roundrect(node, win,
  255. 0,
  256. 0,
  257. width,
  258. height,
  259. 10,
  260. fill=False)
  261. node.clip()
  262. # Now let's prepare the scrooler
  263. tileX = 20
  264. current_Y = 10
  265. if "assets" not in win.scroll:
  266. win.scroll["assets"] = 0
  267. ###########################
  268. # Let's get the list of the files first.
  269. files = []
  270. newcreate = win.text["in_asset"]["text"].replace("/","_").replace(" ", "_")\
  271. .replace('"',"_").replace("(","_").replace(")","_").replace("'","_")\
  272. .replace("[","_").replace("]","_").replace("{","_").replace("}","_")
  273. foundblend = True
  274. found_in = False
  275. if win.current["asset_cur_folder"] == "blender":
  276. foundblend = False
  277. # Let's see if an asset blend file exists.
  278. if os.path.exists(win.project+"/ast"+win.cur+".blend") and not newcreate:
  279. files.append(["/ast"+win.cur+".blend", "node_asset"])
  280. foundblend = True
  281. for f in sorted(os.listdir(win.project+"/dev"+win.cur)):
  282. if not os.path.isdir(win.project+"/dev"+win.cur+"/"+f):
  283. # This is for only the blend files. So let's filter the out of all
  284. # the noise. For all files there is a folder icon.
  285. if newcreate == f:
  286. found_in = True
  287. if newcreate and newcreate.lower() not in f.lower():
  288. continue
  289. if f.endswith(".blend"):
  290. files.append(["/dev"+win.cur+"/"+f, "node_blendfile"])
  291. foundblend = True
  292. else:
  293. # This all the rest of the files.
  294. if win.current["asset_cur_folder"] == "idea":
  295. fl = "reference"
  296. elif win.current["asset_cur_folder"] == "texture":
  297. fl = "tex"
  298. elif win.current["asset_cur_folder"] == "render":
  299. fl = "renders"
  300. for f in sorted(os.listdir(win.project+"/dev"+win.cur+"/"+fl)):
  301. if not os.path.isdir(win.project+"/dev"+win.cur+"/"+fl+"/"+f):
  302. if newcreate == f:
  303. found_in = True
  304. if newcreate and newcreate.lower() not in f.lower():
  305. continue
  306. # Now it has to be image or video files. For the rest you have
  307. # the folder icon.
  308. for t in fileformats.images:
  309. if f.endswith(t):
  310. files.append(["/dev"+win.cur+"/"+fl+"/"+f, "node_imagefile"])
  311. for t in fileformats.videos:
  312. if f.endswith(t):
  313. files.append(["/dev"+win.cur+"/"+fl+"/"+f, "node_videofile"])
  314. # Let's make sure that we have at least some blendfile there.
  315. if not foundblend and not newcreate:
  316. oscalls.copy_file(
  317. win,
  318. os.getcwd()+"/new_file/"+acur+".blend",
  319. "/dev"+win.cur+"/",
  320. name+".blend")
  321. if "asset_file_selected" not in win.current:
  322. win.current["asset_file_selected"] = ""
  323. for filename, thecoloris in files:
  324. if int(current_Y + win.scroll["assets"]) in range(0-200, height):
  325. # Making the layer
  326. node2surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 170, 200)
  327. node2 = cairo.Context(node2surface)
  328. node2.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
  329. UI_elements.roundrect(node2, win,
  330. 0,
  331. 0,
  332. 170,
  333. 200,
  334. 10,
  335. fill=False)
  336. node2.clip()
  337. # Background
  338. UI_color.set(node2, win, "dark_overdrop")
  339. node2.rectangle(0,0,170, 200)
  340. node2.fill()
  341. # Banner
  342. UI_color.set(node2, win, thecoloris)
  343. node2.rectangle(0,0,170, 20)
  344. node2.fill()
  345. # Outputting the layer
  346. node.set_source_surface(node2surface,
  347. tileX-10,
  348. current_Y + win.scroll["assets"] )
  349. node.paint()
  350. UI_elements.image(node, win, win.project+filename,
  351. tileX,
  352. current_Y + win.scroll["assets"] + 30,
  353. 150,
  354. 150)
  355. UI_color.set(node, win, "text_normal")
  356. node.set_font_size(12)
  357. node.move_to(tileX,
  358. current_Y + win.scroll["assets"]+15)
  359. node.show_text(filename[filename.rfind("/")+1:][:22])
  360. # If selected
  361. node.set_line_width(4)
  362. if win.current["asset_file_selected"] == win.project+filename:
  363. UI_color.set(node, win, "progress_background")
  364. UI_elements.roundrect(node, win,
  365. tileX-10,
  366. current_Y + win.scroll["assets"],
  367. 170,
  368. 200,
  369. 10,
  370. fill=False)
  371. node.stroke()
  372. # Button to activate it
  373. def do():
  374. if win.current["asset_file_selected"] != win.project+filename:
  375. win.current["asset_file_selected"] = win.project+filename
  376. else:
  377. oscalls.file_open(win, win.project+filename)
  378. UI_elements.roundrect(node, win,
  379. tileX-10,
  380. current_Y + win.scroll["assets"],
  381. 170,
  382. 200,
  383. 10,
  384. button=do,
  385. tip=filename,
  386. fill=False,
  387. clip=[
  388. win.current["w"]/4+20,
  389. 400,
  390. width,
  391. height,
  392. ],
  393. offset=[
  394. win.current["w"]/4+20,
  395. 400])
  396. node.stroke()
  397. node.set_line_width(2)
  398. tileX += 200
  399. if tileX > width-180:
  400. tileX = 20
  401. current_Y += 230
  402. ###########################
  403. # Now i'd like to make things addable. For now if it's a blends selected
  404. # there will an option to add new one and an option to copy. While other
  405. # files will have an option of only copy. (At least for now. Untill I
  406. # figure out what new images will it give.)
  407. if not found_in and newcreate:
  408. if win.current["asset_cur_folder"] == "blender"\
  409. and not newcreate.endswith(".blend"):
  410. newcreate = newcreate+".blend"
  411. def do():
  412. def after(win, var):
  413. newcreate = win.text["in_asset"]["text"].replace("/","_").replace(" ", "_")\
  414. .replace('"',"_").replace("(","_").replace(")","_").replace("'","_")\
  415. .replace("[","_").replace("]","_").replace("{","_").replace("}","_")
  416. win.text["in_asset"]["text"] = ""
  417. win.current["asset_file_selected"] = ""
  418. win.images = {}
  419. if var:
  420. if win.current["asset_cur_folder"] == "blender"\
  421. and var.endswith(".blend"):
  422. if not newcreate.endswith(".blend"):
  423. newcreate = newcreate+".blend"
  424. oscalls.copy_file(
  425. win,
  426. var,
  427. "/dev"+win.cur+"/",
  428. newcreate)
  429. else:
  430. # In case the copying file is not a blend file. Let's
  431. # make sure that it's infect an image.
  432. for t in fileformats.images:
  433. if var.endswith(t):
  434. if not newcreate.endswith(t):
  435. newcreate = newcreate + "." + t
  436. if win.current["asset_cur_folder"] == "idea":
  437. fl = "reference"
  438. elif win.current["asset_cur_folder"] == "texture":
  439. fl = "tex"
  440. elif win.current["asset_cur_folder"] == "render":
  441. fl = "renders"
  442. oscalls.copy_file(
  443. win,
  444. var,
  445. "/dev"+win.cur+"/"+fl+"/",
  446. newcreate)
  447. break
  448. if win.current["asset_cur_folder"] == "blender":
  449. studio_dialogs.file_select(win, name+"_blends", after, force=True,
  450. IMAGE=False, BLEND=True, VIDEO=False, FILE=False, CHR=True, VEH=True,
  451. LOC=True, OBJ=True, RND=False, FOLDER=False)
  452. elif win.current["asset_cur_folder"] == "idea":
  453. studio_dialogs.file_select(win, name+"_reference", after, force=True,
  454. IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True,
  455. LOC=True, OBJ=True, RND=False, FOLDER=False, SEARCH="reference")
  456. elif win.current["asset_cur_folder"] == "texture":
  457. studio_dialogs.file_select(win, name+"_reference", after, force=True,
  458. IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True,
  459. LOC=True, OBJ=True, RND=False, FOLDER=False, SEARCH="tex")
  460. elif win.current["asset_cur_folder"] == "render":
  461. studio_dialogs.file_select(win, name+"_reference", after, force=True,
  462. IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True,
  463. LOC=True, OBJ=True, RND=False, FOLDER=False, SEARCH="renders")
  464. UI_elements.roundrect(node, win,
  465. tileX-10,
  466. current_Y + win.scroll["assets"],
  467. 170,
  468. 200,
  469. 10,
  470. button=do,
  471. tip=talk.text("copy_file_as")+" "+newcreate,
  472. clip=[
  473. win.current["w"]/4+20,
  474. 400,
  475. width,
  476. height,
  477. ],
  478. offset=[
  479. win.current["w"]/4+20,
  480. 400])
  481. UI_color.set(node, win, "progress_background")
  482. UI_elements.roundrect(node, win,
  483. tileX-10,
  484. current_Y + win.scroll["assets"],
  485. 170,
  486. 200,
  487. 10,
  488. fill=False)
  489. node.stroke()
  490. UI_elements.image(node, win,
  491. "settings/themes/"+win.settings["Theme"]+"/icons/copy_file.png",
  492. tileX+55,
  493. current_Y + win.scroll["assets"] + 70,
  494. 40, 40)
  495. UI_color.set(node, win, "text_normal")
  496. node.set_font_size(12)
  497. node.move_to(tileX+75-len(newcreate)*4,
  498. current_Y + win.scroll["assets"]+150)
  499. node.show_text(newcreate)
  500. tileX += 200
  501. if tileX > width-180:
  502. tileX = 20
  503. current_Y += 230
  504. if not found_in and newcreate and win.current["asset_cur_folder"] == "blender":
  505. if not newcreate.endswith(".blend"):
  506. newcreate = newcreate+".blend"
  507. def do():
  508. oscalls.copy_file(
  509. win,
  510. os.getcwd()+"/new_file/"+acur+".blend",
  511. "/dev"+win.cur+"/",
  512. newcreate)
  513. win.text["in_asset"]["text"] = ""
  514. win.current["asset_file_selected"] = ""
  515. win.images = {}
  516. UI_elements.roundrect(node, win,
  517. tileX-10,
  518. current_Y + win.scroll["assets"],
  519. 170,
  520. 200,
  521. 10,
  522. button=do,
  523. tip=talk.text("create_new_blend_file")+" "+newcreate,
  524. clip=[
  525. win.current["w"]/4+20,
  526. 400,
  527. width,
  528. height,
  529. ],
  530. offset=[
  531. win.current["w"]/4+20,
  532. 400])
  533. UI_color.set(node, win, "progress_background")
  534. UI_elements.roundrect(node, win,
  535. tileX-10,
  536. current_Y + win.scroll["assets"],
  537. 170,
  538. 200,
  539. 10,
  540. fill=False)
  541. node.stroke()
  542. UI_elements.image(node, win,
  543. "settings/themes/"+win.settings["Theme"]+"/icons/new_file.png",
  544. tileX+55,
  545. current_Y + win.scroll["assets"] + 70,
  546. 40, 40)
  547. UI_color.set(node, win, "text_normal")
  548. node.set_font_size(12)
  549. node.move_to(tileX+75-len(newcreate)*4,
  550. current_Y + win.scroll["assets"]+150)
  551. node.show_text(newcreate)
  552. current_Y += 230
  553. UI_elements.scroll_area(layer, win, "assets",
  554. win.current["w"]/4+20,
  555. 400,
  556. width,
  557. height,
  558. current_Y,
  559. bar=True,
  560. mmb=True,
  561. url="assets")
  562. # Outputting the layer
  563. layer.set_source_surface(nodesurface,
  564. win.current["w"]/4+20,
  565. 400)
  566. layer.paint()
  567. ############## CHECKLIST ################
  568. if os.path.exists(win.project+"/dev/"+win.cur+"/asset.progress"):
  569. checklist.draw(layer, win, win.project+"/dev/"+win.cur+"/asset.progress", back=win.url)
  570. else:
  571. # If asset.progress does not exist in the folder it will try to create.
  572. # one. The only problem with now is language support. I have some ideas
  573. # I will need to work on it. But later.
  574. oscalls.copy_file(
  575. win,
  576. os.getcwd()+"/new_file/"+acur+".progress",
  577. "/dev"+win.cur+"/",
  578. "asset.progress")
  579. ############## LEFT PANEL ################
  580. # Here on the left panel I want to have 3 things. Which is already more then
  581. # the legacy organizer. But who are we deceiving? This is way cooler then
  582. # the legacy organizer.
  583. leftpanellist = ["scene", "schedule", "history"] # Using the names of the icons.
  584. # We need to choose the correct category based smartly on the project's
  585. # current progress. Or at least on the current progress of this asset.
  586. if "asset_left_panel" not in win.current:
  587. if fraction == 1.0: # If the asset is done
  588. win.current["asset_left_panel"] = "scene" # Then list scenes
  589. else: # Other
  590. win.current["asset_left_panel"] = "schedule" # List schedules
  591. # A little banner.
  592. UI_color.set(layer, win, "node_background")
  593. UI_elements.roundrect(layer, win,
  594. 10,
  595. 10,
  596. win.current["w"]/4-20,
  597. 50,
  598. 10)
  599. for num, thing in enumerate(leftpanellist):
  600. if win.current["asset_left_panel"] == thing:
  601. UI_color.set(layer, win, "progress_time")
  602. UI_elements.roundrect(layer, win,
  603. 20+(40*num),
  604. 15,
  605. 40,
  606. 40,
  607. 10)
  608. def do():
  609. win.current["asset_left_panel"] = thing
  610. UI_elements.roundrect(layer, win,
  611. 20+(40*num),
  612. 15,
  613. 40,
  614. 40,
  615. 10,
  616. do,
  617. thing)
  618. ### SCHEDULES ###
  619. if win.current["asset_left_panel"] == "schedule":
  620. schedule.draw(layer, win)
  621. ### HISTORY ###
  622. if win.current["asset_left_panel"] == "history":
  623. history.draw(layer, win)
  624. ### SCENES ###
  625. # Documentation entry
  626. def do():
  627. def after(win, var):
  628. pass
  629. studio_dialogs.help(win, "help", after, SEARCH=talk.text("documentation_assets"))
  630. UI_elements.roundrect(layer, win,
  631. win.current["w"]-40-win.current["w"]/4-50,
  632. win.current["h"]-80,
  633. 40,
  634. 40,
  635. 10,
  636. do,
  637. "question")
  638. # CANCEl
  639. def do():
  640. win.url = "story_editor"
  641. win.assets = {}
  642. win.current["asset_file_selected"] = ""
  643. UI_elements.roundrect(layer, win,
  644. win.current["w"]-40-win.current["w"]/4,
  645. win.current["h"]-80,
  646. 40,
  647. 40,
  648. 10,
  649. button=do,
  650. icon="cancel",
  651. tip=talk.text("cancel"))
  652. # Short cut ESC
  653. if 65307 in win.current["keys"] and not win.textactive:
  654. do()
  655. if win.current["asset_left_panel"] == "scene":
  656. # Here I want to parse the story data in pusuit of all the scenes that
  657. # have the asset. I think I'm going to make it per shot based. Like
  658. # you have the scenes. And you can open them to enter shots. Maybe with
  659. # a tiny exserp from the story.
  660. if "asset_scenes" not in win.scroll:
  661. win.scroll["asset_scenes"] = 0
  662. if "asset_scene_selected" not in win.current:
  663. win.current["asset_scene_selected"] = False
  664. x = 10
  665. y = 70
  666. width = win.current["w"] / 4 - 20
  667. height = win.current["h"] - 80
  668. UI_elements.roundrect(layer, win,
  669. x,
  670. y,
  671. width,
  672. height,
  673. 10,
  674. fill=False)
  675. layer.clip()
  676. current_Y_scenes = 0
  677. scenes = win.story["scenes"]
  678. for scene in scenes:
  679. fraction = scenes[scene]["fraction"]
  680. shots = scenes[scene]["shots"]
  681. foundinscene = []
  682. for num, block in enumerate(shots):
  683. si = 1
  684. if block[0] == "shot_block":
  685. si = 2
  686. found = []
  687. for n, stuff in enumerate(block[si]):
  688. # DIRECT LINK
  689. #print(block, si)
  690. if stuff[0] == "link" and stuff[1] == win.cur:
  691. start = ""
  692. part = stuff[-1]
  693. end = ""
  694. if n > 0:
  695. start = block[si][n-1][-1]
  696. start = start.replace("\n", " ")
  697. if n < len(block[si])-1:
  698. end = block[si][n+1][-1]
  699. end = end.replace("\n", " ")
  700. found = [start, part, end]
  701. if si == 2:
  702. foundinscene.append([block[1],found,num,n])
  703. else:
  704. foundinscene.append(["",found,num,n])
  705. # FRASE LINK
  706. if stuff[0] == "frase" and stuff[1][0] == "link" and stuff[1][1] == win.cur:
  707. start = ""
  708. part = stuff[1][-1]
  709. end = ""
  710. if n < len(block[si])-1:
  711. end = " : "+stuff[-1]
  712. found = [start, part, end]
  713. if si == 2:
  714. foundinscene.append([block[1],found,num ,n])
  715. else:
  716. foundinscene.append(["",found,num ,n])
  717. if foundinscene:
  718. UI_color.set(layer, win, "node_background")
  719. UI_elements.roundrect(layer, win,
  720. x,
  721. y+win.scroll["asset_scenes"]+current_Y_scenes,
  722. width,
  723. 70,
  724. 10)
  725. # ICON
  726. UI_elements.image(layer, win,
  727. "settings/themes/"+win.settings["Theme"]+"/icons/scene.png",
  728. 20, y+win.scroll["asset_scenes"] + current_Y_scenes+5, 40, 40)
  729. # SELECTION
  730. def do():
  731. if win.current["asset_scene_selected"] == scene:
  732. win.current["asset_scene_selected"] = False
  733. else:
  734. win.current["asset_scene_selected"] = scene
  735. UI_elements.roundrect(layer, win,
  736. x,
  737. y+win.scroll["asset_scenes"]+current_Y_scenes,
  738. width,
  739. 70,
  740. 10,
  741. button=do,
  742. fill=False)
  743. layer.stroke()
  744. # SCENE NAME
  745. UI_color.set(layer, win, "text_normal")
  746. layer.set_font_size(20)
  747. layer.move_to( x+60, y+win.scroll["asset_scenes"] + current_Y_scenes+30)
  748. layer.show_text(scene)
  749. # FRACTION
  750. UI_color.set(layer, win, "progress_background")
  751. UI_elements.roundrect(layer, win,
  752. x+10,
  753. y+50+win.scroll["asset_scenes"] + current_Y_scenes,
  754. width-20,
  755. 0,
  756. 5)
  757. UI_color.set(layer, win, "progress_active")
  758. UI_elements.roundrect(layer, win,
  759. x+10,
  760. y+50+win.scroll["asset_scenes"] + current_Y_scenes,
  761. (width-20)*fraction,
  762. 0,
  763. 5)
  764. # IF SELECTED
  765. if win.current["asset_scene_selected"] == scene:
  766. UI_color.set(layer, win, "progress_background")
  767. UI_elements.roundrect(layer, win,
  768. x,
  769. y+win.scroll["asset_scenes"]+current_Y_scenes,
  770. width,
  771. 70,
  772. 10,
  773. fill=False)
  774. layer.stroke()
  775. # Here if the current scene is selected I want to draw all
  776. # the parts of the scene. It's already a bit more complex
  777. # then what was in the Blender-Organizer legacy.
  778. current_Y_scenes = current_Y_scenes + 80
  779. for block in foundinscene:
  780. # If it's a shot let's mark in the different color.
  781. if block[0]:
  782. if "shot_colors" not in win.story:
  783. win.story["shot_colors"] = {}
  784. surl = "/"+scene+"/"+block[0]
  785. if surl not in win.story["shot_colors"]:
  786. rcolors = [
  787. "shot_1",
  788. "shot_2",
  789. "shot_3",
  790. "shot_4",
  791. "shot_5"
  792. ]
  793. win.story["shot_colors"][surl] = rcolors[len(win.story["shot_colors"]) % len(rcolors)]
  794. col = win.story["shot_colors"][surl]
  795. UI_color.set(layer, win, col)
  796. else:
  797. UI_color.set(layer, win, "node_background")
  798. UI_elements.roundrect(layer, win,
  799. x,
  800. y+win.scroll["asset_scenes"]+current_Y_scenes,
  801. width,
  802. 30,
  803. 10)
  804. # GET TO THE SCENE BUTTON
  805. def do():
  806. win.current["script_find"] = [block[2],block[3]]
  807. win.url = "script"
  808. print(scene)
  809. win.cur = "/"+scene+"/"+block[0]
  810. print(win.cur)
  811. UI_elements.roundrect(layer, win,
  812. x,
  813. y+win.scroll["asset_scenes"]+current_Y_scenes,
  814. width,
  815. 30,
  816. 10,
  817. button=do,
  818. fill=False)
  819. layer.stroke()
  820. start = block[1][0]
  821. name = block[1][1]
  822. end = block[1][2]
  823. sp = x+width/2-len(name)*12/2-len(start)*12
  824. np = x+width/2-len(name)*12/2
  825. ep = x+width/2+len(name)*12/2
  826. if sp > x+5 and x+5 + ep + len(end)*12 > width:
  827. sp = x+5
  828. np = x+5 + len(start)*12
  829. ep = x+5 + len(start)*12 + len(name)*12
  830. elif ep + len(end)*12 < width and sp < x+5:
  831. ep = width - len(end)*12
  832. np = ep - len(name)*12
  833. sp = np - len(start)*12
  834. # BEFORE NAME
  835. UI_color.set(layer, win, "text_normal")
  836. layer.set_font_size(20)
  837. layer.move_to( sp, y+win.scroll["asset_scenes"] + current_Y_scenes+20)
  838. layer.show_text(start)
  839. # NAME AS MENTIONED IN THE SCRIPT
  840. UI_color.set(layer, win, "node_asset")
  841. UI_elements.roundrect(layer, win,
  842. np-6,
  843. y+win.scroll["asset_scenes"]+current_Y_scenes+2,
  844. len(name)*12+12,
  845. 26,
  846. 10)
  847. UI_color.set(layer, win, "text_normal")
  848. layer.set_font_size(20)
  849. layer.move_to(np, y+win.scroll["asset_scenes"] + current_Y_scenes+20)
  850. layer.show_text(name)
  851. # AFTER NAME
  852. UI_color.set(layer, win, "text_normal")
  853. layer.set_font_size(20)
  854. layer.move_to( ep, y+win.scroll["asset_scenes"] + current_Y_scenes+20)
  855. layer.show_text(end)
  856. current_Y_scenes = current_Y_scenes + 40
  857. else:
  858. current_Y_scenes = current_Y_scenes + 80
  859. # Scroll
  860. UI_elements.scroll_area(layer, win, "asset_scenes",
  861. x+0,
  862. y+50,
  863. width,
  864. height-50,
  865. current_Y_scenes,
  866. bar=True,
  867. mmb=True)
  868. return surface