Exemplo n.º 1
0
/* TODO de-duplicate redo panel functions - campbell */
static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
{
	wmOperator *op = WM_operator_last_redo(C);
	ARegion *ar;
	ARegion *ar1;

	if (op == NULL) {
		return;
	}

	/* keep in sync with logic in ED_undo_operator_repeat() */
	ar = CTX_wm_region(C);
	ar1 = BKE_area_find_region_active_win(CTX_wm_area(C));
	if (ar1)
		CTX_wm_region_set((bContext *)C, ar1);

	if (WM_operator_poll((bContext *)C, op->type)) {
		uiBlock *block = uiLayoutGetBlock(pa->layout);

		if (!WM_operator_check_ui_enabled(C, op->type->name))
			uiLayoutSetEnabled(pa->layout, false);

		/* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */
		UI_block_func_handle_set(block, ED_undo_operator_repeat_cb_evt, op);

		view3d_panel_operator_redo_operator(C, pa, op);
	}

	/* set region back */
	CTX_wm_region_set((bContext *)C, ar);
}
Exemplo n.º 2
0
static void gizmo_op_redo_exec(struct ValueOpRedoGroup *igzgroup)
{
  wmOperator *op = igzgroup->state.op;
  if (op == WM_operator_last_redo((bContext *)igzgroup->state.context)) {
    ED_undo_operator_repeat((bContext *)igzgroup->state.context, op);
  }
}
Exemplo n.º 3
0
static void view3d_panel_operator_redo_header(const bContext *C, Panel *pa)
{
	wmOperator *op= WM_operator_last_redo(C);

	if(op) BLI_strncpy(pa->drawname, op->type->name, sizeof(pa->drawname));
	else BLI_strncpy(pa->drawname, "Operator", sizeof(pa->drawname));
}
Exemplo n.º 4
0
static int file_browse_exec(bContext *C, wmOperator *op)
{
	FileBrowseOp *fbo = op->customdata;
	ID *id;
	char *str, path[FILE_MAX];
	const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath";
	
	if (RNA_struct_property_is_set(op->ptr, path_prop) == 0 || fbo == NULL)
		return OPERATOR_CANCELLED;
	
	str = RNA_string_get_alloc(op->ptr, path_prop, NULL, 0);

	/* add slash for directories, important for some properties */
	if (RNA_property_subtype(fbo->prop) == PROP_DIRPATH) {
		int is_relative = RNA_boolean_get(op->ptr, "relative_path");
		id = fbo->ptr.id.data;

		BLI_strncpy(path, str, FILE_MAX);
		BLI_path_abs(path, id ? ID_BLEND_PATH(G.main, id) : G.main->name);
		
		if (BLI_is_dir(path)) {
			/* do this first so '//' isnt converted to '//\' on windows */
			BLI_add_slash(path);
			if (is_relative) {
				BLI_strncpy(path, str, FILE_MAX);
				BLI_path_rel(path, G.main->name);
				str = MEM_reallocN(str, strlen(path) + 2);
				BLI_strncpy(str, path, FILE_MAX);
			}
			else {
				str = MEM_reallocN(str, strlen(str) + 2);
			}
		}
		else {
			char * const lslash = (char *)BLI_last_slash(str);
			if (lslash) lslash[1] = '\0';
		}
	}

	RNA_property_string_set(&fbo->ptr, fbo->prop, str);
	RNA_property_update(C, &fbo->ptr, fbo->prop);
	MEM_freeN(str);


	/* special, annoying exception, filesel on redo panel [#26618] */
	{
		wmOperator *redo_op = WM_operator_last_redo(C);
		if (redo_op) {
			if (fbo->ptr.data == redo_op->ptr->data) {
				ED_undo_operator_repeat(C, redo_op);
			}
		}
	}

	MEM_freeN(op->customdata);

	return OPERATOR_FINISHED;
}
Exemplo n.º 5
0
static void view3d_panel_operator_redo_header(const bContext *C, Panel *pa)
{
	wmOperator *op = WM_operator_last_redo(C);

	if (op)
		BLI_strncpy(pa->drawname, RNA_struct_ui_name(op->type->srna), sizeof(pa->drawname));
	else
		BLI_strncpy(pa->drawname, IFACE_("Operator"), sizeof(pa->drawname));
}
Exemplo n.º 6
0
static int file_browse_exec(bContext *C, wmOperator *op)
{
	FileBrowseOp *fbo= op->customdata;
	ID *id;
	char *base, *str, path[FILE_MAX];
	const char *path_prop= RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath";
	
	if (RNA_property_is_set(op->ptr, path_prop)==0 || fbo==NULL)
		return OPERATOR_CANCELLED;
	
	str= RNA_string_get_alloc(op->ptr, path_prop, NULL, 0);

	/* add slash for directories, important for some properties */
	if(RNA_property_subtype(fbo->prop) == PROP_DIRPATH) {
		char name[FILE_MAX];
		
		id = fbo->ptr.id.data;
		base = (id && id->lib)? id->lib->filepath: G.main->name;

		BLI_strncpy(path, str, FILE_MAX);
		BLI_path_abs(path, base);
		
		if(BLI_is_dir(path)) {
			str = MEM_reallocN(str, strlen(str)+2);
			BLI_add_slash(str);
		}
		else
			BLI_splitdirstring(str, name);
	}

	RNA_property_string_set(&fbo->ptr, fbo->prop, str);
	RNA_property_update(C, &fbo->ptr, fbo->prop);
	MEM_freeN(str);


	/* special, annoying exception, filesel on redo panel [#26618] */
	{
		wmOperator *redo_op= WM_operator_last_redo(C);
		if(redo_op) {
			if(fbo->ptr.data == redo_op->ptr->data) {
				ED_undo_operator_repeat(C, redo_op);
			}
		}
	}

	MEM_freeN(op->customdata);

	return OPERATOR_FINISHED;
}
Exemplo n.º 7
0
/* TODO de-duplicate redo panel functions - campbell */
static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
{
	wmOperator *op = WM_operator_last_redo(C);
	uiBlock *block;
	
	if (op == NULL)
		return;
	if (WM_operator_poll((bContext *)C, op->type) == 0)
		return;
	
	block = uiLayoutGetBlock(pa->layout);
	
	if (!WM_operator_check_ui_enabled(C, op->type->name))
		uiLayoutSetEnabled(pa->layout, FALSE);

	/* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */
	uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, op);
	
	view3d_panel_operator_redo_operator(C, pa, op);
}
Exemplo n.º 8
0
static void WIDGETGROUP_value_operator_redo_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
  struct ValueOpRedoGroup *igzgroup = MEM_mallocN(sizeof(struct ValueOpRedoGroup), __func__);

  igzgroup->gizmo = WM_gizmo_new("GIZMO_GT_value_2d", gzgroup, NULL);
  wmGizmo *gz = igzgroup->gizmo;

  igzgroup->state.context = C;
  igzgroup->state.op = WM_operator_last_redo(C);

  gzgroup->customdata = igzgroup;

  UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color);
  UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi);

  WM_gizmo_target_property_def_func(gz,
                                    "offset",
                                    &(const struct wmGizmoPropertyFnParams){
                                        .value_get_fn = gizmo_value_operator_redo_value_get,
                                        .value_set_fn = gizmo_value_operator_redo_value_set,
                                        .range_get_fn = NULL,
                                        .user_data = igzgroup,
                                    });
