Upload files to 'studio'

This commit is contained in:
Jeison Yehuda Amihud (Blender Dumbass) 2020-12-07 21:40:45 +00:00
parent 63ac32b215
commit a9963ceb9c
6 changed files with 872 additions and 38 deletions

92
studio/studio_dialogs.py Normal file
View file

@ -0,0 +1,92 @@
# 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
#################
def file_select(win, name, call):
# 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
}
# Here everything is set. I hope so.

View file

@ -0,0 +1,358 @@
# THIS FILE IS A PART OF VCStudio
# PYTHON 3
# This a console project manager.
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 settings import fileformats
from project_manager import pm_project
#UI modules
from UI import UI_elements
from UI import UI_color
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 dialogue deals with file selection. This is not the only place where
# files are drawn. So don't rely on this dialog only.
# To make all the files drawn first off all I want to get all the files data
# and later to clean it. The problem is that it's running on every frame so
# some particular cleverness is required.
# I do want to clean after the dialog is closed so if a change in the files
# happened it could be loaded on the next loading of this window.
# On the other hand reading all the file dynamically would not be wise because
# of expected volume of those files. For things like textures folder in the
# assets it could be possible. But here it will look through the entire
# project. With all the renders of all of the shots from all of the scenes.
# Imagine a movie that is 2 hour long and it's a good 24 frames per second.
# Each of which has 4 versions saved in different folders. This is not the
# kind of data I would try to load dynamically. Unless you know a clever
# way to do so. Please tell me so if you do.
############################################################################
if "AllFiles" not in win.current:
win.current["AllFiles"] = []
for r, d, f in os.walk(win.project):
for item in f:
win.current["AllFiles"].append(os.path.join(r, item).replace(win.project, ""))
# Now that we have the files. There should be some way to filter them.
# I guess let's add a searchbox and buttons on the side for filtering.
# But first let's make a container to save those setting between frames
if "file_selector" not in win.current:
win.current["file_selector"] = {
"image" :True,
"blender":True,
"video" :True,
"file" :False,
"chr" :True,
"veh" :True,
"loc" :True,
"obj" :True,
"vse" :False,
"folder" :False
}
############### TOP PANEL ###################
# Left Icons
for num, thing in enumerate(win.current["file_selector"]):
if num > 3:
num = num + 1
if win.current["file_selector"][thing]:
UI_color.set(layer, win, "progress_time")
UI_elements.roundrect(layer, win,
50+(40*num),
50,
40,
40,
10)
def do():
win.current["file_selector"][thing] = not win.current["file_selector"][thing]
UI_elements.roundrect(layer, win,
50+(40*num),
50,
40,
40,
10,
do,
thing)
# Search
UI_elements.image(layer, win, "settings/themes/"\
+win.settings["Theme"]+"/icons/search.png",
win.current["w"]-440,
50,
40,
40)
UI_elements.text(layer, win, "file_select_search",
win.current["w"]-400,
50,
350,
40,
set_text="")
##### BOTTOM BUTTONS ####
def do():
win.current["calls"][call]["var"] = False
del win.current["AllFiles"]
UI_elements.roundrect(layer, win,
win.current["w"]-80,
win.current["h"]-80,
40,
40,
10,
button=do,
icon="cancel",
tip=talk.text("cancel"))
# Now let's prepare the ground for the next part.
UI_elements.roundrect(layer, win,
50,
100,
win.current["w"]-100,
win.current["h"]-200,
10,
fill=False)
layer.clip()
UI_color.set(layer, win, "dark_overdrop")
layer.rectangle(
0,
0,
win.current["w"],
win.current["h"],
)
layer.fill()
### ACTUALL FILES LIST ###
tileX = 70
current_Y = 0
if "file_select" not in win.scroll:
win.scroll["file_select"] = 0
if "AllFiles" in win.current:
for filename in win.current["AllFiles"]:
######################## FILTERING STARTS ##########################
okay = True
# By search
for stuff in win.text["file_select_search"]["text"].split(" "):
if stuff:
if stuff.lower() not in filename.lower():
okay = False
# By folder
folderfound = False
if okay and "chr/" in filename:
folderfound = True
if not win.current["file_selector"]["chr"]:
okay = False
if okay and "veh/" in filename:
folderfound = True
if not win.current["file_selector"]["veh"]:
okay = False
if okay and "loc/" in filename:
folderfound = True
if not win.current["file_selector"]["loc"]:
okay = False
if okay and "obj/" in filename:
folderfound = True
if not win.current["file_selector"]["obj"]:
okay = False
if okay and "rnd/" in filename:
folderfound = True
if not win.current["file_selector"]["vse"]:
okay = False
if okay and not folderfound:
if not win.current["file_selector"]["folder"]:
okay = False
# By filetype
typefound = False
if okay:
# Images
for f in fileformats.images:
if filename.endswith(f):
typefound = True
UI_color.set(layer, win, "node_imagefile")
if not win.current["file_selector"]["image"]:
okay = False
break
if okay:
# Videos
for f in fileformats.videos:
if filename.endswith(f):
typefound = True
UI_color.set(layer, win, "node_videofile")
if not win.current["file_selector"]["video"]:
okay = False
break
if okay:
# Blend Files
if filename.endswith(".blend"):
typefound = True
UI_color.set(layer, win, "node_blendfile")
if not win.current["file_selector"]["blender"]:
okay = False
if okay:
if typefound == False:
UI_color.set(layer, win, "node_script")
if not win.current["file_selector"]["file"]:
okay = False
######################### FILTERING END ############################
if okay:
UI_elements.roundrect(layer, win,
tileX-10,
current_Y + win.scroll["file_select"] + 120,
170,
200,
10)
if int(current_Y + win.scroll["file_select"] + 100) in range(0, win.current["h"]):
UI_elements.image(layer, win, win.project+filename,
tileX,
current_Y + win.scroll["file_select"] + 150,
150,
150)
UI_color.set(layer, win, "text_normal")
layer.set_font_size(12)
layer.move_to(tileX,
current_Y + win.scroll["file_select"] + 135)
layer.show_text(filename[filename.rfind("/")+1:][:22])
# Button to activate it
def do():
win.current["calls"][call]["var"] = filename
UI_elements.roundrect(layer, win,
tileX-10,
current_Y + win.scroll["file_select"] + 120,
170,
200,
10,
button=do,
tip=filename,
fill=False)
layer.stroke()
tileX += 200
if tileX > win.current["w"]-220:
tileX = 70
current_Y += 230
current_Y += 230
UI_elements.scroll_area(layer, win, "file_select",
50,
100,
win.current["w"]-100,
win.current["h"]-200,
current_Y,
bar=True,
mmb=True,
url="file_select"
)
return surface

