# 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 import cairo # Own modules from settings import settings from settings import talk from settings import fileformats from settings import oscalls # Studio from studio import story from studio import analytics from studio import studio_dialogs from studio import checklist # UI modules from UI import UI_testing from UI import UI_color from UI import UI_elements from UI import UI_math def node_dot(layer, win, x, y, direction="in", entry="end"): # This function will draw a dot to which various nodes are connected. And # from which connections going off. # This is a very alpha version of the dot thing raw_entry = entry if type(entry) == list: entry = entry[0]+":"+entry[1] if entry.startswith("scene:") or entry in ["start", "end"]: UI_color.set(layer, win, "node_script") elif entry.startswith("blend:"): UI_color.set(layer, win, "node_blendfile") else: UI_color.set(layer, win, "node_imagefile") UI_elements.roundrect(layer, win, x, y, 0, 0, 6) if int(win.current["mx"]) in range(int(x), int(x+12))\ and int(win.current["my"]) in range(int(y), int(y+12)): UI_color.set(layer, win, "text_normal") UI_elements.roundrect(layer, win, x, y, 0, 0, 6, fill=False) layer.stroke() win.current["cursor"] = win.cursors["arrow"] # Start drawing the line if not win.previous["LMB"] and win.current["LMB"] and direction != "in": # Out point win.current["tool"] = "connect" win.current["draw_dot"] = raw_entry elif not win.previous["LMB"] and win.current["LMB"] and direction == "in" and win.current["tool"] != "connect": # Take out of the in point try: found = False win.current["tool"] = "connect" for arrow in win.story["arrows"]: if raw_entry == arrow[1]: win.current["draw_dot"] = arrow[0]#.copy() found = arrow break if found: win.story["arrows"].remove(found) else: win.current["draw_dot"] = "end" except: pass # Refrashing analytics story.save(win.project, win.story) win.analytics = analytics.load(win.project) analytics.save(win.project, win.analytics) # Connecting the line if win.current["tool"] == "connect" and direction == "in" and not win.current["LMB"]: # Connecting the scenes together if raw_entry[0] not in ["file", "blend"] and win.current["draw_dot"][0] not in ["file", "blend"]: new_arrow = [ win.current["draw_dot"], raw_entry ] 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 story.save(win.project, win.story) win.analytics = analytics.load(win.project) analytics.save(win.project, win.analytics) if direction != "in": win.out_dots[entry] = [x+6, y+6] elif entry.startswith("scene:") or entry in ["start", "end"]: for arrow in win.story["arrows"]: if raw_entry == arrow[1]: fr = arrow[0] 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(x+6, y+6) layer.stroke() except: pass elif entry.startswith("asset:"): for link in win.story["links"]: if link[0] == "file": link = link[1] fr = "file:"+link if entry[entry.find(":")+1:] in link: try: UI_color.set(layer, win, "node_imagefile") layer.move_to( win.out_dots[fr][0], win.out_dots[fr][1] ) layer.line_to(x+6, y+6) layer.stroke() except: pass elif entry.startswith("blend:"): for link in win.story["links"]: if link[0] == "file": link = link[1] fr = "blend:"+link if entry[entry.find(":")+1:]+"/" in link or entry[entry.find(":")+1:]+"." in link: try: UI_color.set(layer, win, "node_blendfile") layer.move_to( win.out_dots[fr][0], win.out_dots[fr][1] ) layer.line_to(x+6, y+6) layer.stroke() except: pass def start_node(outlayer, win, x, y, width, height): # This function will draw a start node in the top left corner of the story # editor. This is where the story begins. # Making the layer surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height)) layer = cairo.Context(surface) # Clip UI_elements.roundrect(layer, win, 0, 0, width, height, 10, fill=False) layer.clip() # Background UI_color.set(layer, win, "dark_overdrop") layer.rectangle(0,0,width, height) layer.fill() # top banner UI_color.set(layer, win, "node_badfile") layer.rectangle(0,0,width, 20) layer.fill() # Text saying START UI_color.set(layer, win, "text_normal") layer.set_font_size(15) layer.move_to(width/2-len(talk.text("Start"))*9/2,15) layer.show_text(talk.text("Start")) # Outputting the layer outlayer.set_source_surface(surface, x, y) outlayer.paint() # Dot node_dot(outlayer, win, x+width-7, y+height-12, direction="out", entry="start") def end_node(outlayer, win, x, y, width, height): # This function will draw a end node in the bottom right corner of the story # editor. This is where the story ends. # Making the layer surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height)) layer = cairo.Context(surface) # Clip UI_elements.roundrect(layer, win, 0, 0, width, height, 10, fill=False) layer.clip() # Background UI_color.set(layer, win, "dark_overdrop") layer.rectangle(0,0,width, height) layer.fill() # top banner UI_color.set(layer, win, "node_badfile") layer.rectangle(0,0,width, 20) layer.fill() # Text saying END UI_color.set(layer, win, "text_normal") layer.set_font_size(15) layer.move_to(width/2-len(talk.text("End"))*9/2,15) layer.show_text(talk.text("End")) # Outputting the layer outlayer.set_source_surface(surface, x, y) outlayer.paint() # Dot node_dot(outlayer, win, x-2, y+height-12) def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0, shots=[]): # This function will draw scene nodes. entry = ['scene', name] width = max(width,20) height = max(height,20) doparent = True if int(x) in range(int(0-width), int(win.current["w"]))\ and int(y) in range(int(0-height), int(win.current["h"])): # Making the layer surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height)) layer = cairo.Context(surface) layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) selected = False if win.url == "story_editor"\ 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)): if win.current["LMB"] and entry in win.story["selected"]: if int(win.current["LMB"][0]) in range(int(x), int(x+width))\ and int(win.current["LMB"][1]) in range(int(y), int(y+height))\ and win.current["tool"] == "selection": win.current["tool"] = "grab" win.story["active"] = entry # Launching the item if int(win.current["mx"]) in range(int(x), int(x+width))\ and int(win.current["my"]) in range(int(y), int(y+height)): win.current["cursor"] = win.cursors["hand"] if not win.current["LMB"] and win.previous["LMB"]\ and entry in win.story["selected"]\ and int(win.current["mx"]) == int(win.previous["LMB"][0])\ and int(win.current["my"]) == int(win.previous["LMB"][1]): win.url = "script" win.cur = "/"+name win.current["tool"] = "selection" if win.current["LMB"] and win.current["tool"] == "selection": # If mouse over. But way more complex. Because we might select more then # 1 scene at ones. mx = win.current["mx"] my = win.current["my"] pmx = win.current["LMB"][0] pmy = win.current["LMB"][1] intersect = UI_math.rectangle_overlap( [mx, my, pmx-mx, pmy-my], [x,y,width, height]) # Now let's make a higlight if intersect: selected = True elif win.previous["LMB"] and win.previous["tool"] == "selection": # If you released the mouse while selecting. Then do selecting. I guess. mx = win.previous["mx"] my = win.previous["my"] pmx = win.previous["LMB"][0] pmy = win.previous["LMB"][1] intersect = UI_math.rectangle_overlap( [mx, my, pmx-mx, pmy-my], [x,y,width, height]) # Now let's make a selection if intersect: if entry not in win.story["selected"]: win.story["selected"].append(entry) if win.story["active"] not in win.story["selected"]: win.story["active"] = entry if entry in win.story["selected"]: selected = True if selected: if win.current["tool"] == "selection": UI_math.rectangle_surround(win, "selection", win.szone[0], win.szone[1], [x,y], [width, height] ) # Now let's make the stratching thing do it's stratching. It's the # circle in the bottom, right corner of the selection. if win.current["tool"] == "scale" and win.current["LMB"] and win.previous["LMB"]: # let's get the points of the selection zone. zx = win.szone[0][0] zy = win.szone[0][1] zsx = win.previous["LMB"][0] zsy = win.previous["LMB"][1] if win.current["mx"] > zx and win.current["my"] > zy: # now let's get the motion fraction. mvx = (x - zx) / (zsx - zx) mvy = (y - zy) / (zsy - zy) svx = (win.current["mx"]- zx) / (win.previous["mx"]-zx) svy = (win.current["my"]- zy) / (win.previous["my"]-zy) # now let's apply these win.story["scenes"][name]["position"][0]\ += (win.current["mx"] - win.previous["mx"])*mvx win.story["scenes"][name]["position"][1]\ += (win.current["my"] - win.previous["my"])*mvy win.story["scenes"][name]["size"][0]\ = max(win.story["scenes"][name]["size"][0] * svx, 40) win.story["scenes"][name]["size"][1]\ = max(win.story["scenes"][name]["size"][1] * svy, 40) # Now let's do the simple grab tool. if win.current["tool"] == "grab": # If you press shift, You take things out of events if 65505 in win.current["keys"]: doparent = False try: if win.current["LMB"]: x += win.current["mx"] - win.current["LMB"][0] y += win.current["my"] - win.current["LMB"][1] elif win.previous["LMB"]: win.story["scenes"][name]["position"][0]\ += win.previous["mx"] - win.previous["LMB"][0] win.story["scenes"][name]["position"][1]\ += win.previous["my"] - win.previous["LMB"][1] x += win.previous["mx"] - win.previous["LMB"][0] y += win.previous["my"] - win.previous["LMB"][1] # Parent removing / assigning if not doparent: win.story["scenes"][name]["parent"] = "" elif not win.story["scenes"][name]["parent"]: for event in win.story["events"]: mx, my = win.story["events"][event]["position"] pmx, pmy = win.story["events"][event]["size"] if UI_math.rectangle_overlap( [mx, my, pmx, pmy], [x,y,width, height]): win.story["scenes"][name]["parent"] = event break elif win.current["tool"] != "connect": win.current["tool"] = "selection" except: raise() # The selected outline UI_color.set(outlayer, win, "progress_background") if win.story["active"] == entry: UI_color.set(outlayer, win, "text_normal") outlayer.set_line_width(4) UI_elements.roundrect(outlayer, win, x, y, width, height, 10, fill=False) outlayer.stroke() outlayer.set_line_width(2) # Clip UI_elements.roundrect(layer, win, 0, 0, width, height, 10, fill=False) layer.clip() # Tooltip if int(win.current["mx"]) in range(int(x), int(x+width))\ and int(win.current["my"]) in range(int(y), int(y+height)): UI_elements.tooltip(win, name) # Background UI_color.set(layer, win, "dark_overdrop") layer.rectangle(0,0,width, height) layer.fill() # top banner UI_color.set(layer, win, "node_script") layer.rectangle(0,0,width, 20) layer.fill() # Text saying The name of the scene UI_color.set(layer, win, "text_normal") layer.set_font_size(15) layer.move_to(15,15) layer.show_text(name) text_height = 10 # Fraction if fraction: text_height = 40 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) # A bit of the scene itself if the size allows. if width > 100 and height > text_height: # Very simple text from the scene, nothing fancy alltext = "" for i in shots: for b in i[-1]: if b[0] == "frase": alltext = alltext + b[1][-1]+": " alltext = alltext + b[-1] alltext = alltext.replace("\n", " \n ") # Rendering it. fx = 15 fy = 50 for word in alltext.split(" "): if word == "\n" or len(word)*9 + fx > width: fy = fy + 20 fx = 15 if fy > height - text_height: break if word != "\n": UI_color.set(layer, win, "text_normal") layer.set_font_size(15) layer.move_to(fx,fy) layer.show_text(word) fx = fx + len(word)*9 + 10 # Outputting the layer outlayer.set_source_surface(surface, x, y) outlayer.paint() # In case there is a parent event in the scene. if win.story["scenes"][name]["parent"] and doparent: parent = win.story["scenes"][name]["parent"] UI_math.rectangle_surround(win, parent, win.story["events"][parent]["position"], win.story["events"][parent]["size"], [x,y], [width, height] ) # Dots node_dot(outlayer, win, x-5, y+25, entry=entry) node_dot(outlayer, win, x+width-7, y+25, direction="out",entry=entry) def event_node(outlayer, win, x, y, width, height, name="Unknown"): # This function draws events. x = x - 20 y = y - 20 width = width + 40 height = height + 40 entry = ['event', name] # Making sure the size is alright if width < 100: width = 100 if height < 100: height = 100 # Making the layer surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height)) layer = cairo.Context(surface) # Clip UI_elements.roundrect(layer, win, 0, 0, width, height, 10, fill=False) layer.clip() # Background UI_color.set(layer, win, "dark_overdrop") layer.rectangle(0,0,width, height) layer.fill() # Here should be the event name thing. But I thought that it wasn't # important for a simple framing thing. # Outputting the layer outlayer.set_source_surface(surface, x, y) outlayer.paint() def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linktype="file"): filetype = "" # This node will output links to files. if linktype == "asset": width += 50 height += 80 else: # Let's find out what type of file is it. for f in fileformats.images: if name.endswith(f): filetype = "image" if not filetype: for f in fileformats.videos: if name.endswith(f): filetype = "video" doparent = True if int(x) in range(int(0-width), int(win.current["w"]))\ and int(y) in range(int(0-height), int(win.current["h"])): # Making the layer surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height)) layer = cairo.Context(surface) entry = [linktype, num] selected = False if win.url == "story_editor"\ 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)): if win.current["LMB"] and entry in win.story["selected"]: if int(win.current["LMB"][0]) in range(int(x), int(x+width))\ and int(win.current["LMB"][1]) in range(int(y), int(y+height))\ and win.current["tool"] == "selection": win.current["tool"] = "grab" win.story["active"] = entry # Launching the item if int(win.current["mx"]) in range(int(x), int(x+width))\ and int(win.current["my"]) in range(int(y), int(y+height)): win.current["cursor"] = win.cursors["hand"] if not win.current["LMB"] and win.previous["LMB"]\ and entry in win.story["selected"]\ and int(win.current["mx"]) == int(win.previous["LMB"][0])\ and int(win.current["my"]) == int(win.previous["LMB"][1]): if linktype == "file": oscalls.file_open(win, name) elif int(win.current["mx"]) > x+40: # This is a hack. But whatever. win.url = "assets" win.cur = name win.current["tool"] = "selection" win.previous["LMB"] = False if win.current["LMB"] and win.current["tool"] == "selection": # If mouse over. But way more complex. Because we might select more then # 1 scene at ones. mx = win.current["mx"] my = win.current["my"] pmx = win.current["LMB"][0] pmy = win.current["LMB"][1] intersect = UI_math.rectangle_overlap( [mx, my, pmx-mx, pmy-my], [x,y,width, height]) # Now let's make a higlight if intersect: selected = True elif win.previous["LMB"] and win.previous["tool"] == "selection": # If you released the mouse while selecting. Then do selecting. I guess. mx = win.previous["mx"] my = win.previous["my"] pmx = win.previous["LMB"][0] pmy = win.previous["LMB"][1] intersect = UI_math.rectangle_overlap( [mx, my, pmx-mx, pmy-my], [x,y,width, height]) # Now let's make a selection if intersect: if entry not in win.story["selected"]: win.story["selected"].append(entry) # Making it active. if win.story["active"] not in win.story["selected"]: win.story["active"] = entry if entry in win.story["selected"]: selected = True if selected: if win.current["tool"] == "selection": UI_math.rectangle_surround(win, "selection", win.szone[0], win.szone[1], [x,y], [width, height] ) # Now let's make the stratching thing do it's stratching. It's the # circle in the bottom, right corner of the selection. if win.current["tool"] == "scale" and win.current["LMB"] and win.previous["LMB"]: # let's get the points of the selection zone. zx = win.szone[0][0] zy = win.szone[0][1] zsx = win.previous["LMB"][0] zsy = win.previous["LMB"][1] if win.current["mx"] > zx and win.current["my"] > zy: # now let's get the motion fraction. mvx = (x - zx) / (zsx - zx) mvy = (y - zy) / (zsy - zy) # now let's apply these win.story["links"][num][2][0]\ += (win.current["mx"] - win.previous["mx"])*mvx win.story["links"][num][2][1]\ += (win.current["my"] - win.previous["my"])*mvy if win.current["tool"] == "grab": # If you press shift, You take things out of events if 65505 in win.current["keys"]: doparent = False try: if win.current["LMB"]: x += win.current["mx"] - win.current["LMB"][0] y += win.current["my"] - win.current["LMB"][1] elif win.previous["LMB"]: win.story["links"][num][2][0]\ += win.previous["mx"] - win.previous["LMB"][0] win.story["links"][num][2][1]\ += win.previous["my"] - win.previous["LMB"][1] x += win.previous["mx"] - win.previous["LMB"][0] y += win.previous["my"] - win.previous["LMB"][1] # Parent removing / assigning if not doparent: win.story["links"][num][3] = "" elif not win.story["links"][num][3]: for event in win.story["events"]: mx, my = win.story["events"][event]["position"] pmx, pmy = win.story["events"][event]["size"] if UI_math.rectangle_overlap( [mx, my, pmx, pmy], [x,y,width, height]): win.story["links"][num][3] = event break elif win.current["tool"] != "connect": win.current["tool"] = "selection" except: raise() # The selected outline UI_color.set(outlayer, win, "progress_background") if win.story["active"] == entry: UI_color.set(outlayer, win, "text_normal") outlayer.set_line_width(4) UI_elements.roundrect(outlayer, win, x, y, width, height, 10, fill=False) outlayer.stroke() outlayer.set_line_width(2) # Clip UI_elements.roundrect(layer, win, 0, 0, width, height, 10, fill=False) layer.clip() # Background UI_color.set(layer, win, "dark_overdrop") layer.rectangle(0,0,width, height) layer.fill() if linktype == "asset": assettype = name[:name.rfind("/")].replace("/", "") if os.path.exists(win.project+"/dev"+name+"/renders/Preview.png"): UI_elements.image(layer, win, win.project+"/dev"+name+"/renders/Preview.png", 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", 0, 0, width, height, cell="story_asset_previews") else: UI_elements.image(layer, win, "settings/themes/"+win.settings["Theme"]+"/icons/"+assettype+".png", 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. 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] # 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, win.project+"/"+name, 0, 0, width, height) else: UI_elements.image(layer, win, name, 0, 0, width, height) if name.endswith(".progress"): fraction = checklist.get_fraction(win, name) UI_color.set(layer, win, "progress_background") UI_elements.roundrect(layer, win, 10, height-20, width-20, 0, 5) UI_color.set(layer, win, "progress_active") UI_elements.roundrect(layer, win, 10, height-20, (width-20)*fraction, 0, 5) if name.endswith(".blend"): UI_color.set(layer, win, "node_blendfile") if "ast/" in name: UI_color.set(layer, win, "node_asset") elif filetype == "image": UI_color.set(layer, win, "node_imagefile") elif filetype == "video": UI_color.set(layer, win, "node_videofile") else: UI_color.set(layer, win, "node_script") # Tooltip if int(win.current["mx"]) in range(int(x), int(x+width))\ and int(win.current["my"]) in range(int(y), int(y+height)): UI_elements.tooltip(win, name) # top banner layer.rectangle(0,0,width, 20) layer.fill() # Text saying The name of the event UI_color.set(layer, win, "text_normal") layer.set_font_size(15) layer.move_to(15,15) layer.show_text(name[name.rfind("/")+1:]) # Outputting the layer outlayer.set_source_surface(surface, x, y) outlayer.paint() if linktype == "asset": node_dot(outlayer, win, x-6, y+25+14, entry=["blend", name]) node_dot(outlayer, win, x-6, y+75+14, entry=["asset", name+"/reference"]) node_dot(outlayer, win, x-6, y+125+14, entry=["asset", name+"/tex"]) node_dot(outlayer, win, x-6, y+175+14, entry=["asset", name+"/renders"]) else: if name.endswith(".blend"): node_dot(outlayer, win, x+width-6, y+120, entry=["blend", name], direction="out") elif filetype in ["image", "video"]: node_dot(outlayer, win, x+width-6, y+120, entry=["file", name], direction="out") else: # If not in the frame if linktype == "file": try: if name.endswith(".blend"): del win.out_dots["blend:"+name] else: del win.out_dots["file:"+name] except: pass # In case there is a parent event in the scene. if win.story["links"][num][3] and doparent: parent = win.story["links"][num][3] UI_math.rectangle_surround(win, parent, win.story["events"][parent]["position"], win.story["events"][parent]["size"], [x,y], [width, height] ) def marker(outlayer, win, name ,x, y ): # This function will draw markers to the screen. They are like shortcuts in # a story editor space. if int(x) in range(int(60), int(win.current["w"]-100))\ and int(y) in range(int(60), int(win.current["h"]-80)): width = 200 height = 40 inscreen = True else: x = min(max(x, 60), win.current["w"]-100) y = min(max(y, 60), win.current["h"]-80) width = 40 height = 40 inscreen = False # Making the layer surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height)) layer = cairo.Context(surface) entry = ["marker", name] if inscreen: doparent = True selected = False if win.url == "story_editor"\ 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)): if win.current["LMB"] and entry in win.story["selected"]: if int(win.current["LMB"][0]) in range(int(x), int(x+40))\ and int(win.current["LMB"][1]) in range(int(y), int(y+height))\ and win.current["tool"] == "selection": win.current["tool"] = "grab" win.story["active"] = entry if win.current["LMB"] and win.current["tool"] == "selection": # If mouse over. But way more complex. Because we might select more then # 1 scene at ones. mx = win.current["mx"] my = win.current["my"] pmx = win.current["LMB"][0] pmy = win.current["LMB"][1] intersect = UI_math.rectangle_overlap( [mx, my, pmx-mx, pmy-my], [x,y,width, height]) # Now let's make a higlight if intersect: selected = True elif win.previous["LMB"] and win.previous["tool"] == "selection": # If you released the mouse while selecting. Then do selecting. I guess. mx = win.previous["mx"] my = win.previous["my"] pmx = win.previous["LMB"][0] pmy = win.previous["LMB"][1] intersect = UI_math.rectangle_overlap( [mx, my, pmx-mx, pmy-my], [x,y,width, height]) # Now let's make a selection if intersect: if entry not in win.story["selected"]: win.story["selected"].append(entry) # Making it active. if win.story["active"] not in win.story["selected"]: win.story["active"] = entry if entry in win.story["selected"]: selected = True if selected: if win.current["tool"] == "selection": UI_math.rectangle_surround(win, "selection", win.szone[0], win.szone[1], [x,y], [width, height] ) # Now let's make the stratching thing do it's stratching. It's the # circle in the bottom, right corner of the selection. if win.current["tool"] == "scale" and win.current["LMB"] and win.previous["LMB"]: # let's get the points of the selection zone. zx = win.szone[0][0] zy = win.szone[0][1] zsx = win.previous["LMB"][0] zsy = win.previous["LMB"][1] if win.current["mx"] > zx and win.current["my"] > zy: # now let's get the motion fraction. mvx = (x - zx) / (zsx - zx) mvy = (y - zy) / (zsy - zy) # now let's apply these win.story["markers"][name][0]\ += (win.current["mx"] - win.previous["mx"])*mvx win.story["markers"][name][1]\ += (win.current["my"] - win.previous["my"])*mvy if win.current["tool"] == "grab": # If you press shift, You take things out of events if 65505 in win.current["keys"]: doparent = False try: if win.current["LMB"]: x += win.current["mx"] - win.current["LMB"][0] y += win.current["my"] - win.current["LMB"][1] elif win.previous["LMB"]: win.story["markers"][name][0]\ += win.previous["mx"] - win.previous["LMB"][0] win.story["markers"][name][1]\ += win.previous["my"] - win.previous["LMB"][1] x += win.previous["mx"] - win.previous["LMB"][0] y += win.previous["my"] - win.previous["LMB"][1] # Parent removing / assigning if not doparent: win.story["markers"][name][2] = "" elif not win.story["markers"][name][2] : for event in win.story["events"]: mx, my = win.story["events"][event]["position"] pmx, pmy = win.story["events"][event]["size"] if UI_math.rectangle_overlap( [mx, my, pmx, pmy], [x,y,width, height]): win.story["markers"][name][2] = event print(event) break elif win.current["tool"] != "connect": win.current["tool"] = "selection" except: raise() # The selected outline UI_color.set(outlayer, win, "progress_background") if win.story["active"] == entry: UI_color.set(outlayer, win, "text_normal") outlayer.set_line_width(4) UI_elements.roundrect(outlayer, win, x, y, width, height, 10, fill=False) outlayer.stroke() outlayer.set_line_width(2) # Clip UI_elements.roundrect(layer, win, 0, 0, width, height, 10, fill=False) layer.clip() # Background UI_color.set(layer, win, "dark_overdrop") layer.rectangle(0,0,width, height) layer.fill() # Pin Icon UI_elements.image(layer, win, "settings/themes/"+win.settings["Theme"]+"/icons/pin.png", 0, 0, 40, 40) # Outputting the layer outlayer.set_source_surface(surface, x, y) outlayer.paint() if inscreen: # Text editor for the marker's name. UI_elements.text(outlayer, win, name+"_marker", x+40, y, width-40, 40, set_text=name) if name != win.text[name+"_marker"]["text"] and win.text[name+"_marker"]["text"]: def do(): win.story["selected"] = [] win.story["markers"][win.text[name+"_marker"]["text"]] = [ x - win.story["camera"][0], y - win.story["camera"][1], win.story["markers"][name][2] ] win.textactive = "" del win.story["markers"][name] UI_elements.roundrect(outlayer, win, x+width-40, y, 40, 40, 10, button=do, icon="ok", tip=talk.text("checked")) if 65293 in win.current["keys"]: do() # In case there is a parent event in the scene. if win.story["markers"][name][2] and doparent: parent = win.story["markers"][name][2] UI_math.rectangle_surround(win, parent, win.story["events"][parent]["position"], win.story["events"][parent]["size"], [x,y], [width, height] ) else: if win.textactive == name+"_marker": win.textactive = "" def do(): nex = 0-win.story["markers"][name][0] + win.current["w"]/2 ney = 0-win.story["markers"][name][1] + win.current["h"]/2 UI_elements.animate("cameraX", win, win.story["camera"][0],nex, time=20, force=True) UI_elements.animate("cameraY", win, win.story["camera"][1],ney, time=20, force=True) UI_elements.roundrect(outlayer, win, x+width-40, y, 40, 40, 10, button=do, tip=name, fill=False) outlayer.stroke() def user(outlayer, win, name ,x, y, user): # This function will draw users from multiuser to the screen. if int(x) in range(int(60), int(win.current["w"]-100))\ and int(y) in range(int(60), int(win.current["h"]-80)): width = 200 height = 40 inscreen = True else: x = min(max(x, 60), win.current["w"]-100) y = min(max(y, 60), win.current["h"]-80) width = 40 height = 40 inscreen = False # Making the layer surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height)) layer = cairo.Context(surface) # Clip UI_elements.roundrect(layer, win, 0, 0, width, height, 10, fill=False) layer.clip() # Background UI_color.set(layer, win, "dark_overdrop") layer.rectangle(0,0,width, height) layer.fill() # Pin Icon UI_elements.image(layer, win, "settings/themes/"+win.settings["Theme"]+"/icons/user.png", 0, 0, 40, 40) # Outputting the layer outlayer.set_source_surface(surface, x, y) outlayer.paint() if inscreen: # Text editor for the marker's name. UI_elements.text(outlayer, win, name+"_user", x+40, y, width-40, 40, set_text=name, editable=False) else: # Going to the other user with 1 click def do(): nex = win.multiuser["users"][user]["camera"][0] ney = win.multiuser["users"][user]["camera"][1] UI_elements.animate("cameraX", win, win.story["camera"][0],nex, time=20, force=True) UI_elements.animate("cameraY", win, win.story["camera"][1],ney, time=20, force=True) UI_elements.roundrect(outlayer, win, x+width-40, y, 40, 40, 10, button=do, tip=name, fill=False) outlayer.stroke()