WIP: Compositor Viewer shortcuts prototype #105268
@ -20,6 +20,7 @@ from mathutils import Vector
|
||||
from os import path
|
||||
from glob import glob
|
||||
from copy import copy
|
||||
import json
|
||||
from itertools import chain
|
||||
|
||||
from .interface import NWConnectionListInputs, NWConnectionListOutputs
|
||||
@ -486,6 +487,54 @@ class NWAddAttrNode(Operator, NWBase):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class NWFastPreview(Operator):
|
||||
bl_idname = "node.nw_fast_preview"
|
||||
bl_label = "Fast Preview"
|
||||
bl_description = "Preview favorite nodes by pressing 1, 2, 3, 4 and 5"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
# Workaround: simulating a dict with json.loads() and json.dumps()
|
||||
|
||||
node_preview_map : StringProperty(name="")
|
||||
update_map : BoolProperty(default=False)
|
||||
|
||||
viewer_index : IntProperty()
|
||||
|
||||
@classmethod
|
||||
def poll(self, context):
|
||||
return bpy.ops.node.link_viewer.poll()
|
||||
|
||||
def execute(self, context):
|
||||
nodes, _ = get_nodes_links(context)
|
||||
|
||||
if self.node_preview_map != '':
|
||||
temp_dict = json.loads(self.node_preview_map)
|
||||
else:
|
||||
temp_dict = {}
|
||||
|
||||
selected_nodes = context.selected_nodes
|
||||
if self.update_map:
|
||||
if len(selected_nodes) > 0:
|
||||
n1 = selected_nodes[0]
|
||||
|
||||
temp_dict[self.viewer_index] = n1.name
|
||||
self.node_preview_map = json.dumps(temp_dict)
|
||||
bpy.ops.node.link_viewer()
|
||||
Damien Picard
commented
With a slight modification of
With a slight modification of `NWPreviewNode`, you could use this to make it work in shader trees as well:
```python
if context.space_data.tree_type in {'CompositorNodeTree', 'GeometryNodeTree'}:
bpy.ops.node.link_viewer()
elif context.space_data.tree_type == 'ShaderNodeTree':
bpy.ops.node.nw_preview_node()
```
---
```diff
@@ -764,6 +764,8 @@ class NWPreviewNode(Operator, NWBase):
if 'FINISHED' not in select_node: # only run if mouse click is on a node
return {'CANCELLED'}
+ def execute(self, context):
+ space = context.space_data
base_node_tree = space.node_tree
active_tree = context.space_data.edit_tree
path = context.space_data.path
```
|
||||
self.report({'INFO'}, "Set node %s to shortcut %i" % (n1.name, self.viewer_index))
|
||||
else:
|
||||
self.report({'ERROR'}, "No previews to set. Reason: No nodes selected.")
|
||||
|
||||
else:
|
||||
if str(self.viewer_index) in temp_dict:
|
||||
if temp_dict[str(self.viewer_index)] in nodes:
|
||||
n = nodes[temp_dict[str(self.viewer_index)]]
|
||||
n.select = True
|
||||
nodes.active = n
|
||||
bpy.ops.node.link_viewer()
|
||||
n.select = False
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class NWPreviewNode(Operator, NWBase):
|
||||
bl_idname = "node.nw_preview_node"
|
||||
bl_label = "Preview Node"
|
||||
@ -2592,6 +2641,63 @@ class NWAddMultipleImages(Operator, NWBase, ImportHelper):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class NWViewerFocus(bpy.types.Operator):
|
||||
Damien Picard
commented
I think this was added back by mistake? I think this was added back by mistake?
|
||||
"""Set the viewer tile center to the mouse position"""
|
||||
bl_idname = "node.nw_viewer_focus"
|
||||
bl_label = "Viewer Focus"
|
||||
|
||||
x: bpy.props.IntProperty()
|
||||
y: bpy.props.IntProperty()
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (nw_check(cls, context)
|
||||
and nw_check_space_type(cls, context, {'CompositorNodeTree'}))
|
||||
|
||||
def execute(self, context):
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
render = context.scene.render
|
||||
space = context.space_data
|
||||
percent = render.resolution_percentage * 0.01
|
||||
|
||||
nodes, links = get_nodes_links(context)
|
||||
viewers = [n for n in nodes if n.type == 'VIEWER']
|
||||
|
||||
if viewers:
|
||||
mlocx = event.mouse_region_x
|
||||
mlocy = event.mouse_region_y
|
||||
select_node = bpy.ops.node.select(location=(mlocx, mlocy), extend=False)
|
||||
|
||||
if 'FINISHED' not in select_node: # only run if we're not clicking on a node
|
||||
region_x = context.region.width
|
||||
region_y = context.region.height
|
||||
|
||||
region_center_x = context.region.width / 2
|
||||
region_center_y = context.region.height / 2
|
||||
|
||||
bd_x = render.resolution_x * percent * space.backdrop_zoom
|
||||
bd_y = render.resolution_y * percent * space.backdrop_zoom
|
||||
|
||||
backdrop_center_x = (bd_x / 2) - space.backdrop_offset[0]
|
||||
backdrop_center_y = (bd_y / 2) - space.backdrop_offset[1]
|
||||
|
||||
margin_x = region_center_x - backdrop_center_x
|
||||
margin_y = region_center_y - backdrop_center_y
|
||||
|
||||
abs_mouse_x = (mlocx - margin_x) / bd_x
|
||||
abs_mouse_y = (mlocy - margin_y) / bd_y
|
||||
|
||||
for node in viewers:
|
||||
node.center_x = abs_mouse_x
|
||||
node.center_y = abs_mouse_y
|
||||
else:
|
||||
return {'PASS_THROUGH'}
|
||||
|
||||
return self.execute(context)
|
||||
|
||||
|
||||
class NWSaveViewer(bpy.types.Operator, ExportHelper):
|
||||
"""Save the current viewer node to an image file"""
|
||||
bl_idname = "node.nw_save_viewer"
|
||||
@ -2759,6 +2865,7 @@ classes = (
|
||||
NWSwapLinks,
|
||||
NWResetBG,
|
||||
NWAddAttrNode,
|
||||
NWFastPreview,
|
||||
NWPreviewNode,
|
||||
NWFrameSelected,
|
||||
NWReloadImages,
|
||||
@ -2781,6 +2888,7 @@ classes = (
|
||||
NWCallInputsMenu,
|
||||
NWAddSequence,
|
||||
NWAddMultipleImages,
|
||||
NWViewerFocus,
|
||||
NWSaveViewer,
|
||||
NWResetNodes,
|
||||
)
|
||||
|
@ -338,6 +338,35 @@ kmi_defs = (
|
||||
False, (('run_in_geometry_nodes', False),), "Preview node output"),
|
||||
(operators.NWPreviewNode.bl_idname, 'LEFTMOUSE', 'PRESS', False, True,
|
||||
True, (('run_in_geometry_nodes', True),), "Preview node output"),
|
||||
|
||||
|
||||
# Fast Preview
|
||||
(operators.NWFastPreview.bl_idname, 'ONE', 'PRESS', False, False, False,
|
||||
(('viewer_index', 1), ('update_map', False)), "Fast Preview"),
|
||||
(operators.NWFastPreview.bl_idname, 'ONE', 'PRESS', True, False, False,
|
||||
(('viewer_index', 1), ('update_map', True)), "Fast Preview"),
|
||||
|
||||
(operators.NWFastPreview.bl_idname, 'TWO', 'PRESS', False, False, False,
|
||||
(('viewer_index', 2), ('update_map', False)), "Fast Preview"),
|
||||
(operators.NWFastPreview.bl_idname, 'TWO', 'PRESS', True, False, False,
|
||||
(('viewer_index', 2), ('update_map', True)), "Fast Preview"),
|
||||
|
||||
(operators.NWFastPreview.bl_idname, 'THREE', 'PRESS', False, False, False,
|
||||
(('viewer_index', 3), ('update_map', False)), "Fast Preview"),
|
||||
(operators.NWFastPreview.bl_idname, 'THREE', 'PRESS', True, False, False,
|
||||
(('viewer_index', 3), ('update_map', True)), "Fast Preview"),
|
||||
|
||||
(operators.NWFastPreview.bl_idname, 'FOUR', 'PRESS', False, False, False,
|
||||
(('viewer_index', 4), ('update_map', False)), "Fast Preview"),
|
||||
(operators.NWFastPreview.bl_idname, 'FOUR', 'PRESS', True, False, False,
|
||||
(('viewer_index', 4), ('update_map', True)), "Fast Preview"),
|
||||
|
||||
(operators.NWFastPreview.bl_idname, 'FIVE', 'PRESS', False, False, False,
|
||||
(('viewer_index', 5), ('update_map', False)), "Fast Preview"),
|
||||
(operators.NWFastPreview.bl_idname, 'FIVE', 'PRESS', True, False, False,
|
||||
(('viewer_index', 5), ('update_map', True)), "Fast Preview"),
|
||||
|
||||
|
||||
# Reload Images
|
||||
(operators.NWReloadImages.bl_idname, 'R', 'PRESS', False, False, True, None, "Reload images"),
|
||||
# Lazy Mix
|
||||
@ -347,6 +376,8 @@ kmi_defs = (
|
||||
# Lazy Connect with Menu
|
||||
(operators.NWLazyConnect.bl_idname, 'RIGHTMOUSE', 'PRESS', False,
|
||||
True, True, (('with_menu', True),), "Lazy Connect with Socket Menu"),
|
||||
# Viewer Tile Center
|
||||
(operators.NWViewerFocus.bl_idname, 'LEFTMOUSE', 'DOUBLE_CLICK', False, False, False, None, "Set Viewers Tile Center"),
|
||||
# Align Nodes
|
||||
(operators.NWAlignNodes.bl_idname, 'EQUAL', 'PRESS', False, True,
|
||||
False, None, "Align selected nodes neatly in a row/column"),
|
||||
|
Loading…
Reference in New Issue
Block a user
You can store the dict directly here, I don’t think you need to bother serializing to a property.
That didn't seem to work. I think it has to be a property for it to be persistent throughout the lifetime of the operator.