Blender-Pipeline/studio/studio_storyLayer.py
Jeison Yehuda Amihud (Blender Dumbass) 162d3f8038 Multiuser Bug Fixes
Implemented missing features that could be
seen as bugs for the casual users.

Such as sync of the main checklist. And other
minor changes.
2021-01-04 15:52:29 +00:00

1274 lines
39 KiB
Python

# 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 oscalls
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 schedule
#UI modules
from UI import UI_elements
from UI import UI_color
def layer(win):
########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
stf = datetime.datetime.now()
perfStat = []
###################################################################
# 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)
########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
fif = datetime.datetime.now()
mil = fif - stf
perfStat.append([ "Setup", mil.microseconds ])
stf = datetime.datetime.now()
###################################################################
UI_color.set(layer, win, "darker_parts")
UI_elements.roundrect(layer, win,
50,
50,
win.current["w"] - 100,
win.current["h"] - 80,
30)
# Little verion thing in the bottom corner
UI_color.set(layer, win, "testing_banner")
layer.set_font_size(15)
layer.move_to(win.current["w"]-80, win.current["h"] - 7)
layer.show_text(str(win.version))
# Hude analytics button on the top
def do():
win.cur = "/set"
win.url = "analytics"
UI_elements.roundrect(layer, win,
5,
5,
win.current["w"]-(win.current["w"]/3)+45,
40,
10,
do,
"analytics",
talk.text("analytics_tooltip"),
url="story_editor")
# Progressbar
UI_color.set(layer, win, "progress_background")
UI_elements.roundrect(layer, win,
55,
15,
win.current["w"]/3*2-10,
20,
10)
timepassed = 0.0
projectdone = 0.0
try:
timepassed = win.analytics["timepassed"]
projectdone = win.analytics["fraction"]
except:
pass
# Timepassed
UI_color.set(layer, win, "progress_time")
UI_elements.roundrect(layer, win,
55,
15,
(win.current["w"]/3*2-10)*timepassed,
20,
10)
# Project Done
UI_color.set(layer, win, "progress_active")
UI_elements.roundrect(layer, win,
55,
15,
(win.current["w"]/3*2-10)*projectdone,
20,
10)
# Separator
UI_color.set(layer, win, "node_background")
layer.move_to(win.current["w"]/3*2+55, 5)
layer.line_to(win.current["w"]/3*2+55, 45)
layer.stroke()
############ CURRENT TASK SCHEDULED #############
# FIRST WE NEED TO GET A LIST OF TASKS
# This is going to be a simplified version of the same stuff as in the
# scheduling. But since we don't care what date we are in and trying to
# get the oldest unchecked task. Here we go.
schedules = schedule.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:
for item in schedules[date]:
if win.cur == item or not win.cur == "/set":
slist.append([date, item, schedules[date][item]])
# Now that we have our list we can start paring it the same way as in the
# scheduling. Only removing some unnesesary stuff.
foundtask = False
taskname = ""
taskurl = ""
taskcur = ""
for entry in slist:
if not foundtask:
for thing in entry[2]:
if thing[0][3] == "[Checked]":
continue # We do not care about those who are checked here.
elif thing[0][-1] != win.settings["Username"]:
continue # We do not care if it's not for us
else:
foundtask = True
# Here we are going to take out some data about this task
# First if it's not for today let's get a color for it
if entry[0] != "1997/07/30":
draw = False
if entry[0] < today:
UI_color.set(layer, win, "node_badfile") # The Red
draw = True
elif entry[0] > today:
UI_color.set(layer, win, "node_asset") # The Purple
draw = True
if draw:
UI_elements.roundrect(layer, win,
win.current["w"]/3*2+60,
5,
(win.current["w"]/3-65),
40,
10)
name = entry[1][entry[1].rfind("/")+1:]
acur = entry[1].replace(name, "").replace("/", "")
fullurl = ""
for e in thing[0][4][:-1]:
fullurl = fullurl+e+" > "
if acur in ["chr", "veh", "loc", "obj"]:
assetname = talk.text(acur)+": "+name
else:
assetname = entry[1]
# ASSINGING TEXT VALUES
taskname = thing[0][4][-1]
taskurl = fullurl
taskcur = assetname.replace("/set","")
# AND A TINY BUTTON TO ENTER WHAT EVER YOU ARE DOING
goto = "analytics"
if acur in ["chr", "veh", "loc","obj"]:
goto = "assets"
itemtype = "assets"
elif not acur:
itemtype = "files"
else:
goto = "script"
itemtype = "scenes"
def do():
win.url = goto
win.cur = entry[1]
win.current["asset_left_panel"] = "schedule"
UI_elements.roundrect(layer, win,
win.current["w"]/3*2+60,
5,
(win.current["w"]/3-65),
40,
10,
button=do)
break
else:
break
# Schedule
if taskname:
UI_elements.image(layer, win, "settings/themes/"\
+win.settings["Theme"]+"/icons/schedule.png",
win.current["w"]/3*2+60,
5,
40,
40)
UI_color.set(layer, win, "text_normal")
layer.set_font_size(20)
layer.move_to(win.current["w"]/3*2+120, 25)
layer.show_text(taskname)
layer.set_font_size(12)
layer.move_to(win.current["w"]/3*2+130+len(taskname)*12, 25)
layer.show_text(taskurl)
layer.set_font_size(12)
layer.move_to(win.current["w"]/3*2+120, 40)
layer.show_text(taskcur)
########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
fif = datetime.datetime.now()
mil = fif - stf
perfStat.append([ "Analytics", mil.microseconds ])
stf = datetime.datetime.now()
###################################################################
###### LEFT PANNEL #######
# New Scene
def do():
# Okay let's make the adding the scene possible.
# First we need to know what scenes are there. So we don't overwrite
# any existing scene.
scenename = "Scene"
count = 2
while scenename in win.story["scenes"]:
scenename = "Scene_"+str(count)
count = count + 1
# Now that we have an empty name. Let's add a scene.
win.story["scenes"][scenename] = {
"fraction":0.0, # Percentage
"position":[
win.current["mx"]-win.story["camera"][0]-50,
win.current["my"]-win.story["camera"][1]-30
],
"size":[100, 60],
"parent":"", # For when it's in a Frame (Event)
"shots":[[
"text_block",[["text", '']]
]]
}
# Auto select the new scene
win.story["selected"] = [["scene", scenename]]
win.current["tool"] = "grab"
# A hack I guess. I don't know what I'm doing. I'm trying to force
# the motion on click.
win.current["LMB"] = [win.current["mx"], win.current["my"], True]
# In studio/studio_gtk.py there is a command that recognizes the length
# of the LMB. And it's more then 2 it does some magic to make stuff move
# without pressing the actuall key. It's slightly too clever even for me
# so yeah.
UI_elements.roundrect(layer, win,
5,
105,
40,
40,
10,
do,
"scene_new",
talk.text("new_scene_tooltip")+"\n[N]",
url="story_editor")
# Shortcut
if 110 in win.current["keys"] and not win.textactive:
do()
win.current["keys"] = []
# Link Asset
def do():
def after(win, var):
print (var)
if var:
win.story["links"].append([
"asset", var, [
win.current["mx"]-win.story["camera"][0]-75,
win.current["my"]-win.story["camera"][1]-75
],
"" # Parent
])
# Now let's select and move the thing
win.story["selected"] = [["asset", len(win.story["links"])-1]]
win.current["tool"] = "grab"
win.current["LMB"] = [win.current["mx"], win.current["my"], True]
studio_dialogs.asset_select(win, "new_asset_story", after)
UI_elements.roundrect(layer, win,
5,
155,
40,
40,
10,
do,
"obj_link",
talk.text("link_asset_tooltip")+"\n[L]",
url="story_editor")
# Shortcut
if 108 in win.current["keys"] and not win.textactive:
do()
win.current["keys"] = []
# Link File
def do():
def after(win, var):
if var:
win.story["links"].append([
"file", var, [
win.current["mx"]-win.story["camera"][0]-75,
win.current["my"]-win.story["camera"][1]-75
],
"" # Parent
])
# Now let's select and move the thing
win.story["selected"] = [["file", len(win.story["links"])-1]]
win.current["tool"] = "grab"
win.current["LMB"] = [win.current["mx"], win.current["my"], True]
studio_dialogs.file_select(win, "new_file_story", after, force=True)
UI_elements.roundrect(layer, win,
5,
205,
40,
40,
10,
do,
"file_link",
talk.text("link_file_tooltip")+"\n[I]",
url="story_editor")
# Shortcut
if 105 in win.current["keys"] and not win.textactive:
do()
win.current["keys"] = []
# Marker
def do():
markername = "Marker"
count = 2
while markername in win.story["markers"]:
markername = "Marker_"+str(count)
count = count + 1
win.story["markers"][markername] = [
win.current["mx"]-win.story["camera"][0]+50,
win.current["my"]-win.story["camera"][1]-20,
"" # Parent
]
win.textactive = markername+"_marker"
win.text[markername+"_marker"] = {
"text" :markername, # Actuall text you are editing.
"cursor":[len(str(markername)),len(str(markername))], # Cursor
"insert":False, # Whether the insert mode is on
"scroll":"markername_scroll" # If multiline. The pointer for the scroll value.
}
win.story["selected"] = [["marker", markername]]
win.current["tool"] = "grab"
win.current["LMB"] = [win.current["mx"], win.current["my"], True]
UI_elements.roundrect(layer, win,
5,
255,
40,
40,
10,
do,
"pin",
talk.text("marker_tooltip")+"\n[M]",
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
def do():
def after(win, var):
pass
studio_dialogs.render(win, "current_renders", after)
UI_elements.roundrect(layer, win,
5,
405,
40,
40,
10,
do,
"render",
talk.text("render_lists_tooltip"),
url="story_editor")
# Let's draw on top of this button a little indicator of how many renders
# are currently setup.
if win.renders:
count = str(len(win.renders))
UI_color.set(layer, win, "node_background")
UI_elements.roundrect(layer, win,
30,
405,
len(count)*12+6,
25,
5)
layer.fill()
UI_color.set(layer, win, "text_normal")
layer.set_font_size(20)
layer.move_to(33,425)
layer.show_text(count)
# Edit Video
def do():
def after(win, var):
if var:
print(var)
oscalls.file_open(win, var)
studio_dialogs.vse(win, "VSEs", after)
UI_elements.roundrect(layer, win,
5,
455,
40,
40,
10,
do,
"vse",
talk.text("vse_tooltip"),
url="story_editor")
# Bottom
# Multiuser
def do():
win.url = "multiuser"
UI_elements.roundrect(layer, win,
5,
win.current["h"]-95,
40,
40,
10,
do,
"multiuser",
talk.text("multiuser_tooltip"),
url="story_editor")
if win.multiuser["unread"]:
count = str(win.multiuser["unread"])
UI_color.set(layer, win, "node_background")
UI_elements.roundrect(layer, win,
30,
win.current["h"]-100,
len(count)*12+6,
25,
5)
layer.fill()
UI_color.set(layer, win, "text_normal")
layer.set_font_size(20)
layer.move_to(33,win.current["h"]-83)
layer.show_text(count)
# Settings
def do():
win.url = "settings_layer"
UI_elements.roundrect(layer, win,
5,
win.current["h"]-45,
40,
40,
10,
do,
"settings",
talk.text("Settings"),
url="story_editor")
########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
fif = datetime.datetime.now()
mil = fif - stf
perfStat.append([ "Left Panel", mil.microseconds ])
stf = datetime.datetime.now()
###################################################################
###### RIGHT PANNEL #######
def select_character(win, var):
if var:
win.url = "assets"
win.cur = var
win.current["tool"] = "selection"
# Characters
def do():
studio_dialogs.asset_select(win, "new_asset_story", select_character, force=True, cur="chr")
UI_elements.roundrect(layer, win,
win.current["w"]-45,
105,
40,
40,
10,
do,
"chr",
talk.text("chr")+"\n[Shift-C]",
url="story_editor")
# Shortcut
if 67 in win.current["keys"] and not win.textactive:
do()
win.current["keys"] = []
# Vehicles
def do():
studio_dialogs.asset_select(win, "new_asset_story", select_character, force=True, cur="veh")
UI_elements.roundrect(layer, win,
win.current["w"]-45,
155,
40,
40,
10,
do,
"veh",
talk.text("veh")+"\n[Shift-V]",
url="story_editor")
# Shortcut
if 86 in win.current["keys"] and not win.textactive:
do()
win.current["keys"] = []
# Locations
def do():
studio_dialogs.asset_select(win, "new_asset_story", select_character, force=True, cur="loc")
UI_elements.roundrect(layer, win,
win.current["w"]-45,
205,
40,
40,
10,
do,
"loc",
talk.text("loc")+"\n[Shift-L]",
url="story_editor")
# Shortcut
if 76 in win.current["keys"] and not win.textactive:
do()
win.current["keys"] = []
# Other (obj)
def do():
studio_dialogs.asset_select(win, "new_asset_story", select_character, force=True, cur="obj")
UI_elements.roundrect(layer, win,
win.current["w"]-45,
255,
40,
40,
10,
do,
"obj",
talk.text("obj")+"\n[Shift-O]",
url="story_editor")
# Shortcut
if 79 in win.current["keys"] and not win.textactive:
do()
win.current["keys"] = []
# Sounds / Music
def do():
os.system("xdg-open "+win.project+"/mus")
UI_elements.roundrect(layer, win,
win.current["w"]-45,
355,
40,
40,
10,
do,
"mus",
talk.text("mus"),
url="story_editor")
# Help
def do():
def after(win, var):
pass
studio_dialogs.help(win, "help", after, SEARCH=talk.text("documentation_story_editor"))
UI_elements.roundrect(layer, win,
win.current["w"]-45,
win.current["h"]-125,
40,
40,
10,
do,
"question",
url="story_editor")
# Folder
def do():
os.system("xdg-open "+win.project)
UI_elements.roundrect(layer, win,
win.current["w"]-45,
win.current["h"]-75,
40,
40,
10,
do,
"folder",
talk.text("project_folder"),
url="story_editor")
########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
fif = datetime.datetime.now()
mil = fif - stf
perfStat.append([ "Right Pannel", mil.microseconds ])
stf = datetime.datetime.now()
###################################################################
####### NODES #######
# Clipping so it wont draw beyon the frame
UI_elements.roundrect(layer, win,
50,
50,
win.current["w"] - 100,
win.current["h"] - 80,
30,
fill=False)
layer.clip()
# Background Image
if os.path.exists(win.project+"/set/banner.png"):
UI_elements.image(layer, win, win.project+"/set/banner.png",
50,
50,
win.current["w"] - 100,
win.current["h"] - 80,
cell="background")
elif os.path.exists(win.project+"/py_data/banner.png"):
UI_elements.image(layer, win, win.project+"/py_data/banner.png",
50,
50,
win.current["w"] - 100,
win.current["h"] - 80,
cell="background")
else:
UI_elements.image(layer, win, "icon.png",
50,
50,
win.current["w"] - 100,
win.current["h"] - 80,
cell="background")
UI_color.set(layer, win, "node_background")
layer.rectangle(0,0,win.current["w"], win.current["h"])
layer.fill()
########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
fif = datetime.datetime.now()
mil = fif - stf
perfStat.append([ "Background Image", mil.microseconds ])
stf = datetime.datetime.now()
###################################################################
# You probably intersted where is the scroll function for this part. Well
# see there is a thing. It's easier to write one from screach here. Because
# you geassed it we are starting to draw story editor.
# Let's prepare the camera first.
# Animation
win.story["camera"][0] = UI_elements.animate("cameraX", win, 0, win.story["camera"][0])
win.story["camera"][1] = UI_elements.animate("cameraY", win, 0, win.story["camera"][1])
cx, cy = win.story["camera"]
if win.url == "story_editor":
if win.current["MMB"]:
win.story["camera"][0] += ( win.current["mx"]-win.previous["mx"])
win.story["camera"][1] += ( win.current["my"]-win.previous["my"])
win.story["camera"][0] -= win.current["scroll"][0]*50
win.story["camera"][1] -= win.current["scroll"][1]*50
if cx != win.story["camera"][0] or cy != win.story["camera"][1]:
UI_elements.animate("cameraX", win, win.story["camera"][0], force=True)
UI_elements.animate("cameraY", win, win.story["camera"][1], force=True)
########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
fif = datetime.datetime.now()
mil = fif - stf
perfStat.append([ "Camera position", mil.microseconds ])
stf = datetime.datetime.now()
###################################################################
# EVENTS (Frames)
try:
for event in win.story["events"]:
# Loaction
sx, sy = win.story["events"][event]["position"]
# Scale
ssx, ssy = win.story["events"][event]["size"]
#Draw
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
########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
fif = datetime.datetime.now()
mil = fif - stf
perfStat.append([ "Events", mil.microseconds ])
stf = datetime.datetime.now()
###################################################################
# SCENES
try:
for scene in win.story["scenes"]:
# Loaction
sx, sy = win.story["scenes"][scene]["position"]
sx = sx + cx
sy = sy + cy
# Scale
ssx, ssy = win.story["scenes"][scene]["size"]
#Fraction
sf = win.story["scenes"][scene]["fraction"]
#Draw
studio_nodes.scene_node(layer, win, sx, sy, ssx, ssy, name=scene, fraction=sf)
except:
pass
########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
fif = datetime.datetime.now()
mil = fif - stf
perfStat.append([ "Scenes", mil.microseconds ])
stf = datetime.datetime.now()
###################################################################
# LINKS (Images, Stuff)
for num, link in enumerate(win.story["links"]):
linktype = link[0]
linkname = link[1]
lx = link[2][0] + cx
ly = link[2][1] + cy
# For the one inside the project. They should be always relative
# so even if the project is in a complitely different location
# on another machine. Where we have our Multiuser data. It should
# be able to load these.
if win.project in link[1]:
link[1] = link[1].replace(win.project, "")
studio_nodes.link_node(layer, win, lx, ly, name=linkname, num=num, linktype=linktype )
########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
fif = datetime.datetime.now()
mil = fif - stf
perfStat.append([ "Files / Assets", mil.microseconds ])
stf = datetime.datetime.now()
###################################################################
# Let's put in the start and the end nodes. These are drawn on top of
# everything.
studio_nodes.start_node(layer, win, 60,60,100,40)
studio_nodes.end_node(layer, win, win.current["w"] - 160,
win.current["h"] - 80,
100,40)
########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
fif = datetime.datetime.now()
mil = fif - stf
perfStat.append([ "Start / End Nodes", mil.microseconds ])
stf = datetime.datetime.now()
###################################################################
# MARKERS
try:
for marker in win.story["markers"]:
mx = win.story["markers"][marker][0] + cx
my = win.story["markers"][marker][1] + cy
studio_nodes.marker(layer, win, marker, mx, my)
except:
pass
# MARKERS
try:
for user in win.multiuser["users"]:
if user != win.multiuser["userid"]:
mx = 0-win.multiuser["users"][user]["camera"][0] +cx + win.current["w"]/2
my = 0-win.multiuser["users"][user]["camera"][1] +cy + win.current["h"]/2
studio_nodes.user(layer, win, win.multiuser["users"][user]["username"], mx, my, user)
except Exception as e:
print(e, "USER RENDERING")
########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
fif = datetime.datetime.now()
mil = fif - stf
perfStat.append([ "Markers", mil.microseconds ])
stf = datetime.datetime.now()
###################################################################
# In case there is a selection bug
if not win.story["selected"] and win.current["tool"] != "connect":
win.current["tool"] = "selection"
# Selector visualization
if win.current["LMB"] and win.current["tool"] == "selection" and win.url == "story_editor":
# Draw selection box
UI_color.set(layer, win, "progress_background")
layer.rectangle(
win.current["mx"],
win.current["my"],
win.current["LMB"][0] - win.current["mx"],
win.current["LMB"][1] - win.current["my"]
)
layer.stroke()
# Now let's draw the cool AF multi selection zone thingy
# Draw selection box
if len(win.story["selected"]) > 1 and win.current["tool"] == "selection":
UI_color.set(layer, win, "progress_background")
layer.rectangle(
win.szone[0][0]-10,
win.szone[0][1]-10,
win.szone[1][0]+20,
win.szone[1][1]+20
)
layer.stroke()
# Now I want to make a tiny widget that will resize the stuff.
if win.story["selected"]:
if win.current["tool"] == "selection":
draw_circle = True
if len(win.story["selected"]) == 1:
if win.story["selected"][0][0] != "scene":
draw_circle = False
if draw_circle:
UI_color.set(layer, win, "node_badfile")
UI_elements.roundrect(layer, win,
win.szone[0][0]+win.szone[1][0],
win.szone[0][1]+win.szone[1][1],
0,
0,
10)
UI_color.set(layer, win, "progress_background")
UI_elements.roundrect(layer, win,
win.szone[0][0]+win.szone[1][0],
win.szone[0][1]+win.szone[1][1],
0,
0,
10,
fill=False)
layer.stroke()
elif win.current["tool"] == "scale":
UI_color.set(layer, win, "node_badfile")
UI_elements.roundrect(layer, win,
win.current["mx"]-10,
win.current["my"]-10,
0,
0,
10)
UI_color.set(layer, win, "progress_background")
UI_elements.roundrect(layer, win,
win.current["mx"]-10,
win.current["my"]-10,
0,
0,
10,
fill=False)
layer.stroke()
if int(win.current["mx"]) in range(int(win.szone[0][0]+win.szone[1][0]), int(win.szone[0][0]+win.szone[1][0]+20))\
and int(win.current["my"]) in range(int(win.szone[0][1]+win.szone[1][1]), int(win.szone[0][1]+win.szone[1][1]+20))\
and win.current["tool"] == "selection":
UI_color.set(layer, win, "text_normal")
UI_elements.roundrect(layer, win,
win.szone[0][0]+win.szone[1][0],
win.szone[0][1]+win.szone[1][1],
0,
0,
10,
fill=False)
layer.stroke()
if win.current["LMB"] and not win.previous["LMB"]:
win.current["tool"] = "scale"
if win.current["tool"] == "scale" and not win.current["LMB"]:
win.current["tool"] = "selection"
# Canceling seletion. I move it here so it would not interfire with the
# the rest of the program.
if win.current["LMB"] and win.current["tool"] == "selection" and win.url == "story_editor":
# Undo selection
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["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"]:
win.story["selected"] = []
win.textactive = ""
# Let's draw the line while connecting 2 scenes together.
if win.current["tool"] == "connect":
if not win.current["LMB"]:
win.current["tool"] = "selection"
fr = win.current["draw_dot"]
if type(fr) == list:
fr = fr[0]+":"+fr[1]
try:
UI_color.set(layer, win, "node_script")
layer.move_to(
win.out_dots[fr][0],
win.out_dots[fr][1]
)
layer.line_to(win.current["mx"], win.current["my"])
layer.stroke()
except:
pass
########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
fif = datetime.datetime.now()
mil = fif - stf
perfStat.append([ "Selection", mil.microseconds ])
stf = datetime.datetime.now()
###################################################################
# The undo history is quite a new adition so the limit setting might
# not exists. So let's make it if so.
if "Undo_Limit" not in win.settings:
win.settings["Undo_Limit"] = 32
settings.write("Undo_Limit", 32)
if win.animations["cameraX"][1] == cx:
win.current["camera_arrived"] = True
else:
win.current["camera_arrived"] = False
# Save story. I'm going to do it the same way as in the old Blender-Organizer
if win.url == "story_editor":
savenow = False
if win.previous["LMB"] and not win.current["LMB"]:
savenow = True
elif win.previous["RMB"] and not win.current["RMB"]:
savenow = True
elif win.previous["MMB"] and not win.current["MMB"]:
savenow = True
elif win.previous["keys"] and not win.current["keys"]:
savenow = True
elif win.current["camera_arrived"] and not win.previous["camera_arrived"]:
savenow = True
if savenow:
# Now let's run the history record.
story.undo_record(win)
story.save(win.project, win.story)
analytics.save(win.project, win.analytics)
# Need to reload the story to reload the fractions of the scenes.
win.story = story.load(win.project)
# Multiuser sycning
win.multiuser["request"] = "story"
########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
fif = datetime.datetime.now()
mil = fif - stf
perfStat.append([ "File Saving", mil.microseconds ])
stf = datetime.datetime.now()
###################################################################
# To selected
if 65454 in win.current["keys"] and win.story["selected"] and not win.textactive:
nex = cx-win.szone[0][0] - win.szone[1][0]/2 + win.current["w"]/2
ney = cy-win.szone[0][1] - win.szone[1][1]/2 + win.current["h"]/2
UI_elements.animate("cameraX", win, win.story["camera"][0],nex, force=True)
UI_elements.animate("cameraY", win, win.story["camera"][1],ney, force=True)
# Undo
if 65507 in win.current["keys"] and 122 in win.current["keys"] and not win.textactive:
story.undo(win)
win.current["keys"] = []
# Redo
if 65507 in win.current["keys"] and 121 in win.current["keys"] and not win.textactive:
story.redo(win)
win.current["keys"] = []
# Grab
if 103 in win.current["keys"] and win.story["selected"] and not win.textactive:
win.current["tool"] = "grab"
win.current["LMB"] = [win.current["mx"], win.current["my"], True]
# Scale
if 115 in win.current["keys"] and win.story["selected"] and not win.textactive:
win.current["tool"] = "scale"
win.current["LMB"] = [win.current["mx"], win.current["my"], True]
# Deletion
if 65535 in win.current["keys"] and win.current["tool"] == "selection"\
and win.url == "story_editor" and win.story["selected"] and not win.textactive:
win.url = "story_deletion_dialog"
########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
fif = datetime.datetime.now()
mil = fif - stf
perfStat.append([ "Short Cuts", mil.microseconds ])
stf = datetime.datetime.now()
###################################################################
############### PERFORMCE TESTING GROUND ##############
if win.current["testing"]:
h = win.current["h"]+200
w = win.current["w"]
UI_color.set(layer, win, "darker_parts")
UI_elements.roundrect(layer, win,100, h-(len(perfStat)*15)-30-300, 500,len(perfStat)*15+30, 10)
l = 0
s = 0
for i in perfStat:
if int(i[1]) > l:
l = int(i[1])
s = s + int(i[1])
for n, i in enumerate(perfStat):
#UI_color.set(layer, win, "progress_background")
#UI_elements.roundrect(layer, win, 110 + 270, h-(len(perfStat)*15)-20+10+15*n-300, 200,10, 5)
layer.set_source_rgb(1,1,1)
if int(i[1]) == l:
layer.set_source_rgb(1,0,0)
elif int(i[1]) < 1000:
layer.set_source_rgb(0,1,0)
layer.set_font_size(10)
layer.move_to( 110, h-(len(perfStat)*15)+15*n-300)
p = float(i[1]) / s *100
layer.show_text(str(i[0])+" - "+str(i[1])+" MCRS "+str(int(round(p)))+"%")
#UI_color.set(layer, win, "progress_active")
UI_elements.roundrect(layer, win, 110 + 270, h-(len(perfStat)*15)-20+10+15*n-300, int(round(p))*2,10, 5)
return surface