From 758c8d649597ade0e1d10b585f60c1904d9f3c9c Mon Sep 17 00:00:00 2001
From: "Jeison Yehuda Amihud (Blender Dumbass)" <blenderdumbass@gmail.com>
Date: Thu, 10 Dec 2020 22:08:22 +0000
Subject: [PATCH] Upload files to 'studio'

---
 studio/analytics.py            |  58 ++-
 studio/studio_assetLayer.py    | 672 +++++++++++++++++++++++++++++++++
 studio/studio_gtk.py           |  11 +-
 studio/studio_nodes.py         | 316 ++++++++++------
 studio/studio_settingsLayer.py | 511 +++++++++++++++++++++++++
 studio/studio_storyLayer.py    | 198 +++++++++-
 6 files changed, 1624 insertions(+), 142 deletions(-)
 create mode 100644 studio/studio_assetLayer.py
 create mode 100644 studio/studio_settingsLayer.py

diff --git a/studio/analytics.py b/studio/analytics.py
index 6229446..f29734d 100644
--- a/studio/analytics.py
+++ b/studio/analytics.py
@@ -12,6 +12,17 @@ from studio import story
 from settings import settings
 from settings import talk
 
+
+def ifdate(string):
+    new_date_format = "%Y/%m/%d"
+    try:
+        datetime.datetime.strptime(string, new_date_format)
+        ret = True
+    except:
+        ret = False
+    
+    return ret
+
 def get_legacy(project_location):
     
     # This function will return analytics data about a project. This particular
@@ -166,14 +177,19 @@ def get_legacy(project_location):
     startdate = datetime.datetime.today()
     deadline  = datetime.datetime.today()
     
-    for line in projectdata:
-        if line.startswith("STR"):
-            startdate = datetime.datetime.strptime(line[4:], old_date_format)
-            data["startdate"] = datetime.datetime.strftime(startdate, new_date_format)
-        
-        elif line.startswith("FIN"):
-            deadline = datetime.datetime.strptime(line[4:], old_date_format)
-            data["deadline"] = datetime.datetime.strftime(deadline, new_date_format)
+    try:
+        for line in projectdata:
+            if line.startswith("STR"):
+                startdate = datetime.datetime.strptime(line[4:], old_date_format)
+                data["startdate"] = datetime.datetime.strftime(startdate, new_date_format)
+            
+            elif line.startswith("FIN"):
+                deadline = datetime.datetime.strptime(line[4:], old_date_format)
+                data["deadline"] = datetime.datetime.strftime(deadline, new_date_format)
+    except:
+    
+        data["startdate"] = datetime.datetime.strftime(datetime.datetime.today(), new_date_format)
+        data["deadline"]  = datetime.datetime.strftime(datetime.datetime.today()+datetime.timedelta(days=30), new_date_format)
     
     # So we've go the dates. Let's calculate time perventage I guess.
     delta = deadline - startdate
@@ -677,6 +693,30 @@ def load(project_location):
         make.write("[ ] Rendering")
         make.close()
     
+    # Let's see if dates are fine. Or if they are even dates.
+    
+    new_date_format = "%Y/%m/%d"
+    if not ifdate(data["startdate"]) or not ifdate(data["deadline"]):
+        data["startdate"] = datetime.datetime.strftime(datetime.datetime.today(), new_date_format)
+        data["deadline"]  = datetime.datetime.strftime(datetime.datetime.today()+datetime.timedelta(days=30), new_date_format)
+    
+    
+    
+    # So we've go the dates. Let's calculate time perventage I guess.
+    
+    startdate = datetime.datetime.strptime(data["startdate"], new_date_format)
+    deadline  = datetime.datetime.strptime(data["deadline"] , new_date_format)
+    
+    delta = deadline - startdate
+    data["duration"] = int(delta.days)
+    
+    delta = datetime.datetime.today() - startdate
+    data["dayspassed"] = int(delta.days)
+    
+    data["timepassed"] = data["dayspassed"] / data["duration"]
+    if data["timepassed"] > 1.0:
+        data["timepassed"] = 1.0
+    
     # NEXT THING. As I love to type it into place where people read me while I'm
     # working. We've got data from 2 files. Now we need to get data from ALL the
     # project. 
@@ -734,4 +774,4 @@ def load(project_location):
     
     
     return data
