123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664 |
- # THIS FILE IS A PART OF VCStudio
- # PYTHON 3
- import os
- from subprocess import *
- # 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 oscalls
- from settings import talk
- from settings import fileformats
- 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 analytics
- from studio import history
- from studio import studio_dialogs
- from studio import history
- def link_from_script(win):
-
- #########################################################################
-
- # This file is here because there are multiple places in the window where
- # I want to link assets based on what's written in the text of the script.
-
- # So this file will basically parse the text and add the assets it finds
- # linked to the link list.
-
- #########################################################################
-
- print("Reading from the scene")
-
- # Fist we need to know what scene and shot are we.
-
- if win.cur.count("/") > 1:
- tmp = win.cur.replace("/","",1).split("/")
- scene, shotis = tmp[0], tmp[1]
- else:
- scene = win.cur[win.cur.rfind("/")+1:]
- shotis = ""
-
- print(scene, shotis)
-
- # Now let's read through the scene.
-
- for shot in win.story["scenes"][scene]["shots"]:
-
-
- # Ignore the non shots.
- if shot[0] != "shot_block":
- continue
-
- # Ingore all other shots.
- if shot[1] != shotis:
- continue
-
- # Let's read the shot
- for asset in shot[-1]:
- # Ignore text
- if asset[0] == "text":
- continue
-
- # It's it's a staight up link. Just add it.
- if asset[0] == "link" and "/dev"+asset[1] not in win.current["linking_asset_data"]["assets"]:
- win.current["linking_asset_data"]["assets"].append("/dev"+asset[1])
-
- # It's a link in a frase.
- if asset[0] == "frase" and asset[1][0] == "link" and "/dev"+asset[1][1] not in win.current["linking_asset_data"]["assets"]:
- win.current["linking_asset_data"]["assets"].append("/dev"+asset[1][1])
-
-
- def layer(win, call):
-
- # 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()
-
-
-
- UI_color.set(layer, win, "node_background")
- UI_elements.roundrect(layer, win,
- 40,
- 40,
- win.current["w"]-80,
- win.current["h"]-80,
- 10)
-
-
- ##############################################################################
- # This file is configuring and lanunching the linking into blend files. But it's
- # not the only file in the chain of files that is responsible for this operation.
- # For example the linking it self does studio/bpy_do_linking.py that is running
- # inside blender and communicates with this file for the UI side of things.
- ##############################################################################
-
- # Okay
- if not win.current["linking_asset_data"]["fraction"]:
- def do():
-
- # Before we start let's record the history for it.
-
- history.record(win, win.project+win.current["linking_asset_data"]["linking_to"], "[Linked]")
-
- if not win.current["linking_asset_data"]["process"]:
-
- # So this is an apply button. I know it's a little not in the right
- # order. So please read the rest of the file to see what it does.
-
- # So now when a person clicks okay. We first need to save the
- # autolink.data.
-
- datafile = open(win.project+"/rnd"+win.cur+"/extra/autolink.data", "w")
- for asset in win.current["linking_asset_data"]["assets"]:
- datafile.write("Link : "+asset+"\n")
-
- # Also let's write the mode. Because it's important.
- datafile.write("Mode : "+win.current["linking_asset_data"]["mode"]+"\n")
-
- datafile.close()
-
- # Okay... now that we have the file. We can start the process of linking
- # Which will be done using Blender. So let's get blender's url
-
- blenderpath = oscalls.get_current_blender(win)
-
- # Now here is the fun part. We gonna start a background process
- # open there blender and will start linking stuff.
-
- win.current["linking_asset_data"]["process"] = Popen(['stdbuf', '-o0', blenderpath, \
- "-b", win.project+win.current["linking_asset_data"]["linking_to"], \
- "-P", os.getcwd()+"/studio/bpy_do_linking.py"],\
- stdout=PIPE, universal_newlines=True)
-
- win.current["linking_asset_data"]["fraction"] = 0.01
-
- # Hell of a command isn't it.
-
- UI_elements.roundrect(layer, win,
- win.current["w"]-120,
- win.current["h"]-80,
- 40,
- 40,
- 10,
- button=do,
- icon="ok",
- tip=talk.text("checked"),
- url="asset_link")
-
- # Documentation entry
- def do():
- def after(win, var):
- pass
-
- studio_dialogs.help(win, "help", after, SEARCH=talk.text("documentation_link_assets"))
-
- UI_elements.roundrect(layer, win,
- 300,
- 50,
- 40,
- 40,
- 10,
- do,
- "question")
-
- # CANCEl
- if not win.current["linking_asset_data"]["process"]:
- def do():
- if not win.current["linking_asset_data"]["process"]:
- win.current["calls"][call]["var"] = False
- win.assets = {}
-
- UI_elements.roundrect(layer, win,
- win.current["w"]-80,
- win.current["h"]-80,
- 40,
- 40,
- 10,
- button=do,
- icon="cancel",
- tip=talk.text("cancel"),
- url="asset_link")
-
- # Short cut ESC
- if 65307 in win.current["keys"] and not win.textactive:
- do()
-
- # Now let's prepare the ground for the next part.
-
-
-
- # Before we do anything we need to make sure that there is an autolink.data
- # file in the extra folder of the shot. But since this is a system that is
- # designed to be very simple on the user side. There could not even be the
- # extra folder. So...
-
- try:
- os.mkdir(win.project+"/rnd"+win.cur+"/extra")
- except:
- pass
-
- # Next thing will be to see if there is a file called autolink.data. And if
- # yes read from it. We are going to load the data into the memory.
-
- # So if there is nothing yet loaded let's try loading it from file. Try
- # because there nothing quarantees that the file exists. If file does not
- # exists we gonna populate it with assets from the shot. As marked in the
- # scene the user wrote. But it's going to be a separate function since I
- # want to make a button to do it.
-
- if not win.current["linking_asset_data"]["assets"] and not win.current["linking_asset_data"]["read"]:
-
- win.current["linking_asset_data"]["read"] = True
-
- try:
- datafile = open(win.project+"/rnd"+win.cur+"/extra/autolink.data")
- datafile = datafile.read()
- datafile = datafile.split("\n")
-
- for line in datafile:
- if line.startswith("Link : "):
- asset = line[7:]
- win.current["linking_asset_data"]["assets"].append(asset)
- except:
-
- # So if it fails to load the file. Probably because it's not created
- # yet. Let's load from the story. What's so bad about it?
-
- link_from_script(win)
-
- # Now keep in mind that to help the script that runs inside blender all
- # assets have /dev/ in their folder. So to reach /ast/ blend file we will
- # need to parse the link. It's not hard just reminding it here.
-
-
- # IK everything is all over the place in the file but...
- # If there is a process. We should be able to see what it does.
- # Draw like a litte progress bar and stuff
-
- if win.current["linking_asset_data"]["process"]:
-
- # Basically during the execution of the linking. I want to read the
- # output and give the user some feedback of what is going on.
-
- currentline = win.current["linking_asset_data"]["process"].stdout.readline()[:-1]
-
- # In the bpy_do_linking.py file there is an instruction to write
- # out a fraction of a current operation into terminal. Which is
- # piped into the VCStudio and I can read it. So we can use it
- # to draw a progress bar.
-
- if currentline.startswith("FRACTION:"):
- try:
- fraction = float(currentline.split(":")[1])
- win.current["linking_asset_data"]["fraction"] = fraction
- except:
- pass
-
- if currentline == "FINISHED":
- win.current["linking_asset_data"]["process"] = False
- win.current["linking_asset_data"]["fraction"] = 1
-
-
- # The prgoress bar:
- if win.current["linking_asset_data"]["fraction"]:
- fraction = win.current["linking_asset_data"]["fraction"]
-
- UI_color.set(layer, win, "progress_background")
- UI_elements.roundrect(layer, win,
- 70,
- win.current["h"]-75,
- (win.current["w"]-220),
- 0,
- 7)
-
- UI_color.set(layer, win, "progress_active")
- UI_elements.roundrect(layer, win,
- 70,
- win.current["h"]-75,
- (win.current["w"]-220)*fraction,
- 0,
- 7)
-
-
- # This file will fuel of nightmares. Okay. So while developping it I realzed
- # one little problem. Overrides are kind a still buggy. Tho it's good to
- # have them for future releases. And most of rigs work just fine.
-
- # The thing that I want to do is to give the user options. Let's say their
- # rig is broken when trying Library- Overrides but it's okay if you do
- # legacy Proxy thing. So why not give the user the option of doing both.
-
- # And also sometimes you just want to link and decide later what you do with
- # your rig.
-
- # So I gonna make 3 icons. 3 modes so to speak. LINK, OVERRIDE, PROXY.
-
- linkoptions = {
- "link":"link_mode_link",
- "override":"link_mode_overrides", # Icon / Mode : Tooltip
- "proxy":"link_mode_proxy"
- }
-
- for num, mode in enumerate(linkoptions):
-
- if win.current["linking_asset_data"]["mode"] == mode:
-
- UI_color.set(layer, win, "progress_time")
- UI_elements.roundrect(layer, win,
- 50+(40*num),
- 50,
- 40,
- 40,
- 10)
-
- def do():
- win.current["linking_asset_data"]["mode"] = mode
-
- UI_elements.roundrect(layer, win,
- 50+(40*num),
- 50,
- 40,
- 40,
- 10,
- do,
- mode,
- tip=talk.text(linkoptions[mode]))
-
- # Let's add a button that adds assets based on what's written in the script.
-
- def do():
- link_from_script(win)
-
- UI_elements.roundrect(layer, win,
- 200,
- 50,
- 40,
- 40,
- 10,
- do,
- "scene_new",
- tip=talk.text("link_add_from_scene"))
-
-
- if not os.path.exists(win.project+win.current["linking_asset_data"]["selected"]+"/autolink.data")\
- or not os.path.exists(win.project+win.current["linking_asset_data"]["selected"].replace("/dev/","/ast/")+".blend"):
-
- def do():
-
- def after(win, var):
- print(var)
-
- studio_dialogs.asset_configure(win, "configuring_asset", after,
- win.current["linking_asset_data"]["selected"].replace("/dev",""))
-
- UI_elements.roundrect(layer, win,
- 250,
- 50,
- 40,
- 40,
- 10,
- button=do,
- icon="link_configure")
-
-
-
- # That's it. Now we are clipping and drawing the assets them selves.
- UI_elements.roundrect(layer, win,
- 50,
- 100,
- win.current["w"]-100,
- win.current["h"]-200,
- 10,
- fill=False)
- layer.clip()
-
- tileX = 70
- current_Y = 0
-
- if "asset_link" not in win.scroll:
- win.scroll["asset_link"] = 0
-
- #############################
-
- # Let's draw the list of assets that the user chose.
-
- for num, asset in enumerate(win.current["linking_asset_data"]["assets"]):
-
- cur, name = asset.split("/")[2], asset.split("/")[3]
-
- if int(current_Y + win.scroll["asset_link"] + 100) in range(0-100, win.current["h"]):
-
- # Making the layer
- nodesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 170, 200)
- node = cairo.Context(nodesurface)
- node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
-
-
- UI_elements.roundrect(node, win,
- 0,
- 0,
- 170,
- 200,
- 10,
- fill=False)
-
- node.clip()
-
- # Background
- UI_color.set(node, win, "dark_overdrop")
- node.rectangle(0,0,170, 200)
- node.fill()
-
- # Banner
- UI_color.set(node, win, "node_asset")
-
- # Now the banner will be node_asset color if the asset is configured
- # but it could be not configured. Or not even have the asset blend.
- # so we need to quickly check both. And if any of them missing. Make
- # the banner a node_badfile color.
-
- warning = ""
-
- if not os.path.exists(win.project+asset+"/autolink.data")\
- or not os.path.exists(win.project+asset.replace("/dev/","/ast/")+".blend"):
- UI_color.set(node, win, "node_badfile")
-
- warning = "\n"+talk.text("link_asset_not_configured")
-
- # Let's do even cooler. And let's draw a thing arround the asset.
- node.set_line_width(10)
- UI_elements.roundrect(node, win,
- 0,
- 0,
- 170,
- 200,
- 10,
- fill=False)
-
- node.stroke()
- node.set_line_width(2)
-
- # Even cooler. Let's put a configuration button right into here
-
-
-
-
-
- node.rectangle(0,0,170, 20)
- node.fill()
-
- # Outputting the layer
- layer.set_source_surface(nodesurface,
- tileX-10,
- current_Y + win.scroll["asset_link"] + 120)
- layer.paint()
-
-
- # Previes image
-
- if os.path.exists(win.project+asset+"/renders/Preview.png"):
- UI_elements.image(layer, win, win.project+asset+"/renders/Preview.png",
- tileX,
- current_Y + win.scroll["asset_link"] + 140,
- 150,
- 150)
-
- elif os.path.exists(win.project+asset+"/renders/Preview.jpg"):
- UI_elements.image(layer, win, win.project+asset+"/renders/Preview.jpg",
- tileX,
- current_Y + win.scroll["asset_link"] + 140,
- 150,
- 150)
- else:
- UI_elements.image(layer, win, "settings/themes/"+win.settings["Theme"]+"/icons/"+cur+".png",
- tileX+55,
- current_Y + win.scroll["asset_link"] + 150+55,
- 150,
- 150)
-
-
-
- UI_color.set(layer, win, "text_normal")
- layer.set_font_size(12)
- layer.move_to(tileX,
- current_Y + win.scroll["asset_link"] + 135)
- layer.show_text(name[:22])
-
- # Let's make a selection of an asset so you could delete one. Or
- # do other stuff. Maybe.
-
- if win.current["linking_asset_data"]["selected"] == asset:
-
- layer.set_line_width(4)
- UI_color.set(layer, win, "progress_background")
- UI_elements.roundrect(layer, win,
- tileX-10,
- current_Y + win.scroll["asset_link"] + 120,
- 170,
- 200,
- 10,
- fill=False)
-
- layer.stroke()
- layer.set_line_width(2)
-
- # And the delete key.
-
- if 65535 in win.current["keys"]:
- try:
- win.current["linking_asset_data"]["assets"].remove(asset)
- except:
- pass
- win.current["keys"] = []
-
- # Button to activate it
- def do():
- win.current["linking_asset_data"]["selected"] = asset
-
- layer.set_line_width(4)
- UI_elements.roundrect(layer, win,
- tileX-10,
- current_Y + win.scroll["asset_link"] + 120,
- 170,
- 200,
- 10,
- button=do,
- tip=talk.text(cur)+": "+name+warning,
- fill=False,
- clip=[
- 50,
- 100,
- win.current["w"]-100,
- win.current["h"]-200
- ],
- url="asset_link")
-
- layer.stroke()
- layer.set_line_width(2)
-
- tileX += 200
-
- if tileX > win.current["w"]-220:
- tileX = 70
-
- current_Y += 230
-
-
- # Now here I want to put the add new one button. So you could add assets
- # to the stuff manually.
-
- def do():
-
- # Now this is going to be wild. Because I'm going to run a dialog with
- # in a dialog. And I hope that it's going to work.
-
- def after(win, var):
-
- # Funny that it's actually working.
- # Tho there is a little rub. If you press Cancel there is a bug that
- # makes nothing unusable. so...
-
- try:
- del win.current["calls"]["link_add_asset_select"]
- except:
- pass
-
-
- if var and "/dev"+var not in win.current["linking_asset_data"]["assets"]:
- win.current["linking_asset_data"]["assets"].append("/dev"+var)
-
- # So basically I want to add one only if there is not one already.
- # And then select it. So if the use gets which one is added or
- # whether it was already there.
-
- win.current["linking_asset_data"]["selected"] = "/dev"+var
-
- # And since it could allight with the add button. Let's clear the
- # click
-
- win.current["LMB"] = False
- win.previous["LMB"] = False
-
-
- studio_dialogs.asset_select(win, "link_add_asset_select", after)
-
- UI_elements.roundrect(layer, win,
- tileX-10,
- current_Y + win.scroll["asset_link"] + 120,
- 170,
- 200,
- 10,
- button=do,
- url="asset_link")
-
- UI_color.set(layer, win, "progress_background")
- UI_elements.roundrect(layer, win,
- tileX-10,
- current_Y + win.scroll["asset_link"] + 120,
- 170,
- 200,
- 10,
- fill=False)
- layer.stroke()
-
- UI_elements.image(layer, win,
- "settings/themes/"+win.settings["Theme"]+"/icons/asset_new.png",
- tileX+55,
- current_Y + win.scroll["asset_link"] + 200,
- 40, 40)
-
- #############################
-
- current_Y += 230
-
- UI_elements.scroll_area(layer, win, "asset_link",
- 50,
- 100,
- win.current["w"]-100,
- win.current["h"]-200,
- current_Y,
- bar=True,
- mmb=True,
- url="asset_link",
- strenght=130
- )
-
-
-
- return surface
|