View file

@ -19,6 +19,7 @@ from studio import studio_storyLayer
# Studio # Studio
from studio import analytics from studio import analytics
from studio import story from studio import story
from studio import studio_storyDeletionLayer
# UI modules # UI modules
from UI import UI_testing from UI import UI_testing
@ -84,6 +85,8 @@ def run(win):
"frame":0, # as easy to do. See UI / UI_math / rectangle_surround() "frame":0, # as easy to do. See UI / UI_math / rectangle_surround()
"rects":[] # for details of this implementation. "rects":[] # for details of this implementation.
} }
win.calllayer = False
win.layercashe = {} # Here I gonna store layers that are inactive to speed up stuff
if pm_project.is_legacy(project): if pm_project.is_legacy(project):
win.story = story.get_legacy(project) win.story = story.get_legacy(project)
@ -111,6 +114,7 @@ def run(win):
win.current["project"] = "" win.current["project"] = ""
win.current["tool"] = "selection" win.current["tool"] = "selection"
win.current["draw_dot"] = "end" win.current["draw_dot"] = "end"
win.current["calls"] = {} # Calls. See sutdio/studio_dialogs.py
previous(win) previous(win)
@ -176,6 +180,26 @@ def pmdrawing(pmdrawing, main_layer, win):
win.current['w'] = win.get_size()[0] win.current['w'] = win.get_size()[0]
win.current['h'] = win.get_size()[1] win.current['h'] = win.get_size()[1]
# Attemt to make things straight when pressing Ctrl.
if 65507 in win.current["keys"] and win.current["LMB"]:
# Let's see what's got more distance. X or Y motion of the mouse.
dx = win.current["LMB"][0] - win.current["mx"]
dx = max(dx, dx*-1)
dy = win.current["LMB"][1] - win.current["my"]
dy = max(dy, dy*-1)
# If X has more ditance. Then Y should be the same as begining.
if dx > dy:
win.current["my"] = win.current["LMB"][1]
else:
win.current["mx"] = win.current["LMB"][0]
# Attempt at making the mouse cursor a bit more usefull for stuff.
if win.previous["LMB"] and len(win.previous["LMB"]) > 2 and win.current["LMB"]:
win.current["LMB"] = win.previous["LMB"]
#Background color #Background color
UI_color.set(main_layer, win, "background") UI_color.set(main_layer, win, "background")
@ -198,11 +222,45 @@ def pmdrawing(pmdrawing, main_layer, win):
# Layers. Order of them matter # Layers. Order of them matter
Layers = [] Layers = []
Layers.append([studio_storyLayer.layer(win),"story_editor"])
if win.url == "story_editor":
Layers.append([studio_storyLayer.layer(win),"story_editor"])
if "story_editor" in win.layercashe:
del win.layercashe["story_editor"]
else:
if "story_editor" not in win.layercashe:
win.layercashe["story_editor" ] = studio_storyLayer.layer(win)
Layers.append([win.layercashe["story_editor" ],"story_editor"])
if win.url == "story_deletion_dialog":
Layers.append([studio_storyDeletionLayer.layer(win),"story_deletion_dialog"])
# Call layers. See studio/studio_dialogs.py for explanation. It's wild.
win.calllayer = False
remlater = []
for call in win.current["calls"]:
if win.current["calls"][call]["var"] == None:
Layers.append([win.current["calls"][call]["draw"](win, call)])
win.url = win.current["calls"][call]["url"]
win.calllayer = True
else:
win.current["calls"][call]["call"](win, win.current["calls"][call]["var"])
win.url = win.current["calls"][call]["back"]
print()
print(win.current["calls"][call]["back"])
print(win.url)
remlater.append(call)
for call in remlater:
del win.current["calls"][call]
Layers.append([UI_testing.layer(win)]) Layers.append([UI_testing.layer(win)])
Layers.append([win.tooltip_surface]) Layers.append([win.tooltip_surface])
@ -211,7 +269,7 @@ def pmdrawing(pmdrawing, main_layer, win):
if len(layer) > 1: if len(layer) > 1:
layer, url = layer layer, url = layer
blur = UI_elements.animate(url+"_blur", win, 50) blur = UI_elements.animate(url+"_blur", win, 50)
if win.url != url: if win.url != url or win.calllayer:
blur = UI_elements.animate(url+"_blur", win, blur, 50, 2, True) blur = UI_elements.animate(url+"_blur", win, blur, 50, 2, True)
else: else:
blur = UI_elements.animate(url+"_blur", win, blur, 0, 2, True) blur = UI_elements.animate(url+"_blur", win, blur, 0, 2, True)
@ -228,7 +286,10 @@ def pmdrawing(pmdrawing, main_layer, win):
win.current["tool"] = "selection" win.current["tool"] = "selection"
win.current["keys"] = [] win.current["keys"] = []
# There is a but in the Gnome I guess. That autopresses the Shift and Ctrl
# keys when you scroll to different windows. So here is a little fix.
if not win.is_active():
win.current["keys"] = []
# Saving data about this frame for the next one. A bit hard to get WTF am I # Saving data about this frame for the next one. A bit hard to get WTF am I
# doing here. Basically trying to avoid current and previous data to be links # doing here. Basically trying to avoid current and previous data to be links

