Upload files to 'studio'
This commit is contained in:
parent
63ac32b215
commit
a9963ceb9c
6 changed files with 872 additions and 38 deletions
92
studio/studio_dialogs.py
Normal file
92
studio/studio_dialogs.py
Normal 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.
|
||||
|
358
studio/studio_file_selectLayer.py
Normal file
358
studio/studio_file_selectLayer.py
Normal 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
|
|
@ -19,6 +19,7 @@ from studio import studio_storyLayer
|
|||
# Studio
|
||||
from studio import analytics
|
||||
from studio import story
|
||||
from studio import studio_storyDeletionLayer
|
||||
|
||||
# UI modules
|
||||
from UI import UI_testing
|
||||
|
@ -84,6 +85,8 @@ def run(win):
|
|||
"frame":0, # as easy to do. See UI / UI_math / rectangle_surround()
|
||||
"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):
|
||||
win.story = story.get_legacy(project)
|
||||
|
@ -111,6 +114,7 @@ def run(win):
|
|||
win.current["project"] = ""
|
||||
win.current["tool"] = "selection"
|
||||
win.current["draw_dot"] = "end"
|
||||
win.current["calls"] = {} # Calls. See sutdio/studio_dialogs.py
|
||||
|
||||
previous(win)
|
||||
|
||||
|
@ -176,6 +180,26 @@ def pmdrawing(pmdrawing, main_layer, win):
|
|||
win.current['w'] = win.get_size()[0]
|
||||
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
|
||||
UI_color.set(main_layer, win, "background")
|
||||
|
@ -198,11 +222,45 @@ def pmdrawing(pmdrawing, main_layer, win):
|
|||
|
||||
# Layers. Order of them matter
|
||||
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([win.tooltip_surface])
|
||||
|
||||
|
@ -211,7 +269,7 @@ def pmdrawing(pmdrawing, main_layer, win):
|
|||
if len(layer) > 1:
|
||||
layer, url = layer
|
||||
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)
|
||||
else:
|
||||
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["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
|
||||
# doing here. Basically trying to avoid current and previous data to be links
|
||||
|
|
|
@ -37,6 +37,8 @@ def node_dot(layer, win, x, y, direction="in", entry="end"):
|
|||
|
||||
if entry.startswith("scene:") or entry in ["start", "end"]:
|
||||
UI_color.set(layer, win, "node_script")
|
||||
elif entry.startswith("blend:"):
|
||||
UI_color.set(layer, win, "node_blendfile")
|
||||
else:
|
||||
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
|
||||
|
||||
if win.current["LMB"] and direction != "in":
|
||||
if not win.previous["LMB"] and win.current["LMB"] and direction != "in":
|
||||
|
||||
# Out point
|
||||
|
||||
win.current["tool"] = "connect"
|
||||
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
|
||||
try:
|
||||
|
@ -152,7 +154,27 @@ def node_dot(layer, win, x, y, direction="in", entry="end"):
|
|||
|
||||
except:
|
||||
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):
|
||||
|
||||
|
@ -255,6 +277,8 @@ def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0)
|
|||
width = max(width,20)
|
||||
height = max(height,20)
|
||||
|
||||
|
||||
|
||||
if int(x) in range(int(0-width), int(win.current["w"]))\
|
||||
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.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":
|
||||
|
||||
|
@ -307,7 +341,9 @@ def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0)
|
|||
|
||||
# Now let's make a selection
|
||||
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"]:
|
||||
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":
|
||||
try:
|
||||
|
||||
|
||||
if win.current["LMB"]:
|
||||
x += win.current["mx"] - win.current["LMB"][0]
|
||||
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":
|
||||
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.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
|
||||
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()
|
||||
|
||||
|
||||
# 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
|
||||
node_dot(outlayer, win, x-5, y+25, 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()
|
||||
|
||||
|
||||
|
||||
# Text saying The name of the event
|
||||
UI_color.set(layer, win, "text_normal")
|
||||
layer.set_font_size(15)
|
||||
layer.move_to(15,15)
|
||||
layer.show_text(name)
|
||||
|
||||
|
||||
|
||||
# Here should be the event name thing. But I thought that it wasn't
|
||||
# important for a simple framing thing.
|
||||
|
||||
# Outputting the layer
|
||||
outlayer.set_source_surface(surface, x, y)
|
||||
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"]))\
|
||||
and int(y) in range(int(0-height), int(win.current["h"])):
|
||||
|
||||
|
||||
|
||||
# Making the layer
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
|
||||
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))\
|
||||
and int(win.current["LMB"][1]) in range(int(y), int(y+height))\
|
||||
and win.current["tool"] == "selection":
|
||||
|
||||
|
||||
|
||||
win.current["tool"] = "grab"
|
||||
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 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]
|
||||
pmy = win.current["LMB"][1]
|
||||
|
||||
|
||||
|
||||
|
||||
intersect = UI_math.rectangle_overlap(
|
||||
[mx, my, pmx-mx, pmy-my],
|
||||
[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
|
||||
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"]:
|
||||
win.story["active"] = entry
|
||||
|
||||
|
||||
|
||||
|
||||
if entry in win.story["selected"]:
|
||||
selected = True
|
||||
|
||||
|
@ -826,7 +887,10 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
|
|||
name,
|
||||
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
|
||||
|
||||
|
@ -845,16 +909,22 @@ def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linkty
|
|||
outlayer.paint()
|
||||
|
||||
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+125+14, entry=["asset", name+"/tex"])
|
||||
node_dot(outlayer, win, x-6, y+175+14, entry=["asset", name+"/renders"])
|
||||
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
|
||||
if linktype == "file":
|
||||
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:
|
||||
pass
|
||||
|
|
173
studio/studio_storyDeletionLayer.py
Normal file
173
studio/studio_storyDeletionLayer.py
Normal 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
|
|
@ -18,6 +18,7 @@ from project_manager import pm_project
|
|||
|
||||
from studio import analytics
|
||||
from studio import studio_nodes
|
||||
from studio import studio_dialogs
|
||||
|
||||
#UI modules
|
||||
from UI import UI_elements
|
||||
|
@ -140,8 +141,49 @@ def layer(win):
|
|||
|
||||
# New Scene
|
||||
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,
|
||||
5,
|
||||
105,
|
||||
|
@ -170,7 +212,24 @@ def layer(win):
|
|||
|
||||
# Link File
|
||||
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,
|
||||
5,
|
||||
|
@ -354,6 +413,21 @@ def layer(win):
|
|||
talk.text("mus"),
|
||||
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 #######
|
||||
|
||||
# Clipping so it wont draw beyon the frame
|
||||
|
@ -591,6 +665,12 @@ def layer(win):
|
|||
except:
|
||||
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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue