Upload files to 'studio'
This commit is contained in:
parent
b70c783942
commit
76f6ab9863
7 changed files with 1938 additions and 66 deletions
|
@ -7,13 +7,42 @@ import json
|
||||||
|
|
||||||
from studio import checklist
|
from studio import checklist
|
||||||
from studio import story
|
from studio import story
|
||||||
#import checklist
|
from studio import schedule
|
||||||
#import story
|
|
||||||
from settings import settings
|
from settings import settings
|
||||||
from settings import talk
|
from settings import talk
|
||||||
|
|
||||||
|
def iftime(string):
|
||||||
|
|
||||||
|
if len(string) != len("00:00:00"):
|
||||||
|
return False
|
||||||
|
|
||||||
|
if len(string.split(":")) != 3:
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
for n, i in enumerate(string.split(":")):
|
||||||
|
|
||||||
|
if len(i) != 2:
|
||||||
|
return False
|
||||||
|
|
||||||
|
i = int(i)
|
||||||
|
|
||||||
|
if n == 0 and i > 23:
|
||||||
|
return False
|
||||||
|
if i > 59:
|
||||||
|
return False
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def ifdate(string):
|
def ifdate(string):
|
||||||
|
|
||||||
|
if len(string) != len("1997/07/30"):
|
||||||
|
return False
|
||||||
|
|
||||||
new_date_format = "%Y/%m/%d"
|
new_date_format = "%Y/%m/%d"
|
||||||
try:
|
try:
|
||||||
datetime.datetime.strptime(string, new_date_format)
|
datetime.datetime.strptime(string, new_date_format)
|
||||||
|
@ -717,6 +746,12 @@ def load(project_location):
|
||||||
if data["timepassed"] > 1.0:
|
if data["timepassed"] > 1.0:
|
||||||
data["timepassed"] = 1.0
|
data["timepassed"] = 1.0
|
||||||
|
|
||||||
|
# LET's FILTER THE SCHEDULES
|
||||||
|
|
||||||
|
data["dates"] = schedule.filter(project_location, data["dates"])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 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
|
||||||
# project.
|
# project.
|
||||||
|
@ -773,5 +808,20 @@ def load(project_location):
|
||||||
data["fraction"] = (data["donework"] + data["checklist"]) / 2
|
data["fraction"] = (data["donework"] + data["checklist"]) / 2
|
||||||
|
|
||||||
|
|
||||||
|
# Let's record it for today.
|
||||||
|
today = datetime.datetime.strftime(datetime.datetime.today(), new_date_format)
|
||||||
|
if today not in data["dates"]:
|
||||||
|
data["dates"][today] = {}
|
||||||
|
data["dates"][today]["fractions"] = {
|
||||||
|
"project":data["fraction"],
|
||||||
|
"checklist":data["checklist"],
|
||||||
|
"chr":data["chr"],
|
||||||
|
"veh":data["veh"],
|
||||||
|
"loc":data["loc"],
|
||||||
|
"obj":data["obj"],
|
||||||
|
"rnd":data["rnd"]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,9 @@ from UI import UI_color
|
||||||
#settings
|
#settings
|
||||||
from settings import talk
|
from settings import talk
|
||||||
|
|
||||||
|
#studio
|
||||||
|
from studio import analytics
|
||||||
|
|
||||||
def get_list(filepath):
|
def get_list(filepath):
|
||||||
|
|
||||||
# This fucntion converts text documents. (.progress) into a more machine
|
# This fucntion converts text documents. (.progress) into a more machine
|
||||||
|
@ -201,6 +204,34 @@ def get_fraction(win, path):
|
||||||
|
|
||||||
return win.checklists[path]["fraction"]
|
return win.checklists[path]["fraction"]
|
||||||
|
|
||||||
|
def get_task_by_path(tasks, path, p=[]):
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
# This function will give the information about a given task from a non
|
||||||
|
# recursive URL such as ["Task", "Sub-task", "Sub-task2"]. This will look
|
||||||
|
# the recursive list and output the given task. In this case "Sub-task2"
|
||||||
|
# with all the information inside it.
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
for task in tasks:
|
||||||
|
|
||||||
|
pa = p.copy()
|
||||||
|
pa.append(" "+task["string"])
|
||||||
|
|
||||||
|
|
||||||
|
if pa == path:
|
||||||
|
return task
|
||||||
|
|
||||||
|
if task["subtasks"]:
|
||||||
|
t = get_task_by_path(task["subtasks"], path, pa)
|
||||||
|
if t:
|
||||||
|
return t
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def filter_tasks(data):
|
def filter_tasks(data):
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
|
@ -272,7 +303,7 @@ def save(path, data):
|
||||||
|
|
||||||
w.close()
|
w.close()
|
||||||
|
|
||||||
def draw(outlayer, win, path):
|
def draw(outlayer, win, path, back="story_editor"):
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
|
@ -391,13 +422,66 @@ def draw(outlayer, win, path):
|
||||||
if "moving_task_now" not in win.current:
|
if "moving_task_now" not in win.current:
|
||||||
win.current["moving_task_now"] = False
|
win.current["moving_task_now"] = False
|
||||||
|
|
||||||
def draw_tasks(tasks, cXY):
|
def draw_tasks(tasks, cXY, schedulep):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# THIS IS THE RECURSIVE FUNCTION #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
|
||||||
|
# I will try to explain what is going on here. But it will require me
|
||||||
|
# understanding the code myself. And it's a bit redic. There was a hell
|
||||||
|
# of a lot of copy-paste, edit value, continue.
|
||||||
|
|
||||||
for num , task in enumerate(tasks):
|
for num , task in enumerate(tasks):
|
||||||
|
|
||||||
# Delete
|
# This is the code that will be done for each task in the list. Or
|
||||||
|
# subtask if a task have them.
|
||||||
|
|
||||||
if 65535 in win.current["keys"] and task["selected"]:
|
# Let's get a schedule path. A folder like structure.
|
||||||
|
# Exacmple:
|
||||||
|
|
||||||
|
# Instead of:
|
||||||
|
# Task
|
||||||
|
# Sub-Task
|
||||||
|
# Sub-Task 2
|
||||||
|
|
||||||
|
# We get:
|
||||||
|
# ["Task", "Sub-Task", "Sub-Task 2"]
|
||||||
|
|
||||||
|
schedulepath = schedulep.copy()
|
||||||
|
schedulepath.append(" "+task["string"])
|
||||||
|
|
||||||
|
|
||||||
|
###### SCHEDULING STUFF BACKWARD ######
|
||||||
|
|
||||||
|
# This is a set of stuff to make schedules work with checklists.
|
||||||
|
|
||||||
|
if "schedule_task_selected" not in win.current:
|
||||||
|
win.current["schedule_task_selected"] = False
|
||||||
|
|
||||||
|
if win.current["schedule_task_selected"]:
|
||||||
|
csl = win.current["schedule_task_selected"][0][0][4]
|
||||||
|
|
||||||
|
if " "+task["string"] in csl and not task["open"]:
|
||||||
|
task["open"] = True
|
||||||
|
|
||||||
|
if schedulepath == csl and not task["selected"]:
|
||||||
|
filter_tasks(win.checklists[path])
|
||||||
|
task["selected"] = True
|
||||||
|
win.scroll["checklist"] = 0 - cXY[1] + height/2
|
||||||
|
|
||||||
|
|
||||||
|
#### DELETE SHORT KEY ####
|
||||||
|
|
||||||
|
# There is probably a reason to put it here. Probably something
|
||||||
|
# breaks if you put it anywhere else. IDK actually. Test it. I
|
||||||
|
# don't remember
|
||||||
|
|
||||||
|
if 65535 in win.current["keys"] and task["selected"] and not win.current["schedule_task_selected"]:
|
||||||
del tasks[num]
|
del tasks[num]
|
||||||
win.current["keys"] = []
|
win.current["keys"] = []
|
||||||
|
|
||||||
|
@ -405,53 +489,139 @@ def draw(outlayer, win, path):
|
||||||
save(path, win.checklists[path])
|
save(path, win.checklists[path])
|
||||||
win.checklists = {}
|
win.checklists = {}
|
||||||
win.assets = {}
|
win.assets = {}
|
||||||
|
win.analytics = analytics.load(win.project)
|
||||||
|
|
||||||
# Grab
|
#### THE GRABBING FUNCTION ####
|
||||||
if win.current["LMB"]\
|
|
||||||
and int(win.current["LMB"][0]) in range(int(x+cXY[0]), int(x+cXY[0]+width))\
|
|
||||||
and int(win.current["LMB"][1]) in range(int(y+cXY[1]), int(y+cXY[1]+height))\
|
|
||||||
and win.current["tool"] == "selection" and task["selected"]\
|
|
||||||
and int(win.current["LMB"][0]) not in range(int(win.current["mx"]-1), int(win.current["mx"]+1))\
|
|
||||||
and int(win.current["LMB"][1]) not in range(int(win.current["my"]-1), int(win.current["my"]+1)):
|
|
||||||
|
|
||||||
win.current["tool"] = "grab"
|
# This is the activation of the grab tool. It uses the same
|
||||||
win.current["moving_task_now"] = False
|
# win.current["tool"] = "grab" as the story editor. Because it makes
|
||||||
|
# sense to reuse it if it already exists. For sake of conviniense.
|
||||||
|
|
||||||
if not win.current["LMB"] and win.previous["LMB"] and win.current["tool"] == "grab"\
|
# It doesn't mean that it uses the same code. It's a bit different.
|
||||||
and task["selected"]:
|
# due to the nature of lists vs free positioning items.
|
||||||
|
|
||||||
win.current["moving_task_now"] = tasks.pop(num)
|
# Now let's set up a few positional variables. So I could move the tasks
|
||||||
|
# while moving the currently selected task. And in the same time will not
|
||||||
|
# screw the data.
|
||||||
|
|
||||||
|
# So I copy the X and the Y locations like this.
|
||||||
|
|
||||||
sx = cXY[0]
|
sx = cXY[0]
|
||||||
sy = win.scroll["checklist"] + cXY[1]
|
sy = win.scroll["checklist"] + cXY[1]
|
||||||
|
|
||||||
thismoving = False
|
grabY = 40
|
||||||
somemoving = False
|
if task["subtasks"]:
|
||||||
someXY = [0,0]
|
grabY = 60
|
||||||
|
|
||||||
|
# Grab
|
||||||
|
if win.current["LMB"]\
|
||||||
|
and int(win.current["LMB"][0]) in range(int(x+sx), int(x+sx+width))\
|
||||||
|
and int(win.current["LMB"][1]) in range(int(y+sy), int(y+sy+grabY))\
|
||||||
|
and win.current["tool"] == "selection"\
|
||||||
|
and int(win.current["LMB"][0]) not in range(int(win.current["mx"]-2), int(win.current["mx"]+2))\
|
||||||
|
and int(win.current["LMB"][1]) not in range(int(win.current["my"]-2), int(win.current["my"]+2)):
|
||||||
|
|
||||||
|
# So here we set up the grab tool and creating a little variable.
|
||||||
|
# This variable (moving_task_now) will consist of 2 parts on release.
|
||||||
|
|
||||||
|
# 1. The entire task ( will subtasks ) using pop. Which is not simply
|
||||||
|
# a copy. But also removing the task from the checklist's list.
|
||||||
|
|
||||||
|
# 2. The current frame of poping. So to offset insertion for 1 frame.
|
||||||
|
# This insures that you insert the task in the correct spot.
|
||||||
|
|
||||||
|
filter_tasks(win.checklists[path])
|
||||||
|
task["selected"] = True
|
||||||
|
win.current["schedule_task_selected"] = False
|
||||||
|
|
||||||
|
win.current["tool"] = "grab"
|
||||||
|
win.current["moving_task_now"] = False
|
||||||
|
|
||||||
|
# Now let's actually setup the pop. So when the mouse is now pressed, but
|
||||||
|
# was on a previous framae, and our current tool is grab.
|
||||||
|
|
||||||
|
if not win.current["LMB"] and win.previous["LMB"] and win.current["tool"] == "grab"\
|
||||||
|
and task["selected"]:
|
||||||
|
|
||||||
|
# We remove the task from the list. And write it to the variable. With
|
||||||
|
# the current frame.
|
||||||
|
|
||||||
|
win.current["moving_task_now"] = [tasks.pop(num), win.current["frame"]]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Now I can touch the sx and sy without screwing up the cXY or scroll.
|
||||||
|
|
||||||
|
thismoving = False # This is going to be True is this is the task that's
|
||||||
|
# moving currently
|
||||||
|
somemoving = False # This is going to be True if any task is moving
|
||||||
|
someXY = [0,0] # And this is the mouse position translated to location
|
||||||
|
# of the checklist. (x, y coordinates of the whole
|
||||||
|
# widget). Or in other words position of the task.
|
||||||
|
|
||||||
|
# Then comes some logic to determen those 3 values.
|
||||||
|
|
||||||
if win.current["tool"] == "grab":
|
if win.current["tool"] == "grab":
|
||||||
|
|
||||||
|
# Okay so here. If grab first we assume that it's some other
|
||||||
|
# task. And now currently selected one.
|
||||||
|
|
||||||
somemoving = True
|
somemoving = True
|
||||||
someXY = [
|
someXY = [
|
||||||
win.current["mx"]-x,
|
win.current["mx"]-x,
|
||||||
win.current["my"]-y
|
win.current["my"]-y
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Now this is the editing of the sx and sy values. To be at
|
||||||
|
# the position of the mouse.
|
||||||
|
|
||||||
if task["selected"]:
|
if task["selected"]:
|
||||||
sx = win.current["mx"] - x + 5
|
|
||||||
sy = win.current["my"] - y + 5
|
# Calculating so the mouse will end up about in the centre
|
||||||
|
# of the task while the task is at motion.
|
||||||
|
|
||||||
|
sx = win.current["mx"] - x - (width - cXY[0])/2
|
||||||
|
sy = win.current["my"] - y - 10
|
||||||
task["open"] = False
|
task["open"] = False
|
||||||
thismoving = True
|
thismoving = True
|
||||||
|
somemoving = False
|
||||||
|
|
||||||
|
# Now if the mouse is outside the frame of the checklist
|
||||||
|
# it will activate the scheduling.
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# SCHEDULING PART #
|
||||||
|
############################################################
|
||||||
|
|
||||||
|
if win.current["mx"] < x:
|
||||||
|
win.url = "analytics"
|
||||||
|
win.current["grab_data"] = [path, back, win.cur, schedulepath]
|
||||||
|
win.current["tool"] = "schedule"
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# SEE studio/studio_analyticsLayer.py
|
||||||
|
# for more details about scheduling
|
||||||
|
#
|
||||||
|
|
||||||
|
# And if back into frame it will return to normal grab mode.
|
||||||
|
|
||||||
|
elif win.current["tool"] == "schedule" and win.current["mx"] > x:
|
||||||
|
win.url = back
|
||||||
|
win.current["tool"] = "grab"
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# SCHEDULING PART END #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
|
||||||
inside = False
|
inside = False
|
||||||
between = False
|
between = False
|
||||||
|
|
||||||
if sy-10 < someXY[1] < sy+10 and somemoving and not task["selected"]:
|
if sy-10 < someXY[1] < sy+10 and somemoving and not task["selected"]:
|
||||||
|
|
||||||
if win.current["moving_task_now"]:
|
if win.current["moving_task_now"] and win.current["moving_task_now"][1] != win.current["frame"]:
|
||||||
tasks.insert(num, win.current["moving_task_now"])
|
tasks.insert(num, win.current["moving_task_now"][0])
|
||||||
win.current["tool"] = "selection"
|
win.current["tool"] = "selection"
|
||||||
win.current["LMB"] = False
|
win.current["LMB"] = False
|
||||||
win.previous["LMB"] = False
|
win.previous["LMB"] = False
|
||||||
|
@ -460,16 +630,17 @@ def draw(outlayer, win, path):
|
||||||
save(path, win.checklists[path])
|
save(path, win.checklists[path])
|
||||||
win.checklists = {}
|
win.checklists = {}
|
||||||
win.assets = {}
|
win.assets = {}
|
||||||
|
win.analytics = analytics.load(win.project)
|
||||||
|
|
||||||
elif win.current["LMB"]:
|
elif win.current["LMB"]:
|
||||||
UI_color.set(layer, win, "progress_background")
|
|
||||||
UI_elements.roundrect(layer, win,
|
for line in range(int(cXY[0]/20)):
|
||||||
cXY[0],
|
|
||||||
win.scroll["checklist"] + cXY[1],
|
line = line * 20 + 10
|
||||||
width - cXY[0],
|
|
||||||
40,
|
UI_color.set(layer, win, "node_background")
|
||||||
10,
|
layer.move_to(line, win.scroll["checklist"] + cXY[1]-10)
|
||||||
fill=False)
|
layer.line_to(line, win.scroll["checklist"] + cXY[1]+40)
|
||||||
layer.stroke()
|
layer.stroke()
|
||||||
|
|
||||||
cXY[1] = cXY[1] + 50
|
cXY[1] = cXY[1] + 50
|
||||||
|
@ -482,8 +653,8 @@ def draw(outlayer, win, path):
|
||||||
|
|
||||||
elif sy < someXY[1] < sy + 40 and somemoving and not task["selected"]:
|
elif sy < someXY[1] < sy + 40 and somemoving and not task["selected"]:
|
||||||
|
|
||||||
if win.current["moving_task_now"]:
|
if win.current["moving_task_now"] and win.current["moving_task_now"][1] != win.current["frame"]:
|
||||||
task["subtasks"].append(win.current["moving_task_now"])
|
task["subtasks"].append(win.current["moving_task_now"][0])
|
||||||
win.current["tool"] = "selection"
|
win.current["tool"] = "selection"
|
||||||
win.current["LMB"] = False
|
win.current["LMB"] = False
|
||||||
win.previous["LMB"] = False
|
win.previous["LMB"] = False
|
||||||
|
@ -492,6 +663,7 @@ def draw(outlayer, win, path):
|
||||||
save(path, win.checklists[path])
|
save(path, win.checklists[path])
|
||||||
win.checklists = {}
|
win.checklists = {}
|
||||||
win.assets = {}
|
win.assets = {}
|
||||||
|
win.analytics = analytics.load(win.project)
|
||||||
|
|
||||||
elif win.current["LMB"]:
|
elif win.current["LMB"]:
|
||||||
inside = True
|
inside = True
|
||||||
|
@ -501,6 +673,7 @@ def draw(outlayer, win, path):
|
||||||
def do():
|
def do():
|
||||||
ed = task["selected"] and not task["editing"]
|
ed = task["selected"] and not task["editing"]
|
||||||
filter_tasks(win.checklists[path])
|
filter_tasks(win.checklists[path])
|
||||||
|
win.current["schedule_task_selected"] = False
|
||||||
task["selected"] = True
|
task["selected"] = True
|
||||||
if ed:
|
if ed:
|
||||||
task["editing"] = True
|
task["editing"] = True
|
||||||
|
@ -508,7 +681,7 @@ def draw(outlayer, win, path):
|
||||||
sx+40,
|
sx+40,
|
||||||
sy,
|
sy,
|
||||||
width - cXY[0]-40,
|
width - cXY[0]-40,
|
||||||
40,
|
grabY,
|
||||||
10,
|
10,
|
||||||
button=do,
|
button=do,
|
||||||
offset=[x,y],
|
offset=[x,y],
|
||||||
|
@ -577,6 +750,7 @@ def draw(outlayer, win, path):
|
||||||
save(path, win.checklists[path])
|
save(path, win.checklists[path])
|
||||||
win.checklists = {}
|
win.checklists = {}
|
||||||
win.assets = {}
|
win.assets = {}
|
||||||
|
win.analytics = analytics.load(win.project)
|
||||||
|
|
||||||
UI_elements.roundrect(layer, win,
|
UI_elements.roundrect(layer, win,
|
||||||
sx,
|
sx,
|
||||||
|
@ -661,16 +835,16 @@ def draw(outlayer, win, path):
|
||||||
|
|
||||||
def do():
|
def do():
|
||||||
task["open"] = not task["open"]
|
task["open"] = not task["open"]
|
||||||
|
win.current["schedule_task_selected"] = False
|
||||||
# Saving
|
# Saving
|
||||||
save(path, win.checklists[path])
|
save(path, win.checklists[path])
|
||||||
win.checklists = {}
|
|
||||||
win.assets = {}
|
|
||||||
|
|
||||||
UI_elements.roundrect(layer, win,
|
UI_elements.roundrect(layer, win,
|
||||||
sx,
|
sx,
|
||||||
sy,
|
sy,
|
||||||
40,
|
40,
|
||||||
40,
|
60,
|
||||||
10,
|
10,
|
||||||
button=do,
|
button=do,
|
||||||
icon=im,
|
icon=im,
|
||||||
|
@ -695,7 +869,7 @@ def draw(outlayer, win, path):
|
||||||
save(path, win.checklists[path])
|
save(path, win.checklists[path])
|
||||||
win.checklists = {}
|
win.checklists = {}
|
||||||
win.assets = {}
|
win.assets = {}
|
||||||
|
win.analytics = analytics.load(win.project)
|
||||||
|
|
||||||
if not task["editing"]:
|
if not task["editing"]:
|
||||||
layer.set_font_size(20)
|
layer.set_font_size(20)
|
||||||
|
@ -788,13 +962,13 @@ def draw(outlayer, win, path):
|
||||||
# THERE IS YOUR RECURSION
|
# THERE IS YOUR RECURSION
|
||||||
|
|
||||||
if task["open"]:
|
if task["open"]:
|
||||||
draw_tasks(task["subtasks"], cXY)
|
draw_tasks(task["subtasks"], cXY, schedulepath)
|
||||||
|
|
||||||
cXY[0] = cXY[0] - 20
|
cXY[0] = cXY[0] - 20
|
||||||
|
|
||||||
# Adding subtasks
|
# Adding subtasks
|
||||||
|
|
||||||
if ((task["subtasks"] and task["open"])\
|
if ((task["subtasks"] and task["open"] and task["selected"])\
|
||||||
or (task["selected"] and not task["subtasks"]))\
|
or (task["selected"] and not task["subtasks"]))\
|
||||||
and win.textactive != "editing_task"\
|
and win.textactive != "editing_task"\
|
||||||
and win.current["tool"] == "selection":
|
and win.current["tool"] == "selection":
|
||||||
|
@ -856,16 +1030,16 @@ def draw(outlayer, win, path):
|
||||||
cXY[0] = cXY[0] - 20
|
cXY[0] = cXY[0] - 20
|
||||||
cXY[1] = cXY[1] + 50
|
cXY[1] = cXY[1] + 50
|
||||||
|
|
||||||
|
schedulepath = []
|
||||||
draw_tasks(win.checklists[path]["subtasks"], cXY)
|
draw_tasks(win.checklists[path]["subtasks"], cXY, schedulepath)
|
||||||
|
|
||||||
# Go to the bottom.
|
# Go to the bottom.
|
||||||
|
|
||||||
if win.current["tool"] == "grab"\
|
if win.current["tool"] == "grab"\
|
||||||
and win.current["my"] - y > cXY[1]:
|
and win.current["my"] - y > win.scroll["checklist"] + cXY[1]:
|
||||||
|
|
||||||
if win.current["moving_task_now"]:
|
if win.current["moving_task_now"] and win.current["moving_task_now"][1] != win.current["frame"]:
|
||||||
win.checklists[path]["subtasks"].append(win.current["moving_task_now"])
|
win.checklists[path]["subtasks"].append(win.current["moving_task_now"][0])
|
||||||
win.current["tool"] = "selection"
|
win.current["tool"] = "selection"
|
||||||
win.current["LMB"] = False
|
win.current["LMB"] = False
|
||||||
win.previous["LMB"] = False
|
win.previous["LMB"] = False
|
||||||
|
@ -874,17 +1048,8 @@ def draw(outlayer, win, path):
|
||||||
save(path, win.checklists[path])
|
save(path, win.checklists[path])
|
||||||
win.checklists = {}
|
win.checklists = {}
|
||||||
win.assets = {}
|
win.assets = {}
|
||||||
|
win.analytics = analytics.load(win.project)
|
||||||
|
|
||||||
elif win.current["LMB"]:
|
|
||||||
UI_color.set(layer, win, "progress_background")
|
|
||||||
UI_elements.roundrect(layer, win,
|
|
||||||
cXY[0],
|
|
||||||
win.scroll["checklist"] + cXY[1],
|
|
||||||
width - cXY[0],
|
|
||||||
40,
|
|
||||||
10,
|
|
||||||
fill=False)
|
|
||||||
layer.stroke()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -935,6 +1100,13 @@ def draw(outlayer, win, path):
|
||||||
|
|
||||||
tileX, current_Y = cXY
|
tileX, current_Y = cXY
|
||||||
|
|
||||||
|
# So there would not be jumps of stuff. Let's add heigh to the scroll while
|
||||||
|
# in grab.
|
||||||
|
if win.current["tool"] == "grab":
|
||||||
|
current_Y = current_Y + height
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Outputting the layer
|
# Outputting the layer
|
||||||
outlayer.set_source_surface(surface, x, y)
|
outlayer.set_source_surface(surface, x, y)
|
||||||
outlayer.paint()
|
outlayer.paint()
|
||||||
|
|
610
studio/schedule.py
Normal file
610
studio/schedule.py
Normal file
|
@ -0,0 +1,610 @@
|
||||||
|
# THIS FILE IS A PART OF VCStudio
|
||||||
|
# PYTHON 3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import datetime
|
||||||
|
import threading
|
||||||
|
|
||||||
|
# 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 project_manager import pm_project
|
||||||
|
|
||||||
|
from studio import analytics
|
||||||
|
from studio import studio_nodes
|
||||||
|
from studio import studio_dialogs
|
||||||
|
from studio import story
|
||||||
|
from studio import analytics
|
||||||
|
from studio import checklist
|
||||||
|
|
||||||
|
#UI modules
|
||||||
|
from UI import UI_elements
|
||||||
|
from UI import UI_color
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
# This file is going to handle SCHEDULING. Primarily the output of the schedules
|
||||||
|
# to the screen. But also probably a lot of other things related to schediles.
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
def filter(project, dates):
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
# This function is called on reading of analytics read. It will check whether
|
||||||
|
# schedules are finished. Or if they are even found. Using studio/checklist.py
|
||||||
|
# as a help.
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
checkcashe = {} # Temporary checklist cashe.
|
||||||
|
|
||||||
|
delete = [] # Stuff I want to delete later
|
||||||
|
|
||||||
|
for date in dates:
|
||||||
|
for i in ["assets", "scenes", "files"]:
|
||||||
|
if i in dates[date]:
|
||||||
|
for url in dates[date][i]:
|
||||||
|
for num, entry in enumerate(dates[date][i][url]):
|
||||||
|
if dates[date][i][url][num][1] == "schedule":
|
||||||
|
|
||||||
|
# First of all. I didn't think about it when
|
||||||
|
# writting the analytics read
|
||||||
|
# that I will need to know whether schedules
|
||||||
|
# are [Checked] or [Un-Checked]
|
||||||
|
|
||||||
|
if not "[Checked]" in dates[date][i][url][num]\
|
||||||
|
and not "[Un-Checked]" in dates[date][i][url][num]:
|
||||||
|
dates[date][i][url][num].insert(3, "[Un-Checked]")
|
||||||
|
|
||||||
|
# Then let's actually try to find whether the task
|
||||||
|
# is checked.
|
||||||
|
|
||||||
|
|
||||||
|
# For now let's do in a simple way. Because
|
||||||
|
# if the whole checklist is 100% done. Then
|
||||||
|
# obviously the task is also checked.
|
||||||
|
|
||||||
|
path = dates[date][i][url][num][2]
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
# Let's check if path exists in the project first.
|
||||||
|
if os.path.exists(project+"/dev"+url+path):
|
||||||
|
path = project+"/dev"+url+path
|
||||||
|
|
||||||
|
|
||||||
|
elif os.path.exists(project+"rnd/"+url+path):
|
||||||
|
path = project+"/rnd"+url+path
|
||||||
|
|
||||||
|
elif os.path.exists(project+"/set/"+path):
|
||||||
|
path = project+"/set/"+path
|
||||||
|
|
||||||
|
elif os.path.exists(project+"/"+path):
|
||||||
|
path = project+"/"+path
|
||||||
|
|
||||||
|
if path not in checkcashe:
|
||||||
|
checkcashe[path] = checklist.get_list(path)
|
||||||
|
|
||||||
|
# Here we check whether the checklist is 100%
|
||||||
|
|
||||||
|
if checkcashe[path]["fraction"] == 1.0:
|
||||||
|
dates[date][i][url][num][3] = "[Checked]"
|
||||||
|
|
||||||
|
# But what if it's not? Now we need to check
|
||||||
|
# them 1 by one.
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
dates[date][i][url][num][3] = "[Un-Checked]"
|
||||||
|
|
||||||
|
task = checklist.get_task_by_path(checkcashe[path]["subtasks"],dates[date][i][url][num][4])
|
||||||
|
|
||||||
|
# Now if the task is not found. We delete the schedule
|
||||||
|
if task:
|
||||||
|
if task["fraction"] == 1.0:
|
||||||
|
dates[date][i][url][num][3] = "[Checked]"
|
||||||
|
|
||||||
|
else:
|
||||||
|
delete.append([date,i,url,dates[date][i][url][num]])
|
||||||
|
except:
|
||||||
|
delete.append([date,i,url,dates[date][i][url][num]])
|
||||||
|
|
||||||
|
# Deleting all kinds of buddah
|
||||||
|
|
||||||
|
for i in delete:
|
||||||
|
q,w,e,r = i
|
||||||
|
if r in dates[q][w][e]:
|
||||||
|
dates[q][w][e].remove(r)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return dates
|
||||||
|
|
||||||
|
def get_schedules(dates):
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
# This function will parse the dates data from the analytics. And get only
|
||||||
|
# the schedules. In the format {date {url, [list of schedules]}}
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
newdates = {}
|
||||||
|
|
||||||
|
for date in dates:
|
||||||
|
if date not in newdates:
|
||||||
|
newdates[date] = {}
|
||||||
|
|
||||||
|
for i in ["assets", "scenes", "files"]:
|
||||||
|
if i in dates[date]:
|
||||||
|
for url in dates[date][i]:
|
||||||
|
for num, entry in enumerate(dates[date][i][url]):
|
||||||
|
if entry[1] == "schedule":
|
||||||
|
if url not in newdates[date]:
|
||||||
|
newdates[date][url] = []
|
||||||
|
if [entry, num] not in newdates[date][url]:
|
||||||
|
newdates[date][url].append([entry, num])
|
||||||
|
|
||||||
|
|
||||||
|
return newdates
|
||||||
|
|
||||||
|
|
||||||
|
def draw(outlayer, win):
|
||||||
|
|
||||||
|
x = 10
|
||||||
|
y = 70
|
||||||
|
width = win.current["w"] / 4 - 20
|
||||||
|
height = win.current["h"] - 80
|
||||||
|
|
||||||
|
# At the top above the schedules. In the bar. i want to put 2
|
||||||
|
# buttons. One will hide done schedules, the other will
|
||||||
|
# hide everything scheduled for other users.
|
||||||
|
|
||||||
|
if "schedule_layer_settings" not in win.current:
|
||||||
|
win.current["schedule_layer_settings"] = {
|
||||||
|
"checked":False,
|
||||||
|
"multiuser":False
|
||||||
|
}
|
||||||
|
|
||||||
|
for num, button in enumerate(win.current["schedule_layer_settings"]):
|
||||||
|
|
||||||
|
if win.current["schedule_layer_settings"][button]:
|
||||||
|
|
||||||
|
UI_color.set(outlayer, win, "progress_time")
|
||||||
|
UI_elements.roundrect(outlayer, win,
|
||||||
|
20+width-(40*num)-60,
|
||||||
|
15,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10)
|
||||||
|
|
||||||
|
def do():
|
||||||
|
win.current["schedule_layer_settings"][button] = not win.current["schedule_layer_settings"][button]
|
||||||
|
|
||||||
|
UI_elements.roundrect(outlayer, win,
|
||||||
|
20+width-(40*num)-60,
|
||||||
|
15,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
do,
|
||||||
|
button)
|
||||||
|
|
||||||
|
|
||||||
|
# Now let's make a layer.
|
||||||
|
|
||||||
|
# Making the layer
|
||||||
|
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
|
||||||
|
layer = cairo.Context(surface)
|
||||||
|
layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
|
||||||
|
|
||||||
|
# Clip
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
10,
|
||||||
|
fill=False)
|
||||||
|
layer.clip()
|
||||||
|
|
||||||
|
|
||||||
|
# Getting various screadule data
|
||||||
|
schedules = get_schedules(win.analytics["dates"])
|
||||||
|
new_date_format = "%Y/%m/%d"
|
||||||
|
today = datetime.datetime.strftime(datetime.datetime.today(), new_date_format)
|
||||||
|
|
||||||
|
slist = []
|
||||||
|
|
||||||
|
for date in schedules:
|
||||||
|
|
||||||
|
if win.current["date"] != today and date != win.current["date"]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for item in schedules[date]:
|
||||||
|
if win.cur == item or not win.cur:
|
||||||
|
|
||||||
|
slist.append([date, item, schedules[date][item]])
|
||||||
|
|
||||||
|
|
||||||
|
# Selection magic
|
||||||
|
if "schedule_task_selected" not in win.current:
|
||||||
|
win.current["schedule_task_selected"] = False
|
||||||
|
|
||||||
|
# Let's draw them to the screen in some way
|
||||||
|
|
||||||
|
if "schedule" not in win.scroll:
|
||||||
|
win.scroll["schedule"] = 0
|
||||||
|
|
||||||
|
current_Y = 0
|
||||||
|
|
||||||
|
for entry in slist:
|
||||||
|
|
||||||
|
for thing in entry[2]:
|
||||||
|
|
||||||
|
# Parsing the cur to get name and type
|
||||||
|
name = entry[1][entry[1].rfind("/")+1:]
|
||||||
|
acur = entry[1].replace(name, "").replace("/", "")
|
||||||
|
fullurl = ""
|
||||||
|
for e in thing[0][4][:-1]:
|
||||||
|
fullurl = fullurl+e+" > "
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "node_background")
|
||||||
|
|
||||||
|
# If not all users show only current user's tasks
|
||||||
|
if not win.current["schedule_layer_settings"]["multiuser"]\
|
||||||
|
and thing[0][-1] != win.settings["Username"]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# If the task is checked
|
||||||
|
if thing[0][3] == "[Checked]":
|
||||||
|
if not win.current["schedule_layer_settings"]["checked"]:
|
||||||
|
continue
|
||||||
|
UI_color.set(layer, win, "node_blendfile") # The Green
|
||||||
|
|
||||||
|
|
||||||
|
elif entry[0] != "1997/07/30":
|
||||||
|
|
||||||
|
if entry[0] < today:
|
||||||
|
UI_color.set(layer, win, "node_badfile") # The Red
|
||||||
|
elif entry[0] > today:
|
||||||
|
UI_color.set(layer, win, "node_asset") # The Purple
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
0,
|
||||||
|
win.scroll["schedule"] + current_Y,
|
||||||
|
width,
|
||||||
|
75,
|
||||||
|
10)
|
||||||
|
|
||||||
|
# Selection button
|
||||||
|
def do():
|
||||||
|
if win.current["schedule_task_selected"] != [ thing, entry[1] ]:
|
||||||
|
win.current["schedule_task_selected"] = [ thing, entry[1] ]
|
||||||
|
|
||||||
|
else:
|
||||||
|
win.current["schedule_task_selected"] = False
|
||||||
|
|
||||||
|
# Clearing the text
|
||||||
|
try:
|
||||||
|
del win.text["schedule_username_setting"]
|
||||||
|
del win.text["schedule_date_setting"]
|
||||||
|
del win.text["schedule_time_setting"]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
0,
|
||||||
|
win.scroll["schedule"] + current_Y,
|
||||||
|
width,
|
||||||
|
75,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
tip=entry[1]+" : "+fullurl+thing[0][4][-1],
|
||||||
|
offset=[x,y],
|
||||||
|
fill=False)
|
||||||
|
layer.stroke()
|
||||||
|
|
||||||
|
# ICON
|
||||||
|
UI_elements.image(layer, win,
|
||||||
|
"settings/themes/"+win.settings["Theme"]+"/icons/schedule.png",
|
||||||
|
5, win.scroll["schedule"] + current_Y+5, 40, 40)
|
||||||
|
|
||||||
|
# MAIN TASK
|
||||||
|
UI_color.set(layer, win, "text_normal")
|
||||||
|
layer.set_font_size(20)
|
||||||
|
layer.move_to(
|
||||||
|
50,
|
||||||
|
win.scroll["schedule"] + current_Y+25,
|
||||||
|
)
|
||||||
|
layer.show_text(thing[0][4][-1])
|
||||||
|
|
||||||
|
# TASK URL INSIDE THE CHECKLIST
|
||||||
|
|
||||||
|
if fullurl:
|
||||||
|
layer.set_font_size(10)
|
||||||
|
layer.move_to(
|
||||||
|
60+len(thing[0][4][-1])*12,
|
||||||
|
win.scroll["schedule"] + current_Y+25,
|
||||||
|
)
|
||||||
|
layer.show_text(fullurl)
|
||||||
|
|
||||||
|
# NAME OF THE ASSET / SHOT
|
||||||
|
if acur in ["chr", "veh", "loc", "obj"]:
|
||||||
|
assetname = talk.text(acur)+": "+name
|
||||||
|
else:
|
||||||
|
assetname = entry[1]
|
||||||
|
|
||||||
|
layer.set_font_size(15)
|
||||||
|
layer.move_to(
|
||||||
|
50,
|
||||||
|
win.scroll["schedule"] + current_Y+45,
|
||||||
|
)
|
||||||
|
layer.show_text(assetname)
|
||||||
|
|
||||||
|
# DATE
|
||||||
|
if entry[0] != "1997/07/30" and entry[0] != today:
|
||||||
|
layer.set_font_size(15)
|
||||||
|
layer.move_to(
|
||||||
|
width-130,
|
||||||
|
win.scroll["schedule"] + current_Y+45,
|
||||||
|
)
|
||||||
|
layer.show_text(entry[0])
|
||||||
|
|
||||||
|
# TIME
|
||||||
|
|
||||||
|
layer.set_font_size(15)
|
||||||
|
layer.move_to(
|
||||||
|
width-130,
|
||||||
|
win.scroll["schedule"] + current_Y+65,
|
||||||
|
)
|
||||||
|
layer.show_text(thing[0][0])
|
||||||
|
|
||||||
|
# USERNAME
|
||||||
|
layer.set_font_size(15)
|
||||||
|
layer.move_to(
|
||||||
|
20,
|
||||||
|
win.scroll["schedule"] + current_Y+65,
|
||||||
|
)
|
||||||
|
layer.show_text(talk.text("user_schedules")+" "+thing[0][-1])
|
||||||
|
|
||||||
|
# IF SELECTED THERE WILL BE MORE STUFF
|
||||||
|
if win.current["schedule_task_selected"] == [ thing, entry[1] ]:
|
||||||
|
UI_color.set(layer, win, "text_normal")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
1,
|
||||||
|
win.scroll["schedule"] + current_Y,
|
||||||
|
width-2,
|
||||||
|
75,
|
||||||
|
10,
|
||||||
|
fill=False)
|
||||||
|
layer.stroke()
|
||||||
|
|
||||||
|
current_Y = current_Y + 85
|
||||||
|
|
||||||
|
# If it's a task from an asset or a scene. There should be a link
|
||||||
|
# to it. But first let's check that's it's infect an asset.
|
||||||
|
# because...
|
||||||
|
|
||||||
|
if entry[1]:
|
||||||
|
|
||||||
|
# If asset:
|
||||||
|
if acur in ["chr", "veh", "loc","obj"]:
|
||||||
|
# ICON
|
||||||
|
UI_elements.image(layer, win,
|
||||||
|
"settings/themes/"+win.settings["Theme"]+"/icons/"+acur+".png",
|
||||||
|
25, win.scroll["schedule"] + current_Y+5, 40, 40)
|
||||||
|
|
||||||
|
goto = "assets"
|
||||||
|
itemtype = "assets"
|
||||||
|
|
||||||
|
elif not acur:
|
||||||
|
itemtype = "files"
|
||||||
|
else:
|
||||||
|
# ICON
|
||||||
|
UI_elements.image(layer, win,
|
||||||
|
"settings/themes/"+win.settings["Theme"]+"/icons/vse.png",
|
||||||
|
25, win.scroll["schedule"] + current_Y+5, 40, 40)
|
||||||
|
|
||||||
|
goto = "script"
|
||||||
|
itemtype = "scenes"
|
||||||
|
|
||||||
|
|
||||||
|
# Here comes the link button
|
||||||
|
|
||||||
|
def do():
|
||||||
|
win.url = goto
|
||||||
|
win.cur = entry[1]
|
||||||
|
win.current["asset_left_panel"] = "schedule"
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
20,
|
||||||
|
win.scroll["schedule"] + current_Y+5,
|
||||||
|
width-20,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
tip=entry[1]+" : "+fullurl+thing[0][4][-1],
|
||||||
|
offset=[x,y],
|
||||||
|
fill=False)
|
||||||
|
layer.stroke()
|
||||||
|
|
||||||
|
#Title
|
||||||
|
UI_color.set(layer, win, "text_normal")
|
||||||
|
layer.set_font_size(20)
|
||||||
|
layer.move_to(
|
||||||
|
80,
|
||||||
|
win.scroll["schedule"] + current_Y+30,
|
||||||
|
)
|
||||||
|
layer.show_text(assetname)
|
||||||
|
|
||||||
|
current_Y = current_Y + 50
|
||||||
|
|
||||||
|
# Next thing! Let's show the most editable values. I think the first
|
||||||
|
# one. For the director will be important. Is to edit the USER.
|
||||||
|
# or in other words. Who is doing the task.
|
||||||
|
|
||||||
|
# In the end It will be a drop down menu. Like all of it. But for this
|
||||||
|
# I need to implement MULTIUSER first. And it's not a priority right
|
||||||
|
# now. So a simple text editor could be okay.
|
||||||
|
|
||||||
|
# ICON
|
||||||
|
UI_elements.image(layer, win,
|
||||||
|
"settings/themes/"+win.settings["Theme"]+"/icons/user.png",
|
||||||
|
25, win.scroll["schedule"] + current_Y+5, 40, 40)
|
||||||
|
|
||||||
|
UI_elements.text(layer, win, "schedule_username_setting",
|
||||||
|
80,
|
||||||
|
win.scroll["schedule"] + current_Y+5,
|
||||||
|
width-80,
|
||||||
|
40,
|
||||||
|
set_text=thing[0][-1],
|
||||||
|
tip=talk.text("username"),
|
||||||
|
offset=[x,y])
|
||||||
|
|
||||||
|
if win.text["schedule_username_setting"]["text"] != thing[0][-1]:
|
||||||
|
def do():
|
||||||
|
thing[0][-1] = win.text["schedule_username_setting"]["text"]
|
||||||
|
analytics.save(win.project, win.analytics)
|
||||||
|
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
width-40,
|
||||||
|
win.scroll["schedule"] + current_Y+5,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
icon="ok",
|
||||||
|
tip=talk.text("checked"),
|
||||||
|
offset=[x,y])
|
||||||
|
|
||||||
|
current_Y = current_Y + 50
|
||||||
|
|
||||||
|
# DATE : TIME
|
||||||
|
|
||||||
|
UI_elements.image(layer, win,
|
||||||
|
"settings/themes/"+win.settings["Theme"]+"/icons/schedule.png",
|
||||||
|
25, win.scroll["schedule"] + current_Y+5, 40, 40)
|
||||||
|
|
||||||
|
UI_elements.text(layer, win, "schedule_date_setting",
|
||||||
|
80,
|
||||||
|
win.scroll["schedule"] + current_Y+5,
|
||||||
|
(width-80)/2-20,
|
||||||
|
40,
|
||||||
|
set_text=entry[0],
|
||||||
|
tip=talk.text("username"),
|
||||||
|
offset=[x,y])
|
||||||
|
|
||||||
|
### DELETE KEY ###
|
||||||
|
|
||||||
|
if acur in ["chr", "veh", "loc","obj"]:
|
||||||
|
itemtype = "assets"
|
||||||
|
elif not acur:
|
||||||
|
itemtype = "files"
|
||||||
|
else:
|
||||||
|
itemtype = "scenes"
|
||||||
|
|
||||||
|
if 65535 in win.current["keys"]:
|
||||||
|
pop = win.analytics["dates"][entry[0]][itemtype]\
|
||||||
|
[entry[1]].pop(thing[1])
|
||||||
|
win.current["keys"] = []
|
||||||
|
|
||||||
|
analytics.save(win.project, win.analytics)
|
||||||
|
win.analytics = analytics.load(win.project)
|
||||||
|
|
||||||
|
if win.text["schedule_date_setting"]["text"] != entry[0]\
|
||||||
|
and analytics.ifdate(win.text["schedule_date_setting"]["text"]):
|
||||||
|
def do():
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pop = win.analytics["dates"][entry[0]][itemtype]\
|
||||||
|
[entry[1]].pop(thing[1])
|
||||||
|
|
||||||
|
if win.text["schedule_date_setting"]["text"] not in win.analytics["dates"]:
|
||||||
|
win.analytics["dates"][win.text["schedule_date_setting"]["text"]] = {}
|
||||||
|
if itemtype not in win.analytics["dates"][win.text["schedule_date_setting"]["text"]]:
|
||||||
|
win.analytics["dates"][win.text["schedule_date_setting"]["text"]][itemtype] = {}
|
||||||
|
if entry[1] not in win.analytics["dates"][win.text["schedule_date_setting"]["text"]][itemtype]:
|
||||||
|
win.analytics["dates"][win.text["schedule_date_setting"]["text"]][itemtype][entry[1]] = []
|
||||||
|
|
||||||
|
win.analytics["dates"][win.text["schedule_date_setting"]["text"]][itemtype]\
|
||||||
|
[entry[1]].append(pop)
|
||||||
|
|
||||||
|
analytics.save(win.project, win.analytics)
|
||||||
|
win.analytics = analytics.load(win.project)
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
(width-80)/2+20,
|
||||||
|
win.scroll["schedule"] + current_Y+5,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
icon="ok",
|
||||||
|
tip=talk.text("checked"),
|
||||||
|
offset=[x,y])
|
||||||
|
|
||||||
|
# TIME
|
||||||
|
|
||||||
|
UI_elements.text(layer, win, "schedule_time_setting",
|
||||||
|
80+(width-80)/2,
|
||||||
|
win.scroll["schedule"] + current_Y+5,
|
||||||
|
(width-80)/2,
|
||||||
|
40,
|
||||||
|
set_text=thing[0][0],
|
||||||
|
tip=talk.text("username"),
|
||||||
|
offset=[x,y])
|
||||||
|
|
||||||
|
if win.text["schedule_time_setting"]["text"] != thing[0][0]\
|
||||||
|
and analytics.iftime(win.text["schedule_time_setting"]["text"]):
|
||||||
|
def do():
|
||||||
|
thing[0][0] = win.text["schedule_time_setting"]["text"]
|
||||||
|
|
||||||
|
analytics.save(win.project, win.analytics)
|
||||||
|
win.analytics = analytics.load(win.project)
|
||||||
|
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
width-40,
|
||||||
|
win.scroll["schedule"] + current_Y+5,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
icon="ok",
|
||||||
|
tip=talk.text("checked"),
|
||||||
|
offset=[x,y])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
current_Y = current_Y + 70
|
||||||
|
|
||||||
|
|
||||||
|
else:
|
||||||
|
current_Y = current_Y + 85
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Outputting the layer
|
||||||
|
outlayer.set_source_surface(surface, x, y)
|
||||||
|
outlayer.paint()
|
||||||
|
|
||||||
|
# Scroll
|
||||||
|
UI_elements.scroll_area(outlayer, win, "schedule",
|
||||||
|
x+0,
|
||||||
|
y+50,
|
||||||
|
width,
|
||||||
|
height-50,
|
||||||
|
current_Y,
|
||||||
|
bar=True,
|
||||||
|
mmb=True)
|
909
studio/studio_analyticsLayer.py
Normal file
909
studio/studio_analyticsLayer.py
Normal file
|
@ -0,0 +1,909 @@
|
||||||
|
# THIS FILE IS A PART OF VCStudio
|
||||||
|
# PYTHON 3
|
||||||
|
|
||||||
|
# This a console project manager.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
# 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,
|
||||||
|
10,
|
||||||
|
win.current["w"]/2,
|
||||||
|
win.current["h"]-20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
# This is the Analitycs window. This time I want to do something crazy.
|
||||||
|
# There will be 5 sections on the screen.
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
# # # #
|
||||||
|
# # # #
|
||||||
|
# # PROGRESS BARS # #
|
||||||
|
# # # #
|
||||||
|
# # # #
|
||||||
|
# # ####################################### # #
|
||||||
|
# # # #
|
||||||
|
# SCHEDULING # ANALYTICS GRAPH # MAIN #
|
||||||
|
# # # CHECKLIS #
|
||||||
|
# # # #
|
||||||
|
# # ####################################### # #
|
||||||
|
# # # #
|
||||||
|
# # CALENDAR / DAY SELECTOR # #
|
||||||
|
# # # #
|
||||||
|
# # X # #
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
# The idea is that you could be in Assets or Script Editor and drag the
|
||||||
|
# tasks from the checklist down to Calendar and leave it there. So when you
|
||||||
|
# move the task and mouse comes into the center part, you automatically
|
||||||
|
# transferred to the analytics layer for untill you leave the task somewhere
|
||||||
|
# or return it back to the checklist.
|
||||||
|
|
||||||
|
# I want to do the same with the SCHEDULING. So you could simple drag it to
|
||||||
|
# the Calendar to change it's date. Let's see how terribly hard will it be
|
||||||
|
# to implement. Because I'm already fighting with the Scedules all day.
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
############## PROGRESS BARS #############
|
||||||
|
|
||||||
|
|
||||||
|
timepassed = 0.0
|
||||||
|
projectdone = 0.0
|
||||||
|
chrdone = 0.0
|
||||||
|
vehdone = 0.0
|
||||||
|
locdone = 0.0
|
||||||
|
objdone = 0.0
|
||||||
|
rnddone = 0.0
|
||||||
|
|
||||||
|
try:
|
||||||
|
timepassed = win.analytics["timepassed"]
|
||||||
|
projectdone = win.analytics["fraction"]
|
||||||
|
chrdone = win.analytics["chr"]
|
||||||
|
vehdone = win.analytics["veh"]
|
||||||
|
locdone = win.analytics["loc"]
|
||||||
|
objdone = win.analytics["obj"]
|
||||||
|
rnddone = win.analytics["rnd"]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# MAIN PROGRESS
|
||||||
|
|
||||||
|
# Icon
|
||||||
|
UI_elements.image(layer, win, "settings/themes/"\
|
||||||
|
+win.settings["Theme"]+"/icons/analytics.png",
|
||||||
|
win.current["w"]/4+10,
|
||||||
|
15,
|
||||||
|
40,
|
||||||
|
40)
|
||||||
|
|
||||||
|
# Progressbar
|
||||||
|
UI_color.set(layer, win, "progress_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4+60,
|
||||||
|
25,
|
||||||
|
win.current["w"]/2-80,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Project Done
|
||||||
|
UI_color.set(layer, win, "progress_active")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4+60,
|
||||||
|
25,
|
||||||
|
(win.current["w"]/2-80)*projectdone,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
# TIME PASSED
|
||||||
|
|
||||||
|
# Icon
|
||||||
|
UI_elements.image(layer, win, "settings/themes/"\
|
||||||
|
+win.settings["Theme"]+"/icons/schedule.png",
|
||||||
|
win.current["w"]/4+10,
|
||||||
|
55,
|
||||||
|
40,
|
||||||
|
40)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4+60,
|
||||||
|
65,
|
||||||
|
win.current["w"]/2-80,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
# Timepassed
|
||||||
|
UI_color.set(layer, win, "progress_time")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4+60,
|
||||||
|
65,
|
||||||
|
(win.current["w"]/2-80)*timepassed,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
# SCENES DONE ( RND )
|
||||||
|
|
||||||
|
# Icon
|
||||||
|
UI_elements.image(layer, win, "settings/themes/"\
|
||||||
|
+win.settings["Theme"]+"/icons/vse.png",
|
||||||
|
win.current["w"]/4+10,
|
||||||
|
95,
|
||||||
|
40,
|
||||||
|
40)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4+60,
|
||||||
|
105,
|
||||||
|
win.current["w"]/2-80,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
# Scenes
|
||||||
|
UI_color.set(layer, win, "node_videofile")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4+60,
|
||||||
|
105,
|
||||||
|
(win.current["w"]/2-80)*rnddone,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
# CHR DONE
|
||||||
|
|
||||||
|
# Icon
|
||||||
|
UI_elements.image(layer, win, "settings/themes/"\
|
||||||
|
+win.settings["Theme"]+"/icons/chr.png",
|
||||||
|
win.current["w"]/4+10,
|
||||||
|
135,
|
||||||
|
40,
|
||||||
|
40)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4+60,
|
||||||
|
145,
|
||||||
|
win.current["w"]/4-80,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
# progress
|
||||||
|
UI_color.set(layer, win, "node_asset")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4+60,
|
||||||
|
145,
|
||||||
|
(win.current["w"]/4-80)*chrdone,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
# VEH DONE
|
||||||
|
|
||||||
|
# Icon
|
||||||
|
UI_elements.image(layer, win, "settings/themes/"\
|
||||||
|
+win.settings["Theme"]+"/icons/veh.png",
|
||||||
|
win.current["w"]/2,
|
||||||
|
135,
|
||||||
|
40,
|
||||||
|
40)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/2+60,
|
||||||
|
145,
|
||||||
|
win.current["w"]/4-80,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
# progress
|
||||||
|
UI_color.set(layer, win, "node_imagefile")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/2+60,
|
||||||
|
145,
|
||||||
|
(win.current["w"]/4-80)*vehdone,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
# LOC DONE
|
||||||
|
|
||||||
|
# Icon
|
||||||
|
UI_elements.image(layer, win, "settings/themes/"\
|
||||||
|
+win.settings["Theme"]+"/icons/loc.png",
|
||||||
|
win.current["w"]/4+10,
|
||||||
|
175,
|
||||||
|
40,
|
||||||
|
40)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4+60,
|
||||||
|
185,
|
||||||
|
win.current["w"]/4-80,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
# progress
|
||||||
|
UI_color.set(layer, win, "node_blendfile")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4+60,
|
||||||
|
185,
|
||||||
|
(win.current["w"]/4-80)*locdone,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
# OBJ DONE
|
||||||
|
|
||||||
|
# Icon
|
||||||
|
UI_elements.image(layer, win, "settings/themes/"\
|
||||||
|
+win.settings["Theme"]+"/icons/obj.png",
|
||||||
|
win.current["w"]/2,
|
||||||
|
175,
|
||||||
|
40,
|
||||||
|
40)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/2+60,
|
||||||
|
185,
|
||||||
|
win.current["w"]/4-80,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
# progress
|
||||||
|
UI_color.set(layer, win, "node_badfile")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/2+60,
|
||||||
|
185,
|
||||||
|
(win.current["w"]/4-80)*objdone,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
############### THE GRAPH ##################
|
||||||
|
|
||||||
|
# This graph going to show the entire time of the whole project from
|
||||||
|
# StartDate till Deadline. It will fill up with data overtime.
|
||||||
|
|
||||||
|
# We are going to have a couple of modes.
|
||||||
|
|
||||||
|
# Regular mode: Showing actuall values represented on the graph
|
||||||
|
# it's going to be a diagonal line if the work was done
|
||||||
|
# linearly.
|
||||||
|
# Normalized : This this a graph of true values compared to time. So let's
|
||||||
|
# say at a second day you had to be only at 3%. Being at 3% will
|
||||||
|
# make graph show 100%. The expected value is linear from 0%
|
||||||
|
# to 100% over the whole project.
|
||||||
|
# Pulse mode : This mode will give a graph compared to the previous day.
|
||||||
|
# if on a given day there was a gib jump in percentage there
|
||||||
|
# will be a big spike on the graph.
|
||||||
|
|
||||||
|
# Let's make a mode selector.
|
||||||
|
|
||||||
|
if "analytics_middle_graph_mode" not in win.current:
|
||||||
|
win.current["analytics_middle_graph_mode"] = "pulse"
|
||||||
|
|
||||||
|
for num, thing in enumerate(["linear", "analytics", "pulse"]): # By icons
|
||||||
|
|
||||||
|
if win.current["analytics_middle_graph_mode"] == thing:
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_time")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4+10+(40*num),
|
||||||
|
225,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10)
|
||||||
|
|
||||||
|
def do():
|
||||||
|
win.current["analytics_middle_graph_mode"] = thing
|
||||||
|
del win.current["graph_cashe"]
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4+10+(40*num),
|
||||||
|
225,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
do,
|
||||||
|
thing)
|
||||||
|
|
||||||
|
# And before we start a little settings icon.
|
||||||
|
|
||||||
|
# Settings
|
||||||
|
def do():
|
||||||
|
win.url = "settings_layer"
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4*3-60,
|
||||||
|
225,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
do,
|
||||||
|
"settings",
|
||||||
|
talk.text("Settings"))
|
||||||
|
|
||||||
|
# Now let's make a filter by type. As you maybe already know appart from
|
||||||
|
# the main progress I'm reading all the other things too. Every progress
|
||||||
|
# bar on the screen should have a corrisponding graph. But sometimes if
|
||||||
|
# paths go too far appart, this aint helpfull. So a filter is required to
|
||||||
|
# switch a category on and off.
|
||||||
|
|
||||||
|
if "analytics_middle_graph_switch" not in win.current:
|
||||||
|
win.current["analytics_middle_graph_switch"] = {
|
||||||
|
"project":[True,"analytics", "progress_active"],
|
||||||
|
"checklist":[True,"checklist", "darker_parts"],
|
||||||
|
"rnd":[True,"vse", "node_videofile"],
|
||||||
|
"chr":[True,"chr", "node_asset"],
|
||||||
|
"veh":[True,"veh", "node_imagefile"], # Name in data : [ Active, Icon name, color ]
|
||||||
|
"loc":[True,"loc", "node_blendfile"],
|
||||||
|
"obj":[True,"obj", "node_badfile"]
|
||||||
|
}
|
||||||
|
|
||||||
|
cat = win.current["analytics_middle_graph_switch"]
|
||||||
|
mode = win.current["analytics_middle_graph_mode"]
|
||||||
|
|
||||||
|
for num, thing in enumerate(cat):
|
||||||
|
|
||||||
|
if cat[thing][0]:
|
||||||
|
|
||||||
|
UI_color.set(layer, win, cat[thing][2])
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4+160+(40*num),
|
||||||
|
225,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10)
|
||||||
|
|
||||||
|
def do():
|
||||||
|
cat[thing][0] = not cat[thing][0]
|
||||||
|
del win.current["graph_cashe"]
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["w"]/4+160+(40*num),
|
||||||
|
225,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
do,
|
||||||
|
cat[thing][1])
|
||||||
|
|
||||||
|
# Let's set up some very handy values
|
||||||
|
new_date_format = "%Y/%m/%d"
|
||||||
|
startdate = win.analytics["startdate"]
|
||||||
|
deadline = win.analytics["deadline"]
|
||||||
|
duration = win.analytics["duration"]
|
||||||
|
|
||||||
|
# Let's setup the little graph layer. So nothing come out of the frame.
|
||||||
|
|
||||||
|
x = win.current["w"]/4
|
||||||
|
y = 280
|
||||||
|
width = win.current["w"] / 2
|
||||||
|
height = (win.current["h"]-300)/2
|
||||||
|
|
||||||
|
# Now let's make a layer.
|
||||||
|
|
||||||
|
if "graph_cashe" not in win.current:
|
||||||
|
|
||||||
|
|
||||||
|
# Making the layer
|
||||||
|
graphsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
|
||||||
|
node = cairo.Context(graphsurface)
|
||||||
|
node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
|
||||||
|
|
||||||
|
|
||||||
|
# Background
|
||||||
|
#UI_color.set(node, win, "dark_overdrop")
|
||||||
|
#node.rectangle(0,0,width, height)
|
||||||
|
#node.fill()
|
||||||
|
|
||||||
|
# helping line
|
||||||
|
UI_color.set(node, win, "progress_background")
|
||||||
|
|
||||||
|
if mode == "analytics":
|
||||||
|
|
||||||
|
node.move_to(0, height/2)
|
||||||
|
node.line_to(width, height/2)
|
||||||
|
|
||||||
|
elif mode == "pulse":
|
||||||
|
|
||||||
|
ty = height / duration
|
||||||
|
node.move_to(0, height/2-ty)
|
||||||
|
node.line_to(width, height/2-ty)
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
node.move_to(0, height)
|
||||||
|
node.line_to(width, 0)
|
||||||
|
|
||||||
|
node.stroke()
|
||||||
|
|
||||||
|
|
||||||
|
for num, thing in enumerate(reversed(cat)):
|
||||||
|
|
||||||
|
if cat[thing][0]:
|
||||||
|
|
||||||
|
UI_color.set(node, win, cat[thing][2])
|
||||||
|
|
||||||
|
if mode == "linear":
|
||||||
|
node.move_to(0, height)
|
||||||
|
else:
|
||||||
|
node.move_to(0, height/2)
|
||||||
|
|
||||||
|
pfrac = 0
|
||||||
|
|
||||||
|
dates = win.analytics["dates"]
|
||||||
|
for date in dates:
|
||||||
|
|
||||||
|
# Let's calculate the X position of a given part on a graph
|
||||||
|
|
||||||
|
sd = datetime.datetime.strptime(startdate, new_date_format)
|
||||||
|
nd = datetime.datetime.strptime(date , new_date_format)
|
||||||
|
|
||||||
|
dn = nd - sd
|
||||||
|
dn = int(dn.days)
|
||||||
|
|
||||||
|
graphX = width / duration * dn
|
||||||
|
|
||||||
|
# Let's calculate the Y position of a given part on a graph
|
||||||
|
|
||||||
|
if "fractions" in dates[date]:
|
||||||
|
fracs = dates[date]["fractions"]
|
||||||
|
|
||||||
|
if mode == "linear":
|
||||||
|
gfraction = fracs[thing]
|
||||||
|
graphY = height - height * gfraction
|
||||||
|
node.line_to(graphX, graphY)
|
||||||
|
elif mode == "analytics":
|
||||||
|
gfraction = fracs[thing]
|
||||||
|
tfraction = dn / duration
|
||||||
|
gfraction = gfraction / tfraction / 2
|
||||||
|
graphY = height - height * gfraction
|
||||||
|
node.line_to(graphX, graphY)
|
||||||
|
else:
|
||||||
|
gfraction = fracs[thing]
|
||||||
|
gfraction = gfraction - pfrac
|
||||||
|
graphY = height - height * gfraction - height / 2
|
||||||
|
node.line_to(graphX, graphY)
|
||||||
|
|
||||||
|
pfrac = fracs[thing]
|
||||||
|
|
||||||
|
node.stroke()
|
||||||
|
|
||||||
|
win.current["graph_cashe"] = graphsurface
|
||||||
|
# Outputting the layer
|
||||||
|
layer.set_source_surface(win.current["graph_cashe"], x, y)
|
||||||
|
layer.paint()
|
||||||
|
|
||||||
|
|
||||||
|
############### SCHEDULING / DATE SELECTION ################
|
||||||
|
|
||||||
|
|
||||||
|
# So here I want to put a dialog that in the Blender-Organizer legacy was
|
||||||
|
# in the center of the frame. I thought here it makes a bit more sense. Tho
|
||||||
|
# I will remove the graph from it. I have a very good graph on the top from
|
||||||
|
# it. And in my opinion this is enough. In you think otherwise let me know.
|
||||||
|
# or fork VCStudio and implement it yourself. See what I can do with free-
|
||||||
|
# software. I can just tell you to do everything yourself. Imaging doing this
|
||||||
|
# when developing proprietery software.
|
||||||
|
|
||||||
|
# Anyway back to the thing. I do want to draw schedules inside the days cells.
|
||||||
|
# and by their colors. RED or GREY or PURPLE or GREEN you will have an idea of
|
||||||
|
# how much stuff is done and how much stuff is not yet done. A kind of second
|
||||||
|
# graph, so to speak. But representing differnt kind of data.
|
||||||
|
|
||||||
|
|
||||||
|
# OKAY. SETTINGS.
|
||||||
|
|
||||||
|
if "schedule_analytics_settings" not in win.current:
|
||||||
|
win.current["schedule_analytics_settings"] = {
|
||||||
|
"checked":False,
|
||||||
|
"multiuser":False
|
||||||
|
}
|
||||||
|
|
||||||
|
for num, button in enumerate(win.current["schedule_analytics_settings"]):
|
||||||
|
|
||||||
|
if win.current["schedule_analytics_settings"][button]:
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "progress_time")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
x+10+(40*num),
|
||||||
|
y+height+10,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10)
|
||||||
|
|
||||||
|
def do():
|
||||||
|
win.current["schedule_analytics_settings"][button] = not win.current["schedule_analytics_settings"][button]
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
x+10+(40*num),
|
||||||
|
y+height+10,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
do,
|
||||||
|
button)
|
||||||
|
|
||||||
|
# CURRENT DATE
|
||||||
|
today = datetime.datetime.strftime(datetime.datetime.today(), new_date_format)
|
||||||
|
|
||||||
|
UI_elements.text(layer, win, "current_date_setting",
|
||||||
|
x+100,
|
||||||
|
y+height+10,
|
||||||
|
200,
|
||||||
|
40,
|
||||||
|
set_text=win.current["date"])
|
||||||
|
|
||||||
|
if win.text["current_date_setting"]["text"] != win.current["date"]\
|
||||||
|
and analytics.ifdate(win.text["current_date_setting"]["text"]):
|
||||||
|
def do():
|
||||||
|
win.current["date"] = win.text["current_date_setting"]["text"]
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
x+260,
|
||||||
|
y+height+10,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
icon="ok",
|
||||||
|
tip=talk.text("checked"))
|
||||||
|
|
||||||
|
elif win.current["date"] != today:
|
||||||
|
def do():
|
||||||
|
win.current["date"] = today
|
||||||
|
win.text["current_date_setting"]["text"] = today
|
||||||
|
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
x+260,
|
||||||
|
y+height+10,
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
icon="cancel",
|
||||||
|
tip=talk.text("cancel"))
|
||||||
|
|
||||||
|
|
||||||
|
y = y + height + 60
|
||||||
|
height = height - 100
|
||||||
|
|
||||||
|
# Making the layer
|
||||||
|
graphsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
|
||||||
|
node = cairo.Context(graphsurface)
|
||||||
|
node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if "days" not in win.scroll:
|
||||||
|
win.scroll["days"] = 0 - win.analytics["dayspassed"]*50 + width / 2 - 25
|
||||||
|
|
||||||
|
current_X = 0
|
||||||
|
|
||||||
|
prevyear = [startdate.split("/")[0], win.scroll["days"]]
|
||||||
|
prevmonth = [startdate.split("/")[1], win.scroll["days"]]
|
||||||
|
|
||||||
|
|
||||||
|
for doffset in range(duration+1): # FOR ALL DAYS. NO MATTER IF THEY ARE IN DATA
|
||||||
|
|
||||||
|
sd = datetime.datetime.strptime(startdate, new_date_format)
|
||||||
|
theday = datetime.datetime.strftime(sd+datetime.timedelta(days=doffset), new_date_format)
|
||||||
|
|
||||||
|
|
||||||
|
nowyear = [theday.split("/")[0], current_X+win.scroll["days"]]
|
||||||
|
nowmonth = [theday.split("/")[1], current_X+win.scroll["days"]]
|
||||||
|
|
||||||
|
# Focusing if selected
|
||||||
|
|
||||||
|
if win.current["date"] != win.previous["date"] and win.current["date"] == theday:
|
||||||
|
win.scroll["days"] = 0 - current_X + width / 2 - 25
|
||||||
|
|
||||||
|
# YEARS
|
||||||
|
|
||||||
|
if nowyear[0] != prevyear[0]:
|
||||||
|
UI_color.set(node, win, "dark_overdrop")
|
||||||
|
UI_elements.roundrect(node, win,
|
||||||
|
5+prevyear[1]+2,
|
||||||
|
0,
|
||||||
|
nowyear[1] - prevyear[1]-7,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
|
||||||
|
UI_color.set(node, win, "text_normal")
|
||||||
|
node.set_font_size(15)
|
||||||
|
node.move_to(
|
||||||
|
max(prevyear[1] + 200, min(width/2-23, nowyear[1]- 200)),
|
||||||
|
15,
|
||||||
|
)
|
||||||
|
node.show_text(prevyear[0])
|
||||||
|
|
||||||
|
prevyear = nowyear
|
||||||
|
|
||||||
|
# MONTHS
|
||||||
|
|
||||||
|
if nowmonth[0] != prevmonth[0]:
|
||||||
|
UI_color.set(node, win, "dark_overdrop")
|
||||||
|
UI_elements.roundrect(node, win,
|
||||||
|
5+prevmonth[1]+2,
|
||||||
|
22,
|
||||||
|
nowmonth[1]-prevmonth[1]-7,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
UI_color.set(node, win, "text_normal")
|
||||||
|
node.set_font_size(15)
|
||||||
|
node.move_to(
|
||||||
|
max(prevmonth[1] + 12, min(width/2-12, nowmonth[1]- 35)),
|
||||||
|
38,
|
||||||
|
)
|
||||||
|
node.show_text(prevmonth[0])
|
||||||
|
|
||||||
|
prevmonth = nowmonth
|
||||||
|
|
||||||
|
# DAYS
|
||||||
|
if -50 < current_X+win.scroll["days"] < width:
|
||||||
|
|
||||||
|
UI_color.set(node, win, "dark_overdrop")
|
||||||
|
UI_elements.roundrect(node, win,
|
||||||
|
5+current_X+win.scroll["days"],
|
||||||
|
44,
|
||||||
|
40,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
UI_color.set(node, win, "text_normal")
|
||||||
|
node.set_font_size(15)
|
||||||
|
node.move_to(
|
||||||
|
15+current_X+win.scroll["days"],
|
||||||
|
59,
|
||||||
|
)
|
||||||
|
node.show_text(theday.split("/")[2])
|
||||||
|
|
||||||
|
UI_color.set(node, win, "dark_overdrop")
|
||||||
|
if theday == today:
|
||||||
|
UI_color.set(node, win, "button_clicked")
|
||||||
|
UI_elements.roundrect(node, win,
|
||||||
|
5+current_X+win.scroll["days"],
|
||||||
|
67,
|
||||||
|
40,
|
||||||
|
height-67,
|
||||||
|
10)
|
||||||
|
|
||||||
|
if win.current["date"] == theday:
|
||||||
|
UI_color.set(node, win, "progress_background")
|
||||||
|
UI_elements.roundrect(node, win,
|
||||||
|
5+current_X+win.scroll["days"],
|
||||||
|
67,
|
||||||
|
40,
|
||||||
|
height-67,
|
||||||
|
10,
|
||||||
|
fill=False)
|
||||||
|
node.stroke()
|
||||||
|
|
||||||
|
# SELECTION BUTTON
|
||||||
|
|
||||||
|
def do():
|
||||||
|
win.current["date"] = theday
|
||||||
|
win.text["current_date_setting"]["text"] = theday
|
||||||
|
UI_elements.roundrect(node, win,
|
||||||
|
5+current_X+win.scroll["days"],
|
||||||
|
67,
|
||||||
|
40,
|
||||||
|
height-67,
|
||||||
|
10,
|
||||||
|
button=do,
|
||||||
|
offset=[x,y],
|
||||||
|
fill=False)
|
||||||
|
node.stroke()
|
||||||
|
|
||||||
|
|
||||||
|
# Now here I want to draw the representations of scheduled
|
||||||
|
# tasks that are insife
|
||||||
|
|
||||||
|
sch = []
|
||||||
|
if theday in win.analytics["dates"]:
|
||||||
|
date = win.analytics["dates"][theday]
|
||||||
|
for i in ["files", "assets", "scenes"]:
|
||||||
|
if i in date:
|
||||||
|
for item in date[i]:
|
||||||
|
for stuff in date[i][item]:
|
||||||
|
if stuff[1] == "schedule":
|
||||||
|
if not win.current["schedule_analytics_settings"]["multiuser"]:
|
||||||
|
if win.settings["Username"] != stuff[-1]:
|
||||||
|
continue
|
||||||
|
if "[Checked]" in stuff:
|
||||||
|
if win.current["schedule_analytics_settings"]["checked"]:
|
||||||
|
sch.append(True)
|
||||||
|
else:
|
||||||
|
sch.append(False)
|
||||||
|
for n, s in enumerate(sch):
|
||||||
|
UI_color.set(node, win, "node_background")
|
||||||
|
if theday < today:
|
||||||
|
UI_color.set(node, win, "node_badfile")
|
||||||
|
elif theday > today:
|
||||||
|
UI_color.set(node, win, "node_asset")
|
||||||
|
if s:
|
||||||
|
UI_color.set(node, win, "node_blendfile")
|
||||||
|
|
||||||
|
UI_elements.roundrect(node, win,
|
||||||
|
8+current_X+win.scroll["days"],
|
||||||
|
70+13*n,
|
||||||
|
35,
|
||||||
|
8,
|
||||||
|
5)
|
||||||
|
|
||||||
|
|
||||||
|
current_X = current_X + 50
|
||||||
|
|
||||||
|
|
||||||
|
UI_color.set(node, win, "dark_overdrop")
|
||||||
|
UI_elements.roundrect(node, win,
|
||||||
|
5+prevyear[1]+2,
|
||||||
|
0,
|
||||||
|
nowyear[1] - prevyear[1]-4 + 50,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
|
||||||
|
UI_color.set(node, win, "text_normal")
|
||||||
|
node.set_font_size(15)
|
||||||
|
node.move_to(
|
||||||
|
max(prevyear[1] + 200, min(width/2-23, nowyear[1]- 200)),
|
||||||
|
15,
|
||||||
|
)
|
||||||
|
node.show_text(prevyear[0])
|
||||||
|
|
||||||
|
UI_color.set(node, win, "dark_overdrop")
|
||||||
|
UI_elements.roundrect(node, win,
|
||||||
|
5+prevmonth[1]+2,
|
||||||
|
22,
|
||||||
|
nowmonth[1]-prevmonth[1]-4 + 50,
|
||||||
|
20,
|
||||||
|
10)
|
||||||
|
|
||||||
|
UI_color.set(node, win, "text_normal")
|
||||||
|
node.set_font_size(15)
|
||||||
|
node.move_to(
|
||||||
|
max(prevmonth[1] + 12, min(width/2-12, nowmonth[1]- 35)),
|
||||||
|
38,
|
||||||
|
)
|
||||||
|
node.show_text(prevmonth[0])
|
||||||
|
|
||||||
|
# Outputting the layer
|
||||||
|
layer.set_source_surface(graphsurface, x, y)
|
||||||
|
layer.paint()
|
||||||
|
|
||||||
|
# Scroll
|
||||||
|
UI_elements.scroll_area(layer, win, "days",
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height+30,
|
||||||
|
current_X,
|
||||||
|
bar=True,
|
||||||
|
mmb=True,
|
||||||
|
sideways=True)
|
||||||
|
|
||||||
|
|
||||||
|
############## CHECKLIST ################
|
||||||
|
|
||||||
|
if win.current["tool"] == "schedule":
|
||||||
|
|
||||||
|
path, back, cur, schedulepath = win.current["grab_data"]
|
||||||
|
|
||||||
|
print(schedulepath)
|
||||||
|
|
||||||
|
checklist.draw(layer, win, path, back)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "node_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
win.current["mx"],
|
||||||
|
win.current["my"],
|
||||||
|
40,
|
||||||
|
40,
|
||||||
|
10)
|
||||||
|
|
||||||
|
UI_elements.image(layer, win,
|
||||||
|
"settings/themes/"+win.settings["Theme"]+"/icons/schedule.png",
|
||||||
|
win.current["mx"],
|
||||||
|
win.current["my"],
|
||||||
|
40,
|
||||||
|
40)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
elif os.path.exists(win.project+"/set/project.progress"):
|
||||||
|
checklist.draw(layer, win, win.project+"/set/project.progress", back=win.url)
|
||||||
|
|
||||||
|
elif os.path.exists(win.project+"/project.progress"):
|
||||||
|
checklist.draw(layer, win, win.project+"/project.progress", back=win.url)
|
||||||
|
|
||||||
|
UI_color.set(layer, win, "node_background")
|
||||||
|
UI_elements.roundrect(layer, win,
|
||||||
|
10,
|
||||||
|
10,
|
||||||
|
win.current["w"]/4-20,
|
||||||
|
50,
|
||||||
|
10)
|
||||||
|
|
||||||
|
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"]-50,
|
||||||
|
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
|
|
@ -29,6 +29,7 @@ from studio import story
|
||||||
from studio import checklist
|
from studio import checklist
|
||||||
from studio import analytics
|
from studio import analytics
|
||||||
from studio import studio_dialogs
|
from studio import studio_dialogs
|
||||||
|
from studio import schedule
|
||||||
|
|
||||||
def layer(win):
|
def layer(win):
|
||||||
|
|
||||||
|
@ -188,6 +189,41 @@ def layer(win):
|
||||||
"settings/themes/"+win.settings["Theme"]+"/icons/"+acur+".png",
|
"settings/themes/"+win.settings["Theme"]+"/icons/"+acur+".png",
|
||||||
130, 130, 40, 40)
|
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
|
# Outputting the layer
|
||||||
layer.set_source_surface(nodesurface,
|
layer.set_source_surface(nodesurface,
|
||||||
win.current["w"]/4+20,
|
win.current["w"]/4+20,
|
||||||
|
@ -669,7 +705,7 @@ def layer(win):
|
||||||
############## CHECKLIST ################
|
############## CHECKLIST ################
|
||||||
|
|
||||||
if os.path.exists(win.project+"/dev/"+win.cur+"/asset.progress"):
|
if os.path.exists(win.project+"/dev/"+win.cur+"/asset.progress"):
|
||||||
checklist.draw(layer, win, win.project+"/dev/"+win.cur+"/asset.progress")
|
checklist.draw(layer, win, win.project+"/dev/"+win.cur+"/asset.progress", back=win.url)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
# If asset.progress does not exist in the folder it will try to create.
|
# If asset.progress does not exist in the folder it will try to create.
|
||||||
|
@ -682,6 +718,63 @@ def layer(win):
|
||||||
"/dev"+win.cur+"/",
|
"/dev"+win.cur+"/",
|
||||||
"asset.progress")
|
"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
|
# CANCEl
|
||||||
|
|
||||||
def do():
|
def do():
|
||||||
|
|
|
@ -9,6 +9,7 @@ import gi
|
||||||
gi.require_version('Gtk', '3.0')
|
gi.require_version('Gtk', '3.0')
|
||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
import cairo
|
import cairo
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
# Own modules
|
# Own modules
|
||||||
|
@ -18,6 +19,7 @@ from project_manager import pm_project
|
||||||
from studio import studio_storyLayer
|
from studio import studio_storyLayer
|
||||||
from studio import studio_settingsLayer
|
from studio import studio_settingsLayer
|
||||||
from studio import studio_assetLayer
|
from studio import studio_assetLayer
|
||||||
|
from studio import studio_analyticsLayer
|
||||||
|
|
||||||
# Studio
|
# Studio
|
||||||
from studio import analytics
|
from studio import analytics
|
||||||
|
@ -119,6 +121,10 @@ def run(project, win):
|
||||||
win.current["draw_dot"] = "end"
|
win.current["draw_dot"] = "end"
|
||||||
win.current["calls"] = {} # Calls. See sutdio/studio_dialogs.py
|
win.current["calls"] = {} # Calls. See sutdio/studio_dialogs.py
|
||||||
|
|
||||||
|
new_date_format = "%Y/%m/%d"
|
||||||
|
today = datetime.datetime.strftime(datetime.datetime.today(), new_date_format)
|
||||||
|
win.current["date"] = today # Don't even ask. I'm litteraly tired already.
|
||||||
|
|
||||||
previous(win)
|
previous(win)
|
||||||
|
|
||||||
# Version of the software
|
# Version of the software
|
||||||
|
@ -242,10 +248,14 @@ def pmdrawing(pmdrawing, main_layer, win):
|
||||||
elif win.url == "settings_layer":
|
elif win.url == "settings_layer":
|
||||||
Layers.append([studio_settingsLayer.layer(win),"settings_layer"])
|
Layers.append([studio_settingsLayer.layer(win),"settings_layer"])
|
||||||
|
|
||||||
|
elif win.url == "analytics":
|
||||||
|
Layers.append([studio_analyticsLayer.layer(win),"analytics"])
|
||||||
|
|
||||||
elif win.url == "assets":
|
elif win.url == "assets":
|
||||||
Layers.append([studio_assetLayer.layer(win),"assets"])
|
Layers.append([studio_assetLayer.layer(win),"assets"])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Call layers. See studio/studio_dialogs.py for explanation. It's wild.
|
# Call layers. See studio/studio_dialogs.py for explanation. It's wild.
|
||||||
|
|
||||||
win.calllayer = False
|
win.calllayer = False
|
||||||
|
@ -276,10 +286,16 @@ def pmdrawing(pmdrawing, main_layer, win):
|
||||||
if len(layer) > 1:
|
if len(layer) > 1:
|
||||||
layer, url = layer
|
layer, url = layer
|
||||||
blur = UI_elements.animate(url+"_blur", win, 50)
|
blur = UI_elements.animate(url+"_blur", win, 50)
|
||||||
if win.url != url or win.calllayer:
|
if (win.url != url or win.calllayer):
|
||||||
|
if win.current["tool"] not in ["schedule", "grab"]:
|
||||||
blur = UI_elements.animate(url+"_blur", win, blur, 50, 2, True)
|
blur = UI_elements.animate(url+"_blur", win, blur, 50, 2, True)
|
||||||
else:
|
else:
|
||||||
|
blur = UI_elements.animate(url+"_blur", win, 50, 50, 0, True)
|
||||||
|
else:
|
||||||
|
if win.current["tool"] not in ["schedule", "grab"]:
|
||||||
blur = UI_elements.animate(url+"_blur", win, blur, 0, 2, True)
|
blur = UI_elements.animate(url+"_blur", win, blur, 0, 2, True)
|
||||||
|
else:
|
||||||
|
blur = UI_elements.animate(url+"_blur", win, 0, 0, 0, True)
|
||||||
layer = UI_elements.blur(layer, win, blur)
|
layer = UI_elements.blur(layer, win, blur)
|
||||||
else:
|
else:
|
||||||
layer = layer[0]
|
layer = layer[0]
|
||||||
|
|
|
@ -71,7 +71,9 @@ def layer(win):
|
||||||
|
|
||||||
# Hude analytics button on the top
|
# Hude analytics button on the top
|
||||||
def do():
|
def do():
|
||||||
print("Analytics")
|
win.cur = ""
|
||||||
|
win.url = "analytics"
|
||||||
|
|
||||||
|
|
||||||
UI_elements.roundrect(layer, win,
|
UI_elements.roundrect(layer, win,
|
||||||
5,
|
5,
|
||||||
|
@ -480,9 +482,14 @@ def layer(win):
|
||||||
10,
|
10,
|
||||||
do,
|
do,
|
||||||
"chr",
|
"chr",
|
||||||
talk.text("chr"),
|
talk.text("chr")+"\n[Shift-C]",
|
||||||
url="story_editor")
|
url="story_editor")
|
||||||
|
|
||||||
|
# Shortcut
|
||||||
|
if 67 in win.current["keys"] and not win.textactive:
|
||||||
|
do()
|
||||||
|
win.current["keys"] = []
|
||||||
|
|
||||||
# Vehicles
|
# Vehicles
|
||||||
def do():
|
def do():
|
||||||
studio_dialogs.asset_select(win, "new_asset_story", select_character, force=True, cur="veh")
|
studio_dialogs.asset_select(win, "new_asset_story", select_character, force=True, cur="veh")
|
||||||
|
@ -495,9 +502,14 @@ def layer(win):
|
||||||
10,
|
10,
|
||||||
do,
|
do,
|
||||||
"veh",
|
"veh",
|
||||||
talk.text("veh"),
|
talk.text("veh")+"\n[Shift-V]",
|
||||||
url="story_editor")
|
url="story_editor")
|
||||||
|
|
||||||
|
# Shortcut
|
||||||
|
if 86 in win.current["keys"] and not win.textactive:
|
||||||
|
do()
|
||||||
|
win.current["keys"] = []
|
||||||
|
|
||||||
# Locations
|
# Locations
|
||||||
def do():
|
def do():
|
||||||
studio_dialogs.asset_select(win, "new_asset_story", select_character, force=True, cur="loc")
|
studio_dialogs.asset_select(win, "new_asset_story", select_character, force=True, cur="loc")
|
||||||
|
@ -510,9 +522,14 @@ def layer(win):
|
||||||
10,
|
10,
|
||||||
do,
|
do,
|
||||||
"loc",
|
"loc",
|
||||||
talk.text("loc"),
|
talk.text("loc")+"\n[Shift-L]",
|
||||||
url="story_editor")
|
url="story_editor")
|
||||||
|
|
||||||
|
# Shortcut
|
||||||
|
if 76 in win.current["keys"] and not win.textactive:
|
||||||
|
do()
|
||||||
|
win.current["keys"] = []
|
||||||
|
|
||||||
# Other (obj)
|
# Other (obj)
|
||||||
def do():
|
def do():
|
||||||
studio_dialogs.asset_select(win, "new_asset_story", select_character, force=True, cur="obj")
|
studio_dialogs.asset_select(win, "new_asset_story", select_character, force=True, cur="obj")
|
||||||
|
@ -525,9 +542,14 @@ def layer(win):
|
||||||
10,
|
10,
|
||||||
do,
|
do,
|
||||||
"obj",
|
"obj",
|
||||||
talk.text("obj"),
|
talk.text("obj")+"\n[Shift-O]",
|
||||||
url="story_editor")
|
url="story_editor")
|
||||||
|
|
||||||
|
# Shortcut
|
||||||
|
if 79 in win.current["keys"] and not win.textactive:
|
||||||
|
do()
|
||||||
|
win.current["keys"] = []
|
||||||
|
|
||||||
# Sounds / Music
|
# Sounds / Music
|
||||||
def do():
|
def do():
|
||||||
print("Sounds / Music")
|
print("Sounds / Music")
|
||||||
|
|
Loading…
Add table
Reference in a new issue