Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c')
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c364
1 files changed, 364 insertions, 0 deletions
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c
new file mode 100644
index 00000000000..137e8f5639d
--- /dev/null
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c
@@ -0,0 +1,364 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c
+ * \ingroup wm
+ */
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_string_utils.h"
+
+#include "BKE_context.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+#include "WM_message.h"
+
+#include "wm.h"
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+
+/* own includes */
+#include "wm_manipulator_wmapi.h"
+#include "wm_manipulator_intern.h"
+
+/* -------------------------------------------------------------------- */
+
+/** \name Property Definition
+ * \{ */
+
+BLI_INLINE wmManipulatorProperty *wm_manipulator_target_property_array(wmManipulator *mpr)
+{
+ return (wmManipulatorProperty *)(POINTER_OFFSET(mpr, mpr->type->struct_size));
+}
+
+wmManipulatorProperty *WM_manipulator_target_property_array(wmManipulator *mpr)
+{
+ return wm_manipulator_target_property_array(mpr);
+}
+
+wmManipulatorProperty *WM_manipulator_target_property_at_index(wmManipulator *mpr, int index)
+{
+ BLI_assert(index < mpr->type->target_property_defs_len);
+ BLI_assert(index != -1);
+ wmManipulatorProperty *mpr_prop_array = wm_manipulator_target_property_array(mpr);
+ return &mpr_prop_array[index];
+}
+
+wmManipulatorProperty *WM_manipulator_target_property_find(wmManipulator *mpr, const char *idname)
+{
+ int index = BLI_findstringindex(
+ &mpr->type->target_property_defs, idname, offsetof(wmManipulatorPropertyType, idname));
+ if (index != -1) {
+ return WM_manipulator_target_property_at_index(mpr, index);
+ }
+ else {
+ return NULL;
+ }
+}
+
+void WM_manipulator_target_property_def_rna_ptr(
+ wmManipulator *mpr, const wmManipulatorPropertyType *mpr_prop_type,
+ PointerRNA *ptr, PropertyRNA *prop, int index)
+{
+ wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_at_index(mpr, mpr_prop_type->index_in_type);
+
+ /* if manipulator evokes an operator we cannot use it for property manipulation */
+ BLI_assert(mpr->op_data == NULL);
+
+ mpr_prop->type = mpr_prop_type;
+
+ mpr_prop->ptr = *ptr;
+ mpr_prop->prop = prop;
+ mpr_prop->index = index;
+
+ if (mpr->type->property_update) {
+ mpr->type->property_update(mpr, mpr_prop);
+ }
+}
+
+void WM_manipulator_target_property_def_rna(
+ wmManipulator *mpr, const char *idname,
+ PointerRNA *ptr, const char *propname, int index)
+{
+ const wmManipulatorPropertyType *mpr_prop_type = WM_manipulatortype_target_property_find(mpr->type, idname);
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+ WM_manipulator_target_property_def_rna_ptr(mpr, mpr_prop_type, ptr, prop, index);
+}
+
+void WM_manipulator_target_property_def_func_ptr(
+ wmManipulator *mpr, const wmManipulatorPropertyType *mpr_prop_type,
+ const wmManipulatorPropertyFnParams *params)
+{
+ wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_at_index(mpr, mpr_prop_type->index_in_type);
+
+ /* if manipulator evokes an operator we cannot use it for property manipulation */
+ BLI_assert(mpr->op_data == NULL);
+
+ mpr_prop->type = mpr_prop_type;
+
+ mpr_prop->custom_func.value_get_fn = params->value_get_fn;
+ mpr_prop->custom_func.value_set_fn = params->value_set_fn;
+ mpr_prop->custom_func.range_get_fn = params->range_get_fn;
+ mpr_prop->custom_func.free_fn = params->free_fn;
+ mpr_prop->custom_func.user_data = params->user_data;
+
+ if (mpr->type->property_update) {
+ mpr->type->property_update(mpr, mpr_prop);
+ }
+}
+
+void WM_manipulator_target_property_def_func(
+ wmManipulator *mpr, const char *idname,
+ const wmManipulatorPropertyFnParams *params)
+{
+ const wmManipulatorPropertyType *mpr_prop_type = WM_manipulatortype_target_property_find(mpr->type, idname);
+ WM_manipulator_target_property_def_func_ptr(mpr, mpr_prop_type, params);
+}
+
+void WM_manipulator_target_property_clear_rna_ptr(
+ wmManipulator *mpr, const wmManipulatorPropertyType *mpr_prop_type)
+{
+ wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_at_index(mpr, mpr_prop_type->index_in_type);
+
+ /* if manipulator evokes an operator we cannot use it for property manipulation */
+ BLI_assert(mpr->op_data == NULL);
+
+ mpr_prop->type = NULL;
+
+ mpr_prop->ptr = PointerRNA_NULL;
+ mpr_prop->prop = NULL;
+ mpr_prop->index = -1;
+}
+
+void WM_manipulator_target_property_clear_rna(
+ wmManipulator *mpr, const char *idname)
+{
+ const wmManipulatorPropertyType *mpr_prop_type = WM_manipulatortype_target_property_find(mpr->type, idname);
+ WM_manipulator_target_property_clear_rna_ptr(mpr, mpr_prop_type);
+}
+
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Property Access
+ * \{ */
+
+bool WM_manipulator_target_property_is_valid_any(wmManipulator *mpr)
+{
+ wmManipulatorProperty *mpr_prop_array = wm_manipulator_target_property_array(mpr);
+ for (int i = 0; i < mpr->type->target_property_defs_len; i++) {
+ wmManipulatorProperty *mpr_prop = &mpr_prop_array[i];
+ if (WM_manipulator_target_property_is_valid(mpr_prop)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool WM_manipulator_target_property_is_valid(const wmManipulatorProperty *mpr_prop)
+{
+ return ((mpr_prop->prop != NULL) ||
+ (mpr_prop->custom_func.value_get_fn && mpr_prop->custom_func.value_set_fn));
+}
+
+float WM_manipulator_target_property_value_get(
+ const wmManipulator *mpr, wmManipulatorProperty *mpr_prop)
+{
+ if (mpr_prop->custom_func.value_get_fn) {
+ float value = 0.0f;
+ BLI_assert(mpr_prop->type->array_length == 1);
+ mpr_prop->custom_func.value_get_fn(mpr, mpr_prop, &value);
+ return value;
+ }
+
+ if (mpr_prop->index == -1) {
+ return RNA_property_float_get(&mpr_prop->ptr, mpr_prop->prop);
+ }
+ else {
+ return RNA_property_float_get_index(&mpr_prop->ptr, mpr_prop->prop, mpr_prop->index);
+ }
+}
+
+void WM_manipulator_target_property_value_set(
+ bContext *C, const wmManipulator *mpr,
+ wmManipulatorProperty *mpr_prop, const float value)
+{
+ if (mpr_prop->custom_func.value_set_fn) {
+ BLI_assert(mpr_prop->type->array_length == 1);
+ mpr_prop->custom_func.value_set_fn(mpr, mpr_prop, &value);
+ return;
+ }
+
+ /* reset property */
+ if (mpr_prop->index == -1) {
+ RNA_property_float_set(&mpr_prop->ptr, mpr_prop->prop, value);
+ }
+ else {
+ RNA_property_float_set_index(&mpr_prop->ptr, mpr_prop->prop, mpr_prop->index, value);
+ }
+ RNA_property_update(C, &mpr_prop->ptr, mpr_prop->prop);
+}
+
+void WM_manipulator_target_property_value_get_array(
+ const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
+ float *value)
+{
+ if (mpr_prop->custom_func.value_get_fn) {
+ mpr_prop->custom_func.value_get_fn(mpr, mpr_prop, value);
+ return;
+ }
+ RNA_property_float_get_array(&mpr_prop->ptr, mpr_prop->prop, value);
+}
+
+void WM_manipulator_target_property_value_set_array(
+ bContext *C, const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
+ const float *value)
+{
+ if (mpr_prop->custom_func.value_set_fn) {
+ mpr_prop->custom_func.value_set_fn(mpr, mpr_prop, value);
+ return;
+ }
+ RNA_property_float_set_array(&mpr_prop->ptr, mpr_prop->prop, value);
+
+ RNA_property_update(C, &mpr_prop->ptr, mpr_prop->prop);
+}
+
+bool WM_manipulator_target_property_range_get(
+ const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
+ float range[2])
+{
+ if (mpr_prop->custom_func.value_get_fn) {
+ if (mpr_prop->custom_func.range_get_fn) {
+ mpr_prop->custom_func.range_get_fn(mpr, mpr_prop, range);
+ return true;
+ }
+ else {
+ return false;
+
+ }
+ }
+
+ float step, precision;
+ RNA_property_float_ui_range(&mpr_prop->ptr, mpr_prop->prop, &range[0], &range[1], &step, &precision);
+ return true;
+}
+
+int WM_manipulator_target_property_array_length(
+ const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop)
+{
+ if (mpr_prop->custom_func.value_get_fn) {
+ return mpr_prop->type->array_length;
+ }
+ return RNA_property_array_length(&mpr_prop->ptr, mpr_prop->prop);
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Property Define
+ * \{ */
+
+const wmManipulatorPropertyType *WM_manipulatortype_target_property_find(
+ const wmManipulatorType *wt, const char *idname)
+{
+ return BLI_findstring(&wt->target_property_defs, idname, offsetof(wmManipulatorPropertyType, idname));
+}
+
+void WM_manipulatortype_target_property_def(
+ wmManipulatorType *wt, const char *idname, int data_type, int array_length)
+{
+ wmManipulatorPropertyType *mpt;
+
+ BLI_assert(WM_manipulatortype_target_property_find(wt, idname) == NULL);
+
+ const uint idname_size = strlen(idname) + 1;
+ mpt = MEM_callocN(sizeof(wmManipulatorPropertyType) + idname_size, __func__);
+ memcpy(mpt->idname, idname, idname_size);
+ mpt->data_type = data_type;
+ mpt->array_length = array_length;
+ mpt->index_in_type = wt->target_property_defs_len;
+ wt->target_property_defs_len += 1;
+ BLI_addtail(&wt->target_property_defs, mpt);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Property Utilities
+ * \{ */
+
+void WM_manipulator_do_msg_notify_tag_refresh(
+ bContext *UNUSED(C), wmMsgSubscribeKey *UNUSED(msg_key), wmMsgSubscribeValue *msg_val)
+{
+ ARegion *ar = msg_val->owner;
+ wmManipulatorMap *mmap = msg_val->user_data;
+
+ ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
+}
+
+/**
+ * Runs on the "prepare draw" pass,
+ * drawing the region clears.
+ */
+void WM_manipulator_target_property_subscribe_all(
+ wmManipulator *mpr, struct wmMsgBus *mbus, ARegion *ar)
+{
+ if (mpr->type->target_property_defs_len) {
+ wmManipulatorProperty *mpr_prop_array = WM_manipulator_target_property_array(mpr);
+ for (int i = 0; i < mpr->type->target_property_defs_len; i++) {
+ wmManipulatorProperty *mpr_prop = &mpr_prop_array[i];
+ if (WM_manipulator_target_property_is_valid(mpr_prop)) {
+ if (mpr_prop->prop) {
+ WM_msg_subscribe_rna(
+ mbus, &mpr_prop->ptr, mpr_prop->prop,
+ &(const wmMsgSubscribeValue){
+ .owner = ar,
+ .user_data = ar,
+ .notify = ED_region_do_msg_notify_tag_redraw,
+ }, __func__);
+ WM_msg_subscribe_rna(
+ mbus, &mpr_prop->ptr, mpr_prop->prop,
+ &(const wmMsgSubscribeValue){
+ .owner = ar,
+ .user_data = mpr->parent_mgroup->parent_mmap,
+ .notify = WM_manipulator_do_msg_notify_tag_refresh,
+ }, __func__);
+ }
+ }
+ }
+ }
+}
+
+/** \} */