-    
+
diff --git a/studio/studio_assetLayer.py b/studio/studio_assetLayer.py
new file mode 100644
index 0000000..eb99bc6
--- /dev/null
+++ b/studio/studio_assetLayer.py
@@ -0,0 +1,672 @@
+# THIS FILE IS A PART OF VCStudio
+# PYTHON 3
+
+# This a console project manager.
+
+import os
+
+# GTK module ( Graphical interface
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
+from gi.repository import GLib
+from gi.repository import Gdk
+import cairo
+
+# Own modules
+from settings import settings
+from settings import talk
+from settings import fileformats
+from settings import oscalls
+from project_manager import pm_project
+
+#UI modules
+from UI import UI_elements
+from UI import UI_color
+
+# story
+from studio import story
+from studio import analytics
+from studio import studio_dialogs
+
+def layer(win):
+    
+    # Making the layer
+    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, win.current['w'],
+                                                      win.current['h'])
+    layer = cairo.Context(surface)
+    
+    
+    #text setting
+    layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
+    
+    UI_color.set(layer, win, "dark_overdrop")
+    layer.rectangle(
+        0,
+        0,
+        win.current["w"],
+        win.current["h"],
+        )
+    layer.fill()
+    
+    
+    
+    UI_color.set(layer, win, "node_background")
+    UI_elements.roundrect(layer, win, 
+        win.current["w"]/4,
+        150,
+        win.current["w"]/2,
+        win.current["h"]-190,
+        10)
+    
+    ############################################################################
+    
+    # This file will be showing stuff about an asset. It's almost like a folder
+    # / folders of the asset. But with some extendet functionality. Stuff that
+    # will be on screen will include.
+    
+    # Progress Bar
+    # Checklist
+    # Scenes list in which the asset is mentioned
+    # History / Schedules 
+    
+    # It's similar to the old Blender Organizer's Asset thing. But a bit more
+    # modern looking. I would say.
+    
+    ############################################################################
+    
+    if not "asset_cur_folder" in win.current:
+        win.current["asset_cur_folder"] = "blender"
+    
+    ####### MIDDLE PANNEL #######
+    
+    
+    def do():
+        oscalls.Open(win.project+"/dev"+win.cur)
+        
+    UI_elements.roundrect(layer, win,
+        win.current["w"]/4+20,
+        350, 
+        40,
+        40,
+        10,
+        do,
+        "folder")
+    
+    folds = {
+        "blender":"blend_files_folder",
+        "idea":"reference_folder",
+        "texture":"tex_folder",
+        "render":"renders_folder"
+        }
+    
+    for num, cur in enumerate(folds):
+        
+        if win.current["asset_cur_folder"] == cur:
+            
+            UI_color.set(layer, win, "progress_time")
+            UI_elements.roundrect(layer, win,
+                win.current["w"]/4+150+(40*num),
+                350, 
+                40,
+                40,
+                10)
+        
+        def do():
+            win.current["asset_cur_folder"] = cur
+        
+        UI_elements.roundrect(layer, win,
+            win.current["w"]/4+150+(40*num),
+            350, 
+            40,
+            40,
+            10,
+            do,
+            cur,
+            tip=talk.text(folds[cur]))
+    
+    
+    # Parsing the cur to get name and type 
+    name = win.cur[win.cur.rfind("/")+1:]
+    acur = win.cur.replace(name, "").replace("/", "")
+    
+    # Preview 
+    
+    # Making the layer
+    nodesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 300, 300)
+    node = cairo.Context(nodesurface)
+    node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
+    
+    
+    UI_elements.roundrect(node, win, 
+        0,
+        0,
+        300,
+        300,
+        10,
+        fill=False)
+    
+    node.clip()
+    
+    if os.path.exists(win.project+"/dev"+win.cur+"/renders/Preview.png"):
+        UI_elements.image(node, win, 
+            win.project+"/dev"+win.cur+"/renders/Preview.png",
+            0, 0, 300, 300, cell="big_asset_previews")
+    elif os.path.exists(win.project+"/dev"+win.cur+"/renders/Preview.jpg"):
+        UI_elements.image(node, win, 
+            win.project+"/dev"+win.cur+"/renders/Preview.jpg",
+            0, 0, 300, 300, cell="big_asset_previews")
+    else:
+        UI_color.set(node, win, "dark_overdrop")
+        node.rectangle(0,0,300, 300)
+        node.fill()
+        
+        UI_elements.image(node, win, 
+            "settings/themes/"+win.settings["Theme"]+"/icons/"+acur+".png",
+            130, 130, 40, 40)
+    
+    # Outputting the layer
+    layer.set_source_surface(nodesurface, 
+            win.current["w"]/4+20,
+            20)
+    layer.paint()
+    
+    
+    
+    # Name of the asset
+    UI_elements.image(layer, win, 
+        "settings/themes/"+win.settings["Theme"]+"/icons/"+acur+".png",
+        win.current["w"]/4+360, 210, 40, 40)
+    UI_color.set(layer, win, "text_normal")
+    layer.set_font_size(30)
+    layer.move_to(win.current["w"]/4+410,240)
+    layer.show_text(name)
+    
+    # Fraction
+                
+    fraction = story.get_asset_data(win, win.cur)["fraction"]
+    
+    UI_color.set(layer, win, "progress_background")
+    UI_elements.roundrect(layer, win,
+        win.current["w"]/4+350,
+        270, 
+        (win.current["w"]/2-370),
+        0,
+        10)
+    
+    UI_color.set(layer, win, "progress_active")
+    UI_elements.roundrect(layer, win,
+        win.current["w"]/4+350,
+        270, 
+        (win.current["w"]/2-370)*fraction,
+        0,
+        10)
+    
+    # Search
+    
+    UI_elements.image(layer, win, "settings/themes/"\
+        +win.settings["Theme"]+"/icons/search.png", 
+        win.current["w"]-280-win.current["w"]/4,
+        350, 
+        40,
+        40)
+    
+    UI_elements.text(layer, win, "in_asset",
+        win.current["w"]-240-win.current["w"]/4,
+        350,
+        220,
+        40)
+    
+    # FILES
+    
+    # In case the user made the folder manually. 
+    try:
+        os.mkdir(win.project+"/dev/"+win.cur+"/renders")
+        os.mkdir(win.project+"/dev/"+win.cur+"/reference")
+        os.mkdir(win.project+"/dev/"+win.cur+"/tex")
+    except:
+        pass
+    
+    # Now let's prepare the frame
+    
+    width = win.current["w"]/2- 40
+    height = win.current["h"] - 500
+    
+    # Making the layer
+    nodesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
+    node = cairo.Context(nodesurface)
+    node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
+    
+    UI_elements.roundrect(node, win, 
+        0,
+        0,
+        width, 
+        height,
+        10,
+        fill=False)
+    
+    node.clip()
+    
+    
+    # Now let's prepare the scrooler
+    
+    tileX = 20
+    current_Y = 10
+    
+    if "assets" not in win.scroll:
+        win.scroll["assets"] = 0
+    
+    ###########################
+    
+    # Let's get the list of the files first.
+    
+    files = []
+    newcreate = win.text["in_asset"]["text"].replace("/","_").replace(" ", "_")\
+    .replace('"',"_").replace("(","_").replace(")","_").replace("'","_")\
+    .replace("[","_").replace("]","_").replace("{","_").replace("}","_")
+    
+    foundblend = True
+    found_in = False
+    
+    if win.current["asset_cur_folder"] == "blender":
+        
+        foundblend = False
+        
+        # Let's see if an asset blend file exists.
+        if os.path.exists(win.project+"/ast"+win.cur+".blend") and not newcreate:
+            files.append(["/ast"+win.cur+".blend", "node_asset"])
+            foundblend = True
+        for f in os.listdir(win.project+"/dev"+win.cur):
+            if not os.path.isdir(win.project+"/dev"+win.cur+"/"+f):
+            
+            # This is for only the blend files. So let's filter the out of all
+            # the noise. For all files there is a folder icon.
+                if newcreate == f:
+                    found_in = True
+                
+                if newcreate and newcreate.lower() not in f.lower():
+                    continue
+            
+                if f.endswith(".blend"):
+                    files.append(["/dev"+win.cur+"/"+f, "node_blendfile"])
+                    foundblend = True
+    
+    else:
+        
+        # This all the rest of the files.
+        
+        if win.current["asset_cur_folder"] == "idea":
+            fl = "reference"
+        elif win.current["asset_cur_folder"] == "texture":
+            fl = "tex"
+        elif win.current["asset_cur_folder"] == "render":
+            fl = "renders"
+        
+        for f in os.listdir(win.project+"/dev"+win.cur+"/"+fl):
+            if not os.path.isdir(win.project+"/dev"+win.cur+"/"+fl+"/"+f):
+                
+                if newcreate == f:
+                    found_in = True
+                
+                if newcreate and newcreate.lower() not in f.lower():
+                    continue
+                
+                # Now it has to be image or video files. For the rest you have 
+                # the folder icon.
+                
+                for t in fileformats.images:
+                    if f.endswith(t):
+                        files.append(["/dev"+win.cur+"/"+fl+"/"+f, "node_imagefile"])
+                
+                for t in fileformats.videos:
+                    if f.endswith(t):
+                        files.append(["/dev"+win.cur+"/"+fl+"/"+f, "node_videofile"])
+    
+    
+    # Let's make sure that we have at least some blendfile there.
+    if not foundblend and not newcreate:
+        oscalls.copy_file(
+            win,
+            os.getcwd()+"/new_file/"+acur+".blend",
+            "/dev"+win.cur+"/",
+            name+".blend")
+    
+    
+    
+    if "asset_file_selected" not in win.current:
+        win.current["asset_file_selected"] = ""
+    
+    for filename, thecoloris in files:
+        
+        
+        if int(current_Y + win.scroll["assets"]) in range(0-200, height):
+                    
+            # Making the layer
+            node2surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 170, 200)
+            node2 = cairo.Context(node2surface)
+            node2.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
+            
+            
+            UI_elements.roundrect(node2, win, 
+                0,
+                0,
+                170,
+                200,
+                10,
+                fill=False)
+            
+            node2.clip()
+            
+            # Background
+            UI_color.set(node2, win, "dark_overdrop")
+            node2.rectangle(0,0,170, 200)
+            node2.fill()
+            
+            # Banner
+            UI_color.set(node2, win, thecoloris) 
+            node2.rectangle(0,0,170, 20)
+            node2.fill()
+            
+            # Outputting the layer
+            node.set_source_surface(node2surface, 
+                    tileX-10,
+                    current_Y + win.scroll["assets"] )
+            node.paint()
+            
+            UI_elements.image(node, win, win.project+filename, 
+                tileX,
+                current_Y + win.scroll["assets"] + 30, 
+                150,
+                150)
+            
+            UI_color.set(node, win, "text_normal")
+            node.set_font_size(12)
+            node.move_to(tileX,
+                    current_Y + win.scroll["assets"]+15)
+            node.show_text(filename[filename.rfind("/")+1:][:22])
+            
+            # If selected
+            node.set_line_width(4)
+            if win.current["asset_file_selected"] == win.project+filename:
+                UI_color.set(node, win, "progress_background")
+                UI_elements.roundrect(node, win, 
+                    tileX-10,
+                    current_Y + win.scroll["assets"],
+                    170,
+                    200,
+                    10,
+                    fill=False)
+                node.stroke()
+                
+            # Button to activate it
+            def do():
+                if win.current["asset_file_selected"] != win.project+filename:
+                    win.current["asset_file_selected"] = win.project+filename
+                else:
+                    oscalls.file_open(win, win.project+filename)
+            
+                
+            UI_elements.roundrect(node, win, 
+                tileX-10,
+                current_Y + win.scroll["assets"],
+                170,
+                200,
+                10,
+                button=do,
+                tip=filename,
+                fill=False,
+                clip=[
+                    win.current["w"]/4+20,
+                    400,
+                    width, 
+                    height,
+                    ],
+                offset=[
+                    win.current["w"]/4+20,
+                    400])
+            
+            node.stroke()
+            node.set_line_width(2) 
+            
+        tileX += 200
+            
+        if tileX > width-180:
+            tileX = 20
+            current_Y += 230
+            
+    ###########################
+    
+    # Now i'd like to make things addable. For now if it's a blends selected
+    # there will an option to add new one and an option to copy. While other
+    # files will have an option of only copy. (At least for now. Untill I 
+    # figure out what new images will it give.)
+    
+    if not found_in and newcreate:
+        
+        if win.current["asset_cur_folder"] == "blender"\
+        and not newcreate.endswith(".blend"):
+            newcreate = newcreate+".blend"
+        
+        def do():
+            def after(win, var):
+                
+                newcreate = win.text["in_asset"]["text"].replace("/","_").replace(" ", "_")\
+                .replace('"',"_").replace("(","_").replace(")","_").replace("'","_")\
+                .replace("[","_").replace("]","_").replace("{","_").replace("}","_")
+                
+                win.text["in_asset"]["text"] = ""
+                win.current["asset_file_selected"] = ""
+                win.images = {}
+                
+                if var:
+                    if win.current["asset_cur_folder"] == "blender"\
+                    and var.endswith(".blend"):
+                        
+                        if not newcreate.endswith(".blend"):
+                            newcreate = newcreate+".blend"
+                        
+                        oscalls.copy_file(
+                            win,
+                            var,
+                            "/dev"+win.cur+"/",
+                            newcreate)
+                    
+                    else:
+                        
+                        # In case the copying file is not a blend file. Let's
+                        # make sure that it's infect an image.
+                        
+                        for t in fileformats.images:
+                            if var.endswith(t):
+                                
+                                if not newcreate.endswith(t):
+                                    newcreate = newcreate + "." + t
+                                
+                                if win.current["asset_cur_folder"] == "idea":
+                                    fl = "reference"
+                                elif win.current["asset_cur_folder"] == "texture":
+                                    fl = "tex"
+                                elif win.current["asset_cur_folder"] == "render":
+                                    fl = "renders"
+                                
+                                oscalls.copy_file(
+                                    win,
+                                    var,
+                                    "/dev"+win.cur+"/"+fl+"/",
+                                    newcreate)
+                                
+                                break
+                        
+            if win.current["asset_cur_folder"] == "blender":    
+                studio_dialogs.file_select(win, name+"_blends", after, force=True, 
+                    IMAGE=False, BLEND=True, VIDEO=False, FILE=False, CHR=True, VEH=True, 
+                    LOC=True, OBJ=True, RND=False, FOLDER=False)
+            
+            elif win.current["asset_cur_folder"] == "idea":
+                studio_dialogs.file_select(win, name+"_reference", after, force=True, 
+                    IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, 
+                    LOC=True, OBJ=True, RND=False, FOLDER=False,  SEARCH="reference")
+            
+            elif win.current["asset_cur_folder"] == "texture":
+                studio_dialogs.file_select(win, name+"_reference", after, force=True, 
+                    IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, 
+                    LOC=True, OBJ=True, RND=False, FOLDER=False,  SEARCH="tex")
+            
+            elif win.current["asset_cur_folder"] == "render":
+                studio_dialogs.file_select(win, name+"_reference", after, force=True, 
+                    IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, 
+                    LOC=True, OBJ=True, RND=False, FOLDER=False,  SEARCH="renders")
+            
+            
+            
+        UI_elements.roundrect(node, win, 
+            tileX-10,
+            current_Y + win.scroll["assets"],
+            170,
+            200,
+            10,
+            button=do,
+            tip=talk.text("copy_file_as")+" "+newcreate,
+            clip=[
+                win.current["w"]/4+20,
+                400,
+                width, 
+                height,
+                ],
+            offset=[
+                win.current["w"]/4+20,
+                400])
+        
+        UI_color.set(node, win, "progress_background")
+        UI_elements.roundrect(node, win, 
+            tileX-10,
+            current_Y + win.scroll["assets"],
+            170,
+            200,
+            10,
+            fill=False)
+        node.stroke()
+        
+        UI_elements.image(node, win, 
+            "settings/themes/"+win.settings["Theme"]+"/icons/copy_file.png",
+            tileX+55,
+            current_Y + win.scroll["assets"] + 70,
+            40, 40)
+        
+        UI_color.set(node, win, "text_normal")
+        node.set_font_size(12)
+        node.move_to(tileX+75-len(newcreate)*4,
+            current_Y + win.scroll["assets"]+150)
+        node.show_text(newcreate)
+    
+        
+        tileX += 200
+            
+        if tileX > width-180:
+            tileX = 20
+            current_Y += 230
+    
+    if not found_in and newcreate and win.current["asset_cur_folder"] == "blender":
+        
+        if not newcreate.endswith(".blend"):
+            newcreate = newcreate+".blend"
+        
+        def do():
+            
+            oscalls.copy_file(
+                win,
+                os.getcwd()+"/new_file/"+acur+".blend",
+                "/dev"+win.cur+"/",
+                newcreate)
+            
+            win.text["in_asset"]["text"] = ""
+            win.current["asset_file_selected"] = ""
+            win.images = {}
+            
+        UI_elements.roundrect(node, win, 
+            tileX-10,
+            current_Y + win.scroll["assets"],
+            170,
+            200,
+            10,
+            button=do,
+            tip=talk.text("create_new_blend_file")+" "+newcreate,
+            clip=[
+                win.current["w"]/4+20,
+                400,
+                width, 
+                height,
+                ],
+            offset=[
+                win.current["w"]/4+20,
+                400])
+        
+        UI_color.set(node, win, "progress_background")
+        UI_elements.roundrect(node, win, 
+            tileX-10,
+            current_Y + win.scroll["assets"],
+            170,
+            200,
+            10,
+            fill=False)
+        node.stroke()
+        
+        UI_elements.image(node, win, 
+            "settings/themes/"+win.settings["Theme"]+"/icons/new_file.png",
+            tileX+55,
+            current_Y + win.scroll["assets"] + 70,
+            40, 40)
+        
+        UI_color.set(node, win, "text_normal")
+        node.set_font_size(12)
+        node.move_to(tileX+75-len(newcreate)*4,
+            current_Y + win.scroll["assets"]+150)
+        node.show_text(newcreate)
+    
+    
+    current_Y += 230
+    
+    UI_elements.scroll_area(layer, win, "assets", 
+        win.current["w"]/4+20,
+        400,
+        width, 
+        height,
+        current_Y,
+        bar=True,
+        mmb=True,
+        url="assets")
+    
+    # Outputting the layer
+    layer.set_source_surface(nodesurface, 
+            win.current["w"]/4+20,
+            400)
+    layer.paint()
+    
+    # CANCEl
+    
+    def do():
+        win.url = "story_editor"
+        win.assets = {}
+        win.current["asset_file_selected"] = ""
+        
+    UI_elements.roundrect(layer, win, 
+        win.current["w"]-40-win.current["w"]/4,
+        win.current["h"]-80,
+        40,
+        40,
+        10,
+        button=do,
+        icon="cancel",
+        tip=talk.text("cancel"))
+    
+    # Short cut ESC
+    if 65307 in win.current["keys"] and not win.textactive:
+        do()    
+    
+    
+    
+    
+    
+    
+    
+    return surface
diff --git a/studio/studio_gtk.py b/studio/studio_gtk.py
index 4d8504f..c1926d7 100644
--- a/studio/studio_gtk.py
+++ b/studio/studio_gtk.py
@@ -16,6 +16,8 @@ from settings import settings
 from settings import talk
 from project_manager import pm_project
 from studio import studio_storyLayer
