1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313 |
- # THIS FILE IS A PART OF VCStudio
- # PYTHON 3
- import os
- import datetime
- import threading
- import re
- import json
- # 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 settings import oscalls
- from project_manager import pm_project
- #UI modules
- from UI import UI_elements
- from UI import UI_color
- from UI import UI_math
- # story
- from studio import story
- from studio import checklist
- from studio import analytics
- from studio import studio_dialogs
- from studio import schedule
- from studio import history
- from network import http_client
- def select_shot(win):
- # For the http-server stuff
- # Remote Server Stuff
- if win.analytics["from-remote-server"]:
- # Checking date [ FOLDER NAME ] [ FILES TO CHECK FOR ]
- check_folders = {"/rnd"+win.cur : "*",
- "/rnd"+win.cur+"/storyboard" : "*",
- "/rnd"+win.cur+"/opengl" : "*",
- "/rnd"+win.cur+"/test_rnd" : "*",
- "/rnd"+win.cur+"/rendered" : "*",
- "/rnd"+win.cur+"/extra" : "*"
- }
-
- check_updates = threading.Thread(target=http_client.get_folder_info,
- args=(win, check_folders, win.cur, ))
- check_updates.setDaemon(True)
- check_updates.start()
- 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()
-
- ############################################################################
-
- # This is a file that will draw the text editor of VCStudio. The idea is that
- # you not only work on making the movie in VCStudio, but the script to the
- # movie is also written in VCStudio. This was already implemented in Blender-
- # Organizer legacy. And already implemented partially in VCStudio. As there
- # is story editor in place where you can add empty scenes. Or deal with
- # scenes that are converted from legacy.
-
- # But as you may guess by the time I'm writting it there is no way of editing
- # those scene's contents. Or read them in full. ( You can see peaces in the
- # assets )
-
- # The implementation of the editor will be different from Blender-Organizer's
- # where I used an off the shelf GTK text writting widget.
-
- # The problem was that I could not really do much with that widget appart from
- # text. Don't get me wrong it was good for text. But I could not make for
- # example custom ways of drawing particular parts. Like what if I want a
- # round-rectangle arround each frase that the crachater's say. Or what if I
- # want to draw some custom UI buttons somewhere in the text. Stuff like this.
-
- # Which resulted in a weird workflow. I had a pretty script preview thing.
- # and another non-pretty script preview thing. And a script writer thing where
- # you type in code to mark thing. Very non pretty. Non user-friendly. And
- # you had to learn the code. And stuff. Yeah...
-
- # So here I want to make more of traditional editor. Where you see what you are
- # editing as you editing it. Hopefully it's going to work.
-
- ############################################################################
-
- ####### TOP PANEL #########
-
- UI_color.set(layer, win, "node_background")
- UI_elements.roundrect(layer, win,
- win.current["w"]/4,
- 10,
- win.current["w"]/2,
- 50,
- 10)
-
-
- # Let's add the toolbar. There is not a lot of tools we need. Since it's
- # a program only for writting a script.
-
- # Mark Shot
- # Mark Asset
- # Start Dialogue
- # Link Image
-
- # MARK SHOT
- def do():
- win.current["key_letter"] = chr(19)
-
- UI_elements.roundrect(layer, win,
- win.current["w"]/4+5,
- 15,
- 40,
- 40,
- 10,
- do,
- "shot_new",
- talk.text("add_shot_tooltip")+"\n\n[Ctrl - S]")
-
- # MARK ASSET
- def do():
- win.current["key_letter"] = chr(12)
-
- UI_elements.roundrect(layer, win,
- win.current["w"]/4+55,
- 15,
- 40,
- 40,
- 10,
- do,
- "obj_link",
- talk.text("add_asset_tooltip")+"\n\n[Ctrl - L]")
-
- # Do DIALOGUE
- def do():
-
- # Later on I'm doing the Ctrl - D combination to add a frase part
- # and this gives me a character of 00000011 or in other words a 4.
- # So i guess making it thing that I pressed Ctrl-D is fine.
-
- win.current["key_letter"] = chr(4)
-
- UI_elements.roundrect(layer, win,
- win.current["w"]/4+105,
- 15,
- 40,
- 40,
- 10,
- do,
- "frase_new",
- talk.text("add_phrase_tooltip")+"\n\n[Ctrl - D]")
-
- # ADD IMAGE
- def do():
- win.current["key_letter"] = chr(9)
-
- UI_elements.roundrect(layer, win,
- win.current["w"]/4+155,
- 15,
- 40,
- 40,
- 10,
- do,
- "image_link",
- talk.text("add_image_script_tooltip")+"\n\n[Ctrl - I]")
-
- # Next part is to add the scene name editor. It's not as easy as you might
- # thing. Since every scene's shot might contain an actuall folder on the
- # operating system after you create a first blend file to animate the shot.
-
- # So there will be a folder for the scene with many folders for shots inside.
- # And if you change the name of the scene in the story you probably want to
- # change the name of the scene in the folder as well. BUT. Since there could
- # be countless blend files inside. And some names just could be already taken
- # and stuff like that, I will block the editing of the scene if a folder exists.
- # And will give a folder icon.
-
- # Technically it's going to be possible to rename the scene. By renaming the
- # folder first. But this is a kind of breaking everything operation i don't
- # want to implement inside the VCStudio it self. I give constant folder links
- # so editing of files could be done by the user at any time.
-
- # But I don't want it to feel easy. Since stuff like deleting assets or
- # editing names could break things in a different place in the program. That's
- # why I don't provide easy to use functions for it. The user should really
- # decide to make a change like this. To the point of breaking the convinience
- # of VCStudio.
-
- # Parsing the url
- if win.cur.count("/") > 1:
- tmp = win.cur.replace("/","",1).split("/")
- scene, shot = tmp[0], tmp[1]
- else:
- scene = win.cur[win.cur.rfind("/")+1:]
- shot = ""
-
-
-
- # Let's find out if a folder exists.
-
- if os.path.exists(win.project+"/rnd/"+scene):
- editable = False
- minus = 50
-
- # The minus is the width of the folder button
-
- def do():
- oscalls.Open(win.project+"/rnd/"+scene)
-
- UI_elements.roundrect(layer, win,
- win.current["w"]/4*3-45,
- 15,
- 40,
- 40,
- 10,
- do,
- "folder",
- tip="/rnd/"+scene)
-
-
-
- else:
- editable = True
- minus = 0
-
- UI_elements.text(layer, win, "scene_name",
- win.current["w"]/4+205,
- 15,
- win.current["w"]/2-210-minus,
- 40,
- set_text=scene,
- editable=editable,
- fill=False)
-
- # Now let's do the actual edititing part. What we want to look for is whether
- # the key already exists in the scenes, if not allow it to be applied. Now
- # you are probably asking yourself. But the current scene exists there? So
- # how could you apply it. Easy. If you change anything. It already doesn't
- # exist there. And if you didn't change anything. What's the point of applying
- # anyway? So here what we are going to do.
-
- newname = win.text["scene_name"]["text"].replace("/","_").replace(" ", "_")\
- .replace('"',"_").replace("(","_").replace(")","_").replace("'","_")\
- .replace("[","_").replace("]","_").replace("{","_").replace("}","_")
-
- if newname not in win.story["scenes"]:
-
- def do():
-
- win.story["scenes"][newname] = win.story["scenes"].pop(scene)
- win.text["scene_name"]["text"] = newname
- win.cur = newname
-
-
-
- # There is one more rub. Scenes could be connected together.
- # so now we need to preserve the connections as well. This is
- # not that hard.
-
- for arrow in win.story["arrows"]:
- if arrow[0][1] == scene:
- arrow[0][1] = newname
- if arrow[1][1] == scene:
- arrow[1][1] = newname
-
- # Easy. I like how if it's a list. it's a link to the list.
- # so there will not be memory overdrives. So I can itterate
- # over a list of lists and assing values of to the itteration
- # and not trying to get the main list. LOVELY.
-
-
-
- # Saving to the file
- story.save(win.project, win.story)
-
-
- UI_elements.roundrect(layer, win,
- win.current["w"]/4*3-45,
- 15,
- 40,
- 40,
- 10,
- do,
- "ok",
- tip=talk.text("checked"))
-
- # Just in case parsing the url again
- if win.cur.count("/") > 1:
- tmp = win.cur.replace("/","",1).split("/")
- scene, shot = tmp[0], tmp[1]
- else:
- scene = win.cur[win.cur.rfind("/")+1:]
- shot = ""
-
- ######### MAIN PART ###########
-
- # Oh dear. I have no idea how hard it's going to be. But let's try. I don't
- # thing it's going to be that insane. But I need to take in consideration
- # a couple of things. Mainly text warping. Meaning I'm probably rendering
- # each word as an individual object. Now this creates a challenge.
-
- # How do I mark parts of the text having more then 1 word it it? I probably
- # will need to draw a couple layers at ones.
-
- # TEXT LAYER
- # SHOTS MARKING LAYER
- # ASSET MARKING LAYER
-
- # And then combine them in a different order
-
- # SHOT MARKING LAYER
- # ASSET MARKING LAYER (on top)
- # TEXT LAYER (on top of everything)
-
- # So let's make those 3 layers.
-
- x = win.current["w"]/4
- y = 70
- width = win.current["w"]/2 -30
- height = win.current["h"]-130
-
- # Good that at least all layers have the same size.
-
- textsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
- text = cairo.Context(textsurface)
- text.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
-
- shotsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
- shots = cairo.Context(shotsurface)
- shots.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
-
- assetsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
- assets = cairo.Context(assetsurface)
- assets.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
-
- frasesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
- frases = cairo.Context(frasesurface)
- frases.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
-
- ###########################
-
- # Oh dear
-
- # Clips:
- UI_elements.roundrect(text, win, 0,0,width, height, 10,fill=False)
- text.clip()
- UI_elements.roundrect(shots, win, 0,0,width, height, 10,fill=False)
- shots.clip()
- UI_elements.roundrect(assets, win, 0,0,width, height, 10,fill=False)
- assets.clip()
- UI_elements.roundrect(frases, win, 0,0,width, height, 10,fill=False)
- frases.clip()
-
- # Background
- UI_color.set(frases, win, "node_background")
- frases.rectangle(0,0,width, height)
- frases.fill()
-
- # Scroll stuff
- if "script" not in win.scroll:
- win.scroll["script"] = 0
-
- tileX = 12
- current_Y = 0
-
- # For highlights of assets and shots. Basically when mouse is over a given
- # asset it will record itself into the higlight. And be read on the next
- # frame by those above it which are links to the same asset / shot.
- # This is done like so, so I could make multiline drawing of markings.
-
- if "script_asset_higlight" not in win.current:
- win.current["script_asset_higlight"] = ""
- if "script_shot_higlight" not in win.current:
- win.current["script_shot_higlight"] = ""
-
-
- # Next. For editing the text we need a cursor on the screen. A kind of pointer
- # that will be our selection. The only problem is that we are trying to make
- # usefull text editor where you can select a part of text. And do things to it
- # like let's say mark a shot or an asset. This is why there are actually 2
- # points which are souce of quite heavy head auks later on.
-
- pointer = [0,0] # The editing cursor
- point = 0 # The current place in the text of the scene.
- if scene in win.story["pointers"]: # Also I thought sinec we are
- pointer = win.story["pointers"][scene] # saving selection in story
- # editor. Why not save also
- # The text pointers.
-
- # Coming back to the previous thing. If I mouse over the part the part get's
- # highlighted. But simply removing the mouse is not enough. Because I'm
- # writting that it's higlighted into a global dictionary. So I want to clean.
- # it ones in a while. And for now ( It does cause some visual noise ) I chose
- # to remove the selection if the mouse cursor moved over 1 pixel from it's
- # previous frame. So if you move the cursor very slowly, there will be no
- # change.
-
- if int(win.current["mx"]) not in range(int(win.previous["mx"])-1, int(win.previous["mx"])+1)\
- and int(win.current["my"]) not in range(int(win.previous["my"])-1, int(win.previous["my"])+1):
- win.current["script_asset_higlight"] = ""
- win.current["script_shot_higlight"] = ""
-
-
- # This 2 fellas will be responsible for drawing the shot marking.
- shotpart = 0 # This is a pixel where to start the rounded rectangle.
- shotis = "" # this is a current drawing shot's name.
-
- # Same idea for the selection cursor.
- ss = 0 # The pixel where to start drawing the selection cursor.
- smx = ss
-
- # Another one of these for the rectangles under frases. This one is Y location
- # instead.
- frasepart = 0
-
- # This is the scroll when typing.
-
- putscroll = 0
-
-
- # Before we start. Let's bullet proof this. So if the scene does not exist
- # we will be transferred back to story editor and not stuck.
-
- try:
- win.story["scenes"][scene]["shots"]
- except:
- win.url = "story_editor"
- win.cur = ""
- return surface
-
- # Okay if nothing is in the scene we want to create a text block of 1 character
- # into the scene. Because if it will have 0 characters it will be automatically
- # deleted.
-
- if not win.story["scenes"][scene]["shots"]\
- or win.story["scenes"][scene]["shots"][-1][0] == "shot_block":
- win.story["scenes"][scene]["shots"].append([
- "text_block",[["text", ' ']]
- ])
-
- # This is a list of parts that are inside the selection. I will populate it
- # as I itterate trough text. The problem with this text is that it's not a
- # long string. It's a list of blocks. Each of them has a string. But also
- # each of them has some aditional metadata. Like is it a shot, or not. Is it
- # a frase. Is it a link to an asset. This kind a thing. So in order to edit it
- # I need to get all selected peaces into a big thing.
-
- selecwords = []
-
- # And a little thing for the left panel. Since we already itterating through.
- # the shots. Why not get a quick list of them
-
- shot_list = {}
-
- # Okay so let's begin itterating the scene blocks. There are 2 types of scene
- # blocks. (At least for now.) Those are shot_block and text_block. Text is a
- # normal text parts. Shot is everything with in a shot. Shot has one more item
- # in the list. It's the name of the shot. ['shot_block', 'shot_name', [<text>]]
- # while text has just 2. ['text_block', [<text>]]. So you can see me refencing
- # the block[-1] a lot. To get the text parts of the block.
-
-
-
- for num, block in enumerate(win.story["scenes"][scene]["shots"]):
-
-
- # If shot block is empty Let's get rig of it, so not to collect garbage in
- # our story file. Each empty srting is still a string. That requires some
- # characters to write it to file. So let's get rid of it here.
-
- if not block[-1]:
- del win.story["scenes"][scene]["shots"][num]
-
- # Here I want to make another type of filtering. So there will not be
- # 1 million blocks each 1 character long. I want to make it next.
- # If the previous block has the same metadata as this one. Join them.
-
- if num > 0 and win.story["scenes"][scene]["shots"][num-1][0] == "text_block" and block[0] == "text_block":
- win.story["scenes"][scene]["shots"][num-1][-1] = win.story["scenes"][scene]["shots"][num-1][-1] + block[-1]
- del win.story["scenes"][scene]["shots"][num]
-
-
- # THIS ONE IS NOT TESTED YET, BUT I MIGHT ALSO FORGET TO DELETE THE COMMENT.
- elif num > 0 and win.story["scenes"][scene]["shots"][num-1][0] == "shot_block" and block[0] == "shot_block"\
- and win.story["scenes"][scene]["shots"][num-1][1] == block[1]:
- win.story["scenes"][scene]["shots"][num-1][-1] = win.story["scenes"][scene]["shots"][num-1][-1] + block[-1]
- del win.story["scenes"][scene]["shots"][num]
-
- if block[0] == "shot_block" and block[1] not in shot_list:
- shot_list[block[1]] = block
-
-
- # Now other windows might want to reference the script. Like assets for
- # example. So this script_find is for other windows to set. So while in
- # the script it would automatically scroll to that part. And so if set
- # only shot. Here is out shot finder, auto-scroller thingy.
-
- if win.current["script_find"][0] and win.current["script_find"][0] == num:
- win.scroll["script"] = 0-current_Y+height/2
- win.current["script_find"][0] = 0
-
- # Now let's itterate over parts of the text. Now you probably asking wasn't
- # blocks just strings with some metadata? Yes and know. Every text block has
- # blocks with in it. So I could mark items and images and frases with in text
- # across or without a shot. Basically there is our simple Hello-World thing
- # written inside a scene data. ['text_block', ['text','Hello-World']]
- # This are similar. The actual sting is always in the very end. So to find it
- # I'm using part[-1]
-
- for n, part in enumerate(block[-1]):
-
- # If you remember me deleting every empty block. Not this is the same
- # but with empty parts. So you could delete a frase for example. While
- # just backspacing.
-
- if not part[-1]:
- del block[-1][n]
-
- # Here I want to make another type of filtering. So there will not be
- # 1 million blocks each 1 character long. I want to make it next.
- # If the previous block has the same metadata as this one. Join them.
-
- if n > 0 and block[-1][n-1][0] == "text" and part[0] == "text":
- block[-1][n-1][-1] = block[-1][n-1][-1]+part[-1]
- part[-1] = ""
-
- # Now this is our search finder auto-scroller again. But if a part
- # also specified.
-
- if win.current["script_find"][1] and win.current["script_find"][1] == n:
- win.scroll["script"] = 0-current_Y+height/2
- win.current["script_find"][1] = 0
-
- # Now t and p. Well t is simply a shortcut to the string it self. Tho
- # I found it not really usefull since it's not a link to the data. Like
- # in the case of part[-1]. But for rendering it will be okay.
-
- t = part[-1]
- # Now p is a bit more complicated to explain. Basically I always need
- # an index number from all character in the whole scene in relation to
- # this particular part. See i will have a selection across the blocks
- # and across the parts. And in order to edit them at the right place
- # I need a reference point of where in the whole, this part starts.
- p = point
-
- # Now xb and mt you could see as margins of the text. Sometimes you
- # want the whole width to be text. And sometimes. Like in frases you
- # will want the text closer to the center.
-
- xb = 12 # Where is the start of the line
- mt = width # Where is the maximum width
-
- ##### FRASE #####
-
- # Now let's make an example of xb and mt. Here is a frase. So when
- # it's a frase. You want the text be closer to the center.
-
- if part[0] == "frase":
-
-
- # Give it some space. It's a rendering of a frase. You don't
- # want to be a part of the rest of the text.
-
- current_Y = current_Y + 30
-
- # Now frase metadata has another part. Which could be either
- # text or link. This is the name of our character. The little
- # part at the top, in the center. If it's a link we want to
- # draw it accordingly
-
- if part[1][0] == "link":
-
- # First we draw a little purple rectangle. To show us that
- # it's a link to an item.
-
- UI_color.set(assets, win, "node_asset")
- UI_elements.roundrect(assets, win,
- width/2-len(part[1][-1])*6-6,
- win.scroll["script"] + current_Y+6,
- len(part[1][-1])*12+12,
- 28,
- 10)
-
- # Then we make a selection by hovering with the mouse. So if
- # you click later. You will be transferred to the thing.
-
- if int(win.current['mx']) in range(int(x+width/2-len(part[1][-1])*6-6), int(x+width/2-len(part[1][-1])*6-6+len(part[1][-1])*12+12)) \
- and int(win.current['my']) in range(int(y+win.scroll["script"] + current_Y+8), int(y+win.scroll["script"] + current_Y+8+22)) :
-
- win.current["script_asset_higlight"] = part[1][1]
-
- # And if the mouse is over the item's link. No matter if the
- # link is this one. But if mouse is over any other mention of
- # the same asset. We want to draw another rectangle. To give
- # the user a feedback.
-
- if part[1][1] == win.current["script_asset_higlight"]:
-
- UI_color.set(assets, win, "text_normal")
- UI_elements.roundrect(assets, win,
- width/2-len(part[1][-1])*6-6,
- win.scroll["script"] + current_Y+30,
- len(part[1][-1])*12+12,
- 0,
- 3)
-
-
- # Next we will want to do it make a little button to edit the
- # name of the character. Because I guess I'm not smart enough
- # to figure out how to make this a part of the script. And this
- # implementation is not that terrible. I have a chance to put a
- # single line entry into a multiline text. This is something.
-
- if "current_name_frase_editing" not in win.current:
- win.current["current_name_frase_editing"] = False
- win.previous["current_name_frase_editing"] = False
-
- # So we put a selection variable. And set up the button.
-
- if not win.current["current_name_frase_editing"]:
- def do():
-
- win.current["LMB"] = False
- win.previous["LMB"] = False
- if not win.previous["current_name_frase_editing"]:
- print(part[1][-1])
- win.current["current_name_frase_editing"] = [num, n]
- if "current_name_frase_editing" in win.text:
- win.text["current_name_frase_editing"]["text"] = part[1][-1]
- win.textactive = "current_name_frase_editing"
- UI_elements.roundrect(frases, win,
- 0,
- win.scroll["script"] + current_Y+6,
- width,
- 28,
- 10,
- button=do,
- offset=[x,y])
-
- # Now let's draw a little text editor with in a text editor. IK wild.
- # but since everything is custom I can do wild things.
-
- if win.current["current_name_frase_editing"] == [num, n]:
-
- UI_elements.text(text, win, "current_name_frase_editing",
- 200,
- win.scroll["script"] + current_Y-5,
- width-400,
- 40,
- set_text=part[1][-1],
- offset=[x,y])
-
- # Here I will add some logic to this little editor with in
- # editor. OMG WHAT AM I DOING?
-
- # First let's make the apply button. And I guess the enter key.
-
- def linking():
- print("linking")
-
- if "linking_asset_operation_metadata" not in win.current:
- win.current["linking_asset_operation_metadata"] = []
-
- win.current["linking_asset_operation_metadata"] = part
-
- def after(win, var):
- print(var)
- if var:
-
- part = win.current["linking_asset_operation_metadata"]
-
-
- print(part)
- part[1] = ["link", var, part[1][-1]]
-
-
- studio_dialogs.asset_select(win, "link_asset_script_frase", after,
- SEARCH=win.text["current_name_frase_editing"]["text"])
-
-
- UI_elements.roundrect(text, win,
- width-240,
- win.scroll["script"] + current_Y-5,
- 40,
- 40,
- 10,
- button=linking,
- icon="obj_link",
- offset=[x,y])
-
- def do():
- part[1][-1] = win.text["current_name_frase_editing"]["text"]
- win.current["current_name_frase_editing"] = False
- win.current["LMB"] = False
- win.previous["LMB"] = False
- win.textactive = False
- win.current["key_letter"] = ""
-
- UI_elements.roundrect(text, win,
- width-280,
- win.scroll["script"] + current_Y-5,
- 40,
- 40,
- 10,
- button=do,
- icon="ok",
- offset=[x,y])
-
- # Enter key.
-
- if 65293 in win.current["keys"]:
- do()
-
- # If you press Ctrl-Enter instead of Enter. I want it
- # to apply and also give you automatically to select
- # the asset to link in the frase header.
-
- if 65507 in win.current["keys"]:
- linking()
-
- win.current["keys"] = []
-
- # Canceling the editing. If we don't do that the entry thing
- # will still be on the screen. And it's not something that
- # I want to have there.
-
- if not win.textactive:
- win.current["current_name_frase_editing"] = False
- win.current["key_letter"] = ""
- else:
-
- # And if we are not editing the name currently
- # let's just draw the name in the center of the
- # screen.
-
- UI_color.set(text, win, "text_normal")
- text.set_font_size(20)
- text.move_to(
- width/2-len(part[1][-1])*6,
- win.scroll["script"] + current_Y+25,
- )
- text.show_text(part[1][-1])
-
- # Giving it a new line.
-
- current_Y = current_Y + 35
-
- # Putting the line into the frasepart so to draw a rectangle
- # later under the whole thing.
-
- frasepart = current_Y
-
- # And here we are editing the margins. Because actuall text will
- # be done in a different place.
-
- xb = 212
- mt = width - 200
- tileX = xb
-
- # And passing the current starting position to selection drawing
- # so it too will start where it should.
-
- if ss:
- ss = xb
-
- # Now if we are not in the frase. Let's draw the damn rectangle under
- # it finally. # THIS IS STILL BUGGY.
-
- if frasepart and part[0] != "frase":
- UI_color.set(frases, win, "dark_overdrop")
- UI_elements.roundrect(frases, win,
- 200,
- win.scroll["script"] + frasepart,
- width-400,
- current_Y - frasepart+40,
- 10)
- frasepart = 0
-
- # MAKING A NEW LINE
-
- smx = tileX
- tileX = xb
-
- if assetpart:
- assetpart = xb
- if shotpart:
- shotpart = xb
-
- if ss:
-
- UI_color.set(assets, win, "node_blendfile")
- UI_elements.roundrect(assets, win,
- ss,
- win.scroll["script"] + current_Y+5,
- smx-ss,
- 26,
- 10)
- smx = ss
- ss = xb
-
- current_Y = current_Y + 30
-
-
-
- # Now let's draw our images. If they are in the scene. # THIS IS STILL BUGGY
-
- if part[0] == "image":
-
- if UI_math.line_overlap([pointer[1], pointer[0]],[point, point+1]):
- if win.current["key_letter"] and not win.textactive:
-
- # Let's make it possible to delete images by just
- # deleting near them.
-
- part[-1] = ""
-
- current_Y = current_Y + 30
-
- if os.path.exists(win.project+t):
- UI_elements.image(text, win, win.project+t,
- 100,
- win.scroll["script"] + current_Y,
- int(width)-200,
- 380,
- cell="script_images")
- else:
- UI_elements.image(text, win, t,
- 100,
- win.scroll["script"] + current_Y,
- int(width)-200,
- 380,
- cell="script_images")
-
- # Now I guess to simplify the matters let's create a selection
- # button. Double clicking which will open the file.
-
- # So we need a selection dialog. I think I'm going to hack into
- # my own program right now because I'm lazy to implement anything
- # normal. This image thing. Will need more love later on. Now it's
- # thrown together quite in a rush. I would say.
-
- def do():
- if t != win.textactive:
- win.textactive = t
- else:
- oscalls.file_open(win, t)
- UI_elements.roundrect(text, win,
- 100,
- win.scroll["script"] + current_Y,
- int(width)-200,
- 380,
- 10,
- button=do,
- fill=False,
- offset=[x,y])
- text.stroke()
-
- # Selection drawing
-
- if t == win.textactive:
-
- UI_color.set(text, win, "text_normal")
- UI_elements.roundrect(text, win,
- 100,
- win.scroll["script"] + current_Y,
- int(width)-200,
- 380,
- 10,
- fill=False)
- text.stroke()
-
- # Removing it from the selection using ESC
-
- if 65307 in win.current["keys"]:
- win.textactive = ""
- win.current["keys"] = []
- win.current["key_letter"] = ""
-
- # Deleting the image if pressing Delete or Backspace
-
- if 65288 in win.current["keys"] or 65535 in win.current["keys"]:
- win.textactive = ""
- part[-1] = ""
- win.current["keys"] = []
- win.current["key_letter"] = ""
-
- current_Y = current_Y + 400
-
- continue # we don't want to image url in the text it self.
-
- # Do you remember I was doing the starting positions of shots and
- # selection? These 2 are the same concept but to links to assets.
-
- assetpart = 0
- assetis = ""
- ############## TEXT IT SELF ###############
-
- # Here we go and render the text. Now you can see I iterate over
- # lines using re.split rather then built in split(). It's because
- # I need all characters still be present. Since I'm counting every
- # each character.
-
- for line in re.split("(\n)",t):
-
- # Now if the line says '\n' (new_line) then I just want to
- # draw the next line. Note that I'm also drawing the selection
- # box here. And moving all assetpart, shotpart and ss. So on
- # the next line those rectangles would start their drawing from
- # the begining of the line.
-
- # Also not the large comment with a POINT in it. It's I'm counting
- # this character in for to know where I'm editing.
-
- if line == "\n":
-
- smx = tileX
-
- tileX = xb
- #point = point + 1 #################### <<<<<< POINT
-
-
- if assetpart:
- assetpart = xb
- if shotpart:
- shotpart = xb
-
- if ss:
-
- UI_color.set(assets, win, "node_blendfile")
- UI_elements.roundrect(assets, win,
- ss,
- win.scroll["script"] + current_Y+5,
- smx-ss,
- 26,
- 10)
- text.stroke()
- smx = ss
- ss = xb
-
- current_Y = current_Y + 30
-
-
- line = " "
- #continue # And this is since I don't want weird rectangles
- # on the screen. And just new lines.
-
- # Now let's itterate over each and every word. Since we want
- # text wrapping. So if a certain word goes off screen I want
- # to declare a next line. NOTE: I'm still using re.split()
- # becuase we are counting charaters still.
-
- for word in re.split("( )", line):
-
- # Now let's do the actuall text wrapping. For size 20 which
- # is what I'm using. With monospace font. Width of each
- # character is 12 pixels. ( More or less. Good enough for
- # what we are doing ). So if lenght of word times 12, plus
- # current place on X is more then the width of our screen,
- # with all the margins. We want to start a new line.
-
- if tileX + len(word)*12 > mt:
-
- smx = tileX
-
- tileX = xb
-
- # And do not forget about all the asset, shot and selection
- # rendering too.
-
- if assetpart:
- assetpart = xb
- if shotpart:
- shotpart = xb
-
-
- if ss:
-
- UI_color.set(assets, win, "node_blendfile")
- UI_elements.roundrect(assets, win,
- ss,
- win.scroll["script"] + current_Y+5,
- smx-ss,
- 26,
- 10)
- text.stroke()
-
- ss = xb
-
- current_Y = current_Y + 30
-
-
- # This is logic to draw ASSETS higlights.
-
- if part[0] == "link" and part[1] != assetis and not assetpart:
- assetpart = tileX
- assetis = part[1]
-
- if assetpart:
-
- if word:
- UI_color.set(assets, win, "node_asset")
- UI_elements.roundrect(assets, win,
- assetpart-5,
- win.scroll["script"] + current_Y+8,
- tileX - assetpart + len(word)*12+12,
- 22,
- 10)
-
- # Selectiong asset. ( Not actually.) But making a
- # highlight of the asset. And if clicked. Going
- # to the asset.
-
- if int(win.current['mx']) in range(int(x+assetpart-5), int(x+tileX + len(word)*12+12)) \
- and int(win.current['my']) in range(int(y+win.scroll["script"] + current_Y+8), int(y+win.scroll["script"] + current_Y+8+22)) :
-
- win.current["script_asset_higlight"] = assetis
-
- if assetis == win.current["script_asset_higlight"]:
- UI_color.set(assets, win, "text_normal")
- UI_elements.roundrect(assets, win,
- assetpart-6,
- win.scroll["script"] + current_Y+26,
- tileX - assetpart + len(word)*12+12,
- 0,
- 3)
-
-
- assetpart = tileX
- assetis = part[1]
-
- if part[0] != "link":
- assetpart = 0
- assetis = ""
-
- # And this is logic to draw SHOTS higlights.
-
- if block[0] == "shot_block" and block[1] != shotis and not shotpart:
- shotpart = tileX
- shotis = block[1]
-
-
- if shotpart:
-
- if word:
-
- # I want to randomize the shots colors. But I don't it to be an epileptic
- # show. But not too much. Let's actually write the colors into the story
- # data. Why not.
-
- if "shot_colors" not in win.story:
- win.story["shot_colors"] = {}
-
- surl = "/"+scene+"/"+shotis
- # Making it scroll to the selected shot in the story itself.
- # Thankyou very much...
- if "scroll_shot_to_in_script" not in win.current:
- win.current["scroll_shot_to_in_script"] = True
-
- if surl == win.cur and win.current["scroll_shot_to_in_script"]:
- win.scroll["script"] = (0 - current_Y) + (win.current["h"]/2)
- win.current["scroll_shot_to_in_script"] = False
-
- if surl not in win.story["shot_colors"]:
-
-
- rcolors = [
- "shot_1",
- "shot_2",
- "shot_3",
- "shot_4",
- "shot_5"
- ]
-
- win.story["shot_colors"][surl] = rcolors[len(win.story["shot_colors"]) % len(rcolors)]
-
- col = win.story["shot_colors"][surl]
-
- if int(win.current['mx']) in range(int(x+shotpart-5), int(x+tileX + len(word)*12+12)) \
- and int(win.current['my']) in range(int(y+win.scroll["script"] + current_Y+8), int(y+win.scroll["script"] + current_Y+8+22)) :
-
- win.current["script_shot_higlight"] = shotis
-
- UI_color.set(shots, win, col)
- UI_elements.roundrect(shots, win,
- shotpart-6,
- win.scroll["script"] + current_Y+5,
- tileX - shotpart + len(word)*12+12,
- 28,
- 10)
-
- # This is a bit of a hack because I was lazy to
- # figure out how to make shot markings as good
- # as I made the selection. So drawing a thing around it
- # would not really work that well. But a line under the
- # text looks quite alright. I like the look of it.
- # Maybe I will polish this in future and give people
- # an option to draw it differently. I don't know yet.
-
- if shotis == win.current["script_shot_higlight"] or shot == shotis:
- UI_color.set(shots, win, "text_normal")
- UI_elements.roundrect(shots, win,
- shotpart-6,
- win.scroll["script"] + current_Y+30,
- tileX - shotpart + len(word)*12+12,
- 0,
- 3)
-
-
-
- shotpart = tileX
- shotis = block[1]
-
- if block[0] != "shot_block":
- shotpart = 0
- shotis = ""
-
-
-
- # Now let's draw our word. Simple really. What's so special
- # about it? Why is this comment 2 lines high?
-
- UI_color.set(text, win, "text_normal")
- #if win.current["script_shot_higlight"] == block[1] or shot == block[1]:
- # UI_color.set(text, win, "darker_parts")
- text.set_font_size(20)
- text.move_to(
- tileX,
- win.scroll["script"] + current_Y+25,
- )
- text.show_text(word)
-
- # Here I want to make a selection using a mouse. I think it's quite important
- # since using a Shift key and pressing sideways is not cool
- # and I want it to be cool.
-
- if win.current["LMB"]:
- if int(win.current["LMB"][1]) in range(int(y+win.scroll["script"] + current_Y), int(y+win.scroll["script"] + current_Y)+25)\
- and int(win.current["LMB"][0]-x) in range(tileX, tileX+len(word)*12+12):
- pointer[0] = int(point - (tileX+len(word)*12 - int(win.current["LMB"][0]-x))/12 + len(word))
-
- if int(win.current["my"]) in range(int(y+win.scroll["script"] + current_Y), int(y+win.scroll["script"] + current_Y)+25)\
- and int(win.current["mx"]-x) in range(tileX, tileX+len(word)*12+12):
- pointer[1] = int(point - (tileX+len(word)*12 - int(win.current["mx"]-x))/12 + len(word))
-
- win.cur = "/"+scene
- win.textactive = ""
-
- if int(win.current["my"]) in range(int(y+win.scroll["script"] + current_Y), int(y+win.scroll["script"] + current_Y)+25)\
- and int(win.current["mx"]-x) in range(tileX, tileX+len(word)*12+12):
-
- win.current["cursor"] = win.cursors["text"]
-
- # This is the logic to draw our selection and logic that
- # come with the selection.
-
- if UI_math.line_overlap([pointer[1], pointer[0]],[point, point+len(word)+1]) and not ss:
- ss = tileX+(min(pointer[1], pointer[0])-point)*12
- smx = ss
-
- # If current word is inside the selection. It means that
- # current text part is also inside the selection. And this
- # means this part should be edited if I press a button.
-
- if UI_math.line_overlap([pointer[1], pointer[0]],[point, point+len(word)+1]):
-
- # So we need to add this part and some data about this
- # part like amount of characters it's away from the
- # begining of the scene into a list that I could reference
- # later in the writting logic.
-
- if [part, p, num, n] not in selecwords:
- selecwords.append([part, p, num, n])
-
- # Let's make something for me to understand what is going
- # on. If I will enter the testing mode. Let it draw the
- # current number of characters. And the current characrter.
-
- if win.current["testing"]:
-
- # This is our character. It's not always available.
- # sometimes you migt be on the edge of something and
- # something else. So !! will mean seomthing is wrong.
-
- try:
- c = part[-1][pointer[0]-p]
- except:
- c = "!!"
-
-
- UI_color.set(text, win, "text_normal")
- text.set_font_size(10)
- text.move_to(
- tileX+(pointer[0]-point)*12-26,
- win.scroll["script"] + current_Y+35,
- )
- text.show_text(str(pointer[0])+"["+c+"]")
-
- # Now doing it again for the second pointer. If you
- # remeber, We have 2.
-
- try:
- c = part[-1][pointer[1]-p]
- except:
- c = "!!"
-
-
- UI_color.set(text, win, "text_normal")
- text.set_font_size(10)
- text.move_to(
- tileX+(pointer[1]-point)*12-26,
- win.scroll["script"] + current_Y+35,
- )
- text.show_text(str(pointer[1])+"["+c+"]")
-
- if max(pointer[1], pointer[0]) in range(point, point+len(word)+1):
- # This is some more drawing of the selection. This is
- # if the selection is ending mid way through the line.
-
- if ss:
-
- if pointer[0] != pointer[1] :
- UI_color.set(assets, win, "node_blendfile")
- UI_elements.roundrect(assets, win,
- max(ss, xb),
- win.scroll["script"] + current_Y+5,
- min(tileX+(max(pointer[1], pointer[0])-point)*12-max(ss, xb), mt-max(ss, xb)),
- 26,
- 10)
-
- elif not win.textactive and win.blink:
- UI_color.set(text, win, "node_blendfile")
- text.rectangle(
- max(ss, xb),
- win.scroll["script"] + current_Y+5,
- min(tileX+(max(pointer[1], pointer[0])-point)*12-max(ss, xb), mt-max(ss, xb)),
- 26)
- text.stroke()
-
- # win.scroll["script"] + current_Y,
- # min(mt-max(ss,xb), mt-xb),
-
- ss = 0
- #smx = 0
-
- if win.current["keys"] and not win.textactive and not putscroll:
- putscroll = min(0 - current_Y + width/2, win.scroll["script"])
-
- # Now in the end of our word. We are counting it's lenght
- # and moving the tileX so the next word draws after this
- # one and not on top of this one. I think it's important.
-
- point = point + len(word) #################### <<<<<< POINT
- tileX = tileX + len(word)*12
-
- # Also what you probably want to happen is when you type the script
- # will scroll down. Yeah. It's not coming by default. Even on standart
- # GTK text parts. So here is a little thing.
-
-
-
- if putscroll:
- win.scroll["script"] = putscroll
-
- ############# LOGIC ###############
-
- # So I'm doing the logic of typing separatelly from rendering of the text.
- # because it kind a seems right to do so. I'm still figuring it out at this
- # point. I have no idea what could go wrong. Maybe I will reddo the whole
- # thing. Maybe few times. IDK.
-
-
-
- if 65363 in win.current["keys"]: # RIGHT
- pointer[0] = pointer[0]+1
- if not 65506 in win.current["keys"]:
- pointer[1] = pointer[0]
- #win.current["keys"].remove(65363)
-
-
- if 65361 in win.current["keys"]: # LEFT
- pointer[0] = pointer[0]-1
- if not 65506 in win.current["keys"]:
- pointer[1] = pointer[0]
- #win.current["keys"].remove(65361)
-
-
- if 65362 in win.current["keys"]: # UP
- pointer[0] = pointer[0]-min(len(line), int((mt-12)/12)) # STILL BUGGY
- if not 65506 in win.current["keys"]:
- pointer[1] = pointer[0]
- #win.current["keys"].remove(65362)
-
- if 65364 in win.current["keys"]: # DOWN
- pointer[0] = pointer[0]+min(len(line), int((mt-12)/12)) # STILL BUGGY
- if not 65506 in win.current["keys"]:
- pointer[1] = pointer[0]
- #win.current["keys"].remove(65364)
-
- # In order for history to work properly I don't want to save history on
- # each button press. But rather ones every time the scene is edited. So
-
- if "scene_edited_already" not in win.current:
- win.current["scene_edited_already"] = False
-
-
- # I'm going to implement some basic clipboard. It will need love in future.
- # I just need for now something that will "work" so to speak. See where I
- # use the clipboard variable later to learn how it all works.
-
- clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) # This is a clipboard object
-
-
- # If there is a key press that contains a string. Like anything on a keyboard
- # where you can actually type. Let's do something with it.
-
- def clean():
- # This is an empty function. Placeholder for a clean operation after
- # a given key press. Because we are dealing with multiple blocks of
- # text that look like 1 block for the user.
- pass
-
- # To make shot I want to write a little list of text parts that will come
- # into that shot.
-
- new_shot_list = []
- after_shot_list = []
- new_shot = []
-
- if win.current["key_letter"] and not win.textactive:
-
- # Here I'm going to implement history
- if not win.current["scene_edited_already"]:
- win.current["scene_edited_already"] = True
- history.record(win, "/rnd"+win.cur, "[Edited]")
-
-
- #print("------{ BEFORE }--------")
- #print(win.story["scenes"][scene]["shots"])
- #print("------{ }------")
- #print()
-
-
- #print() # For testing
-
- for u, stuff in enumerate(selecwords):
- part, p, num, n = stuff
-
- try:
- block = win.story["scenes"][scene]["shots"][num]
- except:
- break
-
- try:
- ORD = ord(win.current["key_letter"])
- except:
- ORD = 0
-
- print(ORD, "ORD") # Output the value of the button.
-
- # Now some of the ORDs I found to be weird characters. Like on
- # CTRL - C or CTRL - V. So I want to filter them out. So there
- # wont be a bunch of rectangles every time you type.
-
- # Now I need the minimum and maximum parts. So there will not be
- # scips of content I guess.
-
- MIN = min(len(part[-1]), max(0, min(pointer[1], pointer[0])-p))
- MAX = max(0, min(len(part[-1]), max(pointer[1], pointer[0])-p))
-
- #print(pointer,"POINTER")
- #print(p, "P")
- #print(len(part[-1]), "LENGHT", [part[-1]])
- #print(MIN, "MIN")
- #print(MAX, "MAX")
- #print()
-
- # Here I want to record undo history for the script writer. I am going
- # to ignore the letters. And only forcus on other simbols such as
- # spacebars and various commands.
-
- nonhistory = "1234567890qwertyuiopasdfghjklzxcvbnnmQWERTYUIOPASDFGHJKLZXCVBNM"
-
- if win.current["key_letter"] not in nonhistory and ORD not in [26, 25]:
- story.undo_record(win)
- # Multiuser sycning
- win.multiuser["request"] = "story"
-
- # Now let's retrive out data.
-
- # UNDO
- if ORD == 26:
- story.undo(win)
-
- # REDO
- if ORD == 25:
- story.redo(win)
-
-
- if u == 0:
-
- if ORD not in range(32) or ORD in range(127, 160):
-
- # Typing logic
-
- part[-1] = \
- part[-1][:MIN]+\
- win.current["key_letter"]+\
- part[-1][MAX:]
-
- def clean():
- pointer[0] = pointer[0] + 1
- pointer[1] = pointer[0]
- point = point + 1
-
- if ORD == 22: # Paste ( Ctrl - V )
-
- cliptext = str(clipboard.wait_for_text())
-
- part[-1] = \
- part[-1][:MIN]+\
- cliptext+\
- part[-1][MAX:]
-
- def clean():
- pointer[0] = pointer[0] + len(cliptext)
- pointer[1] = pointer[0]
-
- point = point + len(cliptext)
-
- if ORD == 3: # Copy ( Ctrl - C )
-
- clipboard.set_text( part[-1][MIN:MAX] , -1) # VERY BASIC
-
- # If ord 13 it means you pressed enter. And it should be a new line.
- # but for some reason it's ord 13. Maybe it is a new line. Who knows
- # Anyway. It does not return \n but returns a weird rectangle. So
- # here is a little solution.
-
- if ORD == 13: # ENTER
-
- # Only I want to use new line to exit from all kind of things.
- # Like double enter will exit the frase. Ans stuff like this.
-
- if part[-1][MIN-1] == "\n" and part[0] != "text":
-
- block[-1].insert(n+1,
- ["text", "\n"]
- )
- block[-1].insert(n+2,
- ["text", part[-1][MAX:]+" "]
- )
-
- part[-1] = \
- part[-1][:MIN-1]
-
- else:
- part[-1] = \
- part[-1][:MIN]+\
- "\n"+\
- part[-1][MAX:]
-
- def clean():
- pointer[0] = pointer[0] + 1
- pointer[1] = pointer[0]
- point = point + 1
-
- if ORD == 4: # CTRL D ( FOR SOME REASON)
-
- block[-1].insert(n+1,
- ["frase", ["text", " "], " "]
- )
- block[-1].insert(n+2,
- ["text", part[-1][MAX:]]
- )
-
- part[-1] = \
- part[-1][:MIN]
- def clean():
- pointer[0] = pointer[0] + 1
- pointer[1] = pointer[0]
- point = point + 1
-
- # Activating the editing of the name automatically
- if "current_name_frase_editing" in win.text:
- win.text["current_name_frase_editing"]["text"] = ""
- if "current_name_frase_editing" not in win.current:
- win.current["current_name_frase_editing"] = False
- win.current["current_name_frase_editing"] = [num, n+1]
- win.textactive = "current_name_frase_editing"
-
- if ORD == 8: # BACKSPACE
- if pointer[1] == pointer[0]:
- part[-1] = \
- part[-1][:MIN-1]+\
- part[-1][MAX:]
- def clean():
- pointer[0] = pointer[0] - 1
- pointer[1] = pointer[0]
- point = point - 1
- else:
- part[-1] = \
- part[-1][:MIN]+\
- part[-1][MAX:]
- def clean():
- pointer[0] = min(pointer[0], pointer[1])
- pointer[1] = pointer[0]
-
- if ORD == 127: # DELETE (FORWARD)
- part[-1] = \
- part[-1][:MIN]+\
- part[-1][MAX+1:]
- def clean():
- pointer[0] = pointer[0]
- pointer[1] = pointer[0]
-
- if ORD == 19: # NEW SHOT ( CTRL - S )
- app = part.copy()
- app[-1] = part[-1][MIN:MAX]
- new_shot_list.append(app)
- new_shot = [num , n]
-
- after_shot_list = block.copy()
- after_shot_list[-1] = []
-
- app2 = part.copy()
- app2[-1] = part[-1][MAX:]
- after_shot_list[-1].append(app2)
-
- part[-1] = part[-1][:MIN]
-
- if ORD == 12 and part[0] == "text" and pointer[1] != pointer[0]: # Asset higlight
-
- if "linking_asset_operation_metadata" not in win.current:
- win.current["linking_asset_operation_metadata"] = []
-
- win.current["linking_asset_operation_metadata"] = [part , block, MIN, MAX]
-
- def after(win, var):
- print(var)
- if var:
-
- part , block, MIN, MAX = win.current["linking_asset_operation_metadata"]
-
- block[-1].insert(n+1,
- ["link", var, part[-1][MIN:MAX]]
- )
- block[-1].insert(n+2,
- ["text", part[-1][MAX:]]
- )
-
- part[-1] = \
- part[-1][:MIN]
- win.current["key_letter"] = ""
-
- studio_dialogs.asset_select(win, "link_asset_script_frase", after,
- SEARCH=part[-1][MIN:MAX])
-
- if ORD == 9 and part[0] == "text" and pointer[1] == pointer[0]: # Insert image
-
- if "linking_asset_operation_metadata" not in win.current:
- win.current["linking_asset_operation_metadata"] = []
-
- win.current["linking_asset_operation_metadata"] = [part , block, MIN, MAX]
-
- def after(win, var):
- print(var)
- if var:
-
- part , block, MIN, MAX = win.current["linking_asset_operation_metadata"]
-
- block[-1].insert(n+1,
- ["image", var]
- )
- block[-1].insert(n+2,
- ["text", part[-1][MAX:]]
- )
-
- part[-1] = \
- part[-1][:MIN]
- win.current["key_letter"] = ""
-
- studio_dialogs.file_select(win, "link_asset_script_frase", after,
- SEARCH=part[-1][MIN:MAX])
-
-
-
- # Making stuff happen
- elif u < len(selecwords)-1:
- if ORD not in [12, 19, 3, 22, 26, 25]: # 3 = Crtl - C, 22 = Ctrl - V
- part[-1] = ""
-
- if ORD == 19:
- app = part.copy()
- new_shot_list.append(app)
-
- part[-1] = ""
-
- else:
-
- MIN = min(len(part[-1])-1, max(0, min(pointer[1], pointer[0])-p))
- MAX = max(0, min(len(part[-1])-1, max(pointer[1], pointer[0])-p))
-
- if ORD not in [12, 19, 3, 22, 26, 25]:
- part[-1] = part[-1][MAX:]
-
- if ORD == 19:
- app = part.copy()
- app[-1] = part[-1][MIN:]
- new_shot_list.append(app)
-
-
- part[-1] = ""
-
- # Saving to the file
- story.save(win.project, win.story)
- win.current["key_letter"] = ""
-
- # Let's get all the rest of the parts from that block so I could insert them
- # as a separate thing later. Because we basically splitting 1 block into 3
- # making the selection. Middle one our new shot_block. And the rest. Should
- # stay the same.
-
- if new_shot:
- num , n = new_shot
- for l, part in enumerate(win.story["scenes"][scene]["shots"][num][-1]):
- if l > n:
- app = part.copy()
- after_shot_list[-1].append(app)
- part[-1] = ""
- if after_shot_list[0] == "shot_block"\
- and win.story["scenes"][scene]["shots"][num][0] == "shot_block":
- after_shot_list[1] = win.story["scenes"][scene]["shots"][num][1]
-
- if new_shot_list:
-
- #print("NEW: ", new_shot_list)
- #print("KEEP: ", after_shot_list)
-
- nename = "Shot_1"
- count = 1
- while nename in shot_list:
- count = count + 1
- nename = "Shot_"+str(count)
-
-
- num , n = new_shot
- win.story["scenes"][scene]["shots"].insert(num+1,
- ["shot_block", nename, new_shot_list])
-
- win.story["scenes"][scene]["shots"].insert(num+2,
- after_shot_list)
-
- # Saving to the file
- story.save(win.project, win.story)
-
- #print()
- #print("------{ AFTER }--------")
- #print(win.story["scenes"][scene]["shots"])
- #print("------{ }------")
-
- clean()
-
- current_Y = current_Y + 30
-
-
-
-
- if scene not in win.story["pointers"]:
- pointer = [point, point]
- win.story["pointers"][scene] = pointer
- else:
- pointer[0] = min(pointer[0], point)
- pointer[1] = min(pointer[1], point)
- pointer[0] = max(pointer[0], 1)
- pointer[1] = max(pointer[1], 1)
- win.story["pointers"][scene] = pointer
-
- # Selecting the shot
- if win.current["script_shot_higlight"] and win.previous["LMB"] and not win.current["LMB"]:
- win.cur = "/"+scene+"/"+win.current["script_shot_higlight"]
- select_shot(win)
- win.current["shot_left_side_scroll_please_work_omg_wtf"] = True
-
- # Going to that asset
-
- if win.current["script_asset_higlight"] and win.previous["LMB"] and not win.current["LMB"]:
- try:
- del win.text["scene_name"]
- win.previous["script_asset_higlight"]
- win.url = "assets"
- win.cur = win.current["script_asset_higlight"]
- win.current["asset_scene_selected"] = scene
- win.current["asset_left_panel"] = "scene"
- del win.current["script_asset_higlight"]
- # Saving to the file
- story.save(win.project, win.story)
- except:
- pass
-
-
-
-
- ###########################
-
- # And finally combine the layers
-
- # Outputting the layer
- layer.set_source_surface(frasesurface, x, y)
- layer.paint()
-
- # Outputting the layer
- layer.set_source_surface(shotsurface, x, y)
- layer.paint()
-
- # Outputting the layer
- layer.set_source_surface(assetsurface, x, y)
- layer.paint()
-
- # Outputting the layer
- layer.set_source_surface(textsurface, x, y)
- layer.paint()
-
- # Scroll
- UI_elements.scroll_area(layer, win, "script",
- x+0,
- y+0,
- width+30,
- height-0,
- current_Y,
- bar=True,
- mmb=True,
- bar_always=True)
-
- ####### BOTTOM PANEL #########
-
- UI_color.set(layer, win, "node_background")
- UI_elements.roundrect(layer, win,
- win.current["w"]/4,
- win.current["h"]-50,
- win.current["w"]/2,
- 40,
- 10)
-
- # Documentation entry
- def do():
- def after(win, var):
- pass
-
- studio_dialogs.help(win, "help", after, SEARCH=talk.text("documentation_script_writer"))
-
- UI_elements.roundrect(layer, win,
- win.current["w"]/4,
- win.current["h"]-50,
- 40,
- 40,
- 10,
- do,
- "question")
-
- # Here in the bottom I want to introduce little things to go between scenes
- # back and forth.
-
- left = ""
- right = ""
-
- for arrow in win.story["arrows"]:
- if arrow[0][1] == scene and arrow[1] != "end":
- right = arrow[1][1]
- if arrow[1][1] == scene and arrow[0] != "start":
- left = arrow[0][1]
-
-
- if left:
- def do():
- win.scroll["script"] = 0
- win.cur = "/"+left
- win.url = "script"
- try:
- del win.text["scene_name"]
- except:
- pass
-
- UI_elements.roundrect(layer, win,
- win.current["w"]/2-45,
- win.current["h"]-50,
- 40,
- 40,
- 10,
- button=do,
- icon="left")
-
- if right:
- def do():
- win.scroll["script"] = 0
- win.cur = "/"+right
- win.url = "script"
- try:
- del win.text["scene_name"]
- except:
- pass
-
- UI_elements.roundrect(layer, win,
- win.current["w"]/2+5,
- win.current["h"]-50,
- 40,
- 40,
- 10,
- button=do,
- icon="right")
-
-
- # CANCEl
-
- def do():
- win.url = "story_editor"
- win.assets = {}
- try:
- del win.text["scene_name"]
- except:
- pass
- win.story["selected"] = [["scene", scene]]
- win.scroll["script"] = 0
- win.current["scene_edited_already"] = False
-
- UI_elements.roundrect(layer, win,
- win.current["w"]-40-win.current["w"]/4,
- win.current["h"]-50,
- 40,
- 40,
- 10,
- button=do,
- icon="cancel",
- tip=talk.text("cancel"))
-
- # Short cut ESC
- if 65307 in win.current["keys"] and not win.textactive:
- do()
- win.current["keys"].remove(65307)
-
- ############# CHECKLIST #################
-
- # Here I want to have some checklists. Now... I have 4 types of new check-
- # lists prepared for shots and scene. There are 3 types of checklists for
- # a shot. So I can't just simply generate one on the fly. Since I don't
- # know whether this shot is a simple shot, animated or VFX. And also I
- # don't want to generate folders when they are not nessesary. So I want to
- # implement a kind of selection thingy when if a checklists does not exist.
-
- # Now let's first of all display our checklists properly.
-
- if os.path.exists(win.project+"/rnd"+win.cur+"/shot.progress"):
- checklist.draw(layer, win, win.project+"/rnd"+win.cur+"/shot.progress", back=win.url)
- elif os.path.exists(win.project+"/rnd"+win.cur+"/scene.progress") and not shot:
- checklist.draw(layer, win, win.project+"/rnd"+win.cur+"/scene.progress", back=win.url)
-
- else:
-
- # Now if we have no checklist what so ever. We want to give user a way
- # to choose to generate one.
-
- x = win.current["w"] / 4 * 3 + 10
- y = 10
- width = win.current["w"] / 4 - 20
- height = win.current["h"] - 20
-
-
- if shot:
-
- # If we are in a shot I want to give different option to choose from
- # then if we are just simply in a scene.
-
- shot_options = {
- "shot":"add_shot_live_checklist",
- "shot_anim":"add_shot_anim_checklist", # First name of new_file then text on screen
- "shot_vfx":"add_shot_vfx_checklist"
- }
-
- for num, option in enumerate(shot_options):
-
- # We want to draw a button, a rectangle arround it and the text
- # tooltip.
-
- def do():
-
- # First let's make sure that the folder exists. Because
- # it might not exists. I think doing it automatically
- # makes sense.
-
- try:
- os.makedirs(win.project+"/rnd"+win.cur)
- except:
- pass
-
- # Then we copy the file.
-
- oscalls.copy_file(
- win,
- os.getcwd()+"/new_file/"+option+".progress",
- "/rnd"+win.cur+"/",
- "shot.progress")
-
-
- UI_elements.roundrect(layer, win,
- x,
- y+(50*num),
- width,
- 40,
- 10,
- button=do,
- icon="checklist_new")
-
- UI_color.set(layer, win, "progress_background")
- UI_elements.roundrect(layer, win,
- x,
- y+(50*num),
- width,
- 40,
- 10,
- fill=False)
- layer.stroke()
-
- UI_color.set(layer, win, "text_normal")
- layer.set_font_size(20)
- layer.move_to( x+50, y+(50*num)+25)
- layer.show_text(talk.text(shot_options[option]))
- # Add checklist from clipboard
- def do():
- clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
- cliptext = str(clipboard.wait_for_text())
- savetext = ""
- for i in cliptext.split("\n"):
- if "[ ]" in i or "[V]" in i or "[v]" in i:
- savetext = savetext + "\n"+i.replace("[V]", "[ ]").replace("[v]", "[ ]")
- else:
- savetext = savetext + "\n[ ] #"+i
- cliptext = savetext[1:]
-
- filepath = win.project+"/rnd"+win.cur+"/shot.progress"
- s = open(filepath, 'w')
- s.write(cliptext)
- s.close()
-
- UI_elements.roundrect(layer, win,
- x,
- y+(50*num+50),
- width,
- 40,
- 10,
- button=do,
- icon="checklist_new")
- UI_color.set(layer, win, "progress_background")
- UI_elements.roundrect(layer, win,
- x,
- y+(50*num+50),
- width,
- 40,
- 10,
- fill=False)
- layer.stroke()
- UI_color.set(layer, win, "text_normal")
- layer.set_font_size(20)
- layer.move_to( x+50, y+(50*num+50)+25)
- layer.show_text(talk.text("new_checklist_from_clipboard"))
-
- else:
-
- # Now... If it's not a shot. We can do it in one line.
- # It's pretty simple.
-
- def do():
-
- # First let's make sure that the folder exists. Because
- # it might not exists. I think doing it automatically
- # makes sense.
-
- try:
- os.makedirs(win.project+"/rnd"+win.cur)
- except:
- pass
-
- # Then we copy the file.
-
- oscalls.copy_file(
- win,
- os.getcwd()+"/new_file/scene.progress",
- "/rnd"+win.cur+"/",
- "scene.progress")
-
-
- UI_elements.roundrect(layer, win,
- x,
- y,
- width,
- 40,
- 10,
- button=do,
- icon="checklist_new")
-
- UI_color.set(layer, win, "progress_background")
- UI_elements.roundrect(layer, win,
- x,
- y,
- width,
- 40,
- 10,
- fill=False)
- layer.stroke()
-
- UI_color.set(layer, win, "text_normal")
- layer.set_font_size(20)
- layer.move_to( x+50, y+25)
- layer.show_text(talk.text("add_scene_checklist"))
-
-
- ############## LEFT PANEL #####################
-
- leftpanellist = ["shot", "schedule", "history"] # Using the names of the icons.
-
- # We need to choose the correct category based smartly on the project's
- # current progress. Or at least on the current progress of this asset.
-
- if "script_left_panel" not in win.current:
-
- win.current["script_left_panel"] = "shot"
-
- # A little banner.
-
- UI_color.set(layer, win, "node_background")
- UI_elements.roundrect(layer, win,
- 10,
- 10,
- win.current["w"]/4-20,
- 50,
- 10)
-
- for num, thing in enumerate(leftpanellist):
- if win.current["script_left_panel"] == thing:
-
- UI_color.set(layer, win, "progress_time")
- UI_elements.roundrect(layer, win,
- 20+(40*num),
- 15,
- 40,
- 40,
- 10)
-
- def do():
- win.current["script_left_panel"] = thing
-
- UI_elements.roundrect(layer, win,
- 20+(40*num),
- 15,
- 40,
- 40,
- 10,
- do,
- thing)
-
- ### SCHEDULES ###
-
- if win.current["script_left_panel"] == "schedule":
- schedule.draw(layer, win)
-
- ### HISTORY ###
-
- if win.current["script_left_panel"] == "history":
- history.draw(layer, win)
-
-
- #### SHOTS ####
-
- if win.current["script_left_panel"] == "shot":
-
- # Here I want to draw the left panel full of shots and stuff. So you
- # could access the animation Blend-Files, render them and see analytics
- # or rendering.
-
- # Since it's the last thing I'm drawing to this layer. I guess we can clip it.
- # Small progress bar of the scene:
- # # Progressbar
-
- scenedone = win.story["scenes"][scene]["fraction"]
- UI_color.set(layer, win, "progress_background")
- UI_elements.roundrect(layer, win,
- 150,
- 25,
- win.current["w"]/4-180,
- 20,
- 10,
- tip="Entire scene: "+str(round(scenedone*100, 1))+"%")
- # Project Done
- UI_color.set(layer, win, "progress_active")
- UI_elements.roundrect(layer, win,
- 150,
- 25,
- (win.current["w"]/4-180)*scenedone,
- 20,
- 10)
- x = 10
- y = 70
- width = win.current["w"] / 4 - 20
- height = win.current["h"] - 80
-
-
- UI_elements.roundrect(layer, win,
- x,
- y,
- width,
- height,
- 10,
- fill=False)
- layer.clip()
-
-
- if "script_shots" not in win.scroll:
- win.scroll["script_shots"] = 0
-
- current_Y_shots = 0
-
- rcolors = [
- "shot_1",
- "shot_2",
- "shot_3",
- "shot_4",
- "shot_5"
- ]
-
- # So let's itterate over a list of shots we've got from the textview.
-
- for shotis in shot_list:
-
-
-
- # Getting the color. It's not always works.
-
- if "shot_colors" not in win.story:
- win.story["shot_colors"] = {}
-
- surl = "/"+scene+"/"+shotis
- if "shot_left_side_scroll_please_work_omg_wtf" not in win.current:
- win.current["shot_left_side_scroll_please_work_omg_wtf"] = False
- if win.current["shot_left_side_scroll_please_work_omg_wtf"] and win.cur == surl:
- win.scroll["script_shots"] = 0-current_Y_shots+60
- win.current["shot_left_side_scroll_please_work_omg_wtf"] = False
-
- if surl not in win.story["shot_colors"]:
-
- win.story["shot_colors"][surl] = rcolors[len(win.story["shot_colors"]) % len(rcolors)]
-
- col = win.story["shot_colors"][surl]
-
- UI_color.set(layer, win, "node_background")
- UI_elements.roundrect(layer, win,
- x,
- y+win.scroll["script_shots"]+current_Y_shots,
- width,
- 50,
- 10)
- UI_color.set(layer, win, col)
- UI_elements.roundrect(layer, win,
- x+60,
- y+win.scroll["script_shots"]+current_Y_shots+15,
- 10,
- 10,
- 10)
-
- # SHOT NAME
- UI_color.set(layer, win, "text_normal")
- layer.set_font_size(20)
- layer.move_to( x+90, y+win.scroll["script_shots"] + current_Y_shots+30)
- layer.show_text(shotis)
-
- # ICON
- UI_elements.image(layer, win,
- "settings/themes/"+win.settings["Theme"]+"/icons/shot.png",
- 20, y+win.scroll["script_shots"] + current_Y_shots+5, 40, 40)
-
- # The selection will be badically the current win.cur value. SO...
-
- if surl == win.cur:
-
- UI_color.set(layer, win, "text_normal")
- UI_elements.roundrect(layer, win,
- x,
- y+win.scroll["script_shots"]+current_Y_shots,
- width,
- 50,
- 10,
- fill=False)
- layer.stroke()
-
- # If this shot has a folder already. Unfortunatly it's not wise
- # to make it editable. But I already talk about it in the
- # beggining of this file.
-
- # But a folder button could be cool.
-
- if os.path.exists(win.project+"/rnd"+win.cur):
- def do():
- oscalls.Open(win.project+"/rnd"+win.cur)
-
- UI_elements.roundrect(layer, win,
- width-45,
- y+win.scroll["script_shots"]+current_Y_shots+5,
- 40,
- 40,
- 10,
- do,
- "folder",
- tip="/rnd"+win.cur )
- else:
-
- # If there is no folder I want to give people an ability
- # to edit it. I think let's do it like with checklists.
- # like a little second button. That if you click it. You
- # create a text entry. I know. Quite a lot of text entries.
- # There will be more.
-
- if "current_shot_name_editor" not in win.current:
- win.current["current_shot_name_editor"] = ""
-
- # Now if the button is clicked. There will be an editor
- # let's make one.
-
- if win.current["current_shot_name_editor"] == shotis and win.textactive == "shot_name":
-
- UI_elements.text(layer, win, "shot_name",
- x+85,
- y+win.scroll["script_shots"]+current_Y_shots+5,
- width-90,
- 40,
- set_text=shotis)
-
- # Now let's make it applyable. But first we need to filter
- # the name. So there will not be any weird stuff. So the
- # folder when it's created will not make problems.
-
- newname = win.text["shot_name"]["text"].replace("/","_").replace(" ", "_")\
- .replace('"',"_").replace("(","_").replace(")","_").replace("'","_")\
- .replace("[","_").replace("]","_").replace("{","_").replace("}","_")
-
- if newname not in shot_list:
-
- def do():
- win.current["key_letter"] = ""
-
- shot_list[shotis][1] = newname
- win.cur = "/"+scene+"/"+newname
-
- # Saving to the file
- story.save(win.project, win.story)
-
- UI_elements.roundrect(layer, win,
- width-45,
- y+win.scroll["script_shots"]+current_Y_shots+5,
- 40,
- 40,
- 10,
- button=do,
- icon="ok")
-
- else:
-
- # A button to activate the editing I guess.
-
- def do():
- win.current["current_shot_name_editor"] = shotis
- try:
- del win.text["shot_name"]
- except:
- pass
-
- win.textactive = "shot_name"
-
- UI_elements.roundrect(layer, win,
- x+85,
- y+win.scroll["script_shots"]+current_Y_shots+5,
- width-90,
- 40,
- 10,
- button=do,
- fill=False)
- layer.stroke()
-
-
- current_Y_shots = current_Y_shots + 60
-
- # Let's make the color selectiong thing. Because I know people
- # gonna eat me alive if the software does everything for them.
- # Especially when it's something that customazible.
-
- for num, col in enumerate(rcolors):
-
- if win.story["shot_colors"][surl] == col:
-
- # If the current color is the color of the shot then
- # let's draw a little white thing around it.
-
- UI_color.set(layer, win, "text_normal")
- UI_elements.roundrect(layer, win,
- x+(width/len(rcolors)*num),
- y+win.scroll["script_shots"]+current_Y_shots-2,
- width/len(rcolors),
- 10,
- 12)
-
- UI_color.set(layer, win, col)
- UI_elements.roundrect(layer, win,
- x+(width/len(rcolors)*num)+2,
- y+win.scroll["script_shots"]+current_Y_shots,
- width/len(rcolors)-4,
- 10,
- 10)
-
- # Also let's make a button that the user can click to change
- # the color.
-
- def do():
- win.story["shot_colors"][surl] = col
- UI_elements.roundrect(layer, win,
- x+(width/len(rcolors)*num),
- y+win.scroll["script_shots"]+current_Y_shots-2,
- width/len(rcolors),
- 20,
- 12,
- button=do,
- fill=False)
- layer.stroke()
-
- current_Y_shots = current_Y_shots + 30
-
- # Now let's draw 4 main folders of the shot.
-
- # storyboard
- # opengl
- # test_rnd
- # rendered
-
- # There is also an extra folder created always.
- # but since it's very technical let's not include it here.
- # let's focus on those 4 because for the user these 4 will
- # be our progress bar.
-
- ##### ##### ##### #####
- ########## ######### ########## ######## ##########
- ##### ##### ##### #####
-
- # Like 4 links in a chain or something. I think it's a good
- # representation.
-
- fouricons = {
- "storyboard":[],
- "opengl":[],
- "test_rnd":[],
- "rendered":[]
- }
-
- fraction = 0.0
-
- # Let's create a variable for the current selected folder.
-
- if shotis+"_active_folder" not in win.current:
- win.current[shotis+"_active_folder"] = "Pending"
-
- for numb, icon in enumerate(fouricons):
-
- # While we are drawing them. Let's find out whether there
- # are any images inside. If yes. We add this to the over
- # all percentage.
-
- files = []
- try:
- files = sorted(os.listdir(win.project+"/rnd"+win.cur+"/"+icon))
- except:
- pass
-
- fouricons[icon] = files
-
- if files:
- fraction = 0.25*(numb+1)
-
- # If the icon is currently selected.
-
- if win.current[shotis+"_active_folder"] == icon:
- UI_color.set(layer, win, "progress_time")
- UI_elements.roundrect(layer, win,
- x+(width/5)*numb+(width/10)+20,
- y+win.scroll["script_shots"]+current_Y_shots-2,
- 40,
- 40,
- 20)
-
- def do():
- win.current[shotis+"_active_folder"] = icon
-
- UI_elements.roundrect(layer, win,
- x+(width/5)*numb+(width/10)+20,
- y+win.scroll["script_shots"]+current_Y_shots-2,
- 40,
- 40,
- 20,
- button=do,
- icon=icon,
- tip=icon)
-
-
- current_Y_shots = current_Y_shots + 50
-
- # Let's find out which one is going to be selected.
-
- if win.current[shotis+"_active_folder"] == "Pending":
- if fouricons["rendered"]:
- win.current[shotis+"_active_folder"] = "rendered"
- elif fouricons["test_rnd"]:
- win.current[shotis+"_active_folder"] = "test_rnd"
- elif fouricons["opengl"]:
- win.current[shotis+"_active_folder"] = "opengl"
- else:
- win.current[shotis+"_active_folder"] = "storyboard"
-
-
- # Now let's draw a line that will act almost like a progress
- # bar of a kind.
-
- # It will be made of 4 circles stading on a line.
-
- UI_color.set(layer, win, "progress_background")
- UI_elements.roundrect(layer, win,
- x+20,
- y+win.scroll["script_shots"]+current_Y_shots-2,
- width-40,
- 0,
- 5)
-
- UI_color.set(layer, win, "progress_active")
- UI_elements.roundrect(layer, win,
- x+20,
- y+win.scroll["script_shots"]+current_Y_shots-2,
- (width-40)*fraction,
- 0,
- 5)
-
- # Now the 4 circles.
-
- for numb, icon in enumerate(fouricons):
-
-
- UI_color.set(layer, win, "progress_background")
- if fouricons[icon]: # If this folder has any files.
- UI_color.set(layer, win, "progress_active")
- UI_elements.roundrect(layer, win,
- x+(width/5)*numb+(width/10)+30,
- y+win.scroll["script_shots"]+current_Y_shots-7,
- 0,
- 0,
- 10)
-
- current_Y_shots = current_Y_shots + 50
- ifremote = 0
- if win.analytics["from-remote-server"]:
- ifremote = 50
- if "remote-folder-data" not in win.current:
- win.current["remote-folder-data"] = {}
- if win.cur not in win.current["remote-folder-data"]:
- win.current["remote-folder-data"][win.cur] = {"missing":{},
- "changed":{}}
-
- def do():
- def after(win, var):
- UI_elements.reload_images(win)
- win.current["remote-folder-data"]["prompt"] = win.cur
- studio_dialogs.http_client_update_prompt(win, "http-client-prompt", after)
-
- UI_elements.roundrect(layer, win,
- 10,
- y+win.scroll["script_shots"]+current_Y_shots-10,
- 40,
- 40,
- 10,
- button=do,
- icon="download",
- tip=talk.text("RemoteShotUpdates"))
- if win.current["remote-folder-data"][win.cur]["missing"] or win.current["remote-folder-data"][win.cur]["changed"]:
- count = str(len(win.current["remote-folder-data"][win.cur]["missing"])+len(win.current["remote-folder-data"][win.cur]["changed"]))
- UI_color.set(layer, win, "progress_active")
- UI_elements.roundrect(layer, win,
- 10+25,
- y+win.scroll["script_shots"]+current_Y_shots-10,
- len(count)*12+6,
- 25,
- 5)
- layer.fill()
- UI_color.set(layer, win, "text_normal")
- layer.set_font_size(20)
- layer.move_to(10+28,
- y+win.scroll["script_shots"]+current_Y_shots-10+20)
- layer.show_text(count)
-
- # The user might want to add the subfolders if they do not
- # exist already.
- at_least_one_missing = False
- list_of_folders_to_generate = ["storyboard", "opengl", "test_rnd", "rendered", "extra"]
- files_there = []
- try:
- files_there = os.listdir(win.project+"/rnd"+win.cur)
- except:
- pass
- for i in list_of_folders_to_generate:
- if i not in files_there:
- at_least_one_missing = True
-
- if at_least_one_missing:
- def do():
- for i in list_of_folders_to_generate:
- try:
- os.makedirs(win.project+"/rnd"+win.cur+"/"+i)
- except:
- pass
- UI_elements.roundrect(layer, win,
- ifremote+10,
- y+win.scroll["script_shots"]+current_Y_shots-10,
- width-30-ifremote,
- 40,
- 10,
- button=do,
- icon="folder",
- tip=talk.text("GenerateSubfoldersTip"))
- UI_color.set(layer, win, "text_normal")
- layer.move_to(ifremote+60, y+win.scroll["script_shots"]+current_Y_shots+15)
- layer.show_text(talk.text("GenerateSubfolders"))
- if at_least_one_missing or win.analytics["from-remote-server"]:
- current_Y_shots = current_Y_shots + 50
-
-
-
- # Now after we have the progress bar / selection type thingy.
- # let's do a preview of the render. Usually. When rendering
- # using Blender-Organizer legacy ( or blender console ) it makes
- # files like 0001.png, 0002.png, 0003.png and so on. Now
- # user might any type of stuff in that folder. And I don't want
- # a broken program if stuff like this happens. So.
-
- if shotis+"_active_folder_item" not in win.current:
- win.current[shotis+"_active_folder_item"] = 0
-
- # Making sure that we never going to select something beyond selectable.
- if win.current[shotis+"_active_folder_item"] > len(fouricons[win.current[shotis+"_active_folder"]])-1:
- win.current[shotis+"_active_folder_item"] = len(fouricons[win.current[shotis+"_active_folder"]])-1
-
-
- # This will be the user selected file inside the folder.
-
-
- # The frame. In case image fails to load.
-
- UI_color.set(layer, win, "progress_background")
- UI_elements.roundrect(layer, win,
- x+5,
- y+win.scroll["script_shots"]+current_Y_shots-7,
- width-10,
- 200,
- 10,
- fill=False)
- layer.stroke()
-
- # Image it self.
- if fouricons[win.current[shotis+"_active_folder"]]:
-
- imageurl = win.project+"/rnd"+win.cur+"/"+win.current[shotis+"_active_folder"]+"/"+fouricons[win.current[shotis+"_active_folder"]][win.current[shotis+"_active_folder_item"]]
-
- UI_elements.image(layer, win,
- imageurl,
- x+10,
- y+win.scroll["script_shots"]+current_Y_shots-2,
- int(width-20),
- int(190),
- cell="shot_renders")
-
- # Well how to live without a clickable openable thingy.
-
- def do():
- oscalls.file_open(win, imageurl)
- UI_elements.roundrect(layer, win,
- x+5,
- y+win.scroll["script_shots"]+current_Y_shots-7,
- width-10,
- 200,
- 10,
- button=do,
- fill=False)
- layer.stroke()
- else:
- # If there is no image to show we can put one. Using a clipboard.
- def do():
- clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
- im = clipboard.wait_for_image()
- if not im:
- return
- Px = im.get_width()
- Py = im.get_height()
- Pc = cairo.ImageSurface(cairo.FORMAT_ARGB32, Px, Py)
- Pb = cairo.Context(Pc)
- Gdk.cairo_set_source_pixbuf( Pb, im, 0, 0)
- Pb.paint()
- imageurl = win.project+"/rnd"+win.cur+"/"+win.current[shotis+"_active_folder"]+"/0001.png"
- try:
- os.makedirs(win.project+"/rnd"+win.cur+"/"+win.current[shotis+"_active_folder"])
- except:
- pass
- Pc.write_to_png(imageurl)
-
-
- UI_elements.roundrect(layer, win,
- x+5+(width/2)-20,
- y+win.scroll["script_shots"]+current_Y_shots-7+80,
- 40,
- 40,
- 10,
- button=do,
- icon="image_new")
-
- current_Y_shots = current_Y_shots + 210
-
- # After we drew our image. Let's draw a little timeline thing.
- # so the user could select which frame from the animation they
- # want to see. Basically a little bar. I guess. IDK. Like
- # Blender's timeline I guess. But later I will draw a time
- # graph on it. So it's not as simple as that.
-
- UI_color.set(layer, win, "dark_overdrop")
- layer.rectangle(
- x+5,
- y+win.scroll["script_shots"]+current_Y_shots,
- width-10,
- 100)
- layer.fill()
-
- numofis = len(fouricons[win.current[shotis+"_active_folder"]])
-
- # Here as you can see I made the the rectangle a 100 pixels high
- # this is for 1 simple reason. To be able to draw analytics.
-
- # But.
-
- # There are like one million problems with it. Let's go over them.
-
- # * There are multiple blend files each one with analytics data.
-
- # * Reading JSON files and drawing graphs is not a trivial thing
- # requiring cashing of the image. Such as in Analytics window.
- # Bull will see.
-
- # * During rendeing the DATA changes. And I want to see the up
- # to date data at all times.
-
- # Let's try to implement it the simple way. Reading everything
- # live. I've done that in Blender-Organizer. But the data was
- # way simpler.
-
- alldata = {}
- largest = 1
-
- # WAIT extra might not exists.
-
- try:
- for filename in os.listdir(win.project+"/rnd"+win.cur+"/extra"):
- if filename.endswith(".blend.json"):
-
- # I want to now open JSON FILE for each one and parse
- # it. Actually when I think about it. It's not supposed
- # to be that bad. But this computer has an SSD. LOL.
-
- data = {}
- try:
- with open(win.project+"/rnd"+win.cur+"/extra/"+filename) as json_file:
- data = json.load(json_file)
-
- # Since I'm inside try I can do some wild stuff here.
- data = data["analytics"][win.current[shotis+"_active_folder"]]
-
- alldata[filename.replace(".json", "")] = data
-
- for i in data:
- if data[i] > largest:
- largest = data[i]
-
- except:
- pass
- except:
- pass
-
- # So let's now read through all the data that we have
- for n, blend in enumerate(alldata):
-
- data = alldata[blend]
-
- # I want each new file to have it's own color. So
-
- UI_color.set(layer, win, rcolors[n % len(rcolors)])
- layer.move_to(
- x+5,
- y+win.scroll["script_shots"]+current_Y_shots+100
- )
-
- # Now let's draw everything.
- for numb, fil in enumerate(fouricons[win.current[shotis+"_active_folder"]]):
-
- if str(numb+1) in data:
- layer.line_to(
- x+5+(width-10)/numofis*(numb+0.5),
- (y+win.scroll["script_shots"]+current_Y_shots+100)-(100/largest*data[str(numb+1)])
- )
- layer.stroke()
-
- # Funny that it didn't really stuck too much like this. Please
- # let me know if on your machine this way of doing it is hell
- # a slow.
-
- for numb, fil in enumerate(fouricons[win.current[shotis+"_active_folder"]]):
-
-
- # Here I'm going to put some logic. That will enable me to
- # scroll trough the images. In a way that allows me to
- # preview the animation. Simple button wouldn't work since
- # it's waiting for the user to release the button to be
- # activated. This one will be activated by just dragging
- # across.
-
- # Also my roundrect buttons are not ideal when you have little
- # space and 10000 frames.
-
- fill = False
-
- if int(win.current["mx"]) in range(int(x+5+(width-10)/numofis*numb),int(x+5+(width-10)/numofis*numb+(width-10)/numofis))\
- and int(win.current["my"]) in range(int(y+win.scroll["script_shots"]+current_Y_shots), int(y+win.scroll["script_shots"]+current_Y_shots+100)):
-
- # Before we are doing the logic. I want to give user a
- # tooltip about render analytics. So let's do this.
-
- tip = ""
- for n, blend in enumerate(alldata):
- data = alldata[blend]
- if str(numb+1) in data:
- tip = tip + blend+" "+UI_math.timestring(data[str(numb+1)]/1000000)+"\n"
- if tip:
- tip = tip[:-1] # Removing the last \n
- UI_elements.tooltip(win, tip)
-
- # Now let's do the fill and other stuff
-
- fill = True
-
- if win.current["LMB"]:
-
- win.current[shotis+"_active_folder_item"] = numb
-
- if fill or win.current[shotis+"_active_folder_item"] == numb:
-
- UI_color.set(layer, win, "progress_time")
- layer.rectangle(
- x+5+(width-10)/numofis*numb,
- y+win.scroll["script_shots"]+current_Y_shots,
- (width-10)/numofis,
- 100)
- layer.fill()
-
-
- current_Y_shots = current_Y_shots + 110
-
- # Okay let's put blend file from the shot. So you could actually
- # do work on it.
-
- # But first. I want to add a seach promt. So I could add new ones
- # the same way I do it in any other window. By searching. I think
- # it's important to keep the workflow similar.
-
- # I think that if we have no blend files at all. It might give you
- # to make a new one with the name of the shot. And all the rest will
- # be done by searching. Yeah. Makes sense. Wait. I can put the name of
- # the shot in the search. Hm... Okay. Let's make the seach icon first.
-
- UI_elements.image(layer, win,
- "settings/themes/"+win.settings["Theme"]+"/icons/search.png",
- x+10,
- y+win.scroll["script_shots"]+current_Y_shots,
- 40,
- 40)
-
- # Now beside it will be out text entry.
-
- UI_elements.text(layer, win, "shot_search",
- x+50,
- y+win.scroll["script_shots"]+current_Y_shots,
- width-55,
- 40)
-
- current_Y_shots = current_Y_shots + 50
-
- # Now let's get the blend file list. It's going to take a few
- # stept. First we are going to try getting all the files in the
- # folder. Then filter them by .blend in the end. We do not want
- # to show you the .blend1 files. We don't want to show you
- # anything.
-
- blendfiles = []
-
- try:
- for blend in os.listdir(win.project+"/rnd"+win.cur):
- if blend.endswith(".blend") and "_backup" not in blend:
- blendfiles.append(blend)
- except:
- pass
-
- # Now since we've got our blendfiles list. We can now draw them.
- # But I want to preserve the countinuity with the rest of the
- # software. So I will need to draw a little Blendfile node each
- # time. For which I'm going to create a node. But this time it's
- # going to have 2 icons at the bottom.
-
- ############## ############## ##############
- # 01.blend # # 02.blend # # 03.blend #
- ############## ############## ##############
- # ____ # # ____ # # ____ #
- # ( 0 0 ) # # ( 0 0 ) # # ( 0 0 ) #
- # ) ( # # ) ( # # ) ( #
- # \__/ # # \__/ # # \__/ #
- # # # # # #
- ############## ############## ##############
- # 0 # 0 # # 0 # 0 # # 0 # 0 #
- ############## ############## ##############
-
- # Those 2 icons in the bottom of each will be buttons for render
- # and linking. The linking is what you do to put assets inside
- # animation files. A new dialog should be developped for this.
-
- # The rendering will resemble rendering of Blender-Organizer with
- # render times analytics and stuff. But will be way more extended.
- # For example with an ability to open a render task on another
- # computer. So groups of people could work together.
-
- tileX = 5
-
- searchis = win.text["shot_search"]["text"].replace("/","_").replace(" ", "_")\
- .replace('"',"_").replace("(","_").replace(")","_").replace("'","_")\
- .replace("[","_").replace("]","_").replace("{","_").replace("}","_")
-
- for bn, blend in enumerate(blendfiles):
-
- # Each one will be drawn in it's own little layer. Because
- # I want the top bar to have a nice rounded corner and also
- # the image to be cut.
-
- # Each one here will 128 pixels wide. ( Because this is the
- # resolution of blender-thumbnailer.py thumbnails. And I
- # want to save horizontal resolution as much as possible
-
- # But before I render a Blend. I want to exclude it if it's
- # not in a search.
-
- if searchis and searchis.lower() not in blend.lower():
- continue
-
- # Making the layer
- nodesurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 128, 198)
- node = cairo.Context(nodesurface)
- node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
-
- UI_elements.roundrect(node, win,
- 0,
- 0,
- 128,
- 198,
- 10,
- fill=False)
-
- node.clip()
-
- # Background
- UI_color.set(node, win, "dark_overdrop")
- node.rectangle(0,0,128, 198)
- node.fill()
-
- # Blender icon
-
- UI_elements.image(node, win,
- win.project+"/rnd"+win.cur+"/"+blend,
- 0,
- 20,
- 128,
- 128, cell="shot_blends")
-
- # Banner
- UI_color.set(node, win, "node_blendfile")
- node.rectangle(0,0,128, 20)
- node.fill()
-
- # Filename
- UI_color.set(node, win, "text_normal")
- node.set_font_size(12)
- node.move_to(5, 15)
- node.show_text(blend)
-
- # Outputting the layer
- layer.set_source_surface(nodesurface,
- x+tileX,
- y+win.scroll["script_shots"]+current_Y_shots)
- layer.paint()
-
- # Here we gonna out 3 buttons:
-
- # 1. Launch the Blend-File
- # 2. Link into Blend-File
- # 3. Render Blend-File
-
- # Launch the Blend file:
- def do():
- oscalls.file_open(win, win.project+"/rnd"+win.cur+"/"+blend)
-
- UI_elements.roundrect(layer, win,
- x+tileX,
- y+win.scroll["script_shots"]+current_Y_shots,
- 128,
- 148,
- 10,
- button=do,
- fill=False,
- tip=blend)
- layer.stroke()
-
- # Link things into Blend-File
- def do():
-
- # I'm using a dialog here. Because I want to return back
- # to the shot we were in. But I don't really want to do
- # anything after the dialog is closed. So there is this
- # empty function.
-
- def after(win, var):
- pass
-
- studio_dialogs.asset_link(win, "asset_linking", after, "/rnd"+win.cur+"/"+blend)
-
- UI_elements.roundrect(layer, win,
- x+tileX+20,
- y+win.scroll["script_shots"]+current_Y_shots+152,
- 40,
- 40,
- 10,
- icon="obj_link",
- button=do,
- tip=talk.text("link_shot_blend_tooltip")+blend)
-
- # Render
- def do():
- def after(win, var):
- pass
-
- studio_dialogs.render(win, "render_setup", after, "/rnd"+win.cur+"/"+blend)
-
- UI_elements.roundrect(layer, win,
- x+tileX+65,
- y+win.scroll["script_shots"]+current_Y_shots+152,
- 40,
- 40,
- 10,
- icon="render",
- button=do,
- tip=talk.text("render_shot_blend_tooltip")+blend)
-
- tileX = tileX + 150
- if tileX + 128 > width - 10 and bn != len(blendfiles)-1:
- tileX = 5
- current_Y_shots = current_Y_shots + 205
-
-
- # Now before we are finished. We want to able to add new files
- # by typing the names in the search.
-
- if not blendfiles and not searchis:
- searchis = shotis
-
- if not searchis.endswith(".blend"):
- searchis = searchis + ".blend"
-
- if searchis != ".blend" and searchis not in blendfiles:
-
- # There will be 2 buttons. To add a brand new file and to
- # copy one from a different shot. In Blender-Oraniger it
- # had a copy-paste kind of system for this. But since we
- # have a file selector. I'm going to use it instead. Tho
- # tell me if a copy-paste for files is a cool idea.
-
- if tileX + 128 > width - 10:
- tileX = 5
- current_Y_shots = current_Y_shots + 205
-
- # ADD NEW BLEND
-
- def do():
-
- # First let's make sure that the folder exists. Because
- # it might not exists. I think doing it automatically
- # makes sense.
-
- try:
- os.makedirs(win.project+"/rnd"+win.cur)
- except:
- pass
-
- # Then we copy the file.
-
- oscalls.copy_file(
- win,
- os.getcwd()+"/new_file/rnd.blend",
- "/rnd"+win.cur+"/",
- searchis)
-
- # And clear the search
-
- win.text["shot_search"]["text"] = ""
- win.images = {}
-
- UI_elements.roundrect(layer, win,
- x+tileX,
- y+win.scroll["script_shots"]+current_Y_shots,
- 128,
- 198,
- 10,
- button=do)
-
- # A little surrounding thing.
-
- UI_color.set(layer, win, "progress_background")
- UI_elements.roundrect(layer, win,
- x+tileX,
- y+win.scroll["script_shots"]+current_Y_shots,
- 128,
- 198,
- 10,
- fill=False)
- layer.stroke()
-
- # Icon
-
- UI_elements.image(layer, win,
- "settings/themes/"+win.settings["Theme"]+"/icons/new_file.png",
- x+tileX+44,
- y+win.scroll["script_shots"]+current_Y_shots + 70,
- 40, 40)
-
- # preiew
-
- UI_color.set(layer, win, "text_normal")
- layer.set_font_size(12)
- layer.move_to(x+tileX+64-len(searchis)*4,
- y+win.scroll["script_shots"]+current_Y_shots+150)
- layer.show_text(searchis)
-
- tileX = tileX + 150
- if tileX + 128 > width - 10:
- tileX = 5
- current_Y_shots = current_Y_shots + 205
-
- # And a copy file here too
-
- # COPY BLEND
-
- def do():
-
- # Now the copy function going to be a tiny bit harder
- # since we will need to launch a dialog for you to
- # select the file. I think you gonna look for files
- # from this scene more often. So let's do that.
-
- def after(win, var):
- if var:
- try:
- os.makedirs(win.project+"/rnd"+win.cur)
- except:
- pass
-
- # Then we copy the file.
-
- oscalls.copy_file(
- win,var,
- "/rnd"+win.cur+"/",
- searchis)
-
- # And clear the search
-
- win.text["shot_search"]["text"] = ""
- win.images = {}
- # Running the dialog starter
-
- studio_dialogs.file_select(win, shotis+"_blends", after, force=True,
- IMAGE=False, BLEND=True, VIDEO=False, FILE=False, CHR=False, VEH=False,
- LOC=False, OBJ=False, RND=True, FOLDER=False, SEARCH=scene+" ")
-
- UI_elements.roundrect(layer, win,
- x+tileX,
- y+win.scroll["script_shots"]+current_Y_shots,
- 128,
- 198,
- 10,
- button=do)
-
- # A little surrounding thing.
-
- UI_color.set(layer, win, "progress_background")
- UI_elements.roundrect(layer, win,
- x+tileX,
- y+win.scroll["script_shots"]+current_Y_shots,
- 128,
- 198,
- 10,
- fill=False)
- layer.stroke()
-
- # Icon
-
- UI_elements.image(layer, win,
- "settings/themes/"+win.settings["Theme"]+"/icons/copy_file.png",
- x+tileX+44,
- y+win.scroll["script_shots"]+current_Y_shots + 70,
- 40, 40)
-
- # preiew
-
- UI_color.set(layer, win, "text_normal")
- layer.set_font_size(12)
- layer.move_to(x+tileX+64-len(searchis)*4,
- y+win.scroll["script_shots"]+current_Y_shots+150)
- layer.show_text(searchis)
-
-
-
- current_Y_shots = current_Y_shots + 205
-
- else:
-
- # If the shot is not selected I want to be able to select it
- # even if I can't find it in the text of the script.
-
- def do():
- win.cur = surl
- select_shot(win)
- win.current["scroll_shot_to_in_script"] = True
- win.current["shot_left_side_scroll_please_work_omg_wtf"] = True
-
- UI_elements.roundrect(layer, win,
- x,
- y+win.scroll["script_shots"]+current_Y_shots,
- width,
- 50,
- 10,
- button=do,
- fill=False)
- layer.stroke()
-
- # Then I want to show the user which state is the shot at the
- # moment. By putting one of it's icons in the end of the of the
- # shot choosing button.
- fouricons = [
- "storyboard",
- "opengl",
- "test_rnd",
- "rendered"
- ]
-
- for icon in reversed(fouricons):
- try:
- files = sorted(os.listdir(win.project+"/rnd"+surl+"/"+icon))
- except:
- files = []
- if files:
- UI_elements.image(layer, win,
- "settings/themes/"+win.settings["Theme"]+"/icons/"+icon+".png",
- width-50, y+win.scroll["script_shots"] + current_Y_shots+5, 40, 40)
- break
-
- current_Y_shots = current_Y_shots + 60
- # Button for [ That's All The Shots ].
- # The idea is that untill this button is pressed the program will try
- # to estimate how many shots there are still in the text, by looking at
- # the amount of the text. If this button is pressed. The estimation will
- # be ignored.
- if "no_more_shots" not in win.story["scenes"][scene]:
- win.story["scenes"][scene]["no_more_shots"] = False
- icon = "checked"
- if not win.story["scenes"][scene]["no_more_shots"]:
- icon = "unchecked"
-
- def do():
- win.story["scenes"][scene]["no_more_shots"] = not win.story["scenes"][scene]["no_more_shots"]
- story.save(win.project, win.story)
- win.story = story.load(win.project)
-
- UI_elements.roundrect(layer, win,
- x,
- y+win.scroll["script_shots"]+current_Y_shots,
- width,
- 40,
- 10,
- button=do,
- icon=icon)
-
- UI_color.set(layer, win, "text_normal")
- layer.set_font_size(20)
- layer.move_to(x+50,
- y+win.scroll["script_shots"]+current_Y_shots+27 )
- layer.show_text("No More Shots")
- current_Y_shots = current_Y_shots + 60
-
- # Scroll
- UI_elements.scroll_area(layer, win, "script_shots",
- x+0,
- y+0,
- width,
- height,
- current_Y_shots,
- bar=True,
- mmb=True)
-
-
-
- return surface
|