From a9963ceb9cdba52d98175b795aa3d9f995434695 Mon Sep 17 00:00:00 2001 From: "Jeison Yehuda Amihud (Blender Dumbass)" Date: Mon, 7 Dec 2020 21:40:45 +0000 Subject: [PATCH] Upload files to 'studio' --- studio/studio_dialogs.py | 92 +++++++ studio/studio_file_selectLayer.py | 358 ++++++++++++++++++++++++++++ studio/studio_gtk.py | 69 +++++- studio/studio_nodes.py | 132 +++++++--- studio/studio_storyDeletionLayer.py | 173 ++++++++++++++ studio/studio_storyLayer.py | 86 ++++++- 6 files changed, 872 insertions(+), 38 deletions(-) create mode 100644 studio/studio_dialogs.py create mode 100644 studio/studio_file_selectLayer.py create mode 100644 studio/studio_storyDeletionLayer.py diff --git a/studio/studio_dialogs.py b/studio/studio_dialogs.py new file mode 100644 index 0000000..a65c299 --- /dev/null +++ b/studio/studio_dialogs.py @@ -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. + diff --git a/studio/studio_file_selectLayer.py b/studio/studio_file_selectLayer.py new file mode 100644 index 0000000..2e109c5 --- /dev/null +++ b/studio/studio_file_selectLayer.py @@ -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 diff --git a/studio/studio_gtk.py b/studio/studio_gtk.py index 6358b6a..4daa227 100644 --- a/studio/studio_gtk.py +++ b/studio/studio_gtk.py @@ -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 diff --git a/studio/studio_nodes.py b/studio/studio_nodes.py index e79b7fa..d9fad3f 100644 --- a/studio/studio_nodes.py +++ b/studio/studio_nodes.py @@ -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 diff --git a/studio/studio_storyDeletionLayer.py b/studio/studio_storyDeletionLayer.py new file mode 100644 index 0000000..596e2e9 --- /dev/null +++ b/studio/studio_storyDeletionLayer.py @@ -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 diff --git a/studio/studio_storyLayer.py b/studio/studio_storyLayer.py index cc88207..8d86a48 100644 --- a/studio/studio_storyLayer.py +++ b/studio/studio_storyLayer.py @@ -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