+from studio import studio_settingsLayer
+from studio import studio_assetLayer
 
 # Studio
 from studio import analytics
@@ -75,6 +77,7 @@ def run(project, win):
     win.scroll     = {}
     win.FPS        = 0
     win.url        = "story_editor"
+    win.cur        = ""  # This will be used to get precicelly what asset / scene / shot we are in
     win.update     = {"versions":{}}
     win.project    = project
     win.out_dots  = {}
@@ -235,6 +238,12 @@ def pmdrawing(pmdrawing, main_layer, win):
             
     if win.url == "story_deletion_dialog":
         Layers.append([studio_storyDeletionLayer.layer(win),"story_deletion_dialog"])    
+    
+    elif win.url == "settings_layer":
+        Layers.append([studio_settingsLayer.layer(win),"settings_layer"])  
+    
+    elif win.url == "assets":
+        Layers.append([studio_assetLayer.layer(win),"assets"])  
         
     
     # Call layers. See studio/studio_dialogs.py for explanation. It's wild.
@@ -250,8 +259,8 @@ def pmdrawing(pmdrawing, main_layer, win):
             win.calllayer = True    
             
         else:
-            win.current["calls"][call]["call"](win, win.current["calls"][call]["var"])
             win.url = win.current["calls"][call]["back"]
