# THIS FILE IS A PART OF VCStudio # PYTHON 3 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 project_manager import pm_project from studio import analytics from studio import studio_nodes from studio import studio_dialogs #UI modules from UI import UI_elements from UI import UI_color 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, "darker_parts") UI_elements.roundrect(layer, win, 50, 50, win.current["w"] - 100, win.current["h"] - 80, 30) # Little verion thing in the bottom corner UI_color.set(layer, win, "testing_banner") layer.set_font_size(15) layer.move_to(win.current["w"]-80, win.current["h"] - 7) layer.show_text(str(win.version)) # Hude analytics button on the top def do(): print("Analytics") UI_elements.roundrect(layer, win, 5, 5, win.current["w"]-10, 40, 10, do, "analytics", talk.text("analytics_tooltip"), url="story_editor") # Progressbar UI_color.set(layer, win, "progress_background") UI_elements.roundrect(layer, win, 55, 15, win.current["w"]/3*2-10, 20, 10) timepassed = 0.0 projectdone = 0.0 try: timepassed = win.analytics["timepassed"] projectdone = win.analytics["fraction"] except: pass # Timepassed UI_color.set(layer, win, "progress_time") UI_elements.roundrect(layer, win, 55, 15, (win.current["w"]/3*2-10)*timepassed, 20, 10) # Project Done UI_color.set(layer, win, "progress_active") UI_elements.roundrect(layer, win, 55, 15, (win.current["w"]/3*2-10)*projectdone, 20, 10) # Separator UI_color.set(layer, win, "node_background") layer.move_to(win.current["w"]/3*2+55, 5) layer.line_to(win.current["w"]/3*2+55, 45) layer.stroke() # Schedule UI_elements.image(layer, win, "settings/themes/"\ +win.settings["Theme"]+"/icons/schedule.png", win.current["w"]/3*2+60, 5, 40, 40) # Temporarely: UI_color.set(layer, win, "text_normal") layer.set_font_size(20) layer.move_to(win.current["w"]/3*2+120, 25) layer.show_text("The Next Task") layer.set_font_size(12) layer.move_to(win.current["w"]/3*2+130+len("The Next Task")*12, 25) layer.show_text("from: AllTasks > Subtasks > This") layer.set_font_size(12) layer.move_to(win.current["w"]/3*2+120, 40) layer.show_text("Character: Moria") ###### LEFT PANNEL ####### # New Scene def do(): # Okay let's make the adding the scene possible. # First we need to know what scenes are there. So we don't overwrite # any existing scene. scenename = "Scene" count = 2 while scenename in win.story["scenes"]: scenename = "Scene_"+str(count) count = count + 1 # Now that we have an empty name. Let's add a scene. win.story["scenes"][scenename] = { "fraction":0.0, # Percentage "position":[ win.current["mx"]-win.story["camera"][0]-50, win.current["my"]-win.story["camera"][1]-30 ], "size":[100, 60], "parent":"", # For when it's in a Frame (Event) "shots":[[ "text_block",[["text", '']] ]] } # Auto select the new scene win.story["selected"] = [["scene", scenename]] win.current["tool"] = "grab" # A hack I guess. I don't know what I'm doing. I'm trying to force # the motion on click. win.current["LMB"] = [win.current["mx"], win.current["my"], True] # In studio/studio_gtk.py there is a command that recognizes the length # of the LMB. And it's more then 2 it does some magic to make stuff move # without pressing the actuall key. It's slightly too clever even for me # so yeah. UI_elements.roundrect(layer, win, 5, 105, 40, 40, 10, do, "node", talk.text("new_scene_tooltip")+"\n[N]", url="story_editor") # Shortcut if 110 in win.current["keys"] and not win.textactive: do() win.current["keys"] = [] # Link Asset def do(): def after(win, var): print (var) if var: win.story["links"].append([ "asset", var, [ win.current["mx"]-win.story["camera"][0]-75, win.current["my"]-win.story["camera"][1]-75 ] ]) # Now let's select and move the thing win.story["selected"] = [["asset", len(win.story["links"])-1]] win.current["tool"] = "grab" win.current["LMB"] = [win.current["mx"], win.current["my"], True] studio_dialogs.asset_select(win, "new_asset_story", after) UI_elements.roundrect(layer, win, 5, 155, 40, 40, 10, do, "obj_link", talk.text("link_asset_tooltip")+"\n[L]", url="story_editor") # Shortcut if 108 in win.current["keys"] and not win.textactive: do() win.current["keys"] = [] # Link File def do(): def after(win, var): if var: win.story["links"].append([ "file", var, [ win.current["mx"]-win.story["camera"][0]-75, win.current["my"]-win.story["camera"][1]-75 ] ]) # Now let's select and move the thing win.story["selected"] = [["file", len(win.story["links"])-1]] win.current["tool"] = "grab" win.current["LMB"] = [win.current["mx"], win.current["my"], True] studio_dialogs.file_select(win, "new_file_story", after, force=True) UI_elements.roundrect(layer, win, 5, 205, 40, 40, 10, do, "file_link", talk.text("link_file_tooltip")+"\n[I]", url="story_editor") # Shortcut if 105 in win.current["keys"] and not win.textactive: do() win.current["keys"] = [] # Event def do(): print("Event") UI_elements.roundrect(layer, win, 5, 255, 40, 40, 10, do, "event", talk.text("event_tooltip"), url="story_editor") # Marker def do(): markername = "Marker" count = 2 while markername in win.story["markers"]: markername = "Marker_"+str(count) count = count + 1 win.story["markers"][markername] = [ win.current["mx"]-win.story["camera"][0]+50, win.current["my"]-win.story["camera"][1]-20 ] win.textactive = markername+"_marker" win.text[markername+"_marker"] = { "text" :markername, # Actuall text you are editing. "cursor":[len(str(markername)),len(str(markername))], # Cursor "insert":False, # Whether the insert mode is on "scroll":"markername_scroll" # If multiline. The pointer for the scroll value. } win.story["selected"] = [["marker", markername]] win.current["tool"] = "grab" win.current["LMB"] = [win.current["mx"], win.current["my"], True] UI_elements.roundrect(layer, win, 5, 305, 40, 40, 10, do, "pin", talk.text("marker_tooltip"), url="story_editor") # Renders def do(): print("Renders") UI_elements.roundrect(layer, win, 5, 405, 40, 40, 10, do, "render", talk.text("render_lists_tooltip"), url="story_editor") # Edit Video def do(): print("Edit Video") UI_elements.roundrect(layer, win, 5, 455, 40, 40, 10, do, "vse", talk.text("vse_tooltip"), url="story_editor") # Bottom # Multiuser def do(): win.url = "multiuser_layer" UI_elements.roundrect(layer, win, 5, win.current["h"]-95, 40, 40, 10, do, "multiuser", talk.text("multiuser_tooltip"), url="story_editor") # Settings def do(): win.url = "settings_layer" UI_elements.roundrect(layer, win, 5, win.current["h"]-45, 40, 40, 10, do, "settings", talk.text("Settings"), url="story_editor") ###### RIGHT PANNEL ####### def select_character(win, var): print (var) # Characters def do(): studio_dialogs.asset_select(win, "new_asset_story", select_character, force=True, cur="chr") UI_elements.roundrect(layer, win, win.current["w"]-45, 105, 40, 40, 10, do, "chr", talk.text("chr"), url="story_editor") # Vehicles def do(): studio_dialogs.asset_select(win, "new_asset_story", select_character, force=True, cur="veh") UI_elements.roundrect(layer, win, win.current["w"]-45, 155, 40, 40, 10, do, "veh", talk.text("veh"), url="story_editor") # Locations def do(): studio_dialogs.asset_select(win, "new_asset_story", select_character, force=True, cur="loc") UI_elements.roundrect(layer, win, win.current["w"]-45, 205, 40, 40, 10, do, "loc", talk.text("loc"), url="story_editor") # Other (obj) def do(): studio_dialogs.asset_select(win, "new_asset_story", select_character, force=True, cur="obj") UI_elements.roundrect(layer, win, win.current["w"]-45, 255, 40, 40, 10, do, "obj", talk.text("obj"), url="story_editor") # Sounds / Music def do(): print("Sounds / Music") UI_elements.roundrect(layer, win, win.current["w"]-45, 355, 40, 40, 10, do, "mus", talk.text("mus"), url="story_editor") # Folder def do(): os.system("xdg-open "+win.project) UI_elements.roundrect(layer, win, win.current["w"]-45, win.current["h"]-75, 40, 40, 10, do, "folder", talk.text("project_folder"), url="story_editor") ####### NODES ####### # Clipping so it wont draw beyon the frame UI_elements.roundrect(layer, win, 50, 50, win.current["w"] - 100, win.current["h"] - 80, 30, fill=False) layer.clip() # Background Image if os.path.exists(win.project+"/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) else: UI_elements.image(layer, win, "icon.png", 50, 50, win.current["w"] - 100, win.current["h"] - 80) UI_color.set(layer, win, "node_background") layer.rectangle(0,0,win.current["w"], win.current["h"]) layer.fill() # You probably intersted where is the scroll function for this part. Well # see there is a thing. It's easier to write one from screach here. Because # you geassed it we are starting to draw story editor. # Let's prepare the camera first. # Animation win.story["camera"][0] = UI_elements.animate("cameraX", win, 0, win.story["camera"][0]) win.story["camera"][1] = UI_elements.animate("cameraY", win, 0, win.story["camera"][1]) cx, cy = win.story["camera"] if win.url == "story_editor": if win.current["MMB"]: win.story["camera"][0] += ( win.current["mx"]-win.previous["mx"]) win.story["camera"][1] += ( win.current["my"]-win.previous["my"]) win.story["camera"][0] -= win.current["scroll"][0]*50 win.story["camera"][1] -= win.current["scroll"][1]*50 if cx != win.story["camera"][0] or cy != win.story["camera"][1]: UI_elements.animate("cameraX", win, win.story["camera"][0], force=True) UI_elements.animate("cameraY", win, win.story["camera"][1], force=True) # EVENTS (Frames) for event in win.story["events"]: # Loaction sx, sy = win.story["events"][event]["position"] # Scale ssx, ssy = win.story["events"][event]["size"] #Draw studio_nodes.event_node(layer, win, sx, sy, ssx, ssy, name=event) # SCENES for scene in win.story["scenes"]: # Loaction sx, sy = win.story["scenes"][scene]["position"] sx = sx + cx sy = sy + cy # Scale ssx, ssy = win.story["scenes"][scene]["size"] #Fraction sf = win.story["scenes"][scene]["fraction"] #Draw studio_nodes.scene_node(layer, win, sx, sy, ssx, ssy, name=scene, fraction=sf) # LINKS (Images, Stuff) for num, link in enumerate(win.story["links"]): linktype = link[0] linkname = link[1] lx = link[2][0] + cx ly = link[2][1] + cy studio_nodes.link_node(layer, win, lx, ly, name=linkname, num=num, linktype=linktype ) # Let's put in the start and the end nodes. These are drawn on top of # everything. studio_nodes.start_node(layer, win, 60,60,100,40) studio_nodes.end_node(layer, win, win.current["w"] - 160, win.current["h"] - 80, 100,40) # MARKERS try: for marker in win.story["markers"]: mx = win.story["markers"][marker][0] + cx my = win.story["markers"][marker][1] + cy studio_nodes.marker(layer, win, marker, mx, my) except: pass # In case there is a selection bug if not win.story["selected"] and win.current["tool"] != "connect": win.current["tool"] = "selection" # Selector visualization if win.current["LMB"] and win.current["tool"] == "selection" and win.url == "story_editor": # Draw selection box UI_color.set(layer, win, "progress_background") layer.rectangle( win.current["mx"], win.current["my"], win.current["LMB"][0] - win.current["mx"], win.current["LMB"][1] - win.current["my"] ) layer.stroke() # Now let's draw the cool AF multi selection zone thingy # Draw selection box if len(win.story["selected"]) > 1 and win.current["tool"] == "selection": UI_color.set(layer, win, "progress_background") layer.rectangle( win.szone[0][0]-10, win.szone[0][1]-10, win.szone[1][0]+20, win.szone[1][1]+20 ) layer.stroke() # Now I want to make a tiny widget that will resize the stuff. if win.story["selected"]: if win.current["tool"] == "selection": draw_circle = True if len(win.story["selected"]) == 1: if win.story["selected"][0][0] != "scene": draw_circle = False if draw_circle: UI_color.set(layer, win, "node_badfile") UI_elements.roundrect(layer, win, win.szone[0][0]+win.szone[1][0], win.szone[0][1]+win.szone[1][1], 0, 0, 10) UI_color.set(layer, win, "progress_background") UI_elements.roundrect(layer, win, win.szone[0][0]+win.szone[1][0], win.szone[0][1]+win.szone[1][1], 0, 0, 10, fill=False) layer.stroke() elif win.current["tool"] == "scale": UI_color.set(layer, win, "node_badfile") UI_elements.roundrect(layer, win, win.current["mx"]-10, win.current["my"]-10, 0, 0, 10) UI_color.set(layer, win, "progress_background") UI_elements.roundrect(layer, win, win.current["mx"]-10, win.current["my"]-10, 0, 0, 10, fill=False) layer.stroke() if int(win.current["mx"]) in range(int(win.szone[0][0]+win.szone[1][0]), int(win.szone[0][0]+win.szone[1][0]+20))\ and int(win.current["my"]) in range(int(win.szone[0][1]+win.szone[1][1]), int(win.szone[0][1]+win.szone[1][1]+20))\ and win.current["tool"] == "selection": UI_color.set(layer, win, "text_normal") UI_elements.roundrect(layer, win, win.szone[0][0]+win.szone[1][0], win.szone[0][1]+win.szone[1][1], 0, 0, 10, fill=False) layer.stroke() if win.current["LMB"] and not win.previous["LMB"]: win.current["tool"] = "scale" if win.current["tool"] == "scale" and not win.current["LMB"]: win.current["tool"] = "selection" # Canceling seletion. I move it here so it would not interfire with the # the rest of the program. if win.current["LMB"] and win.current["tool"] == "selection" and win.url == "story_editor": # Undo selection if int(win.current["LMB"][0] - win.current["mx"]) in range(-10, 10)\ and int(win.current["LMB"][1] - win.current["my"])in range(-10, 10)\ and 65505 not in win.current["keys"]: win.story["selected"] = [] # Let's draw the line while connecting 2 scenes together. if win.current["tool"] == "connect": if not win.current["LMB"]: win.current["tool"] = "selection" fr = win.current["draw_dot"] if type(fr) == list: fr = fr[0]+":"+fr[1] try: UI_color.set(layer, win, "node_script") layer.move_to( win.out_dots[fr][0], win.out_dots[fr][1] ) layer.line_to(win.current["mx"], win.current["my"]) layer.stroke() except: pass # To selected if 65454 in win.current["keys"] and win.story["selected"] and not win.textactive: nex = cx-win.szone[0][0] - win.szone[1][0]/2 + win.current["w"]/2 ney = cy-win.szone[0][1] - win.szone[1][1]/2 + win.current["h"]/2 UI_elements.animate("cameraX", win, win.story["camera"][0],nex, force=True) UI_elements.animate("cameraY", win, win.story["camera"][1],ney, force=True) # Grab if 103 in win.current["keys"] and win.story["selected"] and not win.textactive: win.current["tool"] = "grab" win.current["LMB"] = [win.current["mx"], win.current["my"], True] # Scale if 115 in win.current["keys"] and win.story["selected"] and not win.textactive: win.current["tool"] = "scale" win.current["LMB"] = [win.current["mx"], win.current["my"], True] # Deletion if 65535 in win.current["keys"] and win.current["tool"] == "selection"\ and win.url == "story_editor" and win.story["selected"] and not win.textactive: win.url = "story_deletion_dialog" return surface