Exemplo n.º 9
0
int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result)
{
	bScreen *sc = CTX_wm_screen(C);
	Scene *scene = sc->scene;
	Base *base;
	unsigned int lay = scene->lay;

#if 0  /* Using the context breaks adding objects in the UI. Need to find out why - campbell */
	Object *obact = CTX_data_active_object(C);
	Object *obedit = CTX_data_edit_object(C);
	base = CTX_data_active_base(C);
#else
	Object *obedit = scene->obedit;
	Object *obact = OBACT;
	base = BASACT;
#endif

	if (CTX_data_dir(member)) {
		CTX_data_dir_set(result, screen_context_dir);
		return 1;
	}
	else if (CTX_data_equals(member, "scene")) {
		CTX_data_id_pointer_set(result, &scene->id);
		return 1;
	}
	else if (CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) {
		int visible_objects = CTX_data_equals(member, "visible_objects");

		for (base = scene->base.first; base; base = base->next) {
			if (((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & scene->lay)) {
				if (visible_objects)
					CTX_data_id_list_add(result, &base->object->id);
				else
					CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
			}
		}
		CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
		return 1;
	}
	else if (CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) {
		int selectable_objects = CTX_data_equals(member, "selectable_objects");

		for (base = scene->base.first; base; base = base->next) {
			if (base->lay & lay) {
				if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0 && (base->object->restrictflag & OB_RESTRICT_SELECT) == 0) {
					if (selectable_objects)
						CTX_data_id_list_add(result, &base->object->id);
					else
						CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
				}
			}
		}
		CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
		return 1;
	}
	else if (CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
		int selected_objects = CTX_data_equals(member, "selected_objects");

		for (base = scene->base.first; base; base = base->next) {
			if ((base->flag & SELECT) && (base->lay & scene->lay)) {
				if (selected_objects)
					CTX_data_id_list_add(result, &base->object->id);
				else
					CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
			}
		}
		CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
		return 1;
	}
	else if (CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) {
		int selected_editable_objects = CTX_data_equals(member, "selected_editable_objects");

		for (base = scene->base.first; base; base = base->next) {
			if ((base->flag & SELECT) && (base->lay & scene->lay)) {
				if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) {
					if (0 == BKE_object_is_libdata(base->object)) {
						if (selected_editable_objects)
							CTX_data_id_list_add(result, &base->object->id);
						else
							CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
					}
				}
			}
		}
		CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
		return 1;
	}
	else if (CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) {
		bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
		EditBone *ebone, *flipbone = NULL;
		int editable_bones = CTX_data_equals(member, "editable_bones");
		
		if (arm && arm->edbo) {
			/* Attention: X-Axis Mirroring is also handled here... */
			for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
				/* first and foremost, bone must be visible and selected */
				if (EBONE_VISIBLE(arm, ebone)) {
					/* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
					 * so that most users of this data don't need to explicitly check for it themselves.
					 * 
					 * We need to make sure that these mirrored copies are not selected, otherwise some
					 * bones will be operated on twice.
					 */
					if (arm->flag & ARM_MIRROR_EDIT)
						flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
					
					/* if we're filtering for editable too, use the check for that instead, as it has selection check too */
					if (editable_bones) {
						/* only selected + editable */
						if (EBONE_EDITABLE(ebone)) {
							CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
						
							if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
								CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
						}
					}
					else {
						/* only include bones if visible */
						CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
						
						if ((flipbone) && EBONE_VISIBLE(arm, flipbone) == 0)
							CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
					}
				}
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "selected_bones") || CTX_data_equals(member, "selected_editable_bones")) {
		bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
		EditBone *ebone, *flipbone = NULL;
		int selected_editable_bones = CTX_data_equals(member, "selected_editable_bones");
		
		if (arm && arm->edbo) {
			/* Attention: X-Axis Mirroring is also handled here... */
			for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
				/* first and foremost, bone must be visible and selected */
				if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) {
					/* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
					 * so that most users of this data don't need to explicitly check for it themselves.
					 * 
					 * We need to make sure that these mirrored copies are not selected, otherwise some
					 * bones will be operated on twice.
					 */
					if (arm->flag & ARM_MIRROR_EDIT)
						flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
					
					/* if we're filtering for editable too, use the check for that instead, as it has selection check too */
					if (selected_editable_bones) {
						/* only selected + editable */
						if (EBONE_EDITABLE(ebone)) {
							CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
						
							if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
								CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
						}
					}
					else {
						/* only include bones if selected */
						CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
						
						if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
							CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
					}
				}
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "visible_pose_bones")) {
		Object *obpose = BKE_object_pose_armature_get(obact);
		bArmature *arm = (obpose) ? obpose->data : NULL;
		bPoseChannel *pchan;
		
		if (obpose && obpose->pose && arm) {
			for (pchan = obpose->pose->chanbase.first; pchan; pchan = pchan->next) {
				/* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
				if (PBONE_VISIBLE(arm, pchan->bone)) {
					CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan);
				}
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "selected_pose_bones")) {
		Object *obpose = BKE_object_pose_armature_get(obact);
		bArmature *arm = (obpose) ? obpose->data : NULL;
		bPoseChannel *pchan;
		
		if (obpose && obpose->pose && arm) {
			for (pchan = obpose->pose->chanbase.first; pchan; pchan = pchan->next) {
				/* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
				if (PBONE_VISIBLE(arm, pchan->bone)) {
					if (pchan->bone->flag & BONE_SELECTED)
						CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan);
				}
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "active_bone")) {
		if (obact && obact->type == OB_ARMATURE) {
			bArmature *arm = obact->data;
			if (arm->edbo) {
				if (arm->act_edbone) {
					CTX_data_pointer_set(result, &arm->id, &RNA_EditBone, arm->act_edbone);
					return 1;
				}
			}
			else {
				if (arm->act_bone) {
					CTX_data_pointer_set(result, &arm->id, &RNA_Bone, arm->act_bone);
					return 1;
				}
			}
		}
	}
	else if (CTX_data_equals(member, "active_pose_bone")) {
		bPoseChannel *pchan;
		Object *obpose = BKE_object_pose_armature_get(obact);
		
		pchan = BKE_pose_channel_active(obpose);
		if (pchan) {
			CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "active_base")) {
		if (base)
			CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, base);

		return 1;
	}
	else if (CTX_data_equals(member, "active_object")) {
		if (obact)
			CTX_data_id_pointer_set(result, &obact->id);

		return 1;
	}
	else if (CTX_data_equals(member, "object")) {
		if (obact)
			CTX_data_id_pointer_set(result, &obact->id);

		return 1;
	}
	else if (CTX_data_equals(member, "edit_object")) {
		/* convenience for now, 1 object per scene in editmode */
		if (obedit)
			CTX_data_id_pointer_set(result, &obedit->id);
		
		return 1;
	}
	else if (CTX_data_equals(member, "sculpt_object")) {
		if (obact && (obact->mode & OB_MODE_SCULPT))
			CTX_data_id_pointer_set(result, &obact->id);

		return 1;
	}
	else if (CTX_data_equals(member, "vertex_paint_object")) {
		if (obact && (obact->mode & OB_MODE_VERTEX_PAINT))
			CTX_data_id_pointer_set(result, &obact->id);

		return 1;
	}
	else if (CTX_data_equals(member, "weight_paint_object")) {
		if (obact && (obact->mode & OB_MODE_WEIGHT_PAINT))
			CTX_data_id_pointer_set(result, &obact->id);

		return 1;
	}
	else if (CTX_data_equals(member, "image_paint_object")) {
		if (obact && (obact->mode & OB_MODE_TEXTURE_PAINT))
			CTX_data_id_pointer_set(result, &obact->id);

		return 1;
	}
	else if (CTX_data_equals(member, "particle_edit_object")) {
		if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT))
			CTX_data_id_pointer_set(result, &obact->id);

		return 1;
	}
	else if (CTX_data_equals(member, "sequences")) {
		Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
		if (ed) {
			Sequence *seq;
			for (seq = ed->seqbasep->first; seq; seq = seq->next) {
				CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "selected_sequences")) {
		Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
		if (ed) {
			Sequence *seq;
			for (seq = ed->seqbasep->first; seq; seq = seq->next) {
				if (seq->flag & SELECT) {
					CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
				}
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "selected_editable_sequences")) {
		Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
		if (ed) {
			Sequence *seq;
			for (seq = ed->seqbasep->first; seq; seq = seq->next) {
				if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) {
					CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
				}
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "active_operator")) {
		wmOperator *op = NULL;

		SpaceFile *sfile = CTX_wm_space_file(C);
		if (sfile) {
			op = sfile->op;
		}
		else if ((op = uiContextActiveOperator(C))) {
			/* do nothign */
		}
		else {
			/* note, this checks poll, could be a problem, but this also
			 * happens for the toolbar */
			op = WM_operator_last_redo(C);
		}
		/* TODO, get the operator from popup's */

		if (op && op->ptr) {
			CTX_data_pointer_set(result, NULL, &RNA_Operator, op);
			return 1;
		}
	}
	else {
		return 0; /* not found */
	}

	return -1; /* found but not available */
}
Exemplo n.º 10
0
int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result)
{
	bScreen *sc = CTX_wm_screen(C);
	ScrArea *sa = CTX_wm_area(C);
	Scene *scene = sc->scene;
	Base *base;

#if 0  /* Using the context breaks adding objects in the UI. Need to find out why - campbell */
	Object *obact = CTX_data_active_object(C);
	Object *obedit = CTX_data_edit_object(C);
	base = CTX_data_active_base(C);
#else
	Object *obedit = scene->obedit;
	Object *obact = OBACT;
	base = BASACT;
#endif

	if (CTX_data_dir(member)) {
		CTX_data_dir_set(result, screen_context_dir);
		return 1;
	}
	else if (CTX_data_equals(member, "scene")) {
		CTX_data_id_pointer_set(result, &scene->id);
		return 1;
	}
	else if (CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) {
		const unsigned int lay = context_layers(sc, scene, sa);
		int visible_objects = CTX_data_equals(member, "visible_objects");

		for (base = scene->base.first; base; base = base->next) {
			if (((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & lay)) {
				if (visible_objects)
					CTX_data_id_list_add(result, &base->object->id);
				else
					CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
			}
		}
		CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
		return 1;
	}
	else if (CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) {
		const unsigned int lay = context_layers(sc, scene, sa);
		int selectable_objects = CTX_data_equals(member, "selectable_objects");

		for (base = scene->base.first; base; base = base->next) {
			if (base->lay & lay) {
				if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0 && (base->object->restrictflag & OB_RESTRICT_SELECT) == 0) {
					if (selectable_objects)
						CTX_data_id_list_add(result, &base->object->id);
					else
						CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
				}
			}
		}
		CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
		return 1;
	}
	else if (CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
		const unsigned int lay = context_layers(sc, scene, sa);
		int selected_objects = CTX_data_equals(member, "selected_objects");

		for (base = scene->base.first; base; base = base->next) {
			if ((base->flag & SELECT) && (base->lay & lay)) {
				if (selected_objects)
					CTX_data_id_list_add(result, &base->object->id);
				else
					CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
			}
		}
		CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
		return 1;
	}
	else if (CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) {
		const unsigned int lay = context_layers(sc, scene, sa);
		int selected_editable_objects = CTX_data_equals(member, "selected_editable_objects");

		for (base = scene->base.first; base; base = base->next) {
			if ((base->flag & SELECT) && (base->lay & lay)) {
				if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) {
					if (0 == BKE_object_is_libdata(base->object)) {
						if (selected_editable_objects)
							CTX_data_id_list_add(result, &base->object->id);
						else
							CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
					}
				}
			}
		}
		CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
		return 1;
	}
	else if (CTX_data_equals(member, "editable_objects") || CTX_data_equals(member, "editable_bases")) {
		const unsigned int lay = context_layers(sc, scene, sa);
		int editable_objects = CTX_data_equals(member, "editable_objects");
		
		/* Visible + Editable, but not necessarily selected */
		for (base = scene->base.first; base; base = base->next) {
			if (((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & lay)) {
				if (0 == BKE_object_is_libdata(base->object)) {
					if (editable_objects)
						CTX_data_id_list_add(result, &base->object->id);
					else
						CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
				}
			}
		}
		CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
		return 1;
	}
	else if (CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) {
		bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
		EditBone *ebone, *flipbone = NULL;
		int editable_bones = CTX_data_equals(member, "editable_bones");
		
		if (arm && arm->edbo) {
			/* Attention: X-Axis Mirroring is also handled here... */
			for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
				/* first and foremost, bone must be visible and selected */
				if (EBONE_VISIBLE(arm, ebone)) {
					/* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
					 * so that most users of this data don't need to explicitly check for it themselves.
					 * 
					 * We need to make sure that these mirrored copies are not selected, otherwise some
					 * bones will be operated on twice.
					 */
					if (arm->flag & ARM_MIRROR_EDIT)
						flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
					
					/* if we're filtering for editable too, use the check for that instead, as it has selection check too */
					if (editable_bones) {
						/* only selected + editable */
						if (EBONE_EDITABLE(ebone)) {
							CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
						
							if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
								CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
						}
					}
					else {
						/* only include bones if visible */
						CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
						
						if ((flipbone) && EBONE_VISIBLE(arm, flipbone) == 0)
							CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
					}
				}
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "selected_bones") || CTX_data_equals(member, "selected_editable_bones")) {
		bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
		EditBone *ebone, *flipbone = NULL;
		int selected_editable_bones = CTX_data_equals(member, "selected_editable_bones");
		
		if (arm && arm->edbo) {
			/* Attention: X-Axis Mirroring is also handled here... */
			for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
				/* first and foremost, bone must be visible and selected */
				if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) {
					/* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
					 * so that most users of this data don't need to explicitly check for it themselves.
					 * 
					 * We need to make sure that these mirrored copies are not selected, otherwise some
					 * bones will be operated on twice.
					 */
					if (arm->flag & ARM_MIRROR_EDIT)
						flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
					
					/* if we're filtering for editable too, use the check for that instead, as it has selection check too */
					if (selected_editable_bones) {
						/* only selected + editable */
						if (EBONE_EDITABLE(ebone)) {
							CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
						
							if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
								CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
						}
					}
					else {
						/* only include bones if selected */
						CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
						
						if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
							CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
					}
				}
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "visible_pose_bones")) {
		Object *obpose = BKE_object_pose_armature_get(obact);
		bArmature *arm = (obpose) ? obpose->data : NULL;
		bPoseChannel *pchan;
		
		if (obpose && obpose->pose && arm) {
			for (pchan = obpose->pose->chanbase.first; pchan; pchan = pchan->next) {
				/* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
				if (PBONE_VISIBLE(arm, pchan->bone)) {
					CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan);
				}
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "selected_pose_bones")) {
		Object *obpose = BKE_object_pose_armature_get(obact);
		bArmature *arm = (obpose) ? obpose->data : NULL;
		bPoseChannel *pchan;
		
		if (obpose && obpose->pose && arm) {
			for (pchan = obpose->pose->chanbase.first; pchan; pchan = pchan->next) {
				/* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
				if (PBONE_VISIBLE(arm, pchan->bone)) {
					if (pchan->bone->flag & BONE_SELECTED)
						CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan);
				}
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "active_bone")) {
		if (obact && obact->type == OB_ARMATURE) {
			bArmature *arm = obact->data;
			if (arm->edbo) {
				if (arm->act_edbone) {
					CTX_data_pointer_set(result, &arm->id, &RNA_EditBone, arm->act_edbone);
					return 1;
				}
			}
			else {
				if (arm->act_bone) {
					CTX_data_pointer_set(result, &arm->id, &RNA_Bone, arm->act_bone);
					return 1;
				}
			}
		}
	}
	else if (CTX_data_equals(member, "active_pose_bone")) {
		bPoseChannel *pchan;
		Object *obpose = BKE_object_pose_armature_get(obact);
		
		pchan = BKE_pose_channel_active(obpose);
		if (pchan) {
			CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "active_base")) {
		if (base)
			CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, base);

		return 1;
	}
	else if (CTX_data_equals(member, "active_object")) {
		if (obact)
			CTX_data_id_pointer_set(result, &obact->id);

		return 1;
	}
	else if (CTX_data_equals(member, "object")) {
		if (obact)
			CTX_data_id_pointer_set(result, &obact->id);

		return 1;
	}
	else if (CTX_data_equals(member, "edit_object")) {
		/* convenience for now, 1 object per scene in editmode */
		if (obedit)
			CTX_data_id_pointer_set(result, &obedit->id);
		
		return 1;
	}
	else if (CTX_data_equals(member, "sculpt_object")) {
		if (obact && (obact->mode & OB_MODE_SCULPT))
			CTX_data_id_pointer_set(result, &obact->id);

		return 1;
	}
	else if (CTX_data_equals(member, "vertex_paint_object")) {
		if (obact && (obact->mode & OB_MODE_VERTEX_PAINT))
			CTX_data_id_pointer_set(result, &obact->id);

		return 1;
	}
	else if (CTX_data_equals(member, "weight_paint_object")) {
		if (obact && (obact->mode & OB_MODE_WEIGHT_PAINT))
			CTX_data_id_pointer_set(result, &obact->id);

		return 1;
	}
	else if (CTX_data_equals(member, "image_paint_object")) {
		if (obact && (obact->mode & OB_MODE_TEXTURE_PAINT))
			CTX_data_id_pointer_set(result, &obact->id);

		return 1;
	}
	else if (CTX_data_equals(member, "particle_edit_object")) {
		if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT))
			CTX_data_id_pointer_set(result, &obact->id);

		return 1;
	}
	else if (CTX_data_equals(member, "sequences")) {
		Editing *ed = BKE_sequencer_editing_get(scene, false);
		if (ed) {
			Sequence *seq;
			for (seq = ed->seqbasep->first; seq; seq = seq->next) {
				CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "selected_sequences")) {
		Editing *ed = BKE_sequencer_editing_get(scene, false);
		if (ed) {
			Sequence *seq;
			for (seq = ed->seqbasep->first; seq; seq = seq->next) {
				if (seq->flag & SELECT) {
					CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
				}
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "selected_editable_sequences")) {
		Editing *ed = BKE_sequencer_editing_get(scene, false);
		if (ed) {
			Sequence *seq;
			for (seq = ed->seqbasep->first; seq; seq = seq->next) {
				if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) {
					CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
				}
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "gpencil_data")) {
		/* FIXME: for some reason, CTX_data_active_object(C) returns NULL when called from these situations
		 * (as outlined above - see Campbell's #ifdefs). That causes the get_active function to fail when 
		 * called from context. For that reason, we end up using an alternative where we pass everything in!
		 */
		bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
		
		if (gpd) {
			CTX_data_id_pointer_set(result, &gpd->id);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "gpencil_data_owner")) {
		/* pointer to which data/datablock owns the reference to the Grease Pencil data being used (as gpencil_data)
		 * XXX: see comment for gpencil_data case... 
		 */
		bGPdata **gpd_ptr = NULL;
		PointerRNA ptr;
		
		/* get pointer to Grease Pencil Data */
		gpd_ptr = ED_gpencil_data_get_pointers_direct((ID *)sc, scene, sa, obact, &ptr);
		
		if (gpd_ptr) {
			CTX_data_pointer_set(result, ptr.id.data, ptr.type, ptr.data);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "active_gpencil_layer")) {
		/* XXX: see comment for gpencil_data case... */
		bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
		
		if (gpd) {
			bGPDlayer *gpl = gpencil_layer_getactive(gpd);
			
			if (gpl) {
				CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl);
				return 1;
			}
		}
	}
	else if (CTX_data_equals(member, "active_gpencil_frame")) {
		/* XXX: see comment for gpencil_data case... */
		bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
		
		if (gpd) {
			bGPDlayer *gpl = gpencil_layer_getactive(gpd);
			
			if (gpl) {
				CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl->actframe);
				return 1;
			}
		}
	}
	else if (CTX_data_equals(member, "visible_gpencil_layers")) {
		/* XXX: see comment for gpencil_data case... */
		bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
		
		if (gpd) {
			bGPDlayer *gpl;
			
			for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
				if ((gpl->flag & GP_LAYER_HIDE) == 0) {
					CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl);
				}
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "editable_gpencil_layers")) {
		/* XXX: see comment for gpencil_data case... */
		bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
		
		if (gpd) {
			bGPDlayer *gpl;
			
			for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
				if (gpencil_layer_is_editable(gpl)) {
					CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl);
				}
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "editable_gpencil_strokes")) {
		/* XXX: see comment for gpencil_data case... */
		bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
		
		if (gpd) {
			bGPDlayer *gpl;
			
			for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
				if (gpencil_layer_is_editable(gpl) && (gpl->actframe)) {
					bGPDframe *gpf = gpl->actframe;
					bGPDstroke *gps;
					
					for (gps = gpf->strokes.first; gps; gps = gps->next) {
						if (ED_gpencil_stroke_can_use_direct(sa, gps)) {
							CTX_data_list_add(result, &gpd->id, &RNA_GPencilStroke, gps);
						}
					}
				}
			}
			CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
			return 1;
		}
	}
	else if (CTX_data_equals(member, "active_operator")) {
		wmOperator *op = NULL;

		SpaceFile *sfile = CTX_wm_space_file(C);
		if (sfile) {
			op = sfile->op;
		}
		else if ((op = UI_context_active_operator_get(C))) {
			/* do nothing */
		}
		else {
			/* note, this checks poll, could be a problem, but this also
			 * happens for the toolbar */
			op = WM_operator_last_redo(C);
		}
		/* TODO, get the operator from popup's */

		if (op && op->ptr) {
			CTX_data_pointer_set(result, NULL, &RNA_Operator, op);
			return 1;
		}
	}
	else {
		return 0; /* not found */
	}

	return -1; /* found but not available */
}
Exemplo n.º 11
0
static int ed_undo_redo_poll(bContext *C)
{
	wmOperator *last_op = WM_operator_last_redo(C);
	return last_op && ED_operator_screenactive(C) && 
		WM_operator_check_ui_enabled(C, last_op->type->name);
}
Exemplo n.º 12
0
static int ed_undo_redo_exec(bContext *C, wmOperator *UNUSED(op))
{
	wmOperator *last_op = WM_operator_last_redo(C);
	const int ret = ED_undo_operator_repeat(C, last_op);
	return ret ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}