Upload files to 'studio'

This commit is contained in:
Jeison Yehuda Amihud (Blender Dumbass) 2020-12-09 19:16:04 +00:00
parent 72b6c81ac8
commit bc0d5980d7
8 changed files with 727 additions and 232 deletions

View file

@ -3,12 +3,14 @@
import os import os
import datetime import datetime
import json
from studio import checklist from studio import checklist
from studio import story from studio import story
#import checklist #import checklist
#import story #import story
from settings import settings from settings import settings
from settings import talk
def get_legacy(project_location): def get_legacy(project_location):
@ -17,8 +19,10 @@ def get_legacy(project_location):
# step of conversion. And used to display basic analitycs into the # step of conversion. And used to display basic analitycs into the
# project-manager. # project-manager.
name_tmp = project_location[project_location.rfind("/")+1:]
data = { data = {
"name" : "", # Name of the project (typed properly) "name" : name_tmp, # Name of the project (typed properly)
"director" : "", # Name of the project's director. "director" : "", # Name of the project's director.
"status" : "", # Projects's comment / type "status" : "", # Projects's comment / type
"donework" : 0.0, # Percentage of Assets and Scenes done "donework" : 0.0, # Percentage of Assets and Scenes done
@ -33,7 +37,7 @@ def get_legacy(project_location):
"veh_factor" : 1, # Importance factor for Vehicles "veh_factor" : 1, # Importance factor for Vehicles
"loc_factor" : 1, # Importance factor for Locations "loc_factor" : 1, # Importance factor for Locations
"obj_factor" : 1, # Importance factor for Objects (Other) "obj_factor" : 1, # Importance factor for Objects (Other)
"rnd_factor" : 1, # Importance factor for Scenes (Renders) "rnd_factor" : 4, # Importance factor for Scenes (Renders)
"chr" : 0.0, # Percentage of Characters done "chr" : 0.0, # Percentage of Characters done
"veh" : 0.0, # Percentage of Vehicles done "veh" : 0.0, # Percentage of Vehicles done
"loc" : 0.0, # Percentage of Locations done "loc" : 0.0, # Percentage of Locations done
@ -186,8 +190,11 @@ def get_legacy(project_location):
# the percentage. Btw It's just a hard thing. That I needed a separate # the percentage. Btw It's just a hard thing. That I needed a separate
# function for it. # function for it.
projectdata = checklist.get_list(project_location+"/project.progress") try:
data["checklist"] = projectdata["fraction"] projectdata = checklist.get_list(project_location+"/project.progress")
data["checklist"] = projectdata["fraction"]
except:
pass
# NEXT THING. As I love to type it into place where people read me while I'm # NEXT THING. As I love to type it into place where people read me while I'm
# working. We've got data from 2 files. Now we need to get data from ALL the # working. We've got data from 2 files. Now we need to get data from ALL the
@ -603,124 +610,128 @@ def get_legacy(project_location):
# print() # print()
# print() # print()
#data_save(data) #data_save(project_location, data)
return data return data
def data_save(data): def save(project, data):
# This function will save the data to the /set folder. It will include a # This file will save analitycs data.
# a whole lot of inforamtion. Basically all analytics data will be there.
new_date_format = "%Y/%m/%d" try:
os.mkdir(project+'/set/')
except:
pass
lines = [] with open(project+'/set/analytics.json', 'w') as fp:
json.dump(data, fp, sort_keys=True, indent=4)
lines.append("##################### VCStudio Analytics File #####################")
lines.append("")
lines.append(" Last update: "+datetime.datetime.strftime(datetime.datetime.today(), new_date_format))
lines.append("")
lines.append(" Project : "+data["name"])
lines.append(" Director: "+data["director"])
lines.append(" Comment : "+data["status"])
lines.append("")
lines.append(" From: "+data["startdate"]+" To: "+data["deadline"])
lines.append("")
lines.append("-------------------------------------------------------------------")
lines.append("")
lines.append(" CURREND PROGRESS : "+str(data["fraction"]*100)+"%")
lines.append("")
lines.append(" Current actuall : "+str(data["donework"]*100)+"%")
lines.append(" Current checklist : "+str(data["checklist"]*100)+"%")
lines.append("")
lines.append(" Current Characters: "+str(data["chr"]*100)+"%")
lines.append(" Current Vehicled : "+str(data["veh"]*100)+"%")
lines.append(" Current Locations : "+str(data["loc"]*100)+"%")
lines.append(" Current Other(obj): "+str(data["obj"]*100)+"%")
lines.append(" Current Scenes : "+str(data["rnd"]*100)+"%")
lines.append("")
lines.append("-------------------------------------------------------------------")
lines.append("")
lines.append(" Bias:")
lines.append(" Characters: X "+str(data["chr_factor"]))
lines.append(" Vehicled : X "+str(data["veh_factor"]))
lines.append(" Locations : X "+str(data["loc_factor"]))
lines.append(" Other(obj): X "+str(data["obj_factor"]))
lines.append(" Scenes : X "+str(data["rnd_factor"]))
lines.append("")
lines.append("##################### Schedule / History #####################")
lines.append("")
for date in sorted(data["dates"]):
lines.append(" date: "+date)
date = data["dates"][date]
if "fractions" in date:
lines.append("")
lines.append(" Fraction : "+str(date["fractions"]["project"]*100)+"%")
lines.append("")
lines.append(" Characters: "+str(date["fractions"]["chr"]*100)+"%")
lines.append(" Vehicles : "+str(date["fractions"]["veh"]*100)+"%")
lines.append(" Locations : "+str(date["fractions"]["loc"]*100)+"%")
lines.append(" Other(obj): "+str(date["fractions"]["obj"]*100)+"%")
lines.append(" Scenes : "+str(date["fractions"]["rnd"]*100)+"%")
for thing in ["assets", "scenes", "files"]: def load(project_location):
if thing in date:
# This is a simple load analytics funtion.
lines.append("") name_tmp = project_location[project_location.rfind("/")+1:]
lines.append(" type: "+thing+" :")
data = {
for asset in sorted( date[thing] ): "name" : name_tmp, # Name of the project (typed properly)
lines.append(" link: "+asset+" : ") "director" : "", # Name of the project's director.
lines.append("") "status" : "", # Projects's comment / type
for task in sorted(date[thing][asset]): "donework" : 0.0, # Percentage of Assets and Scenes done
"fraction" : 0.0, # Project's completion percentage
"checklist" : 0.0, # Project's main checklist percentage
if task[1] == "schedule": "startdate" : "0000/00/00", # Date of the start of the project
lines.append(" at: "+task[0]) "deadline" : "0000/00/00", # Date when project's deadline is
lines.append(" action: "+task[1]) "duration" : 0, # Amount in days between startdate and deadline
lines.append("") "timepassed" : 0.0, # Percentage of how much time had passed
lines.append(" "+task[2]) "dayspassed" : 0, # Amount of days since the startdate
spaces = " " "chr_factor" : 1, # Importance factor for Characters
for directory in task[3]: "veh_factor" : 1, # Importance factor for Vehicles
spaces = spaces + ":..." "loc_factor" : 1, # Importance factor for Locations
lines.append(spaces+directory) "obj_factor" : 1, # Importance factor for Objects (Other)
"rnd_factor" : 4, # Importance factor for Scenes (Renders)
elif task[3] in ["[Un-Checked]", "[Checked]"]: "chr" : 0.0, # Percentage of Characters done
"veh" : 0.0, # Percentage of Vehicles done
lines.append(" at: "+task[0]) "loc" : 0.0, # Percentage of Locations done
lines.append(" action: "+task[1]+" "+task[3]) "obj" : 0.0, # Percentage of Objects (Other) done
lines.append("") "rnd" : 0.0, # Percentage of Scenes (Renders) done
lines.append(" "+task[2]) "dates" : {} # Per date, detailed data about the project
spaces = " " }
for directory in task[4]:
spaces = spaces + ":..." try:
lines.append(spaces+directory) with open(project_location+'/set/analytics.json') as json_file:
data = json.load(json_file)
else: except:
lines.append(" at: "+task[0]) pass
lines.append(" action: "+task[1]+" "+task[3])
lines.append(" "+task[2]) try:
projectdata = checklist.get_list(project_location+"/set/project.progress")
# Username data["checklist"] = projectdata["fraction"]
except:
lines.append("") make = open(project_location+"/set/project.progress", "w")
lines.append(" user: "+task[-1]) make.write("[ ] Story\n")
make.write("[ ] "+talk.text("chr")+"\n")
lines.append("") make.write("[ ] "+talk.text("veh")+"\n")
make.write("[ ] "+talk.text("loc")+"\n")
make.write("[ ] "+talk.text("obj")+"\n")
make.write("[ ] Animation\n")
make.write("[ ] Rendering")
make.close()
# NEXT THING. As I love to type it into place where people read me while I'm
# working. We've got data from 2 files. Now we need to get data from ALL the
# project.
# First we going to get data about the assets. Because it's relativelly easy
# compared to the story. For which you need to parce a crazy complicated .bos
# file. Which is a complex database in it's own right.
# So let's go and quickly get data about the assets.
asstfols = ["chr", "veh", "loc", "obj"]
astlist = []
for n , f in enumerate(asstfols):
lines.append("") flist = []
lines.append("-------------------------------------------------------------------")
lines.append("") if len(os.listdir(project_location+"/dev/"+f)) > 0:
for asset in os.listdir(project_location+"/dev/"+f):
#test = open("/home/vcs/Desktop/testfile.vcsa", "w")
if asset+".blend" in os.listdir(project_location+"/ast/"+f):
flist.append(1.0)
else:
try:
fcheck = checklist.get_list(project_location+"/dev/"+f+"/"+asset+"/asset.progress")
flist.append(fcheck["fraction"])
except:
flist.append(0.0)
# The multiplication thing that I was talking about earlier.
multiply = data[f+"_factor"]
for m in range(multiply):
astlist.append(sum(flist)/len(flist))
data[f] = sum(flist)/len(flist)
for i in lines: # For the next step I need to have the story parsed and read. But it's going
print(i) # to be so hard. That I will need to write a separate function for it.
#test.write(i+"\n")
data["rnd"] = story.load(project_location)["fraction"]
# After all of it we need to get the final project percentage.
multiply = data["rnd_factor"]
for m in range(multiply):
astlist.append(data["rnd"])
try:
data["donework"] = sum(astlist) / len(astlist)
except:
data["donework"] = 0.0
data["fraction"] = (data["donework"] + data["checklist"]) / 2
return data
#test.close()

View file

@ -160,4 +160,33 @@ def get_list(filepath):
return checklist return checklist
def get_fraction(win, path):
############################################################################
# This function will return a fraction of a given checklist. It will ignore
# complitelly what is the asset / shot / project the checklist is from.
# For sake of making this function actually somewhat useful, aka not bloated
# I will use it to cashe the whole checklist data objects. So they could be
# easily accesable later on.
# This is usefull so I would not need to create 2 cash data structures. One
# for fractions and for the checklists them selves.
############################################################################
if path not in win.checklists:
# Let's check if path exists in the project first.
if os.path.exists(win.project+"/"+path):
win.checklists[path] = get_list(win.project+"/"+path)
else:
win.checklists[path] = get_list(path)
# Let's now return back the fraction
return win.checklists[path]["fraction"]

View file

@ -3,6 +3,7 @@
import os import os
import datetime import datetime
import json
from studio import checklist from studio import checklist
#import checklist #import checklist
@ -530,7 +531,7 @@ def get_legacy(project_location):
link = link[:link.rfind("/renders/Preview.")].replace("/dev", "") link = link[:link.rfind("/renders/Preview.")].replace("/dev", "")
data["links"].append([ data["links"].append([
linktype, link, coordinates linktype, link, coordinates, ""
]) ])
# Markers. I nearly forgot about the markers. In the Story-Editor of # Markers. I nearly forgot about the markers. In the Story-Editor of
@ -555,7 +556,7 @@ def get_legacy(project_location):
# which direction are they. For this markers will need to have # which direction are they. For this markers will need to have
# both X and Y coordinates. # both X and Y coordinates.
data["markers"][markstring] = [markloc, 0.0] data["markers"][markstring] = [markloc, 0.0, ""]
# For now the Y is 0. Because we are reading from the old version. # For now the Y is 0. Because we are reading from the old version.
@ -588,6 +589,9 @@ def get_legacy(project_location):
except: except:
data["fraction"] = 0.0 data["fraction"] = 0.0
#save(project_location, data)
#data = load(project_location)
return data return data
def get_asset_data(win, name, force=False): def get_asset_data(win, name, force=False):
@ -613,3 +617,65 @@ def get_asset_data(win, name, force=False):
win.assets[name] = data win.assets[name] = data
return win.assets[name] return win.assets[name]
def save(project, story):
# This is a save of the new VCStudio. Which is using a standard file format.
# so people could parse the data themselves. ( Or because I'm lazy )
try:
os.mkdir(project+'/pln/')
except:
pass
with open(project+'/pln/story.vcss', 'w') as fp:
json.dump(story, fp, sort_keys=True, indent=4)
def load(project):
# This is a convertion back from JSON data to out beloved python dict
try:
with open(project+'/pln/story.vcss') as json_file:
data = json.load(json_file)
except:
# If there is no file.
data = {
"fraction": 0.0, # Percentage of the Scenes finished.
"camera" : [0,0], # The position of where the user left
"selected": [], # List of selected items in the story editor
"active": None, # Active item.
"scenes" : {}, # List of scenes.
"arrows" : [], # List of connections. (A LIST. NOT DICT.)
"links" : [], # List of links to files or assets.
"markers": {}, # List of markers.
"events" : {} # List of frame like containers. (It will have similar)
} # function as events. But will have no text data with in
# it. It will be more like Blender's node editor's Frame.
fractions = []
lastarrow = 'start'
for i in data["arrows"]:
if lastarrow == "end":
break
for arrow in data["arrows"]:
if arrow[0] == lastarrow:
lastarrow = arrow[1]
if arrow[1] != "end":
fractions.append(
data["scenes"][arrow[1][1]]["fraction"]
)
else:
break
# FINAL STUFF...
try:
data["fraction"] = sum(fractions) / len(fractions)
except:
data["fraction"] = 0.0
return data

View file

@ -25,6 +25,7 @@ from UI import UI_color
# story # story
from studio import story from studio import story
from studio import analytics
def layer(win, call): def layer(win, call):
@ -152,6 +153,10 @@ def layer(win, call):
icon="cancel", icon="cancel",
tip=talk.text("cancel")) tip=talk.text("cancel"))
# Short cut ESC
if 65307 in win.current["keys"] and not win.textactive:
do()
# Now let's prepare the ground for the next part. # Now let's prepare the ground for the next part.
UI_elements.roundrect(layer, win, UI_elements.roundrect(layer, win,
@ -163,14 +168,7 @@ def layer(win, call):
fill=False) fill=False)
layer.clip() layer.clip()
UI_color.set(layer, win, "dark_overdrop")
layer.rectangle(
0,
0,
win.current["w"],
win.current["h"],
)
layer.fill()
tileX = 70 tileX = 70
current_Y = 0 current_Y = 0
@ -178,7 +176,12 @@ def layer(win, call):
if "asset_select" not in win.scroll: if "asset_select" not in win.scroll:
win.scroll["asset_select"] = 0 win.scroll["asset_select"] = 0
newcreate = win.text["asset_select_search"]["text"].replace("/","_").replace(" ", "_")\
.replace('"',"_").replace("(","_").replace(")","_").replace("'","_")\
.replace("[","_").replace("]","_").replace("{","_").replace("}","_")
########################### ###########################
okay = True
for asset in os.listdir(win.project+"/dev/"+win.current["asset_cur"]): for asset in os.listdir(win.project+"/dev/"+win.current["asset_cur"]):
if os.path.isdir(win.project+"/dev/"+win.current["asset_cur"]+"/"+asset): if os.path.isdir(win.project+"/dev/"+win.current["asset_cur"]+"/"+asset):
@ -188,7 +191,7 @@ def layer(win, call):
# Search # Search
if win.text["asset_select_search"]["text"]\ if win.text["asset_select_search"]["text"]\
and win.text["asset_select_search"]["text"].lower() not in asset.lower(): and newcreate.lower() not in asset.lower():
okay = False okay = False
if okay: if okay:
@ -196,13 +199,38 @@ def layer(win, call):
if int(current_Y + win.scroll["asset_select"] + 100) in range(0-100, win.current["h"]): if int(current_Y + win.scroll["asset_select"] + 100) in range(0-100, win.current["h"]):
UI_color.set(layer, win, "node_asset") # Making the layer
UI_elements.roundrect(layer, win, nodesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 170, 200)
tileX-10, node = cairo.Context(nodesurface)
current_Y + win.scroll["asset_select"] + 120, node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
UI_elements.roundrect(node, win,
0,
0,
170, 170,
200, 200,
10) 10,
fill=False)
node.clip()
# Background
UI_color.set(node, win, "dark_overdrop")
node.rectangle(0,0,170, 200)
node.fill()
# Banner
UI_color.set(node, win, "node_asset")
node.rectangle(0,0,170, 20)
node.fill()
# Outputting the layer
layer.set_source_surface(nodesurface,
tileX-10,
current_Y + win.scroll["asset_select"] + 120)
layer.paint()
# Previes image # Previes image
@ -246,37 +274,43 @@ def layer(win, call):
0, 0,
5) 5)
UI_color.set(layer, win, "text_normal") UI_color.set(layer, win, "text_normal")
layer.set_font_size(12) layer.set_font_size(12)
layer.move_to(tileX, layer.move_to(tileX,
current_Y + win.scroll["asset_select"] + 135) current_Y + win.scroll["asset_select"] + 135)
layer.show_text(asset[asset.rfind("/")+1:][:22]) layer.show_text(asset[asset.rfind("/")+1:][:22])
# Button to activate it
def do():
win.current["calls"][call]["var"] = "/"+win.current["asset_cur"]+"/"+asset
win.assets = {}
layer.set_line_width(4)
UI_elements.roundrect(layer, win, # Button to activate it
tileX-10, def do():
current_Y + win.scroll["asset_select"] + 120, win.current["calls"][call]["var"] = "/"+win.current["asset_cur"]+"/"+asset
170, win.assets = {}
200,
10, layer.set_line_width(4)
button=do, UI_elements.roundrect(layer, win,
tip=talk.text(win.current["asset_cur"])+": "+asset, tileX-10,
fill=False, current_Y + win.scroll["asset_select"] + 120,
clip=[ 170,
50, 200,
100, 10,
win.current["w"]-100, button=do,
win.current["h"]-200 tip=talk.text(win.current["asset_cur"])+": "+asset,
]) fill=False,
clip=[
layer.stroke() 50,
layer.set_line_width(2) 100,
win.current["w"]-100,
win.current["h"]-200
])
layer.stroke()
layer.set_line_width(2)
tileX += 200 tileX += 200
@ -285,6 +319,71 @@ def layer(win, call):
current_Y += 230 current_Y += 230
if win.text["asset_select_search"]["text"]\
and newcreate\
not in os.listdir(win.project+"/dev/"+win.current["asset_cur"]):
# If there is a seach and there is no asset with the search name. It
# will ask if you want to create such an asset.
def do():
# I don't thing I need to write a whole module for creating a couple
# of folders.
try:
os.mkdir(win.project+"/dev/"+win.current["asset_cur"]+"/"+newcreate)
os.mkdir(win.project+"/dev/"+win.current["asset_cur"]+"/"+newcreate+"/renders")
os.mkdir(win.project+"/dev/"+win.current["asset_cur"]+"/"+newcreate+"/reference")
os.mkdir(win.project+"/dev/"+win.current["asset_cur"]+"/"+newcreate+"/tex")
except:
pass
win.text["asset_select_search"]["text"] = ""
win.current["calls"][call]["var"] = "/"+win.current["asset_cur"]+"/"+newcreate
win.assets = {}
# Refrashing analytics
win.analytics = analytics.load(win.project)
analytics.save(win.project, win.analytics)
UI_elements.roundrect(layer, win,
tileX-10,
current_Y + win.scroll["asset_select"] + 120,
170,
200,
10,
button=do,
tip=talk.text("create_new_asset")+" "+newcreate)
UI_color.set(layer, win, "progress_background")
UI_elements.roundrect(layer, win,
tileX-10,
current_Y + win.scroll["asset_select"] + 120,
170,
200,
10,
fill=False)
layer.stroke()
UI_elements.image(layer, win,
"settings/themes/"+win.settings["Theme"]+"/icons/asset_new.png",
tileX+55,
current_Y + win.scroll["asset_select"] + 200,
40, 40)
UI_color.set(layer, win, "text_normal")
layer.set_font_size(12)
layer.move_to(tileX+85-len(newcreate)*4,
current_Y + win.scroll["asset_select"] + 300)
layer.show_text(newcreate)
########################### ###########################
current_Y += 230 current_Y += 230

