2020-12-07 22:40:45 +01:00
|
|
|
# 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
|
|
|
|
|
2020-12-25 15:20:34 +01:00
|
|
|
################################################### ########################
|
|
|
|
# # #
|
|
|
|
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. #
|
|
|
|
# # #
|
|
|
|
################################################### ########################
|
2020-12-07 22:40:45 +01:00
|
|
|
|
2020-12-25 15:20:34 +01:00
|
|
|
# ^
|
|
|
|
# |
|
2020-12-07 22:40:45 +01:00
|
|
|
|
2020-12-25 15:20:34 +01:00
|
|
|
# Who does that?
|
2020-12-07 22:40:45 +01:00
|
|
|
|
2020-12-09 03:29:21 +01:00
|
|
|
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=""):
|
2020-12-07 22:40:45 +01:00
|
|
|
|
|
|
|
# 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
|
|
|
|
}
|
|
|
|
|
2020-12-09 03:29:21 +01:00
|
|
|
# Now let's make a container to save those setting between frames
|
2020-12-07 22:40:45 +01:00
|
|
|
|
2020-12-09 03:29:21 +01:00
|
|
|
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"
|
|
|
|
|
2020-12-19 11:20:34 +01:00
|
|
|
# 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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-12-23 14:56:18 +01:00
|
|
|
# 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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-12-09 03:29:21 +01:00
|
|
|
# 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
|
2020-12-25 15:20:34 +01:00
|
|
|
|
|
|
|
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.
|
|
|
|
}
|