+            win.current["calls"][call]["call"](win, win.current["calls"][call]["var"])
             win.textactive = ""
             remlater.append(call)
     
diff --git a/studio/studio_nodes.py b/studio/studio_nodes.py
index 4691dac..b17e418 100644
--- a/studio/studio_nodes.py
+++ b/studio/studio_nodes.py
@@ -105,7 +105,7 @@ def node_dot(layer, win, x, y, direction="in", entry="end"):
             
             # Connecting the scenes together
             
-            if raw_entry[0] != "file" and win.current["draw_dot"][0] != "file":
+            if raw_entry[0] not in ["file", "blend"] and win.current["draw_dot"][0] not in ["file", "blend"]:
                 
                 new_arrow = [
                     win.current["draw_dot"],
@@ -115,7 +115,50 @@ def node_dot(layer, win, x, y, direction="in", entry="end"):
                 if new_arrow not in win.story["arrows"]:
                     win.story["arrows"].append(new_arrow)
             
+            # Copying images to places
             
+            elif raw_entry[0] == "asset" and win.current["draw_dot"][0] == "file":
+                
+                new = oscalls.copy_file(
+                    win,
+                    win.current["draw_dot"][1],
+                    "dev"+raw_entry[1])                
+                
+                
+                win.story["links"].append([
+                    "file", new, [
+                        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]
+                
+            elif raw_entry[0] == "blend" and win.current["draw_dot"][0] == "blend":
+                
+                new = oscalls.copy_file(
+                    win,
+                    win.current["draw_dot"][1],
+                    "dev"+raw_entry[1])                
+                
+                
+                win.story["links"].append([
+                    "file", new, [
+                        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]
+                
             UI_math.filter_arrows(win)
             
             # Refrashing analytics
@@ -675,6 +718,7 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
                     
                     elif int(win.current["mx"]) > x+40: # This is a hack. But whatever.
                         win.url = "assets"
+                        win.cur = name
                     
             if win.current["LMB"] and win.current["tool"] == "selection":
                 
@@ -848,139 +892,169 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
             if os.path.exists(win.project+"/dev"+name+"/renders/Preview.png"):
                 UI_elements.image(layer, win, 
                     win.project+"/dev"+name+"/renders/Preview.png",
-                    40, 30, 150, 150)
+                    0, 0, width, height, cell="story_asset_previews")
             elif os.path.exists(win.project+"/dev"+name+"/renders/Preview.jpg"):
                 UI_elements.image(layer, win, 
                     win.project+"/dev"+name+"/renders/Preview.jpg",
-                    40, 30, 150, 150)
+                    0, 0, width, height, cell="story_asset_previews")
             
             else:
                 UI_elements.image(layer, win, 
                     "settings/themes/"+win.settings["Theme"]+"/icons/"+assettype+".png",
-                    width/2, height/2-20, 40, 40)
+                    width/2-20, height/2-20, 40, 40)
             
             # Here I want to add some buttons for accessing the various folder of
             # the asset. And also to link stuff into those folders using nodes.
             
-            # Darkening thing.
-            UI_color.set(layer, win, "dark_overdrop")
-            layer.rectangle(0,0,50, height)
-            layer.fill()
-            
-            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
-                        ]
-                        ])
+            if int(win.current["mx"]) in range(int(x), int(x+width))\
+            and  int(win.current["my"]) in range(int(y), int(y+height)):
+                
+                # Darkening thing.
+                UI_color.set(layer, win, "dark_overdrop")
+                layer.rectangle(0,0,50, height)
+                layer.fill()
+                
+                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
+                            ],
+                            ""
+                            ])
+                        
+                        # 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]
+                
                     