View file

@ -37,6 +37,8 @@ def node_dot(layer, win, x, y, direction="in", entry="end"):
if entry.startswith("scene:") or entry in ["start", "end"]: if entry.startswith("scene:") or entry in ["start", "end"]:
UI_color.set(layer, win, "node_script") UI_color.set(layer, win, "node_script")
elif entry.startswith("blend:"):
UI_color.set(layer, win, "node_blendfile")
else: else:
UI_color.set(layer, win, "node_imagefile") UI_color.set(layer, win, "node_imagefile")
@ -61,14 +63,14 @@ def node_dot(layer, win, x, y, direction="in", entry="end"):
# Start drawing the line # Start drawing the line
if win.current["LMB"] and direction != "in": if not win.previous["LMB"] and win.current["LMB"] and direction != "in":
# Out point # Out point
win.current["tool"] = "connect" win.current["tool"] = "connect"
win.current["draw_dot"] = raw_entry win.current["draw_dot"] = raw_entry
elif win.current["LMB"] and direction == "in" and win.current["tool"] != "connect": elif not win.previous["LMB"] and win.current["LMB"] and direction == "in" and win.current["tool"] != "connect":
# Take out of the in point # Take out of the in point
try: try:
@ -152,7 +154,27 @@ def node_dot(layer, win, x, y, direction="in", entry="end"):
except: except:
pass pass
elif entry.startswith("blend:"):
for link in win.story["links"]:
if link[0] == "file":
link = link[1]
fr = "blend:"+link
if entry[entry.find(":")+1:] in link:
try:
UI_color.set(layer, win, "node_blendfile")
layer.move_to(
win.out_dots[fr][0],
win.out_dots[fr][1]
)
layer.line_to(x+6, y+6)
layer.stroke()
except:
pass
def start_node(outlayer, win, x, y, width, height): def start_node(outlayer, win, x, y, width, height):
@ -255,6 +277,8 @@ def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0)
width = max(width,20) width = max(width,20)
height = max(height,20) height = max(height,20)
if int(x) in range(int(0-width), int(win.current["w"]))\ if int(x) in range(int(0-width), int(win.current["w"]))\
and int(y) in range(int(0-height), int(win.current["h"])): and int(y) in range(int(0-height), int(win.current["h"])):
@ -274,6 +298,16 @@ def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0)
win.current["tool"] = "grab" win.current["tool"] = "grab"
win.story["active"] = entry win.story["active"] = entry
# Launching the item
if int(win.current["mx"]) in range(int(x), int(x+width))\
and int(win.current["my"]) in range(int(y), int(y+height)):
if not win.current["LMB"] and win.previous["LMB"]\
and entry in win.story["selected"]\
and int(win.current["mx"]) == int(win.previous["LMB"][0])\
and int(win.current["my"]) == int(win.previous["LMB"][1]):
win.url = "scene"
if win.current["LMB"] and win.current["tool"] == "selection": if win.current["LMB"] and win.current["tool"] == "selection":
@ -307,7 +341,9 @@ def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0)
# Now let's make a selection # Now let's make a selection
if intersect: if intersect:
win.story["selected"].append(entry)
if entry not in win.story["selected"]:
win.story["selected"].append(entry)
if win.story["active"] not in win.story["selected"]: if win.story["active"] not in win.story["selected"]:
win.story["active"] = entry win.story["active"] = entry
@ -370,6 +406,8 @@ def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0)
if win.current["tool"] == "grab": if win.current["tool"] == "grab":
try: try:
if win.current["LMB"]: if win.current["LMB"]:
x += win.current["mx"] - win.current["LMB"][0] x += win.current["mx"] - win.current["LMB"][0]
y += win.current["my"] - win.current["LMB"][1] y += win.current["my"] - win.current["LMB"][1]
@ -387,6 +425,7 @@ def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0)
elif win.current["tool"] != "connect": elif win.current["tool"] != "connect":
win.current["tool"] = "selection" win.current["tool"] = "selection"
@ -414,18 +453,7 @@ def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0)
outlayer.stroke() outlayer.stroke()
outlayer.set_line_width(2) outlayer.set_line_width(2)
# In case there is a parent event in the scene.
if win.story["scenes"][name]["parent"]:
parent = win.story["scenes"][name]["parent"]
UI_math.rectangle_surround(win, parent,
win.story["events"][parent]["position"],
win.story["events"][parent]["size"],
[x,y], [width, height]
)
# Clip # Clip
UI_elements.roundrect(layer, win, UI_elements.roundrect(layer, win,
@ -477,6 +505,16 @@ def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0)
outlayer.paint() outlayer.paint()
# In case there is a parent event in the scene.
if win.story["scenes"][name]["parent"]:
parent = win.story["scenes"][name]["parent"]
UI_math.rectangle_surround(win, parent,
win.story["events"][parent]["position"],
win.story["events"][parent]["size"],
[x,y], [width, height]
)
# Dots # Dots
node_dot(outlayer, win, x-5, y+25, entry=entry) node_dot(outlayer, win, x-5, y+25, entry=entry)
node_dot(outlayer, win, x+width-7, y+25, direction="out",entry=entry) node_dot(outlayer, win, x+width-7, y+25, direction="out",entry=entry)
@ -520,15 +558,9 @@ def event_node(outlayer, win, x, y, width, height, name="Unknown"):
layer.fill() layer.fill()
# Here should be the event name thing. But I thought that it wasn't
# Text saying The name of the event # important for a simple framing thing.
UI_color.set(layer, win, "text_normal")
layer.set_font_size(15)
layer.move_to(15,15)
layer.show_text(name)
# Outputting the layer # Outputting the layer
outlayer.set_source_surface(surface, x, y) outlayer.set_source_surface(surface, x, y)
outlayer.paint() outlayer.paint()
@ -546,6 +578,8 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
if int(x) in range(int(0-width), int(win.current["w"]))\ if int(x) in range(int(0-width), int(win.current["w"]))\
and int(y) in range(int(0-height), int(win.current["h"])): and int(y) in range(int(0-height), int(win.current["h"])):
# Making the layer # Making the layer
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height)) surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
layer = cairo.Context(surface) layer = cairo.Context(surface)
@ -562,10 +596,30 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
if int(win.current["LMB"][0]) in range(int(x), int(x+width))\ if int(win.current["LMB"][0]) in range(int(x), int(x+width))\
and int(win.current["LMB"][1]) in range(int(y), int(y+height))\ and int(win.current["LMB"][1]) in range(int(y), int(y+height))\
and win.current["tool"] == "selection": and win.current["tool"] == "selection":
win.current["tool"] = "grab" win.current["tool"] = "grab"
win.story["active"] = entry win.story["active"] = entry
# Launching the item
if int(win.current["mx"]) in range(int(x), int(x+width))\
and int(win.current["my"]) in range(int(y), int(y+height)):
if not win.current["LMB"] and win.previous["LMB"]\
and entry in win.story["selected"]\
and int(win.current["mx"]) == int(win.previous["LMB"][0])\
and int(win.current["my"]) == int(win.previous["LMB"][1]):
if linktype == "file":
if os.path.exists(win.project+"/"+name):
os.system("xdg-open "+win.project+"/"+name)
else:
os.system("xdg-open "+name)
else:
win.url = "assets"
if win.current["LMB"] and win.current["tool"] == "selection": if win.current["LMB"] and win.current["tool"] == "selection":
# If mouse over. But way more complex. Because we might select more then # If mouse over. But way more complex. Because we might select more then
@ -576,6 +630,9 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
pmx = win.current["LMB"][0] pmx = win.current["LMB"][0]
pmy = win.current["LMB"][1] pmy = win.current["LMB"][1]
intersect = UI_math.rectangle_overlap( intersect = UI_math.rectangle_overlap(
[mx, my, pmx-mx, pmy-my], [mx, my, pmx-mx, pmy-my],
[x,y,width, height]) [x,y,width, height])
@ -598,11 +655,15 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
# Now let's make a selection # Now let's make a selection
if intersect: if intersect:
win.story["selected"].append(entry) if entry not in win.story["selected"]:
win.story["selected"].append(entry)
# Making it active.
if win.story["active"] not in win.story["selected"]: if win.story["active"] not in win.story["selected"]:
win.story["active"] = entry win.story["active"] = entry
if entry in win.story["selected"]: if entry in win.story["selected"]:
selected = True selected = True
@ -826,7 +887,10 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
name, name,
0, 0, width, height) 0, 0, width, height)
UI_color.set(layer, win, "node_imagefile") if name.endswith(".blend"):
UI_color.set(layer, win, "node_blendfile")
else:
UI_color.set(layer, win, "node_imagefile")
# top banner # top banner
@ -845,16 +909,22 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
outlayer.paint() outlayer.paint()
if linktype == "asset": if linktype == "asset":
node_dot(outlayer, win, x-6, y+25+14, entry="shit") node_dot(outlayer, win, x-6, y+25+14, entry=["blend", name])
node_dot(outlayer, win, x-6, y+75+14, entry=["asset", name+"/reference"]) node_dot(outlayer, win, x-6, y+75+14, entry=["asset", name+"/reference"])
node_dot(outlayer, win, x-6, y+125+14, entry=["asset", name+"/tex"]) node_dot(outlayer, win, x-6, y+125+14, entry=["asset", name+"/tex"])
node_dot(outlayer, win, x-6, y+175+14, entry=["asset", name+"/renders"]) node_dot(outlayer, win, x-6, y+175+14, entry=["asset", name+"/renders"])
else: else:
node_dot(outlayer, win, x+width-6, y+120, entry=["file", name], direction="out") if name.endswith(".blend"):
node_dot(outlayer, win, x+width-6, y+120, entry=["blend", name], direction="out")
else:
node_dot(outlayer, win, x+width-6, y+120, entry=["file", name], direction="out")
else: # If not in the frame else: # If not in the frame
if linktype == "file": if linktype == "file":
try: try:
del win.out_dots["file:"+name] if name.endswith(".blend"):
del win.out_dots["blend:"+name]
else:
del win.out_dots["file:"+name]
except: except:
pass pass

