# THIS FILE IS A PART OF VCStudio # PYTHON 3 # This a console project manager. import os import datetime import re # GTK module ( Graphical interface import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk from gi.repository import GLib from gi.repository import Gdk import cairo # Own modules from settings import settings from settings import talk from settings import fileformats from settings import oscalls from project_manager import pm_project #UI modules from UI import UI_elements from UI import UI_color # story from studio import story from studio import checklist from studio import analytics from studio import studio_dialogs from studio import schedule from studio import history 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() ############################################################################ # This is a file that will draw the text editor of VCStudio. The idea is that # you not only work on making the movie in VCStudio, but the script to the # movie is also written in VCStudio. This was already implemented in Blender- # Organizer legacy. And already implemented partially in VCStudio. As there # is story editor in place where you can add empty scenes. Or deal with # scenes that are converted from legacy. # But as you may guess by the time I'm writting it there is no way of editing # those scene's contents. Or read them in full. ( You can see peaces in the # assets ) # The implementation of the editor will be different from Blender-Organizer's # where I used an off the shelf GTK text writting widget. # The problem was that I could not really do much with that widget appart from # text. Don't get me wrong it was good for text. But I could not make for # example custom ways of drawing particular parts. Like what if I want a # round-rectangle arround each frase that the crachater's say. Or what if I # want to draw some custom UI buttons somewhere in the text. Stuff like this. # Which resulted in a weird workflow. I had a pretty script preview thing. # and another non-pretty script preview thing. And a script writer thing where # you type in code to mark thing. Very non pretty. Non user-friendly. And # you had to learn the code. And stuff. Yeah... # So here I want to make more of traditional editor. Where you see what you are # editing as you editing it. Hopefully it's going to work. ############################################################################ ####### TOP PANEL ######### UI_color.set(layer, win, "node_background") UI_elements.roundrect(layer, win, win.current["w"]/4, 10, win.current["w"]/2, 50, 10) # Let's add the toolbar. There is not a lot of tools we need. Since it's # a program only for writting a script. # Mark Shot # Mark Asset # Start Dialogue # Link Image # MARK SHOT def do(): print("Mark Shot") UI_elements.roundrect(layer, win, win.current["w"]/4+5, 15, 40, 40, 10, do, "shot_new", talk.text("add_shot_tooltip")) # MARK ASSET def do(): print("Mark ASSET") UI_elements.roundrect(layer, win, win.current["w"]/4+55, 15, 40, 40, 10, do, "obj_link", talk.text("add_shot_tooltip")) # Do DIALOGUE def do(): print("Mark Phrase") UI_elements.roundrect(layer, win, win.current["w"]/4+105, 15, 40, 40, 10, do, "frase_new", talk.text("add_phrase_tooltip")) # ADD IMAGE def do(): print("Add Image") UI_elements.roundrect(layer, win, win.current["w"]/4+155, 15, 40, 40, 10, do, "image_link", talk.text("add_image_script_tooltip")) # Next part is to add the scene name editor. It's not as easy as you might # thing. Since every scene's shot might contain an actuall folder on the # operating system after you create a first blend file to animate the shot. # So there will be a folder for the scene with many folders for shots inside. # And if you change the name of the scene in the story you probably want to # change the name of the scene in the folder as well. BUT. Since there could # be countless blend files inside. And some names just could be already taken # and stuff like that, I will block the editing of the scene if a folder exists. # And will give a folder icon. # Technically it's going to be possible to rename the scene. By renaming the # folder first. But this is a kind of breaking everything operation i don't # want to implement inside the VCStudio it self. I give constant folder links # so editing of files could be done by the user at any time. # But I don't want it to feel easy. Since stuff like deleting assets or # editing names could break things in a different place in the program. That's # why I don't provide easy to use functions for it. The user should really # decide to make a change like this. To the point of breaking the convinience # of VCStudio. # Parsing the url if win.cur.count("/") > 1: tmp = win.cur.replace("/","",1).split("/") scene, shot = tmp[0], tmp[1] else: scene = win.cur[win.cur.rfind("/")+1:] shot = "" # Let's find out if a folder exists. if os.path.exists(win.project+"/rnd/"+scene): editable = False minus = 50 # The minus is the width of the folder button def do(): oscalls.Open(win.project+"/rnd/"+scene) UI_elements.roundrect(layer, win, win.current["w"]/4*3-45, 15, 40, 40, 10, do, "folder", tip="/rnd/"+scene) else: editable = True minus = 0 UI_elements.text(layer, win, "scene_name", win.current["w"]/4+205, 15, win.current["w"]/2-210-minus, 40, set_text=scene, editable=editable, fill=False) # Now let's do the actual edititing part. What we want to look for is whether # the key already exists in the scenes, if not allow it to be applied. Now # you are probably asking yourself. But the current scene exists there? So # how could you apply it. Easy. If you change anything. It already doesn't # exist there. And if you didn't change anything. What's the point of applying # anyway? So here what we are going to do. newname = win.text["scene_name"]["text"].replace("/","_").replace(" ", "_")\ .replace('"',"_").replace("(","_").replace(")","_").replace("'","_")\ .replace("[","_").replace("]","_").replace("{","_").replace("}","_") if newname not in win.story["scenes"]: def do(): win.story["scenes"][newname] = win.story["scenes"].pop(scene) win.text["scene_name"]["text"] = newname win.cur = newname # There is one more rub. Scenes could be connected together. # so now we need to preserve the connections as well. This is # not that hard. for arrow in win.story["arrows"]: if arrow[0][1] == scene: arrow[0][1] = newname if arrow[1][1] == scene: arrow[1][1] = newname # Easy. I like how if it's a list. it's a link to the list. # so there will not be memory overdrives. So I can itterate # over a list of lists and assing values of to the itteration # and not trying to get the main list. LOVELY. # Saving to the file story.save(win.project, win.story) UI_elements.roundrect(layer, win, win.current["w"]/4*3-45, 15, 40, 40, 10, do, "ok", tip=talk.text("checked")) # Just in case parsing the url again if win.cur.count("/") > 1: tmp = win.cur.replace("/","",1).split("/") scene, shot = tmp[0], tmp[1] else: scene = win.cur[win.cur.rfind("/")+1:] shot = "" ######### MAIN PART ########### # Oh dear. I have no idea how hard it's going to be. But let's try. I don't # thing it's going to be that insane. But I need to take in consideration # a couple of things. Mainly text warping. Meaning I'm probably rendering # each word as an individual object. Now this creates a challenge. # How do I mark parts of the text having more then 1 word it it? I probably # will need to draw a couple layers at ones. # TEXT LAYER # SHOTS MARKING LAYER # ASSET MARKING LAYER # And then combine them in a different order # SHOT MARKING LAYER # ASSET MARKING LAYER (on top) # TEXT LAYER (on top of everything) # So let's make those 3 layers. x = win.current["w"]/4 y = 70 width = win.current["w"]/2 -30 height = win.current["h"]-130 # Good that at least all layers have the same size. textsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height)) text = cairo.Context(textsurface) text.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) shotsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height)) shots = cairo.Context(shotsurface) shots.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) assetsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height)) assets = cairo.Context(assetsurface) assets.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) ########################### # Oh dear # Clips: UI_elements.roundrect(text, win, 0,0,width, height, 10,fill=False) text.clip() UI_elements.roundrect(shots, win, 0,0,width, height, 10,fill=False) shots.clip() UI_elements.roundrect(assets, win, 0,0,width, height, 10,fill=False) assets.clip() # Background UI_color.set(shots, win, "node_background") shots.rectangle(0,0,width, height) shots.fill() if "script" not in win.scroll: win.scroll["script"] = 0 tileX = 12 current_Y = 0 # For highlights if "script_asset_higlight" not in win.current: win.current["script_asset_higlight"] = "" if "script_shot_higlight" not in win.current: win.current["script_shot_higlight"] = "" pointer = [0,0] # The editing cursor point = 0 # The current place in the scene if scene in win.story["pointers"]: pointer = win.story["pointers"][scene] # Removing highlight if int(win.current["mx"]) not in range(int(win.previous["mx"])-1, int(win.previous["mx"])+1)\ and int(win.current["my"]) not in range(int(win.previous["my"])-1, int(win.previous["my"])+1): win.current["script_asset_higlight"] = "" win.current["script_shot_higlight"] = "" # Okay I guess let's itterrate over the scene and see what's going to happen shotpart = 0 shotis = "" ss = 0 # THE START OF SELECTION BOX frasepart = 0 # Okay so nothing is in the scene we want to create a text block of 1 character # into the scene. Because if it will have 0 characters it will be automatically # deleted. if not win.story["scenes"][scene]["shots"]: win.story["scenes"][scene]["shots"] = [[ "text_block",[["text", ' ']] ]] for num, block in enumerate(win.story["scenes"][scene]["shots"]): # IF NOTHING IN THE PART if not block[-1]: del win.story["scenes"][scene]["shots"][num] if win.current["script_find"][0] and win.current["script_find"][0] == num: win.scroll["script"] = 0-current_Y+height/2 win.current["script_find"][0] = 0 for n, part in enumerate(block[-1]): # IF NOTHING IN THE PART if not part[-1]: del block[-1][n] if win.current["script_find"][1] and win.current["script_find"][1] == n: win.scroll["script"] = 0-current_Y+height/2 win.current["script_find"][1] = 0 t = part[-1] p = point count_newlines = t.count("\n") xb = 12 # Where is the start of the line mt = width # Where is the maximum width ##### FRASE ##### if part[0] == "frase": if ss: UI_color.set(text, win, "progress_background") text.rectangle( ss, win.scroll["script"] + current_Y, mt-ss, 30) text.stroke() current_Y = current_Y + 30 if part[1][0] == "link": UI_color.set(assets, win, "node_asset") UI_elements.roundrect(assets, win, width/2-len(part[1][-1])*6-6, win.scroll["script"] + current_Y+6, len(part[1][-1])*12+12, 28, 10) if int(win.current['mx']) in range(int(x+width/2-len(part[1][-1])*6-6), int(x+width/2-len(part[1][-1])*6-6+len(part[1][-1])*12+12)) \ and int(win.current['my']) in range(int(y+win.scroll["script"] + current_Y+8), int(y+win.scroll["script"] + current_Y+8+22)) : win.current["script_asset_higlight"] = part[1][1] if part[1][1] == win.current["script_asset_higlight"]: UI_color.set(assets, win, "progress_background") UI_elements.roundrect(assets, win, width/2-len(part[1][-1])*6-6, win.scroll["script"] + current_Y+6, len(part[1][-1])*12+12, 28, 10, fill=False) assets.stroke() # So here I want to put a button for editing the name of the phrase. if "current_name_frase_editing" not in win.current: win.current["current_name_frase_editing"] = False def do(): if not win.previous["current_name_frase_editing"]: print(part[1][-1]) win.current["current_name_frase_editing"] = [num, n] if "current_name_frase_editing" in win.text: win.text["current_name_frase_editing"]["text"] = part[1][-1] UI_elements.roundrect(assets, win, 200, win.scroll["script"] + current_Y+6, width-400, 28, 10, button=do, offset=[x,y]) # Now let's drawa little text editor with in a text editor. IK wild. # but since everything is custom I can do wild things. if win.current["current_name_frase_editing"] == [num, n]: UI_elements.text(text, win, "current_name_frase_editing", 200, win.scroll["script"] + current_Y-5, width-400, 40, set_text=part[1][-1], offset=[x,y]) # Here I will add some logic to this little editor with in # editor. OMG WHAT AM I DOING? # First let's make the apply button. And I guess the enter key. if win.text["current_name_frase_editing"]["text"] != part[1][-1]: def do(): part[1][-1] = win.text["current_name_frase_editing"]["text"] win.current["current_name_frase_editing"] = False win.current["LMB"] = False win.previous["LMB"] = False win.textactive = False win.current["key_letter"] = "" UI_elements.roundrect(text, win, width-280, win.scroll["script"] + current_Y-5, 40, 40, 10, button=do, icon="ok", offset=[x,y]) if 65293 in win.current["keys"]: do() win.current["keys"] = [] else: UI_color.set(text, win, "text_normal") text.set_font_size(20) text.move_to( width/2-len(part[1][-1])*6, win.scroll["script"] + current_Y+25, ) text.show_text(part[1][-1]) #point = point + len(part[1][-1]) #################### <<<<<< POINT current_Y = current_Y + 35 frasepart = current_Y xb = 212 mt = width - 200 tileX = xb if ss: ss = xb if frasepart and part[0] != "frase": UI_color.set(assets, win, "dark_overdrop") UI_elements.roundrect(assets, win, 200, win.scroll["script"] + frasepart, width-400, current_Y - frasepart+40, 10) frasepart = 0 #### IMAGE ### if part[0] == "image": current_Y = current_Y + 30 if os.path.exists(win.project+t): UI_elements.image(text, win, win.project+t, 100, win.scroll["script"] + current_Y, int(width)-200, 380, cell="script_images") else: UI_elements.image(text, win, t, 100, win.scroll["script"] + current_Y, int(width)-200, 380, cell="script_images") current_Y = current_Y + 400 continue assetpart = 0 assetis = "" ### TEXT IT SELF ### for line in re.split("(\n)",t): count_spaces = t.count(" ") if line == "\n": tileX = xb point = point + 1 #################### <<<<<< POINT if assetpart: assetpart = xb if shotpart: shotpart = xb if ss: UI_color.set(text, win, "progress_background") text.rectangle( ss, win.scroll["script"] + current_Y, mt-ss, 30) text.stroke() ss = xb current_Y = current_Y + 30 continue for word in re.split("( )", line): # IF TOO MUCH. DO NEXT LINE if tileX + len(word)*12 > mt: tileX = xb if assetpart: assetpart = xb if shotpart: shotpart = xb if ss: UI_color.set(text, win, "progress_background") text.rectangle( ss, win.scroll["script"] + current_Y, mt-ss, 30) text.stroke() ss = xb current_Y = current_Y + 30 # DRAWING ASSET HIGLIGHT if part[0] == "link" and part[1] != assetis and not assetpart: assetpart = tileX assetis = part[1] if assetpart: if word: UI_color.set(assets, win, "node_asset") UI_elements.roundrect(assets, win, assetpart-5, win.scroll["script"] + current_Y+8, tileX - assetpart + len(word)*12+12, 22, 10) # Selectiong asset. ( Not actually.) But making a # highlight of the asset. And if clicked. Going # to the asset. if int(win.current['mx']) in range(int(x+assetpart-5), int(x+tileX + len(word)*12+12)) \ and int(win.current['my']) in range(int(y+win.scroll["script"] + current_Y+8), int(y+win.scroll["script"] + current_Y+8+22)) : win.current["script_asset_higlight"] = assetis if assetis == win.current["script_asset_higlight"]: UI_color.set(assets, win, "progress_background") UI_elements.roundrect(assets, win, assetpart-5, win.scroll["script"] + current_Y+8, tileX - assetpart + len(word)*12+12, 22, 10, fill=False) assets.stroke() assetpart = tileX assetis = part[1] if part[0] != "link": assetpart = 0 assetis = "" ## HIGLIGHTING SHOTS ## if block[0] == "shot_block" and block[1] != shotis and not shotpart: shotpart = tileX shotis = block[1] if shotpart: if word: # I want to randomize the shots colors. But I don't it to be an epileptic # show. rcolors = [ "node_imagefile", "node_videofile", "darker_parts", "node_blendfile", "node_badfile", "progress_time" ] col = rcolors[num % len(rcolors)] if int(win.current['mx']) in range(int(x+shotpart-5), int(x+tileX + len(word)*12+12)) \ and int(win.current['my']) in range(int(y+win.scroll["script"] + current_Y+8), int(y+win.scroll["script"] + current_Y+8+22)) : win.current["script_shot_higlight"] = shotis UI_color.set(shots, win, col) if shotis == win.current["script_shot_higlight"] or shot == shotis: UI_color.set(shots, win, "node_script") UI_elements.roundrect(shots, win, shotpart-6, win.scroll["script"] + current_Y+5, tileX - shotpart + len(word)*12+12, 28, 10) shotpart = tileX shotis = block[1] if block[0] != "shot_block": shotpart = 0 shotis = "" # This is our word UI_color.set(text, win, "text_normal") text.set_font_size(20) text.move_to( tileX, win.scroll["script"] + current_Y+25, ) text.show_text(word) # DRAWING SELECTION ALPHA if 65363 in win.current["keys"]: pointer[0] = pointer[0]+1 if not 65506 in win.current["keys"]: pointer[1] = pointer[0] win.current["keys"].remove(65363) if 65361 in win.current["keys"]: pointer[0] = pointer[0]-1 if not 65506 in win.current["keys"]: pointer[1] = pointer[0] win.current["keys"].remove(65361) if 65362 in win.current["keys"]: # UP pointer[0] = pointer[0]-min(len(line), int((mt-12)/12)) # STILL BUGGY if not 65506 in win.current["keys"]: pointer[1] = pointer[0] win.current["keys"].remove(65362) if 65364 in win.current["keys"]: # DOWN pointer[0] = pointer[0]+min(len(line), int((mt-12)/12)) # STILL BUGGY if not 65506 in win.current["keys"]: pointer[1] = pointer[0] win.current["keys"].remove(65364) # PRESSING A KEY TO TYPE I GUESS if min(pointer[1], pointer[0]) in range(point, point+len(word)+1) and not ss: ss = tileX+(min(pointer[1], pointer[0])-point)*12 if max(pointer[1], pointer[0]) in range(point, point+len(word)+1): # DEVELOPING WHERE THE POINTER IS OMG if win.current["testing"]: try: c = part[-1][pointer[0]-p] except: c = "!!" UI_color.set(text, win, "text_normal") text.set_font_size(10) text.move_to( tileX+(max(pointer[1], pointer[0])-point)*12-26, win.scroll["script"] + current_Y+35, ) text.show_text(str(pointer[0])+"["+c+"]"+str(pointer[1])) if ss: UI_color.set(text, win, "progress_background") text.rectangle( ss, win.scroll["script"] + current_Y, tileX+(max(pointer[1], pointer[0])-point)*12-ss, 30) text.stroke() ss = 0 if win.current["key_letter"] and not win.textactive: try: ORD = ord(win.current["key_letter"]) except: ORD = 0 print(ORD) win.scroll["script"] = min(0 - current_Y + width/2, win.scroll["script"]) if ORD not in range(32) or ORD in range(127, 160): part[-1] = \ part[-1][:min(pointer[1], pointer[0])-p]+\ win.current["key_letter"]+\ part[-1][max(pointer[1], pointer[0])-p:] pointer[0] = pointer[0] + 1 pointer[1] = pointer[0] if ORD == 13: # ENTER if part[-1][min(pointer[1], pointer[0])-p-1] == "\n" and part[0] != "text": block[-1].insert(n+1, ["text", "\n"] ) block[-1].insert(n+2, ["text", part[-1][max(pointer[1], pointer[0])-p:]] ) part[-1] = \ part[-1][:min(pointer[1], pointer[0])-p-1] else: part[-1] = \ part[-1][:min(pointer[1], pointer[0])-p]+\ "\n"+\ part[-1][max(pointer[1], pointer[0])-p:] pointer[0] = pointer[0] + 1 pointer[1] = pointer[0] if ORD == 4: # CTRL D ( FOR SOME REASON) block[-1].insert(n+1, ["frase", ["text", " "], " "] ) block[-1].insert(n+2, ["text", part[-1][max(pointer[1], pointer[0])-p:]] ) part[-1] = \ part[-1][:min(pointer[1], pointer[0])-p] pointer[0] = pointer[0] + 1 pointer[1] = pointer[0] # Activating the editing of the name automatically if "current_name_frase_editing" in win.text: win.text["current_name_frase_editing"]["text"] = "" if "current_name_frase_editing" not in win.current: win.current["current_name_frase_editing"] = False win.current["current_name_frase_editing"] = [num, n+1] win.textactive = "current_name_frase_editing" if ORD == 8: # BACKSPACE if pointer[1] == pointer[0]: part[-1] = \ part[-1][:min(pointer[1], pointer[0])-p-1]+\ part[-1][max(pointer[1], pointer[0])-p:] pointer[0] = pointer[0] - 1 pointer[1] = pointer[0] else: part[-1] = \ part[-1][:min(pointer[1], pointer[0])-p]+\ part[-1][max(pointer[1], pointer[0])-p:] pointer[0] = min(pointer[1], pointer[0]) pointer[1] = pointer[0] if ORD == 127: # DELETE (FORWARD) part[-1] = \ part[-1][:min(pointer[1], pointer[0])-p]+\ part[-1][max(pointer[1], pointer[0])-p+1:] win.current["key_letter"] = "" print(block) print() # Now let's move the tileX point = point + len(word) #################### <<<<<< POINT tileX = tileX + len(word)*12 #if count_spaces: # point = point + 1 #################### <<<<<< POINT # tileX = tileX + 12 # count_spaces = count_spaces - 1 current_Y = current_Y + 30 if scene not in win.story["pointers"]: pointer = [point, point] win.story["pointers"][scene] = pointer else: pointer[0] = min(pointer[0], point) pointer[1] = min(pointer[1], point) pointer[0] = max(pointer[0], 0) pointer[1] = max(pointer[1], 0) win.story["pointers"][scene] = pointer # Selecting the shot if win.current["script_shot_higlight"] and win.previous["LMB"] and not win.current["LMB"]: win.cur = "/"+scene+"/"+win.current["script_shot_higlight"] # Going to that asset if win.current["script_asset_higlight"] and win.previous["LMB"] and not win.current["LMB"]: try: win.previous["script_asset_higlight"] win.url = "assets" win.cur = win.current["script_asset_higlight"] win.current["asset_scene_selected"] = scene win.current["asset_left_panel"] = "scene" del win.current["script_asset_higlight"] # Saving to the file story.save(win.project, win.story) except: pass ########################### # And finally combine the layers # Outputting the layer layer.set_source_surface(shotsurface, x, y) layer.paint() # Outputting the layer layer.set_source_surface(assetsurface, x, y) layer.paint() # Outputting the layer layer.set_source_surface(textsurface, x, y) layer.paint() # Scroll UI_elements.scroll_area(layer, win, "script", x+0, y+0, width+30, height-0, current_Y, bar=True, mmb=True, bar_always=True) ####### BOTTOM PANEL ######### UI_color.set(layer, win, "node_background") UI_elements.roundrect(layer, win, win.current["w"]/4, win.current["h"]-50, win.current["w"]/2, 40, 10) # Here in the bottom I want to introduce little things to go between scenes # back and forth. left = "" right = "" for arrow in win.story["arrows"]: if arrow[0][1] == scene and arrow[1] != "end": right = arrow[1][1] if arrow[1][1] == scene and arrow[0] != "start": left = arrow[0][1] if left: def do(): win.scroll["script"] = 0 win.cur = "/"+left win.url = "script" UI_elements.roundrect(layer, win, win.current["w"]/2-45, win.current["h"]-50, 40, 40, 10, button=do, icon="left") if right: def do(): win.scroll["script"] = 0 win.cur = "/"+right win.url = "script" UI_elements.roundrect(layer, win, win.current["w"]/2+5, win.current["h"]-50, 40, 40, 10, button=do, icon="right") # CANCEl def do(): win.url = "story_editor" win.assets = {} del win.text["scene_name"] win.story["selected"] = [] win.scroll["script"] = 0 UI_elements.roundrect(layer, win, win.current["w"]-40-win.current["w"]/4, win.current["h"]-50, 40, 40, 10, button=do, icon="cancel", tip=talk.text("cancel")) # Short cut ESC if 65307 in win.current["keys"] and not win.textactive: do() ############# CHECKLIST ################# if os.path.exists(win.project+"/rnd"+win.cur+"/shot.progress"): checklist.draw(layer, win, win.project+"/rnd"+win.cur+"/shot.progress", back=win.url) ############## LEFT PANEL ##################### leftpanellist = ["shot", "schedule", "history"] # Using the names of the icons. # We need to choose the correct category based smartly on the project's # current progress. Or at least on the current progress of this asset. if "script_left_panel" not in win.current: win.current["script_left_panel"] = "shot" # A little banner. UI_color.set(layer, win, "node_background") UI_elements.roundrect(layer, win, 10, 10, win.current["w"]/4-20, 50, 10) for num, thing in enumerate(leftpanellist): if win.current["script_left_panel"] == thing: UI_color.set(layer, win, "progress_time") UI_elements.roundrect(layer, win, 20+(40*num), 15, 40, 40, 10) def do(): win.current["script_left_panel"] = thing UI_elements.roundrect(layer, win, 20+(40*num), 15, 40, 40, 10, do, thing) ### SCHEDULES ### if win.current["script_left_panel"] == "schedule": schedule.draw(layer, win) ### HISTORY ### if win.current["script_left_panel"] == "history": history.draw(layer, win) return surface