1133 lines
37 KiB
Python
1133 lines
37 KiB
Python
# 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
|
|
from studio import history
|
|
|
|
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)
|
|
|
|
# Before search. On the other side when you have done the asset there will
|
|
# be a little configure icon. This is configuration for linking. Creating
|
|
# the /ast/ blend.file and autolink.data file. So the linker could link
|
|
# the files into the animation scene.
|
|
#
|
|
# See:
|
|
# studio/studio_shot_linkLayer.py
|
|
# studio/bpy_do_linking.py
|
|
# studio/studio_asset_configureLayer.py
|
|
|
|
def do():
|
|
|
|
def after(win, var):
|
|
print(var)
|
|
|
|
studio_dialogs.asset_configure(win, "configuring_asset", after, win.cur)
|
|
|
|
UI_elements.roundrect(layer, win,
|
|
win.current["w"]/4*3-60,
|
|
210,
|
|
40,
|
|
40,
|
|
10,
|
|
button=do,
|
|
icon="link_configure")
|
|
|
|
|
|
# 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 sorted(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 sorted(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 = ["scene", "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"] = "scene" # 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)
|
|
|
|
### HISTORY ###
|
|
|
|
if win.current["asset_left_panel"] == "history":
|
|
history.draw(layer, win)
|
|
|
|
### SCENES ###
|
|
|
|
# Documentation entry
|
|
def do():
|
|
def after(win, var):
|
|
pass
|
|
|
|
studio_dialogs.help(win, "help", after, SEARCH=talk.text("documentation_assets"))
|
|
|
|
UI_elements.roundrect(layer, win,
|
|
win.current["w"]-40-win.current["w"]/4-50,
|
|
win.current["h"]-80,
|
|
40,
|
|
40,
|
|
10,
|
|
do,
|
|
"question")
|
|
|
|
# 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()
|
|
|
|
if win.current["asset_left_panel"] == "scene":
|
|
|
|
# Here I want to parse the story data in pusuit of all the scenes that
|
|
# have the asset. I think I'm going to make it per shot based. Like
|
|
# you have the scenes. And you can open them to enter shots. Maybe with
|
|
# a tiny exserp from the story.
|
|
|
|
if "asset_scenes" not in win.scroll:
|
|
win.scroll["asset_scenes"] = 0
|
|
|
|
if "asset_scene_selected" not in win.current:
|
|
win.current["asset_scene_selected"] = False
|
|
|
|
x = 10
|
|
y = 70
|
|
width = win.current["w"] / 4 - 20
|
|
height = win.current["h"] - 80
|
|
|
|
|
|
UI_elements.roundrect(layer, win,
|
|
x,
|
|
y,
|
|
width,
|
|
height,
|
|
10,
|
|
fill=False)
|
|
layer.clip()
|
|
|
|
current_Y_scenes = 0
|
|
|
|
scenes = win.story["scenes"]
|
|
|
|
for scene in scenes:
|
|
fraction = scenes[scene]["fraction"]
|
|
shots = scenes[scene]["shots"]
|
|
|
|
foundinscene = []
|
|
|
|
for num, block in enumerate(shots):
|
|
|
|
si = 1
|
|
if block[0] == "shot_block":
|
|
si = 2
|
|
|
|
found = []
|
|
|
|
for n, stuff in enumerate(block[si]):
|
|
|
|
# DIRECT LINK
|
|
#print(block, si)
|
|
if stuff[0] == "link" and stuff[1] == win.cur:
|
|
|
|
start = ""
|
|
part = stuff[-1]
|
|
end = ""
|
|
|
|
if n > 0:
|
|
start = block[si][n-1][-1]
|
|
start = start.replace("\n", " ")
|
|
|
|
if n < len(block[si])-1:
|
|
end = block[si][n+1][-1]
|
|
end = end.replace("\n", " ")
|
|
|
|
found = [start, part, end]
|
|
if si == 2:
|
|
foundinscene.append([block[1],found,num,n])
|
|
else:
|
|
foundinscene.append(["",found,num,n])
|
|
|
|
# FRASE LINK
|
|
|
|
if stuff[0] == "frase" and stuff[1][0] == "link" and stuff[1][1] == win.cur:
|
|
|
|
start = ""
|
|
part = stuff[1][-1]
|
|
end = ""
|
|
|
|
|
|
if n < len(block[si])-1:
|
|
end = " : "+stuff[-1]
|
|
|
|
|
|
found = [start, part, end]
|
|
if si == 2:
|
|
foundinscene.append([block[1],found,num ,n])
|
|
else:
|
|
foundinscene.append(["",found,num ,n])
|
|
|
|
if foundinscene:
|
|
|
|
UI_color.set(layer, win, "node_background")
|
|
UI_elements.roundrect(layer, win,
|
|
x,
|
|
y+win.scroll["asset_scenes"]+current_Y_scenes,
|
|
width,
|
|
70,
|
|
10)
|
|
|
|
# ICON
|
|
UI_elements.image(layer, win,
|
|
"settings/themes/"+win.settings["Theme"]+"/icons/scene.png",
|
|
20, y+win.scroll["asset_scenes"] + current_Y_scenes+5, 40, 40)
|
|
|
|
# SELECTION
|
|
def do():
|
|
if win.current["asset_scene_selected"] == scene:
|
|
win.current["asset_scene_selected"] = False
|
|
else:
|
|
win.current["asset_scene_selected"] = scene
|
|
|
|
|
|
UI_elements.roundrect(layer, win,
|
|
x,
|
|
y+win.scroll["asset_scenes"]+current_Y_scenes,
|
|
width,
|
|
70,
|
|
10,
|
|
button=do,
|
|
fill=False)
|
|
layer.stroke()
|
|
|
|
# SCENE NAME
|
|
UI_color.set(layer, win, "text_normal")
|
|
layer.set_font_size(20)
|
|
layer.move_to( x+60, y+win.scroll["asset_scenes"] + current_Y_scenes+30)
|
|
layer.show_text(scene)
|
|
|
|
# FRACTION
|
|
UI_color.set(layer, win, "progress_background")
|
|
UI_elements.roundrect(layer, win,
|
|
x+10,
|
|
y+50+win.scroll["asset_scenes"] + current_Y_scenes,
|
|
width-20,
|
|
0,
|
|
5)
|
|
|
|
UI_color.set(layer, win, "progress_active")
|
|
UI_elements.roundrect(layer, win,
|
|
x+10,
|
|
y+50+win.scroll["asset_scenes"] + current_Y_scenes,
|
|
(width-20)*fraction,
|
|
0,
|
|
5)
|
|
|
|
# IF SELECTED
|
|
if win.current["asset_scene_selected"] == scene:
|
|
UI_color.set(layer, win, "progress_background")
|
|
UI_elements.roundrect(layer, win,
|
|
x,
|
|
y+win.scroll["asset_scenes"]+current_Y_scenes,
|
|
width,
|
|
70,
|
|
10,
|
|
fill=False)
|
|
layer.stroke()
|
|
|
|
# Here if the current scene is selected I want to draw all
|
|
# the parts of the scene. It's already a bit more complex
|
|
# then what was in the Blender-Organizer legacy.
|
|
|
|
current_Y_scenes = current_Y_scenes + 80
|
|
|
|
for block in foundinscene:
|
|
|
|
# If it's a shot let's mark in the different color.
|
|
|
|
if block[0]:
|
|
if "shot_colors" not in win.story:
|
|
win.story["shot_colors"] = {}
|
|
|
|
surl = "/"+scene+"/"+block[0]
|
|
|
|
if surl not in win.story["shot_colors"]:
|
|
|
|
|
|
rcolors = [
|
|
"shot_1",
|
|
"shot_2",
|
|
"shot_3",
|
|
"shot_4",
|
|
"shot_5"
|
|
]
|
|
|
|
win.story["shot_colors"][surl] = rcolors[len(win.story["shot_colors"]) % len(rcolors)]
|
|
|
|
col = win.story["shot_colors"][surl]
|
|
UI_color.set(layer, win, col)
|
|
else:
|
|
UI_color.set(layer, win, "node_background")
|
|
UI_elements.roundrect(layer, win,
|
|
x,
|
|
y+win.scroll["asset_scenes"]+current_Y_scenes,
|
|
width,
|
|
30,
|
|
10)
|
|
|
|
# GET TO THE SCENE BUTTON
|
|
def do():
|
|
win.current["script_find"] = [block[2],block[3]]
|
|
|
|
win.url = "script"
|
|
print(scene)
|
|
win.cur = "/"+scene+"/"+block[0]
|
|
print(win.cur)
|
|
|
|
UI_elements.roundrect(layer, win,
|
|
x,
|
|
y+win.scroll["asset_scenes"]+current_Y_scenes,
|
|
width,
|
|
30,
|
|
10,
|
|
button=do,
|
|
fill=False)
|
|
layer.stroke()
|
|
|
|
start = block[1][0]
|
|
name = block[1][1]
|
|
end = block[1][2]
|
|
|
|
sp = x+width/2-len(name)*12/2-len(start)*12
|
|
np = x+width/2-len(name)*12/2
|
|
ep = x+width/2+len(name)*12/2
|
|
|
|
if sp > x+5 and x+5 + ep + len(end)*12 > width:
|
|
sp = x+5
|
|
np = x+5 + len(start)*12
|
|
ep = x+5 + len(start)*12 + len(name)*12
|
|
|
|
elif ep + len(end)*12 < width and sp < x+5:
|
|
ep = width - len(end)*12
|
|
np = ep - len(name)*12
|
|
sp = np - len(start)*12
|
|
|
|
# BEFORE NAME
|
|
UI_color.set(layer, win, "text_normal")
|
|
layer.set_font_size(20)
|
|
layer.move_to( sp, y+win.scroll["asset_scenes"] + current_Y_scenes+20)
|
|
layer.show_text(start)
|
|
|
|
|
|
# NAME AS MENTIONED IN THE SCRIPT
|
|
UI_color.set(layer, win, "node_asset")
|
|
UI_elements.roundrect(layer, win,
|
|
np-6,
|
|
y+win.scroll["asset_scenes"]+current_Y_scenes+2,
|
|
len(name)*12+12,
|
|
26,
|
|
10)
|
|
|
|
UI_color.set(layer, win, "text_normal")
|
|
layer.set_font_size(20)
|
|
layer.move_to(np, y+win.scroll["asset_scenes"] + current_Y_scenes+20)
|
|
layer.show_text(name)
|
|
|
|
# AFTER NAME
|
|
UI_color.set(layer, win, "text_normal")
|
|
layer.set_font_size(20)
|
|
layer.move_to( ep, y+win.scroll["asset_scenes"] + current_Y_scenes+20)
|
|
layer.show_text(end)
|
|
|
|
current_Y_scenes = current_Y_scenes + 40
|
|
|
|
else:
|
|
current_Y_scenes = current_Y_scenes + 80
|
|
|
|
# Scroll
|
|
UI_elements.scroll_area(layer, win, "asset_scenes",
|
|
x+0,
|
|
y+50,
|
|
width,
|
|
height-50,
|
|
current_Y_scenes,
|
|
bar=True,
|
|
mmb=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return surface
|