import nuke
nuke.menu("Nodes").addCommand('User/Utility/JS_Backdrop/JS_Backdrop', "create_JS_Backdrop()" , 'alt+b')
nuke.menu("Nodes").addCommand('User/Utility/JS_Backdrop/set random nuke colors', "JS_Backdrop_randomColors()")
menubar = nuke.menu('Nuke')
menubar.addCommand("@;scale backdrop right", "JS_Backdrop_Scale('Right')", 'alt+Right')
menubar.addCommand("@;scale backdrop down", "JS_Backdrop_Scale('Down')", 'alt+Down')
menubar.addCommand("@;scale backdrop left", "JS_Backdrop_Scale('Left')", 'alt+Left')
menubar.addCommand("@;scale backdrop up", "JS_Backdrop_Scale('Up')", 'alt+Up')
def JS_Backdrop_Scale(dir):
undo = nuke.Undo()
undo.disable()
grow = round(50/(nuke.zoom()*4))
for node in nuke.selectedNodes():
if node.Class() == 'BackdropNode':
node.setSelected(False)
width = node['bdwidth']
height = node['bdheight']
x = node['xpos']
y = node['ypos']
try:
bdNodes = JS_Backdrop_getNodes()
if dir == 'Left' or dir == 'Right':
Xmin = min([n.xpos() for n in bdNodes])
Xmax = max([n.xpos() + n.screenWidth() for n in bdNodes])
Xanchor = float( (Xmin + Xmax)/2 - node.xpos() ) / float(node.screenWidth())
else:
Ymin = min([n.ypos() for n in bdNodes])
Ymax = max([n.ypos() + n.screenHeight() for n in bdNodes])
Yanchor = float( (Ymin + Ymax)/2 - node.ypos() ) / float(node.screenHeight())
except:
Xanchor = .5
Yanchor = .5
if dir == 'Left':
width.setValue( width.value() - grow )
x.setValue( x.value() + grow*Xanchor )
elif dir == 'Down':
height.setValue( height.value() - grow )
y.setValue( y.value() + grow*Yanchor )
elif dir == 'Right':
width.setValue( width.value() + grow )
x.setValue( x.value() - grow*Xanchor )
elif dir == 'Up':
height.setValue( height.value() + grow )
y.setValue( y.value() - grow*Yanchor )
node.setSelected(True)
undo.enable()
def JS_Backdrop_getNodes():
origSel = nuke.selectedNodes()
node.selectNodes()
bdNodes = nuke.selectedNodes()
[n.setSelected( False ) for n in bdNodes]
[n.setSelected( True ) for n in origSel]
return bdNodes
def create_JS_Backdrop():
#create backdrop
if len(nuke.selectedNodes()) == 0:
node = nuke.createNode('BackdropNode', inpanel = False)
else:
node = nukescripts.autoBackdrop()
###build UI###
node.addKnob(nuke.Tab_Knob('JS_Backdrop'))
#color knobs
node.addKnob( nuke.Enumeration_Knob('color','color', ['custom', 'grey', 'red', 'green', 'blue', 'nuke lime', 'nuke purple', 'nuke pink', 'nuke teal', 'nuke yellow']) )
cc = nuke.nuke.Color_Knob('customColor','custom color')
cc.clearFlag(nuke.STARTLINE)
if node['z_order'].value() == -3:
zValue = 0.15
else:
zValue = min(max(.5 + node['z_order'].value()/10, 0.05), 1)
cc.setValue(zValue)
node.addKnob( cc )
node.addKnob( nuke.nuke.Text_Knob('divider','') )
#icon knob
icons = ['None', 'Blur', 'Camera', 'Card', 'CheckerBoard', 'ColorAdd', 'ColorGamma', 'ColorMult', 'Cube', 'Defocus', 'denoise', 'Exposure', 'Flare', 'FloodFill', 'Glint', 'Glow', 'Grade','Grain', 'Keyer', 'LensDistort', 'Merge', 'Modify', 'Noise', 'Paint', 'Read', 'Render', 'Roto', 'Tracker', 'Write', 'ZBlur']
node.addKnob( nuke.Enumeration_Knob('iconKnob','icon', icons) )
nodeName = node.name()
labelLink = nuke.Link_Knob( 'labelLink', 'label' )
labelLink.makeLink(nodeName, 'label')
node.addKnob( labelLink )
note_fontLink = nuke.Link_Knob( 'note_fontLink', 'font' )
note_fontLink.makeLink(nodeName, 'note_font')
node.addKnob( note_fontLink )
node['note_font_size'].setFlag(0x0000000010000000) # read only flag
note_font_sizeKnob = nuke.Double_Knob( 'note_font_sizeKnob', '' )
note_font_sizeKnob.clearFlag(0x00000002) #remove slider
note_font_sizeKnob.setFlag(0x00000100) #no_animation
note_font_sizeKnob.setRange(0,10)
note_font_sizeKnob.clearFlag(nuke.STARTLINE)
node.addKnob( note_font_sizeKnob )
note_font_colorLink = nuke.Link_Knob( 'note_font_colorLink', 'color' )
note_font_colorLink.makeLink(nodeName, 'note_font_color')
note_font_colorLink.clearFlag(nuke.STARTLINE)
node.addKnob( note_font_colorLink )
#font knobs
fs = nuke.Double_Knob('fontSize','dynamic font size')
fs.setValue(.5)
node.addKnob(fs)
dynamic = nuke.nuke.Boolean_Knob('dynamic', 'enable')
dynamic.clearFlag(nuke.STARTLINE)
dynamic.setValue(True)
node.addKnob( dynamic )
node.addKnob( nuke.nuke.Text_Knob('zorder_divider','') )
#z order buttons
node.addKnob( nuke.PyScript_Knob('up', 'move up', "knob=nuke.thisNode()['z_order'];knob.setValue(knob.value()+1)") )
down = nuke.PyScript_Knob('down', 'move down', "knob=nuke.thisNode()['z_order'];knob.setValue(knob.value()-1)")
down.clearFlag(nuke.STARTLINE)
node.addKnob( down )
front = nuke.PyScript_Knob('front', 'move to front', "node = nuke.thisNode()\nz = node['z_order'].value()\n\nbackdropNodes = [i for i in nuke.allNodes() if i.Class() == 'BackdropNode' and i != node]\n\nax = node.xpos()\nay = node.ypos()\naw = ax + node['bdwidth'].value()\nah = ay + node['bdheight'].value()\n\nfor bdNode in backdropNodes:\n bx = bdNode.xpos()\n by = bdNode.ypos()\n bw = bx + bdNode['bdwidth'].value()\n bh = by + bdNode['bdheight'].value()\n\n intersect = ax > bw and aw > bx and ay > bh and ah > by \n\n if intersect and bdNode['z_order'].value() > z:\n z = bdNode['z_order'].value()\n\nnode['z_order'].setValue(z + 1)")
front.clearFlag(nuke.STARTLINE)
node.addKnob( front )
back = nuke.PyScript_Knob('back', 'move to back', "node = nuke.thisNode()\nz = node['z_order'].value()\n\nbackdropNodes = [i for i in nuke.allNodes() if i.Class() == 'BackdropNode' and i != node]\n\nax = node.xpos()\nay = node.ypos()\naw = ax + node['bdwidth'].value()\nah = ay + node['bdheight'].value()\n\nfor bdNode in backdropNodes:\n bx = bdNode.xpos()\n by = bdNode.ypos()\n bw = bx + bdNode['bdwidth'].value()\n bh = by + bdNode['bdheight'].value()\n\n intersect = ax > bw and aw > bx and ay > bh and ah > by \n\n if intersect and bdNode['z_order'].value() > z:\n z = bdNode['z_order'].value()\n\nnode['z_order'].setValue(z - 1)")
back.clearFlag(nuke.STARTLINE)
node.addKnob( back )
#get KnobChanged python script
try:
from Scripts import JS_Backdrop
except:
import JS_Backdrop
import inspect
lines = inspect.getsource(JS_Backdrop.JS_Backdrop_knobChanged)
lineList = [line[4:].replace(' ', '\t') + '\n' for line in lines.split('\n') if line[:4] == ' ']
KCcode = (''.join(lineList))
#get OnCreate python script
lines = inspect.getsource(JS_Backdrop.JS_Backdrop_onCreate)
lineList = [line[4:].replace(' ', '\t') + '\n' for line in lines.split('\n') if line[:4] == ' ']
OCcode = (''.join(lineList))
#add code to python knobs
node['knobChanged'].setValue(KCcode)
node['onCreate'].setValue(OCcode)
node['autolabel'].setValue("'@' + nuke.thisNode()['iconKnob'].value() + ' ' + nuke.thisNode()['label'].value() if nuke.thisNode()['iconKnob'].value() != 'None' else nuke.thisNode()['label'].value()")
JS_Backdrop_knobChanged(node)
def JS_Backdrop_randomColors():
import random
selnodes = nuke.selectedNodes()
if len(selnodes) == 0:
nodes = nuke.allNodes()
else:
nodes = selnodes
foo=[1, 5, 6, 7, 8, 9]
for node in nodes:
if node.Class() == 'BackdropNode' and node.knob('JS_Backdrop') is not None:
node['color'].setValue(random.choice(foo))
def JS_Backdrop_knobChanged(node, initial = True):
from math import sqrt
undo = nuke.Undo()
undo.disable()
try:
initial
thisKnob = ''
except:
initial = False
if not initial:
node = nuke.thisNode()
thisKnob = nuke.thisKnob()
try:
if thisKnob in [node['fontSize'], node['dynamic'], node['bdwidth'], node['bdheight'], node['note_font_sizeKnob']] or initial:
#dynamic font size
if node['dynamic'].value() == True:
x = node['bdwidth'].value()
y = node['bdheight'].value()
c = sqrt(pow(x,2) + pow(y,2))
val = 6+(c/10)*node['fontSize'].value()
node['note_font_size'].setValue( int(val) )
node['note_font_sizeKnob'].setValue( int(val) )
else:
node['note_font_size'].setValue( node['note_font_sizeKnob'].value() )
if thisKnob == node['dynamic'] or initial:
if node['dynamic'].value() == True:
node['note_font_sizeKnob'].setFlag(0x0000000010000000) #read only
else:
node['note_font_sizeKnob'].clearFlag(0x0000000010000000) #read only
if thisKnob in [node['color'], node['customColor']] or initial:
#tile color
colorDropdown = node['color'].value()
if colorDropdown == 'custom':
customColor = node['customColor'].value()
if type(customColor) == type([]):
customColor = [max(min(i*255, 255),0) for i in customColor]
cc = int('%02x%02x%02x%02x' % (int(customColor[0]),int(customColor[1]),int(customColor[2]),1),16)
else:
customColor = max(min(customColor*255, 255),0)
cc = int('%02x%02x%02x%02x' % (int(customColor),int(customColor),int(customColor),1),16)
if cc == 1:
cc = 255
node['tile_color'].setValue(cc)
elif colorDropdown == 'grey':
node['tile_color'].setValue(2290649088)
elif colorDropdown == 'red':
node['tile_color'].setValue(2131956481)
elif colorDropdown == 'green':
node['tile_color'].setValue(4987137)
elif colorDropdown == 'blue':
node['tile_color'].setValue(2522881)
elif colorDropdown == 'nuke lime':
node['tile_color'].setValue(1908830464)
elif colorDropdown == 'nuke purple':
node['tile_color'].setValue(1903281664)
elif colorDropdown == 'nuke pink':
node['tile_color'].setValue(2386071040)
elif colorDropdown == 'nuke teal':
node['tile_color'].setValue(948866560)
elif colorDropdown == 'nuke yellow':
node['tile_color'].setValue(2391685120)
elif thisKnob == node['name']:
#reset link knobs in case of missing knob errors
lk = [knob for knob in ['labelLink', 'note_fontLink', 'note_font_colorLink'] if node[knob].Class() == 'Link_Knob']
if len(lk) > 0:
for knob in lk:
node[knob].makeLink(node.name(), knob[:-4])
#hacky way to force the UI to update
wk = node['bdwidth']
wkv = wk.value()
wk.setValue(wkv+1)
wk.setValue(wkv)
except:
pass
undo.enable()
def JS_Backdrop_onCreate():
try:
node = nuke.thisNode()
if node.knob('JS_Backdrop') is not None:
node['note_font_size'].setFlag(0x0000000010000000) #read only
node['note_font_sizeKnob'].clearFlag(0x00000002) #remove slider
node['note_font_sizeKnob'].setFlag(0x00000100) #no_animation
if node['dynamic'].value() == True:
node['note_font_sizeKnob'].setFlag(0x0000000010000000) #read only
except:
pass