diff --git a/area.py b/area.py index 3ada21c..9add478 100644 --- a/area.py +++ b/area.py @@ -155,6 +155,7 @@ classes = ( def register(): + # Remove the tools inside the picker space bpy.types.WM_OT_tool_set_by_id._execute = bpy.types.WM_OT_tool_set_by_id.execute #tool_set_by_id bpy.types.WM_OT_tool_set_by_id.execute = tool_set_by_id diff --git a/gizmo.py b/gizmo.py index f0a16b2..36f3430 100644 --- a/gizmo.py +++ b/gizmo.py @@ -3,10 +3,13 @@ import bpy from bpy.props import (IntProperty, EnumProperty, BoolProperty) from bpy.types import (AddonPreferences, GizmoGroup, Operator, Gizmo) - +import gpu from mathutils import Vector, Matrix, Euler -from .constants import PICKERS +from gpu_extras.batch import batch_for_shader + +from .constants import PICKERS, SHADERS from .core.picker import Picker +from .core.geometry_utils import bounding_rect @@ -38,14 +41,133 @@ class RP_OT_simple_operator(bpy.types.Operator): print('Select Shape') return {'FINISHED'} ''' +''' +class RP_OT_box_select(Operator): + """Box Select bones in the picker view""" + bl_idname = "node.rp_box_select" + bl_label = "Picker Box Select" + mode: EnumProperty(items=[(i, i.title(), '') for i in ('SET', 'EXTEND', 'SUBSTRACT')]) + @classmethod + def poll(cls, context): + if not is_picker_space(context.space_data): + return + + ob = context.object + return ob and ob in PICKERS + + def draw_callback(self): + #print('draw callback border') + if not self.draw_border: + return + + gpu.state.blend_set('ALPHA') + + #print('DRAW BORDER') + + self.color_shader.bind() + self.color_shader.uniform_float("color", self.bg_color) + self.bg_batch.draw(self.color_shader) + + self.dash_shader.bind() + matrix = gpu.matrix.get_projection_matrix() + + self.dash_shader.uniform_float("color", self.border_color) + self.dash_shader.uniform_float("viewMatrix", matrix) + self.dash_shader.uniform_float("dashSize", 5) + self.dash_shader.uniform_float("gapSize", 4) + + self.contour_batch.draw(self.dash_shader) + + gpu.state.blend_set('NONE') + + def invoke(self, context, event): + #print(f'invoke: type={event.type}, value={event.value}, ctrl={event.ctrl}, shift={event.shift}, alt={event.alt}') + + if context.object.mode != 'POSE': + bpy.ops.object.posemode_toggle() + + self.timer = None + #self.mode = self.mode_from_event(event) + #self.invoke_event = event.copy() + self.region = context.region + self.draw_border = False + + self.picker = PICKERS[context.object] + + self.start_mouse = event.mouse_region_x, event.mouse_region_y + #self.shader = line_strip_shader + self.border_color = [1, 1, 1, 1] + self.bg_color = [1, 1, 1, 0.05] + + #args = (self, context) + self.color_shader = gpu.shader.from_builtin('UNIFORM_COLOR') + self.dash_shader = SHADERS['dashed_line'] + self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(self.draw_callback, (), 'WINDOW', 'POST_PIXEL') + + context.window_manager.modal_handler_add(self) + + self.picker.press_event(self.mode) + self.region.tag_redraw() + + return {'RUNNING_MODAL'} + + def modal(self, context, event): + + self.mouse = event.mouse_region_x, event.mouse_region_y + + self.border = bounding_rect((self.start_mouse, self.mouse)) + + self.bg_batch = batch_for_shader(self.color_shader, 'TRI_FAN', {"pos": self.border}) + self.contour_batch = batch_for_shader(self.dash_shader, 'LINE_LOOP', {"pos": self.border}) + + self.draw_border = True + + self.region.tag_redraw() + + if event.value == 'RELEASE': + return self.release_event(context) + + return {'RUNNING_MODAL'} + + def release_event(self, context): + scn = context.scene + + if scn.rig_picker.use_pick_bone: + self.picker.assign_bone_event() + + elif (self.start_mouse[0] != self.mouse[0] or self.start_mouse[1] != self.mouse[1]): + self.picker.border_select(self.border, self.mode) + else: + self.picker.move_event(self.mouse) + self.picker.release_event(self.mode) + + bpy.ops.ed.undo_push(message="Box Select") + + return self.exit(context) + + def exit(self, context): + bpy.types.SpaceNodeEditor.draw_handler_remove(self._handle, 'WINDOW') + context.region.tag_redraw() + return {'FINISHED'} +''' class RP_GT_gizmo(Gizmo): + + + def mode_from_event(self, event): + if event.alt: + return 'SUBSTRACT' + elif event.ctrl or event.shift: + return 'EXTEND' + else: + return 'SET' + def test_select(self, context, location): ob = context.object @@ -54,39 +176,109 @@ class RP_GT_gizmo(Gizmo): return -1 picker.move_event(location) - - #if bpy.app.timers.is_registered(tooltip): - # bpy.app.timers.unregister(tooltip) - #context.region.tag_redraw() - - #picker.tooltip_event(event='START') - #bpy.app.timers.register(partial(tooltip, context.region), first_interval=1) - - #print(location) - - - context.region.tag_redraw() - return -1 + return 1 def draw(self, context): - return - ''' + + print('DRAW_SELECT', self.border) + + if not self.draw_border: + return + + gpu.state.blend_set('ALPHA') + gpu.state.depth_test_set('ALWAYS') + gpu.state.depth_mask_set(False) + + + #print('DRAW BORDER') + + self.color_shader.bind() + self.color_shader.uniform_float("color", self.bg_color) + self.bg_batch.draw(self.color_shader) + + self.dash_shader.bind() + matrix = gpu.matrix.get_projection_matrix() + + self.dash_shader.uniform_float("color", self.border_color) + self.dash_shader.uniform_float("viewMatrix", matrix) + self.dash_shader.uniform_float("dashSize", 5) + self.dash_shader.uniform_float("gapSize", 4) + + self.contour_batch.draw(self.dash_shader) + + #gpu.state.depth_mask_set(False) + gpu.state.blend_set('NONE') + def invoke(self, context, event): print(f'invoke: type={event.type}, value={event.value}, ctrl={event.ctrl}, shift={event.shift}, alt={event.alt}') + + print(self) + + if context.object.mode != 'POSE': + bpy.ops.object.posemode_toggle() + + #self.timer = None + #self.mode = self.mode_from_event(event) + #self.invoke_event = event.copy() + #self.region = context.region + self.draw_border = False + + self.picker = PICKERS[context.object] + + self.start_mouse = event.mouse_region_x, event.mouse_region_y + #self.shader = line_strip_shader + self.border_color = [1, 1, 1, 1] + self.bg_color = [1, 1, 1, 0.05] + + #args = (self, context) + self.color_shader = gpu.shader.from_builtin('UNIFORM_COLOR') + self.dash_shader = SHADERS['dashed_line'] + #self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(self.draw_callback, (), 'WINDOW', 'POST_PIXEL') + + self.border = [(0, 0), (0, 0), (0, 0), (0, 0)] + #context.window_manager.modal_handler_add(self) + self.mode = self.mode_from_event(event) + self.picker.press_event(self.mode) + context.region.tag_redraw() + return {'RUNNING_MODAL'} def modal(self, context, event, tweak): - print(f'invoke: type={event.type}, value={event.value}, ctrl={event.ctrl}, shift={event.shift}, alt={event.alt}') - + #print(f'invoke: type={event.type}, value={event.value}, ctrl={event.ctrl}, shift={event.shift}, alt={event.alt}') + + self.mouse = event.mouse_region_x, event.mouse_region_y + + self.border = bounding_rect((self.start_mouse, self.mouse)) + + self.bg_batch = batch_for_shader(self.color_shader, 'TRI_FAN', {"pos": self.border}) + self.contour_batch = batch_for_shader(self.dash_shader, 'LINE_LOOP', {"pos": self.border}) + + self.draw_border = True + + context.region.tag_redraw() + #self.draw(context) + return {'RUNNING_MODAL'} def exit(self, context, cancel): - print('EXIT') + scn = context.scene - ''' + if scn.rig_picker.use_pick_bone: + self.picker.assign_bone_event() + + elif (self.start_mouse[0] != self.mouse[0] or self.start_mouse[1] != self.mouse[1]): + self.picker.border_select(self.border, self.mode) + else: + self.picker.move_event(self.mouse) + self.picker.release_event(self.mode) + + bpy.ops.ed.undo_push(message="Box Select") + self.draw_border = False + context.region.tag_redraw() + @@ -104,6 +296,9 @@ class RP_GT_gizmogroup(GizmoGroup): def setup(self, context): self.gizmo = self.gizmos.new("RP_GT_gizmo") + self.gizmo.draw_border = False + self.gizmo.border = [] + self.gizmo.use_draw_modal = True diff --git a/operators/picker.py b/operators/picker.py index ae884ae..ffc7d22 100644 --- a/operators/picker.py +++ b/operators/picker.py @@ -755,7 +755,7 @@ def register_keymaps(): kmi = km.keymap_items.new("node.context_menu_picker", type="RIGHTMOUSE", value="PRESS") keymaps.append((km, kmi)) - + ''' kmi = km.keymap_items.new("node.rp_box_select", type="LEFTMOUSE", value="PRESS") kmi.properties.mode = 'SET' keymaps.append((km, kmi)) @@ -764,11 +764,10 @@ def register_keymaps(): kmi.properties.mode = 'EXTEND' keymaps.append((km, kmi)) - #kmi = km.keymap_items.new("node.rp_box_select", type="LEFTMOUSE", value="PRESS", ctrl=True) kmi = km.keymap_items.new("node.rp_box_select", type="LEFTMOUSE", value="PRESS", alt=True) kmi.properties.mode = 'SUBSTRACT' keymaps.append((km, kmi)) - + ''' #km = wm.keyconfigs.addon.keymaps.new(name="View2D") #kmi = km.keymap_items.new("rigpicker.call_operator", type="MIDDLEMOUSE", value="PRESS") #kmi.properties.operator = "bpy.ops.view2d.pan('INVOKE_DEFAULT')"