View file

@ -23,6 +23,8 @@ from project_manager import pm_project
from UI import UI_elements from UI import UI_elements
from UI import UI_color from UI import UI_color
# Studio
from studio import checklist
def layer(win, call): def layer(win, call):
@ -80,7 +82,7 @@ def layer(win, call):
if "AllFiles" not in win.current: if "AllFiles" not in win.current:
win.current["AllFiles"] = [] win.current["AllFiles"] = []
for r, d, f in os.walk(win.project): for r, d, f in sorted(os.walk(win.project)):
for item in f: for item in f:
win.current["AllFiles"].append(os.path.join(r, item).replace(win.project, "")) win.current["AllFiles"].append(os.path.join(r, item).replace(win.project, ""))
@ -153,8 +155,32 @@ def layer(win, call):
##### BOTTOM BUTTONS #### ##### BOTTOM BUTTONS ####
def do():
filechooser = Gtk.FileChooserDialog(talk.text("select_file"),
None,
Gtk.FileChooserAction.OPEN,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
filechooser.set_default_response(Gtk.ResponseType.OK)
response = filechooser.run()
if response == Gtk.ResponseType.OK:
get = filechooser.get_filename()
win.current["calls"][call]["var"] = get
del win.current["AllFiles"]
filechooser.destroy()
UI_elements.roundrect(layer, win,
win.current["w"]-120,
win.current["h"]-80,
40,
40,
10,
button=do,
icon="folder",
tip=talk.text("outside_folder"))
def do(): def do():
win.current["calls"][call]["var"] = False win.current["calls"][call]["var"] = False
@ -171,6 +197,10 @@ def layer(win, call):
icon="cancel", icon="cancel",
tip=talk.text("cancel")) tip=talk.text("cancel"))
# Short cut ESC
if 65307 in win.current["keys"] and not win.textactive:
do()
# Now let's prepare the ground for the next part. # Now let's prepare the ground for the next part.
UI_elements.roundrect(layer, win, UI_elements.roundrect(layer, win,
@ -182,14 +212,7 @@ def layer(win, call):
fill=False) fill=False)
layer.clip() layer.clip()
UI_color.set(layer, win, "dark_overdrop")
layer.rectangle(
0,
0,
win.current["w"],
win.current["h"],
)
layer.fill()
### ACTUALL FILES LIST ### ### ACTUALL FILES LIST ###
@ -255,7 +278,7 @@ def layer(win, call):
for f in fileformats.images: for f in fileformats.images:
if filename.endswith(f): if filename.endswith(f):
typefound = True typefound = True
UI_color.set(layer, win, "node_imagefile") thecoloris = "node_imagefile"
if not win.current["file_selector"]["image"]: if not win.current["file_selector"]["image"]:
okay = False okay = False
break break
@ -265,7 +288,7 @@ def layer(win, call):
for f in fileformats.videos: for f in fileformats.videos:
if filename.endswith(f): if filename.endswith(f):
typefound = True typefound = True
UI_color.set(layer, win, "node_videofile") thecoloris = "node_videofile"
if not win.current["file_selector"]["video"]: if not win.current["file_selector"]["video"]:
okay = False okay = False
break break
@ -274,16 +297,16 @@ def layer(win, call):
# Blend Files # Blend Files
if filename.endswith(".blend"): if filename.endswith(".blend"):
typefound = True typefound = True
UI_color.set(layer, win, "node_blendfile") thecoloris = "node_blendfile"
if "ast/" in filename: if "ast/" in filename:
UI_color.set(layer, win, "node_asset") thecoloris = "node_asset"
if not win.current["file_selector"]["blender"]: if not win.current["file_selector"]["blender"]:
okay = False okay = False
if okay: if okay:
if typefound == False: if typefound == False:
UI_color.set(layer, win, "node_script") thecoloris = "node_script"
if not win.current["file_selector"]["file"]: if not win.current["file_selector"]["file"]:
okay = False okay = False
@ -296,19 +319,67 @@ def layer(win, call):
if int(current_Y + win.scroll["file_select"] + 100) in range(0-100, win.current["h"]): if int(current_Y + win.scroll["file_select"] + 100) in range(0-100, win.current["h"]):
UI_elements.roundrect(layer, win, # Making the layer
tileX-10, nodesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 170, 200)
current_Y + win.scroll["file_select"] + 120, node = cairo.Context(nodesurface)
node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
UI_elements.roundrect(node, win,
0,
0,
170, 170,
200, 200,
10) 10,
fill=False)
node.clip()
# Background
UI_color.set(node, win, "dark_overdrop")
node.rectangle(0,0,170, 200)
node.fill()
# Banner
UI_color.set(node, win, thecoloris)
node.rectangle(0,0,170, 20)
node.fill()
# Outputting the layer
layer.set_source_surface(nodesurface,
tileX-10,
current_Y + win.scroll["file_select"] + 120)
layer.paint()
UI_elements.image(layer, win, win.project+filename, UI_elements.image(layer, win, win.project+filename,
tileX, tileX,
current_Y + win.scroll["file_select"] + 150, current_Y + win.scroll["file_select"] + 150,
150, 150,
150) 150)
# If this is a checklist
if filename.endswith(".progress"):
fraction = checklist.get_fraction(win, filename)
UI_color.set(layer, win, "progress_background")
UI_elements.roundrect(layer, win,
tileX,
current_Y + win.scroll["file_select"] + 300,
150,
0,
5)
UI_color.set(layer, win, "progress_active")
UI_elements.roundrect(layer, win,
tileX,
current_Y + win.scroll["file_select"] + 300,
150*fraction,
0,
5)
UI_color.set(layer, win, "text_normal") UI_color.set(layer, win, "text_normal")
layer.set_font_size(12) layer.set_font_size(12)
layer.move_to(tileX, layer.move_to(tileX,

View file

@ -36,15 +36,13 @@ def previous(win):
win.previous[i] = win.current[i] win.previous[i] = win.current[i]
# OK let's make a window # OK let's make a window
def run(win): def run(project, win):
# In the Blender-Organizer I was putting the version into the title. Not cool. # In the Blender-Organizer I was putting the version into the title. Not cool.
# Because if you would snap it to the sidebar in Ubuntu. On mouse over it would # Because if you would snap it to the sidebar in Ubuntu. On mouse over it would
# show the first ever version. So there will be a better way to see version. # show the first ever version. So there will be a better way to see version.
# I think let's do that like in Blender. Drawn with in the window somewhere. # I think let's do that like in Blender. Drawn with in the window somewhere.
project = win.current["project"]
win.destroy() win.destroy()
# Setting up the window # Setting up the window
win = Gtk.Window() win = Gtk.Window()
win.maximize() win.maximize()
@ -88,13 +86,14 @@ def run(win):
} }
win.calllayer = False win.calllayer = False
win.layercashe = {} # Here I gonna store layers that are inactive to speed up stuff win.layercashe = {} # Here I gonna store layers that are inactive to speed up stuff
win.checklists = {}
if pm_project.is_legacy(project): if pm_project.is_legacy(project):
win.story = story.get_legacy(project) win.story = story.get_legacy(project)
win.analytics = analytics.get_legacy(project) win.analytics = analytics.get_legacy(project)
else: else:
win.story = {} win.story = story.load(project)
win.analytics = {} win.analytics = analytics.load(project)
# Try to put a name of the project at the title # Try to put a name of the project at the title
win.set_title("VCStudio : "+win.analytics["name"]) win.set_title("VCStudio : "+win.analytics["name"])