View file

@ -0,0 +1,173 @@
# THIS FILE IS A PART OF VCStudio
# PYTHON 3
# This a console project manager.
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
#UI modules
from UI import UI_elements
from UI import UI_color
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()
# So it's going to be like a little window in the center of the VCStudio
# with a simple UI. Probably like 2 things. Folder and a projectname.
UI_color.set(layer, win, "node_background")
UI_elements.roundrect(layer, win,
win.current["w"]/2-250,
win.current["h"]/2-150,
500,
300,
10)
# Title of the operation. Incase the user forgot.
UI_elements.text(layer, win, "delete_scenes_question",
win.current["w"]/2-250,
win.current["h"]/2-140,
500,
30,
10,
fill=False,
centered=True,
editable=False)
win.text["delete_scenes_question"]["text"] = talk.text("DeleteQuestion")
# Let's count how much of what it's going to be deleting.
scenes = 0
files = 0
assets = 0
markers = 0
for thing in win.story["selected"]:
if thing[0] == "scene":
scenes += 1
elif thing[0] == "file":
files += 1
elif thing[0] == "asset":
assets += 1
elif thing[0] == "marker":
markers += 1
# Text saying Stuff
UI_color.set(layer, win, "text_normal")
layer.set_font_size(20)
layer.move_to(
win.current["w"]/2-200,
win.current["h"]/2-60)
layer.show_text(str(scenes)+" "+talk.text("Scenes"))
layer.move_to(
win.current["w"]/2-200,
win.current["h"]/2-30)
layer.show_text(str(files)+" "+talk.text("LinksToFiles"))
layer.move_to(
win.current["w"]/2-200,
win.current["h"]/2)
layer.show_text(str(assets)+" "+talk.text("LinksToAssets"))
layer.move_to(
win.current["w"]/2-200,
win.current["h"]/2+30)
layer.show_text(str(markers)+" "+talk.text("Markers"))
# Text at the bottom
UI_elements.text(layer, win, "delete_scenes_conformation",
win.current["w"]/2-250,
win.current["h"]/2+60,
500,
30,
10,
fill=False,
centered=True,
editable=False)
win.text["delete_scenes_conformation"]["text"] = talk.text("OperationIrrevesable")
def do():
win.url = "story_editor"
links = []
for thing in win.story["selected"]:
if thing[0] == "scene":
del win.story["scenes"][thing[1]]
elif thing[0] in ["asset", "file"]:
links.append(thing[1])
new = []
print(thing)
for num, i in enumerate(win.story["links"]):
if num not in links:
new.append(i)
win.story["links"] = new
win.story["selected"] = []
UI_elements.roundrect(layer, win,
win.current["w"]/2+170,
win.current["h"]/2+110,
40,
40,
10,
button=do,
icon="ok",
tip=talk.text("checked"))
def do():
win.url = "story_editor"
UI_elements.roundrect(layer, win,
win.current["w"]/2+210,
win.current["h"]/2+110,
40,
40,
10,
button=do,
icon="cancel",
tip=talk.text("cancel"))
return surface

