123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- # 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
- import time
- import threading
- # 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. #
- from network import http_client # # #
- # # #
- ################################################### ########################
- # ^
- # |
- # 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.
- }
-
- def http_client_dialog(win, name, call, function, args=""):
-
- # This function is going to be the UI for http-client.
-
- 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" :"http-server",
- "back":win.url,# This is where it's going to come back when it's done
- "draw":http_client.layer
- }
-
- # Let's clear the LMB just in case
- win.previous["LMB"] = False
-
- # Some variables to pass so the function.
- win.current["http-server"] = {
- "args" :args, # arguments to the function
- "progress":0, # progress of that function
- "fileprog":0, # progress for a file download
- "call" :name, # The call to stop the process
- "message" :"", # message about the progress
- "started" :time.time()# current time ( to calculate progress completion )
- }
- # Let's now run the function
- function_run = threading.Thread(target=function, args=(win,))
- function_run.setDaemon(True)
- function_run.start()
- def http_client_update_prompt(win, name, call):
-
- # This function is going to be the UI for http-client.
-
- 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" :"http-server-prompt",
- "back":win.url,# This is where it's going to come back when it's done
- "draw":http_client.prompt_layer
- }
-
- # Let's clear the LMB just in case
- win.previous["LMB"] = False
|