# THIS FILE IS A PART OF VCStudio # PYTHON 3 ################################################################################ # This file here will act like simple set of functions for the developer of the # software. But infect will be a little more complex behimith. To explain the # idea we need to look a little bit deeper into how this program functions and # draws UI peaces. # Basically every Layer py file is a set of instuction of how to draw a specific # UI on to the screen. Those function return the finished canvas. An image # basically. That the compositing layer (studio_gtk.py or pm_gtk.py ) combine # into a bigger picture. # There is a blur effect added to undernith layers if the top layer is drawn. # I do this by checking the win.url string. Each layer has they own urls. # Some are composited at all times. Some only if their url is the url. But all # get blurred if it's not their url. # Unfortunatly I can't make a function that will return a value. Because it means # to stop the drawing of the UI. And I need the UI to get to next frame in order # to draw the function's UI. # Let's say I want to add a link to an image to the story-editor. I click on the # add button. Next what I want to see is a searcher dialog appear. As soon as I # have selected the image I want to link, then the new link appears in the story # editor space which is automatically moving. Untill I place it. # For this I need to set up some kind of variable. And as soon as this variable # is not None. For example. We are doing the rest of the operation. # Step 0 : User Clicks the add button. And a funtion is called. # Step 1 : This function creates a dictionary with a variable NONE and a callable # Step 2 : win.url changes to the Layer which is the searcher. # Step 3 : User selects the images, or a file that he or she wanted to select. # Step 4 : This filename is being written into the variable that used to be NONE. # Step 5 : As soon as this variable is not NONE the callable is called. # Step 6 : This callable is the one that does the setup work. # Of course it would defeat the purpose if the callable always standard. It shold # be one of the inputs to the dialogue function. # Function template function_name(win, operation_name, callable): ################################################################################ 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 #UI modules from UI import UI_elements from UI import UI_color ################################################### ######################## # # # from studio import studio_file_selectLayer # # These modules he- # from studio import studio_asset_selectLayer # # re. Are the modu- # from studio import studio_shot_linkLayer # # les that are ac- # from studio import studio_asset_configureLayer # # tual UI of dialo- # from studio import studio_renderLayer # # gs that I was ta- # from studio import studio_vseLayer # # lking about at # from UI import UI_helpDialog # # the top. # # # # ################################################### ######################## # ^ # | # Who does that? def file_select(win, name, call, force=False, IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, LOC=True, OBJ=True, RND=False, FOLDER=False, SEARCH=""): # Forcing reload of the fileswin.current["AllFiles"] = [] try: del win.current["AllFiles"] except: pass # This function will select files for any kind of stuff. It will search # through the files of the project. Similar to image searcher in the old # organizer. if name not in win.current["calls"]: win.current["calls"][name] = { "var" :None, # This is the variable that we are waiting for "call":call, # This is what it's going to run when it's done "url" :"file_select", "back":win.url,# This is where it's going to come back when it's done "draw":studio_file_selectLayer.layer } # Now let's make a container to save those setting between frames if force or "file_selector" not in win.current: win.current["file_selector"] = { "image" :IMAGE, "blender":BLEND, "video" :VIDEO, "file" :FILE, "chr" :CHR, "veh" :VEH, "loc" :LOC, "obj" :OBJ, "vse" :RND, "folder" :FOLDER } # Search text win.text["file_select_search"] = { "text" :SEARCH, # Actuall text you are editing. "cursor":[len(str(SEARCH)),len(str(SEARCH))], # Cursor "insert":False, # Whether the insert mode is on "scroll":"file_select_search_scroll" # If multiline. The pointer for the scroll value. } # Let's activate the text so you could type immediatly win.textactive = "file_select_search" # Let's clear the LMB just in case win.previous["LMB"] = False def asset_select(win, name, call, force=False, cur="chr", SEARCH=""): # This function will be an asset selector. The idea it to be something # in between itemselector and assets in the same time. # If you remember # in the Blender-Organizer there were tabs on the top bar. If you click # on Characters let's say, you would get a full screen selector to enter # a given character. # But for linking and such you would get a small window with only names. # But with a search dialog. # Well this dialog will be some kind a merge of both of them. Having both # a very good cell-based preview type list and search. And could be used # not only to enter the asset, but also for linking and such. if name not in win.current["calls"]: win.current["calls"][name] = { "var" :None, # This is the variable that we are waiting for "call":call, # This is what it's going to run when it's done "url" :"asset_select", "back":win.url,# This is where it's going to come back when it's done "draw":studio_asset_selectLayer.layer } # Now let's make a container to save those setting between frames if force or "asset_cur" not in win.current: win.current["asset_cur"] = cur # Search text win.text["asset_select_search"] = { "text" :SEARCH, # Actuall text you are editing. "cursor":[len(str(SEARCH)),len(str(SEARCH))], # Cursor "insert":False, # Whether the insert mode is on "scroll":"asset_select_search_scroll" # If multiline. The pointer for the scroll value. } # Let's activate the text so you could type immediatly win.textactive = "asset_select_search" # Wiping the history of the assets. See studio/studio_asset_selectLayer.py win.assets = {} # Let's clear the LMB just in case win.previous["LMB"] = False def asset_link(win, name, call, filename, force=False): # This function will configure the linking of the assets into animation files # it's in theory a quite simple operation, but requires nesting of dialogs. # which is untested by the time I'm writting this comment. if name not in win.current["calls"]: win.current["calls"][name] = { "var" :None, # This is the variable that we are waiting for "call":call, # This is what it's going to run when it's done "url" :"asset_link", "back":win.url,# This is where it's going to come back when it's done "draw":studio_shot_linkLayer.layer } # let's prepare the data for this operation if force or "linking_asset_data" not in win.current\ or win.current["linking_asset_data"]["linking_to"] != filename: win.current["linking_asset_data"] = { "linking_to":filename, "assets":[], "read":False, "selected":"", "mode":"link", "fraction":0, "process":False } if win.current["linking_asset_data"]["fraction"]: win.current["linking_asset_data"]["assets"] = [] win.current["linking_asset_data"]["fraction"] = 0 # Wiping the history of the assets. See studio/studio_asset_selectLayer.py win.assets = {} # Let's clear the LMB just in case win.previous["LMB"] = False def asset_configure(win, name, call, asset, force=False): # This function going to configure assets. More deatailed explanation is # in the file: studio/studio_asset_configureLayer.py if name not in win.current["calls"]: win.current["calls"][name] = { "var" :None, # This is the variable that we are waiting for "call":call, # This is what it's going to run when it's done "url" :"asset_configure", "back":win.url,# This is where it's going to come back when it's done "draw":studio_asset_configureLayer.layer } # let's prepare the data for this operation if force or "asset_configure" not in win.current\ or win.current["asset_configure"]["asset"] != asset: win.current["asset_configure"] = { "asset":asset, "blend_to_copy":"", "collections":{}, "step3_button":"collection", "apply":False } # Wiping the history of the assets. See studio/studio_asset_selectLayer.py win.assets = {} # Let's clear the LMB just in case win.previous["LMB"] = False def render(win, name, call, filename="", force=False): # This function going to launch a window that shows all current renders and # confuge them. if name not in win.current["calls"]: win.current["calls"][name] = { "var" :None, # This is the variable that we are waiting for "call":call, # This is what it's going to run when it's done "url" :"render", "back":win.url,# This is where it's going to come back when it's done "draw":studio_renderLayer.layer } # let's prepare the data for this operation if force or "renders_window" not in win.current\ or win.current["renders_window"]["filename"] != filename: win.current["renders_window"] = { "filename":filename } # Wiping the history of the assets. See studio/studio_asset_selectLayer.py win.assets = {} # Let's clear the LMB just in case win.previous["LMB"] = False def vse(win, name, call, filename="", force=False): # This function going to select vse blend files. if name not in win.current["calls"]: win.current["calls"][name] = { "var" :None, # This is the variable that we are waiting for "call":call, # This is what it's going to run when it's done "url" :"vse", "back":win.url,# This is where it's going to come back when it's done "draw":studio_vseLayer.layer } # Let's clear the LMB just in case win.previous["LMB"] = False def help(win, name, call, filename="", force=False, SEARCH=""): # This function going to select vse blend files. if name not in win.current["calls"]: win.current["calls"][name] = { "var" :None, # This is the variable that we are waiting for "call":call, # This is what it's going to run when it's done "url" :"help", "back":win.url,# This is where it's going to come back when it's done "draw":UI_helpDialog.layer } # Let's clear the LMB just in case win.previous["LMB"] = False win.text["in_help"] = { "text" :SEARCH, # Actuall text you are editing. "cursor":[len(str(SEARCH)),len(str(SEARCH))], # Cursor "insert":False, # Whether the insert mode is on "scroll":"in_help_search_scroll" # If multiline. The pointer for the scroll value. }