-                    # 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]
             
                 
-        
-            
-            # Blendfiles
-            def do():
-                studio_dialogs.file_select(win, name+"_blends", after, force=True, 
-                    IMAGE=False, BLEND=True, VIDEO=False, FILE=False, CHR=True, VEH=True, 
-                    LOC=True, OBJ=True, RND=False, FOLDER=False,  SEARCH=name)
-            
-            UI_elements.roundrect(layer, win,
-                5,
-                25, 
-                40,
-                40,
-                10,
-                do,
-                "blender",
-                talk.text("blend_files_folder"),
-                url="story_editor",
-                offset=[x,y])
-            
-            
-            
-            # References
-            def do():
-                studio_dialogs.file_select(win, name+"_reference", after, force=True, 
-                    IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, 
-                    LOC=True, OBJ=True, RND=False, FOLDER=False,  SEARCH=name+"/reference")
-            
-            UI_elements.roundrect(layer, win,
-                5,
-                75, 
-                40,
-                40,
-                10,
-                do,
-                "idea",
-                talk.text("reference_folder"),
-                url="story_editor",
-                offset=[x,y])
-            
-            # Textures
-            def do():
-                studio_dialogs.file_select(win, name+"_textures", after, force=True, 
-                    IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, 
-                    LOC=True, OBJ=True, RND=False, FOLDER=False,  SEARCH=name+"/tex")
-            
-            UI_elements.roundrect(layer, win,
-                5,
-                125, 
-                40,
-                40,
-                10,
-                do,
-                "texture",
-                talk.text("tex_folder"),
-                url="story_editor",
-                offset=[x,y])
-            
-            # Renders
-            def do():
-                studio_dialogs.file_select(win, name+"_renders", after, force=True, 
-                    IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, 
-                    LOC=True, OBJ=True, RND=False, FOLDER=False,  SEARCH=name+"/renders")
-            
-            UI_elements.roundrect(layer, win,
-                5,
-                175, 
-                40,
-                40,
-                10,
-                do,
-                "render",
-                talk.text("renders_folder"),
-                url="story_editor",
-                offset=[x,y])
-            
-            # Fraction
-            
-            fraction = story.get_asset_data(win, name)["fraction"]
-            
-            UI_color.set(layer, win, "progress_background")
-            UI_elements.roundrect(layer, win,
-                65,
-                height-20, 
-                width-85,
-                0,
-                5)
-            
-            UI_color.set(layer, win, "progress_active")
-            UI_elements.roundrect(layer, win,
-                65,
-                height-20, 
-                (width-85)*fraction,
-                0,
-                5)
+                # Blendfiles
+                def do():
+                    studio_dialogs.file_select(win, name+"_blends", after, force=True, 
+                        IMAGE=False, BLEND=True, VIDEO=False, FILE=False, CHR=True, VEH=True, 
+                        LOC=True, OBJ=True, RND=False, FOLDER=False,  SEARCH=name)
+                
+                UI_elements.roundrect(layer, win,
+                    5,
+                    25, 
+                    40,
+                    40,
+                    10,
+                    do,
+                    "blender",
+                    talk.text("blend_files_folder"),
+                    url="story_editor",
+                    offset=[x,y])
+                
+                
+                
+                # References
+                def do():
+                    studio_dialogs.file_select(win, name+"_reference", after, force=True, 
+                        IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, 
+                        LOC=True, OBJ=True, RND=False, FOLDER=False,  SEARCH=name+"/reference")
+                
+                UI_elements.roundrect(layer, win,
+                    5,
+                    75, 
+                    40,
+                    40,
+                    10,
+                    do,
+                    "idea",
+                    talk.text("reference_folder"),
+                    url="story_editor",
+                    offset=[x,y])
+                
+                # Textures
+                def do():
+                    studio_dialogs.file_select(win, name+"_textures", after, force=True, 
+                        IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, 
+                        LOC=True, OBJ=True, RND=False, FOLDER=False,  SEARCH=name+"/tex")
+                
+                UI_elements.roundrect(layer, win,
+                    5,
+                    125, 
+                    40,
+                    40,
+                    10,
+                    do,
+                    "texture",
+                    talk.text("tex_folder"),
+                    url="story_editor",
+                    offset=[x,y])
+                
+                # Renders
+                def do():
+                    studio_dialogs.file_select(win, name+"_renders", after, force=True, 
+                        IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, 
+                        LOC=True, OBJ=True, RND=False, FOLDER=False,  SEARCH=name+"/renders")
+                
+                UI_elements.roundrect(layer, win,
+                    5,
+                    175, 
+                    40,
+                    40,
+                    10,
+                    do,
+                    "render",
+                    talk.text("renders_folder"),
+                    url="story_editor",
+                    offset=[x,y])
             
