studio_file_selectLayer.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  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 project_manager import pm_project
  17. #UI modules
  18. from UI import UI_elements
  19. from UI import UI_color
  20. from UI import UI_math
  21. # Studio
  22. from studio import checklist
  23. def layer(win, call):
  24. # Making the layer
  25. surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, win.current['w'],
  26. win.current['h'])
  27. layer = cairo.Context(surface)
  28. #text setting
  29. layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
  30. UI_color.set(layer, win, "dark_overdrop")
  31. layer.rectangle(
  32. 0,
  33. 0,
  34. win.current["w"],
  35. win.current["h"],
  36. )
  37. layer.fill()
  38. UI_color.set(layer, win, "node_background")
  39. UI_elements.roundrect(layer, win,
  40. 40,
  41. 40,
  42. win.current["w"]-80,
  43. win.current["h"]-80,
  44. 10)
  45. ############################################################################
  46. # This dialogue deals with file selection. This is not the only place where
  47. # files are drawn. So don't rely on this dialog only.
  48. # To make all the files drawn first off all I want to get all the files data
  49. # and later to clean it. The problem is that it's running on every frame so
  50. # some particular cleverness is required.
  51. # I do want to clean after the dialog is closed so if a change in the files
  52. # happened it could be loaded on the next loading of this window.
  53. # On the other hand reading all the file dynamically would not be wise because
  54. # of expected volume of those files. For things like textures folder in the
  55. # assets it could be possible. But here it will look through the entire
  56. # project. With all the renders of all of the shots from all of the scenes.
  57. # Imagine a movie that is 2 hour long and it's a good 24 frames per second.
  58. # Each of which has 4 versions saved in different folders. This is not the
  59. # kind of data I would try to load dynamically. Unless you know a clever
  60. # way to do so. Please tell me so if you do.
  61. ############################################################################
  62. if "AllFiles" not in win.current:
  63. win.current["AllFiles"] = []
  64. for r, d, f in os.walk(win.project):
  65. for item in f:
  66. win.current["AllFiles"].append(os.path.join(r, item).replace(win.project, ""))
  67. UI_math.sort_nicely(win.current["AllFiles"])
  68. # Now that we have the files. There should be some way to filter them.
  69. # I guess let's add a searchbox and buttons on the side for filtering.
  70. if "file_selector" not in win.current:
  71. win.current["file_selector"] = {
  72. "image" :True,
  73. "blender":False,
  74. "video" :True,
  75. "file" :False,
  76. "chr" :True,
  77. "veh" :True,
  78. "loc" :True,
  79. "obj" :True,
  80. "vse" :False,
  81. "folder" :False
  82. }
  83. ############### TOP PANEL ###################
  84. # Left Icons
  85. for num, thing in enumerate(win.current["file_selector"]):
  86. if num > 3:
  87. num = num + 1
  88. if win.current["file_selector"][thing]:
  89. UI_color.set(layer, win, "progress_time")
  90. UI_elements.roundrect(layer, win,
  91. 50+(40*num),
  92. 50,
  93. 40,
  94. 40,
  95. 10)
  96. def do():
  97. win.current["file_selector"][thing] = not win.current["file_selector"][thing]
  98. UI_elements.roundrect(layer, win,
  99. 50+(40*num),
  100. 50,
  101. 40,
  102. 40,
  103. 10,
  104. do,
  105. thing)
  106. # Search
  107. UI_elements.image(layer, win, "settings/themes/"\
  108. +win.settings["Theme"]+"/icons/search.png",
  109. win.current["w"]-440,
  110. 50,
  111. 40,
  112. 40)
  113. UI_elements.text(layer, win, "file_select_search",
  114. win.current["w"]-400,
  115. 50,
  116. 350,
  117. 40)
  118. ##### BOTTOM BUTTONS ####
  119. def do():
  120. filechooser = Gtk.FileChooserDialog(talk.text("select_file"),
  121. None,
  122. Gtk.FileChooserAction.OPEN,
  123. (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
  124. Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
  125. filechooser.set_default_response(Gtk.ResponseType.OK)
  126. response = filechooser.run()
  127. if response == Gtk.ResponseType.OK:
  128. get = filechooser.get_filename()
  129. win.current["calls"][call]["var"] = get
  130. del win.current["AllFiles"]
  131. filechooser.destroy()
  132. UI_elements.roundrect(layer, win,
  133. win.current["w"]-120,
  134. win.current["h"]-80,
  135. 40,
  136. 40,
  137. 10,
  138. button=do,
  139. icon="folder",
  140. tip=talk.text("outside_folder"))
  141. def do():
  142. win.current["calls"][call]["var"] = False
  143. del win.current["AllFiles"]
  144. UI_elements.roundrect(layer, win,
  145. win.current["w"]-80,
  146. win.current["h"]-80,
  147. 40,
  148. 40,
  149. 10,
  150. button=do,
  151. icon="cancel",
  152. tip=talk.text("cancel"))
  153. # Short cut ESC
  154. if 65307 in win.current["keys"] and not win.textactive:
  155. do()
  156. # Now let's prepare the ground for the next part.
  157. UI_elements.roundrect(layer, win,
  158. 50,
  159. 100,
  160. win.current["w"]-100,
  161. win.current["h"]-200,
  162. 10,
  163. fill=False)
  164. layer.clip()
  165. ### ACTUALL FILES LIST ###
  166. tileX = 70
  167. current_Y = 0
  168. if "file_select" not in win.scroll:
  169. win.scroll["file_select"] = 0
  170. if "AllFiles" in win.current:
  171. for filename in reversed(win.current["AllFiles"]):
  172. ######################## FILTERING STARTS ##########################
  173. okay = UI_math.found(filename, win.text["file_select_search"]["text"])
  174. # Remove all _backup files
  175. if "_backup" in filename:
  176. okay = False
  177. # By search
  178. # for stuff in win.text["file_select_search"]["text"].split(" "):
  179. # if stuff:
  180. # if stuff.lower() not in filename.lower():
  181. # okay = False
  182. # By folder
  183. folderfound = False
  184. if okay and "chr/" in filename:
  185. folderfound = True
  186. if not win.current["file_selector"]["chr"]:
  187. okay = False
  188. if okay and "veh/" in filename:
  189. folderfound = True
  190. if not win.current["file_selector"]["veh"]:
  191. okay = False
  192. if okay and "loc/" in filename:
  193. folderfound = True
  194. if not win.current["file_selector"]["loc"]:
  195. okay = False
  196. if okay and "obj/" in filename:
  197. folderfound = True
  198. if not win.current["file_selector"]["obj"]:
  199. okay = False
  200. if okay and "rnd/" in filename:
  201. folderfound = True
  202. if not win.current["file_selector"]["vse"]:
  203. okay = False
  204. if okay and not folderfound:
  205. if not win.current["file_selector"]["folder"]:
  206. okay = False
  207. # By filetype
  208. typefound = False
  209. if okay:
  210. # Images
  211. for f in fileformats.images:
  212. if filename.endswith(f):
  213. typefound = True
  214. thecoloris = "node_imagefile"
  215. if not win.current["file_selector"]["image"]:
  216. okay = False
  217. break
  218. if okay:
  219. # Videos
  220. for f in fileformats.videos:
  221. if filename.endswith(f):
  222. typefound = True
  223. thecoloris = "node_videofile"
  224. if not win.current["file_selector"]["video"]:
  225. okay = False
  226. break
  227. if okay:
  228. # Blend Files
  229. if filename.endswith(".blend"):
  230. typefound = True
  231. thecoloris = "node_blendfile"
  232. if "ast/" in filename:
  233. thecoloris = "node_asset"
  234. if not win.current["file_selector"]["blender"]:
  235. okay = False
  236. if okay:
  237. if typefound == False:
  238. thecoloris = "node_script"
  239. if not win.current["file_selector"]["file"]:
  240. okay = False
  241. ######################### FILTERING END ############################
  242. if okay:
  243. if int(current_Y + win.scroll["file_select"] + 100) in range(0-100, win.current["h"]):
  244. # Making the layer
  245. nodesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 170, 200)
  246. node = cairo.Context(nodesurface)
  247. node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
  248. UI_elements.roundrect(node, win,
  249. 0,
  250. 0,
  251. 170,
  252. 200,
  253. 10,
  254. fill=False)
  255. node.clip()
  256. # Background
  257. UI_color.set(node, win, "dark_overdrop")
  258. node.rectangle(0,0,170, 200)
  259. node.fill()
  260. # Banner
  261. UI_color.set(node, win, thecoloris)
  262. node.rectangle(0,0,170, 20)
  263. node.fill()
  264. # Outputting the layer
  265. layer.set_source_surface(nodesurface,
  266. tileX-10,
  267. current_Y + win.scroll["file_select"] + 120)
  268. layer.paint()
  269. UI_elements.image(layer, win, win.project+filename,
  270. tileX,
  271. current_Y + win.scroll["file_select"] + 150,
  272. 150,
  273. 150)
  274. # If this is a checklist
  275. if filename.endswith(".progress"):
  276. fraction = checklist.get_fraction(win, filename)
  277. UI_color.set(layer, win, "progress_background")
  278. UI_elements.roundrect(layer, win,
  279. tileX,
  280. current_Y + win.scroll["file_select"] + 300,
  281. 150,
  282. 0,
  283. 5)
  284. UI_color.set(layer, win, "progress_active")
  285. UI_elements.roundrect(layer, win,
  286. tileX,
  287. current_Y + win.scroll["file_select"] + 300,
  288. 150*fraction,
  289. 0,
  290. 5)
  291. UI_color.set(layer, win, "text_normal")
  292. layer.set_font_size(12)
  293. layer.move_to(tileX,
  294. current_Y + win.scroll["file_select"] + 135)
  295. layer.show_text(filename[filename.rfind("/")+1:][:22])
  296. # Button to activate it
  297. def do():
  298. win.current["calls"][call]["var"] = filename
  299. layer.set_line_width(4)
  300. UI_elements.roundrect(layer, win,
  301. tileX-10,
  302. current_Y + win.scroll["file_select"] + 120,
  303. 170,
  304. 200,
  305. 10,
  306. button=do,
  307. tip=filename,
  308. fill=False,
  309. clip=[
  310. 50,
  311. 100,
  312. win.current["w"]-100,
  313. win.current["h"]-200
  314. ])
  315. layer.stroke()
  316. layer.set_line_width(2)
  317. tileX += 200
  318. if tileX > win.current["w"]-220:
  319. tileX = 70
  320. current_Y += 230
  321. current_Y += 230
  322. UI_elements.scroll_area(layer, win, "file_select",
  323. 50,
  324. 100,
  325. win.current["w"]-100,
  326. win.current["h"]-200,
  327. current_Y,
  328. bar=True,
  329. mmb=True,
  330. url="file_select",
  331. strenght=130
  332. )
  333. return surface