studio_file_selectLayer.py 14 KB

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