+                # Fraction
+                
+                fraction = story.get_asset_data(win, name)["fraction"]
+                
+                UI_color.set(layer, win, "progress_background")
+                UI_elements.roundrect(layer, win,
+                    65,
+                    height-20, 
+                    width-85,
+                    0,
+                    5)
+                
+                UI_color.set(layer, win, "progress_active")
+                UI_elements.roundrect(layer, win,
+                    65,
+                    height-20, 
+                    (width-85)*fraction,
+                    0,
+                    5)
+            else:
+                
+                # Fraction
+                
+                fraction = story.get_asset_data(win, name)["fraction"]
+                
+                UI_color.set(layer, win, "progress_background")
+                UI_elements.roundrect(layer, win,
+                    10,
+                    height-20, 
+                    width-20,
+                    0,
+                    5)
+                
+                UI_color.set(layer, win, "progress_active")
+                UI_elements.roundrect(layer, win,
+                    10,
+                    height-20, 
+                    (width-20)*fraction,
+                    0,
+                    5)
             
             UI_color.set(layer, win, "node_asset")    
             
+            # Tooltip
+            
+            if int(win.current["mx"]) in range(int(x+40), int(x+width))\
+            and  int(win.current["my"]) in range(int(y), int(y+height)):
+               UI_elements.tooltip(win, name)
+            
         else:
             if os.path.exists(win.project+"/"+name):
                 UI_elements.image(layer, win, 
@@ -1026,11 +1100,11 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
                 UI_color.set(layer, win, "node_script")
             
             
-        # Tooltip
-        
-        if int(win.current["mx"]) in range(int(x), int(x+width))\
-        and  int(win.current["my"]) in range(int(y), int(y+height)):
-           UI_elements.tooltip(win, name)
+            # Tooltip
+            
+            if int(win.current["mx"]) in range(int(x), int(x+width))\
+            and  int(win.current["my"]) in range(int(y), int(y+height)):
+               UI_elements.tooltip(win, name)
             
         # top banner
         
diff --git a/studio/studio_settingsLayer.py b/studio/studio_settingsLayer.py
new file mode 100644
index 0000000..393c3ff
--- /dev/null
+++ b/studio/studio_settingsLayer.py
@@ -0,0 +1,511 @@
+# THIS FILE IS A PART OF VCStudio
+# PYTHON 3
+
+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 project_manager import pm_project
+
+#UI modules
+from UI import UI_elements
+from UI import UI_color
+
+# Studio
+from studio import studio_dialogs
+from studio import analytics
+
+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"]/2-250,
+        100,
+        500,
+        win.current["h"]-200,
+        10)
+    
+    # Exit button
+    def do():
+        win.url = "story_editor" 
+        win.textactive = ""
+        
+        
+    UI_elements.roundrect(layer, win, 
+        win.current["w"]/2+210,
+        win.current["h"]-140,
+        40,
+        40,
+        10,
+        button=do,
+        icon="cancel",
+        tip=talk.text("cancel"))
+    
+      
+        
+    # Clipping everything
+    UI_elements.roundrect(layer, win, 
+        win.current["w"]/2-250,
+        100,
+        500,
+        win.current["h"]-260,
+        10,
+        fill=False)
+    layer.clip()
+    
+    clip = [
+        win.current["w"]/2-250,
+        100,
+        500,
+        win.current["h"]-260]
+    
+    # Setting up the scroll
+    if "studio_settings" not in win.scroll:
+        win.scroll["studio_settings"] = 0
+    
+    current_Y = 0 # The max scroll value
+    
+    # Projectname 
+    
+    UI_elements.image(layer, win, "settings/themes/"\
+        +win.settings["Theme"]+"/icons/analytics.png", 
+        win.current["w"]/2-240,
+        110 + current_Y + win.scroll["studio_settings"], 
+        40,
+        40)
+    
+    UI_elements.text(layer, win, "Project_Name_setting",
+        win.current["w"]/2-190,
+        110 + current_Y + win.scroll["studio_settings"],
+        420,
+        40,
+        set_text=win.analytics["name"],
+        tip=talk.text("project_name"))
+    
+    if win.text["Project_Name_setting"]["text"] != win.analytics["name"]:
+        def do():
+            win.analytics["name"] = win.text["Project_Name_setting"]["text"]
+            
+            
+        UI_elements.roundrect(layer, win, 
+            win.current["w"]/2-240+430,
+            110 + current_Y + win.scroll["studio_settings"],
+            40,
+            40,
+            10,
+            button=do,
+            icon="ok",
+            tip=talk.text("checked"))
+    
+    
+    current_Y += 50
+    
+    # Director 
+    
+    UI_elements.image(layer, win, "settings/themes/"\
+        +win.settings["Theme"]+"/icons/analytics.png", 
+        win.current["w"]/2-240,
+        110 + current_Y + win.scroll["studio_settings"], 
+        40,
+        40)
+    
+    UI_elements.text(layer, win, "Project_Director_setting",
+        win.current["w"]/2-190,
+        110 + current_Y + win.scroll["studio_settings"],
+        420,
+        40,
+        set_text=win.analytics["director"],
+        tip=talk.text("project_director"))
+    
+    if win.text["Project_Director_setting"]["text"] != win.analytics["director"]:
+        def do():
+            win.analytics["director"] = win.text["Project_Director_setting"]["text"]
+            
+            
+        UI_elements.roundrect(layer, win, 
+            win.current["w"]/2-240+430,
+            110 + current_Y + win.scroll["studio_settings"],
+            40,
+            40,
+            10,
+            button=do,
+            icon="ok",
+            tip=talk.text("checked"))
+    
+    
+    current_Y += 50
+    
+    # Project Comment 
+    
+    UI_elements.image(layer, win, "settings/themes/"\
+        +win.settings["Theme"]+"/icons/analytics.png", 
+        win.current["w"]/2-240,
+        110 + current_Y + win.scroll["studio_settings"], 
+        40,
+        40)
+    
+    UI_elements.text(layer, win, "Project_status_setting",
+        win.current["w"]/2-190,
+        110 + current_Y + win.scroll["studio_settings"],
+        420,
+        40,
+        set_text=win.analytics["status"],
+        tip=talk.text("project_status"))
+    
+    if win.text["Project_status_setting"]["text"] != win.analytics["status"]:
+        def do():
+            win.analytics["status"] = win.text["Project_status_setting"]["text"]
+            
+            
+        UI_elements.roundrect(layer, win, 
+            win.current["w"]/2-240+430,
+            110 + current_Y + win.scroll["studio_settings"],
+            40,
+            40,
+            10,
+            button=do,
+            icon="ok",
+            tip=talk.text("checked"))
+    
+    
+    current_Y += 50
+    
+    # Banner / Background image settings.
+    
+    if os.path.exists(win.project+"/set/banner.png"):
+        UI_elements.image(layer, win, win.project+"/set/banner.png",
+            win.current["w"]/2-240,
+            110 + current_Y + win.scroll["studio_settings"],  
+            480,
+            200,
+            cell="settings_background")
+    elif os.path.exists(win.project+"/py_data/banner.png"):
+        UI_elements.image(layer, win, win.project+"/py_data/banner.png",
+            win.current["w"]/2-240,
+            110 + current_Y + win.scroll["studio_settings"],  
+            480,
+            200,
+            cell="settings_background")
+    else:
+        UI_elements.image(layer, win, "icon.png",
+            win.current["w"]/2-240,
+            110 + current_Y + win.scroll["studio_settings"],  
+            480,
+            200,
+            cell="settings_background")
+    
+    def do():
+        def after(win, var):
+            try:
+                if var:
+                    # Let's check that the selected if an image.
+                    
+                    for f in fileformats.images:
+                        if var.endswith(f):
+
+                            # Now let's copy the picture from whereever it is to be the new
+                            # banner. For this first of all I need to check whether it exists
+                            # inside the project. 
+                            
+                            if os.path.exists(win.project+"/"+var):
+                                fr = win.project+"/"+var
+                            else:
+                                fr = var
+                            
+                            with open(fr, "rb") as in_file, open(win.project+"/set/banner.png", "wb") as out_file:
+                                out_file.write(in_file.read())
+                            
+                            
+                            # Refrashing images
+                            win.images = {}
+                            break
+            except:
+                raise()
+                
+        studio_dialogs.file_select(win, "banner_editing", after, force=True)
+        
+        
+    UI_elements.roundrect(layer, win, 
+        win.current["w"]/2-250,
+        100 + current_Y + win.scroll["studio_settings"], 
+        500,
+        220,
+        10,
+        button=do,
+        fill=False,
+        tip=talk.text("project_banner"))
+    layer.stroke()
+    
+    current_Y += 220
+    
+    # Start date and Deadline
+    
+    
+    
+    
+    UI_elements.image(layer, win, "settings/themes/"\
+        +win.settings["Theme"]+"/icons/schedule.png", 
+        win.current["w"]/2-240,
+        110 + current_Y + win.scroll["studio_settings"], 
+        40,
+        40)
+    
+    UI_elements.text(layer, win, "Project_startdate_setting",
+        win.current["w"]/2-190,
+        110 + current_Y + win.scroll["studio_settings"],
+        200,
+        40,
+        set_text=win.analytics["startdate"],
+        tip=talk.text("project_startdate"))
+    
+    if win.text["Project_startdate_setting"]["text"] != win.analytics["startdate"]\
+    and analytics.ifdate(win.text["Project_startdate_setting"]["text"]):
+        def do():
+            win.analytics["startdate"] = win.text["Project_startdate_setting"]["text"]
+            
+            # Refrashing the analytics
+            analytics.save(win.project, win.analytics)
+            win.analytics = analytics.load(win.project)
+            
+        UI_elements.roundrect(layer, win, 
+            win.current["w"]/2-240+210,
+            110 + current_Y + win.scroll["studio_settings"],
+            40,
+            40,
+            10,
+            button=do,
+            icon="ok",
+            tip=talk.text("checked"))
+    
+    UI_elements.text(layer, win, "Project_deadline_setting",
+        win.current["w"]/2-190+210,
+        110 + current_Y + win.scroll["studio_settings"],
+        200,
+        40,
+        set_text=win.analytics["deadline"],
+        tip=talk.text("project_deadline"))
+    
+    if win.text["Project_deadline_setting"]["text"] != win.analytics["deadline"]\
+    and analytics.ifdate(win.text["Project_deadline_setting"]["text"]):
+        def do():
+            win.analytics["deadline"] = win.text["Project_deadline_setting"]["text"]
+            
+            # Refrashing the analytics
+            analytics.save(win.project, win.analytics)
+            win.analytics = analytics.load(win.project)
+            
+        UI_elements.roundrect(layer, win, 
+            win.current["w"]/2-240+420,
+            110 + current_Y + win.scroll["studio_settings"],
+            40,
+            40,
+            10,
+            button=do,
+            icon="ok",
+            tip=talk.text("checked"))
+    
+    current_Y += 100
+    
+    
+    
+    # Username 
+    
+    UI_elements.image(layer, win, "settings/themes/"\
+        +win.settings["Theme"]+"/icons/user.png", 
+        win.current["w"]/2-240,
+        110 + current_Y + win.scroll["studio_settings"], 
+        40,
+        40)
+    
+    UI_elements.text(layer, win, "Username_setting",
+        win.current["w"]/2-190,
+        110 + current_Y + win.scroll["studio_settings"],
+        420,
+        40,
+        set_text=win.settings["Username"],
+        tip=talk.text("username"))
+    
+    if win.text["Username_setting"]["text"] != win.settings["Username"]:
+        def do():
+            win.settings["Username"] = win.text["Username_setting"]["text"]
+            settings.write("Username", win.settings["Username"])
+            
+        UI_elements.roundrect(layer, win, 
+            win.current["w"]/2-240+430,
+            110 + current_Y + win.scroll["studio_settings"],
+            40,
+            40,
+            10,
+            button=do,
+            icon="ok",
+            tip=talk.text("checked"))
+    
+    
+    current_Y += 50
+    
+    
+    # Preparing lists.
+    if "settings_lists" not in win.current:
+        
+        win.current["settings_lists"] = {}
+        win.current["settings_lists"]["languages"] = settings.list_languages()
+        win.current["settings_lists"]["languages_open"] = False
+    
+    
+    # Languages
+    def do():
+        win.current["settings_lists"]["languages_open"] = \
+        not win.current["settings_lists"]["languages_open"]
+        
+    UI_elements.roundrect(layer, win, 
+        win.current["w"]/2-240,
+        110 + current_Y + win.scroll["studio_settings"],
+        450,
+        40,
+        10,
+        button=do,
+        icon="font",
+        tip=talk.text("change_language"))
+    
+    UI_color.set(layer, win, "text_normal")
+    layer.set_font_size(20)
+    layer.move_to(win.current["w"]/2-180,
+        current_Y + win.scroll["studio_settings"] + 135)
+    layer.show_text(win.settings["Language"])
+    
+    current_Y += 50
+    
+    if win.current["settings_lists"]["languages_open"]:
+        
+        
+        for lang in win.current["settings_lists"]["languages"]:
+            if lang != win.settings["Language"]:
+                
+                UI_color.set(layer, win, "button_active")
+                layer.move_to(win.current["w"]/2-227, 102 + current_Y + win.scroll["studio_settings"])
+                layer.line_to(win.current["w"]/2-227, 152 + current_Y + win.scroll["studio_settings"])
+                layer.stroke()
+                
+                def do():
+                    win.settings["Language"] = lang
+                    settings.write("Language", lang)
+                    win.current["settings_lists"]["languages_open"] = False
+                
+                UI_elements.roundrect(layer, win, 
+                    win.current["w"]/2-220,
+                    110 + current_Y + win.scroll["studio_settings"],
+                    430,
+                    40,
+                    10,
+                    button=do,
+                    icon="font",
+                    tip=talk.text("set_language")+lang)
+                
+                
+                UI_color.set(layer, win, "text_normal")
+                layer.set_font_size(20)
+                layer.move_to(win.current["w"]/2-150,
+                    current_Y + win.scroll["studio_settings"] + 135)
+                layer.show_text(lang)
+                
+                current_Y += 50
+    
+    # BLUR
+    
+    blur_ok = "unchecked"
+    if win.settings["Blur"]:
+        blur_ok = "checked"
+                
+    def do():
+        win.settings["Blur"] = not win.settings["Blur"]
+        settings.write("Blur", win.settings["Blur"])
+    
+    UI_elements.roundrect(layer, win, 
+        win.current["w"]/2-240,
+        110 + current_Y + win.scroll["studio_settings"],
+        450,
+        40,
+        10,
+        button=do,
+        icon=blur_ok,
+        tip=talk.text("Blur"))
+    
+    UI_color.set(layer, win, "text_normal")
+    layer.set_font_size(20)
+    layer.move_to(win.current["w"]/2-180,
+        current_Y + win.scroll["studio_settings"] + 135)
+    layer.show_text(talk.text("Blur"))
+    
+    current_Y += 50
+    
+    if win.settings["Blur"]:
+        ablur_ok = "unchecked"            
+        if win.settings["Auto_De-Blur"]:
+            ablur_ok = "checked"
+        
+        def do():
+            win.settings["Auto_De-Blur"] = not win.settings["Auto_De-Blur"]
+            settings.write("Auto_De-Blur", win.settings["Auto_De-Blur"])
+        
+        UI_elements.roundrect(layer, win, 
+            win.current["w"]/2-240,
+            110 + current_Y + win.scroll["studio_settings"],
+            450,
+            40,
+            10,
+            button=do,
+            icon=ablur_ok,
+            tip=talk.text("Auto_De-Blur"))
+        
+        UI_color.set(layer, win, "text_normal")
+        layer.set_font_size(20)
+        layer.move_to(win.current["w"]/2-180,
+            current_Y + win.scroll["studio_settings"] + 135)
+        layer.show_text(talk.text("Auto_De-Blur"))
+    
+    
+    current_Y += 50
+    
+    UI_elements.scroll_area(layer, win, "studio_settings", 
+        int(win.current["w"]/2-250),
+        100,
+        500,
+        win.current["h"]-260,
+        current_Y,
+        bar=True,
+        mmb=True,
+        url="settings_layer"
+        )
+    
+    
+    return surface
diff --git a/studio/studio_storyLayer.py b/studio/studio_storyLayer.py
index eed72a5..f254f15 100644
--- a/studio/studio_storyLayer.py
+++ b/studio/studio_storyLayer.py
@@ -2,6 +2,8 @@
 # PYTHON 3
 
 import os