View file

@ -18,7 +18,9 @@ from settings import oscalls
# Studio # Studio
from studio import story from studio import story
from studio import analytics
from studio import studio_dialogs from studio import studio_dialogs
from studio import checklist
# UI modules # UI modules
from UI import UI_testing from UI import UI_testing
@ -91,6 +93,10 @@ def node_dot(layer, win, x, y, direction="in", entry="end"):
except: except:
pass pass
# Refrashing analytics
story.save(win.project, win.story)
win.analytics = analytics.load(win.project)
analytics.save(win.project, win.analytics)
# Connecting the line # Connecting the line
@ -110,10 +116,13 @@ def node_dot(layer, win, x, y, direction="in", entry="end"):
win.story["arrows"].append(new_arrow) win.story["arrows"].append(new_arrow)
UI_math.filter_arrows(win) UI_math.filter_arrows(win)
# Refrashing analytics
story.save(win.project, win.story)
win.analytics = analytics.load(win.project)
analytics.save(win.project, win.analytics)
if direction != "in": if direction != "in":
win.out_dots[entry] = [x+6, y+6] win.out_dots[entry] = [x+6, y+6]
@ -280,7 +289,7 @@ def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0)
width = max(width,20) width = max(width,20)
height = max(height,20) height = max(height,20)
doparent = True
if int(x) in range(int(0-width), int(win.current["w"]))\ if int(x) in range(int(0-width), int(win.current["w"]))\
and int(y) in range(int(0-height), int(win.current["h"])): and int(y) in range(int(0-height), int(win.current["h"])):
@ -292,6 +301,7 @@ def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0)
selected = False selected = False
if win.url == "story_editor"\ if win.url == "story_editor"\
and int(win.current["mx"]) in range(50, int(win.current["w"]-50)) \ and int(win.current["mx"]) in range(50, int(win.current["w"]-50)) \
and int(win.current["my"]) in range(50, int(win.current["h"]-30)): and int(win.current["my"]) in range(50, int(win.current["h"]-30)):
@ -410,6 +420,11 @@ def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0)
# Now let's do the simple grab tool. # Now let's do the simple grab tool.
if win.current["tool"] == "grab": if win.current["tool"] == "grab":
# If you press shift, You take things out of events
if 65505 in win.current["keys"]:
doparent = False
try: try:
@ -426,9 +441,25 @@ def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0)
x += win.previous["mx"] - win.previous["LMB"][0] x += win.previous["mx"] - win.previous["LMB"][0]
y += win.previous["my"] - win.previous["LMB"][1] y += win.previous["my"] - win.previous["LMB"][1]
# Parent removing / assigning
if not doparent:
win.story["scenes"][name]["parent"] = ""
elif not win.story["scenes"][name]["parent"]:
for event in win.story["events"]:
mx, my = win.story["events"][event]["position"]
pmx, pmy = win.story["events"][event]["size"]
if UI_math.rectangle_overlap(
[mx, my, pmx, pmy],
[x,y,width, height]):
win.story["scenes"][name]["parent"] = event
break
elif win.current["tool"] != "connect": elif win.current["tool"] != "connect":
@ -470,6 +501,12 @@ def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0)
fill=False) fill=False)
layer.clip() layer.clip()
# Tooltip
if int(win.current["mx"]) in range(int(x), int(x+width))\
and int(win.current["my"]) in range(int(y), int(y+height)):
UI_elements.tooltip(win, name)
# Background # Background
UI_color.set(layer, win, "dark_overdrop") UI_color.set(layer, win, "dark_overdrop")
layer.rectangle(0,0,width, height) layer.rectangle(0,0,width, height)
@ -512,7 +549,7 @@ def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0)
# In case there is a parent event in the scene. # In case there is a parent event in the scene.
if win.story["scenes"][name]["parent"]: if win.story["scenes"][name]["parent"] and doparent:
parent = win.story["scenes"][name]["parent"] parent = win.story["scenes"][name]["parent"]
UI_math.rectangle_surround(win, parent, UI_math.rectangle_surround(win, parent,
win.story["events"][parent]["position"], win.story["events"][parent]["position"],
@ -592,7 +629,9 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
for f in fileformats.videos: for f in fileformats.videos:
if name.endswith(f): if name.endswith(f):
filetype = "video" filetype = "video"
doparent = True
if int(x) in range(int(0-width), int(win.current["w"]))\ if int(x) in range(int(0-width), int(win.current["w"]))\
and int(y) in range(int(0-height), int(win.current["h"])): and int(y) in range(int(0-height), int(win.current["h"])):
@ -722,6 +761,11 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
if win.current["tool"] == "grab": if win.current["tool"] == "grab":
# If you press shift, You take things out of events
if 65505 in win.current["keys"]:
doparent = False
try: try:
if win.current["LMB"]: if win.current["LMB"]:
x += win.current["mx"] - win.current["LMB"][0] x += win.current["mx"] - win.current["LMB"][0]
@ -736,6 +780,25 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
x += win.previous["mx"] - win.previous["LMB"][0] x += win.previous["mx"] - win.previous["LMB"][0]
y += win.previous["my"] - win.previous["LMB"][1] y += win.previous["my"] - win.previous["LMB"][1]
# Parent removing / assigning
if not doparent:
win.story["links"][num][3] = ""
elif not win.story["links"][num][3]:
for event in win.story["events"]:
mx, my = win.story["events"][event]["position"]
pmx, pmy = win.story["events"][event]["size"]
if UI_math.rectangle_overlap(
[mx, my, pmx, pmy],
[x,y,width, height]):
win.story["links"][num][3] = event
break
elif win.current["tool"] != "connect": elif win.current["tool"] != "connect":
win.current["tool"] = "selection" win.current["tool"] = "selection"
@ -929,6 +992,26 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
name, name,
0, 0, width, height) 0, 0, width, height)
if name.endswith(".progress"):
fraction = checklist.get_fraction(win, name)
UI_color.set(layer, win, "progress_background")
UI_elements.roundrect(layer, win,
10,
height-20,
width-20,
0,
5)
UI_color.set(layer, win, "progress_active")
UI_elements.roundrect(layer, win,
10,
height-20,
(width-20)*fraction,
0,
5)
if name.endswith(".blend"): if name.endswith(".blend"):
UI_color.set(layer, win, "node_blendfile") UI_color.set(layer, win, "node_blendfile")
if "ast/" in name: if "ast/" in name:
@ -941,7 +1024,14 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
else: else:
UI_color.set(layer, win, "node_script") UI_color.set(layer, win, "node_script")
# Tooltip
if int(win.current["mx"]) in range(int(x), int(x+width))\
and int(win.current["my"]) in range(int(y), int(y+height)):
UI_elements.tooltip(win, name)
# top banner # top banner
@ -978,12 +1068,24 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
del win.out_dots["file:"+name] del win.out_dots["file:"+name]
except: except:
pass pass
# In case there is a parent event in the scene.
if win.story["links"][num][3] and doparent:
parent = win.story["links"][num][3]
UI_math.rectangle_surround(win, parent,
win.story["events"][parent]["position"],
win.story["events"][parent]["size"],
[x,y], [width, height]
)
def marker(outlayer, win, name ,x, y ): def marker(outlayer, win, name ,x, y ):
# This function will draw markers to the screen. They are like shortcuts in # This function will draw markers to the screen. They are like shortcuts in
# a story editor space. # a story editor space.
if int(x) in range(int(60), int(win.current["w"]-100))\ if int(x) in range(int(60), int(win.current["w"]-100))\
and int(y) in range(int(60), int(win.current["h"]-80)): and int(y) in range(int(60), int(win.current["h"]-80)):
width = 200 width = 200
@ -1008,6 +1110,8 @@ def marker(outlayer, win, name ,x, y ):
if inscreen: if inscreen:
doparent = True
selected = False selected = False
if win.url == "story_editor"\ if win.url == "story_editor"\
and int(win.current["mx"]) in range(50, int(win.current["w"]-50)) \ and int(win.current["mx"]) in range(50, int(win.current["w"]-50)) \
@ -1110,6 +1214,11 @@ def marker(outlayer, win, name ,x, y ):
if win.current["tool"] == "grab": if win.current["tool"] == "grab":
# If you press shift, You take things out of events
if 65505 in win.current["keys"]:
doparent = False
try: try:
if win.current["LMB"]: if win.current["LMB"]:
x += win.current["mx"] - win.current["LMB"][0] x += win.current["mx"] - win.current["LMB"][0]
@ -1125,6 +1234,28 @@ def marker(outlayer, win, name ,x, y ):
x += win.previous["mx"] - win.previous["LMB"][0] x += win.previous["mx"] - win.previous["LMB"][0]
y += win.previous["my"] - win.previous["LMB"][1] y += win.previous["my"] - win.previous["LMB"][1]
# Parent removing / assigning
if not doparent:
win.story["markers"][name][2] = ""
elif not win.story["markers"][name][2] :
for event in win.story["events"]:
mx, my = win.story["events"][event]["position"]
pmx, pmy = win.story["events"][event]["size"]
if UI_math.rectangle_overlap(
[mx, my, pmx, pmy],
[x,y,width, height]):
win.story["markers"][name][2] = event
print(event)
break
elif win.current["tool"] != "connect": elif win.current["tool"] != "connect":
win.current["tool"] = "selection" win.current["tool"] = "selection"
@ -1191,10 +1322,13 @@ def marker(outlayer, win, name ,x, y ):
if name != win.text[name+"_marker"]["text"] and win.text[name+"_marker"]["text"]: if name != win.text[name+"_marker"]["text"] and win.text[name+"_marker"]["text"]:
def do(): def do():
win.story["selected"] = [] win.story["selected"] = []
win.story["markers"][win.text[name+"_marker"]["text"]] = [ win.story["markers"][win.text[name+"_marker"]["text"]] = [
x - win.story["camera"][0], x - win.story["camera"][0],
y - win.story["camera"][1] y - win.story["camera"][1],
win.story["markers"][name][2]
] ]
win.textactive = "" win.textactive = ""
@ -1213,7 +1347,17 @@ def marker(outlayer, win, name ,x, y ):
if 65293 in win.current["keys"]: if 65293 in win.current["keys"]:
do() do()
# In case there is a parent event in the scene.
if win.story["markers"][name][2] and doparent:
parent = win.story["markers"][name][2]
UI_math.rectangle_surround(win, parent,
win.story["events"][parent]["position"],
win.story["events"][parent]["size"],
[x,y], [width, height]
)
else: else:
if win.textactive == name+"_marker": if win.textactive == name+"_marker":
@ -1238,4 +1382,4 @@ def marker(outlayer, win, name ,x, y ):
fill=False) fill=False)
outlayer.stroke() outlayer.stroke()

