# THIS FILE IS A PART OF VCStudio # PYTHON 3 # This a console project manager. import os # GTK module ( Graphical interface import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk from gi.repository import GLib from gi.repository import Gdk import cairo # Own modules from settings import settings from settings import talk from settings import fileformats from settings import oscalls from project_manager import pm_project #UI modules from UI import UI_elements from UI import UI_color # story from studio import story from studio import checklist from studio import analytics from studio import studio_dialogs from studio import schedule def layer(win): # Making the layer surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, win.current['w'], win.current['h']) layer = cairo.Context(surface) #text setting layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) UI_color.set(layer, win, "dark_overdrop") layer.rectangle( 0, 0, win.current["w"], win.current["h"], ) layer.fill() UI_color.set(layer, win, "node_background") UI_elements.roundrect(layer, win, win.current["w"]/4, 150, win.current["w"]/2, win.current["h"]-190, 10) ############################################################################ # This file will be showing stuff about an asset. It's almost like a folder # / folders of the asset. But with some extendet functionality. Stuff that # will be on screen will include. # Progress Bar # Checklist # Scenes list in which the asset is mentioned # History / Schedules # It's similar to the old Blender Organizer's Asset thing. But a bit more # modern looking. I would say. ############################################################################ # before we start I want to make a little safe mechanism. Just in case the # win.cur is not written properly. # Parsing the cur to get name and type name = win.cur[win.cur.rfind("/")+1:] acur = win.cur.replace(name, "").replace("/", "") if not os.path.exists(win.project+"/dev/"+win.cur) or not win.cur: def select_character(win, var): if var: win.url = "assets" win.cur = var else: win.url = "story_editor" if not acur: acur = "chr" studio_dialogs.asset_select(win, "select_asset_check", select_character, force=True, cur=acur, SEARCH=name) if not "asset_cur_folder" in win.current: win.current["asset_cur_folder"] = "blender" ####### MIDDLE PANNEL ####### def do(): oscalls.Open(win.project+"/dev"+win.cur) UI_elements.roundrect(layer, win, win.current["w"]/4+20, 350, 40, 40, 10, do, "folder") folds = { "blender":"blend_files_folder", "idea":"reference_folder", "texture":"tex_folder", "render":"renders_folder" } for num, cur in enumerate(folds): if win.current["asset_cur_folder"] == cur: UI_color.set(layer, win, "progress_time") UI_elements.roundrect(layer, win, win.current["w"]/4+150+(40*num), 350, 40, 40, 10) def do(): win.current["asset_cur_folder"] = cur UI_elements.roundrect(layer, win, win.current["w"]/4+150+(40*num), 350, 40, 40, 10, do, cur, tip=talk.text(folds[cur])) # Preview # Making the layer nodesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 300, 300) node = cairo.Context(nodesurface) node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) UI_elements.roundrect(node, win, 0, 0, 300, 300, 10, fill=False) node.clip() if os.path.exists(win.project+"/dev"+win.cur+"/renders/Preview.png"): UI_elements.image(node, win, win.project+"/dev"+win.cur+"/renders/Preview.png", 0, 0, 300, 300, cell="big_asset_previews") elif os.path.exists(win.project+"/dev"+win.cur+"/renders/Preview.jpg"): UI_elements.image(node, win, win.project+"/dev"+win.cur+"/renders/Preview.jpg", 0, 0, 300, 300, cell="big_asset_previews") else: UI_color.set(node, win, "dark_overdrop") node.rectangle(0,0,300, 300) node.fill() UI_elements.image(node, win, "settings/themes/"+win.settings["Theme"]+"/icons/"+acur+".png", 130, 130, 40, 40) def do(): def after(win, var): win.current["asset_file_selected"] = "" win.images = {} if var: for t in fileformats.images: if var.endswith(t): oscalls.copy_file( win, var, "/dev"+win.cur+"/renders/", "Preview.png") break studio_dialogs.file_select(win, name+"_preview", after, force=True, IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, LOC=True, OBJ=True, RND=False, FOLDER=False, SEARCH=win.cur+" renders") UI_elements.roundrect(node, win, 2, 2, 296, 296, 10, button=do, fill=False, offset=[ win.current["w"]/4+20, 20 ] ) node.stroke() # Outputting the layer layer.set_source_surface(nodesurface, win.current["w"]/4+20, 20) layer.paint() # Name of the asset UI_elements.image(layer, win, "settings/themes/"+win.settings["Theme"]+"/icons/"+acur+".png", win.current["w"]/4+360, 210, 40, 40) UI_color.set(layer, win, "text_normal") layer.set_font_size(30) layer.move_to(win.current["w"]/4+410,240) layer.show_text(name) # Fraction fraction = story.get_asset_data(win, win.cur)["fraction"] UI_color.set(layer, win, "progress_background") UI_elements.roundrect(layer, win, win.current["w"]/4+350, 270, (win.current["w"]/2-370), 0, 10) UI_color.set(layer, win, "progress_active") UI_elements.roundrect(layer, win, win.current["w"]/4+350, 270, (win.current["w"]/2-370)*fraction, 0, 10) # Search UI_elements.image(layer, win, "settings/themes/"\ +win.settings["Theme"]+"/icons/search.png", win.current["w"]-280-win.current["w"]/4, 350, 40, 40) UI_elements.text(layer, win, "in_asset", win.current["w"]-240-win.current["w"]/4, 350, 220, 40) # FILES # In case the user made the folder manually. try: os.mkdir(win.project+"/dev/"+win.cur+"/renders") os.mkdir(win.project+"/dev/"+win.cur+"/reference") os.mkdir(win.project+"/dev/"+win.cur+"/tex") except: pass # Now let's prepare the frame width = win.current["w"]/2- 40 height = win.current["h"] - 500 # Making the layer nodesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height)) node = cairo.Context(nodesurface) node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) UI_elements.roundrect(node, win, 0, 0, width, height, 10, fill=False) node.clip() # Now let's prepare the scrooler tileX = 20 current_Y = 10 if "assets" not in win.scroll: win.scroll["assets"] = 0 ########################### # Let's get the list of the files first. files = [] newcreate = win.text["in_asset"]["text"].replace("/","_").replace(" ", "_")\ .replace('"',"_").replace("(","_").replace(")","_").replace("'","_")\ .replace("[","_").replace("]","_").replace("{","_").replace("}","_") foundblend = True found_in = False if win.current["asset_cur_folder"] == "blender": foundblend = False # Let's see if an asset blend file exists. if os.path.exists(win.project+"/ast"+win.cur+".blend") and not newcreate: files.append(["/ast"+win.cur+".blend", "node_asset"]) foundblend = True for f in os.listdir(win.project+"/dev"+win.cur): if not os.path.isdir(win.project+"/dev"+win.cur+"/"+f): # This is for only the blend files. So let's filter the out of all # the noise. For all files there is a folder icon. if newcreate == f: found_in = True if newcreate and newcreate.lower() not in f.lower(): continue if f.endswith(".blend"): files.append(["/dev"+win.cur+"/"+f, "node_blendfile"]) foundblend = True else: # This all the rest of the files. if win.current["asset_cur_folder"] == "idea": fl = "reference" elif win.current["asset_cur_folder"] == "texture": fl = "tex" elif win.current["asset_cur_folder"] == "render": fl = "renders" for f in os.listdir(win.project+"/dev"+win.cur+"/"+fl): if not os.path.isdir(win.project+"/dev"+win.cur+"/"+fl+"/"+f): if newcreate == f: found_in = True if newcreate and newcreate.lower() not in f.lower(): continue # Now it has to be image or video files. For the rest you have # the folder icon. for t in fileformats.images: if f.endswith(t): files.append(["/dev"+win.cur+"/"+fl+"/"+f, "node_imagefile"]) for t in fileformats.videos: if f.endswith(t): files.append(["/dev"+win.cur+"/"+fl+"/"+f, "node_videofile"]) # Let's make sure that we have at least some blendfile there. if not foundblend and not newcreate: oscalls.copy_file( win, os.getcwd()+"/new_file/"+acur+".blend", "/dev"+win.cur+"/", name+".blend") if "asset_file_selected" not in win.current: win.current["asset_file_selected"] = "" for filename, thecoloris in files: if int(current_Y + win.scroll["assets"]) in range(0-200, height): # Making the layer node2surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 170, 200) node2 = cairo.Context(node2surface) node2.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) UI_elements.roundrect(node2, win, 0, 0, 170, 200, 10, fill=False) node2.clip() # Background UI_color.set(node2, win, "dark_overdrop") node2.rectangle(0,0,170, 200) node2.fill() # Banner UI_color.set(node2, win, thecoloris) node2.rectangle(0,0,170, 20) node2.fill() # Outputting the layer node.set_source_surface(node2surface, tileX-10, current_Y + win.scroll["assets"] ) node.paint() UI_elements.image(node, win, win.project+filename, tileX, current_Y + win.scroll["assets"] + 30, 150, 150) UI_color.set(node, win, "text_normal") node.set_font_size(12) node.move_to(tileX, current_Y + win.scroll["assets"]+15) node.show_text(filename[filename.rfind("/")+1:][:22]) # If selected node.set_line_width(4) if win.current["asset_file_selected"] == win.project+filename: UI_color.set(node, win, "progress_background") UI_elements.roundrect(node, win, tileX-10, current_Y + win.scroll["assets"], 170, 200, 10, fill=False) node.stroke() # Button to activate it def do(): if win.current["asset_file_selected"] != win.project+filename: win.current["asset_file_selected"] = win.project+filename else: oscalls.file_open(win, win.project+filename) UI_elements.roundrect(node, win, tileX-10, current_Y + win.scroll["assets"], 170, 200, 10, button=do, tip=filename, fill=False, clip=[ win.current["w"]/4+20, 400, width, height, ], offset=[ win.current["w"]/4+20, 400]) node.stroke() node.set_line_width(2) tileX += 200 if tileX > width-180: tileX = 20 current_Y += 230 ########################### # Now i'd like to make things addable. For now if it's a blends selected # there will an option to add new one and an option to copy. While other # files will have an option of only copy. (At least for now. Untill I # figure out what new images will it give.) if not found_in and newcreate: if win.current["asset_cur_folder"] == "blender"\ and not newcreate.endswith(".blend"): newcreate = newcreate+".blend" def do(): def after(win, var): newcreate = win.text["in_asset"]["text"].replace("/","_").replace(" ", "_")\ .replace('"',"_").replace("(","_").replace(")","_").replace("'","_")\ .replace("[","_").replace("]","_").replace("{","_").replace("}","_") win.text["in_asset"]["text"] = "" win.current["asset_file_selected"] = "" win.images = {} if var: if win.current["asset_cur_folder"] == "blender"\ and var.endswith(".blend"): if not newcreate.endswith(".blend"): newcreate = newcreate+".blend" oscalls.copy_file( win, var, "/dev"+win.cur+"/", newcreate) else: # In case the copying file is not a blend file. Let's # make sure that it's infect an image. for t in fileformats.images: if var.endswith(t): if not newcreate.endswith(t): newcreate = newcreate + "." + t if win.current["asset_cur_folder"] == "idea": fl = "reference" elif win.current["asset_cur_folder"] == "texture": fl = "tex" elif win.current["asset_cur_folder"] == "render": fl = "renders" oscalls.copy_file( win, var, "/dev"+win.cur+"/"+fl+"/", newcreate) break if win.current["asset_cur_folder"] == "blender": studio_dialogs.file_select(win, name+"_blends", after, force=True, IMAGE=False, BLEND=True, VIDEO=False, FILE=False, CHR=True, VEH=True, LOC=True, OBJ=True, RND=False, FOLDER=False) elif win.current["asset_cur_folder"] == "idea": studio_dialogs.file_select(win, name+"_reference", after, force=True, IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, LOC=True, OBJ=True, RND=False, FOLDER=False, SEARCH="reference") elif win.current["asset_cur_folder"] == "texture": studio_dialogs.file_select(win, name+"_reference", after, force=True, IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, LOC=True, OBJ=True, RND=False, FOLDER=False, SEARCH="tex") elif win.current["asset_cur_folder"] == "render": studio_dialogs.file_select(win, name+"_reference", after, force=True, IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, LOC=True, OBJ=True, RND=False, FOLDER=False, SEARCH="renders") UI_elements.roundrect(node, win, tileX-10, current_Y + win.scroll["assets"], 170, 200, 10, button=do, tip=talk.text("copy_file_as")+" "+newcreate, clip=[ win.current["w"]/4+20, 400, width, height, ], offset=[ win.current["w"]/4+20, 400]) UI_color.set(node, win, "progress_background") UI_elements.roundrect(node, win, tileX-10, current_Y + win.scroll["assets"], 170, 200, 10, fill=False) node.stroke() UI_elements.image(node, win, "settings/themes/"+win.settings["Theme"]+"/icons/copy_file.png", tileX+55, current_Y + win.scroll["assets"] + 70, 40, 40) UI_color.set(node, win, "text_normal") node.set_font_size(12) node.move_to(tileX+75-len(newcreate)*4, current_Y + win.scroll["assets"]+150) node.show_text(newcreate) tileX += 200 if tileX > width-180: tileX = 20 current_Y += 230 if not found_in and newcreate and win.current["asset_cur_folder"] == "blender": if not newcreate.endswith(".blend"): newcreate = newcreate+".blend" def do(): oscalls.copy_file( win, os.getcwd()+"/new_file/"+acur+".blend", "/dev"+win.cur+"/", newcreate) win.text["in_asset"]["text"] = "" win.current["asset_file_selected"] = "" win.images = {} UI_elements.roundrect(node, win, tileX-10, current_Y + win.scroll["assets"], 170, 200, 10, button=do, tip=talk.text("create_new_blend_file")+" "+newcreate, clip=[ win.current["w"]/4+20, 400, width, height, ], offset=[ win.current["w"]/4+20, 400]) UI_color.set(node, win, "progress_background") UI_elements.roundrect(node, win, tileX-10, current_Y + win.scroll["assets"], 170, 200, 10, fill=False) node.stroke() UI_elements.image(node, win, "settings/themes/"+win.settings["Theme"]+"/icons/new_file.png", tileX+55, current_Y + win.scroll["assets"] + 70, 40, 40) UI_color.set(node, win, "text_normal") node.set_font_size(12) node.move_to(tileX+75-len(newcreate)*4, current_Y + win.scroll["assets"]+150) node.show_text(newcreate) current_Y += 230 UI_elements.scroll_area(layer, win, "assets", win.current["w"]/4+20, 400, width, height, current_Y, bar=True, mmb=True, url="assets") # Outputting the layer layer.set_source_surface(nodesurface, win.current["w"]/4+20, 400) layer.paint() ############## CHECKLIST ################ if os.path.exists(win.project+"/dev/"+win.cur+"/asset.progress"): checklist.draw(layer, win, win.project+"/dev/"+win.cur+"/asset.progress", back=win.url) else: # If asset.progress does not exist in the folder it will try to create. # one. The only problem with now is language support. I have some ideas # I will need to work on it. But later. oscalls.copy_file( win, os.getcwd()+"/new_file/"+acur+".progress", "/dev"+win.cur+"/", "asset.progress") ############## LEFT PANEL ################ # Here on the left panel I want to have 3 things. Which is already more then # the legacy organizer. But who are we deceiving? This is way cooler then # the legacy organizer. leftpanellist = ["vse", "schedule", "history"] # Using the names of the icons. # We need to choose the correct category based smartly on the project's # current progress. Or at least on the current progress of this asset. if "asset_left_panel" not in win.current: if fraction == 1.0: # If the asset is done win.current["asset_left_panel"] = "vse" # Then list scenes else: # Other win.current["asset_left_panel"] = "schedule" # List schedules # A little banner. UI_color.set(layer, win, "node_background") UI_elements.roundrect(layer, win, 10, 10, win.current["w"]/4-20, 50, 10) for num, thing in enumerate(leftpanellist): if win.current["asset_left_panel"] == thing: UI_color.set(layer, win, "progress_time") UI_elements.roundrect(layer, win, 20+(40*num), 15, 40, 40, 10) def do(): win.current["asset_left_panel"] = thing UI_elements.roundrect(layer, win, 20+(40*num), 15, 40, 40, 10, do, thing) ### SCHEDULES ### if win.current["asset_left_panel"] == "schedule": schedule.draw(layer, win) # CANCEl def do(): win.url = "story_editor" win.assets = {} win.current["asset_file_selected"] = "" UI_elements.roundrect(layer, win, win.current["w"]-40-win.current["w"]/4, win.current["h"]-80, 40, 40, 10, button=do, icon="cancel", tip=talk.text("cancel")) # Short cut ESC if 65307 in win.current["keys"] and not win.textactive: do() return surface