+import datetime
+import threading
 
 # GTK module ( Graphical interface
 import gi
@@ -29,6 +31,12 @@ 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'])
@@ -38,6 +46,15 @@ def layer(win):
     #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,
@@ -133,7 +150,12 @@ def layer(win):
     layer.show_text("Character: Moria")
     
     
-    
+    ########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
+    fif = datetime.datetime.now()
+    mil  = fif - stf
+    perfStat.append([ "Analytics", mil.microseconds ])
+    stf = datetime.datetime.now()
+    ###################################################################
     
     
     
@@ -427,13 +449,23 @@ def layer(win):
         "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):
             
-        print (var)
-        
+        if var:
+            win.url = "assets"
+            win.cur  = var
+            
     
     # Characters
     def do():
@@ -526,6 +558,14 @@ def layer(win):
         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
@@ -539,23 +579,38 @@ def layer(win):
     layer.clip()
     
     # Background Image
-    if os.path.exists(win.project+"/py_data/banner.png"):
+    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)
+            win.current["h"] - 80,
+            cell="background")
     else:
         UI_elements.image(layer, win, "icon.png",
             50,
             50, 
             win.current["w"] - 100,
-            win.current["h"] - 80)
+            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
@@ -583,6 +638,13 @@ def layer(win):
         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:
