Blender 2.8 Windows 10 x64
I have a start and stop button operator on my panel. The start button executes the modal as expected but I don't know how to get the stop button to exit the model via return('CANCELED')
Below is my code if you need it for testing
bl_info = {
"name": "Brush strength mousewheel",
"blender": (2, 80, 0),
"category": "Brush",
}
import bpy
from bpy.props import EnumProperty
from bpy.types import Operator, Panel, PropertyGroup
# ------------------------------------------------------------------------
# Scene Properties
# ------------------------------------------------------------------------
class MY_Properties(PropertyGroup):
float_slider: bpy.props.FloatProperty(
name = "Float Value",
description = "A float property",
default = 1.0,
min = 0.010,
max = 10.0
)
class SCULPT_PT_CustomPanel(Panel):
bl_label = "My Panel"
bl_idname = "SCULPT_PT_custom_panel"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Tool"
bl_context = "sculpt_mode"
def draw(self, context):
layout = self.layout
scene = context.scene
mytool = scene.my_tool
layout.operator('my.brush_stregth_op', text='Start').action = 'Start'
layout.operator('my.brush_stregth_op', text='Stop').action = 'Stop'
layout.prop(mytool, "float_slider")
class MY_OT_brush_stregth_op(Operator):
bl_idname = 'my.brush_stregth_op'
bl_label = 'Test'
bl_description = 'Test'
bl_options = {'REGISTER', 'UNDO'}
# _timer = None
# Determines which button was clicke by .action attachd to operator from panel
# action: EnumProperty(
# items=[
# ('Start', 'start', 'start'),
# ('Stop', 'stop', 'stop')
# ]
# )
# if self.action == "Start"
# do something
def modal(self, context, event):
scene = context.scene
if event.type == 'WHEELDOWNMOUSE':
scene.my_tool.float_slider = scene.my_tool.float_slider - .1
self.report({'INFO'}, "The value of the slider: " + str(scene.my_tool.float_slider))
elif event.type == 'WHEELUPMOUSE':
self.report({'INFO'}, "The value of the slider: " + str(scene.my_tool.float_slider))
scene.my_tool.float_slider = scene.my_tool.float_slider + .1
elif event.type in {'ESC', 'RIGHTMOUSE'}: # Cancel
self.report({'INFO'}, "The value of the: " + str(self.action))
return {'CANCELLED'}
elif event.type == 'TIMER':
self.report({'INFO'}, "The value of the: " + str(self.action))
if self.action == 'Stop':
return {'CANCELLED'}
else:
bpy.context.tool_settings.sculpt.brush.strength = scene.my_tool.float_slider
return {'PASS_THROUGH'}
bpy.context.tool_settings.sculpt.brush.strength = scene.my_tool.float_slider
return {'RUNNING_MODAL'}
def invoke(self, context, event):
wm = context.window_manager
# self._timer = wm.event_timer_add(0.1, window=context.window)
# wm.modal_handler_add(self)
return {'RUNNING_MODAL'}
classes = (
MY_Properties,
SCULPT_PT_CustomPanel,
MY_OT_brush_stregth_op
)
def register():
from bpy.utils import register_class
for cls in classes:
register_class(cls)
bpy.types.Scene.my_tool = bpy.props.PointerProperty(type=MY_Properties)
# handle the keymap
# wm = bpy.context.window_manager
#
# # handle the keymap
# wm = bpy.context.window_manager
# km = wm.keyconfigs.addon.keymaps.new(name='Sculpt Mode', space_type='EMPTY')
# kmi = km.keymap_items.new(ModalOperator.bl_idname, 'T', 'PRESS', ctrl=True, shift=True)
# addon_keymaps.append((km, kmi))
def unregister():
# Note: when unregistering, it's usually good practice to do it in reverse order you registered.
# Can avoid strange issues like keymap still referring to operators already unregistered...
# # handle the keymap
# for km, kmi in addon_keymaps:
# km.keymap_items.remove(kmi)
# addon_keymaps.clear()
from bpy.utils import unregister_class
for cls in reversed(classes):
unregister_class(cls)
del bpy.types.Scene.my_tool
if __name__ == "__main__":
register()