View file

@ -19,6 +19,8 @@ from project_manager import pm_project
from studio import analytics from studio import analytics
from studio import studio_nodes from studio import studio_nodes
from studio import studio_dialogs from studio import studio_dialogs
from studio import story
from studio import analytics
#UI modules #UI modules
from UI import UI_elements from UI import UI_elements
@ -210,7 +212,8 @@ def layer(win):
"asset", var, [ "asset", var, [
win.current["mx"]-win.story["camera"][0]-75, win.current["mx"]-win.story["camera"][0]-75,
win.current["my"]-win.story["camera"][1]-75 win.current["my"]-win.story["camera"][1]-75
] ],
"" # Parent
]) ])
# Now let's select and move the thing # Now let's select and move the thing
@ -246,7 +249,8 @@ def layer(win):
"file", var, [ "file", var, [
win.current["mx"]-win.story["camera"][0]-75, win.current["mx"]-win.story["camera"][0]-75,
win.current["my"]-win.story["camera"][1]-75 win.current["my"]-win.story["camera"][1]-75
] ],
"" # Parent
]) ])
# Now let's select and move the thing # Now let's select and move the thing
@ -275,22 +279,6 @@ def layer(win):
do() do()
win.current["keys"] = [] win.current["keys"] = []
# Event
def do():
print("Event")
UI_elements.roundrect(layer, win,
5,
255,
40,
40,
10,
do,
"event",
talk.text("event_tooltip"),
url="story_editor")
# Marker # Marker
def do(): def do():
@ -303,7 +291,8 @@ def layer(win):
win.story["markers"][markername] = [ win.story["markers"][markername] = [
win.current["mx"]-win.story["camera"][0]+50, win.current["mx"]-win.story["camera"][0]+50,
win.current["my"]-win.story["camera"][1]-20 win.current["my"]-win.story["camera"][1]-20,
"" # Parent
] ]
win.textactive = markername+"_marker" win.textactive = markername+"_marker"
@ -319,14 +308,62 @@ def layer(win):
UI_elements.roundrect(layer, win, UI_elements.roundrect(layer, win,
5, 5,
305, 255,
40, 40,
40, 40,
10, 10,
do, do,
"pin", "pin",
talk.text("marker_tooltip"), talk.text("marker_tooltip")+"\n[M]",
url="story_editor") url="story_editor")
# Shortcut
if 109 in win.current["keys"] and not win.textactive:
do()
win.current["keys"] = []
if win.story["selected"]:
# Event
def do():
eventname = "Event"
count = 2
while eventname in win.story["events"]:
eventname = "Event_"+str(count)
count = count + 1
win.story["events"][eventname] = {
"position":[0,0],
"size":[0,0]
}
# Even going to delete it self if there will be noone who parenting
# it.
for thing in win.story["selected"]:
if thing[0] == "scene":
win.story["scenes"][thing[1]]["parent"] = eventname
elif thing[0] in ["file", "asset"]:
win.story["links"][thing[1]][3] = eventname
elif thing[0] == "marker":
win.story["markers"][thing[1]][2] = eventname
UI_elements.roundrect(layer, win,
5,
305,
40,
40,
10,
do,
"event",
talk.text("event_tooltip")+"\n[E]",
url="story_editor")
# Shortcut
if 101 in win.current["keys"] and not win.textactive:
do()
win.current["keys"] = []
# Renders # Renders
def do(): def do():
@ -548,20 +585,51 @@ def layer(win):
# EVENTS (Frames) # EVENTS (Frames)
try:
for event in win.story["events"]: for event in win.story["events"]:
# Loaction # Loaction
sx, sy = win.story["events"][event]["position"] sx, sy = win.story["events"][event]["position"]
# Scale # Scale
ssx, ssy = win.story["events"][event]["size"] ssx, ssy = win.story["events"][event]["size"]
#Draw #Draw
studio_nodes.event_node(layer, win, sx, sy, ssx, ssy, name=event) studio_nodes.event_node(layer, win, sx, sy, ssx, ssy, name=event)
# Let's now check if the event even has anybody inside. It's a bit
# not the best way to implement it yet. Because I will need to look
# through all items. But we can make it simpler if we find that it has
# we can just break out of a thing.
found = False
for scene in win.story["scenes"]:
if event == win.story["scenes"][scene]["parent"]:
found = True
break
if not found:
for link in win.story["links"]:
if event == link[3]:
found = True
break
if not found:
for marker in win.story["markers"]:
if event == win.story["markers"][marker][2]:
found = True
break
# If nobody is inside. Delete the bastard.
if not found:
del win.story["events"][event]
except:
pass
# SCENES # SCENES
@ -722,8 +790,11 @@ def layer(win):
# Undo selection # Undo selection
if int(win.current["LMB"][0] - win.current["mx"]) in range(-10, 10)\ if int(win.current["LMB"][0] - win.current["mx"]) in range(-10, 10)\
and int(win.current["LMB"][1] - win.current["my"])in range(-10, 10)\ and int(win.current["LMB"][1] - win.current["my"])in range(-10, 10)\
and int(win.current["mx"]) in range(50, int(win.current["w"]-50)) \
and int(win.current["my"]) in range(50, int(win.current["h"]-30))\
and 65505 not in win.current["keys"]: and 65505 not in win.current["keys"]:
win.story["selected"] = [] win.story["selected"] = []
win.textactive = ""
@ -748,7 +819,12 @@ def layer(win):
layer.stroke() layer.stroke()
except: except:
pass pass
# Save story. I'm going to do it the same way as in the old Blender-Organizer
if win.current["frame"] % 10 == 0 and win.url == "story_editor"\
and not win.current["LMB"] and not win.current["MMB"] and not win.current["RMB"]:
story.save(win.project, win.story)
analytics.save(win.project, win.analytics)
# To selected # To selected
if 65454 in win.current["keys"] and win.story["selected"] and not win.textactive: if 65454 in win.current["keys"] and win.story["selected"] and not win.textactive: