diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-05-22 15:00:44 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-05-22 16:31:06 +0300 |
commit | 96a7ed8a159fec97ab19a6d19ffe6201a4ee2b35 (patch) | |
tree | ad7164dbc343e62551de15e96c3bdb4841560453 /source | |
parent | 298f8042efe12b4a8861a83c860b3adb0d56f1f6 (diff) |
Tool System: store operator properties in the tool
This replaces last-used property use which wasn't reliable since
properties were not considered 'set' - causing them to be ignored.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/workspace.c | 5 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 5 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_workspace_types.h | 13 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_workspace_api.c | 24 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 6 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 33 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_toolsystem.c | 46 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_event_system.h | 1 |
9 files changed, 123 insertions, 11 deletions
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c index fd316cb9d82..7fc0d814089 100644 --- a/source/blender/blenkernel/intern/workspace.c +++ b/source/blender/blenkernel/intern/workspace.c @@ -34,6 +34,7 @@ #include "BLI_listbase.h" #include "BKE_global.h" +#include "BKE_idprop.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_scene.h" @@ -176,6 +177,10 @@ void BKE_workspace_free(WorkSpace *workspace) tref_next = tref->next; if (tref->runtime) { MEM_freeN(tref->runtime); + if (tref->properties) { + IDP_FreeProperty(tref->properties); + MEM_freeN(tref->properties); + } } } BLI_freelistN(&workspace->tools); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a8181f1e043..c92b27bdb1c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2941,6 +2941,7 @@ static void direct_link_workspace(FileData *fd, WorkSpace *workspace, const Main for (bToolRef *tref = workspace->tools.first; tref; tref = tref->next) { tref->runtime = NULL; + tref->properties = newdataadr(fd, tref->properties); } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 8ea1205be38..a3cac39f609 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -3602,6 +3602,11 @@ static void write_workspace(WriteData *wd, WorkSpace *workspace) writelist(wd, DATA, WorkSpaceDataRelation, &workspace->scene_viewlayer_relations); writelist(wd, DATA, wmOwnerID, &workspace->owner_ids); writelist(wd, DATA, bToolRef, &workspace->tools); + for (bToolRef *tref = workspace->tools.first; tref; tref = tref->next) { + if (tref->properties) { + IDP_WriteProperty(tref->properties, wd); + } + } } /* Keep it last of write_foodata functions. */ diff --git a/source/blender/makesdna/DNA_workspace_types.h b/source/blender/makesdna/DNA_workspace_types.h index 24fa0e06d90..ca9186e16bf 100644 --- a/source/blender/makesdna/DNA_workspace_types.h +++ b/source/blender/makesdna/DNA_workspace_types.h @@ -56,11 +56,13 @@ # # typedef struct bToolRef_Runtime { - /* One of these must be defined. */ int cursor; + + /* One of these 3 must be defined. */ char keymap[64]; char manipulator_group[64]; char data_block[64]; + /* index when a tool is a member of a group */ int index; } bToolRef_Runtime; @@ -82,6 +84,15 @@ typedef struct bToolRef { */ int mode; + /** + * Use for tool options, each group's name must match a tool name: + * + * {"Tool Name": {"SOME_OT_operator": {...}, ..}, ..} + * + * This is done since different tools may call the same operators with their own options. + */ + IDProperty *properties; + /** Variables needed to operate the tool. */ bToolRef_Runtime *runtime; } bToolRef; diff --git a/source/blender/makesrna/intern/rna_workspace_api.c b/source/blender/makesrna/intern/rna_workspace_api.c index 4c6949cc33d..e56d9a0bc33 100644 --- a/source/blender/makesrna/intern/rna_workspace_api.c +++ b/source/blender/makesrna/intern/rna_workspace_api.c @@ -64,6 +64,20 @@ static void rna_WorkspaceTool_setup( WM_toolsystem_ref_set_from_runtime(C, (WorkSpace *)id, tref, &tref_rt, name); } +static PointerRNA rna_WorkspaceTool_operator_properties( + bToolRef *tref, + const char *idname) +{ + wmOperatorType *ot = WM_operatortype_find(idname, true); + + if (ot != NULL) { + PointerRNA ptr; + WM_toolsystem_ref_properties_ensure(tref, ot, &ptr); + return ptr; + } + return PointerRNA_NULL; +} + #else void RNA_api_workspace(StructRNA *UNUSED(srna)) @@ -91,6 +105,16 @@ void RNA_api_workspace_tool(StructRNA *srna) RNA_def_string(func, "manipulator_group", NULL, MAX_NAME, "Manipulator Group", ""); RNA_def_string(func, "data_block", NULL, MAX_NAME, "Data Block", ""); RNA_def_int(func, "index", 0, INT_MIN, INT_MAX, "Index", "", INT_MIN, INT_MAX); + + /* Access tool operator options (optionally create). */ + func = RNA_def_function(srna, "operator_properties", "rna_WorkspaceTool_operator_properties"); + parm = RNA_def_string(func, "operator", NULL, 0, "", ""); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + /* return */ + parm = RNA_def_pointer(func, "result", "OperatorProperties", "", ""); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_RNAPTR); + RNA_def_function_return(func, parm); + } #endif diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 050edb980e9..33222b2f1f1 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -646,6 +646,12 @@ bool WM_toolsystem_active_tool_is_brush(const struct bContext *C); void WM_toolsystem_do_msg_notify_tag_refresh( struct bContext *C, struct wmMsgSubscribeKey *msg_key, struct wmMsgSubscribeValue *msg_val); +struct IDProperty *WM_toolsystem_ref_properties_ensure_idprops(struct bToolRef *tref); +void WM_toolsystem_ref_properties_ensure(struct bToolRef *tref, struct wmOperatorType *ot, struct PointerRNA *ptr); + +void WM_toolsystem_ref_properties_init_for_keymap( + struct bToolRef *tref, struct PointerRNA *dst_ptr, struct PointerRNA *src_ptr, struct wmOperatorType *ot); + /* wm_tooltip.c */ typedef struct ARegion *(*wmTooltipInitFn)(struct bContext *, struct ARegion *, bool *); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index df19f30e31e..f49f961f505 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1235,7 +1235,8 @@ bool WM_operator_last_properties_store(wmOperator *UNUSED(op)) */ static int wm_operator_invoke( bContext *C, wmOperatorType *ot, wmEvent *event, - PointerRNA *properties, ReportList *reports, const bool poll_only) + PointerRNA *properties, ReportList *reports, + const bool poll_only, bool use_last_properties) { int retval = OPERATOR_PASS_THROUGH; @@ -1253,7 +1254,7 @@ static int wm_operator_invoke( } /* initialize setting from previous run */ - if (!is_nested_call) { /* not called by py script */ + if (!is_nested_call && use_last_properties) { /* not called by py script */ WM_operator_last_properties_init(op); } @@ -1301,7 +1302,7 @@ static int wm_operator_invoke( /* do nothing, wm_operator_exec() has been called somewhere */ } else if (retval & OPERATOR_FINISHED) { - const bool store = !is_nested_call; + const bool store = !is_nested_call && use_last_properties; wm_operator_finished(C, op, false, store); } else if (retval & OPERATOR_RUNNING_MODAL) { @@ -1464,7 +1465,7 @@ static int wm_operator_call_internal( CTX_wm_region_set(C, ar1); } - retval = wm_operator_invoke(C, ot, event, properties, reports, poll_only); + retval = wm_operator_invoke(C, ot, event, properties, reports, poll_only, true); /* set region back */ CTX_wm_region_set(C, ar); @@ -1478,7 +1479,7 @@ static int wm_operator_call_internal( ARegion *ar = CTX_wm_region(C); CTX_wm_region_set(C, NULL); - retval = wm_operator_invoke(C, ot, event, properties, reports, poll_only); + retval = wm_operator_invoke(C, ot, event, properties, reports, poll_only, true); CTX_wm_region_set(C, ar); return retval; @@ -1492,7 +1493,7 @@ static int wm_operator_call_internal( CTX_wm_region_set(C, NULL); CTX_wm_area_set(C, NULL); - retval = wm_operator_invoke(C, ot, event, properties, reports, poll_only); + retval = wm_operator_invoke(C, ot, event, properties, reports, poll_only, true); CTX_wm_area_set(C, area); CTX_wm_region_set(C, ar); @@ -1500,7 +1501,7 @@ static int wm_operator_call_internal( } case WM_OP_EXEC_DEFAULT: case WM_OP_INVOKE_DEFAULT: - return wm_operator_invoke(C, ot, event, properties, reports, poll_only); + return wm_operator_invoke(C, ot, event, properties, reports, poll_only, true); } } @@ -1975,9 +1976,19 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand else { wmOperatorType *ot = WM_operatortype_find(event->keymap_idname, 0); - if (ot) { - if (wm_operator_check_locked_interface(C, ot)) { - retval = wm_operator_invoke(C, ot, event, properties, NULL, false); + if (ot && wm_operator_check_locked_interface(C, ot)) { + bool use_last_properties = true; + PointerRNA tool_properties = {0}; + if (handler->keymap_tool) { + WM_toolsystem_ref_properties_init_for_keymap(handler->keymap_tool, &tool_properties, properties, ot); + properties = &tool_properties; + use_last_properties = false; + } + + retval = wm_operator_invoke(C, ot, event, properties, NULL, false, use_last_properties); + + if (handler->keymap_tool) { + WM_operator_properties_free(&tool_properties); } } } @@ -2887,6 +2898,8 @@ void wm_event_do_handlers(bContext *C) C, tref_rt->keymap, sa->spacetype, RGN_TYPE_WINDOW); if (km != NULL) { sneaky_handler.keymap = km; + sneaky_handler.keymap_tool = sa->runtime.tool; + /* Handle widgets first. */ wmEventHandler *handler_last = ar->handlers.last; while (handler_last && handler_last->manipulator_map == NULL) { diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c index c616d143b69..3d9c6d88d2c 100644 --- a/source/blender/windowmanager/intern/wm_toolsystem.c +++ b/source/blender/windowmanager/intern/wm_toolsystem.c @@ -45,6 +45,7 @@ #include "BKE_library.h" #include "BKE_main.h" #include "BKE_paint.h" +#include "BKE_idprop.h" #include "BKE_workspace.h" #include "RNA_access.h" @@ -527,3 +528,48 @@ void WM_toolsystem_do_msg_notify_tag_refresh( }; WM_toolsystem_refresh(C, workspace, &tkey); } + +IDProperty *WM_toolsystem_ref_properties_ensure_idprops(bToolRef *tref) +{ + if (tref->properties == NULL) { + IDPropertyTemplate val = {0}; + tref->properties = IDP_New(IDP_GROUP, &val, "wmOperatorProperties"); + } + return tref->properties; +} + +void WM_toolsystem_ref_properties_ensure(bToolRef *tref, wmOperatorType *ot, PointerRNA *ptr) +{ + IDProperty *group = WM_toolsystem_ref_properties_ensure_idprops(tref); + IDProperty *prop = IDP_GetPropertyFromGroup(group, ot->idname); + if (prop == NULL) { + IDPropertyTemplate val = {0}; + prop = IDP_New(IDP_GROUP, &val, "wmOperatorProperties"); + STRNCPY(prop->name, ot->idname); + IDP_ReplaceInGroup_ex(group, prop, NULL); + } + else { + BLI_assert(prop->type == IDP_GROUP); + } + + RNA_pointer_create(NULL, ot->srna, prop, ptr); +} + +void WM_toolsystem_ref_properties_init_for_keymap( + bToolRef *tref, PointerRNA *dst_ptr, PointerRNA *src_ptr, wmOperatorType *ot) +{ + *dst_ptr = *src_ptr; + if (dst_ptr->data) { + dst_ptr->data = IDP_CopyProperty(dst_ptr->data); + } + else { + IDPropertyTemplate val = {0}; + dst_ptr->data = IDP_New(IDP_GROUP, &val, "wmOpItemProp"); + } + if (tref->properties != NULL) { + IDProperty *prop = IDP_GetPropertyFromGroup(tref->properties, ot->idname); + if (prop) { + IDP_MergeGroup(dst_ptr->data, prop, true); + } + } +} diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h index 452fe377665..7b18ed54c85 100644 --- a/source/blender/windowmanager/wm_event_system.h +++ b/source/blender/windowmanager/wm_event_system.h @@ -54,6 +54,7 @@ typedef struct wmEventHandler { /* Run after the keymap item runs. */ void (*keymap_callback)(wmKeyMap *keymap, wmKeyMapItem *kmi, void *user_data); void *keymap_callback_user_data; + struct bToolRef *keymap_tool; /* modal operator handler */ wmOperator *op; /* for derived/modal handlers */ |