View file

@ -18,6 +18,7 @@ from project_manager import pm_project
from studio import analytics from studio import analytics
from studio import studio_nodes from studio import studio_nodes
from studio import studio_dialogs
#UI modules #UI modules
from UI import UI_elements from UI import UI_elements
@ -140,8 +141,49 @@ def layer(win):
# New Scene # New Scene
def do(): def do():
print("New Scene")
# Okay let's make the adding the scene possible.
# First we need to know what scenes are there. So we don't overwrite
# any existing scene.
scenename = "Scene"
count = 2
while scenename in win.story["scenes"]:
scenename = "Scene_"+str(count)
count = count + 1
# Now that we have an empty name. Let's add a scene.
win.story["scenes"][scenename] = {
"fraction":0.0, # Percentage
"position":[
win.current["mx"]-win.story["camera"][0]-50,
win.current["my"]-win.story["camera"][1]-30
],
"size":[100, 60],
"parent":"", # For when it's in a Frame (Event)
"shots":[[
"text_block",[["text", '']]
]]
}
# Auto select the new scene
win.story["selected"] = [["scene", scenename]]
win.current["tool"] = "grab"
# A hack I guess. I don't know what I'm doing. I'm trying to force
# the motion on click.
win.current["LMB"] = [win.current["mx"], win.current["my"], True]
# In studio/studio_gtk.py there is a command that recognizes the length
# of the LMB. And it's more then 2 it does some magic to make stuff move
# without pressing the actuall key. It's slightly too clever even for me
# so yeah.
UI_elements.roundrect(layer, win, UI_elements.roundrect(layer, win,
5, 5,
105, 105,
@ -170,7 +212,24 @@ def layer(win):
# Link File # Link File
def do(): def do():
print("Link File") def after(win, var):
if var:
win.story["links"].append([
"file", var, [
win.current["mx"]-win.story["camera"][0]-75,
win.current["my"]-win.story["camera"][1]-75
]
])
# Something here breaks the thing IDK what exaclty. I was trying
# to mkae things move. They do not want to. For some reason.
# win.story["selected"] = [["file", var]]
# win.current["tool"] = "grab"
# win.current["LMB"] = [win.current["mx"], win.current["my"], True]
studio_dialogs.file_select(win, "new_file_story", after)
UI_elements.roundrect(layer, win, UI_elements.roundrect(layer, win,
5, 5,
@ -354,6 +413,21 @@ def layer(win):
talk.text("mus"), talk.text("mus"),
url="story_editor") url="story_editor")
# Folder
def do():
os.system("xdg-open "+win.project)
UI_elements.roundrect(layer, win,
win.current["w"]-45,
win.current["h"]-75,
40,
40,
10,
do,
"folder",
talk.text("project_folder"),
url="story_editor")
####### NODES ####### ####### NODES #######
# Clipping so it wont draw beyon the frame # Clipping so it wont draw beyon the frame
@ -591,6 +665,12 @@ def layer(win):
except: except:
pass pass
# Deletion
if 65535 in win.current["keys"] and win.current["tool"] == "selection"\
and win.url == "story_editor" and win.story["selected"]:
win.url = "story_deletion_dialog"
return surface return surface