- template with an example of a modal operator drawing with opengl (draw a line on the screen)
- access to event.mouse_region_x/y - basic type checking to callback functions (use PyCapsule names)
This commit is contained in:
parent
67af290bd1
commit
5369bd9c21
69
release/scripts/templates/operator_modal_draw.py
Normal file
69
release/scripts/templates/operator_modal_draw.py
Normal file
@ -0,0 +1,69 @@
|
||||
import BGL
|
||||
|
||||
def draw_callback_px(self, context):
|
||||
print("mouse points", len(self.mouse_path))
|
||||
|
||||
# 50% alpha, 2 pixel width line
|
||||
BGL.glEnable(BGL.GL_BLEND)
|
||||
BGL.glColor4f(0.0, 0.0, 0.0, 0.5)
|
||||
BGL.glLineWidth(2)
|
||||
|
||||
BGL.glBegin(BGL.GL_LINE_STRIP)
|
||||
for x, y in self.mouse_path:
|
||||
BGL.glVertex2i(x, y)
|
||||
|
||||
BGL.glEnd()
|
||||
|
||||
# restore opengl defaults
|
||||
BGL.glLineWidth(1)
|
||||
BGL.glDisable(BGL.GL_BLEND)
|
||||
BGL.glColor4f(0.0, 0.0, 0.0, 1.0)
|
||||
|
||||
|
||||
class ModalDrawOperator(bpy.types.Operator):
|
||||
'''Draw a line with the mouse'''
|
||||
bl_idname = "object.modal_operator"
|
||||
bl_label = "Simple Modal Operator"
|
||||
|
||||
def modal(self, context, event):
|
||||
context.area.tag_redraw()
|
||||
|
||||
if event.type == 'MOUSEMOVE':
|
||||
self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
|
||||
|
||||
elif event.type == 'LEFTMOUSE':
|
||||
context.region.callback_remove(self._handle)
|
||||
return {'FINISHED'}
|
||||
|
||||
elif event.type in ('RIGHTMOUSE', 'ESC'):
|
||||
context.region.callback_remove(self._handle)
|
||||
return {'CANCELLED'}
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
if context.area.type == 'VIEW_3D':
|
||||
context.manager.add_modal_handler(self)
|
||||
|
||||
# Add the region OpenGL drawing callback
|
||||
# draw in view space with 'POST_VIEW' and 'PRE_VIEW'
|
||||
self._handle = context.region.callback_add(draw_callback_px, (self, context), 'POST_PIXEL')
|
||||
|
||||
self.mouse_path = []
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
else:
|
||||
self.report({'WARNING'}, "View3D not found, cannot run operator")
|
||||
return {'CANCELLED'}
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.register(ModalDrawOperator)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.types.unregister(ModalDrawOperator)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
@ -170,8 +170,7 @@ static void unit_dual_convert(double value, bUnitCollection *usys,
|
||||
{
|
||||
bUnitDef *unit= unit_best_fit(value, usys, NULL, 1);
|
||||
|
||||
if(value < 0.0) *value_a= -floor(-value/unit->scalar) * unit->scalar;
|
||||
else *value_a= floor( value/unit->scalar) * unit->scalar;
|
||||
*value_a= (value < 0.0 ? ceil:floor)(value/unit->scalar) * unit->scalar;
|
||||
*value_b= value - (*value_a);
|
||||
|
||||
*unit_a= unit;
|
||||
|
@ -1088,6 +1088,16 @@ static void rna_def_event(BlenderRNA *brna)
|
||||
RNA_def_property_int_sdna(prop, NULL, "y");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Mouse Y Position", "The window relative horizontal location of the mouse");
|
||||
|
||||
prop= RNA_def_property(srna, "mouse_region_x", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "mval[0]");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Mouse X Position", "The region relative vertical location of the mouse");
|
||||
|
||||
prop= RNA_def_property(srna, "mouse_region_y", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "mval[1]");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Mouse Y Position", "The region relative horizontal location of the mouse");
|
||||
|
||||
prop= RNA_def_property(srna, "mouse_prev_x", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "prevx");
|
||||
|
@ -32,12 +32,9 @@
|
||||
#include "BKE_context.h"
|
||||
#include "ED_space_api.h"
|
||||
|
||||
EnumPropertyItem region_draw_mode_items[] = {
|
||||
{REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Pose View", ""},
|
||||
{REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""},
|
||||
{REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
/* use this to stop other capsules from being mis-used */
|
||||
#define RNA_CAPSULE_ID "RNA_HANDLE"
|
||||
#define RNA_CAPSULE_ID_INVALID "RNA_HANDLE_REMOVED"
|
||||
|
||||
void cb_region_draw(const bContext *C, ARegion *ar, void *customdata)
|
||||
{
|
||||
@ -74,6 +71,12 @@ PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args)
|
||||
|
||||
if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
|
||||
|
||||
EnumPropertyItem region_draw_mode_items[] = {
|
||||
{REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Pose View", ""},
|
||||
{REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""},
|
||||
{REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
if(pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0)
|
||||
return NULL;
|
||||
|
||||
@ -81,24 +84,28 @@ PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args)
|
||||
Py_INCREF(args);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "callbcak_add(): type does not suppport cllbacks");
|
||||
PyErr_SetString(PyExc_TypeError, "callback_add(): type does not suppport callbacks");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return PyCapsule_New((void *)handle, NULL, NULL);
|
||||
return PyCapsule_New((void *)handle, RNA_CAPSULE_ID, NULL);
|
||||
}
|
||||
|
||||
PyObject *pyrna_callback_remove(BPy_StructRNA *self, PyObject *args)
|
||||
{
|
||||
PyObject *py_handle;
|
||||
PyObject *py_args;
|
||||
void *handle;
|
||||
void *customdata;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O!:callback_remove", &PyCapsule_Type, &py_handle))
|
||||
return NULL;
|
||||
|
||||
handle= PyCapsule_GetPointer(py_handle, NULL);
|
||||
handle= PyCapsule_GetPointer(py_handle, RNA_CAPSULE_ID);
|
||||
|
||||
if(handle==NULL) {
|
||||
PyErr_SetString(PyExc_ValueError, "callback_remove(handle): NULL handle given, invalid or already removed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
|
||||
customdata= ED_region_draw_cb_customdata(handle);
|
||||
@ -107,5 +114,8 @@ PyObject *pyrna_callback_remove(BPy_StructRNA *self, PyObject *args)
|
||||
ED_region_draw_cb_exit(((ARegion *)self->ptr.data)->type, handle);
|
||||
}
|
||||
|
||||
/* dont allow reuse */
|
||||
PyCapsule_SetName(py_handle, RNA_CAPSULE_ID_INVALID);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user