@@ -631,6 +693,14 @@ def layer(win):
     except:
         pass
     
+    ########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
+    fif = datetime.datetime.now()
+    mil  = fif - stf
+    perfStat.append([ "Events", mil.microseconds ])
+    stf = datetime.datetime.now()
+    ###################################################################
+    
+    
     # SCENES
     
     for scene in win.story["scenes"]:
@@ -651,7 +721,13 @@ def layer(win):
         #Draw
         studio_nodes.scene_node(layer, win, sx, sy, ssx, ssy, name=scene, fraction=sf)
         
-        
+    
+    ########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
+    fif = datetime.datetime.now()
+    mil  = fif - stf
+    perfStat.append([ "Scenes", mil.microseconds ])
+    stf = datetime.datetime.now()
+    ###################################################################    
     
     # LINKS (Images, Stuff)
     
@@ -664,6 +740,15 @@ def layer(win):
         
         
         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.
@@ -673,6 +758,13 @@ def layer(win):
         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"]:
@@ -685,6 +777,13 @@ def layer(win):
     except:
         pass
     
+    ########### 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"
@@ -783,6 +882,8 @@ def layer(win):
     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":
@@ -820,11 +921,37 @@ def layer(win):
         except:
             pass
     
+    ########### TIMES RECORDING FOR PERFONMANCE MEASURING #############
+    fif = datetime.datetime.now()
+    mil  = fif - stf
+    perfStat.append([ "Selection", mil.microseconds ])
+    stf = datetime.datetime.now()
+    ###################################################################
+    
     # Save story. I'm going to do it the same way as in the old Blender-Organizer
-    if win.current["frame"] % 10 == 0 and win.url == "story_editor"\
-    and not win.current["LMB"] and not win.current["MMB"] and not win.current["RMB"]:
-        story.save(win.project, win.story)
-        analytics.save(win.project, win.analytics)
+    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
+        
+        
+        if savenow:
+        
+            story.save(win.project, win.story)
+            analytics.save(win.project, win.analytics)
+    
+    ########### 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:
@@ -852,6 +979,55 @@ def layer(win):
     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